@liveblocks/client 0.16.10 → 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,45 +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 parseJson(rawMessage) {
74
- try {
75
- return JSON.parse(rawMessage);
76
- } catch (e) {
77
- return;
78
- }
79
- }
183
+ case "NoParent":
184
+ this._parent = NoParent;
185
+ break;
80
186
 
81
- function isJsonArray(data) {
82
- return Array.isArray(data);
83
- }
187
+ case "Orphaned":
188
+ this._parent = Orphaned(this.parent.oldKey);
189
+ break;
84
190
 
85
- function isJsonObject(data) {
86
- return null !== data && "object" == typeof data && !isJsonArray(data);
191
+ default:
192
+ assertNever(this.parent, "Unknown state");
193
+ }
194
+ this.__doc = void 0;
195
+ }
87
196
  }
88
197
 
89
198
  class LiveRegister extends AbstractCrdt {
@@ -97,28 +206,27 @@ class LiveRegister extends AbstractCrdt {
97
206
  const register = new LiveRegister(item.data);
98
207
  return register._attach(id, doc), register;
99
208
  }
100
- _serialize(parentId, parentKey, doc, intent) {
209
+ _serialize(parentId, parentKey, doc) {
101
210
  if (null == this._id || null == parentId || null == parentKey) throw new Error("Cannot serialize register if parentId or parentKey is undefined");
102
211
  return [ {
103
212
  type: OpCode.CREATE_REGISTER,
104
213
  opId: null == doc ? void 0 : doc.generateOpId(),
105
214
  id: this._id,
106
- intent: intent,
107
215
  parentId: parentId,
108
216
  parentKey: parentKey,
109
217
  data: this.data
110
218
  } ];
111
219
  }
112
220
  _toSerializedCrdt() {
113
- var _a;
221
+ if ("HasParent" !== this.parent.type) throw new Error("Cannot serialize LiveRegister if parent is missing");
114
222
  return {
115
223
  type: CrdtType.REGISTER,
116
- parentId: null === (_a = this._parent) || void 0 === _a ? void 0 : _a._id,
117
- parentKey: this._parentKey,
224
+ parentId: nn(this.parent.node._id, "Parent node expected to have ID"),
225
+ parentKey: this.parent.key,
118
226
  data: this.data
119
227
  };
120
228
  }
121
- _attachChild(_op, _isLocal) {
229
+ _attachChild(_op) {
122
230
  throw new Error("Method not implemented.");
123
231
  }
124
232
  _detachChild(_crdt) {
@@ -130,7 +238,7 @@ class LiveRegister extends AbstractCrdt {
130
238
  }
131
239
 
132
240
  function makePosition(before, after) {
133
- 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) {
134
242
  const result = [], beforeCodes = posCodes(before);
135
243
  for (let i = 0; i < beforeCodes.length; i++) {
136
244
  const code = beforeCodes[i];
@@ -144,7 +252,7 @@ function makePosition(before, after) {
144
252
  }
145
253
  }
146
254
  return pos(result);
147
- }(before) : null == before && null != after ? function(after) {
255
+ }(before) : null != after ? function(after) {
148
256
  const result = [], afterCodes = posCodes(after);
149
257
  for (let i = 0; i < afterCodes.length; i++) {
150
258
  const code = afterCodes[i];
@@ -158,7 +266,7 @@ function makePosition(before, after) {
158
266
  }
159
267
  }
160
268
  return pos(result);
161
- }(after) : pos(makePositionFromCodes(posCodes(before), posCodes(after)));
269
+ }(after) : pos([ 33 ]);
162
270
  }
163
271
 
164
272
  function makePositionFromCodes(before, after) {
@@ -204,114 +312,243 @@ function comparePosition(posA, posB) {
204
312
  class LiveList extends AbstractCrdt {
205
313
  constructor(items = []) {
206
314
  let position;
207
- super(), this._items = [];
315
+ super(), this._items = [], this._implicitlyDeletedItems = new Set;
208
316
  for (let i = 0; i < items.length; i++) {
209
- const newPosition = makePosition(position), item = selfOrRegister(items[i]);
210
- 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;
211
319
  }
212
320
  }
213
321
  static _deserialize([id], parentToChildren, doc) {
214
- const list = new LiveList([]);
322
+ const list = new LiveList;
215
323
  list._attach(id, doc);
216
324
  const children = parentToChildren.get(id);
217
325
  if (null == children) return list;
218
- for (const entry of children) {
219
- const child = deserialize(entry, parentToChildren, doc);
220
- child._setParentLink(list, entry[1].parentKey), list._items.push([ child, entry[1].parentKey ]),
221
- 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);
222
329
  }
223
330
  return list;
224
331
  }
225
- _serialize(parentId, parentKey, doc, intent) {
332
+ _serialize(parentId, parentKey, doc) {
226
333
  if (null == this._id) throw new Error("Cannot serialize item is not attached");
227
- if (null == parentId || null == parentKey) throw new Error("Cannot serialize list if parentId or parentKey is undefined");
228
334
  const ops = [], op = {
229
335
  id: this._id,
230
336
  opId: null == doc ? void 0 : doc.generateOpId(),
231
- intent: intent,
232
337
  type: OpCode.CREATE_LIST,
233
338
  parentId: parentId,
234
339
  parentKey: parentKey
235
340
  };
236
341
  ops.push(op);
237
- 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));
238
343
  return ops;
239
344
  }
240
345
  _indexOfPosition(position) {
241
- return this._items.findIndex((item => item[1] === position));
346
+ return this._items.findIndex((item => item._getParentKeyOrThrow() === position));
242
347
  }
243
348
  _attach(id, doc) {
244
349
  super._attach(id, doc);
245
- for (const [item] of this._items) item._attach(doc.generateId(), doc);
350
+ for (const item of this._items) item._attach(doc.generateId(), doc);
246
351
  }
247
352
  _detach() {
248
353
  super._detach();
249
- for (const [value] of this._items) value._detach();
354
+ for (const item of this._items) item._detach();
250
355
  }
251
- _attachChild(op, isLocal) {
252
- var _a;
356
+ _applyRemoteSet(op) {
253
357
  if (null == this._doc) throw new Error("Can't attach child if doc is not present");
254
- const {id: id, parentKey: parentKey, intent: intent} = op, key = parentKey, child = creationOpToLiveStructure(op);
255
- if (void 0 !== this._doc.getItem(id)) return {
256
- modified: !1
257
- };
358
+ const {id: id, parentKey: key} = op, child = creationOpToLiveNode(op);
258
359
  child._attach(id, this._doc), child._setParentLink(this, key);
259
- const index = this._items.findIndex((entry => entry[1] === key));
260
- let newKey = key;
261
- if (-1 !== index) {
262
- if ("set" === intent) {
263
- const existingItem = this._items[index][0];
264
- existingItem._detach();
265
- const storageUpdate = {
266
- node: this,
267
- type: "LiveList",
268
- updates: [ {
269
- index: index,
270
- type: "set",
271
- item: child instanceof LiveRegister ? child.data : child
272
- } ]
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: []
273
424
  };
274
- return this._items[index][0] = child, {
275
- modified: storageUpdate,
276
- reverse: existingItem._serialize(this._id, key, this._doc, "set")
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) {
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);
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: []
277
461
  };
278
462
  }
279
- if (isLocal) {
280
- const before = this._items[index] ? this._items[index][1] : void 0, after = this._items[index + 1] ? this._items[index + 1][1] : void 0;
281
- newKey = makePosition(before, after), child._setParentLink(this, newKey);
282
- } else this._items[index][1] = makePosition(key, null === (_a = this._items[index + 1]) || void 0 === _a ? void 0 : _a[1]);
283
463
  }
284
- this._items.push([ child, newKey ]), this._items.sort(((itemA, itemB) => comparePosition(itemA[1], itemB[1])));
285
- const newIndex = this._items.findIndex((entry => entry[1] === newKey));
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);
286
498
  return {
499
+ modified: makeUpdate(this, [ insertDelta(this._indexOfPosition(newKey), child) ]),
287
500
  reverse: [ {
288
501
  type: OpCode.DELETE_CRDT,
289
502
  id: id
290
- } ],
291
- modified: {
292
- node: this,
293
- type: "LiveList",
294
- updates: [ {
295
- index: newIndex,
296
- type: "insert",
297
- item: child instanceof LiveRegister ? child.data : child
298
- } ]
299
- }
503
+ } ]
300
504
  };
301
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
+ }
302
547
  _detachChild(child) {
303
548
  if (child) {
304
- const reverse = child._serialize(this._id, child._parentKey, this._doc), indexToDelete = this._items.findIndex((item => item[0] === child));
305
- this._items.splice(indexToDelete, 1), child._detach();
306
- return {
307
- modified: {
308
- node: this,
309
- type: "LiveList",
310
- updates: [ {
311
- index: indexToDelete,
312
- type: "delete"
313
- } ]
314
- },
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) ]),
315
552
  reverse: reverse
