@oimdb/core 3.5.0 → 3.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +46 -46
- package/dist/index.cjs +1342 -178
- package/dist/index.d.cts +739 -65
- package/dist/index.d.ts +739 -65
- package/dist/index.js +1315 -177
- package/llms.txt +54 -7
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -708,6 +708,254 @@ var OIMReactiveIndexArrayBased = class extends OIMReactiveIndex {
|
|
|
708
708
|
var OIMObjectStore = class {
|
|
709
709
|
};
|
|
710
710
|
|
|
711
|
+
// src/abstract/OIMGlobalIndex.ts
|
|
712
|
+
var OIMGlobalIndex = class {
|
|
713
|
+
constructor(comparePks) {
|
|
714
|
+
this.emitter = new OIMEventEmitter();
|
|
715
|
+
this.comparePks = comparePks;
|
|
716
|
+
}
|
|
717
|
+
get isEmpty() {
|
|
718
|
+
return this.size === 0;
|
|
719
|
+
}
|
|
720
|
+
/**
|
|
721
|
+
* Materializes the bucket to entities, preserving positional holes: a slot
|
|
722
|
+
* whose entity is not present yet (or was removed) yields `undefined` at its
|
|
723
|
+
* position rather than being dropped — mirroring {@link OIMIndex}.
|
|
724
|
+
*/
|
|
725
|
+
getEntities() {
|
|
726
|
+
const entities = [];
|
|
727
|
+
for (const slot of this.iterateSlots()) {
|
|
728
|
+
entities.push(slot.item);
|
|
729
|
+
}
|
|
730
|
+
return entities;
|
|
731
|
+
}
|
|
732
|
+
getMetrics() {
|
|
733
|
+
return { totalPks: this.size };
|
|
734
|
+
}
|
|
735
|
+
destroy() {
|
|
736
|
+
this.emitter.offAll();
|
|
737
|
+
this.clearBucket();
|
|
738
|
+
}
|
|
739
|
+
emitUpdate() {
|
|
740
|
+
this.emitter.emit(0 /* UPDATE */, void 0);
|
|
741
|
+
}
|
|
742
|
+
};
|
|
743
|
+
|
|
744
|
+
// src/abstract/OIMGlobalIndexSetBased.ts
|
|
745
|
+
var OIMGlobalIndexSetBased = class extends OIMGlobalIndex {
|
|
746
|
+
constructor(options = {}) {
|
|
747
|
+
super(options.comparePks);
|
|
748
|
+
this.slots = /* @__PURE__ */ new Set();
|
|
749
|
+
}
|
|
750
|
+
get size() {
|
|
751
|
+
return this.slots.size;
|
|
752
|
+
}
|
|
753
|
+
iterateSlots() {
|
|
754
|
+
return this.slots;
|
|
755
|
+
}
|
|
756
|
+
clearBucket() {
|
|
757
|
+
this.slots.clear();
|
|
758
|
+
}
|
|
759
|
+
getPks() {
|
|
760
|
+
return this.slotsToPks(this.slots);
|
|
761
|
+
}
|
|
762
|
+
getSlots() {
|
|
763
|
+
return this.slots;
|
|
764
|
+
}
|
|
765
|
+
slotsToPks(slots) {
|
|
766
|
+
const pks = /* @__PURE__ */ new Set();
|
|
767
|
+
for (const slot of slots) pks.add(slot.pk);
|
|
768
|
+
return pks;
|
|
769
|
+
}
|
|
770
|
+
setSlotsWithComparison(newSlots) {
|
|
771
|
+
if (this.comparePks && this.slots.size === newSlots.size) {
|
|
772
|
+
if (this.comparePks(
|
|
773
|
+
Array.from(this.slotsToPks(this.slots)),
|
|
774
|
+
Array.from(this.slotsToPks(newSlots))
|
|
775
|
+
)) {
|
|
776
|
+
return false;
|
|
777
|
+
}
|
|
778
|
+
}
|
|
779
|
+
this.slots = newSlots;
|
|
780
|
+
return true;
|
|
781
|
+
}
|
|
782
|
+
};
|
|
783
|
+
|
|
784
|
+
// src/abstract/OIMGlobalIndexArrayBased.ts
|
|
785
|
+
var OIMGlobalIndexArrayBased = class extends OIMGlobalIndex {
|
|
786
|
+
constructor(options = {}) {
|
|
787
|
+
super(options.comparePks);
|
|
788
|
+
this.slots = [];
|
|
789
|
+
}
|
|
790
|
+
get size() {
|
|
791
|
+
return this.slots.length;
|
|
792
|
+
}
|
|
793
|
+
iterateSlots() {
|
|
794
|
+
return this.slots;
|
|
795
|
+
}
|
|
796
|
+
clearBucket() {
|
|
797
|
+
this.slots = [];
|
|
798
|
+
}
|
|
799
|
+
getPks() {
|
|
800
|
+
return this.slotsToPks(this.slots);
|
|
801
|
+
}
|
|
802
|
+
getSlots() {
|
|
803
|
+
return this.slots;
|
|
804
|
+
}
|
|
805
|
+
slotsToPks(slots) {
|
|
806
|
+
const pks = [];
|
|
807
|
+
pks.length = slots.length;
|
|
808
|
+
for (let i = 0; i < slots.length; i++) pks[i] = slots[i].pk;
|
|
809
|
+
return pks;
|
|
810
|
+
}
|
|
811
|
+
setSlotsWithComparison(newSlots) {
|
|
812
|
+
if (this.comparePks && this.slots.length === newSlots.length) {
|
|
813
|
+
if (this.comparePks(
|
|
814
|
+
this.slotsToPks(this.slots),
|
|
815
|
+
this.slotsToPks(newSlots)
|
|
816
|
+
)) {
|
|
817
|
+
return false;
|
|
818
|
+
}
|
|
819
|
+
}
|
|
820
|
+
this.slots = newSlots;
|
|
821
|
+
return true;
|
|
822
|
+
}
|
|
823
|
+
};
|
|
824
|
+
|
|
825
|
+
// src/core/OIMCarrierSingleEmitter.ts
|
|
826
|
+
var OIMCarrierSingleEmitter = class {
|
|
827
|
+
constructor(queue) {
|
|
828
|
+
this.dirty = false;
|
|
829
|
+
this.isFlushEnqueued = false;
|
|
830
|
+
this.onFlush = () => {
|
|
831
|
+
this.isFlushEnqueued = false;
|
|
832
|
+
if (!this.dirty) return;
|
|
833
|
+
this.dirty = false;
|
|
834
|
+
this.notify();
|
|
835
|
+
};
|
|
836
|
+
this.queue = queue;
|
|
837
|
+
}
|
|
838
|
+
subscribe(handler) {
|
|
839
|
+
let subscribers = this.subscribers;
|
|
840
|
+
if (!subscribers) {
|
|
841
|
+
subscribers = /* @__PURE__ */ new Set();
|
|
842
|
+
this.subscribers = subscribers;
|
|
843
|
+
}
|
|
844
|
+
subscribers.add(handler);
|
|
845
|
+
return () => {
|
|
846
|
+
this.subscribers?.delete(handler);
|
|
847
|
+
};
|
|
848
|
+
}
|
|
849
|
+
markUpdated() {
|
|
850
|
+
this.assertNotInFlush();
|
|
851
|
+
if (!this.subscribers || this.subscribers.size === 0) return;
|
|
852
|
+
if (this.dirty) return;
|
|
853
|
+
this.dirty = true;
|
|
854
|
+
this.scheduleFlush();
|
|
855
|
+
}
|
|
856
|
+
hasSubscriptions() {
|
|
857
|
+
return !!this.subscribers && this.subscribers.size > 0;
|
|
858
|
+
}
|
|
859
|
+
getMetrics() {
|
|
860
|
+
return {
|
|
861
|
+
totalHandlers: this.subscribers?.size ?? 0,
|
|
862
|
+
queueLength: this.dirty ? 1 : 0
|
|
863
|
+
};
|
|
864
|
+
}
|
|
865
|
+
destroy() {
|
|
866
|
+
if (this.isFlushEnqueued) {
|
|
867
|
+
this.queue.cancel(this.onFlush);
|
|
868
|
+
this.isFlushEnqueued = false;
|
|
869
|
+
}
|
|
870
|
+
this.subscribers?.clear();
|
|
871
|
+
this.subscribers = void 0;
|
|
872
|
+
this.dirty = false;
|
|
873
|
+
}
|
|
874
|
+
assertNotInFlush() {
|
|
875
|
+
if (this.queue.isInFlush) {
|
|
876
|
+
throw new Error(
|
|
877
|
+
"OIMCarrierSingleEmitter: updates during queue.flush() are not allowed. Finish all writes before calling queue.flush()."
|
|
878
|
+
);
|
|
879
|
+
}
|
|
880
|
+
}
|
|
881
|
+
scheduleFlush() {
|
|
882
|
+
if (this.isFlushEnqueued) return;
|
|
883
|
+
this.isFlushEnqueued = true;
|
|
884
|
+
this.queue.enqueue(this.onFlush);
|
|
885
|
+
}
|
|
886
|
+
notify() {
|
|
887
|
+
const subscribers = this.subscribers;
|
|
888
|
+
if (!subscribers || subscribers.size === 0) return;
|
|
889
|
+
if (subscribers.size === 1) {
|
|
890
|
+
const only = subscribers.values().next().value;
|
|
891
|
+
if (only) only();
|
|
892
|
+
return;
|
|
893
|
+
}
|
|
894
|
+
const snapshot = [];
|
|
895
|
+
subscribers.forEach((h) => snapshot.push(h));
|
|
896
|
+
for (let i = 0; i < snapshot.length; i++) {
|
|
897
|
+
const handler = snapshot[i];
|
|
898
|
+
if (subscribers.has(handler)) handler();
|
|
899
|
+
}
|
|
900
|
+
}
|
|
901
|
+
};
|
|
902
|
+
|
|
903
|
+
// src/abstract/OIMReactiveGlobalIndex.ts
|
|
904
|
+
var OIMReactiveGlobalIndex = class {
|
|
905
|
+
constructor(queue, createIndex) {
|
|
906
|
+
this.updateEmitter = new OIMCarrierSingleEmitter(queue);
|
|
907
|
+
this.index = createIndex(this.updateEmitter);
|
|
908
|
+
}
|
|
909
|
+
getEntities() {
|
|
910
|
+
return this.index.getEntities();
|
|
911
|
+
}
|
|
912
|
+
get size() {
|
|
913
|
+
return this.index.size;
|
|
914
|
+
}
|
|
915
|
+
get isEmpty() {
|
|
916
|
+
return this.index.isEmpty;
|
|
917
|
+
}
|
|
918
|
+
subscribe(handler) {
|
|
919
|
+
return this.updateEmitter.subscribe(handler);
|
|
920
|
+
}
|
|
921
|
+
hasSubscriptions() {
|
|
922
|
+
return this.updateEmitter.hasSubscriptions();
|
|
923
|
+
}
|
|
924
|
+
getMetrics() {
|
|
925
|
+
return this.index.getMetrics();
|
|
926
|
+
}
|
|
927
|
+
destroy() {
|
|
928
|
+
this.updateEmitter.destroy();
|
|
929
|
+
this.index.destroy();
|
|
930
|
+
}
|
|
931
|
+
};
|
|
932
|
+
|
|
933
|
+
// src/abstract/OIMReactiveGlobalIndexSetBased.ts
|
|
934
|
+
var OIMReactiveGlobalIndexSetBased = class extends OIMReactiveGlobalIndex {
|
|
935
|
+
constructor(queue, createIndex) {
|
|
936
|
+
super(queue, createIndex);
|
|
937
|
+
}
|
|
938
|
+
getPks() {
|
|
939
|
+
return this.index.getPks();
|
|
940
|
+
}
|
|
941
|
+
getSlots() {
|
|
942
|
+
return this.index.getSlots();
|
|
943
|
+
}
|
|
944
|
+
};
|
|
945
|
+
|
|
946
|
+
// src/abstract/OIMReactiveGlobalIndexArrayBased.ts
|
|
947
|
+
var OIMReactiveGlobalIndexArrayBased = class extends OIMReactiveGlobalIndex {
|
|
948
|
+
constructor(queue, createIndex) {
|
|
949
|
+
super(queue, createIndex);
|
|
950
|
+
}
|
|
951
|
+
getPks() {
|
|
952
|
+
return this.index.getPks();
|
|
953
|
+
}
|
|
954
|
+
getSlots() {
|
|
955
|
+
return this.index.getSlots();
|
|
956
|
+
}
|
|
957
|
+
};
|
|
958
|
+
|
|
711
959
|
// src/core/OIMPkSelectorFactory.ts
|
|
712
960
|
var OIMPkSelectorFactory = class {
|
|
713
961
|
createIdSelector() {
|
|
@@ -1151,7 +1399,7 @@ var OIMReactiveCollection = class extends OIMCollection {
|
|
|
1151
1399
|
}
|
|
1152
1400
|
};
|
|
1153
1401
|
|
|
1154
|
-
// src/
|
|
1402
|
+
// src/core/OIMIndexManualOrderedArrayBased.ts
|
|
1155
1403
|
var OIMIndexManualOrderedArrayBased = class extends OIMIndexArrayBased {
|
|
1156
1404
|
clear(key) {
|
|
1157
1405
|
if (key === void 0) {
|
|
@@ -1267,7 +1515,7 @@ var OIMIndexManualOrderedArrayBased = class extends OIMIndexArrayBased {
|
|
|
1267
1515
|
}
|
|
1268
1516
|
};
|
|
1269
1517
|
|
|
1270
|
-
// src/
|
|
1518
|
+
// src/core/OIMCollectionIndexManualOrderedArrayBased.ts
|
|
1271
1519
|
var OIMCollectionIndexManualOrderedArrayBased = class extends OIMIndexManualOrderedArrayBased {
|
|
1272
1520
|
constructor(opts) {
|
|
1273
1521
|
super();
|
|
@@ -1563,35 +1811,67 @@ var OIMUpdateEventEmitter = class {
|
|
|
1563
1811
|
}
|
|
1564
1812
|
};
|
|
1565
1813
|
|
|
1566
|
-
// src/
|
|
1567
|
-
var
|
|
1568
|
-
constructor(queue
|
|
1569
|
-
this.isInWrite = false;
|
|
1814
|
+
// src/abstract/OIMOrderedListCommandBuffer.ts
|
|
1815
|
+
var OIMOrderedListCommandBuffer = class {
|
|
1816
|
+
constructor(queue) {
|
|
1570
1817
|
this.commandsByKey = /* @__PURE__ */ new Map();
|
|
1571
1818
|
this.onAfterFlush = () => {
|
|
1572
1819
|
this.commandsByKey.clear();
|
|
1573
1820
|
};
|
|
1574
|
-
this.onIndexUpdate = (payload) => {
|
|
1575
|
-
if (this.isInWrite) return;
|
|
1576
|
-
if (payload.keys.length === 0) return;
|
|
1577
|
-
for (let i = 0; i < payload.keys.length; i++) {
|
|
1578
|
-
const key = payload.keys[i];
|
|
1579
|
-
this.appendResetCommand(key, this.getSlotsByKey(key));
|
|
1580
|
-
}
|
|
1581
|
-
};
|
|
1582
1821
|
this.commandsEventEmitter = new OIMUpdateEventEmitter(
|
|
1583
1822
|
queue,
|
|
1584
1823
|
"after_flush"
|
|
1585
1824
|
);
|
|
1586
|
-
this.index = index ?? new OIMIndexManualOrderedArrayBased();
|
|
1587
1825
|
this.unsubscribeAfterFlush = queue.emitter.on(
|
|
1588
1826
|
0 /* AFTER_FLUSH */,
|
|
1589
1827
|
this.onAfterFlush
|
|
1590
1828
|
);
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1829
|
+
}
|
|
1830
|
+
subscribeCommands(key, handler) {
|
|
1831
|
+
return this.commandsEventEmitter.subscribeOnKey(key, handler);
|
|
1832
|
+
}
|
|
1833
|
+
getBufferedCommands(key) {
|
|
1834
|
+
return this.commandsByKey.get(key) ?? [];
|
|
1835
|
+
}
|
|
1836
|
+
consumeCommands(key) {
|
|
1837
|
+
const cmds = this.commandsByKey.get(key);
|
|
1838
|
+
if (!cmds || cmds.length === 0) return [];
|
|
1839
|
+
return cmds.slice();
|
|
1840
|
+
}
|
|
1841
|
+
destroy() {
|
|
1842
|
+
this.commandsEventEmitter.destroy();
|
|
1843
|
+
this.unsubscribeAfterFlush();
|
|
1844
|
+
this.commandsByKey.clear();
|
|
1845
|
+
}
|
|
1846
|
+
appendCommand(key, cmd) {
|
|
1847
|
+
let cmds = this.commandsByKey.get(key);
|
|
1848
|
+
if (!cmds) {
|
|
1849
|
+
cmds = [];
|
|
1850
|
+
this.commandsByKey.set(key, cmds);
|
|
1851
|
+
}
|
|
1852
|
+
if (cmd.type === "reset") {
|
|
1853
|
+
cmds.length = 0;
|
|
1854
|
+
cmds.push(cmd);
|
|
1855
|
+
} else if (cmds.length > 0 && cmds[0].type === "reset") {
|
|
1856
|
+
cmds[0] = this.createResetCommand(this.getItemsByKey(key));
|
|
1857
|
+
} else {
|
|
1858
|
+
cmds.push(cmd);
|
|
1859
|
+
}
|
|
1860
|
+
this.commandsEventEmitter.markUpdatedKeys([key]);
|
|
1861
|
+
}
|
|
1862
|
+
appendResetCommand(key, items) {
|
|
1863
|
+
this.appendCommand(key, this.createResetCommand(items));
|
|
1864
|
+
}
|
|
1865
|
+
createResetCommand(items) {
|
|
1866
|
+
return { type: "reset", items };
|
|
1867
|
+
}
|
|
1868
|
+
};
|
|
1869
|
+
|
|
1870
|
+
// src/modules/wrapper/index/OIMOrderedListCommandStream.ts
|
|
1871
|
+
var OIMOrderedListCommandStream = class extends OIMOrderedListCommandBuffer {
|
|
1872
|
+
constructor(queue, index) {
|
|
1873
|
+
super(queue);
|
|
1874
|
+
this.index = index ?? new OIMIndexManualOrderedArrayBased();
|
|
1595
1875
|
}
|
|
1596
1876
|
getPksByKey(key) {
|
|
1597
1877
|
return this.index.getPksByKey(key);
|
|
@@ -1601,14 +1881,10 @@ var OIMOrderedListCommandStream = class {
|
|
|
1601
1881
|
key
|
|
1602
1882
|
);
|
|
1603
1883
|
}
|
|
1604
|
-
/** {@link
|
|
1884
|
+
/** {@link OIMOrderedListCommandBuffer.getItemsByKey} — the slots in order. */
|
|
1605
1885
|
getItemsByKey(key) {
|
|
1606
1886
|
return this.getSlotsByKey(key);
|
|
1607
1887
|
}
|
|
1608
|
-
/** {@link IOIMOrderedListCommandSource} — per-key command subscription. */
|
|
1609
|
-
subscribeCommands(key, handler) {
|
|
1610
|
-
return this.commandsEventEmitter.subscribeOnKey(key, handler);
|
|
1611
|
-
}
|
|
1612
1888
|
getEntitiesByKey(key) {
|
|
1613
1889
|
return this.index.getEntitiesByKey(key);
|
|
1614
1890
|
}
|
|
@@ -1619,57 +1895,46 @@ var OIMOrderedListCommandStream = class {
|
|
|
1619
1895
|
return this.index.getKeys();
|
|
1620
1896
|
}
|
|
1621
1897
|
pushSlot(key, slot) {
|
|
1622
|
-
this.
|
|
1623
|
-
|
|
1624
|
-
this.appendCommand(key, { type: "insert", index, item: slot });
|
|
1625
|
-
});
|
|
1898
|
+
const index = this.index.pushSlot(key, slot);
|
|
1899
|
+
this.appendCommand(key, { type: "insert", index, item: slot });
|
|
1626
1900
|
}
|
|
1627
1901
|
insertSlotAt(key, index, slot) {
|
|
1628
|
-
this.
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
item: slot
|
|
1634
|
-
});
|
|
1902
|
+
const safeIndex = this.index.insertSlotAt(key, index, slot);
|
|
1903
|
+
this.appendCommand(key, {
|
|
1904
|
+
type: "insert",
|
|
1905
|
+
index: safeIndex,
|
|
1906
|
+
item: slot
|
|
1635
1907
|
});
|
|
1636
1908
|
}
|
|
1637
1909
|
/** Replace the slot at `index` in place. */
|
|
1638
1910
|
setSlotAt(key, index, slot) {
|
|
1639
|
-
this.
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
item: slot
|
|
1646
|
-
});
|
|
1911
|
+
const safeIndex = this.index.setSlotAt(key, index, slot);
|
|
1912
|
+
if (safeIndex < 0) return;
|
|
1913
|
+
this.appendCommand(key, {
|
|
1914
|
+
type: "set",
|
|
1915
|
+
index: safeIndex,
|
|
1916
|
+
item: slot
|
|
1647
1917
|
});
|
|
1648
1918
|
}
|
|
1649
1919
|
removeAt(key, index) {
|
|
1650
|
-
this.
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
this.appendCommand(key, { type: "remove", index });
|
|
1654
|
-
});
|
|
1920
|
+
const slot = this.index.removeAt(key, index);
|
|
1921
|
+
if (slot === void 0) return;
|
|
1922
|
+
this.appendCommand(key, { type: "remove", index });
|
|
1655
1923
|
}
|
|
1656
1924
|
/** Remove `count` consecutive elements from `index`; emits `remove` with `count`. */
|
|
1657
1925
|
removeRange(key, index, count) {
|
|
1658
|
-
this.
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
this.appendCommand(key, { type: "remove", index, count: removed });
|
|
1662
|
-
});
|
|
1926
|
+
const removed = this.index.removeRange(key, index, count);
|
|
1927
|
+
if (removed <= 0) return;
|
|
1928
|
+
this.appendCommand(key, { type: "remove", index, count: removed });
|
|
1663
1929
|
}
|
|
1664
1930
|
move(key, fromIndex, toIndex) {
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
});
|
|
1931
|
+
if (fromIndex === toIndex) return;
|
|
1932
|
+
const slot = this.index.move(key, fromIndex, toIndex);
|
|
1933
|
+
if (slot === void 0) return;
|
|
1934
|
+
this.appendCommand(key, {
|
|
1935
|
+
type: "move",
|
|
1936
|
+
from: fromIndex,
|
|
1937
|
+
to: toIndex
|
|
1673
1938
|
});
|
|
1674
1939
|
}
|
|
1675
1940
|
/**
|
|
@@ -1677,74 +1942,31 @@ var OIMOrderedListCommandStream = class {
|
|
|
1677
1942
|
* `count`. `to` is in the post-extraction coordinate space (as single `move`).
|
|
1678
1943
|
*/
|
|
1679
1944
|
moveRange(key, from, to, count) {
|
|
1680
|
-
this.
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
this.appendCommand(key, { type: "move", from, to, count: moved });
|
|
1684
|
-
});
|
|
1945
|
+
const moved = this.index.moveRange(key, from, to, count);
|
|
1946
|
+
if (moved <= 0) return;
|
|
1947
|
+
this.appendCommand(key, { type: "move", from, to, count: moved });
|
|
1685
1948
|
}
|
|
1686
1949
|
setSlots(key, slots) {
|
|
1687
|
-
this.
|
|
1688
|
-
|
|
1689
|
-
this.appendResetCommand(key, slots);
|
|
1690
|
-
});
|
|
1691
|
-
}
|
|
1692
|
-
getBufferedCommands(key) {
|
|
1693
|
-
return this.commandsByKey.get(key) ?? [];
|
|
1694
|
-
}
|
|
1695
|
-
consumeCommands(key) {
|
|
1696
|
-
const cmds = this.commandsByKey.get(key);
|
|
1697
|
-
if (!cmds || cmds.length === 0) return [];
|
|
1698
|
-
return cmds.slice();
|
|
1950
|
+
this.index.resetSlots(key, slots);
|
|
1951
|
+
this.appendResetCommand(key, slots);
|
|
1699
1952
|
}
|
|
1700
1953
|
clear(key) {
|
|
1701
1954
|
if (key === void 0) {
|
|
1702
|
-
this.
|
|
1703
|
-
|
|
1955
|
+
const keys = this.getKeys().slice();
|
|
1956
|
+
if (keys.length === 0) return;
|
|
1957
|
+
this.index.clear();
|
|
1958
|
+
for (let i = 0; i < keys.length; i++) {
|
|
1959
|
+
this.appendResetCommand(keys[i], []);
|
|
1960
|
+
}
|
|
1704
1961
|
return;
|
|
1705
1962
|
}
|
|
1963
|
+
if (!this.index.hasKey(key)) return;
|
|
1706
1964
|
this.index.clear(key);
|
|
1707
|
-
this.
|
|
1965
|
+
this.appendResetCommand(key, []);
|
|
1708
1966
|
}
|
|
1709
1967
|
destroy() {
|
|
1710
|
-
this.
|
|
1711
|
-
|
|
1712
|
-
this.unsubscribeFromIndexEmitter();
|
|
1713
|
-
this.clear();
|
|
1714
|
-
}
|
|
1715
|
-
withWrite(fn) {
|
|
1716
|
-
if (this.isInWrite) {
|
|
1717
|
-
fn();
|
|
1718
|
-
return;
|
|
1719
|
-
}
|
|
1720
|
-
this.isInWrite = true;
|
|
1721
|
-
try {
|
|
1722
|
-
fn();
|
|
1723
|
-
} finally {
|
|
1724
|
-
this.isInWrite = false;
|
|
1725
|
-
}
|
|
1726
|
-
}
|
|
1727
|
-
appendCommand(key, cmd) {
|
|
1728
|
-
let cmds = this.commandsByKey.get(key);
|
|
1729
|
-
if (!cmds) {
|
|
1730
|
-
cmds = [];
|
|
1731
|
-
this.commandsByKey.set(key, cmds);
|
|
1732
|
-
}
|
|
1733
|
-
if (cmd.type === "reset") {
|
|
1734
|
-
cmds.length = 0;
|
|
1735
|
-
cmds.push(cmd);
|
|
1736
|
-
} else if (cmds.length > 0 && cmds[0].type === "reset") {
|
|
1737
|
-
cmds[0] = this.createResetCommand(this.getSlotsByKey(key));
|
|
1738
|
-
} else {
|
|
1739
|
-
cmds.push(cmd);
|
|
1740
|
-
}
|
|
1741
|
-
this.commandsEventEmitter.markUpdatedKeys([key]);
|
|
1742
|
-
}
|
|
1743
|
-
appendResetCommand(key, slots) {
|
|
1744
|
-
this.appendCommand(key, this.createResetCommand(slots));
|
|
1745
|
-
}
|
|
1746
|
-
createResetCommand(slots) {
|
|
1747
|
-
return { type: "reset", items: slots };
|
|
1968
|
+
this.index.destroy();
|
|
1969
|
+
super.destroy();
|
|
1748
1970
|
}
|
|
1749
1971
|
};
|
|
1750
1972
|
|
|
@@ -1758,42 +1980,34 @@ var OIMCollectionOrderedListCommandStream = class extends OIMOrderedListCommandS
|
|
|
1758
1980
|
this.index = index;
|
|
1759
1981
|
}
|
|
1760
1982
|
push(key, pk) {
|
|
1761
|
-
this.
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
this.appendCommand(key, { type: "insert", index, item: slot });
|
|
1765
|
-
});
|
|
1983
|
+
const slot = this.resolvePk(pk);
|
|
1984
|
+
const index = this.index.pushSlot(key, slot);
|
|
1985
|
+
this.appendCommand(key, { type: "insert", index, item: slot });
|
|
1766
1986
|
}
|
|
1767
1987
|
insertAt(key, index, pk) {
|
|
1768
|
-
this.
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
item: slot
|
|
1775
|
-
});
|
|
1988
|
+
const slot = this.resolvePk(pk);
|
|
1989
|
+
const safeIndex = this.index.insertSlotAt(key, index, slot);
|
|
1990
|
+
this.appendCommand(key, {
|
|
1991
|
+
type: "insert",
|
|
1992
|
+
index: safeIndex,
|
|
1993
|
+
item: slot
|
|
1776
1994
|
});
|
|
1777
1995
|
}
|
|
1778
1996
|
/** Replace the element at `index` with the slot for `pk`, in place. */
|
|
1779
1997
|
setAt(key, index, pk) {
|
|
1780
|
-
this.
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
item: slot
|
|
1788
|
-
});
|
|
1998
|
+
const slot = this.resolvePk(pk);
|
|
1999
|
+
const safeIndex = this.index.setSlotAt(key, index, slot);
|
|
2000
|
+
if (safeIndex < 0) return;
|
|
2001
|
+
this.appendCommand(key, {
|
|
2002
|
+
type: "set",
|
|
2003
|
+
index: safeIndex,
|
|
2004
|
+
item: slot
|
|
1789
2005
|
});
|
|
1790
2006
|
}
|
|
1791
2007
|
set(key, pks) {
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
this.appendResetCommand(key, slots);
|
|
1796
|
-
});
|
|
2008
|
+
const slots = pks.map((pk) => this.resolvePk(pk));
|
|
2009
|
+
this.index.resetSlots(key, slots);
|
|
2010
|
+
this.appendResetCommand(key, slots);
|
|
1797
2011
|
}
|
|
1798
2012
|
getSlotsByKey(key) {
|
|
1799
2013
|
return this.index.getSlotsByKey(
|
|
@@ -1804,7 +2018,9 @@ var OIMCollectionOrderedListCommandStream = class extends OIMOrderedListCommandS
|
|
|
1804
2018
|
return this.index.getEntitiesByKey(key);
|
|
1805
2019
|
}
|
|
1806
2020
|
resolvePk(pk) {
|
|
1807
|
-
return this.index.resolvePk(
|
|
2021
|
+
return this.index.resolvePk(
|
|
2022
|
+
pk
|
|
2023
|
+
);
|
|
1808
2024
|
}
|
|
1809
2025
|
};
|
|
1810
2026
|
|
|
@@ -2401,7 +2617,445 @@ var OIMDerivedCollectionIndexArrayBased = class extends OIMReactiveCollectionInd
|
|
|
2401
2617
|
seen.add(key);
|
|
2402
2618
|
result.push(key);
|
|
2403
2619
|
}
|
|
2404
|
-
return result;
|
|
2620
|
+
return result;
|
|
2621
|
+
}
|
|
2622
|
+
};
|
|
2623
|
+
|
|
2624
|
+
// src/core/OIMGlobalIndexManualArrayBased.ts
|
|
2625
|
+
var OIMGlobalIndexManualArrayBased = class extends OIMGlobalIndexArrayBased {
|
|
2626
|
+
constructor(options = {}) {
|
|
2627
|
+
super(options);
|
|
2628
|
+
}
|
|
2629
|
+
setSlots(slots) {
|
|
2630
|
+
if (this.setSlotsWithComparison(slots)) this.emitUpdate();
|
|
2631
|
+
}
|
|
2632
|
+
/**
|
|
2633
|
+
* Appends pre-deduplicated slots to the bucket IN PLACE and emits once.
|
|
2634
|
+
* O(added). Callers own dedup (used by collection-bound `addPks`).
|
|
2635
|
+
*/
|
|
2636
|
+
appendSlots(slots) {
|
|
2637
|
+
if (slots.length === 0) return;
|
|
2638
|
+
for (let i = 0; i < slots.length; i++) this.slots.push(slots[i]);
|
|
2639
|
+
this.emitUpdate();
|
|
2640
|
+
}
|
|
2641
|
+
clear() {
|
|
2642
|
+
if (this.slots.length > 0) {
|
|
2643
|
+
this.slots = [];
|
|
2644
|
+
this.emitUpdate();
|
|
2645
|
+
}
|
|
2646
|
+
}
|
|
2647
|
+
};
|
|
2648
|
+
|
|
2649
|
+
// src/core/OIMReactiveGlobalIndexManualArrayBased.ts
|
|
2650
|
+
var OIMGlobalIndexManualArrayBasedReactive = class extends OIMGlobalIndexManualArrayBased {
|
|
2651
|
+
constructor(updateEmitter, opts) {
|
|
2652
|
+
super(opts);
|
|
2653
|
+
this.updateEmitter = updateEmitter;
|
|
2654
|
+
}
|
|
2655
|
+
emitUpdate() {
|
|
2656
|
+
this.updateEmitter.markUpdated();
|
|
2657
|
+
}
|
|
2658
|
+
};
|
|
2659
|
+
var OIMReactiveGlobalIndexManualArrayBased = class extends OIMReactiveGlobalIndexArrayBased {
|
|
2660
|
+
constructor(queue, opts) {
|
|
2661
|
+
super(
|
|
2662
|
+
queue,
|
|
2663
|
+
(updateEmitter) => new OIMGlobalIndexManualArrayBasedReactive(
|
|
2664
|
+
updateEmitter,
|
|
2665
|
+
opts?.indexOptions
|
|
2666
|
+
)
|
|
2667
|
+
);
|
|
2668
|
+
}
|
|
2669
|
+
setSlots(slots) {
|
|
2670
|
+
this.index.setSlots(slots);
|
|
2671
|
+
}
|
|
2672
|
+
appendSlots(slots) {
|
|
2673
|
+
this.index.appendSlots(slots);
|
|
2674
|
+
}
|
|
2675
|
+
clear() {
|
|
2676
|
+
this.index.clear();
|
|
2677
|
+
}
|
|
2678
|
+
};
|
|
2679
|
+
|
|
2680
|
+
// src/core/OIMReactiveCollectionGlobalIndexManualArrayBased.ts
|
|
2681
|
+
var OIMReactiveCollectionGlobalIndexManualArrayBased = class extends OIMReactiveGlobalIndexManualArrayBased {
|
|
2682
|
+
constructor(queue, opts) {
|
|
2683
|
+
const resolveSlot = opts.collection !== void 0 ? (pk) => opts.collection.getOrReserveSlotByPk(pk) : opts.resolveSlot;
|
|
2684
|
+
super(queue, { indexOptions: opts.indexOptions });
|
|
2685
|
+
// Single pk membership set for O(1) `addPks` dedup. Lazily seeded from the
|
|
2686
|
+
// bucket so it stays correct even after a raw `setSlots` (e.g. derived
|
|
2687
|
+
// rebuild), matching the keyed index's `membershipOf`.
|
|
2688
|
+
this.membership = /* @__PURE__ */ new Set();
|
|
2689
|
+
this.membershipSeeded = false;
|
|
2690
|
+
this.resolveSlot = resolveSlot;
|
|
2691
|
+
}
|
|
2692
|
+
setPks(pks) {
|
|
2693
|
+
this.membership.clear();
|
|
2694
|
+
for (let i = 0; i < pks.length; i++) this.membership.add(pks[i]);
|
|
2695
|
+
this.membershipSeeded = true;
|
|
2696
|
+
super.setSlots(this.resolveSlots(pks));
|
|
2697
|
+
}
|
|
2698
|
+
addPks(pks) {
|
|
2699
|
+
if (pks.length === 0) return;
|
|
2700
|
+
const membership = this.membershipOf();
|
|
2701
|
+
const newSlots = [];
|
|
2702
|
+
for (const pk of pks) {
|
|
2703
|
+
if (membership.has(pk)) continue;
|
|
2704
|
+
membership.add(pk);
|
|
2705
|
+
newSlots.push(this.resolveRequiredSlot(pk));
|
|
2706
|
+
}
|
|
2707
|
+
if (newSlots.length > 0) super.appendSlots(newSlots);
|
|
2708
|
+
}
|
|
2709
|
+
removePks(pks) {
|
|
2710
|
+
if (pks.length === 0) return;
|
|
2711
|
+
const membership = this.membershipOf();
|
|
2712
|
+
if (membership.size === 0) return;
|
|
2713
|
+
const pksToRemove = new Set(pks);
|
|
2714
|
+
const existingSlots = this.index.getSlots();
|
|
2715
|
+
const nextSlots = existingSlots.filter(
|
|
2716
|
+
(slot) => !pksToRemove.has(slot.pk)
|
|
2717
|
+
);
|
|
2718
|
+
if (nextSlots.length === existingSlots.length) return;
|
|
2719
|
+
for (let i = 0; i < pks.length; i++) membership.delete(pks[i]);
|
|
2720
|
+
if (nextSlots.length === 0) this.clear();
|
|
2721
|
+
else super.setSlots(nextSlots);
|
|
2722
|
+
}
|
|
2723
|
+
clear() {
|
|
2724
|
+
this.membership.clear();
|
|
2725
|
+
this.membershipSeeded = false;
|
|
2726
|
+
super.clear();
|
|
2727
|
+
}
|
|
2728
|
+
membershipOf() {
|
|
2729
|
+
if (!this.membershipSeeded) {
|
|
2730
|
+
this.membership.clear();
|
|
2731
|
+
const existing = this.index.getSlots();
|
|
2732
|
+
for (let i = 0; i < existing.length; i++) {
|
|
2733
|
+
this.membership.add(existing[i].pk);
|
|
2734
|
+
}
|
|
2735
|
+
this.membershipSeeded = true;
|
|
2736
|
+
}
|
|
2737
|
+
return this.membership;
|
|
2738
|
+
}
|
|
2739
|
+
getEntities() {
|
|
2740
|
+
return super.getEntities();
|
|
2741
|
+
}
|
|
2742
|
+
resolveSlots(pks) {
|
|
2743
|
+
const slots = [];
|
|
2744
|
+
slots.length = pks.length;
|
|
2745
|
+
for (let i = 0; i < pks.length; i++) {
|
|
2746
|
+
slots[i] = this.resolveRequiredSlot(pks[i]);
|
|
2747
|
+
}
|
|
2748
|
+
return slots;
|
|
2749
|
+
}
|
|
2750
|
+
resolveRequiredSlot(pk) {
|
|
2751
|
+
const slot = this.resolveSlot(pk);
|
|
2752
|
+
if (!slot) return { pk, item: void 0 };
|
|
2753
|
+
return slot;
|
|
2754
|
+
}
|
|
2755
|
+
};
|
|
2756
|
+
|
|
2757
|
+
// src/core/OIMGlobalIndexManualSetBased.ts
|
|
2758
|
+
var OIMGlobalIndexManualSetBased = class extends OIMGlobalIndexSetBased {
|
|
2759
|
+
constructor(options = {}) {
|
|
2760
|
+
super(options);
|
|
2761
|
+
}
|
|
2762
|
+
setSlots(slots) {
|
|
2763
|
+
if (this.setSlotsWithComparison(new Set(slots))) this.emitUpdate();
|
|
2764
|
+
}
|
|
2765
|
+
/** Adds slots IN PLACE (O(added)) and emits once if anything changed. */
|
|
2766
|
+
addSlots(slots) {
|
|
2767
|
+
if (slots.length === 0) return;
|
|
2768
|
+
let changed = false;
|
|
2769
|
+
for (let i = 0; i < slots.length; i++) {
|
|
2770
|
+
if (!this.slots.has(slots[i])) {
|
|
2771
|
+
this.slots.add(slots[i]);
|
|
2772
|
+
changed = true;
|
|
2773
|
+
}
|
|
2774
|
+
}
|
|
2775
|
+
if (changed) this.emitUpdate();
|
|
2776
|
+
}
|
|
2777
|
+
/** Removes slots IN PLACE (O(removed)) and emits once if anything changed. */
|
|
2778
|
+
removeSlots(slots) {
|
|
2779
|
+
if (slots.length === 0) return;
|
|
2780
|
+
let changed = false;
|
|
2781
|
+
for (let i = 0; i < slots.length; i++) {
|
|
2782
|
+
if (this.slots.delete(slots[i])) changed = true;
|
|
2783
|
+
}
|
|
2784
|
+
if (changed) this.emitUpdate();
|
|
2785
|
+
}
|
|
2786
|
+
clear() {
|
|
2787
|
+
if (this.slots.size > 0) {
|
|
2788
|
+
this.slots.clear();
|
|
2789
|
+
this.emitUpdate();
|
|
2790
|
+
}
|
|
2791
|
+
}
|
|
2792
|
+
};
|
|
2793
|
+
|
|
2794
|
+
// src/core/OIMReactiveGlobalIndexManualSetBased.ts
|
|
2795
|
+
var OIMGlobalIndexManualSetBasedReactive = class extends OIMGlobalIndexManualSetBased {
|
|
2796
|
+
constructor(updateEmitter, opts) {
|
|
2797
|
+
super(opts);
|
|
2798
|
+
this.updateEmitter = updateEmitter;
|
|
2799
|
+
}
|
|
2800
|
+
emitUpdate() {
|
|
2801
|
+
this.updateEmitter.markUpdated();
|
|
2802
|
+
}
|
|
2803
|
+
};
|
|
2804
|
+
var OIMReactiveGlobalIndexManualSetBased = class extends OIMReactiveGlobalIndexSetBased {
|
|
2805
|
+
constructor(queue, opts) {
|
|
2806
|
+
super(
|
|
2807
|
+
queue,
|
|
2808
|
+
(updateEmitter) => new OIMGlobalIndexManualSetBasedReactive(
|
|
2809
|
+
updateEmitter,
|
|
2810
|
+
opts?.indexOptions
|
|
2811
|
+
)
|
|
2812
|
+
);
|
|
2813
|
+
}
|
|
2814
|
+
setSlots(slots) {
|
|
2815
|
+
this.index.setSlots(slots);
|
|
2816
|
+
}
|
|
2817
|
+
addSlots(slots) {
|
|
2818
|
+
this.index.addSlots(slots);
|
|
2819
|
+
}
|
|
2820
|
+
removeSlots(slots) {
|
|
2821
|
+
this.index.removeSlots(slots);
|
|
2822
|
+
}
|
|
2823
|
+
clear() {
|
|
2824
|
+
this.index.clear();
|
|
2825
|
+
}
|
|
2826
|
+
};
|
|
2827
|
+
|
|
2828
|
+
// src/core/OIMReactiveCollectionGlobalIndexManualSetBased.ts
|
|
2829
|
+
var OIMReactiveCollectionGlobalIndexManualSetBased = class extends OIMReactiveGlobalIndexManualSetBased {
|
|
2830
|
+
constructor(queue, opts) {
|
|
2831
|
+
const resolveSlot = opts.collection !== void 0 ? (pk) => opts.collection.getOrReserveSlotByPk(pk) : opts.resolveSlot;
|
|
2832
|
+
super(queue, { indexOptions: opts.indexOptions });
|
|
2833
|
+
this.membership = /* @__PURE__ */ new Map();
|
|
2834
|
+
this.membershipSeeded = false;
|
|
2835
|
+
this.resolveSlot = resolveSlot;
|
|
2836
|
+
}
|
|
2837
|
+
setPks(pks) {
|
|
2838
|
+
this.membership.clear();
|
|
2839
|
+
const slots = [];
|
|
2840
|
+
for (let i = 0; i < pks.length; i++) {
|
|
2841
|
+
const pk = pks[i];
|
|
2842
|
+
const slot = this.resolveRequiredSlot(pk);
|
|
2843
|
+
if (!this.membership.has(pk)) this.membership.set(pk, slot);
|
|
2844
|
+
slots.push(slot);
|
|
2845
|
+
}
|
|
2846
|
+
this.membershipSeeded = true;
|
|
2847
|
+
super.setSlots(slots);
|
|
2848
|
+
}
|
|
2849
|
+
addPks(pks) {
|
|
2850
|
+
if (pks.length === 0) return;
|
|
2851
|
+
const membership = this.membershipOf();
|
|
2852
|
+
const newSlots = [];
|
|
2853
|
+
for (const pk of pks) {
|
|
2854
|
+
if (membership.has(pk)) continue;
|
|
2855
|
+
const slot = this.resolveRequiredSlot(pk);
|
|
2856
|
+
membership.set(pk, slot);
|
|
2857
|
+
newSlots.push(slot);
|
|
2858
|
+
}
|
|
2859
|
+
if (newSlots.length > 0) super.addSlots(newSlots);
|
|
2860
|
+
}
|
|
2861
|
+
removePks(pks) {
|
|
2862
|
+
if (pks.length === 0) return;
|
|
2863
|
+
const membership = this.membershipOf();
|
|
2864
|
+
if (membership.size === 0) return;
|
|
2865
|
+
const removed = [];
|
|
2866
|
+
for (const pk of pks) {
|
|
2867
|
+
const slot = membership.get(pk);
|
|
2868
|
+
if (slot) {
|
|
2869
|
+
membership.delete(pk);
|
|
2870
|
+
removed.push(slot);
|
|
2871
|
+
}
|
|
2872
|
+
}
|
|
2873
|
+
if (removed.length === 0) return;
|
|
2874
|
+
super.removeSlots(removed);
|
|
2875
|
+
}
|
|
2876
|
+
clear() {
|
|
2877
|
+
this.membership.clear();
|
|
2878
|
+
this.membershipSeeded = false;
|
|
2879
|
+
super.clear();
|
|
2880
|
+
}
|
|
2881
|
+
membershipOf() {
|
|
2882
|
+
if (!this.membershipSeeded) {
|
|
2883
|
+
this.membership.clear();
|
|
2884
|
+
for (const slot of this.index.getSlots()) {
|
|
2885
|
+
this.membership.set(slot.pk, slot);
|
|
2886
|
+
}
|
|
2887
|
+
this.membershipSeeded = true;
|
|
2888
|
+
}
|
|
2889
|
+
return this.membership;
|
|
2890
|
+
}
|
|
2891
|
+
getEntities() {
|
|
2892
|
+
return super.getEntities();
|
|
2893
|
+
}
|
|
2894
|
+
resolveRequiredSlot(pk) {
|
|
2895
|
+
const slot = this.resolveSlot(pk);
|
|
2896
|
+
if (!slot) return { pk, item: void 0 };
|
|
2897
|
+
return slot;
|
|
2898
|
+
}
|
|
2899
|
+
};
|
|
2900
|
+
|
|
2901
|
+
// src/core/OIMDerivedCollectionGlobalIndexArrayBased.ts
|
|
2902
|
+
var OIMDerivedCollectionGlobalIndexArrayBased = class extends OIMReactiveCollectionGlobalIndexManualArrayBased {
|
|
2903
|
+
constructor(queue, collection, opts) {
|
|
2904
|
+
super(queue, { collection, indexOptions: opts.indexOptions });
|
|
2905
|
+
this.presentPks = /* @__PURE__ */ new Set();
|
|
2906
|
+
// Last known sort value per pk (only with `orderBy`), so an update touching
|
|
2907
|
+
// an unrelated field can skip re-sorting when the value is unchanged.
|
|
2908
|
+
this.orderValueByPk = /* @__PURE__ */ new Map();
|
|
2909
|
+
this.onCollectionUpdate = (pks) => {
|
|
2910
|
+
if (pks.length === 0) {
|
|
2911
|
+
this.rebuildFromCollection();
|
|
2912
|
+
return;
|
|
2913
|
+
}
|
|
2914
|
+
const ordered = !!(this.compareEntities || this.orderBy);
|
|
2915
|
+
let needsSort = false;
|
|
2916
|
+
for (const pk of pks) {
|
|
2917
|
+
const prev = this.presentPks.has(pk);
|
|
2918
|
+
const slot = this.collection.getSlotByPk(pk);
|
|
2919
|
+
const entity = slot?.item;
|
|
2920
|
+
const next = entity !== void 0 && (!this.filter || this.filter(entity));
|
|
2921
|
+
let orderChanged = false;
|
|
2922
|
+
if (this.orderBy) {
|
|
2923
|
+
if (!next || entity === void 0) {
|
|
2924
|
+
this.orderValueByPk.delete(pk);
|
|
2925
|
+
} else {
|
|
2926
|
+
const value = this.orderBy(entity);
|
|
2927
|
+
orderChanged = !this.orderValueByPk.has(pk) || this.orderValueByPk.get(pk) !== value;
|
|
2928
|
+
this.orderValueByPk.set(pk, value);
|
|
2929
|
+
}
|
|
2930
|
+
} else if (this.compareEntities && next) {
|
|
2931
|
+
orderChanged = true;
|
|
2932
|
+
}
|
|
2933
|
+
if (prev && !next) {
|
|
2934
|
+
super.removePks([pk]);
|
|
2935
|
+
this.presentPks.delete(pk);
|
|
2936
|
+
} else if (!prev && next) {
|
|
2937
|
+
super.addPks([pk]);
|
|
2938
|
+
this.presentPks.add(pk);
|
|
2939
|
+
if (ordered) needsSort = true;
|
|
2940
|
+
} else if (prev && next && orderChanged) {
|
|
2941
|
+
needsSort = true;
|
|
2942
|
+
}
|
|
2943
|
+
}
|
|
2944
|
+
if (ordered && needsSort) {
|
|
2945
|
+
super.setSlots(this.sortSlots(this.index.getSlots()));
|
|
2946
|
+
}
|
|
2947
|
+
};
|
|
2948
|
+
this.collection = collection;
|
|
2949
|
+
this.compareEntities = opts.compareEntities;
|
|
2950
|
+
this.orderBy = opts.orderBy;
|
|
2951
|
+
this.filter = opts.filter;
|
|
2952
|
+
this.unsubscribeFromCollection = collection.emitter.on(
|
|
2953
|
+
0 /* UPDATE */,
|
|
2954
|
+
(payload) => this.onCollectionUpdate(payload.pks)
|
|
2955
|
+
);
|
|
2956
|
+
if (opts.buildInitial !== false) {
|
|
2957
|
+
this.rebuildFromCollection();
|
|
2958
|
+
}
|
|
2959
|
+
}
|
|
2960
|
+
rebuildFromCollection() {
|
|
2961
|
+
this.presentPks.clear();
|
|
2962
|
+
this.orderValueByPk.clear();
|
|
2963
|
+
super.clear();
|
|
2964
|
+
const slots = [];
|
|
2965
|
+
for (const slot of this.collection.getAllSlots()) {
|
|
2966
|
+
if (slot.item === void 0) continue;
|
|
2967
|
+
if (this.filter && !this.filter(slot.item)) continue;
|
|
2968
|
+
this.presentPks.add(slot.pk);
|
|
2969
|
+
if (this.orderBy) {
|
|
2970
|
+
this.orderValueByPk.set(slot.pk, this.orderBy(slot.item));
|
|
2971
|
+
}
|
|
2972
|
+
slots.push(slot);
|
|
2973
|
+
}
|
|
2974
|
+
super.setSlots(this.sortSlots(slots));
|
|
2975
|
+
}
|
|
2976
|
+
clear() {
|
|
2977
|
+
this.presentPks.clear();
|
|
2978
|
+
this.orderValueByPk.clear();
|
|
2979
|
+
super.clear();
|
|
2980
|
+
}
|
|
2981
|
+
destroy() {
|
|
2982
|
+
this.unsubscribeFromCollection();
|
|
2983
|
+
this.presentPks.clear();
|
|
2984
|
+
this.orderValueByPk.clear();
|
|
2985
|
+
super.destroy();
|
|
2986
|
+
}
|
|
2987
|
+
sortSlots(slots) {
|
|
2988
|
+
if (!this.compareEntities && !this.orderBy) return slots.slice();
|
|
2989
|
+
return slots.slice().sort((a, b) => {
|
|
2990
|
+
const aItem = a.item;
|
|
2991
|
+
const bItem = b.item;
|
|
2992
|
+
if (aItem === void 0 || bItem === void 0) return 0;
|
|
2993
|
+
if (this.compareEntities) {
|
|
2994
|
+
return this.compareEntities(aItem, bItem);
|
|
2995
|
+
}
|
|
2996
|
+
const aValue = this.orderBy(aItem);
|
|
2997
|
+
const bValue = this.orderBy(bItem);
|
|
2998
|
+
if (aValue < bValue) return -1;
|
|
2999
|
+
if (aValue > bValue) return 1;
|
|
3000
|
+
return 0;
|
|
3001
|
+
});
|
|
3002
|
+
}
|
|
3003
|
+
};
|
|
3004
|
+
|
|
3005
|
+
// src/core/OIMDerivedCollectionGlobalIndexSetBased.ts
|
|
3006
|
+
var OIMDerivedCollectionGlobalIndexSetBased = class extends OIMReactiveCollectionGlobalIndexManualSetBased {
|
|
3007
|
+
constructor(queue, collection, opts) {
|
|
3008
|
+
super(queue, { collection, indexOptions: opts.indexOptions });
|
|
3009
|
+
this.presentPks = /* @__PURE__ */ new Set();
|
|
3010
|
+
this.onCollectionUpdate = (pks) => {
|
|
3011
|
+
if (pks.length === 0) {
|
|
3012
|
+
this.rebuildFromCollection();
|
|
3013
|
+
return;
|
|
3014
|
+
}
|
|
3015
|
+
for (const pk of pks) {
|
|
3016
|
+
const prev = this.presentPks.has(pk);
|
|
3017
|
+
const slot = this.collection.getSlotByPk(pk);
|
|
3018
|
+
const entity = slot?.item;
|
|
3019
|
+
const next = entity !== void 0 && (!this.filter || this.filter(entity));
|
|
3020
|
+
if (prev && !next) {
|
|
3021
|
+
super.removePks([pk]);
|
|
3022
|
+
this.presentPks.delete(pk);
|
|
3023
|
+
} else if (!prev && next) {
|
|
3024
|
+
super.addPks([pk]);
|
|
3025
|
+
this.presentPks.add(pk);
|
|
3026
|
+
}
|
|
3027
|
+
}
|
|
3028
|
+
};
|
|
3029
|
+
this.collection = collection;
|
|
3030
|
+
this.filter = opts.filter;
|
|
3031
|
+
this.unsubscribeFromCollection = collection.emitter.on(
|
|
3032
|
+
0 /* UPDATE */,
|
|
3033
|
+
(payload) => this.onCollectionUpdate(payload.pks)
|
|
3034
|
+
);
|
|
3035
|
+
if (opts.buildInitial !== false) {
|
|
3036
|
+
this.rebuildFromCollection();
|
|
3037
|
+
}
|
|
3038
|
+
}
|
|
3039
|
+
rebuildFromCollection() {
|
|
3040
|
+
this.presentPks.clear();
|
|
3041
|
+
super.clear();
|
|
3042
|
+
const slots = /* @__PURE__ */ new Set();
|
|
3043
|
+
for (const slot of this.collection.getAllSlots()) {
|
|
3044
|
+
if (slot.item === void 0) continue;
|
|
3045
|
+
if (this.filter && !this.filter(slot.item)) continue;
|
|
3046
|
+
this.presentPks.add(slot.pk);
|
|
3047
|
+
slots.add(slot);
|
|
3048
|
+
}
|
|
3049
|
+
super.setSlots(slots);
|
|
3050
|
+
}
|
|
3051
|
+
clear() {
|
|
3052
|
+
this.presentPks.clear();
|
|
3053
|
+
super.clear();
|
|
3054
|
+
}
|
|
3055
|
+
destroy() {
|
|
3056
|
+
this.unsubscribeFromCollection();
|
|
3057
|
+
this.presentPks.clear();
|
|
3058
|
+
super.destroy();
|
|
2405
3059
|
}
|
|
2406
3060
|
};
|
|
2407
3061
|
|
|
@@ -2447,6 +3101,52 @@ var OIMCollectionIndexFactory = class {
|
|
|
2447
3101
|
}
|
|
2448
3102
|
);
|
|
2449
3103
|
}
|
|
3104
|
+
/**
|
|
3105
|
+
* Keyless (whole-collection / "all") manual array-based index. No key —
|
|
3106
|
+
* write pks directly with `setPks`/`addPks`/`removePks`.
|
|
3107
|
+
*/
|
|
3108
|
+
arrayBasedGlobalIndex(opts = {}) {
|
|
3109
|
+
return new OIMReactiveCollectionGlobalIndexManualArrayBased(this.queue, {
|
|
3110
|
+
collection: this.collection,
|
|
3111
|
+
indexOptions: opts.indexOptions
|
|
3112
|
+
});
|
|
3113
|
+
}
|
|
3114
|
+
/** Keyless (whole-collection) manual set-based index. */
|
|
3115
|
+
setBasedGlobalIndex(opts = {}) {
|
|
3116
|
+
return new OIMReactiveCollectionGlobalIndexManualSetBased(this.queue, {
|
|
3117
|
+
collection: this.collection,
|
|
3118
|
+
indexOptions: opts.indexOptions
|
|
3119
|
+
});
|
|
3120
|
+
}
|
|
3121
|
+
/**
|
|
3122
|
+
* Keyless ordered list auto-derived from the whole collection. Pass
|
|
3123
|
+
* `orderBy`/`compareEntities` for order, `filter` to include a subset.
|
|
3124
|
+
*/
|
|
3125
|
+
derivedArrayGlobalIndex(opts = {}) {
|
|
3126
|
+
return new OIMDerivedCollectionGlobalIndexArrayBased(
|
|
3127
|
+
this.queue,
|
|
3128
|
+
this.collection,
|
|
3129
|
+
{
|
|
3130
|
+
buildInitial: opts.buildInitial,
|
|
3131
|
+
compareEntities: opts.compareEntities,
|
|
3132
|
+
orderBy: opts.orderBy,
|
|
3133
|
+
filter: opts.filter,
|
|
3134
|
+
indexOptions: opts.indexOptions
|
|
3135
|
+
}
|
|
3136
|
+
);
|
|
3137
|
+
}
|
|
3138
|
+
/** Keyless set auto-derived from the whole collection. */
|
|
3139
|
+
derivedSetGlobalIndex(opts = {}) {
|
|
3140
|
+
return new OIMDerivedCollectionGlobalIndexSetBased(
|
|
3141
|
+
this.queue,
|
|
3142
|
+
this.collection,
|
|
3143
|
+
{
|
|
3144
|
+
buildInitial: opts.buildInitial,
|
|
3145
|
+
filter: opts.filter,
|
|
3146
|
+
indexOptions: opts.indexOptions
|
|
3147
|
+
}
|
|
3148
|
+
);
|
|
3149
|
+
}
|
|
2450
3150
|
orderedIndex() {
|
|
2451
3151
|
return new OIMCollectionIndexManualOrderedArrayBased({
|
|
2452
3152
|
collection: this.collection
|
|
@@ -3324,6 +4024,137 @@ var OIMEntitiesByIndexKeySetBasedSelector = class extends OIMSelector {
|
|
|
3324
4024
|
}
|
|
3325
4025
|
};
|
|
3326
4026
|
|
|
4027
|
+
// src/modules/selector/core/OIMSelectorSourceDependencyEntitiesByGlobalIndexArrayBased.ts
|
|
4028
|
+
var OIMSelectorSourceDependencyEntitiesByGlobalIndexArrayBased = class {
|
|
4029
|
+
constructor(collection, reactiveIndex) {
|
|
4030
|
+
this.collection = collection;
|
|
4031
|
+
this.reactiveIndex = reactiveIndex;
|
|
4032
|
+
this.currentPks = [];
|
|
4033
|
+
}
|
|
4034
|
+
subscribe(onUpdate) {
|
|
4035
|
+
const resubscribeCollection = () => {
|
|
4036
|
+
const nextPks = this.reactiveIndex.getPks();
|
|
4037
|
+
if (this.sameArray(this.currentPks, nextPks)) return;
|
|
4038
|
+
this.unsubscribeFromCollectionKeys?.();
|
|
4039
|
+
this.unsubscribeFromCollectionKeys = void 0;
|
|
4040
|
+
this.currentPks = nextPks;
|
|
4041
|
+
if (this.currentPks.length === 0) return;
|
|
4042
|
+
this.unsubscribeFromCollectionKeys = this.collection.subscribeOnKeys(this.currentPks, onUpdate);
|
|
4043
|
+
};
|
|
4044
|
+
const onIndexUpdate = () => {
|
|
4045
|
+
resubscribeCollection();
|
|
4046
|
+
onUpdate();
|
|
4047
|
+
};
|
|
4048
|
+
resubscribeCollection();
|
|
4049
|
+
const unsubscribeFromIndex = this.reactiveIndex.subscribe(onIndexUpdate);
|
|
4050
|
+
return () => {
|
|
4051
|
+
unsubscribeFromIndex();
|
|
4052
|
+
this.unsubscribeFromCollectionKeys?.();
|
|
4053
|
+
this.unsubscribeFromCollectionKeys = void 0;
|
|
4054
|
+
this.currentPks = [];
|
|
4055
|
+
};
|
|
4056
|
+
}
|
|
4057
|
+
sameArray(a, b) {
|
|
4058
|
+
if (a === b) return true;
|
|
4059
|
+
if (a.length !== b.length) return false;
|
|
4060
|
+
for (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return false;
|
|
4061
|
+
return true;
|
|
4062
|
+
}
|
|
4063
|
+
};
|
|
4064
|
+
|
|
4065
|
+
// src/modules/selector/core/OIMEntitiesByGlobalIndexArrayBasedSelector.ts
|
|
4066
|
+
var OIMEntitiesByGlobalIndexArrayBasedSelector = class extends OIMSelector {
|
|
4067
|
+
constructor(runtime, collection, reactiveIndex) {
|
|
4068
|
+
super(runtime, [
|
|
4069
|
+
new OIMSelectorSourceDependencyEntitiesByGlobalIndexArrayBased(collection, reactiveIndex)
|
|
4070
|
+
]);
|
|
4071
|
+
this.collection = collection;
|
|
4072
|
+
this.reactiveIndex = reactiveIndex;
|
|
4073
|
+
}
|
|
4074
|
+
getValue() {
|
|
4075
|
+
const pks = this.reactiveIndex.getPks();
|
|
4076
|
+
const entities = [];
|
|
4077
|
+
entities.length = pks.length;
|
|
4078
|
+
for (let i = 0; i < pks.length; i++) {
|
|
4079
|
+
entities[i] = this.collection.getOneByPk(pks[i]);
|
|
4080
|
+
}
|
|
4081
|
+
return entities;
|
|
4082
|
+
}
|
|
4083
|
+
areEqual(prev, next) {
|
|
4084
|
+
if (prev === next) return true;
|
|
4085
|
+
if (prev.length !== next.length) return false;
|
|
4086
|
+
for (let i = 0; i < prev.length; i++)
|
|
4087
|
+
if (prev[i] !== next[i]) return false;
|
|
4088
|
+
return true;
|
|
4089
|
+
}
|
|
4090
|
+
};
|
|
4091
|
+
|
|
4092
|
+
// src/modules/selector/core/OIMSelectorSourceDependencyEntitiesByGlobalIndexSetBased.ts
|
|
4093
|
+
var OIMSelectorSourceDependencyEntitiesByGlobalIndexSetBased = class {
|
|
4094
|
+
constructor(collection, reactiveIndex) {
|
|
4095
|
+
this.collection = collection;
|
|
4096
|
+
this.reactiveIndex = reactiveIndex;
|
|
4097
|
+
this.currentPks = [];
|
|
4098
|
+
}
|
|
4099
|
+
subscribe(onUpdate) {
|
|
4100
|
+
const resubscribeCollection = () => {
|
|
4101
|
+
const nextPks = Array.from(this.reactiveIndex.getPks());
|
|
4102
|
+
if (this.sameArray(this.currentPks, nextPks)) return;
|
|
4103
|
+
this.unsubscribeFromCollectionKeys?.();
|
|
4104
|
+
this.unsubscribeFromCollectionKeys = void 0;
|
|
4105
|
+
this.currentPks = nextPks;
|
|
4106
|
+
if (this.currentPks.length === 0) return;
|
|
4107
|
+
this.unsubscribeFromCollectionKeys = this.collection.subscribeOnKeys(this.currentPks, onUpdate);
|
|
4108
|
+
};
|
|
4109
|
+
const onIndexUpdate = () => {
|
|
4110
|
+
resubscribeCollection();
|
|
4111
|
+
onUpdate();
|
|
4112
|
+
};
|
|
4113
|
+
resubscribeCollection();
|
|
4114
|
+
const unsubscribeFromIndex = this.reactiveIndex.subscribe(onIndexUpdate);
|
|
4115
|
+
return () => {
|
|
4116
|
+
unsubscribeFromIndex();
|
|
4117
|
+
this.unsubscribeFromCollectionKeys?.();
|
|
4118
|
+
this.unsubscribeFromCollectionKeys = void 0;
|
|
4119
|
+
this.currentPks = [];
|
|
4120
|
+
};
|
|
4121
|
+
}
|
|
4122
|
+
sameArray(a, b) {
|
|
4123
|
+
if (a === b) return true;
|
|
4124
|
+
if (a.length !== b.length) return false;
|
|
4125
|
+
for (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return false;
|
|
4126
|
+
return true;
|
|
4127
|
+
}
|
|
4128
|
+
};
|
|
4129
|
+
|
|
4130
|
+
// src/modules/selector/core/OIMEntitiesByGlobalIndexSetBasedSelector.ts
|
|
4131
|
+
var OIMEntitiesByGlobalIndexSetBasedSelector = class extends OIMSelector {
|
|
4132
|
+
constructor(runtime, collection, reactiveIndex) {
|
|
4133
|
+
super(runtime, [
|
|
4134
|
+
new OIMSelectorSourceDependencyEntitiesByGlobalIndexSetBased(collection, reactiveIndex)
|
|
4135
|
+
]);
|
|
4136
|
+
this.collection = collection;
|
|
4137
|
+
this.reactiveIndex = reactiveIndex;
|
|
4138
|
+
}
|
|
4139
|
+
getValue() {
|
|
4140
|
+
const pks = this.reactiveIndex.getPks();
|
|
4141
|
+
const entities = [];
|
|
4142
|
+
entities.length = pks.size;
|
|
4143
|
+
let writeIndex = 0;
|
|
4144
|
+
for (const pk of pks) {
|
|
4145
|
+
entities[writeIndex++] = this.collection.getOneByPk(pk);
|
|
4146
|
+
}
|
|
4147
|
+
return entities;
|
|
4148
|
+
}
|
|
4149
|
+
areEqual(prev, next) {
|
|
4150
|
+
if (prev === next) return true;
|
|
4151
|
+
if (prev.length !== next.length) return false;
|
|
4152
|
+
for (let i = 0; i < prev.length; i++)
|
|
4153
|
+
if (prev[i] !== next[i]) return false;
|
|
4154
|
+
return true;
|
|
4155
|
+
}
|
|
4156
|
+
};
|
|
4157
|
+
|
|
3327
4158
|
// src/dx/OIMCollectionSelectors.ts
|
|
3328
4159
|
var OIMCollectionSelectors = class {
|
|
3329
4160
|
constructor(queue, collection) {
|
|
@@ -3356,6 +4187,22 @@ var OIMCollectionSelectors = class {
|
|
|
3356
4187
|
key
|
|
3357
4188
|
);
|
|
3358
4189
|
}
|
|
4190
|
+
/** Entities of a keyless (whole-collection) array-based index, ordered. */
|
|
4191
|
+
entitiesByArrayGlobalIndex(index) {
|
|
4192
|
+
return new OIMEntitiesByGlobalIndexArrayBasedSelector(
|
|
4193
|
+
this.runtime,
|
|
4194
|
+
this.collection,
|
|
4195
|
+
index
|
|
4196
|
+
);
|
|
4197
|
+
}
|
|
4198
|
+
/** Entities of a keyless (whole-collection) set-based index. */
|
|
4199
|
+
entitiesBySetGlobalIndex(index) {
|
|
4200
|
+
return new OIMEntitiesByGlobalIndexSetBasedSelector(
|
|
4201
|
+
this.runtime,
|
|
4202
|
+
this.collection,
|
|
4203
|
+
index
|
|
4204
|
+
);
|
|
4205
|
+
}
|
|
3359
4206
|
};
|
|
3360
4207
|
|
|
3361
4208
|
// src/dx/OIMCollectionKit.ts
|
|
@@ -3557,7 +4404,7 @@ var OIMCollectionChangedFields = class {
|
|
|
3557
4404
|
|
|
3558
4405
|
// src/modules/wrapper/index/OIMOrderedListMappedCommandStream.ts
|
|
3559
4406
|
var OIMOrderedListMappedCommandStream = class _OIMOrderedListMappedCommandStream {
|
|
3560
|
-
constructor(source,
|
|
4407
|
+
constructor(source, create) {
|
|
3561
4408
|
/** Per-key positional mirror of the mapped elements. */
|
|
3562
4409
|
this.mirror = /* @__PURE__ */ new Map();
|
|
3563
4410
|
/** Mapped commands produced for the current delivery, per key. */
|
|
@@ -3565,8 +4412,7 @@ var OIMOrderedListMappedCommandStream = class _OIMOrderedListMappedCommandStream
|
|
|
3565
4412
|
this.subscribers = /* @__PURE__ */ new Map();
|
|
3566
4413
|
this.sourceUnsubscribers = /* @__PURE__ */ new Map();
|
|
3567
4414
|
this.source = source;
|
|
3568
|
-
this.create =
|
|
3569
|
-
this.destroyItem = opts.destroy;
|
|
4415
|
+
this.create = create;
|
|
3570
4416
|
}
|
|
3571
4417
|
subscribeCommands(key, handler) {
|
|
3572
4418
|
this.ensureWired(key);
|
|
@@ -3593,20 +4439,15 @@ var OIMOrderedListMappedCommandStream = class _OIMOrderedListMappedCommandStream
|
|
|
3593
4439
|
return this.mirror.get(key) ?? [];
|
|
3594
4440
|
}
|
|
3595
4441
|
/** Map this source again, chaining the projection. */
|
|
3596
|
-
map(
|
|
4442
|
+
map(create) {
|
|
3597
4443
|
return new _OIMOrderedListMappedCommandStream(
|
|
3598
4444
|
this,
|
|
3599
|
-
|
|
4445
|
+
create
|
|
3600
4446
|
);
|
|
3601
4447
|
}
|
|
3602
4448
|
destroy() {
|
|
3603
4449
|
this.sourceUnsubscribers.forEach((unsubscribe) => unsubscribe());
|
|
3604
4450
|
this.sourceUnsubscribers.clear();
|
|
3605
|
-
if (this.destroyItem) {
|
|
3606
|
-
this.mirror.forEach(
|
|
3607
|
-
(items) => items.forEach((item) => this.destroyItem(item))
|
|
3608
|
-
);
|
|
3609
|
-
}
|
|
3610
4451
|
this.mirror.clear();
|
|
3611
4452
|
this.buffer.clear();
|
|
3612
4453
|
this.subscribers.clear();
|
|
@@ -3646,12 +4487,7 @@ var OIMOrderedListMappedCommandStream = class _OIMOrderedListMappedCommandStream
|
|
|
3646
4487
|
}
|
|
3647
4488
|
case "remove": {
|
|
3648
4489
|
const count = cmd.count ?? 1;
|
|
3649
|
-
|
|
3650
|
-
if (this.destroyItem) {
|
|
3651
|
-
for (let r = 0; r < removed.length; r++) {
|
|
3652
|
-
this.destroyItem(removed[r]);
|
|
3653
|
-
}
|
|
3654
|
-
}
|
|
4490
|
+
mirror.splice(cmd.index, count);
|
|
3655
4491
|
out.push({ type: "remove", index: cmd.index, count });
|
|
3656
4492
|
break;
|
|
3657
4493
|
}
|
|
@@ -3669,19 +4505,11 @@ var OIMOrderedListMappedCommandStream = class _OIMOrderedListMappedCommandStream
|
|
|
3669
4505
|
}
|
|
3670
4506
|
case "set": {
|
|
3671
4507
|
const mapped = this.create(cmd.item);
|
|
3672
|
-
|
|
3673
|
-
if (this.destroyItem && replaced.length > 0) {
|
|
3674
|
-
this.destroyItem(replaced[0]);
|
|
3675
|
-
}
|
|
4508
|
+
mirror.splice(cmd.index, 1, mapped);
|
|
3676
4509
|
out.push({ type: "set", index: cmd.index, item: mapped });
|
|
3677
4510
|
break;
|
|
3678
4511
|
}
|
|
3679
4512
|
case "reset": {
|
|
3680
|
-
if (this.destroyItem) {
|
|
3681
|
-
for (let r = 0; r < mirror.length; r++) {
|
|
3682
|
-
this.destroyItem(mirror[r]);
|
|
3683
|
-
}
|
|
3684
|
-
}
|
|
3685
4513
|
const mapped = cmd.items.map((item) => this.create(item));
|
|
3686
4514
|
mirror = mapped;
|
|
3687
4515
|
this.mirror.set(key, mapped);
|
|
@@ -3707,8 +4535,274 @@ var OIMOrderedListMappedCommandStream = class _OIMOrderedListMappedCommandStream
|
|
|
3707
4535
|
};
|
|
3708
4536
|
|
|
3709
4537
|
// src/modules/wrapper/index/createOIMOrderedListMappedCommandStream.ts
|
|
3710
|
-
function createOIMOrderedListMappedCommandStream(source,
|
|
3711
|
-
return new OIMOrderedListMappedCommandStream(
|
|
4538
|
+
function createOIMOrderedListMappedCommandStream(source, create) {
|
|
4539
|
+
return new OIMOrderedListMappedCommandStream(
|
|
4540
|
+
source,
|
|
4541
|
+
create
|
|
4542
|
+
);
|
|
4543
|
+
}
|
|
4544
|
+
|
|
4545
|
+
// src/modules/wrapper/index/OIMIndexSlotMap.ts
|
|
4546
|
+
var OIMIndexSlotMap = class _OIMIndexSlotMap {
|
|
4547
|
+
constructor(index, create) {
|
|
4548
|
+
this.cache = /* @__PURE__ */ new WeakMap();
|
|
4549
|
+
this.index = index;
|
|
4550
|
+
this.create = create;
|
|
4551
|
+
}
|
|
4552
|
+
/** The mapped object for a slot, created once and cached by slot identity. */
|
|
4553
|
+
get(slot) {
|
|
4554
|
+
let mapped = this.cache.get(slot);
|
|
4555
|
+
if (mapped === void 0 && !this.cache.has(slot)) {
|
|
4556
|
+
mapped = this.create(slot);
|
|
4557
|
+
this.cache.set(slot, mapped);
|
|
4558
|
+
}
|
|
4559
|
+
return mapped;
|
|
4560
|
+
}
|
|
4561
|
+
/**
|
|
4562
|
+
* Mapped objects for every slot under `key`, with stable references. For a
|
|
4563
|
+
* set-based index the order is unspecified (as the set is); for an
|
|
4564
|
+
* array-based index it follows the index order.
|
|
4565
|
+
*/
|
|
4566
|
+
getByKey(key) {
|
|
4567
|
+
const result = [];
|
|
4568
|
+
for (const slot of this.index.getSlotsByKey(key)) {
|
|
4569
|
+
result.push(this.get(slot));
|
|
4570
|
+
}
|
|
4571
|
+
return result;
|
|
4572
|
+
}
|
|
4573
|
+
/**
|
|
4574
|
+
* Chain another projection. `map(f)` returns a slot map over the SAME index
|
|
4575
|
+
* whose objects are `f(this.get(slot))`, cached by slot identity — so both
|
|
4576
|
+
* levels hand back stable references and each `create` runs once per slot.
|
|
4577
|
+
* Mirrors the command stream's `.map()`.
|
|
4578
|
+
*/
|
|
4579
|
+
map(create) {
|
|
4580
|
+
return new _OIMIndexSlotMap(
|
|
4581
|
+
this.index,
|
|
4582
|
+
(slot) => create(this.get(slot))
|
|
4583
|
+
);
|
|
4584
|
+
}
|
|
4585
|
+
/** Subscribe to a key's changes — passthrough to the index. */
|
|
4586
|
+
subscribeOnKey(key, handler) {
|
|
4587
|
+
return this.index.subscribeOnKey(key, handler);
|
|
4588
|
+
}
|
|
4589
|
+
/** Subscribe to several keys — passthrough to the index. */
|
|
4590
|
+
subscribeOnKeys(keys, handler) {
|
|
4591
|
+
return this.index.subscribeOnKeys(keys, handler);
|
|
4592
|
+
}
|
|
4593
|
+
};
|
|
4594
|
+
|
|
4595
|
+
// src/modules/wrapper/index/createOIMIndexSlotMap.ts
|
|
4596
|
+
function createOIMIndexSlotMap(index, create) {
|
|
4597
|
+
return new OIMIndexSlotMap(index, create);
|
|
4598
|
+
}
|
|
4599
|
+
|
|
4600
|
+
// src/modules/wrapper/index/OIMGlobalIndexSlotMap.ts
|
|
4601
|
+
var OIMGlobalIndexSlotMap = class _OIMGlobalIndexSlotMap {
|
|
4602
|
+
constructor(index, create) {
|
|
4603
|
+
this.cache = /* @__PURE__ */ new WeakMap();
|
|
4604
|
+
this.index = index;
|
|
4605
|
+
this.create = create;
|
|
4606
|
+
}
|
|
4607
|
+
/** The mapped object for a slot, created once and cached by slot identity. */
|
|
4608
|
+
get(slot) {
|
|
4609
|
+
let mapped = this.cache.get(slot);
|
|
4610
|
+
if (mapped === void 0 && !this.cache.has(slot)) {
|
|
4611
|
+
mapped = this.create(slot);
|
|
4612
|
+
this.cache.set(slot, mapped);
|
|
4613
|
+
}
|
|
4614
|
+
return mapped;
|
|
4615
|
+
}
|
|
4616
|
+
/**
|
|
4617
|
+
* Mapped objects for every slot in the index, with stable references. For a
|
|
4618
|
+
* set-based global index the order is unspecified (as the set is); for an
|
|
4619
|
+
* array-based one it follows the index order.
|
|
4620
|
+
*/
|
|
4621
|
+
getAll() {
|
|
4622
|
+
const result = [];
|
|
4623
|
+
for (const slot of this.index.getSlots()) {
|
|
4624
|
+
result.push(this.get(slot));
|
|
4625
|
+
}
|
|
4626
|
+
return result;
|
|
4627
|
+
}
|
|
4628
|
+
/**
|
|
4629
|
+
* Chain another projection. `map(f)` returns a slot map over the SAME index
|
|
4630
|
+
* whose objects are `f(this.get(slot))`, cached by slot identity — both
|
|
4631
|
+
* levels hand back stable references and each `create` runs once per slot.
|
|
4632
|
+
*/
|
|
4633
|
+
map(create) {
|
|
4634
|
+
return new _OIMGlobalIndexSlotMap(
|
|
4635
|
+
this.index,
|
|
4636
|
+
(slot) => create(this.get(slot))
|
|
4637
|
+
);
|
|
4638
|
+
}
|
|
4639
|
+
/** Subscribe to the index's changes — passthrough to the index. */
|
|
4640
|
+
subscribe(handler) {
|
|
4641
|
+
return this.index.subscribe(handler);
|
|
4642
|
+
}
|
|
4643
|
+
};
|
|
4644
|
+
|
|
4645
|
+
// src/modules/wrapper/index/createOIMGlobalIndexSlotMap.ts
|
|
4646
|
+
function createOIMGlobalIndexSlotMap(index, create) {
|
|
4647
|
+
return new OIMGlobalIndexSlotMap(index, create);
|
|
4648
|
+
}
|
|
4649
|
+
|
|
4650
|
+
// src/modules/wrapper/index/diffOrderedListByPk.ts
|
|
4651
|
+
function diffOrderedListByPk(prev, next) {
|
|
4652
|
+
const commands = [];
|
|
4653
|
+
const working = prev.slice();
|
|
4654
|
+
const nextPks = /* @__PURE__ */ new Set();
|
|
4655
|
+
for (let i = 0; i < next.length; i++) nextPks.add(next[i].pk);
|
|
4656
|
+
for (let i = working.length - 1; i >= 0; i--) {
|
|
4657
|
+
if (!nextPks.has(working[i].pk)) {
|
|
4658
|
+
commands.push({ type: "remove", index: i });
|
|
4659
|
+
working.splice(i, 1);
|
|
4660
|
+
}
|
|
4661
|
+
}
|
|
4662
|
+
const workingPos = /* @__PURE__ */ new Map();
|
|
4663
|
+
for (let i = 0; i < working.length; i++) workingPos.set(working[i].pk, i);
|
|
4664
|
+
const commonNextJ = [];
|
|
4665
|
+
const seq = [];
|
|
4666
|
+
for (let j = 0; j < next.length; j++) {
|
|
4667
|
+
const p = workingPos.get(next[j].pk);
|
|
4668
|
+
if (p !== void 0) {
|
|
4669
|
+
commonNextJ.push(j);
|
|
4670
|
+
seq.push(p);
|
|
4671
|
+
}
|
|
4672
|
+
}
|
|
4673
|
+
const anchorJ = /* @__PURE__ */ new Set();
|
|
4674
|
+
for (const s of longestIncreasingSubsequence(seq)) {
|
|
4675
|
+
anchorJ.add(commonNextJ[s]);
|
|
4676
|
+
}
|
|
4677
|
+
for (let j = next.length - 1; j >= 0; j--) {
|
|
4678
|
+
if (anchorJ.has(j)) continue;
|
|
4679
|
+
const target = next[j];
|
|
4680
|
+
const refIdx = j + 1 < next.length ? indexByPk(working, next[j + 1].pk) : working.length;
|
|
4681
|
+
const p = indexByPk(working, target.pk);
|
|
4682
|
+
if (p === -1) {
|
|
4683
|
+
commands.push({ type: "insert", index: refIdx, item: target });
|
|
4684
|
+
working.splice(refIdx, 0, target);
|
|
4685
|
+
} else {
|
|
4686
|
+
const to = p < refIdx ? refIdx - 1 : refIdx;
|
|
4687
|
+
if (p !== to) {
|
|
4688
|
+
commands.push({ type: "move", from: p, to });
|
|
4689
|
+
working.splice(p, 1);
|
|
4690
|
+
working.splice(to, 0, target);
|
|
4691
|
+
}
|
|
4692
|
+
}
|
|
4693
|
+
}
|
|
4694
|
+
return commands;
|
|
4695
|
+
}
|
|
4696
|
+
function indexByPk(items, pk) {
|
|
4697
|
+
for (let i = 0; i < items.length; i++) {
|
|
4698
|
+
if (items[i].pk === pk) return i;
|
|
4699
|
+
}
|
|
4700
|
+
return -1;
|
|
4701
|
+
}
|
|
4702
|
+
function longestIncreasingSubsequence(seq) {
|
|
4703
|
+
const n = seq.length;
|
|
4704
|
+
if (n === 0) return [];
|
|
4705
|
+
const predecessor = new Array(n).fill(-1);
|
|
4706
|
+
const tails = [];
|
|
4707
|
+
for (let i = 0; i < n; i++) {
|
|
4708
|
+
let lo = 0;
|
|
4709
|
+
let hi = tails.length;
|
|
4710
|
+
while (lo < hi) {
|
|
4711
|
+
const mid = lo + hi >> 1;
|
|
4712
|
+
if (seq[tails[mid]] < seq[i]) lo = mid + 1;
|
|
4713
|
+
else hi = mid;
|
|
4714
|
+
}
|
|
4715
|
+
if (lo > 0) predecessor[i] = tails[lo - 1];
|
|
4716
|
+
if (lo === tails.length) tails.push(i);
|
|
4717
|
+
else tails[lo] = i;
|
|
4718
|
+
}
|
|
4719
|
+
const result = [];
|
|
4720
|
+
let k = tails[tails.length - 1];
|
|
4721
|
+
while (k !== -1) {
|
|
4722
|
+
result.push(k);
|
|
4723
|
+
k = predecessor[k];
|
|
4724
|
+
}
|
|
4725
|
+
result.reverse();
|
|
4726
|
+
return result;
|
|
4727
|
+
}
|
|
4728
|
+
|
|
4729
|
+
// src/modules/wrapper/index/OIMOrderedListCommandStreamDiffDriven.ts
|
|
4730
|
+
var OIMOrderedListCommandStreamDiffDriven = class extends OIMOrderedListCommandBuffer {
|
|
4731
|
+
constructor(queue, index, opts) {
|
|
4732
|
+
super(queue);
|
|
4733
|
+
this.prevByKey = /* @__PURE__ */ new Map();
|
|
4734
|
+
this.indexUnsubscribeByKey = /* @__PURE__ */ new Map();
|
|
4735
|
+
this.index = index;
|
|
4736
|
+
this.resetThreshold = opts?.resetThreshold ?? 0;
|
|
4737
|
+
}
|
|
4738
|
+
getItemsByKey(key) {
|
|
4739
|
+
this.ensureWired(key);
|
|
4740
|
+
return this.currentSlots(key);
|
|
4741
|
+
}
|
|
4742
|
+
subscribeCommands(key, handler) {
|
|
4743
|
+
this.ensureWired(key);
|
|
4744
|
+
return super.subscribeCommands(key, handler);
|
|
4745
|
+
}
|
|
4746
|
+
destroy() {
|
|
4747
|
+
this.indexUnsubscribeByKey.forEach((unsubscribe) => unsubscribe());
|
|
4748
|
+
this.indexUnsubscribeByKey.clear();
|
|
4749
|
+
this.prevByKey.clear();
|
|
4750
|
+
super.destroy();
|
|
4751
|
+
}
|
|
4752
|
+
currentSlots(key) {
|
|
4753
|
+
return this.index.getSlotsByKey(key);
|
|
4754
|
+
}
|
|
4755
|
+
/** Snapshot the current order and subscribe to the index once per key. */
|
|
4756
|
+
ensureWired(key) {
|
|
4757
|
+
if (this.indexUnsubscribeByKey.has(key)) return;
|
|
4758
|
+
this.prevByKey.set(key, this.currentSlots(key).slice());
|
|
4759
|
+
const unsubscribe = this.index.subscribeOnKey(
|
|
4760
|
+
key,
|
|
4761
|
+
() => this.onIndexChange(key)
|
|
4762
|
+
);
|
|
4763
|
+
this.indexUnsubscribeByKey.set(key, unsubscribe);
|
|
4764
|
+
}
|
|
4765
|
+
onIndexChange(key) {
|
|
4766
|
+
const prev = this.prevByKey.get(key) ?? [];
|
|
4767
|
+
const next = this.currentSlots(key);
|
|
4768
|
+
this.emitDiff(key, prev, next);
|
|
4769
|
+
this.prevByKey.set(key, next.slice());
|
|
4770
|
+
}
|
|
4771
|
+
emitDiff(key, prev, next) {
|
|
4772
|
+
if (sameOrderByPk(prev, next)) return;
|
|
4773
|
+
const commons = countCommonPks(prev, next);
|
|
4774
|
+
const larger = Math.max(prev.length, next.length);
|
|
4775
|
+
const wholeChange = prev.length === 0 || next.length === 0 || commons === 0 || this.resetThreshold > 0 && commons / larger < this.resetThreshold;
|
|
4776
|
+
if (wholeChange) {
|
|
4777
|
+
this.appendResetCommand(key, next);
|
|
4778
|
+
return;
|
|
4779
|
+
}
|
|
4780
|
+
const commands = diffOrderedListByPk(prev, next);
|
|
4781
|
+
for (let i = 0; i < commands.length; i++) {
|
|
4782
|
+
this.appendCommand(key, commands[i]);
|
|
4783
|
+
}
|
|
4784
|
+
}
|
|
4785
|
+
};
|
|
4786
|
+
function sameOrderByPk(a, b) {
|
|
4787
|
+
if (a.length !== b.length) return false;
|
|
4788
|
+
for (let i = 0; i < a.length; i++) {
|
|
4789
|
+
if (a[i].pk !== b[i].pk) return false;
|
|
4790
|
+
}
|
|
4791
|
+
return true;
|
|
4792
|
+
}
|
|
4793
|
+
function countCommonPks(prev, next) {
|
|
4794
|
+
const prevPks = /* @__PURE__ */ new Set();
|
|
4795
|
+
for (let i = 0; i < prev.length; i++) prevPks.add(prev[i].pk);
|
|
4796
|
+
let common = 0;
|
|
4797
|
+
for (let i = 0; i < next.length; i++) {
|
|
4798
|
+
if (prevPks.has(next[i].pk)) common++;
|
|
4799
|
+
}
|
|
4800
|
+
return common;
|
|
4801
|
+
}
|
|
4802
|
+
|
|
4803
|
+
// src/modules/wrapper/index/createOIMOrderedListCommandStreamDiffDriven.ts
|
|
4804
|
+
function createOIMOrderedListCommandStreamDiffDriven(queue, index, opts) {
|
|
4805
|
+
return new OIMOrderedListCommandStreamDiffDriven(queue, index, opts);
|
|
3712
4806
|
}
|
|
3713
4807
|
|
|
3714
4808
|
// src/core/event-queue-scheduler/OIMEventQueueSchedulerAnimationFrame.ts
|
|
@@ -3835,6 +4929,15 @@ var OIMEventQueueSchedulerImmediate = class extends OIMEventQueueScheduler {
|
|
|
3835
4929
|
}
|
|
3836
4930
|
};
|
|
3837
4931
|
|
|
4932
|
+
// src/core/event-queue-scheduler/OIMEventQueueSchedulerSync.ts
|
|
4933
|
+
var OIMEventQueueSchedulerSync = class extends OIMEventQueueScheduler {
|
|
4934
|
+
schedule() {
|
|
4935
|
+
this.flush();
|
|
4936
|
+
}
|
|
4937
|
+
cancel() {
|
|
4938
|
+
}
|
|
4939
|
+
};
|
|
4940
|
+
|
|
3838
4941
|
// src/core/event-queue-scheduler/OIMEventQueueSchedulerFactory.ts
|
|
3839
4942
|
var OIMEventQueueSchedulerFactory = class {
|
|
3840
4943
|
/**
|
|
@@ -3852,6 +4955,8 @@ var OIMEventQueueSchedulerFactory = class {
|
|
|
3852
4955
|
}
|
|
3853
4956
|
case "immediate":
|
|
3854
4957
|
return new OIMEventQueueSchedulerImmediate();
|
|
4958
|
+
case "sync":
|
|
4959
|
+
return new OIMEventQueueSchedulerSync();
|
|
3855
4960
|
default:
|
|
3856
4961
|
throw new Error(`Unknown scheduler type: ${type}`);
|
|
3857
4962
|
}
|
|
@@ -3875,11 +4980,18 @@ var OIMEventQueueSchedulerFactory = class {
|
|
|
3875
4980
|
return new OIMEventQueueSchedulerTimeout(delay);
|
|
3876
4981
|
}
|
|
3877
4982
|
/**
|
|
3878
|
-
* Create an immediate scheduler (
|
|
4983
|
+
* Create an immediate scheduler (setImmediate / MessageChannel / setTimeout(0)).
|
|
3879
4984
|
*/
|
|
3880
4985
|
static createImmediate() {
|
|
3881
4986
|
return new OIMEventQueueSchedulerImmediate();
|
|
3882
4987
|
}
|
|
4988
|
+
/**
|
|
4989
|
+
* Create a synchronous scheduler — flushes in the same call stack, no
|
|
4990
|
+
* batching. Debug/diagnostic use only (see {@link OIMEventQueueSchedulerSync}).
|
|
4991
|
+
*/
|
|
4992
|
+
static createSync() {
|
|
4993
|
+
return new OIMEventQueueSchedulerSync();
|
|
4994
|
+
}
|
|
3883
4995
|
};
|
|
3884
4996
|
|
|
3885
4997
|
// src/constants/OIMDBSettings.ts
|
|
@@ -4287,6 +5399,7 @@ export {
|
|
|
4287
5399
|
EOIMIndexEventType,
|
|
4288
5400
|
EOIMObjectEventType,
|
|
4289
5401
|
OIMCarrierKeyedEmitter,
|
|
5402
|
+
OIMCarrierSingleEmitter,
|
|
4290
5403
|
OIMCollection,
|
|
4291
5404
|
OIMCollectionByPkSelector,
|
|
4292
5405
|
OIMCollectionByPksSelector,
|
|
@@ -4301,6 +5414,8 @@ export {
|
|
|
4301
5414
|
OIMComputeRuntime,
|
|
4302
5415
|
OIMComputed,
|
|
4303
5416
|
OIMDBSettings,
|
|
5417
|
+
OIMDerivedCollectionGlobalIndexArrayBased,
|
|
5418
|
+
OIMDerivedCollectionGlobalIndexSetBased,
|
|
4304
5419
|
OIMDerivedCollectionIndexArrayBased,
|
|
4305
5420
|
OIMDerivedCollectionIndexSetBased,
|
|
4306
5421
|
OIMEffect,
|
|
@@ -4309,6 +5424,8 @@ export {
|
|
|
4309
5424
|
OIMEffectDependencyKeyedCollection,
|
|
4310
5425
|
OIMEffectDependencyKeyedIndex,
|
|
4311
5426
|
OIMEffectDependencyKeyedObject,
|
|
5427
|
+
OIMEntitiesByGlobalIndexArrayBasedSelector,
|
|
5428
|
+
OIMEntitiesByGlobalIndexSetBasedSelector,
|
|
4312
5429
|
OIMEntitiesByIndexKeyArrayBasedSelector,
|
|
4313
5430
|
OIMEntitiesByIndexKeySetBasedSelector,
|
|
4314
5431
|
OIMEntityUpdaterFactory,
|
|
@@ -4319,7 +5436,14 @@ export {
|
|
|
4319
5436
|
OIMEventQueueSchedulerFactory,
|
|
4320
5437
|
OIMEventQueueSchedulerImmediate,
|
|
4321
5438
|
OIMEventQueueSchedulerMicrotask,
|
|
5439
|
+
OIMEventQueueSchedulerSync,
|
|
4322
5440
|
OIMEventQueueSchedulerTimeout,
|
|
5441
|
+
OIMGlobalIndex,
|
|
5442
|
+
OIMGlobalIndexArrayBased,
|
|
5443
|
+
OIMGlobalIndexManualArrayBased,
|
|
5444
|
+
OIMGlobalIndexManualSetBased,
|
|
5445
|
+
OIMGlobalIndexSetBased,
|
|
5446
|
+
OIMGlobalIndexSlotMap,
|
|
4323
5447
|
OIMIndex,
|
|
4324
5448
|
OIMIndexArrayBased,
|
|
4325
5449
|
OIMIndexComparatorFactory,
|
|
@@ -4331,6 +5455,7 @@ export {
|
|
|
4331
5455
|
OIMIndexPksByKeysArrayBasedSelector,
|
|
4332
5456
|
OIMIndexPksByKeysSetBasedSelector,
|
|
4333
5457
|
OIMIndexSetBased,
|
|
5458
|
+
OIMIndexSlotMap,
|
|
4334
5459
|
OIMIndexStoreArrayBased,
|
|
4335
5460
|
OIMIndexStoreMapDrivenArrayBased,
|
|
4336
5461
|
OIMIndexStoreMapDrivenSetBased,
|
|
@@ -4342,12 +5467,21 @@ export {
|
|
|
4342
5467
|
OIMObjectStoreRecordDriven,
|
|
4343
5468
|
OIMObjectValueByKeySelector,
|
|
4344
5469
|
OIMObjectValuesByKeysSelector,
|
|
5470
|
+
OIMOrderedListCommandBuffer,
|
|
4345
5471
|
OIMOrderedListCommandStream,
|
|
5472
|
+
OIMOrderedListCommandStreamDiffDriven,
|
|
4346
5473
|
OIMOrderedListMappedCommandStream,
|
|
4347
5474
|
OIMPkSelectorFactory,
|
|
4348
5475
|
OIMReactiveCollection,
|
|
5476
|
+
OIMReactiveCollectionGlobalIndexManualArrayBased,
|
|
5477
|
+
OIMReactiveCollectionGlobalIndexManualSetBased,
|
|
4349
5478
|
OIMReactiveCollectionIndexManualArrayBased,
|
|
4350
5479
|
OIMReactiveCollectionIndexManualSetBased,
|
|
5480
|
+
OIMReactiveGlobalIndex,
|
|
5481
|
+
OIMReactiveGlobalIndexArrayBased,
|
|
5482
|
+
OIMReactiveGlobalIndexManualArrayBased,
|
|
5483
|
+
OIMReactiveGlobalIndexManualSetBased,
|
|
5484
|
+
OIMReactiveGlobalIndexSetBased,
|
|
4351
5485
|
OIMReactiveIndex,
|
|
4352
5486
|
OIMReactiveIndexArrayBased,
|
|
4353
5487
|
OIMReactiveIndexManualArrayBased,
|
|
@@ -4359,5 +5493,9 @@ export {
|
|
|
4359
5493
|
createMergeEntityUpdater,
|
|
4360
5494
|
createOIMCollectionIndexFactory,
|
|
4361
5495
|
createOIMCollectionKit,
|
|
4362
|
-
|
|
5496
|
+
createOIMGlobalIndexSlotMap,
|
|
5497
|
+
createOIMIndexSlotMap,
|
|
5498
|
+
createOIMOrderedListCommandStreamDiffDriven,
|
|
5499
|
+
createOIMOrderedListMappedCommandStream,
|
|
5500
|
+
diffOrderedListByPk
|
|
4363
5501
|
};
|