Responding to Jake: With the example in the codepen, as the holder of the observable, I don't > think I have a way of knowing if I'm getting the start, or something in the > middle. Isn't that a bit odd?
Hmm, I see how it can feel a little intuitive, but I think this tradeoff is *less unintuitive* than it was without ref-counted producers, where Observable doesn't really represent anything related to the subscription, causing the footguns that led to us pursuing this path in the first place. Regarding: If it's ok to miss the start, why isn't it ok to miss the end? I don't think it is OK to miss the end, and I don't quite think our proposal makes this possible? If you subscribe half-way through, you will still get `complete()` notifications so you know that the stream has ended. The closest example of "missing the end" I can think of would be the one you mentioned over X/Twitter, which is if you subscribe to an async iterator (not iterable that can be restarted), and you exhaust the iterator, what do subsequent subscriptions do after the iterator is exhausted? * async function* asyncNumbers() { yield* [1,2,3,4]; } const ob = Observable.from(asyncNumbers()); await ob.toArray().then(result => console.log('one', result)); ob.subscribe({ next: v => console.log('second subscription: ', v), complete: () => console.log('complete'), })* By the time the second subscription rolls around, the iterator has been exhausted. But you still don't "miss the end" since the `complete()` handler fires. Hopefully that makes sense. Either way, it's entirely possible this thread isn't the best place to hash all of this out :) On Fri, Feb 28, 2025 at 10:20 AM Dominic Farolino <d...@chromium.org> wrote: > I was told that it would be good to clarify something here from the > original email sent here, about *TC39's engagement* and *WebKit's > standards position*. > > *WebKit*: Positive ( >> https://github.com/WebKit/standards-positions/issues/292) > > > I marked WebKit's standards position as positive since Anne had mentioned > WebKit folks were supportive and he recommended marking the issue as > `position: support` > <https://github.com/WebKit/standards-positions/issues/292#issuecomment-2520739850>. > However, he has since walked it back since the proposal has not been > formally presented to TC39. Such a presentation is abnormal for web APIs > not developing *within* TC39, however is still a reasonable idea that I > am happy to do. (For what it's worth, I tried to present this proposal to > TC39 at the Tokyo virtual meeting in October 2024 after TPAC last year, and > unfortunately after staying up late to do, so I got bumped from the agenda > last minute because other items went over time). > > Regarding my comment on *TC39 engagement*, I wrote: > > We've gotten good design feedback from TC39 members on many issues which >> we have implemented accordingly. > > > This is true—various ECMAScript editors have engaged with us on > substantial design issues. However, since we have not formally presented to > TC39, I was made aware that this kind of engagement might not count as > proper *TC39 engagement*. So I wanted to call out here that we have not > yet sought or received any kind of formal "sign-off" by ECMAScript editors > on our proposal. > > On Thu, Feb 27, 2025 at 1:00 AM Domenic Denicola <dome...@chromium.org> > wrote: > >> I looked into >> <https://github.com/WICG/observable/issues/177#issuecomment-2686242878> the >> SuppressedError proposal a bit more. I'm now about 90% convinced >> SuppressedError does not need to be used. (Or if there is a case for it, >> it's in extreme edge cases that we could address after shipping.) >> >> Given how complete every other aspect of this Intent is, LGTM1, >> conditional on Dominic agreeing with my reasoning that we don't want to use >> SuppressedError for most callbacks. If I misunderstood, then we should >> delay until that gets straightened out. >> >> On Thu, Feb 27, 2025 at 5:53 AM Jake Archibald <jaffathec...@gmail.com> >> wrote: >> >>> On Wed, 26 Feb 2025 at 20:39, Dominic Farolino <d...@chromium.org> wrote: >>> >>>> https://codepen.io/jaffathecake/pen/raNWMmK?editors=0012 - it seems >>>>> inconsistent that two of the calls to ob.map create a new subscriber, >>>>> whereas the other picks up the observable half way through. >>>> >>>> >>>> Right, the idea that a subscription doesn't have side effects if an >>>> existing subscription is in-flight was essentially the outcome of >>>> https://github.com/WICG/observable/issues/170 & >>>> https://github.com/WICG/observable/issues/178. The alternative, where >>>> producer:consumer are 1:1, made it easy to write performance foot-guns >>>> where what you actually want is to tap into an existing stream of values >>>> without paying the cost of setting it up each time if it already exists. >>>> Many userland Observables inevitably get `share()` slapped on them >>>> somewhere in the chain to alleviate this, but the inconsistency made it >>>> hard to judge whether your subscription would have side-effects or not. We >>>> also saw a lot of Observable learning material was taking pains to >>>> caveat >>>> <https://ronnieschaniel.com/rxjs/rxjs-mastery-hot-vs-cold-observables/#:~:text=Why%20do%20we%20need%20cold%20and%20hot%20Observables%20in%20RxJS%3F> >>>> right >>>> away, this unintuitive idea that the Observable type itself doesn't >>>> represent anything but a stateless subscription vendor. Now it basically >>>> represents the producer, and I think that matches peoples' mental >>>> models >>>> <https://github.com/WICG/observable/issues/178#issuecomment-2480525113> >>>> . >>>> >>>> I guess the rule is: A new subscriber is created if the observer has >>>>> closed, but isn't this really inconsistent? >>>> >>>> >>>> I think it is consistent though, no? It's true that it's neither "only >>>> one call to the subscriber" nor "each call to the initial observable >>>> initiates a new subscription". But it is similar to what you wrote above: a >>>> subscriber is invoked/spun up if its subscription is closed (not observer). >>>> The pay-off is that you know you're never going to have "extra" side >>>> effects when subscribing. At most you will spin up a single producer (which >>>> you're OK with since you're subscribing), and at best you will listen in on >>>> an existing one. >>>> >>> >>> I think where it gets confusing is when the observable has a beginning >>> and an end. It's fine for event targets, because they don't have that. >>> >>> For event target observables it's 'interested' (add the listener) and >>> 'distinerested' (remove the listener). Whereas the underlying events are >>> still continuing. >>> >>> With the example in the codepen, as the holder of the observable, I >>> don't think I have a way of knowing if I'm getting the start, or something >>> in the middle. Isn't that a bit odd? If it's ok to miss the start, why >>> isn't it ok to miss the end? >>> >>> Again it might be because I'm not used to the patterns, and they're well >>> understood elsewhere. >>> >>> >>>> If you need a new subscriber to be created on each subscription, you'll >>>> need to basically take a closure over the Observable-vending API and call >>>> each `subscribe()` on it, which I hope is not too burdensome. >>>> >>>> On Wed, Feb 26, 2025 at 2:55 PM Jake Archibald <jaffathec...@gmail.com> >>>> wrote: >>>> >>>>> I'm struggling a little to get my head around how this works. >>>>> >>>>> https://codepen.io/jaffathecake/pen/raNWMmK?editors=0012 - it seems >>>>> inconsistent that two of the calls to ob.map create a new subscriber, >>>>> whereas the other picks up the observable half way through. >>>>> >>>>> If I put the .complete call in a setTimeout, then there's only one >>>>> subscriber created. >>>>> >>>>> I guess the rule is: A new subscriber is created if the observer has >>>>> closed, but isn't this really inconsistent? >>>>> >>>>> I'd expect it to be one way or the other. As in: >>>>> >>>>> There's only one call to the subscriber. >>>>> Or >>>>> Each call to the initial observable is a new subscription. >>>>> >>>>> The way it's neither one or the other is confusing to me. But maybe >>>>> that's totally normal for folks who are used to observables? >>>>> >>>>> On Friday, 21 February 2025 at 21:25:05 UTC Chromestatus wrote: >>>>> >>>>>> Contact emails d...@chromium.org >>>>>> >>>>>> Explainer https://github.com/WICG/observable >>>>>> >>>>>> Specification https://wicg.github.io/observable >>>>>> >>>>>> Summary >>>>>> >>>>>> Observables are a popular reactive-programming paradigm to handle an >>>>>> asynchronous stream of push-based events. They can be thought of as >>>>>> Promises but for multiple events, and aim to do what Promises did for >>>>>> callbacks/nesting. That is, they allow ergonomic event handling by >>>>>> providing an Observable object that represents the asynchronous flow of >>>>>> events. You can "subscribe" to this object to receive events as they come >>>>>> in, and call any of its operators/combinators to declaratively describe >>>>>> the >>>>>> flow of transformations through which events go. This is in contrast with >>>>>> the imperative version, which often requires complicated nesting with >>>>>> things like `addEventListener()`. For more on this, see the examples in >>>>>> the >>>>>> explainer. The big selling point for native Observables is their >>>>>> integration with EventTarget — its proposed `when()` method that returns >>>>>> an >>>>>> Observable which is a "better" `addEventListener()`. See >>>>>> https://github.com/WICG/observable and >>>>>> https://twitter.com/domfarolino/status/1684921351004430336. See the >>>>>> spec https://wicg.github.io/observable/ and the design doc: >>>>>> https://docs.google.com/document/d/1NEobxgiQO-fTSocxJBqcOOOVZRmXcTFg9Iqrhebb7bg/edit >>>>>> . >>>>>> >>>>>> >>>>>> Blink component Blink>DOM >>>>>> <https://issues.chromium.org/issues?q=customfield1222907:%22Blink%3EDOM%22> >>>>>> >>>>>> TAG review https://github.com/w3ctag/design-reviews/issues/902 >>>>>> >>>>>> TAG review status Issues addressed >>>>>> >>>>>> Risks >>>>>> >>>>>> >>>>>> Interoperability and Compatibility >>>>>> >>>>>> Initially we proposed adding the `.on()` method to EventTarget, which >>>>>> was found to conflict with userland versions of the same method. The >>>>>> conflict was found to be too significant to justify shipping our native >>>>>> version of this API (see https://github.com/WICG/observable/issues/39) >>>>>> so we renamed it to `.when()` and we strongly believe this resolves any >>>>>> naming collision issues after searching through public libraries and >>>>>> performing developer outreach on X. See the discussion on that issue. >>>>>> >>>>>> >>>>>> *Gecko*: No signal ( >>>>>> https://github.com/mozilla/standards-positions/issues/945) >>>>>> >>>>>> *WebKit*: Positive ( >>>>>> https://github.com/WebKit/standards-positions/issues/292) >>>>>> >>>>>> *Web developers*: Strongly positive ( >>>>>> https://twitter.com/domfarolino/status/1684921351004430336) Also see >>>>>> https://foolip.github.io/spec-reactions/ and the developer interest >>>>>> in the original WHATWG DOM issue. >>>>>> >>>>>> *Other signals*: We've gotten good design feedback from TC39 members >>>>>> on many issues which we have implemented accordingly. This has led to >>>>>> positive feedback from Node.js, and luke-warm non-negative feedback from >>>>>> WinterCG. See https://github.com/WICG/observable/issues/93; >>>>>> specifically https://github.com/nodejs/standards-positions/issues/1 >>>>>> & https://github.com/WICG/observable/issues/30 for Node, and >>>>>> https://github.com/wintercg/proposal-minimum-common-api/issues/72 >>>>>> for WinterCG. >>>>>> >>>>>> WebView application risks >>>>>> >>>>>> Does this intent deprecate or change behavior of existing APIs, such >>>>>> that it has potentially high risk for Android WebView-based applications? >>>>>> >>>>>> None >>>>>> >>>>>> >>>>>> Debuggability >>>>>> >>>>>> The developer experience of Observables might benefit from >>>>>> Observable-specific DevTools tracking of events and streams (see >>>>>> https://github.com/WICG/observable/issues/55). It is possible that >>>>>> the existing DevTools work that assists asynchronous task tracking and >>>>>> callstack tagging may be sufficient though. At the moment, however, our >>>>>> effort is focused on the platform implementation of Observables. >>>>>> >>>>>> >>>>>> Will this feature be supported on all six Blink platforms (Windows, >>>>>> Mac, Linux, ChromeOS, Android, and Android WebView)? Yes >>>>>> >>>>>> Is this feature fully tested by web-platform-tests >>>>>> <https://chromium.googlesource.com/chromium/src/+/main/docs/testing/web_platform_tests.md> >>>>>> ? Yes >>>>>> >>>>>> See https://wpt.fyi/results/dom/observable/tentative. >>>>>> >>>>>> >>>>>> Flag name on about://flags observable-api >>>>>> >>>>>> Finch feature name ObservableAPI >>>>>> >>>>>> Requires code in //chrome? False >>>>>> >>>>>> Tracking bug >>>>>> https://bugs.chromium.org/p/chromium/issues/detail?id=1485981 >>>>>> >>>>>> Estimated milestones >>>>>> Shipping on desktop 135 >>>>>> >>>>>> Anticipated spec changes >>>>>> >>>>>> Open questions about a feature may be a source of future web compat >>>>>> or interop issues. Please list open issues (e.g. links to known github >>>>>> issues in the project for the feature specification) whose resolution may >>>>>> introduce web compat/interop risk (e.g., changing to naming or structure >>>>>> of >>>>>> the API in a non-backward-compatible way). >>>>>> Issues with the "possible future enhancement" label [1] track >>>>>> possible changes to the feature that may come after we ship the initial >>>>>> API. One issue (https://github.com/WICG/observable/issues/200) is >>>>>> identified to have behavior changes that theoretically pose a compat >>>>>> risk, >>>>>> but only for developers that subclass the API. The behavior change >>>>>> proposed >>>>>> puts the implementation more inline with what subclass users want: the >>>>>> operators that return native Observable objects would instead return >>>>>> objects of `this.constructor` type, as to return instances of the >>>>>> subclass >>>>>> that the operators are called on. This is how JS built-ins like `Array` >>>>>> work, however, no other web platform feature works like this and it >>>>>> likely >>>>>> requires non-trivial Web IDL support. [1]: >>>>>> https://github.com/WICG/observable/issues?q=is%3Aissue%20state%3Aopen%20label%3A%22possible%20future%20enhancement%22 >>>>>> >>>>>> Link to entry on the Chrome Platform Status >>>>>> https://chromestatus.com/feature/5154593776599040?gate=5141110901178368 >>>>>> >>>>>> Links to previous Intent discussions Intent to Prototype: >>>>>> https://groups.google.com/a/chromium.org/d/msgid/blink-dev/CAP-uykBH1%3DUoLN6%3DBRSEZE%2B1iUq6UdcTpo3qtTQ5T%3DSRxwnu5Q%40mail.gmail.com >>>>>> >>>>>> >>>>>> This intent message was generated by Chrome Platform Status >>>>>> <https://chromestatus.com>. >>>>>> >>>>> -- >>> You received this message because you are subscribed to the Google >>> Groups "blink-dev" group. >>> To unsubscribe from this group and stop receiving emails from it, send >>> an email to blink-dev+unsubscr...@chromium.org. >>> To view this discussion visit >>> https://groups.google.com/a/chromium.org/d/msgid/blink-dev/CAJ5xic-3d9ziBOmqHYiSGPxLmDzhu19vfbQHffqJSkprFcE%2Btg%40mail.gmail.com >>> <https://groups.google.com/a/chromium.org/d/msgid/blink-dev/CAJ5xic-3d9ziBOmqHYiSGPxLmDzhu19vfbQHffqJSkprFcE%2Btg%40mail.gmail.com?utm_medium=email&utm_source=footer> >>> . >>> >> -- You received this message because you are subscribed to the Google Groups "blink-dev" group. To unsubscribe from this group and stop receiving emails from it, send an email to blink-dev+unsubscr...@chromium.org. To view this discussion visit https://groups.google.com/a/chromium.org/d/msgid/blink-dev/CAP-uykAqENwMBdoGoQ2ew4sjmVqFAknkyNZ2-AJPkEPFhb2mpQ%40mail.gmail.com.