@liveblocks/core 3.23.1-exp2 → 3.23.1
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 +367 -1840
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +273 -612
- package/dist/index.d.ts +273 -612
- package/dist/index.js +295 -1768
- 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.23.1
|
|
9
|
+
var PKG_VERSION = "3.23.1";
|
|
10
10
|
var PKG_FORMAT = "cjs";
|
|
11
11
|
|
|
12
12
|
// src/dupe-detection.ts
|
|
@@ -988,15 +988,14 @@ var OpCode = Object.freeze({
|
|
|
988
988
|
DELETE_OBJECT_KEY: 6,
|
|
989
989
|
CREATE_MAP: 7,
|
|
990
990
|
CREATE_REGISTER: 8,
|
|
991
|
-
|
|
992
|
-
UPDATE_TEXT: 10,
|
|
991
|
+
// TODO: 9 and 10 are used by LiveText, wait until it's merged.
|
|
993
992
|
CREATE_FILE: 11
|
|
994
993
|
});
|
|
995
994
|
function isIgnoredOp(op) {
|
|
996
995
|
return op.type === OpCode.DELETE_CRDT && op.id === "ACK";
|
|
997
996
|
}
|
|
998
997
|
function isCreateOp(op) {
|
|
999
|
-
return op.type === OpCode.CREATE_OBJECT || op.type === OpCode.CREATE_REGISTER || op.type === OpCode.CREATE_FILE || op.type === OpCode.CREATE_MAP || op.type === OpCode.CREATE_LIST
|
|
998
|
+
return op.type === OpCode.CREATE_OBJECT || op.type === OpCode.CREATE_REGISTER || op.type === OpCode.CREATE_FILE || op.type === OpCode.CREATE_MAP || op.type === OpCode.CREATE_LIST;
|
|
1000
999
|
}
|
|
1001
1000
|
|
|
1002
1001
|
// src/protocol/StorageNode.ts
|
|
@@ -1005,7 +1004,7 @@ var CrdtType = Object.freeze({
|
|
|
1005
1004
|
LIST: 1,
|
|
1006
1005
|
MAP: 2,
|
|
1007
1006
|
REGISTER: 3,
|
|
1008
|
-
|
|
1007
|
+
// TODO: 4 is used by LiveText, wait until it's merged.
|
|
1009
1008
|
FILE: 5
|
|
1010
1009
|
});
|
|
1011
1010
|
function isRootStorageNode(node) {
|
|
@@ -1023,9 +1022,6 @@ function isMapStorageNode(node) {
|
|
|
1023
1022
|
function isRegisterStorageNode(node) {
|
|
1024
1023
|
return node[1].type === CrdtType.REGISTER;
|
|
1025
1024
|
}
|
|
1026
|
-
function isTextStorageNode(node) {
|
|
1027
|
-
return node[1].type === CrdtType.TEXT;
|
|
1028
|
-
}
|
|
1029
1025
|
function isFileStorageNode(node) {
|
|
1030
1026
|
return node[1].type === CrdtType.FILE;
|
|
1031
1027
|
}
|
|
@@ -1051,9 +1047,6 @@ function* compactNodesToNodeStream(compactNodes) {
|
|
|
1051
1047
|
case CrdtType.REGISTER:
|
|
1052
1048
|
yield [cnode[0], { type: CrdtType.REGISTER, parentId: cnode[2], parentKey: cnode[3], data: cnode[4] }];
|
|
1053
1049
|
break;
|
|
1054
|
-
case CrdtType.TEXT:
|
|
1055
|
-
yield [cnode[0], { type: CrdtType.TEXT, parentId: cnode[2], parentKey: cnode[3], data: cnode[4], version: cnode[5] }];
|
|
1056
|
-
break;
|
|
1057
1050
|
case CrdtType.FILE:
|
|
1058
1051
|
yield [cnode[0], { type: CrdtType.FILE, parentId: cnode[2], parentKey: cnode[3], data: cnode[4] }];
|
|
1059
1052
|
break;
|
|
@@ -1085,17 +1078,6 @@ function* nodeStreamToCompactNodes(nodes) {
|
|
|
1085
1078
|
const id = node[0];
|
|
1086
1079
|
const crdt = node[1];
|
|
1087
1080
|
yield [id, CrdtType.REGISTER, crdt.parentId, crdt.parentKey, crdt.data];
|
|
1088
|
-
} else if (isTextStorageNode(node)) {
|
|
1089
|
-
const id = node[0];
|
|
1090
|
-
const crdt = node[1];
|
|
1091
|
-
yield [
|
|
1092
|
-
id,
|
|
1093
|
-
CrdtType.TEXT,
|
|
1094
|
-
crdt.parentId,
|
|
1095
|
-
crdt.parentKey,
|
|
1096
|
-
crdt.data,
|
|
1097
|
-
crdt.version
|
|
1098
|
-
];
|
|
1099
1081
|
} else if (isFileStorageNode(node)) {
|
|
1100
1082
|
const id = node[0];
|
|
1101
1083
|
const crdt = node[1];
|
|
@@ -1105,9 +1087,6 @@ function* nodeStreamToCompactNodes(nodes) {
|
|
|
1105
1087
|
}
|
|
1106
1088
|
}
|
|
1107
1089
|
|
|
1108
|
-
// src/internal.ts
|
|
1109
|
-
var kInternal = /* @__PURE__ */ Symbol();
|
|
1110
|
-
|
|
1111
1090
|
// src/lib/position.ts
|
|
1112
1091
|
var MIN_CODE = 32;
|
|
1113
1092
|
var MAX_CODE = 126;
|
|
@@ -1287,18 +1266,6 @@ function asPos(str) {
|
|
|
1287
1266
|
return isPos(str) ? str : convertToPos(str);
|
|
1288
1267
|
}
|
|
1289
1268
|
|
|
1290
|
-
// src/crdts/StorageUpdates.ts
|
|
1291
|
-
var REMOTE = freeze({ origin: "remote" });
|
|
1292
|
-
var LOCAL_EDIT = freeze({ origin: "local", via: "edit" });
|
|
1293
|
-
var LOCAL_UNDO = freeze({ origin: "local", via: "undo" });
|
|
1294
|
-
var LOCAL_REDO = freeze({ origin: "local", via: "redo" });
|
|
1295
|
-
function toUpdateSource(source) {
|
|
1296
|
-
return source.origin === "remote" ? source : (
|
|
1297
|
-
// Removes `optimistic` field, which is not public
|
|
1298
|
-
{ origin: "local", via: source.via }
|
|
1299
|
-
);
|
|
1300
|
-
}
|
|
1301
|
-
|
|
1302
1269
|
// src/crdts/UnacknowledgedOps.ts
|
|
1303
1270
|
var UnacknowledgedOps = class {
|
|
1304
1271
|
// opId -> op
|
|
@@ -1317,10 +1284,6 @@ ${parentKey}`;
|
|
|
1317
1284
|
get size() {
|
|
1318
1285
|
return this.#byOpId.size;
|
|
1319
1286
|
}
|
|
1320
|
-
/** The still-unacknowledged op with the given opId, if any. */
|
|
1321
|
-
get(opId) {
|
|
1322
|
-
return this.#byOpId.get(opId);
|
|
1323
|
-
}
|
|
1324
1287
|
/**
|
|
1325
1288
|
* Mark the given Op as still unacknowledged.
|
|
1326
1289
|
*/
|
|
@@ -1420,8 +1383,8 @@ function createManagedPool(options) {
|
|
|
1420
1383
|
deleteNode: (id) => void nodes.delete(id),
|
|
1421
1384
|
generateId: () => `${getCurrentConnectionId()}:${clock++}`,
|
|
1422
1385
|
generateOpId: () => `${getCurrentConnectionId()}:${opClock++}`,
|
|
1423
|
-
dispatch(ops, reverse, storageUpdates
|
|
1424
|
-
_optionalChain([onDispatch, 'optionalCall', _23 => _23(ops, reverse, storageUpdates
|
|
1386
|
+
dispatch(ops, reverse, storageUpdates) {
|
|
1387
|
+
_optionalChain([onDispatch, 'optionalCall', _23 => _23(ops, reverse, storageUpdates)]);
|
|
1425
1388
|
},
|
|
1426
1389
|
assertStorageIsWritable: () => {
|
|
1427
1390
|
if (!isStorageWritable()) {
|
|
@@ -1444,17 +1407,10 @@ function Orphaned(oldKey, oldPos = asPos(oldKey)) {
|
|
|
1444
1407
|
return Object.freeze({ type: "Orphaned", oldKey, oldPos });
|
|
1445
1408
|
}
|
|
1446
1409
|
var AbstractCrdt = class {
|
|
1410
|
+
// ^^^^^^^^^^^^ TODO: Make this an interface
|
|
1447
1411
|
#pool;
|
|
1448
1412
|
#id;
|
|
1449
1413
|
#parent = NoParent;
|
|
1450
|
-
constructor() {
|
|
1451
|
-
Object.defineProperty(this, kInternal, {
|
|
1452
|
-
value: {
|
|
1453
|
-
getId: () => this.#id
|
|
1454
|
-
},
|
|
1455
|
-
enumerable: false
|
|
1456
|
-
});
|
|
1457
|
-
}
|
|
1458
1414
|
/** @internal */
|
|
1459
1415
|
_getParentKeyOrThrow() {
|
|
1460
1416
|
switch (this.parent.type) {
|
|
@@ -1507,14 +1463,11 @@ var AbstractCrdt = class {
|
|
|
1507
1463
|
}
|
|
1508
1464
|
}
|
|
1509
1465
|
/** @internal */
|
|
1510
|
-
_apply(op,
|
|
1466
|
+
_apply(op, _isLocal) {
|
|
1511
1467
|
switch (op.type) {
|
|
1512
1468
|
case OpCode.DELETE_CRDT: {
|
|
1513
1469
|
if (this.parent.type === "HasParent") {
|
|
1514
|
-
return this.parent.node._detachChild(
|
|
1515
|
-
crdtAsLiveNode(this),
|
|
1516
|
-
toUpdateSource(source)
|
|
1517
|
-
);
|
|
1470
|
+
return this.parent.node._detachChild(crdtAsLiveNode(this));
|
|
1518
1471
|
}
|
|
1519
1472
|
return { modified: false };
|
|
1520
1473
|
}
|
|
@@ -1704,8 +1657,8 @@ var LiveFile = class _LiveFile extends AbstractCrdt {
|
|
|
1704
1657
|
throw new Error("A LiveFile node cannot have children");
|
|
1705
1658
|
}
|
|
1706
1659
|
/** @internal */
|
|
1707
|
-
_apply(op,
|
|
1708
|
-
return super._apply(op,
|
|
1660
|
+
_apply(op, isLocal) {
|
|
1661
|
+
return super._apply(op, isLocal);
|
|
1709
1662
|
}
|
|
1710
1663
|
/** @internal */
|
|
1711
1664
|
_toTreeNode(key) {
|
|
@@ -4924,6 +4877,9 @@ var ManagedSocket = class {
|
|
|
4924
4877
|
}
|
|
4925
4878
|
};
|
|
4926
4879
|
|
|
4880
|
+
// src/internal.ts
|
|
4881
|
+
var kInternal = /* @__PURE__ */ Symbol();
|
|
4882
|
+
|
|
4927
4883
|
// src/lib/IncrementalJsonParser.ts
|
|
4928
4884
|
var EMPTY_OBJECT = Object.freeze({});
|
|
4929
4885
|
var NULL_KEYWORD_CHARS = Array.from(new Set("null"));
|
|
@@ -6925,8 +6881,8 @@ var LiveRegister = class _LiveRegister extends AbstractCrdt {
|
|
|
6925
6881
|
throw new Error("Method not implemented.");
|
|
6926
6882
|
}
|
|
6927
6883
|
/** @internal */
|
|
6928
|
-
_apply(op,
|
|
6929
|
-
return super._apply(op,
|
|
6884
|
+
_apply(op, isLocal) {
|
|
6885
|
+
return super._apply(op, isLocal);
|
|
6930
6886
|
}
|
|
6931
6887
|
/** @internal */
|
|
6932
6888
|
_toTreeNode(key) {
|
|
@@ -7087,7 +7043,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
7087
7043
|
item._detach();
|
|
7088
7044
|
}
|
|
7089
7045
|
}
|
|
7090
|
-
#
|
|
7046
|
+
#applySetRemote(op) {
|
|
7091
7047
|
if (this._pool === void 0) {
|
|
7092
7048
|
throw new Error("Can't attach child if managed pool is not present");
|
|
7093
7049
|
}
|
|
@@ -7105,11 +7061,9 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
7105
7061
|
itemWithSamePosition._detach();
|
|
7106
7062
|
this.#items.add(child);
|
|
7107
7063
|
return {
|
|
7108
|
-
modified: makeUpdate(
|
|
7109
|
-
|
|
7110
|
-
|
|
7111
|
-
REMOTE
|
|
7112
|
-
),
|
|
7064
|
+
modified: makeUpdate(this, [
|
|
7065
|
+
setDelta(indexOfItemWithSamePosition, child)
|
|
7066
|
+
]),
|
|
7113
7067
|
reverse: []
|
|
7114
7068
|
};
|
|
7115
7069
|
} else {
|
|
@@ -7120,22 +7074,20 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
7120
7074
|
setDelta(indexOfItemWithSamePosition, child)
|
|
7121
7075
|
];
|
|
7122
7076
|
const deleteDelta2 = this.#detachItemAssociatedToSetOperation(
|
|
7123
|
-
op.deletedId
|
|
7124
|
-
REMOTE
|
|
7077
|
+
op.deletedId
|
|
7125
7078
|
);
|
|
7126
7079
|
if (deleteDelta2) {
|
|
7127
7080
|
delta.push(deleteDelta2);
|
|
7128
7081
|
}
|
|
7129
7082
|
return {
|
|
7130
|
-
modified: makeUpdate(this, delta
|
|
7083
|
+
modified: makeUpdate(this, delta),
|
|
7131
7084
|
reverse: []
|
|
7132
7085
|
};
|
|
7133
7086
|
}
|
|
7134
7087
|
} else {
|
|
7135
7088
|
const updates = [];
|
|
7136
7089
|
const deleteDelta2 = this.#detachItemAssociatedToSetOperation(
|
|
7137
|
-
op.deletedId
|
|
7138
|
-
REMOTE
|
|
7090
|
+
op.deletedId
|
|
7139
7091
|
);
|
|
7140
7092
|
if (deleteDelta2) {
|
|
7141
7093
|
updates.push(deleteDelta2);
|
|
@@ -7144,32 +7096,29 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
7144
7096
|
updates.push(insertDelta(this._indexOfPosition(key), child));
|
|
7145
7097
|
return {
|
|
7146
7098
|
reverse: [],
|
|
7147
|
-
modified: makeUpdate(this, updates
|
|
7099
|
+
modified: makeUpdate(this, updates)
|
|
7148
7100
|
};
|
|
7149
7101
|
}
|
|
7150
7102
|
}
|
|
7151
|
-
#applySetAck(op
|
|
7103
|
+
#applySetAck(op) {
|
|
7152
7104
|
if (this._pool === void 0) {
|
|
7153
7105
|
throw new Error("Can't attach child if managed pool is not present");
|
|
7154
7106
|
}
|
|
7155
7107
|
const delta = [];
|
|
7156
|
-
const deletedDelta = this.#detachItemAssociatedToSetOperation(
|
|
7157
|
-
op.deletedId,
|
|
7158
|
-
source
|
|
7159
|
-
);
|
|
7108
|
+
const deletedDelta = this.#detachItemAssociatedToSetOperation(op.deletedId);
|
|
7160
7109
|
if (deletedDelta) {
|
|
7161
7110
|
delta.push(deletedDelta);
|
|
7162
7111
|
}
|
|
7163
7112
|
const unacknowledgedOpId = this.#unacknowledgedSetOpIdAt(op.parentKey);
|
|
7164
7113
|
if (unacknowledgedOpId !== void 0 && unacknowledgedOpId !== op.opId) {
|
|
7165
|
-
return delta.length === 0 ? { modified: false } : { modified: makeUpdate(this, delta
|
|
7114
|
+
return delta.length === 0 ? { modified: false } : { modified: makeUpdate(this, delta), reverse: [] };
|
|
7166
7115
|
}
|
|
7167
7116
|
const indexOfItemWithSamePosition = this._indexOfPosition(op.parentKey);
|
|
7168
7117
|
const existingItem = this.#items.find((item) => item._id === op.id);
|
|
7169
7118
|
if (existingItem !== void 0) {
|
|
7170
7119
|
if (existingItem._parentKey === op.parentKey) {
|
|
7171
7120
|
return {
|
|
7172
|
-
modified: delta.length > 0 ? makeUpdate(this, delta
|
|
7121
|
+
modified: delta.length > 0 ? makeUpdate(this, delta) : false,
|
|
7173
7122
|
reverse: []
|
|
7174
7123
|
};
|
|
7175
7124
|
}
|
|
@@ -7187,7 +7136,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
7187
7136
|
delta.push(moveDelta(prevIndex, newIndex, existingItem));
|
|
7188
7137
|
}
|
|
7189
7138
|
return {
|
|
7190
|
-
modified: delta.length > 0 ? makeUpdate(this, delta
|
|
7139
|
+
modified: delta.length > 0 ? makeUpdate(this, delta) : false,
|
|
7191
7140
|
reverse: []
|
|
7192
7141
|
};
|
|
7193
7142
|
} else {
|
|
@@ -7197,15 +7146,11 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
7197
7146
|
this.#implicitlyDeletedItems.delete(orphan);
|
|
7198
7147
|
const recreatedItemIndex = this.#insert(orphan);
|
|
7199
7148
|
return {
|
|
7200
|
-
modified: makeUpdate(
|
|
7201
|
-
this,
|
|
7202
|
-
|
|
7203
|
-
|
|
7204
|
-
|
|
7205
|
-
...delta
|
|
7206
|
-
],
|
|
7207
|
-
source
|
|
7208
|
-
),
|
|
7149
|
+
modified: makeUpdate(this, [
|
|
7150
|
+
// If there is an item at this position, update is a set, else it's an insert
|
|
7151
|
+
indexOfItemWithSamePosition === -1 ? insertDelta(recreatedItemIndex, orphan) : setDelta(recreatedItemIndex, orphan),
|
|
7152
|
+
...delta
|
|
7153
|
+
]),
|
|
7209
7154
|
reverse: []
|
|
7210
7155
|
};
|
|
7211
7156
|
} else {
|
|
@@ -7220,15 +7165,11 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
7220
7165
|
op.parentKey
|
|
7221
7166
|
);
|
|
7222
7167
|
return {
|
|
7223
|
-
modified: makeUpdate(
|
|
7224
|
-
this,
|
|
7225
|
-
|
|
7226
|
-
|
|
7227
|
-
|
|
7228
|
-
...delta
|
|
7229
|
-
],
|
|
7230
|
-
source
|
|
7231
|
-
),
|
|
7168
|
+
modified: makeUpdate(this, [
|
|
7169
|
+
// If there is an item at this position, update is a set, else it's an insert
|
|
7170
|
+
indexOfItemWithSamePosition === -1 ? insertDelta(newIndex, newItem) : setDelta(newIndex, newItem),
|
|
7171
|
+
...delta
|
|
7172
|
+
]),
|
|
7232
7173
|
reverse: []
|
|
7233
7174
|
};
|
|
7234
7175
|
}
|
|
@@ -7237,7 +7178,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
7237
7178
|
/**
|
|
7238
7179
|
* Returns the update delta of the deletion or null
|
|
7239
7180
|
*/
|
|
7240
|
-
#detachItemAssociatedToSetOperation(deletedId
|
|
7181
|
+
#detachItemAssociatedToSetOperation(deletedId) {
|
|
7241
7182
|
if (deletedId === void 0 || this._pool === void 0) {
|
|
7242
7183
|
return null;
|
|
7243
7184
|
}
|
|
@@ -7245,7 +7186,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
7245
7186
|
if (deletedItem === void 0) {
|
|
7246
7187
|
return null;
|
|
7247
7188
|
}
|
|
7248
|
-
const result = this._detachChild(deletedItem
|
|
7189
|
+
const result = this._detachChild(deletedItem);
|
|
7249
7190
|
if (result.modified === false) {
|
|
7250
7191
|
return null;
|
|
7251
7192
|
}
|
|
@@ -7263,11 +7204,10 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
7263
7204
|
const { newItem, newIndex } = this.#createAttachItemAndSort(op, key);
|
|
7264
7205
|
const bumpDeltas = this.#bumpUnackedPushesAbove(key);
|
|
7265
7206
|
return {
|
|
7266
|
-
modified: makeUpdate(
|
|
7267
|
-
|
|
7268
|
-
|
|
7269
|
-
|
|
7270
|
-
),
|
|
7207
|
+
modified: makeUpdate(this, [
|
|
7208
|
+
insertDelta(newIndex, newItem),
|
|
7209
|
+
...bumpDeltas
|
|
7210
|
+
]),
|
|
7271
7211
|
reverse: []
|
|
7272
7212
|
};
|
|
7273
7213
|
}
|
|
@@ -7348,7 +7288,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
7348
7288
|
}
|
|
7349
7289
|
return deltas;
|
|
7350
7290
|
}
|
|
7351
|
-
#applyInsertAck(op
|
|
7291
|
+
#applyInsertAck(op) {
|
|
7352
7292
|
const existingItem = this.#items.find((item) => item._id === op.id);
|
|
7353
7293
|
const key = asPos(op.parentKey);
|
|
7354
7294
|
const itemIndexAtPosition = this._indexOfPosition(key);
|
|
@@ -7370,11 +7310,9 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
7370
7310
|
return { modified: false };
|
|
7371
7311
|
}
|
|
7372
7312
|
return {
|
|
7373
|
-
modified: makeUpdate(
|
|
7374
|
-
|
|
7375
|
-
|
|
7376
|
-
source
|
|
7377
|
-
),
|
|
7313
|
+
modified: makeUpdate(this, [
|
|
7314
|
+
moveDelta(oldPositionIndex, newIndex, existingItem)
|
|
7315
|
+
]),
|
|
7378
7316
|
reverse: []
|
|
7379
7317
|
};
|
|
7380
7318
|
}
|
|
@@ -7386,7 +7324,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
7386
7324
|
this.#insert(orphan);
|
|
7387
7325
|
const newIndex = this._indexOfPosition(key);
|
|
7388
7326
|
return {
|
|
7389
|
-
modified: makeUpdate(this, [insertDelta(newIndex, orphan)]
|
|
7327
|
+
modified: makeUpdate(this, [insertDelta(newIndex, orphan)]),
|
|
7390
7328
|
reverse: []
|
|
7391
7329
|
};
|
|
7392
7330
|
} else {
|
|
@@ -7395,13 +7333,13 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
7395
7333
|
}
|
|
7396
7334
|
const { newItem, newIndex } = this.#createAttachItemAndSort(op, key);
|
|
7397
7335
|
return {
|
|
7398
|
-
modified: makeUpdate(this, [insertDelta(newIndex, newItem)]
|
|
7336
|
+
modified: makeUpdate(this, [insertDelta(newIndex, newItem)]),
|
|
7399
7337
|
reverse: []
|
|
7400
7338
|
};
|
|
7401
7339
|
}
|
|
7402
7340
|
}
|
|
7403
7341
|
}
|
|
7404
|
-
#
|
|
7342
|
+
#applyInsertUndoRedo(op) {
|
|
7405
7343
|
const { id, parentKey: key } = op;
|
|
7406
7344
|
const child = creationOpToLiveNode(op);
|
|
7407
7345
|
if (_optionalChain([this, 'access', _151 => _151._pool, 'optionalAccess', _152 => _152.getNode, 'call', _153 => _153(id)]) !== void 0) {
|
|
@@ -7420,11 +7358,11 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
7420
7358
|
this.#insert(child);
|
|
7421
7359
|
const newIndex = this._indexOfPosition(newKey);
|
|
7422
7360
|
return {
|
|
7423
|
-
modified: makeUpdate(this, [insertDelta(newIndex, child)]
|
|
7361
|
+
modified: makeUpdate(this, [insertDelta(newIndex, child)]),
|
|
7424
7362
|
reverse: [{ type: OpCode.DELETE_CRDT, id }]
|
|
7425
7363
|
};
|
|
7426
7364
|
}
|
|
7427
|
-
#
|
|
7365
|
+
#applySetUndoRedo(op) {
|
|
7428
7366
|
const { id, parentKey: key } = op;
|
|
7429
7367
|
const child = creationOpToLiveNode(op);
|
|
7430
7368
|
if (_optionalChain([this, 'access', _162 => _162._pool, 'optionalAccess', _163 => _163.getNode, 'call', _164 => _164(id)]) !== void 0) {
|
|
@@ -7446,48 +7384,46 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
7446
7384
|
);
|
|
7447
7385
|
const delta = [setDelta(indexOfItemWithSameKey, child)];
|
|
7448
7386
|
const deletedDelta = this.#detachItemAssociatedToSetOperation(
|
|
7449
|
-
op.deletedId
|
|
7450
|
-
source
|
|
7387
|
+
op.deletedId
|
|
7451
7388
|
);
|
|
7452
7389
|
if (deletedDelta) {
|
|
7453
7390
|
delta.push(deletedDelta);
|
|
7454
7391
|
}
|
|
7455
7392
|
return {
|
|
7456
|
-
modified: makeUpdate(this, delta
|
|
7393
|
+
modified: makeUpdate(this, delta),
|
|
7457
7394
|
reverse
|
|
7458
7395
|
};
|
|
7459
7396
|
} else {
|
|
7460
7397
|
this.#insert(child);
|
|
7461
|
-
this.#detachItemAssociatedToSetOperation(op.deletedId
|
|
7398
|
+
this.#detachItemAssociatedToSetOperation(op.deletedId);
|
|
7462
7399
|
const newIndex = this._indexOfPosition(newKey);
|
|
7463
7400
|
return {
|
|
7464
7401
|
reverse: [{ type: OpCode.DELETE_CRDT, id }],
|
|
7465
|
-
modified: makeUpdate(this, [insertDelta(newIndex, child)]
|
|
7402
|
+
modified: makeUpdate(this, [insertDelta(newIndex, child)])
|
|
7466
7403
|
};
|
|
7467
7404
|
}
|
|
7468
7405
|
}
|
|
7469
7406
|
/** @internal */
|
|
7470
|
-
_attachChild(op,
|
|
7471
|
-
const source = toUpdateSource(opSource);
|
|
7407
|
+
_attachChild(op, source) {
|
|
7472
7408
|
if (this._pool === void 0) {
|
|
7473
7409
|
throw new Error("Can't attach child if managed pool is not present");
|
|
7474
7410
|
}
|
|
7475
7411
|
let result;
|
|
7476
7412
|
if (op.intent === "set") {
|
|
7477
|
-
if (
|
|
7478
|
-
result = this.#
|
|
7479
|
-
} else if (
|
|
7480
|
-
result = this.#applySetAck(op
|
|
7413
|
+
if (source === 1 /* THEIRS */) {
|
|
7414
|
+
result = this.#applySetRemote(op);
|
|
7415
|
+
} else if (source === 2 /* OURS */) {
|
|
7416
|
+
result = this.#applySetAck(op);
|
|
7481
7417
|
} else {
|
|
7482
|
-
result = this.#
|
|
7418
|
+
result = this.#applySetUndoRedo(op);
|
|
7483
7419
|
}
|
|
7484
7420
|
} else {
|
|
7485
|
-
if (
|
|
7421
|
+
if (source === 1 /* THEIRS */) {
|
|
7486
7422
|
result = this.#applyRemoteInsert(op);
|
|
7487
|
-
} else if (
|
|
7488
|
-
result = this.#applyInsertAck(op
|
|
7423
|
+
} else if (source === 2 /* OURS */) {
|
|
7424
|
+
result = this.#applyInsertAck(op);
|
|
7489
7425
|
} else {
|
|
7490
|
-
result = this.#
|
|
7426
|
+
result = this.#applyInsertUndoRedo(op);
|
|
7491
7427
|
}
|
|
7492
7428
|
}
|
|
7493
7429
|
if (result.modified !== false) {
|
|
@@ -7496,7 +7432,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
7496
7432
|
return result;
|
|
7497
7433
|
}
|
|
7498
7434
|
/** @internal */
|
|
7499
|
-
_detachChild(child
|
|
7435
|
+
_detachChild(child) {
|
|
7500
7436
|
if (child) {
|
|
7501
7437
|
const parentKey = nn(child._parentKey);
|
|
7502
7438
|
const reverse = child._toOps(nn(this._id), parentKey);
|
|
@@ -7511,23 +7447,19 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
7511
7447
|
this.invalidate();
|
|
7512
7448
|
child._detach();
|
|
7513
7449
|
return {
|
|
7514
|
-
modified: makeUpdate(
|
|
7515
|
-
this,
|
|
7516
|
-
[deleteDelta(indexToDelete, previousNode)],
|
|
7517
|
-
source
|
|
7518
|
-
),
|
|
7450
|
+
modified: makeUpdate(this, [deleteDelta(indexToDelete, previousNode)]),
|
|
7519
7451
|
reverse
|
|
7520
7452
|
};
|
|
7521
7453
|
}
|
|
7522
7454
|
return { modified: false };
|
|
7523
7455
|
}
|
|
7524
|
-
#
|
|
7456
|
+
#applySetChildKeyRemote(newKey, child) {
|
|
7525
7457
|
if (this.#implicitlyDeletedItems.has(child)) {
|
|
7526
7458
|
this.#implicitlyDeletedItems.delete(child);
|
|
7527
7459
|
child._setParentLink(this, newKey);
|
|
7528
7460
|
const newIndex = this.#insert(child);
|
|
7529
7461
|
return {
|
|
7530
|
-
modified: makeUpdate(this, [insertDelta(newIndex, child)]
|
|
7462
|
+
modified: makeUpdate(this, [insertDelta(newIndex, child)]),
|
|
7531
7463
|
reverse: []
|
|
7532
7464
|
};
|
|
7533
7465
|
}
|
|
@@ -7548,11 +7480,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
7548
7480
|
};
|
|
7549
7481
|
}
|
|
7550
7482
|
return {
|
|
7551
|
-
modified: makeUpdate(
|
|
7552
|
-
this,
|
|
7553
|
-
[moveDelta(previousIndex, newIndex, child)],
|
|
7554
|
-
REMOTE
|
|
7555
|
-
),
|
|
7483
|
+
modified: makeUpdate(this, [moveDelta(previousIndex, newIndex, child)]),
|
|
7556
7484
|
reverse: []
|
|
7557
7485
|
};
|
|
7558
7486
|
} else {
|
|
@@ -7569,16 +7497,12 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
7569
7497
|
};
|
|
7570
7498
|
}
|
|
7571
7499
|
return {
|
|
7572
|
-
modified: makeUpdate(
|
|
7573
|
-
this,
|
|
7574
|
-
[moveDelta(previousIndex, newIndex, child)],
|
|
7575
|
-
REMOTE
|
|
7576
|
-
),
|
|
7500
|
+
modified: makeUpdate(this, [moveDelta(previousIndex, newIndex, child)]),
|
|
7577
7501
|
reverse: []
|
|
7578
7502
|
};
|
|
7579
7503
|
}
|
|
7580
7504
|
}
|
|
7581
|
-
#applySetChildKeyAck(newKey, child
|
|
7505
|
+
#applySetChildKeyAck(newKey, child) {
|
|
7582
7506
|
const previousKey = nn(child._parentKey);
|
|
7583
7507
|
if (this.#implicitlyDeletedItems.has(child)) {
|
|
7584
7508
|
const existingItemIndex = this._indexOfPosition(newKey);
|
|
@@ -7597,7 +7521,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
7597
7521
|
child._setParentLink(this, newKey);
|
|
7598
7522
|
const newIndex = this.#insert(child);
|
|
7599
7523
|
return {
|
|
7600
|
-
modified: makeUpdate(this, [insertDelta(newIndex, child)]
|
|
7524
|
+
modified: makeUpdate(this, [insertDelta(newIndex, child)]),
|
|
7601
7525
|
reverse: []
|
|
7602
7526
|
};
|
|
7603
7527
|
} else {
|
|
@@ -7625,17 +7549,15 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
7625
7549
|
};
|
|
7626
7550
|
} else {
|
|
7627
7551
|
return {
|
|
7628
|
-
modified: makeUpdate(
|
|
7629
|
-
|
|
7630
|
-
|
|
7631
|
-
source
|
|
7632
|
-
),
|
|
7552
|
+
modified: makeUpdate(this, [
|
|
7553
|
+
moveDelta(previousIndex, newIndex, child)
|
|
7554
|
+
]),
|
|
7633
7555
|
reverse: []
|
|
7634
7556
|
};
|
|
7635
7557
|
}
|
|
7636
7558
|
}
|
|
7637
7559
|
}
|
|
7638
|
-
#
|
|
7560
|
+
#applySetChildKeyUndoRedo(newKey, child) {
|
|
7639
7561
|
const previousKey = nn(child._parentKey);
|
|
7640
7562
|
const previousIndex = this.#items.findIndex((item) => item === child);
|
|
7641
7563
|
const existingItemIndex = this._indexOfPosition(newKey);
|
|
@@ -7654,11 +7576,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
7654
7576
|
};
|
|
7655
7577
|
}
|
|
7656
7578
|
return {
|
|
7657
|
-
modified: makeUpdate(
|
|
7658
|
-
this,
|
|
7659
|
-
[moveDelta(previousIndex, newIndex, child)],
|
|
7660
|
-
source
|
|
7661
|
-
),
|
|
7579
|
+
modified: makeUpdate(this, [moveDelta(previousIndex, newIndex, child)]),
|
|
7662
7580
|
reverse: [
|
|
7663
7581
|
{
|
|
7664
7582
|
type: OpCode.SET_PARENT_KEY,
|
|
@@ -7669,19 +7587,18 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
7669
7587
|
};
|
|
7670
7588
|
}
|
|
7671
7589
|
/** @internal */
|
|
7672
|
-
_setChildKey(newKey, child,
|
|
7673
|
-
|
|
7674
|
-
|
|
7675
|
-
|
|
7676
|
-
|
|
7677
|
-
return this.#applySetChildKeyAck(newKey, child, source);
|
|
7590
|
+
_setChildKey(newKey, child, source) {
|
|
7591
|
+
if (source === 1 /* THEIRS */) {
|
|
7592
|
+
return this.#applySetChildKeyRemote(newKey, child);
|
|
7593
|
+
} else if (source === 2 /* OURS */) {
|
|
7594
|
+
return this.#applySetChildKeyAck(newKey, child);
|
|
7678
7595
|
} else {
|
|
7679
|
-
return this.#
|
|
7596
|
+
return this.#applySetChildKeyUndoRedo(newKey, child);
|
|
7680
7597
|
}
|
|
7681
7598
|
}
|
|
7682
7599
|
/** @internal */
|
|
7683
|
-
_apply(op,
|
|
7684
|
-
return super._apply(op,
|
|
7600
|
+
_apply(op, isLocal) {
|
|
7601
|
+
return super._apply(op, isLocal);
|
|
7685
7602
|
}
|
|
7686
7603
|
/** @internal */
|
|
7687
7604
|
_serialize() {
|
|
@@ -7742,7 +7659,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
7742
7659
|
intent === "push" ? addIntentToRootOp(ops, "push") : ops,
|
|
7743
7660
|
[{ type: OpCode.DELETE_CRDT, id }],
|
|
7744
7661
|
/* @__PURE__ */ new Map([
|
|
7745
|
-
[this._id, makeUpdate(this, [insertDelta(index, value)]
|
|
7662
|
+
[this._id, makeUpdate(this, [insertDelta(index, value)])]
|
|
7746
7663
|
])
|
|
7747
7664
|
);
|
|
7748
7665
|
}
|
|
@@ -7783,10 +7700,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
7783
7700
|
this.#updateItemPositionAt(index, position);
|
|
7784
7701
|
if (this._pool && this._id) {
|
|
7785
7702
|
const storageUpdates = /* @__PURE__ */ new Map([
|
|
7786
|
-
[
|
|
7787
|
-
this._id,
|
|
7788
|
-
makeUpdate(this, [moveDelta(index, targetIndex, item)], LOCAL_EDIT)
|
|
7789
|
-
]
|
|
7703
|
+
[this._id, makeUpdate(this, [moveDelta(index, targetIndex, item)])]
|
|
7790
7704
|
]);
|
|
7791
7705
|
this._pool.dispatch(
|
|
7792
7706
|
[
|
|
@@ -7829,7 +7743,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
7829
7743
|
const storageUpdates = /* @__PURE__ */ new Map();
|
|
7830
7744
|
storageUpdates.set(
|
|
7831
7745
|
nn(this._id),
|
|
7832
|
-
makeUpdate(this, [deleteDelta(index, item)]
|
|
7746
|
+
makeUpdate(this, [deleteDelta(index, item)])
|
|
7833
7747
|
);
|
|
7834
7748
|
this._pool.dispatch(
|
|
7835
7749
|
[
|
|
@@ -7869,10 +7783,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
7869
7783
|
this.#items.clear();
|
|
7870
7784
|
this.invalidate();
|
|
7871
7785
|
const storageUpdates = /* @__PURE__ */ new Map();
|
|
7872
|
-
storageUpdates.set(
|
|
7873
|
-
nn(this._id),
|
|
7874
|
-
makeUpdate(this, updateDelta, LOCAL_EDIT)
|
|
7875
|
-
);
|
|
7786
|
+
storageUpdates.set(nn(this._id), makeUpdate(this, updateDelta));
|
|
7876
7787
|
this._pool.dispatch(ops, reverseOps, storageUpdates);
|
|
7877
7788
|
} else {
|
|
7878
7789
|
for (const item of this.#items) {
|
|
@@ -7902,10 +7813,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
7902
7813
|
const id = this._pool.generateId();
|
|
7903
7814
|
value._attach(id, this._pool);
|
|
7904
7815
|
const storageUpdates = /* @__PURE__ */ new Map();
|
|
7905
|
-
storageUpdates.set(
|
|
7906
|
-
this._id,
|
|
7907
|
-
makeUpdate(this, [setDelta(index, value)], LOCAL_EDIT)
|
|
7908
|
-
);
|
|
7816
|
+
storageUpdates.set(this._id, makeUpdate(this, [setDelta(index, value)]));
|
|
7909
7817
|
const ops = addIntentToRootOp(
|
|
7910
7818
|
value._toOpsWithOpId(this._id, position, this._pool),
|
|
7911
7819
|
"set",
|
|
@@ -8078,12 +7986,11 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
8078
7986
|
);
|
|
8079
7987
|
}
|
|
8080
7988
|
};
|
|
8081
|
-
function makeUpdate(liveList, deltaUpdates
|
|
7989
|
+
function makeUpdate(liveList, deltaUpdates) {
|
|
8082
7990
|
return {
|
|
8083
7991
|
node: liveList,
|
|
8084
7992
|
type: "LiveList",
|
|
8085
|
-
updates: deltaUpdates
|
|
8086
|
-
source
|
|
7993
|
+
updates: deltaUpdates
|
|
8087
7994
|
};
|
|
8088
7995
|
}
|
|
8089
7996
|
function setDelta(index, item) {
|
|
@@ -8202,9 +8109,7 @@ var LiveMap = class _LiveMap extends AbstractCrdt {
|
|
|
8202
8109
|
if (this._pool.getNode(id) !== void 0) {
|
|
8203
8110
|
return { modified: false };
|
|
8204
8111
|
}
|
|
8205
|
-
if (source
|
|
8206
|
-
this.#unacknowledgedSet.delete(key);
|
|
8207
|
-
} else if (!source.optimistic) {
|
|
8112
|
+
if (source === 2 /* OURS */) {
|
|
8208
8113
|
const lastUpdateOpId = this.#unacknowledgedSet.get(key);
|
|
8209
8114
|
if (lastUpdateOpId === opId) {
|
|
8210
8115
|
this.#unacknowledgedSet.delete(key);
|
|
@@ -8212,6 +8117,8 @@ var LiveMap = class _LiveMap extends AbstractCrdt {
|
|
|
8212
8117
|
} else if (lastUpdateOpId !== void 0) {
|
|
8213
8118
|
return { modified: false };
|
|
8214
8119
|
}
|
|
8120
|
+
} else if (source === 1 /* THEIRS */) {
|
|
8121
|
+
this.#unacknowledgedSet.delete(key);
|
|
8215
8122
|
}
|
|
8216
8123
|
const previousValue = this.#map.get(key);
|
|
8217
8124
|
let reverse;
|
|
@@ -8230,8 +8137,7 @@ var LiveMap = class _LiveMap extends AbstractCrdt {
|
|
|
8230
8137
|
modified: {
|
|
8231
8138
|
node: this,
|
|
8232
8139
|
type: "LiveMap",
|
|
8233
|
-
updates: { [key]: { type: "update" } }
|
|
8234
|
-
source: toUpdateSource(source)
|
|
8140
|
+
updates: { [key]: { type: "update" } }
|
|
8235
8141
|
},
|
|
8236
8142
|
reverse
|
|
8237
8143
|
};
|
|
@@ -8244,7 +8150,7 @@ var LiveMap = class _LiveMap extends AbstractCrdt {
|
|
|
8244
8150
|
}
|
|
8245
8151
|
}
|
|
8246
8152
|
/** @internal */
|
|
8247
|
-
_detachChild(child
|
|
8153
|
+
_detachChild(child) {
|
|
8248
8154
|
const id = nn(this._id);
|
|
8249
8155
|
const parentKey = nn(child._parentKey);
|
|
8250
8156
|
const reverse = child._toOps(id, parentKey);
|
|
@@ -8263,8 +8169,7 @@ var LiveMap = class _LiveMap extends AbstractCrdt {
|
|
|
8263
8169
|
type: "delete",
|
|
8264
8170
|
deletedItem: liveNodeToLson(child)
|
|
8265
8171
|
}
|
|
8266
|
-
}
|
|
8267
|
-
source
|
|
8172
|
+
}
|
|
8268
8173
|
};
|
|
8269
8174
|
return { modified: storageUpdate, reverse };
|
|
8270
8175
|
}
|
|
@@ -8313,8 +8218,7 @@ var LiveMap = class _LiveMap extends AbstractCrdt {
|
|
|
8313
8218
|
storageUpdates.set(this._id, {
|
|
8314
8219
|
node: this,
|
|
8315
8220
|
type: "LiveMap",
|
|
8316
|
-
updates: { [key]: { type: "update" } }
|
|
8317
|
-
source: LOCAL_EDIT
|
|
8221
|
+
updates: { [key]: { type: "update" } }
|
|
8318
8222
|
});
|
|
8319
8223
|
const ops = item._toOpsWithOpId(this._id, key, this._pool);
|
|
8320
8224
|
this.#unacknowledgedSet.set(key, nn(ops[0].opId));
|
|
@@ -8363,8 +8267,7 @@ var LiveMap = class _LiveMap extends AbstractCrdt {
|
|
|
8363
8267
|
type: "delete",
|
|
8364
8268
|
deletedItem: liveNodeToLson(item)
|
|
8365
8269
|
}
|
|
8366
|
-
}
|
|
8367
|
-
source: LOCAL_EDIT
|
|
8270
|
+
}
|
|
8368
8271
|
});
|
|
8369
8272
|
this._pool.dispatch(
|
|
8370
8273
|
[
|
|
@@ -8729,7 +8632,7 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
|
|
|
8729
8632
|
}
|
|
8730
8633
|
return { modified: false };
|
|
8731
8634
|
}
|
|
8732
|
-
if (source
|
|
8635
|
+
if (source === 0 /* LOCAL */) {
|
|
8733
8636
|
this.#unackedOpsByKey.set(key, nn(opId));
|
|
8734
8637
|
} else if (this.#unackedOpsByKey.get(key) === void 0) {
|
|
8735
8638
|
} else if (this.#unackedOpsByKey.get(key) === opId) {
|
|
@@ -8767,13 +8670,12 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
|
|
|
8767
8670
|
modified: {
|
|
8768
8671
|
node: this,
|
|
8769
8672
|
type: "LiveObject",
|
|
8770
|
-
updates: { [key]: { type: "update" } }
|
|
8771
|
-
source: toUpdateSource(source)
|
|
8673
|
+
updates: { [key]: { type: "update" } }
|
|
8772
8674
|
}
|
|
8773
8675
|
};
|
|
8774
8676
|
}
|
|
8775
8677
|
/** @internal */
|
|
8776
|
-
_detachChild(child
|
|
8678
|
+
_detachChild(child) {
|
|
8777
8679
|
if (child) {
|
|
8778
8680
|
const id = nn(this._id);
|
|
8779
8681
|
const parentKey = nn(child._parentKey);
|
|
@@ -8791,8 +8693,7 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
|
|
|
8791
8693
|
type: "LiveObject",
|
|
8792
8694
|
updates: {
|
|
8793
8695
|
[parentKey]: { type: "delete", deletedItem }
|
|
8794
|
-
}
|
|
8795
|
-
source
|
|
8696
|
+
}
|
|
8796
8697
|
};
|
|
8797
8698
|
return { modified: storageUpdate, reverse };
|
|
8798
8699
|
}
|
|
@@ -8808,13 +8709,13 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
|
|
|
8808
8709
|
}
|
|
8809
8710
|
}
|
|
8810
8711
|
/** @internal */
|
|
8811
|
-
_apply(op,
|
|
8712
|
+
_apply(op, isLocal) {
|
|
8812
8713
|
if (op.type === OpCode.UPDATE_OBJECT) {
|
|
8813
|
-
return this.#applyUpdate(op,
|
|
8714
|
+
return this.#applyUpdate(op, isLocal);
|
|
8814
8715
|
} else if (op.type === OpCode.DELETE_OBJECT_KEY) {
|
|
8815
|
-
return this.#applyDeleteObjectKey(op,
|
|
8716
|
+
return this.#applyDeleteObjectKey(op, isLocal);
|
|
8816
8717
|
}
|
|
8817
|
-
return super._apply(op,
|
|
8718
|
+
return super._apply(op, isLocal);
|
|
8818
8719
|
}
|
|
8819
8720
|
/** @internal */
|
|
8820
8721
|
_serialize() {
|
|
@@ -8838,7 +8739,7 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
|
|
|
8838
8739
|
};
|
|
8839
8740
|
}
|
|
8840
8741
|
}
|
|
8841
|
-
#applyUpdate(op,
|
|
8742
|
+
#applyUpdate(op, isLocal) {
|
|
8842
8743
|
let isModified = false;
|
|
8843
8744
|
const id = nn(this._id);
|
|
8844
8745
|
const reverse = [];
|
|
@@ -8866,7 +8767,7 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
|
|
|
8866
8767
|
if (value === void 0) {
|
|
8867
8768
|
continue;
|
|
8868
8769
|
}
|
|
8869
|
-
if (
|
|
8770
|
+
if (isLocal) {
|
|
8870
8771
|
this.#unackedOpsByKey.set(key, nn(op.opId));
|
|
8871
8772
|
} else if (this.#unackedOpsByKey.get(key) === void 0) {
|
|
8872
8773
|
isModified = true;
|
|
@@ -8893,19 +8794,18 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
|
|
|
8893
8794
|
modified: {
|
|
8894
8795
|
node: this,
|
|
8895
8796
|
type: "LiveObject",
|
|
8896
|
-
updates: updateDelta
|
|
8897
|
-
source: toUpdateSource(source)
|
|
8797
|
+
updates: updateDelta
|
|
8898
8798
|
},
|
|
8899
8799
|
reverse
|
|
8900
8800
|
} : { modified: false };
|
|
8901
8801
|
}
|
|
8902
|
-
#applyDeleteObjectKey(op,
|
|
8802
|
+
#applyDeleteObjectKey(op, isLocal) {
|
|
8903
8803
|
const key = op.key;
|
|
8904
8804
|
const oldValue = this.#synced.get(key);
|
|
8905
8805
|
if (oldValue === void 0) {
|
|
8906
8806
|
return { modified: false };
|
|
8907
8807
|
}
|
|
8908
|
-
if (!
|
|
8808
|
+
if (!isLocal && this.#unackedOpsByKey.get(key) !== void 0) {
|
|
8909
8809
|
return { modified: false };
|
|
8910
8810
|
}
|
|
8911
8811
|
const id = nn(this._id);
|
|
@@ -8931,8 +8831,7 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
|
|
|
8931
8831
|
type: "LiveObject",
|
|
8932
8832
|
updates: {
|
|
8933
8833
|
[op.key]: { type: "delete", deletedItem: oldValue }
|
|
8934
|
-
}
|
|
8935
|
-
source: toUpdateSource(source)
|
|
8834
|
+
}
|
|
8936
8835
|
},
|
|
8937
8836
|
reverse
|
|
8938
8837
|
};
|
|
@@ -8978,8 +8877,7 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
|
|
|
8978
8877
|
updates: {
|
|
8979
8878
|
..._optionalChain([existing, 'optionalAccess', _228 => _228.updates]),
|
|
8980
8879
|
[key]: { type: "update" }
|
|
8981
|
-
}
|
|
8982
|
-
source: LOCAL_EDIT
|
|
8880
|
+
}
|
|
8983
8881
|
});
|
|
8984
8882
|
this._pool.dispatch(ops, reverse, storageUpdates);
|
|
8985
8883
|
}
|
|
@@ -9013,8 +8911,7 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
|
|
|
9013
8911
|
type: "delete",
|
|
9014
8912
|
deletedItem: oldValue2
|
|
9015
8913
|
}
|
|
9016
|
-
}
|
|
9017
|
-
source: LOCAL_EDIT
|
|
8914
|
+
}
|
|
9018
8915
|
});
|
|
9019
8916
|
return [[], [], storageUpdates2];
|
|
9020
8917
|
}
|
|
@@ -9062,8 +8959,7 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
|
|
|
9062
8959
|
type: "LiveObject",
|
|
9063
8960
|
updates: {
|
|
9064
8961
|
[key]: { type: "delete", deletedItem: oldValue }
|
|
9065
|
-
}
|
|
9066
|
-
source: LOCAL_EDIT
|
|
8962
|
+
}
|
|
9067
8963
|
});
|
|
9068
8964
|
return [ops, reverse, storageUpdates];
|
|
9069
8965
|
}
|
|
@@ -9201,8 +9097,7 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
|
|
|
9201
9097
|
storageUpdates.set(this._id, {
|
|
9202
9098
|
node: this,
|
|
9203
9099
|
type: "LiveObject",
|
|
9204
|
-
updates: updateDelta
|
|
9205
|
-
source: LOCAL_EDIT
|
|
9100
|
+
updates: updateDelta
|
|
9206
9101
|
});
|
|
9207
9102
|
this._pool.dispatch(ops, reverseOps, storageUpdates);
|
|
9208
9103
|
}
|
|
@@ -9284,1352 +9179,172 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
|
|
|
9284
9179
|
}
|
|
9285
9180
|
}, _class2.__initStatic(), _class2);
|
|
9286
9181
|
|
|
9287
|
-
// src/crdts/
|
|
9288
|
-
function
|
|
9289
|
-
|
|
9290
|
-
|
|
9182
|
+
// src/crdts/liveblocks-helpers.ts
|
|
9183
|
+
function creationOpToLiveNode(op) {
|
|
9184
|
+
return lsonToLiveNode(creationOpToLson(op));
|
|
9185
|
+
}
|
|
9186
|
+
function creationOpToLson(op) {
|
|
9187
|
+
switch (op.type) {
|
|
9188
|
+
case OpCode.CREATE_FILE:
|
|
9189
|
+
return new LiveFile(op.data);
|
|
9190
|
+
case OpCode.CREATE_REGISTER:
|
|
9191
|
+
return op.data;
|
|
9192
|
+
case OpCode.CREATE_OBJECT:
|
|
9193
|
+
return new LiveObject(op.data);
|
|
9194
|
+
case OpCode.CREATE_MAP:
|
|
9195
|
+
return new LiveMap();
|
|
9196
|
+
case OpCode.CREATE_LIST:
|
|
9197
|
+
return new LiveList([]);
|
|
9198
|
+
default:
|
|
9199
|
+
return assertNever(op, "Unknown creation Op");
|
|
9291
9200
|
}
|
|
9292
|
-
|
|
9293
|
-
|
|
9201
|
+
}
|
|
9202
|
+
function isSameNodeOrChildOf(node, parent) {
|
|
9203
|
+
if (node === parent) {
|
|
9204
|
+
return true;
|
|
9294
9205
|
}
|
|
9295
|
-
|
|
9296
|
-
|
|
9297
|
-
if (leftKeys.length !== rightKeys.length) {
|
|
9298
|
-
return false;
|
|
9206
|
+
if (node.parent.type === "HasParent") {
|
|
9207
|
+
return isSameNodeOrChildOf(node.parent.node, parent);
|
|
9299
9208
|
}
|
|
9300
|
-
|
|
9301
|
-
|
|
9302
|
-
|
|
9209
|
+
return false;
|
|
9210
|
+
}
|
|
9211
|
+
function liveObjectFromNodeStream(nodes) {
|
|
9212
|
+
const pool = createManagedPool({
|
|
9213
|
+
getCurrentConnectionId: () => {
|
|
9214
|
+
throw new Error(
|
|
9215
|
+
"Cannot mutate a historic storage version: it is a read-only snapshot"
|
|
9216
|
+
);
|
|
9303
9217
|
}
|
|
9304
|
-
}
|
|
9305
|
-
return
|
|
9218
|
+
});
|
|
9219
|
+
return LiveObject._fromItems(nodes, pool);
|
|
9306
9220
|
}
|
|
9307
|
-
function
|
|
9308
|
-
|
|
9221
|
+
function deserialize(node, parentToChildren, pool) {
|
|
9222
|
+
if (isObjectStorageNode(node)) {
|
|
9223
|
+
return LiveObject._deserialize(node, parentToChildren, pool);
|
|
9224
|
+
} else if (isListStorageNode(node)) {
|
|
9225
|
+
return LiveList._deserialize(node, parentToChildren, pool);
|
|
9226
|
+
} else if (isMapStorageNode(node)) {
|
|
9227
|
+
return LiveMap._deserialize(node, parentToChildren, pool);
|
|
9228
|
+
} else if (isRegisterStorageNode(node)) {
|
|
9229
|
+
return LiveRegister._deserialize(node, parentToChildren, pool);
|
|
9230
|
+
} else if (isFileStorageNode(node)) {
|
|
9231
|
+
return LiveFile._deserialize(node, parentToChildren, pool);
|
|
9232
|
+
} else {
|
|
9233
|
+
throw new Error("Unexpected CRDT type");
|
|
9234
|
+
}
|
|
9309
9235
|
}
|
|
9310
|
-
function
|
|
9311
|
-
|
|
9312
|
-
|
|
9313
|
-
|
|
9314
|
-
|
|
9315
|
-
|
|
9316
|
-
|
|
9317
|
-
|
|
9318
|
-
|
|
9319
|
-
|
|
9320
|
-
|
|
9321
|
-
|
|
9322
|
-
|
|
9236
|
+
function deserializeToLson(node, parentToChildren, pool) {
|
|
9237
|
+
if (isObjectStorageNode(node)) {
|
|
9238
|
+
return LiveObject._deserialize(node, parentToChildren, pool);
|
|
9239
|
+
} else if (isListStorageNode(node)) {
|
|
9240
|
+
return LiveList._deserialize(node, parentToChildren, pool);
|
|
9241
|
+
} else if (isMapStorageNode(node)) {
|
|
9242
|
+
return LiveMap._deserialize(node, parentToChildren, pool);
|
|
9243
|
+
} else if (isRegisterStorageNode(node)) {
|
|
9244
|
+
return node[1].data;
|
|
9245
|
+
} else if (isFileStorageNode(node)) {
|
|
9246
|
+
return LiveFile._deserialize(node, parentToChildren, pool);
|
|
9247
|
+
} else {
|
|
9248
|
+
throw new Error("Unexpected CRDT type");
|
|
9323
9249
|
}
|
|
9324
|
-
return normalized;
|
|
9325
9250
|
}
|
|
9326
|
-
function
|
|
9327
|
-
return
|
|
9328
|
-
data.map(([text, attributes]) => ({
|
|
9329
|
-
text,
|
|
9330
|
-
attributes
|
|
9331
|
-
}))
|
|
9332
|
-
);
|
|
9251
|
+
function isLiveStructure(value) {
|
|
9252
|
+
return isLiveList(value) || isLiveMap(value) || isLiveObject(value) || isLiveFile(value);
|
|
9333
9253
|
}
|
|
9334
|
-
function
|
|
9335
|
-
return
|
|
9336
|
-
(segment) => segment.attributes === void 0 ? [segment.text] : [segment.text, { ...segment.attributes }]
|
|
9337
|
-
);
|
|
9254
|
+
function isLiveNode(value) {
|
|
9255
|
+
return isLiveStructure(value) || isLiveRegister(value);
|
|
9338
9256
|
}
|
|
9339
|
-
function
|
|
9340
|
-
return
|
|
9257
|
+
function isLiveList(value) {
|
|
9258
|
+
return value instanceof LiveList;
|
|
9341
9259
|
}
|
|
9342
|
-
function
|
|
9343
|
-
|
|
9344
|
-
let offset = 0;
|
|
9345
|
-
for (const segment of segments) {
|
|
9346
|
-
const end = offset + segment.text.length;
|
|
9347
|
-
if (index > offset && index < end) {
|
|
9348
|
-
const before2 = segment.text.slice(0, index - offset);
|
|
9349
|
-
const after2 = segment.text.slice(index - offset);
|
|
9350
|
-
result.push({ text: before2, attributes: segment.attributes });
|
|
9351
|
-
result.push({ text: after2, attributes: segment.attributes });
|
|
9352
|
-
} else {
|
|
9353
|
-
result.push({ text: segment.text, attributes: segment.attributes });
|
|
9354
|
-
}
|
|
9355
|
-
offset = end;
|
|
9356
|
-
}
|
|
9357
|
-
return result;
|
|
9260
|
+
function isLiveMap(value) {
|
|
9261
|
+
return value instanceof LiveMap;
|
|
9358
9262
|
}
|
|
9359
|
-
function
|
|
9360
|
-
|
|
9361
|
-
const clippedEnd = Math.max(
|
|
9362
|
-
clippedIndex,
|
|
9363
|
-
Math.min(index + length, contentLength)
|
|
9364
|
-
);
|
|
9365
|
-
return { index: clippedIndex, length: clippedEnd - clippedIndex };
|
|
9263
|
+
function isLiveObject(value) {
|
|
9264
|
+
return value instanceof LiveObject;
|
|
9366
9265
|
}
|
|
9367
|
-
function
|
|
9368
|
-
|
|
9369
|
-
const next = text.charCodeAt(index);
|
|
9370
|
-
return previous >= 55296 && previous <= 56319 && next >= 56320 && next <= 57343;
|
|
9266
|
+
function isLiveFile(value) {
|
|
9267
|
+
return value instanceof LiveFile;
|
|
9371
9268
|
}
|
|
9372
|
-
function
|
|
9373
|
-
|
|
9374
|
-
return isInSurrogatePair(text, clippedIndex) ? clippedIndex - 1 : clippedIndex;
|
|
9269
|
+
function isLiveRegister(value) {
|
|
9270
|
+
return value instanceof LiveRegister;
|
|
9375
9271
|
}
|
|
9376
|
-
function
|
|
9377
|
-
|
|
9378
|
-
if (clipped.length === 0) {
|
|
9379
|
-
return {
|
|
9380
|
-
index: clipIndexToCodePointBoundary(text, clipped.index),
|
|
9381
|
-
length: 0
|
|
9382
|
-
};
|
|
9383
|
-
}
|
|
9384
|
-
const clippedEnd = clipped.index + clipped.length;
|
|
9385
|
-
const normalizedIndex = isInSurrogatePair(text, clipped.index) ? clipped.index - 1 : clipped.index;
|
|
9386
|
-
const normalizedEnd = isInSurrogatePair(text, clippedEnd) ? clippedEnd + 1 : clippedEnd;
|
|
9387
|
-
return {
|
|
9388
|
-
index: normalizedIndex,
|
|
9389
|
-
length: normalizedEnd - normalizedIndex
|
|
9390
|
-
};
|
|
9272
|
+
function cloneLson(value) {
|
|
9273
|
+
return value === void 0 ? void 0 : isLiveStructure(value) ? value.clone() : deepClone(value);
|
|
9391
9274
|
}
|
|
9392
|
-
function
|
|
9393
|
-
if (
|
|
9394
|
-
return
|
|
9395
|
-
}
|
|
9396
|
-
|
|
9397
|
-
|
|
9398
|
-
|
|
9399
|
-
let inserted = false;
|
|
9400
|
-
for (const segment of split) {
|
|
9401
|
-
if (!inserted && offset === index) {
|
|
9402
|
-
result.push({ text, attributes });
|
|
9403
|
-
inserted = true;
|
|
9404
|
-
}
|
|
9405
|
-
result.push(segment);
|
|
9406
|
-
offset += segment.text.length;
|
|
9407
|
-
}
|
|
9408
|
-
if (!inserted) {
|
|
9409
|
-
result.push({ text, attributes });
|
|
9275
|
+
function liveNodeToLson(obj) {
|
|
9276
|
+
if (obj instanceof LiveRegister) {
|
|
9277
|
+
return obj.data;
|
|
9278
|
+
} else if (obj instanceof LiveList || obj instanceof LiveMap || obj instanceof LiveObject || obj instanceof LiveFile) {
|
|
9279
|
+
return obj;
|
|
9280
|
+
} else {
|
|
9281
|
+
return assertNever(obj, "Unknown AbstractCrdt");
|
|
9410
9282
|
}
|
|
9411
|
-
return normalizeSegments(result);
|
|
9412
9283
|
}
|
|
9413
|
-
function
|
|
9414
|
-
|
|
9415
|
-
|
|
9416
|
-
|
|
9417
|
-
|
|
9418
|
-
const deleted = [];
|
|
9419
|
-
let offset = 0;
|
|
9420
|
-
for (const segment of split) {
|
|
9421
|
-
const end = offset + segment.text.length;
|
|
9422
|
-
if (offset >= index && end <= index + length) {
|
|
9423
|
-
deleted.push({
|
|
9424
|
-
text: segment.text,
|
|
9425
|
-
attributes: segment.attributes
|
|
9426
|
-
});
|
|
9427
|
-
}
|
|
9428
|
-
offset = end;
|
|
9284
|
+
function lsonToLiveNode(value) {
|
|
9285
|
+
if (value instanceof LiveObject || value instanceof LiveMap || value instanceof LiveList || value instanceof LiveFile) {
|
|
9286
|
+
return value;
|
|
9287
|
+
} else {
|
|
9288
|
+
return new LiveRegister(value);
|
|
9429
9289
|
}
|
|
9430
|
-
return normalizeSegments(deleted);
|
|
9431
9290
|
}
|
|
9432
|
-
function
|
|
9433
|
-
const
|
|
9434
|
-
|
|
9435
|
-
|
|
9436
|
-
|
|
9437
|
-
|
|
9438
|
-
|
|
9439
|
-
|
|
9440
|
-
|
|
9441
|
-
|
|
9442
|
-
|
|
9443
|
-
if (
|
|
9444
|
-
|
|
9291
|
+
function dumpPool(pool) {
|
|
9292
|
+
const rows = Array.from(pool.nodes.values(), (node) => {
|
|
9293
|
+
const parent = node.parent;
|
|
9294
|
+
const parentId = parent.type === "HasParent" ? _nullishCoalesce(parent.node._id, () => ( "?")) : parent.type === "Orphaned" ? "<orphaned>" : "-";
|
|
9295
|
+
let value;
|
|
9296
|
+
if (node instanceof LiveRegister) {
|
|
9297
|
+
value = stringifyOrLog(node.data);
|
|
9298
|
+
} else if (node instanceof LiveList) {
|
|
9299
|
+
value = "<LiveList>";
|
|
9300
|
+
} else if (node instanceof LiveMap) {
|
|
9301
|
+
value = "<LiveMap>";
|
|
9302
|
+
} else if (node instanceof LiveFile) {
|
|
9303
|
+
value = stringifyOrLog(node.data);
|
|
9445
9304
|
} else {
|
|
9446
|
-
|
|
9305
|
+
value = "<LiveObject>";
|
|
9447
9306
|
}
|
|
9448
|
-
|
|
9449
|
-
}
|
|
9450
|
-
|
|
9451
|
-
|
|
9452
|
-
|
|
9453
|
-
|
|
9454
|
-
};
|
|
9307
|
+
return { id: nn(node._id), parentId, key: _nullishCoalesce(node._parentKey, () => ( "")), value };
|
|
9308
|
+
});
|
|
9309
|
+
rows.sort((a, b) => {
|
|
9310
|
+
if (a.parentId !== b.parentId) return a.parentId < b.parentId ? -1 : 1;
|
|
9311
|
+
if (a.key !== b.key) return a.key < b.key ? -1 : 1;
|
|
9312
|
+
return 0;
|
|
9313
|
+
});
|
|
9314
|
+
return rows.map(
|
|
9315
|
+
(r) => ` ${r.id} parent=${r.parentId} key=${r.key || "\u2014"} ${r.value}`
|
|
9316
|
+
).join("\n");
|
|
9455
9317
|
}
|
|
9456
|
-
function
|
|
9457
|
-
|
|
9458
|
-
|
|
9459
|
-
index + length
|
|
9460
|
-
);
|
|
9461
|
-
const result = [];
|
|
9462
|
-
let offset = 0;
|
|
9463
|
-
for (const segment of split) {
|
|
9464
|
-
const end = offset + segment.text.length;
|
|
9465
|
-
if (offset >= index && end <= index + length) {
|
|
9466
|
-
const nextAttributes = {
|
|
9467
|
-
..._nullishCoalesce(segment.attributes, () => ( {}))
|
|
9468
|
-
};
|
|
9469
|
-
for (const [key, value] of Object.entries(attributes)) {
|
|
9470
|
-
if (value === null) {
|
|
9471
|
-
delete nextAttributes[key];
|
|
9472
|
-
} else {
|
|
9473
|
-
nextAttributes[key] = value;
|
|
9474
|
-
}
|
|
9475
|
-
}
|
|
9476
|
-
result.push({
|
|
9477
|
-
text: segment.text,
|
|
9478
|
-
attributes: Object.keys(nextAttributes).length === 0 ? void 0 : freeze(nextAttributes)
|
|
9479
|
-
});
|
|
9480
|
-
} else {
|
|
9481
|
-
result.push(segment);
|
|
9482
|
-
}
|
|
9483
|
-
offset = end;
|
|
9318
|
+
function isJsonEq(a, b) {
|
|
9319
|
+
if (a === b) {
|
|
9320
|
+
return true;
|
|
9484
9321
|
}
|
|
9485
|
-
|
|
9486
|
-
|
|
9487
|
-
function formatReverseOperations(segments, index, length, patch) {
|
|
9488
|
-
const split = splitSegmentsAt(
|
|
9489
|
-
splitSegmentsAt(segments, index),
|
|
9490
|
-
index + length
|
|
9491
|
-
);
|
|
9492
|
-
const result = [];
|
|
9493
|
-
let offset = 0;
|
|
9494
|
-
for (const segment of split) {
|
|
9495
|
-
const end = offset + segment.text.length;
|
|
9496
|
-
if (offset >= index && end <= index + length) {
|
|
9497
|
-
const attributes = {};
|
|
9498
|
-
const current = _nullishCoalesce(segment.attributes, () => ( {}));
|
|
9499
|
-
for (const key of Object.keys(patch)) {
|
|
9500
|
-
const value = Object.hasOwn(current, key) ? current[key] : void 0;
|
|
9501
|
-
attributes[key] = _nullishCoalesce(value, () => ( null));
|
|
9502
|
-
}
|
|
9503
|
-
result.push({
|
|
9504
|
-
type: "format",
|
|
9505
|
-
index: offset,
|
|
9506
|
-
length: segment.text.length,
|
|
9507
|
-
attributes
|
|
9508
|
-
});
|
|
9509
|
-
}
|
|
9510
|
-
offset = end;
|
|
9322
|
+
if (typeof a !== "object" || a === null || typeof b !== "object" || b === null) {
|
|
9323
|
+
return false;
|
|
9511
9324
|
}
|
|
9512
|
-
|
|
9513
|
-
|
|
9514
|
-
|
|
9515
|
-
if (op.type === "insert") {
|
|
9516
|
-
return op.index <= index ? index + op.text.length : index;
|
|
9517
|
-
} else if (op.type === "delete") {
|
|
9518
|
-
if (op.index >= index) {
|
|
9519
|
-
return index;
|
|
9325
|
+
if (Array.isArray(a) || Array.isArray(b)) {
|
|
9326
|
+
if (!Array.isArray(a) || !Array.isArray(b) || a.length !== b.length) {
|
|
9327
|
+
return false;
|
|
9520
9328
|
}
|
|
9521
|
-
|
|
9522
|
-
|
|
9523
|
-
|
|
9329
|
+
for (let i = 0; i < a.length; i++) {
|
|
9330
|
+
if (!isJsonEq(a[i], b[i])) {
|
|
9331
|
+
return false;
|
|
9332
|
+
}
|
|
9333
|
+
}
|
|
9334
|
+
return true;
|
|
9524
9335
|
}
|
|
9525
|
-
|
|
9526
|
-
|
|
9527
|
-
|
|
9528
|
-
for (const op of ops) {
|
|
9529
|
-
mapped = mapIndexThroughOperation(mapped, op);
|
|
9336
|
+
const aKeys = Object.keys(a);
|
|
9337
|
+
if (aKeys.length !== Object.keys(b).length) {
|
|
9338
|
+
return false;
|
|
9530
9339
|
}
|
|
9531
|
-
|
|
9532
|
-
|
|
9533
|
-
|
|
9534
|
-
if (op.type === "insert") {
|
|
9535
|
-
if (index <= op.index) {
|
|
9536
|
-
return index;
|
|
9340
|
+
for (const key of aKeys) {
|
|
9341
|
+
if (!isJsonEq(a[key], b[key])) {
|
|
9342
|
+
return false;
|
|
9537
9343
|
}
|
|
9538
|
-
return Math.max(op.index, index - op.text.length);
|
|
9539
|
-
} else if (op.type === "delete") {
|
|
9540
|
-
return op.index <= index ? index + op.length : index;
|
|
9541
|
-
} else {
|
|
9542
|
-
return index;
|
|
9543
|
-
}
|
|
9544
|
-
}
|
|
9545
|
-
function inverseMapTextIndexThroughOperations(index, ops) {
|
|
9546
|
-
let mapped = index;
|
|
9547
|
-
for (let i = ops.length - 1; i >= 0; i--) {
|
|
9548
|
-
mapped = inverseMapIndexThroughOperation(mapped, ops[i]);
|
|
9549
9344
|
}
|
|
9550
|
-
return
|
|
9551
|
-
}
|
|
9552
|
-
function oppositeOrder(order) {
|
|
9553
|
-
return order === "before" ? "after" : "before";
|
|
9345
|
+
return true;
|
|
9554
9346
|
}
|
|
9555
|
-
function
|
|
9556
|
-
if (deleteIndex >= index) {
|
|
9557
|
-
return index;
|
|
9558
|
-
}
|
|
9559
|
-
return Math.max(deleteIndex, index - deleteLength);
|
|
9560
|
-
}
|
|
9561
|
-
function transformInsert(op, over, order) {
|
|
9562
|
-
if (over.type === "insert") {
|
|
9563
|
-
const shifts = over.index < op.index || over.index === op.index && order === "after";
|
|
9564
|
-
return [shifts ? { ...op, index: op.index + over.text.length } : { ...op }];
|
|
9565
|
-
} else if (over.type === "delete") {
|
|
9566
|
-
return [
|
|
9567
|
-
{ ...op, index: mapIndexOverDelete(op.index, over.index, over.length) }
|
|
9568
|
-
];
|
|
9569
|
-
} else {
|
|
9570
|
-
return [{ ...op }];
|
|
9571
|
-
}
|
|
9572
|
-
}
|
|
9573
|
-
function transformDelete(op, over) {
|
|
9574
|
-
const start = op.index;
|
|
9575
|
-
const end = op.index + op.length;
|
|
9576
|
-
if (over.type === "insert") {
|
|
9577
|
-
const at = over.index;
|
|
9578
|
-
const len = over.text.length;
|
|
9579
|
-
if (at <= start) {
|
|
9580
|
-
return [{ ...op, index: start + len }];
|
|
9581
|
-
}
|
|
9582
|
-
if (at >= end) {
|
|
9583
|
-
return [{ ...op }];
|
|
9584
|
-
}
|
|
9585
|
-
return [
|
|
9586
|
-
{ type: "delete", index: start, length: at - start },
|
|
9587
|
-
{ type: "delete", index: start + len, length: end - at }
|
|
9588
|
-
];
|
|
9589
|
-
} else if (over.type === "delete") {
|
|
9590
|
-
const newStart = mapIndexOverDelete(start, over.index, over.length);
|
|
9591
|
-
const newEnd = mapIndexOverDelete(end, over.index, over.length);
|
|
9592
|
-
return newEnd - newStart > 0 ? [{ type: "delete", index: newStart, length: newEnd - newStart }] : [];
|
|
9593
|
-
} else {
|
|
9594
|
-
return [{ ...op }];
|
|
9595
|
-
}
|
|
9596
|
-
}
|
|
9597
|
-
function transformFormat(op, over, order) {
|
|
9598
|
-
const start = op.index;
|
|
9599
|
-
const end = op.index + op.length;
|
|
9600
|
-
if (over.type === "insert") {
|
|
9601
|
-
const at = over.index;
|
|
9602
|
-
const len = over.text.length;
|
|
9603
|
-
if (at <= start) {
|
|
9604
|
-
return [{ ...op, index: start + len }];
|
|
9605
|
-
}
|
|
9606
|
-
if (at >= end) {
|
|
9607
|
-
return [{ ...op }];
|
|
9608
|
-
}
|
|
9609
|
-
return [
|
|
9610
|
-
{
|
|
9611
|
-
type: "format",
|
|
9612
|
-
index: start,
|
|
9613
|
-
length: at - start,
|
|
9614
|
-
attributes: op.attributes
|
|
9615
|
-
},
|
|
9616
|
-
{
|
|
9617
|
-
type: "format",
|
|
9618
|
-
index: at + len,
|
|
9619
|
-
length: end - at,
|
|
9620
|
-
attributes: op.attributes
|
|
9621
|
-
}
|
|
9622
|
-
];
|
|
9623
|
-
} else if (over.type === "delete") {
|
|
9624
|
-
const newStart = mapIndexOverDelete(start, over.index, over.length);
|
|
9625
|
-
const newEnd = mapIndexOverDelete(end, over.index, over.length);
|
|
9626
|
-
return newEnd - newStart > 0 ? [
|
|
9627
|
-
{
|
|
9628
|
-
type: "format",
|
|
9629
|
-
index: newStart,
|
|
9630
|
-
length: newEnd - newStart,
|
|
9631
|
-
attributes: op.attributes
|
|
9632
|
-
}
|
|
9633
|
-
] : [];
|
|
9634
|
-
} else {
|
|
9635
|
-
if (order === "after") {
|
|
9636
|
-
return [{ ...op }];
|
|
9637
|
-
}
|
|
9638
|
-
const overlapStart = Math.max(start, over.index);
|
|
9639
|
-
const overlapEnd = Math.min(end, over.index + over.length);
|
|
9640
|
-
if (overlapStart >= overlapEnd) {
|
|
9641
|
-
return [{ ...op }];
|
|
9642
|
-
}
|
|
9643
|
-
const hasConflict = Object.keys(op.attributes).some(
|
|
9644
|
-
(key) => Object.hasOwn(over.attributes, key)
|
|
9645
|
-
);
|
|
9646
|
-
if (!hasConflict) {
|
|
9647
|
-
return [{ ...op }];
|
|
9648
|
-
}
|
|
9649
|
-
const reduced = {};
|
|
9650
|
-
for (const [key, value] of Object.entries(op.attributes)) {
|
|
9651
|
-
if (!Object.hasOwn(over.attributes, key)) {
|
|
9652
|
-
reduced[key] = value;
|
|
9653
|
-
}
|
|
9654
|
-
}
|
|
9655
|
-
const pieces = [];
|
|
9656
|
-
if (start < overlapStart) {
|
|
9657
|
-
pieces.push({
|
|
9658
|
-
type: "format",
|
|
9659
|
-
index: start,
|
|
9660
|
-
length: overlapStart - start,
|
|
9661
|
-
attributes: op.attributes
|
|
9662
|
-
});
|
|
9663
|
-
}
|
|
9664
|
-
if (Object.keys(reduced).length > 0) {
|
|
9665
|
-
pieces.push({
|
|
9666
|
-
type: "format",
|
|
9667
|
-
index: overlapStart,
|
|
9668
|
-
length: overlapEnd - overlapStart,
|
|
9669
|
-
attributes: reduced
|
|
9670
|
-
});
|
|
9671
|
-
}
|
|
9672
|
-
if (overlapEnd < end) {
|
|
9673
|
-
pieces.push({
|
|
9674
|
-
type: "format",
|
|
9675
|
-
index: overlapEnd,
|
|
9676
|
-
length: end - overlapEnd,
|
|
9677
|
-
attributes: op.attributes
|
|
9678
|
-
});
|
|
9679
|
-
}
|
|
9680
|
-
return pieces;
|
|
9681
|
-
}
|
|
9682
|
-
}
|
|
9683
|
-
function transformSingle(op, over, order) {
|
|
9684
|
-
switch (op.type) {
|
|
9685
|
-
case "insert":
|
|
9686
|
-
return transformInsert(op, over, order);
|
|
9687
|
-
case "delete":
|
|
9688
|
-
return transformDelete(op, over);
|
|
9689
|
-
case "format":
|
|
9690
|
-
return transformFormat(op, over, order);
|
|
9691
|
-
}
|
|
9692
|
-
}
|
|
9693
|
-
function transformTextOperationsX(a, b, order) {
|
|
9694
|
-
if (a.length === 0 || b.length === 0) {
|
|
9695
|
-
return [[...a], [...b]];
|
|
9696
|
-
}
|
|
9697
|
-
if (a.length === 1 && b.length === 1) {
|
|
9698
|
-
return [
|
|
9699
|
-
transformSingle(a[0], b[0], order),
|
|
9700
|
-
transformSingle(b[0], a[0], oppositeOrder(order))
|
|
9701
|
-
];
|
|
9702
|
-
}
|
|
9703
|
-
if (a.length > 1) {
|
|
9704
|
-
const [headA1, b1] = transformTextOperationsX([a[0]], b, order);
|
|
9705
|
-
const [restA1, b2] = transformTextOperationsX(a.slice(1), b1, order);
|
|
9706
|
-
return [[...headA1, ...restA1], b2];
|
|
9707
|
-
}
|
|
9708
|
-
const [a1, headB1] = transformTextOperationsX(a, [b[0]], order);
|
|
9709
|
-
const [a2, restB1] = transformTextOperationsX(a1, b.slice(1), order);
|
|
9710
|
-
return [a2, [...headB1, ...restB1]];
|
|
9711
|
-
}
|
|
9712
|
-
function transformTextOperations(ops, over, order) {
|
|
9713
|
-
return transformTextOperationsX(ops, over, order)[0];
|
|
9714
|
-
}
|
|
9715
|
-
function textOperationsEqual(a, b) {
|
|
9716
|
-
return a === b || stableStringify(a) === stableStringify(b);
|
|
9717
|
-
}
|
|
9718
|
-
function applyTextOperationsToSegments(segments, ops) {
|
|
9719
|
-
let next = [...segments];
|
|
9720
|
-
for (const op of ops) {
|
|
9721
|
-
if (op.type === "insert") {
|
|
9722
|
-
const index = Math.max(0, Math.min(op.index, textLength(next)));
|
|
9723
|
-
next = applyInsert(next, index, op.text, op.attributes);
|
|
9724
|
-
} else if (op.type === "delete") {
|
|
9725
|
-
const index = Math.max(0, Math.min(op.index, textLength(next)));
|
|
9726
|
-
const clipped = clipRange(index, op.length, textLength(next));
|
|
9727
|
-
next = applyDelete(next, clipped.index, clipped.length).segments;
|
|
9728
|
-
} else {
|
|
9729
|
-
const index = Math.max(0, Math.min(op.index, textLength(next)));
|
|
9730
|
-
const clipped = clipRange(index, op.length, textLength(next));
|
|
9731
|
-
next = applyFormat(next, clipped.index, clipped.length, op.attributes);
|
|
9732
|
-
}
|
|
9733
|
-
}
|
|
9734
|
-
return next;
|
|
9735
|
-
}
|
|
9736
|
-
function applyLiveTextOperations(data, ops) {
|
|
9737
|
-
return segmentsToData(
|
|
9738
|
-
applyTextOperationsToSegments(dataToSegments(data), ops)
|
|
9739
|
-
);
|
|
9740
|
-
}
|
|
9741
|
-
function invertTextOperations(segments, ops) {
|
|
9742
|
-
let shadow = [...segments];
|
|
9743
|
-
const reverse = [];
|
|
9744
|
-
for (const op of ops) {
|
|
9745
|
-
if (op.type === "insert") {
|
|
9746
|
-
shadow = applyInsert(shadow, op.index, op.text, op.attributes);
|
|
9747
|
-
reverse.unshift({
|
|
9748
|
-
type: "delete",
|
|
9749
|
-
index: op.index,
|
|
9750
|
-
length: op.text.length
|
|
9751
|
-
});
|
|
9752
|
-
} else if (op.type === "delete") {
|
|
9753
|
-
const deletedSegments = extractDeletedSegments(
|
|
9754
|
-
shadow,
|
|
9755
|
-
op.index,
|
|
9756
|
-
op.length
|
|
9757
|
-
);
|
|
9758
|
-
shadow = applyDelete(shadow, op.index, op.length).segments;
|
|
9759
|
-
const inserts = [];
|
|
9760
|
-
let insertIndex = op.index;
|
|
9761
|
-
for (const segment of deletedSegments) {
|
|
9762
|
-
inserts.push({
|
|
9763
|
-
type: "insert",
|
|
9764
|
-
index: insertIndex,
|
|
9765
|
-
text: segment.text,
|
|
9766
|
-
attributes: segment.attributes
|
|
9767
|
-
});
|
|
9768
|
-
insertIndex += segment.text.length;
|
|
9769
|
-
}
|
|
9770
|
-
for (let index = inserts.length - 1; index >= 0; index--) {
|
|
9771
|
-
reverse.unshift(inserts[index]);
|
|
9772
|
-
}
|
|
9773
|
-
} else {
|
|
9774
|
-
const inverse = formatReverseOperations(
|
|
9775
|
-
shadow,
|
|
9776
|
-
op.index,
|
|
9777
|
-
op.length,
|
|
9778
|
-
op.attributes
|
|
9779
|
-
);
|
|
9780
|
-
shadow = applyFormat(shadow, op.index, op.length, op.attributes);
|
|
9781
|
-
reverse.unshift(...inverse.reverse());
|
|
9782
|
-
}
|
|
9783
|
-
}
|
|
9784
|
-
return reverse;
|
|
9785
|
-
}
|
|
9786
|
-
|
|
9787
|
-
// src/crdts/LiveText.ts
|
|
9788
|
-
var ACCEPTED_OPS_HISTORY_LIMIT = 1e3;
|
|
9789
|
-
var LiveText = class _LiveText extends AbstractCrdt {
|
|
9790
|
-
/** The local document: #confirmed ⊕ #inFlightOps ⊕ #queuedOps. */
|
|
9791
|
-
#segments;
|
|
9792
|
-
/** The server-confirmed document (only authoritative ops applied). */
|
|
9793
|
-
#confirmed;
|
|
9794
|
-
#version;
|
|
9795
|
-
/** The op currently awaiting server acknowledgement (at most one). */
|
|
9796
|
-
#inFlightOpId;
|
|
9797
|
-
/** Its ops, continuously re-expressed against current server state. */
|
|
9798
|
-
#inFlightOps = [];
|
|
9799
|
-
/** Local edits made while an op is in flight; sent after the ack. */
|
|
9800
|
-
#queuedOps = [];
|
|
9801
|
-
#acceptedOps = [];
|
|
9802
|
-
/**
|
|
9803
|
-
* Creates a new LiveText document.
|
|
9804
|
-
*
|
|
9805
|
-
* @param textOrData Initial plain text, or an array of `[text]` /
|
|
9806
|
-
* `[text, attributes]` segments. Defaults to an empty document.
|
|
9807
|
-
*
|
|
9808
|
-
* @example
|
|
9809
|
-
* new LiveText();
|
|
9810
|
-
* new LiveText("Hello world");
|
|
9811
|
-
* new LiveText([["Hello ", { bold: true }], ["world"]]);
|
|
9812
|
-
*/
|
|
9813
|
-
constructor(textOrData = "", version = 0) {
|
|
9814
|
-
super();
|
|
9815
|
-
this.#segments = typeof textOrData === "string" ? textOrData.length === 0 ? [] : [{ text: textOrData }] : dataToSegments(textOrData);
|
|
9816
|
-
this.#confirmed = [...this.#segments];
|
|
9817
|
-
this.#version = version;
|
|
9818
|
-
Object.assign(this[kInternal], {
|
|
9819
|
-
encodeIndex: (localIndex) => this.#encodeIndex(localIndex),
|
|
9820
|
-
decodeIndex: (index, fromVersion) => this.#decodeIndex(index, fromVersion)
|
|
9821
|
-
});
|
|
9822
|
-
}
|
|
9823
|
-
get version() {
|
|
9824
|
-
return this.#version;
|
|
9825
|
-
}
|
|
9826
|
-
get length() {
|
|
9827
|
-
return textLength(this.#segments);
|
|
9828
|
-
}
|
|
9829
|
-
/** @internal */
|
|
9830
|
-
static _deserialize([id, item], _parentToChildren, pool) {
|
|
9831
|
-
const text = new _LiveText(item.data, item.version);
|
|
9832
|
-
text._attach(id, pool);
|
|
9833
|
-
return text;
|
|
9834
|
-
}
|
|
9835
|
-
/** @internal */
|
|
9836
|
-
_toOps(parentId, parentKey) {
|
|
9837
|
-
if (this._id === void 0) {
|
|
9838
|
-
throw new Error("Cannot serialize LiveText if it is not attached");
|
|
9839
|
-
}
|
|
9840
|
-
return [
|
|
9841
|
-
{
|
|
9842
|
-
type: OpCode.CREATE_TEXT,
|
|
9843
|
-
id: this._id,
|
|
9844
|
-
parentId,
|
|
9845
|
-
parentKey,
|
|
9846
|
-
data: this.toJSON(),
|
|
9847
|
-
version: this.#version
|
|
9848
|
-
}
|
|
9849
|
-
];
|
|
9850
|
-
}
|
|
9851
|
-
/** @internal */
|
|
9852
|
-
_serialize() {
|
|
9853
|
-
if (this.parent.type !== "HasParent") {
|
|
9854
|
-
throw new Error("Cannot serialize LiveText if parent is missing");
|
|
9855
|
-
}
|
|
9856
|
-
return {
|
|
9857
|
-
type: CrdtType.TEXT,
|
|
9858
|
-
parentId: nn(this.parent.node._id, "Parent node expected to have ID"),
|
|
9859
|
-
parentKey: this.parent.key,
|
|
9860
|
-
data: this.toJSON(),
|
|
9861
|
-
version: this.#version
|
|
9862
|
-
};
|
|
9863
|
-
}
|
|
9864
|
-
/** @internal */
|
|
9865
|
-
_attachChild(_op) {
|
|
9866
|
-
throw new Error("LiveText cannot contain child nodes");
|
|
9867
|
-
}
|
|
9868
|
-
/** @internal */
|
|
9869
|
-
_detachChild(_crdt) {
|
|
9870
|
-
throw new Error("LiveText cannot contain child nodes");
|
|
9871
|
-
}
|
|
9872
|
-
/** @internal */
|
|
9873
|
-
_apply(op, source) {
|
|
9874
|
-
if (op.type !== OpCode.UPDATE_TEXT) {
|
|
9875
|
-
return super._apply(op, source);
|
|
9876
|
-
}
|
|
9877
|
-
if (source.origin === "local" && source.optimistic) {
|
|
9878
|
-
return this.#applyLocal(op, toUpdateSource(source));
|
|
9879
|
-
}
|
|
9880
|
-
if (op.opId !== void 0 && op.opId === this.#inFlightOpId) {
|
|
9881
|
-
return this.#applyAck(op, toUpdateSource(source));
|
|
9882
|
-
}
|
|
9883
|
-
if (op.opId !== void 0 && this.#acceptedOps.some((entry) => entry.opId === op.opId)) {
|
|
9884
|
-
this.#version = Math.max(this.#version, _nullishCoalesce(op.version, () => ( op.baseVersion + 1)));
|
|
9885
|
-
return { modified: false };
|
|
9886
|
-
}
|
|
9887
|
-
return this.#applyRemote(op, toUpdateSource(source));
|
|
9888
|
-
}
|
|
9889
|
-
/**
|
|
9890
|
-
* Inserts text at the given index.
|
|
9891
|
-
*
|
|
9892
|
-
* @param index Character index at which to insert. Values outside the
|
|
9893
|
-
* document range are clipped.
|
|
9894
|
-
* @param text Text to insert.
|
|
9895
|
-
* @param attributes Optional inline attributes for the inserted text.
|
|
9896
|
-
*
|
|
9897
|
-
* @example
|
|
9898
|
-
* const text = new LiveText("Hello");
|
|
9899
|
-
* text.insert(5, " world");
|
|
9900
|
-
* text.insert(0, "Say: ", { italic: true });
|
|
9901
|
-
*/
|
|
9902
|
-
insert(index, text, attributes) {
|
|
9903
|
-
const clippedIndex = clipIndexToCodePointBoundary(this.toString(), index);
|
|
9904
|
-
this.#dispatch([{ type: "insert", index: clippedIndex, text, attributes }]);
|
|
9905
|
-
}
|
|
9906
|
-
/**
|
|
9907
|
-
* Deletes `length` characters starting at `index`.
|
|
9908
|
-
*
|
|
9909
|
-
* @example
|
|
9910
|
-
* const text = new LiveText("Hello world");
|
|
9911
|
-
* text.delete(5, 6); // "Hello"
|
|
9912
|
-
*/
|
|
9913
|
-
delete(index, length) {
|
|
9914
|
-
const clipped = clipRangeToCodePointBoundaries(
|
|
9915
|
-
this.toString(),
|
|
9916
|
-
index,
|
|
9917
|
-
length
|
|
9918
|
-
);
|
|
9919
|
-
if (clipped.length === 0) {
|
|
9920
|
-
return;
|
|
9921
|
-
}
|
|
9922
|
-
this.#dispatch([
|
|
9923
|
-
{ type: "delete", index: clipped.index, length: clipped.length }
|
|
9924
|
-
]);
|
|
9925
|
-
}
|
|
9926
|
-
/**
|
|
9927
|
-
* Replaces a range of text with new text.
|
|
9928
|
-
*
|
|
9929
|
-
* @example
|
|
9930
|
-
* const text = new LiveText("Hello world");
|
|
9931
|
-
* text.replace(0, 5, "Hi"); // "Hi world"
|
|
9932
|
-
*/
|
|
9933
|
-
replace(index, length, text, attributes) {
|
|
9934
|
-
const clipped = clipRangeToCodePointBoundaries(
|
|
9935
|
-
this.toString(),
|
|
9936
|
-
index,
|
|
9937
|
-
length
|
|
9938
|
-
);
|
|
9939
|
-
const ops = [];
|
|
9940
|
-
if (clipped.length > 0) {
|
|
9941
|
-
ops.push({
|
|
9942
|
-
type: "delete",
|
|
9943
|
-
index: clipped.index,
|
|
9944
|
-
length: clipped.length
|
|
9945
|
-
});
|
|
9946
|
-
}
|
|
9947
|
-
if (text.length > 0) {
|
|
9948
|
-
ops.push({ type: "insert", index: clipped.index, text, attributes });
|
|
9949
|
-
}
|
|
9950
|
-
this.#dispatch(ops);
|
|
9951
|
-
}
|
|
9952
|
-
/**
|
|
9953
|
-
* Encode a local-document index (an offset into this LiveText's current
|
|
9954
|
-
* #segments, which CodeMirror or any consumer mirrors as its document)
|
|
9955
|
-
* into server-confirmed coordinates suitable for broadcasting to peers via
|
|
9956
|
-
* presence or any other side channel.
|
|
9957
|
-
*
|
|
9958
|
-
* The returned index is in this LiveText's current #confirmed coordinates
|
|
9959
|
-
* — that is, with this client's local pending ops inverse-mapped out.
|
|
9960
|
-
* Pair it with the current {@link LiveText.version} when sending so the
|
|
9961
|
-
* receiver can call {@link PrivateLiveTextApi.decodeIndex} to land the
|
|
9962
|
-
* position in their own local document coordinates regardless of their
|
|
9963
|
-
* private pending ops.
|
|
9964
|
-
*
|
|
9965
|
-
* Index ambiguity at boundaries is resolved by an inverse-of-forward
|
|
9966
|
-
* convention: a position at or before a local insertion is reported as
|
|
9967
|
-
* the position right before the insertion in #confirmed; a position past
|
|
9968
|
-
* the insertion shifts left by the insertion's length. Positions inside
|
|
9969
|
-
* an own-pending insertion collapse to the insertion point.
|
|
9970
|
-
*/
|
|
9971
|
-
#encodeIndex(localIndex) {
|
|
9972
|
-
let mapped = Math.max(0, Math.min(localIndex, this.length));
|
|
9973
|
-
mapped = inverseMapTextIndexThroughOperations(mapped, this.#queuedOps);
|
|
9974
|
-
mapped = inverseMapTextIndexThroughOperations(mapped, this.#inFlightOps);
|
|
9975
|
-
return mapped;
|
|
9976
|
-
}
|
|
9977
|
-
/**
|
|
9978
|
-
* Decode an `(index, fromVersion)` pair produced by
|
|
9979
|
-
* {@link PrivateLiveTextApi.encodeIndex} — typically on a peer — into an
|
|
9980
|
-
* offset in this LiveText's current local document (an index suitable for
|
|
9981
|
-
* placing a CodeMirror marker, an annotation anchor, or anything else that
|
|
9982
|
-
* lives over #segments).
|
|
9983
|
-
*
|
|
9984
|
-
* Composes the accepted ops applied since `fromVersion` (drawn from
|
|
9985
|
-
* #acceptedOps in locally-applied form) with this client's own local
|
|
9986
|
-
* pending ops, in that order. The result is in current #segments
|
|
9987
|
-
* coordinates.
|
|
9988
|
-
*
|
|
9989
|
-
* Returns `null` when the position cannot be decoded against the current
|
|
9990
|
-
* state:
|
|
9991
|
-
* - `fromVersion` is greater than this LiveText's current version: the
|
|
9992
|
-
* peer is ahead of us. The caller should park the message and retry
|
|
9993
|
-
* after more accepted ops arrive.
|
|
9994
|
-
* - `fromVersion` falls outside the retained accepted-ops history. This
|
|
9995
|
-
* only happens after very long-lived disconnections; the caller can
|
|
9996
|
-
* fall back to using the raw index and letting subsequent local
|
|
9997
|
-
* transactions map it (with bounded drift).
|
|
9998
|
-
*/
|
|
9999
|
-
#decodeIndex(index, fromVersion) {
|
|
10000
|
-
if (fromVersion > this.#version) {
|
|
10001
|
-
return null;
|
|
10002
|
-
}
|
|
10003
|
-
if (fromVersion < this.#version) {
|
|
10004
|
-
const oldest = _optionalChain([this, 'access', _238 => _238.#acceptedOps, 'access', _239 => _239[0], 'optionalAccess', _240 => _240.version]);
|
|
10005
|
-
if (oldest === void 0 || oldest > fromVersion + 1) {
|
|
10006
|
-
return null;
|
|
10007
|
-
}
|
|
10008
|
-
}
|
|
10009
|
-
let mapped = index;
|
|
10010
|
-
for (const entry of this.#acceptedOps) {
|
|
10011
|
-
if (entry.version <= fromVersion) continue;
|
|
10012
|
-
if (entry.version > this.#version) break;
|
|
10013
|
-
if (entry.ops.length === 0) continue;
|
|
10014
|
-
mapped = mapTextIndexThroughOperations(mapped, entry.ops);
|
|
10015
|
-
}
|
|
10016
|
-
mapped = mapTextIndexThroughOperations(mapped, this.#inFlightOps);
|
|
10017
|
-
mapped = mapTextIndexThroughOperations(mapped, this.#queuedOps);
|
|
10018
|
-
return Math.max(0, Math.min(mapped, this.length));
|
|
10019
|
-
}
|
|
10020
|
-
/**
|
|
10021
|
-
* Applies or removes inline attributes on a range of text.
|
|
10022
|
-
*
|
|
10023
|
-
* Set an attribute to `null` to remove it from the range.
|
|
10024
|
-
*
|
|
10025
|
-
* @example
|
|
10026
|
-
* const text = new LiveText("Hello world");
|
|
10027
|
-
* text.format(0, 5, { bold: true });
|
|
10028
|
-
* text.format(0, 5, { bold: null });
|
|
10029
|
-
*/
|
|
10030
|
-
format(index, length, attributes) {
|
|
10031
|
-
const clipped = clipRangeToCodePointBoundaries(
|
|
10032
|
-
this.toString(),
|
|
10033
|
-
index,
|
|
10034
|
-
length
|
|
10035
|
-
);
|
|
10036
|
-
if (clipped.length === 0) {
|
|
10037
|
-
return;
|
|
10038
|
-
}
|
|
10039
|
-
this.#dispatch([
|
|
10040
|
-
{
|
|
10041
|
-
type: "format",
|
|
10042
|
-
index: clipped.index,
|
|
10043
|
-
length: clipped.length,
|
|
10044
|
-
attributes
|
|
10045
|
-
}
|
|
10046
|
-
]);
|
|
10047
|
-
}
|
|
10048
|
-
/** Local edits made through the public API. */
|
|
10049
|
-
#dispatch(ops) {
|
|
10050
|
-
if (ops.length === 0) {
|
|
10051
|
-
return;
|
|
10052
|
-
}
|
|
10053
|
-
_optionalChain([this, 'access', _241 => _241._pool, 'optionalAccess', _242 => _242.assertStorageIsWritable, 'call', _243 => _243()]);
|
|
10054
|
-
const attached = this._pool !== void 0 && this._id !== void 0;
|
|
10055
|
-
const reverse = attached ? this.#invertOperations(ops) : [];
|
|
10056
|
-
const changes = this.#applyOperationsLocally(ops);
|
|
10057
|
-
if (!attached) {
|
|
10058
|
-
return;
|
|
10059
|
-
}
|
|
10060
|
-
const pool = nn(this._pool);
|
|
10061
|
-
const id = nn(this._id);
|
|
10062
|
-
const updates = /* @__PURE__ */ new Map([
|
|
10063
|
-
[
|
|
10064
|
-
id,
|
|
10065
|
-
{
|
|
10066
|
-
type: "LiveText",
|
|
10067
|
-
node: this,
|
|
10068
|
-
version: this.#version,
|
|
10069
|
-
updates: changes,
|
|
10070
|
-
source: LOCAL_EDIT
|
|
10071
|
-
}
|
|
10072
|
-
]
|
|
10073
|
-
]);
|
|
10074
|
-
if (this.#inFlightOpId === void 0) {
|
|
10075
|
-
const opId = pool.generateOpId();
|
|
10076
|
-
this.#inFlightOpId = opId;
|
|
10077
|
-
this.#inFlightOps = [...ops];
|
|
10078
|
-
pool.dispatch(
|
|
10079
|
-
[
|
|
10080
|
-
{
|
|
10081
|
-
type: OpCode.UPDATE_TEXT,
|
|
10082
|
-
id,
|
|
10083
|
-
opId,
|
|
10084
|
-
baseVersion: this.#version,
|
|
10085
|
-
ops: [...ops]
|
|
10086
|
-
}
|
|
10087
|
-
],
|
|
10088
|
-
reverse,
|
|
10089
|
-
updates
|
|
10090
|
-
);
|
|
10091
|
-
} else {
|
|
10092
|
-
this.#queuedOps.push(...ops);
|
|
10093
|
-
pool.dispatch([], reverse, updates, { clearRedoStack: true });
|
|
10094
|
-
}
|
|
10095
|
-
}
|
|
10096
|
-
/**
|
|
10097
|
-
* A local replay of an existing wire op: an undo/redo frame, or an
|
|
10098
|
-
* unacknowledged op re-sent after a reconnect.
|
|
10099
|
-
*/
|
|
10100
|
-
#applyLocal(op, source) {
|
|
10101
|
-
const mutableOp = op;
|
|
10102
|
-
if (op.opId !== void 0 && op.opId === this.#inFlightOpId) {
|
|
10103
|
-
this.#inFlightOps = [...this.#inFlightOps, ...this.#queuedOps];
|
|
10104
|
-
this.#queuedOps = [];
|
|
10105
|
-
mutableOp.baseVersion = this.#version;
|
|
10106
|
-
mutableOp.ops = [...this.#inFlightOps];
|
|
10107
|
-
return { modified: false };
|
|
10108
|
-
}
|
|
10109
|
-
let ops = op.ops;
|
|
10110
|
-
for (const entry of this.#acceptedOps) {
|
|
10111
|
-
if (entry.version > op.baseVersion && entry.ops.length > 0) {
|
|
10112
|
-
ops = transformTextOperations(ops, entry.ops, "after");
|
|
10113
|
-
}
|
|
10114
|
-
}
|
|
10115
|
-
const reverse = this.#invertOperations(ops);
|
|
10116
|
-
const changes = this.#applyOperationsLocally(ops);
|
|
10117
|
-
if (this.#inFlightOpId === void 0 && ops.length > 0) {
|
|
10118
|
-
this.#inFlightOpId = nn(op.opId, "Local ops must have an opId");
|
|
10119
|
-
this.#inFlightOps = [...ops];
|
|
10120
|
-
mutableOp.baseVersion = this.#version;
|
|
10121
|
-
mutableOp.ops = [...ops];
|
|
10122
|
-
} else {
|
|
10123
|
-
this.#queuedOps.push(...ops);
|
|
10124
|
-
mutableOp.baseVersion = this.#version;
|
|
10125
|
-
mutableOp.ops = [];
|
|
10126
|
-
}
|
|
10127
|
-
if (changes.length === 0) {
|
|
10128
|
-
return { modified: false };
|
|
10129
|
-
}
|
|
10130
|
-
return {
|
|
10131
|
-
reverse,
|
|
10132
|
-
modified: {
|
|
10133
|
-
type: "LiveText",
|
|
10134
|
-
node: this,
|
|
10135
|
-
version: this.#version,
|
|
10136
|
-
updates: changes,
|
|
10137
|
-
source
|
|
10138
|
-
}
|
|
10139
|
-
};
|
|
10140
|
-
}
|
|
10141
|
-
/** Server acknowledgement of our in-flight op. */
|
|
10142
|
-
#applyAck(op, source) {
|
|
10143
|
-
const ackedVersion = _nullishCoalesce(op.version, () => ( Math.max(this.#version, op.baseVersion + 1)));
|
|
10144
|
-
const predicted = this.#inFlightOps;
|
|
10145
|
-
const opId = this.#inFlightOpId;
|
|
10146
|
-
this.#confirmed = applyTextOperationsToSegments(this.#confirmed, op.ops);
|
|
10147
|
-
this.#inFlightOpId = void 0;
|
|
10148
|
-
this.#inFlightOps = [];
|
|
10149
|
-
let appliedOps = [];
|
|
10150
|
-
let result = { modified: false };
|
|
10151
|
-
if (!textOperationsEqual(op.ops, predicted)) {
|
|
10152
|
-
error2(
|
|
10153
|
-
"LiveText: acknowledgement did not match the local prediction; resynchronizing"
|
|
10154
|
-
);
|
|
10155
|
-
const rebuilt = this.#rebuildLocalFromConfirmed();
|
|
10156
|
-
appliedOps = rebuilt.appliedOps;
|
|
10157
|
-
if (rebuilt.changes.length > 0) {
|
|
10158
|
-
result = {
|
|
10159
|
-
reverse: [],
|
|
10160
|
-
modified: {
|
|
10161
|
-
type: "LiveText",
|
|
10162
|
-
node: this,
|
|
10163
|
-
version: ackedVersion,
|
|
10164
|
-
updates: rebuilt.changes,
|
|
10165
|
-
source
|
|
10166
|
-
}
|
|
10167
|
-
};
|
|
10168
|
-
}
|
|
10169
|
-
}
|
|
10170
|
-
this.#version = Math.max(this.#version, ackedVersion);
|
|
10171
|
-
this.#recordAccepted(ackedVersion, appliedOps, opId);
|
|
10172
|
-
this.#flushQueued();
|
|
10173
|
-
return result;
|
|
10174
|
-
}
|
|
10175
|
-
/** An accepted op from another client (or a server-fabricated fix op). */
|
|
10176
|
-
#applyRemote(op, source) {
|
|
10177
|
-
const version = _nullishCoalesce(op.version, () => ( this.#version + 1));
|
|
10178
|
-
this.#confirmed = applyTextOperationsToSegments(this.#confirmed, op.ops);
|
|
10179
|
-
const [overInFlight, inFlight] = transformTextOperationsX(
|
|
10180
|
-
op.ops,
|
|
10181
|
-
this.#inFlightOps,
|
|
10182
|
-
"before"
|
|
10183
|
-
);
|
|
10184
|
-
const [applied, queued] = transformTextOperationsX(
|
|
10185
|
-
overInFlight,
|
|
10186
|
-
this.#queuedOps,
|
|
10187
|
-
"before"
|
|
10188
|
-
);
|
|
10189
|
-
this.#inFlightOps = inFlight;
|
|
10190
|
-
this.#queuedOps = queued;
|
|
10191
|
-
this.#recordAccepted(version, applied, op.opId);
|
|
10192
|
-
if (applied.length === 0) {
|
|
10193
|
-
this.#version = Math.max(this.#version, version);
|
|
10194
|
-
return { modified: false };
|
|
10195
|
-
}
|
|
10196
|
-
const reverse = this.#invertOperations(applied);
|
|
10197
|
-
const changes = this.#applyOperationsLocally(applied);
|
|
10198
|
-
this.#version = Math.max(this.#version, version);
|
|
10199
|
-
return {
|
|
10200
|
-
reverse,
|
|
10201
|
-
modified: {
|
|
10202
|
-
type: "LiveText",
|
|
10203
|
-
node: this,
|
|
10204
|
-
version: this.#version,
|
|
10205
|
-
updates: changes,
|
|
10206
|
-
source
|
|
10207
|
-
}
|
|
10208
|
-
};
|
|
10209
|
-
}
|
|
10210
|
-
/** Send the queued ops as the next in-flight op (after an ack). */
|
|
10211
|
-
#flushQueued() {
|
|
10212
|
-
if (this.#queuedOps.length === 0 || this._pool === void 0 || this._id === void 0) {
|
|
10213
|
-
return;
|
|
10214
|
-
}
|
|
10215
|
-
const opId = this._pool.generateOpId();
|
|
10216
|
-
this.#inFlightOpId = opId;
|
|
10217
|
-
this.#inFlightOps = this.#queuedOps;
|
|
10218
|
-
this.#queuedOps = [];
|
|
10219
|
-
this._pool.dispatch(
|
|
10220
|
-
[
|
|
10221
|
-
{
|
|
10222
|
-
type: OpCode.UPDATE_TEXT,
|
|
10223
|
-
id: this._id,
|
|
10224
|
-
opId,
|
|
10225
|
-
baseVersion: this.#version,
|
|
10226
|
-
ops: [...this.#inFlightOps]
|
|
10227
|
-
}
|
|
10228
|
-
],
|
|
10229
|
-
[],
|
|
10230
|
-
/* @__PURE__ */ new Map(),
|
|
10231
|
-
// The local content was already applied (and made undoable) when the
|
|
10232
|
-
// edits happened; this is purely an outbound flush.
|
|
10233
|
-
{ clearRedoStack: false }
|
|
10234
|
-
);
|
|
10235
|
-
}
|
|
10236
|
-
/**
|
|
10237
|
-
* Rebuild the local document as confirmed ⊕ queued ops, returning the
|
|
10238
|
-
* coarse delta that was applied. Only used by defensive recovery paths.
|
|
10239
|
-
*/
|
|
10240
|
-
#rebuildLocalFromConfirmed() {
|
|
10241
|
-
const before2 = this.#segments;
|
|
10242
|
-
const after2 = applyTextOperationsToSegments(this.#confirmed, [
|
|
10243
|
-
...this.#inFlightOps,
|
|
10244
|
-
...this.#queuedOps
|
|
10245
|
-
]);
|
|
10246
|
-
if (stableStringify(segmentsToData(before2)) === stableStringify(segmentsToData(after2))) {
|
|
10247
|
-
this.#segments = after2;
|
|
10248
|
-
return { appliedOps: [], changes: [] };
|
|
10249
|
-
}
|
|
10250
|
-
const beforeText = before2.map((segment) => segment.text).join("");
|
|
10251
|
-
this.#segments = after2;
|
|
10252
|
-
this.invalidate();
|
|
10253
|
-
const appliedOps = [];
|
|
10254
|
-
const changes = [];
|
|
10255
|
-
if (beforeText.length > 0) {
|
|
10256
|
-
appliedOps.push({ type: "delete", index: 0, length: beforeText.length });
|
|
10257
|
-
changes.push({
|
|
10258
|
-
type: "delete",
|
|
10259
|
-
index: 0,
|
|
10260
|
-
length: beforeText.length,
|
|
10261
|
-
deletedText: beforeText
|
|
10262
|
-
});
|
|
10263
|
-
}
|
|
10264
|
-
let index = 0;
|
|
10265
|
-
for (const segment of after2) {
|
|
10266
|
-
appliedOps.push({
|
|
10267
|
-
type: "insert",
|
|
10268
|
-
index,
|
|
10269
|
-
text: segment.text,
|
|
10270
|
-
attributes: segment.attributes
|
|
10271
|
-
});
|
|
10272
|
-
changes.push({
|
|
10273
|
-
type: "insert",
|
|
10274
|
-
index,
|
|
10275
|
-
text: segment.text,
|
|
10276
|
-
attributes: segment.attributes
|
|
10277
|
-
});
|
|
10278
|
-
index += segment.text.length;
|
|
10279
|
-
}
|
|
10280
|
-
return { appliedOps, changes };
|
|
10281
|
-
}
|
|
10282
|
-
/**
|
|
10283
|
-
* Reconcile this node against an authoritative storage snapshot (e.g.
|
|
10284
|
-
* after a reconnect). The confirmed state and version are replaced by the
|
|
10285
|
-
* snapshot's; pending (in-flight + queued) ops are preserved on top and
|
|
10286
|
-
* will be re-sent by the offline-ops replay.
|
|
10287
|
-
*
|
|
10288
|
-
* @internal
|
|
10289
|
-
*/
|
|
10290
|
-
_resyncText(data, version, source) {
|
|
10291
|
-
this.#confirmed = dataToSegments(data);
|
|
10292
|
-
this.#version = version;
|
|
10293
|
-
this.#acceptedOps = [];
|
|
10294
|
-
const rebuilt = this.#rebuildLocalFromConfirmed();
|
|
10295
|
-
if (rebuilt.changes.length === 0) {
|
|
10296
|
-
return void 0;
|
|
10297
|
-
}
|
|
10298
|
-
return {
|
|
10299
|
-
type: "LiveText",
|
|
10300
|
-
node: this,
|
|
10301
|
-
version: this.#version,
|
|
10302
|
-
updates: rebuilt.changes,
|
|
10303
|
-
source
|
|
10304
|
-
};
|
|
10305
|
-
}
|
|
10306
|
-
/**
|
|
10307
|
-
* Called when the server rejected one of our ops. Drops all pending state
|
|
10308
|
-
* for this node (edits queued behind a rejected op cannot be trusted
|
|
10309
|
-
* either); the room follows up with a storage resync.
|
|
10310
|
-
*
|
|
10311
|
-
* @internal
|
|
10312
|
-
*/
|
|
10313
|
-
_rejectPendingOp(opId) {
|
|
10314
|
-
if (opId !== this.#inFlightOpId) {
|
|
10315
|
-
return;
|
|
10316
|
-
}
|
|
10317
|
-
this.#inFlightOpId = void 0;
|
|
10318
|
-
this.#inFlightOps = [];
|
|
10319
|
-
this.#queuedOps = [];
|
|
10320
|
-
}
|
|
10321
|
-
#recordAccepted(version, ops, opId) {
|
|
10322
|
-
if (this.#acceptedOps.some((entry) => entry.version === version)) {
|
|
10323
|
-
return;
|
|
10324
|
-
}
|
|
10325
|
-
this.#acceptedOps.push({ version, opId, ops: [...ops] });
|
|
10326
|
-
this.#acceptedOps.sort((left, right) => left.version - right.version);
|
|
10327
|
-
if (this.#acceptedOps.length > ACCEPTED_OPS_HISTORY_LIMIT) {
|
|
10328
|
-
this.#acceptedOps.splice(
|
|
10329
|
-
0,
|
|
10330
|
-
this.#acceptedOps.length - ACCEPTED_OPS_HISTORY_LIMIT
|
|
10331
|
-
);
|
|
10332
|
-
}
|
|
10333
|
-
}
|
|
10334
|
-
#applyOperationsLocally(ops) {
|
|
10335
|
-
const changes = [];
|
|
10336
|
-
for (const op of ops) {
|
|
10337
|
-
if (op.type === "insert") {
|
|
10338
|
-
this.#segments = applyInsert(
|
|
10339
|
-
this.#segments,
|
|
10340
|
-
op.index,
|
|
10341
|
-
op.text,
|
|
10342
|
-
op.attributes
|
|
10343
|
-
);
|
|
10344
|
-
changes.push({
|
|
10345
|
-
type: "insert",
|
|
10346
|
-
index: op.index,
|
|
10347
|
-
text: op.text,
|
|
10348
|
-
attributes: op.attributes
|
|
10349
|
-
});
|
|
10350
|
-
} else if (op.type === "delete") {
|
|
10351
|
-
const result = applyDelete(this.#segments, op.index, op.length);
|
|
10352
|
-
this.#segments = result.segments;
|
|
10353
|
-
changes.push({
|
|
10354
|
-
type: "delete",
|
|
10355
|
-
index: op.index,
|
|
10356
|
-
length: op.length,
|
|
10357
|
-
deletedText: result.deletedText
|
|
10358
|
-
});
|
|
10359
|
-
} else {
|
|
10360
|
-
this.#segments = applyFormat(
|
|
10361
|
-
this.#segments,
|
|
10362
|
-
op.index,
|
|
10363
|
-
op.length,
|
|
10364
|
-
op.attributes
|
|
10365
|
-
);
|
|
10366
|
-
changes.push({
|
|
10367
|
-
type: "format",
|
|
10368
|
-
index: op.index,
|
|
10369
|
-
length: op.length,
|
|
10370
|
-
attributes: op.attributes
|
|
10371
|
-
});
|
|
10372
|
-
}
|
|
10373
|
-
}
|
|
10374
|
-
this.invalidate();
|
|
10375
|
-
return changes;
|
|
10376
|
-
}
|
|
10377
|
-
#invertOperations(ops) {
|
|
10378
|
-
return [
|
|
10379
|
-
{
|
|
10380
|
-
type: OpCode.UPDATE_TEXT,
|
|
10381
|
-
id: nn(this._id),
|
|
10382
|
-
baseVersion: this.#version,
|
|
10383
|
-
ops: invertTextOperations(this.#segments, ops)
|
|
10384
|
-
}
|
|
10385
|
-
];
|
|
10386
|
-
}
|
|
10387
|
-
/** Returns the plain text content without attributes. Equivalent to joining the text from each segment in {@link LiveText.toJSON}. */
|
|
10388
|
-
toString() {
|
|
10389
|
-
return this.#segments.map((segment) => segment.text).join("");
|
|
10390
|
-
}
|
|
10391
|
-
/**
|
|
10392
|
-
* Returns a JSON-compatible snapshot of the document as a {@link LiveTextData}
|
|
10393
|
-
* array.
|
|
10394
|
-
*
|
|
10395
|
-
* @example
|
|
10396
|
-
* new LiveText([["Hello ", { bold: true }], ["world"]]).toJSON();
|
|
10397
|
-
* // [["Hello ", { bold: true }], ["world"]]
|
|
10398
|
-
*/
|
|
10399
|
-
toJSON() {
|
|
10400
|
-
return super.toJSON();
|
|
10401
|
-
}
|
|
10402
|
-
/** @internal */
|
|
10403
|
-
_toJSON() {
|
|
10404
|
-
return segmentsToData(this.#segments);
|
|
10405
|
-
}
|
|
10406
|
-
/** @internal */
|
|
10407
|
-
toTreeNode(key) {
|
|
10408
|
-
return super.toTreeNode(key);
|
|
10409
|
-
}
|
|
10410
|
-
/** @internal */
|
|
10411
|
-
_toTreeNode(key) {
|
|
10412
|
-
const nodeId = _nullishCoalesce(this._id, () => ( nanoid()));
|
|
10413
|
-
const payload = this.toJSON().map(
|
|
10414
|
-
(segment, index) => ({
|
|
10415
|
-
type: "Json",
|
|
10416
|
-
id: `${nodeId}:${index}`,
|
|
10417
|
-
key: String(index),
|
|
10418
|
-
payload: segment
|
|
10419
|
-
})
|
|
10420
|
-
);
|
|
10421
|
-
payload.push({
|
|
10422
|
-
type: "Json",
|
|
10423
|
-
id: `${nodeId}:version`,
|
|
10424
|
-
key: "version",
|
|
10425
|
-
payload: this.version
|
|
10426
|
-
});
|
|
10427
|
-
return {
|
|
10428
|
-
type: "LiveText",
|
|
10429
|
-
id: nodeId,
|
|
10430
|
-
key,
|
|
10431
|
-
payload
|
|
10432
|
-
};
|
|
10433
|
-
}
|
|
10434
|
-
clone() {
|
|
10435
|
-
return new _LiveText(this.toJSON(), this.#version);
|
|
10436
|
-
}
|
|
10437
|
-
};
|
|
10438
|
-
|
|
10439
|
-
// src/crdts/liveblocks-helpers.ts
|
|
10440
|
-
function creationOpToLiveNode(op) {
|
|
10441
|
-
return lsonToLiveNode(creationOpToLson(op));
|
|
10442
|
-
}
|
|
10443
|
-
function creationOpToLson(op) {
|
|
10444
|
-
switch (op.type) {
|
|
10445
|
-
case OpCode.CREATE_FILE:
|
|
10446
|
-
return new LiveFile(op.data);
|
|
10447
|
-
case OpCode.CREATE_REGISTER:
|
|
10448
|
-
return op.data;
|
|
10449
|
-
case OpCode.CREATE_OBJECT:
|
|
10450
|
-
return new LiveObject(op.data);
|
|
10451
|
-
case OpCode.CREATE_MAP:
|
|
10452
|
-
return new LiveMap();
|
|
10453
|
-
case OpCode.CREATE_LIST:
|
|
10454
|
-
return new LiveList([]);
|
|
10455
|
-
case OpCode.CREATE_TEXT:
|
|
10456
|
-
return new LiveText(op.data, op.version);
|
|
10457
|
-
default:
|
|
10458
|
-
return assertNever(op, "Unknown creation Op");
|
|
10459
|
-
}
|
|
10460
|
-
}
|
|
10461
|
-
function isSameNodeOrChildOf(node, parent) {
|
|
10462
|
-
if (node === parent) {
|
|
10463
|
-
return true;
|
|
10464
|
-
}
|
|
10465
|
-
if (node.parent.type === "HasParent") {
|
|
10466
|
-
return isSameNodeOrChildOf(node.parent.node, parent);
|
|
10467
|
-
}
|
|
10468
|
-
return false;
|
|
10469
|
-
}
|
|
10470
|
-
function liveObjectFromNodeStream(nodes) {
|
|
10471
|
-
const pool = createManagedPool({
|
|
10472
|
-
getCurrentConnectionId: () => {
|
|
10473
|
-
throw new Error(
|
|
10474
|
-
"Cannot mutate a historic storage version: it is a read-only snapshot"
|
|
10475
|
-
);
|
|
10476
|
-
}
|
|
10477
|
-
});
|
|
10478
|
-
return LiveObject._fromItems(nodes, pool);
|
|
10479
|
-
}
|
|
10480
|
-
function deserialize(node, parentToChildren, pool) {
|
|
10481
|
-
if (isObjectStorageNode(node)) {
|
|
10482
|
-
return LiveObject._deserialize(node, parentToChildren, pool);
|
|
10483
|
-
} else if (isListStorageNode(node)) {
|
|
10484
|
-
return LiveList._deserialize(node, parentToChildren, pool);
|
|
10485
|
-
} else if (isMapStorageNode(node)) {
|
|
10486
|
-
return LiveMap._deserialize(node, parentToChildren, pool);
|
|
10487
|
-
} else if (isRegisterStorageNode(node)) {
|
|
10488
|
-
return LiveRegister._deserialize(node, parentToChildren, pool);
|
|
10489
|
-
} else if (isTextStorageNode(node)) {
|
|
10490
|
-
return LiveText._deserialize(node, parentToChildren, pool);
|
|
10491
|
-
} else if (isFileStorageNode(node)) {
|
|
10492
|
-
return LiveFile._deserialize(node, parentToChildren, pool);
|
|
10493
|
-
} else {
|
|
10494
|
-
throw new Error("Unexpected CRDT type");
|
|
10495
|
-
}
|
|
10496
|
-
}
|
|
10497
|
-
function deserializeToLson(node, parentToChildren, pool) {
|
|
10498
|
-
if (isObjectStorageNode(node)) {
|
|
10499
|
-
return LiveObject._deserialize(node, parentToChildren, pool);
|
|
10500
|
-
} else if (isListStorageNode(node)) {
|
|
10501
|
-
return LiveList._deserialize(node, parentToChildren, pool);
|
|
10502
|
-
} else if (isMapStorageNode(node)) {
|
|
10503
|
-
return LiveMap._deserialize(node, parentToChildren, pool);
|
|
10504
|
-
} else if (isRegisterStorageNode(node)) {
|
|
10505
|
-
return node[1].data;
|
|
10506
|
-
} else if (isTextStorageNode(node)) {
|
|
10507
|
-
return LiveText._deserialize(node, parentToChildren, pool);
|
|
10508
|
-
} else if (isFileStorageNode(node)) {
|
|
10509
|
-
return LiveFile._deserialize(node, parentToChildren, pool);
|
|
10510
|
-
} else {
|
|
10511
|
-
throw new Error("Unexpected CRDT type");
|
|
10512
|
-
}
|
|
10513
|
-
}
|
|
10514
|
-
function isLiveStructure(value) {
|
|
10515
|
-
return isLiveList(value) || isLiveMap(value) || isLiveObject(value) || isLiveText(value) || isLiveFile(value);
|
|
10516
|
-
}
|
|
10517
|
-
function isLiveNode(value) {
|
|
10518
|
-
return isLiveStructure(value) || isLiveRegister(value);
|
|
10519
|
-
}
|
|
10520
|
-
function isLiveList(value) {
|
|
10521
|
-
return value instanceof LiveList;
|
|
10522
|
-
}
|
|
10523
|
-
function isLiveMap(value) {
|
|
10524
|
-
return value instanceof LiveMap;
|
|
10525
|
-
}
|
|
10526
|
-
function isLiveObject(value) {
|
|
10527
|
-
return value instanceof LiveObject;
|
|
10528
|
-
}
|
|
10529
|
-
function isLiveText(value) {
|
|
10530
|
-
return value instanceof LiveText;
|
|
10531
|
-
}
|
|
10532
|
-
function isLiveFile(value) {
|
|
10533
|
-
return value instanceof LiveFile;
|
|
10534
|
-
}
|
|
10535
|
-
function isLiveRegister(value) {
|
|
10536
|
-
return value instanceof LiveRegister;
|
|
10537
|
-
}
|
|
10538
|
-
function cloneLson(value) {
|
|
10539
|
-
return value === void 0 ? void 0 : isLiveStructure(value) ? value.clone() : deepClone(value);
|
|
10540
|
-
}
|
|
10541
|
-
function liveNodeToLson(obj) {
|
|
10542
|
-
if (obj instanceof LiveRegister) {
|
|
10543
|
-
return obj.data;
|
|
10544
|
-
} else if (obj instanceof LiveList || obj instanceof LiveMap || obj instanceof LiveObject || obj instanceof LiveText || obj instanceof LiveFile) {
|
|
10545
|
-
return obj;
|
|
10546
|
-
} else {
|
|
10547
|
-
return assertNever(obj, "Unknown AbstractCrdt");
|
|
10548
|
-
}
|
|
10549
|
-
}
|
|
10550
|
-
function lsonToLiveNode(value) {
|
|
10551
|
-
if (value instanceof LiveObject || value instanceof LiveMap || value instanceof LiveList || value instanceof LiveText || value instanceof LiveFile) {
|
|
10552
|
-
return value;
|
|
10553
|
-
} else {
|
|
10554
|
-
return new LiveRegister(value);
|
|
10555
|
-
}
|
|
10556
|
-
}
|
|
10557
|
-
function dumpPool(pool) {
|
|
10558
|
-
const rows = Array.from(pool.nodes.values(), (node) => {
|
|
10559
|
-
const parent = node.parent;
|
|
10560
|
-
const parentId = parent.type === "HasParent" ? _nullishCoalesce(parent.node._id, () => ( "?")) : parent.type === "Orphaned" ? "<orphaned>" : "-";
|
|
10561
|
-
let value;
|
|
10562
|
-
if (node instanceof LiveRegister) {
|
|
10563
|
-
value = stringifyOrLog(node.data);
|
|
10564
|
-
} else if (node instanceof LiveList) {
|
|
10565
|
-
value = "<LiveList>";
|
|
10566
|
-
} else if (node instanceof LiveMap) {
|
|
10567
|
-
value = "<LiveMap>";
|
|
10568
|
-
} else if (node instanceof LiveFile) {
|
|
10569
|
-
value = stringifyOrLog(node.data);
|
|
10570
|
-
} else {
|
|
10571
|
-
value = "<LiveObject>";
|
|
10572
|
-
}
|
|
10573
|
-
return { id: nn(node._id), parentId, key: _nullishCoalesce(node._parentKey, () => ( "")), value };
|
|
10574
|
-
});
|
|
10575
|
-
rows.sort((a, b) => {
|
|
10576
|
-
if (a.parentId !== b.parentId) return a.parentId < b.parentId ? -1 : 1;
|
|
10577
|
-
if (a.key !== b.key) return a.key < b.key ? -1 : 1;
|
|
10578
|
-
return 0;
|
|
10579
|
-
});
|
|
10580
|
-
return rows.map(
|
|
10581
|
-
(r) => ` ${r.id} parent=${r.parentId} key=${r.key || "\u2014"} ${r.value}`
|
|
10582
|
-
).join("\n");
|
|
10583
|
-
}
|
|
10584
|
-
function isJsonEq(a, b) {
|
|
10585
|
-
if (a === b) {
|
|
10586
|
-
return true;
|
|
10587
|
-
}
|
|
10588
|
-
if (typeof a !== "object" || a === null || typeof b !== "object" || b === null) {
|
|
10589
|
-
return false;
|
|
10590
|
-
}
|
|
10591
|
-
if (Array.isArray(a) || Array.isArray(b)) {
|
|
10592
|
-
if (!Array.isArray(a) || !Array.isArray(b) || a.length !== b.length) {
|
|
10593
|
-
return false;
|
|
10594
|
-
}
|
|
10595
|
-
for (let i = 0; i < a.length; i++) {
|
|
10596
|
-
if (!isJsonEq(a[i], b[i])) {
|
|
10597
|
-
return false;
|
|
10598
|
-
}
|
|
10599
|
-
}
|
|
10600
|
-
return true;
|
|
10601
|
-
}
|
|
10602
|
-
const aKeys = Object.keys(a);
|
|
10603
|
-
if (aKeys.length !== Object.keys(b).length) {
|
|
10604
|
-
return false;
|
|
10605
|
-
}
|
|
10606
|
-
for (const key of aKeys) {
|
|
10607
|
-
if (!isJsonEq(a[key], b[key])) {
|
|
10608
|
-
return false;
|
|
10609
|
-
}
|
|
10610
|
-
}
|
|
10611
|
-
return true;
|
|
10612
|
-
}
|
|
10613
|
-
function liveTextDataToReplaceOps(before2, after2) {
|
|
10614
|
-
const ops = [];
|
|
10615
|
-
const beforeLength = before2.reduce(
|
|
10616
|
-
(length, [text]) => length + text.length,
|
|
10617
|
-
0
|
|
10618
|
-
);
|
|
10619
|
-
if (beforeLength > 0) {
|
|
10620
|
-
ops.push({ type: "delete", index: 0, length: beforeLength });
|
|
10621
|
-
}
|
|
10622
|
-
let index = 0;
|
|
10623
|
-
for (const [text, attributes] of after2) {
|
|
10624
|
-
if (text.length === 0) {
|
|
10625
|
-
continue;
|
|
10626
|
-
}
|
|
10627
|
-
ops.push({ type: "insert", index, text, attributes });
|
|
10628
|
-
index += text.length;
|
|
10629
|
-
}
|
|
10630
|
-
return ops;
|
|
10631
|
-
}
|
|
10632
|
-
function diffNodeMap(prev, next, options) {
|
|
9347
|
+
function diffNodeMap(prev, next) {
|
|
10633
9348
|
const ops = [];
|
|
10634
9349
|
const idsToRecreate = /* @__PURE__ */ new Set();
|
|
10635
9350
|
next.forEach((nextCrdt, id) => {
|
|
@@ -10721,16 +9436,6 @@ function diffNodeMap(prev, next, options) {
|
|
|
10721
9436
|
parentKey: crdt.parentKey
|
|
10722
9437
|
});
|
|
10723
9438
|
break;
|
|
10724
|
-
case CrdtType.TEXT:
|
|
10725
|
-
ops.push({
|
|
10726
|
-
type: OpCode.CREATE_TEXT,
|
|
10727
|
-
id,
|
|
10728
|
-
parentId: crdt.parentId,
|
|
10729
|
-
parentKey: crdt.parentKey,
|
|
10730
|
-
data: crdt.data,
|
|
10731
|
-
version: crdt.version
|
|
10732
|
-
});
|
|
10733
|
-
break;
|
|
10734
9439
|
}
|
|
10735
9440
|
}
|
|
10736
9441
|
next.forEach((crdt, id) => {
|
|
@@ -10757,17 +9462,6 @@ function diffNodeMap(prev, next, options) {
|
|
|
10757
9462
|
}
|
|
10758
9463
|
}
|
|
10759
9464
|
}
|
|
10760
|
-
if (_optionalChain([options, 'optionalAccess', _244 => _244.includeLiveTextUpdates]) === true && crdt.type === CrdtType.TEXT && currentCrdt.type === CrdtType.TEXT && !isJsonEq(crdt.data, currentCrdt.data)) {
|
|
10761
|
-
ops.push({
|
|
10762
|
-
type: OpCode.UPDATE_TEXT,
|
|
10763
|
-
id,
|
|
10764
|
-
// A restore is a new edit in the current timeline. The version from
|
|
10765
|
-
// the historic snapshot describes its old timeline and must not move
|
|
10766
|
-
// this node's current version backwards.
|
|
10767
|
-
baseVersion: currentCrdt.version,
|
|
10768
|
-
ops: liveTextDataToReplaceOps(currentCrdt.data, crdt.data)
|
|
10769
|
-
});
|
|
10770
|
-
}
|
|
10771
9465
|
if (crdt.parentKey !== currentCrdt.parentKey) {
|
|
10772
9466
|
ops.push({
|
|
10773
9467
|
type: OpCode.SET_PARENT_KEY,
|
|
@@ -10808,36 +9502,19 @@ function mergeListStorageUpdates(first, second) {
|
|
|
10808
9502
|
updates: updates.concat(second.updates)
|
|
10809
9503
|
};
|
|
10810
9504
|
}
|
|
10811
|
-
function mergeTextStorageUpdates(first, second) {
|
|
10812
|
-
return {
|
|
10813
|
-
...second,
|
|
10814
|
-
updates: first.updates.concat(second.updates)
|
|
10815
|
-
};
|
|
10816
|
-
}
|
|
10817
|
-
function mergeUpdateSources(first, second) {
|
|
10818
|
-
if (first.origin === "remote" || second.origin === "remote") {
|
|
10819
|
-
return REMOTE;
|
|
10820
|
-
}
|
|
10821
|
-
if (second.via !== "edit") return second;
|
|
10822
|
-
if (first.via !== "edit") return first;
|
|
10823
|
-
return LOCAL_EDIT;
|
|
10824
|
-
}
|
|
10825
9505
|
function mergeStorageUpdates(first, second) {
|
|
10826
9506
|
if (first === void 0) {
|
|
10827
9507
|
return second;
|
|
10828
9508
|
}
|
|
10829
|
-
const source = mergeUpdateSources(first.source, second.source);
|
|
10830
9509
|
if (first.type === "LiveObject" && second.type === "LiveObject") {
|
|
10831
|
-
return
|
|
9510
|
+
return mergeObjectStorageUpdates(first, second);
|
|
10832
9511
|
} else if (first.type === "LiveMap" && second.type === "LiveMap") {
|
|
10833
|
-
return
|
|
9512
|
+
return mergeMapStorageUpdates(first, second);
|
|
10834
9513
|
} else if (first.type === "LiveList" && second.type === "LiveList") {
|
|
10835
|
-
return
|
|
10836
|
-
} else if (first.type === "LiveText" && second.type === "LiveText") {
|
|
10837
|
-
return { ...mergeTextStorageUpdates(first, second), source };
|
|
9514
|
+
return mergeListStorageUpdates(first, second);
|
|
10838
9515
|
} else {
|
|
10839
|
-
return { ...second, source };
|
|
10840
9516
|
}
|
|
9517
|
+
return second;
|
|
10841
9518
|
}
|
|
10842
9519
|
|
|
10843
9520
|
// src/devtools/bridge.ts
|
|
@@ -10853,7 +9530,7 @@ function sendToPanel(message, options) {
|
|
|
10853
9530
|
...message,
|
|
10854
9531
|
source: "liveblocks-devtools-client"
|
|
10855
9532
|
};
|
|
10856
|
-
if (!(_optionalChain([options, 'optionalAccess',
|
|
9533
|
+
if (!(_optionalChain([options, 'optionalAccess', _238 => _238.force]) || _bridgeActive)) {
|
|
10857
9534
|
return;
|
|
10858
9535
|
}
|
|
10859
9536
|
window.postMessage(fullMsg, "*");
|
|
@@ -10861,7 +9538,7 @@ function sendToPanel(message, options) {
|
|
|
10861
9538
|
var eventSource = makeEventSource();
|
|
10862
9539
|
if (process.env.NODE_ENV !== "production" && typeof window !== "undefined") {
|
|
10863
9540
|
window.addEventListener("message", (event) => {
|
|
10864
|
-
if (event.source === window && _optionalChain([event, 'access',
|
|
9541
|
+
if (event.source === window && _optionalChain([event, 'access', _239 => _239.data, 'optionalAccess', _240 => _240.source]) === "liveblocks-devtools-panel") {
|
|
10865
9542
|
eventSource.notify(event.data);
|
|
10866
9543
|
} else {
|
|
10867
9544
|
}
|
|
@@ -11003,7 +9680,7 @@ function fullSync(room) {
|
|
|
11003
9680
|
msg: "room::sync::full",
|
|
11004
9681
|
roomId: room.id,
|
|
11005
9682
|
status: room.getStatus(),
|
|
11006
|
-
storage: _nullishCoalesce(_optionalChain([root, 'optionalAccess',
|
|
9683
|
+
storage: _nullishCoalesce(_optionalChain([root, 'optionalAccess', _241 => _241.toTreeNode, 'call', _242 => _242("root"), 'access', _243 => _243.payload]), () => ( null)),
|
|
11007
9684
|
me,
|
|
11008
9685
|
others
|
|
11009
9686
|
});
|
|
@@ -11690,15 +10367,15 @@ function installBackgroundTabSpy() {
|
|
|
11690
10367
|
const doc = typeof document !== "undefined" ? document : void 0;
|
|
11691
10368
|
const inBackgroundSince = { current: null };
|
|
11692
10369
|
function onVisibilityChange() {
|
|
11693
|
-
if (_optionalChain([doc, 'optionalAccess',
|
|
10370
|
+
if (_optionalChain([doc, 'optionalAccess', _244 => _244.visibilityState]) === "hidden") {
|
|
11694
10371
|
inBackgroundSince.current = _nullishCoalesce(inBackgroundSince.current, () => ( Date.now()));
|
|
11695
10372
|
} else {
|
|
11696
10373
|
inBackgroundSince.current = null;
|
|
11697
10374
|
}
|
|
11698
10375
|
}
|
|
11699
|
-
_optionalChain([doc, 'optionalAccess',
|
|
10376
|
+
_optionalChain([doc, 'optionalAccess', _245 => _245.addEventListener, 'call', _246 => _246("visibilitychange", onVisibilityChange)]);
|
|
11700
10377
|
const unsub = () => {
|
|
11701
|
-
_optionalChain([doc, 'optionalAccess',
|
|
10378
|
+
_optionalChain([doc, 'optionalAccess', _247 => _247.removeEventListener, 'call', _248 => _248("visibilitychange", onVisibilityChange)]);
|
|
11702
10379
|
};
|
|
11703
10380
|
return [inBackgroundSince, unsub];
|
|
11704
10381
|
}
|
|
@@ -11722,7 +10399,7 @@ function makeNodeMapBuffer() {
|
|
|
11722
10399
|
function topLevelKeysOf(nodes) {
|
|
11723
10400
|
const keys2 = /* @__PURE__ */ new Set();
|
|
11724
10401
|
const root = nodes.get("root");
|
|
11725
|
-
for (const key in _optionalChain([root, 'optionalAccess',
|
|
10402
|
+
for (const key in _optionalChain([root, 'optionalAccess', _249 => _249.data])) {
|
|
11726
10403
|
keys2.add(key);
|
|
11727
10404
|
}
|
|
11728
10405
|
for (const node of nodes.values()) {
|
|
@@ -11794,8 +10471,6 @@ function createRoom(options, config) {
|
|
|
11794
10471
|
activeBatch: null,
|
|
11795
10472
|
unacknowledgedOps
|
|
11796
10473
|
};
|
|
11797
|
-
let nextHistoryItemId = 0;
|
|
11798
|
-
let historyDisabled = 0;
|
|
11799
10474
|
const nodeMapBuffer = makeNodeMapBuffer();
|
|
11800
10475
|
const stopwatch = config.enableDebugLogging ? makeStopWatch() : void 0;
|
|
11801
10476
|
let lastTokenKey;
|
|
@@ -11880,7 +10555,7 @@ function createRoom(options, config) {
|
|
|
11880
10555
|
}
|
|
11881
10556
|
}
|
|
11882
10557
|
});
|
|
11883
|
-
function onDispatch(ops, reverse, storageUpdates
|
|
10558
|
+
function onDispatch(ops, reverse, storageUpdates) {
|
|
11884
10559
|
if (context.activeBatch) {
|
|
11885
10560
|
for (const op of ops) {
|
|
11886
10561
|
context.activeBatch.ops.push(op);
|
|
@@ -11895,24 +10570,19 @@ function createRoom(options, config) {
|
|
|
11895
10570
|
);
|
|
11896
10571
|
}
|
|
11897
10572
|
context.activeBatch.reverseOps.pushLeft(reverse);
|
|
11898
|
-
if (_optionalChain([options2, 'optionalAccess', _257 => _257.clearRedoStack])) {
|
|
11899
|
-
context.activeBatch.clearRedoStack = true;
|
|
11900
|
-
}
|
|
11901
10573
|
} else {
|
|
11902
10574
|
if (reverse.length > 0) {
|
|
11903
10575
|
addToUndoStack(reverse);
|
|
11904
10576
|
}
|
|
11905
|
-
if (_nullishCoalesce(_optionalChain([options2, 'optionalAccess', _258 => _258.clearRedoStack]), () => ( ops.length > 0))) {
|
|
11906
|
-
clearRedoStack();
|
|
11907
|
-
}
|
|
11908
10577
|
if (ops.length > 0) {
|
|
10578
|
+
context.redoStack.length = 0;
|
|
11909
10579
|
dispatchOps(ops);
|
|
11910
10580
|
}
|
|
11911
10581
|
notify({ storageUpdates });
|
|
11912
10582
|
}
|
|
11913
10583
|
}
|
|
11914
10584
|
function isStorageWritable() {
|
|
11915
|
-
const permissionMatrix = _optionalChain([context, 'access',
|
|
10585
|
+
const permissionMatrix = _optionalChain([context, 'access', _250 => _250.dynamicSessionInfoSig, 'access', _251 => _251.get, 'call', _252 => _252(), 'optionalAccess', _253 => _253.permissionMatrix]);
|
|
11916
10586
|
return permissionMatrix !== void 0 ? hasPermissionAccess(permissionMatrix, "storage", "write") : true;
|
|
11917
10587
|
}
|
|
11918
10588
|
const eventHub = {
|
|
@@ -11925,7 +10595,6 @@ function createRoom(options, config) {
|
|
|
11925
10595
|
others: makeEventSource(),
|
|
11926
10596
|
storageBatch: makeEventSource(),
|
|
11927
10597
|
history: makeEventSource(),
|
|
11928
|
-
privateHistory: makeEventSource(),
|
|
11929
10598
|
storageDidLoad: makeEventSource(),
|
|
11930
10599
|
storageStatus: makeEventSource(),
|
|
11931
10600
|
ydoc: makeEventSource(),
|
|
@@ -12013,12 +10682,12 @@ function createRoom(options, config) {
|
|
|
12013
10682
|
self,
|
|
12014
10683
|
(me) => me !== null ? userToTreeNode("Me", me) : null
|
|
12015
10684
|
);
|
|
12016
|
-
function diffCurrentStorageAgainst(target
|
|
10685
|
+
function diffCurrentStorageAgainst(target) {
|
|
12017
10686
|
const current = /* @__PURE__ */ new Map();
|
|
12018
10687
|
for (const [id, crdt] of context.pool.nodes) {
|
|
12019
10688
|
current.set(id, crdt._serialize());
|
|
12020
10689
|
}
|
|
12021
|
-
return diffNodeMap(current, target
|
|
10690
|
+
return diffNodeMap(current, target);
|
|
12022
10691
|
}
|
|
12023
10692
|
function createOrUpdateRootFromMessage(nodes) {
|
|
12024
10693
|
if (nodes.size === 0) {
|
|
@@ -12026,23 +10695,6 @@ function createRoom(options, config) {
|
|
|
12026
10695
|
}
|
|
12027
10696
|
if (context.root !== void 0) {
|
|
12028
10697
|
const result = applyRemoteOps(diffCurrentStorageAgainst(nodes));
|
|
12029
|
-
for (const [id, crdt] of nodes) {
|
|
12030
|
-
if (crdt.type === CrdtType.TEXT) {
|
|
12031
|
-
const node = context.pool.nodes.get(id);
|
|
12032
|
-
if (node !== void 0 && isLiveText(node)) {
|
|
12033
|
-
const update = node._resyncText(crdt.data, crdt.version, REMOTE);
|
|
12034
|
-
if (update !== void 0) {
|
|
12035
|
-
result.updates.storageUpdates.set(
|
|
12036
|
-
id,
|
|
12037
|
-
mergeStorageUpdates(
|
|
12038
|
-
result.updates.storageUpdates.get(id),
|
|
12039
|
-
update
|
|
12040
|
-
)
|
|
12041
|
-
);
|
|
12042
|
-
}
|
|
12043
|
-
}
|
|
12044
|
-
}
|
|
12045
|
-
}
|
|
12046
10698
|
notify(result.updates);
|
|
12047
10699
|
} else {
|
|
12048
10700
|
context.root = LiveObject._fromItems(
|
|
@@ -12050,7 +10702,7 @@ function createRoom(options, config) {
|
|
|
12050
10702
|
context.pool
|
|
12051
10703
|
);
|
|
12052
10704
|
}
|
|
12053
|
-
const canWrite = _nullishCoalesce(_optionalChain([self, 'access',
|
|
10705
|
+
const canWrite = _nullishCoalesce(_optionalChain([self, 'access', _254 => _254.get, 'call', _255 => _255(), 'optionalAccess', _256 => _256.canWrite]), () => ( true));
|
|
12054
10706
|
const serverTopLevelKeys = topLevelKeysOf(nodes);
|
|
12055
10707
|
const root = context.root;
|
|
12056
10708
|
disableHistory(() => {
|
|
@@ -12067,23 +10719,12 @@ function createRoom(options, config) {
|
|
|
12067
10719
|
}
|
|
12068
10720
|
});
|
|
12069
10721
|
}
|
|
12070
|
-
function notifyPrivateHistory(event) {
|
|
12071
|
-
if (historyDisabled > 0) return;
|
|
12072
|
-
eventHub.privateHistory.notify(event);
|
|
12073
|
-
}
|
|
12074
|
-
function clearRedoStack() {
|
|
12075
|
-
if (context.redoStack.length === 0) return;
|
|
12076
|
-
const ids = context.redoStack.map((item) => item.id);
|
|
12077
|
-
context.redoStack.length = 0;
|
|
12078
|
-
notifyPrivateHistory({ action: "discard", ids });
|
|
12079
|
-
}
|
|
12080
10722
|
function reconcileStorageWithNodes(nodes) {
|
|
12081
10723
|
if (context.root === void 0) {
|
|
12082
10724
|
throw new Error("Cannot reconcile storage before it is loaded");
|
|
12083
10725
|
}
|
|
12084
10726
|
const ops = diffCurrentStorageAgainst(
|
|
12085
|
-
new Map(nodes)
|
|
12086
|
-
{ includeLiveTextUpdates: true }
|
|
10727
|
+
new Map(nodes)
|
|
12087
10728
|
);
|
|
12088
10729
|
if (ops.length === 0) {
|
|
12089
10730
|
return;
|
|
@@ -12102,14 +10743,9 @@ function createRoom(options, config) {
|
|
|
12102
10743
|
}
|
|
12103
10744
|
function _addToRealUndoStack(frames) {
|
|
12104
10745
|
if (context.undoStack.length >= 50) {
|
|
12105
|
-
|
|
12106
|
-
if (evicted !== void 0) {
|
|
12107
|
-
notifyPrivateHistory({ action: "discard", ids: [evicted.id] });
|
|
12108
|
-
}
|
|
10746
|
+
context.undoStack.shift();
|
|
12109
10747
|
}
|
|
12110
|
-
|
|
12111
|
-
context.undoStack.push({ id, frames });
|
|
12112
|
-
notifyPrivateHistory({ action: "push", id });
|
|
10748
|
+
context.undoStack.push(frames);
|
|
12113
10749
|
onHistoryChange();
|
|
12114
10750
|
}
|
|
12115
10751
|
function addToUndoStack(frames) {
|
|
@@ -12133,10 +10769,7 @@ function createRoom(options, config) {
|
|
|
12133
10769
|
eventHub.myPresence.notify(context.myPresence.get());
|
|
12134
10770
|
}
|
|
12135
10771
|
if (storageUpdates !== void 0 && storageUpdates.size > 0) {
|
|
12136
|
-
const updates2 = Array.from(storageUpdates.values()
|
|
12137
|
-
...update,
|
|
12138
|
-
source: toUpdateSource(update.source)
|
|
12139
|
-
}));
|
|
10772
|
+
const updates2 = Array.from(storageUpdates.values());
|
|
12140
10773
|
eventHub.storageBatch.notify(updates2);
|
|
12141
10774
|
}
|
|
12142
10775
|
notifyStorageStatus();
|
|
@@ -12150,69 +10783,19 @@ function createRoom(options, config) {
|
|
|
12150
10783
|
"Internal. Tried to get connection id but connection was never open"
|
|
12151
10784
|
);
|
|
12152
10785
|
}
|
|
12153
|
-
|
|
12154
|
-
function viaOfAckedOp(opId) {
|
|
12155
|
-
const via = viaByOpId.get(opId);
|
|
12156
|
-
if (via === void 0) {
|
|
12157
|
-
return "edit";
|
|
12158
|
-
}
|
|
12159
|
-
viaByOpId.delete(opId);
|
|
12160
|
-
return via;
|
|
12161
|
-
}
|
|
12162
|
-
function applyLocalOps(frames, localSource = LOCAL_EDIT) {
|
|
10786
|
+
function applyLocalOps(frames) {
|
|
12163
10787
|
const [pframes, ops] = partition(
|
|
12164
10788
|
frames,
|
|
12165
10789
|
(f) => f.type === "presence"
|
|
12166
10790
|
);
|
|
12167
|
-
const
|
|
12168
|
-
for (const op of ops) {
|
|
12169
|
-
if (op.type === OpCode.CREATE_TEXT && op.opId === void 0 && context.pool.nodes.get(op.id) === void 0 && !restoredTextIds.has(op.id)) {
|
|
12170
|
-
restoredTextIds.set(op.id, context.pool.generateId());
|
|
12171
|
-
}
|
|
12172
|
-
}
|
|
12173
|
-
const remappedOps = restoredTextIds.size === 0 ? ops : ops.map((op) => {
|
|
12174
|
-
if (op.opId !== void 0) {
|
|
12175
|
-
return op;
|
|
12176
|
-
}
|
|
12177
|
-
const id = restoredTextIds.get(op.id);
|
|
12178
|
-
if (isCreateOp(op)) {
|
|
12179
|
-
const parentId = restoredTextIds.get(op.parentId);
|
|
12180
|
-
const deletedId = op.deletedId === void 0 ? void 0 : restoredTextIds.get(op.deletedId);
|
|
12181
|
-
if (id === void 0 && parentId === void 0 && deletedId === void 0) {
|
|
12182
|
-
return op;
|
|
12183
|
-
}
|
|
12184
|
-
if (op.type === OpCode.CREATE_TEXT && id !== void 0) {
|
|
12185
|
-
return {
|
|
12186
|
-
...op,
|
|
12187
|
-
id,
|
|
12188
|
-
version: 0,
|
|
12189
|
-
...parentId === void 0 ? {} : { parentId },
|
|
12190
|
-
...deletedId === void 0 ? {} : { deletedId }
|
|
12191
|
-
};
|
|
12192
|
-
}
|
|
12193
|
-
return {
|
|
12194
|
-
...op,
|
|
12195
|
-
...id === void 0 ? {} : { id },
|
|
12196
|
-
...parentId === void 0 ? {} : { parentId },
|
|
12197
|
-
...deletedId === void 0 ? {} : { deletedId }
|
|
12198
|
-
};
|
|
12199
|
-
}
|
|
12200
|
-
return id === void 0 ? op : { ...op, id };
|
|
12201
|
-
});
|
|
12202
|
-
const opsWithOpIds = remappedOps.map(
|
|
10791
|
+
const opsWithOpIds = ops.map(
|
|
12203
10792
|
(op) => op.opId === void 0 ? { ...op, opId: context.pool.generateOpId() } : op
|
|
12204
10793
|
);
|
|
12205
|
-
if (localSource.via !== "edit") {
|
|
12206
|
-
for (const op of opsWithOpIds) {
|
|
12207
|
-
viaByOpId.set(op.opId, localSource.via);
|
|
12208
|
-
}
|
|
12209
|
-
}
|
|
12210
10794
|
const { reverse, updates } = applyOps(
|
|
12211
10795
|
pframes,
|
|
12212
10796
|
opsWithOpIds,
|
|
12213
10797
|
/* isLocal */
|
|
12214
|
-
true
|
|
12215
|
-
localSource
|
|
10798
|
+
true
|
|
12216
10799
|
);
|
|
12217
10800
|
return { opsToEmit: opsWithOpIds, reverse, updates };
|
|
12218
10801
|
}
|
|
@@ -12224,7 +10807,7 @@ function createRoom(options, config) {
|
|
|
12224
10807
|
false
|
|
12225
10808
|
);
|
|
12226
10809
|
}
|
|
12227
|
-
function applyOps(pframes, ops, isLocal
|
|
10810
|
+
function applyOps(pframes, ops, isLocal) {
|
|
12228
10811
|
const output = {
|
|
12229
10812
|
reverse: new Deque(),
|
|
12230
10813
|
storageUpdates: /* @__PURE__ */ new Map(),
|
|
@@ -12253,16 +10836,12 @@ function createRoom(options, config) {
|
|
|
12253
10836
|
for (const op of ops) {
|
|
12254
10837
|
let source;
|
|
12255
10838
|
if (isLocal) {
|
|
12256
|
-
source =
|
|
10839
|
+
source = 0 /* LOCAL */;
|
|
12257
10840
|
} else if (op.opId !== void 0) {
|
|
12258
10841
|
context.unacknowledgedOps.delete(op.opId);
|
|
12259
|
-
source =
|
|
12260
|
-
origin: "local",
|
|
12261
|
-
via: viaOfAckedOp(op.opId),
|
|
12262
|
-
optimistic: false
|
|
12263
|
-
};
|
|
10842
|
+
source = 2 /* OURS */;
|
|
12264
10843
|
} else {
|
|
12265
|
-
source =
|
|
10844
|
+
source = 1 /* THEIRS */;
|
|
12266
10845
|
}
|
|
12267
10846
|
const applyOpResult = applyOp(op, source);
|
|
12268
10847
|
if (applyOpResult.modified) {
|
|
@@ -12277,7 +10856,7 @@ function createRoom(options, config) {
|
|
|
12277
10856
|
);
|
|
12278
10857
|
output.reverse.pushLeft(applyOpResult.reverse);
|
|
12279
10858
|
}
|
|
12280
|
-
if (op.type === OpCode.CREATE_LIST || op.type === OpCode.CREATE_MAP || op.type === OpCode.CREATE_OBJECT || op.type === OpCode.
|
|
10859
|
+
if (op.type === OpCode.CREATE_LIST || op.type === OpCode.CREATE_MAP || op.type === OpCode.CREATE_OBJECT || op.type === OpCode.CREATE_FILE) {
|
|
12281
10860
|
createdNodeIds.add(op.id);
|
|
12282
10861
|
}
|
|
12283
10862
|
}
|
|
@@ -12297,13 +10876,12 @@ function createRoom(options, config) {
|
|
|
12297
10876
|
switch (op.type) {
|
|
12298
10877
|
case OpCode.DELETE_OBJECT_KEY:
|
|
12299
10878
|
case OpCode.UPDATE_OBJECT:
|
|
12300
|
-
case OpCode.UPDATE_TEXT:
|
|
12301
10879
|
case OpCode.DELETE_CRDT: {
|
|
12302
10880
|
const node = context.pool.nodes.get(op.id);
|
|
12303
10881
|
if (node === void 0) {
|
|
12304
10882
|
return { modified: false };
|
|
12305
10883
|
}
|
|
12306
|
-
return node._apply(op, source);
|
|
10884
|
+
return node._apply(op, source === 0 /* LOCAL */);
|
|
12307
10885
|
}
|
|
12308
10886
|
case OpCode.SET_PARENT_KEY: {
|
|
12309
10887
|
const node = context.pool.nodes.get(op.id);
|
|
@@ -12322,7 +10900,6 @@ function createRoom(options, config) {
|
|
|
12322
10900
|
case OpCode.CREATE_OBJECT:
|
|
12323
10901
|
case OpCode.CREATE_LIST:
|
|
12324
10902
|
case OpCode.CREATE_MAP:
|
|
12325
|
-
case OpCode.CREATE_TEXT:
|
|
12326
10903
|
case OpCode.CREATE_FILE:
|
|
12327
10904
|
case OpCode.CREATE_REGISTER: {
|
|
12328
10905
|
if (op.parentId === void 0) {
|
|
@@ -12358,7 +10935,7 @@ function createRoom(options, config) {
|
|
|
12358
10935
|
}
|
|
12359
10936
|
context.myPresence.patch(patch);
|
|
12360
10937
|
if (context.activeBatch) {
|
|
12361
|
-
if (_optionalChain([options2, 'optionalAccess',
|
|
10938
|
+
if (_optionalChain([options2, 'optionalAccess', _257 => _257.addToHistory])) {
|
|
12362
10939
|
context.activeBatch.reverseOps.pushLeft({
|
|
12363
10940
|
type: "presence",
|
|
12364
10941
|
data: oldValues
|
|
@@ -12367,7 +10944,7 @@ function createRoom(options, config) {
|
|
|
12367
10944
|
context.activeBatch.updates.presence = true;
|
|
12368
10945
|
} else {
|
|
12369
10946
|
flushNowOrSoon();
|
|
12370
|
-
if (_optionalChain([options2, 'optionalAccess',
|
|
10947
|
+
if (_optionalChain([options2, 'optionalAccess', _258 => _258.addToHistory])) {
|
|
12371
10948
|
addToUndoStack([{ type: "presence", data: oldValues }]);
|
|
12372
10949
|
}
|
|
12373
10950
|
notify({ presence: true });
|
|
@@ -12546,11 +11123,11 @@ function createRoom(options, config) {
|
|
|
12546
11123
|
break;
|
|
12547
11124
|
}
|
|
12548
11125
|
case ServerMsgCode.STORAGE_CHUNK:
|
|
12549
|
-
_optionalChain([stopwatch, 'optionalAccess',
|
|
11126
|
+
_optionalChain([stopwatch, 'optionalAccess', _259 => _259.lap, 'call', _260 => _260()]);
|
|
12550
11127
|
nodeMapBuffer.append(compactNodesToNodeStream(message.nodes));
|
|
12551
11128
|
break;
|
|
12552
11129
|
case ServerMsgCode.STORAGE_STREAM_END: {
|
|
12553
|
-
const timing = _optionalChain([stopwatch, 'optionalAccess',
|
|
11130
|
+
const timing = _optionalChain([stopwatch, 'optionalAccess', _261 => _261.stop, 'call', _262 => _262()]);
|
|
12554
11131
|
if (timing) {
|
|
12555
11132
|
const ms = (v) => `${v.toFixed(1)}ms`;
|
|
12556
11133
|
const rest = timing.laps.slice(1);
|
|
@@ -12577,38 +11154,16 @@ function createRoom(options, config) {
|
|
|
12577
11154
|
}
|
|
12578
11155
|
break;
|
|
12579
11156
|
}
|
|
12580
|
-
// Receiving a RejectedOps message means the server
|
|
12581
|
-
//
|
|
12582
|
-
//
|
|
12583
|
-
//
|
|
12584
|
-
// server's retained history window — and we can recover: drop the
|
|
12585
|
-
// rejected pending state and re-fetch the authoritative storage
|
|
12586
|
-
// snapshot. For other ops (e.g. permission rejections), rolling back
|
|
12587
|
-
// particular Ops is hard/impossible, so we keep the old behavior of
|
|
12588
|
-
// accepting the out-of-sync reality and surfacing an error.
|
|
11157
|
+
// Receiving a RejectedOps message in the client means that the server is no
|
|
11158
|
+
// longer in sync with the client. Trying to synchronize the client again by
|
|
11159
|
+
// rolling back particular Ops may be hard/impossible. It's fine to not try and
|
|
11160
|
+
// accept the out-of-sync reality and throw an error.
|
|
12589
11161
|
case ServerMsgCode.REJECT_STORAGE_OP: {
|
|
12590
11162
|
errorWithTitle(
|
|
12591
11163
|
"Storage mutation rejection error",
|
|
12592
11164
|
message.reason
|
|
12593
11165
|
);
|
|
12594
|
-
|
|
12595
|
-
for (const opId of message.opIds) {
|
|
12596
|
-
const rejectedOp = context.unacknowledgedOps.get(opId);
|
|
12597
|
-
context.unacknowledgedOps.delete(opId);
|
|
12598
|
-
context.buffer.storageOperations = context.buffer.storageOperations.filter((op) => op.opId !== opId);
|
|
12599
|
-
viaByOpId.delete(opId);
|
|
12600
|
-
if (rejectedOp !== void 0 && rejectedOp.type === OpCode.UPDATE_TEXT) {
|
|
12601
|
-
const node = context.pool.nodes.get(rejectedOp.id);
|
|
12602
|
-
if (node !== void 0 && isLiveText(node)) {
|
|
12603
|
-
node._rejectPendingOp(opId);
|
|
12604
|
-
needsStorageResync = true;
|
|
12605
|
-
}
|
|
12606
|
-
}
|
|
12607
|
-
}
|
|
12608
|
-
if (needsStorageResync) {
|
|
12609
|
-
refreshStorage();
|
|
12610
|
-
flushNowOrSoon();
|
|
12611
|
-
} else if (process.env.NODE_ENV !== "production") {
|
|
11166
|
+
if (process.env.NODE_ENV !== "production") {
|
|
12612
11167
|
throw new Error(
|
|
12613
11168
|
`Storage mutations rejected by server: ${message.reason}`
|
|
12614
11169
|
);
|
|
@@ -12707,11 +11262,11 @@ function createRoom(options, config) {
|
|
|
12707
11262
|
} else if (pendingFeedsRequests.has(requestId)) {
|
|
12708
11263
|
const pending = pendingFeedsRequests.get(requestId);
|
|
12709
11264
|
pendingFeedsRequests.delete(requestId);
|
|
12710
|
-
_optionalChain([pending, 'optionalAccess',
|
|
11265
|
+
_optionalChain([pending, 'optionalAccess', _263 => _263.reject, 'call', _264 => _264(err)]);
|
|
12711
11266
|
} else if (pendingFeedMessagesRequests.has(requestId)) {
|
|
12712
11267
|
const pending = pendingFeedMessagesRequests.get(requestId);
|
|
12713
11268
|
pendingFeedMessagesRequests.delete(requestId);
|
|
12714
|
-
_optionalChain([pending, 'optionalAccess',
|
|
11269
|
+
_optionalChain([pending, 'optionalAccess', _265 => _265.reject, 'call', _266 => _266(err)]);
|
|
12715
11270
|
}
|
|
12716
11271
|
eventHub.feeds.notify(message);
|
|
12717
11272
|
break;
|
|
@@ -12865,10 +11420,10 @@ function createRoom(options, config) {
|
|
|
12865
11420
|
timeoutId,
|
|
12866
11421
|
kind,
|
|
12867
11422
|
feedId,
|
|
12868
|
-
messageId: _optionalChain([options2, 'optionalAccess',
|
|
12869
|
-
expectedClientMessageId: _optionalChain([options2, 'optionalAccess',
|
|
11423
|
+
messageId: _optionalChain([options2, 'optionalAccess', _267 => _267.messageId]),
|
|
11424
|
+
expectedClientMessageId: _optionalChain([options2, 'optionalAccess', _268 => _268.expectedClientMessageId])
|
|
12870
11425
|
});
|
|
12871
|
-
if (kind === "add-message" && _optionalChain([options2, 'optionalAccess',
|
|
11426
|
+
if (kind === "add-message" && _optionalChain([options2, 'optionalAccess', _269 => _269.expectedClientMessageId]) === void 0) {
|
|
12872
11427
|
const q = _nullishCoalesce(pendingAddMessageFifoByFeed.get(feedId), () => ( []));
|
|
12873
11428
|
q.push(requestId);
|
|
12874
11429
|
pendingAddMessageFifoByFeed.set(feedId, q);
|
|
@@ -12919,10 +11474,10 @@ function createRoom(options, config) {
|
|
|
12919
11474
|
}
|
|
12920
11475
|
if (!matched) {
|
|
12921
11476
|
const q = pendingAddMessageFifoByFeed.get(message.feedId);
|
|
12922
|
-
const headId = _optionalChain([q, 'optionalAccess',
|
|
11477
|
+
const headId = _optionalChain([q, 'optionalAccess', _270 => _270[0]]);
|
|
12923
11478
|
if (headId !== void 0) {
|
|
12924
11479
|
const pending = pendingFeedMutations.get(headId);
|
|
12925
|
-
if (_optionalChain([pending, 'optionalAccess',
|
|
11480
|
+
if (_optionalChain([pending, 'optionalAccess', _271 => _271.kind]) === "add-message" && pending.expectedClientMessageId === void 0) {
|
|
12926
11481
|
settleFeedMutation(headId, "ok");
|
|
12927
11482
|
}
|
|
12928
11483
|
}
|
|
@@ -12958,7 +11513,7 @@ function createRoom(options, config) {
|
|
|
12958
11513
|
const unacknowledgedOps2 = [...context.unacknowledgedOps.values()];
|
|
12959
11514
|
createOrUpdateRootFromMessage(nodes);
|
|
12960
11515
|
applyAndSendOfflineOps(unacknowledgedOps2);
|
|
12961
|
-
_optionalChain([_resolveStoragePromise, 'optionalCall',
|
|
11516
|
+
_optionalChain([_resolveStoragePromise, 'optionalCall', _272 => _272()]);
|
|
12962
11517
|
notifyStorageStatus();
|
|
12963
11518
|
eventHub.storageDidLoad.notify();
|
|
12964
11519
|
}
|
|
@@ -12967,7 +11522,7 @@ function createRoom(options, config) {
|
|
|
12967
11522
|
if (!messages.some((msg) => msg.type === ClientMsgCode.FETCH_STORAGE)) {
|
|
12968
11523
|
messages.push({ type: ClientMsgCode.FETCH_STORAGE });
|
|
12969
11524
|
nodeMapBuffer.take();
|
|
12970
|
-
_optionalChain([stopwatch, 'optionalAccess',
|
|
11525
|
+
_optionalChain([stopwatch, 'optionalAccess', _273 => _273.start, 'call', _274 => _274()]);
|
|
12971
11526
|
}
|
|
12972
11527
|
}
|
|
12973
11528
|
function startLoadingStorage() {
|
|
@@ -13021,10 +11576,10 @@ function createRoom(options, config) {
|
|
|
13021
11576
|
const message = {
|
|
13022
11577
|
type: ClientMsgCode.FETCH_FEEDS,
|
|
13023
11578
|
requestId,
|
|
13024
|
-
cursor: _optionalChain([options2, 'optionalAccess',
|
|
13025
|
-
since: _optionalChain([options2, 'optionalAccess',
|
|
13026
|
-
limit: _optionalChain([options2, 'optionalAccess',
|
|
13027
|
-
metadata: _optionalChain([options2, 'optionalAccess',
|
|
11579
|
+
cursor: _optionalChain([options2, 'optionalAccess', _275 => _275.cursor]),
|
|
11580
|
+
since: _optionalChain([options2, 'optionalAccess', _276 => _276.since]),
|
|
11581
|
+
limit: _optionalChain([options2, 'optionalAccess', _277 => _277.limit]),
|
|
11582
|
+
metadata: _optionalChain([options2, 'optionalAccess', _278 => _278.metadata])
|
|
13028
11583
|
};
|
|
13029
11584
|
context.buffer.messages.push(message);
|
|
13030
11585
|
flushNowOrSoon();
|
|
@@ -13044,9 +11599,9 @@ function createRoom(options, config) {
|
|
|
13044
11599
|
type: ClientMsgCode.FETCH_FEED_MESSAGES,
|
|
13045
11600
|
requestId,
|
|
13046
11601
|
feedId,
|
|
13047
|
-
cursor: _optionalChain([options2, 'optionalAccess',
|
|
13048
|
-
since: _optionalChain([options2, 'optionalAccess',
|
|
13049
|
-
limit: _optionalChain([options2, 'optionalAccess',
|
|
11602
|
+
cursor: _optionalChain([options2, 'optionalAccess', _279 => _279.cursor]),
|
|
11603
|
+
since: _optionalChain([options2, 'optionalAccess', _280 => _280.since]),
|
|
11604
|
+
limit: _optionalChain([options2, 'optionalAccess', _281 => _281.limit])
|
|
13050
11605
|
};
|
|
13051
11606
|
context.buffer.messages.push(message);
|
|
13052
11607
|
flushNowOrSoon();
|
|
@@ -13065,8 +11620,8 @@ function createRoom(options, config) {
|
|
|
13065
11620
|
type: ClientMsgCode.ADD_FEED,
|
|
13066
11621
|
requestId,
|
|
13067
11622
|
feedId,
|
|
13068
|
-
metadata: _optionalChain([options2, 'optionalAccess',
|
|
13069
|
-
createdAt: _optionalChain([options2, 'optionalAccess',
|
|
11623
|
+
metadata: _optionalChain([options2, 'optionalAccess', _282 => _282.metadata]),
|
|
11624
|
+
createdAt: _optionalChain([options2, 'optionalAccess', _283 => _283.createdAt])
|
|
13070
11625
|
};
|
|
13071
11626
|
context.buffer.messages.push(message);
|
|
13072
11627
|
flushNowOrSoon();
|
|
@@ -13100,15 +11655,15 @@ function createRoom(options, config) {
|
|
|
13100
11655
|
function addFeedMessage(feedId, data, options2) {
|
|
13101
11656
|
const requestId = nanoid();
|
|
13102
11657
|
const promise = registerFeedMutation(requestId, "add-message", feedId, {
|
|
13103
|
-
expectedClientMessageId: _optionalChain([options2, 'optionalAccess',
|
|
11658
|
+
expectedClientMessageId: _optionalChain([options2, 'optionalAccess', _284 => _284.id])
|
|
13104
11659
|
});
|
|
13105
11660
|
const message = {
|
|
13106
11661
|
type: ClientMsgCode.ADD_FEED_MESSAGE,
|
|
13107
11662
|
requestId,
|
|
13108
11663
|
feedId,
|
|
13109
11664
|
data,
|
|
13110
|
-
id: _optionalChain([options2, 'optionalAccess',
|
|
13111
|
-
createdAt: _optionalChain([options2, 'optionalAccess',
|
|
11665
|
+
id: _optionalChain([options2, 'optionalAccess', _285 => _285.id]),
|
|
11666
|
+
createdAt: _optionalChain([options2, 'optionalAccess', _286 => _286.createdAt])
|
|
13112
11667
|
};
|
|
13113
11668
|
context.buffer.messages.push(message);
|
|
13114
11669
|
flushNowOrSoon();
|
|
@@ -13125,7 +11680,7 @@ function createRoom(options, config) {
|
|
|
13125
11680
|
feedId,
|
|
13126
11681
|
messageId,
|
|
13127
11682
|
data,
|
|
13128
|
-
updatedAt: _optionalChain([options2, 'optionalAccess',
|
|
11683
|
+
updatedAt: _optionalChain([options2, 'optionalAccess', _287 => _287.updatedAt])
|
|
13129
11684
|
};
|
|
13130
11685
|
context.buffer.messages.push(message);
|
|
13131
11686
|
flushNowOrSoon();
|
|
@@ -13150,15 +11705,14 @@ function createRoom(options, config) {
|
|
|
13150
11705
|
if (context.activeBatch) {
|
|
13151
11706
|
throw new Error("undo is not allowed during a batch");
|
|
13152
11707
|
}
|
|
13153
|
-
const
|
|
13154
|
-
if (
|
|
11708
|
+
const frames = context.undoStack.pop();
|
|
11709
|
+
if (frames === void 0) {
|
|
13155
11710
|
return;
|
|
13156
11711
|
}
|
|
13157
11712
|
context.pausedHistory = null;
|
|
13158
|
-
const result = applyLocalOps(
|
|
13159
|
-
context.redoStack.push({ id: item.id, frames: result.reverse });
|
|
13160
|
-
notifyPrivateHistory({ action: "undo", id: item.id });
|
|
11713
|
+
const result = applyLocalOps(frames);
|
|
13161
11714
|
notify(result.updates);
|
|
11715
|
+
context.redoStack.push(result.reverse);
|
|
13162
11716
|
onHistoryChange();
|
|
13163
11717
|
for (const op of result.opsToEmit) {
|
|
13164
11718
|
context.buffer.storageOperations.push(op);
|
|
@@ -13169,15 +11723,14 @@ function createRoom(options, config) {
|
|
|
13169
11723
|
if (context.activeBatch) {
|
|
13170
11724
|
throw new Error("redo is not allowed during a batch");
|
|
13171
11725
|
}
|
|
13172
|
-
const
|
|
13173
|
-
if (
|
|
11726
|
+
const frames = context.redoStack.pop();
|
|
11727
|
+
if (frames === void 0) {
|
|
13174
11728
|
return;
|
|
13175
11729
|
}
|
|
13176
11730
|
context.pausedHistory = null;
|
|
13177
|
-
const result = applyLocalOps(
|
|
13178
|
-
context.undoStack.push({ id: item.id, frames: result.reverse });
|
|
13179
|
-
notifyPrivateHistory({ action: "redo", id: item.id });
|
|
11731
|
+
const result = applyLocalOps(frames);
|
|
13180
11732
|
notify(result.updates);
|
|
11733
|
+
context.undoStack.push(result.reverse);
|
|
13181
11734
|
onHistoryChange();
|
|
13182
11735
|
for (const op of result.opsToEmit) {
|
|
13183
11736
|
context.buffer.storageOperations.push(op);
|
|
@@ -13187,8 +11740,6 @@ function createRoom(options, config) {
|
|
|
13187
11740
|
function clear() {
|
|
13188
11741
|
context.undoStack.length = 0;
|
|
13189
11742
|
context.redoStack.length = 0;
|
|
13190
|
-
notifyPrivateHistory({ action: "clear" });
|
|
13191
|
-
onHistoryChange();
|
|
13192
11743
|
}
|
|
13193
11744
|
function batch2(callback) {
|
|
13194
11745
|
if (context.activeBatch) {
|
|
@@ -13216,8 +11767,8 @@ function createRoom(options, config) {
|
|
|
13216
11767
|
if (currentBatch.scheduleHistoryResume) {
|
|
13217
11768
|
commitPausedHistoryToUndoStack();
|
|
13218
11769
|
}
|
|
13219
|
-
if (currentBatch.ops.length > 0
|
|
13220
|
-
|
|
11770
|
+
if (currentBatch.ops.length > 0) {
|
|
11771
|
+
context.redoStack.length = 0;
|
|
13221
11772
|
}
|
|
13222
11773
|
if (currentBatch.ops.length > 0) {
|
|
13223
11774
|
dispatchOps(currentBatch.ops);
|
|
@@ -13246,6 +11797,7 @@ function createRoom(options, config) {
|
|
|
13246
11797
|
}
|
|
13247
11798
|
commitPausedHistoryToUndoStack();
|
|
13248
11799
|
}
|
|
11800
|
+
let historyDisabled = 0;
|
|
13249
11801
|
function disableHistory(fn) {
|
|
13250
11802
|
const origUndo = context.undoStack;
|
|
13251
11803
|
const origRedo = context.redoStack;
|
|
@@ -13335,8 +11887,8 @@ function createRoom(options, config) {
|
|
|
13335
11887
|
async function getThreads(options2) {
|
|
13336
11888
|
return httpClient.getThreads({
|
|
13337
11889
|
roomId,
|
|
13338
|
-
query: _optionalChain([options2, 'optionalAccess',
|
|
13339
|
-
cursor: _optionalChain([options2, 'optionalAccess',
|
|
11890
|
+
query: _optionalChain([options2, 'optionalAccess', _288 => _288.query]),
|
|
11891
|
+
cursor: _optionalChain([options2, 'optionalAccess', _289 => _289.cursor])
|
|
13340
11892
|
});
|
|
13341
11893
|
}
|
|
13342
11894
|
async function getThread(threadId) {
|
|
@@ -13469,7 +12021,7 @@ function createRoom(options, config) {
|
|
|
13469
12021
|
function getSubscriptionSettings(options2) {
|
|
13470
12022
|
return httpClient.getSubscriptionSettings({
|
|
13471
12023
|
roomId,
|
|
13472
|
-
signal: _optionalChain([options2, 'optionalAccess',
|
|
12024
|
+
signal: _optionalChain([options2, 'optionalAccess', _290 => _290.signal])
|
|
13473
12025
|
});
|
|
13474
12026
|
}
|
|
13475
12027
|
function updateSubscriptionSettings(settings) {
|
|
@@ -13491,45 +12043,30 @@ function createRoom(options, config) {
|
|
|
13491
12043
|
{
|
|
13492
12044
|
[kInternal]: {
|
|
13493
12045
|
get presenceBuffer() {
|
|
13494
|
-
return deepClone(_nullishCoalesce(_optionalChain([context, 'access',
|
|
12046
|
+
return deepClone(_nullishCoalesce(_optionalChain([context, 'access', _291 => _291.buffer, 'access', _292 => _292.presenceUpdates, 'optionalAccess', _293 => _293.data]), () => ( null)));
|
|
13495
12047
|
},
|
|
13496
12048
|
// prettier-ignore
|
|
13497
12049
|
get undoStack() {
|
|
13498
|
-
return
|
|
13499
|
-
context.undoStack.map((item) => ({
|
|
13500
|
-
id: item.id,
|
|
13501
|
-
frames: item.frames
|
|
13502
|
-
}))
|
|
13503
|
-
);
|
|
13504
|
-
},
|
|
13505
|
-
// prettier-ignore
|
|
13506
|
-
get redoStack() {
|
|
13507
|
-
return structuredClone(
|
|
13508
|
-
context.redoStack.map((item) => ({
|
|
13509
|
-
id: item.id,
|
|
13510
|
-
frames: item.frames
|
|
13511
|
-
}))
|
|
13512
|
-
);
|
|
12050
|
+
return deepClone(context.undoStack);
|
|
13513
12051
|
},
|
|
13514
12052
|
// prettier-ignore
|
|
13515
12053
|
get nodeCount() {
|
|
13516
12054
|
return context.pool.nodes.size;
|
|
13517
12055
|
},
|
|
13518
12056
|
// prettier-ignore
|
|
13519
|
-
history: eventHub.privateHistory.observable,
|
|
13520
12057
|
getYjsProvider() {
|
|
13521
12058
|
return context.yjsProvider;
|
|
13522
12059
|
},
|
|
13523
12060
|
setYjsProvider(newProvider) {
|
|
13524
|
-
_optionalChain([context, 'access',
|
|
12061
|
+
_optionalChain([context, 'access', _294 => _294.yjsProvider, 'optionalAccess', _295 => _295.off, 'call', _296 => _296("status", yjsStatusDidChange)]);
|
|
13525
12062
|
context.yjsProvider = newProvider;
|
|
13526
|
-
_optionalChain([newProvider, 'optionalAccess',
|
|
12063
|
+
_optionalChain([newProvider, 'optionalAccess', _297 => _297.on, 'call', _298 => _298("status", yjsStatusDidChange)]);
|
|
13527
12064
|
context.yjsProviderDidChange.notify();
|
|
13528
12065
|
},
|
|
13529
12066
|
yjsProviderDidChange: context.yjsProviderDidChange.observable,
|
|
13530
12067
|
// send metadata when using a text editor
|
|
13531
12068
|
reportTextEditor,
|
|
13532
|
-
getPermissionMatrix: () => _optionalChain([context, 'access',
|
|
12069
|
+
getPermissionMatrix: () => _optionalChain([context, 'access', _299 => _299.dynamicSessionInfoSig, 'access', _300 => _300.get, 'call', _301 => _301(), 'optionalAccess', _302 => _302.permissionMatrix]),
|
|
13533
12070
|
// create a text mention when using a text editor
|
|
13534
12071
|
createTextMention,
|
|
13535
12072
|
// delete a text mention when using a text editor
|
|
@@ -13592,7 +12129,7 @@ ${dumpPool(
|
|
|
13592
12129
|
source.dispose();
|
|
13593
12130
|
}
|
|
13594
12131
|
eventHub.roomWillDestroy.notify();
|
|
13595
|
-
_optionalChain([context, 'access',
|
|
12132
|
+
_optionalChain([context, 'access', _303 => _303.yjsProvider, 'optionalAccess', _304 => _304.off, 'call', _305 => _305("status", yjsStatusDidChange)]);
|
|
13596
12133
|
syncSourceForStorage.destroy();
|
|
13597
12134
|
syncSourceForYjs.destroy();
|
|
13598
12135
|
uninstallBgTabSpy();
|
|
@@ -13756,7 +12293,7 @@ function makeClassicSubscribeFn(roomId, events, errorEvents) {
|
|
|
13756
12293
|
}
|
|
13757
12294
|
if (isLiveNode(first)) {
|
|
13758
12295
|
const node = first;
|
|
13759
|
-
if (_optionalChain([options, 'optionalAccess',
|
|
12296
|
+
if (_optionalChain([options, 'optionalAccess', _306 => _306.isDeep])) {
|
|
13760
12297
|
const storageCallback = second;
|
|
13761
12298
|
return subscribeToLiveStructureDeeply(node, storageCallback);
|
|
13762
12299
|
} else {
|
|
@@ -13846,8 +12383,8 @@ function createClient(options) {
|
|
|
13846
12383
|
const authManager = createAuthManager(options, (token) => {
|
|
13847
12384
|
currentUserId.set(() => token.uid);
|
|
13848
12385
|
});
|
|
13849
|
-
const fetchPolyfill = _optionalChain([clientOptions, 'access',
|
|
13850
|
-
_optionalChain([globalThis, 'access',
|
|
12386
|
+
const fetchPolyfill = _optionalChain([clientOptions, 'access', _307 => _307.polyfills, 'optionalAccess', _308 => _308.fetch]) || /* istanbul ignore next */
|
|
12387
|
+
_optionalChain([globalThis, 'access', _309 => _309.fetch, 'optionalAccess', _310 => _310.bind, 'call', _311 => _311(globalThis)]);
|
|
13851
12388
|
const httpClient = createApiClient({
|
|
13852
12389
|
baseUrl,
|
|
13853
12390
|
fetchPolyfill,
|
|
@@ -13864,7 +12401,7 @@ function createClient(options) {
|
|
|
13864
12401
|
delegates: {
|
|
13865
12402
|
createSocket: makeCreateSocketDelegateForAi(
|
|
13866
12403
|
baseUrl,
|
|
13867
|
-
_optionalChain([clientOptions, 'access',
|
|
12404
|
+
_optionalChain([clientOptions, 'access', _312 => _312.polyfills, 'optionalAccess', _313 => _313.WebSocket])
|
|
13868
12405
|
),
|
|
13869
12406
|
authenticate: async () => {
|
|
13870
12407
|
const resp = await authManager.getAuthValue({
|
|
@@ -13935,7 +12472,7 @@ function createClient(options) {
|
|
|
13935
12472
|
createSocket: makeCreateSocketDelegateForRoom(
|
|
13936
12473
|
roomId,
|
|
13937
12474
|
baseUrl,
|
|
13938
|
-
_optionalChain([clientOptions, 'access',
|
|
12475
|
+
_optionalChain([clientOptions, 'access', _314 => _314.polyfills, 'optionalAccess', _315 => _315.WebSocket])
|
|
13939
12476
|
),
|
|
13940
12477
|
authenticate: makeAuthDelegateForRoom(roomId, authManager)
|
|
13941
12478
|
})),
|
|
@@ -13957,7 +12494,7 @@ function createClient(options) {
|
|
|
13957
12494
|
const shouldConnect = _nullishCoalesce(options2.autoConnect, () => ( true));
|
|
13958
12495
|
if (shouldConnect) {
|
|
13959
12496
|
if (typeof atob === "undefined") {
|
|
13960
|
-
if (_optionalChain([clientOptions, 'access',
|
|
12497
|
+
if (_optionalChain([clientOptions, 'access', _316 => _316.polyfills, 'optionalAccess', _317 => _317.atob]) === void 0) {
|
|
13961
12498
|
throw new Error(
|
|
13962
12499
|
"You need to polyfill atob to use the client in your environment. Please follow the instructions at https://liveblocks.io/docs/errors/liveblocks-client/atob-polyfill"
|
|
13963
12500
|
);
|
|
@@ -13969,7 +12506,7 @@ function createClient(options) {
|
|
|
13969
12506
|
return leaseRoom(newRoomDetails);
|
|
13970
12507
|
}
|
|
13971
12508
|
function getRoom(roomId) {
|
|
13972
|
-
const room = _optionalChain([roomsById, 'access',
|
|
12509
|
+
const room = _optionalChain([roomsById, 'access', _318 => _318.get, 'call', _319 => _319(roomId), 'optionalAccess', _320 => _320.room]);
|
|
13973
12510
|
return room ? room : null;
|
|
13974
12511
|
}
|
|
13975
12512
|
function logout() {
|
|
@@ -13985,7 +12522,7 @@ function createClient(options) {
|
|
|
13985
12522
|
const batchedResolveUsers = new Batch(
|
|
13986
12523
|
async (batchedUserIds) => {
|
|
13987
12524
|
const userIds = batchedUserIds.flat();
|
|
13988
|
-
const users = await _optionalChain([resolveUsers, 'optionalCall',
|
|
12525
|
+
const users = await _optionalChain([resolveUsers, 'optionalCall', _321 => _321({ userIds })]);
|
|
13989
12526
|
warnOnceIf(
|
|
13990
12527
|
!resolveUsers,
|
|
13991
12528
|
"Set the resolveUsers option in createClient to specify user info."
|
|
@@ -14002,7 +12539,7 @@ function createClient(options) {
|
|
|
14002
12539
|
const batchedResolveRoomsInfo = new Batch(
|
|
14003
12540
|
async (batchedRoomIds) => {
|
|
14004
12541
|
const roomIds = batchedRoomIds.flat();
|
|
14005
|
-
const roomsInfo = await _optionalChain([resolveRoomsInfo, 'optionalCall',
|
|
12542
|
+
const roomsInfo = await _optionalChain([resolveRoomsInfo, 'optionalCall', _322 => _322({ roomIds })]);
|
|
14006
12543
|
warnOnceIf(
|
|
14007
12544
|
!resolveRoomsInfo,
|
|
14008
12545
|
"Set the resolveRoomsInfo option in createClient to specify room info."
|
|
@@ -14019,7 +12556,7 @@ function createClient(options) {
|
|
|
14019
12556
|
const batchedResolveGroupsInfo = new Batch(
|
|
14020
12557
|
async (batchedGroupIds) => {
|
|
14021
12558
|
const groupIds = batchedGroupIds.flat();
|
|
14022
|
-
const groupsInfo = await _optionalChain([resolveGroupsInfo, 'optionalCall',
|
|
12559
|
+
const groupsInfo = await _optionalChain([resolveGroupsInfo, 'optionalCall', _323 => _323({ groupIds })]);
|
|
14023
12560
|
warnOnceIf(
|
|
14024
12561
|
!resolveGroupsInfo,
|
|
14025
12562
|
"Set the resolveGroupsInfo option in createClient to specify group info."
|
|
@@ -14078,7 +12615,7 @@ function createClient(options) {
|
|
|
14078
12615
|
}
|
|
14079
12616
|
};
|
|
14080
12617
|
const win = typeof window !== "undefined" ? window : void 0;
|
|
14081
|
-
_optionalChain([win, 'optionalAccess',
|
|
12618
|
+
_optionalChain([win, 'optionalAccess', _324 => _324.addEventListener, 'call', _325 => _325("beforeunload", maybePreventClose)]);
|
|
14082
12619
|
}
|
|
14083
12620
|
async function getNotificationSettings(options2) {
|
|
14084
12621
|
const plainSettings = await httpClient.getNotificationSettings(options2);
|
|
@@ -14206,7 +12743,7 @@ var commentBodyElementsTypes = {
|
|
|
14206
12743
|
mention: "inline"
|
|
14207
12744
|
};
|
|
14208
12745
|
function traverseCommentBody(body, elementOrVisitor, possiblyVisitor) {
|
|
14209
|
-
if (!body || !_optionalChain([body, 'optionalAccess',
|
|
12746
|
+
if (!body || !_optionalChain([body, 'optionalAccess', _326 => _326.content])) {
|
|
14210
12747
|
return;
|
|
14211
12748
|
}
|
|
14212
12749
|
const element = typeof elementOrVisitor === "string" ? elementOrVisitor : void 0;
|
|
@@ -14216,13 +12753,13 @@ function traverseCommentBody(body, elementOrVisitor, possiblyVisitor) {
|
|
|
14216
12753
|
for (const block of body.content) {
|
|
14217
12754
|
if (type === "all" || type === "block") {
|
|
14218
12755
|
if (guard(block)) {
|
|
14219
|
-
_optionalChain([visitor, 'optionalCall',
|
|
12756
|
+
_optionalChain([visitor, 'optionalCall', _327 => _327(block)]);
|
|
14220
12757
|
}
|
|
14221
12758
|
}
|
|
14222
12759
|
if (type === "all" || type === "inline") {
|
|
14223
12760
|
for (const inline of block.children) {
|
|
14224
12761
|
if (guard(inline)) {
|
|
14225
|
-
_optionalChain([visitor, 'optionalCall',
|
|
12762
|
+
_optionalChain([visitor, 'optionalCall', _328 => _328(inline)]);
|
|
14226
12763
|
}
|
|
14227
12764
|
}
|
|
14228
12765
|
}
|
|
@@ -14392,7 +12929,7 @@ var stringifyCommentBodyPlainElements = {
|
|
|
14392
12929
|
text: ({ element }) => element.text,
|
|
14393
12930
|
link: ({ element }) => _nullishCoalesce(element.text, () => ( element.url)),
|
|
14394
12931
|
mention: ({ element, user, group }) => {
|
|
14395
|
-
return `@${_nullishCoalesce(_nullishCoalesce(_optionalChain([user, 'optionalAccess',
|
|
12932
|
+
return `@${_nullishCoalesce(_nullishCoalesce(_optionalChain([user, 'optionalAccess', _329 => _329.name]), () => ( _optionalChain([group, 'optionalAccess', _330 => _330.name]))), () => ( element.id))}`;
|
|
14396
12933
|
}
|
|
14397
12934
|
};
|
|
14398
12935
|
var stringifyCommentBodyHtmlElements = {
|
|
@@ -14422,7 +12959,7 @@ var stringifyCommentBodyHtmlElements = {
|
|
|
14422
12959
|
return html`<a href="${href}" target="_blank" rel="noopener noreferrer">${element.text ? html`${element.text}` : element.url}</a>`;
|
|
14423
12960
|
},
|
|
14424
12961
|
mention: ({ element, user, group }) => {
|
|
14425
|
-
return html`<span data-mention>@${_optionalChain([user, 'optionalAccess',
|
|
12962
|
+
return html`<span data-mention>@${_optionalChain([user, 'optionalAccess', _331 => _331.name]) ? html`${_optionalChain([user, 'optionalAccess', _332 => _332.name])}` : _optionalChain([group, 'optionalAccess', _333 => _333.name]) ? html`${_optionalChain([group, 'optionalAccess', _334 => _334.name])}` : element.id}</span>`;
|
|
14426
12963
|
}
|
|
14427
12964
|
};
|
|
14428
12965
|
var stringifyCommentBodyMarkdownElements = {
|
|
@@ -14452,20 +12989,20 @@ var stringifyCommentBodyMarkdownElements = {
|
|
|
14452
12989
|
return markdown`[${_nullishCoalesce(element.text, () => ( element.url))}](${href})`;
|
|
14453
12990
|
},
|
|
14454
12991
|
mention: ({ element, user, group }) => {
|
|
14455
|
-
return markdown`@${_nullishCoalesce(_nullishCoalesce(_optionalChain([user, 'optionalAccess',
|
|
12992
|
+
return markdown`@${_nullishCoalesce(_nullishCoalesce(_optionalChain([user, 'optionalAccess', _335 => _335.name]), () => ( _optionalChain([group, 'optionalAccess', _336 => _336.name]))), () => ( element.id))}`;
|
|
14456
12993
|
}
|
|
14457
12994
|
};
|
|
14458
12995
|
async function stringifyCommentBody(body, options) {
|
|
14459
|
-
const format = _nullishCoalesce(_optionalChain([options, 'optionalAccess',
|
|
14460
|
-
const separator = _nullishCoalesce(_optionalChain([options, 'optionalAccess',
|
|
12996
|
+
const format = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _337 => _337.format]), () => ( "plain"));
|
|
12997
|
+
const separator = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _338 => _338.separator]), () => ( (format === "markdown" ? "\n\n" : "\n")));
|
|
14461
12998
|
const elements = {
|
|
14462
12999
|
...format === "html" ? stringifyCommentBodyHtmlElements : format === "markdown" ? stringifyCommentBodyMarkdownElements : stringifyCommentBodyPlainElements,
|
|
14463
|
-
..._optionalChain([options, 'optionalAccess',
|
|
13000
|
+
..._optionalChain([options, 'optionalAccess', _339 => _339.elements])
|
|
14464
13001
|
};
|
|
14465
13002
|
const { users: resolvedUsers, groups: resolvedGroupsInfo } = await resolveMentionsInCommentBody(
|
|
14466
13003
|
body,
|
|
14467
|
-
_optionalChain([options, 'optionalAccess',
|
|
14468
|
-
_optionalChain([options, 'optionalAccess',
|
|
13004
|
+
_optionalChain([options, 'optionalAccess', _340 => _340.resolveUsers]),
|
|
13005
|
+
_optionalChain([options, 'optionalAccess', _341 => _341.resolveGroupsInfo])
|
|
14469
13006
|
);
|
|
14470
13007
|
const blocks = body.content.flatMap((block, blockIndex) => {
|
|
14471
13008
|
switch (block.type) {
|
|
@@ -14547,12 +13084,6 @@ function toPlainLson(lson) {
|
|
|
14547
13084
|
liveblocksType: "LiveList",
|
|
14548
13085
|
data: [...lson].map((item) => toPlainLson(item))
|
|
14549
13086
|
};
|
|
14550
|
-
} else if (lson instanceof LiveText) {
|
|
14551
|
-
return {
|
|
14552
|
-
liveblocksType: "LiveText",
|
|
14553
|
-
data: lson.toJSON(),
|
|
14554
|
-
version: lson.version
|
|
14555
|
-
};
|
|
14556
13087
|
} else if (lson instanceof LiveFile) {
|
|
14557
13088
|
return {
|
|
14558
13089
|
liveblocksType: "LiveFile",
|
|
@@ -14611,9 +13142,9 @@ function makePoller(callback, intervalMs, options) {
|
|
|
14611
13142
|
const startTime = performance.now();
|
|
14612
13143
|
const doc = typeof document !== "undefined" ? document : void 0;
|
|
14613
13144
|
const win = typeof window !== "undefined" ? window : void 0;
|
|
14614
|
-
const maxStaleTimeMs = _nullishCoalesce(_optionalChain([options, 'optionalAccess',
|
|
13145
|
+
const maxStaleTimeMs = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _342 => _342.maxStaleTimeMs]), () => ( Number.POSITIVE_INFINITY));
|
|
14615
13146
|
const context = {
|
|
14616
|
-
inForeground: _optionalChain([doc, 'optionalAccess',
|
|
13147
|
+
inForeground: _optionalChain([doc, 'optionalAccess', _343 => _343.visibilityState]) !== "hidden",
|
|
14617
13148
|
lastSuccessfulPollAt: startTime,
|
|
14618
13149
|
count: 0,
|
|
14619
13150
|
backoff: 0
|
|
@@ -14694,11 +13225,11 @@ function makePoller(callback, intervalMs, options) {
|
|
|
14694
13225
|
pollNowIfStale();
|
|
14695
13226
|
}
|
|
14696
13227
|
function onVisibilityChange() {
|
|
14697
|
-
setInForeground(_optionalChain([doc, 'optionalAccess',
|
|
13228
|
+
setInForeground(_optionalChain([doc, 'optionalAccess', _344 => _344.visibilityState]) !== "hidden");
|
|
14698
13229
|
}
|
|
14699
|
-
_optionalChain([doc, 'optionalAccess',
|
|
14700
|
-
_optionalChain([win, 'optionalAccess',
|
|
14701
|
-
_optionalChain([win, 'optionalAccess',
|
|
13230
|
+
_optionalChain([doc, 'optionalAccess', _345 => _345.addEventListener, 'call', _346 => _346("visibilitychange", onVisibilityChange)]);
|
|
13231
|
+
_optionalChain([win, 'optionalAccess', _347 => _347.addEventListener, 'call', _348 => _348("online", onVisibilityChange)]);
|
|
13232
|
+
_optionalChain([win, 'optionalAccess', _349 => _349.addEventListener, 'call', _350 => _350("focus", pollNowIfStale)]);
|
|
14702
13233
|
fsm.start();
|
|
14703
13234
|
return {
|
|
14704
13235
|
inc,
|
|
@@ -14847,9 +13378,5 @@ detectDupes(PKG_NAME, PKG_VERSION, PKG_FORMAT);
|
|
|
14847
13378
|
|
|
14848
13379
|
|
|
14849
13380
|
|
|
14850
|
-
|
|
14851
|
-
|
|
14852
|
-
|
|
14853
|
-
|
|
14854
|
-
exports.ClientMsgCode = ClientMsgCode; exports.CrdtType = CrdtType; exports.DefaultMap = DefaultMap; exports.Deque = Deque; exports.DerivedSignal = DerivedSignal; exports.FeedRequestErrorCode = FeedRequestErrorCode; exports.HttpError = HttpError; exports.LiveFile = LiveFile; exports.LiveList = LiveList; exports.LiveMap = LiveMap; exports.LiveObject = LiveObject; exports.LiveText = LiveText; exports.LiveblocksError = LiveblocksError; exports.MENTION_CHARACTER = MENTION_CHARACTER; exports.MutableSignal = MutableSignal; exports.OpCode = OpCode; exports.Permission = Permission; exports.Promise_withResolvers = Promise_withResolvers; exports.ServerMsgCode = ServerMsgCode; exports.Signal = Signal; exports.SortedList = SortedList; exports.TextEditorType = TextEditorType; exports.WebsocketCloseCodes = WebsocketCloseCodes; exports.applyLiveTextOperations = applyLiveTextOperations; exports.asPos = asPos; exports.assert = assert; exports.assertNever = assertNever; exports.autoRetry = autoRetry; exports.b64decode = b64decode; exports.batch = batch; exports.checkBounds = checkBounds; exports.chunk = chunk; exports.cloneLson = cloneLson; exports.compactNodesToNodeStream = compactNodesToNodeStream; exports.compactObject = compactObject; exports.console = fancy_console_exports; exports.convertToCommentData = convertToCommentData; exports.convertToCommentUserReaction = convertToCommentUserReaction; exports.convertToGroupData = convertToGroupData; exports.convertToInboxNotificationData = convertToInboxNotificationData; exports.convertToSubscriptionData = convertToSubscriptionData; exports.convertToThreadData = convertToThreadData; exports.convertToUserSubscriptionData = convertToUserSubscriptionData; exports.createClient = createClient; exports.createCommentAttachmentId = createCommentAttachmentId; exports.createCommentId = createCommentId; exports.createInboxNotificationId = createInboxNotificationId; exports.createManagedPool = createManagedPool; exports.createNotificationSettings = createNotificationSettings; exports.createStorageFileId = createStorageFileId; exports.createThreadId = createThreadId; exports.deepLiveify = deepLiveify; exports.defineAiTool = defineAiTool; exports.deprecate = deprecate; exports.deprecateIf = deprecateIf; exports.detectDupes = detectDupes; exports.entries = entries; exports.errorIf = errorIf; exports.findLastIndex = findLastIndex; exports.freeze = freeze; exports.generateUrl = generateUrl; exports.getLiveFileId = getLiveFileId; exports.getMentionsFromCommentBody = getMentionsFromCommentBody; exports.getSubscriptionKey = getSubscriptionKey; exports.hasPermissionAccess = hasPermissionAccess; exports.html = html; exports.htmlSafe = htmlSafe; exports.isCommentBodyLink = isCommentBodyLink; exports.isCommentBodyMention = isCommentBodyMention; exports.isCommentBodyText = isCommentBodyText; exports.isFileStorageNode = isFileStorageNode; exports.isJsonArray = isJsonArray; exports.isJsonObject = isJsonObject; exports.isJsonScalar = isJsonScalar; exports.isListStorageNode = isListStorageNode; exports.isLiveNode = isLiveNode; exports.isMapStorageNode = isMapStorageNode; exports.isNotificationChannelEnabled = isNotificationChannelEnabled; exports.isNumberOperator = isNumberOperator; exports.isObjectStorageNode = isObjectStorageNode; exports.isPlainObject = isPlainObject; exports.isRegisterStorageNode = isRegisterStorageNode; exports.isRootStorageNode = isRootStorageNode; exports.isStartsWithOperator = isStartsWithOperator; exports.isTextStorageNode = isTextStorageNode; exports.isUrl = isUrl; exports.kInternal = kInternal; exports.keys = keys; exports.makeAbortController = makeAbortController; exports.makeEventSource = makeEventSource; exports.makePoller = makePoller; exports.makePosition = makePosition; exports.mapValues = mapValues; exports.memoizeOnSuccess = memoizeOnSuccess; exports.mergeRoomPermissionScopes = mergeRoomPermissionScopes; exports.nanoid = nanoid; exports.nn = nn; exports.nodeStreamToCompactNodes = nodeStreamToCompactNodes; exports.normalizeRoomAccesses = normalizeRoomAccesses; exports.normalizeRoomPermissions = normalizeRoomPermissions; exports.normalizeUpdateRoomAccesses = normalizeUpdateRoomAccesses; exports.objectToQuery = objectToQuery; exports.patchNotificationSettings = patchNotificationSettings; exports.permissionMatrixFromScopes = permissionMatrixFromScopes; exports.raise = raise; exports.resolveMentionsInCommentBody = resolveMentionsInCommentBody; exports.sanitizeUrl = sanitizeUrl; exports.shallow = shallow; exports.shallow2 = shallow2; exports.stableStringify = stableStringify; exports.stringifyCommentBody = stringifyCommentBody; exports.throwUsageError = throwUsageError; exports.toPlainLson = toPlainLson; exports.transformTextOperations = transformTextOperations; exports.tryParseJson = tryParseJson; exports.url = url; exports.urljoin = urljoin; exports.validatePermissionsSet = validatePermissionsSet; exports.wait = wait; exports.warnOnce = warnOnce; exports.warnOnceIf = warnOnceIf; exports.withTimeout = withTimeout;
|
|
13381
|
+
exports.ClientMsgCode = ClientMsgCode; exports.CrdtType = CrdtType; exports.DefaultMap = DefaultMap; exports.Deque = Deque; exports.DerivedSignal = DerivedSignal; exports.FeedRequestErrorCode = FeedRequestErrorCode; exports.HttpError = HttpError; exports.LiveFile = LiveFile; exports.LiveList = LiveList; exports.LiveMap = LiveMap; exports.LiveObject = LiveObject; exports.LiveblocksError = LiveblocksError; exports.MENTION_CHARACTER = MENTION_CHARACTER; exports.MutableSignal = MutableSignal; exports.OpCode = OpCode; exports.Permission = Permission; exports.Promise_withResolvers = Promise_withResolvers; exports.ServerMsgCode = ServerMsgCode; exports.Signal = Signal; exports.SortedList = SortedList; exports.TextEditorType = TextEditorType; exports.WebsocketCloseCodes = WebsocketCloseCodes; exports.asPos = asPos; exports.assert = assert; exports.assertNever = assertNever; exports.autoRetry = autoRetry; exports.b64decode = b64decode; exports.batch = batch; exports.checkBounds = checkBounds; exports.chunk = chunk; exports.cloneLson = cloneLson; exports.compactNodesToNodeStream = compactNodesToNodeStream; exports.compactObject = compactObject; exports.console = fancy_console_exports; exports.convertToCommentData = convertToCommentData; exports.convertToCommentUserReaction = convertToCommentUserReaction; exports.convertToGroupData = convertToGroupData; exports.convertToInboxNotificationData = convertToInboxNotificationData; exports.convertToSubscriptionData = convertToSubscriptionData; exports.convertToThreadData = convertToThreadData; exports.convertToUserSubscriptionData = convertToUserSubscriptionData; exports.createClient = createClient; exports.createCommentAttachmentId = createCommentAttachmentId; exports.createCommentId = createCommentId; exports.createInboxNotificationId = createInboxNotificationId; exports.createManagedPool = createManagedPool; exports.createNotificationSettings = createNotificationSettings; exports.createStorageFileId = createStorageFileId; exports.createThreadId = createThreadId; exports.deepLiveify = deepLiveify; exports.defineAiTool = defineAiTool; exports.deprecate = deprecate; exports.deprecateIf = deprecateIf; exports.detectDupes = detectDupes; exports.entries = entries; exports.errorIf = errorIf; exports.findLastIndex = findLastIndex; exports.freeze = freeze; exports.generateUrl = generateUrl; exports.getLiveFileId = getLiveFileId; exports.getMentionsFromCommentBody = getMentionsFromCommentBody; exports.getSubscriptionKey = getSubscriptionKey; exports.hasPermissionAccess = hasPermissionAccess; exports.html = html; exports.htmlSafe = htmlSafe; exports.isCommentBodyLink = isCommentBodyLink; exports.isCommentBodyMention = isCommentBodyMention; exports.isCommentBodyText = isCommentBodyText; exports.isFileStorageNode = isFileStorageNode; exports.isJsonArray = isJsonArray; exports.isJsonObject = isJsonObject; exports.isJsonScalar = isJsonScalar; exports.isListStorageNode = isListStorageNode; exports.isLiveNode = isLiveNode; exports.isMapStorageNode = isMapStorageNode; exports.isNotificationChannelEnabled = isNotificationChannelEnabled; exports.isNumberOperator = isNumberOperator; exports.isObjectStorageNode = isObjectStorageNode; exports.isPlainObject = isPlainObject; exports.isRegisterStorageNode = isRegisterStorageNode; exports.isRootStorageNode = isRootStorageNode; exports.isStartsWithOperator = isStartsWithOperator; exports.isUrl = isUrl; exports.kInternal = kInternal; exports.keys = keys; exports.makeAbortController = makeAbortController; exports.makeEventSource = makeEventSource; exports.makePoller = makePoller; exports.makePosition = makePosition; exports.mapValues = mapValues; exports.memoizeOnSuccess = memoizeOnSuccess; exports.mergeRoomPermissionScopes = mergeRoomPermissionScopes; exports.nanoid = nanoid; exports.nn = nn; exports.nodeStreamToCompactNodes = nodeStreamToCompactNodes; exports.normalizeRoomAccesses = normalizeRoomAccesses; exports.normalizeRoomPermissions = normalizeRoomPermissions; exports.normalizeUpdateRoomAccesses = normalizeUpdateRoomAccesses; exports.objectToQuery = objectToQuery; exports.patchNotificationSettings = patchNotificationSettings; exports.permissionMatrixFromScopes = permissionMatrixFromScopes; exports.raise = raise; exports.resolveMentionsInCommentBody = resolveMentionsInCommentBody; exports.sanitizeUrl = sanitizeUrl; exports.shallow = shallow; exports.shallow2 = shallow2; exports.stableStringify = stableStringify; exports.stringifyCommentBody = stringifyCommentBody; exports.throwUsageError = throwUsageError; exports.toPlainLson = toPlainLson; exports.tryParseJson = tryParseJson; exports.url = url; exports.urljoin = urljoin; exports.validatePermissionsSet = validatePermissionsSet; exports.wait = wait; exports.warnOnce = warnOnce; exports.warnOnceIf = warnOnceIf; exports.withTimeout = withTimeout;
|
|
14855
13382
|
//# sourceMappingURL=index.cjs.map
|