@hf-chimera/store 0.1.0 → 0.2.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.
Files changed (80) hide show
  1. package/README.md +171 -360
  2. package/dist/defaults-CDnbUToo.cjs +175 -0
  3. package/dist/defaults-CDnbUToo.cjs.map +1 -0
  4. package/dist/defaults-DkrKTPXY.mjs +91 -0
  5. package/dist/defaults-DkrKTPXY.mjs.map +1 -0
  6. package/dist/defaults.cjs +3 -14
  7. package/dist/defaults.d.cts +16 -42
  8. package/dist/defaults.d.cts.map +1 -1
  9. package/dist/defaults.d.mts +33 -0
  10. package/dist/defaults.d.mts.map +1 -0
  11. package/dist/defaults.mjs +3 -0
  12. package/dist/index.cjs +1709 -23
  13. package/dist/index.cjs.map +1 -0
  14. package/dist/index.d.cts +634 -2
  15. package/dist/index.d.cts.map +1 -0
  16. package/dist/index.d.mts +634 -0
  17. package/dist/index.d.mts.map +1 -0
  18. package/dist/{src-C74sq0jQ.js → index.mjs} +252 -246
  19. package/dist/index.mjs.map +1 -0
  20. package/dist/types-CNGIuRUw.d.mts +117 -0
  21. package/dist/types-CNGIuRUw.d.mts.map +1 -0
  22. package/dist/types-CuI5yXiY.d.cts +117 -0
  23. package/dist/types-CuI5yXiY.d.cts.map +1 -0
  24. package/package.json +10 -51
  25. package/.changeset/README.md +0 -8
  26. package/CHANGELOG.md +0 -98
  27. package/dist/adapters/react.cjs +0 -70
  28. package/dist/adapters/react.cjs.map +0 -1
  29. package/dist/adapters/react.d.cts +0 -15
  30. package/dist/adapters/react.d.cts.map +0 -1
  31. package/dist/adapters/react.d.ts +0 -15
  32. package/dist/adapters/react.d.ts.map +0 -1
  33. package/dist/adapters/react.js +0 -69
  34. package/dist/adapters/react.js.map +0 -1
  35. package/dist/adapters/vue.cjs +0 -92
  36. package/dist/adapters/vue.cjs.map +0 -1
  37. package/dist/adapters/vue.d.cts +0 -19
  38. package/dist/adapters/vue.d.cts.map +0 -1
  39. package/dist/adapters/vue.d.ts +0 -19
  40. package/dist/adapters/vue.d.ts.map +0 -1
  41. package/dist/adapters/vue.js +0 -91
  42. package/dist/adapters/vue.js.map +0 -1
  43. package/dist/defaults-C48gY1ow.cjs +0 -372
  44. package/dist/defaults-C48gY1ow.cjs.map +0 -1
  45. package/dist/defaults-CLUQg2zK.js +0 -210
  46. package/dist/defaults-CLUQg2zK.js.map +0 -1
  47. package/dist/defaults.cjs.map +0 -1
  48. package/dist/defaults.d.ts +0 -59
  49. package/dist/defaults.d.ts.map +0 -1
  50. package/dist/defaults.js +0 -13
  51. package/dist/defaults.js.map +0 -1
  52. package/dist/index-BuYMaiND.d.ts +0 -22
  53. package/dist/index-BuYMaiND.d.ts.map +0 -1
  54. package/dist/index-C45y61aH.d.ts +0 -821
  55. package/dist/index-C45y61aH.d.ts.map +0 -1
  56. package/dist/index-DP6-nR2O.d.cts +0 -821
  57. package/dist/index-DP6-nR2O.d.cts.map +0 -1
  58. package/dist/index-FQNcJwA7.d.cts +0 -22
  59. package/dist/index-FQNcJwA7.d.cts.map +0 -1
  60. package/dist/index.d.ts +0 -2
  61. package/dist/index.js +0 -4
  62. package/dist/params-B-wurzdZ.d.ts +0 -8
  63. package/dist/params-B-wurzdZ.d.ts.map +0 -1
  64. package/dist/params-C5dnCvJr.cjs +0 -47
  65. package/dist/params-C5dnCvJr.cjs.map +0 -1
  66. package/dist/params-DmOyCS2B.js +0 -13
  67. package/dist/params-DmOyCS2B.js.map +0 -1
  68. package/dist/params-uxNE-e4a.d.cts +0 -8
  69. package/dist/params-uxNE-e4a.d.cts.map +0 -1
  70. package/dist/qb-D6vPK6P0.cjs +0 -50
  71. package/dist/qb-D6vPK6P0.cjs.map +0 -1
  72. package/dist/qb-pchs-vdM.js +0 -45
  73. package/dist/qb-pchs-vdM.js.map +0 -1
  74. package/dist/qb.cjs +0 -5
  75. package/dist/qb.d.cts +0 -3
  76. package/dist/qb.d.ts +0 -3
  77. package/dist/qb.js +0 -5
  78. package/dist/src-C74sq0jQ.js.map +0 -1
  79. package/dist/src-YxpDmKvq.cjs +0 -1771
  80. package/dist/src-YxpDmKvq.cjs.map +0 -1
package/dist/index.cjs CHANGED
@@ -1,29 +1,1715 @@
1
- const require_defaults = require('./defaults-C48gY1ow.cjs');
2
- const require_src = require('./src-YxpDmKvq.cjs');
1
+ const require_defaults = require('./defaults-CDnbUToo.cjs');
3
2
 
