@reforgium/statum 2.1.2 → 2.2.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 +15 -16
- package/fesm2022/reforgium-statum.mjs +12 -18
- package/package.json +1 -1
- package/types/reforgium-statum.d.ts +10 -15
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)
|
|
@@ -181,7 +181,7 @@ entities.removeOne(1);
|
|
|
181
181
|
|
|
182
182
|
## PaginatedDataStore
|
|
183
183
|
|
|
184
|
-
Lightweight store for server-side pagination
|
|
184
|
+
Lightweight store for server-side pagination, filtering, and page cache.
|
|
185
185
|
|
|
186
186
|
### When to use
|
|
187
187
|
|
|
@@ -201,23 +201,22 @@ Lightweight store for server-side pagination with sorting, filtering, and page c
|
|
|
201
201
|
| pageSize | `number` | Page size |
|
|
202
202
|
| totalElements | `number` | Total items on server |
|
|
203
203
|
| filters | `Partial<F>` | Active filters |
|
|
204
|
-
| sort | `string \| undefined` | Sort as `"field,asc"` / `"field,desc"` |
|
|
205
204
|
|
|
206
205
|
### Methods
|
|
207
206
|
|
|
208
|
-
| Method | Description
|
|
209
|
-
|
|
210
|
-
| refresh | Repeat request with current params
|
|
211
|
-
| updatePage | Change page (can use cache)
|
|
212
|
-
| updatePageSize | Change page size (can use cache)
|
|
213
|
-
| updateFilters | Merge filters, reset cache, go to page 0
|
|
214
|
-
| setFilters | Replace filters, reset cache
|
|
215
|
-
| updateQuery | Map table events to `page
|
|
216
|
-
| updateRoute | Change endpoint, reset meta/cache
|
|
217
|
-
| setRouteParams | Fill route url with params
|
|
218
|
-
| updateConfig | Patch config and apply presets
|
|
219
|
-
| copy | Copy config/meta from another store
|
|
220
|
-
| destroy | Manual destroying of caches and abort requests
|
|
207
|
+
| Method | Description |
|
|
208
|
+
|----------------|------------------------------------------------|
|
|
209
|
+
| refresh | Repeat request with current params |
|
|
210
|
+
| updatePage | Change page (can use cache) |
|
|
211
|
+
| updatePageSize | Change page size (can use cache) |
|
|
212
|
+
| updateFilters | Merge filters, reset cache, go to page 0 |
|
|
213
|
+
| setFilters | Replace filters, reset cache, go to page 0 |
|
|
214
|
+
| updateQuery | Map table events to `page` |
|
|
215
|
+
| updateRoute | Change endpoint, reset meta/cache |
|
|
216
|
+
| setRouteParams | Fill route url with params |
|
|
217
|
+
| updateConfig | Patch config and apply presets |
|
|
218
|
+
| copy | Copy config/meta from another store |
|
|
219
|
+
| destroy | Manual destroying of caches and abort requests |
|
|
221
220
|
|
|
222
221
|
Example:
|
|
223
222
|
|
|
@@ -1225,7 +1225,7 @@ class ResourceStore {
|
|
|
1225
1225
|
*
|
|
1226
1226
|
* Provides:
|
|
1227
1227
|
* - reactive signals: `items`, `loading`, `cached`;
|
|
1228
|
-
* - methods to control page/size/filters
|
|
1228
|
+
* - methods to control page/size/filters;
|
|
1229
1229
|
* - optional LRU cache by pages;
|
|
1230
1230
|
* - configurable transport (GET/POST/PATCH/…).
|
|
1231
1231
|
*
|
|
@@ -1250,8 +1250,6 @@ class PaginatedDataStore {
|
|
|
1250
1250
|
loading = signal(false, ...(ngDevMode ? [{ debugName: "loading" }] : []));
|
|
1251
1251
|
/** Current filters (applied to requests). */
|
|
1252
1252
|
filters = {};
|
|
1253
|
-
/** Current sorting (`field,asc|desc`). */
|
|
1254
|
-
sort;
|
|
1255
1253
|
/** Current page index (0-based). */
|
|
1256
1254
|
page = 0;
|
|
1257
1255
|
/** Default page size. */
|
|
@@ -1272,7 +1270,7 @@ class PaginatedDataStore {
|
|
|
1272
1270
|
this.initTransport();
|
|
1273
1271
|
inject(DestroyRef).onDestroy(() => this.destroy());
|
|
1274
1272
|
}
|
|
1275
|
-
/** Force reload current data (with the same page/filters
|
|
1273
|
+
/** Force reload current data (with the same page/filters). */
|
|
1276
1274
|
refresh() {
|
|
1277
1275
|
return this.#fetchItems({});
|
|
1278
1276
|
}
|
|
@@ -1311,21 +1309,20 @@ class PaginatedDataStore {
|
|
|
1311
1309
|
};
|
|
1312
1310
|
/**
|
|
1313
1311
|
* Update the state from table events (PrimeNG, etc.) and fetch.
|
|
1314
|
-
* Supports `page/first/rows
|
|
1312
|
+
* Supports `page/first/rows`.
|
|
1315
1313
|
*/
|
|
1316
|
-
updateQuery = ({ page: pageNum, first = 0, rows = 0
|
|
1314
|
+
updateQuery = ({ page: pageNum, first = 0, rows = 0 }) => {
|
|
1317
1315
|
const page = (pageNum ?? (first && rows && Math.floor(first / rows))) || 0;
|
|
1318
|
-
|
|
1319
|
-
return this.#fetchItems({ page, sort });
|
|
1316
|
+
return this.#fetchItems({ page });
|
|
1320
1317
|
};
|
|
1321
1318
|
/**
|
|
1322
|
-
* Set filters from scratch (goes to the first page
|
|
1319
|
+
* Set filters from scratch (goes to the first page) and fetch.
|
|
1323
1320
|
* Useful for quick presets.
|
|
1324
1321
|
*/
|
|
1325
1322
|
setFilters = (filters = {}) => {
|
|
1326
1323
|
this.#cache.clear();
|
|
1327
1324
|
this.cached.set([]);
|
|
1328
|
-
return this.#fetchItems({ page: 0, filters
|
|
1325
|
+
return this.#fetchItems({ page: 0, filters });
|
|
1329
1326
|
};
|
|
1330
1327
|
/**
|
|
1331
1328
|
* Change the resource route (resets page, cache, and presets) without fetching.
|
|
@@ -1407,14 +1404,13 @@ class PaginatedDataStore {
|
|
|
1407
1404
|
}
|
|
1408
1405
|
}
|
|
1409
1406
|
}
|
|
1410
|
-
#fetchItems = async ({ page = this.page, size = this.pageSize,
|
|
1411
|
-
const query = this.parseQuery({ page, size,
|
|
1407
|
+
#fetchItems = async ({ page = this.page, size = this.pageSize, filters = this.filters }) => {
|
|
1408
|
+
const query = this.parseQuery({ page, size, filters });
|
|
1412
1409
|
this.loading.set(true);
|
|
1413
1410
|
this.#transport.abortAll();
|
|
1414
1411
|
try {
|
|
1415
1412
|
const response = await this.runTransport(filters, query);
|
|
1416
1413
|
this.page = page;
|
|
1417
|
-
this.sort = sort;
|
|
1418
1414
|
this.filters = filters;
|
|
1419
1415
|
const parsed = await this.parseResponseData(response);
|
|
1420
1416
|
this.pageSize = parsed.pageable?.pageSize || size;
|
|
@@ -1437,7 +1433,7 @@ class PaginatedDataStore {
|
|
|
1437
1433
|
this.#transport = new ResourceStore({ [this.config.method || 'GET']: this.route }, {
|
|
1438
1434
|
delay: this.config.debounceTime,
|
|
1439
1435
|
delayMode: 'debounce',
|
|
1440
|
-
presetQueries: { page: this.page, size: this.pageSize
|
|
1436
|
+
presetQueries: { page: this.page, size: this.pageSize },
|
|
1441
1437
|
presetPayload: this.filters,
|
|
1442
1438
|
});
|
|
1443
1439
|
}
|
|
@@ -1450,10 +1446,10 @@ class PaginatedDataStore {
|
|
|
1450
1446
|
// @ts-ignore
|
|
1451
1447
|
return this.#transport[method]({ query, payload, params }, { promote: false, dedupe: true });
|
|
1452
1448
|
}
|
|
1453
|
-
parseQuery({ page = 0, size,
|
|
1449
|
+
parseQuery({ page = 0, size, filters }) {
|
|
1454
1450
|
const method = this.config.method || 'GET';
|
|
1455
1451
|
const requestPayload = { page, size, ...(method === 'GET' ? filters : {}) };
|
|
1456
|
-
const rawQueries = this.config.parseRequest?.({ ...requestPayload
|
|
1452
|
+
const rawQueries = this.config.parseRequest?.({ ...requestPayload }) || requestPayload;
|
|
1457
1453
|
const queries = {};
|
|
1458
1454
|
Object.entries(rawQueries).forEach(([key, value]) => {
|
|
1459
1455
|
if (Array.isArray(value)) {
|
|
@@ -1463,7 +1459,6 @@ class PaginatedDataStore {
|
|
|
1463
1459
|
queries[key] = value;
|
|
1464
1460
|
}
|
|
1465
1461
|
});
|
|
1466
|
-
sort && (queries['sort'] = sort);
|
|
1467
1462
|
return queries;
|
|
1468
1463
|
}
|
|
1469
1464
|
parseResponseData = async (data) => {
|
|
@@ -1509,7 +1504,6 @@ class PaginatedDataStore {
|
|
|
1509
1504
|
this.filters = this.config.presetFilters || {};
|
|
1510
1505
|
this.pageSize = this.config.presetQuery?.pageSize || 20;
|
|
1511
1506
|
this.page = this.config.presetQuery?.page || 0;
|
|
1512
|
-
this.sort = this.config.presetQuery?.sort;
|
|
1513
1507
|
}
|
|
1514
1508
|
}
|
|
1515
1509
|
|
package/package.json
CHANGED
|
@@ -585,17 +585,16 @@ type PaginatedDataStoreConfig<ItemsType extends object, FilterType = unknown> =
|
|
|
585
585
|
cacheSize?: number;
|
|
586
586
|
/** Debounce delay before request (ms). Useful for frequent filter changes. */
|
|
587
587
|
debounceTime?: number;
|
|
588
|
-
/** Initial pagination
|
|
588
|
+
/** Initial pagination params. `page` is required. */
|
|
589
589
|
presetQuery?: {
|
|
590
590
|
page: number;
|
|
591
591
|
pageSize?: number;
|
|
592
|
-
sort?: string;
|
|
593
592
|
};
|
|
594
593
|
/** Initial filters. Will be sent with the first request. */
|
|
595
594
|
presetFilters?: Partial<FilterType>;
|
|
596
595
|
/**
|
|
597
596
|
* Custom transformation of request data into a query object.
|
|
598
|
-
* Useful for mapping `page/pageSize
|
|
597
|
+
* Useful for mapping `page/pageSize` → API-specific keys.
|
|
599
598
|
*/
|
|
600
599
|
parseRequest?: (data: PageableRequest) => Query;
|
|
601
600
|
/**
|
|
@@ -611,9 +610,9 @@ type PaginatedDataStoreConfig<ItemsType extends object, FilterType = unknown> =
|
|
|
611
610
|
type PaginatedDataStoreProviderConfig = {
|
|
612
611
|
/** Default method for all stores (if not overridden locally). */
|
|
613
612
|
defaultMethod?: RestMethods;
|
|
614
|
-
/** Default base `page/pageSize
|
|
613
|
+
/** Default base `page/pageSize`. */
|
|
615
614
|
defaultQuery?: PaginatedDataStoreConfig<object>['presetQuery'];
|
|
616
|
-
/** Global `parseRequest` — maps pagination
|
|
615
|
+
/** Global `parseRequest` — maps pagination into a query object. */
|
|
617
616
|
defaultParseRequest?: PaginatedDataStoreConfig<object>['parseRequest'];
|
|
618
617
|
/** Whether to enable page cache by default. */
|
|
619
618
|
defaultHasCache?: boolean;
|
|
@@ -625,15 +624,13 @@ type PaginationType = {
|
|
|
625
624
|
page?: number;
|
|
626
625
|
first?: number | null;
|
|
627
626
|
rows?: number | null;
|
|
628
|
-
sortField?: string | string[] | null;
|
|
629
|
-
sortOrder?: number | null;
|
|
630
627
|
};
|
|
631
628
|
/**
|
|
632
629
|
* Store for paginated data (tables/lists) with per-page cache and unified requests.
|
|
633
630
|
*
|
|
634
631
|
* Provides:
|
|
635
632
|
* - reactive signals: `items`, `loading`, `cached`;
|
|
636
|
-
* - methods to control page/size/filters
|
|
633
|
+
* - methods to control page/size/filters;
|
|
637
634
|
* - optional LRU cache by pages;
|
|
638
635
|
* - configurable transport (GET/POST/PATCH/…).
|
|
639
636
|
*
|
|
@@ -657,8 +654,6 @@ declare class PaginatedDataStore<ItemsType extends object, FilterType = unknown>
|
|
|
657
654
|
loading: WritableSignal<boolean>;
|
|
658
655
|
/** Current filters (applied to requests). */
|
|
659
656
|
filters: Partial<FilterType>;
|
|
660
|
-
/** Current sorting (`field,asc|desc`). */
|
|
661
|
-
sort?: string | ReadonlyArray<string>;
|
|
662
657
|
/** Current page index (0-based). */
|
|
663
658
|
page: number;
|
|
664
659
|
/** Default page size. */
|
|
@@ -671,7 +666,7 @@ declare class PaginatedDataStore<ItemsType extends object, FilterType = unknown>
|
|
|
671
666
|
* @param config Store behavior: method, cache, request/response parsers, debounce, presets, etc.
|
|
672
667
|
*/
|
|
673
668
|
constructor(route: string, config?: PaginatedDataStoreConfig<ItemsType, FilterType>);
|
|
674
|
-
/** Force reload current data (with the same page/filters
|
|
669
|
+
/** Force reload current data (with the same page/filters). */
|
|
675
670
|
refresh(): Promise<ItemsType[] | undefined>;
|
|
676
671
|
/**
|
|
677
672
|
* Switch page with a request.
|
|
@@ -692,11 +687,11 @@ declare class PaginatedDataStore<ItemsType extends object, FilterType = unknown>
|
|
|
692
687
|
updateFilters: (filters: Partial<FilterType>) => Promise<ItemsType[] | undefined>;
|
|
693
688
|
/**
|
|
694
689
|
* Update the state from table events (PrimeNG, etc.) and fetch.
|
|
695
|
-
* Supports `page/first/rows
|
|
690
|
+
* Supports `page/first/rows`.
|
|
696
691
|
*/
|
|
697
|
-
updateQuery: ({ page: pageNum, first, rows
|
|
692
|
+
updateQuery: ({ page: pageNum, first, rows }: PaginationType) => Promise<ItemsType[] | undefined>;
|
|
698
693
|
/**
|
|
699
|
-
* Set filters from scratch (goes to the first page
|
|
694
|
+
* Set filters from scratch (goes to the first page) and fetch.
|
|
700
695
|
* Useful for quick presets.
|
|
701
696
|
*/
|
|
702
697
|
setFilters: (filters?: Partial<FilterType>) => Promise<ItemsType[] | undefined>;
|
|
@@ -779,7 +774,7 @@ type DictStoreConfig<ItemsType extends object> = {
|
|
|
779
774
|
/** Autoload data on initialization (`true` by default). */
|
|
780
775
|
autoLoad?: boolean | 'whenEmpty';
|
|
781
776
|
/**
|
|
782
|
-
* Custom mapper of pagination
|
|
777
|
+
* Custom mapper of pagination request into query params.
|
|
783
778
|
* Useful if the API expects non-standard field names.
|
|
784
779
|
*/
|
|
785
780
|
parseRequest?: (data: PageableRequest) => AnyDict;
|