summaryrefslogtreecommitdiff
path: root/ext/webidl/00_webidl.js
diff options
context:
space:
mode:
authorLeo Kettmeir <crowlkats@toaxl.com>2024-08-06 00:13:02 -0700
committerGitHub <noreply@github.com>2024-08-06 00:13:02 -0700
commitba40347a35d10cffeae83ee95f69f7bc281096dd (patch)
tree0e981a32601937293967815292d5bf617914163a /ext/webidl/00_webidl.js
parentf0cd2c45fcd4dfb841cee9d36bdda3be25c1a2a5 (diff)
feat(fetch): accept async iterables for body (#24623)
Implements https://github.com/whatwg/webidl/pull/1397 Fixes #21454 Closes #24849
Diffstat (limited to 'ext/webidl/00_webidl.js')
-rw-r--r--ext/webidl/00_webidl.js126
1 files changed, 126 insertions, 0 deletions
diff --git a/ext/webidl/00_webidl.js b/ext/webidl/00_webidl.js
index 9ea2200f3..7440e47e7 100644
--- a/ext/webidl/00_webidl.js
+++ b/ext/webidl/00_webidl.js
@@ -26,6 +26,7 @@ const {
Float32Array,
Float64Array,
FunctionPrototypeBind,
+ FunctionPrototypeCall,
Int16Array,
Int32Array,
Int8Array,
@@ -77,6 +78,7 @@ const {
StringPrototypeToWellFormed,
Symbol,
SymbolIterator,
+ SymbolAsyncIterator,
SymbolToStringTag,
TypedArrayPrototypeGetBuffer,
TypedArrayPrototypeGetSymbolToStringTag,
@@ -919,6 +921,127 @@ function createSequenceConverter(converter) {
};
}
+function isAsyncIterator(obj) {
+ if (obj[SymbolAsyncIterator] === undefined) {
+ if (obj[SymbolIterator] === undefined) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+const AsyncIterable = Symbol("[[asyncIterable]]");
+
+function createAsyncIterableConverter(converter) {
+ return function (
+ V,
+ prefix = undefined,
+ context = undefined,
+ opts = { __proto__: null },
+ ) {
+ if (type(V) !== "Object") {
+ throw makeException(
+ TypeError,
+ "can not be converted to async iterable.",
+ prefix,
+ context,
+ );
+ }
+
+ let isAsync = true;
+ let method = V[SymbolAsyncIterator];
+ if (method === undefined) {
+ method = V[SymbolIterator];
+
+ if (method === undefined) {
+ throw makeException(
+ TypeError,
+ "is not iterable.",
+ prefix,
+ context,
+ );
+ }
+
+ isAsync = false;
+ }
+
+ return {
+ value: V,
+ [AsyncIterable]: AsyncIterable,
+ open(context) {
+ const iter = FunctionPrototypeCall(method, V);
+ if (type(iter) !== "Object") {
+ throw new TypeError(
+ `${context} could not be iterated because iterator method did not return object, but ${
+ type(iter)
+ }.`,
+ );
+ }
+
+ let asyncIterator = iter;
+
+ if (!isAsync) {
+ asyncIterator = {
+ // deno-lint-ignore require-await
+ async next() {
+ // deno-lint-ignore prefer-primordials
+ return iter.next();
+ },
+ };
+ }
+
+ return {
+ async next() {
+ // deno-lint-ignore prefer-primordials
+ const iterResult = await asyncIterator.next();
+ if (type(iterResult) !== "Object") {
+ throw TypeError(
+ `${context} failed to iterate next value because the next() method did not return an object, but ${
+ type(iterResult)
+ }.`,
+ );
+ }
+
+ if (iterResult.done) {
+ return { done: true };
+ }
+
+ const iterValue = converter(
+ iterResult.value,
+ `${context} failed to iterate next value`,
+ `The value returned from the next() method`,
+ opts,
+ );
+
+ return { done: false, value: iterValue };
+ },
+ async return(reason) {
+ if (asyncIterator.return === undefined) {
+ return undefined;
+ }
+
+ // deno-lint-ignore prefer-primordials
+ const returnPromiseResult = await asyncIterator.return(reason);
+ if (type(returnPromiseResult) !== "Object") {
+ throw TypeError(
+ `${context} failed to close iterator because the return() method did not return an object, but ${
+ type(returnPromiseResult)
+ }.`,
+ );
+ }
+
+ return undefined;
+ },
+ [SymbolAsyncIterator]() {
+ return this;
+ },
+ };
+ },
+ };
+ };
+}
+
function createRecordConverter(keyConverter, valueConverter) {
return (V, prefix, context, opts) => {
if (type(V) !== "Object") {
@@ -1287,9 +1410,11 @@ function setlike(obj, objPrototype, readonly) {
export {
assertBranded,
+ AsyncIterable,
brand,
configureInterface,
converters,
+ createAsyncIterableConverter,
createBranded,
createDictionaryConverter,
createEnumConverter,
@@ -1300,6 +1425,7 @@ export {
createSequenceConverter,
illegalConstructor,
invokeCallbackFunction,
+ isAsyncIterator,
makeException,
mixinPairIterable,
requiredArguments,