diff options
Diffstat (limited to 'lib/internal/worker/io.js')
-rw-r--r-- | lib/internal/worker/io.js | 87 |
1 files changed, 83 insertions, 4 deletions
diff --git a/lib/internal/worker/io.js b/lib/internal/worker/io.js index 73958dbc2d7..2352ac6ebf8 100644 --- a/lib/internal/worker/io.js +++ b/lib/internal/worker/io.js @@ -19,11 +19,13 @@ const { const { MessagePort, MessageChannel, + broadcastChannel, drainMessagePort, moveMessagePortToContext, receiveMessageOnPort: receiveMessageOnPort_, stopMessagePort, - checkMessagePort + checkMessagePort, + DOMException, } = internalBinding('messaging'); const { getEnvMessagePort @@ -41,14 +43,20 @@ const { } = require('internal/event_target'); const { inspect } = require('internal/util/inspect'); const { - ERR_INVALID_ARG_TYPE -} = require('internal/errors').codes; + codes: { + ERR_INVALID_ARG_TYPE, + ERR_MISSING_ARGS, + } +} = require('internal/errors'); const kData = Symbol('kData'); +const kHandle = Symbol('kHandle'); const kIncrementsPortRef = Symbol('kIncrementsPortRef'); const kLastEventId = Symbol('kLastEventId'); const kName = Symbol('kName'); const kOrigin = Symbol('kOrigin'); +const kOnMessage = Symbol('kOnMessage'); +const kOnMessageError = Symbol('kOnMessageError'); const kPort = Symbol('kPort'); const kPorts = Symbol('kPorts'); const kWaitingStreams = Symbol('kWaitingStreams'); @@ -324,6 +332,76 @@ function receiveMessageOnPort(port) { return { message }; } +function onMessageEvent(type, data) { + this.dispatchEvent(new MessageEvent(type, { data })); +} + +class BroadcastChannel extends EventTarget { + constructor(name) { + if (arguments.length === 0) + throw new ERR_MISSING_ARGS('name'); + super(); + this[kName] = `${name}`; + this[kHandle] = broadcastChannel(this[kName]); + this[kOnMessage] = onMessageEvent.bind(this, 'message'); + this[kOnMessageError] = onMessageEvent.bind(this, 'messageerror'); + this[kHandle].on('message', this[kOnMessage]); + this[kHandle].on('messageerror', this[kOnMessageError]); + } + + [inspect.custom](depth, options) { + if (depth < 0) + return 'BroadcastChannel'; + + const opts = { + ...options, + depth: options.depth == null ? null : options.depth - 1 + }; + + return `BroadcastChannel ${inspect({ + name: this[kName], + active: this[kHandle] !== undefined, + }, opts)}`; + } + + get name() { return this[kName]; } + + close() { + if (this[kHandle] === undefined) + return; + this[kHandle].off('message', this[kOnMessage]); + this[kHandle].off('messageerror', this[kOnMessageError]); + this[kOnMessage] = undefined; + this[kOnMessageError] = undefined; + this[kHandle].close(); + this[kHandle] = undefined; + } + + postMessage(message) { + if (arguments.length === 0) + throw new ERR_MISSING_ARGS('message'); + if (this[kHandle] === undefined) + throw new DOMException('BroadcastChannel is closed.'); + if (this[kHandle].postMessage(message) === undefined) + throw new DOMException('Message could not be posted.'); + } + + ref() { + if (this[kHandle]) + this[kHandle].ref(); + return this; + } + + unref() { + if (this[kHandle]) + this[kHandle].unref(); + return this; + } +} + +defineEventHandler(BroadcastChannel.prototype, 'message'); +defineEventHandler(BroadcastChannel.prototype, 'messageerror'); + module.exports = { drainMessagePort, messageTypes, @@ -339,5 +417,6 @@ module.exports = { setupPortReferencing, ReadableWorkerStdio, WritableWorkerStdio, - createWorkerStdio + createWorkerStdio, + BroadcastChannel, }; |