• Creates a signal that synchronizes with a foreign data source.

    This kind of signal is useful when integrating another library (DOM APIs, etc.) that does not use the reactivity system provided by this library. The major advantage of this API is that it will automatically subscribe to the foreign data source while the signal is actually being used. It will also automatically unsubscribe when the signal is no longer used. A signal is considered "used" when it is used by some kind of active effect or watch.

    Principles:

    • The getter function should return the current value from the foreign data source. It should be cheap to call and should not have side effects. Ideally it performs some caching on its own, but this is not strictly needed.
    • The subscribe function should implement whatever logic is necessary to listen for changes. It receives a callback function that should be called whenever the value changes. subscribe should return a cleanup function to unsubscribe - it will be called automatically when appropriate.
    • When the signal is not watched in some way, accesses to the getter are not cached.
    • When the signal is being watched (e.g. by an effect), the signal will automatically subscribe to the foreign data source and cache the current value until it is informed about a change.

    Example:

    import { synchronized, watchValue } from "@conterra/reactivity-core";

    const abortController = new AbortController();
    const abortSignal = abortController.signal;
    const aborted = synchronized(

    // getter which returns the current value from the foreign source
    () => abortSignal.aborted,

    // Subscribe function: Automatically called when the signal is used
    (callback) => {
    // Subscribe to changes in the AbortSignal
    abortSignal.addEventListener("abort", callback);

    // Cleanup function is called automatically when the signal is no longer used
    return () => {
    // unsubscribe from changes in the AbortSignal
    abortSignal.removeEventListener("abort", callback);
    };
    }
    );

    watchValue(
    () => aborted.value,
    (aborted) => {
    console.log("Aborted:", aborted);
    },
    {
    immediate: true
    }
    );

    setTimeout(() => {
    abortController.abort();
    }, 1000);

    // Prints:
    // Aborted: false
    // Aborted: true

    Type Parameters

    • T

    Parameters

    Returns ReadonlyReactive<T>