11cb0ef41Sopenharmony_ci// Flags: --expose-internals --no-warnings 21cb0ef41Sopenharmony_ci'use strict'; 31cb0ef41Sopenharmony_ci 41cb0ef41Sopenharmony_ciconst common = require('../common'); 51cb0ef41Sopenharmony_ci 61cb0ef41Sopenharmony_ciconst { 71cb0ef41Sopenharmony_ci ReadableStream, 81cb0ef41Sopenharmony_ci WritableStream, 91cb0ef41Sopenharmony_ci TransformStream, 101cb0ef41Sopenharmony_ci} = require('stream/web'); 111cb0ef41Sopenharmony_ci 121cb0ef41Sopenharmony_ciconst { 131cb0ef41Sopenharmony_ci Worker 141cb0ef41Sopenharmony_ci} = require('worker_threads'); 151cb0ef41Sopenharmony_ci 161cb0ef41Sopenharmony_ciconst { 171cb0ef41Sopenharmony_ci isReadableStream, 181cb0ef41Sopenharmony_ci isReadableByteStreamController, 191cb0ef41Sopenharmony_ci} = require('internal/webstreams/readablestream'); 201cb0ef41Sopenharmony_ci 211cb0ef41Sopenharmony_ciconst { 221cb0ef41Sopenharmony_ci isWritableStream, 231cb0ef41Sopenharmony_ci} = require('internal/webstreams/writablestream'); 241cb0ef41Sopenharmony_ci 251cb0ef41Sopenharmony_ciconst { 261cb0ef41Sopenharmony_ci isTransformStream, 271cb0ef41Sopenharmony_ci} = require('internal/webstreams/transformstream'); 281cb0ef41Sopenharmony_ci 291cb0ef41Sopenharmony_ciconst { 301cb0ef41Sopenharmony_ci kState, 311cb0ef41Sopenharmony_ci} = require('internal/webstreams/util'); 321cb0ef41Sopenharmony_ci 331cb0ef41Sopenharmony_ciconst { 341cb0ef41Sopenharmony_ci makeTransferable, 351cb0ef41Sopenharmony_ci kClone, 361cb0ef41Sopenharmony_ci kTransfer, 371cb0ef41Sopenharmony_ci kDeserialize, 381cb0ef41Sopenharmony_ci} = require('internal/worker/js_transferable'); 391cb0ef41Sopenharmony_ci 401cb0ef41Sopenharmony_ciconst assert = require('assert'); 411cb0ef41Sopenharmony_ci 421cb0ef41Sopenharmony_ciconst theData = 'hello'; 431cb0ef41Sopenharmony_ci 441cb0ef41Sopenharmony_ci{ 451cb0ef41Sopenharmony_ci const { port1, port2 } = new MessageChannel(); 461cb0ef41Sopenharmony_ci port1.onmessageerror = common.mustNotCall(); 471cb0ef41Sopenharmony_ci port2.onmessageerror = common.mustNotCall(); 481cb0ef41Sopenharmony_ci 491cb0ef41Sopenharmony_ci // This test takes the ReadableStream and transfers it to the 501cb0ef41Sopenharmony_ci // port1 first, then again to port2, which reads the data. 511cb0ef41Sopenharmony_ci // Internally, this sets up a pipelined data flow that is 521cb0ef41Sopenharmony_ci // important to understand in case this test fails.. 531cb0ef41Sopenharmony_ci // 541cb0ef41Sopenharmony_ci // Specifically: 551cb0ef41Sopenharmony_ci // 561cb0ef41Sopenharmony_ci // 1. We start with ReadableStream R1, 571cb0ef41Sopenharmony_ci // 2. Calling port2.postMessage causes a new internal WritableStream W1 581cb0ef41Sopenharmony_ci // and a new ReadableStream R2 to be created, both of which are coupled 591cb0ef41Sopenharmony_ci // to each other via a pair of MessagePorts P1 and P2. 601cb0ef41Sopenharmony_ci // 3. ReadableStream R2 is passed to the port1.onmessage callback as the 611cb0ef41Sopenharmony_ci // data property of the MessageEvent, and R1 is configured to pipeTo W1. 621cb0ef41Sopenharmony_ci // 4. Within port1.onmessage, we transfer ReadableStream R2 to port1, which 631cb0ef41Sopenharmony_ci // creates a new internal WritableStream W2 and a new ReadableStream R3, 641cb0ef41Sopenharmony_ci // both of which are coupled to each other via a pair of MessagePorts 651cb0ef41Sopenharmony_ci // P3 and P4. 661cb0ef41Sopenharmony_ci // 5. ReadableStream R3 is passed to the port2.onmessage callback as the 671cb0ef41Sopenharmony_ci // data property of the MessageEvent, and R2 is configured to pipeTo W2. 681cb0ef41Sopenharmony_ci // 6. Once the reader is attached to R3 in the port2.onmessage callback, 691cb0ef41Sopenharmony_ci // a message is sent along the path: R3 -> P4 -> P3 -> R2 -> P2 -> P1 -> R1 701cb0ef41Sopenharmony_ci // to begin pulling the data. The data is then pushed along the pipeline 711cb0ef41Sopenharmony_ci // R1 -> W1 -> P1 -> P2 -> R2 -> W2 -> P3 -> P4 -> R3 721cb0ef41Sopenharmony_ci // 7. The MessagePorts P1, P2, P3, and P4 serve as a control channel for 731cb0ef41Sopenharmony_ci // passing data and control instructions, potentially across realms, 741cb0ef41Sopenharmony_ci // to the other ReadableStream and WritableStream instances. 751cb0ef41Sopenharmony_ci // 761cb0ef41Sopenharmony_ci // If this test experiences timeouts (hangs without finishing), it's most 771cb0ef41Sopenharmony_ci // likely because the control instructions are somehow broken and the 781cb0ef41Sopenharmony_ci // MessagePorts are not being closed properly or it could be caused by 791cb0ef41Sopenharmony_ci // failing the close R1's controller which signals the end of the data 801cb0ef41Sopenharmony_ci // flow. 811cb0ef41Sopenharmony_ci 821cb0ef41Sopenharmony_ci const readable = new ReadableStream({ 831cb0ef41Sopenharmony_ci start: common.mustCall((controller) => { 841cb0ef41Sopenharmony_ci controller.enqueue(theData); 851cb0ef41Sopenharmony_ci controller.close(); 861cb0ef41Sopenharmony_ci }), 871cb0ef41Sopenharmony_ci }); 881cb0ef41Sopenharmony_ci 891cb0ef41Sopenharmony_ci port2.onmessage = common.mustCall(({ data }) => { 901cb0ef41Sopenharmony_ci assert(isReadableStream(data)); 911cb0ef41Sopenharmony_ci 921cb0ef41Sopenharmony_ci const reader = data.getReader(); 931cb0ef41Sopenharmony_ci reader.read().then(common.mustCall((chunk) => { 941cb0ef41Sopenharmony_ci assert.deepStrictEqual(chunk, { done: false, value: theData }); 951cb0ef41Sopenharmony_ci })); 961cb0ef41Sopenharmony_ci 971cb0ef41Sopenharmony_ci port2.close(); 981cb0ef41Sopenharmony_ci }); 991cb0ef41Sopenharmony_ci 1001cb0ef41Sopenharmony_ci port1.onmessage = common.mustCall(({ data }) => { 1011cb0ef41Sopenharmony_ci assert(isReadableStream(data)); 1021cb0ef41Sopenharmony_ci assert(!data.locked); 1031cb0ef41Sopenharmony_ci port1.postMessage(data, [data]); 1041cb0ef41Sopenharmony_ci assert(data.locked); 1051cb0ef41Sopenharmony_ci }); 1061cb0ef41Sopenharmony_ci 1071cb0ef41Sopenharmony_ci assert.throws(() => port2.postMessage(readable), { 1081cb0ef41Sopenharmony_ci code: 'ERR_MISSING_TRANSFERABLE_IN_TRANSFER_LIST', 1091cb0ef41Sopenharmony_ci }); 1101cb0ef41Sopenharmony_ci 1111cb0ef41Sopenharmony_ci port2.postMessage(readable, [readable]); 1121cb0ef41Sopenharmony_ci assert(readable.locked); 1131cb0ef41Sopenharmony_ci} 1141cb0ef41Sopenharmony_ci 1151cb0ef41Sopenharmony_ci{ 1161cb0ef41Sopenharmony_ci const { port1, port2 } = new MessageChannel(); 1171cb0ef41Sopenharmony_ci port1.onmessageerror = common.mustNotCall(); 1181cb0ef41Sopenharmony_ci port2.onmessageerror = common.mustNotCall(); 1191cb0ef41Sopenharmony_ci 1201cb0ef41Sopenharmony_ci // This test repeats the test above, but with a readable byte stream. 1211cb0ef41Sopenharmony_ci // Note transferring a readable byte stream results in a regular 1221cb0ef41Sopenharmony_ci // value-oriented stream on the other side: 1231cb0ef41Sopenharmony_ci // https://streams.spec.whatwg.org/#abstract-opdef-setupcrossrealmtransformwritable 1241cb0ef41Sopenharmony_ci 1251cb0ef41Sopenharmony_ci const theByteData = new Uint8Array([1, 2, 3]); 1261cb0ef41Sopenharmony_ci 1271cb0ef41Sopenharmony_ci const readable = new ReadableStream({ 1281cb0ef41Sopenharmony_ci type: 'bytes', 1291cb0ef41Sopenharmony_ci start: common.mustCall((controller) => { 1301cb0ef41Sopenharmony_ci // `enqueue` will detach its argument's buffer, so clone first 1311cb0ef41Sopenharmony_ci controller.enqueue(theByteData.slice()); 1321cb0ef41Sopenharmony_ci controller.close(); 1331cb0ef41Sopenharmony_ci }), 1341cb0ef41Sopenharmony_ci }); 1351cb0ef41Sopenharmony_ci assert(isReadableByteStreamController(readable[kState].controller)); 1361cb0ef41Sopenharmony_ci 1371cb0ef41Sopenharmony_ci port2.onmessage = common.mustCall(({ data }) => { 1381cb0ef41Sopenharmony_ci assert(isReadableStream(data)); 1391cb0ef41Sopenharmony_ci assert(!isReadableByteStreamController(data[kState].controller)); 1401cb0ef41Sopenharmony_ci 1411cb0ef41Sopenharmony_ci const reader = data.getReader(); 1421cb0ef41Sopenharmony_ci reader.read().then(common.mustCall((chunk) => { 1431cb0ef41Sopenharmony_ci assert.deepStrictEqual(chunk, { done: false, value: theByteData }); 1441cb0ef41Sopenharmony_ci })); 1451cb0ef41Sopenharmony_ci 1461cb0ef41Sopenharmony_ci port2.close(); 1471cb0ef41Sopenharmony_ci }); 1481cb0ef41Sopenharmony_ci 1491cb0ef41Sopenharmony_ci port1.onmessage = common.mustCall(({ data }) => { 1501cb0ef41Sopenharmony_ci assert(isReadableStream(data)); 1511cb0ef41Sopenharmony_ci assert(!isReadableByteStreamController(data[kState].controller)); 1521cb0ef41Sopenharmony_ci assert(!data.locked); 1531cb0ef41Sopenharmony_ci port1.postMessage(data, [data]); 1541cb0ef41Sopenharmony_ci assert(data.locked); 1551cb0ef41Sopenharmony_ci }); 1561cb0ef41Sopenharmony_ci 1571cb0ef41Sopenharmony_ci assert.throws(() => port2.postMessage(readable), { 1581cb0ef41Sopenharmony_ci code: 'ERR_MISSING_TRANSFERABLE_IN_TRANSFER_LIST', 1591cb0ef41Sopenharmony_ci }); 1601cb0ef41Sopenharmony_ci 1611cb0ef41Sopenharmony_ci port2.postMessage(readable, [readable]); 1621cb0ef41Sopenharmony_ci assert(readable.locked); 1631cb0ef41Sopenharmony_ci} 1641cb0ef41Sopenharmony_ci 1651cb0ef41Sopenharmony_ci{ 1661cb0ef41Sopenharmony_ci const { port1, port2 } = new MessageChannel(); 1671cb0ef41Sopenharmony_ci port1.onmessageerror = common.mustNotCall(); 1681cb0ef41Sopenharmony_ci port2.onmessageerror = common.mustNotCall(); 1691cb0ef41Sopenharmony_ci 1701cb0ef41Sopenharmony_ci // Like the ReadableStream test above, this sets up a pipeline 1711cb0ef41Sopenharmony_ci // through which the data flows... 1721cb0ef41Sopenharmony_ci // 1731cb0ef41Sopenharmony_ci // We start with WritableStream W1, which is transferred to port1. 1741cb0ef41Sopenharmony_ci // Doing so creates an internal ReadableStream R1 and WritableStream W2, 1751cb0ef41Sopenharmony_ci // which are coupled together with MessagePorts P1 and P2. 1761cb0ef41Sopenharmony_ci // The port1.onmessage callback receives WritableStream W2 and 1771cb0ef41Sopenharmony_ci // immediately transfers that to port2. Doing so creates an internal 1781cb0ef41Sopenharmony_ci // ReadableStream R2 and WritableStream W3, which are coupled together 1791cb0ef41Sopenharmony_ci // with MessagePorts P3 and P4. WritableStream W3 is handed off to 1801cb0ef41Sopenharmony_ci // port2.onmessage. 1811cb0ef41Sopenharmony_ci // 1821cb0ef41Sopenharmony_ci // When the writer on port2.onmessage writes the chunk of data, it 1831cb0ef41Sopenharmony_ci // gets passed along the pipeline: 1841cb0ef41Sopenharmony_ci // W3 -> P4 -> P3 -> R2 -> W2 -> P2 -> P1 -> R1 -> W1 1851cb0ef41Sopenharmony_ci 1861cb0ef41Sopenharmony_ci const writable = new WritableStream({ 1871cb0ef41Sopenharmony_ci write: common.mustCall((chunk) => { 1881cb0ef41Sopenharmony_ci assert.strictEqual(chunk, theData); 1891cb0ef41Sopenharmony_ci }), 1901cb0ef41Sopenharmony_ci }); 1911cb0ef41Sopenharmony_ci 1921cb0ef41Sopenharmony_ci port2.onmessage = common.mustCall(({ data }) => { 1931cb0ef41Sopenharmony_ci assert(isWritableStream(data)); 1941cb0ef41Sopenharmony_ci assert(!data.locked); 1951cb0ef41Sopenharmony_ci const writer = data.getWriter(); 1961cb0ef41Sopenharmony_ci writer.write(theData).then(common.mustCall()); 1971cb0ef41Sopenharmony_ci writer.close(); 1981cb0ef41Sopenharmony_ci port2.close(); 1991cb0ef41Sopenharmony_ci }); 2001cb0ef41Sopenharmony_ci 2011cb0ef41Sopenharmony_ci port1.onmessage = common.mustCall(({ data }) => { 2021cb0ef41Sopenharmony_ci assert(isWritableStream(data)); 2031cb0ef41Sopenharmony_ci assert(!data.locked); 2041cb0ef41Sopenharmony_ci port1.postMessage(data, [data]); 2051cb0ef41Sopenharmony_ci assert(data.locked); 2061cb0ef41Sopenharmony_ci }); 2071cb0ef41Sopenharmony_ci 2081cb0ef41Sopenharmony_ci assert.throws(() => port2.postMessage(writable), { 2091cb0ef41Sopenharmony_ci code: 'ERR_MISSING_TRANSFERABLE_IN_TRANSFER_LIST', 2101cb0ef41Sopenharmony_ci }); 2111cb0ef41Sopenharmony_ci 2121cb0ef41Sopenharmony_ci port2.postMessage(writable, [writable]); 2131cb0ef41Sopenharmony_ci assert(writable.locked); 2141cb0ef41Sopenharmony_ci} 2151cb0ef41Sopenharmony_ci 2161cb0ef41Sopenharmony_ci{ 2171cb0ef41Sopenharmony_ci const { port1, port2 } = new MessageChannel(); 2181cb0ef41Sopenharmony_ci port1.onmessageerror = common.mustNotCall(); 2191cb0ef41Sopenharmony_ci port2.onmessageerror = common.mustNotCall(); 2201cb0ef41Sopenharmony_ci 2211cb0ef41Sopenharmony_ci // The data flow here is actually quite complicated, and is a combination 2221cb0ef41Sopenharmony_ci // of the WritableStream and ReadableStream examples above. 2231cb0ef41Sopenharmony_ci // 2241cb0ef41Sopenharmony_ci // We start with TransformStream T1, which creates ReadableStream R1, 2251cb0ef41Sopenharmony_ci // and WritableStream W1. 2261cb0ef41Sopenharmony_ci // 2271cb0ef41Sopenharmony_ci // When T1 is transferred to port1.onmessage, R1 and W1 are individually 2281cb0ef41Sopenharmony_ci // transferred. 2291cb0ef41Sopenharmony_ci // 2301cb0ef41Sopenharmony_ci // When R1 is transferred, it creates internal WritableStream W2, and 2311cb0ef41Sopenharmony_ci // new ReadableStream R2, coupled together via MessagePorts P1 and P2. 2321cb0ef41Sopenharmony_ci // 2331cb0ef41Sopenharmony_ci // When W1 is transferred, it creates internal ReadableStream R3 and 2341cb0ef41Sopenharmony_ci // new WritableStream W3, coupled together via MessagePorts P3 and P4. 2351cb0ef41Sopenharmony_ci // 2361cb0ef41Sopenharmony_ci // A new TransformStream T2 is created that owns ReadableStream R2 and 2371cb0ef41Sopenharmony_ci // WritableStream W3. The port1.onmessage callback immediately transfers 2381cb0ef41Sopenharmony_ci // that to port2.onmessage. 2391cb0ef41Sopenharmony_ci // 2401cb0ef41Sopenharmony_ci // When T2 is transferred, R2 and W3 are individually transferred. 2411cb0ef41Sopenharmony_ci // 2421cb0ef41Sopenharmony_ci // When R2 is transferred, it creates internal WritableStream W4, and 2431cb0ef41Sopenharmony_ci // ReadableStream R4, coupled together via MessagePorts P5 and P6. 2441cb0ef41Sopenharmony_ci // 2451cb0ef41Sopenharmony_ci // When W3 is transferred, it creates internal ReadableStream R5, and 2461cb0ef41Sopenharmony_ci // WritableStream W5, coupled together via MessagePorts P7 and P8. 2471cb0ef41Sopenharmony_ci // 2481cb0ef41Sopenharmony_ci // A new TransformStream T3 is created that owns ReadableStream R4 and 2491cb0ef41Sopenharmony_ci // WritableStream W5. 2501cb0ef41Sopenharmony_ci // 2511cb0ef41Sopenharmony_ci // port1.onmessage then writes a chunk of data. That chunk of data 2521cb0ef41Sopenharmony_ci // flows through the pipeline to T1: 2531cb0ef41Sopenharmony_ci // 2541cb0ef41Sopenharmony_ci // W5 -> P8 -> P7 -> R5 -> W3 -> P4 -> P3 -> R3 -> W1 -> T1 2551cb0ef41Sopenharmony_ci // 2561cb0ef41Sopenharmony_ci // T1 performs the transformation, then pushes the chunk back out 2571cb0ef41Sopenharmony_ci // along the pipeline: 2581cb0ef41Sopenharmony_ci // 2591cb0ef41Sopenharmony_ci // T1 -> R1 -> W2 -> P1 -> P2 -> R2 -> W4 -> P5 -> P6 -> R4 2601cb0ef41Sopenharmony_ci 2611cb0ef41Sopenharmony_ci const transform = new TransformStream({ 2621cb0ef41Sopenharmony_ci transform(chunk, controller) { 2631cb0ef41Sopenharmony_ci controller.enqueue(chunk.toUpperCase()); 2641cb0ef41Sopenharmony_ci } 2651cb0ef41Sopenharmony_ci }); 2661cb0ef41Sopenharmony_ci 2671cb0ef41Sopenharmony_ci port2.onmessage = common.mustCall(({ data }) => { 2681cb0ef41Sopenharmony_ci assert(isTransformStream(data)); 2691cb0ef41Sopenharmony_ci const writer = data.writable.getWriter(); 2701cb0ef41Sopenharmony_ci const reader = data.readable.getReader(); 2711cb0ef41Sopenharmony_ci Promise.all([ 2721cb0ef41Sopenharmony_ci writer.write(theData), 2731cb0ef41Sopenharmony_ci writer.close(), 2741cb0ef41Sopenharmony_ci reader.read().then(common.mustCall((result) => { 2751cb0ef41Sopenharmony_ci assert(!result.done); 2761cb0ef41Sopenharmony_ci assert.strictEqual(result.value, theData.toUpperCase()); 2771cb0ef41Sopenharmony_ci })), 2781cb0ef41Sopenharmony_ci reader.read().then(common.mustCall((result) => { 2791cb0ef41Sopenharmony_ci assert(result.done); 2801cb0ef41Sopenharmony_ci })), 2811cb0ef41Sopenharmony_ci ]).then(common.mustCall()); 2821cb0ef41Sopenharmony_ci port2.close(); 2831cb0ef41Sopenharmony_ci }); 2841cb0ef41Sopenharmony_ci 2851cb0ef41Sopenharmony_ci port1.onmessage = common.mustCall(({ data }) => { 2861cb0ef41Sopenharmony_ci assert(isTransformStream(data)); 2871cb0ef41Sopenharmony_ci assert(!data.readable.locked); 2881cb0ef41Sopenharmony_ci assert(!data.writable.locked); 2891cb0ef41Sopenharmony_ci port1.postMessage(data, [data]); 2901cb0ef41Sopenharmony_ci assert(data.readable.locked); 2911cb0ef41Sopenharmony_ci assert(data.writable.locked); 2921cb0ef41Sopenharmony_ci }); 2931cb0ef41Sopenharmony_ci 2941cb0ef41Sopenharmony_ci assert.throws(() => port2.postMessage(transform), { 2951cb0ef41Sopenharmony_ci code: 'ERR_MISSING_TRANSFERABLE_IN_TRANSFER_LIST', 2961cb0ef41Sopenharmony_ci }); 2971cb0ef41Sopenharmony_ci 2981cb0ef41Sopenharmony_ci port2.postMessage(transform, [transform]); 2991cb0ef41Sopenharmony_ci assert(transform.readable.locked); 3001cb0ef41Sopenharmony_ci assert(transform.writable.locked); 3011cb0ef41Sopenharmony_ci} 3021cb0ef41Sopenharmony_ci 3031cb0ef41Sopenharmony_ci{ 3041cb0ef41Sopenharmony_ci const { port1, port2 } = new MessageChannel(); 3051cb0ef41Sopenharmony_ci let controller; 3061cb0ef41Sopenharmony_ci 3071cb0ef41Sopenharmony_ci const readable = new ReadableStream({ 3081cb0ef41Sopenharmony_ci start(c) { controller = c; }, 3091cb0ef41Sopenharmony_ci 3101cb0ef41Sopenharmony_ci cancel: common.mustCall((error) => { 3111cb0ef41Sopenharmony_ci assert.strictEqual(error.code, 25); 3121cb0ef41Sopenharmony_ci assert.strictEqual(error.name, 'DataCloneError'); 3131cb0ef41Sopenharmony_ci }), 3141cb0ef41Sopenharmony_ci }); 3151cb0ef41Sopenharmony_ci 3161cb0ef41Sopenharmony_ci port1.onmessage = ({ data }) => { 3171cb0ef41Sopenharmony_ci const reader = data.getReader(); 3181cb0ef41Sopenharmony_ci assert.rejects(reader.read(), { 3191cb0ef41Sopenharmony_ci code: 25, 3201cb0ef41Sopenharmony_ci name: 'DataCloneError', 3211cb0ef41Sopenharmony_ci }); 3221cb0ef41Sopenharmony_ci port1.close(); 3231cb0ef41Sopenharmony_ci }; 3241cb0ef41Sopenharmony_ci 3251cb0ef41Sopenharmony_ci port2.postMessage(readable, [readable]); 3261cb0ef41Sopenharmony_ci 3271cb0ef41Sopenharmony_ci const notActuallyTransferable = makeTransferable({ 3281cb0ef41Sopenharmony_ci [kClone]() { 3291cb0ef41Sopenharmony_ci return { 3301cb0ef41Sopenharmony_ci data: {}, 3311cb0ef41Sopenharmony_ci deserializeInfo: 'nothing that will work', 3321cb0ef41Sopenharmony_ci }; 3331cb0ef41Sopenharmony_ci }, 3341cb0ef41Sopenharmony_ci [kDeserialize]: common.mustNotCall(), 3351cb0ef41Sopenharmony_ci }); 3361cb0ef41Sopenharmony_ci 3371cb0ef41Sopenharmony_ci controller.enqueue(notActuallyTransferable); 3381cb0ef41Sopenharmony_ci} 3391cb0ef41Sopenharmony_ci 3401cb0ef41Sopenharmony_ci{ 3411cb0ef41Sopenharmony_ci const { port1, port2 } = new MessageChannel(); 3421cb0ef41Sopenharmony_ci 3431cb0ef41Sopenharmony_ci const source = { 3441cb0ef41Sopenharmony_ci abort: common.mustCall((error) => { 3451cb0ef41Sopenharmony_ci process.nextTick(() => { 3461cb0ef41Sopenharmony_ci assert.strictEqual(error.code, 25); 3471cb0ef41Sopenharmony_ci assert.strictEqual(error.name, 'DataCloneError'); 3481cb0ef41Sopenharmony_ci }); 3491cb0ef41Sopenharmony_ci }) 3501cb0ef41Sopenharmony_ci }; 3511cb0ef41Sopenharmony_ci 3521cb0ef41Sopenharmony_ci const writable = new WritableStream(source); 3531cb0ef41Sopenharmony_ci 3541cb0ef41Sopenharmony_ci const notActuallyTransferable = makeTransferable({ 3551cb0ef41Sopenharmony_ci [kClone]() { 3561cb0ef41Sopenharmony_ci return { 3571cb0ef41Sopenharmony_ci data: {}, 3581cb0ef41Sopenharmony_ci deserializeInfo: 'nothing that will work', 3591cb0ef41Sopenharmony_ci }; 3601cb0ef41Sopenharmony_ci }, 3611cb0ef41Sopenharmony_ci [kDeserialize]: common.mustNotCall(), 3621cb0ef41Sopenharmony_ci }); 3631cb0ef41Sopenharmony_ci 3641cb0ef41Sopenharmony_ci port1.onmessage = common.mustCall(({ data }) => { 3651cb0ef41Sopenharmony_ci const writer = data.getWriter(); 3661cb0ef41Sopenharmony_ci 3671cb0ef41Sopenharmony_ci assert.rejects(writer.closed, { 3681cb0ef41Sopenharmony_ci code: 25, 3691cb0ef41Sopenharmony_ci name: 'DataCloneError', 3701cb0ef41Sopenharmony_ci }); 3711cb0ef41Sopenharmony_ci 3721cb0ef41Sopenharmony_ci writer.write(notActuallyTransferable).then(common.mustCall()); 3731cb0ef41Sopenharmony_ci 3741cb0ef41Sopenharmony_ci port1.close(); 3751cb0ef41Sopenharmony_ci }); 3761cb0ef41Sopenharmony_ci 3771cb0ef41Sopenharmony_ci port2.postMessage(writable, [writable]); 3781cb0ef41Sopenharmony_ci} 3791cb0ef41Sopenharmony_ci 3801cb0ef41Sopenharmony_ci{ 3811cb0ef41Sopenharmony_ci const error = new Error('boom'); 3821cb0ef41Sopenharmony_ci const { port1, port2 } = new MessageChannel(); 3831cb0ef41Sopenharmony_ci 3841cb0ef41Sopenharmony_ci const source = { 3851cb0ef41Sopenharmony_ci abort: common.mustCall((reason) => { 3861cb0ef41Sopenharmony_ci process.nextTick(() => { 3871cb0ef41Sopenharmony_ci assert.deepStrictEqual(reason, error); 3881cb0ef41Sopenharmony_ci 3891cb0ef41Sopenharmony_ci // Reason is a clone of the original error. 3901cb0ef41Sopenharmony_ci assert.notStrictEqual(reason, error); 3911cb0ef41Sopenharmony_ci }); 3921cb0ef41Sopenharmony_ci }), 3931cb0ef41Sopenharmony_ci }; 3941cb0ef41Sopenharmony_ci 3951cb0ef41Sopenharmony_ci const writable = new WritableStream(source); 3961cb0ef41Sopenharmony_ci 3971cb0ef41Sopenharmony_ci port1.onmessage = common.mustCall(({ data }) => { 3981cb0ef41Sopenharmony_ci const writer = data.getWriter(); 3991cb0ef41Sopenharmony_ci 4001cb0ef41Sopenharmony_ci assert.rejects(writer.closed, error); 4011cb0ef41Sopenharmony_ci 4021cb0ef41Sopenharmony_ci writer.abort(error).then(common.mustCall()); 4031cb0ef41Sopenharmony_ci port1.close(); 4041cb0ef41Sopenharmony_ci }); 4051cb0ef41Sopenharmony_ci 4061cb0ef41Sopenharmony_ci port2.postMessage(writable, [writable]); 4071cb0ef41Sopenharmony_ci} 4081cb0ef41Sopenharmony_ci 4091cb0ef41Sopenharmony_ci{ 4101cb0ef41Sopenharmony_ci const { port1, port2 } = new MessageChannel(); 4111cb0ef41Sopenharmony_ci 4121cb0ef41Sopenharmony_ci const source = { 4131cb0ef41Sopenharmony_ci abort: common.mustCall((error) => { 4141cb0ef41Sopenharmony_ci process.nextTick(() => { 4151cb0ef41Sopenharmony_ci assert.strictEqual(error.code, 25); 4161cb0ef41Sopenharmony_ci assert.strictEqual(error.name, 'DataCloneError'); 4171cb0ef41Sopenharmony_ci }); 4181cb0ef41Sopenharmony_ci }) 4191cb0ef41Sopenharmony_ci }; 4201cb0ef41Sopenharmony_ci 4211cb0ef41Sopenharmony_ci const writable = new WritableStream(source); 4221cb0ef41Sopenharmony_ci 4231cb0ef41Sopenharmony_ci port1.onmessage = common.mustCall(({ data }) => { 4241cb0ef41Sopenharmony_ci const writer = data.getWriter(); 4251cb0ef41Sopenharmony_ci 4261cb0ef41Sopenharmony_ci const m = new WebAssembly.Memory({ initial: 1 }); 4271cb0ef41Sopenharmony_ci 4281cb0ef41Sopenharmony_ci assert.rejects(writer.abort(m), { 4291cb0ef41Sopenharmony_ci code: 25, 4301cb0ef41Sopenharmony_ci name: 'DataCloneError', 4311cb0ef41Sopenharmony_ci }); 4321cb0ef41Sopenharmony_ci port1.close(); 4331cb0ef41Sopenharmony_ci }); 4341cb0ef41Sopenharmony_ci 4351cb0ef41Sopenharmony_ci port2.postMessage(writable, [writable]); 4361cb0ef41Sopenharmony_ci} 4371cb0ef41Sopenharmony_ci 4381cb0ef41Sopenharmony_ci{ 4391cb0ef41Sopenharmony_ci // Verify that the communication works across worker threads... 4401cb0ef41Sopenharmony_ci 4411cb0ef41Sopenharmony_ci const worker = new Worker(` 4421cb0ef41Sopenharmony_ci const { 4431cb0ef41Sopenharmony_ci isReadableStream, 4441cb0ef41Sopenharmony_ci } = require('internal/webstreams/readablestream'); 4451cb0ef41Sopenharmony_ci 4461cb0ef41Sopenharmony_ci const { 4471cb0ef41Sopenharmony_ci parentPort, 4481cb0ef41Sopenharmony_ci } = require('worker_threads'); 4491cb0ef41Sopenharmony_ci 4501cb0ef41Sopenharmony_ci const assert = require('assert'); 4511cb0ef41Sopenharmony_ci 4521cb0ef41Sopenharmony_ci const tracker = new assert.CallTracker(); 4531cb0ef41Sopenharmony_ci process.on('exit', () => { 4541cb0ef41Sopenharmony_ci tracker.verify(); 4551cb0ef41Sopenharmony_ci }); 4561cb0ef41Sopenharmony_ci 4571cb0ef41Sopenharmony_ci parentPort.onmessage = tracker.calls(({ data }) => { 4581cb0ef41Sopenharmony_ci assert(isReadableStream(data)); 4591cb0ef41Sopenharmony_ci const reader = data.getReader(); 4601cb0ef41Sopenharmony_ci reader.read().then(tracker.calls((result) => { 4611cb0ef41Sopenharmony_ci assert(!result.done); 4621cb0ef41Sopenharmony_ci assert(result.value instanceof Uint8Array); 4631cb0ef41Sopenharmony_ci })); 4641cb0ef41Sopenharmony_ci parentPort.close(); 4651cb0ef41Sopenharmony_ci }); 4661cb0ef41Sopenharmony_ci parentPort.onmessageerror = () => assert.fail('should not be called'); 4671cb0ef41Sopenharmony_ci `, { eval: true }); 4681cb0ef41Sopenharmony_ci 4691cb0ef41Sopenharmony_ci worker.on('error', common.mustNotCall()); 4701cb0ef41Sopenharmony_ci 4711cb0ef41Sopenharmony_ci const readable = new ReadableStream({ 4721cb0ef41Sopenharmony_ci start(controller) { 4731cb0ef41Sopenharmony_ci controller.enqueue(new Uint8Array(10)); 4741cb0ef41Sopenharmony_ci controller.close(); 4751cb0ef41Sopenharmony_ci } 4761cb0ef41Sopenharmony_ci }); 4771cb0ef41Sopenharmony_ci 4781cb0ef41Sopenharmony_ci worker.postMessage(readable, [readable]); 4791cb0ef41Sopenharmony_ci} 4801cb0ef41Sopenharmony_ci 4811cb0ef41Sopenharmony_ci{ 4821cb0ef41Sopenharmony_ci const source = { 4831cb0ef41Sopenharmony_ci cancel: common.mustCall(), 4841cb0ef41Sopenharmony_ci }; 4851cb0ef41Sopenharmony_ci 4861cb0ef41Sopenharmony_ci const readable = new ReadableStream(source); 4871cb0ef41Sopenharmony_ci 4881cb0ef41Sopenharmony_ci const { port1, port2 } = new MessageChannel(); 4891cb0ef41Sopenharmony_ci 4901cb0ef41Sopenharmony_ci port1.onmessage = common.mustCall(({ data }) => { 4911cb0ef41Sopenharmony_ci data.cancel().then(common.mustCall()); 4921cb0ef41Sopenharmony_ci port1.close(); 4931cb0ef41Sopenharmony_ci }); 4941cb0ef41Sopenharmony_ci 4951cb0ef41Sopenharmony_ci port2.postMessage(readable, [readable]); 4961cb0ef41Sopenharmony_ci} 4971cb0ef41Sopenharmony_ci 4981cb0ef41Sopenharmony_ci{ 4991cb0ef41Sopenharmony_ci const source = { 5001cb0ef41Sopenharmony_ci cancel: common.mustCall((error) => { 5011cb0ef41Sopenharmony_ci process.nextTick(() => { 5021cb0ef41Sopenharmony_ci assert.strictEqual(error.code, 25); 5031cb0ef41Sopenharmony_ci assert.strictEqual(error.name, 'DataCloneError'); 5041cb0ef41Sopenharmony_ci }); 5051cb0ef41Sopenharmony_ci }), 5061cb0ef41Sopenharmony_ci }; 5071cb0ef41Sopenharmony_ci 5081cb0ef41Sopenharmony_ci const readable = new ReadableStream(source); 5091cb0ef41Sopenharmony_ci 5101cb0ef41Sopenharmony_ci const { port1, port2 } = new MessageChannel(); 5111cb0ef41Sopenharmony_ci 5121cb0ef41Sopenharmony_ci port1.onmessage = common.mustCall(({ data }) => { 5131cb0ef41Sopenharmony_ci const m = new WebAssembly.Memory({ initial: 1 }); 5141cb0ef41Sopenharmony_ci 5151cb0ef41Sopenharmony_ci const reader = data.getReader(); 5161cb0ef41Sopenharmony_ci 5171cb0ef41Sopenharmony_ci const cancel = reader.cancel(m); 5181cb0ef41Sopenharmony_ci 5191cb0ef41Sopenharmony_ci reader.closed.then(common.mustCall()); 5201cb0ef41Sopenharmony_ci 5211cb0ef41Sopenharmony_ci assert.rejects(cancel, { 5221cb0ef41Sopenharmony_ci code: 25, 5231cb0ef41Sopenharmony_ci name: 'DataCloneError', 5241cb0ef41Sopenharmony_ci }); 5251cb0ef41Sopenharmony_ci 5261cb0ef41Sopenharmony_ci port1.close(); 5271cb0ef41Sopenharmony_ci }); 5281cb0ef41Sopenharmony_ci 5291cb0ef41Sopenharmony_ci port2.postMessage(readable, [readable]); 5301cb0ef41Sopenharmony_ci} 5311cb0ef41Sopenharmony_ci 5321cb0ef41Sopenharmony_ci{ 5331cb0ef41Sopenharmony_ci const source = { 5341cb0ef41Sopenharmony_ci abort: common.mustCall((error) => { 5351cb0ef41Sopenharmony_ci process.nextTick(() => { 5361cb0ef41Sopenharmony_ci assert.strictEqual(error.code, 25); 5371cb0ef41Sopenharmony_ci assert.strictEqual(error.name, 'DataCloneError'); 5381cb0ef41Sopenharmony_ci }); 5391cb0ef41Sopenharmony_ci }), 5401cb0ef41Sopenharmony_ci }; 5411cb0ef41Sopenharmony_ci 5421cb0ef41Sopenharmony_ci const writable = new WritableStream(source); 5431cb0ef41Sopenharmony_ci 5441cb0ef41Sopenharmony_ci const { port1, port2 } = new MessageChannel(); 5451cb0ef41Sopenharmony_ci 5461cb0ef41Sopenharmony_ci port1.onmessage = common.mustCall(({ data }) => { 5471cb0ef41Sopenharmony_ci const m = new WebAssembly.Memory({ initial: 1 }); 5481cb0ef41Sopenharmony_ci const writer = data.getWriter(); 5491cb0ef41Sopenharmony_ci const write = writer.write(m); 5501cb0ef41Sopenharmony_ci assert.rejects(write, { code: 25, name: 'DataCloneError' }); 5511cb0ef41Sopenharmony_ci port1.close(); 5521cb0ef41Sopenharmony_ci }); 5531cb0ef41Sopenharmony_ci 5541cb0ef41Sopenharmony_ci port2.postMessage(writable, [writable]); 5551cb0ef41Sopenharmony_ci} 5561cb0ef41Sopenharmony_ci 5571cb0ef41Sopenharmony_ci{ 5581cb0ef41Sopenharmony_ci const readable = new ReadableStream(); 5591cb0ef41Sopenharmony_ci readable.getReader(); 5601cb0ef41Sopenharmony_ci assert.throws(() => readable[kTransfer](), { 5611cb0ef41Sopenharmony_ci code: 25, 5621cb0ef41Sopenharmony_ci name: 'DataCloneError', 5631cb0ef41Sopenharmony_ci }); 5641cb0ef41Sopenharmony_ci 5651cb0ef41Sopenharmony_ci const writable = new WritableStream(); 5661cb0ef41Sopenharmony_ci writable.getWriter(); 5671cb0ef41Sopenharmony_ci assert.throws(() => writable[kTransfer](), { 5681cb0ef41Sopenharmony_ci code: 25, 5691cb0ef41Sopenharmony_ci name: 'DataCloneError', 5701cb0ef41Sopenharmony_ci }); 5711cb0ef41Sopenharmony_ci} 572