@oimdb/core 3.2.0 → 3.4.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 +58 -16
- package/dist/index.cjs +154 -101
- package/dist/index.d.cts +90 -40
- package/dist/index.d.ts +90 -40
- package/dist/index.js +153 -101
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -545,7 +545,7 @@ var OIMCarrierKeyedEmitter = class {
|
|
|
545
545
|
}
|
|
546
546
|
destroy() {
|
|
547
547
|
if (this.isFlushEnqueued) {
|
|
548
|
-
this.queue.
|
|
548
|
+
this.queue.cancel(this.onFlush);
|
|
549
549
|
this.isFlushEnqueued = false;
|
|
550
550
|
}
|
|
551
551
|
this.subscribedCarriers.forEach((carrier) => {
|
|
@@ -569,7 +569,7 @@ var OIMCarrierKeyedEmitter = class {
|
|
|
569
569
|
scheduleFlush() {
|
|
570
570
|
if (this.isFlushEnqueued) return;
|
|
571
571
|
this.isFlushEnqueued = true;
|
|
572
|
-
this.queue.
|
|
572
|
+
this.queue.enqueue(this.onFlush);
|
|
573
573
|
}
|
|
574
574
|
notify(carrier) {
|
|
575
575
|
const subscribers = carrier.subscribers;
|
|
@@ -865,12 +865,15 @@ var OIMCollectionStoreMapDriven = class extends OIMCollectionStore {
|
|
|
865
865
|
}
|
|
866
866
|
};
|
|
867
867
|
|
|
868
|
+
// src/core/createMergeEntityUpdater.ts
|
|
869
|
+
function createMergeEntityUpdater() {
|
|
870
|
+
return (draft, prev) => ({ ...prev, ...draft });
|
|
871
|
+
}
|
|
872
|
+
|
|
868
873
|
// src/core/OIMEntityUpdaterFactory.ts
|
|
869
874
|
var OIMEntityUpdaterFactory = class {
|
|
870
875
|
createMergeEntityUpdater() {
|
|
871
|
-
return (
|
|
872
|
-
return { ...prev, ...draft };
|
|
873
|
-
};
|
|
876
|
+
return createMergeEntityUpdater();
|
|
874
877
|
}
|
|
875
878
|
};
|
|
876
879
|
|
|
@@ -1134,12 +1137,12 @@ var OIMReactiveCollection = class extends OIMCollection {
|
|
|
1134
1137
|
ensureAnyUpdateEnqueued() {
|
|
1135
1138
|
if (this.isAnyUpdateScheduled) return;
|
|
1136
1139
|
this.isAnyUpdateScheduled = true;
|
|
1137
|
-
this.queue.
|
|
1140
|
+
this.queue.enqueue(this.runAnyUpdate);
|
|
1138
1141
|
}
|
|
1139
1142
|
destroy() {
|
|
1140
1143
|
this.updateEmitter.destroy();
|
|
1141
1144
|
if (this.isAnyUpdateScheduled) {
|
|
1142
|
-
this.queue.
|
|
1145
|
+
this.queue.cancel(this.runAnyUpdate);
|
|
1143
1146
|
this.isAnyUpdateScheduled = false;
|
|
1144
1147
|
}
|
|
1145
1148
|
this.anyUpdateHandlers.clear();
|
|
@@ -1189,6 +1192,22 @@ var OIMIndexManualOrderedArrayBased = class extends OIMIndexArrayBased {
|
|
|
1189
1192
|
this.emitUpdate([key]);
|
|
1190
1193
|
return removed;
|
|
1191
1194
|
}
|
|
1195
|
+
/**
|
|
1196
|
+
* Remove up to `count` consecutive slots starting at `index`.
|
|
1197
|
+
* Returns the number actually removed (clamped to bounds; 0 if nothing).
|
|
1198
|
+
*/
|
|
1199
|
+
removeRange(key, index, count) {
|
|
1200
|
+
const list = this.store.getOneByKey(key);
|
|
1201
|
+
if (!list) return 0;
|
|
1202
|
+
if (index < 0 || index >= list.length || count <= 0) return 0;
|
|
1203
|
+
const actual = Math.min(count, list.length - index);
|
|
1204
|
+
list.splice(index, actual);
|
|
1205
|
+
if (list.length === 0) {
|
|
1206
|
+
this.store.removeOneByKey(key);
|
|
1207
|
+
}
|
|
1208
|
+
this.emitUpdate([key]);
|
|
1209
|
+
return actual;
|
|
1210
|
+
}
|
|
1192
1211
|
move(key, fromIndex, toIndex) {
|
|
1193
1212
|
const list = this.store.getOneByKey(key);
|
|
1194
1213
|
if (!list) return void 0;
|
|
@@ -1201,6 +1220,32 @@ var OIMIndexManualOrderedArrayBased = class extends OIMIndexArrayBased {
|
|
|
1201
1220
|
this.emitUpdate([key]);
|
|
1202
1221
|
return slot;
|
|
1203
1222
|
}
|
|
1223
|
+
/** Replace the slot at `index` in place. Returns the safe index, or -1. */
|
|
1224
|
+
setSlotAt(key, index, slot) {
|
|
1225
|
+
const list = this.store.getOneByKey(key);
|
|
1226
|
+
if (!list) return -1;
|
|
1227
|
+
if (index < 0 || index >= list.length) return -1;
|
|
1228
|
+
list[index] = slot;
|
|
1229
|
+
this.emitUpdate([key]);
|
|
1230
|
+
return index;
|
|
1231
|
+
}
|
|
1232
|
+
/**
|
|
1233
|
+
* Move up to `count` consecutive slots from `from` to `to`. `to` is in the
|
|
1234
|
+
* coordinate space *after* the block is extracted (same as single `move`).
|
|
1235
|
+
* Returns the number actually moved (0 if a no-op / out of bounds).
|
|
1236
|
+
*/
|
|
1237
|
+
moveRange(key, from, to, count) {
|
|
1238
|
+
const list = this.store.getOneByKey(key);
|
|
1239
|
+
if (!list) return 0;
|
|
1240
|
+
if (from < 0 || from >= list.length || count <= 0) return 0;
|
|
1241
|
+
const actual = Math.min(count, list.length - from);
|
|
1242
|
+
const insertAt = Math.max(0, Math.min(to, list.length - actual));
|
|
1243
|
+
if (insertAt === from) return 0;
|
|
1244
|
+
const block = list.splice(from, actual);
|
|
1245
|
+
list.splice(insertAt, 0, ...block);
|
|
1246
|
+
this.emitUpdate([key]);
|
|
1247
|
+
return actual;
|
|
1248
|
+
}
|
|
1204
1249
|
resetSlots(key, slots) {
|
|
1205
1250
|
if (slots.length === 0) {
|
|
1206
1251
|
if (this.store.getOneByKey(key) !== void 0) {
|
|
@@ -1334,7 +1379,7 @@ var OIMUpdateEventEmitter = class {
|
|
|
1334
1379
|
}
|
|
1335
1380
|
if (this.isFlushEnqueued) return;
|
|
1336
1381
|
this.isFlushEnqueued = true;
|
|
1337
|
-
this.queue.
|
|
1382
|
+
this.queue.enqueue(this.onFlush);
|
|
1338
1383
|
}
|
|
1339
1384
|
markUpdatedKey(key) {
|
|
1340
1385
|
if (this.deliveryMode === "queue" && this.queue.isInFlush) {
|
|
@@ -1356,7 +1401,7 @@ var OIMUpdateEventEmitter = class {
|
|
|
1356
1401
|
}
|
|
1357
1402
|
if (this.isFlushEnqueued) return;
|
|
1358
1403
|
this.isFlushEnqueued = true;
|
|
1359
|
-
this.queue.
|
|
1404
|
+
this.queue.enqueue(this.onFlush);
|
|
1360
1405
|
}
|
|
1361
1406
|
markAllUpdated() {
|
|
1362
1407
|
if (this.deliveryMode === "queue" && this.queue.isInFlush) {
|
|
@@ -1378,7 +1423,7 @@ var OIMUpdateEventEmitter = class {
|
|
|
1378
1423
|
}
|
|
1379
1424
|
if (this.isFlushEnqueued) return;
|
|
1380
1425
|
this.isFlushEnqueued = true;
|
|
1381
|
-
this.queue.
|
|
1426
|
+
this.queue.enqueue(this.onFlush);
|
|
1382
1427
|
}
|
|
1383
1428
|
deliverImmediate() {
|
|
1384
1429
|
this.runSinglePass();
|
|
@@ -1411,15 +1456,15 @@ var OIMUpdateEventEmitter = class {
|
|
|
1411
1456
|
const flushingKeys = this.updatedKeys;
|
|
1412
1457
|
this.updatedKeys = /* @__PURE__ */ new Set();
|
|
1413
1458
|
if (this.keyHandlers.size === 0 || flushingKeys.size === 0) return;
|
|
1414
|
-
if (flushingKeys.size
|
|
1415
|
-
|
|
1416
|
-
|
|
1459
|
+
if (flushingKeys.size === this.keyHandlers.size) {
|
|
1460
|
+
this.keyHandlers.forEach((handlers, key) => {
|
|
1461
|
+
if (!flushingKeys.has(key)) return;
|
|
1417
1462
|
if (!handlers || handlers.size === 0) return;
|
|
1418
1463
|
this.notifyHandlers(handlers);
|
|
1419
1464
|
});
|
|
1420
1465
|
} else {
|
|
1421
|
-
|
|
1422
|
-
|
|
1466
|
+
flushingKeys.forEach((key) => {
|
|
1467
|
+
const handlers = this.keyHandlers.get(key);
|
|
1423
1468
|
if (!handlers || handlers.size === 0) return;
|
|
1424
1469
|
this.notifyHandlers(handlers);
|
|
1425
1470
|
});
|
|
@@ -1427,7 +1472,7 @@ var OIMUpdateEventEmitter = class {
|
|
|
1427
1472
|
}
|
|
1428
1473
|
destroy() {
|
|
1429
1474
|
if (this.isFlushEnqueued) {
|
|
1430
|
-
this.queue.
|
|
1475
|
+
this.queue.cancel(this.onFlush);
|
|
1431
1476
|
this.isFlushEnqueued = false;
|
|
1432
1477
|
}
|
|
1433
1478
|
if (this.unsubscribeAfterFlushDelivery) {
|
|
@@ -1487,7 +1532,7 @@ var OIMUpdateEventEmitter = class {
|
|
|
1487
1532
|
if (this.keyHandlers.size === 0) {
|
|
1488
1533
|
this.updatedKeys.clear();
|
|
1489
1534
|
if (this.isFlushEnqueued) {
|
|
1490
|
-
this.queue.
|
|
1535
|
+
this.queue.cancel(this.onFlush);
|
|
1491
1536
|
}
|
|
1492
1537
|
this.isFlushEnqueued = false;
|
|
1493
1538
|
}
|
|
@@ -1531,7 +1576,7 @@ var OIMOrderedListCommandStream = class {
|
|
|
1531
1576
|
if (payload.keys.length === 0) return;
|
|
1532
1577
|
for (let i = 0; i < payload.keys.length; i++) {
|
|
1533
1578
|
const key = payload.keys[i];
|
|
1534
|
-
this.
|
|
1579
|
+
this.appendResetCommand(key, this.getSlotsByKey(key));
|
|
1535
1580
|
}
|
|
1536
1581
|
};
|
|
1537
1582
|
this.commandsEventEmitter = new OIMUpdateEventEmitter(
|
|
@@ -1568,12 +1613,7 @@ var OIMOrderedListCommandStream = class {
|
|
|
1568
1613
|
pushSlot(key, slot) {
|
|
1569
1614
|
this.withWrite(() => {
|
|
1570
1615
|
const index = this.index.pushSlot(key, slot);
|
|
1571
|
-
this.appendCommand(key, {
|
|
1572
|
-
type: "insert",
|
|
1573
|
-
pk: slot.pk,
|
|
1574
|
-
slot,
|
|
1575
|
-
index
|
|
1576
|
-
});
|
|
1616
|
+
this.appendCommand(key, { type: "insert", index, item: slot });
|
|
1577
1617
|
});
|
|
1578
1618
|
}
|
|
1579
1619
|
insertSlotAt(key, index, slot) {
|
|
@@ -1581,9 +1621,20 @@ var OIMOrderedListCommandStream = class {
|
|
|
1581
1621
|
const safeIndex = this.index.insertSlotAt(key, index, slot);
|
|
1582
1622
|
this.appendCommand(key, {
|
|
1583
1623
|
type: "insert",
|
|
1584
|
-
|
|
1585
|
-
slot
|
|
1586
|
-
|
|
1624
|
+
index: safeIndex,
|
|
1625
|
+
item: slot
|
|
1626
|
+
});
|
|
1627
|
+
});
|
|
1628
|
+
}
|
|
1629
|
+
/** Replace the slot at `index` in place. */
|
|
1630
|
+
setSlotAt(key, index, slot) {
|
|
1631
|
+
this.withWrite(() => {
|
|
1632
|
+
const safeIndex = this.index.setSlotAt(key, index, slot);
|
|
1633
|
+
if (safeIndex < 0) return;
|
|
1634
|
+
this.appendCommand(key, {
|
|
1635
|
+
type: "set",
|
|
1636
|
+
index: safeIndex,
|
|
1637
|
+
item: slot
|
|
1587
1638
|
});
|
|
1588
1639
|
});
|
|
1589
1640
|
}
|
|
@@ -1591,12 +1642,15 @@ var OIMOrderedListCommandStream = class {
|
|
|
1591
1642
|
this.withWrite(() => {
|
|
1592
1643
|
const slot = this.index.removeAt(key, index);
|
|
1593
1644
|
if (slot === void 0) return;
|
|
1594
|
-
this.appendCommand(key, {
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1645
|
+
this.appendCommand(key, { type: "remove", index });
|
|
1646
|
+
});
|
|
1647
|
+
}
|
|
1648
|
+
/** Remove `count` consecutive elements from `index`; emits `remove` with `count`. */
|
|
1649
|
+
removeRange(key, index, count) {
|
|
1650
|
+
this.withWrite(() => {
|
|
1651
|
+
const removed = this.index.removeRange(key, index, count);
|
|
1652
|
+
if (removed <= 0) return;
|
|
1653
|
+
this.appendCommand(key, { type: "remove", index, count: removed });
|
|
1600
1654
|
});
|
|
1601
1655
|
}
|
|
1602
1656
|
move(key, fromIndex, toIndex) {
|
|
@@ -1605,17 +1659,26 @@ var OIMOrderedListCommandStream = class {
|
|
|
1605
1659
|
if (slot === void 0) return;
|
|
1606
1660
|
this.appendCommand(key, {
|
|
1607
1661
|
type: "move",
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
fromIndex,
|
|
1611
|
-
toIndex
|
|
1662
|
+
from: fromIndex,
|
|
1663
|
+
to: toIndex
|
|
1612
1664
|
});
|
|
1613
1665
|
});
|
|
1614
1666
|
}
|
|
1667
|
+
/**
|
|
1668
|
+
* Move `count` consecutive elements from `from` to `to`; emits `move` with
|
|
1669
|
+
* `count`. `to` is in the post-extraction coordinate space (as single `move`).
|
|
1670
|
+
*/
|
|
1671
|
+
moveRange(key, from, to, count) {
|
|
1672
|
+
this.withWrite(() => {
|
|
1673
|
+
const moved = this.index.moveRange(key, from, to, count);
|
|
1674
|
+
if (moved <= 0) return;
|
|
1675
|
+
this.appendCommand(key, { type: "move", from, to, count: moved });
|
|
1676
|
+
});
|
|
1677
|
+
}
|
|
1615
1678
|
setSlots(key, slots) {
|
|
1616
1679
|
this.withWrite(() => {
|
|
1617
1680
|
this.index.resetSlots(key, slots);
|
|
1618
|
-
this.
|
|
1681
|
+
this.appendResetCommand(key, slots);
|
|
1619
1682
|
});
|
|
1620
1683
|
}
|
|
1621
1684
|
getBufferedCommands(key) {
|
|
@@ -1659,26 +1722,21 @@ var OIMOrderedListCommandStream = class {
|
|
|
1659
1722
|
cmds = [];
|
|
1660
1723
|
this.commandsByKey.set(key, cmds);
|
|
1661
1724
|
}
|
|
1662
|
-
if (cmd.type === "
|
|
1725
|
+
if (cmd.type === "reset") {
|
|
1663
1726
|
cmds.length = 0;
|
|
1664
1727
|
cmds.push(cmd);
|
|
1665
|
-
} else if (cmds.length > 0 && cmds[0].type === "
|
|
1666
|
-
|
|
1667
|
-
cmds[0] = this.createSetCommand(slots);
|
|
1728
|
+
} else if (cmds.length > 0 && cmds[0].type === "reset") {
|
|
1729
|
+
cmds[0] = this.createResetCommand(this.getSlotsByKey(key));
|
|
1668
1730
|
} else {
|
|
1669
1731
|
cmds.push(cmd);
|
|
1670
1732
|
}
|
|
1671
1733
|
this.commandsEventEmitter.markUpdatedKeys([key]);
|
|
1672
1734
|
}
|
|
1673
|
-
|
|
1674
|
-
this.appendCommand(key, this.
|
|
1735
|
+
appendResetCommand(key, slots) {
|
|
1736
|
+
this.appendCommand(key, this.createResetCommand(slots));
|
|
1675
1737
|
}
|
|
1676
|
-
|
|
1677
|
-
return {
|
|
1678
|
-
type: "set",
|
|
1679
|
-
pks: slots.map((slot) => slot.pk),
|
|
1680
|
-
slots
|
|
1681
|
-
};
|
|
1738
|
+
createResetCommand(slots) {
|
|
1739
|
+
return { type: "reset", items: slots };
|
|
1682
1740
|
}
|
|
1683
1741
|
};
|
|
1684
1742
|
|
|
@@ -1695,12 +1753,7 @@ var OIMCollectionOrderedListCommandStream = class extends OIMOrderedListCommandS
|
|
|
1695
1753
|
this.withWrite(() => {
|
|
1696
1754
|
const slot = this.resolvePk(pk);
|
|
1697
1755
|
const index = this.index.pushSlot(key, slot);
|
|
1698
|
-
this.appendCommand(key, {
|
|
1699
|
-
type: "insert",
|
|
1700
|
-
pk,
|
|
1701
|
-
slot,
|
|
1702
|
-
index
|
|
1703
|
-
});
|
|
1756
|
+
this.appendCommand(key, { type: "insert", index, item: slot });
|
|
1704
1757
|
});
|
|
1705
1758
|
}
|
|
1706
1759
|
insertAt(key, index, pk) {
|
|
@@ -1709,9 +1762,21 @@ var OIMCollectionOrderedListCommandStream = class extends OIMOrderedListCommandS
|
|
|
1709
1762
|
const safeIndex = this.index.insertSlotAt(key, index, slot);
|
|
1710
1763
|
this.appendCommand(key, {
|
|
1711
1764
|
type: "insert",
|
|
1712
|
-
|
|
1713
|
-
slot
|
|
1714
|
-
|
|
1765
|
+
index: safeIndex,
|
|
1766
|
+
item: slot
|
|
1767
|
+
});
|
|
1768
|
+
});
|
|
1769
|
+
}
|
|
1770
|
+
/** Replace the element at `index` with the slot for `pk`, in place. */
|
|
1771
|
+
setAt(key, index, pk) {
|
|
1772
|
+
this.withWrite(() => {
|
|
1773
|
+
const slot = this.resolvePk(pk);
|
|
1774
|
+
const safeIndex = this.index.setSlotAt(key, index, slot);
|
|
1775
|
+
if (safeIndex < 0) return;
|
|
1776
|
+
this.appendCommand(key, {
|
|
1777
|
+
type: "set",
|
|
1778
|
+
index: safeIndex,
|
|
1779
|
+
item: slot
|
|
1715
1780
|
});
|
|
1716
1781
|
});
|
|
1717
1782
|
}
|
|
@@ -1719,7 +1784,7 @@ var OIMCollectionOrderedListCommandStream = class extends OIMOrderedListCommandS
|
|
|
1719
1784
|
this.withWrite(() => {
|
|
1720
1785
|
const slots = pks.map((pk) => this.resolvePk(pk));
|
|
1721
1786
|
this.index.resetSlots(key, slots);
|
|
1722
|
-
this.
|
|
1787
|
+
this.appendResetCommand(key, slots);
|
|
1723
1788
|
});
|
|
1724
1789
|
}
|
|
1725
1790
|
getSlotsByKey(key) {
|
|
@@ -2635,48 +2700,23 @@ var OIMEventQueue = class {
|
|
|
2635
2700
|
}
|
|
2636
2701
|
}
|
|
2637
2702
|
/**
|
|
2638
|
-
* Enqueue a one-shot task to
|
|
2639
|
-
*
|
|
2703
|
+
* Enqueue a one-shot task to run on the next flush. The function is stored
|
|
2704
|
+
* directly (no wrapper, no returned closure) and cancelled via {@link cancel}
|
|
2705
|
+
* by passing the same reference. Enqueuing the same reference twice is
|
|
2706
|
+
* idempotent — it is Set-deduped and runs once per flush.
|
|
2640
2707
|
*/
|
|
2641
2708
|
enqueue(fn) {
|
|
2642
|
-
let isActive = true;
|
|
2643
|
-
const task = () => {
|
|
2644
|
-
if (!isActive) return;
|
|
2645
|
-
fn();
|
|
2646
|
-
};
|
|
2647
|
-
this.tasks.add(task);
|
|
2648
|
-
this.ensureScheduled();
|
|
2649
|
-
return () => {
|
|
2650
|
-
if (!isActive) return;
|
|
2651
|
-
isActive = false;
|
|
2652
|
-
this.tasks.delete(task);
|
|
2653
|
-
};
|
|
2654
|
-
}
|
|
2655
|
-
/**
|
|
2656
|
-
* Allocation-free enqueue for a **stable** function reference (e.g. a bound
|
|
2657
|
-
* `onFlush` method). The function is stored directly — no wrapper, no
|
|
2658
|
-
* returned closure — and cancelled via {@link cancelTask}. Enqueuing the
|
|
2659
|
-
* same reference twice is idempotent (Set-deduped); callers that may run a
|
|
2660
|
-
* task more than once per flush should use {@link enqueue} instead.
|
|
2661
|
-
*/
|
|
2662
|
-
enqueueTask(fn) {
|
|
2663
2709
|
this.tasks.add(fn);
|
|
2664
2710
|
this.ensureScheduled();
|
|
2665
2711
|
}
|
|
2666
|
-
/** Cancel a task
|
|
2667
|
-
|
|
2712
|
+
/** Cancel a previously enqueued task by its reference; safe to call mid-flush. */
|
|
2713
|
+
cancel(fn) {
|
|
2668
2714
|
this.tasks.delete(fn);
|
|
2669
2715
|
this.flushing?.delete(fn);
|
|
2670
2716
|
}
|
|
2671
2717
|
get isInFlush() {
|
|
2672
2718
|
return this.isFlushing;
|
|
2673
2719
|
}
|
|
2674
|
-
/**
|
|
2675
|
-
* Dequeue (cancel) a previously enqueued task by its dequeue function.
|
|
2676
|
-
*/
|
|
2677
|
-
dequeue(dequeueFn) {
|
|
2678
|
-
dequeueFn();
|
|
2679
|
-
}
|
|
2680
2720
|
/**
|
|
2681
2721
|
* Execute all pending tasks.
|
|
2682
2722
|
*
|
|
@@ -3323,20 +3363,27 @@ var OIMCollectionChangedFields = class {
|
|
|
3323
3363
|
constructor(queue, collection, opts) {
|
|
3324
3364
|
this.isInWrite = false;
|
|
3325
3365
|
this.lastEntitySnapshotByPk = /* @__PURE__ */ new Map();
|
|
3366
|
+
// PKs written through this wrapper during the current flush. Their fields are
|
|
3367
|
+
// already tracked accurately via trackPatch, so the flush-time external-write
|
|
3368
|
+
// handler skips them — no redundant diff + snapshot re-clone. Cleared per flush.
|
|
3369
|
+
this.writtenThroughThisFlush = /* @__PURE__ */ new Set();
|
|
3326
3370
|
this.changedFieldsByPk = /* @__PURE__ */ new Map();
|
|
3327
3371
|
this.changedPksByField = /* @__PURE__ */ new Map();
|
|
3328
3372
|
this.onAfterFlush = () => {
|
|
3329
3373
|
this.clear();
|
|
3374
|
+
this.writtenThroughThisFlush.clear();
|
|
3330
3375
|
};
|
|
3331
3376
|
this.onCollectionUpdate = (payload) => {
|
|
3332
3377
|
if (this.isInWrite) return;
|
|
3333
3378
|
if (payload.pks.length === 0) return;
|
|
3334
3379
|
for (let i = 0; i < payload.pks.length; i++) {
|
|
3335
3380
|
const pk = payload.pks[i];
|
|
3381
|
+
if (this.writtenThroughThisFlush.has(pk)) continue;
|
|
3336
3382
|
this.trackExternalMutationByPk(pk);
|
|
3337
3383
|
}
|
|
3338
3384
|
};
|
|
3339
3385
|
this.collection = collection;
|
|
3386
|
+
this.detectExternalMutations = opts?.detectExternalMutations !== false;
|
|
3340
3387
|
this.selectPk = opts?.selectPk ?? (() => {
|
|
3341
3388
|
throw new Error(
|
|
3342
3389
|
`[OIMCollectionChangedFields]: selectPk was not provided. Use upsertOneByPk(...) or pass opts.selectPk.`
|
|
@@ -3351,15 +3398,17 @@ var OIMCollectionChangedFields = class {
|
|
|
3351
3398
|
0 /* AFTER_FLUSH */,
|
|
3352
3399
|
this.onAfterFlush
|
|
3353
3400
|
);
|
|
3354
|
-
|
|
3355
|
-
|
|
3356
|
-
this.
|
|
3357
|
-
|
|
3358
|
-
|
|
3359
|
-
|
|
3360
|
-
|
|
3361
|
-
|
|
3362
|
-
|
|
3401
|
+
if (this.detectExternalMutations) {
|
|
3402
|
+
const maybeReactive = collection;
|
|
3403
|
+
this.unsubscribeFromCollectionEmitter = maybeReactive.subscribeOnAnyUpdate ? maybeReactive.subscribeOnAnyUpdate((pks) => {
|
|
3404
|
+
this.onCollectionUpdate({
|
|
3405
|
+
pks
|
|
3406
|
+
});
|
|
3407
|
+
}) : collection.emitter.on(
|
|
3408
|
+
0 /* UPDATE */,
|
|
3409
|
+
this.onCollectionUpdate
|
|
3410
|
+
);
|
|
3411
|
+
}
|
|
3363
3412
|
}
|
|
3364
3413
|
upsertOneByPk(pk, patch) {
|
|
3365
3414
|
const slot = this.withWrite(() => {
|
|
@@ -3415,7 +3464,7 @@ var OIMCollectionChangedFields = class {
|
|
|
3415
3464
|
this.changedPksEventEmitter.destroy();
|
|
3416
3465
|
this.changedFieldsEventEmitter.destroy();
|
|
3417
3466
|
this.unsubscribeAfterFlush();
|
|
3418
|
-
this.unsubscribeFromCollectionEmitter();
|
|
3467
|
+
this.unsubscribeFromCollectionEmitter?.();
|
|
3419
3468
|
this.clear();
|
|
3420
3469
|
}
|
|
3421
3470
|
withWrite(fn) {
|
|
@@ -3457,6 +3506,8 @@ var OIMCollectionChangedFields = class {
|
|
|
3457
3506
|
return changed;
|
|
3458
3507
|
}
|
|
3459
3508
|
updateEntitySnapshot(pk) {
|
|
3509
|
+
if (!this.detectExternalMutations) return;
|
|
3510
|
+
this.writtenThroughThisFlush.add(pk);
|
|
3460
3511
|
const entity = this.collection.getOneByPk(pk);
|
|
3461
3512
|
if (!entity) {
|
|
3462
3513
|
this.lastEntitySnapshotByPk.delete(pk);
|
|
@@ -4140,6 +4191,7 @@ export {
|
|
|
4140
4191
|
OIMReactiveObject,
|
|
4141
4192
|
OIMSelector,
|
|
4142
4193
|
createInPlaceEntityUpdater,
|
|
4194
|
+
createMergeEntityUpdater,
|
|
4143
4195
|
createOIMCollectionIndexFactory,
|
|
4144
4196
|
createOIMCollectionKit
|
|
4145
4197
|
};
|