signalMap()
A reactive Map-shaped collection where each key has its own subscriber set. Effects that read a specific key via .get() or .has() re-run only when that key changes — effects that iterate or read .size re-run on any structural change.
Shipped from the sub-path @whisq/core/collections, not the main entry.
Signature
Section titled “Signature”import { signalMap } from "@whisq/core/collections";
function signalMap<K, V>( initial?: Iterable<readonly [K, V]>,): SignalMap<K, V>;
interface SignalMap<K, V> { get(key: K): V | undefined; has(key: K): boolean; set(key: K, value: V): SignalMap<K, V>; delete(key: K): boolean; clear(): void; readonly size: number; keys(): IterableIterator<K>; values(): IterableIterator<V>; entries(): IterableIterator<[K, V]>; [Symbol.iterator](): IterableIterator<[K, V]>; forEach(fn: (value: V, key: K, map: SignalMap<K, V>) => void): void;}Parameters
Section titled “Parameters”| Param | Type | Description |
|---|---|---|
initial | Iterable<readonly [K, V]> | Optional initial key/value pairs |
Reactivity
Section titled “Reactivity”.get(key)/.has(key)— subscribe only tokey. Writes to other keys don’t re-run your effect..size, iteration,.keys()/.values()/.entries()/.forEach()— subscribe to structural changes (add/delete/clear)..set(key, value)— notifies subscribers ofkey(and.sizesubscribers if it’s a new key).
Examples
Section titled “Examples”import { effect } from "@whisq/core";import { signalMap } from "@whisq/core/collections";
interface User { name: string }
const users = signalMap<string, User>();users.set("u1", { name: "Alice" });
effect(() => { // Tracks "u1" only — other inserts don't re-run this. console.log(users.get("u1")?.name);});
users.set("u2", { name: "Bob" }); // effect does NOT re-runusers.set("u1", { name: "Carol" }); // effect re-runsUse signalMap when you keep a dictionary keyed by stable IDs and want per-ID subscriptions — it avoids the O(N) re-run cost of a single signal<Record<K, V>> on every mutation.