@oimdb/core 1.4.0 → 1.4.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 +369 -50
- package/dist/index.cjs +1409 -712
- package/dist/index.d.cts +387 -273
- package/dist/index.d.ts +387 -273
- package/dist/index.js +1397 -703
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -22,17 +22,18 @@ var index_exports = {};
|
|
|
22
22
|
__export(index_exports, {
|
|
23
23
|
EOIMCollectionEventType: () => EOIMCollectionEventType,
|
|
24
24
|
EOIMComputedEventType: () => EOIMComputedEventType,
|
|
25
|
-
EOIMEffectPhase: () => EOIMEffectPhase,
|
|
26
25
|
EOIMEventQueueEventType: () => EOIMEventQueueEventType,
|
|
27
26
|
EOIMEventQueueSchedulerEventType: () => EOIMEventQueueSchedulerEventType,
|
|
28
27
|
EOIMIndexEventType: () => EOIMIndexEventType,
|
|
29
28
|
EOIMObjectEventType: () => EOIMObjectEventType,
|
|
30
|
-
EOIMUpdateEventCoalescerEventType: () => EOIMUpdateEventCoalescerEventType,
|
|
31
29
|
OIMCollection: () => OIMCollection,
|
|
30
|
+
OIMCollectionByPkSelector: () => OIMCollectionByPkSelector,
|
|
31
|
+
OIMCollectionByPksSelector: () => OIMCollectionByPksSelector,
|
|
32
32
|
OIMCollectionChangedFieldsWrapper: () => OIMCollectionChangedFieldsWrapper,
|
|
33
33
|
OIMCollectionStore: () => OIMCollectionStore,
|
|
34
34
|
OIMCollectionStoreMapDriven: () => OIMCollectionStoreMapDriven,
|
|
35
35
|
OIMComparatorFactory: () => OIMComparatorFactory,
|
|
36
|
+
OIMComputativeRuntime: () => OIMComputativeRuntime,
|
|
36
37
|
OIMComputed: () => OIMComputed,
|
|
37
38
|
OIMDBSettings: () => OIMDBSettings,
|
|
38
39
|
OIMEffect: () => OIMEffect,
|
|
@@ -41,6 +42,8 @@ __export(index_exports, {
|
|
|
41
42
|
OIMEffectDependencyKeyedCollection: () => OIMEffectDependencyKeyedCollection,
|
|
42
43
|
OIMEffectDependencyKeyedIndex: () => OIMEffectDependencyKeyedIndex,
|
|
43
44
|
OIMEffectDependencyKeyedObject: () => OIMEffectDependencyKeyedObject,
|
|
45
|
+
OIMEntitiesByIndexKeyArrayBasedSelector: () => OIMEntitiesByIndexKeyArrayBasedSelector,
|
|
46
|
+
OIMEntitiesByIndexKeySetBasedSelector: () => OIMEntitiesByIndexKeySetBasedSelector,
|
|
44
47
|
OIMEntityUpdaterFactory: () => OIMEntityUpdaterFactory,
|
|
45
48
|
OIMEventEmitter: () => OIMEventEmitter,
|
|
46
49
|
OIMEventQueue: () => OIMEventQueue,
|
|
@@ -55,6 +58,10 @@ __export(index_exports, {
|
|
|
55
58
|
OIMIndexManualArrayBased: () => OIMIndexManualArrayBased,
|
|
56
59
|
OIMIndexManualOrderedArrayBased: () => OIMIndexManualOrderedArrayBased,
|
|
57
60
|
OIMIndexManualSetBased: () => OIMIndexManualSetBased,
|
|
61
|
+
OIMIndexPksByKeyArrayBasedSelector: () => OIMIndexPksByKeyArrayBasedSelector,
|
|
62
|
+
OIMIndexPksByKeySetBasedSelector: () => OIMIndexPksByKeySetBasedSelector,
|
|
63
|
+
OIMIndexPksByKeysArrayBasedSelector: () => OIMIndexPksByKeysArrayBasedSelector,
|
|
64
|
+
OIMIndexPksByKeysSetBasedSelector: () => OIMIndexPksByKeysSetBasedSelector,
|
|
58
65
|
OIMIndexSetBased: () => OIMIndexSetBased,
|
|
59
66
|
OIMIndexStoreArrayBased: () => OIMIndexStoreArrayBased,
|
|
60
67
|
OIMIndexStoreMapDrivenArrayBased: () => OIMIndexStoreMapDrivenArrayBased,
|
|
@@ -65,6 +72,8 @@ __export(index_exports, {
|
|
|
65
72
|
OIMObjectStore: () => OIMObjectStore,
|
|
66
73
|
OIMObjectStoreMapDriven: () => OIMObjectStoreMapDriven,
|
|
67
74
|
OIMObjectStoreRecordDriven: () => OIMObjectStoreRecordDriven,
|
|
75
|
+
OIMObjectValueByKeySelector: () => OIMObjectValueByKeySelector,
|
|
76
|
+
OIMObjectValuesByKeysSelector: () => OIMObjectValuesByKeysSelector,
|
|
68
77
|
OIMOrderedListIndexCommandStreamWrapper: () => OIMOrderedListIndexCommandStreamWrapper,
|
|
69
78
|
OIMPkSelectorFactory: () => OIMPkSelectorFactory,
|
|
70
79
|
OIMRICollection: () => OIMRICollection,
|
|
@@ -74,13 +83,7 @@ __export(index_exports, {
|
|
|
74
83
|
OIMReactiveIndexManualSetBased: () => OIMReactiveIndexManualSetBased,
|
|
75
84
|
OIMReactiveIndexSetBased: () => OIMReactiveIndexSetBased,
|
|
76
85
|
OIMReactiveObject: () => OIMReactiveObject,
|
|
77
|
-
|
|
78
|
-
OIMUpdateEventCoalescerCollection: () => OIMUpdateEventCoalescerCollection,
|
|
79
|
-
OIMUpdateEventCoalescerComputed: () => OIMUpdateEventCoalescerComputed,
|
|
80
|
-
OIMUpdateEventCoalescerIndex: () => OIMUpdateEventCoalescerIndex,
|
|
81
|
-
OIMUpdateEventCoalescerManual: () => OIMUpdateEventCoalescerManual,
|
|
82
|
-
OIMUpdateEventCoalescerObject: () => OIMUpdateEventCoalescerObject,
|
|
83
|
-
OIMUpdateEventEmitter: () => OIMUpdateEventEmitter
|
|
86
|
+
OIMSelector: () => OIMSelector
|
|
84
87
|
});
|
|
85
88
|
module.exports = __toCommonJS(index_exports);
|
|
86
89
|
|
|
@@ -101,6 +104,11 @@ var OIMEventEmitter = class {
|
|
|
101
104
|
constructor() {
|
|
102
105
|
this.buckets = {};
|
|
103
106
|
}
|
|
107
|
+
hasHandlers(event) {
|
|
108
|
+
const bucket = this.buckets[event];
|
|
109
|
+
if (!bucket) return false;
|
|
110
|
+
return bucket.indexByHandler.size > 0;
|
|
111
|
+
}
|
|
104
112
|
getOrCreateBucket(event) {
|
|
105
113
|
let bucket = this.buckets[event];
|
|
106
114
|
if (!bucket) {
|
|
@@ -383,6 +391,12 @@ var OIMIndexSetBased = class {
|
|
|
383
391
|
emitUpdate(keys) {
|
|
384
392
|
this.emitter.emit(0 /* UPDATE */, { keys });
|
|
385
393
|
}
|
|
394
|
+
/**
|
|
395
|
+
* Emit update event for a single key (fast-path override point).
|
|
396
|
+
*/
|
|
397
|
+
emitUpdateOne(key) {
|
|
398
|
+
this.emitUpdate([key]);
|
|
399
|
+
}
|
|
386
400
|
};
|
|
387
401
|
|
|
388
402
|
// src/core/OIMIndexStoreMapDrivenArrayBased.ts
|
|
@@ -532,45 +546,34 @@ var OIMIndexArrayBased = class {
|
|
|
532
546
|
emitUpdate(keys) {
|
|
533
547
|
this.emitter.emit(0 /* UPDATE */, { keys });
|
|
534
548
|
}
|
|
549
|
+
/**
|
|
550
|
+
* Emit update event for a single key (fast-path override point).
|
|
551
|
+
*/
|
|
552
|
+
emitUpdateOne(key) {
|
|
553
|
+
this.emitUpdate([key]);
|
|
554
|
+
}
|
|
535
555
|
};
|
|
536
556
|
|
|
537
|
-
// src/enum/
|
|
538
|
-
var
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
})(EOIMUpdateEventCoalescerEventType || {});
|
|
557
|
+
// src/enum/EOIMEventQueueEventType.ts
|
|
558
|
+
var EOIMEventQueueEventType = /* @__PURE__ */ ((EOIMEventQueueEventType2) => {
|
|
559
|
+
EOIMEventQueueEventType2[EOIMEventQueueEventType2["AFTER_FLUSH"] = 0] = "AFTER_FLUSH";
|
|
560
|
+
EOIMEventQueueEventType2[EOIMEventQueueEventType2["BEFORE_FLUSH"] = 1] = "BEFORE_FLUSH";
|
|
561
|
+
return EOIMEventQueueEventType2;
|
|
562
|
+
})(EOIMEventQueueEventType || {});
|
|
544
563
|
|
|
545
564
|
// src/core/OIMUpdateEventEmitter.ts
|
|
546
565
|
var OIMUpdateEventEmitter = class {
|
|
547
|
-
constructor(
|
|
548
|
-
this.keyHandlersBeforeFlush = /* @__PURE__ */ new Map();
|
|
566
|
+
constructor(queue, deliveryMode = "queue") {
|
|
549
567
|
this.keyHandlers = /* @__PURE__ */ new Map();
|
|
550
|
-
this.isDestroyed = false;
|
|
551
|
-
this.isDispatching = false;
|
|
552
|
-
this.isInPrePhase = false;
|
|
553
|
-
this.hasPendingDuringPrePhase = false;
|
|
554
568
|
this.isFlushEnqueued = false;
|
|
555
|
-
this.
|
|
556
|
-
|
|
557
|
-
this.hasPendingDuringPrePhase = true;
|
|
558
|
-
return;
|
|
559
|
-
}
|
|
560
|
-
if (this.isFlushEnqueued) return;
|
|
561
|
-
this.isFlushEnqueued = true;
|
|
562
|
-
this.queue.enqueue(this.onFlush);
|
|
563
|
-
};
|
|
569
|
+
this.updatedKeys = /* @__PURE__ */ new Set();
|
|
570
|
+
this.isAfterFlushDeliveryScheduled = false;
|
|
564
571
|
// Stable handler reference to avoid allocating a new closure on every HAS_CHANGES.
|
|
565
572
|
this.onFlush = () => {
|
|
566
573
|
this.isFlushEnqueued = false;
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
this.
|
|
570
|
-
return;
|
|
571
|
-
}
|
|
572
|
-
if (this.keyHandlers.size === 0 && this.keyHandlersBeforeFlush.size === 0) {
|
|
573
|
-
this.coalescer.clearUpdatedKeys();
|
|
574
|
+
this.dequeueFlush = void 0;
|
|
575
|
+
if (this.keyHandlers.size === 0) {
|
|
576
|
+
this.updatedKeys.clear();
|
|
574
577
|
return;
|
|
575
578
|
}
|
|
576
579
|
const makeHandlerSnapshot = (handlers) => {
|
|
@@ -578,95 +581,133 @@ var OIMUpdateEventEmitter = class {
|
|
|
578
581
|
handlers.forEach((h) => snapshot.push(h));
|
|
579
582
|
return snapshot;
|
|
580
583
|
};
|
|
581
|
-
|
|
582
|
-
this.isDispatching = true;
|
|
583
|
-
this.isInPrePhase = true;
|
|
584
|
-
this.hasPendingDuringPrePhase = false;
|
|
585
|
-
const allKeysForNormalPhase = this.runPrePhaseDrain(makeHandlerSnapshot);
|
|
586
|
-
this.isInPrePhase = false;
|
|
587
|
-
this.runHandlersPhase(allKeysForNormalPhase, makeHandlerSnapshot);
|
|
588
|
-
} finally {
|
|
589
|
-
this.isInPrePhase = false;
|
|
590
|
-
this.isDispatching = false;
|
|
591
|
-
}
|
|
584
|
+
this.runSinglePass(makeHandlerSnapshot);
|
|
592
585
|
};
|
|
593
|
-
this.
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
this.
|
|
597
|
-
|
|
598
|
-
this.queue =
|
|
586
|
+
this.onAfterFlush = () => {
|
|
587
|
+
if (!this.isAfterFlushDeliveryScheduled) return;
|
|
588
|
+
this.isAfterFlushDeliveryScheduled = false;
|
|
589
|
+
this.deliverImmediate();
|
|
590
|
+
};
|
|
591
|
+
this.queue = queue;
|
|
592
|
+
this.deliveryMode = deliveryMode;
|
|
593
|
+
if (this.deliveryMode === "after_flush") {
|
|
594
|
+
this.unsubscribeAfterFlushDelivery = this.queue.emitter.on(
|
|
595
|
+
0 /* AFTER_FLUSH */,
|
|
596
|
+
this.onAfterFlush
|
|
597
|
+
);
|
|
598
|
+
}
|
|
599
599
|
}
|
|
600
600
|
/**
|
|
601
|
-
*
|
|
601
|
+
* Mark keys as updated and schedule delivery.
|
|
602
|
+
*
|
|
603
|
+
* If there are no subscriptions, this is a no-op and does not allocate or retain keys.
|
|
602
604
|
*/
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
605
|
+
markUpdatedKeys(keys) {
|
|
606
|
+
if (keys.length === 0) return;
|
|
607
|
+
if (this.deliveryMode === "queue" && this.queue.isInFlush) {
|
|
608
|
+
throw new Error(
|
|
609
|
+
"OIMUpdateEventEmitter: updates during queue.flush() are not allowed. Finish all writes before calling queue.flush()."
|
|
610
|
+
);
|
|
611
|
+
}
|
|
612
|
+
if (this.keyHandlers.size === 0) return;
|
|
613
|
+
let didAddAny = false;
|
|
614
|
+
for (let i = 0; i < keys.length; i++) {
|
|
615
|
+
const key = keys[i];
|
|
616
|
+
const handlers = this.keyHandlers.get(key);
|
|
617
|
+
if (!handlers || handlers.size === 0) continue;
|
|
618
|
+
this.updatedKeys.add(key);
|
|
619
|
+
didAddAny = true;
|
|
620
|
+
}
|
|
621
|
+
if (!didAddAny) return;
|
|
622
|
+
if (this.deliveryMode === "immediate") {
|
|
623
|
+
this.deliverImmediate();
|
|
624
|
+
return;
|
|
625
|
+
}
|
|
626
|
+
if (this.deliveryMode === "after_flush") {
|
|
627
|
+
this.isAfterFlushDeliveryScheduled = true;
|
|
628
|
+
return;
|
|
629
|
+
}
|
|
630
|
+
if (this.isFlushEnqueued) return;
|
|
631
|
+
this.isFlushEnqueued = true;
|
|
632
|
+
this.dequeueFlush = this.queue.enqueue(this.onFlush);
|
|
633
|
+
}
|
|
634
|
+
markUpdatedKey(key) {
|
|
635
|
+
if (this.deliveryMode === "queue" && this.queue.isInFlush) {
|
|
636
|
+
throw new Error(
|
|
637
|
+
"OIMUpdateEventEmitter: updates during queue.flush() are not allowed. Finish all writes before calling queue.flush()."
|
|
638
|
+
);
|
|
639
|
+
}
|
|
640
|
+
if (this.keyHandlers.size === 0) return;
|
|
641
|
+
const handlers = this.keyHandlers.get(key);
|
|
642
|
+
if (!handlers || handlers.size === 0) return;
|
|
643
|
+
this.updatedKeys.add(key);
|
|
644
|
+
if (this.deliveryMode === "immediate") {
|
|
645
|
+
this.deliverImmediate();
|
|
646
|
+
return;
|
|
647
|
+
}
|
|
648
|
+
if (this.deliveryMode === "after_flush") {
|
|
649
|
+
this.isAfterFlushDeliveryScheduled = true;
|
|
650
|
+
return;
|
|
644
651
|
}
|
|
645
|
-
return
|
|
652
|
+
if (this.isFlushEnqueued) return;
|
|
653
|
+
this.isFlushEnqueued = true;
|
|
654
|
+
this.dequeueFlush = this.queue.enqueue(this.onFlush);
|
|
646
655
|
}
|
|
647
|
-
|
|
648
|
-
if (this.
|
|
656
|
+
markAllUpdated() {
|
|
657
|
+
if (this.deliveryMode === "queue" && this.queue.isInFlush) {
|
|
658
|
+
throw new Error(
|
|
659
|
+
"OIMUpdateEventEmitter: updates during queue.flush() are not allowed. Finish all writes before calling queue.flush()."
|
|
660
|
+
);
|
|
661
|
+
}
|
|
662
|
+
if (this.keyHandlers.size === 0) return;
|
|
663
|
+
this.keyHandlers.forEach((_handlers, key) => {
|
|
664
|
+
this.updatedKeys.add(key);
|
|
665
|
+
});
|
|
666
|
+
if (this.deliveryMode === "immediate") {
|
|
667
|
+
this.deliverImmediate();
|
|
668
|
+
return;
|
|
669
|
+
}
|
|
670
|
+
if (this.deliveryMode === "after_flush") {
|
|
671
|
+
this.isAfterFlushDeliveryScheduled = true;
|
|
649
672
|
return;
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
673
|
+
}
|
|
674
|
+
if (this.isFlushEnqueued) return;
|
|
675
|
+
this.isFlushEnqueued = true;
|
|
676
|
+
this.dequeueFlush = this.queue.enqueue(this.onFlush);
|
|
677
|
+
}
|
|
678
|
+
deliverImmediate() {
|
|
679
|
+
const makeHandlerSnapshot = (handlers) => {
|
|
680
|
+
const snapshot = [];
|
|
681
|
+
handlers.forEach((h) => snapshot.push(h));
|
|
682
|
+
return snapshot;
|
|
683
|
+
};
|
|
684
|
+
this.runSinglePass(makeHandlerSnapshot);
|
|
685
|
+
}
|
|
686
|
+
/**
|
|
687
|
+
* Deliver updated keys and notify handlers once.
|
|
688
|
+
* Re-entrant updates during delivery are forbidden and will throw in markUpdatedKeys().
|
|
689
|
+
*/
|
|
690
|
+
runSinglePass(makeHandlerSnapshot) {
|
|
691
|
+
if (this.updatedKeys.size === 0) return;
|
|
692
|
+
const flushingKeys = this.updatedKeys;
|
|
693
|
+
this.updatedKeys = /* @__PURE__ */ new Set();
|
|
694
|
+
if (this.keyHandlers.size === 0 || flushingKeys.size === 0) return;
|
|
695
|
+
if (flushingKeys.size * 2 < this.keyHandlers.size) {
|
|
696
|
+
flushingKeys.forEach((key) => {
|
|
653
697
|
const handlers = this.keyHandlers.get(key);
|
|
654
698
|
if (!handlers || handlers.size === 0) return;
|
|
655
699
|
const handlerSnapshot = makeHandlerSnapshot(handlers);
|
|
656
700
|
for (let i = 0; i < handlerSnapshot.length; i++) {
|
|
657
|
-
if (this.isDestroyed) return;
|
|
658
701
|
const handler = handlerSnapshot[i];
|
|
659
702
|
if (handlers.has(handler)) handler();
|
|
660
703
|
}
|
|
661
704
|
});
|
|
662
705
|
} else {
|
|
663
706
|
this.keyHandlers.forEach((handlers, key) => {
|
|
664
|
-
if (
|
|
665
|
-
if (!allKeysForNormalPhase.has(key)) return;
|
|
707
|
+
if (!flushingKeys.has(key)) return;
|
|
666
708
|
if (!handlers || handlers.size === 0) return;
|
|
667
709
|
const handlerSnapshot = makeHandlerSnapshot(handlers);
|
|
668
710
|
for (let i = 0; i < handlerSnapshot.length; i++) {
|
|
669
|
-
if (this.isDestroyed) return;
|
|
670
711
|
const handler = handlerSnapshot[i];
|
|
671
712
|
if (handlers.has(handler)) handler();
|
|
672
713
|
}
|
|
@@ -674,14 +715,17 @@ var OIMUpdateEventEmitter = class {
|
|
|
674
715
|
}
|
|
675
716
|
}
|
|
676
717
|
destroy() {
|
|
677
|
-
if (this.
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
718
|
+
if (this.dequeueFlush) {
|
|
719
|
+
this.dequeueFlush();
|
|
720
|
+
this.dequeueFlush = void 0;
|
|
721
|
+
}
|
|
722
|
+
if (this.unsubscribeAfterFlushDelivery) {
|
|
723
|
+
this.unsubscribeAfterFlushDelivery();
|
|
724
|
+
this.unsubscribeAfterFlushDelivery = void 0;
|
|
725
|
+
}
|
|
726
|
+
this.keyHandlers.forEach((handlers) => handlers.clear());
|
|
684
727
|
this.keyHandlers.clear();
|
|
728
|
+
this.updatedKeys.clear();
|
|
685
729
|
}
|
|
686
730
|
/**
|
|
687
731
|
* Get performance metrics for monitoring and debugging
|
|
@@ -702,32 +746,13 @@ var OIMUpdateEventEmitter = class {
|
|
|
702
746
|
* Check if there are any active subscriptions
|
|
703
747
|
*/
|
|
704
748
|
hasSubscriptions() {
|
|
705
|
-
return this.keyHandlers.size > 0
|
|
749
|
+
return this.keyHandlers.size > 0;
|
|
706
750
|
}
|
|
707
751
|
/**
|
|
708
752
|
* Get the number of handlers for a specific key
|
|
709
753
|
*/
|
|
710
754
|
getHandlerCount(key) {
|
|
711
|
-
return
|
|
712
|
-
}
|
|
713
|
-
subscribeOnKeyBeforeFlush(key, handler) {
|
|
714
|
-
let handlers = this.keyHandlersBeforeFlush.get(key);
|
|
715
|
-
if (!handlers) {
|
|
716
|
-
handlers = /* @__PURE__ */ new Set();
|
|
717
|
-
this.keyHandlersBeforeFlush.set(key, handlers);
|
|
718
|
-
}
|
|
719
|
-
handlers.add(handler);
|
|
720
|
-
return () => {
|
|
721
|
-
this.unsubscribeFromKeyBeforeFlush(key, handler);
|
|
722
|
-
};
|
|
723
|
-
}
|
|
724
|
-
unsubscribeFromKeyBeforeFlush(key, handler) {
|
|
725
|
-
const handlers = this.keyHandlersBeforeFlush.get(key);
|
|
726
|
-
if (!handlers) return;
|
|
727
|
-
handlers.delete(handler);
|
|
728
|
-
if (handlers.size === 0) {
|
|
729
|
-
this.keyHandlersBeforeFlush.delete(key);
|
|
730
|
-
}
|
|
755
|
+
return this.keyHandlers.get(key)?.size ?? 0;
|
|
731
756
|
}
|
|
732
757
|
subscribeOnKey(key, handler) {
|
|
733
758
|
let handlers = this.keyHandlers.get(key);
|
|
@@ -746,6 +771,15 @@ var OIMUpdateEventEmitter = class {
|
|
|
746
771
|
handlers.delete(handler);
|
|
747
772
|
if (handlers.size === 0) {
|
|
748
773
|
this.keyHandlers.delete(key);
|
|
774
|
+
this.updatedKeys.delete(key);
|
|
775
|
+
}
|
|
776
|
+
if (this.keyHandlers.size === 0) {
|
|
777
|
+
this.updatedKeys.clear();
|
|
778
|
+
if (this.dequeueFlush) {
|
|
779
|
+
this.dequeueFlush();
|
|
780
|
+
this.dequeueFlush = void 0;
|
|
781
|
+
}
|
|
782
|
+
this.isFlushEnqueued = false;
|
|
749
783
|
}
|
|
750
784
|
}
|
|
751
785
|
subscribeOnKeys(keys, handler) {
|
|
@@ -767,30 +801,6 @@ var OIMUpdateEventEmitter = class {
|
|
|
767
801
|
}
|
|
768
802
|
};
|
|
769
803
|
}
|
|
770
|
-
subscribeOnKeysBeforeFlush(keys, handler) {
|
|
771
|
-
const subscribedKeys = [];
|
|
772
|
-
for (const key of keys) {
|
|
773
|
-
let handlers = this.keyHandlersBeforeFlush.get(key);
|
|
774
|
-
if (!handlers) {
|
|
775
|
-
handlers = /* @__PURE__ */ new Set();
|
|
776
|
-
this.keyHandlersBeforeFlush.set(key, handlers);
|
|
777
|
-
}
|
|
778
|
-
if (!handlers.has(handler)) {
|
|
779
|
-
handlers.add(handler);
|
|
780
|
-
subscribedKeys.push(key);
|
|
781
|
-
}
|
|
782
|
-
}
|
|
783
|
-
return () => {
|
|
784
|
-
for (const key of subscribedKeys) {
|
|
785
|
-
this.unsubscribeFromKeyBeforeFlush(key, handler);
|
|
786
|
-
}
|
|
787
|
-
};
|
|
788
|
-
}
|
|
789
|
-
unsubscribeFromKeysBeforeFlush(keys, handler) {
|
|
790
|
-
for (const key of keys) {
|
|
791
|
-
this.unsubscribeFromKeyBeforeFlush(key, handler);
|
|
792
|
-
}
|
|
793
|
-
}
|
|
794
804
|
unsubscribeFromKeys(keys, handler) {
|
|
795
805
|
for (const key of keys) {
|
|
796
806
|
this.unsubscribeFromKey(key, handler);
|
|
@@ -798,203 +808,11 @@ var OIMUpdateEventEmitter = class {
|
|
|
798
808
|
}
|
|
799
809
|
};
|
|
800
810
|
|
|
801
|
-
// src/core/OIMIndexManualSetBased.ts
|
|
802
|
-
var OIMIndexManualSetBased = class extends OIMIndexSetBased {
|
|
803
|
-
constructor(options = {}) {
|
|
804
|
-
super(options);
|
|
805
|
-
}
|
|
806
|
-
/**
|
|
807
|
-
* Set primary keys for a specific index key, replacing any existing values.
|
|
808
|
-
* Uses optional comparator to skip updates if PKs haven't actually changed.
|
|
809
|
-
*/
|
|
810
|
-
setPks(key, pks) {
|
|
811
|
-
const hasChanges = this.setPksWithComparison(key, new Set(pks));
|
|
812
|
-
if (hasChanges) {
|
|
813
|
-
this.emitUpdate([key]);
|
|
814
|
-
}
|
|
815
|
-
}
|
|
816
|
-
/**
|
|
817
|
-
* Add primary keys to a specific index key
|
|
818
|
-
*/
|
|
819
|
-
addPks(key, pks) {
|
|
820
|
-
if (pks.length === 0) return;
|
|
821
|
-
let pksSet = this.store.getOneByKey(key);
|
|
822
|
-
if (!pksSet) {
|
|
823
|
-
pksSet = /* @__PURE__ */ new Set();
|
|
824
|
-
this.store.setOneByKey(key, pksSet);
|
|
825
|
-
}
|
|
826
|
-
let hasChanges = false;
|
|
827
|
-
for (const pk of pks) {
|
|
828
|
-
if (!pksSet.has(pk)) {
|
|
829
|
-
pksSet.add(pk);
|
|
830
|
-
hasChanges = true;
|
|
831
|
-
}
|
|
832
|
-
}
|
|
833
|
-
if (hasChanges) {
|
|
834
|
-
this.store.setOneByKey(key, pksSet);
|
|
835
|
-
this.emitUpdate([key]);
|
|
836
|
-
}
|
|
837
|
-
}
|
|
838
|
-
/**
|
|
839
|
-
* Remove primary keys from a specific index key
|
|
840
|
-
*/
|
|
841
|
-
removePks(key, pks) {
|
|
842
|
-
if (pks.length === 0) return;
|
|
843
|
-
const pksSet = this.store.getOneByKey(key);
|
|
844
|
-
if (!pksSet) return;
|
|
845
|
-
let hasChanges = false;
|
|
846
|
-
for (const pk of pks) {
|
|
847
|
-
if (pksSet.delete(pk)) {
|
|
848
|
-
hasChanges = true;
|
|
849
|
-
}
|
|
850
|
-
}
|
|
851
|
-
if (pksSet.size === 0) {
|
|
852
|
-
this.store.removeOneByKey(key);
|
|
853
|
-
hasChanges = true;
|
|
854
|
-
} else if (hasChanges) {
|
|
855
|
-
this.store.setOneByKey(key, pksSet);
|
|
856
|
-
}
|
|
857
|
-
if (hasChanges) {
|
|
858
|
-
this.emitUpdate([key]);
|
|
859
|
-
}
|
|
860
|
-
}
|
|
861
|
-
/**
|
|
862
|
-
* Clear all primary keys for a specific index key, or all keys if no key specified
|
|
863
|
-
*/
|
|
864
|
-
clear(key) {
|
|
865
|
-
if (key === void 0) {
|
|
866
|
-
const allKeys = this.store.getAllKeys();
|
|
867
|
-
if (allKeys.length > 0) {
|
|
868
|
-
this.store.clear();
|
|
869
|
-
this.emitUpdate(allKeys);
|
|
870
|
-
}
|
|
871
|
-
} else {
|
|
872
|
-
if (this.store.getOneByKey(key) !== void 0) {
|
|
873
|
-
this.store.removeOneByKey(key);
|
|
874
|
-
this.emitUpdate([key]);
|
|
875
|
-
}
|
|
876
|
-
}
|
|
877
|
-
}
|
|
878
|
-
};
|
|
879
|
-
|
|
880
|
-
// src/const/OIMDBSettings.ts
|
|
881
|
-
var OIMDBSettings = class {
|
|
882
|
-
};
|
|
883
|
-
/**
|
|
884
|
-
* Fixed key used in the manual index to store updated keys set in coalescers.
|
|
885
|
-
* This constant is exported so users can create their own indexes and pass them to coalescers.
|
|
886
|
-
*/
|
|
887
|
-
OIMDBSettings.UPDATED_KEYS_INDEX_KEY = "__updatedKeys__";
|
|
888
|
-
OIMDBSettings.FLUSHING_KEYS_INDEX_KEY = "__flushingKeys__";
|
|
889
|
-
|
|
890
|
-
// src/core/OIMUpdateEventCoalescer.ts
|
|
891
|
-
var OIMUpdateEventCoalescer = class {
|
|
892
|
-
constructor(index, flushingIndex) {
|
|
893
|
-
this.emitter = new OIMEventEmitter();
|
|
894
|
-
this.hasEmittedChanges = false;
|
|
895
|
-
this.updatedKeysIndex = index ?? new OIMIndexManualSetBased({
|
|
896
|
-
store: new OIMIndexStoreMapDrivenSetBased()
|
|
897
|
-
});
|
|
898
|
-
this.flushingUpdatedKeysIndex = flushingIndex ?? new OIMIndexManualSetBased({
|
|
899
|
-
store: new OIMIndexStoreMapDrivenSetBased()
|
|
900
|
-
});
|
|
901
|
-
if (!this.updatedKeysIndex.hasKey(OIMDBSettings.UPDATED_KEYS_INDEX_KEY)) {
|
|
902
|
-
this.updatedKeysIndex.setPks(
|
|
903
|
-
OIMDBSettings.UPDATED_KEYS_INDEX_KEY,
|
|
904
|
-
[]
|
|
905
|
-
);
|
|
906
|
-
}
|
|
907
|
-
}
|
|
908
|
-
/**
|
|
909
|
-
* Get the set of keys that have been updated since last clear
|
|
910
|
-
*/
|
|
911
|
-
getUpdatedKeys() {
|
|
912
|
-
return this.updatedKeysIndex.getPksByKey(
|
|
913
|
-
OIMDBSettings.UPDATED_KEYS_INDEX_KEY
|
|
914
|
-
);
|
|
915
|
-
}
|
|
916
|
-
getFlushingUpdatedKeys() {
|
|
917
|
-
return this.flushingUpdatedKeysIndex.getPksByKey(
|
|
918
|
-
OIMDBSettings.FLUSHING_KEYS_INDEX_KEY
|
|
919
|
-
);
|
|
920
|
-
}
|
|
921
|
-
markUpdatedKeysAsFlushing() {
|
|
922
|
-
this.flushingUpdatedKeysIndex.setPks(
|
|
923
|
-
OIMDBSettings.FLUSHING_KEYS_INDEX_KEY,
|
|
924
|
-
Array.from(this.getUpdatedKeys())
|
|
925
|
-
);
|
|
926
|
-
this.clearUpdatedKeys();
|
|
927
|
-
}
|
|
928
|
-
/**
|
|
929
|
-
* Clear all updated keys and reset the changed state
|
|
930
|
-
*/
|
|
931
|
-
clearUpdatedKeys() {
|
|
932
|
-
this.emitter.emit(
|
|
933
|
-
1 /* BEFORE_FLUSH */,
|
|
934
|
-
void 0
|
|
935
|
-
);
|
|
936
|
-
this.updatedKeysIndex.setPks(OIMDBSettings.UPDATED_KEYS_INDEX_KEY, []);
|
|
937
|
-
this.hasEmittedChanges = false;
|
|
938
|
-
this.emitter.emit(
|
|
939
|
-
2 /* AFTER_FLUSH */,
|
|
940
|
-
void 0
|
|
941
|
-
);
|
|
942
|
-
}
|
|
943
|
-
clearFlushingUpdatedKeys() {
|
|
944
|
-
this.flushingUpdatedKeysIndex.setPks(
|
|
945
|
-
OIMDBSettings.FLUSHING_KEYS_INDEX_KEY,
|
|
946
|
-
[]
|
|
947
|
-
);
|
|
948
|
-
}
|
|
949
|
-
/**
|
|
950
|
-
* Add keys to the updated set and emit HAS_CHANGES event if needed
|
|
951
|
-
*/
|
|
952
|
-
addUpdatedKeys(keys) {
|
|
953
|
-
this.updatedKeysIndex.addPks(
|
|
954
|
-
OIMDBSettings.UPDATED_KEYS_INDEX_KEY,
|
|
955
|
-
keys
|
|
956
|
-
);
|
|
957
|
-
if (!this.hasEmittedChanges) {
|
|
958
|
-
this.hasEmittedChanges = true;
|
|
959
|
-
this.emitter.emit(
|
|
960
|
-
0 /* HAS_CHANGES */,
|
|
961
|
-
void 0
|
|
962
|
-
);
|
|
963
|
-
}
|
|
964
|
-
}
|
|
965
|
-
};
|
|
966
|
-
|
|
967
|
-
// src/core/OIMUpdateEventCoalescerIndex.ts
|
|
968
|
-
var OIMUpdateEventCoalescerIndex = class extends OIMUpdateEventCoalescer {
|
|
969
|
-
constructor(indexEmitter) {
|
|
970
|
-
super();
|
|
971
|
-
this.indexEmitter = indexEmitter;
|
|
972
|
-
/**
|
|
973
|
-
* When the index is updated, we keep track of the updated keys.
|
|
974
|
-
*/
|
|
975
|
-
this.handleUpdate = (payload) => {
|
|
976
|
-
this.addUpdatedKeys(payload.keys);
|
|
977
|
-
};
|
|
978
|
-
this.indexEmitter.on(0 /* UPDATE */, this.handleUpdate);
|
|
979
|
-
}
|
|
980
|
-
destroy() {
|
|
981
|
-
this.indexEmitter.off(0 /* UPDATE */, this.handleUpdate);
|
|
982
|
-
this.emitter.offAll();
|
|
983
|
-
this.clearUpdatedKeys();
|
|
984
|
-
}
|
|
985
|
-
};
|
|
986
|
-
|
|
987
811
|
// src/abstract/OIMReactiveIndexSetBased.ts
|
|
988
812
|
var OIMReactiveIndexSetBased = class {
|
|
989
|
-
constructor(queue,
|
|
990
|
-
this.
|
|
991
|
-
this.
|
|
992
|
-
this.index.emitter
|
|
993
|
-
);
|
|
994
|
-
this.updateEventEmitter = new OIMUpdateEventEmitter({
|
|
995
|
-
coalescer: this.coalescer,
|
|
996
|
-
queue
|
|
997
|
-
});
|
|
813
|
+
constructor(queue, createIndex) {
|
|
814
|
+
this.updateEmitter = new OIMUpdateEventEmitter(queue);
|
|
815
|
+
this.index = createIndex(this.updateEmitter);
|
|
998
816
|
}
|
|
999
817
|
getPksByKey(key) {
|
|
1000
818
|
return this.index.getPksByKey(key);
|
|
@@ -1020,24 +838,38 @@ var OIMReactiveIndexSetBased = class {
|
|
|
1020
838
|
getMetrics() {
|
|
1021
839
|
return this.index.getMetrics();
|
|
1022
840
|
}
|
|
841
|
+
subscribeOnKey(key, handler) {
|
|
842
|
+
return this.updateEmitter.subscribeOnKey(key, handler);
|
|
843
|
+
}
|
|
844
|
+
subscribeOnKeys(keys, handler) {
|
|
845
|
+
return this.updateEmitter.subscribeOnKeys(keys, handler);
|
|
846
|
+
}
|
|
847
|
+
unsubscribeFromKey(key, handler) {
|
|
848
|
+
this.updateEmitter.unsubscribeFromKey(key, handler);
|
|
849
|
+
}
|
|
850
|
+
unsubscribeFromKeys(keys, handler) {
|
|
851
|
+
this.updateEmitter.unsubscribeFromKeys(keys, handler);
|
|
852
|
+
}
|
|
853
|
+
hasSubscriptions() {
|
|
854
|
+
return this.updateEmitter.hasSubscriptions();
|
|
855
|
+
}
|
|
856
|
+
getHandlerCount(key) {
|
|
857
|
+
return this.updateEmitter.getHandlerCount(key);
|
|
858
|
+
}
|
|
859
|
+
getSubscriptionMetrics() {
|
|
860
|
+
return this.updateEmitter.getMetrics();
|
|
861
|
+
}
|
|
1023
862
|
destroy() {
|
|
1024
|
-
this.
|
|
1025
|
-
this.coalescer.destroy();
|
|
863
|
+
this.updateEmitter.destroy();
|
|
1026
864
|
this.index.destroy();
|
|
1027
865
|
}
|
|
1028
866
|
};
|
|
1029
867
|
|
|
1030
868
|
// src/abstract/OIMReactiveIndexArrayBased.ts
|
|
1031
869
|
var OIMReactiveIndexArrayBased = class {
|
|
1032
|
-
constructor(queue,
|
|
1033
|
-
this.
|
|
1034
|
-
this.
|
|
1035
|
-
this.index.emitter
|
|
1036
|
-
);
|
|
1037
|
-
this.updateEventEmitter = new OIMUpdateEventEmitter({
|
|
1038
|
-
coalescer: this.coalescer,
|
|
1039
|
-
queue
|
|
1040
|
-
});
|
|
870
|
+
constructor(queue, createIndex) {
|
|
871
|
+
this.updateEmitter = new OIMUpdateEventEmitter(queue);
|
|
872
|
+
this.index = createIndex(this.updateEmitter);
|
|
1041
873
|
}
|
|
1042
874
|
getPksByKey(key) {
|
|
1043
875
|
return this.index.getPksByKey(key);
|
|
@@ -1063,9 +895,29 @@ var OIMReactiveIndexArrayBased = class {
|
|
|
1063
895
|
getMetrics() {
|
|
1064
896
|
return this.index.getMetrics();
|
|
1065
897
|
}
|
|
898
|
+
subscribeOnKey(key, handler) {
|
|
899
|
+
return this.updateEmitter.subscribeOnKey(key, handler);
|
|
900
|
+
}
|
|
901
|
+
subscribeOnKeys(keys, handler) {
|
|
902
|
+
return this.updateEmitter.subscribeOnKeys(keys, handler);
|
|
903
|
+
}
|
|
904
|
+
unsubscribeFromKey(key, handler) {
|
|
905
|
+
this.updateEmitter.unsubscribeFromKey(key, handler);
|
|
906
|
+
}
|
|
907
|
+
unsubscribeFromKeys(keys, handler) {
|
|
908
|
+
this.updateEmitter.unsubscribeFromKeys(keys, handler);
|
|
909
|
+
}
|
|
910
|
+
hasSubscriptions() {
|
|
911
|
+
return this.updateEmitter.hasSubscriptions();
|
|
912
|
+
}
|
|
913
|
+
getHandlerCount(key) {
|
|
914
|
+
return this.updateEmitter.getHandlerCount(key);
|
|
915
|
+
}
|
|
916
|
+
getSubscriptionMetrics() {
|
|
917
|
+
return this.updateEmitter.getMetrics();
|
|
918
|
+
}
|
|
1066
919
|
destroy() {
|
|
1067
|
-
this.
|
|
1068
|
-
this.coalescer.destroy();
|
|
920
|
+
this.updateEmitter.destroy();
|
|
1069
921
|
this.index.destroy();
|
|
1070
922
|
}
|
|
1071
923
|
};
|
|
@@ -1237,47 +1089,131 @@ var OIMCollection = class {
|
|
|
1237
1089
|
}
|
|
1238
1090
|
};
|
|
1239
1091
|
|
|
1240
|
-
// src/core/OIMUpdateEventCoalescerCollection.ts
|
|
1241
|
-
var OIMUpdateEventCoalescerCollection = class extends OIMUpdateEventCoalescer {
|
|
1242
|
-
constructor(collectionEmitter) {
|
|
1243
|
-
super();
|
|
1244
|
-
this.collectionEmitter = collectionEmitter;
|
|
1245
|
-
/**
|
|
1246
|
-
* When the collection is updated, we keep track of the updated pks.
|
|
1247
|
-
*/
|
|
1248
|
-
this.handleUpdate = (payload) => {
|
|
1249
|
-
this.addUpdatedKeys(payload.pks);
|
|
1250
|
-
};
|
|
1251
|
-
this.collectionEmitter.on(
|
|
1252
|
-
0 /* UPDATE */,
|
|
1253
|
-
this.handleUpdate
|
|
1254
|
-
);
|
|
1255
|
-
}
|
|
1256
|
-
destroy() {
|
|
1257
|
-
this.collectionEmitter.off(
|
|
1258
|
-
0 /* UPDATE */,
|
|
1259
|
-
this.handleUpdate
|
|
1260
|
-
);
|
|
1261
|
-
this.emitter.offAll();
|
|
1262
|
-
this.clearUpdatedKeys();
|
|
1263
|
-
}
|
|
1264
|
-
};
|
|
1265
|
-
|
|
1266
1092
|
// src/core/OIMReactiveCollection.ts
|
|
1267
1093
|
var OIMReactiveCollection = class extends OIMCollection {
|
|
1268
1094
|
constructor(queue, opts) {
|
|
1269
1095
|
super(opts);
|
|
1270
|
-
this.
|
|
1271
|
-
|
|
1096
|
+
this.anyUpdateHandlers = /* @__PURE__ */ new Set();
|
|
1097
|
+
this.pendingAnyUpdatePks = /* @__PURE__ */ new Set();
|
|
1098
|
+
this.isAnyUpdateClearPending = false;
|
|
1099
|
+
this.isAnyUpdateScheduled = false;
|
|
1100
|
+
this.runAnyUpdate = () => {
|
|
1101
|
+
if (!this.isAnyUpdateScheduled) return;
|
|
1102
|
+
this.isAnyUpdateScheduled = false;
|
|
1103
|
+
this.dequeueAnyUpdate = void 0;
|
|
1104
|
+
const pks = this.isAnyUpdateClearPending ? [] : Array.from(this.pendingAnyUpdatePks);
|
|
1105
|
+
this.pendingAnyUpdatePks.clear();
|
|
1106
|
+
this.isAnyUpdateClearPending = false;
|
|
1107
|
+
const snapshot = Array.from(this.anyUpdateHandlers);
|
|
1108
|
+
for (let i = 0; i < snapshot.length; i++) snapshot[i](pks);
|
|
1109
|
+
};
|
|
1110
|
+
this.queue = queue;
|
|
1111
|
+
this.updateEmitter = new OIMUpdateEventEmitter(queue, "queue");
|
|
1112
|
+
}
|
|
1113
|
+
subscribeOnKey(pk, handler) {
|
|
1114
|
+
return this.updateEmitter.subscribeOnKey(pk, handler);
|
|
1115
|
+
}
|
|
1116
|
+
subscribeOnKeys(pks, handler) {
|
|
1117
|
+
return this.updateEmitter.subscribeOnKeys(pks, handler);
|
|
1118
|
+
}
|
|
1119
|
+
unsubscribeFromKey(pk, handler) {
|
|
1120
|
+
this.updateEmitter.unsubscribeFromKey(pk, handler);
|
|
1121
|
+
}
|
|
1122
|
+
unsubscribeFromKeys(pks, handler) {
|
|
1123
|
+
this.updateEmitter.unsubscribeFromKeys(pks, handler);
|
|
1124
|
+
}
|
|
1125
|
+
destroySubscriptions() {
|
|
1126
|
+
this.updateEmitter.destroy();
|
|
1127
|
+
}
|
|
1128
|
+
hasSubscriptions() {
|
|
1129
|
+
return this.updateEmitter.hasSubscriptions();
|
|
1130
|
+
}
|
|
1131
|
+
getHandlerCount(pk) {
|
|
1132
|
+
return this.updateEmitter.getHandlerCount(pk);
|
|
1133
|
+
}
|
|
1134
|
+
getMetrics() {
|
|
1135
|
+
return this.updateEmitter.getMetrics();
|
|
1136
|
+
}
|
|
1137
|
+
subscribeOnAnyUpdate(handler) {
|
|
1138
|
+
this.anyUpdateHandlers.add(handler);
|
|
1139
|
+
return () => {
|
|
1140
|
+
this.anyUpdateHandlers.delete(handler);
|
|
1141
|
+
};
|
|
1142
|
+
}
|
|
1143
|
+
upsertOneByPk(pk, entity) {
|
|
1144
|
+
this.upsertOneWithoutNotificationsByPk(pk, entity);
|
|
1145
|
+
this.updateEmitter.markUpdatedKey(pk);
|
|
1146
|
+
this.trackAnyUpdatePk(pk);
|
|
1147
|
+
}
|
|
1148
|
+
upsertOne(entity) {
|
|
1149
|
+
const pk = this.upsertOneWithoutNotifications(entity);
|
|
1150
|
+
this.updateEmitter.markUpdatedKey(pk);
|
|
1151
|
+
this.trackAnyUpdatePk(pk);
|
|
1152
|
+
}
|
|
1153
|
+
upsertMany(entities) {
|
|
1154
|
+
const pks = entities.map(
|
|
1155
|
+
(entity) => this.upsertOneWithoutNotifications(entity)
|
|
1272
1156
|
);
|
|
1273
|
-
this.
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1157
|
+
this.updateEmitter.markUpdatedKeys(pks);
|
|
1158
|
+
this.trackAnyUpdatePks(pks);
|
|
1159
|
+
}
|
|
1160
|
+
removeOne(entity) {
|
|
1161
|
+
const pk = this.selectPk(entity);
|
|
1162
|
+
this.store.removeOneByPk(pk);
|
|
1163
|
+
this.updateEmitter.markUpdatedKey(pk);
|
|
1164
|
+
this.trackAnyUpdatePk(pk);
|
|
1165
|
+
}
|
|
1166
|
+
removeMany(entities) {
|
|
1167
|
+
const pks = entities.map(this.selectPk);
|
|
1168
|
+
this.store.removeManyByPks(pks);
|
|
1169
|
+
this.updateEmitter.markUpdatedKeys(pks);
|
|
1170
|
+
this.trackAnyUpdatePks(pks);
|
|
1171
|
+
}
|
|
1172
|
+
removeOneByPk(pk) {
|
|
1173
|
+
this.store.removeOneByPk(pk);
|
|
1174
|
+
this.updateEmitter.markUpdatedKey(pk);
|
|
1175
|
+
this.trackAnyUpdatePk(pk);
|
|
1176
|
+
}
|
|
1177
|
+
removeManyByPks(pks) {
|
|
1178
|
+
this.store.removeManyByPks(pks);
|
|
1179
|
+
this.updateEmitter.markUpdatedKeys(pks);
|
|
1180
|
+
this.trackAnyUpdatePks(pks);
|
|
1181
|
+
}
|
|
1182
|
+
clear() {
|
|
1183
|
+
this.store.clear();
|
|
1184
|
+
this.updateEmitter.markAllUpdated();
|
|
1185
|
+
this.trackAnyUpdateClear();
|
|
1186
|
+
}
|
|
1187
|
+
trackAnyUpdatePk(pk) {
|
|
1188
|
+
if (this.anyUpdateHandlers.size === 0) return;
|
|
1189
|
+
this.pendingAnyUpdatePks.add(pk);
|
|
1190
|
+
this.ensureAnyUpdateEnqueued();
|
|
1191
|
+
}
|
|
1192
|
+
trackAnyUpdatePks(pks) {
|
|
1193
|
+
if (this.anyUpdateHandlers.size === 0) return;
|
|
1194
|
+
for (let i = 0; i < pks.length; i++)
|
|
1195
|
+
this.pendingAnyUpdatePks.add(pks[i]);
|
|
1196
|
+
this.ensureAnyUpdateEnqueued();
|
|
1197
|
+
}
|
|
1198
|
+
trackAnyUpdateClear() {
|
|
1199
|
+
if (this.anyUpdateHandlers.size === 0) return;
|
|
1200
|
+
this.isAnyUpdateClearPending = true;
|
|
1201
|
+
this.pendingAnyUpdatePks.clear();
|
|
1202
|
+
this.ensureAnyUpdateEnqueued();
|
|
1203
|
+
}
|
|
1204
|
+
ensureAnyUpdateEnqueued() {
|
|
1205
|
+
if (this.isAnyUpdateScheduled) return;
|
|
1206
|
+
this.isAnyUpdateScheduled = true;
|
|
1207
|
+
this.dequeueAnyUpdate = this.queue.enqueue(this.runAnyUpdate);
|
|
1277
1208
|
}
|
|
1278
1209
|
destroy() {
|
|
1279
|
-
this.
|
|
1280
|
-
this.
|
|
1210
|
+
this.updateEmitter.destroy();
|
|
1211
|
+
if (this.dequeueAnyUpdate) {
|
|
1212
|
+
this.dequeueAnyUpdate();
|
|
1213
|
+
this.dequeueAnyUpdate = void 0;
|
|
1214
|
+
}
|
|
1215
|
+
this.anyUpdateHandlers.clear();
|
|
1216
|
+
this.pendingAnyUpdatePks.clear();
|
|
1281
1217
|
super.destroy();
|
|
1282
1218
|
}
|
|
1283
1219
|
};
|
|
@@ -1377,50 +1313,142 @@ var OIMObject = class {
|
|
|
1377
1313
|
}
|
|
1378
1314
|
};
|
|
1379
1315
|
|
|
1380
|
-
// src/core/OIMUpdateEventCoalescerObject.ts
|
|
1381
|
-
var OIMUpdateEventCoalescerObject = class extends OIMUpdateEventCoalescer {
|
|
1382
|
-
constructor(objectEmitter) {
|
|
1383
|
-
super();
|
|
1384
|
-
this.objectEmitter = objectEmitter;
|
|
1385
|
-
/**
|
|
1386
|
-
* When the object is updated, we keep track of the updated keys.
|
|
1387
|
-
*/
|
|
1388
|
-
this.handleUpdate = (payload) => {
|
|
1389
|
-
this.addUpdatedKeys(payload.keys);
|
|
1390
|
-
};
|
|
1391
|
-
this.objectEmitter.on(0 /* UPDATE */, this.handleUpdate);
|
|
1392
|
-
}
|
|
1393
|
-
destroy() {
|
|
1394
|
-
this.objectEmitter.off(0 /* UPDATE */, this.handleUpdate);
|
|
1395
|
-
this.emitter.offAll();
|
|
1396
|
-
this.clearUpdatedKeys();
|
|
1397
|
-
}
|
|
1398
|
-
};
|
|
1399
|
-
|
|
1400
1316
|
// src/core/OIMReactiveObject.ts
|
|
1401
1317
|
var OIMReactiveObject = class extends OIMObject {
|
|
1402
1318
|
constructor(queue, opts) {
|
|
1403
1319
|
super(opts);
|
|
1404
|
-
this.
|
|
1405
|
-
this.
|
|
1406
|
-
|
|
1407
|
-
queue
|
|
1320
|
+
this.updateEmitter = new OIMUpdateEventEmitter(queue, "queue");
|
|
1321
|
+
this.emitter.on(0 /* UPDATE */, (payload) => {
|
|
1322
|
+
this.updateEmitter.markUpdatedKeys(payload.keys);
|
|
1408
1323
|
});
|
|
1409
1324
|
}
|
|
1325
|
+
subscribeOnKey(key, handler) {
|
|
1326
|
+
return this.updateEmitter.subscribeOnKey(key, handler);
|
|
1327
|
+
}
|
|
1328
|
+
subscribeOnKeys(keys, handler) {
|
|
1329
|
+
return this.updateEmitter.subscribeOnKeys(keys, handler);
|
|
1330
|
+
}
|
|
1331
|
+
unsubscribeFromKey(key, handler) {
|
|
1332
|
+
this.updateEmitter.unsubscribeFromKey(key, handler);
|
|
1333
|
+
}
|
|
1334
|
+
unsubscribeFromKeys(keys, handler) {
|
|
1335
|
+
this.updateEmitter.unsubscribeFromKeys(keys, handler);
|
|
1336
|
+
}
|
|
1337
|
+
hasSubscriptions() {
|
|
1338
|
+
return this.updateEmitter.hasSubscriptions();
|
|
1339
|
+
}
|
|
1340
|
+
getHandlerCount(key) {
|
|
1341
|
+
return this.updateEmitter.getHandlerCount(key);
|
|
1342
|
+
}
|
|
1343
|
+
getMetrics() {
|
|
1344
|
+
return this.updateEmitter.getMetrics();
|
|
1345
|
+
}
|
|
1410
1346
|
destroy() {
|
|
1411
|
-
this.
|
|
1412
|
-
this.coalescer.destroy();
|
|
1347
|
+
this.updateEmitter.destroy();
|
|
1413
1348
|
super.destroy();
|
|
1414
1349
|
}
|
|
1415
1350
|
};
|
|
1416
1351
|
|
|
1352
|
+
// src/core/OIMIndexManualSetBased.ts
|
|
1353
|
+
var OIMIndexManualSetBased = class extends OIMIndexSetBased {
|
|
1354
|
+
constructor(options = {}) {
|
|
1355
|
+
super(options);
|
|
1356
|
+
}
|
|
1357
|
+
/**
|
|
1358
|
+
* Set primary keys for a specific index key, replacing any existing values.
|
|
1359
|
+
* Uses optional comparator to skip updates if PKs haven't actually changed.
|
|
1360
|
+
*/
|
|
1361
|
+
setPks(key, pks) {
|
|
1362
|
+
const hasChanges = this.setPksWithComparison(key, new Set(pks));
|
|
1363
|
+
if (hasChanges) {
|
|
1364
|
+
this.emitUpdateOne(key);
|
|
1365
|
+
}
|
|
1366
|
+
}
|
|
1367
|
+
/**
|
|
1368
|
+
* Add primary keys to a specific index key
|
|
1369
|
+
*/
|
|
1370
|
+
addPks(key, pks) {
|
|
1371
|
+
if (pks.length === 0) return;
|
|
1372
|
+
let pksSet = this.store.getOneByKey(key);
|
|
1373
|
+
if (!pksSet) {
|
|
1374
|
+
pksSet = /* @__PURE__ */ new Set();
|
|
1375
|
+
this.store.setOneByKey(key, pksSet);
|
|
1376
|
+
}
|
|
1377
|
+
let hasChanges = false;
|
|
1378
|
+
for (const pk of pks) {
|
|
1379
|
+
if (!pksSet.has(pk)) {
|
|
1380
|
+
pksSet.add(pk);
|
|
1381
|
+
hasChanges = true;
|
|
1382
|
+
}
|
|
1383
|
+
}
|
|
1384
|
+
if (hasChanges) {
|
|
1385
|
+
this.store.setOneByKey(key, pksSet);
|
|
1386
|
+
this.emitUpdateOne(key);
|
|
1387
|
+
}
|
|
1388
|
+
}
|
|
1389
|
+
/**
|
|
1390
|
+
* Remove primary keys from a specific index key
|
|
1391
|
+
*/
|
|
1392
|
+
removePks(key, pks) {
|
|
1393
|
+
if (pks.length === 0) return;
|
|
1394
|
+
const pksSet = this.store.getOneByKey(key);
|
|
1395
|
+
if (!pksSet) return;
|
|
1396
|
+
let hasChanges = false;
|
|
1397
|
+
for (const pk of pks) {
|
|
1398
|
+
if (pksSet.delete(pk)) {
|
|
1399
|
+
hasChanges = true;
|
|
1400
|
+
}
|
|
1401
|
+
}
|
|
1402
|
+
if (pksSet.size === 0) {
|
|
1403
|
+
this.store.removeOneByKey(key);
|
|
1404
|
+
hasChanges = true;
|
|
1405
|
+
} else if (hasChanges) {
|
|
1406
|
+
this.store.setOneByKey(key, pksSet);
|
|
1407
|
+
}
|
|
1408
|
+
if (hasChanges) {
|
|
1409
|
+
this.emitUpdateOne(key);
|
|
1410
|
+
}
|
|
1411
|
+
}
|
|
1412
|
+
/**
|
|
1413
|
+
* Clear all primary keys for a specific index key, or all keys if no key specified
|
|
1414
|
+
*/
|
|
1415
|
+
clear(key) {
|
|
1416
|
+
if (key === void 0) {
|
|
1417
|
+
const allKeys = this.store.getAllKeys();
|
|
1418
|
+
if (allKeys.length > 0) {
|
|
1419
|
+
this.store.clear();
|
|
1420
|
+
this.emitUpdate(allKeys);
|
|
1421
|
+
}
|
|
1422
|
+
} else {
|
|
1423
|
+
if (this.store.getOneByKey(key) !== void 0) {
|
|
1424
|
+
this.store.removeOneByKey(key);
|
|
1425
|
+
this.emitUpdateOne(key);
|
|
1426
|
+
}
|
|
1427
|
+
}
|
|
1428
|
+
}
|
|
1429
|
+
};
|
|
1430
|
+
|
|
1417
1431
|
// src/core/OIMReactiveIndexManualSetBased.ts
|
|
1432
|
+
var OIMIndexManualSetBasedReactive = class extends OIMIndexManualSetBased {
|
|
1433
|
+
constructor(updateEmitter, opts) {
|
|
1434
|
+
super(opts);
|
|
1435
|
+
this.updateEmitter = updateEmitter;
|
|
1436
|
+
}
|
|
1437
|
+
emitUpdate(keys) {
|
|
1438
|
+
this.updateEmitter.markUpdatedKeys(keys);
|
|
1439
|
+
}
|
|
1440
|
+
emitUpdateOne(key) {
|
|
1441
|
+
this.updateEmitter.markUpdatedKey(key);
|
|
1442
|
+
}
|
|
1443
|
+
};
|
|
1418
1444
|
var OIMReactiveIndexManualSetBased = class extends OIMReactiveIndexSetBased {
|
|
1419
1445
|
constructor(queue, opts) {
|
|
1420
|
-
super(queue,
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1446
|
+
super(queue, (updateEmitter) => {
|
|
1447
|
+
return new OIMIndexManualSetBasedReactive(
|
|
1448
|
+
updateEmitter,
|
|
1449
|
+
opts?.indexOptions
|
|
1450
|
+
);
|
|
1451
|
+
});
|
|
1424
1452
|
}
|
|
1425
1453
|
setPks(key, pks) {
|
|
1426
1454
|
this.index.setPks(key, pks);
|
|
@@ -1448,7 +1476,7 @@ var OIMIndexManualArrayBased = class extends OIMIndexArrayBased {
|
|
|
1448
1476
|
setPks(key, pks) {
|
|
1449
1477
|
const hasChanges = this.setPksWithComparison(key, pks);
|
|
1450
1478
|
if (hasChanges) {
|
|
1451
|
-
this.
|
|
1479
|
+
this.emitUpdateOne(key);
|
|
1452
1480
|
}
|
|
1453
1481
|
}
|
|
1454
1482
|
/**
|
|
@@ -1471,7 +1499,7 @@ var OIMIndexManualArrayBased = class extends OIMIndexArrayBased {
|
|
|
1471
1499
|
}
|
|
1472
1500
|
if (hasChanges) {
|
|
1473
1501
|
this.store.setOneByKey(key, Array.from(pksSet));
|
|
1474
|
-
this.
|
|
1502
|
+
this.emitUpdateOne(key);
|
|
1475
1503
|
}
|
|
1476
1504
|
}
|
|
1477
1505
|
/**
|
|
@@ -1490,7 +1518,7 @@ var OIMIndexManualArrayBased = class extends OIMIndexArrayBased {
|
|
|
1490
1518
|
} else {
|
|
1491
1519
|
this.store.setOneByKey(key, filtered);
|
|
1492
1520
|
}
|
|
1493
|
-
this.
|
|
1521
|
+
this.emitUpdateOne(key);
|
|
1494
1522
|
}
|
|
1495
1523
|
}
|
|
1496
1524
|
/**
|
|
@@ -1506,19 +1534,33 @@ var OIMIndexManualArrayBased = class extends OIMIndexArrayBased {
|
|
|
1506
1534
|
} else {
|
|
1507
1535
|
if (this.store.getOneByKey(key) !== void 0) {
|
|
1508
1536
|
this.store.removeOneByKey(key);
|
|
1509
|
-
this.
|
|
1537
|
+
this.emitUpdateOne(key);
|
|
1510
1538
|
}
|
|
1511
1539
|
}
|
|
1512
1540
|
}
|
|
1513
1541
|
};
|
|
1514
1542
|
|
|
1515
1543
|
// src/core/OIMReactiveIndexManualArrayBased.ts
|
|
1544
|
+
var OIMIndexManualArrayBasedReactive = class extends OIMIndexManualArrayBased {
|
|
1545
|
+
constructor(updateEmitter, opts) {
|
|
1546
|
+
super(opts);
|
|
1547
|
+
this.updateEmitter = updateEmitter;
|
|
1548
|
+
}
|
|
1549
|
+
emitUpdate(keys) {
|
|
1550
|
+
this.updateEmitter.markUpdatedKeys(keys);
|
|
1551
|
+
}
|
|
1552
|
+
emitUpdateOne(key) {
|
|
1553
|
+
this.updateEmitter.markUpdatedKey(key);
|
|
1554
|
+
}
|
|
1555
|
+
};
|
|
1516
1556
|
var OIMReactiveIndexManualArrayBased = class extends OIMReactiveIndexArrayBased {
|
|
1517
1557
|
constructor(queue, opts) {
|
|
1518
|
-
super(queue,
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1558
|
+
super(queue, (updateEmitter) => {
|
|
1559
|
+
return new OIMIndexManualArrayBasedReactive(
|
|
1560
|
+
updateEmitter,
|
|
1561
|
+
opts?.indexOptions
|
|
1562
|
+
);
|
|
1563
|
+
});
|
|
1522
1564
|
}
|
|
1523
1565
|
setPks(key, pks) {
|
|
1524
1566
|
this.index.setPks(key, pks);
|
|
@@ -1607,20 +1649,12 @@ var OIMComparatorFactory = class {
|
|
|
1607
1649
|
}
|
|
1608
1650
|
};
|
|
1609
1651
|
|
|
1610
|
-
// src/enum/EOIMEventQueueEventType.ts
|
|
1611
|
-
var EOIMEventQueueEventType = /* @__PURE__ */ ((EOIMEventQueueEventType2) => {
|
|
1612
|
-
EOIMEventQueueEventType2[EOIMEventQueueEventType2["AFTER_FLUSH"] = 0] = "AFTER_FLUSH";
|
|
1613
|
-
EOIMEventQueueEventType2[EOIMEventQueueEventType2["BEFORE_FLUSH"] = 1] = "BEFORE_FLUSH";
|
|
1614
|
-
return EOIMEventQueueEventType2;
|
|
1615
|
-
})(EOIMEventQueueEventType || {});
|
|
1616
|
-
|
|
1617
1652
|
// src/core/OIMEventQueue.ts
|
|
1618
1653
|
var OIMEventQueue = class {
|
|
1619
1654
|
constructor(options = {}) {
|
|
1620
1655
|
this.emitter = new OIMEventEmitter();
|
|
1621
|
-
this.
|
|
1656
|
+
this.tasks = /* @__PURE__ */ new Set();
|
|
1622
1657
|
this.isFlushing = false;
|
|
1623
|
-
this.pendingSchedule = false;
|
|
1624
1658
|
this.scheduler = options.scheduler;
|
|
1625
1659
|
if (this.scheduler) {
|
|
1626
1660
|
this.flushBound = () => this.flush();
|
|
@@ -1631,62 +1665,76 @@ var OIMEventQueue = class {
|
|
|
1631
1665
|
}
|
|
1632
1666
|
}
|
|
1633
1667
|
/**
|
|
1634
|
-
*
|
|
1635
|
-
*
|
|
1668
|
+
* Enqueue a one-shot task to be executed on the next flush.
|
|
1669
|
+
* Returns a dequeue function that can be called to cancel the task before it runs.
|
|
1636
1670
|
*/
|
|
1637
1671
|
enqueue(fn) {
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1672
|
+
let isActive = true;
|
|
1673
|
+
const task = () => {
|
|
1674
|
+
if (!isActive) return;
|
|
1675
|
+
fn();
|
|
1676
|
+
};
|
|
1677
|
+
this.tasks.add(task);
|
|
1678
|
+
this.ensureScheduled();
|
|
1679
|
+
return () => {
|
|
1680
|
+
if (!isActive) return;
|
|
1681
|
+
isActive = false;
|
|
1682
|
+
this.tasks.delete(task);
|
|
1683
|
+
};
|
|
1684
|
+
}
|
|
1685
|
+
get isInFlush() {
|
|
1686
|
+
return this.isFlushing;
|
|
1687
|
+
}
|
|
1688
|
+
/**
|
|
1689
|
+
* Dequeue (cancel) a previously enqueued task by its dequeue function.
|
|
1690
|
+
*/
|
|
1691
|
+
dequeue(dequeueFn) {
|
|
1692
|
+
dequeueFn();
|
|
1647
1693
|
}
|
|
1648
1694
|
/**
|
|
1649
|
-
* Execute all
|
|
1650
|
-
*
|
|
1695
|
+
* Execute all pending tasks.
|
|
1696
|
+
*
|
|
1697
|
+
* This flush drains until the queue is empty. If tasks enqueue more tasks, they will be
|
|
1698
|
+
* executed within the same flush.
|
|
1651
1699
|
*/
|
|
1652
1700
|
flush() {
|
|
1653
|
-
if (this.queue.length === 0) return;
|
|
1654
1701
|
this.scheduler?.cancel();
|
|
1655
1702
|
this.isFlushing = true;
|
|
1656
1703
|
this.emitter.emit(1 /* BEFORE_FLUSH */, void 0);
|
|
1657
|
-
const
|
|
1658
|
-
this.
|
|
1659
|
-
for (let i = 0; i <
|
|
1660
|
-
|
|
1704
|
+
const snapshot = Array.from(this.tasks);
|
|
1705
|
+
this.tasks.clear();
|
|
1706
|
+
for (let i = 0; i < snapshot.length; i++) {
|
|
1707
|
+
snapshot[i]();
|
|
1661
1708
|
}
|
|
1662
|
-
this.emitter.emit(0 /* AFTER_FLUSH */, void 0);
|
|
1663
1709
|
this.isFlushing = false;
|
|
1664
|
-
|
|
1665
|
-
this.pendingSchedule = false;
|
|
1666
|
-
this.scheduler.schedule();
|
|
1667
|
-
} else {
|
|
1668
|
-
this.pendingSchedule = false;
|
|
1669
|
-
}
|
|
1710
|
+
this.emitter.emit(0 /* AFTER_FLUSH */, void 0);
|
|
1670
1711
|
}
|
|
1671
1712
|
/**
|
|
1672
1713
|
* Get the current number of queued functions.
|
|
1673
1714
|
*/
|
|
1674
1715
|
get length() {
|
|
1675
|
-
return this.
|
|
1716
|
+
return this.tasks.size;
|
|
1676
1717
|
}
|
|
1677
1718
|
/**
|
|
1678
1719
|
* Check if the queue is empty.
|
|
1679
1720
|
*/
|
|
1680
1721
|
get isEmpty() {
|
|
1681
|
-
return this.
|
|
1722
|
+
return this.tasks.size === 0;
|
|
1682
1723
|
}
|
|
1683
1724
|
/**
|
|
1684
1725
|
* Clear the queue without executing functions and cancel any scheduled flush.
|
|
1685
1726
|
*/
|
|
1686
1727
|
clear() {
|
|
1687
|
-
this.
|
|
1728
|
+
this.tasks.clear();
|
|
1688
1729
|
this.scheduler?.cancel();
|
|
1689
1730
|
}
|
|
1731
|
+
ensureScheduled() {
|
|
1732
|
+
if (!this.scheduler) return;
|
|
1733
|
+
if (this.isFlushing) return;
|
|
1734
|
+
if (this.tasks.size === 1) {
|
|
1735
|
+
this.scheduler.schedule();
|
|
1736
|
+
}
|
|
1737
|
+
}
|
|
1690
1738
|
/**
|
|
1691
1739
|
* Clean up scheduler subscription when queue is no longer needed.
|
|
1692
1740
|
*/
|
|
@@ -1800,56 +1848,75 @@ var OIMMap2Keys = class {
|
|
|
1800
1848
|
}
|
|
1801
1849
|
};
|
|
1802
1850
|
|
|
1803
|
-
// src/modules/wrapper/OIMUpdateEventCoalescerManual.ts
|
|
1804
|
-
var OIMUpdateEventCoalescerManual = class extends OIMUpdateEventCoalescer {
|
|
1805
|
-
markUpdatedKeys(keys) {
|
|
1806
|
-
if (keys.length === 0) return;
|
|
1807
|
-
this.addUpdatedKeys(keys);
|
|
1808
|
-
}
|
|
1809
|
-
destroy() {
|
|
1810
|
-
this.emitter.offAll();
|
|
1811
|
-
this.updatedKeysIndex.destroy();
|
|
1812
|
-
this.flushingUpdatedKeysIndex.destroy();
|
|
1813
|
-
}
|
|
1814
|
-
};
|
|
1815
|
-
|
|
1816
1851
|
// src/modules/wrapper/collection/OIMCollectionChangedFieldsWrapper.ts
|
|
1817
1852
|
var OIMCollectionChangedFieldsWrapper = class {
|
|
1818
1853
|
constructor(queue, collection, opts) {
|
|
1854
|
+
this.isInWrite = false;
|
|
1855
|
+
this.lastEntitySnapshotByPk = /* @__PURE__ */ new Map();
|
|
1819
1856
|
this.changedFieldsByPk = /* @__PURE__ */ new Map();
|
|
1820
1857
|
this.changedPksByField = /* @__PURE__ */ new Map();
|
|
1858
|
+
this.onAfterFlush = () => {
|
|
1859
|
+
this.clear();
|
|
1860
|
+
};
|
|
1861
|
+
this.onCollectionUpdate = (payload) => {
|
|
1862
|
+
if (this.isInWrite) return;
|
|
1863
|
+
if (payload.pks.length === 0) return;
|
|
1864
|
+
for (let i = 0; i < payload.pks.length; i++) {
|
|
1865
|
+
const pk = payload.pks[i];
|
|
1866
|
+
this.trackExternalMutationByPk(pk);
|
|
1867
|
+
}
|
|
1868
|
+
};
|
|
1821
1869
|
this.collection = collection;
|
|
1822
1870
|
this.selectPk = opts?.selectPk ?? (() => {
|
|
1823
1871
|
throw new Error(
|
|
1824
1872
|
`[OIMCollectionChangedFieldsWrapper]: selectPk was not provided. Use upsertOneByPk(...) or pass opts.selectPk.`
|
|
1825
1873
|
);
|
|
1826
1874
|
});
|
|
1827
|
-
this.
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
this.
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1875
|
+
this.changedPksEventEmitter = new OIMUpdateEventEmitter(
|
|
1876
|
+
queue,
|
|
1877
|
+
"after_flush"
|
|
1878
|
+
);
|
|
1879
|
+
this.changedFieldsEventEmitter = new OIMUpdateEventEmitter(queue, "after_flush");
|
|
1880
|
+
this.unsubscribeAfterFlush = queue.emitter.on(
|
|
1881
|
+
0 /* AFTER_FLUSH */,
|
|
1882
|
+
this.onAfterFlush
|
|
1883
|
+
);
|
|
1884
|
+
const maybeReactive = collection;
|
|
1885
|
+
this.unsubscribeFromCollectionEmitter = maybeReactive.subscribeOnAnyUpdate ? maybeReactive.subscribeOnAnyUpdate((pks) => {
|
|
1886
|
+
this.onCollectionUpdate({
|
|
1887
|
+
pks
|
|
1888
|
+
});
|
|
1889
|
+
}) : collection.emitter.on(
|
|
1890
|
+
0 /* UPDATE */,
|
|
1891
|
+
this.onCollectionUpdate
|
|
1892
|
+
);
|
|
1837
1893
|
}
|
|
1838
1894
|
upsertOneByPk(pk, patch) {
|
|
1839
|
-
this.
|
|
1840
|
-
|
|
1895
|
+
this.withWrite(() => {
|
|
1896
|
+
this.trackPatch(pk, patch);
|
|
1897
|
+
this.collection.upsertOneByPk(pk, patch);
|
|
1898
|
+
});
|
|
1899
|
+
this.updateEntitySnapshot(pk);
|
|
1841
1900
|
}
|
|
1842
1901
|
upsertOne(entity) {
|
|
1843
|
-
|
|
1844
|
-
this.trackPatch(pk, entity);
|
|
1845
|
-
this.collection.upsertOne(entity);
|
|
1846
|
-
}
|
|
1847
|
-
upsertMany(entities) {
|
|
1848
|
-
for (const entity of entities) {
|
|
1902
|
+
this.withWrite(() => {
|
|
1849
1903
|
const pk = this.selectPk(entity);
|
|
1850
1904
|
this.trackPatch(pk, entity);
|
|
1851
|
-
|
|
1852
|
-
|
|
1905
|
+
this.collection.upsertOne(entity);
|
|
1906
|
+
});
|
|
1907
|
+
this.updateEntitySnapshot(this.selectPk(entity));
|
|
1908
|
+
}
|
|
1909
|
+
upsertMany(entities) {
|
|
1910
|
+
const pks = [];
|
|
1911
|
+
this.withWrite(() => {
|
|
1912
|
+
for (const entity of entities) {
|
|
1913
|
+
const pk = this.selectPk(entity);
|
|
1914
|
+
pks.push(pk);
|
|
1915
|
+
this.trackPatch(pk, entity);
|
|
1916
|
+
}
|
|
1917
|
+
this.collection.upsertMany(entities);
|
|
1918
|
+
});
|
|
1919
|
+
for (let i = 0; i < pks.length; i++) this.updateEntitySnapshot(pks[i]);
|
|
1853
1920
|
}
|
|
1854
1921
|
getChangedFieldsByPk(pk) {
|
|
1855
1922
|
return this.changedFieldsByPk.get(pk) ?? /* @__PURE__ */ new Set();
|
|
@@ -1857,8 +1924,7 @@ var OIMCollectionChangedFieldsWrapper = class {
|
|
|
1857
1924
|
consumeChangedFieldsByPk(pk) {
|
|
1858
1925
|
const existing = this.changedFieldsByPk.get(pk);
|
|
1859
1926
|
if (!existing) return /* @__PURE__ */ new Set();
|
|
1860
|
-
|
|
1861
|
-
return existing;
|
|
1927
|
+
return new Set(existing);
|
|
1862
1928
|
}
|
|
1863
1929
|
getChangedPksByField(field) {
|
|
1864
1930
|
return this.changedPksByField.get(field) ?? /* @__PURE__ */ new Set();
|
|
@@ -1866,8 +1932,7 @@ var OIMCollectionChangedFieldsWrapper = class {
|
|
|
1866
1932
|
consumeChangedPksByField(field) {
|
|
1867
1933
|
const existing = this.changedPksByField.get(field);
|
|
1868
1934
|
if (!existing) return /* @__PURE__ */ new Set();
|
|
1869
|
-
|
|
1870
|
-
return existing;
|
|
1935
|
+
return new Set(existing);
|
|
1871
1936
|
}
|
|
1872
1937
|
clear() {
|
|
1873
1938
|
this.changedFieldsByPk.clear();
|
|
@@ -1876,18 +1941,60 @@ var OIMCollectionChangedFieldsWrapper = class {
|
|
|
1876
1941
|
destroy() {
|
|
1877
1942
|
this.changedPksEventEmitter.destroy();
|
|
1878
1943
|
this.changedFieldsEventEmitter.destroy();
|
|
1879
|
-
this.
|
|
1880
|
-
this.
|
|
1944
|
+
this.unsubscribeAfterFlush();
|
|
1945
|
+
this.unsubscribeFromCollectionEmitter();
|
|
1881
1946
|
this.clear();
|
|
1882
1947
|
}
|
|
1883
|
-
|
|
1884
|
-
if (
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
);
|
|
1948
|
+
withWrite(fn) {
|
|
1949
|
+
if (this.isInWrite) {
|
|
1950
|
+
fn();
|
|
1951
|
+
return;
|
|
1888
1952
|
}
|
|
1889
|
-
|
|
1890
|
-
|
|
1953
|
+
this.isInWrite = true;
|
|
1954
|
+
try {
|
|
1955
|
+
fn();
|
|
1956
|
+
} finally {
|
|
1957
|
+
this.isInWrite = false;
|
|
1958
|
+
}
|
|
1959
|
+
}
|
|
1960
|
+
trackExternalMutationByPk(pk) {
|
|
1961
|
+
const prev = this.lastEntitySnapshotByPk.get(pk);
|
|
1962
|
+
const next = this.collection.getOneByPk(pk);
|
|
1963
|
+
const changedKeys = this.diffChangedKeys(prev, next);
|
|
1964
|
+
this.updateEntitySnapshot(pk);
|
|
1965
|
+
if (changedKeys.length > 0) {
|
|
1966
|
+
this.trackChangedKeys(pk, changedKeys);
|
|
1967
|
+
} else {
|
|
1968
|
+
this.changedPksEventEmitter.markUpdatedKeys([pk]);
|
|
1969
|
+
}
|
|
1970
|
+
}
|
|
1971
|
+
diffChangedKeys(prev, next) {
|
|
1972
|
+
if (!prev && !next) return [];
|
|
1973
|
+
if (!prev && next) return Object.keys(next);
|
|
1974
|
+
if (prev && !next) return Object.keys(prev);
|
|
1975
|
+
const prevObj = prev;
|
|
1976
|
+
const nextObj = next;
|
|
1977
|
+
const keys = /* @__PURE__ */ new Set();
|
|
1978
|
+
Object.keys(prevObj).forEach((k) => keys.add(k));
|
|
1979
|
+
Object.keys(nextObj).forEach((k) => keys.add(k));
|
|
1980
|
+
const changed = [];
|
|
1981
|
+
keys.forEach((k) => {
|
|
1982
|
+
if (prevObj[k] !== nextObj[k])
|
|
1983
|
+
changed.push(k);
|
|
1984
|
+
});
|
|
1985
|
+
return changed;
|
|
1986
|
+
}
|
|
1987
|
+
updateEntitySnapshot(pk) {
|
|
1988
|
+
const entity = this.collection.getOneByPk(pk);
|
|
1989
|
+
if (!entity) {
|
|
1990
|
+
this.lastEntitySnapshotByPk.delete(pk);
|
|
1991
|
+
return;
|
|
1992
|
+
}
|
|
1993
|
+
this.lastEntitySnapshotByPk.set(pk, {
|
|
1994
|
+
...entity
|
|
1995
|
+
});
|
|
1996
|
+
}
|
|
1997
|
+
trackChangedKeys(pk, keys) {
|
|
1891
1998
|
let pkFields = this.changedFieldsByPk.get(pk);
|
|
1892
1999
|
if (!pkFields) {
|
|
1893
2000
|
pkFields = /* @__PURE__ */ new Set();
|
|
@@ -1902,8 +2009,18 @@ var OIMCollectionChangedFieldsWrapper = class {
|
|
|
1902
2009
|
}
|
|
1903
2010
|
fieldPks.add(pk);
|
|
1904
2011
|
}
|
|
1905
|
-
this.
|
|
1906
|
-
this.
|
|
2012
|
+
this.changedPksEventEmitter.markUpdatedKeys([pk]);
|
|
2013
|
+
this.changedFieldsEventEmitter.markUpdatedKeys(keys);
|
|
2014
|
+
}
|
|
2015
|
+
trackPatch(pk, patch) {
|
|
2016
|
+
if (pk === void 0 || pk === null || pk === "") {
|
|
2017
|
+
throw new Error(
|
|
2018
|
+
`[OIMCollectionChangedFieldsWrapper]: PK is required to track changes.`
|
|
2019
|
+
);
|
|
2020
|
+
}
|
|
2021
|
+
const keys = Object.keys(patch);
|
|
2022
|
+
if (keys.length === 0) return;
|
|
2023
|
+
this.trackChangedKeys(pk, keys);
|
|
1907
2024
|
}
|
|
1908
2025
|
};
|
|
1909
2026
|
|
|
@@ -1983,13 +2100,33 @@ var OIMIndexManualOrderedArrayBased = class extends OIMIndexArrayBased {
|
|
|
1983
2100
|
// src/modules/wrapper/index/OIMOrderedListIndexCommandStreamWrapper.ts
|
|
1984
2101
|
var OIMOrderedListIndexCommandStreamWrapper = class {
|
|
1985
2102
|
constructor(queue, index) {
|
|
2103
|
+
this.isInWrite = false;
|
|
1986
2104
|
this.commandsByKey = /* @__PURE__ */ new Map();
|
|
1987
|
-
this.
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
2105
|
+
this.onAfterFlush = () => {
|
|
2106
|
+
this.commandsByKey.clear();
|
|
2107
|
+
};
|
|
2108
|
+
this.onIndexUpdate = (payload) => {
|
|
2109
|
+
if (this.isInWrite) return;
|
|
2110
|
+
if (payload.keys.length === 0) return;
|
|
2111
|
+
for (let i = 0; i < payload.keys.length; i++) {
|
|
2112
|
+
const key = payload.keys[i];
|
|
2113
|
+
const list = this.index.getPksByKey(key);
|
|
2114
|
+
this.appendCommand(key, { type: "set", keys: Array.from(list) });
|
|
2115
|
+
}
|
|
2116
|
+
};
|
|
2117
|
+
this.commandsEventEmitter = new OIMUpdateEventEmitter(
|
|
2118
|
+
queue,
|
|
2119
|
+
"after_flush"
|
|
2120
|
+
);
|
|
1992
2121
|
this.index = index ?? new OIMIndexManualOrderedArrayBased();
|
|
2122
|
+
this.unsubscribeAfterFlush = queue.emitter.on(
|
|
2123
|
+
0 /* AFTER_FLUSH */,
|
|
2124
|
+
this.onAfterFlush
|
|
2125
|
+
);
|
|
2126
|
+
this.unsubscribeFromIndexEmitter = this.index.emitter.on(
|
|
2127
|
+
0 /* UPDATE */,
|
|
2128
|
+
this.onIndexUpdate
|
|
2129
|
+
);
|
|
1993
2130
|
}
|
|
1994
2131
|
getPksByKey(key) {
|
|
1995
2132
|
return this.index.getPksByKey(key);
|
|
@@ -2001,27 +2138,35 @@ var OIMOrderedListIndexCommandStreamWrapper = class {
|
|
|
2001
2138
|
return this.index.getKeys();
|
|
2002
2139
|
}
|
|
2003
2140
|
push(key, itemKey) {
|
|
2004
|
-
|
|
2005
|
-
|
|
2141
|
+
this.withWrite(() => {
|
|
2142
|
+
const index = this.index.push(key, itemKey);
|
|
2143
|
+
this.appendCommand(key, { type: "add", key: itemKey, index });
|
|
2144
|
+
});
|
|
2006
2145
|
}
|
|
2007
2146
|
removeAt(key, index) {
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2147
|
+
this.withWrite(() => {
|
|
2148
|
+
const itemKey = this.index.removeAt(key, index);
|
|
2149
|
+
if (itemKey === void 0) return;
|
|
2150
|
+
this.appendCommand(key, { type: "remove", key: itemKey, index });
|
|
2151
|
+
});
|
|
2011
2152
|
}
|
|
2012
2153
|
move(key, fromIndex, toIndex) {
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2154
|
+
this.withWrite(() => {
|
|
2155
|
+
const itemKey = this.index.move(key, fromIndex, toIndex);
|
|
2156
|
+
if (itemKey === void 0) return;
|
|
2157
|
+
this.appendCommand(key, {
|
|
2158
|
+
type: "move",
|
|
2159
|
+
key: itemKey,
|
|
2160
|
+
fromIndex,
|
|
2161
|
+
toIndex
|
|
2162
|
+
});
|
|
2020
2163
|
});
|
|
2021
2164
|
}
|
|
2022
|
-
|
|
2023
|
-
this.
|
|
2024
|
-
|
|
2165
|
+
set(key, keys) {
|
|
2166
|
+
this.withWrite(() => {
|
|
2167
|
+
this.index.reset(key, keys);
|
|
2168
|
+
this.appendCommand(key, { type: "set", keys });
|
|
2169
|
+
});
|
|
2025
2170
|
}
|
|
2026
2171
|
/**
|
|
2027
2172
|
* Read-only peek at buffered commands without clearing them.
|
|
@@ -2036,8 +2181,7 @@ var OIMOrderedListIndexCommandStreamWrapper = class {
|
|
|
2036
2181
|
consumeCommands(key) {
|
|
2037
2182
|
const cmds = this.commandsByKey.get(key);
|
|
2038
2183
|
if (!cmds || cmds.length === 0) return [];
|
|
2039
|
-
|
|
2040
|
-
return cmds;
|
|
2184
|
+
return cmds.slice();
|
|
2041
2185
|
}
|
|
2042
2186
|
clear(key) {
|
|
2043
2187
|
if (key === void 0) {
|
|
@@ -2050,17 +2194,38 @@ var OIMOrderedListIndexCommandStreamWrapper = class {
|
|
|
2050
2194
|
}
|
|
2051
2195
|
destroy() {
|
|
2052
2196
|
this.commandsEventEmitter.destroy();
|
|
2053
|
-
this.
|
|
2197
|
+
this.unsubscribeAfterFlush();
|
|
2198
|
+
this.unsubscribeFromIndexEmitter();
|
|
2054
2199
|
this.clear();
|
|
2055
2200
|
}
|
|
2201
|
+
withWrite(fn) {
|
|
2202
|
+
if (this.isInWrite) {
|
|
2203
|
+
fn();
|
|
2204
|
+
return;
|
|
2205
|
+
}
|
|
2206
|
+
this.isInWrite = true;
|
|
2207
|
+
try {
|
|
2208
|
+
fn();
|
|
2209
|
+
} finally {
|
|
2210
|
+
this.isInWrite = false;
|
|
2211
|
+
}
|
|
2212
|
+
}
|
|
2056
2213
|
appendCommand(key, cmd) {
|
|
2057
2214
|
let cmds = this.commandsByKey.get(key);
|
|
2058
2215
|
if (!cmds) {
|
|
2059
2216
|
cmds = [];
|
|
2060
2217
|
this.commandsByKey.set(key, cmds);
|
|
2061
2218
|
}
|
|
2062
|
-
|
|
2063
|
-
|
|
2219
|
+
if (cmd.type === "set") {
|
|
2220
|
+
cmds.length = 0;
|
|
2221
|
+
cmds.push(cmd);
|
|
2222
|
+
} else if (cmds.length > 0 && cmds[0].type === "set") {
|
|
2223
|
+
const setCmd = cmds[0];
|
|
2224
|
+
setCmd.keys = Array.from(this.index.getPksByKey(key));
|
|
2225
|
+
} else {
|
|
2226
|
+
cmds.push(cmd);
|
|
2227
|
+
}
|
|
2228
|
+
this.commandsEventEmitter.markUpdatedKeys([key]);
|
|
2064
2229
|
}
|
|
2065
2230
|
};
|
|
2066
2231
|
|
|
@@ -2233,159 +2398,160 @@ var OIMEventQueueSchedulerFactory = class {
|
|
|
2233
2398
|
}
|
|
2234
2399
|
};
|
|
2235
2400
|
|
|
2401
|
+
// src/const/OIMDBSettings.ts
|
|
2402
|
+
var OIMDBSettings = class {
|
|
2403
|
+
};
|
|
2404
|
+
/**
|
|
2405
|
+
* Fixed key used in the manual index to store updated keys set in coalescers.
|
|
2406
|
+
* This constant is exported so users can create their own indexes and pass them to coalescers.
|
|
2407
|
+
*/
|
|
2408
|
+
OIMDBSettings.UPDATED_KEYS_INDEX_KEY = "__updatedKeys__";
|
|
2409
|
+
OIMDBSettings.FLUSHING_KEYS_INDEX_KEY = "__flushingKeys__";
|
|
2410
|
+
|
|
2411
|
+
// src/modules/effect/core/OIMEffectDependencyComputed.ts
|
|
2412
|
+
var OIMEffectDependencyComputed = class {
|
|
2413
|
+
constructor(computed) {
|
|
2414
|
+
this.computed = computed;
|
|
2415
|
+
}
|
|
2416
|
+
subscribe(onUpdate) {
|
|
2417
|
+
return this.computed.emitter.on("update", onUpdate);
|
|
2418
|
+
}
|
|
2419
|
+
};
|
|
2420
|
+
|
|
2236
2421
|
// src/modules/effect/core/OIMEffect.ts
|
|
2237
2422
|
var OIMEffect = class {
|
|
2238
|
-
constructor(
|
|
2239
|
-
this.
|
|
2240
|
-
this.
|
|
2241
|
-
this.
|
|
2242
|
-
this.
|
|
2423
|
+
constructor(runtime, opts) {
|
|
2424
|
+
this.sourceDeps = [];
|
|
2425
|
+
this.computedDeps = [];
|
|
2426
|
+
this.sourceUnsubscribers = [];
|
|
2427
|
+
this.computedUnsubscribers = [];
|
|
2428
|
+
this.isResubscribeEnqueued = false;
|
|
2429
|
+
this.isTemporarilyUnsubscribedForFlush = false;
|
|
2243
2430
|
this.isScheduled = false;
|
|
2244
|
-
this.handleQueueBeforeFlush = () => {
|
|
2245
|
-
this.isInFlush = true;
|
|
2246
|
-
this.hasRunInThisFlush = false;
|
|
2247
|
-
};
|
|
2248
|
-
this.handleQueueAfterFlush = () => {
|
|
2249
|
-
this.isInFlush = false;
|
|
2250
|
-
this.hasRunInThisFlush = false;
|
|
2251
|
-
};
|
|
2252
2431
|
this.runTask = () => {
|
|
2253
2432
|
this.isScheduled = false;
|
|
2254
|
-
|
|
2433
|
+
this.dequeueScheduled = void 0;
|
|
2255
2434
|
this.runOnce();
|
|
2256
2435
|
};
|
|
2257
|
-
this.
|
|
2258
|
-
|
|
2259
|
-
this.
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
this.
|
|
2263
|
-
this.runOnce();
|
|
2264
|
-
return;
|
|
2436
|
+
this.onSourceInvalidate = () => {
|
|
2437
|
+
this.onUpdate?.();
|
|
2438
|
+
if (!this.isTemporarilyUnsubscribedForFlush) {
|
|
2439
|
+
this.isTemporarilyUnsubscribedForFlush = true;
|
|
2440
|
+
this.unsubscribeFromSourceDeps();
|
|
2441
|
+
this.ensureResubscribeAfterFlush();
|
|
2265
2442
|
}
|
|
2266
2443
|
if (this.isScheduled) return;
|
|
2267
2444
|
this.isScheduled = true;
|
|
2268
|
-
this.
|
|
2445
|
+
this.dequeueScheduled = this.runtime.schedule(this.runTask);
|
|
2269
2446
|
};
|
|
2270
|
-
this.
|
|
2271
|
-
|
|
2272
|
-
|
|
2447
|
+
this.onComputedInvalidate = () => {
|
|
2448
|
+
this.onUpdate?.();
|
|
2449
|
+
if (this.isScheduled) return;
|
|
2450
|
+
this.isScheduled = true;
|
|
2451
|
+
this.dequeueScheduled = this.runtime.schedule(this.runTask);
|
|
2452
|
+
};
|
|
2453
|
+
this.onAfterFlush = () => {
|
|
2454
|
+
if (!this.isResubscribeEnqueued) return;
|
|
2455
|
+
this.isResubscribeEnqueued = false;
|
|
2456
|
+
this.dequeueResubscribe = void 0;
|
|
2457
|
+
this.isTemporarilyUnsubscribedForFlush = false;
|
|
2458
|
+
if (this.sourceUnsubscribers.length === 0) {
|
|
2459
|
+
for (const dep of this.sourceDeps) {
|
|
2460
|
+
this.sourceUnsubscribers.push(
|
|
2461
|
+
dep.subscribe(this.onSourceInvalidate)
|
|
2462
|
+
);
|
|
2463
|
+
}
|
|
2464
|
+
}
|
|
2465
|
+
};
|
|
2466
|
+
this.runtime = runtime;
|
|
2467
|
+
this.onUpdate = opts.onUpdate;
|
|
2273
2468
|
this.run = opts.run;
|
|
2274
2469
|
this.deps = opts.deps ?? [];
|
|
2275
|
-
this.queue.emitter.on(
|
|
2276
|
-
1 /* BEFORE_FLUSH */,
|
|
2277
|
-
this.handleQueueBeforeFlush
|
|
2278
|
-
);
|
|
2279
|
-
this.queue.emitter.on(
|
|
2280
|
-
0 /* AFTER_FLUSH */,
|
|
2281
|
-
this.handleQueueAfterFlush
|
|
2282
|
-
);
|
|
2283
2470
|
for (const dep of this.deps) {
|
|
2284
|
-
|
|
2471
|
+
if (dep instanceof OIMEffectDependencyComputed) {
|
|
2472
|
+
this.computedDeps.push(dep);
|
|
2473
|
+
} else {
|
|
2474
|
+
this.sourceDeps.push(dep);
|
|
2475
|
+
}
|
|
2285
2476
|
}
|
|
2477
|
+
this.subscribeToDeps();
|
|
2286
2478
|
}
|
|
2287
2479
|
destroy() {
|
|
2288
|
-
if (this.
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
this.
|
|
2293
|
-
|
|
2294
|
-
this.
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
);
|
|
2480
|
+
if (this.dequeueScheduled) {
|
|
2481
|
+
this.dequeueScheduled();
|
|
2482
|
+
this.dequeueScheduled = void 0;
|
|
2483
|
+
}
|
|
2484
|
+
this.unsubscribeFromAllDeps();
|
|
2485
|
+
if (this.dequeueResubscribe) {
|
|
2486
|
+
this.dequeueResubscribe();
|
|
2487
|
+
this.dequeueResubscribe = void 0;
|
|
2488
|
+
}
|
|
2489
|
+
this.isResubscribeEnqueued = false;
|
|
2490
|
+
this.isTemporarilyUnsubscribedForFlush = false;
|
|
2300
2491
|
}
|
|
2301
2492
|
runOnce() {
|
|
2302
|
-
if (this.isDestroyed) return;
|
|
2303
2493
|
this.run();
|
|
2304
2494
|
}
|
|
2495
|
+
subscribeToDeps() {
|
|
2496
|
+
if (this.sourceUnsubscribers.length > 0 || this.computedUnsubscribers.length > 0)
|
|
2497
|
+
return;
|
|
2498
|
+
for (const dep of this.sourceDeps) {
|
|
2499
|
+
this.sourceUnsubscribers.push(
|
|
2500
|
+
dep.subscribe(this.onSourceInvalidate)
|
|
2501
|
+
);
|
|
2502
|
+
}
|
|
2503
|
+
for (const dep of this.computedDeps) {
|
|
2504
|
+
this.computedUnsubscribers.push(
|
|
2505
|
+
dep.subscribe(this.onComputedInvalidate)
|
|
2506
|
+
);
|
|
2507
|
+
}
|
|
2508
|
+
}
|
|
2509
|
+
unsubscribeFromSourceDeps() {
|
|
2510
|
+
if (this.sourceUnsubscribers.length === 0) return;
|
|
2511
|
+
for (const unsubscribe of this.sourceUnsubscribers) unsubscribe();
|
|
2512
|
+
this.sourceUnsubscribers = [];
|
|
2513
|
+
}
|
|
2514
|
+
unsubscribeFromAllDeps() {
|
|
2515
|
+
this.unsubscribeFromSourceDeps();
|
|
2516
|
+
if (this.computedUnsubscribers.length === 0) return;
|
|
2517
|
+
for (const unsubscribe of this.computedUnsubscribers) unsubscribe();
|
|
2518
|
+
this.computedUnsubscribers = [];
|
|
2519
|
+
}
|
|
2520
|
+
ensureResubscribeAfterFlush() {
|
|
2521
|
+
if (this.isResubscribeEnqueued) return;
|
|
2522
|
+
this.isResubscribeEnqueued = true;
|
|
2523
|
+
this.dequeueResubscribe = this.runtime.scheduleAfterFlush(
|
|
2524
|
+
this.onAfterFlush
|
|
2525
|
+
);
|
|
2526
|
+
}
|
|
2305
2527
|
};
|
|
2306
2528
|
|
|
2307
|
-
// src/modules/effect/enum/EOIMEffectPhase.ts
|
|
2308
|
-
var EOIMEffectPhase = /* @__PURE__ */ ((EOIMEffectPhase2) => {
|
|
2309
|
-
EOIMEffectPhase2["PRE"] = "pre";
|
|
2310
|
-
EOIMEffectPhase2["HANDLERS"] = "handlers";
|
|
2311
|
-
return EOIMEffectPhase2;
|
|
2312
|
-
})(EOIMEffectPhase || {});
|
|
2313
|
-
|
|
2314
2529
|
// src/modules/computed/enum/EOIMComputedEventType.ts
|
|
2315
2530
|
var EOIMComputedEventType = /* @__PURE__ */ ((EOIMComputedEventType2) => {
|
|
2316
2531
|
EOIMComputedEventType2["UPDATE"] = "update";
|
|
2317
2532
|
return EOIMComputedEventType2;
|
|
2318
2533
|
})(EOIMComputedEventType || {});
|
|
2319
2534
|
|
|
2320
|
-
// src/modules/computed/core/OIMUpdateEventCoalescerComputed.ts
|
|
2321
|
-
var OIMUpdateEventCoalescerComputed = class extends OIMUpdateEventCoalescer {
|
|
2322
|
-
constructor(computedEmitter) {
|
|
2323
|
-
super();
|
|
2324
|
-
this.computedEmitter = computedEmitter;
|
|
2325
|
-
this.handleUpdate = (payload) => {
|
|
2326
|
-
this.addUpdatedKeys(payload.keys);
|
|
2327
|
-
};
|
|
2328
|
-
this.computedEmitter.on(
|
|
2329
|
-
"update" /* UPDATE */,
|
|
2330
|
-
this.handleUpdate
|
|
2331
|
-
);
|
|
2332
|
-
}
|
|
2333
|
-
destroy() {
|
|
2334
|
-
this.computedEmitter.off(
|
|
2335
|
-
"update" /* UPDATE */,
|
|
2336
|
-
this.handleUpdate
|
|
2337
|
-
);
|
|
2338
|
-
this.emitter.offAll();
|
|
2339
|
-
this.clearUpdatedKeys();
|
|
2340
|
-
}
|
|
2341
|
-
};
|
|
2342
|
-
|
|
2343
2535
|
// src/modules/computed/core/OIMComputed.ts
|
|
2344
2536
|
var OIMComputed = class {
|
|
2345
|
-
constructor(
|
|
2537
|
+
constructor(runtime, opts) {
|
|
2346
2538
|
this.emitter = new OIMEventEmitter();
|
|
2347
2539
|
this.hasValue = false;
|
|
2348
2540
|
this.isDirty = true;
|
|
2349
|
-
this.
|
|
2350
|
-
this.hasRecomputedInThisFlush = false;
|
|
2351
|
-
this.handleQueueBeforeFlush = () => {
|
|
2352
|
-
this.isInFlush = true;
|
|
2353
|
-
this.hasRecomputedInThisFlush = false;
|
|
2354
|
-
};
|
|
2355
|
-
this.handleQueueAfterFlush = () => {
|
|
2356
|
-
this.isInFlush = false;
|
|
2357
|
-
this.hasRecomputedInThisFlush = false;
|
|
2358
|
-
};
|
|
2359
|
-
this.queue = queue;
|
|
2541
|
+
this.runtime = runtime;
|
|
2360
2542
|
this.compute = opts.compute;
|
|
2361
2543
|
this.compare = opts.compare ?? Object.is;
|
|
2362
2544
|
this.deps = opts.deps ?? [];
|
|
2363
|
-
this.
|
|
2364
|
-
this.
|
|
2365
|
-
|
|
2366
|
-
this.updateEventEmitter = new OIMUpdateEventEmitter({
|
|
2367
|
-
coalescer: this.coalescer,
|
|
2368
|
-
queue: this.queue
|
|
2369
|
-
});
|
|
2370
|
-
this.queue.emitter.on(
|
|
2371
|
-
1 /* BEFORE_FLUSH */,
|
|
2372
|
-
this.handleQueueBeforeFlush
|
|
2373
|
-
);
|
|
2374
|
-
this.queue.emitter.on(
|
|
2375
|
-
0 /* AFTER_FLUSH */,
|
|
2376
|
-
this.handleQueueAfterFlush
|
|
2545
|
+
this.updateEventEmitter = new OIMUpdateEventEmitter(
|
|
2546
|
+
this.runtime.queue,
|
|
2547
|
+
"immediate"
|
|
2377
2548
|
);
|
|
2378
|
-
this.effect = new OIMEffect(this.
|
|
2549
|
+
this.effect = new OIMEffect(this.runtime, {
|
|
2379
2550
|
deps: this.deps,
|
|
2380
|
-
|
|
2381
|
-
onInvalidate: () => {
|
|
2551
|
+
onUpdate: () => {
|
|
2382
2552
|
this.isDirty = true;
|
|
2383
2553
|
},
|
|
2384
2554
|
run: () => {
|
|
2385
|
-
if (this.isInFlush) {
|
|
2386
|
-
if (this.hasRecomputedInThisFlush) return;
|
|
2387
|
-
this.hasRecomputedInThisFlush = true;
|
|
2388
|
-
}
|
|
2389
2555
|
this.recomputeAndEmitIfChanged();
|
|
2390
2556
|
}
|
|
2391
2557
|
});
|
|
@@ -2399,16 +2565,7 @@ var OIMComputed = class {
|
|
|
2399
2565
|
}
|
|
2400
2566
|
destroy() {
|
|
2401
2567
|
this.effect.destroy();
|
|
2402
|
-
this.queue.emitter.off(
|
|
2403
|
-
1 /* BEFORE_FLUSH */,
|
|
2404
|
-
this.handleQueueBeforeFlush
|
|
2405
|
-
);
|
|
2406
|
-
this.queue.emitter.off(
|
|
2407
|
-
0 /* AFTER_FLUSH */,
|
|
2408
|
-
this.handleQueueAfterFlush
|
|
2409
|
-
);
|
|
2410
2568
|
this.updateEventEmitter.destroy();
|
|
2411
|
-
this.coalescer.destroy();
|
|
2412
2569
|
this.emitter.offAll();
|
|
2413
2570
|
}
|
|
2414
2571
|
recomputeAndEmitIfChanged() {
|
|
@@ -2424,6 +2581,7 @@ var OIMComputed = class {
|
|
|
2424
2581
|
this.emitter.emit("update" /* UPDATE */, {
|
|
2425
2582
|
keys: ["value"]
|
|
2426
2583
|
});
|
|
2584
|
+
this.updateEventEmitter.markUpdatedKey("value");
|
|
2427
2585
|
}
|
|
2428
2586
|
};
|
|
2429
2587
|
|
|
@@ -2432,31 +2590,21 @@ function isReadonlyArray(value) {
|
|
|
2432
2590
|
return Array.isArray(value);
|
|
2433
2591
|
}
|
|
2434
2592
|
var OIMEffectDependencyKeyed = class {
|
|
2435
|
-
constructor(
|
|
2436
|
-
this.
|
|
2593
|
+
constructor(subscription, keyOrKeys) {
|
|
2594
|
+
this.subscription = subscription;
|
|
2437
2595
|
if (isReadonlyArray(keyOrKeys)) {
|
|
2438
2596
|
this.keys = keyOrKeys;
|
|
2439
2597
|
} else {
|
|
2440
2598
|
this.key = keyOrKeys;
|
|
2441
2599
|
}
|
|
2442
2600
|
}
|
|
2443
|
-
subscribe(
|
|
2444
|
-
const isPre = phase === "pre" /* PRE */;
|
|
2601
|
+
subscribe(onUpdate) {
|
|
2445
2602
|
if (this.keys !== void 0) {
|
|
2446
|
-
return
|
|
2447
|
-
this.keys,
|
|
2448
|
-
onInvalidate
|
|
2449
|
-
) : this.updateEventEmitter.subscribeOnKeys(
|
|
2450
|
-
this.keys,
|
|
2451
|
-
onInvalidate
|
|
2452
|
-
);
|
|
2603
|
+
return this.subscription.subscribeOnKeys(this.keys, onUpdate);
|
|
2453
2604
|
}
|
|
2454
2605
|
if (this.key === void 0) return () => {
|
|
2455
2606
|
};
|
|
2456
|
-
return
|
|
2457
|
-
this.key,
|
|
2458
|
-
onInvalidate
|
|
2459
|
-
) : this.updateEventEmitter.subscribeOnKey(this.key, onInvalidate);
|
|
2607
|
+
return this.subscription.subscribeOnKey(this.key, onUpdate);
|
|
2460
2608
|
}
|
|
2461
2609
|
};
|
|
2462
2610
|
|
|
@@ -2464,12 +2612,12 @@ var OIMEffectDependencyKeyed = class {
|
|
|
2464
2612
|
var OIMEffectDependencyKeyedObject = class {
|
|
2465
2613
|
constructor(object, keyOrKeys) {
|
|
2466
2614
|
this.dep = new OIMEffectDependencyKeyed(
|
|
2467
|
-
object
|
|
2615
|
+
object,
|
|
2468
2616
|
keyOrKeys
|
|
2469
2617
|
);
|
|
2470
2618
|
}
|
|
2471
|
-
subscribe(
|
|
2472
|
-
return this.dep.subscribe(
|
|
2619
|
+
subscribe(onUpdate) {
|
|
2620
|
+
return this.dep.subscribe(onUpdate);
|
|
2473
2621
|
}
|
|
2474
2622
|
};
|
|
2475
2623
|
|
|
@@ -2477,12 +2625,12 @@ var OIMEffectDependencyKeyedObject = class {
|
|
|
2477
2625
|
var OIMEffectDependencyKeyedCollection = class {
|
|
2478
2626
|
constructor(collection, pkOrPks) {
|
|
2479
2627
|
this.dep = new OIMEffectDependencyKeyed(
|
|
2480
|
-
collection
|
|
2628
|
+
collection,
|
|
2481
2629
|
pkOrPks
|
|
2482
2630
|
);
|
|
2483
2631
|
}
|
|
2484
|
-
subscribe(
|
|
2485
|
-
return this.dep.subscribe(
|
|
2632
|
+
subscribe(onUpdate) {
|
|
2633
|
+
return this.dep.subscribe(onUpdate);
|
|
2486
2634
|
}
|
|
2487
2635
|
};
|
|
2488
2636
|
|
|
@@ -2490,45 +2638,592 @@ var OIMEffectDependencyKeyedCollection = class {
|
|
|
2490
2638
|
var OIMEffectDependencyKeyedIndex = class {
|
|
2491
2639
|
constructor(index, keyOrKeys) {
|
|
2492
2640
|
this.dep = new OIMEffectDependencyKeyed(
|
|
2493
|
-
index
|
|
2641
|
+
index,
|
|
2494
2642
|
keyOrKeys
|
|
2495
2643
|
);
|
|
2496
2644
|
}
|
|
2497
|
-
subscribe(
|
|
2498
|
-
return this.dep.subscribe(
|
|
2645
|
+
subscribe(onUpdate) {
|
|
2646
|
+
return this.dep.subscribe(onUpdate);
|
|
2499
2647
|
}
|
|
2500
2648
|
};
|
|
2501
2649
|
|
|
2502
|
-
// src/modules/
|
|
2503
|
-
var
|
|
2504
|
-
constructor(
|
|
2505
|
-
this.
|
|
2650
|
+
// src/modules/selector/core/OIMSelector.ts
|
|
2651
|
+
var OIMSelector = class {
|
|
2652
|
+
constructor(runtime, sourceDeps, computedDeps = []) {
|
|
2653
|
+
this.runtime = runtime;
|
|
2654
|
+
this.sourceDeps = sourceDeps;
|
|
2655
|
+
this.computedDeps = computedDeps;
|
|
2656
|
+
this.listeners = /* @__PURE__ */ new Set();
|
|
2657
|
+
this.sourceUnsubscribers = [];
|
|
2658
|
+
this.computedUnsubscribers = [];
|
|
2659
|
+
this.isResubscribeEnqueued = false;
|
|
2660
|
+
this.isTemporarilyUnsubscribedForFlush = false;
|
|
2661
|
+
this.isDeliveryEnqueued = false;
|
|
2662
|
+
this.hasLastValue = false;
|
|
2663
|
+
this.onSourceInvalidate = () => {
|
|
2664
|
+
if (this.listeners.size === 0) return;
|
|
2665
|
+
if (!this.isTemporarilyUnsubscribedForFlush) {
|
|
2666
|
+
this.isTemporarilyUnsubscribedForFlush = true;
|
|
2667
|
+
this.unsubscribeFromSourceDeps();
|
|
2668
|
+
this.ensureResubscribeAfterFlush();
|
|
2669
|
+
}
|
|
2670
|
+
if (this.isDeliveryEnqueued) return;
|
|
2671
|
+
this.isDeliveryEnqueued = true;
|
|
2672
|
+
this.dequeueDelivery = this.runtime.schedule(this.deliver);
|
|
2673
|
+
};
|
|
2674
|
+
this.onComputedInvalidate = () => {
|
|
2675
|
+
if (this.listeners.size === 0) return;
|
|
2676
|
+
if (this.isDeliveryEnqueued) return;
|
|
2677
|
+
this.isDeliveryEnqueued = true;
|
|
2678
|
+
this.dequeueDelivery = this.runtime.schedule(this.deliver);
|
|
2679
|
+
};
|
|
2680
|
+
this.deliver = () => {
|
|
2681
|
+
this.isDeliveryEnqueued = false;
|
|
2682
|
+
this.dequeueDelivery = void 0;
|
|
2683
|
+
if (this.listeners.size === 0) return;
|
|
2684
|
+
const next = this.getValue();
|
|
2685
|
+
if (this.hasLastValue && this.areEqual(this.lastValue, next)) return;
|
|
2686
|
+
this.setLastValue(next);
|
|
2687
|
+
const snapshot = Array.from(this.listeners);
|
|
2688
|
+
for (let i = 0; i < snapshot.length; i++) {
|
|
2689
|
+
const listener = snapshot[i];
|
|
2690
|
+
if (this.listeners.has(listener)) listener(next);
|
|
2691
|
+
}
|
|
2692
|
+
};
|
|
2693
|
+
this.onAfterFlush = () => {
|
|
2694
|
+
if (!this.isResubscribeEnqueued) return;
|
|
2695
|
+
this.isResubscribeEnqueued = false;
|
|
2696
|
+
this.dequeueResubscribe = void 0;
|
|
2697
|
+
if (this.listeners.size === 0) return;
|
|
2698
|
+
this.isTemporarilyUnsubscribedForFlush = false;
|
|
2699
|
+
if (this.sourceUnsubscribers.length === 0) {
|
|
2700
|
+
for (const dep of this.sourceDeps) {
|
|
2701
|
+
this.sourceUnsubscribers.push(
|
|
2702
|
+
dep.subscribe(this.onSourceInvalidate)
|
|
2703
|
+
);
|
|
2704
|
+
}
|
|
2705
|
+
}
|
|
2706
|
+
};
|
|
2707
|
+
}
|
|
2708
|
+
get queue() {
|
|
2709
|
+
return this.runtime.queue;
|
|
2710
|
+
}
|
|
2711
|
+
/**
|
|
2712
|
+
* Start watching this selector. The callback is called immediately with the current value,
|
|
2713
|
+
* then coalesced and delivered on `queue.flush()` when the selector invalidates.
|
|
2714
|
+
*/
|
|
2715
|
+
watch(onValue) {
|
|
2716
|
+
this.listeners.add(onValue);
|
|
2717
|
+
if (this.listeners.size === 1) {
|
|
2718
|
+
this.subscribeToDeps();
|
|
2719
|
+
}
|
|
2720
|
+
const current = this.getValue();
|
|
2721
|
+
this.setLastValue(current);
|
|
2722
|
+
onValue(current);
|
|
2723
|
+
return () => {
|
|
2724
|
+
this.listeners.delete(onValue);
|
|
2725
|
+
if (this.listeners.size > 0) return;
|
|
2726
|
+
this.unsubscribeFromAllDeps();
|
|
2727
|
+
if (this.dequeueResubscribe) {
|
|
2728
|
+
this.dequeueResubscribe();
|
|
2729
|
+
this.dequeueResubscribe = void 0;
|
|
2730
|
+
}
|
|
2731
|
+
this.isResubscribeEnqueued = false;
|
|
2732
|
+
this.isTemporarilyUnsubscribedForFlush = false;
|
|
2733
|
+
if (this.dequeueDelivery) {
|
|
2734
|
+
this.dequeueDelivery();
|
|
2735
|
+
this.dequeueDelivery = void 0;
|
|
2736
|
+
}
|
|
2737
|
+
this.isDeliveryEnqueued = false;
|
|
2738
|
+
this.hasLastValue = false;
|
|
2739
|
+
};
|
|
2506
2740
|
}
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
|
|
2741
|
+
areEqual(prev, next) {
|
|
2742
|
+
return Object.is(prev, next);
|
|
2743
|
+
}
|
|
2744
|
+
setLastValue(value) {
|
|
2745
|
+
this.lastValue = value;
|
|
2746
|
+
this.hasLastValue = true;
|
|
2747
|
+
}
|
|
2748
|
+
subscribeToDeps() {
|
|
2749
|
+
if (this.sourceUnsubscribers.length > 0 || this.computedUnsubscribers.length > 0)
|
|
2750
|
+
return;
|
|
2751
|
+
for (const dep of this.sourceDeps) {
|
|
2752
|
+
this.sourceUnsubscribers.push(
|
|
2753
|
+
dep.subscribe(this.onSourceInvalidate)
|
|
2754
|
+
);
|
|
2510
2755
|
}
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2756
|
+
for (const dep of this.computedDeps) {
|
|
2757
|
+
this.computedUnsubscribers.push(
|
|
2758
|
+
dep.subscribe(this.onComputedInvalidate)
|
|
2759
|
+
);
|
|
2760
|
+
}
|
|
2761
|
+
}
|
|
2762
|
+
unsubscribeFromSourceDeps() {
|
|
2763
|
+
if (this.sourceUnsubscribers.length === 0) return;
|
|
2764
|
+
for (const unsub of this.sourceUnsubscribers) unsub();
|
|
2765
|
+
this.sourceUnsubscribers = [];
|
|
2766
|
+
}
|
|
2767
|
+
unsubscribeFromAllDeps() {
|
|
2768
|
+
this.unsubscribeFromSourceDeps();
|
|
2769
|
+
if (this.computedUnsubscribers.length === 0) return;
|
|
2770
|
+
for (const unsub of this.computedUnsubscribers) unsub();
|
|
2771
|
+
this.computedUnsubscribers = [];
|
|
2772
|
+
}
|
|
2773
|
+
ensureResubscribeAfterFlush() {
|
|
2774
|
+
if (this.isResubscribeEnqueued) return;
|
|
2775
|
+
this.isResubscribeEnqueued = true;
|
|
2776
|
+
this.dequeueResubscribe = this.runtime.scheduleAfterFlush(
|
|
2777
|
+
this.onAfterFlush
|
|
2514
2778
|
);
|
|
2515
2779
|
}
|
|
2516
2780
|
};
|
|
2781
|
+
|
|
2782
|
+
// src/modules/selector/core/OIMSelectorSourceDependencyUpdateEventEmitterKey.ts
|
|
2783
|
+
var OIMSelectorSourceDependencyUpdateEventEmitterKey = class {
|
|
2784
|
+
constructor(subscription, key) {
|
|
2785
|
+
this.subscription = subscription;
|
|
2786
|
+
this.key = key;
|
|
2787
|
+
}
|
|
2788
|
+
subscribe(onUpdate) {
|
|
2789
|
+
return this.subscription.subscribeOnKey(this.key, onUpdate);
|
|
2790
|
+
}
|
|
2791
|
+
};
|
|
2792
|
+
|
|
2793
|
+
// src/modules/selector/core/OIMCollectionByPkSelector.ts
|
|
2794
|
+
var OIMCollectionByPkSelector = class extends OIMSelector {
|
|
2795
|
+
constructor(runtime, collection, pk) {
|
|
2796
|
+
super(runtime, [
|
|
2797
|
+
new OIMSelectorSourceDependencyUpdateEventEmitterKey(
|
|
2798
|
+
collection,
|
|
2799
|
+
pk
|
|
2800
|
+
)
|
|
2801
|
+
]);
|
|
2802
|
+
this.collection = collection;
|
|
2803
|
+
this.pk = pk;
|
|
2804
|
+
}
|
|
2805
|
+
getValue() {
|
|
2806
|
+
return this.collection.getOneByPk(this.pk);
|
|
2807
|
+
}
|
|
2808
|
+
};
|
|
2809
|
+
|
|
2810
|
+
// src/modules/selector/core/OIMSelectorSourceDependencyUpdateEventEmitterKeys.ts
|
|
2811
|
+
var OIMSelectorSourceDependencyUpdateEventEmitterKeys = class {
|
|
2812
|
+
constructor(subscription, keys) {
|
|
2813
|
+
this.subscription = subscription;
|
|
2814
|
+
this.keys = keys;
|
|
2815
|
+
}
|
|
2816
|
+
subscribe(onUpdate) {
|
|
2817
|
+
return this.subscription.subscribeOnKeys(this.keys, onUpdate);
|
|
2818
|
+
}
|
|
2819
|
+
};
|
|
2820
|
+
|
|
2821
|
+
// src/modules/selector/core/OIMCollectionByPksSelector.ts
|
|
2822
|
+
var OIMCollectionByPksSelector = class extends OIMSelector {
|
|
2823
|
+
constructor(runtime, collection, pks) {
|
|
2824
|
+
super(runtime, [
|
|
2825
|
+
new OIMSelectorSourceDependencyUpdateEventEmitterKeys(
|
|
2826
|
+
collection,
|
|
2827
|
+
pks
|
|
2828
|
+
)
|
|
2829
|
+
]);
|
|
2830
|
+
this.collection = collection;
|
|
2831
|
+
this.pks = pks;
|
|
2832
|
+
}
|
|
2833
|
+
getValue() {
|
|
2834
|
+
return this.pks.map((pk) => this.collection.getOneByPk(pk));
|
|
2835
|
+
}
|
|
2836
|
+
areEqual(prev, next) {
|
|
2837
|
+
if (prev === next) return true;
|
|
2838
|
+
if (prev.length !== next.length) return false;
|
|
2839
|
+
for (let i = 0; i < prev.length; i++) {
|
|
2840
|
+
if (prev[i] !== next[i]) return false;
|
|
2841
|
+
}
|
|
2842
|
+
return true;
|
|
2843
|
+
}
|
|
2844
|
+
};
|
|
2845
|
+
|
|
2846
|
+
// src/modules/selector/core/OIMObjectValueByKeySelector.ts
|
|
2847
|
+
var OIMObjectValueByKeySelector = class extends OIMSelector {
|
|
2848
|
+
constructor(runtime, obj, key) {
|
|
2849
|
+
super(runtime, [
|
|
2850
|
+
new OIMSelectorSourceDependencyUpdateEventEmitterKey(
|
|
2851
|
+
obj,
|
|
2852
|
+
key
|
|
2853
|
+
)
|
|
2854
|
+
]);
|
|
2855
|
+
this.obj = obj;
|
|
2856
|
+
this.key = key;
|
|
2857
|
+
}
|
|
2858
|
+
getValue() {
|
|
2859
|
+
return this.obj.get(this.key);
|
|
2860
|
+
}
|
|
2861
|
+
};
|
|
2862
|
+
|
|
2863
|
+
// src/modules/selector/core/OIMObjectValuesByKeysSelector.ts
|
|
2864
|
+
var OIMObjectValuesByKeysSelector = class extends OIMSelector {
|
|
2865
|
+
constructor(runtime, obj, keys) {
|
|
2866
|
+
super(runtime, [
|
|
2867
|
+
new OIMSelectorSourceDependencyUpdateEventEmitterKeys(
|
|
2868
|
+
obj,
|
|
2869
|
+
keys
|
|
2870
|
+
)
|
|
2871
|
+
]);
|
|
2872
|
+
this.obj = obj;
|
|
2873
|
+
this.keys = keys;
|
|
2874
|
+
}
|
|
2875
|
+
getValue() {
|
|
2876
|
+
return this.keys.map((k) => this.obj.get(k));
|
|
2877
|
+
}
|
|
2878
|
+
areEqual(prev, next) {
|
|
2879
|
+
if (prev === next) return true;
|
|
2880
|
+
if (prev.length !== next.length) return false;
|
|
2881
|
+
for (let i = 0; i < prev.length; i++) {
|
|
2882
|
+
if (prev[i] !== next[i]) return false;
|
|
2883
|
+
}
|
|
2884
|
+
return true;
|
|
2885
|
+
}
|
|
2886
|
+
};
|
|
2887
|
+
|
|
2888
|
+
// src/modules/selector/core/OIMIndexPksByKeySetBasedSelector.ts
|
|
2889
|
+
var OIMIndexPksByKeySetBasedSelector = class extends OIMSelector {
|
|
2890
|
+
constructor(runtime, reactiveIndex, key) {
|
|
2891
|
+
super(runtime, [
|
|
2892
|
+
new OIMSelectorSourceDependencyUpdateEventEmitterKey(
|
|
2893
|
+
reactiveIndex,
|
|
2894
|
+
key
|
|
2895
|
+
)
|
|
2896
|
+
]);
|
|
2897
|
+
this.reactiveIndex = reactiveIndex;
|
|
2898
|
+
this.key = key;
|
|
2899
|
+
}
|
|
2900
|
+
getValue() {
|
|
2901
|
+
return this.reactiveIndex.getPksByKey(this.key);
|
|
2902
|
+
}
|
|
2903
|
+
};
|
|
2904
|
+
|
|
2905
|
+
// src/modules/selector/core/OIMIndexPksByKeyArrayBasedSelector.ts
|
|
2906
|
+
var OIMIndexPksByKeyArrayBasedSelector = class extends OIMSelector {
|
|
2907
|
+
constructor(runtime, reactiveIndex, key) {
|
|
2908
|
+
super(runtime, [
|
|
2909
|
+
new OIMSelectorSourceDependencyUpdateEventEmitterKey(
|
|
2910
|
+
reactiveIndex,
|
|
2911
|
+
key
|
|
2912
|
+
)
|
|
2913
|
+
]);
|
|
2914
|
+
this.reactiveIndex = reactiveIndex;
|
|
2915
|
+
this.key = key;
|
|
2916
|
+
}
|
|
2917
|
+
getValue() {
|
|
2918
|
+
return this.reactiveIndex.getPksByKey(this.key);
|
|
2919
|
+
}
|
|
2920
|
+
areEqual(prev, next) {
|
|
2921
|
+
if (prev === next) return true;
|
|
2922
|
+
if (prev.length !== next.length) return false;
|
|
2923
|
+
for (let i = 0; i < prev.length; i++)
|
|
2924
|
+
if (prev[i] !== next[i]) return false;
|
|
2925
|
+
return true;
|
|
2926
|
+
}
|
|
2927
|
+
};
|
|
2928
|
+
|
|
2929
|
+
// src/modules/selector/core/OIMIndexPksByKeysSetBasedSelector.ts
|
|
2930
|
+
var OIMIndexPksByKeysSetBasedSelector = class extends OIMSelector {
|
|
2931
|
+
constructor(runtime, reactiveIndex, keys) {
|
|
2932
|
+
super(runtime, [
|
|
2933
|
+
new OIMSelectorSourceDependencyUpdateEventEmitterKeys(
|
|
2934
|
+
reactiveIndex,
|
|
2935
|
+
keys
|
|
2936
|
+
)
|
|
2937
|
+
]);
|
|
2938
|
+
this.reactiveIndex = reactiveIndex;
|
|
2939
|
+
this.keys = keys;
|
|
2940
|
+
}
|
|
2941
|
+
getValue() {
|
|
2942
|
+
return this.keys.map((key) => Array.from(this.reactiveIndex.getPksByKey(key))).flat();
|
|
2943
|
+
}
|
|
2944
|
+
areEqual(prev, next) {
|
|
2945
|
+
if (prev === next) return true;
|
|
2946
|
+
if (prev.length !== next.length) return false;
|
|
2947
|
+
for (let i = 0; i < prev.length; i++)
|
|
2948
|
+
if (prev[i] !== next[i]) return false;
|
|
2949
|
+
return true;
|
|
2950
|
+
}
|
|
2951
|
+
};
|
|
2952
|
+
|
|
2953
|
+
// src/modules/selector/core/OIMIndexPksByKeysArrayBasedSelector.ts
|
|
2954
|
+
var OIMIndexPksByKeysArrayBasedSelector = class extends OIMSelector {
|
|
2955
|
+
constructor(runtime, reactiveIndex, keys) {
|
|
2956
|
+
super(runtime, [
|
|
2957
|
+
new OIMSelectorSourceDependencyUpdateEventEmitterKeys(
|
|
2958
|
+
reactiveIndex,
|
|
2959
|
+
keys
|
|
2960
|
+
)
|
|
2961
|
+
]);
|
|
2962
|
+
this.reactiveIndex = reactiveIndex;
|
|
2963
|
+
this.keys = keys;
|
|
2964
|
+
}
|
|
2965
|
+
getValue() {
|
|
2966
|
+
return this.keys.map((key) => this.reactiveIndex.getPksByKey(key)).flat();
|
|
2967
|
+
}
|
|
2968
|
+
areEqual(prev, next) {
|
|
2969
|
+
if (prev === next) return true;
|
|
2970
|
+
if (prev.length !== next.length) return false;
|
|
2971
|
+
for (let i = 0; i < prev.length; i++)
|
|
2972
|
+
if (prev[i] !== next[i]) return false;
|
|
2973
|
+
return true;
|
|
2974
|
+
}
|
|
2975
|
+
};
|
|
2976
|
+
|
|
2977
|
+
// src/modules/selector/core/OIMSelectorSourceDependencyEntitiesByIndexKeySetBased.ts
|
|
2978
|
+
var OIMSelectorSourceDependencyEntitiesByIndexKeySetBased = class {
|
|
2979
|
+
constructor(collection, reactiveIndex, key) {
|
|
2980
|
+
this.collection = collection;
|
|
2981
|
+
this.reactiveIndex = reactiveIndex;
|
|
2982
|
+
this.key = key;
|
|
2983
|
+
this.currentPks = [];
|
|
2984
|
+
}
|
|
2985
|
+
subscribe(onUpdate) {
|
|
2986
|
+
const resubscribeCollection = () => {
|
|
2987
|
+
const nextPks = Array.from(
|
|
2988
|
+
this.reactiveIndex.getPksByKey(this.key)
|
|
2989
|
+
);
|
|
2990
|
+
if (this.sameArray(this.currentPks, nextPks)) return;
|
|
2991
|
+
this.unsubscribeFromCollectionKeys?.();
|
|
2992
|
+
this.unsubscribeFromCollectionKeys = void 0;
|
|
2993
|
+
this.currentPks = nextPks;
|
|
2994
|
+
if (this.currentPks.length === 0) return;
|
|
2995
|
+
this.unsubscribeFromCollectionKeys = this.collection.subscribeOnKeys(this.currentPks, onUpdate);
|
|
2996
|
+
};
|
|
2997
|
+
const onIndexUpdate = () => {
|
|
2998
|
+
resubscribeCollection();
|
|
2999
|
+
onUpdate();
|
|
3000
|
+
};
|
|
3001
|
+
resubscribeCollection();
|
|
3002
|
+
const unsubscribeFromIndex = this.reactiveIndex.subscribeOnKey(
|
|
3003
|
+
this.key,
|
|
3004
|
+
onIndexUpdate
|
|
3005
|
+
);
|
|
3006
|
+
return () => {
|
|
3007
|
+
unsubscribeFromIndex();
|
|
3008
|
+
this.unsubscribeFromCollectionKeys?.();
|
|
3009
|
+
this.unsubscribeFromCollectionKeys = void 0;
|
|
3010
|
+
this.currentPks = [];
|
|
3011
|
+
};
|
|
3012
|
+
}
|
|
3013
|
+
sameArray(a, b) {
|
|
3014
|
+
if (a === b) return true;
|
|
3015
|
+
if (a.length !== b.length) return false;
|
|
3016
|
+
for (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return false;
|
|
3017
|
+
return true;
|
|
3018
|
+
}
|
|
3019
|
+
};
|
|
3020
|
+
|
|
3021
|
+
// src/modules/selector/core/OIMEntitiesByIndexKeySetBasedSelector.ts
|
|
3022
|
+
var OIMEntitiesByIndexKeySetBasedSelector = class extends OIMSelector {
|
|
3023
|
+
constructor(runtime, collection, reactiveIndex, key) {
|
|
3024
|
+
super(runtime, [
|
|
3025
|
+
new OIMSelectorSourceDependencyEntitiesByIndexKeySetBased(collection, reactiveIndex, key)
|
|
3026
|
+
]);
|
|
3027
|
+
this.collection = collection;
|
|
3028
|
+
this.reactiveIndex = reactiveIndex;
|
|
3029
|
+
this.key = key;
|
|
3030
|
+
}
|
|
3031
|
+
getValue() {
|
|
3032
|
+
const pks = Array.from(this.reactiveIndex.getPksByKey(this.key));
|
|
3033
|
+
return pks.map((pk) => this.collection.getOneByPk(pk));
|
|
3034
|
+
}
|
|
3035
|
+
areEqual(prev, next) {
|
|
3036
|
+
if (prev === next) return true;
|
|
3037
|
+
if (prev.length !== next.length) return false;
|
|
3038
|
+
for (let i = 0; i < prev.length; i++)
|
|
3039
|
+
if (prev[i] !== next[i]) return false;
|
|
3040
|
+
return true;
|
|
3041
|
+
}
|
|
3042
|
+
};
|
|
3043
|
+
|
|
3044
|
+
// src/modules/selector/core/OIMSelectorSourceDependencyEntitiesByIndexKeyArrayBased.ts
|
|
3045
|
+
var OIMSelectorSourceDependencyEntitiesByIndexKeyArrayBased = class {
|
|
3046
|
+
constructor(collection, reactiveIndex, key) {
|
|
3047
|
+
this.collection = collection;
|
|
3048
|
+
this.reactiveIndex = reactiveIndex;
|
|
3049
|
+
this.key = key;
|
|
3050
|
+
this.currentPks = [];
|
|
3051
|
+
}
|
|
3052
|
+
subscribe(onUpdate) {
|
|
3053
|
+
const resubscribeCollection = () => {
|
|
3054
|
+
const nextPks = this.reactiveIndex.getPksByKey(this.key);
|
|
3055
|
+
if (this.sameArray(this.currentPks, nextPks)) return;
|
|
3056
|
+
this.unsubscribeFromCollectionKeys?.();
|
|
3057
|
+
this.unsubscribeFromCollectionKeys = void 0;
|
|
3058
|
+
this.currentPks = nextPks;
|
|
3059
|
+
if (this.currentPks.length === 0) return;
|
|
3060
|
+
this.unsubscribeFromCollectionKeys = this.collection.subscribeOnKeys(this.currentPks, onUpdate);
|
|
3061
|
+
};
|
|
3062
|
+
const onIndexUpdate = () => {
|
|
3063
|
+
resubscribeCollection();
|
|
3064
|
+
onUpdate();
|
|
3065
|
+
};
|
|
3066
|
+
resubscribeCollection();
|
|
3067
|
+
const unsubscribeFromIndex = this.reactiveIndex.subscribeOnKey(
|
|
3068
|
+
this.key,
|
|
3069
|
+
onIndexUpdate
|
|
3070
|
+
);
|
|
3071
|
+
return () => {
|
|
3072
|
+
unsubscribeFromIndex();
|
|
3073
|
+
this.unsubscribeFromCollectionKeys?.();
|
|
3074
|
+
this.unsubscribeFromCollectionKeys = void 0;
|
|
3075
|
+
this.currentPks = [];
|
|
3076
|
+
};
|
|
3077
|
+
}
|
|
3078
|
+
sameArray(a, b) {
|
|
3079
|
+
if (a === b) return true;
|
|
3080
|
+
if (a.length !== b.length) return false;
|
|
3081
|
+
for (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return false;
|
|
3082
|
+
return true;
|
|
3083
|
+
}
|
|
3084
|
+
};
|
|
3085
|
+
|
|
3086
|
+
// src/modules/selector/core/OIMEntitiesByIndexKeyArrayBasedSelector.ts
|
|
3087
|
+
var OIMEntitiesByIndexKeyArrayBasedSelector = class extends OIMSelector {
|
|
3088
|
+
constructor(runtime, collection, reactiveIndex, key) {
|
|
3089
|
+
super(runtime, [
|
|
3090
|
+
new OIMSelectorSourceDependencyEntitiesByIndexKeyArrayBased(collection, reactiveIndex, key)
|
|
3091
|
+
]);
|
|
3092
|
+
this.collection = collection;
|
|
3093
|
+
this.reactiveIndex = reactiveIndex;
|
|
3094
|
+
this.key = key;
|
|
3095
|
+
}
|
|
3096
|
+
getValue() {
|
|
3097
|
+
const pks = this.reactiveIndex.getPksByKey(this.key);
|
|
3098
|
+
return pks.map((pk) => this.collection.getOneByPk(pk));
|
|
3099
|
+
}
|
|
3100
|
+
areEqual(prev, next) {
|
|
3101
|
+
if (prev === next) return true;
|
|
3102
|
+
if (prev.length !== next.length) return false;
|
|
3103
|
+
for (let i = 0; i < prev.length; i++)
|
|
3104
|
+
if (prev[i] !== next[i]) return false;
|
|
3105
|
+
return true;
|
|
3106
|
+
}
|
|
3107
|
+
};
|
|
3108
|
+
|
|
3109
|
+
// src/modules/computative/core/OIMComputativeRuntime.ts
|
|
3110
|
+
var OIMComputativeRuntime = class {
|
|
3111
|
+
constructor(queue) {
|
|
3112
|
+
this.queue = queue;
|
|
3113
|
+
this.isFlushScheduled = false;
|
|
3114
|
+
this.isFlushing = false;
|
|
3115
|
+
this.minLevel = Infinity;
|
|
3116
|
+
this.maxLevel = -Infinity;
|
|
3117
|
+
this.dirtyByLevel = /* @__PURE__ */ new Map();
|
|
3118
|
+
this.afterFlushTasks = /* @__PURE__ */ new Set();
|
|
3119
|
+
this.queue.emitter.on(0 /* AFTER_FLUSH */, () => {
|
|
3120
|
+
if (!this.isFlushScheduled) return;
|
|
3121
|
+
this.flush();
|
|
3122
|
+
});
|
|
3123
|
+
}
|
|
3124
|
+
/**
|
|
3125
|
+
* Schedule a one-shot task to run on the next `queue.flush()` (AFTER_FLUSH),
|
|
3126
|
+
* ordered by `level` ascending.
|
|
3127
|
+
*/
|
|
3128
|
+
schedule(task, level = 0) {
|
|
3129
|
+
let isActive = true;
|
|
3130
|
+
const wrapped = () => {
|
|
3131
|
+
if (!isActive) return;
|
|
3132
|
+
task();
|
|
3133
|
+
};
|
|
3134
|
+
let bucket = this.dirtyByLevel.get(level);
|
|
3135
|
+
if (!bucket) {
|
|
3136
|
+
bucket = /* @__PURE__ */ new Set();
|
|
3137
|
+
this.dirtyByLevel.set(level, bucket);
|
|
3138
|
+
}
|
|
3139
|
+
bucket.add(wrapped);
|
|
3140
|
+
if (level < this.minLevel) this.minLevel = level;
|
|
3141
|
+
if (level > this.maxLevel) this.maxLevel = level;
|
|
3142
|
+
if (!this.isFlushing) this.isFlushScheduled = true;
|
|
3143
|
+
return () => {
|
|
3144
|
+
if (!isActive) return;
|
|
3145
|
+
isActive = false;
|
|
3146
|
+
bucket.delete(wrapped);
|
|
3147
|
+
};
|
|
3148
|
+
}
|
|
3149
|
+
/**
|
|
3150
|
+
* Run once at the start of the next runtime flush (i.e. after queue.flush()).
|
|
3151
|
+
* Useful for resubscribing dependencies exactly once per source flush.
|
|
3152
|
+
*/
|
|
3153
|
+
scheduleAfterFlush(task) {
|
|
3154
|
+
let isActive = true;
|
|
3155
|
+
const wrapped = () => {
|
|
3156
|
+
if (!isActive) return;
|
|
3157
|
+
task();
|
|
3158
|
+
};
|
|
3159
|
+
this.afterFlushTasks.add(wrapped);
|
|
3160
|
+
if (!this.isFlushing) this.isFlushScheduled = true;
|
|
3161
|
+
return () => {
|
|
3162
|
+
if (!isActive) return;
|
|
3163
|
+
isActive = false;
|
|
3164
|
+
this.afterFlushTasks.delete(wrapped);
|
|
3165
|
+
};
|
|
3166
|
+
}
|
|
3167
|
+
flush() {
|
|
3168
|
+
this.isFlushScheduled = false;
|
|
3169
|
+
if (this.dirtyByLevel.size === 0 && this.afterFlushTasks.size === 0)
|
|
3170
|
+
return;
|
|
3171
|
+
this.isFlushing = true;
|
|
3172
|
+
try {
|
|
3173
|
+
if (this.afterFlushTasks.size > 0) {
|
|
3174
|
+
const snapshot = Array.from(this.afterFlushTasks);
|
|
3175
|
+
this.afterFlushTasks.clear();
|
|
3176
|
+
for (let i = 0; i < snapshot.length; i++) snapshot[i]();
|
|
3177
|
+
}
|
|
3178
|
+
if (this.dirtyByLevel.size === 0) return;
|
|
3179
|
+
let level = this.minLevel;
|
|
3180
|
+
let max = this.maxLevel;
|
|
3181
|
+
while (level <= max) {
|
|
3182
|
+
for (; ; ) {
|
|
3183
|
+
const bucket = this.dirtyByLevel.get(level);
|
|
3184
|
+
if (!bucket || bucket.size === 0) break;
|
|
3185
|
+
this.dirtyByLevel.delete(level);
|
|
3186
|
+
const snapshot = Array.from(bucket);
|
|
3187
|
+
for (let i = 0; i < snapshot.length; i++) snapshot[i]();
|
|
3188
|
+
}
|
|
3189
|
+
if (this.maxLevel > max) max = this.maxLevel;
|
|
3190
|
+
level++;
|
|
3191
|
+
}
|
|
3192
|
+
} finally {
|
|
3193
|
+
this.isFlushing = false;
|
|
3194
|
+
if (this.dirtyByLevel.size === 0) {
|
|
3195
|
+
this.minLevel = Infinity;
|
|
3196
|
+
this.maxLevel = -Infinity;
|
|
3197
|
+
} else {
|
|
3198
|
+
let nextMin = Infinity;
|
|
3199
|
+
let nextMax = -Infinity;
|
|
3200
|
+
this.dirtyByLevel.forEach((_bucket, lvl) => {
|
|
3201
|
+
if (lvl < nextMin) nextMin = lvl;
|
|
3202
|
+
if (lvl > nextMax) nextMax = lvl;
|
|
3203
|
+
});
|
|
3204
|
+
this.minLevel = nextMin;
|
|
3205
|
+
this.maxLevel = nextMax;
|
|
3206
|
+
this.isFlushScheduled = true;
|
|
3207
|
+
}
|
|
3208
|
+
}
|
|
3209
|
+
}
|
|
3210
|
+
};
|
|
2517
3211
|
// Annotate the CommonJS export names for ESM import in node:
|
|
2518
3212
|
0 && (module.exports = {
|
|
2519
3213
|
EOIMCollectionEventType,
|
|
2520
3214
|
EOIMComputedEventType,
|
|
2521
|
-
EOIMEffectPhase,
|
|
2522
3215
|
EOIMEventQueueEventType,
|
|
2523
3216
|
EOIMEventQueueSchedulerEventType,
|
|
2524
3217
|
EOIMIndexEventType,
|
|
2525
3218
|
EOIMObjectEventType,
|
|
2526
|
-
EOIMUpdateEventCoalescerEventType,
|
|
2527
3219
|
OIMCollection,
|
|
3220
|
+
OIMCollectionByPkSelector,
|
|
3221
|
+
OIMCollectionByPksSelector,
|
|
2528
3222
|
OIMCollectionChangedFieldsWrapper,
|
|
2529
3223
|
OIMCollectionStore,
|
|
2530
3224
|
OIMCollectionStoreMapDriven,
|
|
2531
3225
|
OIMComparatorFactory,
|
|
3226
|
+
OIMComputativeRuntime,
|
|
2532
3227
|
OIMComputed,
|
|
2533
3228
|
OIMDBSettings,
|
|
2534
3229
|
OIMEffect,
|
|
@@ -2537,6 +3232,8 @@ var OIMEffectDependencyComputed = class {
|
|
|
2537
3232
|
OIMEffectDependencyKeyedCollection,
|
|
2538
3233
|
OIMEffectDependencyKeyedIndex,
|
|
2539
3234
|
OIMEffectDependencyKeyedObject,
|
|
3235
|
+
OIMEntitiesByIndexKeyArrayBasedSelector,
|
|
3236
|
+
OIMEntitiesByIndexKeySetBasedSelector,
|
|
2540
3237
|
OIMEntityUpdaterFactory,
|
|
2541
3238
|
OIMEventEmitter,
|
|
2542
3239
|
OIMEventQueue,
|
|
@@ -2551,6 +3248,10 @@ var OIMEffectDependencyComputed = class {
|
|
|
2551
3248
|
OIMIndexManualArrayBased,
|
|
2552
3249
|
OIMIndexManualOrderedArrayBased,
|
|
2553
3250
|
OIMIndexManualSetBased,
|
|
3251
|
+
OIMIndexPksByKeyArrayBasedSelector,
|
|
3252
|
+
OIMIndexPksByKeySetBasedSelector,
|
|
3253
|
+
OIMIndexPksByKeysArrayBasedSelector,
|
|
3254
|
+
OIMIndexPksByKeysSetBasedSelector,
|
|
2554
3255
|
OIMIndexSetBased,
|
|
2555
3256
|
OIMIndexStoreArrayBased,
|
|
2556
3257
|
OIMIndexStoreMapDrivenArrayBased,
|
|
@@ -2561,6 +3262,8 @@ var OIMEffectDependencyComputed = class {
|
|
|
2561
3262
|
OIMObjectStore,
|
|
2562
3263
|
OIMObjectStoreMapDriven,
|
|
2563
3264
|
OIMObjectStoreRecordDriven,
|
|
3265
|
+
OIMObjectValueByKeySelector,
|
|
3266
|
+
OIMObjectValuesByKeysSelector,
|
|
2564
3267
|
OIMOrderedListIndexCommandStreamWrapper,
|
|
2565
3268
|
OIMPkSelectorFactory,
|
|
2566
3269
|
OIMRICollection,
|
|
@@ -2570,11 +3273,5 @@ var OIMEffectDependencyComputed = class {
|
|
|
2570
3273
|
OIMReactiveIndexManualSetBased,
|
|
2571
3274
|
OIMReactiveIndexSetBased,
|
|
2572
3275
|
OIMReactiveObject,
|
|
2573
|
-
|
|
2574
|
-
OIMUpdateEventCoalescerCollection,
|
|
2575
|
-
OIMUpdateEventCoalescerComputed,
|
|
2576
|
-
OIMUpdateEventCoalescerIndex,
|
|
2577
|
-
OIMUpdateEventCoalescerManual,
|
|
2578
|
-
OIMUpdateEventCoalescerObject,
|
|
2579
|
-
OIMUpdateEventEmitter
|
|
3276
|
+
OIMSelector
|
|
2580
3277
|
});
|