From 9268b939e26f97f6165159e8e7bca8750becd477 Mon Sep 17 00:00:00 2001 From: Isiah Meadows Date: Thu, 16 Aug 2018 04:52:06 -0400 Subject: [PATCH 1/4] Fix various consistency/technical issues within the spec. --- spec/constructor-properties.html | 59 +++++++++++++++----------- spec/index.html | 24 ++++++++++- spec/prototype-properties.html | 31 +++++++------- spec/subscription-observer.html | 72 +++++++++++++++----------------- spec/subscription.html | 14 +++---- 5 files changed, 111 insertions(+), 89 deletions(-) diff --git a/spec/constructor-properties.html b/spec/constructor-properties.html index 5cee5c9..3ee996c 100644 --- a/spec/constructor-properties.html +++ b/spec/constructor-properties.html @@ -13,21 +13,21 @@

Observable.from ( _x_ )

1. Let _C_ be the *this* value. - 1. If IsConstructor(C) is *false*, let _C_ be %Observable%. + 1. If IsConstructor(_C_) is *false*, let _C_ be %Observable%. 1. Let _observableMethod_ be ? GetMethod(_x_, `@@observable`). 1. If _observableMethod_ is not *undefined*, then - 1. Let _observable_ be ? Call(_observableMethod_, _x_, «‍ »). + 1. Let _observable_ be ? Call(_observableMethod_, _x_, « »). 1. If Type(_observable_) is not Object, throw a *TypeError* exception. 1. Let _constructor_ be ? Get(_observable_, `"constructor"`). 1. If SameValue(_constructor_, _C_) is *true*, return _observable_. 1. Let _subscriber_ be a new built-in function object as defined in Observable.from Delegating Functions. - 1. Set _subscriber_'s [[Observable]] internal slot to _observable_. + 1. Set _subscriber_.[[Observable]] to _observable_. 1. Else, - 1. Let _iteratorMethod_ be ? GetMethod(_x_, `@@observable`). + 1. Let _iteratorMethod_ be ? GetMethod(_x_, `@@iterator`). 1. If _iteratorMethod_ is *undefined*, throw a *TypeError* exception. 1. Let _subscriber_ be a new built-in function object as defined in Observable.from Iteration Functions. - 1. Set _subscriber_'s [[Iterable]] internal slot to _x_. - 1. Set _subscriber_'s [[IteratorMethod]] internal slot to _iteratorMethod_. + 1. Set _subscriber_.[[Iterable]] to _x_. + 1. Set _subscriber_.[[IteratorMethod]] to _iteratorMethod_. 1. Return Construct(_C_, « ‍_subscriber_ »). @@ -39,7 +39,9 @@

Observable.from Delegating Functions

When an Observable.from delegating function is called with argument _observer_, the following steps are taken:

- 1. Let _observable_ be the value of the [[Observable]] internal slot of _F_. + 1. Assert: _F_ has an [[Observable]] internal slot whose value is an Object. + 1. If Type(_observer_) is not Object, throw a *TypeError* exception. + 1. Let _observable_ be _F_.[[Observable]]. 1. Return Invoke(_observable_, `"subscribe"`, « ‍_observer_ »). @@ -49,24 +51,29 @@

Observable.from Delegating Functions

Observable.from Iteration Functions

-

An Observable.from iteration function is an anonymous built-in function that has [[Iterable]] and [[IteratorFunction]] internal slots.

+

An Observable.from iteration function is an anonymous built-in function that has [[Iterable]] and [[IteratorMethod]] internal slots.

When an Observable.from iteration function is called with argument _observer_, the following steps are taken:

