Skip to content

Commit

Permalink
Use async iterable webidl type in ReadableStream.from
Browse files Browse the repository at this point in the history
  • Loading branch information
lucacasonato committed Mar 25, 2024
1 parent 007d729 commit 7271cc8
Showing 1 changed file with 13 additions and 31 deletions.
44 changes: 13 additions & 31 deletions index.bs
Original file line number Diff line number Diff line change
Expand Up @@ -488,7 +488,7 @@ The Web IDL definition for the {{ReadableStream}} class is given as follows:
interface ReadableStream {
constructor(optional object underlyingSource, optional QueuingStrategy strategy = {});

static ReadableStream from(any asyncIterable);
static ReadableStream from(async iterable<any> asyncIterable);

readonly attribute boolean locked;

Expand Down Expand Up @@ -2127,39 +2127,21 @@ The following abstract operations operate on {{ReadableStream}} instances at a h
ReadableStreamFromIterable(|asyncIterable|)</dfn> performs the following steps:

1. Let |stream| be undefined.
1. Let |iteratorRecord| be ? [$GetIterator$](|asyncIterable|, async).
1. Let |startAlgorithm| be an algorithm that returns undefined.
1. Let |pullAlgorithm| be the following steps:
1. Let |nextResult| be [$IteratorNext$](|iteratorRecord|).
1. If |nextResult| is an abrupt completion, return [=a promise rejected with=]
|nextResult|.\[[Value]].
1. Let |nextPromise| be [=a promise resolved with=] |nextResult|.\[[Value]].
1. Return the result of [=reacting=] to |nextPromise| with the following fulfillment steps,
given |iterResult|:
1. If [$Type$](|iterResult|) is not Object, throw a {{TypeError}}.
1. Let |done| be ? [$IteratorComplete$](|iterResult|).
1. If |done| is true:
1. Perform ! [$ReadableStreamDefaultControllerClose$](|stream|.[=ReadableStream/[[controller]]=]).
1. Otherwise:
1. Let |value| be ? [$IteratorValue$](|iterResult|).
1. Perform ! [$ReadableStreamDefaultControllerEnqueue$](|stream|.[=ReadableStream/[[controller]]=],
|value|).
<!-- TODO (future): If we allow changing the queuing strategy, this Enqueue might throw.
We'll then need to catch the error and close the async iterator. -->
1. Let |nextPromise| be the result of [=getting the next value/get an async iterable next value=]
from |asyncIterable|.
1. Return the result of [=reacting=] to |nextPromise|:
- If |next| was fulfilled with value |v|:
1. If |v| is [=end of iteration=], perform ! [$ReadableStreamDefaultControllerClose$](|stream|.[=ReadableStream/[[controller]]=]).
1. Otherwise, perform ! [$ReadableStreamDefaultControllerEnqueue$](|stream|.[=ReadableStream/[[controller]]=], |v|).
- If |next| was rejected with reason |r|, perform ! [$ReadableStreamDefaultControllerError$](|stream|.[=ReadableStream/[[controller]]=], |r|).
1. Let |cancelAlgorithm| be the following steps, given |reason|:
1. Let |iterator| be |iteratorRecord|.\[[Iterator]].
1. Let |returnMethod| be [$GetMethod$](|iterator|, "`return`").
1. If |returnMethod| is an abrupt completion, return [=a promise rejected with=]
|returnMethod|.\[[Value]].
1. If |returnMethod|.\[[Value]] is undefined, return [=a promise resolved with=] undefined.
1. Let |returnResult| be [$Call$](|returnMethod|.\[[Value]], |iterator|, « |reason| »).
1. If |returnResult| is an abrupt completion, return [=a promise rejected with=]
|returnResult|.\[[Value]].
1. Let |returnPromise| be [=a promise resolved with=] |returnResult|.\[[Value]].
1. Return the result of [=reacting=] to |returnPromise| with the following fulfillment steps,
given |iterResult|:
1. If [$Type$](|iterResult|) is not Object, throw a {{TypeError}}.
1. Return undefined.
1. Let |finishPromise| be the result of [=finishing iteration/finish iterating an async iterable=]
of |asyncIterable|.
1. Return the result of [=reacting=] to |finishPromise|:
- If |finishPromise| was fulfilled, return undefined.
- If |finishPromise| was rejected with reason |r|, throw |r|.
1. Set |stream| to ! [$CreateReadableStream$](|startAlgorithm|, |pullAlgorithm|, |cancelAlgorithm|,
0).
1. Return |stream|.
Expand Down

0 comments on commit 7271cc8

Please sign in to comment.