From 98aaa6a01f02ab0bb71418691ca25abaa4c1817f Mon Sep 17 00:00:00 2001 From: SudhansuBandha Date: Tue, 7 Jul 2026 07:43:55 +0530 Subject: [PATCH] worker: populate BroadcastChannel MessageEvent source Populate the MessageEvent source property with the sender's worker thread ID for BroadcastChannel messages originating from worker threads. Fixes: https://github.com/nodejs/node/issues/59053 Signed-off-by: Sudhansu Bandha --- lib/internal/worker/io.js | 9 ++++-- test/parallel/test-worker-broadcastchannel.js | 31 ++++++++++++++++++- 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/lib/internal/worker/io.js b/lib/internal/worker/io.js index 786ee36c1927fa..4182538561fb9e 100644 --- a/lib/internal/worker/io.js +++ b/lib/internal/worker/io.js @@ -48,6 +48,7 @@ const { } = internalBinding('messaging'); const { getEnvMessagePort, + threadId, } = internalBinding('worker'); const { Readable, Writable } = require('stream'); @@ -346,7 +347,7 @@ function receiveMessageOnPort(port) { } function onMessageEvent(type, data) { - this.dispatchEvent(lazyMessageEvent(type, { data })); + this.dispatchEvent(lazyMessageEvent(type, { data: data.value, source: data.source })); } function isBroadcastChannel(value) { @@ -419,13 +420,17 @@ class BroadcastChannel extends EventTarget { * @returns {void} */ postMessage(message) { + const broadcastMessage = { + source: threadId, + value: message, + }; if (!isBroadcastChannel(this)) throw new ERR_INVALID_THIS('BroadcastChannel'); if (arguments.length === 0) throw new ERR_MISSING_ARGS('message'); if (this[kHandle] === undefined) throw new DOMException('BroadcastChannel is closed.', 'InvalidStateError'); - if (this[kHandle].postMessage(message) === undefined) + if (this[kHandle].postMessage(broadcastMessage) === undefined) throw new DOMException('Message could not be posted.'); } diff --git a/test/parallel/test-worker-broadcastchannel.js b/test/parallel/test-worker-broadcastchannel.js index 12535271c15596..89bccd1fbddf19 100644 --- a/test/parallel/test-worker-broadcastchannel.js +++ b/test/parallel/test-worker-broadcastchannel.js @@ -147,7 +147,7 @@ assert.throws(() => new BroadcastChannel(), { const bc1 = new BroadcastChannel('channel4'); const bc2 = new BroadcastChannel('channel4'); bc1.postMessage('some data'); - assert.strictEqual(receiveMessageOnPort(bc2).message, 'some data'); + assert.strictEqual(receiveMessageOnPort(bc2).message.value, 'some data'); assert.strictEqual(receiveMessageOnPort(bc2), undefined); bc1.close(); bc2.close(); @@ -183,3 +183,32 @@ assert.throws(() => new BroadcastChannel(), { "BroadcastChannel { name: 'channel5', active: false }" ); } + +{ + const bc = new BroadcastChannel('worker-source'); + + new Worker(` + const assert = require('assert'); + const { BroadcastChannel, threadId } = require('worker_threads'); + + const bc = new BroadcastChannel('worker-source'); + + bc.onmessage = (evt) => { + assert.strictEqual(evt.data, 'from-main'); + assert.strictEqual(evt.source, 0); + + bc.close(); + }; + + bc.postMessage('from-worker'); + `, { eval: true }); + + bc.onmessage = common.mustCall((evt) => { + assert.strictEqual(evt.data, 'from-worker'); + + assert.ok(evt.source > 0); + + bc.postMessage('from-main'); + bc.close(); + }); +}