Skip to content

signalSet()

A reactive Set-shaped collection with per-value membership signals. Effects that read .has(x) re-run only when x is added or removed, not on other changes.

Shipped from the sub-path @whisq/core/collections, not the main entry.

import { signalSet } from "@whisq/core/collections";
function signalSet<T>(initial?: Iterable<T>): SignalSet<T>;
interface SignalSet<T> {
has(value: T): boolean;
add(value: T): SignalSet<T>;
delete(value: T): boolean;
clear(): void;
readonly size: number;
keys(): IterableIterator<T>;
values(): IterableIterator<T>;
entries(): IterableIterator<[T, T]>;
[Symbol.iterator](): IterableIterator<T>;
forEach(fn: (value: T, value2: T, set: SignalSet<T>) => void): void;
}
ParamTypeDescription
initialIterable<T>Optional initial values
  • .has(value) — subscribes only to membership of that specific value.
  • .size, iteration, .keys() / .values() / .entries() / .forEach() — subscribe to structural changes (add/delete/clear).
  • .add(value) / .delete(value) — notifies subscribers of that value and the structure signal.
import { effect } from "@whisq/core";
import { signalSet } from "@whisq/core/collections";
const selected = signalSet<string>();
effect(() => {
// Tracks "admin" only — other adds/deletes don't re-run this.
console.log("admin selected:", selected.has("admin"));
});
selected.add("user"); // effect does NOT re-run
selected.add("admin"); // effect re-runs (prints true)
selected.delete("admin"); // effect re-runs (prints false)

Pair with signalMap for patterns like “which rows are selected in a table” — each row’s has() only re-renders when its own membership flips.