LGTM3

On 3/5/25 4:02 PM, Chris Harrelson wrote:
Sorry, make that LGTM2

On Wed, Mar 5, 2025 at 1:00 PM Chris Harrelson <chris...@chromium.org> wrote:

    Thanks Dominic!

    LGTM1

    On Wed, Mar 5, 2025 at 12:57 PM Dominic Farolino
    <d...@chromium.org> wrote:

        Thanks for the summary Jake. So from the perspective of API
        OWNERS, I don't believe anything is blocking here. Folks agree
        that the ref-counted producer design is the right way,
        consistent with the developer feedback, and while you can hold
        the API in a way that appears surprising, (1) there are more
        surprises/quirks with the non-ref-counted approach, and (2)
        our design is consistent with the ways developers use
        Observables in the wild, mitigating the consequences of any
        surprises—I believe we're making the right trade-off.

        Given that, I believe we can proceed with the review.

        On Fri, Feb 28, 2025 at 12:32 PM Jake Archibald
        <jaffathec...@gmail.com> wrote:

            By missing the end, I mean this:

            const ob = new Observable((subscriber) => {
              subscriber.next(1);
              setTimeout(() => {
                subscriber.next(2);
                subscriber.complete();
              }, 1000);
            });

            ob.toArray().then((vals) => {
              // You're first, so you get things from the start.
              console.log(vals); // [1, 2]
            });

            ob.toArray().then((vals) => {
              // You missed the start, so you get the remaining values.
              // I'd describe the model here as: too late, you miss out!
              console.log(vals); // [2]
            });

            setTimeout(() => {
              ob.toArray().then((vals) => {
                // You missed the end, so we restart.
                // I'd describe the model here as: we'll fix it so you
            don't miss out
                console.log(vals); // [1, 2]
              });
            }, 1500);

            The bit where it sometimes restarts the thing so you don't
            miss out, and sometimes doesn't, felt unusual to me. To be
            clear, I think the ref-counting approach is right, but it
            would have felt more consistent if the final log was [],
            since the thing had already completed.

            The other case I found inconsistent is:

            const ob = Observable.from([1, 2, 3]);

            ob.toArray().then((vals) => {
              console.log(vals); // [1, 2, 3]
            });

            ob.toArray().then((vals) => {
              console.log(vals); // [1, 2, 3]
            });

            vs

            const ob = Observable.from([1, 2, 3].values());

            ob.toArray().then((vals) => {
              console.log(vals); // [1, 2, 3]
            });

            ob.toArray().then((vals) => {
              console.log(vals); // []
            });

            I had a meeting with Dominic and I now understand why it
            happens. It still seems unusual, but given that this
            hasn't come up for anyone else looking at the API (people
            who have way more experience with observables than I do),
            I guess it's just that I'm unfamiliar with these patterns.
            It's certainly something I'd call out in developer
            documentation for others coming to this fresh.

            Thanks all!
            Jake.

            On Fri, 28 Feb 2025 at 15:32, Dominic Farolino
            <d...@chromium.org> wrote:

                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-uykDqj_RgJ8xkPvkgxeGqVbj9vHbipMuzMjR35fH%3DpY-NJw%40mail.gmail.com
        
<https://groups.google.com/a/chromium.org/d/msgid/blink-dev/CAP-uykDqj_RgJ8xkPvkgxeGqVbj9vHbipMuzMjR35fH%3DpY-NJw%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/CAOMQ%2Bw_U3Wa45QJKUB-ned8EVoHCjKJgC5ECNjLsR7Or%3D_kv%3DQ%40mail.gmail.com <https://groups.google.com/a/chromium.org/d/msgid/blink-dev/CAOMQ%2Bw_U3Wa45QJKUB-ned8EVoHCjKJgC5ECNjLsR7Or%3D_kv%3DQ%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/2d45bcbd-6a73-4f10-875d-eaba377903a8%40chromium.org.

Reply via email to