type CancelFn = () => void; type Subscriber = (value: T) => void | CancelFn; export interface Store { set: (val: T) => void; read: () => T; readInitial: () => T; subscribe: (sub: Subscriber) => () => void; } /** * Creates a new Suspense ready Store */ export const createStore = ( initialValue: T, ): Store => { const subscribers = new Set>(); const cancelations = new Set(); let value: T = initialValue; const read = () => value; const readInitial = () => initialValue; const set = (val: T) => { value = val; // Cancel previous, dangling operations cancelations.forEach((cancel) => cancel()); cancelations.clear(); // Broadcast subscribers subscribers.forEach((sub) => { const cancel = sub(val); if (typeof cancel === "function") { cancelations.add(cancel); } }); }; const subscribe = (sub: Subscriber) => { subscribers.add(sub); return () => { subscribers.delete(sub); }; }; return { set, read, readInitial, subscribe, }; };