From e5f06e6074330bac50465a40062a408626835a71 Mon Sep 17 00:00:00 2001 From: Dominic Farolino Date: Tue, 2 Apr 2024 14:40:52 -0400 Subject: [PATCH 1/3] Spec the `first()` operator --- spec.bs | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) diff --git a/spec.bs b/spec.bs index 24c0651..95a327f 100644 --- a/spec.bs +++ b/spec.bs @@ -358,7 +358,8 @@ interface Observable { Promise> toArray(optional SubscribeOptions options = {}); Promise forEach(Visitor callback, optional SubscribeOptions options = {}); Promise every(Predicate predicate, optional SubscribeOptions options = {}); - // Maybe? Promise first(optional SubscribeOptions options = {}); + Promise first(optional SubscribeOptions options = {}); + Promise last(optional SubscribeOptions options = {}); Promise find(Predicate predicate, optional SubscribeOptions options = {}); Promise some(Predicate predicate, optional SubscribeOptions options = {}); Promise reduce(Reducer reducer, optional any initialValue, optional SubscribeOptions options = {}); @@ -1101,6 +1102,57 @@ For now, see [https://github.com/wicg/observable#operators](https://github.com/w 1. TODO: Spec this and use |predicate| and |options|. +
+ The first(|options|) method steps are: + + 1. Let |p| [=a new promise=]. + + 1. Let |controller| be a [=new=] {{AbortController}}. + + 1. Let |internal options| be a new {{SubscribeOptions}} whose {{SubscribeOptions/signal}} is the + result of [=creating a dependent abort signal=] from the list «|controller|'s + [=AbortController/signal=], |options|'s {{SubscribeOptions/signal}} if non-null», using + {{AbortSignal}}, and the [=current realm=]. + + 1. If |internal options|'s {{SubscribeOptions/signal}} is [=AbortSignal/aborted=], then: + + 1. [=Reject=] |p| with |internal options|'s {{SubscribeOptions/signal}}'s + [=AbortSignal/abort reason=]. + + 1. Return |p|. + + 1. [=AbortSignal/add|Add the following abort algorithm=] to |internal options|'s + {{SubscribeOptions/signal}}: + + 1. [=Reject=] |p| with |internal options|'s {{SubscribeOptions/signal}}'s [=AbortSignal/abort + reason=]. + + 1. Let |internal observer| be a new [=internal observer=], initialized as follows: + + : [=internal observer/next steps=] + :: 1. [=Resolve=] |p| with the passed in value. + + 1. [=AbortController/Signal abort=] |controller|. + + : [=internal observer/error steps=] + :: [=Reject=] |p| with the passed in error. + + : [=internal observer/complete steps=] + :: [=Resolve=] |p| with {{undefined}}. + + 1. Subscribe to [=this=] given |internal + observer| and |internal options|. + + 1. Return |p|. + +
+ +
+ The last(|options|) method steps are: + + 1. TODO: Spec this and use |options|. +
+
The find(|predicate|, |options|) method steps are: From d1366f6a9f4925a4cc02c22939efcb3c47b69516 Mon Sep 17 00:00:00 2001 From: Dominic Farolino Date: Tue, 2 Apr 2024 15:38:30 -0400 Subject: [PATCH 2/3] Completion before next is an error --- spec.bs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/spec.bs b/spec.bs index 95a327f..8293601 100644 --- a/spec.bs +++ b/spec.bs @@ -1138,7 +1138,10 @@ For now, see [https://github.com/wicg/observable#operators](https://github.com/w :: [=Reject=] |p| with the passed in error. : [=internal observer/complete steps=] - :: [=Resolve=] |p| with {{undefined}}. + :: [=Reject=] |p| with a [=new=] {{RangeError}}. + + Note: This is only reached when the source {{Observable}} completes *before* it emits a + single value, which is considered an error. 1. Subscribe to [=this=] given |internal observer| and |internal options|. From 501b4f7729323f457cf3e457f50831d2ac79e7ef Mon Sep 17 00:00:00 2001 From: Dominic Farolino Date: Sun, 5 May 2024 10:42:10 -0400 Subject: [PATCH 3/3] Do not use `RangeError` in `first()` --- spec.bs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/spec.bs b/spec.bs index 8293601..2571a4f 100644 --- a/spec.bs +++ b/spec.bs @@ -1138,10 +1138,13 @@ For now, see [https://github.com/wicg/observable#operators](https://github.com/w :: [=Reject=] |p| with the passed in error. : [=internal observer/complete steps=] - :: [=Reject=] |p| with a [=new=] {{RangeError}}. + :: [=Resolve=] |p| with {{undefined}}. Note: This is only reached when the source {{Observable}} completes *before* it emits a - single value, which is considered an error. + single value; in this case, resolving with {{undefined}} is harmless but makes it + difficult to distinguish between the first value trule being {{undefined}} and premature + completion. See #132 for + discussion on this. 1. Subscribe to [=this=] given |internal observer| and |internal options|.