Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use async iterable webidl type in ReadableStream.from #1310

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from
Draft
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 15 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 @@ -2123,43 +2123,27 @@ The following abstract operations operate on {{ReadableStream}} instances at a h
</div>

<div algorithm>
<dfn abstract-op lt="ReadableStreamFromIterable" id="readable-stream-from-iterable">
<dfn abstract-op export lt="ReadableStreamFromIterable" id="readable-stream-from-iterable">
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why export, btw?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will be needed to resolve whatwg/fetch#1291, which is my next project :)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In that case you would want a separate op in section 9, this one is in section 4 and not supposed to be directly used by other specs.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, will revert this here

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|).
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]]=]).
<!-- 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. -->
We'll then need to catch the error and close the async iterator. -->
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| »).
lucacasonato marked this conversation as resolved.
Show resolved Hide resolved
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 [=closing/close an async iterable=] |asyncIterable| with
reason |reason|.
1. Return the result of [=reacting=] to |finishPromise|:
- If |finishPromise| was fulfilled, return undefined.
- If |finishPromise| was rejected with reason |r|, throw |r|.
lucacasonato marked this conversation as resolved.
Show resolved Hide resolved
1. Set |stream| to ! [$CreateReadableStream$](|startAlgorithm|, |pullAlgorithm|, |cancelAlgorithm|,
0).
1. Return |stream|.
Expand Down
Loading