@signalium/query 1.0.15 → 1.0.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/dist/cjs/development/index.js +2 -2
- package/dist/cjs/development/index.js.map +1 -1
- package/dist/cjs/production/index.js +2 -2
- package/dist/cjs/production/index.js.map +1 -1
- package/dist/esm/development/index.js +2 -2
- package/dist/esm/development/index.js.map +1 -1
- package/dist/esm/production/index.js +2 -2
- package/dist/esm/production/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../src/types.ts","../../../src/typeDefs.ts","../../../src/errors.ts","../../../src/utils.ts","../../../src/proxy.ts","../../../src/EntityMap.ts","../../../src/NetworkManager.ts","../../../src/parseEntities.ts","../../../src/QueryResult.ts","../../../src/MutationResult.ts","../../../src/RefetchManager.ts","../../../src/MemoryEvictionManager.ts","../../../src/QueryClient.ts","../../../src/pathInterpolator.ts","../../../src/query.ts","../../../src/mutation.ts"],"sourcesContent":["import { PendingReactivePromise, ReadyReactivePromise, type Signal } from 'signalium';\nimport { ReactivePromise } from 'signalium';\nimport { HasRequiredKeys, Optionalize, Prettify, Signalize } from './type-utils.js';\n\n// ================================\n// Base URL and Request Types\n// ================================\n\n/**\n * Flexible base URL value - can be a static string, a Signal, or a function.\n * Functions are wrapped in reactiveSignal internally for memoization.\n */\nexport type BaseUrlValue = string | Signal<string> | (() => string);\n\n/**\n * Extended RequestInit with additional query-specific options.\n * This is what gets passed to the fetch function.\n */\nexport interface QueryRequestInit extends RequestInit {\n baseUrl?: string;\n searchParams?: URLSearchParams;\n}\n\n/**\n * Request options that can be specified at the query definition level.\n * These can override context-level settings.\n */\nexport interface QueryRequestOptions {\n baseUrl?: BaseUrlValue;\n headers?: HeadersInit;\n credentials?: RequestCredentials;\n mode?: RequestMode;\n cache?: RequestCache;\n redirect?: RequestRedirect;\n referrer?: string;\n referrerPolicy?: ReferrerPolicy;\n integrity?: string;\n keepalive?: boolean;\n signal?: AbortSignal;\n}\n\n// ================================\n// Type Definitions\n// ================================\n\nexport enum RefetchInterval {\n Every1Second = 1000,\n Every5Seconds = 5000,\n Every10Seconds = 10000,\n Every30Seconds = 30000,\n Every1Minute = 60000,\n Every5Minutes = 300000,\n}\n\nexport enum NetworkMode {\n /**\n * Always fetch regardless of network status\n */\n Always = 'always',\n /**\n * Only fetch when online (default)\n */\n Online = 'online',\n /**\n * Fetch if cached data exists, even when offline\n */\n OfflineFirst = 'offlineFirst',\n}\n\nexport interface RetryConfig {\n /**\n * Number of retry attempts\n */\n retries: number;\n /**\n * Optional custom delay function (receives attempt index starting at 0)\n * Default: exponential backoff (1000ms * 2^attempt)\n */\n retryDelay?: (attemptIndex: number) => number;\n}\n\nexport const enum Mask {\n // Fundamental types\n UNDEFINED = 1 << 0,\n NULL = 1 << 1,\n NUMBER = 1 << 2,\n STRING = 1 << 3,\n BOOLEAN = 1 << 4,\n OBJECT = 1 << 5,\n ARRAY = 1 << 6,\n ID = 1 << 7,\n\n // Complex types\n RECORD = 1 << 8,\n UNION = 1 << 9,\n ENTITY = 1 << 10,\n\n // Flags\n HAS_SUB_ENTITY = 1 << 11,\n HAS_NUMBER_FORMAT = 1 << 12,\n HAS_STRING_FORMAT = 1 << 13,\n PARSE_RESULT = 1 << 14,\n}\n\n// ================================\n// ParseResult Types\n// ================================\n\nexport type ParseSuccess<T> = { success: true; value: T };\nexport type ParseError = { success: false; error: Error };\nexport type ParseResult<T> = ParseSuccess<T> | ParseError;\n\n/**\n * Interface for case-insensitive enum sets.\n * String values are matched case-insensitively during parsing,\n * but always return the canonical (originally defined) casing.\n */\nexport interface CaseInsensitiveEnumSet<T extends string | boolean | number> extends Set<T> {\n /**\n * Check if a value exists in the set (case-insensitively for strings).\n */\n has(value: unknown): boolean;\n\n /**\n * Get the canonical value for a given input.\n * For strings, performs case-insensitive lookup and returns the canonical casing.\n * For numbers/booleans, performs exact match.\n * Returns undefined if no match is found.\n */\n get(value: unknown): T | undefined;\n}\n\nexport type SimpleTypeDef =\n // Sets are constant values\n | Set<string | boolean | number>\n\n // Case-insensitive enum sets\n | CaseInsensitiveEnumSet<string | boolean | number>\n\n // Numbers are primitive type masks (potentially multiple masks combined)\n | Mask;\n\nexport type ComplexTypeDef =\n // Objects, arrays, records, unions, and parse results are definitions\n ObjectDef | EntityDef | ArrayDef | RecordDef | UnionDef | ParseResultDef;\n\nexport type TypeDef = SimpleTypeDef | ComplexTypeDef;\n\nexport type ObjectFieldTypeDef = TypeDef | string;\n\nexport type ObjectShape = Record<string, ObjectFieldTypeDef>;\n\n// ================================\n// Extend Type Utilities\n// ================================\n\n/**\n * Utility type that prevents extending with keys that already exist in T.\n * If U contains a key from T, that key's type becomes `never`, causing a type error.\n */\nexport type StrictExtend<T extends ObjectShape, U extends ObjectShape> = {\n [K in keyof U]: K extends keyof T ? never : U[K];\n};\n\nexport const ARRAY_KEY = Symbol('array');\nexport const RECORD_KEY = Symbol('record');\n\nexport interface UnionTypeDefs {\n [ARRAY_KEY]?: TypeDef;\n [RECORD_KEY]?: TypeDef;\n [key: string]: ObjectDef | EntityDef;\n}\n\nexport interface BaseTypeDef {\n mask: Mask;\n shapeKey: number;\n typenameField: string;\n typenameValue: string;\n idField: string;\n subEntityPaths: undefined | string | string[];\n values: Set<string | boolean | number> | undefined;\n\n optional: this | Mask.UNDEFINED;\n nullable: this | Mask.NULL;\n nullish: this | Mask.UNDEFINED | Mask.NULL;\n}\n\nexport type EntityMethods = Record<string, (...args: any[]) => any>;\n\n// Helper type to conditionally include methods - unknown (invisible) when M is the default EntityMethods\n// We check if M has an index signature by seeing if it allows any string key\nexport type IncludeMethods<M> = string extends keyof M ? unknown : M;\n\n// Entity configuration options\nexport interface EntityConfig<T extends ObjectShape> {\n stream: {\n subscribe: (\n context: import('./QueryClient.js').QueryContext,\n id: string | number,\n onUpdate: (update: Partial<ExtractTypesFromShape<T>>) => void,\n ) => (() => void) | undefined;\n };\n}\n\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\nexport interface EntityDef<T extends ObjectShape = ObjectShape, M extends EntityMethods = {}> extends BaseTypeDef {\n mask: Mask.ENTITY;\n shape: T;\n\n /**\n * Creates a new EntityDef that extends this one with additional fields and optional methods.\n * The function is called lazily on first shape access to support circular references.\n * Prevents overriding of existing fields including id and typename.\n *\n * @param newFieldsGetter - Lazy factory returning new fields to add\n * @param newMethodsGetter - Optional lazy factory returning new methods to add (merged with existing)\n */\n // eslint-disable-next-line @typescript-eslint/no-empty-object-type\n extend<U extends ObjectShape, N extends EntityMethods = {}>(\n newFieldsGetter: () => StrictExtend<T, U> & U,\n newMethodsGetter?: () => N & ThisType<N & ExtractTypesFromShape<T & U> & IncludeMethods<M>>,\n ): EntityDef<T & U, M & N>;\n}\n\nexport interface ObjectDef<T extends ObjectShape = ObjectShape> extends BaseTypeDef {\n mask: Mask.OBJECT;\n shape: T;\n /**\n * Creates a new ObjectDef that extends this one with additional fields.\n * Prevents overriding of existing fields including id and typename.\n */\n extend<U extends ObjectShape>(newFields: StrictExtend<T, U> & U): ObjectDef<T & U>;\n}\n\nexport interface ArrayDef<T extends TypeDef = TypeDef> extends BaseTypeDef {\n mask: Mask.ARRAY;\n shape: T;\n}\n\nexport interface UnionDef<_T extends readonly TypeDef[] = readonly TypeDef[]> extends BaseTypeDef {\n mask: Mask.UNION;\n shape: UnionTypeDefs | undefined;\n}\n\nexport interface RecordDef<T extends TypeDef = TypeDef> extends BaseTypeDef {\n mask: Mask.RECORD;\n shape: T;\n}\n\nexport interface ParseResultDef<T extends TypeDef = TypeDef> extends BaseTypeDef {\n mask: Mask.PARSE_RESULT;\n shape: T;\n}\n\n/**\n * Global format registry interface that maps format names to their TypeScript types.\n * This can be extended via module augmentation using the SignaliumQuery namespace.\n */\ndeclare global {\n // eslint-disable-next-line @typescript-eslint/no-namespace\n namespace SignaliumQuery {\n interface FormatRegistry {\n date: Date;\n 'date-time': Date;\n // Users can extend this via module augmentation\n // Example: declare global { namespace SignaliumQuery { interface FormatRegistry { 'custom-format': CustomType } } }\n }\n }\n}\n\ndeclare const FormattedSymbol: unique symbol;\n\nexport type Formatted<T> = number & {\n [FormattedSymbol]: T;\n};\n\nexport interface APITypes {\n format: <K extends keyof SignaliumQuery.FormatRegistry>(format: K) => Formatted<SignaliumQuery.FormatRegistry[K]>;\n typename: <T extends string>(value: T) => T;\n const: <T extends string | boolean | number>(value: T) => Set<T>;\n enum: {\n <T extends readonly (string | boolean | number)[]>(...values: T): Set<T[number]>;\n caseInsensitive<T extends readonly (string | boolean | number)[]>(...values: T): Set<T[number]>;\n };\n\n id: Mask.ID;\n string: Mask.STRING;\n number: Mask.NUMBER;\n boolean: Mask.BOOLEAN;\n null: Mask.NULL;\n undefined: Mask.UNDEFINED;\n\n array: <T extends TypeDef>(shape: T) => ArrayDef<T>;\n\n object: <T extends ObjectShape>(shape: T) => ObjectDef<T>;\n record: <T extends TypeDef>(shape: T) => RecordDef<T>;\n\n union: <VS extends readonly TypeDef[]>(...types: VS) => UnionDef<VS>;\n\n nullish: <T extends TypeDef>(type: T) => T | Mask.UNDEFINED | Mask.NULL;\n optional: <T extends TypeDef>(type: T) => T | Mask.UNDEFINED;\n nullable: <T extends TypeDef>(type: T) => T | Mask.NULL;\n\n result: <T extends TypeDef>(type: T) => ParseResultDef<T>;\n}\n\n// ================================\n// Type Extraction\n// ================================\n\ntype ExtractPrimitiveTypeFromMask<T extends number> = T extends Mask.UNDEFINED\n ? undefined\n : T extends Mask.NULL\n ? null\n : T extends Mask.NUMBER\n ? number\n : T extends Mask.STRING\n ? string\n : T extends Mask.BOOLEAN\n ? boolean\n : T extends Mask.ID\n ? string | number\n : never;\n\nexport type ExtractTypesFromShape<S extends Record<string, ObjectFieldTypeDef>> = {\n [K in keyof S]: ExtractType<S[K]>;\n};\n\nexport type ExtractType<T extends ObjectFieldTypeDef> =\n T extends Formatted<infer U>\n ? U\n : T extends number\n ? ExtractPrimitiveTypeFromMask<T>\n : T extends string\n ? T\n : T extends Set<infer TSet>\n ? TSet\n : T extends ObjectDef<infer S>\n ? Prettify<ExtractTypesFromShape<S>>\n : T extends EntityDef<infer S, infer M>\n ? Prettify<ExtractTypesFromShape<S> & IncludeMethods<M>>\n : T extends ArrayDef<infer S>\n ? ExtractType<S>[]\n : T extends RecordDef<infer S>\n ? Record<string, ExtractType<S>>\n : T extends UnionDef<infer VS>\n ? ExtractType<VS[number]>\n : T extends ParseResultDef<infer S>\n ? ParseResult<ExtractType<S>>\n : never;\n\nexport type QueryType<T> = T extends () => infer Response\n ? Response extends QueryResult<infer T, unknown, unknown>\n ? T\n : never\n : never;\n\nexport type ResponseTypeDef = Record<string, ObjectFieldTypeDef> | ObjectFieldTypeDef;\n\nexport type ParamsOrUndefined<Params extends Record<string, unknown>> =\n // eslint-disable-next-line @typescript-eslint/no-empty-object-type\n {} extends Params ? undefined : Params;\n\nexport type ExtractTypesFromObjectOrEntity<S extends ResponseTypeDef> =\n S extends Record<string, ObjectFieldTypeDef>\n ? {\n [K in keyof S]: ExtractType<S[K]>;\n }\n : S extends ObjectFieldTypeDef\n ? ExtractType<S>\n : // eslint-disable-next-line @typescript-eslint/no-empty-object-type\n {};\n\nexport type ExtractTypesFromEntityOrUndefined<S extends EntityDef | UnionDef<EntityDef[]> | undefined = undefined> =\n S extends EntityDef<infer Shape, infer Methods>\n ? Prettify<ExtractTypesFromShape<Shape> & IncludeMethods<Methods>>\n : S extends UnionDef<infer VS>\n ? ExtractType<VS[number]>\n : undefined;\n\n// ================================\n// Query Extra Types\n// ================================\n\nexport type QueryExtra<StreamType, OptimisticInsertType> = {\n streamOrphans: StreamType extends undefined ? undefined : ReadonlySet<StreamType>;\n optimisticInserts: OptimisticInsertType extends undefined ? undefined : ReadonlySet<OptimisticInsertType>;\n};\n\n// ================================\n// Query Types\n// ================================\n\ninterface BaseQueryResultExtensions<T, StreamType, OptimisticUpdateType> {\n readonly isFetching: boolean;\n readonly isPaused: boolean;\n readonly extra: QueryExtra<StreamType, OptimisticUpdateType>;\n}\n\ninterface QueryResultExtensions<T, StreamType, OptimisticUpdateType>\n extends BaseQueryResultExtensions<T, StreamType, OptimisticUpdateType> {\n refetch: () => Promise<T>;\n readonly isRefetching: boolean;\n}\n\nexport type BaseQueryResult<T, StreamType, OptimisticUpdateType> = ReactivePromise<T> &\n QueryResultExtensions<T, StreamType, OptimisticUpdateType>;\n\nexport type PendingQueryResult<T, StreamType, OptimisticUpdateType> = PendingReactivePromise<T> &\n QueryResultExtensions<T, StreamType, OptimisticUpdateType>;\n\nexport type ReadyQueryResult<T, StreamType, OptimisticUpdateType> = ReadyReactivePromise<T> &\n QueryResultExtensions<T, StreamType, OptimisticUpdateType>;\n\nexport type QueryResult<T, StreamType = undefined, OptimisticUpdateType = undefined> =\n | PendingQueryResult<T, StreamType, OptimisticUpdateType>\n | ReadyQueryResult<T, StreamType, OptimisticUpdateType>;\n\nexport type QueryFn<\n Params extends Record<string, unknown>,\n Response extends ResponseTypeDef,\n StreamType extends EntityDef | UnionDef<EntityDef[]> | undefined = undefined,\n OptimisticUpdateType extends EntityDef | UnionDef<EntityDef[]> | undefined = undefined,\n> =\n HasRequiredKeys<Params> extends true\n ? (\n params: Prettify<Optionalize<Signalize<Params>>>,\n ) => QueryResult<\n Readonly<Prettify<ExtractTypesFromObjectOrEntity<Response>>>,\n Readonly<Prettify<ExtractTypesFromEntityOrUndefined<StreamType>>>,\n Readonly<Prettify<ExtractTypesFromEntityOrUndefined<OptimisticUpdateType>>>\n >\n : (\n params?: Prettify<Optionalize<ParamsOrUndefined<Signalize<Params>>>>,\n ) => QueryResult<\n Readonly<Prettify<ExtractTypesFromObjectOrEntity<Response>>>,\n Readonly<Prettify<ExtractTypesFromEntityOrUndefined<StreamType>>>,\n Readonly<Prettify<ExtractTypesFromEntityOrUndefined<OptimisticUpdateType>>>\n >;\n\n// ================================\n// Infinite Query Types\n// ================================\n\ninterface InfiniteQueryResultExtensions<T, StreamType, OptimisticUpdateType>\n extends QueryResultExtensions<T, StreamType, OptimisticUpdateType> {\n fetchNextPage: () => Promise<T>;\n hasNextPage: boolean;\n isFetchingMore: boolean;\n}\n\nexport type BaseInfiniteQueryResult<T, StreamType, OptimisticUpdateType> = ReactivePromise<T> &\n InfiniteQueryResultExtensions<T, StreamType, OptimisticUpdateType>;\n\nexport type PendingInfiniteQueryResult<T, StreamType, OptimisticUpdateType> = PendingReactivePromise<T> &\n InfiniteQueryResultExtensions<T, StreamType, OptimisticUpdateType>;\n\nexport type ReadyInfiniteQueryResult<T, StreamType, OptimisticUpdateType> = ReadyReactivePromise<T> &\n InfiniteQueryResultExtensions<T, StreamType, OptimisticUpdateType>;\n\nexport type InfiniteQueryResult<T, StreamType = undefined, OptimisticUpdateType = undefined> =\n | PendingInfiniteQueryResult<T, StreamType, OptimisticUpdateType>\n | ReadyInfiniteQueryResult<T, StreamType, OptimisticUpdateType>;\n\nexport type InfiniteQueryFn<\n Params extends Record<string, unknown>,\n Response extends Record<string, ObjectFieldTypeDef> | ObjectFieldTypeDef,\n StreamType extends EntityDef | UnionDef<EntityDef[]> | undefined = undefined,\n OptimisticUpdateType extends EntityDef | UnionDef<EntityDef[]> | undefined = undefined,\n> =\n HasRequiredKeys<Params> extends true\n ? (\n params: Prettify<Optionalize<Signalize<Params>>>,\n ) => InfiniteQueryResult<\n Readonly<Prettify<ExtractTypesFromObjectOrEntity<Response>>>[],\n Readonly<Prettify<ExtractTypesFromEntityOrUndefined<StreamType>>>,\n Readonly<Prettify<ExtractTypesFromEntityOrUndefined<OptimisticUpdateType>>>\n >\n : (\n params?: Prettify<Optionalize<ParamsOrUndefined<Signalize<Params>>>>,\n ) => InfiniteQueryResult<\n Readonly<Prettify<ExtractTypesFromObjectOrEntity<Response>>>[],\n Readonly<Prettify<ExtractTypesFromEntityOrUndefined<StreamType>>>,\n Readonly<Prettify<ExtractTypesFromEntityOrUndefined<OptimisticUpdateType>>>\n >;\n\n// ================================\n// Stream Query Types\n// ================================\n\ntype StreamQueryResultExtensions<T> = BaseQueryResultExtensions<T, undefined, undefined>;\n\nexport type BaseStreamQueryResult<T> = ReactivePromise<T> & StreamQueryResultExtensions<T>;\n\nexport type PendingStreamQueryResult<T> = PendingReactivePromise<T> & StreamQueryResultExtensions<T>;\n\nexport type ReadyStreamQueryResult<T> = ReadyReactivePromise<T> & StreamQueryResultExtensions<T>;\n\nexport type StreamQueryResult<T> = PendingStreamQueryResult<T> | ReadyStreamQueryResult<T>;\n\nexport type StreamQueryFn<Params extends Record<string, unknown>, Response extends EntityDef | UnionDef<EntityDef[]>> =\n HasRequiredKeys<Params> extends true\n ? (\n params: Prettify<Optionalize<Params>>,\n ) => StreamQueryResult<Readonly<Prettify<ExtractTypesFromObjectOrEntity<Response>>>>\n : (\n params?: Prettify<Optionalize<ParamsOrUndefined<Params>>>,\n ) => StreamQueryResult<Readonly<Prettify<ExtractTypesFromObjectOrEntity<Response>>>>;\n\n// ================================\n// Mutation Types\n// ================================\n\n/**\n * Base mutation result interface extending ReactivePromise with mutation-specific properties.\n */\ninterface MutationResultExtensions<Request, Response> {\n /**\n * Reset the mutation state.\n */\n reset(): void;\n /**\n * Execute the mutation with the given request data.\n */\n run(request: Request): MutationResult<Request, Response>;\n}\n\nexport type BaseMutationResult<Request, Response> = ReactivePromise<Response> &\n MutationResultExtensions<Request, Response>;\n\nexport type PendingMutationResult<Request, Response> = PendingReactivePromise<Response> &\n MutationResultExtensions<Request, Response>;\n\nexport type ReadyMutationResult<Request, Response> = ReadyReactivePromise<Response> &\n MutationResultExtensions<Request, Response>;\n\nexport type MutationResult<Request, Response> =\n | PendingMutationResult<Request, Response>\n | ReadyMutationResult<Request, Response>;\n\n/**\n * A mutation function that returns a MutationResult.\n * The mutation must be explicitly run via `.run(request)`.\n */\nexport type MutationFn<Request, Response extends ResponseTypeDef> = () => MutationResult<\n Request,\n Readonly<Prettify<ExtractTypesFromObjectOrEntity<Response>>>\n>;\n","import {\n APITypes,\n ARRAY_KEY,\n ArrayDef,\n ComplexTypeDef,\n EntityConfig,\n EntityDef,\n EntityMethods,\n ExtractTypesFromShape,\n Formatted,\n Mask,\n ObjectDef,\n ObjectShape,\n ParseResultDef,\n RECORD_KEY,\n RecordDef,\n TypeDef,\n UnionDef,\n UnionTypeDefs,\n} from './types.js';\nimport { Prettify } from './type-utils.js';\nimport { hashValue } from 'signalium/utils';\n\nconst entries = Object.entries;\nconst isArray = Array.isArray;\n\nconst enum ComplexTypeDefKind {\n OBJECT = 0,\n UNION = 1,\n PRIMITIVE_UNION = 2,\n ARRAY = 3,\n RECORD = 4,\n ENTITY = 5,\n PARSE_RESULT = 6,\n}\n\nexport class ValidatorDef<T> {\n private kind: ComplexTypeDefKind;\n public mask: Mask;\n private _optional: ValidatorDef<T | undefined> | undefined;\n private _nullable: ValidatorDef<T | null> | undefined;\n private _nullish: ValidatorDef<T | null | undefined> | undefined;\n private _shapeKey: number | undefined = undefined;\n private _shape: TypeDef | ObjectShape | UnionTypeDefs | (() => ObjectShape) | ComplexTypeDef[] | undefined;\n public subEntityPaths: undefined | string | string[] = undefined;\n public typenameField: string | undefined = undefined;\n public typenameValue: string | undefined = undefined;\n public idField: string | undefined = undefined;\n public values: Set<string | boolean | number> | undefined = undefined;\n /**\n * Lazy factory function for creating entity methods.\n * Evaluated once during reifyShape() and cached in _methods.\n */\n public _methodsFactory: (() => EntityMethods) | undefined = undefined;\n\n /**\n * Cached methods object from evaluating _methodsFactory.\n * Populated during reifyShape() - the same methods object is shared across all proxies,\n * but each proxy binds its own reactive method wrappers.\n */\n public _methods: EntityMethods | undefined = undefined;\n\n /**\n * Entity configuration including stream options.\n */\n public _entityConfig: EntityConfig<any> | undefined = undefined;\n\n constructor(\n kind: ComplexTypeDefKind,\n mask: Mask,\n shape: TypeDef | ObjectShape | UnionTypeDefs | (() => ObjectShape) | ComplexTypeDef[] | undefined,\n values: Set<string | boolean | number> | undefined = undefined,\n ) {\n this.kind = kind;\n this.mask = mask;\n this._shape = shape;\n this.values = values;\n }\n\n static cloneWith(\n def: ValidatorDef<any>,\n mask: Mask,\n values: Set<string | boolean | number> | undefined = undefined,\n ): ValidatorDef<any> {\n const newDef = new ValidatorDef(def.kind, mask | def.mask, def._shape, values);\n newDef.subEntityPaths = def.subEntityPaths;\n newDef.values = def.values;\n newDef.typenameField = def.typenameField;\n newDef.typenameValue = def.typenameValue;\n newDef.idField = def.idField;\n newDef._methodsFactory = def._methodsFactory;\n newDef._methods = def._methods;\n newDef._entityConfig = def._entityConfig;\n return newDef;\n }\n\n reifyShape() {\n if (this._shapeKey === undefined) {\n switch (this.kind) {\n case ComplexTypeDefKind.ENTITY: {\n const shape = (this._shape as () => ObjectShape)();\n this._shape = reifyObjectShape(this, shape);\n // Evaluate and cache the methods factory once during shape reification\n if (this._methodsFactory && !this._methods) {\n this._methods = this._methodsFactory();\n }\n break;\n }\n case ComplexTypeDefKind.OBJECT:\n this._shape = reifyObjectShape(this, this._shape as ObjectShape);\n break;\n case ComplexTypeDefKind.UNION:\n this._shape = reifyUnionShape(this, this._shape as ComplexTypeDef[]);\n break;\n case ComplexTypeDefKind.ARRAY:\n case ComplexTypeDefKind.RECORD:\n case ComplexTypeDefKind.PARSE_RESULT: {\n const shape = this._shape;\n\n let shapeKey;\n\n if (shape instanceof ValidatorDef) {\n shapeKey = shape.shapeKey;\n\n if (shape.mask & (Mask.ENTITY | Mask.HAS_SUB_ENTITY)) {\n this.mask |= Mask.HAS_SUB_ENTITY;\n }\n } else if (shape instanceof CaseInsensitiveSet) {\n shapeKey = hashValue(Array.from(shape));\n } else {\n shapeKey = hashValue(shape);\n }\n\n this._shapeKey = hashValue([this.kind, this.mask, this.values, shapeKey]);\n\n break;\n }\n }\n }\n }\n\n get shape(): TypeDef | ObjectShape | UnionTypeDefs | undefined {\n this.reifyShape();\n\n return this._shape as TypeDef | ObjectShape | UnionTypeDefs | undefined;\n }\n\n get methods(): EntityMethods | undefined {\n this.reifyShape();\n\n return this._methods;\n }\n\n get shapeKey(): number {\n this.reifyShape();\n\n return this._shapeKey!;\n }\n\n set shapeKey(key: number) {\n this._shapeKey = key >>> 0;\n }\n\n get optional(): ValidatorDef<T | undefined> {\n if (this._optional === undefined) {\n this._optional = ValidatorDef.cloneWith(this, Mask.UNDEFINED);\n }\n return this._optional;\n }\n\n get nullable(): ValidatorDef<T | null> {\n if (this._nullable === undefined) {\n this._nullable = ValidatorDef.cloneWith(this, Mask.NULL);\n }\n return this._nullable;\n }\n\n get nullish(): ValidatorDef<T | null | undefined> {\n if (this._nullish === undefined) {\n this._nullish = ValidatorDef.cloneWith(this, Mask.UNDEFINED | Mask.NULL);\n }\n return this._nullish;\n }\n\n /**\n * Creates a new ValidatorDef that extends this one with additional fields and optional methods.\n * Only valid for ENTITY and OBJECT types.\n * Prevents overriding of existing fields including id and typename.\n *\n * For entities, accepts a function that returns the new fields (lazy reification).\n * For objects, accepts the new fields directly.\n *\n * @param newFieldsOrGetter - New fields to add (lazy function for entities, direct object for objects)\n * @param newMethodsGetter - Optional lazy factory returning new methods to add (entities only, merged with existing)\n */\n extend<U extends ObjectShape, N extends EntityMethods = EntityMethods>(\n newFieldsOrGetter: U | (() => U),\n // Note: ThisType here will be the extended entity type - TypeScript infers it from context\n newMethodsGetter?: () => N,\n ): ValidatorDef<any> {\n // Validate that this is an extendable type (ENTITY or OBJECT)\n if (this.kind !== ComplexTypeDefKind.ENTITY && this.kind !== ComplexTypeDefKind.OBJECT) {\n throw new Error('extend() can only be called on Entity or Object types');\n }\n\n if (this.kind === ComplexTypeDefKind.ENTITY) {\n // For entities, keep the shape lazy - only reify on first usage\n // This preserves the lazy evaluation pattern and supports circular references\n // We bind getParentShape to access the parent's `.shape` getter which properly\n // reifies and caches the shape, avoiding multiple reification calls\n const newFieldsGetter = newFieldsOrGetter as () => U;\n const parentMethodsFactory = this._methodsFactory;\n\n const extendedDef = new ValidatorDef(ComplexTypeDefKind.ENTITY, this.mask, () => {\n const existingShape = this.shape as ObjectShape;\n const newFields = newFieldsGetter();\n\n // Runtime validation: check for field conflicts\n for (const key of Object.keys(newFields)) {\n if (key in existingShape) {\n throw new Error(`Cannot extend: field '${key}' already exists in type definition`);\n }\n }\n\n return { ...existingShape, ...newFields };\n });\n\n // Merge methods factories if either parent or new methods exist\n if (parentMethodsFactory || newMethodsGetter) {\n extendedDef._methodsFactory = () => {\n const parentMethods = parentMethodsFactory ? parentMethodsFactory() : {};\n const newMethods = newMethodsGetter ? newMethodsGetter() : {};\n return { ...parentMethods, ...newMethods } as EntityMethods;\n };\n }\n\n // Preserve entity config from parent\n extendedDef._entityConfig = this._entityConfig;\n\n return extendedDef;\n } else {\n // For objects, reify immediately since they're not lazy\n this.reifyShape();\n\n const existingShape = this._shape as ObjectShape;\n const newFields = newFieldsOrGetter as U;\n\n // Runtime validation: check for field conflicts\n for (const key of Object.keys(newFields)) {\n if (key in existingShape) {\n throw new Error(`Cannot extend: field '${key}' already exists in type definition`);\n }\n }\n\n return new ValidatorDef(ComplexTypeDefKind.OBJECT, this.mask, { ...existingShape, ...newFields });\n }\n }\n}\n\n// -----------------------------------------------------------------------------\n// Case-Insensitive Enum Set\n// -----------------------------------------------------------------------------\n\n/**\n * A Set-like class for enum values that matches string values case-insensitively.\n * Non-string values (numbers, booleans) are matched exactly.\n * Returns the canonical (originally defined) casing when a match is found.\n */\nexport class CaseInsensitiveSet<T extends string | boolean | number> extends Set<T> {\n private readonly lowercaseMap: Map<string, T>; // lowercase -> canonical (strings only)\n\n constructor(values: readonly T[]) {\n super(values);\n\n this.lowercaseMap = new Map<string, T>();\n\n for (const value of values) {\n if (typeof value === 'string') {\n const lowercase = value.toLowerCase();\n const existing = this.lowercaseMap.get(lowercase);\n\n if (existing !== undefined) {\n throw new Error(\n `Case-insensitive enum cannot have multiple values with the same lowercase form: '${existing}' and '${value}' both become '${lowercase}'`,\n );\n }\n\n this.lowercaseMap.set(lowercase, value);\n }\n }\n }\n\n /**\n * Check if a value exists in the set (case-insensitively for strings).\n * Used for backwards compatibility with Set-based checks.\n */\n has(value: unknown): boolean {\n return this.get(value) !== undefined;\n }\n\n /**\n * Get the canonical value for a given input.\n * For strings, performs case-insensitive lookup and returns the canonical casing.\n * For numbers/booleans, performs exact match.\n * Returns undefined if no match is found.\n */\n get(value: unknown): T | undefined {\n if (typeof value === 'string') {\n return this.lowercaseMap.get(value.toLowerCase());\n }\n\n if (super.has(value as T)) {\n return value as T;\n }\n\n return undefined;\n }\n}\n\n// -----------------------------------------------------------------------------\n// Complex Type Definitions\n// -----------------------------------------------------------------------------\n\nexport function defineArray<T extends TypeDef>(shape: T): ArrayDef<T> {\n return new ValidatorDef(ComplexTypeDefKind.ARRAY, Mask.ARRAY, shape) as unknown as ArrayDef<T>;\n}\n\nexport function defineRecord<T extends TypeDef>(shape: T): RecordDef<T> {\n return new ValidatorDef(ComplexTypeDefKind.RECORD, Mask.RECORD | Mask.OBJECT, shape) as unknown as RecordDef<T>;\n}\n\nexport function defineParseResult<T extends TypeDef>(innerType: T): ParseResultDef<T> {\n return new ValidatorDef(\n ComplexTypeDefKind.PARSE_RESULT,\n Mask.PARSE_RESULT,\n innerType,\n ) as unknown as ParseResultDef<T>;\n}\n\nexport function defineObject<T extends ObjectShape>(shape: T): ObjectDef<T> {\n return new ValidatorDef(ComplexTypeDefKind.OBJECT, Mask.OBJECT, shape) as unknown as ObjectDef<T>;\n}\n\nfunction defineUnion<T extends readonly TypeDef[]>(...types: T): UnionDef<T> {\n let mask = 0;\n let definition: ComplexTypeDef | undefined;\n let shape: ComplexTypeDef[] | undefined;\n let values: Set<string | boolean | number> | undefined;\n\n for (const type of types) {\n if (typeof type === 'number') {\n mask |= type;\n continue;\n }\n\n if (type instanceof Set) {\n if (values === undefined) {\n values = new Set(type);\n } else {\n for (const val of type) {\n values.add(val);\n }\n }\n\n continue;\n }\n\n if (definition === undefined) {\n definition = type;\n continue;\n }\n\n if (shape === undefined) {\n shape = [definition];\n }\n\n shape.push(type);\n }\n\n if (definition === undefined) {\n // It was a union of primitives, so return the mask\n if (values === undefined) {\n // This type coercion is incorrect, but we can't return the mask as a Mask\n // because that loses the type information about the union, which breaks\n // inference.\n //\n // TODO: Figure out how to make this correct type-wise\n return mask as unknown as UnionDef<T>;\n }\n\n // It was a union of enums/constants, so return the value as a Set\n if (mask === 0) {\n // This type coercion is incorrect, but we can't return the mask as a Mask\n // because that loses the type information about the union, which breaks\n // inference.\n //\n // TODO: Figure out how to make this correct type-wise\n\n return values as unknown as UnionDef<T>;\n }\n\n // It was a union of primitives and enums, so return the mask and values as a new ValidatorDef\n return new ValidatorDef(ComplexTypeDefKind.PRIMITIVE_UNION, mask | Mask.UNION, undefined, values) as UnionDef;\n }\n\n // It was a single complex type, so return the clone with the new mask and values\n if (shape === undefined) {\n return ValidatorDef.cloneWith(definition as ValidatorDef<any>, mask | Mask.UNION, values) as UnionDef<T>;\n }\n\n return new ValidatorDef(ComplexTypeDefKind.UNION, mask | Mask.UNION, shape, values) as UnionDef;\n}\n\nfunction defineNullish<T extends TypeDef>(type: T): T | Mask.UNDEFINED | Mask.NULL {\n if (typeof type === 'number') {\n return (type | Mask.UNDEFINED | Mask.NULL) as T | Mask.UNDEFINED | Mask.NULL;\n }\n\n if (type instanceof Set) {\n return defineUnion(type, Mask.UNDEFINED, Mask.NULL) as T | Mask.UNDEFINED | Mask.NULL;\n }\n\n // Complex type - use the cached property\n return type.nullish as T | Mask.UNDEFINED | Mask.NULL;\n}\n\nfunction defineOptional<T extends TypeDef>(type: T): T | Mask.UNDEFINED {\n if (typeof type === 'number') {\n return (type | Mask.UNDEFINED) as T | Mask.UNDEFINED;\n }\n\n if (type instanceof Set) {\n return defineUnion(type, Mask.UNDEFINED) as T | Mask.UNDEFINED;\n }\n\n // Complex type - use the cached property\n return type.optional as T | Mask.UNDEFINED;\n}\n\nfunction defineNullable<T extends TypeDef>(type: T): T | Mask.NULL {\n if (typeof type === 'number') {\n return (type | Mask.NULL) as T | Mask.NULL;\n }\n\n if (type instanceof Set) {\n return defineUnion(type, Mask.NULL) as T | Mask.NULL;\n }\n\n // Complex type - use the cached property\n return type.nullable as T | Mask.NULL;\n}\n\n// -----------------------------------------------------------------------------\n// Shape Reification\n// -----------------------------------------------------------------------------\n\nexport function reifyObjectShape(def: ValidatorDef<any>, shape: ObjectShape): ObjectShape {\n // create a hash of the shape, starting with the object mask as the base\n let shapeKey = hashValue([def.mask, def.values]);\n\n for (const [key, value] of entries(shape)) {\n switch (typeof value) {\n case 'number':\n if ((value & Mask.ID) !== 0) {\n if (def.idField !== undefined) {\n throw new Error(`Duplicate id field: ${key}`);\n }\n\n def.idField = key;\n }\n\n // Add to shape key (order independent operation)\n shapeKey += hashValue(key) ^ value;\n break;\n case 'string':\n // This is a typename field (plain string value)\n if (def.typenameField !== undefined && def.typenameField !== key) {\n throw new Error(`Duplicate typename field: ${key}`);\n }\n\n def.typenameField = key;\n def.typenameValue = value;\n\n // Add to shape key (order independent operation)\n shapeKey += hashValue(key) ^ hashValue(value);\n break;\n case 'object':\n if (value instanceof CaseInsensitiveSet) {\n shapeKey ^= hashValue(key) ^ hashValue(Array.from(value));\n break;\n }\n\n if (value instanceof Set) {\n shapeKey ^= hashValue(key) ^ hashValue(value);\n break;\n }\n\n // Add to shape key (order independent operation)\n shapeKey += hashValue(key) ^ value.shapeKey;\n\n if (value.mask & (Mask.ENTITY | Mask.HAS_SUB_ENTITY)) {\n def.mask |= Mask.HAS_SUB_ENTITY;\n if (def.subEntityPaths === undefined) {\n def.subEntityPaths = key;\n } else if (isArray(def.subEntityPaths)) {\n def.subEntityPaths.push(key);\n } else {\n def.subEntityPaths = [def.subEntityPaths, key];\n }\n }\n break;\n }\n }\n\n // Convert to unsigned 32-bit integer\n def.shapeKey = shapeKey >>> 0;\n\n return shape;\n}\n\nfunction reifyUnionShape(def: ValidatorDef<any>, defs: ComplexTypeDef[]): UnionTypeDefs {\n let mask = def.mask;\n\n let shape: UnionTypeDefs = Object.create(null);\n let unionTypenameField: string | undefined;\n\n // Start with the union mask and any values as the base\n let shapeKey = hashValue([mask, def.values]);\n\n for (const nestedDef of defs) {\n const nestedMask = nestedDef.mask;\n\n mask |= nestedMask;\n\n // load the shape key and also reify the shape if not yet reified\n shapeKey += nestedDef.shapeKey;\n\n if ((nestedMask & Mask.UNION) !== 0) {\n // Merge nested union into parent union\n const nestedUnion = nestedDef as UnionDef;\n\n // Check typename field consistency\n if (nestedUnion.typenameField !== undefined) {\n if (unionTypenameField !== undefined && unionTypenameField !== nestedUnion.typenameField) {\n throw new Error(\n `Union typename field conflict: Cannot merge unions with different typename fields ('${unionTypenameField}' vs '${nestedUnion.typenameField}')`,\n );\n }\n unionTypenameField = nestedUnion.typenameField;\n }\n\n const nestedShape = nestedUnion.shape;\n\n // Merge nested union's shape into parent\n if (nestedShape !== undefined) {\n for (const key of [...Object.keys(nestedShape), ARRAY_KEY, RECORD_KEY] as const) {\n // Check for conflicts\n const value = nestedShape[key];\n\n if (shape[key] !== undefined && shape[key] !== value) {\n throw new Error(\n `Union merge conflict: Duplicate typename value '${String(key)}' found when merging nested unions (${String(shape[key])} vs ${String(value)})`,\n );\n }\n\n // coerce type because we know the value is the same type as the key\n shape[key] = value as any;\n }\n }\n } else if ((nestedMask & Mask.ARRAY) !== 0) {\n if (shape[ARRAY_KEY] !== undefined) {\n throw new Error('Array shape already defined');\n }\n\n shape[ARRAY_KEY] = nestedDef.shape as TypeDef;\n } else if ((nestedMask & Mask.RECORD) !== 0) {\n if (shape[RECORD_KEY] !== undefined) {\n throw new Error('Record shape already defined');\n }\n\n shape[RECORD_KEY] = nestedDef.shape as TypeDef;\n } else {\n // definition is ObjectDef | EntityDef\n const typenameField = (nestedDef as ObjectDef).typenameField;\n const typename = (nestedDef as ObjectDef).typenameValue;\n\n if (typename === undefined) {\n throw new Error(\n 'Object definitions must have a typename to be in a union with other objects, records, or arrays',\n );\n }\n\n if (unionTypenameField !== undefined && typenameField !== unionTypenameField) {\n throw new Error('Object definitions must have the same typename field to be in the same union');\n }\n\n unionTypenameField = typenameField;\n shape[typename] = nestedDef as ObjectDef;\n }\n }\n\n def.typenameField = unionTypenameField;\n def.shapeKey = shapeKey >>> 0;\n def.mask = mask;\n\n return shape;\n}\n\n// -----------------------------------------------------------------------------\n// Marker Functions\n// -----------------------------------------------------------------------------\n\nfunction defineTypename<T extends string>(value: T): T {\n return value;\n}\n\nfunction defineConst<T extends string | boolean | number>(value: T): Set<T> {\n return new Set([value]);\n}\n\nconst defineEnum = (<T extends readonly (string | boolean | number)[]>(...values: T): Set<T[number]> => {\n return new Set(values as unknown as T[number][]);\n}) as unknown as APITypes['enum'];\n\ndefineEnum.caseInsensitive = <T extends readonly (string | boolean | number)[]>(\n ...values: T\n): CaseInsensitiveSet<T[number]> => {\n return new CaseInsensitiveSet(values as unknown as T[number][]);\n};\n\n// -----------------------------------------------------------------------------\n// Formatted Values\n// -----------------------------------------------------------------------------\n\nconst FORMAT_MASK_SHIFT = 16;\n\nlet nextFormatId = 0;\nconst FORMAT_PARSERS: ((value: unknown) => unknown)[] = [];\nconst FORMAT_SERIALIZERS: ((value: unknown) => unknown)[] = [];\nconst FORMAT_MAP = new Map<string, number>();\nconst FORMAT_ID_TO_NAME = new Map<number, string>();\n\nfunction defineFormatted<K extends keyof SignaliumQuery.FormatRegistry>(\n format: K,\n): Formatted<SignaliumQuery.FormatRegistry[K]> {\n const mask = FORMAT_MAP.get(format);\n\n if (mask === undefined) {\n throw new Error(`Format ${format} not registered`);\n }\n\n return mask as Formatted<SignaliumQuery.FormatRegistry[K]>;\n}\n\nexport function getFormat(mask: number): (value: unknown) => unknown {\n const formatId = mask >> FORMAT_MASK_SHIFT;\n\n return FORMAT_PARSERS[formatId];\n}\n\nexport function getFormatSerializer(mask: number): ((value: unknown) => unknown) | undefined {\n const formatId = mask >> FORMAT_MASK_SHIFT;\n return FORMAT_SERIALIZERS[formatId];\n}\n\nexport function getFormatName(mask: number): string | undefined {\n const formatId = mask >> FORMAT_MASK_SHIFT;\n return FORMAT_ID_TO_NAME.get(formatId);\n}\n\nexport function registerFormat<Input extends Mask.STRING | Mask.NUMBER, T>(\n name: string,\n type: Input,\n parse: (value: Input extends Mask.STRING ? string : number) => T,\n serialize: (value: T) => Input extends Mask.STRING ? string : number,\n) {\n const maskId = nextFormatId++;\n FORMAT_PARSERS[maskId] = parse as (value: unknown) => unknown;\n FORMAT_SERIALIZERS[maskId] = serialize as (value: unknown) => unknown;\n FORMAT_ID_TO_NAME.set(maskId, name);\n\n const shiftedId = maskId << FORMAT_MASK_SHIFT;\n const formatMask = type === Mask.STRING ? Mask.HAS_STRING_FORMAT : Mask.HAS_NUMBER_FORMAT;\n const mask = shiftedId | type | formatMask;\n\n FORMAT_MAP.set(name, mask);\n}\n\n// -----------------------------------------------------------------------------\n// Built-in Formats\n// -----------------------------------------------------------------------------\n\n// Register 'date' format: ISO date string (YYYY-MM-DD) ↔ Date\nregisterFormat(\n 'date',\n Mask.STRING,\n value => {\n // Parse YYYY-MM-DD as UTC date to avoid timezone issues\n const match = value.match(/^(\\d{4})-(\\d{2})-(\\d{2})$/);\n if (!match) {\n throw new Error(`Invalid date string: ${value}. Expected YYYY-MM-DD format.`);\n }\n const [, year, month, day] = match;\n const date = new Date(Date.UTC(parseInt(year, 10), parseInt(month, 10) - 1, parseInt(day, 10)));\n if (isNaN(date.getTime())) {\n throw new Error(`Invalid date string: ${value}`);\n }\n return date;\n },\n value => {\n // Format as YYYY-MM-DD using UTC to avoid timezone issues\n const year = value.getUTCFullYear();\n const month = String(value.getUTCMonth() + 1).padStart(2, '0');\n const day = String(value.getUTCDate()).padStart(2, '0');\n return `${year}-${month}-${day}`;\n },\n);\n\n// Register 'date-time' format: ISO datetime string (ISO 8601) ↔ Date\nregisterFormat(\n 'date-time',\n Mask.STRING,\n value => {\n const date = new Date(value);\n if (isNaN(date.getTime())) {\n throw new Error(`Invalid date-time string: ${value}`);\n }\n return date;\n },\n value => {\n // Format as ISO 8601 string\n return value.toISOString();\n },\n);\n\n// -----------------------------------------------------------------------------\n// Entity Definitions\n// -----------------------------------------------------------------------------\n\n/**\n * Creates an entity definition with optional methods.\n *\n * @param shape - Lazy factory function that returns the entity's field definitions\n * @param methods - Optional lazy factory function that returns methods for the entity.\n * Methods have access to `this` typed as the reified entity shape.\n * Methods are wrapped with reactiveMethod for automatic caching.\n *\n * @example\n * const User = entity(\n * () => ({\n * __typename: t.typename('User'),\n * id: t.id,\n * name: t.string,\n * age: t.number,\n * }),\n * () => ({\n * greet() {\n * return `Hello, ${this.name}!`;\n * },\n * isAdult() {\n * return this.age >= 18;\n * },\n * })\n * );\n */\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\nexport function entity<T extends ObjectShape, M extends EntityMethods = {}>(\n shape: () => T,\n methods?: () => M & ThisType<M & Prettify<ExtractTypesFromShape<T>>>,\n config?: EntityConfig<T>,\n): EntityDef<T, M> {\n const def = new ValidatorDef(\n ComplexTypeDefKind.ENTITY,\n // The mask should be OBJECT | ENTITY so that values match when compared\n Mask.ENTITY | Mask.OBJECT,\n shape,\n );\n\n if (methods) {\n def._methodsFactory = methods as () => EntityMethods;\n }\n\n if (config) {\n // `any` because of infinite recursive type issue\n (def as any)._entityConfig = config;\n }\n\n return def as unknown as EntityDef<T, M>;\n}\n\nexport const t: APITypes = {\n format: defineFormatted,\n typename: defineTypename,\n const: defineConst,\n enum: defineEnum,\n id: Mask.ID | Mask.STRING | Mask.NUMBER,\n string: Mask.STRING,\n number: Mask.NUMBER,\n boolean: Mask.BOOLEAN,\n null: Mask.NULL,\n undefined: Mask.UNDEFINED,\n array: defineArray,\n object: defineObject,\n record: defineRecord,\n union: defineUnion,\n nullish: defineNullish,\n optional: defineOptional,\n nullable: defineNullable,\n result: defineParseResult,\n};\n","import {\n ARRAY_KEY,\n ArrayDef,\n EntityDef,\n Mask,\n ObjectDef,\n RECORD_KEY,\n RecordDef,\n ObjectFieldTypeDef,\n UnionDef,\n} from './types.js';\nimport { CaseInsensitiveSet, getFormatName } from './typeDefs.js';\n\nexport function typeToString(type: ObjectFieldTypeDef): string {\n // Handle case-insensitive enum sets\n if (type instanceof CaseInsensitiveSet) {\n const values = Array.from(type).map(v => (typeof v === 'string' ? `\"${v}\"` : String(v)));\n return values.join(' | ');\n }\n\n // Handle Set-based constants/enums\n if (type instanceof Set) {\n const values = Array.from(type).map(v => (typeof v === 'string' ? `\"${v}\"` : String(v)));\n return values.join(' | ');\n }\n\n // Handle constants\n if (typeof type === 'string') {\n return `\"${type}\"`;\n }\n\n if (typeof type === 'boolean') {\n return String(type);\n }\n\n // Handle primitive masks\n if (typeof type === 'number') {\n // Check for formatted types first\n const hasFormat = (type & (Mask.HAS_STRING_FORMAT | Mask.HAS_NUMBER_FORMAT)) !== 0;\n if (hasFormat) {\n const formatName = getFormatName(type);\n if (formatName) {\n // Show format name instead of base type\n return `\"${formatName}\"`;\n }\n }\n\n const types: string[] = [];\n\n if (type & Mask.UNDEFINED) types.push('undefined');\n if (type & Mask.NULL) types.push('null');\n if (type & Mask.NUMBER) types.push('number');\n if (type & Mask.STRING) types.push('string');\n if (type & Mask.BOOLEAN) types.push('boolean');\n if (type & Mask.OBJECT) types.push('object');\n if (type & Mask.ARRAY) types.push('array');\n\n if (types.length === 0) {\n return 'unknown';\n }\n\n return types.length === 1 ? types[0] : types.join(' | ');\n }\n\n // Handle complex types - CHECK UNION FIRST since it contains other types\n let mask = type.mask;\n\n if (mask & Mask.UNION) {\n const unionType = type as UnionDef;\n const parts: string[] = [];\n\n // Add const/enum values from the values Set\n if (unionType.values !== undefined && unionType.values.size > 0) {\n for (const val of unionType.values) {\n const valStr = typeof val === 'string' ? `\"${val}\"` : String(val);\n parts.push(valStr);\n }\n }\n\n // Add complex types from the shape object\n if (unionType.shape !== undefined) {\n if (unionType.shape[ARRAY_KEY] !== undefined) {\n parts.push(`Array<${typeToString(unionType.shape[ARRAY_KEY] as ObjectFieldTypeDef)}>`);\n }\n\n if (unionType.shape[RECORD_KEY] !== undefined) {\n parts.push(`Record<string, ${typeToString(unionType.shape[RECORD_KEY] as ObjectFieldTypeDef)}>`);\n }\n\n // Add entity/object types by typename\n for (const [key, value] of Object.entries(unionType.shape)) {\n if (key !== (ARRAY_KEY as any) && key !== (RECORD_KEY as any)) {\n // key is the typename value (e.g., \"User\", \"Post\")\n parts.push(key);\n }\n }\n }\n\n mask = unionType.mask;\n\n // Check for formatted types in union mask\n const hasFormat = (mask & (Mask.HAS_STRING_FORMAT | Mask.HAS_NUMBER_FORMAT)) !== 0;\n if (hasFormat) {\n const formatName = getFormatName(mask);\n if (formatName) {\n parts.push(`\"${formatName}\"`);\n }\n }\n\n // Add primitive types from the mask\n if (mask & Mask.UNDEFINED) parts.push('undefined');\n if (mask & Mask.NULL) parts.push('null');\n if (mask & Mask.NUMBER) parts.push('number');\n if (mask & Mask.STRING) parts.push('string');\n if (mask & Mask.BOOLEAN) parts.push('boolean');\n\n if (parts.length === 0) {\n return 'union';\n }\n\n return parts.join(' | ');\n }\n\n if (mask & Mask.ENTITY) {\n return `Entity<${(type as EntityDef).typenameValue}>`;\n }\n\n if (mask & Mask.ARRAY) {\n const shape = (type as ArrayDef).shape;\n return `Array<${typeToString(shape)}>`;\n }\n\n if (mask & Mask.RECORD) {\n const shape = (type as RecordDef).shape;\n return `Record<string, ${typeToString(shape)}>`;\n }\n\n if (mask & Mask.OBJECT) {\n const typename = (type as ObjectDef).typenameValue;\n return typename ? `Object<${typename}>` : 'object';\n }\n\n return 'unknown';\n}\n\nexport function typeError(path: string, expectedType: ObjectFieldTypeDef, value: unknown): Error {\n return new TypeError(\n `Validation error at ${path}: expected ${typeToString(expectedType)}, got ${\n typeof value === 'object' ? (value === null ? 'null' : Array.isArray(value) ? 'array' : 'object') : typeof value\n }`,\n );\n}\n","import { Mask } from './types.js';\n\nconst isArray = Array.isArray;\n\nexport function typeMaskOf(value: unknown): Mask {\n if (value === null) return Mask.NULL;\n\n switch (typeof value) {\n case 'number':\n return Mask.NUMBER;\n case 'string':\n return Mask.STRING;\n case 'boolean':\n return Mask.BOOLEAN;\n case 'undefined':\n return Mask.UNDEFINED;\n case 'object':\n return isArray(value) ? Mask.ARRAY : Mask.OBJECT;\n default:\n throw new Error(`Invalid type: ${typeof value}`);\n }\n}\n\n// ================================\n// Draft Helper Types\n// ================================\n\n/**\n * Recursively makes all properties of T mutable (removes readonly).\n * This is the return type of the draft() function.\n */\nexport type Draft<T> = T extends readonly (infer U)[]\n ? Draft<U>[]\n : T extends Date\n ? Date\n : T extends Map<infer K, infer V>\n ? Map<Draft<K>, Draft<V>>\n : T extends Set<infer U>\n ? Set<Draft<U>>\n : T extends object\n ? { -readonly [K in keyof T]: Draft<T[K]> }\n : T;\n\n/**\n * Deep clones an entity or object, returning a plain mutable copy.\n * This is useful for creating a \"draft\" version of an entity that can be modified\n * before being passed to a mutation.\n *\n * The draft is a plain JavaScript object (not an entity proxy), so:\n * - All fields are mutable via property assignment\n * - Changes don't affect the original entity\n * - When passed to a mutation, it's serialized as a normal object\n *\n * @example\n * ```ts\n * // Get an entity from a query\n * const user = await getUser({ id: '123' });\n *\n * // Create a draft to modify\n * const updatedUser = draft(user);\n * updatedUser.name = 'New Name';\n * updatedUser.email = 'new@example.com';\n *\n * // Pass to mutation\n * await updateUser().run(updatedUser);\n * ```\n *\n * @param entity - The entity or object to clone\n * @returns A deep clone of the entity as a plain mutable object\n */\nexport function draft<T>(entity: T): Draft<T> {\n return deepClone(entity) as Draft<T>;\n}\n\n/**\n * Deep clones a value, handling objects, arrays, and primitives.\n * Entity proxies are converted to plain objects by reading all enumerable properties.\n */\nfunction deepClone<T>(value: T): T {\n // Handle null and primitives\n if (value === null || typeof value !== 'object') {\n return value;\n }\n\n // Handle arrays\n if (isArray(value)) {\n return value.map(item => deepClone(item)) as T;\n }\n\n // Handle Date objects\n if (value instanceof Date) {\n return new Date(value.getTime()) as T;\n }\n\n // Handle Map\n if (value instanceof Map) {\n const clonedMap = new Map();\n for (const [k, v] of value) {\n clonedMap.set(deepClone(k), deepClone(v));\n }\n return clonedMap as T;\n }\n\n // Handle Set\n if (value instanceof Set) {\n const clonedSet = new Set();\n for (const v of value) {\n clonedSet.add(deepClone(v));\n }\n return clonedSet as T;\n }\n\n // Handle plain objects (including entity proxies)\n // For entity proxies, reading properties will extract the underlying data\n const result: Record<string, unknown> = {};\n\n // Get all enumerable own properties (works for both plain objects and proxies)\n for (const key of Object.keys(value as object)) {\n result[key] = deepClone((value as Record<string, unknown>)[key]);\n }\n\n return result as T;\n}\n","import { reactiveMethod, setScopeOwner } from 'signalium';\nimport { typeError } from './errors.js';\nimport { CaseInsensitiveSet, getFormat, ValidatorDef } from './typeDefs.js';\nimport {\n ARRAY_KEY,\n ComplexTypeDef,\n EntityDef,\n Mask,\n ObjectDef,\n RECORD_KEY,\n ObjectFieldTypeDef,\n UnionDef,\n TypeDef,\n RecordDef,\n} from './types.js';\nimport { typeMaskOf } from './utils.js';\nimport { PreloadedEntityRecord } from './EntityMap.js';\n\nexport type WarnFn = (message: string, context?: Record<string, unknown>) => void;\nconst noopWarn: WarnFn = () => {};\n\nconst entries = Object.entries;\nconst isArray = Array.isArray;\n\nconst PROXY_ID = new WeakMap();\n\n// Placeholder class used as the prototype for entity proxies.\n// This prevents them from being treated as plain objects in utilities like `hashValue()`.\nexport class Entity {}\n\nfunction parseUnionValue(\n valueType: number,\n value: Record<string, unknown> | unknown[],\n unionDef: UnionDef,\n path: string,\n warn: WarnFn = noopWarn,\n): unknown {\n if (valueType === Mask.ARRAY) {\n const shape = unionDef.shape![ARRAY_KEY];\n\n if (shape === undefined || typeof shape === 'number') {\n return value;\n }\n\n return parseArrayValue(value as unknown[], shape, path, warn);\n } else {\n // Use the cached typename field from the union definition\n const typenameField = unionDef.typenameField;\n const typename = typenameField ? (value as Record<string, unknown>)[typenameField] : undefined;\n\n if (typename === undefined || typeof typename !== 'string') {\n const recordShape = unionDef.shape![RECORD_KEY];\n\n if (recordShape === undefined || typeof recordShape === 'number') {\n // Union of objects/entities requires typename for discrimination\n throw new Error(\n `Typename field '${typenameField}' is required for union discrimination but was not found in the data`,\n );\n }\n\n return parseRecordValue(value as Record<string, unknown>, recordShape as ComplexTypeDef, path, warn);\n }\n\n const matchingDef = unionDef.shape![typename];\n\n if (matchingDef === undefined || typeof matchingDef === 'number') {\n throw new Error(`Unknown typename '${typename}' in union`);\n }\n\n return parseObjectValue(value as Record<string, unknown>, matchingDef as ObjectDef | EntityDef, path, warn);\n }\n}\n\nexport function parseArrayValue(array: unknown[], arrayShape: TypeDef, path: string, warn: WarnFn = noopWarn) {\n const result: unknown[] = [];\n\n for (let i = 0; i < array.length; i++) {\n try {\n result.push(parseValue(array[i], arrayShape, `${path}[${i}]`, false, warn));\n } catch (e) {\n warn('Failed to parse array item, filtering out', {\n index: i,\n value: array[i],\n error: e instanceof Error ? e.message : String(e),\n });\n }\n }\n\n return result;\n}\n\nexport function parseRecordValue(\n record: Record<string, unknown>,\n recordShape: ObjectFieldTypeDef,\n path: string,\n warn: WarnFn = noopWarn,\n) {\n for (const [key, value] of entries(record)) {\n record[key] = parseValue(value, recordShape, `${path}[\"${key}\"]`, false, warn);\n }\n\n return record;\n}\n\nexport function parseObjectValue(\n object: Record<string, unknown>,\n objectShape: ObjectDef | EntityDef,\n path: string,\n warn: WarnFn = noopWarn,\n) {\n if (PROXY_ID.has(object)) {\n // Is an entity proxy, so return it directly\n return object;\n }\n\n const shape = objectShape.shape;\n\n for (const [key, propShape] of entries(shape)) {\n // parse and replace the property in place\n object[key] = parseValue(object[key], propShape, `${path}.${key}`, false, warn);\n }\n\n return object;\n}\n\nexport function parseValue(\n value: unknown,\n propDef: ObjectFieldTypeDef,\n path: string,\n skipFallbacks = false,\n warn: WarnFn = noopWarn,\n): unknown {\n // Handle case-insensitive enums\n if (propDef instanceof CaseInsensitiveSet) {\n const canonical = propDef.get(value);\n if (canonical === undefined) {\n throw typeError(path, propDef as any, value);\n }\n return canonical; // Return the canonical casing\n }\n\n // Handle Set-based constants/enums\n if (propDef instanceof Set) {\n if (!propDef.has(value as string | boolean | number)) {\n throw typeError(path, propDef as any, value);\n }\n return value;\n }\n\n switch (typeof propDef) {\n case 'string':\n // If value is undefined/null, return the typename from definition\n if (value === undefined || value === null) {\n return propDef;\n }\n if (value !== propDef) {\n throw typeError(path, propDef, value);\n }\n\n return value;\n\n // handle primitives\n case 'number': {\n let valueType = typeMaskOf(value);\n\n if ((propDef & valueType) === 0) {\n if (!skipFallbacks && (propDef & Mask.UNDEFINED) !== 0) {\n warn('Invalid value for optional type, defaulting to undefined', { value, path });\n return undefined;\n }\n throw typeError(path, propDef, value);\n }\n\n // Check if this field has a format - if so, parse with the format parser\n if ((propDef & (Mask.HAS_STRING_FORMAT | Mask.HAS_NUMBER_FORMAT)) !== 0) {\n // Lazy format parsing: parse the raw value using the format parser\n try {\n return getFormat(propDef)(value);\n } catch (e) {\n if (!skipFallbacks && (propDef & Mask.UNDEFINED) !== 0) {\n warn('Invalid formatted value for optional type, defaulting to undefined', {\n value,\n path,\n error: e instanceof Error ? e.message : String(e),\n });\n return undefined;\n }\n throw e;\n }\n }\n\n return value;\n }\n\n // handle complex objects\n default: {\n // Note: Keep in mind that at this point, we're using `valueType`\n // primarily, so some of the logic is \"reversed\" from the above where\n // we use the `propDef` type primarily\n let valueType = typeMaskOf(value);\n const propMask = propDef.mask;\n\n // Handle parseResult wrapper - wraps parsing in try-catch and returns discriminated union\n // Pass skipFallbacks=true so errors are thrown instead of defaulting to undefined\n if ((propMask & Mask.PARSE_RESULT) !== 0) {\n try {\n const innerResult = parseValue(value, propDef.shape as ObjectFieldTypeDef, path, true, warn);\n return { success: true as const, value: innerResult };\n } catch (e) {\n return { success: false as const, error: e instanceof Error ? e : new Error(String(e)) };\n }\n }\n\n // Check if the value type is allowed by the propMask\n // Also check if it's in a values set (for enums/constants stored in ValidatorDef)\n if ((propMask & valueType) === 0 && !propDef.values?.has(value as string | boolean | number)) {\n if (!skipFallbacks && (propMask & Mask.UNDEFINED) !== 0) {\n warn('Invalid value for optional type, defaulting to undefined', { value, path });\n return undefined;\n }\n throw typeError(path, propMask, value);\n }\n\n if (valueType < Mask.OBJECT) {\n // Check if this field has a format - if so, parse with the format parser\n if ((propMask & (Mask.HAS_STRING_FORMAT | Mask.HAS_NUMBER_FORMAT)) !== 0) {\n try {\n return getFormat(propMask)(value);\n } catch (e) {\n if (!skipFallbacks && (propMask & Mask.UNDEFINED) !== 0) {\n warn('Invalid formatted value for optional type, defaulting to undefined', {\n value,\n path,\n error: e instanceof Error ? e.message : String(e),\n });\n return undefined;\n }\n throw e;\n }\n }\n\n // value is a primitive, it has already passed the mask so return it now\n return value;\n }\n\n if ((valueType & Mask.UNION) !== 0) {\n return parseUnionValue(\n valueType,\n value as Record<string, unknown> | unknown[],\n propDef as UnionDef,\n path,\n warn,\n );\n }\n\n if (valueType === Mask.ARRAY) {\n return parseArrayValue(value as unknown[], propDef.shape as ComplexTypeDef, path, warn);\n }\n\n if ((propMask & Mask.RECORD) !== 0) {\n return parseRecordValue(value as Record<string, unknown>, (propDef as RecordDef).shape, path, warn);\n }\n\n return parseObjectValue(value as Record<string, unknown>, propDef as ObjectDef | EntityDef, path, warn);\n }\n }\n}\n\n/**\n * Deep merge two objects, with the update object taking precedence.\n * Arrays are replaced, not merged.\n * Handles nested objects recursively.\n */\nexport function mergeValues<T extends Record<string, unknown>>(\n target: Record<string, unknown>,\n update: Record<string, unknown>,\n): T {\n // Iterate over update properties\n for (const [key, value] of entries(update)) {\n const targetValue = target[key];\n // Only merge if both value and targetValue are plain objects (not arrays or proxies)\n if (\n typeof value === 'object' &&\n value !== null &&\n !isArray(value) &&\n !PROXY_ID.has(value) &&\n typeof targetValue === 'object' &&\n targetValue !== null &&\n !isArray(targetValue) &&\n !PROXY_ID.has(targetValue)\n ) {\n mergeValues(targetValue as Record<string, unknown>, value as Record<string, unknown>);\n } else {\n target[key] = value;\n }\n }\n\n return target as T;\n}\n\nconst CustomNodeInspect = Symbol.for('nodejs.util.inspect.custom');\n\nexport function createEntityProxy(\n id: number,\n entityRecord: PreloadedEntityRecord,\n def: ObjectDef | EntityDef,\n entityRelay: any,\n scopeOwner: object,\n warn: WarnFn = noopWarn,\n desc?: string,\n): Record<string, unknown> {\n // Cache for nested proxies - each proxy gets its own cache\n const shape = def.shape;\n\n // Get cached methods from the definition (evaluated once during reifyShape)\n const methods = (def as ValidatorDef<unknown>).methods;\n\n // Cache for wrapped reactive methods - each proxy gets its own bound methods\n const wrappedMethods = new Map<string, (...args: unknown[]) => unknown>();\n\n const toJSON = () => ({\n __entityRef: id,\n });\n\n // We need to declare proxy first so we can reference it in the handler\n let proxy: Record<string, unknown>;\n\n const handler: ProxyHandler<object> = {\n getPrototypeOf() {\n return Entity.prototype;\n },\n\n get(target, prop) {\n // Handle toJSON for serialization\n if (prop === 'toJSON') {\n return toJSON;\n }\n\n const { data, cache, notifier } = entityRecord;\n\n // Access relay value if it exists - this will activate it when watched in reactive context\n // The relay access happens here to establish tracking when signal.value is read\n // eslint-disable-next-line @typescript-eslint/no-unused-expressions\n entityRelay?.value;\n\n notifier.consume();\n\n // Check cache first, BEFORE any expensive checks\n if (cache.has(prop)) {\n return cache.get(prop);\n }\n\n // Check for method access\n if (methods && typeof prop === 'string' && prop in methods) {\n let wrapped = wrappedMethods.get(prop);\n if (!wrapped) {\n // Create reactive method wrapper bound to the proxy\n // Bind the method to the proxy so `this` refers to the entity\n wrapped = reactiveMethod(proxy, methods[prop].bind(proxy));\n wrappedMethods.set(prop, wrapped);\n }\n return wrapped;\n }\n\n const value = data[prop as string];\n const propDef = shape[prop as string];\n\n if (!Object.hasOwnProperty.call(shape, prop)) {\n return value;\n }\n\n const parsed = parseValue(value, propDef, `[[${desc}]].${prop as string}`, false, warn);\n\n cache.set(prop, parsed);\n\n return parsed;\n },\n\n has(target, prop) {\n // Include methods in the \"in\" check\n if (methods && typeof prop === 'string' && prop in methods) {\n return true;\n }\n return prop in shape;\n },\n\n ownKeys(target) {\n const keys = Object.keys(shape);\n // Add typename field if it exists on the definition\n const typenameField = (def as ObjectDef | EntityDef).typenameField;\n if (typenameField && !keys.includes(typenameField)) {\n keys.push(typenameField);\n }\n // Add method keys\n if (methods) {\n for (const methodKey of Object.keys(methods)) {\n if (!keys.includes(methodKey)) {\n keys.push(methodKey);\n }\n }\n }\n return keys;\n },\n\n getOwnPropertyDescriptor(target, prop) {\n const typenameField = (def as ObjectDef | EntityDef).typenameField;\n if (prop in shape || prop === typenameField) {\n return {\n enumerable: true,\n configurable: true,\n };\n }\n // Methods are non-enumerable (like regular object methods)\n if (methods && typeof prop === 'string' && prop in methods) {\n return {\n enumerable: false,\n configurable: true,\n };\n }\n return undefined;\n },\n };\n\n proxy = new Proxy<Record<string, unknown>>(\n {\n [CustomNodeInspect]: () => {\n return Object.keys(shape).reduce(\n (acc, key) => {\n acc[key] = proxy[key];\n return acc;\n },\n {} as Record<string, unknown>,\n );\n },\n } as Record<string, unknown>,\n handler,\n );\n\n // Add the proxy to the proxy brand set so we can easily identify it later\n PROXY_ID.set(proxy, id);\n\n // Associate the proxy with a scope owner for reactive method caching\n setScopeOwner(proxy, scopeOwner);\n\n return proxy;\n}\n\nexport function getProxyId(object: Record<string, unknown>): number | undefined {\n return PROXY_ID.get(object);\n}\n","import { relay, DiscriminatedReactivePromise, Notifier, notifier } from 'signalium';\nimport { EntityDef } from './types.js';\nimport { createEntityProxy, mergeValues } from './proxy.js';\nimport type { QueryClient } from './QueryClient.js';\nimport { ValidatorDef } from './typeDefs.js';\n\n/**\n * Deep clone an object, handling nested objects and arrays.\n * Used for snapshotting entity data before optimistic updates.\n */\nfunction deepClone<T>(value: T): T {\n if (value === null || typeof value !== 'object') {\n return value;\n }\n\n if (Array.isArray(value)) {\n return value.map(item => deepClone(item)) as T;\n }\n\n if (value instanceof Date) {\n return new Date(value.getTime()) as T;\n }\n\n // For plain objects, create a shallow copy and recursively clone values\n const cloned = {} as Record<string, unknown>;\n for (const key of Object.keys(value)) {\n cloned[key] = deepClone((value as Record<string, unknown>)[key]);\n }\n return cloned as T;\n}\n\nexport interface PreloadedEntityRecord {\n key: number;\n data: Record<string, unknown>;\n notifier: Notifier;\n cache: Map<PropertyKey, any>;\n id?: string | number;\n proxy?: Record<string, unknown>;\n entityRefs?: Set<number>;\n}\n\nexport type EntityRecord = Required<PreloadedEntityRecord>;\n\n/**\n * Tracks pending optimistic updates for an entity.\n * Includes the snapshot of original data for rollback.\n */\ninterface PendingOptimisticUpdate {\n snapshot: Record<string, unknown>; // Original data before optimistic update\n}\n\nexport class EntityStore {\n private map = new Map<number, PreloadedEntityRecord | EntityRecord>();\n private queryClient: QueryClient;\n\n /**\n * Tracks pending optimistic updates by entity key.\n * Each entity can only have one pending update at a time (throws if concurrent).\n */\n private pendingOptimisticUpdates = new Map<number, PendingOptimisticUpdate>();\n\n constructor(queryClient: QueryClient) {\n this.queryClient = queryClient;\n }\n\n hasEntity(key: number): boolean {\n return this.map.has(key);\n }\n\n getEntity(key: number): PreloadedEntityRecord | EntityRecord | undefined {\n return this.map.get(key);\n }\n\n getNestedEntityRefIds(key: number, refIds: Set<number>): Set<number> {\n const record = this.getEntity(key);\n\n if (record === undefined) {\n throw new Error(`Entity ${key} not found when getting nested entity ref ids`);\n }\n\n refIds.add(key);\n\n // Entangle the signal value. Whenever the signal value is updated, refIds\n // will also be updated, so no need for a second signal.\n record.notifier.consume();\n\n if (record.entityRefs !== undefined) {\n for (const ref of record.entityRefs) {\n this.getNestedEntityRefIds(ref, refIds);\n }\n }\n\n return refIds;\n }\n\n hydratePreloadedEntity(key: number, shape: EntityDef): EntityRecord {\n const record = this.getEntity(key);\n if (record === undefined) {\n throw new Error(`Entity ${key} not found`);\n }\n\n record.proxy = this.createEntityProxy(record, shape);\n\n return record as EntityRecord;\n }\n\n setPreloadedEntity(key: number, data: Record<string, unknown>): PreloadedEntityRecord {\n const record: PreloadedEntityRecord = {\n key,\n data,\n notifier: notifier(),\n cache: new Map(),\n id: undefined,\n proxy: undefined,\n entityRefs: undefined,\n };\n\n this.map.set(key, record);\n\n return record;\n }\n\n setEntity(key: number, obj: Record<string, unknown>, shape: EntityDef, entityRefs?: Set<number>): EntityRecord {\n let record = this.map.get(key);\n\n if (record === undefined) {\n record = this.setPreloadedEntity(key, obj);\n\n record.proxy = this.createEntityProxy(record, shape);\n } else {\n record.data = mergeValues(record.data, obj);\n record.notifier.notify();\n record.cache.clear();\n }\n\n record.entityRefs = entityRefs;\n\n return record as EntityRecord;\n }\n\n // ======================================================\n // Optimistic Update Tracking\n // ======================================================\n\n /**\n * Register a pending optimistic update for an entity.\n * Snapshots the current state and applies the optimistic update.\n *\n * @throws Error if the entity already has a pending optimistic update\n */\n registerOptimisticUpdate(entityKey: number, fields: Record<string, unknown>): void {\n // Throw if entity already has pending optimistic updates\n if (this.pendingOptimisticUpdates.has(entityKey)) {\n throw new Error(\n `Cannot apply optimistic update: entity ${entityKey} already has a pending optimistic update from another mutation.`,\n );\n }\n\n const record = this.map.get(entityKey);\n if (!record) {\n // Entity doesn't exist yet - nothing to snapshot, just track\n this.pendingOptimisticUpdates.set(entityKey, { snapshot: {} });\n return;\n }\n\n // Deep snapshot the current data BEFORE applying the update\n const snapshot = deepClone(record.data);\n\n // Store the pending update with snapshot\n this.pendingOptimisticUpdates.set(entityKey, { snapshot });\n\n // Apply the optimistic update to the entity\n record.data = mergeValues(record.data, fields);\n record.cache.clear();\n\n // Defer notification to avoid dirtying signal within reactive context\n queueMicrotask(() => {\n record.notifier.notify();\n });\n }\n\n /**\n * Revert the optimistic update for an entity, restoring its snapshot.\n * Called when a mutation fails.\n */\n revertOptimisticUpdate(entityKey: number): void {\n const pending = this.pendingOptimisticUpdates.get(entityKey);\n if (!pending) {\n return; // No pending update to revert\n }\n\n const record = this.map.get(entityKey);\n if (record && Object.keys(pending.snapshot).length > 0) {\n // Restore the snapshot\n record.data = pending.snapshot;\n record.cache.clear();\n\n // Defer notification to avoid dirtying signal within reactive context\n queueMicrotask(() => {\n record.notifier.notify();\n });\n }\n\n // Clear the pending update\n this.pendingOptimisticUpdates.delete(entityKey);\n }\n\n /**\n * Clear the optimistic update for an entity without reverting.\n * Called when a mutation succeeds (the optimistic update is now confirmed).\n */\n clearOptimisticUpdates(entityKey: number): void {\n this.pendingOptimisticUpdates.delete(entityKey);\n }\n\n private createEntityProxy(record: PreloadedEntityRecord, shape: EntityDef): Record<string, unknown> {\n const idField = shape.idField;\n if (idField === undefined) {\n throw new Error(`Entity id field is required ${shape.typenameValue}`);\n }\n\n const id = record.data[idField];\n\n if (typeof id !== 'string' && typeof id !== 'number') {\n console.log(record.data);\n throw new Error(`Entity id must be string or number: ${shape.typenameValue}`);\n }\n\n record.id = id;\n\n let entityRelay: DiscriminatedReactivePromise<Record<string, unknown>> | undefined;\n const entityConfig = (shape as unknown as ValidatorDef<unknown>)._entityConfig;\n\n if (entityConfig?.stream) {\n entityRelay = relay(state => {\n const context = this.queryClient.getContext();\n const onUpdate = (update: Partial<Record<string, unknown>>) => {\n const currentValue = record.data;\n const merged = mergeValues(currentValue, update);\n record.data = merged;\n record.notifier.notify();\n record.cache.clear();\n };\n\n const unsubscribe = entityConfig.stream.subscribe(context, id as string | number, onUpdate as any);\n\n // Set initial value to the proxy - this resolves the relay promise\n // Proxy should always exist at this point since it's created before relay access\n state.value = record.proxy!;\n\n return unsubscribe;\n });\n }\n\n const warn = this.queryClient.getContext().log?.warn;\n return createEntityProxy(record.key, record, shape, entityRelay, this.queryClient, warn);\n }\n}\n","/**\n * NetworkManager - Tracks network connectivity status\n *\n * Features:\n * - Signal-based reactivity for online/offline status\n * - Automatic detection using navigator.onLine and events\n * - Manual override capability for testing and custom scenarios\n * - Platform-agnostic (works in browser and React Native)\n */\n\nimport { signal, Signal, context, Context } from 'signalium';\n\nexport class NetworkManager {\n private onlineSignal: Signal<boolean>;\n private manualOverride: boolean | undefined = undefined;\n private eventListenersAttached = false;\n\n constructor(initialStatus?: boolean) {\n // Initialize with manual status if provided, otherwise detect from environment\n const initialOnlineStatus = initialStatus ?? this.detectOnlineStatus();\n this.onlineSignal = signal(initialOnlineStatus);\n\n // Automatically attach event listeners if in browser/React Native environment\n if (this.canAttachListeners()) {\n this.attachEventListeners();\n }\n }\n\n /**\n * Returns true if the network is currently online\n */\n get isOnline(): boolean {\n // Manual override takes precedence\n if (this.manualOverride !== undefined) {\n return this.manualOverride;\n }\n\n return this.onlineSignal.value;\n }\n\n /**\n * Manually set the network status (useful for testing)\n */\n setNetworkStatus(online: boolean): void {\n this.manualOverride = online;\n this.onlineSignal.value = online;\n }\n\n /**\n * Clear manual override and return to automatic detection\n */\n clearManualOverride(): void {\n this.manualOverride = undefined;\n this.onlineSignal.value = this.detectOnlineStatus();\n }\n\n /**\n * Get the reactive signal for online status\n * This allows reactive functions to depend on network status\n */\n getOnlineSignal(): Signal<boolean> {\n return this.onlineSignal;\n }\n\n /**\n * Detect current online status from the environment\n */\n private detectOnlineStatus(): boolean {\n // Check if we're in a browser or React Native environment\n if (typeof navigator !== 'undefined' && 'onLine' in navigator) {\n return navigator.onLine;\n }\n\n // Default to online if we can't detect (e.g., Node.js/SSR)\n return true;\n }\n\n /**\n * Check if we can attach event listeners (browser or React Native)\n */\n private canAttachListeners(): boolean {\n return typeof window !== 'undefined' && typeof window.addEventListener === 'function';\n }\n\n /**\n * Attach event listeners for online/offline events\n */\n private attachEventListeners(): void {\n if (this.eventListenersAttached) {\n return;\n }\n\n const handleOnline = () => {\n if (this.manualOverride === undefined) {\n this.onlineSignal.value = true;\n }\n };\n\n const handleOffline = () => {\n if (this.manualOverride === undefined) {\n this.onlineSignal.value = false;\n }\n };\n\n window.addEventListener('online', handleOnline);\n window.addEventListener('offline', handleOffline);\n\n this.eventListenersAttached = true;\n\n // Note: In a real production app, you might want to provide a cleanup method\n // to remove these listeners, but for a singleton that lives for the app lifetime,\n // it's not critical\n }\n}\n\n// No-op implementation for SSR environments where network status tracking is not needed\nexport class NoOpNetworkManager {\n private static readonly onlineSignal: Signal<boolean> = signal(true);\n\n get isOnline(): boolean {\n return true;\n }\n\n setNetworkStatus(_online: boolean): void {\n // No-op: do nothing\n }\n\n clearManualOverride(): void {\n // No-op: do nothing\n }\n\n getOnlineSignal(): Signal<boolean> {\n return NoOpNetworkManager.onlineSignal;\n }\n\n destroy(): void {\n // No-op: do nothing\n }\n}\n\n// Default singleton instance for convenience\nexport const defaultNetworkManager = new NetworkManager();\n\n// Context for dependency injection\nexport const NetworkManagerContext: Context<NetworkManager> = context<NetworkManager>(defaultNetworkManager);\n","// -----------------------------------------------------------------------------\n// Entity System\n// -----------------------------------------------------------------------------\n\nimport { hashValue } from 'signalium/utils';\nimport { QueryClient } from './QueryClient.js';\nimport { parseValue } from './proxy.js';\nimport {\n ARRAY_KEY,\n ArrayDef,\n ComplexTypeDef,\n EntityDef,\n Mask,\n ObjectDef,\n ObjectFieldTypeDef,\n ParseResultDef,\n RECORD_KEY,\n RecordDef,\n UnionDef,\n} from './types.js';\nimport { typeMaskOf } from './utils.js';\n\nconst entries = Object.entries;\n\nexport function parseUnionEntities(\n valueType: number,\n value: object | unknown[],\n unionDef: UnionDef,\n queryClient: QueryClient,\n entityRefs?: Set<number>,\n): unknown {\n if (valueType === Mask.ARRAY) {\n const shape = unionDef.shape![ARRAY_KEY];\n\n if (shape === undefined || typeof shape === 'number') {\n return value;\n }\n\n return parseArrayEntities(\n value as unknown[],\n { mask: Mask.ARRAY, shape, values: undefined } as ArrayDef,\n queryClient,\n entityRefs,\n );\n } else {\n // Use the cached typename field from the union definition\n const typenameField = unionDef.typenameField;\n const typename = typenameField ? (value as Record<string, unknown>)[typenameField] : undefined;\n\n if (typename === undefined || typeof typename !== 'string') {\n const recordShape = unionDef.shape![RECORD_KEY];\n\n if (recordShape === undefined || typeof recordShape === 'number') {\n // Union of objects/entities requires typename for discrimination\n throw new Error(\n `Typename field '${typenameField}' is required for union discrimination but was not found in the data`,\n );\n }\n\n return parseRecordEntities(\n value as Record<string, unknown>,\n recordShape as ComplexTypeDef,\n queryClient,\n entityRefs,\n );\n }\n\n const matchingDef = unionDef.shape![typename];\n\n if (matchingDef === undefined || typeof matchingDef === 'number') {\n throw new Error(`Unknown typename '${typename}' in union`);\n }\n\n return parseObjectEntities(\n value as Record<string, unknown>,\n matchingDef as ObjectDef | EntityDef,\n queryClient,\n entityRefs,\n );\n }\n}\n\nexport function parseArrayEntities(\n array: unknown[],\n arrayShape: ComplexTypeDef,\n queryClient: QueryClient,\n entityRefs?: Set<number>,\n): unknown[] {\n const result: unknown[] = [];\n\n for (let i = 0; i < array.length; i++) {\n try {\n result.push(parseEntities(array[i], arrayShape, queryClient, entityRefs));\n } catch (e) {\n queryClient.getContext().log?.warn?.('Failed to parse array item, filtering out', {\n index: i,\n value: array[i],\n error: e instanceof Error ? e.message : String(e),\n });\n }\n }\n\n return result;\n}\n\nexport function parseRecordEntities(\n record: Record<string, unknown>,\n recordShape: ComplexTypeDef,\n queryClient: QueryClient,\n entityRefs?: Set<number>,\n): Record<string, unknown> {\n if (typeof recordShape === 'number') {\n return record;\n }\n\n for (const [key, value] of entries(record)) {\n record[key] = parseEntities(value, recordShape, queryClient, entityRefs);\n }\n\n return record;\n}\n\nexport function parseObjectEntities(\n obj: Record<string, unknown>,\n objectShape: ObjectDef | EntityDef,\n queryClient: QueryClient,\n entityRefs?: Set<number>,\n): Record<string, unknown> {\n const entityRefId = obj.__entityRef as number;\n\n // Check if this is an entity reference (from cache)\n if (typeof entityRefId === 'number') {\n return queryClient.hydrateEntity(entityRefId, objectShape as EntityDef).proxy;\n }\n\n // Process sub-entity paths (only these paths can contain entities)\n const { mask } = objectShape;\n\n const childRefs = mask & Mask.ENTITY ? new Set<number>() : entityRefs;\n\n // Extract shape first to resolve lazy definitions and set subEntityPaths\n const shape = objectShape.shape;\n const subEntityPaths = objectShape.subEntityPaths;\n\n if (subEntityPaths !== undefined) {\n if (typeof subEntityPaths === 'string') {\n // Single path - avoid array allocation\n const propDef = shape[subEntityPaths];\n obj[subEntityPaths] = parseEntities(obj[subEntityPaths], propDef as ComplexTypeDef, queryClient, childRefs);\n } else {\n // Multiple paths - iterate directly\n for (const path of subEntityPaths) {\n const propDef = shape[path];\n obj[path] = parseEntities(obj[path], propDef as ComplexTypeDef, queryClient, childRefs);\n }\n }\n }\n\n // Handle entity replacement (entities get cached and replaced with proxies)\n if (mask & Mask.ENTITY) {\n const entityDef = objectShape as EntityDef;\n const typename = entityDef.typenameValue;\n const id = obj[entityDef.idField];\n\n if (id === undefined) {\n throw new Error(`Entity id is required: ${typename}`);\n }\n\n const desc = `${typename}:${id}`;\n const key = hashValue(desc);\n\n // Add this entity's key to the parent's entityRefs (if provided)\n if (entityRefs !== undefined) {\n entityRefs.add(key);\n }\n\n return queryClient.saveEntity(key, obj, entityDef, childRefs).proxy;\n }\n\n // For non-entity objects, parse all fields (including enums, formatted values, etc.)\n // Entities handle this lazily via their proxy\n const warn = queryClient.getContext().log?.warn;\n for (const [key, propDef] of entries(shape)) {\n // Skip fields that were already processed as sub-entity paths\n if (subEntityPaths !== undefined) {\n if (typeof subEntityPaths === 'string' ? key === subEntityPaths : subEntityPaths.includes(key)) {\n continue;\n }\n }\n obj[key] = parseValue(\n obj[key],\n propDef as ObjectFieldTypeDef,\n `${objectShape.typenameValue ?? 'object'}.${key}`,\n false,\n warn,\n );\n }\n\n return obj;\n}\n\nexport function parseEntities(\n value: unknown,\n def: ComplexTypeDef,\n queryClient: QueryClient,\n entityRefs?: Set<number>,\n): unknown {\n const valueType = typeMaskOf(value);\n const defType = def.mask;\n\n // Handle parseResult wrapper - wraps parsing in try-catch and returns discriminated union\n if ((defType & Mask.PARSE_RESULT) !== 0) {\n try {\n const innerResult = parseEntities(\n value,\n (def as ParseResultDef).shape as ComplexTypeDef,\n queryClient,\n entityRefs,\n );\n return { success: true as const, value: innerResult };\n } catch (e) {\n return { success: false as const, error: e instanceof Error ? e : new Error(String(e)) };\n }\n }\n\n // Skip primitives and incompatible types - they can't contain entities\n // Note: We silently return incompatible values rather than erroring\n if (valueType < Mask.OBJECT || (defType & valueType) === 0) {\n return value;\n }\n\n // Handle unions first - they can contain multiple types, and all of the union\n // logic is handled above, so we return early here if it's a union\n if ((defType & Mask.UNION) !== 0) {\n return parseUnionEntities(\n valueType,\n value as Record<string, unknown> | unknown[],\n def as UnionDef,\n queryClient,\n entityRefs,\n );\n }\n\n // If it's not a union, AND the value IS an array, then the definition must\n // be an ArrayDef, so we can cast safely here\n if (valueType === Mask.ARRAY) {\n return parseArrayEntities(value as unknown[], (def as ArrayDef).shape as ComplexTypeDef, queryClient, entityRefs);\n }\n\n // Now we know the value is an object, so def must be a RecordDef, ObjectDef\n // or EntityDef. We first check to see if it's a RecordDef, and if so, we can\n // cast it here and return early.\n if ((defType & Mask.RECORD) !== 0) {\n return parseRecordEntities(\n value as Record<string, unknown>,\n (def as RecordDef).shape as ComplexTypeDef,\n queryClient,\n entityRefs,\n );\n }\n\n // Now we know the def is an ObjectDef or EntityDef. These are both handled\n // the same way _mostly_, with Entities just returning a proxy instead of the\n // object itself\n return parseObjectEntities(value as Record<string, unknown>, def as ObjectDef | EntityDef, queryClient, entityRefs);\n}\n","import {\n relay,\n type RelayState,\n DiscriminatedReactivePromise,\n Signal,\n signal,\n ReadonlySignal,\n reactiveSignal,\n Notifier,\n notifier,\n} from 'signalium';\nimport { setReactivePromise } from 'signalium/utils';\nimport { EntityDef, BaseQueryResult, ComplexTypeDef, NetworkMode, QueryExtra } from './types.js';\nimport { getProxyId, parseValue } from './proxy.js';\nimport { parseEntities, parseObjectEntities } from './parseEntities.js';\nimport { ValidatorDef } from './typeDefs.js';\nimport {\n InfiniteQueryDefinition,\n QueryDefinition,\n QueryType,\n StreamSubscribeFn,\n type AnyQueryDefinition,\n type QueryClient,\n type QueryParams,\n extractParamsForKey,\n queryKeyFor,\n} from './QueryClient.js';\nimport { CachedQuery, CachedQueryExtra } from './QueryClient.js';\n\n// ======================================================\n// QueryResultExtra - Manages stream orphans and optimistic inserts\n// ======================================================\n\n/**\n * Manages extra data for a query result: stream orphans and optimistic inserts.\n * Created lazily when first needed.\n */\nclass QueryResultExtra {\n private _streamOrphansNotifier: Notifier | undefined = undefined;\n private _streamOrphans: Set<Record<string, unknown>> | undefined = undefined;\n\n private _optimisticInsertsNotifier: Notifier | undefined = undefined;\n private _optimisticInserts: Set<Record<string, unknown>> | undefined = undefined;\n\n private onChanged: () => void;\n\n constructor(onChanged: () => void) {\n this.onChanged = onChanged;\n }\n\n private get streamOrphansNotifier(): Notifier {\n return this._streamOrphansNotifier ?? (this._streamOrphansNotifier = notifier());\n }\n\n private get optimisticInsertsNotifier(): Notifier {\n return this._optimisticInsertsNotifier ?? (this._optimisticInsertsNotifier = notifier());\n }\n\n get streamOrphans(): Set<Record<string, unknown>> {\n return this._streamOrphans ?? (this._streamOrphans = new Set());\n }\n\n get optimisticInserts(): Set<Record<string, unknown>> {\n return this._optimisticInserts ?? (this._optimisticInserts = new Set());\n }\n\n /**\n * Returns the QueryExtra object for public API consumption.\n * Consumes the notifiers to establish reactive tracking.\n */\n getExtra(): QueryExtra<unknown, unknown> {\n this.streamOrphansNotifier.consume();\n this.optimisticInsertsNotifier.consume();\n return {\n streamOrphans: this.streamOrphans,\n optimisticInserts: this.optimisticInserts,\n };\n }\n\n /**\n * Add a stream orphan entity.\n * Returns true if the orphan was added (not a duplicate).\n */\n addStreamOrphan(entity: Record<string, unknown>): boolean {\n const orphans = this.streamOrphans;\n const sizeBefore = orphans.size;\n orphans.add(entity);\n\n if (orphans.size !== sizeBefore) {\n this.streamOrphansNotifier.notify();\n\n // Check if this orphan was an optimistic insert - if so, remove it\n const proxyId = getProxyId(entity);\n if (proxyId !== undefined) {\n this.removeOptimisticInsertById(proxyId);\n }\n\n this.onChanged();\n return true;\n }\n\n return false;\n }\n\n /**\n * Add an optimistic insert entity.\n * Returns true if the insert was added (not a duplicate).\n */\n addOptimisticInsert(entity: Record<string, unknown>): boolean {\n const inserts = this.optimisticInserts;\n const sizeBefore = inserts.size;\n inserts.add(entity);\n\n if (inserts.size !== sizeBefore) {\n this.optimisticInsertsNotifier.notify();\n this.onChanged();\n return true;\n }\n\n return false;\n }\n\n /**\n * Remove an optimistic insert by its entity.\n * Returns true if the insert was removed.\n */\n removeOptimisticInsert(entity: Record<string, unknown>): boolean {\n const proxyId = getProxyId(entity);\n if (proxyId === undefined) {\n return false;\n }\n\n return this.removeOptimisticInsertById(proxyId);\n }\n\n /**\n * Remove an optimistic insert by proxy ID.\n */\n private removeOptimisticInsertById(proxyId: number): boolean {\n const inserts = this._optimisticInserts;\n if (inserts === undefined || inserts.size === 0) {\n return false;\n }\n\n for (const existing of inserts) {\n if (getProxyId(existing) === proxyId) {\n inserts.delete(existing);\n this.optimisticInsertsNotifier.notify();\n this.onChanged();\n return true;\n }\n }\n\n return false;\n }\n\n /**\n * Check if a proxy ID exists in stream orphans.\n */\n hasOrphanWithId(proxyId: number): boolean {\n const orphans = this._streamOrphans;\n if (orphans === undefined) {\n return false;\n }\n\n for (const orphan of orphans) {\n if (getProxyId(orphan) === proxyId) {\n return true;\n }\n }\n\n return false;\n }\n\n /**\n * Reconcile orphans and optimistic inserts against the main response entity refs.\n * Removes any that now exist in the main response.\n */\n reconcile(allRefIds: Set<number>): void {\n // Check stream orphans for entities that now exist in main response\n const orphans = this._streamOrphans;\n if (orphans !== undefined && orphans.size > 0) {\n let orphansChanged = false;\n\n for (const orphan of orphans) {\n const entityRefId = getProxyId(orphan);\n if (entityRefId !== undefined && allRefIds.has(entityRefId)) {\n orphans.delete(orphan);\n orphansChanged = true;\n }\n }\n\n if (orphansChanged) {\n this.streamOrphansNotifier.notify();\n }\n }\n\n // Check optimistic inserts for entities that now exist in main response or stream orphans\n const inserts = this._optimisticInserts;\n if (inserts !== undefined && inserts.size > 0) {\n let insertsChanged = false;\n\n for (const insert of inserts) {\n const entityRefId = getProxyId(insert);\n if (entityRefId !== undefined) {\n // Remove if entity is now in main response\n if (allRefIds.has(entityRefId)) {\n inserts.delete(insert);\n insertsChanged = true;\n }\n // Also remove if entity is now in stream orphans\n else if (orphans !== undefined && orphans.has(insert)) {\n inserts.delete(insert);\n insertsChanged = true;\n }\n }\n }\n\n if (insertsChanged) {\n this.optimisticInsertsNotifier.notify();\n }\n }\n }\n\n /**\n * Clear all stream orphans and optimistic inserts.\n * Called on refetch.\n */\n clear(): void {\n let changed = false;\n\n if (this._streamOrphans !== undefined && this._streamOrphans.size > 0) {\n this._streamOrphans = undefined;\n this.streamOrphansNotifier.notify();\n changed = true;\n }\n\n if (this._optimisticInserts !== undefined && this._optimisticInserts.size > 0) {\n this._optimisticInserts = undefined;\n this.optimisticInsertsNotifier.notify();\n changed = true;\n }\n\n if (changed) {\n this.onChanged();\n }\n }\n\n /**\n * Load extra data from cached values.\n */\n loadFromCache(\n cachedExtra: CachedQueryExtra,\n queryClient: QueryClient,\n streamShape: EntityDef | undefined,\n optimisticInsertsShape: EntityDef | undefined,\n ): void {\n if (cachedExtra.streamOrphanRefs && cachedExtra.streamOrphanRefs.length > 0 && streamShape) {\n const orphans = this.streamOrphans;\n for (const refId of cachedExtra.streamOrphanRefs) {\n const entityRecord = queryClient.hydrateEntity(refId, streamShape);\n orphans.add(entityRecord.proxy);\n }\n }\n\n if (cachedExtra.optimisticInsertRefs && cachedExtra.optimisticInsertRefs.length > 0 && optimisticInsertsShape) {\n const inserts = this.optimisticInserts;\n for (const refId of cachedExtra.optimisticInsertRefs) {\n const entityRecord = queryClient.hydrateEntity(refId, optimisticInsertsShape);\n inserts.add(entityRecord.proxy);\n }\n }\n }\n\n /**\n * Get extra data for persistence (converts Sets to arrays of entity ref IDs).\n */\n getForPersistence(): CachedQueryExtra | undefined {\n const orphans = this._streamOrphans;\n const inserts = this._optimisticInserts;\n\n if ((orphans === undefined || orphans.size === 0) && (inserts === undefined || inserts.size === 0)) {\n return undefined;\n }\n\n const extra: CachedQueryExtra = {};\n\n if (orphans !== undefined && orphans.size > 0) {\n extra.streamOrphanRefs = [];\n for (const orphan of orphans) {\n const refId = getProxyId(orphan);\n if (refId !== undefined) {\n extra.streamOrphanRefs.push(refId);\n }\n }\n }\n\n if (inserts !== undefined && inserts.size > 0) {\n extra.optimisticInsertRefs = [];\n for (const insert of inserts) {\n const refId = getProxyId(insert);\n if (refId !== undefined) {\n extra.optimisticInsertRefs.push(refId);\n }\n }\n }\n\n return extra;\n }\n\n /**\n * Check if there's any extra data.\n */\n get hasData(): boolean {\n return (\n (this._streamOrphans !== undefined && this._streamOrphans.size > 0) ||\n (this._optimisticInserts !== undefined && this._optimisticInserts.size > 0)\n );\n }\n}\n\n// ======================================================\n// QueryResultImpl\n// ======================================================\n\n/**\n * QueryResult wraps a DiscriminatedReactivePromise and adds additional functionality\n * like refetch, while forwarding all the base relay properties.\n * This class combines the old QueryInstance and QueryResultImpl into a single entity.\n */\nexport class QueryResultImpl<T> implements BaseQueryResult<T, unknown, unknown> {\n def: AnyQueryDefinition<any, any, any>;\n queryKey: number; // Instance key (includes Signal identity)\n storageKey: number = -1; // Storage key (extracted values only)\n\n private queryClient: QueryClient;\n private initialized: boolean = false;\n private isRefetchingSignal: Signal<boolean> = signal(false);\n private isFetchingMoreSignal: Signal<boolean> = signal(false);\n private updatedAt: number | undefined = undefined;\n private params: QueryParams | undefined = undefined;\n private refIds: Set<number> | undefined = undefined;\n\n private allNestedRefIdsSignal: ReadonlySignal<Set<number>> | undefined = undefined;\n\n private refetchPromise: Promise<T> | undefined = undefined;\n private fetchMorePromise: Promise<T> | undefined = undefined;\n private unsubscribe?: () => void = undefined;\n\n private relay: DiscriminatedReactivePromise<T>;\n private _relayState: RelayState<any> | undefined = undefined;\n private wasPaused: boolean = false;\n private currentParams: QueryParams | undefined = undefined;\n private debounceTimer: ReturnType<typeof setTimeout> | undefined = undefined;\n\n private get relayState(): RelayState<any> {\n const relayState = this._relayState;\n\n if (!relayState) {\n throw new Error('Relay state not initialized');\n }\n\n return relayState;\n }\n\n private _extra: QueryResultExtra | undefined = undefined;\n\n private get extraData(): QueryResultExtra {\n return this._extra ?? (this._extra = new QueryResultExtra(() => this.persistExtraData()));\n }\n\n private _nextPageParams: QueryParams | undefined | null = undefined;\n\n private get nextPageParams(): QueryParams | null {\n // Streams and non-infinite queries don't have pagination\n if (this.def.type !== QueryType.InfiniteQuery) {\n return null;\n }\n\n let params = this._nextPageParams;\n\n const value = this.relayState.value;\n\n if (params === undefined && value !== undefined) {\n if (!Array.isArray(value)) {\n throw new Error('Query result is not an array, this is a bug');\n }\n\n const infiniteDef = this.def as InfiniteQueryDefinition<any, any, any>;\n const nextParams = infiniteDef.pagination?.getNextPageParams?.(value[value.length - 1]);\n\n if (nextParams === undefined) {\n // store null to indicate that there is no next page, but we've already calculated\n params = null;\n } else {\n // Clone current params\n let hasDefinedParams = false;\n const clonedParams = { ...this.currentParams };\n\n // iterate over the next page params and copy any defined values to the\n for (const [key, value] of Object.entries(nextParams)) {\n if (value !== undefined && value !== null) {\n clonedParams[key] = value;\n hasDefinedParams = true;\n }\n }\n\n this._nextPageParams = params = hasDefinedParams ? clonedParams : null;\n }\n }\n\n return params ?? null;\n }\n\n constructor(\n def: AnyQueryDefinition<any, any, any>,\n queryClient: QueryClient,\n queryKey: number,\n params: QueryParams | undefined,\n ) {\n setReactivePromise(this);\n this.def = def;\n this.queryClient = queryClient;\n this.queryKey = queryKey; // Instance key (Signal identity)\n this.params = params;\n\n // Create the relay and handle activation/deactivation\n this.relay = relay<T>(state => {\n this._relayState = state;\n\n // Extract params (reading Signal values establishes tracking)\n this.currentParams = extractParamsForKey(this.params);\n this.storageKey = queryKeyFor(this.def, this.currentParams);\n\n // Load from cache first, then fetch fresh data\n this.queryClient.activateQuery(this);\n\n // Store initial offline state\n const isPaused = this.isPaused;\n this.wasPaused = isPaused;\n\n if (this.initialized) {\n if (!isPaused) {\n // For any query with streams, resubscribe on reactivation\n if (\n this.def.type === QueryType.Stream ||\n (this.def as QueryDefinition<any, any, any> | InfiniteQueryDefinition<any, any, any>).stream\n ) {\n this.setupSubscription();\n }\n\n if (this.def.type !== QueryType.Stream && this.isStale) {\n this.refetch();\n }\n }\n } else {\n this.initialize();\n }\n\n const deactivate = () => {\n // Clear debounce timer if active\n clearTimeout(this.debounceTimer);\n this.debounceTimer = undefined;\n\n // Last subscriber left, deactivate refetch and schedule memory eviction\n // Unsubscribe from any active streams\n this.unsubscribe?.();\n this.unsubscribe = undefined;\n\n // Remove from refetch manager if configured\n if (this.def.type !== QueryType.Stream && this.def.cache?.refetchInterval) {\n this.queryClient.refetchManager.removeQuery(this);\n }\n\n // Schedule removal from memory using the global eviction manager\n // This allows quick reactivation from memory if needed again soon\n // Disk cache (if configured) will still be available after eviction\n // Use queryKey for instance eviction, storageKey for cache eviction\n this.queryClient.memoryEvictionManager.scheduleEviction(this.queryKey);\n };\n\n // Return deactivation callback\n return {\n update: () => {\n const { wasPaused, isPaused } = this;\n this.wasPaused = isPaused;\n\n if (isPaused) {\n deactivate();\n\n // TODO: Add abort signal\n return;\n }\n\n // Read Signal values again to establish tracking for any new Signals\n // Extract params (reading Signal values establishes tracking)\n const newExtractedParams = extractParamsForKey(this.params);\n const newStorageKey = queryKeyFor(this.def, newExtractedParams);\n\n const paramsDidChange = newStorageKey !== this.storageKey;\n\n // Check if storage key changed (comparing hash values)\n if (paramsDidChange) {\n // Same storage key, just Signal instances changed but values are the same\n // Update params and trigger debounced refetch\n this.params = newExtractedParams as QueryParams;\n this.storageKey = newStorageKey;\n }\n\n if (wasPaused) {\n this.queryClient.activateQuery(this);\n\n if (this.def.type !== QueryType.Stream) {\n const refreshStaleOnReconnect = this.def.cache?.refreshStaleOnReconnect ?? true;\n if (refreshStaleOnReconnect && this.isStale) {\n state.setPromise(this.runQuery(this.currentParams, true));\n }\n } else {\n this.setupSubscription();\n }\n } else if (paramsDidChange) {\n if (this.def.type !== QueryType.Stream) {\n this.debouncedRefetch();\n } else {\n this.setupSubscription();\n }\n }\n },\n deactivate,\n };\n }) as DiscriminatedReactivePromise<T>;\n }\n\n // ======================================================\n // ReactivePromise properties\n // =====================================================\n\n get value(): T | undefined {\n return this.relay.value;\n }\n\n get error(): unknown {\n return this.relay.error;\n }\n\n get isPending(): boolean {\n return this.relay.isPending;\n }\n\n get isRejected(): boolean {\n return this.relay.isRejected;\n }\n\n get isResolved(): boolean {\n return this.relay.isResolved;\n }\n\n get isSettled(): boolean {\n return this.relay.isSettled;\n }\n\n get isReady(): boolean {\n return this.relay.isReady;\n }\n\n // TODO: Intimate APIs needed for `useReactive`, this is a code smell and\n // we should find a better way to entangle these more generically\n private get _version(): Signal<number> {\n return (this.relay as any)._version;\n }\n\n private get _signal(): Signal<T> {\n return (this.relay as any)._signal;\n }\n\n private get _flags(): number {\n return (this.relay as any)._flags;\n }\n\n // Forward Promise methods\n then<TResult1 = T, TResult2 = never>(\n onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | null | undefined,\n onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null | undefined,\n ): Promise<TResult1 | TResult2> {\n return this.relay.then(onfulfilled, onrejected);\n }\n\n catch<TResult = never>(\n onrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | null | undefined,\n ): Promise<T | TResult> {\n return this.relay.catch(onrejected);\n }\n\n finally(onfinally?: (() => void) | null | undefined): Promise<T> {\n return this.relay.finally(onfinally);\n }\n\n get [Symbol.toStringTag](): string {\n return 'QueryResult';\n }\n\n // ======================================================\n // Internal fetch methods\n // ======================================================\n\n private getAllEntityRefs(): Set<number> {\n let allNestedRefIdsSignal = this.allNestedRefIdsSignal;\n\n if (!allNestedRefIdsSignal) {\n const queryClient = this.queryClient;\n\n this.allNestedRefIdsSignal = allNestedRefIdsSignal = reactiveSignal(() => {\n // Entangle the relay value. Whenever the relay value is updated, the\n // allNestedRefIdsSignal will be updated, so no need for a second signal.\n // eslint-disable-next-line @typescript-eslint/no-unused-expressions\n this.relay.value;\n\n const allRefIds = new Set<number>();\n\n if (this.refIds !== undefined) {\n for (const refId of this.refIds) {\n queryClient.getNestedEntityRefIds(refId, allRefIds);\n }\n }\n\n // Reconcile extra data against the main response\n this.extraData.reconcile(allRefIds);\n\n return allRefIds;\n });\n }\n\n return allNestedRefIdsSignal.value;\n }\n\n /**\n * Initialize the query by loading from cache and fetching if stale\n */\n private async initialize(): Promise<void> {\n const state = this.relayState;\n\n this.initialized = true;\n\n let cached: CachedQuery | undefined;\n\n try {\n // Load from cache first (use storage key for cache operations)\n cached = await this.queryClient.loadCachedQuery(this.def, this.storageKey);\n\n if (cached !== undefined) {\n // Set the cached timestamp\n this.updatedAt = cached.updatedAt;\n\n // Set the cached reference IDs\n this.refIds = cached.refIds;\n\n // Load extra data (stream orphans and optimistic inserts) BEFORE setting state.value\n // because setting state.value resolves the relay\n if (cached.extra) {\n const def = this.def as QueryDefinition<any, any, any> | InfiniteQueryDefinition<any, any, any>;\n this.extraData.loadFromCache(\n cached.extra,\n this.queryClient,\n def.stream?.shape as EntityDef | undefined,\n def.optimisticInserts?.shape as EntityDef | undefined,\n );\n }\n\n // Set the value last - this resolves the relay\n const shape = this.def.shape;\n state.value =\n shape instanceof ValidatorDef\n ? parseEntities(cached.value, shape as ComplexTypeDef, this.queryClient, new Set())\n : parseValue(cached.value, shape, this.def.id);\n }\n } catch (error) {\n this.queryClient.deleteCachedQuery(this.storageKey);\n this.queryClient\n .getContext()\n .log?.warn?.('Failed to initialize query, the query cache may be corrupted or invalid', error);\n }\n\n if (this.isPaused) {\n return;\n }\n\n try {\n // Setup subscriptions (handles both StreamQuery and Query/InfiniteQuery with stream)\n if (\n this.def.type === QueryType.Stream ||\n (this.def as QueryDefinition<any, any, any> | InfiniteQueryDefinition<any, any, any>).stream\n ) {\n this.setupSubscription();\n }\n\n // For non-stream queries, fetch if stale or no cache\n if (this.def.type !== QueryType.Stream) {\n if (cached !== undefined) {\n // Check if data is stale\n if (this.isStale) {\n // Data is stale, trigger background refetch (with debounce if configured)\n if (this.def.debounce !== undefined && this.def.debounce > 0) {\n this.debouncedRefetch();\n } else {\n this.refetch();\n }\n }\n } else {\n // No cached data, fetch fresh immediately (don't debounce initial fetch)\n // Debounce only applies to refetches triggered by parameter changes\n state.setPromise(this.runQuery(this.currentParams, true));\n }\n }\n } catch (error) {\n // Relay will handle the error state automatically\n state.setError(error as Error);\n }\n }\n\n /**\n * Handle stream updates. This method handles both StreamQuery and Query/InfiniteQuery with stream options.\n * - For StreamQuery: directly updates the relay state with the entity\n * - For Query/InfiniteQuery with stream: updates entities in response or adds to orphans\n */\n private setupSubscription(): void {\n this.unsubscribe?.();\n\n let subscribeFn: StreamSubscribeFn<any, any>;\n let shapeDef: EntityDef;\n\n if (this.def.type === QueryType.Stream) {\n shapeDef = this.def.shape as EntityDef;\n subscribeFn = this.def.subscribeFn;\n } else {\n const stream = (this.def as QueryDefinition<any, any, any> | InfiniteQueryDefinition<any, any, any>).stream;\n\n if (!stream) {\n return;\n }\n\n shapeDef = stream.shape as EntityDef;\n subscribeFn = stream.subscribeFn;\n }\n\n // Extract params (reading Signal values establishes tracking)\n const extractedParams = this.currentParams;\n this.unsubscribe = subscribeFn(this.queryClient.getContext(), extractedParams as QueryParams, update => {\n const parsedData = parseObjectEntities(update, shapeDef, this.queryClient);\n\n // Update the relay state\n if (this.def.type === QueryType.Stream) {\n this.relayState.value = parsedData;\n this.updatedAt = Date.now();\n\n // Cache the data\n // Use storage key for cache operations\n this.queryClient.saveQueryData(this.def, this.storageKey, parsedData, this.updatedAt);\n } else {\n const allRefIds = this.getAllEntityRefs();\n const proxyId = getProxyId(parsedData);\n\n // Add to orphans if not in main response\n if (proxyId !== undefined && !allRefIds.has(proxyId)) {\n this.extraData.addStreamOrphan(parsedData);\n }\n }\n });\n }\n\n /**\n * Fetches fresh data, updates the cache, and updates updatedAt timestamp\n */\n private async runQuery(params: QueryParams | undefined, reset = false): Promise<T> {\n // Check if paused before attempting fetch\n if (this.isPaused) {\n throw new Error('Query is paused due to network status');\n }\n\n const { retries, retryDelay } = this.getRetryConfig();\n let lastError: unknown;\n\n // Attempt fetch with retries\n for (let attempt = 0; attempt <= retries; attempt++) {\n try {\n const queryDef = this.def as QueryDefinition<any, any, any> | InfiniteQueryDefinition<any, any, any>;\n const freshData = await queryDef.fetchFn(this.queryClient.getContext(), params);\n\n // Parse and cache the fresh data\n let entityRefs;\n\n const isInfinite = this.def.type === QueryType.InfiniteQuery;\n\n if (isInfinite && !reset && this.refIds !== undefined) {\n entityRefs = this.refIds;\n } else {\n entityRefs = this.refIds = new Set<number>();\n }\n\n const shape = this.def.shape;\n\n const parsedData =\n shape instanceof ValidatorDef\n ? parseEntities(freshData, shape as ComplexTypeDef, this.queryClient, entityRefs)\n : parseValue(freshData, shape, this.def.id);\n\n let queryData;\n\n if (isInfinite) {\n const prevQueryData = this.relayState.value;\n queryData = reset || prevQueryData === undefined ? [parsedData] : [...prevQueryData, parsedData];\n } else {\n queryData = parsedData;\n }\n\n let updatedAt;\n\n if (reset) {\n updatedAt = this.updatedAt = Date.now();\n } else {\n updatedAt = this.updatedAt ??= Date.now();\n }\n\n this._nextPageParams = undefined;\n\n // Cache the data (synchronous, fire-and-forget)\n // Use storage key for cache operations\n this.queryClient.saveQueryData(\n this.def,\n this.storageKey,\n queryData,\n updatedAt,\n entityRefs,\n this.getExtraForPersistence(),\n );\n\n // Update the timestamp\n this.updatedAt = Date.now();\n\n return queryData as T;\n } catch (error) {\n lastError = error;\n\n // If we've exhausted retries, throw the error\n if (attempt >= retries) {\n throw error;\n }\n\n // Wait before retrying (unless paused)\n const delay = retryDelay(attempt);\n await new Promise(resolve => setTimeout(resolve, delay));\n\n // Check if paused during retry delay\n if (this.isPaused) {\n throw new Error('Query is paused due to network status');\n }\n }\n }\n\n // Should never reach here, but TypeScript needs it\n throw lastError;\n }\n\n // ======================================================\n // Private debounce methods\n // ======================================================\n\n /**\n * Triggers a debounced refetch. If debounce is configured, delays the fetch.\n * Otherwise, calls refetch immediately.\n */\n private debouncedRefetch(): void {\n // We know this is a non-stream query because we're calling refetch, which is only available on non-stream queries\n const debounce = (this.def as QueryDefinition<any, any, any> | InfiniteQueryDefinition<any, any, any>).debounce;\n\n if (debounce === undefined) {\n this.refetch();\n return;\n }\n\n // Clear existing timer\n clearTimeout(this.debounceTimer);\n\n // Set new timer\n this.debounceTimer = setTimeout(() => {\n this.debounceTimer = undefined;\n this.refetch();\n }, debounce);\n }\n\n // ======================================================\n // Public methods\n // ======================================================\n\n refetch = (): Promise<T> => {\n if (this.def.type === QueryType.Stream) {\n throw new Error('Cannot refetch a stream query');\n }\n\n if (this.fetchMorePromise) {\n throw new Error('Query is fetching more, cannot refetch');\n }\n\n if (this.refetchPromise) {\n return this.refetchPromise;\n }\n\n // Clear debounce timer if active (manual refetch should bypass debounce)\n clearTimeout(this.debounceTimer);\n this.debounceTimer = undefined;\n\n // Clear memoized nextPageParams so it's recalculated after refetch\n this._nextPageParams = undefined;\n\n // Set the signal before any async operations so it's immediately visible\n // Use untrack to avoid reactive violations when called from reactive context\n this.isRefetchingSignal.value = true;\n this._version.update(v => v + 1);\n\n const promise = this.runQuery(this.currentParams, true)\n .then(result => {\n this.relayState.value = result;\n\n // Clear stream orphans and optimistic inserts on refetch\n if (this._extra !== undefined) {\n this._extra.clear();\n }\n\n return result;\n })\n .catch((error: unknown) => {\n this.relayState.setError(error);\n return Promise.reject(error);\n })\n .finally(() => {\n this._version.update(v => v + 1);\n this.isRefetchingSignal.value = false;\n this.refetchPromise = undefined;\n });\n\n this.refetchPromise = promise;\n return promise;\n };\n\n fetchNextPage = (): Promise<T> => {\n if (this.def.type === QueryType.Stream) {\n throw new Error('Cannot fetch next page on a stream query');\n }\n\n if (this.refetchPromise) {\n return Promise.reject(new Error('Query is refetching, cannot fetch next page'));\n }\n\n if (this.fetchMorePromise) {\n return this.fetchMorePromise;\n }\n\n // Read nextPageParams in untracked context to avoid reactive violations\n const nextPageParams = this.nextPageParams;\n\n if (!nextPageParams) {\n return Promise.reject(new Error('No next page params'));\n }\n\n // Set the signal before any async operations so it's immediately visible\n // Use untrack to avoid reactive violations when called from reactive context\n this.isFetchingMoreSignal.value = true;\n this._version.update(v => v + 1);\n\n const promise = this.runQuery(nextPageParams, false)\n .then(result => {\n this.relayState!.value = result;\n return result as T;\n })\n .catch((error: unknown) => {\n this.relayState.setError(error);\n return Promise.reject(error);\n })\n .finally(() => {\n this._version.update(v => v + 1);\n this.isFetchingMoreSignal.value = false;\n this.fetchMorePromise = undefined;\n });\n\n this.fetchMorePromise = promise;\n return promise;\n };\n\n // ======================================================\n // Public properties\n // ======================================================\n\n get isRefetching(): boolean {\n return this.isRefetchingSignal.value;\n }\n\n get isFetchingMore(): boolean {\n return this.isFetchingMoreSignal.value;\n }\n\n get isFetching(): boolean {\n return this.relay.isPending || this.isRefetching || this.isFetchingMore;\n }\n\n get hasNextPage(): boolean {\n return this.nextPageParams !== null;\n }\n\n get extra(): QueryExtra<unknown, unknown> {\n this.getAllEntityRefs();\n return this.extraData.getExtra();\n }\n\n /**\n * Persist the current extra data to the store\n */\n private persistExtraData(): void {\n if (this.updatedAt === undefined) {\n return; // Query not initialized yet\n }\n\n const extra = this._extra?.getForPersistence();\n // Use storage key for cache operations\n this.queryClient.saveQueryData(\n this.def,\n this.storageKey,\n this.relayState.value,\n this.updatedAt,\n this.refIds,\n extra,\n );\n }\n\n /**\n * Get extra data for persistence (converts Sets to arrays of entity ref IDs)\n */\n private getExtraForPersistence(): CachedQueryExtra | undefined {\n return this._extra?.getForPersistence();\n }\n\n /**\n * Add an optimistic insert to the query result.\n * The insert will be automatically removed when:\n * - The entity appears in a refetched response\n * - The entity appears as a stream orphan\n * - refetch() is called\n */\n addOptimisticInsert(insert: Record<string, unknown>): void {\n // Check that the query has optimisticInserts configured\n const def = this.def as QueryDefinition<any, any, any> | InfiniteQueryDefinition<any, any, any>;\n const optimisticInsertsConfig = def.optimisticInserts;\n\n if (optimisticInsertsConfig === undefined) {\n throw new Error(\n 'Query does not have optimisticInserts configured. Add optimisticInserts: { type: YourEntity } to the query definition.',\n );\n }\n\n let proxyId = getProxyId(insert);\n let parsedInsert = insert;\n\n // If not already a proxy, parse it through the optimisticInserts shape\n if (proxyId === undefined) {\n parsedInsert = parseObjectEntities(insert, optimisticInsertsConfig.shape as EntityDef, this.queryClient);\n proxyId = getProxyId(parsedInsert);\n\n if (proxyId === undefined) {\n throw new Error('Optimistic insert must be or produce an entity proxy');\n }\n }\n\n // Check if already in main response\n const allRefIds = this.getAllEntityRefs();\n if (allRefIds.has(proxyId)) {\n return; // Already in response, no-op\n }\n\n // Check if already in stream orphans\n if (this.extraData.hasOrphanWithId(proxyId)) {\n return; // Already in stream orphans, no-op\n }\n\n this.extraData.addOptimisticInsert(parsedInsert);\n }\n\n /**\n * Remove an optimistic insert from the query result.\n * This is a no-op if the insert has already been removed.\n */\n removeOptimisticInsert(insert: Record<string, unknown>): void {\n this.extraData.removeOptimisticInsert(insert);\n }\n\n get isStale(): boolean {\n // Streams are never stale - they're always receiving updates\n if (this.def.type === QueryType.Stream) {\n return false;\n }\n\n if (this.updatedAt === undefined) {\n return true; // No data yet, needs fetch\n }\n\n const staleTime = this.def.cache?.staleTime ?? 0;\n return Date.now() - this.updatedAt >= staleTime;\n }\n\n get isPaused(): boolean {\n // Streams handle their own connection state\n if (this.def.type === QueryType.Stream) {\n return false;\n }\n\n const networkMode = this.def.cache?.networkMode ?? NetworkMode.Online;\n const networkManager = this.queryClient.networkManager;\n\n // Read the online signal to make this reactive\n const isOnline = networkManager.getOnlineSignal().value;\n\n switch (networkMode) {\n case NetworkMode.Always:\n return false;\n case NetworkMode.Online:\n return !isOnline;\n case NetworkMode.OfflineFirst:\n // Only paused if we have no cached data AND we're offline\n return !isOnline && this.updatedAt === undefined;\n default:\n return false;\n }\n }\n\n private getRetryConfig(): { retries: number; retryDelay: (attempt: number) => number } {\n // Streams don't have retry config\n if (this.def.type === QueryType.Stream) {\n return { retries: 0, retryDelay: () => 0 };\n }\n\n const retryOption = this.def.cache?.retry;\n const isServer = this.queryClient.isServer;\n\n // Default retry count: 3 on client, 0 on server\n let retries: number;\n let retryDelay: (attempt: number) => number;\n\n if (retryOption === false) {\n retries = 0;\n } else if (retryOption === undefined) {\n retries = isServer ? 0 : 3;\n } else if (typeof retryOption === 'number') {\n retries = retryOption;\n } else {\n retries = retryOption.retries;\n }\n\n // Default exponential backoff: 1000ms * 2^attempt\n if (typeof retryOption === 'object' && retryOption.retryDelay) {\n retryDelay = retryOption.retryDelay;\n } else {\n retryDelay = (attempt: number) => 1000 * Math.pow(2, attempt);\n }\n\n return { retries, retryDelay };\n }\n}\n","import { task, type ReactiveTask } from 'signalium';\nimport { hashValue } from 'signalium/utils';\nimport {\n ArrayDef,\n BaseMutationResult,\n ComplexTypeDef,\n EntityDef,\n Mask,\n MutationResult,\n ObjectDef,\n ObjectFieldTypeDef,\n RecordDef,\n UnionDef,\n} from './types.js';\nimport { parseEntities } from './parseEntities.js';\nimport { ValidatorDef } from './typeDefs.js';\nimport { type QueryClient } from './QueryClient.js';\nimport { MutationDefinition } from './mutation.js';\nimport { typeMaskOf } from './utils.js';\n\n// ======================================================\n// MutationResultImpl\n// ======================================================\n\n/**\n * MutationResult is a thin wrapper around ReactiveTask that adds:\n * - Optimistic update support with rollback on failure\n * - Entity parsing from responses\n * - reset() functionality\n */\nexport class MutationResultImpl<Request, Response> implements BaseMutationResult<Request, Response> {\n def: MutationDefinition<Request, Response>;\n private queryClient: QueryClient;\n\n // The underlying ReactiveTask that handles all state management\n private _task: ReactiveTask<Response, [Request]>;\n\n // Track which entity keys we've registered optimistic updates for\n // EntityMap handles the actual snapshots\n private _pendingOptimisticKeys: Set<number> = new Set();\n\n constructor(def: MutationDefinition<Request, Response>, queryClient: QueryClient) {\n this.def = def;\n this.queryClient = queryClient;\n this._task = this.createTask();\n }\n\n private createTask(): ReactiveTask<Response, [Request]> {\n return task(async (request: Request): Promise<Response> => {\n try {\n const response = await this.executeWithRetry(request);\n\n // Parse response and update entities\n const parsedResponse = this.parseAndUpdateEntities(response);\n\n // Clear optimistic update tracking on success (updates are now confirmed)\n this.clearOptimisticUpdates();\n\n return parsedResponse;\n } catch (error) {\n // Revert optimistic updates on failure\n this.revertOptimisticUpdates();\n throw error;\n }\n });\n }\n\n // ======================================================\n // Delegated ReactivePromise properties\n // ======================================================\n\n get value(): Response | undefined {\n return this._task.value;\n }\n\n get error(): unknown {\n return this._task.error;\n }\n\n get isPending(): boolean {\n return this._task.isPending;\n }\n\n get isRejected(): boolean {\n return this._task.isRejected;\n }\n\n get isResolved(): boolean {\n return this._task.isResolved;\n }\n\n get isSettled(): boolean {\n return this._task.isSettled;\n }\n\n get isReady(): boolean {\n return this._task.isReady;\n }\n\n // ======================================================\n // Promise interface (delegated)\n // ======================================================\n\n then<TResult1 = Response, TResult2 = never>(\n onfulfilled?: ((value: Response) => TResult1 | PromiseLike<TResult1>) | null | undefined,\n onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null | undefined,\n ): Promise<TResult1 | TResult2> {\n return this._task.then(onfulfilled, onrejected);\n }\n\n catch<TResult = never>(\n onrejected?: ((reason: unknown) => TResult | PromiseLike<TResult>) | null | undefined,\n ): Promise<Response | TResult> {\n return this._task.catch(onrejected);\n }\n\n finally(onfinally?: (() => void) | null | undefined): Promise<Response> {\n return this._task.finally(onfinally);\n }\n\n get [Symbol.toStringTag](): string {\n return 'MutationResult';\n }\n\n // ======================================================\n // Mutation execution\n // ======================================================\n\n run = (request: Request): MutationResult<Request, Response> => {\n // Apply optimistic updates if enabled\n if (this.def.optimisticUpdates) {\n this.applyOptimisticUpdates(request);\n }\n\n // Run the underlying task\n this._task.run(request);\n\n return this as unknown as MutationResult<Request, Response>;\n };\n\n reset = (): void => {\n // Revert any pending optimistic updates\n this.revertOptimisticUpdates();\n\n // Create a fresh task to reset state\n this._task = this.createTask();\n };\n\n // ======================================================\n // Optimistic updates\n // ======================================================\n\n private applyOptimisticUpdates(request: Request): void {\n // Clear any previous tracking\n this._pendingOptimisticKeys.clear();\n\n const requestShape = this.def.requestShape;\n\n if (!(requestShape instanceof ValidatorDef)) {\n return;\n }\n\n // Recursively find and update all entities in the request\n this.findAndUpdateEntities(request, requestShape as ComplexTypeDef);\n }\n\n /**\n * Recursively walks the data according to its shape, finding and updating all entities.\n */\n private findAndUpdateEntities(value: unknown, def: ComplexTypeDef): void {\n const valueType = typeMaskOf(value);\n const defType = def.mask;\n\n // Skip primitives and incompatible types\n if (valueType < Mask.OBJECT || (defType & valueType) === 0) {\n return;\n }\n\n // Handle unions - find the matching type\n if ((defType & Mask.UNION) !== 0) {\n const unionDef = def as UnionDef;\n if (valueType === Mask.ARRAY) {\n const arrayShape = unionDef.shape!['[]' as keyof typeof unionDef.shape];\n if (arrayShape && typeof arrayShape !== 'number') {\n this.findAndUpdateEntitiesInArray(value as unknown[], arrayShape as ComplexTypeDef);\n }\n } else {\n const typenameField = unionDef.typenameField;\n const typename = typenameField ? (value as Record<string, unknown>)[typenameField] : undefined;\n if (typename && typeof typename === 'string') {\n const matchingDef = unionDef.shape![typename as keyof typeof unionDef.shape];\n if (matchingDef && typeof matchingDef !== 'number') {\n this.findAndUpdateEntitiesInObject(value as Record<string, unknown>, matchingDef as ObjectDef | EntityDef);\n }\n }\n }\n return;\n }\n\n // Handle arrays\n if (valueType === Mask.ARRAY) {\n const arrayShape = (def as ArrayDef).shape;\n if (arrayShape && typeof arrayShape !== 'number') {\n this.findAndUpdateEntitiesInArray(value as unknown[], arrayShape as ComplexTypeDef);\n }\n return;\n }\n\n // Handle records\n if ((defType & Mask.RECORD) !== 0) {\n const recordShape = (def as RecordDef).shape;\n if (recordShape && typeof recordShape !== 'number') {\n for (const item of Object.values(value as Record<string, unknown>)) {\n this.findAndUpdateEntities(item, recordShape as ComplexTypeDef);\n }\n }\n return;\n }\n\n // Handle objects/entities\n this.findAndUpdateEntitiesInObject(value as Record<string, unknown>, def as ObjectDef | EntityDef);\n }\n\n private findAndUpdateEntitiesInArray(array: unknown[], shape: ComplexTypeDef): void {\n for (const item of array) {\n this.findAndUpdateEntities(item, shape);\n }\n }\n\n private findAndUpdateEntitiesInObject(obj: Record<string, unknown>, def: ObjectDef | EntityDef): void {\n const { mask } = def;\n\n // If this is an entity, update it in the store\n if (mask & Mask.ENTITY) {\n const entityDef = def as EntityDef;\n const idField = entityDef.idField;\n const entityId = obj[idField];\n\n if (entityId !== undefined) {\n const typename = entityDef.typenameValue;\n const entityKey = hashValue(`${typename}:${entityId}`);\n\n // Register the optimistic update\n this.queryClient.registerOptimisticUpdate(entityKey, obj);\n this._pendingOptimisticKeys.add(entityKey);\n }\n }\n\n // Recurse into sub-entity paths to find nested entities\n const shape = def.shape;\n const subEntityPaths = def.subEntityPaths;\n\n if (subEntityPaths !== undefined) {\n if (typeof subEntityPaths === 'string') {\n const propDef = shape[subEntityPaths];\n if (propDef && typeof propDef !== 'number') {\n this.findAndUpdateEntities(obj[subEntityPaths], propDef as ComplexTypeDef);\n }\n } else {\n for (const path of subEntityPaths) {\n const propDef = shape[path] as ObjectFieldTypeDef;\n if (propDef && typeof propDef !== 'number') {\n this.findAndUpdateEntities(obj[path], propDef as ComplexTypeDef);\n }\n }\n }\n }\n }\n\n private revertOptimisticUpdates(): void {\n // Revert each optimistic update - EntityMap handles restoring snapshots\n for (const entityKey of this._pendingOptimisticKeys) {\n this.queryClient.revertOptimisticUpdate(entityKey);\n }\n this._pendingOptimisticKeys.clear();\n }\n\n private clearOptimisticUpdates(): void {\n // Clear optimistic update tracking (mutation succeeded, updates are confirmed)\n for (const entityKey of this._pendingOptimisticKeys) {\n this.queryClient.clearOptimisticUpdates(entityKey);\n }\n this._pendingOptimisticKeys.clear();\n }\n\n // ======================================================\n // Response parsing\n // ======================================================\n\n private parseAndUpdateEntities(response: unknown): Response {\n const responseShape = this.def.responseShape;\n\n if (!(responseShape instanceof ValidatorDef)) {\n return response as Response;\n }\n\n // Parse entities from response and update the entity store\n const entityRefs = new Set<number>();\n const parsed = parseEntities(response, responseShape as ComplexTypeDef, this.queryClient, entityRefs);\n\n return parsed as Response;\n }\n\n // ======================================================\n // Retry logic\n // ======================================================\n\n private async executeWithRetry(request: Request): Promise<Response> {\n const { retries, retryDelay } = this.getRetryConfig();\n let lastError: unknown;\n\n for (let attempt = 0; attempt <= retries; attempt++) {\n try {\n return await this.def.mutateFn(this.queryClient.getContext(), request);\n } catch (error) {\n lastError = error;\n\n // If we've exhausted retries, throw the error\n if (attempt >= retries) {\n throw error;\n }\n\n // Wait before retrying\n const delay = retryDelay(attempt);\n await new Promise(resolve => setTimeout(resolve, delay));\n }\n }\n\n // Should never reach here, but TypeScript needs it\n throw lastError;\n }\n\n private getRetryConfig(): { retries: number; retryDelay: (attempt: number) => number } {\n const retryOption = this.def.cache?.retry;\n\n let retries: number;\n let retryDelay: (attempt: number) => number;\n\n if (retryOption === false) {\n retries = 0;\n } else if (retryOption === undefined) {\n retries = 0; // Mutations default to no retries\n } else if (typeof retryOption === 'number') {\n retries = retryOption;\n } else {\n retries = retryOption.retries;\n }\n\n // Default exponential backoff: 1000ms * 2^attempt\n if (typeof retryOption === 'object' && retryOption.retryDelay) {\n retryDelay = retryOption.retryDelay;\n } else {\n retryDelay = (attempt: number) => 1000 * Math.pow(2, attempt);\n }\n\n return { retries, retryDelay };\n }\n}\n","import { QueryType } from './QueryClient.js';\nimport type { QueryResultImpl } from './QueryResult.js';\n\nconst BASE_TICK_INTERVAL = 1000; // 1 second\n\n// Refetch interval manager - uses a fixed 1-second tick\nexport class RefetchManager {\n private intervalId: NodeJS.Timeout;\n private clock: number = 0; // Increments by 1000ms on each tick\n\n // Buckets: Map of actual interval -> Set of query instances\n private buckets = new Map<number, Set<QueryResultImpl<any>>>();\n\n constructor(private multiplier: number = 1) {\n // Start the timer immediately and keep it running\n const tickInterval = BASE_TICK_INTERVAL * this.multiplier;\n this.intervalId = setTimeout(() => this.tick(), tickInterval);\n }\n\n addQuery(instance: QueryResultImpl<any>) {\n if (instance.def.type === QueryType.Stream) {\n return; // Streams don't have refetch intervals\n }\n\n const interval = instance.def.cache?.refetchInterval;\n\n if (!interval) {\n return;\n }\n\n const actualInterval = interval * this.multiplier;\n // Add to bucket by actual interval\n let bucket = this.buckets.get(actualInterval);\n if (!bucket) {\n bucket = new Set();\n this.buckets.set(actualInterval, bucket);\n }\n bucket.add(instance);\n }\n\n removeQuery(query: QueryResultImpl<any>) {\n if (query.def.type === QueryType.Stream) {\n return; // Streams don't have refetch intervals\n }\n\n const interval = query.def.cache?.refetchInterval;\n\n if (!interval) {\n return;\n }\n\n const actualInterval = interval * this.multiplier;\n // Remove from bucket\n const bucket = this.buckets.get(actualInterval);\n if (bucket) {\n bucket.delete(query);\n\n if (bucket.size === 0) {\n this.buckets.delete(actualInterval);\n }\n }\n }\n\n private tick() {\n this.clock += BASE_TICK_INTERVAL * this.multiplier;\n\n // Only process buckets where clock is aligned with the interval\n for (const [interval, bucket] of this.buckets.entries()) {\n if (this.clock % interval === 0) {\n // Process all queries in this bucket\n for (const query of bucket) {\n // Skip if already fetching - let the current fetch complete\n if (query && !query.isFetching) {\n query.refetch();\n }\n }\n }\n }\n\n const tickInterval = BASE_TICK_INTERVAL * this.multiplier;\n this.intervalId = setTimeout(() => this.tick(), tickInterval);\n }\n\n destroy(): void {\n clearTimeout(this.intervalId);\n }\n}\n\n// No-op implementation for SSR environments where timers are not needed\nexport class NoOpRefetchManager {\n addQuery(_instance: QueryResultImpl<any>): void {\n // No-op: do nothing\n }\n\n removeQuery(_query: QueryResultImpl<any>): void {\n // No-op: do nothing\n }\n\n destroy(): void {\n // No-op: do nothing\n }\n}\n","import { type QueryClient } from './QueryClient.js';\n\nconst EVICTION_INTERVAL = 60 * 1000; // 1 minute\n\n// Memory eviction manager - uses a single interval with rotating sets to avoid timeout overhead\nexport class MemoryEvictionManager {\n private intervalId: NodeJS.Timeout;\n private currentFlush = new Set<number>(); // Queries to evict on next tick\n private nextFlush = new Set<number>(); // Queries to evict on tick after next\n\n constructor(\n private queryClient: QueryClient,\n private multiplier: number = 1,\n ) {\n this.intervalId = setInterval(this.tick, EVICTION_INTERVAL * this.multiplier);\n }\n\n scheduleEviction(queryKey: number) {\n // Add to nextFlush so it waits at least one full interval\n // This prevents immediate eviction if scheduled right before a tick\n this.nextFlush.add(queryKey);\n }\n\n cancelEviction(queryKey: number) {\n // Remove from both sets to handle reactivation\n this.currentFlush.delete(queryKey);\n this.nextFlush.delete(queryKey);\n }\n\n private tick = () => {\n if (!this.queryClient) return;\n\n // Evict all queries in currentFlush\n for (const queryKey of this.currentFlush) {\n this.queryClient.queryInstances.delete(queryKey);\n }\n\n // Rotate: currentFlush becomes nextFlush, nextFlush becomes empty\n this.currentFlush = this.nextFlush;\n this.nextFlush = new Set();\n };\n\n destroy(): void {\n clearInterval(this.intervalId);\n }\n}\n\n// No-op implementation for SSR environments where timers are not needed\nexport class NoOpMemoryEvictionManager {\n scheduleEviction(_queryKey: number): void {\n // No-op: do nothing\n }\n\n cancelEviction(_queryKey: number): void {\n // No-op: do nothing\n }\n\n destroy(): void {\n // No-op: do nothing\n }\n}\n","/**\n * Query Client with Entity Caching and Deduplication\n *\n * Features:\n * - Global entity map for deduplication\n * - Entity definitions with cached sub-entity paths\n * - Eager entity discovery and caching\n * - Permanent proxy cache for entities\n * - Response caching for offline access\n * - Signalium-based reactivity for entity updates\n * - Self-contained validator (no external dependencies except Signalium)\n */\n\nimport { context, type Context } from 'signalium';\nimport { hashValue } from 'signalium/utils';\nimport {\n QueryResult,\n EntityDef,\n RefetchInterval,\n NetworkMode,\n RetryConfig,\n TypeDef,\n UnionDef,\n BaseUrlValue,\n QueryRequestInit,\n MutationResult,\n} from './types.js';\nimport { EntityRecord, EntityStore } from './EntityMap.js';\nimport { NetworkManager } from './NetworkManager.js';\nimport { QueryResultImpl } from './QueryResult.js';\nimport { MutationResultImpl } from './MutationResult.js';\nimport { MutationDefinition } from './mutation.js';\nimport { RefetchManager } from './RefetchManager.js';\nimport { MemoryEvictionManager } from './MemoryEvictionManager.js';\nimport { type Signal } from 'signalium';\n\n// -----------------------------------------------------------------------------\n// Query Types\n// -----------------------------------------------------------------------------\n\nexport interface QueryContext {\n fetch: (url: string, init?: QueryRequestInit) => Promise<Response>;\n baseUrl?: BaseUrlValue;\n log?: {\n error?: (message: string, error?: unknown) => void;\n warn?: (message: string, error?: unknown) => void;\n info?: (message: string) => void;\n debug?: (message: string) => void;\n };\n evictionMultiplier?: number;\n refetchMultiplier?: number;\n}\n\n/**\n * Resolves a BaseUrlValue to a string.\n * Handles static strings, Signals, and functions.\n */\nexport function resolveBaseUrl(baseUrl: BaseUrlValue | undefined): string | undefined {\n if (baseUrl === undefined) return undefined;\n if (typeof baseUrl === 'string') return baseUrl;\n if (typeof baseUrl === 'function') return baseUrl();\n return baseUrl.value; // Signal\n}\n\nexport interface QueryCacheOptions {\n maxCount?: number;\n gcTime?: number; // milliseconds - only applies to on-disk/persistent storage cleanup\n staleTime?: number;\n refetchInterval?: RefetchInterval;\n networkMode?: NetworkMode; // default: NetworkMode.Online\n retry?: RetryConfig | number | false; // default: 3 on client, 0 on server\n refreshStaleOnReconnect?: boolean; // default: true\n}\n\nexport interface StreamCacheOptions {\n maxCount?: number;\n gcTime?: number; // milliseconds - only applies to on-disk/persistent storage cleanup\n}\n\nexport interface QueryPaginationOptions<Result> {\n getNextPageParams?(lastPage: Result, params?: QueryParams | undefined): QueryParams | undefined;\n}\n\nexport type QueryParams = Record<\n string,\n string | number | boolean | undefined | null | Signal<string | number | boolean | undefined | null>\n>;\n\nexport const enum QueryType {\n Query = 'query',\n InfiniteQuery = 'infiniteQuery',\n Stream = 'stream',\n}\n\nexport type StreamSubscribeFn<Params extends QueryParams | undefined, StreamType> = (\n context: QueryContext,\n params: Params,\n onUpdate: (update: StreamType) => void,\n) => () => void;\n\nexport interface QueryDefinition<Params extends QueryParams | undefined, Result, StreamType> {\n type: QueryType.Query;\n id: string;\n shape: TypeDef;\n shapeKey: number;\n fetchFn: (context: QueryContext, params: Params, prevResult?: Result) => Promise<Result>;\n debounce?: number;\n cache?: QueryCacheOptions;\n stream?: {\n shape: TypeDef;\n shapeKey: number;\n subscribeFn: StreamSubscribeFn<Params, StreamType>;\n };\n optimisticInserts?: {\n shape: TypeDef;\n shapeKey: number;\n };\n}\n\nexport interface InfiniteQueryDefinition<Params extends QueryParams | undefined, Result, StreamType> {\n type: QueryType.InfiniteQuery;\n id: string;\n shape: TypeDef;\n shapeKey: number;\n fetchFn: (context: QueryContext, params: Params, prevResult?: Result) => Promise<Result>;\n pagination: QueryPaginationOptions<Result>;\n debounce?: number;\n cache?: QueryCacheOptions;\n stream?: {\n shape: TypeDef;\n shapeKey: number;\n subscribeFn: StreamSubscribeFn<Params, StreamType>;\n };\n optimisticInserts?: {\n shape: TypeDef;\n shapeKey: number;\n };\n}\n\nexport interface StreamQueryDefinition<Params extends QueryParams | undefined, StreamType> {\n type: QueryType.Stream;\n id: string;\n shape: EntityDef; // Must be entity\n shapeKey: number;\n subscribeFn: StreamSubscribeFn<Params, StreamType>;\n cache?: StreamCacheOptions;\n}\n\nexport type AnyQueryDefinition<Params extends QueryParams | undefined, Result, Event> =\n | QueryDefinition<Params, Result, Event>\n | InfiniteQueryDefinition<Params, Result, Event>\n | StreamQueryDefinition<Params, Event>;\n\n// -----------------------------------------------------------------------------\n// QueryStore Interface\n// -----------------------------------------------------------------------------\n\nexport interface CachedQuery {\n value: unknown;\n refIds: Set<number> | undefined;\n updatedAt: number;\n extra?: CachedQueryExtra;\n}\n\nexport interface CachedQueryExtra {\n streamOrphanRefs?: number[];\n optimisticInsertRefs?: number[];\n}\n\nexport interface QueryStore {\n /**\n * Asynchronously retrieves a document by key.\n * May return undefined if the document is not in the store.\n */\n loadQuery(\n queryDef: QueryDefinition<any, any, any>,\n queryKey: number,\n entityMap: EntityStore,\n ): MaybePromise<CachedQuery | undefined>;\n\n /**\n * Synchronously stores a document with optional reference IDs.\n * This is fire-and-forget for async implementations.\n */\n saveQuery(\n queryDef: QueryDefinition<any, any, any>,\n queryKey: number,\n value: unknown,\n updatedAt: number,\n refIds?: Set<number>,\n extra?: CachedQueryExtra,\n ): void;\n\n /**\n * Synchronously stores an entity with optional reference IDs.\n * This is fire-and-forget for async implementations.\n */\n saveEntity(entityKey: number, value: unknown, refIds?: Set<number>): void;\n\n /**\n * Marks a query as accessed, updating the LRU queue.\n * Handles eviction internally when the cache is full.\n */\n activateQuery(queryDef: QueryDefinition<any, any, any>, queryKey: number): void;\n\n deleteQuery(queryKey: number): void;\n}\n\nexport type MaybePromise<T> = T | Promise<T>;\n\n/**\n * Checks if a value is a Signal instance\n */\nfunction isSignal(value: unknown): value is Signal<any> {\n return typeof value === 'object' && value !== null;\n}\n\n/**\n * Extracts actual values from params that may contain Signals.\n */\nexport function extractParamsForKey(\n params: QueryParams | undefined,\n): Record<string, string | number | boolean | undefined | null> | undefined {\n if (params === undefined) {\n return undefined;\n }\n\n const extracted: Record<string, string | number | boolean | undefined | null> = {};\n\n for (const [key, value] of Object.entries(params)) {\n if (isSignal(value)) {\n extracted[key] = value.value as string | number | boolean | undefined | null;\n } else {\n extracted[key] = value as string | number | boolean | undefined | null;\n }\n }\n\n return extracted;\n}\n\n/**\n * Computes the query key for instance lookup. This is used for two different keys:\n *\n * - Query instance key\n * - Query storage key\n *\n * Instance keys are created by passing in the query definition and parameters WITHOUT\n * extracting the Signal values, whereas storage keys are created by extracting the Signal values.\n * This way, we can reuse the same instance for given Signals, but different underlying values\n * will be stored and put into the LRU cache separately.\n */\nexport const queryKeyFor = (queryDef: AnyQueryDefinition<any, any, any>, params: unknown): number => {\n return hashValue([queryDef.id, queryDef.shapeKey, params]);\n};\n\nexport class QueryClient {\n private entityMap: EntityStore;\n queryInstances = new Map<number, QueryResultImpl<unknown>>();\n mutationInstances = new Map<string, MutationResultImpl<unknown, unknown>>();\n memoryEvictionManager: MemoryEvictionManager;\n refetchManager: RefetchManager;\n networkManager: NetworkManager;\n isServer: boolean;\n\n constructor(\n private store: QueryStore,\n private context: QueryContext = { fetch, log: console },\n networkManager?: NetworkManager,\n memoryEvictionManager?: MemoryEvictionManager,\n refetchManager?: RefetchManager,\n ) {\n this.memoryEvictionManager =\n memoryEvictionManager ?? new MemoryEvictionManager(this, this.context.evictionMultiplier);\n this.refetchManager = refetchManager ?? new RefetchManager(this.context.refetchMultiplier);\n this.networkManager = networkManager ?? new NetworkManager();\n this.isServer = typeof window === 'undefined';\n this.entityMap = new EntityStore(this);\n }\n\n getContext(): QueryContext {\n return this.context;\n }\n\n saveQueryData(\n queryDef: AnyQueryDefinition<QueryParams | undefined, unknown, unknown>,\n queryKey: number,\n data: unknown,\n updatedAt: number,\n entityRefs?: Set<number>,\n extra?: CachedQueryExtra,\n ): void {\n // Clone entityRefs to avoid mutation in setValue\n const clonedRefs = entityRefs !== undefined ? new Set(entityRefs) : undefined;\n // QueryStore expects the base definition structure\n this.store.saveQuery(queryDef as any, queryKey, data, updatedAt, clonedRefs, extra);\n }\n\n activateQuery(queryInstance: QueryResultImpl<unknown>): void {\n const { def, queryKey, storageKey } = queryInstance;\n // Use storageKey for cache operations (store.activateQuery)\n this.store.activateQuery(def as any, storageKey);\n\n // Only add to refetch manager if it's not a stream\n if (def.type !== QueryType.Stream && def.cache?.refetchInterval) {\n this.refetchManager.addQuery(queryInstance);\n }\n // Use queryKey for instance eviction (memoryEvictionManager)\n this.memoryEvictionManager.cancelEviction(queryKey);\n }\n\n loadCachedQuery(queryDef: AnyQueryDefinition<QueryParams | undefined, unknown, unknown>, queryKey: number) {\n return this.store.loadQuery(queryDef as any, queryKey, this.entityMap);\n }\n\n deleteCachedQuery(queryKey: number): void {\n this.store.deleteQuery(queryKey);\n }\n\n /**\n * Loads a query from the document store and returns a QueryResult\n * that triggers fetches and prepopulates with cached data\n */\n getQuery<T>(\n queryDef: AnyQueryDefinition<any, any, any>,\n params: QueryParams | undefined,\n ): QueryResult<T, unknown, unknown> {\n const queryKey = queryKeyFor(queryDef, params);\n\n let queryInstance = this.queryInstances.get(queryKey) as QueryResultImpl<T> | undefined;\n\n // Create a new instance if it doesn't exist\n if (queryInstance === undefined) {\n queryInstance = new QueryResultImpl(queryDef, this, queryKey, params);\n\n // Store for future use\n this.queryInstances.set(queryKey, queryInstance as QueryResultImpl<unknown>);\n }\n\n return queryInstance as unknown as QueryResult<T, unknown, unknown>;\n }\n\n /**\n * Gets or creates a MutationResult for the given mutation definition.\n * Mutations are cached by their definition ID.\n */\n getMutation<Request, Response>(\n mutationDef: MutationDefinition<Request, Response>,\n ): MutationResult<Request, Response> {\n const mutationId = mutationDef.id;\n\n let mutationInstance = this.mutationInstances.get(mutationId) as MutationResultImpl<Request, Response> | undefined;\n\n // Create a new instance if it doesn't exist\n if (mutationInstance === undefined) {\n mutationInstance = new MutationResultImpl(mutationDef, this);\n\n // Store for future use\n this.mutationInstances.set(mutationId, mutationInstance as MutationResultImpl<unknown, unknown>);\n }\n\n return mutationInstance as MutationResult<Request, Response>;\n }\n\n // ======================================================\n // Optimistic Update Management\n // ======================================================\n\n /**\n * Register pending optimistic updates for an entity.\n * Called by MutationResult when applying optimistic updates.\n */\n registerOptimisticUpdate(entityKey: number, fields: Record<string, unknown>): void {\n this.entityMap.registerOptimisticUpdate(entityKey, fields);\n }\n\n /**\n * Clear pending optimistic updates for an entity without reverting.\n * Called by MutationResult when mutation succeeds.\n */\n clearOptimisticUpdates(entityKey: number): void {\n this.entityMap.clearOptimisticUpdates(entityKey);\n }\n\n /**\n * Revert pending optimistic updates for an entity, restoring its snapshot.\n * Called by MutationResult when mutation fails.\n */\n revertOptimisticUpdate(entityKey: number): void {\n this.entityMap.revertOptimisticUpdate(entityKey);\n }\n\n hydrateEntity(key: number, shape: EntityDef): EntityRecord {\n return this.entityMap.hydratePreloadedEntity(key, shape);\n }\n\n saveEntity(key: number, obj: Record<string, unknown>, shape: EntityDef, entityRefs?: Set<number>): EntityRecord {\n // console.log('saveEntity', key, JSON.stringify(obj, null, 2), shape, entityRefs, new Error().stack);\n\n const record = this.entityMap.setEntity(key, obj, shape, entityRefs);\n\n // console.log('saveEntity record', JSON.stringify(obj, null, 2), new Error().stack);\n\n this.store.saveEntity(key, obj, entityRefs);\n\n return record;\n }\n\n getNestedEntityRefIds(key: number, refIds: Set<number>): Set<number> {\n return this.entityMap.getNestedEntityRefIds(key, refIds);\n }\n\n destroy(): void {\n this.refetchManager.destroy();\n this.memoryEvictionManager.destroy();\n }\n}\n\nexport const QueryClientContext: Context<QueryClient | undefined> = context<QueryClient | undefined>(undefined);\n\n/**\n * Add an optimistic insert to a query result.\n * The insert will be automatically removed when:\n * - The entity appears in a refetched response\n * - The entity appears as a stream orphan\n * - refetch() is called\n */\nexport function addOptimisticInsert<T extends Record<string, unknown>>(\n query: QueryResult<unknown, unknown, unknown>,\n insert: T,\n): void {\n (query as unknown as QueryResultImpl<unknown>).addOptimisticInsert(insert);\n}\n\n/**\n * Remove an optimistic insert from a query result.\n * This is a no-op if the insert has already been removed.\n */\nexport function removeOptimisticInsert<T extends Record<string, unknown>>(\n query: QueryResult<unknown, unknown, unknown>,\n insert: T,\n): void {\n (query as unknown as QueryResultImpl<unknown>).removeOptimisticInsert(insert);\n}\n","/**\n * Path interpolation utilities for URL templates with parameter substitution.\n *\n * Converts path templates like \"/users/{userId}/posts/{postId}\" into functions\n * that efficiently interpolate parameter values.\n *\n * The implementation pre-parses the path template once into segments and parameter\n * keys, then uses simple string concatenation at runtime for optimal performance.\n */\n\nexport type PathInterpolator = (params: Record<string, any>) => string;\n\n/**\n * Creates an optimized path interpolation function from a URL template.\n *\n * The template uses curly braces for parameters (e.g., \"/items/{id}\").\n * Parameter values are URL-encoded when interpolated. Any parameters not\n * found in the path template are appended as query string parameters.\n *\n * @param pathTemplate - URL template with {paramName} placeholders\n * @returns Function that interpolates parameters into the path with search params\n *\n * @example\n * ```ts\n * const interpolate = createPathInterpolator('/users/{userId}/posts/{postId}');\n * const url = interpolate({ userId: '123', postId: '456', page: 2, limit: 10 });\n * // Returns: \"/users/123/posts/456?page=2&limit=10\"\n * ```\n */\nexport function createPathInterpolator(pathTemplate: string): PathInterpolator {\n // Pre-parse path into segments and param keys (parse once, concatenate many times)\n const segments: string[] = [];\n const paramKeys: string[] = [];\n const paramKeysSet = new Set<string>();\n let lastIndex = 0;\n const paramRegex = /\\[([^\\]]+)\\]/g;\n let match: RegExpExecArray | null;\n\n while ((match = paramRegex.exec(pathTemplate)) !== null) {\n segments.push(pathTemplate.slice(lastIndex, match.index));\n paramKeys.push(match[1]);\n paramKeysSet.add(match[1]);\n lastIndex = paramRegex.lastIndex;\n }\n segments.push(pathTemplate.slice(lastIndex));\n\n // Return optimized interpolation function with pre-parsed segments\n return (params: Record<string, any>): string => {\n // Build the path with interpolated path parameters\n let result = segments[0];\n for (let i = 0; i < paramKeys.length; i++) {\n result += encodeURIComponent(String(params[paramKeys[i]])) + segments[i + 1];\n }\n\n // Collect remaining parameters as search params\n let searchParams: URLSearchParams | null = null;\n for (const key in params) {\n if (!paramKeysSet.has(key) && params[key] !== undefined) {\n if (searchParams === null) {\n searchParams = new URLSearchParams();\n }\n\n searchParams.append(key, String(params[key]));\n }\n }\n\n // Append search params if any exist\n if (searchParams !== null) {\n result += '?' + searchParams.toString();\n }\n\n return result;\n };\n}\n","import { getContext, reactive } from 'signalium';\nimport {\n QueryResult,\n Mask,\n ObjectFieldTypeDef,\n UnionDef,\n QueryFn,\n InfiniteQueryFn,\n ExtractTypesFromObjectOrEntity,\n EntityDef,\n StreamQueryFn,\n TypeDef,\n QueryRequestOptions,\n} from './types.js';\nimport {\n QueryCacheOptions,\n QueryClientContext,\n QueryContext,\n QueryDefinition,\n QueryParams,\n StreamCacheOptions,\n QueryType,\n queryKeyFor,\n resolveBaseUrl,\n} from './QueryClient.js';\nimport { entity, t, ValidatorDef } from './typeDefs.js';\nimport { createPathInterpolator } from './pathInterpolator.js';\nimport { hashValue } from 'signalium/utils';\n\ntype IsParameter<Part> = Part extends `[${infer ParamName}]` ? ParamName : never;\ntype FilteredParts<Path> = Path extends `${infer PartA}/${infer PartB}`\n ? IsParameter<PartA> | FilteredParts<PartB>\n : IsParameter<Path>;\ntype ParamValue<Key> = Key extends `...${infer Anything}` ? (string | number)[] : string | number;\ntype RemovePrefixDots<Key> = Key extends `...${infer Name}` ? Name : Key;\ntype PathParams<Path> = {\n [Key in FilteredParts<Path> as RemovePrefixDots<Key>]: ParamValue<Key>;\n};\n\ntype SearchParamsType =\n | Mask.NUMBER\n | Mask.STRING\n | Mask.BOOLEAN\n | Mask.UNDEFINED\n | Mask.NULL\n | Set<string | boolean | number>;\ntype SearchParamsDefinition = Record<string, SearchParamsType | UnionDef<SearchParamsType[]>>;\n\ninterface StreamOptions<\n Params extends SearchParamsDefinition,\n Event extends Record<string, ObjectFieldTypeDef> | ObjectFieldTypeDef,\n> {\n type: Event;\n subscribe: (\n context: QueryContext,\n params: ExtractTypesFromObjectOrEntity<Params>,\n onUpdate: (update: Partial<ExtractTypesFromObjectOrEntity<Event>>) => void,\n ) => () => void;\n}\n\n// Map for getting query definitions by function reference, for testing\n// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\nconst QUERY_DEFINITION_MAP = new Map<Function, () => QueryDefinition<any, any, any>>();\n\n// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\nexport const queryKeyForFn = (fn: Function, params: unknown): number => {\n const queryDef = QUERY_DEFINITION_MAP.get(fn);\n\n if (queryDef === undefined) {\n throw new Error('Query definition not found');\n }\n\n return queryKeyFor(queryDef(), params);\n};\n\ninterface OptimisticInsertOptions<OptimisticInsertDef extends EntityDef | UnionDef<EntityDef[]>> {\n type: OptimisticInsertDef;\n}\n\n/**\n * BIG TODO:\n *\n * All of the `any` types in this file need to be removed, but we need to figure\n * out why we're getting so many infinite recursion errors with types first. When\n * we remove them, the types should work without the `any`s.\n */\ninterface RESTQueryDefinition<\n Path extends string,\n SearchParams extends SearchParamsDefinition,\n ResponseDef extends Record<string, ObjectFieldTypeDef> | ObjectFieldTypeDef,\n StreamEntityDef extends EntityDef | UnionDef<EntityDef[]> | undefined = undefined,\n OptimisticInsertDef extends EntityDef | UnionDef<EntityDef[]> | undefined = undefined,\n> {\n path: Path;\n method?: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';\n searchParams?: SearchParams;\n response: ResponseDef;\n requestOptions?: QueryRequestOptions;\n cache?: QueryCacheOptions;\n stream?: StreamEntityDef extends EntityDef | UnionDef<EntityDef[]>\n ? StreamOptions<SearchParams, StreamEntityDef>\n : undefined;\n optimisticInserts?: OptimisticInsertDef extends EntityDef | UnionDef<EntityDef[]>\n ? OptimisticInsertOptions<OptimisticInsertDef>\n : undefined;\n debounce?: number;\n}\n\ninterface InfiniteRESTQueryDefinition<\n Path extends string,\n SearchParams extends SearchParamsDefinition,\n ResponseDef extends Record<string, ObjectFieldTypeDef> | ObjectFieldTypeDef,\n StreamEntityDef extends EntityDef | UnionDef<EntityDef[]> | undefined = undefined,\n OptimisticInsertDef extends EntityDef | UnionDef<EntityDef[]> | undefined = undefined,\n> {\n path: Path;\n method?: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';\n searchParams?: SearchParams;\n response: ResponseDef;\n requestOptions?: QueryRequestOptions;\n cache?: QueryCacheOptions;\n stream?: StreamEntityDef extends EntityDef | UnionDef<EntityDef[]>\n ? StreamOptions<SearchParams, StreamEntityDef>\n : undefined;\n optimisticInserts?: OptimisticInsertDef extends EntityDef | UnionDef<EntityDef[]>\n ? OptimisticInsertOptions<OptimisticInsertDef>\n : undefined;\n pagination: {\n getNextPageParams?(\n lastPage: ExtractTypesFromObjectOrEntity<ResponseDef>,\n params?: ExtractTypesFromObjectOrEntity<SearchParams> | undefined,\n ): QueryParams | undefined;\n };\n debounce?: number;\n}\n\ntype ExtractQueryParams<Path extends string, SearchParams extends SearchParamsDefinition> = PathParams<Path> &\n ExtractTypesFromObjectOrEntity<SearchParams>;\n\ninterface StreamQueryDefinitionBuilder<\n Params extends SearchParamsDefinition,\n Response extends Record<string, ObjectFieldTypeDef> | ObjectFieldTypeDef,\n> {\n id: string;\n params?: Params;\n response: Response;\n subscribe: (\n params: ExtractTypesFromObjectOrEntity<Params>,\n onUpdate: (update: Partial<ExtractTypesFromObjectOrEntity<Response>>) => void,\n ) => () => void;\n cache?: StreamCacheOptions;\n}\n\nfunction buildQueryFn(\n queryDefinitionBuilder: () =>\n | RESTQueryDefinition<\n string,\n SearchParamsDefinition,\n ObjectFieldTypeDef | Record<string, ObjectFieldTypeDef>,\n EntityDef | UnionDef<EntityDef[]>\n >\n | InfiniteRESTQueryDefinition<\n string,\n SearchParamsDefinition,\n ObjectFieldTypeDef | Record<string, ObjectFieldTypeDef>,\n EntityDef | UnionDef<EntityDef[]>\n >,\n): QueryDefinition<QueryParams, unknown, unknown> {\n let queryDefinition: any | undefined;\n\n const getQueryDefinition = () => {\n if (queryDefinition === undefined) {\n const {\n path,\n method = 'GET',\n response,\n requestOptions,\n cache,\n pagination,\n stream,\n optimisticInserts,\n debounce,\n } = queryDefinitionBuilder() as InfiniteRESTQueryDefinition<any, any, any, any, any>;\n\n const id = `${method}:${path}`;\n\n let shape: TypeDef;\n let shapeKey: number;\n\n if (typeof response === 'object') {\n if (response instanceof ValidatorDef) {\n shape = response as TypeDef;\n shapeKey = response.shapeKey;\n } else if (response instanceof Set) {\n shape = response;\n shapeKey = hashValue(response);\n } else {\n shape = t.object(response as Record<string, ObjectFieldTypeDef>);\n shapeKey = shape.shapeKey;\n }\n } else {\n shape = response as Mask;\n shapeKey = hashValue(shape);\n }\n\n // Create optimized path interpolator (parses template once)\n const interpolatePath = createPathInterpolator(path);\n\n const fetchFn = async (context: QueryContext, params: QueryParams) => {\n // Interpolate path params and append search params automatically\n const interpolatedPath = interpolatePath(params);\n\n // Resolve baseUrl: query-level requestOptions overrides context-level\n const baseUrl = resolveBaseUrl(requestOptions?.baseUrl) ?? resolveBaseUrl(context.baseUrl);\n const fullUrl = baseUrl ? `${baseUrl}${interpolatedPath}` : interpolatedPath;\n\n // Extract request init options (excluding baseUrl which is not a valid RequestInit property)\n const { baseUrl: _baseUrl, ...fetchOptions } = requestOptions ?? {};\n\n const response = await context.fetch(fullUrl, {\n method,\n ...fetchOptions,\n });\n\n return response.json();\n };\n\n // Process stream configuration if provided\n let streamConfig: any = undefined;\n if (stream) {\n let streamShape: TypeDef;\n let streamShapeKey: number;\n\n const eventDef = stream.type;\n\n if (typeof eventDef === 'object') {\n if (eventDef instanceof ValidatorDef) {\n streamShape = eventDef as TypeDef;\n streamShapeKey = eventDef.shapeKey;\n } else if (eventDef instanceof Set) {\n streamShape = eventDef;\n streamShapeKey = hashValue(eventDef);\n } else {\n streamShape = t.object(eventDef as Record<string, ObjectFieldTypeDef>);\n streamShapeKey = streamShape.shapeKey;\n }\n } else {\n streamShape = eventDef as Mask;\n streamShapeKey = hashValue(streamShape);\n }\n\n streamConfig = {\n shape: streamShape,\n shapeKey: streamShapeKey,\n subscribeFn: (context: QueryContext, params: QueryParams | undefined, onUpdate: any) => {\n return (stream.subscribe as any)(context, params as any, onUpdate);\n },\n };\n }\n\n // Process optimistic inserts configuration if provided\n let optimisticInsertsConfig: any = undefined;\n if (optimisticInserts) {\n let insertShape: TypeDef;\n let insertShapeKey: number;\n\n const insertDef = optimisticInserts.type;\n\n if (typeof insertDef === 'object') {\n if (insertDef instanceof ValidatorDef) {\n insertShape = insertDef as TypeDef;\n insertShapeKey = insertDef.shapeKey;\n } else if (insertDef instanceof Set) {\n insertShape = insertDef;\n insertShapeKey = hashValue(insertDef);\n } else {\n insertShape = t.object(insertDef as Record<string, ObjectFieldTypeDef>);\n insertShapeKey = insertShape.shapeKey;\n }\n } else {\n insertShape = insertDef as Mask;\n insertShapeKey = hashValue(insertShape);\n }\n\n optimisticInsertsConfig = {\n shape: insertShape,\n shapeKey: insertShapeKey,\n };\n }\n\n queryDefinition = {\n type: pagination ? QueryType.InfiniteQuery : QueryType.Query,\n id,\n shape,\n shapeKey,\n fetchFn,\n pagination,\n cache,\n stream: streamConfig,\n optimisticInserts: optimisticInsertsConfig,\n debounce,\n };\n }\n\n return queryDefinition;\n };\n\n const queryFn = reactive(\n (params: QueryParams | undefined): QueryResult<unknown, unknown, unknown> => {\n const queryClient = getContext(QueryClientContext);\n\n if (queryClient === undefined) {\n throw new Error('QueryClient not found');\n }\n\n return queryClient.getQuery<unknown>(getQueryDefinition(), params);\n },\n // TODO: Getting a lot of type errors due to infinite recursion here.\n // For now, we return as any to coerce to the external type signature,\n // and internally we manage the difference.\n ) as any;\n\n QUERY_DEFINITION_MAP.set(queryFn, getQueryDefinition);\n\n return queryFn;\n}\n\nexport function query<\n Path extends string,\n SearchParams extends SearchParamsDefinition,\n Response extends Record<string, ObjectFieldTypeDef> | ObjectFieldTypeDef,\n EventDef extends EntityDef | UnionDef<EntityDef[]> | undefined = undefined,\n OptimisticUpdateDef extends EntityDef | UnionDef<EntityDef[]> | undefined = undefined,\n>(\n queryDefinitionBuilder: () => RESTQueryDefinition<Path, SearchParams, Response, EventDef, OptimisticUpdateDef>,\n): QueryFn<ExtractQueryParams<Path, SearchParams>, Response, EventDef, OptimisticUpdateDef> {\n return buildQueryFn(queryDefinitionBuilder as any) as any;\n}\n\nexport function infiniteQuery<\n Path extends string,\n SearchParams extends SearchParamsDefinition,\n Response extends Record<string, ObjectFieldTypeDef> | ObjectFieldTypeDef,\n EventDef extends EntityDef | UnionDef<EntityDef[]> | undefined = undefined,\n OptimisticInsertDef extends EntityDef | UnionDef<EntityDef[]> | undefined = undefined,\n>(\n queryDefinitionBuilder: () => InfiniteRESTQueryDefinition<\n Path,\n SearchParams,\n Response,\n EventDef,\n OptimisticInsertDef\n >,\n): InfiniteQueryFn<ExtractQueryParams<Path, SearchParams>, Response, EventDef, OptimisticInsertDef> {\n return buildQueryFn(queryDefinitionBuilder as any) as any;\n}\n\nexport function streamQuery<\n // TODO: This is a hack to get the type signature to work. We should find a better way to do this.\n Path extends '',\n Params extends SearchParamsDefinition,\n Response extends EntityDef | UnionDef<EntityDef[]>,\n>(\n queryDefinitionBuilder: () => StreamQueryDefinitionBuilder<Params, Response>,\n): StreamQueryFn<ExtractQueryParams<Path, Params>, Response> {\n let streamDefinition: any | undefined;\n\n const getStreamDefinition = () => {\n if (streamDefinition === undefined) {\n const { id, response, subscribe, cache } = queryDefinitionBuilder();\n\n // Validate that response is an EntityDef\n if (!(response instanceof ValidatorDef) || (response.mask & Mask.ENTITY) === 0) {\n throw new Error('Stream query response must be an EntityDef');\n }\n\n streamDefinition = {\n type: QueryType.Stream,\n id,\n shape: response as EntityDef,\n shapeKey: response.shapeKey,\n subscribeFn: (context: QueryContext, params: QueryParams | undefined, onUpdate: any) => {\n return (subscribe as any)(params as any, onUpdate);\n },\n cache,\n };\n }\n return streamDefinition;\n };\n\n const streamFn = reactive((params: QueryParams | undefined): QueryResult<unknown, unknown, unknown> => {\n const queryClient = getContext(QueryClientContext);\n\n if (queryClient === undefined) {\n throw new Error('QueryClient not found');\n }\n\n return queryClient.getQuery<unknown>(getStreamDefinition(), params);\n }) as any;\n\n QUERY_DEFINITION_MAP.set(streamFn, getStreamDefinition);\n\n return streamFn;\n}\n","import { getContext } from 'signalium';\nimport {\n MutationResult,\n MutationFn,\n Mask,\n ObjectFieldTypeDef,\n UnionDef,\n ExtractTypesFromObjectOrEntity,\n EntityDef,\n TypeDef,\n RetryConfig,\n} from './types.js';\nimport { QueryClientContext, QueryContext } from './QueryClient.js';\nimport { t, ValidatorDef } from './typeDefs.js';\nimport { createPathInterpolator } from './pathInterpolator.js';\nimport { hashValue } from 'signalium/utils';\n\ntype IsParameter<Part> = Part extends `[${infer ParamName}]` ? ParamName : never;\ntype FilteredParts<Path> = Path extends `${infer PartA}/${infer PartB}`\n ? IsParameter<PartA> | FilteredParts<PartB>\n : IsParameter<Path>;\ntype ParamValue<Key> = Key extends `...${infer Anything}` ? (string | number)[] : string | number;\ntype RemovePrefixDots<Key> = Key extends `...${infer Name}` ? Name : Key;\ntype PathParams<Path> = {\n [Key in FilteredParts<Path> as RemovePrefixDots<Key>]: ParamValue<Key>;\n};\n\n// -----------------------------------------------------------------------------\n// Mutation Definition Types\n// -----------------------------------------------------------------------------\n\nexport interface MutationCacheOptions {\n /**\n * Retry configuration for failed mutations\n */\n retry?: RetryConfig | number | false;\n}\n\nexport interface MutationDefinition<Request, Response> {\n id: string;\n requestShape: TypeDef;\n requestShapeKey: number;\n responseShape: TypeDef;\n responseShapeKey: number;\n mutateFn: (context: QueryContext, request: Request) => Promise<Response>;\n optimisticUpdates: boolean;\n cache?: MutationCacheOptions;\n}\n\n// Map for getting mutation definitions by function reference, for testing\n// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\nconst MUTATION_DEFINITION_MAP = new Map<Function, () => MutationDefinition<any, any>>();\n\n// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\nexport const mutationKeyFor = (fn: Function): string => {\n const mutationDef = MUTATION_DEFINITION_MAP.get(fn);\n\n if (mutationDef === undefined) {\n throw new Error('Mutation definition not found');\n }\n\n return mutationDef().id;\n};\n\n// -----------------------------------------------------------------------------\n// REST Mutation Definition\n// -----------------------------------------------------------------------------\n\ninterface RESTMutationDefinition<\n Path extends string,\n RequestDef extends Record<string, ObjectFieldTypeDef> | ObjectFieldTypeDef,\n ResponseDef extends Record<string, ObjectFieldTypeDef> | ObjectFieldTypeDef,\n> {\n /**\n * The URL path for the mutation. Supports path parameters like `/users/[id]`.\n */\n path: Path;\n /**\n * HTTP method for the mutation. Defaults to POST.\n */\n method?: 'POST' | 'PUT' | 'DELETE' | 'PATCH';\n /**\n * TypeDef for the request body.\n */\n request: RequestDef;\n /**\n * TypeDef for the response body.\n */\n response: ResponseDef;\n /**\n * Whether to automatically apply optimistic updates.\n * When true, entities in the request will be immediately updated in the store\n * before the mutation completes, and reverted if the mutation fails.\n * Defaults to false.\n */\n optimisticUpdates?: boolean;\n /**\n * Cache options including retry configuration.\n */\n cache?: MutationCacheOptions;\n}\n\ntype ExtractMutationRequest<\n Path extends string,\n RequestDef extends Record<string, ObjectFieldTypeDef> | ObjectFieldTypeDef,\n> = PathParams<Path> & ExtractTypesFromObjectOrEntity<RequestDef>;\n\n// -----------------------------------------------------------------------------\n// Build Mutation Function\n// -----------------------------------------------------------------------------\n\nfunction processTypeDef(typeDef: Record<string, ObjectFieldTypeDef> | ObjectFieldTypeDef): {\n shape: TypeDef;\n shapeKey: number;\n} {\n let shape: TypeDef;\n let shapeKey: number;\n\n if (typeof typeDef === 'object') {\n if (typeDef instanceof ValidatorDef) {\n shape = typeDef as TypeDef;\n shapeKey = typeDef.shapeKey;\n } else if (typeDef instanceof Set) {\n shape = typeDef;\n shapeKey = hashValue(typeDef);\n } else {\n shape = t.object(typeDef as Record<string, ObjectFieldTypeDef>);\n shapeKey = shape.shapeKey;\n }\n } else {\n shape = typeDef as Mask;\n shapeKey = hashValue(shape);\n }\n\n return { shape, shapeKey };\n}\n\nfunction buildMutationFn<Request, Response>(\n mutationDefinitionBuilder: () => RESTMutationDefinition<\n string,\n ObjectFieldTypeDef | Record<string, ObjectFieldTypeDef>,\n ObjectFieldTypeDef | Record<string, ObjectFieldTypeDef>\n >,\n): () => MutationResult<Request, Response> {\n let mutationDefinition: MutationDefinition<Request, Response> | undefined;\n\n const getMutationDefinition = (): MutationDefinition<Request, Response> => {\n if (mutationDefinition === undefined) {\n const {\n path,\n method = 'POST',\n request,\n response,\n optimisticUpdates = false,\n cache,\n } = mutationDefinitionBuilder();\n\n const id = `mutation:${method}:${path}`;\n\n const { shape: requestShape, shapeKey: requestShapeKey } = processTypeDef(request);\n const { shape: responseShape, shapeKey: responseShapeKey } = processTypeDef(response);\n\n // Create optimized path interpolator (parses template once)\n const interpolatePath = createPathInterpolator(path);\n\n // Extract path parameter names from the path template\n const pathParamNames = new Set<string>();\n const paramRegex = /\\[([^\\]]+)\\]/g;\n let match: RegExpExecArray | null;\n while ((match = paramRegex.exec(path)) !== null) {\n pathParamNames.add(match[1]);\n }\n\n const mutateFn = async (context: QueryContext, requestData: Request): Promise<Response> => {\n // Only pass path params to the interpolator, not the full request\n const pathParams: Record<string, unknown> = {};\n for (const paramName of pathParamNames) {\n pathParams[paramName] = (requestData as Record<string, unknown>)[paramName];\n }\n const url = interpolatePath(pathParams);\n\n const fetchResponse = await context.fetch(url, {\n method,\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(requestData),\n });\n\n return fetchResponse.json();\n };\n\n mutationDefinition = {\n id,\n requestShape,\n requestShapeKey,\n responseShape,\n responseShapeKey,\n mutateFn,\n optimisticUpdates,\n cache,\n };\n }\n\n return mutationDefinition;\n };\n\n const mutationFn = (): MutationResult<Request, Response> => {\n const queryClient = getContext(QueryClientContext);\n\n if (queryClient === undefined) {\n throw new Error('QueryClient not found');\n }\n\n return queryClient.getMutation<Request, Response>(getMutationDefinition());\n };\n\n MUTATION_DEFINITION_MAP.set(mutationFn, getMutationDefinition);\n\n return mutationFn;\n}\n\n// -----------------------------------------------------------------------------\n// Public API\n// -----------------------------------------------------------------------------\n\n/**\n * Creates a mutation function that returns a MutationResult.\n * Mutations must be explicitly run via `.run(request)`.\n *\n * @example\n * ```ts\n * const updateUser = mutation(() => ({\n * path: '/users/[id]',\n * method: 'PUT',\n * request: {\n * id: t.id,\n * name: t.string,\n * email: t.string,\n * },\n * response: User,\n * optimisticUpdates: true,\n * }));\n *\n * // Usage:\n * const mutation = updateUser();\n * await mutation.run({ id: '123', name: 'John', email: 'john@example.com' });\n * ```\n */\nexport function mutation<\n Path extends string,\n RequestDef extends Record<string, ObjectFieldTypeDef> | ObjectFieldTypeDef,\n ResponseDef extends Record<string, ObjectFieldTypeDef> | ObjectFieldTypeDef,\n>(\n mutationDefinitionBuilder: () => RESTMutationDefinition<Path, RequestDef, ResponseDef>,\n): MutationFn<ExtractMutationRequest<Path, RequestDef>, ResponseDef> {\n return buildMutationFn(mutationDefinitionBuilder as any) as any;\n}\n"],"names":["RefetchInterval","NetworkMode","Mask","entries","isArray","hashValue","entity","deepClone","reactiveMethod","setScopeOwner","notifier","relay","signal","context","value","setReactivePromise","isPaused","reactiveSignal","task","query","QueryType","response","reactive","getContext"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../src/types.ts","../../../src/typeDefs.ts","../../../src/errors.ts","../../../src/utils.ts","../../../src/proxy.ts","../../../src/EntityMap.ts","../../../src/NetworkManager.ts","../../../src/parseEntities.ts","../../../src/QueryResult.ts","../../../src/MutationResult.ts","../../../src/RefetchManager.ts","../../../src/MemoryEvictionManager.ts","../../../src/QueryClient.ts","../../../src/pathInterpolator.ts","../../../src/query.ts","../../../src/mutation.ts"],"sourcesContent":["import { PendingReactivePromise, ReadyReactivePromise, type Signal } from 'signalium';\nimport { ReactivePromise } from 'signalium';\nimport { HasRequiredKeys, Optionalize, Prettify, Signalize } from './type-utils.js';\n\n// ================================\n// Base URL and Request Types\n// ================================\n\n/**\n * Flexible base URL value - can be a static string, a Signal, or a function.\n * Functions are wrapped in reactiveSignal internally for memoization.\n */\nexport type BaseUrlValue = string | Signal<string> | (() => string);\n\n/**\n * Extended RequestInit with additional query-specific options.\n * This is what gets passed to the fetch function.\n */\nexport interface QueryRequestInit extends RequestInit {\n baseUrl?: string;\n searchParams?: URLSearchParams;\n}\n\n/**\n * Request options that can be specified at the query definition level.\n * These can override context-level settings.\n */\nexport interface QueryRequestOptions {\n baseUrl?: BaseUrlValue;\n headers?: HeadersInit;\n credentials?: RequestCredentials;\n mode?: RequestMode;\n cache?: RequestCache;\n redirect?: RequestRedirect;\n referrer?: string;\n referrerPolicy?: ReferrerPolicy;\n integrity?: string;\n keepalive?: boolean;\n signal?: AbortSignal;\n}\n\n// ================================\n// Type Definitions\n// ================================\n\nexport enum RefetchInterval {\n Every1Second = 1000,\n Every5Seconds = 5000,\n Every10Seconds = 10000,\n Every30Seconds = 30000,\n Every1Minute = 60000,\n Every5Minutes = 300000,\n}\n\nexport enum NetworkMode {\n /**\n * Always fetch regardless of network status\n */\n Always = 'always',\n /**\n * Only fetch when online (default)\n */\n Online = 'online',\n /**\n * Fetch if cached data exists, even when offline\n */\n OfflineFirst = 'offlineFirst',\n}\n\nexport interface RetryConfig {\n /**\n * Number of retry attempts\n */\n retries: number;\n /**\n * Optional custom delay function (receives attempt index starting at 0)\n * Default: exponential backoff (1000ms * 2^attempt)\n */\n retryDelay?: (attemptIndex: number) => number;\n}\n\nexport const enum Mask {\n // Fundamental types\n UNDEFINED = 1 << 0,\n NULL = 1 << 1,\n NUMBER = 1 << 2,\n STRING = 1 << 3,\n BOOLEAN = 1 << 4,\n OBJECT = 1 << 5,\n ARRAY = 1 << 6,\n ID = 1 << 7,\n\n // Complex types\n RECORD = 1 << 8,\n UNION = 1 << 9,\n ENTITY = 1 << 10,\n\n // Flags\n HAS_SUB_ENTITY = 1 << 11,\n HAS_NUMBER_FORMAT = 1 << 12,\n HAS_STRING_FORMAT = 1 << 13,\n PARSE_RESULT = 1 << 14,\n}\n\n// ================================\n// ParseResult Types\n// ================================\n\nexport type ParseSuccess<T> = { success: true; value: T };\nexport type ParseError = { success: false; error: Error };\nexport type ParseResult<T> = ParseSuccess<T> | ParseError;\n\n/**\n * Interface for case-insensitive enum sets.\n * String values are matched case-insensitively during parsing,\n * but always return the canonical (originally defined) casing.\n */\nexport interface CaseInsensitiveEnumSet<T extends string | boolean | number> extends Set<T> {\n /**\n * Check if a value exists in the set (case-insensitively for strings).\n */\n has(value: unknown): boolean;\n\n /**\n * Get the canonical value for a given input.\n * For strings, performs case-insensitive lookup and returns the canonical casing.\n * For numbers/booleans, performs exact match.\n * Returns undefined if no match is found.\n */\n get(value: unknown): T | undefined;\n}\n\nexport type SimpleTypeDef =\n // Sets are constant values\n | Set<string | boolean | number>\n\n // Case-insensitive enum sets\n | CaseInsensitiveEnumSet<string | boolean | number>\n\n // Numbers are primitive type masks (potentially multiple masks combined)\n | Mask;\n\nexport type ComplexTypeDef =\n // Objects, arrays, records, unions, and parse results are definitions\n ObjectDef | EntityDef | ArrayDef | RecordDef | UnionDef | ParseResultDef;\n\nexport type TypeDef = SimpleTypeDef | ComplexTypeDef;\n\nexport type ObjectFieldTypeDef = TypeDef | string;\n\nexport type ObjectShape = Record<string, ObjectFieldTypeDef>;\n\n// ================================\n// Extend Type Utilities\n// ================================\n\n/**\n * Utility type that prevents extending with keys that already exist in T.\n * If U contains a key from T, that key's type becomes `never`, causing a type error.\n */\nexport type StrictExtend<T extends ObjectShape, U extends ObjectShape> = {\n [K in keyof U]: K extends keyof T ? never : U[K];\n};\n\nexport const ARRAY_KEY = Symbol('array');\nexport const RECORD_KEY = Symbol('record');\n\nexport interface UnionTypeDefs {\n [ARRAY_KEY]?: TypeDef;\n [RECORD_KEY]?: TypeDef;\n [key: string]: ObjectDef | EntityDef;\n}\n\nexport interface BaseTypeDef {\n mask: Mask;\n shapeKey: number;\n typenameField: string;\n typenameValue: string;\n idField: string;\n subEntityPaths: undefined | string | string[];\n values: Set<string | boolean | number> | undefined;\n\n optional: this | Mask.UNDEFINED;\n nullable: this | Mask.NULL;\n nullish: this | Mask.UNDEFINED | Mask.NULL;\n}\n\nexport type EntityMethods = Record<string, (...args: any[]) => any>;\n\n// Helper type to conditionally include methods - unknown (invisible) when M is the default EntityMethods\n// We check if M has an index signature by seeing if it allows any string key\nexport type IncludeMethods<M> = string extends keyof M ? unknown : M;\n\n// Entity configuration options\nexport interface EntityConfig<T extends ObjectShape> {\n stream: {\n subscribe: (\n context: import('./QueryClient.js').QueryContext,\n id: string | number,\n onUpdate: (update: Partial<ExtractTypesFromShape<T>>) => void,\n ) => (() => void) | undefined;\n };\n}\n\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\nexport interface EntityDef<T extends ObjectShape = ObjectShape, M extends EntityMethods = {}> extends BaseTypeDef {\n mask: Mask.ENTITY;\n shape: T;\n\n /**\n * Creates a new EntityDef that extends this one with additional fields and optional methods.\n * The function is called lazily on first shape access to support circular references.\n * Prevents overriding of existing fields including id and typename.\n *\n * @param newFieldsGetter - Lazy factory returning new fields to add\n * @param newMethodsGetter - Optional lazy factory returning new methods to add (merged with existing)\n */\n // eslint-disable-next-line @typescript-eslint/no-empty-object-type\n extend<U extends ObjectShape, N extends EntityMethods = {}>(\n newFieldsGetter: () => StrictExtend<T, U> & U,\n newMethodsGetter?: () => N & ThisType<N & ExtractTypesFromShape<T & U> & IncludeMethods<M>>,\n ): EntityDef<T & U, M & N>;\n}\n\nexport interface ObjectDef<T extends ObjectShape = ObjectShape> extends BaseTypeDef {\n mask: Mask.OBJECT;\n shape: T;\n /**\n * Creates a new ObjectDef that extends this one with additional fields.\n * Prevents overriding of existing fields including id and typename.\n */\n extend<U extends ObjectShape>(newFields: StrictExtend<T, U> & U): ObjectDef<T & U>;\n}\n\nexport interface ArrayDef<T extends TypeDef = TypeDef> extends BaseTypeDef {\n mask: Mask.ARRAY;\n shape: T;\n}\n\nexport interface UnionDef<_T extends readonly TypeDef[] = readonly TypeDef[]> extends BaseTypeDef {\n mask: Mask.UNION;\n shape: UnionTypeDefs | undefined;\n}\n\nexport interface RecordDef<T extends TypeDef = TypeDef> extends BaseTypeDef {\n mask: Mask.RECORD;\n shape: T;\n}\n\nexport interface ParseResultDef<T extends TypeDef = TypeDef> extends BaseTypeDef {\n mask: Mask.PARSE_RESULT;\n shape: T;\n}\n\n/**\n * Global format registry interface that maps format names to their TypeScript types.\n * This can be extended via module augmentation using the SignaliumQuery namespace.\n */\ndeclare global {\n // eslint-disable-next-line @typescript-eslint/no-namespace\n namespace SignaliumQuery {\n interface FormatRegistry {\n date: Date;\n 'date-time': Date;\n // Users can extend this via module augmentation\n // Example: declare global { namespace SignaliumQuery { interface FormatRegistry { 'custom-format': CustomType } } }\n }\n }\n}\n\ndeclare const FormattedSymbol: unique symbol;\n\nexport type Formatted<T> = number & {\n [FormattedSymbol]: T;\n};\n\nexport interface APITypes {\n format: <K extends keyof SignaliumQuery.FormatRegistry>(format: K) => Formatted<SignaliumQuery.FormatRegistry[K]>;\n typename: <T extends string>(value: T) => T;\n const: <T extends string | boolean | number>(value: T) => Set<T>;\n enum: {\n <T extends readonly (string | boolean | number)[]>(...values: T): Set<T[number]>;\n caseInsensitive<T extends readonly (string | boolean | number)[]>(...values: T): Set<T[number]>;\n };\n\n id: Mask.ID;\n string: Mask.STRING;\n number: Mask.NUMBER;\n boolean: Mask.BOOLEAN;\n null: Mask.NULL;\n undefined: Mask.UNDEFINED;\n\n array: <T extends TypeDef>(shape: T) => ArrayDef<T>;\n\n object: <T extends ObjectShape>(shape: T) => ObjectDef<T>;\n record: <T extends TypeDef>(shape: T) => RecordDef<T>;\n\n union: <VS extends readonly TypeDef[]>(...types: VS) => UnionDef<VS>;\n\n nullish: <T extends TypeDef>(type: T) => T | Mask.UNDEFINED | Mask.NULL;\n optional: <T extends TypeDef>(type: T) => T | Mask.UNDEFINED;\n nullable: <T extends TypeDef>(type: T) => T | Mask.NULL;\n\n result: <T extends TypeDef>(type: T) => ParseResultDef<T>;\n}\n\n// ================================\n// Type Extraction\n// ================================\n\ntype ExtractPrimitiveTypeFromMask<T extends number> = T extends Mask.UNDEFINED\n ? undefined\n : T extends Mask.NULL\n ? null\n : T extends Mask.NUMBER\n ? number\n : T extends Mask.STRING\n ? string\n : T extends Mask.BOOLEAN\n ? boolean\n : T extends Mask.ID\n ? string | number\n : never;\n\nexport type ExtractTypesFromShape<S extends Record<string, ObjectFieldTypeDef>> = {\n [K in keyof S]: ExtractType<S[K]>;\n};\n\nexport type ExtractType<T extends ObjectFieldTypeDef> =\n T extends Formatted<infer U>\n ? U\n : T extends number\n ? ExtractPrimitiveTypeFromMask<T>\n : T extends string\n ? T\n : T extends Set<infer TSet>\n ? TSet\n : T extends ObjectDef<infer S>\n ? Prettify<ExtractTypesFromShape<S>>\n : T extends EntityDef<infer S, infer M>\n ? Prettify<ExtractTypesFromShape<S> & IncludeMethods<M>>\n : T extends ArrayDef<infer S>\n ? ExtractType<S>[]\n : T extends RecordDef<infer S>\n ? Record<string, ExtractType<S>>\n : T extends UnionDef<infer VS>\n ? ExtractType<VS[number]>\n : T extends ParseResultDef<infer S>\n ? ParseResult<ExtractType<S>>\n : never;\n\nexport type QueryType<T> = T extends () => infer Response\n ? Response extends QueryResult<infer T, unknown, unknown>\n ? T\n : never\n : never;\n\nexport type ResponseTypeDef = Record<string, ObjectFieldTypeDef> | ObjectFieldTypeDef;\n\nexport type ParamsOrUndefined<Params extends Record<string, unknown>> =\n // eslint-disable-next-line @typescript-eslint/no-empty-object-type\n {} extends Params ? undefined : Params;\n\nexport type ExtractTypesFromObjectOrEntity<S extends ResponseTypeDef> =\n S extends Record<string, ObjectFieldTypeDef>\n ? {\n [K in keyof S]: ExtractType<S[K]>;\n }\n : S extends ObjectFieldTypeDef\n ? ExtractType<S>\n : // eslint-disable-next-line @typescript-eslint/no-empty-object-type\n {};\n\nexport type ExtractTypesFromEntityOrUndefined<S extends EntityDef | UnionDef<EntityDef[]> | undefined = undefined> =\n S extends EntityDef<infer Shape, infer Methods>\n ? Prettify<ExtractTypesFromShape<Shape> & IncludeMethods<Methods>>\n : S extends UnionDef<infer VS>\n ? ExtractType<VS[number]>\n : undefined;\n\n// ================================\n// Query Extra Types\n// ================================\n\nexport type QueryExtra<StreamType, OptimisticInsertType> = {\n streamOrphans: StreamType extends undefined ? undefined : ReadonlySet<StreamType>;\n optimisticInserts: OptimisticInsertType extends undefined ? undefined : ReadonlySet<OptimisticInsertType>;\n};\n\n// ================================\n// Query Types\n// ================================\n\ninterface BaseQueryResultExtensions<T, StreamType, OptimisticUpdateType> {\n readonly isFetching: boolean;\n readonly isPaused: boolean;\n readonly extra: QueryExtra<StreamType, OptimisticUpdateType>;\n}\n\ninterface QueryResultExtensions<T, StreamType, OptimisticUpdateType>\n extends BaseQueryResultExtensions<T, StreamType, OptimisticUpdateType> {\n refetch: () => Promise<T>;\n readonly isRefetching: boolean;\n}\n\nexport type BaseQueryResult<T, StreamType, OptimisticUpdateType> = ReactivePromise<T> &\n QueryResultExtensions<T, StreamType, OptimisticUpdateType>;\n\nexport type PendingQueryResult<T, StreamType, OptimisticUpdateType> = PendingReactivePromise<T> &\n QueryResultExtensions<T, StreamType, OptimisticUpdateType>;\n\nexport type ReadyQueryResult<T, StreamType, OptimisticUpdateType> = ReadyReactivePromise<T> &\n QueryResultExtensions<T, StreamType, OptimisticUpdateType>;\n\nexport type QueryResult<T, StreamType = undefined, OptimisticUpdateType = undefined> =\n | PendingQueryResult<T, StreamType, OptimisticUpdateType>\n | ReadyQueryResult<T, StreamType, OptimisticUpdateType>;\n\nexport type QueryFn<\n Params extends Record<string, unknown>,\n Response extends ResponseTypeDef,\n StreamType extends EntityDef | UnionDef<EntityDef[]> | undefined = undefined,\n OptimisticUpdateType extends EntityDef | UnionDef<EntityDef[]> | undefined = undefined,\n> =\n HasRequiredKeys<Params> extends true\n ? (\n params: Prettify<Optionalize<Signalize<Params>>>,\n ) => QueryResult<\n Readonly<Prettify<ExtractTypesFromObjectOrEntity<Response>>>,\n Readonly<Prettify<ExtractTypesFromEntityOrUndefined<StreamType>>>,\n Readonly<Prettify<ExtractTypesFromEntityOrUndefined<OptimisticUpdateType>>>\n >\n : (\n params?: Prettify<Optionalize<ParamsOrUndefined<Signalize<Params>>>>,\n ) => QueryResult<\n Readonly<Prettify<ExtractTypesFromObjectOrEntity<Response>>>,\n Readonly<Prettify<ExtractTypesFromEntityOrUndefined<StreamType>>>,\n Readonly<Prettify<ExtractTypesFromEntityOrUndefined<OptimisticUpdateType>>>\n >;\n\n// ================================\n// Infinite Query Types\n// ================================\n\ninterface InfiniteQueryResultExtensions<T, StreamType, OptimisticUpdateType>\n extends QueryResultExtensions<T, StreamType, OptimisticUpdateType> {\n fetchNextPage: () => Promise<T>;\n hasNextPage: boolean;\n isFetchingMore: boolean;\n}\n\nexport type BaseInfiniteQueryResult<T, StreamType, OptimisticUpdateType> = ReactivePromise<T> &\n InfiniteQueryResultExtensions<T, StreamType, OptimisticUpdateType>;\n\nexport type PendingInfiniteQueryResult<T, StreamType, OptimisticUpdateType> = PendingReactivePromise<T> &\n InfiniteQueryResultExtensions<T, StreamType, OptimisticUpdateType>;\n\nexport type ReadyInfiniteQueryResult<T, StreamType, OptimisticUpdateType> = ReadyReactivePromise<T> &\n InfiniteQueryResultExtensions<T, StreamType, OptimisticUpdateType>;\n\nexport type InfiniteQueryResult<T, StreamType = undefined, OptimisticUpdateType = undefined> =\n | PendingInfiniteQueryResult<T, StreamType, OptimisticUpdateType>\n | ReadyInfiniteQueryResult<T, StreamType, OptimisticUpdateType>;\n\nexport type InfiniteQueryFn<\n Params extends Record<string, unknown>,\n Response extends Record<string, ObjectFieldTypeDef> | ObjectFieldTypeDef,\n StreamType extends EntityDef | UnionDef<EntityDef[]> | undefined = undefined,\n OptimisticUpdateType extends EntityDef | UnionDef<EntityDef[]> | undefined = undefined,\n> =\n HasRequiredKeys<Params> extends true\n ? (\n params: Prettify<Optionalize<Signalize<Params>>>,\n ) => InfiniteQueryResult<\n Readonly<Prettify<ExtractTypesFromObjectOrEntity<Response>>>[],\n Readonly<Prettify<ExtractTypesFromEntityOrUndefined<StreamType>>>,\n Readonly<Prettify<ExtractTypesFromEntityOrUndefined<OptimisticUpdateType>>>\n >\n : (\n params?: Prettify<Optionalize<ParamsOrUndefined<Signalize<Params>>>>,\n ) => InfiniteQueryResult<\n Readonly<Prettify<ExtractTypesFromObjectOrEntity<Response>>>[],\n Readonly<Prettify<ExtractTypesFromEntityOrUndefined<StreamType>>>,\n Readonly<Prettify<ExtractTypesFromEntityOrUndefined<OptimisticUpdateType>>>\n >;\n\n// ================================\n// Stream Query Types\n// ================================\n\ntype StreamQueryResultExtensions<T> = BaseQueryResultExtensions<T, undefined, undefined>;\n\nexport type BaseStreamQueryResult<T> = ReactivePromise<T> & StreamQueryResultExtensions<T>;\n\nexport type PendingStreamQueryResult<T> = PendingReactivePromise<T> & StreamQueryResultExtensions<T>;\n\nexport type ReadyStreamQueryResult<T> = ReadyReactivePromise<T> & StreamQueryResultExtensions<T>;\n\nexport type StreamQueryResult<T> = PendingStreamQueryResult<T> | ReadyStreamQueryResult<T>;\n\nexport type StreamQueryFn<Params extends Record<string, unknown>, Response extends EntityDef | UnionDef<EntityDef[]>> =\n HasRequiredKeys<Params> extends true\n ? (\n params: Prettify<Optionalize<Params>>,\n ) => StreamQueryResult<Readonly<Prettify<ExtractTypesFromObjectOrEntity<Response>>>>\n : (\n params?: Prettify<Optionalize<ParamsOrUndefined<Params>>>,\n ) => StreamQueryResult<Readonly<Prettify<ExtractTypesFromObjectOrEntity<Response>>>>;\n\n// ================================\n// Mutation Types\n// ================================\n\n/**\n * Base mutation result interface extending ReactivePromise with mutation-specific properties.\n */\ninterface MutationResultExtensions<Request, Response> {\n /**\n * Reset the mutation state.\n */\n reset(): void;\n /**\n * Execute the mutation with the given request data.\n */\n run(request: Request): MutationResult<Request, Response>;\n}\n\nexport type BaseMutationResult<Request, Response> = ReactivePromise<Response> &\n MutationResultExtensions<Request, Response>;\n\nexport type PendingMutationResult<Request, Response> = PendingReactivePromise<Response> &\n MutationResultExtensions<Request, Response>;\n\nexport type ReadyMutationResult<Request, Response> = ReadyReactivePromise<Response> &\n MutationResultExtensions<Request, Response>;\n\nexport type MutationResult<Request, Response> =\n | PendingMutationResult<Request, Response>\n | ReadyMutationResult<Request, Response>;\n\n/**\n * A mutation function that returns a MutationResult.\n * The mutation must be explicitly run via `.run(request)`.\n */\nexport type MutationFn<Request, Response extends ResponseTypeDef> = () => MutationResult<\n Request,\n Readonly<Prettify<ExtractTypesFromObjectOrEntity<Response>>>\n>;\n","import {\n APITypes,\n ARRAY_KEY,\n ArrayDef,\n ComplexTypeDef,\n EntityConfig,\n EntityDef,\n EntityMethods,\n ExtractTypesFromShape,\n Formatted,\n Mask,\n ObjectDef,\n ObjectShape,\n ParseResultDef,\n RECORD_KEY,\n RecordDef,\n TypeDef,\n UnionDef,\n UnionTypeDefs,\n} from './types.js';\nimport { Prettify } from './type-utils.js';\nimport { hashValue } from 'signalium/utils';\n\nconst entries = Object.entries;\nconst isArray = Array.isArray;\n\nconst enum ComplexTypeDefKind {\n OBJECT = 0,\n UNION = 1,\n PRIMITIVE_UNION = 2,\n ARRAY = 3,\n RECORD = 4,\n ENTITY = 5,\n PARSE_RESULT = 6,\n}\n\nexport class ValidatorDef<T> {\n private kind: ComplexTypeDefKind;\n public mask: Mask;\n private _optional: ValidatorDef<T | undefined> | undefined;\n private _nullable: ValidatorDef<T | null> | undefined;\n private _nullish: ValidatorDef<T | null | undefined> | undefined;\n private _shapeKey: number | undefined = undefined;\n private _shape: TypeDef | ObjectShape | UnionTypeDefs | (() => ObjectShape) | ComplexTypeDef[] | undefined;\n public subEntityPaths: undefined | string | string[] = undefined;\n public typenameField: string | undefined = undefined;\n public typenameValue: string | undefined = undefined;\n public idField: string | undefined = undefined;\n public values: Set<string | boolean | number> | undefined = undefined;\n /**\n * Lazy factory function for creating entity methods.\n * Evaluated once during reifyShape() and cached in _methods.\n */\n public _methodsFactory: (() => EntityMethods) | undefined = undefined;\n\n /**\n * Cached methods object from evaluating _methodsFactory.\n * Populated during reifyShape() - the same methods object is shared across all proxies,\n * but each proxy binds its own reactive method wrappers.\n */\n public _methods: EntityMethods | undefined = undefined;\n\n /**\n * Entity configuration including stream options.\n */\n public _entityConfig: EntityConfig<any> | undefined = undefined;\n\n constructor(\n kind: ComplexTypeDefKind,\n mask: Mask,\n shape: TypeDef | ObjectShape | UnionTypeDefs | (() => ObjectShape) | ComplexTypeDef[] | undefined,\n values: Set<string | boolean | number> | undefined = undefined,\n ) {\n this.kind = kind;\n this.mask = mask;\n this._shape = shape;\n this.values = values;\n }\n\n static cloneWith(\n def: ValidatorDef<any>,\n mask: Mask,\n values: Set<string | boolean | number> | undefined = undefined,\n ): ValidatorDef<any> {\n const newDef = new ValidatorDef(def.kind, mask | def.mask, def._shape, values);\n newDef.subEntityPaths = def.subEntityPaths;\n newDef.values = def.values;\n newDef.typenameField = def.typenameField;\n newDef.typenameValue = def.typenameValue;\n newDef.idField = def.idField;\n newDef._methodsFactory = def._methodsFactory;\n newDef._methods = def._methods;\n newDef._entityConfig = def._entityConfig;\n return newDef;\n }\n\n reifyShape() {\n if (this._shapeKey === undefined) {\n switch (this.kind) {\n case ComplexTypeDefKind.ENTITY: {\n const shape = (this._shape as () => ObjectShape)();\n this._shape = reifyObjectShape(this, shape);\n // Evaluate and cache the methods factory once during shape reification\n if (this._methodsFactory && !this._methods) {\n this._methods = this._methodsFactory();\n }\n break;\n }\n case ComplexTypeDefKind.OBJECT:\n this._shape = reifyObjectShape(this, this._shape as ObjectShape);\n break;\n case ComplexTypeDefKind.UNION:\n this._shape = reifyUnionShape(this, this._shape as ComplexTypeDef[]);\n break;\n case ComplexTypeDefKind.ARRAY:\n case ComplexTypeDefKind.RECORD:\n case ComplexTypeDefKind.PARSE_RESULT: {\n const shape = this._shape;\n\n let shapeKey;\n\n if (shape instanceof ValidatorDef) {\n shapeKey = shape.shapeKey;\n\n if (shape.mask & (Mask.ENTITY | Mask.HAS_SUB_ENTITY)) {\n this.mask |= Mask.HAS_SUB_ENTITY;\n }\n } else if (shape instanceof CaseInsensitiveSet) {\n shapeKey = hashValue(Array.from(shape));\n } else {\n shapeKey = hashValue(shape);\n }\n\n this._shapeKey = hashValue([this.kind, this.mask, this.values, shapeKey]);\n\n break;\n }\n }\n }\n }\n\n get shape(): TypeDef | ObjectShape | UnionTypeDefs | undefined {\n this.reifyShape();\n\n return this._shape as TypeDef | ObjectShape | UnionTypeDefs | undefined;\n }\n\n get methods(): EntityMethods | undefined {\n this.reifyShape();\n\n return this._methods;\n }\n\n get shapeKey(): number {\n this.reifyShape();\n\n return this._shapeKey!;\n }\n\n set shapeKey(key: number) {\n this._shapeKey = key >>> 0;\n }\n\n get optional(): ValidatorDef<T | undefined> {\n if (this._optional === undefined) {\n this._optional = ValidatorDef.cloneWith(this, Mask.UNDEFINED);\n }\n return this._optional;\n }\n\n get nullable(): ValidatorDef<T | null> {\n if (this._nullable === undefined) {\n this._nullable = ValidatorDef.cloneWith(this, Mask.NULL);\n }\n return this._nullable;\n }\n\n get nullish(): ValidatorDef<T | null | undefined> {\n if (this._nullish === undefined) {\n this._nullish = ValidatorDef.cloneWith(this, Mask.UNDEFINED | Mask.NULL);\n }\n return this._nullish;\n }\n\n /**\n * Creates a new ValidatorDef that extends this one with additional fields and optional methods.\n * Only valid for ENTITY and OBJECT types.\n * Prevents overriding of existing fields including id and typename.\n *\n * For entities, accepts a function that returns the new fields (lazy reification).\n * For objects, accepts the new fields directly.\n *\n * @param newFieldsOrGetter - New fields to add (lazy function for entities, direct object for objects)\n * @param newMethodsGetter - Optional lazy factory returning new methods to add (entities only, merged with existing)\n */\n extend<U extends ObjectShape, N extends EntityMethods = EntityMethods>(\n newFieldsOrGetter: U | (() => U),\n // Note: ThisType here will be the extended entity type - TypeScript infers it from context\n newMethodsGetter?: () => N,\n ): ValidatorDef<any> {\n // Validate that this is an extendable type (ENTITY or OBJECT)\n if (this.kind !== ComplexTypeDefKind.ENTITY && this.kind !== ComplexTypeDefKind.OBJECT) {\n throw new Error('extend() can only be called on Entity or Object types');\n }\n\n if (this.kind === ComplexTypeDefKind.ENTITY) {\n // For entities, keep the shape lazy - only reify on first usage\n // This preserves the lazy evaluation pattern and supports circular references\n // We bind getParentShape to access the parent's `.shape` getter which properly\n // reifies and caches the shape, avoiding multiple reification calls\n const newFieldsGetter = newFieldsOrGetter as () => U;\n const parentMethodsFactory = this._methodsFactory;\n\n const extendedDef = new ValidatorDef(ComplexTypeDefKind.ENTITY, this.mask, () => {\n const existingShape = this.shape as ObjectShape;\n const newFields = newFieldsGetter();\n\n // Runtime validation: check for field conflicts\n for (const key of Object.keys(newFields)) {\n if (key in existingShape) {\n throw new Error(`Cannot extend: field '${key}' already exists in type definition`);\n }\n }\n\n return { ...existingShape, ...newFields };\n });\n\n // Merge methods factories if either parent or new methods exist\n if (parentMethodsFactory || newMethodsGetter) {\n extendedDef._methodsFactory = () => {\n const parentMethods = parentMethodsFactory ? parentMethodsFactory() : {};\n const newMethods = newMethodsGetter ? newMethodsGetter() : {};\n return { ...parentMethods, ...newMethods } as EntityMethods;\n };\n }\n\n // Preserve entity config from parent\n extendedDef._entityConfig = this._entityConfig;\n\n return extendedDef;\n } else {\n // For objects, reify immediately since they're not lazy\n this.reifyShape();\n\n const existingShape = this._shape as ObjectShape;\n const newFields = newFieldsOrGetter as U;\n\n // Runtime validation: check for field conflicts\n for (const key of Object.keys(newFields)) {\n if (key in existingShape) {\n throw new Error(`Cannot extend: field '${key}' already exists in type definition`);\n }\n }\n\n return new ValidatorDef(ComplexTypeDefKind.OBJECT, this.mask, { ...existingShape, ...newFields });\n }\n }\n}\n\n// -----------------------------------------------------------------------------\n// Case-Insensitive Enum Set\n// -----------------------------------------------------------------------------\n\n/**\n * A Set-like class for enum values that matches string values case-insensitively.\n * Non-string values (numbers, booleans) are matched exactly.\n * Returns the canonical (originally defined) casing when a match is found.\n */\nexport class CaseInsensitiveSet<T extends string | boolean | number> extends Set<T> {\n private readonly lowercaseMap: Map<string, T>; // lowercase -> canonical (strings only)\n\n constructor(values: readonly T[]) {\n super(values);\n\n this.lowercaseMap = new Map<string, T>();\n\n for (const value of values) {\n if (typeof value === 'string') {\n const lowercase = value.toLowerCase();\n const existing = this.lowercaseMap.get(lowercase);\n\n if (existing !== undefined) {\n throw new Error(\n `Case-insensitive enum cannot have multiple values with the same lowercase form: '${existing}' and '${value}' both become '${lowercase}'`,\n );\n }\n\n this.lowercaseMap.set(lowercase, value);\n }\n }\n }\n\n /**\n * Check if a value exists in the set (case-insensitively for strings).\n * Used for backwards compatibility with Set-based checks.\n */\n has(value: unknown): boolean {\n return this.get(value) !== undefined;\n }\n\n /**\n * Get the canonical value for a given input.\n * For strings, performs case-insensitive lookup and returns the canonical casing.\n * For numbers/booleans, performs exact match.\n * Returns undefined if no match is found.\n */\n get(value: unknown): T | undefined {\n if (typeof value === 'string') {\n return this.lowercaseMap.get(value.toLowerCase());\n }\n\n if (super.has(value as T)) {\n return value as T;\n }\n\n return undefined;\n }\n}\n\n// -----------------------------------------------------------------------------\n// Complex Type Definitions\n// -----------------------------------------------------------------------------\n\nexport function defineArray<T extends TypeDef>(shape: T): ArrayDef<T> {\n return new ValidatorDef(ComplexTypeDefKind.ARRAY, Mask.ARRAY, shape) as unknown as ArrayDef<T>;\n}\n\nexport function defineRecord<T extends TypeDef>(shape: T): RecordDef<T> {\n return new ValidatorDef(ComplexTypeDefKind.RECORD, Mask.RECORD | Mask.OBJECT, shape) as unknown as RecordDef<T>;\n}\n\nexport function defineParseResult<T extends TypeDef>(innerType: T): ParseResultDef<T> {\n return new ValidatorDef(\n ComplexTypeDefKind.PARSE_RESULT,\n Mask.PARSE_RESULT,\n innerType,\n ) as unknown as ParseResultDef<T>;\n}\n\nexport function defineObject<T extends ObjectShape>(shape: T): ObjectDef<T> {\n return new ValidatorDef(ComplexTypeDefKind.OBJECT, Mask.OBJECT, shape) as unknown as ObjectDef<T>;\n}\n\nfunction defineUnion<T extends readonly TypeDef[]>(...types: T): UnionDef<T> {\n let mask = 0;\n let definition: ComplexTypeDef | undefined;\n let shape: ComplexTypeDef[] | undefined;\n let values: Set<string | boolean | number> | undefined;\n\n for (const type of types) {\n if (typeof type === 'number') {\n mask |= type;\n continue;\n }\n\n if (type instanceof Set) {\n if (values === undefined) {\n values = new Set(type);\n } else {\n for (const val of type) {\n values.add(val);\n }\n }\n\n continue;\n }\n\n if (definition === undefined) {\n definition = type;\n continue;\n }\n\n if (shape === undefined) {\n shape = [definition];\n }\n\n shape.push(type);\n }\n\n if (definition === undefined) {\n // It was a union of primitives, so return the mask\n if (values === undefined) {\n // This type coercion is incorrect, but we can't return the mask as a Mask\n // because that loses the type information about the union, which breaks\n // inference.\n //\n // TODO: Figure out how to make this correct type-wise\n return mask as unknown as UnionDef<T>;\n }\n\n // It was a union of enums/constants, so return the value as a Set\n if (mask === 0) {\n // This type coercion is incorrect, but we can't return the mask as a Mask\n // because that loses the type information about the union, which breaks\n // inference.\n //\n // TODO: Figure out how to make this correct type-wise\n\n return values as unknown as UnionDef<T>;\n }\n\n // It was a union of primitives and enums, so return the mask and values as a new ValidatorDef\n return new ValidatorDef(ComplexTypeDefKind.PRIMITIVE_UNION, mask | Mask.UNION, undefined, values) as UnionDef;\n }\n\n // It was a single complex type, so return the clone with the new mask and values\n if (shape === undefined) {\n return ValidatorDef.cloneWith(definition as ValidatorDef<any>, mask, values) as UnionDef<T>;\n }\n\n return new ValidatorDef(ComplexTypeDefKind.UNION, mask | Mask.UNION, shape, values) as UnionDef;\n}\n\nfunction defineNullish<T extends TypeDef>(type: T): T | Mask.UNDEFINED | Mask.NULL {\n if (typeof type === 'number') {\n return (type | Mask.UNDEFINED | Mask.NULL) as T | Mask.UNDEFINED | Mask.NULL;\n }\n\n if (type instanceof Set) {\n return defineUnion(type, Mask.UNDEFINED, Mask.NULL) as T | Mask.UNDEFINED | Mask.NULL;\n }\n\n // Complex type - use the cached property\n return type.nullish as T | Mask.UNDEFINED | Mask.NULL;\n}\n\nfunction defineOptional<T extends TypeDef>(type: T): T | Mask.UNDEFINED {\n if (typeof type === 'number') {\n return (type | Mask.UNDEFINED) as T | Mask.UNDEFINED;\n }\n\n if (type instanceof Set) {\n return defineUnion(type, Mask.UNDEFINED) as T | Mask.UNDEFINED;\n }\n\n // Complex type - use the cached property\n return type.optional as T | Mask.UNDEFINED;\n}\n\nfunction defineNullable<T extends TypeDef>(type: T): T | Mask.NULL {\n if (typeof type === 'number') {\n return (type | Mask.NULL) as T | Mask.NULL;\n }\n\n if (type instanceof Set) {\n return defineUnion(type, Mask.NULL) as T | Mask.NULL;\n }\n\n // Complex type - use the cached property\n return type.nullable as T | Mask.NULL;\n}\n\n// -----------------------------------------------------------------------------\n// Shape Reification\n// -----------------------------------------------------------------------------\n\nexport function reifyObjectShape(def: ValidatorDef<any>, shape: ObjectShape): ObjectShape {\n // create a hash of the shape, starting with the object mask as the base\n let shapeKey = hashValue([def.mask, def.values]);\n\n for (const [key, value] of entries(shape)) {\n switch (typeof value) {\n case 'number':\n if ((value & Mask.ID) !== 0) {\n if (def.idField !== undefined) {\n throw new Error(`Duplicate id field: ${key}`);\n }\n\n def.idField = key;\n }\n\n // Add to shape key (order independent operation)\n shapeKey += hashValue(key) ^ value;\n break;\n case 'string':\n // This is a typename field (plain string value)\n if (def.typenameField !== undefined && def.typenameField !== key) {\n throw new Error(`Duplicate typename field: ${key}`);\n }\n\n def.typenameField = key;\n def.typenameValue = value;\n\n // Add to shape key (order independent operation)\n shapeKey += hashValue(key) ^ hashValue(value);\n break;\n case 'object':\n if (value instanceof CaseInsensitiveSet) {\n shapeKey ^= hashValue(key) ^ hashValue(Array.from(value));\n break;\n }\n\n if (value instanceof Set) {\n shapeKey ^= hashValue(key) ^ hashValue(value);\n break;\n }\n\n // Add to shape key (order independent operation)\n shapeKey += hashValue(key) ^ value.shapeKey;\n\n if (value.mask & (Mask.ENTITY | Mask.HAS_SUB_ENTITY)) {\n def.mask |= Mask.HAS_SUB_ENTITY;\n if (def.subEntityPaths === undefined) {\n def.subEntityPaths = key;\n } else if (isArray(def.subEntityPaths)) {\n def.subEntityPaths.push(key);\n } else {\n def.subEntityPaths = [def.subEntityPaths, key];\n }\n }\n break;\n }\n }\n\n // Convert to unsigned 32-bit integer\n def.shapeKey = shapeKey >>> 0;\n\n return shape;\n}\n\nfunction reifyUnionShape(def: ValidatorDef<any>, defs: ComplexTypeDef[]): UnionTypeDefs {\n let mask = def.mask;\n\n let shape: UnionTypeDefs = Object.create(null);\n let unionTypenameField: string | undefined;\n\n // Start with the union mask and any values as the base\n let shapeKey = hashValue([mask, def.values]);\n\n for (const nestedDef of defs) {\n const nestedMask = nestedDef.mask;\n\n mask |= nestedMask;\n\n // load the shape key and also reify the shape if not yet reified\n shapeKey += nestedDef.shapeKey;\n\n if ((nestedMask & Mask.UNION) !== 0) {\n // Merge nested union into parent union\n const nestedUnion = nestedDef as UnionDef;\n\n // Check typename field consistency\n if (nestedUnion.typenameField !== undefined) {\n if (unionTypenameField !== undefined && unionTypenameField !== nestedUnion.typenameField) {\n throw new Error(\n `Union typename field conflict: Cannot merge unions with different typename fields ('${unionTypenameField}' vs '${nestedUnion.typenameField}')`,\n );\n }\n unionTypenameField = nestedUnion.typenameField;\n }\n\n const nestedShape = nestedUnion.shape;\n\n // Merge nested union's shape into parent\n if (nestedShape !== undefined) {\n for (const key of [...Object.keys(nestedShape), ARRAY_KEY, RECORD_KEY] as const) {\n // Check for conflicts\n const value = nestedShape[key];\n\n if (shape[key] !== undefined && shape[key] !== value) {\n throw new Error(\n `Union merge conflict: Duplicate typename value '${String(key)}' found when merging nested unions (${String(shape[key])} vs ${String(value)})`,\n );\n }\n\n // coerce type because we know the value is the same type as the key\n shape[key] = value as any;\n }\n }\n } else if ((nestedMask & Mask.ARRAY) !== 0) {\n if (shape[ARRAY_KEY] !== undefined) {\n throw new Error('Array shape already defined');\n }\n\n shape[ARRAY_KEY] = nestedDef.shape as TypeDef;\n } else if ((nestedMask & Mask.RECORD) !== 0) {\n if (shape[RECORD_KEY] !== undefined) {\n throw new Error('Record shape already defined');\n }\n\n shape[RECORD_KEY] = nestedDef.shape as TypeDef;\n } else {\n // definition is ObjectDef | EntityDef\n const typenameField = (nestedDef as ObjectDef).typenameField;\n const typename = (nestedDef as ObjectDef).typenameValue;\n\n if (typename === undefined) {\n throw new Error(\n 'Object definitions must have a typename to be in a union with other objects, records, or arrays',\n );\n }\n\n if (unionTypenameField !== undefined && typenameField !== unionTypenameField) {\n throw new Error('Object definitions must have the same typename field to be in the same union');\n }\n\n unionTypenameField = typenameField;\n shape[typename] = nestedDef as ObjectDef;\n }\n }\n\n def.typenameField = unionTypenameField;\n def.shapeKey = shapeKey >>> 0;\n def.mask = mask;\n\n return shape;\n}\n\n// -----------------------------------------------------------------------------\n// Marker Functions\n// -----------------------------------------------------------------------------\n\nfunction defineTypename<T extends string>(value: T): T {\n return value;\n}\n\nfunction defineConst<T extends string | boolean | number>(value: T): Set<T> {\n return new Set([value]);\n}\n\nconst defineEnum = (<T extends readonly (string | boolean | number)[]>(...values: T): Set<T[number]> => {\n return new Set(values as unknown as T[number][]);\n}) as unknown as APITypes['enum'];\n\ndefineEnum.caseInsensitive = <T extends readonly (string | boolean | number)[]>(\n ...values: T\n): CaseInsensitiveSet<T[number]> => {\n return new CaseInsensitiveSet(values as unknown as T[number][]);\n};\n\n// -----------------------------------------------------------------------------\n// Formatted Values\n// -----------------------------------------------------------------------------\n\nconst FORMAT_MASK_SHIFT = 16;\n\nlet nextFormatId = 0;\nconst FORMAT_PARSERS: ((value: unknown) => unknown)[] = [];\nconst FORMAT_SERIALIZERS: ((value: unknown) => unknown)[] = [];\nconst FORMAT_MAP = new Map<string, number>();\nconst FORMAT_ID_TO_NAME = new Map<number, string>();\n\nfunction defineFormatted<K extends keyof SignaliumQuery.FormatRegistry>(\n format: K,\n): Formatted<SignaliumQuery.FormatRegistry[K]> {\n const mask = FORMAT_MAP.get(format);\n\n if (mask === undefined) {\n throw new Error(`Format ${format} not registered`);\n }\n\n return mask as Formatted<SignaliumQuery.FormatRegistry[K]>;\n}\n\nexport function getFormat(mask: number): (value: unknown) => unknown {\n const formatId = mask >> FORMAT_MASK_SHIFT;\n\n return FORMAT_PARSERS[formatId];\n}\n\nexport function getFormatSerializer(mask: number): ((value: unknown) => unknown) | undefined {\n const formatId = mask >> FORMAT_MASK_SHIFT;\n return FORMAT_SERIALIZERS[formatId];\n}\n\nexport function getFormatName(mask: number): string | undefined {\n const formatId = mask >> FORMAT_MASK_SHIFT;\n return FORMAT_ID_TO_NAME.get(formatId);\n}\n\nexport function registerFormat<Input extends Mask.STRING | Mask.NUMBER, T>(\n name: string,\n type: Input,\n parse: (value: Input extends Mask.STRING ? string : number) => T,\n serialize: (value: T) => Input extends Mask.STRING ? string : number,\n) {\n const maskId = nextFormatId++;\n FORMAT_PARSERS[maskId] = parse as (value: unknown) => unknown;\n FORMAT_SERIALIZERS[maskId] = serialize as (value: unknown) => unknown;\n FORMAT_ID_TO_NAME.set(maskId, name);\n\n const shiftedId = maskId << FORMAT_MASK_SHIFT;\n const formatMask = type === Mask.STRING ? Mask.HAS_STRING_FORMAT : Mask.HAS_NUMBER_FORMAT;\n const mask = shiftedId | type | formatMask;\n\n FORMAT_MAP.set(name, mask);\n}\n\n// -----------------------------------------------------------------------------\n// Built-in Formats\n// -----------------------------------------------------------------------------\n\n// Register 'date' format: ISO date string (YYYY-MM-DD) ↔ Date\nregisterFormat(\n 'date',\n Mask.STRING,\n value => {\n // Parse YYYY-MM-DD as UTC date to avoid timezone issues\n const match = value.match(/^(\\d{4})-(\\d{2})-(\\d{2})$/);\n if (!match) {\n throw new Error(`Invalid date string: ${value}. Expected YYYY-MM-DD format.`);\n }\n const [, year, month, day] = match;\n const date = new Date(Date.UTC(parseInt(year, 10), parseInt(month, 10) - 1, parseInt(day, 10)));\n if (isNaN(date.getTime())) {\n throw new Error(`Invalid date string: ${value}`);\n }\n return date;\n },\n value => {\n // Format as YYYY-MM-DD using UTC to avoid timezone issues\n const year = value.getUTCFullYear();\n const month = String(value.getUTCMonth() + 1).padStart(2, '0');\n const day = String(value.getUTCDate()).padStart(2, '0');\n return `${year}-${month}-${day}`;\n },\n);\n\n// Register 'date-time' format: ISO datetime string (ISO 8601) ↔ Date\nregisterFormat(\n 'date-time',\n Mask.STRING,\n value => {\n const date = new Date(value);\n if (isNaN(date.getTime())) {\n throw new Error(`Invalid date-time string: ${value}`);\n }\n return date;\n },\n value => {\n // Format as ISO 8601 string\n return value.toISOString();\n },\n);\n\n// -----------------------------------------------------------------------------\n// Entity Definitions\n// -----------------------------------------------------------------------------\n\n/**\n * Creates an entity definition with optional methods.\n *\n * @param shape - Lazy factory function that returns the entity's field definitions\n * @param methods - Optional lazy factory function that returns methods for the entity.\n * Methods have access to `this` typed as the reified entity shape.\n * Methods are wrapped with reactiveMethod for automatic caching.\n *\n * @example\n * const User = entity(\n * () => ({\n * __typename: t.typename('User'),\n * id: t.id,\n * name: t.string,\n * age: t.number,\n * }),\n * () => ({\n * greet() {\n * return `Hello, ${this.name}!`;\n * },\n * isAdult() {\n * return this.age >= 18;\n * },\n * })\n * );\n */\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\nexport function entity<T extends ObjectShape, M extends EntityMethods = {}>(\n shape: () => T,\n methods?: () => M & ThisType<M & Prettify<ExtractTypesFromShape<T>>>,\n config?: EntityConfig<T>,\n): EntityDef<T, M> {\n const def = new ValidatorDef(\n ComplexTypeDefKind.ENTITY,\n // The mask should be OBJECT | ENTITY so that values match when compared\n Mask.ENTITY | Mask.OBJECT,\n shape,\n );\n\n if (methods) {\n def._methodsFactory = methods as () => EntityMethods;\n }\n\n if (config) {\n // `any` because of infinite recursive type issue\n (def as any)._entityConfig = config;\n }\n\n return def as unknown as EntityDef<T, M>;\n}\n\nexport const t: APITypes = {\n format: defineFormatted,\n typename: defineTypename,\n const: defineConst,\n enum: defineEnum,\n id: Mask.ID | Mask.STRING | Mask.NUMBER,\n string: Mask.STRING,\n number: Mask.NUMBER,\n boolean: Mask.BOOLEAN,\n null: Mask.NULL,\n undefined: Mask.UNDEFINED,\n array: defineArray,\n object: defineObject,\n record: defineRecord,\n union: defineUnion,\n nullish: defineNullish,\n optional: defineOptional,\n nullable: defineNullable,\n result: defineParseResult,\n};\n","import {\n ARRAY_KEY,\n ArrayDef,\n EntityDef,\n Mask,\n ObjectDef,\n RECORD_KEY,\n RecordDef,\n ObjectFieldTypeDef,\n UnionDef,\n} from './types.js';\nimport { CaseInsensitiveSet, getFormatName } from './typeDefs.js';\n\nexport function typeToString(type: ObjectFieldTypeDef): string {\n // Handle case-insensitive enum sets\n if (type instanceof CaseInsensitiveSet) {\n const values = Array.from(type).map(v => (typeof v === 'string' ? `\"${v}\"` : String(v)));\n return values.join(' | ');\n }\n\n // Handle Set-based constants/enums\n if (type instanceof Set) {\n const values = Array.from(type).map(v => (typeof v === 'string' ? `\"${v}\"` : String(v)));\n return values.join(' | ');\n }\n\n // Handle constants\n if (typeof type === 'string') {\n return `\"${type}\"`;\n }\n\n if (typeof type === 'boolean') {\n return String(type);\n }\n\n // Handle primitive masks\n if (typeof type === 'number') {\n // Check for formatted types first\n const hasFormat = (type & (Mask.HAS_STRING_FORMAT | Mask.HAS_NUMBER_FORMAT)) !== 0;\n if (hasFormat) {\n const formatName = getFormatName(type);\n if (formatName) {\n // Show format name instead of base type\n return `\"${formatName}\"`;\n }\n }\n\n const types: string[] = [];\n\n if (type & Mask.UNDEFINED) types.push('undefined');\n if (type & Mask.NULL) types.push('null');\n if (type & Mask.NUMBER) types.push('number');\n if (type & Mask.STRING) types.push('string');\n if (type & Mask.BOOLEAN) types.push('boolean');\n if (type & Mask.OBJECT) types.push('object');\n if (type & Mask.ARRAY) types.push('array');\n\n if (types.length === 0) {\n return 'unknown';\n }\n\n return types.length === 1 ? types[0] : types.join(' | ');\n }\n\n // Handle complex types - CHECK UNION FIRST since it contains other types\n let mask = type.mask;\n\n if (mask & Mask.UNION) {\n const unionType = type as UnionDef;\n const parts: string[] = [];\n\n // Add const/enum values from the values Set\n if (unionType.values !== undefined && unionType.values.size > 0) {\n for (const val of unionType.values) {\n const valStr = typeof val === 'string' ? `\"${val}\"` : String(val);\n parts.push(valStr);\n }\n }\n\n // Add complex types from the shape object\n if (unionType.shape !== undefined) {\n if (unionType.shape[ARRAY_KEY] !== undefined) {\n parts.push(`Array<${typeToString(unionType.shape[ARRAY_KEY] as ObjectFieldTypeDef)}>`);\n }\n\n if (unionType.shape[RECORD_KEY] !== undefined) {\n parts.push(`Record<string, ${typeToString(unionType.shape[RECORD_KEY] as ObjectFieldTypeDef)}>`);\n }\n\n // Add entity/object types by typename\n for (const [key, value] of Object.entries(unionType.shape)) {\n if (key !== (ARRAY_KEY as any) && key !== (RECORD_KEY as any)) {\n // key is the typename value (e.g., \"User\", \"Post\")\n parts.push(key);\n }\n }\n }\n\n mask = unionType.mask;\n\n // Check for formatted types in union mask\n const hasFormat = (mask & (Mask.HAS_STRING_FORMAT | Mask.HAS_NUMBER_FORMAT)) !== 0;\n if (hasFormat) {\n const formatName = getFormatName(mask);\n if (formatName) {\n parts.push(`\"${formatName}\"`);\n }\n }\n\n // Add primitive types from the mask\n if (mask & Mask.UNDEFINED) parts.push('undefined');\n if (mask & Mask.NULL) parts.push('null');\n if (mask & Mask.NUMBER) parts.push('number');\n if (mask & Mask.STRING) parts.push('string');\n if (mask & Mask.BOOLEAN) parts.push('boolean');\n\n if (parts.length === 0) {\n return 'union';\n }\n\n return parts.join(' | ');\n }\n\n if (mask & Mask.ENTITY) {\n return `Entity<${(type as EntityDef).typenameValue}>`;\n }\n\n if (mask & Mask.ARRAY) {\n const shape = (type as ArrayDef).shape;\n return `Array<${typeToString(shape)}>`;\n }\n\n if (mask & Mask.RECORD) {\n const shape = (type as RecordDef).shape;\n return `Record<string, ${typeToString(shape)}>`;\n }\n\n if (mask & Mask.OBJECT) {\n const typename = (type as ObjectDef).typenameValue;\n return typename ? `Object<${typename}>` : 'object';\n }\n\n return 'unknown';\n}\n\nexport function typeError(path: string, expectedType: ObjectFieldTypeDef, value: unknown): Error {\n return new TypeError(\n `Validation error at ${path}: expected ${typeToString(expectedType)}, got ${\n typeof value === 'object' ? (value === null ? 'null' : Array.isArray(value) ? 'array' : 'object') : typeof value\n }`,\n );\n}\n","import { Mask } from './types.js';\n\nconst isArray = Array.isArray;\n\nexport function typeMaskOf(value: unknown): Mask {\n if (value === null) return Mask.NULL;\n\n switch (typeof value) {\n case 'number':\n return Mask.NUMBER;\n case 'string':\n return Mask.STRING;\n case 'boolean':\n return Mask.BOOLEAN;\n case 'undefined':\n return Mask.UNDEFINED;\n case 'object':\n return isArray(value) ? Mask.ARRAY : Mask.OBJECT;\n default:\n throw new Error(`Invalid type: ${typeof value}`);\n }\n}\n\n// ================================\n// Draft Helper Types\n// ================================\n\n/**\n * Recursively makes all properties of T mutable (removes readonly).\n * This is the return type of the draft() function.\n */\nexport type Draft<T> = T extends readonly (infer U)[]\n ? Draft<U>[]\n : T extends Date\n ? Date\n : T extends Map<infer K, infer V>\n ? Map<Draft<K>, Draft<V>>\n : T extends Set<infer U>\n ? Set<Draft<U>>\n : T extends object\n ? { -readonly [K in keyof T]: Draft<T[K]> }\n : T;\n\n/**\n * Deep clones an entity or object, returning a plain mutable copy.\n * This is useful for creating a \"draft\" version of an entity that can be modified\n * before being passed to a mutation.\n *\n * The draft is a plain JavaScript object (not an entity proxy), so:\n * - All fields are mutable via property assignment\n * - Changes don't affect the original entity\n * - When passed to a mutation, it's serialized as a normal object\n *\n * @example\n * ```ts\n * // Get an entity from a query\n * const user = await getUser({ id: '123' });\n *\n * // Create a draft to modify\n * const updatedUser = draft(user);\n * updatedUser.name = 'New Name';\n * updatedUser.email = 'new@example.com';\n *\n * // Pass to mutation\n * await updateUser().run(updatedUser);\n * ```\n *\n * @param entity - The entity or object to clone\n * @returns A deep clone of the entity as a plain mutable object\n */\nexport function draft<T>(entity: T): Draft<T> {\n return deepClone(entity) as Draft<T>;\n}\n\n/**\n * Deep clones a value, handling objects, arrays, and primitives.\n * Entity proxies are converted to plain objects by reading all enumerable properties.\n */\nfunction deepClone<T>(value: T): T {\n // Handle null and primitives\n if (value === null || typeof value !== 'object') {\n return value;\n }\n\n // Handle arrays\n if (isArray(value)) {\n return value.map(item => deepClone(item)) as T;\n }\n\n // Handle Date objects\n if (value instanceof Date) {\n return new Date(value.getTime()) as T;\n }\n\n // Handle Map\n if (value instanceof Map) {\n const clonedMap = new Map();\n for (const [k, v] of value) {\n clonedMap.set(deepClone(k), deepClone(v));\n }\n return clonedMap as T;\n }\n\n // Handle Set\n if (value instanceof Set) {\n const clonedSet = new Set();\n for (const v of value) {\n clonedSet.add(deepClone(v));\n }\n return clonedSet as T;\n }\n\n // Handle plain objects (including entity proxies)\n // For entity proxies, reading properties will extract the underlying data\n const result: Record<string, unknown> = {};\n\n // Get all enumerable own properties (works for both plain objects and proxies)\n for (const key of Object.keys(value as object)) {\n result[key] = deepClone((value as Record<string, unknown>)[key]);\n }\n\n return result as T;\n}\n","import { reactiveMethod, setScopeOwner } from 'signalium';\nimport { typeError } from './errors.js';\nimport { CaseInsensitiveSet, getFormat, ValidatorDef } from './typeDefs.js';\nimport {\n ARRAY_KEY,\n ComplexTypeDef,\n EntityDef,\n Mask,\n ObjectDef,\n RECORD_KEY,\n ObjectFieldTypeDef,\n UnionDef,\n TypeDef,\n RecordDef,\n} from './types.js';\nimport { typeMaskOf } from './utils.js';\nimport { PreloadedEntityRecord } from './EntityMap.js';\n\nexport type WarnFn = (message: string, context?: Record<string, unknown>) => void;\nconst noopWarn: WarnFn = () => {};\n\nconst entries = Object.entries;\nconst isArray = Array.isArray;\n\nconst PROXY_ID = new WeakMap();\n\n// Placeholder class used as the prototype for entity proxies.\n// This prevents them from being treated as plain objects in utilities like `hashValue()`.\nexport class Entity {}\n\nfunction parseUnionValue(\n valueType: number,\n value: Record<string, unknown> | unknown[],\n unionDef: UnionDef,\n path: string,\n warn: WarnFn = noopWarn,\n): unknown {\n if (valueType === Mask.ARRAY) {\n const shape = unionDef.shape![ARRAY_KEY];\n\n if (shape === undefined || typeof shape === 'number') {\n return value;\n }\n\n return parseArrayValue(value as unknown[], shape, path, warn);\n } else {\n // Use the cached typename field from the union definition\n const typenameField = unionDef.typenameField;\n const typename = typenameField ? (value as Record<string, unknown>)[typenameField] : undefined;\n\n if (typename === undefined || typeof typename !== 'string') {\n const recordShape = unionDef.shape![RECORD_KEY];\n\n if (recordShape === undefined || typeof recordShape === 'number') {\n // Union of objects/entities requires typename for discrimination\n throw new Error(\n `Typename field '${typenameField}' is required for union discrimination but was not found in the data`,\n );\n }\n\n return parseRecordValue(value as Record<string, unknown>, recordShape as ComplexTypeDef, path, warn);\n }\n\n const matchingDef = unionDef.shape![typename];\n\n if (matchingDef === undefined || typeof matchingDef === 'number') {\n throw new Error(`Unknown typename '${typename}' in union`);\n }\n\n return parseObjectValue(value as Record<string, unknown>, matchingDef as ObjectDef | EntityDef, path, warn);\n }\n}\n\nexport function parseArrayValue(array: unknown[], arrayShape: TypeDef, path: string, warn: WarnFn = noopWarn) {\n const result: unknown[] = [];\n\n for (let i = 0; i < array.length; i++) {\n try {\n result.push(parseValue(array[i], arrayShape, `${path}[${i}]`, false, warn));\n } catch (e) {\n warn('Failed to parse array item, filtering out', {\n index: i,\n value: array[i],\n error: e instanceof Error ? e.message : String(e),\n });\n }\n }\n\n return result;\n}\n\nexport function parseRecordValue(\n record: Record<string, unknown>,\n recordShape: ObjectFieldTypeDef,\n path: string,\n warn: WarnFn = noopWarn,\n) {\n for (const [key, value] of entries(record)) {\n record[key] = parseValue(value, recordShape, `${path}[\"${key}\"]`, false, warn);\n }\n\n return record;\n}\n\nexport function parseObjectValue(\n object: Record<string, unknown>,\n objectShape: ObjectDef | EntityDef,\n path: string,\n warn: WarnFn = noopWarn,\n) {\n if (PROXY_ID.has(object)) {\n // Is an entity proxy, so return it directly\n return object;\n }\n\n const shape = objectShape.shape;\n\n for (const [key, propShape] of entries(shape)) {\n // parse and replace the property in place\n object[key] = parseValue(object[key], propShape, `${path}.${key}`, false, warn);\n }\n\n return object;\n}\n\nexport function parseValue(\n value: unknown,\n propDef: ObjectFieldTypeDef,\n path: string,\n skipFallbacks = false,\n warn: WarnFn = noopWarn,\n): unknown {\n // Handle case-insensitive enums\n if (propDef instanceof CaseInsensitiveSet) {\n const canonical = propDef.get(value);\n if (canonical === undefined) {\n throw typeError(path, propDef as any, value);\n }\n return canonical; // Return the canonical casing\n }\n\n // Handle Set-based constants/enums\n if (propDef instanceof Set) {\n if (!propDef.has(value as string | boolean | number)) {\n throw typeError(path, propDef as any, value);\n }\n return value;\n }\n\n switch (typeof propDef) {\n case 'string':\n // If value is undefined/null, return the typename from definition\n if (value === undefined || value === null) {\n return propDef;\n }\n if (value !== propDef) {\n throw typeError(path, propDef, value);\n }\n\n return value;\n\n // handle primitives\n case 'number': {\n let valueType = typeMaskOf(value);\n\n if ((propDef & valueType) === 0) {\n if (!skipFallbacks && (propDef & Mask.UNDEFINED) !== 0) {\n warn('Invalid value for optional type, defaulting to undefined', { value, path });\n return undefined;\n }\n throw typeError(path, propDef, value);\n }\n\n // Check if this field has a format - if so, parse with the format parser\n if ((propDef & (Mask.HAS_STRING_FORMAT | Mask.HAS_NUMBER_FORMAT)) !== 0) {\n // Lazy format parsing: parse the raw value using the format parser\n try {\n return getFormat(propDef)(value);\n } catch (e) {\n if (!skipFallbacks && (propDef & Mask.UNDEFINED) !== 0) {\n warn('Invalid formatted value for optional type, defaulting to undefined', {\n value,\n path,\n error: e instanceof Error ? e.message : String(e),\n });\n return undefined;\n }\n throw e;\n }\n }\n\n return value;\n }\n\n // handle complex objects\n default: {\n // Note: Keep in mind that at this point, we're using `valueType`\n // primarily, so some of the logic is \"reversed\" from the above where\n // we use the `propDef` type primarily\n let valueType = typeMaskOf(value);\n const propMask = propDef.mask;\n\n // Handle parseResult wrapper - wraps parsing in try-catch and returns discriminated union\n // Pass skipFallbacks=true so errors are thrown instead of defaulting to undefined\n if ((propMask & Mask.PARSE_RESULT) !== 0) {\n try {\n const innerResult = parseValue(value, propDef.shape as ObjectFieldTypeDef, path, true, warn);\n return { success: true as const, value: innerResult };\n } catch (e) {\n return { success: false as const, error: e instanceof Error ? e : new Error(String(e)) };\n }\n }\n\n // Check if the value type is allowed by the propMask\n // Also check if it's in a values set (for enums/constants stored in ValidatorDef)\n if ((propMask & valueType) === 0 && !propDef.values?.has(value as string | boolean | number)) {\n if (!skipFallbacks && (propMask & Mask.UNDEFINED) !== 0) {\n warn('Invalid value for optional type, defaulting to undefined', { value, path });\n return undefined;\n }\n throw typeError(path, propMask, value);\n }\n\n if (valueType < Mask.OBJECT) {\n // Check if this field has a format - if so, parse with the format parser\n if ((propMask & (Mask.HAS_STRING_FORMAT | Mask.HAS_NUMBER_FORMAT)) !== 0) {\n try {\n return getFormat(propMask)(value);\n } catch (e) {\n if (!skipFallbacks && (propMask & Mask.UNDEFINED) !== 0) {\n warn('Invalid formatted value for optional type, defaulting to undefined', {\n value,\n path,\n error: e instanceof Error ? e.message : String(e),\n });\n return undefined;\n }\n throw e;\n }\n }\n\n // value is a primitive, it has already passed the mask so return it now\n return value;\n }\n\n if ((propMask & Mask.UNION) !== 0) {\n return parseUnionValue(\n valueType,\n value as Record<string, unknown> | unknown[],\n propDef as UnionDef,\n path,\n warn,\n );\n }\n\n if (valueType === Mask.ARRAY) {\n return parseArrayValue(value as unknown[], propDef.shape as ComplexTypeDef, path, warn);\n }\n\n if ((propMask & Mask.RECORD) !== 0) {\n return parseRecordValue(value as Record<string, unknown>, (propDef as RecordDef).shape, path, warn);\n }\n\n return parseObjectValue(value as Record<string, unknown>, propDef as ObjectDef | EntityDef, path, warn);\n }\n }\n}\n\n/**\n * Deep merge two objects, with the update object taking precedence.\n * Arrays are replaced, not merged.\n * Handles nested objects recursively.\n */\nexport function mergeValues<T extends Record<string, unknown>>(\n target: Record<string, unknown>,\n update: Record<string, unknown>,\n): T {\n // Iterate over update properties\n for (const [key, value] of entries(update)) {\n const targetValue = target[key];\n // Only merge if both value and targetValue are plain objects (not arrays or proxies)\n if (\n typeof value === 'object' &&\n value !== null &&\n !isArray(value) &&\n !PROXY_ID.has(value) &&\n typeof targetValue === 'object' &&\n targetValue !== null &&\n !isArray(targetValue) &&\n !PROXY_ID.has(targetValue)\n ) {\n mergeValues(targetValue as Record<string, unknown>, value as Record<string, unknown>);\n } else {\n target[key] = value;\n }\n }\n\n return target as T;\n}\n\nconst CustomNodeInspect = Symbol.for('nodejs.util.inspect.custom');\n\nexport function createEntityProxy(\n id: number,\n entityRecord: PreloadedEntityRecord,\n def: ObjectDef | EntityDef,\n entityRelay: any,\n scopeOwner: object,\n warn: WarnFn = noopWarn,\n desc?: string,\n): Record<string, unknown> {\n // Cache for nested proxies - each proxy gets its own cache\n const shape = def.shape;\n\n // Get cached methods from the definition (evaluated once during reifyShape)\n const methods = (def as ValidatorDef<unknown>).methods;\n\n // Cache for wrapped reactive methods - each proxy gets its own bound methods\n const wrappedMethods = new Map<string, (...args: unknown[]) => unknown>();\n\n const toJSON = () => ({\n __entityRef: id,\n });\n\n // We need to declare proxy first so we can reference it in the handler\n let proxy: Record<string, unknown>;\n\n const handler: ProxyHandler<object> = {\n getPrototypeOf() {\n return Entity.prototype;\n },\n\n get(target, prop) {\n // Handle toJSON for serialization\n if (prop === 'toJSON') {\n return toJSON;\n }\n\n const { data, cache, notifier } = entityRecord;\n\n // Access relay value if it exists - this will activate it when watched in reactive context\n // The relay access happens here to establish tracking when signal.value is read\n // eslint-disable-next-line @typescript-eslint/no-unused-expressions\n entityRelay?.value;\n\n notifier.consume();\n\n // Check cache first, BEFORE any expensive checks\n if (cache.has(prop)) {\n return cache.get(prop);\n }\n\n // Check for method access\n if (methods && typeof prop === 'string' && prop in methods) {\n let wrapped = wrappedMethods.get(prop);\n if (!wrapped) {\n // Create reactive method wrapper bound to the proxy\n // Bind the method to the proxy so `this` refers to the entity\n wrapped = reactiveMethod(proxy, methods[prop].bind(proxy));\n wrappedMethods.set(prop, wrapped);\n }\n return wrapped;\n }\n\n const value = data[prop as string];\n const propDef = shape[prop as string];\n\n if (!Object.hasOwnProperty.call(shape, prop)) {\n return value;\n }\n\n const parsed = parseValue(value, propDef, `[[${desc}]].${prop as string}`, false, warn);\n\n cache.set(prop, parsed);\n\n return parsed;\n },\n\n has(target, prop) {\n // Include methods in the \"in\" check\n if (methods && typeof prop === 'string' && prop in methods) {\n return true;\n }\n return prop in shape;\n },\n\n ownKeys(target) {\n const keys = Object.keys(shape);\n // Add typename field if it exists on the definition\n const typenameField = (def as ObjectDef | EntityDef).typenameField;\n if (typenameField && !keys.includes(typenameField)) {\n keys.push(typenameField);\n }\n // Add method keys\n if (methods) {\n for (const methodKey of Object.keys(methods)) {\n if (!keys.includes(methodKey)) {\n keys.push(methodKey);\n }\n }\n }\n return keys;\n },\n\n getOwnPropertyDescriptor(target, prop) {\n const typenameField = (def as ObjectDef | EntityDef).typenameField;\n if (prop in shape || prop === typenameField) {\n return {\n enumerable: true,\n configurable: true,\n };\n }\n // Methods are non-enumerable (like regular object methods)\n if (methods && typeof prop === 'string' && prop in methods) {\n return {\n enumerable: false,\n configurable: true,\n };\n }\n return undefined;\n },\n };\n\n proxy = new Proxy<Record<string, unknown>>(\n {\n [CustomNodeInspect]: () => {\n return Object.keys(shape).reduce(\n (acc, key) => {\n acc[key] = proxy[key];\n return acc;\n },\n {} as Record<string, unknown>,\n );\n },\n } as Record<string, unknown>,\n handler,\n );\n\n // Add the proxy to the proxy brand set so we can easily identify it later\n PROXY_ID.set(proxy, id);\n\n // Associate the proxy with a scope owner for reactive method caching\n setScopeOwner(proxy, scopeOwner);\n\n return proxy;\n}\n\nexport function getProxyId(object: Record<string, unknown>): number | undefined {\n return PROXY_ID.get(object);\n}\n","import { relay, DiscriminatedReactivePromise, Notifier, notifier } from 'signalium';\nimport { EntityDef } from './types.js';\nimport { createEntityProxy, mergeValues } from './proxy.js';\nimport type { QueryClient } from './QueryClient.js';\nimport { ValidatorDef } from './typeDefs.js';\n\n/**\n * Deep clone an object, handling nested objects and arrays.\n * Used for snapshotting entity data before optimistic updates.\n */\nfunction deepClone<T>(value: T): T {\n if (value === null || typeof value !== 'object') {\n return value;\n }\n\n if (Array.isArray(value)) {\n return value.map(item => deepClone(item)) as T;\n }\n\n if (value instanceof Date) {\n return new Date(value.getTime()) as T;\n }\n\n // For plain objects, create a shallow copy and recursively clone values\n const cloned = {} as Record<string, unknown>;\n for (const key of Object.keys(value)) {\n cloned[key] = deepClone((value as Record<string, unknown>)[key]);\n }\n return cloned as T;\n}\n\nexport interface PreloadedEntityRecord {\n key: number;\n data: Record<string, unknown>;\n notifier: Notifier;\n cache: Map<PropertyKey, any>;\n id?: string | number;\n proxy?: Record<string, unknown>;\n entityRefs?: Set<number>;\n}\n\nexport type EntityRecord = Required<PreloadedEntityRecord>;\n\n/**\n * Tracks pending optimistic updates for an entity.\n * Includes the snapshot of original data for rollback.\n */\ninterface PendingOptimisticUpdate {\n snapshot: Record<string, unknown>; // Original data before optimistic update\n}\n\nexport class EntityStore {\n private map = new Map<number, PreloadedEntityRecord | EntityRecord>();\n private queryClient: QueryClient;\n\n /**\n * Tracks pending optimistic updates by entity key.\n * Each entity can only have one pending update at a time (throws if concurrent).\n */\n private pendingOptimisticUpdates = new Map<number, PendingOptimisticUpdate>();\n\n constructor(queryClient: QueryClient) {\n this.queryClient = queryClient;\n }\n\n hasEntity(key: number): boolean {\n return this.map.has(key);\n }\n\n getEntity(key: number): PreloadedEntityRecord | EntityRecord | undefined {\n return this.map.get(key);\n }\n\n getNestedEntityRefIds(key: number, refIds: Set<number>): Set<number> {\n const record = this.getEntity(key);\n\n if (record === undefined) {\n throw new Error(`Entity ${key} not found when getting nested entity ref ids`);\n }\n\n refIds.add(key);\n\n // Entangle the signal value. Whenever the signal value is updated, refIds\n // will also be updated, so no need for a second signal.\n record.notifier.consume();\n\n if (record.entityRefs !== undefined) {\n for (const ref of record.entityRefs) {\n this.getNestedEntityRefIds(ref, refIds);\n }\n }\n\n return refIds;\n }\n\n hydratePreloadedEntity(key: number, shape: EntityDef): EntityRecord {\n const record = this.getEntity(key);\n if (record === undefined) {\n throw new Error(`Entity ${key} not found`);\n }\n\n record.proxy = this.createEntityProxy(record, shape);\n\n return record as EntityRecord;\n }\n\n setPreloadedEntity(key: number, data: Record<string, unknown>): PreloadedEntityRecord {\n const record: PreloadedEntityRecord = {\n key,\n data,\n notifier: notifier(),\n cache: new Map(),\n id: undefined,\n proxy: undefined,\n entityRefs: undefined,\n };\n\n this.map.set(key, record);\n\n return record;\n }\n\n setEntity(key: number, obj: Record<string, unknown>, shape: EntityDef, entityRefs?: Set<number>): EntityRecord {\n let record = this.map.get(key);\n\n if (record === undefined) {\n record = this.setPreloadedEntity(key, obj);\n\n record.proxy = this.createEntityProxy(record, shape);\n } else {\n record.data = mergeValues(record.data, obj);\n record.notifier.notify();\n record.cache.clear();\n }\n\n record.entityRefs = entityRefs;\n\n return record as EntityRecord;\n }\n\n // ======================================================\n // Optimistic Update Tracking\n // ======================================================\n\n /**\n * Register a pending optimistic update for an entity.\n * Snapshots the current state and applies the optimistic update.\n *\n * @throws Error if the entity already has a pending optimistic update\n */\n registerOptimisticUpdate(entityKey: number, fields: Record<string, unknown>): void {\n // Throw if entity already has pending optimistic updates\n if (this.pendingOptimisticUpdates.has(entityKey)) {\n throw new Error(\n `Cannot apply optimistic update: entity ${entityKey} already has a pending optimistic update from another mutation.`,\n );\n }\n\n const record = this.map.get(entityKey);\n if (!record) {\n // Entity doesn't exist yet - nothing to snapshot, just track\n this.pendingOptimisticUpdates.set(entityKey, { snapshot: {} });\n return;\n }\n\n // Deep snapshot the current data BEFORE applying the update\n const snapshot = deepClone(record.data);\n\n // Store the pending update with snapshot\n this.pendingOptimisticUpdates.set(entityKey, { snapshot });\n\n // Apply the optimistic update to the entity\n record.data = mergeValues(record.data, fields);\n record.cache.clear();\n\n // Defer notification to avoid dirtying signal within reactive context\n queueMicrotask(() => {\n record.notifier.notify();\n });\n }\n\n /**\n * Revert the optimistic update for an entity, restoring its snapshot.\n * Called when a mutation fails.\n */\n revertOptimisticUpdate(entityKey: number): void {\n const pending = this.pendingOptimisticUpdates.get(entityKey);\n if (!pending) {\n return; // No pending update to revert\n }\n\n const record = this.map.get(entityKey);\n if (record && Object.keys(pending.snapshot).length > 0) {\n // Restore the snapshot\n record.data = pending.snapshot;\n record.cache.clear();\n\n // Defer notification to avoid dirtying signal within reactive context\n queueMicrotask(() => {\n record.notifier.notify();\n });\n }\n\n // Clear the pending update\n this.pendingOptimisticUpdates.delete(entityKey);\n }\n\n /**\n * Clear the optimistic update for an entity without reverting.\n * Called when a mutation succeeds (the optimistic update is now confirmed).\n */\n clearOptimisticUpdates(entityKey: number): void {\n this.pendingOptimisticUpdates.delete(entityKey);\n }\n\n private createEntityProxy(record: PreloadedEntityRecord, shape: EntityDef): Record<string, unknown> {\n const idField = shape.idField;\n if (idField === undefined) {\n throw new Error(`Entity id field is required ${shape.typenameValue}`);\n }\n\n const id = record.data[idField];\n\n if (typeof id !== 'string' && typeof id !== 'number') {\n console.log(record.data);\n throw new Error(`Entity id must be string or number: ${shape.typenameValue}`);\n }\n\n record.id = id;\n\n let entityRelay: DiscriminatedReactivePromise<Record<string, unknown>> | undefined;\n const entityConfig = (shape as unknown as ValidatorDef<unknown>)._entityConfig;\n\n if (entityConfig?.stream) {\n entityRelay = relay(state => {\n const context = this.queryClient.getContext();\n const onUpdate = (update: Partial<Record<string, unknown>>) => {\n const currentValue = record.data;\n const merged = mergeValues(currentValue, update);\n record.data = merged;\n record.notifier.notify();\n record.cache.clear();\n };\n\n const unsubscribe = entityConfig.stream.subscribe(context, id as string | number, onUpdate as any);\n\n // Set initial value to the proxy - this resolves the relay promise\n // Proxy should always exist at this point since it's created before relay access\n state.value = record.proxy!;\n\n return unsubscribe;\n });\n }\n\n const warn = this.queryClient.getContext().log?.warn;\n return createEntityProxy(record.key, record, shape, entityRelay, this.queryClient, warn);\n }\n}\n","/**\n * NetworkManager - Tracks network connectivity status\n *\n * Features:\n * - Signal-based reactivity for online/offline status\n * - Automatic detection using navigator.onLine and events\n * - Manual override capability for testing and custom scenarios\n * - Platform-agnostic (works in browser and React Native)\n */\n\nimport { signal, Signal, context, Context } from 'signalium';\n\nexport class NetworkManager {\n private onlineSignal: Signal<boolean>;\n private manualOverride: boolean | undefined = undefined;\n private eventListenersAttached = false;\n\n constructor(initialStatus?: boolean) {\n // Initialize with manual status if provided, otherwise detect from environment\n const initialOnlineStatus = initialStatus ?? this.detectOnlineStatus();\n this.onlineSignal = signal(initialOnlineStatus);\n\n // Automatically attach event listeners if in browser/React Native environment\n if (this.canAttachListeners()) {\n this.attachEventListeners();\n }\n }\n\n /**\n * Returns true if the network is currently online\n */\n get isOnline(): boolean {\n // Manual override takes precedence\n if (this.manualOverride !== undefined) {\n return this.manualOverride;\n }\n\n return this.onlineSignal.value;\n }\n\n /**\n * Manually set the network status (useful for testing)\n */\n setNetworkStatus(online: boolean): void {\n this.manualOverride = online;\n this.onlineSignal.value = online;\n }\n\n /**\n * Clear manual override and return to automatic detection\n */\n clearManualOverride(): void {\n this.manualOverride = undefined;\n this.onlineSignal.value = this.detectOnlineStatus();\n }\n\n /**\n * Get the reactive signal for online status\n * This allows reactive functions to depend on network status\n */\n getOnlineSignal(): Signal<boolean> {\n return this.onlineSignal;\n }\n\n /**\n * Detect current online status from the environment\n */\n private detectOnlineStatus(): boolean {\n // Check if we're in a browser or React Native environment\n if (typeof navigator !== 'undefined' && 'onLine' in navigator) {\n return navigator.onLine;\n }\n\n // Default to online if we can't detect (e.g., Node.js/SSR)\n return true;\n }\n\n /**\n * Check if we can attach event listeners (browser or React Native)\n */\n private canAttachListeners(): boolean {\n return typeof window !== 'undefined' && typeof window.addEventListener === 'function';\n }\n\n /**\n * Attach event listeners for online/offline events\n */\n private attachEventListeners(): void {\n if (this.eventListenersAttached) {\n return;\n }\n\n const handleOnline = () => {\n if (this.manualOverride === undefined) {\n this.onlineSignal.value = true;\n }\n };\n\n const handleOffline = () => {\n if (this.manualOverride === undefined) {\n this.onlineSignal.value = false;\n }\n };\n\n window.addEventListener('online', handleOnline);\n window.addEventListener('offline', handleOffline);\n\n this.eventListenersAttached = true;\n\n // Note: In a real production app, you might want to provide a cleanup method\n // to remove these listeners, but for a singleton that lives for the app lifetime,\n // it's not critical\n }\n}\n\n// No-op implementation for SSR environments where network status tracking is not needed\nexport class NoOpNetworkManager {\n private static readonly onlineSignal: Signal<boolean> = signal(true);\n\n get isOnline(): boolean {\n return true;\n }\n\n setNetworkStatus(_online: boolean): void {\n // No-op: do nothing\n }\n\n clearManualOverride(): void {\n // No-op: do nothing\n }\n\n getOnlineSignal(): Signal<boolean> {\n return NoOpNetworkManager.onlineSignal;\n }\n\n destroy(): void {\n // No-op: do nothing\n }\n}\n\n// Default singleton instance for convenience\nexport const defaultNetworkManager = new NetworkManager();\n\n// Context for dependency injection\nexport const NetworkManagerContext: Context<NetworkManager> = context<NetworkManager>(defaultNetworkManager);\n","// -----------------------------------------------------------------------------\n// Entity System\n// -----------------------------------------------------------------------------\n\nimport { hashValue } from 'signalium/utils';\nimport { QueryClient } from './QueryClient.js';\nimport { parseValue } from './proxy.js';\nimport {\n ARRAY_KEY,\n ArrayDef,\n ComplexTypeDef,\n EntityDef,\n Mask,\n ObjectDef,\n ObjectFieldTypeDef,\n ParseResultDef,\n RECORD_KEY,\n RecordDef,\n UnionDef,\n} from './types.js';\nimport { typeMaskOf } from './utils.js';\n\nconst entries = Object.entries;\n\nexport function parseUnionEntities(\n valueType: number,\n value: object | unknown[],\n unionDef: UnionDef,\n queryClient: QueryClient,\n entityRefs?: Set<number>,\n): unknown {\n if (valueType === Mask.ARRAY) {\n const shape = unionDef.shape![ARRAY_KEY];\n\n if (shape === undefined || typeof shape === 'number') {\n return value;\n }\n\n return parseArrayEntities(\n value as unknown[],\n { mask: Mask.ARRAY, shape, values: undefined } as ArrayDef,\n queryClient,\n entityRefs,\n );\n } else {\n // Use the cached typename field from the union definition\n const typenameField = unionDef.typenameField;\n const typename = typenameField ? (value as Record<string, unknown>)[typenameField] : undefined;\n\n if (typename === undefined || typeof typename !== 'string') {\n const recordShape = unionDef.shape![RECORD_KEY];\n\n if (recordShape === undefined || typeof recordShape === 'number') {\n // Union of objects/entities requires typename for discrimination\n throw new Error(\n `Typename field '${typenameField}' is required for union discrimination but was not found in the data`,\n );\n }\n\n return parseRecordEntities(\n value as Record<string, unknown>,\n recordShape as ComplexTypeDef,\n queryClient,\n entityRefs,\n );\n }\n\n const matchingDef = unionDef.shape![typename];\n\n if (matchingDef === undefined || typeof matchingDef === 'number') {\n throw new Error(`Unknown typename '${typename}' in union`);\n }\n\n return parseObjectEntities(\n value as Record<string, unknown>,\n matchingDef as ObjectDef | EntityDef,\n queryClient,\n entityRefs,\n );\n }\n}\n\nexport function parseArrayEntities(\n array: unknown[],\n arrayShape: ComplexTypeDef,\n queryClient: QueryClient,\n entityRefs?: Set<number>,\n): unknown[] {\n const result: unknown[] = [];\n\n for (let i = 0; i < array.length; i++) {\n try {\n result.push(parseEntities(array[i], arrayShape, queryClient, entityRefs));\n } catch (e) {\n queryClient.getContext().log?.warn?.('Failed to parse array item, filtering out', {\n index: i,\n value: array[i],\n error: e instanceof Error ? e.message : String(e),\n });\n }\n }\n\n return result;\n}\n\nexport function parseRecordEntities(\n record: Record<string, unknown>,\n recordShape: ComplexTypeDef,\n queryClient: QueryClient,\n entityRefs?: Set<number>,\n): Record<string, unknown> {\n if (typeof recordShape === 'number') {\n return record;\n }\n\n for (const [key, value] of entries(record)) {\n record[key] = parseEntities(value, recordShape, queryClient, entityRefs);\n }\n\n return record;\n}\n\nexport function parseObjectEntities(\n obj: Record<string, unknown>,\n objectShape: ObjectDef | EntityDef,\n queryClient: QueryClient,\n entityRefs?: Set<number>,\n): Record<string, unknown> {\n const entityRefId = obj.__entityRef as number;\n\n // Check if this is an entity reference (from cache)\n if (typeof entityRefId === 'number') {\n return queryClient.hydrateEntity(entityRefId, objectShape as EntityDef).proxy;\n }\n\n // Process sub-entity paths (only these paths can contain entities)\n const { mask } = objectShape;\n\n const childRefs = mask & Mask.ENTITY ? new Set<number>() : entityRefs;\n\n // Extract shape first to resolve lazy definitions and set subEntityPaths\n const shape = objectShape.shape;\n const subEntityPaths = objectShape.subEntityPaths;\n\n if (subEntityPaths !== undefined) {\n if (typeof subEntityPaths === 'string') {\n // Single path - avoid array allocation\n const propDef = shape[subEntityPaths];\n obj[subEntityPaths] = parseEntities(obj[subEntityPaths], propDef as ComplexTypeDef, queryClient, childRefs);\n } else {\n // Multiple paths - iterate directly\n for (const path of subEntityPaths) {\n const propDef = shape[path];\n obj[path] = parseEntities(obj[path], propDef as ComplexTypeDef, queryClient, childRefs);\n }\n }\n }\n\n // Handle entity replacement (entities get cached and replaced with proxies)\n if (mask & Mask.ENTITY) {\n const entityDef = objectShape as EntityDef;\n const typename = entityDef.typenameValue;\n const id = obj[entityDef.idField];\n\n if (id === undefined) {\n throw new Error(`Entity id is required: ${typename}`);\n }\n\n const desc = `${typename}:${id}`;\n const key = hashValue(desc);\n\n // Add this entity's key to the parent's entityRefs (if provided)\n if (entityRefs !== undefined) {\n entityRefs.add(key);\n }\n\n return queryClient.saveEntity(key, obj, entityDef, childRefs).proxy;\n }\n\n // For non-entity objects, parse all fields (including enums, formatted values, etc.)\n // Entities handle this lazily via their proxy\n const warn = queryClient.getContext().log?.warn;\n for (const [key, propDef] of entries(shape)) {\n // Skip fields that were already processed as sub-entity paths\n if (subEntityPaths !== undefined) {\n if (typeof subEntityPaths === 'string' ? key === subEntityPaths : subEntityPaths.includes(key)) {\n continue;\n }\n }\n obj[key] = parseValue(\n obj[key],\n propDef as ObjectFieldTypeDef,\n `${objectShape.typenameValue ?? 'object'}.${key}`,\n false,\n warn,\n );\n }\n\n return obj;\n}\n\nexport function parseEntities(\n value: unknown,\n def: ComplexTypeDef,\n queryClient: QueryClient,\n entityRefs?: Set<number>,\n): unknown {\n const valueType = typeMaskOf(value);\n const defType = def.mask;\n\n // Handle parseResult wrapper - wraps parsing in try-catch and returns discriminated union\n if ((defType & Mask.PARSE_RESULT) !== 0) {\n try {\n const innerResult = parseEntities(\n value,\n (def as ParseResultDef).shape as ComplexTypeDef,\n queryClient,\n entityRefs,\n );\n return { success: true as const, value: innerResult };\n } catch (e) {\n return { success: false as const, error: e instanceof Error ? e : new Error(String(e)) };\n }\n }\n\n // Skip primitives and incompatible types - they can't contain entities\n // Note: We silently return incompatible values rather than erroring\n if (valueType < Mask.OBJECT || (defType & valueType) === 0) {\n return value;\n }\n\n // Handle unions first - they can contain multiple types, and all of the union\n // logic is handled above, so we return early here if it's a union\n if ((defType & Mask.UNION) !== 0) {\n return parseUnionEntities(\n valueType,\n value as Record<string, unknown> | unknown[],\n def as UnionDef,\n queryClient,\n entityRefs,\n );\n }\n\n // If it's not a union, AND the value IS an array, then the definition must\n // be an ArrayDef, so we can cast safely here\n if (valueType === Mask.ARRAY) {\n return parseArrayEntities(value as unknown[], (def as ArrayDef).shape as ComplexTypeDef, queryClient, entityRefs);\n }\n\n // Now we know the value is an object, so def must be a RecordDef, ObjectDef\n // or EntityDef. We first check to see if it's a RecordDef, and if so, we can\n // cast it here and return early.\n if ((defType & Mask.RECORD) !== 0) {\n return parseRecordEntities(\n value as Record<string, unknown>,\n (def as RecordDef).shape as ComplexTypeDef,\n queryClient,\n entityRefs,\n );\n }\n\n // Now we know the def is an ObjectDef or EntityDef. These are both handled\n // the same way _mostly_, with Entities just returning a proxy instead of the\n // object itself\n return parseObjectEntities(value as Record<string, unknown>, def as ObjectDef | EntityDef, queryClient, entityRefs);\n}\n","import {\n relay,\n type RelayState,\n DiscriminatedReactivePromise,\n Signal,\n signal,\n ReadonlySignal,\n reactiveSignal,\n Notifier,\n notifier,\n} from 'signalium';\nimport { setReactivePromise } from 'signalium/utils';\nimport { EntityDef, BaseQueryResult, ComplexTypeDef, NetworkMode, QueryExtra } from './types.js';\nimport { getProxyId, parseValue } from './proxy.js';\nimport { parseEntities, parseObjectEntities } from './parseEntities.js';\nimport { ValidatorDef } from './typeDefs.js';\nimport {\n InfiniteQueryDefinition,\n QueryDefinition,\n QueryType,\n StreamSubscribeFn,\n type AnyQueryDefinition,\n type QueryClient,\n type QueryParams,\n extractParamsForKey,\n queryKeyFor,\n} from './QueryClient.js';\nimport { CachedQuery, CachedQueryExtra } from './QueryClient.js';\n\n// ======================================================\n// QueryResultExtra - Manages stream orphans and optimistic inserts\n// ======================================================\n\n/**\n * Manages extra data for a query result: stream orphans and optimistic inserts.\n * Created lazily when first needed.\n */\nclass QueryResultExtra {\n private _streamOrphansNotifier: Notifier | undefined = undefined;\n private _streamOrphans: Set<Record<string, unknown>> | undefined = undefined;\n\n private _optimisticInsertsNotifier: Notifier | undefined = undefined;\n private _optimisticInserts: Set<Record<string, unknown>> | undefined = undefined;\n\n private onChanged: () => void;\n\n constructor(onChanged: () => void) {\n this.onChanged = onChanged;\n }\n\n private get streamOrphansNotifier(): Notifier {\n return this._streamOrphansNotifier ?? (this._streamOrphansNotifier = notifier());\n }\n\n private get optimisticInsertsNotifier(): Notifier {\n return this._optimisticInsertsNotifier ?? (this._optimisticInsertsNotifier = notifier());\n }\n\n get streamOrphans(): Set<Record<string, unknown>> {\n return this._streamOrphans ?? (this._streamOrphans = new Set());\n }\n\n get optimisticInserts(): Set<Record<string, unknown>> {\n return this._optimisticInserts ?? (this._optimisticInserts = new Set());\n }\n\n /**\n * Returns the QueryExtra object for public API consumption.\n * Consumes the notifiers to establish reactive tracking.\n */\n getExtra(): QueryExtra<unknown, unknown> {\n this.streamOrphansNotifier.consume();\n this.optimisticInsertsNotifier.consume();\n return {\n streamOrphans: this.streamOrphans,\n optimisticInserts: this.optimisticInserts,\n };\n }\n\n /**\n * Add a stream orphan entity.\n * Returns true if the orphan was added (not a duplicate).\n */\n addStreamOrphan(entity: Record<string, unknown>): boolean {\n const orphans = this.streamOrphans;\n const sizeBefore = orphans.size;\n orphans.add(entity);\n\n if (orphans.size !== sizeBefore) {\n this.streamOrphansNotifier.notify();\n\n // Check if this orphan was an optimistic insert - if so, remove it\n const proxyId = getProxyId(entity);\n if (proxyId !== undefined) {\n this.removeOptimisticInsertById(proxyId);\n }\n\n this.onChanged();\n return true;\n }\n\n return false;\n }\n\n /**\n * Add an optimistic insert entity.\n * Returns true if the insert was added (not a duplicate).\n */\n addOptimisticInsert(entity: Record<string, unknown>): boolean {\n const inserts = this.optimisticInserts;\n const sizeBefore = inserts.size;\n inserts.add(entity);\n\n if (inserts.size !== sizeBefore) {\n this.optimisticInsertsNotifier.notify();\n this.onChanged();\n return true;\n }\n\n return false;\n }\n\n /**\n * Remove an optimistic insert by its entity.\n * Returns true if the insert was removed.\n */\n removeOptimisticInsert(entity: Record<string, unknown>): boolean {\n const proxyId = getProxyId(entity);\n if (proxyId === undefined) {\n return false;\n }\n\n return this.removeOptimisticInsertById(proxyId);\n }\n\n /**\n * Remove an optimistic insert by proxy ID.\n */\n private removeOptimisticInsertById(proxyId: number): boolean {\n const inserts = this._optimisticInserts;\n if (inserts === undefined || inserts.size === 0) {\n return false;\n }\n\n for (const existing of inserts) {\n if (getProxyId(existing) === proxyId) {\n inserts.delete(existing);\n this.optimisticInsertsNotifier.notify();\n this.onChanged();\n return true;\n }\n }\n\n return false;\n }\n\n /**\n * Check if a proxy ID exists in stream orphans.\n */\n hasOrphanWithId(proxyId: number): boolean {\n const orphans = this._streamOrphans;\n if (orphans === undefined) {\n return false;\n }\n\n for (const orphan of orphans) {\n if (getProxyId(orphan) === proxyId) {\n return true;\n }\n }\n\n return false;\n }\n\n /**\n * Reconcile orphans and optimistic inserts against the main response entity refs.\n * Removes any that now exist in the main response.\n */\n reconcile(allRefIds: Set<number>): void {\n // Check stream orphans for entities that now exist in main response\n const orphans = this._streamOrphans;\n if (orphans !== undefined && orphans.size > 0) {\n let orphansChanged = false;\n\n for (const orphan of orphans) {\n const entityRefId = getProxyId(orphan);\n if (entityRefId !== undefined && allRefIds.has(entityRefId)) {\n orphans.delete(orphan);\n orphansChanged = true;\n }\n }\n\n if (orphansChanged) {\n this.streamOrphansNotifier.notify();\n }\n }\n\n // Check optimistic inserts for entities that now exist in main response or stream orphans\n const inserts = this._optimisticInserts;\n if (inserts !== undefined && inserts.size > 0) {\n let insertsChanged = false;\n\n for (const insert of inserts) {\n const entityRefId = getProxyId(insert);\n if (entityRefId !== undefined) {\n // Remove if entity is now in main response\n if (allRefIds.has(entityRefId)) {\n inserts.delete(insert);\n insertsChanged = true;\n }\n // Also remove if entity is now in stream orphans\n else if (orphans !== undefined && orphans.has(insert)) {\n inserts.delete(insert);\n insertsChanged = true;\n }\n }\n }\n\n if (insertsChanged) {\n this.optimisticInsertsNotifier.notify();\n }\n }\n }\n\n /**\n * Clear all stream orphans and optimistic inserts.\n * Called on refetch.\n */\n clear(): void {\n let changed = false;\n\n if (this._streamOrphans !== undefined && this._streamOrphans.size > 0) {\n this._streamOrphans = undefined;\n this.streamOrphansNotifier.notify();\n changed = true;\n }\n\n if (this._optimisticInserts !== undefined && this._optimisticInserts.size > 0) {\n this._optimisticInserts = undefined;\n this.optimisticInsertsNotifier.notify();\n changed = true;\n }\n\n if (changed) {\n this.onChanged();\n }\n }\n\n /**\n * Load extra data from cached values.\n */\n loadFromCache(\n cachedExtra: CachedQueryExtra,\n queryClient: QueryClient,\n streamShape: EntityDef | undefined,\n optimisticInsertsShape: EntityDef | undefined,\n ): void {\n if (cachedExtra.streamOrphanRefs && cachedExtra.streamOrphanRefs.length > 0 && streamShape) {\n const orphans = this.streamOrphans;\n for (const refId of cachedExtra.streamOrphanRefs) {\n const entityRecord = queryClient.hydrateEntity(refId, streamShape);\n orphans.add(entityRecord.proxy);\n }\n }\n\n if (cachedExtra.optimisticInsertRefs && cachedExtra.optimisticInsertRefs.length > 0 && optimisticInsertsShape) {\n const inserts = this.optimisticInserts;\n for (const refId of cachedExtra.optimisticInsertRefs) {\n const entityRecord = queryClient.hydrateEntity(refId, optimisticInsertsShape);\n inserts.add(entityRecord.proxy);\n }\n }\n }\n\n /**\n * Get extra data for persistence (converts Sets to arrays of entity ref IDs).\n */\n getForPersistence(): CachedQueryExtra | undefined {\n const orphans = this._streamOrphans;\n const inserts = this._optimisticInserts;\n\n if ((orphans === undefined || orphans.size === 0) && (inserts === undefined || inserts.size === 0)) {\n return undefined;\n }\n\n const extra: CachedQueryExtra = {};\n\n if (orphans !== undefined && orphans.size > 0) {\n extra.streamOrphanRefs = [];\n for (const orphan of orphans) {\n const refId = getProxyId(orphan);\n if (refId !== undefined) {\n extra.streamOrphanRefs.push(refId);\n }\n }\n }\n\n if (inserts !== undefined && inserts.size > 0) {\n extra.optimisticInsertRefs = [];\n for (const insert of inserts) {\n const refId = getProxyId(insert);\n if (refId !== undefined) {\n extra.optimisticInsertRefs.push(refId);\n }\n }\n }\n\n return extra;\n }\n\n /**\n * Check if there's any extra data.\n */\n get hasData(): boolean {\n return (\n (this._streamOrphans !== undefined && this._streamOrphans.size > 0) ||\n (this._optimisticInserts !== undefined && this._optimisticInserts.size > 0)\n );\n }\n}\n\n// ======================================================\n// QueryResultImpl\n// ======================================================\n\n/**\n * QueryResult wraps a DiscriminatedReactivePromise and adds additional functionality\n * like refetch, while forwarding all the base relay properties.\n * This class combines the old QueryInstance and QueryResultImpl into a single entity.\n */\nexport class QueryResultImpl<T> implements BaseQueryResult<T, unknown, unknown> {\n def: AnyQueryDefinition<any, any, any>;\n queryKey: number; // Instance key (includes Signal identity)\n storageKey: number = -1; // Storage key (extracted values only)\n\n private queryClient: QueryClient;\n private initialized: boolean = false;\n private isRefetchingSignal: Signal<boolean> = signal(false);\n private isFetchingMoreSignal: Signal<boolean> = signal(false);\n private updatedAt: number | undefined = undefined;\n private params: QueryParams | undefined = undefined;\n private refIds: Set<number> | undefined = undefined;\n\n private allNestedRefIdsSignal: ReadonlySignal<Set<number>> | undefined = undefined;\n\n private refetchPromise: Promise<T> | undefined = undefined;\n private fetchMorePromise: Promise<T> | undefined = undefined;\n private unsubscribe?: () => void = undefined;\n\n private relay: DiscriminatedReactivePromise<T>;\n private _relayState: RelayState<any> | undefined = undefined;\n private wasPaused: boolean = false;\n private currentParams: QueryParams | undefined = undefined;\n private debounceTimer: ReturnType<typeof setTimeout> | undefined = undefined;\n\n private get relayState(): RelayState<any> {\n const relayState = this._relayState;\n\n if (!relayState) {\n throw new Error('Relay state not initialized');\n }\n\n return relayState;\n }\n\n private _extra: QueryResultExtra | undefined = undefined;\n\n private get extraData(): QueryResultExtra {\n return this._extra ?? (this._extra = new QueryResultExtra(() => this.persistExtraData()));\n }\n\n private _nextPageParams: QueryParams | undefined | null = undefined;\n\n private get nextPageParams(): QueryParams | null {\n // Streams and non-infinite queries don't have pagination\n if (this.def.type !== QueryType.InfiniteQuery) {\n return null;\n }\n\n let params = this._nextPageParams;\n\n const value = this.relayState.value;\n\n if (params === undefined && value !== undefined) {\n if (!Array.isArray(value)) {\n throw new Error('Query result is not an array, this is a bug');\n }\n\n const infiniteDef = this.def as InfiniteQueryDefinition<any, any, any>;\n const nextParams = infiniteDef.pagination?.getNextPageParams?.(value[value.length - 1]);\n\n if (nextParams === undefined) {\n // store null to indicate that there is no next page, but we've already calculated\n params = null;\n } else {\n // Clone current params\n let hasDefinedParams = false;\n const clonedParams = { ...this.currentParams };\n\n // iterate over the next page params and copy any defined values to the\n for (const [key, value] of Object.entries(nextParams)) {\n if (value !== undefined && value !== null) {\n clonedParams[key] = value;\n hasDefinedParams = true;\n }\n }\n\n this._nextPageParams = params = hasDefinedParams ? clonedParams : null;\n }\n }\n\n return params ?? null;\n }\n\n constructor(\n def: AnyQueryDefinition<any, any, any>,\n queryClient: QueryClient,\n queryKey: number,\n params: QueryParams | undefined,\n ) {\n setReactivePromise(this);\n this.def = def;\n this.queryClient = queryClient;\n this.queryKey = queryKey; // Instance key (Signal identity)\n this.params = params;\n\n // Create the relay and handle activation/deactivation\n this.relay = relay<T>(state => {\n this._relayState = state;\n\n // Extract params (reading Signal values establishes tracking)\n this.currentParams = extractParamsForKey(this.params);\n this.storageKey = queryKeyFor(this.def, this.currentParams);\n\n // Load from cache first, then fetch fresh data\n this.queryClient.activateQuery(this);\n\n // Store initial offline state\n const isPaused = this.isPaused;\n this.wasPaused = isPaused;\n\n if (this.initialized) {\n if (!isPaused) {\n // For any query with streams, resubscribe on reactivation\n if (\n this.def.type === QueryType.Stream ||\n (this.def as QueryDefinition<any, any, any> | InfiniteQueryDefinition<any, any, any>).stream\n ) {\n this.setupSubscription();\n }\n\n if (this.def.type !== QueryType.Stream && this.isStale) {\n this.refetch();\n }\n }\n } else {\n this.initialize();\n }\n\n const deactivate = () => {\n // Clear debounce timer if active\n clearTimeout(this.debounceTimer);\n this.debounceTimer = undefined;\n\n // Last subscriber left, deactivate refetch and schedule memory eviction\n // Unsubscribe from any active streams\n this.unsubscribe?.();\n this.unsubscribe = undefined;\n\n // Remove from refetch manager if configured\n if (this.def.type !== QueryType.Stream && this.def.cache?.refetchInterval) {\n this.queryClient.refetchManager.removeQuery(this);\n }\n\n // Schedule removal from memory using the global eviction manager\n // This allows quick reactivation from memory if needed again soon\n // Disk cache (if configured) will still be available after eviction\n // Use queryKey for instance eviction, storageKey for cache eviction\n this.queryClient.memoryEvictionManager.scheduleEviction(this.queryKey);\n };\n\n // Return deactivation callback\n return {\n update: () => {\n const { wasPaused, isPaused } = this;\n this.wasPaused = isPaused;\n\n if (isPaused) {\n deactivate();\n\n // TODO: Add abort signal\n return;\n }\n\n // Read Signal values again to establish tracking for any new Signals\n // Extract params (reading Signal values establishes tracking)\n const newExtractedParams = extractParamsForKey(this.params);\n const newStorageKey = queryKeyFor(this.def, newExtractedParams);\n\n const paramsDidChange = newStorageKey !== this.storageKey;\n\n // Check if storage key changed (comparing hash values)\n if (paramsDidChange) {\n // Same storage key, just Signal instances changed but values are the same\n // Update params and trigger debounced refetch\n this.params = newExtractedParams as QueryParams;\n this.storageKey = newStorageKey;\n }\n\n if (wasPaused) {\n this.queryClient.activateQuery(this);\n\n if (this.def.type !== QueryType.Stream) {\n const refreshStaleOnReconnect = this.def.cache?.refreshStaleOnReconnect ?? true;\n if (refreshStaleOnReconnect && this.isStale) {\n state.setPromise(this.runQuery(this.currentParams, true));\n }\n } else {\n this.setupSubscription();\n }\n } else if (paramsDidChange) {\n if (this.def.type !== QueryType.Stream) {\n this.debouncedRefetch();\n } else {\n this.setupSubscription();\n }\n }\n },\n deactivate,\n };\n }) as DiscriminatedReactivePromise<T>;\n }\n\n // ======================================================\n // ReactivePromise properties\n // =====================================================\n\n get value(): T | undefined {\n return this.relay.value;\n }\n\n get error(): unknown {\n return this.relay.error;\n }\n\n get isPending(): boolean {\n return this.relay.isPending;\n }\n\n get isRejected(): boolean {\n return this.relay.isRejected;\n }\n\n get isResolved(): boolean {\n return this.relay.isResolved;\n }\n\n get isSettled(): boolean {\n return this.relay.isSettled;\n }\n\n get isReady(): boolean {\n return this.relay.isReady;\n }\n\n // TODO: Intimate APIs needed for `useReactive`, this is a code smell and\n // we should find a better way to entangle these more generically\n private get _version(): Signal<number> {\n return (this.relay as any)._version;\n }\n\n private get _signal(): Signal<T> {\n return (this.relay as any)._signal;\n }\n\n private get _flags(): number {\n return (this.relay as any)._flags;\n }\n\n // Forward Promise methods\n then<TResult1 = T, TResult2 = never>(\n onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | null | undefined,\n onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null | undefined,\n ): Promise<TResult1 | TResult2> {\n return this.relay.then(onfulfilled, onrejected);\n }\n\n catch<TResult = never>(\n onrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | null | undefined,\n ): Promise<T | TResult> {\n return this.relay.catch(onrejected);\n }\n\n finally(onfinally?: (() => void) | null | undefined): Promise<T> {\n return this.relay.finally(onfinally);\n }\n\n get [Symbol.toStringTag](): string {\n return 'QueryResult';\n }\n\n // ======================================================\n // Internal fetch methods\n // ======================================================\n\n private getAllEntityRefs(): Set<number> {\n let allNestedRefIdsSignal = this.allNestedRefIdsSignal;\n\n if (!allNestedRefIdsSignal) {\n const queryClient = this.queryClient;\n\n this.allNestedRefIdsSignal = allNestedRefIdsSignal = reactiveSignal(() => {\n // Entangle the relay value. Whenever the relay value is updated, the\n // allNestedRefIdsSignal will be updated, so no need for a second signal.\n // eslint-disable-next-line @typescript-eslint/no-unused-expressions\n this.relay.value;\n\n const allRefIds = new Set<number>();\n\n if (this.refIds !== undefined) {\n for (const refId of this.refIds) {\n queryClient.getNestedEntityRefIds(refId, allRefIds);\n }\n }\n\n // Reconcile extra data against the main response\n this.extraData.reconcile(allRefIds);\n\n return allRefIds;\n });\n }\n\n return allNestedRefIdsSignal.value;\n }\n\n /**\n * Initialize the query by loading from cache and fetching if stale\n */\n private async initialize(): Promise<void> {\n const state = this.relayState;\n\n this.initialized = true;\n\n let cached: CachedQuery | undefined;\n\n try {\n // Load from cache first (use storage key for cache operations)\n cached = await this.queryClient.loadCachedQuery(this.def, this.storageKey);\n\n if (cached !== undefined) {\n // Set the cached timestamp\n this.updatedAt = cached.updatedAt;\n\n // Set the cached reference IDs\n this.refIds = cached.refIds;\n\n // Load extra data (stream orphans and optimistic inserts) BEFORE setting state.value\n // because setting state.value resolves the relay\n if (cached.extra) {\n const def = this.def as QueryDefinition<any, any, any> | InfiniteQueryDefinition<any, any, any>;\n this.extraData.loadFromCache(\n cached.extra,\n this.queryClient,\n def.stream?.shape as EntityDef | undefined,\n def.optimisticInserts?.shape as EntityDef | undefined,\n );\n }\n\n // Set the value last - this resolves the relay\n const shape = this.def.shape;\n state.value =\n shape instanceof ValidatorDef\n ? parseEntities(cached.value, shape as ComplexTypeDef, this.queryClient, new Set())\n : parseValue(cached.value, shape, this.def.id);\n }\n } catch (error) {\n this.queryClient.deleteCachedQuery(this.storageKey);\n this.queryClient\n .getContext()\n .log?.warn?.('Failed to initialize query, the query cache may be corrupted or invalid', error);\n }\n\n if (this.isPaused) {\n return;\n }\n\n try {\n // Setup subscriptions (handles both StreamQuery and Query/InfiniteQuery with stream)\n if (\n this.def.type === QueryType.Stream ||\n (this.def as QueryDefinition<any, any, any> | InfiniteQueryDefinition<any, any, any>).stream\n ) {\n this.setupSubscription();\n }\n\n // For non-stream queries, fetch if stale or no cache\n if (this.def.type !== QueryType.Stream) {\n if (cached !== undefined) {\n // Check if data is stale\n if (this.isStale) {\n // Data is stale, trigger background refetch (with debounce if configured)\n if (this.def.debounce !== undefined && this.def.debounce > 0) {\n this.debouncedRefetch();\n } else {\n this.refetch();\n }\n }\n } else {\n // No cached data, fetch fresh immediately (don't debounce initial fetch)\n // Debounce only applies to refetches triggered by parameter changes\n state.setPromise(this.runQuery(this.currentParams, true));\n }\n }\n } catch (error) {\n // Relay will handle the error state automatically\n state.setError(error as Error);\n }\n }\n\n /**\n * Handle stream updates. This method handles both StreamQuery and Query/InfiniteQuery with stream options.\n * - For StreamQuery: directly updates the relay state with the entity\n * - For Query/InfiniteQuery with stream: updates entities in response or adds to orphans\n */\n private setupSubscription(): void {\n this.unsubscribe?.();\n\n let subscribeFn: StreamSubscribeFn<any, any>;\n let shapeDef: EntityDef;\n\n if (this.def.type === QueryType.Stream) {\n shapeDef = this.def.shape as EntityDef;\n subscribeFn = this.def.subscribeFn;\n } else {\n const stream = (this.def as QueryDefinition<any, any, any> | InfiniteQueryDefinition<any, any, any>).stream;\n\n if (!stream) {\n return;\n }\n\n shapeDef = stream.shape as EntityDef;\n subscribeFn = stream.subscribeFn;\n }\n\n // Extract params (reading Signal values establishes tracking)\n const extractedParams = this.currentParams;\n this.unsubscribe = subscribeFn(this.queryClient.getContext(), extractedParams as QueryParams, update => {\n const parsedData = parseObjectEntities(update, shapeDef, this.queryClient);\n\n // Update the relay state\n if (this.def.type === QueryType.Stream) {\n this.relayState.value = parsedData;\n this.updatedAt = Date.now();\n\n // Cache the data\n // Use storage key for cache operations\n this.queryClient.saveQueryData(this.def, this.storageKey, parsedData, this.updatedAt);\n } else {\n const allRefIds = this.getAllEntityRefs();\n const proxyId = getProxyId(parsedData);\n\n // Add to orphans if not in main response\n if (proxyId !== undefined && !allRefIds.has(proxyId)) {\n this.extraData.addStreamOrphan(parsedData);\n }\n }\n });\n }\n\n /**\n * Fetches fresh data, updates the cache, and updates updatedAt timestamp\n */\n private async runQuery(params: QueryParams | undefined, reset = false): Promise<T> {\n // Check if paused before attempting fetch\n if (this.isPaused) {\n throw new Error('Query is paused due to network status');\n }\n\n const { retries, retryDelay } = this.getRetryConfig();\n let lastError: unknown;\n\n // Attempt fetch with retries\n for (let attempt = 0; attempt <= retries; attempt++) {\n try {\n const queryDef = this.def as QueryDefinition<any, any, any> | InfiniteQueryDefinition<any, any, any>;\n const freshData = await queryDef.fetchFn(this.queryClient.getContext(), params);\n\n // Parse and cache the fresh data\n let entityRefs;\n\n const isInfinite = this.def.type === QueryType.InfiniteQuery;\n\n if (isInfinite && !reset && this.refIds !== undefined) {\n entityRefs = this.refIds;\n } else {\n entityRefs = this.refIds = new Set<number>();\n }\n\n const shape = this.def.shape;\n\n const parsedData =\n shape instanceof ValidatorDef\n ? parseEntities(freshData, shape as ComplexTypeDef, this.queryClient, entityRefs)\n : parseValue(freshData, shape, this.def.id);\n\n let queryData;\n\n if (isInfinite) {\n const prevQueryData = this.relayState.value;\n queryData = reset || prevQueryData === undefined ? [parsedData] : [...prevQueryData, parsedData];\n } else {\n queryData = parsedData;\n }\n\n let updatedAt;\n\n if (reset) {\n updatedAt = this.updatedAt = Date.now();\n } else {\n updatedAt = this.updatedAt ??= Date.now();\n }\n\n this._nextPageParams = undefined;\n\n // Cache the data (synchronous, fire-and-forget)\n // Use storage key for cache operations\n this.queryClient.saveQueryData(\n this.def,\n this.storageKey,\n queryData,\n updatedAt,\n entityRefs,\n this.getExtraForPersistence(),\n );\n\n // Update the timestamp\n this.updatedAt = Date.now();\n\n return queryData as T;\n } catch (error) {\n lastError = error;\n\n // If we've exhausted retries, throw the error\n if (attempt >= retries) {\n throw error;\n }\n\n // Wait before retrying (unless paused)\n const delay = retryDelay(attempt);\n await new Promise(resolve => setTimeout(resolve, delay));\n\n // Check if paused during retry delay\n if (this.isPaused) {\n throw new Error('Query is paused due to network status');\n }\n }\n }\n\n // Should never reach here, but TypeScript needs it\n throw lastError;\n }\n\n // ======================================================\n // Private debounce methods\n // ======================================================\n\n /**\n * Triggers a debounced refetch. If debounce is configured, delays the fetch.\n * Otherwise, calls refetch immediately.\n */\n private debouncedRefetch(): void {\n // We know this is a non-stream query because we're calling refetch, which is only available on non-stream queries\n const debounce = (this.def as QueryDefinition<any, any, any> | InfiniteQueryDefinition<any, any, any>).debounce;\n\n if (debounce === undefined) {\n this.refetch();\n return;\n }\n\n // Clear existing timer\n clearTimeout(this.debounceTimer);\n\n // Set new timer\n this.debounceTimer = setTimeout(() => {\n this.debounceTimer = undefined;\n this.refetch();\n }, debounce);\n }\n\n // ======================================================\n // Public methods\n // ======================================================\n\n refetch = (): Promise<T> => {\n if (this.def.type === QueryType.Stream) {\n throw new Error('Cannot refetch a stream query');\n }\n\n if (this.fetchMorePromise) {\n throw new Error('Query is fetching more, cannot refetch');\n }\n\n if (this.refetchPromise) {\n return this.refetchPromise;\n }\n\n // Clear debounce timer if active (manual refetch should bypass debounce)\n clearTimeout(this.debounceTimer);\n this.debounceTimer = undefined;\n\n // Clear memoized nextPageParams so it's recalculated after refetch\n this._nextPageParams = undefined;\n\n // Set the signal before any async operations so it's immediately visible\n // Use untrack to avoid reactive violations when called from reactive context\n this.isRefetchingSignal.value = true;\n this._version.update(v => v + 1);\n\n const promise = this.runQuery(this.currentParams, true)\n .then(result => {\n this.relayState.value = result;\n\n // Clear stream orphans and optimistic inserts on refetch\n if (this._extra !== undefined) {\n this._extra.clear();\n }\n\n return result;\n })\n .catch((error: unknown) => {\n this.relayState.setError(error);\n return Promise.reject(error);\n })\n .finally(() => {\n this._version.update(v => v + 1);\n this.isRefetchingSignal.value = false;\n this.refetchPromise = undefined;\n });\n\n this.refetchPromise = promise;\n return promise;\n };\n\n fetchNextPage = (): Promise<T> => {\n if (this.def.type === QueryType.Stream) {\n throw new Error('Cannot fetch next page on a stream query');\n }\n\n if (this.refetchPromise) {\n return Promise.reject(new Error('Query is refetching, cannot fetch next page'));\n }\n\n if (this.fetchMorePromise) {\n return this.fetchMorePromise;\n }\n\n // Read nextPageParams in untracked context to avoid reactive violations\n const nextPageParams = this.nextPageParams;\n\n if (!nextPageParams) {\n return Promise.reject(new Error('No next page params'));\n }\n\n // Set the signal before any async operations so it's immediately visible\n // Use untrack to avoid reactive violations when called from reactive context\n this.isFetchingMoreSignal.value = true;\n this._version.update(v => v + 1);\n\n const promise = this.runQuery(nextPageParams, false)\n .then(result => {\n this.relayState!.value = result;\n return result as T;\n })\n .catch((error: unknown) => {\n this.relayState.setError(error);\n return Promise.reject(error);\n })\n .finally(() => {\n this._version.update(v => v + 1);\n this.isFetchingMoreSignal.value = false;\n this.fetchMorePromise = undefined;\n });\n\n this.fetchMorePromise = promise;\n return promise;\n };\n\n // ======================================================\n // Public properties\n // ======================================================\n\n get isRefetching(): boolean {\n return this.isRefetchingSignal.value;\n }\n\n get isFetchingMore(): boolean {\n return this.isFetchingMoreSignal.value;\n }\n\n get isFetching(): boolean {\n return this.relay.isPending || this.isRefetching || this.isFetchingMore;\n }\n\n get hasNextPage(): boolean {\n return this.nextPageParams !== null;\n }\n\n get extra(): QueryExtra<unknown, unknown> {\n this.getAllEntityRefs();\n return this.extraData.getExtra();\n }\n\n /**\n * Persist the current extra data to the store\n */\n private persistExtraData(): void {\n if (this.updatedAt === undefined) {\n return; // Query not initialized yet\n }\n\n const extra = this._extra?.getForPersistence();\n // Use storage key for cache operations\n this.queryClient.saveQueryData(\n this.def,\n this.storageKey,\n this.relayState.value,\n this.updatedAt,\n this.refIds,\n extra,\n );\n }\n\n /**\n * Get extra data for persistence (converts Sets to arrays of entity ref IDs)\n */\n private getExtraForPersistence(): CachedQueryExtra | undefined {\n return this._extra?.getForPersistence();\n }\n\n /**\n * Add an optimistic insert to the query result.\n * The insert will be automatically removed when:\n * - The entity appears in a refetched response\n * - The entity appears as a stream orphan\n * - refetch() is called\n */\n addOptimisticInsert(insert: Record<string, unknown>): void {\n // Check that the query has optimisticInserts configured\n const def = this.def as QueryDefinition<any, any, any> | InfiniteQueryDefinition<any, any, any>;\n const optimisticInsertsConfig = def.optimisticInserts;\n\n if (optimisticInsertsConfig === undefined) {\n throw new Error(\n 'Query does not have optimisticInserts configured. Add optimisticInserts: { type: YourEntity } to the query definition.',\n );\n }\n\n let proxyId = getProxyId(insert);\n let parsedInsert = insert;\n\n // If not already a proxy, parse it through the optimisticInserts shape\n if (proxyId === undefined) {\n parsedInsert = parseObjectEntities(insert, optimisticInsertsConfig.shape as EntityDef, this.queryClient);\n proxyId = getProxyId(parsedInsert);\n\n if (proxyId === undefined) {\n throw new Error('Optimistic insert must be or produce an entity proxy');\n }\n }\n\n // Check if already in main response\n const allRefIds = this.getAllEntityRefs();\n if (allRefIds.has(proxyId)) {\n return; // Already in response, no-op\n }\n\n // Check if already in stream orphans\n if (this.extraData.hasOrphanWithId(proxyId)) {\n return; // Already in stream orphans, no-op\n }\n\n this.extraData.addOptimisticInsert(parsedInsert);\n }\n\n /**\n * Remove an optimistic insert from the query result.\n * This is a no-op if the insert has already been removed.\n */\n removeOptimisticInsert(insert: Record<string, unknown>): void {\n this.extraData.removeOptimisticInsert(insert);\n }\n\n get isStale(): boolean {\n // Streams are never stale - they're always receiving updates\n if (this.def.type === QueryType.Stream) {\n return false;\n }\n\n if (this.updatedAt === undefined) {\n return true; // No data yet, needs fetch\n }\n\n const staleTime = this.def.cache?.staleTime ?? 0;\n return Date.now() - this.updatedAt >= staleTime;\n }\n\n get isPaused(): boolean {\n // Streams handle their own connection state\n if (this.def.type === QueryType.Stream) {\n return false;\n }\n\n const networkMode = this.def.cache?.networkMode ?? NetworkMode.Online;\n const networkManager = this.queryClient.networkManager;\n\n // Read the online signal to make this reactive\n const isOnline = networkManager.getOnlineSignal().value;\n\n switch (networkMode) {\n case NetworkMode.Always:\n return false;\n case NetworkMode.Online:\n return !isOnline;\n case NetworkMode.OfflineFirst:\n // Only paused if we have no cached data AND we're offline\n return !isOnline && this.updatedAt === undefined;\n default:\n return false;\n }\n }\n\n private getRetryConfig(): { retries: number; retryDelay: (attempt: number) => number } {\n // Streams don't have retry config\n if (this.def.type === QueryType.Stream) {\n return { retries: 0, retryDelay: () => 0 };\n }\n\n const retryOption = this.def.cache?.retry;\n const isServer = this.queryClient.isServer;\n\n // Default retry count: 3 on client, 0 on server\n let retries: number;\n let retryDelay: (attempt: number) => number;\n\n if (retryOption === false) {\n retries = 0;\n } else if (retryOption === undefined) {\n retries = isServer ? 0 : 3;\n } else if (typeof retryOption === 'number') {\n retries = retryOption;\n } else {\n retries = retryOption.retries;\n }\n\n // Default exponential backoff: 1000ms * 2^attempt\n if (typeof retryOption === 'object' && retryOption.retryDelay) {\n retryDelay = retryOption.retryDelay;\n } else {\n retryDelay = (attempt: number) => 1000 * Math.pow(2, attempt);\n }\n\n return { retries, retryDelay };\n }\n}\n","import { task, type ReactiveTask } from 'signalium';\nimport { hashValue } from 'signalium/utils';\nimport {\n ArrayDef,\n BaseMutationResult,\n ComplexTypeDef,\n EntityDef,\n Mask,\n MutationResult,\n ObjectDef,\n ObjectFieldTypeDef,\n RecordDef,\n UnionDef,\n} from './types.js';\nimport { parseEntities } from './parseEntities.js';\nimport { ValidatorDef } from './typeDefs.js';\nimport { type QueryClient } from './QueryClient.js';\nimport { MutationDefinition } from './mutation.js';\nimport { typeMaskOf } from './utils.js';\n\n// ======================================================\n// MutationResultImpl\n// ======================================================\n\n/**\n * MutationResult is a thin wrapper around ReactiveTask that adds:\n * - Optimistic update support with rollback on failure\n * - Entity parsing from responses\n * - reset() functionality\n */\nexport class MutationResultImpl<Request, Response> implements BaseMutationResult<Request, Response> {\n def: MutationDefinition<Request, Response>;\n private queryClient: QueryClient;\n\n // The underlying ReactiveTask that handles all state management\n private _task: ReactiveTask<Response, [Request]>;\n\n // Track which entity keys we've registered optimistic updates for\n // EntityMap handles the actual snapshots\n private _pendingOptimisticKeys: Set<number> = new Set();\n\n constructor(def: MutationDefinition<Request, Response>, queryClient: QueryClient) {\n this.def = def;\n this.queryClient = queryClient;\n this._task = this.createTask();\n }\n\n private createTask(): ReactiveTask<Response, [Request]> {\n return task(async (request: Request): Promise<Response> => {\n try {\n const response = await this.executeWithRetry(request);\n\n // Parse response and update entities\n const parsedResponse = this.parseAndUpdateEntities(response);\n\n // Clear optimistic update tracking on success (updates are now confirmed)\n this.clearOptimisticUpdates();\n\n return parsedResponse;\n } catch (error) {\n // Revert optimistic updates on failure\n this.revertOptimisticUpdates();\n throw error;\n }\n });\n }\n\n // ======================================================\n // Delegated ReactivePromise properties\n // ======================================================\n\n get value(): Response | undefined {\n return this._task.value;\n }\n\n get error(): unknown {\n return this._task.error;\n }\n\n get isPending(): boolean {\n return this._task.isPending;\n }\n\n get isRejected(): boolean {\n return this._task.isRejected;\n }\n\n get isResolved(): boolean {\n return this._task.isResolved;\n }\n\n get isSettled(): boolean {\n return this._task.isSettled;\n }\n\n get isReady(): boolean {\n return this._task.isReady;\n }\n\n // ======================================================\n // Promise interface (delegated)\n // ======================================================\n\n then<TResult1 = Response, TResult2 = never>(\n onfulfilled?: ((value: Response) => TResult1 | PromiseLike<TResult1>) | null | undefined,\n onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null | undefined,\n ): Promise<TResult1 | TResult2> {\n return this._task.then(onfulfilled, onrejected);\n }\n\n catch<TResult = never>(\n onrejected?: ((reason: unknown) => TResult | PromiseLike<TResult>) | null | undefined,\n ): Promise<Response | TResult> {\n return this._task.catch(onrejected);\n }\n\n finally(onfinally?: (() => void) | null | undefined): Promise<Response> {\n return this._task.finally(onfinally);\n }\n\n get [Symbol.toStringTag](): string {\n return 'MutationResult';\n }\n\n // ======================================================\n // Mutation execution\n // ======================================================\n\n run = (request: Request): MutationResult<Request, Response> => {\n // Apply optimistic updates if enabled\n if (this.def.optimisticUpdates) {\n this.applyOptimisticUpdates(request);\n }\n\n // Run the underlying task\n this._task.run(request);\n\n return this as unknown as MutationResult<Request, Response>;\n };\n\n reset = (): void => {\n // Revert any pending optimistic updates\n this.revertOptimisticUpdates();\n\n // Create a fresh task to reset state\n this._task = this.createTask();\n };\n\n // ======================================================\n // Optimistic updates\n // ======================================================\n\n private applyOptimisticUpdates(request: Request): void {\n // Clear any previous tracking\n this._pendingOptimisticKeys.clear();\n\n const requestShape = this.def.requestShape;\n\n if (!(requestShape instanceof ValidatorDef)) {\n return;\n }\n\n // Recursively find and update all entities in the request\n this.findAndUpdateEntities(request, requestShape as ComplexTypeDef);\n }\n\n /**\n * Recursively walks the data according to its shape, finding and updating all entities.\n */\n private findAndUpdateEntities(value: unknown, def: ComplexTypeDef): void {\n const valueType = typeMaskOf(value);\n const defType = def.mask;\n\n // Skip primitives and incompatible types\n if (valueType < Mask.OBJECT || (defType & valueType) === 0) {\n return;\n }\n\n // Handle unions - find the matching type\n if ((defType & Mask.UNION) !== 0) {\n const unionDef = def as UnionDef;\n if (valueType === Mask.ARRAY) {\n const arrayShape = unionDef.shape!['[]' as keyof typeof unionDef.shape];\n if (arrayShape && typeof arrayShape !== 'number') {\n this.findAndUpdateEntitiesInArray(value as unknown[], arrayShape as ComplexTypeDef);\n }\n } else {\n const typenameField = unionDef.typenameField;\n const typename = typenameField ? (value as Record<string, unknown>)[typenameField] : undefined;\n if (typename && typeof typename === 'string') {\n const matchingDef = unionDef.shape![typename as keyof typeof unionDef.shape];\n if (matchingDef && typeof matchingDef !== 'number') {\n this.findAndUpdateEntitiesInObject(value as Record<string, unknown>, matchingDef as ObjectDef | EntityDef);\n }\n }\n }\n return;\n }\n\n // Handle arrays\n if (valueType === Mask.ARRAY) {\n const arrayShape = (def as ArrayDef).shape;\n if (arrayShape && typeof arrayShape !== 'number') {\n this.findAndUpdateEntitiesInArray(value as unknown[], arrayShape as ComplexTypeDef);\n }\n return;\n }\n\n // Handle records\n if ((defType & Mask.RECORD) !== 0) {\n const recordShape = (def as RecordDef).shape;\n if (recordShape && typeof recordShape !== 'number') {\n for (const item of Object.values(value as Record<string, unknown>)) {\n this.findAndUpdateEntities(item, recordShape as ComplexTypeDef);\n }\n }\n return;\n }\n\n // Handle objects/entities\n this.findAndUpdateEntitiesInObject(value as Record<string, unknown>, def as ObjectDef | EntityDef);\n }\n\n private findAndUpdateEntitiesInArray(array: unknown[], shape: ComplexTypeDef): void {\n for (const item of array) {\n this.findAndUpdateEntities(item, shape);\n }\n }\n\n private findAndUpdateEntitiesInObject(obj: Record<string, unknown>, def: ObjectDef | EntityDef): void {\n const { mask } = def;\n\n // If this is an entity, update it in the store\n if (mask & Mask.ENTITY) {\n const entityDef = def as EntityDef;\n const idField = entityDef.idField;\n const entityId = obj[idField];\n\n if (entityId !== undefined) {\n const typename = entityDef.typenameValue;\n const entityKey = hashValue(`${typename}:${entityId}`);\n\n // Register the optimistic update\n this.queryClient.registerOptimisticUpdate(entityKey, obj);\n this._pendingOptimisticKeys.add(entityKey);\n }\n }\n\n // Recurse into sub-entity paths to find nested entities\n const shape = def.shape;\n const subEntityPaths = def.subEntityPaths;\n\n if (subEntityPaths !== undefined) {\n if (typeof subEntityPaths === 'string') {\n const propDef = shape[subEntityPaths];\n if (propDef && typeof propDef !== 'number') {\n this.findAndUpdateEntities(obj[subEntityPaths], propDef as ComplexTypeDef);\n }\n } else {\n for (const path of subEntityPaths) {\n const propDef = shape[path] as ObjectFieldTypeDef;\n if (propDef && typeof propDef !== 'number') {\n this.findAndUpdateEntities(obj[path], propDef as ComplexTypeDef);\n }\n }\n }\n }\n }\n\n private revertOptimisticUpdates(): void {\n // Revert each optimistic update - EntityMap handles restoring snapshots\n for (const entityKey of this._pendingOptimisticKeys) {\n this.queryClient.revertOptimisticUpdate(entityKey);\n }\n this._pendingOptimisticKeys.clear();\n }\n\n private clearOptimisticUpdates(): void {\n // Clear optimistic update tracking (mutation succeeded, updates are confirmed)\n for (const entityKey of this._pendingOptimisticKeys) {\n this.queryClient.clearOptimisticUpdates(entityKey);\n }\n this._pendingOptimisticKeys.clear();\n }\n\n // ======================================================\n // Response parsing\n // ======================================================\n\n private parseAndUpdateEntities(response: unknown): Response {\n const responseShape = this.def.responseShape;\n\n if (!(responseShape instanceof ValidatorDef)) {\n return response as Response;\n }\n\n // Parse entities from response and update the entity store\n const entityRefs = new Set<number>();\n const parsed = parseEntities(response, responseShape as ComplexTypeDef, this.queryClient, entityRefs);\n\n return parsed as Response;\n }\n\n // ======================================================\n // Retry logic\n // ======================================================\n\n private async executeWithRetry(request: Request): Promise<Response> {\n const { retries, retryDelay } = this.getRetryConfig();\n let lastError: unknown;\n\n for (let attempt = 0; attempt <= retries; attempt++) {\n try {\n return await this.def.mutateFn(this.queryClient.getContext(), request);\n } catch (error) {\n lastError = error;\n\n // If we've exhausted retries, throw the error\n if (attempt >= retries) {\n throw error;\n }\n\n // Wait before retrying\n const delay = retryDelay(attempt);\n await new Promise(resolve => setTimeout(resolve, delay));\n }\n }\n\n // Should never reach here, but TypeScript needs it\n throw lastError;\n }\n\n private getRetryConfig(): { retries: number; retryDelay: (attempt: number) => number } {\n const retryOption = this.def.cache?.retry;\n\n let retries: number;\n let retryDelay: (attempt: number) => number;\n\n if (retryOption === false) {\n retries = 0;\n } else if (retryOption === undefined) {\n retries = 0; // Mutations default to no retries\n } else if (typeof retryOption === 'number') {\n retries = retryOption;\n } else {\n retries = retryOption.retries;\n }\n\n // Default exponential backoff: 1000ms * 2^attempt\n if (typeof retryOption === 'object' && retryOption.retryDelay) {\n retryDelay = retryOption.retryDelay;\n } else {\n retryDelay = (attempt: number) => 1000 * Math.pow(2, attempt);\n }\n\n return { retries, retryDelay };\n }\n}\n","import { QueryType } from './QueryClient.js';\nimport type { QueryResultImpl } from './QueryResult.js';\n\nconst BASE_TICK_INTERVAL = 1000; // 1 second\n\n// Refetch interval manager - uses a fixed 1-second tick\nexport class RefetchManager {\n private intervalId: NodeJS.Timeout;\n private clock: number = 0; // Increments by 1000ms on each tick\n\n // Buckets: Map of actual interval -> Set of query instances\n private buckets = new Map<number, Set<QueryResultImpl<any>>>();\n\n constructor(private multiplier: number = 1) {\n // Start the timer immediately and keep it running\n const tickInterval = BASE_TICK_INTERVAL * this.multiplier;\n this.intervalId = setTimeout(() => this.tick(), tickInterval);\n }\n\n addQuery(instance: QueryResultImpl<any>) {\n if (instance.def.type === QueryType.Stream) {\n return; // Streams don't have refetch intervals\n }\n\n const interval = instance.def.cache?.refetchInterval;\n\n if (!interval) {\n return;\n }\n\n const actualInterval = interval * this.multiplier;\n // Add to bucket by actual interval\n let bucket = this.buckets.get(actualInterval);\n if (!bucket) {\n bucket = new Set();\n this.buckets.set(actualInterval, bucket);\n }\n bucket.add(instance);\n }\n\n removeQuery(query: QueryResultImpl<any>) {\n if (query.def.type === QueryType.Stream) {\n return; // Streams don't have refetch intervals\n }\n\n const interval = query.def.cache?.refetchInterval;\n\n if (!interval) {\n return;\n }\n\n const actualInterval = interval * this.multiplier;\n // Remove from bucket\n const bucket = this.buckets.get(actualInterval);\n if (bucket) {\n bucket.delete(query);\n\n if (bucket.size === 0) {\n this.buckets.delete(actualInterval);\n }\n }\n }\n\n private tick() {\n this.clock += BASE_TICK_INTERVAL * this.multiplier;\n\n // Only process buckets where clock is aligned with the interval\n for (const [interval, bucket] of this.buckets.entries()) {\n if (this.clock % interval === 0) {\n // Process all queries in this bucket\n for (const query of bucket) {\n // Skip if already fetching - let the current fetch complete\n if (query && !query.isFetching) {\n query.refetch();\n }\n }\n }\n }\n\n const tickInterval = BASE_TICK_INTERVAL * this.multiplier;\n this.intervalId = setTimeout(() => this.tick(), tickInterval);\n }\n\n destroy(): void {\n clearTimeout(this.intervalId);\n }\n}\n\n// No-op implementation for SSR environments where timers are not needed\nexport class NoOpRefetchManager {\n addQuery(_instance: QueryResultImpl<any>): void {\n // No-op: do nothing\n }\n\n removeQuery(_query: QueryResultImpl<any>): void {\n // No-op: do nothing\n }\n\n destroy(): void {\n // No-op: do nothing\n }\n}\n","import { type QueryClient } from './QueryClient.js';\n\nconst EVICTION_INTERVAL = 60 * 1000; // 1 minute\n\n// Memory eviction manager - uses a single interval with rotating sets to avoid timeout overhead\nexport class MemoryEvictionManager {\n private intervalId: NodeJS.Timeout;\n private currentFlush = new Set<number>(); // Queries to evict on next tick\n private nextFlush = new Set<number>(); // Queries to evict on tick after next\n\n constructor(\n private queryClient: QueryClient,\n private multiplier: number = 1,\n ) {\n this.intervalId = setInterval(this.tick, EVICTION_INTERVAL * this.multiplier);\n }\n\n scheduleEviction(queryKey: number) {\n // Add to nextFlush so it waits at least one full interval\n // This prevents immediate eviction if scheduled right before a tick\n this.nextFlush.add(queryKey);\n }\n\n cancelEviction(queryKey: number) {\n // Remove from both sets to handle reactivation\n this.currentFlush.delete(queryKey);\n this.nextFlush.delete(queryKey);\n }\n\n private tick = () => {\n if (!this.queryClient) return;\n\n // Evict all queries in currentFlush\n for (const queryKey of this.currentFlush) {\n this.queryClient.queryInstances.delete(queryKey);\n }\n\n // Rotate: currentFlush becomes nextFlush, nextFlush becomes empty\n this.currentFlush = this.nextFlush;\n this.nextFlush = new Set();\n };\n\n destroy(): void {\n clearInterval(this.intervalId);\n }\n}\n\n// No-op implementation for SSR environments where timers are not needed\nexport class NoOpMemoryEvictionManager {\n scheduleEviction(_queryKey: number): void {\n // No-op: do nothing\n }\n\n cancelEviction(_queryKey: number): void {\n // No-op: do nothing\n }\n\n destroy(): void {\n // No-op: do nothing\n }\n}\n","/**\n * Query Client with Entity Caching and Deduplication\n *\n * Features:\n * - Global entity map for deduplication\n * - Entity definitions with cached sub-entity paths\n * - Eager entity discovery and caching\n * - Permanent proxy cache for entities\n * - Response caching for offline access\n * - Signalium-based reactivity for entity updates\n * - Self-contained validator (no external dependencies except Signalium)\n */\n\nimport { context, type Context } from 'signalium';\nimport { hashValue } from 'signalium/utils';\nimport {\n QueryResult,\n EntityDef,\n RefetchInterval,\n NetworkMode,\n RetryConfig,\n TypeDef,\n UnionDef,\n BaseUrlValue,\n QueryRequestInit,\n MutationResult,\n} from './types.js';\nimport { EntityRecord, EntityStore } from './EntityMap.js';\nimport { NetworkManager } from './NetworkManager.js';\nimport { QueryResultImpl } from './QueryResult.js';\nimport { MutationResultImpl } from './MutationResult.js';\nimport { MutationDefinition } from './mutation.js';\nimport { RefetchManager } from './RefetchManager.js';\nimport { MemoryEvictionManager } from './MemoryEvictionManager.js';\nimport { type Signal } from 'signalium';\n\n// -----------------------------------------------------------------------------\n// Query Types\n// -----------------------------------------------------------------------------\n\nexport interface QueryContext {\n fetch: (url: string, init?: QueryRequestInit) => Promise<Response>;\n baseUrl?: BaseUrlValue;\n log?: {\n error?: (message: string, error?: unknown) => void;\n warn?: (message: string, error?: unknown) => void;\n info?: (message: string) => void;\n debug?: (message: string) => void;\n };\n evictionMultiplier?: number;\n refetchMultiplier?: number;\n}\n\n/**\n * Resolves a BaseUrlValue to a string.\n * Handles static strings, Signals, and functions.\n */\nexport function resolveBaseUrl(baseUrl: BaseUrlValue | undefined): string | undefined {\n if (baseUrl === undefined) return undefined;\n if (typeof baseUrl === 'string') return baseUrl;\n if (typeof baseUrl === 'function') return baseUrl();\n return baseUrl.value; // Signal\n}\n\nexport interface QueryCacheOptions {\n maxCount?: number;\n gcTime?: number; // milliseconds - only applies to on-disk/persistent storage cleanup\n staleTime?: number;\n refetchInterval?: RefetchInterval;\n networkMode?: NetworkMode; // default: NetworkMode.Online\n retry?: RetryConfig | number | false; // default: 3 on client, 0 on server\n refreshStaleOnReconnect?: boolean; // default: true\n}\n\nexport interface StreamCacheOptions {\n maxCount?: number;\n gcTime?: number; // milliseconds - only applies to on-disk/persistent storage cleanup\n}\n\nexport interface QueryPaginationOptions<Result> {\n getNextPageParams?(lastPage: Result, params?: QueryParams | undefined): QueryParams | undefined;\n}\n\nexport type QueryParams = Record<\n string,\n string | number | boolean | undefined | null | Signal<string | number | boolean | undefined | null>\n>;\n\nexport const enum QueryType {\n Query = 'query',\n InfiniteQuery = 'infiniteQuery',\n Stream = 'stream',\n}\n\nexport type StreamSubscribeFn<Params extends QueryParams | undefined, StreamType> = (\n context: QueryContext,\n params: Params,\n onUpdate: (update: StreamType) => void,\n) => () => void;\n\nexport interface QueryDefinition<Params extends QueryParams | undefined, Result, StreamType> {\n type: QueryType.Query;\n id: string;\n shape: TypeDef;\n shapeKey: number;\n fetchFn: (context: QueryContext, params: Params, prevResult?: Result) => Promise<Result>;\n debounce?: number;\n cache?: QueryCacheOptions;\n stream?: {\n shape: TypeDef;\n shapeKey: number;\n subscribeFn: StreamSubscribeFn<Params, StreamType>;\n };\n optimisticInserts?: {\n shape: TypeDef;\n shapeKey: number;\n };\n}\n\nexport interface InfiniteQueryDefinition<Params extends QueryParams | undefined, Result, StreamType> {\n type: QueryType.InfiniteQuery;\n id: string;\n shape: TypeDef;\n shapeKey: number;\n fetchFn: (context: QueryContext, params: Params, prevResult?: Result) => Promise<Result>;\n pagination: QueryPaginationOptions<Result>;\n debounce?: number;\n cache?: QueryCacheOptions;\n stream?: {\n shape: TypeDef;\n shapeKey: number;\n subscribeFn: StreamSubscribeFn<Params, StreamType>;\n };\n optimisticInserts?: {\n shape: TypeDef;\n shapeKey: number;\n };\n}\n\nexport interface StreamQueryDefinition<Params extends QueryParams | undefined, StreamType> {\n type: QueryType.Stream;\n id: string;\n shape: EntityDef; // Must be entity\n shapeKey: number;\n subscribeFn: StreamSubscribeFn<Params, StreamType>;\n cache?: StreamCacheOptions;\n}\n\nexport type AnyQueryDefinition<Params extends QueryParams | undefined, Result, Event> =\n | QueryDefinition<Params, Result, Event>\n | InfiniteQueryDefinition<Params, Result, Event>\n | StreamQueryDefinition<Params, Event>;\n\n// -----------------------------------------------------------------------------\n// QueryStore Interface\n// -----------------------------------------------------------------------------\n\nexport interface CachedQuery {\n value: unknown;\n refIds: Set<number> | undefined;\n updatedAt: number;\n extra?: CachedQueryExtra;\n}\n\nexport interface CachedQueryExtra {\n streamOrphanRefs?: number[];\n optimisticInsertRefs?: number[];\n}\n\nexport interface QueryStore {\n /**\n * Asynchronously retrieves a document by key.\n * May return undefined if the document is not in the store.\n */\n loadQuery(\n queryDef: QueryDefinition<any, any, any>,\n queryKey: number,\n entityMap: EntityStore,\n ): MaybePromise<CachedQuery | undefined>;\n\n /**\n * Synchronously stores a document with optional reference IDs.\n * This is fire-and-forget for async implementations.\n */\n saveQuery(\n queryDef: QueryDefinition<any, any, any>,\n queryKey: number,\n value: unknown,\n updatedAt: number,\n refIds?: Set<number>,\n extra?: CachedQueryExtra,\n ): void;\n\n /**\n * Synchronously stores an entity with optional reference IDs.\n * This is fire-and-forget for async implementations.\n */\n saveEntity(entityKey: number, value: unknown, refIds?: Set<number>): void;\n\n /**\n * Marks a query as accessed, updating the LRU queue.\n * Handles eviction internally when the cache is full.\n */\n activateQuery(queryDef: QueryDefinition<any, any, any>, queryKey: number): void;\n\n deleteQuery(queryKey: number): void;\n}\n\nexport type MaybePromise<T> = T | Promise<T>;\n\n/**\n * Checks if a value is a Signal instance\n */\nfunction isSignal(value: unknown): value is Signal<any> {\n return typeof value === 'object' && value !== null;\n}\n\n/**\n * Extracts actual values from params that may contain Signals.\n */\nexport function extractParamsForKey(\n params: QueryParams | undefined,\n): Record<string, string | number | boolean | undefined | null> | undefined {\n if (params === undefined) {\n return undefined;\n }\n\n const extracted: Record<string, string | number | boolean | undefined | null> = {};\n\n for (const [key, value] of Object.entries(params)) {\n if (isSignal(value)) {\n extracted[key] = value.value as string | number | boolean | undefined | null;\n } else {\n extracted[key] = value as string | number | boolean | undefined | null;\n }\n }\n\n return extracted;\n}\n\n/**\n * Computes the query key for instance lookup. This is used for two different keys:\n *\n * - Query instance key\n * - Query storage key\n *\n * Instance keys are created by passing in the query definition and parameters WITHOUT\n * extracting the Signal values, whereas storage keys are created by extracting the Signal values.\n * This way, we can reuse the same instance for given Signals, but different underlying values\n * will be stored and put into the LRU cache separately.\n */\nexport const queryKeyFor = (queryDef: AnyQueryDefinition<any, any, any>, params: unknown): number => {\n return hashValue([queryDef.id, queryDef.shapeKey, params]);\n};\n\nexport class QueryClient {\n private entityMap: EntityStore;\n queryInstances = new Map<number, QueryResultImpl<unknown>>();\n mutationInstances = new Map<string, MutationResultImpl<unknown, unknown>>();\n memoryEvictionManager: MemoryEvictionManager;\n refetchManager: RefetchManager;\n networkManager: NetworkManager;\n isServer: boolean;\n\n constructor(\n private store: QueryStore,\n private context: QueryContext = { fetch, log: console },\n networkManager?: NetworkManager,\n memoryEvictionManager?: MemoryEvictionManager,\n refetchManager?: RefetchManager,\n ) {\n this.memoryEvictionManager =\n memoryEvictionManager ?? new MemoryEvictionManager(this, this.context.evictionMultiplier);\n this.refetchManager = refetchManager ?? new RefetchManager(this.context.refetchMultiplier);\n this.networkManager = networkManager ?? new NetworkManager();\n this.isServer = typeof window === 'undefined';\n this.entityMap = new EntityStore(this);\n }\n\n getContext(): QueryContext {\n return this.context;\n }\n\n saveQueryData(\n queryDef: AnyQueryDefinition<QueryParams | undefined, unknown, unknown>,\n queryKey: number,\n data: unknown,\n updatedAt: number,\n entityRefs?: Set<number>,\n extra?: CachedQueryExtra,\n ): void {\n // Clone entityRefs to avoid mutation in setValue\n const clonedRefs = entityRefs !== undefined ? new Set(entityRefs) : undefined;\n // QueryStore expects the base definition structure\n this.store.saveQuery(queryDef as any, queryKey, data, updatedAt, clonedRefs, extra);\n }\n\n activateQuery(queryInstance: QueryResultImpl<unknown>): void {\n const { def, queryKey, storageKey } = queryInstance;\n // Use storageKey for cache operations (store.activateQuery)\n this.store.activateQuery(def as any, storageKey);\n\n // Only add to refetch manager if it's not a stream\n if (def.type !== QueryType.Stream && def.cache?.refetchInterval) {\n this.refetchManager.addQuery(queryInstance);\n }\n // Use queryKey for instance eviction (memoryEvictionManager)\n this.memoryEvictionManager.cancelEviction(queryKey);\n }\n\n loadCachedQuery(queryDef: AnyQueryDefinition<QueryParams | undefined, unknown, unknown>, queryKey: number) {\n return this.store.loadQuery(queryDef as any, queryKey, this.entityMap);\n }\n\n deleteCachedQuery(queryKey: number): void {\n this.store.deleteQuery(queryKey);\n }\n\n /**\n * Loads a query from the document store and returns a QueryResult\n * that triggers fetches and prepopulates with cached data\n */\n getQuery<T>(\n queryDef: AnyQueryDefinition<any, any, any>,\n params: QueryParams | undefined,\n ): QueryResult<T, unknown, unknown> {\n const queryKey = queryKeyFor(queryDef, params);\n\n let queryInstance = this.queryInstances.get(queryKey) as QueryResultImpl<T> | undefined;\n\n // Create a new instance if it doesn't exist\n if (queryInstance === undefined) {\n queryInstance = new QueryResultImpl(queryDef, this, queryKey, params);\n\n // Store for future use\n this.queryInstances.set(queryKey, queryInstance as QueryResultImpl<unknown>);\n }\n\n return queryInstance as unknown as QueryResult<T, unknown, unknown>;\n }\n\n /**\n * Gets or creates a MutationResult for the given mutation definition.\n * Mutations are cached by their definition ID.\n */\n getMutation<Request, Response>(\n mutationDef: MutationDefinition<Request, Response>,\n ): MutationResult<Request, Response> {\n const mutationId = mutationDef.id;\n\n let mutationInstance = this.mutationInstances.get(mutationId) as MutationResultImpl<Request, Response> | undefined;\n\n // Create a new instance if it doesn't exist\n if (mutationInstance === undefined) {\n mutationInstance = new MutationResultImpl(mutationDef, this);\n\n // Store for future use\n this.mutationInstances.set(mutationId, mutationInstance as MutationResultImpl<unknown, unknown>);\n }\n\n return mutationInstance as MutationResult<Request, Response>;\n }\n\n // ======================================================\n // Optimistic Update Management\n // ======================================================\n\n /**\n * Register pending optimistic updates for an entity.\n * Called by MutationResult when applying optimistic updates.\n */\n registerOptimisticUpdate(entityKey: number, fields: Record<string, unknown>): void {\n this.entityMap.registerOptimisticUpdate(entityKey, fields);\n }\n\n /**\n * Clear pending optimistic updates for an entity without reverting.\n * Called by MutationResult when mutation succeeds.\n */\n clearOptimisticUpdates(entityKey: number): void {\n this.entityMap.clearOptimisticUpdates(entityKey);\n }\n\n /**\n * Revert pending optimistic updates for an entity, restoring its snapshot.\n * Called by MutationResult when mutation fails.\n */\n revertOptimisticUpdate(entityKey: number): void {\n this.entityMap.revertOptimisticUpdate(entityKey);\n }\n\n hydrateEntity(key: number, shape: EntityDef): EntityRecord {\n return this.entityMap.hydratePreloadedEntity(key, shape);\n }\n\n saveEntity(key: number, obj: Record<string, unknown>, shape: EntityDef, entityRefs?: Set<number>): EntityRecord {\n // console.log('saveEntity', key, JSON.stringify(obj, null, 2), shape, entityRefs, new Error().stack);\n\n const record = this.entityMap.setEntity(key, obj, shape, entityRefs);\n\n // console.log('saveEntity record', JSON.stringify(obj, null, 2), new Error().stack);\n\n this.store.saveEntity(key, obj, entityRefs);\n\n return record;\n }\n\n getNestedEntityRefIds(key: number, refIds: Set<number>): Set<number> {\n return this.entityMap.getNestedEntityRefIds(key, refIds);\n }\n\n destroy(): void {\n this.refetchManager.destroy();\n this.memoryEvictionManager.destroy();\n }\n}\n\nexport const QueryClientContext: Context<QueryClient | undefined> = context<QueryClient | undefined>(undefined);\n\n/**\n * Add an optimistic insert to a query result.\n * The insert will be automatically removed when:\n * - The entity appears in a refetched response\n * - The entity appears as a stream orphan\n * - refetch() is called\n */\nexport function addOptimisticInsert<T extends Record<string, unknown>>(\n query: QueryResult<unknown, unknown, unknown>,\n insert: T,\n): void {\n (query as unknown as QueryResultImpl<unknown>).addOptimisticInsert(insert);\n}\n\n/**\n * Remove an optimistic insert from a query result.\n * This is a no-op if the insert has already been removed.\n */\nexport function removeOptimisticInsert<T extends Record<string, unknown>>(\n query: QueryResult<unknown, unknown, unknown>,\n insert: T,\n): void {\n (query as unknown as QueryResultImpl<unknown>).removeOptimisticInsert(insert);\n}\n","/**\n * Path interpolation utilities for URL templates with parameter substitution.\n *\n * Converts path templates like \"/users/{userId}/posts/{postId}\" into functions\n * that efficiently interpolate parameter values.\n *\n * The implementation pre-parses the path template once into segments and parameter\n * keys, then uses simple string concatenation at runtime for optimal performance.\n */\n\nexport type PathInterpolator = (params: Record<string, any>) => string;\n\n/**\n * Creates an optimized path interpolation function from a URL template.\n *\n * The template uses curly braces for parameters (e.g., \"/items/{id}\").\n * Parameter values are URL-encoded when interpolated. Any parameters not\n * found in the path template are appended as query string parameters.\n *\n * @param pathTemplate - URL template with {paramName} placeholders\n * @returns Function that interpolates parameters into the path with search params\n *\n * @example\n * ```ts\n * const interpolate = createPathInterpolator('/users/{userId}/posts/{postId}');\n * const url = interpolate({ userId: '123', postId: '456', page: 2, limit: 10 });\n * // Returns: \"/users/123/posts/456?page=2&limit=10\"\n * ```\n */\nexport function createPathInterpolator(pathTemplate: string): PathInterpolator {\n // Pre-parse path into segments and param keys (parse once, concatenate many times)\n const segments: string[] = [];\n const paramKeys: string[] = [];\n const paramKeysSet = new Set<string>();\n let lastIndex = 0;\n const paramRegex = /\\[([^\\]]+)\\]/g;\n let match: RegExpExecArray | null;\n\n while ((match = paramRegex.exec(pathTemplate)) !== null) {\n segments.push(pathTemplate.slice(lastIndex, match.index));\n paramKeys.push(match[1]);\n paramKeysSet.add(match[1]);\n lastIndex = paramRegex.lastIndex;\n }\n segments.push(pathTemplate.slice(lastIndex));\n\n // Return optimized interpolation function with pre-parsed segments\n return (params: Record<string, any>): string => {\n // Build the path with interpolated path parameters\n let result = segments[0];\n for (let i = 0; i < paramKeys.length; i++) {\n result += encodeURIComponent(String(params[paramKeys[i]])) + segments[i + 1];\n }\n\n // Collect remaining parameters as search params\n let searchParams: URLSearchParams | null = null;\n for (const key in params) {\n if (!paramKeysSet.has(key) && params[key] !== undefined) {\n if (searchParams === null) {\n searchParams = new URLSearchParams();\n }\n\n searchParams.append(key, String(params[key]));\n }\n }\n\n // Append search params if any exist\n if (searchParams !== null) {\n result += '?' + searchParams.toString();\n }\n\n return result;\n };\n}\n","import { getContext, reactive } from 'signalium';\nimport {\n QueryResult,\n Mask,\n ObjectFieldTypeDef,\n UnionDef,\n QueryFn,\n InfiniteQueryFn,\n ExtractTypesFromObjectOrEntity,\n EntityDef,\n StreamQueryFn,\n TypeDef,\n QueryRequestOptions,\n} from './types.js';\nimport {\n QueryCacheOptions,\n QueryClientContext,\n QueryContext,\n QueryDefinition,\n QueryParams,\n StreamCacheOptions,\n QueryType,\n queryKeyFor,\n resolveBaseUrl,\n} from './QueryClient.js';\nimport { entity, t, ValidatorDef } from './typeDefs.js';\nimport { createPathInterpolator } from './pathInterpolator.js';\nimport { hashValue } from 'signalium/utils';\n\ntype IsParameter<Part> = Part extends `[${infer ParamName}]` ? ParamName : never;\ntype FilteredParts<Path> = Path extends `${infer PartA}/${infer PartB}`\n ? IsParameter<PartA> | FilteredParts<PartB>\n : IsParameter<Path>;\ntype ParamValue<Key> = Key extends `...${infer Anything}` ? (string | number)[] : string | number;\ntype RemovePrefixDots<Key> = Key extends `...${infer Name}` ? Name : Key;\ntype PathParams<Path> = {\n [Key in FilteredParts<Path> as RemovePrefixDots<Key>]: ParamValue<Key>;\n};\n\ntype SearchParamsType =\n | Mask.NUMBER\n | Mask.STRING\n | Mask.BOOLEAN\n | Mask.UNDEFINED\n | Mask.NULL\n | Set<string | boolean | number>;\ntype SearchParamsDefinition = Record<string, SearchParamsType | UnionDef<SearchParamsType[]>>;\n\ninterface StreamOptions<\n Params extends SearchParamsDefinition,\n Event extends Record<string, ObjectFieldTypeDef> | ObjectFieldTypeDef,\n> {\n type: Event;\n subscribe: (\n context: QueryContext,\n params: ExtractTypesFromObjectOrEntity<Params>,\n onUpdate: (update: Partial<ExtractTypesFromObjectOrEntity<Event>>) => void,\n ) => () => void;\n}\n\n// Map for getting query definitions by function reference, for testing\n// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\nconst QUERY_DEFINITION_MAP = new Map<Function, () => QueryDefinition<any, any, any>>();\n\n// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\nexport const queryKeyForFn = (fn: Function, params: unknown): number => {\n const queryDef = QUERY_DEFINITION_MAP.get(fn);\n\n if (queryDef === undefined) {\n throw new Error('Query definition not found');\n }\n\n return queryKeyFor(queryDef(), params);\n};\n\ninterface OptimisticInsertOptions<OptimisticInsertDef extends EntityDef | UnionDef<EntityDef[]>> {\n type: OptimisticInsertDef;\n}\n\n/**\n * BIG TODO:\n *\n * All of the `any` types in this file need to be removed, but we need to figure\n * out why we're getting so many infinite recursion errors with types first. When\n * we remove them, the types should work without the `any`s.\n */\ninterface RESTQueryDefinition<\n Path extends string,\n SearchParams extends SearchParamsDefinition,\n ResponseDef extends Record<string, ObjectFieldTypeDef> | ObjectFieldTypeDef,\n StreamEntityDef extends EntityDef | UnionDef<EntityDef[]> | undefined = undefined,\n OptimisticInsertDef extends EntityDef | UnionDef<EntityDef[]> | undefined = undefined,\n> {\n path: Path;\n method?: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';\n searchParams?: SearchParams;\n response: ResponseDef;\n requestOptions?: QueryRequestOptions;\n cache?: QueryCacheOptions;\n stream?: StreamEntityDef extends EntityDef | UnionDef<EntityDef[]>\n ? StreamOptions<SearchParams, StreamEntityDef>\n : undefined;\n optimisticInserts?: OptimisticInsertDef extends EntityDef | UnionDef<EntityDef[]>\n ? OptimisticInsertOptions<OptimisticInsertDef>\n : undefined;\n debounce?: number;\n}\n\ninterface InfiniteRESTQueryDefinition<\n Path extends string,\n SearchParams extends SearchParamsDefinition,\n ResponseDef extends Record<string, ObjectFieldTypeDef> | ObjectFieldTypeDef,\n StreamEntityDef extends EntityDef | UnionDef<EntityDef[]> | undefined = undefined,\n OptimisticInsertDef extends EntityDef | UnionDef<EntityDef[]> | undefined = undefined,\n> {\n path: Path;\n method?: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';\n searchParams?: SearchParams;\n response: ResponseDef;\n requestOptions?: QueryRequestOptions;\n cache?: QueryCacheOptions;\n stream?: StreamEntityDef extends EntityDef | UnionDef<EntityDef[]>\n ? StreamOptions<SearchParams, StreamEntityDef>\n : undefined;\n optimisticInserts?: OptimisticInsertDef extends EntityDef | UnionDef<EntityDef[]>\n ? OptimisticInsertOptions<OptimisticInsertDef>\n : undefined;\n pagination: {\n getNextPageParams?(\n lastPage: ExtractTypesFromObjectOrEntity<ResponseDef>,\n params?: ExtractTypesFromObjectOrEntity<SearchParams> | undefined,\n ): QueryParams | undefined;\n };\n debounce?: number;\n}\n\ntype ExtractQueryParams<Path extends string, SearchParams extends SearchParamsDefinition> = PathParams<Path> &\n ExtractTypesFromObjectOrEntity<SearchParams>;\n\ninterface StreamQueryDefinitionBuilder<\n Params extends SearchParamsDefinition,\n Response extends Record<string, ObjectFieldTypeDef> | ObjectFieldTypeDef,\n> {\n id: string;\n params?: Params;\n response: Response;\n subscribe: (\n params: ExtractTypesFromObjectOrEntity<Params>,\n onUpdate: (update: Partial<ExtractTypesFromObjectOrEntity<Response>>) => void,\n ) => () => void;\n cache?: StreamCacheOptions;\n}\n\nfunction buildQueryFn(\n queryDefinitionBuilder: () =>\n | RESTQueryDefinition<\n string,\n SearchParamsDefinition,\n ObjectFieldTypeDef | Record<string, ObjectFieldTypeDef>,\n EntityDef | UnionDef<EntityDef[]>\n >\n | InfiniteRESTQueryDefinition<\n string,\n SearchParamsDefinition,\n ObjectFieldTypeDef | Record<string, ObjectFieldTypeDef>,\n EntityDef | UnionDef<EntityDef[]>\n >,\n): QueryDefinition<QueryParams, unknown, unknown> {\n let queryDefinition: any | undefined;\n\n const getQueryDefinition = () => {\n if (queryDefinition === undefined) {\n const {\n path,\n method = 'GET',\n response,\n requestOptions,\n cache,\n pagination,\n stream,\n optimisticInserts,\n debounce,\n } = queryDefinitionBuilder() as InfiniteRESTQueryDefinition<any, any, any, any, any>;\n\n const id = `${method}:${path}`;\n\n let shape: TypeDef;\n let shapeKey: number;\n\n if (typeof response === 'object') {\n if (response instanceof ValidatorDef) {\n shape = response as TypeDef;\n shapeKey = response.shapeKey;\n } else if (response instanceof Set) {\n shape = response;\n shapeKey = hashValue(response);\n } else {\n shape = t.object(response as Record<string, ObjectFieldTypeDef>);\n shapeKey = shape.shapeKey;\n }\n } else {\n shape = response as Mask;\n shapeKey = hashValue(shape);\n }\n\n // Create optimized path interpolator (parses template once)\n const interpolatePath = createPathInterpolator(path);\n\n const fetchFn = async (context: QueryContext, params: QueryParams) => {\n // Interpolate path params and append search params automatically\n const interpolatedPath = interpolatePath(params);\n\n // Resolve baseUrl: query-level requestOptions overrides context-level\n const baseUrl = resolveBaseUrl(requestOptions?.baseUrl) ?? resolveBaseUrl(context.baseUrl);\n const fullUrl = baseUrl ? `${baseUrl}${interpolatedPath}` : interpolatedPath;\n\n // Extract request init options (excluding baseUrl which is not a valid RequestInit property)\n const { baseUrl: _baseUrl, ...fetchOptions } = requestOptions ?? {};\n\n const response = await context.fetch(fullUrl, {\n method,\n ...fetchOptions,\n });\n\n return response.json();\n };\n\n // Process stream configuration if provided\n let streamConfig: any = undefined;\n if (stream) {\n let streamShape: TypeDef;\n let streamShapeKey: number;\n\n const eventDef = stream.type;\n\n if (typeof eventDef === 'object') {\n if (eventDef instanceof ValidatorDef) {\n streamShape = eventDef as TypeDef;\n streamShapeKey = eventDef.shapeKey;\n } else if (eventDef instanceof Set) {\n streamShape = eventDef;\n streamShapeKey = hashValue(eventDef);\n } else {\n streamShape = t.object(eventDef as Record<string, ObjectFieldTypeDef>);\n streamShapeKey = streamShape.shapeKey;\n }\n } else {\n streamShape = eventDef as Mask;\n streamShapeKey = hashValue(streamShape);\n }\n\n streamConfig = {\n shape: streamShape,\n shapeKey: streamShapeKey,\n subscribeFn: (context: QueryContext, params: QueryParams | undefined, onUpdate: any) => {\n return (stream.subscribe as any)(context, params as any, onUpdate);\n },\n };\n }\n\n // Process optimistic inserts configuration if provided\n let optimisticInsertsConfig: any = undefined;\n if (optimisticInserts) {\n let insertShape: TypeDef;\n let insertShapeKey: number;\n\n const insertDef = optimisticInserts.type;\n\n if (typeof insertDef === 'object') {\n if (insertDef instanceof ValidatorDef) {\n insertShape = insertDef as TypeDef;\n insertShapeKey = insertDef.shapeKey;\n } else if (insertDef instanceof Set) {\n insertShape = insertDef;\n insertShapeKey = hashValue(insertDef);\n } else {\n insertShape = t.object(insertDef as Record<string, ObjectFieldTypeDef>);\n insertShapeKey = insertShape.shapeKey;\n }\n } else {\n insertShape = insertDef as Mask;\n insertShapeKey = hashValue(insertShape);\n }\n\n optimisticInsertsConfig = {\n shape: insertShape,\n shapeKey: insertShapeKey,\n };\n }\n\n queryDefinition = {\n type: pagination ? QueryType.InfiniteQuery : QueryType.Query,\n id,\n shape,\n shapeKey,\n fetchFn,\n pagination,\n cache,\n stream: streamConfig,\n optimisticInserts: optimisticInsertsConfig,\n debounce,\n };\n }\n\n return queryDefinition;\n };\n\n const queryFn = reactive(\n (params: QueryParams | undefined): QueryResult<unknown, unknown, unknown> => {\n const queryClient = getContext(QueryClientContext);\n\n if (queryClient === undefined) {\n throw new Error('QueryClient not found');\n }\n\n return queryClient.getQuery<unknown>(getQueryDefinition(), params);\n },\n // TODO: Getting a lot of type errors due to infinite recursion here.\n // For now, we return as any to coerce to the external type signature,\n // and internally we manage the difference.\n ) as any;\n\n QUERY_DEFINITION_MAP.set(queryFn, getQueryDefinition);\n\n return queryFn;\n}\n\nexport function query<\n Path extends string,\n SearchParams extends SearchParamsDefinition,\n Response extends Record<string, ObjectFieldTypeDef> | ObjectFieldTypeDef,\n EventDef extends EntityDef | UnionDef<EntityDef[]> | undefined = undefined,\n OptimisticUpdateDef extends EntityDef | UnionDef<EntityDef[]> | undefined = undefined,\n>(\n queryDefinitionBuilder: () => RESTQueryDefinition<Path, SearchParams, Response, EventDef, OptimisticUpdateDef>,\n): QueryFn<ExtractQueryParams<Path, SearchParams>, Response, EventDef, OptimisticUpdateDef> {\n return buildQueryFn(queryDefinitionBuilder as any) as any;\n}\n\nexport function infiniteQuery<\n Path extends string,\n SearchParams extends SearchParamsDefinition,\n Response extends Record<string, ObjectFieldTypeDef> | ObjectFieldTypeDef,\n EventDef extends EntityDef | UnionDef<EntityDef[]> | undefined = undefined,\n OptimisticInsertDef extends EntityDef | UnionDef<EntityDef[]> | undefined = undefined,\n>(\n queryDefinitionBuilder: () => InfiniteRESTQueryDefinition<\n Path,\n SearchParams,\n Response,\n EventDef,\n OptimisticInsertDef\n >,\n): InfiniteQueryFn<ExtractQueryParams<Path, SearchParams>, Response, EventDef, OptimisticInsertDef> {\n return buildQueryFn(queryDefinitionBuilder as any) as any;\n}\n\nexport function streamQuery<\n // TODO: This is a hack to get the type signature to work. We should find a better way to do this.\n Path extends '',\n Params extends SearchParamsDefinition,\n Response extends EntityDef | UnionDef<EntityDef[]>,\n>(\n queryDefinitionBuilder: () => StreamQueryDefinitionBuilder<Params, Response>,\n): StreamQueryFn<ExtractQueryParams<Path, Params>, Response> {\n let streamDefinition: any | undefined;\n\n const getStreamDefinition = () => {\n if (streamDefinition === undefined) {\n const { id, response, subscribe, cache } = queryDefinitionBuilder();\n\n // Validate that response is an EntityDef\n if (!(response instanceof ValidatorDef) || (response.mask & Mask.ENTITY) === 0) {\n throw new Error('Stream query response must be an EntityDef');\n }\n\n streamDefinition = {\n type: QueryType.Stream,\n id,\n shape: response as EntityDef,\n shapeKey: response.shapeKey,\n subscribeFn: (context: QueryContext, params: QueryParams | undefined, onUpdate: any) => {\n return (subscribe as any)(params as any, onUpdate);\n },\n cache,\n };\n }\n return streamDefinition;\n };\n\n const streamFn = reactive((params: QueryParams | undefined): QueryResult<unknown, unknown, unknown> => {\n const queryClient = getContext(QueryClientContext);\n\n if (queryClient === undefined) {\n throw new Error('QueryClient not found');\n }\n\n return queryClient.getQuery<unknown>(getStreamDefinition(), params);\n }) as any;\n\n QUERY_DEFINITION_MAP.set(streamFn, getStreamDefinition);\n\n return streamFn;\n}\n","import { getContext } from 'signalium';\nimport {\n MutationResult,\n MutationFn,\n Mask,\n ObjectFieldTypeDef,\n UnionDef,\n ExtractTypesFromObjectOrEntity,\n EntityDef,\n TypeDef,\n RetryConfig,\n} from './types.js';\nimport { QueryClientContext, QueryContext } from './QueryClient.js';\nimport { t, ValidatorDef } from './typeDefs.js';\nimport { createPathInterpolator } from './pathInterpolator.js';\nimport { hashValue } from 'signalium/utils';\n\ntype IsParameter<Part> = Part extends `[${infer ParamName}]` ? ParamName : never;\ntype FilteredParts<Path> = Path extends `${infer PartA}/${infer PartB}`\n ? IsParameter<PartA> | FilteredParts<PartB>\n : IsParameter<Path>;\ntype ParamValue<Key> = Key extends `...${infer Anything}` ? (string | number)[] : string | number;\ntype RemovePrefixDots<Key> = Key extends `...${infer Name}` ? Name : Key;\ntype PathParams<Path> = {\n [Key in FilteredParts<Path> as RemovePrefixDots<Key>]: ParamValue<Key>;\n};\n\n// -----------------------------------------------------------------------------\n// Mutation Definition Types\n// -----------------------------------------------------------------------------\n\nexport interface MutationCacheOptions {\n /**\n * Retry configuration for failed mutations\n */\n retry?: RetryConfig | number | false;\n}\n\nexport interface MutationDefinition<Request, Response> {\n id: string;\n requestShape: TypeDef;\n requestShapeKey: number;\n responseShape: TypeDef;\n responseShapeKey: number;\n mutateFn: (context: QueryContext, request: Request) => Promise<Response>;\n optimisticUpdates: boolean;\n cache?: MutationCacheOptions;\n}\n\n// Map for getting mutation definitions by function reference, for testing\n// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\nconst MUTATION_DEFINITION_MAP = new Map<Function, () => MutationDefinition<any, any>>();\n\n// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\nexport const mutationKeyFor = (fn: Function): string => {\n const mutationDef = MUTATION_DEFINITION_MAP.get(fn);\n\n if (mutationDef === undefined) {\n throw new Error('Mutation definition not found');\n }\n\n return mutationDef().id;\n};\n\n// -----------------------------------------------------------------------------\n// REST Mutation Definition\n// -----------------------------------------------------------------------------\n\ninterface RESTMutationDefinition<\n Path extends string,\n RequestDef extends Record<string, ObjectFieldTypeDef> | ObjectFieldTypeDef,\n ResponseDef extends Record<string, ObjectFieldTypeDef> | ObjectFieldTypeDef,\n> {\n /**\n * The URL path for the mutation. Supports path parameters like `/users/[id]`.\n */\n path: Path;\n /**\n * HTTP method for the mutation. Defaults to POST.\n */\n method?: 'POST' | 'PUT' | 'DELETE' | 'PATCH';\n /**\n * TypeDef for the request body.\n */\n request: RequestDef;\n /**\n * TypeDef for the response body.\n */\n response: ResponseDef;\n /**\n * Whether to automatically apply optimistic updates.\n * When true, entities in the request will be immediately updated in the store\n * before the mutation completes, and reverted if the mutation fails.\n * Defaults to false.\n */\n optimisticUpdates?: boolean;\n /**\n * Cache options including retry configuration.\n */\n cache?: MutationCacheOptions;\n}\n\ntype ExtractMutationRequest<\n Path extends string,\n RequestDef extends Record<string, ObjectFieldTypeDef> | ObjectFieldTypeDef,\n> = PathParams<Path> & ExtractTypesFromObjectOrEntity<RequestDef>;\n\n// -----------------------------------------------------------------------------\n// Build Mutation Function\n// -----------------------------------------------------------------------------\n\nfunction processTypeDef(typeDef: Record<string, ObjectFieldTypeDef> | ObjectFieldTypeDef): {\n shape: TypeDef;\n shapeKey: number;\n} {\n let shape: TypeDef;\n let shapeKey: number;\n\n if (typeof typeDef === 'object') {\n if (typeDef instanceof ValidatorDef) {\n shape = typeDef as TypeDef;\n shapeKey = typeDef.shapeKey;\n } else if (typeDef instanceof Set) {\n shape = typeDef;\n shapeKey = hashValue(typeDef);\n } else {\n shape = t.object(typeDef as Record<string, ObjectFieldTypeDef>);\n shapeKey = shape.shapeKey;\n }\n } else {\n shape = typeDef as Mask;\n shapeKey = hashValue(shape);\n }\n\n return { shape, shapeKey };\n}\n\nfunction buildMutationFn<Request, Response>(\n mutationDefinitionBuilder: () => RESTMutationDefinition<\n string,\n ObjectFieldTypeDef | Record<string, ObjectFieldTypeDef>,\n ObjectFieldTypeDef | Record<string, ObjectFieldTypeDef>\n >,\n): () => MutationResult<Request, Response> {\n let mutationDefinition: MutationDefinition<Request, Response> | undefined;\n\n const getMutationDefinition = (): MutationDefinition<Request, Response> => {\n if (mutationDefinition === undefined) {\n const {\n path,\n method = 'POST',\n request,\n response,\n optimisticUpdates = false,\n cache,\n } = mutationDefinitionBuilder();\n\n const id = `mutation:${method}:${path}`;\n\n const { shape: requestShape, shapeKey: requestShapeKey } = processTypeDef(request);\n const { shape: responseShape, shapeKey: responseShapeKey } = processTypeDef(response);\n\n // Create optimized path interpolator (parses template once)\n const interpolatePath = createPathInterpolator(path);\n\n // Extract path parameter names from the path template\n const pathParamNames = new Set<string>();\n const paramRegex = /\\[([^\\]]+)\\]/g;\n let match: RegExpExecArray | null;\n while ((match = paramRegex.exec(path)) !== null) {\n pathParamNames.add(match[1]);\n }\n\n const mutateFn = async (context: QueryContext, requestData: Request): Promise<Response> => {\n // Only pass path params to the interpolator, not the full request\n const pathParams: Record<string, unknown> = {};\n for (const paramName of pathParamNames) {\n pathParams[paramName] = (requestData as Record<string, unknown>)[paramName];\n }\n const url = interpolatePath(pathParams);\n\n const fetchResponse = await context.fetch(url, {\n method,\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(requestData),\n });\n\n return fetchResponse.json();\n };\n\n mutationDefinition = {\n id,\n requestShape,\n requestShapeKey,\n responseShape,\n responseShapeKey,\n mutateFn,\n optimisticUpdates,\n cache,\n };\n }\n\n return mutationDefinition;\n };\n\n const mutationFn = (): MutationResult<Request, Response> => {\n const queryClient = getContext(QueryClientContext);\n\n if (queryClient === undefined) {\n throw new Error('QueryClient not found');\n }\n\n return queryClient.getMutation<Request, Response>(getMutationDefinition());\n };\n\n MUTATION_DEFINITION_MAP.set(mutationFn, getMutationDefinition);\n\n return mutationFn;\n}\n\n// -----------------------------------------------------------------------------\n// Public API\n// -----------------------------------------------------------------------------\n\n/**\n * Creates a mutation function that returns a MutationResult.\n * Mutations must be explicitly run via `.run(request)`.\n *\n * @example\n * ```ts\n * const updateUser = mutation(() => ({\n * path: '/users/[id]',\n * method: 'PUT',\n * request: {\n * id: t.id,\n * name: t.string,\n * email: t.string,\n * },\n * response: User,\n * optimisticUpdates: true,\n * }));\n *\n * // Usage:\n * const mutation = updateUser();\n * await mutation.run({ id: '123', name: 'John', email: 'john@example.com' });\n * ```\n */\nexport function mutation<\n Path extends string,\n RequestDef extends Record<string, ObjectFieldTypeDef> | ObjectFieldTypeDef,\n ResponseDef extends Record<string, ObjectFieldTypeDef> | ObjectFieldTypeDef,\n>(\n mutationDefinitionBuilder: () => RESTMutationDefinition<Path, RequestDef, ResponseDef>,\n): MutationFn<ExtractMutationRequest<Path, RequestDef>, ResponseDef> {\n return buildMutationFn(mutationDefinitionBuilder as any) as any;\n}\n"],"names":["RefetchInterval","NetworkMode","Mask","entries","isArray","hashValue","entity","deepClone","reactiveMethod","setScopeOwner","notifier","relay","signal","context","value","setReactivePromise","isPaused","reactiveSignal","task","query","QueryType","response","reactive","getContext"],"mappings":";;;;AA6CO,IAAK,oCAAAA,qBAAL;AACLA,mBAAAA,iBAAA,kBAAe,GAAA,IAAf;AACAA,mBAAAA,iBAAA,mBAAgB,GAAA,IAAhB;AACAA,mBAAAA,iBAAA,oBAAiB,GAAA,IAAjB;AACAA,mBAAAA,iBAAA,oBAAiB,GAAA,IAAjB;AACAA,mBAAAA,iBAAA,kBAAe,GAAA,IAAf;AACAA,mBAAAA,iBAAA,mBAAgB,GAAA,IAAhB;AANU,SAAAA;AAAA,GAAA,mBAAA,CAAA,CAAA;AASL,IAAK,gCAAAC,iBAAL;AAILA,eAAA,QAAA,IAAS;AAITA,eAAA,QAAA,IAAS;AAITA,eAAA,cAAA,IAAe;AAZL,SAAAA;AAAA,GAAA,eAAA,CAAA,CAAA;AA2BL,IAAW,yBAAAC,UAAX;AAELA,QAAAA,MAAA,eAAY,CAAA,IAAZ;AACAA,QAAAA,MAAA,UAAO,CAAA,IAAP;AACAA,QAAAA,MAAA,YAAS,CAAA,IAAT;AACAA,QAAAA,MAAA,YAAS,CAAA,IAAT;AACAA,QAAAA,MAAA,aAAU,EAAA,IAAV;AACAA,QAAAA,MAAA,YAAS,EAAA,IAAT;AACAA,QAAAA,MAAA,WAAQ,EAAA,IAAR;AACAA,QAAAA,MAAA,QAAK,GAAA,IAAL;AAGAA,QAAAA,MAAA,YAAS,GAAA,IAAT;AACAA,QAAAA,MAAA,WAAQ,GAAA,IAAR;AACAA,QAAAA,MAAA,YAAS,IAAA,IAAT;AAGAA,QAAAA,MAAA,oBAAiB,IAAA,IAAjB;AACAA,QAAAA,MAAA,uBAAoB,IAAA,IAApB;AACAA,QAAAA,MAAA,uBAAoB,IAAA,IAApB;AACAA,QAAAA,MAAA,kBAAe,KAAA,IAAf;AApBgB,SAAAA;AAAA,GAAA,QAAA,CAAA,CAAA;AAmFX,MAAM,YAAY,OAAO,OAAO;AAChC,MAAM,aAAa,OAAO,QAAQ;AC9IzC,MAAMC,YAAU,OAAO;AACvB,MAAMC,YAAU,MAAM;AAYf,MAAM,aAAgB;AAAA,EACnB;AAAA,EACD;AAAA,EACC;AAAA,EACA;AAAA,EACA;AAAA,EACA,YAAgC;AAAA,EAChC;AAAA,EACD,iBAAgD;AAAA,EAChD,gBAAoC;AAAA,EACpC,gBAAoC;AAAA,EACpC,UAA8B;AAAA,EAC9B,SAAqD;AAAA;AAAA;AAAA;AAAA;AAAA,EAKrD,kBAAqD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOrD,WAAsC;AAAA;AAAA;AAAA;AAAA,EAKtC,gBAA+C;AAAA,EAEtD,YACE,MACA,MACA,OACA,SAAqD,QACrD;AACA,SAAK,OAAO;AACZ,SAAK,OAAO;AACZ,SAAK,SAAS;AACd,SAAK,SAAS;AAAA,EAChB;AAAA,EAEA,OAAO,UACL,KACA,MACA,SAAqD,QAClC;AACnB,UAAM,SAAS,IAAI,aAAa,IAAI,MAAM,OAAO,IAAI,MAAM,IAAI,QAAQ,MAAM;AAC7E,WAAO,iBAAiB,IAAI;AAC5B,WAAO,SAAS,IAAI;AACpB,WAAO,gBAAgB,IAAI;AAC3B,WAAO,gBAAgB,IAAI;AAC3B,WAAO,UAAU,IAAI;AACrB,WAAO,kBAAkB,IAAI;AAC7B,WAAO,WAAW,IAAI;AACtB,WAAO,gBAAgB,IAAI;AAC3B,WAAO;AAAA,EACT;AAAA,EAEA,aAAa;AACX,QAAI,KAAK,cAAc,QAAW;AAChC,cAAQ,KAAK,MAAA;AAAA,QACX,KAAK,GAA2B;AAC9B,gBAAM,QAAS,KAAK,OAAA;AACpB,eAAK,SAAS,iBAAiB,MAAM,KAAK;AAE1C,cAAI,KAAK,mBAAmB,CAAC,KAAK,UAAU;AAC1C,iBAAK,WAAW,KAAK,gBAAA;AAAA,UACvB;AACA;AAAA,QACF;AAAA,QACA,KAAK;AACH,eAAK,SAAS,iBAAiB,MAAM,KAAK,MAAqB;AAC/D;AAAA,QACF,KAAK;AACH,eAAK,SAAS,gBAAgB,MAAM,KAAK,MAA0B;AACnE;AAAA,QACF,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK,GAAiC;AACpC,gBAAM,QAAQ,KAAK;AAEnB,cAAI;AAEJ,cAAI,iBAAiB,cAAc;AACjC,uBAAW,MAAM;AAEjB,gBAAI,MAAM,QAAQ,KAAK,SAAS,KAAK,iBAAiB;AACpD,mBAAK,QAAQ,KAAK;AAAA,YACpB;AAAA,UACF,WAAW,iBAAiB,oBAAoB;AAC9C,uBAAWC,MAAAA,UAAU,MAAM,KAAK,KAAK,CAAC;AAAA,UACxC,OAAO;AACL,uBAAWA,MAAAA,UAAU,KAAK;AAAA,UAC5B;AAEA,eAAK,YAAYA,gBAAU,CAAC,KAAK,MAAM,KAAK,MAAM,KAAK,QAAQ,QAAQ,CAAC;AAExE;AAAA,QACF;AAAA,MAAA;AAAA,IAEJ;AAAA,EACF;AAAA,EAEA,IAAI,QAA2D;AAC7D,SAAK,WAAA;AAEL,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAI,UAAqC;AACvC,SAAK,WAAA;AAEL,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAI,WAAmB;AACrB,SAAK,WAAA;AAEL,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAI,SAAS,KAAa;AACxB,SAAK,YAAY,QAAQ;AAAA,EAC3B;AAAA,EAEA,IAAI,WAAwC;AAC1C,QAAI,KAAK,cAAc,QAAW;AAChC,WAAK,YAAY,aAAa,UAAU,MAAM,KAAK,SAAS;AAAA,IAC9D;AACA,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAI,WAAmC;AACrC,QAAI,KAAK,cAAc,QAAW;AAChC,WAAK,YAAY,aAAa,UAAU,MAAM,KAAK,IAAI;AAAA,IACzD;AACA,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAI,UAA8C;AAChD,QAAI,KAAK,aAAa,QAAW;AAC/B,WAAK,WAAW,aAAa,UAAU,MAAM,KAAK,YAAY,KAAK,IAAI;AAAA,IACzE;AACA,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,OACE,mBAEA,kBACmB;AAEnB,QAAI,KAAK,SAAS,KAA6B,KAAK,SAAS,GAA2B;AACtF,YAAM,IAAI,MAAM,uDAAuD;AAAA,IACzE;AAEA,QAAI,KAAK,SAAS,GAA2B;AAK3C,YAAM,kBAAkB;AACxB,YAAM,uBAAuB,KAAK;AAElC,YAAM,cAAc,IAAI,aAAa,GAA2B,KAAK,MAAM,MAAM;AAC/E,cAAM,gBAAgB,KAAK;AAC3B,cAAM,YAAY,gBAAA;AAGlB,mBAAW,OAAO,OAAO,KAAK,SAAS,GAAG;AACxC,cAAI,OAAO,eAAe;AACxB,kBAAM,IAAI,MAAM,yBAAyB,GAAG,qCAAqC;AAAA,UACnF;AAAA,QACF;AAEA,eAAO,EAAE,GAAG,eAAe,GAAG,UAAA;AAAA,MAChC,CAAC;AAGD,UAAI,wBAAwB,kBAAkB;AAC5C,oBAAY,kBAAkB,MAAM;AAClC,gBAAM,gBAAgB,uBAAuB,qBAAA,IAAyB,CAAA;AACtE,gBAAM,aAAa,mBAAmB,iBAAA,IAAqB,CAAA;AAC3D,iBAAO,EAAE,GAAG,eAAe,GAAG,WAAA;AAAA,QAChC;AAAA,MACF;AAGA,kBAAY,gBAAgB,KAAK;AAEjC,aAAO;AAAA,IACT,OAAO;AAEL,WAAK,WAAA;AAEL,YAAM,gBAAgB,KAAK;AAC3B,YAAM,YAAY;AAGlB,iBAAW,OAAO,OAAO,KAAK,SAAS,GAAG;AACxC,YAAI,OAAO,eAAe;AACxB,gBAAM,IAAI,MAAM,yBAAyB,GAAG,qCAAqC;AAAA,QACnF;AAAA,MACF;AAEA,aAAO,IAAI,aAAa,GAA2B,KAAK,MAAM,EAAE,GAAG,eAAe,GAAG,WAAW;AAAA,IAClG;AAAA,EACF;AACF;AAWO,MAAM,2BAAgE,IAAO;AAAA,EACjE;AAAA;AAAA,EAEjB,YAAY,QAAsB;AAChC,UAAM,MAAM;AAEZ,SAAK,mCAAmB,IAAA;AAExB,eAAW,SAAS,QAAQ;AAC1B,UAAI,OAAO,UAAU,UAAU;AAC7B,cAAM,YAAY,MAAM,YAAA;AACxB,cAAM,WAAW,KAAK,aAAa,IAAI,SAAS;AAEhD,YAAI,aAAa,QAAW;AAC1B,gBAAM,IAAI;AAAA,YACR,oFAAoF,QAAQ,UAAU,KAAK,kBAAkB,SAAS;AAAA,UAAA;AAAA,QAE1I;AAEA,aAAK,aAAa,IAAI,WAAW,KAAK;AAAA,MACxC;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,IAAI,OAAyB;AAC3B,WAAO,KAAK,IAAI,KAAK,MAAM;AAAA,EAC7B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,IAAI,OAA+B;AACjC,QAAI,OAAO,UAAU,UAAU;AAC7B,aAAO,KAAK,aAAa,IAAI,MAAM,aAAa;AAAA,IAClD;AAEA,QAAI,MAAM,IAAI,KAAU,GAAG;AACzB,aAAO;AAAA,IACT;AAEA,WAAO;AAAA,EACT;AACF;AAMO,SAAS,YAA+B,OAAuB;AACpE,SAAO,IAAI,aAAa,GAA0B,KAAK,OAAO,KAAK;AACrE;AAEO,SAAS,aAAgC,OAAwB;AACtE,SAAO,IAAI,aAAa,GAA2B,KAAK,SAAS,KAAK,QAAQ,KAAK;AACrF;AAEO,SAAS,kBAAqC,WAAiC;AACpF,SAAO,IAAI;AAAA,IACT;AAAA,IACA,KAAK;AAAA,IACL;AAAA,EAAA;AAEJ;AAEO,SAAS,aAAoC,OAAwB;AAC1E,SAAO,IAAI,aAAa,GAA2B,KAAK,QAAQ,KAAK;AACvE;AAEA,SAAS,eAA6C,OAAuB;AAC3E,MAAI,OAAO;AACX,MAAI;AACJ,MAAI;AACJ,MAAI;AAEJ,aAAW,QAAQ,OAAO;AACxB,QAAI,OAAO,SAAS,UAAU;AAC5B,cAAQ;AACR;AAAA,IACF;AAEA,QAAI,gBAAgB,KAAK;AACvB,UAAI,WAAW,QAAW;AACxB,iBAAS,IAAI,IAAI,IAAI;AAAA,MACvB,OAAO;AACL,mBAAW,OAAO,MAAM;AACtB,iBAAO,IAAI,GAAG;AAAA,QAChB;AAAA,MACF;AAEA;AAAA,IACF;AAEA,QAAI,eAAe,QAAW;AAC5B,mBAAa;AACb;AAAA,IACF;AAEA,QAAI,UAAU,QAAW;AACvB,cAAQ,CAAC,UAAU;AAAA,IACrB;AAEA,UAAM,KAAK,IAAI;AAAA,EACjB;AAEA,MAAI,eAAe,QAAW;AAE5B,QAAI,WAAW,QAAW;AAMxB,aAAO;AAAA,IACT;AAGA,QAAI,SAAS,GAAG;AAOd,aAAO;AAAA,IACT;AAGA,WAAO,IAAI,aAAa,GAAoC,OAAO,KAAK,OAAO,QAAW,MAAM;AAAA,EAClG;AAGA,MAAI,UAAU,QAAW;AACvB,WAAO,aAAa,UAAU,YAAiC,MAAM,MAAM;AAAA,EAC7E;AAEA,SAAO,IAAI,aAAa,GAA0B,OAAO,KAAK,OAAO,OAAO,MAAM;AACpF;AAEA,SAAS,cAAiC,MAAyC;AACjF,MAAI,OAAO,SAAS,UAAU;AAC5B,WAAQ,OAAO,KAAK,YAAY,KAAK;AAAA,EACvC;AAEA,MAAI,gBAAgB,KAAK;AACvB,WAAO,YAAY,MAAM,KAAK,WAAW,KAAK,IAAI;AAAA,EACpD;AAGA,SAAO,KAAK;AACd;AAEA,SAAS,eAAkC,MAA6B;AACtE,MAAI,OAAO,SAAS,UAAU;AAC5B,WAAQ,OAAO,KAAK;AAAA,EACtB;AAEA,MAAI,gBAAgB,KAAK;AACvB,WAAO,YAAY,MAAM,KAAK,SAAS;AAAA,EACzC;AAGA,SAAO,KAAK;AACd;AAEA,SAAS,eAAkC,MAAwB;AACjE,MAAI,OAAO,SAAS,UAAU;AAC5B,WAAQ,OAAO,KAAK;AAAA,EACtB;AAEA,MAAI,gBAAgB,KAAK;AACvB,WAAO,YAAY,MAAM,KAAK,IAAI;AAAA,EACpC;AAGA,SAAO,KAAK;AACd;AAMO,SAAS,iBAAiB,KAAwB,OAAiC;AAExF,MAAI,WAAWA,MAAAA,UAAU,CAAC,IAAI,MAAM,IAAI,MAAM,CAAC;AAE/C,aAAW,CAAC,KAAK,KAAK,KAAKF,UAAQ,KAAK,GAAG;AACzC,YAAQ,OAAO,OAAA;AAAA,MACb,KAAK;AACH,aAAK,QAAQ,KAAK,QAAQ,GAAG;AAC3B,cAAI,IAAI,YAAY,QAAW;AAC7B,kBAAM,IAAI,MAAM,uBAAuB,GAAG,EAAE;AAAA,UAC9C;AAEA,cAAI,UAAU;AAAA,QAChB;AAGA,oBAAYE,MAAAA,UAAU,GAAG,IAAI;AAC7B;AAAA,MACF,KAAK;AAEH,YAAI,IAAI,kBAAkB,UAAa,IAAI,kBAAkB,KAAK;AAChE,gBAAM,IAAI,MAAM,6BAA6B,GAAG,EAAE;AAAA,QACpD;AAEA,YAAI,gBAAgB;AACpB,YAAI,gBAAgB;AAGpB,oBAAYA,MAAAA,UAAU,GAAG,IAAIA,MAAAA,UAAU,KAAK;AAC5C;AAAA,MACF,KAAK;AACH,YAAI,iBAAiB,oBAAoB;AACvC,sBAAYA,MAAAA,UAAU,GAAG,IAAIA,MAAAA,UAAU,MAAM,KAAK,KAAK,CAAC;AACxD;AAAA,QACF;AAEA,YAAI,iBAAiB,KAAK;AACxB,sBAAYA,MAAAA,UAAU,GAAG,IAAIA,MAAAA,UAAU,KAAK;AAC5C;AAAA,QACF;AAGA,oBAAYA,MAAAA,UAAU,GAAG,IAAI,MAAM;AAEnC,YAAI,MAAM,QAAQ,KAAK,SAAS,KAAK,iBAAiB;AACpD,cAAI,QAAQ,KAAK;AACjB,cAAI,IAAI,mBAAmB,QAAW;AACpC,gBAAI,iBAAiB;AAAA,UACvB,WAAWD,UAAQ,IAAI,cAAc,GAAG;AACtC,gBAAI,eAAe,KAAK,GAAG;AAAA,UAC7B,OAAO;AACL,gBAAI,iBAAiB,CAAC,IAAI,gBAAgB,GAAG;AAAA,UAC/C;AAAA,QACF;AACA;AAAA,IAAA;AAAA,EAEN;AAGA,MAAI,WAAW,aAAa;AAE5B,SAAO;AACT;AAEA,SAAS,gBAAgB,KAAwB,MAAuC;AACtF,MAAI,OAAO,IAAI;AAEf,MAAI,QAAuB,uBAAO,OAAO,IAAI;AAC7C,MAAI;AAGJ,MAAI,WAAWC,MAAAA,UAAU,CAAC,MAAM,IAAI,MAAM,CAAC;AAE3C,aAAW,aAAa,MAAM;AAC5B,UAAM,aAAa,UAAU;AAE7B,YAAQ;AAGR,gBAAY,UAAU;AAEtB,SAAK,aAAa,KAAK,WAAW,GAAG;AAEnC,YAAM,cAAc;AAGpB,UAAI,YAAY,kBAAkB,QAAW;AAC3C,YAAI,uBAAuB,UAAa,uBAAuB,YAAY,eAAe;AACxF,gBAAM,IAAI;AAAA,YACR,uFAAuF,kBAAkB,SAAS,YAAY,aAAa;AAAA,UAAA;AAAA,QAE/I;AACA,6BAAqB,YAAY;AAAA,MACnC;AAEA,YAAM,cAAc,YAAY;AAGhC,UAAI,gBAAgB,QAAW;AAC7B,mBAAW,OAAO,CAAC,GAAG,OAAO,KAAK,WAAW,GAAG,WAAW,UAAU,GAAY;AAE/E,gBAAM,QAAQ,YAAY,GAAG;AAE7B,cAAI,MAAM,GAAG,MAAM,UAAa,MAAM,GAAG,MAAM,OAAO;AACpD,kBAAM,IAAI;AAAA,cACR,mDAAmD,OAAO,GAAG,CAAC,uCAAuC,OAAO,MAAM,GAAG,CAAC,CAAC,OAAO,OAAO,KAAK,CAAC;AAAA,YAAA;AAAA,UAE/I;AAGA,gBAAM,GAAG,IAAI;AAAA,QACf;AAAA,MACF;AAAA,IACF,YAAY,aAAa,KAAK,WAAW,GAAG;AAC1C,UAAI,MAAM,SAAS,MAAM,QAAW;AAClC,cAAM,IAAI,MAAM,6BAA6B;AAAA,MAC/C;AAEA,YAAM,SAAS,IAAI,UAAU;AAAA,IAC/B,YAAY,aAAa,KAAK,YAAY,GAAG;AAC3C,UAAI,MAAM,UAAU,MAAM,QAAW;AACnC,cAAM,IAAI,MAAM,8BAA8B;AAAA,MAChD;AAEA,YAAM,UAAU,IAAI,UAAU;AAAA,IAChC,OAAO;AAEL,YAAM,gBAAiB,UAAwB;AAC/C,YAAM,WAAY,UAAwB;AAE1C,UAAI,aAAa,QAAW;AAC1B,cAAM,IAAI;AAAA,UACR;AAAA,QAAA;AAAA,MAEJ;AAEA,UAAI,uBAAuB,UAAa,kBAAkB,oBAAoB;AAC5E,cAAM,IAAI,MAAM,8EAA8E;AAAA,MAChG;AAEA,2BAAqB;AACrB,YAAM,QAAQ,IAAI;AAAA,IACpB;AAAA,EACF;AAEA,MAAI,gBAAgB;AACpB,MAAI,WAAW,aAAa;AAC5B,MAAI,OAAO;AAEX,SAAO;AACT;AAMA,SAAS,eAAiC,OAAa;AACrD,SAAO;AACT;AAEA,SAAS,YAAiD,OAAkB;AAC1E,SAAO,oBAAI,IAAI,CAAC,KAAK,CAAC;AACxB;AAEA,MAAM,cAAc,IAAsD,WAA8B;AACtG,SAAO,IAAI,IAAI,MAAgC;AACjD;AAEA,WAAW,kBAAkB,IACxB,WAC+B;AAClC,SAAO,IAAI,mBAAmB,MAAgC;AAChE;AAMA,MAAM,oBAAoB;AAE1B,IAAI,eAAe;AACnB,MAAM,iBAAkD,CAAA;AAExD,MAAM,iCAAiB,IAAA;AACvB,MAAM,wCAAwB,IAAA;AAE9B,SAAS,gBACP,QAC6C;AAC7C,QAAM,OAAO,WAAW,IAAI,MAAM;AAElC,MAAI,SAAS,QAAW;AACtB,UAAM,IAAI,MAAM,UAAU,MAAM,iBAAiB;AAAA,EACnD;AAEA,SAAO;AACT;AAEO,SAAS,UAAU,MAA2C;AACnE,QAAM,WAAW,QAAQ;AAEzB,SAAO,eAAe,QAAQ;AAChC;AAOO,SAAS,cAAc,MAAkC;AAC9D,QAAM,WAAW,QAAQ;AACzB,SAAO,kBAAkB,IAAI,QAAQ;AACvC;AAEO,SAAS,eACd,MACA,MACA,OACA,WACA;AACA,QAAM,SAAS;AACf,iBAAe,MAAM,IAAI;AAEzB,oBAAkB,IAAI,QAAQ,IAAI;AAElC,QAAM,YAAY,UAAU;AAC5B,QAAM,aAAa,SAAS,KAAK,SAAS,KAAK,oBAAoB,KAAK;AACxE,QAAM,OAAO,YAAY,OAAO;AAEhC,aAAW,IAAI,MAAM,IAAI;AAC3B;AAOA;AAAA,EACE;AAAA,EACA,KAAK;AAAA,EACL,CAAA,UAAS;AAEP,UAAM,QAAQ,MAAM,MAAM,2BAA2B;AACrD,QAAI,CAAC,OAAO;AACV,YAAM,IAAI,MAAM,wBAAwB,KAAK,+BAA+B;AAAA,IAC9E;AACA,UAAM,GAAG,MAAM,OAAO,GAAG,IAAI;AAC7B,UAAM,OAAO,IAAI,KAAK,KAAK,IAAI,SAAS,MAAM,EAAE,GAAG,SAAS,OAAO,EAAE,IAAI,GAAG,SAAS,KAAK,EAAE,CAAC,CAAC;AAC9F,QAAI,MAAM,KAAK,QAAA,CAAS,GAAG;AACzB,YAAM,IAAI,MAAM,wBAAwB,KAAK,EAAE;AAAA,IACjD;AACA,WAAO;AAAA,EACT;AAQF;AAGA;AAAA,EACE;AAAA,EACA,KAAK;AAAA,EACL,CAAA,UAAS;AACP,UAAM,OAAO,IAAI,KAAK,KAAK;AAC3B,QAAI,MAAM,KAAK,QAAA,CAAS,GAAG;AACzB,YAAM,IAAI,MAAM,6BAA6B,KAAK,EAAE;AAAA,IACtD;AACA,WAAO;AAAA,EACT;AAKF;AAiCO,SAAS,OACd,OACA,SACA,QACiB;AACjB,QAAM,MAAM,IAAI;AAAA,IACd;AAAA;AAAA,IAEA,KAAK,SAAS,KAAK;AAAA,IACnB;AAAA,EAAA;AAGF,MAAI,SAAS;AACX,QAAI,kBAAkB;AAAA,EACxB;AAEA,MAAI,QAAQ;AAET,QAAY,gBAAgB;AAAA,EAC/B;AAEA,SAAO;AACT;AAEO,MAAM,IAAc;AAAA,EACzB,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,OAAO;AAAA,EACP,MAAM;AAAA,EACN,IAAI,KAAK,KAAK,KAAK,SAAS,KAAK;AAAA,EACjC,QAAQ,KAAK;AAAA,EACb,QAAQ,KAAK;AAAA,EACb,SAAS,KAAK;AAAA,EACd,MAAM,KAAK;AAAA,EACX,WAAW,KAAK;AAAA,EAChB,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,SAAS;AAAA,EACT,UAAU;AAAA,EACV,UAAU;AAAA,EACV,QAAQ;AACV;AC5xBO,SAAS,aAAa,MAAkC;AAE7D,MAAI,gBAAgB,oBAAoB;AACtC,UAAM,SAAS,MAAM,KAAK,IAAI,EAAE,IAAI,CAAA,MAAM,OAAO,MAAM,WAAW,IAAI,CAAC,MAAM,OAAO,CAAC,CAAE;AACvF,WAAO,OAAO,KAAK,KAAK;AAAA,EAC1B;AAGA,MAAI,gBAAgB,KAAK;AACvB,UAAM,SAAS,MAAM,KAAK,IAAI,EAAE,IAAI,CAAA,MAAM,OAAO,MAAM,WAAW,IAAI,CAAC,MAAM,OAAO,CAAC,CAAE;AACvF,WAAO,OAAO,KAAK,KAAK;AAAA,EAC1B;AAGA,MAAI,OAAO,SAAS,UAAU;AAC5B,WAAO,IAAI,IAAI;AAAA,EACjB;AAEA,MAAI,OAAO,SAAS,WAAW;AAC7B,WAAO,OAAO,IAAI;AAAA,EACpB;AAGA,MAAI,OAAO,SAAS,UAAU;AAE5B,UAAM,aAAa,QAAQ,KAAK,oBAAoB,KAAK,wBAAwB;AACjF,QAAI,WAAW;AACb,YAAM,aAAa,cAAc,IAAI;AACrC,UAAI,YAAY;AAEd,eAAO,IAAI,UAAU;AAAA,MACvB;AAAA,IACF;AAEA,UAAM,QAAkB,CAAA;AAExB,QAAI,OAAO,KAAK,UAAW,OAAM,KAAK,WAAW;AACjD,QAAI,OAAO,KAAK,KAAM,OAAM,KAAK,MAAM;AACvC,QAAI,OAAO,KAAK,OAAQ,OAAM,KAAK,QAAQ;AAC3C,QAAI,OAAO,KAAK,OAAQ,OAAM,KAAK,QAAQ;AAC3C,QAAI,OAAO,KAAK,QAAS,OAAM,KAAK,SAAS;AAC7C,QAAI,OAAO,KAAK,OAAQ,OAAM,KAAK,QAAQ;AAC3C,QAAI,OAAO,KAAK,MAAO,OAAM,KAAK,OAAO;AAEzC,QAAI,MAAM,WAAW,GAAG;AACtB,aAAO;AAAA,IACT;AAEA,WAAO,MAAM,WAAW,IAAI,MAAM,CAAC,IAAI,MAAM,KAAK,KAAK;AAAA,EACzD;AAGA,MAAI,OAAO,KAAK;AAEhB,MAAI,OAAO,KAAK,OAAO;AACrB,UAAM,YAAY;AAClB,UAAM,QAAkB,CAAA;AAGxB,QAAI,UAAU,WAAW,UAAa,UAAU,OAAO,OAAO,GAAG;AAC/D,iBAAW,OAAO,UAAU,QAAQ;AAClC,cAAM,SAAS,OAAO,QAAQ,WAAW,IAAI,GAAG,MAAM,OAAO,GAAG;AAChE,cAAM,KAAK,MAAM;AAAA,MACnB;AAAA,IACF;AAGA,QAAI,UAAU,UAAU,QAAW;AACjC,UAAI,UAAU,MAAM,SAAS,MAAM,QAAW;AAC5C,cAAM,KAAK,SAAS,aAAa,UAAU,MAAM,SAAS,CAAuB,CAAC,GAAG;AAAA,MACvF;AAEA,UAAI,UAAU,MAAM,UAAU,MAAM,QAAW;AAC7C,cAAM,KAAK,kBAAkB,aAAa,UAAU,MAAM,UAAU,CAAuB,CAAC,GAAG;AAAA,MACjG;AAGA,iBAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,UAAU,KAAK,GAAG;AAC1D,YAAI,QAAS,aAAqB,QAAS,YAAoB;AAE7D,gBAAM,KAAK,GAAG;AAAA,QAChB;AAAA,MACF;AAAA,IACF;AAEA,WAAO,UAAU;AAGjB,UAAM,aAAa,QAAQ,KAAK,oBAAoB,KAAK,wBAAwB;AACjF,QAAI,WAAW;AACb,YAAM,aAAa,cAAc,IAAI;AACrC,UAAI,YAAY;AACd,cAAM,KAAK,IAAI,UAAU,GAAG;AAAA,MAC9B;AAAA,IACF;AAGA,QAAI,OAAO,KAAK,UAAW,OAAM,KAAK,WAAW;AACjD,QAAI,OAAO,KAAK,KAAM,OAAM,KAAK,MAAM;AACvC,QAAI,OAAO,KAAK,OAAQ,OAAM,KAAK,QAAQ;AAC3C,QAAI,OAAO,KAAK,OAAQ,OAAM,KAAK,QAAQ;AAC3C,QAAI,OAAO,KAAK,QAAS,OAAM,KAAK,SAAS;AAE7C,QAAI,MAAM,WAAW,GAAG;AACtB,aAAO;AAAA,IACT;AAEA,WAAO,MAAM,KAAK,KAAK;AAAA,EACzB;AAEA,MAAI,OAAO,KAAK,QAAQ;AACtB,WAAO,UAAW,KAAmB,aAAa;AAAA,EACpD;AAEA,MAAI,OAAO,KAAK,OAAO;AACrB,UAAM,QAAS,KAAkB;AACjC,WAAO,SAAS,aAAa,KAAK,CAAC;AAAA,EACrC;AAEA,MAAI,OAAO,KAAK,QAAQ;AACtB,UAAM,QAAS,KAAmB;AAClC,WAAO,kBAAkB,aAAa,KAAK,CAAC;AAAA,EAC9C;AAEA,MAAI,OAAO,KAAK,QAAQ;AACtB,UAAM,WAAY,KAAmB;AACrC,WAAO,WAAW,UAAU,QAAQ,MAAM;AAAA,EAC5C;AAEA,SAAO;AACT;AAEO,SAAS,UAAU,MAAc,cAAkC,OAAuB;AAC/F,SAAO,IAAI;AAAA,IACT,uBAAuB,IAAI,cAAc,aAAa,YAAY,CAAC,SACjE,OAAO,UAAU,WAAY,UAAU,OAAO,SAAS,MAAM,QAAQ,KAAK,IAAI,UAAU,WAAY,OAAO,KAC7G;AAAA,EAAA;AAEJ;ACrJA,MAAMD,YAAU,MAAM;AAEf,SAAS,WAAW,OAAsB;AAC/C,MAAI,UAAU,KAAM,QAAO,KAAK;AAEhC,UAAQ,OAAO,OAAA;AAAA,IACb,KAAK;AACH,aAAO,KAAK;AAAA,IACd,KAAK;AACH,aAAO,KAAK;AAAA,IACd,KAAK;AACH,aAAO,KAAK;AAAA,IACd,KAAK;AACH,aAAO,KAAK;AAAA,IACd,KAAK;AACH,aAAOA,UAAQ,KAAK,IAAI,KAAK,QAAQ,KAAK;AAAA,IAC5C;AACE,YAAM,IAAI,MAAM,iBAAiB,OAAO,KAAK,EAAE;AAAA,EAAA;AAErD;AAiDO,SAAS,MAASE,SAAqB;AAC5C,SAAOC,YAAUD,OAAM;AACzB;AAMA,SAASC,YAAa,OAAa;AAEjC,MAAI,UAAU,QAAQ,OAAO,UAAU,UAAU;AAC/C,WAAO;AAAA,EACT;AAGA,MAAIH,UAAQ,KAAK,GAAG;AAClB,WAAO,MAAM,IAAI,CAAA,SAAQG,YAAU,IAAI,CAAC;AAAA,EAC1C;AAGA,MAAI,iBAAiB,MAAM;AACzB,WAAO,IAAI,KAAK,MAAM,SAAS;AAAA,EACjC;AAGA,MAAI,iBAAiB,KAAK;AACxB,UAAM,gCAAgB,IAAA;AACtB,eAAW,CAAC,GAAG,CAAC,KAAK,OAAO;AAC1B,gBAAU,IAAIA,YAAU,CAAC,GAAGA,YAAU,CAAC,CAAC;AAAA,IAC1C;AACA,WAAO;AAAA,EACT;AAGA,MAAI,iBAAiB,KAAK;AACxB,UAAM,gCAAgB,IAAA;AACtB,eAAW,KAAK,OAAO;AACrB,gBAAU,IAAIA,YAAU,CAAC,CAAC;AAAA,IAC5B;AACA,WAAO;AAAA,EACT;AAIA,QAAM,SAAkC,CAAA;AAGxC,aAAW,OAAO,OAAO,KAAK,KAAe,GAAG;AAC9C,WAAO,GAAG,IAAIA,YAAW,MAAkC,GAAG,CAAC;AAAA,EACjE;AAEA,SAAO;AACT;ACvGA,MAAM,WAAmB,MAAM;AAAC;AAEhC,MAAMJ,YAAU,OAAO;AACvB,MAAM,UAAU,MAAM;AAEtB,MAAM,+BAAe,QAAA;AAId,MAAM,OAAO;AAAC;AAErB,SAAS,gBACP,WACA,OACA,UACA,MACA,OAAe,UACN;AACT,MAAI,cAAc,KAAK,OAAO;AAC5B,UAAM,QAAQ,SAAS,MAAO,SAAS;AAEvC,QAAI,UAAU,UAAa,OAAO,UAAU,UAAU;AACpD,aAAO;AAAA,IACT;AAEA,WAAO,gBAAgB,OAAoB,OAAO,MAAM,IAAI;AAAA,EAC9D,OAAO;AAEL,UAAM,gBAAgB,SAAS;AAC/B,UAAM,WAAW,gBAAiB,MAAkC,aAAa,IAAI;AAErF,QAAI,aAAa,UAAa,OAAO,aAAa,UAAU;AAC1D,YAAM,cAAc,SAAS,MAAO,UAAU;AAE9C,UAAI,gBAAgB,UAAa,OAAO,gBAAgB,UAAU;AAEhE,cAAM,IAAI;AAAA,UACR,mBAAmB,aAAa;AAAA,QAAA;AAAA,MAEpC;AAEA,aAAO,iBAAiB,OAAkC,aAA+B,MAAM,IAAI;AAAA,IACrG;AAEA,UAAM,cAAc,SAAS,MAAO,QAAQ;AAE5C,QAAI,gBAAgB,UAAa,OAAO,gBAAgB,UAAU;AAChE,YAAM,IAAI,MAAM,qBAAqB,QAAQ,YAAY;AAAA,IAC3D;AAEA,WAAO,iBAAiB,OAAkC,aAAsC,MAAM,IAAI;AAAA,EAC5G;AACF;AAEO,SAAS,gBAAgB,OAAkB,YAAqB,MAAc,OAAe,UAAU;AAC5G,QAAM,SAAoB,CAAA;AAE1B,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,QAAI;AACF,aAAO,KAAK,WAAW,MAAM,CAAC,GAAG,YAAY,GAAG,IAAI,IAAI,CAAC,KAAK,OAAO,IAAI,CAAC;AAAA,IAC5E,SAAS,GAAG;AACV,WAAK,6CAA6C;AAAA,QAChD,OAAO;AAAA,QACP,OAAO,MAAM,CAAC;AAAA,QACd,OAAO,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC;AAAA,MAAA,CACjD;AAAA,IACH;AAAA,EACF;AAEA,SAAO;AACT;AAEO,SAAS,iBACd,QACA,aACA,MACA,OAAe,UACf;AACA,aAAW,CAAC,KAAK,KAAK,KAAKA,UAAQ,MAAM,GAAG;AAC1C,WAAO,GAAG,IAAI,WAAW,OAAO,aAAa,GAAG,IAAI,KAAK,GAAG,MAAM,OAAO,IAAI;AAAA,EAC/E;AAEA,SAAO;AACT;AAEO,SAAS,iBACd,QACA,aACA,MACA,OAAe,UACf;AACA,MAAI,SAAS,IAAI,MAAM,GAAG;AAExB,WAAO;AAAA,EACT;AAEA,QAAM,QAAQ,YAAY;AAE1B,aAAW,CAAC,KAAK,SAAS,KAAKA,UAAQ,KAAK,GAAG;AAE7C,WAAO,GAAG,IAAI,WAAW,OAAO,GAAG,GAAG,WAAW,GAAG,IAAI,IAAI,GAAG,IAAI,OAAO,IAAI;AAAA,EAChF;AAEA,SAAO;AACT;AAEO,SAAS,WACd,OACA,SACA,MACA,gBAAgB,OAChB,OAAe,UACN;AAET,MAAI,mBAAmB,oBAAoB;AACzC,UAAM,YAAY,QAAQ,IAAI,KAAK;AACnC,QAAI,cAAc,QAAW;AAC3B,YAAM,UAAU,MAAM,SAAgB,KAAK;AAAA,IAC7C;AACA,WAAO;AAAA,EACT;AAGA,MAAI,mBAAmB,KAAK;AAC1B,QAAI,CAAC,QAAQ,IAAI,KAAkC,GAAG;AACpD,YAAM,UAAU,MAAM,SAAgB,KAAK;AAAA,IAC7C;AACA,WAAO;AAAA,EACT;AAEA,UAAQ,OAAO,SAAA;AAAA,IACb,KAAK;AAEH,UAAI,UAAU,UAAa,UAAU,MAAM;AACzC,eAAO;AAAA,MACT;AACA,UAAI,UAAU,SAAS;AACrB,cAAM,UAAU,MAAM,SAAS,KAAK;AAAA,MACtC;AAEA,aAAO;AAAA;AAAA,IAGT,KAAK,UAAU;AACb,UAAI,YAAY,WAAW,KAAK;AAEhC,WAAK,UAAU,eAAe,GAAG;AAC/B,YAAI,CAAC,kBAAkB,UAAU,KAAK,eAAe,GAAG;AACtD,eAAK,4DAA4D,EAAE,OAAO,KAAA,CAAM;AAChF,iBAAO;AAAA,QACT;AACA,cAAM,UAAU,MAAM,SAAS,KAAK;AAAA,MACtC;AAGA,WAAK,WAAW,KAAK,oBAAoB,KAAK,wBAAwB,GAAG;AAEvE,YAAI;AACF,iBAAO,UAAU,OAAO,EAAE,KAAK;AAAA,QACjC,SAAS,GAAG;AACV,cAAI,CAAC,kBAAkB,UAAU,KAAK,eAAe,GAAG;AACtD,iBAAK,sEAAsE;AAAA,cACzE;AAAA,cACA;AAAA,cACA,OAAO,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC;AAAA,YAAA,CACjD;AACD,mBAAO;AAAA,UACT;AACA,gBAAM;AAAA,QACR;AAAA,MACF;AAEA,aAAO;AAAA,IACT;AAAA;AAAA,IAGA,SAAS;AAIP,UAAI,YAAY,WAAW,KAAK;AAChC,YAAM,WAAW,QAAQ;AAIzB,WAAK,WAAW,KAAK,kBAAkB,GAAG;AACxC,YAAI;AACF,gBAAM,cAAc,WAAW,OAAO,QAAQ,OAA6B,MAAM,MAAM,IAAI;AAC3F,iBAAO,EAAE,SAAS,MAAe,OAAO,YAAA;AAAA,QAC1C,SAAS,GAAG;AACV,iBAAO,EAAE,SAAS,OAAgB,OAAO,aAAa,QAAQ,IAAI,IAAI,MAAM,OAAO,CAAC,CAAC,EAAA;AAAA,QACvF;AAAA,MACF;AAIA,WAAK,WAAW,eAAe,KAAK,CAAC,QAAQ,QAAQ,IAAI,KAAkC,GAAG;AAC5F,YAAI,CAAC,kBAAkB,WAAW,KAAK,eAAe,GAAG;AACvD,eAAK,4DAA4D,EAAE,OAAO,KAAA,CAAM;AAChF,iBAAO;AAAA,QACT;AACA,cAAM,UAAU,MAAM,UAAU,KAAK;AAAA,MACvC;AAEA,UAAI,YAAY,KAAK,QAAQ;AAE3B,aAAK,YAAY,KAAK,oBAAoB,KAAK,wBAAwB,GAAG;AACxE,cAAI;AACF,mBAAO,UAAU,QAAQ,EAAE,KAAK;AAAA,UAClC,SAAS,GAAG;AACV,gBAAI,CAAC,kBAAkB,WAAW,KAAK,eAAe,GAAG;AACvD,mBAAK,sEAAsE;AAAA,gBACzE;AAAA,gBACA;AAAA,gBACA,OAAO,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC;AAAA,cAAA,CACjD;AACD,qBAAO;AAAA,YACT;AACA,kBAAM;AAAA,UACR;AAAA,QACF;AAGA,eAAO;AAAA,MACT;AAEA,WAAK,WAAW,KAAK,WAAW,GAAG;AACjC,eAAO;AAAA,UACL;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QAAA;AAAA,MAEJ;AAEA,UAAI,cAAc,KAAK,OAAO;AAC5B,eAAO,gBAAgB,OAAoB,QAAQ,OAAyB,MAAM,IAAI;AAAA,MACxF;AAEA,WAAK,WAAW,KAAK,YAAY,GAAG;AAClC,eAAO,iBAAiB,OAAmC,QAAsB,OAAO,MAAM,IAAI;AAAA,MACpG;AAEA,aAAO,iBAAiB,OAAkC,SAAkC,MAAM,IAAI;AAAA,IACxG;AAAA,EAAA;AAEJ;AAOO,SAAS,YACd,QACA,QACG;AAEH,aAAW,CAAC,KAAK,KAAK,KAAKA,UAAQ,MAAM,GAAG;AAC1C,UAAM,cAAc,OAAO,GAAG;AAE9B,QACE,OAAO,UAAU,YACjB,UAAU,QACV,CAAC,QAAQ,KAAK,KACd,CAAC,SAAS,IAAI,KAAK,KACnB,OAAO,gBAAgB,YACvB,gBAAgB,QAChB,CAAC,QAAQ,WAAW,KACpB,CAAC,SAAS,IAAI,WAAW,GACzB;AACA,kBAAY,aAAwC,KAAgC;AAAA,IACtF,OAAO;AACL,aAAO,GAAG,IAAI;AAAA,IAChB;AAAA,EACF;AAEA,SAAO;AACT;AAEA,MAAM,oBAAoB,OAAO,IAAI,4BAA4B;AAE1D,SAAS,kBACd,IACA,cACA,KACA,aACA,YACA,OAAe,UACf,MACyB;AAEzB,QAAM,QAAQ,IAAI;AAGlB,QAAM,UAAW,IAA8B;AAG/C,QAAM,qCAAqB,IAAA;AAE3B,QAAM,SAAS,OAAO;AAAA,IACpB,aAAa;AAAA,EAAA;AAIf,MAAI;AAEJ,QAAM,UAAgC;AAAA,IACpC,iBAAiB;AACf,aAAO,OAAO;AAAA,IAChB;AAAA,IAEA,IAAI,QAAQ,MAAM;AAEhB,UAAI,SAAS,UAAU;AACrB,eAAO;AAAA,MACT;AAEA,YAAM,EAAE,MAAM,OAAO,SAAA,IAAa;AAKlC,mBAAa;AAEb,eAAS,QAAA;AAGT,UAAI,MAAM,IAAI,IAAI,GAAG;AACnB,eAAO,MAAM,IAAI,IAAI;AAAA,MACvB;AAGA,UAAI,WAAW,OAAO,SAAS,YAAY,QAAQ,SAAS;AAC1D,YAAI,UAAU,eAAe,IAAI,IAAI;AACrC,YAAI,CAAC,SAAS;AAGZ,oBAAUK,UAAAA,eAAe,OAAO,QAAQ,IAAI,EAAE,KAAK,KAAK,CAAC;AACzD,yBAAe,IAAI,MAAM,OAAO;AAAA,QAClC;AACA,eAAO;AAAA,MACT;AAEA,YAAM,QAAQ,KAAK,IAAc;AACjC,YAAM,UAAU,MAAM,IAAc;AAEpC,UAAI,CAAC,OAAO,eAAe,KAAK,OAAO,IAAI,GAAG;AAC5C,eAAO;AAAA,MACT;AAEA,YAAM,SAAS,WAAW,OAAO,SAAS,KAAK,IAAI,MAAM,IAAc,IAAI,OAAO,IAAI;AAEtF,YAAM,IAAI,MAAM,MAAM;AAEtB,aAAO;AAAA,IACT;AAAA,IAEA,IAAI,QAAQ,MAAM;AAEhB,UAAI,WAAW,OAAO,SAAS,YAAY,QAAQ,SAAS;AAC1D,eAAO;AAAA,MACT;AACA,aAAO,QAAQ;AAAA,IACjB;AAAA,IAEA,QAAQ,QAAQ;AACd,YAAM,OAAO,OAAO,KAAK,KAAK;AAE9B,YAAM,gBAAiB,IAA8B;AACrD,UAAI,iBAAiB,CAAC,KAAK,SAAS,aAAa,GAAG;AAClD,aAAK,KAAK,aAAa;AAAA,MACzB;AAEA,UAAI,SAAS;AACX,mBAAW,aAAa,OAAO,KAAK,OAAO,GAAG;AAC5C,cAAI,CAAC,KAAK,SAAS,SAAS,GAAG;AAC7B,iBAAK,KAAK,SAAS;AAAA,UACrB;AAAA,QACF;AAAA,MACF;AACA,aAAO;AAAA,IACT;AAAA,IAEA,yBAAyB,QAAQ,MAAM;AACrC,YAAM,gBAAiB,IAA8B;AACrD,UAAI,QAAQ,SAAS,SAAS,eAAe;AAC3C,eAAO;AAAA,UACL,YAAY;AAAA,UACZ,cAAc;AAAA,QAAA;AAAA,MAElB;AAEA,UAAI,WAAW,OAAO,SAAS,YAAY,QAAQ,SAAS;AAC1D,eAAO;AAAA,UACL,YAAY;AAAA,UACZ,cAAc;AAAA,QAAA;AAAA,MAElB;AACA,aAAO;AAAA,IACT;AAAA,EAAA;AAGF,UAAQ,IAAI;AAAA,IACV;AAAA,MACE,CAAC,iBAAiB,GAAG,MAAM;AACzB,eAAO,OAAO,KAAK,KAAK,EAAE;AAAA,UACxB,CAAC,KAAK,QAAQ;AACZ,gBAAI,GAAG,IAAI,MAAM,GAAG;AACpB,mBAAO;AAAA,UACT;AAAA,UACA,CAAA;AAAA,QAAC;AAAA,MAEL;AAAA,IAAA;AAAA,IAEF;AAAA,EAAA;AAIF,WAAS,IAAI,OAAO,EAAE;AAGtBC,YAAAA,cAAc,OAAO,UAAU;AAE/B,SAAO;AACT;AAEO,SAAS,WAAW,QAAqD;AAC9E,SAAO,SAAS,IAAI,MAAM;AAC5B;ACvbA,SAAS,UAAa,OAAa;AACjC,MAAI,UAAU,QAAQ,OAAO,UAAU,UAAU;AAC/C,WAAO;AAAA,EACT;AAEA,MAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,WAAO,MAAM,IAAI,CAAA,SAAQ,UAAU,IAAI,CAAC;AAAA,EAC1C;AAEA,MAAI,iBAAiB,MAAM;AACzB,WAAO,IAAI,KAAK,MAAM,SAAS;AAAA,EACjC;AAGA,QAAM,SAAS,CAAA;AACf,aAAW,OAAO,OAAO,KAAK,KAAK,GAAG;AACpC,WAAO,GAAG,IAAI,UAAW,MAAkC,GAAG,CAAC;AAAA,EACjE;AACA,SAAO;AACT;AAsBO,MAAM,YAAY;AAAA,EACf,0BAAU,IAAA;AAAA,EACV;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,+CAA+B,IAAA;AAAA,EAEvC,YAAY,aAA0B;AACpC,SAAK,cAAc;AAAA,EACrB;AAAA,EAEA,UAAU,KAAsB;AAC9B,WAAO,KAAK,IAAI,IAAI,GAAG;AAAA,EACzB;AAAA,EAEA,UAAU,KAA+D;AACvE,WAAO,KAAK,IAAI,IAAI,GAAG;AAAA,EACzB;AAAA,EAEA,sBAAsB,KAAa,QAAkC;AACnE,UAAM,SAAS,KAAK,UAAU,GAAG;AAEjC,QAAI,WAAW,QAAW;AACxB,YAAM,IAAI,MAAM,UAAU,GAAG,+CAA+C;AAAA,IAC9E;AAEA,WAAO,IAAI,GAAG;AAId,WAAO,SAAS,QAAA;AAEhB,QAAI,OAAO,eAAe,QAAW;AACnC,iBAAW,OAAO,OAAO,YAAY;AACnC,aAAK,sBAAsB,KAAK,MAAM;AAAA,MACxC;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,uBAAuB,KAAa,OAAgC;AAClE,UAAM,SAAS,KAAK,UAAU,GAAG;AACjC,QAAI,WAAW,QAAW;AACxB,YAAM,IAAI,MAAM,UAAU,GAAG,YAAY;AAAA,IAC3C;AAEA,WAAO,QAAQ,KAAK,kBAAkB,QAAQ,KAAK;AAEnD,WAAO;AAAA,EACT;AAAA,EAEA,mBAAmB,KAAa,MAAsD;AACpF,UAAM,SAAgC;AAAA,MACpC;AAAA,MACA;AAAA,MACA,UAAUC,UAAAA,SAAA;AAAA,MACV,2BAAW,IAAA;AAAA,MACX,IAAI;AAAA,MACJ,OAAO;AAAA,MACP,YAAY;AAAA,IAAA;AAGd,SAAK,IAAI,IAAI,KAAK,MAAM;AAExB,WAAO;AAAA,EACT;AAAA,EAEA,UAAU,KAAa,KAA8B,OAAkB,YAAwC;AAC7G,QAAI,SAAS,KAAK,IAAI,IAAI,GAAG;AAE7B,QAAI,WAAW,QAAW;AACxB,eAAS,KAAK,mBAAmB,KAAK,GAAG;AAEzC,aAAO,QAAQ,KAAK,kBAAkB,QAAQ,KAAK;AAAA,IACrD,OAAO;AACL,aAAO,OAAO,YAAY,OAAO,MAAM,GAAG;AAC1C,aAAO,SAAS,OAAA;AAChB,aAAO,MAAM,MAAA;AAAA,IACf;AAEA,WAAO,aAAa;AAEpB,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,yBAAyB,WAAmB,QAAuC;AAEjF,QAAI,KAAK,yBAAyB,IAAI,SAAS,GAAG;AAChD,YAAM,IAAI;AAAA,QACR,0CAA0C,SAAS;AAAA,MAAA;AAAA,IAEvD;AAEA,UAAM,SAAS,KAAK,IAAI,IAAI,SAAS;AACrC,QAAI,CAAC,QAAQ;AAEX,WAAK,yBAAyB,IAAI,WAAW,EAAE,UAAU,CAAA,GAAI;AAC7D;AAAA,IACF;AAGA,UAAM,WAAW,UAAU,OAAO,IAAI;AAGtC,SAAK,yBAAyB,IAAI,WAAW,EAAE,UAAU;AAGzD,WAAO,OAAO,YAAY,OAAO,MAAM,MAAM;AAC7C,WAAO,MAAM,MAAA;AAGb,mBAAe,MAAM;AACnB,aAAO,SAAS,OAAA;AAAA,IAClB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,uBAAuB,WAAyB;AAC9C,UAAM,UAAU,KAAK,yBAAyB,IAAI,SAAS;AAC3D,QAAI,CAAC,SAAS;AACZ;AAAA,IACF;AAEA,UAAM,SAAS,KAAK,IAAI,IAAI,SAAS;AACrC,QAAI,UAAU,OAAO,KAAK,QAAQ,QAAQ,EAAE,SAAS,GAAG;AAEtD,aAAO,OAAO,QAAQ;AACtB,aAAO,MAAM,MAAA;AAGb,qBAAe,MAAM;AACnB,eAAO,SAAS,OAAA;AAAA,MAClB,CAAC;AAAA,IACH;AAGA,SAAK,yBAAyB,OAAO,SAAS;AAAA,EAChD;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,uBAAuB,WAAyB;AAC9C,SAAK,yBAAyB,OAAO,SAAS;AAAA,EAChD;AAAA,EAEQ,kBAAkB,QAA+B,OAA2C;AAClG,UAAM,UAAU,MAAM;AACtB,QAAI,YAAY,QAAW;AACzB,YAAM,IAAI,MAAM,+BAA+B,MAAM,aAAa,EAAE;AAAA,IACtE;AAEA,UAAM,KAAK,OAAO,KAAK,OAAO;AAE9B,QAAI,OAAO,OAAO,YAAY,OAAO,OAAO,UAAU;AACpD,cAAQ,IAAI,OAAO,IAAI;AACvB,YAAM,IAAI,MAAM,uCAAuC,MAAM,aAAa,EAAE;AAAA,IAC9E;AAEA,WAAO,KAAK;AAEZ,QAAI;AACJ,UAAM,eAAgB,MAA2C;AAEjE,QAAI,cAAc,QAAQ;AACxB,oBAAcC,UAAAA,MAAM,CAAA,UAAS;AAC3B,cAAM,UAAU,KAAK,YAAY,WAAA;AACjC,cAAM,WAAW,CAAC,WAA6C;AAC7D,gBAAM,eAAe,OAAO;AAC5B,gBAAM,SAAS,YAAY,cAAc,MAAM;AAC/C,iBAAO,OAAO;AACd,iBAAO,SAAS,OAAA;AAChB,iBAAO,MAAM,MAAA;AAAA,QACf;AAEA,cAAM,cAAc,aAAa,OAAO,UAAU,SAAS,IAAuB,QAAe;AAIjG,cAAM,QAAQ,OAAO;AAErB,eAAO;AAAA,MACT,CAAC;AAAA,IACH;AAEA,UAAM,OAAO,KAAK,YAAY,WAAA,EAAa,KAAK;AAChD,WAAO,kBAAkB,OAAO,KAAK,QAAQ,OAAO,aAAa,KAAK,aAAa,IAAI;AAAA,EACzF;AACF;ACrPO,MAAM,eAAe;AAAA,EAClB;AAAA,EACA,iBAAsC;AAAA,EACtC,yBAAyB;AAAA,EAEjC,YAAY,eAAyB;AAEnC,UAAM,sBAAsB,iBAAiB,KAAK,mBAAA;AAClD,SAAK,eAAeC,UAAAA,OAAO,mBAAmB;AAG9C,QAAI,KAAK,sBAAsB;AAC7B,WAAK,qBAAA;AAAA,IACP;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,WAAoB;AAEtB,QAAI,KAAK,mBAAmB,QAAW;AACrC,aAAO,KAAK;AAAA,IACd;AAEA,WAAO,KAAK,aAAa;AAAA,EAC3B;AAAA;AAAA;AAAA;AAAA,EAKA,iBAAiB,QAAuB;AACtC,SAAK,iBAAiB;AACtB,SAAK,aAAa,QAAQ;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA,EAKA,sBAA4B;AAC1B,SAAK,iBAAiB;AACtB,SAAK,aAAa,QAAQ,KAAK,mBAAA;AAAA,EACjC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,kBAAmC;AACjC,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKQ,qBAA8B;AAEpC,QAAI,OAAO,cAAc,eAAe,YAAY,WAAW;AAC7D,aAAO,UAAU;AAAA,IACnB;AAGA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKQ,qBAA8B;AACpC,WAAO,OAAO,WAAW,eAAe,OAAO,OAAO,qBAAqB;AAAA,EAC7E;AAAA;AAAA;AAAA;AAAA,EAKQ,uBAA6B;AACnC,QAAI,KAAK,wBAAwB;AAC/B;AAAA,IACF;AAEA,UAAM,eAAe,MAAM;AACzB,UAAI,KAAK,mBAAmB,QAAW;AACrC,aAAK,aAAa,QAAQ;AAAA,MAC5B;AAAA,IACF;AAEA,UAAM,gBAAgB,MAAM;AAC1B,UAAI,KAAK,mBAAmB,QAAW;AACrC,aAAK,aAAa,QAAQ;AAAA,MAC5B;AAAA,IACF;AAEA,WAAO,iBAAiB,UAAU,YAAY;AAC9C,WAAO,iBAAiB,WAAW,aAAa;AAEhD,SAAK,yBAAyB;AAAA,EAKhC;AACF;AAGO,MAAM,mBAAmB;AAAA,EAC9B,OAAwB,eAAgCA,UAAAA,OAAO,IAAI;AAAA,EAEnE,IAAI,WAAoB;AACtB,WAAO;AAAA,EACT;AAAA,EAEA,iBAAiB,SAAwB;AAAA,EAEzC;AAAA,EAEA,sBAA4B;AAAA,EAE5B;AAAA,EAEA,kBAAmC;AACjC,WAAO,mBAAmB;AAAA,EAC5B;AAAA,EAEA,UAAgB;AAAA,EAEhB;AACF;AAGO,MAAM,wBAAwB,IAAI,eAAA;AAGlC,MAAM,wBAAiDC,UAAAA,QAAwB,qBAAqB;AC1H3G,MAAM,UAAU,OAAO;AAEhB,SAAS,mBACd,WACA,OACA,UACA,aACA,YACS;AACT,MAAI,cAAc,KAAK,OAAO;AAC5B,UAAM,QAAQ,SAAS,MAAO,SAAS;AAEvC,QAAI,UAAU,UAAa,OAAO,UAAU,UAAU;AACpD,aAAO;AAAA,IACT;AAEA,WAAO;AAAA,MACL;AAAA,MACA,EAAE,MAAM,KAAK,OAAO,OAAO,QAAQ,OAAA;AAAA,MACnC;AAAA,MACA;AAAA,IAAA;AAAA,EAEJ,OAAO;AAEL,UAAM,gBAAgB,SAAS;AAC/B,UAAM,WAAW,gBAAiB,MAAkC,aAAa,IAAI;AAErF,QAAI,aAAa,UAAa,OAAO,aAAa,UAAU;AAC1D,YAAM,cAAc,SAAS,MAAO,UAAU;AAE9C,UAAI,gBAAgB,UAAa,OAAO,gBAAgB,UAAU;AAEhE,cAAM,IAAI;AAAA,UACR,mBAAmB,aAAa;AAAA,QAAA;AAAA,MAEpC;AAEA,aAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MAAA;AAAA,IAEJ;AAEA,UAAM,cAAc,SAAS,MAAO,QAAQ;AAE5C,QAAI,gBAAgB,UAAa,OAAO,gBAAgB,UAAU;AAChE,YAAM,IAAI,MAAM,qBAAqB,QAAQ,YAAY;AAAA,IAC3D;AAEA,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAAA,EAEJ;AACF;AAEO,SAAS,mBACd,OACA,YACA,aACA,YACW;AACX,QAAM,SAAoB,CAAA;AAE1B,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,QAAI;AACF,aAAO,KAAK,cAAc,MAAM,CAAC,GAAG,YAAY,aAAa,UAAU,CAAC;AAAA,IAC1E,SAAS,GAAG;AACV,kBAAY,WAAA,EAAa,KAAK,OAAO,6CAA6C;AAAA,QAChF,OAAO;AAAA,QACP,OAAO,MAAM,CAAC;AAAA,QACd,OAAO,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC;AAAA,MAAA,CACjD;AAAA,IACH;AAAA,EACF;AAEA,SAAO;AACT;AAEO,SAAS,oBACd,QACA,aACA,aACA,YACyB;AACzB,MAAI,OAAO,gBAAgB,UAAU;AACnC,WAAO;AAAA,EACT;AAEA,aAAW,CAAC,KAAK,KAAK,KAAK,QAAQ,MAAM,GAAG;AAC1C,WAAO,GAAG,IAAI,cAAc,OAAO,aAAa,aAAa,UAAU;AAAA,EACzE;AAEA,SAAO;AACT;AAEO,SAAS,oBACd,KACA,aACA,aACA,YACyB;AACzB,QAAM,cAAc,IAAI;AAGxB,MAAI,OAAO,gBAAgB,UAAU;AACnC,WAAO,YAAY,cAAc,aAAa,WAAwB,EAAE;AAAA,EAC1E;AAGA,QAAM,EAAE,SAAS;AAEjB,QAAM,YAAY,OAAO,KAAK,SAAS,oBAAI,QAAgB;AAG3D,QAAM,QAAQ,YAAY;AAC1B,QAAM,iBAAiB,YAAY;AAEnC,MAAI,mBAAmB,QAAW;AAChC,QAAI,OAAO,mBAAmB,UAAU;AAEtC,YAAM,UAAU,MAAM,cAAc;AACpC,UAAI,cAAc,IAAI,cAAc,IAAI,cAAc,GAAG,SAA2B,aAAa,SAAS;AAAA,IAC5G,OAAO;AAEL,iBAAW,QAAQ,gBAAgB;AACjC,cAAM,UAAU,MAAM,IAAI;AAC1B,YAAI,IAAI,IAAI,cAAc,IAAI,IAAI,GAAG,SAA2B,aAAa,SAAS;AAAA,MACxF;AAAA,IACF;AAAA,EACF;AAGA,MAAI,OAAO,KAAK,QAAQ;AACtB,UAAM,YAAY;AAClB,UAAM,WAAW,UAAU;AAC3B,UAAM,KAAK,IAAI,UAAU,OAAO;AAEhC,QAAI,OAAO,QAAW;AACpB,YAAM,IAAI,MAAM,0BAA0B,QAAQ,EAAE;AAAA,IACtD;AAEA,UAAM,OAAO,GAAG,QAAQ,IAAI,EAAE;AAC9B,UAAM,MAAMR,MAAAA,UAAU,IAAI;AAG1B,QAAI,eAAe,QAAW;AAC5B,iBAAW,IAAI,GAAG;AAAA,IACpB;AAEA,WAAO,YAAY,WAAW,KAAK,KAAK,WAAW,SAAS,EAAE;AAAA,EAChE;AAIA,QAAM,OAAO,YAAY,WAAA,EAAa,KAAK;AAC3C,aAAW,CAAC,KAAK,OAAO,KAAK,QAAQ,KAAK,GAAG;AAE3C,QAAI,mBAAmB,QAAW;AAChC,UAAI,OAAO,mBAAmB,WAAW,QAAQ,iBAAiB,eAAe,SAAS,GAAG,GAAG;AAC9F;AAAA,MACF;AAAA,IACF;AACA,QAAI,GAAG,IAAI;AAAA,MACT,IAAI,GAAG;AAAA,MACP;AAAA,MACA,GAAG,YAAY,iBAAiB,QAAQ,IAAI,GAAG;AAAA,MAC/C;AAAA,MACA;AAAA,IAAA;AAAA,EAEJ;AAEA,SAAO;AACT;AAEO,SAAS,cACd,OACA,KACA,aACA,YACS;AACT,QAAM,YAAY,WAAW,KAAK;AAClC,QAAM,UAAU,IAAI;AAGpB,OAAK,UAAU,KAAK,kBAAkB,GAAG;AACvC,QAAI;AACF,YAAM,cAAc;AAAA,QAClB;AAAA,QACC,IAAuB;AAAA,QACxB;AAAA,QACA;AAAA,MAAA;AAEF,aAAO,EAAE,SAAS,MAAe,OAAO,YAAA;AAAA,IAC1C,SAAS,GAAG;AACV,aAAO,EAAE,SAAS,OAAgB,OAAO,aAAa,QAAQ,IAAI,IAAI,MAAM,OAAO,CAAC,CAAC,EAAA;AAAA,IACvF;AAAA,EACF;AAIA,MAAI,YAAY,KAAK,WAAW,UAAU,eAAe,GAAG;AAC1D,WAAO;AAAA,EACT;AAIA,OAAK,UAAU,KAAK,WAAW,GAAG;AAChC,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAAA,EAEJ;AAIA,MAAI,cAAc,KAAK,OAAO;AAC5B,WAAO,mBAAmB,OAAqB,IAAiB,OAAyB,aAAa,UAAU;AAAA,EAClH;AAKA,OAAK,UAAU,KAAK,YAAY,GAAG;AACjC,WAAO;AAAA,MACL;AAAA,MACC,IAAkB;AAAA,MACnB;AAAA,MACA;AAAA,IAAA;AAAA,EAEJ;AAKA,SAAO,oBAAoB,OAAkC,KAA8B,aAAa,UAAU;AACpH;ACpOA,MAAM,iBAAiB;AAAA,EACb,yBAA+C;AAAA,EAC/C,iBAA2D;AAAA,EAE3D,6BAAmD;AAAA,EACnD,qBAA+D;AAAA,EAE/D;AAAA,EAER,YAAY,WAAuB;AACjC,SAAK,YAAY;AAAA,EACnB;AAAA,EAEA,IAAY,wBAAkC;AAC5C,WAAO,KAAK,2BAA2B,KAAK,yBAAyBK,UAAAA,SAAA;AAAA,EACvE;AAAA,EAEA,IAAY,4BAAsC;AAChD,WAAO,KAAK,+BAA+B,KAAK,6BAA6BA,UAAAA,SAAA;AAAA,EAC/E;AAAA,EAEA,IAAI,gBAA8C;AAChD,WAAO,KAAK,mBAAmB,KAAK,qCAAqB,IAAA;AAAA,EAC3D;AAAA,EAEA,IAAI,oBAAkD;AACpD,WAAO,KAAK,uBAAuB,KAAK,yCAAyB,IAAA;AAAA,EACnE;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,WAAyC;AACvC,SAAK,sBAAsB,QAAA;AAC3B,SAAK,0BAA0B,QAAA;AAC/B,WAAO;AAAA,MACL,eAAe,KAAK;AAAA,MACpB,mBAAmB,KAAK;AAAA,IAAA;AAAA,EAE5B;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,gBAAgBJ,SAA0C;AACxD,UAAM,UAAU,KAAK;AACrB,UAAM,aAAa,QAAQ;AAC3B,YAAQ,IAAIA,OAAM;AAElB,QAAI,QAAQ,SAAS,YAAY;AAC/B,WAAK,sBAAsB,OAAA;AAG3B,YAAM,UAAU,WAAWA,OAAM;AACjC,UAAI,YAAY,QAAW;AACzB,aAAK,2BAA2B,OAAO;AAAA,MACzC;AAEA,WAAK,UAAA;AACL,aAAO;AAAA,IACT;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,oBAAoBA,SAA0C;AAC5D,UAAM,UAAU,KAAK;AACrB,UAAM,aAAa,QAAQ;AAC3B,YAAQ,IAAIA,OAAM;AAElB,QAAI,QAAQ,SAAS,YAAY;AAC/B,WAAK,0BAA0B,OAAA;AAC/B,WAAK,UAAA;AACL,aAAO;AAAA,IACT;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,uBAAuBA,SAA0C;AAC/D,UAAM,UAAU,WAAWA,OAAM;AACjC,QAAI,YAAY,QAAW;AACzB,aAAO;AAAA,IACT;AAEA,WAAO,KAAK,2BAA2B,OAAO;AAAA,EAChD;AAAA;AAAA;AAAA;AAAA,EAKQ,2BAA2B,SAA0B;AAC3D,UAAM,UAAU,KAAK;AACrB,QAAI,YAAY,UAAa,QAAQ,SAAS,GAAG;AAC/C,aAAO;AAAA,IACT;AAEA,eAAW,YAAY,SAAS;AAC9B,UAAI,WAAW,QAAQ,MAAM,SAAS;AACpC,gBAAQ,OAAO,QAAQ;AACvB,aAAK,0BAA0B,OAAA;AAC/B,aAAK,UAAA;AACL,eAAO;AAAA,MACT;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,gBAAgB,SAA0B;AACxC,UAAM,UAAU,KAAK;AACrB,QAAI,YAAY,QAAW;AACzB,aAAO;AAAA,IACT;AAEA,eAAW,UAAU,SAAS;AAC5B,UAAI,WAAW,MAAM,MAAM,SAAS;AAClC,eAAO;AAAA,MACT;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,UAAU,WAA8B;AAEtC,UAAM,UAAU,KAAK;AACrB,QAAI,YAAY,UAAa,QAAQ,OAAO,GAAG;AAC7C,UAAI,iBAAiB;AAErB,iBAAW,UAAU,SAAS;AAC5B,cAAM,cAAc,WAAW,MAAM;AACrC,YAAI,gBAAgB,UAAa,UAAU,IAAI,WAAW,GAAG;AAC3D,kBAAQ,OAAO,MAAM;AACrB,2BAAiB;AAAA,QACnB;AAAA,MACF;AAEA,UAAI,gBAAgB;AAClB,aAAK,sBAAsB,OAAA;AAAA,MAC7B;AAAA,IACF;AAGA,UAAM,UAAU,KAAK;AACrB,QAAI,YAAY,UAAa,QAAQ,OAAO,GAAG;AAC7C,UAAI,iBAAiB;AAErB,iBAAW,UAAU,SAAS;AAC5B,cAAM,cAAc,WAAW,MAAM;AACrC,YAAI,gBAAgB,QAAW;AAE7B,cAAI,UAAU,IAAI,WAAW,GAAG;AAC9B,oBAAQ,OAAO,MAAM;AACrB,6BAAiB;AAAA,UACnB,WAES,YAAY,UAAa,QAAQ,IAAI,MAAM,GAAG;AACrD,oBAAQ,OAAO,MAAM;AACrB,6BAAiB;AAAA,UACnB;AAAA,QACF;AAAA,MACF;AAEA,UAAI,gBAAgB;AAClB,aAAK,0BAA0B,OAAA;AAAA,MACjC;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,QAAc;AACZ,QAAI,UAAU;AAEd,QAAI,KAAK,mBAAmB,UAAa,KAAK,eAAe,OAAO,GAAG;AACrE,WAAK,iBAAiB;AACtB,WAAK,sBAAsB,OAAA;AAC3B,gBAAU;AAAA,IACZ;AAEA,QAAI,KAAK,uBAAuB,UAAa,KAAK,mBAAmB,OAAO,GAAG;AAC7E,WAAK,qBAAqB;AAC1B,WAAK,0BAA0B,OAAA;AAC/B,gBAAU;AAAA,IACZ;AAEA,QAAI,SAAS;AACX,WAAK,UAAA;AAAA,IACP;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,cACE,aACA,aACA,aACA,wBACM;AACN,QAAI,YAAY,oBAAoB,YAAY,iBAAiB,SAAS,KAAK,aAAa;AAC1F,YAAM,UAAU,KAAK;AACrB,iBAAW,SAAS,YAAY,kBAAkB;AAChD,cAAM,eAAe,YAAY,cAAc,OAAO,WAAW;AACjE,gBAAQ,IAAI,aAAa,KAAK;AAAA,MAChC;AAAA,IACF;AAEA,QAAI,YAAY,wBAAwB,YAAY,qBAAqB,SAAS,KAAK,wBAAwB;AAC7G,YAAM,UAAU,KAAK;AACrB,iBAAW,SAAS,YAAY,sBAAsB;AACpD,cAAM,eAAe,YAAY,cAAc,OAAO,sBAAsB;AAC5E,gBAAQ,IAAI,aAAa,KAAK;AAAA,MAChC;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,oBAAkD;AAChD,UAAM,UAAU,KAAK;AACrB,UAAM,UAAU,KAAK;AAErB,SAAK,YAAY,UAAa,QAAQ,SAAS,OAAO,YAAY,UAAa,QAAQ,SAAS,IAAI;AAClG,aAAO;AAAA,IACT;AAEA,UAAM,QAA0B,CAAA;AAEhC,QAAI,YAAY,UAAa,QAAQ,OAAO,GAAG;AAC7C,YAAM,mBAAmB,CAAA;AACzB,iBAAW,UAAU,SAAS;AAC5B,cAAM,QAAQ,WAAW,MAAM;AAC/B,YAAI,UAAU,QAAW;AACvB,gBAAM,iBAAiB,KAAK,KAAK;AAAA,QACnC;AAAA,MACF;AAAA,IACF;AAEA,QAAI,YAAY,UAAa,QAAQ,OAAO,GAAG;AAC7C,YAAM,uBAAuB,CAAA;AAC7B,iBAAW,UAAU,SAAS;AAC5B,cAAM,QAAQ,WAAW,MAAM;AAC/B,YAAI,UAAU,QAAW;AACvB,gBAAM,qBAAqB,KAAK,KAAK;AAAA,QACvC;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,UAAmB;AACrB,WACG,KAAK,mBAAmB,UAAa,KAAK,eAAe,OAAO,KAChE,KAAK,uBAAuB,UAAa,KAAK,mBAAmB,OAAO;AAAA,EAE7E;AACF;AAWO,MAAM,gBAAmE;AAAA,EAC9E;AAAA,EACA;AAAA;AAAA,EACA,aAAqB;AAAA;AAAA,EAEb;AAAA,EACA,cAAuB;AAAA,EACvB,qBAAsCM,UAAAA,OAAO,KAAK;AAAA,EAClD,uBAAwCA,UAAAA,OAAO,KAAK;AAAA,EACpD,YAAgC;AAAA,EAChC,SAAkC;AAAA,EAClC,SAAkC;AAAA,EAElC,wBAAiE;AAAA,EAEjE,iBAAyC;AAAA,EACzC,mBAA2C;AAAA,EAC3C,cAA2B;AAAA,EAE3B;AAAA,EACA,cAA2C;AAAA,EAC3C,YAAqB;AAAA,EACrB,gBAAyC;AAAA,EACzC,gBAA2D;AAAA,EAEnE,IAAY,aAA8B;AACxC,UAAM,aAAa,KAAK;AAExB,QAAI,CAAC,YAAY;AACf,YAAM,IAAI,MAAM,6BAA6B;AAAA,IAC/C;AAEA,WAAO;AAAA,EACT;AAAA,EAEQ,SAAuC;AAAA,EAE/C,IAAY,YAA8B;AACxC,WAAO,KAAK,WAAW,KAAK,SAAS,IAAI,iBAAiB,MAAM,KAAK,iBAAA,CAAkB;AAAA,EACzF;AAAA,EAEQ,kBAAkD;AAAA,EAE1D,IAAY,iBAAqC;AAE/C,QAAI,KAAK,IAAI,SAAS,UAAU,eAAe;AAC7C,aAAO;AAAA,IACT;AAEA,QAAI,SAAS,KAAK;AAElB,UAAM,QAAQ,KAAK,WAAW;AAE9B,QAAI,WAAW,UAAa,UAAU,QAAW;AAC/C,UAAI,CAAC,MAAM,QAAQ,KAAK,GAAG;AACzB,cAAM,IAAI,MAAM,6CAA6C;AAAA,MAC/D;AAEA,YAAM,cAAc,KAAK;AACzB,YAAM,aAAa,YAAY,YAAY,oBAAoB,MAAM,MAAM,SAAS,CAAC,CAAC;AAEtF,UAAI,eAAe,QAAW;AAE5B,iBAAS;AAAA,MACX,OAAO;AAEL,YAAI,mBAAmB;AACvB,cAAM,eAAe,EAAE,GAAG,KAAK,cAAA;AAG/B,mBAAW,CAAC,KAAKE,MAAK,KAAK,OAAO,QAAQ,UAAU,GAAG;AACrD,cAAIA,WAAU,UAAaA,WAAU,MAAM;AACzC,yBAAa,GAAG,IAAIA;AACpB,+BAAmB;AAAA,UACrB;AAAA,QACF;AAEA,aAAK,kBAAkB,SAAS,mBAAmB,eAAe;AAAA,MACpE;AAAA,IACF;AAEA,WAAO,UAAU;AAAA,EACnB;AAAA,EAEA,YACE,KACA,aACA,UACA,QACA;AACAC,UAAAA,mBAAmB,IAAI;AACvB,SAAK,MAAM;AACX,SAAK,cAAc;AACnB,SAAK,WAAW;AAChB,SAAK,SAAS;AAGd,SAAK,QAAQJ,gBAAS,CAAA,UAAS;AAC7B,WAAK,cAAc;AAGnB,WAAK,gBAAgB,oBAAoB,KAAK,MAAM;AACpD,WAAK,aAAa,YAAY,KAAK,KAAK,KAAK,aAAa;AAG1D,WAAK,YAAY,cAAc,IAAI;AAGnC,YAAM,WAAW,KAAK;AACtB,WAAK,YAAY;AAEjB,UAAI,KAAK,aAAa;AACpB,YAAI,CAAC,UAAU;AAEb,cACE,KAAK,IAAI,SAAS,UAAU,UAC3B,KAAK,IAAgF,QACtF;AACA,iBAAK,kBAAA;AAAA,UACP;AAEA,cAAI,KAAK,IAAI,SAAS,UAAU,UAAU,KAAK,SAAS;AACtD,iBAAK,QAAA;AAAA,UACP;AAAA,QACF;AAAA,MACF,OAAO;AACL,aAAK,WAAA;AAAA,MACP;AAEA,YAAM,aAAa,MAAM;AAEvB,qBAAa,KAAK,aAAa;AAC/B,aAAK,gBAAgB;AAIrB,aAAK,cAAA;AACL,aAAK,cAAc;AAGnB,YAAI,KAAK,IAAI,SAAS,UAAU,UAAU,KAAK,IAAI,OAAO,iBAAiB;AACzE,eAAK,YAAY,eAAe,YAAY,IAAI;AAAA,QAClD;AAMA,aAAK,YAAY,sBAAsB,iBAAiB,KAAK,QAAQ;AAAA,MACvE;AAGA,aAAO;AAAA,QACL,QAAQ,MAAM;AACZ,gBAAM,EAAE,WAAW,UAAAK,UAAAA,IAAa;AAChC,eAAK,YAAYA;AAEjB,cAAIA,WAAU;AACZ,uBAAA;AAGA;AAAA,UACF;AAIA,gBAAM,qBAAqB,oBAAoB,KAAK,MAAM;AAC1D,gBAAM,gBAAgB,YAAY,KAAK,KAAK,kBAAkB;AAE9D,gBAAM,kBAAkB,kBAAkB,KAAK;AAG/C,cAAI,iBAAiB;AAGnB,iBAAK,SAAS;AACd,iBAAK,aAAa;AAAA,UACpB;AAEA,cAAI,WAAW;AACb,iBAAK,YAAY,cAAc,IAAI;AAEnC,gBAAI,KAAK,IAAI,SAAS,UAAU,QAAQ;AACtC,oBAAM,0BAA0B,KAAK,IAAI,OAAO,2BAA2B;AAC3E,kBAAI,2BAA2B,KAAK,SAAS;AAC3C,sBAAM,WAAW,KAAK,SAAS,KAAK,eAAe,IAAI,CAAC;AAAA,cAC1D;AAAA,YACF,OAAO;AACL,mBAAK,kBAAA;AAAA,YACP;AAAA,UACF,WAAW,iBAAiB;AAC1B,gBAAI,KAAK,IAAI,SAAS,UAAU,QAAQ;AACtC,mBAAK,iBAAA;AAAA,YACP,OAAO;AACL,mBAAK,kBAAA;AAAA,YACP;AAAA,UACF;AAAA,QACF;AAAA,QACA;AAAA,MAAA;AAAA,IAEJ,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAMA,IAAI,QAAuB;AACzB,WAAO,KAAK,MAAM;AAAA,EACpB;AAAA,EAEA,IAAI,QAAiB;AACnB,WAAO,KAAK,MAAM;AAAA,EACpB;AAAA,EAEA,IAAI,YAAqB;AACvB,WAAO,KAAK,MAAM;AAAA,EACpB;AAAA,EAEA,IAAI,aAAsB;AACxB,WAAO,KAAK,MAAM;AAAA,EACpB;AAAA,EAEA,IAAI,aAAsB;AACxB,WAAO,KAAK,MAAM;AAAA,EACpB;AAAA,EAEA,IAAI,YAAqB;AACvB,WAAO,KAAK,MAAM;AAAA,EACpB;AAAA,EAEA,IAAI,UAAmB;AACrB,WAAO,KAAK,MAAM;AAAA,EACpB;AAAA;AAAA;AAAA,EAIA,IAAY,WAA2B;AACrC,WAAQ,KAAK,MAAc;AAAA,EAC7B;AAAA,EAEA,IAAY,UAAqB;AAC/B,WAAQ,KAAK,MAAc;AAAA,EAC7B;AAAA,EAEA,IAAY,SAAiB;AAC3B,WAAQ,KAAK,MAAc;AAAA,EAC7B;AAAA;AAAA,EAGA,KACE,aACA,YAC8B;AAC9B,WAAO,KAAK,MAAM,KAAK,aAAa,UAAU;AAAA,EAChD;AAAA,EAEA,MACE,YACsB;AACtB,WAAO,KAAK,MAAM,MAAM,UAAU;AAAA,EACpC;AAAA,EAEA,QAAQ,WAAyD;AAC/D,WAAO,KAAK,MAAM,QAAQ,SAAS;AAAA,EACrC;AAAA,EAEA,KAAK,OAAO,WAAW,IAAY;AACjC,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAMQ,mBAAgC;AACtC,QAAI,wBAAwB,KAAK;AAEjC,QAAI,CAAC,uBAAuB;AAC1B,YAAM,cAAc,KAAK;AAEzB,WAAK,wBAAwB,wBAAwBC,UAAAA,eAAe,MAAM;AAIxE,aAAK,MAAM;AAEX,cAAM,gCAAgB,IAAA;AAEtB,YAAI,KAAK,WAAW,QAAW;AAC7B,qBAAW,SAAS,KAAK,QAAQ;AAC/B,wBAAY,sBAAsB,OAAO,SAAS;AAAA,UACpD;AAAA,QACF;AAGA,aAAK,UAAU,UAAU,SAAS;AAElC,eAAO;AAAA,MACT,CAAC;AAAA,IACH;AAEA,WAAO,sBAAsB;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,aAA4B;AACxC,UAAM,QAAQ,KAAK;AAEnB,SAAK,cAAc;AAEnB,QAAI;AAEJ,QAAI;AAEF,eAAS,MAAM,KAAK,YAAY,gBAAgB,KAAK,KAAK,KAAK,UAAU;AAEzE,UAAI,WAAW,QAAW;AAExB,aAAK,YAAY,OAAO;AAGxB,aAAK,SAAS,OAAO;AAIrB,YAAI,OAAO,OAAO;AAChB,gBAAM,MAAM,KAAK;AACjB,eAAK,UAAU;AAAA,YACb,OAAO;AAAA,YACP,KAAK;AAAA,YACL,IAAI,QAAQ;AAAA,YACZ,IAAI,mBAAmB;AAAA,UAAA;AAAA,QAE3B;AAGA,cAAM,QAAQ,KAAK,IAAI;AACvB,cAAM,QACJ,iBAAiB,eACb,cAAc,OAAO,OAAO,OAAyB,KAAK,iCAAiB,IAAA,CAAK,IAChF,WAAW,OAAO,OAAO,OAAO,KAAK,IAAI,EAAE;AAAA,MACnD;AAAA,IACF,SAAS,OAAO;AACd,WAAK,YAAY,kBAAkB,KAAK,UAAU;AAClD,WAAK,YACF,WAAA,EACA,KAAK,OAAO,2EAA2E,KAAK;AAAA,IACjG;AAEA,QAAI,KAAK,UAAU;AACjB;AAAA,IACF;AAEA,QAAI;AAEF,UACE,KAAK,IAAI,SAAS,UAAU,UAC3B,KAAK,IAAgF,QACtF;AACA,aAAK,kBAAA;AAAA,MACP;AAGA,UAAI,KAAK,IAAI,SAAS,UAAU,QAAQ;AACtC,YAAI,WAAW,QAAW;AAExB,cAAI,KAAK,SAAS;AAEhB,gBAAI,KAAK,IAAI,aAAa,UAAa,KAAK,IAAI,WAAW,GAAG;AAC5D,mBAAK,iBAAA;AAAA,YACP,OAAO;AACL,mBAAK,QAAA;AAAA,YACP;AAAA,UACF;AAAA,QACF,OAAO;AAGL,gBAAM,WAAW,KAAK,SAAS,KAAK,eAAe,IAAI,CAAC;AAAA,QAC1D;AAAA,MACF;AAAA,IACF,SAAS,OAAO;AAEd,YAAM,SAAS,KAAc;AAAA,IAC/B;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOQ,oBAA0B;AAChC,SAAK,cAAA;AAEL,QAAI;AACJ,QAAI;AAEJ,QAAI,KAAK,IAAI,SAAS,UAAU,QAAQ;AACtC,iBAAW,KAAK,IAAI;AACpB,oBAAc,KAAK,IAAI;AAAA,IACzB,OAAO;AACL,YAAM,SAAU,KAAK,IAAgF;AAErG,UAAI,CAAC,QAAQ;AACX;AAAA,MACF;AAEA,iBAAW,OAAO;AAClB,oBAAc,OAAO;AAAA,IACvB;AAGA,UAAM,kBAAkB,KAAK;AAC7B,SAAK,cAAc,YAAY,KAAK,YAAY,WAAA,GAAc,iBAAgC,CAAA,WAAU;AACtG,YAAM,aAAa,oBAAoB,QAAQ,UAAU,KAAK,WAAW;AAGzE,UAAI,KAAK,IAAI,SAAS,UAAU,QAAQ;AACtC,aAAK,WAAW,QAAQ;AACxB,aAAK,YAAY,KAAK,IAAA;AAItB,aAAK,YAAY,cAAc,KAAK,KAAK,KAAK,YAAY,YAAY,KAAK,SAAS;AAAA,MACtF,OAAO;AACL,cAAM,YAAY,KAAK,iBAAA;AACvB,cAAM,UAAU,WAAW,UAAU;AAGrC,YAAI,YAAY,UAAa,CAAC,UAAU,IAAI,OAAO,GAAG;AACpD,eAAK,UAAU,gBAAgB,UAAU;AAAA,QAC3C;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,SAAS,QAAiC,QAAQ,OAAmB;AAEjF,QAAI,KAAK,UAAU;AACjB,YAAM,IAAI,MAAM,uCAAuC;AAAA,IACzD;AAEA,UAAM,EAAE,SAAS,eAAe,KAAK,eAAA;AACrC,QAAI;AAGJ,aAAS,UAAU,GAAG,WAAW,SAAS,WAAW;AACnD,UAAI;AACF,cAAM,WAAW,KAAK;AACtB,cAAM,YAAY,MAAM,SAAS,QAAQ,KAAK,YAAY,WAAA,GAAc,MAAM;AAG9E,YAAI;AAEJ,cAAM,aAAa,KAAK,IAAI,SAAS,UAAU;AAE/C,YAAI,cAAc,CAAC,SAAS,KAAK,WAAW,QAAW;AACrD,uBAAa,KAAK;AAAA,QACpB,OAAO;AACL,uBAAa,KAAK,SAAS,oBAAI,IAAA;AAAA,QACjC;AAEA,cAAM,QAAQ,KAAK,IAAI;AAEvB,cAAM,aACJ,iBAAiB,eACb,cAAc,WAAW,OAAyB,KAAK,aAAa,UAAU,IAC9E,WAAW,WAAW,OAAO,KAAK,IAAI,EAAE;AAE9C,YAAI;AAEJ,YAAI,YAAY;AACd,gBAAM,gBAAgB,KAAK,WAAW;AACtC,sBAAY,SAAS,kBAAkB,SAAY,CAAC,UAAU,IAAI,CAAC,GAAG,eAAe,UAAU;AAAA,QACjG,OAAO;AACL,sBAAY;AAAA,QACd;AAEA,YAAI;AAEJ,YAAI,OAAO;AACT,sBAAY,KAAK,YAAY,KAAK,IAAA;AAAA,QACpC,OAAO;AACL,sBAAY,KAAK,cAAc,KAAK,IAAA;AAAA,QACtC;AAEA,aAAK,kBAAkB;AAIvB,aAAK,YAAY;AAAA,UACf,KAAK;AAAA,UACL,KAAK;AAAA,UACL;AAAA,UACA;AAAA,UACA;AAAA,UACA,KAAK,uBAAA;AAAA,QAAuB;AAI9B,aAAK,YAAY,KAAK,IAAA;AAEtB,eAAO;AAAA,MACT,SAAS,OAAO;AACd,oBAAY;AAGZ,YAAI,WAAW,SAAS;AACtB,gBAAM;AAAA,QACR;AAGA,cAAM,QAAQ,WAAW,OAAO;AAChC,cAAM,IAAI,QAAQ,CAAA,YAAW,WAAW,SAAS,KAAK,CAAC;AAGvD,YAAI,KAAK,UAAU;AACjB,gBAAM,IAAI,MAAM,uCAAuC;AAAA,QACzD;AAAA,MACF;AAAA,IACF;AAGA,UAAM;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUQ,mBAAyB;AAE/B,UAAM,WAAY,KAAK,IAAgF;AAEvG,QAAI,aAAa,QAAW;AAC1B,WAAK,QAAA;AACL;AAAA,IACF;AAGA,iBAAa,KAAK,aAAa;AAG/B,SAAK,gBAAgB,WAAW,MAAM;AACpC,WAAK,gBAAgB;AACrB,WAAK,QAAA;AAAA,IACP,GAAG,QAAQ;AAAA,EACb;AAAA;AAAA;AAAA;AAAA,EAMA,UAAU,MAAkB;AAC1B,QAAI,KAAK,IAAI,SAAS,UAAU,QAAQ;AACtC,YAAM,IAAI,MAAM,+BAA+B;AAAA,IACjD;AAEA,QAAI,KAAK,kBAAkB;AACzB,YAAM,IAAI,MAAM,wCAAwC;AAAA,IAC1D;AAEA,QAAI,KAAK,gBAAgB;AACvB,aAAO,KAAK;AAAA,IACd;AAGA,iBAAa,KAAK,aAAa;AAC/B,SAAK,gBAAgB;AAGrB,SAAK,kBAAkB;AAIvB,SAAK,mBAAmB,QAAQ;AAChC,SAAK,SAAS,OAAO,CAAA,MAAK,IAAI,CAAC;AAE/B,UAAM,UAAU,KAAK,SAAS,KAAK,eAAe,IAAI,EACnD,KAAK,CAAA,WAAU;AACd,WAAK,WAAW,QAAQ;AAGxB,UAAI,KAAK,WAAW,QAAW;AAC7B,aAAK,OAAO,MAAA;AAAA,MACd;AAEA,aAAO;AAAA,IACT,CAAC,EACA,MAAM,CAAC,UAAmB;AACzB,WAAK,WAAW,SAAS,KAAK;AAC9B,aAAO,QAAQ,OAAO,KAAK;AAAA,IAC7B,CAAC,EACA,QAAQ,MAAM;AACb,WAAK,SAAS,OAAO,CAAA,MAAK,IAAI,CAAC;AAC/B,WAAK,mBAAmB,QAAQ;AAChC,WAAK,iBAAiB;AAAA,IACxB,CAAC;AAEH,SAAK,iBAAiB;AACtB,WAAO;AAAA,EACT;AAAA,EAEA,gBAAgB,MAAkB;AAChC,QAAI,KAAK,IAAI,SAAS,UAAU,QAAQ;AACtC,YAAM,IAAI,MAAM,0CAA0C;AAAA,IAC5D;AAEA,QAAI,KAAK,gBAAgB;AACvB,aAAO,QAAQ,OAAO,IAAI,MAAM,6CAA6C,CAAC;AAAA,IAChF;AAEA,QAAI,KAAK,kBAAkB;AACzB,aAAO,KAAK;AAAA,IACd;AAGA,UAAM,iBAAiB,KAAK;AAE5B,QAAI,CAAC,gBAAgB;AACnB,aAAO,QAAQ,OAAO,IAAI,MAAM,qBAAqB,CAAC;AAAA,IACxD;AAIA,SAAK,qBAAqB,QAAQ;AAClC,SAAK,SAAS,OAAO,CAAA,MAAK,IAAI,CAAC;AAE/B,UAAM,UAAU,KAAK,SAAS,gBAAgB,KAAK,EAChD,KAAK,CAAA,WAAU;AACd,WAAK,WAAY,QAAQ;AACzB,aAAO;AAAA,IACT,CAAC,EACA,MAAM,CAAC,UAAmB;AACzB,WAAK,WAAW,SAAS,KAAK;AAC9B,aAAO,QAAQ,OAAO,KAAK;AAAA,IAC7B,CAAC,EACA,QAAQ,MAAM;AACb,WAAK,SAAS,OAAO,CAAA,MAAK,IAAI,CAAC;AAC/B,WAAK,qBAAqB,QAAQ;AAClC,WAAK,mBAAmB;AAAA,IAC1B,CAAC;AAEH,SAAK,mBAAmB;AACxB,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAMA,IAAI,eAAwB;AAC1B,WAAO,KAAK,mBAAmB;AAAA,EACjC;AAAA,EAEA,IAAI,iBAA0B;AAC5B,WAAO,KAAK,qBAAqB;AAAA,EACnC;AAAA,EAEA,IAAI,aAAsB;AACxB,WAAO,KAAK,MAAM,aAAa,KAAK,gBAAgB,KAAK;AAAA,EAC3D;AAAA,EAEA,IAAI,cAAuB;AACzB,WAAO,KAAK,mBAAmB;AAAA,EACjC;AAAA,EAEA,IAAI,QAAsC;AACxC,SAAK,iBAAA;AACL,WAAO,KAAK,UAAU,SAAA;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA,EAKQ,mBAAyB;AAC/B,QAAI,KAAK,cAAc,QAAW;AAChC;AAAA,IACF;AAEA,UAAM,QAAQ,KAAK,QAAQ,kBAAA;AAE3B,SAAK,YAAY;AAAA,MACf,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK,WAAW;AAAA,MAChB,KAAK;AAAA,MACL,KAAK;AAAA,MACL;AAAA,IAAA;AAAA,EAEJ;AAAA;AAAA;AAAA;AAAA,EAKQ,yBAAuD;AAC7D,WAAO,KAAK,QAAQ,kBAAA;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,oBAAoB,QAAuC;AAEzD,UAAM,MAAM,KAAK;AACjB,UAAM,0BAA0B,IAAI;AAEpC,QAAI,4BAA4B,QAAW;AACzC,YAAM,IAAI;AAAA,QACR;AAAA,MAAA;AAAA,IAEJ;AAEA,QAAI,UAAU,WAAW,MAAM;AAC/B,QAAI,eAAe;AAGnB,QAAI,YAAY,QAAW;AACzB,qBAAe,oBAAoB,QAAQ,wBAAwB,OAAoB,KAAK,WAAW;AACvG,gBAAU,WAAW,YAAY;AAEjC,UAAI,YAAY,QAAW;AACzB,cAAM,IAAI,MAAM,sDAAsD;AAAA,MACxE;AAAA,IACF;AAGA,UAAM,YAAY,KAAK,iBAAA;AACvB,QAAI,UAAU,IAAI,OAAO,GAAG;AAC1B;AAAA,IACF;AAGA,QAAI,KAAK,UAAU,gBAAgB,OAAO,GAAG;AAC3C;AAAA,IACF;AAEA,SAAK,UAAU,oBAAoB,YAAY;AAAA,EACjD;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,uBAAuB,QAAuC;AAC5D,SAAK,UAAU,uBAAuB,MAAM;AAAA,EAC9C;AAAA,EAEA,IAAI,UAAmB;AAErB,QAAI,KAAK,IAAI,SAAS,UAAU,QAAQ;AACtC,aAAO;AAAA,IACT;AAEA,QAAI,KAAK,cAAc,QAAW;AAChC,aAAO;AAAA,IACT;AAEA,UAAM,YAAY,KAAK,IAAI,OAAO,aAAa;AAC/C,WAAO,KAAK,IAAA,IAAQ,KAAK,aAAa;AAAA,EACxC;AAAA,EAEA,IAAI,WAAoB;AAEtB,QAAI,KAAK,IAAI,SAAS,UAAU,QAAQ;AACtC,aAAO;AAAA,IACT;AAEA,UAAM,cAAc,KAAK,IAAI,OAAO,eAAe,YAAY;AAC/D,UAAM,iBAAiB,KAAK,YAAY;AAGxC,UAAM,WAAW,eAAe,gBAAA,EAAkB;AAElD,YAAQ,aAAA;AAAA,MACN,KAAK,YAAY;AACf,eAAO;AAAA,MACT,KAAK,YAAY;AACf,eAAO,CAAC;AAAA,MACV,KAAK,YAAY;AAEf,eAAO,CAAC,YAAY,KAAK,cAAc;AAAA,MACzC;AACE,eAAO;AAAA,IAAA;AAAA,EAEb;AAAA,EAEQ,iBAA+E;AAErF,QAAI,KAAK,IAAI,SAAS,UAAU,QAAQ;AACtC,aAAO,EAAE,SAAS,GAAG,YAAY,MAAM,EAAA;AAAA,IACzC;AAEA,UAAM,cAAc,KAAK,IAAI,OAAO;AACpC,UAAM,WAAW,KAAK,YAAY;AAGlC,QAAI;AACJ,QAAI;AAEJ,QAAI,gBAAgB,OAAO;AACzB,gBAAU;AAAA,IACZ,WAAW,gBAAgB,QAAW;AACpC,gBAAU,WAAW,IAAI;AAAA,IAC3B,WAAW,OAAO,gBAAgB,UAAU;AAC1C,gBAAU;AAAA,IACZ,OAAO;AACL,gBAAU,YAAY;AAAA,IACxB;AAGA,QAAI,OAAO,gBAAgB,YAAY,YAAY,YAAY;AAC7D,mBAAa,YAAY;AAAA,IAC3B,OAAO;AACL,mBAAa,CAAC,YAAoB,MAAO,KAAK,IAAI,GAAG,OAAO;AAAA,IAC9D;AAEA,WAAO,EAAE,SAAS,WAAA;AAAA,EACpB;AACF;AC7mCO,MAAM,mBAAuF;AAAA,EAClG;AAAA,EACQ;AAAA;AAAA,EAGA;AAAA;AAAA;AAAA,EAIA,6CAA0C,IAAA;AAAA,EAElD,YAAY,KAA4C,aAA0B;AAChF,SAAK,MAAM;AACX,SAAK,cAAc;AACnB,SAAK,QAAQ,KAAK,WAAA;AAAA,EACpB;AAAA,EAEQ,aAAgD;AACtD,WAAOC,UAAAA,KAAK,OAAO,YAAwC;AACzD,UAAI;AACF,cAAM,WAAW,MAAM,KAAK,iBAAiB,OAAO;AAGpD,cAAM,iBAAiB,KAAK,uBAAuB,QAAQ;AAG3D,aAAK,uBAAA;AAEL,eAAO;AAAA,MACT,SAAS,OAAO;AAEd,aAAK,wBAAA;AACL,cAAM;AAAA,MACR;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAMA,IAAI,QAA8B;AAChC,WAAO,KAAK,MAAM;AAAA,EACpB;AAAA,EAEA,IAAI,QAAiB;AACnB,WAAO,KAAK,MAAM;AAAA,EACpB;AAAA,EAEA,IAAI,YAAqB;AACvB,WAAO,KAAK,MAAM;AAAA,EACpB;AAAA,EAEA,IAAI,aAAsB;AACxB,WAAO,KAAK,MAAM;AAAA,EACpB;AAAA,EAEA,IAAI,aAAsB;AACxB,WAAO,KAAK,MAAM;AAAA,EACpB;AAAA,EAEA,IAAI,YAAqB;AACvB,WAAO,KAAK,MAAM;AAAA,EACpB;AAAA,EAEA,IAAI,UAAmB;AACrB,WAAO,KAAK,MAAM;AAAA,EACpB;AAAA;AAAA;AAAA;AAAA,EAMA,KACE,aACA,YAC8B;AAC9B,WAAO,KAAK,MAAM,KAAK,aAAa,UAAU;AAAA,EAChD;AAAA,EAEA,MACE,YAC6B;AAC7B,WAAO,KAAK,MAAM,MAAM,UAAU;AAAA,EACpC;AAAA,EAEA,QAAQ,WAAgE;AACtE,WAAO,KAAK,MAAM,QAAQ,SAAS;AAAA,EACrC;AAAA,EAEA,KAAK,OAAO,WAAW,IAAY;AACjC,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,CAAC,YAAwD;AAE7D,QAAI,KAAK,IAAI,mBAAmB;AAC9B,WAAK,uBAAuB,OAAO;AAAA,IACrC;AAGA,SAAK,MAAM,IAAI,OAAO;AAEtB,WAAO;AAAA,EACT;AAAA,EAEA,QAAQ,MAAY;AAElB,SAAK,wBAAA;AAGL,SAAK,QAAQ,KAAK,WAAA;AAAA,EACpB;AAAA;AAAA;AAAA;AAAA,EAMQ,uBAAuB,SAAwB;AAErD,SAAK,uBAAuB,MAAA;AAE5B,UAAM,eAAe,KAAK,IAAI;AAE9B,QAAI,EAAE,wBAAwB,eAAe;AAC3C;AAAA,IACF;AAGA,SAAK,sBAAsB,SAAS,YAA8B;AAAA,EACpE;AAAA;AAAA;AAAA;AAAA,EAKQ,sBAAsB,OAAgB,KAA2B;AACvE,UAAM,YAAY,WAAW,KAAK;AAClC,UAAM,UAAU,IAAI;AAGpB,QAAI,YAAY,KAAK,WAAW,UAAU,eAAe,GAAG;AAC1D;AAAA,IACF;AAGA,SAAK,UAAU,KAAK,WAAW,GAAG;AAChC,YAAM,WAAW;AACjB,UAAI,cAAc,KAAK,OAAO;AAC5B,cAAM,aAAa,SAAS,MAAO,IAAmC;AACtE,YAAI,cAAc,OAAO,eAAe,UAAU;AAChD,eAAK,6BAA6B,OAAoB,UAA4B;AAAA,QACpF;AAAA,MACF,OAAO;AACL,cAAM,gBAAgB,SAAS;AAC/B,cAAM,WAAW,gBAAiB,MAAkC,aAAa,IAAI;AACrF,YAAI,YAAY,OAAO,aAAa,UAAU;AAC5C,gBAAM,cAAc,SAAS,MAAO,QAAuC;AAC3E,cAAI,eAAe,OAAO,gBAAgB,UAAU;AAClD,iBAAK,8BAA8B,OAAkC,WAAoC;AAAA,UAC3G;AAAA,QACF;AAAA,MACF;AACA;AAAA,IACF;AAGA,QAAI,cAAc,KAAK,OAAO;AAC5B,YAAM,aAAc,IAAiB;AACrC,UAAI,cAAc,OAAO,eAAe,UAAU;AAChD,aAAK,6BAA6B,OAAoB,UAA4B;AAAA,MACpF;AACA;AAAA,IACF;AAGA,SAAK,UAAU,KAAK,YAAY,GAAG;AACjC,YAAM,cAAe,IAAkB;AACvC,UAAI,eAAe,OAAO,gBAAgB,UAAU;AAClD,mBAAW,QAAQ,OAAO,OAAO,KAAgC,GAAG;AAClE,eAAK,sBAAsB,MAAM,WAA6B;AAAA,QAChE;AAAA,MACF;AACA;AAAA,IACF;AAGA,SAAK,8BAA8B,OAAkC,GAA4B;AAAA,EACnG;AAAA,EAEQ,6BAA6B,OAAkB,OAA6B;AAClF,eAAW,QAAQ,OAAO;AACxB,WAAK,sBAAsB,MAAM,KAAK;AAAA,IACxC;AAAA,EACF;AAAA,EAEQ,8BAA8B,KAA8B,KAAkC;AACpG,UAAM,EAAE,SAAS;AAGjB,QAAI,OAAO,KAAK,QAAQ;AACtB,YAAM,YAAY;AAClB,YAAM,UAAU,UAAU;AAC1B,YAAM,WAAW,IAAI,OAAO;AAE5B,UAAI,aAAa,QAAW;AAC1B,cAAM,WAAW,UAAU;AAC3B,cAAM,YAAYb,MAAAA,UAAU,GAAG,QAAQ,IAAI,QAAQ,EAAE;AAGrD,aAAK,YAAY,yBAAyB,WAAW,GAAG;AACxD,aAAK,uBAAuB,IAAI,SAAS;AAAA,MAC3C;AAAA,IACF;AAGA,UAAM,QAAQ,IAAI;AAClB,UAAM,iBAAiB,IAAI;AAE3B,QAAI,mBAAmB,QAAW;AAChC,UAAI,OAAO,mBAAmB,UAAU;AACtC,cAAM,UAAU,MAAM,cAAc;AACpC,YAAI,WAAW,OAAO,YAAY,UAAU;AAC1C,eAAK,sBAAsB,IAAI,cAAc,GAAG,OAAyB;AAAA,QAC3E;AAAA,MACF,OAAO;AACL,mBAAW,QAAQ,gBAAgB;AACjC,gBAAM,UAAU,MAAM,IAAI;AAC1B,cAAI,WAAW,OAAO,YAAY,UAAU;AAC1C,iBAAK,sBAAsB,IAAI,IAAI,GAAG,OAAyB;AAAA,UACjE;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,0BAAgC;AAEtC,eAAW,aAAa,KAAK,wBAAwB;AACnD,WAAK,YAAY,uBAAuB,SAAS;AAAA,IACnD;AACA,SAAK,uBAAuB,MAAA;AAAA,EAC9B;AAAA,EAEQ,yBAA+B;AAErC,eAAW,aAAa,KAAK,wBAAwB;AACnD,WAAK,YAAY,uBAAuB,SAAS;AAAA,IACnD;AACA,SAAK,uBAAuB,MAAA;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA,EAMQ,uBAAuB,UAA6B;AAC1D,UAAM,gBAAgB,KAAK,IAAI;AAE/B,QAAI,EAAE,yBAAyB,eAAe;AAC5C,aAAO;AAAA,IACT;AAGA,UAAM,iCAAiB,IAAA;AACvB,UAAM,SAAS,cAAc,UAAU,eAAiC,KAAK,aAAa,UAAU;AAEpG,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAMA,MAAc,iBAAiB,SAAqC;AAClE,UAAM,EAAE,SAAS,eAAe,KAAK,eAAA;AACrC,QAAI;AAEJ,aAAS,UAAU,GAAG,WAAW,SAAS,WAAW;AACnD,UAAI;AACF,eAAO,MAAM,KAAK,IAAI,SAAS,KAAK,YAAY,WAAA,GAAc,OAAO;AAAA,MACvE,SAAS,OAAO;AACd,oBAAY;AAGZ,YAAI,WAAW,SAAS;AACtB,gBAAM;AAAA,QACR;AAGA,cAAM,QAAQ,WAAW,OAAO;AAChC,cAAM,IAAI,QAAQ,CAAA,YAAW,WAAW,SAAS,KAAK,CAAC;AAAA,MACzD;AAAA,IACF;AAGA,UAAM;AAAA,EACR;AAAA,EAEQ,iBAA+E;AACrF,UAAM,cAAc,KAAK,IAAI,OAAO;AAEpC,QAAI;AACJ,QAAI;AAEJ,QAAI,gBAAgB,OAAO;AACzB,gBAAU;AAAA,IACZ,WAAW,gBAAgB,QAAW;AACpC,gBAAU;AAAA,IACZ,WAAW,OAAO,gBAAgB,UAAU;AAC1C,gBAAU;AAAA,IACZ,OAAO;AACL,gBAAU,YAAY;AAAA,IACxB;AAGA,QAAI,OAAO,gBAAgB,YAAY,YAAY,YAAY;AAC7D,mBAAa,YAAY;AAAA,IAC3B,OAAO;AACL,mBAAa,CAAC,YAAoB,MAAO,KAAK,IAAI,GAAG,OAAO;AAAA,IAC9D;AAEA,WAAO,EAAE,SAAS,WAAA;AAAA,EACpB;AACF;AClWA,MAAM,qBAAqB;AAGpB,MAAM,eAAe;AAAA,EAO1B,YAAoB,aAAqB,GAAG;AAAxB,SAAA,aAAA;AAElB,UAAM,eAAe,qBAAqB,KAAK;AAC/C,SAAK,aAAa,WAAW,MAAM,KAAK,KAAA,GAAQ,YAAY;AAAA,EAC9D;AAAA,EAVQ;AAAA,EACA,QAAgB;AAAA;AAAA;AAAA,EAGhB,8BAAc,IAAA;AAAA,EAQtB,SAAS,UAAgC;AACvC,QAAI,SAAS,IAAI,SAAS,UAAU,QAAQ;AAC1C;AAAA,IACF;AAEA,UAAM,WAAW,SAAS,IAAI,OAAO;AAErC,QAAI,CAAC,UAAU;AACb;AAAA,IACF;AAEA,UAAM,iBAAiB,WAAW,KAAK;AAEvC,QAAI,SAAS,KAAK,QAAQ,IAAI,cAAc;AAC5C,QAAI,CAAC,QAAQ;AACX,mCAAa,IAAA;AACb,WAAK,QAAQ,IAAI,gBAAgB,MAAM;AAAA,IACzC;AACA,WAAO,IAAI,QAAQ;AAAA,EACrB;AAAA,EAEA,YAAYc,QAA6B;AACvC,QAAIA,OAAM,IAAI,SAAS,UAAU,QAAQ;AACvC;AAAA,IACF;AAEA,UAAM,WAAWA,OAAM,IAAI,OAAO;AAElC,QAAI,CAAC,UAAU;AACb;AAAA,IACF;AAEA,UAAM,iBAAiB,WAAW,KAAK;AAEvC,UAAM,SAAS,KAAK,QAAQ,IAAI,cAAc;AAC9C,QAAI,QAAQ;AACV,aAAO,OAAOA,MAAK;AAEnB,UAAI,OAAO,SAAS,GAAG;AACrB,aAAK,QAAQ,OAAO,cAAc;AAAA,MACpC;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,OAAO;AACb,SAAK,SAAS,qBAAqB,KAAK;AAGxC,eAAW,CAAC,UAAU,MAAM,KAAK,KAAK,QAAQ,WAAW;AACvD,UAAI,KAAK,QAAQ,aAAa,GAAG;AAE/B,mBAAWA,UAAS,QAAQ;AAE1B,cAAIA,UAAS,CAACA,OAAM,YAAY;AAC9B,YAAAA,OAAM,QAAA;AAAA,UACR;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,UAAM,eAAe,qBAAqB,KAAK;AAC/C,SAAK,aAAa,WAAW,MAAM,KAAK,KAAA,GAAQ,YAAY;AAAA,EAC9D;AAAA,EAEA,UAAgB;AACd,iBAAa,KAAK,UAAU;AAAA,EAC9B;AACF;AAGO,MAAM,mBAAmB;AAAA,EAC9B,SAAS,WAAuC;AAAA,EAEhD;AAAA,EAEA,YAAY,QAAoC;AAAA,EAEhD;AAAA,EAEA,UAAgB;AAAA,EAEhB;AACF;ACnGA,MAAM,oBAAoB,KAAK;AAGxB,MAAM,sBAAsB;AAAA;AAAA,EAKjC,YACU,aACA,aAAqB,GAC7B;AAFQ,SAAA,cAAA;AACA,SAAA,aAAA;AAER,SAAK,aAAa,YAAY,KAAK,MAAM,oBAAoB,KAAK,UAAU;AAAA,EAC9E;AAAA,EATQ;AAAA,EACA,mCAAmB,IAAA;AAAA;AAAA,EACnB,gCAAgB,IAAA;AAAA,EASxB,iBAAiB,UAAkB;AAGjC,SAAK,UAAU,IAAI,QAAQ;AAAA,EAC7B;AAAA,EAEA,eAAe,UAAkB;AAE/B,SAAK,aAAa,OAAO,QAAQ;AACjC,SAAK,UAAU,OAAO,QAAQ;AAAA,EAChC;AAAA,EAEQ,OAAO,MAAM;AACnB,QAAI,CAAC,KAAK,YAAa;AAGvB,eAAW,YAAY,KAAK,cAAc;AACxC,WAAK,YAAY,eAAe,OAAO,QAAQ;AAAA,IACjD;AAGA,SAAK,eAAe,KAAK;AACzB,SAAK,gCAAgB,IAAA;AAAA,EACvB;AAAA,EAEA,UAAgB;AACd,kBAAc,KAAK,UAAU;AAAA,EAC/B;AACF;AAGO,MAAM,0BAA0B;AAAA,EACrC,iBAAiB,WAAyB;AAAA,EAE1C;AAAA,EAEA,eAAe,WAAyB;AAAA,EAExC;AAAA,EAEA,UAAgB;AAAA,EAEhB;AACF;ACHO,SAAS,eAAe,SAAuD;AACpF,MAAI,YAAY,OAAW,QAAO;AAClC,MAAI,OAAO,YAAY,SAAU,QAAO;AACxC,MAAI,OAAO,YAAY,WAAY,QAAO,QAAA;AAC1C,SAAO,QAAQ;AACjB;AA0BO,IAAW,8BAAAC,eAAX;AACLA,aAAA,OAAA,IAAQ;AACRA,aAAA,eAAA,IAAgB;AAChBA,aAAA,QAAA,IAAS;AAHO,SAAAA;AAAA,GAAA,aAAA,CAAA,CAAA;AA6HlB,SAAS,SAAS,OAAsC;AACtD,SAAO,OAAO,UAAU,YAAY,UAAU;AAChD;AAKO,SAAS,oBACd,QAC0E;AAC1E,MAAI,WAAW,QAAW;AACxB,WAAO;AAAA,EACT;AAEA,QAAM,YAA0E,CAAA;AAEhF,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,MAAM,GAAG;AACjD,QAAI,SAAS,KAAK,GAAG;AACnB,gBAAU,GAAG,IAAI,MAAM;AAAA,IACzB,OAAO;AACL,gBAAU,GAAG,IAAI;AAAA,IACnB;AAAA,EACF;AAEA,SAAO;AACT;AAaO,MAAM,cAAc,CAAC,UAA6C,WAA4B;AACnG,SAAOf,MAAAA,UAAU,CAAC,SAAS,IAAI,SAAS,UAAU,MAAM,CAAC;AAC3D;AAEO,MAAM,YAAY;AAAA,EASvB,YACU,OACAQ,WAAwB,EAAE,OAAO,KAAK,WAC9C,gBACA,uBACA,gBACA;AALQ,SAAA,QAAA;AACA,SAAA,UAAAA;AAKR,SAAK,wBACH,yBAAyB,IAAI,sBAAsB,MAAM,KAAK,QAAQ,kBAAkB;AAC1F,SAAK,iBAAiB,kBAAkB,IAAI,eAAe,KAAK,QAAQ,iBAAiB;AACzF,SAAK,iBAAiB,kBAAkB,IAAI,eAAA;AAC5C,SAAK,WAAW,OAAO,WAAW;AAClC,SAAK,YAAY,IAAI,YAAY,IAAI;AAAA,EACvC;AAAA,EArBQ;AAAA,EACR,qCAAqB,IAAA;AAAA,EACrB,wCAAwB,IAAA;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAiBA,aAA2B;AACzB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,cACE,UACA,UACA,MACA,WACA,YACA,OACM;AAEN,UAAM,aAAa,eAAe,SAAY,IAAI,IAAI,UAAU,IAAI;AAEpE,SAAK,MAAM,UAAU,UAAiB,UAAU,MAAM,WAAW,YAAY,KAAK;AAAA,EACpF;AAAA,EAEA,cAAc,eAA+C;AAC3D,UAAM,EAAE,KAAK,UAAU,WAAA,IAAe;AAEtC,SAAK,MAAM,cAAc,KAAY,UAAU;AAG/C,QAAI,IAAI,SAAS,YAAoB,IAAI,OAAO,iBAAiB;AAC/D,WAAK,eAAe,SAAS,aAAa;AAAA,IAC5C;AAEA,SAAK,sBAAsB,eAAe,QAAQ;AAAA,EACpD;AAAA,EAEA,gBAAgB,UAAyE,UAAkB;AACzG,WAAO,KAAK,MAAM,UAAU,UAAiB,UAAU,KAAK,SAAS;AAAA,EACvE;AAAA,EAEA,kBAAkB,UAAwB;AACxC,SAAK,MAAM,YAAY,QAAQ;AAAA,EACjC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,SACE,UACA,QACkC;AAClC,UAAM,WAAW,YAAY,UAAU,MAAM;AAE7C,QAAI,gBAAgB,KAAK,eAAe,IAAI,QAAQ;AAGpD,QAAI,kBAAkB,QAAW;AAC/B,sBAAgB,IAAI,gBAAgB,UAAU,MAAM,UAAU,MAAM;AAGpE,WAAK,eAAe,IAAI,UAAU,aAAyC;AAAA,IAC7E;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,YACE,aACmC;AACnC,UAAM,aAAa,YAAY;AAE/B,QAAI,mBAAmB,KAAK,kBAAkB,IAAI,UAAU;AAG5D,QAAI,qBAAqB,QAAW;AAClC,yBAAmB,IAAI,mBAAmB,aAAa,IAAI;AAG3D,WAAK,kBAAkB,IAAI,YAAY,gBAAwD;AAAA,IACjG;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,yBAAyB,WAAmB,QAAuC;AACjF,SAAK,UAAU,yBAAyB,WAAW,MAAM;AAAA,EAC3D;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,uBAAuB,WAAyB;AAC9C,SAAK,UAAU,uBAAuB,SAAS;AAAA,EACjD;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,uBAAuB,WAAyB;AAC9C,SAAK,UAAU,uBAAuB,SAAS;AAAA,EACjD;AAAA,EAEA,cAAc,KAAa,OAAgC;AACzD,WAAO,KAAK,UAAU,uBAAuB,KAAK,KAAK;AAAA,EACzD;AAAA,EAEA,WAAW,KAAa,KAA8B,OAAkB,YAAwC;AAG9G,UAAM,SAAS,KAAK,UAAU,UAAU,KAAK,KAAK,OAAO,UAAU;AAInE,SAAK,MAAM,WAAW,KAAK,KAAK,UAAU;AAE1C,WAAO;AAAA,EACT;AAAA,EAEA,sBAAsB,KAAa,QAAkC;AACnE,WAAO,KAAK,UAAU,sBAAsB,KAAK,MAAM;AAAA,EACzD;AAAA,EAEA,UAAgB;AACd,SAAK,eAAe,QAAA;AACpB,SAAK,sBAAsB,QAAA;AAAA,EAC7B;AACF;AAEO,MAAM,qBAAuDA,UAAAA,QAAiC,MAAS;AASvG,SAAS,oBACdM,QACA,QACM;AACL,EAAAA,OAA8C,oBAAoB,MAAM;AAC3E;AAMO,SAAS,uBACdA,QACA,QACM;AACL,EAAAA,OAA8C,uBAAuB,MAAM;AAC9E;AC7ZO,SAAS,uBAAuB,cAAwC;AAE7E,QAAM,WAAqB,CAAA;AAC3B,QAAM,YAAsB,CAAA;AAC5B,QAAM,mCAAmB,IAAA;AACzB,MAAI,YAAY;AAChB,QAAM,aAAa;AACnB,MAAI;AAEJ,UAAQ,QAAQ,WAAW,KAAK,YAAY,OAAO,MAAM;AACvD,aAAS,KAAK,aAAa,MAAM,WAAW,MAAM,KAAK,CAAC;AACxD,cAAU,KAAK,MAAM,CAAC,CAAC;AACvB,iBAAa,IAAI,MAAM,CAAC,CAAC;AACzB,gBAAY,WAAW;AAAA,EACzB;AACA,WAAS,KAAK,aAAa,MAAM,SAAS,CAAC;AAG3C,SAAO,CAAC,WAAwC;AAE9C,QAAI,SAAS,SAAS,CAAC;AACvB,aAAS,IAAI,GAAG,IAAI,UAAU,QAAQ,KAAK;AACzC,gBAAU,mBAAmB,OAAO,OAAO,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,SAAS,IAAI,CAAC;AAAA,IAC7E;AAGA,QAAI,eAAuC;AAC3C,eAAW,OAAO,QAAQ;AACxB,UAAI,CAAC,aAAa,IAAI,GAAG,KAAK,OAAO,GAAG,MAAM,QAAW;AACvD,YAAI,iBAAiB,MAAM;AACzB,yBAAe,IAAI,gBAAA;AAAA,QACrB;AAEA,qBAAa,OAAO,KAAK,OAAO,OAAO,GAAG,CAAC,CAAC;AAAA,MAC9C;AAAA,IACF;AAGA,QAAI,iBAAiB,MAAM;AACzB,gBAAU,MAAM,aAAa,SAAA;AAAA,IAC/B;AAEA,WAAO;AAAA,EACT;AACF;ACXA,MAAM,2CAA2B,IAAA;AA2FjC,SAAS,aACP,wBAagD;AAChD,MAAI;AAEJ,QAAM,qBAAqB,MAAM;AAC/B,QAAI,oBAAoB,QAAW;AACjC,YAAM;AAAA,QACJ;AAAA,QACA,SAAS;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MAAA,IACE,uBAAA;AAEJ,YAAM,KAAK,GAAG,MAAM,IAAI,IAAI;AAE5B,UAAI;AACJ,UAAI;AAEJ,UAAI,OAAO,aAAa,UAAU;AAChC,YAAI,oBAAoB,cAAc;AACpC,kBAAQ;AACR,qBAAW,SAAS;AAAA,QACtB,WAAW,oBAAoB,KAAK;AAClC,kBAAQ;AACR,qBAAWd,MAAAA,UAAU,QAAQ;AAAA,QAC/B,OAAO;AACL,kBAAQ,EAAE,OAAO,QAA8C;AAC/D,qBAAW,MAAM;AAAA,QACnB;AAAA,MACF,OAAO;AACL,gBAAQ;AACR,mBAAWA,MAAAA,UAAU,KAAK;AAAA,MAC5B;AAGA,YAAM,kBAAkB,uBAAuB,IAAI;AAEnD,YAAM,UAAU,OAAO,SAAuB,WAAwB;AAEpE,cAAM,mBAAmB,gBAAgB,MAAM;AAG/C,cAAM,UAAU,eAAe,gBAAgB,OAAO,KAAK,eAAe,QAAQ,OAAO;AACzF,cAAM,UAAU,UAAU,GAAG,OAAO,GAAG,gBAAgB,KAAK;AAG5D,cAAM,EAAE,SAAS,UAAU,GAAG,aAAA,IAAiB,kBAAkB,CAAA;AAEjE,cAAMgB,YAAW,MAAM,QAAQ,MAAM,SAAS;AAAA,UAC5C;AAAA,UACA,GAAG;AAAA,QAAA,CACJ;AAED,eAAOA,UAAS,KAAA;AAAA,MAClB;AAGA,UAAI,eAAoB;AACxB,UAAI,QAAQ;AACV,YAAI;AACJ,YAAI;AAEJ,cAAM,WAAW,OAAO;AAExB,YAAI,OAAO,aAAa,UAAU;AAChC,cAAI,oBAAoB,cAAc;AACpC,0BAAc;AACd,6BAAiB,SAAS;AAAA,UAC5B,WAAW,oBAAoB,KAAK;AAClC,0BAAc;AACd,6BAAiBhB,MAAAA,UAAU,QAAQ;AAAA,UACrC,OAAO;AACL,0BAAc,EAAE,OAAO,QAA8C;AACrE,6BAAiB,YAAY;AAAA,UAC/B;AAAA,QACF,OAAO;AACL,wBAAc;AACd,2BAAiBA,MAAAA,UAAU,WAAW;AAAA,QACxC;AAEA,uBAAe;AAAA,UACb,OAAO;AAAA,UACP,UAAU;AAAA,UACV,aAAa,CAAC,SAAuB,QAAiC,aAAkB;AACtF,mBAAQ,OAAO,UAAkB,SAAS,QAAe,QAAQ;AAAA,UACnE;AAAA,QAAA;AAAA,MAEJ;AAGA,UAAI,0BAA+B;AACnC,UAAI,mBAAmB;AACrB,YAAI;AACJ,YAAI;AAEJ,cAAM,YAAY,kBAAkB;AAEpC,YAAI,OAAO,cAAc,UAAU;AACjC,cAAI,qBAAqB,cAAc;AACrC,0BAAc;AACd,6BAAiB,UAAU;AAAA,UAC7B,WAAW,qBAAqB,KAAK;AACnC,0BAAc;AACd,6BAAiBA,MAAAA,UAAU,SAAS;AAAA,UACtC,OAAO;AACL,0BAAc,EAAE,OAAO,SAA+C;AACtE,6BAAiB,YAAY;AAAA,UAC/B;AAAA,QACF,OAAO;AACL,wBAAc;AACd,2BAAiBA,MAAAA,UAAU,WAAW;AAAA,QACxC;AAEA,kCAA0B;AAAA,UACxB,OAAO;AAAA,UACP,UAAU;AAAA,QAAA;AAAA,MAEd;AAEA,wBAAkB;AAAA,QAChB,MAAM,aAAa,UAAU,gBAAgB,UAAU;AAAA,QACvD;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,QAAQ;AAAA,QACR,mBAAmB;AAAA,QACnB;AAAA,MAAA;AAAA,IAEJ;AAEA,WAAO;AAAA,EACT;AAEA,QAAM,UAAUiB,UAAAA;AAAAA,IACd,CAAC,WAA4E;AAC3E,YAAM,cAAcC,UAAAA,WAAW,kBAAkB;AAEjD,UAAI,gBAAgB,QAAW;AAC7B,cAAM,IAAI,MAAM,uBAAuB;AAAA,MACzC;AAEA,aAAO,YAAY,SAAkB,mBAAA,GAAsB,MAAM;AAAA,IACnE;AAAA;AAAA;AAAA;AAAA,EAAA;AAMF,uBAAqB,IAAI,SAAS,kBAAkB;AAEpD,SAAO;AACT;AAEO,SAAS,MAOd,wBAC0F;AAC1F,SAAO,aAAa,sBAA6B;AACnD;AAEO,SAAS,cAOd,wBAOkG;AAClG,SAAO,aAAa,sBAA6B;AACnD;AAEO,SAAS,YAMd,wBAC2D;AAC3D,MAAI;AAEJ,QAAM,sBAAsB,MAAM;AAChC,QAAI,qBAAqB,QAAW;AAClC,YAAM,EAAE,IAAI,UAAU,WAAW,MAAA,IAAU,uBAAA;AAG3C,UAAI,EAAE,oBAAoB,kBAAkB,SAAS,OAAO,KAAK,YAAY,GAAG;AAC9E,cAAM,IAAI,MAAM,4CAA4C;AAAA,MAC9D;AAEA,yBAAmB;AAAA,QACjB,MAAM,UAAU;AAAA,QAChB;AAAA,QACA,OAAO;AAAA,QACP,UAAU,SAAS;AAAA,QACnB,aAAa,CAAC,SAAuB,QAAiC,aAAkB;AACtF,iBAAQ,UAAkB,QAAe,QAAQ;AAAA,QACnD;AAAA,QACA;AAAA,MAAA;AAAA,IAEJ;AACA,WAAO;AAAA,EACT;AAEA,QAAM,WAAWD,mBAAS,CAAC,WAA4E;AACrG,UAAM,cAAcC,UAAAA,WAAW,kBAAkB;AAEjD,QAAI,gBAAgB,QAAW;AAC7B,YAAM,IAAI,MAAM,uBAAuB;AAAA,IACzC;AAEA,WAAO,YAAY,SAAkB,oBAAA,GAAuB,MAAM;AAAA,EACpE,CAAC;AAED,uBAAqB,IAAI,UAAU,mBAAmB;AAEtD,SAAO;AACT;AChWA,MAAM,8CAA8B,IAAA;AA4DpC,SAAS,eAAe,SAGtB;AACA,MAAI;AACJ,MAAI;AAEJ,MAAI,OAAO,YAAY,UAAU;AAC/B,QAAI,mBAAmB,cAAc;AACnC,cAAQ;AACR,iBAAW,QAAQ;AAAA,IACrB,WAAW,mBAAmB,KAAK;AACjC,cAAQ;AACR,iBAAWlB,MAAAA,UAAU,OAAO;AAAA,IAC9B,OAAO;AACL,cAAQ,EAAE,OAAO,OAA6C;AAC9D,iBAAW,MAAM;AAAA,IACnB;AAAA,EACF,OAAO;AACL,YAAQ;AACR,eAAWA,MAAAA,UAAU,KAAK;AAAA,EAC5B;AAEA,SAAO,EAAE,OAAO,SAAA;AAClB;AAEA,SAAS,gBACP,2BAKyC;AACzC,MAAI;AAEJ,QAAM,wBAAwB,MAA6C;AACzE,QAAI,uBAAuB,QAAW;AACpC,YAAM;AAAA,QACJ;AAAA,QACA,SAAS;AAAA,QACT;AAAA,QACA;AAAA,QACA,oBAAoB;AAAA,QACpB;AAAA,MAAA,IACE,0BAAA;AAEJ,YAAM,KAAK,YAAY,MAAM,IAAI,IAAI;AAErC,YAAM,EAAE,OAAO,cAAc,UAAU,gBAAA,IAAoB,eAAe,OAAO;AACjF,YAAM,EAAE,OAAO,eAAe,UAAU,iBAAA,IAAqB,eAAe,QAAQ;AAGpF,YAAM,kBAAkB,uBAAuB,IAAI;AAGnD,YAAM,qCAAqB,IAAA;AAC3B,YAAM,aAAa;AACnB,UAAI;AACJ,cAAQ,QAAQ,WAAW,KAAK,IAAI,OAAO,MAAM;AAC/C,uBAAe,IAAI,MAAM,CAAC,CAAC;AAAA,MAC7B;AAEA,YAAM,WAAW,OAAO,SAAuB,gBAA4C;AAEzF,cAAM,aAAsC,CAAA;AAC5C,mBAAW,aAAa,gBAAgB;AACtC,qBAAW,SAAS,IAAK,YAAwC,SAAS;AAAA,QAC5E;AACA,cAAM,MAAM,gBAAgB,UAAU;AAEtC,cAAM,gBAAgB,MAAM,QAAQ,MAAM,KAAK;AAAA,UAC7C;AAAA,UACA,SAAS;AAAA,YACP,gBAAgB;AAAA,UAAA;AAAA,UAElB,MAAM,KAAK,UAAU,WAAW;AAAA,QAAA,CACjC;AAED,eAAO,cAAc,KAAA;AAAA,MACvB;AAEA,2BAAqB;AAAA,QACnB;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MAAA;AAAA,IAEJ;AAEA,WAAO;AAAA,EACT;AAEA,QAAM,aAAa,MAAyC;AAC1D,UAAM,cAAckB,UAAAA,WAAW,kBAAkB;AAEjD,QAAI,gBAAgB,QAAW;AAC7B,YAAM,IAAI,MAAM,uBAAuB;AAAA,IACzC;AAEA,WAAO,YAAY,YAA+B,uBAAuB;AAAA,EAC3E;AAEA,0BAAwB,IAAI,YAAY,qBAAqB;AAE7D,SAAO;AACT;AA6BO,SAAS,SAKd,2BACmE;AACnE,SAAO,gBAAgB,yBAAgC;AACzD;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|