2025-05-07 [18:27:59.0904] 👋 Hey team! I'd like to introduce myself and andrew-cnv . We're working for Canva, a web based online design platform. We're currently looking to improve our telemetry in the product and have come across Async Context. We were wondering if we could attend the next meeting and get a lay of the land. The future topic on usable polyfills to test with is especially interesting. We were also wondering what are the blockers for this proposal reaching stage 2.7. [18:28:57.0937] Hi! The main blocker for stage 2.7 is figuring out exactly how the context should propagate across the many web APIs, especially events [18:30:30.0634] currently Mozilla is blocking the proposal because they think the complexity in implementation (if every single event that is caused asynchronously by some web API needs to have the context propagated) would not be worth the use cases [18:31:32.0108] * currently Mozilla is blocking the proposal because they think the complexity in implementation (if every single event that is caused asynchronously by some web API needs to have the context propagated) would not be worth it considering the use cases [18:34:01.0374] Does Mozilla have recommendations or a path forward? Is there any way we can help? [18:34:26.0874] * Does Mozilla have recommendations or a path forward? Is there any way we can help? (Also thanks for the background!) [18:35:14.0309] it'd be really helpful to know if the current web integration works for you, and in particular whether you need it to work for some specific async events [18:35:17.0636] https://github.com/tc39/proposal-async-context/blob/master/WEB-INTEGRATION.md [18:56:20.0673] Regarding the current web integration, I think the one that jumps out at me is ResizeObserver. From what I read, it sounds like the callbacks themselves will be run under the empty context. This presents a problem as we're looking to figure out how much rendering work is the result of certain actions in the UI. These actions may be resizing some parent container, and have that change propagated down to child elements. I note that you mention certain observations may expose the causal snapshot related to that particular observation. The specific callout was PerformanceEntry, but I was wondering if ResizeObserverEntry is in that bucket? [18:58:11.0359] it wasn't so far [18:59:19.0046] I don't know how easy that would be to implement, I'll look into it [19:00:38.0047] (That same problem applies to IntersectionObserver as well) [19:00:48.0577] in any case, exposing the causal snapshot in specific kinds of observers is something that can be added later without risking web compat concerns, which isn't the case for extending propagation of almost everything else in the proposal [19:02:14.0285] For more context: We've been experimenting with using Zone.js to do this context propagation. We're not happy with the limitations that are imposed by using Zone.js and was looking to see how far away Async Context would realistically be. [03:10:47.0782] A few months back, I built a lightweight polyfill. https://github.com/iliasbhal/simple-async-context It’s fully tested and I’ve used it in several projects (nothing quite at Canva scale 😄 ). Feel free to try it out—I’d appreciate any feedback, especially if you hit edge cases or have a unique use cases. 2025-05-08 [19:05:40.0737] Hey Andreu Botella I've had a deeper read of the WEB-INTEGRATIONS document and especially at the Events section. I'm interested in the difference between the "Browser-originated dispatches" and "Asynchronous dispatches" and specifically what is meant by 'where the event originates from JS calling into some web API'. What constitutes a JS call into a web API here? Is it only explicit function calls, as given in the XHR examples? Or would it include events fired implicitly by the rendering of components. The example I have in my mind is the following: We have a component that renders something, and that component has an animation defined in css. Work is done after the transition is completed, via 'transitionend' event. That can obviously happen from a number of different paths. Would the context that scheduled the work be considered 'some web API'? 2025-05-13 [00:33:26.0259] Huh, good question. So you're thinking of, e.g. changing some class from JS, which triggers the animation? Tracking that would not be easy 2025-05-15 [23:20:06.0124] > changing some class from JS, which triggers the animation Yep exactly. >Tracking that would not be easy :( [23:23:00.0128] I think it's a similar problem raised in the above ResizeObserver scenario. There's no good way to currently link these things in user land, especially if the changes came from different parts of an application. 2025-05-19 [09:41:11.0448] Looking over the slides for next weeks discussion around AsyncContext... in particular Mozilla's objections, and specifically the concerns over the niche use case. I wanted to ask if it would be helpful at all for me to discuss the way that the Workers runtime itself is making use of async context propagation for tracing and diagnostics independent of any frameworks and third-party libraries? [09:42:58.0973] I think browsers need to hear about _browser_ use cases, and hopefully they were satisfied with the answer about use cases we gave last time (even though I'd like them to confirm at this meeting that that answer was satisfying). I think the main problem now is the implementation complexity [09:43:37.0411] Fair, ok, that's what I was thinking but wanted to at least ask [09:47:43.0399] IIRC, CF Workers implements some browser web APIs (as what WinterTC covers). Maybe you'd have thoughts about how the web APIs listed in the slides are implemented with AsyncContext/AsyncLocalStorage on CF Workers? [09:47:57.0622] * IIRC, CF Workers implement some browser web APIs (as what WinterTC covers). Maybe you'd have thoughts about how the web APIs listed in the slides are implemented with AsyncContext/AsyncLocalStorage on CF Workers? [09:51:02.0505] yes we do. Currently we don't do anything special for some of the more complicated cases. On `setTimeout`, `setInterval`, and `queueMicrotask` we capture the current context and propagate it, as well as in any promise-based apis. But for the higher level apis like `EventTarget`, streams, etc we have been intentionally waiting on see how this conversation in the committee plays out [09:51:38.0127] fortunately for us we are not heavily dependent on `EventTarget` and we haven't hit many cases with other standard apis where it matters much [09:51:55.0674] oh... we also capture and restore the context for unhandled promise rejections [09:52:08.0480] For what is worth, I think although WinterTC includes events and EventTarget, the only specific events it includes are `error`/`unhandledrejection`/`rejectionhandled` [09:52:36.0848] well, and AbortSignal's abort event, which doesn't need propagation because it's fired synchronously [09:53:53.0089] for `UnderlyingSink` and `UnderlyingSource` in streams, it is possible to polyfill using `AsyncContext.snapshot` (I've done similar with `AsyncLocalStorage`). It's not all that difficult to get close to exactly what you want there [09:55:17.0524] the most difficult cases -- in terms of ambiguity -- are the EventTarget cases where it is just not clear when an event is triggered whether you want to propagate the context active when the event is dispatched or the context active when the listener was registered, but even that is possible to work around [09:59:05.0023] No, for streams you also have an ambiguity between the context in which the stream is created and the context which causes e.g. the `pull` method to be called [09:59:16.0611] * No, for streams you also have an ambiguity between the context in which the stream is created and the context from which the stream is read which causes e.g. the `pull` method to be called [09:59:35.0713] and I think this should be clearer in the slides [10:02:27.0554] if you implement things exactly according to the spec, the context in which `pull` would be called wouldn't be the one in which the ReadableStream is constructed. I think if the previous pull has already resolved, it would be the context from which you read from the reader [10:03:17.0897] but now that I'm thinking through this, I realize that the interaction with fetch and anything else that consumes or produces a stream browser/runtime-internally would not be as easy to implement [10:03:17.0944] Yeah, true. I haven't encountered this being an issue in the wild *yet* but it certainly is a valid concern [10:03:49.0247] * but now that I'm thinking through this, I realize that the interaction with fetch and anything else that consumes or produces a stream browser/runtime-internally might not be as easy to implement 2025-05-28 [04:23:32.0021] Monkey-patching for postMessage the way it's used as a scheduler would be something like this: ```js class MessageChannel extends globalThis.MessageChannel { constructor(...args) { super(...args); this.port1.__channel = this; this.port2.__channel = this; patch(this.port1); patch(this.port2); } } ``` where `patch` wraps `onmessage`/`addEventListener` to get a registration-time snapshot, or as an alternative to store the `.postMessage`-time snapshot on this.__channel and run the event callback in it. [04:23:53.0556] (I think that this is bad code, but it's _possible_) [04:24:30.0075] And if the code patching is the same as the code needing the patch, it can just call `.wrap` instead (e.g. for React) [05:09:22.0954] for MessageChannel, yes, but there's postMessage on window as well [05:16:46.0573] Hey folks-- great presentation today. Thanks for the invite. [05:17:26.0165] thank you for attending and providing your use cases! [05:17:51.0595] Well I didn't provide use cases today but I was prepared to :P Seems we didn't need more support in the room, though [05:18:43.0024] right 😅 [05:18:56.0035] I'm not too cogent after these long discussions [07:54:39.0766] I'm not sure this does work - if you want to get dispatch-time snapshotting, you need to mutate the message to refer to the right snapshot, but AIUI you can't know whether one of the ports has been transferred to another agent - if so, then the patching won't work and the mutation is wrong.