Reactivity (API)
The reactive functions are available both as top-level exports from
@fullhaus/rivet and (partly) on the component context.
import { signal, computed, effect, batch, untrack } from "@fullhaus/rivet";signal
Section titled “signal”function signal<T>(initial: T): SignalGetter<T>;Creates a reactive signal with an initial value.
type SignalGetter<T> = { (): T; // read (subscribes the effect) set(value: T): void; // write; no-op on Object.is equality update(fn: (current: T) => T): void; // transform peek(): T; // read without subscribing};| Call | Effect |
|---|---|
s() | Reads the value; inside an effect the dependency is registered. |
s.set(v) | Sets the value. Ignored if Object.is(old, new). |
s.update(f) | Sets f(current). |
s.peek() | Reads the value without subscribing. |
computed
Section titled “computed”function computed<T>(fn: () => T): SignalGetter<T>;Derived signal that updates as soon as a dependency read in fn changes. The
result is itself a SignalGetter<T>.
const total = computed(() => price() * qty());effect
Section titled “effect”type EffectFn = () => void | (() => void);
function effect(fn: EffectFn): Dispose;Runs fn immediately and again on changes of signals read inside. If fn
returns a function, it runs before the next run and on dispose as cleanup.
const stop = effect(() => { const id = setInterval(tick, 1000); return () => clearInterval(id);});
stop(); // stop the effect + run the last cleanupfunction batch(fn: () => void): void;Bundles writes: dependent effects run once at the end of fn instead of
after every individual set.
batch(() => { price.set(20); qty.set(5);}); // one re-run instead of twountrack
Section titled “untrack”function untrack<T>(fn: () => T): T;Runs fn without the signals read inside subscribing the surrounding effect.
effect(() => { const snapshot = untrack(() => config()); // does NOT react to config render(data(), snapshot);});Dispose
Section titled “Dispose”type Dispose = (() => void) & Disposable;A Dispose is callable and implements Symbol.dispose, so it works with
using:
{ using stop = effect(() => { /* … */ });} // stopped automaticallySemantics in brief
Section titled “Semantics in brief”- Reading inside an effect = subscribe;
peek/untrackdo not subscribe. setwith anObject.is-equal value is a no-op.- Updates are synchronous unless bundled in
batch. - Effects and computeds release resources via cleanup return / dispose.