@liveblocks/client 0.14.0 → 0.15.0-alpha.1

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.
@@ -72,6 +72,9 @@ export class LiveList extends AbstractCrdt {
72
72
  }
73
73
  return ops;
74
74
  }
75
+ _indexOfPosition(position) {
76
+ return __classPrivateFieldGet(this, _LiveList_items, "f").findIndex((item) => item[1] === position);
77
+ }
75
78
  /**
76
79
  * INTERNAL
77
80
  */
@@ -120,22 +123,38 @@ export class LiveList extends AbstractCrdt {
120
123
  }
121
124
  __classPrivateFieldGet(this, _LiveList_items, "f").push([child, newKey]);
122
125
  __classPrivateFieldGet(this, _LiveList_items, "f").sort((itemA, itemB) => compare(itemA[1], itemB[1]));
123
- return { reverse: [{ type: OpType.DeleteCrdt, id }], modified: this };
126
+ const newIndex = __classPrivateFieldGet(this, _LiveList_items, "f").findIndex((entry) => entry[1] === newKey);
127
+ return {
128
+ reverse: [{ type: OpType.DeleteCrdt, id }],
129
+ modified: {
130
+ node: this,
131
+ type: "LiveList",
132
+ updates: [{ index: newIndex, type: "insert" }],
133
+ },
134
+ };
124
135
  }
125
136
  /**
126
137
  * INTERNAL
127
138
  */
128
139
  _detachChild(child) {
129
- const indexToDelete = __classPrivateFieldGet(this, _LiveList_items, "f").findIndex((item) => item[0] === child);
130
- __classPrivateFieldGet(this, _LiveList_items, "f").splice(indexToDelete, 1);
131
140
  if (child) {
141
+ const reverse = this._serialize(this._id, child._parentKey, this._doc);
142
+ const indexToDelete = __classPrivateFieldGet(this, _LiveList_items, "f").findIndex((item) => item[0] === child);
143
+ __classPrivateFieldGet(this, _LiveList_items, "f").splice(indexToDelete, 1);
132
144
  child._detach();
145
+ const storageUpdate = {
146
+ node: this,
147
+ type: "LiveList",
148
+ updates: [{ index: indexToDelete, type: "delete" }],
149
+ };
150
+ return { modified: storageUpdate, reverse };
133
151
  }
152
+ return { modified: false };
134
153
  }
135
154
  /**
136
155
  * INTERNAL
137
156
  */