4
- exports.ChimeraCollectionQuery = require_src.ChimeraCollectionQuery;
3
+ //#region ../../src/shared/shared.ts
4
+ const deepObjectAssign = (dst, srcObj, visited = /* @__PURE__ */ new WeakSet()) => {
5
+ for (const { 0: key, 1: srcVal } of Object.entries(srcObj)) {
6
+ if (srcVal === null || typeof srcVal !== "object" || Array.isArray(srcVal)) {
7
+ dst[key] = srcVal;
8
+ continue;
9
+ }
10
+ if (visited.has(srcVal)) {
11
+ dst[key] = srcVal;
12
+ continue;
13
+ }
14
+ visited.add(srcVal);
15
+ const destVal = dst[key];
16
+ dst[key] = destVal === null || typeof destVal !== "object" || Array.isArray(destVal) ? {} : destVal;
17
+ deepObjectAssign(dst[key], srcVal, visited);
18
+ visited.delete(srcVal);
19
+ }
20
+ return dst;
21
+ };
22
+ const deepObjectFreeze = (obj, frozenObjects = /* @__PURE__ */ new WeakSet()) => {
23
+ if (obj === null || typeof obj !== "object" || Object.isFrozen(obj) || frozenObjects.has(obj)) return obj;
24
+ frozenObjects.add(obj);
25
+ for (const value of Object.values(obj)) if (value && typeof value === "object") deepObjectFreeze(value, frozenObjects);
26
+ return Object.freeze(obj);
27
+ };
28
+ const TypedArray = Object.getPrototypeOf(Int8Array);
29
+ const deepObjectClone = (value, refs) => {
30
+ if (value === null) return null;
31
+ if (value === void 0) return void 0;
32
+ if (typeof value !== "object") return value;
33
+ if (refs) {
34
+ const ref = refs.get(value);
35
+ if (ref !== void 0) return ref;
36
+ }
37
+ if (value.constructor === Object) {
38
+ const keys$1 = Object.keys(value).concat(Object.getOwnPropertySymbols(value));
39
+ const length$1 = keys$1.length;
40
+ const clone$1 = {};
41
+ refs ??= /* @__PURE__ */ new Map();
42
+ refs.set(value, clone$1);
43
+ for (let i = 0; i < length$1; i++) clone$1[keys$1[i]] = deepObjectClone(value[keys$1[i]], refs);
44
+ return clone$1;
45
+ }
46
+ if (Array.isArray(value)) {
47
+ const length$1 = value.length;
48
+ const clone$1 = new Array(length$1);
49
+ refs ??= /* @__PURE__ */ new Map();
50
+ refs.set(value, clone$1);
51
+ for (let i = 0; i < length$1; i++) clone$1[i] = deepObjectClone(value[i], refs);
52
+ return clone$1;
53
+ }
54
+ if (value instanceof Date) return new value.constructor(value.valueOf());
55
+ if (value instanceof RegExp) return value.constructor;
56
+ if (value instanceof Map) {
57
+ const clone$1 = new value.constructor();
58
+ refs ??= /* @__PURE__ */ new Map();
59
+ refs.set(value, clone$1);
60
+ for (const entry of value.entries()) clone$1.set(entry[0], deepObjectClone(entry[1], refs));
61
+ return clone$1;
62
+ }
63
+ if (value instanceof Set) {
64
+ const clone$1 = new value.constructor();
65
+ refs ??= /* @__PURE__ */ new Map();
66
+ refs.set(value, clone$1);
67
+ for (const entry of value.values()) clone$1.add(deepObjectClone(entry, refs));
68
+ return clone$1;
69
+ }
70
+ if (value instanceof Error) {
71
+ const clone$1 = new value.constructor(value.message);
72
+ const keys$1 = Object.keys(value).concat(Object.getOwnPropertySymbols(value));
73
+ const length$1 = keys$1.length;
74
+ refs ??= /* @__PURE__ */ new Map();
75
+ refs.set(value, clone$1);
76
+ for (let i = 0; i < length$1; i++) clone$1[keys$1[i]] = deepObjectClone(value[keys$1[i]], refs);
77
+ return clone$1;
78
+ }
79
+ if (value instanceof ArrayBuffer) return value.slice();
80
+ if (value instanceof TypedArray) return value.slice();
81
+ if (value instanceof DataView) return new DataView(value.buffer.slice());
82
+ if (value instanceof WeakMap) return value;
83
+ if (value instanceof WeakSet) return value;
84
+ const clone = Object.create(value.constructor.prototype);
85
+ const keys = Object.keys(value).concat(Object.getOwnPropertySymbols(value));
86
+ const length = keys.length;
87
+ refs ??= /* @__PURE__ */ new Map();
88
+ refs.set(value, clone);
89
+ for (let i = 0; i < length; i++) clone[keys[i]] = deepObjectClone(value[keys[i]], refs);
90
+ return clone;
91
+ };
92
+ const compilePropertyGetter = ({ get }) => typeof get === "function" ? get : (e) => e[get];
93
+ const simplifyPropertyGetter = ({ key }) => key;
94
+ const makeCancellablePromise = (promise, controller = new AbortController()) => {
95
+ const signal = controller.signal;
96
+ const newPromise = promise.then((v) => signal.aborted ? new Promise(() => null) : v, (err) => {
97
+ return signal.aborted ? new Promise(() => null) : Promise.reject(err);
98
+ });
99
+ newPromise.cancel = () => controller.abort();
100
+ newPromise.cancelled = (cb) => signal.aborted ? queueMicrotask(cb) : signal.addEventListener("abort", cb);
101
+ if ("cancelled" in promise) {
102
+ promise.cancelled(() => newPromise.cancel());
103
+ controller.signal.addEventListener("abort", () => promise.cancel());
104
+ }
105
+ return newPromise;
106
+ };
107
+
108
+ //#endregion
109
+ //#region ../../src/filter/constants.ts
110
+ const ChimeraOperatorSymbol = Symbol("ChimeraOperatorSymbol");
111
+ const ChimeraConjunctionSymbol = Symbol("ChimeraConjunctionSymbol");
112
+
113
+ //#endregion
114
+ //#region ../../src/filter/errors.ts
115
+ var ChimeraFilterError = class extends require_defaults.ChimeraError {};
116
+ var ChimeraFilterOperatorError = class extends ChimeraFilterError {
117
+ constructor(operator, message) {
118
+ super(`Operator "${operator}" ${message}`);
119
+ }
120
+ };
121
+ var ChimeraFilterOperatorNotFoundError = class extends ChimeraFilterOperatorError {
122
+ constructor(operator) {
123
+ super(operator, "not found");
124
+ }
125
+ };
126
+
127
+ //#endregion
128
+ //#region ../../src/filter/filter.ts
129
+ const filterConjunctions = {
130
+ and: (operations) => operations.every((op) => op()),
131
+ not: (operations) => !operations.every((op) => op()),
132
+ or: (operations) => operations.some((op) => op())
133
+ };
134
+ const compileOperator = (config, { op, value, test }) => {
135
+ const operatorFunc = config.operators[op];
136
+ if (!operatorFunc) throw new ChimeraFilterOperatorNotFoundError(op);
137
+ const getter = compilePropertyGetter(value);
138
+ return (entity) => operatorFunc(getter(entity), test);
139
+ };
140
+ const compileConjunction = (config, { kind, operations }) => {
141
+ const conjunction = filterConjunctions[kind];
142
+ const compiledOperations = operations.map((operation) => {
143
+ switch (operation.type) {
144
+ case ChimeraOperatorSymbol: return compileOperator(config, operation);
145
+ case ChimeraConjunctionSymbol: return compileConjunction(config, operation);
146
+ default: throw new require_defaults.ChimeraInternalError(`Invalid filter operation ${operation.type}`);
147
+ }
148
+ }).filter(Boolean);
149
+ return (entity) => conjunction(compiledOperations.map((op) => () => op(entity)));
150
+ };
151
+ const simplifyOperator = ({ op, value, test }) => ({
152
+ key: simplifyPropertyGetter(value),
153
+ op,
154
+ test,
155
+ type: ChimeraOperatorSymbol
156
+ });
157
+ const compareSimplifiedOperator = (a, b) => a.key.localeCompare(b.key) || a.op.localeCompare(b.op) || JSON.stringify(a.test).localeCompare(JSON.stringify(b.test));
158
+ const compareSimplifiedOperation = (a, b) => {
159
+ if (a.type !== b.type) return a.type === ChimeraOperatorSymbol ? -1 : 1;
160
+ if (a.type === ChimeraOperatorSymbol && b.type === ChimeraOperatorSymbol) return compareSimplifiedOperator(a, b);
161
+ if (a.type === ChimeraConjunctionSymbol && b.type === ChimeraConjunctionSymbol) return compareSimplifiedConjunction(a, b);
162
+ return 0;
163
+ };
164
+ const compareSimplifiedConjunction = (a, b) => {
165
+ const kindCompare = a.kind.localeCompare(b.kind);
166
+ if (kindCompare !== 0) return kindCompare;
167
+ const aOps = a.operations;
168
+ const bOps = b.operations;
169
+ const minLength = Math.min(aOps.length, bOps.length);
170
+ for (let i = 0; i < minLength; i++) {
171
+ const aOp = aOps[i];
172
+ const bOp = bOps[i];
173
+ if (aOp && bOp) {
174
+ const compare = compareSimplifiedOperation(aOp, bOp);
175
+ if (compare !== 0) return compare;
176
+ }
177
+ }
178
+ return aOps.length - bOps.length;
179
+ };
180
+ const simplifyConjunction = ({ kind, operations }) => {
181
+ return {
182
+ kind,
183
+ operations: operations.map((op) => {
184
+ switch (op.type) {
185
+ case ChimeraOperatorSymbol: return simplifyOperator(op);
186
+ case ChimeraConjunctionSymbol: return simplifyConjunction(op);
187
+ default: throw new require_defaults.ChimeraInternalError(`Invalid filter operation ${op.type}`);
188
+ }
189
+ }).filter(Boolean).sort((a, b) => compareSimplifiedOperation(a, b)),
190
+ type: ChimeraConjunctionSymbol
191
+ };
192
+ };
193
+ const chimeraCreateOperator = (op, value, test) => ({
194
+ op,
195
+ test,
196
+ type: ChimeraOperatorSymbol,
197
+ value: typeof value === "string" ? {
198
+ get: value,
199
+ key: value
200
+ } : value
201
+ });
202
+ const chimeraCreateConjunction = (kind, operations) => ({
203
+ kind,
204
+ operations,
205
+ type: ChimeraConjunctionSymbol
206
+ });
207
+ const chimeraCreateNot = (operation) => ({
208
+ kind: "not",
209
+ operations: [operation],
210
+ type: ChimeraConjunctionSymbol
211
+ });
212
+ function chimeraIsConjunction(item) {
213
+ return item.type === ChimeraConjunctionSymbol;
214
+ }
215
+ function chimeraIsOperator(item) {
216
+ return item.type === ChimeraOperatorSymbol;
217
+ }
218
+ const compileFilter = (config, descriptor) => descriptor ? compileConjunction(config, descriptor) : () => true;
219
+ const simplifyFilter = (descriptor) => descriptor ? simplifyConjunction(descriptor) : null;
220
+ const isOperationSubset = (candidateOp, targetOp, getOperatorKey) => {
221
+ if (candidateOp.type !== targetOp.type) return false;
222
+ if (candidateOp.type === ChimeraOperatorSymbol && targetOp.type === ChimeraOperatorSymbol) return candidateOp.key === targetOp.key && candidateOp.op === targetOp.op && getOperatorKey(candidateOp) === getOperatorKey(targetOp);
223
+ if (candidateOp.type === ChimeraConjunctionSymbol && targetOp.type === ChimeraConjunctionSymbol) return isConjunctionSubset(candidateOp, targetOp, getOperatorKey);
224
+ return false;
225
+ };
226
+ const isConjunctionSubset = (candidate, target, getOperatorKey) => {
227
+ if (candidate.kind !== target.kind) return false;
228
+ switch (candidate.kind) {
229
+ case "and":
230
+ case "not": return candidate.operations.every((candidateOp) => target.operations.some((targetOp) => isOperationSubset(candidateOp, targetOp, getOperatorKey)));
231
+ case "or": return target.operations.every((targetOp) => candidate.operations.some((candidateOp) => isOperationSubset(candidateOp, targetOp, getOperatorKey)));
232
+ }
233
+ };
234
+ const isFilterSubset = (candidate, target, getOperatorKey) => {
235
+ if (candidate === null) return true;
236
+ if (target === null) return false;
237
+ return isConjunctionSubset(candidate, target, getOperatorKey);
238
+ };
239
+
240
+ //#endregion
241
+ //#region ../../src/order/types.ts
242
+ let ChimeraOrderNulls = /* @__PURE__ */ function(ChimeraOrderNulls$1) {
243
+ ChimeraOrderNulls$1["First"] = "first";
244
+ ChimeraOrderNulls$1["Last"] = "last";
245
+ return ChimeraOrderNulls$1;
246
+ }({});
247
+
248
+ //#endregion
249
+ //#region ../../src/order/order.ts
250
+ const compileOrderDescriptor = ({ key, desc, nulls }) => ({
251
+ desc,
252
+ get: compilePropertyGetter(key),
253
+ nulls
254
+ });
255
+ const chimeraCreateOrderBy = (key, desc = false, nulls = ChimeraOrderNulls.Last) => ({
256
+ desc,
257
+ key: typeof key === "string" ? {
258
+ get: key,
259
+ key
260
+ } : key,
261
+ nulls
262
+ });
263
+ const nullsComparator = (a, b, nulls) => {
264
+ return a == b ? 0 : (a == null ? -1 : 1) * (nulls === ChimeraOrderNulls.First ? 1 : -1);
265
+ };
266
+ const buildComparator = (comparator, orderBy) => {
267
+ if (!orderBy) return () => 0;
268
+ const compiledPriority = orderBy.map((ob) => compileOrderDescriptor(ob));
269
+ return (a, b) => {
270
+ let result = 0;
271
+ for (const descriptor of compiledPriority) {
272
+ const vA = descriptor.get(a);
273
+ const vB = descriptor.get(b);
274
+ if (vA == null || vB == null) {
275
+ result = nullsComparator(vA, vB, descriptor.nulls);
276
+ if (result) break;
277
+ continue;
278
+ }
279
+ result = comparator(descriptor.get(a), descriptor.get(b));
280
+ descriptor.desc && (result *= -1);
281
+ if (result) break;
282
+ }
283
+ return result;
284
+ };
285
+ };
286
+ const simplifyOrderBy = (orderBy) => orderBy ? orderBy.map((ob) => ({
287
+ desc: ob.desc,
288
+ field: ob.key.key,
289
+ nulls: ob.nulls
290
+ })) : null;
291
+
292
+ //#endregion
293
+ //#region ../../src/shared/ChimeraEventEmitter/ChimeraEventEmitter.ts
294
+ var Events = function Events$1() {};
295
+ Events.prototype = Object.create(null);
296
+ var ChimeraEventEmitter = class {
297
+ _events;
298
+ _eventsCount;
299
+ constructor() {
300
+ this._events = new Events();
301
+ this._eventsCount = 0;
302
+ }
303
+ #addListener(event, fn, once) {
304
+ var listener = {
305
+ fn,
306
+ once
307
+ };
308
+ if (!this._events[event]) {
309
+ this._events[event] = listener;
310
+ this._eventsCount++;
311
+ } else if (!this._events[event].fn) this._events[event].push(listener);
312
+ else this._events[event] = [this._events[event], listener];
313
+ return this;
314
+ }
315
+ #clearEvent(event) {
316
+ if (--this._eventsCount === 0) this._events = new Events();
317
+ else delete this._events[event];
318
+ }
319
+ eventNames() {
320
+ return Object.keys(this._events);
321
+ }
322
+ listeners(event) {
323
+ var handlers = this._events[event];
324
+ if (!handlers) return [];
325
+ if (handlers.fn) return [handlers.fn];
326
+ for (var i = 0, l = handlers.length, ee = new Array(l); i < l; i++) ee[i] = handlers[i].fn;
327
+ return ee;
328
+ }
329
+ listenerCount(event) {
330
+ var listeners = this._events[event];
331
+ if (!listeners) return 0;
332
+ if (listeners.fn) return 1;
333
+ return listeners.length;
334
+ }
335
+ removeListener(event, fn, once) {
336
+ if (!this._events[event]) return this;
337
+ if (!fn) {
338
+ this.#clearEvent(event);
339
+ return this;
340
+ }
341
+ var listeners = this._events[event];
342
+ if (listeners.fn) {
343
+ if (listeners.fn === fn && (!once || listeners.once)) this.#clearEvent(event);
344
+ } else {
345
+ for (var i = 0, events = [], length = listeners.length; i < length; i++) if (listeners[i].fn !== fn || once && !listeners[i].once) events.push(listeners[i]);
346
+ if (events.length) this._events[event] = events.length === 1 ? events[0] : events;
347
+ else this.#clearEvent(event);
348
+ }
349
+ return this;
350
+ }
351
+ emit(event, arg) {
352
+ if (!this._events[event]) return false;
353
+ var listeners = this._events[event];
354
+ if (listeners.fn) {
355
+ if (listeners.once) this.removeListener(event, listeners.fn, true);
356
+ listeners.fn.call(this, arg);
357
+ } else for (var i = 0, length = listeners.length; i < length; i++) {
358
+ if (listeners[i].once) this.removeListener(event, listeners[i].fn, true);
359
+ listeners[i].fn.call(this, arg);
360
+ }
361
+ return true;
362
+ }
363
+ on(event, fn) {
364
+ return this.#addListener(event, fn, false);
365
+ }
366
+ once(event, fn) {
367
+ return this.#addListener(event, fn, true);
368
+ }
369
+ removeAllListeners(event) {
370
+ if (event) {
371
+ if (this._events[event]) this.#clearEvent(event);
372
+ } else {
373
+ this._events = new Events();
374
+ this._eventsCount = 0;
375
+ }
376
+ return this;
377
+ }
378
+ off = this.removeListener;
379
+ addListener = this.on;
380
+ };
381
+
382
+ //#endregion
383
+ //#region ../../src/query/types.ts
384
+ let ChimeraQueryFetchingState = /* @__PURE__ */ function(ChimeraQueryFetchingState$1) {
385
+ /** Query just initialized. */
386
+ ChimeraQueryFetchingState$1["Initialized"] = "initialized";
387
+ /** Not used yet. */
388
+ ChimeraQueryFetchingState$1["Scheduled"] = "scheduled";
389
+ /** Fetching in progress. */
390
+ ChimeraQueryFetchingState$1["Fetching"] = "fetching";
391
+ /** Creating in progress */
392
+ ChimeraQueryFetchingState$1["Creating"] = "creating";
393
+ /** Updating in progress. */
394
+ ChimeraQueryFetchingState$1["Updating"] = "updating";
395
+ /** Deleting in progress. */
396
+ ChimeraQueryFetchingState$1["Deleting"] = "deleting";
397
+ /** Fetch requested after reaching the Fetched, Errored, or Prefetched states. */
398
+ ChimeraQueryFetchingState$1["Refetching"] = "refetching";
399
+ /** Data retrieved from existing queries without initiating a fetch. */
400
+ ChimeraQueryFetchingState$1["Prefetched"] = "prefetched";
401
+ /** Fetch ended successfully; data is ready for use. */
402
+ ChimeraQueryFetchingState$1["Fetched"] = "fetched";
403
+ /** Fetch ended with an error; no data is available. */
404
+ ChimeraQueryFetchingState$1["Errored"] = "errored";
405
+ /** Refetch ended with an error, but old data is still available. */
406
+ ChimeraQueryFetchingState$1["ReErrored"] = "reErrored";
407
+ /**
408
+ * Only for the item query, data is deleted, but the local value is still present,
409
+ * no longer allows updates, but `refetch` still works (in case of strange errors, allows recovering state)
410
+ */
411
+ ChimeraQueryFetchingState$1["Deleted"] = "deleted";
412
+ /** Only for the item query, data was actualized from an external event */
413
+ ChimeraQueryFetchingState$1["Actualized"] = "actualized";
414
+ return ChimeraQueryFetchingState$1;
415
+ }({});
416
+
417
+ //#endregion
418
+ //#region ../../src/query/constants.ts
419
+ const ChimeraGetParamsSym = Symbol("ChimeraGetParamsSym");
420
+ const ChimeraSetOneSym = Symbol("ChimeraSetOneSym");
421
+ const ChimeraSetManySym = Symbol("ChimeraSetManySym");
422
+ const ChimeraDeleteOneSym = Symbol("ChimeraDeleteOneSym");
423
+ const ChimeraDeleteManySym = Symbol("ChimeraDeleteManySym");
424
+ const ChimeraUpdateMixedSym = Symbol("ChimeraUpdateMixedSym");
425
+ const IN_PROGRESS_STATES = [
426
+ ChimeraQueryFetchingState.Scheduled,
427
+ ChimeraQueryFetchingState.Creating,
428
+ ChimeraQueryFetchingState.Fetching,
429
+ ChimeraQueryFetchingState.Refetching,
430
+ ChimeraQueryFetchingState.Updating,
431
+ ChimeraQueryFetchingState.Deleting
432
+ ];
433
+
434
+ //#endregion
435
+ //#region ../../src/query/errors.ts
436
+ const formatDeepErrorMessage = (message, cause) => `${message}: ${cause instanceof Error ? `\n ${cause.stack}` : cause}`;
437
+ var ChimeraQueryError = class extends require_defaults.ChimeraError {
438
+ entityName;
439
+ constructor(entityName, message, options) {
440
+ super(message, options);
441
+ this.entityName = entityName;
442
+ }
443
+ };
444
+ var ChimeraQueryIdMismatchError = class extends ChimeraQueryError {
445
+ old;
446
+ new;
447
+ constructor(entityName, oldId, newId) {
448
+ super(entityName, `
449
+ Can't update "${entityName}" item if the change updates it's [id] (changed from "${oldId}" to "${newId}").
450
+ If such an update should not be an error, update <idGetter> field in "${entityName}" entity config to make Chimera get the [id] value properly.
451
+ `.trim());
452
+ this.old = oldId;
453
+ this.new = newId;
454
+ }
455
+ };
456
+ var ChimeraQueryNotSpecifiedError = class extends ChimeraQueryError {
457
+ methodName;
458
+ constructor(entityName, methodName) {
459
+ super(entityName, `<${methodName}> for entity "${entityName}" was not specified`);
460
+ this.methodName = methodName;
461
+ }
462
+ };
463
+ var ChimeraQueryTrustError = class extends ChimeraQueryError {
464
+ constructor(entityName, description) {
465
+ super(entityName, `
466
+ DO NOT IGNORE THIS ERROR OR YOUR PROD MAY BREAK!
467
+
468
+ Looks like your "${entityName}" query provider ${description}
469
+
470
+ By default Chimera tend to trust external query provider to avoid extra data processing.
471
+ If it is not your case, set field "trustQuery" to "false" in config defaults or for specific entity.
472
+ This error visible only if "devMode" is "true".
473
+ If you'll ignore it, your production may fail, because Chimera won't check the data correctness.
474
+ `.trim());
475
+ }
476
+ };
477
+ var ChimeraQueryTrustIdMismatchError = class extends ChimeraQueryTrustError {
478
+ old;
479
+ new;
480
+ constructor(entityName, oldId, newId) {
481
+ super(entityName, `
482
+ returned an item with [id] that not matches with the [id] of item that was updated (changed from "${oldId}" to "${newId}").
483
+ If it is not an error, update <idGetter> field in "${entityName}" entity config to make Chimera get the [id] value properly.
484
+ `.trim());
485
+ this.old = oldId;
486
+ this.new = newId;
487
+ }
488
+ };
489
+ var ChimeraQueryTrustFetchedCollectionError = class extends ChimeraQueryTrustError {
490
+ old;
491
+ new;
492
+ constructor(entityName, input, output) {
493
+ super(entityName, "returned not properly sorted or ordered collection.");
494
+ this.old = input;
495
+ this.new = output;
496
+ }
497
+ };
498
+ var ChimeraQueryFetchingError = class extends ChimeraQueryError {
499
+ constructor(entityName, cause) {
500
+ super(entityName, formatDeepErrorMessage("Something went wrong", cause), { cause });
501
+ }
502
+ };
503
+ var ChimeraQueryDeletingError = class extends ChimeraQueryError {
504
+ constructor(entityName, cause) {
505
+ super(entityName, formatDeepErrorMessage("Something went wrong", cause), { cause });
506
+ }
507
+ };
508
+ var ChimeraQueryNotReadyError = class extends ChimeraQueryError {
509
+ constructor(entityName) {
510
+ super(entityName, "Unable to get unready value.");
511
+ }
512
+ };
513
+ var ChimeraQueryDeletedItemError = class extends ChimeraQueryError {
514
+ constructor(entityName, id) {
515
+ super(entityName, `Unable to updated deleted item with [id] "${id}."`);
516
+ }
517
+ };
518
+ var ChimeraQueryUnsuccessfulDeletionError = class extends ChimeraQueryError {
519
+ constructor(entityName, id) {
520
+ super(entityName, `Item with [id] "${id}" was not deleted.`);
521
+ }
522
+ };
523
+ var ChimeraQueryAlreadyRunningError = class extends ChimeraQueryError {
524
+ constructor(entityName, status) {
525
+ super(entityName, `Unable to operate query. Other process already running ${status}.`);
526
+ }
527
+ };
528
+ var ChimeraQueryNotCreatedError = class extends ChimeraQueryError {
529
+ constructor(entityName) {
530
+ super(entityName, "Unable to operate not created item.");
531
+ }
532
+ };
533
+
534
+ //#endregion
535
+ //#region ../../src/query/ChimeraCollectionQuery.ts
536
+ var ChimeraCollectionQuery = class extends ChimeraEventEmitter {
537
+ #state;
538
+ #promise;
539
+ #lastError;
540
+ #items;
541
+ #entityConfig;
542
+ #debugConfig;
543
+ #idGetter;
544
+ #params;
545
+ #order;
546
+ #filter;
547
+ #emit(event, arg) {
548
+ queueMicrotask(() => super.emit(event, arg));
549
+ }
550
+ emit() {
551
+ throw new require_defaults.ChimeraInternalError("External events dispatching is not supported.");
552
+ }
553
+ #prepareRequestParams() {
554
+ return { controller: new AbortController() };
555
+ }
556
+ #readyItems(internalMessage) {
557
+ if (this.#items) return this.#items;
558
+ throw internalMessage ? new require_defaults.ChimeraInternalError(internalMessage) : new ChimeraQueryNotReadyError(this.#entityConfig.name);
559
+ }
560
+ #addItem(item) {
561
+ const items = this.#readyItems("Trying to update not ready collection");
562
+ const foundIndex = items.findIndex((el) => this.#order(el, item) > 0);
563
+ items.splice(foundIndex !== -1 ? foundIndex : items.length, 0, item);
564
+ this.#emit("itemAdded", {
565
+ instance: this,
566
+ item
567
+ });
568
+ }
569
+ #setItems(items) {
570
+ !this.#items && this.#emit("ready", { instance: this });
571
+ const oldItems = this.#items;
572
+ this.#items = items;
573
+ this.#emit("updated", {
574
+ instance: this,
575
+ items,
576
+ oldItems
577
+ });
578
+ }
579
+ #setNewItems(items) {
580
+ items.forEach((i) => void deepObjectFreeze(i));
581
+ this.#emit("selfUpdated", {
582
+ instance: this,
583
+ items,
584
+ oldItems: this.#items
585
+ });
586
+ this.#setItems(items);
587
+ }
588
+ #setPromise(promise) {
589
+ this.#promise?.cancel();
590
+ this.#promise = promise;
591
+ return promise;
592
+ }
593
+ #deleteAtIndex(index) {
594
+ if (index === -1) return;
595
+ const { 0: old } = this.#readyItems("Trying to update not ready collection").splice(index, 1);
596
+ this.#emit("itemDeleted", {
597
+ instance: this,
598
+ item: old
599
+ });
600
+ }
601
+ #deleteItem(item) {
602
+ this.#deleteAtIndex(this.#readyItems("Trying to update not ready collection").indexOf(item));
603
+ }
604
+ #deleteById(id) {
605
+ const name = this.#entityConfig.name;
606
+ this.#deleteAtIndex(this.#readyItems("Trying to update not ready collection").findIndex((item) => this.#idGetter(item, name) === id));
607
+ }
608
+ #replaceItem(oldItem, newItem) {
609
+ const items = this.#readyItems("Trying to update not ready collection");
610
+ const index = items.indexOf(oldItem);
611
+ const old = items[index];
612
+ items[index] = newItem;
613
+ this.#emit("itemUpdated", {
614
+ instance: this,
615
+ newItem,
616
+ oldItem: old
617
+ });
618
+ }
619
+ #getById(id) {
620
+ const name = this.#entityConfig.name;
621
+ return this.#readyItems("Trying to update not ready collection").find((item) => this.#idGetter(item, name) === id);
622
+ }
623
+ #setOne(item) {
624
+ const existingItem = this.#getById(this.#idGetter(item, this.#entityConfig.name));
625
+ const nowMatches = this.#filter(item);
626
+ if (!(nowMatches || existingItem)) return;
627
+ if (existingItem) {
628
+ if (this.#order(existingItem, item) === 0) {
629
+ this.#replaceItem(existingItem, item);
630
+ return;
631
+ }
632
+ this.#deleteItem(existingItem);
633
+ }
634
+ nowMatches && this.#addItem(item);
635
+ }
636
+ #setNewOne(item) {
637
+ deepObjectFreeze(item);
638
+ this.#setOne(item);
639
+ }
640
+ #apply(input) {
641
+ return input.filter((item) => this.#filter(item)).sort((a, b) => this.#order(a, b));
642
+ }
643
+ #validate(input) {
644
+ if (this.#entityConfig.trustQuery && !this.#debugConfig.devMode) return input;
645
+ const prepared = this.#apply(input);
646
+ if (!this.#entityConfig.trustQuery) return prepared;
647
+ if (this.#debugConfig.devMode) {
648
+ for (let i = 0; i < input.length; i++) if (input[i] !== prepared[i]) {
649
+ console.warn(new ChimeraQueryTrustFetchedCollectionError(this.#entityConfig.name, input, prepared));
650
+ break;
651
+ }
652
+ }
653
+ return input;
654
+ }
655
+ #setError(error, source) {
656
+ this.#state = this.#items ? ChimeraQueryFetchingState.ReErrored : ChimeraQueryFetchingState.Errored;
657
+ this.#lastError = error;
658
+ this.#emit("error", {
659
+ error,
660
+ instance: this
661
+ });
662
+ throw source;
663
+ }
664
+ #watchPromise(promise, controller) {
665
+ return makeCancellablePromise(promise.then((response) => {
666
+ this.#setNewItems(this.#validate(response.data));
667
+ this.#state = ChimeraQueryFetchingState.Fetched;
668
+ return response;
669
+ }).catch((error) => this.#setError(error, new ChimeraQueryFetchingError(this.#entityConfig.name, error))), controller);
670
+ }
671
+ constructor(config, debugConfig, params, existingItems, order, filter, alreadyValid) {
672
+ super();
673
+ this.#entityConfig = config;
674
+ this.#debugConfig = debugConfig;
675
+ this.#params = params;
676
+ this.#promise = null;
677
+ this.#items = null;
678
+ this.#state = ChimeraQueryFetchingState.Initialized;
679
+ this.#idGetter = config.idGetter;
680
+ this.#filter = filter;
681
+ this.#order = order;
682
+ if (existingItems) {
683
+ const input = Array.from(existingItems);
684
+ this.#setItems(alreadyValid ? this.#validate(input) : this.#apply(input));
685
+ this.#state = ChimeraQueryFetchingState.Prefetched;
686
+ } else {
687
+ this.#state = ChimeraQueryFetchingState.Fetching;
688
+ const { controller } = this.#prepareRequestParams();
689
+ this.#setPromise(this.#watchPromise(makeCancellablePromise(config.collectionFetcher(params, { signal: controller.signal }, this.#entityConfig.name), controller), controller));
690
+ }
691
+ this.#emit("initialized", { instance: this });
692
+ }
693
+ get name() {
694
+ return this.#entityConfig.name;
695
+ }
696
+ get [ChimeraGetParamsSym]() {
697
+ return this.#params;
698
+ }
699
+ [ChimeraSetOneSym](item) {
700
+ this.#items && this.#setOne(item);
701
+ }
702
+ [ChimeraDeleteOneSym](id) {
703
+ this.#items && this.#deleteById(id);
704
+ }
705
+ [ChimeraSetManySym](items) {
706
+ if (this.#items) for (const item of items) this.#setOne(item);
707
+ }
708
+ [ChimeraDeleteManySym](ids) {
709
+ if (this.#items) for (const id of ids) this.#deleteById(id);
710
+ }
711
+ [ChimeraUpdateMixedSym](toAdd, toDelete) {
712
+ if (this.#items) {
713
+ for (const id of toDelete) this.#deleteById(id);
714
+ for (const item of toAdd) this.#setOne(item);
715
+ }
716
+ }
717
+ get state() {
718
+ return this.#state;
719
+ }
720
+ get inProgress() {
721
+ return IN_PROGRESS_STATES.includes(this.#state);
722
+ }
723
+ get ready() {
724
+ return this.#items !== null;
725
+ }
726
+ get lastError() {
727
+ return this.#lastError;
728
+ }
729
+ /**
730
+ * Wait for the current progress process to complete (both success or error)
731
+ */
732
+ get progress() {
733
+ return new Promise((res) => {
734
+ const resolve = () => queueMicrotask(() => res());
735
+ if (this.#promise) {
736
+ this.#promise.then(resolve, resolve);
737
+ this.#promise.cancelled(() => this.progress.then(resolve, resolve));
738
+ } else resolve();
739
+ });
740
+ }
741
+ /**
742
+ * Wait for the current progress process to complete, throw an error if it fails
743
+ */
744
+ get result() {
745
+ return new Promise((res, rej) => {
746
+ const resolve = () => queueMicrotask(() => res());
747
+ if (this.#promise) {
748
+ this.#promise.then(resolve, rej);
749
+ this.#promise.cancelled(() => this.#promise ? this.result.then(res, rej) : rej("cancelled"));
750
+ } else resolve();
751
+ });
752
+ }
753
+ /** Return an item if it is ready, throw error otherwise */
754
+ getById(id) {
755
+ const name = this.#entityConfig.name;
756
+ return this.#readyItems().find((item) => this.#idGetter(item, name) === id);
757
+ }
758
+ /** Return mutable ref to item by idx if it is ready, throw error otherwise */
759
+ mutableAt(idx) {
760
+ return deepObjectClone(this.#readyItems().at(idx));
761
+ }
762
+ /** Return mutable ref to item by [id] if it is ready, throw error otherwise */
763
+ mutableGetById(id) {
764
+ const name = this.#entityConfig.name;
765
+ return deepObjectClone(this.#readyItems().find((item) => this.#idGetter(item, name) === id));
766
+ }
767
+ /**
768
+ * Trigger refetch, return existing refetch promise if already running
769
+ * @param force If true cancels any running process and starts a new one
770
+ * @throws {ChimeraQueryAlreadyRunningError} If deleting or updating already in progress
771
+ */
772
+ refetch(force = false) {
773
+ if (!force && this.#promise && [ChimeraQueryFetchingState.Fetching, ChimeraQueryFetchingState.Refetching].includes(this.#state)) return this.#promise;
774
+ if (!force && [ChimeraQueryFetchingState.Updating, ChimeraQueryFetchingState.Deleting].includes(this.#state)) throw new ChimeraQueryAlreadyRunningError(this.#entityConfig.name, this.#state);
775
+ this.#state = ChimeraQueryFetchingState.Refetching;
776
+ const { controller } = this.#prepareRequestParams();
777
+ return this.#setPromise(this.#watchPromise(makeCancellablePromise(this.#entityConfig.collectionFetcher(this.#params, { signal: controller.signal }, this.#entityConfig.name), controller), controller));
778
+ }
779
+ /**
780
+ * Update item using updated copy
781
+ * @param newItem new item to update
782
+ */
783
+ update(newItem) {
784
+ const { controller } = this.#prepareRequestParams();
785
+ return this.#entityConfig.itemUpdater(newItem, { signal: controller.signal }, this.#entityConfig.name).then((response) => {
786
+ const { data } = response;
787
+ this.#items && this.#setNewOne(data);
788
+ this.#emit("selfItemUpdated", {
789
+ instance: this,
790
+ item: data
791
+ });
792
+ return response;
793
+ });
794
+ }
795
+ /**
796
+ * Update item using updated copy
797
+ * @param newItems array of items to update
798
+ */
799
+ batchedUpdate(newItems) {
800
+ const { controller } = this.#prepareRequestParams();
801
+ return this.#entityConfig.batchedUpdater(Array.from(newItems), { signal: controller.signal }, this.#entityConfig.name).then((response) => {
802
+ const ready = this.ready;
803
+ response.data.forEach((item) => {
804
+ ready && this.#setNewOne(item);
805
+ this.#emit("selfItemUpdated", {
806
+ instance: this,
807
+ item
808
+ });
809
+ });
810
+ return response;
811
+ });
812
+ }
813
+ /**
814
+ * Delete item using its [id]
815
+ * @param id id of item to delete
816
+ */
817
+ delete(id) {
818
+ const name = this.#entityConfig.name;
819
+ const { controller } = this.#prepareRequestParams();
820
+ return this.#entityConfig.itemDeleter(id, { signal: controller.signal }, name).then((response) => {
821
+ const { result: { id: newId, success } } = response;
822
+ if (!this.#items) {
823
+ success && this.#emit("selfItemDeleted", {
824
+ id: newId,
825
+ instance: this
826
+ });
827
+ return response;
828
+ }
829
+ if (this.#entityConfig.trustQuery && !this.#debugConfig.devMode && success) {
830
+ this.#deleteById(newId);
831
+ this.#emit("selfItemDeleted", {
832
+ id: newId,
833
+ instance: this
834
+ });
835
+ return response;
836
+ }
837
+ if (id !== newId) {
838
+ this.#debugConfig.devMode && this.#entityConfig.trustQuery && console.warn(new ChimeraQueryTrustIdMismatchError(this.#entityConfig.name, id, newId));
839
+ if (!this.#entityConfig.trustQuery) {
840
+ success && this.#emit("selfItemDeleted", {
841
+ id: newId,
842
+ instance: this
843
+ });
844
+ throw new ChimeraQueryTrustIdMismatchError(this.#entityConfig.name, id, newId);
845
+ }
846
+ }
847
+ if (success) {
848
+ this.#deleteById(newId);
849
+ this.#emit("selfItemDeleted", {
850
+ id: newId,
851
+ instance: this
852
+ });
853
+ return response;
854
+ }
855
+ const error = new ChimeraQueryUnsuccessfulDeletionError(this.#entityConfig.name, id);
856
+ this.#state = ChimeraQueryFetchingState.ReErrored;
857
+ this.#lastError = error;
858
+ throw error;
859
+ }, (error) => this.#setError(error, new ChimeraQueryDeletingError(name, error)));
860
+ }
861
+ /**
862
+ * Delete a list of items by their [id]s
863
+ * @param ids array of items to delete
864
+ */
865
+ batchedDelete(ids) {
866
+ const name = this.#entityConfig.name;
867
+ const { controller } = this.#prepareRequestParams();
868
+ return this.#entityConfig.batchedDeleter(Array.from(ids), { signal: controller.signal }, name).then((response) => {
869
+ this.#items && response.result.forEach(({ id: newId, success }) => {
870
+ if (success) {
871
+ this.#deleteById(newId);
872
+ this.#emit("selfItemDeleted", {
873
+ id: newId,
874
+ instance: this
875
+ });
876
+ } else {
877
+ const error = new ChimeraQueryUnsuccessfulDeletionError(this.#entityConfig.name, newId);
878
+ this.#state = ChimeraQueryFetchingState.ReErrored;
879
+ this.#lastError = error;
880
+ throw error;
881
+ }
882
+ });
883
+ return response;
884
+ }, (error) => this.#setError(error, new ChimeraQueryDeletingError(name, error)));
885
+ }
886
+ /**
887
+ * Create new item using partial data
888
+ * @param item partial item data to create new item
889
+ */
890
+ create(item) {
891
+ const name = this.#entityConfig.name;
892
+ const { controller } = this.#prepareRequestParams();
893
+ return this.#entityConfig.itemCreator(item, { signal: controller.signal }, name).then((response) => {
894
+ const { data } = response;
895
+ this.#items && this.#setNewOne(data);
896
+ this.#emit("selfItemCreated", {
897
+ instance: this,
898
+ item: data
899
+ });
900
+ return response;
901
+ }, (error) => this.#setError(error, new ChimeraQueryFetchingError(name, error)));
902
+ }
903
+ /**
904
+ * Create multiple items using partial data
905
+ * @param items array of partial item data to create new items
906
+ */
907
+ batchedCreate(items) {
908
+ const name = this.#entityConfig.name;
909
+ const { controller } = this.#prepareRequestParams();
910
+ return this.#entityConfig.batchedCreator(Array.from(items), { signal: controller.signal }, name).then((response) => {
911
+ this.#items && response.data.forEach((item) => {
912
+ this.#setNewOne(item);
913
+ this.#emit("selfItemCreated", {
914
+ instance: this,
915
+ item
916
+ });
917
+ });
918
+ return response;
919
+ }, (error) => this.#setError(error, new ChimeraQueryFetchingError(name, error)));
920
+ }
921
+ /**
922
+ * Standard Array API without mutations
923
+ */
924
+ get length() {
925
+ return this.#readyItems().length;
926
+ }
927
+ [Symbol.iterator]() {
928
+ return this.#readyItems()[Symbol.iterator]();
929
+ }
930
+ at(idx) {
931
+ return this.#readyItems().at(idx);
932
+ }
933
+ entries() {
934
+ return this.#readyItems().entries();
935
+ }
936
+ values() {
937
+ return this.#readyItems().values();
938
+ }
939
+ keys() {
940
+ return this.#readyItems().keys();
941
+ }
942
+ every(predicate) {
943
+ return this.#readyItems().every((item, idx) => predicate(item, idx, this));
944
+ }
945
+ some(predicate) {
946
+ return this.#readyItems().some((item, idx) => predicate(item, idx, this));
947
+ }
948
+ filter(predicate) {
949
+ return this.#readyItems().filter((item, idx) => predicate(item, idx, this));
950
+ }
951
+ find(predicate) {
952
+ return this.#readyItems().find((item, idx) => predicate(item, idx, this));
953
+ }
954
+ findIndex(predicate) {
955
+ return this.#readyItems().findIndex((item, idx) => predicate(item, idx, this));
956
+ }
957
+ findLast(predicate) {
958
+ return this.#readyItems().findLast((item, idx) => predicate(item, idx, this));
959
+ }
960
+ findLastIndex(predicate) {
961
+ return this.#readyItems().findLastIndex((item, idx) => predicate(item, idx, this));
962
+ }
963
+ forEach(cb) {
964
+ this.#readyItems().forEach((item, idx) => void cb(item, idx, this));
965
+ }
966
+ includes(item) {
967
+ return this.#readyItems().includes(item);
968
+ }
969
+ indexOf(item) {
970
+ return this.#readyItems().indexOf(item);
971
+ }
972
+ map(cb) {
973
+ return this.#readyItems().map((item, idx) => cb(item, idx, this));
974
+ }
975
+ reduce(cb, initialValue) {
976
+ return this.#readyItems().reduce((prev, cur, idx) => cb(prev, cur, idx, this), initialValue);
977
+ }
978
+ reduceRight(cb, initialValue) {
979
+ return this.#readyItems().reduceRight((prev, cur, idx) => cb(prev, cur, idx, this), initialValue);
980
+ }
981
+ slice(start, end) {
982
+ return this.#readyItems().slice(start, end);
983
+ }
984
+ toSorted(compareFn) {
985
+ return this.#readyItems().toSorted(compareFn);
986
+ }
987
+ toSpliced(start, deleteCount, ...items) {
988
+ return this.#readyItems().toSpliced(start, deleteCount, ...items);
989
+ }
990
+ toJSON() {
991
+ return Array.from(this.#readyItems());
992
+ }
993
+ toString() {
994
+ return this.#readyItems().toString();
995
+ }
996
+ };
997
+
998
+ //#endregion
999
+ //#region ../../src/query/ChimeraItemQuery.ts
1000
+ var ChimeraItemQuery = class extends ChimeraEventEmitter {
1001
+ #item;
1002
+ #mutable;
1003
+ #state;
1004
+ #promise;
1005
+ #lastError;
1006
+ #params;
1007
+ #entityConfig;
1008
+ #debugConfig;
1009
+ #idGetter;
1010
+ #emit(event, arg) {
1011
+ queueMicrotask(() => super.emit(event, arg));
1012
+ }
1013
+ emit() {
1014
+ throw new require_defaults.ChimeraInternalError("External events dispatching is not supported.");
1015
+ }
1016
+ #prepareRequestParams() {
1017
+ return { controller: new AbortController() };
1018
+ }
1019
+ #setPromise(promise) {
1020
+ this.#promise?.cancel();
1021
+ this.#promise = promise;
1022
+ return promise;
1023
+ }
1024
+ #readyItem(internalMessage) {
1025
+ if (this.#item) return this.#item;
1026
+ throw internalMessage ? new require_defaults.ChimeraInternalError(internalMessage) : new ChimeraQueryNotReadyError(this.#entityConfig.name);
1027
+ }
1028
+ #mutableItem(internalMessage) {
1029
+ if (this.#state === ChimeraQueryFetchingState.Deleted) throw internalMessage ? new require_defaults.ChimeraInternalError(internalMessage) : new ChimeraQueryDeletedItemError(this.#entityConfig.name, this.#params.id);
1030
+ return this.#readyItem(internalMessage);
1031
+ }
1032
+ #setMutable(item) {
1033
+ if (item != null) if (this.#mutable) deepObjectAssign(this.#mutable, item);
1034
+ else this.#mutable = deepObjectClone(item);
1035
+ else this.#mutable = item;
1036
+ }
1037
+ #resetMutable() {
1038
+ this.#setMutable(this.#readyItem(`Trying to reset mutable ref for empty item (${this.#entityConfig.name}[${this.#params.id}])`));
1039
+ }
1040
+ #setItem(item) {
1041
+ !this.#item && this.#emit("ready", { instance: this });
1042
+ const oldItem = this.#item;
1043
+ this.#item = item;
1044
+ this.#resetMutable();
1045
+ this.#emit("updated", {
1046
+ instance: this,
1047
+ item,
1048
+ oldItem
1049
+ });
1050
+ }
1051
+ #setNewItem(item) {
1052
+ deepObjectFreeze(item);
1053
+ const oldItem = this.#item;
1054
+ this.#setItem(item);
1055
+ this.#emit("selfUpdated", {
1056
+ instance: this,
1057
+ item,
1058
+ oldItem
1059
+ });
1060
+ }
1061
+ #deleteItem() {
1062
+ this.#state = ChimeraQueryFetchingState.Deleted;
1063
+ this.#emit("deleted", {
1064
+ id: this.#params.id,
1065
+ instance: this
1066
+ });
1067
+ }
1068
+ #setError(error, source) {
1069
+ this.#state = this.#item ? ChimeraQueryFetchingState.ReErrored : ChimeraQueryFetchingState.Errored;
1070
+ this.#lastError = error;
1071
+ this.#emit("error", {
1072
+ error,
1073
+ instance: this
1074
+ });
1075
+ throw source;
1076
+ }
1077
+ #watchPromise(promise, controller) {
1078
+ const name = this.#entityConfig.name;
1079
+ return makeCancellablePromise(promise.then(({ data }) => {
1080
+ if (this.#entityConfig.trustQuery && !this.#debugConfig.devMode) {
1081
+ this.#setNewItem(data);
1082
+ this.#state = ChimeraQueryFetchingState.Fetched;
1083
+ return { data };
1084
+ }
1085
+ const localId = this.#params.id;
1086
+ const newId = this.#idGetter(data, name);
1087
+ if (localId === newId || this.#state === ChimeraQueryFetchingState.Creating) {
1088
+ this.#setNewItem(data);
1089
+ if (this.#state === ChimeraQueryFetchingState.Creating) this.#emit("selfCreated", {
1090
+ instance: this,
1091
+ item: data
1092
+ });
1093
+ this.#state = ChimeraQueryFetchingState.Fetched;
1094
+ } else {
1095
+ this.#debugConfig.devMode && this.#entityConfig.trustQuery && console.warn(new ChimeraQueryTrustIdMismatchError(this.#entityConfig.name, localId, newId));
1096
+ if (!this.#entityConfig.trustQuery) throw new ChimeraQueryTrustIdMismatchError(this.#entityConfig.name, localId, newId);
1097
+ this.#setNewItem(data);
1098
+ this.#params.id = newId;
1099
+ this.#state = ChimeraQueryFetchingState.Fetched;
1100
+ }
1101
+ return { data };
1102
+ }).catch((error) => this.#setError(error, new ChimeraQueryFetchingError(this.#entityConfig.name, error))), controller);
1103
+ }
1104
+ #updateItem(newItem) {
1105
+ const name = this.#entityConfig.name;
1106
+ const newId = this.#idGetter(newItem, name);
1107
+ const oldId = this.#idGetter(this.#readyItem(`Trying to update not ready item (${this.#entityConfig.name}[${this.#params.id}])`), name);
1108
+ if (newId !== oldId && !this.#entityConfig.trustQuery) {
1109
+ this.#resetMutable();
1110
+ throw new ChimeraQueryIdMismatchError(this.#entityConfig.name, oldId, newId);
1111
+ }
1112
+ this.#state = ChimeraQueryFetchingState.Updating;
1113
+ const { controller } = this.#prepareRequestParams();
1114
+ return this.#setPromise(this.#watchPromise(makeCancellablePromise(this.#entityConfig.itemUpdater(newItem, { signal: controller.signal }, name), controller), controller));
1115
+ }
1116
+ #requestDelete() {
1117
+ this.#state = ChimeraQueryFetchingState.Deleting;
1118
+ const { controller } = this.#prepareRequestParams();
1119
+ const name = this.#entityConfig.name;
1120
+ return this.#setPromise(makeCancellablePromise(makeCancellablePromise(this.#entityConfig.itemDeleter(this.#params.id, { signal: controller.signal }, name), controller).then(({ result }) => {
1121
+ const { id, success } = result;
1122
+ if (this.#entityConfig.trustQuery && !this.#debugConfig.devMode && success) {
1123
+ this.#deleteItem();
1124
+ return { result };
1125
+ }
1126
+ const localId = this.#params.id;
1127
+ if (localId !== id) {
1128
+ this.#debugConfig.devMode && this.#entityConfig.trustQuery && console.warn(new ChimeraQueryTrustIdMismatchError(this.#entityConfig.name, localId, id));
1129
+ if (!this.#entityConfig.trustQuery) throw new ChimeraQueryTrustIdMismatchError(this.#entityConfig.name, localId, id);
1130
+ }
1131
+ if (success) {
1132
+ this.#deleteItem();
1133
+ this.#emit("selfDeleted", {
1134
+ id,
1135
+ instance: this
1136
+ });
1137
+ } else {
1138
+ const error = new ChimeraQueryUnsuccessfulDeletionError(this.#entityConfig.name, this.#params.id);
1139
+ this.#state = ChimeraQueryFetchingState.ReErrored;
1140
+ this.#lastError = error;
1141
+ throw error;
1142
+ }
1143
+ return { result };
1144
+ }, (error) => this.#setError(error, new ChimeraQueryDeletingError(this.#entityConfig.name, error)))));
1145
+ }
1146
+ constructor(config, debugConfig, params, existingItem, toCreateItem) {
1147
+ super();
1148
+ this.#entityConfig = config;
1149
+ this.#debugConfig = debugConfig;
1150
+ this.#idGetter = config.idGetter;
1151
+ this.#params = params;
1152
+ this.#promise = null;
1153
+ this.#item = null;
1154
+ this.#mutable = null;
1155
+ this.#state = ChimeraQueryFetchingState.Initialized;
1156
+ const name = config.name;
1157
+ if (existingItem) {
1158
+ const item = existingItem;
1159
+ this.#setItem(item);
1160
+ if (debugConfig.devMode && this.#idGetter(item, name) !== params.id) {
1161
+ this.#state = ChimeraQueryFetchingState.Errored;
1162
+ throw new require_defaults.ChimeraInternalError(`Invalid item query [id] (changed from "${params.id}" to "${this.#idGetter(item, name)}")`);
1163
+ }
1164
+ this.#state = ChimeraQueryFetchingState.Prefetched;
1165
+ } else if (toCreateItem) {
1166
+ this.#state = ChimeraQueryFetchingState.Creating;
1167
+ const { controller } = this.#prepareRequestParams();
1168
+ this.#setPromise(this.#watchPromise(makeCancellablePromise(config.itemCreator(toCreateItem, { signal: controller.signal }, name), controller).then(({ data }) => {
1169
+ this.#params.id = this.#idGetter(data, name);
1170
+ return { data };
1171
+ }), controller));
1172
+ } else {
1173
+ this.#state = ChimeraQueryFetchingState.Fetching;
1174
+ const { controller } = this.#prepareRequestParams();
1175
+ this.#setPromise(this.#watchPromise(makeCancellablePromise(config.itemFetcher(params, { signal: controller.signal }, name), controller), controller));
1176
+ }
1177
+ this.#emit("initialized", { instance: this });
1178
+ }
1179
+ get name() {
1180
+ return this.#entityConfig.name;
1181
+ }
1182
+ get [ChimeraGetParamsSym]() {
1183
+ return this.#params;
1184
+ }
1185
+ [ChimeraSetOneSym](item) {
1186
+ this.#setItem(item);
1187
+ !this.inProgress && (this.#state = ChimeraQueryFetchingState.Actualized);
1188
+ }
1189
+ [ChimeraDeleteOneSym](id) {
1190
+ if (id === this.#params.id) {
1191
+ this.#promise?.cancel();
1192
+ this.#promise = null;
1193
+ this.#deleteItem();
1194
+ }
1195
+ }
1196
+ get state() {
1197
+ return this.#state;
1198
+ }
1199
+ get inProgress() {
1200
+ return IN_PROGRESS_STATES.includes(this.#state);
1201
+ }
1202
+ get ready() {
1203
+ return this.#item !== null;
1204
+ }
1205
+ get lastError() {
1206
+ return this.#lastError;
1207
+ }
1208
+ get id() {
1209
+ return this.#params.id;
1210
+ }
1211
+ /** Return an item if it is ready, throw error otherwise */
1212
+ get data() {
1213
+ return this.#readyItem();
1214
+ }
1215
+ /** Get ref for an item that can be changed as a regular object. To send changes to updater, use <commit> method */
1216
+ get mutable() {
1217
+ this.#readyItem();
1218
+ return this.#mutable;
1219
+ }
1220
+ get promise() {
1221
+ return this.#promise;
1222
+ }
1223
+ /**
1224
+ * Wait for the current progress process to complete (both success or error)
1225
+ */
1226
+ get progress() {
1227
+ return new Promise((res) => {
1228
+ const resolve = () => queueMicrotask(() => res());
1229
+ if (this.#promise) {
1230
+ this.#promise.then(resolve, resolve);
1231
+ this.#promise.cancelled(() => this.progress.then(resolve, resolve));
1232
+ } else resolve();
1233
+ });
1234
+ }
1235
+ /**
1236
+ * Wait for the current progress process to complete, throw an error if it fails
1237
+ */
1238
+ get result() {
1239
+ return new Promise((res, rej) => {
1240
+ const resolve = () => queueMicrotask(() => res());
1241
+ if (this.#promise) {
1242
+ this.#promise.then(resolve, rej);
1243
+ this.#promise.cancelled(() => this.#promise ? this.result.then(res, rej) : rej("cancelled"));
1244
+ } else resolve();
1245
+ });
1246
+ }
1247
+ /**
1248
+ * Trigger refetch, return existing refetch promise if already running
1249
+ * @param force If true cancels any running process and starts a new one
1250
+ * @throws {ChimeraQueryAlreadyRunningError} If deleting or updating already in progress
1251
+ */
1252
+ refetch(force = false) {
1253
+ if (!force && this.#promise && [ChimeraQueryFetchingState.Fetching, ChimeraQueryFetchingState.Refetching].includes(this.#state)) return this.#promise;
1254
+ if (this.#state === ChimeraQueryFetchingState.Creating) throw new ChimeraQueryNotCreatedError(this.#entityConfig.name);
1255
+ if (!force && [ChimeraQueryFetchingState.Updating, ChimeraQueryFetchingState.Deleting].includes(this.#state)) throw new ChimeraQueryAlreadyRunningError(this.#entityConfig.name, this.#state);
1256
+ this.#state = ChimeraQueryFetchingState.Refetching;
1257
+ const { controller } = this.#prepareRequestParams();
1258
+ return this.#setPromise(this.#watchPromise(makeCancellablePromise(this.#entityConfig.itemFetcher(this.#params, { signal: controller.signal }, this.#entityConfig.name), controller), controller));
1259
+ }
1260
+ /**
1261
+ * Update item using updated copy, a running update process will be cancelled
1262
+ * @param newItem new item to replace existing
1263
+ * @param force if true cancels any running process including fetch and delete
1264
+ * @throws {ChimeraQueryAlreadyRunningError} If deleting or updating already in progress
1265
+ */
1266
+ update(newItem, force = false) {
1267
+ if (this.#state === ChimeraQueryFetchingState.Creating) throw new ChimeraQueryNotCreatedError(this.#entityConfig.name);
1268
+ if (!force && [
1269
+ ChimeraQueryFetchingState.Fetching,
1270
+ ChimeraQueryFetchingState.Refetching,
1271
+ ChimeraQueryFetchingState.Deleting
1272
+ ].includes(this.#state)) throw new ChimeraQueryAlreadyRunningError(this.#entityConfig.name, this.#state);
1273
+ this.#mutableItem();
1274
+ return this.#updateItem(newItem);
1275
+ }
1276
+ /**
1277
+ * Update item using function with draft item as argument
1278
+ * that can be used to patch item in place or return a patched value,
1279
+ * a running update process will be cancelled
1280
+ * @param mutator mutator function
1281
+ * @param force if true cancels any running process including fetch and delete
1282
+ * @throws {ChimeraQueryAlreadyRunningError} If deleting or updating already in progress
1283
+ */
1284
+ mutate(mutator, force = false) {
1285
+ if (this.#state === ChimeraQueryFetchingState.Creating) throw new ChimeraQueryNotCreatedError(this.#entityConfig.name);
1286
+ if (!force && [
1287
+ ChimeraQueryFetchingState.Fetching,
1288
+ ChimeraQueryFetchingState.Refetching,
1289
+ ChimeraQueryFetchingState.Deleting
1290
+ ].includes(this.#state)) throw new ChimeraQueryAlreadyRunningError(this.#entityConfig.name, this.#state);
1291
+ const item = deepObjectClone(this.#mutableItem());
1292
+ return this.#updateItem(mutator(item) ?? item);
1293
+ }
1294
+ /**
1295
+ * Commit updated value from mutable ref, a running update process will be canceled
1296
+ * @param force if true cancels any running process including fetch and delete
1297
+ * @throws {ChimeraQueryAlreadyRunningError} If deleting or updating already in progress
1298
+ */
1299
+ commit(force = false) {
1300
+ if (this.#state === ChimeraQueryFetchingState.Creating) throw new ChimeraQueryNotCreatedError(this.#entityConfig.name);
1301
+ if (!force && [
1302
+ ChimeraQueryFetchingState.Fetching,
1303
+ ChimeraQueryFetchingState.Refetching,
1304
+ ChimeraQueryFetchingState.Deleting
1305
+ ].includes(this.#state)) throw new ChimeraQueryAlreadyRunningError(this.#entityConfig.name, this.#state);
1306
+ this.#mutableItem();
1307
+ return this.#updateItem(this.#mutable);
1308
+ }
1309
+ /**
1310
+ * Request to delete the value.
1311
+ * Local copy will still be available if it was present.
1312
+ * A running delete process will be canceled
1313
+ * @param force if true cancels any running process including fetch and update
1314
+ * @throws {ChimeraQueryAlreadyRunningError} If deleting or updating already in progress
1315
+ */
1316
+ delete(force = false) {
1317
+ if (this.#state === ChimeraQueryFetchingState.Creating) throw new ChimeraQueryNotCreatedError(this.#entityConfig.name);
1318
+ if (!force && [
1319
+ ChimeraQueryFetchingState.Fetching,
1320
+ ChimeraQueryFetchingState.Refetching,
1321
+ ChimeraQueryFetchingState.Updating
1322
+ ].includes(this.#state)) throw new ChimeraQueryAlreadyRunningError(this.#entityConfig.name, this.#state);
1323
+ return this.#requestDelete();
1324
+ }
1325
+ toJSON() {
1326
+ return this.#readyItem();
1327
+ }
1328
+ toString() {
1329
+ return `${this.#readyItem()}`;
1330
+ }
1331
+ };
1332
+
1333
+ //#endregion
1334
+ //#region ../../src/shared/ChimeraWeakValueMap/ChimeraWeakValueMap.ts
1335
+ var ChimeraWeakValueMap = class extends ChimeraEventEmitter {
1336
+ #map;
1337
+ #registry;
1338
+ #cleanupScheduled = false;
1339
+ #emit(event, arg) {
1340
+ queueMicrotask(() => super.emit(event, arg));
1341
+ }
1342
+ emit() {
1343
+ throw new require_defaults.ChimeraInternalError("External events dispatching is not supported.");
1344
+ }
1345
+ #scheduleCleanup() {
1346
+ if (this.#cleanupScheduled) return;
1347
+ this.#cleanupScheduled = true;
1348
+ (typeof requestIdleCallback !== "undefined" ? requestIdleCallback : (cb) => setTimeout(cb, 0))(() => {
1349
+ this.#cleanup();
1350
+ this.#cleanupScheduled = false;
1351
+ });
1352
+ }
1353
+ #cleanup() {
1354
+ for (const [key, weakRef] of this.#map.entries()) if (weakRef.deref() === void 0) {
1355
+ this.#map.delete(key);
1356
+ this.#emit("finalize", {
1357
+ instance: this,
1358
+ key
1359
+ });
1360
+ }
1361
+ }
1362
+ constructor(values) {
1363
+ super();
1364
+ this.#registry = new FinalizationRegistry((key) => {
1365
+ const weakRef = this.#map.get(key);
1366
+ if (weakRef && weakRef.deref() === void 0) {
1367
+ this.#map.delete(key);
1368
+ this.#emit("finalize", {
1369
+ instance: this,
1370
+ key
1371
+ });
1372
+ }
1373
+ });
1374
+ this.#map = new Map(values ? values.map(([k, v]) => {
1375
+ this.#registry.register(v, k, v);
1376
+ return [k, new WeakRef(v)];
1377
+ }) : null);
1378
+ }
1379
+ set(key, value) {
1380
+ const existingRef = this.#map.get(key);
1381
+ if (existingRef) {
1382
+ const existingValue = existingRef.deref();
1383
+ if (existingValue) this.#registry.unregister(existingValue);
1384
+ }
1385
+ this.#registry.register(value, key, value);
1386
+ this.#map.set(key, new WeakRef(value));
1387
+ this.#emit("set", {
1388
+ instance: this,
1389
+ key,
1390
+ value
1391
+ });
1392
+ return this;
1393
+ }
1394
+ delete(key) {
1395
+ if (!this.#map.has(key)) return false;
1396
+ const value = this.#map.get(key)?.deref();
1397
+ if (value === void 0) {
1398
+ this.#map.delete(key);
1399
+ this.#emit("finalize", {
1400
+ instance: this,
1401
+ key
1402
+ });
1403
+ return true;
1404
+ }
1405
+ this.#map.delete(key);
1406
+ this.#registry.unregister(value);
1407
+ this.#emit("delete", {
1408
+ instance: this,
1409
+ key,
1410
+ value
1411
+ });
1412
+ return true;
1413
+ }
1414
+ has(key) {
1415
+ const weakRef = this.#map.get(key);
1416
+ const value = weakRef?.deref();
1417
+ if (value === void 0 && weakRef) {
1418
+ this.#map.delete(key);
1419
+ this.#emit("finalize", {
1420
+ instance: this,
1421
+ key
1422
+ });
1423
+ this.#scheduleCleanup();
1424
+ }
1425
+ return value !== void 0;
1426
+ }
1427
+ forEach(callbackFn, thisArg) {
1428
+ this.#map.forEach((weakRef, k) => {
1429
+ const value = weakRef.deref();
1430
+ if (value !== void 0) callbackFn.call(thisArg, value, k, this);
1431
+ else {
1432
+ this.#map.delete(k);
1433
+ this.#emit("finalize", {
1434
+ instance: this,
1435
+ key: k
1436
+ });
1437
+ }
1438
+ });
1439
+ if (this.#map.size > 0) this.#scheduleCleanup();
1440
+ }
1441
+ get(key) {
1442
+ const weakRef = this.#map.get(key);
1443
+ const value = weakRef?.deref();
1444
+ if (value === void 0 && weakRef) {
1445
+ this.#map.delete(key);
1446
+ this.#emit("finalize", {
1447
+ instance: this,
1448
+ key
1449
+ });
1450
+ this.#scheduleCleanup();
1451
+ }
1452
+ return value;
1453
+ }
1454
+ get size() {
1455
+ this.#cleanup();
1456
+ return this.#map.size;
1457
+ }
1458
+ *entries() {
1459
+ for (const [k, weakRef] of this.#map.entries()) {
1460
+ const value = weakRef.deref();
1461
+ if (value !== void 0) yield [k, value];
1462
+ else {
1463
+ this.#map.delete(k);
1464
+ this.#emit("finalize", {
1465
+ instance: this,
1466
+ key: k
1467
+ });
1468
+ }
1469
+ }
1470
+ if (this.#map.size > 0) this.#scheduleCleanup();
1471
+ }
1472
+ *keys() {
1473
+ for (const [k, weakRef] of this.#map.entries()) if (weakRef.deref() !== void 0) yield k;
1474
+ else {
1475
+ this.#map.delete(k);
1476
+ this.#emit("finalize", {
1477
+ instance: this,
1478
+ key: k
1479
+ });
1480
+ }
1481
+ if (this.#map.size > 0) this.#scheduleCleanup();
1482
+ }
1483
+ *values() {
1484
+ for (const weakRef of this.#map.values()) {
1485
+ const value = weakRef.deref();
1486
+ if (value !== void 0) yield value;
1487
+ }
1488
+ this.#cleanup();
1489
+ }
1490
+ *[Symbol.iterator]() {
1491
+ yield* this.entries();
1492
+ }
1493
+ clear() {
1494
+ for (const weakRef of this.#map.values()) {
1495
+ const value = weakRef.deref();
1496
+ if (value !== void 0) this.#registry.unregister(value);
1497
+ }
1498
+ this.#map.clear();
1499
+ this.#emit("clear", { instance: this });
1500
+ }
1501
+ cleanup() {
1502
+ this.#cleanup();
1503
+ }
1504
+ get rawSize() {
1505
+ return this.#map.size;
1506
+ }
1507
+ };
1508
+
1509
+ //#endregion
1510
+ //#region ../../src/entity-store/ChimeraEntityStore.ts
1511
+ var ChimeraEntityStore = class extends ChimeraEventEmitter {
1512
+ #entityConfig;
1513
+ #filterConfig;
1514
+ #orderConfig;
1515
+ #debugConfig;
1516
+ #idGetter;
1517
+ #itemsMap;
1518
+ #collectionQueryMap;
1519
+ #itemQueryMap;
1520
+ #emit(event, arg) {
1521
+ queueMicrotask(() => super.emit(event, arg));
1522
+ }
1523
+ emit() {
1524
+ throw new require_defaults.ChimeraInternalError("External events dispatching is not supported.");
1525
+ }
1526
+ #registerUpdate(item, skipItem) {
1527
+ const id = this.#idGetter(item, this.#entityConfig.name);
1528
+ const oldItem = this.#itemsMap.get(id);
1529
+ this.#itemsMap.set(id, item);
1530
+ const itemQuery = this.#itemQueryMap.get(id);
1531
+ itemQuery && skipItem !== itemQuery && itemQuery[ChimeraSetOneSym](item);
1532
+ !oldItem && this.#emit("itemAdded", {
1533
+ instance: this,
1534
+ item
1535
+ });
1536
+ this.#emit("itemUpdated", {
1537
+ instance: this,
1538
+ item,
1539
+ oldItem: oldItem ?? null
1540
+ });
1541
+ }
1542
+ #registerDelete(id, skipItem) {
1543
+ const oldItem = this.#itemsMap.get(id);
1544
+ if (!oldItem) return;
1545
+ this.#itemsMap.delete(id);
1546
+ const itemQuery = this.#itemQueryMap.get(id);
1547
+ itemQuery && skipItem !== itemQuery && itemQuery[ChimeraDeleteOneSym](id);
1548
+ this.#emit("itemDeleted", {
1549
+ instance: this,
1550
+ oldItem: oldItem ?? null
1551
+ });
1552
+ }
1553
+ #propagateUpdateOne(item, { item: skipItem, collection: skipCollection } = {}) {
1554
+ this.#registerUpdate(item, skipItem);
1555
+ for (const c of this.#collectionQueryMap.values()) c !== skipCollection && c[ChimeraSetOneSym](item);
1556
+ }
1557
+ #propagateDeleteOne(id, { item: skipItem, collection: skipCollection } = {}) {
1558
+ this.#registerDelete(id, skipItem);
1559
+ for (const c of this.#collectionQueryMap.values()) c !== skipCollection && c[ChimeraDeleteOneSym](id);
1560
+ }
1561
+ #propagateUpdateMany(items, { item: skipItem, collection: skipCollection } = {}) {
1562
+ for (const item of items) this.#registerUpdate(item, skipItem);
1563
+ this.#emit("updated", {
1564
+ instance: this,
1565
+ items
1566
+ });
1567
+ for (const c of this.#collectionQueryMap.values()) c !== skipCollection && c[ChimeraSetManySym](items);
1568
+ }
1569
+ #propagateDeleteMany(ids, { item: skipItem, collection: skipCollection } = {}) {
1570
+ for (const id of ids) this.#registerDelete(id, skipItem);
1571
+ this.#emit("deleted", {
1572
+ ids,
1573
+ instance: this
1574
+ });
1575
+ for (const c of this.#collectionQueryMap.values()) c !== skipCollection && c[ChimeraDeleteManySym](ids);
1576
+ }
1577
+ #itemUpdateHandler(query, item) {
1578
+ this.#propagateUpdateOne(item, { item: query });
1579
+ }
1580
+ #itemDeleteHandler(query, id) {
1581
+ this.#itemQueryMap.delete(id);
1582
+ this.#propagateDeleteOne(id, { item: query });
1583
+ }
1584
+ #prepareItemQuery(query) {
1585
+ if (query.id !== "") this.#itemQueryMap.set(query.id, query);
1586
+ query.on("selfCreated", ({ instance }) => this.#itemQueryMap.set(instance.id, instance));
1587
+ query.on("selfUpdated", ({ instance, item }) => this.#itemUpdateHandler(instance, item));
1588
+ query.on("selfDeleted", ({ instance, id }) => this.#itemDeleteHandler(instance, id));
1589
+ return query;
1590
+ }
1591
+ #simplifyCollectionParams(params) {
1592
+ return {
1593
+ filter: simplifyFilter(params.filter),
1594
+ order: simplifyOrderBy(params.order),
1595
+ meta: params.meta
1596
+ };
1597
+ }
1598
+ #getCollectionKey({ order, filter }) {
1599
+ return `${this.#entityConfig.name}:ORDER<${order ? this.#orderConfig.getKey(order) : ""}>:FILTER<${filter ? this.#filterConfig.getFilterKey(filter) : ""}>`;
1600
+ }
1601
+ #collectionUpdateHandler(query, items) {
1602
+ this.#propagateUpdateMany(items, { collection: query });
1603
+ }
1604
+ #collectionCreateHandler(query, item) {
1605
+ this.#propagateUpdateOne(item, { collection: query });
1606
+ }
1607
+ #collectionItemUpdated(query, item) {
1608
+ this.#propagateUpdateOne(item, { collection: query });
1609
+ }
1610
+ #collectionItemDeleted(query, id) {
1611
+ this.#propagateDeleteOne(id, { collection: query });
1612
+ }
1613
+ #prepareCollectionQuery(query) {
1614
+ this.#collectionQueryMap.set(this.#getCollectionKey(query[ChimeraGetParamsSym]), query);
1615
+ query.on("selfUpdated", ({ instance, items }) => this.#collectionUpdateHandler(instance, items));
1616
+ query.on("selfItemCreated", ({ instance, item }) => this.#collectionCreateHandler(instance, item));
1617
+ query.on("selfItemUpdated", ({ instance, item }) => this.#collectionItemUpdated(instance, item));
1618
+ query.on("selfItemDeleted", ({ instance, id }) => this.#collectionItemDeleted(instance, id));
1619
+ return query;
1620
+ }
1621
+ #getParentQuery(filter) {
1622
+ for (const q of this.#collectionQueryMap.values()) if (q.ready && isFilterSubset(q[ChimeraGetParamsSym].filter, filter, this.#filterConfig.getOperatorKey)) return q;
1623
+ return null;
1624
+ }
1625
+ constructor(config, filterConfig, orderConfig, debugConfig) {
1626
+ super();
1627
+ this.#entityConfig = config;
1628
+ this.#filterConfig = filterConfig;
1629
+ this.#orderConfig = orderConfig;
1630
+ this.#debugConfig = debugConfig;
1631
+ this.#idGetter = typeof this.#entityConfig.idGetter === "function" ? this.#entityConfig.idGetter : (entity) => entity[this.#entityConfig.idGetter];
1632
+ this.#itemsMap = new ChimeraWeakValueMap();
1633
+ this.#collectionQueryMap = new ChimeraWeakValueMap();
1634
+ this.#itemQueryMap = new ChimeraWeakValueMap();
1635
+ this.#emit("initialized", { instance: this });
1636
+ }
1637
+ get name() {
1638
+ return this.#entityConfig.name;
1639
+ }
1640
+ updateOne(TItem) {
1641
+ this.#propagateUpdateOne(TItem);
1642
+ }
1643
+ deleteOne(id) {
1644
+ this.#propagateDeleteOne(id);
1645
+ }
1646
+ updateMany(items) {
1647
+ this.#propagateUpdateMany(items);
1648
+ }
1649
+ deleteMany(ids) {
1650
+ this.#propagateDeleteMany(ids);
1651
+ }
1652
+ updateMixed(toAdd, toDelete) {
1653
+ this.#propagateUpdateMany(toAdd);
1654
+ this.#propagateDeleteMany(toDelete);
1655
+ }
1656
+ createItem(TItem, meta) {
1657
+ return this.#prepareItemQuery(new ChimeraItemQuery(this.#entityConfig, this.#debugConfig, {
1658
+ id: "",
1659
+ meta
1660
+ }, null, TItem));
1661
+ }
1662
+ getItem(id, meta) {
1663
+ const query = this.#itemQueryMap.get(id);
1664
+ if (query) return query;
1665
+ return this.#prepareItemQuery(new ChimeraItemQuery(this.#entityConfig, this.#debugConfig, {
1666
+ id,
1667
+ meta
1668
+ }, this.#itemsMap.get(id) ?? null, null));
1669
+ }
1670
+ getCollection(params) {
1671
+ const simplifiedParams = this.#simplifyCollectionParams(params);
1672
+ const key = this.#getCollectionKey(simplifiedParams);
1673
+ const query = this.#collectionQueryMap.get(key);
1674
+ if (query) return query;
1675
+ return this.#prepareCollectionQuery(new ChimeraCollectionQuery(this.#entityConfig, this.#debugConfig, simplifiedParams, this.#getParentQuery(simplifiedParams.filter), buildComparator(this.#orderConfig.primitiveComparator, params.order), compileFilter(this.#filterConfig, params.filter), false));
1676
+ }
1677
+ };
1678
+ function createChimeraEntityStore(entityConfig, filterConfig, orderConfig, debugConfig) {
1679
+ return new ChimeraEntityStore({
1680
+ ...require_defaults.chimeraDefaultQueryEntityConfig,
1681
+ ...entityConfig,
1682
+ idGetter: typeof entityConfig.idGetter === "function" ? entityConfig.idGetter : (entity) => entity[entityConfig.idGetter]
1683
+ }, filterConfig ?? require_defaults.chimeraDefaultFilterConfig, orderConfig ?? require_defaults.chimeraDefaultOrderConfig, debugConfig ?? require_defaults.chimeraDefaultDebugConfig);
1684
+ }
1685
+
1686
+ //#endregion
1687
+ exports.ChimeraCollectionQuery = ChimeraCollectionQuery;
1688
+ exports.ChimeraEntityStore = ChimeraEntityStore;
5
1689
  exports.ChimeraError = require_defaults.ChimeraError;
