@reforgium/statum 2.0.1 → 2.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md
CHANGED
|
@@ -16,9 +16,11 @@ Designed for **application state**, not abstract reducers.
|
|
|
16
16
|
|
|
17
17
|
- Signals-first API (`signal()` everywhere)
|
|
18
18
|
- API-driven stores (resource / paginated / dictionaries)
|
|
19
|
+
- Normalized entity store (`EntityStore`)
|
|
19
20
|
- Built-in cache strategies (TTL, prefix grouping)
|
|
20
21
|
- Deterministic request lifecycle: loading / error / data
|
|
21
22
|
- Optional transport-level: dedupe, debounce/throttle, abort
|
|
23
|
+
- Unified retry and trace hooks in `ResourceStore`
|
|
22
24
|
- Explicit serialization / deserialization boundary
|
|
23
25
|
|
|
24
26
|
---
|
|
@@ -134,6 +136,47 @@ const user = await userStore.get(
|
|
|
134
136
|
);
|
|
135
137
|
```
|
|
136
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
|
+
|
|
137
180
|
---
|
|
138
181
|
|
|
139
182
|
## PaginatedDataStore
|
|
@@ -264,6 +307,28 @@ dict.search('kir'); // local search over cache
|
|
|
264
307
|
|
|
265
308
|
---
|
|
266
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
|
+
|
|
267
332
|
## Serializer
|
|
268
333
|
|
|
269
334
|
### Serializer
|