- 1. Let _iterable_ be the value of the [[Iterable]] internal slot of _F_. - 1. Let _iteratorMethod_ be the value of the [[IteratorMethod]] internal slot of _F_. - 1. Let _iterator_ be ? GetIterator(_items_, _iteratorMethod_). - 1. Let _subscription_ be the value of _observer_'s [[Subscription]] internal slot. + 1. Assert: _F_ has an [[Iterable]] internal slot whose value is an Object. + 1. Assert: _F_ has an [[IteratorMethod]] internal slot whose value is an Object. + 1. Assert: IsCallable(_F_.[[IteratorMethod]]) is *true*. + 1. If Type(_observer_) is not Object, throw a *TypeError* exception. + 1. Let _iterable_ be _F_.[[Iterable]]. + 1. Let _iteratorMethod_ be _F_.[[IteratorMethod]]. + 1. Let _iterator_ be ? GetIterator(_iterable_, ~sync~, _iteratorMethod_). 1. Repeat + 1. Let _closed_ be ? ToBoolean(? GetV(_observer_, `"closed"`)). + 1. If _closed_ is *true*, then + 1. Perform ? IteratorClose(_iterator_, *undefined*). + 1. Return *undefined*. 1. Let _next_ be ? IteratorStep(_iterator_). 1. If _next_ is *false*, then - 1. Perform ! Invoke(_observer_, `"complete"`, «‍ »). + 1. Perform ? Invoke(_observer_, `"complete"`, « »). 1. Return *undefined*. 1. Let _nextValue_ be ? IteratorValue(_next_). - 1. Perform ! Invoke(_observer_, `"next"`, « ‍_nextValue_ »). - 1. If SubscriptionClosed(_subscription_) is *true*, then - 1. Return ? IteratorClose(_iterator_, *undefined*). + 1. Perform ? Invoke(_observer_, `"next"`, « ‍_nextValue_ »).

The `length` property of an Observable.from iteration function is `1`.

@@ -79,9 +86,10 @@

Observable.of ( ..._items_ )

1. Let _C_ be the *this* value. - 1. If IsConstructor(C) is *false*, let _C_ be %Observable%. + 1. If IsConstructor(_C_) is *false*, let _C_ be %Observable%. 1. Let _subscriber_ be a new built-in function object as defined in Observable.of Subscriber Functions. - 1. Set _subscriber_'s [[Items]] internal slot to _items_. + 1. Let _items_ be the List of arguments passed to this function. + 1. Set _subscriber_.[[Items]] to _items_. 1. Return Construct(_C_, « ‍_subscriber_ »). @@ -93,13 +101,16 @@

Observable.of Subscriber Functions

When an Observable.of subscriber function is called with argument _observer_, the following steps are taken:

- 1. Let _items_ be the value of the [[Items]] internal slot of _F_. - 1. Let _subscription_ be the value of _observer_'s [[Subscription]] internal slot. + 1. Assert: _F_ has an [[Items]] internal slot whose value is a List. + 1. If Type(_observer_) is not Object, throw a *TypeError* exception. + 1. Let _items_ be _F_.[[Items]]. 1. For each element _value_ of _items_ - 1. Perform ! Invoke(_observer_, `"next"`, « ‍_value_ »). - 1. If SubscriptionClosed(_subscription_) is *true*, then - 1. Return *undefined*. - 1. Perform ! Invoke(_observer_, `"complete"`, «‍ »). + 1. Let _closed_ be ? ToBoolean(? GetV(_observer_, `"closed"`)). + 1. If _closed_ is *true*, then return *undefined*. + 1. Perform ? Invoke(_observer_, `"next"`, « ‍_value_ »). + 1. Let _closed_ be ? ToBoolean(? GetV(_observer_, `"closed"`)). + 1. If _closed_ is *true*, then return *undefined*. + 1. Perform ? Invoke(_observer_, `"complete"`, « »). 1. Return *undefined*. diff --git a/spec/index.html b/spec/index.html index 7172572..f8718c8 100644 --- a/spec/index.html +++ b/spec/index.html @@ -9,6 +9,26 @@ contributors: Kevin Smith + +

WarnIfAbrupt ( _completion_, _result_ )

+ +

WarnIfAbrupt is similar to ReturnIfAbrupt, but instead of propagating an error, it returns a value. For example, algorithm steps that say or are otherwise equivalent to:

+ + + 1. WarnIfAbrupt(_argument_, _value_). + + +

mean the same thing as:

+ + + 1. If _argument_ is abrupt, then + 1. Perform HostReportErrors(« _argument_.[[Value]] »). + 1. Return _value_. + 1. Else, + 1. Let _argument_ be _argument_.[[Value]]. + +
+

The Observable Constructor

@@ -28,8 +48,8 @@

Observable ( _subscriber_ )

