@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.
- package/lib/cjs/AbstractCrdt.d.ts +5 -3
- package/lib/cjs/AbstractCrdt.js +1 -4
- package/lib/cjs/LiveList.d.ts +8 -2
- package/lib/cjs/LiveList.js +113 -9
- package/lib/cjs/LiveMap.d.ts +5 -1
- package/lib/cjs/LiveMap.js +35 -3
- package/lib/cjs/LiveObject.d.ts +5 -1
- package/lib/cjs/LiveObject.js +65 -10
- package/lib/cjs/LiveRegister.d.ts +5 -1
- package/lib/cjs/LiveRegister.js +6 -0
- package/lib/cjs/immutable.d.ts +9 -0
- package/lib/cjs/immutable.js +299 -0
- package/lib/cjs/index.d.ts +1 -0
- package/lib/cjs/index.js +8 -1
- package/lib/cjs/room.d.ts +1 -1
- package/lib/cjs/room.js +34 -54
- package/lib/cjs/types.d.ts +25 -4
- package/lib/cjs/utils.d.ts +6 -0
- package/lib/cjs/utils.js +76 -1
- package/lib/esm/AbstractCrdt.d.ts +5 -3
- package/lib/esm/AbstractCrdt.js +1 -4
- package/lib/esm/LiveList.d.ts +8 -2
- package/lib/esm/LiveList.js +113 -9
- package/lib/esm/LiveMap.d.ts +5 -1
- package/lib/esm/LiveMap.js +35 -3
- package/lib/esm/LiveObject.d.ts +5 -1
- package/lib/esm/LiveObject.js +65 -10
- package/lib/esm/LiveRegister.d.ts +5 -1
- package/lib/esm/LiveRegister.js +6 -0
- package/lib/esm/immutable.d.ts +9 -0
- package/lib/esm/immutable.js +290 -0
- package/lib/esm/index.d.ts +1 -0
- package/lib/esm/index.js +1 -0
- package/lib/esm/room.d.ts +1 -1
- package/lib/esm/room.js +35 -55
- package/lib/esm/types.d.ts +25 -4
- package/lib/esm/utils.d.ts +6 -0
- package/lib/esm/utils.js +73 -0
- package/package.json +3 -2
|
@@ -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:
|
|
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[],
|
|
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):
|
|
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
|
}
|
package/lib/esm/AbstractCrdt.js
CHANGED
|
@@ -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
|
-
|
|
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
|
}
|
package/lib/esm/LiveList.d.ts
CHANGED
|
@@ -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):
|
|
33
|
+
_detachChild(child: AbstractCrdt): ApplyResult;
|
|
33
34
|
/**
|
|
34
35
|
* INTERNAL
|
|
35
36
|
*/
|
|
36
|
-
_setChildKey(key: string, child: AbstractCrdt):
|
|
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).
|
package/lib/esm/LiveList.js
CHANGED
|
@@ -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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
],
|
|
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]),
|
|
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
|
-
|
|
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).
|
package/lib/esm/LiveMap.d.ts
CHANGED
|
@@ -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):
|
|
34
|
+
_detachChild(child: AbstractCrdt): ApplyResult;
|
|
35
|
+
/**
|
|
36
|
+
* INTERNAL
|
|
37
|
+
*/
|
|
38
|
+
_getType(): string;
|
|
35
39
|
/**
|
|
36
40
|
* INTERNAL
|
|
37
41
|
*/
|
package/lib/esm/LiveMap.js
CHANGED
|
@@ -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 {
|
|
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 }],
|
|
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),
|
|
248
|
+
], item._serialize(this._id, key), storageUpdates);
|
|
217
249
|
}
|
|
218
250
|
__classPrivateFieldGet(this, _LiveMap_map, "f").delete(key);
|
|
219
251
|
return true;
|
package/lib/esm/LiveObject.d.ts
CHANGED
|
@@ -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):
|
|
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
|
*/
|
package/lib/esm/LiveObject.js
CHANGED
|
@@ -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 {
|
|
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,
|
|
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
|
-
|
|
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
|
|
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 {
|
|
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):
|
|
23
|
+
_detachChild(crdt: AbstractCrdt): ApplyResult;
|
|
24
24
|
_apply(op: Op, isLocal: boolean): ApplyResult;
|
|
25
|
+
/**
|
|
26
|
+
* INTERNAL
|
|
27
|
+
*/
|
|
28
|
+
_getType(): string;
|
|
25
29
|
}
|
package/lib/esm/LiveRegister.js
CHANGED
|
@@ -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;
|