Skip to content

Commit 9846eff

Browse files
committed
fix(): release prep
1 parent 0aed1cd commit 9846eff

19 files changed

Lines changed: 973 additions & 423 deletions

‎api/shared-worker/index.js‎

Lines changed: 110 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -15,46 +15,119 @@ export const SHARED_WORKER_WINDOW_PATH = '/oro/shared-worker/index.html'
1515

1616
export const channel = new BroadcastChannel('oro.runtime.sharedWorker')
1717
export const workers = new Map()
18+
const workerReferences = new Map()
1819

1920
channel.addEventListener('message', (event) => {
20-
if (event.data?.error?.id) {
21-
const ref = workers.get(event.data.error.id)
22-
if (ref) {
23-
const worker = ref.deref()
24-
if (!worker) {
21+
if (event.data?.error?.id !== null && event.data?.error?.id !== undefined) {
22+
const refs = workerReferences.get(event.data.error.id)
23+
if (refs) {
24+
const error = new Error(event.data.error.message)
25+
26+
for (const ref of refs) {
27+
const worker = ref.deref()
28+
if (!worker) {
29+
refs.delete(ref)
30+
} else {
31+
worker.dispatchEvent(
32+
new ErrorEvent('error', {
33+
error,
34+
message: error.message
35+
})
36+
)
37+
}
38+
}
39+
40+
if (refs.size === 0) {
41+
workerReferences.delete(event.data.error.id)
2542
workers.delete(event.data.error.id)
2643
} else {
27-
worker.dispatchEvent(
28-
new ErrorEvent('error', {
29-
error: new Error(event.data.error.message)
30-
})
31-
)
44+
updateWorkerReference(event.data.error.id, refs)
3245
}
3346
}
3447
}
3548
})
3649

37-
export async function init (sharedWorker, options) {
38-
const currentWindow = await application.getCurrentWindow()
39-
const window = await getContextWindow()
40-
await currentWindow.send({
41-
event: 'connect',
42-
window: window.index,
43-
value: {
44-
connect: {
45-
scriptURL: options.scriptURL,
46-
client: client.toJSON(),
47-
name: options.name,
48-
port: serialize(
49-
ipc.findIPCMessageTransfers(new Set(), sharedWorker.channel.port2)
50-
),
51-
id: sharedWorker.id
52-
}
50+
// Register before the first await so early module failures reach every
51+
// SharedWorker object using the same URL and name.
52+
function registerWorker (sharedWorker) {
53+
let refs = workerReferences.get(sharedWorker.id)
54+
if (!refs) {
55+
refs = new Set()
56+
workerReferences.set(sharedWorker.id, refs)
57+
}
58+
59+
const ref = new WeakRef(sharedWorker)
60+
refs.add(ref)
61+
workers.set(sharedWorker.id, ref)
62+
return { ref, refs }
63+
}
64+
65+
function unregisterWorker (sharedWorker, registration) {
66+
const refs = workerReferences.get(sharedWorker.id)
67+
if (refs === registration.refs) {
68+
refs.delete(registration.ref)
69+
70+
if (refs.size === 0) {
71+
workerReferences.delete(sharedWorker.id)
72+
workers.delete(sharedWorker.id)
73+
} else {
74+
updateWorkerReference(sharedWorker.id, refs)
75+
}
76+
}
77+
}
78+
79+
function updateWorkerReference (id, refs) {
80+
const current = workers.get(id)
81+
if (current && refs.has(current) && current.deref()) {
82+
return
83+
}
84+
85+
for (const ref of refs) {
86+
if (ref.deref()) {
87+
workers.set(id, ref)
88+
return
5389
}
54-
})
90+
}
5591

56-
ipc.IPCMessagePort.transfer(sharedWorker.channel.port2)
57-
workers.set(sharedWorker.id, new WeakRef(sharedWorker))
92+
workerReferences.delete(id)
93+
workers.delete(id)
94+
}
95+
96+
export async function init (sharedWorker, options) {
97+
const registration = registerWorker(sharedWorker)
98+
99+
try {
100+
const currentWindow = await application.getCurrentWindow()
101+
const window = await getContextWindow()
102+
const port = serialize(
103+
ipc.findIPCMessageTransfers(new Set(), sharedWorker.channel.port2)
104+
)
105+
106+
// Serialize before marking the sending endpoint as transferred, then
107+
// activate the local relay before the receiving worker can reply.
108+
ipc.IPCMessagePort.transfer(sharedWorker.channel.port2)
109+
110+
await currentWindow.send({
111+
event: 'connect',
112+
window: window.index,
113+
value: {
114+
connect: {
115+
scriptURL: options.scriptURL,
116+
client: client.toJSON(),
117+
name: options.name,
118+
port,
119+
id: sharedWorker.id
120+
}
121+
}
122+
})
123+
} catch (err) {
124+
unregisterWorker(sharedWorker, registration)
125+
try {
126+
sharedWorker.channel.port1.close()
127+
sharedWorker.channel.port2.close()
128+
} catch {}
129+
throw err
130+
}
58131
}
59132

60133
export class SharedWorkerMessagePort extends ipc.IPCMessagePort {
@@ -94,20 +167,21 @@ export class SharedWorker extends EventTarget {
94167
}
95168

96169
const url = new URL(aURL, location.origin)
97-
const id = crypto.murmur3(url.origin + url.pathname)
170+
const name =
171+
typeof nameOrOptions === 'string'
172+
? nameOrOptions
173+
: typeof nameOrOptions?.name === 'string'
174+
? nameOrOptions.name
175+
: null
176+
const id = crypto.murmur3(`${url.toString()}\0${name ?? ''}`)
98177

99178
// @ts-ignore
100179
super(url.toString(), nameOrOptions)
101180

102181
this.#id = id
103182
this.#ready = init(this, {
104183
scriptURL: url.toString(),
105-
name:
106-
typeof nameOrOptions === 'string'
107-
? nameOrOptions
108-
: typeof nameOrOptions?.name === 'string'
109-
? nameOrOptions.name
110-
: null
184+
name
111185
})
112186
}
113187

0 commit comments

Comments
 (0)