/** * @module store * * Reactive store for objects with path-based access and partial updates. * Integrates with signals, computed, and effects. * * @example Basic Usage * ```typescript * import { store, effect } from '@doeixd/dom'; * * const state = store({ * user: { name: 'Alice', age: 30 }, * settings: { theme: 'dark' } * }); * * effect(() => { * console.log(`Hello, ${state.value.user.name}`); * }); * * state.set('user.name', 'Bob'); // Effect runs * ``` */ import type { Unsubscribe, ReadonlySignal, SignalOptions } from './signals'; /** Deep partial type */ type DeepPartial = T extends object ? { [K in keyof T]?: DeepPartial; } : T; /** Path type for nested access */ type Path = string | readonly (string | number)[]; /** Get type at path */ type PathValue = P extends `${infer K}.${infer Rest}` ? K extends keyof T ? PathValue : never : P extends keyof T ? T[P] : never; /** Store change event */ interface StoreChange { /** Full path that changed */ path: string[]; /** Previous value at path */ prev: unknown; /** New value at path */ next: unknown; /** Full previous state */ prevState: T; /** Full new state */ nextState: T; } /** Store options */ interface StoreOptions extends SignalOptions { /** Deep clone values on get. Default: `false` */ immutable?: boolean; /** Custom merge function for partial updates */ merge?: (target: T, source: DeepPartial) => T; } /** Selector function */ type Selector = (state: T) => R; /** Store subscription callback */ type StoreCallback = (state: T, change: StoreChange) => void; /** Path subscription callback */ type PathCallback = (value: V, prev: V | undefined) => void; /** Writable store interface */ interface WritableStore { /** Current state (reactive read) */ readonly value: T; /** Previous state */ readonly prev: T | undefined; /** Get value at path */ get

(path: P): PathValue; get(path: Path): V; /** Set entire state */ set(value: T): void; /** Partial update (shallow merge) */ set(partial: DeepPartial): void; /** Set value at path */ set

(path: P, value: PathValue): void; set(path: Path, value: unknown): void; /** Update state using function */ update(fn: (current: T) => T): void; /** Update value at path using function */ update

(path: P, fn: (current: PathValue) => PathValue): void; update(path: Path, fn: (current: unknown) => unknown): void; /** Merge partial state (deep merge) */ merge(partial: DeepPartial): void; /** Reset to initial state */ reset(): void; /** Reset specific path to initial value */ reset(path: Path): void; /** Subscribe to all changes */ subscribe(callback: StoreCallback): Unsubscribe; /** Subscribe to specific path */ subscribe

(path: P, callback: PathCallback>): Unsubscribe; subscribe(path: Path, callback: PathCallback): Unsubscribe; /** Create computed selector */ select(selector: Selector): ReadonlySignal; /** Run effect when store changes */ effect(fn: (state: T) => void | Unsubscribe): Unsubscribe; /** Run effect when path changes */ effect

(path: P, fn: (value: PathValue) => void | Unsubscribe): Unsubscribe; /** Read without tracking */ peek(): T; peek

(path: P): PathValue; peek(path: Path): unknown; /** Batch multiple updates */ batch(fn: () => void): void; /** Create a readonly view */ readonly: ReadonlyStore; /** Store brand for type guards */ readonly [STORE_BRAND]: true; } /** Read-only store interface */ interface ReadonlyStore { readonly value: T; get

(path: P): PathValue; get(path: Path): V; subscribe(callback: StoreCallback): Unsubscribe; subscribe

(path: P, callback: PathCallback>): Unsubscribe; select(selector: Selector): ReadonlySignal; effect(fn: (state: T) => void | Unsubscribe): Unsubscribe; peek(): T; peek(path: Path): unknown; readonly [STORE_BRAND]: true; } declare const STORE_BRAND: unique symbol; /** * Creates a reactive store for managing complex state objects. * * Stores provide path-based access, partial updates, and fine-grained * subscriptions. They integrate with signals and effects. * * @param initial - Initial state object * @param options - Store options * @returns A writable store * * @example Basic Usage * ```typescript * const state = store({ * count: 0, * user: { name: 'Alice', email: 'alice@example.com' } * }); * * // Read * console.log(state.value.count); // 0 * console.log(state.get('user.name')); // 'Alice' * * // Write * state.set({ count: 1 }); // Partial update * state.set('user.name', 'Bob'); // Path update * ``` * * @example Subscriptions * ```typescript * // Subscribe to all changes * const unsub = state.subscribe((value, change) => { * console.log('Changed:', change.path, change.next); * }); * * // Subscribe to specific path * state.subscribe('user.name', (name, prev) => { * console.log(`Name changed from ${prev} to ${name}`); * }); * ``` * * @example With Effects * ```typescript * // Effect on entire store * state.effect((value) => { * document.title = `${value.user.name} - ${value.count}`; * }); * * // Effect on specific path * state.effect('user.email', (email) => { * validateEmail(email); * }); * ``` * * @example Computed Selectors * ```typescript * const fullName = state.select(s => * `${s.user.firstName} ${s.user.lastName}` * ); * * effect(() => { * console.log(fullName.value); * }); * ``` * * @example Batched Updates * ```typescript * state.batch(() => { * state.set('user.name', 'Charlie'); * state.set('user.email', 'charlie@example.com'); * state.set({ count: 10 }); * }); * // Single notification after batch completes * ``` * * @example Deep Merge * ```typescript * state.merge({ * user: { name: 'Updated' } * // email preserved, not overwritten * }); * ``` * * @example Update Functions * ```typescript * state.update(s => ({ * ...s, * count: s.count + 1 * })); * * state.update('user.name', name => name.toUpperCase()); * ``` */ export declare function store(initial: T, options?: StoreOptions): WritableStore; /** * Check if a value is a store. * * @example * ```typescript * const state = store({ count: 0 }); * const sig = signal(0); * * isStore(state); // true * isStore(sig); // false * ``` */ export declare function isStore(value: unknown): value is WritableStore; export type { DeepPartial, Path, PathValue, StoreChange, StoreOptions, Selector, StoreCallback, PathCallback, WritableStore, ReadonlyStore, }; export { STORE_BRAND }; //# sourceMappingURL=store.d.ts.map