Skip to content

Commit 1266013

Browse files
authored
stream: simplify readableStreamFromIterable
Signed-off-by: Antoine du Hamel <duhamelantoine1995@gmail.com> PR-URL: #62651 Reviewed-By: Aviv Keller <me@aviv.sh>
1 parent df5a925 commit 1266013

File tree

2 files changed

+23
-92
lines changed

2 files changed

+23
-92
lines changed

lib/internal/webstreams/readablestream.js

Lines changed: 23 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ const {
2424
Symbol,
2525
SymbolAsyncIterator,
2626
SymbolDispose,
27+
SymbolIterator,
2728
SymbolToStringTag,
2829
TypedArrayPrototypeGetLength,
2930
Uint8Array,
@@ -32,6 +33,7 @@ const {
3233
const {
3334
AbortError,
3435
codes: {
36+
ERR_ARG_NOT_ITERABLE,
3537
ERR_ILLEGAL_CONSTRUCTOR,
3638
ERR_INVALID_ARG_TYPE,
3739
ERR_INVALID_ARG_VALUE,
@@ -111,8 +113,6 @@ const {
111113
nonOpCancel,
112114
nonOpPull,
113115
nonOpStart,
114-
getIterator,
115-
iteratorNext,
116116
kType,
117117
kState,
118118
} = require('internal/webstreams/util');
@@ -1360,41 +1360,36 @@ function createReadableStreamState() {
13601360

13611361
function readableStreamFromIterable(iterable) {
13621362
let stream;
1363-
const iteratorRecord = getIterator(iterable, 'async');
1364-
1363+
const iteratorGetter = iterable[SymbolAsyncIterator] ?? iterable[SymbolIterator];
1364+
if (iteratorGetter == null || typeof iteratorGetter !== 'function') {
1365+
throw new ERR_ARG_NOT_ITERABLE(iterable);
1366+
}
1367+
const iterator = FunctionPrototypeCall(iteratorGetter, iterable);
13651368
const startAlgorithm = nonOpStart;
13661369

13671370
async function pullAlgorithm() {
1368-
const nextResult = iteratorNext(iteratorRecord);
1369-
const nextPromise = PromiseResolve(nextResult);
1370-
return PromisePrototypeThen(nextPromise, (iterResult) => {
1371-
if (typeof iterResult !== 'object' || iterResult === null) {
1372-
throw new ERR_INVALID_STATE.TypeError(
1373-
'The promise returned by the iterator.next() method must fulfill with an object');
1374-
}
1375-
if (iterResult.done) {
1376-
readableStreamDefaultControllerClose(stream[kState].controller);
1377-
} else {
1378-
readableStreamDefaultControllerEnqueue(stream[kState].controller, iterResult.value);
1379-
}
1380-
});
1371+
const iterResult = await iterator.next();
1372+
if (typeof iterResult !== 'object' || iterResult === null) {
1373+
throw new ERR_INVALID_STATE.TypeError(
1374+
'The promise returned by the iterator.next() method must fulfill with an object');
1375+
}
1376+
if (iterResult.done) {
1377+
readableStreamDefaultControllerClose(stream[kState].controller);
1378+
} else {
1379+
readableStreamDefaultControllerEnqueue(stream[kState].controller, await iterResult.value);
1380+
}
13811381
}
13821382

13831383
async function cancelAlgorithm(reason) {
1384-
const iterator = iteratorRecord.iterator;
13851384
const returnMethod = iterator.return;
13861385
if (returnMethod === undefined) {
1387-
return PromiseResolve();
1386+
return;
1387+
}
1388+
const iterResult = await FunctionPrototypeCall(returnMethod, iterator, reason);
1389+
if (typeof iterResult !== 'object' || iterResult === null) {
1390+
throw new ERR_INVALID_STATE.TypeError(
1391+
'The promise returned by the iterator.return() method must fulfill with an object');
13881392
}
1389-
const returnResult = FunctionPrototypeCall(returnMethod, iterator, reason);
1390-
const returnPromise = PromiseResolve(returnResult);
1391-
return PromisePrototypeThen(returnPromise, (iterResult) => {
1392-
if (typeof iterResult !== 'object' || iterResult === null) {
1393-
throw new ERR_INVALID_STATE.TypeError(
1394-
'The promise returned by the iterator.return() method must fulfill with an object');
1395-
}
1396-
return undefined;
1397-
});
13981393
}
13991394

14001395
stream = createReadableStream(

lib/internal/webstreams/util.js

Lines changed: 0 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,12 @@ const {
1414
ReflectApply,
1515
ReflectGet,
1616
Symbol,
17-
SymbolAsyncIterator,
18-
SymbolIterator,
1917
Uint8Array,
2018
} = primordials;
2119

2220
const {
2321
codes: {
24-
ERR_ARG_NOT_ITERABLE,
2522
ERR_INVALID_ARG_VALUE,
26-
ERR_INVALID_STATE,
2723
},
2824
} = require('internal/errors');
2925

@@ -203,64 +199,6 @@ function lazyTransfer() {
203199
return transfer;
204200
}
205201

206-
function createAsyncFromSyncIterator(syncIteratorRecord) {
207-
const syncIterable = {
208-
[SymbolIterator]: () => syncIteratorRecord.iterator,
209-
};
210-
211-
const asyncIterator = (async function* () {
212-
return yield* syncIterable;
213-
}());
214-
215-
const nextMethod = asyncIterator.next;
216-
return { iterator: asyncIterator, nextMethod, done: false };
217-
}
218-
219-
// Refs: https://tc39.es/ecma262/#sec-getiterator
220-
function getIterator(obj, kind = 'sync', method) {
221-
if (method === undefined) {
222-
if (kind === 'async') {
223-
method = obj[SymbolAsyncIterator];
224-
if (method == null) {
225-
const syncMethod = obj[SymbolIterator];
226-
227-
if (syncMethod === undefined) {
228-
throw new ERR_ARG_NOT_ITERABLE(obj);
229-
}
230-
231-
const syncIteratorRecord = getIterator(obj, 'sync', syncMethod);
232-
return createAsyncFromSyncIterator(syncIteratorRecord);
233-
}
234-
} else {
235-
method = obj[SymbolIterator];
236-
}
237-
}
238-
239-
if (method === undefined) {
240-
throw new ERR_ARG_NOT_ITERABLE(obj);
241-
}
242-
243-
const iterator = FunctionPrototypeCall(method, obj);
244-
if (typeof iterator !== 'object' || iterator === null) {
245-
throw new ERR_INVALID_STATE.TypeError('The iterator method must return an object');
246-
}
247-
const nextMethod = iterator.next;
248-
return { iterator, nextMethod, done: false };
249-
}
250-
251-
function iteratorNext(iteratorRecord, value) {
252-
let result;
253-
if (value === undefined) {
254-
result = FunctionPrototypeCall(iteratorRecord.nextMethod, iteratorRecord.iterator);
255-
} else {
256-
result = FunctionPrototypeCall(iteratorRecord.nextMethod, iteratorRecord.iterator, [value]);
257-
}
258-
if (typeof result !== 'object' || result === null) {
259-
throw new ERR_INVALID_STATE.TypeError('The iterator.next() method must return an object');
260-
}
261-
return result;
262-
}
263-
264202
module.exports = {
265203
ArrayBufferViewGetBuffer,
266204
ArrayBufferViewGetByteLength,
@@ -286,8 +224,6 @@ module.exports = {
286224
nonOpPull,
287225
nonOpStart,
288226
nonOpWrite,
289-
getIterator,
290-
iteratorNext,
291227
kType,
292228
kState,
293229
};

0 commit comments

Comments
 (0)