@flurryx/core 0.8.0 → 1.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/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +122 -3
- package/dist/index.d.ts +122 -3
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/keyed-resource.ts","../src/constants.ts"],"sourcesContent":["export type { ResourceState, StoreEnum } from './resource-state';\nexport type {\n KeyedResourceData,\n KeyedResourceKey,\n ResourceStatus,\n ResourceErrors,\n} from './keyed-resource';\nexport {\n isKeyedResourceData,\n createKeyedResourceData,\n isAnyKeyLoading,\n} from './keyed-resource';\nexport { CACHE_NO_TIMEOUT, DEFAULT_CACHE_TTL_MS } from './constants';\n","import { ResourceState } from
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/keyed-resource.ts","../src/constants.ts"],"sourcesContent":["export type { ResourceState, StoreEnum } from './resource-state';\nexport type {\n KeyedResourceData,\n KeyedResourceKey,\n ResourceStatus,\n ResourceErrors,\n} from './keyed-resource';\nexport {\n isKeyedResourceData,\n createKeyedResourceData,\n isAnyKeyLoading,\n} from './keyed-resource';\nexport { CACHE_NO_TIMEOUT, DEFAULT_CACHE_TTL_MS } from './constants';\n","import { ResourceState } from \"./resource-state\";\n\n/**\n * Type for resource keys used to index entities in a {@link KeyedResourceData} slot.\n */\nexport type KeyedResourceKey = string | number;\n\n/**\n * Literal union for resource status: `'Success'` or `'Error'`.\n */\nexport type ResourceStatus = NonNullable<ResourceState<unknown>[\"status\"]>;\n\n/**\n * Normalized error array shape: `Array<{ code: string; message: string }>`.\n */\nexport type ResourceErrors = NonNullable<ResourceState<unknown>[\"errors\"]>;\n\n/**\n * Container for keyed (indexed by ID) resource data.\n *\n * Each entity gets **independent** loading, status, and error tracking.\n * Use this when a single store slot manages multiple entities (e.g. user profiles by ID).\n *\n * @template TKey - The entity identifier type (`string` or `number`).\n * @template TValue - The entity type.\n *\n * @example\n * ```ts\n * interface InvoiceStoreConfig {\n * ITEMS: KeyedResourceData<string, Invoice>;\n * }\n *\n * // Accessing per-key state:\n * const data = store.get('ITEMS')().data;\n * const invoice = data?.entities['inv-123'];\n * const loading = data?.isLoading['inv-123'];\n * const errors = data?.errors['inv-123'];\n * ```\n */\nexport interface KeyedResourceData<TKey extends KeyedResourceKey, TValue> {\n /** Map of entity ID → entity value. */\n entities: Partial<Record<TKey, TValue>>;\n /** Map of entity ID → whether that entity is currently loading. */\n isLoading: Partial<Record<TKey, boolean>>;\n /** Map of entity ID → resource status (`'Success'` or `'Error'`). */\n status: Partial<Record<TKey, ResourceStatus>>;\n /** Map of entity ID → error array for that entity. */\n errors: Partial<Record<TKey, ResourceErrors>>;\n}\n\n/**\n * Type guard that checks whether a value is a {@link KeyedResourceData} structure.\n *\n * @param value - The value to check.\n * @returns `true` if the value has `entities`, `isLoading`, `status`, and `errors` object fields.\n *\n * @example\n * ```ts\n * const state = store.get('ITEMS')();\n * if (isKeyedResourceData(state.data)) {\n * console.log(state.data.entities);\n * }\n * ```\n */\nexport function isKeyedResourceData(\n value: unknown\n): value is KeyedResourceData<KeyedResourceKey, unknown> {\n if (typeof value !== \"object\" || value === null) {\n return false;\n }\n\n const data = value as Partial<KeyedResourceData<KeyedResourceKey, unknown>>;\n return (\n typeof data.entities === \"object\" &&\n data.entities !== null &&\n typeof data.isLoading === \"object\" &&\n data.isLoading !== null &&\n typeof data.status === \"object\" &&\n data.status !== null &&\n typeof data.errors === \"object\" &&\n data.errors !== null\n );\n}\n\n/**\n * Creates an empty {@link KeyedResourceData} with all maps initialized to `{}`.\n *\n * @template TKey - The entity identifier type.\n * @template TValue - The entity type.\n * @returns A new `KeyedResourceData` with empty `entities`, `isLoading`, `status`, and `errors`.\n *\n * @example\n * ```ts\n * const initial = createKeyedResourceData<string, Invoice>();\n * // { entities: {}, isLoading: {}, status: {}, errors: {} }\n * ```\n */\nexport function createKeyedResourceData<\n TKey extends KeyedResourceKey,\n TValue\n>(): KeyedResourceData<TKey, TValue> {\n return {\n entities: {} as Partial<Record<TKey, TValue>>,\n isLoading: {} as Partial<Record<TKey, boolean>>,\n status: {} as Partial<Record<TKey, ResourceStatus>>,\n errors: {} as Partial<Record<TKey, ResourceErrors>>,\n };\n}\n\n/**\n * Checks whether any entity in a keyed loading map is currently loading.\n *\n * @param loading - The `isLoading` map from a {@link KeyedResourceData}.\n * @returns `true` if at least one key has a value of `true`.\n *\n * @example\n * ```ts\n * const data = store.get('ITEMS')().data;\n * if (data && isAnyKeyLoading(data.isLoading)) {\n * console.log('At least one item is loading');\n * }\n * ```\n */\nexport function isAnyKeyLoading<TKey extends KeyedResourceKey>(\n loading: Partial<Record<TKey, boolean>>\n): boolean {\n return Object.values(loading).some((value) => value === true);\n}\n","/**\n * Sentinel value indicating the cache should never expire.\n * Pass to `@SkipIfCached` `timeoutMs` parameter to disable TTL-based invalidation.\n *\n * @example\n * ```ts\n * @SkipIfCached('LIST', (i) => i.store, false, CACHE_NO_TIMEOUT)\n * ```\n */\nexport const CACHE_NO_TIMEOUT = Infinity;\n\n/**\n * Default cache time-to-live in milliseconds: **5 minutes** (300 000 ms).\n * Used by `@SkipIfCached` when no `timeoutMs` is provided.\n */\nexport const DEFAULT_CACHE_TTL_MS = 5 * 60 * 1000;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACgEO,SAAS,oBACd,OACuD;AACvD,MAAI,OAAO,UAAU,YAAY,UAAU,MAAM;AAC/C,WAAO;AAAA,EACT;AAEA,QAAM,OAAO;AACb,SACE,OAAO,KAAK,aAAa,YACzB,KAAK,aAAa,QAClB,OAAO,KAAK,cAAc,YAC1B,KAAK,cAAc,QACnB,OAAO,KAAK,WAAW,YACvB,KAAK,WAAW,QAChB,OAAO,KAAK,WAAW,YACvB,KAAK,WAAW;AAEpB;AAeO,SAAS,0BAGqB;AACnC,SAAO;AAAA,IACL,UAAU,CAAC;AAAA,IACX,WAAW,CAAC;AAAA,IACZ,QAAQ,CAAC;AAAA,IACT,QAAQ,CAAC;AAAA,EACX;AACF;AAgBO,SAAS,gBACd,SACS;AACT,SAAO,OAAO,OAAO,OAAO,EAAE,KAAK,CAAC,UAAU,UAAU,IAAI;AAC9D;;;ACtHO,IAAM,mBAAmB;AAMzB,IAAM,uBAAuB,IAAI,KAAK;","names":[]}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,28 +1,147 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generic state wrapper for an async resource (e.g. an HTTP call).
|
|
3
|
+
*
|
|
4
|
+
* Every store slot holds a `ResourceState`. It starts as idle and transitions
|
|
5
|
+
* through loading → success/error as the underlying operation progresses.
|
|
6
|
+
*
|
|
7
|
+
* @template T - The type of the data payload.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* // Initial (idle) state
|
|
12
|
+
* { data: undefined, isLoading: false, status: undefined, errors: undefined }
|
|
13
|
+
*
|
|
14
|
+
* // Loading
|
|
15
|
+
* { data: undefined, isLoading: true, status: undefined, errors: undefined }
|
|
16
|
+
*
|
|
17
|
+
* // Success
|
|
18
|
+
* { data: product, isLoading: false, status: 'Success', errors: undefined }
|
|
19
|
+
*
|
|
20
|
+
* // Error
|
|
21
|
+
* { data: undefined, isLoading: false, status: 'Error', errors: [{ code: '404', message: 'Not found' }] }
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
1
24
|
interface ResourceState<T> {
|
|
25
|
+
/** Whether the resource is currently being fetched. */
|
|
2
26
|
isLoading?: boolean;
|
|
27
|
+
/** The data payload. `undefined` until the first successful fetch. */
|
|
3
28
|
data?: T;
|
|
4
|
-
|
|
29
|
+
/** `'Success'` after a successful fetch, `'Error'` after a failure. `undefined` while idle or loading. */
|
|
30
|
+
status?: "Success" | "Error";
|
|
31
|
+
/** Normalized error array. Present only when `status` is `'Error'`. */
|
|
5
32
|
errors?: Array<{
|
|
6
33
|
code: string;
|
|
7
34
|
message: string;
|
|
8
35
|
}>;
|
|
9
36
|
}
|
|
37
|
+
/**
|
|
38
|
+
* Union type accepted as a store key identifier.
|
|
39
|
+
*/
|
|
10
40
|
type StoreEnum = string | number | symbol;
|
|
11
41
|
|
|
42
|
+
/**
|
|
43
|
+
* Type for resource keys used to index entities in a {@link KeyedResourceData} slot.
|
|
44
|
+
*/
|
|
12
45
|
type KeyedResourceKey = string | number;
|
|
13
|
-
|
|
14
|
-
|
|
46
|
+
/**
|
|
47
|
+
* Literal union for resource status: `'Success'` or `'Error'`.
|
|
48
|
+
*/
|
|
49
|
+
type ResourceStatus = NonNullable<ResourceState<unknown>["status"]>;
|
|
50
|
+
/**
|
|
51
|
+
* Normalized error array shape: `Array<{ code: string; message: string }>`.
|
|
52
|
+
*/
|
|
53
|
+
type ResourceErrors = NonNullable<ResourceState<unknown>["errors"]>;
|
|
54
|
+
/**
|
|
55
|
+
* Container for keyed (indexed by ID) resource data.
|
|
56
|
+
*
|
|
57
|
+
* Each entity gets **independent** loading, status, and error tracking.
|
|
58
|
+
* Use this when a single store slot manages multiple entities (e.g. user profiles by ID).
|
|
59
|
+
*
|
|
60
|
+
* @template TKey - The entity identifier type (`string` or `number`).
|
|
61
|
+
* @template TValue - The entity type.
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* ```ts
|
|
65
|
+
* interface InvoiceStoreConfig {
|
|
66
|
+
* ITEMS: KeyedResourceData<string, Invoice>;
|
|
67
|
+
* }
|
|
68
|
+
*
|
|
69
|
+
* // Accessing per-key state:
|
|
70
|
+
* const data = store.get('ITEMS')().data;
|
|
71
|
+
* const invoice = data?.entities['inv-123'];
|
|
72
|
+
* const loading = data?.isLoading['inv-123'];
|
|
73
|
+
* const errors = data?.errors['inv-123'];
|
|
74
|
+
* ```
|
|
75
|
+
*/
|
|
15
76
|
interface KeyedResourceData<TKey extends KeyedResourceKey, TValue> {
|
|
77
|
+
/** Map of entity ID → entity value. */
|
|
16
78
|
entities: Partial<Record<TKey, TValue>>;
|
|
79
|
+
/** Map of entity ID → whether that entity is currently loading. */
|
|
17
80
|
isLoading: Partial<Record<TKey, boolean>>;
|
|
81
|
+
/** Map of entity ID → resource status (`'Success'` or `'Error'`). */
|
|
18
82
|
status: Partial<Record<TKey, ResourceStatus>>;
|
|
83
|
+
/** Map of entity ID → error array for that entity. */
|
|
19
84
|
errors: Partial<Record<TKey, ResourceErrors>>;
|
|
20
85
|
}
|
|
86
|
+
/**
|
|
87
|
+
* Type guard that checks whether a value is a {@link KeyedResourceData} structure.
|
|
88
|
+
*
|
|
89
|
+
* @param value - The value to check.
|
|
90
|
+
* @returns `true` if the value has `entities`, `isLoading`, `status`, and `errors` object fields.
|
|
91
|
+
*
|
|
92
|
+
* @example
|
|
93
|
+
* ```ts
|
|
94
|
+
* const state = store.get('ITEMS')();
|
|
95
|
+
* if (isKeyedResourceData(state.data)) {
|
|
96
|
+
* console.log(state.data.entities);
|
|
97
|
+
* }
|
|
98
|
+
* ```
|
|
99
|
+
*/
|
|
21
100
|
declare function isKeyedResourceData(value: unknown): value is KeyedResourceData<KeyedResourceKey, unknown>;
|
|
101
|
+
/**
|
|
102
|
+
* Creates an empty {@link KeyedResourceData} with all maps initialized to `{}`.
|
|
103
|
+
*
|
|
104
|
+
* @template TKey - The entity identifier type.
|
|
105
|
+
* @template TValue - The entity type.
|
|
106
|
+
* @returns A new `KeyedResourceData` with empty `entities`, `isLoading`, `status`, and `errors`.
|
|
107
|
+
*
|
|
108
|
+
* @example
|
|
109
|
+
* ```ts
|
|
110
|
+
* const initial = createKeyedResourceData<string, Invoice>();
|
|
111
|
+
* // { entities: {}, isLoading: {}, status: {}, errors: {} }
|
|
112
|
+
* ```
|
|
113
|
+
*/
|
|
22
114
|
declare function createKeyedResourceData<TKey extends KeyedResourceKey, TValue>(): KeyedResourceData<TKey, TValue>;
|
|
115
|
+
/**
|
|
116
|
+
* Checks whether any entity in a keyed loading map is currently loading.
|
|
117
|
+
*
|
|
118
|
+
* @param loading - The `isLoading` map from a {@link KeyedResourceData}.
|
|
119
|
+
* @returns `true` if at least one key has a value of `true`.
|
|
120
|
+
*
|
|
121
|
+
* @example
|
|
122
|
+
* ```ts
|
|
123
|
+
* const data = store.get('ITEMS')().data;
|
|
124
|
+
* if (data && isAnyKeyLoading(data.isLoading)) {
|
|
125
|
+
* console.log('At least one item is loading');
|
|
126
|
+
* }
|
|
127
|
+
* ```
|
|
128
|
+
*/
|
|
23
129
|
declare function isAnyKeyLoading<TKey extends KeyedResourceKey>(loading: Partial<Record<TKey, boolean>>): boolean;
|
|
24
130
|
|
|
131
|
+
/**
|
|
132
|
+
* Sentinel value indicating the cache should never expire.
|
|
133
|
+
* Pass to `@SkipIfCached` `timeoutMs` parameter to disable TTL-based invalidation.
|
|
134
|
+
*
|
|
135
|
+
* @example
|
|
136
|
+
* ```ts
|
|
137
|
+
* @SkipIfCached('LIST', (i) => i.store, false, CACHE_NO_TIMEOUT)
|
|
138
|
+
* ```
|
|
139
|
+
*/
|
|
25
140
|
declare const CACHE_NO_TIMEOUT: number;
|
|
141
|
+
/**
|
|
142
|
+
* Default cache time-to-live in milliseconds: **5 minutes** (300 000 ms).
|
|
143
|
+
* Used by `@SkipIfCached` when no `timeoutMs` is provided.
|
|
144
|
+
*/
|
|
26
145
|
declare const DEFAULT_CACHE_TTL_MS: number;
|
|
27
146
|
|
|
28
147
|
export { CACHE_NO_TIMEOUT, DEFAULT_CACHE_TTL_MS, type KeyedResourceData, type KeyedResourceKey, type ResourceErrors, type ResourceState, type ResourceStatus, type StoreEnum, createKeyedResourceData, isAnyKeyLoading, isKeyedResourceData };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,28 +1,147 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generic state wrapper for an async resource (e.g. an HTTP call).
|
|
3
|
+
*
|
|
4
|
+
* Every store slot holds a `ResourceState`. It starts as idle and transitions
|
|
5
|
+
* through loading → success/error as the underlying operation progresses.
|
|
6
|
+
*
|
|
7
|
+
* @template T - The type of the data payload.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* // Initial (idle) state
|
|
12
|
+
* { data: undefined, isLoading: false, status: undefined, errors: undefined }
|
|
13
|
+
*
|
|
14
|
+
* // Loading
|
|
15
|
+
* { data: undefined, isLoading: true, status: undefined, errors: undefined }
|
|
16
|
+
*
|
|
17
|
+
* // Success
|
|
18
|
+
* { data: product, isLoading: false, status: 'Success', errors: undefined }
|
|
19
|
+
*
|
|
20
|
+
* // Error
|
|
21
|
+
* { data: undefined, isLoading: false, status: 'Error', errors: [{ code: '404', message: 'Not found' }] }
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
1
24
|
interface ResourceState<T> {
|
|
25
|
+
/** Whether the resource is currently being fetched. */
|
|
2
26
|
isLoading?: boolean;
|
|
27
|
+
/** The data payload. `undefined` until the first successful fetch. */
|
|
3
28
|
data?: T;
|
|
4
|
-
|
|
29
|
+
/** `'Success'` after a successful fetch, `'Error'` after a failure. `undefined` while idle or loading. */
|
|
30
|
+
status?: "Success" | "Error";
|
|
31
|
+
/** Normalized error array. Present only when `status` is `'Error'`. */
|
|
5
32
|
errors?: Array<{
|
|
6
33
|
code: string;
|
|
7
34
|
message: string;
|
|
8
35
|
}>;
|
|
9
36
|
}
|
|
37
|
+
/**
|
|
38
|
+
* Union type accepted as a store key identifier.
|
|
39
|
+
*/
|
|
10
40
|
type StoreEnum = string | number | symbol;
|
|
11
41
|
|
|
42
|
+
/**
|
|
43
|
+
* Type for resource keys used to index entities in a {@link KeyedResourceData} slot.
|
|
44
|
+
*/
|
|
12
45
|
type KeyedResourceKey = string | number;
|
|
13
|
-
|
|
14
|
-
|
|
46
|
+
/**
|
|
47
|
+
* Literal union for resource status: `'Success'` or `'Error'`.
|
|
48
|
+
*/
|
|
49
|
+
type ResourceStatus = NonNullable<ResourceState<unknown>["status"]>;
|
|
50
|
+
/**
|
|
51
|
+
* Normalized error array shape: `Array<{ code: string; message: string }>`.
|
|
52
|
+
*/
|
|
53
|
+
type ResourceErrors = NonNullable<ResourceState<unknown>["errors"]>;
|
|
54
|
+
/**
|
|
55
|
+
* Container for keyed (indexed by ID) resource data.
|
|
56
|
+
*
|
|
57
|
+
* Each entity gets **independent** loading, status, and error tracking.
|
|
58
|
+
* Use this when a single store slot manages multiple entities (e.g. user profiles by ID).
|
|
59
|
+
*
|
|
60
|
+
* @template TKey - The entity identifier type (`string` or `number`).
|
|
61
|
+
* @template TValue - The entity type.
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* ```ts
|
|
65
|
+
* interface InvoiceStoreConfig {
|
|
66
|
+
* ITEMS: KeyedResourceData<string, Invoice>;
|
|
67
|
+
* }
|
|
68
|
+
*
|
|
69
|
+
* // Accessing per-key state:
|
|
70
|
+
* const data = store.get('ITEMS')().data;
|
|
71
|
+
* const invoice = data?.entities['inv-123'];
|
|
72
|
+
* const loading = data?.isLoading['inv-123'];
|
|
73
|
+
* const errors = data?.errors['inv-123'];
|
|
74
|
+
* ```
|
|
75
|
+
*/
|
|
15
76
|
interface KeyedResourceData<TKey extends KeyedResourceKey, TValue> {
|
|
77
|
+
/** Map of entity ID → entity value. */
|
|
16
78
|
entities: Partial<Record<TKey, TValue>>;
|
|
79
|
+
/** Map of entity ID → whether that entity is currently loading. */
|
|
17
80
|
isLoading: Partial<Record<TKey, boolean>>;
|
|
81
|
+
/** Map of entity ID → resource status (`'Success'` or `'Error'`). */
|
|
18
82
|
status: Partial<Record<TKey, ResourceStatus>>;
|
|
83
|
+
/** Map of entity ID → error array for that entity. */
|
|
19
84
|
errors: Partial<Record<TKey, ResourceErrors>>;
|
|
20
85
|
}
|
|
86
|
+
/**
|
|
87
|
+
* Type guard that checks whether a value is a {@link KeyedResourceData} structure.
|
|
88
|
+
*
|
|
89
|
+
* @param value - The value to check.
|
|
90
|
+
* @returns `true` if the value has `entities`, `isLoading`, `status`, and `errors` object fields.
|
|
91
|
+
*
|
|
92
|
+
* @example
|
|
93
|
+
* ```ts
|
|
94
|
+
* const state = store.get('ITEMS')();
|
|
95
|
+
* if (isKeyedResourceData(state.data)) {
|
|
96
|
+
* console.log(state.data.entities);
|
|
97
|
+
* }
|
|
98
|
+
* ```
|
|
99
|
+
*/
|
|
21
100
|
declare function isKeyedResourceData(value: unknown): value is KeyedResourceData<KeyedResourceKey, unknown>;
|
|
101
|
+
/**
|
|
102
|
+
* Creates an empty {@link KeyedResourceData} with all maps initialized to `{}`.
|
|
103
|
+
*
|
|
104
|
+
* @template TKey - The entity identifier type.
|
|
105
|
+
* @template TValue - The entity type.
|
|
106
|
+
* @returns A new `KeyedResourceData` with empty `entities`, `isLoading`, `status`, and `errors`.
|
|
107
|
+
*
|
|
108
|
+
* @example
|
|
109
|
+
* ```ts
|
|
110
|
+
* const initial = createKeyedResourceData<string, Invoice>();
|
|
111
|
+
* // { entities: {}, isLoading: {}, status: {}, errors: {} }
|
|
112
|
+
* ```
|
|
113
|
+
*/
|
|
22
114
|
declare function createKeyedResourceData<TKey extends KeyedResourceKey, TValue>(): KeyedResourceData<TKey, TValue>;
|
|
115
|
+
/**
|
|
116
|
+
* Checks whether any entity in a keyed loading map is currently loading.
|
|
117
|
+
*
|
|
118
|
+
* @param loading - The `isLoading` map from a {@link KeyedResourceData}.
|
|
119
|
+
* @returns `true` if at least one key has a value of `true`.
|
|
120
|
+
*
|
|
121
|
+
* @example
|
|
122
|
+
* ```ts
|
|
123
|
+
* const data = store.get('ITEMS')().data;
|
|
124
|
+
* if (data && isAnyKeyLoading(data.isLoading)) {
|
|
125
|
+
* console.log('At least one item is loading');
|
|
126
|
+
* }
|
|
127
|
+
* ```
|
|
128
|
+
*/
|
|
23
129
|
declare function isAnyKeyLoading<TKey extends KeyedResourceKey>(loading: Partial<Record<TKey, boolean>>): boolean;
|
|
24
130
|
|
|
131
|
+
/**
|
|
132
|
+
* Sentinel value indicating the cache should never expire.
|
|
133
|
+
* Pass to `@SkipIfCached` `timeoutMs` parameter to disable TTL-based invalidation.
|
|
134
|
+
*
|
|
135
|
+
* @example
|
|
136
|
+
* ```ts
|
|
137
|
+
* @SkipIfCached('LIST', (i) => i.store, false, CACHE_NO_TIMEOUT)
|
|
138
|
+
* ```
|
|
139
|
+
*/
|
|
25
140
|
declare const CACHE_NO_TIMEOUT: number;
|
|
141
|
+
/**
|
|
142
|
+
* Default cache time-to-live in milliseconds: **5 minutes** (300 000 ms).
|
|
143
|
+
* Used by `@SkipIfCached` when no `timeoutMs` is provided.
|
|
144
|
+
*/
|
|
26
145
|
declare const DEFAULT_CACHE_TTL_MS: number;
|
|
27
146
|
|
|
28
147
|
export { CACHE_NO_TIMEOUT, DEFAULT_CACHE_TTL_MS, type KeyedResourceData, type KeyedResourceKey, type ResourceErrors, type ResourceState, type ResourceStatus, type StoreEnum, createKeyedResourceData, isAnyKeyLoading, isKeyedResourceData };
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/keyed-resource.ts","../src/constants.ts"],"sourcesContent":["import { ResourceState } from
|
|
1
|
+
{"version":3,"sources":["../src/keyed-resource.ts","../src/constants.ts"],"sourcesContent":["import { ResourceState } from \"./resource-state\";\n\n/**\n * Type for resource keys used to index entities in a {@link KeyedResourceData} slot.\n */\nexport type KeyedResourceKey = string | number;\n\n/**\n * Literal union for resource status: `'Success'` or `'Error'`.\n */\nexport type ResourceStatus = NonNullable<ResourceState<unknown>[\"status\"]>;\n\n/**\n * Normalized error array shape: `Array<{ code: string; message: string }>`.\n */\nexport type ResourceErrors = NonNullable<ResourceState<unknown>[\"errors\"]>;\n\n/**\n * Container for keyed (indexed by ID) resource data.\n *\n * Each entity gets **independent** loading, status, and error tracking.\n * Use this when a single store slot manages multiple entities (e.g. user profiles by ID).\n *\n * @template TKey - The entity identifier type (`string` or `number`).\n * @template TValue - The entity type.\n *\n * @example\n * ```ts\n * interface InvoiceStoreConfig {\n * ITEMS: KeyedResourceData<string, Invoice>;\n * }\n *\n * // Accessing per-key state:\n * const data = store.get('ITEMS')().data;\n * const invoice = data?.entities['inv-123'];\n * const loading = data?.isLoading['inv-123'];\n * const errors = data?.errors['inv-123'];\n * ```\n */\nexport interface KeyedResourceData<TKey extends KeyedResourceKey, TValue> {\n /** Map of entity ID → entity value. */\n entities: Partial<Record<TKey, TValue>>;\n /** Map of entity ID → whether that entity is currently loading. */\n isLoading: Partial<Record<TKey, boolean>>;\n /** Map of entity ID → resource status (`'Success'` or `'Error'`). */\n status: Partial<Record<TKey, ResourceStatus>>;\n /** Map of entity ID → error array for that entity. */\n errors: Partial<Record<TKey, ResourceErrors>>;\n}\n\n/**\n * Type guard that checks whether a value is a {@link KeyedResourceData} structure.\n *\n * @param value - The value to check.\n * @returns `true` if the value has `entities`, `isLoading`, `status`, and `errors` object fields.\n *\n * @example\n * ```ts\n * const state = store.get('ITEMS')();\n * if (isKeyedResourceData(state.data)) {\n * console.log(state.data.entities);\n * }\n * ```\n */\nexport function isKeyedResourceData(\n value: unknown\n): value is KeyedResourceData<KeyedResourceKey, unknown> {\n if (typeof value !== \"object\" || value === null) {\n return false;\n }\n\n const data = value as Partial<KeyedResourceData<KeyedResourceKey, unknown>>;\n return (\n typeof data.entities === \"object\" &&\n data.entities !== null &&\n typeof data.isLoading === \"object\" &&\n data.isLoading !== null &&\n typeof data.status === \"object\" &&\n data.status !== null &&\n typeof data.errors === \"object\" &&\n data.errors !== null\n );\n}\n\n/**\n * Creates an empty {@link KeyedResourceData} with all maps initialized to `{}`.\n *\n * @template TKey - The entity identifier type.\n * @template TValue - The entity type.\n * @returns A new `KeyedResourceData` with empty `entities`, `isLoading`, `status`, and `errors`.\n *\n * @example\n * ```ts\n * const initial = createKeyedResourceData<string, Invoice>();\n * // { entities: {}, isLoading: {}, status: {}, errors: {} }\n * ```\n */\nexport function createKeyedResourceData<\n TKey extends KeyedResourceKey,\n TValue\n>(): KeyedResourceData<TKey, TValue> {\n return {\n entities: {} as Partial<Record<TKey, TValue>>,\n isLoading: {} as Partial<Record<TKey, boolean>>,\n status: {} as Partial<Record<TKey, ResourceStatus>>,\n errors: {} as Partial<Record<TKey, ResourceErrors>>,\n };\n}\n\n/**\n * Checks whether any entity in a keyed loading map is currently loading.\n *\n * @param loading - The `isLoading` map from a {@link KeyedResourceData}.\n * @returns `true` if at least one key has a value of `true`.\n *\n * @example\n * ```ts\n * const data = store.get('ITEMS')().data;\n * if (data && isAnyKeyLoading(data.isLoading)) {\n * console.log('At least one item is loading');\n * }\n * ```\n */\nexport function isAnyKeyLoading<TKey extends KeyedResourceKey>(\n loading: Partial<Record<TKey, boolean>>\n): boolean {\n return Object.values(loading).some((value) => value === true);\n}\n","/**\n * Sentinel value indicating the cache should never expire.\n * Pass to `@SkipIfCached` `timeoutMs` parameter to disable TTL-based invalidation.\n *\n * @example\n * ```ts\n * @SkipIfCached('LIST', (i) => i.store, false, CACHE_NO_TIMEOUT)\n * ```\n */\nexport const CACHE_NO_TIMEOUT = Infinity;\n\n/**\n * Default cache time-to-live in milliseconds: **5 minutes** (300 000 ms).\n * Used by `@SkipIfCached` when no `timeoutMs` is provided.\n */\nexport const DEFAULT_CACHE_TTL_MS = 5 * 60 * 1000;\n"],"mappings":";AAgEO,SAAS,oBACd,OACuD;AACvD,MAAI,OAAO,UAAU,YAAY,UAAU,MAAM;AAC/C,WAAO;AAAA,EACT;AAEA,QAAM,OAAO;AACb,SACE,OAAO,KAAK,aAAa,YACzB,KAAK,aAAa,QAClB,OAAO,KAAK,cAAc,YAC1B,KAAK,cAAc,QACnB,OAAO,KAAK,WAAW,YACvB,KAAK,WAAW,QAChB,OAAO,KAAK,WAAW,YACvB,KAAK,WAAW;AAEpB;AAeO,SAAS,0BAGqB;AACnC,SAAO;AAAA,IACL,UAAU,CAAC;AAAA,IACX,WAAW,CAAC;AAAA,IACZ,QAAQ,CAAC;AAAA,IACT,QAAQ,CAAC;AAAA,EACX;AACF;AAgBO,SAAS,gBACd,SACS;AACT,SAAO,OAAO,OAAO,OAAO,EAAE,KAAK,CAAC,UAAU,UAAU,IAAI;AAC9D;;;ACtHO,IAAM,mBAAmB;AAMzB,IAAM,uBAAuB,IAAI,KAAK;","names":[]}
|