316
553
  };
317
554
  }
@@ -319,41 +556,100 @@ class LiveList extends AbstractCrdt {
319
556
  modified: !1
320
557
  };
321
558
  }
322
- _setChildKey(key, child, previousKey) {
559
+ _applySetChildKeyRemote(newKey, child) {
323
560
  var _a;
324
- child._setParentLink(this, key);
325
- const previousIndex = this._items.findIndex((entry => entry[0]._id === child._id)), index = this._items.findIndex((entry => entry[1] === key));
326
- -1 !== index && (this._items[index][1] = makePosition(key, null === (_a = this._items[index + 1]) || void 0 === _a ? void 0 : _a[1]));
327
- const item = this._items.find((item => item[0] === child));
328
- item && (item[1] = key), this._items.sort(((itemA, itemB) => comparePosition(itemA[1], itemB[1])));
329
- const newIndex = this._items.findIndex((entry => entry[0]._id === child._id));
330
- return {
331
- modified: {
332
- node: this,
333
- type: "LiveList",
334
- updates: newIndex === previousIndex ? [] : [ {
335
- index: newIndex,
336
- item: child instanceof LiveRegister ? child.data : child,
337
- previousIndex: previousIndex,
338
- type: "move"
339
- } ]
340
- },
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) ]),
341
634
  reverse: [ {
342
635
  type: OpCode.SET_PARENT_KEY,
343
- id: null == item ? void 0 : item[0]._id,
636
+ id: nn(child._id),
344
637
  parentKey: previousKey
345
638
  } ]
346
639
  };
347
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
+ }
348
644
  _apply(op, isLocal) {
349
645
  return super._apply(op, isLocal);
350
646
  }
351
647
  _toSerializedCrdt() {
352
- var _a;
648
+ if ("HasParent" !== this.parent.type) throw new Error("Cannot serialize LiveList if parent is missing");
353
649
  return {
354
650
  type: CrdtType.LIST,
355
- parentId: null === (_a = this._parent) || void 0 === _a ? void 0 : _a._id,
356
- parentKey: this._parentKey
651
+ parentId: nn(this.parent.node._id, "Parent node expected to have ID"),
652
+ parentKey: this.parent.key
357
653
  };
358
654
  }
