UNPKG

@zeix/cause-effect

Version:

Cause & Effect - reactive state management primitives library for TypeScript.

63 lines (62 loc) 2.69 kB
import { type Cleanup, TYPE_STORE } from '../graph'; import { type List, type UnknownRecord } from './list'; import { type State } from './state'; /** * Configuration options for `createStore`. */ type StoreOptions = { /** Invoked when the store gains its first downstream subscriber; returns a cleanup called when the last one unsubscribes. */ watched?: () => Cleanup; }; type BaseStore<T extends UnknownRecord> = { readonly [Symbol.toStringTag]: 'Store'; readonly [Symbol.isConcatSpreadable]: false; [Symbol.iterator](): IterableIterator<[ string, State<T[keyof T] & {}> | Store<UnknownRecord> | List<unknown & {}> ]>; keys(): IterableIterator<string>; byKey<K extends keyof T & string>(key: K): T[K] extends readonly (infer U extends {})[] ? List<U> : T[K] extends UnknownRecord ? Store<T[K]> : T[K] extends unknown & {} ? State<T[K] & {}> : State<T[K] & {}> | undefined; get(): T; set(next: T): void; update(fn: (prev: T) => T): void; add<K extends keyof T & string>(key: K, value: T[K]): K; remove(key: string): void; }; /** * A reactive object with per-property reactivity. * Each property is wrapped as a `State`, nested `Store`, or `List` signal, accessible directly via proxy. * Updating one property only re-runs effects that read that property. * * @template T - The plain-object type whose properties become reactive signals */ type Store<T extends UnknownRecord> = BaseStore<T> & { [K in keyof T]: T[K] extends readonly (infer U extends {})[] ? List<U> : T[K] extends UnknownRecord ? Store<T[K]> : T[K] extends unknown & {} ? State<T[K] & {}> : State<T[K] & {}> | undefined; }; /** * Creates a reactive store with deeply nested reactive properties. * Each property becomes its own signal (State for primitives, nested Store for objects, List for arrays). * Properties are accessible directly via proxy. * * @since 0.15.0 * @param value - Initial object value of the store * @param options - Optional configuration for watch lifecycle * @returns A Store with reactive properties * * @example * ```ts * const user = createStore({ name: 'Alice', age: 30 }); * user.name.set('Bob'); // Only name subscribers react * console.log(user.get()); // { name: 'Bob', age: 30 } * ``` */ declare function createStore<T extends UnknownRecord>(value: T, options?: StoreOptions): Store<T>; /** * Checks if a value is a Store signal. * * @since 0.15.0 * @param value - The value to check * @returns True if the value is a Store */ declare function isStore<T extends UnknownRecord>(value: unknown): value is Store<T>; export { createStore, isStore, type Store, type StoreOptions, TYPE_STORE };