Skip to content

Commit e55ddb6

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

File tree

1 file changed

+30
-23
lines changed

1 file changed

+30
-23
lines changed

ext/web/06_streams.js

Lines changed: 30 additions & 23 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");
5108+
}
5109+
if (typeof iterator.next !== "function") {
5110+
throw new TypeError("iterator.next is not a function");
51125111
}
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,26 +5208,29 @@ 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) {
52165220
readableStreamDefaultControllerClose(stream[_controller]);
52175221
} else {
5218-
readableStreamDefaultControllerEnqueue(stream[_controller], res.value);
5222+
readableStreamDefaultControllerEnqueue(
5223+
stream[_controller],
5224+
await res.value,
5225+
);
52195226
}
52205227
}, async (reason) => {
5221-
if (typeof iterator.return === "undefined") {
5228+
if (iterator.return == null) {
52225229
return undefined;
52235230
} else {
52245231
// deno-lint-ignore prefer-primordials
52255232
const res = await iterator.return(reason);
5226-
if (typeof res !== "object") {
5233+
if (!isObject(res)) {
52275234
throw new TypeError("iterator.return value is not an object");
52285235
} else {
52295236
return undefined;

0 commit comments

Comments
 (0)