1. If NewTarget is *undefined*, throw a *TypeError* exception. 1. If IsCallable(_subscriber_) is *false*, throw a *TypeError* exception. - 1. Let _observable_ be ? OrdinaryCreateFromConstructor(NewTarget, %ObservablePrototype%, «‍ [[Subscriber]] »). - 1. Set _observable's_ [[Subscriber]] internal slot to _subscriber_. + 1. Let _observable_ be ? OrdinaryCreateFromConstructor(NewTarget, %ObservablePrototype%, « [[Subscriber]] »). + 1. Set _observable.[[Subscriber]] to _subscriber_. 1. Return _observable_.
diff --git a/spec/prototype-properties.html b/spec/prototype-properties.html index be7703b..020a22f 100644 --- a/spec/prototype-properties.html +++ b/spec/prototype-properties.html @@ -8,7 +8,7 @@

Observable.prototype.subscribe ( _observer_ )

1. Let _O_ be the *this* value. 1. If Type(_O_) is not Object, throw a *TypeError* exception. - 1. If _O_ does not have an [[Subscriber]] internal slot, throw a *TypeError* exception. + 1. If _O_ does not have all the internal slots of an Observable object, throw a *TypeError* exception. 1. If IsCallable(_observer_) is *true*, then 1. Let _len_ be the actual number of arguments passed to this function. 1. Let _args_ be the List of arguments passed to this function. @@ -23,24 +23,21 @@

Observable.prototype.subscribe ( _observer_ )

1. Perform ! CreateDataProperty(_observer_, `"complete"`, _completeCallback_). 1. Else if Type(_observer_) is not Object, Let _observer_ be ObjectCreate(%ObjectPrototype%). 1. Let _subscription_ be ? CreateSubscription(_observer_). - 1. Let _startMethodResult_ be GetMethod(_observer_, `"start"`). - 1. If _startMethodResult_.[[Type]] is ~normal~, then - 1. Let _start_ be _startMethodResult_.[[Value]]. - 1. If _start_ is not *undefined*, then - 1. Let _result_ be Call(_start_, _observer_, « _subscription_ »). - 1. If _result_ is an abrupt completion, perform HostReportErrors(« _result_.[[Value]] »). - 1. If SubscriptionClosed(_subscription_) is *true*, then - 1. Return _subscription_. - 1. Else if _startMethodResult_.[[Type]] is ~throw~, then perform HostReportErrors(« _startMethodResult_.[[Value]] »). - 1. If _result_ is an abrupt completion, perform HostReportErrors(« _result_.[[Value]] »). + 1. Let _start_ be GetMethod(_observer_, `"start"`). + 1. WarnIfAbrupt(_start_, _subscription_). + 1. If _start_ is not *undefined*, then + 1. Let _result_ be Call(_start_, _observer_, « _subscription_ »). + 1. WarnIfAbrupt(_result_, _subscription_). + 1. If SubscriptionClosed(_subscription_) is *true*, then + 1. Return _subscription_. 1. Let _subscriptionObserver_ be ? CreateSubscriptionObserver(_subscription_). - 1. Let _subscriber_ be the value of _O's_ [[Subscriber]] internal slot. + 1. Let _subscriber_ be _O_.[[Subscriber]]. 1. Assert: IsCallable(_subscriber_) is *true*. 1. Let _subscriberResult_ be ExecuteSubscriber(_subscriber_, _subscriptionObserver_). 1. If _subscriberResult_ is an abrupt completion, then - 1. Perform ! Invoke(_subscriptionObserver_, `"error"`, « ‍_subscriberResult_.[[value]] »). + 1. Perform ! EmitSubscriptionHook(_subscriptionObserver_, `"error"`, ‍_subscriberResult_.[[value]]). 1. Else, - 1. Set the [[Cleanup]] internal slot of _subscription_ to _subscriberResult_.[[value]]. + 1. Set _subscription_.[[Cleanup]] to _subscriberResult_.[[value]]. 1. If SubscriptionClosed(_subscription_) is *true*, then 1. Perform ! CleanupSubscription(_subscription_). 1. Return _subscription_. @@ -60,7 +57,7 @@

ExecuteSubscriber ( _subscriber_, _observer_ )

1. Let _result_ be ? GetMethod(_subscriberResult_, `"unsubscribe"`). 1. If _result_ is *undefined*, throw a *TypeError* exception. 1. Let _cleanupFunction_ be a new built-in function object as defined in Subscription Cleanup Functions. - 1. Set _cleanupFunction_'s [[Subscription]] internal slot to _subscriberResult_. + 1. Set _cleanupFunction_.[[Subscription]] to _subscriberResult_. 1. Return _cleanupFunction_.
@@ -73,8 +70,8 @@

