@liveblocks/core 3.23.1-exp3 → 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 -1869
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +273 -620
- package/dist/index.d.ts +273 -620
- package/dist/index.js +295 -1797
- 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,1380 +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 normalizeLiveTextOperations(data, operations) {
|
|
9742
|
-
let shadow = dataToSegments(data);
|
|
9743
|
-
const normalized = [];
|
|
9744
|
-
for (const operation of operations) {
|
|
9745
|
-
const text = shadow.map((segment) => segment.text).join("");
|
|
9746
|
-
let normalizedOperation;
|
|
9747
|
-
if (operation.type === "insert") {
|
|
9748
|
-
normalizedOperation = {
|
|
9749
|
-
...operation,
|
|
9750
|
-
index: clipIndexToCodePointBoundary(text, operation.index)
|
|
9751
|
-
};
|
|
9752
|
-
} else {
|
|
9753
|
-
const range = clipRangeToCodePointBoundaries(
|
|
9754
|
-
text,
|
|
9755
|
-
operation.index,
|
|
9756
|
-
operation.length
|
|
9757
|
-
);
|
|
9758
|
-
normalizedOperation = {
|
|
9759
|
-
...operation,
|
|
9760
|
-
index: range.index,
|
|
9761
|
-
length: range.length
|
|
9762
|
-
};
|
|
9763
|
-
}
|
|
9764
|
-
normalized.push(normalizedOperation);
|
|
9765
|
-
shadow = applyTextOperationsToSegments(shadow, [normalizedOperation]);
|
|
9766
|
-
}
|
|
9767
|
-
return normalized;
|
|
9768
|
-
}
|
|
9769
|
-
function invertTextOperations(segments, ops) {
|
|
9770
|
-
let shadow = [...segments];
|
|
9771
|
-
const reverse = [];
|
|
9772
|
-
for (const op of ops) {
|
|
9773
|
-
if (op.type === "insert") {
|
|
9774
|
-
shadow = applyInsert(shadow, op.index, op.text, op.attributes);
|
|
9775
|
-
reverse.unshift({
|
|
9776
|
-
type: "delete",
|
|
9777
|
-
index: op.index,
|
|
9778
|
-
length: op.text.length
|
|
9779
|
-
});
|
|
9780
|
-
} else if (op.type === "delete") {
|
|
9781
|
-
const deletedSegments = extractDeletedSegments(
|
|
9782
|
-
shadow,
|
|
9783
|
-
op.index,
|
|
9784
|
-
op.length
|
|
9785
|
-
);
|
|
9786
|
-
shadow = applyDelete(shadow, op.index, op.length).segments;
|
|
9787
|
-
const inserts = [];
|
|
9788
|
-
let insertIndex = op.index;
|
|
9789
|
-
for (const segment of deletedSegments) {
|
|
9790
|
-
inserts.push({
|
|
9791
|
-
type: "insert",
|
|
9792
|
-
index: insertIndex,
|
|
9793
|
-
text: segment.text,
|
|
9794
|
-
attributes: segment.attributes
|
|
9795
|
-
});
|
|
9796
|
-
insertIndex += segment.text.length;
|
|
9797
|
-
}
|
|
9798
|
-
for (let index = inserts.length - 1; index >= 0; index--) {
|
|
9799
|
-
reverse.unshift(inserts[index]);
|
|
9800
|
-
}
|
|
9801
|
-
} else {
|
|
9802
|
-
const inverse = formatReverseOperations(
|
|
9803
|
-
shadow,
|
|
9804
|
-
op.index,
|
|
9805
|
-
op.length,
|
|
9806
|
-
op.attributes
|
|
9807
|
-
);
|
|
9808
|
-
shadow = applyFormat(shadow, op.index, op.length, op.attributes);
|
|
9809
|
-
reverse.unshift(...inverse.reverse());
|
|
9810
|
-
}
|
|
9811
|
-
}
|
|
9812
|
-
return reverse;
|
|
9813
|
-
}
|
|
9814
|
-
|
|
9815
|
-
// src/crdts/LiveText.ts
|
|
9816
|
-
var ACCEPTED_OPS_HISTORY_LIMIT = 1e3;
|
|
9817
|
-
var LiveText = class _LiveText extends AbstractCrdt {
|
|
9818
|
-
/** The local document: #confirmed ⊕ #inFlightOps ⊕ #queuedOps. */
|
|
9819
|
-
#segments;
|
|
9820
|
-
/** The server-confirmed document (only authoritative ops applied). */
|
|
9821
|
-
#confirmed;
|
|
9822
|
-
#version;
|
|
9823
|
-
/** The op currently awaiting server acknowledgement (at most one). */
|
|
9824
|
-
#inFlightOpId;
|
|
9825
|
-
/** Its ops, continuously re-expressed against current server state. */
|
|
9826
|
-
#inFlightOps = [];
|
|
9827
|
-
/** Local edits made while an op is in flight; sent after the ack. */
|
|
9828
|
-
#queuedOps = [];
|
|
9829
|
-
#acceptedOps = [];
|
|
9830
|
-
/**
|
|
9831
|
-
* Creates a new LiveText document.
|
|
9832
|
-
*
|
|
9833
|
-
* @param textOrData Initial plain text, or an array of `[text]` /
|
|
9834
|
-
* `[text, attributes]` segments. Defaults to an empty document.
|
|
9835
|
-
*
|
|
9836
|
-
* @example
|
|
9837
|
-
* new LiveText();
|
|
9838
|
-
* new LiveText("Hello world");
|
|
9839
|
-
* new LiveText([["Hello ", { bold: true }], ["world"]]);
|
|
9840
|
-
*/
|
|
9841
|
-
constructor(textOrData = "", version = 0) {
|
|
9842
|
-
super();
|
|
9843
|
-
this.#segments = typeof textOrData === "string" ? textOrData.length === 0 ? [] : [{ text: textOrData }] : dataToSegments(textOrData);
|
|
9844
|
-
this.#confirmed = [...this.#segments];
|
|
9845
|
-
this.#version = version;
|
|
9846
|
-
Object.assign(this[kInternal], {
|
|
9847
|
-
encodeIndex: (localIndex) => this.#encodeIndex(localIndex),
|
|
9848
|
-
decodeIndex: (index, fromVersion) => this.#decodeIndex(index, fromVersion)
|
|
9849
|
-
});
|
|
9850
|
-
}
|
|
9851
|
-
get version() {
|
|
9852
|
-
return this.#version;
|
|
9853
|
-
}
|
|
9854
|
-
get length() {
|
|
9855
|
-
return textLength(this.#segments);
|
|
9856
|
-
}
|
|
9857
|
-
/** @internal */
|
|
9858
|
-
static _deserialize([id, item], _parentToChildren, pool) {
|
|
9859
|
-
const text = new _LiveText(item.data, item.version);
|
|
9860
|
-
text._attach(id, pool);
|
|
9861
|
-
return text;
|
|
9862
|
-
}
|
|
9863
|
-
/** @internal */
|
|
9864
|
-
_toOps(parentId, parentKey) {
|
|
9865
|
-
if (this._id === void 0) {
|
|
9866
|
-
throw new Error("Cannot serialize LiveText if it is not attached");
|
|
9867
|
-
}
|
|
9868
|
-
return [
|
|
9869
|
-
{
|
|
9870
|
-
type: OpCode.CREATE_TEXT,
|
|
9871
|
-
id: this._id,
|
|
9872
|
-
parentId,
|
|
9873
|
-
parentKey,
|
|
9874
|
-
data: this.toJSON(),
|
|
9875
|
-
version: this.#version
|
|
9876
|
-
}
|
|
9877
|
-
];
|
|
9878
|
-
}
|
|
9879
|
-
/** @internal */
|
|
9880
|
-
_serialize() {
|
|
9881
|
-
if (this.parent.type !== "HasParent") {
|
|
9882
|
-
throw new Error("Cannot serialize LiveText if parent is missing");
|
|
9883
|
-
}
|
|
9884
|
-
return {
|
|
9885
|
-
type: CrdtType.TEXT,
|
|
9886
|
-
parentId: nn(this.parent.node._id, "Parent node expected to have ID"),
|
|
9887
|
-
parentKey: this.parent.key,
|
|
9888
|
-
data: this.toJSON(),
|
|
9889
|
-
version: this.#version
|
|
9890
|
-
};
|
|
9891
|
-
}
|
|
9892
|
-
/** @internal */
|
|
9893
|
-
_attachChild(_op) {
|
|
9894
|
-
throw new Error("LiveText cannot contain child nodes");
|
|
9895
|
-
}
|
|
9896
|
-
/** @internal */
|
|
9897
|
-
_detachChild(_crdt) {
|
|
9898
|
-
throw new Error("LiveText cannot contain child nodes");
|
|
9899
|
-
}
|
|
9900
|
-
/** @internal */
|
|
9901
|
-
_apply(op, source) {
|
|
9902
|
-
if (op.type !== OpCode.UPDATE_TEXT) {
|
|
9903
|
-
return super._apply(op, source);
|
|
9904
|
-
}
|
|
9905
|
-
if (source.origin === "local" && source.optimistic) {
|
|
9906
|
-
return this.#applyLocal(op, toUpdateSource(source));
|
|
9907
|
-
}
|
|
9908
|
-
if (op.opId !== void 0 && op.opId === this.#inFlightOpId) {
|
|
9909
|
-
return this.#applyAck(op, toUpdateSource(source));
|
|
9910
|
-
}
|
|
9911
|
-
if (op.opId !== void 0 && this.#acceptedOps.some((entry) => entry.opId === op.opId)) {
|
|
9912
|
-
this.#version = Math.max(this.#version, _nullishCoalesce(op.version, () => ( op.baseVersion + 1)));
|
|
9913
|
-
return { modified: false };
|
|
9914
|
-
}
|
|
9915
|
-
return this.#applyRemote(op, toUpdateSource(source));
|
|
9916
|
-
}
|
|
9917
|
-
/**
|
|
9918
|
-
* Inserts text at the given index.
|
|
9919
|
-
*
|
|
9920
|
-
* @param index Character index at which to insert. Values outside the
|
|
9921
|
-
* document range are clipped.
|
|
9922
|
-
* @param text Text to insert.
|
|
9923
|
-
* @param attributes Optional inline attributes for the inserted text.
|
|
9924
|
-
*
|
|
9925
|
-
* @example
|
|
9926
|
-
* const text = new LiveText("Hello");
|
|
9927
|
-
* text.insert(5, " world");
|
|
9928
|
-
* text.insert(0, "Say: ", { italic: true });
|
|
9929
|
-
*/
|
|
9930
|
-
insert(index, text, attributes) {
|
|
9931
|
-
const clippedIndex = clipIndexToCodePointBoundary(this.toString(), index);
|
|
9932
|
-
this.#dispatch([{ type: "insert", index: clippedIndex, text, attributes }]);
|
|
9933
|
-
}
|
|
9934
|
-
/**
|
|
9935
|
-
* Deletes `length` characters starting at `index`.
|
|
9936
|
-
*
|
|
9937
|
-
* @example
|
|
9938
|
-
* const text = new LiveText("Hello world");
|
|
9939
|
-
* text.delete(5, 6); // "Hello"
|
|
9940
|
-
*/
|
|
9941
|
-
delete(index, length) {
|
|
9942
|
-
const clipped = clipRangeToCodePointBoundaries(
|
|
9943
|
-
this.toString(),
|
|
9944
|
-
index,
|
|
9945
|
-
length
|
|
9946
|
-
);
|
|
9947
|
-
if (clipped.length === 0) {
|
|
9948
|
-
return;
|
|
9949
|
-
}
|
|
9950
|
-
this.#dispatch([
|
|
9951
|
-
{ type: "delete", index: clipped.index, length: clipped.length }
|
|
9952
|
-
]);
|
|
9953
|
-
}
|
|
9954
|
-
/**
|
|
9955
|
-
* Replaces a range of text with new text.
|
|
9956
|
-
*
|
|
9957
|
-
* @example
|
|
9958
|
-
* const text = new LiveText("Hello world");
|
|
9959
|
-
* text.replace(0, 5, "Hi"); // "Hi world"
|
|
9960
|
-
*/
|
|
9961
|
-
replace(index, length, text, attributes) {
|
|
9962
|
-
const clipped = clipRangeToCodePointBoundaries(
|
|
9963
|
-
this.toString(),
|
|
9964
|
-
index,
|
|
9965
|
-
length
|
|
9966
|
-
);
|
|
9967
|
-
const ops = [];
|
|
9968
|
-
if (clipped.length > 0) {
|
|
9969
|
-
ops.push({
|
|
9970
|
-
type: "delete",
|
|
9971
|
-
index: clipped.index,
|
|
9972
|
-
length: clipped.length
|
|
9973
|
-
});
|
|
9974
|
-
}
|
|
9975
|
-
if (text.length > 0) {
|
|
9976
|
-
ops.push({ type: "insert", index: clipped.index, text, attributes });
|
|
9977
|
-
}
|
|
9978
|
-
this.#dispatch(ops);
|
|
9979
|
-
}
|
|
9980
|
-
/**
|
|
9981
|
-
* Encode a local-document index (an offset into this LiveText's current
|
|
9982
|
-
* #segments, which CodeMirror or any consumer mirrors as its document)
|
|
9983
|
-
* into server-confirmed coordinates suitable for broadcasting to peers via
|
|
9984
|
-
* presence or any other side channel.
|
|
9985
|
-
*
|
|
9986
|
-
* The returned index is in this LiveText's current #confirmed coordinates
|
|
9987
|
-
* — that is, with this client's local pending ops inverse-mapped out.
|
|
9988
|
-
* Pair it with the current {@link LiveText.version} when sending so the
|
|
9989
|
-
* receiver can call {@link PrivateLiveTextApi.decodeIndex} to land the
|
|
9990
|
-
* position in their own local document coordinates regardless of their
|
|
9991
|
-
* private pending ops.
|
|
9992
|
-
*
|
|
9993
|
-
* Index ambiguity at boundaries is resolved by an inverse-of-forward
|
|
9994
|
-
* convention: a position at or before a local insertion is reported as
|
|
9995
|
-
* the position right before the insertion in #confirmed; a position past
|
|
9996
|
-
* the insertion shifts left by the insertion's length. Positions inside
|
|
9997
|
-
* an own-pending insertion collapse to the insertion point.
|
|
9998
|
-
*/
|
|
9999
|
-
#encodeIndex(localIndex) {
|
|
10000
|
-
let mapped = Math.max(0, Math.min(localIndex, this.length));
|
|
10001
|
-
mapped = inverseMapTextIndexThroughOperations(mapped, this.#queuedOps);
|
|
10002
|
-
mapped = inverseMapTextIndexThroughOperations(mapped, this.#inFlightOps);
|
|
10003
|
-
return mapped;
|
|
10004
|
-
}
|
|
10005
|
-
/**
|
|
10006
|
-
* Decode an `(index, fromVersion)` pair produced by
|
|
10007
|
-
* {@link PrivateLiveTextApi.encodeIndex} — typically on a peer — into an
|
|
10008
|
-
* offset in this LiveText's current local document (an index suitable for
|
|
10009
|
-
* placing a CodeMirror marker, an annotation anchor, or anything else that
|
|
10010
|
-
* lives over #segments).
|
|
10011
|
-
*
|
|
10012
|
-
* Composes the accepted ops applied since `fromVersion` (drawn from
|
|
10013
|
-
* #acceptedOps in locally-applied form) with this client's own local
|
|
10014
|
-
* pending ops, in that order. The result is in current #segments
|
|
10015
|
-
* coordinates.
|
|
10016
|
-
*
|
|
10017
|
-
* Returns `null` when the position cannot be decoded against the current
|
|
10018
|
-
* state:
|
|
10019
|
-
* - `fromVersion` is greater than this LiveText's current version: the
|
|
10020
|
-
* peer is ahead of us. The caller should park the message and retry
|
|
10021
|
-
* after more accepted ops arrive.
|
|
10022
|
-
* - `fromVersion` falls outside the retained accepted-ops history. This
|
|
10023
|
-
* only happens after very long-lived disconnections; the caller can
|
|
10024
|
-
* fall back to using the raw index and letting subsequent local
|
|
10025
|
-
* transactions map it (with bounded drift).
|
|
10026
|
-
*/
|
|
10027
|
-
#decodeIndex(index, fromVersion) {
|
|
10028
|
-
if (fromVersion > this.#version) {
|
|
10029
|
-
return null;
|
|
10030
|
-
}
|
|
10031
|
-
if (fromVersion < this.#version) {
|
|
10032
|
-
const oldest = _optionalChain([this, 'access', _238 => _238.#acceptedOps, 'access', _239 => _239[0], 'optionalAccess', _240 => _240.version]);
|
|
10033
|
-
if (oldest === void 0 || oldest > fromVersion + 1) {
|
|
10034
|
-
return null;
|
|
10035
|
-
}
|
|
10036
|
-
}
|
|
10037
|
-
let mapped = index;
|
|
10038
|
-
for (const entry of this.#acceptedOps) {
|
|
10039
|
-
if (entry.version <= fromVersion) continue;
|
|
10040
|
-
if (entry.version > this.#version) break;
|
|
10041
|
-
if (entry.ops.length === 0) continue;
|
|
10042
|
-
mapped = mapTextIndexThroughOperations(mapped, entry.ops);
|
|
10043
|
-
}
|
|
10044
|
-
mapped = mapTextIndexThroughOperations(mapped, this.#inFlightOps);
|
|
10045
|
-
mapped = mapTextIndexThroughOperations(mapped, this.#queuedOps);
|
|
10046
|
-
return Math.max(0, Math.min(mapped, this.length));
|
|
10047
|
-
}
|
|
10048
|
-
/**
|
|
10049
|
-
* Applies or removes inline attributes on a range of text.
|
|
10050
|
-
*
|
|
10051
|
-
* Set an attribute to `null` to remove it from the range.
|
|
10052
|
-
*
|
|
10053
|
-
* @example
|
|
10054
|
-
* const text = new LiveText("Hello world");
|
|
10055
|
-
* text.format(0, 5, { bold: true });
|
|
10056
|
-
* text.format(0, 5, { bold: null });
|
|
10057
|
-
*/
|
|
10058
|
-
format(index, length, attributes) {
|
|
10059
|
-
const clipped = clipRangeToCodePointBoundaries(
|
|
10060
|
-
this.toString(),
|
|
10061
|
-
index,
|
|
10062
|
-
length
|
|
10063
|
-
);
|
|
10064
|
-
if (clipped.length === 0) {
|
|
10065
|
-
return;
|
|
10066
|
-
}
|
|
10067
|
-
this.#dispatch([
|
|
10068
|
-
{
|
|
10069
|
-
type: "format",
|
|
10070
|
-
index: clipped.index,
|
|
10071
|
-
length: clipped.length,
|
|
10072
|
-
attributes
|
|
10073
|
-
}
|
|
10074
|
-
]);
|
|
10075
|
-
}
|
|
10076
|
-
/** Local edits made through the public API. */
|
|
10077
|
-
#dispatch(ops) {
|
|
10078
|
-
if (ops.length === 0) {
|
|
10079
|
-
return;
|
|
10080
|
-
}
|
|
10081
|
-
_optionalChain([this, 'access', _241 => _241._pool, 'optionalAccess', _242 => _242.assertStorageIsWritable, 'call', _243 => _243()]);
|
|
10082
|
-
const attached = this._pool !== void 0 && this._id !== void 0;
|
|
10083
|
-
const reverse = attached ? this.#invertOperations(ops) : [];
|
|
10084
|
-
const changes = this.#applyOperationsLocally(ops);
|
|
10085
|
-
if (!attached) {
|
|
10086
|
-
return;
|
|
10087
|
-
}
|
|
10088
|
-
const pool = nn(this._pool);
|
|
10089
|
-
const id = nn(this._id);
|
|
10090
|
-
const updates = /* @__PURE__ */ new Map([
|
|
10091
|
-
[
|
|
10092
|
-
id,
|
|
10093
|
-
{
|
|
10094
|
-
type: "LiveText",
|
|
10095
|
-
node: this,
|
|
10096
|
-
version: this.#version,
|
|
10097
|
-
updates: changes,
|
|
10098
|
-
source: LOCAL_EDIT
|
|
10099
|
-
}
|
|
10100
|
-
]
|
|
10101
|
-
]);
|
|
10102
|
-
if (this.#inFlightOpId === void 0) {
|
|
10103
|
-
const opId = pool.generateOpId();
|
|
10104
|
-
this.#inFlightOpId = opId;
|
|
10105
|
-
this.#inFlightOps = [...ops];
|
|
10106
|
-
pool.dispatch(
|
|
10107
|
-
[
|
|
10108
|
-
{
|
|
10109
|
-
type: OpCode.UPDATE_TEXT,
|
|
10110
|
-
id,
|
|
10111
|
-
opId,
|
|
10112
|
-
baseVersion: this.#version,
|
|
10113
|
-
ops: [...ops]
|
|
10114
|
-
}
|
|
10115
|
-
],
|
|
10116
|
-
reverse,
|
|
10117
|
-
updates
|
|
10118
|
-
);
|
|
10119
|
-
} else {
|
|
10120
|
-
this.#queuedOps.push(...ops);
|
|
10121
|
-
pool.dispatch([], reverse, updates, { clearRedoStack: true });
|
|
10122
|
-
}
|
|
10123
|
-
}
|
|
10124
|
-
/**
|
|
10125
|
-
* A local replay of an existing wire op: an undo/redo frame, or an
|
|
10126
|
-
* unacknowledged op re-sent after a reconnect.
|
|
10127
|
-
*/
|
|
10128
|
-
#applyLocal(op, source) {
|
|
10129
|
-
const mutableOp = op;
|
|
10130
|
-
if (op.opId !== void 0 && op.opId === this.#inFlightOpId) {
|
|
10131
|
-
this.#inFlightOps = [...this.#inFlightOps, ...this.#queuedOps];
|
|
10132
|
-
this.#queuedOps = [];
|
|
10133
|
-
mutableOp.baseVersion = this.#version;
|
|
10134
|
-
mutableOp.ops = [...this.#inFlightOps];
|
|
10135
|
-
return { modified: false };
|
|
10136
|
-
}
|
|
10137
|
-
let ops = op.ops;
|
|
10138
|
-
for (const entry of this.#acceptedOps) {
|
|
10139
|
-
if (entry.version > op.baseVersion && entry.ops.length > 0) {
|
|
10140
|
-
ops = transformTextOperations(ops, entry.ops, "after");
|
|
10141
|
-
}
|
|
10142
|
-
}
|
|
10143
|
-
const reverse = this.#invertOperations(ops);
|
|
10144
|
-
const changes = this.#applyOperationsLocally(ops);
|
|
10145
|
-
if (this.#inFlightOpId === void 0 && ops.length > 0) {
|
|
10146
|
-
this.#inFlightOpId = nn(op.opId, "Local ops must have an opId");
|
|
10147
|
-
this.#inFlightOps = [...ops];
|
|
10148
|
-
mutableOp.baseVersion = this.#version;
|
|
10149
|
-
mutableOp.ops = [...ops];
|
|
10150
|
-
} else {
|
|
10151
|
-
this.#queuedOps.push(...ops);
|
|
10152
|
-
mutableOp.baseVersion = this.#version;
|
|
10153
|
-
mutableOp.ops = [];
|
|
10154
|
-
}
|
|
10155
|
-
if (changes.length === 0) {
|
|
10156
|
-
return { modified: false };
|
|
10157
|
-
}
|
|
10158
|
-
return {
|
|
10159
|
-
reverse,
|
|
10160
|
-
modified: {
|
|
10161
|
-
type: "LiveText",
|
|
10162
|
-
node: this,
|
|
10163
|
-
version: this.#version,
|
|
10164
|
-
updates: changes,
|
|
10165
|
-
source
|
|
10166
|
-
}
|
|
10167
|
-
};
|
|
10168
|
-
}
|
|
10169
|
-
/** Server acknowledgement of our in-flight op. */
|
|
10170
|
-
#applyAck(op, source) {
|
|
10171
|
-
const ackedVersion = _nullishCoalesce(op.version, () => ( Math.max(this.#version, op.baseVersion + 1)));
|
|
10172
|
-
const predicted = this.#inFlightOps;
|
|
10173
|
-
const opId = this.#inFlightOpId;
|
|
10174
|
-
this.#confirmed = applyTextOperationsToSegments(this.#confirmed, op.ops);
|
|
10175
|
-
this.#inFlightOpId = void 0;
|
|
10176
|
-
this.#inFlightOps = [];
|
|
10177
|
-
let appliedOps = [];
|
|
10178
|
-
let result = { modified: false };
|
|
10179
|
-
if (!textOperationsEqual(op.ops, predicted)) {
|
|
10180
|
-
error2(
|
|
10181
|
-
"LiveText: acknowledgement did not match the local prediction; resynchronizing"
|
|
10182
|
-
);
|
|
10183
|
-
const rebuilt = this.#rebuildLocalFromConfirmed();
|
|
10184
|
-
appliedOps = rebuilt.appliedOps;
|
|
10185
|
-
if (rebuilt.changes.length > 0) {
|
|
10186
|
-
result = {
|
|
10187
|
-
reverse: [],
|
|
10188
|
-
modified: {
|
|
10189
|
-
type: "LiveText",
|
|
10190
|
-
node: this,
|
|
10191
|
-
version: ackedVersion,
|
|
10192
|
-
updates: rebuilt.changes,
|
|
10193
|
-
source
|
|
10194
|
-
}
|
|
10195
|
-
};
|
|
10196
|
-
}
|
|
10197
|
-
}
|
|
10198
|
-
this.#version = Math.max(this.#version, ackedVersion);
|
|
10199
|
-
this.#recordAccepted(ackedVersion, appliedOps, opId);
|
|
10200
|
-
this.#flushQueued();
|
|
10201
|
-
return result;
|
|
10202
|
-
}
|
|
10203
|
-
/** An accepted op from another client (or a server-fabricated fix op). */
|
|
10204
|
-
#applyRemote(op, source) {
|
|
10205
|
-
const version = _nullishCoalesce(op.version, () => ( this.#version + 1));
|
|
10206
|
-
this.#confirmed = applyTextOperationsToSegments(this.#confirmed, op.ops);
|
|
10207
|
-
const [overInFlight, inFlight] = transformTextOperationsX(
|
|
10208
|
-
op.ops,
|
|
10209
|
-
this.#inFlightOps,
|
|
10210
|
-
"before"
|
|
10211
|
-
);
|
|
10212
|
-
const [applied, queued] = transformTextOperationsX(
|
|
10213
|
-
overInFlight,
|
|
10214
|
-
this.#queuedOps,
|
|
10215
|
-
"before"
|
|
10216
|
-
);
|
|
10217
|
-
this.#inFlightOps = inFlight;
|
|
10218
|
-
this.#queuedOps = queued;
|
|
10219
|
-
this.#recordAccepted(version, applied, op.opId);
|
|
10220
|
-
if (applied.length === 0) {
|
|
10221
|
-
this.#version = Math.max(this.#version, version);
|
|
10222
|
-
return { modified: false };
|
|
10223
|
-
}
|
|
10224
|
-
const reverse = this.#invertOperations(applied);
|
|
10225
|
-
const changes = this.#applyOperationsLocally(applied);
|
|
10226
|
-
this.#version = Math.max(this.#version, version);
|
|
10227
|
-
return {
|
|
10228
|
-
reverse,
|
|
10229
|
-
modified: {
|
|
10230
|
-
type: "LiveText",
|
|
10231
|
-
node: this,
|
|
10232
|
-
version: this.#version,
|
|
10233
|
-
updates: changes,
|
|
10234
|
-
source
|
|
10235
|
-
}
|
|
10236
|
-
};
|
|
10237
|
-
}
|
|
10238
|
-
/** Send the queued ops as the next in-flight op (after an ack). */
|
|
10239
|
-
#flushQueued() {
|
|
10240
|
-
if (this.#queuedOps.length === 0 || this._pool === void 0 || this._id === void 0) {
|
|
10241
|
-
return;
|
|
10242
|
-
}
|
|
10243
|
-
const opId = this._pool.generateOpId();
|
|
10244
|
-
this.#inFlightOpId = opId;
|
|
10245
|
-
this.#inFlightOps = this.#queuedOps;
|
|
10246
|
-
this.#queuedOps = [];
|
|
10247
|
-
this._pool.dispatch(
|
|
10248
|
-
[
|
|
10249
|
-
{
|
|
10250
|
-
type: OpCode.UPDATE_TEXT,
|
|
10251
|
-
id: this._id,
|
|
10252
|
-
opId,
|
|
10253
|
-
baseVersion: this.#version,
|
|
10254
|
-
ops: [...this.#inFlightOps]
|
|
10255
|
-
}
|
|
10256
|
-
],
|
|
10257
|
-
[],
|
|
10258
|
-
/* @__PURE__ */ new Map(),
|
|
10259
|
-
// The local content was already applied (and made undoable) when the
|
|
10260
|
-
// edits happened; this is purely an outbound flush.
|
|
10261
|
-
{ clearRedoStack: false }
|
|
10262
|
-
);
|
|
10263
|
-
}
|
|
10264
|
-
/**
|
|
10265
|
-
* Rebuild the local document as confirmed ⊕ queued ops, returning the
|
|
10266
|
-
* coarse delta that was applied. Only used by defensive recovery paths.
|
|
10267
|
-
*/
|
|
10268
|
-
#rebuildLocalFromConfirmed() {
|
|
10269
|
-
const before2 = this.#segments;
|
|
10270
|
-
const after2 = applyTextOperationsToSegments(this.#confirmed, [
|
|
10271
|
-
...this.#inFlightOps,
|
|
10272
|
-
...this.#queuedOps
|
|
10273
|
-
]);
|
|
10274
|
-
if (stableStringify(segmentsToData(before2)) === stableStringify(segmentsToData(after2))) {
|
|
10275
|
-
this.#segments = after2;
|
|
10276
|
-
return { appliedOps: [], changes: [] };
|
|
10277
|
-
}
|
|
10278
|
-
const beforeText = before2.map((segment) => segment.text).join("");
|
|
10279
|
-
this.#segments = after2;
|
|
10280
|
-
this.invalidate();
|
|
10281
|
-
const appliedOps = [];
|
|
10282
|
-
const changes = [];
|
|
10283
|
-
if (beforeText.length > 0) {
|
|
10284
|
-
appliedOps.push({ type: "delete", index: 0, length: beforeText.length });
|
|
10285
|
-
changes.push({
|
|
10286
|
-
type: "delete",
|
|
10287
|
-
index: 0,
|
|
10288
|
-
length: beforeText.length,
|
|
10289
|
-
deletedText: beforeText
|
|
10290
|
-
});
|
|
10291
|
-
}
|
|
10292
|
-
let index = 0;
|
|
10293
|
-
for (const segment of after2) {
|
|
10294
|
-
appliedOps.push({
|
|
10295
|
-
type: "insert",
|
|
10296
|
-
index,
|
|
10297
|
-
text: segment.text,
|
|
10298
|
-
attributes: segment.attributes
|
|
10299
|
-
});
|
|
10300
|
-
changes.push({
|
|
10301
|
-
type: "insert",
|
|
10302
|
-
index,
|
|
10303
|
-
text: segment.text,
|
|
10304
|
-
attributes: segment.attributes
|
|
10305
|
-
});
|
|
10306
|
-
index += segment.text.length;
|
|
10307
|
-
}
|
|
10308
|
-
return { appliedOps, changes };
|
|
10309
|
-
}
|
|
10310
|
-
/**
|
|
10311
|
-
* Reconcile this node against an authoritative storage snapshot (e.g.
|
|
10312
|
-
* after a reconnect). The confirmed state and version are replaced by the
|
|
10313
|
-
* snapshot's; pending (in-flight + queued) ops are preserved on top and
|
|
10314
|
-
* will be re-sent by the offline-ops replay.
|
|
10315
|
-
*
|
|
10316
|
-
* @internal
|
|
10317
|
-
*/
|
|
10318
|
-
_resyncText(data, version, source) {
|
|
10319
|
-
this.#confirmed = dataToSegments(data);
|
|
10320
|
-
this.#version = version;
|
|
10321
|
-
this.#acceptedOps = [];
|
|
10322
|
-
const rebuilt = this.#rebuildLocalFromConfirmed();
|
|
10323
|
-
if (rebuilt.changes.length === 0) {
|
|
10324
|
-
return void 0;
|
|
10325
|
-
}
|
|
10326
|
-
return {
|
|
10327
|
-
type: "LiveText",
|
|
10328
|
-
node: this,
|
|
10329
|
-
version: this.#version,
|
|
10330
|
-
updates: rebuilt.changes,
|
|
10331
|
-
source
|
|
10332
|
-
};
|
|
10333
|
-
}
|
|
10334
|
-
/**
|
|
10335
|
-
* Called when the server rejected one of our ops. Drops all pending state
|
|
10336
|
-
* for this node (edits queued behind a rejected op cannot be trusted
|
|
10337
|
-
* either); the room follows up with a storage resync.
|
|
10338
|
-
*
|
|
10339
|
-
* @internal
|
|
10340
|
-
*/
|
|
10341
|
-
_rejectPendingOp(opId) {
|
|
10342
|
-
if (opId !== this.#inFlightOpId) {
|
|
10343
|
-
return;
|
|
10344
|
-
}
|
|
10345
|
-
this.#inFlightOpId = void 0;
|
|
10346
|
-
this.#inFlightOps = [];
|
|
10347
|
-
this.#queuedOps = [];
|
|
10348
|
-
}
|
|
10349
|
-
#recordAccepted(version, ops, opId) {
|
|
10350
|
-
if (this.#acceptedOps.some((entry) => entry.version === version)) {
|
|
10351
|
-
return;
|
|
10352
|
-
}
|
|
10353
|
-
this.#acceptedOps.push({ version, opId, ops: [...ops] });
|
|
10354
|
-
this.#acceptedOps.sort((left, right) => left.version - right.version);
|
|
10355
|
-
if (this.#acceptedOps.length > ACCEPTED_OPS_HISTORY_LIMIT) {
|
|
10356
|
-
this.#acceptedOps.splice(
|
|
10357
|
-
0,
|
|
10358
|
-
this.#acceptedOps.length - ACCEPTED_OPS_HISTORY_LIMIT
|
|
10359
|
-
);
|
|
10360
|
-
}
|
|
10361
|
-
}
|
|
10362
|
-
#applyOperationsLocally(ops) {
|
|
10363
|
-
const changes = [];
|
|
10364
|
-
for (const op of ops) {
|
|
10365
|
-
if (op.type === "insert") {
|
|
10366
|
-
this.#segments = applyInsert(
|
|
10367
|
-
this.#segments,
|
|
10368
|
-
op.index,
|
|
10369
|
-
op.text,
|
|
10370
|
-
op.attributes
|
|
10371
|
-
);
|
|
10372
|
-
changes.push({
|
|
10373
|
-
type: "insert",
|
|
10374
|
-
index: op.index,
|
|
10375
|
-
text: op.text,
|
|
10376
|
-
attributes: op.attributes
|
|
10377
|
-
});
|
|
10378
|
-
} else if (op.type === "delete") {
|
|
10379
|
-
const result = applyDelete(this.#segments, op.index, op.length);
|
|
10380
|
-
this.#segments = result.segments;
|
|
10381
|
-
changes.push({
|
|
10382
|
-
type: "delete",
|
|
10383
|
-
index: op.index,
|
|
10384
|
-
length: op.length,
|
|
10385
|
-
deletedText: result.deletedText
|
|
10386
|
-
});
|
|
10387
|
-
} else {
|
|
10388
|
-
this.#segments = applyFormat(
|
|
10389
|
-
this.#segments,
|
|
10390
|
-
op.index,
|
|
10391
|
-
op.length,
|
|
10392
|
-
op.attributes
|
|
10393
|
-
);
|
|
10394
|
-
changes.push({
|
|
10395
|
-
type: "format",
|
|
10396
|
-
index: op.index,
|
|
10397
|
-
length: op.length,
|
|
10398
|
-
attributes: op.attributes
|
|
10399
|
-
});
|
|
10400
|
-
}
|
|
10401
|
-
}
|
|
10402
|
-
this.invalidate();
|
|
10403
|
-
return changes;
|
|
10404
|
-
}
|
|
10405
|
-
#invertOperations(ops) {
|
|
10406
|
-
return [
|
|
10407
|
-
{
|
|
10408
|
-
type: OpCode.UPDATE_TEXT,
|
|
10409
|
-
id: nn(this._id),
|
|
10410
|
-
baseVersion: this.#version,
|
|
10411
|
-
ops: invertTextOperations(this.#segments, ops)
|
|
10412
|
-
}
|
|
10413
|
-
];
|
|
10414
|
-
}
|
|
10415
|
-
/** Returns the plain text content without attributes. Equivalent to joining the text from each segment in {@link LiveText.toJSON}. */
|
|
10416
|
-
toString() {
|
|
10417
|
-
return this.#segments.map((segment) => segment.text).join("");
|
|
10418
|
-
}
|
|
10419
|
-
/**
|
|
10420
|
-
* Returns a JSON-compatible snapshot of the document as a {@link LiveTextData}
|
|
10421
|
-
* array.
|
|
10422
|
-
*
|
|
10423
|
-
* @example
|
|
10424
|
-
* new LiveText([["Hello ", { bold: true }], ["world"]]).toJSON();
|
|
10425
|
-
* // [["Hello ", { bold: true }], ["world"]]
|
|
10426
|
-
*/
|
|
10427
|
-
toJSON() {
|
|
10428
|
-
return super.toJSON();
|
|
10429
|
-
}
|
|
10430
|
-
/** @internal */
|
|
10431
|
-
_toJSON() {
|
|
10432
|
-
return segmentsToData(this.#segments);
|
|
10433
|
-
}
|
|
10434
|
-
/** @internal */
|
|
10435
|
-
toTreeNode(key) {
|
|
10436
|
-
return super.toTreeNode(key);
|
|
10437
|
-
}
|
|
10438
|
-
/** @internal */
|
|
10439
|
-
_toTreeNode(key) {
|
|
10440
|
-
const nodeId = _nullishCoalesce(this._id, () => ( nanoid()));
|
|
10441
|
-
const payload = this.toJSON().map(
|
|
10442
|
-
(segment, index) => ({
|
|
10443
|
-
type: "Json",
|
|
10444
|
-
id: `${nodeId}:${index}`,
|
|
10445
|
-
key: String(index),
|
|
10446
|
-
payload: segment
|
|
10447
|
-
})
|
|
10448
|
-
);
|
|
10449
|
-
payload.push({
|
|
10450
|
-
type: "Json",
|
|
10451
|
-
id: `${nodeId}:version`,
|
|
10452
|
-
key: "version",
|
|
10453
|
-
payload: this.version
|
|
10454
|
-
});
|
|
10455
|
-
return {
|
|
10456
|
-
type: "LiveText",
|
|
10457
|
-
id: nodeId,
|
|
10458
|
-
key,
|
|
10459
|
-
payload
|
|
10460
|
-
};
|
|
10461
|
-
}
|
|
10462
|
-
clone() {
|
|
10463
|
-
return new _LiveText(this.toJSON(), this.#version);
|
|
10464
|
-
}
|
|
10465
|
-
};
|
|
10466
|
-
|
|
10467
|
-
// src/crdts/liveblocks-helpers.ts
|
|
10468
|
-
function creationOpToLiveNode(op) {
|
|
10469
|
-
return lsonToLiveNode(creationOpToLson(op));
|
|
10470
|
-
}
|
|
10471
|
-
function creationOpToLson(op) {
|
|
10472
|
-
switch (op.type) {
|
|
10473
|
-
case OpCode.CREATE_FILE:
|
|
10474
|
-
return new LiveFile(op.data);
|
|
10475
|
-
case OpCode.CREATE_REGISTER:
|
|
10476
|
-
return op.data;
|
|
10477
|
-
case OpCode.CREATE_OBJECT:
|
|
10478
|
-
return new LiveObject(op.data);
|
|
10479
|
-
case OpCode.CREATE_MAP:
|
|
10480
|
-
return new LiveMap();
|
|
10481
|
-
case OpCode.CREATE_LIST:
|
|
10482
|
-
return new LiveList([]);
|
|
10483
|
-
case OpCode.CREATE_TEXT:
|
|
10484
|
-
return new LiveText(op.data, op.version);
|
|
10485
|
-
default:
|
|
10486
|
-
return assertNever(op, "Unknown creation Op");
|
|
10487
|
-
}
|
|
10488
|
-
}
|
|
10489
|
-
function isSameNodeOrChildOf(node, parent) {
|
|
10490
|
-
if (node === parent) {
|
|
10491
|
-
return true;
|
|
10492
|
-
}
|
|
10493
|
-
if (node.parent.type === "HasParent") {
|
|
10494
|
-
return isSameNodeOrChildOf(node.parent.node, parent);
|
|
10495
|
-
}
|
|
10496
|
-
return false;
|
|
10497
|
-
}
|
|
10498
|
-
function liveObjectFromNodeStream(nodes) {
|
|
10499
|
-
const pool = createManagedPool({
|
|
10500
|
-
getCurrentConnectionId: () => {
|
|
10501
|
-
throw new Error(
|
|
10502
|
-
"Cannot mutate a historic storage version: it is a read-only snapshot"
|
|
10503
|
-
);
|
|
10504
|
-
}
|
|
10505
|
-
});
|
|
10506
|
-
return LiveObject._fromItems(nodes, pool);
|
|
10507
|
-
}
|
|
10508
|
-
function deserialize(node, parentToChildren, pool) {
|
|
10509
|
-
if (isObjectStorageNode(node)) {
|
|
10510
|
-
return LiveObject._deserialize(node, parentToChildren, pool);
|
|
10511
|
-
} else if (isListStorageNode(node)) {
|
|
10512
|
-
return LiveList._deserialize(node, parentToChildren, pool);
|
|
10513
|
-
} else if (isMapStorageNode(node)) {
|
|
10514
|
-
return LiveMap._deserialize(node, parentToChildren, pool);
|
|
10515
|
-
} else if (isRegisterStorageNode(node)) {
|
|
10516
|
-
return LiveRegister._deserialize(node, parentToChildren, pool);
|
|
10517
|
-
} else if (isTextStorageNode(node)) {
|
|
10518
|
-
return LiveText._deserialize(node, parentToChildren, pool);
|
|
10519
|
-
} else if (isFileStorageNode(node)) {
|
|
10520
|
-
return LiveFile._deserialize(node, parentToChildren, pool);
|
|
10521
|
-
} else {
|
|
10522
|
-
throw new Error("Unexpected CRDT type");
|
|
10523
|
-
}
|
|
10524
|
-
}
|
|
10525
|
-
function deserializeToLson(node, parentToChildren, pool) {
|
|
10526
|
-
if (isObjectStorageNode(node)) {
|
|
10527
|
-
return LiveObject._deserialize(node, parentToChildren, pool);
|
|
10528
|
-
} else if (isListStorageNode(node)) {
|
|
10529
|
-
return LiveList._deserialize(node, parentToChildren, pool);
|
|
10530
|
-
} else if (isMapStorageNode(node)) {
|
|
10531
|
-
return LiveMap._deserialize(node, parentToChildren, pool);
|
|
10532
|
-
} else if (isRegisterStorageNode(node)) {
|
|
10533
|
-
return node[1].data;
|
|
10534
|
-
} else if (isTextStorageNode(node)) {
|
|
10535
|
-
return LiveText._deserialize(node, parentToChildren, pool);
|
|
10536
|
-
} else if (isFileStorageNode(node)) {
|
|
10537
|
-
return LiveFile._deserialize(node, parentToChildren, pool);
|
|
10538
|
-
} else {
|
|
10539
|
-
throw new Error("Unexpected CRDT type");
|
|
10540
|
-
}
|
|
10541
|
-
}
|
|
10542
|
-
function isLiveStructure(value) {
|
|
10543
|
-
return isLiveList(value) || isLiveMap(value) || isLiveObject(value) || isLiveText(value) || isLiveFile(value);
|
|
10544
|
-
}
|
|
10545
|
-
function isLiveNode(value) {
|
|
10546
|
-
return isLiveStructure(value) || isLiveRegister(value);
|
|
10547
|
-
}
|
|
10548
|
-
function isLiveList(value) {
|
|
10549
|
-
return value instanceof LiveList;
|
|
10550
|
-
}
|
|
10551
|
-
function isLiveMap(value) {
|
|
10552
|
-
return value instanceof LiveMap;
|
|
10553
|
-
}
|
|
10554
|
-
function isLiveObject(value) {
|
|
10555
|
-
return value instanceof LiveObject;
|
|
10556
|
-
}
|
|
10557
|
-
function isLiveText(value) {
|
|
10558
|
-
return value instanceof LiveText;
|
|
10559
|
-
}
|
|
10560
|
-
function isLiveFile(value) {
|
|
10561
|
-
return value instanceof LiveFile;
|
|
10562
|
-
}
|
|
10563
|
-
function isLiveRegister(value) {
|
|
10564
|
-
return value instanceof LiveRegister;
|
|
10565
|
-
}
|
|
10566
|
-
function cloneLson(value) {
|
|
10567
|
-
return value === void 0 ? void 0 : isLiveStructure(value) ? value.clone() : deepClone(value);
|
|
10568
|
-
}
|
|
10569
|
-
function liveNodeToLson(obj) {
|
|
10570
|
-
if (obj instanceof LiveRegister) {
|
|
10571
|
-
return obj.data;
|
|
10572
|
-
} else if (obj instanceof LiveList || obj instanceof LiveMap || obj instanceof LiveObject || obj instanceof LiveText || obj instanceof LiveFile) {
|
|
10573
|
-
return obj;
|
|
10574
|
-
} else {
|
|
10575
|
-
return assertNever(obj, "Unknown AbstractCrdt");
|
|
10576
|
-
}
|
|
10577
|
-
}
|
|
10578
|
-
function lsonToLiveNode(value) {
|
|
10579
|
-
if (value instanceof LiveObject || value instanceof LiveMap || value instanceof LiveList || value instanceof LiveText || value instanceof LiveFile) {
|
|
10580
|
-
return value;
|
|
10581
|
-
} else {
|
|
10582
|
-
return new LiveRegister(value);
|
|
10583
|
-
}
|
|
10584
|
-
}
|
|
10585
|
-
function dumpPool(pool) {
|
|
10586
|
-
const rows = Array.from(pool.nodes.values(), (node) => {
|
|
10587
|
-
const parent = node.parent;
|
|
10588
|
-
const parentId = parent.type === "HasParent" ? _nullishCoalesce(parent.node._id, () => ( "?")) : parent.type === "Orphaned" ? "<orphaned>" : "-";
|
|
10589
|
-
let value;
|
|
10590
|
-
if (node instanceof LiveRegister) {
|
|
10591
|
-
value = stringifyOrLog(node.data);
|
|
10592
|
-
} else if (node instanceof LiveList) {
|
|
10593
|
-
value = "<LiveList>";
|
|
10594
|
-
} else if (node instanceof LiveMap) {
|
|
10595
|
-
value = "<LiveMap>";
|
|
10596
|
-
} else if (node instanceof LiveFile) {
|
|
10597
|
-
value = stringifyOrLog(node.data);
|
|
10598
|
-
} else {
|
|
10599
|
-
value = "<LiveObject>";
|
|
10600
|
-
}
|
|
10601
|
-
return { id: nn(node._id), parentId, key: _nullishCoalesce(node._parentKey, () => ( "")), value };
|
|
10602
|
-
});
|
|
10603
|
-
rows.sort((a, b) => {
|
|
10604
|
-
if (a.parentId !== b.parentId) return a.parentId < b.parentId ? -1 : 1;
|
|
10605
|
-
if (a.key !== b.key) return a.key < b.key ? -1 : 1;
|
|
10606
|
-
return 0;
|
|
10607
|
-
});
|
|
10608
|
-
return rows.map(
|
|
10609
|
-
(r) => ` ${r.id} parent=${r.parentId} key=${r.key || "\u2014"} ${r.value}`
|
|
10610
|
-
).join("\n");
|
|
10611
|
-
}
|
|
10612
|
-
function isJsonEq(a, b) {
|
|
10613
|
-
if (a === b) {
|
|
10614
|
-
return true;
|
|
10615
|
-
}
|
|
10616
|
-
if (typeof a !== "object" || a === null || typeof b !== "object" || b === null) {
|
|
10617
|
-
return false;
|
|
10618
|
-
}
|
|
10619
|
-
if (Array.isArray(a) || Array.isArray(b)) {
|
|
10620
|
-
if (!Array.isArray(a) || !Array.isArray(b) || a.length !== b.length) {
|
|
10621
|
-
return false;
|
|
10622
|
-
}
|
|
10623
|
-
for (let i = 0; i < a.length; i++) {
|
|
10624
|
-
if (!isJsonEq(a[i], b[i])) {
|
|
10625
|
-
return false;
|
|
10626
|
-
}
|
|
10627
|
-
}
|
|
10628
|
-
return true;
|
|
10629
|
-
}
|
|
10630
|
-
const aKeys = Object.keys(a);
|
|
10631
|
-
if (aKeys.length !== Object.keys(b).length) {
|
|
10632
|
-
return false;
|
|
10633
|
-
}
|
|
10634
|
-
for (const key of aKeys) {
|
|
10635
|
-
if (!isJsonEq(a[key], b[key])) {
|
|
10636
|
-
return false;
|
|
10637
|
-
}
|
|
10638
|
-
}
|
|
10639
|
-
return true;
|
|
10640
|
-
}
|
|
10641
|
-
function liveTextDataToReplaceOps(before2, after2) {
|
|
10642
|
-
const ops = [];
|
|
10643
|
-
const beforeLength = before2.reduce(
|
|
10644
|
-
(length, [text]) => length + text.length,
|
|
10645
|
-
0
|
|
10646
|
-
);
|
|
10647
|
-
if (beforeLength > 0) {
|
|
10648
|
-
ops.push({ type: "delete", index: 0, length: beforeLength });
|
|
10649
|
-
}
|
|
10650
|
-
let index = 0;
|
|
10651
|
-
for (const [text, attributes] of after2) {
|
|
10652
|
-
if (text.length === 0) {
|
|
10653
|
-
continue;
|
|
10654
|
-
}
|
|
10655
|
-
ops.push({ type: "insert", index, text, attributes });
|
|
10656
|
-
index += text.length;
|
|
10657
|
-
}
|
|
10658
|
-
return ops;
|
|
10659
|
-
}
|
|
10660
|
-
function diffNodeMap(prev, next, options) {
|
|
9347
|
+
function diffNodeMap(prev, next) {
|
|
10661
9348
|
const ops = [];
|
|
10662
9349
|
const idsToRecreate = /* @__PURE__ */ new Set();
|
|
10663
9350
|
next.forEach((nextCrdt, id) => {
|
|
@@ -10749,16 +9436,6 @@ function diffNodeMap(prev, next, options) {
|
|
|
10749
9436
|
parentKey: crdt.parentKey
|
|
10750
9437
|
});
|
|
10751
9438
|
break;
|
|
10752
|
-
case CrdtType.TEXT:
|
|
10753
|
-
ops.push({
|
|
10754
|
-
type: OpCode.CREATE_TEXT,
|
|
10755
|
-
id,
|
|
10756
|
-
parentId: crdt.parentId,
|
|
10757
|
-
parentKey: crdt.parentKey,
|
|
10758
|
-
data: crdt.data,
|
|
10759
|
-
version: crdt.version
|
|
10760
|
-
});
|
|
10761
|
-
break;
|
|
10762
9439
|
}
|
|
10763
9440
|
}
|
|
10764
9441
|
next.forEach((crdt, id) => {
|
|
@@ -10785,17 +9462,6 @@ function diffNodeMap(prev, next, options) {
|
|
|
10785
9462
|
}
|
|
10786
9463
|
}
|
|
10787
9464
|
}
|
|
10788
|
-
if (_optionalChain([options, 'optionalAccess', _244 => _244.includeLiveTextUpdates]) === true && crdt.type === CrdtType.TEXT && currentCrdt.type === CrdtType.TEXT && !isJsonEq(crdt.data, currentCrdt.data)) {
|
|
10789
|
-
ops.push({
|
|
10790
|
-
type: OpCode.UPDATE_TEXT,
|
|
10791
|
-
id,
|
|
10792
|
-
// A restore is a new edit in the current timeline. The version from
|
|
10793
|
-
// the historic snapshot describes its old timeline and must not move
|
|
10794
|
-
// this node's current version backwards.
|
|
10795
|
-
baseVersion: currentCrdt.version,
|
|
10796
|
-
ops: liveTextDataToReplaceOps(currentCrdt.data, crdt.data)
|
|
10797
|
-
});
|
|
10798
|
-
}
|
|
10799
9465
|
if (crdt.parentKey !== currentCrdt.parentKey) {
|
|
10800
9466
|
ops.push({
|
|
10801
9467
|
type: OpCode.SET_PARENT_KEY,
|
|
@@ -10836,36 +9502,19 @@ function mergeListStorageUpdates(first, second) {
|
|
|
10836
9502
|
updates: updates.concat(second.updates)
|
|
10837
9503
|
};
|
|
10838
9504
|
}
|
|
10839
|
-
function mergeTextStorageUpdates(first, second) {
|
|
10840
|
-
return {
|
|
10841
|
-
...second,
|
|
10842
|
-
updates: first.updates.concat(second.updates)
|
|
10843
|
-
};
|
|
10844
|
-
}
|
|
10845
|
-
function mergeUpdateSources(first, second) {
|
|
10846
|
-
if (first.origin === "remote" || second.origin === "remote") {
|
|
10847
|
-
return REMOTE;
|
|
10848
|
-
}
|
|
10849
|
-
if (second.via !== "edit") return second;
|
|
10850
|
-
if (first.via !== "edit") return first;
|
|
10851
|
-
return LOCAL_EDIT;
|
|
10852
|
-
}
|
|
10853
9505
|
function mergeStorageUpdates(first, second) {
|
|
10854
9506
|
if (first === void 0) {
|
|
10855
9507
|
return second;
|
|
10856
9508
|
}
|
|
10857
|
-
const source = mergeUpdateSources(first.source, second.source);
|
|
10858
9509
|
if (first.type === "LiveObject" && second.type === "LiveObject") {
|
|
10859
|
-
return
|
|
9510
|
+
return mergeObjectStorageUpdates(first, second);
|
|
10860
9511
|
} else if (first.type === "LiveMap" && second.type === "LiveMap") {
|
|
10861
|
-
return
|
|
9512
|
+
return mergeMapStorageUpdates(first, second);
|
|
10862
9513
|
} else if (first.type === "LiveList" && second.type === "LiveList") {
|
|
10863
|
-
return
|
|
10864
|
-
} else if (first.type === "LiveText" && second.type === "LiveText") {
|
|
10865
|
-
return { ...mergeTextStorageUpdates(first, second), source };
|
|
9514
|
+
return mergeListStorageUpdates(first, second);
|
|
10866
9515
|
} else {
|
|
10867
|
-
return { ...second, source };
|
|
10868
9516
|
}
|
|
9517
|
+
return second;
|
|
10869
9518
|
}
|
|
10870
9519
|
|
|
10871
9520
|
// src/devtools/bridge.ts
|
|
@@ -10881,7 +9530,7 @@ function sendToPanel(message, options) {
|
|
|
10881
9530
|
...message,
|
|
10882
9531
|
source: "liveblocks-devtools-client"
|
|
10883
9532
|
};
|
|
10884
|
-
if (!(_optionalChain([options, 'optionalAccess',
|
|
9533
|
+
if (!(_optionalChain([options, 'optionalAccess', _238 => _238.force]) || _bridgeActive)) {
|
|
10885
9534
|
return;
|
|
10886
9535
|
}
|
|
10887
9536
|
window.postMessage(fullMsg, "*");
|
|
@@ -10889,7 +9538,7 @@ function sendToPanel(message, options) {
|
|
|
10889
9538
|
var eventSource = makeEventSource();
|
|
10890
9539
|
if (process.env.NODE_ENV !== "production" && typeof window !== "undefined") {
|
|
10891
9540
|
window.addEventListener("message", (event) => {
|
|
10892
|
-
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") {
|
|
10893
9542
|
eventSource.notify(event.data);
|
|
10894
9543
|
} else {
|
|
10895
9544
|
}
|
|
@@ -11031,7 +9680,7 @@ function fullSync(room) {
|
|
|
11031
9680
|
msg: "room::sync::full",
|
|
11032
9681
|
roomId: room.id,
|
|
11033
9682
|
status: room.getStatus(),
|
|
11034
|
-
storage: _nullishCoalesce(_optionalChain([root, 'optionalAccess',
|
|
9683
|
+
storage: _nullishCoalesce(_optionalChain([root, 'optionalAccess', _241 => _241.toTreeNode, 'call', _242 => _242("root"), 'access', _243 => _243.payload]), () => ( null)),
|
|
11035
9684
|
me,
|
|
11036
9685
|
others
|
|
11037
9686
|
});
|
|
@@ -11718,15 +10367,15 @@ function installBackgroundTabSpy() {
|
|
|
11718
10367
|
const doc = typeof document !== "undefined" ? document : void 0;
|
|
11719
10368
|
const inBackgroundSince = { current: null };
|
|
11720
10369
|
function onVisibilityChange() {
|
|
11721
|
-
if (_optionalChain([doc, 'optionalAccess',
|
|
10370
|
+
if (_optionalChain([doc, 'optionalAccess', _244 => _244.visibilityState]) === "hidden") {
|
|
11722
10371
|
inBackgroundSince.current = _nullishCoalesce(inBackgroundSince.current, () => ( Date.now()));
|
|
11723
10372
|
} else {
|
|
11724
10373
|
inBackgroundSince.current = null;
|
|
11725
10374
|
}
|
|
11726
10375
|
}
|
|
11727
|
-
_optionalChain([doc, 'optionalAccess',
|
|
10376
|
+
_optionalChain([doc, 'optionalAccess', _245 => _245.addEventListener, 'call', _246 => _246("visibilitychange", onVisibilityChange)]);
|
|
11728
10377
|
const unsub = () => {
|
|
11729
|
-
_optionalChain([doc, 'optionalAccess',
|
|
10378
|
+
_optionalChain([doc, 'optionalAccess', _247 => _247.removeEventListener, 'call', _248 => _248("visibilitychange", onVisibilityChange)]);
|
|
11730
10379
|
};
|
|
11731
10380
|
return [inBackgroundSince, unsub];
|
|
11732
10381
|
}
|
|
@@ -11750,7 +10399,7 @@ function makeNodeMapBuffer() {
|
|
|
11750
10399
|
function topLevelKeysOf(nodes) {
|
|
11751
10400
|
const keys2 = /* @__PURE__ */ new Set();
|
|
11752
10401
|
const root = nodes.get("root");
|
|
11753
|
-
for (const key in _optionalChain([root, 'optionalAccess',
|
|
10402
|
+
for (const key in _optionalChain([root, 'optionalAccess', _249 => _249.data])) {
|
|
11754
10403
|
keys2.add(key);
|
|
11755
10404
|
}
|
|
11756
10405
|
for (const node of nodes.values()) {
|
|
@@ -11822,8 +10471,6 @@ function createRoom(options, config) {
|
|
|
11822
10471
|
activeBatch: null,
|
|
11823
10472
|
unacknowledgedOps
|
|
11824
10473
|
};
|
|
11825
|
-
let nextHistoryItemId = 0;
|
|
11826
|
-
let historyDisabled = 0;
|
|
11827
10474
|
const nodeMapBuffer = makeNodeMapBuffer();
|
|
11828
10475
|
const stopwatch = config.enableDebugLogging ? makeStopWatch() : void 0;
|
|
11829
10476
|
let lastTokenKey;
|
|
@@ -11908,7 +10555,7 @@ function createRoom(options, config) {
|
|
|
11908
10555
|
}
|
|
11909
10556
|
}
|
|
11910
10557
|
});
|
|
11911
|
-
function onDispatch(ops, reverse, storageUpdates
|
|
10558
|
+
function onDispatch(ops, reverse, storageUpdates) {
|
|
11912
10559
|
if (context.activeBatch) {
|
|
11913
10560
|
for (const op of ops) {
|
|
11914
10561
|
context.activeBatch.ops.push(op);
|
|
@@ -11923,24 +10570,19 @@ function createRoom(options, config) {
|
|
|
11923
10570
|
);
|
|
11924
10571
|
}
|
|
11925
10572
|
context.activeBatch.reverseOps.pushLeft(reverse);
|
|
11926
|
-
if (_optionalChain([options2, 'optionalAccess', _257 => _257.clearRedoStack])) {
|
|
11927
|
-
context.activeBatch.clearRedoStack = true;
|
|
11928
|
-
}
|
|
11929
10573
|
} else {
|
|
11930
10574
|
if (reverse.length > 0) {
|
|
11931
10575
|
addToUndoStack(reverse);
|
|
11932
10576
|
}
|
|
11933
|
-
if (_nullishCoalesce(_optionalChain([options2, 'optionalAccess', _258 => _258.clearRedoStack]), () => ( ops.length > 0))) {
|
|
11934
|
-
clearRedoStack();
|
|
11935
|
-
}
|
|
11936
10577
|
if (ops.length > 0) {
|
|
10578
|
+
context.redoStack.length = 0;
|
|
11937
10579
|
dispatchOps(ops);
|
|
11938
10580
|
}
|
|
11939
10581
|
notify({ storageUpdates });
|
|
11940
10582
|
}
|
|
11941
10583
|
}
|
|
11942
10584
|
function isStorageWritable() {
|
|
11943
|
-
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]);
|
|
11944
10586
|
return permissionMatrix !== void 0 ? hasPermissionAccess(permissionMatrix, "storage", "write") : true;
|
|
11945
10587
|
}
|
|
11946
10588
|
const eventHub = {
|
|
@@ -11953,7 +10595,6 @@ function createRoom(options, config) {
|
|
|
11953
10595
|
others: makeEventSource(),
|
|
11954
10596
|
storageBatch: makeEventSource(),
|
|
11955
10597
|
history: makeEventSource(),
|
|
11956
|
-
privateHistory: makeEventSource(),
|
|
11957
10598
|
storageDidLoad: makeEventSource(),
|
|
11958
10599
|
storageStatus: makeEventSource(),
|
|
11959
10600
|
ydoc: makeEventSource(),
|
|
@@ -12041,12 +10682,12 @@ function createRoom(options, config) {
|
|
|
12041
10682
|
self,
|
|
12042
10683
|
(me) => me !== null ? userToTreeNode("Me", me) : null
|
|
12043
10684
|
);
|
|
12044
|
-
function diffCurrentStorageAgainst(target
|
|
10685
|
+
function diffCurrentStorageAgainst(target) {
|
|
12045
10686
|
const current = /* @__PURE__ */ new Map();
|
|
12046
10687
|
for (const [id, crdt] of context.pool.nodes) {
|
|
12047
10688
|
current.set(id, crdt._serialize());
|
|
12048
10689
|
}
|
|
12049
|
-
return diffNodeMap(current, target
|
|
10690
|
+
return diffNodeMap(current, target);
|
|
12050
10691
|
}
|
|
12051
10692
|
function createOrUpdateRootFromMessage(nodes) {
|
|
12052
10693
|
if (nodes.size === 0) {
|
|
@@ -12054,23 +10695,6 @@ function createRoom(options, config) {
|
|
|
12054
10695
|
}
|
|
12055
10696
|
if (context.root !== void 0) {
|
|
12056
10697
|
const result = applyRemoteOps(diffCurrentStorageAgainst(nodes));
|
|
12057
|
-
for (const [id, crdt] of nodes) {
|
|
12058
|
-
if (crdt.type === CrdtType.TEXT) {
|
|
12059
|
-
const node = context.pool.nodes.get(id);
|
|
12060
|
-
if (node !== void 0 && isLiveText(node)) {
|
|
12061
|
-
const update = node._resyncText(crdt.data, crdt.version, REMOTE);
|
|
12062
|
-
if (update !== void 0) {
|
|
12063
|
-
result.updates.storageUpdates.set(
|
|
12064
|
-
id,
|
|
12065
|
-
mergeStorageUpdates(
|
|
12066
|
-
result.updates.storageUpdates.get(id),
|
|
12067
|
-
update
|
|
12068
|
-
)
|
|
12069
|
-
);
|
|
12070
|
-
}
|
|
12071
|
-
}
|
|
12072
|
-
}
|
|
12073
|
-
}
|
|
12074
10698
|
notify(result.updates);
|
|
12075
10699
|
} else {
|
|
12076
10700
|
context.root = LiveObject._fromItems(
|
|
@@ -12078,7 +10702,7 @@ function createRoom(options, config) {
|
|
|
12078
10702
|
context.pool
|
|
12079
10703
|
);
|
|
12080
10704
|
}
|
|
12081
|
-
const canWrite = _nullishCoalesce(_optionalChain([self, 'access',
|
|
10705
|
+
const canWrite = _nullishCoalesce(_optionalChain([self, 'access', _254 => _254.get, 'call', _255 => _255(), 'optionalAccess', _256 => _256.canWrite]), () => ( true));
|
|
12082
10706
|
const serverTopLevelKeys = topLevelKeysOf(nodes);
|
|
12083
10707
|
const root = context.root;
|
|
12084
10708
|
disableHistory(() => {
|
|
@@ -12095,23 +10719,12 @@ function createRoom(options, config) {
|
|
|
12095
10719
|
}
|
|
12096
10720
|
});
|
|
12097
10721
|
}
|
|
12098
|
-
function notifyPrivateHistory(event) {
|
|
12099
|
-
if (historyDisabled > 0) return;
|
|
12100
|
-
eventHub.privateHistory.notify(event);
|
|
12101
|
-
}
|
|
12102
|
-
function clearRedoStack() {
|
|
12103
|
-
if (context.redoStack.length === 0) return;
|
|
12104
|
-
const ids = context.redoStack.map((item) => item.id);
|
|
12105
|
-
context.redoStack.length = 0;
|
|
12106
|
-
notifyPrivateHistory({ action: "discard", ids });
|
|
12107
|
-
}
|
|
12108
10722
|
function reconcileStorageWithNodes(nodes) {
|
|
12109
10723
|
if (context.root === void 0) {
|
|
12110
10724
|
throw new Error("Cannot reconcile storage before it is loaded");
|
|
12111
10725
|
}
|
|
12112
10726
|
const ops = diffCurrentStorageAgainst(
|
|
12113
|
-
new Map(nodes)
|
|
12114
|
-
{ includeLiveTextUpdates: true }
|
|
10727
|
+
new Map(nodes)
|
|
12115
10728
|
);
|
|
12116
10729
|
if (ops.length === 0) {
|
|
12117
10730
|
return;
|
|
@@ -12130,14 +10743,9 @@ function createRoom(options, config) {
|
|
|
12130
10743
|
}
|
|
12131
10744
|
function _addToRealUndoStack(frames) {
|
|
12132
10745
|
if (context.undoStack.length >= 50) {
|
|
12133
|
-
|
|
12134
|
-
if (evicted !== void 0) {
|
|
12135
|
-
notifyPrivateHistory({ action: "discard", ids: [evicted.id] });
|
|
12136
|
-
}
|
|
10746
|
+
context.undoStack.shift();
|
|
12137
10747
|
}
|
|
12138
|
-
|
|
12139
|
-
context.undoStack.push({ id, frames });
|
|
12140
|
-
notifyPrivateHistory({ action: "push", id });
|
|
10748
|
+
context.undoStack.push(frames);
|
|
12141
10749
|
onHistoryChange();
|
|
12142
10750
|
}
|
|
12143
10751
|
function addToUndoStack(frames) {
|
|
@@ -12161,10 +10769,7 @@ function createRoom(options, config) {
|
|
|
12161
10769
|
eventHub.myPresence.notify(context.myPresence.get());
|
|
12162
10770
|
}
|
|
12163
10771
|
if (storageUpdates !== void 0 && storageUpdates.size > 0) {
|
|
12164
|
-
const updates2 = Array.from(storageUpdates.values()
|
|
12165
|
-
...update,
|
|
12166
|
-
source: toUpdateSource(update.source)
|
|
12167
|
-
}));
|
|
10772
|
+
const updates2 = Array.from(storageUpdates.values());
|
|
12168
10773
|
eventHub.storageBatch.notify(updates2);
|
|
12169
10774
|
}
|
|
12170
10775
|
notifyStorageStatus();
|
|
@@ -12178,69 +10783,19 @@ function createRoom(options, config) {
|
|
|
12178
10783
|
"Internal. Tried to get connection id but connection was never open"
|
|
12179
10784
|
);
|
|
12180
10785
|
}
|
|
12181
|
-
|
|
12182
|
-
function viaOfAckedOp(opId) {
|
|
12183
|
-
const via = viaByOpId.get(opId);
|
|
12184
|
-
if (via === void 0) {
|
|
12185
|
-
return "edit";
|
|
12186
|
-
}
|
|
12187
|
-
viaByOpId.delete(opId);
|
|
12188
|
-
return via;
|
|
12189
|
-
}
|
|
12190
|
-
function applyLocalOps(frames, localSource = LOCAL_EDIT) {
|
|
10786
|
+
function applyLocalOps(frames) {
|
|
12191
10787
|
const [pframes, ops] = partition(
|
|
12192
10788
|
frames,
|
|
12193
10789
|
(f) => f.type === "presence"
|
|
12194
10790
|
);
|
|
12195
|
-
const
|
|
12196
|
-
for (const op of ops) {
|
|
12197
|
-
if (op.type === OpCode.CREATE_TEXT && op.opId === void 0 && context.pool.nodes.get(op.id) === void 0 && !restoredTextIds.has(op.id)) {
|
|
12198
|
-
restoredTextIds.set(op.id, context.pool.generateId());
|
|
12199
|
-
}
|
|
12200
|
-
}
|
|
12201
|
-
const remappedOps = restoredTextIds.size === 0 ? ops : ops.map((op) => {
|
|
12202
|
-
if (op.opId !== void 0) {
|
|
12203
|
-
return op;
|
|
12204
|
-
}
|
|
12205
|
-
const id = restoredTextIds.get(op.id);
|
|
12206
|
-
if (isCreateOp(op)) {
|
|
12207
|
-
const parentId = restoredTextIds.get(op.parentId);
|
|
12208
|
-
const deletedId = op.deletedId === void 0 ? void 0 : restoredTextIds.get(op.deletedId);
|
|
12209
|
-
if (id === void 0 && parentId === void 0 && deletedId === void 0) {
|
|
12210
|
-
return op;
|
|
12211
|
-
}
|
|
12212
|
-
if (op.type === OpCode.CREATE_TEXT && id !== void 0) {
|
|
12213
|
-
return {
|
|
12214
|
-
...op,
|
|
12215
|
-
id,
|
|
12216
|
-
version: 0,
|
|
12217
|
-
...parentId === void 0 ? {} : { parentId },
|
|
12218
|
-
...deletedId === void 0 ? {} : { deletedId }
|
|
12219
|
-
};
|
|
12220
|
-
}
|
|
12221
|
-
return {
|
|
12222
|
-
...op,
|
|
12223
|
-
...id === void 0 ? {} : { id },
|
|
12224
|
-
...parentId === void 0 ? {} : { parentId },
|
|
12225
|
-
...deletedId === void 0 ? {} : { deletedId }
|
|
12226
|
-
};
|
|
12227
|
-
}
|
|
12228
|
-
return id === void 0 ? op : { ...op, id };
|
|
12229
|
-
});
|
|
12230
|
-
const opsWithOpIds = remappedOps.map(
|
|
10791
|
+
const opsWithOpIds = ops.map(
|
|
12231
10792
|
(op) => op.opId === void 0 ? { ...op, opId: context.pool.generateOpId() } : op
|
|
12232
10793
|
);
|
|
12233
|
-
if (localSource.via !== "edit") {
|
|
12234
|
-
for (const op of opsWithOpIds) {
|
|
12235
|
-
viaByOpId.set(op.opId, localSource.via);
|
|
12236
|
-
}
|
|
12237
|
-
}
|
|
12238
10794
|
const { reverse, updates } = applyOps(
|
|
12239
10795
|
pframes,
|
|
12240
10796
|
opsWithOpIds,
|
|
12241
10797
|
/* isLocal */
|
|
12242
|
-
true
|
|
12243
|
-
localSource
|
|
10798
|
+
true
|
|
12244
10799
|
);
|
|
12245
10800
|
return { opsToEmit: opsWithOpIds, reverse, updates };
|
|
12246
10801
|
}
|
|
@@ -12252,7 +10807,7 @@ function createRoom(options, config) {
|
|
|
12252
10807
|
false
|
|
12253
10808
|
);
|
|
12254
10809
|
}
|
|
12255
|
-
function applyOps(pframes, ops, isLocal
|
|
10810
|
+
function applyOps(pframes, ops, isLocal) {
|
|
12256
10811
|
const output = {
|
|
12257
10812
|
reverse: new Deque(),
|
|
12258
10813
|
storageUpdates: /* @__PURE__ */ new Map(),
|
|
@@ -12281,16 +10836,12 @@ function createRoom(options, config) {
|
|
|
12281
10836
|
for (const op of ops) {
|
|
12282
10837
|
let source;
|
|
12283
10838
|
if (isLocal) {
|
|
12284
|
-
source =
|
|
10839
|
+
source = 0 /* LOCAL */;
|
|
12285
10840
|
} else if (op.opId !== void 0) {
|
|
12286
10841
|
context.unacknowledgedOps.delete(op.opId);
|
|
12287
|
-
source =
|
|
12288
|
-
origin: "local",
|
|
12289
|
-
via: viaOfAckedOp(op.opId),
|
|
12290
|
-
optimistic: false
|
|
12291
|
-
};
|
|
10842
|
+
source = 2 /* OURS */;
|
|
12292
10843
|
} else {
|
|
12293
|
-
source =
|
|
10844
|
+
source = 1 /* THEIRS */;
|
|
12294
10845
|
}
|
|
12295
10846
|
const applyOpResult = applyOp(op, source);
|
|
12296
10847
|
if (applyOpResult.modified) {
|
|
@@ -12305,7 +10856,7 @@ function createRoom(options, config) {
|
|
|
12305
10856
|
);
|
|
12306
10857
|
output.reverse.pushLeft(applyOpResult.reverse);
|
|
12307
10858
|
}
|
|
12308
|
-
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) {
|
|
12309
10860
|
createdNodeIds.add(op.id);
|
|
12310
10861
|
}
|
|
12311
10862
|
}
|
|
@@ -12325,13 +10876,12 @@ function createRoom(options, config) {
|
|
|
12325
10876
|
switch (op.type) {
|
|
12326
10877
|
case OpCode.DELETE_OBJECT_KEY:
|
|
12327
10878
|
case OpCode.UPDATE_OBJECT:
|
|
12328
|
-
case OpCode.UPDATE_TEXT:
|
|
12329
10879
|
case OpCode.DELETE_CRDT: {
|
|
12330
10880
|
const node = context.pool.nodes.get(op.id);
|
|
12331
10881
|
if (node === void 0) {
|
|
12332
10882
|
return { modified: false };
|
|
12333
10883
|
}
|
|
12334
|
-
return node._apply(op, source);
|
|
10884
|
+
return node._apply(op, source === 0 /* LOCAL */);
|
|
12335
10885
|
}
|
|
12336
10886
|
case OpCode.SET_PARENT_KEY: {
|
|
12337
10887
|
const node = context.pool.nodes.get(op.id);
|
|
@@ -12350,7 +10900,6 @@ function createRoom(options, config) {
|
|
|
12350
10900
|
case OpCode.CREATE_OBJECT:
|
|
12351
10901
|
case OpCode.CREATE_LIST:
|
|
12352
10902
|
case OpCode.CREATE_MAP:
|
|
12353
|
-
case OpCode.CREATE_TEXT:
|
|
12354
10903
|
case OpCode.CREATE_FILE:
|
|
12355
10904
|
case OpCode.CREATE_REGISTER: {
|
|
12356
10905
|
if (op.parentId === void 0) {
|
|
@@ -12386,7 +10935,7 @@ function createRoom(options, config) {
|
|
|
12386
10935
|
}
|
|
12387
10936
|
context.myPresence.patch(patch);
|
|
12388
10937
|
if (context.activeBatch) {
|
|
12389
|
-
if (_optionalChain([options2, 'optionalAccess',
|
|
10938
|
+
if (_optionalChain([options2, 'optionalAccess', _257 => _257.addToHistory])) {
|
|
12390
10939
|
context.activeBatch.reverseOps.pushLeft({
|
|
12391
10940
|
type: "presence",
|
|
12392
10941
|
data: oldValues
|
|
@@ -12395,7 +10944,7 @@ function createRoom(options, config) {
|
|
|
12395
10944
|
context.activeBatch.updates.presence = true;
|
|
12396
10945
|
} else {
|
|
12397
10946
|
flushNowOrSoon();
|
|
12398
|
-
if (_optionalChain([options2, 'optionalAccess',
|
|
10947
|
+
if (_optionalChain([options2, 'optionalAccess', _258 => _258.addToHistory])) {
|
|
12399
10948
|
addToUndoStack([{ type: "presence", data: oldValues }]);
|
|
12400
10949
|
}
|
|
12401
10950
|
notify({ presence: true });
|
|
@@ -12574,11 +11123,11 @@ function createRoom(options, config) {
|
|
|
12574
11123
|
break;
|
|
12575
11124
|
}
|
|
12576
11125
|
case ServerMsgCode.STORAGE_CHUNK:
|
|
12577
|
-
_optionalChain([stopwatch, 'optionalAccess',
|
|
11126
|
+
_optionalChain([stopwatch, 'optionalAccess', _259 => _259.lap, 'call', _260 => _260()]);
|
|
12578
11127
|
nodeMapBuffer.append(compactNodesToNodeStream(message.nodes));
|
|
12579
11128
|
break;
|
|
12580
11129
|
case ServerMsgCode.STORAGE_STREAM_END: {
|
|
12581
|
-
const timing = _optionalChain([stopwatch, 'optionalAccess',
|
|
11130
|
+
const timing = _optionalChain([stopwatch, 'optionalAccess', _261 => _261.stop, 'call', _262 => _262()]);
|
|
12582
11131
|
if (timing) {
|
|
12583
11132
|
const ms = (v) => `${v.toFixed(1)}ms`;
|
|
12584
11133
|
const rest = timing.laps.slice(1);
|
|
@@ -12605,38 +11154,16 @@ function createRoom(options, config) {
|
|
|
12605
11154
|
}
|
|
12606
11155
|
break;
|
|
12607
11156
|
}
|
|
12608
|
-
// Receiving a RejectedOps message means the server
|
|
12609
|
-
//
|
|
12610
|
-
//
|
|
12611
|
-
//
|
|
12612
|
-
// server's retained history window — and we can recover: drop the
|
|
12613
|
-
// rejected pending state and re-fetch the authoritative storage
|
|
12614
|
-
// snapshot. For other ops (e.g. permission rejections), rolling back
|
|
12615
|
-
// particular Ops is hard/impossible, so we keep the old behavior of
|
|
12616
|
-
// 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.
|
|
12617
11161
|
case ServerMsgCode.REJECT_STORAGE_OP: {
|
|
12618
11162
|
errorWithTitle(
|
|
12619
11163
|
"Storage mutation rejection error",
|
|
12620
11164
|
message.reason
|
|
12621
11165
|
);
|
|
12622
|
-
|
|
12623
|
-
for (const opId of message.opIds) {
|
|
12624
|
-
const rejectedOp = context.unacknowledgedOps.get(opId);
|
|
12625
|
-
context.unacknowledgedOps.delete(opId);
|
|
12626
|
-
context.buffer.storageOperations = context.buffer.storageOperations.filter((op) => op.opId !== opId);
|
|
12627
|
-
viaByOpId.delete(opId);
|
|
12628
|
-
if (rejectedOp !== void 0 && rejectedOp.type === OpCode.UPDATE_TEXT) {
|
|
12629
|
-
const node = context.pool.nodes.get(rejectedOp.id);
|
|
12630
|
-
if (node !== void 0 && isLiveText(node)) {
|
|
12631
|
-
node._rejectPendingOp(opId);
|
|
12632
|
-
needsStorageResync = true;
|
|
12633
|
-
}
|
|
12634
|
-
}
|
|
12635
|
-
}
|
|
12636
|
-
if (needsStorageResync) {
|
|
12637
|
-
refreshStorage();
|
|
12638
|
-
flushNowOrSoon();
|
|
12639
|
-
} else if (process.env.NODE_ENV !== "production") {
|
|
11166
|
+
if (process.env.NODE_ENV !== "production") {
|
|
12640
11167
|
throw new Error(
|
|
12641
11168
|
`Storage mutations rejected by server: ${message.reason}`
|
|
12642
11169
|
);
|
|
@@ -12735,11 +11262,11 @@ function createRoom(options, config) {
|
|
|
12735
11262
|
} else if (pendingFeedsRequests.has(requestId)) {
|
|
12736
11263
|
const pending = pendingFeedsRequests.get(requestId);
|
|
12737
11264
|
pendingFeedsRequests.delete(requestId);
|
|
12738
|
-
_optionalChain([pending, 'optionalAccess',
|
|
11265
|
+
_optionalChain([pending, 'optionalAccess', _263 => _263.reject, 'call', _264 => _264(err)]);
|
|
12739
11266
|
} else if (pendingFeedMessagesRequests.has(requestId)) {
|
|
12740
11267
|
const pending = pendingFeedMessagesRequests.get(requestId);
|
|
12741
11268
|
pendingFeedMessagesRequests.delete(requestId);
|
|
12742
|
-
_optionalChain([pending, 'optionalAccess',
|
|
11269
|
+
_optionalChain([pending, 'optionalAccess', _265 => _265.reject, 'call', _266 => _266(err)]);
|
|
12743
11270
|
}
|
|
12744
11271
|
eventHub.feeds.notify(message);
|
|
12745
11272
|
break;
|
|
@@ -12893,10 +11420,10 @@ function createRoom(options, config) {
|
|
|
12893
11420
|
timeoutId,
|
|
12894
11421
|
kind,
|
|
12895
11422
|
feedId,
|
|
12896
|
-
messageId: _optionalChain([options2, 'optionalAccess',
|
|
12897
|
-
expectedClientMessageId: _optionalChain([options2, 'optionalAccess',
|
|
11423
|
+
messageId: _optionalChain([options2, 'optionalAccess', _267 => _267.messageId]),
|
|
11424
|
+
expectedClientMessageId: _optionalChain([options2, 'optionalAccess', _268 => _268.expectedClientMessageId])
|
|
12898
11425
|
});
|
|
12899
|
-
if (kind === "add-message" && _optionalChain([options2, 'optionalAccess',
|
|
11426
|
+
if (kind === "add-message" && _optionalChain([options2, 'optionalAccess', _269 => _269.expectedClientMessageId]) === void 0) {
|
|
12900
11427
|
const q = _nullishCoalesce(pendingAddMessageFifoByFeed.get(feedId), () => ( []));
|
|
12901
11428
|
q.push(requestId);
|
|
12902
11429
|
pendingAddMessageFifoByFeed.set(feedId, q);
|
|
@@ -12947,10 +11474,10 @@ function createRoom(options, config) {
|
|
|
12947
11474
|
}
|
|
12948
11475
|
if (!matched) {
|
|
12949
11476
|
const q = pendingAddMessageFifoByFeed.get(message.feedId);
|
|
12950
|
-
const headId = _optionalChain([q, 'optionalAccess',
|
|
11477
|
+
const headId = _optionalChain([q, 'optionalAccess', _270 => _270[0]]);
|
|
12951
11478
|
if (headId !== void 0) {
|
|
12952
11479
|
const pending = pendingFeedMutations.get(headId);
|
|
12953
|
-
if (_optionalChain([pending, 'optionalAccess',
|
|
11480
|
+
if (_optionalChain([pending, 'optionalAccess', _271 => _271.kind]) === "add-message" && pending.expectedClientMessageId === void 0) {
|
|
12954
11481
|
settleFeedMutation(headId, "ok");
|
|
12955
11482
|
}
|
|
12956
11483
|
}
|
|
@@ -12986,7 +11513,7 @@ function createRoom(options, config) {
|
|
|
12986
11513
|
const unacknowledgedOps2 = [...context.unacknowledgedOps.values()];
|
|
12987
11514
|
createOrUpdateRootFromMessage(nodes);
|
|
12988
11515
|
applyAndSendOfflineOps(unacknowledgedOps2);
|
|
12989
|
-
_optionalChain([_resolveStoragePromise, 'optionalCall',
|
|
11516
|
+
_optionalChain([_resolveStoragePromise, 'optionalCall', _272 => _272()]);
|
|
12990
11517
|
notifyStorageStatus();
|
|
12991
11518
|
eventHub.storageDidLoad.notify();
|
|
12992
11519
|
}
|
|
@@ -12995,7 +11522,7 @@ function createRoom(options, config) {
|
|
|
12995
11522
|
if (!messages.some((msg) => msg.type === ClientMsgCode.FETCH_STORAGE)) {
|
|
12996
11523
|
messages.push({ type: ClientMsgCode.FETCH_STORAGE });
|
|
12997
11524
|
nodeMapBuffer.take();
|
|
12998
|
-
_optionalChain([stopwatch, 'optionalAccess',
|
|
11525
|
+
_optionalChain([stopwatch, 'optionalAccess', _273 => _273.start, 'call', _274 => _274()]);
|
|
12999
11526
|
}
|
|
13000
11527
|
}
|
|
13001
11528
|
function startLoadingStorage() {
|
|
@@ -13049,10 +11576,10 @@ function createRoom(options, config) {
|
|
|
13049
11576
|
const message = {
|
|
13050
11577
|
type: ClientMsgCode.FETCH_FEEDS,
|
|
13051
11578
|
requestId,
|
|
13052
|
-
cursor: _optionalChain([options2, 'optionalAccess',
|
|
13053
|
-
since: _optionalChain([options2, 'optionalAccess',
|
|
13054
|
-
limit: _optionalChain([options2, 'optionalAccess',
|
|
13055
|
-
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])
|
|
13056
11583
|
};
|
|
13057
11584
|
context.buffer.messages.push(message);
|
|
13058
11585
|
flushNowOrSoon();
|
|
@@ -13072,9 +11599,9 @@ function createRoom(options, config) {
|
|
|
13072
11599
|
type: ClientMsgCode.FETCH_FEED_MESSAGES,
|
|
13073
11600
|
requestId,
|
|
13074
11601
|
feedId,
|
|
13075
|
-
cursor: _optionalChain([options2, 'optionalAccess',
|
|
13076
|
-
since: _optionalChain([options2, 'optionalAccess',
|
|
13077
|
-
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])
|
|
13078
11605
|
};
|
|
13079
11606
|
context.buffer.messages.push(message);
|
|
13080
11607
|
flushNowOrSoon();
|
|
@@ -13093,8 +11620,8 @@ function createRoom(options, config) {
|
|
|
13093
11620
|
type: ClientMsgCode.ADD_FEED,
|
|
13094
11621
|
requestId,
|
|
13095
11622
|
feedId,
|
|
13096
|
-
metadata: _optionalChain([options2, 'optionalAccess',
|
|
13097
|
-
createdAt: _optionalChain([options2, 'optionalAccess',
|
|
11623
|
+
metadata: _optionalChain([options2, 'optionalAccess', _282 => _282.metadata]),
|
|
11624
|
+
createdAt: _optionalChain([options2, 'optionalAccess', _283 => _283.createdAt])
|
|
13098
11625
|
};
|
|
13099
11626
|
context.buffer.messages.push(message);
|
|
13100
11627
|
flushNowOrSoon();
|
|
@@ -13128,15 +11655,15 @@ function createRoom(options, config) {
|
|
|
13128
11655
|
function addFeedMessage(feedId, data, options2) {
|
|
13129
11656
|
const requestId = nanoid();
|
|
13130
11657
|
const promise = registerFeedMutation(requestId, "add-message", feedId, {
|
|
13131
|
-
expectedClientMessageId: _optionalChain([options2, 'optionalAccess',
|
|
11658
|
+
expectedClientMessageId: _optionalChain([options2, 'optionalAccess', _284 => _284.id])
|
|
13132
11659
|
});
|
|
13133
11660
|
const message = {
|
|
13134
11661
|
type: ClientMsgCode.ADD_FEED_MESSAGE,
|
|
13135
11662
|
requestId,
|
|
13136
11663
|
feedId,
|
|
13137
11664
|
data,
|
|
13138
|
-
id: _optionalChain([options2, 'optionalAccess',
|
|
13139
|
-
createdAt: _optionalChain([options2, 'optionalAccess',
|
|
11665
|
+
id: _optionalChain([options2, 'optionalAccess', _285 => _285.id]),
|
|
11666
|
+
createdAt: _optionalChain([options2, 'optionalAccess', _286 => _286.createdAt])
|
|
13140
11667
|
};
|
|
13141
11668
|
context.buffer.messages.push(message);
|
|
13142
11669
|
flushNowOrSoon();
|
|
@@ -13153,7 +11680,7 @@ function createRoom(options, config) {
|
|
|
13153
11680
|
feedId,
|
|
13154
11681
|
messageId,
|
|
13155
11682
|
data,
|
|
13156
|
-
updatedAt: _optionalChain([options2, 'optionalAccess',
|
|
11683
|
+
updatedAt: _optionalChain([options2, 'optionalAccess', _287 => _287.updatedAt])
|
|
13157
11684
|
};
|
|
13158
11685
|
context.buffer.messages.push(message);
|
|
13159
11686
|
flushNowOrSoon();
|
|
@@ -13178,15 +11705,14 @@ function createRoom(options, config) {
|
|
|
13178
11705
|
if (context.activeBatch) {
|
|
13179
11706
|
throw new Error("undo is not allowed during a batch");
|
|
13180
11707
|
}
|
|
13181
|
-
const
|
|
13182
|
-
if (
|
|
11708
|
+
const frames = context.undoStack.pop();
|
|
11709
|
+
if (frames === void 0) {
|
|
13183
11710
|
return;
|
|
13184
11711
|
}
|
|
13185
11712
|
context.pausedHistory = null;
|
|
13186
|
-
const result = applyLocalOps(
|
|
13187
|
-
context.redoStack.push({ id: item.id, frames: result.reverse });
|
|
13188
|
-
notifyPrivateHistory({ action: "undo", id: item.id });
|
|
11713
|
+
const result = applyLocalOps(frames);
|
|
13189
11714
|
notify(result.updates);
|
|
11715
|
+
context.redoStack.push(result.reverse);
|
|
13190
11716
|
onHistoryChange();
|
|
13191
11717
|
for (const op of result.opsToEmit) {
|
|
13192
11718
|
context.buffer.storageOperations.push(op);
|
|
@@ -13197,15 +11723,14 @@ function createRoom(options, config) {
|
|
|
13197
11723
|
if (context.activeBatch) {
|
|
13198
11724
|
throw new Error("redo is not allowed during a batch");
|
|
13199
11725
|
}
|
|
13200
|
-
const
|
|
13201
|
-
if (
|
|
11726
|
+
const frames = context.redoStack.pop();
|
|
11727
|
+
if (frames === void 0) {
|
|
13202
11728
|
return;
|
|
13203
11729
|
}
|
|
13204
11730
|
context.pausedHistory = null;
|
|
13205
|
-
const result = applyLocalOps(
|
|
13206
|
-
context.undoStack.push({ id: item.id, frames: result.reverse });
|
|
13207
|
-
notifyPrivateHistory({ action: "redo", id: item.id });
|
|
11731
|
+
const result = applyLocalOps(frames);
|
|
13208
11732
|
notify(result.updates);
|
|
11733
|
+
context.undoStack.push(result.reverse);
|
|
13209
11734
|
onHistoryChange();
|
|
13210
11735
|
for (const op of result.opsToEmit) {
|
|
13211
11736
|
context.buffer.storageOperations.push(op);
|
|
@@ -13215,8 +11740,6 @@ function createRoom(options, config) {
|
|
|
13215
11740
|
function clear() {
|
|
13216
11741
|
context.undoStack.length = 0;
|
|
13217
11742
|
context.redoStack.length = 0;
|
|
13218
|
-
notifyPrivateHistory({ action: "clear" });
|
|
13219
|
-
onHistoryChange();
|
|
13220
11743
|
}
|
|
13221
11744
|
function batch2(callback) {
|
|
13222
11745
|
if (context.activeBatch) {
|
|
@@ -13244,8 +11767,8 @@ function createRoom(options, config) {
|
|
|
13244
11767
|
if (currentBatch.scheduleHistoryResume) {
|
|
13245
11768
|
commitPausedHistoryToUndoStack();
|
|
13246
11769
|
}
|
|
13247
|
-
if (currentBatch.ops.length > 0
|
|
13248
|
-
|
|
11770
|
+
if (currentBatch.ops.length > 0) {
|
|
11771
|
+
context.redoStack.length = 0;
|
|
13249
11772
|
}
|
|
13250
11773
|
if (currentBatch.ops.length > 0) {
|
|
13251
11774
|
dispatchOps(currentBatch.ops);
|
|
@@ -13274,6 +11797,7 @@ function createRoom(options, config) {
|
|
|
13274
11797
|
}
|
|
13275
11798
|
commitPausedHistoryToUndoStack();
|
|
13276
11799
|
}
|
|
11800
|
+
let historyDisabled = 0;
|
|
13277
11801
|
function disableHistory(fn) {
|
|
13278
11802
|
const origUndo = context.undoStack;
|
|
13279
11803
|
const origRedo = context.redoStack;
|
|
@@ -13363,8 +11887,8 @@ function createRoom(options, config) {
|
|
|
13363
11887
|
async function getThreads(options2) {
|
|
13364
11888
|
return httpClient.getThreads({
|
|
13365
11889
|
roomId,
|
|
13366
|
-
query: _optionalChain([options2, 'optionalAccess',
|
|
13367
|
-
cursor: _optionalChain([options2, 'optionalAccess',
|
|
11890
|
+
query: _optionalChain([options2, 'optionalAccess', _288 => _288.query]),
|
|
11891
|
+
cursor: _optionalChain([options2, 'optionalAccess', _289 => _289.cursor])
|
|
13368
11892
|
});
|
|
13369
11893
|
}
|
|
13370
11894
|
async function getThread(threadId) {
|
|
@@ -13497,7 +12021,7 @@ function createRoom(options, config) {
|
|
|
13497
12021
|
function getSubscriptionSettings(options2) {
|
|
13498
12022
|
return httpClient.getSubscriptionSettings({
|
|
13499
12023
|
roomId,
|
|
13500
|
-
signal: _optionalChain([options2, 'optionalAccess',
|
|
12024
|
+
signal: _optionalChain([options2, 'optionalAccess', _290 => _290.signal])
|
|
13501
12025
|
});
|
|
13502
12026
|
}
|
|
13503
12027
|
function updateSubscriptionSettings(settings) {
|
|
@@ -13519,45 +12043,30 @@ function createRoom(options, config) {
|
|
|
13519
12043
|
{
|
|
13520
12044
|
[kInternal]: {
|
|
13521
12045
|
get presenceBuffer() {
|
|
13522
|
-
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)));
|
|
13523
12047
|
},
|
|
13524
12048
|
// prettier-ignore
|
|
13525
12049
|
get undoStack() {
|
|
13526
|
-
return
|
|
13527
|
-
context.undoStack.map((item) => ({
|
|
13528
|
-
id: item.id,
|
|
13529
|
-
frames: item.frames
|
|
13530
|
-
}))
|
|
13531
|
-
);
|
|
13532
|
-
},
|
|
13533
|
-
// prettier-ignore
|
|
13534
|
-
get redoStack() {
|
|
13535
|
-
return structuredClone(
|
|
13536
|
-
context.redoStack.map((item) => ({
|
|
13537
|
-
id: item.id,
|
|
13538
|
-
frames: item.frames
|
|
13539
|
-
}))
|
|
13540
|
-
);
|
|
12050
|
+
return deepClone(context.undoStack);
|
|
13541
12051
|
},
|
|
13542
12052
|
// prettier-ignore
|
|
13543
12053
|
get nodeCount() {
|
|
13544
12054
|
return context.pool.nodes.size;
|
|
13545
12055
|
},
|
|
13546
12056
|
// prettier-ignore
|
|
13547
|
-
history: eventHub.privateHistory.observable,
|
|
13548
12057
|
getYjsProvider() {
|
|
13549
12058
|
return context.yjsProvider;
|
|
13550
12059
|
},
|
|
13551
12060
|
setYjsProvider(newProvider) {
|
|
13552
|
-
_optionalChain([context, 'access',
|
|
12061
|
+
_optionalChain([context, 'access', _294 => _294.yjsProvider, 'optionalAccess', _295 => _295.off, 'call', _296 => _296("status", yjsStatusDidChange)]);
|
|
13553
12062
|
context.yjsProvider = newProvider;
|
|
13554
|
-
_optionalChain([newProvider, 'optionalAccess',
|
|
12063
|
+
_optionalChain([newProvider, 'optionalAccess', _297 => _297.on, 'call', _298 => _298("status", yjsStatusDidChange)]);
|
|
13555
12064
|
context.yjsProviderDidChange.notify();
|
|
13556
12065
|
},
|
|
13557
12066
|
yjsProviderDidChange: context.yjsProviderDidChange.observable,
|
|
13558
12067
|
// send metadata when using a text editor
|
|
13559
12068
|
reportTextEditor,
|
|
13560
|
-
getPermissionMatrix: () => _optionalChain([context, 'access',
|
|
12069
|
+
getPermissionMatrix: () => _optionalChain([context, 'access', _299 => _299.dynamicSessionInfoSig, 'access', _300 => _300.get, 'call', _301 => _301(), 'optionalAccess', _302 => _302.permissionMatrix]),
|
|
13561
12070
|
// create a text mention when using a text editor
|
|
13562
12071
|
createTextMention,
|
|
13563
12072
|
// delete a text mention when using a text editor
|
|
@@ -13620,7 +12129,7 @@ ${dumpPool(
|
|
|
13620
12129
|
source.dispose();
|
|
13621
12130
|
}
|
|
13622
12131
|
eventHub.roomWillDestroy.notify();
|
|
13623
|
-
_optionalChain([context, 'access',
|
|
12132
|
+
_optionalChain([context, 'access', _303 => _303.yjsProvider, 'optionalAccess', _304 => _304.off, 'call', _305 => _305("status", yjsStatusDidChange)]);
|
|
13624
12133
|
syncSourceForStorage.destroy();
|
|
13625
12134
|
syncSourceForYjs.destroy();
|
|
13626
12135
|
uninstallBgTabSpy();
|
|
@@ -13784,7 +12293,7 @@ function makeClassicSubscribeFn(roomId, events, errorEvents) {
|
|
|
13784
12293
|
}
|
|
13785
12294
|
if (isLiveNode(first)) {
|
|
13786
12295
|
const node = first;
|
|
13787
|
-
if (_optionalChain([options, 'optionalAccess',
|
|
12296
|
+
if (_optionalChain([options, 'optionalAccess', _306 => _306.isDeep])) {
|
|
13788
12297
|
const storageCallback = second;
|
|
13789
12298
|
return subscribeToLiveStructureDeeply(node, storageCallback);
|
|
13790
12299
|
} else {
|
|
@@ -13874,8 +12383,8 @@ function createClient(options) {
|
|
|
13874
12383
|
const authManager = createAuthManager(options, (token) => {
|
|
13875
12384
|
currentUserId.set(() => token.uid);
|
|
13876
12385
|
});
|
|
13877
|
-
const fetchPolyfill = _optionalChain([clientOptions, 'access',
|
|
13878
|
-
_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)]);
|
|
13879
12388
|
const httpClient = createApiClient({
|
|
13880
12389
|
baseUrl,
|
|
13881
12390
|
fetchPolyfill,
|
|
@@ -13892,7 +12401,7 @@ function createClient(options) {
|
|
|
13892
12401
|
delegates: {
|
|
13893
12402
|
createSocket: makeCreateSocketDelegateForAi(
|
|
13894
12403
|
baseUrl,
|
|
13895
|
-
_optionalChain([clientOptions, 'access',
|
|
12404
|
+
_optionalChain([clientOptions, 'access', _312 => _312.polyfills, 'optionalAccess', _313 => _313.WebSocket])
|
|
13896
12405
|
),
|
|
13897
12406
|
authenticate: async () => {
|
|
13898
12407
|
const resp = await authManager.getAuthValue({
|
|
@@ -13963,7 +12472,7 @@ function createClient(options) {
|
|
|
13963
12472
|
createSocket: makeCreateSocketDelegateForRoom(
|
|
13964
12473
|
roomId,
|
|
13965
12474
|
baseUrl,
|
|
13966
|
-
_optionalChain([clientOptions, 'access',
|
|
12475
|
+
_optionalChain([clientOptions, 'access', _314 => _314.polyfills, 'optionalAccess', _315 => _315.WebSocket])
|
|
13967
12476
|
),
|
|
13968
12477
|
authenticate: makeAuthDelegateForRoom(roomId, authManager)
|
|
13969
12478
|
})),
|
|
@@ -13985,7 +12494,7 @@ function createClient(options) {
|
|
|
13985
12494
|
const shouldConnect = _nullishCoalesce(options2.autoConnect, () => ( true));
|
|
13986
12495
|
if (shouldConnect) {
|
|
13987
12496
|
if (typeof atob === "undefined") {
|
|
13988
|
-
if (_optionalChain([clientOptions, 'access',
|
|
12497
|
+
if (_optionalChain([clientOptions, 'access', _316 => _316.polyfills, 'optionalAccess', _317 => _317.atob]) === void 0) {
|
|
13989
12498
|
throw new Error(
|
|
13990
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"
|
|
13991
12500
|
);
|
|
@@ -13997,7 +12506,7 @@ function createClient(options) {
|
|
|
13997
12506
|
return leaseRoom(newRoomDetails);
|
|
13998
12507
|
}
|
|
13999
12508
|
function getRoom(roomId) {
|
|
14000
|
-
const room = _optionalChain([roomsById, 'access',
|
|
12509
|
+
const room = _optionalChain([roomsById, 'access', _318 => _318.get, 'call', _319 => _319(roomId), 'optionalAccess', _320 => _320.room]);
|
|
14001
12510
|
return room ? room : null;
|
|
14002
12511
|
}
|
|
14003
12512
|
function logout() {
|
|
@@ -14013,7 +12522,7 @@ function createClient(options) {
|
|
|
14013
12522
|
const batchedResolveUsers = new Batch(
|
|
14014
12523
|
async (batchedUserIds) => {
|
|
14015
12524
|
const userIds = batchedUserIds.flat();
|
|
14016
|
-
const users = await _optionalChain([resolveUsers, 'optionalCall',
|
|
12525
|
+
const users = await _optionalChain([resolveUsers, 'optionalCall', _321 => _321({ userIds })]);
|
|
14017
12526
|
warnOnceIf(
|
|
14018
12527
|
!resolveUsers,
|
|
14019
12528
|
"Set the resolveUsers option in createClient to specify user info."
|
|
@@ -14030,7 +12539,7 @@ function createClient(options) {
|
|
|
14030
12539
|
const batchedResolveRoomsInfo = new Batch(
|
|
14031
12540
|
async (batchedRoomIds) => {
|
|
14032
12541
|
const roomIds = batchedRoomIds.flat();
|
|
14033
|
-
const roomsInfo = await _optionalChain([resolveRoomsInfo, 'optionalCall',
|
|
12542
|
+
const roomsInfo = await _optionalChain([resolveRoomsInfo, 'optionalCall', _322 => _322({ roomIds })]);
|
|
14034
12543
|
warnOnceIf(
|
|
14035
12544
|
!resolveRoomsInfo,
|
|
14036
12545
|
"Set the resolveRoomsInfo option in createClient to specify room info."
|
|
@@ -14047,7 +12556,7 @@ function createClient(options) {
|
|
|
14047
12556
|
const batchedResolveGroupsInfo = new Batch(
|
|
14048
12557
|
async (batchedGroupIds) => {
|
|
14049
12558
|
const groupIds = batchedGroupIds.flat();
|
|
14050
|
-
const groupsInfo = await _optionalChain([resolveGroupsInfo, 'optionalCall',
|
|
12559
|
+
const groupsInfo = await _optionalChain([resolveGroupsInfo, 'optionalCall', _323 => _323({ groupIds })]);
|
|
14051
12560
|
warnOnceIf(
|
|
14052
12561
|
!resolveGroupsInfo,
|
|
14053
12562
|
"Set the resolveGroupsInfo option in createClient to specify group info."
|
|
@@ -14106,7 +12615,7 @@ function createClient(options) {
|
|
|
14106
12615
|
}
|
|
14107
12616
|
};
|
|
14108
12617
|
const win = typeof window !== "undefined" ? window : void 0;
|
|
14109
|
-
_optionalChain([win, 'optionalAccess',
|
|
12618
|
+
_optionalChain([win, 'optionalAccess', _324 => _324.addEventListener, 'call', _325 => _325("beforeunload", maybePreventClose)]);
|
|
14110
12619
|
}
|
|
14111
12620
|
async function getNotificationSettings(options2) {
|
|
14112
12621
|
const plainSettings = await httpClient.getNotificationSettings(options2);
|
|
@@ -14234,7 +12743,7 @@ var commentBodyElementsTypes = {
|
|
|
14234
12743
|
mention: "inline"
|
|
14235
12744
|
};
|
|
14236
12745
|
function traverseCommentBody(body, elementOrVisitor, possiblyVisitor) {
|
|
14237
|
-
if (!body || !_optionalChain([body, 'optionalAccess',
|
|
12746
|
+
if (!body || !_optionalChain([body, 'optionalAccess', _326 => _326.content])) {
|
|
14238
12747
|
return;
|
|
14239
12748
|
}
|
|
14240
12749
|
const element = typeof elementOrVisitor === "string" ? elementOrVisitor : void 0;
|
|
@@ -14244,13 +12753,13 @@ function traverseCommentBody(body, elementOrVisitor, possiblyVisitor) {
|
|
|
14244
12753
|
for (const block of body.content) {
|
|
14245
12754
|
if (type === "all" || type === "block") {
|
|
14246
12755
|
if (guard(block)) {
|
|
14247
|
-
_optionalChain([visitor, 'optionalCall',
|
|
12756
|
+
_optionalChain([visitor, 'optionalCall', _327 => _327(block)]);
|
|
14248
12757
|
}
|
|
14249
12758
|
}
|
|
14250
12759
|
if (type === "all" || type === "inline") {
|
|
14251
12760
|
for (const inline of block.children) {
|
|
14252
12761
|
if (guard(inline)) {
|
|
14253
|
-
_optionalChain([visitor, 'optionalCall',
|
|
12762
|
+
_optionalChain([visitor, 'optionalCall', _328 => _328(inline)]);
|
|
14254
12763
|
}
|
|
14255
12764
|
}
|
|
14256
12765
|
}
|
|
@@ -14420,7 +12929,7 @@ var stringifyCommentBodyPlainElements = {
|
|
|
14420
12929
|
text: ({ element }) => element.text,
|
|
14421
12930
|
link: ({ element }) => _nullishCoalesce(element.text, () => ( element.url)),
|
|
14422
12931
|
mention: ({ element, user, group }) => {
|
|
14423
|
-
return `@${_nullishCoalesce(_nullishCoalesce(_optionalChain([user, 'optionalAccess',
|
|
12932
|
+
return `@${_nullishCoalesce(_nullishCoalesce(_optionalChain([user, 'optionalAccess', _329 => _329.name]), () => ( _optionalChain([group, 'optionalAccess', _330 => _330.name]))), () => ( element.id))}`;
|
|
14424
12933
|
}
|
|
14425
12934
|
};
|
|
14426
12935
|
var stringifyCommentBodyHtmlElements = {
|
|
@@ -14450,7 +12959,7 @@ var stringifyCommentBodyHtmlElements = {
|
|
|
14450
12959
|
return html`<a href="${href}" target="_blank" rel="noopener noreferrer">${element.text ? html`${element.text}` : element.url}</a>`;
|
|
14451
12960
|
},
|
|
14452
12961
|
mention: ({ element, user, group }) => {
|
|
14453
|
-
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>`;
|
|
14454
12963
|
}
|
|
14455
12964
|
};
|
|
14456
12965
|
var stringifyCommentBodyMarkdownElements = {
|
|
@@ -14480,20 +12989,20 @@ var stringifyCommentBodyMarkdownElements = {
|
|
|
14480
12989
|
return markdown`[${_nullishCoalesce(element.text, () => ( element.url))}](${href})`;
|
|
14481
12990
|
},
|
|
14482
12991
|
mention: ({ element, user, group }) => {
|
|
14483
|
-
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))}`;
|
|
14484
12993
|
}
|
|
14485
12994
|
};
|
|
14486
12995
|
async function stringifyCommentBody(body, options) {
|
|
14487
|
-
const format = _nullishCoalesce(_optionalChain([options, 'optionalAccess',
|
|
14488
|
-
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")));
|
|
14489
12998
|
const elements = {
|
|
14490
12999
|
...format === "html" ? stringifyCommentBodyHtmlElements : format === "markdown" ? stringifyCommentBodyMarkdownElements : stringifyCommentBodyPlainElements,
|
|
14491
|
-
..._optionalChain([options, 'optionalAccess',
|
|
13000
|
+
..._optionalChain([options, 'optionalAccess', _339 => _339.elements])
|
|
14492
13001
|
};
|
|
14493
13002
|
const { users: resolvedUsers, groups: resolvedGroupsInfo } = await resolveMentionsInCommentBody(
|
|
14494
13003
|
body,
|
|
14495
|
-
_optionalChain([options, 'optionalAccess',
|
|
14496
|
-
_optionalChain([options, 'optionalAccess',
|
|
13004
|
+
_optionalChain([options, 'optionalAccess', _340 => _340.resolveUsers]),
|
|
13005
|
+
_optionalChain([options, 'optionalAccess', _341 => _341.resolveGroupsInfo])
|
|
14497
13006
|
);
|
|
14498
13007
|
const blocks = body.content.flatMap((block, blockIndex) => {
|
|
14499
13008
|
switch (block.type) {
|
|
@@ -14575,12 +13084,6 @@ function toPlainLson(lson) {
|
|
|
14575
13084
|
liveblocksType: "LiveList",
|
|
14576
13085
|
data: [...lson].map((item) => toPlainLson(item))
|
|
14577
13086
|
};
|
|
14578
|
-
} else if (lson instanceof LiveText) {
|
|
14579
|
-
return {
|
|
14580
|
-
liveblocksType: "LiveText",
|
|
14581
|
-
data: lson.toJSON(),
|
|
14582
|
-
version: lson.version
|
|
14583
|
-
};
|
|
14584
13087
|
} else if (lson instanceof LiveFile) {
|
|
14585
13088
|
return {
|
|
14586
13089
|
liveblocksType: "LiveFile",
|
|
@@ -14639,9 +13142,9 @@ function makePoller(callback, intervalMs, options) {
|
|
|
14639
13142
|
const startTime = performance.now();
|
|
14640
13143
|
const doc = typeof document !== "undefined" ? document : void 0;
|
|
14641
13144
|
const win = typeof window !== "undefined" ? window : void 0;
|
|
14642
|
-
const maxStaleTimeMs = _nullishCoalesce(_optionalChain([options, 'optionalAccess',
|
|
13145
|
+
const maxStaleTimeMs = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _342 => _342.maxStaleTimeMs]), () => ( Number.POSITIVE_INFINITY));
|
|
14643
13146
|
const context = {
|
|
14644
|
-
inForeground: _optionalChain([doc, 'optionalAccess',
|
|
13147
|
+
inForeground: _optionalChain([doc, 'optionalAccess', _343 => _343.visibilityState]) !== "hidden",
|
|
14645
13148
|
lastSuccessfulPollAt: startTime,
|
|
14646
13149
|
count: 0,
|
|
14647
13150
|
backoff: 0
|
|
@@ -14722,11 +13225,11 @@ function makePoller(callback, intervalMs, options) {
|
|
|
14722
13225
|
pollNowIfStale();
|
|
14723
13226
|
}
|
|
14724
13227
|
function onVisibilityChange() {
|
|
14725
|
-
setInForeground(_optionalChain([doc, 'optionalAccess',
|
|
13228
|
+
setInForeground(_optionalChain([doc, 'optionalAccess', _344 => _344.visibilityState]) !== "hidden");
|
|
14726
13229
|
}
|
|
14727
|
-
_optionalChain([doc, 'optionalAccess',
|
|
14728
|
-
_optionalChain([win, 'optionalAccess',
|
|
14729
|
-
_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)]);
|
|
14730
13233
|
fsm.start();
|
|
14731
13234
|
return {
|
|
14732
13235
|
inc,
|
|
@@ -14875,10 +13378,5 @@ detectDupes(PKG_NAME, PKG_VERSION, PKG_FORMAT);
|
|
|
14875
13378
|
|
|
14876
13379
|
|
|
14877
13380
|
|
|
14878
|
-
|
|
14879
|
-
|
|
14880
|
-
|
|
14881
|
-
|
|
14882
|
-
|
|
14883
|
-
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.normalizeLiveTextOperations = normalizeLiveTextOperations; 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;
|
|
14884
13382
|
//# sourceMappingURL=index.cjs.map
|