Skip to content

Commit 8b8d1ab

Browse files
committed
fix(ext/web): ReadableStream.from() allows Iterable <Milly>
1 parent 214cdaa commit 8b8d1ab

File tree

1 file changed

+26
-22
lines changed

1 file changed

+26
-22
lines changed

ext/web/06_streams.js

Lines changed: 26 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5088,28 +5088,32 @@ function initializeCountSizeFunction(globalObject) {
50885088
WeakMapPrototypeSet(countSizeFunctionWeakMap, globalObject, size);
50895089
}
50905090

5091-
async function* createAsyncFromSyncIterator(syncIterator) {
5092-
// deno-lint-ignore prefer-primordials
5093-
yield* syncIterator;
5094-
}
5095-
50965091
// Ref: https://tc39.es/ecma262/#sec-getiterator
5097-
function getIterator(obj, async = false) {
5098-
if (async) {
5099-
if (obj[SymbolAsyncIterator] == null) {
5100-
if (obj[SymbolIterator] == null) {
5101-
throw new TypeError("No iterator found");
5102-
}
5103-
return createAsyncFromSyncIterator(obj);
5104-
} else {
5105-
return obj[SymbolAsyncIterator]();
5092+
function getAsyncOrSyncIterator(obj) {
5093+
let iterator;
5094+
if (obj[SymbolAsyncIterator] != null) {
5095+
iterator = obj[SymbolAsyncIterator]();
5096+
if (!isObject(iterator)) {
5097+
throw new TypeError(
5098+
"[Symbol.asyncIterator] returned a non-object value",
5099+
);
51065100
}
5107-
} else {
5108-
if (obj[SymbolIterator] == null) {
5109-
throw new TypeError("No iterator found");
5101+
} else if (obj[SymbolIterator] != null) {
5102+
iterator = obj[SymbolIterator]();
5103+
if (!isObject(iterator)) {
5104+
throw new TypeError("[Symbol.iterator] returned a non-object value");
51105105
}
5111-
return obj[SymbolIterator]();
5106+
} else {
5107+
throw new TypeError("No iterator found");
51125108
}
5109+
if (typeof iterator.next !== "function") {
5110+
throw new TypeError("iterator.next is not a function");
5111+
}
5112+
return iterator;
5113+
}
5114+
5115+
function isObject(x) {
5116+
return (typeof x === "object" && x != null) || typeof x === "function";
51135117
}
51145118

51155119
const _resourceBacking = Symbol("[[resourceBacking]]");
@@ -5204,12 +5208,12 @@ class ReadableStream {
52045208
);
52055209
asyncIterable = webidl.converters.any(asyncIterable);
52065210

5207-
const iterator = getIterator(asyncIterable, true);
5211+
const iterator = getAsyncOrSyncIterator(asyncIterable);
52085212

52095213
const stream = createReadableStream(noop, async () => {
52105214
// deno-lint-ignore prefer-primordials
52115215
const res = await iterator.next();
5212-
if (typeof res !== "object") {
5216+
if (!isObject(res)) {
52135217
throw new TypeError("iterator.next value is not an object");
52145218
}
52155219
if (res.done) {
@@ -5218,12 +5222,12 @@ class ReadableStream {
52185222
readableStreamDefaultControllerEnqueue(stream[_controller], res.value);
52195223
}
52205224
}, async (reason) => {
5221-
if (typeof iterator.return === "undefined") {
5225+
if (iterator.return == null) {
52225226
return undefined;
52235227
} else {
52245228
// deno-lint-ignore prefer-primordials
52255229
const res = await iterator.return(reason);
5226-
if (typeof res !== "object") {
5230+
if (!isObject(res)) {
52275231
throw new TypeError("iterator.return value is not an object");
52285232
} else {
52295233
return undefined;

0 commit comments

Comments
 (0)