@liveblocks/client 0.13.3 → 0.15.0-alpha.2

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.
Files changed (45) hide show
  1. package/lib/cjs/AbstractCrdt.d.ts +13 -7
  2. package/lib/cjs/AbstractCrdt.js +2 -5
  3. package/lib/cjs/LiveList.d.ts +16 -6
  4. package/lib/cjs/LiveList.js +148 -17
  5. package/lib/cjs/LiveMap.d.ts +12 -4
  6. package/lib/cjs/LiveMap.js +57 -7
  7. package/lib/cjs/LiveObject.d.ts +22 -8
  8. package/lib/cjs/LiveObject.js +109 -24
  9. package/lib/cjs/LiveRegister.d.ts +13 -5
  10. package/lib/cjs/LiveRegister.js +23 -4
  11. package/lib/cjs/immutable.d.ts +1 -0
  12. package/lib/cjs/immutable.js +64 -6
  13. package/lib/cjs/index.d.ts +1 -0
  14. package/lib/cjs/index.js +8 -1
  15. package/lib/cjs/live.d.ts +7 -0
  16. package/lib/cjs/room.d.ts +9 -1
  17. package/lib/cjs/room.js +131 -70
  18. package/lib/cjs/types.d.ts +25 -0
  19. package/lib/cjs/utils.d.ts +4 -1
  20. package/lib/cjs/utils.js +101 -1
  21. package/lib/esm/AbstractCrdt.d.ts +13 -7
  22. package/lib/esm/AbstractCrdt.js +2 -5
  23. package/lib/esm/LiveList.d.ts +16 -6
  24. package/lib/esm/LiveList.js +149 -18
  25. package/lib/esm/LiveMap.d.ts +12 -4
  26. package/lib/esm/LiveMap.js +57 -7
  27. package/lib/esm/LiveObject.d.ts +22 -8
  28. package/lib/esm/LiveObject.js +109 -24
  29. package/lib/esm/LiveRegister.d.ts +13 -5
  30. package/lib/esm/LiveRegister.js +24 -5
  31. package/lib/esm/immutable.d.ts +1 -0
  32. package/lib/esm/immutable.js +63 -6
  33. package/lib/esm/index.d.ts +1 -0
  34. package/lib/esm/index.js +1 -0
  35. package/lib/esm/live.d.ts +7 -0
  36. package/lib/esm/room.d.ts +9 -1
  37. package/lib/esm/room.js +132 -71
  38. package/lib/esm/types.d.ts +25 -0
  39. package/lib/esm/utils.d.ts +4 -1
  40. package/lib/esm/utils.js +99 -1
  41. package/package.json +2 -2
  42. package/lib/cjs/immutable/index.d.ts +0 -7
  43. package/lib/cjs/immutable/index.js +0 -214
  44. package/lib/esm/immutable/index.d.ts +0 -7
  45. package/lib/esm/immutable/index.js +0 -207
@@ -1,7 +1,8 @@
1
- import { Op } from "./live";
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
  };
@@ -10,7 +11,7 @@ export interface Doc {
10
11
  generateOpId: () => string;
11
12
  addItem: (id: string, item: AbstractCrdt) => void;
12
13
  deleteItem: (id: string) => void;
13
- dispatch: (ops: Op[], reverseOps: Op[], modified: AbstractCrdt[]) => void;
14
+ dispatch: (ops: Op[], reverseOps: Op[], storageUpdates: Map<string, StorageUpdate>) => void;
14
15
  }
