@oimdb/core 1.5.0 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +575 -69
- package/dist/index.cjs +1849 -1535
- package/dist/index.d.cts +587 -507
- package/dist/index.d.ts +587 -507
- package/dist/index.js +1833 -1530
- package/llms.txt +429 -0
- package/package.json +4 -2
package/dist/index.cjs
CHANGED
|
@@ -29,13 +29,19 @@ __export(index_exports, {
|
|
|
29
29
|
OIMCollection: () => OIMCollection,
|
|
30
30
|
OIMCollectionByPkSelector: () => OIMCollectionByPkSelector,
|
|
31
31
|
OIMCollectionByPksSelector: () => OIMCollectionByPksSelector,
|
|
32
|
-
|
|
32
|
+
OIMCollectionChangedFields: () => OIMCollectionChangedFields,
|
|
33
|
+
OIMCollectionIndexFactory: () => OIMCollectionIndexFactory,
|
|
34
|
+
OIMCollectionIndexManualOrderedArrayBased: () => OIMCollectionIndexManualOrderedArrayBased,
|
|
35
|
+
OIMCollectionOrderedListCommandStream: () => OIMCollectionOrderedListCommandStream,
|
|
36
|
+
OIMCollectionSelectors: () => OIMCollectionSelectors,
|
|
33
37
|
OIMCollectionStore: () => OIMCollectionStore,
|
|
34
38
|
OIMCollectionStoreMapDriven: () => OIMCollectionStoreMapDriven,
|
|
35
39
|
OIMComparatorFactory: () => OIMComparatorFactory,
|
|
36
|
-
|
|
40
|
+
OIMComputeRuntime: () => OIMComputeRuntime,
|
|
37
41
|
OIMComputed: () => OIMComputed,
|
|
38
42
|
OIMDBSettings: () => OIMDBSettings,
|
|
43
|
+
OIMDerivedCollectionIndexArrayBased: () => OIMDerivedCollectionIndexArrayBased,
|
|
44
|
+
OIMDerivedCollectionIndexSetBased: () => OIMDerivedCollectionIndexSetBased,
|
|
39
45
|
OIMEffect: () => OIMEffect,
|
|
40
46
|
OIMEffectDependencyComputed: () => OIMEffectDependencyComputed,
|
|
41
47
|
OIMEffectDependencyKeyed: () => OIMEffectDependencyKeyed,
|
|
@@ -53,6 +59,7 @@ __export(index_exports, {
|
|
|
53
59
|
OIMEventQueueSchedulerImmediate: () => OIMEventQueueSchedulerImmediate,
|
|
54
60
|
OIMEventQueueSchedulerMicrotask: () => OIMEventQueueSchedulerMicrotask,
|
|
55
61
|
OIMEventQueueSchedulerTimeout: () => OIMEventQueueSchedulerTimeout,
|
|
62
|
+
OIMIndex: () => OIMIndex,
|
|
56
63
|
OIMIndexArrayBased: () => OIMIndexArrayBased,
|
|
57
64
|
OIMIndexComparatorFactory: () => OIMIndexComparatorFactory,
|
|
58
65
|
OIMIndexManualArrayBased: () => OIMIndexManualArrayBased,
|
|
@@ -74,16 +81,20 @@ __export(index_exports, {
|
|
|
74
81
|
OIMObjectStoreRecordDriven: () => OIMObjectStoreRecordDriven,
|
|
75
82
|
OIMObjectValueByKeySelector: () => OIMObjectValueByKeySelector,
|
|
76
83
|
OIMObjectValuesByKeysSelector: () => OIMObjectValuesByKeysSelector,
|
|
77
|
-
|
|
84
|
+
OIMOrderedListCommandStream: () => OIMOrderedListCommandStream,
|
|
78
85
|
OIMPkSelectorFactory: () => OIMPkSelectorFactory,
|
|
79
|
-
OIMRICollection: () => OIMRICollection,
|
|
80
86
|
OIMReactiveCollection: () => OIMReactiveCollection,
|
|
87
|
+
OIMReactiveCollectionIndexManualArrayBased: () => OIMReactiveCollectionIndexManualArrayBased,
|
|
88
|
+
OIMReactiveCollectionIndexManualSetBased: () => OIMReactiveCollectionIndexManualSetBased,
|
|
89
|
+
OIMReactiveIndex: () => OIMReactiveIndex,
|
|
81
90
|
OIMReactiveIndexArrayBased: () => OIMReactiveIndexArrayBased,
|
|
82
91
|
OIMReactiveIndexManualArrayBased: () => OIMReactiveIndexManualArrayBased,
|
|
83
92
|
OIMReactiveIndexManualSetBased: () => OIMReactiveIndexManualSetBased,
|
|
84
93
|
OIMReactiveIndexSetBased: () => OIMReactiveIndexSetBased,
|
|
85
94
|
OIMReactiveObject: () => OIMReactiveObject,
|
|
86
|
-
OIMSelector: () => OIMSelector
|
|
95
|
+
OIMSelector: () => OIMSelector,
|
|
96
|
+
createOIMCollectionContext: () => createOIMCollectionContext,
|
|
97
|
+
createOIMCollectionIndexFactory: () => createOIMCollectionIndexFactory
|
|
87
98
|
});
|
|
88
99
|
module.exports = __toCommonJS(index_exports);
|
|
89
100
|
|
|
@@ -91,14 +102,6 @@ module.exports = __toCommonJS(index_exports);
|
|
|
91
102
|
var OIMCollectionStore = class {
|
|
92
103
|
};
|
|
93
104
|
|
|
94
|
-
// src/abstract/OIMIndexStoreSetBased.ts
|
|
95
|
-
var OIMIndexStoreSetBased = class {
|
|
96
|
-
};
|
|
97
|
-
|
|
98
|
-
// src/abstract/OIMIndexStoreArrayBased.ts
|
|
99
|
-
var OIMIndexStoreArrayBased = class {
|
|
100
|
-
};
|
|
101
|
-
|
|
102
105
|
// src/core/OIMEventEmitter.ts
|
|
103
106
|
var OIMEventEmitter = class {
|
|
104
107
|
constructor() {
|
|
@@ -204,7 +207,94 @@ var OIMEventEmitter = class {
|
|
|
204
207
|
}
|
|
205
208
|
};
|
|
206
209
|
|
|
207
|
-
// src/
|
|
210
|
+
// src/enums/EOIMIndexEventType.ts
|
|
211
|
+
var EOIMIndexEventType = /* @__PURE__ */ ((EOIMIndexEventType2) => {
|
|
212
|
+
EOIMIndexEventType2[EOIMIndexEventType2["UPDATE"] = 0] = "UPDATE";
|
|
213
|
+
return EOIMIndexEventType2;
|
|
214
|
+
})(EOIMIndexEventType || {});
|
|
215
|
+
|
|
216
|
+
// src/abstract/OIMIndex.ts
|
|
217
|
+
var OIMIndex = class {
|
|
218
|
+
constructor(store, comparePks) {
|
|
219
|
+
this.emitter = new OIMEventEmitter();
|
|
220
|
+
this.store = store;
|
|
221
|
+
this.comparePks = comparePks;
|
|
222
|
+
}
|
|
223
|
+
hasKey(key) {
|
|
224
|
+
return this.store.getOneByKey(key) !== void 0;
|
|
225
|
+
}
|
|
226
|
+
getKeys() {
|
|
227
|
+
return this.store.getAllKeys();
|
|
228
|
+
}
|
|
229
|
+
getKeySize(key) {
|
|
230
|
+
const bucket = this.store.getOneByKey(key);
|
|
231
|
+
return bucket ? this.getBucketSize(bucket) : 0;
|
|
232
|
+
}
|
|
233
|
+
get size() {
|
|
234
|
+
return this.store.countAll();
|
|
235
|
+
}
|
|
236
|
+
get isEmpty() {
|
|
237
|
+
return this.store.countAll() === 0;
|
|
238
|
+
}
|
|
239
|
+
getEntitiesByKey(key) {
|
|
240
|
+
const bucket = this.store.getOneByKey(key);
|
|
241
|
+
return bucket ? this.slotsToEntities(bucket) : [];
|
|
242
|
+
}
|
|
243
|
+
getEntitiesByKeys(keys) {
|
|
244
|
+
const result = /* @__PURE__ */ new Map();
|
|
245
|
+
const bucketsByKey = this.store.getManyByKeys(keys);
|
|
246
|
+
for (const [key, bucket] of bucketsByKey) {
|
|
247
|
+
result.set(key, this.slotsToEntities(bucket));
|
|
248
|
+
}
|
|
249
|
+
return result;
|
|
250
|
+
}
|
|
251
|
+
getMetrics() {
|
|
252
|
+
let totalPks = 0;
|
|
253
|
+
let maxBucketSize = 0;
|
|
254
|
+
let minBucketSize = Infinity;
|
|
255
|
+
const all = this.store.getAll();
|
|
256
|
+
for (const bucket of all.values()) {
|
|
257
|
+
const size = this.getBucketSize(bucket);
|
|
258
|
+
totalPks += size;
|
|
259
|
+
maxBucketSize = Math.max(maxBucketSize, size);
|
|
260
|
+
minBucketSize = Math.min(minBucketSize, size);
|
|
261
|
+
}
|
|
262
|
+
return {
|
|
263
|
+
totalKeys: all.size,
|
|
264
|
+
totalPks,
|
|
265
|
+
averagePksPerKey: all.size > 0 ? totalPks / all.size : 0,
|
|
266
|
+
maxBucketSize: maxBucketSize === -Infinity ? 0 : maxBucketSize,
|
|
267
|
+
minBucketSize: minBucketSize === Infinity ? 0 : minBucketSize
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
destroy() {
|
|
271
|
+
this.emitter.offAll();
|
|
272
|
+
this.store.clear();
|
|
273
|
+
}
|
|
274
|
+
emitUpdate(keys) {
|
|
275
|
+
this.emitter.emit(0 /* UPDATE */, { keys });
|
|
276
|
+
}
|
|
277
|
+
emitUpdateOne(key) {
|
|
278
|
+
this.emitUpdate([key]);
|
|
279
|
+
}
|
|
280
|
+
slotsToEntities(slots) {
|
|
281
|
+
const entities = [];
|
|
282
|
+
for (const slot of slots) {
|
|
283
|
+
if (slot.item !== void 0) entities.push(slot.item);
|
|
284
|
+
}
|
|
285
|
+
return entities;
|
|
286
|
+
}
|
|
287
|
+
};
|
|
288
|
+
|
|
289
|
+
// src/abstract/OIMIndexStoreSetBased.ts
|
|
290
|
+
var OIMIndexStoreSetBased = class {
|
|
291
|
+
};
|
|
292
|
+
|
|
293
|
+
// src/abstract/OIMIndexStoreArrayBased.ts
|
|
294
|
+
var OIMIndexStoreArrayBased = class {
|
|
295
|
+
};
|
|
296
|
+
|
|
297
|
+
// src/enums/EOIMEventQueueSchedulerEventType.ts
|
|
208
298
|
var EOIMEventQueueSchedulerEventType = /* @__PURE__ */ ((EOIMEventQueueSchedulerEventType2) => {
|
|
209
299
|
EOIMEventQueueSchedulerEventType2[EOIMEventQueueSchedulerEventType2["FLUSH"] = 0] = "FLUSH";
|
|
210
300
|
return EOIMEventQueueSchedulerEventType2;
|
|
@@ -229,12 +319,6 @@ var OIMEventQueueScheduler = class {
|
|
|
229
319
|
}
|
|
230
320
|
};
|
|
231
321
|
|
|
232
|
-
// src/enum/EOIMIndexEventType.ts
|
|
233
|
-
var EOIMIndexEventType = /* @__PURE__ */ ((EOIMIndexEventType2) => {
|
|
234
|
-
EOIMIndexEventType2[EOIMIndexEventType2["UPDATE"] = 0] = "UPDATE";
|
|
235
|
-
return EOIMIndexEventType2;
|
|
236
|
-
})(EOIMIndexEventType || {});
|
|
237
|
-
|
|
238
322
|
// src/core/OIMIndexStoreMapDrivenSetBased.ts
|
|
239
323
|
var OIMIndexStoreMapDrivenSetBased = class extends OIMIndexStoreSetBased {
|
|
240
324
|
constructor() {
|
|
@@ -280,17 +364,20 @@ var OIMIndexStoreMapDrivenSetBased = class extends OIMIndexStoreSetBased {
|
|
|
280
364
|
};
|
|
281
365
|
|
|
282
366
|
// src/abstract/OIMIndexSetBased.ts
|
|
283
|
-
var OIMIndexSetBased = class {
|
|
367
|
+
var OIMIndexSetBased = class extends OIMIndex {
|
|
284
368
|
constructor(options = {}) {
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
369
|
+
super(
|
|
370
|
+
options.store ?? new OIMIndexStoreMapDrivenSetBased(),
|
|
371
|
+
options.comparePks
|
|
372
|
+
);
|
|
373
|
+
}
|
|
374
|
+
getBucketSize(bucket) {
|
|
375
|
+
return bucket.size;
|
|
376
|
+
}
|
|
377
|
+
getPksByKey(key) {
|
|
378
|
+
const slotsSet = this.store.getOneByKey(key);
|
|
379
|
+
return slotsSet ? this.slotsToPks(slotsSet) : /* @__PURE__ */ new Set();
|
|
290
380
|
}
|
|
291
|
-
/**
|
|
292
|
-
* Get primary keys for multiple index keys
|
|
293
|
-
*/
|
|
294
381
|
getPksByKeys(keys) {
|
|
295
382
|
const result = /* @__PURE__ */ new Map();
|
|
296
383
|
const slotsByKey = this.store.getManyByKeys(keys);
|
|
@@ -299,112 +386,25 @@ var OIMIndexSetBased = class {
|
|
|
299
386
|
}
|
|
300
387
|
return result;
|
|
301
388
|
}
|
|
302
|
-
setSlotResolver(resolveSlot) {
|
|
303
|
-
this.resolveSlot = resolveSlot;
|
|
304
|
-
const allSlots = this.store.getAll();
|
|
305
|
-
for (const [key, slots] of allSlots) {
|
|
306
|
-
this.store.setOneByKey(
|
|
307
|
-
key,
|
|
308
|
-
this.resolveSlots(this.slotsToPks(slots))
|
|
309
|
-
);
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
/**
|
|
313
|
-
* @deprecated Use getPksByKey instead
|
|
314
|
-
* Get primary keys for a specific index key
|
|
315
|
-
*/
|
|
316
|
-
getPks(key) {
|
|
317
|
-
return this.getPksByKey(key);
|
|
318
|
-
}
|
|
319
|
-
/**
|
|
320
|
-
* Get primary keys for a specific index key
|
|
321
|
-
*/
|
|
322
|
-
getPksByKey(key) {
|
|
323
|
-
const slotsSet = this.store.getOneByKey(key);
|
|
324
|
-
return slotsSet ? this.slotsToPks(slotsSet) : /* @__PURE__ */ new Set();
|
|
325
|
-
}
|
|
326
389
|
getSlotsByKey(key) {
|
|
327
|
-
|
|
328
|
-
return slotsSet ? slotsSet : /* @__PURE__ */ new Set();
|
|
390
|
+
return this.store.getOneByKey(key) ?? /* @__PURE__ */ new Set();
|
|
329
391
|
}
|
|
330
392
|
getSlotsByKeys(keys) {
|
|
331
393
|
return this.store.getManyByKeys(keys);
|
|
332
394
|
}
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
return this.store.getOneByKey(key) !== void 0;
|
|
338
|
-
}
|
|
339
|
-
/**
|
|
340
|
-
* Get all index keys
|
|
341
|
-
*/
|
|
342
|
-
getKeys() {
|
|
343
|
-
return this.store.getAllKeys();
|
|
344
|
-
}
|
|
345
|
-
/**
|
|
346
|
-
* Get the number of primary keys for a specific index key
|
|
347
|
-
*/
|
|
348
|
-
getKeySize(key) {
|
|
349
|
-
const slotsSet = this.store.getOneByKey(key);
|
|
350
|
-
return slotsSet ? slotsSet.size : 0;
|
|
351
|
-
}
|
|
352
|
-
/**
|
|
353
|
-
* Get total number of index keys
|
|
354
|
-
*/
|
|
355
|
-
get size() {
|
|
356
|
-
return this.store.countAll();
|
|
357
|
-
}
|
|
358
|
-
/**
|
|
359
|
-
* Check if the index is empty
|
|
360
|
-
*/
|
|
361
|
-
get isEmpty() {
|
|
362
|
-
return this.store.countAll() === 0;
|
|
363
|
-
}
|
|
364
|
-
/**
|
|
365
|
-
* Get performance metrics for monitoring and debugging
|
|
366
|
-
*/
|
|
367
|
-
getMetrics() {
|
|
368
|
-
let totalPks = 0;
|
|
369
|
-
let maxBucketSize = 0;
|
|
370
|
-
let minBucketSize = Infinity;
|
|
371
|
-
const allPks = this.store.getAll();
|
|
372
|
-
for (const slotsSet of allPks.values()) {
|
|
373
|
-
totalPks += slotsSet.size;
|
|
374
|
-
maxBucketSize = Math.max(maxBucketSize, slotsSet.size);
|
|
375
|
-
minBucketSize = Math.min(minBucketSize, slotsSet.size);
|
|
376
|
-
}
|
|
377
|
-
return {
|
|
378
|
-
totalKeys: allPks.size,
|
|
379
|
-
totalPks,
|
|
380
|
-
averagePksPerKey: allPks.size > 0 ? totalPks / allPks.size : 0,
|
|
381
|
-
maxBucketSize: maxBucketSize === -Infinity ? 0 : maxBucketSize,
|
|
382
|
-
minBucketSize: minBucketSize === Infinity ? 0 : minBucketSize
|
|
383
|
-
};
|
|
384
|
-
}
|
|
385
|
-
/**
|
|
386
|
-
* Clean up event listeners when index is no longer needed
|
|
387
|
-
*/
|
|
388
|
-
destroy() {
|
|
389
|
-
this.emitter.offAll();
|
|
390
|
-
this.store.clear();
|
|
391
|
-
}
|
|
392
|
-
/**
|
|
393
|
-
* Set primary keys for a specific index key with optional comparison.
|
|
394
|
-
* If comparator is provided and returns true (no changes), skip the update.
|
|
395
|
-
*/
|
|
396
|
-
setPksWithComparison(key, newPks) {
|
|
397
|
-
return this.setSlotsWithComparison(key, this.resolveSlots(newPks));
|
|
395
|
+
slotsToPks(slots) {
|
|
396
|
+
const pks = /* @__PURE__ */ new Set();
|
|
397
|
+
for (const slot of slots) pks.add(slot.pk);
|
|
398
|
+
return pks;
|
|
398
399
|
}
|
|
399
400
|
setSlotsWithComparison(key, newSlots) {
|
|
400
401
|
if (this.comparePks) {
|
|
401
402
|
const existingSlotsSet = this.store.getOneByKey(key);
|
|
402
403
|
if (existingSlotsSet && existingSlotsSet.size === newSlots.size) {
|
|
403
|
-
|
|
404
|
-
this.slotsToPks(existingSlotsSet)
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
if (this.comparePks(existingPksArray, newPksArray)) {
|
|
404
|
+
if (this.comparePks(
|
|
405
|
+
Array.from(this.slotsToPks(existingSlotsSet)),
|
|
406
|
+
Array.from(this.slotsToPks(newSlots))
|
|
407
|
+
)) {
|
|
408
408
|
return false;
|
|
409
409
|
}
|
|
410
410
|
} else if (!existingSlotsSet && newSlots.size === 0) {
|
|
@@ -414,38 +414,6 @@ var OIMIndexSetBased = class {
|
|
|
414
414
|
this.store.setOneByKey(key, newSlots);
|
|
415
415
|
return true;
|
|
416
416
|
}
|
|
417
|
-
resolveSlots(pks) {
|
|
418
|
-
const slots = /* @__PURE__ */ new Set();
|
|
419
|
-
for (const pk of pks) slots.add(this.getOrCreateSlot(pk));
|
|
420
|
-
return slots;
|
|
421
|
-
}
|
|
422
|
-
getOrCreateSlot(pk) {
|
|
423
|
-
const resolved = this.resolveSlot?.(pk);
|
|
424
|
-
if (resolved) return resolved;
|
|
425
|
-
let fallback = this.fallbackSlots.get(pk);
|
|
426
|
-
if (!fallback) {
|
|
427
|
-
fallback = { pk, item: void 0 };
|
|
428
|
-
this.fallbackSlots.set(pk, fallback);
|
|
429
|
-
}
|
|
430
|
-
return fallback;
|
|
431
|
-
}
|
|
432
|
-
slotsToPks(slots) {
|
|
433
|
-
const pks = /* @__PURE__ */ new Set();
|
|
434
|
-
for (const slot of slots) pks.add(slot.pk);
|
|
435
|
-
return pks;
|
|
436
|
-
}
|
|
437
|
-
/**
|
|
438
|
-
* Emit update event with changed keys
|
|
439
|
-
*/
|
|
440
|
-
emitUpdate(keys) {
|
|
441
|
-
this.emitter.emit(0 /* UPDATE */, { keys });
|
|
442
|
-
}
|
|
443
|
-
/**
|
|
444
|
-
* Emit update event for a single key (fast-path override point).
|
|
445
|
-
*/
|
|
446
|
-
emitUpdateOne(key) {
|
|
447
|
-
this.emitUpdate([key]);
|
|
448
|
-
}
|
|
449
417
|
};
|
|
450
418
|
|
|
451
419
|
// src/core/OIMIndexStoreMapDrivenArrayBased.ts
|
|
@@ -493,17 +461,20 @@ var OIMIndexStoreMapDrivenArrayBased = class extends OIMIndexStoreArrayBased {
|
|
|
493
461
|
};
|
|
494
462
|
|
|
495
463
|
// src/abstract/OIMIndexArrayBased.ts
|
|
496
|
-
var OIMIndexArrayBased = class {
|
|
464
|
+
var OIMIndexArrayBased = class extends OIMIndex {
|
|
497
465
|
constructor(options = {}) {
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
466
|
+
super(
|
|
467
|
+
options.store ?? new OIMIndexStoreMapDrivenArrayBased(),
|
|
468
|
+
options.comparePks
|
|
469
|
+
);
|
|
470
|
+
}
|
|
471
|
+
getBucketSize(bucket) {
|
|
472
|
+
return bucket.length;
|
|
473
|
+
}
|
|
474
|
+
getPksByKey(key) {
|
|
475
|
+
const slotsArray = this.store.getOneByKey(key);
|
|
476
|
+
return slotsArray ? this.slotsToPks(slotsArray) : [];
|
|
503
477
|
}
|
|
504
|
-
/**
|
|
505
|
-
* Get primary keys for multiple index keys
|
|
506
|
-
*/
|
|
507
478
|
getPksByKeys(keys) {
|
|
508
479
|
const result = /* @__PURE__ */ new Map();
|
|
509
480
|
const slotsByKey = this.store.getManyByKeys(keys);
|
|
@@ -512,95 +483,17 @@ var OIMIndexArrayBased = class {
|
|
|
512
483
|
}
|
|
513
484
|
return result;
|
|
514
485
|
}
|
|
515
|
-
setSlotResolver(resolveSlot) {
|
|
516
|
-
this.resolveSlot = resolveSlot;
|
|
517
|
-
const allSlots = this.store.getAll();
|
|
518
|
-
for (const [key, slots] of allSlots) {
|
|
519
|
-
this.store.setOneByKey(
|
|
520
|
-
key,
|
|
521
|
-
slots.map((slot) => this.getOrCreateSlot(slot.pk))
|
|
522
|
-
);
|
|
523
|
-
}
|
|
524
|
-
}
|
|
525
|
-
/**
|
|
526
|
-
* Get primary keys for a specific index key
|
|
527
|
-
*/
|
|
528
|
-
getPksByKey(key) {
|
|
529
|
-
const slotsArray = this.store.getOneByKey(key);
|
|
530
|
-
return slotsArray ? this.slotsToPks(slotsArray) : [];
|
|
531
|
-
}
|
|
532
486
|
getSlotsByKey(key) {
|
|
533
|
-
|
|
534
|
-
return slotsArray ? slotsArray : [];
|
|
487
|
+
return this.store.getOneByKey(key) ?? [];
|
|
535
488
|
}
|
|
536
489
|
getSlotsByKeys(keys) {
|
|
537
490
|
return this.store.getManyByKeys(keys);
|
|
538
491
|
}
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
return
|
|
544
|
-
}
|
|
545
|
-
/**
|
|
546
|
-
* Get all index keys
|
|
547
|
-
*/
|
|
548
|
-
getKeys() {
|
|
549
|
-
return this.store.getAllKeys();
|
|
550
|
-
}
|
|
551
|
-
/**
|
|
552
|
-
* Get the number of primary keys for a specific index key
|
|
553
|
-
*/
|
|
554
|
-
getKeySize(key) {
|
|
555
|
-
const slotsArray = this.store.getOneByKey(key);
|
|
556
|
-
return slotsArray ? slotsArray.length : 0;
|
|
557
|
-
}
|
|
558
|
-
/**
|
|
559
|
-
* Get total number of index keys
|
|
560
|
-
*/
|
|
561
|
-
get size() {
|
|
562
|
-
return this.store.countAll();
|
|
563
|
-
}
|
|
564
|
-
/**
|
|
565
|
-
* Check if the index is empty
|
|
566
|
-
*/
|
|
567
|
-
get isEmpty() {
|
|
568
|
-
return this.store.countAll() === 0;
|
|
569
|
-
}
|
|
570
|
-
/**
|
|
571
|
-
* Get performance metrics for monitoring and debugging
|
|
572
|
-
*/
|
|
573
|
-
getMetrics() {
|
|
574
|
-
let totalPks = 0;
|
|
575
|
-
let maxBucketSize = 0;
|
|
576
|
-
let minBucketSize = Infinity;
|
|
577
|
-
const allPks = this.store.getAll();
|
|
578
|
-
for (const slotsArray of allPks.values()) {
|
|
579
|
-
totalPks += slotsArray.length;
|
|
580
|
-
maxBucketSize = Math.max(maxBucketSize, slotsArray.length);
|
|
581
|
-
minBucketSize = Math.min(minBucketSize, slotsArray.length);
|
|
582
|
-
}
|
|
583
|
-
return {
|
|
584
|
-
totalKeys: allPks.size,
|
|
585
|
-
totalPks,
|
|
586
|
-
averagePksPerKey: allPks.size > 0 ? totalPks / allPks.size : 0,
|
|
587
|
-
maxBucketSize: maxBucketSize === -Infinity ? 0 : maxBucketSize,
|
|
588
|
-
minBucketSize: minBucketSize === Infinity ? 0 : minBucketSize
|
|
589
|
-
};
|
|
590
|
-
}
|
|
591
|
-
/**
|
|
592
|
-
* Clean up event listeners when index is no longer needed
|
|
593
|
-
*/
|
|
594
|
-
destroy() {
|
|
595
|
-
this.emitter.offAll();
|
|
596
|
-
this.store.clear();
|
|
597
|
-
}
|
|
598
|
-
/**
|
|
599
|
-
* Set primary keys for a specific index key with optional comparison.
|
|
600
|
-
* If comparator is provided and returns true (no changes), skip the update.
|
|
601
|
-
*/
|
|
602
|
-
setPksWithComparison(key, newPks) {
|
|
603
|
-
return this.setSlotsWithComparison(key, this.resolveSlots(newPks));
|
|
492
|
+
slotsToPks(slots) {
|
|
493
|
+
const pks = [];
|
|
494
|
+
pks.length = slots.length;
|
|
495
|
+
for (let i = 0; i < slots.length; i++) pks[i] = slots[i].pk;
|
|
496
|
+
return pks;
|
|
604
497
|
}
|
|
605
498
|
setSlotsWithComparison(key, newSlots) {
|
|
606
499
|
if (this.comparePks) {
|
|
@@ -619,45 +512,9 @@ var OIMIndexArrayBased = class {
|
|
|
619
512
|
this.store.setOneByKey(key, newSlots);
|
|
620
513
|
return true;
|
|
621
514
|
}
|
|
622
|
-
resolveSlots(pks) {
|
|
623
|
-
const slots = [];
|
|
624
|
-
slots.length = pks.length;
|
|
625
|
-
for (let i = 0; i < pks.length; i++) {
|
|
626
|
-
slots[i] = this.getOrCreateSlot(pks[i]);
|
|
627
|
-
}
|
|
628
|
-
return slots;
|
|
629
|
-
}
|
|
630
|
-
getOrCreateSlot(pk) {
|
|
631
|
-
const resolved = this.resolveSlot?.(pk);
|
|
632
|
-
if (resolved) return resolved;
|
|
633
|
-
let fallback = this.fallbackSlots.get(pk);
|
|
634
|
-
if (!fallback) {
|
|
635
|
-
fallback = { pk, item: void 0 };
|
|
636
|
-
this.fallbackSlots.set(pk, fallback);
|
|
637
|
-
}
|
|
638
|
-
return fallback;
|
|
639
|
-
}
|
|
640
|
-
slotsToPks(slots) {
|
|
641
|
-
const pks = [];
|
|
642
|
-
pks.length = slots.length;
|
|
643
|
-
for (let i = 0; i < slots.length; i++) pks[i] = slots[i].pk;
|
|
644
|
-
return pks;
|
|
645
|
-
}
|
|
646
|
-
/**
|
|
647
|
-
* Emit update event with changed keys
|
|
648
|
-
*/
|
|
649
|
-
emitUpdate(keys) {
|
|
650
|
-
this.emitter.emit(0 /* UPDATE */, { keys });
|
|
651
|
-
}
|
|
652
|
-
/**
|
|
653
|
-
* Emit update event for a single key (fast-path override point).
|
|
654
|
-
*/
|
|
655
|
-
emitUpdateOne(key) {
|
|
656
|
-
this.emitUpdate([key]);
|
|
657
|
-
}
|
|
658
515
|
};
|
|
659
516
|
|
|
660
|
-
// src/
|
|
517
|
+
// src/enums/EOIMEventQueueEventType.ts
|
|
661
518
|
var EOIMEventQueueEventType = /* @__PURE__ */ ((EOIMEventQueueEventType2) => {
|
|
662
519
|
EOIMEventQueueEventType2[EOIMEventQueueEventType2["AFTER_FLUSH"] = 0] = "AFTER_FLUSH";
|
|
663
520
|
EOIMEventQueueEventType2[EOIMEventQueueEventType2["BEFORE_FLUSH"] = 1] = "BEFORE_FLUSH";
|
|
@@ -911,23 +768,17 @@ var OIMUpdateEventEmitter = class {
|
|
|
911
768
|
}
|
|
912
769
|
};
|
|
913
770
|
|
|
914
|
-
// src/abstract/
|
|
915
|
-
var
|
|
771
|
+
// src/abstract/OIMReactiveIndex.ts
|
|
772
|
+
var OIMReactiveIndex = class {
|
|
916
773
|
constructor(queue, createIndex) {
|
|
917
774
|
this.updateEmitter = new OIMUpdateEventEmitter(queue);
|
|
918
775
|
this.index = createIndex(this.updateEmitter);
|
|
919
776
|
}
|
|
920
|
-
|
|
921
|
-
return this.index.
|
|
922
|
-
}
|
|
923
|
-
getPksByKeys(keys) {
|
|
924
|
-
return this.index.getPksByKeys(keys);
|
|
925
|
-
}
|
|
926
|
-
getSlotsByKey(key) {
|
|
927
|
-
return this.index.getSlotsByKey(key);
|
|
777
|
+
getEntitiesByKey(key) {
|
|
778
|
+
return this.index.getEntitiesByKey(key);
|
|
928
779
|
}
|
|
929
|
-
|
|
930
|
-
return this.index.
|
|
780
|
+
getEntitiesByKeys(keys) {
|
|
781
|
+
return this.index.getEntitiesByKeys(keys);
|
|
931
782
|
}
|
|
932
783
|
hasKey(key) {
|
|
933
784
|
return this.index.hasKey(key);
|
|
@@ -974,11 +825,10 @@ var OIMReactiveIndexSetBased = class {
|
|
|
974
825
|
}
|
|
975
826
|
};
|
|
976
827
|
|
|
977
|
-
// src/abstract/
|
|
978
|
-
var
|
|
828
|
+
// src/abstract/OIMReactiveIndexSetBased.ts
|
|
829
|
+
var OIMReactiveIndexSetBased = class extends OIMReactiveIndex {
|
|
979
830
|
constructor(queue, createIndex) {
|
|
980
|
-
|
|
981
|
-
this.index = createIndex(this.updateEmitter);
|
|
831
|
+
super(queue, createIndex);
|
|
982
832
|
}
|
|
983
833
|
getPksByKey(key) {
|
|
984
834
|
return this.index.getPksByKey(key);
|
|
@@ -992,48 +842,24 @@ var OIMReactiveIndexArrayBased = class {
|
|
|
992
842
|
getSlotsByKeys(keys) {
|
|
993
843
|
return this.index.getSlotsByKeys(keys);
|
|
994
844
|
}
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
getKeySize(key) {
|
|
1002
|
-
return this.index.getKeySize(key);
|
|
1003
|
-
}
|
|
1004
|
-
get size() {
|
|
1005
|
-
return this.index.size;
|
|
1006
|
-
}
|
|
1007
|
-
get isEmpty() {
|
|
1008
|
-
return this.index.isEmpty;
|
|
1009
|
-
}
|
|
1010
|
-
getMetrics() {
|
|
1011
|
-
return this.index.getMetrics();
|
|
1012
|
-
}
|
|
1013
|
-
subscribeOnKey(key, handler) {
|
|
1014
|
-
return this.updateEmitter.subscribeOnKey(key, handler);
|
|
1015
|
-
}
|
|
1016
|
-
subscribeOnKeys(keys, handler) {
|
|
1017
|
-
return this.updateEmitter.subscribeOnKeys(keys, handler);
|
|
1018
|
-
}
|
|
1019
|
-
unsubscribeFromKey(key, handler) {
|
|
1020
|
-
this.updateEmitter.unsubscribeFromKey(key, handler);
|
|
1021
|
-
}
|
|
1022
|
-
unsubscribeFromKeys(keys, handler) {
|
|
1023
|
-
this.updateEmitter.unsubscribeFromKeys(keys, handler);
|
|
845
|
+
};
|
|
846
|
+
|
|
847
|
+
// src/abstract/OIMReactiveIndexArrayBased.ts
|
|
848
|
+
var OIMReactiveIndexArrayBased = class extends OIMReactiveIndex {
|
|
849
|
+
constructor(queue, createIndex) {
|
|
850
|
+
super(queue, createIndex);
|
|
1024
851
|
}
|
|
1025
|
-
|
|
1026
|
-
return this.
|
|
852
|
+
getPksByKey(key) {
|
|
853
|
+
return this.index.getPksByKey(key);
|
|
1027
854
|
}
|
|
1028
|
-
|
|
1029
|
-
return this.
|
|
855
|
+
getPksByKeys(keys) {
|
|
856
|
+
return this.index.getPksByKeys(keys);
|
|
1030
857
|
}
|
|
1031
|
-
|
|
1032
|
-
return this.
|
|
858
|
+
getSlotsByKey(key) {
|
|
859
|
+
return this.index.getSlotsByKey(key);
|
|
1033
860
|
}
|
|
1034
|
-
|
|
1035
|
-
this.
|
|
1036
|
-
this.index.destroy();
|
|
861
|
+
getSlotsByKeys(keys) {
|
|
862
|
+
return this.index.getSlotsByKeys(keys);
|
|
1037
863
|
}
|
|
1038
864
|
};
|
|
1039
865
|
|
|
@@ -1058,14 +884,20 @@ var OIMCollectionStoreMapDriven = class extends OIMCollectionStore {
|
|
|
1058
884
|
const slot = this.slots.get(pk);
|
|
1059
885
|
if (slot) {
|
|
1060
886
|
slot.item = entity;
|
|
887
|
+
return slot;
|
|
1061
888
|
} else {
|
|
1062
|
-
|
|
889
|
+
const nextSlot = { pk, item: entity };
|
|
890
|
+
this.slots.set(pk, nextSlot);
|
|
891
|
+
return nextSlot;
|
|
1063
892
|
}
|
|
1064
893
|
}
|
|
1065
894
|
setManyByPks(pks, entities) {
|
|
895
|
+
const slots = [];
|
|
896
|
+
slots.length = pks.length;
|
|
1066
897
|
for (let i = 0; i < pks.length; i++) {
|
|
1067
|
-
this.setOneByPk(pks[i], entities[i]);
|
|
898
|
+
slots[i] = this.setOneByPk(pks[i], entities[i]);
|
|
1068
899
|
}
|
|
900
|
+
return slots;
|
|
1069
901
|
}
|
|
1070
902
|
getSlotByPk(pk) {
|
|
1071
903
|
return this.slots.get(pk);
|
|
@@ -1145,7 +977,7 @@ var OIMEntityUpdaterFactory = class {
|
|
|
1145
977
|
}
|
|
1146
978
|
};
|
|
1147
979
|
|
|
1148
|
-
// src/
|
|
980
|
+
// src/enums/EOIMCollectionEventType.ts
|
|
1149
981
|
var EOIMCollectionEventType = /* @__PURE__ */ ((EOIMCollectionEventType2) => {
|
|
1150
982
|
EOIMCollectionEventType2[EOIMCollectionEventType2["UPDATE"] = 0] = "UPDATE";
|
|
1151
983
|
return EOIMCollectionEventType2;
|
|
@@ -1175,18 +1007,23 @@ var OIMCollection = class {
|
|
|
1175
1007
|
return this.store.getAllSlots();
|
|
1176
1008
|
}
|
|
1177
1009
|
upsertOneByPk(pk, entity) {
|
|
1178
|
-
this.upsertOneWithoutNotificationsByPk(pk, entity);
|
|
1010
|
+
const slot = this.upsertOneWithoutNotificationsByPk(pk, entity);
|
|
1179
1011
|
this.emitter.emit(0 /* UPDATE */, { pks: [pk] });
|
|
1012
|
+
return slot;
|
|
1180
1013
|
}
|
|
1181
1014
|
upsertOne(entity) {
|
|
1182
|
-
const
|
|
1183
|
-
this.emitter.emit(0 /* UPDATE */, { pks: [pk] });
|
|
1015
|
+
const slot = this.upsertOneWithoutNotifications(entity);
|
|
1016
|
+
this.emitter.emit(0 /* UPDATE */, { pks: [slot.pk] });
|
|
1017
|
+
return slot;
|
|
1184
1018
|
}
|
|
1185
1019
|
upsertMany(entities) {
|
|
1186
|
-
|
|
1020
|
+
if (entities.length === 0) return [];
|
|
1021
|
+
const slots = entities.map(
|
|
1187
1022
|
(entity) => this.upsertOneWithoutNotifications(entity)
|
|
1188
1023
|
);
|
|
1024
|
+
const pks = slots.map((slot) => slot.pk);
|
|
1189
1025
|
this.emitter.emit(0 /* UPDATE */, { pks });
|
|
1026
|
+
return slots;
|
|
1190
1027
|
}
|
|
1191
1028
|
removeOne(entity) {
|
|
1192
1029
|
const pk = this.selectPk(entity);
|
|
@@ -1194,6 +1031,7 @@ var OIMCollection = class {
|
|
|
1194
1031
|
this.emitter.emit(0 /* UPDATE */, { pks: [pk] });
|
|
1195
1032
|
}
|
|
1196
1033
|
removeMany(entities) {
|
|
1034
|
+
if (entities.length === 0) return;
|
|
1197
1035
|
const pks = entities.map(this.selectPk);
|
|
1198
1036
|
this.store.removeManyByPks(pks);
|
|
1199
1037
|
this.emitter.emit(0 /* UPDATE */, { pks });
|
|
@@ -1203,6 +1041,7 @@ var OIMCollection = class {
|
|
|
1203
1041
|
this.emitter.emit(0 /* UPDATE */, { pks: [pk] });
|
|
1204
1042
|
}
|
|
1205
1043
|
removeManyByPks(pks) {
|
|
1044
|
+
if (pks.length === 0) return;
|
|
1206
1045
|
this.store.removeManyByPks(pks);
|
|
1207
1046
|
this.emitter.emit(0 /* UPDATE */, { pks });
|
|
1208
1047
|
}
|
|
@@ -1221,8 +1060,7 @@ var OIMCollection = class {
|
|
|
1221
1060
|
}
|
|
1222
1061
|
upsertOneWithoutNotifications(entity) {
|
|
1223
1062
|
const pk = this.selectPk(entity);
|
|
1224
|
-
this.upsertOneWithoutNotificationsByPk(pk, entity);
|
|
1225
|
-
return pk;
|
|
1063
|
+
return this.upsertOneWithoutNotificationsByPk(pk, entity);
|
|
1226
1064
|
}
|
|
1227
1065
|
upsertOneWithoutNotificationsByPk(pk, entity) {
|
|
1228
1066
|
if (!pk) {
|
|
@@ -1232,12 +1070,12 @@ var OIMCollection = class {
|
|
|
1232
1070
|
}
|
|
1233
1071
|
const existingEntity = this.store.getOneByPk(pk);
|
|
1234
1072
|
if (existingEntity) {
|
|
1235
|
-
this.store.setOneByPk(
|
|
1073
|
+
return this.store.setOneByPk(
|
|
1236
1074
|
pk,
|
|
1237
1075
|
this.updateEntity(entity, existingEntity)
|
|
1238
1076
|
);
|
|
1239
1077
|
} else {
|
|
1240
|
-
this.store.setOneByPk(pk, entity);
|
|
1078
|
+
return this.store.setOneByPk(pk, entity);
|
|
1241
1079
|
}
|
|
1242
1080
|
}
|
|
1243
1081
|
destroy() {
|
|
@@ -1298,24 +1136,29 @@ var OIMReactiveCollection = class extends OIMCollection {
|
|
|
1298
1136
|
};
|
|
1299
1137
|
}
|
|
1300
1138
|
upsertOneByPk(pk, entity) {
|
|
1301
|
-
this.upsertOneWithoutNotificationsByPk(pk, entity);
|
|
1139
|
+
const slot = this.upsertOneWithoutNotificationsByPk(pk, entity);
|
|
1302
1140
|
this.emitter.emit(0 /* UPDATE */, { pks: [pk] });
|
|
1303
1141
|
this.updateEmitter.markUpdatedKey(pk);
|
|
1304
1142
|
this.trackAnyUpdatePk(pk);
|
|
1143
|
+
return slot;
|
|
1305
1144
|
}
|
|
1306
1145
|
upsertOne(entity) {
|
|
1307
|
-
const
|
|
1308
|
-
this.emitter.emit(0 /* UPDATE */, { pks: [pk] });
|
|
1309
|
-
this.updateEmitter.markUpdatedKey(pk);
|
|
1310
|
-
this.trackAnyUpdatePk(pk);
|
|
1146
|
+
const slot = this.upsertOneWithoutNotifications(entity);
|
|
1147
|
+
this.emitter.emit(0 /* UPDATE */, { pks: [slot.pk] });
|
|
1148
|
+
this.updateEmitter.markUpdatedKey(slot.pk);
|
|
1149
|
+
this.trackAnyUpdatePk(slot.pk);
|
|
1150
|
+
return slot;
|
|
1311
1151
|
}
|
|
1312
1152
|
upsertMany(entities) {
|
|
1313
|
-
|
|
1153
|
+
if (entities.length === 0) return [];
|
|
1154
|
+
const slots = entities.map(
|
|
1314
1155
|
(entity) => this.upsertOneWithoutNotifications(entity)
|
|
1315
1156
|
);
|
|
1157
|
+
const pks = slots.map((slot) => slot.pk);
|
|
1316
1158
|
this.emitter.emit(0 /* UPDATE */, { pks });
|
|
1317
1159
|
this.updateEmitter.markUpdatedKeys(pks);
|
|
1318
1160
|
this.trackAnyUpdatePks(pks);
|
|
1161
|
+
return slots;
|
|
1319
1162
|
}
|
|
1320
1163
|
removeOne(entity) {
|
|
1321
1164
|
const pk = this.selectPk(entity);
|
|
@@ -1325,6 +1168,7 @@ var OIMReactiveCollection = class extends OIMCollection {
|
|
|
1325
1168
|
this.trackAnyUpdatePk(pk);
|
|
1326
1169
|
}
|
|
1327
1170
|
removeMany(entities) {
|
|
1171
|
+
if (entities.length === 0) return;
|
|
1328
1172
|
const pks = entities.map(this.selectPk);
|
|
1329
1173
|
this.store.removeManyByPks(pks);
|
|
1330
1174
|
this.emitter.emit(0 /* UPDATE */, { pks });
|
|
@@ -1338,6 +1182,7 @@ var OIMReactiveCollection = class extends OIMCollection {
|
|
|
1338
1182
|
this.trackAnyUpdatePk(pk);
|
|
1339
1183
|
}
|
|
1340
1184
|
removeManyByPks(pks) {
|
|
1185
|
+
if (pks.length === 0) return;
|
|
1341
1186
|
this.store.removeManyByPks(pks);
|
|
1342
1187
|
this.emitter.emit(0 /* UPDATE */, { pks });
|
|
1343
1188
|
this.updateEmitter.markUpdatedKeys(pks);
|
|
@@ -1383,202 +1228,347 @@ var OIMReactiveCollection = class extends OIMCollection {
|
|
|
1383
1228
|
}
|
|
1384
1229
|
};
|
|
1385
1230
|
|
|
1386
|
-
// src/
|
|
1387
|
-
var
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
get(key) {
|
|
1402
|
-
return this.properties[key];
|
|
1403
|
-
}
|
|
1404
|
-
getAll() {
|
|
1405
|
-
return { ...this.properties };
|
|
1231
|
+
// src/modules/wrapper/index/OIMIndexManualOrderedArrayBased.ts
|
|
1232
|
+
var OIMIndexManualOrderedArrayBased = class extends OIMIndexArrayBased {
|
|
1233
|
+
clear(key) {
|
|
1234
|
+
if (key === void 0) {
|
|
1235
|
+
const keys = this.getKeys();
|
|
1236
|
+
if (keys.length > 0) {
|
|
1237
|
+
this.store.clear();
|
|
1238
|
+
this.emitUpdate(Array.from(keys));
|
|
1239
|
+
}
|
|
1240
|
+
return;
|
|
1241
|
+
}
|
|
1242
|
+
if (this.store.getOneByKey(key) !== void 0) {
|
|
1243
|
+
this.store.removeOneByKey(key);
|
|
1244
|
+
this.emitUpdate([key]);
|
|
1245
|
+
}
|
|
1406
1246
|
}
|
|
1407
|
-
|
|
1408
|
-
|
|
1247
|
+
pushSlot(key, slot) {
|
|
1248
|
+
const list = this.getOrCreateList(key);
|
|
1249
|
+
const index = list.length;
|
|
1250
|
+
list.push(slot);
|
|
1251
|
+
this.emitUpdate([key]);
|
|
1252
|
+
return index;
|
|
1409
1253
|
}
|
|
1410
|
-
|
|
1411
|
-
|
|
1254
|
+
insertSlotAt(key, index, slot) {
|
|
1255
|
+
const list = this.getOrCreateList(key);
|
|
1256
|
+
const safeIndex = Math.max(0, Math.min(index, list.length));
|
|
1257
|
+
list.splice(safeIndex, 0, slot);
|
|
1258
|
+
this.emitUpdate([key]);
|
|
1259
|
+
return safeIndex;
|
|
1412
1260
|
}
|
|
1413
|
-
|
|
1414
|
-
|
|
1261
|
+
removeAt(key, index) {
|
|
1262
|
+
const list = this.store.getOneByKey(key);
|
|
1263
|
+
if (!list) return void 0;
|
|
1264
|
+
if (index < 0 || index >= list.length) return void 0;
|
|
1265
|
+
const [removed] = list.splice(index, 1);
|
|
1266
|
+
if (list.length === 0) {
|
|
1267
|
+
this.store.removeOneByKey(key);
|
|
1268
|
+
}
|
|
1269
|
+
this.emitUpdate([key]);
|
|
1270
|
+
return removed;
|
|
1415
1271
|
}
|
|
1416
|
-
|
|
1417
|
-
|
|
1272
|
+
move(key, fromIndex, toIndex) {
|
|
1273
|
+
const list = this.store.getOneByKey(key);
|
|
1274
|
+
if (!list) return void 0;
|
|
1275
|
+
if (fromIndex < 0 || fromIndex >= list.length) return void 0;
|
|
1276
|
+
if (toIndex < 0 || toIndex >= list.length) return void 0;
|
|
1277
|
+
if (fromIndex === toIndex) return list[fromIndex];
|
|
1278
|
+
const [slot] = list.splice(fromIndex, 1);
|
|
1279
|
+
if (slot === void 0) return void 0;
|
|
1280
|
+
list.splice(toIndex, 0, slot);
|
|
1281
|
+
this.emitUpdate([key]);
|
|
1282
|
+
return slot;
|
|
1418
1283
|
}
|
|
1419
|
-
|
|
1420
|
-
|
|
1284
|
+
resetSlots(key, slots) {
|
|
1285
|
+
if (slots.length === 0) {
|
|
1286
|
+
if (this.store.getOneByKey(key) !== void 0) {
|
|
1287
|
+
this.store.removeOneByKey(key);
|
|
1288
|
+
this.emitUpdate([key]);
|
|
1289
|
+
}
|
|
1290
|
+
return;
|
|
1291
|
+
}
|
|
1292
|
+
this.store.setOneByKey(key, slots.slice());
|
|
1293
|
+
this.emitUpdate([key]);
|
|
1421
1294
|
}
|
|
1422
|
-
|
|
1423
|
-
this.
|
|
1295
|
+
getOrCreateList(key) {
|
|
1296
|
+
let list = this.store.getOneByKey(key);
|
|
1297
|
+
if (!list) {
|
|
1298
|
+
list = [];
|
|
1299
|
+
this.store.setOneByKey(key, list);
|
|
1300
|
+
}
|
|
1301
|
+
return list;
|
|
1424
1302
|
}
|
|
1425
1303
|
};
|
|
1426
1304
|
|
|
1427
|
-
// src/
|
|
1428
|
-
var
|
|
1429
|
-
EOIMObjectEventType2[EOIMObjectEventType2["UPDATE"] = 0] = "UPDATE";
|
|
1430
|
-
return EOIMObjectEventType2;
|
|
1431
|
-
})(EOIMObjectEventType || {});
|
|
1432
|
-
|
|
1433
|
-
// src/core/OIMObject.ts
|
|
1434
|
-
var OIMObject = class {
|
|
1305
|
+
// src/modules/wrapper/index/OIMCollectionIndexManualOrderedArrayBased.ts
|
|
1306
|
+
var OIMCollectionIndexManualOrderedArrayBased = class extends OIMIndexManualOrderedArrayBased {
|
|
1435
1307
|
constructor(opts) {
|
|
1436
|
-
|
|
1437
|
-
this.
|
|
1308
|
+
super();
|
|
1309
|
+
this.resolveSlot = opts.collection !== void 0 ? (pk) => opts.collection.getSlotByPk(pk) : opts.resolveSlot;
|
|
1438
1310
|
}
|
|
1439
|
-
|
|
1440
|
-
this.
|
|
1441
|
-
this.emitter.emit(0 /* UPDATE */, { keys: [key] });
|
|
1311
|
+
push(key, pk) {
|
|
1312
|
+
return this.pushSlot(key, this.resolveRequiredSlot(pk));
|
|
1442
1313
|
}
|
|
1443
|
-
|
|
1444
|
-
this.
|
|
1445
|
-
this.emitter.emit(0 /* UPDATE */, {
|
|
1446
|
-
keys: Object.keys(draft)
|
|
1447
|
-
});
|
|
1314
|
+
insertAt(key, index, pk) {
|
|
1315
|
+
return this.insertSlotAt(key, index, this.resolveRequiredSlot(pk));
|
|
1448
1316
|
}
|
|
1449
|
-
|
|
1450
|
-
this.
|
|
1451
|
-
this.emitter.emit(0 /* UPDATE */, { keys: [key] });
|
|
1317
|
+
reset(key, pks) {
|
|
1318
|
+
this.resetSlots(key, this.resolveSlots(pks));
|
|
1452
1319
|
}
|
|
1453
|
-
|
|
1454
|
-
return
|
|
1320
|
+
getEntitiesByKey(key) {
|
|
1321
|
+
return super.getEntitiesByKey(key);
|
|
1455
1322
|
}
|
|
1456
|
-
|
|
1457
|
-
return
|
|
1323
|
+
getEntitiesByKeys(keys) {
|
|
1324
|
+
return super.getEntitiesByKeys(keys);
|
|
1458
1325
|
}
|
|
1459
|
-
|
|
1460
|
-
this.
|
|
1461
|
-
this.emitter.emit(0 /* UPDATE */, { keys: [] });
|
|
1326
|
+
resolvePk(pk) {
|
|
1327
|
+
return this.resolveRequiredSlot(pk);
|
|
1462
1328
|
}
|
|
1463
|
-
|
|
1464
|
-
|
|
1329
|
+
resolveSlots(pks) {
|
|
1330
|
+
const slots = [];
|
|
1331
|
+
slots.length = pks.length;
|
|
1332
|
+
for (let i = 0; i < pks.length; i++) {
|
|
1333
|
+
slots[i] = this.resolveRequiredSlot(pks[i]);
|
|
1334
|
+
}
|
|
1335
|
+
return slots;
|
|
1465
1336
|
}
|
|
1466
|
-
|
|
1467
|
-
|
|
1337
|
+
resolveRequiredSlot(pk) {
|
|
1338
|
+
const slot = this.resolveSlot(pk);
|
|
1339
|
+
if (!slot) {
|
|
1340
|
+
throw new Error(
|
|
1341
|
+
`[OIMCollectionIndexManualOrderedArrayBased]: Unable to resolve slot for PK "${String(pk)}".`
|
|
1342
|
+
);
|
|
1343
|
+
}
|
|
1344
|
+
return slot;
|
|
1468
1345
|
}
|
|
1469
|
-
|
|
1470
|
-
|
|
1346
|
+
};
|
|
1347
|
+
|
|
1348
|
+
// src/modules/wrapper/index/OIMOrderedListCommandStream.ts
|
|
1349
|
+
var OIMOrderedListCommandStream = class {
|
|
1350
|
+
constructor(queue, index) {
|
|
1351
|
+
this.isInWrite = false;
|
|
1352
|
+
this.commandsByKey = /* @__PURE__ */ new Map();
|
|
1353
|
+
this.onAfterFlush = () => {
|
|
1354
|
+
this.commandsByKey.clear();
|
|
1355
|
+
};
|
|
1356
|
+
this.onIndexUpdate = (payload) => {
|
|
1357
|
+
if (this.isInWrite) return;
|
|
1358
|
+
if (payload.keys.length === 0) return;
|
|
1359
|
+
for (let i = 0; i < payload.keys.length; i++) {
|
|
1360
|
+
const key = payload.keys[i];
|
|
1361
|
+
this.appendSetCommand(key, this.getSlotsByKey(key));
|
|
1362
|
+
}
|
|
1363
|
+
};
|
|
1364
|
+
this.commandsEventEmitter = new OIMUpdateEventEmitter(
|
|
1365
|
+
queue,
|
|
1366
|
+
"after_flush"
|
|
1367
|
+
);
|
|
1368
|
+
this.index = index ?? new OIMIndexManualOrderedArrayBased();
|
|
1369
|
+
this.unsubscribeAfterFlush = queue.emitter.on(
|
|
1370
|
+
0 /* AFTER_FLUSH */,
|
|
1371
|
+
this.onAfterFlush
|
|
1372
|
+
);
|
|
1373
|
+
this.unsubscribeFromIndexEmitter = this.index.emitter.on(
|
|
1374
|
+
0 /* UPDATE */,
|
|
1375
|
+
this.onIndexUpdate
|
|
1376
|
+
);
|
|
1471
1377
|
}
|
|
1472
|
-
|
|
1473
|
-
return this.
|
|
1378
|
+
getPksByKey(key) {
|
|
1379
|
+
return this.index.getPksByKey(key);
|
|
1474
1380
|
}
|
|
1475
|
-
|
|
1476
|
-
this.
|
|
1477
|
-
|
|
1381
|
+
getSlotsByKey(key) {
|
|
1382
|
+
return this.index.getSlotsByKey(
|
|
1383
|
+
key
|
|
1384
|
+
);
|
|
1478
1385
|
}
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
// src/core/OIMReactiveObject.ts
|
|
1482
|
-
var OIMReactiveObject = class extends OIMObject {
|
|
1483
|
-
constructor(queue, opts) {
|
|
1484
|
-
super(opts);
|
|
1485
|
-
this.updateEmitter = new OIMUpdateEventEmitter(queue, "queue");
|
|
1486
|
-
this.emitter.on(0 /* UPDATE */, (payload) => {
|
|
1487
|
-
this.updateEmitter.markUpdatedKeys(payload.keys);
|
|
1488
|
-
});
|
|
1386
|
+
getEntitiesByKey(key) {
|
|
1387
|
+
return this.index.getEntitiesByKey(key);
|
|
1489
1388
|
}
|
|
1490
|
-
|
|
1491
|
-
return this.
|
|
1389
|
+
hasKey(key) {
|
|
1390
|
+
return this.index.hasKey(key);
|
|
1492
1391
|
}
|
|
1493
|
-
|
|
1494
|
-
return this.
|
|
1392
|
+
getKeys() {
|
|
1393
|
+
return this.index.getKeys();
|
|
1495
1394
|
}
|
|
1496
|
-
|
|
1497
|
-
this.
|
|
1395
|
+
pushSlot(key, slot) {
|
|
1396
|
+
this.withWrite(() => {
|
|
1397
|
+
const index = this.index.pushSlot(key, slot);
|
|
1398
|
+
this.appendCommand(key, {
|
|
1399
|
+
type: "insert",
|
|
1400
|
+
pk: slot.pk,
|
|
1401
|
+
slot,
|
|
1402
|
+
index
|
|
1403
|
+
});
|
|
1404
|
+
});
|
|
1498
1405
|
}
|
|
1499
|
-
|
|
1500
|
-
this.
|
|
1406
|
+
insertSlotAt(key, index, slot) {
|
|
1407
|
+
this.withWrite(() => {
|
|
1408
|
+
const safeIndex = this.index.insertSlotAt(key, index, slot);
|
|
1409
|
+
this.appendCommand(key, {
|
|
1410
|
+
type: "insert",
|
|
1411
|
+
pk: slot.pk,
|
|
1412
|
+
slot,
|
|
1413
|
+
index: safeIndex
|
|
1414
|
+
});
|
|
1415
|
+
});
|
|
1501
1416
|
}
|
|
1502
|
-
|
|
1503
|
-
|
|
1417
|
+
removeAt(key, index) {
|
|
1418
|
+
this.withWrite(() => {
|
|
1419
|
+
const slot = this.index.removeAt(key, index);
|
|
1420
|
+
if (slot === void 0) return;
|
|
1421
|
+
this.appendCommand(key, {
|
|
1422
|
+
type: "remove",
|
|
1423
|
+
pk: slot.pk,
|
|
1424
|
+
slot,
|
|
1425
|
+
index
|
|
1426
|
+
});
|
|
1427
|
+
});
|
|
1504
1428
|
}
|
|
1505
|
-
|
|
1506
|
-
|
|
1429
|
+
move(key, fromIndex, toIndex) {
|
|
1430
|
+
this.withWrite(() => {
|
|
1431
|
+
const slot = this.index.move(key, fromIndex, toIndex);
|
|
1432
|
+
if (slot === void 0) return;
|
|
1433
|
+
this.appendCommand(key, {
|
|
1434
|
+
type: "move",
|
|
1435
|
+
pk: slot.pk,
|
|
1436
|
+
slot,
|
|
1437
|
+
fromIndex,
|
|
1438
|
+
toIndex
|
|
1439
|
+
});
|
|
1440
|
+
});
|
|
1507
1441
|
}
|
|
1508
|
-
|
|
1509
|
-
|
|
1442
|
+
setSlots(key, slots) {
|
|
1443
|
+
this.withWrite(() => {
|
|
1444
|
+
this.index.resetSlots(key, slots);
|
|
1445
|
+
this.appendSetCommand(key, slots);
|
|
1446
|
+
});
|
|
1510
1447
|
}
|
|
1511
|
-
|
|
1512
|
-
this.
|
|
1513
|
-
super.destroy();
|
|
1448
|
+
getBufferedCommands(key) {
|
|
1449
|
+
return this.commandsByKey.get(key) ?? [];
|
|
1514
1450
|
}
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
constructor(options = {}) {
|
|
1520
|
-
super(options);
|
|
1451
|
+
consumeCommands(key) {
|
|
1452
|
+
const cmds = this.commandsByKey.get(key);
|
|
1453
|
+
if (!cmds || cmds.length === 0) return [];
|
|
1454
|
+
return cmds.slice();
|
|
1521
1455
|
}
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
const hasChanges = this.setPksWithComparison(key, new Set(pks));
|
|
1528
|
-
if (hasChanges) {
|
|
1529
|
-
this.emitUpdateOne(key);
|
|
1456
|
+
clear(key) {
|
|
1457
|
+
if (key === void 0) {
|
|
1458
|
+
this.index.destroy();
|
|
1459
|
+
this.commandsByKey.clear();
|
|
1460
|
+
return;
|
|
1530
1461
|
}
|
|
1462
|
+
this.index.clear(key);
|
|
1463
|
+
this.commandsByKey.delete(key);
|
|
1531
1464
|
}
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1465
|
+
destroy() {
|
|
1466
|
+
this.commandsEventEmitter.destroy();
|
|
1467
|
+
this.unsubscribeAfterFlush();
|
|
1468
|
+
this.unsubscribeFromIndexEmitter();
|
|
1469
|
+
this.clear();
|
|
1537
1470
|
}
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
if (pks.length === 0) return;
|
|
1543
|
-
let slotsSet = this.store.getOneByKey(key);
|
|
1544
|
-
if (!slotsSet) {
|
|
1545
|
-
slotsSet = /* @__PURE__ */ new Set();
|
|
1546
|
-
this.store.setOneByKey(key, slotsSet);
|
|
1547
|
-
}
|
|
1548
|
-
const pksSet = this.slotsToPks(slotsSet);
|
|
1549
|
-
let hasChanges = false;
|
|
1550
|
-
for (const pk of pks) {
|
|
1551
|
-
if (!pksSet.has(pk)) {
|
|
1552
|
-
pksSet.add(pk);
|
|
1553
|
-
slotsSet.add(this.getOrCreateSlot(pk));
|
|
1554
|
-
hasChanges = true;
|
|
1555
|
-
}
|
|
1471
|
+
withWrite(fn) {
|
|
1472
|
+
if (this.isInWrite) {
|
|
1473
|
+
fn();
|
|
1474
|
+
return;
|
|
1556
1475
|
}
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1476
|
+
this.isInWrite = true;
|
|
1477
|
+
try {
|
|
1478
|
+
fn();
|
|
1479
|
+
} finally {
|
|
1480
|
+
this.isInWrite = false;
|
|
1560
1481
|
}
|
|
1561
1482
|
}
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
const slotsSet = this.store.getOneByKey(key);
|
|
1568
|
-
if (!slotsSet) return;
|
|
1569
|
-
let hasChanges = false;
|
|
1570
|
-
const pksToRemove = new Set(pks);
|
|
1571
|
-
for (const slot of Array.from(slotsSet)) {
|
|
1572
|
-
if (pksToRemove.has(slot.pk) && slotsSet.delete(slot)) {
|
|
1573
|
-
hasChanges = true;
|
|
1574
|
-
}
|
|
1483
|
+
appendCommand(key, cmd) {
|
|
1484
|
+
let cmds = this.commandsByKey.get(key);
|
|
1485
|
+
if (!cmds) {
|
|
1486
|
+
cmds = [];
|
|
1487
|
+
this.commandsByKey.set(key, cmds);
|
|
1575
1488
|
}
|
|
1576
|
-
if (
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
} else if (
|
|
1580
|
-
this.
|
|
1489
|
+
if (cmd.type === "set") {
|
|
1490
|
+
cmds.length = 0;
|
|
1491
|
+
cmds.push(cmd);
|
|
1492
|
+
} else if (cmds.length > 0 && cmds[0].type === "set") {
|
|
1493
|
+
const slots = this.getSlotsByKey(key);
|
|
1494
|
+
cmds[0] = this.createSetCommand(slots);
|
|
1495
|
+
} else {
|
|
1496
|
+
cmds.push(cmd);
|
|
1581
1497
|
}
|
|
1498
|
+
this.commandsEventEmitter.markUpdatedKeys([key]);
|
|
1499
|
+
}
|
|
1500
|
+
appendSetCommand(key, slots) {
|
|
1501
|
+
this.appendCommand(key, this.createSetCommand(slots));
|
|
1502
|
+
}
|
|
1503
|
+
createSetCommand(slots) {
|
|
1504
|
+
return {
|
|
1505
|
+
type: "set",
|
|
1506
|
+
pks: slots.map((slot) => slot.pk),
|
|
1507
|
+
slots
|
|
1508
|
+
};
|
|
1509
|
+
}
|
|
1510
|
+
};
|
|
1511
|
+
|
|
1512
|
+
// src/modules/wrapper/index/OIMCollectionOrderedListCommandStream.ts
|
|
1513
|
+
var OIMCollectionOrderedListCommandStream = class extends OIMOrderedListCommandStream {
|
|
1514
|
+
constructor(queue, opts) {
|
|
1515
|
+
const index = opts.index ?? new OIMCollectionIndexManualOrderedArrayBased(
|
|
1516
|
+
opts.collection !== void 0 ? { collection: opts.collection } : { resolveSlot: opts.resolveSlot }
|
|
1517
|
+
);
|
|
1518
|
+
super(queue, index);
|
|
1519
|
+
this.index = index;
|
|
1520
|
+
}
|
|
1521
|
+
push(key, pk) {
|
|
1522
|
+
this.withWrite(() => {
|
|
1523
|
+
const slot = this.resolvePk(pk);
|
|
1524
|
+
const index = this.index.pushSlot(key, slot);
|
|
1525
|
+
this.appendCommand(key, {
|
|
1526
|
+
type: "insert",
|
|
1527
|
+
pk,
|
|
1528
|
+
slot,
|
|
1529
|
+
index
|
|
1530
|
+
});
|
|
1531
|
+
});
|
|
1532
|
+
}
|
|
1533
|
+
insertAt(key, index, pk) {
|
|
1534
|
+
this.withWrite(() => {
|
|
1535
|
+
const slot = this.resolvePk(pk);
|
|
1536
|
+
const safeIndex = this.index.insertSlotAt(key, index, slot);
|
|
1537
|
+
this.appendCommand(key, {
|
|
1538
|
+
type: "insert",
|
|
1539
|
+
pk,
|
|
1540
|
+
slot,
|
|
1541
|
+
index: safeIndex
|
|
1542
|
+
});
|
|
1543
|
+
});
|
|
1544
|
+
}
|
|
1545
|
+
set(key, pks) {
|
|
1546
|
+
this.withWrite(() => {
|
|
1547
|
+
const slots = pks.map((pk) => this.resolvePk(pk));
|
|
1548
|
+
this.index.resetSlots(key, slots);
|
|
1549
|
+
this.appendSetCommand(key, slots);
|
|
1550
|
+
});
|
|
1551
|
+
}
|
|
1552
|
+
getSlotsByKey(key) {
|
|
1553
|
+
return this.index.getSlotsByKey(
|
|
1554
|
+
key
|
|
1555
|
+
);
|
|
1556
|
+
}
|
|
1557
|
+
getEntitiesByKey(key) {
|
|
1558
|
+
return this.index.getEntitiesByKey(key);
|
|
1559
|
+
}
|
|
1560
|
+
resolvePk(pk) {
|
|
1561
|
+
return this.index.resolvePk(pk);
|
|
1562
|
+
}
|
|
1563
|
+
};
|
|
1564
|
+
|
|
1565
|
+
// src/core/OIMIndexManualArrayBased.ts
|
|
1566
|
+
var OIMIndexManualArrayBased = class extends OIMIndexArrayBased {
|
|
1567
|
+
constructor(options = {}) {
|
|
1568
|
+
super(options);
|
|
1569
|
+
}
|
|
1570
|
+
setSlots(key, slots) {
|
|
1571
|
+
const hasChanges = this.setSlotsWithComparison(key, slots);
|
|
1582
1572
|
if (hasChanges) {
|
|
1583
1573
|
this.emitUpdateOne(key);
|
|
1584
1574
|
}
|
|
@@ -1602,8 +1592,8 @@ var OIMIndexManualSetBased = class extends OIMIndexSetBased {
|
|
|
1602
1592
|
}
|
|
1603
1593
|
};
|
|
1604
1594
|
|
|
1605
|
-
// src/core/
|
|
1606
|
-
var
|
|
1595
|
+
// src/core/OIMReactiveIndexManualArrayBased.ts
|
|
1596
|
+
var OIMIndexManualArrayBasedReactive = class extends OIMIndexManualArrayBased {
|
|
1607
1597
|
constructor(updateEmitter, opts) {
|
|
1608
1598
|
super(opts);
|
|
1609
1599
|
this.updateEmitter = updateEmitter;
|
|
@@ -1615,94 +1605,93 @@ var OIMIndexManualSetBasedReactive = class extends OIMIndexManualSetBased {
|
|
|
1615
1605
|
this.updateEmitter.markUpdatedKey(key);
|
|
1616
1606
|
}
|
|
1617
1607
|
};
|
|
1618
|
-
var
|
|
1608
|
+
var OIMReactiveIndexManualArrayBased = class extends OIMReactiveIndexArrayBased {
|
|
1619
1609
|
constructor(queue, opts) {
|
|
1620
1610
|
super(queue, (updateEmitter) => {
|
|
1621
|
-
return new
|
|
1611
|
+
return new OIMIndexManualArrayBasedReactive(
|
|
1622
1612
|
updateEmitter,
|
|
1623
1613
|
opts?.indexOptions
|
|
1624
1614
|
);
|
|
1625
1615
|
});
|
|
1626
1616
|
}
|
|
1627
|
-
setPks(key, pks) {
|
|
1628
|
-
this.index.setPks(key, pks);
|
|
1629
|
-
}
|
|
1630
1617
|
setSlots(key, slots) {
|
|
1631
1618
|
this.index.setSlots(key, slots);
|
|
1632
1619
|
}
|
|
1633
|
-
addPks(key, pks) {
|
|
1634
|
-
this.index.addPks(key, pks);
|
|
1635
|
-
}
|
|
1636
|
-
removePks(key, pks) {
|
|
1637
|
-
this.index.removePks(key, pks);
|
|
1638
|
-
}
|
|
1639
1620
|
clear(key) {
|
|
1640
1621
|
this.index.clear(key);
|
|
1641
1622
|
}
|
|
1642
1623
|
};
|
|
1643
1624
|
|
|
1644
|
-
// src/core/
|
|
1645
|
-
var
|
|
1646
|
-
constructor(
|
|
1647
|
-
|
|
1625
|
+
// src/core/OIMReactiveCollectionIndexManualArrayBased.ts
|
|
1626
|
+
var OIMReactiveCollectionIndexManualArrayBased = class extends OIMReactiveIndexManualArrayBased {
|
|
1627
|
+
constructor(queue, opts) {
|
|
1628
|
+
const resolveSlot = opts.collection !== void 0 ? (pk) => opts.collection.getSlotByPk(pk) : opts.resolveSlot;
|
|
1629
|
+
super(queue, {
|
|
1630
|
+
indexOptions: opts.indexOptions
|
|
1631
|
+
});
|
|
1632
|
+
this.resolveSlot = resolveSlot;
|
|
1648
1633
|
}
|
|
1649
|
-
/**
|
|
1650
|
-
* Set primary keys for a specific index key, replacing any existing values.
|
|
1651
|
-
* Uses optional comparator to skip updates if PKs haven't actually changed.
|
|
1652
|
-
*/
|
|
1653
1634
|
setPks(key, pks) {
|
|
1654
|
-
|
|
1655
|
-
if (hasChanges) {
|
|
1656
|
-
this.emitUpdateOne(key);
|
|
1657
|
-
}
|
|
1658
|
-
}
|
|
1659
|
-
setSlots(key, slots) {
|
|
1660
|
-
const hasChanges = this.setSlotsWithComparison(key, slots);
|
|
1661
|
-
if (hasChanges) {
|
|
1662
|
-
this.emitUpdateOne(key);
|
|
1663
|
-
}
|
|
1635
|
+
this.setSlots(key, this.resolveSlots(pks));
|
|
1664
1636
|
}
|
|
1665
|
-
/**
|
|
1666
|
-
* Add primary keys to a specific index key
|
|
1667
|
-
*/
|
|
1668
1637
|
addPks(key, pks) {
|
|
1669
1638
|
if (pks.length === 0) return;
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
this.store.setOneByKey(key, slotsArray);
|
|
1674
|
-
}
|
|
1675
|
-
const pksSet = new Set(slotsArray.map((slot) => slot.pk));
|
|
1639
|
+
const existingSlots = this.index.getSlotsByKey(key);
|
|
1640
|
+
const existingPks = new Set(existingSlots.map((slot) => slot.pk));
|
|
1641
|
+
const nextSlots = existingSlots.slice();
|
|
1676
1642
|
let hasChanges = false;
|
|
1677
|
-
const nextSlots = slotsArray.slice();
|
|
1678
1643
|
for (const pk of pks) {
|
|
1679
|
-
if (
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
}
|
|
1684
|
-
}
|
|
1685
|
-
if (hasChanges) {
|
|
1686
|
-
this.store.setOneByKey(key, nextSlots);
|
|
1687
|
-
this.emitUpdateOne(key);
|
|
1644
|
+
if (existingPks.has(pk)) continue;
|
|
1645
|
+
nextSlots.push(this.resolveRequiredSlot(pk));
|
|
1646
|
+
existingPks.add(pk);
|
|
1647
|
+
hasChanges = true;
|
|
1688
1648
|
}
|
|
1649
|
+
if (hasChanges) this.setSlots(key, nextSlots);
|
|
1689
1650
|
}
|
|
1690
|
-
/**
|
|
1691
|
-
* Remove primary keys from a specific index key
|
|
1692
|
-
*/
|
|
1693
1651
|
removePks(key, pks) {
|
|
1694
1652
|
if (pks.length === 0) return;
|
|
1695
|
-
const
|
|
1696
|
-
|
|
1697
|
-
const
|
|
1698
|
-
|
|
1699
|
-
|
|
1653
|
+
const pksToRemove = new Set(pks);
|
|
1654
|
+
const existingSlots = this.index.getSlotsByKey(key);
|
|
1655
|
+
const nextSlots = existingSlots.filter(
|
|
1656
|
+
(slot) => !pksToRemove.has(slot.pk)
|
|
1657
|
+
);
|
|
1658
|
+
if (nextSlots.length === existingSlots.length) return;
|
|
1659
|
+
if (nextSlots.length === 0) this.clear(key);
|
|
1660
|
+
else this.setSlots(key, nextSlots);
|
|
1661
|
+
}
|
|
1662
|
+
getEntitiesByKey(key) {
|
|
1663
|
+
return super.getEntitiesByKey(key);
|
|
1664
|
+
}
|
|
1665
|
+
getEntitiesByKeys(keys) {
|
|
1666
|
+
return super.getEntitiesByKeys(keys);
|
|
1667
|
+
}
|
|
1668
|
+
resolveSlots(pks) {
|
|
1669
|
+
const slots = [];
|
|
1670
|
+
slots.length = pks.length;
|
|
1671
|
+
for (let i = 0; i < pks.length; i++) {
|
|
1672
|
+
slots[i] = this.resolveRequiredSlot(pks[i]);
|
|
1673
|
+
}
|
|
1674
|
+
return slots;
|
|
1675
|
+
}
|
|
1676
|
+
resolveRequiredSlot(pk) {
|
|
1677
|
+
const slot = this.resolveSlot(pk);
|
|
1678
|
+
if (!slot) {
|
|
1679
|
+
throw new Error(
|
|
1680
|
+
`[OIMReactiveCollectionIndexManualArrayBased]: Unable to resolve slot for PK "${String(pk)}".`
|
|
1681
|
+
);
|
|
1682
|
+
}
|
|
1683
|
+
return slot;
|
|
1684
|
+
}
|
|
1685
|
+
};
|
|
1686
|
+
|
|
1687
|
+
// src/core/OIMIndexManualSetBased.ts
|
|
1688
|
+
var OIMIndexManualSetBased = class extends OIMIndexSetBased {
|
|
1689
|
+
constructor(options = {}) {
|
|
1690
|
+
super(options);
|
|
1691
|
+
}
|
|
1692
|
+
setSlots(key, slots) {
|
|
1693
|
+
const hasChanges = this.setSlotsWithComparison(key, new Set(slots));
|
|
1700
1694
|
if (hasChanges) {
|
|
1701
|
-
if (filtered.length === 0) {
|
|
1702
|
-
this.store.removeOneByKey(key);
|
|
1703
|
-
} else {
|
|
1704
|
-
this.store.setOneByKey(key, filtered);
|
|
1705
|
-
}
|
|
1706
1695
|
this.emitUpdateOne(key);
|
|
1707
1696
|
}
|
|
1708
1697
|
}
|
|
@@ -1725,8 +1714,8 @@ var OIMIndexManualArrayBased = class extends OIMIndexArrayBased {
|
|
|
1725
1714
|
}
|
|
1726
1715
|
};
|
|
1727
1716
|
|
|
1728
|
-
// src/core/
|
|
1729
|
-
var
|
|
1717
|
+
// src/core/OIMReactiveIndexManualSetBased.ts
|
|
1718
|
+
var OIMIndexManualSetBasedReactive = class extends OIMIndexManualSetBased {
|
|
1730
1719
|
constructor(updateEmitter, opts) {
|
|
1731
1720
|
super(opts);
|
|
1732
1721
|
this.updateEmitter = updateEmitter;
|
|
@@ -1738,310 +1727,1256 @@ var OIMIndexManualArrayBasedReactive = class extends OIMIndexManualArrayBased {
|
|
|
1738
1727
|
this.updateEmitter.markUpdatedKey(key);
|
|
1739
1728
|
}
|
|
1740
1729
|
};
|
|
1741
|
-
var
|
|
1730
|
+
var OIMReactiveIndexManualSetBased = class extends OIMReactiveIndexSetBased {
|
|
1742
1731
|
constructor(queue, opts) {
|
|
1743
1732
|
super(queue, (updateEmitter) => {
|
|
1744
|
-
return new
|
|
1733
|
+
return new OIMIndexManualSetBasedReactive(
|
|
1745
1734
|
updateEmitter,
|
|
1746
1735
|
opts?.indexOptions
|
|
1747
1736
|
);
|
|
1748
1737
|
});
|
|
1749
1738
|
}
|
|
1750
|
-
setPks(key, pks) {
|
|
1751
|
-
this.index.setPks(key, pks);
|
|
1752
|
-
}
|
|
1753
1739
|
setSlots(key, slots) {
|
|
1754
1740
|
this.index.setSlots(key, slots);
|
|
1755
1741
|
}
|
|
1756
|
-
addPks(key, pks) {
|
|
1757
|
-
this.index.addPks(key, pks);
|
|
1758
|
-
}
|
|
1759
|
-
removePks(key, pks) {
|
|
1760
|
-
this.index.removePks(key, pks);
|
|
1761
|
-
}
|
|
1762
1742
|
clear(key) {
|
|
1763
1743
|
this.index.clear(key);
|
|
1764
1744
|
}
|
|
1765
1745
|
};
|
|
1766
1746
|
|
|
1767
|
-
// src/core/
|
|
1768
|
-
var
|
|
1747
|
+
// src/core/OIMReactiveCollectionIndexManualSetBased.ts
|
|
1748
|
+
var OIMReactiveCollectionIndexManualSetBased = class extends OIMReactiveIndexManualSetBased {
|
|
1769
1749
|
constructor(queue, opts) {
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
}
|
|
1776
|
-
}
|
|
1777
|
-
};
|
|
1778
|
-
|
|
1779
|
-
// src/core/OIMObjectStoreMapDriven.ts
|
|
1780
|
-
var OIMObjectStoreMapDriven = class extends OIMObjectStore {
|
|
1781
|
-
constructor() {
|
|
1782
|
-
super(...arguments);
|
|
1783
|
-
this.properties = /* @__PURE__ */ new Map();
|
|
1750
|
+
const resolveSlot = opts.collection !== void 0 ? (pk) => opts.collection.getSlotByPk(pk) : opts.resolveSlot;
|
|
1751
|
+
super(queue, {
|
|
1752
|
+
indexOptions: opts.indexOptions
|
|
1753
|
+
});
|
|
1754
|
+
this.resolveSlot = resolveSlot;
|
|
1784
1755
|
}
|
|
1785
|
-
|
|
1786
|
-
this.
|
|
1756
|
+
setPks(key, pks) {
|
|
1757
|
+
this.setSlots(key, this.resolveSlots(pks));
|
|
1787
1758
|
}
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1759
|
+
addPks(key, pks) {
|
|
1760
|
+
if (pks.length === 0) return;
|
|
1761
|
+
const existingSlots = this.index.getSlotsByKey(key);
|
|
1762
|
+
const existingPks = this.index.getPksByKey(key);
|
|
1763
|
+
const nextSlots = new Set(existingSlots);
|
|
1764
|
+
let hasChanges = false;
|
|
1765
|
+
for (const pk of pks) {
|
|
1766
|
+
if (existingPks.has(pk)) continue;
|
|
1767
|
+
const slot = this.resolveRequiredSlot(pk);
|
|
1768
|
+
nextSlots.add(slot);
|
|
1769
|
+
existingPks.add(pk);
|
|
1770
|
+
hasChanges = true;
|
|
1795
1771
|
}
|
|
1772
|
+
if (hasChanges) this.setSlots(key, nextSlots);
|
|
1796
1773
|
}
|
|
1797
|
-
|
|
1798
|
-
|
|
1774
|
+
removePks(key, pks) {
|
|
1775
|
+
if (pks.length === 0) return;
|
|
1776
|
+
const pksToRemove = new Set(pks);
|
|
1777
|
+
const existingSlots = this.index.getSlotsByKey(key);
|
|
1778
|
+
const nextSlots = /* @__PURE__ */ new Set();
|
|
1779
|
+
let hasChanges = false;
|
|
1780
|
+
for (const slot of existingSlots) {
|
|
1781
|
+
if (pksToRemove.has(slot.pk)) {
|
|
1782
|
+
hasChanges = true;
|
|
1783
|
+
} else {
|
|
1784
|
+
nextSlots.add(slot);
|
|
1785
|
+
}
|
|
1786
|
+
}
|
|
1787
|
+
if (!hasChanges) return;
|
|
1788
|
+
if (nextSlots.size === 0) this.clear(key);
|
|
1789
|
+
else this.setSlots(key, nextSlots);
|
|
1799
1790
|
}
|
|
1800
|
-
|
|
1801
|
-
return
|
|
1791
|
+
getEntitiesByKey(key) {
|
|
1792
|
+
return super.getEntitiesByKey(key);
|
|
1802
1793
|
}
|
|
1803
|
-
|
|
1804
|
-
return
|
|
1794
|
+
getEntitiesByKeys(keys) {
|
|
1795
|
+
return super.getEntitiesByKeys(keys);
|
|
1805
1796
|
}
|
|
1806
|
-
|
|
1807
|
-
|
|
1797
|
+
resolveSlots(pks) {
|
|
1798
|
+
const slots = /* @__PURE__ */ new Set();
|
|
1799
|
+
for (const pk of pks) slots.add(this.resolveRequiredSlot(pk));
|
|
1800
|
+
return slots;
|
|
1808
1801
|
}
|
|
1809
|
-
|
|
1810
|
-
|
|
1802
|
+
resolveRequiredSlot(pk) {
|
|
1803
|
+
const slot = this.resolveSlot(pk);
|
|
1804
|
+
if (!slot) {
|
|
1805
|
+
throw new Error(
|
|
1806
|
+
`[OIMReactiveCollectionIndexManualSetBased]: Unable to resolve slot for PK "${String(pk)}".`
|
|
1807
|
+
);
|
|
1808
|
+
}
|
|
1809
|
+
return slot;
|
|
1811
1810
|
}
|
|
1812
|
-
|
|
1813
|
-
|
|
1811
|
+
};
|
|
1812
|
+
|
|
1813
|
+
// src/core/OIMDerivedCollectionIndexSetBased.ts
|
|
1814
|
+
var OIMDerivedCollectionIndexSetBased = class extends OIMReactiveCollectionIndexManualSetBased {
|
|
1815
|
+
constructor(queue, collection, opts) {
|
|
1816
|
+
super(queue, {
|
|
1817
|
+
collection,
|
|
1818
|
+
indexOptions: opts.indexOptions
|
|
1819
|
+
});
|
|
1820
|
+
this.keysByPk = /* @__PURE__ */ new Map();
|
|
1821
|
+
this.onCollectionUpdate = (pks) => {
|
|
1822
|
+
if (pks.length === 0) {
|
|
1823
|
+
this.rebuildFromCollection();
|
|
1824
|
+
return;
|
|
1825
|
+
}
|
|
1826
|
+
for (const pk of pks) {
|
|
1827
|
+
this.syncPk(pk);
|
|
1828
|
+
}
|
|
1829
|
+
};
|
|
1830
|
+
this.collection = collection;
|
|
1831
|
+
this.selectIndexKeys = opts.selectIndexKeys;
|
|
1832
|
+
this.unsubscribeFromCollection = collection.emitter.on(
|
|
1833
|
+
0 /* UPDATE */,
|
|
1834
|
+
(payload) => this.onCollectionUpdate(payload.pks)
|
|
1835
|
+
);
|
|
1836
|
+
if (opts.buildInitial !== false) {
|
|
1837
|
+
this.rebuildFromCollection();
|
|
1838
|
+
}
|
|
1814
1839
|
}
|
|
1815
|
-
|
|
1816
|
-
|
|
1840
|
+
rebuildFromCollection() {
|
|
1841
|
+
this.keysByPk.clear();
|
|
1842
|
+
super.clear();
|
|
1843
|
+
const slotsByKey = /* @__PURE__ */ new Map();
|
|
1844
|
+
const slots = this.collection.getAllSlots();
|
|
1845
|
+
for (const slot of slots) {
|
|
1846
|
+
if (slot.item === void 0) continue;
|
|
1847
|
+
const keys = this.normalizeKeys(this.selectIndexKeys(slot.item));
|
|
1848
|
+
if (keys.length === 0) continue;
|
|
1849
|
+
this.keysByPk.set(slot.pk, new Set(keys));
|
|
1850
|
+
for (const key of keys) {
|
|
1851
|
+
let slotsForKey = slotsByKey.get(key);
|
|
1852
|
+
if (!slotsForKey) {
|
|
1853
|
+
slotsForKey = /* @__PURE__ */ new Set();
|
|
1854
|
+
slotsByKey.set(key, slotsForKey);
|
|
1855
|
+
}
|
|
1856
|
+
slotsForKey.add(slot);
|
|
1857
|
+
}
|
|
1858
|
+
}
|
|
1859
|
+
for (const [key, keySlots] of slotsByKey) {
|
|
1860
|
+
this.setSlots(key, keySlots);
|
|
1861
|
+
}
|
|
1817
1862
|
}
|
|
1818
|
-
|
|
1819
|
-
|
|
1863
|
+
clear(key) {
|
|
1864
|
+
if (key === void 0) {
|
|
1865
|
+
this.keysByPk.clear();
|
|
1866
|
+
} else {
|
|
1867
|
+
for (const keys of this.keysByPk.values()) {
|
|
1868
|
+
keys.delete(key);
|
|
1869
|
+
}
|
|
1870
|
+
}
|
|
1871
|
+
super.clear(key);
|
|
1820
1872
|
}
|
|
1821
1873
|
destroy() {
|
|
1822
|
-
this.
|
|
1874
|
+
this.unsubscribeFromCollection();
|
|
1875
|
+
this.keysByPk.clear();
|
|
1876
|
+
super.destroy();
|
|
1823
1877
|
}
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
if (
|
|
1831
|
-
|
|
1832
|
-
const kb = Object.keys(b);
|
|
1833
|
-
if (ka.length !== kb.length) return true;
|
|
1834
|
-
for (let i = 0; i < ka.length; i++) {
|
|
1835
|
-
const k = ka[i];
|
|
1836
|
-
if (b[k] !== a[k])
|
|
1837
|
-
return true;
|
|
1878
|
+
syncPk(pk) {
|
|
1879
|
+
const prevKeys = this.keysByPk.get(pk) ?? /* @__PURE__ */ new Set();
|
|
1880
|
+
const slot = this.collection.getSlotByPk(pk);
|
|
1881
|
+
const entity = slot?.item;
|
|
1882
|
+
const nextKeys = entity === void 0 ? /* @__PURE__ */ new Set() : new Set(this.normalizeKeys(this.selectIndexKeys(entity)));
|
|
1883
|
+
for (const key of prevKeys) {
|
|
1884
|
+
if (!nextKeys.has(key)) {
|
|
1885
|
+
this.removePks(key, [pk]);
|
|
1838
1886
|
}
|
|
1839
|
-
|
|
1840
|
-
|
|
1887
|
+
}
|
|
1888
|
+
if (entity !== void 0) {
|
|
1889
|
+
for (const key of nextKeys) {
|
|
1890
|
+
if (!prevKeys.has(key)) {
|
|
1891
|
+
this.addPks(key, [pk]);
|
|
1892
|
+
}
|
|
1893
|
+
}
|
|
1894
|
+
}
|
|
1895
|
+
if (nextKeys.size === 0) {
|
|
1896
|
+
this.keysByPk.delete(pk);
|
|
1897
|
+
} else {
|
|
1898
|
+
this.keysByPk.set(pk, nextKeys);
|
|
1899
|
+
}
|
|
1841
1900
|
}
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
if (this.scheduler) {
|
|
1852
|
-
this.flushBound = () => this.flush();
|
|
1853
|
-
this.scheduler.on(
|
|
1854
|
-
0 /* FLUSH */,
|
|
1855
|
-
this.flushBound
|
|
1856
|
-
);
|
|
1901
|
+
normalizeKeys(keys) {
|
|
1902
|
+
if (keys === void 0 || keys === null) return [];
|
|
1903
|
+
const rawKeys = Array.isArray(keys) ? keys : [keys];
|
|
1904
|
+
const result = [];
|
|
1905
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1906
|
+
for (const key of rawKeys) {
|
|
1907
|
+
if (seen.has(key)) continue;
|
|
1908
|
+
seen.add(key);
|
|
1909
|
+
result.push(key);
|
|
1857
1910
|
}
|
|
1911
|
+
return result;
|
|
1858
1912
|
}
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
this.
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1913
|
+
};
|
|
1914
|
+
|
|
1915
|
+
// src/core/OIMDerivedCollectionIndexArrayBased.ts
|
|
1916
|
+
var OIMDerivedCollectionIndexArrayBased = class extends OIMReactiveCollectionIndexManualArrayBased {
|
|
1917
|
+
constructor(queue, collection, opts) {
|
|
1918
|
+
super(queue, {
|
|
1919
|
+
collection,
|
|
1920
|
+
indexOptions: opts.indexOptions
|
|
1921
|
+
});
|
|
1922
|
+
this.keysByPk = /* @__PURE__ */ new Map();
|
|
1923
|
+
this.onCollectionUpdate = (pks) => {
|
|
1924
|
+
if (pks.length === 0) {
|
|
1925
|
+
this.rebuildFromCollection();
|
|
1926
|
+
return;
|
|
1927
|
+
}
|
|
1928
|
+
const affectedKeys = /* @__PURE__ */ new Set();
|
|
1929
|
+
for (const pk of pks) {
|
|
1930
|
+
this.trackPkKeys(pk, affectedKeys);
|
|
1931
|
+
}
|
|
1932
|
+
for (const key of affectedKeys) {
|
|
1933
|
+
this.rebuildKey(key);
|
|
1934
|
+
}
|
|
1875
1935
|
};
|
|
1936
|
+
this.collection = collection;
|
|
1937
|
+
this.selectIndexKeys = opts.selectIndexKeys;
|
|
1938
|
+
this.compareEntities = opts.compareEntities;
|
|
1939
|
+
this.orderBy = opts.orderBy;
|
|
1940
|
+
this.unsubscribeFromCollection = collection.emitter.on(
|
|
1941
|
+
0 /* UPDATE */,
|
|
1942
|
+
(payload) => this.onCollectionUpdate(payload.pks)
|
|
1943
|
+
);
|
|
1944
|
+
if (opts.buildInitial !== false) {
|
|
1945
|
+
this.rebuildFromCollection();
|
|
1946
|
+
}
|
|
1876
1947
|
}
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
const
|
|
1897
|
-
|
|
1898
|
-
for (let i = 0; i < snapshot.length; i++) {
|
|
1899
|
-
snapshot[i]();
|
|
1948
|
+
rebuildFromCollection() {
|
|
1949
|
+
this.keysByPk.clear();
|
|
1950
|
+
super.clear();
|
|
1951
|
+
const slotsByKey = /* @__PURE__ */ new Map();
|
|
1952
|
+
const slots = this.collection.getAllSlots();
|
|
1953
|
+
for (const slot of slots) {
|
|
1954
|
+
if (slot.item === void 0) continue;
|
|
1955
|
+
const keys = this.normalizeKeys(this.selectIndexKeys(slot.item));
|
|
1956
|
+
if (keys.length === 0) continue;
|
|
1957
|
+
this.keysByPk.set(slot.pk, new Set(keys));
|
|
1958
|
+
for (const key of keys) {
|
|
1959
|
+
let slotsForKey = slotsByKey.get(key);
|
|
1960
|
+
if (!slotsForKey) {
|
|
1961
|
+
slotsForKey = [];
|
|
1962
|
+
slotsByKey.set(key, slotsForKey);
|
|
1963
|
+
}
|
|
1964
|
+
slotsForKey.push(slot);
|
|
1965
|
+
}
|
|
1966
|
+
}
|
|
1967
|
+
for (const [key, keySlots] of slotsByKey) {
|
|
1968
|
+
this.setSlots(key, this.sortSlots(keySlots));
|
|
1900
1969
|
}
|
|
1901
|
-
this.isFlushing = false;
|
|
1902
|
-
this.emitter.emit(0 /* AFTER_FLUSH */, void 0);
|
|
1903
1970
|
}
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1971
|
+
clear(key) {
|
|
1972
|
+
if (key === void 0) {
|
|
1973
|
+
this.keysByPk.clear();
|
|
1974
|
+
} else {
|
|
1975
|
+
for (const keys of this.keysByPk.values()) {
|
|
1976
|
+
keys.delete(key);
|
|
1977
|
+
}
|
|
1978
|
+
}
|
|
1979
|
+
super.clear(key);
|
|
1909
1980
|
}
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
return this.tasks.size === 0;
|
|
1981
|
+
destroy() {
|
|
1982
|
+
this.unsubscribeFromCollection();
|
|
1983
|
+
this.keysByPk.clear();
|
|
1984
|
+
super.destroy();
|
|
1915
1985
|
}
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
this.
|
|
1986
|
+
trackPkKeys(pk, affectedKeys) {
|
|
1987
|
+
const prevKeys = this.keysByPk.get(pk) ?? /* @__PURE__ */ new Set();
|
|
1988
|
+
for (const key of prevKeys) affectedKeys.add(key);
|
|
1989
|
+
const slot = this.collection.getSlotByPk(pk);
|
|
1990
|
+
const entity = slot?.item;
|
|
1991
|
+
const nextKeys = entity === void 0 ? /* @__PURE__ */ new Set() : new Set(this.normalizeKeys(this.selectIndexKeys(entity)));
|
|
1992
|
+
for (const key of nextKeys) affectedKeys.add(key);
|
|
1993
|
+
if (nextKeys.size === 0) {
|
|
1994
|
+
this.keysByPk.delete(pk);
|
|
1995
|
+
} else {
|
|
1996
|
+
this.keysByPk.set(pk, nextKeys);
|
|
1997
|
+
}
|
|
1922
1998
|
}
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1999
|
+
rebuildKey(key) {
|
|
2000
|
+
const keySlots = [];
|
|
2001
|
+
const slots = this.collection.getAllSlots();
|
|
2002
|
+
for (const slot of slots) {
|
|
2003
|
+
if (slot.item === void 0) continue;
|
|
2004
|
+
const keys = this.keysByPk.get(slot.pk);
|
|
2005
|
+
if (keys?.has(key)) keySlots.push(slot);
|
|
2006
|
+
}
|
|
2007
|
+
if (keySlots.length === 0) {
|
|
2008
|
+
super.clear(key);
|
|
2009
|
+
} else {
|
|
2010
|
+
this.setSlots(key, this.sortSlots(keySlots));
|
|
1928
2011
|
}
|
|
1929
2012
|
}
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
this.
|
|
1938
|
-
|
|
2013
|
+
sortSlots(slots) {
|
|
2014
|
+
if (!this.compareEntities && !this.orderBy) return slots;
|
|
2015
|
+
return slots.slice().sort((a, b) => {
|
|
2016
|
+
const aItem = a.item;
|
|
2017
|
+
const bItem = b.item;
|
|
2018
|
+
if (aItem === void 0 || bItem === void 0) return 0;
|
|
2019
|
+
if (this.compareEntities) {
|
|
2020
|
+
return this.compareEntities(aItem, bItem);
|
|
2021
|
+
}
|
|
2022
|
+
const aValue = this.orderBy(aItem);
|
|
2023
|
+
const bValue = this.orderBy(bItem);
|
|
2024
|
+
if (aValue < bValue) return -1;
|
|
2025
|
+
if (aValue > bValue) return 1;
|
|
2026
|
+
return 0;
|
|
2027
|
+
});
|
|
2028
|
+
}
|
|
2029
|
+
normalizeKeys(keys) {
|
|
2030
|
+
if (keys === void 0 || keys === null) return [];
|
|
2031
|
+
const rawKeys = Array.isArray(keys) ? keys : [keys];
|
|
2032
|
+
const result = [];
|
|
2033
|
+
const seen = /* @__PURE__ */ new Set();
|
|
2034
|
+
for (const key of rawKeys) {
|
|
2035
|
+
if (seen.has(key)) continue;
|
|
2036
|
+
seen.add(key);
|
|
2037
|
+
result.push(key);
|
|
1939
2038
|
}
|
|
1940
|
-
|
|
2039
|
+
return result;
|
|
1941
2040
|
}
|
|
1942
2041
|
};
|
|
1943
2042
|
|
|
1944
|
-
// src/core/
|
|
1945
|
-
var
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
return (
|
|
1952
|
-
|
|
1953
|
-
|
|
2043
|
+
// src/core/OIMCollectionIndexFactory.ts
|
|
2044
|
+
var OIMCollectionIndexFactory = class {
|
|
2045
|
+
constructor(queue, collection) {
|
|
2046
|
+
this.queue = queue;
|
|
2047
|
+
this.collection = collection;
|
|
2048
|
+
}
|
|
2049
|
+
setBasedIndex(opts = {}) {
|
|
2050
|
+
return new OIMReactiveCollectionIndexManualSetBased(this.queue, {
|
|
2051
|
+
collection: this.collection,
|
|
2052
|
+
indexOptions: opts.indexOptions
|
|
2053
|
+
});
|
|
2054
|
+
}
|
|
2055
|
+
derivedSetIndex(selectIndexKeys, opts = {}) {
|
|
2056
|
+
return new OIMDerivedCollectionIndexSetBased(
|
|
2057
|
+
this.queue,
|
|
2058
|
+
this.collection,
|
|
2059
|
+
{
|
|
2060
|
+
selectIndexKeys,
|
|
2061
|
+
buildInitial: opts.buildInitial,
|
|
2062
|
+
indexOptions: opts.indexOptions
|
|
1954
2063
|
}
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
2064
|
+
);
|
|
2065
|
+
}
|
|
2066
|
+
arrayBasedIndex(opts = {}) {
|
|
2067
|
+
return new OIMReactiveCollectionIndexManualArrayBased(this.queue, {
|
|
2068
|
+
collection: this.collection,
|
|
2069
|
+
indexOptions: opts.indexOptions
|
|
2070
|
+
});
|
|
2071
|
+
}
|
|
2072
|
+
derivedArrayIndex(selectIndexKeys, opts = {}) {
|
|
2073
|
+
return new OIMDerivedCollectionIndexArrayBased(
|
|
2074
|
+
this.queue,
|
|
2075
|
+
this.collection,
|
|
2076
|
+
{
|
|
2077
|
+
selectIndexKeys,
|
|
2078
|
+
buildInitial: opts.buildInitial,
|
|
2079
|
+
compareEntities: opts.compareEntities,
|
|
2080
|
+
orderBy: opts.orderBy,
|
|
2081
|
+
indexOptions: opts.indexOptions
|
|
1959
2082
|
}
|
|
1960
|
-
|
|
1961
|
-
};
|
|
2083
|
+
);
|
|
1962
2084
|
}
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
}
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
2085
|
+
orderedIndex() {
|
|
2086
|
+
return new OIMCollectionIndexManualOrderedArrayBased({
|
|
2087
|
+
collection: this.collection
|
|
2088
|
+
});
|
|
2089
|
+
}
|
|
2090
|
+
orderedList(opts = {}) {
|
|
2091
|
+
return new OIMCollectionOrderedListCommandStream(
|
|
2092
|
+
this.queue,
|
|
2093
|
+
opts.index ? { collection: this.collection, index: opts.index } : { collection: this.collection }
|
|
2094
|
+
);
|
|
2095
|
+
}
|
|
2096
|
+
};
|
|
2097
|
+
function createOIMCollectionIndexFactory(queue, collection) {
|
|
2098
|
+
return new OIMCollectionIndexFactory(queue, collection);
|
|
2099
|
+
}
|
|
2100
|
+
|
|
2101
|
+
// src/core/OIMObjectStoreRecordDriven.ts
|
|
2102
|
+
var OIMObjectStoreRecordDriven = class extends OIMObjectStore {
|
|
2103
|
+
constructor(initial) {
|
|
2104
|
+
super();
|
|
2105
|
+
this.properties = Object.assign(/* @__PURE__ */ Object.create(null), initial ?? {});
|
|
2106
|
+
}
|
|
2107
|
+
setProperty(key, value) {
|
|
2108
|
+
this.properties[key] = value;
|
|
2109
|
+
}
|
|
2110
|
+
merge(draft) {
|
|
2111
|
+
Object.assign(this.properties, draft);
|
|
2112
|
+
}
|
|
2113
|
+
delete(key) {
|
|
2114
|
+
delete this.properties[key];
|
|
2115
|
+
}
|
|
2116
|
+
get(key) {
|
|
2117
|
+
return this.properties[key];
|
|
2118
|
+
}
|
|
2119
|
+
getAll() {
|
|
2120
|
+
return { ...this.properties };
|
|
2121
|
+
}
|
|
2122
|
+
clear() {
|
|
2123
|
+
this.properties = /* @__PURE__ */ Object.create(null);
|
|
2124
|
+
}
|
|
2125
|
+
count() {
|
|
2126
|
+
return Object.keys(this.properties).length;
|
|
2127
|
+
}
|
|
2128
|
+
keys() {
|
|
2129
|
+
return Object.keys(this.properties);
|
|
2130
|
+
}
|
|
2131
|
+
values() {
|
|
2132
|
+
return Object.values(this.properties);
|
|
2133
|
+
}
|
|
2134
|
+
entries() {
|
|
2135
|
+
return Object.entries(this.properties);
|
|
2136
|
+
}
|
|
2137
|
+
destroy() {
|
|
2138
|
+
this.clear();
|
|
2139
|
+
}
|
|
2140
|
+
};
|
|
2141
|
+
|
|
2142
|
+
// src/enums/EOIMObjectEventType.ts
|
|
2143
|
+
var EOIMObjectEventType = /* @__PURE__ */ ((EOIMObjectEventType2) => {
|
|
2144
|
+
EOIMObjectEventType2[EOIMObjectEventType2["UPDATE"] = 0] = "UPDATE";
|
|
2145
|
+
return EOIMObjectEventType2;
|
|
2146
|
+
})(EOIMObjectEventType || {});
|
|
2147
|
+
|
|
2148
|
+
// src/core/OIMObject.ts
|
|
2149
|
+
var OIMObject = class {
|
|
2150
|
+
constructor(opts) {
|
|
2151
|
+
this.emitter = new OIMEventEmitter();
|
|
2152
|
+
this.store = opts?.store ?? new OIMObjectStoreRecordDriven();
|
|
2153
|
+
}
|
|
2154
|
+
setProperty(key, value) {
|
|
2155
|
+
this.store.setProperty(key, value);
|
|
2156
|
+
this.emitter.emit(0 /* UPDATE */, { keys: [key] });
|
|
2157
|
+
}
|
|
2158
|
+
merge(draft) {
|
|
2159
|
+
this.store.merge(draft);
|
|
2160
|
+
this.emitter.emit(0 /* UPDATE */, {
|
|
2161
|
+
keys: Object.keys(draft)
|
|
2162
|
+
});
|
|
2163
|
+
}
|
|
2164
|
+
delete(key) {
|
|
2165
|
+
this.store.delete(key);
|
|
2166
|
+
this.emitter.emit(0 /* UPDATE */, { keys: [key] });
|
|
2167
|
+
}
|
|
2168
|
+
get(key) {
|
|
2169
|
+
return this.store.get(key);
|
|
2170
|
+
}
|
|
2171
|
+
getAll() {
|
|
2172
|
+
return this.store.getAll();
|
|
2173
|
+
}
|
|
2174
|
+
clear() {
|
|
2175
|
+
this.store.clear();
|
|
2176
|
+
this.emitter.emit(0 /* UPDATE */, { keys: [] });
|
|
2177
|
+
}
|
|
2178
|
+
count() {
|
|
2179
|
+
return this.store.count();
|
|
2180
|
+
}
|
|
2181
|
+
keys() {
|
|
2182
|
+
return this.store.keys();
|
|
2183
|
+
}
|
|
2184
|
+
values() {
|
|
2185
|
+
return this.store.values();
|
|
2186
|
+
}
|
|
2187
|
+
entries() {
|
|
2188
|
+
return this.store.entries();
|
|
2189
|
+
}
|
|
2190
|
+
destroy() {
|
|
2191
|
+
this.store.destroy();
|
|
2192
|
+
this.emitter.offAll();
|
|
2193
|
+
}
|
|
2194
|
+
};
|
|
2195
|
+
|
|
2196
|
+
// src/core/OIMReactiveObject.ts
|
|
2197
|
+
var OIMReactiveObject = class extends OIMObject {
|
|
2198
|
+
constructor(queue, opts) {
|
|
2199
|
+
super(opts);
|
|
2200
|
+
this.updateEmitter = new OIMUpdateEventEmitter(queue, "queue");
|
|
2201
|
+
this.emitter.on(0 /* UPDATE */, (payload) => {
|
|
2202
|
+
this.updateEmitter.markUpdatedKeys(payload.keys);
|
|
2203
|
+
});
|
|
2204
|
+
}
|
|
2205
|
+
subscribeOnKey(key, handler) {
|
|
2206
|
+
return this.updateEmitter.subscribeOnKey(key, handler);
|
|
2207
|
+
}
|
|
2208
|
+
subscribeOnKeys(keys, handler) {
|
|
2209
|
+
return this.updateEmitter.subscribeOnKeys(keys, handler);
|
|
2210
|
+
}
|
|
2211
|
+
unsubscribeFromKey(key, handler) {
|
|
2212
|
+
this.updateEmitter.unsubscribeFromKey(key, handler);
|
|
2213
|
+
}
|
|
2214
|
+
unsubscribeFromKeys(keys, handler) {
|
|
2215
|
+
this.updateEmitter.unsubscribeFromKeys(keys, handler);
|
|
2216
|
+
}
|
|
2217
|
+
hasSubscriptions() {
|
|
2218
|
+
return this.updateEmitter.hasSubscriptions();
|
|
2219
|
+
}
|
|
2220
|
+
getHandlerCount(key) {
|
|
2221
|
+
return this.updateEmitter.getHandlerCount(key);
|
|
2222
|
+
}
|
|
2223
|
+
getMetrics() {
|
|
2224
|
+
return this.updateEmitter.getMetrics();
|
|
2225
|
+
}
|
|
2226
|
+
destroy() {
|
|
2227
|
+
this.updateEmitter.destroy();
|
|
2228
|
+
super.destroy();
|
|
2229
|
+
}
|
|
2230
|
+
};
|
|
2231
|
+
|
|
2232
|
+
// src/core/OIMObjectStoreMapDriven.ts
|
|
2233
|
+
var OIMObjectStoreMapDriven = class extends OIMObjectStore {
|
|
2234
|
+
constructor() {
|
|
2235
|
+
super(...arguments);
|
|
2236
|
+
this.properties = /* @__PURE__ */ new Map();
|
|
2237
|
+
}
|
|
2238
|
+
setProperty(key, value) {
|
|
2239
|
+
this.properties.set(key, value);
|
|
2240
|
+
}
|
|
2241
|
+
merge(draft) {
|
|
2242
|
+
for (const key in draft) {
|
|
2243
|
+
if (!Object.prototype.hasOwnProperty.call(draft, key)) continue;
|
|
2244
|
+
this.properties.set(
|
|
2245
|
+
key,
|
|
2246
|
+
draft[key]
|
|
2247
|
+
);
|
|
2248
|
+
}
|
|
2249
|
+
}
|
|
2250
|
+
delete(key) {
|
|
2251
|
+
this.properties.delete(key);
|
|
2252
|
+
}
|
|
2253
|
+
get(key) {
|
|
2254
|
+
return this.properties.get(key);
|
|
2255
|
+
}
|
|
2256
|
+
getAll() {
|
|
2257
|
+
return Object.fromEntries(this.properties.entries());
|
|
2258
|
+
}
|
|
2259
|
+
clear() {
|
|
2260
|
+
this.properties.clear();
|
|
2261
|
+
}
|
|
2262
|
+
count() {
|
|
2263
|
+
return this.properties.size;
|
|
2264
|
+
}
|
|
2265
|
+
keys() {
|
|
2266
|
+
return Array.from(this.properties.keys());
|
|
2267
|
+
}
|
|
2268
|
+
values() {
|
|
2269
|
+
return Array.from(this.properties.values());
|
|
2270
|
+
}
|
|
2271
|
+
entries() {
|
|
2272
|
+
return Array.from(this.properties.entries());
|
|
2273
|
+
}
|
|
2274
|
+
destroy() {
|
|
2275
|
+
this.properties.clear();
|
|
2276
|
+
}
|
|
2277
|
+
};
|
|
2278
|
+
|
|
2279
|
+
// src/core/OIMComparatorFactory.ts
|
|
2280
|
+
var OIMComparatorFactory = class {
|
|
2281
|
+
createShallowComparator() {
|
|
2282
|
+
return (a, b) => {
|
|
2283
|
+
if (a === b) return false;
|
|
2284
|
+
const ka = Object.keys(a);
|
|
2285
|
+
const kb = Object.keys(b);
|
|
2286
|
+
if (ka.length !== kb.length) return true;
|
|
2287
|
+
for (let i = 0; i < ka.length; i++) {
|
|
2288
|
+
const k = ka[i];
|
|
2289
|
+
if (b[k] !== a[k])
|
|
2290
|
+
return true;
|
|
1981
2291
|
}
|
|
1982
|
-
return
|
|
2292
|
+
return false;
|
|
1983
2293
|
};
|
|
1984
2294
|
}
|
|
2295
|
+
};
|
|
2296
|
+
|
|
2297
|
+
// src/core/OIMEventQueue.ts
|
|
2298
|
+
var OIMEventQueue = class {
|
|
2299
|
+
constructor(options = {}) {
|
|
2300
|
+
this.emitter = new OIMEventEmitter();
|
|
2301
|
+
this.tasks = /* @__PURE__ */ new Set();
|
|
2302
|
+
this.isFlushing = false;
|
|
2303
|
+
this.scheduler = options.scheduler;
|
|
2304
|
+
if (this.scheduler) {
|
|
2305
|
+
this.flushBound = () => this.flush();
|
|
2306
|
+
this.scheduler.on(
|
|
2307
|
+
0 /* FLUSH */,
|
|
2308
|
+
this.flushBound
|
|
2309
|
+
);
|
|
2310
|
+
}
|
|
2311
|
+
}
|
|
1985
2312
|
/**
|
|
1986
|
-
*
|
|
1987
|
-
*
|
|
2313
|
+
* Enqueue a one-shot task to be executed on the next flush.
|
|
2314
|
+
* Returns a dequeue function that can be called to cancel the task before it runs.
|
|
1988
2315
|
*/
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
2316
|
+
enqueue(fn) {
|
|
2317
|
+
let isActive = true;
|
|
2318
|
+
const task = () => {
|
|
2319
|
+
if (!isActive) return;
|
|
2320
|
+
fn();
|
|
1992
2321
|
};
|
|
2322
|
+
this.tasks.add(task);
|
|
2323
|
+
this.ensureScheduled();
|
|
2324
|
+
return () => {
|
|
2325
|
+
if (!isActive) return;
|
|
2326
|
+
isActive = false;
|
|
2327
|
+
this.tasks.delete(task);
|
|
2328
|
+
};
|
|
2329
|
+
}
|
|
2330
|
+
get isInFlush() {
|
|
2331
|
+
return this.isFlushing;
|
|
1993
2332
|
}
|
|
1994
2333
|
/**
|
|
1995
|
-
*
|
|
1996
|
-
* Useful for disabling comparison while keeping the same interface.
|
|
2334
|
+
* Dequeue (cancel) a previously enqueued task by its dequeue function.
|
|
1997
2335
|
*/
|
|
1998
|
-
|
|
1999
|
-
|
|
2336
|
+
dequeue(dequeueFn) {
|
|
2337
|
+
dequeueFn();
|
|
2338
|
+
}
|
|
2339
|
+
/**
|
|
2340
|
+
* Execute all pending tasks.
|
|
2341
|
+
*
|
|
2342
|
+
* This flush drains until the queue is empty. If tasks enqueue more tasks, they will be
|
|
2343
|
+
* executed within the same flush.
|
|
2344
|
+
*/
|
|
2345
|
+
flush() {
|
|
2346
|
+
this.scheduler?.cancel();
|
|
2347
|
+
this.isFlushing = true;
|
|
2348
|
+
this.emitter.emit(1 /* BEFORE_FLUSH */, void 0);
|
|
2349
|
+
const snapshot = Array.from(this.tasks);
|
|
2350
|
+
this.tasks.clear();
|
|
2351
|
+
for (let i = 0; i < snapshot.length; i++) {
|
|
2352
|
+
snapshot[i]();
|
|
2353
|
+
}
|
|
2354
|
+
this.isFlushing = false;
|
|
2355
|
+
this.emitter.emit(0 /* AFTER_FLUSH */, void 0);
|
|
2356
|
+
}
|
|
2357
|
+
/**
|
|
2358
|
+
* Get the current number of queued functions.
|
|
2359
|
+
*/
|
|
2360
|
+
get length() {
|
|
2361
|
+
return this.tasks.size;
|
|
2362
|
+
}
|
|
2363
|
+
/**
|
|
2364
|
+
* Check if the queue is empty.
|
|
2365
|
+
*/
|
|
2366
|
+
get isEmpty() {
|
|
2367
|
+
return this.tasks.size === 0;
|
|
2368
|
+
}
|
|
2369
|
+
/**
|
|
2370
|
+
* Clear the queue without executing functions and cancel any scheduled flush.
|
|
2371
|
+
*/
|
|
2372
|
+
clear() {
|
|
2373
|
+
this.tasks.clear();
|
|
2374
|
+
this.scheduler?.cancel();
|
|
2375
|
+
}
|
|
2376
|
+
ensureScheduled() {
|
|
2377
|
+
if (!this.scheduler) return;
|
|
2378
|
+
if (this.isFlushing) return;
|
|
2379
|
+
if (this.tasks.size === 1) {
|
|
2380
|
+
this.scheduler.schedule();
|
|
2381
|
+
}
|
|
2382
|
+
}
|
|
2383
|
+
/**
|
|
2384
|
+
* Clean up scheduler subscription when queue is no longer needed.
|
|
2385
|
+
*/
|
|
2386
|
+
destroy() {
|
|
2387
|
+
if (this.scheduler && this.flushBound) {
|
|
2388
|
+
this.scheduler.off(
|
|
2389
|
+
0 /* FLUSH */,
|
|
2390
|
+
this.flushBound
|
|
2391
|
+
);
|
|
2392
|
+
}
|
|
2393
|
+
this.clear();
|
|
2394
|
+
}
|
|
2395
|
+
};
|
|
2396
|
+
|
|
2397
|
+
// src/core/OIMIndexComparatorFactory.ts
|
|
2398
|
+
var OIMIndexComparatorFactory = class {
|
|
2399
|
+
/**
|
|
2400
|
+
* Create an element-wise comparator that checks arrays for strict equality.
|
|
2401
|
+
* Compares array lengths and each element using strict equality (===).
|
|
2402
|
+
*/
|
|
2403
|
+
static createElementWiseComparator() {
|
|
2404
|
+
return (existingPks, newPks) => {
|
|
2405
|
+
if (existingPks.length !== newPks.length) {
|
|
2406
|
+
return false;
|
|
2407
|
+
}
|
|
2408
|
+
for (let i = 0; i < existingPks.length; i++) {
|
|
2409
|
+
if (existingPks[i] !== newPks[i]) {
|
|
2410
|
+
return false;
|
|
2411
|
+
}
|
|
2412
|
+
}
|
|
2413
|
+
return true;
|
|
2414
|
+
};
|
|
2415
|
+
}
|
|
2416
|
+
/**
|
|
2417
|
+
* Create a set-based comparator that checks if arrays contain the same elements.
|
|
2418
|
+
* Order doesn't matter, only the presence of elements.
|
|
2419
|
+
*/
|
|
2420
|
+
static createSetBasedComparator() {
|
|
2421
|
+
return (existingPks, newPks) => {
|
|
2422
|
+
if (existingPks.length !== newPks.length) {
|
|
2423
|
+
return false;
|
|
2424
|
+
}
|
|
2425
|
+
const existingSet = new Set(existingPks);
|
|
2426
|
+
const newSet = new Set(newPks);
|
|
2427
|
+
if (existingSet.size !== newSet.size || existingSet.size !== existingPks.length) {
|
|
2428
|
+
return false;
|
|
2429
|
+
}
|
|
2430
|
+
for (const pk of Array.from(existingSet)) {
|
|
2431
|
+
if (!newSet.has(pk)) {
|
|
2432
|
+
return false;
|
|
2433
|
+
}
|
|
2434
|
+
}
|
|
2435
|
+
return true;
|
|
2436
|
+
};
|
|
2437
|
+
}
|
|
2438
|
+
/**
|
|
2439
|
+
* Create a shallow comparator that only checks array references.
|
|
2440
|
+
* Fastest but only works if you're reusing the same array instances.
|
|
2441
|
+
*/
|
|
2442
|
+
static createShallowComparator() {
|
|
2443
|
+
return (existingPks, newPks) => {
|
|
2444
|
+
return existingPks === newPks;
|
|
2445
|
+
};
|
|
2446
|
+
}
|
|
2447
|
+
/**
|
|
2448
|
+
* Create a no-comparison comparator that always returns false (always updates).
|
|
2449
|
+
* Useful for disabling comparison while keeping the same interface.
|
|
2450
|
+
*/
|
|
2451
|
+
static createAlwaysUpdateComparator() {
|
|
2452
|
+
return () => false;
|
|
2453
|
+
}
|
|
2454
|
+
};
|
|
2455
|
+
|
|
2456
|
+
// src/core/OIMMap2Keys.ts
|
|
2457
|
+
var OIMMap2Keys = class {
|
|
2458
|
+
constructor() {
|
|
2459
|
+
this.map = /* @__PURE__ */ new Map();
|
|
2460
|
+
this._size = 0;
|
|
2461
|
+
}
|
|
2462
|
+
get size() {
|
|
2463
|
+
return this._size;
|
|
2464
|
+
}
|
|
2465
|
+
set(k1, k2, v) {
|
|
2466
|
+
let m = this.map.get(k1);
|
|
2467
|
+
if (!m) {
|
|
2468
|
+
m = /* @__PURE__ */ new Map();
|
|
2469
|
+
this.map.set(k1, m);
|
|
2470
|
+
}
|
|
2471
|
+
if (!m.has(k2)) this._size++;
|
|
2472
|
+
m.set(k2, v);
|
|
2473
|
+
}
|
|
2474
|
+
get(k1, k2) {
|
|
2475
|
+
return this.map.get(k1)?.get(k2);
|
|
2476
|
+
}
|
|
2477
|
+
has(k1, k2) {
|
|
2478
|
+
return this.map.get(k1)?.has(k2);
|
|
2479
|
+
}
|
|
2480
|
+
delete(k1, k2) {
|
|
2481
|
+
const m = this.map.get(k1);
|
|
2482
|
+
if (!m) return false;
|
|
2483
|
+
const had = m.delete(k2);
|
|
2484
|
+
if (had) {
|
|
2485
|
+
this._size--;
|
|
2486
|
+
if (m.size === 0) this.map.delete(k1);
|
|
2487
|
+
}
|
|
2488
|
+
return had;
|
|
2489
|
+
}
|
|
2490
|
+
clear() {
|
|
2491
|
+
this.map.clear();
|
|
2492
|
+
this._size = 0;
|
|
2493
|
+
}
|
|
2494
|
+
};
|
|
2495
|
+
|
|
2496
|
+
// src/modules/compute/core/OIMComputeRuntime.ts
|
|
2497
|
+
var OIMComputeRuntime = class {
|
|
2498
|
+
constructor(queue) {
|
|
2499
|
+
this.queue = queue;
|
|
2500
|
+
this.isFlushScheduled = false;
|
|
2501
|
+
this.isFlushing = false;
|
|
2502
|
+
this.minLevel = Infinity;
|
|
2503
|
+
this.maxLevel = -Infinity;
|
|
2504
|
+
this.dirtyByLevel = /* @__PURE__ */ new Map();
|
|
2505
|
+
this.afterFlushTasks = /* @__PURE__ */ new Set();
|
|
2506
|
+
this.queue.emitter.on(0 /* AFTER_FLUSH */, () => {
|
|
2507
|
+
if (!this.isFlushScheduled) return;
|
|
2508
|
+
this.flush();
|
|
2509
|
+
});
|
|
2510
|
+
}
|
|
2511
|
+
/**
|
|
2512
|
+
* Schedule a one-shot task to run on the next `queue.flush()` (AFTER_FLUSH),
|
|
2513
|
+
* ordered by `level` ascending.
|
|
2514
|
+
*/
|
|
2515
|
+
schedule(task, level = 0) {
|
|
2516
|
+
let isActive = true;
|
|
2517
|
+
const wrapped = () => {
|
|
2518
|
+
if (!isActive) return;
|
|
2519
|
+
task();
|
|
2520
|
+
};
|
|
2521
|
+
let bucket = this.dirtyByLevel.get(level);
|
|
2522
|
+
if (!bucket) {
|
|
2523
|
+
bucket = /* @__PURE__ */ new Set();
|
|
2524
|
+
this.dirtyByLevel.set(level, bucket);
|
|
2525
|
+
}
|
|
2526
|
+
bucket.add(wrapped);
|
|
2527
|
+
if (level < this.minLevel) this.minLevel = level;
|
|
2528
|
+
if (level > this.maxLevel) this.maxLevel = level;
|
|
2529
|
+
if (!this.isFlushing) this.isFlushScheduled = true;
|
|
2530
|
+
return () => {
|
|
2531
|
+
if (!isActive) return;
|
|
2532
|
+
isActive = false;
|
|
2533
|
+
bucket.delete(wrapped);
|
|
2534
|
+
};
|
|
2535
|
+
}
|
|
2536
|
+
/**
|
|
2537
|
+
* Run once at the start of the next runtime flush (i.e. after queue.flush()).
|
|
2538
|
+
* Useful for resubscribing dependencies exactly once per source flush.
|
|
2539
|
+
*/
|
|
2540
|
+
scheduleAfterFlush(task) {
|
|
2541
|
+
let isActive = true;
|
|
2542
|
+
const wrapped = () => {
|
|
2543
|
+
if (!isActive) return;
|
|
2544
|
+
task();
|
|
2545
|
+
};
|
|
2546
|
+
this.afterFlushTasks.add(wrapped);
|
|
2547
|
+
if (!this.isFlushing) this.isFlushScheduled = true;
|
|
2548
|
+
return () => {
|
|
2549
|
+
if (!isActive) return;
|
|
2550
|
+
isActive = false;
|
|
2551
|
+
this.afterFlushTasks.delete(wrapped);
|
|
2552
|
+
};
|
|
2553
|
+
}
|
|
2554
|
+
flush() {
|
|
2555
|
+
this.isFlushScheduled = false;
|
|
2556
|
+
if (this.dirtyByLevel.size === 0 && this.afterFlushTasks.size === 0)
|
|
2557
|
+
return;
|
|
2558
|
+
this.isFlushing = true;
|
|
2559
|
+
try {
|
|
2560
|
+
if (this.afterFlushTasks.size > 0) {
|
|
2561
|
+
const snapshot = Array.from(this.afterFlushTasks);
|
|
2562
|
+
this.afterFlushTasks.clear();
|
|
2563
|
+
for (let i = 0; i < snapshot.length; i++) snapshot[i]();
|
|
2564
|
+
}
|
|
2565
|
+
if (this.dirtyByLevel.size === 0) return;
|
|
2566
|
+
let level = this.minLevel;
|
|
2567
|
+
let max = this.maxLevel;
|
|
2568
|
+
while (level <= max) {
|
|
2569
|
+
for (; ; ) {
|
|
2570
|
+
const bucket = this.dirtyByLevel.get(level);
|
|
2571
|
+
if (!bucket || bucket.size === 0) break;
|
|
2572
|
+
this.dirtyByLevel.delete(level);
|
|
2573
|
+
const snapshot = Array.from(bucket);
|
|
2574
|
+
for (let i = 0; i < snapshot.length; i++) snapshot[i]();
|
|
2575
|
+
}
|
|
2576
|
+
if (this.maxLevel > max) max = this.maxLevel;
|
|
2577
|
+
level++;
|
|
2578
|
+
}
|
|
2579
|
+
} finally {
|
|
2580
|
+
this.isFlushing = false;
|
|
2581
|
+
if (this.dirtyByLevel.size === 0) {
|
|
2582
|
+
this.minLevel = Infinity;
|
|
2583
|
+
this.maxLevel = -Infinity;
|
|
2584
|
+
} else {
|
|
2585
|
+
let nextMin = Infinity;
|
|
2586
|
+
let nextMax = -Infinity;
|
|
2587
|
+
this.dirtyByLevel.forEach((_bucket, lvl) => {
|
|
2588
|
+
if (lvl < nextMin) nextMin = lvl;
|
|
2589
|
+
if (lvl > nextMax) nextMax = lvl;
|
|
2590
|
+
});
|
|
2591
|
+
this.minLevel = nextMin;
|
|
2592
|
+
this.maxLevel = nextMax;
|
|
2593
|
+
this.isFlushScheduled = true;
|
|
2594
|
+
}
|
|
2595
|
+
}
|
|
2596
|
+
}
|
|
2597
|
+
};
|
|
2598
|
+
|
|
2599
|
+
// src/modules/selector/core/OIMSelector.ts
|
|
2600
|
+
var OIMSelector = class {
|
|
2601
|
+
constructor(runtime, sourceDeps, computedDeps = []) {
|
|
2602
|
+
this.runtime = runtime;
|
|
2603
|
+
this.sourceDeps = sourceDeps;
|
|
2604
|
+
this.computedDeps = computedDeps;
|
|
2605
|
+
this.listeners = /* @__PURE__ */ new Set();
|
|
2606
|
+
this.sourceUnsubscribers = [];
|
|
2607
|
+
this.computedUnsubscribers = [];
|
|
2608
|
+
this.isResubscribeEnqueued = false;
|
|
2609
|
+
this.isTemporarilyUnsubscribedForFlush = false;
|
|
2610
|
+
this.isDeliveryEnqueued = false;
|
|
2611
|
+
this.hasLastValue = false;
|
|
2612
|
+
this.onSourceInvalidate = () => {
|
|
2613
|
+
if (this.listeners.size === 0) return;
|
|
2614
|
+
if (!this.isTemporarilyUnsubscribedForFlush) {
|
|
2615
|
+
this.isTemporarilyUnsubscribedForFlush = true;
|
|
2616
|
+
this.unsubscribeFromSourceDeps();
|
|
2617
|
+
this.ensureResubscribeAfterFlush();
|
|
2618
|
+
}
|
|
2619
|
+
if (this.isDeliveryEnqueued) return;
|
|
2620
|
+
this.isDeliveryEnqueued = true;
|
|
2621
|
+
this.dequeueDelivery = this.runtime.schedule(this.deliver);
|
|
2622
|
+
};
|
|
2623
|
+
this.onComputedInvalidate = () => {
|
|
2624
|
+
if (this.listeners.size === 0) return;
|
|
2625
|
+
if (this.isDeliveryEnqueued) return;
|
|
2626
|
+
this.isDeliveryEnqueued = true;
|
|
2627
|
+
this.dequeueDelivery = this.runtime.schedule(this.deliver);
|
|
2628
|
+
};
|
|
2629
|
+
this.deliver = () => {
|
|
2630
|
+
this.isDeliveryEnqueued = false;
|
|
2631
|
+
this.dequeueDelivery = void 0;
|
|
2632
|
+
if (this.listeners.size === 0) return;
|
|
2633
|
+
const next = this.getValue();
|
|
2634
|
+
if (this.hasLastValue && this.areEqual(this.lastValue, next)) return;
|
|
2635
|
+
this.setLastValue(next);
|
|
2636
|
+
const snapshot = Array.from(this.listeners);
|
|
2637
|
+
for (let i = 0; i < snapshot.length; i++) {
|
|
2638
|
+
const listener = snapshot[i];
|
|
2639
|
+
if (this.listeners.has(listener)) listener(next);
|
|
2640
|
+
}
|
|
2641
|
+
};
|
|
2642
|
+
this.onAfterFlush = () => {
|
|
2643
|
+
if (!this.isResubscribeEnqueued) return;
|
|
2644
|
+
this.isResubscribeEnqueued = false;
|
|
2645
|
+
this.dequeueResubscribe = void 0;
|
|
2646
|
+
if (this.listeners.size === 0) return;
|
|
2647
|
+
this.isTemporarilyUnsubscribedForFlush = false;
|
|
2648
|
+
if (this.sourceUnsubscribers.length === 0) {
|
|
2649
|
+
for (const dep of this.sourceDeps) {
|
|
2650
|
+
this.sourceUnsubscribers.push(
|
|
2651
|
+
dep.subscribe(this.onSourceInvalidate)
|
|
2652
|
+
);
|
|
2653
|
+
}
|
|
2654
|
+
}
|
|
2655
|
+
};
|
|
2656
|
+
}
|
|
2657
|
+
get queue() {
|
|
2658
|
+
return this.runtime.queue;
|
|
2659
|
+
}
|
|
2660
|
+
/**
|
|
2661
|
+
* Start watching this selector. The callback is called immediately with the current value,
|
|
2662
|
+
* then coalesced and delivered on `queue.flush()` when the selector invalidates.
|
|
2663
|
+
*/
|
|
2664
|
+
watch(onValue) {
|
|
2665
|
+
this.listeners.add(onValue);
|
|
2666
|
+
if (this.listeners.size === 1) {
|
|
2667
|
+
this.subscribeToDeps();
|
|
2668
|
+
}
|
|
2669
|
+
const current = this.getValue();
|
|
2670
|
+
this.setLastValue(current);
|
|
2671
|
+
onValue(current);
|
|
2672
|
+
return () => {
|
|
2673
|
+
this.listeners.delete(onValue);
|
|
2674
|
+
if (this.listeners.size > 0) return;
|
|
2675
|
+
this.unsubscribeFromAllDeps();
|
|
2676
|
+
if (this.dequeueResubscribe) {
|
|
2677
|
+
this.dequeueResubscribe();
|
|
2678
|
+
this.dequeueResubscribe = void 0;
|
|
2679
|
+
}
|
|
2680
|
+
this.isResubscribeEnqueued = false;
|
|
2681
|
+
this.isTemporarilyUnsubscribedForFlush = false;
|
|
2682
|
+
if (this.dequeueDelivery) {
|
|
2683
|
+
this.dequeueDelivery();
|
|
2684
|
+
this.dequeueDelivery = void 0;
|
|
2685
|
+
}
|
|
2686
|
+
this.isDeliveryEnqueued = false;
|
|
2687
|
+
this.hasLastValue = false;
|
|
2688
|
+
};
|
|
2689
|
+
}
|
|
2690
|
+
areEqual(prev, next) {
|
|
2691
|
+
return Object.is(prev, next);
|
|
2692
|
+
}
|
|
2693
|
+
setLastValue(value) {
|
|
2694
|
+
this.lastValue = value;
|
|
2695
|
+
this.hasLastValue = true;
|
|
2696
|
+
}
|
|
2697
|
+
subscribeToDeps() {
|
|
2698
|
+
if (this.sourceUnsubscribers.length > 0 || this.computedUnsubscribers.length > 0)
|
|
2699
|
+
return;
|
|
2700
|
+
for (const dep of this.sourceDeps) {
|
|
2701
|
+
this.sourceUnsubscribers.push(
|
|
2702
|
+
dep.subscribe(this.onSourceInvalidate)
|
|
2703
|
+
);
|
|
2704
|
+
}
|
|
2705
|
+
for (const dep of this.computedDeps) {
|
|
2706
|
+
this.computedUnsubscribers.push(
|
|
2707
|
+
dep.subscribe(this.onComputedInvalidate)
|
|
2708
|
+
);
|
|
2709
|
+
}
|
|
2710
|
+
}
|
|
2711
|
+
unsubscribeFromSourceDeps() {
|
|
2712
|
+
if (this.sourceUnsubscribers.length === 0) return;
|
|
2713
|
+
for (const unsub of this.sourceUnsubscribers) unsub();
|
|
2714
|
+
this.sourceUnsubscribers = [];
|
|
2715
|
+
}
|
|
2716
|
+
unsubscribeFromAllDeps() {
|
|
2717
|
+
this.unsubscribeFromSourceDeps();
|
|
2718
|
+
if (this.computedUnsubscribers.length === 0) return;
|
|
2719
|
+
for (const unsub of this.computedUnsubscribers) unsub();
|
|
2720
|
+
this.computedUnsubscribers = [];
|
|
2721
|
+
}
|
|
2722
|
+
ensureResubscribeAfterFlush() {
|
|
2723
|
+
if (this.isResubscribeEnqueued) return;
|
|
2724
|
+
this.isResubscribeEnqueued = true;
|
|
2725
|
+
this.dequeueResubscribe = this.runtime.scheduleAfterFlush(
|
|
2726
|
+
this.onAfterFlush
|
|
2727
|
+
);
|
|
2728
|
+
}
|
|
2729
|
+
};
|
|
2730
|
+
|
|
2731
|
+
// src/modules/selector/core/OIMSelectorSourceDependencyUpdateEventEmitterKey.ts
|
|
2732
|
+
var OIMSelectorSourceDependencyUpdateEventEmitterKey = class {
|
|
2733
|
+
constructor(subscription, key) {
|
|
2734
|
+
this.subscription = subscription;
|
|
2735
|
+
this.key = key;
|
|
2736
|
+
}
|
|
2737
|
+
subscribe(onUpdate) {
|
|
2738
|
+
return this.subscription.subscribeOnKey(this.key, onUpdate);
|
|
2739
|
+
}
|
|
2740
|
+
};
|
|
2741
|
+
|
|
2742
|
+
// src/modules/selector/core/OIMCollectionByPkSelector.ts
|
|
2743
|
+
var OIMCollectionByPkSelector = class extends OIMSelector {
|
|
2744
|
+
constructor(runtime, collection, pk) {
|
|
2745
|
+
super(runtime, [
|
|
2746
|
+
new OIMSelectorSourceDependencyUpdateEventEmitterKey(
|
|
2747
|
+
collection,
|
|
2748
|
+
pk
|
|
2749
|
+
)
|
|
2750
|
+
]);
|
|
2751
|
+
this.collection = collection;
|
|
2752
|
+
this.pk = pk;
|
|
2753
|
+
}
|
|
2754
|
+
getValue() {
|
|
2755
|
+
return this.collection.getOneByPk(this.pk);
|
|
2756
|
+
}
|
|
2757
|
+
};
|
|
2758
|
+
|
|
2759
|
+
// src/modules/selector/core/OIMSelectorSourceDependencyUpdateEventEmitterKeys.ts
|
|
2760
|
+
var OIMSelectorSourceDependencyUpdateEventEmitterKeys = class {
|
|
2761
|
+
constructor(subscription, keys) {
|
|
2762
|
+
this.subscription = subscription;
|
|
2763
|
+
this.keys = keys;
|
|
2764
|
+
}
|
|
2765
|
+
subscribe(onUpdate) {
|
|
2766
|
+
return this.subscription.subscribeOnKeys(this.keys, onUpdate);
|
|
2767
|
+
}
|
|
2768
|
+
};
|
|
2769
|
+
|
|
2770
|
+
// src/modules/selector/core/OIMCollectionByPksSelector.ts
|
|
2771
|
+
var OIMCollectionByPksSelector = class extends OIMSelector {
|
|
2772
|
+
constructor(runtime, collection, pks) {
|
|
2773
|
+
super(runtime, [
|
|
2774
|
+
new OIMSelectorSourceDependencyUpdateEventEmitterKeys(
|
|
2775
|
+
collection,
|
|
2776
|
+
pks
|
|
2777
|
+
)
|
|
2778
|
+
]);
|
|
2779
|
+
this.collection = collection;
|
|
2780
|
+
this.pks = pks;
|
|
2781
|
+
}
|
|
2782
|
+
getValue() {
|
|
2783
|
+
return this.pks.map((pk) => this.collection.getOneByPk(pk));
|
|
2784
|
+
}
|
|
2785
|
+
areEqual(prev, next) {
|
|
2786
|
+
if (prev === next) return true;
|
|
2787
|
+
if (prev.length !== next.length) return false;
|
|
2788
|
+
for (let i = 0; i < prev.length; i++) {
|
|
2789
|
+
if (prev[i] !== next[i]) return false;
|
|
2790
|
+
}
|
|
2791
|
+
return true;
|
|
2792
|
+
}
|
|
2793
|
+
};
|
|
2794
|
+
|
|
2795
|
+
// src/modules/selector/core/OIMSelectorSourceDependencyEntitiesByIndexKeyArrayBased.ts
|
|
2796
|
+
var OIMSelectorSourceDependencyEntitiesByIndexKeyArrayBased = class {
|
|
2797
|
+
constructor(collection, reactiveIndex, key) {
|
|
2798
|
+
this.collection = collection;
|
|
2799
|
+
this.reactiveIndex = reactiveIndex;
|
|
2800
|
+
this.key = key;
|
|
2801
|
+
this.currentPks = [];
|
|
2802
|
+
}
|
|
2803
|
+
subscribe(onUpdate) {
|
|
2804
|
+
const resubscribeCollection = () => {
|
|
2805
|
+
const nextPks = this.reactiveIndex.getPksByKey(this.key);
|
|
2806
|
+
if (this.sameArray(this.currentPks, nextPks)) return;
|
|
2807
|
+
this.unsubscribeFromCollectionKeys?.();
|
|
2808
|
+
this.unsubscribeFromCollectionKeys = void 0;
|
|
2809
|
+
this.currentPks = nextPks;
|
|
2810
|
+
if (this.currentPks.length === 0) return;
|
|
2811
|
+
this.unsubscribeFromCollectionKeys = this.collection.subscribeOnKeys(this.currentPks, onUpdate);
|
|
2812
|
+
};
|
|
2813
|
+
const onIndexUpdate = () => {
|
|
2814
|
+
resubscribeCollection();
|
|
2815
|
+
onUpdate();
|
|
2816
|
+
};
|
|
2817
|
+
resubscribeCollection();
|
|
2818
|
+
const unsubscribeFromIndex = this.reactiveIndex.subscribeOnKey(
|
|
2819
|
+
this.key,
|
|
2820
|
+
onIndexUpdate
|
|
2821
|
+
);
|
|
2822
|
+
return () => {
|
|
2823
|
+
unsubscribeFromIndex();
|
|
2824
|
+
this.unsubscribeFromCollectionKeys?.();
|
|
2825
|
+
this.unsubscribeFromCollectionKeys = void 0;
|
|
2826
|
+
this.currentPks = [];
|
|
2827
|
+
};
|
|
2828
|
+
}
|
|
2829
|
+
sameArray(a, b) {
|
|
2830
|
+
if (a === b) return true;
|
|
2831
|
+
if (a.length !== b.length) return false;
|
|
2832
|
+
for (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return false;
|
|
2833
|
+
return true;
|
|
2834
|
+
}
|
|
2835
|
+
};
|
|
2836
|
+
|
|
2837
|
+
// src/modules/selector/core/OIMEntitiesByIndexKeyArrayBasedSelector.ts
|
|
2838
|
+
var OIMEntitiesByIndexKeyArrayBasedSelector = class extends OIMSelector {
|
|
2839
|
+
constructor(runtime, collection, reactiveIndex, key) {
|
|
2840
|
+
super(runtime, [
|
|
2841
|
+
new OIMSelectorSourceDependencyEntitiesByIndexKeyArrayBased(collection, reactiveIndex, key)
|
|
2842
|
+
]);
|
|
2843
|
+
this.collection = collection;
|
|
2844
|
+
this.reactiveIndex = reactiveIndex;
|
|
2845
|
+
this.key = key;
|
|
2846
|
+
}
|
|
2847
|
+
getValue() {
|
|
2848
|
+
const pks = this.reactiveIndex.getPksByKey(this.key);
|
|
2849
|
+
const entities = [];
|
|
2850
|
+
entities.length = pks.length;
|
|
2851
|
+
for (let i = 0; i < pks.length; i++) {
|
|
2852
|
+
entities[i] = this.collection.getOneByPk(pks[i]);
|
|
2853
|
+
}
|
|
2854
|
+
return entities;
|
|
2855
|
+
}
|
|
2856
|
+
areEqual(prev, next) {
|
|
2857
|
+
if (prev === next) return true;
|
|
2858
|
+
if (prev.length !== next.length) return false;
|
|
2859
|
+
for (let i = 0; i < prev.length; i++)
|
|
2860
|
+
if (prev[i] !== next[i]) return false;
|
|
2861
|
+
return true;
|
|
2862
|
+
}
|
|
2863
|
+
};
|
|
2864
|
+
|
|
2865
|
+
// src/modules/selector/core/OIMSelectorSourceDependencyEntitiesByIndexKeySetBased.ts
|
|
2866
|
+
var OIMSelectorSourceDependencyEntitiesByIndexKeySetBased = class {
|
|
2867
|
+
constructor(collection, reactiveIndex, key) {
|
|
2868
|
+
this.collection = collection;
|
|
2869
|
+
this.reactiveIndex = reactiveIndex;
|
|
2870
|
+
this.key = key;
|
|
2871
|
+
this.currentPks = [];
|
|
2872
|
+
}
|
|
2873
|
+
subscribe(onUpdate) {
|
|
2874
|
+
const resubscribeCollection = () => {
|
|
2875
|
+
const nextPks = Array.from(this.reactiveIndex.getPksByKey(this.key));
|
|
2876
|
+
if (this.sameArray(this.currentPks, nextPks)) return;
|
|
2877
|
+
this.unsubscribeFromCollectionKeys?.();
|
|
2878
|
+
this.unsubscribeFromCollectionKeys = void 0;
|
|
2879
|
+
this.currentPks = nextPks;
|
|
2880
|
+
if (this.currentPks.length === 0) return;
|
|
2881
|
+
this.unsubscribeFromCollectionKeys = this.collection.subscribeOnKeys(this.currentPks, onUpdate);
|
|
2882
|
+
};
|
|
2883
|
+
const onIndexUpdate = () => {
|
|
2884
|
+
resubscribeCollection();
|
|
2885
|
+
onUpdate();
|
|
2886
|
+
};
|
|
2887
|
+
resubscribeCollection();
|
|
2888
|
+
const unsubscribeFromIndex = this.reactiveIndex.subscribeOnKey(
|
|
2889
|
+
this.key,
|
|
2890
|
+
onIndexUpdate
|
|
2891
|
+
);
|
|
2892
|
+
return () => {
|
|
2893
|
+
unsubscribeFromIndex();
|
|
2894
|
+
this.unsubscribeFromCollectionKeys?.();
|
|
2895
|
+
this.unsubscribeFromCollectionKeys = void 0;
|
|
2896
|
+
this.currentPks = [];
|
|
2897
|
+
};
|
|
2898
|
+
}
|
|
2899
|
+
sameArray(a, b) {
|
|
2900
|
+
if (a === b) return true;
|
|
2901
|
+
if (a.length !== b.length) return false;
|
|
2902
|
+
for (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return false;
|
|
2903
|
+
return true;
|
|
2000
2904
|
}
|
|
2001
2905
|
};
|
|
2002
2906
|
|
|
2003
|
-
// src/core/
|
|
2004
|
-
var
|
|
2005
|
-
constructor() {
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2907
|
+
// src/modules/selector/core/OIMEntitiesByIndexKeySetBasedSelector.ts
|
|
2908
|
+
var OIMEntitiesByIndexKeySetBasedSelector = class extends OIMSelector {
|
|
2909
|
+
constructor(runtime, collection, reactiveIndex, key) {
|
|
2910
|
+
super(runtime, [
|
|
2911
|
+
new OIMSelectorSourceDependencyEntitiesByIndexKeySetBased(collection, reactiveIndex, key)
|
|
2912
|
+
]);
|
|
2913
|
+
this.collection = collection;
|
|
2914
|
+
this.reactiveIndex = reactiveIndex;
|
|
2915
|
+
this.key = key;
|
|
2011
2916
|
}
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2917
|
+
getValue() {
|
|
2918
|
+
const pks = this.reactiveIndex.getPksByKey(this.key);
|
|
2919
|
+
const entities = [];
|
|
2920
|
+
entities.length = pks.size;
|
|
2921
|
+
let writeIndex = 0;
|
|
2922
|
+
for (const pk of pks) {
|
|
2923
|
+
entities[writeIndex++] = this.collection.getOneByPk(pk);
|
|
2017
2924
|
}
|
|
2018
|
-
|
|
2019
|
-
m.set(k2, v);
|
|
2925
|
+
return entities;
|
|
2020
2926
|
}
|
|
2021
|
-
|
|
2022
|
-
|
|
2927
|
+
areEqual(prev, next) {
|
|
2928
|
+
if (prev === next) return true;
|
|
2929
|
+
if (prev.length !== next.length) return false;
|
|
2930
|
+
for (let i = 0; i < prev.length; i++)
|
|
2931
|
+
if (prev[i] !== next[i]) return false;
|
|
2932
|
+
return true;
|
|
2023
2933
|
}
|
|
2024
|
-
|
|
2025
|
-
|
|
2934
|
+
};
|
|
2935
|
+
|
|
2936
|
+
// src/dx/OIMCollectionSelectors.ts
|
|
2937
|
+
var OIMCollectionSelectors = class {
|
|
2938
|
+
constructor(queue, collection) {
|
|
2939
|
+
this.collection = collection;
|
|
2940
|
+
this.runtime = new OIMComputeRuntime(queue);
|
|
2026
2941
|
}
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
if (!m) return false;
|
|
2030
|
-
const had = m.delete(k2);
|
|
2031
|
-
if (had) {
|
|
2032
|
-
this._size--;
|
|
2033
|
-
if (m.size === 0) this.map.delete(k1);
|
|
2034
|
-
}
|
|
2035
|
-
return had;
|
|
2942
|
+
byPk(pk) {
|
|
2943
|
+
return new OIMCollectionByPkSelector(this.runtime, this.collection, pk);
|
|
2036
2944
|
}
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2945
|
+
byPks(pks) {
|
|
2946
|
+
return new OIMCollectionByPksSelector(
|
|
2947
|
+
this.runtime,
|
|
2948
|
+
this.collection,
|
|
2949
|
+
pks
|
|
2950
|
+
);
|
|
2951
|
+
}
|
|
2952
|
+
entitiesBySetIndexKey(index, key) {
|
|
2953
|
+
return new OIMEntitiesByIndexKeySetBasedSelector(
|
|
2954
|
+
this.runtime,
|
|
2955
|
+
this.collection,
|
|
2956
|
+
index,
|
|
2957
|
+
key
|
|
2958
|
+
);
|
|
2959
|
+
}
|
|
2960
|
+
entitiesByArrayIndexKey(index, key) {
|
|
2961
|
+
return new OIMEntitiesByIndexKeyArrayBasedSelector(
|
|
2962
|
+
this.runtime,
|
|
2963
|
+
this.collection,
|
|
2964
|
+
index,
|
|
2965
|
+
key
|
|
2966
|
+
);
|
|
2040
2967
|
}
|
|
2041
2968
|
};
|
|
2042
2969
|
|
|
2043
|
-
// src/
|
|
2044
|
-
|
|
2970
|
+
// src/dx/OIMCollectionContext.ts
|
|
2971
|
+
function createOIMCollectionContext(queue, opts) {
|
|
2972
|
+
const collection = new OIMReactiveCollection(queue, opts);
|
|
2973
|
+
const indexFactory = new OIMCollectionIndexFactory(queue, collection);
|
|
2974
|
+
const select = new OIMCollectionSelectors(queue, collection);
|
|
2975
|
+
return { queue, collection, indexFactory, select };
|
|
2976
|
+
}
|
|
2977
|
+
|
|
2978
|
+
// src/modules/wrapper/collection/OIMCollectionChangedFields.ts
|
|
2979
|
+
var OIMCollectionChangedFields = class {
|
|
2045
2980
|
constructor(queue, collection, opts) {
|
|
2046
2981
|
this.isInWrite = false;
|
|
2047
2982
|
this.lastEntitySnapshotByPk = /* @__PURE__ */ new Map();
|
|
@@ -2061,7 +2996,7 @@ var OIMCollectionChangedFieldsWrapper = class {
|
|
|
2061
2996
|
this.collection = collection;
|
|
2062
2997
|
this.selectPk = opts?.selectPk ?? (() => {
|
|
2063
2998
|
throw new Error(
|
|
2064
|
-
`[
|
|
2999
|
+
`[OIMCollectionChangedFields]: selectPk was not provided. Use upsertOneByPk(...) or pass opts.selectPk.`
|
|
2065
3000
|
);
|
|
2066
3001
|
});
|
|
2067
3002
|
this.changedPksEventEmitter = new OIMUpdateEventEmitter(
|
|
@@ -2084,31 +3019,34 @@ var OIMCollectionChangedFieldsWrapper = class {
|
|
|
2084
3019
|
);
|
|
2085
3020
|
}
|
|
2086
3021
|
upsertOneByPk(pk, patch) {
|
|
2087
|
-
this.withWrite(() => {
|
|
3022
|
+
const slot = this.withWrite(() => {
|
|
2088
3023
|
this.trackPatch(pk, patch);
|
|
2089
|
-
this.collection.upsertOneByPk(pk, patch);
|
|
3024
|
+
return this.collection.upsertOneByPk(pk, patch);
|
|
2090
3025
|
});
|
|
2091
3026
|
this.updateEntitySnapshot(pk);
|
|
3027
|
+
return slot;
|
|
2092
3028
|
}
|
|
2093
3029
|
upsertOne(entity) {
|
|
2094
|
-
this.withWrite(() => {
|
|
3030
|
+
const slot = this.withWrite(() => {
|
|
2095
3031
|
const pk = this.selectPk(entity);
|
|
2096
3032
|
this.trackPatch(pk, entity);
|
|
2097
|
-
this.collection.upsertOne(entity);
|
|
3033
|
+
return this.collection.upsertOne(entity);
|
|
2098
3034
|
});
|
|
2099
|
-
this.updateEntitySnapshot(
|
|
3035
|
+
this.updateEntitySnapshot(slot.pk);
|
|
3036
|
+
return slot;
|
|
2100
3037
|
}
|
|
2101
3038
|
upsertMany(entities) {
|
|
2102
3039
|
const pks = [];
|
|
2103
|
-
this.withWrite(() => {
|
|
3040
|
+
const slots = this.withWrite(() => {
|
|
2104
3041
|
for (const entity of entities) {
|
|
2105
3042
|
const pk = this.selectPk(entity);
|
|
2106
3043
|
pks.push(pk);
|
|
2107
3044
|
this.trackPatch(pk, entity);
|
|
2108
3045
|
}
|
|
2109
|
-
this.collection.upsertMany(entities);
|
|
3046
|
+
return this.collection.upsertMany(entities);
|
|
2110
3047
|
});
|
|
2111
3048
|
for (let i = 0; i < pks.length; i++) this.updateEntitySnapshot(pks[i]);
|
|
3049
|
+
return slots;
|
|
2112
3050
|
}
|
|
2113
3051
|
getChangedFieldsByPk(pk) {
|
|
2114
3052
|
return this.changedFieldsByPk.get(pk) ?? /* @__PURE__ */ new Set();
|
|
@@ -2139,12 +3077,11 @@ var OIMCollectionChangedFieldsWrapper = class {
|
|
|
2139
3077
|
}
|
|
2140
3078
|
withWrite(fn) {
|
|
2141
3079
|
if (this.isInWrite) {
|
|
2142
|
-
fn();
|
|
2143
|
-
return;
|
|
3080
|
+
return fn();
|
|
2144
3081
|
}
|
|
2145
3082
|
this.isInWrite = true;
|
|
2146
3083
|
try {
|
|
2147
|
-
fn();
|
|
3084
|
+
return fn();
|
|
2148
3085
|
} finally {
|
|
2149
3086
|
this.isInWrite = false;
|
|
2150
3087
|
}
|
|
@@ -2176,248 +3113,43 @@ var OIMCollectionChangedFieldsWrapper = class {
|
|
|
2176
3113
|
});
|
|
2177
3114
|
return changed;
|
|
2178
3115
|
}
|
|
2179
|
-
updateEntitySnapshot(pk) {
|
|
2180
|
-
const entity = this.collection.getOneByPk(pk);
|
|
2181
|
-
if (!entity) {
|
|
2182
|
-
this.lastEntitySnapshotByPk.delete(pk);
|
|
2183
|
-
return;
|
|
2184
|
-
}
|
|
2185
|
-
this.lastEntitySnapshotByPk.set(pk, {
|
|
2186
|
-
...entity
|
|
2187
|
-
});
|
|
2188
|
-
}
|
|
2189
|
-
trackChangedKeys(pk, keys) {
|
|
2190
|
-
let pkFields = this.changedFieldsByPk.get(pk);
|
|
2191
|
-
if (!pkFields) {
|
|
2192
|
-
pkFields = /* @__PURE__ */ new Set();
|
|
2193
|
-
this.changedFieldsByPk.set(pk, pkFields);
|
|
2194
|
-
}
|
|
2195
|
-
for (const key of keys) {
|
|
2196
|
-
pkFields.add(key);
|
|
2197
|
-
let fieldPks = this.changedPksByField.get(key);
|
|
2198
|
-
if (!fieldPks) {
|
|
2199
|
-
fieldPks = /* @__PURE__ */ new Set();
|
|
2200
|
-
this.changedPksByField.set(key, fieldPks);
|
|
2201
|
-
}
|
|
2202
|
-
fieldPks.add(pk);
|
|
2203
|
-
}
|
|
2204
|
-
this.changedPksEventEmitter.markUpdatedKeys([pk]);
|
|
2205
|
-
this.changedFieldsEventEmitter.markUpdatedKeys(keys);
|
|
2206
|
-
}
|
|
2207
|
-
trackPatch(pk, patch) {
|
|
2208
|
-
if (pk === void 0 || pk === null || pk === "") {
|
|
2209
|
-
throw new Error(
|
|
2210
|
-
`[OIMCollectionChangedFieldsWrapper]: PK is required to track changes.`
|
|
2211
|
-
);
|
|
2212
|
-
}
|
|
2213
|
-
const keys = Object.keys(patch);
|
|
2214
|
-
if (keys.length === 0) return;
|
|
2215
|
-
this.trackChangedKeys(pk, keys);
|
|
2216
|
-
}
|
|
2217
|
-
};
|
|
2218
|
-
|
|
2219
|
-
// src/modules/wrapper/index/OIMIndexManualOrderedArrayBased.ts
|
|
2220
|
-
var OIMIndexManualOrderedArrayBased = class extends OIMIndexArrayBased {
|
|
2221
|
-
clear(key) {
|
|
2222
|
-
if (key === void 0) {
|
|
2223
|
-
const keys = this.getKeys();
|
|
2224
|
-
if (keys.length > 0) {
|
|
2225
|
-
this.store.clear();
|
|
2226
|
-
this.emitUpdate(Array.from(keys));
|
|
2227
|
-
}
|
|
2228
|
-
return;
|
|
2229
|
-
}
|
|
2230
|
-
if (this.store.getOneByKey(key) !== void 0) {
|
|
2231
|
-
this.store.removeOneByKey(key);
|
|
2232
|
-
this.emitUpdate([key]);
|
|
2233
|
-
}
|
|
2234
|
-
}
|
|
2235
|
-
push(key, itemKey) {
|
|
2236
|
-
const list = this.getOrCreateList(key);
|
|
2237
|
-
const index = list.length;
|
|
2238
|
-
list.push(this.getOrCreateSlot(itemKey));
|
|
2239
|
-
this.emitUpdate([key]);
|
|
2240
|
-
return index;
|
|
2241
|
-
}
|
|
2242
|
-
insertAt(key, index, itemKey) {
|
|
2243
|
-
const list = this.getOrCreateList(key);
|
|
2244
|
-
const safeIndex = Math.max(0, Math.min(index, list.length));
|
|
2245
|
-
list.splice(safeIndex, 0, this.getOrCreateSlot(itemKey));
|
|
2246
|
-
this.emitUpdate([key]);
|
|
2247
|
-
}
|
|
2248
|
-
removeAt(key, index) {
|
|
2249
|
-
const list = this.store.getOneByKey(key);
|
|
2250
|
-
if (!list) return void 0;
|
|
2251
|
-
if (index < 0 || index >= list.length) return void 0;
|
|
2252
|
-
const [removed] = list.splice(index, 1);
|
|
2253
|
-
if (list.length === 0) {
|
|
2254
|
-
this.store.removeOneByKey(key);
|
|
2255
|
-
}
|
|
2256
|
-
this.emitUpdate([key]);
|
|
2257
|
-
return removed?.pk;
|
|
2258
|
-
}
|
|
2259
|
-
move(key, fromIndex, toIndex) {
|
|
2260
|
-
const list = this.store.getOneByKey(key);
|
|
2261
|
-
if (!list) return void 0;
|
|
2262
|
-
if (fromIndex < 0 || fromIndex >= list.length) return void 0;
|
|
2263
|
-
if (toIndex < 0 || toIndex >= list.length) return void 0;
|
|
2264
|
-
if (fromIndex === toIndex) return list[fromIndex]?.pk;
|
|
2265
|
-
const [itemKey] = list.splice(fromIndex, 1);
|
|
2266
|
-
if (itemKey === void 0) return void 0;
|
|
2267
|
-
list.splice(toIndex, 0, itemKey);
|
|
2268
|
-
this.emitUpdate([key]);
|
|
2269
|
-
return itemKey.pk;
|
|
2270
|
-
}
|
|
2271
|
-
reset(key, itemKeys) {
|
|
2272
|
-
if (itemKeys.length === 0) {
|
|
2273
|
-
if (this.store.getOneByKey(key) !== void 0) {
|
|
2274
|
-
this.store.removeOneByKey(key);
|
|
2275
|
-
this.emitUpdate([key]);
|
|
2276
|
-
}
|
|
2277
|
-
return;
|
|
2278
|
-
}
|
|
2279
|
-
this.store.setOneByKey(key, this.resolveSlots(itemKeys));
|
|
2280
|
-
this.emitUpdate([key]);
|
|
2281
|
-
}
|
|
2282
|
-
getOrCreateList(key) {
|
|
2283
|
-
let list = this.store.getOneByKey(key);
|
|
2284
|
-
if (!list) {
|
|
2285
|
-
list = [];
|
|
2286
|
-
this.store.setOneByKey(key, list);
|
|
2287
|
-
}
|
|
2288
|
-
return list;
|
|
2289
|
-
}
|
|
2290
|
-
};
|
|
2291
|
-
|
|
2292
|
-
// src/modules/wrapper/index/OIMOrderedListIndexCommandStreamWrapper.ts
|
|
2293
|
-
var OIMOrderedListIndexCommandStreamWrapper = class {
|
|
2294
|
-
constructor(queue, index) {
|
|
2295
|
-
this.isInWrite = false;
|
|
2296
|
-
this.commandsByKey = /* @__PURE__ */ new Map();
|
|
2297
|
-
this.onAfterFlush = () => {
|
|
2298
|
-
this.commandsByKey.clear();
|
|
2299
|
-
};
|
|
2300
|
-
this.onIndexUpdate = (payload) => {
|
|
2301
|
-
if (this.isInWrite) return;
|
|
2302
|
-
if (payload.keys.length === 0) return;
|
|
2303
|
-
for (let i = 0; i < payload.keys.length; i++) {
|
|
2304
|
-
const key = payload.keys[i];
|
|
2305
|
-
const list = this.index.getPksByKey(key);
|
|
2306
|
-
this.appendCommand(key, { type: "set", keys: Array.from(list) });
|
|
2307
|
-
}
|
|
2308
|
-
};
|
|
2309
|
-
this.commandsEventEmitter = new OIMUpdateEventEmitter(
|
|
2310
|
-
queue,
|
|
2311
|
-
"after_flush"
|
|
2312
|
-
);
|
|
2313
|
-
this.index = index ?? new OIMIndexManualOrderedArrayBased();
|
|
2314
|
-
this.unsubscribeAfterFlush = queue.emitter.on(
|
|
2315
|
-
0 /* AFTER_FLUSH */,
|
|
2316
|
-
this.onAfterFlush
|
|
2317
|
-
);
|
|
2318
|
-
this.unsubscribeFromIndexEmitter = this.index.emitter.on(
|
|
2319
|
-
0 /* UPDATE */,
|
|
2320
|
-
this.onIndexUpdate
|
|
2321
|
-
);
|
|
2322
|
-
}
|
|
2323
|
-
getPksByKey(key) {
|
|
2324
|
-
return this.index.getPksByKey(key);
|
|
2325
|
-
}
|
|
2326
|
-
hasKey(key) {
|
|
2327
|
-
return this.index.hasKey(key);
|
|
2328
|
-
}
|
|
2329
|
-
getKeys() {
|
|
2330
|
-
return this.index.getKeys();
|
|
2331
|
-
}
|
|
2332
|
-
push(key, itemKey) {
|
|
2333
|
-
this.withWrite(() => {
|
|
2334
|
-
const index = this.index.push(key, itemKey);
|
|
2335
|
-
this.appendCommand(key, { type: "add", key: itemKey, index });
|
|
2336
|
-
});
|
|
2337
|
-
}
|
|
2338
|
-
removeAt(key, index) {
|
|
2339
|
-
this.withWrite(() => {
|
|
2340
|
-
const itemKey = this.index.removeAt(key, index);
|
|
2341
|
-
if (itemKey === void 0) return;
|
|
2342
|
-
this.appendCommand(key, { type: "remove", key: itemKey, index });
|
|
2343
|
-
});
|
|
2344
|
-
}
|
|
2345
|
-
move(key, fromIndex, toIndex) {
|
|
2346
|
-
this.withWrite(() => {
|
|
2347
|
-
const itemKey = this.index.move(key, fromIndex, toIndex);
|
|
2348
|
-
if (itemKey === void 0) return;
|
|
2349
|
-
this.appendCommand(key, {
|
|
2350
|
-
type: "move",
|
|
2351
|
-
key: itemKey,
|
|
2352
|
-
fromIndex,
|
|
2353
|
-
toIndex
|
|
2354
|
-
});
|
|
2355
|
-
});
|
|
2356
|
-
}
|
|
2357
|
-
set(key, keys) {
|
|
2358
|
-
this.withWrite(() => {
|
|
2359
|
-
this.index.reset(key, keys);
|
|
2360
|
-
this.appendCommand(key, { type: "set", keys });
|
|
2361
|
-
});
|
|
2362
|
-
}
|
|
2363
|
-
/**
|
|
2364
|
-
* Read-only peek at buffered commands without clearing them.
|
|
2365
|
-
*/
|
|
2366
|
-
getBufferedCommands(key) {
|
|
2367
|
-
return this.commandsByKey.get(key) ?? [];
|
|
2368
|
-
}
|
|
2369
|
-
/**
|
|
2370
|
-
* Drain buffered commands for a key, preserving order.
|
|
2371
|
-
* Intended usage: call inside a `commandsEventEmitter.subscribeOnKey(key, ...)` handler.
|
|
2372
|
-
*/
|
|
2373
|
-
consumeCommands(key) {
|
|
2374
|
-
const cmds = this.commandsByKey.get(key);
|
|
2375
|
-
if (!cmds || cmds.length === 0) return [];
|
|
2376
|
-
return cmds.slice();
|
|
2377
|
-
}
|
|
2378
|
-
clear(key) {
|
|
2379
|
-
if (key === void 0) {
|
|
2380
|
-
this.index.destroy();
|
|
2381
|
-
this.commandsByKey.clear();
|
|
2382
|
-
return;
|
|
2383
|
-
}
|
|
2384
|
-
this.index.clear(key);
|
|
2385
|
-
this.commandsByKey.delete(key);
|
|
2386
|
-
}
|
|
2387
|
-
destroy() {
|
|
2388
|
-
this.commandsEventEmitter.destroy();
|
|
2389
|
-
this.unsubscribeAfterFlush();
|
|
2390
|
-
this.unsubscribeFromIndexEmitter();
|
|
2391
|
-
this.clear();
|
|
2392
|
-
}
|
|
2393
|
-
withWrite(fn) {
|
|
2394
|
-
if (this.isInWrite) {
|
|
2395
|
-
fn();
|
|
3116
|
+
updateEntitySnapshot(pk) {
|
|
3117
|
+
const entity = this.collection.getOneByPk(pk);
|
|
3118
|
+
if (!entity) {
|
|
3119
|
+
this.lastEntitySnapshotByPk.delete(pk);
|
|
2396
3120
|
return;
|
|
2397
3121
|
}
|
|
2398
|
-
this.
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
} finally {
|
|
2402
|
-
this.isInWrite = false;
|
|
2403
|
-
}
|
|
3122
|
+
this.lastEntitySnapshotByPk.set(pk, {
|
|
3123
|
+
...entity
|
|
3124
|
+
});
|
|
2404
3125
|
}
|
|
2405
|
-
|
|
2406
|
-
let
|
|
2407
|
-
if (!
|
|
2408
|
-
|
|
2409
|
-
this.
|
|
3126
|
+
trackChangedKeys(pk, keys) {
|
|
3127
|
+
let pkFields = this.changedFieldsByPk.get(pk);
|
|
3128
|
+
if (!pkFields) {
|
|
3129
|
+
pkFields = /* @__PURE__ */ new Set();
|
|
3130
|
+
this.changedFieldsByPk.set(pk, pkFields);
|
|
2410
3131
|
}
|
|
2411
|
-
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
|
|
2418
|
-
|
|
3132
|
+
for (const key of keys) {
|
|
3133
|
+
pkFields.add(key);
|
|
3134
|
+
let fieldPks = this.changedPksByField.get(key);
|
|
3135
|
+
if (!fieldPks) {
|
|
3136
|
+
fieldPks = /* @__PURE__ */ new Set();
|
|
3137
|
+
this.changedPksByField.set(key, fieldPks);
|
|
3138
|
+
}
|
|
3139
|
+
fieldPks.add(pk);
|
|
2419
3140
|
}
|
|
2420
|
-
this.
|
|
3141
|
+
this.changedPksEventEmitter.markUpdatedKeys([pk]);
|
|
3142
|
+
this.changedFieldsEventEmitter.markUpdatedKeys(keys);
|
|
3143
|
+
}
|
|
3144
|
+
trackPatch(pk, patch) {
|
|
3145
|
+
if (pk === void 0 || pk === null || pk === "") {
|
|
3146
|
+
throw new Error(
|
|
3147
|
+
`[OIMCollectionChangedFields]: PK is required to track changes.`
|
|
3148
|
+
);
|
|
3149
|
+
}
|
|
3150
|
+
const keys = Object.keys(patch);
|
|
3151
|
+
if (keys.length === 0) return;
|
|
3152
|
+
this.trackChangedKeys(pk, keys);
|
|
2421
3153
|
}
|
|
2422
3154
|
};
|
|
2423
3155
|
|
|
@@ -2533,7 +3265,9 @@ var OIMEventQueueSchedulerImmediate = class extends OIMEventQueueScheduler {
|
|
|
2533
3265
|
cancel() {
|
|
2534
3266
|
if (this.immediateId === void 0) return;
|
|
2535
3267
|
if (this.useSetImmediate) {
|
|
2536
|
-
clearImmediate(
|
|
3268
|
+
clearImmediate(
|
|
3269
|
+
this.immediateId
|
|
3270
|
+
);
|
|
2537
3271
|
} else if (this.useMessageChannel) {
|
|
2538
3272
|
this.pendingCallback = void 0;
|
|
2539
3273
|
} else {
|
|
@@ -2590,7 +3324,7 @@ var OIMEventQueueSchedulerFactory = class {
|
|
|
2590
3324
|
}
|
|
2591
3325
|
};
|
|
2592
3326
|
|
|
2593
|
-
// src/
|
|
3327
|
+
// src/constants/OIMDBSettings.ts
|
|
2594
3328
|
var OIMDBSettings = class {
|
|
2595
3329
|
};
|
|
2596
3330
|
/**
|
|
@@ -2602,11 +3336,11 @@ OIMDBSettings.FLUSHING_KEYS_INDEX_KEY = "__flushingKeys__";
|
|
|
2602
3336
|
|
|
2603
3337
|
// src/modules/effect/core/OIMEffectDependencyComputed.ts
|
|
2604
3338
|
var OIMEffectDependencyComputed = class {
|
|
2605
|
-
constructor(
|
|
2606
|
-
this.
|
|
3339
|
+
constructor(source) {
|
|
3340
|
+
this.source = source;
|
|
2607
3341
|
}
|
|
2608
3342
|
subscribe(onUpdate) {
|
|
2609
|
-
return this.
|
|
3343
|
+
return this.source.emitter.on("update", onUpdate);
|
|
2610
3344
|
}
|
|
2611
3345
|
};
|
|
2612
3346
|
|
|
@@ -2718,7 +3452,7 @@ var OIMEffect = class {
|
|
|
2718
3452
|
}
|
|
2719
3453
|
};
|
|
2720
3454
|
|
|
2721
|
-
// src/modules/computed/
|
|
3455
|
+
// src/modules/computed/enums/EOIMComputedEventType.ts
|
|
2722
3456
|
var EOIMComputedEventType = /* @__PURE__ */ ((EOIMComputedEventType2) => {
|
|
2723
3457
|
EOIMComputedEventType2["UPDATE"] = "update";
|
|
2724
3458
|
return EOIMComputedEventType2;
|
|
@@ -2733,13 +3467,13 @@ var OIMComputed = class {
|
|
|
2733
3467
|
this.runtime = runtime;
|
|
2734
3468
|
this.compute = opts.compute;
|
|
2735
3469
|
this.compare = opts.compare ?? Object.is;
|
|
2736
|
-
this.
|
|
3470
|
+
this._deps = opts.deps ?? [];
|
|
2737
3471
|
this.updateEventEmitter = new OIMUpdateEventEmitter(
|
|
2738
3472
|
this.runtime.queue,
|
|
2739
3473
|
"immediate"
|
|
2740
3474
|
);
|
|
2741
3475
|
this.effect = new OIMEffect(this.runtime, {
|
|
2742
|
-
deps: this.
|
|
3476
|
+
deps: this._deps,
|
|
2743
3477
|
onUpdate: () => {
|
|
2744
3478
|
this.isDirty = true;
|
|
2745
3479
|
},
|
|
@@ -2748,6 +3482,15 @@ var OIMComputed = class {
|
|
|
2748
3482
|
}
|
|
2749
3483
|
});
|
|
2750
3484
|
}
|
|
3485
|
+
get needsRecompute() {
|
|
3486
|
+
return this.isDirty;
|
|
3487
|
+
}
|
|
3488
|
+
get isReady() {
|
|
3489
|
+
return this.hasValue;
|
|
3490
|
+
}
|
|
3491
|
+
get deps() {
|
|
3492
|
+
return this._deps;
|
|
3493
|
+
}
|
|
2751
3494
|
get() {
|
|
2752
3495
|
this.recomputeAndEmitIfChanged();
|
|
2753
3496
|
return this.value;
|
|
@@ -2782,8 +3525,8 @@ function isReadonlyArray(value) {
|
|
|
2782
3525
|
return Array.isArray(value);
|
|
2783
3526
|
}
|
|
2784
3527
|
var OIMEffectDependencyKeyed = class {
|
|
2785
|
-
constructor(
|
|
2786
|
-
this.
|
|
3528
|
+
constructor(source, keyOrKeys) {
|
|
3529
|
+
this.source = source;
|
|
2787
3530
|
if (isReadonlyArray(keyOrKeys)) {
|
|
2788
3531
|
this.keys = keyOrKeys;
|
|
2789
3532
|
} else {
|
|
@@ -2792,11 +3535,11 @@ var OIMEffectDependencyKeyed = class {
|
|
|
2792
3535
|
}
|
|
2793
3536
|
subscribe(onUpdate) {
|
|
2794
3537
|
if (this.keys !== void 0) {
|
|
2795
|
-
return this.
|
|
3538
|
+
return this.source.subscribeOnKeys(this.keys, onUpdate);
|
|
2796
3539
|
}
|
|
2797
3540
|
if (this.key === void 0) return () => {
|
|
2798
3541
|
};
|
|
2799
|
-
return this.
|
|
3542
|
+
return this.source.subscribeOnKey(this.key, onUpdate);
|
|
2800
3543
|
}
|
|
2801
3544
|
};
|
|
2802
3545
|
|
|
@@ -2808,6 +3551,9 @@ var OIMEffectDependencyKeyedObject = class {
|
|
|
2808
3551
|
keyOrKeys
|
|
2809
3552
|
);
|
|
2810
3553
|
}
|
|
3554
|
+
get source() {
|
|
3555
|
+
return this.dep.source;
|
|
3556
|
+
}
|
|
2811
3557
|
subscribe(onUpdate) {
|
|
2812
3558
|
return this.dep.subscribe(onUpdate);
|
|
2813
3559
|
}
|
|
@@ -2821,217 +3567,27 @@ var OIMEffectDependencyKeyedCollection = class {
|
|
|
2821
3567
|
pkOrPks
|
|
2822
3568
|
);
|
|
2823
3569
|
}
|
|
2824
|
-
|
|
2825
|
-
return this.dep.
|
|
2826
|
-
}
|
|
2827
|
-
};
|
|
2828
|
-
|
|
2829
|
-
// src/modules/effect/core/OIMEffectDependencyKeyedIndex.ts
|
|
2830
|
-
var OIMEffectDependencyKeyedIndex = class {
|
|
2831
|
-
constructor(index, keyOrKeys) {
|
|
2832
|
-
this.dep = new OIMEffectDependencyKeyed(
|
|
2833
|
-
index,
|
|
2834
|
-
keyOrKeys
|
|
2835
|
-
);
|
|
3570
|
+
get source() {
|
|
3571
|
+
return this.dep.source;
|
|
2836
3572
|
}
|
|
2837
3573
|
subscribe(onUpdate) {
|
|
2838
3574
|
return this.dep.subscribe(onUpdate);
|
|
2839
3575
|
}
|
|
2840
|
-
};
|
|
2841
|
-
|
|
2842
|
-
// src/modules/
|
|
2843
|
-
var
|
|
2844
|
-
constructor(
|
|
2845
|
-
this.
|
|
2846
|
-
|
|
2847
|
-
|
|
2848
|
-
|
|
2849
|
-
this.sourceUnsubscribers = [];
|
|
2850
|
-
this.computedUnsubscribers = [];
|
|
2851
|
-
this.isResubscribeEnqueued = false;
|
|
2852
|
-
this.isTemporarilyUnsubscribedForFlush = false;
|
|
2853
|
-
this.isDeliveryEnqueued = false;
|
|
2854
|
-
this.hasLastValue = false;
|
|
2855
|
-
this.onSourceInvalidate = () => {
|
|
2856
|
-
if (this.listeners.size === 0) return;
|
|
2857
|
-
if (!this.isTemporarilyUnsubscribedForFlush) {
|
|
2858
|
-
this.isTemporarilyUnsubscribedForFlush = true;
|
|
2859
|
-
this.unsubscribeFromSourceDeps();
|
|
2860
|
-
this.ensureResubscribeAfterFlush();
|
|
2861
|
-
}
|
|
2862
|
-
if (this.isDeliveryEnqueued) return;
|
|
2863
|
-
this.isDeliveryEnqueued = true;
|
|
2864
|
-
this.dequeueDelivery = this.runtime.schedule(this.deliver);
|
|
2865
|
-
};
|
|
2866
|
-
this.onComputedInvalidate = () => {
|
|
2867
|
-
if (this.listeners.size === 0) return;
|
|
2868
|
-
if (this.isDeliveryEnqueued) return;
|
|
2869
|
-
this.isDeliveryEnqueued = true;
|
|
2870
|
-
this.dequeueDelivery = this.runtime.schedule(this.deliver);
|
|
2871
|
-
};
|
|
2872
|
-
this.deliver = () => {
|
|
2873
|
-
this.isDeliveryEnqueued = false;
|
|
2874
|
-
this.dequeueDelivery = void 0;
|
|
2875
|
-
if (this.listeners.size === 0) return;
|
|
2876
|
-
const next = this.getValue();
|
|
2877
|
-
if (this.hasLastValue && this.areEqual(this.lastValue, next)) return;
|
|
2878
|
-
this.setLastValue(next);
|
|
2879
|
-
const snapshot = Array.from(this.listeners);
|
|
2880
|
-
for (let i = 0; i < snapshot.length; i++) {
|
|
2881
|
-
const listener = snapshot[i];
|
|
2882
|
-
if (this.listeners.has(listener)) listener(next);
|
|
2883
|
-
}
|
|
2884
|
-
};
|
|
2885
|
-
this.onAfterFlush = () => {
|
|
2886
|
-
if (!this.isResubscribeEnqueued) return;
|
|
2887
|
-
this.isResubscribeEnqueued = false;
|
|
2888
|
-
this.dequeueResubscribe = void 0;
|
|
2889
|
-
if (this.listeners.size === 0) return;
|
|
2890
|
-
this.isTemporarilyUnsubscribedForFlush = false;
|
|
2891
|
-
if (this.sourceUnsubscribers.length === 0) {
|
|
2892
|
-
for (const dep of this.sourceDeps) {
|
|
2893
|
-
this.sourceUnsubscribers.push(
|
|
2894
|
-
dep.subscribe(this.onSourceInvalidate)
|
|
2895
|
-
);
|
|
2896
|
-
}
|
|
2897
|
-
}
|
|
2898
|
-
};
|
|
2899
|
-
}
|
|
2900
|
-
get queue() {
|
|
2901
|
-
return this.runtime.queue;
|
|
2902
|
-
}
|
|
2903
|
-
/**
|
|
2904
|
-
* Start watching this selector. The callback is called immediately with the current value,
|
|
2905
|
-
* then coalesced and delivered on `queue.flush()` when the selector invalidates.
|
|
2906
|
-
*/
|
|
2907
|
-
watch(onValue) {
|
|
2908
|
-
this.listeners.add(onValue);
|
|
2909
|
-
if (this.listeners.size === 1) {
|
|
2910
|
-
this.subscribeToDeps();
|
|
2911
|
-
}
|
|
2912
|
-
const current = this.getValue();
|
|
2913
|
-
this.setLastValue(current);
|
|
2914
|
-
onValue(current);
|
|
2915
|
-
return () => {
|
|
2916
|
-
this.listeners.delete(onValue);
|
|
2917
|
-
if (this.listeners.size > 0) return;
|
|
2918
|
-
this.unsubscribeFromAllDeps();
|
|
2919
|
-
if (this.dequeueResubscribe) {
|
|
2920
|
-
this.dequeueResubscribe();
|
|
2921
|
-
this.dequeueResubscribe = void 0;
|
|
2922
|
-
}
|
|
2923
|
-
this.isResubscribeEnqueued = false;
|
|
2924
|
-
this.isTemporarilyUnsubscribedForFlush = false;
|
|
2925
|
-
if (this.dequeueDelivery) {
|
|
2926
|
-
this.dequeueDelivery();
|
|
2927
|
-
this.dequeueDelivery = void 0;
|
|
2928
|
-
}
|
|
2929
|
-
this.isDeliveryEnqueued = false;
|
|
2930
|
-
this.hasLastValue = false;
|
|
2931
|
-
};
|
|
2932
|
-
}
|
|
2933
|
-
areEqual(prev, next) {
|
|
2934
|
-
return Object.is(prev, next);
|
|
2935
|
-
}
|
|
2936
|
-
setLastValue(value) {
|
|
2937
|
-
this.lastValue = value;
|
|
2938
|
-
this.hasLastValue = true;
|
|
2939
|
-
}
|
|
2940
|
-
subscribeToDeps() {
|
|
2941
|
-
if (this.sourceUnsubscribers.length > 0 || this.computedUnsubscribers.length > 0)
|
|
2942
|
-
return;
|
|
2943
|
-
for (const dep of this.sourceDeps) {
|
|
2944
|
-
this.sourceUnsubscribers.push(
|
|
2945
|
-
dep.subscribe(this.onSourceInvalidate)
|
|
2946
|
-
);
|
|
2947
|
-
}
|
|
2948
|
-
for (const dep of this.computedDeps) {
|
|
2949
|
-
this.computedUnsubscribers.push(
|
|
2950
|
-
dep.subscribe(this.onComputedInvalidate)
|
|
2951
|
-
);
|
|
2952
|
-
}
|
|
2953
|
-
}
|
|
2954
|
-
unsubscribeFromSourceDeps() {
|
|
2955
|
-
if (this.sourceUnsubscribers.length === 0) return;
|
|
2956
|
-
for (const unsub of this.sourceUnsubscribers) unsub();
|
|
2957
|
-
this.sourceUnsubscribers = [];
|
|
2958
|
-
}
|
|
2959
|
-
unsubscribeFromAllDeps() {
|
|
2960
|
-
this.unsubscribeFromSourceDeps();
|
|
2961
|
-
if (this.computedUnsubscribers.length === 0) return;
|
|
2962
|
-
for (const unsub of this.computedUnsubscribers) unsub();
|
|
2963
|
-
this.computedUnsubscribers = [];
|
|
2964
|
-
}
|
|
2965
|
-
ensureResubscribeAfterFlush() {
|
|
2966
|
-
if (this.isResubscribeEnqueued) return;
|
|
2967
|
-
this.isResubscribeEnqueued = true;
|
|
2968
|
-
this.dequeueResubscribe = this.runtime.scheduleAfterFlush(
|
|
2969
|
-
this.onAfterFlush
|
|
2970
|
-
);
|
|
2971
|
-
}
|
|
2972
|
-
};
|
|
2973
|
-
|
|
2974
|
-
// src/modules/selector/core/OIMSelectorSourceDependencyUpdateEventEmitterKey.ts
|
|
2975
|
-
var OIMSelectorSourceDependencyUpdateEventEmitterKey = class {
|
|
2976
|
-
constructor(subscription, key) {
|
|
2977
|
-
this.subscription = subscription;
|
|
2978
|
-
this.key = key;
|
|
2979
|
-
}
|
|
2980
|
-
subscribe(onUpdate) {
|
|
2981
|
-
return this.subscription.subscribeOnKey(this.key, onUpdate);
|
|
2982
|
-
}
|
|
2983
|
-
};
|
|
2984
|
-
|
|
2985
|
-
// src/modules/selector/core/OIMCollectionByPkSelector.ts
|
|
2986
|
-
var OIMCollectionByPkSelector = class extends OIMSelector {
|
|
2987
|
-
constructor(runtime, collection, pk) {
|
|
2988
|
-
super(runtime, [
|
|
2989
|
-
new OIMSelectorSourceDependencyUpdateEventEmitterKey(
|
|
2990
|
-
collection,
|
|
2991
|
-
pk
|
|
2992
|
-
)
|
|
2993
|
-
]);
|
|
2994
|
-
this.collection = collection;
|
|
2995
|
-
this.pk = pk;
|
|
2996
|
-
}
|
|
2997
|
-
getValue() {
|
|
2998
|
-
return this.collection.getOneByPk(this.pk);
|
|
2999
|
-
}
|
|
3000
|
-
};
|
|
3001
|
-
|
|
3002
|
-
// src/modules/selector/core/OIMSelectorSourceDependencyUpdateEventEmitterKeys.ts
|
|
3003
|
-
var OIMSelectorSourceDependencyUpdateEventEmitterKeys = class {
|
|
3004
|
-
constructor(subscription, keys) {
|
|
3005
|
-
this.subscription = subscription;
|
|
3006
|
-
this.keys = keys;
|
|
3007
|
-
}
|
|
3008
|
-
subscribe(onUpdate) {
|
|
3009
|
-
return this.subscription.subscribeOnKeys(this.keys, onUpdate);
|
|
3010
|
-
}
|
|
3011
|
-
};
|
|
3012
|
-
|
|
3013
|
-
// src/modules/selector/core/OIMCollectionByPksSelector.ts
|
|
3014
|
-
var OIMCollectionByPksSelector = class extends OIMSelector {
|
|
3015
|
-
constructor(runtime, collection, pks) {
|
|
3016
|
-
super(runtime, [
|
|
3017
|
-
new OIMSelectorSourceDependencyUpdateEventEmitterKeys(
|
|
3018
|
-
collection,
|
|
3019
|
-
pks
|
|
3020
|
-
)
|
|
3021
|
-
]);
|
|
3022
|
-
this.collection = collection;
|
|
3023
|
-
this.pks = pks;
|
|
3576
|
+
};
|
|
3577
|
+
|
|
3578
|
+
// src/modules/effect/core/OIMEffectDependencyKeyedIndex.ts
|
|
3579
|
+
var OIMEffectDependencyKeyedIndex = class {
|
|
3580
|
+
constructor(index, keyOrKeys) {
|
|
3581
|
+
this.dep = new OIMEffectDependencyKeyed(
|
|
3582
|
+
index,
|
|
3583
|
+
keyOrKeys
|
|
3584
|
+
);
|
|
3024
3585
|
}
|
|
3025
|
-
|
|
3026
|
-
return this.
|
|
3586
|
+
get source() {
|
|
3587
|
+
return this.dep.source;
|
|
3027
3588
|
}
|
|
3028
|
-
|
|
3029
|
-
|
|
3030
|
-
if (prev.length !== next.length) return false;
|
|
3031
|
-
for (let i = 0; i < prev.length; i++) {
|
|
3032
|
-
if (prev[i] !== next[i]) return false;
|
|
3033
|
-
}
|
|
3034
|
-
return true;
|
|
3589
|
+
subscribe(onUpdate) {
|
|
3590
|
+
return this.dep.subscribe(onUpdate);
|
|
3035
3591
|
}
|
|
3036
3592
|
};
|
|
3037
3593
|
|
|
@@ -3165,259 +3721,6 @@ var OIMIndexPksByKeysArrayBasedSelector = class extends OIMSelector {
|
|
|
3165
3721
|
return true;
|
|
3166
3722
|
}
|
|
3167
3723
|
};
|
|
3168
|
-
|
|
3169
|
-
// src/modules/selector/core/OIMSelectorSourceDependencyEntitiesByIndexKeySetBased.ts
|
|
3170
|
-
var OIMSelectorSourceDependencyEntitiesByIndexKeySetBased = class {
|
|
3171
|
-
constructor(collection, reactiveIndex, key) {
|
|
3172
|
-
this.collection = collection;
|
|
3173
|
-
this.reactiveIndex = reactiveIndex;
|
|
3174
|
-
this.key = key;
|
|
3175
|
-
this.currentPks = [];
|
|
3176
|
-
}
|
|
3177
|
-
subscribe(onUpdate) {
|
|
3178
|
-
const resubscribeCollection = () => {
|
|
3179
|
-
const nextPks = Array.from(
|
|
3180
|
-
this.reactiveIndex.getSlotsByKey(this.key),
|
|
3181
|
-
(slot) => slot.pk
|
|
3182
|
-
);
|
|
3183
|
-
if (this.sameArray(this.currentPks, nextPks)) return;
|
|
3184
|
-
this.unsubscribeFromCollectionKeys?.();
|
|
3185
|
-
this.unsubscribeFromCollectionKeys = void 0;
|
|
3186
|
-
this.currentPks = nextPks;
|
|
3187
|
-
if (this.currentPks.length === 0) return;
|
|
3188
|
-
this.unsubscribeFromCollectionKeys = this.collection.subscribeOnKeys(this.currentPks, onUpdate);
|
|
3189
|
-
};
|
|
3190
|
-
const onIndexUpdate = () => {
|
|
3191
|
-
resubscribeCollection();
|
|
3192
|
-
onUpdate();
|
|
3193
|
-
};
|
|
3194
|
-
resubscribeCollection();
|
|
3195
|
-
const unsubscribeFromIndex = this.reactiveIndex.subscribeOnKey(
|
|
3196
|
-
this.key,
|
|
3197
|
-
onIndexUpdate
|
|
3198
|
-
);
|
|
3199
|
-
return () => {
|
|
3200
|
-
unsubscribeFromIndex();
|
|
3201
|
-
this.unsubscribeFromCollectionKeys?.();
|
|
3202
|
-
this.unsubscribeFromCollectionKeys = void 0;
|
|
3203
|
-
this.currentPks = [];
|
|
3204
|
-
};
|
|
3205
|
-
}
|
|
3206
|
-
sameArray(a, b) {
|
|
3207
|
-
if (a === b) return true;
|
|
3208
|
-
if (a.length !== b.length) return false;
|
|
3209
|
-
for (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return false;
|
|
3210
|
-
return true;
|
|
3211
|
-
}
|
|
3212
|
-
};
|
|
3213
|
-
|
|
3214
|
-
// src/modules/selector/core/OIMEntitiesByIndexKeySetBasedSelector.ts
|
|
3215
|
-
var OIMEntitiesByIndexKeySetBasedSelector = class extends OIMSelector {
|
|
3216
|
-
constructor(runtime, collection, reactiveIndex, key) {
|
|
3217
|
-
super(runtime, [
|
|
3218
|
-
new OIMSelectorSourceDependencyEntitiesByIndexKeySetBased(collection, reactiveIndex, key)
|
|
3219
|
-
]);
|
|
3220
|
-
this.collection = collection;
|
|
3221
|
-
this.reactiveIndex = reactiveIndex;
|
|
3222
|
-
this.key = key;
|
|
3223
|
-
this.reactiveIndex.index.setSlotResolver(
|
|
3224
|
-
(pk) => this.collection.getSlotByPk(pk)
|
|
3225
|
-
);
|
|
3226
|
-
}
|
|
3227
|
-
getValue() {
|
|
3228
|
-
const slots = this.reactiveIndex.getSlotsByKey(this.key);
|
|
3229
|
-
const entities = [];
|
|
3230
|
-
entities.length = slots.size;
|
|
3231
|
-
let writeIndex = 0;
|
|
3232
|
-
for (const slot of slots) {
|
|
3233
|
-
entities[writeIndex++] = slot.item;
|
|
3234
|
-
}
|
|
3235
|
-
return entities;
|
|
3236
|
-
}
|
|
3237
|
-
areEqual(prev, next) {
|
|
3238
|
-
if (prev === next) return true;
|
|
3239
|
-
if (prev.length !== next.length) return false;
|
|
3240
|
-
for (let i = 0; i < prev.length; i++)
|
|
3241
|
-
if (prev[i] !== next[i]) return false;
|
|
3242
|
-
return true;
|
|
3243
|
-
}
|
|
3244
|
-
};
|
|
3245
|
-
|
|
3246
|
-
// src/modules/selector/core/OIMSelectorSourceDependencyEntitiesByIndexKeyArrayBased.ts
|
|
3247
|
-
var OIMSelectorSourceDependencyEntitiesByIndexKeyArrayBased = class {
|
|
3248
|
-
constructor(collection, reactiveIndex, key) {
|
|
3249
|
-
this.collection = collection;
|
|
3250
|
-
this.reactiveIndex = reactiveIndex;
|
|
3251
|
-
this.key = key;
|
|
3252
|
-
this.currentPks = [];
|
|
3253
|
-
}
|
|
3254
|
-
subscribe(onUpdate) {
|
|
3255
|
-
const resubscribeCollection = () => {
|
|
3256
|
-
const nextPks = this.reactiveIndex.getSlotsByKey(this.key).map((slot) => slot.pk);
|
|
3257
|
-
if (this.sameArray(this.currentPks, nextPks)) return;
|
|
3258
|
-
this.unsubscribeFromCollectionKeys?.();
|
|
3259
|
-
this.unsubscribeFromCollectionKeys = void 0;
|
|
3260
|
-
this.currentPks = nextPks;
|
|
3261
|
-
if (this.currentPks.length === 0) return;
|
|
3262
|
-
this.unsubscribeFromCollectionKeys = this.collection.subscribeOnKeys(this.currentPks, onUpdate);
|
|
3263
|
-
};
|
|
3264
|
-
const onIndexUpdate = () => {
|
|
3265
|
-
resubscribeCollection();
|
|
3266
|
-
onUpdate();
|
|
3267
|
-
};
|
|
3268
|
-
resubscribeCollection();
|
|
3269
|
-
const unsubscribeFromIndex = this.reactiveIndex.subscribeOnKey(
|
|
3270
|
-
this.key,
|
|
3271
|
-
onIndexUpdate
|
|
3272
|
-
);
|
|
3273
|
-
return () => {
|
|
3274
|
-
unsubscribeFromIndex();
|
|
3275
|
-
this.unsubscribeFromCollectionKeys?.();
|
|
3276
|
-
this.unsubscribeFromCollectionKeys = void 0;
|
|
3277
|
-
this.currentPks = [];
|
|
3278
|
-
};
|
|
3279
|
-
}
|
|
3280
|
-
sameArray(a, b) {
|
|
3281
|
-
if (a === b) return true;
|
|
3282
|
-
if (a.length !== b.length) return false;
|
|
3283
|
-
for (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return false;
|
|
3284
|
-
return true;
|
|
3285
|
-
}
|
|
3286
|
-
};
|
|
3287
|
-
|
|
3288
|
-
// src/modules/selector/core/OIMEntitiesByIndexKeyArrayBasedSelector.ts
|
|
3289
|
-
var OIMEntitiesByIndexKeyArrayBasedSelector = class extends OIMSelector {
|
|
3290
|
-
constructor(runtime, collection, reactiveIndex, key) {
|
|
3291
|
-
super(runtime, [
|
|
3292
|
-
new OIMSelectorSourceDependencyEntitiesByIndexKeyArrayBased(collection, reactiveIndex, key)
|
|
3293
|
-
]);
|
|
3294
|
-
this.collection = collection;
|
|
3295
|
-
this.reactiveIndex = reactiveIndex;
|
|
3296
|
-
this.key = key;
|
|
3297
|
-
this.reactiveIndex.index.setSlotResolver(
|
|
3298
|
-
(pk) => this.collection.getSlotByPk(pk)
|
|
3299
|
-
);
|
|
3300
|
-
}
|
|
3301
|
-
getValue() {
|
|
3302
|
-
const slots = this.reactiveIndex.getSlotsByKey(this.key);
|
|
3303
|
-
const entities = [];
|
|
3304
|
-
entities.length = slots.length;
|
|
3305
|
-
for (let i = 0; i < slots.length; i++) {
|
|
3306
|
-
entities[i] = slots[i].item;
|
|
3307
|
-
}
|
|
3308
|
-
return entities;
|
|
3309
|
-
}
|
|
3310
|
-
areEqual(prev, next) {
|
|
3311
|
-
if (prev === next) return true;
|
|
3312
|
-
if (prev.length !== next.length) return false;
|
|
3313
|
-
for (let i = 0; i < prev.length; i++)
|
|
3314
|
-
if (prev[i] !== next[i]) return false;
|
|
3315
|
-
return true;
|
|
3316
|
-
}
|
|
3317
|
-
};
|
|
3318
|
-
|
|
3319
|
-
// src/modules/computative/core/OIMComputativeRuntime.ts
|
|
3320
|
-
var OIMComputativeRuntime = class {
|
|
3321
|
-
constructor(queue) {
|
|
3322
|
-
this.queue = queue;
|
|
3323
|
-
this.isFlushScheduled = false;
|
|
3324
|
-
this.isFlushing = false;
|
|
3325
|
-
this.minLevel = Infinity;
|
|
3326
|
-
this.maxLevel = -Infinity;
|
|
3327
|
-
this.dirtyByLevel = /* @__PURE__ */ new Map();
|
|
3328
|
-
this.afterFlushTasks = /* @__PURE__ */ new Set();
|
|
3329
|
-
this.queue.emitter.on(0 /* AFTER_FLUSH */, () => {
|
|
3330
|
-
if (!this.isFlushScheduled) return;
|
|
3331
|
-
this.flush();
|
|
3332
|
-
});
|
|
3333
|
-
}
|
|
3334
|
-
/**
|
|
3335
|
-
* Schedule a one-shot task to run on the next `queue.flush()` (AFTER_FLUSH),
|
|
3336
|
-
* ordered by `level` ascending.
|
|
3337
|
-
*/
|
|
3338
|
-
schedule(task, level = 0) {
|
|
3339
|
-
let isActive = true;
|
|
3340
|
-
const wrapped = () => {
|
|
3341
|
-
if (!isActive) return;
|
|
3342
|
-
task();
|
|
3343
|
-
};
|
|
3344
|
-
let bucket = this.dirtyByLevel.get(level);
|
|
3345
|
-
if (!bucket) {
|
|
3346
|
-
bucket = /* @__PURE__ */ new Set();
|
|
3347
|
-
this.dirtyByLevel.set(level, bucket);
|
|
3348
|
-
}
|
|
3349
|
-
bucket.add(wrapped);
|
|
3350
|
-
if (level < this.minLevel) this.minLevel = level;
|
|
3351
|
-
if (level > this.maxLevel) this.maxLevel = level;
|
|
3352
|
-
if (!this.isFlushing) this.isFlushScheduled = true;
|
|
3353
|
-
return () => {
|
|
3354
|
-
if (!isActive) return;
|
|
3355
|
-
isActive = false;
|
|
3356
|
-
bucket.delete(wrapped);
|
|
3357
|
-
};
|
|
3358
|
-
}
|
|
3359
|
-
/**
|
|
3360
|
-
* Run once at the start of the next runtime flush (i.e. after queue.flush()).
|
|
3361
|
-
* Useful for resubscribing dependencies exactly once per source flush.
|
|
3362
|
-
*/
|
|
3363
|
-
scheduleAfterFlush(task) {
|
|
3364
|
-
let isActive = true;
|
|
3365
|
-
const wrapped = () => {
|
|
3366
|
-
if (!isActive) return;
|
|
3367
|
-
task();
|
|
3368
|
-
};
|
|
3369
|
-
this.afterFlushTasks.add(wrapped);
|
|
3370
|
-
if (!this.isFlushing) this.isFlushScheduled = true;
|
|
3371
|
-
return () => {
|
|
3372
|
-
if (!isActive) return;
|
|
3373
|
-
isActive = false;
|
|
3374
|
-
this.afterFlushTasks.delete(wrapped);
|
|
3375
|
-
};
|
|
3376
|
-
}
|
|
3377
|
-
flush() {
|
|
3378
|
-
this.isFlushScheduled = false;
|
|
3379
|
-
if (this.dirtyByLevel.size === 0 && this.afterFlushTasks.size === 0)
|
|
3380
|
-
return;
|
|
3381
|
-
this.isFlushing = true;
|
|
3382
|
-
try {
|
|
3383
|
-
if (this.afterFlushTasks.size > 0) {
|
|
3384
|
-
const snapshot = Array.from(this.afterFlushTasks);
|
|
3385
|
-
this.afterFlushTasks.clear();
|
|
3386
|
-
for (let i = 0; i < snapshot.length; i++) snapshot[i]();
|
|
3387
|
-
}
|
|
3388
|
-
if (this.dirtyByLevel.size === 0) return;
|
|
3389
|
-
let level = this.minLevel;
|
|
3390
|
-
let max = this.maxLevel;
|
|
3391
|
-
while (level <= max) {
|
|
3392
|
-
for (; ; ) {
|
|
3393
|
-
const bucket = this.dirtyByLevel.get(level);
|
|
3394
|
-
if (!bucket || bucket.size === 0) break;
|
|
3395
|
-
this.dirtyByLevel.delete(level);
|
|
3396
|
-
const snapshot = Array.from(bucket);
|
|
3397
|
-
for (let i = 0; i < snapshot.length; i++) snapshot[i]();
|
|
3398
|
-
}
|
|
3399
|
-
if (this.maxLevel > max) max = this.maxLevel;
|
|
3400
|
-
level++;
|
|
3401
|
-
}
|
|
3402
|
-
} finally {
|
|
3403
|
-
this.isFlushing = false;
|
|
3404
|
-
if (this.dirtyByLevel.size === 0) {
|
|
3405
|
-
this.minLevel = Infinity;
|
|
3406
|
-
this.maxLevel = -Infinity;
|
|
3407
|
-
} else {
|
|
3408
|
-
let nextMin = Infinity;
|
|
3409
|
-
let nextMax = -Infinity;
|
|
3410
|
-
this.dirtyByLevel.forEach((_bucket, lvl) => {
|
|
3411
|
-
if (lvl < nextMin) nextMin = lvl;
|
|
3412
|
-
if (lvl > nextMax) nextMax = lvl;
|
|
3413
|
-
});
|
|
3414
|
-
this.minLevel = nextMin;
|
|
3415
|
-
this.maxLevel = nextMax;
|
|
3416
|
-
this.isFlushScheduled = true;
|
|
3417
|
-
}
|
|
3418
|
-
}
|
|
3419
|
-
}
|
|
3420
|
-
};
|
|
3421
3724
|
// Annotate the CommonJS export names for ESM import in node:
|
|
3422
3725
|
0 && (module.exports = {
|
|
3423
3726
|
EOIMCollectionEventType,
|
|
@@ -3429,13 +3732,19 @@ var OIMComputativeRuntime = class {
|
|
|
3429
3732
|
OIMCollection,
|
|
3430
3733
|
OIMCollectionByPkSelector,
|
|
3431
3734
|
OIMCollectionByPksSelector,
|
|
3432
|
-
|
|
3735
|
+
OIMCollectionChangedFields,
|
|
3736
|
+
OIMCollectionIndexFactory,
|
|
3737
|
+
OIMCollectionIndexManualOrderedArrayBased,
|
|
3738
|
+
OIMCollectionOrderedListCommandStream,
|
|
3739
|
+
OIMCollectionSelectors,
|
|
3433
3740
|
OIMCollectionStore,
|
|
3434
3741
|
OIMCollectionStoreMapDriven,
|
|
3435
3742
|
OIMComparatorFactory,
|
|
3436
|
-
|
|
3743
|
+
OIMComputeRuntime,
|
|
3437
3744
|
OIMComputed,
|
|
3438
3745
|
OIMDBSettings,
|
|
3746
|
+
OIMDerivedCollectionIndexArrayBased,
|
|
3747
|
+
OIMDerivedCollectionIndexSetBased,
|
|
3439
3748
|
OIMEffect,
|
|
3440
3749
|
OIMEffectDependencyComputed,
|
|
3441
3750
|
OIMEffectDependencyKeyed,
|
|
@@ -3453,6 +3762,7 @@ var OIMComputativeRuntime = class {
|
|
|
3453
3762
|
OIMEventQueueSchedulerImmediate,
|
|
3454
3763
|
OIMEventQueueSchedulerMicrotask,
|
|
3455
3764
|
OIMEventQueueSchedulerTimeout,
|
|
3765
|
+
OIMIndex,
|
|
3456
3766
|
OIMIndexArrayBased,
|
|
3457
3767
|
OIMIndexComparatorFactory,
|
|
3458
3768
|
OIMIndexManualArrayBased,
|
|
@@ -3474,14 +3784,18 @@ var OIMComputativeRuntime = class {
|
|
|
3474
3784
|
OIMObjectStoreRecordDriven,
|
|
3475
3785
|
OIMObjectValueByKeySelector,
|
|
3476
3786
|
OIMObjectValuesByKeysSelector,
|
|
3477
|
-
|
|
3787
|
+
OIMOrderedListCommandStream,
|
|
3478
3788
|
OIMPkSelectorFactory,
|
|
3479
|
-
OIMRICollection,
|
|
3480
3789
|
OIMReactiveCollection,
|
|
3790
|
+
OIMReactiveCollectionIndexManualArrayBased,
|
|
3791
|
+
OIMReactiveCollectionIndexManualSetBased,
|
|
3792
|
+
OIMReactiveIndex,
|
|
3481
3793
|
OIMReactiveIndexArrayBased,
|
|
3482
3794
|
OIMReactiveIndexManualArrayBased,
|
|
3483
3795
|
OIMReactiveIndexManualSetBased,
|
|
3484
3796
|
OIMReactiveIndexSetBased,
|
|
3485
3797
|
OIMReactiveObject,
|
|
3486
|
-
OIMSelector
|
|
3798
|
+
OIMSelector,
|
|
3799
|
+
createOIMCollectionContext,
|
|
3800
|
+
createOIMCollectionIndexFactory
|
|
3487
3801
|
});
|