11cb0ef41Sopenharmony_ci'use strict'; 21cb0ef41Sopenharmony_ci 31cb0ef41Sopenharmony_ciconst { 41cb0ef41Sopenharmony_ci ArrayPrototypeForEach, 51cb0ef41Sopenharmony_ci ArrayPrototypeMap, 61cb0ef41Sopenharmony_ci ArrayPrototypePush, 71cb0ef41Sopenharmony_ci FunctionPrototypeBind, 81cb0ef41Sopenharmony_ci FunctionPrototypeCall, 91cb0ef41Sopenharmony_ci ObjectAssign, 101cb0ef41Sopenharmony_ci ObjectCreate, 111cb0ef41Sopenharmony_ci ObjectDefineProperty, 121cb0ef41Sopenharmony_ci ObjectDefineProperties, 131cb0ef41Sopenharmony_ci ObjectGetOwnPropertyDescriptors, 141cb0ef41Sopenharmony_ci ObjectGetPrototypeOf, 151cb0ef41Sopenharmony_ci ObjectSetPrototypeOf, 161cb0ef41Sopenharmony_ci ObjectValues, 171cb0ef41Sopenharmony_ci ReflectApply, 181cb0ef41Sopenharmony_ci Symbol, 191cb0ef41Sopenharmony_ci SymbolFor, 201cb0ef41Sopenharmony_ci} = primordials; 211cb0ef41Sopenharmony_ci 221cb0ef41Sopenharmony_ciconst { 231cb0ef41Sopenharmony_ci kEmptyObject, 241cb0ef41Sopenharmony_ci kEnumerableProperty, 251cb0ef41Sopenharmony_ci setOwnProperty, 261cb0ef41Sopenharmony_ci} = require('internal/util'); 271cb0ef41Sopenharmony_ci 281cb0ef41Sopenharmony_ciconst { 291cb0ef41Sopenharmony_ci handle_onclose: handleOnCloseSymbol, 301cb0ef41Sopenharmony_ci oninit: onInitSymbol, 311cb0ef41Sopenharmony_ci no_message_symbol: noMessageSymbol, 321cb0ef41Sopenharmony_ci} = internalBinding('symbols'); 331cb0ef41Sopenharmony_ciconst { 341cb0ef41Sopenharmony_ci MessagePort, 351cb0ef41Sopenharmony_ci MessageChannel, 361cb0ef41Sopenharmony_ci broadcastChannel, 371cb0ef41Sopenharmony_ci drainMessagePort, 381cb0ef41Sopenharmony_ci moveMessagePortToContext, 391cb0ef41Sopenharmony_ci receiveMessageOnPort: receiveMessageOnPort_, 401cb0ef41Sopenharmony_ci stopMessagePort, 411cb0ef41Sopenharmony_ci checkMessagePort, 421cb0ef41Sopenharmony_ci DOMException, 431cb0ef41Sopenharmony_ci} = internalBinding('messaging'); 441cb0ef41Sopenharmony_ciconst { 451cb0ef41Sopenharmony_ci getEnvMessagePort, 461cb0ef41Sopenharmony_ci} = internalBinding('worker'); 471cb0ef41Sopenharmony_ci 481cb0ef41Sopenharmony_ciconst { Readable, Writable } = require('stream'); 491cb0ef41Sopenharmony_ciconst { 501cb0ef41Sopenharmony_ci Event, 511cb0ef41Sopenharmony_ci EventTarget, 521cb0ef41Sopenharmony_ci NodeEventTarget, 531cb0ef41Sopenharmony_ci defineEventHandler, 541cb0ef41Sopenharmony_ci initNodeEventTarget, 551cb0ef41Sopenharmony_ci kCreateEvent, 561cb0ef41Sopenharmony_ci kNewListener, 571cb0ef41Sopenharmony_ci kRemoveListener, 581cb0ef41Sopenharmony_ci} = require('internal/event_target'); 591cb0ef41Sopenharmony_ciconst { inspect } = require('internal/util/inspect'); 601cb0ef41Sopenharmony_ciconst { 611cb0ef41Sopenharmony_ci codes: { 621cb0ef41Sopenharmony_ci ERR_INVALID_ARG_TYPE, 631cb0ef41Sopenharmony_ci ERR_INVALID_THIS, 641cb0ef41Sopenharmony_ci ERR_MISSING_ARGS, 651cb0ef41Sopenharmony_ci }, 661cb0ef41Sopenharmony_ci} = require('internal/errors'); 671cb0ef41Sopenharmony_ci 681cb0ef41Sopenharmony_ciconst kData = Symbol('kData'); 691cb0ef41Sopenharmony_ciconst kHandle = Symbol('kHandle'); 701cb0ef41Sopenharmony_ciconst kIncrementsPortRef = Symbol('kIncrementsPortRef'); 711cb0ef41Sopenharmony_ciconst kLastEventId = Symbol('kLastEventId'); 721cb0ef41Sopenharmony_ciconst kName = Symbol('kName'); 731cb0ef41Sopenharmony_ciconst kOrigin = Symbol('kOrigin'); 741cb0ef41Sopenharmony_ciconst kOnMessage = Symbol('kOnMessage'); 751cb0ef41Sopenharmony_ciconst kOnMessageError = Symbol('kOnMessageError'); 761cb0ef41Sopenharmony_ciconst kPort = Symbol('kPort'); 771cb0ef41Sopenharmony_ciconst kPorts = Symbol('kPorts'); 781cb0ef41Sopenharmony_ciconst kWaitingStreams = Symbol('kWaitingStreams'); 791cb0ef41Sopenharmony_ciconst kWritableCallbacks = Symbol('kWritableCallbacks'); 801cb0ef41Sopenharmony_ciconst kSource = Symbol('kSource'); 811cb0ef41Sopenharmony_ciconst kStartedReading = Symbol('kStartedReading'); 821cb0ef41Sopenharmony_ciconst kStdioWantsMoreDataCallback = Symbol('kStdioWantsMoreDataCallback'); 831cb0ef41Sopenharmony_ciconst kCurrentlyReceivingPorts = 841cb0ef41Sopenharmony_ci SymbolFor('nodejs.internal.kCurrentlyReceivingPorts'); 851cb0ef41Sopenharmony_ciconst kType = Symbol('kType'); 861cb0ef41Sopenharmony_ci 871cb0ef41Sopenharmony_ciconst messageTypes = { 881cb0ef41Sopenharmony_ci UP_AND_RUNNING: 'upAndRunning', 891cb0ef41Sopenharmony_ci COULD_NOT_SERIALIZE_ERROR: 'couldNotSerializeError', 901cb0ef41Sopenharmony_ci ERROR_MESSAGE: 'errorMessage', 911cb0ef41Sopenharmony_ci STDIO_PAYLOAD: 'stdioPayload', 921cb0ef41Sopenharmony_ci STDIO_WANTS_MORE_DATA: 'stdioWantsMoreData', 931cb0ef41Sopenharmony_ci LOAD_SCRIPT: 'loadScript', 941cb0ef41Sopenharmony_ci}; 951cb0ef41Sopenharmony_ci 961cb0ef41Sopenharmony_ci// We have to mess with the MessagePort prototype a bit, so that a) we can make 971cb0ef41Sopenharmony_ci// it inherit from NodeEventTarget, even though it is a C++ class, and b) we do 981cb0ef41Sopenharmony_ci// not provide methods that are not present in the Browser and not documented 991cb0ef41Sopenharmony_ci// on our side (e.g. stopMessagePort). 1001cb0ef41Sopenharmony_ciconst messagePortPrototypePropertyDescriptors = ObjectGetOwnPropertyDescriptors(MessagePort.prototype); 1011cb0ef41Sopenharmony_ciconst propertiesValues = ObjectValues(messagePortPrototypePropertyDescriptors); 1021cb0ef41Sopenharmony_cifor (let i = 0; i < propertiesValues.length; i++) { 1031cb0ef41Sopenharmony_ci // We want to use null-prototype objects to not rely on globally mutable 1041cb0ef41Sopenharmony_ci // %Object.prototype%. 1051cb0ef41Sopenharmony_ci ObjectSetPrototypeOf(propertiesValues[i], null); 1061cb0ef41Sopenharmony_ci} 1071cb0ef41Sopenharmony_ci// Save a copy of the original set of methods as a shallow clone. 1081cb0ef41Sopenharmony_ciconst MessagePortPrototype = ObjectCreate( 1091cb0ef41Sopenharmony_ci ObjectGetPrototypeOf(MessagePort.prototype), 1101cb0ef41Sopenharmony_ci messagePortPrototypePropertyDescriptors); 1111cb0ef41Sopenharmony_ci// Set up the new inheritance chain. 1121cb0ef41Sopenharmony_ciObjectSetPrototypeOf(MessagePort, NodeEventTarget); 1131cb0ef41Sopenharmony_ciObjectSetPrototypeOf(MessagePort.prototype, NodeEventTarget.prototype); 1141cb0ef41Sopenharmony_ci// Copy methods that are inherited from HandleWrap, because 1151cb0ef41Sopenharmony_ci// changing the prototype of MessagePort.prototype implicitly removed them. 1161cb0ef41Sopenharmony_ciMessagePort.prototype.ref = MessagePortPrototype.ref; 1171cb0ef41Sopenharmony_ciMessagePort.prototype.unref = MessagePortPrototype.unref; 1181cb0ef41Sopenharmony_ciMessagePort.prototype.hasRef = function() { 1191cb0ef41Sopenharmony_ci return !!FunctionPrototypeCall(MessagePortPrototype.hasRef, this); 1201cb0ef41Sopenharmony_ci}; 1211cb0ef41Sopenharmony_ci 1221cb0ef41Sopenharmony_cifunction validateMessagePort(port, name) { 1231cb0ef41Sopenharmony_ci if (!checkMessagePort(port)) 1241cb0ef41Sopenharmony_ci throw new ERR_INVALID_ARG_TYPE(name, 'MessagePort', port); 1251cb0ef41Sopenharmony_ci} 1261cb0ef41Sopenharmony_ci 1271cb0ef41Sopenharmony_cifunction isMessageEvent(value) { 1281cb0ef41Sopenharmony_ci return value != null && kData in value; 1291cb0ef41Sopenharmony_ci} 1301cb0ef41Sopenharmony_ci 1311cb0ef41Sopenharmony_ciclass MessageEvent extends Event { 1321cb0ef41Sopenharmony_ci constructor(type, { 1331cb0ef41Sopenharmony_ci data = null, 1341cb0ef41Sopenharmony_ci origin = '', 1351cb0ef41Sopenharmony_ci lastEventId = '', 1361cb0ef41Sopenharmony_ci source = null, 1371cb0ef41Sopenharmony_ci ports = [], 1381cb0ef41Sopenharmony_ci } = kEmptyObject) { 1391cb0ef41Sopenharmony_ci super(type); 1401cb0ef41Sopenharmony_ci this[kData] = data; 1411cb0ef41Sopenharmony_ci this[kOrigin] = `${origin}`; 1421cb0ef41Sopenharmony_ci this[kLastEventId] = `${lastEventId}`; 1431cb0ef41Sopenharmony_ci this[kSource] = source; 1441cb0ef41Sopenharmony_ci this[kPorts] = [...ports]; 1451cb0ef41Sopenharmony_ci 1461cb0ef41Sopenharmony_ci if (this[kSource] !== null) 1471cb0ef41Sopenharmony_ci validateMessagePort(this[kSource], 'init.source'); 1481cb0ef41Sopenharmony_ci for (let i = 0; i < this[kPorts].length; i++) 1491cb0ef41Sopenharmony_ci validateMessagePort(this[kPorts][i], `init.ports[${i}]`); 1501cb0ef41Sopenharmony_ci } 1511cb0ef41Sopenharmony_ci} 1521cb0ef41Sopenharmony_ci 1531cb0ef41Sopenharmony_ciObjectDefineProperties(MessageEvent.prototype, { 1541cb0ef41Sopenharmony_ci data: { 1551cb0ef41Sopenharmony_ci __proto__: null, 1561cb0ef41Sopenharmony_ci get() { 1571cb0ef41Sopenharmony_ci if (!isMessageEvent(this)) 1581cb0ef41Sopenharmony_ci throw new ERR_INVALID_THIS('MessageEvent'); 1591cb0ef41Sopenharmony_ci return this[kData]; 1601cb0ef41Sopenharmony_ci }, 1611cb0ef41Sopenharmony_ci enumerable: true, 1621cb0ef41Sopenharmony_ci configurable: true, 1631cb0ef41Sopenharmony_ci set: undefined, 1641cb0ef41Sopenharmony_ci }, 1651cb0ef41Sopenharmony_ci origin: { 1661cb0ef41Sopenharmony_ci __proto__: null, 1671cb0ef41Sopenharmony_ci get() { 1681cb0ef41Sopenharmony_ci if (!isMessageEvent(this)) 1691cb0ef41Sopenharmony_ci throw new ERR_INVALID_THIS('MessageEvent'); 1701cb0ef41Sopenharmony_ci return this[kOrigin]; 1711cb0ef41Sopenharmony_ci }, 1721cb0ef41Sopenharmony_ci enumerable: true, 1731cb0ef41Sopenharmony_ci configurable: true, 1741cb0ef41Sopenharmony_ci set: undefined, 1751cb0ef41Sopenharmony_ci }, 1761cb0ef41Sopenharmony_ci lastEventId: { 1771cb0ef41Sopenharmony_ci __proto__: null, 1781cb0ef41Sopenharmony_ci get() { 1791cb0ef41Sopenharmony_ci if (!isMessageEvent(this)) 1801cb0ef41Sopenharmony_ci throw new ERR_INVALID_THIS('MessageEvent'); 1811cb0ef41Sopenharmony_ci return this[kLastEventId]; 1821cb0ef41Sopenharmony_ci }, 1831cb0ef41Sopenharmony_ci enumerable: true, 1841cb0ef41Sopenharmony_ci configurable: true, 1851cb0ef41Sopenharmony_ci set: undefined, 1861cb0ef41Sopenharmony_ci }, 1871cb0ef41Sopenharmony_ci source: { 1881cb0ef41Sopenharmony_ci __proto__: null, 1891cb0ef41Sopenharmony_ci get() { 1901cb0ef41Sopenharmony_ci if (!isMessageEvent(this)) 1911cb0ef41Sopenharmony_ci throw new ERR_INVALID_THIS('MessageEvent'); 1921cb0ef41Sopenharmony_ci return this[kSource]; 1931cb0ef41Sopenharmony_ci }, 1941cb0ef41Sopenharmony_ci enumerable: true, 1951cb0ef41Sopenharmony_ci configurable: true, 1961cb0ef41Sopenharmony_ci set: undefined, 1971cb0ef41Sopenharmony_ci }, 1981cb0ef41Sopenharmony_ci ports: { 1991cb0ef41Sopenharmony_ci __proto__: null, 2001cb0ef41Sopenharmony_ci get() { 2011cb0ef41Sopenharmony_ci if (!isMessageEvent(this)) 2021cb0ef41Sopenharmony_ci throw new ERR_INVALID_THIS('MessageEvent'); 2031cb0ef41Sopenharmony_ci return this[kPorts]; 2041cb0ef41Sopenharmony_ci }, 2051cb0ef41Sopenharmony_ci enumerable: true, 2061cb0ef41Sopenharmony_ci configurable: true, 2071cb0ef41Sopenharmony_ci set: undefined, 2081cb0ef41Sopenharmony_ci }, 2091cb0ef41Sopenharmony_ci}); 2101cb0ef41Sopenharmony_ci 2111cb0ef41Sopenharmony_ciconst originalCreateEvent = EventTarget.prototype[kCreateEvent]; 2121cb0ef41Sopenharmony_ciObjectDefineProperty( 2131cb0ef41Sopenharmony_ci MessagePort.prototype, 2141cb0ef41Sopenharmony_ci kCreateEvent, 2151cb0ef41Sopenharmony_ci { 2161cb0ef41Sopenharmony_ci __proto__: null, 2171cb0ef41Sopenharmony_ci value: function(data, type) { 2181cb0ef41Sopenharmony_ci if (type !== 'message' && type !== 'messageerror') { 2191cb0ef41Sopenharmony_ci return ReflectApply(originalCreateEvent, this, arguments); 2201cb0ef41Sopenharmony_ci } 2211cb0ef41Sopenharmony_ci const ports = this[kCurrentlyReceivingPorts]; 2221cb0ef41Sopenharmony_ci this[kCurrentlyReceivingPorts] = undefined; 2231cb0ef41Sopenharmony_ci return new MessageEvent(type, { data, ports }); 2241cb0ef41Sopenharmony_ci }, 2251cb0ef41Sopenharmony_ci configurable: false, 2261cb0ef41Sopenharmony_ci writable: false, 2271cb0ef41Sopenharmony_ci enumerable: false, 2281cb0ef41Sopenharmony_ci }); 2291cb0ef41Sopenharmony_ci 2301cb0ef41Sopenharmony_ci// This is called from inside the `MessagePort` constructor. 2311cb0ef41Sopenharmony_cifunction oninit() { 2321cb0ef41Sopenharmony_ci initNodeEventTarget(this); 2331cb0ef41Sopenharmony_ci setupPortReferencing(this, this, 'message'); 2341cb0ef41Sopenharmony_ci this[kCurrentlyReceivingPorts] = undefined; 2351cb0ef41Sopenharmony_ci} 2361cb0ef41Sopenharmony_ci 2371cb0ef41Sopenharmony_cidefineEventHandler(MessagePort.prototype, 'message'); 2381cb0ef41Sopenharmony_cidefineEventHandler(MessagePort.prototype, 'messageerror'); 2391cb0ef41Sopenharmony_ci 2401cb0ef41Sopenharmony_ciObjectDefineProperty(MessagePort.prototype, onInitSymbol, { 2411cb0ef41Sopenharmony_ci __proto__: null, 2421cb0ef41Sopenharmony_ci enumerable: true, 2431cb0ef41Sopenharmony_ci writable: false, 2441cb0ef41Sopenharmony_ci value: oninit, 2451cb0ef41Sopenharmony_ci}); 2461cb0ef41Sopenharmony_ci 2471cb0ef41Sopenharmony_ciclass MessagePortCloseEvent extends Event { 2481cb0ef41Sopenharmony_ci constructor() { 2491cb0ef41Sopenharmony_ci super('close'); 2501cb0ef41Sopenharmony_ci } 2511cb0ef41Sopenharmony_ci} 2521cb0ef41Sopenharmony_ci 2531cb0ef41Sopenharmony_ci// This is called after the underlying `uv_async_t` has been closed. 2541cb0ef41Sopenharmony_cifunction onclose() { 2551cb0ef41Sopenharmony_ci this.dispatchEvent(new MessagePortCloseEvent()); 2561cb0ef41Sopenharmony_ci} 2571cb0ef41Sopenharmony_ci 2581cb0ef41Sopenharmony_ciObjectDefineProperty(MessagePort.prototype, handleOnCloseSymbol, { 2591cb0ef41Sopenharmony_ci __proto__: null, 2601cb0ef41Sopenharmony_ci enumerable: false, 2611cb0ef41Sopenharmony_ci writable: false, 2621cb0ef41Sopenharmony_ci value: onclose, 2631cb0ef41Sopenharmony_ci}); 2641cb0ef41Sopenharmony_ci 2651cb0ef41Sopenharmony_ciMessagePort.prototype.close = function(cb) { 2661cb0ef41Sopenharmony_ci if (typeof cb === 'function') 2671cb0ef41Sopenharmony_ci this.once('close', cb); 2681cb0ef41Sopenharmony_ci FunctionPrototypeCall(MessagePortPrototype.close, this); 2691cb0ef41Sopenharmony_ci}; 2701cb0ef41Sopenharmony_ci 2711cb0ef41Sopenharmony_ciObjectDefineProperty(MessagePort.prototype, inspect.custom, { 2721cb0ef41Sopenharmony_ci __proto__: null, 2731cb0ef41Sopenharmony_ci enumerable: false, 2741cb0ef41Sopenharmony_ci writable: false, 2751cb0ef41Sopenharmony_ci value: function inspect() { // eslint-disable-line func-name-matching 2761cb0ef41Sopenharmony_ci let ref; 2771cb0ef41Sopenharmony_ci try { 2781cb0ef41Sopenharmony_ci // This may throw when `this` does not refer to a native object, 2791cb0ef41Sopenharmony_ci // e.g. when accessing the prototype directly. 2801cb0ef41Sopenharmony_ci ref = FunctionPrototypeCall(MessagePortPrototype.hasRef, this); 2811cb0ef41Sopenharmony_ci } catch { return this; } 2821cb0ef41Sopenharmony_ci return ObjectAssign(ObjectCreate(MessagePort.prototype), 2831cb0ef41Sopenharmony_ci ref === undefined ? { 2841cb0ef41Sopenharmony_ci active: false, 2851cb0ef41Sopenharmony_ci } : { 2861cb0ef41Sopenharmony_ci active: true, 2871cb0ef41Sopenharmony_ci refed: ref, 2881cb0ef41Sopenharmony_ci }, 2891cb0ef41Sopenharmony_ci this); 2901cb0ef41Sopenharmony_ci }, 2911cb0ef41Sopenharmony_ci}); 2921cb0ef41Sopenharmony_ci 2931cb0ef41Sopenharmony_cifunction setupPortReferencing(port, eventEmitter, eventName) { 2941cb0ef41Sopenharmony_ci // Keep track of whether there are any workerMessage listeners: 2951cb0ef41Sopenharmony_ci // If there are some, ref() the channel so it keeps the event loop alive. 2961cb0ef41Sopenharmony_ci // If there are none or all are removed, unref() the channel so the worker 2971cb0ef41Sopenharmony_ci // can shutdown gracefully. 2981cb0ef41Sopenharmony_ci port.unref(); 2991cb0ef41Sopenharmony_ci eventEmitter.on('newListener', function(name) { 3001cb0ef41Sopenharmony_ci if (name === eventName) newListener(eventEmitter.listenerCount(name)); 3011cb0ef41Sopenharmony_ci }); 3021cb0ef41Sopenharmony_ci eventEmitter.on('removeListener', function(name) { 3031cb0ef41Sopenharmony_ci if (name === eventName) removeListener(eventEmitter.listenerCount(name)); 3041cb0ef41Sopenharmony_ci }); 3051cb0ef41Sopenharmony_ci const origNewListener = eventEmitter[kNewListener]; 3061cb0ef41Sopenharmony_ci setOwnProperty(eventEmitter, kNewListener, function(size, type, ...args) { 3071cb0ef41Sopenharmony_ci if (type === eventName) newListener(size - 1); 3081cb0ef41Sopenharmony_ci return ReflectApply(origNewListener, this, arguments); 3091cb0ef41Sopenharmony_ci }); 3101cb0ef41Sopenharmony_ci const origRemoveListener = eventEmitter[kRemoveListener]; 3111cb0ef41Sopenharmony_ci setOwnProperty(eventEmitter, kRemoveListener, function(size, type, ...args) { 3121cb0ef41Sopenharmony_ci if (type === eventName) removeListener(size); 3131cb0ef41Sopenharmony_ci return ReflectApply(origRemoveListener, this, arguments); 3141cb0ef41Sopenharmony_ci }); 3151cb0ef41Sopenharmony_ci 3161cb0ef41Sopenharmony_ci function newListener(size) { 3171cb0ef41Sopenharmony_ci if (size === 0) { 3181cb0ef41Sopenharmony_ci port.ref(); 3191cb0ef41Sopenharmony_ci FunctionPrototypeCall(MessagePortPrototype.start, port); 3201cb0ef41Sopenharmony_ci } 3211cb0ef41Sopenharmony_ci } 3221cb0ef41Sopenharmony_ci 3231cb0ef41Sopenharmony_ci function removeListener(size) { 3241cb0ef41Sopenharmony_ci if (size === 0) { 3251cb0ef41Sopenharmony_ci stopMessagePort(port); 3261cb0ef41Sopenharmony_ci port.unref(); 3271cb0ef41Sopenharmony_ci } 3281cb0ef41Sopenharmony_ci } 3291cb0ef41Sopenharmony_ci} 3301cb0ef41Sopenharmony_ci 3311cb0ef41Sopenharmony_ci 3321cb0ef41Sopenharmony_ciclass ReadableWorkerStdio extends Readable { 3331cb0ef41Sopenharmony_ci constructor(port, name) { 3341cb0ef41Sopenharmony_ci super(); 3351cb0ef41Sopenharmony_ci this[kPort] = port; 3361cb0ef41Sopenharmony_ci this[kName] = name; 3371cb0ef41Sopenharmony_ci this[kIncrementsPortRef] = true; 3381cb0ef41Sopenharmony_ci this[kStartedReading] = false; 3391cb0ef41Sopenharmony_ci this.on('end', () => { 3401cb0ef41Sopenharmony_ci if (this[kStartedReading] && this[kIncrementsPortRef]) { 3411cb0ef41Sopenharmony_ci if (--this[kPort][kWaitingStreams] === 0) 3421cb0ef41Sopenharmony_ci this[kPort].unref(); 3431cb0ef41Sopenharmony_ci } 3441cb0ef41Sopenharmony_ci }); 3451cb0ef41Sopenharmony_ci } 3461cb0ef41Sopenharmony_ci 3471cb0ef41Sopenharmony_ci _read() { 3481cb0ef41Sopenharmony_ci if (!this[kStartedReading] && this[kIncrementsPortRef]) { 3491cb0ef41Sopenharmony_ci this[kStartedReading] = true; 3501cb0ef41Sopenharmony_ci if (this[kPort][kWaitingStreams]++ === 0) 3511cb0ef41Sopenharmony_ci this[kPort].ref(); 3521cb0ef41Sopenharmony_ci } 3531cb0ef41Sopenharmony_ci 3541cb0ef41Sopenharmony_ci this[kPort].postMessage({ 3551cb0ef41Sopenharmony_ci type: messageTypes.STDIO_WANTS_MORE_DATA, 3561cb0ef41Sopenharmony_ci stream: this[kName], 3571cb0ef41Sopenharmony_ci }); 3581cb0ef41Sopenharmony_ci } 3591cb0ef41Sopenharmony_ci} 3601cb0ef41Sopenharmony_ci 3611cb0ef41Sopenharmony_ciclass WritableWorkerStdio extends Writable { 3621cb0ef41Sopenharmony_ci constructor(port, name) { 3631cb0ef41Sopenharmony_ci super({ decodeStrings: false }); 3641cb0ef41Sopenharmony_ci this[kPort] = port; 3651cb0ef41Sopenharmony_ci this[kName] = name; 3661cb0ef41Sopenharmony_ci this[kWritableCallbacks] = []; 3671cb0ef41Sopenharmony_ci } 3681cb0ef41Sopenharmony_ci 3691cb0ef41Sopenharmony_ci _writev(chunks, cb) { 3701cb0ef41Sopenharmony_ci this[kPort].postMessage({ 3711cb0ef41Sopenharmony_ci type: messageTypes.STDIO_PAYLOAD, 3721cb0ef41Sopenharmony_ci stream: this[kName], 3731cb0ef41Sopenharmony_ci chunks: ArrayPrototypeMap(chunks, 3741cb0ef41Sopenharmony_ci ({ chunk, encoding }) => ({ chunk, encoding })), 3751cb0ef41Sopenharmony_ci }); 3761cb0ef41Sopenharmony_ci ArrayPrototypePush(this[kWritableCallbacks], cb); 3771cb0ef41Sopenharmony_ci if (this[kPort][kWaitingStreams]++ === 0) 3781cb0ef41Sopenharmony_ci this[kPort].ref(); 3791cb0ef41Sopenharmony_ci } 3801cb0ef41Sopenharmony_ci 3811cb0ef41Sopenharmony_ci _final(cb) { 3821cb0ef41Sopenharmony_ci this[kPort].postMessage({ 3831cb0ef41Sopenharmony_ci type: messageTypes.STDIO_PAYLOAD, 3841cb0ef41Sopenharmony_ci stream: this[kName], 3851cb0ef41Sopenharmony_ci chunks: [ { chunk: null, encoding: '' } ], 3861cb0ef41Sopenharmony_ci }); 3871cb0ef41Sopenharmony_ci cb(); 3881cb0ef41Sopenharmony_ci } 3891cb0ef41Sopenharmony_ci 3901cb0ef41Sopenharmony_ci [kStdioWantsMoreDataCallback]() { 3911cb0ef41Sopenharmony_ci const cbs = this[kWritableCallbacks]; 3921cb0ef41Sopenharmony_ci this[kWritableCallbacks] = []; 3931cb0ef41Sopenharmony_ci ArrayPrototypeForEach(cbs, (cb) => cb()); 3941cb0ef41Sopenharmony_ci if ((this[kPort][kWaitingStreams] -= cbs.length) === 0) 3951cb0ef41Sopenharmony_ci this[kPort].unref(); 3961cb0ef41Sopenharmony_ci } 3971cb0ef41Sopenharmony_ci} 3981cb0ef41Sopenharmony_ci 3991cb0ef41Sopenharmony_cifunction createWorkerStdio() { 4001cb0ef41Sopenharmony_ci const port = getEnvMessagePort(); 4011cb0ef41Sopenharmony_ci port[kWaitingStreams] = 0; 4021cb0ef41Sopenharmony_ci return { 4031cb0ef41Sopenharmony_ci stdin: new ReadableWorkerStdio(port, 'stdin'), 4041cb0ef41Sopenharmony_ci stdout: new WritableWorkerStdio(port, 'stdout'), 4051cb0ef41Sopenharmony_ci stderr: new WritableWorkerStdio(port, 'stderr'), 4061cb0ef41Sopenharmony_ci }; 4071cb0ef41Sopenharmony_ci} 4081cb0ef41Sopenharmony_ci 4091cb0ef41Sopenharmony_cifunction receiveMessageOnPort(port) { 4101cb0ef41Sopenharmony_ci const message = receiveMessageOnPort_(port?.[kHandle] ?? port); 4111cb0ef41Sopenharmony_ci if (message === noMessageSymbol) return undefined; 4121cb0ef41Sopenharmony_ci return { message }; 4131cb0ef41Sopenharmony_ci} 4141cb0ef41Sopenharmony_ci 4151cb0ef41Sopenharmony_cifunction onMessageEvent(type, data) { 4161cb0ef41Sopenharmony_ci this.dispatchEvent(new MessageEvent(type, { data })); 4171cb0ef41Sopenharmony_ci} 4181cb0ef41Sopenharmony_ci 4191cb0ef41Sopenharmony_cifunction isBroadcastChannel(value) { 4201cb0ef41Sopenharmony_ci return value?.[kType] === 'BroadcastChannel'; 4211cb0ef41Sopenharmony_ci} 4221cb0ef41Sopenharmony_ci 4231cb0ef41Sopenharmony_ciclass BroadcastChannel extends EventTarget { 4241cb0ef41Sopenharmony_ci /** 4251cb0ef41Sopenharmony_ci * @param {string} name 4261cb0ef41Sopenharmony_ci */ 4271cb0ef41Sopenharmony_ci constructor(name) { 4281cb0ef41Sopenharmony_ci if (arguments.length === 0) 4291cb0ef41Sopenharmony_ci throw new ERR_MISSING_ARGS('name'); 4301cb0ef41Sopenharmony_ci super(); 4311cb0ef41Sopenharmony_ci this[kType] = 'BroadcastChannel'; 4321cb0ef41Sopenharmony_ci this[kName] = `${name}`; 4331cb0ef41Sopenharmony_ci this[kHandle] = broadcastChannel(this[kName]); 4341cb0ef41Sopenharmony_ci this[kOnMessage] = FunctionPrototypeBind(onMessageEvent, this, 'message'); 4351cb0ef41Sopenharmony_ci this[kOnMessageError] = 4361cb0ef41Sopenharmony_ci FunctionPrototypeBind(onMessageEvent, this, 'messageerror'); 4371cb0ef41Sopenharmony_ci this[kHandle].on('message', this[kOnMessage]); 4381cb0ef41Sopenharmony_ci this[kHandle].on('messageerror', this[kOnMessageError]); 4391cb0ef41Sopenharmony_ci } 4401cb0ef41Sopenharmony_ci 4411cb0ef41Sopenharmony_ci [inspect.custom](depth, options) { 4421cb0ef41Sopenharmony_ci if (!isBroadcastChannel(this)) 4431cb0ef41Sopenharmony_ci throw new ERR_INVALID_THIS('BroadcastChannel'); 4441cb0ef41Sopenharmony_ci if (depth < 0) 4451cb0ef41Sopenharmony_ci return 'BroadcastChannel'; 4461cb0ef41Sopenharmony_ci 4471cb0ef41Sopenharmony_ci const opts = { 4481cb0ef41Sopenharmony_ci ...options, 4491cb0ef41Sopenharmony_ci depth: options.depth == null ? null : options.depth - 1, 4501cb0ef41Sopenharmony_ci }; 4511cb0ef41Sopenharmony_ci 4521cb0ef41Sopenharmony_ci return `BroadcastChannel ${inspect({ 4531cb0ef41Sopenharmony_ci name: this[kName], 4541cb0ef41Sopenharmony_ci active: this[kHandle] !== undefined, 4551cb0ef41Sopenharmony_ci }, opts)}`; 4561cb0ef41Sopenharmony_ci } 4571cb0ef41Sopenharmony_ci 4581cb0ef41Sopenharmony_ci /** 4591cb0ef41Sopenharmony_ci * @type {string} 4601cb0ef41Sopenharmony_ci */ 4611cb0ef41Sopenharmony_ci get name() { 4621cb0ef41Sopenharmony_ci if (!isBroadcastChannel(this)) 4631cb0ef41Sopenharmony_ci throw new ERR_INVALID_THIS('BroadcastChannel'); 4641cb0ef41Sopenharmony_ci return this[kName]; 4651cb0ef41Sopenharmony_ci } 4661cb0ef41Sopenharmony_ci 4671cb0ef41Sopenharmony_ci /** 4681cb0ef41Sopenharmony_ci * @returns {void} 4691cb0ef41Sopenharmony_ci */ 4701cb0ef41Sopenharmony_ci close() { 4711cb0ef41Sopenharmony_ci if (!isBroadcastChannel(this)) 4721cb0ef41Sopenharmony_ci throw new ERR_INVALID_THIS('BroadcastChannel'); 4731cb0ef41Sopenharmony_ci if (this[kHandle] === undefined) 4741cb0ef41Sopenharmony_ci return; 4751cb0ef41Sopenharmony_ci this[kHandle].off('message', this[kOnMessage]); 4761cb0ef41Sopenharmony_ci this[kHandle].off('messageerror', this[kOnMessageError]); 4771cb0ef41Sopenharmony_ci this[kOnMessage] = undefined; 4781cb0ef41Sopenharmony_ci this[kOnMessageError] = undefined; 4791cb0ef41Sopenharmony_ci this[kHandle].close(); 4801cb0ef41Sopenharmony_ci this[kHandle] = undefined; 4811cb0ef41Sopenharmony_ci } 4821cb0ef41Sopenharmony_ci 4831cb0ef41Sopenharmony_ci /** 4841cb0ef41Sopenharmony_ci * 4851cb0ef41Sopenharmony_ci * @param {any} message 4861cb0ef41Sopenharmony_ci * @returns {void} 4871cb0ef41Sopenharmony_ci */ 4881cb0ef41Sopenharmony_ci postMessage(message) { 4891cb0ef41Sopenharmony_ci if (!isBroadcastChannel(this)) 4901cb0ef41Sopenharmony_ci throw new ERR_INVALID_THIS('BroadcastChannel'); 4911cb0ef41Sopenharmony_ci if (arguments.length === 0) 4921cb0ef41Sopenharmony_ci throw new ERR_MISSING_ARGS('message'); 4931cb0ef41Sopenharmony_ci if (this[kHandle] === undefined) 4941cb0ef41Sopenharmony_ci throw new DOMException('BroadcastChannel is closed.'); 4951cb0ef41Sopenharmony_ci if (this[kHandle].postMessage(message) === undefined) 4961cb0ef41Sopenharmony_ci throw new DOMException('Message could not be posted.'); 4971cb0ef41Sopenharmony_ci } 4981cb0ef41Sopenharmony_ci 4991cb0ef41Sopenharmony_ci // The ref() method is Node.js specific and not part of the standard 5001cb0ef41Sopenharmony_ci // BroadcastChannel API definition. Typically we shouldn't extend Web 5011cb0ef41Sopenharmony_ci // Platform APIs with Node.js specific methods but ref and unref 5021cb0ef41Sopenharmony_ci // are a bit special. 5031cb0ef41Sopenharmony_ci /** 5041cb0ef41Sopenharmony_ci * @returns {BroadcastChannel} 5051cb0ef41Sopenharmony_ci */ 5061cb0ef41Sopenharmony_ci ref() { 5071cb0ef41Sopenharmony_ci if (!isBroadcastChannel(this)) 5081cb0ef41Sopenharmony_ci throw new ERR_INVALID_THIS('BroadcastChannel'); 5091cb0ef41Sopenharmony_ci if (this[kHandle]) 5101cb0ef41Sopenharmony_ci this[kHandle].ref(); 5111cb0ef41Sopenharmony_ci return this; 5121cb0ef41Sopenharmony_ci } 5131cb0ef41Sopenharmony_ci 5141cb0ef41Sopenharmony_ci // The unref() method is Node.js specific and not part of the standard 5151cb0ef41Sopenharmony_ci // BroadcastChannel API definition. Typically we shouldn't extend Web 5161cb0ef41Sopenharmony_ci // Platform APIs with Node.js specific methods but ref and unref 5171cb0ef41Sopenharmony_ci // are a bit special. 5181cb0ef41Sopenharmony_ci /** 5191cb0ef41Sopenharmony_ci * @returns {BroadcastChannel} 5201cb0ef41Sopenharmony_ci */ 5211cb0ef41Sopenharmony_ci unref() { 5221cb0ef41Sopenharmony_ci if (!isBroadcastChannel(this)) 5231cb0ef41Sopenharmony_ci throw new ERR_INVALID_THIS('BroadcastChannel'); 5241cb0ef41Sopenharmony_ci if (this[kHandle]) 5251cb0ef41Sopenharmony_ci this[kHandle].unref(); 5261cb0ef41Sopenharmony_ci return this; 5271cb0ef41Sopenharmony_ci } 5281cb0ef41Sopenharmony_ci} 5291cb0ef41Sopenharmony_ci 5301cb0ef41Sopenharmony_ciObjectDefineProperties(BroadcastChannel.prototype, { 5311cb0ef41Sopenharmony_ci name: kEnumerableProperty, 5321cb0ef41Sopenharmony_ci close: kEnumerableProperty, 5331cb0ef41Sopenharmony_ci postMessage: kEnumerableProperty, 5341cb0ef41Sopenharmony_ci}); 5351cb0ef41Sopenharmony_ci 5361cb0ef41Sopenharmony_cidefineEventHandler(BroadcastChannel.prototype, 'message'); 5371cb0ef41Sopenharmony_cidefineEventHandler(BroadcastChannel.prototype, 'messageerror'); 5381cb0ef41Sopenharmony_ci 5391cb0ef41Sopenharmony_cimodule.exports = { 5401cb0ef41Sopenharmony_ci drainMessagePort, 5411cb0ef41Sopenharmony_ci messageTypes, 5421cb0ef41Sopenharmony_ci kPort, 5431cb0ef41Sopenharmony_ci kIncrementsPortRef, 5441cb0ef41Sopenharmony_ci kWaitingStreams, 5451cb0ef41Sopenharmony_ci kStdioWantsMoreDataCallback, 5461cb0ef41Sopenharmony_ci moveMessagePortToContext, 5471cb0ef41Sopenharmony_ci MessagePort, 5481cb0ef41Sopenharmony_ci MessageChannel, 5491cb0ef41Sopenharmony_ci MessageEvent, 5501cb0ef41Sopenharmony_ci receiveMessageOnPort, 5511cb0ef41Sopenharmony_ci setupPortReferencing, 5521cb0ef41Sopenharmony_ci ReadableWorkerStdio, 5531cb0ef41Sopenharmony_ci WritableWorkerStdio, 5541cb0ef41Sopenharmony_ci createWorkerStdio, 5551cb0ef41Sopenharmony_ci BroadcastChannel, 5561cb0ef41Sopenharmony_ci}; 557