Skip to content

Commit c02e1e9

Browse files
committed
fix: event routing to service workers
1 parent 8e1cce4 commit c02e1e9

File tree

1 file changed

+45
-29
lines changed
  • packages/electron-chrome-extensions/src/browser

1 file changed

+45
-29
lines changed

packages/electron-chrome-extensions/src/browser/router.ts

Lines changed: 45 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,11 @@ class RoutingDelegate {
128128
) => {
129129
const observer = this.sessionMap.get(getSessionFromEvent(event))
130130
const host = getHostFromEvent(event)
131-
const listener: EventListener = { host, extensionId }
131+
const type = (event as any).type || 'frame'
132+
const listener: EventListener =
133+
type === 'service-worker'
134+
? { extensionId, type: (event as any).type }
135+
: { extensionId, type: (event as any).type, host }
132136
return observer?.addListener(listener, extensionId, eventName)
133137
}
134138

@@ -139,7 +143,11 @@ class RoutingDelegate {
139143
) => {
140144
const observer = this.sessionMap.get(getSessionFromEvent(event))
141145
const host = getHostFromEvent(event)
142-
const listener: EventListener = { host, extensionId }
146+
const type = (event as any).type || 'frame'
147+
const listener: EventListener =
148+
type === 'service-worker'
149+
? { extensionId, type: (event as any).type }
150+
: { extensionId, type: (event as any).type, host }
143151
return observer?.removeListener(listener, extensionId, eventName)
144152
}
145153
}
@@ -169,7 +177,8 @@ type HandlerMap = Map<EventName, Handler>
169177

170178
interface EventListener {
171179
// TODO(mv3): host: Electron.WebContents | Electron.ServiceWorkerMain
172-
host: any
180+
host?: any
181+
type: 'service-worker' | 'frame'
173182
extensionId: string
174183
}
175184

@@ -217,8 +226,15 @@ export class ExtensionRouter {
217226
if (runningStatus !== 'starting') return
218227

219228
const serviceWorker = (session as any).serviceWorkers.getWorkerFromVersionID(versionId)
220-
if (serviceWorker) {
221-
debug(`storing reference to background service worker [url:'${serviceWorker.scope}']`)
229+
if (!serviceWorker) return
230+
231+
const { scope } = serviceWorker
232+
if (!scope.startsWith('chrome-extension:')) return
233+
234+
if (this.extensionHosts.has(serviceWorker)) {
235+
debug('%s running status changed to %s', scope, runningStatus)
236+
} else {
237+
debug(`storing reference to background service worker [url:'${scope}']`)
222238
this.extensionWorkers.add(serviceWorker)
223239
}
224240
},
@@ -271,7 +287,9 @@ export class ExtensionRouter {
271287
} else {
272288
debug(`adding '${eventName}' event listener for ${extensionId}`)
273289
eventListeners.push(listener)
274-
this.observeListenerHost(listener.host)
290+
if (listener.host) {
291+
this.observeListenerHost(listener.host)
292+
}
275293
}
276294
}
277295

@@ -356,43 +374,41 @@ export class ExtensionRouter {
356374
* Sends extension event to the host for the given extension ID if it
357375
* registered a listener for it.
358376
*/
359-
sendEvent(extensionId: string | undefined, eventName: string, ...args: any[]) {
377+
sendEvent(targetExtensionId: string | undefined, eventName: string, ...args: any[]) {
360378
const { listeners } = this
361-
362379
let eventListeners = listeners.get(eventName)
363-
364-
if (extensionId) {
365-
// TODO: extension permissions check
366-
367-
eventListeners = eventListeners?.filter((el) => el.extensionId === extensionId)
368-
}
380+
const ipcName = `crx-${eventName}`
369381

370382
if (!eventListeners || eventListeners.length === 0) {
371383
debug(`ignoring '${eventName}' event with no listeners`)
372384
return
373385
}
374386

375387
let sentCount = 0
376-
for (const { host } of eventListeners) {
377-
const ipcName = `crx-${eventName}`
378-
const send = () => {
379-
if (host.isDestroyed()) {
380-
console.error(`Unable to send '${eventName}' to extension host for ${extensionId}`)
381-
return
382-
}
383-
host.send(ipcName, ...args)
388+
for (const { type, extensionId, host } of eventListeners) {
389+
if (targetExtensionId && targetExtensionId !== extensionId) {
390+
continue
384391
}
385392

386-
if (host.constructor.name === 'ServiceWorkerMain') {
393+
if (type === 'service-worker') {
394+
const scope = `chrome-extension://${extensionId}/`
395+
// TODO(mv3): remove any
396+
;(this.session.serviceWorkers as any)
397+
.startWorkerForScope(scope)
398+
.then((serviceWorker: any) => {
399+
serviceWorker.send(ipcName, ...args)
400+
})
401+
.catch((error: any) => {
402+
debug('failed to send %s to %s', eventName, extensionId)
403+
console.error(error)
404+
process.exit(1)
405+
})
406+
} else {
387407
if (host.isDestroyed()) {
388-
console.error(
389-
`Service Worker is destroyed.\nUnable to send '${eventName}' to extension host for ${extensionId}`,
390-
)
408+
console.error(`Unable to send '${eventName}' to extension host for ${extensionId}`)
391409
return
392410
}
393-
host.startWorker().then(send)
394-
} else {
395-
send()
411+
host.send(ipcName, ...args)
396412
}
397413

398414
sentCount++

0 commit comments

Comments
 (0)