359
655
  get length() {
@@ -364,25 +660,14 @@ class LiveList extends AbstractCrdt {
364
660
  }
365
661
  insert(element, index) {
366
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}`);
367
- 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);
368
- value._setParentLink(this, position), this._items.push([ value, position ]), this._items.sort(((itemA, itemB) => comparePosition(itemA[1], itemB[1])));
369
- const newIndex = this._items.findIndex((entry => entry[1] === position));
370
- 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) {
371
666
  const id = this._doc.generateId();
372
- value._attach(id, this._doc);
373
- const storageUpdates = new Map;
374
- storageUpdates.set(this._id, {
375
- node: this,
376
- type: "LiveList",
377
- updates: [ {
378
- index: newIndex,
379
- item: value instanceof LiveRegister ? value.data : value,
380
- type: "insert"
381
- } ]
382
- }), 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), [ {
383
668
  type: OpCode.DELETE_CRDT,
384
669
  id: id
385
- } ], storageUpdates);
670
+ } ], new Map([ [ this._id, makeUpdate(this, [ insertDelta(index, value) ]) ] ]));
386
671
  }
387
672
  }
388
673
  move(index, targetIndex) {
@@ -391,31 +676,20 @@ class LiveList extends AbstractCrdt {
391
676
  if (index < 0) throw new Error("index cannot be less than 0");
392
677
  if (index >= this._items.length) throw new Error("index cannot be greater or equal than the list length");
393
678
  let beforePosition = null, afterPosition = null;
394
- index < targetIndex ? (afterPosition = targetIndex === this._items.length - 1 ? void 0 : this._items[targetIndex + 1][1],
395
- beforePosition = this._items[targetIndex][1]) : (afterPosition = this._items[targetIndex][1],
396
- beforePosition = 0 === targetIndex ? void 0 : this._items[targetIndex - 1][1]);
397
- const position = makePosition(beforePosition, afterPosition), item = this._items[index], previousPosition = item[1];
398
- item[1] = position, item[0]._setParentLink(this, position), this._items.sort(((itemA, itemB) => comparePosition(itemA[1], itemB[1])));
399
- const newIndex = this._items.findIndex((entry => entry[1] === position));
400
- if (this._doc && this._id) {
401
- const storageUpdates = new Map;
402
- storageUpdates.set(this._id, {
403
- node: this,
404
- type: "LiveList",
405
- updates: [ {
406
- index: newIndex,
407
- previousIndex: index,
408
- item: item[0],
409
- type: "move"
410
- } ]
411
- }), 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([ {
412
686
  type: OpCode.SET_PARENT_KEY,
413
- id: item[0]._id,
687
+ id: nn(item._id),
414
688
  opId: this._doc.generateOpId(),
415
689
  parentKey: position
416
690
  } ], [ {
417
691
  type: OpCode.SET_PARENT_KEY,
418
- id: item[0]._id,
692
+ id: nn(item._id),
419
693
  parentKey: previousPosition
420
694
  } ], storageUpdates);
421
695
  }
@@ -423,22 +697,15 @@ class LiveList extends AbstractCrdt {
423
697
  delete(index) {
424
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}`);
425
699
  const item = this._items[index];
426
- if (item[0]._detach(), this._items.splice(index, 1), this._doc) {
427
- const childRecordId = item[0]._id;
700
+ if (item._detach(), this._items.splice(index, 1), this._doc) {
701
+ const childRecordId = item._id;
428
702
  if (childRecordId) {
429
703
  const storageUpdates = new Map;
430
- storageUpdates.set(this._id, {
431
- node: this,
432
- type: "LiveList",
433
- updates: [ {
434
- index: index,
435
- type: "delete"
436
- } ]
437
- }), this._doc.dispatch([ {
704
+ storageUpdates.set(nn(this._id), makeUpdate(this, [ deleteDelta(index) ])), this._doc.dispatch([ {
438
705
  id: childRecordId,
439
706
  opId: this._doc.generateOpId(),
440
707
  type: OpCode.DELETE_CRDT
441
- } ], item[0]._serialize(this._id, item[1]), storageUpdates);
708
+ } ], item._serialize(nn(this._id), item._getParentKeyOrThrow()), storageUpdates);
442
709
  }
443
710
  }
444
711
  }
@@ -447,50 +714,41 @@ class LiveList extends AbstractCrdt {
447
714
  const ops = [], reverseOps = [], updateDelta = [];
448
715
  let i = 0;
449
716
  for (const item of this._items) {
450
- item[0]._detach();
451
- const childId = item[0]._id;
717
+ item._detach();
718
+ const childId = item._id;
452
719
  childId && (ops.push({
720
+ type: OpCode.DELETE_CRDT,
453
721
  id: childId,
454
- type: OpCode.DELETE_CRDT
455
- }), reverseOps.push(...item[0]._serialize(this._id, item[1])), updateDelta.push({
456
- index: i,
457
- type: "delete"
458
- })), i++;
722
+ opId: this._doc.generateOpId()
723
+ }), reverseOps.push(...item._serialize(nn(this._id), item._getParentKeyOrThrow())),
724
+ updateDelta.push(deleteDelta(i))), i++;
459
725
  }
460
726
  this._items = [];
461
727
  const storageUpdates = new Map;
462
- storageUpdates.set(this._id, {
463
- node: this,
464
- type: "LiveList",
465
- updates: updateDelta
466
- }), this._doc.dispatch(ops, reverseOps, storageUpdates);
728
+ storageUpdates.set(nn(this._id), makeUpdate(this, updateDelta)), this._doc.dispatch(ops, reverseOps, storageUpdates);
467
729
  } else {
468
- for (const item of this._items) item[0]._detach();
730
+ for (const item of this._items) item._detach();
469
731
  this._items = [];
470
732
  }
471
733
  }
