Reactivity
@mikata/reactivity is the signal runtime the rest of the framework is built on. There are three primitives: signals, computeds, and effects.
Signals
A signal holds a value and tracks every read. Call the getter to read; call the setter to write.
import { signal } from '@mikata/reactivity';
const [count, setCount] = signal(0);
count(); // 0
setCount(1);
count(); // 1
setCount((n) => n + 1);
count(); // 2Computed
computed returns a read-only getter whose value is derived from other signals. It only re-runs when a read dependency changes, and it's memoized - reading a computed twice in a row doesn't recompute.
import { signal, computed } from '@mikata/reactivity';
const [items, setItems] = signal<number[]>([1, 2, 3]);
const total = computed(() => items().reduce((a, b) => a + b, 0));
total(); // 6
setItems([1, 2, 3, 4]);
total(); // 10Effects
Effects run side effects when their tracked signals change. They run once on creation, then again whenever a dependency fires.
import { signal, effect } from '@mikata/reactivity';
const [name, setName] = signal('world');
effect(() => {
console.log('hello,', name());
});
setName('mikata');
// logs: hello, mikataBatching
Multiple writes inside batch() collapse into a single notification, so effects run once with the final state.
import { signal, effect, batch } from '@mikata/reactivity';
const [a, setA] = signal(1);
const [b, setB] = signal(2);
effect(() => console.log(a() + b()));
// logs: 3
batch(() => {
setA(10);
setB(20);
});
// logs once: 30 - not twice