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