@oimdb/core 3.6.0 → 3.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +20 -0
- package/dist/index.cjs +1332 -270
- package/dist/index.d.cts +984 -230
- package/dist/index.d.ts +984 -230
- package/dist/index.js +1314 -270
- package/llms.txt +44 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -26,6 +26,7 @@ __export(index_exports, {
|
|
|
26
26
|
EOIMEventQueueSchedulerEventType: () => EOIMEventQueueSchedulerEventType,
|
|
27
27
|
EOIMIndexEventType: () => EOIMIndexEventType,
|
|
28
28
|
EOIMObjectEventType: () => EOIMObjectEventType,
|
|
29
|
+
OIMBucketCarrierResolver: () => OIMBucketCarrierResolver,
|
|
29
30
|
OIMCarrierKeyedEmitter: () => OIMCarrierKeyedEmitter,
|
|
30
31
|
OIMCarrierSingleEmitter: () => OIMCarrierSingleEmitter,
|
|
31
32
|
OIMCollection: () => OIMCollection,
|
|
@@ -38,6 +39,7 @@ __export(index_exports, {
|
|
|
38
39
|
OIMCollectionSelectors: () => OIMCollectionSelectors,
|
|
39
40
|
OIMCollectionStore: () => OIMCollectionStore,
|
|
40
41
|
OIMCollectionStoreMapDriven: () => OIMCollectionStoreMapDriven,
|
|
42
|
+
OIMCollectionStoreTrieDriven: () => OIMCollectionStoreTrieDriven,
|
|
41
43
|
OIMComparatorFactory: () => OIMComparatorFactory,
|
|
42
44
|
OIMComputeRuntime: () => OIMComputeRuntime,
|
|
43
45
|
OIMComputed: () => OIMComputed,
|
|
@@ -46,6 +48,7 @@ __export(index_exports, {
|
|
|
46
48
|
OIMDerivedCollectionGlobalIndexSetBased: () => OIMDerivedCollectionGlobalIndexSetBased,
|
|
47
49
|
OIMDerivedCollectionIndexArrayBased: () => OIMDerivedCollectionIndexArrayBased,
|
|
48
50
|
OIMDerivedCollectionIndexSetBased: () => OIMDerivedCollectionIndexSetBased,
|
|
51
|
+
OIMDisposeScope: () => OIMDisposeScope,
|
|
49
52
|
OIMEffect: () => OIMEffect,
|
|
50
53
|
OIMEffectDependencyComputed: () => OIMEffectDependencyComputed,
|
|
51
54
|
OIMEffectDependencyKeyed: () => OIMEffectDependencyKeyed,
|
|
@@ -71,6 +74,7 @@ __export(index_exports, {
|
|
|
71
74
|
OIMGlobalIndexManualArrayBased: () => OIMGlobalIndexManualArrayBased,
|
|
72
75
|
OIMGlobalIndexManualSetBased: () => OIMGlobalIndexManualSetBased,
|
|
73
76
|
OIMGlobalIndexSetBased: () => OIMGlobalIndexSetBased,
|
|
77
|
+
OIMGlobalIndexSlotMap: () => OIMGlobalIndexSlotMap,
|
|
74
78
|
OIMIndex: () => OIMIndex,
|
|
75
79
|
OIMIndexArrayBased: () => OIMIndexArrayBased,
|
|
76
80
|
OIMIndexComparatorFactory: () => OIMIndexComparatorFactory,
|
|
@@ -87,6 +91,13 @@ __export(index_exports, {
|
|
|
87
91
|
OIMIndexStoreMapDrivenArrayBased: () => OIMIndexStoreMapDrivenArrayBased,
|
|
88
92
|
OIMIndexStoreMapDrivenSetBased: () => OIMIndexStoreMapDrivenSetBased,
|
|
89
93
|
OIMIndexStoreSetBased: () => OIMIndexStoreSetBased,
|
|
94
|
+
OIMIndexStoreTrieDrivenArrayBased: () => OIMIndexStoreTrieDrivenArrayBased,
|
|
95
|
+
OIMIndexStoreTrieDrivenSetBased: () => OIMIndexStoreTrieDrivenSetBased,
|
|
96
|
+
OIMKeyDomainNative: () => OIMKeyDomainNative,
|
|
97
|
+
OIMKeyDomainTrie: () => OIMKeyDomainTrie,
|
|
98
|
+
OIMKeyPathCarrierResolver: () => OIMKeyPathCarrierResolver,
|
|
99
|
+
OIMKeyedBucketArrayBased: () => OIMKeyedBucketArrayBased,
|
|
100
|
+
OIMKeyedBucketSetBased: () => OIMKeyedBucketSetBased,
|
|
90
101
|
OIMMap2Keys: () => OIMMap2Keys,
|
|
91
102
|
OIMObject: () => OIMObject,
|
|
92
103
|
OIMObjectStore: () => OIMObjectStore,
|
|
@@ -98,10 +109,13 @@ __export(index_exports, {
|
|
|
98
109
|
OIMOrderedListCommandStream: () => OIMOrderedListCommandStream,
|
|
99
110
|
OIMOrderedListCommandStreamDiffDriven: () => OIMOrderedListCommandStreamDiffDriven,
|
|
100
111
|
OIMOrderedListMappedCommandStream: () => OIMOrderedListMappedCommandStream,
|
|
112
|
+
OIMPkCodecKeyPath: () => OIMPkCodecKeyPath,
|
|
101
113
|
OIMPkSelectorFactory: () => OIMPkSelectorFactory,
|
|
102
114
|
OIMReactiveCollection: () => OIMReactiveCollection,
|
|
103
115
|
OIMReactiveCollectionGlobalIndexManualArrayBased: () => OIMReactiveCollectionGlobalIndexManualArrayBased,
|
|
104
116
|
OIMReactiveCollectionGlobalIndexManualSetBased: () => OIMReactiveCollectionGlobalIndexManualSetBased,
|
|
117
|
+
OIMReactiveCollectionIndexCompositeTrieArrayBased: () => OIMReactiveCollectionIndexCompositeTrieArrayBased,
|
|
118
|
+
OIMReactiveCollectionIndexCompositeTrieSetBased: () => OIMReactiveCollectionIndexCompositeTrieSetBased,
|
|
105
119
|
OIMReactiveCollectionIndexManualArrayBased: () => OIMReactiveCollectionIndexManualArrayBased,
|
|
106
120
|
OIMReactiveCollectionIndexManualSetBased: () => OIMReactiveCollectionIndexManualSetBased,
|
|
107
121
|
OIMReactiveGlobalIndex: () => OIMReactiveGlobalIndex,
|
|
@@ -116,10 +130,14 @@ __export(index_exports, {
|
|
|
116
130
|
OIMReactiveIndexSetBased: () => OIMReactiveIndexSetBased,
|
|
117
131
|
OIMReactiveObject: () => OIMReactiveObject,
|
|
118
132
|
OIMSelector: () => OIMSelector,
|
|
133
|
+
OIMTrieMap: () => OIMTrieMap,
|
|
134
|
+
OIMTrieSet: () => OIMTrieSet,
|
|
119
135
|
createInPlaceEntityUpdater: () => createInPlaceEntityUpdater,
|
|
120
136
|
createMergeEntityUpdater: () => createMergeEntityUpdater,
|
|
121
137
|
createOIMCollectionIndexFactory: () => createOIMCollectionIndexFactory,
|
|
122
138
|
createOIMCollectionKit: () => createOIMCollectionKit,
|
|
139
|
+
createOIMDisposeScope: () => createOIMDisposeScope,
|
|
140
|
+
createOIMGlobalIndexSlotMap: () => createOIMGlobalIndexSlotMap,
|
|
123
141
|
createOIMIndexSlotMap: () => createOIMIndexSlotMap,
|
|
124
142
|
createOIMOrderedListCommandStreamDiffDriven: () => createOIMOrderedListCommandStreamDiffDriven,
|
|
125
143
|
createOIMOrderedListMappedCommandStream: () => createOIMOrderedListMappedCommandStream,
|
|
@@ -356,21 +374,82 @@ var OIMEventQueueScheduler = class {
|
|
|
356
374
|
}
|
|
357
375
|
};
|
|
358
376
|
|
|
377
|
+
// src/core/OIMKeyedBucketSetBased.ts
|
|
378
|
+
var OIMKeyedBucketSetBased = class extends Set {
|
|
379
|
+
constructor(key) {
|
|
380
|
+
super();
|
|
381
|
+
this.key = key;
|
|
382
|
+
}
|
|
383
|
+
hasSubscribers() {
|
|
384
|
+
return this.subscribers !== void 0 && this.subscribers.size > 0;
|
|
385
|
+
}
|
|
386
|
+
/** Clearing the slot set also clears the pk membership — they stay in sync. */
|
|
387
|
+
clear() {
|
|
388
|
+
super.clear();
|
|
389
|
+
this.membership?.clear();
|
|
390
|
+
}
|
|
391
|
+
};
|
|
392
|
+
|
|
359
393
|
// src/core/OIMIndexStoreMapDrivenSetBased.ts
|
|
360
394
|
var OIMIndexStoreMapDrivenSetBased = class extends OIMIndexStoreSetBased {
|
|
361
395
|
constructor() {
|
|
362
396
|
super(...arguments);
|
|
397
|
+
// Live buckets (non-empty, or freshly promoted). Enumeration reads these only.
|
|
363
398
|
this.slots = /* @__PURE__ */ new Map();
|
|
399
|
+
// Empty buckets kept alive solely by their subscribers, so a subscription
|
|
400
|
+
// survives a key going empty → re-filled. Invisible to reads/enumeration.
|
|
401
|
+
this.reservedBuckets = /* @__PURE__ */ new Map();
|
|
402
|
+
}
|
|
403
|
+
getOrReserveBucket(key) {
|
|
404
|
+
const live = this.slots.get(key);
|
|
405
|
+
if (live) return live;
|
|
406
|
+
let reserved = this.reservedBuckets.get(key);
|
|
407
|
+
if (!reserved) {
|
|
408
|
+
reserved = new OIMKeyedBucketSetBased(key);
|
|
409
|
+
this.reservedBuckets.set(key, reserved);
|
|
410
|
+
}
|
|
411
|
+
return reserved;
|
|
412
|
+
}
|
|
413
|
+
findBucket(key) {
|
|
414
|
+
return this.slots.get(key) ?? this.reservedBuckets.get(key);
|
|
415
|
+
}
|
|
416
|
+
retainBucket(bucket) {
|
|
417
|
+
if (bucket.size === 0) return;
|
|
418
|
+
this.reservedBuckets.delete(bucket.key);
|
|
419
|
+
if (!this.slots.has(bucket.key)) this.slots.set(bucket.key, bucket);
|
|
420
|
+
}
|
|
421
|
+
releaseBucket(bucket) {
|
|
422
|
+
if (bucket.size > 0) return;
|
|
423
|
+
this.slots.delete(bucket.key);
|
|
424
|
+
if (bucket.hasSubscribers()) {
|
|
425
|
+
this.reservedBuckets.set(bucket.key, bucket);
|
|
426
|
+
} else {
|
|
427
|
+
this.reservedBuckets.delete(bucket.key);
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
dropIfReserved(key) {
|
|
431
|
+
const reserved = this.reservedBuckets.get(key);
|
|
432
|
+
if (reserved && reserved.size === 0 && !reserved.hasSubscribers()) {
|
|
433
|
+
this.reservedBuckets.delete(key);
|
|
434
|
+
}
|
|
364
435
|
}
|
|
365
436
|
setOneByKey(key, slots) {
|
|
366
|
-
this.
|
|
437
|
+
const bucket = this.getOrReserveBucket(key);
|
|
438
|
+
if (bucket !== slots) {
|
|
439
|
+
bucket.clear();
|
|
440
|
+
for (const slot of slots) bucket.add(slot);
|
|
441
|
+
}
|
|
442
|
+
if (bucket.size > 0) this.retainBucket(bucket);
|
|
443
|
+
else this.releaseBucket(bucket);
|
|
367
444
|
}
|
|
368
445
|
removeOneByKey(key) {
|
|
369
446
|
this.slots.delete(key);
|
|
447
|
+
this.reservedBuckets.delete(key);
|
|
370
448
|
}
|
|
371
449
|
removeManyByKeys(keys) {
|
|
372
450
|
for (const key of keys) {
|
|
373
451
|
this.slots.delete(key);
|
|
452
|
+
this.reservedBuckets.delete(key);
|
|
374
453
|
}
|
|
375
454
|
}
|
|
376
455
|
getOneByKey(key) {
|
|
@@ -379,10 +458,8 @@ var OIMIndexStoreMapDrivenSetBased = class extends OIMIndexStoreSetBased {
|
|
|
379
458
|
getManyByKeys(keys) {
|
|
380
459
|
const result = /* @__PURE__ */ new Map();
|
|
381
460
|
for (const key of keys) {
|
|
382
|
-
const slots = this.
|
|
383
|
-
if (slots !== void 0)
|
|
384
|
-
result.set(key, slots);
|
|
385
|
-
}
|
|
461
|
+
const slots = this.slots.get(key);
|
|
462
|
+
if (slots !== void 0) result.set(key, slots);
|
|
386
463
|
}
|
|
387
464
|
return result;
|
|
388
465
|
}
|
|
@@ -396,6 +473,12 @@ var OIMIndexStoreMapDrivenSetBased = class extends OIMIndexStoreSetBased {
|
|
|
396
473
|
return this.slots.size;
|
|
397
474
|
}
|
|
398
475
|
clear() {
|
|
476
|
+
for (const bucket of this.slots.values()) {
|
|
477
|
+
bucket.clear();
|
|
478
|
+
if (bucket.hasSubscribers()) {
|
|
479
|
+
this.reservedBuckets.set(bucket.key, bucket);
|
|
480
|
+
}
|
|
481
|
+
}
|
|
399
482
|
this.slots.clear();
|
|
400
483
|
}
|
|
401
484
|
};
|
|
@@ -403,10 +486,9 @@ var OIMIndexStoreMapDrivenSetBased = class extends OIMIndexStoreSetBased {
|
|
|
403
486
|
// src/abstract/OIMIndexSetBased.ts
|
|
404
487
|
var OIMIndexSetBased = class extends OIMIndex {
|
|
405
488
|
constructor(options = {}) {
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
);
|
|
489
|
+
const store = options.store ?? new OIMIndexStoreMapDrivenSetBased();
|
|
490
|
+
super(store, options.comparePks);
|
|
491
|
+
this.setStore = store;
|
|
410
492
|
}
|
|
411
493
|
getBucketSize(bucket) {
|
|
412
494
|
return bucket.size;
|
|
@@ -434,22 +516,36 @@ var OIMIndexSetBased = class extends OIMIndex {
|
|
|
434
516
|
for (const slot of slots) pks.add(slot.pk);
|
|
435
517
|
return pks;
|
|
436
518
|
}
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
519
|
+
/**
|
|
520
|
+
* True if a comparator is set and considers `bucket`'s current pks equal to
|
|
521
|
+
* `newSlots` — i.e. a `setSlots` would be a no-op and should not emit.
|
|
522
|
+
*/
|
|
523
|
+
bucketMatchesComparator(bucket, newSlots) {
|
|
524
|
+
if (!this.comparePks) return false;
|
|
525
|
+
if (bucket.size !== newSlots.size) return false;
|
|
526
|
+
if (bucket.size === 0) return true;
|
|
527
|
+
return this.comparePks(
|
|
528
|
+
Array.from(this.slotsToPks(bucket)),
|
|
529
|
+
Array.from(this.slotsToPks(newSlots))
|
|
530
|
+
);
|
|
531
|
+
}
|
|
532
|
+
};
|
|
533
|
+
|
|
534
|
+
// src/core/OIMKeyedBucketArrayBased.ts
|
|
535
|
+
var OIMKeyedBucketArrayBased = class extends Array {
|
|
536
|
+
constructor(key) {
|
|
537
|
+
super();
|
|
538
|
+
this.key = key;
|
|
539
|
+
}
|
|
540
|
+
static get [Symbol.species]() {
|
|
541
|
+
return Array;
|
|
542
|
+
}
|
|
543
|
+
hasSubscribers() {
|
|
544
|
+
return this.subscribers !== void 0 && this.subscribers.size > 0;
|
|
545
|
+
}
|
|
546
|
+
/** Empty the bucket in place (Array has no `clear`). */
|
|
547
|
+
clear() {
|
|
548
|
+
this.length = 0;
|
|
453
549
|
}
|
|
454
550
|
};
|
|
455
551
|
|
|
@@ -457,17 +553,61 @@ var OIMIndexSetBased = class extends OIMIndex {
|
|
|
457
553
|
var OIMIndexStoreMapDrivenArrayBased = class extends OIMIndexStoreArrayBased {
|
|
458
554
|
constructor() {
|
|
459
555
|
super(...arguments);
|
|
556
|
+
// Live buckets (non-empty). Enumeration reads these only.
|
|
460
557
|
this.slots = /* @__PURE__ */ new Map();
|
|
558
|
+
// Empty buckets kept alive by their subscribers, invisible to reads.
|
|
559
|
+
this.reservedBuckets = /* @__PURE__ */ new Map();
|
|
560
|
+
}
|
|
561
|
+
getOrReserveBucket(key) {
|
|
562
|
+
const live = this.slots.get(key);
|
|
563
|
+
if (live) return live;
|
|
564
|
+
let reserved = this.reservedBuckets.get(key);
|
|
565
|
+
if (!reserved) {
|
|
566
|
+
reserved = new OIMKeyedBucketArrayBased(key);
|
|
567
|
+
this.reservedBuckets.set(key, reserved);
|
|
568
|
+
}
|
|
569
|
+
return reserved;
|
|
570
|
+
}
|
|
571
|
+
findBucket(key) {
|
|
572
|
+
return this.slots.get(key) ?? this.reservedBuckets.get(key);
|
|
573
|
+
}
|
|
574
|
+
retainBucket(bucket) {
|
|
575
|
+
if (bucket.length === 0) return;
|
|
576
|
+
this.reservedBuckets.delete(bucket.key);
|
|
577
|
+
if (!this.slots.has(bucket.key)) this.slots.set(bucket.key, bucket);
|
|
578
|
+
}
|
|
579
|
+
releaseBucket(bucket) {
|
|
580
|
+
if (bucket.length > 0) return;
|
|
581
|
+
this.slots.delete(bucket.key);
|
|
582
|
+
if (bucket.hasSubscribers()) {
|
|
583
|
+
this.reservedBuckets.set(bucket.key, bucket);
|
|
584
|
+
} else {
|
|
585
|
+
this.reservedBuckets.delete(bucket.key);
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
dropIfReserved(key) {
|
|
589
|
+
const reserved = this.reservedBuckets.get(key);
|
|
590
|
+
if (reserved && reserved.length === 0 && !reserved.hasSubscribers()) {
|
|
591
|
+
this.reservedBuckets.delete(key);
|
|
592
|
+
}
|
|
461
593
|
}
|
|
462
594
|
setOneByKey(key, slots) {
|
|
463
|
-
this.
|
|
595
|
+
const bucket = this.getOrReserveBucket(key);
|
|
596
|
+
if (bucket !== slots) {
|
|
597
|
+
bucket.length = 0;
|
|
598
|
+
for (let i = 0; i < slots.length; i++) bucket.push(slots[i]);
|
|
599
|
+
}
|
|
600
|
+
if (bucket.length > 0) this.retainBucket(bucket);
|
|
601
|
+
else this.releaseBucket(bucket);
|
|
464
602
|
}
|
|
465
603
|
removeOneByKey(key) {
|
|
466
604
|
this.slots.delete(key);
|
|
605
|
+
this.reservedBuckets.delete(key);
|
|
467
606
|
}
|
|
468
607
|
removeManyByKeys(keys) {
|
|
469
608
|
for (const key of keys) {
|
|
470
609
|
this.slots.delete(key);
|
|
610
|
+
this.reservedBuckets.delete(key);
|
|
471
611
|
}
|
|
472
612
|
}
|
|
473
613
|
getOneByKey(key) {
|
|
@@ -476,10 +616,8 @@ var OIMIndexStoreMapDrivenArrayBased = class extends OIMIndexStoreArrayBased {
|
|
|
476
616
|
getManyByKeys(keys) {
|
|
477
617
|
const result = /* @__PURE__ */ new Map();
|
|
478
618
|
for (const key of keys) {
|
|
479
|
-
const slots = this.
|
|
480
|
-
if (slots !== void 0)
|
|
481
|
-
result.set(key, slots);
|
|
482
|
-
}
|
|
619
|
+
const slots = this.slots.get(key);
|
|
620
|
+
if (slots !== void 0) result.set(key, slots);
|
|
483
621
|
}
|
|
484
622
|
return result;
|
|
485
623
|
}
|
|
@@ -493,6 +631,12 @@ var OIMIndexStoreMapDrivenArrayBased = class extends OIMIndexStoreArrayBased {
|
|
|
493
631
|
return this.slots.size;
|
|
494
632
|
}
|
|
495
633
|
clear() {
|
|
634
|
+
for (const bucket of this.slots.values()) {
|
|
635
|
+
bucket.length = 0;
|
|
636
|
+
if (bucket.hasSubscribers()) {
|
|
637
|
+
this.reservedBuckets.set(bucket.key, bucket);
|
|
638
|
+
}
|
|
639
|
+
}
|
|
496
640
|
this.slots.clear();
|
|
497
641
|
}
|
|
498
642
|
};
|
|
@@ -500,10 +644,9 @@ var OIMIndexStoreMapDrivenArrayBased = class extends OIMIndexStoreArrayBased {
|
|
|
500
644
|
// src/abstract/OIMIndexArrayBased.ts
|
|
501
645
|
var OIMIndexArrayBased = class extends OIMIndex {
|
|
502
646
|
constructor(options = {}) {
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
);
|
|
647
|
+
const store = options.store ?? new OIMIndexStoreMapDrivenArrayBased();
|
|
648
|
+
super(store, options.comparePks);
|
|
649
|
+
this.arrayStore = store;
|
|
507
650
|
}
|
|
508
651
|
getBucketSize(bucket) {
|
|
509
652
|
return bucket.length;
|
|
@@ -521,10 +664,15 @@ var OIMIndexArrayBased = class extends OIMIndex {
|
|
|
521
664
|
return result;
|
|
522
665
|
}
|
|
523
666
|
getSlotsByKey(key) {
|
|
524
|
-
|
|
667
|
+
const bucket = this.store.getOneByKey(key);
|
|
668
|
+
return bucket ? bucket.slice() : [];
|
|
525
669
|
}
|
|
526
670
|
getSlotsByKeys(keys) {
|
|
527
|
-
|
|
671
|
+
const result = /* @__PURE__ */ new Map();
|
|
672
|
+
for (const [key, bucket] of this.store.getManyByKeys(keys)) {
|
|
673
|
+
result.set(key, bucket.slice());
|
|
674
|
+
}
|
|
675
|
+
return result;
|
|
528
676
|
}
|
|
529
677
|
slotsToPks(slots) {
|
|
530
678
|
const pks = [];
|
|
@@ -532,22 +680,18 @@ var OIMIndexArrayBased = class extends OIMIndex {
|
|
|
532
680
|
for (let i = 0; i < slots.length; i++) pks[i] = slots[i].pk;
|
|
533
681
|
return pks;
|
|
534
682
|
}
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
}
|
|
548
|
-
}
|
|
549
|
-
this.store.setOneByKey(key, newSlots);
|
|
550
|
-
return true;
|
|
683
|
+
/**
|
|
684
|
+
* True if a comparator is set and considers `bucket`'s pks equal to
|
|
685
|
+
* `newSlots` — i.e. a `setSlots` would be a no-op and should not emit.
|
|
686
|
+
*/
|
|
687
|
+
bucketMatchesComparator(bucket, newSlots) {
|
|
688
|
+
if (!this.comparePks) return false;
|
|
689
|
+
if (bucket.length !== newSlots.length) return false;
|
|
690
|
+
if (bucket.length === 0) return true;
|
|
691
|
+
return this.comparePks(
|
|
692
|
+
this.slotsToPks(bucket),
|
|
693
|
+
this.slotsToPks(newSlots)
|
|
694
|
+
);
|
|
551
695
|
}
|
|
552
696
|
};
|
|
553
697
|
|
|
@@ -636,11 +780,19 @@ var OIMCarrierKeyedEmitter = class {
|
|
|
636
780
|
this.scheduleFlush();
|
|
637
781
|
}
|
|
638
782
|
markUpdatedKey(key) {
|
|
783
|
+
if (this.subscribedCarriers.size === 0) {
|
|
784
|
+
this.assertNotInFlush();
|
|
785
|
+
return;
|
|
786
|
+
}
|
|
639
787
|
const carrier = this.resolver.findCarrier(key);
|
|
640
788
|
if (carrier) this.markUpdatedCarrier(carrier);
|
|
641
789
|
else this.assertNotInFlush();
|
|
642
790
|
}
|
|
643
791
|
markUpdatedKeys(keys) {
|
|
792
|
+
if (this.subscribedCarriers.size === 0) {
|
|
793
|
+
this.assertNotInFlush();
|
|
794
|
+
return;
|
|
795
|
+
}
|
|
644
796
|
for (let i = 0; i < keys.length; i++) this.markUpdatedKey(keys[i]);
|
|
645
797
|
}
|
|
646
798
|
markAllUpdated() {
|
|
@@ -740,8 +892,8 @@ var OIMKeyedCarrierResolver = class {
|
|
|
740
892
|
|
|
741
893
|
// src/abstract/OIMReactiveIndex.ts
|
|
742
894
|
var OIMReactiveIndex = class {
|
|
743
|
-
constructor(queue, createIndex) {
|
|
744
|
-
this.updateEmitter = new OIMCarrierKeyedEmitter(queue,
|
|
895
|
+
constructor(queue, createIndex, createResolver = () => new OIMKeyedCarrierResolver()) {
|
|
896
|
+
this.updateEmitter = new OIMCarrierKeyedEmitter(queue, createResolver());
|
|
745
897
|
this.index = createIndex(this.updateEmitter);
|
|
746
898
|
}
|
|
747
899
|
getEntitiesByKey(key) {
|
|
@@ -797,8 +949,8 @@ var OIMReactiveIndex = class {
|
|
|
797
949
|
|
|
798
950
|
// src/abstract/OIMReactiveIndexSetBased.ts
|
|
799
951
|
var OIMReactiveIndexSetBased = class extends OIMReactiveIndex {
|
|
800
|
-
constructor(queue, createIndex) {
|
|
801
|
-
super(queue, createIndex);
|
|
952
|
+
constructor(queue, createIndex, createResolver) {
|
|
953
|
+
super(queue, createIndex, createResolver);
|
|
802
954
|
}
|
|
803
955
|
getPksByKey(key) {
|
|
804
956
|
return this.index.getPksByKey(key);
|
|
@@ -816,8 +968,8 @@ var OIMReactiveIndexSetBased = class extends OIMReactiveIndex {
|
|
|
816
968
|
|
|
817
969
|
// src/abstract/OIMReactiveIndexArrayBased.ts
|
|
818
970
|
var OIMReactiveIndexArrayBased = class extends OIMReactiveIndex {
|
|
819
|
-
constructor(queue, createIndex) {
|
|
820
|
-
super(queue, createIndex);
|
|
971
|
+
constructor(queue, createIndex, createResolver) {
|
|
972
|
+
super(queue, createIndex, createResolver);
|
|
821
973
|
}
|
|
822
974
|
getPksByKey(key) {
|
|
823
975
|
return this.index.getPksByKey(key);
|
|
@@ -1092,10 +1244,24 @@ var OIMPkSelectorFactory = class {
|
|
|
1092
1244
|
}
|
|
1093
1245
|
};
|
|
1094
1246
|
|
|
1247
|
+
// src/core/OIMKeyDomainNative.ts
|
|
1248
|
+
var OIMKeyDomainNative = class {
|
|
1249
|
+
createMap() {
|
|
1250
|
+
return /* @__PURE__ */ new Map();
|
|
1251
|
+
}
|
|
1252
|
+
createSet() {
|
|
1253
|
+
return /* @__PURE__ */ new Set();
|
|
1254
|
+
}
|
|
1255
|
+
canonicalize(key) {
|
|
1256
|
+
return key;
|
|
1257
|
+
}
|
|
1258
|
+
};
|
|
1259
|
+
|
|
1095
1260
|
// src/core/OIMCollectionStoreMapDriven.ts
|
|
1096
1261
|
var OIMCollectionStoreMapDriven = class extends OIMCollectionStore {
|
|
1097
1262
|
constructor() {
|
|
1098
1263
|
super(...arguments);
|
|
1264
|
+
this.keyDomain = new OIMKeyDomainNative();
|
|
1099
1265
|
this.slots = /* @__PURE__ */ new Map();
|
|
1100
1266
|
// Slots reserved by indexes for PKs whose entity has not arrived yet.
|
|
1101
1267
|
// They carry `item: undefined` and live apart from `slots` so they do not
|
|
@@ -1268,6 +1434,10 @@ var OIMCollection = class {
|
|
|
1268
1434
|
this.store = opts?.store ?? new OIMCollectionStoreMapDriven();
|
|
1269
1435
|
this.updateEntity = opts?.updateEntity ?? new OIMEntityUpdaterFactory().createMergeEntityUpdater();
|
|
1270
1436
|
}
|
|
1437
|
+
/** The collection's PK keying strategy — read by indexes and wrappers. */
|
|
1438
|
+
get keyDomain() {
|
|
1439
|
+
return this.store.keyDomain;
|
|
1440
|
+
}
|
|
1271
1441
|
getOneByPk(pk) {
|
|
1272
1442
|
return this.store.getOneByPk(pk);
|
|
1273
1443
|
}
|
|
@@ -1348,15 +1518,12 @@ var OIMCollection = class {
|
|
|
1348
1518
|
`[OIMCollection]: PK is required to upsert an entity ${JSON.stringify(entity)}`
|
|
1349
1519
|
);
|
|
1350
1520
|
}
|
|
1351
|
-
const
|
|
1352
|
-
if (
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
this.updateEntity(entity, existingEntity)
|
|
1356
|
-
);
|
|
1357
|
-
} else {
|
|
1358
|
-
return this.store.setOneByPk(pk, entity);
|
|
1521
|
+
const slot = this.store.getSlotByPk(pk);
|
|
1522
|
+
if (slot !== void 0 && slot.item !== void 0) {
|
|
1523
|
+
slot.item = this.updateEntity(entity, slot.item);
|
|
1524
|
+
return slot;
|
|
1359
1525
|
}
|
|
1526
|
+
return this.store.setOneByPk(pk, entity);
|
|
1360
1527
|
}
|
|
1361
1528
|
destroy() {
|
|
1362
1529
|
this.store.destroy();
|
|
@@ -1369,13 +1536,13 @@ var OIMReactiveCollection = class extends OIMCollection {
|
|
|
1369
1536
|
constructor(queue, opts) {
|
|
1370
1537
|
super(opts);
|
|
1371
1538
|
this.anyUpdateHandlers = /* @__PURE__ */ new Set();
|
|
1372
|
-
this.pendingAnyUpdatePks =
|
|
1539
|
+
this.pendingAnyUpdatePks = this.store.keyDomain.createSet();
|
|
1373
1540
|
this.isAnyUpdateClearPending = false;
|
|
1374
1541
|
this.isAnyUpdateScheduled = false;
|
|
1375
1542
|
this.runAnyUpdate = () => {
|
|
1376
1543
|
if (!this.isAnyUpdateScheduled) return;
|
|
1377
1544
|
this.isAnyUpdateScheduled = false;
|
|
1378
|
-
const pks = this.isAnyUpdateClearPending ? [] : Array.from(this.pendingAnyUpdatePks);
|
|
1545
|
+
const pks = this.isAnyUpdateClearPending ? [] : Array.from(this.pendingAnyUpdatePks.values());
|
|
1379
1546
|
this.pendingAnyUpdatePks.clear();
|
|
1380
1547
|
this.isAnyUpdateClearPending = false;
|
|
1381
1548
|
const snapshot = Array.from(this.anyUpdateHandlers);
|
|
@@ -1534,38 +1701,40 @@ var OIMIndexManualOrderedArrayBased = class extends OIMIndexArrayBased {
|
|
|
1534
1701
|
if (key === void 0) {
|
|
1535
1702
|
const keys = this.getKeys();
|
|
1536
1703
|
if (keys.length > 0) {
|
|
1537
|
-
this.
|
|
1704
|
+
this.arrayStore.clear();
|
|
1538
1705
|
this.emitUpdate(Array.from(keys));
|
|
1539
1706
|
}
|
|
1540
1707
|
return;
|
|
1541
1708
|
}
|
|
1542
|
-
|
|
1543
|
-
|
|
1709
|
+
const bucket = this.arrayStore.findBucket(key);
|
|
1710
|
+
if (bucket && bucket.length > 0) {
|
|
1711
|
+
bucket.length = 0;
|
|
1712
|
+
this.arrayStore.releaseBucket(bucket);
|
|
1544
1713
|
this.emitUpdate([key]);
|
|
1545
1714
|
}
|
|
1546
1715
|
}
|
|
1547
1716
|
pushSlot(key, slot) {
|
|
1548
|
-
const
|
|
1549
|
-
const index =
|
|
1550
|
-
|
|
1717
|
+
const bucket = this.arrayStore.getOrReserveBucket(key);
|
|
1718
|
+
const index = bucket.length;
|
|
1719
|
+
bucket.push(slot);
|
|
1720
|
+
this.arrayStore.retainBucket(bucket);
|
|
1551
1721
|
this.emitUpdate([key]);
|
|
1552
1722
|
return index;
|
|
1553
1723
|
}
|
|
1554
1724
|
insertSlotAt(key, index, slot) {
|
|
1555
|
-
const
|
|
1556
|
-
const safeIndex = Math.max(0, Math.min(index,
|
|
1557
|
-
|
|
1725
|
+
const bucket = this.arrayStore.getOrReserveBucket(key);
|
|
1726
|
+
const safeIndex = Math.max(0, Math.min(index, bucket.length));
|
|
1727
|
+
bucket.splice(safeIndex, 0, slot);
|
|
1728
|
+
this.arrayStore.retainBucket(bucket);
|
|
1558
1729
|
this.emitUpdate([key]);
|
|
1559
1730
|
return safeIndex;
|
|
1560
1731
|
}
|
|
1561
1732
|
removeAt(key, index) {
|
|
1562
|
-
const
|
|
1563
|
-
if (!
|
|
1564
|
-
if (index < 0 || index >=
|
|
1565
|
-
const [removed] =
|
|
1566
|
-
if (
|
|
1567
|
-
this.store.removeOneByKey(key);
|
|
1568
|
-
}
|
|
1733
|
+
const bucket = this.arrayStore.findBucket(key);
|
|
1734
|
+
if (!bucket) return void 0;
|
|
1735
|
+
if (index < 0 || index >= bucket.length) return void 0;
|
|
1736
|
+
const [removed] = bucket.splice(index, 1);
|
|
1737
|
+
if (bucket.length === 0) this.arrayStore.releaseBucket(bucket);
|
|
1569
1738
|
this.emitUpdate([key]);
|
|
1570
1739
|
return removed;
|
|
1571
1740
|
}
|
|
@@ -1574,35 +1743,33 @@ var OIMIndexManualOrderedArrayBased = class extends OIMIndexArrayBased {
|
|
|
1574
1743
|
* Returns the number actually removed (clamped to bounds; 0 if nothing).
|
|
1575
1744
|
*/
|
|
1576
1745
|
removeRange(key, index, count) {
|
|
1577
|
-
const
|
|
1578
|
-
if (!
|
|
1579
|
-
if (index < 0 || index >=
|
|
1580
|
-
const actual = Math.min(count,
|
|
1581
|
-
|
|
1582
|
-
if (
|
|
1583
|
-
this.store.removeOneByKey(key);
|
|
1584
|
-
}
|
|
1746
|
+
const bucket = this.arrayStore.findBucket(key);
|
|
1747
|
+
if (!bucket) return 0;
|
|
1748
|
+
if (index < 0 || index >= bucket.length || count <= 0) return 0;
|
|
1749
|
+
const actual = Math.min(count, bucket.length - index);
|
|
1750
|
+
bucket.splice(index, actual);
|
|
1751
|
+
if (bucket.length === 0) this.arrayStore.releaseBucket(bucket);
|
|
1585
1752
|
this.emitUpdate([key]);
|
|
1586
1753
|
return actual;
|
|
1587
1754
|
}
|
|
1588
1755
|
move(key, fromIndex, toIndex) {
|
|
1589
|
-
const
|
|
1590
|
-
if (!
|
|
1591
|
-
if (fromIndex < 0 || fromIndex >=
|
|
1592
|
-
if (toIndex < 0 || toIndex >=
|
|
1593
|
-
if (fromIndex === toIndex) return
|
|
1594
|
-
const [slot] =
|
|
1756
|
+
const bucket = this.arrayStore.findBucket(key);
|
|
1757
|
+
if (!bucket) return void 0;
|
|
1758
|
+
if (fromIndex < 0 || fromIndex >= bucket.length) return void 0;
|
|
1759
|
+
if (toIndex < 0 || toIndex >= bucket.length) return void 0;
|
|
1760
|
+
if (fromIndex === toIndex) return bucket[fromIndex];
|
|
1761
|
+
const [slot] = bucket.splice(fromIndex, 1);
|
|
1595
1762
|
if (slot === void 0) return void 0;
|
|
1596
|
-
|
|
1763
|
+
bucket.splice(toIndex, 0, slot);
|
|
1597
1764
|
this.emitUpdate([key]);
|
|
1598
1765
|
return slot;
|
|
1599
1766
|
}
|
|
1600
1767
|
/** Replace the slot at `index` in place. Returns the safe index, or -1. */
|
|
1601
1768
|
setSlotAt(key, index, slot) {
|
|
1602
|
-
const
|
|
1603
|
-
if (!
|
|
1604
|
-
if (index < 0 || index >=
|
|
1605
|
-
|
|
1769
|
+
const bucket = this.arrayStore.findBucket(key);
|
|
1770
|
+
if (!bucket) return -1;
|
|
1771
|
+
if (index < 0 || index >= bucket.length) return -1;
|
|
1772
|
+
bucket[index] = slot;
|
|
1606
1773
|
this.emitUpdate([key]);
|
|
1607
1774
|
return index;
|
|
1608
1775
|
}
|
|
@@ -1612,36 +1779,33 @@ var OIMIndexManualOrderedArrayBased = class extends OIMIndexArrayBased {
|
|
|
1612
1779
|
* Returns the number actually moved (0 if a no-op / out of bounds).
|
|
1613
1780
|
*/
|
|
1614
1781
|
moveRange(key, from, to, count) {
|
|
1615
|
-
const
|
|
1616
|
-
if (!
|
|
1617
|
-
if (from < 0 || from >=
|
|
1618
|
-
const actual = Math.min(count,
|
|
1619
|
-
const insertAt = Math.max(0, Math.min(to,
|
|
1782
|
+
const bucket = this.arrayStore.findBucket(key);
|
|
1783
|
+
if (!bucket) return 0;
|
|
1784
|
+
if (from < 0 || from >= bucket.length || count <= 0) return 0;
|
|
1785
|
+
const actual = Math.min(count, bucket.length - from);
|
|
1786
|
+
const insertAt = Math.max(0, Math.min(to, bucket.length - actual));
|
|
1620
1787
|
if (insertAt === from) return 0;
|
|
1621
|
-
const block =
|
|
1622
|
-
|
|
1788
|
+
const block = bucket.splice(from, actual);
|
|
1789
|
+
bucket.splice(insertAt, 0, ...block);
|
|
1623
1790
|
this.emitUpdate([key]);
|
|
1624
1791
|
return actual;
|
|
1625
1792
|
}
|
|
1626
1793
|
resetSlots(key, slots) {
|
|
1627
1794
|
if (slots.length === 0) {
|
|
1628
|
-
|
|
1629
|
-
|
|
1795
|
+
const bucket2 = this.arrayStore.findBucket(key);
|
|
1796
|
+
if (bucket2 && bucket2.length > 0) {
|
|
1797
|
+
bucket2.length = 0;
|
|
1798
|
+
this.arrayStore.releaseBucket(bucket2);
|
|
1630
1799
|
this.emitUpdate([key]);
|
|
1631
1800
|
}
|
|
1632
1801
|
return;
|
|
1633
1802
|
}
|
|
1634
|
-
this.
|
|
1803
|
+
const bucket = this.arrayStore.getOrReserveBucket(key);
|
|
1804
|
+
bucket.length = 0;
|
|
1805
|
+
for (let i = 0; i < slots.length; i++) bucket.push(slots[i]);
|
|
1806
|
+
this.arrayStore.retainBucket(bucket);
|
|
1635
1807
|
this.emitUpdate([key]);
|
|
1636
1808
|
}
|
|
1637
|
-
getOrCreateList(key) {
|
|
1638
|
-
let list = this.store.getOneByKey(key);
|
|
1639
|
-
if (!list) {
|
|
1640
|
-
list = [];
|
|
1641
|
-
this.store.setOneByKey(key, list);
|
|
1642
|
-
}
|
|
1643
|
-
return list;
|
|
1644
|
-
}
|
|
1645
1809
|
};
|
|
1646
1810
|
|
|
1647
1811
|
// src/core/OIMCollectionIndexManualOrderedArrayBased.ts
|
|
@@ -2159,43 +2323,68 @@ var OIMIndexManualArrayBased = class extends OIMIndexArrayBased {
|
|
|
2159
2323
|
super(options);
|
|
2160
2324
|
}
|
|
2161
2325
|
setSlots(key, slots) {
|
|
2162
|
-
const
|
|
2163
|
-
if (
|
|
2164
|
-
|
|
2165
|
-
|
|
2326
|
+
const bucket = this.arrayStore.getOrReserveBucket(key);
|
|
2327
|
+
if (this.bucketMatchesComparator(bucket, slots)) return;
|
|
2328
|
+
bucket.length = 0;
|
|
2329
|
+
for (let i = 0; i < slots.length; i++) bucket.push(slots[i]);
|
|
2330
|
+
if (bucket.length > 0) this.arrayStore.retainBucket(bucket);
|
|
2331
|
+
else this.arrayStore.releaseBucket(bucket);
|
|
2332
|
+
this.emitBucketChanged(bucket);
|
|
2166
2333
|
}
|
|
2167
2334
|
/**
|
|
2168
|
-
* Appends pre-deduplicated slots to a key's bucket IN PLACE
|
|
2169
|
-
*
|
|
2170
|
-
* not O(bucket)); used by collection-bound indexes for fast `addPks`.
|
|
2335
|
+
* Appends pre-deduplicated slots to a key's bucket IN PLACE and emits once.
|
|
2336
|
+
* O(added); callers own dedup.
|
|
2171
2337
|
*/
|
|
2172
2338
|
appendSlots(key, slots) {
|
|
2173
2339
|
if (slots.length === 0) return;
|
|
2174
|
-
|
|
2175
|
-
if (!bucket) {
|
|
2176
|
-
bucket = [];
|
|
2177
|
-
this.store.setOneByKey(key, bucket);
|
|
2178
|
-
}
|
|
2340
|
+
const bucket = this.arrayStore.getOrReserveBucket(key);
|
|
2179
2341
|
for (let i = 0; i < slots.length; i++) bucket.push(slots[i]);
|
|
2180
|
-
this.
|
|
2342
|
+
this.arrayStore.retainBucket(bucket);
|
|
2343
|
+
this.emitBucketChanged(bucket);
|
|
2181
2344
|
}
|
|
2182
2345
|
/**
|
|
2183
|
-
* Clear all primary keys for a specific index key, or all keys if
|
|
2346
|
+
* Clear all primary keys for a specific index key, or all keys if none given.
|
|
2184
2347
|
*/
|
|
2185
2348
|
clear(key) {
|
|
2186
2349
|
if (key === void 0) {
|
|
2187
|
-
const allKeys = this.
|
|
2350
|
+
const allKeys = this.arrayStore.getAllKeys();
|
|
2188
2351
|
if (allKeys.length > 0) {
|
|
2189
|
-
this.
|
|
2352
|
+
this.arrayStore.clear();
|
|
2190
2353
|
this.emitUpdate(allKeys);
|
|
2191
2354
|
}
|
|
2192
2355
|
} else {
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2356
|
+
const bucket = this.arrayStore.findBucket(key);
|
|
2357
|
+
if (bucket && bucket.length > 0) {
|
|
2358
|
+
bucket.length = 0;
|
|
2359
|
+
this.arrayStore.releaseBucket(bucket);
|
|
2360
|
+
this.emitBucketChanged(bucket);
|
|
2196
2361
|
}
|
|
2197
2362
|
}
|
|
2198
2363
|
}
|
|
2364
|
+
/**
|
|
2365
|
+
* Emit that a bucket changed. Base (non-reactive) path emits by key on the
|
|
2366
|
+
* plain event emitter; the reactive subclass overrides this to mark the
|
|
2367
|
+
* bucket carrier directly (O(1), no key→carrier lookup).
|
|
2368
|
+
*/
|
|
2369
|
+
emitBucketChanged(bucket) {
|
|
2370
|
+
this.emitUpdateOne(bucket.key);
|
|
2371
|
+
}
|
|
2372
|
+
};
|
|
2373
|
+
|
|
2374
|
+
// src/core/OIMBucketCarrierResolver.ts
|
|
2375
|
+
var OIMBucketCarrierResolver = class {
|
|
2376
|
+
constructor(store) {
|
|
2377
|
+
this.store = store;
|
|
2378
|
+
}
|
|
2379
|
+
getOrReserveCarrier(key) {
|
|
2380
|
+
return this.store.getOrReserveBucket(key);
|
|
2381
|
+
}
|
|
2382
|
+
findCarrier(key) {
|
|
2383
|
+
return this.store.findBucket(key);
|
|
2384
|
+
}
|
|
2385
|
+
onCarrierEmptied(carrier) {
|
|
2386
|
+
this.store.dropIfReserved(carrier.key);
|
|
2387
|
+
}
|
|
2199
2388
|
};
|
|
2200
2389
|
|
|
2201
2390
|
// src/core/OIMReactiveIndexManualArrayBased.ts
|
|
@@ -2204,6 +2393,10 @@ var OIMIndexManualArrayBasedReactive = class extends OIMIndexManualArrayBased {
|
|
|
2204
2393
|
super(opts);
|
|
2205
2394
|
this.updateEmitter = updateEmitter;
|
|
2206
2395
|
}
|
|
2396
|
+
// Deliver straight off the bucket the write just touched — O(1).
|
|
2397
|
+
emitBucketChanged(bucket) {
|
|
2398
|
+
this.updateEmitter.markUpdatedCarrier(bucket);
|
|
2399
|
+
}
|
|
2207
2400
|
emitUpdate(keys) {
|
|
2208
2401
|
this.updateEmitter.markUpdatedKeys(keys);
|
|
2209
2402
|
}
|
|
@@ -2213,12 +2406,15 @@ var OIMIndexManualArrayBasedReactive = class extends OIMIndexManualArrayBased {
|
|
|
2213
2406
|
};
|
|
2214
2407
|
var OIMReactiveIndexManualArrayBased = class extends OIMReactiveIndexArrayBased {
|
|
2215
2408
|
constructor(queue, opts) {
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2409
|
+
const store = opts?.indexOptions?.store ?? new OIMIndexStoreMapDrivenArrayBased();
|
|
2410
|
+
super(
|
|
2411
|
+
queue,
|
|
2412
|
+
(updateEmitter) => new OIMIndexManualArrayBasedReactive(updateEmitter, {
|
|
2413
|
+
comparePks: opts?.indexOptions?.comparePks,
|
|
2414
|
+
store
|
|
2415
|
+
}),
|
|
2416
|
+
() => new OIMBucketCarrierResolver(store)
|
|
2417
|
+
);
|
|
2222
2418
|
}
|
|
2223
2419
|
setSlots(key, slots) {
|
|
2224
2420
|
this.index.setSlots(key, slots);
|
|
@@ -2235,6 +2431,7 @@ var OIMReactiveIndexManualArrayBased = class extends OIMReactiveIndexArrayBased
|
|
|
2235
2431
|
var OIMReactiveCollectionIndexManualArrayBased = class extends OIMReactiveIndexManualArrayBased {
|
|
2236
2432
|
constructor(queue, opts) {
|
|
2237
2433
|
const resolveSlot = opts.collection !== void 0 ? (pk) => opts.collection.getOrReserveSlotByPk(pk) : opts.resolveSlot;
|
|
2434
|
+
const pkDomain = opts.collection?.keyDomain ?? new OIMKeyDomainNative();
|
|
2238
2435
|
super(queue, {
|
|
2239
2436
|
indexOptions: opts.indexOptions
|
|
2240
2437
|
});
|
|
@@ -2242,9 +2439,10 @@ var OIMReactiveCollectionIndexManualArrayBased = class extends OIMReactiveIndexM
|
|
|
2242
2439
|
// a Set from the whole bucket on every call). Kept in sync by setSlots/clear.
|
|
2243
2440
|
this.pksByKey = /* @__PURE__ */ new Map();
|
|
2244
2441
|
this.resolveSlot = resolveSlot;
|
|
2442
|
+
this.pkDomain = pkDomain;
|
|
2245
2443
|
}
|
|
2246
2444
|
setPks(key, pks) {
|
|
2247
|
-
const pkSet =
|
|
2445
|
+
const pkSet = this.pkDomain.createSet();
|
|
2248
2446
|
for (let i = 0; i < pks.length; i++) pkSet.add(pks[i]);
|
|
2249
2447
|
this.pksByKey.set(key, pkSet);
|
|
2250
2448
|
super.setSlots(key, this.resolveSlots(pks));
|
|
@@ -2287,7 +2485,7 @@ var OIMReactiveCollectionIndexManualArrayBased = class extends OIMReactiveIndexM
|
|
|
2287
2485
|
membershipOf(key) {
|
|
2288
2486
|
let pkSet = this.pksByKey.get(key);
|
|
2289
2487
|
if (!pkSet) {
|
|
2290
|
-
pkSet =
|
|
2488
|
+
pkSet = this.pkDomain.createSet();
|
|
2291
2489
|
const existing = this.index.getSlotsByKey(key);
|
|
2292
2490
|
for (let i = 0; i < existing.length; i++) {
|
|
2293
2491
|
pkSet.add(existing[i].pk);
|
|
@@ -2321,24 +2519,98 @@ var OIMReactiveCollectionIndexManualArrayBased = class extends OIMReactiveIndexM
|
|
|
2321
2519
|
var OIMIndexManualSetBased = class extends OIMIndexSetBased {
|
|
2322
2520
|
constructor(options = {}) {
|
|
2323
2521
|
super(options);
|
|
2522
|
+
this.pkDomain = options.pkDomain ?? new OIMKeyDomainNative();
|
|
2324
2523
|
}
|
|
2325
2524
|
setSlots(key, slots) {
|
|
2326
|
-
const
|
|
2327
|
-
|
|
2328
|
-
|
|
2525
|
+
const bucket = this.setStore.getOrReserveBucket(key);
|
|
2526
|
+
this.replaceBucketContents(bucket, slots);
|
|
2527
|
+
}
|
|
2528
|
+
// --- pk-oriented writes: resolve the bucket ONCE and use its own membership
|
|
2529
|
+
// (pk → slot) for dedup/removal, so a composite (trie) key is walked a single
|
|
2530
|
+
// time instead of once for the bucket and once for a separate membership map.
|
|
2531
|
+
setPks(key, pks, resolveSlot) {
|
|
2532
|
+
const bucket = this.setStore.getOrReserveBucket(key);
|
|
2533
|
+
const slots = [];
|
|
2534
|
+
for (let i = 0; i < pks.length; i++) slots.push(resolveSlot(pks[i]));
|
|
2535
|
+
this.replaceBucketContents(bucket, slots);
|
|
2536
|
+
const membership = bucket.membership ?? (bucket.membership = this.pkDomain.createMap());
|
|
2537
|
+
membership.clear();
|
|
2538
|
+
for (let i = 0; i < pks.length; i++) {
|
|
2539
|
+
if (!membership.has(pks[i])) membership.set(pks[i], slots[i]);
|
|
2540
|
+
}
|
|
2541
|
+
}
|
|
2542
|
+
addPks(key, pks, resolveSlot) {
|
|
2543
|
+
if (pks.length === 0) return;
|
|
2544
|
+
const bucket = this.setStore.getOrReserveBucket(key);
|
|
2545
|
+
const membership = this.membershipOf(bucket);
|
|
2546
|
+
let changed = false;
|
|
2547
|
+
for (let i = 0; i < pks.length; i++) {
|
|
2548
|
+
const pk = pks[i];
|
|
2549
|
+
if (membership.has(pk)) continue;
|
|
2550
|
+
const slot = resolveSlot(pk);
|
|
2551
|
+
membership.set(pk, slot);
|
|
2552
|
+
if (!bucket.has(slot)) {
|
|
2553
|
+
bucket.add(slot);
|
|
2554
|
+
changed = true;
|
|
2555
|
+
}
|
|
2556
|
+
}
|
|
2557
|
+
if (!changed) return;
|
|
2558
|
+
this.setStore.retainBucket(bucket);
|
|
2559
|
+
this.emitBucketChanged(bucket);
|
|
2560
|
+
}
|
|
2561
|
+
removePks(key, pks) {
|
|
2562
|
+
if (pks.length === 0) return;
|
|
2563
|
+
const bucket = this.setStore.findBucket(key);
|
|
2564
|
+
if (!bucket || bucket.size === 0) return;
|
|
2565
|
+
const membership = this.membershipOf(bucket);
|
|
2566
|
+
let changed = false;
|
|
2567
|
+
for (let i = 0; i < pks.length; i++) {
|
|
2568
|
+
const slot = membership.get(pks[i]);
|
|
2569
|
+
if (slot) {
|
|
2570
|
+
membership.delete(pks[i]);
|
|
2571
|
+
if (bucket.delete(slot)) changed = true;
|
|
2572
|
+
}
|
|
2573
|
+
}
|
|
2574
|
+
if (!changed) return;
|
|
2575
|
+
if (bucket.size === 0) this.setStore.releaseBucket(bucket);
|
|
2576
|
+
this.emitBucketChanged(bucket);
|
|
2577
|
+
}
|
|
2578
|
+
/**
|
|
2579
|
+
* The bucket's pk → slot membership, lazily created and seeded from the
|
|
2580
|
+
* bucket's current slots (so it stays correct even if slots were written
|
|
2581
|
+
* through the lower-level `setSlots` path).
|
|
2582
|
+
*/
|
|
2583
|
+
membershipOf(bucket) {
|
|
2584
|
+
let membership = bucket.membership;
|
|
2585
|
+
if (!membership) {
|
|
2586
|
+
membership = this.pkDomain.createMap();
|
|
2587
|
+
bucket.membership = membership;
|
|
2588
|
+
}
|
|
2589
|
+
if (membership.size === 0 && bucket.size > 0) {
|
|
2590
|
+
for (const slot of bucket) membership.set(slot.pk, slot);
|
|
2591
|
+
}
|
|
2592
|
+
return membership;
|
|
2593
|
+
}
|
|
2594
|
+
replaceBucketContents(bucket, slots) {
|
|
2595
|
+
if (this.comparePks) {
|
|
2596
|
+
const newSet = slots instanceof Set ? slots : new Set(slots);
|
|
2597
|
+
if (this.bucketMatchesComparator(bucket, newSet)) return;
|
|
2598
|
+
bucket.clear();
|
|
2599
|
+
for (const slot of newSet) bucket.add(slot);
|
|
2600
|
+
} else {
|
|
2601
|
+
bucket.clear();
|
|
2602
|
+
for (const slot of slots) bucket.add(slot);
|
|
2329
2603
|
}
|
|
2604
|
+
if (bucket.size > 0) this.setStore.retainBucket(bucket);
|
|
2605
|
+
else this.setStore.releaseBucket(bucket);
|
|
2606
|
+
this.emitBucketChanged(bucket);
|
|
2330
2607
|
}
|
|
2331
2608
|
/**
|
|
2332
|
-
* Adds slots to a key's bucket IN PLACE
|
|
2333
|
-
* emits once. O(added). Used by collection-bound indexes for fast `addPks`.
|
|
2609
|
+
* Adds slots to a key's bucket IN PLACE and emits once. O(added).
|
|
2334
2610
|
*/
|
|
2335
2611
|
addSlots(key, slots) {
|
|
2336
2612
|
if (slots.length === 0) return;
|
|
2337
|
-
|
|
2338
|
-
if (!bucket) {
|
|
2339
|
-
bucket = /* @__PURE__ */ new Set();
|
|
2340
|
-
this.store.setOneByKey(key, bucket);
|
|
2341
|
-
}
|
|
2613
|
+
const bucket = this.setStore.getOrReserveBucket(key);
|
|
2342
2614
|
let changed = false;
|
|
2343
2615
|
for (let i = 0; i < slots.length; i++) {
|
|
2344
2616
|
if (!bucket.has(slots[i])) {
|
|
@@ -2346,25 +2618,27 @@ var OIMIndexManualSetBased = class extends OIMIndexSetBased {
|
|
|
2346
2618
|
changed = true;
|
|
2347
2619
|
}
|
|
2348
2620
|
}
|
|
2349
|
-
if (changed)
|
|
2621
|
+
if (!changed) return;
|
|
2622
|
+
this.setStore.retainBucket(bucket);
|
|
2623
|
+
this.emitBucketChanged(bucket);
|
|
2350
2624
|
}
|
|
2351
2625
|
/**
|
|
2352
2626
|
* Removes slots from a key's bucket IN PLACE (O(removed)) and emits once.
|
|
2353
2627
|
*/
|
|
2354
2628
|
removeSlots(key, slots) {
|
|
2355
2629
|
if (slots.length === 0) return;
|
|
2356
|
-
const bucket = this.
|
|
2630
|
+
const bucket = this.setStore.findBucket(key);
|
|
2357
2631
|
if (!bucket) return;
|
|
2358
2632
|
let changed = false;
|
|
2359
2633
|
for (let i = 0; i < slots.length; i++) {
|
|
2360
2634
|
if (bucket.delete(slots[i])) changed = true;
|
|
2361
2635
|
}
|
|
2362
2636
|
if (!changed) return;
|
|
2363
|
-
if (bucket.size === 0) this.
|
|
2364
|
-
this.
|
|
2637
|
+
if (bucket.size === 0) this.setStore.releaseBucket(bucket);
|
|
2638
|
+
this.emitBucketChanged(bucket);
|
|
2365
2639
|
}
|
|
2366
2640
|
/**
|
|
2367
|
-
* Clear all primary keys for a specific index key, or all keys if
|
|
2641
|
+
* Clear all primary keys for a specific index key, or all keys if none given.
|
|
2368
2642
|
*/
|
|
2369
2643
|
clear(key) {
|
|
2370
2644
|
if (key === void 0) {
|
|
@@ -2374,12 +2648,22 @@ var OIMIndexManualSetBased = class extends OIMIndexSetBased {
|
|
|
2374
2648
|
this.emitUpdate(allKeys);
|
|
2375
2649
|
}
|
|
2376
2650
|
} else {
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
2651
|
+
const bucket = this.setStore.findBucket(key);
|
|
2652
|
+
if (bucket && bucket.size > 0) {
|
|
2653
|
+
bucket.clear();
|
|
2654
|
+
this.setStore.releaseBucket(bucket);
|
|
2655
|
+
this.emitBucketChanged(bucket);
|
|
2380
2656
|
}
|
|
2381
2657
|
}
|
|
2382
2658
|
}
|
|
2659
|
+
/**
|
|
2660
|
+
* Emit that a bucket changed. Base (non-reactive) path emits by key on the
|
|
2661
|
+
* plain event emitter; the reactive subclass overrides this to mark the
|
|
2662
|
+
* bucket carrier directly (O(1), no key→carrier lookup).
|
|
2663
|
+
*/
|
|
2664
|
+
emitBucketChanged(bucket) {
|
|
2665
|
+
this.emitUpdateOne(bucket.key);
|
|
2666
|
+
}
|
|
2383
2667
|
};
|
|
2384
2668
|
|
|
2385
2669
|
// src/core/OIMReactiveIndexManualSetBased.ts
|
|
@@ -2388,6 +2672,12 @@ var OIMIndexManualSetBasedReactive = class extends OIMIndexManualSetBased {
|
|
|
2388
2672
|
super(opts);
|
|
2389
2673
|
this.updateEmitter = updateEmitter;
|
|
2390
2674
|
}
|
|
2675
|
+
// Deliver straight off the bucket the write just touched — O(1), no
|
|
2676
|
+
// key→carrier lookup (the whole point of bucket-as-carrier).
|
|
2677
|
+
emitBucketChanged(bucket) {
|
|
2678
|
+
this.updateEmitter.markUpdatedCarrier(bucket);
|
|
2679
|
+
}
|
|
2680
|
+
// clear(all) still emits by key set (rare path).
|
|
2391
2681
|
emitUpdate(keys) {
|
|
2392
2682
|
this.updateEmitter.markUpdatedKeys(keys);
|
|
2393
2683
|
}
|
|
@@ -2397,12 +2687,16 @@ var OIMIndexManualSetBasedReactive = class extends OIMIndexManualSetBased {
|
|
|
2397
2687
|
};
|
|
2398
2688
|
var OIMReactiveIndexManualSetBased = class extends OIMReactiveIndexSetBased {
|
|
2399
2689
|
constructor(queue, opts) {
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
|
|
2403
|
-
|
|
2404
|
-
|
|
2405
|
-
|
|
2690
|
+
const store = opts?.indexOptions?.store ?? new OIMIndexStoreMapDrivenSetBased();
|
|
2691
|
+
super(
|
|
2692
|
+
queue,
|
|
2693
|
+
(updateEmitter) => new OIMIndexManualSetBasedReactive(updateEmitter, {
|
|
2694
|
+
comparePks: opts?.indexOptions?.comparePks,
|
|
2695
|
+
store,
|
|
2696
|
+
pkDomain: opts?.pkDomain
|
|
2697
|
+
}),
|
|
2698
|
+
() => new OIMBucketCarrierResolver(store)
|
|
2699
|
+
);
|
|
2406
2700
|
}
|
|
2407
2701
|
setSlots(key, slots) {
|
|
2408
2702
|
this.index.setSlots(key, slots);
|
|
@@ -2423,71 +2717,26 @@ var OIMReactiveCollectionIndexManualSetBased = class extends OIMReactiveIndexMan
|
|
|
2423
2717
|
constructor(queue, opts) {
|
|
2424
2718
|
const resolveSlot = opts.collection !== void 0 ? (pk) => opts.collection.getOrReserveSlotByPk(pk) : opts.resolveSlot;
|
|
2425
2719
|
super(queue, {
|
|
2426
|
-
indexOptions: opts.indexOptions
|
|
2720
|
+
indexOptions: opts.indexOptions,
|
|
2721
|
+
pkDomain: opts.collection?.keyDomain
|
|
2427
2722
|
});
|
|
2428
|
-
//
|
|
2429
|
-
//
|
|
2430
|
-
this.
|
|
2723
|
+
// Bound once so the hot pk-write path passes a stable function (no per-call
|
|
2724
|
+
// closure allocation).
|
|
2725
|
+
this.resolveRequiredSlot = (pk) => {
|
|
2726
|
+
const slot = this.resolveSlot(pk);
|
|
2727
|
+
if (!slot) return { pk, item: void 0 };
|
|
2728
|
+
return slot;
|
|
2729
|
+
};
|
|
2431
2730
|
this.resolveSlot = resolveSlot;
|
|
2432
2731
|
}
|
|
2433
2732
|
setPks(key, pks) {
|
|
2434
|
-
|
|
2435
|
-
const slots = [];
|
|
2436
|
-
for (let i = 0; i < pks.length; i++) {
|
|
2437
|
-
const pk = pks[i];
|
|
2438
|
-
const slot = this.resolveRequiredSlot(pk);
|
|
2439
|
-
if (!map.has(pk)) map.set(pk, slot);
|
|
2440
|
-
slots.push(slot);
|
|
2441
|
-
}
|
|
2442
|
-
this.slotByPk.set(key, map);
|
|
2443
|
-
super.setSlots(key, slots);
|
|
2733
|
+
this.index.setPks(key, pks, this.resolveRequiredSlot);
|
|
2444
2734
|
}
|
|
2445
2735
|
addPks(key, pks) {
|
|
2446
|
-
|
|
2447
|
-
const map = this.membershipOf(key);
|
|
2448
|
-
const newSlots = [];
|
|
2449
|
-
for (const pk of pks) {
|
|
2450
|
-
if (map.has(pk)) continue;
|
|
2451
|
-
const slot = this.resolveRequiredSlot(pk);
|
|
2452
|
-
map.set(pk, slot);
|
|
2453
|
-
newSlots.push(slot);
|
|
2454
|
-
}
|
|
2455
|
-
if (newSlots.length > 0) this.addSlots(key, newSlots);
|
|
2736
|
+
this.index.addPks(key, pks, this.resolveRequiredSlot);
|
|
2456
2737
|
}
|
|
2457
2738
|
removePks(key, pks) {
|
|
2458
|
-
|
|
2459
|
-
const map = this.membershipOf(key);
|
|
2460
|
-
if (map.size === 0) return;
|
|
2461
|
-
const removed = [];
|
|
2462
|
-
for (const pk of pks) {
|
|
2463
|
-
const slot = map.get(pk);
|
|
2464
|
-
if (slot) {
|
|
2465
|
-
map.delete(pk);
|
|
2466
|
-
removed.push(slot);
|
|
2467
|
-
}
|
|
2468
|
-
}
|
|
2469
|
-
if (removed.length === 0) return;
|
|
2470
|
-
if (map.size === 0) this.slotByPk.delete(key);
|
|
2471
|
-
this.removeSlots(key, removed);
|
|
2472
|
-
}
|
|
2473
|
-
clear(key) {
|
|
2474
|
-
if (key === void 0) this.slotByPk.clear();
|
|
2475
|
-
else this.slotByPk.delete(key);
|
|
2476
|
-
super.clear(key);
|
|
2477
|
-
}
|
|
2478
|
-
/**
|
|
2479
|
-
* The pk→slot map for a key, lazily seeded from the current bucket so it
|
|
2480
|
-
* stays correct even if slots were set through a lower-level path.
|
|
2481
|
-
*/
|
|
2482
|
-
membershipOf(key) {
|
|
2483
|
-
let map = this.slotByPk.get(key);
|
|
2484
|
-
if (!map) {
|
|
2485
|
-
map = /* @__PURE__ */ new Map();
|
|
2486
|
-
const existing = this.index.getSlotsByKey(key);
|
|
2487
|
-
for (const slot of existing) map.set(slot.pk, slot);
|
|
2488
|
-
this.slotByPk.set(key, map);
|
|
2489
|
-
}
|
|
2490
|
-
return map;
|
|
2739
|
+
this.index.removePks(key, pks);
|
|
2491
2740
|
}
|
|
2492
2741
|
getEntitiesByKey(key) {
|
|
2493
2742
|
return super.getEntitiesByKey(key);
|
|
@@ -2495,50 +2744,459 @@ var OIMReactiveCollectionIndexManualSetBased = class extends OIMReactiveIndexMan
|
|
|
2495
2744
|
getEntitiesByKeys(keys) {
|
|
2496
2745
|
return super.getEntitiesByKeys(keys);
|
|
2497
2746
|
}
|
|
2498
|
-
resolveRequiredSlot(pk) {
|
|
2499
|
-
const slot = this.resolveSlot(pk);
|
|
2500
|
-
if (!slot) return { pk, item: void 0 };
|
|
2501
|
-
return slot;
|
|
2502
|
-
}
|
|
2503
2747
|
};
|
|
2504
2748
|
|
|
2505
|
-
// src/core/
|
|
2506
|
-
var
|
|
2507
|
-
constructor(
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
this.
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
|
|
2749
|
+
// src/core/OIMTrieMap.ts
|
|
2750
|
+
var OIMTrieMap = class {
|
|
2751
|
+
constructor() {
|
|
2752
|
+
this.root = { hasValue: false };
|
|
2753
|
+
this._size = 0;
|
|
2754
|
+
}
|
|
2755
|
+
/** Number of stored paths (terminal nodes), not the number of trie nodes. */
|
|
2756
|
+
get size() {
|
|
2757
|
+
return this._size;
|
|
2758
|
+
}
|
|
2759
|
+
set(path, value) {
|
|
2760
|
+
let node = this.root;
|
|
2761
|
+
for (let i = 0; i < path.length; i++) {
|
|
2762
|
+
let children = node.children;
|
|
2763
|
+
if (!children) {
|
|
2764
|
+
children = /* @__PURE__ */ new Map();
|
|
2765
|
+
node.children = children;
|
|
2517
2766
|
}
|
|
2518
|
-
|
|
2519
|
-
|
|
2767
|
+
let next = children.get(path[i]);
|
|
2768
|
+
if (!next) {
|
|
2769
|
+
next = { hasValue: false };
|
|
2770
|
+
children.set(path[i], next);
|
|
2520
2771
|
}
|
|
2521
|
-
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
|
|
2525
|
-
|
|
2526
|
-
|
|
2527
|
-
|
|
2528
|
-
|
|
2529
|
-
|
|
2772
|
+
node = next;
|
|
2773
|
+
}
|
|
2774
|
+
if (!node.hasValue) {
|
|
2775
|
+
node.hasValue = true;
|
|
2776
|
+
this._size++;
|
|
2777
|
+
}
|
|
2778
|
+
node.value = value;
|
|
2779
|
+
}
|
|
2780
|
+
get(path) {
|
|
2781
|
+
const node = this.findNode(path);
|
|
2782
|
+
return node && node.hasValue ? node.value : void 0;
|
|
2783
|
+
}
|
|
2784
|
+
has(path) {
|
|
2785
|
+
const node = this.findNode(path);
|
|
2786
|
+
return !!node && node.hasValue;
|
|
2787
|
+
}
|
|
2788
|
+
delete(path) {
|
|
2789
|
+
const parents = [];
|
|
2790
|
+
let node = this.root;
|
|
2791
|
+
for (let i = 0; i < path.length; i++) {
|
|
2792
|
+
const next = node.children?.get(path[i]);
|
|
2793
|
+
if (!next) return false;
|
|
2794
|
+
parents.push(node);
|
|
2795
|
+
node = next;
|
|
2796
|
+
}
|
|
2797
|
+
if (!node.hasValue) return false;
|
|
2798
|
+
node.hasValue = false;
|
|
2799
|
+
node.value = void 0;
|
|
2800
|
+
this._size--;
|
|
2801
|
+
let child = node;
|
|
2802
|
+
for (let i = parents.length - 1; i >= 0; i--) {
|
|
2803
|
+
if (child.hasValue || child.children && child.children.size > 0) {
|
|
2804
|
+
break;
|
|
2805
|
+
}
|
|
2806
|
+
const parent = parents[i];
|
|
2807
|
+
parent.children.delete(path[i]);
|
|
2808
|
+
if (parent.children.size === 0) parent.children = void 0;
|
|
2809
|
+
child = parent;
|
|
2530
2810
|
}
|
|
2811
|
+
return true;
|
|
2531
2812
|
}
|
|
2532
|
-
|
|
2533
|
-
this.
|
|
2534
|
-
|
|
2535
|
-
|
|
2536
|
-
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
|
|
2540
|
-
|
|
2541
|
-
|
|
2813
|
+
clear() {
|
|
2814
|
+
this.root.children = void 0;
|
|
2815
|
+
this.root.value = void 0;
|
|
2816
|
+
this.root.hasValue = false;
|
|
2817
|
+
this._size = 0;
|
|
2818
|
+
}
|
|
2819
|
+
/** Depth-first iteration over `[path, value]` for every stored path. */
|
|
2820
|
+
*entries() {
|
|
2821
|
+
const stack = [{ node: this.root, path: [] }];
|
|
2822
|
+
while (stack.length > 0) {
|
|
2823
|
+
const frame = stack.pop();
|
|
2824
|
+
const { node, path } = frame;
|
|
2825
|
+
if (node.hasValue) {
|
|
2826
|
+
yield [path, node.value];
|
|
2827
|
+
}
|
|
2828
|
+
if (node.children) {
|
|
2829
|
+
for (const [segment, child] of node.children) {
|
|
2830
|
+
stack.push({ node: child, path: [...path, segment] });
|
|
2831
|
+
}
|
|
2832
|
+
}
|
|
2833
|
+
}
|
|
2834
|
+
}
|
|
2835
|
+
*keys() {
|
|
2836
|
+
for (const [path] of this.entries()) yield path;
|
|
2837
|
+
}
|
|
2838
|
+
*values() {
|
|
2839
|
+
for (const [, value] of this.entries()) yield value;
|
|
2840
|
+
}
|
|
2841
|
+
findNode(path) {
|
|
2842
|
+
let node = this.root;
|
|
2843
|
+
for (let i = 0; i < path.length; i++) {
|
|
2844
|
+
node = node.children?.get(path[i]);
|
|
2845
|
+
if (!node) return void 0;
|
|
2846
|
+
}
|
|
2847
|
+
return node;
|
|
2848
|
+
}
|
|
2849
|
+
};
|
|
2850
|
+
|
|
2851
|
+
// src/core/OIMIndexStoreTrieDrivenSetBased.ts
|
|
2852
|
+
var OIMIndexStoreTrieDrivenSetBased = class extends OIMIndexStoreSetBased {
|
|
2853
|
+
constructor() {
|
|
2854
|
+
super(...arguments);
|
|
2855
|
+
this.slots = new OIMTrieMap();
|
|
2856
|
+
this.reservedBuckets = new OIMTrieMap();
|
|
2857
|
+
}
|
|
2858
|
+
getOrReserveBucket(key) {
|
|
2859
|
+
const live = this.slots.get(key);
|
|
2860
|
+
if (live) return live;
|
|
2861
|
+
let reserved = this.reservedBuckets.get(key);
|
|
2862
|
+
if (!reserved) {
|
|
2863
|
+
reserved = new OIMKeyedBucketSetBased(key);
|
|
2864
|
+
this.reservedBuckets.set(key, reserved);
|
|
2865
|
+
}
|
|
2866
|
+
return reserved;
|
|
2867
|
+
}
|
|
2868
|
+
findBucket(key) {
|
|
2869
|
+
return this.slots.get(key) ?? this.reservedBuckets.get(key);
|
|
2870
|
+
}
|
|
2871
|
+
retainBucket(bucket) {
|
|
2872
|
+
if (bucket.size === 0) return;
|
|
2873
|
+
this.reservedBuckets.delete(bucket.key);
|
|
2874
|
+
if (!this.slots.has(bucket.key)) this.slots.set(bucket.key, bucket);
|
|
2875
|
+
}
|
|
2876
|
+
releaseBucket(bucket) {
|
|
2877
|
+
if (bucket.size > 0) return;
|
|
2878
|
+
this.slots.delete(bucket.key);
|
|
2879
|
+
if (bucket.hasSubscribers()) {
|
|
2880
|
+
this.reservedBuckets.set(bucket.key, bucket);
|
|
2881
|
+
} else {
|
|
2882
|
+
this.reservedBuckets.delete(bucket.key);
|
|
2883
|
+
}
|
|
2884
|
+
}
|
|
2885
|
+
dropIfReserved(key) {
|
|
2886
|
+
const reserved = this.reservedBuckets.get(key);
|
|
2887
|
+
if (reserved && reserved.size === 0 && !reserved.hasSubscribers()) {
|
|
2888
|
+
this.reservedBuckets.delete(key);
|
|
2889
|
+
}
|
|
2890
|
+
}
|
|
2891
|
+
setOneByKey(key, slots) {
|
|
2892
|
+
const bucket = this.getOrReserveBucket(key);
|
|
2893
|
+
if (bucket !== slots) {
|
|
2894
|
+
bucket.clear();
|
|
2895
|
+
for (const slot of slots) bucket.add(slot);
|
|
2896
|
+
}
|
|
2897
|
+
if (bucket.size > 0) this.retainBucket(bucket);
|
|
2898
|
+
else this.releaseBucket(bucket);
|
|
2899
|
+
}
|
|
2900
|
+
removeOneByKey(key) {
|
|
2901
|
+
this.slots.delete(key);
|
|
2902
|
+
this.reservedBuckets.delete(key);
|
|
2903
|
+
}
|
|
2904
|
+
removeManyByKeys(keys) {
|
|
2905
|
+
for (let i = 0; i < keys.length; i++) {
|
|
2906
|
+
this.slots.delete(keys[i]);
|
|
2907
|
+
this.reservedBuckets.delete(keys[i]);
|
|
2908
|
+
}
|
|
2909
|
+
}
|
|
2910
|
+
getOneByKey(key) {
|
|
2911
|
+
return this.slots.get(key);
|
|
2912
|
+
}
|
|
2913
|
+
getManyByKeys(keys) {
|
|
2914
|
+
const result = /* @__PURE__ */ new Map();
|
|
2915
|
+
for (let i = 0; i < keys.length; i++) {
|
|
2916
|
+
const slots = this.slots.get(keys[i]);
|
|
2917
|
+
if (slots !== void 0) result.set(keys[i], slots);
|
|
2918
|
+
}
|
|
2919
|
+
return result;
|
|
2920
|
+
}
|
|
2921
|
+
getAllKeys() {
|
|
2922
|
+
return Array.from(this.slots.keys());
|
|
2923
|
+
}
|
|
2924
|
+
getAll() {
|
|
2925
|
+
const result = /* @__PURE__ */ new Map();
|
|
2926
|
+
for (const [path, bucket] of this.slots.entries()) {
|
|
2927
|
+
result.set(path, bucket);
|
|
2928
|
+
}
|
|
2929
|
+
return result;
|
|
2930
|
+
}
|
|
2931
|
+
countAll() {
|
|
2932
|
+
return this.slots.size;
|
|
2933
|
+
}
|
|
2934
|
+
clear() {
|
|
2935
|
+
for (const bucket of this.slots.values()) {
|
|
2936
|
+
bucket.clear();
|
|
2937
|
+
if (bucket.hasSubscribers()) {
|
|
2938
|
+
this.reservedBuckets.set(bucket.key, bucket);
|
|
2939
|
+
}
|
|
2940
|
+
}
|
|
2941
|
+
this.slots.clear();
|
|
2942
|
+
}
|
|
2943
|
+
};
|
|
2944
|
+
|
|
2945
|
+
// src/core/OIMReactiveCollectionIndexCompositeTrieSetBased.ts
|
|
2946
|
+
var OIMReactiveCollectionIndexCompositeTrieSetBased = class extends OIMReactiveIndexManualSetBased {
|
|
2947
|
+
constructor(queue, opts) {
|
|
2948
|
+
const resolveSlot = opts.collection !== void 0 ? (pk) => opts.collection.getOrReserveSlotByPk(pk) : opts.resolveSlot;
|
|
2949
|
+
super(queue, {
|
|
2950
|
+
indexOptions: {
|
|
2951
|
+
comparePks: opts.indexOptions?.comparePks,
|
|
2952
|
+
store: opts.indexOptions?.store ?? new OIMIndexStoreTrieDrivenSetBased()
|
|
2953
|
+
},
|
|
2954
|
+
pkDomain: opts.collection?.keyDomain
|
|
2955
|
+
});
|
|
2956
|
+
this.resolveRequiredSlot = (pk) => {
|
|
2957
|
+
const slot = this.resolveSlot(pk);
|
|
2958
|
+
if (!slot) return { pk, item: void 0 };
|
|
2959
|
+
return slot;
|
|
2960
|
+
};
|
|
2961
|
+
this.resolveSlot = resolveSlot;
|
|
2962
|
+
}
|
|
2963
|
+
setPks(key, pks) {
|
|
2964
|
+
this.index.setPks(key, pks, this.resolveRequiredSlot);
|
|
2965
|
+
}
|
|
2966
|
+
addPks(key, pks) {
|
|
2967
|
+
this.index.addPks(key, pks, this.resolveRequiredSlot);
|
|
2968
|
+
}
|
|
2969
|
+
removePks(key, pks) {
|
|
2970
|
+
this.index.removePks(key, pks);
|
|
2971
|
+
}
|
|
2972
|
+
getEntitiesByKey(key) {
|
|
2973
|
+
return super.getEntitiesByKey(key);
|
|
2974
|
+
}
|
|
2975
|
+
getEntitiesByKeys(keys) {
|
|
2976
|
+
return super.getEntitiesByKeys(keys);
|
|
2977
|
+
}
|
|
2978
|
+
};
|
|
2979
|
+
|
|
2980
|
+
// src/core/OIMIndexStoreTrieDrivenArrayBased.ts
|
|
2981
|
+
var OIMIndexStoreTrieDrivenArrayBased = class extends OIMIndexStoreArrayBased {
|
|
2982
|
+
constructor() {
|
|
2983
|
+
super(...arguments);
|
|
2984
|
+
this.slots = new OIMTrieMap();
|
|
2985
|
+
this.reservedBuckets = new OIMTrieMap();
|
|
2986
|
+
}
|
|
2987
|
+
getOrReserveBucket(key) {
|
|
2988
|
+
const live = this.slots.get(key);
|
|
2989
|
+
if (live) return live;
|
|
2990
|
+
let reserved = this.reservedBuckets.get(key);
|
|
2991
|
+
if (!reserved) {
|
|
2992
|
+
reserved = new OIMKeyedBucketArrayBased(key);
|
|
2993
|
+
this.reservedBuckets.set(key, reserved);
|
|
2994
|
+
}
|
|
2995
|
+
return reserved;
|
|
2996
|
+
}
|
|
2997
|
+
findBucket(key) {
|
|
2998
|
+
return this.slots.get(key) ?? this.reservedBuckets.get(key);
|
|
2999
|
+
}
|
|
3000
|
+
retainBucket(bucket) {
|
|
3001
|
+
if (bucket.length === 0) return;
|
|
3002
|
+
this.reservedBuckets.delete(bucket.key);
|
|
3003
|
+
if (!this.slots.has(bucket.key)) this.slots.set(bucket.key, bucket);
|
|
3004
|
+
}
|
|
3005
|
+
releaseBucket(bucket) {
|
|
3006
|
+
if (bucket.length > 0) return;
|
|
3007
|
+
this.slots.delete(bucket.key);
|
|
3008
|
+
if (bucket.hasSubscribers()) {
|
|
3009
|
+
this.reservedBuckets.set(bucket.key, bucket);
|
|
3010
|
+
} else {
|
|
3011
|
+
this.reservedBuckets.delete(bucket.key);
|
|
3012
|
+
}
|
|
3013
|
+
}
|
|
3014
|
+
dropIfReserved(key) {
|
|
3015
|
+
const reserved = this.reservedBuckets.get(key);
|
|
3016
|
+
if (reserved && reserved.length === 0 && !reserved.hasSubscribers()) {
|
|
3017
|
+
this.reservedBuckets.delete(key);
|
|
3018
|
+
}
|
|
3019
|
+
}
|
|
3020
|
+
setOneByKey(key, slots) {
|
|
3021
|
+
const bucket = this.getOrReserveBucket(key);
|
|
3022
|
+
if (bucket !== slots) {
|
|
3023
|
+
bucket.length = 0;
|
|
3024
|
+
for (let i = 0; i < slots.length; i++) bucket.push(slots[i]);
|
|
3025
|
+
}
|
|
3026
|
+
if (bucket.length > 0) this.retainBucket(bucket);
|
|
3027
|
+
else this.releaseBucket(bucket);
|
|
3028
|
+
}
|
|
3029
|
+
removeOneByKey(key) {
|
|
3030
|
+
this.slots.delete(key);
|
|
3031
|
+
this.reservedBuckets.delete(key);
|
|
3032
|
+
}
|
|
3033
|
+
removeManyByKeys(keys) {
|
|
3034
|
+
for (let i = 0; i < keys.length; i++) {
|
|
3035
|
+
this.slots.delete(keys[i]);
|
|
3036
|
+
this.reservedBuckets.delete(keys[i]);
|
|
3037
|
+
}
|
|
3038
|
+
}
|
|
3039
|
+
getOneByKey(key) {
|
|
3040
|
+
return this.slots.get(key);
|
|
3041
|
+
}
|
|
3042
|
+
getManyByKeys(keys) {
|
|
3043
|
+
const result = /* @__PURE__ */ new Map();
|
|
3044
|
+
for (let i = 0; i < keys.length; i++) {
|
|
3045
|
+
const slots = this.slots.get(keys[i]);
|
|
3046
|
+
if (slots !== void 0) result.set(keys[i], slots);
|
|
3047
|
+
}
|
|
3048
|
+
return result;
|
|
3049
|
+
}
|
|
3050
|
+
getAllKeys() {
|
|
3051
|
+
return Array.from(this.slots.keys());
|
|
3052
|
+
}
|
|
3053
|
+
getAll() {
|
|
3054
|
+
const result = /* @__PURE__ */ new Map();
|
|
3055
|
+
for (const [path, bucket] of this.slots.entries()) {
|
|
3056
|
+
result.set(path, bucket);
|
|
3057
|
+
}
|
|
3058
|
+
return result;
|
|
3059
|
+
}
|
|
3060
|
+
countAll() {
|
|
3061
|
+
return this.slots.size;
|
|
3062
|
+
}
|
|
3063
|
+
clear() {
|
|
3064
|
+
for (const bucket of this.slots.values()) {
|
|
3065
|
+
bucket.length = 0;
|
|
3066
|
+
if (bucket.hasSubscribers()) {
|
|
3067
|
+
this.reservedBuckets.set(bucket.key, bucket);
|
|
3068
|
+
}
|
|
3069
|
+
}
|
|
3070
|
+
this.slots.clear();
|
|
3071
|
+
}
|
|
3072
|
+
};
|
|
3073
|
+
|
|
3074
|
+
// src/core/OIMReactiveCollectionIndexCompositeTrieArrayBased.ts
|
|
3075
|
+
var OIMReactiveCollectionIndexCompositeTrieArrayBased = class extends OIMReactiveIndexManualArrayBased {
|
|
3076
|
+
constructor(queue, opts) {
|
|
3077
|
+
const resolveSlot = opts.collection !== void 0 ? (pk) => opts.collection.getOrReserveSlotByPk(pk) : opts.resolveSlot;
|
|
3078
|
+
super(queue, {
|
|
3079
|
+
indexOptions: {
|
|
3080
|
+
comparePks: opts.indexOptions?.comparePks,
|
|
3081
|
+
store: opts.indexOptions?.store ?? new OIMIndexStoreTrieDrivenArrayBased()
|
|
3082
|
+
}
|
|
3083
|
+
});
|
|
3084
|
+
// Persistent per-key-path pk membership for O(1) `addPks` dedup. Trie-keyed
|
|
3085
|
+
// so a rebuilt key path matches by content.
|
|
3086
|
+
this.pksByKey = new OIMTrieMap();
|
|
3087
|
+
this.resolveSlot = resolveSlot;
|
|
3088
|
+
}
|
|
3089
|
+
setPks(key, pks) {
|
|
3090
|
+
const pkSet = /* @__PURE__ */ new Set();
|
|
3091
|
+
for (let i = 0; i < pks.length; i++) pkSet.add(pks[i]);
|
|
3092
|
+
this.pksByKey.set(key, pkSet);
|
|
3093
|
+
super.setSlots(key, this.resolveSlots(pks));
|
|
3094
|
+
}
|
|
3095
|
+
addPks(key, pks) {
|
|
3096
|
+
if (pks.length === 0) return;
|
|
3097
|
+
const pkSet = this.membershipOf(key);
|
|
3098
|
+
const newSlots = [];
|
|
3099
|
+
for (const pk of pks) {
|
|
3100
|
+
if (pkSet.has(pk)) continue;
|
|
3101
|
+
pkSet.add(pk);
|
|
3102
|
+
newSlots.push(this.resolveRequiredSlot(pk));
|
|
3103
|
+
}
|
|
3104
|
+
if (newSlots.length > 0) this.appendSlots(key, newSlots);
|
|
3105
|
+
}
|
|
3106
|
+
removePks(key, pks) {
|
|
3107
|
+
if (pks.length === 0) return;
|
|
3108
|
+
const pksToRemove = new Set(pks);
|
|
3109
|
+
const existingSlots = this.index.getSlotsByKey(key);
|
|
3110
|
+
const nextSlots = existingSlots.filter(
|
|
3111
|
+
(slot) => !pksToRemove.has(slot.pk)
|
|
3112
|
+
);
|
|
3113
|
+
if (nextSlots.length === existingSlots.length) return;
|
|
3114
|
+
const pkSet = this.pksByKey.get(key);
|
|
3115
|
+
if (pkSet) {
|
|
3116
|
+
for (let i = 0; i < pks.length; i++) pkSet.delete(pks[i]);
|
|
3117
|
+
}
|
|
3118
|
+
if (nextSlots.length === 0) this.clear(key);
|
|
3119
|
+
else super.setSlots(key, nextSlots);
|
|
3120
|
+
}
|
|
3121
|
+
clear(key) {
|
|
3122
|
+
if (key === void 0) this.pksByKey.clear();
|
|
3123
|
+
else this.pksByKey.delete(key);
|
|
3124
|
+
super.clear(key);
|
|
3125
|
+
}
|
|
3126
|
+
/**
|
|
3127
|
+
* The membership set for a key path, lazily seeded from the current bucket so
|
|
3128
|
+
* it stays correct even if slots were set through a lower-level path.
|
|
3129
|
+
*/
|
|
3130
|
+
membershipOf(key) {
|
|
3131
|
+
let pkSet = this.pksByKey.get(key);
|
|
3132
|
+
if (!pkSet) {
|
|
3133
|
+
pkSet = /* @__PURE__ */ new Set();
|
|
3134
|
+
const existing = this.index.getSlotsByKey(key);
|
|
3135
|
+
for (let i = 0; i < existing.length; i++) {
|
|
3136
|
+
pkSet.add(existing[i].pk);
|
|
3137
|
+
}
|
|
3138
|
+
this.pksByKey.set(key, pkSet);
|
|
3139
|
+
}
|
|
3140
|
+
return pkSet;
|
|
3141
|
+
}
|
|
3142
|
+
getEntitiesByKey(key) {
|
|
3143
|
+
return super.getEntitiesByKey(key);
|
|
3144
|
+
}
|
|
3145
|
+
getEntitiesByKeys(keys) {
|
|
3146
|
+
return super.getEntitiesByKeys(keys);
|
|
3147
|
+
}
|
|
3148
|
+
resolveSlots(pks) {
|
|
3149
|
+
const slots = [];
|
|
3150
|
+
slots.length = pks.length;
|
|
3151
|
+
for (let i = 0; i < pks.length; i++) {
|
|
3152
|
+
slots[i] = this.resolveRequiredSlot(pks[i]);
|
|
3153
|
+
}
|
|
3154
|
+
return slots;
|
|
3155
|
+
}
|
|
3156
|
+
resolveRequiredSlot(pk) {
|
|
3157
|
+
const slot = this.resolveSlot(pk);
|
|
3158
|
+
if (!slot) return { pk, item: void 0 };
|
|
3159
|
+
return slot;
|
|
3160
|
+
}
|
|
3161
|
+
};
|
|
3162
|
+
|
|
3163
|
+
// src/core/OIMDerivedCollectionIndexSetBased.ts
|
|
3164
|
+
var OIMDerivedCollectionIndexSetBased = class extends OIMReactiveCollectionIndexManualSetBased {
|
|
3165
|
+
constructor(queue, collection, opts) {
|
|
3166
|
+
super(queue, {
|
|
3167
|
+
collection,
|
|
3168
|
+
indexOptions: opts.indexOptions
|
|
3169
|
+
});
|
|
3170
|
+
this.keysByPk = /* @__PURE__ */ new Map();
|
|
3171
|
+
this.onCollectionUpdate = (pks) => {
|
|
3172
|
+
if (pks.length === 0) {
|
|
3173
|
+
this.rebuildFromCollection();
|
|
3174
|
+
return;
|
|
3175
|
+
}
|
|
3176
|
+
for (const pk of pks) {
|
|
3177
|
+
this.syncPk(pk);
|
|
3178
|
+
}
|
|
3179
|
+
};
|
|
3180
|
+
this.collection = collection;
|
|
3181
|
+
this.selectIndexKeys = opts.selectIndexKeys;
|
|
3182
|
+
this.unsubscribeFromCollection = collection.emitter.on(
|
|
3183
|
+
0 /* UPDATE */,
|
|
3184
|
+
(payload) => this.onCollectionUpdate(payload.pks)
|
|
3185
|
+
);
|
|
3186
|
+
if (opts.buildInitial !== false) {
|
|
3187
|
+
this.rebuildFromCollection();
|
|
3188
|
+
}
|
|
3189
|
+
}
|
|
3190
|
+
rebuildFromCollection() {
|
|
3191
|
+
this.keysByPk.clear();
|
|
3192
|
+
super.clear();
|
|
3193
|
+
const slotsByKey = /* @__PURE__ */ new Map();
|
|
3194
|
+
const slots = this.collection.getAllSlots();
|
|
3195
|
+
for (const slot of slots) {
|
|
3196
|
+
if (slot.item === void 0) continue;
|
|
3197
|
+
const keys = this.normalizeKeys(this.selectIndexKeys(slot.item));
|
|
3198
|
+
if (keys.length === 0) continue;
|
|
3199
|
+
this.keysByPk.set(slot.pk, new Set(keys));
|
|
2542
3200
|
for (const key of keys) {
|
|
2543
3201
|
let slotsForKey = slotsByKey.get(key);
|
|
2544
3202
|
if (!slotsForKey) {
|
|
@@ -3194,8 +3852,32 @@ var OIMCollectionIndexFactory = class {
|
|
|
3194
3852
|
this.queue = queue;
|
|
3195
3853
|
this.collection = collection;
|
|
3196
3854
|
}
|
|
3197
|
-
setBasedIndex(opts = {}) {
|
|
3198
|
-
return new OIMReactiveCollectionIndexManualSetBased(this.queue, {
|
|
3855
|
+
setBasedIndex(opts = {}) {
|
|
3856
|
+
return new OIMReactiveCollectionIndexManualSetBased(this.queue, {
|
|
3857
|
+
collection: this.collection,
|
|
3858
|
+
indexOptions: opts.indexOptions
|
|
3859
|
+
});
|
|
3860
|
+
}
|
|
3861
|
+
/**
|
|
3862
|
+
* Composite (trie-backed) manual Set-based index keyed by an
|
|
3863
|
+
* arbitrary-length key path, e.g. `setPks([userId, projectId, role], pks)`.
|
|
3864
|
+
* Key paths are matched by content in O(arity) — no string concatenation,
|
|
3865
|
+
* no separator collisions, each segment keeps its type. Primitive-keyed
|
|
3866
|
+
* indexes are unaffected and keep their native-`Map` fast path.
|
|
3867
|
+
*/
|
|
3868
|
+
compositeSetIndex(opts = {}) {
|
|
3869
|
+
return new OIMReactiveCollectionIndexCompositeTrieSetBased(this.queue, {
|
|
3870
|
+
collection: this.collection,
|
|
3871
|
+
indexOptions: opts.indexOptions
|
|
3872
|
+
});
|
|
3873
|
+
}
|
|
3874
|
+
/**
|
|
3875
|
+
* Composite (trie-backed) manual Array-based (ordered) index keyed by an
|
|
3876
|
+
* arbitrary-length key path, e.g. `setPks([channelId, threadId], pks)`.
|
|
3877
|
+
* Ordered counterpart of `compositeSetIndex`.
|
|
3878
|
+
*/
|
|
3879
|
+
compositeArrayIndex(opts = {}) {
|
|
3880
|
+
return new OIMReactiveCollectionIndexCompositeTrieArrayBased(this.queue, {
|
|
3199
3881
|
collection: this.collection,
|
|
3200
3882
|
indexOptions: opts.indexOptions
|
|
3201
3883
|
});
|
|
@@ -3448,6 +4130,195 @@ var OIMReactiveObject = class extends OIMObject {
|
|
|
3448
4130
|
}
|
|
3449
4131
|
};
|
|
3450
4132
|
|
|
4133
|
+
// src/core/OIMTrieSet.ts
|
|
4134
|
+
var OIMTrieSet = class {
|
|
4135
|
+
constructor() {
|
|
4136
|
+
this.map = new OIMTrieMap();
|
|
4137
|
+
}
|
|
4138
|
+
get size() {
|
|
4139
|
+
return this.map.size;
|
|
4140
|
+
}
|
|
4141
|
+
add(key) {
|
|
4142
|
+
this.map.set(key, true);
|
|
4143
|
+
}
|
|
4144
|
+
has(key) {
|
|
4145
|
+
return this.map.has(key);
|
|
4146
|
+
}
|
|
4147
|
+
delete(key) {
|
|
4148
|
+
return this.map.delete(key);
|
|
4149
|
+
}
|
|
4150
|
+
*values() {
|
|
4151
|
+
yield* this.map.keys();
|
|
4152
|
+
}
|
|
4153
|
+
clear() {
|
|
4154
|
+
this.map.clear();
|
|
4155
|
+
}
|
|
4156
|
+
};
|
|
4157
|
+
|
|
4158
|
+
// src/core/OIMKeyDomainTrie.ts
|
|
4159
|
+
var OIMKeyDomainTrie = class {
|
|
4160
|
+
constructor() {
|
|
4161
|
+
// Interning pool: logical key (by content) → the one canonical reference.
|
|
4162
|
+
this.pool = new OIMTrieMap();
|
|
4163
|
+
}
|
|
4164
|
+
createMap() {
|
|
4165
|
+
return new OIMTrieMap();
|
|
4166
|
+
}
|
|
4167
|
+
createSet() {
|
|
4168
|
+
return new OIMTrieSet();
|
|
4169
|
+
}
|
|
4170
|
+
canonicalize(key) {
|
|
4171
|
+
const existing = this.pool.get(key);
|
|
4172
|
+
if (existing !== void 0) return existing;
|
|
4173
|
+
const canonical = Object.freeze(key.slice());
|
|
4174
|
+
this.pool.set(canonical, canonical);
|
|
4175
|
+
return canonical;
|
|
4176
|
+
}
|
|
4177
|
+
};
|
|
4178
|
+
|
|
4179
|
+
// src/core/OIMCollectionStoreTrieDriven.ts
|
|
4180
|
+
var OIMCollectionStoreTrieDriven = class extends OIMCollectionStore {
|
|
4181
|
+
constructor(keyDomain = new OIMKeyDomainTrie()) {
|
|
4182
|
+
super();
|
|
4183
|
+
this.keyDomain = keyDomain;
|
|
4184
|
+
this.slots = new OIMTrieMap();
|
|
4185
|
+
this.reservedSlots = new OIMTrieMap();
|
|
4186
|
+
}
|
|
4187
|
+
setOneByPk(pk, entity) {
|
|
4188
|
+
const slot = this.slots.get(pk);
|
|
4189
|
+
if (slot) {
|
|
4190
|
+
slot.item = entity;
|
|
4191
|
+
return slot;
|
|
4192
|
+
}
|
|
4193
|
+
const reserved = this.reservedSlots.get(pk);
|
|
4194
|
+
if (reserved) {
|
|
4195
|
+
reserved.item = entity;
|
|
4196
|
+
this.reservedSlots.delete(pk);
|
|
4197
|
+
this.slots.set(pk, reserved);
|
|
4198
|
+
return reserved;
|
|
4199
|
+
}
|
|
4200
|
+
const nextSlot = {
|
|
4201
|
+
pk: this.keyDomain.canonicalize(pk),
|
|
4202
|
+
item: entity
|
|
4203
|
+
};
|
|
4204
|
+
this.slots.set(pk, nextSlot);
|
|
4205
|
+
return nextSlot;
|
|
4206
|
+
}
|
|
4207
|
+
getOrReserveSlotByPk(pk) {
|
|
4208
|
+
const slot = this.slots.get(pk);
|
|
4209
|
+
if (slot) return slot;
|
|
4210
|
+
let reserved = this.reservedSlots.get(pk);
|
|
4211
|
+
if (!reserved) {
|
|
4212
|
+
reserved = { pk: this.keyDomain.canonicalize(pk), item: void 0 };
|
|
4213
|
+
this.reservedSlots.set(pk, reserved);
|
|
4214
|
+
}
|
|
4215
|
+
return reserved;
|
|
4216
|
+
}
|
|
4217
|
+
setManyByPks(pks, entities) {
|
|
4218
|
+
const slots = [];
|
|
4219
|
+
slots.length = pks.length;
|
|
4220
|
+
for (let i = 0; i < pks.length; i++) {
|
|
4221
|
+
slots[i] = this.setOneByPk(pks[i], entities[i]);
|
|
4222
|
+
}
|
|
4223
|
+
return slots;
|
|
4224
|
+
}
|
|
4225
|
+
getSlotByPk(pk) {
|
|
4226
|
+
return this.slots.get(pk);
|
|
4227
|
+
}
|
|
4228
|
+
findSlotByPk(pk) {
|
|
4229
|
+
return this.slots.get(pk) ?? this.reservedSlots.get(pk);
|
|
4230
|
+
}
|
|
4231
|
+
hasSubscribers(slot) {
|
|
4232
|
+
return slot.subscribers !== void 0 && slot.subscribers.size > 0;
|
|
4233
|
+
}
|
|
4234
|
+
getSlotsByPks(pks) {
|
|
4235
|
+
const result = [];
|
|
4236
|
+
result.length = pks.length;
|
|
4237
|
+
let writeIndex = 0;
|
|
4238
|
+
for (let i = 0; i < pks.length; i++) {
|
|
4239
|
+
const slot = this.slots.get(pks[i]);
|
|
4240
|
+
if (slot !== void 0) result[writeIndex++] = slot;
|
|
4241
|
+
}
|
|
4242
|
+
result.length = writeIndex;
|
|
4243
|
+
return result;
|
|
4244
|
+
}
|
|
4245
|
+
getAllSlots() {
|
|
4246
|
+
return Array.from(this.slots.values());
|
|
4247
|
+
}
|
|
4248
|
+
removeOneByPk(pk) {
|
|
4249
|
+
const slot = this.slots.get(pk);
|
|
4250
|
+
if (slot) {
|
|
4251
|
+
slot.item = void 0;
|
|
4252
|
+
this.slots.delete(pk);
|
|
4253
|
+
if (this.hasSubscribers(slot)) {
|
|
4254
|
+
this.reservedSlots.set(pk, slot);
|
|
4255
|
+
}
|
|
4256
|
+
return;
|
|
4257
|
+
}
|
|
4258
|
+
const reserved = this.reservedSlots.get(pk);
|
|
4259
|
+
if (reserved) {
|
|
4260
|
+
reserved.item = void 0;
|
|
4261
|
+
if (!this.hasSubscribers(reserved)) {
|
|
4262
|
+
this.reservedSlots.delete(pk);
|
|
4263
|
+
}
|
|
4264
|
+
}
|
|
4265
|
+
}
|
|
4266
|
+
removeManyByPks(pks) {
|
|
4267
|
+
for (const pk of pks) this.removeOneByPk(pk);
|
|
4268
|
+
}
|
|
4269
|
+
getOneByPk(pk) {
|
|
4270
|
+
return this.slots.get(pk)?.item;
|
|
4271
|
+
}
|
|
4272
|
+
getManyByPks(pks) {
|
|
4273
|
+
const result = [];
|
|
4274
|
+
result.length = pks.length;
|
|
4275
|
+
let writeIndex = 0;
|
|
4276
|
+
for (let i = 0; i < pks.length; i++) {
|
|
4277
|
+
const entity = this.getOneByPk(pks[i]);
|
|
4278
|
+
if (entity !== void 0) result[writeIndex++] = entity;
|
|
4279
|
+
}
|
|
4280
|
+
result.length = writeIndex;
|
|
4281
|
+
return result;
|
|
4282
|
+
}
|
|
4283
|
+
getAll() {
|
|
4284
|
+
const result = [];
|
|
4285
|
+
for (const slot of this.slots.values()) {
|
|
4286
|
+
if (slot.item !== void 0) result.push(slot.item);
|
|
4287
|
+
}
|
|
4288
|
+
return result;
|
|
4289
|
+
}
|
|
4290
|
+
countAll() {
|
|
4291
|
+
return this.slots.size;
|
|
4292
|
+
}
|
|
4293
|
+
clear() {
|
|
4294
|
+
const retained = [];
|
|
4295
|
+
for (const slot of this.slots.values()) {
|
|
4296
|
+
slot.item = void 0;
|
|
4297
|
+
if (this.hasSubscribers(slot)) retained.push(slot);
|
|
4298
|
+
}
|
|
4299
|
+
this.slots.clear();
|
|
4300
|
+
for (const slot of this.reservedSlots.values()) {
|
|
4301
|
+
slot.item = void 0;
|
|
4302
|
+
if (this.hasSubscribers(slot)) retained.push(slot);
|
|
4303
|
+
}
|
|
4304
|
+
this.reservedSlots.clear();
|
|
4305
|
+
for (const slot of retained) {
|
|
4306
|
+
this.reservedSlots.set(slot.pk, slot);
|
|
4307
|
+
}
|
|
4308
|
+
}
|
|
4309
|
+
getAllPks() {
|
|
4310
|
+
return Array.from(this.slots.keys());
|
|
4311
|
+
}
|
|
4312
|
+
destroy() {
|
|
4313
|
+
this.clear();
|
|
4314
|
+
for (const slot of this.reservedSlots.values()) {
|
|
4315
|
+
slot.subscribers?.clear();
|
|
4316
|
+
slot.subscribers = void 0;
|
|
4317
|
+
}
|
|
4318
|
+
this.reservedSlots.clear();
|
|
4319
|
+
}
|
|
4320
|
+
};
|
|
4321
|
+
|
|
3451
4322
|
// src/core/OIMObjectStoreMapDriven.ts
|
|
3452
4323
|
var OIMObjectStoreMapDriven = class extends OIMObjectStore {
|
|
3453
4324
|
constructor() {
|
|
@@ -3495,6 +4366,27 @@ var OIMObjectStoreMapDriven = class extends OIMObjectStore {
|
|
|
3495
4366
|
}
|
|
3496
4367
|
};
|
|
3497
4368
|
|
|
4369
|
+
// src/core/OIMKeyPathCarrierResolver.ts
|
|
4370
|
+
var OIMKeyPathCarrierResolver = class {
|
|
4371
|
+
constructor() {
|
|
4372
|
+
this.carriers = new OIMTrieMap();
|
|
4373
|
+
}
|
|
4374
|
+
getOrReserveCarrier(key) {
|
|
4375
|
+
let carrier = this.carriers.get(key);
|
|
4376
|
+
if (!carrier) {
|
|
4377
|
+
carrier = { key };
|
|
4378
|
+
this.carriers.set(key, carrier);
|
|
4379
|
+
}
|
|
4380
|
+
return carrier;
|
|
4381
|
+
}
|
|
4382
|
+
findCarrier(key) {
|
|
4383
|
+
return this.carriers.get(key);
|
|
4384
|
+
}
|
|
4385
|
+
onCarrierEmptied(carrier) {
|
|
4386
|
+
this.carriers.delete(carrier.key);
|
|
4387
|
+
}
|
|
4388
|
+
};
|
|
4389
|
+
|
|
3498
4390
|
// src/core/OIMComparatorFactory.ts
|
|
3499
4391
|
var OIMComparatorFactory = class {
|
|
3500
4392
|
createShallowComparator() {
|
|
@@ -3713,6 +4605,78 @@ var OIMMap2Keys = class {
|
|
|
3713
4605
|
}
|
|
3714
4606
|
};
|
|
3715
4607
|
|
|
4608
|
+
// src/core/OIMDisposeScope.ts
|
|
4609
|
+
var OIMDisposeScope = class _OIMDisposeScope {
|
|
4610
|
+
constructor() {
|
|
4611
|
+
this.disposables = [];
|
|
4612
|
+
this.disposed = false;
|
|
4613
|
+
}
|
|
4614
|
+
/** Number of not-yet-disposed items currently held. */
|
|
4615
|
+
get size() {
|
|
4616
|
+
return this.disposables.length;
|
|
4617
|
+
}
|
|
4618
|
+
get isDisposed() {
|
|
4619
|
+
return this.disposed;
|
|
4620
|
+
}
|
|
4621
|
+
/**
|
|
4622
|
+
* Register a disposable (object with `destroy()` or an unsubscribe function)
|
|
4623
|
+
* and return it unchanged, so it can be captured inline. If the scope is
|
|
4624
|
+
* already disposed the item is disposed immediately, so nothing leaks.
|
|
4625
|
+
*/
|
|
4626
|
+
add(disposable) {
|
|
4627
|
+
if (this.disposed) {
|
|
4628
|
+
this.disposeOne(disposable);
|
|
4629
|
+
return disposable;
|
|
4630
|
+
}
|
|
4631
|
+
this.disposables.push(disposable);
|
|
4632
|
+
return disposable;
|
|
4633
|
+
}
|
|
4634
|
+
/** A nested scope, itself registered here — dispose it early or with the parent. */
|
|
4635
|
+
child() {
|
|
4636
|
+
return this.add(new _OIMDisposeScope());
|
|
4637
|
+
}
|
|
4638
|
+
/**
|
|
4639
|
+
* Dispose everything in reverse registration order, then clear. Idempotent.
|
|
4640
|
+
* If any `destroy()`/unsubscribe throws, the rest are still disposed and the
|
|
4641
|
+
* first error is rethrown once teardown completes.
|
|
4642
|
+
*/
|
|
4643
|
+
destroy() {
|
|
4644
|
+
if (this.disposed) return;
|
|
4645
|
+
this.disposed = true;
|
|
4646
|
+
let firstError;
|
|
4647
|
+
let hasError = false;
|
|
4648
|
+
for (let i = this.disposables.length - 1; i >= 0; i--) {
|
|
4649
|
+
try {
|
|
4650
|
+
this.disposeOne(this.disposables[i]);
|
|
4651
|
+
} catch (error) {
|
|
4652
|
+
if (!hasError) {
|
|
4653
|
+
hasError = true;
|
|
4654
|
+
firstError = error;
|
|
4655
|
+
}
|
|
4656
|
+
}
|
|
4657
|
+
}
|
|
4658
|
+
this.disposables.length = 0;
|
|
4659
|
+
if (hasError) throw firstError;
|
|
4660
|
+
}
|
|
4661
|
+
disposeOne(disposable) {
|
|
4662
|
+
if (typeof disposable === "function") disposable();
|
|
4663
|
+
else disposable.destroy();
|
|
4664
|
+
}
|
|
4665
|
+
};
|
|
4666
|
+
function createOIMDisposeScope() {
|
|
4667
|
+
return new OIMDisposeScope();
|
|
4668
|
+
}
|
|
4669
|
+
|
|
4670
|
+
// src/core/OIMPkCodecKeyPath.ts
|
|
4671
|
+
var OIMPkCodecKeyPath = class {
|
|
4672
|
+
encode(pk) {
|
|
4673
|
+
return JSON.stringify(pk);
|
|
4674
|
+
}
|
|
4675
|
+
decode(encoded) {
|
|
4676
|
+
return JSON.parse(encoded);
|
|
4677
|
+
}
|
|
4678
|
+
};
|
|
4679
|
+
|
|
3716
4680
|
// src/modules/compute/core/OIMComputeRuntime.ts
|
|
3717
4681
|
var OIMComputeRuntime = class {
|
|
3718
4682
|
constructor(queue) {
|
|
@@ -4316,6 +5280,27 @@ var OIMCollectionSelectors = class {
|
|
|
4316
5280
|
key
|
|
4317
5281
|
);
|
|
4318
5282
|
}
|
|
5283
|
+
/**
|
|
5284
|
+
* Entities of a composite (key-path) set-based index for one key path, e.g.
|
|
5285
|
+
* `entitiesByCompositeSetIndexKey(index, [projectId, role])`.
|
|
5286
|
+
*/
|
|
5287
|
+
entitiesByCompositeSetIndexKey(index, key) {
|
|
5288
|
+
return new OIMEntitiesByIndexKeySetBasedSelector(
|
|
5289
|
+
this.runtime,
|
|
5290
|
+
this.collection,
|
|
5291
|
+
index,
|
|
5292
|
+
key
|
|
5293
|
+
);
|
|
5294
|
+
}
|
|
5295
|
+
/** Entities of a composite (key-path) array-based index for one key path. */
|
|
5296
|
+
entitiesByCompositeArrayIndexKey(index, key) {
|
|
5297
|
+
return new OIMEntitiesByIndexKeyArrayBasedSelector(
|
|
5298
|
+
this.runtime,
|
|
5299
|
+
this.collection,
|
|
5300
|
+
index,
|
|
5301
|
+
key
|
|
5302
|
+
);
|
|
5303
|
+
}
|
|
4319
5304
|
/** Entities of a keyless (whole-collection) array-based index, ordered. */
|
|
4320
5305
|
entitiesByArrayGlobalIndex(index) {
|
|
4321
5306
|
return new OIMEntitiesByGlobalIndexArrayBasedSelector(
|
|
@@ -4339,7 +5324,16 @@ function createOIMCollectionKit(queue, opts) {
|
|
|
4339
5324
|
const collection = new OIMReactiveCollection(queue, opts);
|
|
4340
5325
|
const indexFactory = new OIMCollectionIndexFactory(queue, collection);
|
|
4341
5326
|
const select = new OIMCollectionSelectors(queue, collection);
|
|
4342
|
-
|
|
5327
|
+
const scope = new OIMDisposeScope();
|
|
5328
|
+
scope.add(collection);
|
|
5329
|
+
return {
|
|
5330
|
+
queue,
|
|
5331
|
+
collection,
|
|
5332
|
+
indexFactory,
|
|
5333
|
+
select,
|
|
5334
|
+
scope,
|
|
5335
|
+
destroy: () => scope.destroy()
|
|
5336
|
+
};
|
|
4343
5337
|
}
|
|
4344
5338
|
|
|
4345
5339
|
// src/modules/wrapper/collection/OIMCollectionChangedFields.ts
|
|
@@ -4726,6 +5720,56 @@ function createOIMIndexSlotMap(index, create) {
|
|
|
4726
5720
|
return new OIMIndexSlotMap(index, create);
|
|
4727
5721
|
}
|
|
4728
5722
|
|
|
5723
|
+
// src/modules/wrapper/index/OIMGlobalIndexSlotMap.ts
|
|
5724
|
+
var OIMGlobalIndexSlotMap = class _OIMGlobalIndexSlotMap {
|
|
5725
|
+
constructor(index, create) {
|
|
5726
|
+
this.cache = /* @__PURE__ */ new WeakMap();
|
|
5727
|
+
this.index = index;
|
|
5728
|
+
this.create = create;
|
|
5729
|
+
}
|
|
5730
|
+
/** The mapped object for a slot, created once and cached by slot identity. */
|
|
5731
|
+
get(slot) {
|
|
5732
|
+
let mapped = this.cache.get(slot);
|
|
5733
|
+
if (mapped === void 0 && !this.cache.has(slot)) {
|
|
5734
|
+
mapped = this.create(slot);
|
|
5735
|
+
this.cache.set(slot, mapped);
|
|
5736
|
+
}
|
|
5737
|
+
return mapped;
|
|
5738
|
+
}
|
|
5739
|
+
/**
|
|
5740
|
+
* Mapped objects for every slot in the index, with stable references. For a
|
|
5741
|
+
* set-based global index the order is unspecified (as the set is); for an
|
|
5742
|
+
* array-based one it follows the index order.
|
|
5743
|
+
*/
|
|
5744
|
+
getAll() {
|
|
5745
|
+
const result = [];
|
|
5746
|
+
for (const slot of this.index.getSlots()) {
|
|
5747
|
+
result.push(this.get(slot));
|
|
5748
|
+
}
|
|
5749
|
+
return result;
|
|
5750
|
+
}
|
|
5751
|
+
/**
|
|
5752
|
+
* Chain another projection. `map(f)` returns a slot map over the SAME index
|
|
5753
|
+
* whose objects are `f(this.get(slot))`, cached by slot identity — both
|
|
5754
|
+
* levels hand back stable references and each `create` runs once per slot.
|
|
5755
|
+
*/
|
|
5756
|
+
map(create) {
|
|
5757
|
+
return new _OIMGlobalIndexSlotMap(
|
|
5758
|
+
this.index,
|
|
5759
|
+
(slot) => create(this.get(slot))
|
|
5760
|
+
);
|
|
5761
|
+
}
|
|
5762
|
+
/** Subscribe to the index's changes — passthrough to the index. */
|
|
5763
|
+
subscribe(handler) {
|
|
5764
|
+
return this.index.subscribe(handler);
|
|
5765
|
+
}
|
|
5766
|
+
};
|
|
5767
|
+
|
|
5768
|
+
// src/modules/wrapper/index/createOIMGlobalIndexSlotMap.ts
|
|
5769
|
+
function createOIMGlobalIndexSlotMap(index, create) {
|
|
5770
|
+
return new OIMGlobalIndexSlotMap(index, create);
|
|
5771
|
+
}
|
|
5772
|
+
|
|
4729
5773
|
// src/modules/wrapper/index/diffOrderedListByPk.ts
|
|
4730
5774
|
function diffOrderedListByPk(prev, next) {
|
|
4731
5775
|
const commands = [];
|
|
@@ -5478,6 +6522,7 @@ var OIMIndexPksByKeysArrayBasedSelector = class extends OIMSelector {
|
|
|
5478
6522
|
EOIMEventQueueSchedulerEventType,
|
|
5479
6523
|
EOIMIndexEventType,
|
|
5480
6524
|
EOIMObjectEventType,
|
|
6525
|
+
OIMBucketCarrierResolver,
|
|
5481
6526
|
OIMCarrierKeyedEmitter,
|
|
5482
6527
|
OIMCarrierSingleEmitter,
|
|
5483
6528
|
OIMCollection,
|
|
@@ -5490,6 +6535,7 @@ var OIMIndexPksByKeysArrayBasedSelector = class extends OIMSelector {
|
|
|
5490
6535
|
OIMCollectionSelectors,
|
|
5491
6536
|
OIMCollectionStore,
|
|
5492
6537
|
OIMCollectionStoreMapDriven,
|
|
6538
|
+
OIMCollectionStoreTrieDriven,
|
|
5493
6539
|
OIMComparatorFactory,
|
|
5494
6540
|
OIMComputeRuntime,
|
|
5495
6541
|
OIMComputed,
|
|
@@ -5498,6 +6544,7 @@ var OIMIndexPksByKeysArrayBasedSelector = class extends OIMSelector {
|
|
|
5498
6544
|
OIMDerivedCollectionGlobalIndexSetBased,
|
|
5499
6545
|
OIMDerivedCollectionIndexArrayBased,
|
|
5500
6546
|
OIMDerivedCollectionIndexSetBased,
|
|
6547
|
+
OIMDisposeScope,
|
|
5501
6548
|
OIMEffect,
|
|
5502
6549
|
OIMEffectDependencyComputed,
|
|
5503
6550
|
OIMEffectDependencyKeyed,
|
|
@@ -5523,6 +6570,7 @@ var OIMIndexPksByKeysArrayBasedSelector = class extends OIMSelector {
|
|
|
5523
6570
|
OIMGlobalIndexManualArrayBased,
|
|
5524
6571
|
OIMGlobalIndexManualSetBased,
|
|
5525
6572
|
OIMGlobalIndexSetBased,
|
|
6573
|
+
OIMGlobalIndexSlotMap,
|
|
5526
6574
|
OIMIndex,
|
|
5527
6575
|
OIMIndexArrayBased,
|
|
5528
6576
|
OIMIndexComparatorFactory,
|
|
@@ -5539,6 +6587,13 @@ var OIMIndexPksByKeysArrayBasedSelector = class extends OIMSelector {
|
|
|
5539
6587
|
OIMIndexStoreMapDrivenArrayBased,
|
|
5540
6588
|
OIMIndexStoreMapDrivenSetBased,
|
|
5541
6589
|
OIMIndexStoreSetBased,
|
|
6590
|
+
OIMIndexStoreTrieDrivenArrayBased,
|
|
6591
|
+
OIMIndexStoreTrieDrivenSetBased,
|
|
6592
|
+
OIMKeyDomainNative,
|
|
6593
|
+
OIMKeyDomainTrie,
|
|
6594
|
+
OIMKeyPathCarrierResolver,
|
|
6595
|
+
OIMKeyedBucketArrayBased,
|
|
6596
|
+
OIMKeyedBucketSetBased,
|
|
5542
6597
|
OIMMap2Keys,
|
|
5543
6598
|
OIMObject,
|
|
5544
6599
|
OIMObjectStore,
|
|
@@ -5550,10 +6605,13 @@ var OIMIndexPksByKeysArrayBasedSelector = class extends OIMSelector {
|
|
|
5550
6605
|
OIMOrderedListCommandStream,
|
|
5551
6606
|
OIMOrderedListCommandStreamDiffDriven,
|
|
5552
6607
|
OIMOrderedListMappedCommandStream,
|
|
6608
|
+
OIMPkCodecKeyPath,
|
|
5553
6609
|
OIMPkSelectorFactory,
|
|
5554
6610
|
OIMReactiveCollection,
|
|
5555
6611
|
OIMReactiveCollectionGlobalIndexManualArrayBased,
|
|
5556
6612
|
OIMReactiveCollectionGlobalIndexManualSetBased,
|
|
6613
|
+
OIMReactiveCollectionIndexCompositeTrieArrayBased,
|
|
6614
|
+
OIMReactiveCollectionIndexCompositeTrieSetBased,
|
|
5557
6615
|
OIMReactiveCollectionIndexManualArrayBased,
|
|
5558
6616
|
OIMReactiveCollectionIndexManualSetBased,
|
|
5559
6617
|
OIMReactiveGlobalIndex,
|
|
@@ -5568,10 +6626,14 @@ var OIMIndexPksByKeysArrayBasedSelector = class extends OIMSelector {
|
|
|
5568
6626
|
OIMReactiveIndexSetBased,
|
|
5569
6627
|
OIMReactiveObject,
|
|
5570
6628
|
OIMSelector,
|
|
6629
|
+
OIMTrieMap,
|
|
6630
|
+
OIMTrieSet,
|
|
5571
6631
|
createInPlaceEntityUpdater,
|
|
5572
6632
|
createMergeEntityUpdater,
|
|
5573
6633
|
createOIMCollectionIndexFactory,
|
|
5574
6634
|
createOIMCollectionKit,
|
|
6635
|
+
createOIMDisposeScope,
|
|
6636
|
+
createOIMGlobalIndexSlotMap,
|
|
5575
6637
|
createOIMIndexSlotMap,
|
|
5576
6638
|
createOIMOrderedListCommandStreamDiffDriven,
|
|
5577
6639
|
createOIMOrderedListMappedCommandStream,
|