@oimdb/core 3.4.0 → 3.6.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 +1424 -146
- package/dist/index.d.cts +741 -29
- package/dist/index.d.ts +741 -29
- package/dist/index.js +1397 -145
- package/llms.txt +82 -2
- 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,6 +1881,10 @@ var OIMOrderedListCommandStream = class {
|
|
|
1601
1881
|
key
|
|
1602
1882
|
);
|
|
1603
1883
|
}
|
|
1884
|
+
/** {@link OIMOrderedListCommandBuffer.getItemsByKey} — the slots in order. */
|
|
1885
|
+
getItemsByKey(key) {
|
|
1886
|
+
return this.getSlotsByKey(key);
|
|
1887
|
+
}
|
|
1604
1888
|
getEntitiesByKey(key) {
|
|
1605
1889
|
return this.index.getEntitiesByKey(key);
|
|
1606
1890
|
}
|
|
@@ -1611,57 +1895,46 @@ var OIMOrderedListCommandStream = class {
|
|
|
1611
1895
|
return this.index.getKeys();
|
|
1612
1896
|
}
|
|
1613
1897
|
pushSlot(key, slot) {
|
|
1614
|
-
this.
|
|
1615
|
-
|
|
1616
|
-
this.appendCommand(key, { type: "insert", index, item: slot });
|
|
1617
|
-
});
|
|
1898
|
+
const index = this.index.pushSlot(key, slot);
|
|
1899
|
+
this.appendCommand(key, { type: "insert", index, item: slot });
|
|
1618
1900
|
}
|
|
1619
1901
|
insertSlotAt(key, index, slot) {
|
|
1620
|
-
this.
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
item: slot
|
|
1626
|
-
});
|
|
1902
|
+
const safeIndex = this.index.insertSlotAt(key, index, slot);
|
|
1903
|
+
this.appendCommand(key, {
|
|
1904
|
+
type: "insert",
|
|
1905
|
+
index: safeIndex,
|
|
1906
|
+
item: slot
|
|
1627
1907
|
});
|
|
1628
1908
|
}
|
|
1629
1909
|
/** Replace the slot at `index` in place. */
|
|
1630
1910
|
setSlotAt(key, index, slot) {
|
|
1631
|
-
this.
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
item: slot
|
|
1638
|
-
});
|
|
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
|
|
1639
1917
|
});
|
|
1640
1918
|
}
|
|
1641
1919
|
removeAt(key, index) {
|
|
1642
|
-
this.
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
this.appendCommand(key, { type: "remove", index });
|
|
1646
|
-
});
|
|
1920
|
+
const slot = this.index.removeAt(key, index);
|
|
1921
|
+
if (slot === void 0) return;
|
|
1922
|
+
this.appendCommand(key, { type: "remove", index });
|
|
1647
1923
|
}
|
|
1648
1924
|
/** Remove `count` consecutive elements from `index`; emits `remove` with `count`. */
|
|
1649
1925
|
removeRange(key, index, count) {
|
|
1650
|
-
this.
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
this.appendCommand(key, { type: "remove", index, count: removed });
|
|
1654
|
-
});
|
|
1926
|
+
const removed = this.index.removeRange(key, index, count);
|
|
1927
|
+
if (removed <= 0) return;
|
|
1928
|
+
this.appendCommand(key, { type: "remove", index, count: removed });
|
|
1655
1929
|
}
|
|
1656
1930
|
move(key, fromIndex, toIndex) {
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
});
|
|
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
|
|
1665
1938
|
});
|
|
1666
1939
|
}
|
|
1667
1940
|
/**
|
|
@@ -1669,74 +1942,31 @@ var OIMOrderedListCommandStream = class {
|
|
|
1669
1942
|
* `count`. `to` is in the post-extraction coordinate space (as single `move`).
|
|
1670
1943
|
*/
|
|
1671
1944
|
moveRange(key, from, to, count) {
|
|
1672
|
-
this.
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
this.appendCommand(key, { type: "move", from, to, count: moved });
|
|
1676
|
-
});
|
|
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 });
|
|
1677
1948
|
}
|
|
1678
1949
|
setSlots(key, slots) {
|
|
1679
|
-
this.
|
|
1680
|
-
|
|
1681
|
-
this.appendResetCommand(key, slots);
|
|
1682
|
-
});
|
|
1683
|
-
}
|
|
1684
|
-
getBufferedCommands(key) {
|
|
1685
|
-
return this.commandsByKey.get(key) ?? [];
|
|
1686
|
-
}
|
|
1687
|
-
consumeCommands(key) {
|
|
1688
|
-
const cmds = this.commandsByKey.get(key);
|
|
1689
|
-
if (!cmds || cmds.length === 0) return [];
|
|
1690
|
-
return cmds.slice();
|
|
1950
|
+
this.index.resetSlots(key, slots);
|
|
1951
|
+
this.appendResetCommand(key, slots);
|
|
1691
1952
|
}
|
|
1692
1953
|
clear(key) {
|
|
1693
1954
|
if (key === void 0) {
|
|
1694
|
-
this.
|
|
1695
|
-
|
|
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
|
+
}
|
|
1696
1961
|
return;
|
|
1697
1962
|
}
|
|
1963
|
+
if (!this.index.hasKey(key)) return;
|
|
1698
1964
|
this.index.clear(key);
|
|
1699
|
-
this.
|
|
1965
|
+
this.appendResetCommand(key, []);
|
|
1700
1966
|
}
|
|
1701
1967
|
destroy() {
|
|
1702
|
-
this.
|
|
1703
|
-
|
|
1704
|
-
this.unsubscribeFromIndexEmitter();
|
|
1705
|
-
this.clear();
|
|
1706
|
-
}
|
|
1707
|
-
withWrite(fn) {
|
|
1708
|
-
if (this.isInWrite) {
|
|
1709
|
-
fn();
|
|
1710
|
-
return;
|
|
1711
|
-
}
|
|
1712
|
-
this.isInWrite = true;
|
|
1713
|
-
try {
|
|
1714
|
-
fn();
|
|
1715
|
-
} finally {
|
|
1716
|
-
this.isInWrite = false;
|
|
1717
|
-
}
|
|
1718
|
-
}
|
|
1719
|
-
appendCommand(key, cmd) {
|
|
1720
|
-
let cmds = this.commandsByKey.get(key);
|
|
1721
|
-
if (!cmds) {
|
|
1722
|
-
cmds = [];
|
|
1723
|
-
this.commandsByKey.set(key, cmds);
|
|
1724
|
-
}
|
|
1725
|
-
if (cmd.type === "reset") {
|
|
1726
|
-
cmds.length = 0;
|
|
1727
|
-
cmds.push(cmd);
|
|
1728
|
-
} else if (cmds.length > 0 && cmds[0].type === "reset") {
|
|
1729
|
-
cmds[0] = this.createResetCommand(this.getSlotsByKey(key));
|
|
1730
|
-
} else {
|
|
1731
|
-
cmds.push(cmd);
|
|
1732
|
-
}
|
|
1733
|
-
this.commandsEventEmitter.markUpdatedKeys([key]);
|
|
1734
|
-
}
|
|
1735
|
-
appendResetCommand(key, slots) {
|
|
1736
|
-
this.appendCommand(key, this.createResetCommand(slots));
|
|
1737
|
-
}
|
|
1738
|
-
createResetCommand(slots) {
|
|
1739
|
-
return { type: "reset", items: slots };
|
|
1968
|
+
this.index.destroy();
|
|
1969
|
+
super.destroy();
|
|
1740
1970
|
}
|
|
1741
1971
|
};
|
|
1742
1972
|
|
|
@@ -1750,42 +1980,34 @@ var OIMCollectionOrderedListCommandStream = class extends OIMOrderedListCommandS
|
|
|
1750
1980
|
this.index = index;
|
|
1751
1981
|
}
|
|
1752
1982
|
push(key, pk) {
|
|
1753
|
-
this.
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
this.appendCommand(key, { type: "insert", index, item: slot });
|
|
1757
|
-
});
|
|
1983
|
+
const slot = this.resolvePk(pk);
|
|
1984
|
+
const index = this.index.pushSlot(key, slot);
|
|
1985
|
+
this.appendCommand(key, { type: "insert", index, item: slot });
|
|
1758
1986
|
}
|
|
1759
1987
|
insertAt(key, index, pk) {
|
|
1760
|
-
this.
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
item: slot
|
|
1767
|
-
});
|
|
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
|
|
1768
1994
|
});
|
|
1769
1995
|
}
|
|
1770
1996
|
/** Replace the element at `index` with the slot for `pk`, in place. */
|
|
1771
1997
|
setAt(key, index, pk) {
|
|
1772
|
-
this.
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
item: slot
|
|
1780
|
-
});
|
|
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
|
|
1781
2005
|
});
|
|
1782
2006
|
}
|
|
1783
2007
|
set(key, pks) {
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
this.appendResetCommand(key, slots);
|
|
1788
|
-
});
|
|
2008
|
+
const slots = pks.map((pk) => this.resolvePk(pk));
|
|
2009
|
+
this.index.resetSlots(key, slots);
|
|
2010
|
+
this.appendResetCommand(key, slots);
|
|
1789
2011
|
}
|
|
1790
2012
|
getSlotsByKey(key) {
|
|
1791
2013
|
return this.index.getSlotsByKey(
|
|
@@ -1796,7 +2018,9 @@ var OIMCollectionOrderedListCommandStream = class extends OIMOrderedListCommandS
|
|
|
1796
2018
|
return this.index.getEntitiesByKey(key);
|
|
1797
2019
|
}
|
|
1798
2020
|
resolvePk(pk) {
|
|
1799
|
-
return this.index.resolvePk(
|
|
2021
|
+
return this.index.resolvePk(
|
|
2022
|
+
pk
|
|
2023
|
+
);
|
|
1800
2024
|
}
|
|
1801
2025
|
};
|
|
1802
2026
|
|
|
@@ -2393,7 +2617,445 @@ var OIMDerivedCollectionIndexArrayBased = class extends OIMReactiveCollectionInd
|
|
|
2393
2617
|
seen.add(key);
|
|
2394
2618
|
result.push(key);
|
|
2395
2619
|
}
|
|
2396
|
-
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();
|
|
2397
3059
|
}
|
|
2398
3060
|
};
|
|
2399
3061
|
|
|
@@ -2439,6 +3101,52 @@ var OIMCollectionIndexFactory = class {
|
|
|
2439
3101
|
}
|
|
2440
3102
|
);
|
|
2441
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
|
+
}
|
|
2442
3150
|
orderedIndex() {
|
|
2443
3151
|
return new OIMCollectionIndexManualOrderedArrayBased({
|
|
2444
3152
|
collection: this.collection
|
|
@@ -3316,6 +4024,137 @@ var OIMEntitiesByIndexKeySetBasedSelector = class extends OIMSelector {
|
|
|
3316
4024
|
}
|
|
3317
4025
|
};
|
|
3318
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
|
+
|
|
3319
4158
|
// src/dx/OIMCollectionSelectors.ts
|
|
3320
4159
|
var OIMCollectionSelectors = class {
|
|
3321
4160
|
constructor(queue, collection) {
|
|
@@ -3348,6 +4187,22 @@ var OIMCollectionSelectors = class {
|
|
|
3348
4187
|
key
|
|
3349
4188
|
);
|
|
3350
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
|
+
}
|
|
3351
4206
|
};
|
|
3352
4207
|
|
|
3353
4208
|
// src/dx/OIMCollectionKit.ts
|
|
@@ -3547,6 +4402,359 @@ var OIMCollectionChangedFields = class {
|
|
|
3547
4402
|
}
|
|
3548
4403
|
};
|
|
3549
4404
|
|
|
4405
|
+
// src/modules/wrapper/index/OIMOrderedListMappedCommandStream.ts
|
|
4406
|
+
var OIMOrderedListMappedCommandStream = class _OIMOrderedListMappedCommandStream {
|
|
4407
|
+
constructor(source, create) {
|
|
4408
|
+
/** Per-key positional mirror of the mapped elements. */
|
|
4409
|
+
this.mirror = /* @__PURE__ */ new Map();
|
|
4410
|
+
/** Mapped commands produced for the current delivery, per key. */
|
|
4411
|
+
this.buffer = /* @__PURE__ */ new Map();
|
|
4412
|
+
this.subscribers = /* @__PURE__ */ new Map();
|
|
4413
|
+
this.sourceUnsubscribers = /* @__PURE__ */ new Map();
|
|
4414
|
+
this.source = source;
|
|
4415
|
+
this.create = create;
|
|
4416
|
+
}
|
|
4417
|
+
subscribeCommands(key, handler) {
|
|
4418
|
+
this.ensureWired(key);
|
|
4419
|
+
let subs = this.subscribers.get(key);
|
|
4420
|
+
if (!subs) {
|
|
4421
|
+
subs = /* @__PURE__ */ new Set();
|
|
4422
|
+
this.subscribers.set(key, subs);
|
|
4423
|
+
}
|
|
4424
|
+
subs.add(handler);
|
|
4425
|
+
return () => {
|
|
4426
|
+
const current = this.subscribers.get(key);
|
|
4427
|
+
if (!current) return;
|
|
4428
|
+
current.delete(handler);
|
|
4429
|
+
if (current.size === 0) this.subscribers.delete(key);
|
|
4430
|
+
};
|
|
4431
|
+
}
|
|
4432
|
+
consumeCommands(key) {
|
|
4433
|
+
const cmds = this.buffer.get(key);
|
|
4434
|
+
if (!cmds || cmds.length === 0) return [];
|
|
4435
|
+
return cmds.slice();
|
|
4436
|
+
}
|
|
4437
|
+
getItemsByKey(key) {
|
|
4438
|
+
this.ensureWired(key);
|
|
4439
|
+
return this.mirror.get(key) ?? [];
|
|
4440
|
+
}
|
|
4441
|
+
/** Map this source again, chaining the projection. */
|
|
4442
|
+
map(create) {
|
|
4443
|
+
return new _OIMOrderedListMappedCommandStream(
|
|
4444
|
+
this,
|
|
4445
|
+
create
|
|
4446
|
+
);
|
|
4447
|
+
}
|
|
4448
|
+
destroy() {
|
|
4449
|
+
this.sourceUnsubscribers.forEach((unsubscribe) => unsubscribe());
|
|
4450
|
+
this.sourceUnsubscribers.clear();
|
|
4451
|
+
this.mirror.clear();
|
|
4452
|
+
this.buffer.clear();
|
|
4453
|
+
this.subscribers.clear();
|
|
4454
|
+
}
|
|
4455
|
+
/** Build the initial mirror and subscribe to the source once per key. */
|
|
4456
|
+
ensureWired(key) {
|
|
4457
|
+
if (this.mirror.has(key)) return;
|
|
4458
|
+
const items = this.source.getItemsByKey(key);
|
|
4459
|
+
this.mirror.set(key, items.map((item) => this.create(item)));
|
|
4460
|
+
const unsubscribe = this.source.subscribeCommands(
|
|
4461
|
+
key,
|
|
4462
|
+
() => this.onSourceCommands(key)
|
|
4463
|
+
);
|
|
4464
|
+
this.sourceUnsubscribers.set(key, unsubscribe);
|
|
4465
|
+
}
|
|
4466
|
+
onSourceCommands(key) {
|
|
4467
|
+
const cmds = this.source.consumeCommands(key);
|
|
4468
|
+
if (cmds.length === 0) return;
|
|
4469
|
+
let mirror = this.mirror.get(key);
|
|
4470
|
+
if (!mirror) {
|
|
4471
|
+
mirror = [];
|
|
4472
|
+
this.mirror.set(key, mirror);
|
|
4473
|
+
}
|
|
4474
|
+
const out = [];
|
|
4475
|
+
for (let i = 0; i < cmds.length; i++) {
|
|
4476
|
+
const cmd = cmds[i];
|
|
4477
|
+
switch (cmd.type) {
|
|
4478
|
+
case "insert": {
|
|
4479
|
+
const mapped = this.create(cmd.item);
|
|
4480
|
+
mirror.splice(cmd.index, 0, mapped);
|
|
4481
|
+
out.push({
|
|
4482
|
+
type: "insert",
|
|
4483
|
+
index: cmd.index,
|
|
4484
|
+
item: mapped
|
|
4485
|
+
});
|
|
4486
|
+
break;
|
|
4487
|
+
}
|
|
4488
|
+
case "remove": {
|
|
4489
|
+
const count = cmd.count ?? 1;
|
|
4490
|
+
mirror.splice(cmd.index, count);
|
|
4491
|
+
out.push({ type: "remove", index: cmd.index, count });
|
|
4492
|
+
break;
|
|
4493
|
+
}
|
|
4494
|
+
case "move": {
|
|
4495
|
+
const count = cmd.count ?? 1;
|
|
4496
|
+
const segment = mirror.splice(cmd.from, count);
|
|
4497
|
+
mirror.splice(cmd.to, 0, ...segment);
|
|
4498
|
+
out.push({
|
|
4499
|
+
type: "move",
|
|
4500
|
+
from: cmd.from,
|
|
4501
|
+
to: cmd.to,
|
|
4502
|
+
count
|
|
4503
|
+
});
|
|
4504
|
+
break;
|
|
4505
|
+
}
|
|
4506
|
+
case "set": {
|
|
4507
|
+
const mapped = this.create(cmd.item);
|
|
4508
|
+
mirror.splice(cmd.index, 1, mapped);
|
|
4509
|
+
out.push({ type: "set", index: cmd.index, item: mapped });
|
|
4510
|
+
break;
|
|
4511
|
+
}
|
|
4512
|
+
case "reset": {
|
|
4513
|
+
const mapped = cmd.items.map((item) => this.create(item));
|
|
4514
|
+
mirror = mapped;
|
|
4515
|
+
this.mirror.set(key, mapped);
|
|
4516
|
+
out.push({ type: "reset", items: mapped });
|
|
4517
|
+
break;
|
|
4518
|
+
}
|
|
4519
|
+
}
|
|
4520
|
+
}
|
|
4521
|
+
this.buffer.set(key, out);
|
|
4522
|
+
try {
|
|
4523
|
+
const subs = this.subscribers.get(key);
|
|
4524
|
+
if (subs && subs.size > 0) {
|
|
4525
|
+
const snapshot = Array.from(subs);
|
|
4526
|
+
for (let s = 0; s < snapshot.length; s++) {
|
|
4527
|
+
const handler = snapshot[s];
|
|
4528
|
+
if (subs.has(handler)) handler();
|
|
4529
|
+
}
|
|
4530
|
+
}
|
|
4531
|
+
} finally {
|
|
4532
|
+
this.buffer.delete(key);
|
|
4533
|
+
}
|
|
4534
|
+
}
|
|
4535
|
+
};
|
|
4536
|
+
|
|
4537
|
+
// src/modules/wrapper/index/createOIMOrderedListMappedCommandStream.ts
|
|
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/diffOrderedListByPk.ts
|
|
4601
|
+
function diffOrderedListByPk(prev, next) {
|
|
4602
|
+
const commands = [];
|
|
4603
|
+
const working = prev.slice();
|
|
4604
|
+
const nextPks = /* @__PURE__ */ new Set();
|
|
4605
|
+
for (let i = 0; i < next.length; i++) nextPks.add(next[i].pk);
|
|
4606
|
+
for (let i = working.length - 1; i >= 0; i--) {
|
|
4607
|
+
if (!nextPks.has(working[i].pk)) {
|
|
4608
|
+
commands.push({ type: "remove", index: i });
|
|
4609
|
+
working.splice(i, 1);
|
|
4610
|
+
}
|
|
4611
|
+
}
|
|
4612
|
+
const workingPos = /* @__PURE__ */ new Map();
|
|
4613
|
+
for (let i = 0; i < working.length; i++) workingPos.set(working[i].pk, i);
|
|
4614
|
+
const commonNextJ = [];
|
|
4615
|
+
const seq = [];
|
|
4616
|
+
for (let j = 0; j < next.length; j++) {
|
|
4617
|
+
const p = workingPos.get(next[j].pk);
|
|
4618
|
+
if (p !== void 0) {
|
|
4619
|
+
commonNextJ.push(j);
|
|
4620
|
+
seq.push(p);
|
|
4621
|
+
}
|
|
4622
|
+
}
|
|
4623
|
+
const anchorJ = /* @__PURE__ */ new Set();
|
|
4624
|
+
for (const s of longestIncreasingSubsequence(seq)) {
|
|
4625
|
+
anchorJ.add(commonNextJ[s]);
|
|
4626
|
+
}
|
|
4627
|
+
for (let j = next.length - 1; j >= 0; j--) {
|
|
4628
|
+
if (anchorJ.has(j)) continue;
|
|
4629
|
+
const target = next[j];
|
|
4630
|
+
const refIdx = j + 1 < next.length ? indexByPk(working, next[j + 1].pk) : working.length;
|
|
4631
|
+
const p = indexByPk(working, target.pk);
|
|
4632
|
+
if (p === -1) {
|
|
4633
|
+
commands.push({ type: "insert", index: refIdx, item: target });
|
|
4634
|
+
working.splice(refIdx, 0, target);
|
|
4635
|
+
} else {
|
|
4636
|
+
const to = p < refIdx ? refIdx - 1 : refIdx;
|
|
4637
|
+
if (p !== to) {
|
|
4638
|
+
commands.push({ type: "move", from: p, to });
|
|
4639
|
+
working.splice(p, 1);
|
|
4640
|
+
working.splice(to, 0, target);
|
|
4641
|
+
}
|
|
4642
|
+
}
|
|
4643
|
+
}
|
|
4644
|
+
return commands;
|
|
4645
|
+
}
|
|
4646
|
+
function indexByPk(items, pk) {
|
|
4647
|
+
for (let i = 0; i < items.length; i++) {
|
|
4648
|
+
if (items[i].pk === pk) return i;
|
|
4649
|
+
}
|
|
4650
|
+
return -1;
|
|
4651
|
+
}
|
|
4652
|
+
function longestIncreasingSubsequence(seq) {
|
|
4653
|
+
const n = seq.length;
|
|
4654
|
+
if (n === 0) return [];
|
|
4655
|
+
const predecessor = new Array(n).fill(-1);
|
|
4656
|
+
const tails = [];
|
|
4657
|
+
for (let i = 0; i < n; i++) {
|
|
4658
|
+
let lo = 0;
|
|
4659
|
+
let hi = tails.length;
|
|
4660
|
+
while (lo < hi) {
|
|
4661
|
+
const mid = lo + hi >> 1;
|
|
4662
|
+
if (seq[tails[mid]] < seq[i]) lo = mid + 1;
|
|
4663
|
+
else hi = mid;
|
|
4664
|
+
}
|
|
4665
|
+
if (lo > 0) predecessor[i] = tails[lo - 1];
|
|
4666
|
+
if (lo === tails.length) tails.push(i);
|
|
4667
|
+
else tails[lo] = i;
|
|
4668
|
+
}
|
|
4669
|
+
const result = [];
|
|
4670
|
+
let k = tails[tails.length - 1];
|
|
4671
|
+
while (k !== -1) {
|
|
4672
|
+
result.push(k);
|
|
4673
|
+
k = predecessor[k];
|
|
4674
|
+
}
|
|
4675
|
+
result.reverse();
|
|
4676
|
+
return result;
|
|
4677
|
+
}
|
|
4678
|
+
|
|
4679
|
+
// src/modules/wrapper/index/OIMOrderedListCommandStreamDiffDriven.ts
|
|
4680
|
+
var OIMOrderedListCommandStreamDiffDriven = class extends OIMOrderedListCommandBuffer {
|
|
4681
|
+
constructor(queue, index, opts) {
|
|
4682
|
+
super(queue);
|
|
4683
|
+
this.prevByKey = /* @__PURE__ */ new Map();
|
|
4684
|
+
this.indexUnsubscribeByKey = /* @__PURE__ */ new Map();
|
|
4685
|
+
this.index = index;
|
|
4686
|
+
this.resetThreshold = opts?.resetThreshold ?? 0;
|
|
4687
|
+
}
|
|
4688
|
+
getItemsByKey(key) {
|
|
4689
|
+
this.ensureWired(key);
|
|
4690
|
+
return this.currentSlots(key);
|
|
4691
|
+
}
|
|
4692
|
+
subscribeCommands(key, handler) {
|
|
4693
|
+
this.ensureWired(key);
|
|
4694
|
+
return super.subscribeCommands(key, handler);
|
|
4695
|
+
}
|
|
4696
|
+
destroy() {
|
|
4697
|
+
this.indexUnsubscribeByKey.forEach((unsubscribe) => unsubscribe());
|
|
4698
|
+
this.indexUnsubscribeByKey.clear();
|
|
4699
|
+
this.prevByKey.clear();
|
|
4700
|
+
super.destroy();
|
|
4701
|
+
}
|
|
4702
|
+
currentSlots(key) {
|
|
4703
|
+
return this.index.getSlotsByKey(key);
|
|
4704
|
+
}
|
|
4705
|
+
/** Snapshot the current order and subscribe to the index once per key. */
|
|
4706
|
+
ensureWired(key) {
|
|
4707
|
+
if (this.indexUnsubscribeByKey.has(key)) return;
|
|
4708
|
+
this.prevByKey.set(key, this.currentSlots(key).slice());
|
|
4709
|
+
const unsubscribe = this.index.subscribeOnKey(
|
|
4710
|
+
key,
|
|
4711
|
+
() => this.onIndexChange(key)
|
|
4712
|
+
);
|
|
4713
|
+
this.indexUnsubscribeByKey.set(key, unsubscribe);
|
|
4714
|
+
}
|
|
4715
|
+
onIndexChange(key) {
|
|
4716
|
+
const prev = this.prevByKey.get(key) ?? [];
|
|
4717
|
+
const next = this.currentSlots(key);
|
|
4718
|
+
this.emitDiff(key, prev, next);
|
|
4719
|
+
this.prevByKey.set(key, next.slice());
|
|
4720
|
+
}
|
|
4721
|
+
emitDiff(key, prev, next) {
|
|
4722
|
+
if (sameOrderByPk(prev, next)) return;
|
|
4723
|
+
const commons = countCommonPks(prev, next);
|
|
4724
|
+
const larger = Math.max(prev.length, next.length);
|
|
4725
|
+
const wholeChange = prev.length === 0 || next.length === 0 || commons === 0 || this.resetThreshold > 0 && commons / larger < this.resetThreshold;
|
|
4726
|
+
if (wholeChange) {
|
|
4727
|
+
this.appendResetCommand(key, next);
|
|
4728
|
+
return;
|
|
4729
|
+
}
|
|
4730
|
+
const commands = diffOrderedListByPk(prev, next);
|
|
4731
|
+
for (let i = 0; i < commands.length; i++) {
|
|
4732
|
+
this.appendCommand(key, commands[i]);
|
|
4733
|
+
}
|
|
4734
|
+
}
|
|
4735
|
+
};
|
|
4736
|
+
function sameOrderByPk(a, b) {
|
|
4737
|
+
if (a.length !== b.length) return false;
|
|
4738
|
+
for (let i = 0; i < a.length; i++) {
|
|
4739
|
+
if (a[i].pk !== b[i].pk) return false;
|
|
4740
|
+
}
|
|
4741
|
+
return true;
|
|
4742
|
+
}
|
|
4743
|
+
function countCommonPks(prev, next) {
|
|
4744
|
+
const prevPks = /* @__PURE__ */ new Set();
|
|
4745
|
+
for (let i = 0; i < prev.length; i++) prevPks.add(prev[i].pk);
|
|
4746
|
+
let common = 0;
|
|
4747
|
+
for (let i = 0; i < next.length; i++) {
|
|
4748
|
+
if (prevPks.has(next[i].pk)) common++;
|
|
4749
|
+
}
|
|
4750
|
+
return common;
|
|
4751
|
+
}
|
|
4752
|
+
|
|
4753
|
+
// src/modules/wrapper/index/createOIMOrderedListCommandStreamDiffDriven.ts
|
|
4754
|
+
function createOIMOrderedListCommandStreamDiffDriven(queue, index, opts) {
|
|
4755
|
+
return new OIMOrderedListCommandStreamDiffDriven(queue, index, opts);
|
|
4756
|
+
}
|
|
4757
|
+
|
|
3550
4758
|
// src/core/event-queue-scheduler/OIMEventQueueSchedulerAnimationFrame.ts
|
|
3551
4759
|
var OIMEventQueueSchedulerAnimationFrame = class extends OIMEventQueueScheduler {
|
|
3552
4760
|
constructor() {
|
|
@@ -3671,6 +4879,15 @@ var OIMEventQueueSchedulerImmediate = class extends OIMEventQueueScheduler {
|
|
|
3671
4879
|
}
|
|
3672
4880
|
};
|
|
3673
4881
|
|
|
4882
|
+
// src/core/event-queue-scheduler/OIMEventQueueSchedulerSync.ts
|
|
4883
|
+
var OIMEventQueueSchedulerSync = class extends OIMEventQueueScheduler {
|
|
4884
|
+
schedule() {
|
|
4885
|
+
this.flush();
|
|
4886
|
+
}
|
|
4887
|
+
cancel() {
|
|
4888
|
+
}
|
|
4889
|
+
};
|
|
4890
|
+
|
|
3674
4891
|
// src/core/event-queue-scheduler/OIMEventQueueSchedulerFactory.ts
|
|
3675
4892
|
var OIMEventQueueSchedulerFactory = class {
|
|
3676
4893
|
/**
|
|
@@ -3688,6 +4905,8 @@ var OIMEventQueueSchedulerFactory = class {
|
|
|
3688
4905
|
}
|
|
3689
4906
|
case "immediate":
|
|
3690
4907
|
return new OIMEventQueueSchedulerImmediate();
|
|
4908
|
+
case "sync":
|
|
4909
|
+
return new OIMEventQueueSchedulerSync();
|
|
3691
4910
|
default:
|
|
3692
4911
|
throw new Error(`Unknown scheduler type: ${type}`);
|
|
3693
4912
|
}
|
|
@@ -3711,11 +4930,18 @@ var OIMEventQueueSchedulerFactory = class {
|
|
|
3711
4930
|
return new OIMEventQueueSchedulerTimeout(delay);
|
|
3712
4931
|
}
|
|
3713
4932
|
/**
|
|
3714
|
-
* Create an immediate scheduler (
|
|
4933
|
+
* Create an immediate scheduler (setImmediate / MessageChannel / setTimeout(0)).
|
|
3715
4934
|
*/
|
|
3716
4935
|
static createImmediate() {
|
|
3717
4936
|
return new OIMEventQueueSchedulerImmediate();
|
|
3718
4937
|
}
|
|
4938
|
+
/**
|
|
4939
|
+
* Create a synchronous scheduler — flushes in the same call stack, no
|
|
4940
|
+
* batching. Debug/diagnostic use only (see {@link OIMEventQueueSchedulerSync}).
|
|
4941
|
+
*/
|
|
4942
|
+
static createSync() {
|
|
4943
|
+
return new OIMEventQueueSchedulerSync();
|
|
4944
|
+
}
|
|
3719
4945
|
};
|
|
3720
4946
|
|
|
3721
4947
|
// src/constants/OIMDBSettings.ts
|
|
@@ -4123,6 +5349,7 @@ export {
|
|
|
4123
5349
|
EOIMIndexEventType,
|
|
4124
5350
|
EOIMObjectEventType,
|
|
4125
5351
|
OIMCarrierKeyedEmitter,
|
|
5352
|
+
OIMCarrierSingleEmitter,
|
|
4126
5353
|
OIMCollection,
|
|
4127
5354
|
OIMCollectionByPkSelector,
|
|
4128
5355
|
OIMCollectionByPksSelector,
|
|
@@ -4137,6 +5364,8 @@ export {
|
|
|
4137
5364
|
OIMComputeRuntime,
|
|
4138
5365
|
OIMComputed,
|
|
4139
5366
|
OIMDBSettings,
|
|
5367
|
+
OIMDerivedCollectionGlobalIndexArrayBased,
|
|
5368
|
+
OIMDerivedCollectionGlobalIndexSetBased,
|
|
4140
5369
|
OIMDerivedCollectionIndexArrayBased,
|
|
4141
5370
|
OIMDerivedCollectionIndexSetBased,
|
|
4142
5371
|
OIMEffect,
|
|
@@ -4145,6 +5374,8 @@ export {
|
|
|
4145
5374
|
OIMEffectDependencyKeyedCollection,
|
|
4146
5375
|
OIMEffectDependencyKeyedIndex,
|
|
4147
5376
|
OIMEffectDependencyKeyedObject,
|
|
5377
|
+
OIMEntitiesByGlobalIndexArrayBasedSelector,
|
|
5378
|
+
OIMEntitiesByGlobalIndexSetBasedSelector,
|
|
4148
5379
|
OIMEntitiesByIndexKeyArrayBasedSelector,
|
|
4149
5380
|
OIMEntitiesByIndexKeySetBasedSelector,
|
|
4150
5381
|
OIMEntityUpdaterFactory,
|
|
@@ -4155,7 +5386,13 @@ export {
|
|
|
4155
5386
|
OIMEventQueueSchedulerFactory,
|
|
4156
5387
|
OIMEventQueueSchedulerImmediate,
|
|
4157
5388
|
OIMEventQueueSchedulerMicrotask,
|
|
5389
|
+
OIMEventQueueSchedulerSync,
|
|
4158
5390
|
OIMEventQueueSchedulerTimeout,
|
|
5391
|
+
OIMGlobalIndex,
|
|
5392
|
+
OIMGlobalIndexArrayBased,
|
|
5393
|
+
OIMGlobalIndexManualArrayBased,
|
|
5394
|
+
OIMGlobalIndexManualSetBased,
|
|
5395
|
+
OIMGlobalIndexSetBased,
|
|
4159
5396
|
OIMIndex,
|
|
4160
5397
|
OIMIndexArrayBased,
|
|
4161
5398
|
OIMIndexComparatorFactory,
|
|
@@ -4167,6 +5404,7 @@ export {
|
|
|
4167
5404
|
OIMIndexPksByKeysArrayBasedSelector,
|
|
4168
5405
|
OIMIndexPksByKeysSetBasedSelector,
|
|
4169
5406
|
OIMIndexSetBased,
|
|
5407
|
+
OIMIndexSlotMap,
|
|
4170
5408
|
OIMIndexStoreArrayBased,
|
|
4171
5409
|
OIMIndexStoreMapDrivenArrayBased,
|
|
4172
5410
|
OIMIndexStoreMapDrivenSetBased,
|
|
@@ -4178,11 +5416,21 @@ export {
|
|
|
4178
5416
|
OIMObjectStoreRecordDriven,
|
|
4179
5417
|
OIMObjectValueByKeySelector,
|
|
4180
5418
|
OIMObjectValuesByKeysSelector,
|
|
5419
|
+
OIMOrderedListCommandBuffer,
|
|
4181
5420
|
OIMOrderedListCommandStream,
|
|
5421
|
+
OIMOrderedListCommandStreamDiffDriven,
|
|
5422
|
+
OIMOrderedListMappedCommandStream,
|
|
4182
5423
|
OIMPkSelectorFactory,
|
|
4183
5424
|
OIMReactiveCollection,
|
|
5425
|
+
OIMReactiveCollectionGlobalIndexManualArrayBased,
|
|
5426
|
+
OIMReactiveCollectionGlobalIndexManualSetBased,
|
|
4184
5427
|
OIMReactiveCollectionIndexManualArrayBased,
|
|
4185
5428
|
OIMReactiveCollectionIndexManualSetBased,
|
|
5429
|
+
OIMReactiveGlobalIndex,
|
|
5430
|
+
OIMReactiveGlobalIndexArrayBased,
|
|
5431
|
+
OIMReactiveGlobalIndexManualArrayBased,
|
|
5432
|
+
OIMReactiveGlobalIndexManualSetBased,
|
|
5433
|
+
OIMReactiveGlobalIndexSetBased,
|
|
4186
5434
|
OIMReactiveIndex,
|
|
4187
5435
|
OIMReactiveIndexArrayBased,
|
|
4188
5436
|
OIMReactiveIndexManualArrayBased,
|
|
@@ -4193,5 +5441,9 @@ export {
|
|
|
4193
5441
|
createInPlaceEntityUpdater,
|
|
4194
5442
|
createMergeEntityUpdater,
|
|
4195
5443
|
createOIMCollectionIndexFactory,
|
|
4196
|
-
createOIMCollectionKit
|
|
5444
|
+
createOIMCollectionKit,
|
|
5445
|
+
createOIMIndexSlotMap,
|
|
5446
|
+
createOIMOrderedListCommandStreamDiffDriven,
|
|
5447
|
+
createOIMOrderedListMappedCommandStream,
|
|
5448
|
+
diffOrderedListByPk
|
|
4197
5449
|
};
|