6
- exports.ChimeraFilterError = require_src.ChimeraFilterError;
7
- exports.ChimeraFilterOperatorError = require_src.ChimeraFilterOperatorError;
8
- exports.ChimeraFilterOperatorNotFoundError = require_src.ChimeraFilterOperatorNotFoundError;
1690
+ exports.ChimeraEventEmitter = ChimeraEventEmitter;
1691
+ exports.ChimeraFilterError = ChimeraFilterError;
1692
+ exports.ChimeraFilterOperatorError = ChimeraFilterOperatorError;
1693
+ exports.ChimeraFilterOperatorNotFoundError = ChimeraFilterOperatorNotFoundError;
9
1694
  exports.ChimeraInternalError = require_defaults.ChimeraInternalError;
10
- exports.ChimeraItemQuery = require_src.ChimeraItemQuery;
1695
+ exports.ChimeraItemQuery = ChimeraItemQuery;
11
1696
  exports.ChimeraOrderError = require_defaults.ChimeraOrderError;
12
- exports.ChimeraOrderNulls = require_src.ChimeraOrderNulls;
1697
+ exports.ChimeraOrderNulls = ChimeraOrderNulls;
13
1698
  exports.ChimeraOrderTypeComparisonError = require_defaults.ChimeraOrderTypeComparisonError;
