@flurryx/store 0.7.3 → 0.7.5

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/base-store.ts","../src/lazy-store.ts","../src/store-builder.ts","../src/dynamic-store.ts","../src/mirror-key.ts","../src/resource.ts","../src/collect-keyed.ts"],"sourcesContent":["export { BaseStore } from \"./base-store\";\nexport { LazyStore } from \"./lazy-store\";\nexport { Store } from \"./store-builder\";\nexport { mirrorKey } from \"./mirror-key\";\nexport { collectKeyed } from \"./collect-keyed\";\nexport type { MirrorOptions } from \"./mirror-key\";\nexport type { CollectKeyedOptions } from \"./collect-keyed\";\nexport type { IStore, ConfigToData } from \"./types\";\n","import { signal, WritableSignal } from \"@angular/core\";\nimport {\n ResourceState,\n isAnyKeyLoading,\n isKeyedResourceData,\n createKeyedResourceData,\n type KeyedResourceKey,\n} from \"@flurryx/core\";\nimport type { IStore } from \"./types\";\n\ntype UpdateHooksMap = Map<\n unknown,\n Array<\n (\n nextState: ResourceState<unknown>,\n previousState: ResourceState<unknown>\n ) => void\n >\n>;\n\nconst updateHooksMap = new WeakMap<object, UpdateHooksMap>();\n\nexport abstract class BaseStore<\n TEnum extends Record<string, string | number>,\n TData extends { [K in keyof TEnum]: ResourceState<unknown> }\n> implements IStore<TData>\n{\n private readonly signalsState = new Map<\n keyof TEnum,\n WritableSignal<TData[keyof TEnum]>\n >();\n\n protected constructor(protected readonly storeEnum: TEnum) {\n this.initializeState();\n updateHooksMap.set(this, new Map());\n }\n\n get<K extends keyof TData>(key: K): WritableSignal<TData[K]> {\n return this.signalsState.get(key.toString()) as WritableSignal<TData[K]>;\n }\n\n onUpdate<K extends keyof TData>(\n key: K,\n callback: (state: TData[K], previousState: TData[K]) => void\n ): () => void {\n const hooks = updateHooksMap.get(this)!;\n if (!hooks.has(key)) {\n hooks.set(key, []);\n }\n hooks\n .get(key)!\n .push(\n callback as (\n nextState: ResourceState<unknown>,\n previousState: ResourceState<unknown>\n ) => void\n );\n\n return () => {\n const hooksMap = hooks.get(key);\n if (!hooksMap) {\n return;\n }\n const index = hooksMap.indexOf(\n callback as (\n nextState: ResourceState<unknown>,\n previousState: ResourceState<unknown>\n ) => void\n );\n if (index > -1) {\n hooksMap.splice(index, 1);\n }\n };\n }\n\n update<K extends keyof TData>(key: K, newState: Partial<TData[K]>): void {\n const currentState = this.signalsState.get(key.toString());\n if (!currentState) {\n return;\n }\n\n const previousState = currentState() as TData[K];\n currentState.update((state) => ({\n ...state,\n ...newState,\n }));\n\n const updatedState = currentState() as TData[K];\n this.notifyUpdateHooks(key, updatedState, previousState);\n }\n\n clearAll(): void {\n Object.keys(this.storeEnum).forEach((key) => {\n this.clear(key as keyof TData);\n });\n }\n\n clear<K extends keyof TData>(key: K): void {\n const currentState = this.signalsState.get(key.toString());\n if (!currentState) {\n return;\n }\n\n const previousState = currentState() as TData[K];\n const _typedKey = key as keyof TEnum;\n currentState.set({\n data: undefined,\n isLoading: false,\n status: undefined,\n errors: undefined,\n } as TData[typeof _typedKey]);\n\n const nextState = currentState() as TData[K];\n this.notifyUpdateHooks(key, nextState, previousState);\n }\n\n startLoading<K extends keyof TData>(key: K): void {\n const currentState = this.signalsState.get(key.toString());\n if (!currentState) {\n return;\n }\n\n const _typedKey = key as keyof TEnum;\n currentState.update(\n (state) =>\n ({\n ...state,\n status: undefined,\n isLoading: true,\n errors: undefined,\n } as TData[typeof _typedKey])\n );\n }\n\n stopLoading<K extends keyof TData>(key: K): void {\n const currentState = this.signalsState.get(key.toString());\n if (!currentState) {\n return;\n }\n\n const _typedKey = key as keyof TEnum;\n currentState.update(\n (state) =>\n ({\n ...state,\n isLoading: false,\n status: undefined,\n errors: undefined,\n } as TData[typeof _typedKey])\n );\n }\n\n updateKeyedOne<K extends keyof TData>(\n key: K,\n resourceKey: KeyedResourceKey,\n entity: unknown\n ): void {\n const currentState = this.signalsState.get(key.toString());\n if (!currentState) {\n return;\n }\n\n const state = currentState();\n const data = isKeyedResourceData(state.data)\n ? state.data\n : createKeyedResourceData();\n\n const nextErrors = { ...data.errors };\n delete nextErrors[resourceKey];\n\n const nextData = {\n ...data,\n entities: {\n ...data.entities,\n [resourceKey]: entity,\n },\n isLoading: {\n ...data.isLoading,\n [resourceKey]: false,\n },\n status: {\n ...data.status,\n [resourceKey]: \"Success\" as const,\n },\n errors: nextErrors,\n };\n\n this.update(key, {\n data: nextData as unknown,\n isLoading: isAnyKeyLoading(nextData.isLoading),\n status: undefined,\n errors: undefined,\n } as Partial<TData[K]>);\n }\n\n clearKeyedOne<K extends keyof TData>(\n key: K,\n resourceKey: KeyedResourceKey\n ): void {\n const currentState = this.signalsState.get(key.toString());\n if (!currentState) {\n return;\n }\n\n const previousState = currentState() as TData[K];\n const state = previousState as ResourceState<unknown>;\n if (!isKeyedResourceData(state.data)) {\n return;\n }\n\n const data = state.data;\n\n const nextEntities = { ...data.entities };\n delete nextEntities[resourceKey];\n\n const nextIsLoading = { ...data.isLoading };\n delete nextIsLoading[resourceKey];\n\n const nextStatus = { ...data.status };\n delete nextStatus[resourceKey];\n\n const nextErrors = { ...data.errors };\n delete nextErrors[resourceKey];\n\n const nextData = {\n ...data,\n entities: nextEntities,\n isLoading: nextIsLoading,\n status: nextStatus,\n errors: nextErrors,\n };\n\n const _typedKey = key as keyof TEnum;\n currentState.update(\n (prev) =>\n ({\n ...prev,\n data: nextData as unknown,\n status: undefined,\n isLoading: isAnyKeyLoading(nextIsLoading),\n errors: undefined,\n } as TData[typeof _typedKey])\n );\n\n const updatedState = currentState() as TData[K];\n this.notifyUpdateHooks(key, updatedState, previousState);\n }\n\n startKeyedLoading<K extends keyof TData>(\n key: K,\n resourceKey: KeyedResourceKey\n ): void {\n const currentState = this.signalsState.get(key.toString());\n if (!currentState) {\n return;\n }\n\n const _typedKey = key as keyof TEnum;\n const state = currentState();\n if (!isKeyedResourceData(state.data)) {\n this.startLoading(key);\n return;\n }\n\n const previousState = state as TData[K];\n const data = state.data;\n\n const nextIsLoading = {\n ...data.isLoading,\n [resourceKey]: true,\n } as typeof data.isLoading;\n\n const nextStatus: typeof data.status = {\n ...data.status,\n };\n delete nextStatus[resourceKey];\n\n const nextErrors: typeof data.errors = {\n ...data.errors,\n };\n delete nextErrors[resourceKey];\n\n const nextData = {\n ...data,\n isLoading: nextIsLoading,\n status: nextStatus,\n errors: nextErrors,\n };\n\n currentState.update(\n (previous) =>\n ({\n ...previous,\n data: nextData,\n status: undefined,\n isLoading: isAnyKeyLoading(nextIsLoading),\n errors: undefined,\n } as TData[typeof _typedKey])\n );\n\n const updatedState = currentState() as TData[K];\n this.notifyUpdateHooks(key, updatedState, previousState);\n }\n\n private notifyUpdateHooks<K extends keyof TData>(\n key: K,\n nextState: TData[K],\n previousState: TData[K]\n ): void {\n const hooks = updateHooksMap.get(this);\n const keyHooks = hooks?.get(key);\n if (!keyHooks) {\n return;\n }\n\n keyHooks.forEach((hook) =>\n hook(\n nextState as ResourceState<unknown>,\n previousState as ResourceState<unknown>\n )\n );\n }\n\n private initializeState(): void {\n Object.keys(this.storeEnum).forEach((key) => {\n const _typedKey = key as keyof TEnum;\n const initialState: ResourceState<unknown> = {\n data: undefined,\n isLoading: false,\n status: undefined,\n errors: undefined,\n };\n this.signalsState.set(\n _typedKey,\n signal<TData[typeof _typedKey]>(initialState as TData[typeof _typedKey])\n );\n });\n }\n}\n","import { signal, WritableSignal } from '@angular/core';\nimport type { ResourceState } from '@flurryx/core';\nimport type { IStore } from './types';\n\ntype UpdateCallback = (\n nextState: ResourceState<unknown>,\n previousState: ResourceState<unknown>\n) => void;\n\nfunction createDefaultState<T>(): ResourceState<T> {\n return {\n data: undefined,\n isLoading: false,\n status: undefined,\n errors: undefined,\n };\n}\n\n/**\n * Lazy store that creates signals on first access.\n * Used by the `Store.for<Config>().build()` API where keys are\n * known only at the type level (no runtime enum).\n */\nexport class LazyStore<\n TData extends Record<string, ResourceState<unknown>>,\n> implements IStore<TData>\n{\n private readonly signals = new Map<string, WritableSignal<ResourceState<unknown>>>();\n private readonly hooks = new Map<string, UpdateCallback[]>();\n\n private getOrCreate<K extends keyof TData & string>(\n key: K\n ): WritableSignal<TData[K]> {\n let sig = this.signals.get(key);\n if (!sig) {\n sig = signal<ResourceState<unknown>>(createDefaultState());\n this.signals.set(key, sig);\n }\n return sig as WritableSignal<TData[K]>;\n }\n\n get<K extends keyof TData & string>(key: K): WritableSignal<TData[K]> {\n return this.getOrCreate(key);\n }\n\n update<K extends keyof TData & string>(\n key: K,\n newState: Partial<TData[K]>\n ): void {\n const sig = this.getOrCreate(key);\n const previousState = sig();\n sig.update((state) => ({ ...state, ...newState }));\n const nextState = sig();\n this.notifyHooks(key, nextState, previousState);\n }\n\n clear<K extends keyof TData & string>(key: K): void {\n const sig = this.getOrCreate(key);\n const previousState = sig();\n sig.set(createDefaultState() as TData[K]);\n const nextState = sig();\n this.notifyHooks(key, nextState, previousState);\n }\n\n clearAll(): void {\n for (const key of this.signals.keys()) {\n this.clear(key as keyof TData & string);\n }\n }\n\n startLoading<K extends keyof TData & string>(key: K): void {\n const sig = this.getOrCreate(key);\n sig.update(\n (state) =>\n ({\n ...state,\n status: undefined,\n isLoading: true,\n errors: undefined,\n }) as TData[K]\n );\n }\n\n stopLoading<K extends keyof TData & string>(key: K): void {\n const sig = this.getOrCreate(key);\n sig.update(\n (state) =>\n ({\n ...state,\n isLoading: false,\n status: undefined,\n errors: undefined,\n }) as TData[K]\n );\n }\n\n onUpdate<K extends keyof TData & string>(\n key: K,\n callback: (state: TData[K], previousState: TData[K]) => void\n ): () => void {\n if (!this.hooks.has(key)) {\n this.hooks.set(key, []);\n }\n const typedCallback = callback as UpdateCallback;\n this.hooks.get(key)!.push(typedCallback);\n\n return () => {\n const keyHooks = this.hooks.get(key);\n if (!keyHooks) {\n return;\n }\n const index = keyHooks.indexOf(typedCallback);\n if (index > -1) {\n keyHooks.splice(index, 1);\n }\n };\n }\n\n private notifyHooks<K extends keyof TData & string>(\n key: K,\n nextState: TData[K],\n previousState: TData[K]\n ): void {\n const keyHooks = this.hooks.get(key);\n if (!keyHooks) {\n return;\n }\n keyHooks.forEach((hook) =>\n hook(\n nextState as ResourceState<unknown>,\n previousState as ResourceState<unknown>\n )\n );\n }\n}\n","import { InjectionToken, inject } from \"@angular/core\";\nimport { BaseStore } from \"./base-store\";\nimport { DynamicStore } from \"./dynamic-store\";\nimport { LazyStore } from \"./lazy-store\";\nimport { mirrorKey } from \"./mirror-key\";\nimport { resource } from \"./resource\";\nimport type { ResourceState } from \"@flurryx/core\";\nimport type {\n StoreConfig,\n ResourceDef,\n InferEnum,\n InferData,\n ConfigToData,\n IStore,\n} from \"./types\";\n\n// ---------------------------------------------------------------------------\n// Mirror definition — accumulated by builders, wired up in build() factory\n// ---------------------------------------------------------------------------\n\ninterface MirrorDef {\n readonly sourceToken: InjectionToken<\n IStore<Record<string, ResourceState<unknown>>>\n >;\n readonly sourceKey: string;\n readonly targetKey: string;\n}\n\nfunction wireMirrors<\n TStore extends IStore<Record<string, ResourceState<unknown>>>\n>(store: TStore, mirrors: readonly MirrorDef[]): TStore {\n for (const def of mirrors) {\n const sourceStore = inject(def.sourceToken);\n mirrorKey(sourceStore, def.sourceKey, store, def.targetKey);\n }\n return store;\n}\n\n// ---------------------------------------------------------------------------\n// Unconstrained builder (existing API)\n// ---------------------------------------------------------------------------\n\n/**\n * Intermediate builder step after .resource('key') — awaits .as<T>().\n */\ninterface AsStep<TAccum extends StoreConfig, TKey extends string> {\n as<T>(): StoreBuilder<TAccum & Record<TKey, ResourceDef<T>>>;\n}\n\n/**\n * Fluent builder for creating stores.\n * Accumulates resource definitions then produces an InjectionToken on .build().\n */\ninterface StoreBuilder<TAccum extends StoreConfig> {\n resource<TKey extends string>(key: TKey): AsStep<TAccum, TKey>;\n mirror<TSourceData extends Record<string, ResourceState<unknown>>>(\n source: InjectionToken<IStore<TSourceData>>,\n sourceKey: keyof TSourceData & string,\n targetKey?: keyof TAccum & string\n ): StoreBuilder<TAccum>;\n build(): InjectionToken<BaseStore<InferEnum<TAccum>, InferData<TAccum>>>;\n}\n\nfunction createBuilder<TAccum extends StoreConfig>(\n accum: TAccum,\n mirrors: readonly MirrorDef[] = []\n): StoreBuilder<TAccum> {\n return {\n resource<TKey extends string>(key: TKey): AsStep<TAccum, TKey> {\n return {\n as<T>(): StoreBuilder<TAccum & Record<TKey, ResourceDef<T>>> {\n const nextAccum = {\n ...accum,\n [key]: resource<T>(),\n } as TAccum & Record<TKey, ResourceDef<T>>;\n return createBuilder(nextAccum, mirrors);\n },\n };\n },\n mirror(source, sourceKey, targetKey?) {\n const def: MirrorDef = {\n sourceToken: source as InjectionToken<\n IStore<Record<string, ResourceState<unknown>>>\n >,\n sourceKey,\n targetKey: (targetKey ?? sourceKey) as string,\n };\n return createBuilder(accum, [...mirrors, def]);\n },\n build() {\n return new InjectionToken<\n BaseStore<InferEnum<TAccum>, InferData<TAccum>>\n >(\"FlurryxStore\", {\n providedIn: \"root\",\n factory: () =>\n wireMirrors(new DynamicStore(accum), mirrors) as BaseStore<\n InferEnum<TAccum>,\n InferData<TAccum>\n >,\n });\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// Constrained builder (.for(enum) API)\n// ---------------------------------------------------------------------------\n\n/** Keys from the enum that have NOT yet been defined. */\ntype Remaining<\n TEnum extends Record<string, string>,\n TAccum extends StoreConfig\n> = Exclude<keyof TEnum & string, keyof TAccum>;\n\n/** Intermediate .as<T>() step for the constrained builder. */\ninterface ConstrainedAsStep<\n TEnum extends Record<string, string>,\n TAccum extends StoreConfig,\n TKey extends string\n> {\n as<T>(): ConstrainedBuilder<TEnum, TAccum & Record<TKey, ResourceDef<T>>>;\n}\n\n/**\n * Constrained builder — only allows keys from the enum that haven't been\n * defined yet. `.build()` is only available when all keys are accounted for.\n */\ntype ConstrainedBuilder<\n TEnum extends Record<string, string>,\n TAccum extends StoreConfig\n> = [Remaining<TEnum, TAccum>] extends [never]\n ? {\n mirror<TSourceData extends Record<string, ResourceState<unknown>>>(\n source: InjectionToken<IStore<TSourceData>>,\n sourceKey: keyof TSourceData & string,\n targetKey?: keyof TAccum & string\n ): ConstrainedBuilder<TEnum, TAccum>;\n build(): InjectionToken<BaseStore<InferEnum<TAccum>, InferData<TAccum>>>;\n }\n : {\n resource<TKey extends Remaining<TEnum, TAccum>>(\n key: TKey\n ): ConstrainedAsStep<TEnum, TAccum, TKey>;\n };\n\nfunction createConstrainedBuilder<\n TEnum extends Record<string, string>,\n TAccum extends StoreConfig\n>(\n _enumObj: TEnum,\n accum: TAccum,\n mirrors: readonly MirrorDef[] = []\n): ConstrainedBuilder<TEnum, TAccum> {\n return {\n resource<TKey extends string>(\n key: TKey\n ): ConstrainedAsStep<TEnum, TAccum, TKey> {\n return {\n as<T>(): ConstrainedBuilder<\n TEnum,\n TAccum & Record<TKey, ResourceDef<T>>\n > {\n const nextAccum = {\n ...accum,\n [key]: resource<T>(),\n } as TAccum & Record<TKey, ResourceDef<T>>;\n return createConstrainedBuilder(_enumObj, nextAccum, mirrors);\n },\n };\n },\n mirror(\n source: InjectionToken<IStore<Record<string, ResourceState<unknown>>>>,\n sourceKey: string,\n targetKey?: string\n ) {\n const def: MirrorDef = {\n sourceToken: source,\n sourceKey,\n targetKey: targetKey ?? sourceKey,\n };\n return createConstrainedBuilder(_enumObj, accum, [...mirrors, def]);\n },\n build() {\n return new InjectionToken<\n BaseStore<InferEnum<TAccum>, InferData<TAccum>>\n >(\"FlurryxStore\", {\n providedIn: \"root\",\n factory: () =>\n wireMirrors(new DynamicStore(accum), mirrors) as BaseStore<\n InferEnum<TAccum>,\n InferData<TAccum>\n >,\n });\n },\n } as ConstrainedBuilder<TEnum, TAccum>;\n}\n\n// ---------------------------------------------------------------------------\n// Interface-based builder (Store.for<Config>() API)\n// ---------------------------------------------------------------------------\n\ninterface InterfaceBuilder<TConfig extends Record<string, unknown>> {\n mirror<TSourceData extends Record<string, ResourceState<unknown>>>(\n source: InjectionToken<IStore<TSourceData>>,\n sourceKey: keyof TSourceData & string,\n targetKey?: keyof TConfig & string\n ): InterfaceBuilder<TConfig>;\n build(): InjectionToken<IStore<ConfigToData<TConfig>>>;\n}\n\nfunction createInterfaceBuilder<TConfig extends Record<string, unknown>>(\n mirrors: readonly MirrorDef[] = []\n): InterfaceBuilder<TConfig> {\n return {\n mirror(source, sourceKey, targetKey?) {\n const def: MirrorDef = {\n sourceToken: source as InjectionToken<\n IStore<Record<string, ResourceState<unknown>>>\n >,\n sourceKey,\n targetKey: (targetKey ?? sourceKey) as string,\n };\n return createInterfaceBuilder<TConfig>([...mirrors, def]);\n },\n build() {\n return new InjectionToken(\"FlurryxStore\", {\n providedIn: \"root\",\n factory: () =>\n wireMirrors(\n new LazyStore() as IStore<Record<string, ResourceState<unknown>>>,\n mirrors\n ) as unknown as IStore<ConfigToData<TConfig>>,\n });\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// Public entry point\n// ---------------------------------------------------------------------------\n\ninterface StoreEntry {\n /**\n * Define a named resource slot.\n * Chain .as<T>() to assign its type, then continue with more .resource() calls\n * or call .build() when done.\n */\n resource<TKey extends string>(\n key: TKey\n ): {\n as<T>(): StoreBuilder<Record<TKey, ResourceDef<T>>>;\n };\n\n /**\n * Interface-based builder: pass a config interface as a generic.\n * No runtime argument needed — keys and types are inferred from the interface.\n *\n * @example\n * interface ChatStoreConfig {\n * SESSIONS: ChatSession[];\n * MESSAGES: ChatMessage[];\n * }\n * const ChatStore = Store.for<ChatStoreConfig>().build();\n */\n for<TConfig extends Record<string, unknown>>(): InterfaceBuilder<TConfig>;\n\n /**\n * Bind the builder to an enum object for compile-time key validation.\n *\n * @example\n * const Enum = { A: 'A', B: 'B' } as const;\n * const MyStore = Store.for(Enum)\n * .resource('A').as<string>()\n * .resource('B').as<number>()\n * .build();\n */\n for<TEnum extends Record<string, string>>(\n enumObj: TEnum\n ): ConstrainedBuilder<TEnum, Record<string, never>>;\n}\n\n/**\n * Fluent store builder entry point.\n *\n * @example\n * // Unconstrained\n * export const CustomersStore = Store\n * .resource('customers').as<Customer[]>()\n * .resource('customerDetails').as<Customer>()\n * .build();\n *\n * @example\n * // Constrained with enum\n * const Enum = { SESSIONS: 'SESSIONS', MESSAGES: 'MESSAGES' } as const;\n * export const ChatStore = Store.for(Enum)\n * .resource('SESSIONS').as<Session[]>()\n * .resource('MESSAGES').as<Message[]>()\n * .build();\n */\nexport const Store: StoreEntry = {\n ...createBuilder({} as StoreConfig),\n for(enumObj?: Record<string, string>) {\n if (arguments.length === 0) {\n return createInterfaceBuilder();\n }\n return createConstrainedBuilder(enumObj!, {} as Record<string, never>);\n },\n};\n","import { BaseStore } from './base-store';\nimport type { StoreConfig, InferEnum, InferData } from './types';\n\n/**\n * Internal concrete subclass of BaseStore.\n * Auto-generates an identity enum from config keys.\n * NOT publicly exported — consumers interact via BaseStore interface.\n */\nexport class DynamicStore<\n TConfig extends StoreConfig,\n> extends BaseStore<InferEnum<TConfig>, InferData<TConfig>> {\n constructor(config: TConfig) {\n const identityEnum = Object.keys(config).reduce(\n (acc, key) => ({ ...acc, [key]: key }),\n {} as InferEnum<TConfig>\n );\n super(identityEnum);\n }\n}\n","import type { ResourceState } from \"@flurryx/core\";\nimport type { IStore } from \"./types\";\n\nexport interface MirrorOptions {\n destroyRef?: { onDestroy: (fn: () => void) => void };\n}\n\n/**\n * Mirrors a resource key from a source store to a target store.\n * When the source key updates, the target key is updated with the same state.\n *\n * @param source - The store to mirror from\n * @param sourceKey - The key to watch on the source store\n * @param target - The store to mirror to\n * @param targetKeyOrOptions - Either the target key name or options (defaults source key)\n * @param options - Mirror options when a target key is provided\n * @returns Cleanup function to stop mirroring\n */\nexport function mirrorKey<\n TSource extends Record<string, ResourceState<unknown>>,\n TTarget extends Record<string, ResourceState<unknown>>\n>(\n source: IStore<TSource>,\n sourceKey: keyof TSource & string,\n target: IStore<TTarget>,\n targetKeyOrOptions?: (keyof TTarget & string) | MirrorOptions,\n options?: MirrorOptions\n): () => void {\n const resolvedTargetKey = (\n typeof targetKeyOrOptions === \"string\" ? targetKeyOrOptions : sourceKey\n ) as keyof TTarget & string;\n\n const resolvedOptions =\n typeof targetKeyOrOptions === \"object\" ? targetKeyOrOptions : options;\n\n const cleanup = source.onUpdate(sourceKey, (state) => {\n target.update(\n resolvedTargetKey,\n state as unknown as Partial<TTarget[keyof TTarget & string]>\n );\n });\n\n if (resolvedOptions?.destroyRef) {\n resolvedOptions.destroyRef.onDestroy(cleanup);\n }\n\n return cleanup;\n}\n","import type { ResourceDef } from './types';\n\n/**\n * Creates a phantom-typed resource definition marker.\n * Zero runtime cost — returns an empty object that only carries type info.\n *\n * @example\n * const config = {\n * customers: resource<Customer[]>(),\n * customerDetails: resource<Customer>(),\n * };\n */\nexport function resource<T>(): ResourceDef<T> {\n return {} as ResourceDef<T>;\n}\n","import type {\n ResourceState,\n KeyedResourceKey,\n KeyedResourceData,\n} from '@flurryx/core';\nimport { createKeyedResourceData, isAnyKeyLoading } from '@flurryx/core';\nimport type { IStore } from './types';\n\nexport interface CollectKeyedOptions<TEntity> {\n extractId: (data: TEntity | undefined) => KeyedResourceKey | undefined;\n destroyRef?: { onDestroy: (fn: () => void) => void };\n}\n\n/**\n * Accumulates single-entity resource fetches into a keyed cache on a target store.\n *\n * On each source update:\n * - If status is 'Success' and extractId returns a valid key, merges the entity\n * into the target's keyed resource data.\n * - If the source data is cleared and a previous entity existed, removes it from\n * the target's keyed data.\n *\n * @param source - The store containing the single-entity resource\n * @param sourceKey - The key to watch on the source store\n * @param target - The store to accumulate entities into\n * @param targetKeyOrOptions - Either the target key name or options (defaults source key)\n * @param options - Collect options when a target key is provided\n * @returns Cleanup function to stop collecting\n */\nexport function collectKeyed<\n TSource extends Record<string, ResourceState<unknown>>,\n TTarget extends Record<string, ResourceState<unknown>>,\n TEntity = unknown,\n>(\n source: IStore<TSource>,\n sourceKey: keyof TSource & string,\n target: IStore<TTarget>,\n targetKeyOrOptions?: (keyof TTarget & string) | CollectKeyedOptions<TEntity>,\n options?: CollectKeyedOptions<TEntity>,\n): () => void {\n const resolvedTargetKey = (\n typeof targetKeyOrOptions === 'string'\n ? targetKeyOrOptions\n : sourceKey\n ) as keyof TTarget & string;\n\n const resolvedOptions = (\n typeof targetKeyOrOptions === 'object' ? targetKeyOrOptions : options\n ) as CollectKeyedOptions<TEntity>;\n\n // Initialize target with empty keyed resource data\n target.update(resolvedTargetKey, {\n data: createKeyedResourceData(),\n } as Partial<TTarget[keyof TTarget & string]>);\n\n let previousId: KeyedResourceKey | undefined;\n\n const cleanup = source.onUpdate(sourceKey, (state) => {\n const resourceState = state as ResourceState<TEntity>;\n const currentId = resolvedOptions.extractId(resourceState.data);\n const currentTarget = target.get(resolvedTargetKey)();\n const currentKeyed = (currentTarget as ResourceState<unknown>).data as\n KeyedResourceData<KeyedResourceKey, TEntity> | undefined;\n\n if (!currentKeyed) {\n return;\n }\n\n if (resourceState.status === 'Success' && currentId !== undefined) {\n const newEntities = { ...currentKeyed.entities, [currentId]: resourceState.data };\n const newIsLoading = { ...currentKeyed.isLoading, [currentId]: false };\n const newStatus = { ...currentKeyed.status, [currentId]: resourceState.status };\n const newErrors = { ...currentKeyed.errors };\n delete newErrors[currentId];\n\n const updatedKeyed: KeyedResourceData<KeyedResourceKey, TEntity> = {\n entities: newEntities,\n isLoading: newIsLoading,\n status: newStatus,\n errors: newErrors,\n };\n\n target.update(resolvedTargetKey, {\n data: updatedKeyed,\n isLoading: isAnyKeyLoading(newIsLoading),\n status: 'Success',\n } as Partial<TTarget[keyof TTarget & string]>);\n\n previousId = currentId;\n } else if (resourceState.status === 'Error' && currentId !== undefined) {\n const newIsLoading = { ...currentKeyed.isLoading, [currentId]: false };\n const newStatus = { ...currentKeyed.status, [currentId]: resourceState.status };\n const newErrors = { ...currentKeyed.errors, [currentId]: resourceState.errors };\n\n const updatedKeyed: KeyedResourceData<KeyedResourceKey, TEntity> = {\n entities: { ...currentKeyed.entities },\n isLoading: newIsLoading,\n status: newStatus,\n errors: newErrors,\n };\n\n target.update(resolvedTargetKey, {\n data: updatedKeyed,\n isLoading: isAnyKeyLoading(newIsLoading),\n } as Partial<TTarget[keyof TTarget & string]>);\n\n previousId = currentId;\n } else if (resourceState.data === undefined && previousId !== undefined) {\n // Source cleared — remove previous entity from cache\n const { [previousId]: _removed, ...remainingEntities } = currentKeyed.entities;\n const { [previousId]: _removedLoading, ...remainingLoading } = currentKeyed.isLoading;\n const { [previousId]: _removedStatus, ...remainingStatus } = currentKeyed.status;\n const { [previousId]: _removedErrors, ...remainingErrors } = currentKeyed.errors;\n\n const updatedKeyed: KeyedResourceData<KeyedResourceKey, TEntity> = {\n entities: remainingEntities,\n isLoading: remainingLoading,\n status: remainingStatus,\n errors: remainingErrors,\n };\n\n target.update(resolvedTargetKey, {\n data: updatedKeyed,\n isLoading: isAnyKeyLoading(remainingLoading),\n } as Partial<TTarget[keyof TTarget & string]>);\n\n previousId = undefined;\n } else if (resourceState.isLoading && currentId !== undefined) {\n const newIsLoading = { ...currentKeyed.isLoading, [currentId]: true };\n\n const updatedKeyed: KeyedResourceData<KeyedResourceKey, TEntity> = {\n entities: { ...currentKeyed.entities },\n isLoading: newIsLoading,\n status: { ...currentKeyed.status },\n errors: { ...currentKeyed.errors },\n };\n\n target.update(resolvedTargetKey, {\n data: updatedKeyed,\n isLoading: true,\n } as Partial<TTarget[keyof TTarget & string]>);\n\n previousId = currentId;\n }\n });\n\n if (resolvedOptions?.destroyRef) {\n resolvedOptions.destroyRef.onDestroy(cleanup);\n }\n\n return cleanup;\n}\n"],"mappings":"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","names":["import_core","import_core","import_core","import_core"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/base-store.ts","../src/lazy-store.ts","../src/store-builder.ts","../src/dynamic-store.ts","../src/mirror-key.ts","../src/collect-keyed.ts","../src/resource.ts"],"sourcesContent":["export { BaseStore } from \"./base-store\";\nexport { LazyStore } from \"./lazy-store\";\nexport { Store } from \"./store-builder\";\nexport { mirrorKey } from \"./mirror-key\";\nexport { collectKeyed } from \"./collect-keyed\";\nexport type { MirrorOptions } from \"./mirror-key\";\nexport type { CollectKeyedOptions } from \"./collect-keyed\";\nexport type { IStore, ConfigToData } from \"./types\";\n","import { signal, WritableSignal } from \"@angular/core\";\nimport {\n ResourceState,\n isAnyKeyLoading,\n isKeyedResourceData,\n createKeyedResourceData,\n type KeyedResourceKey,\n} from \"@flurryx/core\";\nimport type { IStore } from \"./types\";\n\ntype UpdateHooksMap = Map<\n unknown,\n Array<\n (\n nextState: ResourceState<unknown>,\n previousState: ResourceState<unknown>\n ) => void\n >\n>;\n\nconst updateHooksMap = new WeakMap<object, UpdateHooksMap>();\n\nexport abstract class BaseStore<\n TEnum extends Record<string, string | number>,\n TData extends { [K in keyof TEnum]: ResourceState<unknown> }\n> implements IStore<TData>\n{\n private readonly signalsState = new Map<\n keyof TEnum,\n WritableSignal<TData[keyof TEnum]>\n >();\n\n protected constructor(protected readonly storeEnum: TEnum) {\n this.initializeState();\n updateHooksMap.set(this, new Map());\n }\n\n get<K extends keyof TData>(key: K): WritableSignal<TData[K]> {\n return this.signalsState.get(key.toString()) as WritableSignal<TData[K]>;\n }\n\n onUpdate<K extends keyof TData>(\n key: K,\n callback: (state: TData[K], previousState: TData[K]) => void\n ): () => void {\n const hooks = updateHooksMap.get(this)!;\n if (!hooks.has(key)) {\n hooks.set(key, []);\n }\n hooks\n .get(key)!\n .push(\n callback as (\n nextState: ResourceState<unknown>,\n previousState: ResourceState<unknown>\n ) => void\n );\n\n return () => {\n const hooksMap = hooks.get(key);\n if (!hooksMap) {\n return;\n }\n const index = hooksMap.indexOf(\n callback as (\n nextState: ResourceState<unknown>,\n previousState: ResourceState<unknown>\n ) => void\n );\n if (index > -1) {\n hooksMap.splice(index, 1);\n }\n };\n }\n\n update<K extends keyof TData>(key: K, newState: Partial<TData[K]>): void {\n const currentState = this.signalsState.get(key.toString());\n if (!currentState) {\n return;\n }\n\n const previousState = currentState() as TData[K];\n currentState.update((state) => ({\n ...state,\n ...newState,\n }));\n\n const updatedState = currentState() as TData[K];\n this.notifyUpdateHooks(key, updatedState, previousState);\n }\n\n clearAll(): void {\n Object.keys(this.storeEnum).forEach((key) => {\n this.clear(key as keyof TData);\n });\n }\n\n clear<K extends keyof TData>(key: K): void {\n const currentState = this.signalsState.get(key.toString());\n if (!currentState) {\n return;\n }\n\n const previousState = currentState() as TData[K];\n const _typedKey = key as keyof TEnum;\n currentState.set({\n data: undefined,\n isLoading: false,\n status: undefined,\n errors: undefined,\n } as TData[typeof _typedKey]);\n\n const nextState = currentState() as TData[K];\n this.notifyUpdateHooks(key, nextState, previousState);\n }\n\n startLoading<K extends keyof TData>(key: K): void {\n const currentState = this.signalsState.get(key.toString());\n if (!currentState) {\n return;\n }\n\n const _typedKey = key as keyof TEnum;\n currentState.update(\n (state) =>\n ({\n ...state,\n status: undefined,\n isLoading: true,\n errors: undefined,\n } as TData[typeof _typedKey])\n );\n }\n\n stopLoading<K extends keyof TData>(key: K): void {\n const currentState = this.signalsState.get(key.toString());\n if (!currentState) {\n return;\n }\n\n const _typedKey = key as keyof TEnum;\n currentState.update(\n (state) =>\n ({\n ...state,\n isLoading: false,\n status: undefined,\n errors: undefined,\n } as TData[typeof _typedKey])\n );\n }\n\n updateKeyedOne<K extends keyof TData>(\n key: K,\n resourceKey: KeyedResourceKey,\n entity: unknown\n ): void {\n const currentState = this.signalsState.get(key.toString());\n if (!currentState) {\n return;\n }\n\n const state = currentState();\n const data = isKeyedResourceData(state.data)\n ? state.data\n : createKeyedResourceData();\n\n const nextErrors = { ...data.errors };\n delete nextErrors[resourceKey];\n\n const nextData = {\n ...data,\n entities: {\n ...data.entities,\n [resourceKey]: entity,\n },\n isLoading: {\n ...data.isLoading,\n [resourceKey]: false,\n },\n status: {\n ...data.status,\n [resourceKey]: \"Success\" as const,\n },\n errors: nextErrors,\n };\n\n this.update(key, {\n data: nextData as unknown,\n isLoading: isAnyKeyLoading(nextData.isLoading),\n status: undefined,\n errors: undefined,\n } as Partial<TData[K]>);\n }\n\n clearKeyedOne<K extends keyof TData>(\n key: K,\n resourceKey: KeyedResourceKey\n ): void {\n const currentState = this.signalsState.get(key.toString());\n if (!currentState) {\n return;\n }\n\n const previousState = currentState() as TData[K];\n const state = previousState as ResourceState<unknown>;\n if (!isKeyedResourceData(state.data)) {\n return;\n }\n\n const data = state.data;\n\n const nextEntities = { ...data.entities };\n delete nextEntities[resourceKey];\n\n const nextIsLoading = { ...data.isLoading };\n delete nextIsLoading[resourceKey];\n\n const nextStatus = { ...data.status };\n delete nextStatus[resourceKey];\n\n const nextErrors = { ...data.errors };\n delete nextErrors[resourceKey];\n\n const nextData = {\n ...data,\n entities: nextEntities,\n isLoading: nextIsLoading,\n status: nextStatus,\n errors: nextErrors,\n };\n\n const _typedKey = key as keyof TEnum;\n currentState.update(\n (prev) =>\n ({\n ...prev,\n data: nextData as unknown,\n status: undefined,\n isLoading: isAnyKeyLoading(nextIsLoading),\n errors: undefined,\n } as TData[typeof _typedKey])\n );\n\n const updatedState = currentState() as TData[K];\n this.notifyUpdateHooks(key, updatedState, previousState);\n }\n\n startKeyedLoading<K extends keyof TData>(\n key: K,\n resourceKey: KeyedResourceKey\n ): void {\n const currentState = this.signalsState.get(key.toString());\n if (!currentState) {\n return;\n }\n\n const _typedKey = key as keyof TEnum;\n const state = currentState();\n if (!isKeyedResourceData(state.data)) {\n this.startLoading(key);\n return;\n }\n\n const previousState = state as TData[K];\n const data = state.data;\n\n const nextIsLoading = {\n ...data.isLoading,\n [resourceKey]: true,\n } as typeof data.isLoading;\n\n const nextStatus: typeof data.status = {\n ...data.status,\n };\n delete nextStatus[resourceKey];\n\n const nextErrors: typeof data.errors = {\n ...data.errors,\n };\n delete nextErrors[resourceKey];\n\n const nextData = {\n ...data,\n isLoading: nextIsLoading,\n status: nextStatus,\n errors: nextErrors,\n };\n\n currentState.update(\n (previous) =>\n ({\n ...previous,\n data: nextData,\n status: undefined,\n isLoading: isAnyKeyLoading(nextIsLoading),\n errors: undefined,\n } as TData[typeof _typedKey])\n );\n\n const updatedState = currentState() as TData[K];\n this.notifyUpdateHooks(key, updatedState, previousState);\n }\n\n private notifyUpdateHooks<K extends keyof TData>(\n key: K,\n nextState: TData[K],\n previousState: TData[K]\n ): void {\n const hooks = updateHooksMap.get(this);\n const keyHooks = hooks?.get(key);\n if (!keyHooks) {\n return;\n }\n\n keyHooks.forEach((hook) =>\n hook(\n nextState as ResourceState<unknown>,\n previousState as ResourceState<unknown>\n )\n );\n }\n\n private initializeState(): void {\n Object.keys(this.storeEnum).forEach((key) => {\n const _typedKey = key as keyof TEnum;\n const initialState: ResourceState<unknown> = {\n data: undefined,\n isLoading: false,\n status: undefined,\n errors: undefined,\n };\n this.signalsState.set(\n _typedKey,\n signal<TData[typeof _typedKey]>(initialState as TData[typeof _typedKey])\n );\n });\n }\n}\n","import { signal, WritableSignal } from \"@angular/core\";\nimport {\n isAnyKeyLoading,\n isKeyedResourceData,\n createKeyedResourceData,\n type ResourceState,\n type KeyedResourceKey,\n} from \"@flurryx/core\";\nimport type { IStore } from \"./types\";\n\ntype UpdateCallback = (\n nextState: ResourceState<unknown>,\n previousState: ResourceState<unknown>\n) => void;\n\nfunction createDefaultState<T>(): ResourceState<T> {\n return {\n data: undefined,\n isLoading: false,\n status: undefined,\n errors: undefined,\n };\n}\n\n/**\n * Lazy store that creates signals on first access.\n * Used by the `Store.for<Config>().build()` API where keys are\n * known only at the type level (no runtime enum).\n */\nexport class LazyStore<TData extends Record<string, ResourceState<unknown>>>\n implements IStore<TData>\n{\n private readonly signals = new Map<\n string,\n WritableSignal<ResourceState<unknown>>\n >();\n private readonly hooks = new Map<string, UpdateCallback[]>();\n\n private getOrCreate<K extends keyof TData & string>(\n key: K\n ): WritableSignal<TData[K]> {\n let sig = this.signals.get(key);\n if (!sig) {\n sig = signal<ResourceState<unknown>>(createDefaultState());\n this.signals.set(key, sig);\n }\n return sig as WritableSignal<TData[K]>;\n }\n\n get<K extends keyof TData & string>(key: K): WritableSignal<TData[K]> {\n return this.getOrCreate(key);\n }\n\n update<K extends keyof TData & string>(\n key: K,\n newState: Partial<TData[K]>\n ): void {\n const sig = this.getOrCreate(key);\n const previousState = sig();\n sig.update((state) => ({ ...state, ...newState }));\n const nextState = sig();\n this.notifyHooks(key, nextState, previousState);\n }\n\n clear<K extends keyof TData & string>(key: K): void {\n const sig = this.getOrCreate(key);\n const previousState = sig();\n sig.set(createDefaultState() as TData[K]);\n const nextState = sig();\n this.notifyHooks(key, nextState, previousState);\n }\n\n clearAll(): void {\n for (const key of this.signals.keys()) {\n this.clear(key as keyof TData & string);\n }\n }\n\n startLoading<K extends keyof TData & string>(key: K): void {\n const sig = this.getOrCreate(key);\n sig.update(\n (state) =>\n ({\n ...state,\n status: undefined,\n isLoading: true,\n errors: undefined,\n } as TData[K])\n );\n }\n\n stopLoading<K extends keyof TData & string>(key: K): void {\n const sig = this.getOrCreate(key);\n sig.update(\n (state) =>\n ({\n ...state,\n isLoading: false,\n status: undefined,\n errors: undefined,\n } as TData[K])\n );\n }\n\n updateKeyedOne<K extends keyof TData & string>(\n key: K,\n resourceKey: KeyedResourceKey,\n entity: unknown\n ): void {\n const sig = this.getOrCreate(key);\n const state = sig();\n const data = isKeyedResourceData(state.data)\n ? state.data\n : createKeyedResourceData();\n\n const nextErrors = { ...data.errors };\n delete nextErrors[resourceKey];\n\n const nextData = {\n ...data,\n entities: { ...data.entities, [resourceKey]: entity },\n isLoading: { ...data.isLoading, [resourceKey]: false },\n status: { ...data.status, [resourceKey]: \"Success\" as const },\n errors: nextErrors,\n };\n\n this.update(key, {\n data: nextData as unknown,\n isLoading: isAnyKeyLoading(nextData.isLoading),\n status: undefined,\n errors: undefined,\n } as Partial<TData[K]>);\n }\n\n clearKeyedOne<K extends keyof TData & string>(\n key: K,\n resourceKey: KeyedResourceKey\n ): void {\n const sig = this.getOrCreate(key);\n const state = sig();\n if (!isKeyedResourceData(state.data)) {\n return;\n }\n\n const data = state.data;\n const previousState = state as TData[K];\n\n const nextEntities = { ...data.entities };\n delete nextEntities[resourceKey];\n\n const nextIsLoading = { ...data.isLoading };\n delete nextIsLoading[resourceKey];\n\n const nextStatus = { ...data.status };\n delete nextStatus[resourceKey];\n\n const nextErrors = { ...data.errors };\n delete nextErrors[resourceKey];\n\n const nextData = {\n ...data,\n entities: nextEntities,\n isLoading: nextIsLoading,\n status: nextStatus,\n errors: nextErrors,\n };\n\n sig.update(\n (prev) =>\n ({\n ...prev,\n data: nextData as unknown,\n status: undefined,\n isLoading: isAnyKeyLoading(nextIsLoading),\n errors: undefined,\n } as TData[K])\n );\n\n const updatedState = sig() as TData[K];\n this.notifyHooks(key, updatedState, previousState);\n }\n\n startKeyedLoading<K extends keyof TData & string>(\n key: K,\n resourceKey: KeyedResourceKey\n ): void {\n const sig = this.getOrCreate(key);\n const state = sig();\n if (!isKeyedResourceData(state.data)) {\n this.startLoading(key);\n return;\n }\n\n const previousState = state as TData[K];\n const data = state.data;\n\n const nextIsLoading = {\n ...data.isLoading,\n [resourceKey]: true,\n } as typeof data.isLoading;\n\n const nextStatus: typeof data.status = { ...data.status };\n delete nextStatus[resourceKey];\n\n const nextErrors: typeof data.errors = { ...data.errors };\n delete nextErrors[resourceKey];\n\n const nextData = {\n ...data,\n isLoading: nextIsLoading,\n status: nextStatus,\n errors: nextErrors,\n };\n\n sig.update(\n (previous) =>\n ({\n ...previous,\n data: nextData,\n status: undefined,\n isLoading: isAnyKeyLoading(nextIsLoading),\n errors: undefined,\n } as TData[K])\n );\n\n const updatedState = sig() as TData[K];\n this.notifyHooks(key, updatedState, previousState);\n }\n\n onUpdate<K extends keyof TData & string>(\n key: K,\n callback: (state: TData[K], previousState: TData[K]) => void\n ): () => void {\n if (!this.hooks.has(key)) {\n this.hooks.set(key, []);\n }\n const typedCallback = callback as UpdateCallback;\n this.hooks.get(key)!.push(typedCallback);\n\n return () => {\n const keyHooks = this.hooks.get(key);\n if (!keyHooks) {\n return;\n }\n const index = keyHooks.indexOf(typedCallback);\n if (index > -1) {\n keyHooks.splice(index, 1);\n }\n };\n }\n\n private notifyHooks<K extends keyof TData & string>(\n key: K,\n nextState: TData[K],\n previousState: TData[K]\n ): void {\n const keyHooks = this.hooks.get(key);\n if (!keyHooks) {\n return;\n }\n keyHooks.forEach((hook) =>\n hook(\n nextState as ResourceState<unknown>,\n previousState as ResourceState<unknown>\n )\n );\n }\n}\n","import { InjectionToken, inject } from \"@angular/core\";\nimport { BaseStore } from \"./base-store\";\nimport { DynamicStore } from \"./dynamic-store\";\nimport { LazyStore } from \"./lazy-store\";\nimport { mirrorKey } from \"./mirror-key\";\nimport { collectKeyed } from \"./collect-keyed\";\nimport { resource } from \"./resource\";\nimport type { ResourceState, KeyedResourceKey } from \"@flurryx/core\";\nimport type {\n StoreConfig,\n ResourceDef,\n InferEnum,\n InferData,\n ConfigToData,\n IStore,\n} from \"./types\";\n\n// ---------------------------------------------------------------------------\n// Mirror definition — accumulated by builders, wired up in build() factory\n// ---------------------------------------------------------------------------\n\ninterface MirrorDef {\n readonly sourceToken: InjectionToken<\n IStore<Record<string, ResourceState<unknown>>>\n >;\n readonly sourceKey: string;\n readonly targetKey: string;\n}\n\nfunction wireMirrors<\n TStore extends IStore<Record<string, ResourceState<unknown>>>\n>(store: TStore, mirrors: readonly MirrorDef[]): TStore {\n for (const def of mirrors) {\n const sourceStore = inject(def.sourceToken);\n mirrorKey(sourceStore, def.sourceKey, store, def.targetKey);\n }\n return store;\n}\n\n// ---------------------------------------------------------------------------\n// MirrorKeyed definition — accumulated by builders, wired up in build()\n// ---------------------------------------------------------------------------\n\ninterface MirrorKeyedDef {\n readonly sourceToken: InjectionToken<\n IStore<Record<string, ResourceState<unknown>>>\n >;\n readonly sourceKey: string;\n readonly targetKey: string;\n readonly extractId: (data: unknown) => KeyedResourceKey | undefined;\n}\n\nfunction wireMirrorKeyed<\n TStore extends IStore<Record<string, ResourceState<unknown>>>\n>(store: TStore, defs: readonly MirrorKeyedDef[]): TStore {\n for (const def of defs) {\n const sourceStore = inject(def.sourceToken);\n collectKeyed(sourceStore, def.sourceKey, store, def.targetKey, {\n extractId: def.extractId,\n });\n }\n return store;\n}\n\n// ---------------------------------------------------------------------------\n// Unconstrained builder (existing API)\n// ---------------------------------------------------------------------------\n\n/**\n * Intermediate builder step after .resource('key') — awaits .as<T>().\n */\ninterface AsStep<TAccum extends StoreConfig, TKey extends string> {\n as<T>(): StoreBuilder<TAccum & Record<TKey, ResourceDef<T>>>;\n}\n\n/**\n * Fluent builder for creating stores.\n * Accumulates resource definitions then produces an InjectionToken on .build().\n */\ninterface StoreBuilder<TAccum extends StoreConfig> {\n resource<TKey extends string>(key: TKey): AsStep<TAccum, TKey>;\n mirror<TSourceData extends Record<string, ResourceState<unknown>>>(\n source: InjectionToken<IStore<TSourceData>>,\n sourceKey: keyof TSourceData & string,\n targetKey?: keyof TAccum & string\n ): StoreBuilder<TAccum>;\n mirrorKeyed<\n TSourceData extends Record<string, ResourceState<unknown>>,\n TEntity\n >(\n source: InjectionToken<IStore<TSourceData>>,\n sourceKey: keyof TSourceData & string,\n options: {\n extractId: (data: TEntity | undefined) => KeyedResourceKey | undefined;\n },\n targetKey?: keyof TAccum & string\n ): StoreBuilder<TAccum>;\n build(): InjectionToken<BaseStore<InferEnum<TAccum>, InferData<TAccum>>>;\n}\n\nfunction createBuilder<TAccum extends StoreConfig>(\n accum: TAccum,\n mirrors: readonly MirrorDef[] = [],\n mirrorKeyedDefs: readonly MirrorKeyedDef[] = []\n): StoreBuilder<TAccum> {\n return {\n resource<TKey extends string>(key: TKey): AsStep<TAccum, TKey> {\n return {\n as<T>(): StoreBuilder<TAccum & Record<TKey, ResourceDef<T>>> {\n const nextAccum = {\n ...accum,\n [key]: resource<T>(),\n } as TAccum & Record<TKey, ResourceDef<T>>;\n return createBuilder(nextAccum, mirrors, mirrorKeyedDefs);\n },\n };\n },\n mirror(source, sourceKey, targetKey?) {\n const def: MirrorDef = {\n sourceToken: source as InjectionToken<\n IStore<Record<string, ResourceState<unknown>>>\n >,\n sourceKey,\n targetKey: (targetKey ?? sourceKey) as string,\n };\n return createBuilder(accum, [...mirrors, def], mirrorKeyedDefs);\n },\n mirrorKeyed(source, sourceKey, options, targetKey?) {\n const def: MirrorKeyedDef = {\n sourceToken: source as InjectionToken<\n IStore<Record<string, ResourceState<unknown>>>\n >,\n sourceKey,\n targetKey: (targetKey ?? sourceKey) as string,\n extractId: options.extractId as (\n data: unknown\n ) => KeyedResourceKey | undefined,\n };\n return createBuilder(accum, mirrors, [...mirrorKeyedDefs, def]);\n },\n build() {\n return new InjectionToken<\n BaseStore<InferEnum<TAccum>, InferData<TAccum>>\n >(\"FlurryxStore\", {\n providedIn: \"root\",\n factory: () => {\n const store = new DynamicStore(accum);\n wireMirrors(store, mirrors);\n wireMirrorKeyed(store, mirrorKeyedDefs);\n return store as BaseStore<InferEnum<TAccum>, InferData<TAccum>>;\n },\n });\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// Constrained builder (.for(enum) API)\n// ---------------------------------------------------------------------------\n\n/** Keys from the enum that have NOT yet been defined. */\ntype Remaining<\n TEnum extends Record<string, string>,\n TAccum extends StoreConfig\n> = Exclude<keyof TEnum & string, keyof TAccum>;\n\n/** Intermediate .as<T>() step for the constrained builder. */\ninterface ConstrainedAsStep<\n TEnum extends Record<string, string>,\n TAccum extends StoreConfig,\n TKey extends string\n> {\n as<T>(): ConstrainedBuilder<TEnum, TAccum & Record<TKey, ResourceDef<T>>>;\n}\n\n/**\n * Constrained builder — only allows keys from the enum that haven't been\n * defined yet. `.build()` is only available when all keys are accounted for.\n */\ntype ConstrainedBuilder<\n TEnum extends Record<string, string>,\n TAccum extends StoreConfig\n> = [Remaining<TEnum, TAccum>] extends [never]\n ? {\n mirror<TSourceData extends Record<string, ResourceState<unknown>>>(\n source: InjectionToken<IStore<TSourceData>>,\n sourceKey: keyof TSourceData & string,\n targetKey?: keyof TAccum & string\n ): ConstrainedBuilder<TEnum, TAccum>;\n mirrorKeyed<\n TSourceData extends Record<string, ResourceState<unknown>>,\n TEntity\n >(\n source: InjectionToken<IStore<TSourceData>>,\n sourceKey: keyof TSourceData & string,\n options: {\n extractId: (\n data: TEntity | undefined\n ) => KeyedResourceKey | undefined;\n },\n targetKey?: keyof TAccum & string\n ): ConstrainedBuilder<TEnum, TAccum>;\n build(): InjectionToken<BaseStore<InferEnum<TAccum>, InferData<TAccum>>>;\n }\n : {\n resource<TKey extends Remaining<TEnum, TAccum>>(\n key: TKey\n ): ConstrainedAsStep<TEnum, TAccum, TKey>;\n };\n\nfunction createConstrainedBuilder<\n TEnum extends Record<string, string>,\n TAccum extends StoreConfig\n>(\n _enumObj: TEnum,\n accum: TAccum,\n mirrors: readonly MirrorDef[] = [],\n mirrorKeyedDefs: readonly MirrorKeyedDef[] = []\n): ConstrainedBuilder<TEnum, TAccum> {\n return {\n resource<TKey extends string>(\n key: TKey\n ): ConstrainedAsStep<TEnum, TAccum, TKey> {\n return {\n as<T>(): ConstrainedBuilder<\n TEnum,\n TAccum & Record<TKey, ResourceDef<T>>\n > {\n const nextAccum = {\n ...accum,\n [key]: resource<T>(),\n } as TAccum & Record<TKey, ResourceDef<T>>;\n return createConstrainedBuilder(\n _enumObj,\n nextAccum,\n mirrors,\n mirrorKeyedDefs\n );\n },\n };\n },\n mirror(\n source: InjectionToken<IStore<Record<string, ResourceState<unknown>>>>,\n sourceKey: string,\n targetKey?: string\n ) {\n const def: MirrorDef = {\n sourceToken: source,\n sourceKey,\n targetKey: targetKey ?? sourceKey,\n };\n return createConstrainedBuilder(\n _enumObj,\n accum,\n [...mirrors, def],\n mirrorKeyedDefs\n );\n },\n mirrorKeyed(\n source: InjectionToken<IStore<Record<string, ResourceState<unknown>>>>,\n sourceKey: string,\n options: {\n extractId: (data: unknown) => KeyedResourceKey | undefined;\n },\n targetKey?: string\n ) {\n const def: MirrorKeyedDef = {\n sourceToken: source,\n sourceKey,\n targetKey: targetKey ?? sourceKey,\n extractId: options.extractId,\n };\n return createConstrainedBuilder(_enumObj, accum, mirrors, [\n ...mirrorKeyedDefs,\n def,\n ]);\n },\n build() {\n return new InjectionToken<\n BaseStore<InferEnum<TAccum>, InferData<TAccum>>\n >(\"FlurryxStore\", {\n providedIn: \"root\",\n factory: () => {\n const store = new DynamicStore(accum);\n wireMirrors(store, mirrors);\n wireMirrorKeyed(store, mirrorKeyedDefs);\n return store as BaseStore<InferEnum<TAccum>, InferData<TAccum>>;\n },\n });\n },\n } as ConstrainedBuilder<TEnum, TAccum>;\n}\n\n// ---------------------------------------------------------------------------\n// Interface-based builder (Store.for<Config>() API)\n// ---------------------------------------------------------------------------\n\ninterface InterfaceBuilder<TConfig extends Record<string, unknown>> {\n mirror<TSourceData extends Record<string, ResourceState<unknown>>>(\n source: InjectionToken<IStore<TSourceData>>,\n sourceKey: keyof TSourceData & string,\n targetKey?: keyof TConfig & string\n ): InterfaceBuilder<TConfig>;\n mirrorKeyed<\n TSourceData extends Record<string, ResourceState<unknown>>,\n TEntity\n >(\n source: InjectionToken<IStore<TSourceData>>,\n sourceKey: keyof TSourceData & string,\n options: {\n extractId: (data: TEntity | undefined) => KeyedResourceKey | undefined;\n },\n targetKey?: keyof TConfig & string\n ): InterfaceBuilder<TConfig>;\n build(): InjectionToken<IStore<ConfigToData<TConfig>>>;\n}\n\nfunction createInterfaceBuilder<TConfig extends Record<string, unknown>>(\n mirrors: readonly MirrorDef[] = [],\n mirrorKeyedDefs: readonly MirrorKeyedDef[] = []\n): InterfaceBuilder<TConfig> {\n return {\n mirror(source, sourceKey, targetKey?) {\n const def: MirrorDef = {\n sourceToken: source as InjectionToken<\n IStore<Record<string, ResourceState<unknown>>>\n >,\n sourceKey,\n targetKey: (targetKey ?? sourceKey) as string,\n };\n return createInterfaceBuilder<TConfig>(\n [...mirrors, def],\n mirrorKeyedDefs\n );\n },\n mirrorKeyed(source, sourceKey, options, targetKey?) {\n const def: MirrorKeyedDef = {\n sourceToken: source as InjectionToken<\n IStore<Record<string, ResourceState<unknown>>>\n >,\n sourceKey,\n targetKey: (targetKey ?? sourceKey) as string,\n extractId: options.extractId as (\n data: unknown\n ) => KeyedResourceKey | undefined,\n };\n return createInterfaceBuilder<TConfig>(mirrors, [\n ...mirrorKeyedDefs,\n def,\n ]);\n },\n build() {\n return new InjectionToken(\"FlurryxStore\", {\n providedIn: \"root\",\n factory: () => {\n const store = new LazyStore() as IStore<\n Record<string, ResourceState<unknown>>\n >;\n wireMirrors(store, mirrors);\n wireMirrorKeyed(store, mirrorKeyedDefs);\n return store as unknown as IStore<ConfigToData<TConfig>>;\n },\n });\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// Public entry point\n// ---------------------------------------------------------------------------\n\ninterface StoreEntry {\n /**\n * Define a named resource slot.\n * Chain .as<T>() to assign its type, then continue with more .resource() calls\n * or call .build() when done.\n */\n resource<TKey extends string>(\n key: TKey\n ): {\n as<T>(): StoreBuilder<Record<TKey, ResourceDef<T>>>;\n };\n\n /**\n * Interface-based builder: pass a config interface as a generic.\n * No runtime argument needed — keys and types are inferred from the interface.\n *\n * @example\n * interface ChatStoreConfig {\n * SESSIONS: ChatSession[];\n * MESSAGES: ChatMessage[];\n * }\n * const ChatStore = Store.for<ChatStoreConfig>().build();\n */\n for<TConfig extends Record<string, unknown>>(): InterfaceBuilder<TConfig>;\n\n /**\n * Bind the builder to an enum object for compile-time key validation.\n *\n * @example\n * const Enum = { A: 'A', B: 'B' } as const;\n * const MyStore = Store.for(Enum)\n * .resource('A').as<string>()\n * .resource('B').as<number>()\n * .build();\n */\n for<TEnum extends Record<string, string>>(\n enumObj: TEnum\n ): ConstrainedBuilder<TEnum, Record<string, never>>;\n}\n\n/**\n * Fluent store builder entry point.\n *\n * @example\n * // Unconstrained\n * export const CustomersStore = Store\n * .resource('customers').as<Customer[]>()\n * .resource('customerDetails').as<Customer>()\n * .build();\n *\n * @example\n * // Constrained with enum\n * const Enum = { SESSIONS: 'SESSIONS', MESSAGES: 'MESSAGES' } as const;\n * export const ChatStore = Store.for(Enum)\n * .resource('SESSIONS').as<Session[]>()\n * .resource('MESSAGES').as<Message[]>()\n * .build();\n */\nexport const Store: StoreEntry = {\n ...createBuilder({} as StoreConfig),\n for(enumObj?: Record<string, string>) {\n if (arguments.length === 0) {\n return createInterfaceBuilder();\n }\n return createConstrainedBuilder(enumObj!, {} as Record<string, never>);\n },\n};\n","import { BaseStore } from './base-store';\nimport type { StoreConfig, InferEnum, InferData } from './types';\n\n/**\n * Internal concrete subclass of BaseStore.\n * Auto-generates an identity enum from config keys.\n * NOT publicly exported — consumers interact via BaseStore interface.\n */\nexport class DynamicStore<\n TConfig extends StoreConfig,\n> extends BaseStore<InferEnum<TConfig>, InferData<TConfig>> {\n constructor(config: TConfig) {\n const identityEnum = Object.keys(config).reduce(\n (acc, key) => ({ ...acc, [key]: key }),\n {} as InferEnum<TConfig>\n );\n super(identityEnum);\n }\n}\n","import type { ResourceState } from \"@flurryx/core\";\nimport type { IStore } from \"./types\";\n\nexport interface MirrorOptions {\n destroyRef?: { onDestroy: (fn: () => void) => void };\n}\n\n/**\n * Mirrors a resource key from a source store to a target store.\n * When the source key updates, the target key is updated with the same state.\n *\n * @param source - The store to mirror from\n * @param sourceKey - The key to watch on the source store\n * @param target - The store to mirror to\n * @param targetKeyOrOptions - Either the target key name or options (defaults source key)\n * @param options - Mirror options when a target key is provided\n * @returns Cleanup function to stop mirroring\n */\nexport function mirrorKey<\n TSource extends Record<string, ResourceState<unknown>>,\n TTarget extends Record<string, ResourceState<unknown>>\n>(\n source: IStore<TSource>,\n sourceKey: keyof TSource & string,\n target: IStore<TTarget>,\n targetKeyOrOptions?: (keyof TTarget & string) | MirrorOptions,\n options?: MirrorOptions\n): () => void {\n const resolvedTargetKey = (\n typeof targetKeyOrOptions === \"string\" ? targetKeyOrOptions : sourceKey\n ) as keyof TTarget & string;\n\n const resolvedOptions =\n typeof targetKeyOrOptions === \"object\" ? targetKeyOrOptions : options;\n\n const cleanup = source.onUpdate(sourceKey, (state) => {\n target.update(\n resolvedTargetKey,\n state as unknown as Partial<TTarget[keyof TTarget & string]>\n );\n });\n\n if (resolvedOptions?.destroyRef) {\n resolvedOptions.destroyRef.onDestroy(cleanup);\n }\n\n return cleanup;\n}\n","import type {\n ResourceState,\n KeyedResourceKey,\n KeyedResourceData,\n} from '@flurryx/core';\nimport { createKeyedResourceData, isAnyKeyLoading } from '@flurryx/core';\nimport type { IStore } from './types';\n\nexport interface CollectKeyedOptions<TEntity> {\n extractId: (data: TEntity | undefined) => KeyedResourceKey | undefined;\n destroyRef?: { onDestroy: (fn: () => void) => void };\n}\n\n/**\n * Accumulates single-entity resource fetches into a keyed cache on a target store.\n *\n * On each source update:\n * - If status is 'Success' and extractId returns a valid key, merges the entity\n * into the target's keyed resource data.\n * - If the source data is cleared and a previous entity existed, removes it from\n * the target's keyed data.\n *\n * @param source - The store containing the single-entity resource\n * @param sourceKey - The key to watch on the source store\n * @param target - The store to accumulate entities into\n * @param targetKeyOrOptions - Either the target key name or options (defaults source key)\n * @param options - Collect options when a target key is provided\n * @returns Cleanup function to stop collecting\n */\nexport function collectKeyed<\n TSource extends Record<string, ResourceState<unknown>>,\n TTarget extends Record<string, ResourceState<unknown>>,\n TEntity = unknown,\n>(\n source: IStore<TSource>,\n sourceKey: keyof TSource & string,\n target: IStore<TTarget>,\n targetKeyOrOptions?: (keyof TTarget & string) | CollectKeyedOptions<TEntity>,\n options?: CollectKeyedOptions<TEntity>,\n): () => void {\n const resolvedTargetKey = (\n typeof targetKeyOrOptions === 'string'\n ? targetKeyOrOptions\n : sourceKey\n ) as keyof TTarget & string;\n\n const resolvedOptions = (\n typeof targetKeyOrOptions === 'object' ? targetKeyOrOptions : options\n ) as CollectKeyedOptions<TEntity>;\n\n // Initialize target with empty keyed resource data\n target.update(resolvedTargetKey, {\n data: createKeyedResourceData(),\n } as Partial<TTarget[keyof TTarget & string]>);\n\n let previousId: KeyedResourceKey | undefined;\n\n const cleanup = source.onUpdate(sourceKey, (state) => {\n const resourceState = state as ResourceState<TEntity>;\n const currentId = resolvedOptions.extractId(resourceState.data);\n const currentTarget = target.get(resolvedTargetKey)();\n const currentKeyed = (currentTarget as ResourceState<unknown>).data as\n KeyedResourceData<KeyedResourceKey, TEntity> | undefined;\n\n if (!currentKeyed) {\n return;\n }\n\n if (resourceState.status === 'Success' && currentId !== undefined) {\n const newEntities = { ...currentKeyed.entities, [currentId]: resourceState.data };\n const newIsLoading = { ...currentKeyed.isLoading, [currentId]: false };\n const newStatus = { ...currentKeyed.status, [currentId]: resourceState.status };\n const newErrors = { ...currentKeyed.errors };\n delete newErrors[currentId];\n\n const updatedKeyed: KeyedResourceData<KeyedResourceKey, TEntity> = {\n entities: newEntities,\n isLoading: newIsLoading,\n status: newStatus,\n errors: newErrors,\n };\n\n target.update(resolvedTargetKey, {\n data: updatedKeyed,\n isLoading: isAnyKeyLoading(newIsLoading),\n status: 'Success',\n } as Partial<TTarget[keyof TTarget & string]>);\n\n previousId = currentId;\n } else if (resourceState.status === 'Error' && currentId !== undefined) {\n const newIsLoading = { ...currentKeyed.isLoading, [currentId]: false };\n const newStatus = { ...currentKeyed.status, [currentId]: resourceState.status };\n const newErrors = { ...currentKeyed.errors, [currentId]: resourceState.errors };\n\n const updatedKeyed: KeyedResourceData<KeyedResourceKey, TEntity> = {\n entities: { ...currentKeyed.entities },\n isLoading: newIsLoading,\n status: newStatus,\n errors: newErrors,\n };\n\n target.update(resolvedTargetKey, {\n data: updatedKeyed,\n isLoading: isAnyKeyLoading(newIsLoading),\n } as Partial<TTarget[keyof TTarget & string]>);\n\n previousId = currentId;\n } else if (resourceState.data === undefined && previousId !== undefined) {\n // Source cleared — remove previous entity from cache\n const { [previousId]: _removed, ...remainingEntities } = currentKeyed.entities;\n const { [previousId]: _removedLoading, ...remainingLoading } = currentKeyed.isLoading;\n const { [previousId]: _removedStatus, ...remainingStatus } = currentKeyed.status;\n const { [previousId]: _removedErrors, ...remainingErrors } = currentKeyed.errors;\n\n const updatedKeyed: KeyedResourceData<KeyedResourceKey, TEntity> = {\n entities: remainingEntities,\n isLoading: remainingLoading,\n status: remainingStatus,\n errors: remainingErrors,\n };\n\n target.update(resolvedTargetKey, {\n data: updatedKeyed,\n isLoading: isAnyKeyLoading(remainingLoading),\n } as Partial<TTarget[keyof TTarget & string]>);\n\n previousId = undefined;\n } else if (resourceState.isLoading && currentId !== undefined) {\n const newIsLoading = { ...currentKeyed.isLoading, [currentId]: true };\n\n const updatedKeyed: KeyedResourceData<KeyedResourceKey, TEntity> = {\n entities: { ...currentKeyed.entities },\n isLoading: newIsLoading,\n status: { ...currentKeyed.status },\n errors: { ...currentKeyed.errors },\n };\n\n target.update(resolvedTargetKey, {\n data: updatedKeyed,\n isLoading: true,\n } as Partial<TTarget[keyof TTarget & string]>);\n\n previousId = currentId;\n }\n });\n\n if (resolvedOptions?.destroyRef) {\n resolvedOptions.destroyRef.onDestroy(cleanup);\n }\n\n return cleanup;\n}\n","import type { ResourceDef } from './types';\n\n/**\n * Creates a phantom-typed resource definition marker.\n * Zero runtime cost — returns an empty object that only carries type info.\n *\n * @example\n * const config = {\n * customers: resource<Customer[]>(),\n * customerDetails: resource<Customer>(),\n * };\n */\nexport function resource<T>(): ResourceDef<T> {\n return {} as ResourceDef<T>;\n}\n"],"mappings":"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","names":["import_core","import_core","import_core","import_core"]}
package/dist/index.d.cts CHANGED
@@ -44,6 +44,9 @@ interface IStore<TData extends Record<string, ResourceState<unknown>>> {
44
44
  clearAll(): void;
45
45
  startLoading<K extends keyof TData & string>(key: K): void;
46
46
  stopLoading<K extends keyof TData & string>(key: K): void;
47
+ updateKeyedOne<K extends keyof TData & string>(key: K, resourceKey: KeyedResourceKey, entity: unknown): void;
48
+ clearKeyedOne<K extends keyof TData & string>(key: K, resourceKey: KeyedResourceKey): void;
49
+ startKeyedLoading<K extends keyof TData & string>(key: K, resourceKey: KeyedResourceKey): void;
47
50
  onUpdate<K extends keyof TData & string>(key: K, callback: (state: TData[K], previousState: TData[K]) => void): () => void;
48
51
  }
