11import { app , session } from 'electron' ;
22import path from 'node:path' ;
33import { createRequire } from 'node:module' ;
4- import type { Direction , IpcEventData } from './types/shared' ;
4+ import type { Direction , IpcEventData , ServiceWorkerDetails } from './types/shared' ;
55
66let isInstalled = false ;
77let isInstalledToDefaultSession = false ;
@@ -13,23 +13,25 @@ function trackIpcEvent(
1313 direction : Direction ,
1414 channel : string ,
1515 args : any [ ] ,
16- serviceWorker : Electron . ServiceWorkerMain ,
16+ devtronSW : Electron . ServiceWorkerMain ,
17+ serviceWorkerDetails ?: ServiceWorkerDetails ,
1718) {
1819 const eventData : IpcEventData = {
1920 direction,
2021 channel,
2122 args,
2223 timestamp : Date . now ( ) ,
24+ serviceWorkerDetails,
2325 } ;
2426
25- if ( serviceWorker === null ) {
27+ if ( devtronSW === null ) {
2628 console . error ( 'The service-worker for Devtron is not registered yet. Cannot track IPC event.' ) ;
2729 return ;
2830 }
29- serviceWorker . send ( 'devtron-render-event' , eventData ) ;
31+ devtronSW . send ( 'devtron-render-event' , eventData ) ;
3032}
3133
32- function registerIpcListeners ( ses : Electron . Session , serviceWorker : Electron . ServiceWorkerMain ) {
34+ function registerIpcListeners ( ses : Electron . Session , devtronSW : Electron . ServiceWorkerMain ) {
3335 ses . on (
3436 // @ts -expect-error: '-ipc-message' is an internal event
3537 '-ipc-message' ,
@@ -38,9 +40,9 @@ function registerIpcListeners(ses: Electron.Session, serviceWorker: Electron.Ser
3840 channel : string ,
3941 args : any [ ] ,
4042 ) => {
41- if ( event . type === 'frame' ) trackIpcEvent ( 'renderer-to-main' , channel , args , serviceWorker ) ;
43+ if ( event . type === 'frame' ) trackIpcEvent ( 'renderer-to-main' , channel , args , devtronSW ) ;
4244 else if ( event . type === 'service-worker' )
43- trackIpcEvent ( 'service-worker-to-main' , channel , args , serviceWorker ) ;
45+ trackIpcEvent ( 'service-worker-to-main' , channel , args , devtronSW ) ;
4446 } ,
4547 ) ;
4648
@@ -52,9 +54,9 @@ function registerIpcListeners(ses: Electron.Session, serviceWorker: Electron.Ser
5254 channel : string ,
5355 args : any [ ] ,
5456 ) => {
55- if ( event . type === 'frame' ) trackIpcEvent ( 'renderer-to-main' , channel , args , serviceWorker ) ;
57+ if ( event . type === 'frame' ) trackIpcEvent ( 'renderer-to-main' , channel , args , devtronSW ) ;
5658 else if ( event . type === 'service-worker' )
57- trackIpcEvent ( 'service-worker-to-main' , channel , args , serviceWorker ) ;
59+ trackIpcEvent ( 'service-worker-to-main' , channel , args , devtronSW ) ;
5860 } ,
5961 ) ;
6062 ses . on (
@@ -65,18 +67,87 @@ function registerIpcListeners(ses: Electron.Session, serviceWorker: Electron.Ser
6567 channel : string ,
6668 args : any [ ] ,
6769 ) => {
68- if ( event . type === 'frame' ) trackIpcEvent ( 'renderer-to-main' , channel , args , serviceWorker ) ;
70+ if ( event . type === 'frame' ) trackIpcEvent ( 'renderer-to-main' , channel , args , devtronSW ) ;
6971 else if ( event . type === 'service-worker' )
70- trackIpcEvent ( 'service-worker-to-main' , channel , args , serviceWorker ) ;
72+ trackIpcEvent ( 'service-worker-to-main' , channel , args , devtronSW ) ;
7173 } ,
7274 ) ;
7375}
7476
77+ /**
78+ * Registers a listener for the service worker's send method to track IPC events
79+ * sent from the main process to the service worker.
80+ */
81+ function registerServiceWorkerSendListener (
82+ ses : Electron . Session ,
83+ devtronSW : Electron . ServiceWorkerMain ,
84+ ) : void {
85+ const isInstalledSet = new Set < number > ( ) ; // stores version IDs of patched service workers
86+
87+ // register listener for existing service workers
88+ const allRunning = ses . serviceWorkers . getAllRunning ( ) ;
89+ for ( const vid in allRunning ) {
90+ const swInfo = allRunning [ vid ] ;
91+
92+ const sw = ses . serviceWorkers . getWorkerFromVersionID ( Number ( vid ) ) ;
93+
94+ if ( typeof sw === 'undefined' || sw . scope === devtronSW . scope ) continue ;
95+ isInstalledSet . add ( swInfo . versionId ) ;
96+
97+ const originalSend = sw . send ;
98+ sw . send = function ( ...args ) {
99+ trackIpcEvent (
100+ 'main-to-service-worker' ,
101+ args [ 0 ] , // channel
102+ args . slice ( 1 ) , // args
103+ devtronSW ,
104+ {
105+ serviceWorkerScope : sw . scope ,
106+ serviceWorkerVersionId : sw . versionId ,
107+ } ,
108+ ) ;
109+ return originalSend . apply ( this , args ) ;
110+ } ;
111+ }
112+
113+ // register listener for new service workers
114+ ses . serviceWorkers . on ( 'running-status-changed' , ( details ) => {
115+ if ( details . runningStatus === 'running' || details . runningStatus === 'starting' ) {
116+ const sw = ses . serviceWorkers . getWorkerFromVersionID ( details . versionId ) ;
117+
118+ if (
119+ typeof sw === 'undefined' ||
120+ sw . scope === devtronSW . scope ||
121+ isInstalledSet . has ( sw . versionId )
122+ )
123+ return ;
124+
125+ isInstalledSet . add ( details . versionId ) ;
126+
127+ const originalSend = sw . send ;
128+ sw . send = function ( ...args ) {
129+ trackIpcEvent (
130+ 'main-to-service-worker' ,
131+ args [ 0 ] , // channel
132+ args . slice ( 1 ) , // args
133+ devtronSW ,
134+ {
135+ serviceWorkerScope : sw . scope ,
136+ serviceWorkerVersionId : sw . versionId ,
137+ } ,
138+ ) ;
139+ return originalSend . apply ( this , args ) ;
140+ } ;
141+ }
142+ } ) ;
143+ }
144+
75145async function startServiceWorker ( ses : Electron . Session , extension : Electron . Extension ) {
76146 try {
77147 const sw = await ses . serviceWorkers . startWorkerForScope ( extension . url ) ;
78148 sw . startTask ( ) ;
79149 registerIpcListeners ( ses , sw ) ;
150+ registerServiceWorkerSendListener ( ses , sw ) ;
80151 } catch ( error ) {
81152 console . warn ( `Failed to start Devtron service-worker (${ error } ), trying again...` ) ;
82153 /**
@@ -93,6 +164,7 @@ async function startServiceWorker(ses: Electron.Session, extension: Electron.Ext
93164 const sw = await ses . serviceWorkers . startWorkerForScope ( extension . url ) ;
94165 sw . startTask ( ) ;
95166 registerIpcListeners ( ses , sw ) ;
167+ registerServiceWorkerSendListener ( ses , sw ) ;
96168 ses . serviceWorkers . removeListener ( 'registration-completed' , handleDetails ) ;
97169 console . log ( `Devtron service-worker started successfully` ) ;
98170 }
0 commit comments