@reforgium/statum 3.1.0 → 3.1.2

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/CHANGELOG.md CHANGED
@@ -1,3 +1,25 @@
1
+ ## [3.1.2]: 2026-04-06
2
+
3
+ ### Fix:
4
+ - `DictStore`: `presetFilters` were passed to the internal `PagedQueryStore` as its initial filter state, which was immediately overwritten on the first `fetch()` call; `presetFilters` are now stored directly on `DictStore` and explicitly merged into every `fetch` call as `{ name, ...presetFilters, ...runtimeFilters }`, so direction/status constraints are always included regardless of runtime filter state
5
+
6
+ ---
7
+
8
+ ## [3.1.1]: 2026-04-04
9
+
10
+ ### Refactor:
11
+ - Moved `Serializer` core into `@reforgium/internal`; `statum` now keeps serializer presets and public wrappers while reusing the shared codec engine underneath.
12
+ - Moved low-level storage implementations and `storageStrategy(...)` into `@reforgium/internal`; `statum` cache exports now act as compatibility wrappers over the shared foundation layer.
13
+
14
+ ### Fix:
15
+ - Package build and workspace resolution were aligned with hidden `@reforgium/internal` usage.
16
+ - `PagedQueryStore` transport generic ordering was corrected for package build stability.
17
+
18
+ ### Docs:
19
+ - `README` now reflects `storageStrategy(...)` naming and clarifies that serializer/storage core are shared through `@reforgium/internal`.
20
+
21
+ ---
22
+
1
23
  ## [3.1.0]: 2026-04-01
2
24
 
3
25
  ### Feat:
package/README.md CHANGED
@@ -5,7 +5,7 @@
5
5
 
6
6
  **Signals-first query and data stores for Angular (18+).**
7
7
 
8
- `@reforgium/statum` provides **API-oriented stores**, **cache strategies**, and a
8
+ `@reforgium/statum` provides **API-oriented stores**, **cache strategies**, and a
9
9
  **serialization layer** for Angular applications that talk to HTTP backends.
10
10
 
11
11
  Designed for **request orchestration, pagination, dictionaries, and entity state**.
@@ -94,6 +94,9 @@ The safest long-term entry points are:
94
94
  - **Stores** - reusable state containers over HttpClient
95
95
  - **Serializer** - configurable data transformation utility
96
96
 
97
+ Low-level serializer and storage primitives are shared through hidden `@reforgium/internal`.
98
+ `statum` remains the user-facing package; you do not need to install or reason about `@reforgium/internal` directly in normal usage.
99
+
97
100
  ## Behavioral Guarantees
98
101
 
99
102
  The core stores are designed around explicit, testable runtime guarantees.
@@ -151,9 +154,9 @@ Those numbers are machine-specific and should be treated as a local envelope, no
151
154
 
152
155
  ## Cache
153
156
 
154
- ### cacheStrategy
157
+ ### storageStrategy
155
158
 
156
- `cacheStrategy<T>(kind)` is a factory that returns a cache storage implementing `StorageInterface<T>`
159
+ `storageStrategy<T>(kind)` is a factory that returns a cache storage implementing `StorageInterface<T>`
157
160
 
158
161
  Available strategies:
159
162
 