Subscription Cleanup Functions

When a subscription cleanup function _F_ is called the following steps are taken:

- 1. Assert: _F_ as a [[Subscription]] internal slot whose value is an Object. - 1. Let _subscription_ be the value of _F_'s [[Subscription]] internal slot. + 1. Assert: _F_ has a [[Subscription]] internal slot whose value is an Object. + 1. Let _subscription_ be _F_.[[Subscription]]. 1. Return Invoke(_subscription_, `"unsubscribe"`, « ‍»). diff --git a/spec/subscription-observer.html b/spec/subscription-observer.html index 1263a88..b88705a 100644 --- a/spec/subscription-observer.html +++ b/spec/subscription-observer.html @@ -9,10 +9,38 @@

CreateSubscriptionObserver ( _subscription_ )

1. Assert: Type(_subscription_) is Object. 1. Let _subscriptionObserver_ be ObjectCreate(%SubscriptionObserverPrototype%, «‍ [[Subscription]] »). - 1. Set _subscriptionObserver_'s [[Subscription]] internal slot to _subscription_. + 1. Set _subscriptionObserver_.[[Subscription]] to _subscription_. 1. Return _subscriptionObserver_. + + +

EmitSubscriptionHook ( _O_, _methodName_ [ , _value_ ] )

+ +

The abstract operation EmitSubscriptionHook with arguments _O_, _methodName_, and optional _value_ is used to invoke method on a given subscriber's observer. It performs the following steps:

+ + + 1. Assert: Type(_O_) is Object. + 1. Assert: _O_ is a Subscription Observer instance. + 1. Assert: Type(_methodName_) is either `"next"`, `"error"`, or `"complete"`. + 1. Assert: _args_ is a List. + 1. Let _subscription_ be _O_.[[Subscription]]. + 1. If SubscriptionClosed(_subscription_) is *true*, return *undefined*. + 1. Let _observer_ be _subscription_.[[Observer]]. + 1. If _methodName_ is not `"next"`, then + 1. Set _subscription_.[[Observer]] to *undefined*. + 1. Assert: Type(_observer_) is Object. + 1. Let _method_ be GetMethod(_observer_, _methodName_). + 1. WarnIfAbrupt(_method_, *undefined*). + 1. If _method_ is not *undefined*, then + 1. If _value_ is present, let _args_ be « value »; otherwise, let _args_ be the empty list. + 1. Let _result_ be Call(_method_, _observer_, _args). + 1. WarnIfAbrupt(_result_, *undefined*). + 1. If _methodName_ is not `"next"`, then + 1. Perform ! CleanupSubscription(_subscription_). + 1. Return *undefined*. + +
@@ -26,7 +54,7 @@

get %SubscriptionObserverPrototype%.closed

1. Let _O_ be the *this* value. 1. If Type(_O_) is not Object, throw a *TypeError* exception. 1. If _O_ does not have all of the internal slots of a Subscription Observer instance, throw a *TypeError* exception. - 1. Let _subscription_ be the value of _O_'s [[Subscription]] internal. + 1. Let _subscription_ be _O_.[[Subscription]]. 1. Return ! SubscriptionClosed(_subscription_).
@@ -37,17 +65,7 @@

%SubscriptionObserverPrototype%.next ( _value_ )

1. Let _O_ be the *this* value. 1. If Type(_O_) is not Object, throw a *TypeError* exception. 1. If _O_ does not have all of the internal slots of a Subscription Observer instance, throw a *TypeError* exception. - 1. Let _subscription_ be the value of _O_'s [[Subscription]] internal slot. - 1. If SubscriptionClosed(_subscription_) is *true*, return *undefined*. - 1. Let _observer_ be the value of _subscription_'s [[Observer]] internal slot. - 1. Assert: Type(_observer_) is Object. - 1. Let _nextMethodResult_ be GetMethod(_observer_, `"next"`). - 1. If _nextMethodResult_.[[Type]] is ~normal~, then - 1. Let _nextMethod_ be _nextMethodResult_.[[Value]]. - 1. If _nextMethod_ is not *undefined*, then - 1. Let _result_ be Call(_nextMethod_, _observer_, « ‍_value_ »). - 1. If _result_ is an abrupt completion, perform HostReportErrors(« _result_.[[Value]] »). - 1. Else if _nextMethodResult_.[[Type]] is ~throw~, then perform HostReportErrors(« _nextMethodResult_.[[Value]] »). + 1. Perform ! EmitSubscriptionHook(_O_, `"next"`, _value_). 1. Return *undefined*. @@ -58,19 +76,7 @@

