@liveblocks/client 0.13.2 → 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.
- package/lib/cjs/AbstractCrdt.d.ts +13 -7
- package/lib/cjs/AbstractCrdt.js +2 -5
- package/lib/cjs/LiveList.d.ts +17 -6
- package/lib/cjs/LiveList.js +140 -15
- 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/index.d.ts → immutable.d.ts} +5 -3
- package/lib/cjs/{immutable/index.js → immutable.js} +77 -19
- package/lib/cjs/index.d.ts +2 -1
- package/lib/cjs/index.js +8 -1
- package/lib/cjs/live.d.ts +7 -0
- package/lib/cjs/room.d.ts +11 -3
- package/lib/cjs/room.js +150 -76
- package/lib/cjs/types.d.ts +33 -1
- 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 +17 -6
- package/lib/esm/LiveList.js +141 -16
- 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/index.d.ts → immutable.d.ts} +5 -3
- package/lib/esm/{immutable/index.js → immutable.js} +75 -19
- package/lib/esm/index.d.ts +2 -1
- package/lib/esm/index.js +1 -0
- package/lib/esm/live.d.ts +7 -0
- package/lib/esm/room.d.ts +11 -3
- package/lib/esm/room.js +151 -77
- package/lib/esm/types.d.ts +33 -1
- package/lib/esm/utils.d.ts +4 -1
- package/lib/esm/utils.js +99 -1
- package/package.json +1 -1
|
@@ -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:
|
|
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[],
|
|
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):
|
|
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
|
}
|
package/lib/esm/AbstractCrdt.js
CHANGED
|
@@ -45,14 +45,11 @@ export class AbstractCrdt {
|
|
|
45
45
|
/**
|
|
46
46
|
* INTERNAL
|
|
47
47
|
*/
|
|
48
|
-
_apply(op) {
|
|
48
|
+
_apply(op, isLocal) {
|
|
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);
|
|
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
|
@@ -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
|
*/
|
|
@@ -64,10 +73,12 @@ export declare class LiveList<T> extends AbstractCrdt {
|
|
|
64
73
|
* @param index The index of the element to delete
|
|
65
74
|
*/
|
|
66
75
|
delete(index: number): void;
|
|
76
|
+
clear(): void;
|
|
67
77
|
/**
|
|
68
78
|
* Returns an Array of all the elements in the LiveList.
|
|
69
79
|
*/
|
|
70
80
|
toArray(): T[];
|
|
81
|
+
toCrdtArray(): AbstractCrdt[];
|
|
71
82
|
/**
|
|
72
83
|
* Tests whether all elements pass the test implemented by the provided function.
|
|
73
84
|
* @param predicate Function to test for each element, taking two arguments (the element and its index).
|
package/lib/esm/LiveList.js
CHANGED
|
@@ -12,7 +12,7 @@ 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
17
|
/**
|
|
18
18
|
* The LiveList class represents an ordered collection of items that is synchorinized across clients.
|
|
@@ -51,7 +51,7 @@ export class LiveList extends AbstractCrdt {
|
|
|
51
51
|
/**
|
|
52
52
|
* INTERNAL
|
|
53
53
|
*/
|
|
54
|
-
_serialize(parentId, parentKey) {
|
|
54
|
+
_serialize(parentId, parentKey, doc) {
|
|
55
55
|
if (this._id == null) {
|
|
56
56
|
throw new Error("Cannot serialize item is not attached");
|
|
57
57
|
}
|
|
@@ -61,16 +61,20 @@ export class LiveList extends AbstractCrdt {
|
|
|
61
61
|
const ops = [];
|
|
62
62
|
const op = {
|
|
63
63
|
id: this._id,
|
|
64
|
+
opId: doc === null || doc === void 0 ? void 0 : doc.generateOpId(),
|
|
64
65
|
type: OpType.CreateList,
|
|
65
66
|
parentId,
|
|
66
67
|
parentKey,
|
|
67
68
|
};
|
|
68
69
|
ops.push(op);
|
|
69
70
|
for (const [value, key] of __classPrivateFieldGet(this, _LiveList_items, "f")) {
|
|
70
|
-
ops.push(...value._serialize(this._id, key));
|
|
71
|
+
ops.push(...value._serialize(this._id, key, doc));
|
|
71
72
|
}
|
|
72
73
|
return ops;
|
|
73
74
|
}
|
|
75
|
+
_indexOfPosition(position) {
|
|
76
|
+
return __classPrivateFieldGet(this, _LiveList_items, "f").findIndex((item) => item[1] === position);
|
|
77
|
+
}
|
|
74
78
|
/**
|
|
75
79
|
* INTERNAL
|
|
76
80
|
*/
|
|
@@ -92,7 +96,7 @@ export class LiveList extends AbstractCrdt {
|
|
|
92
96
|
/**
|
|
93
97
|
* INTERNAL
|
|
94
98
|
*/
|
|
95
|
-
_attachChild(id, key, child) {
|
|
99
|
+
_attachChild(id, key, child, isLocal) {
|
|
96
100
|
var _a;
|
|
97
101
|
if (this._doc == null) {
|
|
98
102
|
throw new Error("Can't attach child if doc is not present");
|
|
@@ -100,28 +104,57 @@ export class LiveList extends AbstractCrdt {
|
|
|
100
104
|
child._attach(id, this._doc);
|
|
101
105
|
child._setParentLink(this, key);
|
|
102
106
|
const index = __classPrivateFieldGet(this, _LiveList_items, "f").findIndex((entry) => entry[1] === key);
|
|
103
|
-
|
|
107
|
+
let newKey = key;
|
|
108
|
+
// If there is a conflict
|
|
104
109
|
if (index !== -1) {
|
|
105
|
-
|
|
110
|
+
if (isLocal) {
|
|
111
|
+
// If change is local => assign a temporary position to newly attached child
|
|
112
|
+
let before = __classPrivateFieldGet(this, _LiveList_items, "f")[index] ? __classPrivateFieldGet(this, _LiveList_items, "f")[index][1] : undefined;
|
|
113
|
+
let after = __classPrivateFieldGet(this, _LiveList_items, "f")[index + 1]
|
|
114
|
+
? __classPrivateFieldGet(this, _LiveList_items, "f")[index + 1][1]
|
|
115
|
+
: undefined;
|
|
116
|
+
newKey = makePosition(before, after);
|
|
117
|
+
child._setParentLink(this, newKey);
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
// If change is remote => assign a temporary position to existing child until we get the fix from the backend
|
|
121
|
+
__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]);
|
|
122
|
+
}
|
|
106
123
|
}
|
|
107
|
-
__classPrivateFieldGet(this, _LiveList_items, "f").push([child,
|
|
124
|
+
__classPrivateFieldGet(this, _LiveList_items, "f").push([child, newKey]);
|
|
108
125
|
__classPrivateFieldGet(this, _LiveList_items, "f").sort((itemA, itemB) => compare(itemA[1], itemB[1]));
|
|
109
|
-
|
|
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
|
+
};
|
|
110
135
|
}
|
|
111
136
|
/**
|
|
112
137
|
* INTERNAL
|
|
113
138
|
*/
|
|
114
139
|
_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
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);
|
|
118
144
|
child._detach();
|
|
145
|
+
const storageUpdate = {
|
|
146
|
+
node: this,
|
|
147
|
+
type: "LiveList",
|
|
148
|
+
updates: [{ index: indexToDelete, type: "delete" }],
|
|
149
|
+
};
|
|
150
|
+
return { modified: storageUpdate, reverse };
|
|
119
151
|
}
|
|
152
|
+
return { modified: false };
|
|
120
153
|
}
|
|
121
154
|
/**
|
|
122
155
|
* INTERNAL
|
|
123
156
|
*/
|
|
124
|
-
_setChildKey(key, child) {
|
|
157
|
+
_setChildKey(key, child, previousKey) {
|
|
125
158
|
var _a;
|
|
126
159
|
child._setParentLink(this, key);
|
|
127
160
|
const index = __classPrivateFieldGet(this, _LiveList_items, "f").findIndex((entry) => entry[1] === key);
|
|
@@ -134,12 +167,44 @@ export class LiveList extends AbstractCrdt {
|
|
|
134
167
|
item[1] = key;
|
|
135
168
|
}
|
|
136
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
|
+
};
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* INTERNAL
|
|
188
|
+
*/
|
|
189
|
+
_apply(op, isLocal) {
|
|
190
|
+
return super._apply(op, isLocal);
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* INTERNAL
|
|
194
|
+
*/
|
|
195
|
+
_getType() {
|
|
196
|
+
return "LiveList";
|
|
137
197
|
}
|
|
138
198
|
/**
|
|
139
199
|
* INTERNAL
|
|
140
200
|
*/
|
|
141
|
-
|
|
142
|
-
|
|
201
|
+
_toSerializedCrdt() {
|
|
202
|
+
var _a;
|
|
203
|
+
return {
|
|
204
|
+
type: CrdtType.List,
|
|
205
|
+
parentId: (_a = this._parent) === null || _a === void 0 ? void 0 : _a._id,
|
|
206
|
+
parentKey: this._parentKey,
|
|
207
|
+
};
|
|
143
208
|
}
|
|
144
209
|
/**
|
|
145
210
|
* Returns the number of elements.
|
|
@@ -170,10 +235,17 @@ export class LiveList extends AbstractCrdt {
|
|
|
170
235
|
value._setParentLink(this, position);
|
|
171
236
|
__classPrivateFieldGet(this, _LiveList_items, "f").push([value, position]);
|
|
172
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);
|
|
173
239
|
if (this._doc && this._id) {
|
|
174
240
|
const id = this._doc.generateId();
|
|
175
241
|
value._attach(id, this._doc);
|
|
176
|
-
|
|
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);
|
|
177
249
|
}
|
|
178
250
|
}
|
|
179
251
|
/**
|
|
@@ -214,11 +286,22 @@ export class LiveList extends AbstractCrdt {
|
|
|
214
286
|
item[1] = position;
|
|
215
287
|
item[0]._setParentLink(this, position);
|
|
216
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);
|
|
217
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
|
+
});
|
|
218
300
|
this._doc.dispatch([
|
|
219
301
|
{
|
|
220
302
|
type: OpType.SetParentKey,
|
|
221
303
|
id: item[0]._id,
|
|
304
|
+
opId: this._doc.generateOpId(),
|
|
222
305
|
parentKey: position,
|
|
223
306
|
},
|
|
224
307
|
], [
|
|
@@ -227,7 +310,7 @@ export class LiveList extends AbstractCrdt {
|
|
|
227
310
|
id: item[0]._id,
|
|
228
311
|
parentKey: previousPosition,
|
|
229
312
|
},
|
|
230
|
-
],
|
|
313
|
+
], storageUpdates);
|
|
231
314
|
}
|
|
232
315
|
}
|
|
233
316
|
/**
|
|
@@ -244,21 +327,63 @@ export class LiveList extends AbstractCrdt {
|
|
|
244
327
|
if (this._doc) {
|
|
245
328
|
const childRecordId = item[0]._id;
|
|
246
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
|
+
});
|
|
247
336
|
this._doc.dispatch([
|
|
248
337
|
{
|
|
249
338
|
id: childRecordId,
|
|
339
|
+
opId: this._doc.generateOpId(),
|
|
250
340
|
type: OpType.DeleteCrdt,
|
|
251
341
|
},
|
|
252
|
-
], item[0]._serialize(this._id, item[1]),
|
|
342
|
+
], item[0]._serialize(this._id, item[1]), storageUpdates);
|
|
253
343
|
}
|
|
254
344
|
}
|
|
255
345
|
}
|
|
346
|
+
clear() {
|
|
347
|
+
if (this._doc) {
|
|
348
|
+
let ops = [];
|
|
349
|
+
let reverseOps = [];
|
|
350
|
+
let updateDelta = [];
|
|
351
|
+
let i = 0;
|
|
352
|
+
for (const item of __classPrivateFieldGet(this, _LiveList_items, "f")) {
|
|
353
|
+
item[0]._detach();
|
|
354
|
+
const childId = item[0]._id;
|
|
355
|
+
if (childId) {
|
|
356
|
+
ops.push({ id: childId, type: OpType.DeleteCrdt });
|
|
357
|
+
reverseOps.push(...item[0]._serialize(this._id, item[1]));
|
|
358
|
+
updateDelta.push({ index: i, type: "delete" });
|
|
359
|
+
}
|
|
360
|
+
i++;
|
|
361
|
+
}
|
|
362
|
+
__classPrivateFieldSet(this, _LiveList_items, [], "f");
|
|
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);
|
|
370
|
+
}
|
|
371
|
+
else {
|
|
372
|
+
for (const item of __classPrivateFieldGet(this, _LiveList_items, "f")) {
|
|
373
|
+
item[0]._detach();
|
|
374
|
+
}
|
|
375
|
+
__classPrivateFieldSet(this, _LiveList_items, [], "f");
|
|
376
|
+
}
|
|
377
|
+
}
|
|
256
378
|
/**
|
|
257
379
|
* Returns an Array of all the elements in the LiveList.
|
|
258
380
|
*/
|
|
259
381
|
toArray() {
|
|
260
382
|
return __classPrivateFieldGet(this, _LiveList_items, "f").map((entry) => selfOrRegisterValue(entry[0]));
|
|
261
383
|
}
|
|
384
|
+
toCrdtArray() {
|
|
385
|
+
return __classPrivateFieldGet(this, _LiveList_items, "f").map((entry) => entry[0]);
|
|
386
|
+
}
|
|
262
387
|
/**
|
|
263
388
|
* Tests whether all elements pass the test implemented by the provided function.
|
|
264
389
|
* @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 = this._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
|
*/
|