@liveblocks/core 3.20.0-exp5 → 3.20.0-exp7
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/dist/index.cjs +40 -17
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +9 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +40 -17
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -990,6 +990,15 @@ interface ReadonlyUnacknowledgedOps {
|
|
|
990
990
|
* the given ones (i.e. targeting one exact position).
|
|
991
991
|
*/
|
|
992
992
|
getByParentIdAndKey(parentId: string, parentKey: string): Iterable<ClientWireCreateOp>;
|
|
993
|
+
/**
|
|
994
|
+
* Whether the given pending op may already have been processed by the
|
|
995
|
+
* server. True for ops that were in flight when a connection died: the
|
|
996
|
+
* server may have stored them with the ack getting lost in the disconnect,
|
|
997
|
+
* or may never have received them. Until the (re-sent) op's ack arrives,
|
|
998
|
+
* the client cannot know which, so optimistic predictions that assume the
|
|
999
|
+
* op has not been processed yet are unsound for these ops.
|
|
1000
|
+
*/
|
|
1001
|
+
isPossiblyStored(opId: string): boolean;
|
|
993
1002
|
}
|
|
994
1003
|
|
|
995
1004
|
/**
|
package/dist/index.d.ts
CHANGED
|
@@ -990,6 +990,15 @@ interface ReadonlyUnacknowledgedOps {
|
|
|
990
990
|
* the given ones (i.e. targeting one exact position).
|
|
991
991
|
*/
|
|
992
992
|
getByParentIdAndKey(parentId: string, parentKey: string): Iterable<ClientWireCreateOp>;
|
|
993
|
+
/**
|
|
994
|
+
* Whether the given pending op may already have been processed by the
|
|
995
|
+
* server. True for ops that were in flight when a connection died: the
|
|
996
|
+
* server may have stored them with the ack getting lost in the disconnect,
|
|
997
|
+
* or may never have received them. Until the (re-sent) op's ack arrives,
|
|
998
|
+
* the client cannot know which, so optimistic predictions that assume the
|
|
999
|
+
* op has not been processed yet are unsound for these ops.
|
|
1000
|
+
*/
|
|
1001
|
+
isPossiblyStored(opId: string): boolean;
|
|
993
1002
|
}
|
|
994
1003
|
|
|
995
1004
|
/**
|
package/dist/index.js
CHANGED
|
@@ -6,7 +6,7 @@ var __export = (target, all) => {
|
|
|
6
6
|
|
|
7
7
|
// src/version.ts
|
|
8
8
|
var PKG_NAME = "@liveblocks/core";
|
|
9
|
-
var PKG_VERSION = "3.20.0-
|
|
9
|
+
var PKG_VERSION = "3.20.0-exp7";
|
|
10
10
|
var PKG_FORMAT = "esm";
|
|
11
11
|
|
|
12
12
|
// src/dupe-detection.ts
|
|
@@ -5804,6 +5804,9 @@ var UnacknowledgedOps = class {
|
|
|
5804
5804
|
#createOpsByPosition = /* @__PURE__ */ new Map();
|
|
5805
5805
|
// parentId -> (opId -> Create op)
|
|
5806
5806
|
#createOpsByParent = /* @__PURE__ */ new Map();
|
|
5807
|
+
// opIds of pending ops that were in flight when a connection died, so the
|
|
5808
|
+
// server may already have processed them. See isPossiblyStored().
|
|
5809
|
+
#possiblyStoredOpIds = /* @__PURE__ */ new Set();
|
|
5807
5810
|
#posKey(parentId, parentKey) {
|
|
5808
5811
|
return `${parentId}
|
|
5809
5812
|
${parentKey}`;
|
|
@@ -5843,6 +5846,7 @@ ${parentKey}`;
|
|
|
5843
5846
|
return;
|
|
5844
5847
|
}
|
|
5845
5848
|
this.#byOpId.delete(opId);
|
|
5849
|
+
this.#possiblyStoredOpIds.delete(opId);
|
|
5846
5850
|
if (isCreateOp(op)) {
|
|
5847
5851
|
const posKey = this.#posKey(op.parentId, op.parentKey);
|
|
5848
5852
|
const atPosition = this.#createOpsByPosition.get(posKey);
|
|
@@ -5876,6 +5880,19 @@ ${parentKey}`;
|
|
|
5876
5880
|
values() {
|
|
5877
5881
|
return this.#byOpId.values();
|
|
5878
5882
|
}
|
|
5883
|
+
isPossiblyStored(opId) {
|
|
5884
|
+
return this.#possiblyStoredOpIds.has(opId);
|
|
5885
|
+
}
|
|
5886
|
+
/**
|
|
5887
|
+
* Mark every currently pending op as possibly stored on the server. Called
|
|
5888
|
+
* when the connection dies: all of these ops were in flight, and their
|
|
5889
|
+
* (possibly lost) acks would have been the only way to know their fate.
|
|
5890
|
+
*/
|
|
5891
|
+
markAllAsPossiblyStored() {
|
|
5892
|
+
for (const opId of this.#byOpId.keys()) {
|
|
5893
|
+
this.#possiblyStoredOpIds.add(opId);
|
|
5894
|
+
}
|
|
5895
|
+
}
|
|
5879
5896
|
};
|
|
5880
5897
|
|
|
5881
5898
|
// src/crdts/AbstractCrdt.ts
|
|
@@ -6472,7 +6489,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
6472
6489
|
}
|
|
6473
6490
|
return result.modified.updates[0];
|
|
6474
6491
|
}
|
|
6475
|
-
#applyRemoteInsert(op
|
|
6492
|
+
#applyRemoteInsert(op) {
|
|
6476
6493
|
if (this._pool === void 0) {
|
|
6477
6494
|
throw new Error("Can't attach child if managed pool is not present");
|
|
6478
6495
|
}
|
|
@@ -6482,7 +6499,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
6482
6499
|
this.#shiftItemPosition(existingItemIndex, key);
|
|
6483
6500
|
}
|
|
6484
6501
|
const { newItem, newIndex } = this.#createAttachItemAndSort(op, key);
|
|
6485
|
-
const bumpDeltas =
|
|
6502
|
+
const bumpDeltas = this.#bumpUnackedPushesAbove(key);
|
|
6486
6503
|
return {
|
|
6487
6504
|
modified: makeUpdate(this, [
|
|
6488
6505
|
insertDelta(newIndex, newItem),
|
|
@@ -6497,6 +6514,13 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
6497
6514
|
* the single source of truth, so an item drops out the instant its op is
|
|
6498
6515
|
* acked, with no per-instance membership to leak. Yielded in push order.
|
|
6499
6516
|
*
|
|
6517
|
+
* Excludes ops that may already be stored on the server (they were in
|
|
6518
|
+
* flight when a connection died, so their fate is unknown): the bump
|
|
6519
|
+
* prediction assumes the server has not processed the op yet, which is only
|
|
6520
|
+
* guaranteed for ops sent on the current connection. For these excluded
|
|
6521
|
+
* ops, the server's (re-)ack states the authoritative position; predicting
|
|
6522
|
+
* locally could produce a wrong position that no ack would correct.
|
|
6523
|
+
*
|
|
6500
6524
|
* Restricted to items currently in `#items`: a pushed node whose op is still
|
|
6501
6525
|
* pending may have been pulled out of the list (e.g. implicitly deleted by a
|
|
6502
6526
|
* remote set, or removed by an undo) while still living in the pool, and such
|
|
@@ -6510,6 +6534,9 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
6510
6534
|
if (op.intent !== "push") {
|
|
6511
6535
|
continue;
|
|
6512
6536
|
}
|
|
6537
|
+
if (this._pool.unacknowledgedOps.isPossiblyStored(op.opId)) {
|
|
6538
|
+
continue;
|
|
6539
|
+
}
|
|
6513
6540
|
const node = this._pool.getNode(op.id);
|
|
6514
6541
|
if (node !== void 0 && this.#items.includes(node)) {
|
|
6515
6542
|
yield node;
|
|
@@ -6674,7 +6701,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
6674
6701
|
}
|
|
6675
6702
|
}
|
|
6676
6703
|
/** @internal */
|
|
6677
|
-
_attachChild(op, source
|
|
6704
|
+
_attachChild(op, source) {
|
|
6678
6705
|
if (this._pool === void 0) {
|
|
6679
6706
|
throw new Error("Can't attach child if managed pool is not present");
|
|
6680
6707
|
}
|
|
@@ -6689,7 +6716,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
6689
6716
|
}
|
|
6690
6717
|
} else {
|
|
6691
6718
|
if (source === 1 /* THEIRS */) {
|
|
6692
|
-
result = this.#applyRemoteInsert(op
|
|
6719
|
+
result = this.#applyRemoteInsert(op);
|
|
6693
6720
|
} else if (source === 2 /* OURS */) {
|
|
6694
6721
|
result = this.#applyInsertAck(op);
|
|
6695
6722
|
} else {
|
|
@@ -10354,6 +10381,7 @@ function createRoom(options, config) {
|
|
|
10354
10381
|
}
|
|
10355
10382
|
function onDidDisconnect() {
|
|
10356
10383
|
clearTimeout(context.buffer.flushTimerID);
|
|
10384
|
+
context.unacknowledgedOps.markAllAsPossiblyStored();
|
|
10357
10385
|
}
|
|
10358
10386
|
managedSocket.events.onMessage.subscribe(handleServerMessage);
|
|
10359
10387
|
managedSocket.events.statusDidChange.subscribe(onStatusDidChange);
|
|
@@ -10495,11 +10523,7 @@ function createRoom(options, config) {
|
|
|
10495
10523
|
currentItems.set(id, crdt._serialize());
|
|
10496
10524
|
}
|
|
10497
10525
|
const ops = getTreesDiffOperations(currentItems, nodes);
|
|
10498
|
-
const result = applyRemoteOps(
|
|
10499
|
-
ops,
|
|
10500
|
-
/* fromSnapshot */
|
|
10501
|
-
true
|
|
10502
|
-
);
|
|
10526
|
+
const result = applyRemoteOps(ops);
|
|
10503
10527
|
notify(result.updates);
|
|
10504
10528
|
} else {
|
|
10505
10529
|
context.root = LiveObject._fromItems(
|
|
@@ -10581,16 +10605,15 @@ function createRoom(options, config) {
|
|
|
10581
10605
|
);
|
|
10582
10606
|
return { opsToEmit: opsWithOpIds, reverse, updates };
|
|
10583
10607
|
}
|
|
10584
|
-
function applyRemoteOps(ops
|
|
10608
|
+
function applyRemoteOps(ops) {
|
|
10585
10609
|
return applyOps(
|
|
10586
10610
|
[],
|
|
10587
10611
|
ops,
|
|
10588
10612
|
/* isLocal */
|
|
10589
|
-
false
|
|
10590
|
-
fromSnapshot
|
|
10613
|
+
false
|
|
10591
10614
|
);
|
|
10592
10615
|
}
|
|
10593
|
-
function applyOps(pframes, ops, isLocal
|
|
10616
|
+
function applyOps(pframes, ops, isLocal) {
|
|
10594
10617
|
const output = {
|
|
10595
10618
|
reverse: new Deque(),
|
|
10596
10619
|
storageUpdates: /* @__PURE__ */ new Map(),
|
|
@@ -10626,7 +10649,7 @@ function createRoom(options, config) {
|
|
|
10626
10649
|
} else {
|
|
10627
10650
|
source = 1 /* THEIRS */;
|
|
10628
10651
|
}
|
|
10629
|
-
const applyOpResult = applyOp(op, source
|
|
10652
|
+
const applyOpResult = applyOp(op, source);
|
|
10630
10653
|
if (applyOpResult.modified) {
|
|
10631
10654
|
const nodeId = applyOpResult.modified.node._id;
|
|
10632
10655
|
if (!(nodeId && createdNodeIds.has(nodeId))) {
|
|
@@ -10652,7 +10675,7 @@ function createRoom(options, config) {
|
|
|
10652
10675
|
}
|
|
10653
10676
|
};
|
|
10654
10677
|
}
|
|
10655
|
-
function applyOp(op, source
|
|
10678
|
+
function applyOp(op, source) {
|
|
10656
10679
|
if (isIgnoredOp(op)) {
|
|
10657
10680
|
return { modified: false };
|
|
10658
10681
|
}
|
|
@@ -10693,7 +10716,7 @@ function createRoom(options, config) {
|
|
|
10693
10716
|
if (parentNode === void 0) {
|
|
10694
10717
|
return { modified: false };
|
|
10695
10718
|
}
|
|
10696
|
-
return parentNode._attachChild(op, source
|
|
10719
|
+
return parentNode._attachChild(op, source);
|
|
10697
10720
|
}
|
|
10698
10721
|
}
|
|
10699
10722
|
}
|