%SubscriptionObserverPrototype%.error ( _exception_ )

1. Let _O_ be the *this* value. 1. If Type(_O_) is not Object, throw a *TypeError* exception. 1. If _O_ does not have all of the internal slots of a Subscription Observer instance, throw a *TypeError* exception. - 1. Let _subscription_ be the value of _O_'s [[Subscription]] internal slot. - 1. If SubscriptionClosed(_subscription_) is *true*, return *undefined*. - 1. Let _observer_ be the value of _subscription_'s [[Observer]] internal slot. - 1. Set _subscription_'s [[Observer]] internal slot to *undefined*. - 1. Assert: Type(_observer_) is Object. - 1. Let _errorMethodResult_ be GetMethod(_observer_, `"error"`). - 1. If _errorMethodResult_.[[Type]] is ~normal~, then - 1. Let _errorMethod_ be _errorMethodResult_.[[Value]]. - 1. If _errorMethod_ is not *undefined*, then - 1. Let _result_ be Call(_errorMethod_, _observer_, « _exception_ »). - 1. If _result_ is an abrupt completion, perform HostReportErrors(« _result_.[[Value]] »). - 1. Else if _errorMethodResult_.[[Type]] is ~throw~, then perform HostReportErrors(« _errorMethodResult_.[[Value]] »). - 1. Perform ! CleanupSubscription(_subscription_). + 1. Perform ! EmitSubscriptionHook(_O_, `"error"`, _value_). 1. Return *undefined*. @@ -81,19 +87,7 @@

%SubscriptionObserverPrototype%.complete ( )

1. Let _O_ be the *this* value. 1. If Type(_O_) is not Object, throw a *TypeError* exception. 1. If _O_ does not have all of the internal slots of a Subscription Observer instance, throw a *TypeError* exception. - 1. Let _subscription_ be the value of _O_'s [[Subscription]] internal slot. - 1. If SubscriptionClosed(_subscription_) is *true*, return *undefined*. - 1. Let _observer_ be the value of _subscription_'s [[Observer]] internal slot. - 1. Set _subscription_'s [[Observer]] internal slot to *undefined*. - 1. Assert: Type(_observer_) is Object. - 1. Let _completeMethodResult_ be GetMethod(_observer_, `"complete"`). - 1. If _completeMethodResult_.[[Type]] is ~normal~, then - 1. Let _completeMethod_ be _completeMethodResult_.[[Value]]. - 1. If _completeMethod_ is not *undefined*, then - 1. Let _result_ be Call(_completeMethod_, _observer_). - 1. If _result_ is an abrupt completion, perform HostReportErrors(« _result_.[[Value]] »). - 1. Else if _completeMethodResult_.[[Type]] is ~throw~, then perform HostReportErrors(« _completeMethodResult_.[[Value]] »). - 1. Perform ! CleanupSubscription(_subscription_). + 1. Perform ! EmitSubscriptionHook(_O_, `"complete"`). 1. Return *undefined*. diff --git a/spec/subscription.html b/spec/subscription.html index d035c63..32b34d7 100644 --- a/spec/subscription.html +++ b/spec/subscription.html @@ -9,8 +9,8 @@

CreateSubscription ( _observer_ )

1. Assert: Type(_observer_) is Object. 1. Let _subscription_ be ObjectCreate(%SubscriptionPrototype%, «‍ [[Observer]], [[Cleanup]] »). - 1. Set _subscription_'s [[Observer]] internal slot to _observer_. - 1. Set _subscription_'s [[Cleanup]] internal slot to *undefined*. + 1. Set _subscription_.[[Observer]] to _observer_. + 1. Set _subscription_.[[Cleanup]] to *undefined*. 1. Return _subscription_. @@ -22,12 +22,12 @@

CleanupSubscription ( _subscription_ )

