summaryrefslogtreecommitdiff
path: root/ext/web
diff options
context:
space:
mode:
authorLuca Casonato <hello@lcas.dev>2024-11-15 15:54:28 +0100
committerGitHub <noreply@github.com>2024-11-15 15:54:28 +0100
commitb8cf2599242a9d85d03b57d3649ccdf8bce1530e (patch)
tree87a6288f2174aa6d22730a9ec020292b778c9dca /ext/web
parent3f26310728ef2d56ace7370a555eb9a862295983 (diff)
feat(fetch): accept async iterables for body (#26882)
Reland of #24623, but with a fix for `String` objects. Co-authored-by: crowlkats <crowlkats@toaxl.com>
Diffstat (limited to 'ext/web')
-rw-r--r--ext/web/06_streams.js63
1 files changed, 15 insertions, 48 deletions
diff --git a/ext/web/06_streams.js b/ext/web/06_streams.js
index a4f2275c5..f29e5f204 100644
--- a/ext/web/06_streams.js
+++ b/ext/web/06_streams.js
@@ -70,7 +70,6 @@ const {
String,
Symbol,
SymbolAsyncIterator,
- SymbolIterator,
SymbolFor,
TypeError,
TypedArrayPrototypeGetBuffer,
@@ -5084,34 +5083,6 @@ function initializeCountSizeFunction(globalObject) {
WeakMapPrototypeSet(countSizeFunctionWeakMap, globalObject, size);
}
-// Ref: https://tc39.es/ecma262/#sec-getiterator
-function getAsyncOrSyncIterator(obj) {
- let iterator;
- if (obj[SymbolAsyncIterator] != null) {
- iterator = obj[SymbolAsyncIterator]();
- if (!isObject(iterator)) {
- throw new TypeError(
- "[Symbol.asyncIterator] returned a non-object value",
- );
- }
- } else if (obj[SymbolIterator] != null) {
- iterator = obj[SymbolIterator]();
- if (!isObject(iterator)) {
- throw new TypeError("[Symbol.iterator] returned a non-object value");
- }
- } else {
- throw new TypeError("No iterator found");
- }
- if (typeof iterator.next !== "function") {
- throw new TypeError("iterator.next is not a function");
- }
- return iterator;
-}
-
-function isObject(x) {
- return (typeof x === "object" && x != null) || typeof x === "function";
-}
-
const _resourceBacking = Symbol("[[resourceBacking]]");
// This distinction exists to prevent unrefable streams being used in
// regular fast streams that are unaware of refability
@@ -5197,21 +5168,22 @@ class ReadableStream {
}
static from(asyncIterable) {
+ const prefix = "Failed to execute 'ReadableStream.from'";
webidl.requiredArguments(
arguments.length,
1,
- "Failed to execute 'ReadableStream.from'",
+ prefix,
);
- asyncIterable = webidl.converters.any(asyncIterable);
-
- const iterator = getAsyncOrSyncIterator(asyncIterable);
+ asyncIterable = webidl.converters["async iterable<any>"](
+ asyncIterable,
+ prefix,
+ "Argument 1",
+ );
+ const iter = asyncIterable.open();
const stream = createReadableStream(noop, async () => {
// deno-lint-ignore prefer-primordials
- const res = await iterator.next();
- if (!isObject(res)) {
- throw new TypeError("iterator.next value is not an object");
- }
+ const res = await iter.next();
if (res.done) {
readableStreamDefaultControllerClose(stream[_controller]);
} else {
@@ -5221,17 +5193,8 @@ class ReadableStream {
);
}
}, async (reason) => {
- if (iterator.return == null) {
- return undefined;
- } else {
- // deno-lint-ignore prefer-primordials
- const res = await iterator.return(reason);
- if (!isObject(res)) {
- throw new TypeError("iterator.return value is not an object");
- } else {
- return undefined;
- }
- }
+ // deno-lint-ignore prefer-primordials
+ await iter.return(reason);
}, 0);
return stream;
}
@@ -6892,6 +6855,10 @@ webidl.converters.StreamPipeOptions = webidl
{ key: "signal", converter: webidl.converters.AbortSignal },
]);
+webidl.converters["async iterable<any>"] = webidl.createAsyncIterableConverter(
+ webidl.converters.any,
+);
+
internals.resourceForReadableStream = resourceForReadableStream;
export {