import { LitElementStateService } from './litElementState.service.js'; export interface StateConfig { cache?: { name?: string; exceptions?: RegExp[]; storePathsAsJson?: string[]; handlers: CacheHandler[]; }; defaultSubscribeOptions?: SubscribeStateFromElementOptions; global: boolean; } export interface CacheHandler { name: string; set(change: StateChange, stateServiceInstance: LitElementStateService): Promise; load(stateServiceInstance: LitElementStateService): Promise>; } export type StateSubscriptionFunction = (value: Change) => void; export interface Change

{ readonly previous: P | null; readonly current: P | null; } export type StateReducerMode = 'merge' | 'replace'; export type PredicateFunction = (array: ArrayType, index?: number) => boolean; export type IndexOrPredicateFunction = number | PredicateFunction; export type ArrayElementSelector = { array: ArrayName; get: IndexOrPredicateFunction; }; export interface GetStateOptions { getDeepCopy?: boolean; } export interface SubscribeStateOptions extends GetStateOptions { getInitialValue?: boolean; pushNestedChanges?: boolean; } export interface SubscribeStateFromElementOptions extends SubscribeStateOptions { autoUnsubscribe?: boolean; } export interface SetStateOptions { cacheHandlerName?: string; } export type StateChange = State extends Array ? { _arrayOperation: { op: 'update'; at: IndexOrPredicateFunction; val: StateChange | ((element: State[number]) => StateChange); } | { op: 'push'; at?: number; val: State[number]; } | { op: 'pull'; at?: IndexOrPredicateFunction; }; } | State : { [P in keyof State]?: State[P] | StateChange; } & { _reducerMode?: StateReducerMode; }; /** True only for `any`. */ type IsAny = 0 extends (1 & T) ? true : false; /** What the runtime's `Array.isArray` accepts: arrays, readonly arrays, tuples. */ type AnyArray = readonly any[]; /** Element type of an array-typed value. */ type ElementOf = NonNullable extends readonly (infer E)[] ? E : never; /** Keys of T holding arrays (guards per [6]). */ type ArrayKeys = { [K in keyof NonNullable]-?: IsAny[K]> extends true ? never : NonNullable[K]> extends AnyArray ? K : never; }[keyof NonNullable]; /** Keys of T not holding arrays. */ type NonArrayKeys = Exclude, ArrayKeys>; /** One type-level step of the runtime path walk. NonNullable first, so optional * intermediates never collapse `keyof` to `never`; invalid segments descend to * `any` so only the segment that is already reported errors, not its suffix. */ type Descend = IsAny extends true ? any : Seg extends { array: infer A; } ? (A extends keyof NonNullable ? ElementOf[A]> : any) : (Seg extends keyof NonNullable ? NonNullable[Seg] : any); /** Value at the end of path P. A plain array key in last position yields the * whole array (mirrors getStateData); non-tuple P (dynamic path) yields any. */ export type StatePathValue = number extends P['length'] ? any : P extends readonly [infer Head, ...infer Rest] ? (Rest extends readonly [unknown, ...unknown[]] ? StatePathValue, Rest> : Descend) : (IsAny extends true ? any : undefined); /** Position-exact selector for array key K of T — INLINE shape per [2]. */ type ArraySelectorFor = K extends keyof NonNullable ? { array: K; get: number | ((element: ElementOf[K]>, index?: number) => boolean); } : never; /** All position-exact selectors of one node T. */ type ArraySelectors = { [K in ArrayKeys]: ArraySelectorFor; }[ArrayKeys]; /** Plain keys allowed at a node: array keys only in last position (whole-array * subscription); mid-path an array requires a selector. KEYS-ONLY per [3]. */ type AllowedSegments = IsLast extends true ? keyof NonNullable : NonArrayKeys; /** Expected type of one segment: a well-formed selector resolves to its * position-exact shape, everything else to the allowed alternatives — which * drive both the error message and the IDE completions. */ type SegmentOut = IsAny extends true ? Seg : [ Seg ] extends [{ array: infer A; }] ? ([A] extends [ArrayKeys] ? ArraySelectorFor : ArraySelectors) : AllowedSegments; /** Expected tuple for path P (tail-recursive — exempt from the instantiation * depth limit). Non-tuple P degrades to the loose constraint shape; this covers * dynamic path variables AND the transient constraint-fixed moment while a * context-sensitive literal is contextually typed [1] — afterwards P is * inferred from the typed literal, so the final check is position-exact even * for unannotated predicates. The empty path stays an arity error. */ type ValidatePath = P extends readonly [infer Head, ...infer Rest] ? (Rest extends readonly [unknown, ...unknown[]] ? ValidatePath, Rest, readonly [...Acc, SegmentOut]> : readonly [...Acc, SegmentOut]) : P extends readonly [] ? readonly [...Acc, AllowedSegments] : StatePath; /** P itself when it matches the expected tuple (the naked P here carries the * literal inference), otherwise the expected tuple (per-segment errors). */ type ValidateShape = P extends Expected ? P : Expected; /** Non-unit string keys: `string` itself and template-literal patterns (a * Record over such a key has no required properties). */ type IsPatternKey = {} extends Record ? true : false; /** Walk collecting an entry for every array-typed property reachable in T * (depth-capped, linear in the state size, cached per T — NOT a path * enumeration). Literal keys are tagged `array`, pattern keys `patternArray` * per [5]; guards per [6]; numeric/symbol keys are not addressable by the * runtime's string segments. */ type DeepArrayEntries = Depth['length'] extends 10 ? never : IsAny extends true ? never : NonNullable extends infer U ? U extends readonly (infer E)[] ? DeepArrayEntries : U extends object ? { [K in keyof U]-?: (IsAny extends true ? never : [ NonNullable ] extends [never] ? never : NonNullable extends AnyArray ? (K extends string ? (IsPatternKey extends true ? { patternArray: K; element: ElementOf; } : { array: K; element: ElementOf; }) : never) : never) | DeepArrayEntries; }[keyof U] : never : never; /** All literal entry names (pattern entries stay out per [5]). */ type EntryNames = Entries extends { array: infer N extends string; } ? N : never; /** Union of the element types of every entry named N (same-name merge, [3]). */ type ElementForName = Entries extends { array: N; element: infer E; } ? E : never; /** The name-discriminated selector union that auto-types unannotated predicate * parameters [1]: one MERGED member per literal array name (element union, * [3]; `| Function` per [4]) plus SIGNATURE-FREE members for pattern names * ([3] — their predicates must be annotated). */ type DeepArraySelectors = DeepArrayEntries extends infer Entries ? [Entries] extends [never] ? never : (EntryNames extends infer Names ? (Names extends string ? { array: Names; get: number | ((element: ElementForName, index?: number) => boolean) | Function; } : never) : never) | (Entries extends { patternArray: infer PN extends string; } ? { array: PN; get: unknown; } : never) : never; /** The public path type: constraint of the path type parameter (any sequence * of keys and well-formed selectors for arrays existing anywhere in State) * and the type for DYNAMIC (non-literal) path variables. Doubles as the * contextual type that auto-types unannotated predicates — plain union + * distributive conditional are both required, see [1]. * * NOTE: do NOT use StatePath/StatePath for state-agnostic * storage — DeepArraySelectors guards `any` out (per [6]) and finds nothing * in `unknown`, so both collapse to `readonly string[]` and reject selector * segments. State-agnostic code (e.g. LitElementStateSubscription.path) * inlines the loose shape `readonly (string | ArrayElementSelector)[]`. */ export type StatePath = State extends unknown ? readonly (string | DeepArraySelectors)[] : never; /** Parameter type of the public path methods: position-exact validation and * value/predicate typing for literal paths (including unannotated predicates, * see ValidatePath); only dynamic (non-literal) paths stay loosely typed. */ export type CheckedStatePath = ValidateShape>; export * from './litElementStateful.js'; export * from './litElementState.service.js'; export * from './litElementStateSubscription.js'; //# sourceMappingURL=index.d.ts.map