472
734
  set(index, item) {
473
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}`);
474
- const [existingItem, position] = this._items[index];
736
+ const existingItem = this._items[index], position = existingItem._getParentKeyOrThrow(), existingId = existingItem._id;
475
737
  existingItem._detach();
476
- const value = selfOrRegister(item);
477
- 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) {
478
740
  const id = this._doc.generateId();
479
741
  value._attach(id, this._doc);
480
742
  const storageUpdates = new Map;
481
- storageUpdates.set(this._id, {
482
- node: this,
483
- type: "LiveList",
484
- updates: [ {
485
- index: index,
486
- item: value instanceof LiveRegister ? value.data : value,
487
- type: "set"
488
- } ]
489
- }), 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);
490
748
  }
491
749
  }
492
750
  toArray() {
493
- return this._items.map((entry => selfOrRegisterValue(entry[0])));
751
+ return this._items.map((entry => liveNodeToLson(entry)));
494
752
  }
495
753
  every(predicate) {
496
754
  return this.toArray().every(predicate);
@@ -508,7 +766,7 @@ class LiveList extends AbstractCrdt {
508
766
  return this.toArray().forEach(callbackfn);
509
767
  }
510
768
  get(index) {
511
- 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]);
512
770
  }
513
771
  indexOf(searchElement, fromIndex) {
514
772
  return this.toArray().indexOf(searchElement, fromIndex);
@@ -517,7 +775,7 @@ class LiveList extends AbstractCrdt {
517
775
  return this.toArray().lastIndexOf(searchElement, fromIndex);
518
776
  }
519
777
  map(callback) {
520
- return this._items.map(((entry, i) => callback(selfOrRegisterValue(entry[0]), i)));
778
+ return this._items.map(((entry, i) => callback(liveNodeToLson(entry), i)));
521
779
  }
522
780
  some(predicate) {
523
781
  return this.toArray().some(predicate);
@@ -525,6 +783,20 @@ class LiveList extends AbstractCrdt {
525
783
  [Symbol.iterator]() {
526
784
  return new LiveListIterator(this._items);
527
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
+ }
528
800
  }
529
801
 
530
802
  class LiveListIterator {
@@ -536,57 +808,85 @@ class LiveListIterator {
536
808
  }
537
809
  next() {
538
810
  const result = this._innerIterator.next();
539
- return result.done ? {
811
+ if (result.done) return {
540
812
  done: !0,
541
813
  value: void 0
542
- } : {
543
- value: selfOrRegisterValue(result.value[0])
814
+ };
815
+ return {
816
+ value: liveNodeToLson(result.value)
544
817
  };
545
818
  }
546
819
  }
547
820
 
548
- const _emittedDeprecationWarnings = new Set;
821
+ function makeUpdate(liveList, deltaUpdates) {
822
+ return {
823
+ node: liveList,
824
+ type: "LiveList",
825
+ updates: deltaUpdates
826
+ };
827
+ }
549
828
 
550
- function deprecate(message, key = message) {
551
- "production" !== process.env.NODE_ENV && (_emittedDeprecationWarnings.has(key) || (_emittedDeprecationWarnings.add(key),
552
- 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
+ };
553
835
  }
554
836
 
555
- function deprecateIf(condition, message, key = message) {
556
- "production" !== process.env.NODE_ENV && condition && deprecate(message, key);
837
+ function deleteDelta(index) {
838
+ return {
839
+ index: index,
840
+ type: "delete"
841
+ };
557
842
  }
558
843
 
559
- function throwUsageError(message) {
560
- if ("production" !== process.env.NODE_ENV) {
561
- const usageError = new Error(message);
562
- throw usageError.name = "Usage error", usageError;
563
- }
844
+ function insertDelta(index, item) {
845
+ return {
846
+ index: index,
847
+ type: "insert",
848
+ item: item instanceof LiveRegister ? item.data : item
849
+ };
564
850
  }
565
851
 
566
- function errorIf(condition, message) {
567
- "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;
568
870
  }
569
871
 
570
872
  class LiveMap extends AbstractCrdt {
571
873
  constructor(entries) {
572
- 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([])`."),
573
875
  entries) {
574
876
  const mappedEntries = [];
575
877
  for (const entry of entries) {
576
- const value = selfOrRegister(entry[1]);
878
+ const value = lsonToLiveNode(entry[1]);
577
879
  value._setParentLink(this, entry[0]), mappedEntries.push([ entry[0], value ]);
578
880
  }
579
881
  this._map = new Map(mappedEntries);
580
882
  } else this._map = new Map;
581
883
  }
