@flurryx/store 0.8.0 → 0.8.1
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/README.md +17 -2
- package/dist/index.cjs +32 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +46 -39
- package/dist/index.d.ts +46 -39
- package/dist/index.js +31 -7
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -51,7 +51,8 @@ export const MyStore = Store.for(Enum)
|
|
|
51
51
|
| `get(key)` | Returns the `Signal` for a slot |
|
|
52
52
|
| `update(key, partial)` | Merges partial state (immutable spread) |
|
|
53
53
|
| `clear(key)` | Resets a slot to its initial empty state |
|
|
54
|
-
| `clearAll()` | Resets every slot |
|
|
54
|
+
| `clearAll()` | Resets every slot in one store |
|
|
55
|
+
| `clearAllStores()` | Resets every tracked store instance |
|
|
55
56
|
| `startLoading(key)` | Sets `isLoading: true`, clears `status` and `errors` |
|
|
56
57
|
| `stopLoading(key)` | Sets `isLoading: false`, clears `status` and `errors` |
|
|
57
58
|
| `onUpdate(key, callback)` | Registers a listener fired after `update` or `clear`. Returns an unsubscribe function |
|
|
@@ -84,6 +85,19 @@ store.clear('LIST');
|
|
|
84
85
|
|
|
85
86
|
// Clear every slot in the store
|
|
86
87
|
store.clearAll();
|
|
88
|
+
|
|
89
|
+
// Clear every tracked store instance in the app
|
|
90
|
+
clearAllStores();
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Import `clearAllStores` when you need a global cache reset, such as logout or tenant switching:
|
|
94
|
+
|
|
95
|
+
```typescript
|
|
96
|
+
import { clearAllStores } from "@flurryx/store";
|
|
97
|
+
|
|
98
|
+
logout() {
|
|
99
|
+
clearAllStores();
|
|
100
|
+
}
|
|
87
101
|
```
|
|
88
102
|
|
|
89
103
|
### Per-key clearing for keyed resources
|
|
@@ -133,7 +147,8 @@ export class InvoiceFacade {
|
|
|
133
147
|
| Method | Scope | Use when |
|
|
134
148
|
|---|---|---|
|
|
135
149
|
| `clear(key)` | Entire slot | Logging out, resetting a form, full refresh |
|
|
136
|
-
| `clearAll()` | Every slot |
|
|
150
|
+
| `clearAll()` | Every slot in one store | Reset one feature store |
|
|
151
|
+
| `clearAllStores()` | Every tracked store instance | Logout, tenant switch, full app cache reset |
|
|
137
152
|
| `clearKeyedOne(key, resourceKey)` | Single entity in a keyed slot | Deleting or invalidating one cached item |
|
|
138
153
|
|
|
139
154
|
## Store Mirroring
|
package/dist/index.cjs
CHANGED
|
@@ -23,6 +23,7 @@ __export(index_exports, {
|
|
|
23
23
|
BaseStore: () => BaseStore,
|
|
24
24
|
LazyStore: () => LazyStore,
|
|
25
25
|
Store: () => Store,
|
|
26
|
+
clearAllStores: () => clearAllStores,
|
|
26
27
|
collectKeyed: () => collectKeyed,
|
|
27
28
|
mirrorKey: () => mirrorKey
|
|
28
29
|
});
|
|
@@ -31,12 +32,26 @@ module.exports = __toCommonJS(index_exports);
|
|
|
31
32
|
// src/base-store.ts
|
|
32
33
|
var import_core = require("@angular/core");
|
|
33
34
|
var import_core2 = require("@flurryx/core");
|
|
35
|
+
|
|
36
|
+
// src/store-registry.ts
|
|
37
|
+
var trackedStores = /* @__PURE__ */ new Set();
|
|
38
|
+
function trackStore(store) {
|
|
39
|
+
trackedStores.add(store);
|
|
40
|
+
}
|
|
41
|
+
function clearAllStores() {
|
|
42
|
+
for (const store of [...trackedStores]) {
|
|
43
|
+
store.clearAll();
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// src/base-store.ts
|
|
34
48
|
var updateHooksMap = /* @__PURE__ */ new WeakMap();
|
|
35
49
|
var BaseStore = class {
|
|
36
50
|
constructor(storeEnum) {
|
|
37
51
|
this.storeEnum = storeEnum;
|
|
38
52
|
this.initializeState();
|
|
39
53
|
updateHooksMap.set(this, /* @__PURE__ */ new Map());
|
|
54
|
+
trackStore(this);
|
|
40
55
|
}
|
|
41
56
|
signalsState = /* @__PURE__ */ new Map();
|
|
42
57
|
get(key) {
|
|
@@ -285,6 +300,9 @@ function createDefaultState() {
|
|
|
285
300
|
var LazyStore = class {
|
|
286
301
|
signals = /* @__PURE__ */ new Map();
|
|
287
302
|
hooks = /* @__PURE__ */ new Map();
|
|
303
|
+
constructor() {
|
|
304
|
+
trackStore(this);
|
|
305
|
+
}
|
|
288
306
|
getOrCreate(key) {
|
|
289
307
|
let sig = this.signals.get(key);
|
|
290
308
|
if (!sig) {
|
|
@@ -603,7 +621,12 @@ function wireSelfMirrors(store, defs) {
|
|
|
603
621
|
if (def.sourceKey === def.targetKey) {
|
|
604
622
|
throw new Error(MIRROR_SELF_SAME_KEY_ERROR);
|
|
605
623
|
}
|
|
606
|
-
mirrorKey(
|
|
624
|
+
mirrorKey(
|
|
625
|
+
store,
|
|
626
|
+
def.sourceKey,
|
|
627
|
+
store,
|
|
628
|
+
def.targetKey
|
|
629
|
+
);
|
|
607
630
|
}
|
|
608
631
|
return store;
|
|
609
632
|
}
|
|
@@ -804,18 +827,20 @@ function createInterfaceBuilder(mirrors = [], mirrorKeyedDefs = [], selfMirrors
|
|
|
804
827
|
}
|
|
805
828
|
var Store = {
|
|
806
829
|
...createBuilder({}),
|
|
807
|
-
for
|
|
808
|
-
if (arguments.length === 0) {
|
|
809
|
-
return createInterfaceBuilder();
|
|
810
|
-
}
|
|
811
|
-
return createConstrainedBuilder(enumObj, {});
|
|
812
|
-
}
|
|
830
|
+
for: createStoreFor
|
|
813
831
|
};
|
|
832
|
+
function createStoreFor(enumObj) {
|
|
833
|
+
if (arguments.length === 0) {
|
|
834
|
+
return createInterfaceBuilder();
|
|
835
|
+
}
|
|
836
|
+
return createConstrainedBuilder(enumObj, {});
|
|
837
|
+
}
|
|
814
838
|
// Annotate the CommonJS export names for ESM import in node:
|
|
815
839
|
0 && (module.exports = {
|
|
816
840
|
BaseStore,
|
|
817
841
|
LazyStore,
|
|
818
842
|
Store,
|
|
843
|
+
clearAllStores,
|
|
819
844
|
collectKeyed,
|
|
820
845
|
mirrorKey
|
|
821
846
|
});
|
package/dist/index.cjs.map
CHANGED
|
@@ -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/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, type 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): Signal<TData[K]> {\n return this.signalsState.get(key.toString()) as unknown as Signal<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, type 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): Signal<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\ninterface SelfMirrorDef {\n readonly sourceKey: string;\n readonly targetKey: string;\n}\n\nconst MIRROR_SELF_SAME_KEY_ERROR =\n \"mirrorSelf source and target keys must be different\";\n\nfunction wireSelfMirrors<\n TStore extends IStore<Record<string, ResourceState<unknown>>>,\n>(store: TStore, defs: readonly SelfMirrorDef[]): TStore {\n for (const def of defs) {\n if (def.sourceKey === def.targetKey) {\n throw new Error(MIRROR_SELF_SAME_KEY_ERROR);\n }\n\n mirrorKey(store, 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 mirrorSelf(\n sourceKey: keyof TAccum & 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 selfMirrors: readonly SelfMirrorDef[] = [],\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(\n nextAccum,\n mirrors,\n mirrorKeyedDefs,\n selfMirrors,\n );\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(\n accum,\n [...mirrors, def],\n mirrorKeyedDefs,\n selfMirrors,\n );\n },\n mirrorSelf(sourceKey, targetKey) {\n const def: SelfMirrorDef = {\n sourceKey,\n targetKey,\n };\n return createBuilder(accum, mirrors, mirrorKeyedDefs, [\n ...selfMirrors,\n def,\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 createBuilder(\n accum,\n mirrors,\n [...mirrorKeyedDefs, def],\n selfMirrors,\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 wireSelfMirrors(store, selfMirrors);\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 mirrorSelf(\n sourceKey: keyof TAccum & 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 selfMirrors: readonly SelfMirrorDef[] = [],\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 selfMirrors,\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 selfMirrors,\n );\n },\n mirrorSelf(sourceKey: string, targetKey: string) {\n const def: SelfMirrorDef = {\n sourceKey,\n targetKey,\n };\n return createConstrainedBuilder(\n _enumObj,\n accum,\n mirrors,\n mirrorKeyedDefs,\n [...selfMirrors, def],\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(\n _enumObj,\n accum,\n mirrors,\n [...mirrorKeyedDefs, def],\n selfMirrors,\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 wireSelfMirrors(store, selfMirrors);\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 mirrorSelf(\n sourceKey: keyof TConfig & 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 selfMirrors: readonly SelfMirrorDef[] = [],\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 selfMirrors,\n );\n },\n mirrorSelf(sourceKey, targetKey) {\n const def: SelfMirrorDef = {\n sourceKey: sourceKey as string,\n targetKey: targetKey as string,\n };\n return createInterfaceBuilder<TConfig>(mirrors, mirrorKeyedDefs, [\n ...selfMirrors,\n def,\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>(\n mirrors,\n [...mirrorKeyedDefs, def],\n selfMirrors,\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 wireSelfMirrors(store, selfMirrors);\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"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/base-store.ts","../src/store-registry.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 { clearAllStores } from \"./store-registry\";\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, type 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\";\nimport { trackStore } from \"./store-registry\";\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 trackStore(this);\n }\n\n get<K extends keyof TData>(key: K): Signal<TData[K]> {\n return this.signalsState.get(key.toString()) as unknown as Signal<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","interface Clearable {\n clearAll(): void;\n}\n\nconst trackedStores = new Set<Clearable>();\n\nexport function trackStore(store: Clearable): void {\n trackedStores.add(store);\n}\n\nexport function clearAllStores(): void {\n for (const store of [...trackedStores]) {\n store.clearAll();\n }\n}\n\nexport function resetTrackedStoresForTests(): void {\n trackedStores.clear();\n}\n","import { signal, type 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, StoreDataShape, StoreKey } from \"./types\";\nimport { trackStore } from \"./store-registry\";\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 StoreDataShape<TData>>\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 constructor() {\n trackStore(this);\n }\n\n private getOrCreate<K extends StoreKey<TData>>(\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 StoreKey<TData>>(key: K): Signal<TData[K]> {\n return this.getOrCreate(key);\n }\n\n update<K extends StoreKey<TData>>(key: K, newState: Partial<TData[K]>): 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 StoreKey<TData>>(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 StoreKey<TData>);\n }\n }\n\n startLoading<K extends StoreKey<TData>>(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 StoreKey<TData>>(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 StoreKey<TData>>(\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 StoreKey<TData>>(\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 StoreKey<TData>>(\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 StoreKey<TData>>(\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 StoreKey<TData>>(\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 StoreDataShape,\n StoreKey,\n} from \"./types\";\n\ntype AnyStoreData = Record<string, ResourceState<unknown>>;\n\n// ---------------------------------------------------------------------------\n// Mirror definition — accumulated by builders, wired up in build() factory\n// ---------------------------------------------------------------------------\n\ninterface MirrorDef {\n readonly sourceToken: InjectionToken<IStore<AnyStoreData>>;\n readonly sourceKey: string;\n readonly targetKey: string;\n}\n\nfunction wireMirrors<\n TData extends StoreDataShape<TData>,\n TStore extends IStore<TData>,\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 as StoreKey<TData>);\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<IStore<AnyStoreData>>;\n readonly sourceKey: string;\n readonly targetKey: string;\n readonly extractId: (data: unknown) => KeyedResourceKey | undefined;\n}\n\nfunction wireMirrorKeyed<\n TData extends StoreDataShape<TData>,\n TStore extends IStore<TData>,\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 as StoreKey<TData>, {\n extractId: def.extractId,\n });\n }\n return store;\n}\n\ninterface SelfMirrorDef {\n readonly sourceKey: string;\n readonly targetKey: string;\n}\n\nconst MIRROR_SELF_SAME_KEY_ERROR =\n \"mirrorSelf source and target keys must be different\";\n\nfunction wireSelfMirrors<\n TData extends StoreDataShape<TData>,\n TStore extends IStore<TData>,\n>(store: TStore, defs: readonly SelfMirrorDef[]): TStore {\n for (const def of defs) {\n if (def.sourceKey === def.targetKey) {\n throw new Error(MIRROR_SELF_SAME_KEY_ERROR);\n }\n\n mirrorKey(\n store,\n def.sourceKey as StoreKey<TData>,\n store,\n def.targetKey as StoreKey<TData>,\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 StoreDataShape<TSourceData>>(\n source: InjectionToken<IStore<TSourceData>>,\n sourceKey: StoreKey<TSourceData>,\n targetKey?: StoreKey<TAccum>,\n ): StoreBuilder<TAccum>;\n mirrorSelf(\n sourceKey: StoreKey<TAccum>,\n targetKey: StoreKey<TAccum>,\n ): StoreBuilder<TAccum>;\n mirrorKeyed<\n TSourceData extends StoreDataShape<TSourceData>,\n TEntity,\n >(\n source: InjectionToken<IStore<TSourceData>>,\n sourceKey: StoreKey<TSourceData>,\n options: {\n extractId: (data: TEntity | undefined) => KeyedResourceKey | undefined;\n },\n targetKey?: StoreKey<TAccum>,\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 selfMirrors: readonly SelfMirrorDef[] = [],\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(\n nextAccum,\n mirrors,\n mirrorKeyedDefs,\n selfMirrors,\n );\n },\n };\n },\n mirror(source, sourceKey, targetKey?) {\n const def: MirrorDef = {\n sourceToken: source as InjectionToken<\n IStore<AnyStoreData>\n >,\n sourceKey: sourceKey as string,\n targetKey: (targetKey ?? sourceKey) as string,\n };\n return createBuilder(\n accum,\n [...mirrors, def],\n mirrorKeyedDefs,\n selfMirrors,\n );\n },\n mirrorSelf(sourceKey, targetKey) {\n const def: SelfMirrorDef = {\n sourceKey: sourceKey as string,\n targetKey: targetKey as string,\n };\n return createBuilder(accum, mirrors, mirrorKeyedDefs, [\n ...selfMirrors,\n def,\n ]);\n },\n mirrorKeyed(source, sourceKey, options, targetKey?) {\n const def: MirrorKeyedDef = {\n sourceToken: source as InjectionToken<\n IStore<AnyStoreData>\n >,\n sourceKey: sourceKey as string,\n targetKey: (targetKey ?? sourceKey) as string,\n extractId: options.extractId as (\n data: unknown,\n ) => KeyedResourceKey | undefined,\n };\n return createBuilder(\n accum,\n mirrors,\n [...mirrorKeyedDefs, def],\n selfMirrors,\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) as IStore<InferData<TAccum>>;\n wireMirrors(store, mirrors);\n wireMirrorKeyed(store, mirrorKeyedDefs);\n wireSelfMirrors(store, selfMirrors);\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 StoreDataShape<TSourceData>>(\n source: InjectionToken<IStore<TSourceData>>,\n sourceKey: StoreKey<TSourceData>,\n targetKey?: StoreKey<TAccum>,\n ): ConstrainedBuilder<TEnum, TAccum>;\n mirrorSelf(\n sourceKey: StoreKey<TAccum>,\n targetKey: StoreKey<TAccum>,\n ): ConstrainedBuilder<TEnum, TAccum>;\n mirrorKeyed<\n TSourceData extends StoreDataShape<TSourceData>,\n TEntity,\n >(\n source: InjectionToken<IStore<TSourceData>>,\n sourceKey: StoreKey<TSourceData>,\n options: {\n extractId: (\n data: TEntity | undefined,\n ) => KeyedResourceKey | undefined;\n },\n targetKey?: StoreKey<TAccum>,\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 selfMirrors: readonly SelfMirrorDef[] = [],\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 selfMirrors,\n );\n },\n };\n },\n mirror(\n source: InjectionToken<\n IStore<AnyStoreData>\n >,\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 selfMirrors,\n );\n },\n mirrorSelf(sourceKey: string, targetKey: string) {\n const def: SelfMirrorDef = {\n sourceKey,\n targetKey,\n };\n return createConstrainedBuilder(\n _enumObj,\n accum,\n mirrors,\n mirrorKeyedDefs,\n [...selfMirrors, def],\n );\n },\n mirrorKeyed(\n source: InjectionToken<\n IStore<AnyStoreData>\n >,\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(\n _enumObj,\n accum,\n mirrors,\n [...mirrorKeyedDefs, def],\n selfMirrors,\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) as IStore<InferData<TAccum>>;\n wireMirrors(store, mirrors);\n wireMirrorKeyed(store, mirrorKeyedDefs);\n wireSelfMirrors(store, selfMirrors);\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 object> {\n mirror<TSourceData extends StoreDataShape<TSourceData>>(\n source: InjectionToken<IStore<TSourceData>>,\n sourceKey: StoreKey<TSourceData>,\n targetKey?: StoreKey<ConfigToData<TConfig>>,\n ): InterfaceBuilder<TConfig>;\n mirrorSelf(\n sourceKey: StoreKey<ConfigToData<TConfig>>,\n targetKey: StoreKey<ConfigToData<TConfig>>,\n ): InterfaceBuilder<TConfig>;\n mirrorKeyed<\n TSourceData extends StoreDataShape<TSourceData>,\n TEntity,\n >(\n source: InjectionToken<IStore<TSourceData>>,\n sourceKey: StoreKey<TSourceData>,\n options: {\n extractId: (data: TEntity | undefined) => KeyedResourceKey | undefined;\n },\n targetKey?: StoreKey<ConfigToData<TConfig>>,\n ): InterfaceBuilder<TConfig>;\n build(): InjectionToken<IStore<ConfigToData<TConfig>>>;\n}\n\nfunction createInterfaceBuilder<TConfig extends object>(\n mirrors: readonly MirrorDef[] = [],\n mirrorKeyedDefs: readonly MirrorKeyedDef[] = [],\n selfMirrors: readonly SelfMirrorDef[] = [],\n): InterfaceBuilder<TConfig> {\n return {\n mirror(source, sourceKey, targetKey?) {\n const def: MirrorDef = {\n sourceToken: source as InjectionToken<\n IStore<AnyStoreData>\n >,\n sourceKey: sourceKey as string,\n targetKey: (targetKey ?? sourceKey) as string,\n };\n return createInterfaceBuilder<TConfig>(\n [...mirrors, def],\n mirrorKeyedDefs,\n selfMirrors,\n );\n },\n mirrorSelf(sourceKey, targetKey) {\n const def: SelfMirrorDef = {\n sourceKey: sourceKey as string,\n targetKey: targetKey as string,\n };\n return createInterfaceBuilder<TConfig>(mirrors, mirrorKeyedDefs, [\n ...selfMirrors,\n def,\n ]);\n },\n mirrorKeyed(source, sourceKey, options, targetKey?) {\n const def: MirrorKeyedDef = {\n sourceToken: source as InjectionToken<\n IStore<AnyStoreData>\n >,\n sourceKey: sourceKey as string,\n targetKey: (targetKey ?? sourceKey) as string,\n extractId: options.extractId as (\n data: unknown,\n ) => KeyedResourceKey | undefined,\n };\n return createInterfaceBuilder<TConfig>(\n mirrors,\n [...mirrorKeyedDefs, def],\n selfMirrors,\n );\n },\n build() {\n return new InjectionToken(\"FlurryxStore\", {\n providedIn: \"root\",\n factory: () => {\n const store = new LazyStore() as IStore<\n AnyStoreData\n >;\n wireMirrors(store, mirrors);\n wireMirrorKeyed(store, mirrorKeyedDefs);\n wireSelfMirrors(store, selfMirrors);\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 object>(): 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<never, 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: createStoreFor,\n};\n\nfunction createStoreFor<TConfig extends object>(): InterfaceBuilder<TConfig>;\nfunction createStoreFor<TEnum extends Record<string, string>>(\n enumObj: TEnum,\n): ConstrainedBuilder<TEnum, Record<never, never>>;\nfunction createStoreFor(enumObj?: Record<string, string>) {\n if (arguments.length === 0) {\n return createInterfaceBuilder();\n }\n\n return createConstrainedBuilder(enumObj!, {} as Record<never, never>);\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 { IStore, StoreDataShape, StoreKey } 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 StoreDataShape<TSource>,\n TTarget extends StoreDataShape<TTarget>\n>(\n source: IStore<TSource>,\n sourceKey: StoreKey<TSource>,\n target: IStore<TTarget>,\n targetKeyOrOptions?: StoreKey<TTarget> | MirrorOptions,\n options?: MirrorOptions\n): () => void {\n const resolvedTargetKey = (\n typeof targetKeyOrOptions === \"string\" ? targetKeyOrOptions : sourceKey\n ) as StoreKey<TTarget>;\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[StoreKey<TTarget>]>\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, StoreDataShape, StoreKey } 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 StoreDataShape<TSource>,\n TTarget extends StoreDataShape<TTarget>,\n TEntity = unknown,\n>(\n source: IStore<TSource>,\n sourceKey: StoreKey<TSource>,\n target: IStore<TTarget>,\n targetKeyOrOptions?: StoreKey<TTarget> | CollectKeyedOptions<TEntity>,\n options?: CollectKeyedOptions<TEntity>,\n): () => void {\n const resolvedTargetKey = (\n typeof targetKeyOrOptions === 'string'\n ? targetKeyOrOptions\n : sourceKey\n ) as StoreKey<TTarget>;\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[StoreKey<TTarget>]>);\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[StoreKey<TTarget>]>);\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[StoreKey<TTarget>]>);\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[StoreKey<TTarget>]>);\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[StoreKey<TTarget>]>);\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
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { Signal, InjectionToken } from '@angular/core';
|
|
2
2
|
import { ResourceState, KeyedResourceKey } from '@flurryx/core';
|
|
3
3
|
|
|
4
|
+
type StoreDataShape<TData> = {
|
|
5
|
+
[K in keyof TData]: ResourceState<unknown>;
|
|
6
|
+
};
|
|
7
|
+
type StoreKey<TData> = keyof TData & string;
|
|
4
8
|
/**
|
|
5
9
|
* Phantom-typed marker for a store resource slot.
|
|
6
10
|
* Carries type information at compile time with zero runtime cost.
|
|
@@ -31,23 +35,23 @@ type InferData<TConfig extends StoreConfig> = {
|
|
|
31
35
|
* Maps a plain config interface to ResourceState-wrapped data.
|
|
32
36
|
* e.g. { SESSIONS: ChatSession[] } -> { SESSIONS: ResourceState<ChatSession[]> }
|
|
33
37
|
*/
|
|
34
|
-
type ConfigToData<TConfig extends
|
|
38
|
+
type ConfigToData<TConfig extends object> = {
|
|
35
39
|
[K in keyof TConfig & string]: ResourceState<TConfig[K]>;
|
|
36
40
|
};
|
|
37
41
|
/**
|
|
38
42
|
* Shared store interface implemented by both BaseStore and LazyStore.
|
|
39
43
|
*/
|
|
40
|
-
interface IStore<TData extends
|
|
41
|
-
get<K extends
|
|
42
|
-
update<K extends
|
|
43
|
-
clear<K extends
|
|
44
|
+
interface IStore<TData extends StoreDataShape<TData>> {
|
|
45
|
+
get<K extends StoreKey<TData>>(key: K): Signal<TData[K]>;
|
|
46
|
+
update<K extends StoreKey<TData>>(key: K, newState: Partial<TData[K]>): void;
|
|
47
|
+
clear<K extends StoreKey<TData>>(key: K): void;
|
|
44
48
|
clearAll(): void;
|
|
45
|
-
startLoading<K extends
|
|
46
|
-
stopLoading<K extends
|
|
47
|
-
updateKeyedOne<K extends
|
|
48
|
-
clearKeyedOne<K extends
|
|
49
|
-
startKeyedLoading<K extends
|
|
50
|
-
onUpdate<K extends
|
|
49
|
+
startLoading<K extends StoreKey<TData>>(key: K): void;
|
|
50
|
+
stopLoading<K extends StoreKey<TData>>(key: K): void;
|
|
51
|
+
updateKeyedOne<K extends StoreKey<TData>>(key: K, resourceKey: KeyedResourceKey, entity: unknown): void;
|
|
52
|
+
clearKeyedOne<K extends StoreKey<TData>>(key: K, resourceKey: KeyedResourceKey): void;
|
|
53
|
+
startKeyedLoading<K extends StoreKey<TData>>(key: K, resourceKey: KeyedResourceKey): void;
|
|
54
|
+
onUpdate<K extends StoreKey<TData>>(key: K, callback: (state: TData[K], previousState: TData[K]) => void): () => void;
|
|
51
55
|
}
|
|
52
56
|
|
|
53
57
|
declare abstract class BaseStore<TEnum extends Record<string, string | number>, TData extends {
|
|
@@ -75,20 +79,21 @@ declare abstract class BaseStore<TEnum extends Record<string, string | number>,
|
|
|
75
79
|
* Used by the `Store.for<Config>().build()` API where keys are
|
|
76
80
|
* known only at the type level (no runtime enum).
|
|
77
81
|
*/
|
|
78
|
-
declare class LazyStore<TData extends
|
|
82
|
+
declare class LazyStore<TData extends StoreDataShape<TData>> implements IStore<TData> {
|
|
79
83
|
private readonly signals;
|
|
80
84
|
private readonly hooks;
|
|
85
|
+
constructor();
|
|
81
86
|
private getOrCreate;
|
|
82
|
-
get<K extends
|
|
83
|
-
update<K extends
|
|
84
|
-
clear<K extends
|
|
87
|
+
get<K extends StoreKey<TData>>(key: K): Signal<TData[K]>;
|
|
88
|
+
update<K extends StoreKey<TData>>(key: K, newState: Partial<TData[K]>): void;
|
|
89
|
+
clear<K extends StoreKey<TData>>(key: K): void;
|
|
85
90
|
clearAll(): void;
|
|
86
|
-
startLoading<K extends
|
|
87
|
-
stopLoading<K extends
|
|
88
|
-
updateKeyedOne<K extends
|
|
89
|
-
clearKeyedOne<K extends
|
|
90
|
-
startKeyedLoading<K extends
|
|
91
|
-
onUpdate<K extends
|
|
91
|
+
startLoading<K extends StoreKey<TData>>(key: K): void;
|
|
92
|
+
stopLoading<K extends StoreKey<TData>>(key: K): void;
|
|
93
|
+
updateKeyedOne<K extends StoreKey<TData>>(key: K, resourceKey: KeyedResourceKey, entity: unknown): void;
|
|
94
|
+
clearKeyedOne<K extends StoreKey<TData>>(key: K, resourceKey: KeyedResourceKey): void;
|
|
95
|
+
startKeyedLoading<K extends StoreKey<TData>>(key: K, resourceKey: KeyedResourceKey): void;
|
|
96
|
+
onUpdate<K extends StoreKey<TData>>(key: K, callback: (state: TData[K], previousState: TData[K]) => void): () => void;
|
|
92
97
|
private notifyHooks;
|
|
93
98
|
}
|
|
94
99
|
|
|
@@ -104,11 +109,11 @@ interface AsStep<TAccum extends StoreConfig, TKey extends string> {
|
|
|
104
109
|
*/
|
|
105
110
|
interface StoreBuilder<TAccum extends StoreConfig> {
|
|
106
111
|
resource<TKey extends string>(key: TKey): AsStep<TAccum, TKey>;
|
|
107
|
-
mirror<TSourceData extends
|
|
108
|
-
mirrorSelf(sourceKey:
|
|
109
|
-
mirrorKeyed<TSourceData extends
|
|
112
|
+
mirror<TSourceData extends StoreDataShape<TSourceData>>(source: InjectionToken<IStore<TSourceData>>, sourceKey: StoreKey<TSourceData>, targetKey?: StoreKey<TAccum>): StoreBuilder<TAccum>;
|
|
113
|
+
mirrorSelf(sourceKey: StoreKey<TAccum>, targetKey: StoreKey<TAccum>): StoreBuilder<TAccum>;
|
|
114
|
+
mirrorKeyed<TSourceData extends StoreDataShape<TSourceData>, TEntity>(source: InjectionToken<IStore<TSourceData>>, sourceKey: StoreKey<TSourceData>, options: {
|
|
110
115
|
extractId: (data: TEntity | undefined) => KeyedResourceKey | undefined;
|
|
111
|
-
}, targetKey?:
|
|
116
|
+
}, targetKey?: StoreKey<TAccum>): StoreBuilder<TAccum>;
|
|
112
117
|
build(): InjectionToken<BaseStore<InferEnum<TAccum>, InferData<TAccum>>>;
|
|
113
118
|
}
|
|
114
119
|
/** Keys from the enum that have NOT yet been defined. */
|
|
@@ -122,21 +127,21 @@ interface ConstrainedAsStep<TEnum extends Record<string, string>, TAccum extends
|
|
|
122
127
|
* defined yet. `.build()` is only available when all keys are accounted for.
|
|
123
128
|
*/
|
|
124
129
|
type ConstrainedBuilder<TEnum extends Record<string, string>, TAccum extends StoreConfig> = [Remaining<TEnum, TAccum>] extends [never] ? {
|
|
125
|
-
mirror<TSourceData extends
|
|
126
|
-
mirrorSelf(sourceKey:
|
|
127
|
-
mirrorKeyed<TSourceData extends
|
|
130
|
+
mirror<TSourceData extends StoreDataShape<TSourceData>>(source: InjectionToken<IStore<TSourceData>>, sourceKey: StoreKey<TSourceData>, targetKey?: StoreKey<TAccum>): ConstrainedBuilder<TEnum, TAccum>;
|
|
131
|
+
mirrorSelf(sourceKey: StoreKey<TAccum>, targetKey: StoreKey<TAccum>): ConstrainedBuilder<TEnum, TAccum>;
|
|
132
|
+
mirrorKeyed<TSourceData extends StoreDataShape<TSourceData>, TEntity>(source: InjectionToken<IStore<TSourceData>>, sourceKey: StoreKey<TSourceData>, options: {
|
|
128
133
|
extractId: (data: TEntity | undefined) => KeyedResourceKey | undefined;
|
|
129
|
-
}, targetKey?:
|
|
134
|
+
}, targetKey?: StoreKey<TAccum>): ConstrainedBuilder<TEnum, TAccum>;
|
|
130
135
|
build(): InjectionToken<BaseStore<InferEnum<TAccum>, InferData<TAccum>>>;
|
|
131
136
|
} : {
|
|
132
137
|
resource<TKey extends Remaining<TEnum, TAccum>>(key: TKey): ConstrainedAsStep<TEnum, TAccum, TKey>;
|
|
133
138
|
};
|
|
134
|
-
interface InterfaceBuilder<TConfig extends
|
|
135
|
-
mirror<TSourceData extends
|
|
136
|
-
mirrorSelf(sourceKey:
|
|
137
|
-
mirrorKeyed<TSourceData extends
|
|
139
|
+
interface InterfaceBuilder<TConfig extends object> {
|
|
140
|
+
mirror<TSourceData extends StoreDataShape<TSourceData>>(source: InjectionToken<IStore<TSourceData>>, sourceKey: StoreKey<TSourceData>, targetKey?: StoreKey<ConfigToData<TConfig>>): InterfaceBuilder<TConfig>;
|
|
141
|
+
mirrorSelf(sourceKey: StoreKey<ConfigToData<TConfig>>, targetKey: StoreKey<ConfigToData<TConfig>>): InterfaceBuilder<TConfig>;
|
|
142
|
+
mirrorKeyed<TSourceData extends StoreDataShape<TSourceData>, TEntity>(source: InjectionToken<IStore<TSourceData>>, sourceKey: StoreKey<TSourceData>, options: {
|
|
138
143
|
extractId: (data: TEntity | undefined) => KeyedResourceKey | undefined;
|
|
139
|
-
}, targetKey?:
|
|
144
|
+
}, targetKey?: StoreKey<ConfigToData<TConfig>>): InterfaceBuilder<TConfig>;
|
|
140
145
|
build(): InjectionToken<IStore<ConfigToData<TConfig>>>;
|
|
141
146
|
}
|
|
142
147
|
interface StoreEntry {
|
|
@@ -159,7 +164,7 @@ interface StoreEntry {
|
|
|
159
164
|
* }
|
|
160
165
|
* const ChatStore = Store.for<ChatStoreConfig>().build();
|
|
161
166
|
*/
|
|
162
|
-
for<TConfig extends
|
|
167
|
+
for<TConfig extends object>(): InterfaceBuilder<TConfig>;
|
|
163
168
|
/**
|
|
164
169
|
* Bind the builder to an enum object for compile-time key validation.
|
|
165
170
|
*
|
|
@@ -170,7 +175,7 @@ interface StoreEntry {
|
|
|
170
175
|
* .resource('B').as<number>()
|
|
171
176
|
* .build();
|
|
172
177
|
*/
|
|
173
|
-
for<TEnum extends Record<string, string>>(enumObj: TEnum): ConstrainedBuilder<TEnum, Record<
|
|
178
|
+
for<TEnum extends Record<string, string>>(enumObj: TEnum): ConstrainedBuilder<TEnum, Record<never, never>>;
|
|
174
179
|
}
|
|
175
180
|
/**
|
|
176
181
|
* Fluent store builder entry point.
|
|
@@ -192,6 +197,8 @@ interface StoreEntry {
|
|
|
192
197
|
*/
|
|
193
198
|
declare const Store: StoreEntry;
|
|
194
199
|
|
|
200
|
+
declare function clearAllStores(): void;
|
|
201
|
+
|
|
195
202
|
interface MirrorOptions {
|
|
196
203
|
destroyRef?: {
|
|
197
204
|
onDestroy: (fn: () => void) => void;
|
|
@@ -208,7 +215,7 @@ interface MirrorOptions {
|
|
|
208
215
|
* @param options - Mirror options when a target key is provided
|
|
209
216
|
* @returns Cleanup function to stop mirroring
|
|
210
217
|
*/
|
|
211
|
-
declare function mirrorKey<TSource extends
|
|
218
|
+
declare function mirrorKey<TSource extends StoreDataShape<TSource>, TTarget extends StoreDataShape<TTarget>>(source: IStore<TSource>, sourceKey: StoreKey<TSource>, target: IStore<TTarget>, targetKeyOrOptions?: StoreKey<TTarget> | MirrorOptions, options?: MirrorOptions): () => void;
|
|
212
219
|
|
|
213
220
|
interface CollectKeyedOptions<TEntity> {
|
|
214
221
|
extractId: (data: TEntity | undefined) => KeyedResourceKey | undefined;
|
|
@@ -232,6 +239,6 @@ interface CollectKeyedOptions<TEntity> {
|
|
|
232
239
|
* @param options - Collect options when a target key is provided
|
|
233
240
|
* @returns Cleanup function to stop collecting
|
|
234
241
|
*/
|
|
235
|
-
declare function collectKeyed<TSource extends
|
|
242
|
+
declare function collectKeyed<TSource extends StoreDataShape<TSource>, TTarget extends StoreDataShape<TTarget>, TEntity = unknown>(source: IStore<TSource>, sourceKey: StoreKey<TSource>, target: IStore<TTarget>, targetKeyOrOptions?: StoreKey<TTarget> | CollectKeyedOptions<TEntity>, options?: CollectKeyedOptions<TEntity>): () => void;
|
|
236
243
|
|
|
237
|
-
export { BaseStore, type CollectKeyedOptions, type ConfigToData, type IStore, LazyStore, type MirrorOptions, Store, collectKeyed, mirrorKey };
|
|
244
|
+
export { BaseStore, type CollectKeyedOptions, type ConfigToData, type IStore, LazyStore, type MirrorOptions, Store, clearAllStores, collectKeyed, mirrorKey };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { Signal, InjectionToken } from '@angular/core';
|
|
2
2
|
import { ResourceState, KeyedResourceKey } from '@flurryx/core';
|
|
3
3
|
|
|
4
|
+
type StoreDataShape<TData> = {
|
|
5
|
+
[K in keyof TData]: ResourceState<unknown>;
|
|
6
|
+
};
|
|
7
|
+
type StoreKey<TData> = keyof TData & string;
|
|
4
8
|
/**
|
|
5
9
|
* Phantom-typed marker for a store resource slot.
|
|
6
10
|
* Carries type information at compile time with zero runtime cost.
|
|
@@ -31,23 +35,23 @@ type InferData<TConfig extends StoreConfig> = {
|
|
|
31
35
|
* Maps a plain config interface to ResourceState-wrapped data.
|
|
32
36
|
* e.g. { SESSIONS: ChatSession[] } -> { SESSIONS: ResourceState<ChatSession[]> }
|
|
33
37
|
*/
|
|
34
|
-
type ConfigToData<TConfig extends
|
|
38
|
+
type ConfigToData<TConfig extends object> = {
|
|
35
39
|
[K in keyof TConfig & string]: ResourceState<TConfig[K]>;
|
|
36
40
|
};
|
|
37
41
|
/**
|
|
38
42
|
* Shared store interface implemented by both BaseStore and LazyStore.
|
|
39
43
|
*/
|
|
40
|
-
interface IStore<TData extends
|
|
41
|
-
get<K extends
|
|
42
|
-
update<K extends
|
|
43
|
-
clear<K extends
|
|
44
|
+
interface IStore<TData extends StoreDataShape<TData>> {
|
|
45
|
+
get<K extends StoreKey<TData>>(key: K): Signal<TData[K]>;
|
|
46
|
+
update<K extends StoreKey<TData>>(key: K, newState: Partial<TData[K]>): void;
|
|
47
|
+
clear<K extends StoreKey<TData>>(key: K): void;
|
|
44
48
|
clearAll(): void;
|
|
45
|
-
startLoading<K extends
|
|
46
|
-
stopLoading<K extends
|
|
47
|
-
updateKeyedOne<K extends
|
|
48
|
-
clearKeyedOne<K extends
|
|
49
|
-
startKeyedLoading<K extends
|
|
50
|
-
onUpdate<K extends
|
|
49
|
+
startLoading<K extends StoreKey<TData>>(key: K): void;
|
|
50
|
+
stopLoading<K extends StoreKey<TData>>(key: K): void;
|
|
51
|
+
updateKeyedOne<K extends StoreKey<TData>>(key: K, resourceKey: KeyedResourceKey, entity: unknown): void;
|
|
52
|
+
clearKeyedOne<K extends StoreKey<TData>>(key: K, resourceKey: KeyedResourceKey): void;
|
|
53
|
+
startKeyedLoading<K extends StoreKey<TData>>(key: K, resourceKey: KeyedResourceKey): void;
|
|
54
|
+
onUpdate<K extends StoreKey<TData>>(key: K, callback: (state: TData[K], previousState: TData[K]) => void): () => void;
|
|
51
55
|
}
|
|
52
56
|
|
|
53
57
|
declare abstract class BaseStore<TEnum extends Record<string, string | number>, TData extends {
|
|
@@ -75,20 +79,21 @@ declare abstract class BaseStore<TEnum extends Record<string, string | number>,
|
|
|
75
79
|
* Used by the `Store.for<Config>().build()` API where keys are
|
|
76
80
|
* known only at the type level (no runtime enum).
|
|
77
81
|
*/
|
|
78
|
-
declare class LazyStore<TData extends
|
|
82
|
+
declare class LazyStore<TData extends StoreDataShape<TData>> implements IStore<TData> {
|
|
79
83
|
private readonly signals;
|
|
80
84
|
private readonly hooks;
|
|
85
|
+
constructor();
|
|
81
86
|
private getOrCreate;
|
|
82
|
-
get<K extends
|
|
83
|
-
update<K extends
|
|
84
|
-
clear<K extends
|
|
87
|
+
get<K extends StoreKey<TData>>(key: K): Signal<TData[K]>;
|
|
88
|
+
update<K extends StoreKey<TData>>(key: K, newState: Partial<TData[K]>): void;
|
|
89
|
+
clear<K extends StoreKey<TData>>(key: K): void;
|
|
85
90
|
clearAll(): void;
|
|
86
|
-
startLoading<K extends
|
|
87
|
-
stopLoading<K extends
|
|
88
|
-
updateKeyedOne<K extends
|
|
89
|
-
clearKeyedOne<K extends
|
|
90
|
-
startKeyedLoading<K extends
|
|
91
|
-
onUpdate<K extends
|
|
91
|
+
startLoading<K extends StoreKey<TData>>(key: K): void;
|
|
92
|
+
stopLoading<K extends StoreKey<TData>>(key: K): void;
|
|
93
|
+
updateKeyedOne<K extends StoreKey<TData>>(key: K, resourceKey: KeyedResourceKey, entity: unknown): void;
|
|
94
|
+
clearKeyedOne<K extends StoreKey<TData>>(key: K, resourceKey: KeyedResourceKey): void;
|
|
95
|
+
startKeyedLoading<K extends StoreKey<TData>>(key: K, resourceKey: KeyedResourceKey): void;
|
|
96
|
+
onUpdate<K extends StoreKey<TData>>(key: K, callback: (state: TData[K], previousState: TData[K]) => void): () => void;
|
|
92
97
|
private notifyHooks;
|
|
93
98
|
}
|
|
94
99
|
|
|
@@ -104,11 +109,11 @@ interface AsStep<TAccum extends StoreConfig, TKey extends string> {
|
|
|
104
109
|
*/
|
|
105
110
|
interface StoreBuilder<TAccum extends StoreConfig> {
|
|
106
111
|
resource<TKey extends string>(key: TKey): AsStep<TAccum, TKey>;
|
|
107
|
-
mirror<TSourceData extends
|
|
108
|
-
mirrorSelf(sourceKey:
|
|
109
|
-
mirrorKeyed<TSourceData extends
|
|
112
|
+
mirror<TSourceData extends StoreDataShape<TSourceData>>(source: InjectionToken<IStore<TSourceData>>, sourceKey: StoreKey<TSourceData>, targetKey?: StoreKey<TAccum>): StoreBuilder<TAccum>;
|
|
113
|
+
mirrorSelf(sourceKey: StoreKey<TAccum>, targetKey: StoreKey<TAccum>): StoreBuilder<TAccum>;
|
|
114
|
+
mirrorKeyed<TSourceData extends StoreDataShape<TSourceData>, TEntity>(source: InjectionToken<IStore<TSourceData>>, sourceKey: StoreKey<TSourceData>, options: {
|
|
110
115
|
extractId: (data: TEntity | undefined) => KeyedResourceKey | undefined;
|
|
111
|
-
}, targetKey?:
|
|
116
|
+
}, targetKey?: StoreKey<TAccum>): StoreBuilder<TAccum>;
|
|
112
117
|
build(): InjectionToken<BaseStore<InferEnum<TAccum>, InferData<TAccum>>>;
|
|
113
118
|
}
|
|
114
119
|
/** Keys from the enum that have NOT yet been defined. */
|
|
@@ -122,21 +127,21 @@ interface ConstrainedAsStep<TEnum extends Record<string, string>, TAccum extends
|
|
|
122
127
|
* defined yet. `.build()` is only available when all keys are accounted for.
|
|
123
128
|
*/
|
|
124
129
|
type ConstrainedBuilder<TEnum extends Record<string, string>, TAccum extends StoreConfig> = [Remaining<TEnum, TAccum>] extends [never] ? {
|
|
125
|
-
mirror<TSourceData extends
|
|
126
|
-
mirrorSelf(sourceKey:
|
|
127
|
-
mirrorKeyed<TSourceData extends
|
|
130
|
+
mirror<TSourceData extends StoreDataShape<TSourceData>>(source: InjectionToken<IStore<TSourceData>>, sourceKey: StoreKey<TSourceData>, targetKey?: StoreKey<TAccum>): ConstrainedBuilder<TEnum, TAccum>;
|
|
131
|
+
mirrorSelf(sourceKey: StoreKey<TAccum>, targetKey: StoreKey<TAccum>): ConstrainedBuilder<TEnum, TAccum>;
|
|
132
|
+
mirrorKeyed<TSourceData extends StoreDataShape<TSourceData>, TEntity>(source: InjectionToken<IStore<TSourceData>>, sourceKey: StoreKey<TSourceData>, options: {
|
|
128
133
|
extractId: (data: TEntity | undefined) => KeyedResourceKey | undefined;
|
|
129
|
-
}, targetKey?:
|
|
134
|
+
}, targetKey?: StoreKey<TAccum>): ConstrainedBuilder<TEnum, TAccum>;
|
|
130
135
|
build(): InjectionToken<BaseStore<InferEnum<TAccum>, InferData<TAccum>>>;
|
|
131
136
|
} : {
|
|
132
137
|
resource<TKey extends Remaining<TEnum, TAccum>>(key: TKey): ConstrainedAsStep<TEnum, TAccum, TKey>;
|
|
133
138
|
};
|
|
134
|
-
interface InterfaceBuilder<TConfig extends
|
|
135
|
-
mirror<TSourceData extends
|
|
136
|
-
mirrorSelf(sourceKey:
|
|
137
|
-
mirrorKeyed<TSourceData extends
|
|
139
|
+
interface InterfaceBuilder<TConfig extends object> {
|
|
140
|
+
mirror<TSourceData extends StoreDataShape<TSourceData>>(source: InjectionToken<IStore<TSourceData>>, sourceKey: StoreKey<TSourceData>, targetKey?: StoreKey<ConfigToData<TConfig>>): InterfaceBuilder<TConfig>;
|
|
141
|
+
mirrorSelf(sourceKey: StoreKey<ConfigToData<TConfig>>, targetKey: StoreKey<ConfigToData<TConfig>>): InterfaceBuilder<TConfig>;
|
|
142
|
+
mirrorKeyed<TSourceData extends StoreDataShape<TSourceData>, TEntity>(source: InjectionToken<IStore<TSourceData>>, sourceKey: StoreKey<TSourceData>, options: {
|
|
138
143
|
extractId: (data: TEntity | undefined) => KeyedResourceKey | undefined;
|
|
139
|
-
}, targetKey?:
|
|
144
|
+
}, targetKey?: StoreKey<ConfigToData<TConfig>>): InterfaceBuilder<TConfig>;
|
|
140
145
|
build(): InjectionToken<IStore<ConfigToData<TConfig>>>;
|
|
141
146
|
}
|
|
142
147
|
interface StoreEntry {
|
|
@@ -159,7 +164,7 @@ interface StoreEntry {
|
|
|
159
164
|
* }
|
|
160
165
|
* const ChatStore = Store.for<ChatStoreConfig>().build();
|
|
161
166
|
*/
|
|
162
|
-
for<TConfig extends
|
|
167
|
+
for<TConfig extends object>(): InterfaceBuilder<TConfig>;
|
|
163
168
|
/**
|
|
164
169
|
* Bind the builder to an enum object for compile-time key validation.
|
|
165
170
|
*
|
|
@@ -170,7 +175,7 @@ interface StoreEntry {
|
|
|
170
175
|
* .resource('B').as<number>()
|
|
171
176
|
* .build();
|
|
172
177
|
*/
|
|
173
|
-
for<TEnum extends Record<string, string>>(enumObj: TEnum): ConstrainedBuilder<TEnum, Record<
|
|
178
|
+
for<TEnum extends Record<string, string>>(enumObj: TEnum): ConstrainedBuilder<TEnum, Record<never, never>>;
|
|
174
179
|
}
|
|
175
180
|
/**
|
|
176
181
|
* Fluent store builder entry point.
|
|
@@ -192,6 +197,8 @@ interface StoreEntry {
|
|
|
192
197
|
*/
|
|
193
198
|
declare const Store: StoreEntry;
|
|
194
199
|
|
|
200
|
+
declare function clearAllStores(): void;
|
|
201
|
+
|
|
195
202
|
interface MirrorOptions {
|
|
196
203
|
destroyRef?: {
|
|
197
204
|
onDestroy: (fn: () => void) => void;
|
|
@@ -208,7 +215,7 @@ interface MirrorOptions {
|
|
|
208
215
|
* @param options - Mirror options when a target key is provided
|
|
209
216
|
* @returns Cleanup function to stop mirroring
|
|
210
217
|
*/
|
|
211
|
-
declare function mirrorKey<TSource extends
|
|
218
|
+
declare function mirrorKey<TSource extends StoreDataShape<TSource>, TTarget extends StoreDataShape<TTarget>>(source: IStore<TSource>, sourceKey: StoreKey<TSource>, target: IStore<TTarget>, targetKeyOrOptions?: StoreKey<TTarget> | MirrorOptions, options?: MirrorOptions): () => void;
|
|
212
219
|
|
|
213
220
|
interface CollectKeyedOptions<TEntity> {
|
|
214
221
|
extractId: (data: TEntity | undefined) => KeyedResourceKey | undefined;
|
|
@@ -232,6 +239,6 @@ interface CollectKeyedOptions<TEntity> {
|
|
|
232
239
|
* @param options - Collect options when a target key is provided
|
|
233
240
|
* @returns Cleanup function to stop collecting
|
|
234
241
|
*/
|
|
235
|
-
declare function collectKeyed<TSource extends
|
|
242
|
+
declare function collectKeyed<TSource extends StoreDataShape<TSource>, TTarget extends StoreDataShape<TTarget>, TEntity = unknown>(source: IStore<TSource>, sourceKey: StoreKey<TSource>, target: IStore<TTarget>, targetKeyOrOptions?: StoreKey<TTarget> | CollectKeyedOptions<TEntity>, options?: CollectKeyedOptions<TEntity>): () => void;
|
|
236
243
|
|
|
237
|
-
export { BaseStore, type CollectKeyedOptions, type ConfigToData, type IStore, LazyStore, type MirrorOptions, Store, collectKeyed, mirrorKey };
|
|
244
|
+
export { BaseStore, type CollectKeyedOptions, type ConfigToData, type IStore, LazyStore, type MirrorOptions, Store, clearAllStores, collectKeyed, mirrorKey };
|
package/dist/index.js
CHANGED
|
@@ -5,12 +5,26 @@ import {
|
|
|
5
5
|
isKeyedResourceData,
|
|
6
6
|
createKeyedResourceData
|
|
7
7
|
} from "@flurryx/core";
|
|
8
|
+
|
|
9
|
+
// src/store-registry.ts
|
|
10
|
+
var trackedStores = /* @__PURE__ */ new Set();
|
|
11
|
+
function trackStore(store) {
|
|
12
|
+
trackedStores.add(store);
|
|
13
|
+
}
|
|
14
|
+
function clearAllStores() {
|
|
15
|
+
for (const store of [...trackedStores]) {
|
|
16
|
+
store.clearAll();
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// src/base-store.ts
|
|
8
21
|
var updateHooksMap = /* @__PURE__ */ new WeakMap();
|
|
9
22
|
var BaseStore = class {
|
|
10
23
|
constructor(storeEnum) {
|
|
11
24
|
this.storeEnum = storeEnum;
|
|
12
25
|
this.initializeState();
|
|
13
26
|
updateHooksMap.set(this, /* @__PURE__ */ new Map());
|
|
27
|
+
trackStore(this);
|
|
14
28
|
}
|
|
15
29
|
signalsState = /* @__PURE__ */ new Map();
|
|
16
30
|
get(key) {
|
|
@@ -263,6 +277,9 @@ function createDefaultState() {
|
|
|
263
277
|
var LazyStore = class {
|
|
264
278
|
signals = /* @__PURE__ */ new Map();
|
|
265
279
|
hooks = /* @__PURE__ */ new Map();
|
|
280
|
+
constructor() {
|
|
281
|
+
trackStore(this);
|
|
282
|
+
}
|
|
266
283
|
getOrCreate(key) {
|
|
267
284
|
let sig = this.signals.get(key);
|
|
268
285
|
if (!sig) {
|
|
@@ -581,7 +598,12 @@ function wireSelfMirrors(store, defs) {
|
|
|
581
598
|
if (def.sourceKey === def.targetKey) {
|
|
582
599
|
throw new Error(MIRROR_SELF_SAME_KEY_ERROR);
|
|
583
600
|
}
|
|
584
|
-
mirrorKey(
|
|
601
|
+
mirrorKey(
|
|
602
|
+
store,
|
|
603
|
+
def.sourceKey,
|
|
604
|
+
store,
|
|
605
|
+
def.targetKey
|
|
606
|
+
);
|
|
585
607
|
}
|
|
586
608
|
return store;
|
|
587
609
|
}
|
|
@@ -782,17 +804,19 @@ function createInterfaceBuilder(mirrors = [], mirrorKeyedDefs = [], selfMirrors
|
|
|
782
804
|
}
|
|
783
805
|
var Store = {
|
|
784
806
|
...createBuilder({}),
|
|
785
|
-
for
|
|
786
|
-
if (arguments.length === 0) {
|
|
787
|
-
return createInterfaceBuilder();
|
|
788
|
-
}
|
|
789
|
-
return createConstrainedBuilder(enumObj, {});
|
|
790
|
-
}
|
|
807
|
+
for: createStoreFor
|
|
791
808
|
};
|
|
809
|
+
function createStoreFor(enumObj) {
|
|
810
|
+
if (arguments.length === 0) {
|
|
811
|
+
return createInterfaceBuilder();
|
|
812
|
+
}
|
|
813
|
+
return createConstrainedBuilder(enumObj, {});
|
|
814
|
+
}
|
|
792
815
|
export {
|
|
793
816
|
BaseStore,
|
|
794
817
|
LazyStore,
|
|
795
818
|
Store,
|
|
819
|
+
clearAllStores,
|
|
796
820
|
collectKeyed,
|
|
797
821
|
mirrorKey
|
|
798
822
|
};
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../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":["import { signal, type 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): Signal<TData[K]> {\n return this.signalsState.get(key.toString()) as unknown as Signal<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, type 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): Signal<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\ninterface SelfMirrorDef {\n readonly sourceKey: string;\n readonly targetKey: string;\n}\n\nconst MIRROR_SELF_SAME_KEY_ERROR =\n \"mirrorSelf source and target keys must be different\";\n\nfunction wireSelfMirrors<\n TStore extends IStore<Record<string, ResourceState<unknown>>>,\n>(store: TStore, defs: readonly SelfMirrorDef[]): TStore {\n for (const def of defs) {\n if (def.sourceKey === def.targetKey) {\n throw new Error(MIRROR_SELF_SAME_KEY_ERROR);\n }\n\n mirrorKey(store, 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 mirrorSelf(\n sourceKey: keyof TAccum & 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 selfMirrors: readonly SelfMirrorDef[] = [],\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(\n nextAccum,\n mirrors,\n mirrorKeyedDefs,\n selfMirrors,\n );\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(\n accum,\n [...mirrors, def],\n mirrorKeyedDefs,\n selfMirrors,\n );\n },\n mirrorSelf(sourceKey, targetKey) {\n const def: SelfMirrorDef = {\n sourceKey,\n targetKey,\n };\n return createBuilder(accum, mirrors, mirrorKeyedDefs, [\n ...selfMirrors,\n def,\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 createBuilder(\n accum,\n mirrors,\n [...mirrorKeyedDefs, def],\n selfMirrors,\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 wireSelfMirrors(store, selfMirrors);\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 mirrorSelf(\n sourceKey: keyof TAccum & 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 selfMirrors: readonly SelfMirrorDef[] = [],\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 selfMirrors,\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 selfMirrors,\n );\n },\n mirrorSelf(sourceKey: string, targetKey: string) {\n const def: SelfMirrorDef = {\n sourceKey,\n targetKey,\n };\n return createConstrainedBuilder(\n _enumObj,\n accum,\n mirrors,\n mirrorKeyedDefs,\n [...selfMirrors, def],\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(\n _enumObj,\n accum,\n mirrors,\n [...mirrorKeyedDefs, def],\n selfMirrors,\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 wireSelfMirrors(store, selfMirrors);\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 mirrorSelf(\n sourceKey: keyof TConfig & 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 selfMirrors: readonly SelfMirrorDef[] = [],\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 selfMirrors,\n );\n },\n mirrorSelf(sourceKey, targetKey) {\n const def: SelfMirrorDef = {\n sourceKey: sourceKey as string,\n targetKey: targetKey as string,\n };\n return createInterfaceBuilder<TConfig>(mirrors, mirrorKeyedDefs, [\n ...selfMirrors,\n def,\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>(\n mirrors,\n [...mirrorKeyedDefs, def],\n selfMirrors,\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 wireSelfMirrors(store, selfMirrors);\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":["signal","isAnyKeyLoading","isKeyedResourceData","createKeyedResourceData","createKeyedResourceData","isAnyKeyLoading"]}
|
|
1
|
+
{"version":3,"sources":["../src/base-store.ts","../src/store-registry.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":["import { signal, type 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\";\nimport { trackStore } from \"./store-registry\";\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 trackStore(this);\n }\n\n get<K extends keyof TData>(key: K): Signal<TData[K]> {\n return this.signalsState.get(key.toString()) as unknown as Signal<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","interface Clearable {\n clearAll(): void;\n}\n\nconst trackedStores = new Set<Clearable>();\n\nexport function trackStore(store: Clearable): void {\n trackedStores.add(store);\n}\n\nexport function clearAllStores(): void {\n for (const store of [...trackedStores]) {\n store.clearAll();\n }\n}\n\nexport function resetTrackedStoresForTests(): void {\n trackedStores.clear();\n}\n","import { signal, type 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, StoreDataShape, StoreKey } from \"./types\";\nimport { trackStore } from \"./store-registry\";\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 StoreDataShape<TData>>\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 constructor() {\n trackStore(this);\n }\n\n private getOrCreate<K extends StoreKey<TData>>(\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 StoreKey<TData>>(key: K): Signal<TData[K]> {\n return this.getOrCreate(key);\n }\n\n update<K extends StoreKey<TData>>(key: K, newState: Partial<TData[K]>): 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 StoreKey<TData>>(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 StoreKey<TData>);\n }\n }\n\n startLoading<K extends StoreKey<TData>>(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 StoreKey<TData>>(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 StoreKey<TData>>(\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 StoreKey<TData>>(\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 StoreKey<TData>>(\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 StoreKey<TData>>(\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 StoreKey<TData>>(\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 StoreDataShape,\n StoreKey,\n} from \"./types\";\n\ntype AnyStoreData = Record<string, ResourceState<unknown>>;\n\n// ---------------------------------------------------------------------------\n// Mirror definition — accumulated by builders, wired up in build() factory\n// ---------------------------------------------------------------------------\n\ninterface MirrorDef {\n readonly sourceToken: InjectionToken<IStore<AnyStoreData>>;\n readonly sourceKey: string;\n readonly targetKey: string;\n}\n\nfunction wireMirrors<\n TData extends StoreDataShape<TData>,\n TStore extends IStore<TData>,\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 as StoreKey<TData>);\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<IStore<AnyStoreData>>;\n readonly sourceKey: string;\n readonly targetKey: string;\n readonly extractId: (data: unknown) => KeyedResourceKey | undefined;\n}\n\nfunction wireMirrorKeyed<\n TData extends StoreDataShape<TData>,\n TStore extends IStore<TData>,\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 as StoreKey<TData>, {\n extractId: def.extractId,\n });\n }\n return store;\n}\n\ninterface SelfMirrorDef {\n readonly sourceKey: string;\n readonly targetKey: string;\n}\n\nconst MIRROR_SELF_SAME_KEY_ERROR =\n \"mirrorSelf source and target keys must be different\";\n\nfunction wireSelfMirrors<\n TData extends StoreDataShape<TData>,\n TStore extends IStore<TData>,\n>(store: TStore, defs: readonly SelfMirrorDef[]): TStore {\n for (const def of defs) {\n if (def.sourceKey === def.targetKey) {\n throw new Error(MIRROR_SELF_SAME_KEY_ERROR);\n }\n\n mirrorKey(\n store,\n def.sourceKey as StoreKey<TData>,\n store,\n def.targetKey as StoreKey<TData>,\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 StoreDataShape<TSourceData>>(\n source: InjectionToken<IStore<TSourceData>>,\n sourceKey: StoreKey<TSourceData>,\n targetKey?: StoreKey<TAccum>,\n ): StoreBuilder<TAccum>;\n mirrorSelf(\n sourceKey: StoreKey<TAccum>,\n targetKey: StoreKey<TAccum>,\n ): StoreBuilder<TAccum>;\n mirrorKeyed<\n TSourceData extends StoreDataShape<TSourceData>,\n TEntity,\n >(\n source: InjectionToken<IStore<TSourceData>>,\n sourceKey: StoreKey<TSourceData>,\n options: {\n extractId: (data: TEntity | undefined) => KeyedResourceKey | undefined;\n },\n targetKey?: StoreKey<TAccum>,\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 selfMirrors: readonly SelfMirrorDef[] = [],\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(\n nextAccum,\n mirrors,\n mirrorKeyedDefs,\n selfMirrors,\n );\n },\n };\n },\n mirror(source, sourceKey, targetKey?) {\n const def: MirrorDef = {\n sourceToken: source as InjectionToken<\n IStore<AnyStoreData>\n >,\n sourceKey: sourceKey as string,\n targetKey: (targetKey ?? sourceKey) as string,\n };\n return createBuilder(\n accum,\n [...mirrors, def],\n mirrorKeyedDefs,\n selfMirrors,\n );\n },\n mirrorSelf(sourceKey, targetKey) {\n const def: SelfMirrorDef = {\n sourceKey: sourceKey as string,\n targetKey: targetKey as string,\n };\n return createBuilder(accum, mirrors, mirrorKeyedDefs, [\n ...selfMirrors,\n def,\n ]);\n },\n mirrorKeyed(source, sourceKey, options, targetKey?) {\n const def: MirrorKeyedDef = {\n sourceToken: source as InjectionToken<\n IStore<AnyStoreData>\n >,\n sourceKey: sourceKey as string,\n targetKey: (targetKey ?? sourceKey) as string,\n extractId: options.extractId as (\n data: unknown,\n ) => KeyedResourceKey | undefined,\n };\n return createBuilder(\n accum,\n mirrors,\n [...mirrorKeyedDefs, def],\n selfMirrors,\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) as IStore<InferData<TAccum>>;\n wireMirrors(store, mirrors);\n wireMirrorKeyed(store, mirrorKeyedDefs);\n wireSelfMirrors(store, selfMirrors);\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 StoreDataShape<TSourceData>>(\n source: InjectionToken<IStore<TSourceData>>,\n sourceKey: StoreKey<TSourceData>,\n targetKey?: StoreKey<TAccum>,\n ): ConstrainedBuilder<TEnum, TAccum>;\n mirrorSelf(\n sourceKey: StoreKey<TAccum>,\n targetKey: StoreKey<TAccum>,\n ): ConstrainedBuilder<TEnum, TAccum>;\n mirrorKeyed<\n TSourceData extends StoreDataShape<TSourceData>,\n TEntity,\n >(\n source: InjectionToken<IStore<TSourceData>>,\n sourceKey: StoreKey<TSourceData>,\n options: {\n extractId: (\n data: TEntity | undefined,\n ) => KeyedResourceKey | undefined;\n },\n targetKey?: StoreKey<TAccum>,\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 selfMirrors: readonly SelfMirrorDef[] = [],\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 selfMirrors,\n );\n },\n };\n },\n mirror(\n source: InjectionToken<\n IStore<AnyStoreData>\n >,\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 selfMirrors,\n );\n },\n mirrorSelf(sourceKey: string, targetKey: string) {\n const def: SelfMirrorDef = {\n sourceKey,\n targetKey,\n };\n return createConstrainedBuilder(\n _enumObj,\n accum,\n mirrors,\n mirrorKeyedDefs,\n [...selfMirrors, def],\n );\n },\n mirrorKeyed(\n source: InjectionToken<\n IStore<AnyStoreData>\n >,\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(\n _enumObj,\n accum,\n mirrors,\n [...mirrorKeyedDefs, def],\n selfMirrors,\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) as IStore<InferData<TAccum>>;\n wireMirrors(store, mirrors);\n wireMirrorKeyed(store, mirrorKeyedDefs);\n wireSelfMirrors(store, selfMirrors);\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 object> {\n mirror<TSourceData extends StoreDataShape<TSourceData>>(\n source: InjectionToken<IStore<TSourceData>>,\n sourceKey: StoreKey<TSourceData>,\n targetKey?: StoreKey<ConfigToData<TConfig>>,\n ): InterfaceBuilder<TConfig>;\n mirrorSelf(\n sourceKey: StoreKey<ConfigToData<TConfig>>,\n targetKey: StoreKey<ConfigToData<TConfig>>,\n ): InterfaceBuilder<TConfig>;\n mirrorKeyed<\n TSourceData extends StoreDataShape<TSourceData>,\n TEntity,\n >(\n source: InjectionToken<IStore<TSourceData>>,\n sourceKey: StoreKey<TSourceData>,\n options: {\n extractId: (data: TEntity | undefined) => KeyedResourceKey | undefined;\n },\n targetKey?: StoreKey<ConfigToData<TConfig>>,\n ): InterfaceBuilder<TConfig>;\n build(): InjectionToken<IStore<ConfigToData<TConfig>>>;\n}\n\nfunction createInterfaceBuilder<TConfig extends object>(\n mirrors: readonly MirrorDef[] = [],\n mirrorKeyedDefs: readonly MirrorKeyedDef[] = [],\n selfMirrors: readonly SelfMirrorDef[] = [],\n): InterfaceBuilder<TConfig> {\n return {\n mirror(source, sourceKey, targetKey?) {\n const def: MirrorDef = {\n sourceToken: source as InjectionToken<\n IStore<AnyStoreData>\n >,\n sourceKey: sourceKey as string,\n targetKey: (targetKey ?? sourceKey) as string,\n };\n return createInterfaceBuilder<TConfig>(\n [...mirrors, def],\n mirrorKeyedDefs,\n selfMirrors,\n );\n },\n mirrorSelf(sourceKey, targetKey) {\n const def: SelfMirrorDef = {\n sourceKey: sourceKey as string,\n targetKey: targetKey as string,\n };\n return createInterfaceBuilder<TConfig>(mirrors, mirrorKeyedDefs, [\n ...selfMirrors,\n def,\n ]);\n },\n mirrorKeyed(source, sourceKey, options, targetKey?) {\n const def: MirrorKeyedDef = {\n sourceToken: source as InjectionToken<\n IStore<AnyStoreData>\n >,\n sourceKey: sourceKey as string,\n targetKey: (targetKey ?? sourceKey) as string,\n extractId: options.extractId as (\n data: unknown,\n ) => KeyedResourceKey | undefined,\n };\n return createInterfaceBuilder<TConfig>(\n mirrors,\n [...mirrorKeyedDefs, def],\n selfMirrors,\n );\n },\n build() {\n return new InjectionToken(\"FlurryxStore\", {\n providedIn: \"root\",\n factory: () => {\n const store = new LazyStore() as IStore<\n AnyStoreData\n >;\n wireMirrors(store, mirrors);\n wireMirrorKeyed(store, mirrorKeyedDefs);\n wireSelfMirrors(store, selfMirrors);\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 object>(): 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<never, 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: createStoreFor,\n};\n\nfunction createStoreFor<TConfig extends object>(): InterfaceBuilder<TConfig>;\nfunction createStoreFor<TEnum extends Record<string, string>>(\n enumObj: TEnum,\n): ConstrainedBuilder<TEnum, Record<never, never>>;\nfunction createStoreFor(enumObj?: Record<string, string>) {\n if (arguments.length === 0) {\n return createInterfaceBuilder();\n }\n\n return createConstrainedBuilder(enumObj!, {} as Record<never, never>);\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 { IStore, StoreDataShape, StoreKey } 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 StoreDataShape<TSource>,\n TTarget extends StoreDataShape<TTarget>\n>(\n source: IStore<TSource>,\n sourceKey: StoreKey<TSource>,\n target: IStore<TTarget>,\n targetKeyOrOptions?: StoreKey<TTarget> | MirrorOptions,\n options?: MirrorOptions\n): () => void {\n const resolvedTargetKey = (\n typeof targetKeyOrOptions === \"string\" ? targetKeyOrOptions : sourceKey\n ) as StoreKey<TTarget>;\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[StoreKey<TTarget>]>\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, StoreDataShape, StoreKey } 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 StoreDataShape<TSource>,\n TTarget extends StoreDataShape<TTarget>,\n TEntity = unknown,\n>(\n source: IStore<TSource>,\n sourceKey: StoreKey<TSource>,\n target: IStore<TTarget>,\n targetKeyOrOptions?: StoreKey<TTarget> | CollectKeyedOptions<TEntity>,\n options?: CollectKeyedOptions<TEntity>,\n): () => void {\n const resolvedTargetKey = (\n typeof targetKeyOrOptions === 'string'\n ? targetKeyOrOptions\n : sourceKey\n ) as StoreKey<TTarget>;\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[StoreKey<TTarget>]>);\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[StoreKey<TTarget>]>);\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[StoreKey<TTarget>]>);\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[StoreKey<TTarget>]>);\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[StoreKey<TTarget>]>);\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":["signal","isAnyKeyLoading","isKeyedResourceData","createKeyedResourceData","signal","isKeyedResourceData","createKeyedResourceData","isAnyKeyLoading","createKeyedResourceData","isAnyKeyLoading"]}
|