import type { StorageValue } from './storage/storageTypes'; import type { PersistOptions, StateCreator as StoreStateCreator, StoreApi, StoreMutators, WithPersist } from './store/types'; import type { SyncConfig } from './sync/types'; import type { FunctionKeys } from './types/functions'; import type { SetFull, SetPartial, SetStateArgs } from './types/setState'; import type { EqualityFn, Selector, SubscribeOverloads } from './types/subscribe'; import type { UseStoreCallSignatures } from './types/useStoreCallSignatures'; export type { StoreMutators } from './store/types'; export type * from './types/setState'; export type * from './types/subscribe'; export type * from './types/useStoreCallSignatures'; export type StoreMutatorsWithSelector = Mutators; export type StateCreator = StoreStateCreator; export type UseBoundStoreWithEqualityFn unknown; }, State = InferStoreState> = UseStoreCallSignatures & Store; export type BaseStore = UseBoundStoreWithEqualityFn> & { subscribe: SubscribeOverloads; }; export type PersistedStore, PersistReturn extends void | Promise = void | Promise> = UseStoreCallSignatures & WithPersist, PersistedState, PersistReturn>; export type Store = never, PersistReturn extends void | Promise = void | Promise> = [ PersistedState ] extends [never] ? BaseStore : PersistedStore; /** * Store returned by creators that accept optional persistence options. * `persist` exists only when persistence is configured. */ export type OptionallyPersistedStore = void> = UseStoreCallSignatures & Omit, 'setState'> & { persist?: PersistedStore['persist']; setState(update: SetPartial, replace?: false): PersistReturn; setState(update: SetFull, replace: true): PersistReturn; }; export type NoInfer = [T][T extends unknown ? 0 : never]; export type Timeout = ReturnType; export type InferStoreState = Store extends { getState: () => infer T; } ? T : never; /** * Action methods returned by `createStoreActions(store)`. */ export type StoreActions> = Pick, FunctionKeys>>; /** * Extracts a store's `setState` return type. * - `void` for non-persisted or synchronous persisted stores. * - `Promise` for async persisted stores. */ export type InferSetStateReturn = Store extends { setState(...args: SetStateArgs): infer R; } ? R : void; /** * Extracts a store's `PersistedState` type. * Returns `never` if the store doesn't use persistence. */ export type InferPersistedState = PersistedStore extends Store ? PersistedState : never; /** * Reads store state and records dependencies for tracked computations. * - `$(store, selector, equalityFn?)` depends on the selected state * - `$(store)` depends on accessed state paths */ export type DeriveGetter = { >>(store: Store): InferStoreState; >, Selected>(store: Store, selector: Selector, Selected>, equalityFn?: EqualityFn): Selected; }; export type DerivedStore = WithFlushUpdates>>; export type WithFlushUpdates> = Store & { /** * Destroy the derived store and its subscriptions. * * Derived stores automatically clean up internal resources and subscriptions * when no subscribers exist. So calling `destroy()` is usually unnecessary, * unless `keepAlive: true` is specified and explict teardown is desired. */ destroy: () => void; /** * Flush all pending updates — only applicable to **debounced** derived stores. */ flushUpdates: () => void; }; export type WithGetSnapshot> = Store & { /** * Reads the current snapshot while activating lazy derived stores before subscription. */ getSnapshot: () => InferStoreState; }; type ReadOnlyDerivedStore> = Omit & UseStoreCallSignatures> & { /** * @deprecated **Not applicable to derived stores.** Will throw an error. */ getInitialState: Store['getInitialState']; /** * @deprecated **Not applicable to derived stores.** Will throw an error. */ setState: Store['setState']; }; /** * Configuration for creating derived stores. You can pass either: * - A **function** (used as `equalityFn`), or * - An **object** with the fields below */ export type DeriveOptions = EqualityFn | { /** * Delay before triggering a re-derive when dependencies change. * Accepts a number (ms) or debounce options: * * `{ delay: number, leading?: boolean, trailing?: boolean, maxWait?: number }` * @default 0 */ debounce?: number | DebounceOptions; /** * If `true`, the store will log debug messages to the console. * * If `'verbose'`, the store will log the subscriptions it creates each time the derive * function is run, rather than only the first time. * @default false */ debugMode?: boolean | 'verbose'; /** * A custom comparison function for detecting state changes. * @default `Object.is` */ equalityFn?: EqualityFn; /** * If `true`, the derived store will never destroy itself. Useful in cases where your * derived store serves as a permanent cache subscribed to intermittently or not at all. * Manual calls to `destroy` *will* destroy the store even when `keepAlive` is `true`. * * *Use this option carefully.* * @default false */ keepAlive?: boolean; /** * Locks the dependency graph after the first derivation. Subscriptions to * underlying stores are established once and reused on subsequent runs, rather * than being torn down and rebuilt (the default behavior). * * This avoids the overhead of regenerating selectors and prevents unnecessary * subscription churn. However, it means only the *initially tracked* dependencies * will trigger updates — even if your derive function conditionally reads different * stores in later runs. * * **Requirement**: All `$` calls in your derive function must be consistent and * top level. Conditional dependency tracking will not work correctly. * * Safe to enable for most derived stores where dependencies are static. * * @default false */ lockDependencies?: boolean; }; export type Deserializer = (serializedState: SerializedState) => StorageValue; export type Serializer = (storageValue: StorageValue) => SerializedState; /** * Synchronous storage interface. * Used for localStorage and MMKV implementations. */ export type SyncStorageInterface = { readonly async?: false; /** * Adapter-level deserializer used when a store does not supply its own. * Acts as the default before falling back to the framework implementation. */ deserializer?(serializedState: SerializedState): StorageValue; /** * Adapter-level serializer used when a store does not supply its own. * Acts as the default before falling back to the framework implementation. */ serializer?(storageValue: StorageValue): SerializedState; clearAll(): void; contains(key: string): boolean; delete(key: string): void; get(key: string): SerializedState | undefined; getAllKeys(): string[]; set(key: string, value: SerializedState): void; }; /** * Asynchronous storage interface. * Used for Chrome storage and other async storage implementations. */ export type AsyncStorageInterface = { readonly async: true; /** * Adapter-level deserializer used when a store does not supply its own. * Acts as the default before falling back to the framework implementation. */ deserializer?(serializedState: SerializedState): StorageValue; /** * Adapter-level serializer used when a store does not supply its own. * Acts as the default before falling back to the framework implementation. */ serializer?(storageValue: StorageValue): SerializedState; clearAll(): Promise; contains(key: string): Promise; delete(key: string): Promise; get(key: string): Promise; getAllKeys(): Promise; set(key: string, value: SerializedState): Promise; }; /** * Configuration options for creating a persistable store. */ export type PersistConfig = Partial, PersistReturn = void> = { /** * A function to convert the serialized value back into the state object. * If not provided, the storage adapter's `deserializer` is used before falling back to the default implementation. */ deserializer?: (serializedState: unknown) => StorageValue; /** * A function to merge persisted state with current state during hydration. * By default, persisted state is shallow-merged into the current state. */ merge?: PersistOptions['merge']; /** * A function to perform persisted state migration. * This function will be called when persisted state versions mismatch with the one specified here. */ migrate?: PersistOptions['migrate']; /** * A function returning another (optional) function. * The main function will be called before the state rehydration. * The returned function will be called after the state rehydration or when an error occurred. */ onRehydrateStorage?: PersistOptions['onRehydrateStorage']; /** * A function that determines which parts of the state should be persisted. * By default, the entire state is persisted. */ partialize?: (state: Readonly) => PersistedState; /** * The throttle rate for the persist operation in milliseconds. * @default iOS: time.seconds(3) | Android: time.seconds(5) */ persistThrottleMs?: PersistReturn extends Promise ? undefined : number; /** * A function to serialize the state and version for storage. * If not provided, the storage adapter's `serializer` is used before falling back to the default implementation. */ serializer?: (storageValue: StorageValue) => string; /** * Custom storage implementation. If async, `setState` will return a Promise that resolves * when the state is persisted. If sync, `setState` will return void. */ storage?: PersistReturn extends Promise ? AsyncStorageInterface : SyncStorageInterface; /** * The unique key for the persisted store. */ storageKey: string; /** * The version of the store's schema. * Useful for handling schema changes across app versions. * @default 0 */ version?: number; }; export type EnforceStorageKey = { storageKey: string; } extends Options ? Options : never; export type BaseStoreOptions = Partial, PersistReturn = void> = (PersistConfig & { sync?: S extends Record ? SyncOption : undefined; }) | ({ sync: S extends Record ? SyncWithoutStorageOption> : undefined; } & UndefinedPersistKeys); /** * The `sync` option can be: * - `SyncConfig` object * - `string` (shorthand for `{ key: string }`) * - `true` (inherits key from `storageKey` — only valid with persistence) */ export type SyncOption> = SyncConfig | string | true; type SyncWithoutStorageOption> = string | (Omit, 'injectStorageMetadata' | 'key'> & { injectStorageMetadata?: never; key: SyncWithoutStorageKey>; }); type SyncWithoutStorageKey = Config extends { key?: infer Key; } ? Extract extends never ? string : Extract : string; type UndefinedPersistKeys, PersistReturn> = { [K in keyof PersistConfig]?: undefined; }; /** * Expanded options for custom debounce behavior. */ export type DebounceOptions = { delay: number; leading?: boolean; maxWait?: number; trailing?: boolean; };