49
52
 
@@ -82,6 +85,9 @@ declare class LazyStore<TData extends Record<string, ResourceState<unknown>>> im
82
85
  clearAll(): void;
83
86
  startLoading<K extends keyof TData & string>(key: K): void;
84
87
  stopLoading<K extends keyof TData & string>(key: K): void;
88
+ updateKeyedOne<K extends keyof TData & string>(key: K, resourceKey: KeyedResourceKey, entity: unknown): void;
89
+ clearKeyedOne<K extends keyof TData & string>(key: K, resourceKey: KeyedResourceKey): void;
90
+ startKeyedLoading<K extends keyof TData & string>(key: K, resourceKey: KeyedResourceKey): void;
85
91
  onUpdate<K extends keyof TData & string>(key: K, callback: (state: TData[K], previousState: TData[K]) => void): () => void;
86
92
  private notifyHooks;
87
93
  }
@@ -99,6 +105,9 @@ interface AsStep<TAccum extends StoreConfig, TKey extends string> {
99
105
  interface StoreBuilder<TAccum extends StoreConfig> {
100
106
  resource<TKey extends string>(key: TKey): AsStep<TAccum, TKey>;
101
107
  mirror<TSourceData extends Record<string, ResourceState<unknown>>>(source: InjectionToken<IStore<TSourceData>>, sourceKey: keyof TSourceData & string, targetKey?: keyof TAccum & string): StoreBuilder<TAccum>;
108
+ mirrorKeyed<TSourceData extends Record<string, ResourceState<unknown>>, TEntity>(source: InjectionToken<IStore<TSourceData>>, sourceKey: keyof TSourceData & string, options: {
109
+ extractId: (data: TEntity | undefined) => KeyedResourceKey | undefined;
110
+ }, targetKey?: keyof TAccum & string): StoreBuilder<TAccum>;
102
111
  build(): InjectionToken<BaseStore<InferEnum<TAccum>, InferData<TAccum>>>;
103
112
  }
104
113
  /** Keys from the enum that have NOT yet been defined. */
@@ -113,12 +122,18 @@ interface ConstrainedAsStep<TEnum extends Record<string, string>, TAccum extends
113
122
  */
114
123
  type ConstrainedBuilder<TEnum extends Record<string, string>, TAccum extends StoreConfig> = [Remaining<TEnum, TAccum>] extends [never] ? {
115
124
  mirror<TSourceData extends Record<string, ResourceState<unknown>>>(source: InjectionToken<IStore<TSourceData>>, sourceKey: keyof TSourceData & string, targetKey?: keyof TAccum & string): ConstrainedBuilder<TEnum, TAccum>;
125
+ mirrorKeyed<TSourceData extends Record<string, ResourceState<unknown>>, TEntity>(source: InjectionToken<IStore<TSourceData>>, sourceKey: keyof TSourceData & string, options: {
126
+ extractId: (data: TEntity | undefined) => KeyedResourceKey | undefined;
127
+ }, targetKey?: keyof TAccum & string): ConstrainedBuilder<TEnum, TAccum>;
116
128
  build(): InjectionToken<BaseStore<InferEnum<TAccum>, InferData<TAccum>>>;
117
129
  } : {
118
130
  resource<TKey extends Remaining<TEnum, TAccum>>(key: TKey): ConstrainedAsStep<TEnum, TAccum, TKey>;
119
131
  };
120
132
  interface InterfaceBuilder<TConfig extends Record<string, unknown>> {
121
133
  mirror<TSourceData extends Record<string, ResourceState<unknown>>>(source: InjectionToken<IStore<TSourceData>>, sourceKey: keyof TSourceData & string, targetKey?: keyof TConfig & string): InterfaceBuilder<TConfig>;
134
+ mirrorKeyed<TSourceData extends Record<string, ResourceState<unknown>>, TEntity>(source: InjectionToken<IStore<TSourceData>>, sourceKey: keyof TSourceData & string, options: {
135
+ extractId: (data: TEntity | undefined) => KeyedResourceKey | undefined;
136
+ }, targetKey?: keyof TConfig & string): InterfaceBuilder<TConfig>;
122
137
  build(): InjectionToken<IStore<ConfigToData<TConfig>>>;
123
138
  }
124
139
  interface StoreEntry {
package/dist/index.d.ts CHANGED
@@ -44,6 +44,9 @@ interface IStore<TData extends Record<string, ResourceState<unknown>>> {
44
44
  clearAll(): void;
45
45
  startLoading<K extends keyof TData & string>(key: K): void;
46
46
  stopLoading<K extends keyof TData & string>(key: K): void;
47
+ updateKeyedOne<K extends keyof TData & string>(key: K, resourceKey: KeyedResourceKey, entity: unknown): void;
48
+ clearKeyedOne<K extends keyof TData & string>(key: K, resourceKey: KeyedResourceKey): void;
49
+ startKeyedLoading<K extends keyof TData & string>(key: K, resourceKey: KeyedResourceKey): void;
47
50
  onUpdate<K extends keyof TData & string>(key: K, callback: (state: TData[K], previousState: TData[K]) => void): () => void;
48
51
  }
49
52
 
@@ -82,6 +85,9 @@ declare class LazyStore<TData extends Record<string, ResourceState<unknown>>> im
82
85
  clearAll(): void;
83
86
  startLoading<K extends keyof TData & string>(key: K): void;
84
87
  stopLoading<K extends keyof TData & string>(key: K): void;
88
+ updateKeyedOne<K extends keyof TData & string>(key: K, resourceKey: KeyedResourceKey, entity: unknown): void;
89
+ clearKeyedOne<K extends keyof TData & string>(key: K, resourceKey: KeyedResourceKey): void;
90
+ startKeyedLoading<K extends keyof TData & string>(key: K, resourceKey: KeyedResourceKey): void;
85
91
  onUpdate<K extends keyof TData & string>(key: K, callback: (state: TData[K], previousState: TData[K]) => void): () => void;
86
92
  private notifyHooks;
87
93
  }
@@ -99,6 +105,9 @@ interface AsStep<TAccum extends StoreConfig, TKey extends string> {
99
105
  interface StoreBuilder<TAccum extends StoreConfig> {
100
106
  resource<TKey extends string>(key: TKey): AsStep<TAccum, TKey>;
101
107
  mirror<TSourceData extends Record<string, ResourceState<unknown>>>(source: InjectionToken<IStore<TSourceData>>, sourceKey: keyof TSourceData & string, targetKey?: keyof TAccum & string): StoreBuilder<TAccum>;
108
+ mirrorKeyed<TSourceData extends Record<string, ResourceState<unknown>>, TEntity>(source: InjectionToken<IStore<TSourceData>>, sourceKey: keyof TSourceData & string, options: {
109
+ extractId: (data: TEntity | undefined) => KeyedResourceKey | undefined;
110
+ }, targetKey?: keyof TAccum & string): StoreBuilder<TAccum>;
102
111
  build(): InjectionToken<BaseStore<InferEnum<TAccum>, InferData<TAccum>>>;
103
112
  }
104
113
  /** Keys from the enum that have NOT yet been defined. */
@@ -113,12 +122,18 @@ interface ConstrainedAsStep<TEnum extends Record<string, string>, TAccum extends
113
122
  */
114
123
  type ConstrainedBuilder<TEnum extends Record<string, string>, TAccum extends StoreConfig> = [Remaining<TEnum, TAccum>] extends [never] ? {
115
124
  mirror<TSourceData extends Record<string, ResourceState<unknown>>>(source: InjectionToken<IStore<TSourceData>>, sourceKey: keyof TSourceData & string, targetKey?: keyof TAccum & string): ConstrainedBuilder<TEnum, TAccum>;
125
+ mirrorKeyed<TSourceData extends Record<string, ResourceState<unknown>>, TEntity>(source: InjectionToken<IStore<TSourceData>>, sourceKey: keyof TSourceData & string, options: {
126
+ extractId: (data: TEntity | undefined) => KeyedResourceKey | undefined;
127
+ }, targetKey?: keyof TAccum & string): ConstrainedBuilder<TEnum, TAccum>;
116
128
  build(): InjectionToken<BaseStore<InferEnum<TAccum>, InferData<TAccum>>>;
117
129
  } : {
118
130
  resource<TKey extends Remaining<TEnum, TAccum>>(key: TKey): ConstrainedAsStep<TEnum, TAccum, TKey>;
119
131
  };
120
132
  interface InterfaceBuilder<TConfig extends Record<string, unknown>> {
121
133
  mirror<TSourceData extends Record<string, ResourceState<unknown>>>(source: InjectionToken<IStore<TSourceData>>, sourceKey: keyof TSourceData & string, targetKey?: keyof TConfig & string): InterfaceBuilder<TConfig>;
134
+ mirrorKeyed<TSourceData extends Record<string, ResourceState<unknown>>, TEntity>(source: InjectionToken<IStore<TSourceData>>, sourceKey: keyof TSourceData & string, options: {
135
+ extractId: (data: TEntity | undefined) => KeyedResourceKey | undefined;
136
+ }, targetKey?: keyof TConfig & string): InterfaceBuilder<TConfig>;
122
137
  build(): InjectionToken<IStore<ConfigToData<TConfig>>>;
123
138
  }
124
139
  interface StoreEntry {