@flurryx/store 0.7.1 → 0.7.4

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/dist/index.cjs CHANGED
@@ -368,7 +368,7 @@ var LazyStore = class {
368
368
  };
369
369
 
370
370
  // src/store-builder.ts
371
- var import_core4 = require("@angular/core");
371
+ var import_core5 = require("@angular/core");
372
372
 
373
373
  // src/dynamic-store.ts
374
374
  var DynamicStore = class extends BaseStore {
@@ -381,71 +381,6 @@ var DynamicStore = class extends BaseStore {
381
381
  }
382
382
  };
383
383
 
384
- // src/resource.ts
385
- function resource() {
386
- return {};
387
- }
388
-
389
- // src/store-builder.ts
390
- function createBuilder(accum) {
391
- return {
392
- resource(key) {
393
- return {
394
- as() {
395
- const nextAccum = {
396
- ...accum,
397
- [key]: resource()
398
- };
399
- return createBuilder(nextAccum);
400
- }
401
- };
402
- },
403
- build() {
404
- return new import_core4.InjectionToken("FlurryxStore", {
405
- providedIn: "root",
406
- factory: () => new DynamicStore(accum)
407
- });
408
- }
409
- };
410
- }
411
- function createConstrainedBuilder(_enumObj, accum) {
412
- return {
413
- resource(key) {
414
- return {
415
- as() {
416
- const nextAccum = {
417
- ...accum,
418
- [key]: resource()
419
- };
420
- return createConstrainedBuilder(_enumObj, nextAccum);
421
- }
422
- };
423
- },
424
- build() {
425
- return new import_core4.InjectionToken("FlurryxStore", {
426
- providedIn: "root",
427
- factory: () => new DynamicStore(accum)
428
- });
429
- }
430
- };
431
- }
432
- var Store = {
433
- ...createBuilder({}),
434
- for(enumObj) {
435
- if (arguments.length === 0) {
436
- return {
437
- build() {
438
- return new import_core4.InjectionToken("FlurryxStore", {
439
- providedIn: "root",
440
- factory: () => new LazyStore()
441
- });
442
- }
443
- };
444
- }
445
- return createConstrainedBuilder(enumObj, {});
446
- }
447
- };
448
-
449
384
  // src/mirror-key.ts
