@reforgium/statum 2.0.1 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -12,14 +12,16 @@ Designed for **application state**, not abstract reducers.
12
12
 
13
13
  ---
14
14
 
15
- ## Features
16
-
17
- - Signals-first API (`signal()` everywhere)
18
- - API-driven stores (resource / paginated / dictionaries)
19
- - Built-in cache strategies (TTL, prefix grouping)
20
- - Deterministic request lifecycle: loading / error / data
21
- - Optional transport-level: dedupe, debounce/throttle, abort
22
- - Explicit serialization / deserialization boundary
15
+ ## Features
16
+
17
+ - Signals-first API (`signal()` everywhere)
18
+ - API-driven stores (resource / paginated / dictionaries)
19
+ - Normalized entity store (`EntityStore`)
20
+ - Built-in cache strategies (TTL, prefix grouping)
21
+ - Deterministic request lifecycle: loading / error / data
22
+ - Optional transport-level: dedupe, debounce/throttle, abort
23
+ - Unified retry and trace hooks in `ResourceStore`
24
+ - Explicit serialization / deserialization boundary
23
25
 
24
26
  ---
25
27
 
@@ -67,7 +69,7 @@ interface StorageInterface<T> {
67
69
  }
68
70
  ```
69
71
 
70
- Example:
72
+ Example:
71
73
 
72
74
  ```ts
73
75
  import { cacheStrategy } from '@reforgium/statum';
@@ -128,15 +130,56 @@ const userStore = new ResourceStore<User>(
128
130
  { baseUrl: '/api', ttlMs: 60_000 }
129
131
  );
130
132
 
131
- const user = await userStore.get(
132
- { params: { id: '42' }, query: {} },
133
- { dedupe: true }
134
- );
135
- ```
136
-
137
- ---
138
-
139
- ## PaginatedDataStore
133
+ const user = await userStore.get(
134
+ { params: { id: '42' }, query: {} },
135
+ { dedupe: true }
136
+ );
137
+ ```
138
+
139
+ Retry + trace example:
140
+
141
+ ```ts
142
+ import { ResourceStore } from '@reforgium/statum';
143
+
144
+ const store = new ResourceStore<{ id: number; name: string }>(
145
+ { GET: '/users/:id' },
146
+ {
147
+ baseUrl: '/api',
148
+ retry: { attempts: 2, delayMs: 150, backoff: 'exponential' },
149
+ onTrace: (event) => console.debug('[resource-trace]', event),
150
+ }
151
+ );
152
+
153
+ await store.get(
154
+ { params: { id: '42' } },
155
+ { retry: { attempts: 1 } } // per-call override
156
+ );
157
+ ```
158
+
159
+ ---
160
+
161
+ ## EntityStore
162
+
163
+ Normalized entities store (`byId` + `ids`) for fast updates and stable list composition.
164
+
165
+ Example:
166
+
167
+ ```ts
168
+ import { EntityStore } from '@reforgium/statum';
169
+
170
+ type User = { id: number; name: string };
171
+
172
+ const entities = new EntityStore<User, 'id'>({ idKey: 'id' });
173
+
174
+ entities.setAll([{ id: 1, name: 'Neo' }]);
175
+ entities.upsertOne({ id: 2, name: 'Trinity' });
176
+ entities.patchOne(2, { name: 'Trin' });
177
+ entities.removeOne(1);
178
+ ```
179
+
180
+ ---
181
+
182
+ ## PaginatedDataStore
140
183
 
141
184
  Lightweight store for server-side pagination with sorting, filtering, and page cache.
142
185
 
@@ -259,12 +302,34 @@ const dict = new DictStore<Country>('api/dictionaries/countries', 'countries', {
259
302
  });
260
303
 
261
304
  dict.search(''); // initial fill
262
- dict.search('kir'); // local search over cache
263
- ```
264
-
265
- ---
266
-
267
- ## Serializer
305
+ dict.search('kir'); // local search over cache
306
+ ```
307
+
308
+ ---
309
+
310
+ ## Composition Patterns
311
+
312
+ ### PaginatedDataStore + EntityStore
313
+
314
+ ```ts
315
+ import { effect } from '@angular/core';
316
+ import { EntityStore, PaginatedDataStore } from '@reforgium/statum';
317
+
318
+ type User = { id: number; name: string };
319
+
320
+ const pages = new PaginatedDataStore<User, { search?: string }>('/api/users');
321
+ const entities = new EntityStore<User, 'id'>({ idKey: 'id' });
322
+
323
+ effect(() => {
324
+ entities.upsertMany(pages.items());
325
+ });
326
+ ```
327
+
328
+ This keeps page-loading logic in `PaginatedDataStore` and normalized lookup/update logic in `EntityStore`.
329
+
330
+ ---
331
+
332
+ ## Serializer
268
333
 
269
334
  ### Serializer
270
335