138
- _setChildKey(key, child) {
157
+ _setChildKey(key, child, previousKey) {
139
158
  var _a;
140
159
  child._setParentLink(this, key);
141
160
  const index = __classPrivateFieldGet(this, _LiveList_items, "f").findIndex((entry) => entry[1] === key);
@@ -148,6 +167,21 @@ export class LiveList extends AbstractCrdt {
148
167
  item[1] = key;
149
168
  }
150
169
  __classPrivateFieldGet(this, _LiveList_items, "f").sort((itemA, itemB) => compare(itemA[1], itemB[1]));
170
+ const newIndex = this._indexOfPosition(key);
171
+ return {
172
+ modified: {
173
+ node: this,
174
+ type: "LiveList",
175
+ updates: [{ index: newIndex, type: "insert" }],
176
+ },
177
+ reverse: [
178
+ {
179
+ type: OpType.SetParentKey,
180
+ id: item === null || item === void 0 ? void 0 : item[0]._id,
181
+ parentKey: previousKey,
182
+ },
183
+ ],
184
+ };
151
185
  }
152
186
  /**
153
187
  * INTERNAL
@@ -155,6 +189,12 @@ export class LiveList extends AbstractCrdt {
155
189
  _apply(op, isLocal) {
156
190
  return super._apply(op, isLocal);
157
191
  }
192
+ /**
193
+ * INTERNAL
194
+ */
195
+ _getType() {
196
+ return "LiveList";
197
+ }
158
198
  /**
159
199
  * INTERNAL
160
200
  */
@@ -195,10 +235,17 @@ export class LiveList extends AbstractCrdt {
195
235
  value._setParentLink(this, position);
196
236
  __classPrivateFieldGet(this, _LiveList_items, "f").push([value, position]);
197
237
  __classPrivateFieldGet(this, _LiveList_items, "f").sort((itemA, itemB) => compare(itemA[1], itemB[1]));
238
+ const newIndex = __classPrivateFieldGet(this, _LiveList_items, "f").findIndex((entry) => entry[1] === position);
198
239
  if (this._doc && this._id) {
199
240
  const id = this._doc.generateId();
200
241
  value._attach(id, this._doc);
201
- this._doc.dispatch(value._serialize(this._id, position, this._doc), [{ type: OpType.DeleteCrdt, id }], [this]);
242
+ const storageUpdates = new Map();
243
+ storageUpdates.set(this._id, {
244
+ node: this,
245
+ type: "LiveList",
246
+ updates: [{ index: newIndex, type: "insert" }],
247
+ });
248
+ this._doc.dispatch(value._serialize(this._id, position, this._doc), [{ type: OpType.DeleteCrdt, id }], storageUpdates);
202
249
  }
203
250
  }
204
251
  /**
@@ -239,7 +286,17 @@ export class LiveList extends AbstractCrdt {
239
286
  item[1] = position;
240
287
  item[0]._setParentLink(this, position);
241
288
  __classPrivateFieldGet(this, _LiveList_items, "f").sort((itemA, itemB) => compare(itemA[1], itemB[1]));
289
+ const newIndex = __classPrivateFieldGet(this, _LiveList_items, "f").findIndex((entry) => entry[1] === position);
242
290
  if (this._doc && this._id) {
291
+ const storageUpdates = new Map();
292
+ storageUpdates.set(this._id, {
293
+ node: this,
294
+ type: "LiveList",
295
+ updates: [
296
+ { index: index, type: "delete" },
297
+ { index: newIndex, type: "insert" },
298
+ ],
299
+ });
243
300
  this._doc.dispatch([
244
301
  {
245
302
  type: OpType.SetParentKey,
@@ -253,7 +310,7 @@ export class LiveList extends AbstractCrdt {
253
310
  id: item[0]._id,
254
311
  parentKey: previousPosition,
255
312
  },
256
- ], [this]);
313
+ ], storageUpdates);
257
314
  }
258
315
  }
259
316
  /**
@@ -270,13 +327,19 @@ export class LiveList extends AbstractCrdt {
270
327
  if (this._doc) {
271
328
  const childRecordId = item[0]._id;
272
329
  if (childRecordId) {
330
+ const storageUpdates = new Map();
331
+ storageUpdates.set(this._id, {
332
+ node: this,
333
+ type: "LiveList",
334
+ updates: [{ index: index, type: "delete" }],
335
+ });
273
336
  this._doc.dispatch([
274
337
  {
275
338
  id: childRecordId,
276
339
  opId: this._doc.generateOpId(),
277
340
  type: OpType.DeleteCrdt,
278
341
  },
279
- ], item[0]._serialize(this._id, item[1]), [this]);
342
+ ], item[0]._serialize(this._id, item[1]), storageUpdates);
280
343
  }
281
344
  }
282
345
  }
@@ -284,16 +347,26 @@ export class LiveList extends AbstractCrdt {
284
347
  if (this._doc) {
285
348
  let ops = [];
286
349
  let reverseOps = [];
350
+ let updateDelta = [];
351
+ let i = 0;
287
352
  for (const item of __classPrivateFieldGet(this, _LiveList_items, "f")) {
288
353
  item[0]._detach();
289
354
  const childId = item[0]._id;
290
355
  if (childId) {
291
356
  ops.push({ id: childId, type: OpType.DeleteCrdt });
292
357
  reverseOps.push(...item[0]._serialize(this._id, item[1]));
358
+ updateDelta.push({ index: i, type: "delete" });
293
359
  }
360
+ i++;
294
361
  }
295
362
  __classPrivateFieldSet(this, _LiveList_items, [], "f");
296
- this._doc.dispatch(ops, reverseOps, [this]);
363
+ const storageUpdates = new Map();
364
+ storageUpdates.set(this._id, {
365
+ node: this,
366
+ type: "LiveList",
367
+ updates: updateDelta,
368
+ });
369
+ this._doc.dispatch(ops, reverseOps, storageUpdates);
297
370
  }
298
371
  else {
299
372
  for (const item of __classPrivateFieldGet(this, _LiveList_items, "f")) {
@@ -308,6 +381,9 @@ export class LiveList extends AbstractCrdt {
308
381
  toArray() {
309
382
  return __classPrivateFieldGet(this, _LiveList_items, "f").map((entry) => selfOrRegisterValue(entry[0]));
310
383
  }
384
+ toCrdtArray() {
385
+ return __classPrivateFieldGet(this, _LiveList_items, "f").map((entry) => entry[0]);
386
+ }
311
387
  /**
312
388
  * Tests whether all elements pass the test implemented by the provided function.
313
389
  * @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
  */
@@ -113,7 +113,14 @@ export class LiveMap extends AbstractCrdt {
113
113
  child._setParentLink(this, key);
114
114
  child._attach(id, this._doc);
115
115
  __classPrivateFieldGet(this, _LiveMap_map, "f").set(key, child);
116
- return { modified: this, reverse };
116
+ return {
117
+ modified: {
118
+ node: this,
119
+ type: "LiveMap",
120
+ updates: { [key]: { type: "update" } },
121
+ },
122
+ reverse,
123
+ };
117
124
  }
118
125
  /**
119
126
  * INTERNAL
@@ -128,12 +135,25 @@ export class LiveMap extends AbstractCrdt {
128
135
  * INTERNAL
129
136
  */
130
137
  _detachChild(child) {
138
+ const reverse = this._serialize(this._id, child._parentKey, this._doc);
131
139
  for (const [key, value] of __classPrivateFieldGet(this, _LiveMap_map, "f")) {
132
140
  if (value === child) {
133
141
  __classPrivateFieldGet(this, _LiveMap_map, "f").delete(key);
134
142
  }
135
143
  }
136
144
  child._detach();
145
+ const storageUpdate = {
146
+ node: this,
147
+ type: "LiveMap",
148
+ updates: { [child._parentKey]: { type: "delete" } },
149
+ };
150
+ return { modified: storageUpdate, reverse };
151
+ }
152
+ /**
153
+ * INTERNAL
154
+ */
155
+ _getType() {
156
+ return "LiveMap";
137
157
  }
138
158
  /**
139
159
  * INTERNAL
@@ -174,9 +194,15 @@ export class LiveMap extends AbstractCrdt {
174
194
  if (this._doc && this._id) {
175
195
  const id = this._doc.generateId();
176
196
  item._attach(id, this._doc);
197
+ const storageUpdates = new Map();
198
+ storageUpdates.set(this._id, {
199
+ node: this,
200
+ type: "LiveMap",
201
+ updates: { [key]: { type: "update" } },
202
+ });
177
203
  this._doc.dispatch(item._serialize(this._id, key, this._doc), oldValue
178
204
  ? oldValue._serialize(this._id, key)
179
- : [{ type: OpType.DeleteCrdt, id }], [this]);
205
+ : [{ type: OpType.DeleteCrdt, id }], storageUpdates);
180
206
  }
181
207
  }
182
208
  /**
@@ -204,13 +230,19 @@ export class LiveMap extends AbstractCrdt {
204
230
  }
205
231
  item._detach();
206
232
  if (this._doc && item._id) {
233
+ const storageUpdates = new Map();
234
+ storageUpdates.set(this._id, {
235
+ node: this,
236
+ type: "LiveMap",
237
+ updates: { [key]: { type: "delete" } },
238
+ });
207
239
  this._doc.dispatch([
208
240
  {
209
241
  type: OpType.DeleteCrdt,
210
242
  id: item._id,
211
243
  opId: this._doc.generateOpId(),
212
244
  },
213
- ], item._serialize(this._id, key), [this]);
245
+ ], item._serialize(this._id, key), storageUpdates);
214
246
  }
215
247
  __classPrivateFieldGet(this, _LiveMap_map, "f").delete(key);
216
248
  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
  */
@@ -130,20 +130,37 @@ export class LiveObject extends AbstractCrdt {
130
130
  __classPrivateFieldGet(this, _LiveObject_map, "f").set(key, child);
131
131
  child._setParentLink(this, key);
132
132
  child._attach(id, this._doc);
133
- return { reverse, modified: this };
133
+ return {
134
+ reverse,
135
+ modified: {
136
+ node: this,
137
+ type: "LiveObject",
138
+ updates: { [key]: { type: "update" } },
139
+ },
140
+ };
134
141
  }
135
142
  /**
136
143
  * INTERNAL
137
144
  */
138
145
  _detachChild(child) {
139
- for (const [key, value] of __classPrivateFieldGet(this, _LiveObject_map, "f")) {
140
- if (value === child) {
141
- __classPrivateFieldGet(this, _LiveObject_map, "f").delete(key);
142
- }
143
- }
144
146
  if (child) {
147
+ const reverse = this._serialize(this._id, child._parentKey, this._doc);
148
+ for (const [key, value] of __classPrivateFieldGet(this, _LiveObject_map, "f")) {
149
+ if (value === child) {
150
+ __classPrivateFieldGet(this, _LiveObject_map, "f").delete(key);
151
+ }
152
+ }
145
153
  child._detach();
154
+ const storageUpdate = {
155
+ node: this,
156
+ type: "LiveObject",
157
+ updates: {
158
+ [child._parentKey]: { type: "delete" },
159
+ },
160
+ };
161
+ return { modified: storageUpdate, reverse };
146
162
  }
163
+ return { modified: false };
147
164
  }
148
165
  /**
149
166
  * INTERNAL
@@ -189,6 +206,12 @@ export class LiveObject extends AbstractCrdt {
189
206
  data: this.toObject(),
190
207
  };
191
208
  }
209
+ /**
210
+ * INTERNAL
211
+ */
212
+ _getType() {
213
+ return "LiveObject";
214
+ }
192
215
  /**
193
216
  * Transform the LiveObject into a javascript object
194
217
  */
@@ -243,6 +266,12 @@ export class LiveObject extends AbstractCrdt {
243
266
  ];
244
267
  }
