Signals
A signal is a container for a value. When the value changes, it notifies everything that depends on it.
Creating Signals
import { signal, path } from 'sairin';
const count = signal(path("counter", "value"), 0);
Reading and Writing
count.get(); // Read
count.set(5); // Write
count.set(5); // No-op: same value
count.update(c => c + 1); // Update from current
What Happens on .get()
- Sairin records which effect is currently running
- The signal adds that effect to its subscriber list
- The value is returned
What Happens on .set()
- If new value equals old value, do nothing
- Check for lock violations
- Notify all subscribers
- Each subscriber re-runs
Signal API
| Method | Description |
|---|---|
get() |
Read the current value |
set(value) |
Set a new value |
update(fn) |
Update using current value |
subscribe(fn) |
Subscribe to changes |
unsubscribe(fn) |
Unsubscribe |
peek() |
Read without subscribing |
version |
Get the version number |
Subscriptions
const count = signal(path("counter"), 0);
const unsubscribe = count.subscribe((value) => {
console.log("Count changed to:", value);
});
count.set(1); // Logs: "Count changed to: 1"
count.set(2); // Logs: "Count changed to: 2"
unsubscribe();
count.set(3); // Nothing logged
Equality
Sairin uses Object.is() for equality checks:
const obj = signal(path("data", "obj"), { a: 1 });
obj.set({ a: 1 }); // Different reference - triggers
obj.update(d => d); // Same object - no trigger
Check If Signal
import { isSignal, signal, path } from 'sairin';
const s = signal(path("test"), 42);
const notSignal = "hello";
isSignal(s); // true
isSignal(notSignal); // false