Skip to content

Commit a89d7c5

Browse files
Spec from() static converter (#160)
This PR implements the `from()` static conversion operator, with the exception of the async iterable conversion semantics which is tracked as a follow-up issue in #191. This PR also uses the "from" conversion algorithm in `takeUntil()` on the notifier argument, for starters. --------- Co-authored-by: Dominic Farolino <[email protected]>
1 parent 5df4a38 commit a89d7c5

File tree

1 file changed

+98
-3
lines changed

1 file changed

+98
-3
lines changed

spec.bs

Lines changed: 98 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,14 @@ WPT Display: open
2626
urlPrefix: https://tc39.es/ecma262/#; spec: ECMASCRIPT
2727
type: dfn
2828
text: current realm
29+
text: Object; url: sec-object-type
30+
text: normal completion; url: sec-normalcompletion
31+
text: throw completion; url: sec-throwcompletion
32+
url: sec-returnifabrupt-shorthands
33+
text: ?
34+
text: !
35+
type: abstract-op
36+
text: Type; url: sec-ecmascript-data-types-and-values
2937
urlPrefix: https://dom.spec.whatwg.org; spec: DOM
3038
type: dfn
3139
for: event listener
@@ -38,6 +46,11 @@ urlPrefix: https://dom.spec.whatwg.org; spec: DOM
3846
text: dependent signals; url: abortsignal-dependent-signals
3947
text: signal abort; url:abortsignal-signal-abort
4048
text: abort reason; url:abortsignal-abort-reason
49+
urlPrefix: https://webidl.spec.whatwg.org; spec: WEBIDL
50+
type: dfn
51+
text: a promise rejected with
52+
type: dfn
53+
text: react
4154
</pre>
4255

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

477+
<div algorithm>
478+
To <dfn for=Observable>convert to an Observable</dfn> an {{any}} |value|, run these steps:
479+
480+
Note: We split this algorithm out from the Web IDL {{Observable/from()}} method, so that
481+
spec prose can <a for=Observable lt="convert to an observable">convert</a> values to without
482+
going through the Web IDL bindings.
483+
484+
1. If [$Type$](|value|) is not [=Object=], [=exception/throw=] a {{TypeError}}.
485+
486+
Note: This prevents primitive types from being coerced into iterables (e.g., String). See
487+
discussion in <a href=https://github.com/WICG/observable/issues/125>WICG/observable#125</a>.
488+
489+
1. <i id=from-observable-conversion><b>From Observable</b></i>: If |value|'s [=specific type=]
490+
is an {{Observable}}, then return |value|.
491+
492+
1. Issue: Spec the <i><b>From async iterable</b></i> conversion steps which take place before
493+
the iterable conversion steps.
494+
495+
1. <i id=from-iterable-conversion><b>From iterable</b></i>: Let |iteratorMethod| be [=?=]
496+
[$GetMethod$](|value|, {{%Symbol.iterator%}}).
497+
498+
1. If |iteratorMethod| is undefined, then jump to the step labeled <a
499+
href=#from-promise-conversion>From Promise</a>.
500+
501+
Otherwise, return a [=new=] {{Observable}} whose [=Observable/subscribe callback=] is an
502+
algorithm that takes a {{Subscriber}} |subscriber| and does the following:
503+
504+
1. Let |iteratorRecordCompletion| be [$GetIterator$](|value|, sync).
505+
506+
1. If |iteratorRecordCompletion| is a [=throw completion=], then run |subscriber|'s
507+
{{Subscriber/error()}} method, given |iteratorRecordCompletion|'s \[[Value]], and abort
508+
these steps.
509+
510+
1. Let |iteratorRecord| be [=!=] |iteratorRecordCompletion|.
511+
512+
1. [=iteration/While=] true:
513+
514+
1. Let |next| be [$IteratorStepValue$](|iteratorRecord|).
515+
516+
1. If |next| is a [=throw completion=], then run |subscriber|'s {{Subscriber/error()}}
517+
method, given |next|'s \[[Value]], and [=iteration/break=].
518+
519+
1. Set |next| to [=!=] to |next|.
520+
521+
1. If |next| is done, then:
522+
523+
1. [=Assert=]: |iteratorRecord|'s \[[Done]] is true.
524+
525+
2. Run |subscriber|'s {{Subscriber/complete()}}.
526+
527+
3. Return.
528+
529+
1. Run |subscriber|'s {{Subscriber/next()}} given |next|.
530+
531+
1. <i id=from-promise-conversion><b>From Promise</b></i>: If [$IsPromise$](|value|) is true,
532+
then:
533+
534+
1. Return a [=new=] {{Observable}} whose [=Observable/subscribe callback=] is an algorithm
535+
that takes a {{Subscriber}} |subscriber| and does the following:
536+
537+
1. [=React=] to |value|:
538+
539+
1. If |value| was fulfilled with value |v|, then:
540+
541+
1. Run |subscriber|'s {{Subscriber/next()}} method, given |v|.
542+
543+
1. Run |subscriber|'s {{Subscriber/complete()}} method.
544+
545+
1. If |value| was rejected with reason |r|, then run |subscriber|'s
546+
{{Subscriber/error()}} method, given |r|.
547+
548+
1. [=exception/Throw=] a {{TypeError}}.
549+
</div>
550+
464551
<div algorithm>
465552
To <dfn for=Observable>subscribe to an {{Observable}}</dfn> given an
466553
{{ObserverUnion}}-or-[=internal observer=] |observer|, and a {{SubscribeOptions}} |options|, run
@@ -577,15 +664,23 @@ For now, see [https://github.com/wicg/observable#operators](https://github.com/w
577664

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

580-
<p class=XXX>Spec the exact semantics of {{Observable/from()}} conversion.</p>
667+
<div algorithm>
668+
The <dfn for=Observable method><code>from(|value|)</code></dfn> method steps are:
669+
670+
1. Return the result of <a for=Observable lt="convert to an Observable">converting</a> |value|
671+
to an {{Observable}}. Rethrow any exceptions.
672+
</div>
581673

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

584676
<div algorithm>
585-
The <dfn for=Observable method><code>takeUntil(|notifier|)</code></dfn> method steps are:
677+
The <dfn for=Observable method><code>takeUntil(|value|)</code></dfn> method steps are:
586678

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

681+
1. Let |notifier| be the result of <a for=Observable lt="convert to an Observable">
682+
converting</a> |value| to an Observable.
683+
589684
1. Let |observable| be a [=new=] {{Observable}} whose [=Observable/subscribe callback=] is an
590685
algorithm that takes a {{Subscriber}} |subscriber| and does the following:
591686

0 commit comments

Comments
 (0)