15
16
  export declare abstract class AbstractCrdt {
16
17
  #private;
@@ -33,7 +34,7 @@ export declare abstract class AbstractCrdt {
33
34
  /**
34
35
  * INTERNAL
35
36
  */
36
- _apply(op: Op): ApplyResult;
37
+ _apply(op: Op, isLocal: boolean): ApplyResult;
37
38
  /**
38
39
  * INTERNAL
39
40
  */
@@ -45,7 +46,7 @@ export declare abstract class AbstractCrdt {
45
46
  /**
46
47
  * INTERNAL
47
48
  */
48
- abstract _attachChild(id: string, key: string, crdt: AbstractCrdt): ApplyResult;
49
+ abstract _attachChild(id: string, key: string, crdt: AbstractCrdt, isLocal: boolean): ApplyResult;
49
50
  /**
50
51
  * INTERNAL
51
52
  */
@@ -53,9 +54,14 @@ export declare abstract class AbstractCrdt {
53
54
  /**
54
55
  * INTERNAL
55
56
  */
56
- abstract _detachChild(crdt: AbstractCrdt): void;
57
+ abstract _detachChild(crdt: AbstractCrdt): ApplyResult;
57
58
  /**
58
59
  * INTERNAL
59
60
  */
60
- abstract _serialize(parentId: string, parentKey: string): Op[];
61
+ abstract _serialize(parentId: string, parentKey: string, doc?: Doc): Op[];
62
+ /**
63
+ * INTERNAL
64
+ */
65
+ abstract _toSerializedCrdt(): SerializedCrdt;
66
+ abstract _getType(): string;
61
67
  }
@@ -48,14 +48,11 @@ class AbstractCrdt {
48
48
  /**
49
49
  * INTERNAL
50
50
  */
51
- _apply(op) {
51
+ _apply(op, isLocal) {
52
52
  switch (op.type) {
53
53
  case live_1.OpType.DeleteCrdt: {
54
54
  if (this._parent != null && this._parentKey != null) {
55
- const parent = this._parent;
56
- const reverse = this._serialize(this._parent._id, this._parentKey);
57
- this._parent._detachChild(this);
58
- return { modified: parent, reverse };
55
+ return this._parent._detachChild(this);
59
56
  }
60
57
  return { modified: false };
61
58
  }
@@ -1,5 +1,5 @@
1
1
  import { AbstractCrdt, Doc, ApplyResult } from "./AbstractCrdt";
2
- import { SerializedList, SerializedCrdtWithId, Op } from "./live";
2
+ import { SerializedList, SerializedCrdtWithId, Op, SerializedCrdt } from "./live";
3
3
  /**
4
4
  * The LiveList class represents an ordered collection of items that is synchorinized across clients.
5
5
  */
@@ -13,7 +13,8 @@ export declare class LiveList<T> extends AbstractCrdt {
13
13
  /**
14
14
  * INTERNAL
15
15
  */
16
- _serialize(parentId?: string, parentKey?: string): Op[];
16
+ _serialize(parentId?: string, parentKey?: string, doc?: Doc): Op[];
17
+ _indexOfPosition(position: string): number;
17
18
  /**
18
19
  * INTERNAL
19
20
  */
@@ -25,19 +26,27 @@ export declare class LiveList<T> extends AbstractCrdt {
25
26
  /**
26
27
  * INTERNAL
27
28
  */
28
- _attachChild(id: string, key: string, child: AbstractCrdt): ApplyResult;
29
+ _attachChild(id: string, key: string, child: AbstractCrdt, isLocal: boolean): ApplyResult;
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
- _apply(op: Op): ApplyResult;
41
+ _apply(op: Op, isLocal: boolean): ApplyResult;
42
+ /**
43
+ * INTERNAL
44
+ */
45
+ _getType(): string;
46
+ /**
47
+ * INTERNAL
48
+ */
49
+ _toSerializedCrdt(): SerializedCrdt;
41
50
  /**
42
51
  * Returns the number of elements.
43
52
  */
@@ -69,6 +78,7 @@ export declare class LiveList<T> extends AbstractCrdt {
69
78
  * Returns an Array of all the elements in the LiveList.
70
79
  */
71
80
  toArray(): T[];
81
+ toCrdtArray(): AbstractCrdt[];
72
82
  /**
73
83
  * Tests whether all elements pass the test implemented by the provided function.
74
84
  * @param predicate Function to test for each element, taking two arguments (the element and its index).
@@ -17,6 +17,7 @@ const AbstractCrdt_1 = require("./AbstractCrdt");
17
17
  const utils_1 = require("./utils");
18
18
  const live_1 = require("./live");
19
19
  const position_1 = require("./position");
20
+ const LiveRegister_1 = require("./LiveRegister");
20
21
  /**
21
22
  * The LiveList class represents an ordered collection of items that is synchorinized across clients.
22
23
  */
@@ -54,7 +55,7 @@ class LiveList extends AbstractCrdt_1.AbstractCrdt {
54
55
  /**
55
56
  * INTERNAL
56
57
  */
57
- _serialize(parentId, parentKey) {
58
+ _serialize(parentId, parentKey, doc) {
58
59
  if (this._id == null) {
59
60
  throw new Error("Cannot serialize item is not attached");
60
61
  }
@@ -64,16 +65,20 @@ class LiveList extends AbstractCrdt_1.AbstractCrdt {
64
65
  const ops = [];
65
66
  const op = {
66
67
  id: this._id,
68
+ opId: doc === null || doc === void 0 ? void 0 : doc.generateOpId(),
67
69
  type: live_1.OpType.CreateList,
68
70
  parentId,
69
71
  parentKey,
70
72
  };
71
73
  ops.push(op);
72
74
  for (const [value, key] of __classPrivateFieldGet(this, _LiveList_items, "f")) {
73
- ops.push(...value._serialize(this._id, key));
75
+ ops.push(...value._serialize(this._id, key, doc));
74
76
  }
75
77
  return ops;
76
78
  }
79
+ _indexOfPosition(position) {
80
+ return __classPrivateFieldGet(this, _LiveList_items, "f").findIndex((item) => item[1] === position);
81
+ }
77
82
  /**
78
83
  * INTERNAL
79
84
  */
@@ -95,7 +100,7 @@ class LiveList extends AbstractCrdt_1.AbstractCrdt {
95
100
  /**
96
101
  * INTERNAL
97
102
  */
98
- _attachChild(id, key, child) {
103
+ _attachChild(id, key, child, isLocal) {
99
104
  var _a;
100
105
  if (this._doc == null) {
101
106
  throw new Error("Can't attach child if doc is not present");
@@ -103,30 +108,66 @@ class LiveList extends AbstractCrdt_1.AbstractCrdt {
103
108
  child._attach(id, this._doc);
104
109
  child._setParentLink(this, key);
105
110
  const index = __classPrivateFieldGet(this, _LiveList_items, "f").findIndex((entry) => entry[1] === key);
106
- // Assign a temporary position until we get the fix from the backend
111
+ let newKey = key;
112
+ // If there is a conflict
107
113
  if (index !== -1) {
108
- __classPrivateFieldGet(this, _LiveList_items, "f")[index][1] = (0, position_1.makePosition)(key, (_a = __classPrivateFieldGet(this, _LiveList_items, "f")[index + 1]) === null || _a === void 0 ? void 0 : _a[1]);
114
+ if (isLocal) {
115
+ // If change is local => assign a temporary position to newly attached child
116
+ let before = __classPrivateFieldGet(this, _LiveList_items, "f")[index] ? __classPrivateFieldGet(this, _LiveList_items, "f")[index][1] : undefined;
117
+ let after = __classPrivateFieldGet(this, _LiveList_items, "f")[index + 1]
118
+ ? __classPrivateFieldGet(this, _LiveList_items, "f")[index + 1][1]
119
+ : undefined;
120
+ newKey = (0, position_1.makePosition)(before, after);
121
+ child._setParentLink(this, newKey);
122
+ }
123
+ else {
124
+ // If change is remote => assign a temporary position to existing child until we get the fix from the backend
125
+ __classPrivateFieldGet(this, _LiveList_items, "f")[index][1] = (0, position_1.makePosition)(key, (_a = __classPrivateFieldGet(this, _LiveList_items, "f")[index + 1]) === null || _a === void 0 ? void 0 : _a[1]);
126
+ }
109
127
  }
110
- __classPrivateFieldGet(this, _LiveList_items, "f").push([child, key]);
128
+ __classPrivateFieldGet(this, _LiveList_items, "f").push([child, newKey]);
111
129
  __classPrivateFieldGet(this, _LiveList_items, "f").sort((itemA, itemB) => (0, position_1.compare)(itemA[1], itemB[1]));
112
- return { reverse: [{ type: live_1.OpType.DeleteCrdt, id }], modified: this };
130
+ const newIndex = __classPrivateFieldGet(this, _LiveList_items, "f").findIndex((entry) => entry[1] === newKey);
131
+ return {
132
+ reverse: [{ type: live_1.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_1.LiveRegister ? child.data : child,
141
+ },
142
+ ],
143
+ },
144
+ };
113
145
  }
114
146
  /**
115
147
  * INTERNAL
116
148
  */
117
149
  _detachChild(child) {
118
- const indexToDelete = __classPrivateFieldGet(this, _LiveList_items, "f").findIndex((item) => item[0] === child);
119
- __classPrivateFieldGet(this, _LiveList_items, "f").splice(indexToDelete, 1);
120
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);
121
154
  child._detach();
155
+ const storageUpdate = {
156
+ node: this,
157
+ type: "LiveList",
158
+ updates: [{ index: indexToDelete, type: "delete" }],
159
+ };
160
+ return { modified: storageUpdate, reverse };
122
161
  }
162
+ return { modified: false };
123
163
  }
124
164
  /**
125
165
  * INTERNAL
126
166
  */
127
- _setChildKey(key, child) {
167
+ _setChildKey(key, child, previousKey) {
128
168
  var _a;
129
169
  child._setParentLink(this, key);
170
+ const previousIndex = __classPrivateFieldGet(this, _LiveList_items, "f").findIndex((entry) => entry[0]._id === child._id);
130
171
  const index = __classPrivateFieldGet(this, _LiveList_items, "f").findIndex((entry) => entry[1] === key);
131
172
  // Assign a temporary position until we get the fix from the backend
132
173
  if (index !== -1) {
@@ -137,12 +178,54 @@ class LiveList extends AbstractCrdt_1.AbstractCrdt {
137
178
  item[1] = key;
138
179
  }
139
180
  __classPrivateFieldGet(this, _LiveList_items, "f").sort((itemA, itemB) => (0, position_1.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_1.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: live_1.OpType.SetParentKey,
201
+ id: item === null || item === void 0 ? void 0 : item[0]._id,
202
+ parentKey: previousKey,
203
+ },
204
+ ],
205
+ };
140
206
  }
141
207
  /**
142
208
  * INTERNAL
143
209
  */
144
- _apply(op) {
145
- return super._apply(op);
210
+ _apply(op, isLocal) {
211
+ return super._apply(op, isLocal);
212
+ }
213
+ /**
214
+ * INTERNAL
215
+ */
216
+ _getType() {
217
+ return "LiveList";
218
+ }
219
+ /**
220
+ * INTERNAL
221
+ */
222
+ _toSerializedCrdt() {
223
+ var _a;
224
+ return {
225
+ type: live_1.CrdtType.List,
226
+ parentId: (_a = this._parent) === null || _a === void 0 ? void 0 : _a._id,
227
+ parentKey: this._parentKey,
228
+ };
146
229
  }
147
230
  /**
148
231
  * Returns the number of elements.
@@ -164,7 +247,7 @@ class LiveList extends AbstractCrdt_1.AbstractCrdt {
164
247
  */
165
248
  insert(element, index) {
166
249
  if (index < 0 || index > __classPrivateFieldGet(this, _LiveList_items, "f").length) {
167
- 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}`);
168
251
  }
169
252
  let before = __classPrivateFieldGet(this, _LiveList_items, "f")[index - 1] ? __classPrivateFieldGet(this, _LiveList_items, "f")[index - 1][1] : undefined;
170
253
  let after = __classPrivateFieldGet(this, _LiveList_items, "f")[index] ? __classPrivateFieldGet(this, _LiveList_items, "f")[index][1] : undefined;
@@ -173,10 +256,23 @@ class LiveList extends AbstractCrdt_1.AbstractCrdt {
173
256
  value._setParentLink(this, position);
174
257
  __classPrivateFieldGet(this, _LiveList_items, "f").push([value, position]);
175
258
  __classPrivateFieldGet(this, _LiveList_items, "f").sort((itemA, itemB) => (0, position_1.compare)(itemA[1], itemB[1]));
259
+ const newIndex = __classPrivateFieldGet(this, _LiveList_items, "f").findIndex((entry) => entry[1] === position);
176
260
  if (this._doc && this._id) {
177
261
  const id = this._doc.generateId();
178
262
  value._attach(id, this._doc);
179
- this._doc.dispatch(value._serialize(this._id, position), [{ type: live_1.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_1.LiveRegister ? value.data : value,
271
+ type: "insert",
272
+ },
273
+ ],
274
+ });
275
+ this._doc.dispatch(value._serialize(this._id, position, this._doc), [{ type: live_1.OpType.DeleteCrdt, id }], storageUpdates);
180
276
  }
181
277
  }
182
278
  /**
@@ -217,11 +313,26 @@ class LiveList extends AbstractCrdt_1.AbstractCrdt {
217
313
  item[1] = position;
218
314
  item[0]._setParentLink(this, position);
219
315
  __classPrivateFieldGet(this, _LiveList_items, "f").sort((itemA, itemB) => (0, position_1.compare)(itemA[1], itemB[1]));
316
+ const newIndex = __classPrivateFieldGet(this, _LiveList_items, "f").findIndex((entry) => entry[1] === position);
220
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
+ });
221
331
  this._doc.dispatch([
222
332
  {
223
333
  type: live_1.OpType.SetParentKey,
224
334
  id: item[0]._id,
335
+ opId: this._doc.generateOpId(),
225
336
  parentKey: position,
226
337
  },
227
338
  ], [
@@ -230,7 +341,7 @@ class LiveList extends AbstractCrdt_1.AbstractCrdt {
230
341
  id: item[0]._id,
231
342
  parentKey: previousPosition,
232
343
  },
233
- ], [this]);
344
+ ], storageUpdates);
234
345
  }
235
346
  }
236
347
  /**
@@ -247,12 +358,19 @@ class LiveList extends AbstractCrdt_1.AbstractCrdt {
247
358
  if (this._doc) {
248
359
  const childRecordId = item[0]._id;
249
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
+ });
250
367
  this._doc.dispatch([
251
368
  {
252
369
  id: childRecordId,
370
+ opId: this._doc.generateOpId(),
253
371
  type: live_1.OpType.DeleteCrdt,
254
372
  },
255
- ], item[0]._serialize(this._id, item[1]), [this]);
373
+ ], item[0]._serialize(this._id, item[1]), storageUpdates);
256
374
  }
257
375
  }
258
376
  }
@@ -260,16 +378,26 @@ class LiveList extends AbstractCrdt_1.AbstractCrdt {
260
378
  if (this._doc) {
261
379
  let ops = [];
262
380
  let reverseOps = [];
381
+ let updateDelta = [];
382
+ let i = 0;
263
383
  for (const item of __classPrivateFieldGet(this, _LiveList_items, "f")) {
264
384
  item[0]._detach();
265
385
  const childId = item[0]._id;
266
386
  if (childId) {
267
387
  ops.push({ id: childId, type: live_1.OpType.DeleteCrdt });
268
388
  reverseOps.push(...item[0]._serialize(this._id, item[1]));
389
+ updateDelta.push({ index: i, type: "delete" });
269
390
  }
391
+ i++;
270
392
  }
271
393
  __classPrivateFieldSet(this, _LiveList_items, [], "f");
272
- 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);
273
401
  }
274
402
  else {
275
403
  for (const item of __classPrivateFieldGet(this, _LiveList_items, "f")) {
@@ -284,6 +412,9 @@ class LiveList extends AbstractCrdt_1.AbstractCrdt {
284
412
  toArray() {
285
413
  return __classPrivateFieldGet(this, _LiveList_items, "f").map((entry) => (0, utils_1.selfOrRegisterValue)(entry[0]));
286
414
  }
415
+ toCrdtArray() {
416
+ return __classPrivateFieldGet(this, _LiveList_items, "f").map((entry) => entry[0]);
417
+ }
287
418
  /**
288
419
  * Tests whether all elements pass the test implemented by the provided function.
289
420
  * @param predicate Function to test for each element, taking two arguments (the element and its index).
@@ -1,5 +1,5 @@
1
1
  import { AbstractCrdt, Doc, ApplyResult } from "./AbstractCrdt";
2
- import { Op, SerializedCrdtWithId } from "./live";
2
+ import { Op, SerializedCrdtWithId, SerializedCrdt } from "./live";
3
3
  /**
4
4
  * The LiveMap class is similar to a JavaScript Map that is synchronized on all clients.
5
5
  * Keys should be a string, and values should be serializable to JSON.
@@ -11,7 +11,7 @@ export declare class LiveMap<TKey extends string, TValue> extends AbstractCrdt {
11
11
  /**
12
12
  * INTERNAL
13
13
  */
14
- _serialize(parentId?: string, parentKey?: string): Op[];
14
+ _serialize(parentId?: string, parentKey?: string, doc?: Doc): Op[];
15
15
  /**
16
16
  * INTERNAL
17
17
  */
@@ -23,7 +23,7 @@ export declare class LiveMap<TKey extends string, TValue> extends AbstractCrdt {
23
23
  /**
24
24
  * INTERNAL
25
25
  */
26
- _attachChild(id: string, key: TKey, child: AbstractCrdt): ApplyResult;
26
+ _attachChild(id: string, key: TKey, child: AbstractCrdt, isLocal: boolean): ApplyResult;
27
27
  /**
28
28
  * INTERNAL
29
29
  */
@@ -31,7 +31,15 @@ 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;
39
+ /**
40
+ * INTERNAL
41
+ */
42
+ _toSerializedCrdt(): SerializedCrdt;
35
43
  /**
36
44
  * Returns a specified element from the LiveMap.
37
45
  * @param key The key of the element to return.
@@ -41,7 +41,7 @@ class LiveMap extends AbstractCrdt_1.AbstractCrdt {
41
41
  /**
42
42
  * INTERNAL
43
43
  */
44
- _serialize(parentId, parentKey) {
44
+ _serialize(parentId, parentKey, doc) {
45
45
  if (this._id == null) {
46
46
  throw new Error("Cannot serialize item is not attached");
47
47
  }
@@ -51,13 +51,14 @@ class LiveMap extends AbstractCrdt_1.AbstractCrdt {
51
51
  const ops = [];
52
52
  const op = {
53
53
  id: this._id,
54
+ opId: doc === null || doc === void 0 ? void 0 : doc.generateOpId(),
54
55
  type: live_1.OpType.CreateMap,
55
56
  parentId,
56
57
  parentKey,
57
58
  };
58
59
  ops.push(op);
59
60
  for (const [key, value] of __classPrivateFieldGet(this, _LiveMap_map, "f")) {
60
- ops.push(...value._serialize(this._id, key));
61
+ ops.push(...value._serialize(this._id, key, doc));
61
62
  }
62
63
  return ops;
63
64
  }
@@ -99,7 +100,7 @@ class LiveMap extends AbstractCrdt_1.AbstractCrdt {
99
100
  /**
100
101
  * INTERNAL
101
102
  */
102
- _attachChild(id, key, child) {
103
+ _attachChild(id, key, child, isLocal) {
103
104
  if (this._doc == null) {
104
105
  throw new Error("Can't attach child if doc is not present");
105
106
  }
@@ -115,7 +116,14 @@ class LiveMap extends AbstractCrdt_1.AbstractCrdt {
115
116
  child._setParentLink(this, key);
116
117
  child._attach(id, this._doc);
117
118
  __classPrivateFieldGet(this, _LiveMap_map, "f").set(key, child);
118
- return { modified: this, reverse };
119
+ return {
120
+ modified: {
121
+ node: this,
122
+ type: "LiveMap",
123
+ updates: { [key]: { type: "update" } },
124
+ },
125
+ reverse,
126
+ };
119
127
  }
120
128
  /**
121
129
  * INTERNAL
@@ -130,12 +138,36 @@ class LiveMap extends AbstractCrdt_1.AbstractCrdt {
130
138
  * INTERNAL
131
139
  */
132
140
  _detachChild(child) {
141
+ const reverse = child._serialize(this._id, child._parentKey, this._doc);
133
142
  for (const [key, value] of __classPrivateFieldGet(this, _LiveMap_map, "f")) {
134
143
  if (value === child) {
135
144
  __classPrivateFieldGet(this, _LiveMap_map, "f").delete(key);
136
145
  }
137
146
  }
138
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";
160
+ }
161
+ /**
162
+ * INTERNAL
163
+ */
164
+ _toSerializedCrdt() {
165
+ var _a;
166
+ return {
167
+ type: live_1.CrdtType.Map,
168
+ parentId: (_a = this._parent) === null || _a === void 0 ? void 0 : _a._id,
169
+ parentKey: this._parentKey,
170
+ };
139
171
  }
140
172
  /**
141
173
  * Returns a specified element from the LiveMap.
@@ -165,9 +197,15 @@ class LiveMap extends AbstractCrdt_1.AbstractCrdt {
165
197
  if (this._doc && this._id) {
166
198
  const id = this._doc.generateId();
167
199
  item._attach(id, this._doc);
168
- this._doc.dispatch(item._serialize(this._id, key), oldValue
200
+ const storageUpdates = new Map();
201
+ storageUpdates.set(this._id, {
202
+ node: this,
203
+ type: "LiveMap",
204
+ updates: { [key]: { type: "update" } },
205
+ });
206
+ this._doc.dispatch(item._serialize(this._id, key, this._doc), oldValue
169
207
  ? oldValue._serialize(this._id, key)
170
- : [{ type: live_1.OpType.DeleteCrdt, id }], [this]);
208
+ : [{ type: live_1.OpType.DeleteCrdt, id }], storageUpdates);
171
209
  }
172
210
  }
173
211
  /**
@@ -195,7 +233,19 @@ class LiveMap extends AbstractCrdt_1.AbstractCrdt {
195
233
  }
196
234
  item._detach();
197
235
  if (this._doc && item._id) {
198
- this._doc.dispatch([{ type: live_1.OpType.DeleteCrdt, id: item._id }], item._serialize(this._id, key), [this]);
236
+ const storageUpdates = new Map();
237
+ storageUpdates.set(this._id, {
238
+ node: this,
239
+ type: "LiveMap",
240
+ updates: { [key]: { type: "delete" } },
241
+ });
242
+ this._doc.dispatch([
243
+ {
244
+ type: live_1.OpType.DeleteCrdt,
245
+ id: item._id,
246
+ opId: this._doc.generateOpId(),
247
+ },
248
+ ], item._serialize(this._id, key), storageUpdates);
199
249
  }
200
250
  __classPrivateFieldGet(this, _LiveMap_map, "f").delete(key);
201
251
  return true;
@@ -1,5 +1,5 @@
1
1
  import { AbstractCrdt, Doc, ApplyResult } from "./AbstractCrdt";
2
- import { Op, SerializedCrdtWithId } from "./live";
2
+ import { Op, SerializedCrdt, SerializedCrdtWithId } from "./live";
3
3
  /**
4
4
  * The LiveObject class is similar to a JavaScript object that is synchronized on all clients.
5
5
  * Keys should be a string, and values should be serializable to JSON.
@@ -11,13 +11,15 @@ export declare class LiveObject<T extends Record<string, any> = Record<string, a
11
11
  /**
12
12
  * INTERNAL
13
13
  */
14
- _serialize(parentId?: string, parentKey?: string): Op[];
14
+ _serialize(parentId?: string, parentKey?: string, doc?: Doc): Op[];
15
15
  /**
16
16
  * INTERNAL
17
17
  */
18
- static _deserialize([id, item]: SerializedCrdtWithId, parentToChildren: Map<string, SerializedCrdtWithId[]>, doc: Doc): LiveObject<{
19
- [key: string]: any;
20
- }>;
18
+ static _deserialize([id, item]: SerializedCrdtWithId, parentToChildren: Map<string, SerializedCrdtWithId[]>, doc: Doc): LiveObject<Record<string, any>>;
19
+ /**
20
+ * INTERNAL
21
+ */
22
+ static _deserializeChildren(object: LiveObject, parentToChildren: Map<string, SerializedCrdtWithId[]>, doc: Doc): LiveObject<Record<string, any>>;
21
23
  /**
22
24
  * INTERNAL
23
25
  */
@@ -25,11 +27,15 @@ export declare class LiveObject<T extends Record<string, any> = Record<string, a
25
27
  /**
26
28
  * INTERNAL
27
29
  */
28
- _attachChild(id: string, key: keyof T, child: AbstractCrdt): ApplyResult;
30
+ _attachChild(id: string, key: keyof T, child: AbstractCrdt, isLocal: boolean): ApplyResult;
31
+ /**
32
+ * INTERNAL
33
+ */
34
+ _detachChild(child: AbstractCrdt): ApplyResult;
29
35
  /**
30
36
  * INTERNAL
31
37
  */
32
- _detachChild(child: AbstractCrdt): void;
38
+ _detachChildren(): void;
33
39
  /**
34
40
  * INTERNAL
35
41
  */
@@ -37,7 +43,15 @@ export declare class LiveObject<T extends Record<string, any> = Record<string, a
37
43
  /**
38
44
  * INTERNAL
39
45
  */
40
- _apply(op: Op): ApplyResult;
46
+ _apply(op: Op, isLocal: boolean): ApplyResult;
47
+ /**
48
+ * INTERNAL
49
+ */
50
+ _toSerializedCrdt(): SerializedCrdt;
51
+ /**
52
+ * INTERNAL
53
+ */
54
+ _getType(): string;
41
55
  /**
42
56
  * Transform the LiveObject into a javascript object
43
57
  */