1. Assert: _subscription_ is a Subscription object. - 1. Let _cleanup_ be the value of _subscription_'s [[Cleanup]] internal slot. + 1. Let _cleanup_ be _subscription_.[[Cleanup]]. 1. If _cleanup_ is *undefined*, return *undefined*. 1. Assert: IsCallable(_cleanup_) is *true*. - 1. Set _subscription_'s [[Cleanup]] internal slot to *undefined*. + 1. Set _subscription_.[[Cleanup]] to *undefined*. 1. Let _result_ be Call(_cleanup_, *undefined*, «‍ »). - 1. If _result_ is an abrupt completion, perform HostReportErrors(« _result_.[[Value]] »). + 1. WarnIfAbrupt(_result_, *undefined*). 1. Return *undefined*. @@ -39,7 +39,7 @@

SubscriptionClosed ( _subscription_ )

1. Assert: _subscription_ is a Subscription object. - 1. If the value of _subscription_'s [[Observer]] internal slot is *undefined*, return *true*. + 1. If _subscription_.[[Observer]] is *undefined*, return *true*. 1. Else, return *false*. @@ -68,7 +68,7 @@

%SubscriptionPrototype%.unsubscribe ( )

1. If Type(_subscription_) is not Object, throw a *TypeError* exception. 1. If _subscription_ does not have all of the internal slots of a Subscription instance, throw a *TypeError* exception. 1. If SubscriptionClosed(_subscription_) is *true*, return *undefined*. - 1. Set _subscription_'s [[Observer]] internal slot to *undefined*. + 1. Set _subscription_.[[Observer]] to *undefined*. 1. Return CleanupSubscription(_subscription_). From 30815a7d136570b97780cebf45317aa9da6db247 Mon Sep 17 00:00:00 2001 From: Isiah Meadows Date: Thu, 16 Aug 2018 05:04:37 -0400 Subject: [PATCH 2/4] Clarify and correct API description in README. - I used TypeScript syntax more precisely for clarity and better highlighting. --- README.md | 47 ++++++++++++++++++++++------------------------- 1 file changed, 22 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index ce86a8c..47a4648 100644 --- a/README.md +++ b/README.md @@ -99,20 +99,20 @@ require("es-observable-tests").runTests(MyObservable); An Observable represents a sequence of values which may be observed. -```js -interface Observable { - +```ts +class Observable { + // Creates an observable from a callback constructor(subscriber : SubscriberFunction); // Subscribes to the sequence with an observer subscribe(observer : Observer) : Subscription; // Subscribes to the sequence with callbacks - subscribe(onNext : Function, - onError? : Function, - onComplete? : Function) : Subscription; + subscribe(onNext : (value) => void, + onError? : (errorValue) => void, + onComplete? : () => void) : Subscription; - // Returns itself + // Returns itself, but subclasses can override [Symbol.observable]() : Observable; // Converts items to an Observable @@ -120,19 +120,18 @@ interface Observable { // Converts an observable or iterable to an Observable static from(observable) : Observable; - } interface Subscription { - // Cancels the subscription unsubscribe() : void; // A boolean value indicating whether the subscription is closed - get closed() : Boolean; + get closed() : boolean; } -function SubscriberFunction(observer: SubscriptionObserver) : (void => void)|Subscription; +type SubscriberFunction = + (observer : SubscriptionObserver) => (() => void) | Subscription; ``` #### Observable.of #### @@ -159,8 +158,8 @@ Observable.of("red", "green", "blue").subscribe({ `Observable.from` converts its argument to an Observable. - If the argument has a `Symbol.observable` method, then it returns the result of - invoking that method. If the resulting object is not an instance of Observable, - then it is wrapped in an Observable which will delegate subscription. + invoking that method. If the resulting object is not a direct instance of Observable, + then it is wrapped into an Observable which will delegate subscription. - Otherwise, the argument is assumed to be an iterable and the iteration values are delivered synchronously when `subscribe` is called. @@ -216,20 +215,19 @@ argument to **subscribe**. All methods are optional. -```js +```ts interface Observer { - // Receives the subscription object when `subscribe` is called - start(subscription : Subscription); + start(subscription : Subscription) : void; // Receives the next value in the sequence - next(value); + next(value) : void; // Receives the sequence error - error(errorValue); + error(errorValue) : void; // Receives a completion notification - complete(); + complete() : void; } ``` @@ -238,19 +236,18 @@ interface Observer { A SubscriptionObserver is a normalized Observer which wraps the observer object supplied to **subscribe**. -```js +```ts interface SubscriptionObserver { - // Sends the next value in the sequence - next(value); + next(value) : void; // Sends the sequence error - error(errorValue); + error(errorValue) : void; // Sends the completion notification - complete(); + complete() : void; // A boolean value indicating whether the subscription is closed - get closed() : Boolean; + get closed() : boolean; } ``` From 2a465f51ebbcc2cf90152d6a7005b3531b8e072e Mon Sep 17 00:00:00 2001 From: Isiah Meadows Date: Thu, 16 Aug 2018 05:17:28 -0400 Subject: [PATCH 3/4] Implement `@@toStringTag` for the various types --- spec/prototype-properties.html | 8 ++++++++ spec/subscription-observer.html | 8 ++++++++ spec/subscription.html | 8 ++++++++ 3 files changed, 24 insertions(+) diff --git a/spec/prototype-properties.html b/spec/prototype-properties.html index 020a22f..4b37432 100644 --- a/spec/prototype-properties.html +++ b/spec/prototype-properties.html @@ -97,3 +97,11 @@

