@liveblocks/core 3.19.5-pre1 → 3.19.5-rc2
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
|
@@ -886,6 +886,15 @@ interface ReadonlyUnacknowledgedOps {
|
|
|
886
886
|
* the given ones (i.e. targeting one exact position).
|
|
887
887
|
*/
|
|
888
888
|
getByParentIdAndKey(parentId: string, parentKey: string): Iterable<ClientWireCreateOp>;
|
|
889
|
+
/**
|
|
890
|
+
* Whether the given pending op may already have been processed by the
|
|
891
|
+
* server. True for ops that were in flight when a connection died: the
|
|
892
|
+
* server may have stored them with the ack getting lost in the disconnect,
|
|
893
|
+
* or may never have received them. Until the (re-sent) op's ack arrives,
|
|
894
|
+
* the client cannot know which, so optimistic predictions that assume the
|
|
895
|
+
* op has not been processed yet are unsound for these ops.
|
|
896
|
+
*/
|
|
897
|
+
isPossiblyStored(opId: string): boolean;
|
|
889
898
|
}
|
|
890
899
|
|
|
891
900
|
/**
|
package/dist/index.d.ts
CHANGED
|
@@ -886,6 +886,15 @@ interface ReadonlyUnacknowledgedOps {
|
|
|
886
886
|
* the given ones (i.e. targeting one exact position).
|
|
887
887
|
*/
|
|
888
888
|
getByParentIdAndKey(parentId: string, parentKey: string): Iterable<ClientWireCreateOp>;
|
|
889
|
+
/**
|
|
890
|
+
* Whether the given pending op may already have been processed by the
|
|
891
|
+
* server. True for ops that were in flight when a connection died: the
|
|
892
|
+
* server may have stored them with the ack getting lost in the disconnect,
|
|
893
|
+
* or may never have received them. Until the (re-sent) op's ack arrives,
|
|
894
|
+
* the client cannot know which, so optimistic predictions that assume the
|
|
895
|
+
* op has not been processed yet are unsound for these ops.
|
|
896
|
+
*/
|
|
897
|
+
isPossiblyStored(opId: string): boolean;
|
|
889
898
|
}
|
|
890
899
|
|
|
891
900
|
/**
|
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.19.5-
|
|
9
|
+
var PKG_VERSION = "3.19.5-rc2";
|
|
10
10
|
var PKG_FORMAT = "esm";
|
|
11
11
|
|
|
12
12
|
// src/dupe-detection.ts
|
|
@@ -5784,6 +5784,9 @@ var UnacknowledgedOps = class {
|
|
|
5784
5784
|
#createOpsByPosition = /* @__PURE__ */ new Map();
|
|
5785
5785
|
// parentId -> (opId -> Create op)
|
|
5786
5786
|
#createOpsByParent = /* @__PURE__ */ new Map();
|
|
5787
|
+
// opIds of pending ops that were in flight when a connection died, so the
|
|
5788
|
+
// server may already have processed them. See isPossiblyStored().
|
|
5789
|
+
#possiblyStoredOpIds = /* @__PURE__ */ new Set();
|
|
5787
5790
|
#posKey(parentId, parentKey) {
|
|
5788
5791
|
return `${parentId}
|
|
5789
5792
|
${parentKey}`;
|
|
@@ -5823,6 +5826,7 @@ ${parentKey}`;
|
|
|
5823
5826
|
return;
|
|
5824
5827
|
}
|
|
5825
5828
|
this.#byOpId.delete(opId);
|
|
5829
|
+
this.#possiblyStoredOpIds.delete(opId);
|
|
5826
5830
|
if (isCreateOp(op)) {
|
|
5827
5831
|
const posKey = this.#posKey(op.parentId, op.parentKey);
|
|
5828
5832
|
const atPosition = this.#createOpsByPosition.get(posKey);
|
|
@@ -5856,6 +5860,19 @@ ${parentKey}`;
|
|
|
5856
5860
|
values() {
|
|
5857
5861
|
return this.#byOpId.values();
|
|
5858
5862
|
}
|
|
5863
|
+
isPossiblyStored(opId) {
|
|
5864
|
+
return this.#possiblyStoredOpIds.has(opId);
|
|
5865
|
+
}
|
|
5866
|
+
/**
|
|
5867
|
+
* Mark every currently pending op as possibly stored on the server. Called
|
|
5868
|
+
* when the connection dies: all of these ops were in flight, and their
|
|
5869
|
+
* (possibly lost) acks would have been the only way to know their fate.
|
|
5870
|
+
*/
|
|
5871
|
+
markAllAsPossiblyStored() {
|
|
5872
|
+
for (const opId of this.#byOpId.keys()) {
|
|
5873
|
+
this.#possiblyStoredOpIds.add(opId);
|
|
5874
|
+
}
|
|
5875
|
+
}
|
|
5859
5876
|
};
|
|
5860
5877
|
|
|
5861
5878
|
// src/crdts/AbstractCrdt.ts
|
|
@@ -6452,7 +6469,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
6452
6469
|
}
|
|
6453
6470
|
return result.modified.updates[0];
|
|
6454
6471
|
}
|
|
6455
|
-
#applyRemoteInsert(op
|
|
6472
|
+
#applyRemoteInsert(op) {
|
|
6456
6473
|
if (this._pool === void 0) {
|
|
6457
6474
|
throw new Error("Can't attach child if managed pool is not present");
|
|
6458
6475
|
}
|
|
@@ -6462,7 +6479,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
6462
6479
|
this.#shiftItemPosition(existingItemIndex, key);
|
|
6463
6480
|
}
|
|
6464
6481
|
const { newItem, newIndex } = this.#createAttachItemAndSort(op, key);
|
|
6465
|
-
const bumpDeltas =
|
|
6482
|
+
const bumpDeltas = this.#bumpUnackedPushesAbove(key);
|
|
6466
6483
|
return {
|
|
6467
6484
|
modified: makeUpdate(this, [
|
|
6468
6485
|
insertDelta(newIndex, newItem),
|
|
@@ -6477,6 +6494,13 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
6477
6494
|
* the single source of truth, so an item drops out the instant its op is
|
|
6478
6495
|
* acked, with no per-instance membership to leak. Yielded in push order.
|
|
6479
6496
|
*
|
|
6497
|
+
* Excludes ops that may already be stored on the server (they were in
|
|
6498
|
+
* flight when a connection died, so their fate is unknown): the bump
|
|
6499
|
+
* prediction assumes the server has not processed the op yet, which is only
|
|
6500
|
+
* guaranteed for ops sent on the current connection. For these excluded
|
|
6501
|
+
* ops, the server's (re-)ack states the authoritative position; predicting
|
|
6502
|
+
* locally could produce a wrong position that no ack would correct.
|
|
6503
|
+
*
|
|
6480
6504
|
* Restricted to items currently in `#items`: a pushed node whose op is still
|
|
6481
6505
|
* pending may have been pulled out of the list (e.g. implicitly deleted by a
|
|
6482
6506
|
* remote set, or removed by an undo) while still living in the pool, and such
|
|
@@ -6490,6 +6514,9 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
6490
6514
|
if (op.intent !== "push") {
|
|
6491
6515
|
continue;
|
|
6492
6516
|
}
|
|
6517
|
+
if (this._pool.unacknowledgedOps.isPossiblyStored(op.opId)) {
|
|
6518
|
+
continue;
|
|
6519
|
+
}
|
|
6493
6520
|
const node = this._pool.getNode(op.id);
|
|
6494
6521
|
if (node !== void 0 && this.#items.includes(node)) {
|
|
6495
6522
|
yield node;
|
|
@@ -6654,7 +6681,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
6654
6681
|
}
|
|
6655
6682
|
}
|
|
6656
6683
|
/** @internal */
|
|
6657
|
-
_attachChild(op, source
|
|
6684
|
+
_attachChild(op, source) {
|
|
6658
6685
|
if (this._pool === void 0) {
|
|
6659
6686
|
throw new Error("Can't attach child if managed pool is not present");
|
|
6660
6687
|
}
|
|
@@ -6669,7 +6696,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
6669
6696
|
}
|
|
6670
6697
|
} else {
|
|
6671
6698
|
if (source === 1 /* THEIRS */) {
|
|
6672
|
-
result = this.#applyRemoteInsert(op
|
|
6699
|
+
result = this.#applyRemoteInsert(op);
|
|
6673
6700
|
} else if (source === 2 /* OURS */) {
|
|
6674
6701
|
result = this.#applyInsertAck(op);
|
|
6675
6702
|
} else {
|
|
@@ -9699,6 +9726,7 @@ function createRoom(options, config) {
|
|
|
9699
9726
|
}
|
|
9700
9727
|
function onDidDisconnect() {
|
|
9701
9728
|
clearTimeout(context.buffer.flushTimerID);
|
|
9729
|
+
context.unacknowledgedOps.markAllAsPossiblyStored();
|
|
9702
9730
|
}
|
|
9703
9731
|
managedSocket.events.onMessage.subscribe(handleServerMessage);
|
|
9704
9732
|
managedSocket.events.statusDidChange.subscribe(onStatusDidChange);
|
|
@@ -9840,11 +9868,7 @@ function createRoom(options, config) {
|
|
|
9840
9868
|
currentItems.set(id, crdt._serialize());
|
|
9841
9869
|
}
|
|
9842
9870
|
const ops = getTreesDiffOperations(currentItems, nodes);
|
|
9843
|
-
const result = applyRemoteOps(
|
|
9844
|
-
ops,
|
|
9845
|
-
/* fromSnapshot */
|
|
9846
|
-
true
|
|
9847
|
-
);
|
|
9871
|
+
const result = applyRemoteOps(ops);
|
|
9848
9872
|
notify(result.updates);
|
|
9849
9873
|
} else {
|
|
9850
9874
|
context.root = LiveObject._fromItems(
|
|
@@ -9926,16 +9950,15 @@ function createRoom(options, config) {
|
|
|
9926
9950
|
);
|
|
9927
9951
|
return { opsToEmit: opsWithOpIds, reverse, updates };
|
|
9928
9952
|
}
|
|
9929
|
-
function applyRemoteOps(ops
|
|
9953
|
+
function applyRemoteOps(ops) {
|
|
9930
9954
|
return applyOps(
|
|
9931
9955
|
[],
|
|
9932
9956
|
ops,
|
|
9933
9957
|
/* isLocal */
|
|
9934
|
-
false
|
|
9935
|
-
fromSnapshot
|
|
9958
|
+
false
|
|
9936
9959
|
);
|
|
9937
9960
|
}
|
|
9938
|
-
function applyOps(pframes, ops, isLocal
|
|
9961
|
+
function applyOps(pframes, ops, isLocal) {
|
|
9939
9962
|
const output = {
|
|
9940
9963
|
reverse: new Deque(),
|
|
9941
9964
|
storageUpdates: /* @__PURE__ */ new Map(),
|
|
@@ -9971,7 +9994,7 @@ function createRoom(options, config) {
|
|
|
9971
9994
|
} else {
|
|
9972
9995
|
source = 1 /* THEIRS */;
|
|
9973
9996
|
}
|
|
9974
|
-
const applyOpResult = applyOp(op, source
|
|
9997
|
+
const applyOpResult = applyOp(op, source);
|
|
9975
9998
|
if (applyOpResult.modified) {
|
|
9976
9999
|
const nodeId = applyOpResult.modified.node._id;
|
|
9977
10000
|
if (!(nodeId && createdNodeIds.has(nodeId))) {
|
|
@@ -9997,7 +10020,7 @@ function createRoom(options, config) {
|
|
|
9997
10020
|
}
|
|
9998
10021
|
};
|
|
9999
10022
|
}
|
|
10000
|
-
function applyOp(op, source
|
|
10023
|
+
function applyOp(op, source) {
|
|
10001
10024
|
if (isIgnoredOp(op)) {
|
|
10002
10025
|
return { modified: false };
|
|
10003
10026
|
}
|
|
@@ -10036,7 +10059,7 @@ function createRoom(options, config) {
|
|
|
10036
10059
|
if (parentNode === void 0) {
|
|
10037
10060
|
return { modified: false };
|
|
10038
10061
|
}
|
|
10039
|
-
return parentNode._attachChild(op, source
|
|
10062
|
+
return parentNode._attachChild(op, source);
|
|
10040
10063
|
}
|
|
10041
10064
|
}
|
|
10042
10065
|
}
|