Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for volatile functions #1

Draft
wants to merge 6 commits into
base: main
Choose a base branch
from

Conversation

PsychoLlama
Copy link
Owner

@PsychoLlama PsychoLlama commented Aug 18, 2024

An experiment in adding "volatile" functions to the TC39 Signals proposal.

const mediaQuery = window.matchMedia('(min-width: 1200px)')

const $matches = new Signal.Volatile(
  () => mediaQuery.matches,
  (onChange) => {
    mediaQuery.onchange = onChange

    return () => {
      mediaQuery.onchange = null
    }
  },
)

This signal reads from source when not observed, but runs in producer/consumer mode when held by an effect.

See the proposal for reasoning and mechanics.

Not intending to merge this. It supports my development environment on
NixOS where deps like Node from Volta that dynamically link to a glibc
interpreter are not executable.
This introduces a new `Signal.Volatile` function. It follows the initial
proposal here: tc39/proposal-signals#237

Volatile sources bring outside data into the computation graph.
If volatile sources are given a subscriber and the source is being
watched, now it returns from cache instead of querying `getSnapshot`
every time `source.get()` is invoked.

This only applies while being observed. When not observed, it fetches
from the snapshot function every time.
This causes the cache of `Signal.Computed` to be ignored and always
re-evaluate if it depends on volatile sources. We have to do this
because we don't know if the underlying sources changed since the last
time it evaluated.

When a volatile source upgrades to non-volatile (or is removed from the
dependencies list), the downstream consumers can once again cache their
evaluations.
When a volatile signal is upgraded to a tracked source through
`subscribe` it gets an `onChange` handler. Until this commit it was
a no-op. Now the `onChange` handler causes consumers to mark the current
value as dirty.

There are currently no restricted contexts for `onChange`. It's
conceivable we may want to restrict it.
Now volatile signals can depend on other signals inside `getSnapshot`.
Is this desirable? I'm not sure yet, but without supporting it, there
are unexpected edge cases. This is where the abstraction begins to leak
a bit.
divdavem pushed a commit to divdavem/signal-polyfill that referenced this pull request Sep 11, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant