@liveblocks/client 0.14.4 → 0.15.0-alpha.3

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.
@@ -1,7 +1,8 @@
1
1
  import { Op, SerializedCrdt } from "./live";
2
+ import { StorageUpdate } from "./types";
2
3
  export declare type ApplyResult = {
3
4
  reverse: Op[];
4
- modified: AbstractCrdt;
5
+ modified: StorageUpdate;
5
6
  } | {
6
7
  modified: false;
7
8
  };
@@ -11,7 +12,7 @@ export interface Doc {
11
12
  getItem: (id: string) => AbstractCrdt | undefined;
12
13
  addItem: (id: string, item: AbstractCrdt) => void;
13
14
  deleteItem: (id: string) => void;
14
- dispatch: (ops: Op[], reverseOps: Op[], modified: AbstractCrdt[]) => void;
15
+ dispatch: (ops: Op[], reverseOps: Op[], storageUpdates: Map<string, StorageUpdate>) => void;
15
16
  }
16
17
  export declare abstract class AbstractCrdt {
17
18
  #private;
@@ -54,7 +55,7 @@ export declare abstract class AbstractCrdt {
54
55
  /**
55
56
  * INTERNAL
56
57
  */
57
- abstract _detachChild(crdt: AbstractCrdt): void;
58
+ abstract _detachChild(crdt: AbstractCrdt): ApplyResult;
58
59
  /**
59
60
  * INTERNAL
60
61
  */
@@ -63,4 +64,5 @@ export declare abstract class AbstractCrdt {
63
64
  * INTERNAL
64
65
  */
65
66
  abstract _toSerializedCrdt(): SerializedCrdt;
67
+ abstract _getType(): string;
66
68
  }
@@ -49,10 +49,7 @@ export class AbstractCrdt {
49
49
  switch (op.type) {
50
50
  case OpType.DeleteCrdt: {
51
51
  if (this._parent != null && this._parentKey != null) {
52
- const parent = this._parent;
53
- const reverse = this._serialize(this._parent._id, this._parentKey, __classPrivateFieldGet(this, _AbstractCrdt_doc, "f"));
54
- this._parent._detachChild(this);
55
- return { modified: parent, reverse };
52
+ return this._parent._detachChild(this);
56
53
  }
57
54
  return { modified: false };
58
55
  }
@@ -14,6 +14,7 @@ export declare class LiveList<T> extends AbstractCrdt {
14
14
  * INTERNAL
15
15
  */
16
16
  _serialize(parentId?: string, parentKey?: string, doc?: Doc): Op[];
17
+ _indexOfPosition(position: string): number;
17
18
  /**
18
19
  * INTERNAL
19
20
  */
@@ -29,15 +30,19 @@ export declare class LiveList<T> extends AbstractCrdt {
29
30
  /**
30
31
  * INTERNAL
31
32
  */
32
- _detachChild(child: AbstractCrdt): void;
33
+ _detachChild(child: AbstractCrdt): ApplyResult;
33
34
  /**
34
35
  * INTERNAL
35
36
  */
36
- _setChildKey(key: string, child: AbstractCrdt): void;
37
+ _setChildKey(key: string, child: AbstractCrdt, previousKey: string): ApplyResult;
37
38
  /**
38
39
  * INTERNAL
39
40
  */
40
41
  _apply(op: Op, isLocal: boolean): ApplyResult;
42
+ /**
43
+ * INTERNAL
44
+ */
45
+ _getType(): string;
41
46
  /**
42
47
  * INTERNAL
43
48
  */
@@ -73,6 +78,7 @@ export declare class LiveList<T> extends AbstractCrdt {
73
78
  * Returns an Array of all the elements in the LiveList.
74
79
  */
75
80
  toArray(): T[];
81
+ toCrdtArray(): AbstractCrdt[];
76
82
  /**
77
83
  * Tests whether all elements pass the test implemented by the provided function.
78
84
  * @param predicate Function to test for each element, taking two arguments (the element and its index).
@@ -14,6 +14,7 @@ import { AbstractCrdt } from "./AbstractCrdt";
14
14
  import { deserialize, selfOrRegister, selfOrRegisterValue } from "./utils";
15
15
  import { OpType, CrdtType, } from "./live";
16
16
  import { makePosition, compare } from "./position";
17
+ import { LiveRegister } from "./LiveRegister";
17
18
  /**
18
19
  * The LiveList class represents an ordered collection of items that is synchorinized across clients.
19
20
  */
@@ -72,6 +73,9 @@ export class LiveList extends AbstractCrdt {
72
73
  }
73
74
  return ops;
74
75
  }
76
+ _indexOfPosition(position) {
77
+ return __classPrivateFieldGet(this, _LiveList_items, "f").findIndex((item) => item[1] === position);
78
+ }
75
79
  /**
76
80
  * INTERNAL
77
81
  */
@@ -123,24 +127,47 @@ export class LiveList extends AbstractCrdt {
123
127
  }
124
128
  __classPrivateFieldGet(this, _LiveList_items, "f").push([child, newKey]);
125
129
  __classPrivateFieldGet(this, _LiveList_items, "f").sort((itemA, itemB) => compare(itemA[1], itemB[1]));
126
- return { reverse: [{ type: OpType.DeleteCrdt, id }], modified: this };
130
+ const newIndex = __classPrivateFieldGet(this, _LiveList_items, "f").findIndex((entry) => entry[1] === newKey);
131
+ return {
132
+ reverse: [{ type: OpType.DeleteCrdt, id }],
133
+ modified: {
134
+ node: this,
135
+ type: "LiveList",
136
+ updates: [
137
+ {
138
+ index: newIndex,
139
+ type: "insert",
140
+ item: child instanceof LiveRegister ? child.data : child,
141
+ },
142
+ ],
143
+ },
144
+ };
127
145
  }
128
146
  /**
129
147
  * INTERNAL
130
148
  */
131
149
  _detachChild(child) {
132
- const indexToDelete = __classPrivateFieldGet(this, _LiveList_items, "f").findIndex((item) => item[0] === child);
133
- __classPrivateFieldGet(this, _LiveList_items, "f").splice(indexToDelete, 1);
134
150
  if (child) {
151
+ const reverse = child._serialize(this._id, child._parentKey, this._doc);
152
+ const indexToDelete = __classPrivateFieldGet(this, _LiveList_items, "f").findIndex((item) => item[0] === child);
153
+ __classPrivateFieldGet(this, _LiveList_items, "f").splice(indexToDelete, 1);
135
154
  child._detach();
155
+ const storageUpdate = {
156
+ node: this,
157
+ type: "LiveList",
158
+ updates: [{ index: indexToDelete, type: "delete" }],
159
+ };
160
+ return { modified: storageUpdate, reverse };
136
161
  }
162
+ return { modified: false };
137
163
  }
138
164
  /**
139
165
  * INTERNAL
140
166
  */
141
- _setChildKey(key, child) {
167
+ _setChildKey(key, child, previousKey) {
142
168
  var _a;
143
169
  child._setParentLink(this, key);
170
+ const previousIndex = __classPrivateFieldGet(this, _LiveList_items, "f").findIndex((entry) => entry[0]._id === child._id);
144
171
  const index = __classPrivateFieldGet(this, _LiveList_items, "f").findIndex((entry) => entry[1] === key);
145
172
  // Assign a temporary position until we get the fix from the backend
146
173
  if (index !== -1) {
@@ -151,6 +178,31 @@ export class LiveList extends AbstractCrdt {
151
178
  item[1] = key;
152
179
  }
153
180
  __classPrivateFieldGet(this, _LiveList_items, "f").sort((itemA, itemB) => compare(itemA[1], itemB[1]));
181
+ const newIndex = __classPrivateFieldGet(this, _LiveList_items, "f").findIndex((entry) => entry[0]._id === child._id);
182
+ const updatesDelta = newIndex === previousIndex
183
+ ? []
184
+ : [
185
+ {
186
+ index: newIndex,
187
+ item: child instanceof LiveRegister ? child.data : child,
188
+ previousIndex: previousIndex,
189
+ type: "move",
190
+ },
191
+ ];
192
+ return {
193
+ modified: {
194
+ node: this,
195
+ type: "LiveList",
196
+ updates: updatesDelta,
197
+ },
198
+ reverse: [
199
+ {
200
+ type: OpType.SetParentKey,
201
+ id: item === null || item === void 0 ? void 0 : item[0]._id,
202
+ parentKey: previousKey,
203
+ },
204
+ ],
205
+ };
154
206
  }
155
207
  /**
156
208
  * INTERNAL
@@ -158,6 +210,12 @@ export class LiveList extends AbstractCrdt {
158
210
  _apply(op, isLocal) {
159
211
  return super._apply(op, isLocal);
160
212
  }
213
+ /**
214
+ * INTERNAL
215
+ */
216
+ _getType() {
217
+ return "LiveList";
218
+ }
161
219
  /**
162
220
  * INTERNAL
163
221
  */
@@ -189,7 +247,7 @@ export class LiveList extends AbstractCrdt {
189
247
  */
190
248
  insert(element, index) {
191
249
  if (index < 0 || index > __classPrivateFieldGet(this, _LiveList_items, "f").length) {
192
- throw new Error(`Cannot delete list item at index "${index}". index should be between 0 and ${__classPrivateFieldGet(this, _LiveList_items, "f").length}`);
250
+ throw new Error(`Cannot insert list item at index "${index}". index should be between 0 and ${__classPrivateFieldGet(this, _LiveList_items, "f").length}`);
193
251
  }
194
252
  let before = __classPrivateFieldGet(this, _LiveList_items, "f")[index - 1] ? __classPrivateFieldGet(this, _LiveList_items, "f")[index - 1][1] : undefined;
195
253
  let after = __classPrivateFieldGet(this, _LiveList_items, "f")[index] ? __classPrivateFieldGet(this, _LiveList_items, "f")[index][1] : undefined;
@@ -198,10 +256,23 @@ export class LiveList extends AbstractCrdt {
198
256
  value._setParentLink(this, position);
199
257
  __classPrivateFieldGet(this, _LiveList_items, "f").push([value, position]);
200
258
  __classPrivateFieldGet(this, _LiveList_items, "f").sort((itemA, itemB) => compare(itemA[1], itemB[1]));
259
+ const newIndex = __classPrivateFieldGet(this, _LiveList_items, "f").findIndex((entry) => entry[1] === position);
201
260
  if (this._doc && this._id) {
202
261
  const id = this._doc.generateId();
203
262
  value._attach(id, this._doc);
204
- this._doc.dispatch(value._serialize(this._id, position, this._doc), [{ type: OpType.DeleteCrdt, id }], [this]);
263
+ const storageUpdates = new Map();
264
+ storageUpdates.set(this._id, {
265
+ node: this,
266
+ type: "LiveList",
267
+ updates: [
268
+ {
269
+ index: newIndex,
270
+ item: value instanceof LiveRegister ? value.data : value,
271
+ type: "insert",
272
+ },
273
+ ],
274
+ });
275
+ this._doc.dispatch(value._serialize(this._id, position, this._doc), [{ type: OpType.DeleteCrdt, id }], storageUpdates);
205
276
  }
206
277
  }
207
278
  /**
@@ -242,7 +313,21 @@ export class LiveList extends AbstractCrdt {
242
313
  item[1] = position;
243
314
  item[0]._setParentLink(this, position);
244
315
  __classPrivateFieldGet(this, _LiveList_items, "f").sort((itemA, itemB) => compare(itemA[1], itemB[1]));
316
+ const newIndex = __classPrivateFieldGet(this, _LiveList_items, "f").findIndex((entry) => entry[1] === position);
245
317
  if (this._doc && this._id) {
318
+ const storageUpdates = new Map();
319
+ storageUpdates.set(this._id, {
320
+ node: this,
321
+ type: "LiveList",
322
+ updates: [
323
+ {
324
+ index: newIndex,
325
+ previousIndex: index,
326
+ item: item[0],
327
+ type: "move",
328
+ },
329
+ ],
330
+ });
246
331
  this._doc.dispatch([
247
332
  {
248
333
  type: OpType.SetParentKey,
@@ -256,7 +341,7 @@ export class LiveList extends AbstractCrdt {
256
341
  id: item[0]._id,
257
342
  parentKey: previousPosition,
258
343
  },
259
- ], [this]);
344
+ ], storageUpdates);
260
345
  }
261
346
  }
262
347
  /**
@@ -273,13 +358,19 @@ export class LiveList extends AbstractCrdt {
273
358
  if (this._doc) {
274
359
  const childRecordId = item[0]._id;
275
360
  if (childRecordId) {
361
+ const storageUpdates = new Map();
362
+ storageUpdates.set(this._id, {
363
+ node: this,
364
+ type: "LiveList",
365
+ updates: [{ index: index, type: "delete" }],
366
+ });
276
367
  this._doc.dispatch([
277
368
  {
278
369
  id: childRecordId,
279
370
  opId: this._doc.generateOpId(),
280
371
  type: OpType.DeleteCrdt,
281
372
  },
282
- ], item[0]._serialize(this._id, item[1]), [this]);
373
+ ], item[0]._serialize(this._id, item[1]), storageUpdates);
283
374
  }
284
375
  }
285
376
  }
@@ -287,16 +378,26 @@ export class LiveList extends AbstractCrdt {
287
378
  if (this._doc) {
288
379
  let ops = [];
289
380
  let reverseOps = [];
381
+ let updateDelta = [];
382
+ let i = 0;
290
383
  for (const item of __classPrivateFieldGet(this, _LiveList_items, "f")) {
291
384
  item[0]._detach();
292
385
  const childId = item[0]._id;
293
386
  if (childId) {
294
387
  ops.push({ id: childId, type: OpType.DeleteCrdt });
295
388
  reverseOps.push(...item[0]._serialize(this._id, item[1]));
389
+ updateDelta.push({ index: i, type: "delete" });
296
390
  }
391
+ i++;
297
392
  }
298
393
  __classPrivateFieldSet(this, _LiveList_items, [], "f");
299
- this._doc.dispatch(ops, reverseOps, [this]);
394
+ const storageUpdates = new Map();
395
+ storageUpdates.set(this._id, {
396
+ node: this,
397
+ type: "LiveList",
398
+ updates: updateDelta,
399
+ });
400
+ this._doc.dispatch(ops, reverseOps, storageUpdates);
300
401
  }
301
402
  else {
302
403
  for (const item of __classPrivateFieldGet(this, _LiveList_items, "f")) {
@@ -311,6 +412,9 @@ export class LiveList extends AbstractCrdt {
311
412
  toArray() {
312
413
  return __classPrivateFieldGet(this, _LiveList_items, "f").map((entry) => selfOrRegisterValue(entry[0]));
313
414
  }
415
+ toCrdtArray() {
416
+ return __classPrivateFieldGet(this, _LiveList_items, "f").map((entry) => entry[0]);
417
+ }
314
418
  /**
315
419
  * Tests whether all elements pass the test implemented by the provided function.
316
420
  * @param predicate Function to test for each element, taking two arguments (the element and its index).
@@ -31,7 +31,11 @@ export declare class LiveMap<TKey extends string, TValue> extends AbstractCrdt {
31
31
  /**
32
32
  * INTERNAL
33
33
  */
34
- _detachChild(child: AbstractCrdt): void;
34
+ _detachChild(child: AbstractCrdt): ApplyResult;
35
+ /**
36
+ * INTERNAL
37
+ */
38
+ _getType(): string;
35
39
  /**
36
40
  * INTERNAL
37
41
  */
@@ -116,7 +116,14 @@ export class LiveMap extends AbstractCrdt {
116
116
  child._setParentLink(this, key);
117
117
  child._attach(id, this._doc);
118
118
  __classPrivateFieldGet(this, _LiveMap_map, "f").set(key, child);
119
- return { modified: this, reverse };
119
+ return {
120
+ modified: {
121
+ node: this,
122
+ type: "LiveMap",
123
+ updates: { [key]: { type: "update" } },
124
+ },
125
+ reverse,
126
+ };
120
127
  }
121
128
  /**
122
129
  * INTERNAL
@@ -131,12 +138,25 @@ export class LiveMap extends AbstractCrdt {
131
138
  * INTERNAL
132
139
  */
133
140
  _detachChild(child) {
141
+ const reverse = child._serialize(this._id, child._parentKey, this._doc);
134
142
  for (const [key, value] of __classPrivateFieldGet(this, _LiveMap_map, "f")) {
135
143
  if (value === child) {
136
144
  __classPrivateFieldGet(this, _LiveMap_map, "f").delete(key);
137
145
  }
138
146
  }
139
147
  child._detach();
148
+ const storageUpdate = {
149
+ node: this,
150
+ type: "LiveMap",
151
+ updates: { [child._parentKey]: { type: "delete" } },
152
+ };
153
+ return { modified: storageUpdate, reverse };
154
+ }
155
+ /**
156
+ * INTERNAL
157
+ */
158
+ _getType() {
159
+ return "LiveMap";
140
160
  }
141
161
  /**
142
162
  * INTERNAL
@@ -177,9 +197,15 @@ export class LiveMap extends AbstractCrdt {
177
197
  if (this._doc && this._id) {
178
198
  const id = this._doc.generateId();
179
199
  item._attach(id, this._doc);
200
+ const storageUpdates = new Map();
201
+ storageUpdates.set(this._id, {
202
+ node: this,
203
+ type: "LiveMap",
204
+ updates: { [key]: { type: "update" } },
205
+ });
180
206
  this._doc.dispatch(item._serialize(this._id, key, this._doc), oldValue
181
207
  ? oldValue._serialize(this._id, key)
182
- : [{ type: OpType.DeleteCrdt, id }], [this]);
208
+ : [{ type: OpType.DeleteCrdt, id }], storageUpdates);
183
209
  }
184
210
  }
185
211
  /**
@@ -207,13 +233,19 @@ export class LiveMap extends AbstractCrdt {
207
233
  }
208
234
  item._detach();
209
235
  if (this._doc && item._id) {
236
+ const storageUpdates = new Map();
237
+ storageUpdates.set(this._id, {
238
+ node: this,
239
+ type: "LiveMap",
240
+ updates: { [key]: { type: "delete" } },
241
+ });
210
242
  this._doc.dispatch([
211
243
  {
212
244
  type: OpType.DeleteCrdt,
213
245
  id: item._id,
214
246
  opId: this._doc.generateOpId(),
215
247
  },
216
- ], item._serialize(this._id, key), [this]);
248
+ ], item._serialize(this._id, key), storageUpdates);
217
249
  }
218
250
  __classPrivateFieldGet(this, _LiveMap_map, "f").delete(key);
219
251
  return true;
@@ -31,7 +31,7 @@ export declare class LiveObject<T extends Record<string, any> = Record<string, a
31
31
  /**
32
32
  * INTERNAL
33
33
  */
34
- _detachChild(child: AbstractCrdt): void;
34
+ _detachChild(child: AbstractCrdt): ApplyResult;
35
35
  /**
36
36
  * INTERNAL
37
37
  */
@@ -48,6 +48,10 @@ export declare class LiveObject<T extends Record<string, any> = Record<string, a
48
48
  * INTERNAL
49
49
  */
50
50
  _toSerializedCrdt(): SerializedCrdt;
51
+ /**
52
+ * INTERNAL
53
+ */
54
+ _getType(): string;
51
55
  /**
52
56
  * Transform the LiveObject into a javascript object
53
57
  */
@@ -152,20 +152,37 @@ export class LiveObject extends AbstractCrdt {
152
152
  __classPrivateFieldGet(this, _LiveObject_map, "f").set(key, child);
153
153
  child._setParentLink(this, key);
154
154
  child._attach(id, this._doc);
155
- return { reverse, modified: this };
155
+ return {
156
+ reverse,
157
+ modified: {
158
+ node: this,
159
+ type: "LiveObject",
160
+ updates: { [key]: { type: "update" } },
161
+ },
162
+ };
156
163
  }
157
164
  /**
158
165
  * INTERNAL
159
166
  */
160
167
  _detachChild(child) {
161
- for (const [key, value] of __classPrivateFieldGet(this, _LiveObject_map, "f")) {
162
- if (value === child) {
163
- __classPrivateFieldGet(this, _LiveObject_map, "f").delete(key);
164
- }
165
- }
166
168
  if (child) {
169
+ const reverse = child._serialize(this._id, child._parentKey, this._doc);
170
+ for (const [key, value] of __classPrivateFieldGet(this, _LiveObject_map, "f")) {
171
+ if (value === child) {
172
+ __classPrivateFieldGet(this, _LiveObject_map, "f").delete(key);
173
+ }
174
+ }
167
175
  child._detach();
176
+ const storageUpdate = {
177
+ node: this,
178
+ type: "LiveObject",
179
+ updates: {
180
+ [child._parentKey]: { type: "delete" },
181
+ },
182
+ };
183
+ return { modified: storageUpdate, reverse };
168
184
  }
185
+ return { modified: false };
169
186
  }
170
187
  /**
171
188
  * INTERNAL
@@ -211,6 +228,12 @@ export class LiveObject extends AbstractCrdt {
211
228
  data: this.toObject(),
212
229
  };
213
230
  }
231
+ /**
232
+ * INTERNAL
233
+ */
234
+ _getType() {
235
+ return "LiveObject";
236
+ }
214
237
  /**
215
238
  * Transform the LiveObject into a javascript object
216
239
  */
@@ -265,6 +288,12 @@ export class LiveObject extends AbstractCrdt {
265
288
  ];
266
289
  }
267
290
  __classPrivateFieldGet(this, _LiveObject_map, "f").delete(keyAsString);
291
+ const storageUpdates = new Map();
292
+ storageUpdates.set(this._id, {
293
+ node: this,
294
+ type: "LiveObject",
295
+ updates: { [key]: { type: "delete" } },
296
+ });
268
297
  this._doc.dispatch([
269
298
  {
270
299
  type: OpType.DeleteObjectKey,
@@ -272,7 +301,7 @@ export class LiveObject extends AbstractCrdt {
272
301
  id: this._id,
273
302
  opId: this._doc.generateOpId(),
274
303
  },
275
- ], reverse, [this]);
304
+ ], reverse, storageUpdates);
276
305
  }
277
306
  /**
278
307
  * Adds or updates multiple properties at once with an object.
@@ -302,6 +331,7 @@ export class LiveObject extends AbstractCrdt {
302
331
  type: OpType.UpdateObject,
303
332
  data: {},
304
333
  };
334
+ const updateDelta = {};
305
335
  for (const key in overrides) {
306
336
  const oldValue = __classPrivateFieldGet(this, _LiveObject_map, "f").get(key);
307
337
  if (oldValue instanceof AbstractCrdt) {
@@ -330,6 +360,7 @@ export class LiveObject extends AbstractCrdt {
330
360
  __classPrivateFieldGet(this, _LiveObject_propToLastUpdate, "f").set(key, opId);
331
361
  }
332
362
  __classPrivateFieldGet(this, _LiveObject_map, "f").set(key, newValue);
363
+ updateDelta[key] = { type: "update" };
333
364
  }
334
365
  if (Object.keys(reverseUpdateOp.data).length !== 0) {
335
366
  reverseOps.unshift(reverseUpdateOp);
@@ -342,7 +373,13 @@ export class LiveObject extends AbstractCrdt {
342
373
  data: updatedProps,
343
374
  });
344
375
  }
345
- this._doc.dispatch(ops, reverseOps, [this]);
376
+ const storageUpdates = new Map();
377
+ storageUpdates.set(this._id, {
378
+ node: this,
379
+ type: "LiveObject",
380
+ updates: updateDelta,
381
+ });
382
+ this._doc.dispatch(ops, reverseOps, storageUpdates);
346
383
  }
347
384
  }
348
385
  _LiveObject_map = new WeakMap(), _LiveObject_propToLastUpdate = new WeakMap(), _LiveObject_instances = new WeakSet(), _LiveObject_applyUpdate = function _LiveObject_applyUpdate(op, isLocal) {
@@ -367,6 +404,7 @@ _LiveObject_map = new WeakMap(), _LiveObject_propToLastUpdate = new WeakMap(), _
367
404
  reverse.push({ type: OpType.DeleteObjectKey, id: this._id, key });
368
405
  }
369
406
  }
407
+ let updateDelta = {};
370
408
  for (const key in op.data) {
371
409
  if (isLocal) {
372
410
  __classPrivateFieldGet(this, _LiveObject_propToLastUpdate, "f").set(key, op.opId);
@@ -389,12 +427,22 @@ _LiveObject_map = new WeakMap(), _LiveObject_propToLastUpdate = new WeakMap(), _
389
427
  oldValue._detach();
390
428
  }
391
429
  isModified = true;
430
+ updateDelta[key] = { type: "update" };
392
431
  __classPrivateFieldGet(this, _LiveObject_map, "f").set(key, op.data[key]);
393
432
  }
394
433
  if (Object.keys(reverseUpdate.data).length !== 0) {
395
434
  reverse.unshift(reverseUpdate);
396
435
  }
397
- return isModified ? { modified: this, reverse } : { modified: false };
436
+ return isModified
437
+ ? {
438
+ modified: {
439
+ node: this,
440
+ type: "LiveObject",
441
+ updates: updateDelta,
442
+ },
443
+ reverse,
444
+ }
445
+ : { modified: false };
398
446
  }, _LiveObject_applyDeleteObjectKey = function _LiveObject_applyDeleteObjectKey(op) {
399
447
  const key = op.key;
400
448
  // If property does not exist, exit without notifying
@@ -422,5 +470,12 @@ _LiveObject_map = new WeakMap(), _LiveObject_propToLastUpdate = new WeakMap(), _
422
470
  ];
423
471
  }
424
472
  __classPrivateFieldGet(this, _LiveObject_map, "f").delete(key);
425
- return { modified: this, reverse };
473
+ return {
474
+ modified: {
475
+ node: this,
476
+ type: "LiveObject",
477
+ updates: { [op.key]: { type: "delete" } },
478
+ },
479
+ reverse,
480
+ };
426
481
  };
@@ -20,6 +20,10 @@ export declare class LiveRegister<TValue = any> extends AbstractCrdt {
20
20
  */
21
21
  _toSerializedCrdt(): SerializedCrdt;
22
22
  _attachChild(id: string, key: string, crdt: AbstractCrdt, opId: string, isLocal: boolean): ApplyResult;
23
- _detachChild(crdt: AbstractCrdt): void;
23
+ _detachChild(crdt: AbstractCrdt): ApplyResult;
24
24
  _apply(op: Op, isLocal: boolean): ApplyResult;
25
+ /**
26
+ * INTERNAL
27
+ */
28
+ _getType(): string;
25
29
  }
@@ -74,5 +74,11 @@ export class LiveRegister extends AbstractCrdt {
74
74
  _apply(op, isLocal) {
75
75
  return super._apply(op, isLocal);
76
76
  }
77
+ /**
78
+ * INTERNAL
79
+ */
80
+ _getType() {
81
+ return "LiveRegister";
82
+ }
77
83
  }
78
84
  _LiveRegister_data = new WeakMap();
@@ -0,0 +1,9 @@
1
+ import { LiveList } from "./LiveList";
2
+ import { LiveObject } from "./LiveObject";
3
+ import { StorageUpdate } from "./types";
4
+ export declare function liveObjectToJson(liveObject: LiveObject<any>): any;
5
+ export declare function liveNodeToJson(value: any): any;
6
+ export declare function patchLiveList<T>(liveList: LiveList<T>, prev: Array<T>, next: Array<T>): void;
7
+ export declare function patchLiveObjectKey<T>(liveObject: LiveObject<T>, key: keyof T, prev: any, next: any): void;
8
+ export declare function patchLiveObject<T extends Record<string, any>>(root: LiveObject<T>, prev: T, next: T): void;
9
+ export declare function patchImmutableObject<T>(state: T, updates: StorageUpdate[]): T;