Observable.prototype [ @@observable ] ( )

The value of the `name` property of this function is `"[Symbol.observable]"`.

+ + +

Observable.prototype [ @@toStringTag ] ( )

+ +

The initial value of the `@@toStringTag` property of `Observable.prototype` is the String value `"Observable"`.

+ +

This property has the attributes { [[Writable]]: *false*, [[Enumerable]]: *false*, [[Configurable]]: *true* }.

+
diff --git a/spec/subscription-observer.html b/spec/subscription-observer.html index b88705a..380bfaf 100644 --- a/spec/subscription-observer.html +++ b/spec/subscription-observer.html @@ -92,4 +92,12 @@

%SubscriptionObserverPrototype%.complete ( )

+ +

%SubscriptionObserverPrototype% [ @@toStringTag ] ( )

+ +

The initial value of the `@@toStringTag` property of %SubscriptionObserverPrototype% is the String value `"Subscription Observer"`.

+ +

This property has the attributes { [[Writable]]: *false*, [[Enumerable]]: *false*, [[Configurable]]: *true* }.

+
+ diff --git a/spec/subscription.html b/spec/subscription.html index 32b34d7..e60f807 100644 --- a/spec/subscription.html +++ b/spec/subscription.html @@ -72,4 +72,12 @@

%SubscriptionPrototype%.unsubscribe ( )

1. Return CleanupSubscription(_subscription_). + + +

%SubscriptionPrototype% [ @@toStringTag ] ( )

+ +

The initial value of the `@@toStringTag` property of %SubscriptionPrototype% is the String value `"Subscription"`.

+ +

This property has the attributes { [[Writable]]: *false*, [[Enumerable]]: *false*, [[Configurable]]: *true* }.

+
From 039c6f16cc7d32f4bb2bdfe4fc4539b9d7e93c9c Mon Sep 17 00:00:00 2001 From: Isiah Meadows Date: Thu, 16 Aug 2018 05:21:25 -0400 Subject: [PATCH 4/4] Defer the `unsubscribe` type check to when the method is invoked --- spec/prototype-properties.html | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/spec/prototype-properties.html b/spec/prototype-properties.html index 4b37432..0040a4a 100644 --- a/spec/prototype-properties.html +++ b/spec/prototype-properties.html @@ -54,8 +54,7 @@

ExecuteSubscriber ( _subscriber_, _observer_ )

1. Let _subscriberResult_ be ? Call(_subscriber_, *undefined*, _observer_). 1. If _subscriberResult_ is *null* or *undefined*, return *undefined*. 1. If IsCallable(_subscriberResult_) is *true*, return _subscriberResult_. - 1. Let _result_ be ? GetMethod(_subscriberResult_, `"unsubscribe"`). - 1. If _result_ is *undefined*, throw a *TypeError* exception. + 1. If Type(_subscriberResult_) is not Object, throw a *TypeError* exception. 1. Let _cleanupFunction_ be a new built-in function object as defined in Subscription Cleanup Functions. 1. Set _cleanupFunction_.[[Subscription]] to _subscriberResult_. 1. Return _cleanupFunction_.