@liveblocks/core 3.24.2 → 3.24.3
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 +102 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +14 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.js +102 -9
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
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.24.
|
|
9
|
+
var PKG_VERSION = "3.24.3";
|
|
10
10
|
var PKG_FORMAT = "cjs";
|
|
11
11
|
|
|
12
12
|
// src/dupe-detection.ts
|
|
@@ -9850,6 +9850,10 @@ var LiveText = class _LiveText extends AbstractCrdt {
|
|
|
9850
9850
|
/** Local edits made while an op is in flight; sent after the ack. */
|
|
9851
9851
|
#queuedOps = [];
|
|
9852
9852
|
#acceptedOps = [];
|
|
9853
|
+
/** Wait for replay history before applying post-snapshot remote ops. */
|
|
9854
|
+
#reconnecting = false;
|
|
9855
|
+
#deferredHistorylessAck = false;
|
|
9856
|
+
#bufferedRemoteOps = [];
|
|
9853
9857
|
/**
|
|
9854
9858
|
* Creates a new LiveText document.
|
|
9855
9859
|
*
|
|
@@ -9921,6 +9925,14 @@ var LiveText = class _LiveText extends AbstractCrdt {
|
|
|
9921
9925
|
throw new Error("LiveText cannot contain child nodes");
|
|
9922
9926
|
}
|
|
9923
9927
|
/** @internal */
|
|
9928
|
+
_deferAckWithoutHistory(op) {
|
|
9929
|
+
if (this.#reconnecting && !this.#deferredHistorylessAck && op.opId !== void 0 && op.opId === this.#inFlightOpId && op.history === void 0) {
|
|
9930
|
+
this.#deferredHistorylessAck = true;
|
|
9931
|
+
return true;
|
|
9932
|
+
}
|
|
9933
|
+
return false;
|
|
9934
|
+
}
|
|
9935
|
+
/** @internal */
|
|
9924
9936
|
_apply(op, source) {
|
|
9925
9937
|
if (op.type !== OpCode.UPDATE_TEXT) {
|
|
9926
9938
|
return super._apply(op, source);
|
|
@@ -10152,8 +10164,6 @@ var LiveText = class _LiveText extends AbstractCrdt {
|
|
|
10152
10164
|
#applyLocal(op, source) {
|
|
10153
10165
|
const mutableOp = op;
|
|
10154
10166
|
if (op.opId !== void 0 && op.opId === this.#inFlightOpId) {
|
|
10155
|
-
this.#inFlightOps = [...this.#inFlightOps, ...this.#queuedOps];
|
|
10156
|
-
this.#queuedOps = [];
|
|
10157
10167
|
mutableOp.baseVersion = this.#version;
|
|
10158
10168
|
mutableOp.ops = [...this.#inFlightOps];
|
|
10159
10169
|
return { modified: false };
|
|
@@ -10192,6 +10202,9 @@ var LiveText = class _LiveText extends AbstractCrdt {
|
|
|
10192
10202
|
}
|
|
10193
10203
|
/** Server acknowledgement of our in-flight op. */
|
|
10194
10204
|
#applyAck(op, source) {
|
|
10205
|
+
if (this.#reconnecting) {
|
|
10206
|
+
return this.#reconcileAck(op, source);
|
|
10207
|
+
}
|
|
10195
10208
|
const ackedVersion = _nullishCoalesce(op.version, () => ( Math.max(this.#version, op.baseVersion + 1)));
|
|
10196
10209
|
const predicted = this.#inFlightOps;
|
|
10197
10210
|
const opId = this.#inFlightOpId;
|
|
@@ -10214,7 +10227,9 @@ var LiveText = class _LiveText extends AbstractCrdt {
|
|
|
10214
10227
|
node: this,
|
|
10215
10228
|
version: ackedVersion,
|
|
10216
10229
|
updates: rebuilt.changes,
|
|
10217
|
-
|
|
10230
|
+
// A correction was not applied by the originating editor. It
|
|
10231
|
+
// must not be filtered out as an echo of a local edit.
|
|
10232
|
+
source: REMOTE
|
|
10218
10233
|
}
|
|
10219
10234
|
};
|
|
10220
10235
|
}
|
|
@@ -10224,9 +10239,69 @@ var LiveText = class _LiveText extends AbstractCrdt {
|
|
|
10224
10239
|
this.#flushQueued();
|
|
10225
10240
|
return result;
|
|
10226
10241
|
}
|
|
10242
|
+
/** Recover the missing server timeline, preserving the normal OT invariants. */
|
|
10243
|
+
#reconcileAck(op, source) {
|
|
10244
|
+
const history = op.history;
|
|
10245
|
+
if (history === void 0) {
|
|
10246
|
+
this._rejectPendingOp(nn(op.opId));
|
|
10247
|
+
return { modified: false, needsStorageResync: true };
|
|
10248
|
+
}
|
|
10249
|
+
this.#reconnecting = false;
|
|
10250
|
+
this.#deferredHistorylessAck = false;
|
|
10251
|
+
const buffered = this.#bufferedRemoteOps;
|
|
10252
|
+
this.#bufferedRemoteOps = [];
|
|
10253
|
+
const changes = [];
|
|
10254
|
+
const collect = (result) => {
|
|
10255
|
+
if (result.modified && result.modified.type === "LiveText") {
|
|
10256
|
+
changes.push(...result.modified.updates);
|
|
10257
|
+
}
|
|
10258
|
+
};
|
|
10259
|
+
for (const entry of history) {
|
|
10260
|
+
if (entry.version <= this.#version) continue;
|
|
10261
|
+
if (entry.version === op.version) {
|
|
10262
|
+
collect(this.#applyAck(op, source));
|
|
10263
|
+
} else {
|
|
10264
|
+
collect(
|
|
10265
|
+
this.#applyRemote(
|
|
10266
|
+
{
|
|
10267
|
+
type: OpCode.UPDATE_TEXT,
|
|
10268
|
+
id: op.id,
|
|
10269
|
+
baseVersion: entry.version - 1,
|
|
10270
|
+
version: entry.version,
|
|
10271
|
+
ops: entry.ops
|
|
10272
|
+
},
|
|
10273
|
+
REMOTE
|
|
10274
|
+
)
|
|
10275
|
+
);
|
|
10276
|
+
}
|
|
10277
|
+
}
|
|
10278
|
+
if (this.#inFlightOpId === op.opId) {
|
|
10279
|
+
collect(this.#applyAck(op, source));
|
|
10280
|
+
}
|
|
10281
|
+
for (const remote of buffered) {
|
|
10282
|
+
collect(this.#applyRemote(remote, REMOTE));
|
|
10283
|
+
}
|
|
10284
|
+
return changes.length === 0 ? { modified: false } : {
|
|
10285
|
+
reverse: [],
|
|
10286
|
+
modified: {
|
|
10287
|
+
type: "LiveText",
|
|
10288
|
+
node: this,
|
|
10289
|
+
version: this.#version,
|
|
10290
|
+
updates: changes,
|
|
10291
|
+
source: REMOTE
|
|
10292
|
+
}
|
|
10293
|
+
};
|
|
10294
|
+
}
|
|
10227
10295
|
/** An accepted op from another client (or a server-fabricated fix op). */
|
|
10228
10296
|
#applyRemote(op, source) {
|
|
10229
10297
|
const version = _nullishCoalesce(op.version, () => ( this.#version + 1));
|
|
10298
|
+
if (op.version !== void 0 && op.version <= this.#version) {
|
|
10299
|
+
return { modified: false };
|
|
10300
|
+
}
|
|
10301
|
+
if (this.#reconnecting) {
|
|
10302
|
+
this.#bufferedRemoteOps.push(op);
|
|
10303
|
+
return { modified: false };
|
|
10304
|
+
}
|
|
10230
10305
|
this.#confirmed = applyTextOperationsToSegments(this.#confirmed, op.ops);
|
|
10231
10306
|
const [overInFlight, inFlight] = transformTextOperationsX(
|
|
10232
10307
|
op.ops,
|
|
@@ -10332,14 +10407,18 @@ var LiveText = class _LiveText extends AbstractCrdt {
|
|
|
10332
10407
|
return { appliedOps, changes };
|
|
10333
10408
|
}
|
|
10334
10409
|
/**
|
|
10335
|
-
* Reconcile
|
|
10336
|
-
*
|
|
10337
|
-
* snapshot
|
|
10338
|
-
* will be re-sent by the offline-ops replay.
|
|
10410
|
+
* Reconcile against an authoritative snapshot. With pending edits, retain
|
|
10411
|
+
* the current document and confirmed version until replay history arrives:
|
|
10412
|
+
* a snapshot alone cannot re-express the queue over unseen operations.
|
|
10339
10413
|
*
|
|
10340
10414
|
* @internal
|
|
10341
10415
|
*/
|
|
10342
10416
|
_resyncText(data, version, source) {
|
|
10417
|
+
if (this.#inFlightOpId !== void 0) {
|
|
10418
|
+
this.#reconnecting = true;
|
|
10419
|
+
this.#deferredHistorylessAck = false;
|
|
10420
|
+
return void 0;
|
|
10421
|
+
}
|
|
10343
10422
|
this.#confirmed = dataToSegments(data);
|
|
10344
10423
|
this.#version = version;
|
|
10345
10424
|
this.#acceptedOps = [];
|
|
@@ -10369,6 +10448,9 @@ var LiveText = class _LiveText extends AbstractCrdt {
|
|
|
10369
10448
|
this.#inFlightOpId = void 0;
|
|
10370
10449
|
this.#inFlightOps = [];
|
|
10371
10450
|
this.#queuedOps = [];
|
|
10451
|
+
this.#bufferedRemoteOps = [];
|
|
10452
|
+
this.#reconnecting = false;
|
|
10453
|
+
this.#deferredHistorylessAck = false;
|
|
10372
10454
|
}
|
|
10373
10455
|
#recordAccepted(version, ops, opId) {
|
|
10374
10456
|
if (this.#acceptedOps.some((entry) => entry.version === version)) {
|
|
@@ -12303,6 +12385,12 @@ function createRoom(options, config) {
|
|
|
12303
12385
|
}
|
|
12304
12386
|
const createdNodeIds = /* @__PURE__ */ new Set();
|
|
12305
12387
|
for (const op of ops) {
|
|
12388
|
+
if (!isLocal && op.type === OpCode.UPDATE_TEXT && op.opId !== void 0) {
|
|
12389
|
+
const node = context.pool.nodes.get(op.id);
|
|
12390
|
+
if (node !== void 0 && isLiveText(node) && node._deferAckWithoutHistory(op)) {
|
|
12391
|
+
continue;
|
|
12392
|
+
}
|
|
12393
|
+
}
|
|
12306
12394
|
let source;
|
|
12307
12395
|
if (isLocal) {
|
|
12308
12396
|
source = { ...localSource, optimistic: true };
|
|
@@ -12317,6 +12405,10 @@ function createRoom(options, config) {
|
|
|
12317
12405
|
source = REMOTE;
|
|
12318
12406
|
}
|
|
12319
12407
|
const applyOpResult = applyOp(op, source);
|
|
12408
|
+
if ("needsStorageResync" in applyOpResult) {
|
|
12409
|
+
refreshStorage();
|
|
12410
|
+
flushNowOrSoon();
|
|
12411
|
+
}
|
|
12320
12412
|
if (applyOpResult.modified) {
|
|
12321
12413
|
const nodeId = applyOpResult.modified.node._id;
|
|
12322
12414
|
if (!(nodeId && createdNodeIds.has(nodeId))) {
|
|
@@ -12537,7 +12629,8 @@ function createRoom(options, config) {
|
|
|
12537
12629
|
const result = applyLocalOps(unackedOps);
|
|
12538
12630
|
messages.push({
|
|
12539
12631
|
type: ClientMsgCode.UPDATE_STORAGE,
|
|
12540
|
-
ops: result.opsToEmit
|
|
12632
|
+
ops: result.opsToEmit,
|
|
12633
|
+
includeTextHistory: true
|
|
12541
12634
|
});
|
|
12542
12635
|
notify(result.updates);
|
|
12543
12636
|
sendMessages(messages);
|