@reforgium/statum 2.1.1 → 3.0.0-rc.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 +88 -50
- package/fesm2022/reforgium-statum.mjs +103 -76
- package/package.json +2 -1
- package/types/reforgium-statum.d.ts +93 -63
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# @reforgium/statum
|
|
1
|
+
# @reforgium/statum
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/@reforgium/statum)
|
|
4
4
|
[](https://opensource.org/licenses/MIT)
|
|
@@ -25,13 +25,29 @@ Designed for **application state**, not abstract reducers.
|
|
|
25
25
|
|
|
26
26
|
---
|
|
27
27
|
|
|
28
|
-
## Installation
|
|
29
|
-
|
|
30
|
-
```bash
|
|
31
|
-
npm install @reforgium/statum
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
|
|
28
|
+
## Installation
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npm install @reforgium/statum
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Configuration
|
|
35
|
+
|
|
36
|
+
```ts
|
|
37
|
+
import { provideStatum } from '@reforgium/statum';
|
|
38
|
+
|
|
39
|
+
providers: [
|
|
40
|
+
provideStatum({
|
|
41
|
+
pagedQuery: {
|
|
42
|
+
defaultMethod: 'GET',
|
|
43
|
+
defaultHasCache: true,
|
|
44
|
+
defaultCacheSize: 10,
|
|
45
|
+
},
|
|
46
|
+
}),
|
|
47
|
+
];
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
---
|
|
35
51
|
|
|
36
52
|
## Package Structure
|
|
37
53
|
|
|
@@ -136,7 +152,7 @@ const user = await userStore.get(
|
|
|
136
152
|
);
|
|
137
153
|
```
|
|
138
154
|
|
|
139
|
-
Retry + trace example:
|
|
155
|
+
Retry + trace example:
|
|
140
156
|
|
|
141
157
|
```ts
|
|
142
158
|
import { ResourceStore } from '@reforgium/statum';
|
|
@@ -150,11 +166,22 @@ const store = new ResourceStore<{ id: number; name: string }>(
|
|
|
150
166
|
}
|
|
151
167
|
);
|
|
152
168
|
|
|
153
|
-
await store.get(
|
|
154
|
-
{ params: { id: '42' } },
|
|
155
|
-
{ retry: { attempts: 1 } } // per-call override
|
|
156
|
-
);
|
|
157
|
-
```
|
|
169
|
+
await store.get(
|
|
170
|
+
{ params: { id: '42' } },
|
|
171
|
+
{ retry: { attempts: 1 } } // per-call override
|
|
172
|
+
);
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
Profiles example:
|
|
176
|
+
|
|
177
|
+
```ts
|
|
178
|
+
import { createResourceProfile, ResourceStore } from '@reforgium/statum';
|
|
179
|
+
|
|
180
|
+
const usersStore = new ResourceStore<{ id: number; name: string }>(
|
|
181
|
+
{ GET: '/users' },
|
|
182
|
+
createResourceProfile('table', { baseUrl: '/api' })
|
|
183
|
+
);
|
|
184
|
+
```
|
|
158
185
|
|
|
159
186
|
---
|
|
160
187
|
|
|
@@ -179,9 +206,9 @@ entities.removeOne(1);
|
|
|
179
206
|
|
|
180
207
|
---
|
|
181
208
|
|
|
182
|
-
##
|
|
183
|
-
|
|
184
|
-
Lightweight store for server-side pagination with
|
|
209
|
+
## PagedQueryStore
|
|
210
|
+
|
|
211
|
+
Lightweight store for server-side pagination with filtering, dynamic query params, and page cache.
|
|
185
212
|
|
|
186
213
|
### When to use
|
|
187
214
|
|
|
@@ -200,46 +227,54 @@ Lightweight store for server-side pagination with sorting, filtering, and page c
|
|
|
200
227
|
| page | `number` | Current page (0-based) |
|
|
201
228
|
| pageSize | `number` | Page size |
|
|
202
229
|
| totalElements | `number` | Total items on server |
|
|
203
|
-
| filters | `Partial<F>` | Active filters |
|
|
204
|
-
|
|
|
230
|
+
| filters | `Partial<F>` | Active filters |
|
|
231
|
+
| query | `Record<string, unknown>` | Active query params |
|
|
205
232
|
|
|
206
233
|
### Methods
|
|
207
234
|
|
|
208
|
-
| Method | Description
|
|
209
|
-
|
|
210
|
-
|
|
|
211
|
-
|
|
|
212
|
-
|
|
|
213
|
-
|
|
|
214
|
-
|
|
|
215
|
-
|
|
|
216
|
-
|
|
|
217
|
-
|
|
|
218
|
-
|
|
|
219
|
-
|
|
220
|
-
|
|
235
|
+
| Method | Description |
|
|
236
|
+
|----------------|---------------------------------------------------------------------------|
|
|
237
|
+
| fetch | Clean first-page request: `fetch({ filters, query, routeParams })` |
|
|
238
|
+
| refresh | Repeat request, optional merge overrides: `refresh({ filters, query })` |
|
|
239
|
+
| updatePage | Change page: `updatePage(page, { ignoreCache })` |
|
|
240
|
+
| updatePageSize | Change page size and reset cache: `updatePageSize(size)` |
|
|
241
|
+
| updateByOffset | Table-event mapper: `updateByOffset({ page/first/rows }, { query })` |
|
|
242
|
+
| setRouteParams | Update route params: `setRouteParams(params, { reset, abort })` |
|
|
243
|
+
| updateConfig | Patch config: `updateConfig(config)` |
|
|
244
|
+
| copy | Copy config/meta: `copy(store)` |
|
|
245
|
+
| destroy | Manual destroying of caches and abort requests |
|
|
246
|
+
|
|
247
|
+
### Cache behavior
|
|
248
|
+
|
|
249
|
+
| Method | Cache read | Cache reset | Notes |
|
|
250
|
+
|----------------|------------|-------------|-------|
|
|
251
|
+
| fetch | no | yes | Always starts clean from page `0` |
|
|
252
|
+
| refresh | no | no | Uses active page/filters/query, merges overrides |
|
|
253
|
+
| updatePage | yes | no | Can bypass with `ignoreCache: true` |
|
|
254
|
+
| updatePageSize | no | yes | Prevents mixed caches for different page sizes |
|
|
255
|
+
| updateByOffset | yes | no | Internally maps to `page + size` |
|
|
221
256
|
|
|
222
257
|
Example:
|
|
223
258
|
|
|
224
259
|
```ts
|
|
225
|
-
import {
|
|
260
|
+
import { PagedQueryStore } from '@reforgium/statum';
|
|
226
261
|
|
|
227
262
|
type User = { id: number; name: string };
|
|
228
263
|
|
|
229
|
-
const store = new
|
|
230
|
-
method: 'GET',
|
|
231
|
-
debounceTime: 200,
|
|
232
|
-
});
|
|
233
|
-
|
|
234
|
-
store.
|
|
235
|
-
store.
|
|
264
|
+
const store = new PagedQueryStore<User, { search?: string }>('api/users', {
|
|
265
|
+
method: 'GET',
|
|
266
|
+
debounceTime: 200,
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
store.fetch({ filters: { search: 'neo' }, query: { tenant: 'kg' } });
|
|
270
|
+
store.updateByOffset({ first: 20, rows: 20 });
|
|
236
271
|
```
|
|
237
272
|
|
|
238
273
|
---
|
|
239
274
|
|
|
240
275
|
## DictStore
|
|
241
276
|
|
|
242
|
-
Helper for dictionaries/options (select/autocomplete) on top of
|
|
277
|
+
Helper for dictionaries/options (select/autocomplete) on top of PagedQueryStore.
|
|
243
278
|
|
|
244
279
|
### When to use
|
|
245
280
|
|
|
@@ -309,15 +344,15 @@ dict.search('kir'); // local search over cache
|
|
|
309
344
|
|
|
310
345
|
## Composition Patterns
|
|
311
346
|
|
|
312
|
-
###
|
|
347
|
+
### PagedQueryStore + EntityStore
|
|
313
348
|
|
|
314
349
|
```ts
|
|
315
350
|
import { effect } from '@angular/core';
|
|
316
|
-
import { EntityStore,
|
|
351
|
+
import { EntityStore, PagedQueryStore } from '@reforgium/statum';
|
|
317
352
|
|
|
318
353
|
type User = { id: number; name: string };
|
|
319
354
|
|
|
320
|
-
const pages = new
|
|
355
|
+
const pages = new PagedQueryStore<User, { search?: string }>('/api/users');
|
|
321
356
|
const entities = new EntityStore<User, 'id'>({ idKey: 'id' });
|
|
322
357
|
|
|
323
358
|
effect(() => {
|
|
@@ -325,7 +360,7 @@ effect(() => {
|
|
|
325
360
|
});
|
|
326
361
|
```
|
|
327
362
|
|
|
328
|
-
This keeps page-loading logic in `
|
|
363
|
+
This keeps page-loading logic in `PagedQueryStore` and normalized lookup/update logic in `EntityStore`.
|
|
329
364
|
|
|
330
365
|
---
|
|
331
366
|
|
|
@@ -374,11 +409,12 @@ const body = serializer.serialize({ name: ' Vasya ', active: null });
|
|
|
374
409
|
|
|
375
410
|
---
|
|
376
411
|
|
|
377
|
-
## Source Structure
|
|
378
|
-
|
|
379
|
-
- Cache: `src/cache`
|
|
380
|
-
- Stores: `src/stores`
|
|
381
|
-
- Serializer: `src/serializer`
|
|
412
|
+
## Source Structure
|
|
413
|
+
|
|
414
|
+
- Cache: `src/cache`
|
|
415
|
+
- Stores: `src/stores`
|
|
416
|
+
- Serializer: `src/serializer`
|
|
417
|
+
- Migration: `MIGRATION.md`
|
|
382
418
|
|
|
383
419
|
---
|
|
384
420
|
|
|
@@ -393,3 +429,5 @@ const body = serializer.serialize({ name: ' Vasya ', active: null });
|
|
|
393
429
|
## License
|
|
394
430
|
|
|
395
431
|
MIT
|
|
432
|
+
|
|
433
|
+
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { formatDate, isNullable, isDatePeriod, parseToDate, makeQuery, isNumber, isObject, parseToDatePeriod, parseQueryArray, fillUrlWithParams, deepEqual, concatArray, debounceSignal } from '@reforgium/internal';
|
|
2
2
|
import { HttpClient } from '@angular/common/http';
|
|
3
|
-
import { InjectionToken, inject, signal, computed, DestroyRef, effect, untracked } from '@angular/core';
|
|
3
|
+
import { InjectionToken, makeEnvironmentProviders, inject, signal, computed, DestroyRef, effect, untracked } from '@angular/core';
|
|
4
4
|
import { Subject, filter, timer, merge, map } from 'rxjs';
|
|
5
5
|
import { debounce, tap, throttle, finalize } from 'rxjs/operators';
|
|
6
6
|
|
|
@@ -599,6 +599,7 @@ const storageStrategy = (strategy, options = {}) => {
|
|
|
599
599
|
|
|
600
600
|
// noinspection ES6PreferShortImport
|
|
601
601
|
const STATUM_CONFIG = new InjectionToken('RE_STATUM_CONFIG');
|
|
602
|
+
const provideStatum = (config) => makeEnvironmentProviders([{ provide: STATUM_CONFIG, useValue: config }]);
|
|
602
603
|
|
|
603
604
|
/**
|
|
604
605
|
* Error thrown when requested data is missing in the cache.
|
|
@@ -1013,7 +1014,14 @@ class ResourceStore {
|
|
|
1013
1014
|
abort(method, args, reason) {
|
|
1014
1015
|
const url = this.buildUrl(method, args);
|
|
1015
1016
|
const key = buildKey(method, url, args);
|
|
1017
|
+
const entry = this.entries.get(key);
|
|
1016
1018
|
this.trace({ type: 'abort', method, key });
|
|
1019
|
+
if (entry) {
|
|
1020
|
+
entry.inflight = undefined;
|
|
1021
|
+
if (entry.status === 'loading' || entry.status === 'stale') {
|
|
1022
|
+
entry.status = 'idle';
|
|
1023
|
+
}
|
|
1024
|
+
}
|
|
1017
1025
|
this.scheduler.cancel?.(key, reason);
|
|
1018
1026
|
}
|
|
1019
1027
|
/**
|
|
@@ -1023,6 +1031,12 @@ class ResourceStore {
|
|
|
1023
1031
|
*/
|
|
1024
1032
|
abortAll(reason) {
|
|
1025
1033
|
this.trace({ type: 'abort', method: 'GET', key: '*' });
|
|
1034
|
+
this.entries.forEach((entry) => {
|
|
1035
|
+
entry.inflight = undefined;
|
|
1036
|
+
if (entry.status === 'loading' || entry.status === 'stale') {
|
|
1037
|
+
entry.status = 'idle';
|
|
1038
|
+
}
|
|
1039
|
+
});
|
|
1026
1040
|
this.scheduler.cancelAll?.(reason);
|
|
1027
1041
|
}
|
|
1028
1042
|
ensureEntry(key) {
|
|
@@ -1206,39 +1220,64 @@ class ResourceStore {
|
|
|
1206
1220
|
}
|
|
1207
1221
|
}
|
|
1208
1222
|
|
|
1223
|
+
const RESOURCE_PROFILES = {
|
|
1224
|
+
table: {
|
|
1225
|
+
ttlMs: 15_000,
|
|
1226
|
+
delay: 120,
|
|
1227
|
+
delayMode: 'debounce',
|
|
1228
|
+
maxEntries: 500,
|
|
1229
|
+
},
|
|
1230
|
+
lookup: {
|
|
1231
|
+
ttlMs: 60_000,
|
|
1232
|
+
delay: 200,
|
|
1233
|
+
delayMode: 'debounce',
|
|
1234
|
+
maxEntries: 300,
|
|
1235
|
+
},
|
|
1236
|
+
mutation: {
|
|
1237
|
+
ttlMs: 0,
|
|
1238
|
+
delay: 0,
|
|
1239
|
+
delayMode: 'throttle',
|
|
1240
|
+
maxEntries: 50,
|
|
1241
|
+
},
|
|
1242
|
+
};
|
|
1243
|
+
const createResourceProfile = (profile, overrides = {}) => ({
|
|
1244
|
+
...RESOURCE_PROFILES[profile],
|
|
1245
|
+
...overrides,
|
|
1246
|
+
});
|
|
1247
|
+
|
|
1209
1248
|
// noinspection ES6PreferShortImport
|
|
1210
1249
|
/**
|
|
1211
1250
|
* Store for paginated data (tables/lists) with per-page cache and unified requests.
|
|
1212
1251
|
*
|
|
1213
1252
|
* Provides:
|
|
1214
1253
|
* - reactive signals: `items`, `loading`, `cached`;
|
|
1215
|
-
* - methods to control page/size/
|
|
1254
|
+
* - methods to control page/size/query;
|
|
1216
1255
|
* - optional LRU cache by pages;
|
|
1217
|
-
* - configurable transport (GET/POST/PATCH
|
|
1256
|
+
* - configurable transport (GET/POST/PATCH/…).
|
|
1218
1257
|
*
|
|
1219
1258
|
* Example:
|
|
1220
1259
|
* ```ts
|
|
1221
|
-
* const ds = new
|
|
1260
|
+
* const ds = new PagedQueryStore<User>('/users', { method: 'GET', hasCache: true });
|
|
1222
1261
|
* await ds.updatePage(0); // load the first page
|
|
1223
1262
|
* effect(() => console.log(ds.items(), ds.loading()));
|
|
1224
1263
|
* ```
|
|
1225
1264
|
*/
|
|
1226
|
-
class
|
|
1265
|
+
class PagedQueryStore {
|
|
1227
1266
|
route;
|
|
1228
1267
|
config;
|
|
1229
|
-
defaultConfig = inject(STATUM_CONFIG, { optional: true })?.
|
|
1268
|
+
defaultConfig = inject(STATUM_CONFIG, { optional: true })?.pagedQuery || {};
|
|
1230
1269
|
#transport;
|
|
1231
1270
|
#cache;
|
|
1232
1271
|
/** Current page data (reactive). */
|
|
1233
1272
|
items = signal([], ...(ngDevMode ? [{ debugName: "items" }] : []));
|
|
1234
|
-
/** Merged cache of pages (flat list)
|
|
1273
|
+
/** Merged cache of pages (flat list) — handy for search/export. */
|
|
1235
1274
|
cached = signal([], ...(ngDevMode ? [{ debugName: "cached" }] : []));
|
|
1236
1275
|
/** Loading flag of the current operation. */
|
|
1237
1276
|
loading = signal(false, ...(ngDevMode ? [{ debugName: "loading" }] : []));
|
|
1238
1277
|
/** Current filters (applied to requests). */
|
|
1239
1278
|
filters = {};
|
|
1240
|
-
/**
|
|
1241
|
-
|
|
1279
|
+
/** Additional query params sent to transport requests. */
|
|
1280
|
+
query = {};
|
|
1242
1281
|
/** Current page index (0-based). */
|
|
1243
1282
|
page = 0;
|
|
1244
1283
|
/** Default page size. */
|
|
@@ -1259,17 +1298,32 @@ class PaginatedDataStore {
|
|
|
1259
1298
|
this.initTransport();
|
|
1260
1299
|
inject(DestroyRef).onDestroy(() => this.destroy());
|
|
1261
1300
|
}
|
|
1262
|
-
/**
|
|
1263
|
-
|
|
1264
|
-
|
|
1301
|
+
/**
|
|
1302
|
+
* Fetch data with explicit filters and query params from the first page.
|
|
1303
|
+
* Replaces legacy `setFilters`.
|
|
1304
|
+
*/
|
|
1305
|
+
fetch = ({ filters = {}, query = {}, routeParams = {} } = {}) => {
|
|
1306
|
+
this.#cache.clear();
|
|
1307
|
+
this.cached.set([]);
|
|
1308
|
+
return this.#fetchItems({ page: 0, filters, query, routeParams });
|
|
1309
|
+
};
|
|
1310
|
+
/**
|
|
1311
|
+
* Force reload current data.
|
|
1312
|
+
* Optional args merge into active filters/query.
|
|
1313
|
+
* Route params are intentionally not changed from `refresh`.
|
|
1314
|
+
*/
|
|
1315
|
+
refresh({ filters, query } = {}) {
|
|
1316
|
+
const nextFilters = filters == null ? this.filters : { ...this.filters, ...filters };
|
|
1317
|
+
const nextQuery = query == null ? this.query : { ...this.query, ...query };
|
|
1318
|
+
return this.#fetchItems({ filters: nextFilters, query: nextQuery });
|
|
1265
1319
|
}
|
|
1266
1320
|
/**
|
|
1267
1321
|
* Switch page with a request.
|
|
1268
|
-
* If cache is enabled and the page is present in LRU
|
|
1322
|
+
* If cache is enabled and the page is present in LRU — returns it from cache.
|
|
1269
1323
|
* @param page page index (0-based)
|
|
1270
1324
|
* @param ignoreCache ignore cache and fetch from network
|
|
1271
1325
|
*/
|
|
1272
|
-
updatePage = (page = this.page, ignoreCache = false) => {
|
|
1326
|
+
updatePage = (page = this.page, { ignoreCache = false } = {}) => {
|
|
1273
1327
|
if (this.config.hasCache && this.#cache.has(page) && !ignoreCache) {
|
|
1274
1328
|
const cached = this.#cache.get(page);
|
|
1275
1329
|
this.items.set(cached);
|
|
@@ -1285,54 +1339,23 @@ class PaginatedDataStore {
|
|
|
1285
1339
|
* @param size new size (rows per page)
|
|
1286
1340
|
*/
|
|
1287
1341
|
updatePageSize = (size = this.pageSize) => {
|
|
1288
|
-
return this.#fetchItems({ page: 0, size });
|
|
1289
|
-
};
|
|
1290
|
-
/**
|
|
1291
|
-
* Update filters (goes to the first page) and fetch.
|
|
1292
|
-
* The previous cache is cleared.
|
|
1293
|
-
*/
|
|
1294
|
-
updateFilters = (filters) => {
|
|
1295
1342
|
this.#cache.clear();
|
|
1296
1343
|
this.cached.set([]);
|
|
1297
|
-
return this.#fetchItems({ page: 0,
|
|
1344
|
+
return this.#fetchItems({ page: 0, size });
|
|
1298
1345
|
};
|
|
1299
1346
|
/**
|
|
1300
|
-
*
|
|
1301
|
-
* Supports `page/first/rows/sortField/sortOrder`.
|
|
1347
|
+
* Helper for offset-based table events (PrimeNG, etc.) with `page/first/rows`.
|
|
1302
1348
|
*/
|
|
1303
|
-
|
|
1349
|
+
updateByOffset = ({ page: pageNum, first = 0, rows = 0 } = {}, { query = this.query } = {}) => {
|
|
1304
1350
|
const page = (pageNum ?? (first && rows && Math.floor(first / rows))) || 0;
|
|
1305
|
-
const
|
|
1306
|
-
return this.#fetchItems({ page,
|
|
1307
|
-
};
|
|
1308
|
-
/**
|
|
1309
|
-
* Set filters from scratch (goes to the first page and resets sorting) and fetch.
|
|
1310
|
-
* Useful for quick presets.
|
|
1311
|
-
*/
|
|
1312
|
-
setFilters = (filters = {}) => {
|
|
1313
|
-
this.#cache.clear();
|
|
1314
|
-
this.cached.set([]);
|
|
1315
|
-
return this.#fetchItems({ page: 0, filters, sort: undefined });
|
|
1316
|
-
};
|
|
1317
|
-
/**
|
|
1318
|
-
* Change the resource route (resets page, cache, and presets) without fetching.
|
|
1319
|
-
* Useful when one store should work with different endpoints.
|
|
1320
|
-
*/
|
|
1321
|
-
updateRoute = (route) => {
|
|
1322
|
-
this.route = route;
|
|
1323
|
-
this.page = 0;
|
|
1324
|
-
this.pageSize = 20;
|
|
1325
|
-
this.totalElements = 0;
|
|
1326
|
-
this.#cache.clear();
|
|
1327
|
-
this.cached.set([]);
|
|
1328
|
-
this.initTransport();
|
|
1351
|
+
const size = rows || this.pageSize;
|
|
1352
|
+
return this.#fetchItems({ page, size, query });
|
|
1329
1353
|
};
|
|
1330
1354
|
/**
|
|
1331
1355
|
* Set route parameters (path variables) for the resource URL.
|
|
1332
|
-
* Does not trigger loading automatically
|
|
1356
|
+
* Does not trigger loading automatically - call `refresh()` or `updatePage()` after.
|
|
1333
1357
|
*
|
|
1334
1358
|
* @param params Dictionary of route parameters (e.g., `{ id: '123' }`)
|
|
1335
|
-
* @param opts Options object
|
|
1336
1359
|
* @param opts.reset If `true`, resets page to 0, clears cache, total elements count, and items
|
|
1337
1360
|
* @param opts.abort If `true`, aborts all active transport requests and sets loading to false
|
|
1338
1361
|
*
|
|
@@ -1345,20 +1368,20 @@ class PaginatedDataStore {
|
|
|
1345
1368
|
* store.setRouteParams({ userId: '42' }, { reset: false, abort: true });
|
|
1346
1369
|
* ```
|
|
1347
1370
|
*/
|
|
1348
|
-
setRouteParams = (params = {},
|
|
1371
|
+
setRouteParams = (params = {}, { reset = false, abort = false } = {}) => {
|
|
1349
1372
|
const isChanged = !deepEqual(this.routeParams, params);
|
|
1350
1373
|
if (!isChanged) {
|
|
1351
1374
|
return;
|
|
1352
1375
|
}
|
|
1353
1376
|
this.routeParams = params;
|
|
1354
|
-
if (
|
|
1377
|
+
if (reset) {
|
|
1355
1378
|
this.page = 0;
|
|
1356
1379
|
this.totalElements = 0;
|
|
1357
1380
|
this.#cache.clear();
|
|
1358
1381
|
this.cached.set([]);
|
|
1359
1382
|
this.items.set([]);
|
|
1360
1383
|
}
|
|
1361
|
-
if (
|
|
1384
|
+
if (abort) {
|
|
1362
1385
|
try {
|
|
1363
1386
|
this.#transport?.abortAll?.('Route params changed');
|
|
1364
1387
|
}
|
|
@@ -1379,14 +1402,14 @@ class PaginatedDataStore {
|
|
|
1379
1402
|
/**
|
|
1380
1403
|
* Copy configuration and presets from another store of the same type.
|
|
1381
1404
|
*/
|
|
1382
|
-
copy(
|
|
1383
|
-
this.applyConfig(
|
|
1405
|
+
copy(store) {
|
|
1406
|
+
this.applyConfig(store.config);
|
|
1384
1407
|
this.applyPresetMeta();
|
|
1385
1408
|
}
|
|
1386
1409
|
/** Clean up resources and cancel active requests. Automatically called onDestroy. */
|
|
1387
1410
|
destroy() {
|
|
1388
1411
|
try {
|
|
1389
|
-
this.#transport?.abortAll?.('
|
|
1412
|
+
this.#transport?.abortAll?.('PagedQueryStore destroyed');
|
|
1390
1413
|
}
|
|
1391
1414
|
catch (e) {
|
|
1392
1415
|
if (!isAbort(e)) {
|
|
@@ -1394,15 +1417,16 @@ class PaginatedDataStore {
|
|
|
1394
1417
|
}
|
|
1395
1418
|
}
|
|
1396
1419
|
}
|
|
1397
|
-
#fetchItems = async ({ page = this.page, size = this.pageSize,
|
|
1398
|
-
const
|
|
1420
|
+
#fetchItems = async ({ page = this.page, size = this.pageSize, filters = this.filters, query = this.query, routeParams = this.routeParams, }) => {
|
|
1421
|
+
const builtQuery = this.parseQuery({ page, size, filters, query });
|
|
1399
1422
|
this.loading.set(true);
|
|
1423
|
+
this.routeParams = routeParams;
|
|
1400
1424
|
this.#transport.abortAll();
|
|
1401
1425
|
try {
|
|
1402
|
-
const response = await this.runTransport(filters,
|
|
1426
|
+
const response = await this.runTransport(filters, builtQuery, routeParams);
|
|
1403
1427
|
this.page = page;
|
|
1404
|
-
this.sort = sort;
|
|
1405
1428
|
this.filters = filters;
|
|
1429
|
+
this.query = query;
|
|
1406
1430
|
const parsed = await this.parseResponseData(response);
|
|
1407
1431
|
this.pageSize = parsed.pageable?.pageSize || size;
|
|
1408
1432
|
this.totalElements = parsed.totalElements;
|
|
@@ -1424,12 +1448,11 @@ class PaginatedDataStore {
|
|
|
1424
1448
|
this.#transport = new ResourceStore({ [this.config.method || 'GET']: this.route }, {
|
|
1425
1449
|
delay: this.config.debounceTime,
|
|
1426
1450
|
delayMode: 'debounce',
|
|
1427
|
-
presetQueries: { page: this.page, size: this.pageSize
|
|
1451
|
+
presetQueries: { page: this.page, size: this.pageSize },
|
|
1428
1452
|
presetPayload: this.filters,
|
|
1429
1453
|
});
|
|
1430
1454
|
}
|
|
1431
|
-
async runTransport(payload, query) {
|
|
1432
|
-
const params = this.routeParams;
|
|
1455
|
+
async runTransport(payload, query, params) {
|
|
1433
1456
|
if (this.config.method === 'GET') {
|
|
1434
1457
|
return this.#transport.get({ query, params }, { promote: false, dedupe: true });
|
|
1435
1458
|
}
|
|
@@ -1437,10 +1460,16 @@ class PaginatedDataStore {
|
|
|
1437
1460
|
// @ts-ignore
|
|
1438
1461
|
return this.#transport[method]({ query, payload, params }, { promote: false, dedupe: true });
|
|
1439
1462
|
}
|
|
1440
|
-
parseQuery({ page = 0, size,
|
|
1463
|
+
parseQuery({ page = 0, size, filters, query = {} }) {
|
|
1441
1464
|
const method = this.config.method || 'GET';
|
|
1442
|
-
const requestPayload = {
|
|
1443
|
-
|
|
1465
|
+
const requestPayload = {
|
|
1466
|
+
page,
|
|
1467
|
+
size,
|
|
1468
|
+
...filters,
|
|
1469
|
+
...query,
|
|
1470
|
+
};
|
|
1471
|
+
const fallbackQuery = method === 'GET' ? requestPayload : { page, size, ...query };
|
|
1472
|
+
const rawQueries = this.config.parseRequest?.(requestPayload) || fallbackQuery;
|
|
1444
1473
|
const queries = {};
|
|
1445
1474
|
Object.entries(rawQueries).forEach(([key, value]) => {
|
|
1446
1475
|
if (Array.isArray(value)) {
|
|
@@ -1450,7 +1479,6 @@ class PaginatedDataStore {
|
|
|
1450
1479
|
queries[key] = value;
|
|
1451
1480
|
}
|
|
1452
1481
|
});
|
|
1453
|
-
sort && (queries['sort'] = sort);
|
|
1454
1482
|
return queries;
|
|
1455
1483
|
}
|
|
1456
1484
|
parseResponseData = async (data) => {
|
|
@@ -1496,7 +1524,6 @@ class PaginatedDataStore {
|
|
|
1496
1524
|
this.filters = this.config.presetFilters || {};
|
|
1497
1525
|
this.pageSize = this.config.presetQuery?.pageSize || 20;
|
|
1498
1526
|
this.page = this.config.presetQuery?.page || 0;
|
|
1499
|
-
this.sort = this.config.presetQuery?.sort;
|
|
1500
1527
|
}
|
|
1501
1528
|
}
|
|
1502
1529
|
|
|
@@ -1508,7 +1535,7 @@ var _a;
|
|
|
1508
1535
|
* - reactive `items` (current list) and `options` (label/value),
|
|
1509
1536
|
* - local cache filtering (`fixed: true`) or server-side search by name (`fixed: false`),
|
|
1510
1537
|
* - preload and restore cache from `storage` (`localStorage/session/LRU`),
|
|
1511
|
-
* - smooth integration with `
|
|
1538
|
+
* - smooth integration with `PagedQueryStore` for server fetching.
|
|
1512
1539
|
*
|
|
1513
1540
|
* Example:
|
|
1514
1541
|
* ```ts
|
|
@@ -1548,7 +1575,7 @@ class DictStore {
|
|
|
1548
1575
|
cachedItems = signal([], ...(ngDevMode ? [{ debugName: "cachedItems" }] : []));
|
|
1549
1576
|
/**
|
|
1550
1577
|
* Current list of dictionary items.
|
|
1551
|
-
* Source
|
|
1578
|
+
* Source — local cache (fixed=true) or data from `PagedQueryStore`.
|
|
1552
1579
|
*/
|
|
1553
1580
|
items = computed(() => {
|
|
1554
1581
|
const cached = this.cachedItems();
|
|
@@ -1578,7 +1605,7 @@ class DictStore {
|
|
|
1578
1605
|
this.storageKey = storageKey;
|
|
1579
1606
|
const searchDebounce = debounceTime ?? 300;
|
|
1580
1607
|
this.debouncedSearchText = debounceSignal(this.searchText, searchDebounce);
|
|
1581
|
-
this.#helper = new
|
|
1608
|
+
this.#helper = new PagedQueryStore(this.apiUrl, {
|
|
1582
1609
|
method: method,
|
|
1583
1610
|
hasCache: false,
|
|
1584
1611
|
presetFilters: { name: '', ...presetFilters },
|
|
@@ -1611,12 +1638,12 @@ class DictStore {
|
|
|
1611
1638
|
if (!this.fixed) {
|
|
1612
1639
|
const query = this.debouncedSearchText().trim();
|
|
1613
1640
|
untracked(() => {
|
|
1614
|
-
this._lastPromise = this.#helper.
|
|
1641
|
+
this._lastPromise = this.#helper.fetch({ filters: { name: query, ...rest } });
|
|
1615
1642
|
});
|
|
1616
1643
|
}
|
|
1617
1644
|
else if (!this.cachedItems().length) {
|
|
1618
1645
|
untracked(() => {
|
|
1619
|
-
this._lastPromise = this.#helper.
|
|
1646
|
+
this._lastPromise = this.#helper.fetch({ filters: { name: '', ...rest } });
|
|
1620
1647
|
});
|
|
1621
1648
|
}
|
|
1622
1649
|
}));
|
|
@@ -1627,7 +1654,7 @@ class DictStore {
|
|
|
1627
1654
|
}
|
|
1628
1655
|
/**
|
|
1629
1656
|
* Set a search query and filters.
|
|
1630
|
-
* With `fixed: false` initiates server search; with `fixed: true`
|
|
1657
|
+
* With `fixed: false` initiates server search; with `fixed: true` — local filtering.
|
|
1631
1658
|
*/
|
|
1632
1659
|
search = (name = '', filters = {}) => {
|
|
1633
1660
|
this._armed.set(true);
|
|
@@ -2004,5 +2031,5 @@ class EntityStore {
|
|
|
2004
2031
|
* Generated bundle index. Do not edit.
|
|
2005
2032
|
*/
|
|
2006
2033
|
|
|
2007
|
-
export { AbortError, CacheMissError, DictLocalStore, DictStore, EntityStore, LruCache,
|
|
2034
|
+
export { AbortError, CacheMissError, DictLocalStore, DictStore, EntityStore, LruCache, PagedQueryStore, RESOURCE_PROFILES, ResourceStore, STATUM_CONFIG, Serializer, SerializerFieldError, createBodySerializer, createQuerySerializer, createResourceProfile, createStrictSerializer, isAbort, provideStatum, storageStrategy };
|
|
2008
2035
|
//# sourceMappingURL=reforgium-statum.mjs.map
|
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "
|
|
2
|
+
"version": "3.0.0-rc.0",
|
|
3
3
|
"name": "@reforgium/statum",
|
|
4
4
|
"description": "reforgium State modules",
|
|
5
5
|
"author": "rtommievich",
|
|
@@ -32,6 +32,7 @@
|
|
|
32
32
|
"types/*.d.ts",
|
|
33
33
|
"package.json",
|
|
34
34
|
"README.md",
|
|
35
|
+
"MIGRATION.md",
|
|
35
36
|
"CHANGELOG.md",
|
|
36
37
|
"LICENSE*"
|
|
37
38
|
],
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { AnyType, AnyDict, RestMethods, PageableRequest,
|
|
1
|
+
import { AnyType, AnyDict, RestMethods, PageableRequest, PageableResponse } from '@reforgium/internal';
|
|
2
2
|
import * as _angular_core from '@angular/core';
|
|
3
|
-
import { Signal, WritableSignal, InjectionToken } from '@angular/core';
|
|
3
|
+
import { Signal, WritableSignal, EnvironmentProviders, InjectionToken } from '@angular/core';
|
|
4
4
|
import * as _reforgium_statum from '@reforgium/statum';
|
|
5
5
|
|
|
6
6
|
/**
|
|
@@ -534,6 +534,29 @@ declare class ResourceStore<Data> {
|
|
|
534
534
|
private promoteCurrent;
|
|
535
535
|
}
|
|
536
536
|
|
|
537
|
+
declare const RESOURCE_PROFILES: {
|
|
538
|
+
readonly table: {
|
|
539
|
+
readonly ttlMs: 15000;
|
|
540
|
+
readonly delay: 120;
|
|
541
|
+
readonly delayMode: "debounce";
|
|
542
|
+
readonly maxEntries: 500;
|
|
543
|
+
};
|
|
544
|
+
readonly lookup: {
|
|
545
|
+
readonly ttlMs: 60000;
|
|
546
|
+
readonly delay: 200;
|
|
547
|
+
readonly delayMode: "debounce";
|
|
548
|
+
readonly maxEntries: 300;
|
|
549
|
+
};
|
|
550
|
+
readonly mutation: {
|
|
551
|
+
readonly ttlMs: 0;
|
|
552
|
+
readonly delay: 0;
|
|
553
|
+
readonly delayMode: "throttle";
|
|
554
|
+
readonly maxEntries: 50;
|
|
555
|
+
};
|
|
556
|
+
};
|
|
557
|
+
type ResourceProfileName = keyof typeof RESOURCE_PROFILES;
|
|
558
|
+
declare const createResourceProfile: (profile: ResourceProfileName, overrides?: ResourceStoreOptions) => ResourceStoreOptions;
|
|
559
|
+
|
|
537
560
|
/**
|
|
538
561
|
* Error thrown when requested data is missing in the cache.
|
|
539
562
|
*
|
|
@@ -576,7 +599,7 @@ declare function isAbort(e: unknown): e is AbortError;
|
|
|
576
599
|
* Controls request method, page cache, debounce delay, and
|
|
577
600
|
* request/response transformations.
|
|
578
601
|
*/
|
|
579
|
-
type
|
|
602
|
+
type PagedQueryStoreConfig<ItemsType extends object, FilterType = unknown> = {
|
|
580
603
|
/** Transport HTTP method: `GET`/`POST`/`PATCH`/`PUT`/`DELETE`. Defaults to global config or `POST`. */
|
|
581
604
|
method?: RestMethods;
|
|
582
605
|
/** Enable LRU cache for pages. */
|
|
@@ -585,19 +608,19 @@ type PaginatedDataStoreConfig<ItemsType extends object, FilterType = unknown> =
|
|
|
585
608
|
cacheSize?: number;
|
|
586
609
|
/** Debounce delay before request (ms). Useful for frequent filter changes. */
|
|
587
610
|
debounceTime?: number;
|
|
588
|
-
/** Initial pagination
|
|
611
|
+
/** Initial pagination params. `page` is required. */
|
|
589
612
|
presetQuery?: {
|
|
590
613
|
page: number;
|
|
591
614
|
pageSize?: number;
|
|
592
|
-
sort?: string;
|
|
593
615
|
};
|
|
594
616
|
/** Initial filters. Will be sent with the first request. */
|
|
595
617
|
presetFilters?: Partial<FilterType>;
|
|
596
618
|
/**
|
|
597
619
|
* Custom transformation of request data into a query object.
|
|
598
|
-
* Useful for mapping `page/pageSize
|
|
620
|
+
* Useful for mapping `page/pageSize` and selected filter fields в†’ API-specific query keys.
|
|
621
|
+
* Returned object can contain nullable values; they are filtered before the transport call.
|
|
599
622
|
*/
|
|
600
|
-
parseRequest?: (data: PageableRequest) =>
|
|
623
|
+
parseRequest?: (data: PageableRequest & Partial<FilterType> & AnyDict) => AnyDict;
|
|
601
624
|
/**
|
|
602
625
|
* Custom parser of API response into unified `PageableResponse<ItemsType>`.
|
|
603
626
|
* Use if the server returns an array or a "non-standard" structure.
|
|
@@ -605,60 +628,77 @@ type PaginatedDataStoreConfig<ItemsType extends object, FilterType = unknown> =
|
|
|
605
628
|
parseResponse?: (data: AnyType) => PageableResponse<ItemsType> | Promise<PageableResponse<ItemsType>>;
|
|
606
629
|
};
|
|
607
630
|
/**
|
|
608
|
-
* Global defaults for `
|
|
631
|
+
* Global defaults for `PagedQueryStore`.
|
|
609
632
|
* Can be provided via DI to avoid duplicating config in each store.
|
|
610
633
|
*/
|
|
611
|
-
type
|
|
634
|
+
type PagedQueryStoreProviderConfig = {
|
|
612
635
|
/** Default method for all stores (if not overridden locally). */
|
|
613
636
|
defaultMethod?: RestMethods;
|
|
614
|
-
/** Default base `page/pageSize
|
|
615
|
-
defaultQuery?:
|
|
616
|
-
/** Global `parseRequest`
|
|
617
|
-
defaultParseRequest?:
|
|
637
|
+
/** Default base `page/pageSize`. */
|
|
638
|
+
defaultQuery?: PagedQueryStoreConfig<object>['presetQuery'];
|
|
639
|
+
/** Global `parseRequest` — maps pagination into a query object. */
|
|
640
|
+
defaultParseRequest?: PagedQueryStoreConfig<object>['parseRequest'];
|
|
618
641
|
/** Whether to enable page cache by default. */
|
|
619
642
|
defaultHasCache?: boolean;
|
|
620
643
|
/** Default LRU page cache size. */
|
|
621
644
|
defaultCacheSize?: number;
|
|
622
645
|
};
|
|
623
646
|
|
|
624
|
-
type
|
|
647
|
+
type OffsetPaginationType = {
|
|
625
648
|
page?: number;
|
|
626
649
|
first?: number | null;
|
|
627
650
|
rows?: number | null;
|
|
628
|
-
|
|
629
|
-
|
|
651
|
+
};
|
|
652
|
+
type FetchInput<FilterType> = {
|
|
653
|
+
filters?: Partial<FilterType>;
|
|
654
|
+
query?: AnyDict;
|
|
655
|
+
routeParams?: AnyDict;
|
|
656
|
+
};
|
|
657
|
+
type RefreshInput<FilterType> = {
|
|
658
|
+
filters?: Partial<FilterType>;
|
|
659
|
+
query?: AnyDict;
|
|
660
|
+
};
|
|
661
|
+
type UpdatePageOptions = {
|
|
662
|
+
ignoreCache?: boolean;
|
|
663
|
+
};
|
|
664
|
+
type UpdateByOffsetOptions = {
|
|
665
|
+
query?: AnyDict;
|
|
666
|
+
};
|
|
667
|
+
type SetRouteParamsOptions = {
|
|
668
|
+
reset?: boolean;
|
|
669
|
+
abort?: boolean;
|
|
630
670
|
};
|
|
631
671
|
/**
|
|
632
672
|
* Store for paginated data (tables/lists) with per-page cache and unified requests.
|
|
633
673
|
*
|
|
634
674
|
* Provides:
|
|
635
675
|
* - reactive signals: `items`, `loading`, `cached`;
|
|
636
|
-
* - methods to control page/size/
|
|
676
|
+
* - methods to control page/size/query;
|
|
637
677
|
* - optional LRU cache by pages;
|
|
638
|
-
* - configurable transport (GET/POST/PATCH
|
|
678
|
+
* - configurable transport (GET/POST/PATCH/…).
|
|
639
679
|
*
|
|
640
680
|
* Example:
|
|
641
681
|
* ```ts
|
|
642
|
-
* const ds = new
|
|
682
|
+
* const ds = new PagedQueryStore<User>('/users', { method: 'GET', hasCache: true });
|
|
643
683
|
* await ds.updatePage(0); // load the first page
|
|
644
684
|
* effect(() => console.log(ds.items(), ds.loading()));
|
|
645
685
|
* ```
|
|
646
686
|
*/
|
|
647
|
-
declare class
|
|
687
|
+
declare class PagedQueryStore<ItemsType extends object, FilterType = unknown> {
|
|
648
688
|
#private;
|
|
649
689
|
private route;
|
|
650
|
-
config:
|
|
690
|
+
config: PagedQueryStoreConfig<ItemsType, FilterType>;
|
|
651
691
|
private readonly defaultConfig;
|
|
652
692
|
/** Current page data (reactive). */
|
|
653
693
|
items: WritableSignal<ItemsType[]>;
|
|
654
|
-
/** Merged cache of pages (flat list)
|
|
694
|
+
/** Merged cache of pages (flat list) — handy for search/export. */
|
|
655
695
|
cached: WritableSignal<ItemsType[]>;
|
|
656
696
|
/** Loading flag of the current operation. */
|
|
657
697
|
loading: WritableSignal<boolean>;
|
|
658
698
|
/** Current filters (applied to requests). */
|
|
659
699
|
filters: Partial<FilterType>;
|
|
660
|
-
/**
|
|
661
|
-
|
|
700
|
+
/** Additional query params sent to transport requests. */
|
|
701
|
+
query: AnyDict;
|
|
662
702
|
/** Current page index (0-based). */
|
|
663
703
|
page: number;
|
|
664
704
|
/** Default page size. */
|
|
@@ -670,47 +710,39 @@ declare class PaginatedDataStore<ItemsType extends object, FilterType = unknown>
|
|
|
670
710
|
* @param route Resource URL pattern (e.g., `'/users'`)
|
|
671
711
|
* @param config Store behavior: method, cache, request/response parsers, debounce, presets, etc.
|
|
672
712
|
*/
|
|
673
|
-
constructor(route: string, config?:
|
|
674
|
-
/**
|
|
675
|
-
|
|
713
|
+
constructor(route: string, config?: PagedQueryStoreConfig<ItemsType, FilterType>);
|
|
714
|
+
/**
|
|
715
|
+
* Fetch data with explicit filters and query params from the first page.
|
|
716
|
+
* Replaces legacy `setFilters`.
|
|
717
|
+
*/
|
|
718
|
+
fetch: ({ filters, query, routeParams }?: FetchInput<FilterType>) => Promise<ItemsType[] | undefined>;
|
|
719
|
+
/**
|
|
720
|
+
* Force reload current data.
|
|
721
|
+
* Optional args merge into active filters/query.
|
|
722
|
+
* Route params are intentionally not changed from `refresh`.
|
|
723
|
+
*/
|
|
724
|
+
refresh({ filters, query }?: RefreshInput<FilterType>): Promise<ItemsType[] | undefined>;
|
|
676
725
|
/**
|
|
677
726
|
* Switch page with a request.
|
|
678
|
-
* If cache is enabled and the page is present in LRU
|
|
727
|
+
* If cache is enabled and the page is present in LRU — returns it from cache.
|
|
679
728
|
* @param page page index (0-based)
|
|
680
729
|
* @param ignoreCache ignore cache and fetch from network
|
|
681
730
|
*/
|
|
682
|
-
updatePage: (page?: number, ignoreCache?:
|
|
731
|
+
updatePage: (page?: number, { ignoreCache }?: UpdatePageOptions) => Promise<ItemsType[] | undefined>;
|
|
683
732
|
/**
|
|
684
733
|
* Change page size (will go to the first page) and fetch.
|
|
685
734
|
* @param size new size (rows per page)
|
|
686
735
|
*/
|
|
687
736
|
updatePageSize: (size?: number) => Promise<ItemsType[] | undefined>;
|
|
688
737
|
/**
|
|
689
|
-
*
|
|
690
|
-
* The previous cache is cleared.
|
|
691
|
-
*/
|
|
692
|
-
updateFilters: (filters: Partial<FilterType>) => Promise<ItemsType[] | undefined>;
|
|
693
|
-
/**
|
|
694
|
-
* Update the state from table events (PrimeNG, etc.) and fetch.
|
|
695
|
-
* Supports `page/first/rows/sortField/sortOrder`.
|
|
738
|
+
* Helper for offset-based table events (PrimeNG, etc.) with `page/first/rows`.
|
|
696
739
|
*/
|
|
697
|
-
|
|
698
|
-
/**
|
|
699
|
-
* Set filters from scratch (goes to the first page and resets sorting) and fetch.
|
|
700
|
-
* Useful for quick presets.
|
|
701
|
-
*/
|
|
702
|
-
setFilters: (filters?: Partial<FilterType>) => Promise<ItemsType[] | undefined>;
|
|
703
|
-
/**
|
|
704
|
-
* Change the resource route (resets page, cache, and presets) without fetching.
|
|
705
|
-
* Useful when one store should work with different endpoints.
|
|
706
|
-
*/
|
|
707
|
-
updateRoute: (route: string) => void;
|
|
740
|
+
updateByOffset: ({ page: pageNum, first, rows }?: OffsetPaginationType, { query }?: UpdateByOffsetOptions) => Promise<ItemsType[] | undefined>;
|
|
708
741
|
/**
|
|
709
742
|
* Set route parameters (path variables) for the resource URL.
|
|
710
|
-
* Does not trigger loading automatically
|
|
743
|
+
* Does not trigger loading automatically - call `refresh()` or `updatePage()` after.
|
|
711
744
|
*
|
|
712
745
|
* @param params Dictionary of route parameters (e.g., `{ id: '123' }`)
|
|
713
|
-
* @param opts Options object
|
|
714
746
|
* @param opts.reset If `true`, resets page to 0, clears cache, total elements count, and items
|
|
715
747
|
* @param opts.abort If `true`, aborts all active transport requests and sets loading to false
|
|
716
748
|
*
|
|
@@ -723,19 +755,16 @@ declare class PaginatedDataStore<ItemsType extends object, FilterType = unknown>
|
|
|
723
755
|
* store.setRouteParams({ userId: '42' }, { reset: false, abort: true });
|
|
724
756
|
* ```
|
|
725
757
|
*/
|
|
726
|
-
setRouteParams: (params?: AnyDict,
|
|
727
|
-
reset?: boolean;
|
|
728
|
-
abort?: boolean;
|
|
729
|
-
}) => void;
|
|
758
|
+
setRouteParams: (params?: AnyDict, { reset, abort }?: SetRouteParamsOptions) => void;
|
|
730
759
|
/**
|
|
731
760
|
* Update store config on the fly (without re-creation).
|
|
732
761
|
* Does not trigger loading automatically.
|
|
733
762
|
*/
|
|
734
|
-
updateConfig: (config:
|
|
763
|
+
updateConfig: (config: PagedQueryStoreConfig<ItemsType, FilterType>) => void;
|
|
735
764
|
/**
|
|
736
765
|
* Copy configuration and presets from another store of the same type.
|
|
737
766
|
*/
|
|
738
|
-
copy(
|
|
767
|
+
copy(store: PagedQueryStore<ItemsType, FilterType>): void;
|
|
739
768
|
/** Clean up resources and cancel active requests. Automatically called onDestroy. */
|
|
740
769
|
destroy(): void;
|
|
741
770
|
private initTransport;
|
|
@@ -856,7 +885,7 @@ type ValueType = string[] | string | number | null | undefined;
|
|
|
856
885
|
* - reactive `items` (current list) and `options` (label/value),
|
|
857
886
|
* - local cache filtering (`fixed: true`) or server-side search by name (`fixed: false`),
|
|
858
887
|
* - preload and restore cache from `storage` (`localStorage/session/LRU`),
|
|
859
|
-
* - smooth integration with `
|
|
888
|
+
* - smooth integration with `PagedQueryStore` for server fetching.
|
|
860
889
|
*
|
|
861
890
|
* Example:
|
|
862
891
|
* ```ts
|
|
@@ -894,7 +923,7 @@ declare class DictStore<Type extends AnyDict> {
|
|
|
894
923
|
private cachedItems;
|
|
895
924
|
/**
|
|
896
925
|
* Current list of dictionary items.
|
|
897
|
-
* Source
|
|
926
|
+
* Source — local cache (fixed=true) or data from `PagedQueryStore`.
|
|
898
927
|
*/
|
|
899
928
|
items: Signal<readonly Type[]>;
|
|
900
929
|
/**
|
|
@@ -917,7 +946,7 @@ declare class DictStore<Type extends AnyDict> {
|
|
|
917
946
|
restoreCache(): void;
|
|
918
947
|
/**
|
|
919
948
|
* Set a search query and filters.
|
|
920
|
-
* With `fixed: false` initiates server search; with `fixed: true`
|
|
949
|
+
* With `fixed: false` initiates server search; with `fixed: true` — local filtering.
|
|
921
950
|
*/
|
|
922
951
|
search: (name?: string, filters?: AnyDict) => void;
|
|
923
952
|
/**
|
|
@@ -1050,8 +1079,8 @@ declare class EntityStore<Entity extends AnyDict, IdKey extends keyof Entity = k
|
|
|
1050
1079
|
private isValidId;
|
|
1051
1080
|
}
|
|
1052
1081
|
|
|
1053
|
-
type
|
|
1054
|
-
|
|
1082
|
+
type PagedQueryProviderConfig = {
|
|
1083
|
+
pagedQuery?: PagedQueryStoreProviderConfig;
|
|
1055
1084
|
};
|
|
1056
1085
|
type SerializerProviderConfig = {
|
|
1057
1086
|
serializer?: Partial<SerializerConfig>;
|
|
@@ -1059,9 +1088,10 @@ type SerializerProviderConfig = {
|
|
|
1059
1088
|
type DictProviderConfig = {
|
|
1060
1089
|
dict?: DictStoreProviderConfig;
|
|
1061
1090
|
};
|
|
1062
|
-
type StatumConfig =
|
|
1091
|
+
type StatumConfig = PagedQueryProviderConfig & SerializerProviderConfig & DictProviderConfig;
|
|
1063
1092
|
declare const STATUM_CONFIG: InjectionToken<StatumConfig>;
|
|
1093
|
+
declare const provideStatum: (config: StatumConfig) => EnvironmentProviders;
|
|
1064
1094
|
|
|
1065
|
-
export { AbortError, CacheMissError, DictLocalStore, DictStore, EntityStore, LruCache,
|
|
1066
|
-
export type { DataType, DictLocalConfig, DictStoreConfig, DictStoreProviderConfig, EntityId, EntityStoreConfig, FieldConfig,
|
|
1095
|
+
export { AbortError, CacheMissError, DictLocalStore, DictStore, EntityStore, LruCache, PagedQueryStore, RESOURCE_PROFILES, ResourceStore, STATUM_CONFIG, Serializer, SerializerFieldError, createBodySerializer, createQuerySerializer, createResourceProfile, createStrictSerializer, isAbort, provideStatum, storageStrategy };
|
|
1096
|
+
export type { DataType, DictLocalConfig, DictStoreConfig, DictStoreProviderConfig, EntityId, EntityStoreConfig, FieldConfig, PagedQueryStoreConfig, PagedQueryStoreProviderConfig, ResourceProfileName, ResourceRoutesMap, ResourceStatus, ResourceStoreOptions, ResourceTraceEvent, RetryConfig, SerializedType, SerializerConfig, StatumConfig, StorageInterface, StorageStrategy, StorageStrategyOptions, Types };
|
|
1067
1097
|
//# sourceMappingURL=reforgium-statum.d.ts.map
|