@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.js CHANGED
@@ -122,52 +122,141 @@ function _createForOfIteratorHelperLoose(o, allowArrayLike) {
122
122
  throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
123
123
  }
124
124
 
125
- var ServerMsgCode, ClientMsgCode, CrdtType, OpCode, WebsocketCloseCodes;
125
+ var ClientMsgCode, OpCode, CrdtType, ServerMsgCode, WebsocketCloseCodes, OpSource, _emittedDeprecationWarnings = new Set;
126
+
127
+ function deprecate(message, key) {
128
+ void 0 === key && (key = message), "production" !== process.env.NODE_ENV && (_emittedDeprecationWarnings.has(key) || (_emittedDeprecationWarnings.add(key),
129
+ console.error("DEPRECATION WARNING: " + message)));
130
+ }
131
+
132
+ function throwUsageError(message) {
133
+ if ("production" !== process.env.NODE_ENV) {
134
+ var usageError = new Error(message);
135
+ throw usageError.name = "Usage error", usageError;
136
+ }
137
+ }
138
+
139
+ function errorIf(condition, message) {
140
+ "production" !== process.env.NODE_ENV && condition && throwUsageError(message);
141
+ }
142
+
143
+ function assertNever(_value, errmsg) {
144
+ throw new Error(errmsg);
145
+ }
146
+
147
+ function nn(value, errmsg) {
148
+ return void 0 === errmsg && (errmsg = "Expected value to be non-nullable"), function(condition, errmsg) {
149
+ if ("production" !== process.env.NODE_ENV && !condition) {
150
+ var err = new Error(errmsg);
151
+ throw err.name = "Assertion failure", err;
152
+ }
153
+ }(null != value, errmsg), value;
154
+ }
126
155
 
127
156
  function isChildCrdt(crdt) {
128
157
  return void 0 !== crdt.parentId && void 0 !== crdt.parentKey;
129
158
  }
130
159
 
160
+ function HasParent(node, key) {
161
+ return Object.freeze({
162
+ type: "HasParent",
163
+ node: node,
164
+ key: key
165
+ });
166
+ }
167
+
168
+ exports.ClientMsgCode = void 0, (ClientMsgCode = exports.ClientMsgCode || (exports.ClientMsgCode = {}))[ClientMsgCode.UPDATE_PRESENCE = 100] = "UPDATE_PRESENCE",
169
+ ClientMsgCode[ClientMsgCode.BROADCAST_EVENT = 103] = "BROADCAST_EVENT", ClientMsgCode[ClientMsgCode.FETCH_STORAGE = 200] = "FETCH_STORAGE",
170
+ ClientMsgCode[ClientMsgCode.UPDATE_STORAGE = 201] = "UPDATE_STORAGE", exports.OpCode = void 0,
171
+ (OpCode = exports.OpCode || (exports.OpCode = {}))[OpCode.INIT = 0] = "INIT", OpCode[OpCode.SET_PARENT_KEY = 1] = "SET_PARENT_KEY",
172
+ OpCode[OpCode.CREATE_LIST = 2] = "CREATE_LIST", OpCode[OpCode.UPDATE_OBJECT = 3] = "UPDATE_OBJECT",
173
+ OpCode[OpCode.CREATE_OBJECT = 4] = "CREATE_OBJECT", OpCode[OpCode.DELETE_CRDT = 5] = "DELETE_CRDT",
174
+ OpCode[OpCode.DELETE_OBJECT_KEY = 6] = "DELETE_OBJECT_KEY", OpCode[OpCode.CREATE_MAP = 7] = "CREATE_MAP",
175
+ OpCode[OpCode.CREATE_REGISTER = 8] = "CREATE_REGISTER", exports.CrdtType = void 0,
176
+ (CrdtType = exports.CrdtType || (exports.CrdtType = {}))[CrdtType.OBJECT = 0] = "OBJECT",
177
+ CrdtType[CrdtType.LIST = 1] = "LIST", CrdtType[CrdtType.MAP = 2] = "MAP", CrdtType[CrdtType.REGISTER = 3] = "REGISTER",
131
178
  exports.ServerMsgCode = void 0, (ServerMsgCode = exports.ServerMsgCode || (exports.ServerMsgCode = {}))[ServerMsgCode.UPDATE_PRESENCE = 100] = "UPDATE_PRESENCE",
132
179
  ServerMsgCode[ServerMsgCode.USER_JOINED = 101] = "USER_JOINED", ServerMsgCode[ServerMsgCode.USER_LEFT = 102] = "USER_LEFT",
133
180
  ServerMsgCode[ServerMsgCode.BROADCASTED_EVENT = 103] = "BROADCASTED_EVENT", ServerMsgCode[ServerMsgCode.ROOM_STATE = 104] = "ROOM_STATE",
134
181
  ServerMsgCode[ServerMsgCode.INITIAL_STORAGE_STATE = 200] = "INITIAL_STORAGE_STATE",
135
- ServerMsgCode[ServerMsgCode.UPDATE_STORAGE = 201] = "UPDATE_STORAGE", exports.ClientMsgCode = void 0,
136
- (ClientMsgCode = exports.ClientMsgCode || (exports.ClientMsgCode = {}))[ClientMsgCode.UPDATE_PRESENCE = 100] = "UPDATE_PRESENCE",
137
- ClientMsgCode[ClientMsgCode.BROADCAST_EVENT = 103] = "BROADCAST_EVENT", ClientMsgCode[ClientMsgCode.FETCH_STORAGE = 200] = "FETCH_STORAGE",
138
- ClientMsgCode[ClientMsgCode.UPDATE_STORAGE = 201] = "UPDATE_STORAGE", exports.CrdtType = void 0,
139
- (CrdtType = exports.CrdtType || (exports.CrdtType = {}))[CrdtType.OBJECT = 0] = "OBJECT",
140
- CrdtType[CrdtType.LIST = 1] = "LIST", CrdtType[CrdtType.MAP = 2] = "MAP", CrdtType[CrdtType.REGISTER = 3] = "REGISTER",
141
- exports.OpCode = void 0, (OpCode = exports.OpCode || (exports.OpCode = {}))[OpCode.INIT = 0] = "INIT",
142
- OpCode[OpCode.SET_PARENT_KEY = 1] = "SET_PARENT_KEY", OpCode[OpCode.CREATE_LIST = 2] = "CREATE_LIST",
143
- OpCode[OpCode.UPDATE_OBJECT = 3] = "UPDATE_OBJECT", OpCode[OpCode.CREATE_OBJECT = 4] = "CREATE_OBJECT",
144
- OpCode[OpCode.DELETE_CRDT = 5] = "DELETE_CRDT", OpCode[OpCode.DELETE_OBJECT_KEY = 6] = "DELETE_OBJECT_KEY",
145
- OpCode[OpCode.CREATE_MAP = 7] = "CREATE_MAP", OpCode[OpCode.CREATE_REGISTER = 8] = "CREATE_REGISTER",
146
- exports.WebsocketCloseCodes = void 0, (WebsocketCloseCodes = exports.WebsocketCloseCodes || (exports.WebsocketCloseCodes = {}))[WebsocketCloseCodes.CLOSE_ABNORMAL = 1006] = "CLOSE_ABNORMAL",
182
+ ServerMsgCode[ServerMsgCode.UPDATE_STORAGE = 201] = "UPDATE_STORAGE", exports.WebsocketCloseCodes = void 0,
183
+ (WebsocketCloseCodes = exports.WebsocketCloseCodes || (exports.WebsocketCloseCodes = {}))[WebsocketCloseCodes.CLOSE_ABNORMAL = 1006] = "CLOSE_ABNORMAL",
147
184
  WebsocketCloseCodes[WebsocketCloseCodes.INVALID_MESSAGE_FORMAT = 4e3] = "INVALID_MESSAGE_FORMAT",
148
185
  WebsocketCloseCodes[WebsocketCloseCodes.NOT_ALLOWED = 4001] = "NOT_ALLOWED", WebsocketCloseCodes[WebsocketCloseCodes.MAX_NUMBER_OF_MESSAGES_PER_SECONDS = 4002] = "MAX_NUMBER_OF_MESSAGES_PER_SECONDS",
149
186
  WebsocketCloseCodes[WebsocketCloseCodes.MAX_NUMBER_OF_CONCURRENT_CONNECTIONS = 4003] = "MAX_NUMBER_OF_CONCURRENT_CONNECTIONS",
150
187
  WebsocketCloseCodes[WebsocketCloseCodes.MAX_NUMBER_OF_MESSAGES_PER_DAY_PER_APP = 4004] = "MAX_NUMBER_OF_MESSAGES_PER_DAY_PER_APP",
151
188
  WebsocketCloseCodes[WebsocketCloseCodes.MAX_NUMBER_OF_CONCURRENT_CONNECTIONS_PER_ROOM = 4005] = "MAX_NUMBER_OF_CONCURRENT_CONNECTIONS_PER_ROOM",
152
- WebsocketCloseCodes[WebsocketCloseCodes.CLOSE_WITHOUT_RETRY = 4999] = "CLOSE_WITHOUT_RETRY";
189
+ WebsocketCloseCodes[WebsocketCloseCodes.CLOSE_WITHOUT_RETRY = 4999] = "CLOSE_WITHOUT_RETRY",
190
+ exports.OpSource = void 0, (OpSource = exports.OpSource || (exports.OpSource = {}))[OpSource.UNDOREDO_RECONNECT = 0] = "UNDOREDO_RECONNECT",
191
+ OpSource[OpSource.REMOTE = 1] = "REMOTE", OpSource[OpSource.ACK = 2] = "ACK";
192
+
193
+ var NoParent = Object.freeze({
194
+ type: "NoParent"
195
+ });
153
196
 
