11cb0ef41Sopenharmony_ci'use strict'; 21cb0ef41Sopenharmony_ci 31cb0ef41Sopenharmony_ciconst { 41cb0ef41Sopenharmony_ci ObjectDefineProperties, 51cb0ef41Sopenharmony_ci PromiseResolve, 61cb0ef41Sopenharmony_ci ReflectConstruct, 71cb0ef41Sopenharmony_ci} = primordials; 81cb0ef41Sopenharmony_ci 91cb0ef41Sopenharmony_ciconst { 101cb0ef41Sopenharmony_ci kState, 111cb0ef41Sopenharmony_ci setPromiseHandled, 121cb0ef41Sopenharmony_ci} = require('internal/webstreams/util'); 131cb0ef41Sopenharmony_ci 141cb0ef41Sopenharmony_ciconst { 151cb0ef41Sopenharmony_ci DOMException, 161cb0ef41Sopenharmony_ci} = internalBinding('messaging'); 171cb0ef41Sopenharmony_ci 181cb0ef41Sopenharmony_ciconst { 191cb0ef41Sopenharmony_ci ReadableStream, 201cb0ef41Sopenharmony_ci readableStreamDefaultControllerEnqueue, 211cb0ef41Sopenharmony_ci readableStreamDefaultControllerClose, 221cb0ef41Sopenharmony_ci readableStreamDefaultControllerError, 231cb0ef41Sopenharmony_ci readableStreamPipeTo, 241cb0ef41Sopenharmony_ci} = require('internal/webstreams/readablestream'); 251cb0ef41Sopenharmony_ci 261cb0ef41Sopenharmony_ciconst { 271cb0ef41Sopenharmony_ci WritableStream, 281cb0ef41Sopenharmony_ci writableStreamDefaultControllerErrorIfNeeded, 291cb0ef41Sopenharmony_ci} = require('internal/webstreams/writablestream'); 301cb0ef41Sopenharmony_ci 311cb0ef41Sopenharmony_ciconst { 321cb0ef41Sopenharmony_ci createDeferredPromise, 331cb0ef41Sopenharmony_ci} = require('internal/util'); 341cb0ef41Sopenharmony_ci 351cb0ef41Sopenharmony_ciconst assert = require('internal/assert'); 361cb0ef41Sopenharmony_ci 371cb0ef41Sopenharmony_ciconst { 381cb0ef41Sopenharmony_ci makeTransferable, 391cb0ef41Sopenharmony_ci kClone, 401cb0ef41Sopenharmony_ci kDeserialize, 411cb0ef41Sopenharmony_ci} = require('internal/worker/js_transferable'); 421cb0ef41Sopenharmony_ci 431cb0ef41Sopenharmony_ci// This class is a bit of a hack. The Node.js implementation of 441cb0ef41Sopenharmony_ci// DOMException is not transferable/cloneable. This provides us 451cb0ef41Sopenharmony_ci// with a variant that is. Unfortunately, it means playing around 461cb0ef41Sopenharmony_ci// a bit with the message, name, and code properties and the 471cb0ef41Sopenharmony_ci// prototype. We can revisit this if DOMException is ever made 481cb0ef41Sopenharmony_ci// properly cloneable. 491cb0ef41Sopenharmony_ciclass CloneableDOMException extends DOMException { 501cb0ef41Sopenharmony_ci constructor(message, name) { 511cb0ef41Sopenharmony_ci super(message, name); 521cb0ef41Sopenharmony_ci this[kDeserialize]({ 531cb0ef41Sopenharmony_ci message: this.message, 541cb0ef41Sopenharmony_ci name: this.name, 551cb0ef41Sopenharmony_ci code: this.code, 561cb0ef41Sopenharmony_ci }); 571cb0ef41Sopenharmony_ci // eslint-disable-next-line no-constructor-return 581cb0ef41Sopenharmony_ci return makeTransferable(this); 591cb0ef41Sopenharmony_ci } 601cb0ef41Sopenharmony_ci 611cb0ef41Sopenharmony_ci [kClone]() { 621cb0ef41Sopenharmony_ci return { 631cb0ef41Sopenharmony_ci data: { 641cb0ef41Sopenharmony_ci message: this.message, 651cb0ef41Sopenharmony_ci name: this.name, 661cb0ef41Sopenharmony_ci code: this.code, 671cb0ef41Sopenharmony_ci }, 681cb0ef41Sopenharmony_ci deserializeInfo: 691cb0ef41Sopenharmony_ci 'internal/webstreams/transfer:InternalCloneableDOMException', 701cb0ef41Sopenharmony_ci }; 711cb0ef41Sopenharmony_ci } 721cb0ef41Sopenharmony_ci 731cb0ef41Sopenharmony_ci [kDeserialize]({ message, name, code }) { 741cb0ef41Sopenharmony_ci ObjectDefineProperties(this, { 751cb0ef41Sopenharmony_ci message: { 761cb0ef41Sopenharmony_ci __proto__: null, 771cb0ef41Sopenharmony_ci configurable: true, 781cb0ef41Sopenharmony_ci enumerable: true, 791cb0ef41Sopenharmony_ci get() { return message; }, 801cb0ef41Sopenharmony_ci }, 811cb0ef41Sopenharmony_ci name: { 821cb0ef41Sopenharmony_ci __proto__: null, 831cb0ef41Sopenharmony_ci configurable: true, 841cb0ef41Sopenharmony_ci enumerable: true, 851cb0ef41Sopenharmony_ci get() { return name; }, 861cb0ef41Sopenharmony_ci }, 871cb0ef41Sopenharmony_ci code: { 881cb0ef41Sopenharmony_ci __proto__: null, 891cb0ef41Sopenharmony_ci configurable: true, 901cb0ef41Sopenharmony_ci enumerable: true, 911cb0ef41Sopenharmony_ci get() { return code; }, 921cb0ef41Sopenharmony_ci }, 931cb0ef41Sopenharmony_ci }); 941cb0ef41Sopenharmony_ci } 951cb0ef41Sopenharmony_ci} 961cb0ef41Sopenharmony_ci 971cb0ef41Sopenharmony_cifunction InternalCloneableDOMException() { 981cb0ef41Sopenharmony_ci return makeTransferable( 991cb0ef41Sopenharmony_ci ReflectConstruct( 1001cb0ef41Sopenharmony_ci CloneableDOMException, 1011cb0ef41Sopenharmony_ci [], 1021cb0ef41Sopenharmony_ci DOMException)); 1031cb0ef41Sopenharmony_ci} 1041cb0ef41Sopenharmony_ciInternalCloneableDOMException[kDeserialize] = () => {}; 1051cb0ef41Sopenharmony_ci 1061cb0ef41Sopenharmony_ciclass CrossRealmTransformReadableSource { 1071cb0ef41Sopenharmony_ci constructor(port) { 1081cb0ef41Sopenharmony_ci this[kState] = { 1091cb0ef41Sopenharmony_ci port, 1101cb0ef41Sopenharmony_ci controller: undefined, 1111cb0ef41Sopenharmony_ci }; 1121cb0ef41Sopenharmony_ci 1131cb0ef41Sopenharmony_ci port.onmessage = ({ data }) => { 1141cb0ef41Sopenharmony_ci const { 1151cb0ef41Sopenharmony_ci controller, 1161cb0ef41Sopenharmony_ci } = this[kState]; 1171cb0ef41Sopenharmony_ci const { 1181cb0ef41Sopenharmony_ci type, 1191cb0ef41Sopenharmony_ci value, 1201cb0ef41Sopenharmony_ci } = data; 1211cb0ef41Sopenharmony_ci switch (type) { 1221cb0ef41Sopenharmony_ci case 'chunk': 1231cb0ef41Sopenharmony_ci readableStreamDefaultControllerEnqueue( 1241cb0ef41Sopenharmony_ci controller, 1251cb0ef41Sopenharmony_ci value); 1261cb0ef41Sopenharmony_ci break; 1271cb0ef41Sopenharmony_ci case 'close': 1281cb0ef41Sopenharmony_ci readableStreamDefaultControllerClose(controller); 1291cb0ef41Sopenharmony_ci port.close(); 1301cb0ef41Sopenharmony_ci break; 1311cb0ef41Sopenharmony_ci case 'error': 1321cb0ef41Sopenharmony_ci readableStreamDefaultControllerError(controller, value); 1331cb0ef41Sopenharmony_ci port.close(); 1341cb0ef41Sopenharmony_ci break; 1351cb0ef41Sopenharmony_ci } 1361cb0ef41Sopenharmony_ci }; 1371cb0ef41Sopenharmony_ci 1381cb0ef41Sopenharmony_ci port.onmessageerror = () => { 1391cb0ef41Sopenharmony_ci const error = new CloneableDOMException( 1401cb0ef41Sopenharmony_ci 'Internal transferred ReadableStream error', 1411cb0ef41Sopenharmony_ci 'DataCloneError'); 1421cb0ef41Sopenharmony_ci port.postMessage({ type: 'error', value: error }); 1431cb0ef41Sopenharmony_ci readableStreamDefaultControllerError( 1441cb0ef41Sopenharmony_ci this[kState].controller, 1451cb0ef41Sopenharmony_ci error); 1461cb0ef41Sopenharmony_ci port.close(); 1471cb0ef41Sopenharmony_ci }; 1481cb0ef41Sopenharmony_ci } 1491cb0ef41Sopenharmony_ci 1501cb0ef41Sopenharmony_ci start(controller) { 1511cb0ef41Sopenharmony_ci this[kState].controller = controller; 1521cb0ef41Sopenharmony_ci } 1531cb0ef41Sopenharmony_ci 1541cb0ef41Sopenharmony_ci async pull() { 1551cb0ef41Sopenharmony_ci this[kState].port.postMessage({ type: 'pull' }); 1561cb0ef41Sopenharmony_ci } 1571cb0ef41Sopenharmony_ci 1581cb0ef41Sopenharmony_ci async cancel(reason) { 1591cb0ef41Sopenharmony_ci try { 1601cb0ef41Sopenharmony_ci this[kState].port.postMessage({ type: 'error', value: reason }); 1611cb0ef41Sopenharmony_ci } catch (error) { 1621cb0ef41Sopenharmony_ci if (error instanceof DOMException) { 1631cb0ef41Sopenharmony_ci // eslint-disable-next-line no-ex-assign 1641cb0ef41Sopenharmony_ci error = new CloneableDOMException(error.message, error.name); 1651cb0ef41Sopenharmony_ci } 1661cb0ef41Sopenharmony_ci this[kState].port.postMessage({ type: 'error', value: error }); 1671cb0ef41Sopenharmony_ci throw error; 1681cb0ef41Sopenharmony_ci } finally { 1691cb0ef41Sopenharmony_ci this[kState].port.close(); 1701cb0ef41Sopenharmony_ci } 1711cb0ef41Sopenharmony_ci } 1721cb0ef41Sopenharmony_ci} 1731cb0ef41Sopenharmony_ci 1741cb0ef41Sopenharmony_ciclass CrossRealmTransformWritableSink { 1751cb0ef41Sopenharmony_ci constructor(port) { 1761cb0ef41Sopenharmony_ci this[kState] = { 1771cb0ef41Sopenharmony_ci port, 1781cb0ef41Sopenharmony_ci controller: undefined, 1791cb0ef41Sopenharmony_ci backpressurePromise: createDeferredPromise(), 1801cb0ef41Sopenharmony_ci }; 1811cb0ef41Sopenharmony_ci 1821cb0ef41Sopenharmony_ci port.onmessage = ({ data }) => { 1831cb0ef41Sopenharmony_ci assert(typeof data === 'object'); 1841cb0ef41Sopenharmony_ci const { 1851cb0ef41Sopenharmony_ci type, 1861cb0ef41Sopenharmony_ci value, 1871cb0ef41Sopenharmony_ci } = { ...data }; 1881cb0ef41Sopenharmony_ci assert(typeof type === 'string'); 1891cb0ef41Sopenharmony_ci switch (type) { 1901cb0ef41Sopenharmony_ci case 'pull': 1911cb0ef41Sopenharmony_ci if (this[kState].backpressurePromise !== undefined) 1921cb0ef41Sopenharmony_ci this[kState].backpressurePromise.resolve?.(); 1931cb0ef41Sopenharmony_ci this[kState].backpressurePromise = undefined; 1941cb0ef41Sopenharmony_ci break; 1951cb0ef41Sopenharmony_ci case 'error': 1961cb0ef41Sopenharmony_ci writableStreamDefaultControllerErrorIfNeeded( 1971cb0ef41Sopenharmony_ci this[kState].controller, 1981cb0ef41Sopenharmony_ci value); 1991cb0ef41Sopenharmony_ci if (this[kState].backpressurePromise !== undefined) 2001cb0ef41Sopenharmony_ci this[kState].backpressurePromise.resolve?.(); 2011cb0ef41Sopenharmony_ci this[kState].backpressurePromise = undefined; 2021cb0ef41Sopenharmony_ci break; 2031cb0ef41Sopenharmony_ci } 2041cb0ef41Sopenharmony_ci }; 2051cb0ef41Sopenharmony_ci port.onmessageerror = () => { 2061cb0ef41Sopenharmony_ci const error = new CloneableDOMException( 2071cb0ef41Sopenharmony_ci 'Internal transferred ReadableStream error', 2081cb0ef41Sopenharmony_ci 'DataCloneError'); 2091cb0ef41Sopenharmony_ci port.postMessage({ type: 'error', value: error }); 2101cb0ef41Sopenharmony_ci writableStreamDefaultControllerErrorIfNeeded( 2111cb0ef41Sopenharmony_ci this[kState].controller, 2121cb0ef41Sopenharmony_ci error); 2131cb0ef41Sopenharmony_ci port.close(); 2141cb0ef41Sopenharmony_ci }; 2151cb0ef41Sopenharmony_ci 2161cb0ef41Sopenharmony_ci } 2171cb0ef41Sopenharmony_ci 2181cb0ef41Sopenharmony_ci start(controller) { 2191cb0ef41Sopenharmony_ci this[kState].controller = controller; 2201cb0ef41Sopenharmony_ci } 2211cb0ef41Sopenharmony_ci 2221cb0ef41Sopenharmony_ci async write(chunk) { 2231cb0ef41Sopenharmony_ci if (this[kState].backpressurePromise === undefined) { 2241cb0ef41Sopenharmony_ci this[kState].backpressurePromise = { 2251cb0ef41Sopenharmony_ci promise: PromiseResolve(), 2261cb0ef41Sopenharmony_ci resolve: undefined, 2271cb0ef41Sopenharmony_ci reject: undefined, 2281cb0ef41Sopenharmony_ci }; 2291cb0ef41Sopenharmony_ci } 2301cb0ef41Sopenharmony_ci await this[kState].backpressurePromise.promise; 2311cb0ef41Sopenharmony_ci this[kState].backpressurePromise = createDeferredPromise(); 2321cb0ef41Sopenharmony_ci try { 2331cb0ef41Sopenharmony_ci this[kState].port.postMessage({ type: 'chunk', value: chunk }); 2341cb0ef41Sopenharmony_ci } catch (error) { 2351cb0ef41Sopenharmony_ci if (error instanceof DOMException) { 2361cb0ef41Sopenharmony_ci // eslint-disable-next-line no-ex-assign 2371cb0ef41Sopenharmony_ci error = new CloneableDOMException(error.message, error.name); 2381cb0ef41Sopenharmony_ci } 2391cb0ef41Sopenharmony_ci this[kState].port.postMessage({ type: 'error', value: error }); 2401cb0ef41Sopenharmony_ci this[kState].port.close(); 2411cb0ef41Sopenharmony_ci throw error; 2421cb0ef41Sopenharmony_ci } 2431cb0ef41Sopenharmony_ci } 2441cb0ef41Sopenharmony_ci 2451cb0ef41Sopenharmony_ci close() { 2461cb0ef41Sopenharmony_ci this[kState].port.postMessage({ type: 'close' }); 2471cb0ef41Sopenharmony_ci this[kState].port.close(); 2481cb0ef41Sopenharmony_ci } 2491cb0ef41Sopenharmony_ci 2501cb0ef41Sopenharmony_ci abort(reason) { 2511cb0ef41Sopenharmony_ci try { 2521cb0ef41Sopenharmony_ci this[kState].port.postMessage({ type: 'error', value: reason }); 2531cb0ef41Sopenharmony_ci } catch (error) { 2541cb0ef41Sopenharmony_ci if (error instanceof DOMException) { 2551cb0ef41Sopenharmony_ci // eslint-disable-next-line no-ex-assign 2561cb0ef41Sopenharmony_ci error = new CloneableDOMException(error.message, error.name); 2571cb0ef41Sopenharmony_ci } 2581cb0ef41Sopenharmony_ci this[kState].port.postMessage({ type: 'error', value: error }); 2591cb0ef41Sopenharmony_ci throw error; 2601cb0ef41Sopenharmony_ci } finally { 2611cb0ef41Sopenharmony_ci this[kState].port.close(); 2621cb0ef41Sopenharmony_ci } 2631cb0ef41Sopenharmony_ci } 2641cb0ef41Sopenharmony_ci} 2651cb0ef41Sopenharmony_ci 2661cb0ef41Sopenharmony_cifunction newCrossRealmReadableStream(writable, port) { 2671cb0ef41Sopenharmony_ci const readable = 2681cb0ef41Sopenharmony_ci new ReadableStream( 2691cb0ef41Sopenharmony_ci new CrossRealmTransformReadableSource(port)); 2701cb0ef41Sopenharmony_ci 2711cb0ef41Sopenharmony_ci const promise = 2721cb0ef41Sopenharmony_ci readableStreamPipeTo(readable, writable, false, false, false); 2731cb0ef41Sopenharmony_ci 2741cb0ef41Sopenharmony_ci setPromiseHandled(promise); 2751cb0ef41Sopenharmony_ci 2761cb0ef41Sopenharmony_ci return { 2771cb0ef41Sopenharmony_ci readable, 2781cb0ef41Sopenharmony_ci promise, 2791cb0ef41Sopenharmony_ci }; 2801cb0ef41Sopenharmony_ci} 2811cb0ef41Sopenharmony_ci 2821cb0ef41Sopenharmony_cifunction newCrossRealmWritableSink(readable, port) { 2831cb0ef41Sopenharmony_ci const writable = 2841cb0ef41Sopenharmony_ci new WritableStream( 2851cb0ef41Sopenharmony_ci new CrossRealmTransformWritableSink(port)); 2861cb0ef41Sopenharmony_ci 2871cb0ef41Sopenharmony_ci const promise = readableStreamPipeTo(readable, writable, false, false, false); 2881cb0ef41Sopenharmony_ci setPromiseHandled(promise); 2891cb0ef41Sopenharmony_ci return { 2901cb0ef41Sopenharmony_ci writable, 2911cb0ef41Sopenharmony_ci promise, 2921cb0ef41Sopenharmony_ci }; 2931cb0ef41Sopenharmony_ci} 2941cb0ef41Sopenharmony_ci 2951cb0ef41Sopenharmony_cimodule.exports = { 2961cb0ef41Sopenharmony_ci newCrossRealmReadableStream, 2971cb0ef41Sopenharmony_ci newCrossRealmWritableSink, 2981cb0ef41Sopenharmony_ci CrossRealmTransformWritableSink, 2991cb0ef41Sopenharmony_ci CrossRealmTransformReadableSource, 3001cb0ef41Sopenharmony_ci CloneableDOMException, 3011cb0ef41Sopenharmony_ci InternalCloneableDOMException, 3021cb0ef41Sopenharmony_ci}; 303