@liveblocks/server 1.6.2 → 1.8.0-pre1
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 +292 -39
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +55 -21
- package/dist/index.d.ts +55 -21
- package/dist/index.js +279 -26
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -165,7 +165,21 @@ var jsonObjectYolo = jsonYolo.refine(
|
|
|
165
165
|
|
|
166
166
|
|
|
167
167
|
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
|
|
168
174
|
var intent = _decoders.oneOf.call(void 0, ["set", "push"]);
|
|
175
|
+
var storageFileId = _decoders.sized.call(void 0, _decoders.startsWith.call(void 0, "fl_"), { size: 24 });
|
|
176
|
+
var fileSize = _decoders.number.refine(
|
|
177
|
+
(value) => Number.isSafeInteger(value) && value >= 0,
|
|
178
|
+
"Must be a valid file size"
|
|
179
|
+
);
|
|
180
|
+
var liveTextVersion = _decoders.number.reject(
|
|
181
|
+
(value) => Number.isSafeInteger(value) && value >= 0 ? null : "Must be a non-negative safe integer"
|
|
182
|
+
);
|
|
169
183
|
var updateObjectOp = _decoders.object.call(void 0, {
|
|
170
184
|
type: _decoders.constant.call(void 0, _core.OpCode.UPDATE_OBJECT),
|
|
171
185
|
opId: _decoders.string,
|
|
@@ -210,6 +224,64 @@ var createRegisterOp = _decoders.object.call(void 0, {
|
|
|
210
224
|
intent: _decoders.optional.call(void 0, intent),
|
|
211
225
|
deletedId: _decoders.optional.call(void 0, _decoders.string)
|
|
212
226
|
});
|
|
227
|
+
var liveTextSegment = _decoders.either.call(void 0,
|
|
228
|
+
_decoders.tuple.call(void 0, _decoders.string),
|
|
229
|
+
_decoders.tuple.call(void 0, _decoders.string, jsonObjectYolo)
|
|
230
|
+
);
|
|
231
|
+
var liveTextData = _decoders.array.call(void 0, liveTextSegment);
|
|
232
|
+
var textOperation = _decoders.taggedUnion.call(void 0, "type", {
|
|
233
|
+
insert: _decoders.object.call(void 0, {
|
|
234
|
+
type: _decoders.constant.call(void 0, "insert"),
|
|
235
|
+
index: _decoders.number,
|
|
236
|
+
text: _decoders.string,
|
|
237
|
+
attributes: _decoders.optional.call(void 0, jsonObjectYolo)
|
|
238
|
+
}),
|
|
239
|
+
delete: _decoders.object.call(void 0, {
|
|
240
|
+
type: _decoders.constant.call(void 0, "delete"),
|
|
241
|
+
index: _decoders.number,
|
|
242
|
+
length: _decoders.number
|
|
243
|
+
}),
|
|
244
|
+
format: _decoders.object.call(void 0, {
|
|
245
|
+
type: _decoders.constant.call(void 0, "format"),
|
|
246
|
+
index: _decoders.number,
|
|
247
|
+
length: _decoders.number,
|
|
248
|
+
attributes: jsonObjectYolo
|
|
249
|
+
})
|
|
250
|
+
});
|
|
251
|
+
var createTextOp = _decoders.object.call(void 0, {
|
|
252
|
+
type: _decoders.constant.call(void 0, _core.OpCode.CREATE_TEXT),
|
|
253
|
+
opId: _decoders.string,
|
|
254
|
+
id: _decoders.string,
|
|
255
|
+
parentId: _decoders.string,
|
|
256
|
+
parentKey: _decoders.string,
|
|
257
|
+
data: liveTextData,
|
|
258
|
+
version: liveTextVersion,
|
|
259
|
+
intent: _decoders.optional.call(void 0, intent),
|
|
260
|
+
deletedId: _decoders.optional.call(void 0, _decoders.string)
|
|
261
|
+
});
|
|
262
|
+
var createFileOp = _decoders.object.call(void 0, {
|
|
263
|
+
type: _decoders.constant.call(void 0, _core.OpCode.CREATE_FILE),
|
|
264
|
+
opId: _decoders.string,
|
|
265
|
+
id: _decoders.string,
|
|
266
|
+
parentId: _decoders.string,
|
|
267
|
+
parentKey: _decoders.string,
|
|
268
|
+
data: _decoders.object.call(void 0, {
|
|
269
|
+
id: storageFileId,
|
|
270
|
+
name: _decoders.string,
|
|
271
|
+
size: fileSize,
|
|
272
|
+
mimeType: _decoders.string
|
|
273
|
+
}),
|
|
274
|
+
intent: _decoders.optional.call(void 0, intent),
|
|
275
|
+
deletedId: _decoders.optional.call(void 0, _decoders.string)
|
|
276
|
+
});
|
|
277
|
+
var updateTextOp = _decoders.object.call(void 0, {
|
|
278
|
+
type: _decoders.constant.call(void 0, _core.OpCode.UPDATE_TEXT),
|
|
279
|
+
opId: _decoders.string,
|
|
280
|
+
id: _decoders.string,
|
|
281
|
+
baseVersion: liveTextVersion,
|
|
282
|
+
version: _decoders.optional.call(void 0, liveTextVersion),
|
|
283
|
+
ops: _decoders.array.call(void 0, textOperation)
|
|
284
|
+
});
|
|
213
285
|
var deleteCrdtOp = _decoders.object.call(void 0, {
|
|
214
286
|
type: _decoders.constant.call(void 0, _core.OpCode.DELETE_CRDT),
|
|
215
287
|
opId: _decoders.string,
|
|
@@ -233,6 +305,9 @@ var op = _decoders.taggedUnion.call(void 0, "type", {
|
|
|
233
305
|
[_core.OpCode.CREATE_LIST]: createListOp,
|
|
234
306
|
[_core.OpCode.CREATE_MAP]: createMapOp,
|
|
235
307
|
[_core.OpCode.CREATE_REGISTER]: createRegisterOp,
|
|
308
|
+
[_core.OpCode.CREATE_TEXT]: createTextOp,
|
|
309
|
+
[_core.OpCode.UPDATE_TEXT]: updateTextOp,
|
|
310
|
+
[_core.OpCode.CREATE_FILE]: createFileOp,
|
|
236
311
|
[_core.OpCode.DELETE_CRDT]: deleteCrdtOp,
|
|
237
312
|
[_core.OpCode.SET_PARENT_KEY]: setParentKeyOp,
|
|
238
313
|
[_core.OpCode.DELETE_OBJECT_KEY]: deleteObjectKeyOp
|
|
@@ -372,6 +447,10 @@ function buildNode(snapshot2, id) {
|
|
|
372
447
|
return buildList(snapshot2, id);
|
|
373
448
|
} else if (node.type === _core.CrdtType.MAP) {
|
|
374
449
|
return buildMap(snapshot2, id);
|
|
450
|
+
} else if (node.type === _core.CrdtType.TEXT) {
|
|
451
|
+
return node.data;
|
|
452
|
+
} else if (node.type === _core.CrdtType.FILE) {
|
|
453
|
+
return node.data;
|
|
375
454
|
} else {
|
|
376
455
|
return node.data;
|
|
377
456
|
}
|
|
@@ -415,6 +494,10 @@ function* emit(snapshot2, id) {
|
|
|
415
494
|
yield* emitMap(snapshot2, id);
|
|
416
495
|
} else if (node.type === _core.CrdtType.REGISTER) {
|
|
417
496
|
yield JSON.stringify(node.data);
|
|
497
|
+
} else if (node.type === _core.CrdtType.TEXT) {
|
|
498
|
+
yield JSON.stringify(node.data);
|
|
499
|
+
} else if (node.type === _core.CrdtType.FILE) {
|
|
500
|
+
yield JSON.stringify(node.data);
|
|
418
501
|
}
|
|
419
502
|
}
|
|
420
503
|
function* emitObject(snapshot2, id, staticJson) {
|
|
@@ -486,6 +569,29 @@ function* iterJson(key, data, parent, state) {
|
|
|
486
569
|
case "LiveMap":
|
|
487
570
|
yield* iterMap(key, data.data, parent, state);
|
|
488
571
|
return;
|
|
572
|
+
case "LiveText":
|
|
573
|
+
yield [
|
|
574
|
+
generateId(state),
|
|
575
|
+
{
|
|
576
|
+
type: _core.CrdtType.TEXT,
|
|
577
|
+
data: data.data,
|
|
578
|
+
version: _nullishCoalesce(data.version, () => ( 0)),
|
|
579
|
+
parentId: parent[0],
|
|
580
|
+
parentKey: key
|
|
581
|
+
}
|
|
582
|
+
];
|
|
583
|
+
return;
|
|
584
|
+
case "LiveFile":
|
|
585
|
+
yield [
|
|
586
|
+
generateId(state),
|
|
587
|
+
{
|
|
588
|
+
type: _core.CrdtType.FILE,
|
|
589
|
+
data: data.data,
|
|
590
|
+
parentId: parent[0],
|
|
591
|
+
parentKey: key
|
|
592
|
+
}
|
|
593
|
+
];
|
|
594
|
+
return;
|
|
489
595
|
// istanbul ignore next
|
|
490
596
|
default:
|
|
491
597
|
_core.assertNever.call(void 0, data, "Unknown `liveblocksType` field");
|
|
@@ -570,6 +676,13 @@ function buildNode2(snapshot2, id) {
|
|
|
570
676
|
return buildList2(snapshot2, id);
|
|
571
677
|
} else if (node.type === _core.CrdtType.MAP) {
|
|
572
678
|
return buildMap2(snapshot2, id);
|
|
679
|
+
} else if (node.type === _core.CrdtType.TEXT) {
|
|
680
|
+
return {
|
|
681
|
+
liveblocksType: "LiveText",
|
|
682
|
+
data: node.data
|
|
683
|
+
};
|
|
684
|
+
} else if (node.type === _core.CrdtType.FILE) {
|
|
685
|
+
return { liveblocksType: "LiveFile", data: node.data };
|
|
573
686
|
} else {
|
|
574
687
|
return _nullishCoalesce(node.data, () => ( null));
|
|
575
688
|
}
|
|
@@ -616,6 +729,15 @@ function* emit2(snapshot2, id) {
|
|
|
616
729
|
yield* emitMap2(snapshot2, id);
|
|
617
730
|
} else if (node.type === _core.CrdtType.REGISTER) {
|
|
618
731
|
yield JSON.stringify(_nullishCoalesce(node.data, () => ( null)));
|
|
732
|
+
} else if (node.type === _core.CrdtType.TEXT) {
|
|
733
|
+
yield JSON.stringify({
|
|
734
|
+
liveblocksType: "LiveText",
|
|
735
|
+
data: node.data
|
|
736
|
+
});
|
|
737
|
+
} else if (node.type === _core.CrdtType.FILE) {
|
|
738
|
+
yield '{"liveblocksType":"LiveFile","data":';
|
|
739
|
+
yield JSON.stringify(node.data);
|
|
740
|
+
yield "}";
|
|
619
741
|
}
|
|
620
742
|
}
|
|
621
743
|
function* emitObject2(snapshot2, id, staticJson) {
|
|
@@ -1012,9 +1134,10 @@ function buildReverseLookup(nodes) {
|
|
|
1012
1134
|
delete node.data[key];
|
|
1013
1135
|
}
|
|
1014
1136
|
}
|
|
1015
|
-
|
|
1137
|
+
const isLeafNode = node.type === _core.CrdtType.REGISTER || node.type === _core.CrdtType.FILE || node.type === _core.CrdtType.TEXT;
|
|
1138
|
+
if (!isLeafNode) {
|
|
1016
1139
|
queue.push(...revNodes.valuesAt(nodeId));
|
|
1017
|
-
} else {
|
|
1140
|
+
} else if (node.type === _core.CrdtType.REGISTER) {
|
|
1018
1141
|
const parent = nodes.get(node.parentId);
|
|
1019
1142
|
if (_optionalChain([parent, 'optionalAccess', _34 => _34.type]) === _core.CrdtType.OBJECT) {
|
|
1020
1143
|
continue;
|
|
@@ -1035,7 +1158,6 @@ function hasStaticDataAt(node, key) {
|
|
|
1035
1158
|
return node.type === _core.CrdtType.OBJECT && Object.prototype.hasOwnProperty.call(node.data, key) && node.data[key] !== void 0;
|
|
1036
1159
|
}
|
|
1037
1160
|
var InMemoryDriver = class {
|
|
1038
|
-
// Key: `${feedId}:${messageId}`
|
|
1039
1161
|
constructor(options) {
|
|
1040
1162
|
__publicField(this, "_nextActor");
|
|
1041
1163
|
__publicField(this, "_nodes");
|
|
@@ -1045,12 +1167,15 @@ var InMemoryDriver = class {
|
|
|
1045
1167
|
__publicField(this, "_leasedSessions");
|
|
1046
1168
|
__publicField(this, "_feeds");
|
|
1047
1169
|
__publicField(this, "_feedMessages");
|
|
1170
|
+
// Key: `${feedId}:${messageId}`
|
|
1171
|
+
__publicField(this, "_liveTextHistory");
|
|
1048
1172
|
this._nodes = /* @__PURE__ */ new Map();
|
|
1049
1173
|
this._metadb = /* @__PURE__ */ new Map();
|
|
1050
1174
|
this._ydb = /* @__PURE__ */ new Map();
|
|
1051
1175
|
this._leasedSessions = /* @__PURE__ */ new Map();
|
|
1052
1176
|
this._feeds = /* @__PURE__ */ new Map();
|
|
1053
1177
|
this._feedMessages = /* @__PURE__ */ new Map();
|
|
1178
|
+
this._liveTextHistory = /* @__PURE__ */ new Map();
|
|
1054
1179
|
this._nextActor = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _35 => _35.initialActor]), () => ( -1));
|
|
1055
1180
|
for (const [key, value] of _nullishCoalesce(_optionalChain([options, 'optionalAccess', _36 => _36.initialNodes]), () => ( []))) {
|
|
1056
1181
|
this._nodes.set(key, value);
|
|
@@ -1066,10 +1191,40 @@ var InMemoryDriver = class {
|
|
|
1066
1191
|
DANGEROUSLY_reset_nodes(doc) {
|
|
1067
1192
|
this.reinitialize();
|
|
1068
1193
|
this._nodes.clear();
|
|
1194
|
+
this._liveTextHistory.clear();
|
|
1069
1195
|
for (const [id, node] of plainLsonToNodeStream(doc)) {
|
|
1070
1196
|
this._nodes.set(id, node);
|
|
1071
1197
|
}
|
|
1072
1198
|
}
|
|
1199
|
+
get_live_text_history_since(nodeId, version) {
|
|
1200
|
+
return (_nullishCoalesce(this._liveTextHistory.get(nodeId), () => ( []))).filter((entry) => entry.version > version).sort((left, right) => left.version - right.version).map((entry) => ({ ...entry, ops: [...entry.ops] }));
|
|
1201
|
+
}
|
|
1202
|
+
get_live_text_history_by_op_id(nodeId, opId) {
|
|
1203
|
+
const entry = (_nullishCoalesce(this._liveTextHistory.get(nodeId), () => ( []))).find(
|
|
1204
|
+
(item) => item.opId === opId
|
|
1205
|
+
);
|
|
1206
|
+
return entry === void 0 ? void 0 : { ...entry, ops: [...entry.ops] };
|
|
1207
|
+
}
|
|
1208
|
+
append_live_text_history(entry) {
|
|
1209
|
+
const history = _nullishCoalesce(this._liveTextHistory.get(entry.nodeId), () => ( []));
|
|
1210
|
+
history.push({ ...entry, ops: [...entry.ops] });
|
|
1211
|
+
history.sort((left, right) => left.version - right.version);
|
|
1212
|
+
this._liveTextHistory.set(entry.nodeId, history);
|
|
1213
|
+
}
|
|
1214
|
+
purge_live_text_history_before(nodeId, minVersionToKeep) {
|
|
1215
|
+
const history = this._liveTextHistory.get(nodeId);
|
|
1216
|
+
if (history === void 0) {
|
|
1217
|
+
return;
|
|
1218
|
+
}
|
|
1219
|
+
const retained = history.filter(
|
|
1220
|
+
(entry) => entry.version >= minVersionToKeep
|
|
1221
|
+
);
|
|
1222
|
+
if (retained.length === 0) {
|
|
1223
|
+
this._liveTextHistory.delete(nodeId);
|
|
1224
|
+
} else {
|
|
1225
|
+
this._liveTextHistory.set(nodeId, retained);
|
|
1226
|
+
}
|
|
1227
|
+
}
|
|
1073
1228
|
get_meta(key) {
|
|
1074
1229
|
return this._metadb.get(key);
|
|
1075
1230
|
}
|
|
@@ -1345,6 +1500,7 @@ var InMemoryDriver = class {
|
|
|
1345
1500
|
}
|
|
1346
1501
|
_loadNodesApi() {
|
|
1347
1502
|
const nodes = this._nodes;
|
|
1503
|
+
const liveTextHistory = this._liveTextHistory;
|
|
1348
1504
|
if (!nodes.has("root")) {
|
|
1349
1505
|
nodes.set("root", { type: _core.CrdtType.OBJECT, data: {} });
|
|
1350
1506
|
}
|
|
@@ -1377,6 +1533,9 @@ var InMemoryDriver = class {
|
|
|
1377
1533
|
if (node.type === _core.CrdtType.REGISTER && parentNode.type === _core.CrdtType.OBJECT) {
|
|
1378
1534
|
throw new Error("Cannot add register under object");
|
|
1379
1535
|
}
|
|
1536
|
+
if (parentNode.type === _core.CrdtType.FILE) {
|
|
1537
|
+
throw new Error("Cannot add child under file");
|
|
1538
|
+
}
|
|
1380
1539
|
const conflictingSiblingId = revNodes.get(node.parentId, node.parentKey);
|
|
1381
1540
|
if (conflictingSiblingId !== id) {
|
|
1382
1541
|
const parentNode2 = nodes.get(node.parentId);
|
|
@@ -1432,6 +1591,7 @@ var InMemoryDriver = class {
|
|
|
1432
1591
|
const currid = queue.pop();
|
|
1433
1592
|
queue.push(...revNodes.valuesAt(currid));
|
|
1434
1593
|
nodes.delete(currid);
|
|
1594
|
+
liveTextHistory.delete(currid);
|
|
1435
1595
|
revNodes.deleteAll(currid);
|
|
1436
1596
|
}
|
|
1437
1597
|
}
|
|
@@ -1557,18 +1717,21 @@ function makeNewInMemoryDriver(options) {
|
|
|
1557
1717
|
|
|
1558
1718
|
|
|
1559
1719
|
|
|
1720
|
+
|
|
1721
|
+
|
|
1722
|
+
var LIVE_TEXT_HISTORY_LIMIT = 1e3;
|
|
1723
|
+
var LIVE_TEXT_HISTORY_TOO_OLD_REASON = "LiveText operation is older than retained history";
|
|
1560
1724
|
function accept(op2, fix) {
|
|
1561
1725
|
return { action: "accepted", op: op2, fix };
|
|
1562
1726
|
}
|
|
1563
1727
|
function ignore(ignoredOp) {
|
|
1564
1728
|
return { action: "ignored", ignoredOpId: ignoredOp.opId };
|
|
1565
1729
|
}
|
|
1566
|
-
function
|
|
1567
|
-
return {
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
};
|
|
1730
|
+
function reject(op2, reason) {
|
|
1731
|
+
return { action: "rejected", opIds: [op2.opId], reason };
|
|
1732
|
+
}
|
|
1733
|
+
function rectify(ackOp, fix) {
|
|
1734
|
+
return { action: "rectified", ackOp, fix };
|
|
1572
1735
|
}
|
|
1573
1736
|
function nodeFromCreateChildOp(op2) {
|
|
1574
1737
|
switch (op2.type) {
|
|
@@ -1598,6 +1761,21 @@ function nodeFromCreateChildOp(op2) {
|
|
|
1598
1761
|
parentKey: op2.parentKey,
|
|
1599
1762
|
data: op2.data
|
|
1600
1763
|
};
|
|
1764
|
+
case _core.OpCode.CREATE_TEXT:
|
|
1765
|
+
return {
|
|
1766
|
+
type: _core.CrdtType.TEXT,
|
|
1767
|
+
parentId: op2.parentId,
|
|
1768
|
+
parentKey: op2.parentKey,
|
|
1769
|
+
data: op2.data,
|
|
1770
|
+
version: op2.version
|
|
1771
|
+
};
|
|
1772
|
+
case _core.OpCode.CREATE_FILE:
|
|
1773
|
+
return {
|
|
1774
|
+
type: _core.CrdtType.FILE,
|
|
1775
|
+
parentId: op2.parentId,
|
|
1776
|
+
parentKey: op2.parentKey,
|
|
1777
|
+
data: op2.data
|
|
1778
|
+
};
|
|
1601
1779
|
// istanbul ignore next
|
|
1602
1780
|
default:
|
|
1603
1781
|
return _core.assertNever.call(void 0, op2, "Unknown op code");
|
|
@@ -1639,9 +1817,13 @@ var Storage = class {
|
|
|
1639
1817
|
case _core.OpCode.CREATE_MAP:
|
|
1640
1818
|
case _core.OpCode.CREATE_REGISTER:
|
|
1641
1819
|
case _core.OpCode.CREATE_OBJECT:
|
|
1820
|
+
case _core.OpCode.CREATE_TEXT:
|
|
1821
|
+
case _core.OpCode.CREATE_FILE:
|
|
1642
1822
|
return this.applyCreateOp(op2);
|
|
1643
1823
|
case _core.OpCode.UPDATE_OBJECT:
|
|
1644
1824
|
return this.applyUpdateObjectOp(op2);
|
|
1825
|
+
case _core.OpCode.UPDATE_TEXT:
|
|
1826
|
+
return this.applyUpdateTextOp(op2);
|
|
1645
1827
|
case _core.OpCode.SET_PARENT_KEY:
|
|
1646
1828
|
return this.applySetParentKeyOp(op2);
|
|
1647
1829
|
case _core.OpCode.DELETE_OBJECT_KEY:
|
|
@@ -1662,7 +1844,14 @@ var Storage = class {
|
|
|
1662
1844
|
if (op2.intent === "push") {
|
|
1663
1845
|
const stored = this.driver.get_node(op2.id);
|
|
1664
1846
|
if (_optionalChain([stored, 'optionalAccess', _47 => _47.parentId]) !== void 0 && _optionalChain([this, 'access', _48 => _48.driver, 'access', _49 => _49.get_node, 'call', _50 => _50(stored.parentId), 'optionalAccess', _51 => _51.type]) === _core.CrdtType.LIST) {
|
|
1665
|
-
return rectify(
|
|
1847
|
+
return rectify(
|
|
1848
|
+
{ ...op2, parentKey: stored.parentKey },
|
|
1849
|
+
{
|
|
1850
|
+
type: _core.OpCode.SET_PARENT_KEY,
|
|
1851
|
+
id: op2.id,
|
|
1852
|
+
parentKey: stored.parentKey
|
|
1853
|
+
}
|
|
1854
|
+
);
|
|
1666
1855
|
}
|
|
1667
1856
|
}
|
|
1668
1857
|
return ignore(op2);
|
|
@@ -1684,6 +1873,8 @@ var Storage = class {
|
|
|
1684
1873
|
case _core.CrdtType.LIST:
|
|
1685
1874
|
return this.createChildAsListItem(op2, node);
|
|
1686
1875
|
case _core.CrdtType.REGISTER:
|
|
1876
|
+
case _core.CrdtType.TEXT:
|
|
1877
|
+
case _core.CrdtType.FILE:
|
|
1687
1878
|
return ignore(op2);
|
|
1688
1879
|
// istanbul ignore next
|
|
1689
1880
|
default:
|
|
@@ -1740,6 +1931,59 @@ var Storage = class {
|
|
|
1740
1931
|
this.driver.set_object_data(op2.id, op2.data, true);
|
|
1741
1932
|
return accept(op2);
|
|
1742
1933
|
}
|
|
1934
|
+
applyUpdateTextOp(op2) {
|
|
1935
|
+
const node = this.driver.get_node(op2.id);
|
|
1936
|
+
if (_optionalChain([node, 'optionalAccess', _56 => _56.type]) !== _core.CrdtType.TEXT) {
|
|
1937
|
+
return ignore(op2);
|
|
1938
|
+
}
|
|
1939
|
+
const duplicate = this.driver.get_live_text_history_by_op_id(
|
|
1940
|
+
op2.id,
|
|
1941
|
+
op2.opId
|
|
1942
|
+
);
|
|
1943
|
+
if (duplicate !== void 0) {
|
|
1944
|
+
return rectify({
|
|
1945
|
+
...op2,
|
|
1946
|
+
baseVersion: duplicate.baseVersion,
|
|
1947
|
+
version: duplicate.version,
|
|
1948
|
+
ops: [...duplicate.ops]
|
|
1949
|
+
});
|
|
1950
|
+
}
|
|
1951
|
+
if (op2.ops.length === 0) {
|
|
1952
|
+
return ignore(op2);
|
|
1953
|
+
}
|
|
1954
|
+
if (op2.baseVersion > node.version) {
|
|
1955
|
+
return reject(op2, "LiveText operation base version is ahead of storage");
|
|
1956
|
+
}
|
|
1957
|
+
const history = op2.baseVersion < node.version ? this.driver.get_live_text_history_since(op2.id, op2.baseVersion) : [];
|
|
1958
|
+
if (op2.baseVersion < node.version && history.length !== node.version - op2.baseVersion) {
|
|
1959
|
+
return reject(op2, LIVE_TEXT_HISTORY_TOO_OLD_REASON);
|
|
1960
|
+
}
|
|
1961
|
+
const acceptedOps = history.flatMap((entry) => entry.ops);
|
|
1962
|
+
const ops = acceptedOps.length > 0 ? _core.transformTextOperations.call(void 0, op2.ops, acceptedOps, "after") : op2.ops;
|
|
1963
|
+
const version = node.version + 1;
|
|
1964
|
+
const data = _core.applyLiveTextOperations.call(void 0, node.data, ops);
|
|
1965
|
+
this.driver.set_child(
|
|
1966
|
+
op2.id,
|
|
1967
|
+
{
|
|
1968
|
+
...node,
|
|
1969
|
+
data,
|
|
1970
|
+
version
|
|
1971
|
+
},
|
|
1972
|
+
true
|
|
1973
|
+
);
|
|
1974
|
+
this.driver.append_live_text_history({
|
|
1975
|
+
nodeId: op2.id,
|
|
1976
|
+
baseVersion: node.version,
|
|
1977
|
+
version,
|
|
1978
|
+
opId: op2.opId,
|
|
1979
|
+
ops: [...ops]
|
|
1980
|
+
});
|
|
1981
|
+
this.driver.purge_live_text_history_before(
|
|
1982
|
+
op2.id,
|
|
1983
|
+
Math.max(0, version - LIVE_TEXT_HISTORY_LIMIT + 1)
|
|
1984
|
+
);
|
|
1985
|
+
return accept({ ...op2, baseVersion: node.version, version, ops: [...ops] });
|
|
1986
|
+
}
|
|
1743
1987
|
applyDeleteCrdtOp(op2) {
|
|
1744
1988
|
this.driver.delete_node(op2.id);
|
|
1745
1989
|
return accept(op2);
|
|
@@ -1811,10 +2055,10 @@ var Storage = class {
|
|
|
1811
2055
|
*/
|
|
1812
2056
|
moveToPosInList(id, targetKey) {
|
|
1813
2057
|
const node = this.driver.get_node(id);
|
|
1814
|
-
if (_optionalChain([node, 'optionalAccess',
|
|
2058
|
+
if (_optionalChain([node, 'optionalAccess', _57 => _57.parentId]) === void 0) {
|
|
1815
2059
|
return;
|
|
1816
2060
|
}
|
|
1817
|
-
if (_optionalChain([this, 'access',
|
|
2061
|
+
if (_optionalChain([this, 'access', _58 => _58.driver, 'access', _59 => _59.get_node, 'call', _60 => _60(node.parentId), 'optionalAccess', _61 => _61.type]) !== _core.CrdtType.LIST) {
|
|
1818
2062
|
return;
|
|
1819
2063
|
}
|
|
1820
2064
|
if (node.parentKey === targetKey) {
|
|
@@ -2225,13 +2469,13 @@ var BrowserSession = class {
|
|
|
2225
2469
|
this.publicMeta = ticket.publicMeta;
|
|
2226
2470
|
__privateSet(this, __socket, socket);
|
|
2227
2471
|
__privateSet(this, __debug, debug);
|
|
2228
|
-
const now = _nullishCoalesce(_optionalChain([createdAt, 'optionalAccess',
|
|
2472
|
+
const now = _nullishCoalesce(_optionalChain([createdAt, 'optionalAccess', _62 => _62.getTime, 'call', _63 => _63()]), () => ( Date.now()));
|
|
2229
2473
|
this.createdAt = now;
|
|
2230
2474
|
__privateSet(this, __lastActiveAt, now);
|
|
2231
2475
|
__privateSet(this, __hasNotifiedClientStorageUpdateError, false);
|
|
2232
2476
|
}
|
|
2233
2477
|
get lastActiveAt() {
|
|
2234
|
-
const lastPing = _optionalChain([__privateGet, 'call',
|
|
2478
|
+
const lastPing = _optionalChain([__privateGet, 'call', _64 => _64(this, __socket), 'access', _65 => _65.getLastPongTimestamp, 'optionalCall', _66 => _66()]);
|
|
2235
2479
|
if (lastPing && lastPing.getTime() > __privateGet(this, __lastActiveAt)) {
|
|
2236
2480
|
return lastPing.getTime();
|
|
2237
2481
|
} else {
|
|
@@ -2332,25 +2576,25 @@ var Room = class {
|
|
|
2332
2576
|
__publicField(this, "sessions", new UniqueMap((s) => s.actor));
|
|
2333
2577
|
__publicField(this, "hooks");
|
|
2334
2578
|
__privateAdd(this, __debug2);
|
|
2335
|
-
const driver = _nullishCoalesce(_optionalChain([options, 'optionalAccess',
|
|
2579
|
+
const driver = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _67 => _67.storage]), () => ( makeNewInMemoryDriver()));
|
|
2336
2580
|
this.meta = meta;
|
|
2337
2581
|
this.driver = driver;
|
|
2338
2582
|
this._storage = new Storage(this.driver);
|
|
2339
2583
|
this._yjsStorage = new YjsStorage(this.driver);
|
|
2340
|
-
__privateSet(this, _logger, _nullishCoalesce(_optionalChain([options, 'optionalAccess',
|
|
2584
|
+
__privateSet(this, _logger, _nullishCoalesce(_optionalChain([options, 'optionalAccess', _68 => _68.logger]), () => ( BLACK_HOLE)));
|
|
2341
2585
|
this.hooks = {
|
|
2342
|
-
isClientMsgAllowed: _nullishCoalesce(_optionalChain([options, 'optionalAccess',
|
|
2586
|
+
isClientMsgAllowed: _nullishCoalesce(_optionalChain([options, 'optionalAccess', _69 => _69.hooks, 'optionalAccess', _70 => _70.isClientMsgAllowed]), () => ( (() => {
|
|
2343
2587
|
return {
|
|
2344
2588
|
allowed: true
|
|
2345
2589
|
};
|
|
2346
2590
|
}))),
|
|
2347
|
-
onRoomWillUnload: _optionalChain([options, 'optionalAccess',
|
|
2348
|
-
onSessionDidStart: _optionalChain([options, 'optionalAccess',
|
|
2349
|
-
onSessionDidEnd: _optionalChain([options, 'optionalAccess',
|
|
2350
|
-
postClientMsgStorageDidUpdate: _optionalChain([options, 'optionalAccess',
|
|
2351
|
-
postClientMsgYdocDidUpdate: _optionalChain([options, 'optionalAccess',
|
|
2591
|
+
onRoomWillUnload: _optionalChain([options, 'optionalAccess', _71 => _71.hooks, 'optionalAccess', _72 => _72.onRoomWillUnload]),
|
|
2592
|
+
onSessionDidStart: _optionalChain([options, 'optionalAccess', _73 => _73.hooks, 'optionalAccess', _74 => _74.onSessionDidStart]),
|
|
2593
|
+
onSessionDidEnd: _optionalChain([options, 'optionalAccess', _75 => _75.hooks, 'optionalAccess', _76 => _76.onSessionDidEnd]),
|
|
2594
|
+
postClientMsgStorageDidUpdate: _optionalChain([options, 'optionalAccess', _77 => _77.hooks, 'optionalAccess', _78 => _78.postClientMsgStorageDidUpdate]),
|
|
2595
|
+
postClientMsgYdocDidUpdate: _optionalChain([options, 'optionalAccess', _79 => _79.hooks, 'optionalAccess', _80 => _80.postClientMsgYdocDidUpdate])
|
|
2352
2596
|
};
|
|
2353
|
-
__privateSet(this, __debug2, _nullishCoalesce(_optionalChain([options, 'optionalAccess',
|
|
2597
|
+
__privateSet(this, __debug2, _nullishCoalesce(_optionalChain([options, 'optionalAccess', _81 => _81.enableDebugLogging]), () => ( false)));
|
|
2354
2598
|
}
|
|
2355
2599
|
get storage() {
|
|
2356
2600
|
return this._storage;
|
|
@@ -2396,7 +2640,7 @@ var Room = class {
|
|
|
2396
2640
|
* is used, fresh instances will lazily be created.
|
|
2397
2641
|
*/
|
|
2398
2642
|
unload(ctx) {
|
|
2399
|
-
_optionalChain([this, 'access',
|
|
2643
|
+
_optionalChain([this, 'access', _82 => _82.hooks, 'access', _83 => _83.onRoomWillUnload, 'optionalCall', _84 => _84(ctx)]);
|
|
2400
2644
|
this.driver.reinitialize();
|
|
2401
2645
|
this._storage = new Storage(this.driver);
|
|
2402
2646
|
this._yjsStorage = new YjsStorage(this.driver);
|
|
@@ -2413,17 +2657,17 @@ var Room = class {
|
|
|
2413
2657
|
* unused Ticket will simply get garbage collected.
|
|
2414
2658
|
*/
|
|
2415
2659
|
createTicket(options) {
|
|
2416
|
-
const actor = _nullishCoalesce(_optionalChain([options, 'optionalAccess',
|
|
2660
|
+
const actor = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _85 => _85.actor]), () => ( this.getNextActor()));
|
|
2417
2661
|
const sessionKey = _nanoid.nanoid.call(void 0, );
|
|
2418
|
-
const info = _optionalChain([options, 'optionalAccess',
|
|
2662
|
+
const info = _optionalChain([options, 'optionalAccess', _86 => _86.info]);
|
|
2419
2663
|
const ticket = {
|
|
2420
|
-
version: _nullishCoalesce(_optionalChain([options, 'optionalAccess',
|
|
2664
|
+
version: _nullishCoalesce(_optionalChain([options, 'optionalAccess', _87 => _87.version]), () => ( HIGHEST_PROTOCOL_VERSION)),
|
|
2421
2665
|
actor,
|
|
2422
2666
|
sessionKey,
|
|
2423
|
-
meta: _optionalChain([options, 'optionalAccess',
|
|
2424
|
-
publicMeta: _optionalChain([options, 'optionalAccess',
|
|
2425
|
-
user: _optionalChain([options, 'optionalAccess',
|
|
2426
|
-
scopes: _nullishCoalesce(_optionalChain([options, 'optionalAccess',
|
|
2667
|
+
meta: _optionalChain([options, 'optionalAccess', _88 => _88.meta]),
|
|
2668
|
+
publicMeta: _optionalChain([options, 'optionalAccess', _89 => _89.publicMeta]),
|
|
2669
|
+
user: _optionalChain([options, 'optionalAccess', _90 => _90.id]) ? { id: options.id, info } : { anonymousId: _nullishCoalesce(_optionalChain([options, 'optionalAccess', _91 => _91.anonymousId]), () => ( _nanoid.nanoid.call(void 0, ))), info },
|
|
2670
|
+
scopes: _nullishCoalesce(_optionalChain([options, 'optionalAccess', _92 => _92.scopes]), () => ( ["room:write"]))
|
|
2427
2671
|
};
|
|
2428
2672
|
if (__privateGet(this, __debug2)) {
|
|
2429
2673
|
console.log(`new ticket created: ${JSON.stringify(ticket)}`);
|
|
@@ -2554,7 +2798,7 @@ var Room = class {
|
|
|
2554
2798
|
ctx,
|
|
2555
2799
|
defer
|
|
2556
2800
|
);
|
|
2557
|
-
const p$ = _optionalChain([this, 'access',
|
|
2801
|
+
const p$ = _optionalChain([this, 'access', _93 => _93.hooks, 'access', _94 => _94.onSessionDidStart, 'optionalCall', _95 => _95(newSession, ctx)]);
|
|
2558
2802
|
if (p$) defer(p$);
|
|
2559
2803
|
}
|
|
2560
2804
|
/**
|
|
@@ -2578,7 +2822,7 @@ var Room = class {
|
|
|
2578
2822
|
for (const other of this.otherSessions(key)) {
|
|
2579
2823
|
other.send({ type: ServerMsgCode2.USER_LEFT, actor: session.actor });
|
|
2580
2824
|
}
|
|
2581
|
-
const p$ = _optionalChain([this, 'access',
|
|
2825
|
+
const p$ = _optionalChain([this, 'access', _96 => _96.hooks, 'access', _97 => _97.onSessionDidEnd, 'optionalCall', _98 => _98(session, ctx)]);
|
|
2582
2826
|
if (p$) defer(p$);
|
|
2583
2827
|
}
|
|
2584
2828
|
}
|
|
@@ -2609,7 +2853,7 @@ var Room = class {
|
|
|
2609
2853
|
);
|
|
2610
2854
|
}) {
|
|
2611
2855
|
const text = typeof data === "string" ? data : _core.raise.call(void 0, "Unsupported message format");
|
|
2612
|
-
_optionalChain([this, 'access',
|
|
2856
|
+
_optionalChain([this, 'access', _99 => _99.sessions, 'access', _100 => _100.get, 'call', _101 => _101(key), 'optionalAccess', _102 => _102.markActive, 'call', _103 => _103()]);
|
|
2613
2857
|
if (text === "ping") {
|
|
2614
2858
|
await this.handlePing(key, ctx);
|
|
2615
2859
|
} else {
|
|
@@ -2986,7 +3230,7 @@ var Room = class {
|
|
|
2986
3230
|
}
|
|
2987
3231
|
const sent = session.sendPong();
|
|
2988
3232
|
if (sent !== 0) {
|
|
2989
|
-
await _optionalChain([this, 'access',
|
|
3233
|
+
await _optionalChain([this, 'access', _104 => _104.hooks, 'access', _105 => _105.onDidPong, 'optionalCall', _106 => _106(ctx)]);
|
|
2990
3234
|
}
|
|
2991
3235
|
}
|
|
2992
3236
|
_processClientMsg_withExclusiveAccess(sessionKey, messages, ctx, defer) {
|
|
@@ -3117,7 +3361,7 @@ var Room = class {
|
|
|
3117
3361
|
break;
|
|
3118
3362
|
}
|
|
3119
3363
|
case _core.ClientMsgCode.UPDATE_STORAGE: {
|
|
3120
|
-
_optionalChain([this, 'access',
|
|
3364
|
+
_optionalChain([this, 'access', _107 => _107.driver, 'access', _108 => _108.bump_storage_version, 'optionalCall', _109 => _109()]);
|
|
3121
3365
|
const result = this.storage.applyOps(msg.ops);
|
|
3122
3366
|
const opsToForward = result.flatMap(
|
|
3123
3367
|
(r) => r.action === "accepted" ? [r.op] : []
|
|
@@ -3128,9 +3372,11 @@ var Room = class {
|
|
|
3128
3372
|
case "ignored":
|
|
3129
3373
|
return r.ignoredOpId !== void 0 ? [ackIgnoredOp(r.ignoredOpId)] : [];
|
|
3130
3374
|
case "rectified":
|
|
3131
|
-
return [r.ackOp, r.fix];
|
|
3375
|
+
return r.fix !== void 0 ? [r.ackOp, r.fix] : [r.ackOp];
|
|
3132
3376
|
case "accepted":
|
|
3133
3377
|
return r.fix !== void 0 ? [r.fix] : [];
|
|
3378
|
+
case "rejected":
|
|
3379
|
+
return [];
|
|
3134
3380
|
// istanbul ignore next
|
|
3135
3381
|
default:
|
|
3136
3382
|
return _core.assertNever.call(void 0, r, "Unhandled case");
|
|
@@ -3153,8 +3399,15 @@ var Room = class {
|
|
|
3153
3399
|
ops: opsToSendBack
|
|
3154
3400
|
});
|
|
3155
3401
|
}
|
|
3402
|
+
for (const rejected of result.filter((r) => r.action === "rejected")) {
|
|
3403
|
+
replyImmediately({
|
|
3404
|
+
type: ServerMsgCode2.REJECT_STORAGE_OP,
|
|
3405
|
+
opIds: rejected.opIds,
|
|
3406
|
+
reason: rejected.reason
|
|
3407
|
+
});
|
|
3408
|
+
}
|
|
3156
3409
|
if (opsToForward.length > 0) {
|
|
3157
|
-
const p$ = _optionalChain([this, 'access',
|
|
3410
|
+
const p$ = _optionalChain([this, 'access', _110 => _110.hooks, 'access', _111 => _111.postClientMsgStorageDidUpdate, 'optionalCall', _112 => _112(ctx, session)]);
|
|
3158
3411
|
if (p$) defer(p$);
|
|
3159
3412
|
}
|
|
3160
3413
|
break;
|
|
@@ -3211,7 +3464,7 @@ var Room = class {
|
|
|
3211
3464
|
defer
|
|
3212
3465
|
);
|
|
3213
3466
|
if (result.isUpdated) {
|
|
3214
|
-
const p$ = _optionalChain([this, 'access',
|
|
3467
|
+
const p$ = _optionalChain([this, 'access', _113 => _113.hooks, 'access', _114 => _114.postClientMsgYdocDidUpdate, 'optionalCall', _115 => _115(ctx, session)]);
|
|
3215
3468
|
if (p$) defer(p$);
|
|
3216
3469
|
}
|
|
3217
3470
|
break;
|