Skip to content

Commit

Permalink
fix: event routing to service workers
Browse files Browse the repository at this point in the history
  • Loading branch information
samuelmaddock committed Dec 14, 2024
1 parent 8e1cce4 commit c02e1e9
Showing 1 changed file with 45 additions and 29 deletions.
74 changes: 45 additions & 29 deletions packages/electron-chrome-extensions/src/browser/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,11 @@ class RoutingDelegate {
) => {
const observer = this.sessionMap.get(getSessionFromEvent(event))
const host = getHostFromEvent(event)
const listener: EventListener = { host, extensionId }
const type = (event as any).type || 'frame'
const listener: EventListener =
type === 'service-worker'
? { extensionId, type: (event as any).type }
: { extensionId, type: (event as any).type, host }
return observer?.addListener(listener, extensionId, eventName)
}

Expand All @@ -139,7 +143,11 @@ class RoutingDelegate {
) => {
const observer = this.sessionMap.get(getSessionFromEvent(event))
const host = getHostFromEvent(event)
const listener: EventListener = { host, extensionId }
const type = (event as any).type || 'frame'
const listener: EventListener =
type === 'service-worker'
? { extensionId, type: (event as any).type }
: { extensionId, type: (event as any).type, host }
return observer?.removeListener(listener, extensionId, eventName)
}
}
Expand Down Expand Up @@ -169,7 +177,8 @@ type HandlerMap = Map<EventName, Handler>

interface EventListener {
// TODO(mv3): host: Electron.WebContents | Electron.ServiceWorkerMain
host: any
host?: any
type: 'service-worker' | 'frame'
extensionId: string
}

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

const serviceWorker = (session as any).serviceWorkers.getWorkerFromVersionID(versionId)
if (serviceWorker) {
debug(`storing reference to background service worker [url:'${serviceWorker.scope}']`)
if (!serviceWorker) return

const { scope } = serviceWorker
if (!scope.startsWith('chrome-extension:')) return

if (this.extensionHosts.has(serviceWorker)) {
debug('%s running status changed to %s', scope, runningStatus)
} else {
debug(`storing reference to background service worker [url:'${scope}']`)
this.extensionWorkers.add(serviceWorker)
}
},
Expand Down Expand Up @@ -271,7 +287,9 @@ export class ExtensionRouter {
} else {
debug(`adding '${eventName}' event listener for ${extensionId}`)
eventListeners.push(listener)
this.observeListenerHost(listener.host)
if (listener.host) {
this.observeListenerHost(listener.host)
}
}
}

Expand Down Expand Up @@ -356,43 +374,41 @@ export class ExtensionRouter {
* Sends extension event to the host for the given extension ID if it
* registered a listener for it.
*/
sendEvent(extensionId: string | undefined, eventName: string, ...args: any[]) {
sendEvent(targetExtensionId: string | undefined, eventName: string, ...args: any[]) {
const { listeners } = this

let eventListeners = listeners.get(eventName)

if (extensionId) {
// TODO: extension permissions check

eventListeners = eventListeners?.filter((el) => el.extensionId === extensionId)
}
const ipcName = `crx-${eventName}`

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

let sentCount = 0
for (const { host } of eventListeners) {
const ipcName = `crx-${eventName}`
const send = () => {
if (host.isDestroyed()) {
console.error(`Unable to send '${eventName}' to extension host for ${extensionId}`)
return
}
host.send(ipcName, ...args)
for (const { type, extensionId, host } of eventListeners) {
if (targetExtensionId && targetExtensionId !== extensionId) {
continue
}

if (host.constructor.name === 'ServiceWorkerMain') {
if (type === 'service-worker') {
const scope = `chrome-extension://${extensionId}/`
// TODO(mv3): remove any
;(this.session.serviceWorkers as any)
.startWorkerForScope(scope)
.then((serviceWorker: any) => {
serviceWorker.send(ipcName, ...args)
})
.catch((error: any) => {
debug('failed to send %s to %s', eventName, extensionId)
console.error(error)
process.exit(1)
})
} else {
if (host.isDestroyed()) {
console.error(
`Service Worker is destroyed.\nUnable to send '${eventName}' to extension host for ${extensionId}`,
)
console.error(`Unable to send '${eventName}' to extension host for ${extensionId}`)
return
}
host.startWorker().then(send)
} else {
send()
host.send(ipcName, ...args)
}

sentCount++
Expand Down

0 comments on commit c02e1e9

Please sign in to comment.