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

Spec from() static converter #160

Merged
merged 19 commits into from
Jan 25, 2025
Merged
Changes from all 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
101 changes: 98 additions & 3 deletions spec.bs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,14 @@ WPT Display: open
urlPrefix: https://tc39.es/ecma262/#; spec: ECMASCRIPT
type: dfn
text: current realm
text: Object; url: sec-object-type
text: normal completion; url: sec-normalcompletion
text: throw completion; url: sec-throwcompletion
url: sec-returnifabrupt-shorthands
text: ?
text: !
type: abstract-op
text: Type; url: sec-ecmascript-data-types-and-values
urlPrefix: https://dom.spec.whatwg.org; spec: DOM
type: dfn
for: event listener
Expand All @@ -38,6 +46,11 @@ urlPrefix: https://dom.spec.whatwg.org; spec: DOM
text: dependent signals; url: abortsignal-dependent-signals
text: signal abort; url:abortsignal-signal-abort
text: abort reason; url:abortsignal-abort-reason
urlPrefix: https://webidl.spec.whatwg.org; spec: WEBIDL
type: dfn
text: a promise rejected with
type: dfn
text: react
</pre>

<style>
Expand Down Expand Up @@ -371,7 +384,7 @@ interface Observable {
//
// takeUntil() can consume promises, iterables, async iterables, and other
// observables.
Observable takeUntil(any notifier);
Observable takeUntil(any value);
Observable map(Mapper mapper);
Observable filter(Predicate predicate);
Observable take(unsigned long long amount);
Expand Down Expand Up @@ -461,6 +474,80 @@ An <dfn>internal observer</dfn> is a [=struct=] with the following [=struct/item
[[#promise-returning-operators]] that make use of this, for example.</p>
</div>

<div algorithm>
To <dfn for=Observable>convert to an Observable</dfn> an {{any}} |value|, run these steps:

Note: We split this algorithm out from the Web IDL {{Observable/from()}} method, so that
spec prose can <a for=Observable lt="convert to an observable">convert</a> values to without
going through the Web IDL bindings.

1. If [$Type$](|value|) is not [=Object=], [=exception/throw=] a {{TypeError}}.

Note: This prevents primitive types from being coerced into iterables (e.g., String). See
discussion in <a href=https://github.com/WICG/observable/issues/125>WICG/observable#125</a>.

1. <i id=from-observable-conversion><b>From Observable</b></i>: If |value|'s [=specific type=]
is an {{Observable}}, then return |value|.

1. Issue: Spec the <i><b>From async iterable</b></i> conversion steps which take place before
the iterable conversion steps.

1. <i id=from-iterable-conversion><b>From iterable</b></i>: Let |iteratorMethod| be [=?=]
[$GetMethod$](|value|, {{%Symbol.iterator%}}).

1. If |iteratorMethod| is undefined, then jump to the step labeled <a
href=#from-promise-conversion>From Promise</a>.

Otherwise, return a [=new=] {{Observable}} whose [=Observable/subscribe callback=] is an
algorithm that takes a {{Subscriber}} |subscriber| and does the following:

1. Let |iteratorRecordCompletion| be [$GetIterator$](|value|, sync).

1. If |iteratorRecordCompletion| is a [=throw completion=], then run |subscriber|'s
{{Subscriber/error()}} method, given |iteratorRecordCompletion|'s \[[Value]], and abort
these steps.

1. Let |iteratorRecord| be [=!=] |iteratorRecordCompletion|.

1. [=iteration/While=] true:

1. Let |next| be [$IteratorStepValue$](|iteratorRecord|).

1. If |next| is a [=throw completion=], then run |subscriber|'s {{Subscriber/error()}}
method, given |next|'s \[[Value]], and [=iteration/break=].

1. Set |next| to [=!=] to |next|.

1. If |next| is done, then:

1. [=Assert=]: |iteratorRecord|'s \[[Done]] is true.

2. Run |subscriber|'s {{Subscriber/complete()}}.

3. Return.

1. Run |subscriber|'s {{Subscriber/next()}} given |next|.

1. <i id=from-promise-conversion><b>From Promise</b></i>: If [$IsPromise$](|value|) is true,
then:

1. Return a [=new=] {{Observable}} whose [=Observable/subscribe callback=] is an algorithm
that takes a {{Subscriber}} |subscriber| and does the following:

1. [=React=] to |value|:

1. If |value| was fulfilled with value |v|, then:

1. Run |subscriber|'s {{Subscriber/next()}} method, given |v|.

1. Run |subscriber|'s {{Subscriber/complete()}} method.

1. If |value| was rejected with reason |r|, then run |subscriber|'s
{{Subscriber/error()}} method, given |r|.

1. [=exception/Throw=] a {{TypeError}}.
</div>

<div algorithm>
To <dfn for=Observable>subscribe to an {{Observable}}</dfn> given an
{{ObserverUnion}}-or-[=internal observer=] |observer|, and a {{SubscribeOptions}} |options|, run
Expand Down Expand Up @@ -577,15 +664,23 @@ For now, see [https://github.com/wicg/observable#operators](https://github.com/w

<h4 id=observable-from>{{Observable/from()}}</h4>

<p class=XXX>Spec the exact semantics of {{Observable/from()}} conversion.</p>
<div algorithm>
The <dfn for=Observable method><code>from(|value|)</code></dfn> method steps are:

1. Return the result of <a for=Observable lt="convert to an Observable">converting</a> |value|
to an {{Observable}}. Rethrow any exceptions.
</div>

<h4 id=observable-returning-operators>{{Observable}}-returning operators</h4>

<div algorithm>
The <dfn for=Observable method><code>takeUntil(|notifier|)</code></dfn> method steps are:
The <dfn for=Observable method><code>takeUntil(|value|)</code></dfn> method steps are:

1. Let |sourceObservable| be [=this=].

1. Let |notifier| be the result of <a for=Observable lt="convert to an Observable">
converting</a> |value| to an Observable.

1. Let |observable| be a [=new=] {{Observable}} whose [=Observable/subscribe callback=] is an
algorithm that takes a {{Subscriber}} |subscriber| and does the following:

Expand Down
Loading