14
1699
  exports.ChimeraOrderTypeError = require_defaults.ChimeraOrderTypeError;
15
- exports.ChimeraQueryError = require_defaults.ChimeraQueryError;
16
- exports.ChimeraQueryFetchingState = require_src.ChimeraQueryFetchingState;
17
- exports.ChimeraQueryIdMismatchError = require_defaults.ChimeraQueryIdMismatchError;
18
- exports.ChimeraQueryNotSpecifiedError = require_defaults.ChimeraQueryNotSpecifiedError;
19
- exports.ChimeraQueryTrustError = require_defaults.ChimeraQueryTrustError;
20
- exports.ChimeraQueryTrustFetchedCollectionError = require_defaults.ChimeraQueryTrustFetchedCollectionError;
21
- exports.ChimeraQueryTrustIdMismatchError = require_defaults.ChimeraQueryTrustIdMismatchError;
22
- exports.ChimeraStore = require_src.ChimeraStore;
23
- exports.ChimeraWeakValueMap = require_src.ChimeraWeakValueMap;
24
- exports.chimeraCreateConjunction = require_src.chimeraCreateConjunction;
25
- exports.chimeraCreateNot = require_src.chimeraCreateNot;
26
- exports.chimeraCreateOperator = require_src.chimeraCreateOperator;
27
- exports.chimeraCreateOrderBy = require_src.chimeraCreateOrderBy;
28
- exports.chimeraIsConjunction = require_src.chimeraIsConjunction;
29
- exports.chimeraIsOperator = require_src.chimeraIsOperator;
1700
+ exports.ChimeraQueryError = ChimeraQueryError;
1701
+ exports.ChimeraQueryFetchingState = ChimeraQueryFetchingState;
1702
+ exports.ChimeraQueryIdMismatchError = ChimeraQueryIdMismatchError;
1703
+ exports.ChimeraQueryNotSpecifiedError = ChimeraQueryNotSpecifiedError;
1704
+ exports.ChimeraQueryTrustError = ChimeraQueryTrustError;
1705
+ exports.ChimeraQueryTrustFetchedCollectionError = ChimeraQueryTrustFetchedCollectionError;
1706
+ exports.ChimeraQueryTrustIdMismatchError = ChimeraQueryTrustIdMismatchError;
1707
+ exports.ChimeraWeakValueMap = ChimeraWeakValueMap;
1708
+ exports.chimeraCreateConjunction = chimeraCreateConjunction;
1709
+ exports.chimeraCreateNot = chimeraCreateNot;
1710
+ exports.chimeraCreateOperator = chimeraCreateOperator;
1711
+ exports.chimeraCreateOrderBy = chimeraCreateOrderBy;
1712
+ exports.chimeraIsConjunction = chimeraIsConjunction;
1713
+ exports.chimeraIsOperator = chimeraIsOperator;
1714
+ exports.createChimeraEntityStore = createChimeraEntityStore;
1715
+ //# sourceMappingURL=index.cjs.map