@flurryx/store 0.8.4 → 1.0.1
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 +1233 -320
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +588 -18
- package/dist/index.d.ts +588 -18
- package/dist/index.js +1236 -334
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,176 @@
|
|
|
1
1
|
import { Signal, InjectionToken } from '@angular/core';
|
|
2
|
-
import { ResourceState, KeyedResourceKey } from '@flurryx/core';
|
|
2
|
+
import { ResourceState, KeyedResourceData, KeyedResourceKey } from '@flurryx/core';
|
|
3
|
+
|
|
4
|
+
/** Message produced by `store.update(key, partial)` — merges partial state into a slot. */
|
|
5
|
+
type UpdateStoreMessage<TData extends StoreDataShape<TData>, TKey extends StoreKey<TData> = StoreKey<TData>> = {
|
|
6
|
+
readonly [K in TKey]: {
|
|
7
|
+
readonly type: "update";
|
|
8
|
+
readonly key: K;
|
|
9
|
+
readonly state: Partial<TData[K]>;
|
|
10
|
+
};
|
|
11
|
+
}[TKey];
|
|
12
|
+
/** Message produced by `store.clear(key)` — resets a single slot to its initial state. */
|
|
13
|
+
type ClearStoreMessage<TData extends StoreDataShape<TData>, TKey extends StoreKey<TData> = StoreKey<TData>> = {
|
|
14
|
+
readonly [K in TKey]: {
|
|
15
|
+
readonly type: "clear";
|
|
16
|
+
readonly key: K;
|
|
17
|
+
};
|
|
18
|
+
}[TKey];
|
|
19
|
+
/** Message produced by `store.clearAll()` — resets every slot in the store. */
|
|
20
|
+
interface ClearAllStoreMessage<TData extends StoreDataShape<TData>> {
|
|
21
|
+
readonly type: "clearAll";
|
|
22
|
+
}
|
|
23
|
+
/** Message produced by `store.startLoading(key)` — sets `isLoading: true` and clears `status`/`errors`. */
|
|
24
|
+
type StartLoadingStoreMessage<TData extends StoreDataShape<TData>, TKey extends StoreKey<TData> = StoreKey<TData>> = {
|
|
25
|
+
readonly [K in TKey]: {
|
|
26
|
+
readonly type: "startLoading";
|
|
27
|
+
readonly key: K;
|
|
28
|
+
};
|
|
29
|
+
}[TKey];
|
|
30
|
+
/** Message produced by `store.stopLoading(key)` — sets `isLoading: false`. */
|
|
31
|
+
type StopLoadingStoreMessage<TData extends StoreDataShape<TData>, TKey extends StoreKey<TData> = StoreKey<TData>> = {
|
|
32
|
+
readonly [K in TKey]: {
|
|
33
|
+
readonly type: "stopLoading";
|
|
34
|
+
readonly key: K;
|
|
35
|
+
};
|
|
36
|
+
}[TKey];
|
|
37
|
+
/** Message produced by `store.updateKeyedOne(key, resourceKey, entity)` — merges a single entity into a keyed slot. */
|
|
38
|
+
type UpdateKeyedOneStoreMessage<TData extends StoreDataShape<TData>, TKey extends StoreKey<TData> = StoreKey<TData>> = {
|
|
39
|
+
readonly [K in KeyedStoreKey<TData, TKey>]: {
|
|
40
|
+
readonly type: "updateKeyedOne";
|
|
41
|
+
readonly key: K;
|
|
42
|
+
readonly resourceKey: KeyedResourceEntryKey<TData, K>;
|
|
43
|
+
readonly entity: KeyedResourceEntryValue<TData, K>;
|
|
44
|
+
};
|
|
45
|
+
}[KeyedStoreKey<TData, TKey>];
|
|
46
|
+
/** Message produced by `store.clearKeyedOne(key, resourceKey)` — removes a single entity from a keyed slot. */
|
|
47
|
+
type ClearKeyedOneStoreMessage<TData extends StoreDataShape<TData>, TKey extends StoreKey<TData> = StoreKey<TData>> = {
|
|
48
|
+
readonly [K in KeyedStoreKey<TData, TKey>]: {
|
|
49
|
+
readonly type: "clearKeyedOne";
|
|
50
|
+
readonly key: K;
|
|
51
|
+
readonly resourceKey: KeyedResourceEntryKey<TData, K>;
|
|
52
|
+
};
|
|
53
|
+
}[KeyedStoreKey<TData, TKey>];
|
|
54
|
+
/** Message produced by `store.startKeyedLoading(key, resourceKey)` — marks a single entity as loading. */
|
|
55
|
+
type StartKeyedLoadingStoreMessage<TData extends StoreDataShape<TData>, TKey extends StoreKey<TData> = StoreKey<TData>> = {
|
|
56
|
+
readonly [K in KeyedStoreKey<TData, TKey>]: {
|
|
57
|
+
readonly type: "startKeyedLoading";
|
|
58
|
+
readonly key: K;
|
|
59
|
+
readonly resourceKey: KeyedResourceEntryKey<TData, K>;
|
|
60
|
+
};
|
|
61
|
+
}[KeyedStoreKey<TData, TKey>];
|
|
62
|
+
/** Discriminated union of all typed store messages published to the broker channel. */
|
|
63
|
+
type StoreMessage<TData extends StoreDataShape<TData>, TKey extends StoreKey<TData> = StoreKey<TData>> = UpdateStoreMessage<TData, TKey> | ClearStoreMessage<TData, TKey> | ClearAllStoreMessage<TData> | StartLoadingStoreMessage<TData, TKey> | StopLoadingStoreMessage<TData, TKey> | UpdateKeyedOneStoreMessage<TData, TKey> | ClearKeyedOneStoreMessage<TData, TKey> | StartKeyedLoadingStoreMessage<TData, TKey>;
|
|
64
|
+
/** Full store state captured at a point in time, keyed by slot name. Used by history and time travel. */
|
|
65
|
+
type StoreSnapshot<TData extends StoreDataShape<TData>, TKey extends StoreKey<TData> = StoreKey<TData>> = Partial<{
|
|
66
|
+
readonly [K in TKey]: TData[K];
|
|
67
|
+
}>;
|
|
68
|
+
/** Delivery status of a broker message: `"pending"` → `"acknowledged"` or `"dead-letter"`. */
|
|
69
|
+
type StoreMessageStatus = "pending" | "acknowledged" | "dead-letter";
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Persisted broker message record stored in the active message channel.
|
|
73
|
+
*
|
|
74
|
+
* Message ids are allocated when the message is first published and remain stable
|
|
75
|
+
* across acknowledgement, replay, and dead-letter transitions.
|
|
76
|
+
*/
|
|
77
|
+
interface StoreMessageRecord<TData extends StoreDataShape<TData>, TKey extends StoreKey<TData> = StoreKey<TData>> {
|
|
78
|
+
/** Stable message id used by `replay(...)` and dead-letter recovery APIs. */
|
|
79
|
+
readonly id: number;
|
|
80
|
+
/** Published store message payload. */
|
|
81
|
+
readonly message: StoreMessage<TData, TKey>;
|
|
82
|
+
/** Latest delivery status stored by the broker channel. */
|
|
83
|
+
readonly status: StoreMessageStatus;
|
|
84
|
+
/** Number of delivery attempts made for this message. */
|
|
85
|
+
readonly attempts: number;
|
|
86
|
+
/** Timestamp when the message was first published to the channel. */
|
|
87
|
+
readonly createdAt: number;
|
|
88
|
+
/** Timestamp of the most recent delivery attempt. */
|
|
89
|
+
readonly lastAttemptedAt: number | null;
|
|
90
|
+
/** Timestamp of the most recent successful acknowledgement, if any. */
|
|
91
|
+
readonly acknowledgedAt: number | null;
|
|
92
|
+
/** Last recorded delivery error, or `null` when the latest attempt succeeded. */
|
|
93
|
+
readonly error: string | null;
|
|
94
|
+
}
|
|
95
|
+
/** Minimal string-based storage adapter used by storage-backed message channels. */
|
|
96
|
+
interface StoreMessageChannelStorage {
|
|
97
|
+
getItem(key: string): string | null;
|
|
98
|
+
setItem(key: string, value: string): void;
|
|
99
|
+
removeItem(key: string): void;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Pluggable persistence channel used by the broker to store published messages.
|
|
103
|
+
*
|
|
104
|
+
* The default channel is in-memory, but storage-backed or custom providers can be
|
|
105
|
+
* supplied to keep messages available across refreshes or offline sessions.
|
|
106
|
+
*/
|
|
107
|
+
interface StoreMessageChannel<TData extends StoreDataShape<TData>, TKey extends StoreKey<TData> = StoreKey<TData>> {
|
|
108
|
+
/** Stores a newly published message and allocates its stable message id. */
|
|
109
|
+
publish(message: StoreMessage<TData, TKey>): StoreMessageRecord<TData, TKey>;
|
|
110
|
+
/** Reads a single persisted message record by id. */
|
|
111
|
+
getMessage(id: number): StoreMessageRecord<TData, TKey> | undefined;
|
|
112
|
+
/** Reads every persisted message record from the channel. */
|
|
113
|
+
getMessages(): readonly StoreMessageRecord<TData, TKey>[];
|
|
114
|
+
/** Persists a new state for an existing message record. */
|
|
115
|
+
saveMessage(entry: StoreMessageRecord<TData, TKey>): void;
|
|
116
|
+
}
|
|
117
|
+
/** Optional store configuration used to override the default in-memory message channel. */
|
|
118
|
+
interface StoreMessageChannelOptions<TData extends StoreDataShape<TData>, TKey extends StoreKey<TData> = StoreKey<TData>> {
|
|
119
|
+
readonly channel?: StoreMessageChannel<TData, TKey>;
|
|
120
|
+
}
|
|
121
|
+
/** Options for {@link createCompositeStoreMessageChannel}. The first channel is the primary (reads + id allocation); replicas receive all writes. */
|
|
122
|
+
interface CompositeStoreMessageChannelOptions<TData extends StoreDataShape<TData>, TKey extends StoreKey<TData> = StoreKey<TData>> {
|
|
123
|
+
readonly channels: readonly StoreMessageChannel<TData, TKey>[];
|
|
124
|
+
}
|
|
125
|
+
/** Options for {@link createStorageStoreMessageChannel}. Provide a custom storage adapter, key, and optional serialize/deserialize hooks. */
|
|
126
|
+
interface StorageStoreMessageChannelOptions<TData extends StoreDataShape<TData>, TKey extends StoreKey<TData> = StoreKey<TData>> {
|
|
127
|
+
readonly storage: StoreMessageChannelStorage;
|
|
128
|
+
readonly storageKey: string;
|
|
129
|
+
readonly serialize?: (state: PersistedStoreMessageChannelState<TData, TKey>) => string;
|
|
130
|
+
readonly deserialize?: (value: string) => PersistedStoreMessageChannelState<TData, TKey>;
|
|
131
|
+
}
|
|
132
|
+
/** Options for {@link createLocalStorageStoreMessageChannel} and {@link createSessionStorageStoreMessageChannel}. Storage defaults to the browser global. */
|
|
133
|
+
interface BrowserStorageStoreMessageChannelOptions<TData extends StoreDataShape<TData>, TKey extends StoreKey<TData> = StoreKey<TData>> extends Omit<StorageStoreMessageChannelOptions<TData, TKey>, "storage"> {
|
|
134
|
+
readonly storage?: StoreMessageChannelStorage;
|
|
135
|
+
}
|
|
136
|
+
interface PersistedStoreMessageChannelState<TData extends StoreDataShape<TData>, TKey extends StoreKey<TData> = StoreKey<TData>> {
|
|
137
|
+
readonly nextId: number;
|
|
138
|
+
readonly messages: readonly StoreMessageRecord<TData, TKey>[];
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Creates an in-memory message channel. Messages are stored in a JavaScript array
|
|
142
|
+
* and lost on page refresh. This is the default channel when no `channel` option is provided.
|
|
143
|
+
*/
|
|
144
|
+
declare function createInMemoryStoreMessageChannel<TData extends StoreDataShape<TData>, TKey extends StoreKey<TData> = StoreKey<TData>>(): StoreMessageChannel<TData, TKey>;
|
|
145
|
+
/**
|
|
146
|
+
* Creates a message channel backed by a custom storage adapter.
|
|
147
|
+
* Messages are serialized and persisted via the provided `storage` object.
|
|
148
|
+
* When the storage quota is exceeded, the oldest messages are evicted automatically.
|
|
149
|
+
*
|
|
150
|
+
* @param options - Storage adapter, key, and optional serialize/deserialize hooks.
|
|
151
|
+
*/
|
|
152
|
+
declare function createStorageStoreMessageChannel<TData extends StoreDataShape<TData>, TKey extends StoreKey<TData> = StoreKey<TData>>(options: StorageStoreMessageChannelOptions<TData, TKey>): StoreMessageChannel<TData, TKey>;
|
|
153
|
+
/**
|
|
154
|
+
* Creates a message channel backed by `localStorage`.
|
|
155
|
+
* Messages survive page refreshes and browser restarts (same-origin only).
|
|
156
|
+
*
|
|
157
|
+
* @param options - Storage key and optional serialize/deserialize hooks.
|
|
158
|
+
*/
|
|
159
|
+
declare function createLocalStorageStoreMessageChannel<TData extends StoreDataShape<TData>, TKey extends StoreKey<TData> = StoreKey<TData>>(options: BrowserStorageStoreMessageChannelOptions<TData, TKey>): StoreMessageChannel<TData, TKey>;
|
|
160
|
+
/**
|
|
161
|
+
* Creates a message channel backed by `sessionStorage`.
|
|
162
|
+
* Messages survive page refreshes but are lost when the browser tab closes.
|
|
163
|
+
*
|
|
164
|
+
* @param options - Storage key and optional serialize/deserialize hooks.
|
|
165
|
+
*/
|
|
166
|
+
declare function createSessionStorageStoreMessageChannel<TData extends StoreDataShape<TData>, TKey extends StoreKey<TData> = StoreKey<TData>>(options: BrowserStorageStoreMessageChannelOptions<TData, TKey>): StoreMessageChannel<TData, TKey>;
|
|
167
|
+
/**
|
|
168
|
+
* Creates a composite message channel that fans out writes to multiple channels.
|
|
169
|
+
* The first channel is the primary (handles reads and id allocation); all channels receive writes.
|
|
170
|
+
*
|
|
171
|
+
* @param options - Array of channels. Must contain at least one.
|
|
172
|
+
*/
|
|
173
|
+
declare function createCompositeStoreMessageChannel<TData extends StoreDataShape<TData>, TKey extends StoreKey<TData> = StoreKey<TData>>(options: CompositeStoreMessageChannelOptions<TData, TKey>): StoreMessageChannel<TData, TKey>;
|
|
3
174
|
|
|
4
175
|
/**
|
|
5
176
|
* Constraint type ensuring every key in a store data map holds a {@link ResourceState}.
|
|
@@ -11,6 +182,16 @@ type StoreDataShape<TData> = {
|
|
|
11
182
|
* Extracts the string-typed keys from a store data map.
|
|
12
183
|
*/
|
|
13
184
|
type StoreKey<TData> = keyof TData & string;
|
|
185
|
+
/** Extracts the value stored inside a store slot's `ResourceState<T>`. */
|
|
186
|
+
type StoreResourceValue<TData extends StoreDataShape<TData>, K extends StoreKey<TData>> = TData[K] extends ResourceState<infer TValue> ? TValue : never;
|
|
187
|
+
/** Narrows store keys whose `data` payload is a keyed resource map. */
|
|
188
|
+
type KeyedStoreKey<TData extends StoreDataShape<TData>, TKey extends StoreKey<TData> = StoreKey<TData>> = {
|
|
189
|
+
[K in TKey]: StoreResourceValue<TData, K> extends KeyedResourceData<infer _TResourceKey, infer _TValue> ? K : never;
|
|
190
|
+
}[TKey];
|
|
191
|
+
/** Extracts the resource key type for a keyed store slot. */
|
|
192
|
+
type KeyedResourceEntryKey<TData extends StoreDataShape<TData>, K extends KeyedStoreKey<TData>> = StoreResourceValue<TData, K> extends KeyedResourceData<infer TResourceKey, unknown> ? TResourceKey : never;
|
|
193
|
+
/** Extracts the entity value type for a keyed store slot. */
|
|
194
|
+
type KeyedResourceEntryValue<TData extends StoreDataShape<TData>, K extends KeyedStoreKey<TData>> = StoreResourceValue<TData, K> extends KeyedResourceData<KeyedResourceKey, infer TValue> ? TValue : never;
|
|
14
195
|
/**
|
|
15
196
|
* Phantom-typed marker for a store resource slot.
|
|
16
197
|
* Carries type information at compile time with zero runtime cost.
|
|
@@ -44,6 +225,15 @@ type InferData<TConfig extends StoreConfig> = {
|
|
|
44
225
|
type ConfigToData<TConfig extends object> = {
|
|
45
226
|
[K in keyof TConfig & string]: ResourceState<TConfig[K]>;
|
|
46
227
|
};
|
|
228
|
+
/**
|
|
229
|
+
* Optional runtime configuration for a store instance.
|
|
230
|
+
*
|
|
231
|
+
* The default channel is in-memory. Supply `channel` to persist broker messages
|
|
232
|
+
* elsewhere, such as local storage, session storage, a composite channel, or a
|
|
233
|
+
* custom provider.
|
|
234
|
+
*/
|
|
235
|
+
interface StoreOptions<TData extends StoreDataShape<TData>, TKey extends StoreKey<TData> = StoreKey<TData>> extends StoreMessageChannelOptions<TData, TKey> {
|
|
236
|
+
}
|
|
47
237
|
/**
|
|
48
238
|
* Shared store interface implemented by both BaseStore and LazyStore.
|
|
49
239
|
*
|
|
@@ -63,6 +253,48 @@ interface IStore<TData extends StoreDataShape<TData>> {
|
|
|
63
253
|
startLoading<K extends StoreKey<TData>>(key: K): void;
|
|
64
254
|
/** Marks a slot as no longer loading: sets `isLoading: false`. */
|
|
65
255
|
stopLoading<K extends StoreKey<TData>>(key: K): void;
|
|
256
|
+
/**
|
|
257
|
+
* Re-executes previously published channel message id(s).
|
|
258
|
+
*
|
|
259
|
+
* Unlike `travelTo(...)`, replay goes back through the broker/consumer path,
|
|
260
|
+
* so it can mutate the store again, truncate future history after time
|
|
261
|
+
* travel, and record new acknowledged history entries.
|
|
262
|
+
*/
|
|
263
|
+
replay: StoreHistory<TData>["replay"];
|
|
264
|
+
/**
|
|
265
|
+
* Restores the store to a previously recorded history index.
|
|
266
|
+
*
|
|
267
|
+
* This navigates snapshots only and does not re-run any message.
|
|
268
|
+
*/
|
|
269
|
+
travelTo: StoreHistory<TData>["travelTo"];
|
|
270
|
+
/** Moves one step backward in the recorded snapshot history when possible. */
|
|
271
|
+
undo: StoreHistory<TData>["undo"];
|
|
272
|
+
/** Moves one step forward in the recorded snapshot history when possible. */
|
|
273
|
+
redo: StoreHistory<TData>["redo"];
|
|
274
|
+
/**
|
|
275
|
+
* Returns a defensive copy of the recorded history.
|
|
276
|
+
*
|
|
277
|
+
* The first entry is always the initial snapshot captured when the store was created.
|
|
278
|
+
*/
|
|
279
|
+
getHistory: StoreHistory<TData>["getHistory"];
|
|
280
|
+
/**
|
|
281
|
+
* Returns persisted broker message records from the configured channel.
|
|
282
|
+
*
|
|
283
|
+
* Use `getMessages(key)` to inspect only the messages that affected one store key.
|
|
284
|
+
*/
|
|
285
|
+
getMessages: StoreHistory<TData>["getMessages"];
|
|
286
|
+
/**
|
|
287
|
+
* Returns messages that failed broker acknowledgement.
|
|
288
|
+
*
|
|
289
|
+
* These entries can be inspected for diagnostics and retried later.
|
|
290
|
+
*/
|
|
291
|
+
getDeadLetters: StoreHistory<TData>["getDeadLetters"];
|
|
292
|
+
/** Replays a single dead-letter message by dead-letter id. */
|
|
293
|
+
replayDeadLetter: StoreHistory<TData>["replayDeadLetter"];
|
|
294
|
+
/** Attempts to replay all current dead-letter messages once. */
|
|
295
|
+
replayDeadLetters: StoreHistory<TData>["replayDeadLetters"];
|
|
296
|
+
/** Returns the currently restored snapshot index used by `travelTo`, `undo`, and `redo`. */
|
|
297
|
+
getCurrentIndex: StoreHistory<TData>["getCurrentIndex"];
|
|
66
298
|
/** Merges a single entity into a keyed slot and sets its status to `'Success'`. */
|
|
67
299
|
updateKeyedOne<K extends StoreKey<TData>>(key: K, resourceKey: KeyedResourceKey, entity: unknown): void;
|
|
68
300
|
/** Removes a single entity (and its loading/status/errors) from a keyed slot. */
|
|
@@ -74,6 +306,163 @@ interface IStore<TData extends StoreDataShape<TData>> {
|
|
|
74
306
|
* @returns A cleanup function that removes the listener.
|
|
75
307
|
*/
|
|
76
308
|
onUpdate<K extends StoreKey<TData>>(key: K, callback: (state: TData[K], previousState: TData[K]) => void): () => void;
|
|
309
|
+
/** Reactive signal containing the full history entries. */
|
|
310
|
+
readonly history: Signal<readonly StoreHistoryEntry<TData>[]>;
|
|
311
|
+
/** Reactive signal containing all channel message records. */
|
|
312
|
+
readonly messages: Signal<readonly StoreMessageRecord<TData>[]>;
|
|
313
|
+
/** Reactive signal containing the current history index. */
|
|
314
|
+
readonly currentIndex: Signal<number>;
|
|
315
|
+
/** Reactive signal containing all registered store keys. */
|
|
316
|
+
readonly keys: Signal<readonly StoreKey<TData>[]>;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
/**
|
|
320
|
+
* Creates a deep clone of the given value.
|
|
321
|
+
*
|
|
322
|
+
* **Warning:** Class instances with constructor logic, private fields, or
|
|
323
|
+
* non-enumerable state will not clone correctly. The clone preserves the
|
|
324
|
+
* prototype chain via `Object.create(Object.getPrototypeOf(...))` but does
|
|
325
|
+
* **not** invoke the constructor, so any side-effects or hidden state set
|
|
326
|
+
* during construction will be missing from the clone.
|
|
327
|
+
*/
|
|
328
|
+
declare function cloneValue<T>(value: T): T;
|
|
329
|
+
/**
|
|
330
|
+
* Creates a minimal patch object that, when spread onto `currentState`, produces `snapshotState`.
|
|
331
|
+
* Properties present in the snapshot are cloned; properties absent from the snapshot are set to `undefined`.
|
|
332
|
+
*
|
|
333
|
+
* @param currentState - The current slot state.
|
|
334
|
+
* @param snapshotState - The target snapshot state to restore.
|
|
335
|
+
* @returns A partial state object suitable for `Signal.update()`.
|
|
336
|
+
*/
|
|
337
|
+
declare function createSnapshotRestorePatch<TState extends ResourceState<unknown>>(currentState: TState, snapshotState: TState): Partial<TState>;
|
|
338
|
+
|
|
339
|
+
/**
|
|
340
|
+
* Single acknowledged point in store history.
|
|
341
|
+
*
|
|
342
|
+
* Entry `0` is always the initial snapshot captured when the history driver is
|
|
343
|
+
* created, so its `id`, `message`, and `acknowledgedAt` are `null`.
|
|
344
|
+
*/
|
|
345
|
+
interface StoreHistoryEntry<TData extends StoreDataShape<TData>, TKey extends StoreKey<TData> = StoreKey<TData>> {
|
|
346
|
+
/** Stable message id used by `replay(...)`; `null` for the initial snapshot entry. */
|
|
347
|
+
readonly id: number | null;
|
|
348
|
+
/** Snapshot position used by `travelTo(index)`, `undo()`, and `redo()`. */
|
|
349
|
+
readonly index: number;
|
|
350
|
+
/** Acknowledged message that produced this snapshot; `null` for the initial entry. */
|
|
351
|
+
readonly message: StoreMessage<TData, TKey> | null;
|
|
352
|
+
/** Full store snapshot captured immediately after the message was acknowledged. */
|
|
353
|
+
readonly snapshot: StoreSnapshot<TData, TKey>;
|
|
354
|
+
/** Acknowledgement timestamp for the message; `null` for the initial snapshot entry. */
|
|
355
|
+
readonly acknowledgedAt: number | null;
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* Failed message tracked by the internal broker when the store consumer does not
|
|
359
|
+
* acknowledge a published message.
|
|
360
|
+
*/
|
|
361
|
+
interface StoreDeadLetterEntry<TData extends StoreDataShape<TData>, TKey extends StoreKey<TData> = StoreKey<TData>> {
|
|
362
|
+
/** Stable dead-letter id used by `replayDeadLetter(id)`. */
|
|
363
|
+
readonly id: number;
|
|
364
|
+
/** Original message that failed acknowledgement. */
|
|
365
|
+
readonly message: StoreMessage<TData, TKey>;
|
|
366
|
+
/** Number of failed acknowledgement attempts for this dead letter. */
|
|
367
|
+
readonly attempts: number;
|
|
368
|
+
/** Last acknowledgement error captured for this dead letter. */
|
|
369
|
+
readonly error: string;
|
|
370
|
+
/** Timestamp of the most recent failure. */
|
|
371
|
+
readonly failedAt: number;
|
|
372
|
+
}
|
|
373
|
+
/**
|
|
374
|
+
* Public history and recovery API exposed on every store instance.
|
|
375
|
+
*
|
|
376
|
+
* `travelTo(...)` navigates snapshots by history index, while `replay(...)`
|
|
377
|
+
* re-executes previously published channel messages by their stable message ids.
|
|
378
|
+
*/
|
|
379
|
+
interface StoreHistory<TData extends StoreDataShape<TData>, TKey extends StoreKey<TData> = StoreKey<TData>> {
|
|
380
|
+
/**
|
|
381
|
+
* Re-executes one previously published message by id.
|
|
382
|
+
*
|
|
383
|
+
* The message does not need to have been acknowledged before. Replay resolves it
|
|
384
|
+
* from the configured message channel, sends it back through the broker/consumer
|
|
385
|
+
* flow, and may create a fresh acknowledged history entry if the replay succeeds.
|
|
386
|
+
*
|
|
387
|
+
* @throws {Error} When the id does not point to a persisted channel message.
|
|
388
|
+
* @returns Number of successfully acknowledged replayed messages.
|
|
389
|
+
*/
|
|
390
|
+
replay(id: number): number;
|
|
391
|
+
/**
|
|
392
|
+
* Re-executes multiple previously published messages in the provided order.
|
|
393
|
+
*
|
|
394
|
+
* Every id must resolve to a persisted channel message. Replay stops with an error
|
|
395
|
+
* if any supplied id is invalid.
|
|
396
|
+
*
|
|
397
|
+
* @throws {Error} When any id does not point to a persisted channel message.
|
|
398
|
+
* @returns Number of successfully acknowledged replayed messages.
|
|
399
|
+
*/
|
|
400
|
+
replay(ids: readonly number[]): number;
|
|
401
|
+
/**
|
|
402
|
+
* Restores the store to the snapshot recorded at a specific history index.
|
|
403
|
+
*
|
|
404
|
+
* This is snapshot navigation only. It does not publish or acknowledge any
|
|
405
|
+
* message and does not create a new history entry.
|
|
406
|
+
*
|
|
407
|
+
* @throws {Error} When the index is outside the recorded history range.
|
|
408
|
+
*/
|
|
409
|
+
travelTo(index: number): void;
|
|
410
|
+
/**
|
|
411
|
+
* Moves to the previous recorded snapshot.
|
|
412
|
+
*
|
|
413
|
+
* Equivalent to `travelTo(getCurrentIndex() - 1)` when possible.
|
|
414
|
+
*
|
|
415
|
+
* @returns `true` when the pointer moved, otherwise `false` at the initial snapshot.
|
|
416
|
+
*/
|
|
417
|
+
undo(): boolean;
|
|
418
|
+
/**
|
|
419
|
+
* Moves to the next recorded snapshot when history exists ahead of the current pointer.
|
|
420
|
+
*
|
|
421
|
+
* Equivalent to `travelTo(getCurrentIndex() + 1)` when possible.
|
|
422
|
+
*
|
|
423
|
+
* @returns `true` when the pointer moved, otherwise `false` at the latest snapshot.
|
|
424
|
+
*/
|
|
425
|
+
redo(): boolean;
|
|
426
|
+
/** Returns a defensive copy of every recorded history entry, including the initial snapshot entry. */
|
|
427
|
+
getHistory(): readonly StoreHistoryEntry<TData, TKey>[];
|
|
428
|
+
/**
|
|
429
|
+
* Returns the history entries that affected a specific store key.
|
|
430
|
+
*
|
|
431
|
+
* The initial snapshot entry is always included as the first item. Messages such
|
|
432
|
+
* as `clearAll` that affect every key are included in every filtered view.
|
|
433
|
+
*/
|
|
434
|
+
getHistory<K extends TKey>(key: K): readonly StoreHistoryEntry<TData, K>[];
|
|
435
|
+
/** Returns a defensive copy of the current dead-letter collection. */
|
|
436
|
+
getDeadLetters(): readonly StoreDeadLetterEntry<TData, TKey>[];
|
|
437
|
+
/** Returns every message currently stored in the configured channel. */
|
|
438
|
+
getMessages(): readonly StoreMessageRecord<TData, TKey>[];
|
|
439
|
+
/** Returns channel messages that affected a specific store key. */
|
|
440
|
+
getMessages<K extends TKey>(key: K): readonly StoreMessageRecord<TData, K>[];
|
|
441
|
+
/**
|
|
442
|
+
* Republishes a single dead-letter message by dead-letter id.
|
|
443
|
+
*
|
|
444
|
+
* On success the dead letter is removed and a new acknowledged history entry is recorded.
|
|
445
|
+
*
|
|
446
|
+
* @returns `true` when the dead letter was acknowledged on replay, otherwise `false`.
|
|
447
|
+
*/
|
|
448
|
+
replayDeadLetter(id: number): boolean;
|
|
449
|
+
/**
|
|
450
|
+
* Attempts to republish every current dead letter once.
|
|
451
|
+
*
|
|
452
|
+
* Successfully acknowledged dead letters are removed. Failures remain in the
|
|
453
|
+
* dead-letter collection with incremented attempt counts.
|
|
454
|
+
*
|
|
455
|
+
* @returns Number of dead letters successfully acknowledged during the replay attempt.
|
|
456
|
+
*/
|
|
457
|
+
replayDeadLetters(): number;
|
|
458
|
+
/** Returns the currently restored history index used by snapshot navigation. */
|
|
459
|
+
getCurrentIndex(): number;
|
|
460
|
+
/** Reactive signal containing the full history entries. */
|
|
461
|
+
readonly historySignal: Signal<readonly StoreHistoryEntry<TData, TKey>[]>;
|
|
462
|
+
/** Reactive signal containing all channel message records. */
|
|
463
|
+
readonly messagesSignal: Signal<readonly StoreMessageRecord<TData, TKey>[]>;
|
|
464
|
+
/** Reactive signal containing the current history index. */
|
|
465
|
+
readonly currentIndexSignal: Signal<number>;
|
|
77
466
|
}
|
|
78
467
|
|
|
79
468
|
/**
|
|
@@ -88,19 +477,55 @@ interface IStore<TData extends StoreDataShape<TData>> {
|
|
|
88
477
|
* @template TEnum - Record mapping slot names to their string/number keys.
|
|
89
478
|
* @template TData - Record mapping slot names to `ResourceState<T>` types.
|
|
90
479
|
*/
|
|
91
|
-
declare abstract class BaseStore<TEnum extends Record<string, string | number>, TData extends {
|
|
480
|
+
declare abstract class BaseStore<TEnum extends Record<string, string | number>, TData extends StoreDataShape<TData> & {
|
|
92
481
|
[K in keyof TEnum]: ResourceState<unknown>;
|
|
93
482
|
}> implements IStore<TData> {
|
|
94
483
|
protected readonly storeEnum: TEnum;
|
|
95
484
|
private readonly signalsState;
|
|
96
|
-
|
|
485
|
+
private readonly storeKeys;
|
|
486
|
+
private readonly historyDriver;
|
|
487
|
+
/** @inheritDoc */
|
|
488
|
+
readonly travelTo: (index: number) => void;
|
|
489
|
+
/** @inheritDoc */
|
|
490
|
+
readonly undo: () => boolean;
|
|
491
|
+
/** @inheritDoc */
|
|
492
|
+
readonly redo: () => boolean;
|
|
493
|
+
/** @inheritDoc */
|
|
494
|
+
readonly getDeadLetters: () => readonly StoreDeadLetterEntry<TData, StoreKey<TData>>[];
|
|
495
|
+
/** @inheritDoc */
|
|
496
|
+
readonly replayDeadLetter: (id: number) => boolean;
|
|
497
|
+
/** @inheritDoc */
|
|
498
|
+
readonly replayDeadLetters: () => number;
|
|
499
|
+
/** @inheritDoc */
|
|
500
|
+
readonly getCurrentIndex: () => number;
|
|
501
|
+
/** @inheritDoc */
|
|
502
|
+
readonly history: Signal<readonly StoreHistoryEntry<TData>[]>;
|
|
503
|
+
/** @inheritDoc */
|
|
504
|
+
readonly messages: Signal<readonly StoreMessageRecord<TData>[]>;
|
|
505
|
+
/** @inheritDoc */
|
|
506
|
+
readonly currentIndex: Signal<number>;
|
|
507
|
+
/** @inheritDoc */
|
|
508
|
+
readonly keys: Signal<readonly StoreKey<TData>[]>;
|
|
509
|
+
/** @inheritDoc */
|
|
510
|
+
replay(id: number): number;
|
|
511
|
+
/** @inheritDoc */
|
|
512
|
+
replay(ids: readonly number[]): number;
|
|
513
|
+
/** @inheritDoc */
|
|
514
|
+
getHistory(): readonly StoreHistoryEntry<TData>[];
|
|
515
|
+
/** @inheritDoc */
|
|
516
|
+
getHistory<K extends StoreKey<TData>>(key: K): readonly StoreHistoryEntry<TData, K>[];
|
|
517
|
+
/** @inheritDoc */
|
|
518
|
+
getMessages(): readonly StoreMessageRecord<TData>[];
|
|
519
|
+
/** @inheritDoc */
|
|
520
|
+
getMessages<K extends StoreKey<TData>>(key: K): readonly StoreMessageRecord<TData, K>[];
|
|
521
|
+
protected constructor(storeEnum: TEnum, options?: StoreOptions<TData>);
|
|
97
522
|
/**
|
|
98
523
|
* Returns a **read-only** `Signal` for the given store slot.
|
|
99
524
|
*
|
|
100
525
|
* @param key - The slot name to read.
|
|
101
526
|
* @returns A `Signal` wrapping the slot's current {@link ResourceState}.
|
|
102
527
|
*/
|
|
103
|
-
get<K extends
|
|
528
|
+
get<K extends StoreKey<TData>>(key: K): Signal<TData[K]>;
|
|
104
529
|
/**
|
|
105
530
|
* Registers a callback fired after every `update` or `clear` on the given slot.
|
|
106
531
|
*
|
|
@@ -108,14 +533,14 @@ declare abstract class BaseStore<TEnum extends Record<string, string | number>,
|
|
|
108
533
|
* @param callback - Receives the new state and the previous state.
|
|
109
534
|
* @returns A cleanup function that removes the listener when called.
|
|
110
535
|
*/
|
|
111
|
-
onUpdate<K extends
|
|
536
|
+
onUpdate<K extends StoreKey<TData>>(key: K, callback: (state: TData[K], previousState: TData[K]) => void): () => void;
|
|
112
537
|
/**
|
|
113
538
|
* Partially updates a slot by merging `newState` into the current value (immutable spread).
|
|
114
539
|
*
|
|
115
540
|
* @param key - The slot to update.
|
|
116
541
|
* @param newState - Partial state to merge (e.g. `{ data: newData, status: 'Success' }`).
|
|
117
542
|
*/
|
|
118
|
-
update<K extends
|
|
543
|
+
update<K extends StoreKey<TData>>(key: K, newState: Partial<TData[K]>): void;
|
|
119
544
|
/** Resets every slot in this store to its initial idle state. */
|
|
120
545
|
clearAll(): void;
|
|
121
546
|
/**
|
|
@@ -123,20 +548,20 @@ declare abstract class BaseStore<TEnum extends Record<string, string | number>,
|
|
|
123
548
|
*
|
|
124
549
|
* @param key - The slot to clear.
|
|
125
550
|
*/
|
|
126
|
-
clear<K extends
|
|
551
|
+
clear<K extends StoreKey<TData>>(key: K): void;
|
|
127
552
|
/**
|
|
128
553
|
* Marks a slot as loading: sets `isLoading: true` and clears `status` and `errors`.
|
|
129
554
|
*
|
|
130
555
|
* @param key - The slot to mark as loading.
|
|
131
556
|
*/
|
|
132
|
-
startLoading<K extends
|
|
557
|
+
startLoading<K extends StoreKey<TData>>(key: K): void;
|
|
133
558
|
/**
|
|
134
559
|
* Marks a slot as no longer loading: sets `isLoading: false`.
|
|
135
560
|
* Does **not** clear `status` or `errors`.
|
|
136
561
|
*
|
|
137
562
|
* @param key - The slot to stop loading.
|
|
138
563
|
*/
|
|
139
|
-
stopLoading<K extends
|
|
564
|
+
stopLoading<K extends StoreKey<TData>>(key: K): void;
|
|
140
565
|
/**
|
|
141
566
|
* Merges a single entity into a {@link KeyedResourceData} slot.
|
|
142
567
|
* Sets its status to `'Success'` and clears per-key errors.
|
|
@@ -146,7 +571,7 @@ declare abstract class BaseStore<TEnum extends Record<string, string | number>,
|
|
|
146
571
|
* @param resourceKey - The entity identifier (e.g. `'inv-123'`).
|
|
147
572
|
* @param entity - The entity value to store.
|
|
148
573
|
*/
|
|
149
|
-
updateKeyedOne<K extends
|
|
574
|
+
updateKeyedOne<K extends StoreKey<TData>>(key: K, resourceKey: KeyedResourceKey, entity: unknown): void;
|
|
150
575
|
/**
|
|
151
576
|
* Removes a single entity from a {@link KeyedResourceData} slot,
|
|
152
577
|
* including its loading flag, status, and errors.
|
|
@@ -155,7 +580,7 @@ declare abstract class BaseStore<TEnum extends Record<string, string | number>,
|
|
|
155
580
|
* @param key - The keyed slot name.
|
|
156
581
|
* @param resourceKey - The entity identifier to remove.
|
|
157
582
|
*/
|
|
158
|
-
clearKeyedOne<K extends
|
|
583
|
+
clearKeyedOne<K extends StoreKey<TData>>(key: K, resourceKey: KeyedResourceKey): void;
|
|
159
584
|
/**
|
|
160
585
|
* Marks a single entity within a keyed slot as loading.
|
|
161
586
|
* Clears its status and errors. If the slot data is not yet a {@link KeyedResourceData},
|
|
@@ -164,7 +589,7 @@ declare abstract class BaseStore<TEnum extends Record<string, string | number>,
|
|
|
164
589
|
* @param key - The keyed slot name.
|
|
165
590
|
* @param resourceKey - The entity identifier to mark as loading.
|
|
166
591
|
*/
|
|
167
|
-
startKeyedLoading<K extends
|
|
592
|
+
startKeyedLoading<K extends StoreKey<TData>>(key: K, resourceKey: KeyedResourceKey): void;
|
|
168
593
|
private notifyUpdateHooks;
|
|
169
594
|
private initializeState;
|
|
170
595
|
}
|
|
@@ -177,17 +602,62 @@ declare abstract class BaseStore<TEnum extends Record<string, string | number>,
|
|
|
177
602
|
declare class LazyStore<TData extends StoreDataShape<TData>> implements IStore<TData> {
|
|
178
603
|
private readonly signals;
|
|
179
604
|
private readonly hooks;
|
|
180
|
-
|
|
605
|
+
private readonly historyDriver;
|
|
606
|
+
/** @inheritDoc */
|
|
607
|
+
readonly travelTo: (index: number) => void;
|
|
608
|
+
/** @inheritDoc */
|
|
609
|
+
readonly undo: () => boolean;
|
|
610
|
+
/** @inheritDoc */
|
|
611
|
+
readonly redo: () => boolean;
|
|
612
|
+
/** @inheritDoc */
|
|
613
|
+
getMessages(): readonly StoreMessageRecord<TData>[];
|
|
614
|
+
/** @inheritDoc */
|
|
615
|
+
getMessages<K extends StoreKey<TData>>(key: K): readonly StoreMessageRecord<TData, K>[];
|
|
616
|
+
readonly getDeadLetters: () => readonly StoreDeadLetterEntry<TData, StoreKey<TData>>[];
|
|
617
|
+
/** @inheritDoc */
|
|
618
|
+
readonly replayDeadLetter: (id: number) => boolean;
|
|
619
|
+
/** @inheritDoc */
|
|
620
|
+
readonly replayDeadLetters: () => number;
|
|
621
|
+
/** @inheritDoc */
|
|
622
|
+
readonly getCurrentIndex: () => number;
|
|
623
|
+
/** @inheritDoc */
|
|
624
|
+
readonly history: Signal<readonly StoreHistoryEntry<TData>[]>;
|
|
625
|
+
/** @inheritDoc */
|
|
626
|
+
readonly messages: Signal<readonly StoreMessageRecord<TData>[]>;
|
|
627
|
+
/** @inheritDoc */
|
|
628
|
+
readonly currentIndex: Signal<number>;
|
|
629
|
+
/** @inheritDoc */
|
|
630
|
+
readonly keys: Signal<readonly StoreKey<TData>[]>;
|
|
631
|
+
private readonly keysSignal;
|
|
632
|
+
/** @inheritDoc */
|
|
633
|
+
replay(id: number): number;
|
|
634
|
+
/** @inheritDoc */
|
|
635
|
+
replay(ids: readonly number[]): number;
|
|
636
|
+
/** @inheritDoc */
|
|
637
|
+
getHistory(): readonly StoreHistoryEntry<TData>[];
|
|
638
|
+
/** @inheritDoc */
|
|
639
|
+
getHistory<K extends StoreKey<TData>>(key: K): readonly StoreHistoryEntry<TData, K>[];
|
|
640
|
+
constructor(options?: StoreOptions<TData>);
|
|
181
641
|
private getOrCreate;
|
|
642
|
+
/** @inheritDoc */
|
|
182
643
|
get<K extends StoreKey<TData>>(key: K): Signal<TData[K]>;
|
|
644
|
+
/** @inheritDoc */
|
|
183
645
|
update<K extends StoreKey<TData>>(key: K, newState: Partial<TData[K]>): void;
|
|
646
|
+
/** @inheritDoc */
|
|
184
647
|
clear<K extends StoreKey<TData>>(key: K): void;
|
|
648
|
+
/** @inheritDoc */
|
|
185
649
|
clearAll(): void;
|
|
650
|
+
/** @inheritDoc */
|
|
186
651
|
startLoading<K extends StoreKey<TData>>(key: K): void;
|
|
652
|
+
/** @inheritDoc */
|
|
187
653
|
stopLoading<K extends StoreKey<TData>>(key: K): void;
|
|
654
|
+
/** @inheritDoc */
|
|
188
655
|
updateKeyedOne<K extends StoreKey<TData>>(key: K, resourceKey: KeyedResourceKey, entity: unknown): void;
|
|
656
|
+
/** @inheritDoc */
|
|
189
657
|
clearKeyedOne<K extends StoreKey<TData>>(key: K, resourceKey: KeyedResourceKey): void;
|
|
658
|
+
/** @inheritDoc */
|
|
190
659
|
startKeyedLoading<K extends StoreKey<TData>>(key: K, resourceKey: KeyedResourceKey): void;
|
|
660
|
+
/** @inheritDoc */
|
|
191
661
|
onUpdate<K extends StoreKey<TData>>(key: K, callback: (state: TData[K], previousState: TData[K]) => void): () => void;
|
|
192
662
|
private notifyHooks;
|
|
193
663
|
}
|
|
@@ -196,6 +666,19 @@ declare class LazyStore<TData extends StoreDataShape<TData>> implements IStore<T
|
|
|
196
666
|
* Intermediate builder step after .resource('key') — awaits .as<T>().
|
|
197
667
|
*/
|
|
198
668
|
interface AsStep<TAccum extends StoreConfig, TKey extends string> {
|
|
669
|
+
/**
|
|
670
|
+
* Assign the resource value type for the previously declared key.
|
|
671
|
+
*
|
|
672
|
+
* Returns the main fluent builder so you can define more resources, configure
|
|
673
|
+
* mirrors, or call `.build()`.
|
|
674
|
+
*
|
|
675
|
+
* @example
|
|
676
|
+
* ```ts
|
|
677
|
+
* const CustomersStore = Store
|
|
678
|
+
* .resource('CUSTOMERS').as<Customer[]>()
|
|
679
|
+
* .build();
|
|
680
|
+
* ```
|
|
681
|
+
*/
|
|
199
682
|
as<T>(): StoreBuilder<TAccum & Record<TKey, ResourceDef<T>>>;
|
|
200
683
|
}
|
|
201
684
|
/**
|
|
@@ -236,12 +719,17 @@ interface StoreBuilder<TAccum extends StoreConfig> {
|
|
|
236
719
|
* Finalize the builder and create an `InjectionToken` (`providedIn: 'root'`).
|
|
237
720
|
* All mirrors are wired up automatically when Angular creates the store.
|
|
238
721
|
*/
|
|
239
|
-
build(): InjectionToken<BaseStore<InferEnum<TAccum>, InferData<TAccum>>>;
|
|
722
|
+
build(options?: StoreOptions<InferData<TAccum>>): InjectionToken<BaseStore<InferEnum<TAccum>, InferData<TAccum>>>;
|
|
240
723
|
}
|
|
241
724
|
/** Keys from the enum that have NOT yet been defined. */
|
|
242
725
|
type Remaining<TEnum extends Record<string, string>, TAccum extends StoreConfig> = Exclude<keyof TEnum & string, keyof TAccum>;
|
|
243
726
|
/** Intermediate .as<T>() step for the constrained builder. */
|
|
244
727
|
interface ConstrainedAsStep<TEnum extends Record<string, string>, TAccum extends StoreConfig, TKey extends string> {
|
|
728
|
+
/**
|
|
729
|
+
* Assign the resource value type for the selected enum key.
|
|
730
|
+
*
|
|
731
|
+
* Returns the constrained builder for the remaining enum keys.
|
|
732
|
+
*/
|
|
245
733
|
as<T>(): ConstrainedBuilder<TEnum, TAccum & Record<TKey, ResourceDef<T>>>;
|
|
246
734
|
}
|
|
247
735
|
/**
|
|
@@ -249,22 +737,94 @@ interface ConstrainedAsStep<TEnum extends Record<string, string>, TAccum extends
|
|
|
249
737
|
* defined yet. `.build()` is only available when all keys are accounted for.
|
|
250
738
|
*/
|
|
251
739
|
type ConstrainedBuilder<TEnum extends Record<string, string>, TAccum extends StoreConfig> = [Remaining<TEnum, TAccum>] extends [never] ? {
|
|
740
|
+
/**
|
|
741
|
+
* Mirror a slot from another store. When the source updates, the target is kept in sync.
|
|
742
|
+
*
|
|
743
|
+
* @param source - The source store's `InjectionToken`.
|
|
744
|
+
* @param sourceKey - The key to watch on the source store.
|
|
745
|
+
* @param targetKey - The key on this store to write to. Defaults to `sourceKey`.
|
|
746
|
+
*/
|
|
252
747
|
mirror<TSourceData extends StoreDataShape<TSourceData>>(source: InjectionToken<IStore<TSourceData>>, sourceKey: StoreKey<TSourceData>, targetKey?: StoreKey<TAccum>): ConstrainedBuilder<TEnum, TAccum>;
|
|
748
|
+
/**
|
|
749
|
+
* Mirror one slot to another within the same store.
|
|
750
|
+
* Source and target keys must be different.
|
|
751
|
+
*
|
|
752
|
+
* @param sourceKey - The slot to read from.
|
|
753
|
+
* @param targetKey - The slot to write to.
|
|
754
|
+
*/
|
|
253
755
|
mirrorSelf(sourceKey: StoreKey<TAccum>, targetKey: StoreKey<TAccum>): ConstrainedBuilder<TEnum, TAccum>;
|
|
756
|
+
/**
|
|
757
|
+
* Accumulate single-entity fetches from a source store into a keyed slot.
|
|
758
|
+
*
|
|
759
|
+
* @param source - The source store's `InjectionToken`.
|
|
760
|
+
* @param sourceKey - The single-entity key on the source store.
|
|
761
|
+
* @param options - Must include `extractId` to derive the entity's key from its data.
|
|
762
|
+
* @param targetKey - The keyed slot on this store. Defaults to `sourceKey`.
|
|
763
|
+
*/
|
|
254
764
|
mirrorKeyed<TSourceData extends StoreDataShape<TSourceData>, TEntity>(source: InjectionToken<IStore<TSourceData>>, sourceKey: StoreKey<TSourceData>, options: {
|
|
255
765
|
extractId: (data: TEntity | undefined) => KeyedResourceKey | undefined;
|
|
256
766
|
}, targetKey?: StoreKey<TAccum>): ConstrainedBuilder<TEnum, TAccum>;
|
|
257
|
-
|
|
767
|
+
/**
|
|
768
|
+
* Finalize the builder and create an `InjectionToken` (`providedIn: 'root'`).
|
|
769
|
+
* Available only after all enum keys have been defined.
|
|
770
|
+
*/
|
|
771
|
+
build(options?: StoreOptions<InferData<TAccum>>): InjectionToken<BaseStore<InferEnum<TAccum>, InferData<TAccum>>>;
|
|
258
772
|
} : {
|
|
773
|
+
/** Define the next resource slot from the remaining enum keys. */
|
|
259
774
|
resource<TKey extends Remaining<TEnum, TAccum>>(key: TKey): ConstrainedAsStep<TEnum, TAccum, TKey>;
|
|
260
775
|
};
|
|
776
|
+
/**
|
|
777
|
+
* Interface-based builder for `Store.for<Config>()`.
|
|
778
|
+
*
|
|
779
|
+
* Uses a config interface for compile-time shape only, so no runtime enum is required.
|
|
780
|
+
*/
|
|
261
781
|
interface InterfaceBuilder<TConfig extends object> {
|
|
782
|
+
/**
|
|
783
|
+
* Mirror a slot from another store. When the source updates, the target is kept in sync.
|
|
784
|
+
*
|
|
785
|
+
* @param source - The source store's `InjectionToken`.
|
|
786
|
+
* @param sourceKey - The key to watch on the source store.
|
|
787
|
+
* @param targetKey - The key on this store to write to. Defaults to `sourceKey`.
|
|
788
|
+
*/
|
|
262
789
|
mirror<TSourceData extends StoreDataShape<TSourceData>>(source: InjectionToken<IStore<TSourceData>>, sourceKey: StoreKey<TSourceData>, targetKey?: StoreKey<ConfigToData<TConfig>>): InterfaceBuilder<TConfig>;
|
|
790
|
+
/**
|
|
791
|
+
* Mirror one slot to another within the same store.
|
|
792
|
+
* Source and target keys must be different.
|
|
793
|
+
*
|
|
794
|
+
* @param sourceKey - The slot to read from.
|
|
795
|
+
* @param targetKey - The slot to write to.
|
|
796
|
+
*/
|
|
263
797
|
mirrorSelf(sourceKey: StoreKey<ConfigToData<TConfig>>, targetKey: StoreKey<ConfigToData<TConfig>>): InterfaceBuilder<TConfig>;
|
|
798
|
+
/**
|
|
799
|
+
* Accumulate single-entity fetches from a source store into a keyed slot.
|
|
800
|
+
*
|
|
801
|
+
* @param source - The source store's `InjectionToken`.
|
|
802
|
+
* @param sourceKey - The single-entity key on the source store.
|
|
803
|
+
* @param options - Must include `extractId` to derive the entity's key from its data.
|
|
804
|
+
* @param targetKey - The keyed slot on this store. Defaults to `sourceKey`.
|
|
805
|
+
*/
|
|
264
806
|
mirrorKeyed<TSourceData extends StoreDataShape<TSourceData>, TEntity>(source: InjectionToken<IStore<TSourceData>>, sourceKey: StoreKey<TSourceData>, options: {
|
|
265
807
|
extractId: (data: TEntity | undefined) => KeyedResourceKey | undefined;
|
|
266
808
|
}, targetKey?: StoreKey<ConfigToData<TConfig>>): InterfaceBuilder<TConfig>;
|
|
267
|
-
|
|
809
|
+
/**
|
|
810
|
+
* Finalize the interface-based builder and create a store `InjectionToken`.
|
|
811
|
+
*
|
|
812
|
+
* The resulting token is registered with `providedIn: 'root'` and resolves to
|
|
813
|
+
* a `LazyStore` implementing `IStore<ConfigToData<TConfig>>`.
|
|
814
|
+
*
|
|
815
|
+
* @returns An Angular `InjectionToken` for the configured store.
|
|
816
|
+
*
|
|
817
|
+
* @example
|
|
818
|
+
* ```ts
|
|
819
|
+
* interface ChatStoreConfig {
|
|
820
|
+
* SESSIONS: ChatSession[];
|
|
821
|
+
* MESSAGES: ChatMessage[];
|
|
822
|
+
* }
|
|
823
|
+
*
|
|
824
|
+
* export const ChatStore = Store.for<ChatStoreConfig>().build();
|
|
825
|
+
* ```
|
|
826
|
+
*/
|
|
827
|
+
build(options?: StoreOptions<ConfigToData<TConfig>>): InjectionToken<IStore<ConfigToData<TConfig>>>;
|
|
268
828
|
}
|
|
269
829
|
interface StoreEntry {
|
|
270
830
|
/**
|
|
@@ -273,6 +833,16 @@ interface StoreEntry {
|
|
|
273
833
|
* or call .build() when done.
|
|
274
834
|
*/
|
|
275
835
|
resource<TKey extends string>(key: TKey): {
|
|
836
|
+
/**
|
|
837
|
+
* Set the resource value type and continue the fluent builder chain.
|
|
838
|
+
*
|
|
839
|
+
* @example
|
|
840
|
+
* ```ts
|
|
841
|
+
* const UsersStore = Store
|
|
842
|
+
* .resource('USERS').as<User[]>()
|
|
843
|
+
* .build();
|
|
844
|
+
* ```
|
|
845
|
+
*/
|
|
276
846
|
as<T>(): StoreBuilder<Record<TKey, ResourceDef<T>>>;
|
|
277
847
|
};
|
|
278
848
|
/**
|
|
@@ -327,7 +897,7 @@ declare const Store: StoreEntry;
|
|
|
327
897
|
*
|
|
328
898
|
* @example
|
|
329
899
|
* ```ts
|
|
330
|
-
* import { clearAllStores } from 'flurryx';
|
|
900
|
+
* import { clearAllStores } from '@flurryx/store';
|
|
331
901
|
*
|
|
332
902
|
* logout() {
|
|
333
903
|
* clearAllStores();
|
|
@@ -398,4 +968,4 @@ interface CollectKeyedOptions<TEntity> {
|
|
|
398
968
|
*/
|
|
399
969
|
declare function collectKeyed<TSource extends StoreDataShape<TSource>, TTarget extends StoreDataShape<TTarget>, TEntity = unknown>(source: IStore<TSource>, sourceKey: StoreKey<TSource>, target: IStore<TTarget>, targetKeyOrOptions?: StoreKey<TTarget> | CollectKeyedOptions<TEntity>, options?: CollectKeyedOptions<TEntity>): () => void;
|
|
400
970
|
|
|
401
|
-
export { BaseStore, type CollectKeyedOptions, type ConfigToData, type IStore, LazyStore, type MirrorOptions, Store, clearAllStores, collectKeyed, mirrorKey };
|
|
971
|
+
export { BaseStore, type BrowserStorageStoreMessageChannelOptions, type ClearAllStoreMessage, type ClearKeyedOneStoreMessage, type ClearStoreMessage, type CollectKeyedOptions, type CompositeStoreMessageChannelOptions, type ConfigToData, type IStore, LazyStore, type MirrorOptions, type StartKeyedLoadingStoreMessage, type StartLoadingStoreMessage, type StopLoadingStoreMessage, type StorageStoreMessageChannelOptions, Store, type StoreDeadLetterEntry, type StoreHistory, type StoreHistoryEntry, type StoreMessage, type StoreMessageChannel, type StoreMessageChannelOptions, type StoreMessageChannelStorage, type StoreMessageRecord, type StoreMessageStatus, type StoreOptions, type StoreSnapshot, type UpdateKeyedOneStoreMessage, type UpdateStoreMessage, clearAllStores, cloneValue, collectKeyed, createCompositeStoreMessageChannel, createInMemoryStoreMessageChannel, createLocalStorageStoreMessageChannel, createSessionStorageStoreMessageChannel, createSnapshotRestorePatch, createStorageStoreMessageChannel, mirrorKey };
|