@@ -180,11 +183,11 @@ interface StorageInterface<T> {
180
183
  Example:
181
184
 
182
185
  ```ts
183
- import { cacheStrategy } from '@reforgium/statum';
186
+ import { storageStrategy } from '@reforgium/statum';
184
187
 
185
188
  type User = { id: number; name: string };
186
189
 
187
- const storage = cacheStrategy<User>('persist');
190
+ const storage = storageStrategy<User>('persist');
188
191
 
189
192
  storage.set('user:1', { id: 1, name: 'John' });
190
193
 
@@ -651,6 +654,8 @@ Use this when list fetching and local item mutations need different lifecycles.
651
654
 
652
655
  Utility for serialization/deserialization between layers (UI -> API, objects -> query string).
653
656
 
657
+ `statum` keeps the user-facing serializer API and presets, while the low-level codec engine is shared from hidden `@reforgium/internal`.
658
+
654
659
  Core API:
655
660
 
656
661
  | Method | Description |
@@ -1,389 +1,10 @@
1
- import { formatDate, isNullable, isDatePeriod, parseToDate, buildQueryParams, isNumber, isObject, parseToDatePeriod, parseQueryParamsByMode, fillUrlWithParams, mergeQueryParams, deepEqual, normalizeSortInput, sortInputToTokens, debounceSignal } from '@reforgium/internal';
1
+ import { Serializer, fillUrlWithParams, mergeQueryParams, LruCache, deepEqual, isNullable, normalizeSortInput, sortInputToTokens, debounceSignal, storageStrategy } from '@reforgium/internal';
2
+ export { LocalStorage, LruCache, MemoryStorage, Serializer, SerializerFieldError, SessionStorage, storageStrategy } from '@reforgium/internal';
2
3
  import { HttpClient, HttpParams } from '@angular/common/http';
3
4
  import { InjectionToken, makeEnvironmentProviders, inject, signal, computed, EnvironmentInjector, DestroyRef, runInInjectionContext, effect, untracked } from '@angular/core';
4
5
  import { Subject, filter, timer, merge, map } from 'rxjs';
5
6
  import { debounce, tap, throttle, finalize } from 'rxjs/operators';
6
7
 
7
- const serializeString = (config, value) => config.mapString.format?.(value) ?? (config.mapString.trim ? value.trim() : value);
8
- const serializeNumber = (config, value) => config.mapNumber.format?.(value) ?? Number(value);
9
- const serializeBoolean = (config, value) => config.mapBoolean.format?.(value) ?? (value ? (config.mapBoolean.true ?? true) : (config.mapBoolean.false ?? false));
10
- const serializeDate = (config, value) => config.mapDate.format?.(value) ?? formatDate(value, config.mapDate.dateFormat);
11
-
12
- class SerializerFieldError extends Error {
13
- field;
14
- stage;
15
- originalError;
16
- constructor(field, stage, originalError) {
17
- const originalMessage = originalError instanceof Error ? originalError.message : String(originalError);
18
- super(`Serializer ${stage} error for field "${field}": ${originalMessage}`);
19
- this.field = field;
20
- this.stage = stage;
21
- this.originalError = originalError;
22
- this.name = 'SerializerFieldError';
23
- }
24
- }
25
- /**
26
- * Universal serializer/deserializer for values used in forms, filters, and DTOs.
27
- *
28
- * Supports types: `string | number | boolean | Date | [Date, Date] (period) | array | object | nullable`.
29
- * Capabilities:
30
- * - normalize values according to config (trim strings, parse numbers from strings, boolean strings, etc.),
31
- * - transform date periods into paired keys (`from/to`) or a single joined string,
32
- * - build/parse a query string (or JSON) to and from an object.
33
- *
34
- * Example:
35
- * ```ts
36
- * type Filters = { q?: string; active?: boolean; created?: [Date, Date] | null };
37
- * const s = new Serializer<Filters>({
38
- * mapPeriod: { transformMode: { mode: 'split', dateFromKeyPostfix: 'From', dateToKeyPostfix: 'To' } }
39
- * });
40
- *
41
- * // -> { q: 'john', createdFrom: '2025-01-01', createdTo: '2025-01-31' }
42
- * const plain = s.serialize({
43
- * q: ' john ',
44
- * active: undefined,
45
- * created: [new Date('2025-01-01'), new Date('2025-01-31')]
46
- * });
47
- *
48
- * // -> 'q=john&createdFrom=2025-01-01&createdTo=2025-01-31'
49
- * const qs = s.toQuery({ q: 'john', created: [new Date('2025-01-01'), new Date('2025-01-31')] });
50
- *
51
- * // <- { q: 'john', created: [Date, Date] }
52
- * const parsed = s.deserialize('q=john&createdFrom=2025-01-01&createdTo=2025-01-31');
53
- * ```
54
- */
55
- class Serializer {
56
- config;
57
- /**
58
- * Creates a serializer with a partially overridden configuration.
59
- * Provide only the options you want to change (the rest are taken from defaults).
60
- *
61
- * @param config partial transformation configuration
62
- */
63
- constructor(config = {}) {
64
- this.config = this.mergeConfig({
65
- mapString: { trim: true },
66
- mapNumber: { fromString: false },
67
- mapBoolean: {},
68
- mapArray: { concatType: 'comma' },
69
- mapObject: { deep: true },
70
- mapDate: { dateFormat: 'yyyy-MM-dd' },
71
- mapPeriod: {
72
- dateFormat: 'yyyy-MM-dd',
73
- transformMode: { mode: 'split', dateFromKeyPostfix: 'From', dateToKeyPostfix: 'To' },
74
- },
75
- mapNullable: { remove: true, includeEmptyString: false },
76
- }, config);
77
- }
78
- /**
79
- * Converts a domain object into a flat serialized representation
80
- * (ready to send to an API or build a query string).
81
- *
82
- * Rules are taken from `config`:
83
- * — strings can be trimmed (if enabled),
84
- * — numbers can be converted from strings/numbers,
85
- * — boolean supports custom true/false representations,
86
- * — dates are formatted by `dateFormat`,
87
- * — date periods can be split/joined,
88
- * — `nullable` can be removed from the result (`remove`) or formatted.
89
- *
90
- * @param obj source object
91
- * @returns a flat dictionary with string/primitive values
92
- */
93
- serialize(obj, _seen = new WeakSet()) {
94
- const result = {};
95
- if (obj != null && typeof obj === 'object') {
96
- _seen.add(obj);
97
- }
98
- for (const [key, value] of Object.entries(obj ?? {})) {
99
- const fields = this.config.mapFields?.[key];
100
- if (fields && 'format' in fields) {
101
- try {
102
- result[key] = fields.format(value, obj);
103
- }
104
- catch (error) {
105
- throw new SerializerFieldError(key, 'format', error);
106
- }
107
- continue;
108
- }
109
- if (fields?.type === 'nullable' || isNullable(value, this.config.mapNullable?.includeEmptyString)) {
110
- if (this.config.mapNullable.remove) {
111
- continue;
112
- }
113
- }
114
- if (fields?.type === 'period' || isDatePeriod(value)) {
115
- const transform = this.config.mapPeriod.transformMode;
116
- const [from, to] = value;
117
- if (transform?.mode === 'split') {
118
- result[`${key}${transform.dateFromKeyPostfix}`] = formatDate(from, this.config.mapPeriod.dateFormat);
119
- result[`${key}${transform.dateToKeyPostfix}`] = formatDate(to, this.config.mapPeriod.dateFormat);
120
- continue;
121
- }
122
- }
123
- result[key] = this.serializeElement(value, key, _seen);
124
- }
125
- if (obj != null && typeof obj === 'object') {
126
- _seen.delete(obj);
127
- }
128
- return result;
129
- }
130
- /**
131
- * Parse serialized data into a domain object.
132
- *
133
- * Source can be:
134
- * — a query string (`key=value&arr=1,2`) or `JSON.stringify(obj)`,
135
- * — an already prepared flat object.
136
- *
137
- * Transformations are reverse of `serialize`: strings → number/boolean/Date/period,
138
- * arrays are collected according to strategy (`comma`/`pipe`/`multi`), objects — deeply or as JSON.
139
- *
140
- * @param val query string or object
141
- * @returns a domain object of the specified type
142
- */
143
- deserialize = (val) => {
144
- const data = typeof val === 'string' ? this.parseInputString(val) : val;
145
- const result = {};
146
- for (const [key, value] of Object.entries(data ?? {})) {
147
- const field = this.config.mapFields?.[key];
148
- if (field && 'parse' in field) {
149
- try {
150
- result[key] = field.parse(value, data);
151
- }
152
- catch (error) {
153
- throw new SerializerFieldError(key, 'parse', error);
154
- }
155
- continue;
156
- }
157
- if (field?.type === 'nullable' ||
158
- (field?.type !== 'array' && isNullable(value, this.config.mapNullable?.includeEmptyString))) {
159
- if (this.config.mapNullable.remove) {
160
- continue;
161
- }
162
- }
163
- const periodTransform = this.config.mapPeriod.transformMode;
164
- if (periodTransform.mode === 'split') {
165
- const isFrom = (key || '').endsWith(periodTransform.dateFromKeyPostfix);
166
- const isTo = (key || '').endsWith(periodTransform.dateToKeyPostfix);
167
- const keyJoint = (key || '')
168
- .replace(periodTransform.dateFromKeyPostfix, '')
169
- .replace(periodTransform.dateToKeyPostfix, '');
170
- const field = this.config.mapFields?.[keyJoint];
171
- const fieldType = field && 'type' in field ? field.type : undefined;
172
- if (fieldType === 'period' && (isFrom || isTo)) {
173
- result[keyJoint] ??= [null, null];
174
- if (isFrom) {
175
- result[keyJoint][0] = parseToDate(value, this.config.mapPeriod.dateFormat);
176
- }
177
- else if (isTo) {
178
- result[keyJoint][1] = parseToDate(value, this.config.mapPeriod.dateFormat);
179
- }
180
- continue;
181
- }
182
- }
183
- result[key] = this.deserializeElement(value, key);
184
- }
185
- return result;
186
- };
187
- /** Parse only query-string input. */
188
- deserializeQuery = (query) => {
189
- return this.deserialize(this.parseQuery(query));
190
- };
191
- /** Parse only JSON object input. */
192
- deserializeJson = (json) => {
193
- return this.deserialize(this.parseJsonObject(json));
194
- };
195
- /**
196
- * Build a query string from a domain object using `serialize` rules
197
- * and the array joining strategy (`concatType`).
198
- *
199
- * @param val domain object
200
- * @returns query string (suitable for URL or history API)
201
- */
202
- toQuery = (val) => {
203
- return buildQueryParams(this.serialize(val), this.config.mapArray.concatType, this.resolveArrayFieldModes());
204
- };
205
- /**
206
- * Returns a new serializer instance with a merged configuration.
207
- * Useful for ad-hoc overrides for a specific call.
208
- *
209
- * @param config partial config changes
210
- * @returns new `Serializer` with the provided `config` applied
211
- */
212
- withConfig(config) {
213
- return new Serializer(this.mergeConfig(this.config, config));
214
- }
215
- serializeElement(value, key, _seen = new WeakSet()) {
216
- const fields = this.config.mapFields?.[key || ''];
217
- if (fields && 'format' in fields) {
218
- return;
219
- }
220
- if (fields?.type === 'nullable' || isNullable(value, this.config.mapNullable?.includeEmptyString)) {
221
- const nullableVal = value ?? null;
222
- return this.config.mapNullable.format?.(nullableVal) || this.config.mapNullable.replaceWith || nullableVal;
223
- }
224
- if (fields?.type === 'string') {
225
- return serializeString(this.config, value);
226
- }
227
- if (fields?.type === 'number' || isNumber(value, this.config.mapNumber.fromString)) {
228
- return serializeNumber(this.config, value);
229
- }
230
- if (typeof value === 'string') {
231
- return serializeString(this.config, value);
232
- }
233
- if (fields?.type === 'boolean' || typeof value === 'boolean') {
234
- return serializeBoolean(this.config, value);
235
- }
236
- if (fields?.type === 'date' || value instanceof Date) {
237
- return serializeDate(this.config, value);
238
- }
239
- if (fields?.type === 'period' || isDatePeriod(value)) {
240
- const mapPeriod = this.config.mapPeriod;
241
- if (mapPeriod.format) {
242
- return mapPeriod.format(value);
243
- }
244
- else {
245
- const [from, to] = value;
246
- const transform = mapPeriod.transformMode;
247
- if (transform.mode === 'join') {
248
- const period = [
249
- formatDate(from, this.config.mapPeriod.dateFormat),
250
- formatDate(to, this.config.mapPeriod.dateFormat),
251
- ];
252
- return period.join(transform.concat);
253
- }
254
- }
255
- }
256
- if (fields?.type === 'array' || Array.isArray(value)) {
257
- return value.map((it) => this.serializeElement(it, undefined, _seen));
258
- }
259
- if (fields?.type === 'object' || isObject(value)) {
260
- if (this.config.mapObject.deep && !this.config.mapObject.format && value != null && _seen.has(value)) {
261
- return undefined;
262
- }
263
- return (this.config.mapObject.format?.(value) ??
264
- (this.config.mapObject.deep ? this.serialize(value, _seen) : JSON.stringify(value)));
265
- }
266
- }
267
- deserializeElement(value, key) {
268
- const field = this.config.mapFields?.[key || ''];
269
- if (field && 'format' in field) {
270
- return;
271
- }
272
- if (field?.type === 'array' || Array.isArray(value)) {
273
- const array = Array.isArray(value) ? value : [value];
274
- if (this.config.mapArray.removeNullable) {
275
- if (!isNullable(value, this.config.mapNullable?.includeEmptyString)) {
276
- return array.map((it) => this.deserializeElement(it));
277
- }
278
- else {
279
- return;
280
- }
281
- }
282
- else {
283
- return !value ? [] : array.map((it) => this.deserializeElement(it));
284
- }
285
- }
286
- if (field?.type === 'object') {
287
- try {
288
- if (this.config.mapObject.deep) {
289
- return isObject(value) ? this.deserialize(value) : value;
290
- }
291
- else {
292
- return typeof value === 'string' ? JSON.parse(value) : value;
293
- }
294
- }
295
- catch {
296
- return value;
297
- }
298
- }
299
- if (field?.type === 'nullable' || isNullable(value, this.config.mapNullable?.includeEmptyString)) {
300
- return this.config.mapNullable.parse?.(value) || value;
301
- }
302
- if (field?.type === 'boolean' ||
303
- typeof value === 'boolean' ||
304
- value === this.config.mapBoolean.true ||
305
- value === this.config.mapBoolean.false) {
306
- return this.config.mapBoolean.parse?.(value) ?? (value === this.config.mapBoolean.true || value === true);
307
- }
308
- const maybeDate = parseToDate(value, this.config.mapDate.dateFormat);
309
- if (field?.type === 'date' || maybeDate) {
310
- return this.config.mapDate.parse?.(value) || maybeDate;
311
- }
312
- const periodTransform = this.config.mapPeriod.transformMode;
313
- if (periodTransform.mode === 'join') {
314
- const maybePeriod = parseToDatePeriod(value, this.config.mapPeriod.dateFormat);
315
- if (field?.type === 'period' || (maybePeriod || []).some(Boolean)) {
316
- return this.config.mapPeriod.parse?.(value) || maybePeriod;
317
- }
318
- }
319
- if (field?.type === 'number' || isNumber(value, this.config.mapNumber.fromString)) {
320
- return this.config.mapNumber.parse?.(value) || Number(String(value).trim());
321
- }
322
- if (field?.type === 'string' || typeof value === 'string') {
323
- const parsed = this.config.mapString.parse?.(value);
324
- if (parsed !== undefined) {
325
- return parsed;
326
- }
327
- return this.config.mapString.trim ? String(value).trim() : value;
328
- }
329
- return value;
330
- }
331
- parseQuery(val) {
332
- return parseQueryParamsByMode(val, undefined, this.resolveArrayFieldModes());
333
- }
334
- parseJsonObject(val) {
335
- try {
336
- const parsed = JSON.parse(val);
337
- if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) {
338
- return parsed;
339
- }
340
- }
341
- catch (error) {
342
- throw new Error(`Invalid JSON input: ${error instanceof Error ? error.message : String(error)}`);
343
- }
344
- throw new Error('Invalid JSON input: expected a JSON object');
345
- }
346
- parseInputString(val) {
347
- try {
348
- return this.parseJsonObject(val);
349
- }
350
- catch {
351
- return this.parseQuery(val);
352
- }
353
- }
354
- mergeConfig(base, override) {
355
- return {
356
- ...base,
357
- ...override,
358
- mapString: { ...base.mapString, ...override.mapString },
359
- mapNumber: { ...base.mapNumber, ...override.mapNumber },
360
- mapBoolean: { ...base.mapBoolean, ...override.mapBoolean },
361
- mapDate: { ...base.mapDate, ...override.mapDate },
362
- mapPeriod: {
363
- ...base.mapPeriod,
364
- ...override.mapPeriod,
365
- transformMode: {
366
- ...base.mapPeriod.transformMode,
367
- ...override.mapPeriod?.transformMode,
368
- },
369
- },
370
- mapNullable: { ...base.mapNullable, ...override.mapNullable },
371
- mapArray: { ...base.mapArray, ...override.mapArray },
372
- mapObject: { ...base.mapObject, ...override.mapObject },
373
- mapFields: { ...(base.mapFields || {}), ...(override.mapFields || {}) },
374
- };
375
- }
376
- resolveArrayFieldModes() {
377
- const result = {};
378
- Object.entries(this.config.mapFields || {}).forEach(([key, field]) => {
379
- if ('type' in field && field.type === 'array') {
380
- result[key] = field.concatType ?? this.config.mapArray.concatType;
381
- }
382
- });
383
- return result;
384
- }
385
- }
386
-
387
8
  const createQuerySerializer = (config = {}) => {
388
9
  return new Serializer({
389
10
  mapArray: { concatType: 'comma' },
@@ -409,197 +30,6 @@ const createStrictSerializer = (config = {}) => {
409
30
  });
410
31
  };
411
32
 
412
- class LruCache {
413
- map = new Map();
414
- _limit = 100;
415
- constructor(limit = 100) {
416
- this.limit = limit;
417
- }
418
- get limit() {
419
- return this._limit;
420
- }
421
- get length() {
422
- return this.map.size;
423
- }
424
- set limit(value) {
425
- this._limit = Math.max(1, Math.floor(value || 0));
426
- }
427
- get(key) {
428
- if (!this.map.has(key)) {
429
- return null;
430
- }
431
- const val = this.map.get(key);
432
- this.map.delete(key);
433
- this.map.set(key, val);
434
- return val;
435
- }
436
- set(key, value) {
437
- if (this.map.has(key)) {
438
- this.map.delete(key);
439
- }
440
- else if (this.map.size >= this.limit) {
441
- const oldest = this.map.keys().next().value;
442
- oldest !== undefined && this.map.delete(oldest);
443
- }
444
- this.map.set(key, value);
445
- }
446
- remove(key) {
447
- return this.map.delete(key);
448
- }
449
- clear() {
450
- this.map.clear();
451
- }
452
- has(key) {
453
- return this.map.has(key);
454
- }
455
- keys() {
456
- return Array.from(this.map.keys());
457
- }
458
- values() {
459
- return Array.from(this.map.values());
460
- }
461
- entries() {
462
- return Array.from(this.map.entries());
463
- }
464
- toArray() {
465
- return Array.from(this.map.values());
466
- }
467
- fromArray(entries) {
468
- this.map.clear();
469
- for (const [k, v] of entries) {
470
- this.set(k, v);
471
- }
472
- }
473
- }
474
-
475
- class LocalStorage {
476
- prefix;
477
- constructor(prefix = 're') {
478
- this.prefix = prefix;
479
- }
480
- get length() {
481
- return Object.keys(localStorage).filter((key) => key.startsWith(this.safePrefix())).length;
482
- }
483
- get(key) {
484
- const storageKey = this.getSafePrefix(key);
485
- const raw = localStorage.getItem(storageKey);
486
- if (raw == null) {
487
- return null;
488
- }
489
- try {
490
- const parsed = JSON.parse(raw);
491
- return parsed ?? null;
492
- }
493
- catch {
494
- localStorage.removeItem(storageKey);
495
- return null;
496
- }
497
- }
498
- set(key, value) {
499
- const str = JSON.stringify(value);
500
- localStorage.setItem(this.getSafePrefix(key), str);
501
- }
502
- remove(key) {
503
- return localStorage.removeItem(this.getSafePrefix(key));
504
- }
505
- clear() {
506
- const keys = Object.keys(localStorage).filter((key) => key.startsWith(this.safePrefix()));
507
- keys.forEach((key) => localStorage.removeItem(key));
508
- }
509
- getSafePrefix(key) {
510
- return this.prefix ? `${this.prefix}:${key}` : String(key);
511
- }
512
- safePrefix() {
513
- return this.prefix ? `${this.prefix}:` : '';
514
- }
515
- }
516
-
517
- class MemoryStorage {
518
- cache = new Map();
519
- get length() {
520
- return this.cache.size;
521
- }
522
- get(key) {
523
- return this.cache.get(key) ?? null;
524
- }
525
- set(key, value) {
526
- this.cache.set(key, value);
527
- }
528
- remove(key) {
529
- this.cache.delete(key);
530
- }
531
- clear() {
532
- this.cache.clear();
533
- }
534
- }
535
-
536
- class SessionStorage {
537
- prefix;
538
- constructor(prefix = 're') {
539
- this.prefix = prefix;
540
- }
541
- get length() {
542
- return Object.keys(sessionStorage).filter((key) => key.startsWith(this.safePrefix())).length;
543
- }
544
- get(key) {
545
- const storageKey = this.getSafePrefix(key);
546
- const raw = sessionStorage.getItem(storageKey);
547
- if (raw == null) {
548
- return null;
549
- }
550
- try {
551
- const parsed = JSON.parse(raw);
552
- return parsed ?? null;
553
- }
554
- catch {
555
- sessionStorage.removeItem(storageKey);
556
- return null;
557
- }
558
- }
559
- set(key, value) {
560
- const str = JSON.stringify(value);
561
- sessionStorage.setItem(this.getSafePrefix(key), str);
562
- }
563
- remove(key) {
564
- return sessionStorage.removeItem(this.getSafePrefix(key));
565
- }
566
- clear() {
567
- const keys = Object.keys(sessionStorage).filter((key) => key.startsWith(this.safePrefix()));
568
- keys.forEach((key) => sessionStorage.removeItem(key));
569
- }
570
- getSafePrefix(key) {
571
- return this.prefix ? `${this.prefix}:${key}` : String(key);
572
- }
573
- safePrefix() {
574
- return this.prefix ? `${this.prefix}:` : '';
575
- }
576
- }
577
-
578
- /**
579
- * Factory for data storage strategies.
580
- *
581
- * Returns a `StorageInterface` implementation depending on the selected strategy:
582
- * - `'memory'` — in-memory storage (for the session lifetime);
583
- * - `'session'` — `sessionStorage`, lives until the tab is closed;
584
- * - `'persist'` — `localStorage`, persists between sessions;
585
- * - `'lru'` — size-limited cache (Least Recently Used).
586
- *
587
- * Used to choose an appropriate storage implementation
588
- * depending on the scenario: temporary data, long-term, cache, etc.
589
- *
590
- * @param strategy storage strategy type (`memory`, `session`, `persist`, `lru`)
591
- * @returns instance implementing `StorageInterface<Key, Type>`
592
- */
593
- const storageStrategy = (strategy, options = {}) => {
594
- const fabrics = {
595
- memory: () => new MemoryStorage(),
596
- session: () => new SessionStorage(),
597
- persist: () => new LocalStorage(),
598
- lru: () => new LruCache(options.lruLimit ?? 100),
599
- };
600
- return fabrics[strategy]();
601
- };
602
-
603
33
  // noinspection ES6PreferShortImport
604
34
  const STATUM_CONFIG = new InjectionToken('RE_STATUM_CONFIG');
605
35
  const provideStatum = (config) => makeEnvironmentProviders([{ provide: STATUM_CONFIG, useValue: config }]);
@@ -1389,7 +819,7 @@ const createResourceProfile = (profile, overrides = {}) => ({
1389
819
  * - reactive signals: `items`, `loading`, `cached`;
1390
820
  * - methods to control page/size/query;
1391
821
  * - optional LRU cache by pages;
1392
- * - configurable transport (GET/POST/PATCH/…).
822
+ * - configurable transport (GET/POST/PATCH/…).
1393
823
  *
1394
824
  * Example:
1395
825
  * ```ts
@@ -1856,6 +1286,7 @@ class DictStore {
1856
1286
  ttlMs;
1857
1287
  revalidate;
1858
1288
  cacheUpdatedAt = signal(null, ...(ngDevMode ? [{ debugName: "cacheUpdatedAt" }] : []));
1289
+ presetFilters = {};
1859
1290
  /**
1860
1291
  * Search text.
1861
1292
  * With `fixed: true` filters the local cache; with `fixed: false` triggers server search.
@@ -1869,7 +1300,7 @@ class DictStore {
1869
1300
  cachedItems = signal([], ...(ngDevMode ? [{ debugName: "cachedItems" }] : []));
1870
1301
  /**
1871
1302
  * Current list of dictionary items.
1872
- * Source — local cache (fixed=true) or data from `PagedQueryStore`.
1303
+ * Source local cache (fixed=true) or data from `PagedQueryStore`.
1873
1304
  */
1874
1305
  items = computed(() => {
1875
1306
  const cached = this.cachedItems();
@@ -1899,10 +1330,10 @@ class DictStore {
1899
1330
  this.storageKey = storageKey;
1900
1331
  const searchDebounce = debounceTime ?? 300;
1901
1332
  this.debouncedSearchText = debounceSignal(this.searchText, searchDebounce);
1333
+ this.presetFilters = presetFilters ?? {};
1902
1334
  this.#helper = new PagedQueryStore(this.apiUrl, {
1903
1335
  method: method,
1904
1336
  hasCache: false,
1905
- presetFilters: { name: '', ...presetFilters },
1906
1337
  parseResponse: parseResponse,
1907
1338
  parseRequest: parseRequest,
1908
1339
  debounceTime: debounceTime,
@@ -1936,12 +1367,14 @@ class DictStore {
1936
1367
  if (!this.fixed) {
1937
1368
  const query = this.debouncedSearchText().trim();
1938
1369
  untracked(() => {
1939
- this._lastPromise = this.#helper.fetch({ filters: { name: query, ...rest } });
1370
+ this._lastPromise = this.#helper.fetch({ filters: { name: query, ...this.presetFilters, ...rest } });
1940
1371
  });
1941
1372
  }
1942
1373
  else if (this.shouldFetchFixedCache()) {
1943
1374
  untracked(() => {
1944
- this._lastPromise = this.#helper.fetch({ filters: { name: '', ...rest } }).then((items) => {
1375
+ this._lastPromise = this.#helper
1376
+ .fetch({ filters: { name: '', ...this.presetFilters, ...rest } })
1377
+ .then((items) => {
1945
1378
  items?.length && this.mergeIntoCache(items);
1946
1379
  return items;
1947
1380
  });
@@ -1962,7 +1395,7 @@ class DictStore {
1962
1395
  }
1963
1396
  /**
1964
1397
  * Set a search query and filters.
1965
- * With `fixed: false` initiates server search; with `fixed: true` — local filtering.
1398
+ * With `fixed: false` initiates server search; with `fixed: true` local filtering.
1966
1399
  */
1967
1400
  search = (name = '', filters = {}) => {
1968
1401
  this._armed.set(true);
@@ -2372,5 +1805,5 @@ class EntityStore {
2372
1805
  * Generated bundle index. Do not edit.
2373
1806
  */
2374
1807
 
2375
- export { AbortError, CacheMissError, DictLocalStore, DictStore, EntityStore, LruCache, PagedQueryStore, RESOURCE_PROFILES, ResourceStore, STATUM_CONFIG, Serializer, SerializerFieldError, createBodySerializer, createQuerySerializer, createResourceProfile, createStrictSerializer, isAbort, provideStatum, storageStrategy };
1808
+ export { AbortError, CacheMissError, DictLocalStore, DictStore, EntityStore, PagedQueryStore, RESOURCE_PROFILES, ResourceStore, STATUM_CONFIG, createBodySerializer, createQuerySerializer, createResourceProfile, createStrictSerializer, isAbort, provideStatum };
2376
1809
  //# sourceMappingURL=reforgium-statum.mjs.map
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
- "version": "3.1.0",
2
+ "version": "3.1.2",
3
3
  "name": "@reforgium/statum",
4
- "description": "Signals-first query and data stores for Angular",
4
+ "description": "Signals-first API state and query stores for Angular",
5
5
  "author": "rtommievich",
6
6
  "license": "MIT",
7
7
  "type": "module",
@@ -21,10 +21,21 @@
21
21
  },
22
22
  "keywords": [
23
23
  "reforgium",
24
- "state",
24
+ "angular",
25
+ "angular-library",
26
+ "signals",
27
+ "signal-store",
25
28
  "store",
26
- "signal",
27
- "angular"
29
+ "data-store",
30
+ "resource-store",
31
+ "entity-store",
32
+ "dictionary",
33
+ "query",
34
+ "pagination",
35
+ "cache",
36
+ "http",
37
+ "api",
38
+ "serializer"
28
39
  ],
29
40
  "types": "../../dist/@reforgium/statum/index.d.ts",
30
41
  "files": [
@@ -42,7 +53,7 @@
42
53
  "peerDependencies": {
43
54
  "@angular/common": ">=18.0.0",
44
55
  "@angular/core": ">=18.0.0",
45
- "@reforgium/internal": ">=1.3.0",
56
+ "@reforgium/internal": ">=2.0.0",
46
57
  "rxjs": ">=7.0.0"
47
58
  },
48
59
  "module": "fesm2022/reforgium-statum.mjs",
@@ -1,286 +1,14 @@
1
- import { AnyType, AnyDict, RestMethods, QueryParams, PageableRequest, PageableResponse } from '@reforgium/internal';
1
+ import { DataType, SerializerConfig, Serializer, RestMethods, AnyDict, AnyType, QueryParams, PageableRequest, PageableResponse, StorageStrategy } from '@reforgium/internal';
2
+ export { DataType, FieldConcatType, FieldConfig, FormatConfig, LocalStorage, LruCache, MemoryStorage, ParseFormatConfig, SerializedType, Serializer, SerializerConfig, SerializerFieldError, SessionStorage, StorageInterface, StorageStrategy, StorageStrategyOptions, Types, storageStrategy } from '@reforgium/internal';
2
3
  import * as _angular_core from '@angular/core';
3
4
  import { Signal, WritableSignal, EnvironmentProviders, InjectionToken } from '@angular/core';
4
5
  import { HttpResponse } from '@angular/common/http';
5
6
  import * as _reforgium_statum from '@reforgium/statum';
6
7
 
7
- /**
8
- * List of supported primitive and composite data types
9
- * that can be serialized/deserialized.
10
- *
11
- * Used in field serialization configuration.
12
- */
13
- type Types = 'string' | 'number' | 'boolean' | 'array' | 'object' | 'date' | 'period' | 'nullable';
14
- type FieldConcatType = 'comma' | 'multi' | 'json';
15
- /**
16
- * Allowed "flat" values after serialization.
17
- * Such values are safe to pass in a query string or JSON.
18
- */
19
- type SerializedPrimitives = string | number | boolean | null;
20
- type SerializedTypeType = SerializedPrimitives | SerializedPrimitives[];
21
- type DatePeriod = [Date | null, Date | null];
22
- /**
23
- * Generic configuration shape to define `parse`/`format`
24
- * for converting a value from/to a serialized form.
25
- *
26
- * @template TypeFrom — domain type before serialization
27
- * @template TypeTo — serialized type (by default a primitive/array of primitives)
28
- */
29
- type ParseFormatConfig<TypeFrom, TypeTo = SerializedTypeType> = {
30
- parse?: (val: TypeTo) => TypeFrom;
31
- format?: (val: TypeFrom) => TypeTo;
32
- };
33
- /**
34
- * Simplified configuration when only `format` is needed.
35
- */
36
- type FormatConfig<TypeFrom, TypeTo = SerializedTypeType> = {
37
- format?: (val: TypeFrom) => TypeTo;
38
- };
39
- type FieldConfig = ({
40
- type: Types;
41
- concatType?: FieldConcatType;
42
- } | FieldsTypeConfig<DataType, AnyType>) & {
43
- concatType?: FieldConcatType;
44
- };
45
- type FieldsTypeConfig<EntityType extends DataType, TypeFrom, TypeTo = SerializedTypeType> = {
46
- parse: (val: TypeTo, data: SerializedType) => TypeFrom;
47
- format: (val: TypeFrom, data: EntityType) => TypeTo;
48
- };
49
- type PeriodSplitMode = {
50
- mode: 'split';
51
- dateFromKeyPostfix: string;
52
- dateToKeyPostfix: string;
53
- };
54
- type PeriodJoinMode = {
55
- mode: 'join';
56
- concat: string;
57
- };
58
- type SerializerConfig = {
59
- mapString: {
60
- trim?: boolean;
61
- } & ParseFormatConfig<string>;
62
- mapNumber: {
63
- fromString?: boolean;
64
- } & ParseFormatConfig<number>;
65
- mapBoolean: {
66
- true?: string;
67
- false?: string;
68
- } & ParseFormatConfig<boolean>;
69
- mapDate: {
70
- dateFormat?: string;
71
- } & ParseFormatConfig<Date>;
72
- /**
73
- * Settings for date period transformation.
74
- * Allows choosing a mode:
75
- * - split: split the period into two keys (e.g., createdFrom/createdTo)
76
- * - join: join into a string using a delimiter
77
- * And set the date format.
78
- */
79
- mapPeriod: {
80
- transformMode?: PeriodSplitMode | PeriodJoinMode;
81
- dateFormat?: string;
82
- } & ParseFormatConfig<DatePeriod>;
83
- /**
84
- * Settings for handling "empty" values.
85
- * - remove: remove the field from the result;
86
- * - replaceWith: replace with a fixed value;
87
- * - includeEmptyString: treat an empty string as "nullable".
88
- */
89
- mapNullable: {
90
- remove?: boolean;
91
- replaceWith?: string;
92
- includeEmptyString?: boolean;
93
- } & ParseFormatConfig<null | undefined>;
94
- /**
95
- * Array settings:
96
- * - concatType: serialization strategy (`comma` | `multi` | `json`);
97
- * - removeNullable: remove empty items;
98
- * - format: custom array formatter.
99
- */
100
- mapArray: {
101
- concatType: FieldConcatType;
102
- removeNullable?: boolean;
103
- } & FormatConfig<AnyType[]>;
104
- /**
105
- * Object settings:
106
- * - deep: deep (recursive) serialization or treat as JSON string;
107
- * - format: custom object formatter.
108
- */
109
- mapObject: {
110
- deep: boolean;
111
- } & FormatConfig<DataType>;
112
- /**
113
- * Per-field overrides by key.
114
- */
115
- mapFields?: Record<string, FieldConfig>;
116
- };
117
- /**
118
- * Flat serialization result: dictionary key → primitive(s).
119
- */
120
- type SerializedType = Record<string, SerializedTypeType>;
121
- /**
122
- * Generic dictionary of domain data.
123
- */
124
- type DataType = AnyDict;
125
-
126
- declare class SerializerFieldError extends Error {
127
- readonly field: string;
128
- readonly stage: 'parse' | 'format';
129
- readonly originalError: unknown;
130
- constructor(field: string, stage: 'parse' | 'format', originalError: unknown);
131
- }
132
- /**
133
- * Universal serializer/deserializer for values used in forms, filters, and DTOs.
134
- *
135
- * Supports types: `string | number | boolean | Date | [Date, Date] (period) | array | object | nullable`.
136
- * Capabilities:
137
- * - normalize values according to config (trim strings, parse numbers from strings, boolean strings, etc.),
138
- * - transform date periods into paired keys (`from/to`) or a single joined string,
139
- * - build/parse a query string (or JSON) to and from an object.
140
- *
141
- * Example:
142
- * ```ts
143
- * type Filters = { q?: string; active?: boolean; created?: [Date, Date] | null };
144
- * const s = new Serializer<Filters>({
145
- * mapPeriod: { transformMode: { mode: 'split', dateFromKeyPostfix: 'From', dateToKeyPostfix: 'To' } }
146
- * });
147
- *
148
- * // -> { q: 'john', createdFrom: '2025-01-01', createdTo: '2025-01-31' }
149
- * const plain = s.serialize({
150
- * q: ' john ',
151
- * active: undefined,
152
- * created: [new Date('2025-01-01'), new Date('2025-01-31')]
153
- * });
154
- *
155
- * // -> 'q=john&createdFrom=2025-01-01&createdTo=2025-01-31'
156
- * const qs = s.toQuery({ q: 'john', created: [new Date('2025-01-01'), new Date('2025-01-31')] });
157
- *
158
- * // <- { q: 'john', created: [Date, Date] }
159
- * const parsed = s.deserialize('q=john&createdFrom=2025-01-01&createdTo=2025-01-31');
160
- * ```
161
- */
162
- declare class Serializer<EntityType extends DataType> {
163
- readonly config: SerializerConfig;
164
- /**
165
- * Creates a serializer with a partially overridden configuration.
166
- * Provide only the options you want to change (the rest are taken from defaults).
167
- *
168
- * @param config partial transformation configuration
169
- */
170
- constructor(config?: Partial<SerializerConfig>);
171
- /**
172
- * Converts a domain object into a flat serialized representation
173
- * (ready to send to an API or build a query string).
174
- *
175
- * Rules are taken from `config`:
176
- * — strings can be trimmed (if enabled),
177
- * — numbers can be converted from strings/numbers,
178
- * — boolean supports custom true/false representations,
179
- * — dates are formatted by `dateFormat`,
180
- * — date periods can be split/joined,
181
- * — `nullable` can be removed from the result (`remove`) or formatted.
182
- *
183
- * @param obj source object
184
- * @returns a flat dictionary with string/primitive values
185
- */
186
- serialize(obj: EntityType, _seen?: WeakSet<object>): SerializedType;
187
- /**
188
- * Parse serialized data into a domain object.
189
- *
190
- * Source can be:
191
- * — a query string (`key=value&arr=1,2`) or `JSON.stringify(obj)`,
192
- * — an already prepared flat object.
193
- *
194
- * Transformations are reverse of `serialize`: strings → number/boolean/Date/period,
195
- * arrays are collected according to strategy (`comma`/`pipe`/`multi`), objects — deeply or as JSON.
196
- *
197
- * @param val query string or object
198
- * @returns a domain object of the specified type
199
- */
200
- deserialize: (val: string | AnyDict) => EntityType;
201
- /** Parse only query-string input. */
202
- deserializeQuery: (query: string) => EntityType;
203
- /** Parse only JSON object input. */
204
- deserializeJson: (json: string) => EntityType;
205
- /**
206
- * Build a query string from a domain object using `serialize` rules
207
- * and the array joining strategy (`concatType`).
208
- *
209
- * @param val domain object
210
- * @returns query string (suitable for URL or history API)
211
- */
212
- toQuery: (val: EntityType) => string;
213
- /**
214
- * Returns a new serializer instance with a merged configuration.
215
- * Useful for ad-hoc overrides for a specific call.
216
- *
217
- * @param config partial config changes
218
- * @returns new `Serializer` with the provided `config` applied
219
- */
220
- withConfig(config: Partial<SerializerConfig>): Serializer<EntityType>;
221
- private serializeElement;
222
- private deserializeElement;
223
- private parseQuery;
224
- private parseJsonObject;
225
- private parseInputString;
226
- private mergeConfig;
227
- private resolveArrayFieldModes;
228
- }
229
-
230
8
  declare const createQuerySerializer: <EntityType extends DataType = DataType>(config?: Partial<SerializerConfig>) => Serializer<EntityType>;
231
9
  declare const createBodySerializer: <EntityType extends DataType = DataType>(config?: Partial<SerializerConfig>) => Serializer<EntityType>;
232
10
  declare const createStrictSerializer: <EntityType extends DataType = DataType>(config?: Partial<SerializerConfig>) => Serializer<EntityType>;
233
11
 
234
- type StorageStrategy = 'memory' | 'lru' | 'session' | 'persist';
235
- type StorageStrategyOptions = {
236
- lruLimit?: number;
237
- };
238
-
239
- type StorageInterface<Key, Type> = {
240
- prefix?: string;
241
- get(key: Key): Type | null;
242
- set(key: Key, value: Type): void;
243
- remove(key: Key): void;
244
- clear(): void;
245
- get length(): number;
246
- };
247
-
248
- declare class LruCache<KeyT, ValueT> implements StorageInterface<KeyT, ValueT> {
249
- private map;
250
- private _limit;
251
- constructor(limit?: number);
252
- get limit(): number;
253
- get length(): number;
254
- set limit(value: number);
255
- get(key: KeyT): NonNullable<ValueT> | null;
256
- set(key: KeyT, value: ValueT): void;
257
- remove(key: KeyT): boolean;
258
- clear(): void;
259
- has(key: KeyT): boolean;
260
- keys(): KeyT[];
261
- values(): ValueT[];
262
- entries(): [KeyT, ValueT][];
263
- toArray(): ValueT[];
264
- fromArray(entries: [KeyT, ValueT][]): void;
265
- }
266
-
267
- /**
268
- * Factory for data storage strategies.
269
- *
270
- * Returns a `StorageInterface` implementation depending on the selected strategy:
271
- * - `'memory'` — in-memory storage (for the session lifetime);
272
- * - `'session'` — `sessionStorage`, lives until the tab is closed;
273
- * - `'persist'` — `localStorage`, persists between sessions;
274
- * - `'lru'` — size-limited cache (Least Recently Used).
275
- *
276
- * Used to choose an appropriate storage implementation
277
- * depending on the scenario: temporary data, long-term, cache, etc.
278
- *
279
- * @param strategy storage strategy type (`memory`, `session`, `persist`, `lru`)
280
- * @returns instance implementing `StorageInterface<Key, Type>`
281
- */
282
- declare const storageStrategy: <Key = string, Type extends AnyType = AnyDict>(strategy: StorageStrategy, options?: StorageStrategyOptions) => StorageInterface<Key, Type>;
283
-
284
12
  /**
285
13
  * Object for request body (payload).
286
14
  * Commonly used with POST/PUT/PATCH/DELETE.
@@ -749,7 +477,7 @@ type PagedQueryStoreProviderConfig = {
749
477
  * - reactive signals: `items`, `loading`, `cached`;
750
478
  * - methods to control page/size/query;
751
479
  * - optional LRU cache by pages;
752
- * - configurable transport (GET/POST/PATCH/…).
480
+ * - configurable transport (GET/POST/PATCH/…).
753
481
  *
754
482
  * Example:
755
483
  * ```ts
@@ -1033,6 +761,7 @@ declare class DictStore<Type extends AnyDict> {
1033
761
  private readonly ttlMs?;
1034
762
  private readonly revalidate;
1035
763
  private readonly cacheUpdatedAt;
764
+ private readonly presetFilters;
1036
765
  /**
1037
766
  * Search text.
1038
767
  * With `fixed: true` filters the local cache; with `fixed: false` triggers server search.
@@ -1046,7 +775,7 @@ declare class DictStore<Type extends AnyDict> {
1046
775
  private cachedItems;
1047
776
  /**
1048
777
  * Current list of dictionary items.
1049
- * Source — local cache (fixed=true) or data from `PagedQueryStore`.
778
+ * Source local cache (fixed=true) or data from `PagedQueryStore`.
1050
779
  */
1051
780
  items: Signal<readonly Type[]>;
1052
781
  /**
@@ -1070,7 +799,7 @@ declare class DictStore<Type extends AnyDict> {
1070
799
  clearCache(): void;
1071
800
  /**
1072
801
  * Set a search query and filters.
1073
- * With `fixed: false` initiates server search; with `fixed: true` — local filtering.
802
+ * With `fixed: false` initiates server search; with `fixed: true` local filtering.
1074
803
  */
1075
804
  search: (name?: string, filters?: AnyDict) => void;
1076
805
  /**
@@ -1221,6 +950,6 @@ type StatumConfig = PagedQueryProviderConfig & SerializerProviderConfig & DictPr
1221
950
  declare const STATUM_CONFIG: InjectionToken<StatumConfig>;
1222
951
  declare const provideStatum: (config: StatumConfig) => EnvironmentProviders;
1223
952
 
1224
- export { AbortError, CacheMissError, DictLocalStore, DictStore, EntityStore, LruCache, PagedQueryStore, RESOURCE_PROFILES, ResourceStore, STATUM_CONFIG, Serializer, SerializerFieldError, createBodySerializer, createQuerySerializer, createResourceProfile, createStrictSerializer, isAbort, provideStatum, storageStrategy };
1225
- export type { DataType, DictLocalConfig, DictStoreConfig, DictStoreProviderConfig, EntityId, EntityStoreConfig, FetchInput, FetchParams, FieldConfig, OffsetPaginationType, PagedQueryStoreConfig, PagedQueryStoreProviderConfig, QuerySortInput, QuerySortOrder, QuerySortRule, RefetchWithInput, ResourceProfileName, ResourceRoutesMap, ResourceStatus, ResourceStoreOptions, ResourceTraceEvent, RetryConfig, SerializedType, SerializerConfig, SetRouteParamsOptions, StatumConfig, StorageInterface, StorageStrategy, StorageStrategyOptions, Types, UpdateByOffsetOptions, UpdatePageInput, UpdatePageOptions };
953
+ export { AbortError, CacheMissError, DictLocalStore, DictStore, EntityStore, PagedQueryStore, RESOURCE_PROFILES, ResourceStore, STATUM_CONFIG, createBodySerializer, createQuerySerializer, createResourceProfile, createStrictSerializer, isAbort, provideStatum };
954
+ export type { DictLocalConfig, DictStoreConfig, DictStoreProviderConfig, EntityId, EntityStoreConfig, FetchInput, FetchParams, OffsetPaginationType, PagedQueryStoreConfig, PagedQueryStoreProviderConfig, QuerySortInput, QuerySortOrder, QuerySortRule, RefetchWithInput, ResourceProfileName, ResourceRoutesMap, ResourceStatus, ResourceStoreOptions, ResourceTraceEvent, RetryConfig, SetRouteParamsOptions, StatumConfig, UpdateByOffsetOptions, UpdatePageInput, UpdatePageOptions };
1226
955
  //# sourceMappingURL=reforgium-statum.d.ts.map