Skip to content

Commit 9d1763d

Browse files
whitphxAriPerkkio
andauthored
fix(web-worker): postMessage to send ports to workers (#9078)
Co-authored-by: Ari Perkkiö <ari.perkkio@gmail.com>
1 parent 73b54ce commit 9d1763d

File tree

3 files changed

+22
-0
lines changed

3 files changed

+22
-0
lines changed

packages/web-worker/src/utils.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,14 @@ function createClonedMessageEvent(
2929

3030
debug('clone worker message %o', data)
3131
const origin = typeof location === 'undefined' ? undefined : location.origin
32+
const ports = transfer?.filter((t): t is MessagePort => t instanceof MessagePort)
3233

3334
if (typeof structuredClone === 'function' && clone === 'native') {
3435
debug('create message event, using native structured clone')
3536
return new MessageEvent('message', {
3637
data: structuredClone(data, { transfer }),
3738
origin,
39+
ports,
3840
})
3941
}
4042
if (clone !== 'none') {
@@ -50,12 +52,14 @@ function createClonedMessageEvent(
5052
return new MessageEvent('message', {
5153
data: ponyfillStructuredClone(data, { lossy: true } as any),
5254
origin,
55+
ports,
5356
})
5457
}
5558
debug('create message event without cloning an object')
5659
return new MessageEvent('message', {
5760
data,
5861
origin,
62+
ports,
5963
})
6064
}
6165

test/core/src/web-worker/worker.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
11
self.onmessage = (e) => {
22
self.postMessage(`${e.data} world`)
3+
4+
const port = e.ports[0]
5+
if (port) {
6+
port.postMessage(`${e.data} world via port`)
7+
}
38
}

test/core/test/web-worker-node.test.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,19 @@ it('self injected into worker and its deps should be equal', async () => {
211211
expect(await testSelfWorker(new Worker(new URL('../src/web-worker/selfWorker.ts', import.meta.url)))).toBeTruthy()
212212
})
213213

214+
it('transfer MessagePort objects to worker as event.ports', async () => {
215+
expect.assertions(1)
216+
217+
const worker = new MyWorker()
218+
const channel = new MessageChannel()
219+
const promise = new Promise<string>((resolve, reject) => {
220+
channel.port1.onmessage = e => resolve(e.data as string)
221+
channel.port1.onmessageerror = reject
222+
})
223+
worker.postMessage('hello', [channel.port2])
224+
await expect(promise).resolves.toBe('hello world via port')
225+
})
226+
214227
it('throws syntax error if no arguments are provided', () => {
215228
const worker = new MyWorker()
216229

0 commit comments

Comments
 (0)