@reforgium/statum 1.1.0 → 2.0.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
@@ -58,6 +58,7 @@ All cache strategies implement the same contract.
58
58
 
59
59
  ```ts
60
60
  interface StorageInterface<T> {
61
+ prefix?: string;
61
62
  get(key: string): T | null;
62
63
  set(key: string, value: T): void;
63
64
  remove(key: string): void;
@@ -148,16 +149,16 @@ Lightweight store for server-side pagination with sorting, filtering and page ca
148
149
 
149
150
  ### State
150
151
 
151
- | Field / Signal | Type | Description |
152
- |---|---|---|
153
- | items | `WritableSignal<T[]>` | Current page items |
154
- | cached | `WritableSignal<T[]>` | Flattened cache of cached pages |
155
- | loading | `WritableSignal<boolean>` | Loading indicator |
156
- | page | `number` | Current page (0-based) |
157
- | pageSize | `number` | Page size |
158
- | totalElements | `number` | Total items on server |
159
- | filters | `Partial<F>` | Active filters |
160
- | sort | `string \| undefined` | Sort as `"field,asc|desc"` |
152
+ | Field / Signal | Type | Description |
153
+ |----------------|---------------------------|---------------------------------|
154
+ | items | `WritableSignal<T[]>` | Current page items |
155
+ | cached | `WritableSignal<T[]>` | Flattened cache of cached pages |
156
+ | loading | `WritableSignal<boolean>` | Loading indicator |
157
+ | page | `number` | Current page (0-based) |
158
+ | pageSize | `number` | Page size |
159
+ | totalElements | `number` | Total items on server |
160
+ | filters | `Partial<F>` | Active filters |
161
+ | sort | `string \| undefined` | Sort as `"field,asc |
161
162
 
162
163
  ### Methods
163
164
 
@@ -170,6 +171,7 @@ Lightweight store for server-side pagination with sorting, filtering and page ca
170
171
  | setFilters | Replace filters, reset cache + sort, go to page 0 |
171
172
  | updateQuery | Map table events to `page`/`sort` |
172
173
  | updateRoute | Change endpoint, reset meta/cache |
174
+ | setRouteParams | Fill route url with params |
173
175
  | updateConfig | Patch config and apply presets |
174
176
  | copy | Copy config/meta from another store |
175
177
  | destroy | Manual destroying of caches and abort requests |