245
268
  __classPrivateFieldGet(this, _LiveObject_map, "f").delete(keyAsString);
269
+ const storageUpdates = new Map();
270
+ storageUpdates.set(this._id, {
271
+ node: this,
272
+ type: "LiveObject",
273
+ updates: { [key]: { type: "delete" } },
274
+ });
246
275
  this._doc.dispatch([
247
276
  {
248
277
  type: OpType.DeleteObjectKey,
@@ -250,7 +279,7 @@ export class LiveObject extends AbstractCrdt {
250
279
  id: this._id,
251
280
  opId: this._doc.generateOpId(),
252
281
  },
253
- ], reverse, [this]);
282
+ ], reverse, storageUpdates);
254
283
  }
255
284
  /**
256
285
  * Adds or updates multiple properties at once with an object.
@@ -280,6 +309,7 @@ export class LiveObject extends AbstractCrdt {
280
309
  type: OpType.UpdateObject,
281
310
  data: {},
282
311
  };
312
+ const updateDelta = {};
283
313
  for (const key in overrides) {
284
314
  __classPrivateFieldGet(this, _LiveObject_propToLastUpdate, "f").set(key, opId);
285
315
  const oldValue = __classPrivateFieldGet(this, _LiveObject_map, "f").get(key);
@@ -303,6 +333,7 @@ export class LiveObject extends AbstractCrdt {
303
333
  updatedProps[key] = newValue;
304
334
  }
305
335
  __classPrivateFieldGet(this, _LiveObject_map, "f").set(key, newValue);
336
+ updateDelta[key] = { type: "update" };
306
337
  }
307
338
  if (Object.keys(reverseUpdateOp.data).length !== 0) {
308
339
  reverseOps.unshift(reverseUpdateOp);
@@ -315,7 +346,13 @@ export class LiveObject extends AbstractCrdt {
315
346
  data: updatedProps,
316
347
  });
317
348
  }
318
- this._doc.dispatch(ops, reverseOps, [this]);
349
+ const storageUpdates = new Map();
350
+ storageUpdates.set(this._id, {
351
+ node: this,
352
+ type: "LiveObject",
353
+ updates: updateDelta,
354
+ });
355
+ this._doc.dispatch(ops, reverseOps, storageUpdates);
319
356
  }
320
357
  }
321
358
  _LiveObject_map = new WeakMap(), _LiveObject_propToLastUpdate = new WeakMap(), _LiveObject_instances = new WeakSet(), _LiveObject_applyUpdate = function _LiveObject_applyUpdate(op, isLocal) {
@@ -340,6 +377,7 @@ _LiveObject_map = new WeakMap(), _LiveObject_propToLastUpdate = new WeakMap(), _
340
377
  reverse.push({ type: OpType.DeleteObjectKey, id: this._id, key });
341
378
  }
342
379
  }
380
+ let updateDelta = {};
343
381
  for (const key in op.data) {
344
382
  if (isLocal) {
345
383
  __classPrivateFieldGet(this, _LiveObject_propToLastUpdate, "f").set(key, op.opId);
@@ -362,12 +400,22 @@ _LiveObject_map = new WeakMap(), _LiveObject_propToLastUpdate = new WeakMap(), _
362
400
  oldValue._detach();
363
401
  }
364
402
  isModified = true;
403
+ updateDelta[key] = { type: "update" };
365
404
  __classPrivateFieldGet(this, _LiveObject_map, "f").set(key, op.data[key]);
366
405
  }
367
406
  if (Object.keys(reverseUpdate.data).length !== 0) {
368
407
  reverse.unshift(reverseUpdate);
369
408
  }
370
- return isModified ? { modified: this, reverse } : { modified: false };
409
+ return isModified
410
+ ? {
411
+ modified: {
412
+ node: this,
413
+ type: "LiveObject",
414
+ updates: updateDelta,
415
+ },
416
+ reverse,
417
+ }
418
+ : { modified: false };
371
419
  }, _LiveObject_applyDeleteObjectKey = function _LiveObject_applyDeleteObjectKey(op) {
372
420
  const key = op.key;
373
421
  // If property does not exist, exit without notifying
@@ -390,5 +438,12 @@ _LiveObject_map = new WeakMap(), _LiveObject_propToLastUpdate = new WeakMap(), _
390
438
  ];
391
439
  }
392
440
  __classPrivateFieldGet(this, _LiveObject_map, "f").delete(key);
393
- return { modified: this, reverse };
441
+ return {
442
+ modified: {
443
+ node: this,
444
+ type: "LiveObject",
445
+ updates: { [op.key]: { type: "delete" } },
446
+ },
447
+ reverse,
448
+ };
394
449
  };
@@ -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, 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;