@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.
- package/lib/cjs/AbstractCrdt.d.ts +13 -7
- package/lib/cjs/AbstractCrdt.js +2 -5
- package/lib/cjs/LiveList.d.ts +16 -6
- package/lib/cjs/LiveList.js +148 -17
- package/lib/cjs/LiveMap.d.ts +12 -4
- package/lib/cjs/LiveMap.js +57 -7
- package/lib/cjs/LiveObject.d.ts +22 -8
- package/lib/cjs/LiveObject.js +109 -24
- package/lib/cjs/LiveRegister.d.ts +13 -5
- package/lib/cjs/LiveRegister.js +23 -4
- package/lib/cjs/immutable.d.ts +1 -0
- package/lib/cjs/immutable.js +64 -6
- package/lib/cjs/index.d.ts +1 -0
- package/lib/cjs/index.js +8 -1
- package/lib/cjs/live.d.ts +7 -0
- package/lib/cjs/room.d.ts +9 -1
- package/lib/cjs/room.js +131 -70
- package/lib/cjs/types.d.ts +25 -0
- package/lib/cjs/utils.d.ts +4 -1
- package/lib/cjs/utils.js +101 -1
- package/lib/esm/AbstractCrdt.d.ts +13 -7
- package/lib/esm/AbstractCrdt.js +2 -5
- package/lib/esm/LiveList.d.ts +16 -6
- package/lib/esm/LiveList.js +149 -18
- package/lib/esm/LiveMap.d.ts +12 -4
- package/lib/esm/LiveMap.js +57 -7
- package/lib/esm/LiveObject.d.ts +22 -8
- package/lib/esm/LiveObject.js +109 -24
- package/lib/esm/LiveRegister.d.ts +13 -5
- package/lib/esm/LiveRegister.js +24 -5
- package/lib/esm/immutable.d.ts +1 -0
- package/lib/esm/immutable.js +63 -6
- package/lib/esm/index.d.ts +1 -0
- package/lib/esm/index.js +1 -0
- package/lib/esm/live.d.ts +7 -0
- package/lib/esm/room.d.ts +9 -1
- package/lib/esm/room.js +132 -71
- package/lib/esm/types.d.ts +25 -0
- package/lib/esm/utils.d.ts +4 -1
- package/lib/esm/utils.js +99 -1
- package/package.json +2 -2
- package/lib/cjs/immutable/index.d.ts +0 -7
- package/lib/cjs/immutable/index.js +0 -214
- package/lib/esm/immutable/index.d.ts +0 -7
- package/lib/esm/immutable/index.js +0 -207
package/lib/esm/LiveList.d.ts
CHANGED
|
@@ -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):
|
|
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
|
-
_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).
|
package/lib/esm/LiveList.js
CHANGED
|
@@ -12,8 +12,9 @@ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (
|
|
|
12
12
|
var _LiveList_items, _LiveListIterator_innerIterator;
|
|
13
13
|
import { AbstractCrdt } from "./AbstractCrdt";
|
|
14
14
|
import { deserialize, selfOrRegister, selfOrRegisterValue } from "./utils";
|
|
15
|
-
import { OpType, } from "./live";
|
|
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
|
*/
|
|
@@ -51,7 +52,7 @@ export class LiveList extends AbstractCrdt {
|
|
|
51
52
|
/**
|
|
52
53
|
* INTERNAL
|
|
53
54
|
*/
|
|
54
|
-
_serialize(parentId, parentKey) {
|
|
55
|
+
_serialize(parentId, parentKey, doc) {
|
|
55
56
|
if (this._id == null) {
|
|
56
57
|
throw new Error("Cannot serialize item is not attached");
|
|
57
58
|
}
|
|
@@ -61,16 +62,20 @@ export class LiveList extends AbstractCrdt {
|
|
|
61
62
|
const ops = [];
|
|
62
63
|
const op = {
|
|
63
64
|
id: this._id,
|
|
65
|
+
opId: doc === null || doc === void 0 ? void 0 : doc.generateOpId(),
|
|
64
66
|
type: OpType.CreateList,
|
|
65
67
|
parentId,
|
|
66
68
|
parentKey,
|
|
67
69
|
};
|
|
68
70
|
ops.push(op);
|
|
69
71
|
for (const [value, key] of __classPrivateFieldGet(this, _LiveList_items, "f")) {
|
|
70
|
-
ops.push(...value._serialize(this._id, key));
|
|
72
|
+
ops.push(...value._serialize(this._id, key, doc));
|
|
71
73
|
}
|
|
72
74
|
return ops;
|
|
73
75
|
}
|
|
76
|
+
_indexOfPosition(position) {
|
|
77
|
+
return __classPrivateFieldGet(this, _LiveList_items, "f").findIndex((item) => item[1] === position);
|
|
78
|
+
}
|
|
74
79
|
/**
|
|
75
80
|
* INTERNAL
|
|
76
81
|
*/
|
|
@@ -92,7 +97,7 @@ export class LiveList extends AbstractCrdt {
|
|
|
92
97
|
/**
|
|
93
98
|
* INTERNAL
|
|
94
99
|
*/
|
|
95
|
-
_attachChild(id, key, child) {
|
|
100
|
+
_attachChild(id, key, child, isLocal) {
|
|
96
101
|
var _a;
|
|
97
102
|
if (this._doc == null) {
|
|
98
103
|
throw new Error("Can't attach child if doc is not present");
|
|
@@ -100,30 +105,66 @@ export class LiveList extends AbstractCrdt {
|
|
|
100
105
|
child._attach(id, this._doc);
|
|
101
106
|
child._setParentLink(this, key);
|
|
102
107
|
const index = __classPrivateFieldGet(this, _LiveList_items, "f").findIndex((entry) => entry[1] === key);
|
|
103
|
-
|
|
108
|
+
let newKey = key;
|
|
109
|
+
// If there is a conflict
|
|
104
110
|
if (index !== -1) {
|
|
105
|
-
|
|
111
|
+
if (isLocal) {
|
|
112
|
+
// If change is local => assign a temporary position to newly attached child
|
|
113
|
+
let before = __classPrivateFieldGet(this, _LiveList_items, "f")[index] ? __classPrivateFieldGet(this, _LiveList_items, "f")[index][1] : undefined;
|
|
114
|
+
let after = __classPrivateFieldGet(this, _LiveList_items, "f")[index + 1]
|
|
115
|
+
? __classPrivateFieldGet(this, _LiveList_items, "f")[index + 1][1]
|
|
116
|
+
: undefined;
|
|
117
|
+
newKey = makePosition(before, after);
|
|
118
|
+
child._setParentLink(this, newKey);
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
// If change is remote => assign a temporary position to existing child until we get the fix from the backend
|
|
122
|
+
__classPrivateFieldGet(this, _LiveList_items, "f")[index][1] = makePosition(key, (_a = __classPrivateFieldGet(this, _LiveList_items, "f")[index + 1]) === null || _a === void 0 ? void 0 : _a[1]);
|
|
123
|
+
}
|
|
106
124
|
}
|
|
107
|
-
__classPrivateFieldGet(this, _LiveList_items, "f").push([child,
|
|
125
|
+
__classPrivateFieldGet(this, _LiveList_items, "f").push([child, newKey]);
|
|
108
126
|
__classPrivateFieldGet(this, _LiveList_items, "f").sort((itemA, itemB) => compare(itemA[1], itemB[1]));
|
|
109
|
-
|
|
127
|
+
const newIndex = __classPrivateFieldGet(this, _LiveList_items, "f").findIndex((entry) => entry[1] === newKey);
|
|
128
|
+
return {
|
|
129
|
+
reverse: [{ type: OpType.DeleteCrdt, id }],
|
|
130
|
+
modified: {
|
|
131
|
+
node: this,
|
|
132
|
+
type: "LiveList",
|
|
133
|
+
updates: [
|
|
134
|
+
{
|
|
135
|
+
index: newIndex,
|
|
136
|
+
type: "insert",
|
|
137
|
+
item: child instanceof LiveRegister ? child.data : child,
|
|
138
|
+
},
|
|
139
|
+
],
|
|
140
|
+
},
|
|
141
|
+
};
|
|
110
142
|
}
|
|
111
143
|
/**
|
|
112
144
|
* INTERNAL
|
|
113
145
|
*/
|
|
114
146
|
_detachChild(child) {
|
|
115
|
-
const indexToDelete = __classPrivateFieldGet(this, _LiveList_items, "f").findIndex((item) => item[0] === child);
|
|
116
|
-
__classPrivateFieldGet(this, _LiveList_items, "f").splice(indexToDelete, 1);
|
|
117
147
|
if (child) {
|
|
148
|
+
const reverse = child._serialize(this._id, child._parentKey, this._doc);
|
|
149
|
+
const indexToDelete = __classPrivateFieldGet(this, _LiveList_items, "f").findIndex((item) => item[0] === child);
|
|
150
|
+
__classPrivateFieldGet(this, _LiveList_items, "f").splice(indexToDelete, 1);
|
|
118
151
|
child._detach();
|
|
152
|
+
const storageUpdate = {
|
|
153
|
+
node: this,
|
|
154
|
+
type: "LiveList",
|
|
155
|
+
updates: [{ index: indexToDelete, type: "delete" }],
|
|
156
|
+
};
|
|
157
|
+
return { modified: storageUpdate, reverse };
|
|
119
158
|
}
|
|
159
|
+
return { modified: false };
|
|
120
160
|
}
|
|
121
161
|
/**
|
|
122
162
|
* INTERNAL
|
|
123
163
|
*/
|
|
124
|
-
_setChildKey(key, child) {
|
|
164
|
+
_setChildKey(key, child, previousKey) {
|
|
125
165
|
var _a;
|
|
126
166
|
child._setParentLink(this, key);
|
|
167
|
+
const previousIndex = __classPrivateFieldGet(this, _LiveList_items, "f").findIndex((entry) => entry[0]._id === child._id);
|
|
127
168
|
const index = __classPrivateFieldGet(this, _LiveList_items, "f").findIndex((entry) => entry[1] === key);
|
|
128
169
|
// Assign a temporary position until we get the fix from the backend
|
|
129
170
|
if (index !== -1) {
|
|
@@ -134,12 +175,54 @@ export class LiveList extends AbstractCrdt {
|
|
|
134
175
|
item[1] = key;
|
|
135
176
|
}
|
|
136
177
|
__classPrivateFieldGet(this, _LiveList_items, "f").sort((itemA, itemB) => compare(itemA[1], itemB[1]));
|
|
178
|
+
const newIndex = __classPrivateFieldGet(this, _LiveList_items, "f").findIndex((entry) => entry[0]._id === child._id);
|
|
179
|
+
const updatesDelta = newIndex === previousIndex
|
|
180
|
+
? []
|
|
181
|
+
: [
|
|
182
|
+
{
|
|
183
|
+
index: newIndex,
|
|
184
|
+
item: child instanceof LiveRegister ? child.data : child,
|
|
185
|
+
previousIndex: previousIndex,
|
|
186
|
+
type: "move",
|
|
187
|
+
},
|
|
188
|
+
];
|
|
189
|
+
return {
|
|
190
|
+
modified: {
|
|
191
|
+
node: this,
|
|
192
|
+
type: "LiveList",
|
|
193
|
+
updates: updatesDelta,
|
|
194
|
+
},
|
|
195
|
+
reverse: [
|
|
196
|
+
{
|
|
197
|
+
type: OpType.SetParentKey,
|
|
198
|
+
id: item === null || item === void 0 ? void 0 : item[0]._id,
|
|
199
|
+
parentKey: previousKey,
|
|
200
|
+
},
|
|
201
|
+
],
|
|
202
|
+
};
|
|
137
203
|
}
|
|
138
204
|
/**
|
|
139
205
|
* INTERNAL
|
|
140
206
|
*/
|
|
141
|
-
_apply(op) {
|
|
142
|
-
return super._apply(op);
|
|
207
|
+
_apply(op, isLocal) {
|
|
208
|
+
return super._apply(op, isLocal);
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* INTERNAL
|
|
212
|
+
*/
|
|
213
|
+
_getType() {
|
|
214
|
+
return "LiveList";
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* INTERNAL
|
|
218
|
+
*/
|
|
219
|
+
_toSerializedCrdt() {
|
|
220
|
+
var _a;
|
|
221
|
+
return {
|
|
222
|
+
type: CrdtType.List,
|
|
223
|
+
parentId: (_a = this._parent) === null || _a === void 0 ? void 0 : _a._id,
|
|
224
|
+
parentKey: this._parentKey,
|
|
225
|
+
};
|
|
143
226
|
}
|
|
144
227
|
/**
|
|
145
228
|
* Returns the number of elements.
|
|
@@ -161,7 +244,7 @@ export class LiveList extends AbstractCrdt {
|
|
|
161
244
|
*/
|
|
162
245
|
insert(element, index) {
|
|
163
246
|
if (index < 0 || index > __classPrivateFieldGet(this, _LiveList_items, "f").length) {
|
|
164
|
-
throw new Error(`Cannot
|
|
247
|
+
throw new Error(`Cannot insert list item at index "${index}". index should be between 0 and ${__classPrivateFieldGet(this, _LiveList_items, "f").length}`);
|
|
165
248
|
}
|
|
166
249
|
let before = __classPrivateFieldGet(this, _LiveList_items, "f")[index - 1] ? __classPrivateFieldGet(this, _LiveList_items, "f")[index - 1][1] : undefined;
|
|
167
250
|
let after = __classPrivateFieldGet(this, _LiveList_items, "f")[index] ? __classPrivateFieldGet(this, _LiveList_items, "f")[index][1] : undefined;
|
|
@@ -170,10 +253,23 @@ export class LiveList extends AbstractCrdt {
|
|
|
170
253
|
value._setParentLink(this, position);
|
|
171
254
|
__classPrivateFieldGet(this, _LiveList_items, "f").push([value, position]);
|
|
172
255
|
__classPrivateFieldGet(this, _LiveList_items, "f").sort((itemA, itemB) => compare(itemA[1], itemB[1]));
|
|
256
|
+
const newIndex = __classPrivateFieldGet(this, _LiveList_items, "f").findIndex((entry) => entry[1] === position);
|
|
173
257
|
if (this._doc && this._id) {
|
|
174
258
|
const id = this._doc.generateId();
|
|
175
259
|
value._attach(id, this._doc);
|
|
176
|
-
|
|
260
|
+
const storageUpdates = new Map();
|
|
261
|
+
storageUpdates.set(this._id, {
|
|
262
|
+
node: this,
|
|
263
|
+
type: "LiveList",
|
|
264
|
+
updates: [
|
|
265
|
+
{
|
|
266
|
+
index: newIndex,
|
|
267
|
+
item: value instanceof LiveRegister ? value.data : value,
|
|
268
|
+
type: "insert",
|
|
269
|
+
},
|
|
270
|
+
],
|
|
271
|
+
});
|
|
272
|
+
this._doc.dispatch(value._serialize(this._id, position, this._doc), [{ type: OpType.DeleteCrdt, id }], storageUpdates);
|
|
177
273
|
}
|
|
178
274
|
}
|
|
179
275
|
/**
|
|
@@ -214,11 +310,26 @@ export class LiveList extends AbstractCrdt {
|
|
|
214
310
|
item[1] = position;
|
|
215
311
|
item[0]._setParentLink(this, position);
|
|
216
312
|
__classPrivateFieldGet(this, _LiveList_items, "f").sort((itemA, itemB) => compare(itemA[1], itemB[1]));
|
|
313
|
+
const newIndex = __classPrivateFieldGet(this, _LiveList_items, "f").findIndex((entry) => entry[1] === position);
|
|
217
314
|
if (this._doc && this._id) {
|
|
315
|
+
const storageUpdates = new Map();
|
|
316
|
+
storageUpdates.set(this._id, {
|
|
317
|
+
node: this,
|
|
318
|
+
type: "LiveList",
|
|
319
|
+
updates: [
|
|
320
|
+
{
|
|
321
|
+
index: newIndex,
|
|
322
|
+
previousIndex: index,
|
|
323
|
+
item: item[0],
|
|
324
|
+
type: "move",
|
|
325
|
+
},
|
|
326
|
+
],
|
|
327
|
+
});
|
|
218
328
|
this._doc.dispatch([
|
|
219
329
|
{
|
|
220
330
|
type: OpType.SetParentKey,
|
|
221
331
|
id: item[0]._id,
|
|
332
|
+
opId: this._doc.generateOpId(),
|
|
222
333
|
parentKey: position,
|
|
223
334
|
},
|
|
224
335
|
], [
|
|
@@ -227,7 +338,7 @@ export class LiveList extends AbstractCrdt {
|
|
|
227
338
|
id: item[0]._id,
|
|
228
339
|
parentKey: previousPosition,
|
|
229
340
|
},
|
|
230
|
-
],
|
|
341
|
+
], storageUpdates);
|
|
231
342
|
}
|
|
232
343
|
}
|
|
233
344
|
/**
|
|
@@ -244,12 +355,19 @@ export class LiveList extends AbstractCrdt {
|
|
|
244
355
|
if (this._doc) {
|
|
245
356
|
const childRecordId = item[0]._id;
|
|
246
357
|
if (childRecordId) {
|
|
358
|
+
const storageUpdates = new Map();
|
|
359
|
+
storageUpdates.set(this._id, {
|
|
360
|
+
node: this,
|
|
361
|
+
type: "LiveList",
|
|
362
|
+
updates: [{ index: index, type: "delete" }],
|
|
363
|
+
});
|
|
247
364
|
this._doc.dispatch([
|
|
248
365
|
{
|
|
249
366
|
id: childRecordId,
|
|
367
|
+
opId: this._doc.generateOpId(),
|
|
250
368
|
type: OpType.DeleteCrdt,
|
|
251
369
|
},
|
|
252
|
-
], item[0]._serialize(this._id, item[1]),
|
|
370
|
+
], item[0]._serialize(this._id, item[1]), storageUpdates);
|
|
253
371
|
}
|
|
254
372
|
}
|
|
255
373
|
}
|
|
@@ -257,16 +375,26 @@ export class LiveList extends AbstractCrdt {
|
|
|
257
375
|
if (this._doc) {
|
|
258
376
|
let ops = [];
|
|
259
377
|
let reverseOps = [];
|
|
378
|
+
let updateDelta = [];
|
|
379
|
+
let i = 0;
|
|
260
380
|
for (const item of __classPrivateFieldGet(this, _LiveList_items, "f")) {
|
|
261
381
|
item[0]._detach();
|
|
262
382
|
const childId = item[0]._id;
|
|
263
383
|
if (childId) {
|
|
264
384
|
ops.push({ id: childId, type: OpType.DeleteCrdt });
|
|
265
385
|
reverseOps.push(...item[0]._serialize(this._id, item[1]));
|
|
386
|
+
updateDelta.push({ index: i, type: "delete" });
|
|
266
387
|
}
|
|
388
|
+
i++;
|
|
267
389
|
}
|
|
268
390
|
__classPrivateFieldSet(this, _LiveList_items, [], "f");
|
|
269
|
-
|
|
391
|
+
const storageUpdates = new Map();
|
|
392
|
+
storageUpdates.set(this._id, {
|
|
393
|
+
node: this,
|
|
394
|
+
type: "LiveList",
|
|
395
|
+
updates: updateDelta,
|
|
396
|
+
});
|
|
397
|
+
this._doc.dispatch(ops, reverseOps, storageUpdates);
|
|
270
398
|
}
|
|
271
399
|
else {
|
|
272
400
|
for (const item of __classPrivateFieldGet(this, _LiveList_items, "f")) {
|
|
@@ -281,6 +409,9 @@ export class LiveList extends AbstractCrdt {
|
|
|
281
409
|
toArray() {
|
|
282
410
|
return __classPrivateFieldGet(this, _LiveList_items, "f").map((entry) => selfOrRegisterValue(entry[0]));
|
|
283
411
|
}
|
|
412
|
+
toCrdtArray() {
|
|
413
|
+
return __classPrivateFieldGet(this, _LiveList_items, "f").map((entry) => entry[0]);
|
|
414
|
+
}
|
|
284
415
|
/**
|
|
285
416
|
* Tests whether all elements pass the test implemented by the provided function.
|
|
286
417
|
* @param predicate Function to test for each element, taking two arguments (the element and its index).
|
package/lib/esm/LiveMap.d.ts
CHANGED
|
@@ -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):
|
|
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.
|
package/lib/esm/LiveMap.js
CHANGED
|
@@ -38,7 +38,7 @@ export class LiveMap extends AbstractCrdt {
|
|
|
38
38
|
/**
|
|
39
39
|
* INTERNAL
|
|
40
40
|
*/
|
|
41
|
-
_serialize(parentId, parentKey) {
|
|
41
|
+
_serialize(parentId, parentKey, doc) {
|
|
42
42
|
if (this._id == null) {
|
|
43
43
|
throw new Error("Cannot serialize item is not attached");
|
|
44
44
|
}
|
|
@@ -48,13 +48,14 @@ export class LiveMap extends AbstractCrdt {
|
|
|
48
48
|
const ops = [];
|
|
49
49
|
const op = {
|
|
50
50
|
id: this._id,
|
|
51
|
+
opId: doc === null || doc === void 0 ? void 0 : doc.generateOpId(),
|
|
51
52
|
type: OpType.CreateMap,
|
|
52
53
|
parentId,
|
|
53
54
|
parentKey,
|
|
54
55
|
};
|
|
55
56
|
ops.push(op);
|
|
56
57
|
for (const [key, value] of __classPrivateFieldGet(this, _LiveMap_map, "f")) {
|
|
57
|
-
ops.push(...value._serialize(this._id, key));
|
|
58
|
+
ops.push(...value._serialize(this._id, key, doc));
|
|
58
59
|
}
|
|
59
60
|
return ops;
|
|
60
61
|
}
|
|
@@ -96,7 +97,7 @@ export class LiveMap extends AbstractCrdt {
|
|
|
96
97
|
/**
|
|
97
98
|
* INTERNAL
|
|
98
99
|
*/
|
|
99
|
-
_attachChild(id, key, child) {
|
|
100
|
+
_attachChild(id, key, child, isLocal) {
|
|
100
101
|
if (this._doc == null) {
|
|
101
102
|
throw new Error("Can't attach child if doc is not present");
|
|
102
103
|
}
|
|
@@ -112,7 +113,14 @@ export class LiveMap extends AbstractCrdt {
|
|
|
112
113
|
child._setParentLink(this, key);
|
|
113
114
|
child._attach(id, this._doc);
|
|
114
115
|
__classPrivateFieldGet(this, _LiveMap_map, "f").set(key, child);
|
|
115
|
-
return {
|
|
116
|
+
return {
|
|
117
|
+
modified: {
|
|
118
|
+
node: this,
|
|
119
|
+
type: "LiveMap",
|
|
120
|
+
updates: { [key]: { type: "update" } },
|
|
121
|
+
},
|
|
122
|
+
reverse,
|
|
123
|
+
};
|
|
116
124
|
}
|
|
117
125
|
/**
|
|
118
126
|
* INTERNAL
|
|
@@ -127,12 +135,36 @@ export class LiveMap extends AbstractCrdt {
|
|
|
127
135
|
* INTERNAL
|
|
128
136
|
*/
|
|
129
137
|
_detachChild(child) {
|
|
138
|
+
const reverse = child._serialize(this._id, child._parentKey, this._doc);
|
|
130
139
|
for (const [key, value] of __classPrivateFieldGet(this, _LiveMap_map, "f")) {
|
|
131
140
|
if (value === child) {
|
|
132
141
|
__classPrivateFieldGet(this, _LiveMap_map, "f").delete(key);
|
|
133
142
|
}
|
|
134
143
|
}
|
|
135
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";
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* INTERNAL
|
|
160
|
+
*/
|
|
161
|
+
_toSerializedCrdt() {
|
|
162
|
+
var _a;
|
|
163
|
+
return {
|
|
164
|
+
type: CrdtType.Map,
|
|
165
|
+
parentId: (_a = this._parent) === null || _a === void 0 ? void 0 : _a._id,
|
|
166
|
+
parentKey: this._parentKey,
|
|
167
|
+
};
|
|
136
168
|
}
|
|
137
169
|
/**
|
|
138
170
|
* Returns a specified element from the LiveMap.
|
|
@@ -162,9 +194,15 @@ export class LiveMap extends AbstractCrdt {
|
|
|
162
194
|
if (this._doc && this._id) {
|
|
163
195
|
const id = this._doc.generateId();
|
|
164
196
|
item._attach(id, this._doc);
|
|
165
|
-
|
|
197
|
+
const storageUpdates = new Map();
|
|
198
|
+
storageUpdates.set(this._id, {
|
|
199
|
+
node: this,
|
|
200
|
+
type: "LiveMap",
|
|
201
|
+
updates: { [key]: { type: "update" } },
|
|
202
|
+
});
|
|
203
|
+
this._doc.dispatch(item._serialize(this._id, key, this._doc), oldValue
|
|
166
204
|
? oldValue._serialize(this._id, key)
|
|
167
|
-
: [{ type: OpType.DeleteCrdt, id }],
|
|
205
|
+
: [{ type: OpType.DeleteCrdt, id }], storageUpdates);
|
|
168
206
|
}
|
|
169
207
|
}
|
|
170
208
|
/**
|
|
@@ -192,7 +230,19 @@ export class LiveMap extends AbstractCrdt {
|
|
|
192
230
|
}
|
|
193
231
|
item._detach();
|
|
194
232
|
if (this._doc && item._id) {
|
|
195
|
-
|
|
233
|
+
const storageUpdates = new Map();
|
|
234
|
+
storageUpdates.set(this._id, {
|
|
235
|
+
node: this,
|
|
236
|
+
type: "LiveMap",
|
|
237
|
+
updates: { [key]: { type: "delete" } },
|
|
238
|
+
});
|
|
239
|
+
this._doc.dispatch([
|
|
240
|
+
{
|
|
241
|
+
type: OpType.DeleteCrdt,
|
|
242
|
+
id: item._id,
|
|
243
|
+
opId: this._doc.generateOpId(),
|
|
244
|
+
},
|
|
245
|
+
], item._serialize(this._id, key), storageUpdates);
|
|
196
246
|
}
|
|
197
247
|
__classPrivateFieldGet(this, _LiveMap_map, "f").delete(key);
|
|
198
248
|
return true;
|
package/lib/esm/LiveObject.d.ts
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
*/
|