@liveblocks/client 0.16.13 → 0.16.16
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/index.d.ts +1 -1
- package/index.js +43 -30
- package/index.mjs +46 -34
- package/internal.d.ts +227 -77
- package/internal.js +57 -17
- package/internal.mjs +57 -15
- package/package.json +9 -13
- package/shared.d.ts +184 -342
- package/shared.js +351 -599
- package/shared.mjs +314 -632
package/shared.mjs
CHANGED
|
@@ -1,39 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
function deprecate(message, key = message) {
|
|
4
|
-
"production" !== process.env.NODE_ENV && (_emittedDeprecationWarnings.has(key) || (_emittedDeprecationWarnings.add(key),
|
|
5
|
-
console.error(`DEPRECATION WARNING: ${message}`)));
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
function deprecateIf(condition, message, key = message) {
|
|
9
|
-
"production" !== process.env.NODE_ENV && condition && deprecate(message, key);
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
function throwUsageError(message) {
|
|
13
|
-
if ("production" !== process.env.NODE_ENV) {
|
|
14
|
-
const usageError = new Error(message);
|
|
15
|
-
throw usageError.name = "Usage error", usageError;
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
function errorIf(condition, message) {
|
|
20
|
-
"production" !== process.env.NODE_ENV && condition && throwUsageError(message);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
function assertNever(_value, errmsg) {
|
|
24
|
-
throw new Error(errmsg);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
function nn(value, errmsg = "Expected value to be non-nullable") {
|
|
28
|
-
return function(condition, errmsg) {
|
|
29
|
-
if ("production" !== process.env.NODE_ENV && !condition) {
|
|
30
|
-
const err = new Error(errmsg);
|
|
31
|
-
throw err.name = "Assertion failure", err;
|
|
32
|
-
}
|
|
33
|
-
}(null != value, errmsg), value;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
var ClientMsgCode, OpCode, CrdtType, ServerMsgCode, WebsocketCloseCodes, OpSource;
|
|
1
|
+
var ServerMsgCode, ClientMsgCode, CrdtType, OpCode, WebsocketCloseCodes;
|
|
37
2
|
|
|
38
3
|
function isRootCrdt(crdt) {
|
|
39
4
|
return crdt.type === CrdtType.OBJECT && !isChildCrdt(crdt);
|
|
@@ -43,32 +8,24 @@ function isChildCrdt(crdt) {
|
|
|
43
8
|
return void 0 !== crdt.parentId && void 0 !== crdt.parentKey;
|
|
44
9
|
}
|
|
45
10
|
|
|
46
|
-
function
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
})
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
!function(ClientMsgCode) {
|
|
11
|
+
!function(ServerMsgCode) {
|
|
12
|
+
ServerMsgCode[ServerMsgCode.UPDATE_PRESENCE = 100] = "UPDATE_PRESENCE", ServerMsgCode[ServerMsgCode.USER_JOINED = 101] = "USER_JOINED",
|
|
13
|
+
ServerMsgCode[ServerMsgCode.USER_LEFT = 102] = "USER_LEFT", ServerMsgCode[ServerMsgCode.BROADCASTED_EVENT = 103] = "BROADCASTED_EVENT",
|
|
14
|
+
ServerMsgCode[ServerMsgCode.ROOM_STATE = 104] = "ROOM_STATE", ServerMsgCode[ServerMsgCode.INITIAL_STORAGE_STATE = 200] = "INITIAL_STORAGE_STATE",
|
|
15
|
+
ServerMsgCode[ServerMsgCode.UPDATE_STORAGE = 201] = "UPDATE_STORAGE";
|
|
16
|
+
}(ServerMsgCode || (ServerMsgCode = {})), function(ClientMsgCode) {
|
|
55
17
|
ClientMsgCode[ClientMsgCode.UPDATE_PRESENCE = 100] = "UPDATE_PRESENCE", ClientMsgCode[ClientMsgCode.BROADCAST_EVENT = 103] = "BROADCAST_EVENT",
|
|
56
18
|
ClientMsgCode[ClientMsgCode.FETCH_STORAGE = 200] = "FETCH_STORAGE", ClientMsgCode[ClientMsgCode.UPDATE_STORAGE = 201] = "UPDATE_STORAGE";
|
|
57
|
-
}(ClientMsgCode || (ClientMsgCode = {})), function(
|
|
19
|
+
}(ClientMsgCode || (ClientMsgCode = {})), function(CrdtType) {
|
|
20
|
+
CrdtType[CrdtType.OBJECT = 0] = "OBJECT", CrdtType[CrdtType.LIST = 1] = "LIST",
|
|
21
|
+
CrdtType[CrdtType.MAP = 2] = "MAP", CrdtType[CrdtType.REGISTER = 3] = "REGISTER";
|
|
22
|
+
}(CrdtType || (CrdtType = {})), function(OpCode) {
|
|
58
23
|
OpCode[OpCode.INIT = 0] = "INIT", OpCode[OpCode.SET_PARENT_KEY = 1] = "SET_PARENT_KEY",
|
|
59
24
|
OpCode[OpCode.CREATE_LIST = 2] = "CREATE_LIST", OpCode[OpCode.UPDATE_OBJECT = 3] = "UPDATE_OBJECT",
|
|
60
25
|
OpCode[OpCode.CREATE_OBJECT = 4] = "CREATE_OBJECT", OpCode[OpCode.DELETE_CRDT = 5] = "DELETE_CRDT",
|
|
61
26
|
OpCode[OpCode.DELETE_OBJECT_KEY = 6] = "DELETE_OBJECT_KEY", OpCode[OpCode.CREATE_MAP = 7] = "CREATE_MAP",
|
|
62
27
|
OpCode[OpCode.CREATE_REGISTER = 8] = "CREATE_REGISTER";
|
|
63
|
-
}(OpCode || (OpCode = {})), function(
|
|
64
|
-
CrdtType[CrdtType.OBJECT = 0] = "OBJECT", CrdtType[CrdtType.LIST = 1] = "LIST",
|
|
65
|
-
CrdtType[CrdtType.MAP = 2] = "MAP", CrdtType[CrdtType.REGISTER = 3] = "REGISTER";
|
|
66
|
-
}(CrdtType || (CrdtType = {})), function(ServerMsgCode) {
|
|
67
|
-
ServerMsgCode[ServerMsgCode.UPDATE_PRESENCE = 100] = "UPDATE_PRESENCE", ServerMsgCode[ServerMsgCode.USER_JOINED = 101] = "USER_JOINED",
|
|
68
|
-
ServerMsgCode[ServerMsgCode.USER_LEFT = 102] = "USER_LEFT", ServerMsgCode[ServerMsgCode.BROADCASTED_EVENT = 103] = "BROADCASTED_EVENT",
|
|
69
|
-
ServerMsgCode[ServerMsgCode.ROOM_STATE = 104] = "ROOM_STATE", ServerMsgCode[ServerMsgCode.INITIAL_STORAGE_STATE = 200] = "INITIAL_STORAGE_STATE",
|
|
70
|
-
ServerMsgCode[ServerMsgCode.UPDATE_STORAGE = 201] = "UPDATE_STORAGE";
|
|
71
|
-
}(ServerMsgCode || (ServerMsgCode = {})), function(WebsocketCloseCodes) {
|
|
28
|
+
}(OpCode || (OpCode = {})), function(WebsocketCloseCodes) {
|
|
72
29
|
WebsocketCloseCodes[WebsocketCloseCodes.CLOSE_ABNORMAL = 1006] = "CLOSE_ABNORMAL",
|
|
73
30
|
WebsocketCloseCodes[WebsocketCloseCodes.INVALID_MESSAGE_FORMAT = 4e3] = "INVALID_MESSAGE_FORMAT",
|
|
74
31
|
WebsocketCloseCodes[WebsocketCloseCodes.NOT_ALLOWED = 4001] = "NOT_ALLOWED", WebsocketCloseCodes[WebsocketCloseCodes.MAX_NUMBER_OF_MESSAGES_PER_SECONDS = 4002] = "MAX_NUMBER_OF_MESSAGES_PER_SECONDS",
|
|
@@ -76,41 +33,9 @@ function HasParent(node, key) {
|
|
|
76
33
|
WebsocketCloseCodes[WebsocketCloseCodes.MAX_NUMBER_OF_MESSAGES_PER_DAY_PER_APP = 4004] = "MAX_NUMBER_OF_MESSAGES_PER_DAY_PER_APP",
|
|
77
34
|
WebsocketCloseCodes[WebsocketCloseCodes.MAX_NUMBER_OF_CONCURRENT_CONNECTIONS_PER_ROOM = 4005] = "MAX_NUMBER_OF_CONCURRENT_CONNECTIONS_PER_ROOM",
|
|
78
35
|
WebsocketCloseCodes[WebsocketCloseCodes.CLOSE_WITHOUT_RETRY = 4999] = "CLOSE_WITHOUT_RETRY";
|
|
79
|
-
}(WebsocketCloseCodes || (WebsocketCloseCodes = {}))
|
|
80
|
-
OpSource[OpSource.UNDOREDO_RECONNECT = 0] = "UNDOREDO_RECONNECT", OpSource[OpSource.REMOTE = 1] = "REMOTE",
|
|
81
|
-
OpSource[OpSource.ACK = 2] = "ACK";
|
|
82
|
-
}(OpSource || (OpSource = {}));
|
|
83
|
-
|
|
84
|
-
const NoParent = Object.freeze({
|
|
85
|
-
type: "NoParent"
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
function Orphaned(oldKey) {
|
|
89
|
-
return Object.freeze({
|
|
90
|
-
type: "Orphaned",
|
|
91
|
-
oldKey: oldKey
|
|
92
|
-
});
|
|
93
|
-
}
|
|
36
|
+
}(WebsocketCloseCodes || (WebsocketCloseCodes = {}));
|
|
94
37
|
|
|
95
38
|
class AbstractCrdt {
|
|
96
|
-
constructor() {
|
|
97
|
-
this._parent = NoParent;
|
|
98
|
-
}
|
|
99
|
-
_getParentKeyOrThrow() {
|
|
100
|
-
switch (this.parent.type) {
|
|
101
|
-
case "HasParent":
|
|
102
|
-
return this.parent.key;
|
|
103
|
-
|
|
104
|
-
case "NoParent":
|
|
105
|
-
throw new Error("Parent key is missing");
|
|
106
|
-
|
|
107
|
-
case "Orphaned":
|
|
108
|
-
return this.parent.oldKey;
|
|
109
|
-
|
|
110
|
-
default:
|
|
111
|
-
return assertNever(this.parent, "Unknown state");
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
39
|
get _doc() {
|
|
115
40
|
return this.__doc;
|
|
116
41
|
}
|
|
@@ -120,79 +45,41 @@ class AbstractCrdt {
|
|
|
120
45
|
get _id() {
|
|
121
46
|
return this.__id;
|
|
122
47
|
}
|
|
123
|
-
get
|
|
124
|
-
return this.
|
|
125
|
-
}
|
|
126
|
-
get _parentNode() {
|
|
127
|
-
switch (this.parent.type) {
|
|
128
|
-
case "HasParent":
|
|
129
|
-
return this.parent.node;
|
|
130
|
-
|
|
131
|
-
case "NoParent":
|
|
132
|
-
case "Orphaned":
|
|
133
|
-
return null;
|
|
134
|
-
|
|
135
|
-
default:
|
|
136
|
-
return assertNever(this.parent, "Unknown state");
|
|
137
|
-
}
|
|
48
|
+
get _parent() {
|
|
49
|
+
return this.__parent;
|
|
138
50
|
}
|
|
139
51
|
get _parentKey() {
|
|
140
|
-
|
|
141
|
-
case "HasParent":
|
|
142
|
-
return this.parent.key;
|
|
143
|
-
|
|
144
|
-
case "NoParent":
|
|
145
|
-
return null;
|
|
146
|
-
|
|
147
|
-
case "Orphaned":
|
|
148
|
-
return this.parent.oldKey;
|
|
149
|
-
|
|
150
|
-
default:
|
|
151
|
-
return assertNever(this.parent, "Unknown state");
|
|
152
|
-
}
|
|
52
|
+
return this.__parentKey;
|
|
153
53
|
}
|
|
154
54
|
_apply(op, _isLocal) {
|
|
155
|
-
return op.type === OpCode.DELETE_CRDT &&
|
|
55
|
+
return op.type === OpCode.DELETE_CRDT && null != this._parent && null != this._parentKey ? this._parent._detachChild(this) : {
|
|
156
56
|
modified: !1
|
|
157
57
|
};
|
|
158
58
|
}
|
|
159
|
-
_setParentLink(
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
if (this.parent.node !== newParentNode) throw new Error("Cannot attach parent if it already exist");
|
|
163
|
-
return void (this._parent = HasParent(newParentNode, newParentKey));
|
|
164
|
-
|
|
165
|
-
case "Orphaned":
|
|
166
|
-
case "NoParent":
|
|
167
|
-
return void (this._parent = HasParent(newParentNode, newParentKey));
|
|
168
|
-
|
|
169
|
-
default:
|
|
170
|
-
return assertNever(this.parent, "Unknown state");
|
|
171
|
-
}
|
|
59
|
+
_setParentLink(parent, key) {
|
|
60
|
+
if (null != this.__parent && this.__parent !== parent) throw new Error("Cannot attach parent if it already exist");
|
|
61
|
+
this.__parentKey = key, this.__parent = parent;
|
|
172
62
|
}
|
|
173
63
|
_attach(id, doc) {
|
|
174
64
|
if (this.__id || this.__doc) throw new Error("Cannot attach if CRDT is already attached");
|
|
175
65
|
doc.addItem(id, this), this.__id = id, this.__doc = doc;
|
|
176
66
|
}
|
|
177
67
|
_detach() {
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
68
|
+
this.__doc && this.__id && this.__doc.deleteItem(this.__id), this.__parent = void 0,
|
|
69
|
+
this.__doc = void 0;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
182
72
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
73
|
+
function isJsonScalar(data) {
|
|
74
|
+
return null === data || "string" == typeof data || "number" == typeof data || "boolean" == typeof data;
|
|
75
|
+
}
|
|
186
76
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
77
|
+
function isJsonArray(data) {
|
|
78
|
+
return Array.isArray(data);
|
|
79
|
+
}
|
|
190
80
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
}
|
|
194
|
-
this.__doc = void 0;
|
|
195
|
-
}
|
|
81
|
+
function isJsonObject(data) {
|
|
82
|
+
return !isJsonScalar(data) && !isJsonArray(data);
|
|
196
83
|
}
|
|
197
84
|
|
|
198
85
|
class LiveRegister extends AbstractCrdt {
|
|
@@ -206,27 +93,28 @@ class LiveRegister extends AbstractCrdt {
|
|
|
206
93
|
const register = new LiveRegister(item.data);
|
|
207
94
|
return register._attach(id, doc), register;
|
|
208
95
|
}
|
|
209
|
-
_serialize(parentId, parentKey, doc) {
|
|
96
|
+
_serialize(parentId, parentKey, doc, intent) {
|
|
210
97
|
if (null == this._id || null == parentId || null == parentKey) throw new Error("Cannot serialize register if parentId or parentKey is undefined");
|
|
211
98
|
return [ {
|
|
212
99
|
type: OpCode.CREATE_REGISTER,
|
|
213
100
|
opId: null == doc ? void 0 : doc.generateOpId(),
|
|
214
101
|
id: this._id,
|
|
102
|
+
intent: intent,
|
|
215
103
|
parentId: parentId,
|
|
216
104
|
parentKey: parentKey,
|
|
217
105
|
data: this.data
|
|
218
106
|
} ];
|
|
219
107
|
}
|
|
220
108
|
_toSerializedCrdt() {
|
|
221
|
-
|
|
109
|
+
var _a;
|
|
222
110
|
return {
|
|
223
111
|
type: CrdtType.REGISTER,
|
|
224
|
-
parentId:
|
|
225
|
-
parentKey: this.
|
|
112
|
+
parentId: null === (_a = this._parent) || void 0 === _a ? void 0 : _a._id,
|
|
113
|
+
parentKey: this._parentKey,
|
|
226
114
|
data: this.data
|
|
227
115
|
};
|
|
228
116
|
}
|
|
229
|
-
_attachChild(_op) {
|
|
117
|
+
_attachChild(_op, _isLocal) {
|
|
230
118
|
throw new Error("Method not implemented.");
|
|
231
119
|
}
|
|
232
120
|
_detachChild(_crdt) {
|
|
@@ -238,7 +126,7 @@ class LiveRegister extends AbstractCrdt {
|
|
|
238
126
|
}
|
|
239
127
|
|
|
240
128
|
function makePosition(before, after) {
|
|
241
|
-
return null
|
|
129
|
+
return null == before && null == after ? pos([ 33 ]) : null != before && null == after ? function(before) {
|
|
242
130
|
const result = [], beforeCodes = posCodes(before);
|
|
243
131
|
for (let i = 0; i < beforeCodes.length; i++) {
|
|
244
132
|
const code = beforeCodes[i];
|
|
@@ -252,7 +140,7 @@ function makePosition(before, after) {
|
|
|
252
140
|
}
|
|
253
141
|
}
|
|
254
142
|
return pos(result);
|
|
255
|
-
}(before) : null != after ? function(after) {
|
|
143
|
+
}(before) : null == before && null != after ? function(after) {
|
|
256
144
|
const result = [], afterCodes = posCodes(after);
|
|
257
145
|
for (let i = 0; i < afterCodes.length; i++) {
|
|
258
146
|
const code = afterCodes[i];
|
|
@@ -266,7 +154,7 @@ function makePosition(before, after) {
|
|
|
266
154
|
}
|
|
267
155
|
}
|
|
268
156
|
return pos(result);
|
|
269
|
-
}(after) : pos(
|
|
157
|
+
}(after) : pos(makePositionFromCodes(posCodes(before), posCodes(after)));
|
|
270
158
|
}
|
|
271
159
|
|
|
272
160
|
function makePositionFromCodes(before, after) {
|
|
@@ -312,243 +200,114 @@ function comparePosition(posA, posB) {
|
|
|
312
200
|
class LiveList extends AbstractCrdt {
|
|
313
201
|
constructor(items = []) {
|
|
314
202
|
let position;
|
|
315
|
-
super(), this._items = []
|
|
203
|
+
super(), this._items = [];
|
|
316
204
|
for (let i = 0; i < items.length; i++) {
|
|
317
|
-
const newPosition = makePosition(position), item =
|
|
318
|
-
|
|
205
|
+
const newPosition = makePosition(position), item = selfOrRegister(items[i]);
|
|
206
|
+
this._items.push([ item, newPosition ]), position = newPosition;
|
|
319
207
|
}
|
|
320
208
|
}
|
|
321
209
|
static _deserialize([id], parentToChildren, doc) {
|
|
322
|
-
const list = new LiveList;
|
|
210
|
+
const list = new LiveList([]);
|
|
323
211
|
list._attach(id, doc);
|
|
324
212
|
const children = parentToChildren.get(id);
|
|
325
213
|
if (null == children) return list;
|
|
326
|
-
for (const
|
|
327
|
-
const child = deserialize(
|
|
328
|
-
child._setParentLink(list,
|
|
214
|
+
for (const entry of children) {
|
|
215
|
+
const child = deserialize(entry, parentToChildren, doc);
|
|
216
|
+
child._setParentLink(list, entry[1].parentKey), list._items.push([ child, entry[1].parentKey ]),
|
|
217
|
+
list._items.sort(((itemA, itemB) => comparePosition(itemA[1], itemB[1])));
|
|
329
218
|
}
|
|
330
219
|
return list;
|
|
331
220
|
}
|
|
332
|
-
_serialize(parentId, parentKey, doc) {
|
|
221
|
+
_serialize(parentId, parentKey, doc, intent) {
|
|
333
222
|
if (null == this._id) throw new Error("Cannot serialize item is not attached");
|
|
223
|
+
if (null == parentId || null == parentKey) throw new Error("Cannot serialize list if parentId or parentKey is undefined");
|
|
334
224
|
const ops = [], op = {
|
|
335
225
|
id: this._id,
|
|
336
226
|
opId: null == doc ? void 0 : doc.generateOpId(),
|
|
227
|
+
intent: intent,
|
|
337
228
|
type: OpCode.CREATE_LIST,
|
|
338
229
|
parentId: parentId,
|
|
339
230
|
parentKey: parentKey
|
|
340
231
|
};
|
|
341
232
|
ops.push(op);
|
|
342
|
-
for (const
|
|
233
|
+
for (const [value, key] of this._items) ops.push(...value._serialize(this._id, key, doc));
|
|
343
234
|
return ops;
|
|
344
235
|
}
|
|
345
236
|
_indexOfPosition(position) {
|
|
346
|
-
return this._items.findIndex((item => item
|
|
237
|
+
return this._items.findIndex((item => item[1] === position));
|
|
347
238
|
}
|
|
348
239
|
_attach(id, doc) {
|
|
349
240
|
super._attach(id, doc);
|
|
350
|
-
for (const item of this._items) item._attach(doc.generateId(), doc);
|
|
241
|
+
for (const [item] of this._items) item._attach(doc.generateId(), doc);
|
|
351
242
|
}
|
|
352
243
|
_detach() {
|
|
353
244
|
super._detach();
|
|
354
|
-
for (const
|
|
245
|
+
for (const [value] of this._items) value._detach();
|
|
355
246
|
}
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
const {id: id, parentKey: key} = op, child = creationOpToLiveNode(op);
|
|
359
|
-
child._attach(id, this._doc), child._setParentLink(this, key);
|
|
360
|
-
const deletedId = op.deletedId, existingItemIndex = this._indexOfPosition(key);
|
|
361
|
-
if (-1 !== existingItemIndex) {
|
|
362
|
-
const existingItem = this._items[existingItemIndex];
|
|
363
|
-
if (existingItem._id === deletedId) return existingItem._detach(), this._items[existingItemIndex] = child,
|
|
364
|
-
{
|
|
365
|
-
modified: makeUpdate(this, [ setDelta(existingItemIndex, child) ]),
|
|
366
|
-
reverse: []
|
|
367
|
-
};
|
|
368
|
-
{
|
|
369
|
-
this._implicitlyDeletedItems.add(existingItem), this._items[existingItemIndex] = child;
|
|
370
|
-
const delta = [ setDelta(existingItemIndex, child) ], deleteDelta = this._detachItemAssociatedToSetOperation(op.deletedId);
|
|
371
|
-
return deleteDelta && delta.push(deleteDelta), {
|
|
372
|
-
modified: makeUpdate(this, delta),
|
|
373
|
-
reverse: []
|
|
374
|
-
};
|
|
375
|
-
}
|
|
376
|
-
}
|
|
377
|
-
{
|
|
378
|
-
const updates = [], deleteDelta = this._detachItemAssociatedToSetOperation(op.deletedId);
|
|
379
|
-
return deleteDelta && updates.push(deleteDelta), this._items.push(child), sortListItem(this._items),
|
|
380
|
-
updates.push(insertDelta(this._indexOfPosition(key), child)), {
|
|
381
|
-
reverse: [],
|
|
382
|
-
modified: makeUpdate(this, updates)
|
|
383
|
-
};
|
|
384
|
-
}
|
|
385
|
-
}
|
|
386
|
-
_applySetAck(op) {
|
|
387
|
-
const delta = [], deletedDelta = this._detachItemAssociatedToSetOperation(op.deletedId);
|
|
388
|
-
deletedDelta && delta.push(deletedDelta);
|
|
389
|
-
const indexOfItemWithSamePosition = this._indexOfPosition(op.parentKey), existingItem = this._items.find((item => item._id === op.id));
|
|
390
|
-
if (null != existingItem) {
|
|
391
|
-
if (existingItem._parentKey === op.parentKey) return delta.length > 0 ? {
|
|
392
|
-
modified: makeUpdate(this, delta),
|
|
393
|
-
reverse: []
|
|
394
|
-
} : {
|
|
395
|
-
modified: !1
|
|
396
|
-
};
|
|
397
|
-
-1 !== indexOfItemWithSamePosition && (this._implicitlyDeletedItems.add(this._items[indexOfItemWithSamePosition]),
|
|
398
|
-
this._items.splice(indexOfItemWithSamePosition, 1), delta.push(deleteDelta(indexOfItemWithSamePosition)));
|
|
399
|
-
const previousIndex = this._items.indexOf(existingItem);
|
|
400
|
-
existingItem._setParentLink(this, op.parentKey), sortListItem(this._items);
|
|
401
|
-
const newIndex = this._items.indexOf(existingItem);
|
|
402
|
-
return newIndex !== previousIndex && delta.push(moveDelta(previousIndex, newIndex, existingItem)),
|
|
403
|
-
{
|
|
404
|
-
modified: delta.length > 0 && makeUpdate(this, delta),
|
|
405
|
-
reverse: []
|
|
406
|
-
};
|
|
407
|
-
}
|
|
408
|
-
{
|
|
409
|
-
const orphan = nn(this._doc).getItem(op.id);
|
|
410
|
-
if (orphan && this._implicitlyDeletedItems.has(orphan)) {
|
|
411
|
-
orphan._setParentLink(this, op.parentKey), this._implicitlyDeletedItems.delete(orphan),
|
|
412
|
-
this._items.push(orphan), sortListItem(this._items);
|
|
413
|
-
const recreatedItemIndex = this._items.indexOf(orphan);
|
|
414
|
-
return {
|
|
415
|
-
modified: makeUpdate(this, [ -1 === indexOfItemWithSamePosition ? insertDelta(recreatedItemIndex, orphan) : setDelta(recreatedItemIndex, orphan), ...delta ]),
|
|
416
|
-
reverse: []
|
|
417
|
-
};
|
|
418
|
-
}
|
|
419
|
-
{
|
|
420
|
-
const {newItem: newItem, newIndex: newIndex} = this._createAttachItemAndSort(op, op.parentKey);
|
|
421
|
-
return {
|
|
422
|
-
modified: makeUpdate(this, [ -1 === indexOfItemWithSamePosition ? insertDelta(newIndex, newItem) : setDelta(newIndex, newItem), ...delta ]),
|
|
423
|
-
reverse: []
|
|
424
|
-
};
|
|
425
|
-
}
|
|
426
|
-
}
|
|
427
|
-
}
|
|
428
|
-
_detachItemAssociatedToSetOperation(deletedId) {
|
|
429
|
-
if (null == deletedId || null == this._doc) return null;
|
|
430
|
-
const deletedItem = this._doc.getItem(deletedId);
|
|
431
|
-
if (null == deletedItem) return null;
|
|
432
|
-
const result = this._detachChild(deletedItem);
|
|
433
|
-
return !1 === result.modified ? null : result.modified.updates[0];
|
|
434
|
-
}
|
|
435
|
-
_applyRemoteInsert(op) {
|
|
247
|
+
_attachChild(op, isLocal) {
|
|
248
|
+
var _a;
|
|
436
249
|
if (null == this._doc) throw new Error("Can't attach child if doc is not present");
|
|
437
|
-
const key =
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
return {
|
|
441
|
-
modified: makeUpdate(this, [ insertDelta(newIndex, newItem) ]),
|
|
442
|
-
reverse: []
|
|
250
|
+
const {id: id, parentKey: parentKey, intent: intent} = op, key = parentKey, child = creationOpToLiveStructure(op);
|
|
251
|
+
if (void 0 !== this._doc.getItem(id)) return {
|
|
252
|
+
modified: !1
|
|
443
253
|
};
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
if (
|
|
448
|
-
if (
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
modified: makeUpdate(this, [ moveDelta(oldPositionIndex, newIndex, existingItem) ]),
|
|
460
|
-
reverse: []
|
|
461
|
-
};
|
|
462
|
-
}
|
|
463
|
-
}
|
|
464
|
-
{
|
|
465
|
-
const orphan = nn(this._doc).getItem(op.id);
|
|
466
|
-
if (orphan && this._implicitlyDeletedItems.has(orphan)) {
|
|
467
|
-
orphan._setParentLink(this, key), this._implicitlyDeletedItems.delete(orphan), this._items.push(orphan),
|
|
468
|
-
sortListItem(this._items);
|
|
469
|
-
return {
|
|
470
|
-
modified: makeUpdate(this, [ insertDelta(this._indexOfPosition(key), orphan) ]),
|
|
471
|
-
reverse: []
|
|
254
|
+
child._attach(id, this._doc), child._setParentLink(this, key);
|
|
255
|
+
const index = this._items.findIndex((entry => entry[1] === key));
|
|
256
|
+
let newKey = key;
|
|
257
|
+
if (-1 !== index) {
|
|
258
|
+
if ("set" === intent) {
|
|
259
|
+
const existingItem = this._items[index][0];
|
|
260
|
+
existingItem._detach();
|
|
261
|
+
const storageUpdate = {
|
|
262
|
+
node: this,
|
|
263
|
+
type: "LiveList",
|
|
264
|
+
updates: [ {
|
|
265
|
+
index: index,
|
|
266
|
+
type: "set",
|
|
267
|
+
item: child instanceof LiveRegister ? child.data : child
|
|
268
|
+
} ]
|
|
472
269
|
};
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
const {newItem: newItem, newIndex: newIndex} = this._createAttachItemAndSort(op, key);
|
|
477
|
-
return {
|
|
478
|
-
modified: makeUpdate(this, [ insertDelta(newIndex, newItem) ]),
|
|
479
|
-
reverse: []
|
|
270
|
+
return this._items[index][0] = child, {
|
|
271
|
+
modified: storageUpdate,
|
|
272
|
+
reverse: existingItem._serialize(this._id, key, this._doc, "set")
|
|
480
273
|
};
|
|
481
274
|
}
|
|
275
|
+
if (isLocal) {
|
|
276
|
+
const before = this._items[index] ? this._items[index][1] : void 0, after = this._items[index + 1] ? this._items[index + 1][1] : void 0;
|
|
277
|
+
newKey = makePosition(before, after), child._setParentLink(this, newKey);
|
|
278
|
+
} else this._items[index][1] = makePosition(key, null === (_a = this._items[index + 1]) || void 0 === _a ? void 0 : _a[1]);
|
|
482
279
|
}
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
var _a;
|
|
486
|
-
const {id: id, parentKey: key} = op, child = creationOpToLiveNode(op);
|
|
487
|
-
if (void 0 !== (null === (_a = this._doc) || void 0 === _a ? void 0 : _a.getItem(id))) return {
|
|
488
|
-
modified: !1
|
|
489
|
-
};
|
|
490
|
-
child._attach(id, nn(this._doc)), child._setParentLink(this, key);
|
|
491
|
-
const existingItemIndex = this._indexOfPosition(key);
|
|
492
|
-
let newKey = key;
|
|
493
|
-
if (-1 !== existingItemIndex) {
|
|
494
|
-
newKey = makePosition(this._items[existingItemIndex] ? this._items[existingItemIndex]._getParentKeyOrThrow() : void 0, this._items[existingItemIndex + 1] ? this._items[existingItemIndex + 1]._getParentKeyOrThrow() : void 0),
|
|
495
|
-
child._setParentLink(this, newKey);
|
|
496
|
-
}
|
|
497
|
-
this._items.push(child), sortListItem(this._items);
|
|
280
|
+
this._items.push([ child, newKey ]), this._items.sort(((itemA, itemB) => comparePosition(itemA[1], itemB[1])));
|
|
281
|
+
const newIndex = this._items.findIndex((entry => entry[1] === newKey));
|
|
498
282
|
return {
|
|
499
|
-
modified: makeUpdate(this, [ insertDelta(this._indexOfPosition(newKey), child) ]),
|
|
500
283
|
reverse: [ {
|
|
501
284
|
type: OpCode.DELETE_CRDT,
|
|
502
285
|
id: id
|
|
503
|
-
} ]
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
286
|
+
} ],
|
|
287
|
+
modified: {
|
|
288
|
+
node: this,
|
|
289
|
+
type: "LiveList",
|
|
290
|
+
updates: [ {
|
|
291
|
+
index: newIndex,
|
|
292
|
+
type: "insert",
|
|
293
|
+
item: child instanceof LiveRegister ? child.data : child
|
|
294
|
+
} ]
|
|
295
|
+
}
|
|
511
296
|
};
|
|
512
|
-
const indexOfItemWithSameKey = this._indexOfPosition(key);
|
|
513
|
-
child._attach(id, nn(this._doc)), child._setParentLink(this, key);
|
|
514
|
-
const newKey = key;
|
|
515
|
-
if (-1 !== indexOfItemWithSameKey) {
|
|
516
|
-
const existingItem = this._items[indexOfItemWithSameKey];
|
|
517
|
-
existingItem._detach(), this._items[indexOfItemWithSameKey] = child;
|
|
518
|
-
const reverse = existingItem._serialize(nn(this._id), key, this._doc);
|
|
519
|
-
addIntentAndDeletedIdToOperation(reverse, op.id);
|
|
520
|
-
const delta = [ setDelta(indexOfItemWithSameKey, child) ], deletedDelta = this._detachItemAssociatedToSetOperation(op.deletedId);
|
|
521
|
-
return deletedDelta && delta.push(deletedDelta), {
|
|
522
|
-
modified: makeUpdate(this, delta),
|
|
523
|
-
reverse: reverse
|
|
524
|
-
};
|
|
525
|
-
}
|
|
526
|
-
{
|
|
527
|
-
this._items.push(child), sortListItem(this._items), this._detachItemAssociatedToSetOperation(op.deletedId);
|
|
528
|
-
const newIndex = this._indexOfPosition(newKey);
|
|
529
|
-
return {
|
|
530
|
-
reverse: [ {
|
|
531
|
-
type: OpCode.DELETE_CRDT,
|
|
532
|
-
id: id
|
|
533
|
-
} ],
|
|
534
|
-
modified: makeUpdate(this, [ insertDelta(newIndex, child) ])
|
|
535
|
-
};
|
|
536
|
-
}
|
|
537
|
-
}
|
|
538
|
-
_attachChild(op, source) {
|
|
539
|
-
if (null == this._doc) throw new Error("Can't attach child if doc is not present");
|
|
540
|
-
if ("set" === op.intent) {
|
|
541
|
-
if (source === OpSource.REMOTE) return this._applyRemoteSet(op);
|
|
542
|
-
if (source === OpSource.UNDOREDO_RECONNECT) return this._applySetUndoRedo(op);
|
|
543
|
-
if (source === OpSource.ACK) return this._applySetAck(op);
|
|
544
|
-
}
|
|
545
|
-
return source === OpSource.REMOTE ? this._applyRemoteInsert(op) : source === OpSource.ACK ? this._applyInsertAck(op) : this._applyInsertUndoRedo(op);
|
|
546
297
|
}
|
|
547
298
|
_detachChild(child) {
|
|
548
299
|
if (child) {
|
|
549
|
-
const
|
|
550
|
-
|
|
551
|
-
|
|
300
|
+
const reverse = child._serialize(this._id, child._parentKey, this._doc), indexToDelete = this._items.findIndex((item => item[0] === child));
|
|
301
|
+
this._items.splice(indexToDelete, 1), child._detach();
|
|
302
|
+
return {
|
|
303
|
+
modified: {
|
|
304
|
+
node: this,
|
|
305
|
+
type: "LiveList",
|
|
306
|
+
updates: [ {
|
|
307
|
+
index: indexToDelete,
|
|
308
|
+
type: "delete"
|
|
309
|
+
} ]
|
|
310
|
+
},
|
|
552
311
|
reverse: reverse
|
|
553
312
|
};
|
|
554
313
|
}
|
|
@@ -556,100 +315,41 @@ class LiveList extends AbstractCrdt {
|
|
|
556
315
|
modified: !1
|
|
557
316
|
};
|
|
558
317
|
}
|
|
559
|
-
|
|
560
|
-
var _a;
|
|
561
|
-
if (this._implicitlyDeletedItems.has(child)) {
|
|
562
|
-
this._implicitlyDeletedItems.delete(child), child._setParentLink(this, newKey),
|
|
563
|
-
this._items.push(child), sortListItem(this._items);
|
|
564
|
-
return {
|
|
565
|
-
modified: makeUpdate(this, [ insertDelta(this._items.indexOf(child), child) ]),
|
|
566
|
-
reverse: []
|
|
567
|
-
};
|
|
568
|
-
}
|
|
569
|
-
if (newKey === child._parentKey) return {
|
|
570
|
-
modified: !1
|
|
571
|
-
};
|
|
572
|
-
const existingItemIndex = this._indexOfPosition(newKey);
|
|
573
|
-
if (-1 === existingItemIndex) {
|
|
574
|
-
const previousIndex = this._items.indexOf(child);
|
|
575
|
-
child._setParentLink(this, newKey), sortListItem(this._items);
|
|
576
|
-
const newIndex = this._items.indexOf(child);
|
|
577
|
-
return newIndex === previousIndex ? {
|
|
578
|
-
modified: !1
|
|
579
|
-
} : {
|
|
580
|
-
modified: makeUpdate(this, [ moveDelta(previousIndex, newIndex, child) ]),
|
|
581
|
-
reverse: []
|
|
582
|
-
};
|
|
583
|
-
}
|
|
584
|
-
{
|
|
585
|
-
this._items[existingItemIndex]._setParentLink(this, makePosition(newKey, null === (_a = this._items[existingItemIndex + 1]) || void 0 === _a ? void 0 : _a._getParentKeyOrThrow()));
|
|
586
|
-
const previousIndex = this._items.indexOf(child);
|
|
587
|
-
child._setParentLink(this, newKey), sortListItem(this._items);
|
|
588
|
-
const newIndex = this._items.indexOf(child);
|
|
589
|
-
return newIndex === previousIndex ? {
|
|
590
|
-
modified: !1
|
|
591
|
-
} : {
|
|
592
|
-
modified: makeUpdate(this, [ moveDelta(previousIndex, newIndex, child) ]),
|
|
593
|
-
reverse: []
|
|
594
|
-
};
|
|
595
|
-
}
|
|
596
|
-
}
|
|
597
|
-
_applySetChildKeyAck(newKey, child) {
|
|
598
|
-
var _a, _b;
|
|
599
|
-
const previousKey = nn(child._parentKey);
|
|
600
|
-
if (this._implicitlyDeletedItems.has(child)) {
|
|
601
|
-
const existingItemIndex = this._indexOfPosition(newKey);
|
|
602
|
-
return this._implicitlyDeletedItems.delete(child), -1 !== existingItemIndex && this._items[existingItemIndex]._setParentLink(this, makePosition(newKey, null === (_a = this._items[existingItemIndex + 1]) || void 0 === _a ? void 0 : _a._getParentKeyOrThrow())),
|
|
603
|
-
child._setParentLink(this, newKey), this._items.push(child), sortListItem(this._items),
|
|
604
|
-
{
|
|
605
|
-
modified: !1
|
|
606
|
-
};
|
|
607
|
-
}
|
|
608
|
-
{
|
|
609
|
-
if (newKey === previousKey) return {
|
|
610
|
-
modified: !1
|
|
611
|
-
};
|
|
612
|
-
const previousIndex = this._items.indexOf(child), existingItemIndex = this._indexOfPosition(newKey);
|
|
613
|
-
-1 !== existingItemIndex && this._items[existingItemIndex]._setParentLink(this, makePosition(newKey, null === (_b = this._items[existingItemIndex + 1]) || void 0 === _b ? void 0 : _b._getParentKeyOrThrow())),
|
|
614
|
-
child._setParentLink(this, newKey), sortListItem(this._items);
|
|
615
|
-
const newIndex = this._items.indexOf(child);
|
|
616
|
-
return previousIndex === newIndex ? {
|
|
617
|
-
modified: !1
|
|
618
|
-
} : {
|
|
619
|
-
modified: makeUpdate(this, [ moveDelta(previousIndex, newIndex, child) ]),
|
|
620
|
-
reverse: []
|
|
621
|
-
};
|
|
622
|
-
}
|
|
623
|
-
}
|
|
624
|
-
_applySetChildKeyUndoRedo(newKey, child) {
|
|
318
|
+
_setChildKey(key, child, previousKey) {
|
|
625
319
|
var _a;
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
const
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
modified:
|
|
320
|
+
child._setParentLink(this, key);
|
|
321
|
+
const previousIndex = this._items.findIndex((entry => entry[0]._id === child._id)), index = this._items.findIndex((entry => entry[1] === key));
|
|
322
|
+
-1 !== index && (this._items[index][1] = makePosition(key, null === (_a = this._items[index + 1]) || void 0 === _a ? void 0 : _a[1]));
|
|
323
|
+
const item = this._items.find((item => item[0] === child));
|
|
324
|
+
item && (item[1] = key), this._items.sort(((itemA, itemB) => comparePosition(itemA[1], itemB[1])));
|
|
325
|
+
const newIndex = this._items.findIndex((entry => entry[0]._id === child._id));
|
|
326
|
+
return {
|
|
327
|
+
modified: {
|
|
328
|
+
node: this,
|
|
329
|
+
type: "LiveList",
|
|
330
|
+
updates: newIndex === previousIndex ? [] : [ {
|
|
331
|
+
index: newIndex,
|
|
332
|
+
item: child instanceof LiveRegister ? child.data : child,
|
|
333
|
+
previousIndex: previousIndex,
|
|
334
|
+
type: "move"
|
|
335
|
+
} ]
|
|
336
|
+
},
|
|
634
337
|
reverse: [ {
|
|
635
338
|
type: OpCode.SET_PARENT_KEY,
|
|
636
|
-
id:
|
|
339
|
+
id: null == item ? void 0 : item[0]._id,
|
|
637
340
|
parentKey: previousKey
|
|
638
341
|
} ]
|
|
639
342
|
};
|
|
640
343
|
}
|
|
641
|
-
_setChildKey(newKey, child, source) {
|
|
642
|
-
return source === OpSource.REMOTE ? this._applySetChildKeyRemote(newKey, child) : source === OpSource.ACK ? this._applySetChildKeyAck(newKey, child) : this._applySetChildKeyUndoRedo(newKey, child);
|
|
643
|
-
}
|
|
644
344
|
_apply(op, isLocal) {
|
|
645
345
|
return super._apply(op, isLocal);
|
|
646
346
|
}
|
|
647
347
|
_toSerializedCrdt() {
|
|
648
|
-
|
|
348
|
+
var _a;
|
|
649
349
|
return {
|
|
650
350
|
type: CrdtType.LIST,
|
|
651
|
-
parentId:
|
|
652
|
-
parentKey: this.
|
|
351
|
+
parentId: null === (_a = this._parent) || void 0 === _a ? void 0 : _a._id,
|
|
352
|
+
parentKey: this._parentKey
|
|
653
353
|
};
|
|
654
354
|
}
|
|
655
355
|
get length() {
|
|
@@ -660,14 +360,25 @@ class LiveList extends AbstractCrdt {
|
|
|
660
360
|
}
|
|
661
361
|
insert(element, index) {
|
|
662
362
|
if (index < 0 || index > this._items.length) throw new Error(`Cannot insert list item at index "${index}". index should be between 0 and ${this._items.length}`);
|
|
663
|
-
const position = makePosition(this._items[index - 1] ? this._items[index - 1]
|
|
664
|
-
|
|
665
|
-
this.
|
|
363
|
+
const position = makePosition(this._items[index - 1] ? this._items[index - 1][1] : void 0, this._items[index] ? this._items[index][1] : void 0), value = selfOrRegister(element);
|
|
364
|
+
value._setParentLink(this, position), this._items.push([ value, position ]), this._items.sort(((itemA, itemB) => comparePosition(itemA[1], itemB[1])));
|
|
365
|
+
const newIndex = this._items.findIndex((entry => entry[1] === position));
|
|
366
|
+
if (this._doc && this._id) {
|
|
666
367
|
const id = this._doc.generateId();
|
|
667
|
-
value._attach(id, this._doc)
|
|
368
|
+
value._attach(id, this._doc);
|
|
369
|
+
const storageUpdates = new Map;
|
|
370
|
+
storageUpdates.set(this._id, {
|
|
371
|
+
node: this,
|
|
372
|
+
type: "LiveList",
|
|
373
|
+
updates: [ {
|
|
374
|
+
index: newIndex,
|
|
375
|
+
item: value instanceof LiveRegister ? value.data : value,
|
|
376
|
+
type: "insert"
|
|
377
|
+
} ]
|
|
378
|
+
}), this._doc.dispatch(value._serialize(this._id, position, this._doc), [ {
|
|
668
379
|
type: OpCode.DELETE_CRDT,
|
|
669
380
|
id: id
|
|
670
|
-
} ],
|
|
381
|
+
} ], storageUpdates);
|
|
671
382
|
}
|
|
672
383
|
}
|
|
673
384
|
move(index, targetIndex) {
|
|
@@ -676,20 +387,31 @@ class LiveList extends AbstractCrdt {
|
|
|
676
387
|
if (index < 0) throw new Error("index cannot be less than 0");
|
|
677
388
|
if (index >= this._items.length) throw new Error("index cannot be greater or equal than the list length");
|
|
678
389
|
let beforePosition = null, afterPosition = null;
|
|
679
|
-
index < targetIndex ? (afterPosition = targetIndex === this._items.length - 1 ? void 0 : this._items[targetIndex + 1]
|
|
680
|
-
beforePosition = this._items[targetIndex]
|
|
681
|
-
beforePosition = 0 === targetIndex ? void 0 : this._items[targetIndex - 1]
|
|
682
|
-
const position = makePosition(beforePosition, afterPosition), item = this._items[index], previousPosition = item
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
390
|
+
index < targetIndex ? (afterPosition = targetIndex === this._items.length - 1 ? void 0 : this._items[targetIndex + 1][1],
|
|
391
|
+
beforePosition = this._items[targetIndex][1]) : (afterPosition = this._items[targetIndex][1],
|
|
392
|
+
beforePosition = 0 === targetIndex ? void 0 : this._items[targetIndex - 1][1]);
|
|
393
|
+
const position = makePosition(beforePosition, afterPosition), item = this._items[index], previousPosition = item[1];
|
|
394
|
+
item[1] = position, item[0]._setParentLink(this, position), this._items.sort(((itemA, itemB) => comparePosition(itemA[1], itemB[1])));
|
|
395
|
+
const newIndex = this._items.findIndex((entry => entry[1] === position));
|
|
396
|
+
if (this._doc && this._id) {
|
|
397
|
+
const storageUpdates = new Map;
|
|
398
|
+
storageUpdates.set(this._id, {
|
|
399
|
+
node: this,
|
|
400
|
+
type: "LiveList",
|
|
401
|
+
updates: [ {
|
|
402
|
+
index: newIndex,
|
|
403
|
+
previousIndex: index,
|
|
404
|
+
item: item[0],
|
|
405
|
+
type: "move"
|
|
406
|
+
} ]
|
|
407
|
+
}), this._doc.dispatch([ {
|
|
686
408
|
type: OpCode.SET_PARENT_KEY,
|
|
687
|
-
id:
|
|
409
|
+
id: item[0]._id,
|
|
688
410
|
opId: this._doc.generateOpId(),
|
|
689
411
|
parentKey: position
|
|
690
412
|
} ], [ {
|
|
691
413
|
type: OpCode.SET_PARENT_KEY,
|
|
692
|
-
id:
|
|
414
|
+
id: item[0]._id,
|
|
693
415
|
parentKey: previousPosition
|
|
694
416
|
} ], storageUpdates);
|
|
695
417
|
}
|
|
@@ -697,15 +419,22 @@ class LiveList extends AbstractCrdt {
|
|
|
697
419
|
delete(index) {
|
|
698
420
|
if (index < 0 || index >= this._items.length) throw new Error(`Cannot delete list item at index "${index}". index should be between 0 and ${this._items.length - 1}`);
|
|
699
421
|
const item = this._items[index];
|
|
700
|
-
if (item._detach(), this._items.splice(index, 1), this._doc) {
|
|
701
|
-
const childRecordId = item._id;
|
|
422
|
+
if (item[0]._detach(), this._items.splice(index, 1), this._doc) {
|
|
423
|
+
const childRecordId = item[0]._id;
|
|
702
424
|
if (childRecordId) {
|
|
703
425
|
const storageUpdates = new Map;
|
|
704
|
-
storageUpdates.set(
|
|
426
|
+
storageUpdates.set(this._id, {
|
|
427
|
+
node: this,
|
|
428
|
+
type: "LiveList",
|
|
429
|
+
updates: [ {
|
|
430
|
+
index: index,
|
|
431
|
+
type: "delete"
|
|
432
|
+
} ]
|
|
433
|
+
}), this._doc.dispatch([ {
|
|
705
434
|
id: childRecordId,
|
|
706
435
|
opId: this._doc.generateOpId(),
|
|
707
436
|
type: OpCode.DELETE_CRDT
|
|
708
|
-
} ], item._serialize(
|
|
437
|
+
} ], item[0]._serialize(this._id, item[1]), storageUpdates);
|
|
709
438
|
}
|
|
710
439
|
}
|
|
711
440
|
}
|
|
@@ -714,41 +443,50 @@ class LiveList extends AbstractCrdt {
|
|
|
714
443
|
const ops = [], reverseOps = [], updateDelta = [];
|
|
715
444
|
let i = 0;
|
|
716
445
|
for (const item of this._items) {
|
|
717
|
-
item._detach();
|
|
718
|
-
const childId = item._id;
|
|
446
|
+
item[0]._detach();
|
|
447
|
+
const childId = item[0]._id;
|
|
719
448
|
childId && (ops.push({
|
|
720
|
-
type: OpCode.DELETE_CRDT,
|
|
721
449
|
id: childId,
|
|
722
|
-
|
|
723
|
-
}), reverseOps.push(...item._serialize(
|
|
724
|
-
|
|
450
|
+
type: OpCode.DELETE_CRDT
|
|
451
|
+
}), reverseOps.push(...item[0]._serialize(this._id, item[1])), updateDelta.push({
|
|
452
|
+
index: i,
|
|
453
|
+
type: "delete"
|
|
454
|
+
})), i++;
|
|
725
455
|
}
|
|
726
456
|
this._items = [];
|
|
727
457
|
const storageUpdates = new Map;
|
|
728
|
-
storageUpdates.set(
|
|
458
|
+
storageUpdates.set(this._id, {
|
|
459
|
+
node: this,
|
|
460
|
+
type: "LiveList",
|
|
461
|
+
updates: updateDelta
|
|
462
|
+
}), this._doc.dispatch(ops, reverseOps, storageUpdates);
|
|
729
463
|
} else {
|
|
730
|
-
for (const item of this._items) item._detach();
|
|
464
|
+
for (const item of this._items) item[0]._detach();
|
|
731
465
|
this._items = [];
|
|
732
466
|
}
|
|
733
467
|
}
|
|
734
468
|
set(index, item) {
|
|
735
469
|
if (index < 0 || index >= this._items.length) throw new Error(`Cannot set list item at index "${index}". index should be between 0 and ${this._items.length - 1}`);
|
|
736
|
-
const existingItem = this._items[index]
|
|
470
|
+
const [existingItem, position] = this._items[index];
|
|
737
471
|
existingItem._detach();
|
|
738
|
-
const value =
|
|
739
|
-
if (value._setParentLink(this, position), this._items[index] = value, this._doc && this._id) {
|
|
472
|
+
const value = selfOrRegister(item);
|
|
473
|
+
if (value._setParentLink(this, position), this._items[index][0] = value, this._doc && this._id) {
|
|
740
474
|
const id = this._doc.generateId();
|
|
741
475
|
value._attach(id, this._doc);
|
|
742
476
|
const storageUpdates = new Map;
|
|
743
|
-
storageUpdates.set(this._id,
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
477
|
+
storageUpdates.set(this._id, {
|
|
478
|
+
node: this,
|
|
479
|
+
type: "LiveList",
|
|
480
|
+
updates: [ {
|
|
481
|
+
index: index,
|
|
482
|
+
item: value instanceof LiveRegister ? value.data : value,
|
|
483
|
+
type: "set"
|
|
484
|
+
} ]
|
|
485
|
+
}), this._doc.dispatch(value._serialize(this._id, position, this._doc, "set"), existingItem._serialize(this._id, position, void 0, "set"), storageUpdates);
|
|
748
486
|
}
|
|
749
487
|
}
|
|
750
488
|
toArray() {
|
|
751
|
-
return this._items.map((entry =>
|
|
489
|
+
return this._items.map((entry => selfOrRegisterValue(entry[0])));
|
|
752
490
|
}
|
|
753
491
|
every(predicate) {
|
|
754
492
|
return this.toArray().every(predicate);
|
|
@@ -766,7 +504,7 @@ class LiveList extends AbstractCrdt {
|
|
|
766
504
|
return this.toArray().forEach(callbackfn);
|
|
767
505
|
}
|
|
768
506
|
get(index) {
|
|
769
|
-
if (!(index < 0 || index >= this._items.length)) return
|
|
507
|
+
if (!(index < 0 || index >= this._items.length)) return selfOrRegisterValue(this._items[index][0]);
|
|
770
508
|
}
|
|
771
509
|
indexOf(searchElement, fromIndex) {
|
|
772
510
|
return this.toArray().indexOf(searchElement, fromIndex);
|
|
@@ -775,7 +513,7 @@ class LiveList extends AbstractCrdt {
|
|
|
775
513
|
return this.toArray().lastIndexOf(searchElement, fromIndex);
|
|
776
514
|
}
|
|
777
515
|
map(callback) {
|
|
778
|
-
return this._items.map(((entry, i) => callback(
|
|
516
|
+
return this._items.map(((entry, i) => callback(selfOrRegisterValue(entry[0]), i)));
|
|
779
517
|
}
|
|
780
518
|
some(predicate) {
|
|
781
519
|
return this.toArray().some(predicate);
|
|
@@ -783,20 +521,6 @@ class LiveList extends AbstractCrdt {
|
|
|
783
521
|
[Symbol.iterator]() {
|
|
784
522
|
return new LiveListIterator(this._items);
|
|
785
523
|
}
|
|
786
|
-
_createAttachItemAndSort(op, key) {
|
|
787
|
-
const newItem = creationOpToLiveNode(op);
|
|
788
|
-
newItem._attach(op.id, nn(this._doc)), newItem._setParentLink(this, key), this._items.push(newItem),
|
|
789
|
-
sortListItem(this._items);
|
|
790
|
-
return {
|
|
791
|
-
newItem: newItem,
|
|
792
|
-
newIndex: this._indexOfPosition(key)
|
|
793
|
-
};
|
|
794
|
-
}
|
|
795
|
-
_shiftItemPosition(index, key) {
|
|
796
|
-
var _a;
|
|
797
|
-
const shiftedPosition = makePosition(key, this._items.length > index + 1 ? null === (_a = this._items[index + 1]) || void 0 === _a ? void 0 : _a._getParentKeyOrThrow() : void 0);
|
|
798
|
-
this._items[index]._setParentLink(this, shiftedPosition);
|
|
799
|
-
}
|
|
800
524
|
}
|
|
801
525
|
|
|
802
526
|
class LiveListIterator {
|
|
@@ -808,85 +532,57 @@ class LiveListIterator {
|
|
|
808
532
|
}
|
|
809
533
|
next() {
|
|
810
534
|
const result = this._innerIterator.next();
|
|
811
|
-
|
|
535
|
+
return result.done ? {
|
|
812
536
|
done: !0,
|
|
813
537
|
value: void 0
|
|
814
|
-
}
|
|
815
|
-
|
|
816
|
-
value: liveNodeToLson(result.value)
|
|
538
|
+
} : {
|
|
539
|
+
value: selfOrRegisterValue(result.value[0])
|
|
817
540
|
};
|
|
818
541
|
}
|
|
819
542
|
}
|
|
820
543
|
|
|
821
|
-
|
|
822
|
-
return {
|
|
823
|
-
node: liveList,
|
|
824
|
-
type: "LiveList",
|
|
825
|
-
updates: deltaUpdates
|
|
826
|
-
};
|
|
827
|
-
}
|
|
828
|
-
|
|
829
|
-
function setDelta(index, item) {
|
|
830
|
-
return {
|
|
831
|
-
index: index,
|
|
832
|
-
type: "set",
|
|
833
|
-
item: item instanceof LiveRegister ? item.data : item
|
|
834
|
-
};
|
|
835
|
-
}
|
|
836
|
-
|
|
837
|
-
function deleteDelta(index) {
|
|
838
|
-
return {
|
|
839
|
-
index: index,
|
|
840
|
-
type: "delete"
|
|
841
|
-
};
|
|
842
|
-
}
|
|
544
|
+
const _emittedDeprecationWarnings = new Set;
|
|
843
545
|
|
|
844
|
-
function
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
type: "insert",
|
|
848
|
-
item: item instanceof LiveRegister ? item.data : item
|
|
849
|
-
};
|
|
546
|
+
function deprecate(message, key = message) {
|
|
547
|
+
"production" !== process.env.NODE_ENV && (_emittedDeprecationWarnings.has(key) || (_emittedDeprecationWarnings.add(key),
|
|
548
|
+
console.error(`DEPRECATION WARNING: ${message}`)));
|
|
850
549
|
}
|
|
851
550
|
|
|
852
|
-
function
|
|
853
|
-
|
|
854
|
-
index: index,
|
|
855
|
-
type: "move",
|
|
856
|
-
previousIndex: previousIndex,
|
|
857
|
-
item: item instanceof LiveRegister ? item.data : item
|
|
858
|
-
};
|
|
551
|
+
function deprecateIf(condition, message, key = message) {
|
|
552
|
+
"production" !== process.env.NODE_ENV && condition && deprecate(message, key);
|
|
859
553
|
}
|
|
860
554
|
|
|
861
|
-
function
|
|
862
|
-
|
|
555
|
+
function throwUsageError(message) {
|
|
556
|
+
if ("production" !== process.env.NODE_ENV) {
|
|
557
|
+
const usageError = new Error(message);
|
|
558
|
+
throw usageError.name = "Usage error", usageError;
|
|
559
|
+
}
|
|
863
560
|
}
|
|
864
561
|
|
|
865
|
-
function
|
|
866
|
-
|
|
867
|
-
const firstOp = ops[0];
|
|
868
|
-
if (firstOp.type !== OpCode.CREATE_LIST && firstOp.type !== OpCode.CREATE_OBJECT && firstOp.type !== OpCode.CREATE_REGISTER && firstOp.type !== OpCode.CREATE_MAP) throw new Error("Internal error. Serialized LiveStructure first op should be CreateOp");
|
|
869
|
-
firstOp.intent = "set", firstOp.deletedId = deletedId;
|
|
562
|
+
function errorIf(condition, message) {
|
|
563
|
+
"production" !== process.env.NODE_ENV && condition && throwUsageError(message);
|
|
870
564
|
}
|
|
871
565
|
|
|
872
566
|
class LiveMap extends AbstractCrdt {
|
|
873
567
|
constructor(entries) {
|
|
874
|
-
if (super(),
|
|
568
|
+
if (super(), deprecateIf(null === entries, "Support for calling `new LiveMap(null)` will be removed in @liveblocks/client 0.18. Please call as `new LiveMap()`, or `new LiveMap([])`."),
|
|
875
569
|
entries) {
|
|
876
570
|
const mappedEntries = [];
|
|
877
571
|
for (const entry of entries) {
|
|
878
|
-
const value =
|
|
572
|
+
const value = selfOrRegister(entry[1]);
|
|
879
573
|
value._setParentLink(this, entry[0]), mappedEntries.push([ entry[0], value ]);
|
|
880
574
|
}
|
|
881
575
|
this._map = new Map(mappedEntries);
|
|
882
576
|
} else this._map = new Map;
|
|
883
577
|
}
|
|
884
|
-
_serialize(parentId, parentKey, doc) {
|
|
578
|
+
_serialize(parentId, parentKey, doc, intent) {
|
|
885
579
|
if (null == this._id) throw new Error("Cannot serialize item is not attached");
|
|
580
|
+
if (null == parentId || null == parentKey) throw new Error("Cannot serialize map if parentId or parentKey is undefined");
|
|
886
581
|
const ops = [], op = {
|
|
887
582
|
id: this._id,
|
|
888
583
|
opId: null == doc ? void 0 : doc.generateOpId(),
|
|
889
584
|
type: OpCode.CREATE_MAP,
|
|
585
|
+
intent: intent,
|
|
890
586
|
parentId: parentId,
|
|
891
587
|
parentKey: parentKey
|
|
892
588
|
};
|
|
@@ -899,32 +595,30 @@ class LiveMap extends AbstractCrdt {
|
|
|
899
595
|
map._attach(id, doc);
|
|
900
596
|
const children = parentToChildren.get(id);
|
|
901
597
|
if (null == children) return map;
|
|
902
|
-
for (const
|
|
903
|
-
const
|
|
598
|
+
for (const entry of children) {
|
|
599
|
+
const crdt = entry[1];
|
|
600
|
+
if (null == crdt.parentKey) throw new Error("Tried to deserialize a crdt but it does not have a parentKey and is not the root");
|
|
601
|
+
const child = deserialize(entry, parentToChildren, doc);
|
|
904
602
|
child._setParentLink(map, crdt.parentKey), map._map.set(crdt.parentKey, child);
|
|
905
603
|
}
|
|
906
604
|
return map;
|
|
907
605
|
}
|
|
908
606
|
_attach(id, doc) {
|
|
909
607
|
super._attach(id, doc);
|
|
910
|
-
for (const [_key, value] of this._map)
|
|
608
|
+
for (const [_key, value] of this._map) isCrdt(value) && value._attach(doc.generateId(), doc);
|
|
911
609
|
}
|
|
912
|
-
_attachChild(op) {
|
|
610
|
+
_attachChild(op, _isLocal) {
|
|
913
611
|
if (null == this._doc) throw new Error("Can't attach child if doc is not present");
|
|
914
|
-
const {id: id, parentKey:
|
|
612
|
+
const {id: id, parentKey: parentKey} = op, key = parentKey, child = creationOpToLiveStructure(op);
|
|
915
613
|
if (void 0 !== this._doc.getItem(id)) return {
|
|
916
614
|
modified: !1
|
|
917
615
|
};
|
|
918
616
|
const previousValue = this._map.get(key);
|
|
919
617
|
let reverse;
|
|
920
|
-
|
|
921
|
-
const thisId = nn(this._id);
|
|
922
|
-
reverse = previousValue._serialize(thisId, key), previousValue._detach();
|
|
923
|
-
} else reverse = [ {
|
|
618
|
+
return previousValue ? (reverse = previousValue._serialize(this._id, key), previousValue._detach()) : reverse = [ {
|
|
924
619
|
type: OpCode.DELETE_CRDT,
|
|
925
620
|
id: id
|
|
926
|
-
} ]
|
|
927
|
-
return child._setParentLink(this, key), child._attach(id, this._doc), this._map.set(key, child),
|
|
621
|
+
} ], child._setParentLink(this, key), child._attach(id, this._doc), this._map.set(key, child),
|
|
928
622
|
{
|
|
929
623
|
modified: {
|
|
930
624
|
node: this,
|
|
@@ -943,7 +637,7 @@ class LiveMap extends AbstractCrdt {
|
|
|
943
637
|
for (const item of this._map.values()) item._detach();
|
|
944
638
|
}
|
|
945
639
|
_detachChild(child) {
|
|
946
|
-
const
|
|
640
|
+
const reverse = child._serialize(this._id, child._parentKey, this._doc);
|
|
947
641
|
for (const [key, value] of this._map) value === child && this._map.delete(key);
|
|
948
642
|
child._detach();
|
|
949
643
|
return {
|
|
@@ -951,7 +645,7 @@ class LiveMap extends AbstractCrdt {
|
|
|
951
645
|
node: this,
|
|
952
646
|
type: "LiveMap",
|
|
953
647
|
updates: {
|
|
954
|
-
[
|
|
648
|
+
[child._parentKey]: {
|
|
955
649
|
type: "delete"
|
|
956
650
|
}
|
|
957
651
|
}
|
|
@@ -960,21 +654,21 @@ class LiveMap extends AbstractCrdt {
|
|
|
960
654
|
};
|
|
961
655
|
}
|
|
962
656
|
_toSerializedCrdt() {
|
|
963
|
-
|
|
657
|
+
var _a;
|
|
964
658
|
return {
|
|
965
659
|
type: CrdtType.MAP,
|
|
966
|
-
parentId:
|
|
967
|
-
parentKey: this.
|
|
660
|
+
parentId: null === (_a = this._parent) || void 0 === _a ? void 0 : _a._id,
|
|
661
|
+
parentKey: this._parentKey
|
|
968
662
|
};
|
|
969
663
|
}
|
|
970
664
|
get(key) {
|
|
971
665
|
const value = this._map.get(key);
|
|
972
|
-
if (null != value) return
|
|
666
|
+
if (null != value) return selfOrRegisterValue(value);
|
|
973
667
|
}
|
|
974
668
|
set(key, value) {
|
|
975
669
|
const oldValue = this._map.get(key);
|
|
976
670
|
oldValue && oldValue._detach();
|
|
977
|
-
const item =
|
|
671
|
+
const item = selfOrRegister(value);
|
|
978
672
|
if (item._setParentLink(this, key), this._map.set(key, item), this._doc && this._id) {
|
|
979
673
|
const id = this._doc.generateId();
|
|
980
674
|
item._attach(id, this._doc);
|
|
@@ -1003,8 +697,8 @@ class LiveMap extends AbstractCrdt {
|
|
|
1003
697
|
const item = this._map.get(key);
|
|
1004
698
|
if (null == item) return !1;
|
|
1005
699
|
if (item._detach(), this._map.delete(key), this._doc && item._id) {
|
|
1006
|
-
const
|
|
1007
|
-
storageUpdates.set(
|
|
700
|
+
const storageUpdates = new Map;
|
|
701
|
+
storageUpdates.set(this._id, {
|
|
1008
702
|
node: this,
|
|
1009
703
|
type: "LiveMap",
|
|
1010
704
|
updates: {
|
|
@@ -1016,14 +710,14 @@ class LiveMap extends AbstractCrdt {
|
|
|
1016
710
|
type: OpCode.DELETE_CRDT,
|
|
1017
711
|
id: item._id,
|
|
1018
712
|
opId: this._doc.generateOpId()
|
|
1019
|
-
} ], item._serialize(
|
|
713
|
+
} ], item._serialize(this._id, key), storageUpdates);
|
|
1020
714
|
}
|
|
1021
715
|
return !0;
|
|
1022
716
|
}
|
|
1023
717
|
entries() {
|
|
1024
718
|
const innerIterator = this._map.entries();
|
|
1025
719
|
return {
|
|
1026
|
-
[Symbol.iterator]() {
|
|
720
|
+
[Symbol.iterator]: function() {
|
|
1027
721
|
return this;
|
|
1028
722
|
},
|
|
1029
723
|
next() {
|
|
@@ -1033,7 +727,7 @@ class LiveMap extends AbstractCrdt {
|
|
|
1033
727
|
value: void 0
|
|
1034
728
|
};
|
|
1035
729
|
return {
|
|
1036
|
-
value: [ iteratorValue.value[0],
|
|
730
|
+
value: [ iteratorValue.value[0], selfOrRegisterValue(iteratorValue.value[1]) ]
|
|
1037
731
|
};
|
|
1038
732
|
}
|
|
1039
733
|
};
|
|
@@ -1047,17 +741,16 @@ class LiveMap extends AbstractCrdt {
|
|
|
1047
741
|
values() {
|
|
1048
742
|
const innerIterator = this._map.values();
|
|
1049
743
|
return {
|
|
1050
|
-
[Symbol.iterator]() {
|
|
744
|
+
[Symbol.iterator]: function() {
|
|
1051
745
|
return this;
|
|
1052
746
|
},
|
|
1053
747
|
next() {
|
|
1054
748
|
const iteratorValue = innerIterator.next();
|
|
1055
|
-
|
|
749
|
+
return iteratorValue.done ? {
|
|
1056
750
|
done: !0,
|
|
1057
751
|
value: void 0
|
|
1058
|
-
}
|
|
1059
|
-
|
|
1060
|
-
value: liveNodeToLson(iteratorValue.value)
|
|
752
|
+
} : {
|
|
753
|
+
value: selfOrRegisterValue(iteratorValue.value)
|
|
1061
754
|
};
|
|
1062
755
|
}
|
|
1063
756
|
};
|
|
@@ -1067,12 +760,8 @@ class LiveMap extends AbstractCrdt {
|
|
|
1067
760
|
}
|
|
1068
761
|
}
|
|
1069
762
|
|
|
1070
|
-
function
|
|
1071
|
-
|
|
1072
|
-
}
|
|
1073
|
-
|
|
1074
|
-
function isJsonObject(data) {
|
|
1075
|
-
return null !== data && "object" == typeof data && !isJsonArray(data);
|
|
763
|
+
function assertNever(_value, errmsg) {
|
|
764
|
+
throw new Error(errmsg);
|
|
1076
765
|
}
|
|
1077
766
|
|
|
1078
767
|
function remove(array, item) {
|
|
@@ -1086,7 +775,7 @@ function compact(items) {
|
|
|
1086
775
|
return items.filter((item => null != item));
|
|
1087
776
|
}
|
|
1088
777
|
|
|
1089
|
-
function
|
|
778
|
+
function creationOpToLiveStructure(op) {
|
|
1090
779
|
switch (op.type) {
|
|
1091
780
|
case OpCode.CREATE_REGISTER:
|
|
1092
781
|
return new LiveRegister(op.data);
|
|
@@ -1099,14 +788,11 @@ function creationOpToLiveNode(op) {
|
|
|
1099
788
|
|
|
1100
789
|
case OpCode.CREATE_LIST:
|
|
1101
790
|
return new LiveList;
|
|
1102
|
-
|
|
1103
|
-
default:
|
|
1104
|
-
return assertNever(0, "Unknown creation Op");
|
|
1105
791
|
}
|
|
1106
792
|
}
|
|
1107
793
|
|
|
1108
794
|
function isSameNodeOrChildOf(node, parent) {
|
|
1109
|
-
return node === parent ||
|
|
795
|
+
return node === parent || !!node._parent && isSameNodeOrChildOf(node._parent, parent);
|
|
1110
796
|
}
|
|
1111
797
|
|
|
1112
798
|
function deserialize([id, crdt], parentToChildren, doc) {
|
|
@@ -1128,28 +814,18 @@ function deserialize([id, crdt], parentToChildren, doc) {
|
|
|
1128
814
|
}
|
|
1129
815
|
}
|
|
1130
816
|
|
|
1131
|
-
function
|
|
1132
|
-
return
|
|
1133
|
-
return value instanceof LiveMap;
|
|
1134
|
-
}(value) || isLiveObject(value) || function(value) {
|
|
1135
|
-
return value instanceof LiveRegister;
|
|
1136
|
-
}(value);
|
|
1137
|
-
}
|
|
1138
|
-
|
|
1139
|
-
function isLiveList(value) {
|
|
1140
|
-
return value instanceof LiveList;
|
|
817
|
+
function isCrdt(obj) {
|
|
818
|
+
return obj instanceof LiveObject || obj instanceof LiveMap || obj instanceof LiveList || obj instanceof LiveRegister;
|
|
1141
819
|
}
|
|
1142
820
|
|
|
1143
|
-
function
|
|
1144
|
-
return
|
|
821
|
+
function selfOrRegisterValue(obj) {
|
|
822
|
+
return obj instanceof LiveRegister ? obj.data : obj;
|
|
1145
823
|
}
|
|
1146
824
|
|
|
1147
|
-
function
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
function lsonToLiveNode(value) {
|
|
1152
|
-
return value instanceof LiveObject || value instanceof LiveMap || value instanceof LiveList ? value : new LiveRegister(value);
|
|
825
|
+
function selfOrRegister(obj) {
|
|
826
|
+
if (obj instanceof LiveObject || obj instanceof LiveMap || obj instanceof LiveList) return obj;
|
|
827
|
+
if (obj instanceof LiveRegister) throw new Error("Internal error. LiveRegister should not be created from selfOrRegister");
|
|
828
|
+
return new LiveRegister(obj);
|
|
1153
829
|
}
|
|
1154
830
|
|
|
1155
831
|
function getTreesDiffOperations(currentItems, newItems) {
|
|
@@ -1168,7 +844,7 @@ function getTreesDiffOperations(currentItems, newItems) {
|
|
|
1168
844
|
})), crdt.parentKey !== currentCrdt.parentKey && ops.push({
|
|
1169
845
|
type: OpCode.SET_PARENT_KEY,
|
|
1170
846
|
id: id,
|
|
1171
|
-
parentKey:
|
|
847
|
+
parentKey: crdt.parentKey
|
|
1172
848
|
}); else switch (crdt.type) {
|
|
1173
849
|
case CrdtType.REGISTER:
|
|
1174
850
|
ops.push({
|
|
@@ -1237,14 +913,11 @@ function mergeStorageUpdates(first, second) {
|
|
|
1237
913
|
|
|
1238
914
|
function isPlain(value) {
|
|
1239
915
|
const type = typeof value;
|
|
1240
|
-
return "undefined" === type || null === value || "string" === type || "boolean" === type || "number" === type || Array.isArray(value) ||
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
for (;null !== Object.getPrototypeOf(baseProto); ) baseProto = Object.getPrototypeOf(baseProto);
|
|
1246
|
-
return proto === baseProto;
|
|
1247
|
-
}(value);
|
|
916
|
+
return "undefined" === type || null === value || "string" === type || "boolean" === type || "number" === type || Array.isArray(value) || isPlainObject(value);
|
|
917
|
+
}
|
|
918
|
+
|
|
919
|
+
function isPlainObject(blob) {
|
|
920
|
+
return null !== blob && "object" == typeof blob && "[object Object]" === Object.prototype.toString.call(blob);
|
|
1248
921
|
}
|
|
1249
922
|
|
|
1250
923
|
function findNonSerializableValue(value, path = "") {
|
|
@@ -1303,16 +976,17 @@ class LiveObject extends AbstractCrdt {
|
|
|
1303
976
|
super(), this._propToLastUpdate = new Map;
|
|
1304
977
|
for (const key in obj) {
|
|
1305
978
|
const value = obj[key];
|
|
1306
|
-
|
|
979
|
+
value instanceof AbstractCrdt && value._setParentLink(this, key);
|
|
1307
980
|
}
|
|
1308
981
|
this._map = new Map(Object.entries(obj));
|
|
1309
982
|
}
|
|
1310
|
-
_serialize(parentId, parentKey, doc) {
|
|
983
|
+
_serialize(parentId, parentKey, doc, intent) {
|
|
1311
984
|
if (null == this._id) throw new Error("Cannot serialize item is not attached");
|
|
1312
985
|
const opId = null == doc ? void 0 : doc.generateOpId(), ops = [], op = void 0 !== parentId && void 0 !== parentKey ? {
|
|
1313
986
|
type: OpCode.CREATE_OBJECT,
|
|
1314
987
|
id: this._id,
|
|
1315
988
|
opId: opId,
|
|
989
|
+
intent: intent,
|
|
1316
990
|
parentId: parentId,
|
|
1317
991
|
parentKey: parentKey,
|
|
1318
992
|
data: {}
|
|
@@ -1320,10 +994,11 @@ class LiveObject extends AbstractCrdt {
|
|
|
1320
994
|
type: OpCode.CREATE_OBJECT,
|
|
1321
995
|
id: this._id,
|
|
1322
996
|
opId: opId,
|
|
997
|
+
intent: intent,
|
|
1323
998
|
data: {}
|
|
1324
999
|
};
|
|
1325
1000
|
ops.push(op);
|
|
1326
|
-
for (const [key, value] of this._map)
|
|
1001
|
+
for (const [key, value] of this._map) value instanceof AbstractCrdt ? ops.push(...value._serialize(this._id, key, doc)) : op.data[key] = value;
|
|
1327
1002
|
return ops;
|
|
1328
1003
|
}
|
|
1329
1004
|
static _deserialize([id, item], parentToChildren, doc) {
|
|
@@ -1331,41 +1006,43 @@ class LiveObject extends AbstractCrdt {
|
|
|
1331
1006
|
return liveObj._attach(id, doc), this._deserializeChildren(liveObj, parentToChildren, doc);
|
|
1332
1007
|
}
|
|
1333
1008
|
static _deserializeChildren(liveObj, parentToChildren, doc) {
|
|
1334
|
-
const children = parentToChildren.get(
|
|
1009
|
+
const children = parentToChildren.get(liveObj._id);
|
|
1335
1010
|
if (null == children) return liveObj;
|
|
1336
|
-
for (const
|
|
1337
|
-
const
|
|
1011
|
+
for (const entry of children) {
|
|
1012
|
+
const crdt = entry[1];
|
|
1013
|
+
if (null == crdt.parentKey) throw new Error("Tried to deserialize a crdt but it does not have a parentKey and is not the root");
|
|
1014
|
+
const child = deserialize(entry, parentToChildren, doc);
|
|
1338
1015
|
child._setParentLink(liveObj, crdt.parentKey), liveObj._map.set(crdt.parentKey, child);
|
|
1339
1016
|
}
|
|
1340
1017
|
return liveObj;
|
|
1341
1018
|
}
|
|
1342
1019
|
_attach(id, doc) {
|
|
1343
1020
|
super._attach(id, doc);
|
|
1344
|
-
for (const [_key, value] of this._map)
|
|
1021
|
+
for (const [_key, value] of this._map) value instanceof AbstractCrdt && value._attach(doc.generateId(), doc);
|
|
1345
1022
|
}
|
|
1346
|
-
_attachChild(op,
|
|
1023
|
+
_attachChild(op, isLocal) {
|
|
1347
1024
|
if (null == this._doc) throw new Error("Can't attach child if doc is not present");
|
|
1348
|
-
const {id: id,
|
|
1025
|
+
const {id: id, parentKey: parentKey, opId: opId} = op, key = parentKey, child = creationOpToLiveStructure(op);
|
|
1349
1026
|
if (void 0 !== this._doc.getItem(id)) return this._propToLastUpdate.get(key) === opId && this._propToLastUpdate.delete(key),
|
|
1350
1027
|
{
|
|
1351
1028
|
modified: !1
|
|
1352
1029
|
};
|
|
1353
|
-
if (
|
|
1030
|
+
if (isLocal) this._propToLastUpdate.set(key, opId); else if (void 0 !== this._propToLastUpdate.get(key)) return this._propToLastUpdate.get(key) === opId ? (this._propToLastUpdate.delete(key),
|
|
1354
1031
|
{
|
|
1355
1032
|
modified: !1
|
|
1356
1033
|
}) : {
|
|
1357
1034
|
modified: !1
|
|
1358
1035
|
};
|
|
1359
|
-
const
|
|
1036
|
+
const previousValue = this._map.get(key);
|
|
1360
1037
|
let reverse;
|
|
1361
|
-
return
|
|
1038
|
+
return isCrdt(previousValue) ? (reverse = previousValue._serialize(this._id, key),
|
|
1362
1039
|
previousValue._detach()) : reverse = void 0 === previousValue ? [ {
|
|
1363
1040
|
type: OpCode.DELETE_OBJECT_KEY,
|
|
1364
|
-
id:
|
|
1041
|
+
id: this._id,
|
|
1365
1042
|
key: key
|
|
1366
1043
|
} ] : [ {
|
|
1367
1044
|
type: OpCode.UPDATE_OBJECT,
|
|
1368
|
-
id:
|
|
1045
|
+
id: this._id,
|
|
1369
1046
|
data: {
|
|
1370
1047
|
[key]: previousValue
|
|
1371
1048
|
}
|
|
@@ -1385,7 +1062,7 @@ class LiveObject extends AbstractCrdt {
|
|
|
1385
1062
|
}
|
|
1386
1063
|
_detachChild(child) {
|
|
1387
1064
|
if (child) {
|
|
1388
|
-
const
|
|
1065
|
+
const reverse = child._serialize(this._id, child._parentKey, this._doc);
|
|
1389
1066
|
for (const [key, value] of this._map) value === child && this._map.delete(key);
|
|
1390
1067
|
child._detach();
|
|
1391
1068
|
return {
|
|
@@ -1393,7 +1070,7 @@ class LiveObject extends AbstractCrdt {
|
|
|
1393
1070
|
node: this,
|
|
1394
1071
|
type: "LiveObject",
|
|
1395
1072
|
updates: {
|
|
1396
|
-
[
|
|
1073
|
+
[child._parentKey]: {
|
|
1397
1074
|
type: "delete"
|
|
1398
1075
|
}
|
|
1399
1076
|
}
|
|
@@ -1405,20 +1082,24 @@ class LiveObject extends AbstractCrdt {
|
|
|
1405
1082
|
modified: !1
|
|
1406
1083
|
};
|
|
1407
1084
|
}
|
|
1085
|
+
_detachChildren() {
|
|
1086
|
+
for (const [key, value] of this._map) this._map.delete(key), value._detach();
|
|
1087
|
+
}
|
|
1408
1088
|
_detach() {
|
|
1409
1089
|
super._detach();
|
|
1410
|
-
for (const value of this._map.values())
|
|
1090
|
+
for (const value of this._map.values()) isCrdt(value) && value._detach();
|
|
1411
1091
|
}
|
|
1412
1092
|
_apply(op, isLocal) {
|
|
1413
1093
|
return op.type === OpCode.UPDATE_OBJECT ? this._applyUpdate(op, isLocal) : op.type === OpCode.DELETE_OBJECT_KEY ? this._applyDeleteObjectKey(op) : super._apply(op, isLocal);
|
|
1414
1094
|
}
|
|
1415
1095
|
_toSerializedCrdt() {
|
|
1096
|
+
var _a;
|
|
1416
1097
|
const data = {};
|
|
1417
|
-
for (const [key, value] of this._map)
|
|
1418
|
-
return
|
|
1098
|
+
for (const [key, value] of this._map) value instanceof AbstractCrdt == !1 && (data[key] = value);
|
|
1099
|
+
return void 0 !== (null === (_a = this._parent) || void 0 === _a ? void 0 : _a._id) && void 0 !== this._parentKey ? {
|
|
1419
1100
|
type: CrdtType.OBJECT,
|
|
1420
|
-
parentId: this.
|
|
1421
|
-
parentKey: this.
|
|
1101
|
+
parentId: this._parent._id,
|
|
1102
|
+
parentKey: this._parentKey,
|
|
1422
1103
|
data: data
|
|
1423
1104
|
} : {
|
|
1424
1105
|
type: CrdtType.OBJECT,
|
|
@@ -1427,23 +1108,24 @@ class LiveObject extends AbstractCrdt {
|
|
|
1427
1108
|
}
|
|
1428
1109
|
_applyUpdate(op, isLocal) {
|
|
1429
1110
|
let isModified = !1;
|
|
1430
|
-
const
|
|
1111
|
+
const reverse = [], reverseUpdate = {
|
|
1431
1112
|
type: OpCode.UPDATE_OBJECT,
|
|
1432
|
-
id:
|
|
1113
|
+
id: this._id,
|
|
1433
1114
|
data: {}
|
|
1434
1115
|
};
|
|
1435
1116
|
reverse.push(reverseUpdate);
|
|
1436
1117
|
for (const key in op.data) {
|
|
1437
1118
|
const oldValue = this._map.get(key);
|
|
1438
|
-
|
|
1119
|
+
oldValue instanceof AbstractCrdt ? (reverse.push(...oldValue._serialize(this._id, key)),
|
|
1120
|
+
oldValue._detach()) : void 0 !== oldValue ? reverseUpdate.data[key] = oldValue : void 0 === oldValue && reverse.push({
|
|
1439
1121
|
type: OpCode.DELETE_OBJECT_KEY,
|
|
1440
|
-
id:
|
|
1122
|
+
id: this._id,
|
|
1441
1123
|
key: key
|
|
1442
1124
|
});
|
|
1443
1125
|
}
|
|
1444
1126
|
const updateDelta = {};
|
|
1445
1127
|
for (const key in op.data) {
|
|
1446
|
-
if (isLocal) this._propToLastUpdate.set(key,
|
|
1128
|
+
if (isLocal) this._propToLastUpdate.set(key, op.opId); else {
|
|
1447
1129
|
if (null != this._propToLastUpdate.get(key)) {
|
|
1448
1130
|
if (this._propToLastUpdate.get(key) === op.opId) {
|
|
1449
1131
|
this._propToLastUpdate.delete(key);
|
|
@@ -1454,7 +1136,7 @@ class LiveObject extends AbstractCrdt {
|
|
|
1454
1136
|
isModified = !0;
|
|
1455
1137
|
}
|
|
1456
1138
|
const oldValue = this._map.get(key);
|
|
1457
|
-
|
|
1139
|
+
isCrdt(oldValue) && oldValue._detach(), isModified = !0, updateDelta[key] = {
|
|
1458
1140
|
type: "update"
|
|
1459
1141
|
}, this._map.set(key, op.data[key]);
|
|
1460
1142
|
}
|
|
@@ -1478,11 +1160,11 @@ class LiveObject extends AbstractCrdt {
|
|
|
1478
1160
|
if (void 0 !== this._propToLastUpdate.get(key)) return {
|
|
1479
1161
|
modified: !1
|
|
1480
1162
|
};
|
|
1481
|
-
const oldValue = this._map.get(key)
|
|
1163
|
+
const oldValue = this._map.get(key);
|
|
1482
1164
|
let reverse = [];
|
|
1483
|
-
return
|
|
1165
|
+
return isCrdt(oldValue) ? (reverse = oldValue._serialize(this._id, op.key), oldValue._detach()) : void 0 !== oldValue && (reverse = [ {
|
|
1484
1166
|
type: OpCode.UPDATE_OBJECT,
|
|
1485
|
-
id:
|
|
1167
|
+
id: this._id,
|
|
1486
1168
|
data: {
|
|
1487
1169
|
[key]: oldValue
|
|
1488
1170
|
}
|
|
@@ -1517,10 +1199,10 @@ class LiveObject extends AbstractCrdt {
|
|
|
1517
1199
|
delete(key) {
|
|
1518
1200
|
const keyAsString = key, oldValue = this._map.get(keyAsString);
|
|
1519
1201
|
if (void 0 === oldValue) return;
|
|
1520
|
-
if (null == this._doc || null == this._id) return
|
|
1202
|
+
if (null == this._doc || null == this._id) return oldValue instanceof AbstractCrdt && oldValue._detach(),
|
|
1521
1203
|
void this._map.delete(keyAsString);
|
|
1522
1204
|
let reverse;
|
|
1523
|
-
|
|
1205
|
+
oldValue instanceof AbstractCrdt ? (oldValue._detach(), reverse = oldValue._serialize(this._id, keyAsString)) : reverse = [ {
|
|
1524
1206
|
type: OpCode.UPDATE_OBJECT,
|
|
1525
1207
|
data: {
|
|
1526
1208
|
[keyAsString]: oldValue
|
|
@@ -1547,9 +1229,9 @@ class LiveObject extends AbstractCrdt {
|
|
|
1547
1229
|
if (null == this._doc || null == this._id) {
|
|
1548
1230
|
for (const key in overrides) {
|
|
1549
1231
|
const oldValue = this._map.get(key);
|
|
1550
|
-
|
|
1232
|
+
oldValue instanceof AbstractCrdt && oldValue._detach();
|
|
1551
1233
|
const newValue = overrides[key];
|
|
1552
|
-
|
|
1234
|
+
newValue instanceof AbstractCrdt && newValue._setParentLink(this, key), this._map.set(key, newValue);
|
|
1553
1235
|
}
|
|
1554
1236
|
return;
|
|
1555
1237
|
}
|
|
@@ -1560,17 +1242,17 @@ class LiveObject extends AbstractCrdt {
|
|
|
1560
1242
|
}, updateDelta = {};
|
|
1561
1243
|
for (const key in overrides) {
|
|
1562
1244
|
const oldValue = this._map.get(key);
|
|
1563
|
-
|
|
1245
|
+
oldValue instanceof AbstractCrdt ? (reverseOps.push(...oldValue._serialize(this._id, key)),
|
|
1564
1246
|
oldValue._detach()) : void 0 === oldValue ? reverseOps.push({
|
|
1565
1247
|
type: OpCode.DELETE_OBJECT_KEY,
|
|
1566
1248
|
id: this._id,
|
|
1567
1249
|
key: key
|
|
1568
1250
|
}) : reverseUpdateOp.data[key] = oldValue;
|
|
1569
1251
|
const newValue = overrides[key];
|
|
1570
|
-
if (
|
|
1252
|
+
if (newValue instanceof AbstractCrdt) {
|
|
1571
1253
|
newValue._setParentLink(this, key), newValue._attach(this._doc.generateId(), this._doc);
|
|
1572
1254
|
const newAttachChildOps = newValue._serialize(this._id, key, this._doc), createCrdtOp = newAttachChildOps.find((op => op.parentId === this._id));
|
|
1573
|
-
createCrdtOp && this._propToLastUpdate.set(key,
|
|
1255
|
+
createCrdtOp && this._propToLastUpdate.set(key, createCrdtOp.opId), ops.push(...newAttachChildOps);
|
|
1574
1256
|
} else updatedProps[key] = newValue, this._propToLastUpdate.set(key, opId);
|
|
1575
1257
|
this._map.set(key, newValue), updateDelta[key] = {
|
|
1576
1258
|
type: "update"
|
|
@@ -1592,4 +1274,4 @@ class LiveObject extends AbstractCrdt {
|
|
|
1592
1274
|
}
|
|
1593
1275
|
}
|
|
1594
1276
|
|
|
1595
|
-
export {
|
|
1277
|
+
export { AbstractCrdt as A, ClientMsgCode as C, LiveObject as L, OpCode as O, ServerMsgCode as S, WebsocketCloseCodes as W, isSameNodeOrChildOf as a, LiveList as b, isJsonArray as c, compact as d, b64decode as e, isJsonObject as f, getTreesDiffOperations as g, isRootCrdt as h, isTokenValid as i, deprecateIf as j, LiveMap as k, isPlainObject as l, mergeStorageUpdates as m, LiveRegister as n, findNonSerializableValue as o, deprecate as p, errorIf as q, remove as r, throwUsageError as s, tryParseJson as t, CrdtType as u, comparePosition as v, makePosition as w, isChildCrdt as x, assertNever as y, isJsonScalar as z };
|