Skip to content

Commit

Permalink
refactor(api/service-worker): wait for high priority service workers
Browse files Browse the repository at this point in the history
  • Loading branch information
jwerle committed Jan 9, 2025
1 parent 7c3f6d6 commit fd50876
Show file tree
Hide file tree
Showing 7 changed files with 56 additions and 52 deletions.
79 changes: 35 additions & 44 deletions api/ipc.js
Original file line number Diff line number Diff line change
Expand Up @@ -1772,43 +1772,33 @@ export function findIPCMessageTransfers (transfers, object) {
object[i] = findIPCMessageTransfers(transfers, object[i])
}
} else if (object && typeof object === 'object') {
if (
object instanceof MessagePort || (
typeof object.postMessage === 'function' &&
Object.getPrototypeOf(object).constructor.name === 'MessagePort'
)
) {
const port = IPCMessagePort.create(object)
object.addEventListener('message', function onMessage (event) {
if (port.closed === true) {
port.onmessage = null
event.preventDefault()
event.stopImmediatePropagation()
object.removeEventListener('message', onMessage)
return false
}

port.dispatchEvent(new MessageEvent('message', event))
})

if (object instanceof MessagePort) {
if (object instanceof IPCMessagePort) {
const port = IPCMessagePort.create(object)
ports.get(port.id).channel.onmessage = (event) => {
if (port.closed === true) {
port.onmessage = null
event.preventDefault()
event.stopImmediatePropagation()
return false
}

port.onmessage = (event) => {
if (port.closed === true) {
port.onmessage = null
event.preventDefault()
event.stopImmediatePropagation()
return false
if (port.started && event.data?.token !== port.token) {
console.log(event.data)
const transfers = new Set()
findIPCMessageTransfers(transfers, event.data)
object.postMessage(event.data, {
transfer: Array.from(transfers)
})
}
}

const transfers = new Set()
findIPCMessageTransfers(transfers, event.data)
object.postMessage(event.data, {
transfer: Array.from(transfers)
})
add(port)
return port
} else {
add(object)
return object
}
add(port)
return port
} else {
} else if (Object.getPrototypeOf(object) === Object.prototype) {
for (const key in object) {
object[key] = findIPCMessageTransfers(
transfers,
Expand Down Expand Up @@ -1841,13 +1831,15 @@ export class IPCMessagePort extends MessagePort {
static create (options = null) {
const id = String(options?.id ?? rand64())
const port = Object.create(this.prototype)
const token = String(rand64())
const channel = typeof options?.channel === 'string'
? new BroadcastChannel(options.channel)
: (
(options?.channel && new BroadcastChannel(options.channel.name, options.channel)) ??
new BroadcastChannel(id)
)
const token = ports.get(id)?.token || String(rand64())
const channel = ports.get(id)?.channel ||
(typeof options?.channel === 'string'
? new BroadcastChannel(options.channel)
: (
(options?.channel && new BroadcastChannel(options.channel.name, options.channel)) ??
new BroadcastChannel(id)
)
)

if (ports.has(id)) {
ports.get(id).closed = true
Expand All @@ -1868,8 +1860,8 @@ export class IPCMessagePort extends MessagePort {
eventTarget: { writable: true, value: ports.get(id)?.eventTarget || new EventTarget() }
}))

const state = ports.get(id)
channel.onmessage = function onMessage (event) {
const state = ports.get(id)
if (!state || state?.closed === true) {
event.preventDefault()
event.stopImmediatePropagation()
Expand Down Expand Up @@ -2051,10 +2043,9 @@ export class IPCMessagePort extends MessagePort {
}

[Symbol.for('socket.runtime.serialize')] () {
const channel = ports.get(this.id)?.channel
return {
__type__: 'IPCMessagePort',
channel: channel ? { name: channel.name, origin: channel.origin || location.origin } : null,
channel: ports.get(this.id)?.channel?.name ?? null,
id: this.id
}
}
Expand Down
1 change: 0 additions & 1 deletion api/process/signal.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
*/
import { signal as constants } from '../os/constants.js'
import { SignalEvent } from '../internal/events.js'
import ipc from '../ipc.js'
import os from '../os.js'

/**
Expand Down
1 change: 0 additions & 1 deletion api/service-worker/context.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,6 @@ export class Context {
*/
async client () {
if (this.event.clientId) {
console.log('REQUEST CLIENT', this.event.clientId)
return await clients.get(this.event.clientId)
}

Expand Down
21 changes: 19 additions & 2 deletions api/service-worker/init.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ export class ServiceWorkerInstance extends Worker {
this.postMessage({ register: info })
} else if (event.data.__service_worker_registered?.id === info.id) {
this.postMessage({ install: info })
info.promise.resolve()
} else if (event.data?.message && event?.data.client?.id) {
sharedWorker.port.postMessage({
...event.data,
Expand Down Expand Up @@ -132,6 +133,9 @@ export class ServiceWorkerInfo {
scope = null
scriptURL = null
serializedWorkerArgs = null
priority = 'default'
// @ts-ignore
#promise = Promise.withResolvers()

constructor (data) {
for (const key in data) {
Expand All @@ -149,6 +153,10 @@ export class ServiceWorkerInfo {
get pathname () {
return new URL(this.url).pathname
}

get promise () {
return this.#promise
}
}

export async function onRegister (event) {
Expand All @@ -158,6 +166,16 @@ export async function onRegister (event) {
return
}

for (const worker of workers.values()) {
if (worker.priority === 'high' && /high|default|low/i.test(info.priority)) {
await worker.ready
} else if (worker.priority === 'default' && /default|low/i.test(info.priority)) {
await worker.ready
} else if (worker.priority === 'low' && /low/i.test(info.priority)) {
await worker.ready
}
}

const worker = new ServiceWorkerInstance('./worker.js', {
info
})
Expand Down Expand Up @@ -198,7 +216,6 @@ export async function onActivate (event) {
export async function onFetch (event) {
const info = new ServiceWorkerInfo(event.detail)
const exists = workers.has(info.hash)
console.log(exists, event.detail)

// this may be an early fetch, just try waiting at most
// 32*16 milliseconds for the worker to be available or
Expand Down Expand Up @@ -378,7 +395,7 @@ hooks.onReady(async () => {
const result = await ipc.request('serviceWorker.getRegistrations')
if (Array.isArray(result.data)) {
for (const info of result.data) {
//await navigator.serviceWorker.register(info.scriptURL, info)
await navigator.serviceWorker.register(info.scriptURL, info)
}
}
})
2 changes: 1 addition & 1 deletion api/service-worker/instance.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ export function createServiceWorker (
state: {
configurable: true,
enumerable: false,
get: () => currentState === null ? state.serviceWorker.state : currentState,
get: () => currentState === null ? state.serviceWorker.state : currentState
},

[Symbol.for('socket.runtime.serviceWorker.state')]: {
Expand Down
1 change: 0 additions & 1 deletion api/service-worker/worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,6 @@ export async function onMessage (event) {
}

const url = new URL(data.fetch.request.url)
console.log('FetchEvent: %s', url.href)
const fetchEvent = new FetchEvent('fetch', {
clientId: data.fetch.client.id,
fetchId: data.fetch.request.id,
Expand Down
3 changes: 1 addition & 2 deletions api/shared-worker/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -147,15 +147,14 @@ export async function getContextWindow () {
}

const windows = await application.getWindows([], { max: false })
let firstInit = true

for (const window of windows) {
if (window.title === SHARED_WORKER_WINDOW_TITLE) {
if (window.location) {
const url = new URL(window.location.href, globalThis.location.origin)
if (url.origin === globalThis.location.origin) {
contextWindow = window
firstInit = false
break
}
}
}
Expand Down

0 comments on commit fd50876

Please sign in to comment.