Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 6bf7388

Browse filesBrowse files
mrbbotMylesBorins
authored andcommitted
stream: allow transfer of readable byte streams
Updates the `ReadableStream` constructor to mark byte streams as transferable. When transferred, byte streams become regular streams. Refs: #39062 Refs: https://streams.spec.whatwg.org/#rs-transfer PR-URL: #45955 Reviewed-By: Daeyeon Jeong <daeyeon.dev@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
1 parent 6c69ad6 commit 6bf7388
Copy full SHA for 6bf7388

File tree

Expand file treeCollapse file tree

2 files changed

+63
-9
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

2 files changed

+63
-9
lines changed
Open diff view settings
Collapse file

‎lib/internal/webstreams/readablestream.js‎

Copy file name to clipboardExpand all lines: lib/internal/webstreams/readablestream.js
+8-9Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -281,17 +281,16 @@ class ReadableStream {
281281
this,
282282
source,
283283
extractHighWaterMark(highWaterMark, 0));
284-
return;
284+
} else {
285+
if (type !== undefined)
286+
throw new ERR_INVALID_ARG_VALUE('source.type', type);
287+
setupReadableStreamDefaultControllerFromSource(
288+
this,
289+
source,
290+
extractHighWaterMark(highWaterMark, 1),
291+
extractSizeAlgorithm(size));
285292
}
286293

287-
if (type !== undefined)
288-
throw new ERR_INVALID_ARG_VALUE('source.type', type);
289-
setupReadableStreamDefaultControllerFromSource(
290-
this,
291-
source,
292-
extractHighWaterMark(highWaterMark, 1),
293-
extractSizeAlgorithm(size));
294-
295294
// eslint-disable-next-line no-constructor-return
296295
return makeTransferable(this);
297296
}
Collapse file

‎test/parallel/test-whatwg-webstreams-transfer.js‎

Copy file name to clipboardExpand all lines: test/parallel/test-whatwg-webstreams-transfer.js
+55Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ const {
1515

1616
const {
1717
isReadableStream,
18+
isReadableByteStreamController,
1819
} = require('internal/webstreams/readablestream');
1920

2021
const {
@@ -25,6 +26,10 @@ const {
2526
isTransformStream,
2627
} = require('internal/webstreams/transformstream');
2728

29+
const {
30+
kState,
31+
} = require('internal/webstreams/util');
32+
2833
const {
2934
makeTransferable,
3035
kClone,
@@ -107,6 +112,56 @@ const theData = 'hello';
107112
assert(readable.locked);
108113
}
109114

115+
{
116+
const { port1, port2 } = new MessageChannel();
117+
port1.onmessageerror = common.mustNotCall();
118+
port2.onmessageerror = common.mustNotCall();
119+
120+
// This test repeats the test above, but with a readable byte stream.
121+
// Note transferring a readable byte stream results in a regular
122+
// value-oriented stream on the other side:
123+
// https://streams.spec.whatwg.org/#abstract-opdef-setupcrossrealmtransformwritable
124+
125+
const theByteData = new Uint8Array([1, 2, 3]);
126+
127+
const readable = new ReadableStream({
128+
type: 'bytes',
129+
start: common.mustCall((controller) => {
130+
// `enqueue` will detach its argument's buffer, so clone first
131+
controller.enqueue(theByteData.slice());
132+
controller.close();
133+
}),
134+
});
135+
assert(isReadableByteStreamController(readable[kState].controller));
136+
137+
port2.onmessage = common.mustCall(({ data }) => {
138+
assert(isReadableStream(data));
139+
assert(!isReadableByteStreamController(data[kState].controller));
140+
141+
const reader = data.getReader();
142+
reader.read().then(common.mustCall((chunk) => {
143+
assert.deepStrictEqual(chunk, { done: false, value: theByteData });
144+
}));
145+
146+
port2.close();
147+
});
148+
149+
port1.onmessage = common.mustCall(({ data }) => {
150+
assert(isReadableStream(data));
151+
assert(!isReadableByteStreamController(data[kState].controller));
152+
assert(!data.locked);
153+
port1.postMessage(data, [data]);
154+
assert(data.locked);
155+
});
156+
157+
assert.throws(() => port2.postMessage(readable), {
158+
code: 'ERR_MISSING_TRANSFERABLE_IN_TRANSFER_LIST',
159+
});
160+
161+
port2.postMessage(readable, [readable]);
162+
assert(readable.locked);
163+
}
164+
110165
{
111166
const { port1, port2 } = new MessageChannel();
112167
port1.onmessageerror = common.mustNotCall();

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.