450
385
  function mirrorKey(source, sourceKey, target, targetKeyOrOptions, options) {
451
386
  const resolvedTargetKey = typeof targetKeyOrOptions === "string" ? targetKeyOrOptions : sourceKey;
@@ -463,12 +398,12 @@ function mirrorKey(source, sourceKey, target, targetKeyOrOptions, options) {
463
398
  }
464
399
 
465
400
  // src/collect-keyed.ts
466
- var import_core5 = require("@flurryx/core");
401
+ var import_core4 = require("@flurryx/core");
467
402
  function collectKeyed(source, sourceKey, target, targetKeyOrOptions, options) {
468
403
  const resolvedTargetKey = typeof targetKeyOrOptions === "string" ? targetKeyOrOptions : sourceKey;
469
404
  const resolvedOptions = typeof targetKeyOrOptions === "object" ? targetKeyOrOptions : options;
470
405
  target.update(resolvedTargetKey, {
471
- data: (0, import_core5.createKeyedResourceData)()
406
+ data: (0, import_core4.createKeyedResourceData)()
472
407
  });
473
408
  let previousId;
474
409
  const cleanup = source.onUpdate(sourceKey, (state) => {
@@ -493,7 +428,7 @@ function collectKeyed(source, sourceKey, target, targetKeyOrOptions, options) {
493
428
  };
494
429
  target.update(resolvedTargetKey, {
495
430
  data: updatedKeyed,
496
- isLoading: (0, import_core5.isAnyKeyLoading)(newIsLoading),
431
+ isLoading: (0, import_core4.isAnyKeyLoading)(newIsLoading),
497
432
  status: "Success"
498
433
  });
499
434
  previousId = currentId;
@@ -509,7 +444,7 @@ function collectKeyed(source, sourceKey, target, targetKeyOrOptions, options) {
509
444
  };
510
445
  target.update(resolvedTargetKey, {
511
446
  data: updatedKeyed,
512
- isLoading: (0, import_core5.isAnyKeyLoading)(newIsLoading)
447
+ isLoading: (0, import_core4.isAnyKeyLoading)(newIsLoading)
513
448
  });
514
449
  previousId = currentId;
515
450
  } else if (resourceState.data === void 0 && previousId !== void 0) {
@@ -525,7 +460,7 @@ function collectKeyed(source, sourceKey, target, targetKeyOrOptions, options) {
525
460
  };
526
461
  target.update(resolvedTargetKey, {
527
462
  data: updatedKeyed,
528
- isLoading: (0, import_core5.isAnyKeyLoading)(remainingLoading)
463
+ isLoading: (0, import_core4.isAnyKeyLoading)(remainingLoading)
529
464
  });
530
465
  previousId = void 0;
531
466
  } else if (resourceState.isLoading && currentId !== void 0) {
@@ -548,6 +483,175 @@ function collectKeyed(source, sourceKey, target, targetKeyOrOptions, options) {
548
483
  }
549
484
  return cleanup;
550
485
  }
486
+
487
+ // src/resource.ts
488
+ function resource() {
489
+ return {};
490
+ }
491
+
492
+ // src/store-builder.ts
493
+ function wireMirrors(store, mirrors) {
494
+ for (const def of mirrors) {
495
+ const sourceStore = (0, import_core5.inject)(def.sourceToken);
496
+ mirrorKey(sourceStore, def.sourceKey, store, def.targetKey);
497
+ }
498
+ return store;
499
+ }
500
+ function wireMirrorKeyed(store, defs) {
501
+ for (const def of defs) {
502
+ const sourceStore = (0, import_core5.inject)(def.sourceToken);
503
+ collectKeyed(sourceStore, def.sourceKey, store, def.targetKey, {
504
+ extractId: def.extractId
505
+ });
506
+ }
507
+ return store;
508
+ }
509
+ function createBuilder(accum, mirrors = [], mirrorKeyedDefs = []) {
510
+ return {
511
+ resource(key) {
512
+ return {
513
+ as() {
514
+ const nextAccum = {
515
+ ...accum,
516
+ [key]: resource()
517
+ };
518
+ return createBuilder(nextAccum, mirrors, mirrorKeyedDefs);
519
+ }
520
+ };
521
+ },
522
+ mirror(source, sourceKey, targetKey) {
523
+ const def = {
524
+ sourceToken: source,
525
+ sourceKey,
526
+ targetKey: targetKey ?? sourceKey
527
+ };
528
+ return createBuilder(accum, [...mirrors, def], mirrorKeyedDefs);
529
+ },
530
+ mirrorKeyed(source, sourceKey, options, targetKey) {
531
+ const def = {
532
+ sourceToken: source,
533
+ sourceKey,
534
+ targetKey: targetKey ?? sourceKey,
535
+ extractId: options.extractId
536
+ };
537
+ return createBuilder(accum, mirrors, [...mirrorKeyedDefs, def]);
538
+ },
539
+ build() {
540
+ return new import_core5.InjectionToken("FlurryxStore", {
541
+ providedIn: "root",
542
+ factory: () => {
543
+ const store = new DynamicStore(accum);
544
+ wireMirrors(store, mirrors);
545
+ wireMirrorKeyed(store, mirrorKeyedDefs);
546
+ return store;
547
+ }
548
+ });
549
+ }
550
+ };
551
+ }
552
+ function createConstrainedBuilder(_enumObj, accum, mirrors = [], mirrorKeyedDefs = []) {
553
+ return {
554
+ resource(key) {
555
+ return {
556
+ as() {
557
+ const nextAccum = {
558
+ ...accum,
559
+ [key]: resource()
560
+ };
561
+ return createConstrainedBuilder(
562
+ _enumObj,
563
+ nextAccum,
564
+ mirrors,
565
+ mirrorKeyedDefs
566
+ );
567
+ }
568
+ };
569
+ },
570
+ mirror(source, sourceKey, targetKey) {
571
+ const def = {
572
+ sourceToken: source,
573
+ sourceKey,
574
+ targetKey: targetKey ?? sourceKey
575
+ };
576
+ return createConstrainedBuilder(
577
+ _enumObj,
578
+ accum,
579
+ [...mirrors, def],
580
+ mirrorKeyedDefs
581
+ );
582
+ },
583
+ mirrorKeyed(source, sourceKey, options, targetKey) {
584
+ const def = {
585
+ sourceToken: source,
586
+ sourceKey,
587
+ targetKey: targetKey ?? sourceKey,
588
+ extractId: options.extractId
589
+ };
590
+ return createConstrainedBuilder(_enumObj, accum, mirrors, [
591
+ ...mirrorKeyedDefs,
592
+ def
593
+ ]);
594
+ },
595
+ build() {
596
+ return new import_core5.InjectionToken("FlurryxStore", {
597
+ providedIn: "root",
598
+ factory: () => {
599
+ const store = new DynamicStore(accum);
600
+ wireMirrors(store, mirrors);
601
+ wireMirrorKeyed(store, mirrorKeyedDefs);
602
+ return store;
603
+ }
604
+ });
605
+ }
606
+ };
607
+ }
608
+ function createInterfaceBuilder(mirrors = [], mirrorKeyedDefs = []) {
609
+ return {
610
+ mirror(source, sourceKey, targetKey) {
611
+ const def = {
612
+ sourceToken: source,
613
+ sourceKey,
614
+ targetKey: targetKey ?? sourceKey
615
+ };
616
+ return createInterfaceBuilder(
617
+ [...mirrors, def],
618
+ mirrorKeyedDefs
619
+ );
620
+ },
621
+ mirrorKeyed(source, sourceKey, options, targetKey) {
622
+ const def = {
623
+ sourceToken: source,
624
+ sourceKey,
625
+ targetKey: targetKey ?? sourceKey,
626
+ extractId: options.extractId
627
+ };
628
+ return createInterfaceBuilder(mirrors, [
629
+ ...mirrorKeyedDefs,
630
+ def
631
+ ]);
632
+ },
633
+ build() {
634
+ return new import_core5.InjectionToken("FlurryxStore", {
635
+ providedIn: "root",
636
+ factory: () => {
637
+ const store = new LazyStore();
638
+ wireMirrors(store, mirrors);
639
+ wireMirrorKeyed(store, mirrorKeyedDefs);
640
+ return store;
641
+ }
642
+ });
643
+ }
644
+ };
645
+ }
646
+ var Store = {
647
+ ...createBuilder({}),
648
+ for(enumObj) {
649
+ if (arguments.length === 0) {
650
+ return createInterfaceBuilder();
651
+ }
652
+ return createConstrainedBuilder(enumObj, {});
653
+ }
654
+ };
551
655
  // Annotate the CommonJS export names for ESM import in node:
552
656
  0 && (module.exports = {
553
657
  BaseStore,
@@ -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/resource.ts","../src/mirror-key.ts","../src/collect-keyed.ts"],"sourcesContent":["export { BaseStore } from \"./base-store\";\nexport { LazyStore } from \"./lazy-store\";\nexport { Store } from \"./store-builder\";\nexport { mirrorKey } from \"./mirror-key\";\nexport { collectKeyed } from \"./collect-keyed\";\nexport type { MirrorOptions } from \"./mirror-key\";\nexport type { CollectKeyedOptions } from \"./collect-keyed\";\nexport type { IStore, ConfigToData } from \"./types\";\n","import { signal, WritableSignal } from \"@angular/core\";\nimport {\n ResourceState,\n isAnyKeyLoading,\n isKeyedResourceData,\n createKeyedResourceData,\n type KeyedResourceKey,\n} from \"@flurryx/core\";\nimport type { IStore } from \"./types\";\n\ntype UpdateHooksMap = Map<\n unknown,\n Array<\n (\n nextState: ResourceState<unknown>,\n previousState: ResourceState<unknown>\n ) => void\n >\n>;\n\nconst updateHooksMap = new WeakMap<object, UpdateHooksMap>();\n\nexport abstract class BaseStore<\n TEnum extends Record<string, string | number>,\n TData extends { [K in keyof TEnum]: ResourceState<unknown> }\n> implements IStore<TData>\n{\n private readonly signalsState = new Map<\n keyof TEnum,\n WritableSignal<TData[keyof TEnum]>\n >();\n\n protected constructor(protected readonly storeEnum: TEnum) {\n this.initializeState();\n updateHooksMap.set(this, new Map());\n }\n\n get<K extends keyof TData>(key: K): WritableSignal<TData[K]> {\n return this.signalsState.get(key.toString()) as WritableSignal<TData[K]>;\n }\n\n onUpdate<K extends keyof TData>(\n key: K,\n callback: (state: TData[K], previousState: TData[K]) => void\n ): () => void {\n const hooks = updateHooksMap.get(this)!;\n if (!hooks.has(key)) {\n hooks.set(key, []);\n }\n hooks\n .get(key)!\n .push(\n callback as (\n nextState: ResourceState<unknown>,\n previousState: ResourceState<unknown>\n ) => void\n );\n\n return () => {\n const hooksMap = hooks.get(key);\n if (!hooksMap) {\n return;\n }\n const index = hooksMap.indexOf(\n callback as (\n nextState: ResourceState<unknown>,\n previousState: ResourceState<unknown>\n ) => void\n );\n if (index > -1) {\n hooksMap.splice(index, 1);\n }\n };\n }\n\n update<K extends keyof TData>(key: K, newState: Partial<TData[K]>): void {\n const currentState = this.signalsState.get(key.toString());\n if (!currentState) {\n return;\n }\n\n const previousState = currentState() as TData[K];\n currentState.update((state) => ({\n ...state,\n ...newState,\n }));\n\n const updatedState = currentState() as TData[K];\n this.notifyUpdateHooks(key, updatedState, previousState);\n }\n\n clearAll(): void {\n Object.keys(this.storeEnum).forEach((key) => {\n this.clear(key as keyof TData);\n });\n }\n\n clear<K extends keyof TData>(key: K): void {\n const currentState = this.signalsState.get(key.toString());\n if (!currentState) {\n return;\n }\n\n const previousState = currentState() as TData[K];\n const _typedKey = key as keyof TEnum;\n currentState.set({\n data: undefined,\n isLoading: false,\n status: undefined,\n errors: undefined,\n } as TData[typeof _typedKey]);\n\n const nextState = currentState() as TData[K];\n this.notifyUpdateHooks(key, nextState, previousState);\n }\n\n startLoading<K extends keyof TData>(key: K): void {\n const currentState = this.signalsState.get(key.toString());\n if (!currentState) {\n return;\n }\n\n const _typedKey = key as keyof TEnum;\n currentState.update(\n (state) =>\n ({\n ...state,\n status: undefined,\n isLoading: true,\n errors: undefined,\n } as TData[typeof _typedKey])\n );\n }\n\n stopLoading<K extends keyof TData>(key: K): void {\n const currentState = this.signalsState.get(key.toString());\n if (!currentState) {\n return;\n }\n\n const _typedKey = key as keyof TEnum;\n currentState.update(\n (state) =>\n ({\n ...state,\n isLoading: false,\n status: undefined,\n errors: undefined,\n } as TData[typeof _typedKey])\n );\n }\n\n updateKeyedOne<K extends keyof TData>(\n key: K,\n resourceKey: KeyedResourceKey,\n entity: unknown\n ): void {\n const currentState = this.signalsState.get(key.toString());\n if (!currentState) {\n return;\n }\n\n const state = currentState();\n const data = isKeyedResourceData(state.data)\n ? state.data\n : createKeyedResourceData();\n\n const nextErrors = { ...data.errors };\n delete nextErrors[resourceKey];\n\n const nextData = {\n ...data,\n entities: {\n ...data.entities,\n [resourceKey]: entity,\n },\n isLoading: {\n ...data.isLoading,\n [resourceKey]: false,\n },\n status: {\n ...data.status,\n [resourceKey]: \"Success\" as const,\n },\n errors: nextErrors,\n };\n\n this.update(key, {\n data: nextData as unknown,\n isLoading: isAnyKeyLoading(nextData.isLoading),\n status: undefined,\n errors: undefined,\n } as Partial<TData[K]>);\n }\n\n clearKeyedOne<K extends keyof TData>(\n key: K,\n resourceKey: KeyedResourceKey\n ): void {\n const currentState = this.signalsState.get(key.toString());\n if (!currentState) {\n return;\n }\n\n const previousState = currentState() as TData[K];\n const state = previousState as ResourceState<unknown>;\n if (!isKeyedResourceData(state.data)) {\n return;\n }\n\n const data = state.data;\n\n const nextEntities = { ...data.entities };\n delete nextEntities[resourceKey];\n\n const nextIsLoading = { ...data.isLoading };\n delete nextIsLoading[resourceKey];\n\n const nextStatus = { ...data.status };\n delete nextStatus[resourceKey];\n\n const nextErrors = { ...data.errors };\n delete nextErrors[resourceKey];\n\n const nextData = {\n ...data,\n entities: nextEntities,\n isLoading: nextIsLoading,\n status: nextStatus,\n errors: nextErrors,\n };\n\n const _typedKey = key as keyof TEnum;\n currentState.update(\n (prev) =>\n ({\n ...prev,\n data: nextData as unknown,\n status: undefined,\n isLoading: isAnyKeyLoading(nextIsLoading),\n errors: undefined,\n } as TData[typeof _typedKey])\n );\n\n const updatedState = currentState() as TData[K];\n this.notifyUpdateHooks(key, updatedState, previousState);\n }\n\n startKeyedLoading<K extends keyof TData>(\n key: K,\n resourceKey: KeyedResourceKey\n ): void {\n const currentState = this.signalsState.get(key.toString());\n if (!currentState) {\n return;\n }\n\n const _typedKey = key as keyof TEnum;\n const state = currentState();\n if (!isKeyedResourceData(state.data)) {\n this.startLoading(key);\n return;\n }\n\n const previousState = state as TData[K];\n const data = state.data;\n\n const nextIsLoading = {\n ...data.isLoading,\n [resourceKey]: true,\n } as typeof data.isLoading;\n\n const nextStatus: typeof data.status = {\n ...data.status,\n };\n delete nextStatus[resourceKey];\n\n const nextErrors: typeof data.errors = {\n ...data.errors,\n };\n delete nextErrors[resourceKey];\n\n const nextData = {\n ...data,\n isLoading: nextIsLoading,\n status: nextStatus,\n errors: nextErrors,\n };\n\n currentState.update(\n (previous) =>\n ({\n ...previous,\n data: nextData,\n status: undefined,\n isLoading: isAnyKeyLoading(nextIsLoading),\n errors: undefined,\n } as TData[typeof _typedKey])\n );\n\n const updatedState = currentState() as TData[K];\n this.notifyUpdateHooks(key, updatedState, previousState);\n }\n\n private notifyUpdateHooks<K extends keyof TData>(\n key: K,\n nextState: TData[K],\n previousState: TData[K]\n ): void {\n const hooks = updateHooksMap.get(this);\n const keyHooks = hooks?.get(key);\n if (!keyHooks) {\n return;\n }\n\n keyHooks.forEach((hook) =>\n hook(\n nextState as ResourceState<unknown>,\n previousState as ResourceState<unknown>\n )\n );\n }\n\n private initializeState(): void {\n Object.keys(this.storeEnum).forEach((key) => {\n const _typedKey = key as keyof TEnum;\n const initialState: ResourceState<unknown> = {\n data: undefined,\n isLoading: false,\n status: undefined,\n errors: undefined,\n };\n this.signalsState.set(\n _typedKey,\n signal<TData[typeof _typedKey]>(initialState as TData[typeof _typedKey])\n );\n });\n }\n}\n","import { signal, WritableSignal } from '@angular/core';\nimport type { ResourceState } from '@flurryx/core';\nimport type { IStore } from './types';\n\ntype UpdateCallback = (\n nextState: ResourceState<unknown>,\n previousState: ResourceState<unknown>\n) => void;\n\nfunction createDefaultState<T>(): ResourceState<T> {\n return {\n data: undefined,\n isLoading: false,\n status: undefined,\n errors: undefined,\n };\n}\n\n/**\n * Lazy store that creates signals on first access.\n * Used by the `Store.for<Config>().build()` API where keys are\n * known only at the type level (no runtime enum).\n */\nexport class LazyStore<\n TData extends Record<string, ResourceState<unknown>>,\n> implements IStore<TData>\n{\n private readonly signals = new Map<string, WritableSignal<ResourceState<unknown>>>();\n private readonly hooks = new Map<string, UpdateCallback[]>();\n\n private getOrCreate<K extends keyof TData & string>(\n key: K\n ): WritableSignal<TData[K]> {\n let sig = this.signals.get(key);\n if (!sig) {\n sig = signal<ResourceState<unknown>>(createDefaultState());\n this.signals.set(key, sig);\n }\n return sig as WritableSignal<TData[K]>;\n }\n\n get<K extends keyof TData & string>(key: K): WritableSignal<TData[K]> {\n return this.getOrCreate(key);\n }\n\n update<K extends keyof TData & string>(\n key: K,\n newState: Partial<TData[K]>\n ): void {\n const sig = this.getOrCreate(key);\n const previousState = sig();\n sig.update((state) => ({ ...state, ...newState }));\n const nextState = sig();\n this.notifyHooks(key, nextState, previousState);\n }\n\n clear<K extends keyof TData & string>(key: K): void {\n const sig = this.getOrCreate(key);\n const previousState = sig();\n sig.set(createDefaultState() as TData[K]);\n const nextState = sig();\n this.notifyHooks(key, nextState, previousState);\n }\n\n clearAll(): void {\n for (const key of this.signals.keys()) {\n this.clear(key as keyof TData & string);\n }\n }\n\n startLoading<K extends keyof TData & string>(key: K): void {\n const sig = this.getOrCreate(key);\n sig.update(\n (state) =>\n ({\n ...state,\n status: undefined,\n isLoading: true,\n errors: undefined,\n }) as TData[K]\n );\n }\n\n stopLoading<K extends keyof TData & string>(key: K): void {\n const sig = this.getOrCreate(key);\n sig.update(\n (state) =>\n ({\n ...state,\n isLoading: false,\n status: undefined,\n errors: undefined,\n }) as TData[K]\n );\n }\n\n onUpdate<K extends keyof TData & string>(\n key: K,\n callback: (state: TData[K], previousState: TData[K]) => void\n ): () => void {\n if (!this.hooks.has(key)) {\n this.hooks.set(key, []);\n }\n const typedCallback = callback as UpdateCallback;\n this.hooks.get(key)!.push(typedCallback);\n\n return () => {\n const keyHooks = this.hooks.get(key);\n if (!keyHooks) {\n return;\n }\n const index = keyHooks.indexOf(typedCallback);\n if (index > -1) {\n keyHooks.splice(index, 1);\n }\n };\n }\n\n private notifyHooks<K extends keyof TData & string>(\n key: K,\n nextState: TData[K],\n previousState: TData[K]\n ): void {\n const keyHooks = this.hooks.get(key);\n if (!keyHooks) {\n return;\n }\n keyHooks.forEach((hook) =>\n hook(\n nextState as ResourceState<unknown>,\n previousState as ResourceState<unknown>\n )\n );\n }\n}\n","import { InjectionToken } from \"@angular/core\";\nimport { BaseStore } from \"./base-store\";\nimport { DynamicStore } from \"./dynamic-store\";\nimport { LazyStore } from \"./lazy-store\";\nimport { resource } from \"./resource\";\nimport type {\n StoreConfig,\n ResourceDef,\n InferEnum,\n InferData,\n ConfigToData,\n IStore,\n} from \"./types\";\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 build(): InjectionToken<BaseStore<InferEnum<TAccum>, InferData<TAccum>>>;\n}\n\nfunction createBuilder<TAccum extends StoreConfig>(\n accum: TAccum\n): StoreBuilder<TAccum> {\n return {\n resource<TKey extends string>(key: TKey): AsStep<TAccum, TKey> {\n return {\n as<T>(): StoreBuilder<TAccum & Record<TKey, ResourceDef<T>>> {\n const nextAccum = {\n ...accum,\n [key]: resource<T>(),\n } as TAccum & Record<TKey, ResourceDef<T>>;\n return createBuilder(nextAccum);\n },\n };\n },\n build() {\n return new InjectionToken<\n BaseStore<InferEnum<TAccum>, InferData<TAccum>>\n >(\"FlurryxStore\", {\n providedIn: \"root\",\n factory: () => new DynamicStore(accum),\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 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>(_enumObj: TEnum, accum: TAccum): ConstrainedBuilder<TEnum, TAccum> {\n return {\n resource<TKey extends string>(\n key: TKey\n ): ConstrainedAsStep<TEnum, TAccum, TKey> {\n return {\n as<T>(): ConstrainedBuilder<\n TEnum,\n TAccum & Record<TKey, ResourceDef<T>>\n > {\n const nextAccum = {\n ...accum,\n [key]: resource<T>(),\n } as TAccum & Record<TKey, ResourceDef<T>>;\n return createConstrainedBuilder(_enumObj, nextAccum);\n },\n };\n },\n build() {\n return new InjectionToken<\n BaseStore<InferEnum<TAccum>, InferData<TAccum>>\n >(\"FlurryxStore\", {\n providedIn: \"root\",\n factory: () => new DynamicStore(accum),\n });\n },\n } as ConstrainedBuilder<TEnum, TAccum>;\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>>(): {\n build(): InjectionToken<IStore<ConfigToData<TConfig>>>;\n };\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 {\n build() {\n return new InjectionToken(\"FlurryxStore\", {\n providedIn: \"root\",\n factory: () => new LazyStore(),\n });\n },\n };\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 { ResourceDef } from './types';\n\n/**\n * Creates a phantom-typed resource definition marker.\n * Zero runtime cost — returns an empty object that only carries type info.\n *\n * @example\n * const config = {\n * customers: resource<Customer[]>(),\n * customerDetails: resource<Customer>(),\n * };\n */\nexport function resource<T>(): ResourceDef<T> {\n return {} as ResourceDef<T>;\n}\n","import type { 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"],"mappings":"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","names":["import_core","import_core","import_core","import_core"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/base-store.ts","../src/lazy-store.ts","../src/store-builder.ts","../src/dynamic-store.ts","../src/mirror-key.ts","../src/collect-keyed.ts","../src/resource.ts"],"sourcesContent":["export { BaseStore } from \"./base-store\";\nexport { LazyStore } from \"./lazy-store\";\nexport { Store } from \"./store-builder\";\nexport { mirrorKey } from \"./mirror-key\";\nexport { collectKeyed } from \"./collect-keyed\";\nexport type { MirrorOptions } from \"./mirror-key\";\nexport type { CollectKeyedOptions } from \"./collect-keyed\";\nexport type { IStore, ConfigToData } from \"./types\";\n","import { signal, WritableSignal } from \"@angular/core\";\nimport {\n ResourceState,\n isAnyKeyLoading,\n isKeyedResourceData,\n createKeyedResourceData,\n type KeyedResourceKey,\n} from \"@flurryx/core\";\nimport type { IStore } from \"./types\";\n\ntype UpdateHooksMap = Map<\n unknown,\n Array<\n (\n nextState: ResourceState<unknown>,\n previousState: ResourceState<unknown>\n ) => void\n >\n>;\n\nconst updateHooksMap = new WeakMap<object, UpdateHooksMap>();\n\nexport abstract class BaseStore<\n TEnum extends Record<string, string | number>,\n TData extends { [K in keyof TEnum]: ResourceState<unknown> }\n> implements IStore<TData>\n{\n private readonly signalsState = new Map<\n keyof TEnum,\n WritableSignal<TData[keyof TEnum]>\n >();\n\n protected constructor(protected readonly storeEnum: TEnum) {\n this.initializeState();\n updateHooksMap.set(this, new Map());\n }\n\n get<K extends keyof TData>(key: K): WritableSignal<TData[K]> {\n return this.signalsState.get(key.toString()) as WritableSignal<TData[K]>;\n }\n\n onUpdate<K extends keyof TData>(\n key: K,\n callback: (state: TData[K], previousState: TData[K]) => void\n ): () => void {\n const hooks = updateHooksMap.get(this)!;\n if (!hooks.has(key)) {\n hooks.set(key, []);\n }\n hooks\n .get(key)!\n .push(\n callback as (\n nextState: ResourceState<unknown>,\n previousState: ResourceState<unknown>\n ) => void\n );\n\n return () => {\n const hooksMap = hooks.get(key);\n if (!hooksMap) {\n return;\n }\n const index = hooksMap.indexOf(\n callback as (\n nextState: ResourceState<unknown>,\n previousState: ResourceState<unknown>\n ) => void\n );\n if (index > -1) {\n hooksMap.splice(index, 1);\n }\n };\n }\n\n update<K extends keyof TData>(key: K, newState: Partial<TData[K]>): void {\n const currentState = this.signalsState.get(key.toString());\n if (!currentState) {\n return;\n }\n\n const previousState = currentState() as TData[K];\n currentState.update((state) => ({\n ...state,\n ...newState,\n }));\n\n const updatedState = currentState() as TData[K];\n this.notifyUpdateHooks(key, updatedState, previousState);\n }\n\n clearAll(): void {\n Object.keys(this.storeEnum).forEach((key) => {\n this.clear(key as keyof TData);\n });\n }\n\n clear<K extends keyof TData>(key: K): void {\n const currentState = this.signalsState.get(key.toString());\n if (!currentState) {\n return;\n }\n\n const previousState = currentState() as TData[K];\n const _typedKey = key as keyof TEnum;\n currentState.set({\n data: undefined,\n isLoading: false,\n status: undefined,\n errors: undefined,\n } as TData[typeof _typedKey]);\n\n const nextState = currentState() as TData[K];\n this.notifyUpdateHooks(key, nextState, previousState);\n }\n\n startLoading<K extends keyof TData>(key: K): void {\n const currentState = this.signalsState.get(key.toString());\n if (!currentState) {\n return;\n }\n\n const _typedKey = key as keyof TEnum;\n currentState.update(\n (state) =>\n ({\n ...state,\n status: undefined,\n isLoading: true,\n errors: undefined,\n } as TData[typeof _typedKey])\n );\n }\n\n stopLoading<K extends keyof TData>(key: K): void {\n const currentState = this.signalsState.get(key.toString());\n if (!currentState) {\n return;\n }\n\n const _typedKey = key as keyof TEnum;\n currentState.update(\n (state) =>\n ({\n ...state,\n isLoading: false,\n status: undefined,\n errors: undefined,\n } as TData[typeof _typedKey])\n );\n }\n\n updateKeyedOne<K extends keyof TData>(\n key: K,\n resourceKey: KeyedResourceKey,\n entity: unknown\n ): void {\n const currentState = this.signalsState.get(key.toString());\n if (!currentState) {\n return;\n }\n\n const state = currentState();\n const data = isKeyedResourceData(state.data)\n ? state.data\n : createKeyedResourceData();\n\n const nextErrors = { ...data.errors };\n delete nextErrors[resourceKey];\n\n const nextData = {\n ...data,\n entities: {\n ...data.entities,\n [resourceKey]: entity,\n },\n isLoading: {\n ...data.isLoading,\n [resourceKey]: false,\n },\n status: {\n ...data.status,\n [resourceKey]: \"Success\" as const,\n },\n errors: nextErrors,\n };\n\n this.update(key, {\n data: nextData as unknown,\n isLoading: isAnyKeyLoading(nextData.isLoading),\n status: undefined,\n errors: undefined,\n } as Partial<TData[K]>);\n }\n\n clearKeyedOne<K extends keyof TData>(\n key: K,\n resourceKey: KeyedResourceKey\n ): void {\n const currentState = this.signalsState.get(key.toString());\n if (!currentState) {\n return;\n }\n\n const previousState = currentState() as TData[K];\n const state = previousState as ResourceState<unknown>;\n if (!isKeyedResourceData(state.data)) {\n return;\n }\n\n const data = state.data;\n\n const nextEntities = { ...data.entities };\n delete nextEntities[resourceKey];\n\n const nextIsLoading = { ...data.isLoading };\n delete nextIsLoading[resourceKey];\n\n const nextStatus = { ...data.status };\n delete nextStatus[resourceKey];\n\n const nextErrors = { ...data.errors };\n delete nextErrors[resourceKey];\n\n const nextData = {\n ...data,\n entities: nextEntities,\n isLoading: nextIsLoading,\n status: nextStatus,\n errors: nextErrors,\n };\n\n const _typedKey = key as keyof TEnum;\n currentState.update(\n (prev) =>\n ({\n ...prev,\n data: nextData as unknown,\n status: undefined,\n isLoading: isAnyKeyLoading(nextIsLoading),\n errors: undefined,\n } as TData[typeof _typedKey])\n );\n\n const updatedState = currentState() as TData[K];\n this.notifyUpdateHooks(key, updatedState, previousState);\n }\n\n startKeyedLoading<K extends keyof TData>(\n key: K,\n resourceKey: KeyedResourceKey\n ): void {\n const currentState = this.signalsState.get(key.toString());\n if (!currentState) {\n return;\n }\n\n const _typedKey = key as keyof TEnum;\n const state = currentState();\n if (!isKeyedResourceData(state.data)) {\n this.startLoading(key);\n return;\n }\n\n const previousState = state as TData[K];\n const data = state.data;\n\n const nextIsLoading = {\n ...data.isLoading,\n [resourceKey]: true,\n } as typeof data.isLoading;\n\n const nextStatus: typeof data.status = {\n ...data.status,\n };\n delete nextStatus[resourceKey];\n\n const nextErrors: typeof data.errors = {\n ...data.errors,\n };\n delete nextErrors[resourceKey];\n\n const nextData = {\n ...data,\n isLoading: nextIsLoading,\n status: nextStatus,\n errors: nextErrors,\n };\n\n currentState.update(\n (previous) =>\n ({\n ...previous,\n data: nextData,\n status: undefined,\n isLoading: isAnyKeyLoading(nextIsLoading),\n errors: undefined,\n } as TData[typeof _typedKey])\n );\n\n const updatedState = currentState() as TData[K];\n this.notifyUpdateHooks(key, updatedState, previousState);\n }\n\n private notifyUpdateHooks<K extends keyof TData>(\n key: K,\n nextState: TData[K],\n previousState: TData[K]\n ): void {\n const hooks = updateHooksMap.get(this);\n const keyHooks = hooks?.get(key);\n if (!keyHooks) {\n return;\n }\n\n keyHooks.forEach((hook) =>\n hook(\n nextState as ResourceState<unknown>,\n previousState as ResourceState<unknown>\n )\n );\n }\n\n private initializeState(): void {\n Object.keys(this.storeEnum).forEach((key) => {\n const _typedKey = key as keyof TEnum;\n const initialState: ResourceState<unknown> = {\n data: undefined,\n isLoading: false,\n status: undefined,\n errors: undefined,\n };\n this.signalsState.set(\n _typedKey,\n signal<TData[typeof _typedKey]>(initialState as TData[typeof _typedKey])\n );\n });\n }\n}\n","import { signal, WritableSignal } from '@angular/core';\nimport type { ResourceState } from '@flurryx/core';\nimport type { IStore } from './types';\n\ntype UpdateCallback = (\n nextState: ResourceState<unknown>,\n previousState: ResourceState<unknown>\n) => void;\n\nfunction createDefaultState<T>(): ResourceState<T> {\n return {\n data: undefined,\n isLoading: false,\n status: undefined,\n errors: undefined,\n };\n}\n\n/**\n * Lazy store that creates signals on first access.\n * Used by the `Store.for<Config>().build()` API where keys are\n * known only at the type level (no runtime enum).\n */\nexport class LazyStore<\n TData extends Record<string, ResourceState<unknown>>,\n> implements IStore<TData>\n{\n private readonly signals = new Map<string, WritableSignal<ResourceState<unknown>>>();\n private readonly hooks = new Map<string, UpdateCallback[]>();\n\n private getOrCreate<K extends keyof TData & string>(\n key: K\n ): WritableSignal<TData[K]> {\n let sig = this.signals.get(key);\n if (!sig) {\n sig = signal<ResourceState<unknown>>(createDefaultState());\n this.signals.set(key, sig);\n }\n return sig as WritableSignal<TData[K]>;\n }\n\n get<K extends keyof TData & string>(key: K): WritableSignal<TData[K]> {\n return this.getOrCreate(key);\n }\n\n update<K extends keyof TData & string>(\n key: K,\n newState: Partial<TData[K]>\n ): void {\n const sig = this.getOrCreate(key);\n const previousState = sig();\n sig.update((state) => ({ ...state, ...newState }));\n const nextState = sig();\n this.notifyHooks(key, nextState, previousState);\n }\n\n clear<K extends keyof TData & string>(key: K): void {\n const sig = this.getOrCreate(key);\n const previousState = sig();\n sig.set(createDefaultState() as TData[K]);\n const nextState = sig();\n this.notifyHooks(key, nextState, previousState);\n }\n\n clearAll(): void {\n for (const key of this.signals.keys()) {\n this.clear(key as keyof TData & string);\n }\n }\n\n startLoading<K extends keyof TData & string>(key: K): void {\n const sig = this.getOrCreate(key);\n sig.update(\n (state) =>\n ({\n ...state,\n status: undefined,\n isLoading: true,\n errors: undefined,\n }) as TData[K]\n );\n }\n\n stopLoading<K extends keyof TData & string>(key: K): void {\n const sig = this.getOrCreate(key);\n sig.update(\n (state) =>\n ({\n ...state,\n isLoading: false,\n status: undefined,\n errors: undefined,\n }) as TData[K]\n );\n }\n\n onUpdate<K extends keyof TData & string>(\n key: K,\n callback: (state: TData[K], previousState: TData[K]) => void\n ): () => void {\n if (!this.hooks.has(key)) {\n this.hooks.set(key, []);\n }\n const typedCallback = callback as UpdateCallback;\n this.hooks.get(key)!.push(typedCallback);\n\n return () => {\n const keyHooks = this.hooks.get(key);\n if (!keyHooks) {\n return;\n }\n const index = keyHooks.indexOf(typedCallback);\n if (index > -1) {\n keyHooks.splice(index, 1);\n }\n };\n }\n\n private notifyHooks<K extends keyof TData & string>(\n key: K,\n nextState: TData[K],\n previousState: TData[K]\n ): void {\n const keyHooks = this.hooks.get(key);\n if (!keyHooks) {\n return;\n }\n keyHooks.forEach((hook) =>\n hook(\n nextState as ResourceState<unknown>,\n previousState as ResourceState<unknown>\n )\n );\n }\n}\n","import { InjectionToken, inject } from \"@angular/core\";\nimport { BaseStore } from \"./base-store\";\nimport { DynamicStore } from \"./dynamic-store\";\nimport { LazyStore } from \"./lazy-store\";\nimport { mirrorKey } from \"./mirror-key\";\nimport { collectKeyed } from \"./collect-keyed\";\nimport { resource } from \"./resource\";\nimport type { ResourceState, KeyedResourceKey } from \"@flurryx/core\";\nimport type {\n StoreConfig,\n ResourceDef,\n InferEnum,\n InferData,\n ConfigToData,\n IStore,\n} from \"./types\";\n\n// ---------------------------------------------------------------------------\n// Mirror definition — accumulated by builders, wired up in build() factory\n// ---------------------------------------------------------------------------\n\ninterface MirrorDef {\n readonly sourceToken: InjectionToken<\n IStore<Record<string, ResourceState<unknown>>>\n >;\n readonly sourceKey: string;\n readonly targetKey: string;\n}\n\nfunction wireMirrors<\n TStore extends IStore<Record<string, ResourceState<unknown>>>\n>(store: TStore, mirrors: readonly MirrorDef[]): TStore {\n for (const def of mirrors) {\n const sourceStore = inject(def.sourceToken);\n mirrorKey(sourceStore, def.sourceKey, store, def.targetKey);\n }\n return store;\n}\n\n// ---------------------------------------------------------------------------\n// MirrorKeyed definition — accumulated by builders, wired up in build()\n// ---------------------------------------------------------------------------\n\ninterface MirrorKeyedDef {\n readonly sourceToken: InjectionToken<\n IStore<Record<string, ResourceState<unknown>>>\n >;\n readonly sourceKey: string;\n readonly targetKey: string;\n readonly extractId: (data: unknown) => KeyedResourceKey | undefined;\n}\n\nfunction wireMirrorKeyed<\n TStore extends IStore<Record<string, ResourceState<unknown>>>\n>(store: TStore, defs: readonly MirrorKeyedDef[]): TStore {\n for (const def of defs) {\n const sourceStore = inject(def.sourceToken);\n collectKeyed(sourceStore, def.sourceKey, store, def.targetKey, {\n extractId: def.extractId,\n });\n }\n return store;\n}\n\n// ---------------------------------------------------------------------------\n// Unconstrained builder (existing API)\n// ---------------------------------------------------------------------------\n\n/**\n * Intermediate builder step after .resource('key') — awaits .as<T>().\n */\ninterface AsStep<TAccum extends StoreConfig, TKey extends string> {\n as<T>(): StoreBuilder<TAccum & Record<TKey, ResourceDef<T>>>;\n}\n\n/**\n * Fluent builder for creating stores.\n * Accumulates resource definitions then produces an InjectionToken on .build().\n */\ninterface StoreBuilder<TAccum extends StoreConfig> {\n resource<TKey extends string>(key: TKey): AsStep<TAccum, TKey>;\n mirror<TSourceData extends Record<string, ResourceState<unknown>>>(\n source: InjectionToken<IStore<TSourceData>>,\n sourceKey: keyof TSourceData & string,\n targetKey?: keyof TAccum & string\n ): StoreBuilder<TAccum>;\n mirrorKeyed<\n TSourceData extends Record<string, ResourceState<unknown>>,\n TEntity\n >(\n source: InjectionToken<IStore<TSourceData>>,\n sourceKey: keyof TSourceData & string,\n options: {\n extractId: (data: TEntity | undefined) => KeyedResourceKey | undefined;\n },\n targetKey?: keyof TAccum & string\n ): StoreBuilder<TAccum>;\n build(): InjectionToken<BaseStore<InferEnum<TAccum>, InferData<TAccum>>>;\n}\n\nfunction createBuilder<TAccum extends StoreConfig>(\n accum: TAccum,\n mirrors: readonly MirrorDef[] = [],\n mirrorKeyedDefs: readonly MirrorKeyedDef[] = []\n): StoreBuilder<TAccum> {\n return {\n resource<TKey extends string>(key: TKey): AsStep<TAccum, TKey> {\n return {\n as<T>(): StoreBuilder<TAccum & Record<TKey, ResourceDef<T>>> {\n const nextAccum = {\n ...accum,\n [key]: resource<T>(),\n } as TAccum & Record<TKey, ResourceDef<T>>;\n return createBuilder(nextAccum, mirrors, mirrorKeyedDefs);\n },\n };\n },\n mirror(source, sourceKey, targetKey?) {\n const def: MirrorDef = {\n sourceToken: source as InjectionToken<\n IStore<Record<string, ResourceState<unknown>>>\n >,\n sourceKey,\n targetKey: (targetKey ?? sourceKey) as string,\n };\n return createBuilder(accum, [...mirrors, def], mirrorKeyedDefs);\n },\n mirrorKeyed(source, sourceKey, options, targetKey?) {\n const def: MirrorKeyedDef = {\n sourceToken: source as InjectionToken<\n IStore<Record<string, ResourceState<unknown>>>\n >,\n sourceKey,\n targetKey: (targetKey ?? sourceKey) as string,\n extractId: options.extractId as (\n data: unknown\n ) => KeyedResourceKey | undefined,\n };\n return createBuilder(accum, mirrors, [...mirrorKeyedDefs, def]);\n },\n build() {\n return new InjectionToken<\n BaseStore<InferEnum<TAccum>, InferData<TAccum>>\n >(\"FlurryxStore\", {\n providedIn: \"root\",\n factory: () => {\n const store = new DynamicStore(accum);\n wireMirrors(store, mirrors);\n wireMirrorKeyed(store, mirrorKeyedDefs);\n return store as BaseStore<InferEnum<TAccum>, InferData<TAccum>>;\n },\n });\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// Constrained builder (.for(enum) API)\n// ---------------------------------------------------------------------------\n\n/** Keys from the enum that have NOT yet been defined. */\ntype Remaining<\n TEnum extends Record<string, string>,\n TAccum extends StoreConfig\n> = Exclude<keyof TEnum & string, keyof TAccum>;\n\n/** Intermediate .as<T>() step for the constrained builder. */\ninterface ConstrainedAsStep<\n TEnum extends Record<string, string>,\n TAccum extends StoreConfig,\n TKey extends string\n> {\n as<T>(): ConstrainedBuilder<TEnum, TAccum & Record<TKey, ResourceDef<T>>>;\n}\n\n/**\n * Constrained builder — only allows keys from the enum that haven't been\n * defined yet. `.build()` is only available when all keys are accounted for.\n */\ntype ConstrainedBuilder<\n TEnum extends Record<string, string>,\n TAccum extends StoreConfig\n> = [Remaining<TEnum, TAccum>] extends [never]\n ? {\n mirror<TSourceData extends Record<string, ResourceState<unknown>>>(\n source: InjectionToken<IStore<TSourceData>>,\n sourceKey: keyof TSourceData & string,\n targetKey?: keyof TAccum & string\n ): ConstrainedBuilder<TEnum, TAccum>;\n mirrorKeyed<\n TSourceData extends Record<string, ResourceState<unknown>>,\n TEntity\n >(\n source: InjectionToken<IStore<TSourceData>>,\n sourceKey: keyof TSourceData & string,\n options: {\n extractId: (\n data: TEntity | undefined\n ) => KeyedResourceKey | undefined;\n },\n targetKey?: keyof TAccum & string\n ): ConstrainedBuilder<TEnum, TAccum>;\n build(): InjectionToken<BaseStore<InferEnum<TAccum>, InferData<TAccum>>>;\n }\n : {\n resource<TKey extends Remaining<TEnum, TAccum>>(\n key: TKey\n ): ConstrainedAsStep<TEnum, TAccum, TKey>;\n };\n\nfunction createConstrainedBuilder<\n TEnum extends Record<string, string>,\n TAccum extends StoreConfig\n>(\n _enumObj: TEnum,\n accum: TAccum,\n mirrors: readonly MirrorDef[] = [],\n mirrorKeyedDefs: readonly MirrorKeyedDef[] = []\n): ConstrainedBuilder<TEnum, TAccum> {\n return {\n resource<TKey extends string>(\n key: TKey\n ): ConstrainedAsStep<TEnum, TAccum, TKey> {\n return {\n as<T>(): ConstrainedBuilder<\n TEnum,\n TAccum & Record<TKey, ResourceDef<T>>\n > {\n const nextAccum = {\n ...accum,\n [key]: resource<T>(),\n } as TAccum & Record<TKey, ResourceDef<T>>;\n return createConstrainedBuilder(\n _enumObj,\n nextAccum,\n mirrors,\n mirrorKeyedDefs\n );\n },\n };\n },\n mirror(\n source: InjectionToken<IStore<Record<string, ResourceState<unknown>>>>,\n sourceKey: string,\n targetKey?: string\n ) {\n const def: MirrorDef = {\n sourceToken: source,\n sourceKey,\n targetKey: targetKey ?? sourceKey,\n };\n return createConstrainedBuilder(\n _enumObj,\n accum,\n [...mirrors, def],\n mirrorKeyedDefs\n );\n },\n mirrorKeyed(\n source: InjectionToken<IStore<Record<string, ResourceState<unknown>>>>,\n sourceKey: string,\n options: {\n extractId: (data: unknown) => KeyedResourceKey | undefined;\n },\n targetKey?: string\n ) {\n const def: MirrorKeyedDef = {\n sourceToken: source,\n sourceKey,\n targetKey: targetKey ?? sourceKey,\n extractId: options.extractId,\n };\n return createConstrainedBuilder(_enumObj, accum, mirrors, [\n ...mirrorKeyedDefs,\n def,\n ]);\n },\n build() {\n return new InjectionToken<\n BaseStore<InferEnum<TAccum>, InferData<TAccum>>\n >(\"FlurryxStore\", {\n providedIn: \"root\",\n factory: () => {\n const store = new DynamicStore(accum);\n wireMirrors(store, mirrors);\n wireMirrorKeyed(store, mirrorKeyedDefs);\n return store as BaseStore<InferEnum<TAccum>, InferData<TAccum>>;\n },\n });\n },\n } as ConstrainedBuilder<TEnum, TAccum>;\n}\n\n// ---------------------------------------------------------------------------\n// Interface-based builder (Store.for<Config>() API)\n// ---------------------------------------------------------------------------\n\ninterface InterfaceBuilder<TConfig extends Record<string, unknown>> {\n mirror<TSourceData extends Record<string, ResourceState<unknown>>>(\n source: InjectionToken<IStore<TSourceData>>,\n sourceKey: keyof TSourceData & string,\n targetKey?: keyof TConfig & string\n ): InterfaceBuilder<TConfig>;\n mirrorKeyed<\n TSourceData extends Record<string, ResourceState<unknown>>,\n TEntity\n >(\n source: InjectionToken<IStore<TSourceData>>,\n sourceKey: keyof TSourceData & string,\n options: {\n extractId: (data: TEntity | undefined) => KeyedResourceKey | undefined;\n },\n targetKey?: keyof TConfig & string\n ): InterfaceBuilder<TConfig>;\n build(): InjectionToken<IStore<ConfigToData<TConfig>>>;\n}\n\nfunction createInterfaceBuilder<TConfig extends Record<string, unknown>>(\n mirrors: readonly MirrorDef[] = [],\n mirrorKeyedDefs: readonly MirrorKeyedDef[] = []\n): InterfaceBuilder<TConfig> {\n return {\n mirror(source, sourceKey, targetKey?) {\n const def: MirrorDef = {\n sourceToken: source as InjectionToken<\n IStore<Record<string, ResourceState<unknown>>>\n >,\n sourceKey,\n targetKey: (targetKey ?? sourceKey) as string,\n };\n return createInterfaceBuilder<TConfig>(\n [...mirrors, def],\n mirrorKeyedDefs\n );\n },\n mirrorKeyed(source, sourceKey, options, targetKey?) {\n const def: MirrorKeyedDef = {\n sourceToken: source as InjectionToken<\n IStore<Record<string, ResourceState<unknown>>>\n >,\n sourceKey,\n targetKey: (targetKey ?? sourceKey) as string,\n extractId: options.extractId as (\n data: unknown\n ) => KeyedResourceKey | undefined,\n };\n return createInterfaceBuilder<TConfig>(mirrors, [\n ...mirrorKeyedDefs,\n def,\n ]);\n },\n build() {\n return new InjectionToken(\"FlurryxStore\", {\n providedIn: \"root\",\n factory: () => {\n const store = new LazyStore() as IStore<\n Record<string, ResourceState<unknown>>\n >;\n wireMirrors(store, mirrors);\n wireMirrorKeyed(store, mirrorKeyedDefs);\n return store as unknown as IStore<ConfigToData<TConfig>>;\n },\n });\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// Public entry point\n// ---------------------------------------------------------------------------\n\ninterface StoreEntry {\n /**\n * Define a named resource slot.\n * Chain .as<T>() to assign its type, then continue with more .resource() calls\n * or call .build() when done.\n */\n resource<TKey extends string>(\n key: TKey\n ): {\n as<T>(): StoreBuilder<Record<TKey, ResourceDef<T>>>;\n };\n\n /**\n * Interface-based builder: pass a config interface as a generic.\n * No runtime argument needed — keys and types are inferred from the interface.\n *\n * @example\n * interface ChatStoreConfig {\n * SESSIONS: ChatSession[];\n * MESSAGES: ChatMessage[];\n * }\n * const ChatStore = Store.for<ChatStoreConfig>().build();\n */\n for<TConfig extends Record<string, unknown>>(): InterfaceBuilder<TConfig>;\n\n /**\n * Bind the builder to an enum object for compile-time key validation.\n *\n * @example\n * const Enum = { A: 'A', B: 'B' } as const;\n * const MyStore = Store.for(Enum)\n * .resource('A').as<string>()\n * .resource('B').as<number>()\n * .build();\n */\n for<TEnum extends Record<string, string>>(\n enumObj: TEnum\n ): ConstrainedBuilder<TEnum, Record<string, never>>;\n}\n\n/**\n * Fluent store builder entry point.\n *\n * @example\n * // Unconstrained\n * export const CustomersStore = Store\n * .resource('customers').as<Customer[]>()\n * .resource('customerDetails').as<Customer>()\n * .build();\n *\n * @example\n * // Constrained with enum\n * const Enum = { SESSIONS: 'SESSIONS', MESSAGES: 'MESSAGES' } as const;\n * export const ChatStore = Store.for(Enum)\n * .resource('SESSIONS').as<Session[]>()\n * .resource('MESSAGES').as<Message[]>()\n * .build();\n */\nexport const Store: StoreEntry = {\n ...createBuilder({} as StoreConfig),\n for(enumObj?: Record<string, string>) {\n if (arguments.length === 0) {\n return createInterfaceBuilder();\n }\n return createConstrainedBuilder(enumObj!, {} as Record<string, never>);\n },\n};\n","import { BaseStore } from './base-store';\nimport type { StoreConfig, InferEnum, InferData } from './types';\n\n/**\n * Internal concrete subclass of BaseStore.\n * Auto-generates an identity enum from config keys.\n * NOT publicly exported — consumers interact via BaseStore interface.\n */\nexport class DynamicStore<\n TConfig extends StoreConfig,\n> extends BaseStore<InferEnum<TConfig>, InferData<TConfig>> {\n constructor(config: TConfig) {\n const identityEnum = Object.keys(config).reduce(\n (acc, key) => ({ ...acc, [key]: key }),\n {} as InferEnum<TConfig>\n );\n super(identityEnum);\n }\n}\n","import type { ResourceState } from \"@flurryx/core\";\nimport type { IStore } from \"./types\";\n\nexport interface MirrorOptions {\n destroyRef?: { onDestroy: (fn: () => void) => void };\n}\n\n/**\n * Mirrors a resource key from a source store to a target store.\n * When the source key updates, the target key is updated with the same state.\n *\n * @param source - The store to mirror from\n * @param sourceKey - The key to watch on the source store\n * @param target - The store to mirror to\n * @param targetKeyOrOptions - Either the target key name or options (defaults source key)\n * @param options - Mirror options when a target key is provided\n * @returns Cleanup function to stop mirroring\n */\nexport function mirrorKey<\n TSource extends Record<string, ResourceState<unknown>>,\n TTarget extends Record<string, ResourceState<unknown>>\n>(\n source: IStore<TSource>,\n sourceKey: keyof TSource & string,\n target: IStore<TTarget>,\n targetKeyOrOptions?: (keyof TTarget & string) | MirrorOptions,\n options?: MirrorOptions\n): () => void {\n const resolvedTargetKey = (\n typeof targetKeyOrOptions === \"string\" ? targetKeyOrOptions : sourceKey\n ) as keyof TTarget & string;\n\n const resolvedOptions =\n typeof targetKeyOrOptions === \"object\" ? targetKeyOrOptions : options;\n\n const cleanup = source.onUpdate(sourceKey, (state) => {\n target.update(\n resolvedTargetKey,\n state as unknown as Partial<TTarget[keyof TTarget & string]>\n );\n });\n\n if (resolvedOptions?.destroyRef) {\n resolvedOptions.destroyRef.onDestroy(cleanup);\n }\n\n return cleanup;\n}\n","import type {\n ResourceState,\n KeyedResourceKey,\n KeyedResourceData,\n} from '@flurryx/core';\nimport { createKeyedResourceData, isAnyKeyLoading } from '@flurryx/core';\nimport type { IStore } from './types';\n\nexport interface CollectKeyedOptions<TEntity> {\n extractId: (data: TEntity | undefined) => KeyedResourceKey | undefined;\n destroyRef?: { onDestroy: (fn: () => void) => void };\n}\n\n/**\n * Accumulates single-entity resource fetches into a keyed cache on a target store.\n *\n * On each source update:\n * - If status is 'Success' and extractId returns a valid key, merges the entity\n * into the target's keyed resource data.\n * - If the source data is cleared and a previous entity existed, removes it from\n * the target's keyed data.\n *\n * @param source - The store containing the single-entity resource\n * @param sourceKey - The key to watch on the source store\n * @param target - The store to accumulate entities into\n * @param targetKeyOrOptions - Either the target key name or options (defaults source key)\n * @param options - Collect options when a target key is provided\n * @returns Cleanup function to stop collecting\n */\nexport function collectKeyed<\n TSource extends Record<string, ResourceState<unknown>>,\n TTarget extends Record<string, ResourceState<unknown>>,\n TEntity = unknown,\n>(\n source: IStore<TSource>,\n sourceKey: keyof TSource & string,\n target: IStore<TTarget>,\n targetKeyOrOptions?: (keyof TTarget & string) | CollectKeyedOptions<TEntity>,\n options?: CollectKeyedOptions<TEntity>,\n): () => void {\n const resolvedTargetKey = (\n typeof targetKeyOrOptions === 'string'\n ? targetKeyOrOptions\n : sourceKey\n ) as keyof TTarget & string;\n\n const resolvedOptions = (\n typeof targetKeyOrOptions === 'object' ? targetKeyOrOptions : options\n ) as CollectKeyedOptions<TEntity>;\n\n // Initialize target with empty keyed resource data\n target.update(resolvedTargetKey, {\n data: createKeyedResourceData(),\n } as Partial<TTarget[keyof TTarget & string]>);\n\n let previousId: KeyedResourceKey | undefined;\n\n const cleanup = source.onUpdate(sourceKey, (state) => {\n const resourceState = state as ResourceState<TEntity>;\n const currentId = resolvedOptions.extractId(resourceState.data);\n const currentTarget = target.get(resolvedTargetKey)();\n const currentKeyed = (currentTarget as ResourceState<unknown>).data as\n KeyedResourceData<KeyedResourceKey, TEntity> | undefined;\n\n if (!currentKeyed) {\n return;\n }\n\n if (resourceState.status === 'Success' && currentId !== undefined) {\n const newEntities = { ...currentKeyed.entities, [currentId]: resourceState.data };\n const newIsLoading = { ...currentKeyed.isLoading, [currentId]: false };\n const newStatus = { ...currentKeyed.status, [currentId]: resourceState.status };\n const newErrors = { ...currentKeyed.errors };\n delete newErrors[currentId];\n\n const updatedKeyed: KeyedResourceData<KeyedResourceKey, TEntity> = {\n entities: newEntities,\n isLoading: newIsLoading,\n status: newStatus,\n errors: newErrors,\n };\n\n target.update(resolvedTargetKey, {\n data: updatedKeyed,\n isLoading: isAnyKeyLoading(newIsLoading),\n status: 'Success',\n } as Partial<TTarget[keyof TTarget & string]>);\n\n previousId = currentId;\n } else if (resourceState.status === 'Error' && currentId !== undefined) {\n const newIsLoading = { ...currentKeyed.isLoading, [currentId]: false };\n const newStatus = { ...currentKeyed.status, [currentId]: resourceState.status };\n const newErrors = { ...currentKeyed.errors, [currentId]: resourceState.errors };\n\n const updatedKeyed: KeyedResourceData<KeyedResourceKey, TEntity> = {\n entities: { ...currentKeyed.entities },\n isLoading: newIsLoading,\n status: newStatus,\n errors: newErrors,\n };\n\n target.update(resolvedTargetKey, {\n data: updatedKeyed,\n isLoading: isAnyKeyLoading(newIsLoading),\n } as Partial<TTarget[keyof TTarget & string]>);\n\n previousId = currentId;\n } else if (resourceState.data === undefined && previousId !== undefined) {\n // Source cleared — remove previous entity from cache\n const { [previousId]: _removed, ...remainingEntities } = currentKeyed.entities;\n const { [previousId]: _removedLoading, ...remainingLoading } = currentKeyed.isLoading;\n const { [previousId]: _removedStatus, ...remainingStatus } = currentKeyed.status;\n const { [previousId]: _removedErrors, ...remainingErrors } = currentKeyed.errors;\n\n const updatedKeyed: KeyedResourceData<KeyedResourceKey, TEntity> = {\n entities: remainingEntities,\n isLoading: remainingLoading,\n status: remainingStatus,\n errors: remainingErrors,\n };\n\n target.update(resolvedTargetKey, {\n data: updatedKeyed,\n isLoading: isAnyKeyLoading(remainingLoading),\n } as Partial<TTarget[keyof TTarget & string]>);\n\n previousId = undefined;\n } else if (resourceState.isLoading && currentId !== undefined) {\n const newIsLoading = { ...currentKeyed.isLoading, [currentId]: true };\n\n const updatedKeyed: KeyedResourceData<KeyedResourceKey, TEntity> = {\n entities: { ...currentKeyed.entities },\n isLoading: newIsLoading,\n status: { ...currentKeyed.status },\n errors: { ...currentKeyed.errors },\n };\n\n target.update(resolvedTargetKey, {\n data: updatedKeyed,\n isLoading: true,\n } as Partial<TTarget[keyof TTarget & string]>);\n\n previousId = currentId;\n }\n });\n\n if (resolvedOptions?.destroyRef) {\n resolvedOptions.destroyRef.onDestroy(cleanup);\n }\n\n return cleanup;\n}\n","import type { ResourceDef } from './types';\n\n/**\n * Creates a phantom-typed resource definition marker.\n * Zero runtime cost — returns an empty object that only carries type info.\n *\n * @example\n * const config = {\n * customers: resource<Customer[]>(),\n * customerDetails: resource<Customer>(),\n * };\n */\nexport function resource<T>(): ResourceDef<T> {\n return {} as ResourceDef<T>;\n}\n"],"mappings":"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","names":["import_core","import_core","import_core","import_core"]}
package/dist/index.d.cts CHANGED
@@ -98,6 +98,10 @@ interface AsStep<TAccum extends StoreConfig, TKey extends string> {
98
98
  */
99
99
  interface StoreBuilder<TAccum extends StoreConfig> {
100
100
  resource<TKey extends string>(key: TKey): AsStep<TAccum, TKey>;
101
+ mirror<TSourceData extends Record<string, ResourceState<unknown>>>(source: InjectionToken<IStore<TSourceData>>, sourceKey: keyof TSourceData & string, targetKey?: keyof TAccum & string): StoreBuilder<TAccum>;
102
+ mirrorKeyed<TSourceData extends Record<string, ResourceState<unknown>>, TEntity>(source: InjectionToken<IStore<TSourceData>>, sourceKey: keyof TSourceData & string, options: {
103
+ extractId: (data: TEntity | undefined) => KeyedResourceKey | undefined;
104
+ }, targetKey?: keyof TAccum & string): StoreBuilder<TAccum>;
101
105
  build(): InjectionToken<BaseStore<InferEnum<TAccum>, InferData<TAccum>>>;
102
106
  }
103
107
  /** Keys from the enum that have NOT yet been defined. */
@@ -111,10 +115,21 @@ interface ConstrainedAsStep<TEnum extends Record<string, string>, TAccum extends
111
115
  * defined yet. `.build()` is only available when all keys are accounted for.
112
116
  */
113
117
  type ConstrainedBuilder<TEnum extends Record<string, string>, TAccum extends StoreConfig> = [Remaining<TEnum, TAccum>] extends [never] ? {
118
+ mirror<TSourceData extends Record<string, ResourceState<unknown>>>(source: InjectionToken<IStore<TSourceData>>, sourceKey: keyof TSourceData & string, targetKey?: keyof TAccum & string): ConstrainedBuilder<TEnum, TAccum>;
119
+ mirrorKeyed<TSourceData extends Record<string, ResourceState<unknown>>, TEntity>(source: InjectionToken<IStore<TSourceData>>, sourceKey: keyof TSourceData & string, options: {
120
+ extractId: (data: TEntity | undefined) => KeyedResourceKey | undefined;
121
+ }, targetKey?: keyof TAccum & string): ConstrainedBuilder<TEnum, TAccum>;
114
122
  build(): InjectionToken<BaseStore<InferEnum<TAccum>, InferData<TAccum>>>;
115
123
  } : {
116
124
  resource<TKey extends Remaining<TEnum, TAccum>>(key: TKey): ConstrainedAsStep<TEnum, TAccum, TKey>;
117
125
  };
126
+ interface InterfaceBuilder<TConfig extends Record<string, unknown>> {
127
+ mirror<TSourceData extends Record<string, ResourceState<unknown>>>(source: InjectionToken<IStore<TSourceData>>, sourceKey: keyof TSourceData & string, targetKey?: keyof TConfig & string): InterfaceBuilder<TConfig>;
128
+ mirrorKeyed<TSourceData extends Record<string, ResourceState<unknown>>, TEntity>(source: InjectionToken<IStore<TSourceData>>, sourceKey: keyof TSourceData & string, options: {
129
+ extractId: (data: TEntity | undefined) => KeyedResourceKey | undefined;
130
+ }, targetKey?: keyof TConfig & string): InterfaceBuilder<TConfig>;
131
+ build(): InjectionToken<IStore<ConfigToData<TConfig>>>;
132
+ }
118
133
  interface StoreEntry {
119
134
  /**
120
135
  * Define a named resource slot.
@@ -135,9 +150,7 @@ interface StoreEntry {
135
150
  * }
136
151
  * const ChatStore = Store.for<ChatStoreConfig>().build();
137
152
  */
138
- for<TConfig extends Record<string, unknown>>(): {
139
- build(): InjectionToken<IStore<ConfigToData<TConfig>>>;
140
- };
153
+ for<TConfig extends Record<string, unknown>>(): InterfaceBuilder<TConfig>;
141
154
  /**
142
155
  * Bind the builder to an enum object for compile-time key validation.
143
156
  *
package/dist/index.d.ts CHANGED
@@ -98,6 +98,10 @@ interface AsStep<TAccum extends StoreConfig, TKey extends string> {
98
98
  */
99
99
  interface StoreBuilder<TAccum extends StoreConfig> {
100
100
  resource<TKey extends string>(key: TKey): AsStep<TAccum, TKey>;
101
+ mirror<TSourceData extends Record<string, ResourceState<unknown>>>(source: InjectionToken<IStore<TSourceData>>, sourceKey: keyof TSourceData & string, targetKey?: keyof TAccum & string): StoreBuilder<TAccum>;
102
+ mirrorKeyed<TSourceData extends Record<string, ResourceState<unknown>>, TEntity>(source: InjectionToken<IStore<TSourceData>>, sourceKey: keyof TSourceData & string, options: {
103
+ extractId: (data: TEntity | undefined) => KeyedResourceKey | undefined;
104
+ }, targetKey?: keyof TAccum & string): StoreBuilder<TAccum>;
101
105
  build(): InjectionToken<BaseStore<InferEnum<TAccum>, InferData<TAccum>>>;
102
106
  }
103
107
  /** Keys from the enum that have NOT yet been defined. */
@@ -111,10 +115,21 @@ interface ConstrainedAsStep<TEnum extends Record<string, string>, TAccum extends
111
115
  * defined yet. `.build()` is only available when all keys are accounted for.
112
116
  */
113
117
  type ConstrainedBuilder<TEnum extends Record<string, string>, TAccum extends StoreConfig> = [Remaining<TEnum, TAccum>] extends [never] ? {
118
+ mirror<TSourceData extends Record<string, ResourceState<unknown>>>(source: InjectionToken<IStore<TSourceData>>, sourceKey: keyof TSourceData & string, targetKey?: keyof TAccum & string): ConstrainedBuilder<TEnum, TAccum>;
119
+ mirrorKeyed<TSourceData extends Record<string, ResourceState<unknown>>, TEntity>(source: InjectionToken<IStore<TSourceData>>, sourceKey: keyof TSourceData & string, options: {
120
+ extractId: (data: TEntity | undefined) => KeyedResourceKey | undefined;
121
+ }, targetKey?: keyof TAccum & string): ConstrainedBuilder<TEnum, TAccum>;
114
122
  build(): InjectionToken<BaseStore<InferEnum<TAccum>, InferData<TAccum>>>;
115
123
  } : {
116
124
  resource<TKey extends Remaining<TEnum, TAccum>>(key: TKey): ConstrainedAsStep<TEnum, TAccum, TKey>;
117
125
  };
126
+ interface InterfaceBuilder<TConfig extends Record<string, unknown>> {
127
+ mirror<TSourceData extends Record<string, ResourceState<unknown>>>(source: InjectionToken<IStore<TSourceData>>, sourceKey: keyof TSourceData & string, targetKey?: keyof TConfig & string): InterfaceBuilder<TConfig>;
128
+ mirrorKeyed<TSourceData extends Record<string, ResourceState<unknown>>, TEntity>(source: InjectionToken<IStore<TSourceData>>, sourceKey: keyof TSourceData & string, options: {
129
+ extractId: (data: TEntity | undefined) => KeyedResourceKey | undefined;
130
+ }, targetKey?: keyof TConfig & string): InterfaceBuilder<TConfig>;
131
+ build(): InjectionToken<IStore<ConfigToData<TConfig>>>;
132
+ }
118
133
  interface StoreEntry {
119
134
  /**
120
135
  * Define a named resource slot.
@@ -135,9 +150,7 @@ interface StoreEntry {
135
150
  * }
136
151
  * const ChatStore = Store.for<ChatStoreConfig>().build();
137
152
  */
138
- for<TConfig extends Record<string, unknown>>(): {
139
- build(): InjectionToken<IStore<ConfigToData<TConfig>>>;
140
- };
153
+ for<TConfig extends Record<string, unknown>>(): InterfaceBuilder<TConfig>;
141
154
  /**
142
155
  * Bind the builder to an enum object for compile-time key validation.
143
156
  *
package/dist/index.js CHANGED
@@ -342,7 +342,7 @@ var LazyStore = class {
342
342
  };
343
343
 
344
344
  // src/store-builder.ts
345
- import { InjectionToken } from "@angular/core";
345
+ import { InjectionToken, inject } from "@angular/core";
346
346
 
347
347
  // src/dynamic-store.ts
348
348
  var DynamicStore = class extends BaseStore {
@@ -355,71 +355,6 @@ var DynamicStore = class extends BaseStore {
355
355
  }
356
356
  };
357
357
 
358
- // src/resource.ts
359
- function resource() {
360
- return {};
361
- }
362
-
363
- // src/store-builder.ts
364
- function createBuilder(accum) {
365
- return {
366
- resource(key) {
367
- return {
368
- as() {
369
- const nextAccum = {
370
- ...accum,
371
- [key]: resource()
372
- };
373
- return createBuilder(nextAccum);
374
- }
375
- };
376
- },
377
- build() {
378
- return new InjectionToken("FlurryxStore", {
379
- providedIn: "root",
380
- factory: () => new DynamicStore(accum)
381
- });
382
- }
383
- };
384
- }
385
- function createConstrainedBuilder(_enumObj, accum) {
386
- return {
387
- resource(key) {
388
- return {
389
- as() {
390
- const nextAccum = {
391
- ...accum,
392
- [key]: resource()
393
- };
394
- return createConstrainedBuilder(_enumObj, nextAccum);
395
- }
396
- };
397
- },
398
- build() {
399
- return new InjectionToken("FlurryxStore", {
400
- providedIn: "root",
401
- factory: () => new DynamicStore(accum)
402
- });
403
- }
404
- };
405
- }
406
- var Store = {
407
- ...createBuilder({}),
408
- for(enumObj) {
409
- if (arguments.length === 0) {
410
- return {
411
- build() {
412
- return new InjectionToken("FlurryxStore", {
413
- providedIn: "root",
414
- factory: () => new LazyStore()
415
- });
416
- }
417
- };
418
- }
419
- return createConstrainedBuilder(enumObj, {});
420
- }
421
- };
422
-
423
358
  // src/mirror-key.ts
424
359
  function mirrorKey(source, sourceKey, target, targetKeyOrOptions, options) {
425
360
  const resolvedTargetKey = typeof targetKeyOrOptions === "string" ? targetKeyOrOptions : sourceKey;
@@ -522,6 +457,175 @@ function collectKeyed(source, sourceKey, target, targetKeyOrOptions, options) {
522
457
  }
523
458
  return cleanup;
524
459
  }
460
+
461
+ // src/resource.ts
462
+ function resource() {
463
+ return {};
464
+ }
465
+
466
+ // src/store-builder.ts
467
+ function wireMirrors(store, mirrors) {
468
+ for (const def of mirrors) {
469
+ const sourceStore = inject(def.sourceToken);
470
+ mirrorKey(sourceStore, def.sourceKey, store, def.targetKey);
471
+ }
472
+ return store;
473
+ }
474
+ function wireMirrorKeyed(store, defs) {
475
+ for (const def of defs) {
476
+ const sourceStore = inject(def.sourceToken);
477
+ collectKeyed(sourceStore, def.sourceKey, store, def.targetKey, {
478
+ extractId: def.extractId
479
+ });
480
+ }
481
+ return store;
482
+ }
483
+ function createBuilder(accum, mirrors = [], mirrorKeyedDefs = []) {
484
+ return {
485
+ resource(key) {
486
+ return {
487
+ as() {
488
+ const nextAccum = {
489
+ ...accum,
490
+ [key]: resource()
491
+ };
492
+ return createBuilder(nextAccum, mirrors, mirrorKeyedDefs);
493
+ }
494
+ };
495
+ },
496
+ mirror(source, sourceKey, targetKey) {
497
+ const def = {
498
+ sourceToken: source,
499
+ sourceKey,
500
+ targetKey: targetKey ?? sourceKey
501
+ };
502
+ return createBuilder(accum, [...mirrors, def], mirrorKeyedDefs);
503
+ },
504
+ mirrorKeyed(source, sourceKey, options, targetKey) {
505
+ const def = {
506
+ sourceToken: source,
507
+ sourceKey,
508
+ targetKey: targetKey ?? sourceKey,
509
+ extractId: options.extractId
510
+ };
511
+ return createBuilder(accum, mirrors, [...mirrorKeyedDefs, def]);
512
+ },
513
+ build() {
514
+ return new InjectionToken("FlurryxStore", {
515
+ providedIn: "root",
516
+ factory: () => {
517
+ const store = new DynamicStore(accum);
518
+ wireMirrors(store, mirrors);
519
+ wireMirrorKeyed(store, mirrorKeyedDefs);
520
+ return store;
521
+ }
522
+ });
523
+ }
524
+ };
525
+ }
526
+ function createConstrainedBuilder(_enumObj, accum, mirrors = [], mirrorKeyedDefs = []) {
527
+ return {
528
+ resource(key) {
529
+ return {
530
+ as() {
531
+ const nextAccum = {
532
+ ...accum,
533
+ [key]: resource()
534
+ };
535
+ return createConstrainedBuilder(
536
+ _enumObj,
537
+ nextAccum,
538
+ mirrors,
539
+ mirrorKeyedDefs
540
+ );
541
+ }
542
+ };
543
+ },
544
+ mirror(source, sourceKey, targetKey) {
545
+ const def = {
546
+ sourceToken: source,
547
+ sourceKey,
548
+ targetKey: targetKey ?? sourceKey
549
+ };
550
+ return createConstrainedBuilder(
551
+ _enumObj,
552
+ accum,
553
+ [...mirrors, def],
554
+ mirrorKeyedDefs
555
+ );
556
+ },
557
+ mirrorKeyed(source, sourceKey, options, targetKey) {
558
+ const def = {
559
+ sourceToken: source,
560
+ sourceKey,
561
+ targetKey: targetKey ?? sourceKey,
562
+ extractId: options.extractId
563
+ };
564
+ return createConstrainedBuilder(_enumObj, accum, mirrors, [
565
+ ...mirrorKeyedDefs,
566
+ def
567
+ ]);
568
+ },
569
+ build() {
570
+ return new InjectionToken("FlurryxStore", {
571
+ providedIn: "root",
572
+ factory: () => {
573
+ const store = new DynamicStore(accum);
574
+ wireMirrors(store, mirrors);
575
+ wireMirrorKeyed(store, mirrorKeyedDefs);
576
+ return store;
577
+ }
578
+ });
579
+ }
580
+ };
581
+ }
582
+ function createInterfaceBuilder(mirrors = [], mirrorKeyedDefs = []) {
583
+ return {
584
+ mirror(source, sourceKey, targetKey) {
585
+ const def = {
586
+ sourceToken: source,
587
+ sourceKey,
588
+ targetKey: targetKey ?? sourceKey
589
+ };
590
+ return createInterfaceBuilder(
591
+ [...mirrors, def],
592
+ mirrorKeyedDefs
593
+ );
594
+ },
595
+ mirrorKeyed(source, sourceKey, options, targetKey) {
596
+ const def = {
597
+ sourceToken: source,
598
+ sourceKey,
599
+ targetKey: targetKey ?? sourceKey,
600
+ extractId: options.extractId
601
+ };
602
+ return createInterfaceBuilder(mirrors, [
603
+ ...mirrorKeyedDefs,
604
+ def
605
+ ]);
606
+ },
607
+ build() {
608
+ return new InjectionToken("FlurryxStore", {
609
+ providedIn: "root",
610
+ factory: () => {
611
+ const store = new LazyStore();
612
+ wireMirrors(store, mirrors);
613
+ wireMirrorKeyed(store, mirrorKeyedDefs);
614
+ return store;
615
+ }
616
+ });
617
+ }
618
+ };
619
+ }
620
+ var Store = {
621
+ ...createBuilder({}),
622
+ for(enumObj) {
623
+ if (arguments.length === 0) {
624
+ return createInterfaceBuilder();
625
+ }
626
+ return createConstrainedBuilder(enumObj, {});
627
+ }
628
+ };
525
629
  export {
526
630
  BaseStore,
527
631
  LazyStore,
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/resource.ts","../src/mirror-key.ts","../src/collect-keyed.ts"],"sourcesContent":["import { signal, WritableSignal } from \"@angular/core\";\nimport {\n ResourceState,\n isAnyKeyLoading,\n isKeyedResourceData,\n createKeyedResourceData,\n type KeyedResourceKey,\n} from \"@flurryx/core\";\nimport type { IStore } from \"./types\";\n\ntype UpdateHooksMap = Map<\n unknown,\n Array<\n (\n nextState: ResourceState<unknown>,\n previousState: ResourceState<unknown>\n ) => void\n >\n>;\n\nconst updateHooksMap = new WeakMap<object, UpdateHooksMap>();\n\nexport abstract class BaseStore<\n TEnum extends Record<string, string | number>,\n TData extends { [K in keyof TEnum]: ResourceState<unknown> }\n> implements IStore<TData>\n{\n private readonly signalsState = new Map<\n keyof TEnum,\n WritableSignal<TData[keyof TEnum]>\n >();\n\n protected constructor(protected readonly storeEnum: TEnum) {\n this.initializeState();\n updateHooksMap.set(this, new Map());\n }\n\n get<K extends keyof TData>(key: K): WritableSignal<TData[K]> {\n return this.signalsState.get(key.toString()) as WritableSignal<TData[K]>;\n }\n\n onUpdate<K extends keyof TData>(\n key: K,\n callback: (state: TData[K], previousState: TData[K]) => void\n ): () => void {\n const hooks = updateHooksMap.get(this)!;\n if (!hooks.has(key)) {\n hooks.set(key, []);\n }\n hooks\n .get(key)!\n .push(\n callback as (\n nextState: ResourceState<unknown>,\n previousState: ResourceState<unknown>\n ) => void\n );\n\n return () => {\n const hooksMap = hooks.get(key);\n if (!hooksMap) {\n return;\n }\n const index = hooksMap.indexOf(\n callback as (\n nextState: ResourceState<unknown>,\n previousState: ResourceState<unknown>\n ) => void\n );\n if (index > -1) {\n hooksMap.splice(index, 1);\n }\n };\n }\n\n update<K extends keyof TData>(key: K, newState: Partial<TData[K]>): void {\n const currentState = this.signalsState.get(key.toString());\n if (!currentState) {\n return;\n }\n\n const previousState = currentState() as TData[K];\n currentState.update((state) => ({\n ...state,\n ...newState,\n }));\n\n const updatedState = currentState() as TData[K];\n this.notifyUpdateHooks(key, updatedState, previousState);\n }\n\n clearAll(): void {\n Object.keys(this.storeEnum).forEach((key) => {\n this.clear(key as keyof TData);\n });\n }\n\n clear<K extends keyof TData>(key: K): void {\n const currentState = this.signalsState.get(key.toString());\n if (!currentState) {\n return;\n }\n\n const previousState = currentState() as TData[K];\n const _typedKey = key as keyof TEnum;\n currentState.set({\n data: undefined,\n isLoading: false,\n status: undefined,\n errors: undefined,\n } as TData[typeof _typedKey]);\n\n const nextState = currentState() as TData[K];\n this.notifyUpdateHooks(key, nextState, previousState);\n }\n\n startLoading<K extends keyof TData>(key: K): void {\n const currentState = this.signalsState.get(key.toString());\n if (!currentState) {\n return;\n }\n\n const _typedKey = key as keyof TEnum;\n currentState.update(\n (state) =>\n ({\n ...state,\n status: undefined,\n isLoading: true,\n errors: undefined,\n } as TData[typeof _typedKey])\n );\n }\n\n stopLoading<K extends keyof TData>(key: K): void {\n const currentState = this.signalsState.get(key.toString());\n if (!currentState) {\n return;\n }\n\n const _typedKey = key as keyof TEnum;\n currentState.update(\n (state) =>\n ({\n ...state,\n isLoading: false,\n status: undefined,\n errors: undefined,\n } as TData[typeof _typedKey])\n );\n }\n\n updateKeyedOne<K extends keyof TData>(\n key: K,\n resourceKey: KeyedResourceKey,\n entity: unknown\n ): void {\n const currentState = this.signalsState.get(key.toString());\n if (!currentState) {\n return;\n }\n\n const state = currentState();\n const data = isKeyedResourceData(state.data)\n ? state.data\n : createKeyedResourceData();\n\n const nextErrors = { ...data.errors };\n delete nextErrors[resourceKey];\n\n const nextData = {\n ...data,\n entities: {\n ...data.entities,\n [resourceKey]: entity,\n },\n isLoading: {\n ...data.isLoading,\n [resourceKey]: false,\n },\n status: {\n ...data.status,\n [resourceKey]: \"Success\" as const,\n },\n errors: nextErrors,\n };\n\n this.update(key, {\n data: nextData as unknown,\n isLoading: isAnyKeyLoading(nextData.isLoading),\n status: undefined,\n errors: undefined,\n } as Partial<TData[K]>);\n }\n\n clearKeyedOne<K extends keyof TData>(\n key: K,\n resourceKey: KeyedResourceKey\n ): void {\n const currentState = this.signalsState.get(key.toString());\n if (!currentState) {\n return;\n }\n\n const previousState = currentState() as TData[K];\n const state = previousState as ResourceState<unknown>;\n if (!isKeyedResourceData(state.data)) {\n return;\n }\n\n const data = state.data;\n\n const nextEntities = { ...data.entities };\n delete nextEntities[resourceKey];\n\n const nextIsLoading = { ...data.isLoading };\n delete nextIsLoading[resourceKey];\n\n const nextStatus = { ...data.status };\n delete nextStatus[resourceKey];\n\n const nextErrors = { ...data.errors };\n delete nextErrors[resourceKey];\n\n const nextData = {\n ...data,\n entities: nextEntities,\n isLoading: nextIsLoading,\n status: nextStatus,\n errors: nextErrors,\n };\n\n const _typedKey = key as keyof TEnum;\n currentState.update(\n (prev) =>\n ({\n ...prev,\n data: nextData as unknown,\n status: undefined,\n isLoading: isAnyKeyLoading(nextIsLoading),\n errors: undefined,\n } as TData[typeof _typedKey])\n );\n\n const updatedState = currentState() as TData[K];\n this.notifyUpdateHooks(key, updatedState, previousState);\n }\n\n startKeyedLoading<K extends keyof TData>(\n key: K,\n resourceKey: KeyedResourceKey\n ): void {\n const currentState = this.signalsState.get(key.toString());\n if (!currentState) {\n return;\n }\n\n const _typedKey = key as keyof TEnum;\n const state = currentState();\n if (!isKeyedResourceData(state.data)) {\n this.startLoading(key);\n return;\n }\n\n const previousState = state as TData[K];\n const data = state.data;\n\n const nextIsLoading = {\n ...data.isLoading,\n [resourceKey]: true,\n } as typeof data.isLoading;\n\n const nextStatus: typeof data.status = {\n ...data.status,\n };\n delete nextStatus[resourceKey];\n\n const nextErrors: typeof data.errors = {\n ...data.errors,\n };\n delete nextErrors[resourceKey];\n\n const nextData = {\n ...data,\n isLoading: nextIsLoading,\n status: nextStatus,\n errors: nextErrors,\n };\n\n currentState.update(\n (previous) =>\n ({\n ...previous,\n data: nextData,\n status: undefined,\n isLoading: isAnyKeyLoading(nextIsLoading),\n errors: undefined,\n } as TData[typeof _typedKey])\n );\n\n const updatedState = currentState() as TData[K];\n this.notifyUpdateHooks(key, updatedState, previousState);\n }\n\n private notifyUpdateHooks<K extends keyof TData>(\n key: K,\n nextState: TData[K],\n previousState: TData[K]\n ): void {\n const hooks = updateHooksMap.get(this);\n const keyHooks = hooks?.get(key);\n if (!keyHooks) {\n return;\n }\n\n keyHooks.forEach((hook) =>\n hook(\n nextState as ResourceState<unknown>,\n previousState as ResourceState<unknown>\n )\n );\n }\n\n private initializeState(): void {\n Object.keys(this.storeEnum).forEach((key) => {\n const _typedKey = key as keyof TEnum;\n const initialState: ResourceState<unknown> = {\n data: undefined,\n isLoading: false,\n status: undefined,\n errors: undefined,\n };\n this.signalsState.set(\n _typedKey,\n signal<TData[typeof _typedKey]>(initialState as TData[typeof _typedKey])\n );\n });\n }\n}\n","import { signal, WritableSignal } from '@angular/core';\nimport type { ResourceState } from '@flurryx/core';\nimport type { IStore } from './types';\n\ntype UpdateCallback = (\n nextState: ResourceState<unknown>,\n previousState: ResourceState<unknown>\n) => void;\n\nfunction createDefaultState<T>(): ResourceState<T> {\n return {\n data: undefined,\n isLoading: false,\n status: undefined,\n errors: undefined,\n };\n}\n\n/**\n * Lazy store that creates signals on first access.\n * Used by the `Store.for<Config>().build()` API where keys are\n * known only at the type level (no runtime enum).\n */\nexport class LazyStore<\n TData extends Record<string, ResourceState<unknown>>,\n> implements IStore<TData>\n{\n private readonly signals = new Map<string, WritableSignal<ResourceState<unknown>>>();\n private readonly hooks = new Map<string, UpdateCallback[]>();\n\n private getOrCreate<K extends keyof TData & string>(\n key: K\n ): WritableSignal<TData[K]> {\n let sig = this.signals.get(key);\n if (!sig) {\n sig = signal<ResourceState<unknown>>(createDefaultState());\n this.signals.set(key, sig);\n }\n return sig as WritableSignal<TData[K]>;\n }\n\n get<K extends keyof TData & string>(key: K): WritableSignal<TData[K]> {\n return this.getOrCreate(key);\n }\n\n update<K extends keyof TData & string>(\n key: K,\n newState: Partial<TData[K]>\n ): void {\n const sig = this.getOrCreate(key);\n const previousState = sig();\n sig.update((state) => ({ ...state, ...newState }));\n const nextState = sig();\n this.notifyHooks(key, nextState, previousState);\n }\n\n clear<K extends keyof TData & string>(key: K): void {\n const sig = this.getOrCreate(key);\n const previousState = sig();\n sig.set(createDefaultState() as TData[K]);\n const nextState = sig();\n this.notifyHooks(key, nextState, previousState);\n }\n\n clearAll(): void {\n for (const key of this.signals.keys()) {\n this.clear(key as keyof TData & string);\n }\n }\n\n startLoading<K extends keyof TData & string>(key: K): void {\n const sig = this.getOrCreate(key);\n sig.update(\n (state) =>\n ({\n ...state,\n status: undefined,\n isLoading: true,\n errors: undefined,\n }) as TData[K]\n );\n }\n\n stopLoading<K extends keyof TData & string>(key: K): void {\n const sig = this.getOrCreate(key);\n sig.update(\n (state) =>\n ({\n ...state,\n isLoading: false,\n status: undefined,\n errors: undefined,\n }) as TData[K]\n );\n }\n\n onUpdate<K extends keyof TData & string>(\n key: K,\n callback: (state: TData[K], previousState: TData[K]) => void\n ): () => void {\n if (!this.hooks.has(key)) {\n this.hooks.set(key, []);\n }\n const typedCallback = callback as UpdateCallback;\n this.hooks.get(key)!.push(typedCallback);\n\n return () => {\n const keyHooks = this.hooks.get(key);\n if (!keyHooks) {\n return;\n }\n const index = keyHooks.indexOf(typedCallback);\n if (index > -1) {\n keyHooks.splice(index, 1);\n }\n };\n }\n\n private notifyHooks<K extends keyof TData & string>(\n key: K,\n nextState: TData[K],\n previousState: TData[K]\n ): void {\n const keyHooks = this.hooks.get(key);\n if (!keyHooks) {\n return;\n }\n keyHooks.forEach((hook) =>\n hook(\n nextState as ResourceState<unknown>,\n previousState as ResourceState<unknown>\n )\n );\n }\n}\n","import { InjectionToken } from \"@angular/core\";\nimport { BaseStore } from \"./base-store\";\nimport { DynamicStore } from \"./dynamic-store\";\nimport { LazyStore } from \"./lazy-store\";\nimport { resource } from \"./resource\";\nimport type {\n StoreConfig,\n ResourceDef,\n InferEnum,\n InferData,\n ConfigToData,\n IStore,\n} from \"./types\";\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 build(): InjectionToken<BaseStore<InferEnum<TAccum>, InferData<TAccum>>>;\n}\n\nfunction createBuilder<TAccum extends StoreConfig>(\n accum: TAccum\n): StoreBuilder<TAccum> {\n return {\n resource<TKey extends string>(key: TKey): AsStep<TAccum, TKey> {\n return {\n as<T>(): StoreBuilder<TAccum & Record<TKey, ResourceDef<T>>> {\n const nextAccum = {\n ...accum,\n [key]: resource<T>(),\n } as TAccum & Record<TKey, ResourceDef<T>>;\n return createBuilder(nextAccum);\n },\n };\n },\n build() {\n return new InjectionToken<\n BaseStore<InferEnum<TAccum>, InferData<TAccum>>\n >(\"FlurryxStore\", {\n providedIn: \"root\",\n factory: () => new DynamicStore(accum),\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 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>(_enumObj: TEnum, accum: TAccum): ConstrainedBuilder<TEnum, TAccum> {\n return {\n resource<TKey extends string>(\n key: TKey\n ): ConstrainedAsStep<TEnum, TAccum, TKey> {\n return {\n as<T>(): ConstrainedBuilder<\n TEnum,\n TAccum & Record<TKey, ResourceDef<T>>\n > {\n const nextAccum = {\n ...accum,\n [key]: resource<T>(),\n } as TAccum & Record<TKey, ResourceDef<T>>;\n return createConstrainedBuilder(_enumObj, nextAccum);\n },\n };\n },\n build() {\n return new InjectionToken<\n BaseStore<InferEnum<TAccum>, InferData<TAccum>>\n >(\"FlurryxStore\", {\n providedIn: \"root\",\n factory: () => new DynamicStore(accum),\n });\n },\n } as ConstrainedBuilder<TEnum, TAccum>;\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>>(): {\n build(): InjectionToken<IStore<ConfigToData<TConfig>>>;\n };\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 {\n build() {\n return new InjectionToken(\"FlurryxStore\", {\n providedIn: \"root\",\n factory: () => new LazyStore(),\n });\n },\n };\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 { ResourceDef } from './types';\n\n/**\n * Creates a phantom-typed resource definition marker.\n * Zero runtime cost — returns an empty object that only carries type info.\n *\n * @example\n * const config = {\n * customers: resource<Customer[]>(),\n * customerDetails: resource<Customer>(),\n * };\n */\nexport function resource<T>(): ResourceDef<T> {\n return {} as ResourceDef<T>;\n}\n","import type { 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"],"mappings":"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","names":["signal","createKeyedResourceData","isAnyKeyLoading"]}
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, WritableSignal } from \"@angular/core\";\nimport {\n ResourceState,\n isAnyKeyLoading,\n isKeyedResourceData,\n createKeyedResourceData,\n type KeyedResourceKey,\n} from \"@flurryx/core\";\nimport type { IStore } from \"./types\";\n\ntype UpdateHooksMap = Map<\n unknown,\n Array<\n (\n nextState: ResourceState<unknown>,\n previousState: ResourceState<unknown>\n ) => void\n >\n>;\n\nconst updateHooksMap = new WeakMap<object, UpdateHooksMap>();\n\nexport abstract class BaseStore<\n TEnum extends Record<string, string | number>,\n TData extends { [K in keyof TEnum]: ResourceState<unknown> }\n> implements IStore<TData>\n{\n private readonly signalsState = new Map<\n keyof TEnum,\n WritableSignal<TData[keyof TEnum]>\n >();\n\n protected constructor(protected readonly storeEnum: TEnum) {\n this.initializeState();\n updateHooksMap.set(this, new Map());\n }\n\n get<K extends keyof TData>(key: K): WritableSignal<TData[K]> {\n return this.signalsState.get(key.toString()) as WritableSignal<TData[K]>;\n }\n\n onUpdate<K extends keyof TData>(\n key: K,\n callback: (state: TData[K], previousState: TData[K]) => void\n ): () => void {\n const hooks = updateHooksMap.get(this)!;\n if (!hooks.has(key)) {\n hooks.set(key, []);\n }\n hooks\n .get(key)!\n .push(\n callback as (\n nextState: ResourceState<unknown>,\n previousState: ResourceState<unknown>\n ) => void\n );\n\n return () => {\n const hooksMap = hooks.get(key);\n if (!hooksMap) {\n return;\n }\n const index = hooksMap.indexOf(\n callback as (\n nextState: ResourceState<unknown>,\n previousState: ResourceState<unknown>\n ) => void\n );\n if (index > -1) {\n hooksMap.splice(index, 1);\n }\n };\n }\n\n update<K extends keyof TData>(key: K, newState: Partial<TData[K]>): void {\n const currentState = this.signalsState.get(key.toString());\n if (!currentState) {\n return;\n }\n\n const previousState = currentState() as TData[K];\n currentState.update((state) => ({\n ...state,\n ...newState,\n }));\n\n const updatedState = currentState() as TData[K];\n this.notifyUpdateHooks(key, updatedState, previousState);\n }\n\n clearAll(): void {\n Object.keys(this.storeEnum).forEach((key) => {\n this.clear(key as keyof TData);\n });\n }\n\n clear<K extends keyof TData>(key: K): void {\n const currentState = this.signalsState.get(key.toString());\n if (!currentState) {\n return;\n }\n\n const previousState = currentState() as TData[K];\n const _typedKey = key as keyof TEnum;\n currentState.set({\n data: undefined,\n isLoading: false,\n status: undefined,\n errors: undefined,\n } as TData[typeof _typedKey]);\n\n const nextState = currentState() as TData[K];\n this.notifyUpdateHooks(key, nextState, previousState);\n }\n\n startLoading<K extends keyof TData>(key: K): void {\n const currentState = this.signalsState.get(key.toString());\n if (!currentState) {\n return;\n }\n\n const _typedKey = key as keyof TEnum;\n currentState.update(\n (state) =>\n ({\n ...state,\n status: undefined,\n isLoading: true,\n errors: undefined,\n } as TData[typeof _typedKey])\n );\n }\n\n stopLoading<K extends keyof TData>(key: K): void {\n const currentState = this.signalsState.get(key.toString());\n if (!currentState) {\n return;\n }\n\n const _typedKey = key as keyof TEnum;\n currentState.update(\n (state) =>\n ({\n ...state,\n isLoading: false,\n status: undefined,\n errors: undefined,\n } as TData[typeof _typedKey])\n );\n }\n\n updateKeyedOne<K extends keyof TData>(\n key: K,\n resourceKey: KeyedResourceKey,\n entity: unknown\n ): void {\n const currentState = this.signalsState.get(key.toString());\n if (!currentState) {\n return;\n }\n\n const state = currentState();\n const data = isKeyedResourceData(state.data)\n ? state.data\n : createKeyedResourceData();\n\n const nextErrors = { ...data.errors };\n delete nextErrors[resourceKey];\n\n const nextData = {\n ...data,\n entities: {\n ...data.entities,\n [resourceKey]: entity,\n },\n isLoading: {\n ...data.isLoading,\n [resourceKey]: false,\n },\n status: {\n ...data.status,\n [resourceKey]: \"Success\" as const,\n },\n errors: nextErrors,\n };\n\n this.update(key, {\n data: nextData as unknown,\n isLoading: isAnyKeyLoading(nextData.isLoading),\n status: undefined,\n errors: undefined,\n } as Partial<TData[K]>);\n }\n\n clearKeyedOne<K extends keyof TData>(\n key: K,\n resourceKey: KeyedResourceKey\n ): void {\n const currentState = this.signalsState.get(key.toString());\n if (!currentState) {\n return;\n }\n\n const previousState = currentState() as TData[K];\n const state = previousState as ResourceState<unknown>;\n if (!isKeyedResourceData(state.data)) {\n return;\n }\n\n const data = state.data;\n\n const nextEntities = { ...data.entities };\n delete nextEntities[resourceKey];\n\n const nextIsLoading = { ...data.isLoading };\n delete nextIsLoading[resourceKey];\n\n const nextStatus = { ...data.status };\n delete nextStatus[resourceKey];\n\n const nextErrors = { ...data.errors };\n delete nextErrors[resourceKey];\n\n const nextData = {\n ...data,\n entities: nextEntities,\n isLoading: nextIsLoading,\n status: nextStatus,\n errors: nextErrors,\n };\n\n const _typedKey = key as keyof TEnum;\n currentState.update(\n (prev) =>\n ({\n ...prev,\n data: nextData as unknown,\n status: undefined,\n isLoading: isAnyKeyLoading(nextIsLoading),\n errors: undefined,\n } as TData[typeof _typedKey])\n );\n\n const updatedState = currentState() as TData[K];\n this.notifyUpdateHooks(key, updatedState, previousState);\n }\n\n startKeyedLoading<K extends keyof TData>(\n key: K,\n resourceKey: KeyedResourceKey\n ): void {\n const currentState = this.signalsState.get(key.toString());\n if (!currentState) {\n return;\n }\n\n const _typedKey = key as keyof TEnum;\n const state = currentState();\n if (!isKeyedResourceData(state.data)) {\n this.startLoading(key);\n return;\n }\n\n const previousState = state as TData[K];\n const data = state.data;\n\n const nextIsLoading = {\n ...data.isLoading,\n [resourceKey]: true,\n } as typeof data.isLoading;\n\n const nextStatus: typeof data.status = {\n ...data.status,\n };\n delete nextStatus[resourceKey];\n\n const nextErrors: typeof data.errors = {\n ...data.errors,\n };\n delete nextErrors[resourceKey];\n\n const nextData = {\n ...data,\n isLoading: nextIsLoading,\n status: nextStatus,\n errors: nextErrors,\n };\n\n currentState.update(\n (previous) =>\n ({\n ...previous,\n data: nextData,\n status: undefined,\n isLoading: isAnyKeyLoading(nextIsLoading),\n errors: undefined,\n } as TData[typeof _typedKey])\n );\n\n const updatedState = currentState() as TData[K];\n this.notifyUpdateHooks(key, updatedState, previousState);\n }\n\n private notifyUpdateHooks<K extends keyof TData>(\n key: K,\n nextState: TData[K],\n previousState: TData[K]\n ): void {\n const hooks = updateHooksMap.get(this);\n const keyHooks = hooks?.get(key);\n if (!keyHooks) {\n return;\n }\n\n keyHooks.forEach((hook) =>\n hook(\n nextState as ResourceState<unknown>,\n previousState as ResourceState<unknown>\n )\n );\n }\n\n private initializeState(): void {\n Object.keys(this.storeEnum).forEach((key) => {\n const _typedKey = key as keyof TEnum;\n const initialState: ResourceState<unknown> = {\n data: undefined,\n isLoading: false,\n status: undefined,\n errors: undefined,\n };\n this.signalsState.set(\n _typedKey,\n signal<TData[typeof _typedKey]>(initialState as TData[typeof _typedKey])\n );\n });\n }\n}\n","import { signal, WritableSignal } from '@angular/core';\nimport type { ResourceState } from '@flurryx/core';\nimport type { IStore } from './types';\n\ntype UpdateCallback = (\n nextState: ResourceState<unknown>,\n previousState: ResourceState<unknown>\n) => void;\n\nfunction createDefaultState<T>(): ResourceState<T> {\n return {\n data: undefined,\n isLoading: false,\n status: undefined,\n errors: undefined,\n };\n}\n\n/**\n * Lazy store that creates signals on first access.\n * Used by the `Store.for<Config>().build()` API where keys are\n * known only at the type level (no runtime enum).\n */\nexport class LazyStore<\n TData extends Record<string, ResourceState<unknown>>,\n> implements IStore<TData>\n{\n private readonly signals = new Map<string, WritableSignal<ResourceState<unknown>>>();\n private readonly hooks = new Map<string, UpdateCallback[]>();\n\n private getOrCreate<K extends keyof TData & string>(\n key: K\n ): WritableSignal<TData[K]> {\n let sig = this.signals.get(key);\n if (!sig) {\n sig = signal<ResourceState<unknown>>(createDefaultState());\n this.signals.set(key, sig);\n }\n return sig as WritableSignal<TData[K]>;\n }\n\n get<K extends keyof TData & string>(key: K): WritableSignal<TData[K]> {\n return this.getOrCreate(key);\n }\n\n update<K extends keyof TData & string>(\n key: K,\n newState: Partial<TData[K]>\n ): void {\n const sig = this.getOrCreate(key);\n const previousState = sig();\n sig.update((state) => ({ ...state, ...newState }));\n const nextState = sig();\n this.notifyHooks(key, nextState, previousState);\n }\n\n clear<K extends keyof TData & string>(key: K): void {\n const sig = this.getOrCreate(key);\n const previousState = sig();\n sig.set(createDefaultState() as TData[K]);\n const nextState = sig();\n this.notifyHooks(key, nextState, previousState);\n }\n\n clearAll(): void {\n for (const key of this.signals.keys()) {\n this.clear(key as keyof TData & string);\n }\n }\n\n startLoading<K extends keyof TData & string>(key: K): void {\n const sig = this.getOrCreate(key);\n sig.update(\n (state) =>\n ({\n ...state,\n status: undefined,\n isLoading: true,\n errors: undefined,\n }) as TData[K]\n );\n }\n\n stopLoading<K extends keyof TData & string>(key: K): void {\n const sig = this.getOrCreate(key);\n sig.update(\n (state) =>\n ({\n ...state,\n isLoading: false,\n status: undefined,\n errors: undefined,\n }) as TData[K]\n );\n }\n\n onUpdate<K extends keyof TData & string>(\n key: K,\n callback: (state: TData[K], previousState: TData[K]) => void\n ): () => void {\n if (!this.hooks.has(key)) {\n this.hooks.set(key, []);\n }\n const typedCallback = callback as UpdateCallback;\n this.hooks.get(key)!.push(typedCallback);\n\n return () => {\n const keyHooks = this.hooks.get(key);\n if (!keyHooks) {\n return;\n }\n const index = keyHooks.indexOf(typedCallback);\n if (index > -1) {\n keyHooks.splice(index, 1);\n }\n };\n }\n\n private notifyHooks<K extends keyof TData & string>(\n key: K,\n nextState: TData[K],\n previousState: TData[K]\n ): void {\n const keyHooks = this.hooks.get(key);\n if (!keyHooks) {\n return;\n }\n keyHooks.forEach((hook) =>\n hook(\n nextState as ResourceState<unknown>,\n previousState as ResourceState<unknown>\n )\n );\n }\n}\n","import { InjectionToken, inject } from \"@angular/core\";\nimport { BaseStore } from \"./base-store\";\nimport { DynamicStore } from \"./dynamic-store\";\nimport { LazyStore } from \"./lazy-store\";\nimport { mirrorKey } from \"./mirror-key\";\nimport { collectKeyed } from \"./collect-keyed\";\nimport { resource } from \"./resource\";\nimport type { ResourceState, KeyedResourceKey } from \"@flurryx/core\";\nimport type {\n StoreConfig,\n ResourceDef,\n InferEnum,\n InferData,\n ConfigToData,\n IStore,\n} from \"./types\";\n\n// ---------------------------------------------------------------------------\n// Mirror definition — accumulated by builders, wired up in build() factory\n// ---------------------------------------------------------------------------\n\ninterface MirrorDef {\n readonly sourceToken: InjectionToken<\n IStore<Record<string, ResourceState<unknown>>>\n >;\n readonly sourceKey: string;\n readonly targetKey: string;\n}\n\nfunction wireMirrors<\n TStore extends IStore<Record<string, ResourceState<unknown>>>\n>(store: TStore, mirrors: readonly MirrorDef[]): TStore {\n for (const def of mirrors) {\n const sourceStore = inject(def.sourceToken);\n mirrorKey(sourceStore, def.sourceKey, store, def.targetKey);\n }\n return store;\n}\n\n// ---------------------------------------------------------------------------\n// MirrorKeyed definition — accumulated by builders, wired up in build()\n// ---------------------------------------------------------------------------\n\ninterface MirrorKeyedDef {\n readonly sourceToken: InjectionToken<\n IStore<Record<string, ResourceState<unknown>>>\n >;\n readonly sourceKey: string;\n readonly targetKey: string;\n readonly extractId: (data: unknown) => KeyedResourceKey | undefined;\n}\n\nfunction wireMirrorKeyed<\n TStore extends IStore<Record<string, ResourceState<unknown>>>\n>(store: TStore, defs: readonly MirrorKeyedDef[]): TStore {\n for (const def of defs) {\n const sourceStore = inject(def.sourceToken);\n collectKeyed(sourceStore, def.sourceKey, store, def.targetKey, {\n extractId: def.extractId,\n });\n }\n return store;\n}\n\n// ---------------------------------------------------------------------------\n// Unconstrained builder (existing API)\n// ---------------------------------------------------------------------------\n\n/**\n * Intermediate builder step after .resource('key') — awaits .as<T>().\n */\ninterface AsStep<TAccum extends StoreConfig, TKey extends string> {\n as<T>(): StoreBuilder<TAccum & Record<TKey, ResourceDef<T>>>;\n}\n\n/**\n * Fluent builder for creating stores.\n * Accumulates resource definitions then produces an InjectionToken on .build().\n */\ninterface StoreBuilder<TAccum extends StoreConfig> {\n resource<TKey extends string>(key: TKey): AsStep<TAccum, TKey>;\n mirror<TSourceData extends Record<string, ResourceState<unknown>>>(\n source: InjectionToken<IStore<TSourceData>>,\n sourceKey: keyof TSourceData & string,\n targetKey?: keyof TAccum & string\n ): StoreBuilder<TAccum>;\n mirrorKeyed<\n TSourceData extends Record<string, ResourceState<unknown>>,\n TEntity\n >(\n source: InjectionToken<IStore<TSourceData>>,\n sourceKey: keyof TSourceData & string,\n options: {\n extractId: (data: TEntity | undefined) => KeyedResourceKey | undefined;\n },\n targetKey?: keyof TAccum & string\n ): StoreBuilder<TAccum>;\n build(): InjectionToken<BaseStore<InferEnum<TAccum>, InferData<TAccum>>>;\n}\n\nfunction createBuilder<TAccum extends StoreConfig>(\n accum: TAccum,\n mirrors: readonly MirrorDef[] = [],\n mirrorKeyedDefs: readonly MirrorKeyedDef[] = []\n): StoreBuilder<TAccum> {\n return {\n resource<TKey extends string>(key: TKey): AsStep<TAccum, TKey> {\n return {\n as<T>(): StoreBuilder<TAccum & Record<TKey, ResourceDef<T>>> {\n const nextAccum = {\n ...accum,\n [key]: resource<T>(),\n } as TAccum & Record<TKey, ResourceDef<T>>;\n return createBuilder(nextAccum, mirrors, mirrorKeyedDefs);\n },\n };\n },\n mirror(source, sourceKey, targetKey?) {\n const def: MirrorDef = {\n sourceToken: source as InjectionToken<\n IStore<Record<string, ResourceState<unknown>>>\n >,\n sourceKey,\n targetKey: (targetKey ?? sourceKey) as string,\n };\n return createBuilder(accum, [...mirrors, def], mirrorKeyedDefs);\n },\n mirrorKeyed(source, sourceKey, options, targetKey?) {\n const def: MirrorKeyedDef = {\n sourceToken: source as InjectionToken<\n IStore<Record<string, ResourceState<unknown>>>\n >,\n sourceKey,\n targetKey: (targetKey ?? sourceKey) as string,\n extractId: options.extractId as (\n data: unknown\n ) => KeyedResourceKey | undefined,\n };\n return createBuilder(accum, mirrors, [...mirrorKeyedDefs, def]);\n },\n build() {\n return new InjectionToken<\n BaseStore<InferEnum<TAccum>, InferData<TAccum>>\n >(\"FlurryxStore\", {\n providedIn: \"root\",\n factory: () => {\n const store = new DynamicStore(accum);\n wireMirrors(store, mirrors);\n wireMirrorKeyed(store, mirrorKeyedDefs);\n return store as BaseStore<InferEnum<TAccum>, InferData<TAccum>>;\n },\n });\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// Constrained builder (.for(enum) API)\n// ---------------------------------------------------------------------------\n\n/** Keys from the enum that have NOT yet been defined. */\ntype Remaining<\n TEnum extends Record<string, string>,\n TAccum extends StoreConfig\n> = Exclude<keyof TEnum & string, keyof TAccum>;\n\n/** Intermediate .as<T>() step for the constrained builder. */\ninterface ConstrainedAsStep<\n TEnum extends Record<string, string>,\n TAccum extends StoreConfig,\n TKey extends string\n> {\n as<T>(): ConstrainedBuilder<TEnum, TAccum & Record<TKey, ResourceDef<T>>>;\n}\n\n/**\n * Constrained builder — only allows keys from the enum that haven't been\n * defined yet. `.build()` is only available when all keys are accounted for.\n */\ntype ConstrainedBuilder<\n TEnum extends Record<string, string>,\n TAccum extends StoreConfig\n> = [Remaining<TEnum, TAccum>] extends [never]\n ? {\n mirror<TSourceData extends Record<string, ResourceState<unknown>>>(\n source: InjectionToken<IStore<TSourceData>>,\n sourceKey: keyof TSourceData & string,\n targetKey?: keyof TAccum & string\n ): ConstrainedBuilder<TEnum, TAccum>;\n mirrorKeyed<\n TSourceData extends Record<string, ResourceState<unknown>>,\n TEntity\n >(\n source: InjectionToken<IStore<TSourceData>>,\n sourceKey: keyof TSourceData & string,\n options: {\n extractId: (\n data: TEntity | undefined\n ) => KeyedResourceKey | undefined;\n },\n targetKey?: keyof TAccum & string\n ): ConstrainedBuilder<TEnum, TAccum>;\n build(): InjectionToken<BaseStore<InferEnum<TAccum>, InferData<TAccum>>>;\n }\n : {\n resource<TKey extends Remaining<TEnum, TAccum>>(\n key: TKey\n ): ConstrainedAsStep<TEnum, TAccum, TKey>;\n };\n\nfunction createConstrainedBuilder<\n TEnum extends Record<string, string>,\n TAccum extends StoreConfig\n>(\n _enumObj: TEnum,\n accum: TAccum,\n mirrors: readonly MirrorDef[] = [],\n mirrorKeyedDefs: readonly MirrorKeyedDef[] = []\n): ConstrainedBuilder<TEnum, TAccum> {\n return {\n resource<TKey extends string>(\n key: TKey\n ): ConstrainedAsStep<TEnum, TAccum, TKey> {\n return {\n as<T>(): ConstrainedBuilder<\n TEnum,\n TAccum & Record<TKey, ResourceDef<T>>\n > {\n const nextAccum = {\n ...accum,\n [key]: resource<T>(),\n } as TAccum & Record<TKey, ResourceDef<T>>;\n return createConstrainedBuilder(\n _enumObj,\n nextAccum,\n mirrors,\n mirrorKeyedDefs\n );\n },\n };\n },\n mirror(\n source: InjectionToken<IStore<Record<string, ResourceState<unknown>>>>,\n sourceKey: string,\n targetKey?: string\n ) {\n const def: MirrorDef = {\n sourceToken: source,\n sourceKey,\n targetKey: targetKey ?? sourceKey,\n };\n return createConstrainedBuilder(\n _enumObj,\n accum,\n [...mirrors, def],\n mirrorKeyedDefs\n );\n },\n mirrorKeyed(\n source: InjectionToken<IStore<Record<string, ResourceState<unknown>>>>,\n sourceKey: string,\n options: {\n extractId: (data: unknown) => KeyedResourceKey | undefined;\n },\n targetKey?: string\n ) {\n const def: MirrorKeyedDef = {\n sourceToken: source,\n sourceKey,\n targetKey: targetKey ?? sourceKey,\n extractId: options.extractId,\n };\n return createConstrainedBuilder(_enumObj, accum, mirrors, [\n ...mirrorKeyedDefs,\n def,\n ]);\n },\n build() {\n return new InjectionToken<\n BaseStore<InferEnum<TAccum>, InferData<TAccum>>\n >(\"FlurryxStore\", {\n providedIn: \"root\",\n factory: () => {\n const store = new DynamicStore(accum);\n wireMirrors(store, mirrors);\n wireMirrorKeyed(store, mirrorKeyedDefs);\n return store as BaseStore<InferEnum<TAccum>, InferData<TAccum>>;\n },\n });\n },\n } as ConstrainedBuilder<TEnum, TAccum>;\n}\n\n// ---------------------------------------------------------------------------\n// Interface-based builder (Store.for<Config>() API)\n// ---------------------------------------------------------------------------\n\ninterface InterfaceBuilder<TConfig extends Record<string, unknown>> {\n mirror<TSourceData extends Record<string, ResourceState<unknown>>>(\n source: InjectionToken<IStore<TSourceData>>,\n sourceKey: keyof TSourceData & string,\n targetKey?: keyof TConfig & string\n ): InterfaceBuilder<TConfig>;\n mirrorKeyed<\n TSourceData extends Record<string, ResourceState<unknown>>,\n TEntity\n >(\n source: InjectionToken<IStore<TSourceData>>,\n sourceKey: keyof TSourceData & string,\n options: {\n extractId: (data: TEntity | undefined) => KeyedResourceKey | undefined;\n },\n targetKey?: keyof TConfig & string\n ): InterfaceBuilder<TConfig>;\n build(): InjectionToken<IStore<ConfigToData<TConfig>>>;\n}\n\nfunction createInterfaceBuilder<TConfig extends Record<string, unknown>>(\n mirrors: readonly MirrorDef[] = [],\n mirrorKeyedDefs: readonly MirrorKeyedDef[] = []\n): InterfaceBuilder<TConfig> {\n return {\n mirror(source, sourceKey, targetKey?) {\n const def: MirrorDef = {\n sourceToken: source as InjectionToken<\n IStore<Record<string, ResourceState<unknown>>>\n >,\n sourceKey,\n targetKey: (targetKey ?? sourceKey) as string,\n };\n return createInterfaceBuilder<TConfig>(\n [...mirrors, def],\n mirrorKeyedDefs\n );\n },\n mirrorKeyed(source, sourceKey, options, targetKey?) {\n const def: MirrorKeyedDef = {\n sourceToken: source as InjectionToken<\n IStore<Record<string, ResourceState<unknown>>>\n >,\n sourceKey,\n targetKey: (targetKey ?? sourceKey) as string,\n extractId: options.extractId as (\n data: unknown\n ) => KeyedResourceKey | undefined,\n };\n return createInterfaceBuilder<TConfig>(mirrors, [\n ...mirrorKeyedDefs,\n def,\n ]);\n },\n build() {\n return new InjectionToken(\"FlurryxStore\", {\n providedIn: \"root\",\n factory: () => {\n const store = new LazyStore() as IStore<\n Record<string, ResourceState<unknown>>\n >;\n wireMirrors(store, mirrors);\n wireMirrorKeyed(store, mirrorKeyedDefs);\n return store as unknown as IStore<ConfigToData<TConfig>>;\n },\n });\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// Public entry point\n// ---------------------------------------------------------------------------\n\ninterface StoreEntry {\n /**\n * Define a named resource slot.\n * Chain .as<T>() to assign its type, then continue with more .resource() calls\n * or call .build() when done.\n */\n resource<TKey extends string>(\n key: TKey\n ): {\n as<T>(): StoreBuilder<Record<TKey, ResourceDef<T>>>;\n };\n\n /**\n * Interface-based builder: pass a config interface as a generic.\n * No runtime argument needed — keys and types are inferred from the interface.\n *\n * @example\n * interface ChatStoreConfig {\n * SESSIONS: ChatSession[];\n * MESSAGES: ChatMessage[];\n * }\n * const ChatStore = Store.for<ChatStoreConfig>().build();\n */\n for<TConfig extends Record<string, unknown>>(): InterfaceBuilder<TConfig>;\n\n /**\n * Bind the builder to an enum object for compile-time key validation.\n *\n * @example\n * const Enum = { A: 'A', B: 'B' } as const;\n * const MyStore = Store.for(Enum)\n * .resource('A').as<string>()\n * .resource('B').as<number>()\n * .build();\n */\n for<TEnum extends Record<string, string>>(\n enumObj: TEnum\n ): ConstrainedBuilder<TEnum, Record<string, never>>;\n}\n\n/**\n * Fluent store builder entry point.\n *\n * @example\n * // Unconstrained\n * export const CustomersStore = Store\n * .resource('customers').as<Customer[]>()\n * .resource('customerDetails').as<Customer>()\n * .build();\n *\n * @example\n * // Constrained with enum\n * const Enum = { SESSIONS: 'SESSIONS', MESSAGES: 'MESSAGES' } as const;\n * export const ChatStore = Store.for(Enum)\n * .resource('SESSIONS').as<Session[]>()\n * .resource('MESSAGES').as<Message[]>()\n * .build();\n */\nexport const Store: StoreEntry = {\n ...createBuilder({} as StoreConfig),\n for(enumObj?: Record<string, string>) {\n if (arguments.length === 0) {\n return createInterfaceBuilder();\n }\n return createConstrainedBuilder(enumObj!, {} as Record<string, never>);\n },\n};\n","import { BaseStore } from './base-store';\nimport type { StoreConfig, InferEnum, InferData } from './types';\n\n/**\n * Internal concrete subclass of BaseStore.\n * Auto-generates an identity enum from config keys.\n * NOT publicly exported — consumers interact via BaseStore interface.\n */\nexport class DynamicStore<\n TConfig extends StoreConfig,\n> extends BaseStore<InferEnum<TConfig>, InferData<TConfig>> {\n constructor(config: TConfig) {\n const identityEnum = Object.keys(config).reduce(\n (acc, key) => ({ ...acc, [key]: key }),\n {} as InferEnum<TConfig>\n );\n super(identityEnum);\n }\n}\n","import type { ResourceState } from \"@flurryx/core\";\nimport type { IStore } from \"./types\";\n\nexport interface MirrorOptions {\n destroyRef?: { onDestroy: (fn: () => void) => void };\n}\n\n/**\n * Mirrors a resource key from a source store to a target store.\n * When the source key updates, the target key is updated with the same state.\n *\n * @param source - The store to mirror from\n * @param sourceKey - The key to watch on the source store\n * @param target - The store to mirror to\n * @param targetKeyOrOptions - Either the target key name or options (defaults source key)\n * @param options - Mirror options when a target key is provided\n * @returns Cleanup function to stop mirroring\n */\nexport function mirrorKey<\n TSource extends Record<string, ResourceState<unknown>>,\n TTarget extends Record<string, ResourceState<unknown>>\n>(\n source: IStore<TSource>,\n sourceKey: keyof TSource & string,\n target: IStore<TTarget>,\n targetKeyOrOptions?: (keyof TTarget & string) | MirrorOptions,\n options?: MirrorOptions\n): () => void {\n const resolvedTargetKey = (\n typeof targetKeyOrOptions === \"string\" ? targetKeyOrOptions : sourceKey\n ) as keyof TTarget & string;\n\n const resolvedOptions =\n typeof targetKeyOrOptions === \"object\" ? targetKeyOrOptions : options;\n\n const cleanup = source.onUpdate(sourceKey, (state) => {\n target.update(\n resolvedTargetKey,\n state as unknown as Partial<TTarget[keyof TTarget & string]>\n );\n });\n\n if (resolvedOptions?.destroyRef) {\n resolvedOptions.destroyRef.onDestroy(cleanup);\n }\n\n return cleanup;\n}\n","import type {\n ResourceState,\n KeyedResourceKey,\n KeyedResourceData,\n} from '@flurryx/core';\nimport { createKeyedResourceData, isAnyKeyLoading } from '@flurryx/core';\nimport type { IStore } from './types';\n\nexport interface CollectKeyedOptions<TEntity> {\n extractId: (data: TEntity | undefined) => KeyedResourceKey | undefined;\n destroyRef?: { onDestroy: (fn: () => void) => void };\n}\n\n/**\n * Accumulates single-entity resource fetches into a keyed cache on a target store.\n *\n * On each source update:\n * - If status is 'Success' and extractId returns a valid key, merges the entity\n * into the target's keyed resource data.\n * - If the source data is cleared and a previous entity existed, removes it from\n * the target's keyed data.\n *\n * @param source - The store containing the single-entity resource\n * @param sourceKey - The key to watch on the source store\n * @param target - The store to accumulate entities into\n * @param targetKeyOrOptions - Either the target key name or options (defaults source key)\n * @param options - Collect options when a target key is provided\n * @returns Cleanup function to stop collecting\n */\nexport function collectKeyed<\n TSource extends Record<string, ResourceState<unknown>>,\n TTarget extends Record<string, ResourceState<unknown>>,\n TEntity = unknown,\n>(\n source: IStore<TSource>,\n sourceKey: keyof TSource & string,\n target: IStore<TTarget>,\n targetKeyOrOptions?: (keyof TTarget & string) | CollectKeyedOptions<TEntity>,\n options?: CollectKeyedOptions<TEntity>,\n): () => void {\n const resolvedTargetKey = (\n typeof targetKeyOrOptions === 'string'\n ? targetKeyOrOptions\n : sourceKey\n ) as keyof TTarget & string;\n\n const resolvedOptions = (\n typeof targetKeyOrOptions === 'object' ? targetKeyOrOptions : options\n ) as CollectKeyedOptions<TEntity>;\n\n // Initialize target with empty keyed resource data\n target.update(resolvedTargetKey, {\n data: createKeyedResourceData(),\n } as Partial<TTarget[keyof TTarget & string]>);\n\n let previousId: KeyedResourceKey | undefined;\n\n const cleanup = source.onUpdate(sourceKey, (state) => {\n const resourceState = state as ResourceState<TEntity>;\n const currentId = resolvedOptions.extractId(resourceState.data);\n const currentTarget = target.get(resolvedTargetKey)();\n const currentKeyed = (currentTarget as ResourceState<unknown>).data as\n KeyedResourceData<KeyedResourceKey, TEntity> | undefined;\n\n if (!currentKeyed) {\n return;\n }\n\n if (resourceState.status === 'Success' && currentId !== undefined) {\n const newEntities = { ...currentKeyed.entities, [currentId]: resourceState.data };\n const newIsLoading = { ...currentKeyed.isLoading, [currentId]: false };\n const newStatus = { ...currentKeyed.status, [currentId]: resourceState.status };\n const newErrors = { ...currentKeyed.errors };\n delete newErrors[currentId];\n\n const updatedKeyed: KeyedResourceData<KeyedResourceKey, TEntity> = {\n entities: newEntities,\n isLoading: newIsLoading,\n status: newStatus,\n errors: newErrors,\n };\n\n target.update(resolvedTargetKey, {\n data: updatedKeyed,\n isLoading: isAnyKeyLoading(newIsLoading),\n status: 'Success',\n } as Partial<TTarget[keyof TTarget & string]>);\n\n previousId = currentId;\n } else if (resourceState.status === 'Error' && currentId !== undefined) {\n const newIsLoading = { ...currentKeyed.isLoading, [currentId]: false };\n const newStatus = { ...currentKeyed.status, [currentId]: resourceState.status };\n const newErrors = { ...currentKeyed.errors, [currentId]: resourceState.errors };\n\n const updatedKeyed: KeyedResourceData<KeyedResourceKey, TEntity> = {\n entities: { ...currentKeyed.entities },\n isLoading: newIsLoading,\n status: newStatus,\n errors: newErrors,\n };\n\n target.update(resolvedTargetKey, {\n data: updatedKeyed,\n isLoading: isAnyKeyLoading(newIsLoading),\n } as Partial<TTarget[keyof TTarget & string]>);\n\n previousId = currentId;\n } else if (resourceState.data === undefined && previousId !== undefined) {\n // Source cleared — remove previous entity from cache\n const { [previousId]: _removed, ...remainingEntities } = currentKeyed.entities;\n const { [previousId]: _removedLoading, ...remainingLoading } = currentKeyed.isLoading;\n const { [previousId]: _removedStatus, ...remainingStatus } = currentKeyed.status;\n const { [previousId]: _removedErrors, ...remainingErrors } = currentKeyed.errors;\n\n const updatedKeyed: KeyedResourceData<KeyedResourceKey, TEntity> = {\n entities: remainingEntities,\n isLoading: remainingLoading,\n status: remainingStatus,\n errors: remainingErrors,\n };\n\n target.update(resolvedTargetKey, {\n data: updatedKeyed,\n isLoading: isAnyKeyLoading(remainingLoading),\n } as Partial<TTarget[keyof TTarget & string]>);\n\n previousId = undefined;\n } else if (resourceState.isLoading && currentId !== undefined) {\n const newIsLoading = { ...currentKeyed.isLoading, [currentId]: true };\n\n const updatedKeyed: KeyedResourceData<KeyedResourceKey, TEntity> = {\n entities: { ...currentKeyed.entities },\n isLoading: newIsLoading,\n status: { ...currentKeyed.status },\n errors: { ...currentKeyed.errors },\n };\n\n target.update(resolvedTargetKey, {\n data: updatedKeyed,\n isLoading: true,\n } as Partial<TTarget[keyof TTarget & string]>);\n\n previousId = currentId;\n }\n });\n\n if (resolvedOptions?.destroyRef) {\n resolvedOptions.destroyRef.onDestroy(cleanup);\n }\n\n return cleanup;\n}\n","import type { ResourceDef } from './types';\n\n/**\n * Creates a phantom-typed resource definition marker.\n * Zero runtime cost — returns an empty object that only carries type info.\n *\n * @example\n * const config = {\n * customers: resource<Customer[]>(),\n * customerDetails: resource<Customer>(),\n * };\n */\nexport function resource<T>(): ResourceDef<T> {\n return {} as ResourceDef<T>;\n}\n"],"mappings":"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","names":["signal","createKeyedResourceData","isAnyKeyLoading"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flurryx/store",
3
- "version": "0.7.1",
3
+ "version": "0.7.4",
4
4
  "description": "Signal-first reactive store for Angular",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -28,7 +28,7 @@
28
28
  },
29
29
  "sideEffects": false,
30
30
  "dependencies": {
31
- "@flurryx/core": "0.7.1"
31
+ "@flurryx/core": "0.7.4"
32
32
  },
33
33
  "peerDependencies": {
34
34
  "@angular/core": ">=17.0.0"