154
- var AbstractCrdt = function() {
197
+ function Orphaned(oldKey) {
198
+ return Object.freeze({
199
+ type: "Orphaned",
200
+ oldKey: oldKey
201
+ });
202
+ }
203
+
204
+ var _Symbol$iterator$1, _Symbol$iterator2, AbstractCrdt = function() {
155
205
  function AbstractCrdt() {
156
- this.__parent = void 0, this.__doc = void 0, this.__id = void 0, this.__parentKey = void 0;
206
+ this.__doc = void 0, this.__id = void 0, this._parent = NoParent;
157
207
  }
158
208
  var _proto = AbstractCrdt.prototype;
159
- return _proto._apply = function(op, _isLocal) {
160
- return op.type === exports.OpCode.DELETE_CRDT && null != this._parent && null != this._parentKey ? this._parent._detachChild(this) : {
209
+ return _proto._getParentKeyOrThrow = function() {
210
+ switch (this.parent.type) {
211
+ case "HasParent":
212
+ return this.parent.key;
213
+
214
+ case "NoParent":
215
+ throw new Error("Parent key is missing");
216
+
217
+ case "Orphaned":
218
+ return this.parent.oldKey;
219
+
220
+ default:
221
+ return assertNever(this.parent, "Unknown state");
222
+ }
223
+ }, _proto._apply = function(op, _isLocal) {
224
+ return op.type === exports.OpCode.DELETE_CRDT && "HasParent" === this.parent.type ? this.parent.node._detachChild(this) : {
161
225
  modified: !1
162
226
  };
163
- }, _proto._setParentLink = function(parent, key) {
164
- if (null != this.__parent && this.__parent !== parent) throw new Error("Cannot attach parent if it already exist");
165
- this.__parentKey = key, this.__parent = parent;
227
+ }, _proto._setParentLink = function(newParentNode, newParentKey) {
228
+ switch (this.parent.type) {
229
+ case "HasParent":
230
+ if (this.parent.node !== newParentNode) throw new Error("Cannot attach parent if it already exist");
231
+ return void (this._parent = HasParent(newParentNode, newParentKey));
232
+
233
+ case "Orphaned":
234
+ case "NoParent":
235
+ return void (this._parent = HasParent(newParentNode, newParentKey));
236
+
237
+ default:
238
+ return assertNever(this.parent, "Unknown state");
239
+ }
166
240
  }, _proto._attach = function(id, doc) {
167
241
  if (this.__id || this.__doc) throw new Error("Cannot attach if CRDT is already attached");
168
242
  doc.addItem(id, this), this.__id = id, this.__doc = doc;
169
243
  }, _proto._detach = function() {
170
- this.__doc && this.__id && this.__doc.deleteItem(this.__id), this.__parent = void 0,
244
+ switch (this.__doc && this.__id && this.__doc.deleteItem(this.__id), this.parent.type) {
245
+ case "HasParent":
246
+ this._parent = Orphaned(this.parent.key);
247
+ break;
248
+
249
+ case "NoParent":
250
+ this._parent = NoParent;
251
+ break;
252
+
253
+ case "Orphaned":
254
+ this._parent = Orphaned(this.parent.oldKey);
255
+ break;
256
+
257
+ default:
258
+ assertNever(this.parent, "Unknown state");
259
+ }
171
260
  this.__doc = void 0;
172
261
  }, _createClass(AbstractCrdt, [ {
173
262
  key: "_doc",
@@ -185,35 +274,44 @@ var AbstractCrdt = function() {
185
274
  return this.__id;
186
275
  }
187
276
  }, {
188
- key: "_parent",
277
+ key: "parent",
189
278
  get: function() {
190
- return this.__parent;
279
+ return this._parent;
191
280
  }
192
281
  }, {
193
- key: "_parentKey",
282
+ key: "_parentNode",
194
283
  get: function() {
195
- return this.__parentKey;
196
- }
197
- } ]), AbstractCrdt;
198
- }();
284
+ switch (this.parent.type) {
285
+ case "HasParent":
286
+ return this.parent.node;
199
287
 
200
- function parseJson(rawMessage) {
201
- try {
202
- return JSON.parse(rawMessage);
203
- } catch (e) {
204
- return;
205
- }
206
- }
288
+ case "NoParent":
289
+ case "Orphaned":
290
+ return null;
207
291
 
208
- function isJsonArray(data) {
209
- return Array.isArray(data);
210
- }
292
+ default:
293
+ return assertNever(this.parent, "Unknown state");
294
+ }
295
+ }
296
+ }, {
297
+ key: "_parentKey",
298
+ get: function() {
299
+ switch (this.parent.type) {
300
+ case "HasParent":
301
+ return this.parent.key;
211
302
 
212
- function isJsonObject(data) {
213
- return null !== data && "object" == typeof data && !isJsonArray(data);
214
- }
303
+ case "NoParent":
304
+ return null;
305
+
306
+ case "Orphaned":
307
+ return this.parent.oldKey;
215
308
 
216
- var _Symbol$iterator$1, _Symbol$iterator2, LiveRegister = function(_AbstractCrdt) {
309
+ default:
310
+ return assertNever(this.parent, "Unknown state");
311
+ }
312
+ }
313
+ } ]), AbstractCrdt;
314
+ }(), LiveRegister = function(_AbstractCrdt) {
217
315
  function LiveRegister(data) {
218
316
  var _this;
219
317
  return (_this = _AbstractCrdt.call(this) || this)._data = void 0, _this._data = data,
@@ -224,26 +322,25 @@ var _Symbol$iterator$1, _Symbol$iterator2, LiveRegister = function(_AbstractCrdt
224
322
  return register._attach(id, doc), register;
225
323
  };
226
324
  var _proto = LiveRegister.prototype;
227
- return _proto._serialize = function(parentId, parentKey, doc, intent) {
325
+ return _proto._serialize = function(parentId, parentKey, doc) {
228
326
  if (null == this._id || null == parentId || null == parentKey) throw new Error("Cannot serialize register if parentId or parentKey is undefined");
229
327
  return [ {
230
328
  type: exports.OpCode.CREATE_REGISTER,
231
329
  opId: null == doc ? void 0 : doc.generateOpId(),
232
330
  id: this._id,
233
- intent: intent,
234
331
  parentId: parentId,
235
332
  parentKey: parentKey,
236
333
  data: this.data
237
334
  } ];
238
335
  }, _proto._toSerializedCrdt = function() {
239
- var _this$_parent;
336
+ if ("HasParent" !== this.parent.type) throw new Error("Cannot serialize LiveRegister if parent is missing");
240
337
  return {
241
338
  type: exports.CrdtType.REGISTER,
242
- parentId: null == (_this$_parent = this._parent) ? void 0 : _this$_parent._id,
243
- parentKey: this._parentKey,
339
+ parentId: nn(this.parent.node._id, "Parent node expected to have ID"),
340
+ parentKey: this.parent.key,
244
341
  data: this.data
245
342
  };
246
- }, _proto._attachChild = function(_op, _isLocal) {
343
+ }, _proto._attachChild = function(_op) {
247
344
  throw new Error("Method not implemented.");
248
345
  }, _proto._detachChild = function(_crdt) {
249
346
  throw new Error("Method not implemented.");
@@ -258,7 +355,7 @@ var _Symbol$iterator$1, _Symbol$iterator2, LiveRegister = function(_AbstractCrdt
258
355
  }(AbstractCrdt);
259
356
 
260
357
  function makePosition(before, after) {
261
- return null == before && null == after ? pos([ 33 ]) : null != before && null == after ? function(before) {
358
+ return null != before && null != after ? pos(makePositionFromCodes(posCodes(before), posCodes(after))) : null != before ? function(before) {
262
359
  for (var result = [], beforeCodes = posCodes(before), i = 0; i < beforeCodes.length; i++) {
263
360
  var code = beforeCodes[i];
264
361
  if (126 !== code) {
@@ -271,7 +368,7 @@ function makePosition(before, after) {
271
368
  }
272
369
  }
273
370
  return pos(result);
274
- }(before) : null == before && null != after ? function(after) {
371
+ }(before) : null != after ? function(after) {
275
372
  for (var result = [], afterCodes = posCodes(after), i = 0; i < afterCodes.length; i++) {
276
373
  var code = afterCodes[i];
277
374
  if (!(code <= 33)) {
@@ -284,7 +381,7 @@ function makePosition(before, after) {
284
381
  }
285
382
  }
286
383
  return pos(result);
287
- }(after) : pos(makePositionFromCodes(posCodes(before), posCodes(after)));
384
+ }(after) : pos([ 33 ]);
288
385
  }
289
386
 
290
387
  function makePositionFromCodes(before, after) {
@@ -328,206 +425,322 @@ var LiveList = function(_AbstractCrdt) {
328
425
  function LiveList(items) {
329
426
  var _this;
330
427
  void 0 === items && (items = []), (_this = _AbstractCrdt.call(this) || this)._items = void 0,
331
- _this._items = [];
428
+ _this._implicitlyDeletedItems = void 0, _this._items = [], _this._implicitlyDeletedItems = new Set;
332
429
  for (var position = void 0, i = 0; i < items.length; i++) {
333
- var newPosition = makePosition(position), item = selfOrRegister(items[i]);
334
- _this._items.push([ item, newPosition ]), position = newPosition;
430
+ var newPosition = makePosition(position), item = lsonToLiveNode(items[i]);
431
+ item._setParentLink(_assertThisInitialized(_this), newPosition), _this._items.push(item),
432
+ position = newPosition;
335
433
  }
336
434
  return _this;
337
435
  }
338
436
  _inheritsLoose(LiveList, _AbstractCrdt), LiveList._deserialize = function(_ref, parentToChildren, doc) {
339
- var id = _ref[0], list = new LiveList([]);
437
+ var id = _ref[0], list = new LiveList;
340
438
  list._attach(id, doc);
341
439
  var children = parentToChildren.get(id);
342
440
  if (null == children) return list;
343
441
  for (var _step, _iterator = _createForOfIteratorHelperLoose(children); !(_step = _iterator()).done; ) {
344
- var entry = _step.value, child = deserialize(entry, parentToChildren, doc);
345
- child._setParentLink(list, entry[1].parentKey), list._items.push([ child, entry[1].parentKey ]),
346
- list._items.sort((function(itemA, itemB) {
347
- return comparePosition(itemA[1], itemB[1]);
348
- }));
442
+ var _step$value = _step.value, _id = _step$value[0], crdt = _step$value[1], child = deserialize([ _id, crdt ], parentToChildren, doc);
443
+ child._setParentLink(list, crdt.parentKey), list._items.push(child), sortListItem(list._items);
349
444
  }
350
445
  return list;
351
446
  };
352
447
  var _proto = LiveList.prototype;
353
- return _proto._serialize = function(parentId, parentKey, doc, intent) {
448
+ return _proto._serialize = function(parentId, parentKey, doc) {
354
449
  if (null == this._id) throw new Error("Cannot serialize item is not attached");
355
- if (null == parentId || null == parentKey) throw new Error("Cannot serialize list if parentId or parentKey is undefined");
356
450
  var ops = [], op = {
357
451
  id: this._id,
358
452
  opId: null == doc ? void 0 : doc.generateOpId(),
359
- intent: intent,
360
453
  type: exports.OpCode.CREATE_LIST,
361
454
  parentId: parentId,
362
455
  parentKey: parentKey
363
456
  };
364
457
  ops.push(op);
365
458
  for (var _step2, _iterator2 = _createForOfIteratorHelperLoose(this._items); !(_step2 = _iterator2()).done; ) {
366
- var _step2$value = _step2.value, _value = _step2$value[0], key = _step2$value[1];
367
- ops.push.apply(ops, _value._serialize(this._id, key, doc));
459
+ var item = _step2.value;
460
+ ops.push.apply(ops, item._serialize(this._id, item._getParentKeyOrThrow(), doc));
368
461
  }
369
462
  return ops;
370
463
  }, _proto._indexOfPosition = function(position) {
371
464
  return this._items.findIndex((function(item) {
372
- return item[1] === position;
465
+ return item._getParentKeyOrThrow() === position;
373
466
  }));
374
467
  }, _proto._attach = function(id, doc) {
375
468
  _AbstractCrdt.prototype._attach.call(this, id, doc);
376
469
  for (var _step3, _iterator3 = _createForOfIteratorHelperLoose(this._items); !(_step3 = _iterator3()).done; ) {
377
- _step3.value[0]._attach(doc.generateId(), doc);
470
+ _step3.value._attach(doc.generateId(), doc);
378
471
  }
379
472
  }, _proto._detach = function() {
380
473
  _AbstractCrdt.prototype._detach.call(this);
381
474
  for (var _step4, _iterator4 = _createForOfIteratorHelperLoose(this._items); !(_step4 = _iterator4()).done; ) {
382
- _step4.value[0]._detach();
475
+ _step4.value._detach();
383
476
  }
384
- }, _proto._attachChild = function(op, isLocal) {
477
+ }, _proto._applyRemoteSet = function(op) {
385
478
  if (null == this._doc) throw new Error("Can't attach child if doc is not present");
386
- var id = op.id, parentKey = op.parentKey, intent = op.intent, key = parentKey, child = creationOpToLiveStructure(op);
387
- if (void 0 !== this._doc.getItem(id)) return {
388
- modified: !1
389
- };
479
+ var id = op.id, key = op.parentKey, child = creationOpToLiveNode(op);
390
480
  child._attach(id, this._doc), child._setParentLink(this, key);
391
- var index = this._items.findIndex((function(entry) {
392
- return entry[1] === key;
393
- })), newKey = key;
394
- if (-1 !== index) {
395
- if ("set" === intent) {
396
- var existingItem = this._items[index][0];
397
- existingItem._detach();
398
- var storageUpdate = {
399
- node: this,
400
- type: "LiveList",
401
- updates: [ {
402
- index: index,
403
- type: "set",
404
- item: child instanceof LiveRegister ? child.data : child
405
- } ]
406
- };
407
- return this._items[index][0] = child, {
408
- modified: storageUpdate,
409
- reverse: existingItem._serialize(this._id, key, this._doc, "set")
410
- };
411
- }
412
- if (isLocal) {
413
- var before = this._items[index] ? this._items[index][1] : void 0, after = this._items[index + 1] ? this._items[index + 1][1] : void 0;
414
- newKey = makePosition(before, after), child._setParentLink(this, newKey);
415
- } else {
416
- var _this$_items;
417
- this._items[index][1] = makePosition(key, null == (_this$_items = this._items[index + 1]) ? void 0 : _this$_items[1]);
418
- }
481
+ var deletedId = op.deletedId, existingItemIndex = this._indexOfPosition(key);
482
+ if (-1 !== existingItemIndex) {
483
+ var existingItem = this._items[existingItemIndex];
484
+ if (existingItem._id === deletedId) return existingItem._detach(), this._items[existingItemIndex] = child,
485
+ {
486
+ modified: makeUpdate(this, [ setDelta(existingItemIndex, child) ]),
487
+ reverse: []
488
+ };
489
+ this._implicitlyDeletedItems.add(existingItem), this._items[existingItemIndex] = child;
490
+ var delta = [ setDelta(existingItemIndex, child) ], _deleteDelta = this._detachItemAssociatedToSetOperation(op.deletedId);
491
+ return _deleteDelta && delta.push(_deleteDelta), {
492
+ modified: makeUpdate(this, delta),
493
+ reverse: []
494
+ };
419
495
  }
420
- this._items.push([ child, newKey ]), this._items.sort((function(itemA, itemB) {
421
- return comparePosition(itemA[1], itemB[1]);
422
- }));
423
- var newIndex = this._items.findIndex((function(entry) {
424
- return entry[1] === newKey;
496
+ var updates = [], _deleteDelta2 = this._detachItemAssociatedToSetOperation(op.deletedId);
497
+ return _deleteDelta2 && updates.push(_deleteDelta2), this._items.push(child), sortListItem(this._items),
498
+ updates.push(insertDelta(this._indexOfPosition(key), child)), {
499
+ reverse: [],
500
+ modified: makeUpdate(this, updates)
501
+ };
502
+ }, _proto._applySetAck = function(op) {
503
+ var delta = [], deletedDelta = this._detachItemAssociatedToSetOperation(op.deletedId);
504
+ deletedDelta && delta.push(deletedDelta);
505
+ var indexOfItemWithSamePosition = this._indexOfPosition(op.parentKey), existingItem = this._items.find((function(item) {
506
+ return item._id === op.id;
425
507
  }));
508
+ if (null != existingItem) {
509
+ if (existingItem._parentKey === op.parentKey) return delta.length > 0 ? {
510
+ modified: makeUpdate(this, delta),
511
+ reverse: []
512
+ } : {
513
+ modified: !1
514
+ };
515
+ -1 !== indexOfItemWithSamePosition && (this._implicitlyDeletedItems.add(this._items[indexOfItemWithSamePosition]),
516
+ this._items.splice(indexOfItemWithSamePosition, 1), delta.push(deleteDelta(indexOfItemWithSamePosition)));
517
+ var previousIndex = this._items.indexOf(existingItem);
518
+ existingItem._setParentLink(this, op.parentKey), sortListItem(this._items);
519
+ var newIndex = this._items.indexOf(existingItem);
520
+ return newIndex !== previousIndex && delta.push(moveDelta(previousIndex, newIndex, existingItem)),
521
+ {
522
+ modified: delta.length > 0 && makeUpdate(this, delta),
523
+ reverse: []
524
+ };
525
+ }
526
+ var orphan = nn(this._doc).getItem(op.id);
527
+ if (orphan && this._implicitlyDeletedItems.has(orphan)) {
528
+ orphan._setParentLink(this, op.parentKey), this._implicitlyDeletedItems.delete(orphan),
529
+ this._items.push(orphan), sortListItem(this._items);
530
+ var recreatedItemIndex = this._items.indexOf(orphan);
531
+ return {
532
+ modified: makeUpdate(this, [ -1 === indexOfItemWithSamePosition ? insertDelta(recreatedItemIndex, orphan) : setDelta(recreatedItemIndex, orphan) ].concat(delta)),
533
+ reverse: []
534
+ };
535
+ }
536
+ var _this$_createAttachIt = this._createAttachItemAndSort(op, op.parentKey), newItem = _this$_createAttachIt.newItem, _newIndex = _this$_createAttachIt.newIndex;
537
+ return {
538
+ modified: makeUpdate(this, [ -1 === indexOfItemWithSamePosition ? insertDelta(_newIndex, newItem) : setDelta(_newIndex, newItem) ].concat(delta)),
539
+ reverse: []
540
+ };
541
+ }, _proto._detachItemAssociatedToSetOperation = function(deletedId) {
542
+ if (null == deletedId || null == this._doc) return null;
543
+ var deletedItem = this._doc.getItem(deletedId);
544
+ if (null == deletedItem) return null;
545
+ var result = this._detachChild(deletedItem);
546
+ return !1 === result.modified ? null : result.modified.updates[0];
547
+ }, _proto._applyRemoteInsert = function(op) {
548
+ if (null == this._doc) throw new Error("Can't attach child if doc is not present");
549
+ var key = op.parentKey, existingItemIndex = this._indexOfPosition(key);
550
+ -1 !== existingItemIndex && this._shiftItemPosition(existingItemIndex, key);
551
+ var _this$_createAttachIt2 = this._createAttachItemAndSort(op, key), newItem = _this$_createAttachIt2.newItem;
552
+ return {
553
+ modified: makeUpdate(this, [ insertDelta(_this$_createAttachIt2.newIndex, newItem) ]),
554
+ reverse: []
555
+ };
556
+ }, _proto._applyInsertAck = function(op) {
557
+ var existingItem = this._items.find((function(item) {
558
+ return item._id === op.id;
559
+ })), key = op.parentKey, itemIndexAtPosition = this._indexOfPosition(key);
560
+ if (existingItem) {
561
+ if (existingItem._parentKey === key) return {
562
+ modified: !1
563
+ };
564
+ var oldPositionIndex = this._items.indexOf(existingItem);
565
+ -1 !== itemIndexAtPosition && this._shiftItemPosition(itemIndexAtPosition, key),
566
+ existingItem._setParentLink(this, key), sortListItem(this._items);
567
+ var newIndex = this._indexOfPosition(key);
568
+ return newIndex === oldPositionIndex ? {
569
+ modified: !1
570
+ } : {
571
+ modified: makeUpdate(this, [ moveDelta(oldPositionIndex, newIndex, existingItem) ]),
572
+ reverse: []
573
+ };
574
+ }
575
+ var orphan = nn(this._doc).getItem(op.id);
576
+ if (orphan && this._implicitlyDeletedItems.has(orphan)) return orphan._setParentLink(this, key),
577
+ this._implicitlyDeletedItems.delete(orphan), this._items.push(orphan), sortListItem(this._items),
578
+ {
579
+ modified: makeUpdate(this, [ insertDelta(this._indexOfPosition(key), orphan) ]),
580
+ reverse: []
581
+ };
582
+ -1 !== itemIndexAtPosition && this._shiftItemPosition(itemIndexAtPosition, key);
583
+ var _this$_createAttachIt3 = this._createAttachItemAndSort(op, key), newItem = _this$_createAttachIt3.newItem;
584
+ return {
585
+ modified: makeUpdate(this, [ insertDelta(_this$_createAttachIt3.newIndex, newItem) ]),
586
+ reverse: []
587
+ };
588
+ }, _proto._applyInsertUndoRedo = function(op) {
589
+ var _this$_doc, id = op.id, key = op.parentKey, child = creationOpToLiveNode(op);
590
+ if (void 0 !== (null == (_this$_doc = this._doc) ? void 0 : _this$_doc.getItem(id))) return {
591
+ modified: !1
592
+ };
593
+ child._attach(id, nn(this._doc)), child._setParentLink(this, key);
594
+ var existingItemIndex = this._indexOfPosition(key), newKey = key;
595
+ -1 !== existingItemIndex && (newKey = makePosition(this._items[existingItemIndex] ? this._items[existingItemIndex]._getParentKeyOrThrow() : void 0, this._items[existingItemIndex + 1] ? this._items[existingItemIndex + 1]._getParentKeyOrThrow() : void 0),
596
+ child._setParentLink(this, newKey));
597
+ return this._items.push(child), sortListItem(this._items), {
598
+ modified: makeUpdate(this, [ insertDelta(this._indexOfPosition(newKey), child) ]),
599
+ reverse: [ {
600
+ type: exports.OpCode.DELETE_CRDT,
601
+ id: id
602
+ } ]
603
+ };
604
+ }, _proto._applySetUndoRedo = function(op) {
605
+ var _this$_doc2, id = op.id, key = op.parentKey, child = creationOpToLiveNode(op);
606
+ if (void 0 !== (null == (_this$_doc2 = this._doc) ? void 0 : _this$_doc2.getItem(id))) return {
607
+ modified: !1
608
+ };
609
+ var indexOfItemWithSameKey = this._indexOfPosition(key);
610
+ child._attach(id, nn(this._doc)), child._setParentLink(this, key);
611
+ var newKey = key;
612
+ if (-1 !== indexOfItemWithSameKey) {
613
+ var existingItem = this._items[indexOfItemWithSameKey];
614
+ existingItem._detach(), this._items[indexOfItemWithSameKey] = child;
615
+ var reverse = existingItem._serialize(nn(this._id), key, this._doc);
616
+ addIntentAndDeletedIdToOperation(reverse, op.id);
617
+ var delta = [ setDelta(indexOfItemWithSameKey, child) ], deletedDelta = this._detachItemAssociatedToSetOperation(op.deletedId);
618
+ return deletedDelta && delta.push(deletedDelta), {
619
+ modified: makeUpdate(this, delta),
620
+ reverse: reverse
621
+ };
622
+ }
623
+ this._items.push(child), sortListItem(this._items), this._detachItemAssociatedToSetOperation(op.deletedId);
624
+ var newIndex = this._indexOfPosition(newKey);
426
625
  return {
427
626
  reverse: [ {
428
627
  type: exports.OpCode.DELETE_CRDT,
429
628
  id: id
430
629
  } ],
431
- modified: {
432
- node: this,
433
- type: "LiveList",
434
- updates: [ {
435
- index: newIndex,
436
- type: "insert",
437
- item: child instanceof LiveRegister ? child.data : child
438
- } ]
439
- }
630
+ modified: makeUpdate(this, [ insertDelta(newIndex, child) ])
440
631
  };
632
+ }, _proto._attachChild = function(op, source) {
633
+ if (null == this._doc) throw new Error("Can't attach child if doc is not present");
634
+ if ("set" === op.intent) {
635
+ if (source === exports.OpSource.REMOTE) return this._applyRemoteSet(op);
636
+ if (source === exports.OpSource.UNDOREDO_RECONNECT) return this._applySetUndoRedo(op);
637
+ if (source === exports.OpSource.ACK) return this._applySetAck(op);
638
+ }
639
+ return source === exports.OpSource.REMOTE ? this._applyRemoteInsert(op) : source === exports.OpSource.ACK ? this._applyInsertAck(op) : this._applyInsertUndoRedo(op);
441
640
  }, _proto._detachChild = function(child) {
442
641
  if (child) {
443
- var reverse = child._serialize(this._id, child._parentKey, this._doc), indexToDelete = this._items.findIndex((function(item) {
444
- return item[0] === child;
445
- }));
642
+ var parentKey = nn(child._parentKey), reverse = child._serialize(nn(this._id), parentKey, this._doc), indexToDelete = this._items.indexOf(child);
446
643
  return this._items.splice(indexToDelete, 1), child._detach(), {
447
- modified: {
448
- node: this,
449
- type: "LiveList",
450
- updates: [ {
451
- index: indexToDelete,
452
- type: "delete"
453
- } ]
454
- },
644
+ modified: makeUpdate(this, [ deleteDelta(indexToDelete) ]),
455
645
  reverse: reverse
456
646
  };
457
647
  }
458
648
  return {
459
649
  modified: !1
460
650
  };
461
- }, _proto._setChildKey = function(key, child, previousKey) {
462
- child._setParentLink(this, key);
463
- var _this$_items2, previousIndex = this._items.findIndex((function(entry) {
464
- return entry[0]._id === child._id;
465
- })), index = this._items.findIndex((function(entry) {
466
- return entry[1] === key;
467
- }));
468
- -1 !== index && (this._items[index][1] = makePosition(key, null == (_this$_items2 = this._items[index + 1]) ? void 0 : _this$_items2[1]));
469
- var item = this._items.find((function(item) {
470
- return item[0] === child;
471
- }));
472
- item && (item[1] = key), this._items.sort((function(itemA, itemB) {
473
- return comparePosition(itemA[1], itemB[1]);
474
- }));
475
- var newIndex = this._items.findIndex((function(entry) {
476
- return entry[0]._id === child._id;
477
- }));
478
- return {
479
- modified: {
480
- node: this,
481
- type: "LiveList",
482
- updates: newIndex === previousIndex ? [] : [ {
483
- index: newIndex,
484
- item: child instanceof LiveRegister ? child.data : child,
485
- previousIndex: previousIndex,
486
- type: "move"
487
- } ]
488
- },
651
+ }, _proto._applySetChildKeyRemote = function(newKey, child) {
652
+ if (this._implicitlyDeletedItems.has(child)) return this._implicitlyDeletedItems.delete(child),
653
+ child._setParentLink(this, newKey), this._items.push(child), sortListItem(this._items),
654
+ {
655
+ modified: makeUpdate(this, [ insertDelta(this._items.indexOf(child), child) ]),
656
+ reverse: []
657
+ };
658
+ if (newKey === child._parentKey) return {
659
+ modified: !1
660
+ };
661
+ var _this$_items, existingItemIndex = this._indexOfPosition(newKey);
662
+ if (-1 === existingItemIndex) {
663
+ var previousIndex = this._items.indexOf(child);
664
+ child._setParentLink(this, newKey), sortListItem(this._items);
665
+ var _newIndex4 = this._items.indexOf(child);
666
+ return _newIndex4 === previousIndex ? {
667
+ modified: !1
668
+ } : {
669
+ modified: makeUpdate(this, [ moveDelta(previousIndex, _newIndex4, child) ]),
670
+ reverse: []
671
+ };
672
+ }
673
+ this._items[existingItemIndex]._setParentLink(this, makePosition(newKey, null == (_this$_items = this._items[existingItemIndex + 1]) ? void 0 : _this$_items._getParentKeyOrThrow()));
674
+ var _previousIndex = this._items.indexOf(child);
675
+ child._setParentLink(this, newKey), sortListItem(this._items);
676
+ var _newIndex5 = this._items.indexOf(child);
677
+ return _newIndex5 === _previousIndex ? {
678
+ modified: !1
679
+ } : {
680
+ modified: makeUpdate(this, [ moveDelta(_previousIndex, _newIndex5, child) ]),
681
+ reverse: []
682
+ };
683
+ }, _proto._applySetChildKeyAck = function(newKey, child) {
684
+ var previousKey = nn(child._parentKey);
685
+ if (this._implicitlyDeletedItems.has(child)) {
686
+ var _this$_items2, existingItemIndex = this._indexOfPosition(newKey);
687
+ if (this._implicitlyDeletedItems.delete(child), -1 !== existingItemIndex) this._items[existingItemIndex]._setParentLink(this, makePosition(newKey, null == (_this$_items2 = this._items[existingItemIndex + 1]) ? void 0 : _this$_items2._getParentKeyOrThrow()));
688
+ return child._setParentLink(this, newKey), this._items.push(child), sortListItem(this._items),
689
+ {
690
+ modified: !1
691
+ };
692
+ }
693
+ if (newKey === previousKey) return {
694
+ modified: !1
695
+ };
696
+ var _this$_items3, previousIndex = this._items.indexOf(child), _existingItemIndex = this._indexOfPosition(newKey);
697
+ -1 !== _existingItemIndex && this._items[_existingItemIndex]._setParentLink(this, makePosition(newKey, null == (_this$_items3 = this._items[_existingItemIndex + 1]) ? void 0 : _this$_items3._getParentKeyOrThrow())),
698
+ child._setParentLink(this, newKey), sortListItem(this._items);
699
+ var newIndex = this._items.indexOf(child);
700
+ return previousIndex === newIndex ? {
701
+ modified: !1
702
+ } : {
703
+ modified: makeUpdate(this, [ moveDelta(previousIndex, newIndex, child) ]),
704
+ reverse: []
705
+ };
706
+ }, _proto._applySetChildKeyUndoRedo = function(newKey, child) {
707
+ var _this$_items4, previousKey = nn(child._parentKey), previousIndex = this._items.indexOf(child), existingItemIndex = this._indexOfPosition(newKey);
708
+ -1 !== existingItemIndex && this._items[existingItemIndex]._setParentLink(this, makePosition(newKey, null == (_this$_items4 = this._items[existingItemIndex + 1]) ? void 0 : _this$_items4._getParentKeyOrThrow()));
709
+ child._setParentLink(this, newKey), sortListItem(this._items);
710
+ var newIndex = this._items.indexOf(child);
711
+ return previousIndex === newIndex ? {
712
+ modified: !1
713
+ } : {
714
+ modified: makeUpdate(this, [ moveDelta(previousIndex, newIndex, child) ]),
489
715
  reverse: [ {
490
716
  type: exports.OpCode.SET_PARENT_KEY,
491
- id: null == item ? void 0 : item[0]._id,
717
+ id: nn(child._id),
492
718
  parentKey: previousKey
493
719
  } ]
494
720
  };
721
+ }, _proto._setChildKey = function(newKey, child, source) {
722
+ return source === exports.OpSource.REMOTE ? this._applySetChildKeyRemote(newKey, child) : source === exports.OpSource.ACK ? this._applySetChildKeyAck(newKey, child) : this._applySetChildKeyUndoRedo(newKey, child);
495
723
  }, _proto._apply = function(op, isLocal) {
496
724
  return _AbstractCrdt.prototype._apply.call(this, op, isLocal);
497
725
  }, _proto._toSerializedCrdt = function() {
498
- var _this$_parent;
726
+ if ("HasParent" !== this.parent.type) throw new Error("Cannot serialize LiveList if parent is missing");
499
727
  return {
500
728
  type: exports.CrdtType.LIST,
501
- parentId: null == (_this$_parent = this._parent) ? void 0 : _this$_parent._id,
502
- parentKey: this._parentKey
729
+ parentId: nn(this.parent.node._id, "Parent node expected to have ID"),
730
+ parentKey: this.parent.key
503
731
  };
504
732
  }, _proto.push = function(element) {
505
733
  return this.insert(element, this.length);
506
734
  }, _proto.insert = function(element, index) {
507
735
  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);
508
- var 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);
509
- value._setParentLink(this, position), this._items.push([ value, position ]), this._items.sort((function(itemA, itemB) {
510
- return comparePosition(itemA[1], itemB[1]);
511
- }));
512
- var newIndex = this._items.findIndex((function(entry) {
513
- return entry[1] === position;
514
- }));
515
- if (this._doc && this._id) {
736
+ var 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);
737
+ if (value._setParentLink(this, position), this._items.push(value), sortListItem(this._items),
738
+ this._doc && this._id) {
516
739
  var id = this._doc.generateId();
517
- value._attach(id, this._doc);
518
- var storageUpdates = new Map;
519
- storageUpdates.set(this._id, {
520
- node: this,
521
- type: "LiveList",
522
- updates: [ {
523
- index: newIndex,
524
- item: value instanceof LiveRegister ? value.data : value,
525
- type: "insert"
526
- } ]
527
- }), this._doc.dispatch(value._serialize(this._id, position, this._doc), [ {
740
+ value._attach(id, this._doc), this._doc.dispatch(value._serialize(this._id, position, this._doc), [ {
528
741
  type: exports.OpCode.DELETE_CRDT,
529
742
  id: id
530
- } ], storageUpdates);
743
+ } ], new Map([ [ this._id, makeUpdate(this, [ insertDelta(index, value) ]) ] ]));
531
744
  }
532
745
  }, _proto.move = function(index, targetIndex) {
533
746
  if (targetIndex < 0) throw new Error("targetIndex cannot be less than 0");
@@ -535,108 +748,77 @@ var LiveList = function(_AbstractCrdt) {
535
748
  if (index < 0) throw new Error("index cannot be less than 0");
536
749
  if (index >= this._items.length) throw new Error("index cannot be greater or equal than the list length");
537
750
  var beforePosition = null, afterPosition = null;
538
- index < targetIndex ? (afterPosition = targetIndex === this._items.length - 1 ? void 0 : this._items[targetIndex + 1][1],
539
- beforePosition = this._items[targetIndex][1]) : (afterPosition = this._items[targetIndex][1],
540
- beforePosition = 0 === targetIndex ? void 0 : this._items[targetIndex - 1][1]);
541
- var position = makePosition(beforePosition, afterPosition), item = this._items[index], previousPosition = item[1];
542
- item[1] = position, item[0]._setParentLink(this, position), this._items.sort((function(itemA, itemB) {
543
- return comparePosition(itemA[1], itemB[1]);
544
- }));
545
- var newIndex = this._items.findIndex((function(entry) {
546
- return entry[1] === position;
547
- }));
548
- if (this._doc && this._id) {
549
- var storageUpdates = new Map;
550
- storageUpdates.set(this._id, {
551
- node: this,
552
- type: "LiveList",
553
- updates: [ {
554
- index: newIndex,
555
- previousIndex: index,
556
- item: item[0],
557
- type: "move"
558
- } ]
559
- }), this._doc.dispatch([ {
751
+ index < targetIndex ? (afterPosition = targetIndex === this._items.length - 1 ? void 0 : this._items[targetIndex + 1]._getParentKeyOrThrow(),
752
+ beforePosition = this._items[targetIndex]._getParentKeyOrThrow()) : (afterPosition = this._items[targetIndex]._getParentKeyOrThrow(),
753
+ beforePosition = 0 === targetIndex ? void 0 : this._items[targetIndex - 1]._getParentKeyOrThrow());
754
+ var position = makePosition(beforePosition, afterPosition), item = this._items[index], previousPosition = item._getParentKeyOrThrow();
755
+ if (item._setParentLink(this, position), sortListItem(this._items), this._doc && this._id) {
756
+ var storageUpdates = new Map([ [ this._id, makeUpdate(this, [ moveDelta(index, targetIndex, item) ]) ] ]);
757
+ this._doc.dispatch([ {
560
758
  type: exports.OpCode.SET_PARENT_KEY,
561
- id: item[0]._id,
759
+ id: nn(item._id),
562
760
  opId: this._doc.generateOpId(),
563
761
  parentKey: position
564
762
  } ], [ {
565
763
  type: exports.OpCode.SET_PARENT_KEY,
566
- id: item[0]._id,
764
+ id: nn(item._id),
567
765
  parentKey: previousPosition
568
766
  } ], storageUpdates);
569
767
  }
570
768
  }, _proto.delete = function(index) {
571
769
  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));
572
770
  var item = this._items[index];
573
- if (item[0]._detach(), this._items.splice(index, 1), this._doc) {
574
- var childRecordId = item[0]._id;
771
+ if (item._detach(), this._items.splice(index, 1), this._doc) {
772
+ var childRecordId = item._id;
575
773
  if (childRecordId) {
576
774
  var storageUpdates = new Map;
577
- storageUpdates.set(this._id, {
578
- node: this,
579
- type: "LiveList",
580
- updates: [ {
581
- index: index,
582
- type: "delete"
583
- } ]
584
- }), this._doc.dispatch([ {
775
+ storageUpdates.set(nn(this._id), makeUpdate(this, [ deleteDelta(index) ])), this._doc.dispatch([ {
585
776
  id: childRecordId,
586
777
  opId: this._doc.generateOpId(),
587
778
  type: exports.OpCode.DELETE_CRDT
588
- } ], item[0]._serialize(this._id, item[1]), storageUpdates);
779
+ } ], item._serialize(nn(this._id), item._getParentKeyOrThrow()), storageUpdates);
589
780
  }
590
781
  }
591
782
  }, _proto.clear = function() {
592
783
  if (this._doc) {
593
784
  for (var _step5, ops = [], reverseOps = [], updateDelta = [], i = 0, _iterator5 = _createForOfIteratorHelperLoose(this._items); !(_step5 = _iterator5()).done; ) {
594
785
  var item = _step5.value;
595
- item[0]._detach();
596
- var childId = item[0]._id;
786
+ item._detach();
787
+ var childId = item._id;
597
788
  childId && (ops.push({
789
+ type: exports.OpCode.DELETE_CRDT,
598
790
  id: childId,
599
- type: exports.OpCode.DELETE_CRDT
600
- }), reverseOps.push.apply(reverseOps, item[0]._serialize(this._id, item[1])), updateDelta.push({
601
- index: i,
602
- type: "delete"
603
- })), i++;
791
+ opId: this._doc.generateOpId()
792
+ }), reverseOps.push.apply(reverseOps, item._serialize(nn(this._id), item._getParentKeyOrThrow())),
793
+ updateDelta.push(deleteDelta(i))), i++;
604
794
  }
605
795
  this._items = [];
606
796
  var storageUpdates = new Map;
607
- storageUpdates.set(this._id, {
608
- node: this,
609
- type: "LiveList",
610
- updates: updateDelta
611
- }), this._doc.dispatch(ops, reverseOps, storageUpdates);
797
+ storageUpdates.set(nn(this._id), makeUpdate(this, updateDelta)), this._doc.dispatch(ops, reverseOps, storageUpdates);
612
798
  } else {
613
799
  for (var _step6, _iterator6 = _createForOfIteratorHelperLoose(this._items); !(_step6 = _iterator6()).done; ) {
614
- _step6.value[0]._detach();
800
+ _step6.value._detach();
615
801
  }
616
802
  this._items = [];
617
803
  }
618
804
  }, _proto.set = function(index, item) {
619
805
  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));
620
- var _this$_items$index = this._items[index], existingItem = _this$_items$index[0], position = _this$_items$index[1];
806
+ var existingItem = this._items[index], position = existingItem._getParentKeyOrThrow(), existingId = existingItem._id;
621
807
  existingItem._detach();
622
- var value = selfOrRegister(item);
623
- if (value._setParentLink(this, position), this._items[index][0] = value, this._doc && this._id) {
808
+ var value = lsonToLiveNode(item);
809
+ if (value._setParentLink(this, position), this._items[index] = value, this._doc && this._id) {
624
810
  var id = this._doc.generateId();
625
811
  value._attach(id, this._doc);
626
812
  var storageUpdates = new Map;
627
- storageUpdates.set(this._id, {
628
- node: this,
629
- type: "LiveList",
630
- updates: [ {
631
- index: index,
632
- item: value instanceof LiveRegister ? value.data : value,
633
- type: "set"
634
- } ]
635
- }), this._doc.dispatch(value._serialize(this._id, position, this._doc, "set"), existingItem._serialize(this._id, position, void 0, "set"), storageUpdates);
813
+ storageUpdates.set(this._id, makeUpdate(this, [ setDelta(index, value) ]));
814
+ var ops = value._serialize(this._id, position, this._doc);
815
+ addIntentAndDeletedIdToOperation(ops, existingId);
816
+ var reverseOps = existingItem._serialize(this._id, position, void 0);
817
+ addIntentAndDeletedIdToOperation(reverseOps, id), this._doc.dispatch(ops, reverseOps, storageUpdates);
636
818
  }
637
819
  }, _proto.toArray = function() {
638
820
  return this._items.map((function(entry) {
639
- return selfOrRegisterValue(entry[0]);
821
+ return liveNodeToLson(entry);
640
822
  }));
641
823
  }, _proto.every = function(predicate) {
642
824
  return this.toArray().every(predicate);
@@ -649,19 +831,29 @@ var LiveList = function(_AbstractCrdt) {
649
831
  }, _proto.forEach = function(callbackfn) {
650
832
  return this.toArray().forEach(callbackfn);
651
833
  }, _proto.get = function(index) {
652
- if (!(index < 0 || index >= this._items.length)) return selfOrRegisterValue(this._items[index][0]);
834
+ if (!(index < 0 || index >= this._items.length)) return liveNodeToLson(this._items[index]);
653
835
  }, _proto.indexOf = function(searchElement, fromIndex) {
654
836
  return this.toArray().indexOf(searchElement, fromIndex);
655
837
  }, _proto.lastIndexOf = function(searchElement, fromIndex) {
656
838
  return this.toArray().lastIndexOf(searchElement, fromIndex);
657
839
  }, _proto.map = function(callback) {
658
840
  return this._items.map((function(entry, i) {
659
- return callback(selfOrRegisterValue(entry[0]), i);
841
+ return callback(liveNodeToLson(entry), i);
660
842
  }));
661
843
  }, _proto.some = function(predicate) {
662
844
  return this.toArray().some(predicate);
663
845
  }, _proto[_Symbol$iterator$1] = function() {
664
846
  return new LiveListIterator(this._items);
847
+ }, _proto._createAttachItemAndSort = function(op, key) {
848
+ var newItem = creationOpToLiveNode(op);
849
+ return newItem._attach(op.id, nn(this._doc)), newItem._setParentLink(this, key),
850
+ this._items.push(newItem), sortListItem(this._items), {
851
+ newItem: newItem,
852
+ newIndex: this._indexOfPosition(key)
853
+ };
854
+ }, _proto._shiftItemPosition = function(index, key) {
855
+ var _this$_items5, shiftedPosition = makePosition(key, this._items.length > index + 1 ? null == (_this$_items5 = this._items[index + 1]) ? void 0 : _this$_items5._getParentKeyOrThrow() : void 0);
856
+ this._items[index]._setParentLink(this, shiftedPosition);
665
857
  }, _createClass(LiveList, [ {
666
858
  key: "length",
667
859
  get: function() {
@@ -685,25 +877,62 @@ var _Symbol$iterator, LiveListIterator = function() {
685
877
  done: !0,
686
878
  value: void 0
687
879
  } : {
688
- value: selfOrRegisterValue(result.value[0])
880
+ value: liveNodeToLson(result.value)
689
881
  };
690
882
  }, LiveListIterator;
691
- }(), _emittedDeprecationWarnings = new Set;
883
+ }();
692
884
 
693
- function deprecate(message, key) {
694
- void 0 === key && (key = message), "production" !== process.env.NODE_ENV && (_emittedDeprecationWarnings.has(key) || (_emittedDeprecationWarnings.add(key),
695
- console.error("DEPRECATION WARNING: " + message)));
885
+ function makeUpdate(liveList, deltaUpdates) {
886
+ return {
887
+ node: liveList,
888
+ type: "LiveList",
889
+ updates: deltaUpdates
890
+ };
696
891
  }
697
892
 
698
- function deprecateIf(condition, message, key) {
699
- void 0 === key && (key = message), "production" !== process.env.NODE_ENV && condition && deprecate(message, key);
893
+ function setDelta(index, item) {
894
+ return {
895
+ index: index,
896
+ type: "set",
897
+ item: item instanceof LiveRegister ? item.data : item
898
+ };
700
899
  }
701
900
 
702
- function throwUsageError(message) {
703
- if ("production" !== process.env.NODE_ENV) {
704
- var usageError = new Error(message);
705
- throw usageError.name = "Usage error", usageError;
706
- }
901
+ function deleteDelta(index) {
902
+ return {
903
+ index: index,
904
+ type: "delete"
905
+ };
906
+ }
907
+
908
+ function insertDelta(index, item) {
909
+ return {
910
+ index: index,
911
+ type: "insert",
912
+ item: item instanceof LiveRegister ? item.data : item
913
+ };
914
+ }
915
+
916
+ function moveDelta(previousIndex, index, item) {
917
+ return {
918
+ index: index,
919
+ type: "move",
920
+ previousIndex: previousIndex,
921
+ item: item instanceof LiveRegister ? item.data : item
922
+ };
923
+ }
924
+
925
+ function sortListItem(items) {
926
+ items.sort((function(itemA, itemB) {
927
+ return comparePosition(itemA._getParentKeyOrThrow(), itemB._getParentKeyOrThrow());
928
+ }));
929
+ }
930
+
931
+ function addIntentAndDeletedIdToOperation(ops, deletedId) {
932
+ if (0 === ops.length) throw new Error("Internal error. Serialized LiveStructure should have at least 1 operation");
933
+ var firstOp = ops[0];
934
+ if (firstOp.type !== exports.OpCode.CREATE_LIST && firstOp.type !== exports.OpCode.CREATE_OBJECT && firstOp.type !== exports.OpCode.CREATE_REGISTER && firstOp.type !== exports.OpCode.CREATE_MAP) throw new Error("Internal error. Serialized LiveStructure first op should be CreateOp");
935
+ firstOp.intent = "set", firstOp.deletedId = deletedId;
707
936
  }
708
937
 
709
938
  _Symbol$iterator = Symbol.iterator;
@@ -711,10 +940,10 @@ _Symbol$iterator = Symbol.iterator;
711
940
  var LiveMap = function(_AbstractCrdt) {
712
941
  function LiveMap(entries) {
713
942
  var _this;
714
- if ((_this = _AbstractCrdt.call(this) || this)._map = void 0, 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([])`."),
943
+ if ((_this = _AbstractCrdt.call(this) || this)._map = void 0, 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([])`."),
715
944
  entries) {
716
945
  for (var _step, mappedEntries = [], _iterator = _createForOfIteratorHelperLoose(entries); !(_step = _iterator()).done; ) {
717
- var entry = _step.value, _value = selfOrRegister(entry[1]);
946
+ var entry = _step.value, _value = lsonToLiveNode(entry[1]);
718
947
  _value._setParentLink(_assertThisInitialized(_this), entry[0]), mappedEntries.push([ entry[0], _value ]);
719
948
  }
720
949
  _this._map = new Map(mappedEntries);
@@ -723,14 +952,12 @@ var LiveMap = function(_AbstractCrdt) {
723
952
  }
724
953
  _inheritsLoose(LiveMap, _AbstractCrdt);
725
954
  var _proto = LiveMap.prototype;
726
- return _proto._serialize = function(parentId, parentKey, doc, intent) {
955
+ return _proto._serialize = function(parentId, parentKey, doc) {
727
956
  if (null == this._id) throw new Error("Cannot serialize item is not attached");
728
- if (null == parentId || null == parentKey) throw new Error("Cannot serialize map if parentId or parentKey is undefined");
729
957
  var ops = [], op = {
730
958
  id: this._id,
731
959
  opId: null == doc ? void 0 : doc.generateOpId(),
732
960
  type: exports.OpCode.CREATE_MAP,
733
- intent: intent,
734
961
  parentId: parentId,
735
962
  parentKey: parentKey
736
963
  };
@@ -748,9 +975,7 @@ var LiveMap = function(_AbstractCrdt) {
748
975
  var children = parentToChildren.get(id);
749
976
  if (null == children) return map;
750
977
  for (var _step3, _iterator3 = _createForOfIteratorHelperLoose(children); !(_step3 = _iterator3()).done; ) {
751
- var entry = _step3.value, crdt = entry[1];
752
- if (null == crdt.parentKey) throw new Error("Tried to deserialize a crdt but it does not have a parentKey and is not the root");
753
- var child = deserialize(entry, parentToChildren, doc);
978
+ var _step3$value = _step3.value, _id = _step3$value[0], crdt = _step3$value[1], child = deserialize([ _id, crdt ], parentToChildren, doc);
754
979
  child._setParentLink(map, crdt.parentKey), map._map.set(crdt.parentKey, child);
755
980
  }
756
981
  return map;
@@ -760,20 +985,24 @@ var LiveMap = function(_AbstractCrdt) {
760
985
  var _step4$value = _step4.value;
761
986
  _step4$value[0];
762
987
  var _value3 = _step4$value[1];
763
- isCrdt(_value3) && _value3._attach(doc.generateId(), doc);
988
+ isLiveNode(_value3) && _value3._attach(doc.generateId(), doc);
764
989
  }
765
- }, _proto._attachChild = function(op, _isLocal) {
990
+ }, _proto._attachChild = function(op) {
766
991
  var _updates;
767
992
  if (null == this._doc) throw new Error("Can't attach child if doc is not present");
768
- var id = op.id, key = op.parentKey, child = creationOpToLiveStructure(op);
993
+ var id = op.id, key = op.parentKey, child = creationOpToLiveNode(op);
769
994
  if (void 0 !== this._doc.getItem(id)) return {
770
995
  modified: !1
771
996
  };
772
997
  var reverse, previousValue = this._map.get(key);
773
- return previousValue ? (reverse = previousValue._serialize(this._id, key), previousValue._detach()) : reverse = [ {
998
+ if (previousValue) {
999
+ var thisId = nn(this._id);
1000
+ reverse = previousValue._serialize(thisId, key), previousValue._detach();
1001
+ } else reverse = [ {
774
1002
  type: exports.OpCode.DELETE_CRDT,
775
1003
  id: id
776
- } ], child._setParentLink(this, key), child._attach(id, this._doc), this._map.set(key, child),
1004
+ } ];
1005
+ return child._setParentLink(this, key), child._attach(id, this._doc), this._map.set(key, child),
777
1006
  {
778
1007
  modified: {
779
1008
  node: this,
@@ -790,7 +1019,7 @@ var LiveMap = function(_AbstractCrdt) {
790
1019
  _step5.value._detach();
791
1020
  }
792
1021
  }, _proto._detachChild = function(child) {
793
- for (var _updates2, _step6, reverse = child._serialize(this._id, child._parentKey, this._doc), _iterator6 = _createForOfIteratorHelperLoose(this._map); !(_step6 = _iterator6()).done; ) {
1022
+ for (var _updates2, _step6, id = nn(this._id), parentKey = nn(child._parentKey), reverse = child._serialize(id, parentKey, this._doc), _iterator6 = _createForOfIteratorHelperLoose(this._map); !(_step6 = _iterator6()).done; ) {
794
1023
  var _step6$value = _step6.value, _key3 = _step6$value[0];
795
1024
  _step6$value[1] === child && this._map.delete(_key3);
796
1025
  }
@@ -798,26 +1027,26 @@ var LiveMap = function(_AbstractCrdt) {
798
1027
  modified: {
799
1028
  node: this,
800
1029
  type: "LiveMap",
801
- updates: (_updates2 = {}, _updates2[child._parentKey] = {
1030
+ updates: (_updates2 = {}, _updates2[parentKey] = {
802
1031
  type: "delete"
803
1032
  }, _updates2)
804
1033
  },
805
1034
  reverse: reverse
806
1035
  };
807
1036
  }, _proto._toSerializedCrdt = function() {
808
- var _this$_parent;
1037
+ if ("HasParent" !== this.parent.type) throw new Error("Cannot serialize LiveMap if parent is missing");
809
1038
  return {
810
1039
  type: exports.CrdtType.MAP,
811
- parentId: null == (_this$_parent = this._parent) ? void 0 : _this$_parent._id,
812
- parentKey: this._parentKey
1040
+ parentId: nn(this.parent.node._id, "Parent node expected to have ID"),
1041
+ parentKey: this.parent.key
813
1042
  };
814
1043
  }, _proto.get = function(key) {
815
1044
  var value = this._map.get(key);
816
- if (null != value) return selfOrRegisterValue(value);
1045
+ if (null != value) return liveNodeToLson(value);
817
1046
  }, _proto.set = function(key, value) {
818
1047
  var oldValue = this._map.get(key);
819
1048
  oldValue && oldValue._detach();
820
- var item = selfOrRegister(value);
1049
+ var item = lsonToLiveNode(value);
821
1050
  if (item._setParentLink(this, key), this._map.set(key, item), this._doc && this._id) {
822
1051
  var _updates3, id = this._doc.generateId();
823
1052
  item._attach(id, this._doc);
@@ -839,8 +1068,8 @@ var LiveMap = function(_AbstractCrdt) {
839
1068
  var item = this._map.get(key);
840
1069
  if (null == item) return !1;
841
1070
  if (item._detach(), this._map.delete(key), this._doc && item._id) {
842
- var _updates4, storageUpdates = new Map;
843
- storageUpdates.set(this._id, {
1071
+ var _updates4, thisId = nn(this._id), storageUpdates = new Map;
1072
+ storageUpdates.set(thisId, {
844
1073
  node: this,
845
1074
  type: "LiveMap",
846
1075
  updates: (_updates4 = {}, _updates4[key] = {
@@ -850,7 +1079,7 @@ var LiveMap = function(_AbstractCrdt) {
850
1079
  type: exports.OpCode.DELETE_CRDT,
851
1080
  id: item._id,
852
1081
  opId: this._doc.generateOpId()
853
- } ], item._serialize(this._id, key), storageUpdates);
1082
+ } ], item._serialize(thisId, key), storageUpdates);
854
1083
  }
855
1084
  return !0;
856
1085
  }, _proto.entries = function() {
@@ -863,7 +1092,7 @@ var LiveMap = function(_AbstractCrdt) {
863
1092
  done: !0,
864
1093
  value: void 0
865
1094
  } : {
866
- value: [ iteratorValue.value[0], selfOrRegisterValue(iteratorValue.value[1]) ]
1095
+ value: [ iteratorValue.value[0], liveNodeToLson(iteratorValue.value[1]) ]
867
1096
  };
868
1097
  }, _ref2;
869
1098
  }, _proto[_Symbol$iterator] = function() {
@@ -880,7 +1109,7 @@ var LiveMap = function(_AbstractCrdt) {
880
1109
  done: !0,
881
1110
  value: void 0
882
1111
  } : {
883
- value: selfOrRegisterValue(iteratorValue.value)
1112
+ value: liveNodeToLson(iteratorValue.value)
884
1113
  };
885
1114
  }, _ref3;
886
1115
  }, _proto.forEach = function(callback) {
@@ -896,7 +1125,15 @@ var LiveMap = function(_AbstractCrdt) {
896
1125
  } ]), LiveMap;
897
1126
  }(AbstractCrdt);
898
1127
 
899
- function creationOpToLiveStructure(op) {
1128
+ function isJsonArray(data) {
1129
+ return Array.isArray(data);
1130
+ }
1131
+
1132
+ function isJsonObject(data) {
1133
+ return null !== data && "object" == typeof data && !isJsonArray(data);
1134
+ }
1135
+
1136
+ function creationOpToLiveNode(op) {
900
1137
  switch (op.type) {
901
1138
  case exports.OpCode.CREATE_REGISTER:
902
1139
  return new LiveRegister(op.data);
@@ -909,6 +1146,9 @@ function creationOpToLiveStructure(op) {
909
1146
 
910
1147
  case exports.OpCode.CREATE_LIST:
911
1148
  return new LiveList;
1149
+
1150
+ default:
1151
+ return assertNever(0, "Unknown creation Op");
912
1152
  }
913
1153
  }
914
1154
 
@@ -932,18 +1172,28 @@ function deserialize(_ref, parentToChildren, doc) {
932
1172
  }
933
1173
  }
934
1174
 
935
- function isCrdt(obj) {
936
- return obj instanceof LiveObject || obj instanceof LiveMap || obj instanceof LiveList || obj instanceof LiveRegister;
1175
+ function isLiveNode(value) {
1176
+ return isLiveList(value) || function(value) {
1177
+ return value instanceof LiveMap;
1178
+ }(value) || isLiveObject(value) || function(value) {
1179
+ return value instanceof LiveRegister;
1180
+ }(value);
1181
+ }
1182
+
1183
+ function isLiveList(value) {
1184
+ return value instanceof LiveList;
937
1185
  }
938
1186
 
939
- function selfOrRegisterValue(obj) {
940
- return obj instanceof LiveRegister ? obj.data : obj;
1187
+ function isLiveObject(value) {
1188
+ return value instanceof LiveObject;
941
1189
  }
942
1190
 
943
- function selfOrRegister(obj) {
944
- if (obj instanceof LiveObject || obj instanceof LiveMap || obj instanceof LiveList) return obj;
945
- if (obj instanceof LiveRegister) throw new Error("Internal error. LiveRegister should not be created from selfOrRegister");
946
- return new LiveRegister(obj);
1191
+ function liveNodeToLson(obj) {
1192
+ return obj instanceof LiveRegister ? obj.data : obj instanceof LiveList || obj instanceof LiveMap || obj instanceof LiveObject ? obj : assertNever(0, "Unknown AbstractCrdt");
1193
+ }
1194
+
1195
+ function lsonToLiveNode(value) {
1196
+ return value instanceof LiveObject || value instanceof LiveMap || value instanceof LiveList ? value : new LiveRegister(value);
947
1197
  }
948
1198
 
949
1199
  function isPlain(value) {
@@ -962,25 +1212,32 @@ function entries(obj) {
962
1212
  return Object.entries(obj);
963
1213
  }
964
1214
 
1215
+ function tryParseJson(rawMessage) {
1216
+ try {
1217
+ return JSON.parse(rawMessage);
1218
+ } catch (e) {
1219
+ return;
1220
+ }
1221
+ }
1222
+
965
1223
  var LiveObject = function(_AbstractCrdt) {
966
1224
  function LiveObject(obj) {
967
1225
  var _this;
968
1226
  for (var key in void 0 === obj && (obj = {}), (_this = _AbstractCrdt.call(this) || this)._map = void 0,
969
1227
  _this._propToLastUpdate = void 0, _this._propToLastUpdate = new Map, obj) {
970
1228
  var value = obj[key];
971
- value instanceof AbstractCrdt && value._setParentLink(_assertThisInitialized(_this), key);
1229
+ isLiveNode(value) && value._setParentLink(_assertThisInitialized(_this), key);
972
1230
  }
973
1231
  return _this._map = new Map(Object.entries(obj)), _this;
974
1232
  }
975
1233
  _inheritsLoose(LiveObject, _AbstractCrdt);
976
1234
  var _proto = LiveObject.prototype;
977
- return _proto._serialize = function(parentId, parentKey, doc, intent) {
1235
+ return _proto._serialize = function(parentId, parentKey, doc) {
978
1236
  if (null == this._id) throw new Error("Cannot serialize item is not attached");
979
1237
  var opId = null == doc ? void 0 : doc.generateOpId(), ops = [], op = void 0 !== parentId && void 0 !== parentKey ? {
980
1238
  type: exports.OpCode.CREATE_OBJECT,
981
1239
  id: this._id,
982
1240
  opId: opId,
983
- intent: intent,
984
1241
  parentId: parentId,
985
1242
  parentKey: parentKey,
986
1243
  data: {}
@@ -988,25 +1245,22 @@ var LiveObject = function(_AbstractCrdt) {
988
1245
  type: exports.OpCode.CREATE_OBJECT,
989
1246
  id: this._id,
990
1247
  opId: opId,
991
- intent: intent,
992
1248
  data: {}
993
1249
  };
994
1250
  ops.push(op);
995
1251
  for (var _step, _iterator = _createForOfIteratorHelperLoose(this._map); !(_step = _iterator()).done; ) {
996
1252
  var _step$value = _step.value, key = _step$value[0], value = _step$value[1];
997
- value instanceof AbstractCrdt ? ops.push.apply(ops, value._serialize(this._id, key, doc)) : op.data[key] = value;
1253
+ isLiveNode(value) ? ops.push.apply(ops, value._serialize(this._id, key, doc)) : op.data[key] = value;
998
1254
  }
999
1255
  return ops;
1000
1256
  }, LiveObject._deserialize = function(_ref, parentToChildren, doc) {
1001
1257
  var id = _ref[0], liveObj = new LiveObject(_ref[1].data);
1002
1258
  return liveObj._attach(id, doc), this._deserializeChildren(liveObj, parentToChildren, doc);
1003
1259
  }, LiveObject._deserializeChildren = function(liveObj, parentToChildren, doc) {
1004
- var children = parentToChildren.get(liveObj._id);
1260
+ var children = parentToChildren.get(nn(liveObj._id));
1005
1261
  if (null == children) return liveObj;
1006
1262
  for (var _step2, _iterator2 = _createForOfIteratorHelperLoose(children); !(_step2 = _iterator2()).done; ) {
1007
- var entry = _step2.value, crdt = entry[1];
1008
- if (null == crdt.parentKey) throw new Error("Tried to deserialize a crdt but it does not have a parentKey and is not the root");
1009
- var child = deserialize(entry, parentToChildren, doc);
1263
+ var _step2$value = _step2.value, id = _step2$value[0], crdt = _step2$value[1], child = deserialize([ id, crdt ], parentToChildren, doc);
1010
1264
  child._setParentLink(liveObj, crdt.parentKey), liveObj._map.set(crdt.parentKey, child);
1011
1265
  }
1012
1266
  return liveObj;
@@ -1016,32 +1270,33 @@ var LiveObject = function(_AbstractCrdt) {
1016
1270
  var _step3$value = _step3.value;
1017
1271
  _step3$value[0];
1018
1272
  var value = _step3$value[1];
1019
- value instanceof AbstractCrdt && value._attach(doc.generateId(), doc);
1273
+ isLiveNode(value) && value._attach(doc.generateId(), doc);
1020
1274
  }
1021
- }, _proto._attachChild = function(op, isLocal) {
1275
+ }, _proto._attachChild = function(op, source) {
1022
1276
  var _updates;
1023
1277
  if (null == this._doc) throw new Error("Can't attach child if doc is not present");
1024
- var id = op.id, parentKey = op.parentKey, opId = op.opId, key = parentKey, child = creationOpToLiveStructure(op);
1278
+ var id = op.id, opId = op.opId, key = op.parentKey, child = creationOpToLiveNode(op);
1025
1279
  if (void 0 !== this._doc.getItem(id)) return this._propToLastUpdate.get(key) === opId && this._propToLastUpdate.delete(key),
1026
1280
  {
1027
1281
  modified: !1
1028
1282
  };
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),
1283
+ if (source === exports.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
1284
  {
1031
1285
  modified: !1
1032
1286
  }) : {
1033
1287
  modified: !1
1034
1288
  };
1035
- var reverse, previousValue = this._map.get(key);
1036
- if (isCrdt(previousValue)) reverse = previousValue._serialize(this._id, key), previousValue._detach(); else if (void 0 === previousValue) reverse = [ {
1289
+ var reverse, thisId = nn(this._id), previousValue = this._map.get(key);
1290
+ if (isLiveNode(previousValue)) reverse = previousValue._serialize(thisId, key),
1291
+ previousValue._detach(); else if (void 0 === previousValue) reverse = [ {
1037
1292
  type: exports.OpCode.DELETE_OBJECT_KEY,
1038
- id: this._id,
1293
+ id: thisId,
1039
1294
  key: key
1040
1295
  } ]; else {
1041
1296
  var _data;
1042
1297
  reverse = [ {
1043
1298
  type: exports.OpCode.UPDATE_OBJECT,
1044
- id: this._id,
1299
+ id: thisId,
1045
1300
  data: (_data = {}, _data[key] = previousValue, _data)
1046
1301
  } ];
1047
1302
  }
@@ -1058,7 +1313,7 @@ var LiveObject = function(_AbstractCrdt) {
1058
1313
  };
1059
1314
  }, _proto._detachChild = function(child) {
1060
1315
  if (child) {
1061
- for (var _updates2, _step4, reverse = child._serialize(this._id, child._parentKey, this._doc), _iterator4 = _createForOfIteratorHelperLoose(this._map); !(_step4 = _iterator4()).done; ) {
1316
+ for (var _updates2, _step4, id = nn(this._id), parentKey = nn(child._parentKey), reverse = child._serialize(id, parentKey, this._doc), _iterator4 = _createForOfIteratorHelperLoose(this._map); !(_step4 = _iterator4()).done; ) {
1062
1317
  var _step4$value = _step4.value, key = _step4$value[0];
1063
1318
  _step4$value[1] === child && this._map.delete(key);
1064
1319
  }
@@ -1066,7 +1321,7 @@ var LiveObject = function(_AbstractCrdt) {
1066
1321
  modified: {
1067
1322
  node: this,
1068
1323
  type: "LiveObject",
1069
- updates: (_updates2 = {}, _updates2[child._parentKey] = {
1324
+ updates: (_updates2 = {}, _updates2[parentKey] = {
1070
1325
  type: "delete"
1071
1326
  }, _updates2)
1072
1327
  },
@@ -1076,51 +1331,46 @@ var LiveObject = function(_AbstractCrdt) {
1076
1331
  return {
1077
1332
  modified: !1
1078
1333
  };
1079
- }, _proto._detachChildren = function() {
1080
- for (var _step5, _iterator5 = _createForOfIteratorHelperLoose(this._map); !(_step5 = _iterator5()).done; ) {
1081
- var _step5$value = _step5.value, key = _step5$value[0], value = _step5$value[1];
1082
- this._map.delete(key), value._detach();
1083
- }
1084
1334
  }, _proto._detach = function() {
1085
1335
  _AbstractCrdt.prototype._detach.call(this);
1086
- for (var _step6, _iterator6 = _createForOfIteratorHelperLoose(this._map.values()); !(_step6 = _iterator6()).done; ) {
1087
- var value = _step6.value;
1088
- isCrdt(value) && value._detach();
1336
+ for (var _step5, _iterator5 = _createForOfIteratorHelperLoose(this._map.values()); !(_step5 = _iterator5()).done; ) {
1337
+ var value = _step5.value;
1338
+ isLiveNode(value) && value._detach();
1089
1339
  }
1090
1340
  }, _proto._apply = function(op, isLocal) {
1091
1341
  return op.type === exports.OpCode.UPDATE_OBJECT ? this._applyUpdate(op, isLocal) : op.type === exports.OpCode.DELETE_OBJECT_KEY ? this._applyDeleteObjectKey(op) : _AbstractCrdt.prototype._apply.call(this, op, isLocal);
1092
1342
  }, _proto._toSerializedCrdt = function() {
1093
- for (var _this$_parent, _step7, data = {}, _iterator7 = _createForOfIteratorHelperLoose(this._map); !(_step7 = _iterator7()).done; ) {
1094
- var _step7$value = _step7.value, key = _step7$value[0], value = _step7$value[1];
1095
- value instanceof AbstractCrdt == !1 && (data[key] = value);
1343
+ for (var _step6, data = {}, _iterator6 = _createForOfIteratorHelperLoose(this._map); !(_step6 = _iterator6()).done; ) {
1344
+ var _step6$value = _step6.value, key = _step6$value[0], value = _step6$value[1];
1345
+ isLiveNode(value) || (data[key] = value);
1096
1346
  }
1097
- return void 0 !== (null == (_this$_parent = this._parent) ? void 0 : _this$_parent._id) && void 0 !== this._parentKey ? {
1347
+ return "HasParent" === this.parent.type && this.parent.node._id ? {
1098
1348
  type: exports.CrdtType.OBJECT,
1099
- parentId: this._parent._id,
1100
- parentKey: this._parentKey,
1349
+ parentId: this.parent.node._id,
1350
+ parentKey: this.parent.key,
1101
1351
  data: data
1102
1352
  } : {
1103
1353
  type: exports.CrdtType.OBJECT,
1104
1354
  data: data
1105
1355
  };
1106
1356
  }, _proto._applyUpdate = function(op, isLocal) {
1107
- var isModified = !1, reverse = [], reverseUpdate = {
1357
+ var isModified = !1, id = nn(this._id), reverse = [], reverseUpdate = {
1108
1358
  type: exports.OpCode.UPDATE_OBJECT,
1109
- id: this._id,
1359
+ id: id,
1110
1360
  data: {}
1111
1361
  };
1112
1362
  for (var key in reverse.push(reverseUpdate), op.data) {
1113
1363
  var oldValue = this._map.get(key);
1114
- oldValue instanceof AbstractCrdt ? (reverse.push.apply(reverse, oldValue._serialize(this._id, key)),
1364
+ isLiveNode(oldValue) ? (reverse.push.apply(reverse, oldValue._serialize(id, key)),
1115
1365
  oldValue._detach()) : void 0 !== oldValue ? reverseUpdate.data[key] = oldValue : void 0 === oldValue && reverse.push({
1116
1366
  type: exports.OpCode.DELETE_OBJECT_KEY,
1117
- id: this._id,
1367
+ id: id,
1118
1368
  key: key
1119
1369
  });
1120
1370
  }
1121
1371
  var updateDelta = {};
1122
1372
  for (var _key2 in op.data) {
1123
- if (isLocal) this._propToLastUpdate.set(_key2, op.opId); else {
1373
+ if (isLocal) this._propToLastUpdate.set(_key2, nn(op.opId)); else {
1124
1374
  if (null != this._propToLastUpdate.get(_key2)) {
1125
1375
  if (this._propToLastUpdate.get(_key2) === op.opId) {
1126
1376
  this._propToLastUpdate.delete(_key2);
@@ -1131,7 +1381,7 @@ var LiveObject = function(_AbstractCrdt) {
1131
1381
  isModified = !0;
1132
1382
  }
1133
1383
  var _oldValue = this._map.get(_key2);
1134
- isCrdt(_oldValue) && _oldValue._detach(), isModified = !0, updateDelta[_key2] = {
1384
+ isLiveNode(_oldValue) && _oldValue._detach(), isModified = !0, updateDelta[_key2] = {
1135
1385
  type: "update"
1136
1386
  }, this._map.set(_key2, op.data[_key2]);
1137
1387
  }
@@ -1154,12 +1404,12 @@ var LiveObject = function(_AbstractCrdt) {
1154
1404
  if (void 0 !== this._propToLastUpdate.get(key)) return {
1155
1405
  modified: !1
1156
1406
  };
1157
- var oldValue = this._map.get(key), reverse = [];
1158
- if (isCrdt(oldValue)) reverse = oldValue._serialize(this._id, op.key), oldValue._detach(); else if (void 0 !== oldValue) {
1407
+ var oldValue = this._map.get(key), id = nn(this._id), reverse = [];
1408
+ if (isLiveNode(oldValue)) reverse = oldValue._serialize(id, op.key), oldValue._detach(); else if (void 0 !== oldValue) {
1159
1409
  var _data2;
1160
1410
  reverse = [ {
1161
1411
  type: exports.OpCode.UPDATE_OBJECT,
1162
- id: this._id,
1412
+ id: id,
1163
1413
  data: (_data2 = {}, _data2[key] = oldValue, _data2)
1164
1414
  } ];
1165
1415
  }
@@ -1189,10 +1439,10 @@ var LiveObject = function(_AbstractCrdt) {
1189
1439
  }, _proto.delete = function(key) {
1190
1440
  var _updates4, keyAsString = key, oldValue = this._map.get(keyAsString);
1191
1441
  if (void 0 !== oldValue) {
1192
- if (null == this._doc || null == this._id) return oldValue instanceof AbstractCrdt && oldValue._detach(),
1442
+ if (null == this._doc || null == this._id) return isLiveNode(oldValue) && oldValue._detach(),
1193
1443
  void this._map.delete(keyAsString);
1194
1444
  var reverse, _data3;
1195
- if (oldValue instanceof AbstractCrdt) oldValue._detach(), reverse = oldValue._serialize(this._id, keyAsString); else reverse = [ {
1445
+ if (isLiveNode(oldValue)) oldValue._detach(), reverse = oldValue._serialize(this._id, keyAsString); else reverse = [ {
1196
1446
  type: exports.OpCode.UPDATE_OBJECT,
1197
1447
  data: (_data3 = {}, _data3[keyAsString] = oldValue, _data3),
1198
1448
  id: this._id
@@ -1222,19 +1472,19 @@ var LiveObject = function(_AbstractCrdt) {
1222
1472
  }, updateDelta = {};
1223
1473
  for (var _key3 in overrides) {
1224
1474
  var _oldValue2 = this._map.get(_key3);
1225
- _oldValue2 instanceof AbstractCrdt ? (reverseOps.push.apply(reverseOps, _oldValue2._serialize(this._id, _key3)),
1475
+ isLiveNode(_oldValue2) ? (reverseOps.push.apply(reverseOps, _oldValue2._serialize(this._id, _key3)),
1226
1476
  _oldValue2._detach()) : void 0 === _oldValue2 ? reverseOps.push({
1227
1477
  type: exports.OpCode.DELETE_OBJECT_KEY,
1228
1478
  id: this._id,
1229
1479
  key: _key3
1230
1480
  }) : reverseUpdateOp.data[_key3] = _oldValue2;
1231
1481
  var _newValue = overrides[_key3];
1232
- if (_newValue instanceof AbstractCrdt) {
1482
+ if (isLiveNode(_newValue)) {
1233
1483
  _newValue._setParentLink(this, _key3), _newValue._attach(this._doc.generateId(), this._doc);
1234
1484
  var newAttachChildOps = _newValue._serialize(this._id, _key3, this._doc), createCrdtOp = newAttachChildOps.find((function(op) {
1235
1485
  return op.parentId === _this2._id;
1236
1486
  }));
1237
- createCrdtOp && this._propToLastUpdate.set(_key3, createCrdtOp.opId), ops.push.apply(ops, newAttachChildOps);
1487
+ createCrdtOp && this._propToLastUpdate.set(_key3, nn(createCrdtOp.opId)), ops.push.apply(ops, newAttachChildOps);
1238
1488
  } else updatedProps[_key3] = _newValue, this._propToLastUpdate.set(_key3, opId);
1239
1489
  this._map.set(_key3, _newValue), updateDelta[_key3] = {
1240
1490
  type: "update"
@@ -1255,30 +1505,37 @@ var LiveObject = function(_AbstractCrdt) {
1255
1505
  }), this._doc.dispatch(ops, reverseOps, storageUpdates);
1256
1506
  } else for (var key in overrides) {
1257
1507
  var oldValue = this._map.get(key);
1258
- oldValue instanceof AbstractCrdt && oldValue._detach();
1508
+ isLiveNode(oldValue) && oldValue._detach();
1259
1509
  var newValue = overrides[key];
1260
- newValue instanceof AbstractCrdt && newValue._setParentLink(this, key), this._map.set(key, newValue);
1510
+ isLiveNode(newValue) && newValue._setParentLink(this, key), this._map.set(key, newValue);
1261
1511
  }
1262
1512
  }, LiveObject;
1263
1513
  }(AbstractCrdt);
1264
1514
 
1265
- exports.AbstractCrdt = AbstractCrdt, exports.LiveList = LiveList, exports.LiveMap = LiveMap,
1266
- exports.LiveObject = LiveObject, exports.LiveRegister = LiveRegister, exports._createForOfIteratorHelperLoose = _createForOfIteratorHelperLoose,
1515
+ exports.LiveList = LiveList, exports.LiveMap = LiveMap, exports.LiveObject = LiveObject,
1516
+ exports.LiveRegister = LiveRegister, exports._createForOfIteratorHelperLoose = _createForOfIteratorHelperLoose,
1267
1517
  exports._extends = _extends, exports._inheritsLoose = _inheritsLoose, exports._objectWithoutPropertiesLoose = function(source, excluded) {
1268
1518
  if (null == source) return {};
1269
1519
  var key, i, target = {}, sourceKeys = Object.keys(source);
1270
1520
  for (i = 0; i < sourceKeys.length; i++) key = sourceKeys[i], excluded.indexOf(key) >= 0 || (target[key] = source[key]);
1271
1521
  return target;
1272
- }, exports._wrapNativeSuper = _wrapNativeSuper, exports.assertNever = function(_value, errmsg) {
1273
- throw new Error(errmsg);
1522
+ }, exports._wrapNativeSuper = _wrapNativeSuper, exports.assertNever = assertNever,
1523
+ exports.b64decode = function(b64value) {
1524
+ try {
1525
+ var formattedValue = b64value.replace(/-/g, "+").replace(/_/g, "/");
1526
+ return decodeURIComponent(atob(formattedValue).split("").map((function(c) {
1527
+ return "%" + ("00" + c.charCodeAt(0).toString(16)).slice(-2);
1528
+ })).join(""));
1529
+ } catch (err) {
1530
+ return atob(b64value);
1531
+ }
1274
1532
  }, exports.compact = function(items) {
1275
1533
  return items.filter((function(item) {
1276
1534
  return null != item;
1277
1535
  }));
1278
- }, exports.comparePosition = comparePosition, exports.deprecate = deprecate, exports.deprecateIf = deprecateIf,
1279
- exports.errorIf = function(condition, message) {
1280
- "production" !== process.env.NODE_ENV && condition && throwUsageError(message);
1281
- }, exports.findNonSerializableValue = function findNonSerializableValue(value, path) {
1536
+ }, exports.comparePosition = comparePosition, exports.deprecate = deprecate, exports.deprecateIf = function(condition, message, key) {
1537
+ void 0 === key && (key = message), "production" !== process.env.NODE_ENV && condition && deprecate(message, key);
1538
+ }, exports.errorIf = errorIf, exports.findNonSerializableValue = function findNonSerializableValue(value, path) {
1282
1539
  if (void 0 === path && (path = ""), !isPlain) return {
1283
1540
  path: path || "root",
1284
1541
  value: value
@@ -1312,7 +1569,7 @@ exports.errorIf = function(condition, message) {
1312
1569
  })), crdt.parentKey !== currentCrdt.parentKey && ops.push({
1313
1570
  type: exports.OpCode.SET_PARENT_KEY,
1314
1571
  id: id,
1315
- parentKey: crdt.parentKey
1572
+ parentKey: nn(crdt.parentKey, "Parent key must not be missing")
1316
1573
  }); else switch (crdt.type) {
1317
1574
  case exports.CrdtType.REGISTER:
1318
1575
  ops.push({
@@ -1357,14 +1614,15 @@ exports.errorIf = function(condition, message) {
1357
1614
  }
1358
1615
  })), ops;
1359
1616
  }, exports.isChildCrdt = isChildCrdt, exports.isJsonArray = isJsonArray, exports.isJsonObject = isJsonObject,
1617
+ exports.isLiveList = isLiveList, exports.isLiveNode = isLiveNode, exports.isLiveObject = isLiveObject,
1360
1618
  exports.isRootCrdt = function(crdt) {
1361
1619
  return crdt.type === exports.CrdtType.OBJECT && !isChildCrdt(crdt);
1362
1620
  }, exports.isSameNodeOrChildOf = function isSameNodeOrChildOf(node, parent) {
1363
- return node === parent || !!node._parent && isSameNodeOrChildOf(node._parent, parent);
1621
+ return node === parent || "HasParent" === node.parent.type && isSameNodeOrChildOf(node.parent.node, parent);
1364
1622
  }, exports.isTokenValid = function(token) {
1365
1623
  var tokenParts = token.split(".");
1366
1624
  if (3 !== tokenParts.length) return !1;
1367
- var data = parseJson(atob(tokenParts[1]));
1625
+ var data = tryParseJson(atob(tokenParts[1]));
1368
1626
  return !(void 0 === data || !isJsonObject(data) || "number" != typeof data.exp) && !(Date.now() / 1e3 > data.exp - 300);
1369
1627
  }, exports.makePosition = makePosition, exports.mergeStorageUpdates = function(first, second) {
1370
1628
  return first ? "LiveObject" === first.type && "LiveObject" === second.type ? function(first, second) {
@@ -1388,9 +1646,9 @@ exports.isRootCrdt = function(crdt) {
1388
1646
  updates: first.updates.concat(second.updates)
1389
1647
  });
1390
1648
  }(first, second) : second : second;
1391
- }, exports.parseJson = parseJson, exports.remove = function(array, item) {
1649
+ }, exports.nn = nn, exports.remove = function(array, item) {
1392
1650
  for (var i = 0; i < array.length; i++) if (array[i] === item) {
1393
1651
  array.splice(i, 1);
1394
1652
  break;
1395
1653
  }
1396
- }, exports.throwUsageError = throwUsageError;
1654
+ }, exports.throwUsageError = throwUsageError, exports.tryParseJson = tryParseJson;