582
- _serialize(parentId, parentKey, doc, intent) {
884
+ _serialize(parentId, parentKey, doc) {
583
885
  if (null == this._id) throw new Error("Cannot serialize item is not attached");
584
- if (null == parentId || null == parentKey) throw new Error("Cannot serialize map if parentId or parentKey is undefined");
585
886
  const ops = [], op = {
586
887
  id: this._id,
587
888
  opId: null == doc ? void 0 : doc.generateOpId(),
588
889
  type: OpCode.CREATE_MAP,
589
- intent: intent,
590
890
  parentId: parentId,
591
891
  parentKey: parentKey
592
892
  };
@@ -599,30 +899,32 @@ class LiveMap extends AbstractCrdt {
599
899
  map._attach(id, doc);
600
900
  const children = parentToChildren.get(id);
601
901
  if (null == children) return map;
602
- for (const entry of children) {
603
- const crdt = entry[1];
604
- if (null == crdt.parentKey) throw new Error("Tried to deserialize a crdt but it does not have a parentKey and is not the root");
605
- const child = deserialize(entry, parentToChildren, doc);
902
+ for (const [id, crdt] of children) {
903
+ const child = deserialize([ id, crdt ], parentToChildren, doc);
606
904
  child._setParentLink(map, crdt.parentKey), map._map.set(crdt.parentKey, child);
607
905
  }
608
906
  return map;
609
907
  }
610
908
  _attach(id, doc) {
611
909
  super._attach(id, doc);
612
- 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);
613
911
  }
614
- _attachChild(op, _isLocal) {
912
+ _attachChild(op) {
615
913
  if (null == this._doc) throw new Error("Can't attach child if doc is not present");
616
- const {id: id, parentKey: parentKey} = op, key = parentKey, child = creationOpToLiveStructure(op);
914
+ const {id: id, parentKey: key} = op, child = creationOpToLiveNode(op);
617
915
  if (void 0 !== this._doc.getItem(id)) return {
618
916
  modified: !1
619
917
  };
620
918
  const previousValue = this._map.get(key);
621
919
  let reverse;
622
- 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 = [ {
623
924
  type: OpCode.DELETE_CRDT,
624
925
  id: id
625
- } ], 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),
626
928
  {
627
929
  modified: {
628
930
  node: this,
@@ -641,7 +943,7 @@ class LiveMap extends AbstractCrdt {
641
943
  for (const item of this._map.values()) item._detach();
642
944
  }
643
945
  _detachChild(child) {
644
- 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);
645
947
  for (const [key, value] of this._map) value === child && this._map.delete(key);
646
948
  child._detach();
647
949
  return {
@@ -649,7 +951,7 @@ class LiveMap extends AbstractCrdt {
649
951
  node: this,
650
952
  type: "LiveMap",
651
953
  updates: {
652
- [child._parentKey]: {
954
+ [parentKey]: {
653
955
  type: "delete"
654
956
  }
655
957
  }
@@ -658,21 +960,21 @@ class LiveMap extends AbstractCrdt {
658
960
  };
659
961
  }
660
962
  _toSerializedCrdt() {
661
- var _a;
963
+ if ("HasParent" !== this.parent.type) throw new Error("Cannot serialize LiveMap if parent is missing");
662
964
  return {
663
965
  type: CrdtType.MAP,
664
- parentId: null === (_a = this._parent) || void 0 === _a ? void 0 : _a._id,
665
- parentKey: this._parentKey
966
+ parentId: nn(this.parent.node._id, "Parent node expected to have ID"),
967
+ parentKey: this.parent.key
666
968
  };
667
969
  }
668
970
  get(key) {
669
971
  const value = this._map.get(key);
670
- if (null != value) return selfOrRegisterValue(value);
972
+ if (null != value) return liveNodeToLson(value);
671
973
  }
672
974
  set(key, value) {
673
975
  const oldValue = this._map.get(key);
674
976
  oldValue && oldValue._detach();
675
- const item = selfOrRegister(value);
977
+ const item = lsonToLiveNode(value);
676
978
  if (item._setParentLink(this, key), this._map.set(key, item), this._doc && this._id) {
677
979
  const id = this._doc.generateId();
678
980
  item._attach(id, this._doc);
@@ -701,8 +1003,8 @@ class LiveMap extends AbstractCrdt {
701
1003
  const item = this._map.get(key);
702
1004
  if (null == item) return !1;
703
1005
  if (item._detach(), this._map.delete(key), this._doc && item._id) {
704
- const storageUpdates = new Map;
705
- storageUpdates.set(this._id, {
1006
+ const thisId = nn(this._id), storageUpdates = new Map;
1007
+ storageUpdates.set(thisId, {
706
1008
  node: this,
707
1009
  type: "LiveMap",
708
1010
  updates: {
@@ -714,14 +1016,14 @@ class LiveMap extends AbstractCrdt {
714
1016
  type: OpCode.DELETE_CRDT,
715
1017
  id: item._id,
716
1018
  opId: this._doc.generateOpId()
717
- } ], item._serialize(this._id, key), storageUpdates);
1019
+ } ], item._serialize(thisId, key), storageUpdates);
718
1020
  }
719
1021
  return !0;
720
1022
  }
721
1023
  entries() {
722
1024
  const innerIterator = this._map.entries();
723
1025
  return {
724
- [Symbol.iterator]: function() {
1026
+ [Symbol.iterator]() {
725
1027
  return this;
726
1028
  },
727
1029
  next() {
@@ -731,7 +1033,7 @@ class LiveMap extends AbstractCrdt {
731
1033
  value: void 0
732
1034
  };
733
1035
  return {
734
- value: [ iteratorValue.value[0], selfOrRegisterValue(iteratorValue.value[1]) ]
1036
+ value: [ iteratorValue.value[0], liveNodeToLson(iteratorValue.value[1]) ]
735
1037
  };
736
1038
  }
737
1039
  };
@@ -745,16 +1047,17 @@ class LiveMap extends AbstractCrdt {
745
1047
  values() {
746
1048
  const innerIterator = this._map.values();
747
1049
  return {
748
- [Symbol.iterator]: function() {
1050
+ [Symbol.iterator]() {
749
1051
  return this;
750
1052
  },
751
1053
  next() {
752
1054
  const iteratorValue = innerIterator.next();
753
- return iteratorValue.done ? {
1055
+ if (iteratorValue.done) return {
754
1056
  done: !0,
755
1057
  value: void 0
756
- } : {
757
- value: selfOrRegisterValue(iteratorValue.value)
1058
+ };
1059
+ return {
1060
+ value: liveNodeToLson(iteratorValue.value)
758
1061
  };
759
1062
  }
760
1063
  };
@@ -764,8 +1067,12 @@ class LiveMap extends AbstractCrdt {
764
1067
  }
765
1068
  }
766
1069
 
767
- function assertNever(_value, errmsg) {
768
- 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);
769
1076
  }
770
1077
 
771
1078
  function remove(array, item) {
@@ -779,7 +1086,7 @@ function compact(items) {
779
1086
  return items.filter((item => null != item));
780
1087
  }
781
1088
 
782
- function creationOpToLiveStructure(op) {
1089
+ function creationOpToLiveNode(op) {
783
1090
  switch (op.type) {
784
1091
  case OpCode.CREATE_REGISTER:
785
1092
  return new LiveRegister(op.data);
@@ -792,11 +1099,14 @@ function creationOpToLiveStructure(op) {
792
1099
 
793
1100
  case OpCode.CREATE_LIST:
794
1101
  return new LiveList;
1102
+
1103
+ default:
1104
+ return assertNever(0, "Unknown creation Op");
795
1105
  }
796
1106
  }
797
1107
 
798
1108
  function isSameNodeOrChildOf(node, parent) {
799
- return node === parent || !!node._parent && isSameNodeOrChildOf(node._parent, parent);
1109
+ return node === parent || "HasParent" === node.parent.type && isSameNodeOrChildOf(node.parent.node, parent);
800
1110
  }
801
1111
 
802
1112
  function deserialize([id, crdt], parentToChildren, doc) {
@@ -818,18 +1128,28 @@ function deserialize([id, crdt], parentToChildren, doc) {
818
1128
  }
819
1129
  }
820
1130
 
821
- function isCrdt(obj) {
822
- 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;
823
1141
  }
824
1142
 
825
- function selfOrRegisterValue(obj) {
826
- return obj instanceof LiveRegister ? obj.data : obj;
1143
+ function isLiveObject(value) {
1144
+ return value instanceof LiveObject;
827
1145
  }
828
1146
 
829
- function selfOrRegister(obj) {
830
- if (obj instanceof LiveObject || obj instanceof LiveMap || obj instanceof LiveList) return obj;
831
- if (obj instanceof LiveRegister) throw new Error("Internal error. LiveRegister should not be created from selfOrRegister");
832
- return new LiveRegister(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");
1149
+ }
1150
+
1151
+ function lsonToLiveNode(value) {
1152
+ return value instanceof LiveObject || value instanceof LiveMap || value instanceof LiveList ? value : new LiveRegister(value);
833
1153
  }
834
1154
 
835
1155
  function getTreesDiffOperations(currentItems, newItems) {
@@ -848,7 +1168,7 @@ function getTreesDiffOperations(currentItems, newItems) {
848
1168
  })), crdt.parentKey !== currentCrdt.parentKey && ops.push({
849
1169
  type: OpCode.SET_PARENT_KEY,
850
1170
  id: id,
851
- parentKey: crdt.parentKey
1171
+ parentKey: nn(crdt.parentKey, "Parent key must not be missing")
852
1172
  }); else switch (crdt.type) {
853
1173
  case CrdtType.REGISTER:
854
1174
  ops.push({
@@ -950,7 +1270,7 @@ function findNonSerializableValue(value, path = "") {
950
1270
  function isTokenValid(token) {
951
1271
  const tokenParts = token.split(".");
952
1272
  if (3 !== tokenParts.length) return !1;
953
- const data = parseJson(atob(tokenParts[1]));
1273
+ const data = tryParseJson(atob(tokenParts[1]));
954
1274
  if (void 0 === data || !isJsonObject(data) || "number" != typeof data.exp) return !1;
955
1275
  return !(Date.now() / 1e3 > data.exp - 300);
956
1276
  }
@@ -959,22 +1279,40 @@ function entries(obj) {
959
1279
  return Object.entries(obj);
960
1280
  }
961
1281
 
1282
+ function tryParseJson(rawMessage) {
1283
+ try {
1284
+ return JSON.parse(rawMessage);
1285
+ } catch (e) {
1286
+ return;
1287
+ }
1288
+ }
1289
+
1290
+ function b64decode(b64value) {
1291
+ try {
1292
+ const formattedValue = b64value.replace(/-/g, "+").replace(/_/g, "/");
1293
+ return decodeURIComponent(atob(formattedValue).split("").map((function(c) {
1294
+ return "%" + ("00" + c.charCodeAt(0).toString(16)).slice(-2);
1295
+ })).join(""));
1296
+ } catch (err) {
1297
+ return atob(b64value);
1298
+ }
1299
+ }
1300
+
962
1301
  class LiveObject extends AbstractCrdt {
963
1302
  constructor(obj = {}) {
964
1303
  super(), this._propToLastUpdate = new Map;
965
1304
  for (const key in obj) {
966
1305
  const value = obj[key];
967
- value instanceof AbstractCrdt && value._setParentLink(this, key);
1306
+ isLiveNode(value) && value._setParentLink(this, key);
968
1307
  }
969
1308
  this._map = new Map(Object.entries(obj));
970
1309
  }
971
- _serialize(parentId, parentKey, doc, intent) {
1310
+ _serialize(parentId, parentKey, doc) {
972
1311
  if (null == this._id) throw new Error("Cannot serialize item is not attached");
973
1312
  const opId = null == doc ? void 0 : doc.generateOpId(), ops = [], op = void 0 !== parentId && void 0 !== parentKey ? {
974
1313
  type: OpCode.CREATE_OBJECT,
975
1314
  id: this._id,
976
1315
  opId: opId,
977
- intent: intent,
978
1316
  parentId: parentId,
979
1317
  parentKey: parentKey,
980
1318
  data: {}
@@ -982,11 +1320,10 @@ class LiveObject extends AbstractCrdt {
982
1320
  type: OpCode.CREATE_OBJECT,
983
1321
  id: this._id,
984
1322
  opId: opId,
985
- intent: intent,
986
1323
  data: {}
987
1324
  };
988
1325
  ops.push(op);
989
- 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;
990
1327
  return ops;
991
1328
  }
992
1329
  static _deserialize([id, item], parentToChildren, doc) {
@@ -994,43 +1331,41 @@ class LiveObject extends AbstractCrdt {
994
1331
  return liveObj._attach(id, doc), this._deserializeChildren(liveObj, parentToChildren, doc);
995
1332
  }
996
1333
  static _deserializeChildren(liveObj, parentToChildren, doc) {
997
- const children = parentToChildren.get(liveObj._id);
1334
+ const children = parentToChildren.get(nn(liveObj._id));
998
1335
  if (null == children) return liveObj;
999
- for (const entry of children) {
1000
- const crdt = entry[1];
1001
- if (null == crdt.parentKey) throw new Error("Tried to deserialize a crdt but it does not have a parentKey and is not the root");
1002
- const child = deserialize(entry, parentToChildren, doc);
1336
+ for (const [id, crdt] of children) {
1337
+ const child = deserialize([ id, crdt ], parentToChildren, doc);
1003
1338
  child._setParentLink(liveObj, crdt.parentKey), liveObj._map.set(crdt.parentKey, child);
1004
1339
  }
1005
1340
  return liveObj;
1006
1341
  }
1007
1342
  _attach(id, doc) {
1008
1343
  super._attach(id, doc);
1009
- 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);
1010
1345
  }
1011
- _attachChild(op, isLocal) {
1346
+ _attachChild(op, source) {
1012
1347
  if (null == this._doc) throw new Error("Can't attach child if doc is not present");
1013
- 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);
1014
1349
  if (void 0 !== this._doc.getItem(id)) return this._propToLastUpdate.get(key) === opId && this._propToLastUpdate.delete(key),
1015
1350
  {
1016
1351
  modified: !1
1017
1352
  };
1018
- 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),
1019
1354
  {
1020
1355
  modified: !1
1021
1356
  }) : {
1022
1357
  modified: !1
1023
1358
  };
1024
- const previousValue = this._map.get(key);
1359
+ const thisId = nn(this._id), previousValue = this._map.get(key);
1025
1360
  let reverse;
1026
- return isCrdt(previousValue) ? (reverse = previousValue._serialize(this._id, key),
1361
+ return isLiveNode(previousValue) ? (reverse = previousValue._serialize(thisId, key),
1027
1362
  previousValue._detach()) : reverse = void 0 === previousValue ? [ {
1028
1363
  type: OpCode.DELETE_OBJECT_KEY,
1029
- id: this._id,
1364
+ id: thisId,
1030
1365
  key: key
1031
1366
  } ] : [ {
1032
1367
  type: OpCode.UPDATE_OBJECT,
1033
- id: this._id,
1368
+ id: thisId,
1034
1369
  data: {
1035
1370
  [key]: previousValue
1036
1371
  }
@@ -1050,7 +1385,7 @@ class LiveObject extends AbstractCrdt {
1050
1385
  }
1051
1386
  _detachChild(child) {
1052
1387
  if (child) {
1053
- 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);
1054
1389
  for (const [key, value] of this._map) value === child && this._map.delete(key);
1055
1390
  child._detach();
1056
1391
  return {
@@ -1058,7 +1393,7 @@ class LiveObject extends AbstractCrdt {
1058
1393
  node: this,
1059
1394
  type: "LiveObject",
1060
1395
  updates: {
1061
- [child._parentKey]: {
1396
+ [parentKey]: {
1062
1397
  type: "delete"
1063
1398
  }
1064
1399
  }
@@ -1070,24 +1405,20 @@ class LiveObject extends AbstractCrdt {
1070
1405
  modified: !1
1071
1406
  };
1072
1407
  }
1073
- _detachChildren() {
1074
- for (const [key, value] of this._map) this._map.delete(key), value._detach();
1075
- }
1076
1408
  _detach() {
1077
1409
  super._detach();
1078
- for (const value of this._map.values()) isCrdt(value) && value._detach();
1410
+ for (const value of this._map.values()) isLiveNode(value) && value._detach();
1079
1411
  }
1080
1412
  _apply(op, isLocal) {
1081
1413
  return op.type === OpCode.UPDATE_OBJECT ? this._applyUpdate(op, isLocal) : op.type === OpCode.DELETE_OBJECT_KEY ? this._applyDeleteObjectKey(op) : super._apply(op, isLocal);
1082
1414
  }
1083
1415
  _toSerializedCrdt() {
1084
- var _a;
1085
1416
  const data = {};
1086
- for (const [key, value] of this._map) value instanceof AbstractCrdt == !1 && (data[key] = value);
1087
- 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 ? {
1088
1419
  type: CrdtType.OBJECT,
1089
- parentId: this._parent._id,
1090
- parentKey: this._parentKey,
1420
+ parentId: this.parent.node._id,
1421
+ parentKey: this.parent.key,
1091
1422
  data: data
1092
1423
  } : {
1093
1424
  type: CrdtType.OBJECT,
@@ -1096,24 +1427,23 @@ class LiveObject extends AbstractCrdt {
1096
1427
  }
1097
1428
  _applyUpdate(op, isLocal) {
1098
1429
  let isModified = !1;
1099
- const reverse = [], reverseUpdate = {
1430
+ const id = nn(this._id), reverse = [], reverseUpdate = {
1100
1431
  type: OpCode.UPDATE_OBJECT,
1101
- id: this._id,
1432
+ id: id,
1102
1433
  data: {}
1103
1434
  };
1104
1435
  reverse.push(reverseUpdate);
1105
1436
  for (const key in op.data) {
1106
1437
  const oldValue = this._map.get(key);
1107
- oldValue instanceof AbstractCrdt ? (reverse.push(...oldValue._serialize(this._id, key)),
1108
- 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({
1109
1439
  type: OpCode.DELETE_OBJECT_KEY,
1110
- id: this._id,
1440
+ id: id,
1111
1441
  key: key
1112
1442
  });
1113
1443
  }
1114
1444
  const updateDelta = {};
1115
1445
  for (const key in op.data) {
1116
- if (isLocal) this._propToLastUpdate.set(key, op.opId); else {
1446
+ if (isLocal) this._propToLastUpdate.set(key, nn(op.opId)); else {
1117
1447
  if (null != this._propToLastUpdate.get(key)) {
1118
1448
  if (this._propToLastUpdate.get(key) === op.opId) {
1119
1449
  this._propToLastUpdate.delete(key);
@@ -1124,7 +1454,7 @@ class LiveObject extends AbstractCrdt {
1124
1454
  isModified = !0;
1125
1455
  }
1126
1456
  const oldValue = this._map.get(key);
1127
- isCrdt(oldValue) && oldValue._detach(), isModified = !0, updateDelta[key] = {
1457
+ isLiveNode(oldValue) && oldValue._detach(), isModified = !0, updateDelta[key] = {
1128
1458
  type: "update"
1129
1459
  }, this._map.set(key, op.data[key]);
1130
1460
  }
@@ -1148,11 +1478,11 @@ class LiveObject extends AbstractCrdt {
1148
1478
  if (void 0 !== this._propToLastUpdate.get(key)) return {
1149
1479
  modified: !1
1150
1480
  };
1151
- const oldValue = this._map.get(key);
1481
+ const oldValue = this._map.get(key), id = nn(this._id);
1152
1482
  let reverse = [];
1153
- 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 = [ {
1154
1484
  type: OpCode.UPDATE_OBJECT,
1155
- id: this._id,
1485
+ id: id,
1156
1486
  data: {
1157
1487
  [key]: oldValue
1158
1488
  }
@@ -1187,10 +1517,10 @@ class LiveObject extends AbstractCrdt {
1187
1517
  delete(key) {
1188
1518
  const keyAsString = key, oldValue = this._map.get(keyAsString);
1189
1519
  if (void 0 === oldValue) return;
1190
- 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(),
1191
1521
  void this._map.delete(keyAsString);
1192
1522
  let reverse;
1193
- oldValue instanceof AbstractCrdt ? (oldValue._detach(), reverse = oldValue._serialize(this._id, keyAsString)) : reverse = [ {
1523
+ isLiveNode(oldValue) ? (oldValue._detach(), reverse = oldValue._serialize(this._id, keyAsString)) : reverse = [ {
1194
1524
  type: OpCode.UPDATE_OBJECT,
1195
1525
  data: {
1196
1526
  [keyAsString]: oldValue
@@ -1217,9 +1547,9 @@ class LiveObject extends AbstractCrdt {
1217
1547
  if (null == this._doc || null == this._id) {
1218
1548
  for (const key in overrides) {
1219
1549
  const oldValue = this._map.get(key);
1220
- oldValue instanceof AbstractCrdt && oldValue._detach();
1550
+ isLiveNode(oldValue) && oldValue._detach();
1221
1551
  const newValue = overrides[key];
1222
- newValue instanceof AbstractCrdt && newValue._setParentLink(this, key), this._map.set(key, newValue);
1552
+ isLiveNode(newValue) && newValue._setParentLink(this, key), this._map.set(key, newValue);
1223
1553
  }
1224
1554
  return;
1225
1555
  }
@@ -1230,17 +1560,17 @@ class LiveObject extends AbstractCrdt {
1230
1560
  }, updateDelta = {};
1231
1561
  for (const key in overrides) {
1232
1562
  const oldValue = this._map.get(key);
1233
- oldValue instanceof AbstractCrdt ? (reverseOps.push(...oldValue._serialize(this._id, key)),
1563
+ isLiveNode(oldValue) ? (reverseOps.push(...oldValue._serialize(this._id, key)),
1234
1564
  oldValue._detach()) : void 0 === oldValue ? reverseOps.push({
1235
1565
  type: OpCode.DELETE_OBJECT_KEY,
1236
1566
  id: this._id,
1237
1567
  key: key
1238
1568
  }) : reverseUpdateOp.data[key] = oldValue;
1239
1569
  const newValue = overrides[key];
1240
- if (newValue instanceof AbstractCrdt) {
1570
+ if (isLiveNode(newValue)) {
1241
1571
  newValue._setParentLink(this, key), newValue._attach(this._doc.generateId(), this._doc);
1242
1572
  const newAttachChildOps = newValue._serialize(this._id, key, this._doc), createCrdtOp = newAttachChildOps.find((op => op.parentId === this._id));
1243
- createCrdtOp && this._propToLastUpdate.set(key, createCrdtOp.opId), ops.push(...newAttachChildOps);
1573
+ createCrdtOp && this._propToLastUpdate.set(key, nn(createCrdtOp.opId)), ops.push(...newAttachChildOps);
1244
1574
  } else updatedProps[key] = newValue, this._propToLastUpdate.set(key, opId);
1245
1575
  this._map.set(key, newValue), updateDelta[key] = {
1246
1576
  type: "update"
@@ -1262,4 +1592,4 @@ class LiveObject extends AbstractCrdt {
1262
1592
  }
1263
1593
  }
1264
1594
 
1265
- 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, parseJson as p, CrdtType as q, remove as r, comparePosition as s, throwUsageError as t, makePosition as u, isChildCrdt as v, assertNever as w };
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 };