@flurryx/store 0.8.4 → 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 +1044 -326
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +558 -18
- package/dist/index.d.ts +558 -18
- package/dist/index.js +1038 -331
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -24,14 +24,598 @@ __export(index_exports, {
|
|
|
24
24
|
LazyStore: () => LazyStore,
|
|
25
25
|
Store: () => Store,
|
|
26
26
|
clearAllStores: () => clearAllStores,
|
|
27
|
+
cloneValue: () => cloneValue,
|
|
27
28
|
collectKeyed: () => collectKeyed,
|
|
29
|
+
createCompositeStoreMessageChannel: () => createCompositeStoreMessageChannel,
|
|
30
|
+
createInMemoryStoreMessageChannel: () => createInMemoryStoreMessageChannel,
|
|
31
|
+
createLocalStorageStoreMessageChannel: () => createLocalStorageStoreMessageChannel,
|
|
32
|
+
createSessionStorageStoreMessageChannel: () => createSessionStorageStoreMessageChannel,
|
|
33
|
+
createSnapshotRestorePatch: () => createSnapshotRestorePatch,
|
|
34
|
+
createStorageStoreMessageChannel: () => createStorageStoreMessageChannel,
|
|
28
35
|
mirrorKey: () => mirrorKey
|
|
29
36
|
});
|
|
30
37
|
module.exports = __toCommonJS(index_exports);
|
|
31
38
|
|
|
32
39
|
// src/base-store.ts
|
|
33
|
-
var
|
|
34
|
-
|
|
40
|
+
var import_core2 = require("@angular/core");
|
|
41
|
+
|
|
42
|
+
// src/store-clone.ts
|
|
43
|
+
function cloneValue(value) {
|
|
44
|
+
if (value !== null && typeof value === "object") {
|
|
45
|
+
const existingClone = cloneReference(value, /* @__PURE__ */ new WeakMap());
|
|
46
|
+
return existingClone;
|
|
47
|
+
}
|
|
48
|
+
return value;
|
|
49
|
+
}
|
|
50
|
+
function cloneReference(value, seen) {
|
|
51
|
+
const seenClone = seen.get(value);
|
|
52
|
+
if (seenClone) {
|
|
53
|
+
return seenClone;
|
|
54
|
+
}
|
|
55
|
+
if (value instanceof Date) {
|
|
56
|
+
return new Date(value.getTime());
|
|
57
|
+
}
|
|
58
|
+
if (value instanceof Map) {
|
|
59
|
+
const clonedMap = /* @__PURE__ */ new Map();
|
|
60
|
+
seen.set(value, clonedMap);
|
|
61
|
+
value.forEach((entryValue, key) => {
|
|
62
|
+
clonedMap.set(
|
|
63
|
+
cloneValueWithSeen(key, seen),
|
|
64
|
+
cloneValueWithSeen(entryValue, seen)
|
|
65
|
+
);
|
|
66
|
+
});
|
|
67
|
+
return clonedMap;
|
|
68
|
+
}
|
|
69
|
+
if (value instanceof Set) {
|
|
70
|
+
const clonedSet = /* @__PURE__ */ new Set();
|
|
71
|
+
seen.set(value, clonedSet);
|
|
72
|
+
value.forEach((entryValue) => {
|
|
73
|
+
clonedSet.add(cloneValueWithSeen(entryValue, seen));
|
|
74
|
+
});
|
|
75
|
+
return clonedSet;
|
|
76
|
+
}
|
|
77
|
+
if (Array.isArray(value)) {
|
|
78
|
+
const clonedArray = [];
|
|
79
|
+
seen.set(value, clonedArray);
|
|
80
|
+
value.forEach((item, index) => {
|
|
81
|
+
clonedArray[index] = cloneValueWithSeen(item, seen);
|
|
82
|
+
});
|
|
83
|
+
return clonedArray;
|
|
84
|
+
}
|
|
85
|
+
const clonedObject = Object.create(Object.getPrototypeOf(value));
|
|
86
|
+
seen.set(value, clonedObject);
|
|
87
|
+
Reflect.ownKeys(value).forEach((key) => {
|
|
88
|
+
const descriptor = Object.getOwnPropertyDescriptor(value, key);
|
|
89
|
+
if (!descriptor) {
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
if ("value" in descriptor) {
|
|
93
|
+
descriptor.value = cloneValueWithSeen(descriptor.value, seen);
|
|
94
|
+
}
|
|
95
|
+
Object.defineProperty(clonedObject, key, descriptor);
|
|
96
|
+
});
|
|
97
|
+
return clonedObject;
|
|
98
|
+
}
|
|
99
|
+
function cloneValueWithSeen(value, seen) {
|
|
100
|
+
if (value !== null && typeof value === "object") {
|
|
101
|
+
return cloneReference(value, seen);
|
|
102
|
+
}
|
|
103
|
+
return value;
|
|
104
|
+
}
|
|
105
|
+
function createSnapshotRestorePatch(currentState, snapshotState) {
|
|
106
|
+
const patch = {};
|
|
107
|
+
const keys = /* @__PURE__ */ new Set([
|
|
108
|
+
...Reflect.ownKeys(currentState),
|
|
109
|
+
...Reflect.ownKeys(snapshotState)
|
|
110
|
+
]);
|
|
111
|
+
keys.forEach((key) => {
|
|
112
|
+
if (Object.prototype.hasOwnProperty.call(snapshotState, key)) {
|
|
113
|
+
patch[key] = cloneValue(
|
|
114
|
+
snapshotState[key]
|
|
115
|
+
);
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
patch[key] = void 0;
|
|
119
|
+
});
|
|
120
|
+
return patch;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// src/store-messages.ts
|
|
124
|
+
var INVALID_HISTORY_INDEX_ERROR = "History index is out of range";
|
|
125
|
+
var INVALID_HISTORY_MESSAGE_ID_ERROR = "History message id is out of range";
|
|
126
|
+
var MESSAGE_NOT_ACKNOWLEDGED_ERROR = "Message was not acknowledged";
|
|
127
|
+
|
|
128
|
+
// src/store-channels.ts
|
|
129
|
+
function serializeStoreMessageChannelValue(value) {
|
|
130
|
+
if (value === void 0) {
|
|
131
|
+
return { __flurryxType: "undefined" };
|
|
132
|
+
}
|
|
133
|
+
if (value === null || typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
134
|
+
return value;
|
|
135
|
+
}
|
|
136
|
+
if (value instanceof Date) {
|
|
137
|
+
return {
|
|
138
|
+
__flurryxType: "date",
|
|
139
|
+
value: value.toISOString()
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
if (value instanceof Map) {
|
|
143
|
+
return {
|
|
144
|
+
__flurryxType: "map",
|
|
145
|
+
entries: Array.from(value.entries(), ([key, entryValue]) => [
|
|
146
|
+
serializeStoreMessageChannelValue(key),
|
|
147
|
+
serializeStoreMessageChannelValue(entryValue)
|
|
148
|
+
])
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
if (value instanceof Set) {
|
|
152
|
+
return {
|
|
153
|
+
__flurryxType: "set",
|
|
154
|
+
values: Array.from(
|
|
155
|
+
value.values(),
|
|
156
|
+
(entryValue) => serializeStoreMessageChannelValue(entryValue)
|
|
157
|
+
)
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
if (Array.isArray(value)) {
|
|
161
|
+
return {
|
|
162
|
+
__flurryxType: "array",
|
|
163
|
+
values: value.map(
|
|
164
|
+
(entryValue) => serializeStoreMessageChannelValue(entryValue)
|
|
165
|
+
)
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
if (typeof value === "object") {
|
|
169
|
+
return {
|
|
170
|
+
__flurryxType: "object",
|
|
171
|
+
entries: Object.entries(value).map(
|
|
172
|
+
([key, entryValue]) => [
|
|
173
|
+
key,
|
|
174
|
+
serializeStoreMessageChannelValue(entryValue)
|
|
175
|
+
]
|
|
176
|
+
)
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
throw new Error("Store message channel cannot serialize this value");
|
|
180
|
+
}
|
|
181
|
+
function deserializeStoreMessageChannelValue(value) {
|
|
182
|
+
if (value === null || typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
183
|
+
return value;
|
|
184
|
+
}
|
|
185
|
+
switch (value.__flurryxType) {
|
|
186
|
+
case "undefined":
|
|
187
|
+
return void 0;
|
|
188
|
+
case "date":
|
|
189
|
+
return new Date(value.value);
|
|
190
|
+
case "array":
|
|
191
|
+
return value.values.map(
|
|
192
|
+
(entryValue) => deserializeStoreMessageChannelValue(entryValue)
|
|
193
|
+
);
|
|
194
|
+
case "set":
|
|
195
|
+
return new Set(
|
|
196
|
+
value.values.map(
|
|
197
|
+
(entryValue) => deserializeStoreMessageChannelValue(entryValue)
|
|
198
|
+
)
|
|
199
|
+
);
|
|
200
|
+
case "map":
|
|
201
|
+
return new Map(
|
|
202
|
+
value.entries.map(([key, entryValue]) => [
|
|
203
|
+
deserializeStoreMessageChannelValue(key),
|
|
204
|
+
deserializeStoreMessageChannelValue(entryValue)
|
|
205
|
+
])
|
|
206
|
+
);
|
|
207
|
+
case "object": {
|
|
208
|
+
const result = {};
|
|
209
|
+
value.entries.forEach(([key, entryValue]) => {
|
|
210
|
+
result[key] = deserializeStoreMessageChannelValue(entryValue);
|
|
211
|
+
});
|
|
212
|
+
return result;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
function defaultSerializeStoreMessageChannelState(state) {
|
|
217
|
+
return JSON.stringify(serializeStoreMessageChannelValue(state));
|
|
218
|
+
}
|
|
219
|
+
function defaultDeserializeStoreMessageChannelState(value) {
|
|
220
|
+
return deserializeStoreMessageChannelValue(
|
|
221
|
+
JSON.parse(value)
|
|
222
|
+
);
|
|
223
|
+
}
|
|
224
|
+
function normalizeStoreMessageChannelState(state) {
|
|
225
|
+
const maxId = state.messages.reduce(
|
|
226
|
+
(currentMax, entry) => Math.max(currentMax, entry.id),
|
|
227
|
+
0
|
|
228
|
+
);
|
|
229
|
+
return {
|
|
230
|
+
nextId: Math.max(state.nextId, maxId + 1),
|
|
231
|
+
messages: state.messages.map((entry) => cloneValue(entry))
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
function createInitialStoreMessageRecord(id, message, clock = Date.now) {
|
|
235
|
+
return {
|
|
236
|
+
id,
|
|
237
|
+
message: cloneValue(message),
|
|
238
|
+
status: "pending",
|
|
239
|
+
attempts: 0,
|
|
240
|
+
createdAt: clock(),
|
|
241
|
+
lastAttemptedAt: null,
|
|
242
|
+
acknowledgedAt: null,
|
|
243
|
+
error: null
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
function isQuotaExceededError(error) {
|
|
247
|
+
return error instanceof DOMException && (error.code === 22 || error.code === 1014 || error.name === "QuotaExceededError" || error.name === "NS_ERROR_DOM_QUOTA_REACHED");
|
|
248
|
+
}
|
|
249
|
+
function resolveGlobalStorage(name) {
|
|
250
|
+
const storage = globalThis[name];
|
|
251
|
+
if (!storage) {
|
|
252
|
+
throw new Error(`${name} is not available in this environment`);
|
|
253
|
+
}
|
|
254
|
+
return storage;
|
|
255
|
+
}
|
|
256
|
+
function createInMemoryStoreMessageChannel() {
|
|
257
|
+
let messages = [];
|
|
258
|
+
let nextId = 1;
|
|
259
|
+
return {
|
|
260
|
+
publish(message) {
|
|
261
|
+
const record = createInitialStoreMessageRecord(nextId++, message);
|
|
262
|
+
messages = [...messages, record];
|
|
263
|
+
return cloneValue(record);
|
|
264
|
+
},
|
|
265
|
+
getMessage(id) {
|
|
266
|
+
const record = messages.find((entry) => entry.id === id);
|
|
267
|
+
return record ? cloneValue(record) : void 0;
|
|
268
|
+
},
|
|
269
|
+
getMessages() {
|
|
270
|
+
return messages.map((entry) => cloneValue(entry));
|
|
271
|
+
},
|
|
272
|
+
saveMessage(entry) {
|
|
273
|
+
const record = cloneValue(entry);
|
|
274
|
+
const existingIndex = messages.findIndex(
|
|
275
|
+
(candidate) => candidate.id === record.id
|
|
276
|
+
);
|
|
277
|
+
if (existingIndex === -1) {
|
|
278
|
+
messages = [...messages, record];
|
|
279
|
+
} else {
|
|
280
|
+
messages = messages.map((c, i) => i === existingIndex ? record : c);
|
|
281
|
+
}
|
|
282
|
+
nextId = Math.max(nextId, record.id + 1);
|
|
283
|
+
}
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
function createStorageStoreMessageChannel(options) {
|
|
287
|
+
const serialize = options.serialize ?? defaultSerializeStoreMessageChannelState;
|
|
288
|
+
const deserialize = options.deserialize ?? defaultDeserializeStoreMessageChannelState;
|
|
289
|
+
function readState() {
|
|
290
|
+
const rawState = options.storage.getItem(options.storageKey);
|
|
291
|
+
if (rawState === null) {
|
|
292
|
+
return { nextId: 1, messages: [] };
|
|
293
|
+
}
|
|
294
|
+
try {
|
|
295
|
+
return normalizeStoreMessageChannelState(deserialize(rawState));
|
|
296
|
+
} catch {
|
|
297
|
+
return { nextId: 1, messages: [] };
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
function writeState(state) {
|
|
301
|
+
const normalized = normalizeStoreMessageChannelState(state);
|
|
302
|
+
try {
|
|
303
|
+
options.storage.setItem(options.storageKey, serialize(normalized));
|
|
304
|
+
} catch (error) {
|
|
305
|
+
if (!isQuotaExceededError(error) || normalized.messages.length === 0) {
|
|
306
|
+
throw error;
|
|
307
|
+
}
|
|
308
|
+
let remaining = [...normalized.messages];
|
|
309
|
+
while (remaining.length > 0) {
|
|
310
|
+
remaining = remaining.slice(1);
|
|
311
|
+
try {
|
|
312
|
+
options.storage.setItem(
|
|
313
|
+
options.storageKey,
|
|
314
|
+
serialize({ nextId: normalized.nextId, messages: remaining })
|
|
315
|
+
);
|
|
316
|
+
return;
|
|
317
|
+
} catch (retryError) {
|
|
318
|
+
if (!isQuotaExceededError(retryError)) {
|
|
319
|
+
throw retryError;
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
options.storage.setItem(
|
|
324
|
+
options.storageKey,
|
|
325
|
+
serialize({ nextId: normalized.nextId, messages: [] })
|
|
326
|
+
);
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
return {
|
|
330
|
+
publish(message) {
|
|
331
|
+
const state = readState();
|
|
332
|
+
const record = createInitialStoreMessageRecord(state.nextId, message);
|
|
333
|
+
writeState({
|
|
334
|
+
nextId: state.nextId + 1,
|
|
335
|
+
messages: [...state.messages, record]
|
|
336
|
+
});
|
|
337
|
+
return cloneValue(record);
|
|
338
|
+
},
|
|
339
|
+
getMessage(id) {
|
|
340
|
+
const record = readState().messages.find((entry) => entry.id === id);
|
|
341
|
+
return record ? cloneValue(record) : void 0;
|
|
342
|
+
},
|
|
343
|
+
getMessages() {
|
|
344
|
+
return readState().messages.map((entry) => cloneValue(entry));
|
|
345
|
+
},
|
|
346
|
+
saveMessage(entry) {
|
|
347
|
+
const state = readState();
|
|
348
|
+
const record = cloneValue(entry);
|
|
349
|
+
const existingIndex = state.messages.findIndex(
|
|
350
|
+
(candidate) => candidate.id === record.id
|
|
351
|
+
);
|
|
352
|
+
if (existingIndex === -1) {
|
|
353
|
+
writeState({
|
|
354
|
+
nextId: Math.max(state.nextId, record.id + 1),
|
|
355
|
+
messages: [...state.messages, record]
|
|
356
|
+
});
|
|
357
|
+
return;
|
|
358
|
+
}
|
|
359
|
+
const nextMessages = state.messages.map(
|
|
360
|
+
(c, i) => i === existingIndex ? record : c
|
|
361
|
+
);
|
|
362
|
+
writeState({
|
|
363
|
+
nextId: Math.max(state.nextId, record.id + 1),
|
|
364
|
+
messages: nextMessages
|
|
365
|
+
});
|
|
366
|
+
}
|
|
367
|
+
};
|
|
368
|
+
}
|
|
369
|
+
function createLocalStorageStoreMessageChannel(options) {
|
|
370
|
+
return createStorageStoreMessageChannel({
|
|
371
|
+
...options,
|
|
372
|
+
storage: options.storage ?? resolveGlobalStorage("localStorage")
|
|
373
|
+
});
|
|
374
|
+
}
|
|
375
|
+
function createSessionStorageStoreMessageChannel(options) {
|
|
376
|
+
return createStorageStoreMessageChannel({
|
|
377
|
+
...options,
|
|
378
|
+
storage: options.storage ?? resolveGlobalStorage("sessionStorage")
|
|
379
|
+
});
|
|
380
|
+
}
|
|
381
|
+
function createCompositeStoreMessageChannel(options) {
|
|
382
|
+
if (options.channels.length === 0) {
|
|
383
|
+
throw new Error(
|
|
384
|
+
"createCompositeStoreMessageChannel: 'channels' option must contain at least one channel"
|
|
385
|
+
);
|
|
386
|
+
}
|
|
387
|
+
const primaryChannel = options.channels[0];
|
|
388
|
+
const replicaChannels = options.channels.slice(1);
|
|
389
|
+
return {
|
|
390
|
+
publish(message) {
|
|
391
|
+
const record = primaryChannel.publish(message);
|
|
392
|
+
replicaChannels.forEach((channel) => {
|
|
393
|
+
channel.saveMessage(record);
|
|
394
|
+
});
|
|
395
|
+
return cloneValue(record);
|
|
396
|
+
},
|
|
397
|
+
getMessage(id) {
|
|
398
|
+
const record = primaryChannel.getMessage(id);
|
|
399
|
+
return record ? cloneValue(record) : void 0;
|
|
400
|
+
},
|
|
401
|
+
getMessages() {
|
|
402
|
+
return primaryChannel.getMessages().map((record) => cloneValue(record));
|
|
403
|
+
},
|
|
404
|
+
saveMessage(entry) {
|
|
405
|
+
primaryChannel.saveMessage(entry);
|
|
406
|
+
replicaChannels.forEach((channel) => {
|
|
407
|
+
channel.saveMessage(entry);
|
|
408
|
+
});
|
|
409
|
+
}
|
|
410
|
+
};
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
// src/store-replay.ts
|
|
414
|
+
function messageAffectsKey(message, key) {
|
|
415
|
+
if (message.type === "clearAll") {
|
|
416
|
+
return true;
|
|
417
|
+
}
|
|
418
|
+
return "key" in message && message.key === key;
|
|
419
|
+
}
|
|
420
|
+
function toDeadLetterEntry(record) {
|
|
421
|
+
return {
|
|
422
|
+
id: record.id,
|
|
423
|
+
message: cloneValue(record.message),
|
|
424
|
+
attempts: record.attempts,
|
|
425
|
+
error: record.error ?? MESSAGE_NOT_ACKNOWLEDGED_ERROR,
|
|
426
|
+
failedAt: record.lastAttemptedAt ?? record.createdAt
|
|
427
|
+
};
|
|
428
|
+
}
|
|
429
|
+
function createStoreHistory(config) {
|
|
430
|
+
const messageChannel = config.channel ?? createInMemoryStoreMessageChannel();
|
|
431
|
+
const clock = config.clock ?? Date.now;
|
|
432
|
+
let history = [
|
|
433
|
+
{
|
|
434
|
+
id: null,
|
|
435
|
+
index: 0,
|
|
436
|
+
message: null,
|
|
437
|
+
snapshot: config.captureSnapshot(),
|
|
438
|
+
acknowledgedAt: null
|
|
439
|
+
}
|
|
440
|
+
];
|
|
441
|
+
let currentIndex = 0;
|
|
442
|
+
function recordSnapshot(record) {
|
|
443
|
+
const nextIndex = history.length;
|
|
444
|
+
history = [
|
|
445
|
+
...history,
|
|
446
|
+
{
|
|
447
|
+
id: record.id,
|
|
448
|
+
index: nextIndex,
|
|
449
|
+
message: cloneValue(record.message),
|
|
450
|
+
snapshot: config.captureSnapshot(),
|
|
451
|
+
acknowledgedAt: record.acknowledgedAt
|
|
452
|
+
}
|
|
453
|
+
];
|
|
454
|
+
currentIndex = nextIndex;
|
|
455
|
+
}
|
|
456
|
+
function truncateFutureHistory() {
|
|
457
|
+
if (currentIndex === history.length - 1) {
|
|
458
|
+
return;
|
|
459
|
+
}
|
|
460
|
+
history = history.slice(0, currentIndex + 1);
|
|
461
|
+
}
|
|
462
|
+
function ensureIndexInRange(index) {
|
|
463
|
+
if (!Number.isInteger(index) || index < 0 || index >= history.length) {
|
|
464
|
+
throw new Error(INVALID_HISTORY_INDEX_ERROR);
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
function travelTo(index) {
|
|
468
|
+
ensureIndexInRange(index);
|
|
469
|
+
config.applySnapshot(history[index].snapshot);
|
|
470
|
+
currentIndex = index;
|
|
471
|
+
}
|
|
472
|
+
function undo() {
|
|
473
|
+
if (currentIndex === 0) {
|
|
474
|
+
return false;
|
|
475
|
+
}
|
|
476
|
+
travelTo(currentIndex - 1);
|
|
477
|
+
return true;
|
|
478
|
+
}
|
|
479
|
+
function redo() {
|
|
480
|
+
if (currentIndex >= history.length - 1) {
|
|
481
|
+
return false;
|
|
482
|
+
}
|
|
483
|
+
travelTo(currentIndex + 1);
|
|
484
|
+
return true;
|
|
485
|
+
}
|
|
486
|
+
function getErrorMessage(error) {
|
|
487
|
+
if (error instanceof Error && error.message) {
|
|
488
|
+
return error.message;
|
|
489
|
+
}
|
|
490
|
+
return MESSAGE_NOT_ACKNOWLEDGED_ERROR;
|
|
491
|
+
}
|
|
492
|
+
function persistMessageAttempt(record, status, error, attemptedAt) {
|
|
493
|
+
const nextRecord = {
|
|
494
|
+
...record,
|
|
495
|
+
message: cloneValue(record.message),
|
|
496
|
+
status,
|
|
497
|
+
attempts: record.attempts + 1,
|
|
498
|
+
lastAttemptedAt: attemptedAt,
|
|
499
|
+
acknowledgedAt: status === "acknowledged" ? attemptedAt : record.acknowledgedAt,
|
|
500
|
+
error
|
|
501
|
+
};
|
|
502
|
+
messageChannel.saveMessage(nextRecord);
|
|
503
|
+
return nextRecord;
|
|
504
|
+
}
|
|
505
|
+
function consumeRecord(record, options) {
|
|
506
|
+
const clonedMessage = cloneValue(record.message);
|
|
507
|
+
const attemptedAt = clock();
|
|
508
|
+
try {
|
|
509
|
+
const acknowledged = config.applyMessage(clonedMessage);
|
|
510
|
+
if (!acknowledged) {
|
|
511
|
+
throw new Error(MESSAGE_NOT_ACKNOWLEDGED_ERROR);
|
|
512
|
+
}
|
|
513
|
+
const acknowledgedRecord = persistMessageAttempt(
|
|
514
|
+
{
|
|
515
|
+
...record,
|
|
516
|
+
message: clonedMessage
|
|
517
|
+
},
|
|
518
|
+
"acknowledged",
|
|
519
|
+
null,
|
|
520
|
+
attemptedAt
|
|
521
|
+
);
|
|
522
|
+
if (options?.recordHistory !== false) {
|
|
523
|
+
truncateFutureHistory();
|
|
524
|
+
recordSnapshot(acknowledgedRecord);
|
|
525
|
+
}
|
|
526
|
+
return true;
|
|
527
|
+
} catch (error) {
|
|
528
|
+
persistMessageAttempt(
|
|
529
|
+
{
|
|
530
|
+
...record,
|
|
531
|
+
message: clonedMessage
|
|
532
|
+
},
|
|
533
|
+
"dead-letter",
|
|
534
|
+
getErrorMessage(error),
|
|
535
|
+
attemptedAt
|
|
536
|
+
);
|
|
537
|
+
return false;
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
function resolveReplayRecords(ids) {
|
|
541
|
+
return ids.map((id) => {
|
|
542
|
+
if (!Number.isInteger(id) || id < 1) {
|
|
543
|
+
throw new Error(INVALID_HISTORY_MESSAGE_ID_ERROR);
|
|
544
|
+
}
|
|
545
|
+
const record = messageChannel.getMessage(id);
|
|
546
|
+
if (!record) {
|
|
547
|
+
throw new Error(INVALID_HISTORY_MESSAGE_ID_ERROR);
|
|
548
|
+
}
|
|
549
|
+
return cloneValue(record);
|
|
550
|
+
});
|
|
551
|
+
}
|
|
552
|
+
function replayByIds(input) {
|
|
553
|
+
const ids = Array.isArray(input) ? input : [input];
|
|
554
|
+
const records = resolveReplayRecords(ids);
|
|
555
|
+
let acknowledgedCount = 0;
|
|
556
|
+
records.forEach((record) => {
|
|
557
|
+
if (consumeRecord(record)) {
|
|
558
|
+
acknowledgedCount += 1;
|
|
559
|
+
}
|
|
560
|
+
});
|
|
561
|
+
return acknowledgedCount;
|
|
562
|
+
}
|
|
563
|
+
function replayDeadLetter(id) {
|
|
564
|
+
const record = messageChannel.getMessage(id);
|
|
565
|
+
if (!record || record.status !== "dead-letter") {
|
|
566
|
+
return false;
|
|
567
|
+
}
|
|
568
|
+
return consumeRecord(record);
|
|
569
|
+
}
|
|
570
|
+
function replayDeadLetters() {
|
|
571
|
+
const ids = messageChannel.getMessages().filter((record) => record.status === "dead-letter").map((record) => record.id);
|
|
572
|
+
let acknowledgedCount = 0;
|
|
573
|
+
ids.forEach((id) => {
|
|
574
|
+
if (replayDeadLetter(id)) {
|
|
575
|
+
acknowledgedCount += 1;
|
|
576
|
+
}
|
|
577
|
+
});
|
|
578
|
+
return acknowledgedCount;
|
|
579
|
+
}
|
|
580
|
+
return {
|
|
581
|
+
publish(message) {
|
|
582
|
+
const record = messageChannel.publish(message);
|
|
583
|
+
return consumeRecord(record);
|
|
584
|
+
},
|
|
585
|
+
replay(input) {
|
|
586
|
+
return replayByIds(input);
|
|
587
|
+
},
|
|
588
|
+
travelTo,
|
|
589
|
+
undo,
|
|
590
|
+
redo,
|
|
591
|
+
getHistory(key) {
|
|
592
|
+
if (key === void 0) {
|
|
593
|
+
return history.map((entry) => cloneValue(entry));
|
|
594
|
+
}
|
|
595
|
+
return history.filter((entry) => {
|
|
596
|
+
if (entry.message === null) {
|
|
597
|
+
return true;
|
|
598
|
+
}
|
|
599
|
+
return messageAffectsKey(entry.message, key);
|
|
600
|
+
}).map((entry) => cloneValue(entry));
|
|
601
|
+
},
|
|
602
|
+
getMessages(key) {
|
|
603
|
+
const records = messageChannel.getMessages();
|
|
604
|
+
if (key === void 0) {
|
|
605
|
+
return records.map((record) => cloneValue(record));
|
|
606
|
+
}
|
|
607
|
+
return records.filter((record) => messageAffectsKey(record.message, key)).map((record) => cloneValue(record));
|
|
608
|
+
},
|
|
609
|
+
getDeadLetters() {
|
|
610
|
+
return messageChannel.getMessages().filter((record) => record.status === "dead-letter").map((record) => toDeadLetterEntry(record));
|
|
611
|
+
},
|
|
612
|
+
replayDeadLetter,
|
|
613
|
+
replayDeadLetters,
|
|
614
|
+
getCurrentIndex() {
|
|
615
|
+
return currentIndex;
|
|
616
|
+
}
|
|
617
|
+
};
|
|
618
|
+
}
|
|
35
619
|
|
|
36
620
|
// src/store-registry.ts
|
|
37
621
|
var trackedStores = /* @__PURE__ */ new Set();
|
|
@@ -44,16 +628,305 @@ function clearAllStores() {
|
|
|
44
628
|
}
|
|
45
629
|
}
|
|
46
630
|
|
|
631
|
+
// src/store-message-consumer.ts
|
|
632
|
+
var import_core = require("@flurryx/core");
|
|
633
|
+
function createDefaultState() {
|
|
634
|
+
return {
|
|
635
|
+
data: void 0,
|
|
636
|
+
isLoading: false,
|
|
637
|
+
status: void 0,
|
|
638
|
+
errors: void 0
|
|
639
|
+
};
|
|
640
|
+
}
|
|
641
|
+
function createStoreMessageConsumer(signals, notifier) {
|
|
642
|
+
function applyUpdate(key, newState, notify = true) {
|
|
643
|
+
const sig = signals.getOrCreate(key);
|
|
644
|
+
const previousState = sig();
|
|
645
|
+
sig.update((state) => ({ ...state, ...newState }));
|
|
646
|
+
if (notify) {
|
|
647
|
+
const updatedState = sig();
|
|
648
|
+
notifier.notify(key, updatedState, previousState);
|
|
649
|
+
}
|
|
650
|
+
return true;
|
|
651
|
+
}
|
|
652
|
+
function applyClear(key) {
|
|
653
|
+
const sig = signals.getOrCreate(key);
|
|
654
|
+
const previousState = sig();
|
|
655
|
+
sig.set(createDefaultState());
|
|
656
|
+
const nextState = sig();
|
|
657
|
+
notifier.notify(key, nextState, previousState);
|
|
658
|
+
return true;
|
|
659
|
+
}
|
|
660
|
+
function applyClearAll() {
|
|
661
|
+
const keys = Array.from(signals.getAllKeys());
|
|
662
|
+
if (keys.length === 0) {
|
|
663
|
+
return false;
|
|
664
|
+
}
|
|
665
|
+
keys.forEach((key) => {
|
|
666
|
+
applyClear(key);
|
|
667
|
+
});
|
|
668
|
+
return true;
|
|
669
|
+
}
|
|
670
|
+
function applyStartLoading(key) {
|
|
671
|
+
const sig = signals.getOrCreate(key);
|
|
672
|
+
sig.update(
|
|
673
|
+
(state) => ({
|
|
674
|
+
...state,
|
|
675
|
+
status: void 0,
|
|
676
|
+
isLoading: true,
|
|
677
|
+
errors: void 0
|
|
678
|
+
})
|
|
679
|
+
);
|
|
680
|
+
return true;
|
|
681
|
+
}
|
|
682
|
+
function applyStopLoading(key) {
|
|
683
|
+
const sig = signals.getOrCreate(key);
|
|
684
|
+
sig.update(
|
|
685
|
+
(state) => ({
|
|
686
|
+
...state,
|
|
687
|
+
isLoading: false
|
|
688
|
+
})
|
|
689
|
+
);
|
|
690
|
+
return true;
|
|
691
|
+
}
|
|
692
|
+
function applyUpdateKeyedOne(key, resourceKey, entity) {
|
|
693
|
+
const sig = signals.getOrCreate(key);
|
|
694
|
+
const state = sig();
|
|
695
|
+
const data = (0, import_core.isKeyedResourceData)(state.data) ? state.data : (0, import_core.createKeyedResourceData)();
|
|
696
|
+
const nextErrors = { ...data.errors };
|
|
697
|
+
delete nextErrors[resourceKey];
|
|
698
|
+
const nextData = {
|
|
699
|
+
...data,
|
|
700
|
+
entities: { ...data.entities, [resourceKey]: entity },
|
|
701
|
+
isLoading: { ...data.isLoading, [resourceKey]: false },
|
|
702
|
+
status: { ...data.status, [resourceKey]: "Success" },
|
|
703
|
+
errors: nextErrors
|
|
704
|
+
};
|
|
705
|
+
return applyUpdate(key, {
|
|
706
|
+
data: nextData,
|
|
707
|
+
isLoading: (0, import_core.isAnyKeyLoading)(nextData.isLoading),
|
|
708
|
+
status: void 0,
|
|
709
|
+
errors: void 0
|
|
710
|
+
});
|
|
711
|
+
}
|
|
712
|
+
function applyClearKeyedOne(key, resourceKey) {
|
|
713
|
+
const sig = signals.getOrCreate(key);
|
|
714
|
+
const previousState = sig();
|
|
715
|
+
const state = previousState;
|
|
716
|
+
if (!(0, import_core.isKeyedResourceData)(state.data)) {
|
|
717
|
+
return true;
|
|
718
|
+
}
|
|
719
|
+
const data = state.data;
|
|
720
|
+
const nextEntities = { ...data.entities };
|
|
721
|
+
delete nextEntities[resourceKey];
|
|
722
|
+
const nextIsLoading = { ...data.isLoading };
|
|
723
|
+
delete nextIsLoading[resourceKey];
|
|
724
|
+
const nextStatus = { ...data.status };
|
|
725
|
+
delete nextStatus[resourceKey];
|
|
726
|
+
const nextErrors = { ...data.errors };
|
|
727
|
+
delete nextErrors[resourceKey];
|
|
728
|
+
const nextData = {
|
|
729
|
+
...data,
|
|
730
|
+
entities: nextEntities,
|
|
731
|
+
isLoading: nextIsLoading,
|
|
732
|
+
status: nextStatus,
|
|
733
|
+
errors: nextErrors
|
|
734
|
+
};
|
|
735
|
+
sig.update(
|
|
736
|
+
(prev) => ({
|
|
737
|
+
...prev,
|
|
738
|
+
data: nextData,
|
|
739
|
+
status: void 0,
|
|
740
|
+
isLoading: (0, import_core.isAnyKeyLoading)(nextIsLoading),
|
|
741
|
+
errors: void 0
|
|
742
|
+
})
|
|
743
|
+
);
|
|
744
|
+
const updatedState = sig();
|
|
745
|
+
notifier.notify(key, updatedState, previousState);
|
|
746
|
+
return true;
|
|
747
|
+
}
|
|
748
|
+
function applyStartKeyedLoading(key, resourceKey) {
|
|
749
|
+
const sig = signals.getOrCreate(key);
|
|
750
|
+
const state = sig();
|
|
751
|
+
if (!(0, import_core.isKeyedResourceData)(state.data)) {
|
|
752
|
+
return applyStartLoading(key);
|
|
753
|
+
}
|
|
754
|
+
const previousState = state;
|
|
755
|
+
const data = state.data;
|
|
756
|
+
const nextIsLoading = {
|
|
757
|
+
...data.isLoading,
|
|
758
|
+
[resourceKey]: true
|
|
759
|
+
};
|
|
760
|
+
const nextStatus = { ...data.status };
|
|
761
|
+
delete nextStatus[resourceKey];
|
|
762
|
+
const nextErrors = { ...data.errors };
|
|
763
|
+
delete nextErrors[resourceKey];
|
|
764
|
+
const nextData = {
|
|
765
|
+
...data,
|
|
766
|
+
isLoading: nextIsLoading,
|
|
767
|
+
status: nextStatus,
|
|
768
|
+
errors: nextErrors
|
|
769
|
+
};
|
|
770
|
+
sig.update(
|
|
771
|
+
(previous) => ({
|
|
772
|
+
...previous,
|
|
773
|
+
data: nextData,
|
|
774
|
+
status: void 0,
|
|
775
|
+
isLoading: (0, import_core.isAnyKeyLoading)(nextIsLoading),
|
|
776
|
+
errors: void 0
|
|
777
|
+
})
|
|
778
|
+
);
|
|
779
|
+
const updatedState = sig();
|
|
780
|
+
notifier.notify(key, updatedState, previousState);
|
|
781
|
+
return true;
|
|
782
|
+
}
|
|
783
|
+
function applyMessage(message) {
|
|
784
|
+
switch (message.type) {
|
|
785
|
+
case "update":
|
|
786
|
+
return applyUpdate(message.key, cloneValue(message.state));
|
|
787
|
+
case "clear":
|
|
788
|
+
return applyClear(message.key);
|
|
789
|
+
case "clearAll":
|
|
790
|
+
return applyClearAll();
|
|
791
|
+
case "startLoading":
|
|
792
|
+
return applyStartLoading(message.key);
|
|
793
|
+
case "stopLoading":
|
|
794
|
+
return applyStopLoading(message.key);
|
|
795
|
+
case "updateKeyedOne":
|
|
796
|
+
return applyUpdateKeyedOne(
|
|
797
|
+
message.key,
|
|
798
|
+
message.resourceKey,
|
|
799
|
+
cloneValue(message.entity)
|
|
800
|
+
);
|
|
801
|
+
case "clearKeyedOne":
|
|
802
|
+
return applyClearKeyedOne(message.key, message.resourceKey);
|
|
803
|
+
case "startKeyedLoading":
|
|
804
|
+
return applyStartKeyedLoading(message.key, message.resourceKey);
|
|
805
|
+
}
|
|
806
|
+
}
|
|
807
|
+
function applySnapshot(snapshot) {
|
|
808
|
+
const keys = /* @__PURE__ */ new Set([
|
|
809
|
+
...Array.from(signals.getAllKeys()),
|
|
810
|
+
...Object.keys(snapshot)
|
|
811
|
+
]);
|
|
812
|
+
keys.forEach((rawKey) => {
|
|
813
|
+
const key = rawKey;
|
|
814
|
+
const sig = signals.getOrCreate(key);
|
|
815
|
+
const snapshotState = snapshot[key] ?? createDefaultState();
|
|
816
|
+
applyUpdate(key, createSnapshotRestorePatch(sig(), snapshotState), true);
|
|
817
|
+
});
|
|
818
|
+
}
|
|
819
|
+
function captureSnapshot() {
|
|
820
|
+
const entries = Array.from(signals.getAllKeys()).map((key) => [
|
|
821
|
+
key,
|
|
822
|
+
cloneValue(signals.getOrCreate(key)())
|
|
823
|
+
]);
|
|
824
|
+
return Object.fromEntries(entries);
|
|
825
|
+
}
|
|
826
|
+
return {
|
|
827
|
+
applyMessage,
|
|
828
|
+
applySnapshot,
|
|
829
|
+
createSnapshot: captureSnapshot
|
|
830
|
+
};
|
|
831
|
+
}
|
|
832
|
+
function createUpdateMessage(key, state) {
|
|
833
|
+
return { type: "update", key, state };
|
|
834
|
+
}
|
|
835
|
+
function createClearMessage(key) {
|
|
836
|
+
return { type: "clear", key };
|
|
837
|
+
}
|
|
838
|
+
function createClearAllMessage() {
|
|
839
|
+
return { type: "clearAll" };
|
|
840
|
+
}
|
|
841
|
+
function createStartLoadingMessage(key) {
|
|
842
|
+
return { type: "startLoading", key };
|
|
843
|
+
}
|
|
844
|
+
function createStopLoadingMessage(key) {
|
|
845
|
+
return { type: "stopLoading", key };
|
|
846
|
+
}
|
|
847
|
+
function createUpdateKeyedOneMessage(key, resourceKey, entity) {
|
|
848
|
+
return {
|
|
849
|
+
type: "updateKeyedOne",
|
|
850
|
+
key,
|
|
851
|
+
resourceKey,
|
|
852
|
+
entity
|
|
853
|
+
};
|
|
854
|
+
}
|
|
855
|
+
function createClearKeyedOneMessage(key, resourceKey) {
|
|
856
|
+
return {
|
|
857
|
+
type: "clearKeyedOne",
|
|
858
|
+
key,
|
|
859
|
+
resourceKey
|
|
860
|
+
};
|
|
861
|
+
}
|
|
862
|
+
function createStartKeyedLoadingMessage(key, resourceKey) {
|
|
863
|
+
return {
|
|
864
|
+
type: "startKeyedLoading",
|
|
865
|
+
key,
|
|
866
|
+
resourceKey
|
|
867
|
+
};
|
|
868
|
+
}
|
|
869
|
+
|
|
47
870
|
// src/base-store.ts
|
|
48
871
|
var updateHooksMap = /* @__PURE__ */ new WeakMap();
|
|
49
872
|
var BaseStore = class {
|
|
50
|
-
constructor(storeEnum) {
|
|
873
|
+
constructor(storeEnum, options) {
|
|
51
874
|
this.storeEnum = storeEnum;
|
|
875
|
+
this.storeKeys = Object.keys(storeEnum);
|
|
52
876
|
this.initializeState();
|
|
53
877
|
updateHooksMap.set(this, /* @__PURE__ */ new Map());
|
|
878
|
+
const consumer = createStoreMessageConsumer(
|
|
879
|
+
{
|
|
880
|
+
getOrCreate: (key) => this.signalsState.get(key),
|
|
881
|
+
getAllKeys: () => this.storeKeys
|
|
882
|
+
},
|
|
883
|
+
{
|
|
884
|
+
notify: (key, next, prev) => this.notifyUpdateHooks(key, next, prev)
|
|
885
|
+
}
|
|
886
|
+
);
|
|
887
|
+
this.history = createStoreHistory({
|
|
888
|
+
captureSnapshot: () => consumer.createSnapshot(),
|
|
889
|
+
applySnapshot: (snapshot) => consumer.applySnapshot(snapshot),
|
|
890
|
+
applyMessage: (message) => consumer.applyMessage(message),
|
|
891
|
+
channel: options?.channel
|
|
892
|
+
});
|
|
54
893
|
trackStore(this);
|
|
55
894
|
}
|
|
56
895
|
signalsState = /* @__PURE__ */ new Map();
|
|
896
|
+
storeKeys;
|
|
897
|
+
history;
|
|
898
|
+
/** @inheritDoc */
|
|
899
|
+
travelTo = (index) => this.history.travelTo(index);
|
|
900
|
+
/** @inheritDoc */
|
|
901
|
+
undo = () => this.history.undo();
|
|
902
|
+
/** @inheritDoc */
|
|
903
|
+
redo = () => this.history.redo();
|
|
904
|
+
/** @inheritDoc */
|
|
905
|
+
getDeadLetters = () => this.history.getDeadLetters();
|
|
906
|
+
/** @inheritDoc */
|
|
907
|
+
replayDeadLetter = (id) => this.history.replayDeadLetter(id);
|
|
908
|
+
/** @inheritDoc */
|
|
909
|
+
replayDeadLetters = () => this.history.replayDeadLetters();
|
|
910
|
+
/** @inheritDoc */
|
|
911
|
+
getCurrentIndex = () => this.history.getCurrentIndex();
|
|
912
|
+
replay(idOrIds) {
|
|
913
|
+
if (Array.isArray(idOrIds)) {
|
|
914
|
+
return this.history.replay(idOrIds);
|
|
915
|
+
}
|
|
916
|
+
return this.history.replay(idOrIds);
|
|
917
|
+
}
|
|
918
|
+
getHistory(key) {
|
|
919
|
+
if (key === void 0) {
|
|
920
|
+
return this.history.getHistory();
|
|
921
|
+
}
|
|
922
|
+
return this.history.getHistory(key);
|
|
923
|
+
}
|
|
924
|
+
getMessages(key) {
|
|
925
|
+
if (key === void 0) {
|
|
926
|
+
return this.history.getMessages();
|
|
927
|
+
}
|
|
928
|
+
return this.history.getMessages(key);
|
|
929
|
+
}
|
|
57
930
|
/**
|
|
58
931
|
* Returns a **read-only** `Signal` for the given store slot.
|
|
59
932
|
*
|
|
@@ -98,23 +971,13 @@ var BaseStore = class {
|
|
|
98
971
|
* @param newState - Partial state to merge (e.g. `{ data: newData, status: 'Success' }`).
|
|
99
972
|
*/
|
|
100
973
|
update(key, newState) {
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
}
|
|
105
|
-
const previousState = currentState();
|
|
106
|
-
currentState.update((state) => ({
|
|
107
|
-
...state,
|
|
108
|
-
...newState
|
|
109
|
-
}));
|
|
110
|
-
const updatedState = currentState();
|
|
111
|
-
this.notifyUpdateHooks(key, updatedState, previousState);
|
|
974
|
+
this.history.publish(
|
|
975
|
+
createUpdateMessage(key, cloneValue(newState))
|
|
976
|
+
);
|
|
112
977
|
}
|
|
113
978
|
/** Resets every slot in this store to its initial idle state. */
|
|
114
979
|
clearAll() {
|
|
115
|
-
|
|
116
|
-
this.clear(key);
|
|
117
|
-
});
|
|
980
|
+
this.history.publish(createClearAllMessage());
|
|
118
981
|
}
|
|
119
982
|
/**
|
|
120
983
|
* Resets a single slot to `{ data: undefined, isLoading: false, status: undefined, errors: undefined }`.
|
|
@@ -122,20 +985,7 @@ var BaseStore = class {
|
|
|
122
985
|
* @param key - The slot to clear.
|
|
123
986
|
*/
|
|
124
987
|
clear(key) {
|
|
125
|
-
|
|
126
|
-
if (!currentState) {
|
|
127
|
-
return;
|
|
128
|
-
}
|
|
129
|
-
const previousState = currentState();
|
|
130
|
-
const _typedKey = key;
|
|
131
|
-
currentState.set({
|
|
132
|
-
data: void 0,
|
|
133
|
-
isLoading: false,
|
|
134
|
-
status: void 0,
|
|
135
|
-
errors: void 0
|
|
136
|
-
});
|
|
137
|
-
const nextState = currentState();
|
|
138
|
-
this.notifyUpdateHooks(key, nextState, previousState);
|
|
988
|
+
this.history.publish(createClearMessage(key));
|
|
139
989
|
}
|
|
140
990
|
/**
|
|
141
991
|
* Marks a slot as loading: sets `isLoading: true` and clears `status` and `errors`.
|
|
@@ -143,19 +993,7 @@ var BaseStore = class {
|
|
|
143
993
|
* @param key - The slot to mark as loading.
|
|
144
994
|
*/
|
|
145
995
|
startLoading(key) {
|
|
146
|
-
|
|
147
|
-
if (!currentState) {
|
|
148
|
-
return;
|
|
149
|
-
}
|
|
150
|
-
const _typedKey = key;
|
|
151
|
-
currentState.update(
|
|
152
|
-
(state) => ({
|
|
153
|
-
...state,
|
|
154
|
-
status: void 0,
|
|
155
|
-
isLoading: true,
|
|
156
|
-
errors: void 0
|
|
157
|
-
})
|
|
158
|
-
);
|
|
996
|
+
this.history.publish(createStartLoadingMessage(key));
|
|
159
997
|
}
|
|
160
998
|
/**
|
|
161
999
|
* Marks a slot as no longer loading: sets `isLoading: false`.
|
|
@@ -164,17 +1002,7 @@ var BaseStore = class {
|
|
|
164
1002
|
* @param key - The slot to stop loading.
|
|
165
1003
|
*/
|
|
166
1004
|
stopLoading(key) {
|
|
167
|
-
|
|
168
|
-
if (!currentState) {
|
|
169
|
-
return;
|
|
170
|
-
}
|
|
171
|
-
const _typedKey = key;
|
|
172
|
-
currentState.update(
|
|
173
|
-
(state) => ({
|
|
174
|
-
...state,
|
|
175
|
-
isLoading: false
|
|
176
|
-
})
|
|
177
|
-
);
|
|
1005
|
+
this.history.publish(createStopLoadingMessage(key));
|
|
178
1006
|
}
|
|
179
1007
|
/**
|
|
180
1008
|
* Merges a single entity into a {@link KeyedResourceData} slot.
|
|
@@ -186,36 +1014,13 @@ var BaseStore = class {
|
|
|
186
1014
|
* @param entity - The entity value to store.
|
|
187
1015
|
*/
|
|
188
1016
|
updateKeyedOne(key, resourceKey, entity) {
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
delete nextErrors[resourceKey];
|
|
197
|
-
const nextData = {
|
|
198
|
-
...data,
|
|
199
|
-
entities: {
|
|
200
|
-
...data.entities,
|
|
201
|
-
[resourceKey]: entity
|
|
202
|
-
},
|
|
203
|
-
isLoading: {
|
|
204
|
-
...data.isLoading,
|
|
205
|
-
[resourceKey]: false
|
|
206
|
-
},
|
|
207
|
-
status: {
|
|
208
|
-
...data.status,
|
|
209
|
-
[resourceKey]: "Success"
|
|
210
|
-
},
|
|
211
|
-
errors: nextErrors
|
|
212
|
-
};
|
|
213
|
-
this.update(key, {
|
|
214
|
-
data: nextData,
|
|
215
|
-
isLoading: (0, import_core2.isAnyKeyLoading)(nextData.isLoading),
|
|
216
|
-
status: void 0,
|
|
217
|
-
errors: void 0
|
|
218
|
-
});
|
|
1017
|
+
this.history.publish(
|
|
1018
|
+
createUpdateKeyedOneMessage(
|
|
1019
|
+
key,
|
|
1020
|
+
resourceKey,
|
|
1021
|
+
cloneValue(entity)
|
|
1022
|
+
)
|
|
1023
|
+
);
|
|
219
1024
|
}
|
|
220
1025
|
/**
|
|
221
1026
|
* Removes a single entity from a {@link KeyedResourceData} slot,
|
|
@@ -226,43 +1031,9 @@ var BaseStore = class {
|
|
|
226
1031
|
* @param resourceKey - The entity identifier to remove.
|
|
227
1032
|
*/
|
|
228
1033
|
clearKeyedOne(key, resourceKey) {
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
return;
|
|
232
|
-
}
|
|
233
|
-
const previousState = currentState();
|
|
234
|
-
const state = previousState;
|
|
235
|
-
if (!(0, import_core2.isKeyedResourceData)(state.data)) {
|
|
236
|
-
return;
|
|
237
|
-
}
|
|
238
|
-
const data = state.data;
|
|
239
|
-
const nextEntities = { ...data.entities };
|
|
240
|
-
delete nextEntities[resourceKey];
|
|
241
|
-
const nextIsLoading = { ...data.isLoading };
|
|
242
|
-
delete nextIsLoading[resourceKey];
|
|
243
|
-
const nextStatus = { ...data.status };
|
|
244
|
-
delete nextStatus[resourceKey];
|
|
245
|
-
const nextErrors = { ...data.errors };
|
|
246
|
-
delete nextErrors[resourceKey];
|
|
247
|
-
const nextData = {
|
|
248
|
-
...data,
|
|
249
|
-
entities: nextEntities,
|
|
250
|
-
isLoading: nextIsLoading,
|
|
251
|
-
status: nextStatus,
|
|
252
|
-
errors: nextErrors
|
|
253
|
-
};
|
|
254
|
-
const _typedKey = key;
|
|
255
|
-
currentState.update(
|
|
256
|
-
(prev) => ({
|
|
257
|
-
...prev,
|
|
258
|
-
data: nextData,
|
|
259
|
-
status: void 0,
|
|
260
|
-
isLoading: (0, import_core2.isAnyKeyLoading)(nextIsLoading),
|
|
261
|
-
errors: void 0
|
|
262
|
-
})
|
|
1034
|
+
this.history.publish(
|
|
1035
|
+
createClearKeyedOneMessage(key, resourceKey)
|
|
263
1036
|
);
|
|
264
|
-
const updatedState = currentState();
|
|
265
|
-
this.notifyUpdateHooks(key, updatedState, previousState);
|
|
266
1037
|
}
|
|
267
1038
|
/**
|
|
268
1039
|
* Marks a single entity within a keyed slot as loading.
|
|
@@ -273,47 +1044,9 @@ var BaseStore = class {
|
|
|
273
1044
|
* @param resourceKey - The entity identifier to mark as loading.
|
|
274
1045
|
*/
|
|
275
1046
|
startKeyedLoading(key, resourceKey) {
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
return;
|
|
279
|
-
}
|
|
280
|
-
const _typedKey = key;
|
|
281
|
-
const state = currentState();
|
|
282
|
-
if (!(0, import_core2.isKeyedResourceData)(state.data)) {
|
|
283
|
-
this.startLoading(key);
|
|
284
|
-
return;
|
|
285
|
-
}
|
|
286
|
-
const previousState = state;
|
|
287
|
-
const data = state.data;
|
|
288
|
-
const nextIsLoading = {
|
|
289
|
-
...data.isLoading,
|
|
290
|
-
[resourceKey]: true
|
|
291
|
-
};
|
|
292
|
-
const nextStatus = {
|
|
293
|
-
...data.status
|
|
294
|
-
};
|
|
295
|
-
delete nextStatus[resourceKey];
|
|
296
|
-
const nextErrors = {
|
|
297
|
-
...data.errors
|
|
298
|
-
};
|
|
299
|
-
delete nextErrors[resourceKey];
|
|
300
|
-
const nextData = {
|
|
301
|
-
...data,
|
|
302
|
-
isLoading: nextIsLoading,
|
|
303
|
-
status: nextStatus,
|
|
304
|
-
errors: nextErrors
|
|
305
|
-
};
|
|
306
|
-
currentState.update(
|
|
307
|
-
(previous) => ({
|
|
308
|
-
...previous,
|
|
309
|
-
data: nextData,
|
|
310
|
-
status: void 0,
|
|
311
|
-
isLoading: (0, import_core2.isAnyKeyLoading)(nextIsLoading),
|
|
312
|
-
errors: void 0
|
|
313
|
-
})
|
|
1047
|
+
this.history.publish(
|
|
1048
|
+
createStartKeyedLoadingMessage(key, resourceKey)
|
|
314
1049
|
);
|
|
315
|
-
const updatedState = currentState();
|
|
316
|
-
this.notifyUpdateHooks(key, updatedState, previousState);
|
|
317
1050
|
}
|
|
318
1051
|
notifyUpdateHooks(key, nextState, previousState) {
|
|
319
1052
|
const hooks = updateHooksMap.get(this);
|
|
@@ -321,25 +1054,34 @@ var BaseStore = class {
|
|
|
321
1054
|
if (!keyHooks) {
|
|
322
1055
|
return;
|
|
323
1056
|
}
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
1057
|
+
const errors = [];
|
|
1058
|
+
keyHooks.forEach((hook) => {
|
|
1059
|
+
try {
|
|
1060
|
+
hook(
|
|
1061
|
+
nextState,
|
|
1062
|
+
previousState
|
|
1063
|
+
);
|
|
1064
|
+
} catch (error) {
|
|
1065
|
+
errors.push(error);
|
|
1066
|
+
}
|
|
1067
|
+
});
|
|
1068
|
+
if (errors.length > 0) {
|
|
1069
|
+
queueMicrotask(() => {
|
|
1070
|
+
if (errors.length === 1) {
|
|
1071
|
+
throw errors[0];
|
|
1072
|
+
}
|
|
1073
|
+
throw new AggregateError(
|
|
1074
|
+
errors,
|
|
1075
|
+
`${errors.length} onUpdate hooks threw for key "${String(key)}"`
|
|
1076
|
+
);
|
|
1077
|
+
});
|
|
1078
|
+
}
|
|
330
1079
|
}
|
|
331
1080
|
initializeState() {
|
|
332
|
-
|
|
333
|
-
const _typedKey = key;
|
|
334
|
-
const initialState = {
|
|
335
|
-
data: void 0,
|
|
336
|
-
isLoading: false,
|
|
337
|
-
status: void 0,
|
|
338
|
-
errors: void 0
|
|
339
|
-
};
|
|
1081
|
+
this.storeKeys.forEach((key) => {
|
|
340
1082
|
this.signalsState.set(
|
|
341
|
-
|
|
342
|
-
(0,
|
|
1083
|
+
key,
|
|
1084
|
+
(0, import_core2.signal)(createDefaultState())
|
|
343
1085
|
);
|
|
344
1086
|
});
|
|
345
1087
|
}
|
|
@@ -347,19 +1089,58 @@ var BaseStore = class {
|
|
|
347
1089
|
|
|
348
1090
|
// src/lazy-store.ts
|
|
349
1091
|
var import_core3 = require("@angular/core");
|
|
350
|
-
var import_core4 = require("@flurryx/core");
|
|
351
|
-
function createDefaultState() {
|
|
352
|
-
return {
|
|
353
|
-
data: void 0,
|
|
354
|
-
isLoading: false,
|
|
355
|
-
status: void 0,
|
|
356
|
-
errors: void 0
|
|
357
|
-
};
|
|
358
|
-
}
|
|
359
1092
|
var LazyStore = class {
|
|
360
1093
|
signals = /* @__PURE__ */ new Map();
|
|
361
1094
|
hooks = /* @__PURE__ */ new Map();
|
|
362
|
-
|
|
1095
|
+
history;
|
|
1096
|
+
/** @inheritDoc */
|
|
1097
|
+
travelTo = (index) => this.history.travelTo(index);
|
|
1098
|
+
/** @inheritDoc */
|
|
1099
|
+
undo = () => this.history.undo();
|
|
1100
|
+
/** @inheritDoc */
|
|
1101
|
+
redo = () => this.history.redo();
|
|
1102
|
+
getMessages(key) {
|
|
1103
|
+
if (key === void 0) {
|
|
1104
|
+
return this.history.getMessages();
|
|
1105
|
+
}
|
|
1106
|
+
return this.history.getMessages(key);
|
|
1107
|
+
}
|
|
1108
|
+
/** @inheritDoc */
|
|
1109
|
+
getDeadLetters = () => this.history.getDeadLetters();
|
|
1110
|
+
/** @inheritDoc */
|
|
1111
|
+
replayDeadLetter = (id) => this.history.replayDeadLetter(id);
|
|
1112
|
+
/** @inheritDoc */
|
|
1113
|
+
replayDeadLetters = () => this.history.replayDeadLetters();
|
|
1114
|
+
/** @inheritDoc */
|
|
1115
|
+
getCurrentIndex = () => this.history.getCurrentIndex();
|
|
1116
|
+
replay(idOrIds) {
|
|
1117
|
+
if (Array.isArray(idOrIds)) {
|
|
1118
|
+
return this.history.replay(idOrIds);
|
|
1119
|
+
}
|
|
1120
|
+
return this.history.replay(idOrIds);
|
|
1121
|
+
}
|
|
1122
|
+
getHistory(key) {
|
|
1123
|
+
if (key === void 0) {
|
|
1124
|
+
return this.history.getHistory();
|
|
1125
|
+
}
|
|
1126
|
+
return this.history.getHistory(key);
|
|
1127
|
+
}
|
|
1128
|
+
constructor(options) {
|
|
1129
|
+
const consumer = createStoreMessageConsumer(
|
|
1130
|
+
{
|
|
1131
|
+
getOrCreate: (key) => this.getOrCreate(key),
|
|
1132
|
+
getAllKeys: () => this.signals.keys()
|
|
1133
|
+
},
|
|
1134
|
+
{
|
|
1135
|
+
notify: (key, next, prev) => this.notifyHooks(key, next, prev)
|
|
1136
|
+
}
|
|
1137
|
+
);
|
|
1138
|
+
this.history = createStoreHistory({
|
|
1139
|
+
captureSnapshot: () => consumer.createSnapshot(),
|
|
1140
|
+
applySnapshot: (snapshot) => consumer.applySnapshot(snapshot),
|
|
1141
|
+
applyMessage: (message) => consumer.applyMessage(message),
|
|
1142
|
+
channel: options?.channel
|
|
1143
|
+
});
|
|
363
1144
|
trackStore(this);
|
|
364
1145
|
}
|
|
365
1146
|
getOrCreate(key) {
|
|
@@ -370,138 +1151,55 @@ var LazyStore = class {
|
|
|
370
1151
|
}
|
|
371
1152
|
return sig;
|
|
372
1153
|
}
|
|
1154
|
+
/** @inheritDoc */
|
|
373
1155
|
get(key) {
|
|
374
1156
|
return this.getOrCreate(key);
|
|
375
1157
|
}
|
|
1158
|
+
/** @inheritDoc */
|
|
376
1159
|
update(key, newState) {
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
const nextState = sig();
|
|
381
|
-
this.notifyHooks(key, nextState, previousState);
|
|
1160
|
+
this.history.publish(
|
|
1161
|
+
createUpdateMessage(key, cloneValue(newState))
|
|
1162
|
+
);
|
|
382
1163
|
}
|
|
1164
|
+
/** @inheritDoc */
|
|
383
1165
|
clear(key) {
|
|
384
|
-
|
|
385
|
-
const previousState = sig();
|
|
386
|
-
sig.set(createDefaultState());
|
|
387
|
-
const nextState = sig();
|
|
388
|
-
this.notifyHooks(key, nextState, previousState);
|
|
1166
|
+
this.history.publish(createClearMessage(key));
|
|
389
1167
|
}
|
|
1168
|
+
/** @inheritDoc */
|
|
390
1169
|
clearAll() {
|
|
391
|
-
|
|
392
|
-
this.clear(key);
|
|
393
|
-
}
|
|
1170
|
+
this.history.publish(createClearAllMessage());
|
|
394
1171
|
}
|
|
1172
|
+
/** @inheritDoc */
|
|
395
1173
|
startLoading(key) {
|
|
396
|
-
|
|
397
|
-
sig.update(
|
|
398
|
-
(state) => ({
|
|
399
|
-
...state,
|
|
400
|
-
status: void 0,
|
|
401
|
-
isLoading: true,
|
|
402
|
-
errors: void 0
|
|
403
|
-
})
|
|
404
|
-
);
|
|
1174
|
+
this.history.publish(createStartLoadingMessage(key));
|
|
405
1175
|
}
|
|
1176
|
+
/** @inheritDoc */
|
|
406
1177
|
stopLoading(key) {
|
|
407
|
-
|
|
408
|
-
sig.update(
|
|
409
|
-
(state) => ({
|
|
410
|
-
...state,
|
|
411
|
-
isLoading: false
|
|
412
|
-
})
|
|
413
|
-
);
|
|
1178
|
+
this.history.publish(createStopLoadingMessage(key));
|
|
414
1179
|
}
|
|
1180
|
+
/** @inheritDoc */
|
|
415
1181
|
updateKeyedOne(key, resourceKey, entity) {
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
entities: { ...data.entities, [resourceKey]: entity },
|
|
424
|
-
isLoading: { ...data.isLoading, [resourceKey]: false },
|
|
425
|
-
status: { ...data.status, [resourceKey]: "Success" },
|
|
426
|
-
errors: nextErrors
|
|
427
|
-
};
|
|
428
|
-
this.update(key, {
|
|
429
|
-
data: nextData,
|
|
430
|
-
isLoading: (0, import_core4.isAnyKeyLoading)(nextData.isLoading),
|
|
431
|
-
status: void 0,
|
|
432
|
-
errors: void 0
|
|
433
|
-
});
|
|
1182
|
+
this.history.publish(
|
|
1183
|
+
createUpdateKeyedOneMessage(
|
|
1184
|
+
key,
|
|
1185
|
+
resourceKey,
|
|
1186
|
+
cloneValue(entity)
|
|
1187
|
+
)
|
|
1188
|
+
);
|
|
434
1189
|
}
|
|
1190
|
+
/** @inheritDoc */
|
|
435
1191
|
clearKeyedOne(key, resourceKey) {
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
if (!(0, import_core4.isKeyedResourceData)(state.data)) {
|
|
439
|
-
return;
|
|
440
|
-
}
|
|
441
|
-
const data = state.data;
|
|
442
|
-
const previousState = state;
|
|
443
|
-
const nextEntities = { ...data.entities };
|
|
444
|
-
delete nextEntities[resourceKey];
|
|
445
|
-
const nextIsLoading = { ...data.isLoading };
|
|
446
|
-
delete nextIsLoading[resourceKey];
|
|
447
|
-
const nextStatus = { ...data.status };
|
|
448
|
-
delete nextStatus[resourceKey];
|
|
449
|
-
const nextErrors = { ...data.errors };
|
|
450
|
-
delete nextErrors[resourceKey];
|
|
451
|
-
const nextData = {
|
|
452
|
-
...data,
|
|
453
|
-
entities: nextEntities,
|
|
454
|
-
isLoading: nextIsLoading,
|
|
455
|
-
status: nextStatus,
|
|
456
|
-
errors: nextErrors
|
|
457
|
-
};
|
|
458
|
-
sig.update(
|
|
459
|
-
(prev) => ({
|
|
460
|
-
...prev,
|
|
461
|
-
data: nextData,
|
|
462
|
-
status: void 0,
|
|
463
|
-
isLoading: (0, import_core4.isAnyKeyLoading)(nextIsLoading),
|
|
464
|
-
errors: void 0
|
|
465
|
-
})
|
|
1192
|
+
this.history.publish(
|
|
1193
|
+
createClearKeyedOneMessage(key, resourceKey)
|
|
466
1194
|
);
|
|
467
|
-
const updatedState = sig();
|
|
468
|
-
this.notifyHooks(key, updatedState, previousState);
|
|
469
1195
|
}
|
|
1196
|
+
/** @inheritDoc */
|
|
470
1197
|
startKeyedLoading(key, resourceKey) {
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
if (!(0, import_core4.isKeyedResourceData)(state.data)) {
|
|
474
|
-
this.startLoading(key);
|
|
475
|
-
return;
|
|
476
|
-
}
|
|
477
|
-
const previousState = state;
|
|
478
|
-
const data = state.data;
|
|
479
|
-
const nextIsLoading = {
|
|
480
|
-
...data.isLoading,
|
|
481
|
-
[resourceKey]: true
|
|
482
|
-
};
|
|
483
|
-
const nextStatus = { ...data.status };
|
|
484
|
-
delete nextStatus[resourceKey];
|
|
485
|
-
const nextErrors = { ...data.errors };
|
|
486
|
-
delete nextErrors[resourceKey];
|
|
487
|
-
const nextData = {
|
|
488
|
-
...data,
|
|
489
|
-
isLoading: nextIsLoading,
|
|
490
|
-
status: nextStatus,
|
|
491
|
-
errors: nextErrors
|
|
492
|
-
};
|
|
493
|
-
sig.update(
|
|
494
|
-
(previous) => ({
|
|
495
|
-
...previous,
|
|
496
|
-
data: nextData,
|
|
497
|
-
status: void 0,
|
|
498
|
-
isLoading: (0, import_core4.isAnyKeyLoading)(nextIsLoading),
|
|
499
|
-
errors: void 0
|
|
500
|
-
})
|
|
1198
|
+
this.history.publish(
|
|
1199
|
+
createStartKeyedLoadingMessage(key, resourceKey)
|
|
501
1200
|
);
|
|
502
|
-
const updatedState = sig();
|
|
503
|
-
this.notifyHooks(key, updatedState, previousState);
|
|
504
1201
|
}
|
|
1202
|
+
/** @inheritDoc */
|
|
505
1203
|
onUpdate(key, callback) {
|
|
506
1204
|
if (!this.hooks.has(key)) {
|
|
507
1205
|
this.hooks.set(key, []);
|
|
@@ -524,26 +1222,42 @@ var LazyStore = class {
|
|
|
524
1222
|
if (!keyHooks) {
|
|
525
1223
|
return;
|
|
526
1224
|
}
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
1225
|
+
const errors = [];
|
|
1226
|
+
keyHooks.forEach((hook) => {
|
|
1227
|
+
try {
|
|
1228
|
+
hook(
|
|
1229
|
+
nextState,
|
|
1230
|
+
previousState
|
|
1231
|
+
);
|
|
1232
|
+
} catch (error) {
|
|
1233
|
+
errors.push(error);
|
|
1234
|
+
}
|
|
1235
|
+
});
|
|
1236
|
+
if (errors.length > 0) {
|
|
1237
|
+
queueMicrotask(() => {
|
|
1238
|
+
if (errors.length === 1) {
|
|
1239
|
+
throw errors[0];
|
|
1240
|
+
}
|
|
1241
|
+
throw new AggregateError(
|
|
1242
|
+
errors,
|
|
1243
|
+
`${errors.length} onUpdate hooks threw for key "${String(key)}"`
|
|
1244
|
+
);
|
|
1245
|
+
});
|
|
1246
|
+
}
|
|
533
1247
|
}
|
|
534
1248
|
};
|
|
535
1249
|
|
|
536
1250
|
// src/store-builder.ts
|
|
537
|
-
var
|
|
1251
|
+
var import_core5 = require("@angular/core");
|
|
538
1252
|
|
|
539
1253
|
// src/dynamic-store.ts
|
|
540
1254
|
var DynamicStore = class extends BaseStore {
|
|
541
|
-
constructor(config) {
|
|
1255
|
+
constructor(config, options) {
|
|
542
1256
|
const identityEnum = Object.keys(config).reduce(
|
|
543
1257
|
(acc, key) => ({ ...acc, [key]: key }),
|
|
544
1258
|
{}
|
|
545
1259
|
);
|
|
546
|
-
super(identityEnum);
|
|
1260
|
+
super(identityEnum, options);
|
|
547
1261
|
}
|
|
548
1262
|
};
|
|
549
1263
|
|
|
@@ -564,12 +1278,12 @@ function mirrorKey(source, sourceKey, target, targetKeyOrOptions, options) {
|
|
|
564
1278
|
}
|
|
565
1279
|
|
|
566
1280
|
// src/collect-keyed.ts
|
|
567
|
-
var
|
|
1281
|
+
var import_core4 = require("@flurryx/core");
|
|
568
1282
|
function collectKeyed(source, sourceKey, target, targetKeyOrOptions, options) {
|
|
569
1283
|
const resolvedTargetKey = typeof targetKeyOrOptions === "string" ? targetKeyOrOptions : sourceKey;
|
|
570
1284
|
const resolvedOptions = typeof targetKeyOrOptions === "object" ? targetKeyOrOptions : options;
|
|
571
1285
|
target.update(resolvedTargetKey, {
|
|
572
|
-
data: (0,
|
|
1286
|
+
data: (0, import_core4.createKeyedResourceData)()
|
|
573
1287
|
});
|
|
574
1288
|
let previousId;
|
|
575
1289
|
const cleanup = source.onUpdate(sourceKey, (state) => {
|
|
@@ -600,7 +1314,7 @@ function collectKeyed(source, sourceKey, target, targetKeyOrOptions, options) {
|
|
|
600
1314
|
};
|
|
601
1315
|
target.update(resolvedTargetKey, {
|
|
602
1316
|
data: updatedKeyed,
|
|
603
|
-
isLoading: (0,
|
|
1317
|
+
isLoading: (0, import_core4.isAnyKeyLoading)(newIsLoading),
|
|
604
1318
|
status: "Success"
|
|
605
1319
|
});
|
|
606
1320
|
previousId = currentId;
|
|
@@ -622,7 +1336,7 @@ function collectKeyed(source, sourceKey, target, targetKeyOrOptions, options) {
|
|
|
622
1336
|
};
|
|
623
1337
|
target.update(resolvedTargetKey, {
|
|
624
1338
|
data: updatedKeyed,
|
|
625
|
-
isLoading: (0,
|
|
1339
|
+
isLoading: (0, import_core4.isAnyKeyLoading)(newIsLoading)
|
|
626
1340
|
});
|
|
627
1341
|
previousId = currentId;
|
|
628
1342
|
} else if (resourceState.data === void 0 && previousId !== void 0) {
|
|
@@ -638,7 +1352,7 @@ function collectKeyed(source, sourceKey, target, targetKeyOrOptions, options) {
|
|
|
638
1352
|
};
|
|
639
1353
|
target.update(resolvedTargetKey, {
|
|
640
1354
|
data: updatedKeyed,
|
|
641
|
-
isLoading: (0,
|
|
1355
|
+
isLoading: (0, import_core4.isAnyKeyLoading)(remainingLoading)
|
|
642
1356
|
});
|
|
643
1357
|
previousId = void 0;
|
|
644
1358
|
} else if (resourceState.isLoading && currentId !== void 0) {
|
|
@@ -670,7 +1384,7 @@ function resource() {
|
|
|
670
1384
|
// src/store-builder.ts
|
|
671
1385
|
function wireMirrors(store, mirrors) {
|
|
672
1386
|
for (const def of mirrors) {
|
|
673
|
-
const sourceStore = (0,
|
|
1387
|
+
const sourceStore = (0, import_core5.inject)(def.sourceToken);
|
|
674
1388
|
mirrorKey(
|
|
675
1389
|
sourceStore,
|
|
676
1390
|
def.sourceKey,
|
|
@@ -678,11 +1392,10 @@ function wireMirrors(store, mirrors) {
|
|
|
678
1392
|
def.targetKey
|
|
679
1393
|
);
|
|
680
1394
|
}
|
|
681
|
-
return store;
|
|
682
1395
|
}
|
|
683
1396
|
function wireMirrorKeyed(store, defs) {
|
|
684
1397
|
for (const def of defs) {
|
|
685
|
-
const sourceStore = (0,
|
|
1398
|
+
const sourceStore = (0, import_core5.inject)(def.sourceToken);
|
|
686
1399
|
collectKeyed(
|
|
687
1400
|
sourceStore,
|
|
688
1401
|
def.sourceKey,
|
|
@@ -693,7 +1406,6 @@ function wireMirrorKeyed(store, defs) {
|
|
|
693
1406
|
}
|
|
694
1407
|
);
|
|
695
1408
|
}
|
|
696
|
-
return store;
|
|
697
1409
|
}
|
|
698
1410
|
var MIRROR_SELF_SAME_KEY_ERROR = "mirrorSelf source and target keys must be different";
|
|
699
1411
|
function wireSelfMirrors(store, defs) {
|
|
@@ -708,7 +1420,6 @@ function wireSelfMirrors(store, defs) {
|
|
|
708
1420
|
def.targetKey
|
|
709
1421
|
);
|
|
710
1422
|
}
|
|
711
|
-
return store;
|
|
712
1423
|
}
|
|
713
1424
|
function createBuilder(accum, mirrors = [], mirrorKeyedDefs = [], selfMirrors = []) {
|
|
714
1425
|
return {
|
|
@@ -765,11 +1476,11 @@ function createBuilder(accum, mirrors = [], mirrorKeyedDefs = [], selfMirrors =
|
|
|
765
1476
|
selfMirrors
|
|
766
1477
|
);
|
|
767
1478
|
},
|
|
768
|
-
build() {
|
|
769
|
-
return new
|
|
1479
|
+
build(options) {
|
|
1480
|
+
return new import_core5.InjectionToken("FlurryxStore", {
|
|
770
1481
|
providedIn: "root",
|
|
771
1482
|
factory: () => {
|
|
772
|
-
const store = new DynamicStore(accum);
|
|
1483
|
+
const store = new DynamicStore(accum, options);
|
|
773
1484
|
wireMirrors(store, mirrors);
|
|
774
1485
|
wireMirrorKeyed(store, mirrorKeyedDefs);
|
|
775
1486
|
wireSelfMirrors(store, selfMirrors);
|
|
@@ -840,11 +1551,11 @@ function createConstrainedBuilder(_enumObj, accum, mirrors = [], mirrorKeyedDefs
|
|
|
840
1551
|
selfMirrors
|
|
841
1552
|
);
|
|
842
1553
|
},
|
|
843
|
-
build() {
|
|
844
|
-
return new
|
|
1554
|
+
build(options) {
|
|
1555
|
+
return new import_core5.InjectionToken("FlurryxStore", {
|
|
845
1556
|
providedIn: "root",
|
|
846
1557
|
factory: () => {
|
|
847
|
-
const store = new DynamicStore(accum);
|
|
1558
|
+
const store = new DynamicStore(accum, options);
|
|
848
1559
|
wireMirrors(store, mirrors);
|
|
849
1560
|
wireMirrorKeyed(store, mirrorKeyedDefs);
|
|
850
1561
|
wireSelfMirrors(store, selfMirrors);
|
|
@@ -891,11 +1602,11 @@ function createInterfaceBuilder(mirrors = [], mirrorKeyedDefs = [], selfMirrors
|
|
|
891
1602
|
selfMirrors
|
|
892
1603
|
);
|
|
893
1604
|
},
|
|
894
|
-
build() {
|
|
895
|
-
return new
|
|
1605
|
+
build(options) {
|
|
1606
|
+
return new import_core5.InjectionToken("FlurryxStore", {
|
|
896
1607
|
providedIn: "root",
|
|
897
1608
|
factory: () => {
|
|
898
|
-
const store = new LazyStore();
|
|
1609
|
+
const store = new LazyStore(options);
|
|
899
1610
|
wireMirrors(store, mirrors);
|
|
900
1611
|
wireMirrorKeyed(store, mirrorKeyedDefs);
|
|
901
1612
|
wireSelfMirrors(store, selfMirrors);
|
|
@@ -921,7 +1632,14 @@ function createStoreFor(enumObj) {
|
|
|
921
1632
|
LazyStore,
|
|
922
1633
|
Store,
|
|
923
1634
|
clearAllStores,
|
|
1635
|
+
cloneValue,
|
|
924
1636
|
collectKeyed,
|
|
1637
|
+
createCompositeStoreMessageChannel,
|
|
1638
|
+
createInMemoryStoreMessageChannel,
|
|
1639
|
+
createLocalStorageStoreMessageChannel,
|
|
1640
|
+
createSessionStorageStoreMessageChannel,
|
|
1641
|
+
createSnapshotRestorePatch,
|
|
1642
|
+
createStorageStoreMessageChannel,
|
|
925
1643
|
mirrorKey
|
|
926
1644
|
});
|
|
927
1645
|
//# sourceMappingURL=index.cjs.map
|