flurryx 0.7.3 → 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.
Files changed (2) hide show
  1. package/README.md +78 -1
  2. package/package.json +4 -4
package/README.md CHANGED
@@ -67,6 +67,7 @@ No `async` pipe. No `subscribe` in templates. No manual unsubscription.
67
67
  - [Keyed Resources](#keyed-resources)
68
68
  - [Store Mirroring](#store-mirroring)
69
69
  - [Builder .mirror()](#builder-mirror)
70
+ - [Builder .mirrorKeyed()](#builder-mirrorkeyed)
70
71
  - [mirrorKey](#mirrorkey)
71
72
  - [collectKeyed](#collectkeyed)
72
73
  - [Design Decisions](#design-decisions)
@@ -611,9 +612,14 @@ When building session or aggregation stores that combine state from multiple fea
611
612
  | (ORDERS) |-- mirrorKey ------>| CUSTOMERS + |
612
613
  +--------------------+ | ORDERS + |
613
614
  | CUSTOMER_CACHE + |
614
- +--------------------+ | |
615
+ +--------------------+ | ORDER_CACHE + |
615
616
  | Feature Store C | | |
616
617
  | (CUSTOMER_DETAIL) |-- collectKeyed --->| |
618
+ +--------------------+ | |
619
+ | |
620
+ +--------------------+ | |
621
+ | Feature Store D | | |
622
+ | (ORDER_DETAIL) |-- mirrorKeyed --->| |
617
623
  +--------------------+ +--------------------+
618
624
  ```
619
625
 
@@ -686,6 +692,77 @@ export const SessionStore = Store.for<{ ARTICLES: Item[] }>()
686
692
 
687
693
  The builder calls `inject()` under the hood, so source stores are resolved through Angular's DI. Everything — data, loading, status, errors — is mirrored automatically. No manual cleanup needed; the mirrors live as long as the store.
688
694
 
695
+ ### Builder .mirrorKeyed()
696
+
697
+ When the source store holds a single-entity slot (e.g. `CUSTOMER_DETAILS: Customer`) and you want to accumulate those fetches into a `KeyedResourceData` cache on the target, use `.mirrorKeyed()`. It is the builder equivalent of [`collectKeyed`](#collectkeyed).
698
+
699
+ ```typescript
700
+ // Feature store — fetches one customer at a time
701
+ interface CustomerStoreConfig {
702
+ CUSTOMERS: Customer[];
703
+ CUSTOMER_DETAILS: Customer;
704
+ }
705
+ export const CustomerStore = Store.for<CustomerStoreConfig>().build();
706
+ ```
707
+
708
+ **Interface-based builder** (recommended):
709
+
710
+ ```typescript
711
+ interface SessionStoreConfig {
712
+ CUSTOMERS: Customer[];
713
+ CUSTOMER_CACHE: KeyedResourceData<string, Customer>;
714
+ }
715
+
716
+ export const SessionStore = Store.for<SessionStoreConfig>()
717
+ .mirror(CustomerStore, 'CUSTOMERS')
718
+ .mirrorKeyed(CustomerStore, 'CUSTOMER_DETAILS', {
719
+ extractId: (data) => data?.id,
720
+ }, 'CUSTOMER_CACHE')
721
+ .build();
722
+ ```
723
+
724
+ **Fluent chaining:**
725
+
726
+ ```typescript
727
+ export const SessionStore = Store
728
+ .resource('CUSTOMERS').as<Customer[]>()
729
+ .resource('CUSTOMER_CACHE').as<KeyedResourceData<string, Customer>>()
730
+ .mirror(CustomerStore, 'CUSTOMERS')
731
+ .mirrorKeyed(CustomerStore, 'CUSTOMER_DETAILS', {
732
+ extractId: (data) => data?.id,
733
+ }, 'CUSTOMER_CACHE')
734
+ .build();
735
+ ```
736
+
737
+ **Enum-constrained:**
738
+
739
+ ```typescript
740
+ const SessionEnum = { CUSTOMERS: 'CUSTOMERS', CUSTOMER_CACHE: 'CUSTOMER_CACHE' } as const;
741
+
742
+ export const SessionStore = Store.for(SessionEnum)
743
+ .resource('CUSTOMERS').as<Customer[]>()
744
+ .resource('CUSTOMER_CACHE').as<KeyedResourceData<string, Customer>>()
745
+ .mirror(CustomerStore, 'CUSTOMERS')
746
+ .mirrorKeyed(CustomerStore, 'CUSTOMER_DETAILS', {
747
+ extractId: (data) => data?.id,
748
+ }, 'CUSTOMER_CACHE')
749
+ .build();
750
+ ```
751
+
752
+ **Same source and target key** — when the key names match, the last argument can be omitted:
753
+
754
+ ```typescript
755
+ export const SessionStore = Store.for<{
756
+ CUSTOMER_DETAILS: KeyedResourceData<string, Customer>;
757
+ }>()
758
+ .mirrorKeyed(CustomerStore, 'CUSTOMER_DETAILS', {
759
+ extractId: (data) => data?.id,
760
+ })
761
+ .build();
762
+ ```
763
+
764
+ Each entity fetched through the source slot is accumulated by ID into the target's `KeyedResourceData`. Loading, status, and errors are tracked per entity. When the source is cleared, the corresponding entity is removed from the cache.
765
+
689
766
  ### mirrorKey
690
767
 
691
768
  Mirrors a resource key from one store to another. When the source updates, the target is updated with the same state.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "flurryx",
3
- "version": "0.7.3",
3
+ "version": "0.7.4",
4
4
  "description": "Signal-first reactive state management for Angular",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -38,9 +38,9 @@
38
38
  },
39
39
  "sideEffects": false,
40
40
  "dependencies": {
41
- "@flurryx/core": "0.7.3",
42
- "@flurryx/store": "0.7.3",
43
- "@flurryx/rx": "0.7.3"
41
+ "@flurryx/core": "0.7.4",
42
+ "@flurryx/store": "0.7.4",
43
+ "@flurryx/rx": "0.7.4"
44
44
  },
45
45
  "peerDependencies": {
46
46
  "@angular/core": ">=17.0.0",