@liveblocks/client 0.16.12 → 0.16.13

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