proposal-signals icon indicating copy to clipboard operation
proposal-signals copied to clipboard

Should some EventTargets also be Signals?

Open NotWoods opened this issue 1 year ago • 3 comments

Some DOM event targets (such as MediaQueryList, returned by matchMedia as well as AbortSignal) have a single property and a single event that emits whenever that property's value changes. While signals could be offered as a second property, it might also be nice to have some way for a class to inherit both EventTarget and Signal.

const mql = window.matchMedia('(max-width: 900px)');
const isSmallScreen = new Signal.Computed(() => mql.get());

I'm also really happy to see Signal.subtle.watched/Signal.subtle.unwatched which makes it pretty easy to wrap these APIs in userland :) It's missing from a lot of framework Signal libraries.

function matchMediaSignal(query) {
  const mql = window.matchMedia(query);
  const abortController = new AbortController();

  const signal = new Signal.State(mql.matches, {
    [Signal.subtle.watched]() {
      this.set(mql.matches);
      mql.addEventListener('change', () => this.set(mql.matches), { signal: abortController.signal });
    },
    [Signal.subtle.unwatched]() {
      abortController.abort();
    }
  });
}

NotWoods avatar Apr 05 '24 19:04 NotWoods

similiar issue: https://github.com/proposal-signals/proposal-signals/issues/88 Thank you for adding a use case.

nuxodin avatar Apr 05 '24 20:04 nuxodin

This is an excellent question and corresponds much more closely to how I would like to see signals integrate with the web platform than #88. @wycats was telling me about an idea for ResizeObserver to integrate with signals in a similar way. Let’s develop more examples of how this integration should look—it is nice to see that the signal versions of web APIs can be built as a library on top, as demonstrated above.

littledan avatar Apr 06 '24 20:04 littledan

For what it's worth, I think the critical question is not whether the EventEmitter emits an event with a single value when the value changes, but rather whether it's safe to ignore intermediate values until you're ready to use them in another computation.

(In my opinion, if a lossless stream of intermediate values are important, Observables are a much more effective abstraction).

That said, I think it is quite common for Signal-like modelling to make sense for situations that currently use EventEmitter and I think it's a wide open design space for exploration.

Broadly speaking, I think the *Observer DOM APIs are the strongest initial candidates, because those APIs are already intended to be used in discrete ways (and intentionally batch up changes until a particular phase in the rendering pipeline).

wycats avatar Apr 06 '24 21:04 wycats