@dathomir/reactivity
v0.0.5
Published
dathomir reactivity package
Maintainers
Readme
@dathomir/reactivity
Fine-grained reactivity system built on alien-signals. Provides TC39 Signals-style signal / computed / effect primitives.
Install
npm install @dathomir/reactivityUsage
import { signal, computed, effect, batch } from "@dathomir/reactivity";
const count = signal(0);
const doubled = computed(() => count.value * 2);
const stop = effect(() => {
console.log(`count: ${count.value}, doubled: ${doubled.value}`);
});
count.set(5); // logs: count: 5, doubled: 10
count.set(10); // logs: count: 10, doubled: 20
batch(() => {
count.set(100);
count.set(200); // single notification
});
// logs: count: 200, doubled: 400
stop();API
signal(initialValue)
Create a mutable reactive signal.
const name = signal("world");
console.log(name.value); // "world"
name.set("dathomir"); // triggers dependents
name.set(v => v + "!"); // updater function
name.peek(); // read without trackingcomputed(fn)
Create a cached derived value that recomputes when dependencies change.
const count = signal(1);
const doubled = computed(() => count.value * 2);
console.log(doubled.value); // 2
console.log(doubled.peek()); // read without trackingeffect(fn)
Run a side effect whenever its dependencies change. Returns a cleanup function.
onCleanup called inside the effect body runs before each re-execution and when the effect is stopped.
const count = signal(0);
const stop = effect(() => {
const timer = setInterval(() => {}, 1000);
onCleanup(() => clearInterval(timer)); // runs before re-execution or on stop()
console.log(count.value);
});
count.set(1); // triggers re-run (previous onCleanup fires first)
stop(); // dispose effect (onCleanup fires)batch(fn)
Batch multiple signal writes into a single notification flush.
const a = signal(0);
const b = signal(0);
batch(() => {
a.value = 1;
b.value = 2;
}); // dependents notified oncecreateRoot(fn)
Create a cleanup/ownership scope. Returns a dispose function.
const dispose = createRoot(() => {
const count = signal(0);
effect(() => console.log(count.value));
count.value = 1;
});
dispose(); // cleans up all effects in scopeonCleanup(fn)
Register a cleanup callback within the current scope. Works inside both createRoot and effect.
// Inside createRoot — runs when root is disposed
createRoot(() => {
const timer = setInterval(() => {}, 1000);
onCleanup(() => clearInterval(timer));
});
// Inside effect — runs before each re-execution and on stop()
effect(() => {
const timer = setInterval(() => {}, 1000);
onCleanup(() => clearInterval(timer));
});templateEffect(fn)
Optimized effect for template bindings. Used internally by the runtime.
templateEffect(() => {
setText(node, count.value);
});