@@ -26,6 +26,14 @@ WPT Display: open
2626urlPrefix: 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
2937urlPrefix: 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