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 utility for tracking Signal reads in a callback #257

Open
DavidANeil opened this issue Jan 23, 2025 · 0 comments
Open

Add utility for tracking Signal reads in a callback #257

DavidANeil opened this issue Jan 23, 2025 · 0 comments

Comments

@DavidANeil
Copy link

The current best way to get a list of signals read during a callback is through a function like this

function observeReads<T>(cb: () => T): {result: T, signals: ReadonlyArray<Signal<unknown>>} {
    const computed = new Signal.computed(cb);
    const result = computed.get();
    const signals = Signal.subtle.introspectSources(computed);

    return {result, signals};
}

This is unnecessarily heavy for most use cases. Additionally, it is possible that the internal computed could end up as a Consumer for one of the read signals, making it persist in memory beyond the end of the utility function.

I think a utility like observeReads should be added to the spec, though obviously with a cheaper implementation, designed for occasions when the callback does not need to be reactively re-invoked.


The case I have in mind is for writing a check that no Signals are read in a callback. This is important in contexts where Signals are expected to be passed around, not invoked.

Imagine an API like this:

bindClassNameValue(domNode: HtmlElement, classNames: string | Signal<string>) {
    if (typeof classNames === 'string') {
        domNode.className = classNames;
    } else {
        untrack(() => effect(() => {
            domNode.className = classNames.get();
        }));
    }
}

It would be harmful if people invoked that API as bindClassNameValue(node, myClassNames.get()) on accident, so a framework could monitor and throw errors if any signals are read at inappropriate times.

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

No branches or pull requests

1 participant