@@ -270,12 +272,12 @@ Utility for serialization/deserialization between layers (UI ↔ API, objects
270
272
 
271
273
  Core API:
272
274
 
273
- | Method | Description |
274
- |---|---|
275
- | serialize | Prepare data for transport |
276
- | deserialize | Parse incoming data / query string |
277
- | toQuery | Build query string |
278
- | withConfig | Clone serializer with partial config overrides |
275
+ | Method | Description |
276
+ |-------------|------------------------------------------------|
277
+ | serialize | Prepare data for transport |
278
+ | deserialize | Parse incoming data / query string |
279
+ | toQuery | Build query string |
280
+ | withConfig | Clone serializer with partial config overrides |
279
281
 
280
282
  Config:
281
283
 
@@ -1,6 +1,6 @@
1
1
  import { formatDate, isNullable, isDatePeriod, parseToDate, makeQuery, isNumber, isObject, parseToDatePeriod, parseQueryArray, fillUrlWithParams, deepEqual, concatArray, debounceSignal } from '@reforgium/internal';
2
- import { InjectionToken, inject, signal, computed, DestroyRef, effect, untracked } from '@angular/core';
3
2
  import { HttpClient } from '@angular/common/http';
3
+ import { InjectionToken, 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
 
@@ -311,8 +311,6 @@ class Serializer {
311
311
  }
312
312
  }
313
313
 
314
- const SERIALIZER_CONFIG = new InjectionToken('SERIALIZER_CONFIG');
315
-
316
314
  class LruCache {
317
315
  limit;
318
316
  map = new Map();
@@ -368,23 +366,31 @@ class LruCache {
368
366
  }
369
367
 
370
368
  class LocalStorage {
369
+ prefix;
370
+ constructor(prefix = 're') {
371
+ this.prefix = prefix;
372
+ }
371
373
  get length() {
372
- return localStorage.length;
374
+ return Object.keys(localStorage).filter((key) => key.startsWith(this.prefix || '')).length;
373
375
  }
374
376
  get(key) {
375
- const raw = localStorage.getItem(String(key));
377
+ const raw = localStorage.getItem(this.getSafePrefix(key));
376
378
  const parsed = JSON.parse(raw ?? 'null');
377
379
  return parsed ?? null;
378
380
  }
379
381
  set(key, value) {
380
382
  const str = JSON.stringify(value);
381
- localStorage.setItem(String(key), str);
383
+ localStorage.setItem(this.getSafePrefix(key), str);
382
384
  }
383
385
  remove(key) {
384
- return localStorage.removeItem(String(key));
386
+ return localStorage.removeItem(this.getSafePrefix(key));
385
387
  }
386
388
  clear() {
387
- return localStorage.clear();
389
+ const keys = Object.keys(localStorage).filter((key) => key.startsWith(this.prefix || ''));
390
+ keys.forEach((key) => localStorage.removeItem(key));
391
+ }
392
+ getSafePrefix(key) {
393
+ return this.prefix ? `${this.prefix}:${key}` : String(key);
388
394
  }
389
395
  }
390
396
 
@@ -408,23 +414,31 @@ class MemoryStorage {
408
414
  }
409
415
 
410
416
  class SessionStorage {
417
+ prefix;
418
+ constructor(prefix = 're') {
419
+ this.prefix = prefix;
420
+ }
411
421
  get length() {
412
- return sessionStorage.length;
422
+ return Object.keys(sessionStorage).filter((key) => key.startsWith(this.prefix || '')).length;
413
423
  }
414
424
  get(key) {
415
- const raw = sessionStorage.getItem(String(key));
425
+ const raw = sessionStorage.getItem(this.getSafePrefix(key));
416
426
  const parsed = JSON.parse(raw ?? 'null');
417
427
  return parsed ?? null;
418
428
  }
419
429
  set(key, value) {
420
430
  const str = JSON.stringify(value);
421
- sessionStorage.setItem(String(key), str);
431
+ sessionStorage.setItem(this.getSafePrefix(key), str);
422
432
  }
423
433
  remove(key) {
424
- return sessionStorage.removeItem(String(key));
434
+ return sessionStorage.removeItem(this.getSafePrefix(key));
425
435
  }
426
436
  clear() {
427
- return sessionStorage.clear();
437
+ const keys = Object.keys(sessionStorage).filter((key) => key.startsWith(this.prefix || ''));
438
+ keys.forEach((key) => sessionStorage.removeItem(key));
439
+ }
440
+ getSafePrefix(key) {
441
+ return this.prefix ? `${this.prefix}:${key}` : String(key);
428
442
  }
429
443
  }
430
444
 
@@ -453,6 +467,9 @@ const storageStrategy = (strategy) => {
453
467
  return fabrics[strategy]();
454
468
  };
455
469
 
470
+ // noinspection ES6PreferShortImport
471
+ const STATUM_CONFIG = new InjectionToken('RE_STATUM_CONFIG');
472
+
456
473
  /**
457
474
  * Error thrown when requested data is missing in the cache.
458
475
  *
@@ -647,7 +664,7 @@ class KeyedScheduler {
647
664
  */
648
665
  class ResourceStore {
649
666
  http = inject(HttpClient);
650
- serializer = new Serializer(inject(SERIALIZER_CONFIG, { optional: true }) ?? {});
667
+ serializer = new Serializer(inject(STATUM_CONFIG, { optional: true })?.serializer ?? {});
651
668
  #value = signal(null, ...(ngDevMode ? [{ debugName: "#value" }] : []));
652
669
  #status = signal('idle', ...(ngDevMode ? [{ debugName: "#status" }] : []));
653
670
  #error = signal(null, ...(ngDevMode ? [{ debugName: "#error" }] : []));
@@ -875,8 +892,6 @@ class ResourceStore {
875
892
  }
876
893
  }
877
894
 
878
- const PDS_CONFIG = new InjectionToken('RE_PDS_CONFIG');
879
-
880
895
  // noinspection ES6PreferShortImport
881
896
  /**
882
897
  * Store for paginated data (tables/lists) with per-page cache and unified requests.
@@ -897,7 +912,7 @@ const PDS_CONFIG = new InjectionToken('RE_PDS_CONFIG');
897
912
  class PaginatedDataStore {
898
913
  route;
899
914
  config;
900
- defaultConfig = inject(PDS_CONFIG, { optional: true }) || {};
915
+ defaultConfig = inject(STATUM_CONFIG, { optional: true })?.paginatedData || {};
901
916
  #transport;
902
917
  #cache;
903
918
  /** Current page data (reactive). */
@@ -1182,6 +1197,12 @@ class DictStore {
1182
1197
  apiUrl;
1183
1198
  storageKey;
1184
1199
  static MAX_CACHE_SIZE = 400;
1200
+ /**
1201
+ * Default dictionary configuration resolved from {@link STATUM_CONFIG}.
1202
+ *
1203
+ * Used as a global fallback when local configuration does not explicitly
1204
+ */
1205
+ defaultConfig = inject(STATUM_CONFIG, { optional: true })?.dict || {};
1185
1206
  #helper;
1186
1207
  #lru = new LruCache(_a.MAX_CACHE_SIZE);
1187
1208
  #effectRefs = [];
@@ -1228,7 +1249,7 @@ class DictStore {
1228
1249
  * @param storageKey key for saving cache in the selected strategy
1229
1250
  * @param cfg behavior (fixed/search, parsers, label/value keys, cache strategy, etc.)
1230
1251
  */
1231
- constructor(apiUrl, storageKey, { method, autoLoad = true, presetFilters, parseResponse, parseRequest, debounceTime, fixed = true, maxOptionsSize, labelKey = 'name', valueKey = 'code', cacheStrategy = 'persist', }) {
1252
+ constructor(apiUrl, storageKey, { autoLoad = true, method = this.defaultConfig.defaultRestMethod, presetFilters = this.defaultConfig.defaultPresetFilters, parseResponse, parseRequest, debounceTime = this.defaultConfig.defaultDebounceTime, fixed = true, maxOptionsSize = this.defaultConfig.defaultMaxOptionsSize, labelKey = this.defaultConfig.defaultLabelKey || 'name', valueKey = this.defaultConfig.defaultValueKey || 'code', keyPrefix = this.defaultConfig.defaultPrefix || 're', cacheStrategy = this.defaultConfig.defaultCacheStrategy || 'persist', }) {
1232
1253
  this.apiUrl = apiUrl;
1233
1254
  this.storageKey = storageKey;
1234
1255
  this.#helper = new PaginatedDataStore(this.apiUrl, {
@@ -1243,10 +1264,11 @@ class DictStore {
1243
1264
  this.labelKey = labelKey;
1244
1265
  this.valueKey = valueKey;
1245
1266
  this.maxOptionsSize = maxOptionsSize;
1246
- this._armed.set(autoLoad);
1247
1267
  if (cacheStrategy !== 'memory') {
1248
1268
  this.storage = storageStrategy(cacheStrategy);
1269
+ this.storage.prefix = keyPrefix;
1249
1270
  }
1271
+ this.setAutoload(autoLoad);
1250
1272
  this.restoreFromStorage();
1251
1273
  this.#effectRefs.push(effect(() => {
1252
1274
  const incoming = this.#helper.items();
@@ -1388,15 +1410,41 @@ class DictStore {
1388
1410
  }
1389
1411
  return typeof raw === 'string' ? raw : String(raw);
1390
1412
  }
1413
+ setAutoload(autoLoad) {
1414
+ if (autoLoad === 'whenEmpty') {
1415
+ const isEmpty = !this.storage?.get(this.storageKey)?.length;
1416
+ this._armed.set(isEmpty);
1417
+ }
1418
+ else {
1419
+ this._armed.set(autoLoad);
1420
+ }
1421
+ }
1391
1422
  }
1392
1423
  _a = DictStore;
1393
1424
 
1394
1425
  class DictLocalStore {
1426
+ /**
1427
+ * Default dictionary configuration resolved from {@link STATUM_CONFIG}.
1428
+ *
1429
+ * Used as a global fallback when local configuration does not explicitly
1430
+ * define dictionary keys.
1431
+ */
1432
+ defaultConfig = inject(STATUM_CONFIG, { optional: true })?.dict || {};
1433
+ /**
1434
+ * Source dictionary items.
1435
+ *
1436
+ * Represents the full, unfiltered list of dictionary entries.
1437
+ * Used as the base data set for search and option generation.
1438
+ */
1395
1439
  items = signal([], ...(ngDevMode ? [{ debugName: "items" }] : []));
1396
1440
  #draftItems = signal([], ...(ngDevMode ? [{ debugName: "#draftItems" }] : []));
1397
1441
  /**
1398
- * Ready-to-use options for dropdowns: `{ label, value }`.
1399
- * Respects `maxOptionsSize` to truncate the list.
1442
+ * Computed list of options in `{ label, value }` format.
1443
+ *
1444
+ * Based on the current draft items (after search/filtering).
1445
+ * Respects `maxOptionsSize` to limit the number of generated options.
1446
+ *
1447
+ * Intended for direct use in dropdowns and select-like components.
1400
1448
  */
1401
1449
  options = computed(() => {
1402
1450
  const options = this.#draftItems().map((it) => ({
@@ -1409,19 +1457,30 @@ class DictLocalStore {
1409
1457
  valueKey;
1410
1458
  maxOptionsSize;
1411
1459
  constructor(items, config) {
1412
- this.labelKey = config?.labelKey ?? 'label';
1413
- this.valueKey = config?.valueKey ?? 'value';
1460
+ this.labelKey = config?.labelKey ?? (this.defaultConfig.defaultLabelKey || 'name');
1461
+ this.valueKey = config?.valueKey ?? (this.defaultConfig.defaultValueKey || 'code');
1414
1462
  this.maxOptionsSize = config?.maxOptionsSize ?? 1000;
1415
1463
  this.items.set(items);
1416
1464
  this.#draftItems.set(items);
1417
1465
  }
1466
+ // noinspection JSUnusedGlobalSymbols
1418
1467
  /**
1419
- * No-op method for API compatibility with DictStore.
1468
+ * Restore cached dictionary state.
1469
+ *
1470
+ * This implementation is a no-op and exists only for API compatibility
1471
+ * with {@link DictStore}.
1420
1472
  */
1421
1473
  restoreCache() { }
1422
1474
  /**
1423
- * Find display label by value (usually for reverse binding).
1424
- * @returns label string or `undefined` if not found
1475
+ * Resolve display label by value.
1476
+ *
1477
+ * Performs a linear search over dictionary items and returns
1478
+ * the corresponding label for the given value.
1479
+ *
1480
+ * Commonly used for reverse binding (value → label).
1481
+ *
1482
+ * @param value Dictionary value to look up
1483
+ * @returns Resolved label string, or `undefined` if not found
1425
1484
  */
1426
1485
  findLabel = (value) => {
1427
1486
  for (const item of this.items()) {
@@ -1431,6 +1490,16 @@ class DictLocalStore {
1431
1490
  }
1432
1491
  return undefined;
1433
1492
  };
1493
+ /**
1494
+ * Filter dictionary items by label.
1495
+ *
1496
+ * Applies a case-insensitive substring match against the label field
1497
+ * and updates the internal draft items used for option generation.
1498
+ *
1499
+ * Passing an empty string resets the filter and restores all items.
1500
+ *
1501
+ * @param name Search query string
1502
+ */
1434
1503
  search = (name = '') => {
1435
1504
  const items = this.items();
1436
1505
  if (name?.length) {
@@ -1440,6 +1509,18 @@ class DictLocalStore {
1440
1509
  this.#draftItems.set(items);
1441
1510
  }
1442
1511
  };
1512
+ /**
1513
+ * Preload additional dictionary items.
1514
+ *
1515
+ * Can either replace the current items completely or append
1516
+ * new entries to the existing list.
1517
+ *
1518
+ * Updates both the source items and the current draft items.
1519
+ *
1520
+ * @param items Items to preload
1521
+ * @param opts Preload options
1522
+ * @param opts.replace When `true`, replaces existing items instead of appending
1523
+ */
1443
1524
  preload = (items, opts) => {
1444
1525
  if (opts?.replace) {
1445
1526
  this.items.set(items);
@@ -1457,5 +1538,5 @@ class DictLocalStore {
1457
1538
  * Generated bundle index. Do not edit.
1458
1539
  */
1459
1540
 
1460
- export { AbortError, CacheMissError, DictLocalStore, DictStore, LruCache, PDS_CONFIG, PaginatedDataStore, ResourceStore, SERIALIZER_CONFIG, Serializer, isAbort, storageStrategy };
1541
+ export { AbortError, CacheMissError, DictLocalStore, DictStore, LruCache, PaginatedDataStore, ResourceStore, STATUM_CONFIG, Serializer, isAbort, storageStrategy };
1461
1542
  //# sourceMappingURL=reforgium-statum.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"reforgium-statum.mjs","sources":["../../../../libs/statum/src/serializer/serializer.helpers.ts","../../../../libs/statum/src/serializer/serializer.ts","../../../../libs/statum/src/serializer/serializer.provider.ts","../../../../libs/statum/src/cache/storages/lru.storage.ts","../../../../libs/statum/src/cache/storages/local.storage.ts","../../../../libs/statum/src/cache/storages/memory.storage.ts","../../../../libs/statum/src/cache/storages/session.storage.ts","../../../../libs/statum/src/cache/storage-strategy/storage.strategy.ts","../../../../libs/statum/src/stores/resource-store/resource.utils.ts","../../../../libs/statum/src/stores/resource-store/resource.scheduler.ts","../../../../libs/statum/src/stores/resource-store/resource.store.ts","../../../../libs/statum/src/stores/paginated-data-store/paginated-data.provider.ts","../../../../libs/statum/src/stores/paginated-data-store/paginated-data.store.ts","../../../../libs/statum/src/stores/dict-store/dict.store.ts","../../../../libs/statum/src/stores/dict-store/dict-local.store.ts","../../../../libs/statum/src/reforgium-statum.ts"],"sourcesContent":["import { AnyType, formatDate } from '@reforgium/internal';\r\n\r\n// noinspection ES6PreferShortImport\r\nimport { SerializerConfig } from './serialize.models';\r\n\r\nexport const serializeString = (config: SerializerConfig, value: AnyType) =>\r\n config.mapString.format?.(value) ?? (config.mapString.trim ? value.trim() : value);\r\n\r\nexport const serializeNumber = (config: SerializerConfig, value: AnyType) =>\r\n config.mapNumber.format?.(value) ?? Number(value);\r\n\r\nexport const serializeBoolean = (config: SerializerConfig, value: AnyType) =>\r\n config.mapBoolean.format?.(value) ?? (value ? (config.mapBoolean.true ?? true) : (config.mapBoolean.false ?? false));\r\n\r\nexport const serializeDate = (config: SerializerConfig, value: AnyType) =>\r\n config.mapDate.format?.(value) ?? formatDate(value, config.mapDate.dateFormat);\r\n","import { AnyDict, AnyType } from '@reforgium/internal';\r\nimport {\r\n formatDate,\r\n isDatePeriod,\r\n isNullable,\r\n isNumber,\r\n isObject,\r\n makeQuery,\r\n parseQueryArray,\r\n parseToDate,\r\n parseToDatePeriod,\r\n} from '@reforgium/internal';\r\n\r\nimport { DataType, SerializedType, SerializerConfig } from './serialize.models';\r\nimport { serializeBoolean, serializeDate, serializeNumber, serializeString } from './serializer.helpers';\r\n\r\n/**\r\n * Universal serializer/deserializer for values used in forms, filters, and DTOs.\r\n *\r\n * Supports types: `string | number | boolean | Date | [Date, Date] (period) | array | object | nullable`.\r\n * Capabilities:\r\n * - normalize values according to config (trim strings, parse numbers from strings, boolean strings, etc.),\r\n * - transform date periods into paired keys (`from/to`) or a single joined string,\r\n * - build/parse a query string (or JSON) to and from an object.\r\n *\r\n * Example:\r\n * ```ts\r\n * type Filters = { q?: string; active?: boolean; created?: [Date, Date] | null };\r\n * const s = new Serializer<Filters>({\r\n * mapPeriod: { transformMode: { mode: 'split', dateFromKeyPostfix: 'From', dateToKeyPostfix: 'To' } }\r\n * });\r\n *\r\n * // -> { q: 'john', createdFrom: '2025-01-01', createdTo: '2025-01-31' }\r\n * const plain = s.serialize({\r\n * q: ' john ',\r\n * active: undefined,\r\n * created: [new Date('2025-01-01'), new Date('2025-01-31')]\r\n * });\r\n *\r\n * // -> 'q=john&createdFrom=2025-01-01&createdTo=2025-01-31'\r\n * const qs = s.toQuery({ q: 'john', created: [new Date('2025-01-01'), new Date('2025-01-31')] });\r\n *\r\n * // <- { q: 'john', created: [Date, Date] }\r\n * const parsed = s.deserialize('q=john&createdFrom=2025-01-01&createdTo=2025-01-31');\r\n * ```\r\n */\r\nexport class Serializer<EntityType extends DataType> {\r\n readonly config: SerializerConfig;\r\n\r\n /**\r\n * Creates a serializer with a partially overridden configuration.\r\n * Provide only the options you want to change (the rest are taken from defaults).\r\n *\r\n * @param config partial transformation configuration\r\n */\r\n constructor(config: Partial<SerializerConfig>) {\r\n this.config = {\r\n mapString: { trim: true },\r\n mapNumber: { fromString: false },\r\n mapBoolean: {},\r\n mapArray: { concatType: 'comma' },\r\n mapObject: { deep: true },\r\n mapDate: { dateFormat: 'yyyy-MM-dd' },\r\n mapPeriod: {\r\n dateFormat: 'yyyy-MM-dd',\r\n transformMode: { mode: 'split', dateFromKeyPostfix: 'From', dateToKeyPostfix: 'To' },\r\n },\r\n mapNullable: { remove: true, includeEmptyString: false },\r\n ...config,\r\n };\r\n }\r\n\r\n /**\r\n * Converts a domain object into a flat serialized representation\r\n * (ready to send to an API or build a query string).\r\n *\r\n * Rules are taken from `config`:\r\n * — strings can be trimmed (if enabled),\r\n * — numbers can be converted from strings/numbers,\r\n * — boolean supports custom true/false representations,\r\n * — dates are formatted by `dateFormat`,\r\n * — date periods can be split/joined,\r\n * — `nullable` can be removed from the result (`remove`) or formatted.\r\n *\r\n * @param obj source object\r\n * @returns a flat dictionary with string/primitive values\r\n */\r\n serialize(obj: EntityType): SerializedType {\r\n const result: SerializedType = {};\r\n\r\n for (const [key, value] of Object.entries(obj ?? {})) {\r\n const fields = this.config.mapFields?.[key];\r\n\r\n if (fields && 'format' in fields) {\r\n result[key] = fields.format(value, obj as EntityType);\r\n continue;\r\n }\r\n\r\n if (fields?.type === 'nullable' || isNullable(value, this.config.mapNullable?.includeEmptyString)) {\r\n if (this.config.mapNullable.remove) {\r\n continue;\r\n }\r\n }\r\n\r\n if (fields?.type === 'period' || isDatePeriod(value)) {\r\n const transform = this.config.mapPeriod.transformMode;\r\n const [from, to] = value;\r\n\r\n if (transform?.mode === 'split') {\r\n result[`${key}${transform.dateFromKeyPostfix}`] = formatDate(from, this.config.mapPeriod.dateFormat);\r\n result[`${key}${transform.dateToKeyPostfix}`] = formatDate(to, this.config.mapPeriod.dateFormat);\r\n continue;\r\n }\r\n }\r\n\r\n result[key] = this.serializeElement(value, key);\r\n }\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * Parse serialized data into a domain object.\r\n *\r\n * Source can be:\r\n * — a query string (`key=value&arr=1,2`) or `JSON.stringify(obj)`,\r\n * — an already prepared flat object.\r\n *\r\n * Transformations are reverse of `serialize`: strings → number/boolean/Date/period,\r\n * arrays are collected according to strategy (`comma`/`pipe`/`multi`), objects — deeply or as JSON.\r\n *\r\n * @param val query string or object\r\n * @returns a domain object of the specified type\r\n */\r\n deserialize = (val: string | AnyDict): EntityType => {\r\n const data: SerializedType = typeof val === 'string' ? this.parseQuery(val) : val;\r\n const result: AnyType = {};\r\n\r\n for (const [key, value] of Object.entries(data ?? {})) {\r\n const field = this.config.mapFields?.[key];\r\n\r\n if (field && 'parse' in field) {\r\n result[key] = field.parse(value, data);\r\n continue;\r\n }\r\n\r\n if (\r\n field?.type === 'nullable' ||\r\n (field?.type !== 'array' && isNullable(value, this.config.mapNullable?.includeEmptyString))\r\n ) {\r\n if (this.config.mapNullable.remove) {\r\n continue;\r\n }\r\n }\r\n\r\n const periodTransform = this.config.mapPeriod.transformMode!;\r\n\r\n if (periodTransform.mode === 'split') {\r\n const isFrom = (key || '').endsWith(periodTransform.dateFromKeyPostfix);\r\n const isTo = (key || '').endsWith(periodTransform.dateToKeyPostfix);\r\n const keyJoint = (key || '')\r\n .replace(periodTransform.dateFromKeyPostfix, '')\r\n .replace(periodTransform.dateToKeyPostfix, '');\r\n const field = this.config.mapFields?.[keyJoint];\r\n\r\n // @ts-ignore\r\n if (field?.['type'] === 'period' && (isFrom || isTo)) {\r\n result[keyJoint] ??= [null, null];\r\n\r\n if (isFrom) {\r\n result[keyJoint][0] = parseToDate(value, this.config.mapPeriod.dateFormat);\r\n } else if (isTo) {\r\n result[keyJoint][1] = parseToDate(value, this.config.mapPeriod.dateFormat);\r\n }\r\n\r\n continue;\r\n }\r\n }\r\n\r\n result[key] = this.deserializeElement(value, key);\r\n }\r\n\r\n return result;\r\n };\r\n\r\n /**\r\n * Build a query string from a domain object using `serialize` rules\r\n * and the array joining strategy (`concatType`).\r\n *\r\n * @param val domain object\r\n * @returns query string (suitable for URL or history API)\r\n */\r\n toQuery = (val: EntityType): string => {\r\n return makeQuery(this.serialize(val), this.config.mapArray.concatType);\r\n };\r\n\r\n /**\r\n * Returns a new serializer instance with a merged configuration.\r\n * Useful for ad-hoc overrides for a specific call.\r\n *\r\n * @param config partial config changes\r\n * @returns new `Serializer` with the provided `config` applied\r\n */\r\n withConfig(config: Partial<SerializerConfig>): Serializer<EntityType> {\r\n return new Serializer<EntityType>({ ...this.config, ...config });\r\n }\r\n\r\n private serializeElement(value: AnyType, key?: string): AnyType {\r\n const fields = this.config.mapFields?.[key || ''];\r\n\r\n if (fields && 'format' in fields) {\r\n return;\r\n }\r\n\r\n if (fields?.type === 'nullable' || isNullable(value, this.config.mapNullable?.includeEmptyString)) {\r\n const nullableVal = value || null;\r\n\r\n return this.config.mapNullable.format?.(nullableVal) || this.config.mapNullable.replaceWith || nullableVal;\r\n }\r\n\r\n if (fields?.type === 'string') {\r\n return serializeString(this.config, value);\r\n }\r\n\r\n if (fields?.type === 'number' || isNumber(value, this.config.mapNumber.fromString)) {\r\n return serializeNumber(this.config, value);\r\n }\r\n\r\n if (typeof value === 'string') {\r\n return serializeString(this.config, value);\r\n }\r\n\r\n if (fields?.type === 'boolean' || typeof value === 'boolean') {\r\n return serializeBoolean(this.config, value);\r\n }\r\n\r\n if (fields?.type === 'date' || value instanceof Date) {\r\n return serializeDate(this.config, value);\r\n }\r\n\r\n if (fields?.type === 'period' || isDatePeriod(value)) {\r\n const mapPeriod = this.config.mapPeriod;\r\n\r\n if (mapPeriod.format) {\r\n return mapPeriod.format(value);\r\n } else {\r\n const [from, to] = value;\r\n const transform = mapPeriod.transformMode!;\r\n\r\n if (transform.mode === 'join') {\r\n const period = [\r\n formatDate(from, this.config.mapPeriod.dateFormat),\r\n formatDate(to, this.config.mapPeriod.dateFormat),\r\n ];\r\n\r\n return period.join(transform.concat);\r\n }\r\n }\r\n }\r\n\r\n if (fields?.type === 'array' || Array.isArray(value)) {\r\n return (value as AnyType[]).map((it) => this.serializeElement(it));\r\n }\r\n\r\n if (fields?.type === 'object' || isObject(value)) {\r\n return (\r\n this.config.mapObject.format?.(value) ??\r\n (this.config.mapObject.deep ? this.serialize(value) : JSON.stringify(value))\r\n );\r\n }\r\n }\r\n\r\n private deserializeElement(value: AnyType, key?: string): AnyType {\r\n const field = this.config.mapFields?.[key || ''];\r\n\r\n if (field && 'format' in field) {\r\n return;\r\n }\r\n\r\n if (field?.type === 'array' || Array.isArray(value)) {\r\n const array = Array.isArray(value) ? value : [value];\r\n\r\n if (this.config.mapArray.removeNullable) {\r\n if (!isNullable(value, this.config.mapNullable?.includeEmptyString)) {\r\n return array.map((it) => this.deserializeElement(it));\r\n } else {\r\n return;\r\n }\r\n } else {\r\n return !value ? [] : array.map((it) => this.deserializeElement(it));\r\n }\r\n }\r\n\r\n if (field?.type === 'object') {\r\n try {\r\n if (this.config.mapObject.deep) {\r\n // @ts-ignore\r\n return this.deserializeElement(value);\r\n } else {\r\n // @ts-ignore\r\n return JSON.parse(value);\r\n }\r\n } catch {\r\n return value;\r\n }\r\n }\r\n\r\n if (field?.type === 'nullable' || isNullable(value, this.config.mapNullable?.includeEmptyString)) {\r\n return this.config.mapNullable.parse?.(value) || value;\r\n }\r\n\r\n if (\r\n field?.type === 'boolean' ||\r\n typeof value === 'boolean' ||\r\n value === this.config.mapBoolean.true ||\r\n value === this.config.mapBoolean.false\r\n ) {\r\n return this.config.mapBoolean.parse?.(value) ?? (value === this.config.mapBoolean.true || value === true);\r\n }\r\n\r\n const maybeDate = parseToDate(value, this.config.mapDate.dateFormat);\r\n\r\n if (field?.type === 'date' || maybeDate) {\r\n return this.config.mapDate.parse?.(value) || maybeDate;\r\n }\r\n\r\n const periodTransform = this.config.mapPeriod.transformMode!;\r\n\r\n if (periodTransform.mode === 'join') {\r\n const maybePeriod = parseToDatePeriod(value, this.config.mapPeriod.dateFormat);\r\n\r\n if (field?.type === 'period' || (maybePeriod || []).some(Boolean)) {\r\n return this.config.mapPeriod.parse?.(value) || maybePeriod;\r\n }\r\n }\r\n\r\n if (field?.type === 'number' || isNumber(value, this.config.mapNumber.fromString)) {\r\n return this.config.mapNumber.parse?.(value) || Number(String(value).trim());\r\n }\r\n\r\n if (field?.type === 'string' || typeof value === 'string') {\r\n return this.config.mapString.parse?.(value) || this.config.mapString.trim ? String(value).trim() : value;\r\n }\r\n\r\n return value;\r\n }\r\n\r\n private parseQuery(val: string) {\r\n try {\r\n return JSON.parse(val);\r\n } catch {\r\n const params = new URLSearchParams(val);\r\n const data: SerializedType = {};\r\n\r\n params.forEach((value, key) => {\r\n const field = this.config.mapFields?.[key] || {};\r\n const concatType = this.config.mapArray.concatType;\r\n\r\n if ('type' in field && field.type === 'array') {\r\n data[key] ??= [];\r\n concatType !== 'multi' && (data[key] = parseQueryArray(value, concatType, key));\r\n concatType === 'multi' && (data[key] as string[]).push(value);\r\n } else {\r\n data[key] = value;\r\n }\r\n });\r\n\r\n return data;\r\n }\r\n }\r\n}\r\n","import { InjectionToken } from '@angular/core';\r\n\r\nimport { SerializerConfig } from './serialize.models';\r\n\r\nexport const SERIALIZER_CONFIG = new InjectionToken<Partial<SerializerConfig>>('SERIALIZER_CONFIG');\r\n","import { StorageInterface } from './models';\r\n\r\nexport class LruCache<KeyT, ValueT> implements StorageInterface<KeyT, ValueT> {\r\n private map = new Map<KeyT, ValueT>();\r\n\r\n constructor(public limit: number = 100) {}\r\n\r\n get length(): number {\r\n return this.map.size;\r\n }\r\n\r\n get(key: KeyT) {\r\n if (!this.map.has(key)) {\r\n return null;\r\n }\r\n\r\n const val = this.map.get(key)!;\r\n\r\n this.map.delete(key);\r\n this.map.set(key, val);\r\n\r\n return val;\r\n }\r\n\r\n set(key: KeyT, value: ValueT) {\r\n if (this.map.has(key)) {\r\n this.map.delete(key);\r\n } else if (this.map.size === this.limit) {\r\n const oldest = this.map.keys().next().value;\r\n\r\n oldest !== undefined && this.map.delete(oldest);\r\n }\r\n\r\n this.map.set(key, value);\r\n }\r\n\r\n remove(key: KeyT): boolean {\r\n return this.map.delete(key);\r\n }\r\n\r\n clear(): void {\r\n this.map.clear();\r\n }\r\n\r\n has(key: KeyT): boolean {\r\n return this.map.has(key);\r\n }\r\n\r\n keys(): KeyT[] {\r\n return Array.from(this.map.keys());\r\n }\r\n\r\n values(): ValueT[] {\r\n return Array.from(this.map.values());\r\n }\r\n\r\n toArray(): ValueT[] {\r\n return Array.from(this.map.values());\r\n }\r\n\r\n fromArray(entries: [KeyT, ValueT][]) {\r\n this.map.clear();\r\n\r\n for (const [k, v] of entries) {\r\n this.set(k, v);\r\n }\r\n }\r\n}\r\n","import { AnyDict, AnyType } from '@reforgium/internal';\r\n\r\nimport { StorageInterface } from './models';\r\n\r\nexport class LocalStorage<Key = string, Type extends AnyType = AnyDict> implements StorageInterface<Key, Type> {\r\n get length() {\r\n return localStorage.length;\r\n }\r\n\r\n get(key: Key): Type | null {\r\n const raw = localStorage.getItem(String(key));\r\n const parsed = JSON.parse(raw ?? 'null');\r\n\r\n return (parsed as Type) ?? null;\r\n }\r\n\r\n set(key: Key, value: Type): void {\r\n const str = JSON.stringify(value);\r\n\r\n localStorage.setItem(String(key), str);\r\n }\r\n\r\n remove(key: Key): void {\r\n return localStorage.removeItem(String(key));\r\n }\r\n\r\n clear(): void {\r\n return localStorage.clear();\r\n }\r\n}\r\n","import { AnyDict, AnyType } from '@reforgium/internal';\r\n\r\nimport { StorageInterface } from '.';\r\n\r\nexport class MemoryStorage<Key = string, Type extends AnyType = AnyDict> implements StorageInterface<Key, Type> {\r\n private cache = new Map<Key, Type>();\r\n\r\n get length() {\r\n return this.cache.size;\r\n }\r\n\r\n get(key: Key): Type | null {\r\n return this.cache.get(key) ?? null;\r\n }\r\n\r\n set(key: Key, value: Type): void {\r\n this.cache.set(key, value);\r\n }\r\n\r\n remove(key: Key): void {\r\n this.cache.delete(key);\r\n }\r\n\r\n clear(): void {\r\n this.cache.clear();\r\n }\r\n}\r\n","import { AnyDict, AnyType } from '@reforgium/internal';\r\n\r\nimport { StorageInterface } from './models';\r\n\r\nexport class SessionStorage<Key = string, Type extends AnyType = AnyDict> implements StorageInterface<Key, Type> {\r\n get length() {\r\n return sessionStorage.length;\r\n }\r\n\r\n get(key: Key): Type | null {\r\n const raw = sessionStorage.getItem(String(key));\r\n const parsed = JSON.parse(raw ?? 'null');\r\n\r\n return (parsed as Type) ?? null;\r\n }\r\n\r\n set(key: Key, value: Type): void {\r\n const str = JSON.stringify(value);\r\n\r\n sessionStorage.setItem(String(key), str);\r\n }\r\n\r\n remove(key: Key): void {\r\n return sessionStorage.removeItem(String(key));\r\n }\r\n\r\n clear(): void {\r\n return sessionStorage.clear();\r\n }\r\n}\r\n","import { AnyDict, AnyType } from '@reforgium/internal';\r\n\r\nimport { LruCache, StorageInterface } from '../storages';\r\nimport { LocalStorage } from '../storages/local.storage';\r\nimport { MemoryStorage } from '../storages/memory.storage';\r\nimport { SessionStorage } from '../storages/session.storage';\r\nimport { StorageStrategy } from './models';\r\n\r\n/**\r\n * Factory for data storage strategies.\r\n *\r\n * Returns a `StorageInterface` implementation depending on the selected strategy:\r\n * - `'memory'` — in-memory storage (for the session lifetime);\r\n * - `'session'` — `sessionStorage`, lives until the tab is closed;\r\n * - `'persist'` — `localStorage`, persists between sessions;\r\n * - `'lru'` — size-limited cache (Least Recently Used).\r\n *\r\n * Used to choose an appropriate storage implementation\r\n * depending on the scenario: temporary data, long-term, cache, etc.\r\n *\r\n * @param strategy storage strategy type (`memory`, `session`, `persist`, `lru`)\r\n * @returns instance implementing `StorageInterface<Key, Type>`\r\n */\r\nexport const storageStrategy = <Key = string, Type extends AnyType = AnyDict>(\r\n strategy: StorageStrategy,\r\n): StorageInterface<Key, Type> => {\r\n const fabrics: Record<StorageStrategy, () => StorageInterface<Key, Type>> = {\r\n memory: () => new MemoryStorage<Key, Type>(),\r\n session: () => new SessionStorage<Key, Type>(),\r\n persist: () => new LocalStorage<Key, Type>(),\r\n lru: () => new LruCache<Key, Type>(),\r\n };\r\n\r\n return fabrics[strategy]();\r\n};\r\n","import { RestMethods } from '@reforgium/internal';\r\n\r\nimport { CallArgs } from './resource.models';\r\n\r\n/**\r\n * Error thrown when requested data is missing in the cache.\r\n *\r\n * Used by the `cache-only` strategy when data is not found\r\n * and a network request is not allowed.\r\n *\r\n * Example:\r\n * ```ts\r\n * try {\r\n * await store.get({ query }, { strategy: 'cache-only' });\r\n * } catch (e) {\r\n * if (e instanceof CacheMissError) console.warn(e.key, 'not found in cache');\r\n * }\r\n * ```\r\n */\r\nexport class CacheMissError extends Error {\r\n constructor(public readonly key: string) {\r\n super(`Cache miss for key: ${key}`);\r\n this.name = 'CacheMissError';\r\n }\r\n}\r\n\r\n/**\r\n * Error indicating an aborted (canceled) request.\r\n *\r\n * May be thrown by `abort()` or `abortAll()` in `ResourceStore`.\r\n * Usually does not require handling as an error — used to ignore canceled operations.\r\n */\r\nexport class AbortError extends Error {\r\n constructor(message = 'aborted') {\r\n super(message);\r\n this.name = 'AbortError';\r\n }\r\n}\r\n\r\n/**\r\n * Checks whether the exception is an `AbortError` (including compatible objects).\r\n *\r\n * @param e — any value that may be an error\r\n * @returns `true` if it's an `AbortError`\r\n */\r\nexport function isAbort(e: unknown): e is AbortError {\r\n return (\r\n e instanceof AbortError ||\r\n (typeof e === 'object' && e != null && (e as Error)?.name === 'AbortError' && (e as Error)?.message === 'aborted')\r\n );\r\n}\r\n\r\nexport function joinUrl(base: string | undefined, path: string): string {\r\n return base ? `${base.replace(/\\/$/, '')}/${path.replace(/^\\//, '')}` : path;\r\n}\r\n\r\nexport function buildKey(method: RestMethods, path: string, args: CallArgs): string {\r\n const params = Object.entries(args.params || {})\r\n .map(([key, value]) => `${key}=${value}`)\r\n .join('&');\r\n const query = Object.entries(args.query || {})\r\n .map(([key, value]) => `${key}=${value}`)\r\n .join('&');\r\n\r\n return `${method}|${path}|${params}|${query}`;\r\n}\r\n","import { filter, merge, Observable, Subject, Subscription, timer } from 'rxjs';\r\nimport { debounce as rxDebounce, finalize, tap, throttle as rxThrottle } from 'rxjs/operators';\r\n\r\nimport { AnyType } from '@reforgium/internal';\r\n\r\nimport { DelayMode } from './resource.models';\r\n// noinspection ES6PreferShortImport\r\nimport { AbortError } from './resource.utils';\r\n\r\ntype Waiter<T> = { resolve: (v: T) => void; reject: (e: unknown) => void };\r\n\r\ntype ScheduledTask<Data> = {\r\n mode: DelayMode;\r\n delay: number;\r\n exec: () => Observable<Data>;\r\n};\r\n\r\ntype Channel<Data> = {\r\n subject: Subject<ScheduledTask<Data>>;\r\n waiters: Waiter<Data>[];\r\n lastExec?: () => Observable<Data>;\r\n timerSub?: Subscription;\r\n inflight?: Subscription;\r\n};\r\n\r\n/**\r\n * Per-key task scheduler with `debounce`/`throttle` and result deduplication.\r\n *\r\n * Allows applying delays and rate limiting separately for each key.\r\n * All `schedule` calls for the same key are coalesced: consumers receive a single shared `Promise`\r\n * that resolves with the value of the last started task.\r\n *\r\n * Suitable for API requests, auto-saving forms, incremental search, etc.\r\n *\r\n * Example:\r\n * ```ts\r\n * const ks = new KeyedScheduler();\r\n * // these three calls collapse into one request after 300ms\r\n * ks.schedule('users:list', 'debounce', 300, () => http.get<User[]>('/api/users'));\r\n * ks.schedule('users:list', 'debounce', 300, () => http.get<User[]>('/api/users'));\r\n * const users = await ks.schedule('users:list', 'debounce', 300, () => http.get<User[]>('/api/users'));\r\n * ```\r\n */\r\nexport class KeyedScheduler {\r\n private channels = new Map<string, Channel<AnyType>>();\r\n\r\n /**\r\n * Schedule task execution for the specified key.\r\n *\r\n * Multiple calls with the same key are merged according to the mode:\r\n * `debounce` — runs the last task after a pause;\r\n * `throttle` — runs no more often than the specified delay (uses the last accumulated).\r\n *\r\n * All waiters receive the result of a single execution.\r\n *\r\n * @param key logical channel key (e.g., `'users:list'`)\r\n * @param mode delay mode (`'debounce' | 'throttle'`)\r\n * @param delay delay in milliseconds\r\n * @param exec Observable factory with the actual work (HTTP request, etc.)\r\n * @returns Promise with the result of `exec`\r\n */\r\n schedule<Data>(key: string, mode: DelayMode, delay: number, exec: () => Observable<Data>): Promise<Data> {\r\n const channel = this.ensureChannel<Data>(key);\r\n const promise = new Promise<Data>((resolve, reject) => {\r\n channel.waiters.push({ resolve, reject });\r\n });\r\n\r\n channel.lastExec = exec;\r\n\r\n if (delay <= 0) {\r\n this.startExecution(channel);\r\n } else {\r\n channel.subject.next({ mode, delay, exec });\r\n }\r\n\r\n return promise;\r\n }\r\n\r\n /**\r\n * Cancels scheduled/running tasks for a key.\r\n * All pending `Promise`s will be rejected with `AbortError` (or the provided reason).\r\n *\r\n * @param key channel key\r\n * @param reason cancellation reason (defaults to `AbortError('aborted')`)\r\n */\r\n cancel(key: string, reason: unknown = new AbortError()): void {\r\n const ch = this.channels.get(key);\r\n\r\n if (!ch) {\r\n return;\r\n }\r\n\r\n ch.timerSub?.unsubscribe();\r\n ch.inflight?.unsubscribe();\r\n ch.inflight = undefined;\r\n ch.subject.complete();\r\n\r\n const waiters = ch.waiters.splice(0);\r\n\r\n waiters.forEach((w) => w.reject(reason));\r\n\r\n this.channels.delete(key);\r\n }\r\n\r\n /**\r\n * Cancels all channels and their pending tasks.\r\n *\r\n * @param reason cancellation reason (defaults to `AbortError('aborted')`)\r\n */\r\n cancelAll(reason: unknown = new AbortError()) {\r\n for (const key of Array.from(this.channels.keys())) {\r\n this.cancel(key, reason);\r\n }\r\n }\r\n\r\n private ensureChannel<Type>(key: string): Channel<Type> {\r\n let ch = this.channels.get(key) as Channel<Type> | undefined;\r\n\r\n if (ch) {\r\n return ch;\r\n }\r\n\r\n const subject = new Subject<ScheduledTask<Type>>();\r\n\r\n ch = { subject, waiters: [] };\r\n this.channels.set(key, ch as Channel<Type>);\r\n\r\n const debounced$ = subject.pipe(\r\n filter((t) => t.mode === 'debounce'),\r\n rxDebounce((t) => timer(t.delay)),\r\n tap(() => this.startExecution(ch!)),\r\n );\r\n\r\n const throttled$ = subject.pipe(\r\n filter((t) => t.mode === 'throttle'),\r\n rxThrottle((t) => timer(t.delay), { leading: false, trailing: true }),\r\n tap(() => this.startExecution(ch!)),\r\n );\r\n\r\n ch.timerSub = merge(debounced$, throttled$)\r\n .pipe(finalize(() => this.channels.delete(key)))\r\n .subscribe();\r\n\r\n return ch;\r\n }\r\n\r\n private startExecution<T>(ch: Channel<T>) {\r\n const exec = ch.lastExec;\r\n\r\n if (!exec) {\r\n return;\r\n }\r\n\r\n ch.inflight?.unsubscribe();\r\n ch.inflight = exec().subscribe({\r\n next: (val) => {\r\n const waiters = ch.waiters.splice(0);\r\n\r\n waiters.forEach((w) => w.resolve(val));\r\n },\r\n error: (err) => {\r\n const waiters = ch.waiters.splice(0);\r\n\r\n waiters.forEach((w) => w.reject(err));\r\n },\r\n complete: () => (ch.inflight = undefined),\r\n });\r\n }\r\n}\r\n","import { HttpClient } from '@angular/common/http';\r\nimport { computed, inject, Signal, signal } from '@angular/core';\r\nimport { map, Observable } from 'rxjs';\r\nimport { finalize, tap } from 'rxjs/operators';\r\n\r\nimport { AnyDict, AnyType, fillUrlWithParams, RestMethods } from '@reforgium/internal';\r\n\r\nimport { Serializer, SERIALIZER_CONFIG } from '../../serializer';\r\nimport {\r\n CacheStrategy,\r\n CallArgs,\r\n CallConfig,\r\n DelayMode,\r\n ExecArgs,\r\n GetCallConfig,\r\n PayloadData,\r\n ResourceEntry,\r\n ResourceRoutesMap,\r\n ResourceStatus,\r\n ResourceStoreOptions,\r\n SimpleDict,\r\n} from './resource.models';\r\nimport { KeyedScheduler } from './resource.scheduler';\r\nimport { buildKey, CacheMissError, isAbort, joinUrl } from './resource.utils';\r\n\r\n/**\r\n * Store for REST resources with caching and request deduplication.\r\n *\r\n * Provides reactive access to current value, status, and error;\r\n * supports cache strategies (cache-first / cache-only / network-first),\r\n * TTL, delays (debounce/throttle), request cancellation, and auto-serialization of query/payload.\r\n *\r\n * Example:\r\n * ```ts\r\n * const store = new ResourceStore({ GET: '/users/:id' }, { baseUrl: '/api', ttlMs: 30_000 });\r\n *\r\n * effect(() => {\r\n * if (store.loading()) showSpinner();\r\n * if (store.error()) showError(store.error());\r\n * const user = store.value();\r\n * });\r\n *\r\n * await store.get({ params: { id: '42' }, query: { expand: ['roles'] } }, { strategy: 'cache-first', dedupe: true });\r\n * ```\r\n */\r\nexport class ResourceStore<Data> {\r\n private readonly http = inject(HttpClient);\r\n private readonly serializer = new Serializer<AnyDict>(inject(SERIALIZER_CONFIG, { optional: true }) ?? {});\r\n\r\n #value = signal<Data | null>(null);\r\n #status = signal<ResourceStatus>('idle');\r\n #error = signal<unknown | null>(null);\r\n #activeRequests = signal(0);\r\n\r\n /**\r\n * Current resource value.\r\n * Returns `null` if no data yet or the request failed.\r\n */\r\n value: Signal<Data | null> = this.#value.asReadonly();\r\n\r\n /**\r\n * Current loading status of the resource: `idle | loading | stale | success | error`.\r\n */\r\n status: Signal<ResourceStatus> = this.#status.asReadonly();\r\n\r\n /**\r\n * Last error (if any). Otherwise `null`.\r\n */\r\n error: Signal<unknown | null> = this.#error.asReadonly();\r\n\r\n /**\r\n * Convenience loading flag: `true` when `loading` or `stale`.\r\n * Useful for spinners and disabling buttons.\r\n */\r\n loading: Signal<boolean> = computed(() => this.#activeRequests() > 0 || this.#status() === 'stale');\r\n\r\n private readonly routes: ResourceRoutesMap;\r\n private readonly opts: ResourceStoreOptions;\r\n private readonly entries = new Map<string, ResourceEntry<unknown>>();\r\n private readonly scheduler = new KeyedScheduler();\r\n\r\n /**\r\n * @param routes Map of path templates for methods (`GET/POST/...` → `/users/:id`)\r\n * @param opts Global options (baseUrl, ttlMs, delay, delayMode, presetQueries/payload, etc.)\r\n */\r\n constructor(routes: ResourceRoutesMap, opts: ResourceStoreOptions = {}) {\r\n this.routes = routes;\r\n this.opts = opts;\r\n }\r\n\r\n /**\r\n * Perform a GET request.\r\n *\r\n * Supports cache strategies (`strategy`), TTL (`ttlMs`), revalidation,\r\n * deduplication (`dedupe`), and response parsing (`parseResponse`).\r\n *\r\n * @param args { params, query }\r\n * @param cfg Call settings (strategy, ttlMs, revalidate, parseResponse, delay, delayMode, dedupe, promote)\r\n * @returns Deserialized `Data`\r\n */\r\n async get<\r\n Param extends SimpleDict = SimpleDict,\r\n Query extends PayloadData = PayloadData,\r\n Response extends AnyType = Data,\r\n >(args: CallArgs<Param, Query, never>, cfg: GetCallConfig<Response, Data> = {}): Promise<Data> {\r\n const url = this.buildUrl('GET', args);\r\n const key = buildKey('GET', url, args);\r\n const query = this.prepareQuery(args);\r\n\r\n const entry = this.ensureEntry<Data>(key);\r\n const strategy: CacheStrategy = cfg.strategy ?? 'network-first';\r\n const ttlMs = cfg.ttlMs ?? this.opts.ttlMs ?? 0;\r\n const fresh = entry.updatedAt != null && Date.now() - entry.updatedAt < ttlMs;\r\n\r\n if (cfg.dedupe && entry.inflight) {\r\n return entry.inflight as unknown as Promise<Data>;\r\n }\r\n\r\n if (strategy === 'cache-only') {\r\n if (fresh && entry.data != null) {\r\n this.promoteCurrent(entry, cfg.promote);\r\n\r\n return entry.data as Data;\r\n }\r\n\r\n throw new CacheMissError(key);\r\n }\r\n\r\n if (strategy === 'cache-first' && fresh && !cfg.revalidate && entry.data != null) {\r\n this.promoteCurrent(entry, cfg.promote);\r\n\r\n return entry.data as Data;\r\n }\r\n\r\n const delay = cfg.delay ?? this.opts.delay ?? 0;\r\n const mode: DelayMode = cfg.delayMode ?? this.opts.delayMode ?? 'debounce';\r\n\r\n const isSWR = strategy === 'cache-first' && entry.data != null;\r\n\r\n entry.status = isSWR ? 'stale' : 'loading';\r\n this.promoteCurrent(entry, cfg.promote);\r\n\r\n const task = this.scheduler.schedule(\r\n key,\r\n mode,\r\n delay,\r\n this.exec$({\r\n req$: this.http.get<Response>(url, { params: query }),\r\n entry,\r\n promote: cfg.promote,\r\n parseFn: cfg.parseResponse,\r\n }),\r\n );\r\n\r\n cfg.dedupe && (entry.inflight = task);\r\n void task.catch((e) => {\r\n if (!isAbort(e)) {\r\n throw e;\r\n }\r\n });\r\n\r\n return task;\r\n }\r\n\r\n /**\r\n * POST request.\r\n *\r\n * @param args { params, query, payload }\r\n * @param cfg Call settings (parseResponse, delay, delayMode, dedupe, promote)\r\n * @returns API response (by default — as returned by the server)\r\n */\r\n async post<\r\n Param extends SimpleDict = SimpleDict,\r\n Payload extends PayloadData = PayloadData,\r\n Query extends PayloadData = PayloadData,\r\n Response extends AnyType = AnyType,\r\n >(args: CallArgs<Param, Query, Payload>, cfg: CallConfig<Response, Response> = {}): Promise<Response> {\r\n return await this.callApi<Param, Payload, Query, Response>('POST', args, cfg);\r\n }\r\n\r\n /**\r\n * PUT request (full resource update).\r\n *\r\n * @param args { params, query, payload }\r\n * @param cfg Call settings (parseResponse, delay, delayMode, dedupe, promote)\r\n * @returns API response (by default — as returned by the server)\r\n */\r\n async put<\r\n Param extends SimpleDict = SimpleDict,\r\n Payload extends PayloadData = PayloadData,\r\n Query extends SimpleDict = SimpleDict,\r\n Response extends AnyType = AnyType,\r\n >(args: CallArgs<Param, Query, Partial<Payload>>, cfg: CallConfig<Response, Response> = {}): Promise<Response> {\r\n return await this.callApi<Param, Payload, Query, Response>('PUT', args, cfg);\r\n }\r\n\r\n /**\r\n * PATCH request (partial update).\r\n *\r\n * @param args { params, query, payload }\r\n * @param cfg Call settings (parseResponse, delay, delayMode, dedupe, promote)\r\n * @returns API response (by default — as returned by the server)\r\n */\r\n async patch<\r\n Param extends SimpleDict = SimpleDict,\r\n Payload extends PayloadData = PayloadData,\r\n Query extends SimpleDict = SimpleDict,\r\n Response extends AnyType = AnyType,\r\n >(args: CallArgs<Param, Query, Partial<Payload>>, cfg: CallConfig<Response, Response> = {}): Promise<Response> {\r\n return await this.callApi<Param, Payload, Query, Response>('PATCH', args, cfg);\r\n }\r\n\r\n /**\r\n * DELETE request.\r\n *\r\n * @param args { params, query, payload }\r\n * @param cfg Call settings (parseResponse, delay, delayMode, dedupe, promote)\r\n * @returns API response (by default — as returned by the server)\r\n */\r\n async delete<\r\n Param extends SimpleDict = SimpleDict,\r\n Payload extends PayloadData = PayloadData,\r\n Query extends SimpleDict = SimpleDict,\r\n Response extends AnyType = AnyType,\r\n >(args: CallArgs<Param, Query, Payload>, cfg: CallConfig<Response, Response> = {}): Promise<Response> {\r\n return await this.callApi<Param, Payload, Query, Response>('DELETE', args, cfg);\r\n }\r\n\r\n /**\r\n * Cancel scheduled/running requests for a specific call.\r\n *\r\n * @param method HTTP method\r\n * @param args Arguments used to build the URL (params, query)\r\n * @param reason Cancellation reason (optional)\r\n */\r\n abort<Param extends SimpleDict = SimpleDict, Query extends PayloadData = PayloadData>(\r\n method: RestMethods,\r\n args: CallArgs<Param, Query>,\r\n reason?: string | Error,\r\n ) {\r\n const url = this.buildUrl(method, args);\r\n const key = buildKey(method, url, args);\r\n\r\n this.scheduler.cancel?.(key, reason);\r\n }\r\n\r\n /**\r\n * Cancel all scheduled/running requests for this store.\r\n *\r\n * @param reason Cancellation reason (optional)\r\n */\r\n abortAll(reason?: string | Error) {\r\n this.scheduler.cancelAll?.(reason);\r\n }\r\n\r\n private ensureEntry<R>(key: string): ResourceEntry<R> {\r\n let entry = this.entries.get(key) as ResourceEntry<R> | undefined;\r\n\r\n if (!entry) {\r\n entry = { data: null, status: 'idle', error: null, updatedAt: null };\r\n this.entries.set(key, entry as ResourceEntry<unknown>);\r\n }\r\n\r\n return entry;\r\n }\r\n\r\n private async callApi<\r\n Param extends SimpleDict = SimpleDict,\r\n Payload extends PayloadData = PayloadData,\r\n Query extends SimpleDict = SimpleDict,\r\n Response extends AnyType = AnyType,\r\n >(\r\n method: RestMethods,\r\n args: CallArgs<Param, Query, Partial<Payload>>,\r\n config: CallConfig<Response, Response> = {},\r\n ): Promise<Response> {\r\n const url = this.buildUrl(method, args);\r\n const key = buildKey(method, url, args);\r\n const query = this.prepareQuery(args);\r\n const payload = { ...(this.opts.presetPayload || {}), ...(args.payload || {}) };\r\n const serializedPayload = this.serializer.serialize(payload);\r\n\r\n const entry = this.ensureEntry<Response>(key);\r\n\r\n if (config.dedupe && entry.inflight) {\r\n return entry.inflight as Promise<Response>;\r\n }\r\n\r\n const delay = config.delay ?? this.opts.delay ?? 0;\r\n const mode: DelayMode = config.delayMode ?? this.opts.delayMode ?? 'debounce';\r\n\r\n entry.status = 'loading';\r\n this.promoteCurrent(entry, config.promote);\r\n\r\n let req$: Observable<Response>;\r\n\r\n if (method === 'DELETE') {\r\n req$ = this.http.delete<Response>(url, { body: serializedPayload, params: query });\r\n } else {\r\n // @ts-ignore\r\n req$ = this.http[method.toLowerCase()]<Response>(url, serializedPayload, { params: query });\r\n }\r\n\r\n const task = this.scheduler.schedule<Response>(\r\n key,\r\n mode,\r\n delay,\r\n this.exec$<Response, Response>({ req$, entry, promote: config.promote, parseFn: config.parseResponse }),\r\n );\r\n\r\n config.dedupe && (entry.inflight = task);\r\n void task.catch((e) => {\r\n if (!isAbort(e)) {\r\n throw e;\r\n }\r\n });\r\n\r\n return task;\r\n }\r\n\r\n private buildUrl(method: RestMethods, args: CallArgs) {\r\n const tpl = this.routes[method];\r\n\r\n if (!tpl) {\r\n throw new Error(`${method} route not configured`);\r\n }\r\n\r\n const path = fillUrlWithParams(tpl, args.params);\r\n\r\n return joinUrl(this.opts.baseUrl, path);\r\n }\r\n\r\n private prepareQuery(args: CallArgs) {\r\n const mergedQuery = { ...(this.opts.presetQueries || {}), ...(args.query || {}) } as AnyDict;\r\n\r\n return this.serializer.serialize(mergedQuery) as SimpleDict;\r\n }\r\n\r\n private exec$ =\r\n <Response, Return = Data>({ req$, entry, promote = true, parseFn }: ExecArgs<Response, Return>) =>\r\n () => {\r\n promote && this.#activeRequests.update((n) => n + 1);\r\n\r\n return req$.pipe(\r\n map((data) => (parseFn ? parseFn(data) : (data as unknown as Return))),\r\n tap({\r\n next: (data) => {\r\n promote && (entry.data = data);\r\n entry.status = 'success';\r\n entry.updatedAt = Date.now();\r\n entry.error = null;\r\n this.promoteCurrent(entry, promote);\r\n },\r\n error: (err) => {\r\n entry.error = err;\r\n entry.status = 'error';\r\n this.promoteCurrent(entry, promote);\r\n },\r\n }),\r\n finalize(() => {\r\n entry.inflight = undefined;\r\n promote && this.#activeRequests.update((n) => Math.max(0, n - 1));\r\n this.promoteCurrent(entry, promote);\r\n }),\r\n );\r\n };\r\n\r\n private promoteCurrent(entry: ResourceEntry<unknown>, promote = true) {\r\n if (!promote) {\r\n return;\r\n }\r\n\r\n this.#value.set((entry.data as Data) ?? null);\r\n this.#status.set(entry.status);\r\n this.#error.set(entry.error);\r\n }\r\n}\r\n","import { InjectionToken } from '@angular/core';\r\n\r\nimport { PaginatedDataStoreConfig } from '.';\r\n\r\nexport const PDS_CONFIG = new InjectionToken<PaginatedDataStoreConfig>('RE_PDS_CONFIG');\r\n","// noinspection ES6PreferShortImport\r\n\r\nimport { DestroyRef, inject, signal, WritableSignal } from '@angular/core';\r\n\r\nimport { AnyDict, concatArray, deepEqual, isNullable, PageableResponse, Query, QueryParams } from '@reforgium/internal';\r\n\r\nimport { LruCache } from '../../cache/storages/lru.storage';\r\nimport { isAbort, ResourceStore } from '../../stores/resource-store';\r\n\r\nimport { PaginatedDataConfig, PDS_CONFIG } from '.';\r\n\r\ntype PaginationType = {\r\n page?: number;\r\n first?: number | null;\r\n rows?: number | null;\r\n sortField?: string | string[] | null;\r\n sortOrder?: number | null;\r\n};\r\n\r\n/**\r\n * Store for paginated data (tables/lists) with per-page cache and unified requests.\r\n *\r\n * Provides:\r\n * - reactive signals: `items`, `loading`, `cached`;\r\n * - methods to control page/size/filters/sorting;\r\n * - optional LRU cache by pages;\r\n * - configurable transport (GET/POST/PATCH/…).\r\n *\r\n * Example:\r\n * ```ts\r\n * const ds = new PaginatedDataStore<User>('/users', { method: 'GET', hasCache: true });\r\n * await ds.updatePage(0); // load the first page\r\n * effect(() => console.log(ds.items(), ds.loading()));\r\n * ```\r\n */\r\nexport class PaginatedDataStore<ItemsType extends object, FilterType = unknown> {\r\n private readonly defaultConfig = inject(PDS_CONFIG, { optional: true }) || {};\r\n\r\n #transport!: ResourceStore<PageableResponse<ItemsType> | ItemsType[]>;\r\n #cache: LruCache<number, ItemsType[]>;\r\n\r\n /** Current page data (reactive). */\r\n items: WritableSignal<ItemsType[]> = signal<ItemsType[]>([]);\r\n /** Merged cache of pages (flat list) — handy for search/export. */\r\n cached = signal<ItemsType[]>([]);\r\n /** Loading flag of the current operation. */\r\n loading = signal(false);\r\n\r\n /** Current filters (applied to requests). */\r\n filters: Partial<FilterType> = {};\r\n /** Current sorting (`field,asc|desc`). */\r\n sort?: string | ReadonlyArray<string>;\r\n\r\n /** Current page index (0-based). */\r\n page = 0;\r\n /** Default page size. */\r\n pageSize = 20;\r\n /** Total number of elements reported by the server. */\r\n totalElements = 0;\r\n routeParams: AnyDict = {};\r\n\r\n /**\r\n * @param route Resource URL pattern (e.g., `'/users'`)\r\n * @param config Store behavior: method, cache, request/response parsers, debounce, presets, etc.\r\n */\r\n constructor(\r\n private route: string,\r\n public config: PaginatedDataConfig<ItemsType, FilterType> = {},\r\n ) {\r\n this.#cache = new LruCache<number, ItemsType[]>(config.cacheSize!);\r\n this.applyConfig(config);\r\n this.applyPresetMeta();\r\n this.initTransport();\r\n\r\n inject(DestroyRef).onDestroy(() => this.destroy());\r\n }\r\n\r\n /** Force reload current data (with the same page/filters/sort). */\r\n refresh() {\r\n return this.#fetchItems({});\r\n }\r\n\r\n /**\r\n * Switch page with a request.\r\n * If cache is enabled and the page is present in LRU — returns it from cache.\r\n * @param page page index (0-based)\r\n * @param ignoreCache ignore cache and fetch from network\r\n */\r\n updatePage = (page = this.page, ignoreCache = false) => {\r\n if (this.config.hasCache && this.#cache.has(page) && !ignoreCache) {\r\n const cached = this.#cache.get(page)!;\r\n\r\n this.items.set(cached);\r\n this.page = page;\r\n\r\n return Promise.resolve(cached);\r\n } else {\r\n return this.#fetchItems({ page });\r\n }\r\n };\r\n\r\n /**\r\n * Change page size (will go to the first page) and fetch.\r\n * @param size new size (rows per page)\r\n */\r\n updatePageSize = (size = this.pageSize) => {\r\n return this.#fetchItems({ page: 0, size });\r\n };\r\n\r\n /**\r\n * Update filters (goes to the first page) and fetch.\r\n * The previous cache is cleared.\r\n */\r\n updateFilters = (filters: Partial<FilterType>) => {\r\n this.#cache.clear();\r\n this.cached.set([]);\r\n\r\n return this.#fetchItems({ page: 0, filters: { ...this.filters, ...filters } });\r\n };\r\n\r\n /**\r\n * Update the state from table events (PrimeNG, etc.) and fetch.\r\n * Supports `page/first/rows/sortField/sortOrder`.\r\n */\r\n updateQuery = ({ page: pageNum, first = 0, rows = 0, sortOrder, sortField }: PaginationType) => {\r\n const page = (pageNum ?? (first && rows && Math.floor(first / rows))) || 0;\r\n const sort = sortField ? `${sortField},${sortOrder === 1 ? 'asc' : 'desc'}` : '';\r\n\r\n return this.#fetchItems({ page, sort });\r\n };\r\n\r\n /**\r\n * Set filters from scratch (goes to the first page and resets sorting) and fetch.\r\n * Useful for quick presets.\r\n */\r\n setFilters = (filters: Partial<FilterType> = {}) => {\r\n this.#cache.clear();\r\n this.cached.set([]);\r\n\r\n return this.#fetchItems({ page: 0, filters, sort: undefined });\r\n };\r\n\r\n /**\r\n * Change the resource route (resets page, cache, and presets) without fetching.\r\n * Useful when one store should work with different endpoints.\r\n */\r\n updateRoute = (route: string) => {\r\n this.route = route;\r\n this.page = 0;\r\n this.pageSize = 20;\r\n this.totalElements = 0;\r\n this.#cache.clear();\r\n this.cached.set([]);\r\n this.initTransport();\r\n };\r\n\r\n /**\r\n * Set route parameters (path variables) for the resource URL.\r\n * Does not trigger loading automatically — call `refresh()` or `updatePage()` after.\r\n *\r\n * @param params Dictionary of route parameters (e.g., `{ id: '123' }`)\r\n * @param opts Options object\r\n * @param opts.reset If `true` (default), resets page to 0, clears cache, total elements count, and items\r\n * @param opts.abort If `true`, aborts all active transport requests and sets loading to false\r\n *\r\n * @example\r\n * ```ts\r\n * store.setRouteParams({ userId: '42' });\r\n * await store.refresh(); // fetch with new params\r\n *\r\n * // Or with options:\r\n * store.setRouteParams({ userId: '42' }, { reset: false, abort: true });\r\n * ```\r\n */\r\n setRouteParams = (params: AnyDict = {}, opts: { reset?: boolean; abort?: boolean } = {}) => {\r\n const isChanged = !deepEqual(this.routeParams, params);\r\n\r\n if (!isChanged) {\r\n return;\r\n }\r\n\r\n this.routeParams = params;\r\n\r\n if (opts.reset) {\r\n this.page = 0;\r\n this.totalElements = 0;\r\n this.#cache.clear();\r\n this.cached.set([]);\r\n this.items.set([]);\r\n }\r\n\r\n if (opts?.abort) {\r\n try {\r\n this.#transport?.abortAll?.('Route params changed');\r\n } finally {\r\n this.loading.set(false);\r\n }\r\n }\r\n };\r\n\r\n /**\r\n * Update store config on the fly (without re-creation).\r\n * Does not trigger loading automatically.\r\n */\r\n updateConfig = (config: PaginatedDataConfig<ItemsType>) => {\r\n this.config = { ...this.config, ...config };\r\n this.applyPresetMeta();\r\n };\r\n\r\n /**\r\n * Copy configuration and presets from another store of the same type.\r\n */\r\n copy(helper: PaginatedDataStore<ItemsType, FilterType>) {\r\n this.applyConfig(helper.config);\r\n this.applyPresetMeta();\r\n }\r\n\r\n /** Clean up resources and cancel active requests. Automatically called onDestroy. */\r\n destroy() {\r\n try {\r\n this.#transport?.abortAll?.('PaginatedDataStore destroyed');\r\n } catch (e: unknown) {\r\n if (!isAbort(e)) {\r\n throw e;\r\n }\r\n }\r\n }\r\n\r\n #fetchItems = async ({\r\n page = this.page,\r\n size = this.pageSize,\r\n sort = this.sort,\r\n filters = this.filters,\r\n }: QueryParams<FilterType>) => {\r\n const query = this.parseQuery({ page, size, sort, filters });\r\n\r\n this.loading.set(true);\r\n this.#transport.abortAll();\r\n\r\n try {\r\n const response = await this.runTransport(filters, query);\r\n\r\n this.page = page;\r\n this.sort = sort;\r\n this.filters = filters;\r\n\r\n const parsed = await this.parseResponseData(response);\r\n\r\n this.pageSize = parsed.pageable?.pageSize || size;\r\n this.totalElements = parsed.totalElements;\r\n this.items.set(parsed.content);\r\n this.updateCache(parsed.content);\r\n\r\n return parsed.content;\r\n } catch (e) {\r\n if (isAbort(e)) {\r\n return;\r\n }\r\n\r\n throw e;\r\n } finally {\r\n this.loading.set(false);\r\n }\r\n };\r\n\r\n private initTransport() {\r\n this.#transport = new ResourceStore<PageableResponse<ItemsType> | ItemsType[]>(\r\n { [this.config.method || 'GET']: this.route },\r\n {\r\n delay: this.config.debounceTime,\r\n delayMode: 'debounce',\r\n presetQueries: { page: this.page, size: this.pageSize, sort: this.sort },\r\n presetPayload: this.filters,\r\n },\r\n );\r\n }\r\n\r\n private async runTransport(payload: Partial<FilterType>, query: Query) {\r\n const params = this.routeParams;\r\n\r\n if (this.config.method === 'GET') {\r\n return this.#transport.get<AnyDict, AnyDict>({ query, params }, { promote: false, dedupe: true });\r\n }\r\n\r\n const method = this.config.method?.toLowerCase() || 'post';\r\n\r\n // @ts-ignore\r\n return this.#transport[method]<AnyDict, AnyDict, Partial<FilterType>, PageableResponse<ItemsType> | ItemsType[]>(\r\n { query, payload, params },\r\n { promote: false, dedupe: true },\r\n );\r\n }\r\n\r\n private parseQuery({ page = 0, size, sort, filters }: QueryParams<FilterType>) {\r\n const method = this.config.method || 'GET';\r\n const requestPayload = { page, size, ...(method === 'GET' ? filters : {}) };\r\n const rawQueries = this.config.parseRequest?.({ ...requestPayload, sort }) || requestPayload;\r\n const queries: Query = {};\r\n\r\n Object.entries(rawQueries).forEach(([key, value]) => {\r\n if (Array.isArray(value)) {\r\n queries[key] = concatArray(value, 'comma');\r\n } else if (!isNullable(value)) {\r\n queries[key] = value;\r\n }\r\n });\r\n sort && (queries['sort'] = sort);\r\n\r\n return queries;\r\n }\r\n\r\n private parseResponseData = async (\r\n data: PageableResponse<ItemsType> | ItemsType[],\r\n ): Promise<PageableResponse<ItemsType>> => {\r\n if (this.config?.parseResponse) {\r\n // noinspection ES6RedundantAwait\r\n return await this.config.parseResponse(data);\r\n }\r\n\r\n if (Array.isArray(data)) {\r\n return this.parseFlatArray(data);\r\n }\r\n\r\n return data as PageableResponse<ItemsType>;\r\n };\r\n\r\n private updateCache = (data: ItemsType[]) => {\r\n if (this.config.hasCache) {\r\n this.#cache.set(this.page, data);\r\n }\r\n\r\n this.cached.set(Array.from(this.#cache.values()).flat());\r\n };\r\n\r\n private parseFlatArray(data: ItemsType[]): PageableResponse<ItemsType> {\r\n return { content: data, totalElements: data.length };\r\n }\r\n\r\n private applyConfig(config: PaginatedDataConfig<ItemsType, FilterType>) {\r\n this.config = {\r\n ...config,\r\n method: config.method || this.defaultConfig.defaultMethod || 'POST',\r\n presetQuery: config.presetQuery || this.defaultConfig.defaultQuery,\r\n parseRequest: config.parseRequest || this.defaultConfig.defaultParseRequest,\r\n debounceTime: config.debounceTime || 0,\r\n hasCache: config.hasCache === undefined ? this.defaultConfig.defaultHasCache : config.hasCache,\r\n cacheSize: config.cacheSize || this.defaultConfig.defaultCacheSize || 5,\r\n };\r\n }\r\n\r\n private applyPresetMeta() {\r\n this.filters = this.config.presetFilters || {};\r\n this.pageSize = this.config.presetQuery?.pageSize || 20;\r\n this.page = this.config.presetQuery?.page || 0;\r\n this.sort = this.config.presetQuery?.sort;\r\n }\r\n}\r\n","import { computed, effect, EffectRef, signal, untracked } from '@angular/core';\r\n\r\nimport { AnyDict, debounceSignal } from '@reforgium/internal';\r\n\r\nimport { LruCache, StorageInterface, StorageStrategy, storageStrategy } from '../../cache';\r\n// noinspection ES6PreferShortImport\r\nimport { PaginatedDataStore } from '../../stores/paginated-data-store';\r\nimport { DictStoreConfig, FilterType, ValueType } from './dict.models';\r\n\r\n/**\r\n * Dictionary store (select/options) with local LRU cache and optional persistence.\r\n *\r\n * Provides:\r\n * - reactive `items` (current list) and `options` (label/value),\r\n * - local cache filtering (`fixed: true`) or server-side search by name (`fixed: false`),\r\n * - preload and restore cache from `storage` (`localStorage/session/LRU`),\r\n * - smooth integration with `PaginatedDataStore` for server fetching.\r\n *\r\n * Example:\r\n * ```ts\r\n * const dict = new DictStore<Country>('/countries', 'countries', { labelKey: 'name', valueKey: 'code' });\r\n * dict.search('ki'); // filters locally (fixed=true) or goes to server (fixed=false)\r\n * effect(() => console.log(dict.options())); // [{label:'Kyrgyzstan', value: 'KG'}, ...]\r\n * ```\r\n */\r\nexport class DictStore<Type extends AnyDict> {\r\n static readonly MAX_CACHE_SIZE = 400;\r\n\r\n #helper: PaginatedDataStore<Type, FilterType>;\r\n #lru = new LruCache<string, Type>(DictStore.MAX_CACHE_SIZE);\r\n #effectRefs: EffectRef[] = [];\r\n\r\n private readonly fixed: boolean = true;\r\n private readonly labelKey: keyof Type & string;\r\n private readonly valueKey: keyof Type & string;\r\n private readonly maxOptionsSize?: number;\r\n private readonly storage?: StorageInterface<string, Type[]>;\r\n\r\n /**\r\n * Search text.\r\n * With `fixed: true` filters the local cache; with `fixed: false` triggers server search.\r\n */\r\n searchText = signal<string>('');\r\n\r\n private debouncedSearchText = debounceSignal(this.searchText, 300);\r\n\r\n /**\r\n * Additional filters for server request (or presets).\r\n */\r\n filters = signal<AnyDict>({});\r\n\r\n private cachedItems = signal<readonly Type[]>([]);\r\n\r\n /**\r\n * Current list of dictionary items.\r\n * Source — local cache (fixed=true) or data from `PaginatedDataStore`.\r\n */\r\n items = computed<readonly Type[]>(() => {\r\n const cached = this.cachedItems();\r\n\r\n if (!this.fixed) {\r\n return this.debouncedSearchText() || !cached.length ? this.#helper.items() : cached;\r\n }\r\n\r\n return cached.length ? this.filterLocal() : this.#helper.items();\r\n });\r\n\r\n /**\r\n * Ready-to-use dropdown options: `{ label, value }`.\r\n * Respects `maxOptionsSize` for truncating the list.\r\n */\r\n options = computed(() => {\r\n const options = this.items().map((it) => ({ label: String(it[this.labelKey] ?? ''), value: it[this.valueKey] }));\r\n\r\n return this.maxOptionsSize ? options.slice(0, this.maxOptionsSize) : options;\r\n });\r\n private _lastPromise: Promise<unknown> | null = null;\r\n private _armed = signal(false);\r\n\r\n // todo add i18n support\r\n /**\r\n * @param apiUrl dictionary endpoint (e.g., `'/api/dicts/countries'`)\r\n * @param storageKey key for saving cache in the selected strategy\r\n * @param cfg behavior (fixed/search, parsers, label/value keys, cache strategy, etc.)\r\n */\r\n constructor(\r\n private apiUrl: string,\r\n private storageKey: string,\r\n {\r\n method,\r\n autoLoad = true,\r\n presetFilters,\r\n parseResponse,\r\n parseRequest,\r\n debounceTime,\r\n fixed = true,\r\n maxOptionsSize,\r\n labelKey = 'name',\r\n valueKey = 'code',\r\n cacheStrategy = 'persist',\r\n }: DictStoreConfig<Type>,\r\n ) {\r\n this.#helper = new PaginatedDataStore<Type, FilterType>(this.apiUrl, {\r\n method: method,\r\n hasCache: false,\r\n presetFilters: { name: '', ...presetFilters },\r\n parseResponse: parseResponse,\r\n parseRequest: parseRequest,\r\n debounceTime: debounceTime,\r\n });\r\n this.fixed = fixed;\r\n this.labelKey = labelKey;\r\n this.valueKey = valueKey;\r\n this.maxOptionsSize = maxOptionsSize;\r\n this._armed.set(autoLoad);\r\n\r\n if (cacheStrategy !== 'memory') {\r\n this.storage = storageStrategy<string, Type[]>(cacheStrategy as StorageStrategy);\r\n }\r\n\r\n this.restoreFromStorage();\r\n\r\n this.#effectRefs.push(\r\n effect(() => {\r\n const incoming = this.#helper.items();\r\n\r\n if (incoming.length === 0) {\r\n return;\r\n }\r\n\r\n untracked(() => this.mergeIntoCache(incoming));\r\n }),\r\n );\r\n\r\n this.#effectRefs.push(\r\n effect(() => {\r\n if (!this._armed()) {\r\n return;\r\n }\r\n\r\n const rest = this.filters();\r\n\r\n if (!this.fixed) {\r\n const query = this.debouncedSearchText().trim();\r\n\r\n untracked(() => {\r\n this._lastPromise = this.#helper.updateFilters({ name: query, ...rest });\r\n });\r\n } else if (!this.cachedItems().length) {\r\n untracked(() => {\r\n this._lastPromise = this.#helper.updateFilters({ name: '', ...rest });\r\n });\r\n }\r\n }),\r\n );\r\n }\r\n\r\n /** Restore cache from the selected storage (`persist`/`session`/`lru`/`memory`). */\r\n restoreCache() {\r\n this.restoreFromStorage();\r\n }\r\n\r\n /**\r\n * Set a search query and filters.\r\n * With `fixed: false` initiates server search; with `fixed: true` — local filtering.\r\n */\r\n search = (name = '', filters: AnyDict = {}) => {\r\n this._armed.set(true);\r\n this.searchText.set(name);\r\n this.filters.set(filters);\r\n };\r\n\r\n /**\r\n * Find display label by value (typically for reverse binding).\r\n * @returns label string or `undefined` if not found\r\n */\r\n findLabel = (value: ValueType): string | undefined => {\r\n for (const item of this.cachedItems()) {\r\n if (item[this.valueKey] === value) {\r\n return String(item[this.labelKey] ?? undefined);\r\n }\r\n }\r\n\r\n return undefined;\r\n };\r\n\r\n /**\r\n * Preload dictionary items into a local cache.\r\n * Useful for SSR/static lists/quick presets.\r\n *\r\n * @param items list of items\r\n * @param opts `{ replace?: true }` — completely replace current cache\r\n */\r\n preload = (items: readonly Type[], opts?: { replace?: boolean }) => {\r\n opts?.replace && this.#lru.clear();\r\n let changed = false;\r\n\r\n for (const it of items) {\r\n const key = this.keyOf(it);\r\n\r\n if (!key) {\r\n continue;\r\n }\r\n\r\n const existed = this.#lru.has(key);\r\n\r\n this.#lru.set(key, it);\r\n !existed && (changed = true);\r\n }\r\n\r\n if (changed || opts?.replace) {\r\n const arr = this.#lru.toArray();\r\n\r\n this.cachedItems.set(arr);\r\n this.storage?.set(this.storageKey, arr.slice(0, DictStore.MAX_CACHE_SIZE));\r\n }\r\n };\r\n\r\n /** Release resources and stop internal effects. */\r\n dispose() {\r\n this.#effectRefs.forEach((e) => e.destroy());\r\n this.#effectRefs = [];\r\n }\r\n\r\n /** Syntactic sugar for `using`/`Symbol.dispose`. */\r\n [Symbol.dispose]() {\r\n this.dispose();\r\n }\r\n\r\n private mergeIntoCache(items: Type[]) {\r\n let changed = 0;\r\n\r\n for (const it of items) {\r\n const key = this.keyOf(it);\r\n const before = this.#lru.has(key);\r\n\r\n this.#lru.set(key, it);\r\n !before && changed++;\r\n }\r\n\r\n if (changed > 0) {\r\n const arr = this.#lru.toArray();\r\n\r\n this.cachedItems.set(arr);\r\n this.storage?.set(this.storageKey, arr.slice(0, DictStore.MAX_CACHE_SIZE));\r\n }\r\n }\r\n\r\n private restoreFromStorage() {\r\n try {\r\n const array = this.storage?.get(this.storageKey);\r\n\r\n if (!array) {\r\n return;\r\n }\r\n\r\n for (const it of array) {\r\n const key = this.keyOf(it);\r\n\r\n this.#lru.set(key, it);\r\n }\r\n\r\n this.cachedItems.set(this.#lru.toArray());\r\n } catch {\r\n try {\r\n this.storage?.remove(this.storageKey);\r\n } catch {\r\n /* noop */\r\n }\r\n }\r\n }\r\n\r\n private filterLocal() {\r\n const list = this.cachedItems();\r\n const query = (this.fixed ? this.searchText() : this.debouncedSearchText()).toLowerCase();\r\n\r\n if (!query) {\r\n return list;\r\n }\r\n\r\n const key = this.labelKey;\r\n const out: Type[] = [];\r\n\r\n for (let i = 0; i < list.length; i++) {\r\n const val = list[i][key];\r\n\r\n val.toLowerCase().includes(query) && out.push(list[i]);\r\n }\r\n\r\n return out;\r\n }\r\n\r\n private keyOf(it: Type) {\r\n const raw = it[this.valueKey] as unknown;\r\n\r\n if (raw == null) {\r\n return '';\r\n }\r\n\r\n return typeof raw === 'string' ? raw : String(raw);\r\n }\r\n}\r\n","import { computed, signal } from '@angular/core';\r\n\r\nimport { AnyDict } from '@reforgium/internal';\r\n\r\nimport { DictLocalConfig, ValueType } from './dict.models';\r\n\r\nexport class DictLocalStore<Type extends AnyDict> {\r\n items = signal<readonly Type[]>([]);\r\n #draftItems = signal<readonly Type[]>([]);\r\n\r\n /**\r\n * Ready-to-use options for dropdowns: `{ label, value }`.\r\n * Respects `maxOptionsSize` to truncate the list.\r\n */\r\n options = computed(() => {\r\n const options = this.#draftItems().map((it) => ({\r\n label: String(it[this.labelKey] ?? ''),\r\n value: it[this.valueKey],\r\n }));\r\n\r\n return this.maxOptionsSize ? options.slice(0, this.maxOptionsSize) : options;\r\n });\r\n\r\n private readonly labelKey: keyof Type & string;\r\n private readonly valueKey: keyof Type & string;\r\n private readonly maxOptionsSize?: number;\r\n\r\n constructor(items: Type[], config?: DictLocalConfig<Type>) {\r\n this.labelKey = config?.labelKey ?? 'label';\r\n this.valueKey = config?.valueKey ?? 'value';\r\n this.maxOptionsSize = config?.maxOptionsSize ?? 1000;\r\n\r\n this.items.set(items);\r\n this.#draftItems.set(items);\r\n }\r\n\r\n /**\r\n * No-op method for API compatibility with DictStore.\r\n */\r\n restoreCache() {}\r\n\r\n /**\r\n * Find display label by value (usually for reverse binding).\r\n * @returns label string or `undefined` if not found\r\n */\r\n findLabel = (value: ValueType): string | undefined => {\r\n for (const item of this.items()) {\r\n if (item[this.valueKey] === value) {\r\n return String(item[this.labelKey] ?? undefined);\r\n }\r\n }\r\n\r\n return undefined;\r\n };\r\n\r\n search = (name = '') => {\r\n const items = this.items();\r\n\r\n if (name?.length) {\r\n this.#draftItems.set(\r\n items.filter((item) => String(item[this.labelKey]).toLowerCase().includes(name.toLowerCase())),\r\n );\r\n } else {\r\n this.#draftItems.set(items);\r\n }\r\n };\r\n\r\n preload = (items: readonly Type[], opts?: { replace?: boolean }) => {\r\n if (opts?.replace) {\r\n this.items.set(items);\r\n this.#draftItems.set(items);\r\n } else {\r\n const patch = [...this.items(), ...items] as readonly Type[];\r\n\r\n this.items.set(patch);\r\n this.#draftItems.set(patch);\r\n }\r\n };\r\n}\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["rxDebounce","rxThrottle"],"mappings":"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"}
1
+ {"version":3,"file":"reforgium-statum.mjs","sources":["../../../../libs/statum/src/serializer/serializer.helpers.ts","../../../../libs/statum/src/serializer/serializer.ts","../../../../libs/statum/src/cache/storages/lru.storage.ts","../../../../libs/statum/src/cache/storages/local.storage.ts","../../../../libs/statum/src/cache/storages/memory.storage.ts","../../../../libs/statum/src/cache/storages/session.storage.ts","../../../../libs/statum/src/cache/storage-strategy/storage.strategy.ts","../../../../libs/statum/src/statum.provider.ts","../../../../libs/statum/src/stores/resource-store/resource.utils.ts","../../../../libs/statum/src/stores/resource-store/resource.scheduler.ts","../../../../libs/statum/src/stores/resource-store/resource.store.ts","../../../../libs/statum/src/stores/paginated-data-store/paginated-data.store.ts","../../../../libs/statum/src/stores/dict-store/dict.store.ts","../../../../libs/statum/src/stores/dict-store/dict-local.store.ts","../../../../libs/statum/src/reforgium-statum.ts"],"sourcesContent":["import { AnyType, formatDate } from '@reforgium/internal';\r\n\r\n// noinspection ES6PreferShortImport\r\nimport { SerializerConfig } from './serialize.models';\r\n\r\nexport const serializeString = (config: SerializerConfig, value: AnyType) =>\r\n config.mapString.format?.(value) ?? (config.mapString.trim ? value.trim() : value);\r\n\r\nexport const serializeNumber = (config: SerializerConfig, value: AnyType) =>\r\n config.mapNumber.format?.(value) ?? Number(value);\r\n\r\nexport const serializeBoolean = (config: SerializerConfig, value: AnyType) =>\r\n config.mapBoolean.format?.(value) ?? (value ? (config.mapBoolean.true ?? true) : (config.mapBoolean.false ?? false));\r\n\r\nexport const serializeDate = (config: SerializerConfig, value: AnyType) =>\r\n config.mapDate.format?.(value) ?? formatDate(value, config.mapDate.dateFormat);\r\n","import { AnyDict, AnyType } from '@reforgium/internal';\r\nimport {\r\n formatDate,\r\n isDatePeriod,\r\n isNullable,\r\n isNumber,\r\n isObject,\r\n makeQuery,\r\n parseQueryArray,\r\n parseToDate,\r\n parseToDatePeriod,\r\n} from '@reforgium/internal';\r\n\r\nimport { DataType, SerializedType, SerializerConfig } from './serialize.models';\r\nimport { serializeBoolean, serializeDate, serializeNumber, serializeString } from './serializer.helpers';\r\n\r\n/**\r\n * Universal serializer/deserializer for values used in forms, filters, and DTOs.\r\n *\r\n * Supports types: `string | number | boolean | Date | [Date, Date] (period) | array | object | nullable`.\r\n * Capabilities:\r\n * - normalize values according to config (trim strings, parse numbers from strings, boolean strings, etc.),\r\n * - transform date periods into paired keys (`from/to`) or a single joined string,\r\n * - build/parse a query string (or JSON) to and from an object.\r\n *\r\n * Example:\r\n * ```ts\r\n * type Filters = { q?: string; active?: boolean; created?: [Date, Date] | null };\r\n * const s = new Serializer<Filters>({\r\n * mapPeriod: { transformMode: { mode: 'split', dateFromKeyPostfix: 'From', dateToKeyPostfix: 'To' } }\r\n * });\r\n *\r\n * // -> { q: 'john', createdFrom: '2025-01-01', createdTo: '2025-01-31' }\r\n * const plain = s.serialize({\r\n * q: ' john ',\r\n * active: undefined,\r\n * created: [new Date('2025-01-01'), new Date('2025-01-31')]\r\n * });\r\n *\r\n * // -> 'q=john&createdFrom=2025-01-01&createdTo=2025-01-31'\r\n * const qs = s.toQuery({ q: 'john', created: [new Date('2025-01-01'), new Date('2025-01-31')] });\r\n *\r\n * // <- { q: 'john', created: [Date, Date] }\r\n * const parsed = s.deserialize('q=john&createdFrom=2025-01-01&createdTo=2025-01-31');\r\n * ```\r\n */\r\nexport class Serializer<EntityType extends DataType> {\r\n readonly config: SerializerConfig;\r\n\r\n /**\r\n * Creates a serializer with a partially overridden configuration.\r\n * Provide only the options you want to change (the rest are taken from defaults).\r\n *\r\n * @param config partial transformation configuration\r\n */\r\n constructor(config: Partial<SerializerConfig>) {\r\n this.config = {\r\n mapString: { trim: true },\r\n mapNumber: { fromString: false },\r\n mapBoolean: {},\r\n mapArray: { concatType: 'comma' },\r\n mapObject: { deep: true },\r\n mapDate: { dateFormat: 'yyyy-MM-dd' },\r\n mapPeriod: {\r\n dateFormat: 'yyyy-MM-dd',\r\n transformMode: { mode: 'split', dateFromKeyPostfix: 'From', dateToKeyPostfix: 'To' },\r\n },\r\n mapNullable: { remove: true, includeEmptyString: false },\r\n ...config,\r\n };\r\n }\r\n\r\n /**\r\n * Converts a domain object into a flat serialized representation\r\n * (ready to send to an API or build a query string).\r\n *\r\n * Rules are taken from `config`:\r\n * — strings can be trimmed (if enabled),\r\n * — numbers can be converted from strings/numbers,\r\n * — boolean supports custom true/false representations,\r\n * — dates are formatted by `dateFormat`,\r\n * — date periods can be split/joined,\r\n * — `nullable` can be removed from the result (`remove`) or formatted.\r\n *\r\n * @param obj source object\r\n * @returns a flat dictionary with string/primitive values\r\n */\r\n serialize(obj: EntityType): SerializedType {\r\n const result: SerializedType = {};\r\n\r\n for (const [key, value] of Object.entries(obj ?? {})) {\r\n const fields = this.config.mapFields?.[key];\r\n\r\n if (fields && 'format' in fields) {\r\n result[key] = fields.format(value, obj as EntityType);\r\n continue;\r\n }\r\n\r\n if (fields?.type === 'nullable' || isNullable(value, this.config.mapNullable?.includeEmptyString)) {\r\n if (this.config.mapNullable.remove) {\r\n continue;\r\n }\r\n }\r\n\r\n if (fields?.type === 'period' || isDatePeriod(value)) {\r\n const transform = this.config.mapPeriod.transformMode;\r\n const [from, to] = value;\r\n\r\n if (transform?.mode === 'split') {\r\n result[`${key}${transform.dateFromKeyPostfix}`] = formatDate(from, this.config.mapPeriod.dateFormat);\r\n result[`${key}${transform.dateToKeyPostfix}`] = formatDate(to, this.config.mapPeriod.dateFormat);\r\n continue;\r\n }\r\n }\r\n\r\n result[key] = this.serializeElement(value, key);\r\n }\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * Parse serialized data into a domain object.\r\n *\r\n * Source can be:\r\n * — a query string (`key=value&arr=1,2`) or `JSON.stringify(obj)`,\r\n * — an already prepared flat object.\r\n *\r\n * Transformations are reverse of `serialize`: strings → number/boolean/Date/period,\r\n * arrays are collected according to strategy (`comma`/`pipe`/`multi`), objects — deeply or as JSON.\r\n *\r\n * @param val query string or object\r\n * @returns a domain object of the specified type\r\n */\r\n deserialize = (val: string | AnyDict): EntityType => {\r\n const data: SerializedType = typeof val === 'string' ? this.parseQuery(val) : val;\r\n const result: AnyType = {};\r\n\r\n for (const [key, value] of Object.entries(data ?? {})) {\r\n const field = this.config.mapFields?.[key];\r\n\r\n if (field && 'parse' in field) {\r\n result[key] = field.parse(value, data);\r\n continue;\r\n }\r\n\r\n if (\r\n field?.type === 'nullable' ||\r\n (field?.type !== 'array' && isNullable(value, this.config.mapNullable?.includeEmptyString))\r\n ) {\r\n if (this.config.mapNullable.remove) {\r\n continue;\r\n }\r\n }\r\n\r\n const periodTransform = this.config.mapPeriod.transformMode!;\r\n\r\n if (periodTransform.mode === 'split') {\r\n const isFrom = (key || '').endsWith(periodTransform.dateFromKeyPostfix);\r\n const isTo = (key || '').endsWith(periodTransform.dateToKeyPostfix);\r\n const keyJoint = (key || '')\r\n .replace(periodTransform.dateFromKeyPostfix, '')\r\n .replace(periodTransform.dateToKeyPostfix, '');\r\n const field = this.config.mapFields?.[keyJoint];\r\n\r\n // @ts-ignore\r\n if (field?.['type'] === 'period' && (isFrom || isTo)) {\r\n result[keyJoint] ??= [null, null];\r\n\r\n if (isFrom) {\r\n result[keyJoint][0] = parseToDate(value, this.config.mapPeriod.dateFormat);\r\n } else if (isTo) {\r\n result[keyJoint][1] = parseToDate(value, this.config.mapPeriod.dateFormat);\r\n }\r\n\r\n continue;\r\n }\r\n }\r\n\r\n result[key] = this.deserializeElement(value, key);\r\n }\r\n\r\n return result;\r\n };\r\n\r\n /**\r\n * Build a query string from a domain object using `serialize` rules\r\n * and the array joining strategy (`concatType`).\r\n *\r\n * @param val domain object\r\n * @returns query string (suitable for URL or history API)\r\n */\r\n toQuery = (val: EntityType): string => {\r\n return makeQuery(this.serialize(val), this.config.mapArray.concatType);\r\n };\r\n\r\n /**\r\n * Returns a new serializer instance with a merged configuration.\r\n * Useful for ad-hoc overrides for a specific call.\r\n *\r\n * @param config partial config changes\r\n * @returns new `Serializer` with the provided `config` applied\r\n */\r\n withConfig(config: Partial<SerializerConfig>): Serializer<EntityType> {\r\n return new Serializer<EntityType>({ ...this.config, ...config });\r\n }\r\n\r\n private serializeElement(value: AnyType, key?: string): AnyType {\r\n const fields = this.config.mapFields?.[key || ''];\r\n\r\n if (fields && 'format' in fields) {\r\n return;\r\n }\r\n\r\n if (fields?.type === 'nullable' || isNullable(value, this.config.mapNullable?.includeEmptyString)) {\r\n const nullableVal = value || null;\r\n\r\n return this.config.mapNullable.format?.(nullableVal) || this.config.mapNullable.replaceWith || nullableVal;\r\n }\r\n\r\n if (fields?.type === 'string') {\r\n return serializeString(this.config, value);\r\n }\r\n\r\n if (fields?.type === 'number' || isNumber(value, this.config.mapNumber.fromString)) {\r\n return serializeNumber(this.config, value);\r\n }\r\n\r\n if (typeof value === 'string') {\r\n return serializeString(this.config, value);\r\n }\r\n\r\n if (fields?.type === 'boolean' || typeof value === 'boolean') {\r\n return serializeBoolean(this.config, value);\r\n }\r\n\r\n if (fields?.type === 'date' || value instanceof Date) {\r\n return serializeDate(this.config, value);\r\n }\r\n\r\n if (fields?.type === 'period' || isDatePeriod(value)) {\r\n const mapPeriod = this.config.mapPeriod;\r\n\r\n if (mapPeriod.format) {\r\n return mapPeriod.format(value);\r\n } else {\r\n const [from, to] = value;\r\n const transform = mapPeriod.transformMode!;\r\n\r\n if (transform.mode === 'join') {\r\n const period = [\r\n formatDate(from, this.config.mapPeriod.dateFormat),\r\n formatDate(to, this.config.mapPeriod.dateFormat),\r\n ];\r\n\r\n return period.join(transform.concat);\r\n }\r\n }\r\n }\r\n\r\n if (fields?.type === 'array' || Array.isArray(value)) {\r\n return (value as AnyType[]).map((it) => this.serializeElement(it));\r\n }\r\n\r\n if (fields?.type === 'object' || isObject(value)) {\r\n return (\r\n this.config.mapObject.format?.(value) ??\r\n (this.config.mapObject.deep ? this.serialize(value) : JSON.stringify(value))\r\n );\r\n }\r\n }\r\n\r\n private deserializeElement(value: AnyType, key?: string): AnyType {\r\n const field = this.config.mapFields?.[key || ''];\r\n\r\n if (field && 'format' in field) {\r\n return;\r\n }\r\n\r\n if (field?.type === 'array' || Array.isArray(value)) {\r\n const array = Array.isArray(value) ? value : [value];\r\n\r\n if (this.config.mapArray.removeNullable) {\r\n if (!isNullable(value, this.config.mapNullable?.includeEmptyString)) {\r\n return array.map((it) => this.deserializeElement(it));\r\n } else {\r\n return;\r\n }\r\n } else {\r\n return !value ? [] : array.map((it) => this.deserializeElement(it));\r\n }\r\n }\r\n\r\n if (field?.type === 'object') {\r\n try {\r\n if (this.config.mapObject.deep) {\r\n // @ts-ignore\r\n return this.deserializeElement(value);\r\n } else {\r\n // @ts-ignore\r\n return JSON.parse(value);\r\n }\r\n } catch {\r\n return value;\r\n }\r\n }\r\n\r\n if (field?.type === 'nullable' || isNullable(value, this.config.mapNullable?.includeEmptyString)) {\r\n return this.config.mapNullable.parse?.(value) || value;\r\n }\r\n\r\n if (\r\n field?.type === 'boolean' ||\r\n typeof value === 'boolean' ||\r\n value === this.config.mapBoolean.true ||\r\n value === this.config.mapBoolean.false\r\n ) {\r\n return this.config.mapBoolean.parse?.(value) ?? (value === this.config.mapBoolean.true || value === true);\r\n }\r\n\r\n const maybeDate = parseToDate(value, this.config.mapDate.dateFormat);\r\n\r\n if (field?.type === 'date' || maybeDate) {\r\n return this.config.mapDate.parse?.(value) || maybeDate;\r\n }\r\n\r\n const periodTransform = this.config.mapPeriod.transformMode!;\r\n\r\n if (periodTransform.mode === 'join') {\r\n const maybePeriod = parseToDatePeriod(value, this.config.mapPeriod.dateFormat);\r\n\r\n if (field?.type === 'period' || (maybePeriod || []).some(Boolean)) {\r\n return this.config.mapPeriod.parse?.(value) || maybePeriod;\r\n }\r\n }\r\n\r\n if (field?.type === 'number' || isNumber(value, this.config.mapNumber.fromString)) {\r\n return this.config.mapNumber.parse?.(value) || Number(String(value).trim());\r\n }\r\n\r\n if (field?.type === 'string' || typeof value === 'string') {\r\n return this.config.mapString.parse?.(value) || this.config.mapString.trim ? String(value).trim() : value;\r\n }\r\n\r\n return value;\r\n }\r\n\r\n private parseQuery(val: string) {\r\n try {\r\n return JSON.parse(val);\r\n } catch {\r\n const params = new URLSearchParams(val);\r\n const data: SerializedType = {};\r\n\r\n params.forEach((value, key) => {\r\n const field = this.config.mapFields?.[key] || {};\r\n const concatType = this.config.mapArray.concatType;\r\n\r\n if ('type' in field && field.type === 'array') {\r\n data[key] ??= [];\r\n concatType !== 'multi' && (data[key] = parseQueryArray(value, concatType, key));\r\n concatType === 'multi' && (data[key] as string[]).push(value);\r\n } else {\r\n data[key] = value;\r\n }\r\n });\r\n\r\n return data;\r\n }\r\n }\r\n}\r\n","import { StorageInterface } from './models';\r\n\r\nexport class LruCache<KeyT, ValueT> implements StorageInterface<KeyT, ValueT> {\r\n private map = new Map<KeyT, ValueT>();\r\n\r\n constructor(public limit: number = 100) {}\r\n\r\n get length(): number {\r\n return this.map.size;\r\n }\r\n\r\n get(key: KeyT) {\r\n if (!this.map.has(key)) {\r\n return null;\r\n }\r\n\r\n const val = this.map.get(key)!;\r\n\r\n this.map.delete(key);\r\n this.map.set(key, val);\r\n\r\n return val;\r\n }\r\n\r\n set(key: KeyT, value: ValueT) {\r\n if (this.map.has(key)) {\r\n this.map.delete(key);\r\n } else if (this.map.size === this.limit) {\r\n const oldest = this.map.keys().next().value;\r\n\r\n oldest !== undefined && this.map.delete(oldest);\r\n }\r\n\r\n this.map.set(key, value);\r\n }\r\n\r\n remove(key: KeyT): boolean {\r\n return this.map.delete(key);\r\n }\r\n\r\n clear(): void {\r\n this.map.clear();\r\n }\r\n\r\n has(key: KeyT): boolean {\r\n return this.map.has(key);\r\n }\r\n\r\n keys(): KeyT[] {\r\n return Array.from(this.map.keys());\r\n }\r\n\r\n values(): ValueT[] {\r\n return Array.from(this.map.values());\r\n }\r\n\r\n toArray(): ValueT[] {\r\n return Array.from(this.map.values());\r\n }\r\n\r\n fromArray(entries: [KeyT, ValueT][]) {\r\n this.map.clear();\r\n\r\n for (const [k, v] of entries) {\r\n this.set(k, v);\r\n }\r\n }\r\n}\r\n","import { AnyDict, AnyType } from '@reforgium/internal';\r\n\r\nimport { StorageInterface } from './models';\r\n\r\nexport class LocalStorage<Key = string, Type extends AnyType = AnyDict> implements StorageInterface<Key, Type> {\r\n constructor(public prefix = 're') {}\r\n\r\n get length() {\r\n return Object.keys(localStorage).filter((key) => key.startsWith(this.prefix || '')).length;\r\n }\r\n\r\n get(key: Key): Type | null {\r\n const raw = localStorage.getItem(this.getSafePrefix(key));\r\n const parsed = JSON.parse(raw ?? 'null');\r\n\r\n return (parsed as Type) ?? null;\r\n }\r\n\r\n set(key: Key, value: Type): void {\r\n const str = JSON.stringify(value);\r\n\r\n localStorage.setItem(this.getSafePrefix(key), str);\r\n }\r\n\r\n remove(key: Key): void {\r\n return localStorage.removeItem(this.getSafePrefix(key));\r\n }\r\n\r\n clear(): void {\r\n const keys = Object.keys(localStorage).filter((key) => key.startsWith(this.prefix || ''));\r\n\r\n keys.forEach((key) => localStorage.removeItem(key));\r\n }\r\n\r\n private getSafePrefix(key: Key): string {\r\n return this.prefix ? `${this.prefix}:${key}` : String(key);\r\n }\r\n}\r\n","import { AnyDict, AnyType } from '@reforgium/internal';\r\n\r\nimport { StorageInterface } from '.';\r\n\r\nexport class MemoryStorage<Key = string, Type extends AnyType = AnyDict> implements StorageInterface<Key, Type> {\r\n private cache = new Map<Key, Type>();\r\n\r\n get length() {\r\n return this.cache.size;\r\n }\r\n\r\n get(key: Key): Type | null {\r\n return this.cache.get(key) ?? null;\r\n }\r\n\r\n set(key: Key, value: Type): void {\r\n this.cache.set(key, value);\r\n }\r\n\r\n remove(key: Key): void {\r\n this.cache.delete(key);\r\n }\r\n\r\n clear(): void {\r\n this.cache.clear();\r\n }\r\n}\r\n","import { AnyDict, AnyType } from '@reforgium/internal';\r\n\r\nimport { StorageInterface } from './models';\r\n\r\nexport class SessionStorage<Key = string, Type extends AnyType = AnyDict> implements StorageInterface<Key, Type> {\r\n constructor(public prefix = 're') {}\r\n\r\n get length() {\r\n return Object.keys(sessionStorage).filter((key) => key.startsWith(this.prefix || '')).length;\r\n }\r\n\r\n get(key: Key): Type | null {\r\n const raw = sessionStorage.getItem(this.getSafePrefix(key));\r\n const parsed = JSON.parse(raw ?? 'null');\r\n\r\n return (parsed as Type) ?? null;\r\n }\r\n\r\n set(key: Key, value: Type): void {\r\n const str = JSON.stringify(value);\r\n\r\n sessionStorage.setItem(this.getSafePrefix(key), str);\r\n }\r\n\r\n remove(key: Key): void {\r\n return sessionStorage.removeItem(this.getSafePrefix(key));\r\n }\r\n\r\n clear(): void {\r\n const keys = Object.keys(sessionStorage).filter((key) => key.startsWith(this.prefix || ''));\r\n\r\n keys.forEach((key) => sessionStorage.removeItem(key));\r\n }\r\n\r\n private getSafePrefix(key: Key): string {\r\n return this.prefix ? `${this.prefix}:${key}` : String(key);\r\n }\r\n}\r\n","import { AnyDict, AnyType } from '@reforgium/internal';\r\n\r\nimport { LruCache, StorageInterface } from '../storages';\r\nimport { LocalStorage } from '../storages/local.storage';\r\nimport { MemoryStorage } from '../storages/memory.storage';\r\nimport { SessionStorage } from '../storages/session.storage';\r\nimport { StorageStrategy } from './models';\r\n\r\n/**\r\n * Factory for data storage strategies.\r\n *\r\n * Returns a `StorageInterface` implementation depending on the selected strategy:\r\n * - `'memory'` — in-memory storage (for the session lifetime);\r\n * - `'session'` — `sessionStorage`, lives until the tab is closed;\r\n * - `'persist'` — `localStorage`, persists between sessions;\r\n * - `'lru'` — size-limited cache (Least Recently Used).\r\n *\r\n * Used to choose an appropriate storage implementation\r\n * depending on the scenario: temporary data, long-term, cache, etc.\r\n *\r\n * @param strategy storage strategy type (`memory`, `session`, `persist`, `lru`)\r\n * @returns instance implementing `StorageInterface<Key, Type>`\r\n */\r\nexport const storageStrategy = <Key = string, Type extends AnyType = AnyDict>(\r\n strategy: StorageStrategy,\r\n): StorageInterface<Key, Type> => {\r\n const fabrics: Record<StorageStrategy, () => StorageInterface<Key, Type>> = {\r\n memory: () => new MemoryStorage<Key, Type>(),\r\n session: () => new SessionStorage<Key, Type>(),\r\n persist: () => new LocalStorage<Key, Type>(),\r\n lru: () => new LruCache<Key, Type>(),\r\n };\r\n\r\n return fabrics[strategy]();\r\n};\r\n","// noinspection ES6PreferShortImport\r\n\r\nimport { InjectionToken } from '@angular/core';\r\n\r\nimport { SerializerConfig } from './serializer';\r\nimport { DictStoreProviderConfig } from './stores/dict-store/dict.models';\r\nimport { PaginatedDataStoreProviderConfig } from './stores/paginated-data-store';\r\n\r\ntype PaginatedDataProviderConfig = { paginatedData?: PaginatedDataStoreProviderConfig };\r\ntype SerializerProviderConfig = { serializer?: Partial<SerializerConfig> };\r\ntype DictProviderConfig = { dict?: DictStoreProviderConfig };\r\n\r\ntype StatumConfig = PaginatedDataProviderConfig & SerializerProviderConfig & DictProviderConfig;\r\n\r\nexport const STATUM_CONFIG = new InjectionToken<StatumConfig>('RE_STATUM_CONFIG');\r\n","import { RestMethods } from '@reforgium/internal';\r\n\r\nimport { CallArgs } from './resource.models';\r\n\r\n/**\r\n * Error thrown when requested data is missing in the cache.\r\n *\r\n * Used by the `cache-only` strategy when data is not found\r\n * and a network request is not allowed.\r\n *\r\n * Example:\r\n * ```ts\r\n * try {\r\n * await store.get({ query }, { strategy: 'cache-only' });\r\n * } catch (e) {\r\n * if (e instanceof CacheMissError) console.warn(e.key, 'not found in cache');\r\n * }\r\n * ```\r\n */\r\nexport class CacheMissError extends Error {\r\n constructor(public readonly key: string) {\r\n super(`Cache miss for key: ${key}`);\r\n this.name = 'CacheMissError';\r\n }\r\n}\r\n\r\n/**\r\n * Error indicating an aborted (canceled) request.\r\n *\r\n * May be thrown by `abort()` or `abortAll()` in `ResourceStore`.\r\n * Usually does not require handling as an error — used to ignore canceled operations.\r\n */\r\nexport class AbortError extends Error {\r\n constructor(message = 'aborted') {\r\n super(message);\r\n this.name = 'AbortError';\r\n }\r\n}\r\n\r\n/**\r\n * Checks whether the exception is an `AbortError` (including compatible objects).\r\n *\r\n * @param e — any value that may be an error\r\n * @returns `true` if it's an `AbortError`\r\n */\r\nexport function isAbort(e: unknown): e is AbortError {\r\n return (\r\n e instanceof AbortError ||\r\n (typeof e === 'object' && e != null && (e as Error)?.name === 'AbortError' && (e as Error)?.message === 'aborted')\r\n );\r\n}\r\n\r\nexport function joinUrl(base: string | undefined, path: string): string {\r\n return base ? `${base.replace(/\\/$/, '')}/${path.replace(/^\\//, '')}` : path;\r\n}\r\n\r\nexport function buildKey(method: RestMethods, path: string, args: CallArgs): string {\r\n const params = Object.entries(args.params || {})\r\n .map(([key, value]) => `${key}=${value}`)\r\n .join('&');\r\n const query = Object.entries(args.query || {})\r\n .map(([key, value]) => `${key}=${value}`)\r\n .join('&');\r\n\r\n return `${method}|${path}|${params}|${query}`;\r\n}\r\n","import { filter, merge, Observable, Subject, Subscription, timer } from 'rxjs';\r\nimport { debounce as rxDebounce, finalize, tap, throttle as rxThrottle } from 'rxjs/operators';\r\n\r\nimport { AnyType } from '@reforgium/internal';\r\n\r\nimport { DelayMode } from './resource.models';\r\n// noinspection ES6PreferShortImport\r\nimport { AbortError } from './resource.utils';\r\n\r\ntype Waiter<T> = { resolve: (v: T) => void; reject: (e: unknown) => void };\r\n\r\ntype ScheduledTask<Data> = {\r\n mode: DelayMode;\r\n delay: number;\r\n exec: () => Observable<Data>;\r\n};\r\n\r\ntype Channel<Data> = {\r\n subject: Subject<ScheduledTask<Data>>;\r\n waiters: Waiter<Data>[];\r\n lastExec?: () => Observable<Data>;\r\n timerSub?: Subscription;\r\n inflight?: Subscription;\r\n};\r\n\r\n/**\r\n * Per-key task scheduler with `debounce`/`throttle` and result deduplication.\r\n *\r\n * Allows applying delays and rate limiting separately for each key.\r\n * All `schedule` calls for the same key are coalesced: consumers receive a single shared `Promise`\r\n * that resolves with the value of the last started task.\r\n *\r\n * Suitable for API requests, auto-saving forms, incremental search, etc.\r\n *\r\n * Example:\r\n * ```ts\r\n * const ks = new KeyedScheduler();\r\n * // these three calls collapse into one request after 300ms\r\n * ks.schedule('users:list', 'debounce', 300, () => http.get<User[]>('/api/users'));\r\n * ks.schedule('users:list', 'debounce', 300, () => http.get<User[]>('/api/users'));\r\n * const users = await ks.schedule('users:list', 'debounce', 300, () => http.get<User[]>('/api/users'));\r\n * ```\r\n */\r\nexport class KeyedScheduler {\r\n private channels = new Map<string, Channel<AnyType>>();\r\n\r\n /**\r\n * Schedule task execution for the specified key.\r\n *\r\n * Multiple calls with the same key are merged according to the mode:\r\n * `debounce` — runs the last task after a pause;\r\n * `throttle` — runs no more often than the specified delay (uses the last accumulated).\r\n *\r\n * All waiters receive the result of a single execution.\r\n *\r\n * @param key logical channel key (e.g., `'users:list'`)\r\n * @param mode delay mode (`'debounce' | 'throttle'`)\r\n * @param delay delay in milliseconds\r\n * @param exec Observable factory with the actual work (HTTP request, etc.)\r\n * @returns Promise with the result of `exec`\r\n */\r\n schedule<Data>(key: string, mode: DelayMode, delay: number, exec: () => Observable<Data>): Promise<Data> {\r\n const channel = this.ensureChannel<Data>(key);\r\n const promise = new Promise<Data>((resolve, reject) => {\r\n channel.waiters.push({ resolve, reject });\r\n });\r\n\r\n channel.lastExec = exec;\r\n\r\n if (delay <= 0) {\r\n this.startExecution(channel);\r\n } else {\r\n channel.subject.next({ mode, delay, exec });\r\n }\r\n\r\n return promise;\r\n }\r\n\r\n /**\r\n * Cancels scheduled/running tasks for a key.\r\n * All pending `Promise`s will be rejected with `AbortError` (or the provided reason).\r\n *\r\n * @param key channel key\r\n * @param reason cancellation reason (defaults to `AbortError('aborted')`)\r\n */\r\n cancel(key: string, reason: unknown = new AbortError()): void {\r\n const ch = this.channels.get(key);\r\n\r\n if (!ch) {\r\n return;\r\n }\r\n\r\n ch.timerSub?.unsubscribe();\r\n ch.inflight?.unsubscribe();\r\n ch.inflight = undefined;\r\n ch.subject.complete();\r\n\r\n const waiters = ch.waiters.splice(0);\r\n\r\n waiters.forEach((w) => w.reject(reason));\r\n\r\n this.channels.delete(key);\r\n }\r\n\r\n /**\r\n * Cancels all channels and their pending tasks.\r\n *\r\n * @param reason cancellation reason (defaults to `AbortError('aborted')`)\r\n */\r\n cancelAll(reason: unknown = new AbortError()) {\r\n for (const key of Array.from(this.channels.keys())) {\r\n this.cancel(key, reason);\r\n }\r\n }\r\n\r\n private ensureChannel<Type>(key: string): Channel<Type> {\r\n let ch = this.channels.get(key) as Channel<Type> | undefined;\r\n\r\n if (ch) {\r\n return ch;\r\n }\r\n\r\n const subject = new Subject<ScheduledTask<Type>>();\r\n\r\n ch = { subject, waiters: [] };\r\n this.channels.set(key, ch as Channel<Type>);\r\n\r\n const debounced$ = subject.pipe(\r\n filter((t) => t.mode === 'debounce'),\r\n rxDebounce((t) => timer(t.delay)),\r\n tap(() => this.startExecution(ch!)),\r\n );\r\n\r\n const throttled$ = subject.pipe(\r\n filter((t) => t.mode === 'throttle'),\r\n rxThrottle((t) => timer(t.delay), { leading: false, trailing: true }),\r\n tap(() => this.startExecution(ch!)),\r\n );\r\n\r\n ch.timerSub = merge(debounced$, throttled$)\r\n .pipe(finalize(() => this.channels.delete(key)))\r\n .subscribe();\r\n\r\n return ch;\r\n }\r\n\r\n private startExecution<T>(ch: Channel<T>) {\r\n const exec = ch.lastExec;\r\n\r\n if (!exec) {\r\n return;\r\n }\r\n\r\n ch.inflight?.unsubscribe();\r\n ch.inflight = exec().subscribe({\r\n next: (val) => {\r\n const waiters = ch.waiters.splice(0);\r\n\r\n waiters.forEach((w) => w.resolve(val));\r\n },\r\n error: (err) => {\r\n const waiters = ch.waiters.splice(0);\r\n\r\n waiters.forEach((w) => w.reject(err));\r\n },\r\n complete: () => (ch.inflight = undefined),\r\n });\r\n }\r\n}\r\n","import { HttpClient } from '@angular/common/http';\r\nimport { computed, inject, Signal, signal } from '@angular/core';\r\nimport { map, Observable } from 'rxjs';\r\nimport { finalize, tap } from 'rxjs/operators';\r\n\r\nimport { AnyDict, AnyType, fillUrlWithParams, RestMethods } from '@reforgium/internal';\r\n\r\nimport { Serializer } from '../../serializer';\r\nimport { STATUM_CONFIG } from '../../statum.provider';\r\nimport {\r\n CacheStrategy,\r\n CallArgs,\r\n CallConfig,\r\n DelayMode,\r\n ExecArgs,\r\n GetCallConfig,\r\n PayloadData,\r\n ResourceEntry,\r\n ResourceRoutesMap,\r\n ResourceStatus,\r\n ResourceStoreOptions,\r\n SimpleDict,\r\n} from './resource.models';\r\nimport { KeyedScheduler } from './resource.scheduler';\r\nimport { buildKey, CacheMissError, isAbort, joinUrl } from './resource.utils';\r\n\r\n/**\r\n * Store for REST resources with caching and request deduplication.\r\n *\r\n * Provides reactive access to current value, status, and error;\r\n * supports cache strategies (cache-first / cache-only / network-first),\r\n * TTL, delays (debounce/throttle), request cancellation, and auto-serialization of query/payload.\r\n *\r\n * Example:\r\n * ```ts\r\n * const store = new ResourceStore({ GET: '/users/:id' }, { baseUrl: '/api', ttlMs: 30_000 });\r\n *\r\n * effect(() => {\r\n * if (store.loading()) showSpinner();\r\n * if (store.error()) showError(store.error());\r\n * const user = store.value();\r\n * });\r\n *\r\n * await store.get({ params: { id: '42' }, query: { expand: ['roles'] } }, { strategy: 'cache-first', dedupe: true });\r\n * ```\r\n */\r\nexport class ResourceStore<Data> {\r\n private readonly http = inject(HttpClient);\r\n private readonly serializer = new Serializer<AnyDict>(inject(STATUM_CONFIG, { optional: true })?.serializer ?? {});\r\n\r\n #value = signal<Data | null>(null);\r\n #status = signal<ResourceStatus>('idle');\r\n #error = signal<unknown | null>(null);\r\n #activeRequests = signal(0);\r\n\r\n /**\r\n * Current resource value.\r\n * Returns `null` if no data yet or the request failed.\r\n */\r\n value: Signal<Data | null> = this.#value.asReadonly();\r\n\r\n /**\r\n * Current loading status of the resource: `idle | loading | stale | success | error`.\r\n */\r\n status: Signal<ResourceStatus> = this.#status.asReadonly();\r\n\r\n /**\r\n * Last error (if any). Otherwise `null`.\r\n */\r\n error: Signal<unknown | null> = this.#error.asReadonly();\r\n\r\n /**\r\n * Convenience loading flag: `true` when `loading` or `stale`.\r\n * Useful for spinners and disabling buttons.\r\n */\r\n loading: Signal<boolean> = computed(() => this.#activeRequests() > 0 || this.#status() === 'stale');\r\n\r\n private readonly routes: ResourceRoutesMap;\r\n private readonly opts: ResourceStoreOptions;\r\n private readonly entries = new Map<string, ResourceEntry<unknown>>();\r\n private readonly scheduler = new KeyedScheduler();\r\n\r\n /**\r\n * @param routes Map of path templates for methods (`GET/POST/...` → `/users/:id`)\r\n * @param opts Global options (baseUrl, ttlMs, delay, delayMode, presetQueries/payload, etc.)\r\n */\r\n constructor(routes: ResourceRoutesMap, opts: ResourceStoreOptions = {}) {\r\n this.routes = routes;\r\n this.opts = opts;\r\n }\r\n\r\n /**\r\n * Perform a GET request.\r\n *\r\n * Supports cache strategies (`strategy`), TTL (`ttlMs`), revalidation,\r\n * deduplication (`dedupe`), and response parsing (`parseResponse`).\r\n *\r\n * @param args { params, query }\r\n * @param cfg Call settings (strategy, ttlMs, revalidate, parseResponse, delay, delayMode, dedupe, promote)\r\n * @returns Deserialized `Data`\r\n */\r\n async get<\r\n Param extends SimpleDict = SimpleDict,\r\n Query extends PayloadData = PayloadData,\r\n Response extends AnyType = Data,\r\n >(args: CallArgs<Param, Query, never>, cfg: GetCallConfig<Response, Data> = {}): Promise<Data> {\r\n const url = this.buildUrl('GET', args);\r\n const key = buildKey('GET', url, args);\r\n const query = this.prepareQuery(args);\r\n\r\n const entry = this.ensureEntry<Data>(key);\r\n const strategy: CacheStrategy = cfg.strategy ?? 'network-first';\r\n const ttlMs = cfg.ttlMs ?? this.opts.ttlMs ?? 0;\r\n const fresh = entry.updatedAt != null && Date.now() - entry.updatedAt < ttlMs;\r\n\r\n if (cfg.dedupe && entry.inflight) {\r\n return entry.inflight as unknown as Promise<Data>;\r\n }\r\n\r\n if (strategy === 'cache-only') {\r\n if (fresh && entry.data != null) {\r\n this.promoteCurrent(entry, cfg.promote);\r\n\r\n return entry.data as Data;\r\n }\r\n\r\n throw new CacheMissError(key);\r\n }\r\n\r\n if (strategy === 'cache-first' && fresh && !cfg.revalidate && entry.data != null) {\r\n this.promoteCurrent(entry, cfg.promote);\r\n\r\n return entry.data as Data;\r\n }\r\n\r\n const delay = cfg.delay ?? this.opts.delay ?? 0;\r\n const mode: DelayMode = cfg.delayMode ?? this.opts.delayMode ?? 'debounce';\r\n\r\n const isSWR = strategy === 'cache-first' && entry.data != null;\r\n\r\n entry.status = isSWR ? 'stale' : 'loading';\r\n this.promoteCurrent(entry, cfg.promote);\r\n\r\n const task = this.scheduler.schedule(\r\n key,\r\n mode,\r\n delay,\r\n this.exec$({\r\n req$: this.http.get<Response>(url, { params: query }),\r\n entry,\r\n promote: cfg.promote,\r\n parseFn: cfg.parseResponse,\r\n }),\r\n );\r\n\r\n cfg.dedupe && (entry.inflight = task);\r\n void task.catch((e) => {\r\n if (!isAbort(e)) {\r\n throw e;\r\n }\r\n });\r\n\r\n return task;\r\n }\r\n\r\n /**\r\n * POST request.\r\n *\r\n * @param args { params, query, payload }\r\n * @param cfg Call settings (parseResponse, delay, delayMode, dedupe, promote)\r\n * @returns API response (by default — as returned by the server)\r\n */\r\n async post<\r\n Param extends SimpleDict = SimpleDict,\r\n Payload extends PayloadData = PayloadData,\r\n Query extends PayloadData = PayloadData,\r\n Response extends AnyType = AnyType,\r\n >(args: CallArgs<Param, Query, Payload>, cfg: CallConfig<Response, Response> = {}): Promise<Response> {\r\n return await this.callApi<Param, Payload, Query, Response>('POST', args, cfg);\r\n }\r\n\r\n /**\r\n * PUT request (full resource update).\r\n *\r\n * @param args { params, query, payload }\r\n * @param cfg Call settings (parseResponse, delay, delayMode, dedupe, promote)\r\n * @returns API response (by default — as returned by the server)\r\n */\r\n async put<\r\n Param extends SimpleDict = SimpleDict,\r\n Payload extends PayloadData = PayloadData,\r\n Query extends SimpleDict = SimpleDict,\r\n Response extends AnyType = AnyType,\r\n >(args: CallArgs<Param, Query, Partial<Payload>>, cfg: CallConfig<Response, Response> = {}): Promise<Response> {\r\n return await this.callApi<Param, Payload, Query, Response>('PUT', args, cfg);\r\n }\r\n\r\n /**\r\n * PATCH request (partial update).\r\n *\r\n * @param args { params, query, payload }\r\n * @param cfg Call settings (parseResponse, delay, delayMode, dedupe, promote)\r\n * @returns API response (by default — as returned by the server)\r\n */\r\n async patch<\r\n Param extends SimpleDict = SimpleDict,\r\n Payload extends PayloadData = PayloadData,\r\n Query extends SimpleDict = SimpleDict,\r\n Response extends AnyType = AnyType,\r\n >(args: CallArgs<Param, Query, Partial<Payload>>, cfg: CallConfig<Response, Response> = {}): Promise<Response> {\r\n return await this.callApi<Param, Payload, Query, Response>('PATCH', args, cfg);\r\n }\r\n\r\n /**\r\n * DELETE request.\r\n *\r\n * @param args { params, query, payload }\r\n * @param cfg Call settings (parseResponse, delay, delayMode, dedupe, promote)\r\n * @returns API response (by default — as returned by the server)\r\n */\r\n async delete<\r\n Param extends SimpleDict = SimpleDict,\r\n Payload extends PayloadData = PayloadData,\r\n Query extends SimpleDict = SimpleDict,\r\n Response extends AnyType = AnyType,\r\n >(args: CallArgs<Param, Query, Payload>, cfg: CallConfig<Response, Response> = {}): Promise<Response> {\r\n return await this.callApi<Param, Payload, Query, Response>('DELETE', args, cfg);\r\n }\r\n\r\n /**\r\n * Cancel scheduled/running requests for a specific call.\r\n *\r\n * @param method HTTP method\r\n * @param args Arguments used to build the URL (params, query)\r\n * @param reason Cancellation reason (optional)\r\n */\r\n abort<Param extends SimpleDict = SimpleDict, Query extends PayloadData = PayloadData>(\r\n method: RestMethods,\r\n args: CallArgs<Param, Query>,\r\n reason?: string | Error,\r\n ) {\r\n const url = this.buildUrl(method, args);\r\n const key = buildKey(method, url, args);\r\n\r\n this.scheduler.cancel?.(key, reason);\r\n }\r\n\r\n /**\r\n * Cancel all scheduled/running requests for this store.\r\n *\r\n * @param reason Cancellation reason (optional)\r\n */\r\n abortAll(reason?: string | Error) {\r\n this.scheduler.cancelAll?.(reason);\r\n }\r\n\r\n private ensureEntry<R>(key: string): ResourceEntry<R> {\r\n let entry = this.entries.get(key) as ResourceEntry<R> | undefined;\r\n\r\n if (!entry) {\r\n entry = { data: null, status: 'idle', error: null, updatedAt: null };\r\n this.entries.set(key, entry as ResourceEntry<unknown>);\r\n }\r\n\r\n return entry;\r\n }\r\n\r\n private async callApi<\r\n Param extends SimpleDict = SimpleDict,\r\n Payload extends PayloadData = PayloadData,\r\n Query extends SimpleDict = SimpleDict,\r\n Response extends AnyType = AnyType,\r\n >(\r\n method: RestMethods,\r\n args: CallArgs<Param, Query, Partial<Payload>>,\r\n config: CallConfig<Response, Response> = {},\r\n ): Promise<Response> {\r\n const url = this.buildUrl(method, args);\r\n const key = buildKey(method, url, args);\r\n const query = this.prepareQuery(args);\r\n const payload = { ...(this.opts.presetPayload || {}), ...(args.payload || {}) };\r\n const serializedPayload = this.serializer.serialize(payload);\r\n\r\n const entry = this.ensureEntry<Response>(key);\r\n\r\n if (config.dedupe && entry.inflight) {\r\n return entry.inflight as Promise<Response>;\r\n }\r\n\r\n const delay = config.delay ?? this.opts.delay ?? 0;\r\n const mode: DelayMode = config.delayMode ?? this.opts.delayMode ?? 'debounce';\r\n\r\n entry.status = 'loading';\r\n this.promoteCurrent(entry, config.promote);\r\n\r\n let req$: Observable<Response>;\r\n\r\n if (method === 'DELETE') {\r\n req$ = this.http.delete<Response>(url, { body: serializedPayload, params: query });\r\n } else {\r\n // @ts-ignore\r\n req$ = this.http[method.toLowerCase()]<Response>(url, serializedPayload, { params: query });\r\n }\r\n\r\n const task = this.scheduler.schedule<Response>(\r\n key,\r\n mode,\r\n delay,\r\n this.exec$<Response, Response>({ req$, entry, promote: config.promote, parseFn: config.parseResponse }),\r\n );\r\n\r\n config.dedupe && (entry.inflight = task);\r\n void task.catch((e) => {\r\n if (!isAbort(e)) {\r\n throw e;\r\n }\r\n });\r\n\r\n return task;\r\n }\r\n\r\n private buildUrl(method: RestMethods, args: CallArgs) {\r\n const tpl = this.routes[method];\r\n\r\n if (!tpl) {\r\n throw new Error(`${method} route not configured`);\r\n }\r\n\r\n const path = fillUrlWithParams(tpl, args.params);\r\n\r\n return joinUrl(this.opts.baseUrl, path);\r\n }\r\n\r\n private prepareQuery(args: CallArgs) {\r\n const mergedQuery = { ...(this.opts.presetQueries || {}), ...(args.query || {}) } as AnyDict;\r\n\r\n return this.serializer.serialize(mergedQuery) as SimpleDict;\r\n }\r\n\r\n private exec$ =\r\n <Response, Return = Data>({ req$, entry, promote = true, parseFn }: ExecArgs<Response, Return>) =>\r\n () => {\r\n promote && this.#activeRequests.update((n) => n + 1);\r\n\r\n return req$.pipe(\r\n map((data) => (parseFn ? parseFn(data) : (data as unknown as Return))),\r\n tap({\r\n next: (data) => {\r\n promote && (entry.data = data);\r\n entry.status = 'success';\r\n entry.updatedAt = Date.now();\r\n entry.error = null;\r\n this.promoteCurrent(entry, promote);\r\n },\r\n error: (err) => {\r\n entry.error = err;\r\n entry.status = 'error';\r\n this.promoteCurrent(entry, promote);\r\n },\r\n }),\r\n finalize(() => {\r\n entry.inflight = undefined;\r\n promote && this.#activeRequests.update((n) => Math.max(0, n - 1));\r\n this.promoteCurrent(entry, promote);\r\n }),\r\n );\r\n };\r\n\r\n private promoteCurrent(entry: ResourceEntry<unknown>, promote = true) {\r\n if (!promote) {\r\n return;\r\n }\r\n\r\n this.#value.set((entry.data as Data) ?? null);\r\n this.#status.set(entry.status);\r\n this.#error.set(entry.error);\r\n }\r\n}\r\n","// noinspection ES6PreferShortImport\r\n\r\nimport { DestroyRef, inject, signal, WritableSignal } from '@angular/core';\r\n\r\nimport { AnyDict, concatArray, deepEqual, isNullable, PageableResponse, Query, QueryParams } from '@reforgium/internal';\r\n\r\nimport { LruCache } from '../../cache/storages/lru.storage';\r\nimport { STATUM_CONFIG } from '../../statum.provider';\r\nimport { isAbort, ResourceStore } from '../../stores/resource-store';\r\n\r\nimport { PaginatedDataStoreConfig } from '.';\r\n\r\ntype PaginationType = {\r\n page?: number;\r\n first?: number | null;\r\n rows?: number | null;\r\n sortField?: string | string[] | null;\r\n sortOrder?: number | null;\r\n};\r\n\r\n/**\r\n * Store for paginated data (tables/lists) with per-page cache and unified requests.\r\n *\r\n * Provides:\r\n * - reactive signals: `items`, `loading`, `cached`;\r\n * - methods to control page/size/filters/sorting;\r\n * - optional LRU cache by pages;\r\n * - configurable transport (GET/POST/PATCH/…).\r\n *\r\n * Example:\r\n * ```ts\r\n * const ds = new PaginatedDataStore<User>('/users', { method: 'GET', hasCache: true });\r\n * await ds.updatePage(0); // load the first page\r\n * effect(() => console.log(ds.items(), ds.loading()));\r\n * ```\r\n */\r\nexport class PaginatedDataStore<ItemsType extends object, FilterType = unknown> {\r\n private readonly defaultConfig = inject(STATUM_CONFIG, { optional: true })?.paginatedData || {};\r\n\r\n #transport!: ResourceStore<PageableResponse<ItemsType> | ItemsType[]>;\r\n #cache: LruCache<number, ItemsType[]>;\r\n\r\n /** Current page data (reactive). */\r\n items: WritableSignal<ItemsType[]> = signal<ItemsType[]>([]);\r\n /** Merged cache of pages (flat list) — handy for search/export. */\r\n cached = signal<ItemsType[]>([]);\r\n /** Loading flag of the current operation. */\r\n loading = signal(false);\r\n\r\n /** Current filters (applied to requests). */\r\n filters: Partial<FilterType> = {};\r\n /** Current sorting (`field,asc|desc`). */\r\n sort?: string | ReadonlyArray<string>;\r\n\r\n /** Current page index (0-based). */\r\n page = 0;\r\n /** Default page size. */\r\n pageSize = 20;\r\n /** Total number of elements reported by the server. */\r\n totalElements = 0;\r\n routeParams: AnyDict = {};\r\n\r\n /**\r\n * @param route Resource URL pattern (e.g., `'/users'`)\r\n * @param config Store behavior: method, cache, request/response parsers, debounce, presets, etc.\r\n */\r\n constructor(\r\n private route: string,\r\n public config: PaginatedDataStoreConfig<ItemsType, FilterType> = {},\r\n ) {\r\n this.#cache = new LruCache<number, ItemsType[]>(config.cacheSize!);\r\n this.applyConfig(config);\r\n this.applyPresetMeta();\r\n this.initTransport();\r\n\r\n inject(DestroyRef).onDestroy(() => this.destroy());\r\n }\r\n\r\n /** Force reload current data (with the same page/filters/sort). */\r\n refresh() {\r\n return this.#fetchItems({});\r\n }\r\n\r\n /**\r\n * Switch page with a request.\r\n * If cache is enabled and the page is present in LRU — returns it from cache.\r\n * @param page page index (0-based)\r\n * @param ignoreCache ignore cache and fetch from network\r\n */\r\n updatePage = (page = this.page, ignoreCache = false) => {\r\n if (this.config.hasCache && this.#cache.has(page) && !ignoreCache) {\r\n const cached = this.#cache.get(page)!;\r\n\r\n this.items.set(cached);\r\n this.page = page;\r\n\r\n return Promise.resolve(cached);\r\n } else {\r\n return this.#fetchItems({ page });\r\n }\r\n };\r\n\r\n /**\r\n * Change page size (will go to the first page) and fetch.\r\n * @param size new size (rows per page)\r\n */\r\n updatePageSize = (size = this.pageSize) => {\r\n return this.#fetchItems({ page: 0, size });\r\n };\r\n\r\n /**\r\n * Update filters (goes to the first page) and fetch.\r\n * The previous cache is cleared.\r\n */\r\n updateFilters = (filters: Partial<FilterType>) => {\r\n this.#cache.clear();\r\n this.cached.set([]);\r\n\r\n return this.#fetchItems({ page: 0, filters: { ...this.filters, ...filters } });\r\n };\r\n\r\n /**\r\n * Update the state from table events (PrimeNG, etc.) and fetch.\r\n * Supports `page/first/rows/sortField/sortOrder`.\r\n */\r\n updateQuery = ({ page: pageNum, first = 0, rows = 0, sortOrder, sortField }: PaginationType) => {\r\n const page = (pageNum ?? (first && rows && Math.floor(first / rows))) || 0;\r\n const sort = sortField ? `${sortField},${sortOrder === 1 ? 'asc' : 'desc'}` : '';\r\n\r\n return this.#fetchItems({ page, sort });\r\n };\r\n\r\n /**\r\n * Set filters from scratch (goes to the first page and resets sorting) and fetch.\r\n * Useful for quick presets.\r\n */\r\n setFilters = (filters: Partial<FilterType> = {}) => {\r\n this.#cache.clear();\r\n this.cached.set([]);\r\n\r\n return this.#fetchItems({ page: 0, filters, sort: undefined });\r\n };\r\n\r\n /**\r\n * Change the resource route (resets page, cache, and presets) without fetching.\r\n * Useful when one store should work with different endpoints.\r\n */\r\n updateRoute = (route: string) => {\r\n this.route = route;\r\n this.page = 0;\r\n this.pageSize = 20;\r\n this.totalElements = 0;\r\n this.#cache.clear();\r\n this.cached.set([]);\r\n this.initTransport();\r\n };\r\n\r\n /**\r\n * Set route parameters (path variables) for the resource URL.\r\n * Does not trigger loading automatically — call `refresh()` or `updatePage()` after.\r\n *\r\n * @param params Dictionary of route parameters (e.g., `{ id: '123' }`)\r\n * @param opts Options object\r\n * @param opts.reset If `true` (default), resets page to 0, clears cache, total elements count, and items\r\n * @param opts.abort If `true`, aborts all active transport requests and sets loading to false\r\n *\r\n * @example\r\n * ```ts\r\n * store.setRouteParams({ userId: '42' });\r\n * await store.refresh(); // fetch with new params\r\n *\r\n * // Or with options:\r\n * store.setRouteParams({ userId: '42' }, { reset: false, abort: true });\r\n * ```\r\n */\r\n setRouteParams = (params: AnyDict = {}, opts: { reset?: boolean; abort?: boolean } = {}) => {\r\n const isChanged = !deepEqual(this.routeParams, params);\r\n\r\n if (!isChanged) {\r\n return;\r\n }\r\n\r\n this.routeParams = params;\r\n\r\n if (opts.reset) {\r\n this.page = 0;\r\n this.totalElements = 0;\r\n this.#cache.clear();\r\n this.cached.set([]);\r\n this.items.set([]);\r\n }\r\n\r\n if (opts?.abort) {\r\n try {\r\n this.#transport?.abortAll?.('Route params changed');\r\n } finally {\r\n this.loading.set(false);\r\n }\r\n }\r\n };\r\n\r\n /**\r\n * Update store config on the fly (without re-creation).\r\n * Does not trigger loading automatically.\r\n */\r\n updateConfig = (config: PaginatedDataStoreConfig<ItemsType>) => {\r\n this.config = { ...this.config, ...config };\r\n this.applyPresetMeta();\r\n };\r\n\r\n /**\r\n * Copy configuration and presets from another store of the same type.\r\n */\r\n copy(helper: PaginatedDataStore<ItemsType, FilterType>) {\r\n this.applyConfig(helper.config);\r\n this.applyPresetMeta();\r\n }\r\n\r\n /** Clean up resources and cancel active requests. Automatically called onDestroy. */\r\n destroy() {\r\n try {\r\n this.#transport?.abortAll?.('PaginatedDataStore destroyed');\r\n } catch (e: unknown) {\r\n if (!isAbort(e)) {\r\n throw e;\r\n }\r\n }\r\n }\r\n\r\n #fetchItems = async ({\r\n page = this.page,\r\n size = this.pageSize,\r\n sort = this.sort,\r\n filters = this.filters,\r\n }: QueryParams<FilterType>) => {\r\n const query = this.parseQuery({ page, size, sort, filters });\r\n\r\n this.loading.set(true);\r\n this.#transport.abortAll();\r\n\r\n try {\r\n const response = await this.runTransport(filters, query);\r\n\r\n this.page = page;\r\n this.sort = sort;\r\n this.filters = filters;\r\n\r\n const parsed = await this.parseResponseData(response);\r\n\r\n this.pageSize = parsed.pageable?.pageSize || size;\r\n this.totalElements = parsed.totalElements;\r\n this.items.set(parsed.content);\r\n this.updateCache(parsed.content);\r\n\r\n return parsed.content;\r\n } catch (e) {\r\n if (isAbort(e)) {\r\n return;\r\n }\r\n\r\n throw e;\r\n } finally {\r\n this.loading.set(false);\r\n }\r\n };\r\n\r\n private initTransport() {\r\n this.#transport = new ResourceStore<PageableResponse<ItemsType> | ItemsType[]>(\r\n { [this.config.method || 'GET']: this.route },\r\n {\r\n delay: this.config.debounceTime,\r\n delayMode: 'debounce',\r\n presetQueries: { page: this.page, size: this.pageSize, sort: this.sort },\r\n presetPayload: this.filters,\r\n },\r\n );\r\n }\r\n\r\n private async runTransport(payload: Partial<FilterType>, query: Query) {\r\n const params = this.routeParams;\r\n\r\n if (this.config.method === 'GET') {\r\n return this.#transport.get<AnyDict, AnyDict>({ query, params }, { promote: false, dedupe: true });\r\n }\r\n\r\n const method = this.config.method?.toLowerCase() || 'post';\r\n\r\n // @ts-ignore\r\n return this.#transport[method]<AnyDict, AnyDict, Partial<FilterType>, PageableResponse<ItemsType> | ItemsType[]>(\r\n { query, payload, params },\r\n { promote: false, dedupe: true },\r\n );\r\n }\r\n\r\n private parseQuery({ page = 0, size, sort, filters }: QueryParams<FilterType>) {\r\n const method = this.config.method || 'GET';\r\n const requestPayload = { page, size, ...(method === 'GET' ? filters : {}) };\r\n const rawQueries = this.config.parseRequest?.({ ...requestPayload, sort }) || requestPayload;\r\n const queries: Query = {};\r\n\r\n Object.entries(rawQueries).forEach(([key, value]) => {\r\n if (Array.isArray(value)) {\r\n queries[key] = concatArray(value, 'comma');\r\n } else if (!isNullable(value)) {\r\n queries[key] = value;\r\n }\r\n });\r\n sort && (queries['sort'] = sort);\r\n\r\n return queries;\r\n }\r\n\r\n private parseResponseData = async (\r\n data: PageableResponse<ItemsType> | ItemsType[],\r\n ): Promise<PageableResponse<ItemsType>> => {\r\n if (this.config?.parseResponse) {\r\n // noinspection ES6RedundantAwait\r\n return await this.config.parseResponse(data);\r\n }\r\n\r\n if (Array.isArray(data)) {\r\n return this.parseFlatArray(data);\r\n }\r\n\r\n return data as PageableResponse<ItemsType>;\r\n };\r\n\r\n private updateCache = (data: ItemsType[]) => {\r\n if (this.config.hasCache) {\r\n this.#cache.set(this.page, data);\r\n }\r\n\r\n this.cached.set(Array.from(this.#cache.values()).flat());\r\n };\r\n\r\n private parseFlatArray(data: ItemsType[]): PageableResponse<ItemsType> {\r\n return { content: data, totalElements: data.length };\r\n }\r\n\r\n private applyConfig(config: PaginatedDataStoreConfig<ItemsType, FilterType>) {\r\n this.config = {\r\n ...config,\r\n method: config.method || this.defaultConfig.defaultMethod || 'POST',\r\n presetQuery: config.presetQuery || this.defaultConfig.defaultQuery,\r\n parseRequest: config.parseRequest || this.defaultConfig.defaultParseRequest,\r\n debounceTime: config.debounceTime || 0,\r\n hasCache: config.hasCache === undefined ? this.defaultConfig.defaultHasCache : config.hasCache,\r\n cacheSize: config.cacheSize || this.defaultConfig.defaultCacheSize || 5,\r\n };\r\n }\r\n\r\n private applyPresetMeta() {\r\n this.filters = this.config.presetFilters || {};\r\n this.pageSize = this.config.presetQuery?.pageSize || 20;\r\n this.page = this.config.presetQuery?.page || 0;\r\n this.sort = this.config.presetQuery?.sort;\r\n }\r\n}\r\n","import { computed, effect, EffectRef, inject, signal, untracked } from '@angular/core';\r\n\r\nimport { AnyDict, debounceSignal } from '@reforgium/internal';\r\n\r\nimport { LruCache, StorageInterface, StorageStrategy, storageStrategy } from '../../cache';\r\nimport { STATUM_CONFIG } from '../../statum.provider';\r\n// noinspection ES6PreferShortImport\r\nimport { PaginatedDataStore } from '../../stores/paginated-data-store';\r\nimport { DictStoreConfig, FilterType, ValueType } from './dict.models';\r\n\r\n/**\r\n * Dictionary store (select/options) with local LRU cache and optional persistence.\r\n *\r\n * Provides:\r\n * - reactive `items` (current list) and `options` (label/value),\r\n * - local cache filtering (`fixed: true`) or server-side search by name (`fixed: false`),\r\n * - preload and restore cache from `storage` (`localStorage/session/LRU`),\r\n * - smooth integration with `PaginatedDataStore` for server fetching.\r\n *\r\n * Example:\r\n * ```ts\r\n * const dict = new DictStore<Country>('/countries', 'countries', { labelKey: 'name', valueKey: 'code' });\r\n * dict.search('ki'); // filters locally (fixed=true) or goes to server (fixed=false)\r\n * effect(() => console.log(dict.options())); // [{label:'Kyrgyzstan', value: 'KG'}, ...]\r\n * ```\r\n */\r\nexport class DictStore<Type extends AnyDict> {\r\n static readonly MAX_CACHE_SIZE = 400;\r\n\r\n /**\r\n * Default dictionary configuration resolved from {@link STATUM_CONFIG}.\r\n *\r\n * Used as a global fallback when local configuration does not explicitly\r\n */\r\n defaultConfig = inject(STATUM_CONFIG, { optional: true })?.dict || {};\r\n\r\n #helper: PaginatedDataStore<Type, FilterType>;\r\n #lru = new LruCache<string, Type>(DictStore.MAX_CACHE_SIZE);\r\n #effectRefs: EffectRef[] = [];\r\n\r\n private readonly fixed: boolean = true;\r\n private readonly labelKey: keyof Type & string;\r\n private readonly valueKey: keyof Type & string;\r\n private readonly maxOptionsSize?: number;\r\n private readonly storage?: StorageInterface<string, Type[]>;\r\n\r\n /**\r\n * Search text.\r\n * With `fixed: true` filters the local cache; with `fixed: false` triggers server search.\r\n */\r\n searchText = signal<string>('');\r\n\r\n private debouncedSearchText = debounceSignal(this.searchText, 300);\r\n\r\n /**\r\n * Additional filters for server request (or presets).\r\n */\r\n filters = signal<AnyDict>({});\r\n\r\n private cachedItems = signal<readonly Type[]>([]);\r\n\r\n /**\r\n * Current list of dictionary items.\r\n * Source — local cache (fixed=true) or data from `PaginatedDataStore`.\r\n */\r\n items = computed<readonly Type[]>(() => {\r\n const cached = this.cachedItems();\r\n\r\n if (!this.fixed) {\r\n return this.debouncedSearchText() || !cached.length ? this.#helper.items() : cached;\r\n }\r\n\r\n return cached.length ? this.filterLocal() : this.#helper.items();\r\n });\r\n\r\n /**\r\n * Ready-to-use dropdown options: `{ label, value }`.\r\n * Respects `maxOptionsSize` for truncating the list.\r\n */\r\n options = computed(() => {\r\n const options = this.items().map((it) => ({ label: String(it[this.labelKey] ?? ''), value: it[this.valueKey] }));\r\n\r\n return this.maxOptionsSize ? options.slice(0, this.maxOptionsSize) : options;\r\n });\r\n private _lastPromise: Promise<unknown> | null = null;\r\n private _armed = signal(false);\r\n\r\n // todo add i18n support\r\n /**\r\n * @param apiUrl dictionary endpoint (e.g., `'/api/dicts/countries'`)\r\n * @param storageKey key for saving cache in the selected strategy\r\n * @param cfg behavior (fixed/search, parsers, label/value keys, cache strategy, etc.)\r\n */\r\n constructor(\r\n private apiUrl: string,\r\n private storageKey: string,\r\n {\r\n autoLoad = true,\r\n method = this.defaultConfig.defaultRestMethod,\r\n presetFilters = this.defaultConfig.defaultPresetFilters,\r\n parseResponse,\r\n parseRequest,\r\n debounceTime = this.defaultConfig.defaultDebounceTime,\r\n fixed = true,\r\n maxOptionsSize = this.defaultConfig.defaultMaxOptionsSize,\r\n labelKey = this.defaultConfig.defaultLabelKey || 'name',\r\n valueKey = this.defaultConfig.defaultValueKey || 'code',\r\n keyPrefix = this.defaultConfig.defaultPrefix || 're',\r\n cacheStrategy = this.defaultConfig.defaultCacheStrategy || 'persist',\r\n }: DictStoreConfig<Type>,\r\n ) {\r\n this.#helper = new PaginatedDataStore<Type, FilterType>(this.apiUrl, {\r\n method: method,\r\n hasCache: false,\r\n presetFilters: { name: '', ...presetFilters },\r\n parseResponse: parseResponse,\r\n parseRequest: parseRequest,\r\n debounceTime: debounceTime,\r\n });\r\n this.fixed = fixed;\r\n this.labelKey = labelKey;\r\n this.valueKey = valueKey;\r\n this.maxOptionsSize = maxOptionsSize;\r\n\r\n if (cacheStrategy !== 'memory') {\r\n this.storage = storageStrategy<string, Type[]>(cacheStrategy as StorageStrategy);\r\n this.storage.prefix = keyPrefix;\r\n }\r\n\r\n this.setAutoload(autoLoad);\r\n\r\n this.restoreFromStorage();\r\n\r\n this.#effectRefs.push(\r\n effect(() => {\r\n const incoming = this.#helper.items();\r\n\r\n if (incoming.length === 0) {\r\n return;\r\n }\r\n\r\n untracked(() => this.mergeIntoCache(incoming));\r\n }),\r\n );\r\n\r\n this.#effectRefs.push(\r\n effect(() => {\r\n if (!this._armed()) {\r\n return;\r\n }\r\n\r\n const rest = this.filters();\r\n\r\n if (!this.fixed) {\r\n const query = this.debouncedSearchText().trim();\r\n\r\n untracked(() => {\r\n this._lastPromise = this.#helper.updateFilters({ name: query, ...rest });\r\n });\r\n } else if (!this.cachedItems().length) {\r\n untracked(() => {\r\n this._lastPromise = this.#helper.updateFilters({ name: '', ...rest });\r\n });\r\n }\r\n }),\r\n );\r\n }\r\n\r\n /** Restore cache from the selected storage (`persist`/`session`/`lru`/`memory`). */\r\n restoreCache() {\r\n this.restoreFromStorage();\r\n }\r\n\r\n /**\r\n * Set a search query and filters.\r\n * With `fixed: false` initiates server search; with `fixed: true` — local filtering.\r\n */\r\n search = (name = '', filters: AnyDict = {}) => {\r\n this._armed.set(true);\r\n this.searchText.set(name);\r\n this.filters.set(filters);\r\n };\r\n\r\n /**\r\n * Find display label by value (typically for reverse binding).\r\n * @returns label string or `undefined` if not found\r\n */\r\n findLabel = (value: ValueType): string | undefined => {\r\n for (const item of this.cachedItems()) {\r\n if (item[this.valueKey] === value) {\r\n return String(item[this.labelKey] ?? undefined);\r\n }\r\n }\r\n\r\n return undefined;\r\n };\r\n\r\n /**\r\n * Preload dictionary items into a local cache.\r\n * Useful for SSR/static lists/quick presets.\r\n *\r\n * @param items list of items\r\n * @param opts `{ replace?: true }` — completely replace current cache\r\n */\r\n preload = (items: readonly Type[], opts?: { replace?: boolean }) => {\r\n opts?.replace && this.#lru.clear();\r\n let changed = false;\r\n\r\n for (const it of items) {\r\n const key = this.keyOf(it);\r\n\r\n if (!key) {\r\n continue;\r\n }\r\n\r\n const existed = this.#lru.has(key);\r\n\r\n this.#lru.set(key, it);\r\n !existed && (changed = true);\r\n }\r\n\r\n if (changed || opts?.replace) {\r\n const arr = this.#lru.toArray();\r\n\r\n this.cachedItems.set(arr);\r\n this.storage?.set(this.storageKey, arr.slice(0, DictStore.MAX_CACHE_SIZE));\r\n }\r\n };\r\n\r\n /** Release resources and stop internal effects. */\r\n dispose() {\r\n this.#effectRefs.forEach((e) => e.destroy());\r\n this.#effectRefs = [];\r\n }\r\n\r\n /** Syntactic sugar for `using`/`Symbol.dispose`. */\r\n [Symbol.dispose]() {\r\n this.dispose();\r\n }\r\n\r\n private mergeIntoCache(items: Type[]) {\r\n let changed = 0;\r\n\r\n for (const it of items) {\r\n const key = this.keyOf(it);\r\n const before = this.#lru.has(key);\r\n\r\n this.#lru.set(key, it);\r\n !before && changed++;\r\n }\r\n\r\n if (changed > 0) {\r\n const arr = this.#lru.toArray();\r\n\r\n this.cachedItems.set(arr);\r\n this.storage?.set(this.storageKey, arr.slice(0, DictStore.MAX_CACHE_SIZE));\r\n }\r\n }\r\n\r\n private restoreFromStorage() {\r\n try {\r\n const array = this.storage?.get(this.storageKey);\r\n\r\n if (!array) {\r\n return;\r\n }\r\n\r\n for (const it of array) {\r\n const key = this.keyOf(it);\r\n\r\n this.#lru.set(key, it);\r\n }\r\n\r\n this.cachedItems.set(this.#lru.toArray());\r\n } catch {\r\n try {\r\n this.storage?.remove(this.storageKey);\r\n } catch {\r\n /* noop */\r\n }\r\n }\r\n }\r\n\r\n private filterLocal() {\r\n const list = this.cachedItems();\r\n const query = (this.fixed ? this.searchText() : this.debouncedSearchText()).toLowerCase();\r\n\r\n if (!query) {\r\n return list;\r\n }\r\n\r\n const key = this.labelKey;\r\n const out: Type[] = [];\r\n\r\n for (let i = 0; i < list.length; i++) {\r\n const val = list[i][key];\r\n\r\n val.toLowerCase().includes(query) && out.push(list[i]);\r\n }\r\n\r\n return out;\r\n }\r\n\r\n private keyOf(it: Type) {\r\n const raw = it[this.valueKey] as unknown;\r\n\r\n if (raw == null) {\r\n return '';\r\n }\r\n\r\n return typeof raw === 'string' ? raw : String(raw);\r\n }\r\n\r\n private setAutoload(autoLoad: boolean | 'whenEmpty') {\r\n if (autoLoad === 'whenEmpty') {\r\n const isEmpty = !this.storage?.get(this.storageKey)?.length;\r\n\r\n this._armed.set(isEmpty);\r\n } else {\r\n this._armed.set(autoLoad);\r\n }\r\n }\r\n}\r\n","import { computed, inject, signal } from '@angular/core';\r\n\r\nimport { AnyDict } from '@reforgium/internal';\r\n\r\nimport { STATUM_CONFIG } from '../../statum.provider';\r\nimport { DictLocalConfig, ValueType } from './dict.models';\r\n\r\nexport class DictLocalStore<Type extends AnyDict> {\r\n /**\r\n * Default dictionary configuration resolved from {@link STATUM_CONFIG}.\r\n *\r\n * Used as a global fallback when local configuration does not explicitly\r\n * define dictionary keys.\r\n */\r\n defaultConfig = inject(STATUM_CONFIG, { optional: true })?.dict || {};\r\n\r\n /**\r\n * Source dictionary items.\r\n *\r\n * Represents the full, unfiltered list of dictionary entries.\r\n * Used as the base data set for search and option generation.\r\n */\r\n items = signal<readonly Type[]>([]);\r\n #draftItems = signal<readonly Type[]>([]);\r\n\r\n /**\r\n * Computed list of options in `{ label, value }` format.\r\n *\r\n * Based on the current draft items (after search/filtering).\r\n * Respects `maxOptionsSize` to limit the number of generated options.\r\n *\r\n * Intended for direct use in dropdowns and select-like components.\r\n */\r\n options = computed(() => {\r\n const options = this.#draftItems().map((it) => ({\r\n label: String(it[this.labelKey] ?? ''),\r\n value: it[this.valueKey],\r\n }));\r\n\r\n return this.maxOptionsSize ? options.slice(0, this.maxOptionsSize) : options;\r\n });\r\n\r\n private readonly labelKey: keyof Type & string;\r\n private readonly valueKey: keyof Type & string;\r\n private readonly maxOptionsSize?: number;\r\n\r\n constructor(items: Type[], config?: DictLocalConfig<Type>) {\r\n this.labelKey = config?.labelKey ?? (this.defaultConfig.defaultLabelKey || 'name');\r\n this.valueKey = config?.valueKey ?? (this.defaultConfig.defaultValueKey || 'code');\r\n this.maxOptionsSize = config?.maxOptionsSize ?? 1000;\r\n\r\n this.items.set(items);\r\n this.#draftItems.set(items);\r\n }\r\n\r\n // noinspection JSUnusedGlobalSymbols\r\n /**\r\n * Restore cached dictionary state.\r\n *\r\n * This implementation is a no-op and exists only for API compatibility\r\n * with {@link DictStore}.\r\n */\r\n restoreCache() {}\r\n\r\n /**\r\n * Resolve display label by value.\r\n *\r\n * Performs a linear search over dictionary items and returns\r\n * the corresponding label for the given value.\r\n *\r\n * Commonly used for reverse binding (value → label).\r\n *\r\n * @param value Dictionary value to look up\r\n * @returns Resolved label string, or `undefined` if not found\r\n */\r\n findLabel = (value: ValueType): string | undefined => {\r\n for (const item of this.items()) {\r\n if (item[this.valueKey] === value) {\r\n return String(item[this.labelKey] ?? undefined);\r\n }\r\n }\r\n\r\n return undefined;\r\n };\r\n\r\n /**\r\n * Filter dictionary items by label.\r\n *\r\n * Applies a case-insensitive substring match against the label field\r\n * and updates the internal draft items used for option generation.\r\n *\r\n * Passing an empty string resets the filter and restores all items.\r\n *\r\n * @param name Search query string\r\n */\r\n search = (name = '') => {\r\n const items = this.items();\r\n\r\n if (name?.length) {\r\n this.#draftItems.set(\r\n items.filter((item) => String(item[this.labelKey]).toLowerCase().includes(name.toLowerCase())),\r\n );\r\n } else {\r\n this.#draftItems.set(items);\r\n }\r\n };\r\n\r\n /**\r\n * Preload additional dictionary items.\r\n *\r\n * Can either replace the current items completely or append\r\n * new entries to the existing list.\r\n *\r\n * Updates both the source items and the current draft items.\r\n *\r\n * @param items Items to preload\r\n * @param opts Preload options\r\n * @param opts.replace When `true`, replaces existing items instead of appending\r\n */\r\n preload = (items: readonly Type[], opts?: { replace?: boolean }) => {\r\n if (opts?.replace) {\r\n this.items.set(items);\r\n this.#draftItems.set(items);\r\n } else {\r\n const patch = [...this.items(), ...items] as readonly Type[];\r\n\r\n this.items.set(patch);\r\n this.#draftItems.set(patch);\r\n }\r\n };\r\n}\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["rxDebounce","rxThrottle"],"mappings":"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"}
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.1.0",
2
+ "version": "2.0.0",
3
3
  "name": "@reforgium/statum",
4
4
  "description": "reforgium State modules",
5
5
  "author": "rtommievich",
@@ -1,6 +1,7 @@
1
- import { AnyDict, AnyType, RestMethods, PageableRequest, Query, PageableResponse } from '@reforgium/internal';
1
+ import { AnyType, AnyDict, RestMethods, PageableRequest, Query, PageableResponse } from '@reforgium/internal';
2
2
  import * as _angular_core from '@angular/core';
3
- import { InjectionToken, Signal, WritableSignal } from '@angular/core';
3
+ import { Signal, WritableSignal, InjectionToken } from '@angular/core';
4
+ import * as _reforgium_statum from '@reforgium/statum';
4
5
 
5
6
  /**
6
7
  * List of supported primitive and composite data types
@@ -207,11 +208,10 @@ declare class Serializer<EntityType extends DataType> {
207
208
  private parseQuery;
208
209
  }
209
210
 
210
- declare const SERIALIZER_CONFIG: InjectionToken<Partial<SerializerConfig>>;
211
-
212
211
  type StorageStrategy = 'memory' | 'lru' | 'session' | 'persist';
213
212
 
214
213
  type StorageInterface<Key, Type> = {
214
+ prefix?: string;
215
215
  get(key: Key): Type | null;
216
216
  set(key: Key, value: Type): void;
217
217
  remove(key: Key): void;
@@ -520,7 +520,7 @@ declare function isAbort(e: unknown): e is AbortError;
520
520
  * Controls request method, page cache, debounce delay, and
521
521
  * request/response transformations.
522
522
  */
523
- type PaginatedDataConfig<ItemsType extends object, FilterType = unknown> = {
523
+ type PaginatedDataStoreConfig<ItemsType extends object, FilterType = unknown> = {
524
524
  /** Transport HTTP method: `GET`/`POST`/`PATCH`/`PUT`/`DELETE`. Defaults to global config or `POST`. */
525
525
  method?: RestMethods;
526
526
  /** Enable LRU cache for pages. */
@@ -552,20 +552,18 @@ type PaginatedDataConfig<ItemsType extends object, FilterType = unknown> = {
552
552
  * Global defaults for `PaginatedDataStore`.
553
553
  * Can be provided via DI to avoid duplicating config in each store.
554
554
  */
555
- interface PaginatedDataStoreConfig {
555
+ type PaginatedDataStoreProviderConfig = {
556
556
  /** Default method for all stores (if not overridden locally). */
557
557
  defaultMethod?: RestMethods;
558
558
  /** Default base `page/pageSize/sort`. */
559
- defaultQuery?: PaginatedDataConfig<object>['presetQuery'];
559
+ defaultQuery?: PaginatedDataStoreConfig<object>['presetQuery'];
560
560
  /** Global `parseRequest` — maps pagination/sort into a query object. */
561
- defaultParseRequest?: PaginatedDataConfig<object>['parseRequest'];
561
+ defaultParseRequest?: PaginatedDataStoreConfig<object>['parseRequest'];
562
562
  /** Whether to enable page cache by default. */
563
563
  defaultHasCache?: boolean;
564
564
  /** Default LRU page cache size. */
565
565
  defaultCacheSize?: number;
566
- }
567
-
568
- declare const PDS_CONFIG: InjectionToken<PaginatedDataStoreConfig>;
566
+ };
569
567
 
570
568
  type PaginationType = {
571
569
  page?: number;
@@ -593,7 +591,7 @@ type PaginationType = {
593
591
  declare class PaginatedDataStore<ItemsType extends object, FilterType = unknown> {
594
592
  #private;
595
593
  private route;
596
- config: PaginatedDataConfig<ItemsType, FilterType>;
594
+ config: PaginatedDataStoreConfig<ItemsType, FilterType>;
597
595
  private readonly defaultConfig;
598
596
  /** Current page data (reactive). */
599
597
  items: WritableSignal<ItemsType[]>;
@@ -616,7 +614,7 @@ declare class PaginatedDataStore<ItemsType extends object, FilterType = unknown>
616
614
  * @param route Resource URL pattern (e.g., `'/users'`)
617
615
  * @param config Store behavior: method, cache, request/response parsers, debounce, presets, etc.
618
616
  */
619
- constructor(route: string, config?: PaginatedDataConfig<ItemsType, FilterType>);
617
+ constructor(route: string, config?: PaginatedDataStoreConfig<ItemsType, FilterType>);
620
618
  /** Force reload current data (with the same page/filters/sort). */
621
619
  refresh(): Promise<ItemsType[] | undefined>;
622
620
  /**
@@ -677,7 +675,7 @@ declare class PaginatedDataStore<ItemsType extends object, FilterType = unknown>
677
675
  * Update store config on the fly (without re-creation).
678
676
  * Does not trigger loading automatically.
679
677
  */
680
- updateConfig: (config: PaginatedDataConfig<ItemsType>) => void;
678
+ updateConfig: (config: PaginatedDataStoreConfig<ItemsType>) => void;
681
679
  /**
682
680
  * Copy configuration and presets from another store of the same type.
683
681
  */
@@ -709,10 +707,21 @@ type DictStoreConfig<ItemsType extends object> = {
709
707
  * ('lru' is excluded: used internally for inner structures)
710
708
  */
711
709
  cacheStrategy?: Omit<StorageStrategy, 'lru'>;
710
+ /**
711
+ * Optional prefix applied to all storage keys.
712
+ *
713
+ * Used to isolate keys within preventing collisions
714
+ * between different modules or instances.
715
+ *
716
+ * Example:
717
+ * - keyPrefix: 'user'
718
+ * - stored key: 'user:settings'
719
+ */
720
+ keyPrefix?: string;
712
721
  /** Initial filters (added to the first request/filtering). */
713
722
  presetFilters?: Record<string, string>;
714
723
  /** Autoload data on initialization (`true` by default). */
715
- autoLoad?: boolean;
724
+ autoLoad?: boolean | 'whenEmpty';
716
725
  /**
717
726
  * Custom mapper of pagination/sort request into query params.
718
727
  * Useful if the API expects non-standard field names.
@@ -749,6 +758,39 @@ type DictLocalConfig<ItemsType extends object> = {
749
758
  /** Field key for value in a dictionary item. Defaults to `'code'`. */
750
759
  valueKey?: keyof ItemsType & string;
751
760
  };
761
+ type DictStoreProviderConfig = {
762
+ /**
763
+ * Cache strategy for options:
764
+ * - 'memory' — in-memory only,
765
+ * - 'session' — sessionStorage,
766
+ * - 'persist' — localStorage.
767
+ * ('lru' is excluded: used internally for inner structures)
768
+ */
769
+ defaultCacheStrategy?: DictStoreConfig<AnyType>['cacheStrategy'];
770
+ /**
771
+ * Optional prefix applied to all storage keys.
772
+ *
773
+ * Used to isolate keys within preventing collisions
774
+ * between different modules or instances.
775
+ *
776
+ * Example:
777
+ * - keyPrefix: 'user'
778
+ * - stored key: 'user:settings'
779
+ */
780
+ defaultPrefix?: string;
781
+ /** Initial filters (added to the first request/filtering). */
782
+ defaultPresetFilters?: DictStoreConfig<AnyType>['presetFilters'];
783
+ /** Transport method for fetching the dictionary. Defaults to 'POST'. */
784
+ defaultRestMethod?: DictStoreConfig<AnyType>['method'];
785
+ /** Debounce delay before request (ms) — for frequent input/search. */
786
+ defaultDebounceTime?: DictStoreConfig<AnyType>['debounceTime'];
787
+ /** Maximum number of options exposed (truncates `options`). */
788
+ defaultMaxOptionsSize?: DictStoreConfig<AnyType>['maxOptionsSize'];
789
+ /** Field key for label in a dictionary item. Defaults to `'name'`. */
790
+ defaultLabelKey?: DictStoreConfig<AnyType>['labelKey'];
791
+ /** Field key for value in a dictionary item. Defaults to `'code'`. */
792
+ defaultValueKey?: DictStoreConfig<AnyType>['valueKey'];
793
+ };
752
794
  type ValueType = string[] | string | number | null | undefined;
753
795
 
754
796
  /**
@@ -772,6 +814,12 @@ declare class DictStore<Type extends AnyDict> {
772
814
  private apiUrl;
773
815
  private storageKey;
774
816
  static readonly MAX_CACHE_SIZE = 400;
817
+ /**
818
+ * Default dictionary configuration resolved from {@link STATUM_CONFIG}.
819
+ *
820
+ * Used as a global fallback when local configuration does not explicitly
821
+ */
822
+ defaultConfig: _reforgium_statum.DictStoreProviderConfig;
775
823
  private readonly fixed;
776
824
  private readonly labelKey;
777
825
  private readonly valueKey;
@@ -808,7 +856,7 @@ declare class DictStore<Type extends AnyDict> {
808
856
  * @param storageKey key for saving cache in the selected strategy
809
857
  * @param cfg behavior (fixed/search, parsers, label/value keys, cache strategy, etc.)
810
858
  */
811
- constructor(apiUrl: string, storageKey: string, { method, autoLoad, presetFilters, parseResponse, parseRequest, debounceTime, fixed, maxOptionsSize, labelKey, valueKey, cacheStrategy, }: DictStoreConfig<Type>);
859
+ constructor(apiUrl: string, storageKey: string, { autoLoad, method, presetFilters, parseResponse, parseRequest, debounceTime, fixed, maxOptionsSize, labelKey, valueKey, keyPrefix, cacheStrategy, }: DictStoreConfig<Type>);
812
860
  /** Restore cache from the selected storage (`persist`/`session`/`lru`/`memory`). */
813
861
  restoreCache(): void;
814
862
  /**
@@ -839,14 +887,32 @@ declare class DictStore<Type extends AnyDict> {
839
887
  private restoreFromStorage;
840
888
  private filterLocal;
841
889
  private keyOf;
890
+ private setAutoload;
842
891
  }
843
892
 
844
893
  declare class DictLocalStore<Type extends AnyDict> {
845
894
  #private;
895
+ /**
896
+ * Default dictionary configuration resolved from {@link STATUM_CONFIG}.
897
+ *
898
+ * Used as a global fallback when local configuration does not explicitly
899
+ * define dictionary keys.
900
+ */
901
+ defaultConfig: _reforgium_statum.DictStoreProviderConfig;
902
+ /**
903
+ * Source dictionary items.
904
+ *
905
+ * Represents the full, unfiltered list of dictionary entries.
906
+ * Used as the base data set for search and option generation.
907
+ */
846
908
  items: _angular_core.WritableSignal<readonly Type[]>;
847
909
  /**
848
- * Ready-to-use options for dropdowns: `{ label, value }`.
849
- * Respects `maxOptionsSize` to truncate the list.
910
+ * Computed list of options in `{ label, value }` format.
911
+ *
912
+ * Based on the current draft items (after search/filtering).
913
+ * Respects `maxOptionsSize` to limit the number of generated options.
914
+ *
915
+ * Intended for direct use in dropdowns and select-like components.
850
916
  */
851
917
  options: _angular_core.Signal<{
852
918
  label: string;
@@ -857,20 +923,64 @@ declare class DictLocalStore<Type extends AnyDict> {
857
923
  private readonly maxOptionsSize?;
858
924
  constructor(items: Type[], config?: DictLocalConfig<Type>);
859
925
  /**
860
- * No-op method for API compatibility with DictStore.
926
+ * Restore cached dictionary state.
927
+ *
928
+ * This implementation is a no-op and exists only for API compatibility
929
+ * with {@link DictStore}.
861
930
  */
862
931
  restoreCache(): void;
863
932
  /**
864
- * Find display label by value (usually for reverse binding).
865
- * @returns label string or `undefined` if not found
933
+ * Resolve display label by value.
934
+ *
935
+ * Performs a linear search over dictionary items and returns
936
+ * the corresponding label for the given value.
937
+ *
938
+ * Commonly used for reverse binding (value → label).
939
+ *
940
+ * @param value Dictionary value to look up
941
+ * @returns Resolved label string, or `undefined` if not found
866
942
  */
867
943
  findLabel: (value: ValueType) => string | undefined;
944
+ /**
945
+ * Filter dictionary items by label.
946
+ *
947
+ * Applies a case-insensitive substring match against the label field
948
+ * and updates the internal draft items used for option generation.
949
+ *
950
+ * Passing an empty string resets the filter and restores all items.
951
+ *
952
+ * @param name Search query string
953
+ */
868
954
  search: (name?: string) => void;
955
+ /**
956
+ * Preload additional dictionary items.
957
+ *
958
+ * Can either replace the current items completely or append
959
+ * new entries to the existing list.
960
+ *
961
+ * Updates both the source items and the current draft items.
962
+ *
963
+ * @param items Items to preload
964
+ * @param opts Preload options
965
+ * @param opts.replace When `true`, replaces existing items instead of appending
966
+ */
869
967
  preload: (items: readonly Type[], opts?: {
870
968
  replace?: boolean;
871
969
  }) => void;
872
970
  }
873
971
 
874
- export { AbortError, CacheMissError, DictLocalStore, DictStore, LruCache, PDS_CONFIG, PaginatedDataStore, ResourceStore, SERIALIZER_CONFIG, Serializer, isAbort, storageStrategy };
875
- export type { DataType, DictLocalConfig, DictStoreConfig, FieldConfig, PaginatedDataConfig, PaginatedDataStoreConfig, ResourceRoutesMap, ResourceStatus, ResourceStoreOptions, SerializedType, SerializerConfig, StorageInterface, StorageStrategy, Types };
972
+ type PaginatedDataProviderConfig = {
973
+ paginatedData?: PaginatedDataStoreProviderConfig;
974
+ };
975
+ type SerializerProviderConfig = {
976
+ serializer?: Partial<SerializerConfig>;
977
+ };
978
+ type DictProviderConfig = {
979
+ dict?: DictStoreProviderConfig;
980
+ };
981
+ type StatumConfig = PaginatedDataProviderConfig & SerializerProviderConfig & DictProviderConfig;
982
+ declare const STATUM_CONFIG: InjectionToken<StatumConfig>;
983
+
984
+ export { AbortError, CacheMissError, DictLocalStore, DictStore, LruCache, PaginatedDataStore, ResourceStore, STATUM_CONFIG, Serializer, isAbort, storageStrategy };
985
+ export type { DataType, DictLocalConfig, DictStoreConfig, DictStoreProviderConfig, FieldConfig, PaginatedDataStoreConfig, PaginatedDataStoreProviderConfig, ResourceRoutesMap, ResourceStatus, ResourceStoreOptions, SerializedType, SerializerConfig, StorageInterface, StorageStrategy, Types };
876
986
  //# sourceMappingURL=reforgium-statum.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"reforgium-statum.d.ts","sources":["../../../../libs/statum/src/serializer/serialize.models.ts","../../../../libs/statum/src/serializer/serializer.ts","../../../../libs/statum/src/serializer/serializer.provider.ts","../../../../libs/statum/src/cache/storage-strategy/models.ts","../../../../libs/statum/src/cache/storages/models.ts","../../../../libs/statum/src/cache/storages/lru.storage.ts","../../../../libs/statum/src/cache/storage-strategy/storage.strategy.ts","../../../../libs/statum/src/stores/resource-store/resource.models.ts","../../../../libs/statum/src/stores/resource-store/resource.store.ts","../../../../libs/statum/src/stores/resource-store/resource.utils.ts","../../../../libs/statum/src/stores/paginated-data-store/paginated-data.models.ts","../../../../libs/statum/src/stores/paginated-data-store/paginated-data.provider.ts","../../../../libs/statum/src/stores/paginated-data-store/paginated-data.store.ts","../../../../libs/statum/src/stores/dict-store/dict.models.ts","../../../../libs/statum/src/stores/dict-store/dict.store.ts","../../../../libs/statum/src/stores/dict-store/dict-local.store.ts"],"sourcesContent":[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"reforgium-statum.d.ts","sources":["../../../../libs/statum/src/serializer/serialize.models.ts","../../../../libs/statum/src/serializer/serializer.ts","../../../../libs/statum/src/cache/storage-strategy/models.ts","../../../../libs/statum/src/cache/storages/models.ts","../../../../libs/statum/src/cache/storages/lru.storage.ts","../../../../libs/statum/src/cache/storage-strategy/storage.strategy.ts","../../../../libs/statum/src/stores/resource-store/resource.models.ts","../../../../libs/statum/src/stores/resource-store/resource.store.ts","../../../../libs/statum/src/stores/resource-store/resource.utils.ts","../../../../libs/statum/src/stores/paginated-data-store/paginated-data.models.ts","../../../../libs/statum/src/stores/paginated-data-store/paginated-data.store.ts","../../../../libs/statum/src/stores/dict-store/dict.models.ts","../../../../libs/statum/src/stores/dict-store/dict.store.ts","../../../../libs/statum/src/stores/dict-store/dict-local.store.ts","../../../../libs/statum/src/statum.provider.ts"],"sourcesContent":[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],"names":[],"mappings":"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"}