import { ActionChain, Observable, Settable } from '@zedux/core'; import { AtomApi } from '../classes/AtomApi.js'; import { Ecosystem } from '../classes/Ecosystem.js'; import { SelectorCache } from '../classes/Selectors.js'; import { AnyAtomInstance, AnyAtomTemplate, AtomGenerics, AtomGenericsToAtomApiGenerics, AtomInstanceType, AtomParamsType, AtomStateType } from './atoms.js'; export * from './atoms.js'; export declare type AnyNonNullishValue = {}; export interface AtomConfig { dehydrate?: (state: State) => any; flags?: string[]; hydrate?: (dehydratedState: unknown) => State; manualHydration?: boolean; ttl?: number; } /** * The AtomGettersBase interface. You probably won't want to use this directly. * Use AtomGetters instead. */ export interface AtomGettersBase { /** * Registers a dynamic graph edge on the resolved atom instance when called * synchronously during atom or AtomSelector evaluation. When called * asynchronously, is just an alias for `ecosystem.get` */ get(template: A, params: AtomParamsType): AtomStateType; get>(template: A): AtomStateType; get(template: ParamlessTemplate): AtomStateType; get(instance: I): AtomStateType; /** * Registers a static graph edge on the resolved atom instance when called * synchronously during atom or AtomSelector evaluation. When called * asynchronously, is just an alias for `ecosystem.getInstance` */ getInstance(template: A, params: AtomParamsType, edgeInfo?: GraphEdgeInfo): AtomInstanceType; getInstance>(template: A): AtomInstanceType; getInstance(template: ParamlessTemplate): AtomInstanceType; getInstance(instance: I, params?: [], edgeInfo?: GraphEdgeInfo): I; /** * Runs an AtomSelector which receives its own AtomGetters object and can use * those to register its own dynamic and/or static graph edges (when called * synchronously during the AtomSelector's evaluation) * * ```ts * const mySelector = ion('mySelector', ({ select }) => { * // registers a dynamic dependency on myAtom: * const dynamicVal = select(({ get }) => get(myAtom)) * * injectEffect(() => { * // doesn't register anything: * const staticVal = select(({ get }) => get(myAtom)) * }, []) // no need to pass select as a dep; it's a stable reference * }) * ``` * * @see AtomSelector */ select(selectorOrConfigOrCache: Selectable, ...args: Args): T; } /** * AtomGetters are used all throughout Zedux. When called synchronously during * atom or AtomSelector evaluation, they register graph edges. When called * asynchronously, they're just aliases for the corresponding ecosystem method. * * ```ts * const mySelector = ion('mySelector', ({ ecosystem, get }) => { * const dynamicVal = get(myAtom) // registers graph edge * const staticVal = ecosystem.get(myAtom) // doesn't register anything * * injectEffect(() => { * const staticVal2 = get(myAtom) // doesn't register anything * // const staticVal2 = ecosystem.get(myAtom) // same exact thing * }, []) * }) * ``` */ export interface AtomGetters extends AtomGettersBase { /** * A reference to the ecosystem of the current atom instance or AtomSelector. * * The ecosystem itself has `get`, `getInstance`, and `select` methods which * can be used instead of the other AtomGetters to prevent graph dependencies * from being registered. * * ```ts * // the current component will NOT rerender when myAtom changes: * const staticVal = useAtomSelector(({ ecosystem }) => ecosystem.get(myAtom)) * * // the current component will rerender when myAtom changes: * const dynamicVal = useAtomSelector(({ get }) => get(myAtom)) * ``` */ ecosystem: Ecosystem; } export declare type AtomInstanceTtl = number | Promise | Observable; export declare type AtomSelector = (getters: AtomGetters, ...args: Args) => T; export interface AtomSelectorConfig { argsComparator?: (newArgs: Args, oldArgs: Args) => boolean; name?: string; resultsComparator?: (newResult: T, oldResult: T) => boolean; selector: AtomSelector; } export declare type AtomSelectorOrConfig = AtomSelector | AtomSelectorConfig; export declare type AtomStateFactory = (...params: G['Params']) => AtomApi> | G['Store'] | G['State']; export declare type AtomTuple = [A, AtomParamsType]; export declare type AtomValueOrFactory = AtomStateFactory | G['Store'] | G['State']; export declare type Cleanup = () => void; export declare type DependentCallback = (signal: GraphEdgeSignal, val?: any, reason?: EvaluationReason) => any; export interface DependentEdge { callback?: DependentCallback; createdAt: number; dependentKey?: string; flags: number; isMaterialized?: boolean; operation: string; prevEdge?: WeakRef; task?: () => void; } export interface EcosystemConfig | undefined = any> { atomDefaults?: { ttl?: number; }; complexParams?: boolean; context?: Context; destroyOnUnmount?: boolean; flags?: string[]; id?: string; onReady?: (ecosystem: Ecosystem, prevContext?: Context) => MaybeCleanup; overrides?: AnyAtomTemplate[]; ssr?: boolean; } export interface EcosystemGraphNode { dependencies: Map; dependents: Map; isSelector?: boolean; refCount: number; weight: number; } export declare type EffectCallback = () => MaybeCleanup | Promise; export interface EvaluationReason { action?: ActionChain; newState?: State; oldState?: State; operation: string; sourceType: EvaluationSourceType; sourceId?: string; reasons?: EvaluationReason[]; type: EvaluationType; } export declare type EvaluationSourceType = 'Atom' | 'AtomSelector' | 'External' | 'Injector' | 'Store'; export declare type EvaluationType = 'cache invalidated' | 'node destroyed' | 'promise changed' | 'state changed'; export declare type ExportsInfusedSetter = Exports & { (settable: Settable, meta?: any): State; }; export declare type GraphEdgeInfo = [ flags: number, operation: string ]; /** * A low-level detail that tells dependents what sort of event is causing the * current update. Promise changes and state updates are lumped together as * 'Update' signals. If you need to distinguish between them, look at the * EvaluationType (the `type` field) in the full reasons list. */ export declare type GraphEdgeSignal = 'Destroyed' | 'Updated'; export interface GraphViewRecursive { [key: string]: GraphViewRecursive; } export interface InjectAtomInstanceConfig { operation?: string; subscribe?: boolean; } export declare type InjectorDeps = any[] | undefined; export declare type InjectOrUseSelector = Params extends [] ? (selector: (state: State) => D) => D : (params: Params, selector: (state: State) => D) => D; export interface InjectPromiseConfig { dataOnly?: boolean; initialState?: T; runOnInvalidate?: boolean; } export interface InjectStoreConfig { hydrate?: boolean; subscribe?: boolean; } export declare type IonStateFactory = (getters: AtomGetters, ...params: G['Params']) => AtomApi> | G['Store'] | G['State']; export declare type LifecycleStatus = 'Active' | 'Destroyed' | 'Initializing' | 'Stale'; export declare type MaybeCleanup = Cleanup | void; export interface MutableRefObject { current: T; } /** * Many Zedux APIs make the `params` parameter optional if the atom doesn't take * params or has only optional params. */ export declare type ParamlessTemplate = AtomParamsType extends [AnyNonNullishValue | undefined | null, ...any[]] ? never : A; /** * Part of the atom instance can be accessed during initial evaluation. The only * fields that are inaccessible are those that don't exist yet 'cause the * initial evaluation is supposed to create them. */ export declare type PartialAtomInstance = Omit; export declare type Prettify = { [K in keyof T]: T[K]; } & AnyNonNullishValue; export interface PromiseState { data?: T; error?: Error; isError: boolean; isLoading: boolean; isSuccess: boolean; status: PromiseStatus; } export declare type PromiseStatus = 'error' | 'loading' | 'success'; export declare type Ref = MutableRefObject; export interface RefObject { readonly current: T | null; } export declare type Selectable = AtomSelector | AtomSelectorConfig | SelectorCache; export declare type StateHookTuple = [ State, ExportsInfusedSetter ];