import type { FieldPath, FieldPathValue, FieldValues, IsEqual } from './path'; export type { AllowedKeys, ArrayProxy, ArrayState, DerivedStateProps, ObjectMutationMethods, ObjectProxy, ObjectState, ObjectStateValue, Prettify, ReadOnlyState, State, StoreRoot, StoreSetStateValue, StoreUseComputeFn, StoreUseState, ValueState }; type Prettify = { [K in keyof T]: T[K]; } & {}; type AllowedKeys = Exclude | keyof ObjectMutationMethods>; type MaybeMissingParent = undefined extends TParent ? TValue | undefined : null extends TParent ? TValue | undefined : TValue; type ObjectStateValue = {} extends TNonNullable ? TNonNullable[K] | undefined : MaybeMissingParent; type ArrayMutationMethods = Prettify, 'push' | 'pop' | 'shift' | 'unshift' | 'splice' | 'reverse' | 'sort' | 'fill' | 'copyWithin'>>; /** Type for array proxy with index access */ type ArrayProxy> = ArrayMutationMethods> & { /** Read without subscribing. Returns array or undefined for missing paths. */ readonly value: T[]; /** * Length of the underlying array. Runtime may return undefined when the * current value is not an array at the path. Prefer `Array.isArray(x) && x.length` when unsure. */ readonly length: number; /** Subscribe to array length changes without subscribing to individual element changes. */ useLength(): number; /** Numeric index access never returns undefined at the type level because * the proxy always returns another proxy object, even if the underlying value doesn't exist. */ [K: number]: ElementState; /** Safe accessor that never returns undefined at the type level */ at(index: number): ElementState; /** Insert items into the array in sorted order using the provided comparison function. */ sortedInsert(cmp: (a: T, b: T) => number, ...items: T[]): number; }; type ObjectProxy = { /** Virtual state for the object's keys. * * This does NOT read from a real `keys` property on the stored object; it results in a stable array of keys. */ readonly keys: ReadOnlyState[]>; } & { [K in keyof T]-?: State>; }; type ObjectMutationMethods = { /** Rename a key in an object. */ rename: (oldKey: string, newKey: string) => void; }; /** Tuple returned by Store.use(path). */ type StoreUseState = Readonly<[T, (value: StoreSetStateValue, skipUpdate?: boolean) => void]>; /** Value type for set method. */ type StoreSetStateValue = T | ((prev: T) => T); /** Public API returned by createStore(namespace, defaultValue). */ type StoreRoot = { /** Get the state object for a path. */ state:

>(path: P) => State>; /** Subscribe and read the value at path. Re-renders when the value changes. */ use:

>(path: P) => FieldPathValue; /** Subscribe and read the debounced value at path. Re-renders when the value changes. */ useDebounce:

>(path: P, delay: number) => FieldPathValue; /** Convenience hook returning [value, setValue] for the path. */ useState:

>(path: P) => StoreUseState>; /** Read without subscribing. */ value:

>(path: P) => FieldPathValue; /** Set value at path (creates intermediate nodes as needed). */ set:

>(path: P, value: StoreSetStateValue>, skipUpdate?: boolean) => void; /** Delete value at path (for arrays, removes index; for objects, deletes key). */ reset:

>(path: P) => void; /** Rename a key in an object. */ rename:

>(path: P, oldKey: string, newKey: string) => void; /** Subscribe to changes at path and invoke listener with the new value * * @returns A function to unsubscribe from the path. */ subscribe:

>(path: P, listener: (value: FieldPathValue) => void) => () => void; /** Compute a derived value from the current value, similar to useState + useMemo */ useCompute:

, R>(path: P, fn: StoreUseComputeFn, deps?: readonly unknown[]) => R; /** Notify listeners at path. */ notify:

>(path: P) => void; }; /** Common methods available on any deep proxy node */ type ValueState = { /** Read without subscribing. */ readonly value: T; /** The field name for the proxy. */ readonly field: string; /** The path for the proxy. */ readonly path: string; /** Subscribe and read the value at path. Re-renders when the value changes. */ use(): T; /** Subscribe and read the debounced value at path. Re-renders when the value changes. */ useDebounce(delay: number): T; /** Convenience hook returning [value, setValue] for the path. */ useState(): StoreUseState; /** Set value at path (creates intermediate nodes as needed). */ set(value: T | ((prev: T) => T), skipUpdate?: boolean): void; /** Delete value at path (for arrays, removes index; for objects, deletes key). */ reset(): void; /** Subscribe to changes at path and invoke listener with the new value. * * @returns A function to unsubscribe. * @example * * useEffect(() => { * const unsubscribe = store.a.b.c.subscribe(value => { * console.log(value) * }) * return unsubscribe * }, []) */ subscribe(listener: (value: T) => void): () => void; /** Compute a derived value from the current value, similar to useState + useMemo */ useCompute: (fn: (value: T) => R, deps?: readonly unknown[]) => R; /** Ensure the value is an array. */ ensureArray(): NonNullable extends (infer U)[] ? ArrayState : never; /** Ensure the value is an object. */ ensureObject(): NonNullable extends FieldValues ? ObjectState> : never; /** Return a new state with a default value, and make the type non-nullable */ withDefault(defaultValue: T): State>; /** Virtual state derived from the current value. * * @returns ArrayState if the derived value is an array, ObjectState if the derived value is an object, otherwise State. * @example * const state = store.a.b.c.derived({ * from: value => value + 1, * to: value => value - 1 * }) * state.use() // returns the derived value * state.set(10) // sets the derived value * state.reset() // resets the derived value */ derived: ({ from, to }: DerivedStateProps) => State; /** Notify listener of current value. */ notify(): void; }; /** * A read-only state that provides access to the value, use, Render, and Show methods. */ type ReadOnlyState = Prettify>>, 'value' | 'use' | 'useCompute'>>; type State = IsEqual extends true ? never : [NonNullable] extends [readonly (infer U)[]] ? ArrayState : [NonNullable] extends [FieldValues] ? ObjectState, T> : ValueState; type ArrayState = IsEqual extends true ? never : ValueState & ArrayProxy; type ObjectState = ObjectProxy & ValueState & ObjectMutationMethods; /** Type for useCompute function. */ type StoreUseComputeFn, R> = (value: FieldPathValue) => R; type DerivedStateProps = { from?: (value: T) => R; to?: (value: R) => T; };