@liveblocks/client 0.13.2 → 0.14.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 +8 -4
- package/lib/cjs/AbstractCrdt.js +2 -2
- package/lib/cjs/LiveList.d.ts +9 -4
- package/lib/cjs/LiveList.js +58 -9
- package/lib/cjs/LiveMap.d.ts +7 -3
- package/lib/cjs/LiveMap.js +23 -5
- package/lib/cjs/LiveObject.d.ts +17 -7
- package/lib/cjs/LiveObject.js +45 -15
- package/lib/cjs/LiveRegister.d.ts +8 -4
- package/lib/cjs/LiveRegister.js +17 -4
- package/lib/cjs/client.js +50 -7
- package/lib/cjs/{immutable/index.d.ts → immutable.d.ts} +5 -3
- package/lib/cjs/{immutable/index.js → immutable.js} +98 -21
- package/lib/cjs/index.d.ts +1 -1
- package/lib/cjs/live.d.ts +7 -0
- package/lib/cjs/room.d.ts +17 -9
- package/lib/cjs/room.js +203 -81
- package/lib/cjs/types.d.ts +26 -1
- package/lib/cjs/utils.d.ts +2 -1
- package/lib/cjs/utils.js +76 -1
- package/lib/esm/AbstractCrdt.d.ts +8 -4
- package/lib/esm/AbstractCrdt.js +2 -2
- package/lib/esm/LiveList.d.ts +9 -4
- package/lib/esm/LiveList.js +59 -10
- package/lib/esm/LiveMap.d.ts +7 -3
- package/lib/esm/LiveMap.js +23 -5
- package/lib/esm/LiveObject.d.ts +17 -7
- package/lib/esm/LiveObject.js +45 -15
- package/lib/esm/LiveRegister.d.ts +8 -4
- package/lib/esm/LiveRegister.js +18 -5
- package/lib/esm/client.js +50 -7
- package/lib/esm/{immutable/index.d.ts → immutable.d.ts} +5 -3
- package/lib/esm/{immutable/index.js → immutable.js} +96 -21
- package/lib/esm/index.d.ts +1 -1
- package/lib/esm/live.d.ts +7 -0
- package/lib/esm/room.d.ts +17 -9
- package/lib/esm/room.js +203 -62
- package/lib/esm/types.d.ts +26 -1
- package/lib/esm/utils.d.ts +2 -1
- package/lib/esm/utils.js +75 -1
- package/package.json +6 -2
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Op } from "./live";
|
|
1
|
+
import { Op, SerializedCrdt } from "./live";
|
|
2
2
|
export declare type ApplyResult = {
|
|
3
3
|
reverse: Op[];
|
|
4
4
|
modified: AbstractCrdt;
|
|
@@ -33,7 +33,7 @@ export declare abstract class AbstractCrdt {
|
|
|
33
33
|
/**
|
|
34
34
|
* INTERNAL
|
|
35
35
|
*/
|
|
36
|
-
_apply(op: Op): ApplyResult;
|
|
36
|
+
_apply(op: Op, isLocal: boolean): ApplyResult;
|
|
37
37
|
/**
|
|
38
38
|
* INTERNAL
|
|
39
39
|
*/
|
|
@@ -45,7 +45,7 @@ export declare abstract class AbstractCrdt {
|
|
|
45
45
|
/**
|
|
46
46
|
* INTERNAL
|
|
47
47
|
*/
|
|
48
|
-
abstract _attachChild(id: string, key: string, crdt: AbstractCrdt): ApplyResult;
|
|
48
|
+
abstract _attachChild(id: string, key: string, crdt: AbstractCrdt, isLocal: boolean): ApplyResult;
|
|
49
49
|
/**
|
|
50
50
|
* INTERNAL
|
|
51
51
|
*/
|
|
@@ -57,5 +57,9 @@ export declare abstract class AbstractCrdt {
|
|
|
57
57
|
/**
|
|
58
58
|
* INTERNAL
|
|
59
59
|
*/
|
|
60
|
-
abstract _serialize(parentId: string, parentKey: string): Op[];
|
|
60
|
+
abstract _serialize(parentId: string, parentKey: string, doc?: Doc): Op[];
|
|
61
|
+
/**
|
|
62
|
+
* INTERNAL
|
|
63
|
+
*/
|
|
64
|
+
abstract _toSerializedCrdt(): SerializedCrdt;
|
|
61
65
|
}
|
package/lib/cjs/AbstractCrdt.js
CHANGED
|
@@ -48,12 +48,12 @@ class AbstractCrdt {
|
|
|
48
48
|
/**
|
|
49
49
|
* INTERNAL
|
|
50
50
|
*/
|
|
51
|
-
_apply(op) {
|
|
51
|
+
_apply(op, isLocal) {
|
|
52
52
|
switch (op.type) {
|
|
53
53
|
case live_1.OpType.DeleteCrdt: {
|
|
54
54
|
if (this._parent != null && this._parentKey != null) {
|
|
55
55
|
const parent = this._parent;
|
|
56
|
-
const reverse = this._serialize(this._parent._id, this._parentKey);
|
|
56
|
+
const reverse = this._serialize(this._parent._id, this._parentKey, __classPrivateFieldGet(this, _AbstractCrdt_doc, "f"));
|
|
57
57
|
this._parent._detachChild(this);
|
|
58
58
|
return { modified: parent, reverse };
|
|
59
59
|
}
|
package/lib/cjs/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,7 @@ 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
17
|
/**
|
|
18
18
|
* INTERNAL
|
|
19
19
|
*/
|
|
@@ -25,7 +25,7 @@ export declare class LiveList<T> extends AbstractCrdt {
|
|
|
25
25
|
/**
|
|
26
26
|
* INTERNAL
|
|
27
27
|
*/
|
|
28
|
-
_attachChild(id: string, key: string, child: AbstractCrdt): ApplyResult;
|
|
28
|
+
_attachChild(id: string, key: string, child: AbstractCrdt, isLocal: boolean): ApplyResult;
|
|
29
29
|
/**
|
|
30
30
|
* INTERNAL
|
|
31
31
|
*/
|
|
@@ -37,7 +37,11 @@ export declare class LiveList<T> extends AbstractCrdt {
|
|
|
37
37
|
/**
|
|
38
38
|
* INTERNAL
|
|
39
39
|
*/
|
|
40
|
-
_apply(op: Op): ApplyResult;
|
|
40
|
+
_apply(op: Op, isLocal: boolean): ApplyResult;
|
|
41
|
+
/**
|
|
42
|
+
* INTERNAL
|
|
43
|
+
*/
|
|
44
|
+
_toSerializedCrdt(): SerializedCrdt;
|
|
41
45
|
/**
|
|
42
46
|
* Returns the number of elements.
|
|
43
47
|
*/
|
|
@@ -64,6 +68,7 @@ export declare class LiveList<T> extends AbstractCrdt {
|
|
|
64
68
|
* @param index The index of the element to delete
|
|
65
69
|
*/
|
|
66
70
|
delete(index: number): void;
|
|
71
|
+
clear(): void;
|
|
67
72
|
/**
|
|
68
73
|
* Returns an Array of all the elements in the LiveList.
|
|
69
74
|
*/
|
package/lib/cjs/LiveList.js
CHANGED
|
@@ -54,7 +54,7 @@ class LiveList extends AbstractCrdt_1.AbstractCrdt {
|
|
|
54
54
|
/**
|
|
55
55
|
* INTERNAL
|
|
56
56
|
*/
|
|
57
|
-
_serialize(parentId, parentKey) {
|
|
57
|
+
_serialize(parentId, parentKey, doc) {
|
|
58
58
|
if (this._id == null) {
|
|
59
59
|
throw new Error("Cannot serialize item is not attached");
|
|
60
60
|
}
|
|
@@ -64,13 +64,14 @@ class LiveList extends AbstractCrdt_1.AbstractCrdt {
|
|
|
64
64
|
const ops = [];
|
|
65
65
|
const op = {
|
|
66
66
|
id: this._id,
|
|
67
|
+
opId: doc === null || doc === void 0 ? void 0 : doc.generateOpId(),
|
|
67
68
|
type: live_1.OpType.CreateList,
|
|
68
69
|
parentId,
|
|
69
70
|
parentKey,
|
|
70
71
|
};
|
|
71
72
|
ops.push(op);
|
|
72
73
|
for (const [value, key] of __classPrivateFieldGet(this, _LiveList_items, "f")) {
|
|
73
|
-
ops.push(...value._serialize(this._id, key));
|
|
74
|
+
ops.push(...value._serialize(this._id, key, doc));
|
|
74
75
|
}
|
|
75
76
|
return ops;
|
|
76
77
|
}
|
|
@@ -95,7 +96,7 @@ class LiveList extends AbstractCrdt_1.AbstractCrdt {
|
|
|
95
96
|
/**
|
|
96
97
|
* INTERNAL
|
|
97
98
|
*/
|
|
98
|
-
_attachChild(id, key, child) {
|
|
99
|
+
_attachChild(id, key, child, isLocal) {
|
|
99
100
|
var _a;
|
|
100
101
|
if (this._doc == null) {
|
|
101
102
|
throw new Error("Can't attach child if doc is not present");
|
|
@@ -103,11 +104,24 @@ class LiveList extends AbstractCrdt_1.AbstractCrdt {
|
|
|
103
104
|
child._attach(id, this._doc);
|
|
104
105
|
child._setParentLink(this, key);
|
|
105
106
|
const index = __classPrivateFieldGet(this, _LiveList_items, "f").findIndex((entry) => entry[1] === key);
|
|
106
|
-
|
|
107
|
+
let newKey = key;
|
|
108
|
+
// If there is a conflict
|
|
107
109
|
if (index !== -1) {
|
|
108
|
-
|
|
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 = (0, position_1.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] = (0, position_1.makePosition)(key, (_a = __classPrivateFieldGet(this, _LiveList_items, "f")[index + 1]) === null || _a === void 0 ? void 0 : _a[1]);
|
|
122
|
+
}
|
|
109
123
|
}
|
|
110
|
-
__classPrivateFieldGet(this, _LiveList_items, "f").push([child,
|
|
124
|
+
__classPrivateFieldGet(this, _LiveList_items, "f").push([child, newKey]);
|
|
111
125
|
__classPrivateFieldGet(this, _LiveList_items, "f").sort((itemA, itemB) => (0, position_1.compare)(itemA[1], itemB[1]));
|
|
112
126
|
return { reverse: [{ type: live_1.OpType.DeleteCrdt, id }], modified: this };
|
|
113
127
|
}
|
|
@@ -141,8 +155,19 @@ class LiveList extends AbstractCrdt_1.AbstractCrdt {
|
|
|
141
155
|
/**
|
|
142
156
|
* INTERNAL
|
|
143
157
|
*/
|
|
144
|
-
_apply(op) {
|
|
145
|
-
return super._apply(op);
|
|
158
|
+
_apply(op, isLocal) {
|
|
159
|
+
return super._apply(op, isLocal);
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* INTERNAL
|
|
163
|
+
*/
|
|
164
|
+
_toSerializedCrdt() {
|
|
165
|
+
var _a;
|
|
166
|
+
return {
|
|
167
|
+
type: live_1.CrdtType.List,
|
|
168
|
+
parentId: (_a = this._parent) === null || _a === void 0 ? void 0 : _a._id,
|
|
169
|
+
parentKey: this._parentKey,
|
|
170
|
+
};
|
|
146
171
|
}
|
|
147
172
|
/**
|
|
148
173
|
* Returns the number of elements.
|
|
@@ -176,7 +201,7 @@ class LiveList extends AbstractCrdt_1.AbstractCrdt {
|
|
|
176
201
|
if (this._doc && this._id) {
|
|
177
202
|
const id = this._doc.generateId();
|
|
178
203
|
value._attach(id, this._doc);
|
|
179
|
-
this._doc.dispatch(value._serialize(this._id, position), [{ type: live_1.OpType.DeleteCrdt, id }], [this]);
|
|
204
|
+
this._doc.dispatch(value._serialize(this._id, position, this._doc), [{ type: live_1.OpType.DeleteCrdt, id }], [this]);
|
|
180
205
|
}
|
|
181
206
|
}
|
|
182
207
|
/**
|
|
@@ -222,6 +247,7 @@ class LiveList extends AbstractCrdt_1.AbstractCrdt {
|
|
|
222
247
|
{
|
|
223
248
|
type: live_1.OpType.SetParentKey,
|
|
224
249
|
id: item[0]._id,
|
|
250
|
+
opId: this._doc.generateOpId(),
|
|
225
251
|
parentKey: position,
|
|
226
252
|
},
|
|
227
253
|
], [
|
|
@@ -250,12 +276,35 @@ class LiveList extends AbstractCrdt_1.AbstractCrdt {
|
|
|
250
276
|
this._doc.dispatch([
|
|
251
277
|
{
|
|
252
278
|
id: childRecordId,
|
|
279
|
+
opId: this._doc.generateOpId(),
|
|
253
280
|
type: live_1.OpType.DeleteCrdt,
|
|
254
281
|
},
|
|
255
282
|
], item[0]._serialize(this._id, item[1]), [this]);
|
|
256
283
|
}
|
|
257
284
|
}
|
|
258
285
|
}
|
|
286
|
+
clear() {
|
|
287
|
+
if (this._doc) {
|
|
288
|
+
let ops = [];
|
|
289
|
+
let reverseOps = [];
|
|
290
|
+
for (const item of __classPrivateFieldGet(this, _LiveList_items, "f")) {
|
|
291
|
+
item[0]._detach();
|
|
292
|
+
const childId = item[0]._id;
|
|
293
|
+
if (childId) {
|
|
294
|
+
ops.push({ id: childId, type: live_1.OpType.DeleteCrdt });
|
|
295
|
+
reverseOps.push(...item[0]._serialize(this._id, item[1]));
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
__classPrivateFieldSet(this, _LiveList_items, [], "f");
|
|
299
|
+
this._doc.dispatch(ops, reverseOps, [this]);
|
|
300
|
+
}
|
|
301
|
+
else {
|
|
302
|
+
for (const item of __classPrivateFieldGet(this, _LiveList_items, "f")) {
|
|
303
|
+
item[0]._detach();
|
|
304
|
+
}
|
|
305
|
+
__classPrivateFieldSet(this, _LiveList_items, [], "f");
|
|
306
|
+
}
|
|
307
|
+
}
|
|
259
308
|
/**
|
|
260
309
|
* Returns an Array of all the elements in the LiveList.
|
|
261
310
|
*/
|
package/lib/cjs/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
|
*/
|
|
@@ -32,6 +32,10 @@ export declare class LiveMap<TKey extends string, TValue> extends AbstractCrdt {
|
|
|
32
32
|
* INTERNAL
|
|
33
33
|
*/
|
|
34
34
|
_detachChild(child: AbstractCrdt): void;
|
|
35
|
+
/**
|
|
36
|
+
* INTERNAL
|
|
37
|
+
*/
|
|
38
|
+
_toSerializedCrdt(): SerializedCrdt;
|
|
35
39
|
/**
|
|
36
40
|
* Returns a specified element from the LiveMap.
|
|
37
41
|
* @param key The key of the element to return.
|
package/lib/cjs/LiveMap.js
CHANGED
|
@@ -41,7 +41,7 @@ class LiveMap extends AbstractCrdt_1.AbstractCrdt {
|
|
|
41
41
|
/**
|
|
42
42
|
* INTERNAL
|
|
43
43
|
*/
|
|
44
|
-
_serialize(parentId, parentKey) {
|
|
44
|
+
_serialize(parentId, parentKey, doc) {
|
|
45
45
|
if (this._id == null) {
|
|
46
46
|
throw new Error("Cannot serialize item is not attached");
|
|
47
47
|
}
|
|
@@ -51,13 +51,14 @@ class LiveMap extends AbstractCrdt_1.AbstractCrdt {
|
|
|
51
51
|
const ops = [];
|
|
52
52
|
const op = {
|
|
53
53
|
id: this._id,
|
|
54
|
+
opId: doc === null || doc === void 0 ? void 0 : doc.generateOpId(),
|
|
54
55
|
type: live_1.OpType.CreateMap,
|
|
55
56
|
parentId,
|
|
56
57
|
parentKey,
|
|
57
58
|
};
|
|
58
59
|
ops.push(op);
|
|
59
60
|
for (const [key, value] of __classPrivateFieldGet(this, _LiveMap_map, "f")) {
|
|
60
|
-
ops.push(...value._serialize(this._id, key));
|
|
61
|
+
ops.push(...value._serialize(this._id, key, doc));
|
|
61
62
|
}
|
|
62
63
|
return ops;
|
|
63
64
|
}
|
|
@@ -99,7 +100,7 @@ class LiveMap extends AbstractCrdt_1.AbstractCrdt {
|
|
|
99
100
|
/**
|
|
100
101
|
* INTERNAL
|
|
101
102
|
*/
|
|
102
|
-
_attachChild(id, key, child) {
|
|
103
|
+
_attachChild(id, key, child, isLocal) {
|
|
103
104
|
if (this._doc == null) {
|
|
104
105
|
throw new Error("Can't attach child if doc is not present");
|
|
105
106
|
}
|
|
@@ -137,6 +138,17 @@ class LiveMap extends AbstractCrdt_1.AbstractCrdt {
|
|
|
137
138
|
}
|
|
138
139
|
child._detach();
|
|
139
140
|
}
|
|
141
|
+
/**
|
|
142
|
+
* INTERNAL
|
|
143
|
+
*/
|
|
144
|
+
_toSerializedCrdt() {
|
|
145
|
+
var _a;
|
|
146
|
+
return {
|
|
147
|
+
type: live_1.CrdtType.Map,
|
|
148
|
+
parentId: (_a = this._parent) === null || _a === void 0 ? void 0 : _a._id,
|
|
149
|
+
parentKey: this._parentKey,
|
|
150
|
+
};
|
|
151
|
+
}
|
|
140
152
|
/**
|
|
141
153
|
* Returns a specified element from the LiveMap.
|
|
142
154
|
* @param key The key of the element to return.
|
|
@@ -165,7 +177,7 @@ class LiveMap extends AbstractCrdt_1.AbstractCrdt {
|
|
|
165
177
|
if (this._doc && this._id) {
|
|
166
178
|
const id = this._doc.generateId();
|
|
167
179
|
item._attach(id, this._doc);
|
|
168
|
-
this._doc.dispatch(item._serialize(this._id, key), oldValue
|
|
180
|
+
this._doc.dispatch(item._serialize(this._id, key, this._doc), oldValue
|
|
169
181
|
? oldValue._serialize(this._id, key)
|
|
170
182
|
: [{ type: live_1.OpType.DeleteCrdt, id }], [this]);
|
|
171
183
|
}
|
|
@@ -195,7 +207,13 @@ class LiveMap extends AbstractCrdt_1.AbstractCrdt {
|
|
|
195
207
|
}
|
|
196
208
|
item._detach();
|
|
197
209
|
if (this._doc && item._id) {
|
|
198
|
-
this._doc.dispatch([
|
|
210
|
+
this._doc.dispatch([
|
|
211
|
+
{
|
|
212
|
+
type: live_1.OpType.DeleteCrdt,
|
|
213
|
+
id: item._id,
|
|
214
|
+
opId: this._doc.generateOpId(),
|
|
215
|
+
},
|
|
216
|
+
], item._serialize(this._id, key), [this]);
|
|
199
217
|
}
|
|
200
218
|
__classPrivateFieldGet(this, _LiveMap_map, "f").delete(key);
|
|
201
219
|
return true;
|
package/lib/cjs/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;
|
|
29
31
|
/**
|
|
30
32
|
* INTERNAL
|
|
31
33
|
*/
|
|
32
34
|
_detachChild(child: AbstractCrdt): void;
|
|
35
|
+
/**
|
|
36
|
+
* INTERNAL
|
|
37
|
+
*/
|
|
38
|
+
_detachChildren(): void;
|
|
33
39
|
/**
|
|
34
40
|
* INTERNAL
|
|
35
41
|
*/
|
|
@@ -37,7 +43,11 @@ 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;
|
|
41
51
|
/**
|
|
42
52
|
* Transform the LiveObject into a javascript object
|
|
43
53
|
*/
|
package/lib/cjs/LiveObject.js
CHANGED
|
@@ -38,13 +38,14 @@ class LiveObject extends AbstractCrdt_1.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
|
}
|
|
45
45
|
const ops = [];
|
|
46
46
|
const op = {
|
|
47
47
|
id: this._id,
|
|
48
|
+
opId: doc === null || doc === void 0 ? void 0 : doc.generateOpId(),
|
|
48
49
|
type: live_1.OpType.CreateObject,
|
|
49
50
|
parentId,
|
|
50
51
|
parentKey,
|
|
@@ -53,7 +54,7 @@ class LiveObject extends AbstractCrdt_1.AbstractCrdt {
|
|
|
53
54
|
ops.push(op);
|
|
54
55
|
for (const [key, value] of __classPrivateFieldGet(this, _LiveObject_map, "f")) {
|
|
55
56
|
if (value instanceof AbstractCrdt_1.AbstractCrdt) {
|
|
56
|
-
ops.push(...value._serialize(this._id, key));
|
|
57
|
+
ops.push(...value._serialize(this._id, key, doc));
|
|
57
58
|
}
|
|
58
59
|
else {
|
|
59
60
|
op.data[key] = value;
|
|
@@ -70,7 +71,13 @@ class LiveObject extends AbstractCrdt_1.AbstractCrdt {
|
|
|
70
71
|
}
|
|
71
72
|
const object = new LiveObject(item.data);
|
|
72
73
|
object._attach(id, doc);
|
|
73
|
-
|
|
74
|
+
return this._deserializeChildren(object, parentToChildren, doc);
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* INTERNAL
|
|
78
|
+
*/
|
|
79
|
+
static _deserializeChildren(object, parentToChildren, doc) {
|
|
80
|
+
const children = parentToChildren.get(object._id);
|
|
74
81
|
if (children == null) {
|
|
75
82
|
return object;
|
|
76
83
|
}
|
|
@@ -99,7 +106,7 @@ class LiveObject extends AbstractCrdt_1.AbstractCrdt {
|
|
|
99
106
|
/**
|
|
100
107
|
* INTERNAL
|
|
101
108
|
*/
|
|
102
|
-
_attachChild(id, key, child) {
|
|
109
|
+
_attachChild(id, key, child, isLocal) {
|
|
103
110
|
if (this._doc == null) {
|
|
104
111
|
throw new Error("Can't attach child if doc is not present");
|
|
105
112
|
}
|
|
@@ -141,6 +148,15 @@ class LiveObject extends AbstractCrdt_1.AbstractCrdt {
|
|
|
141
148
|
child._detach();
|
|
142
149
|
}
|
|
143
150
|
}
|
|
151
|
+
/**
|
|
152
|
+
* INTERNAL
|
|
153
|
+
*/
|
|
154
|
+
_detachChildren() {
|
|
155
|
+
for (const [key, value] of __classPrivateFieldGet(this, _LiveObject_map, "f")) {
|
|
156
|
+
__classPrivateFieldGet(this, _LiveObject_map, "f").delete(key);
|
|
157
|
+
value._detach();
|
|
158
|
+
}
|
|
159
|
+
}
|
|
144
160
|
/**
|
|
145
161
|
* INTERNAL
|
|
146
162
|
*/
|
|
@@ -155,14 +171,26 @@ class LiveObject extends AbstractCrdt_1.AbstractCrdt {
|
|
|
155
171
|
/**
|
|
156
172
|
* INTERNAL
|
|
157
173
|
*/
|
|
158
|
-
_apply(op) {
|
|
174
|
+
_apply(op, isLocal) {
|
|
159
175
|
if (op.type === live_1.OpType.UpdateObject) {
|
|
160
|
-
return __classPrivateFieldGet(this, _LiveObject_instances, "m", _LiveObject_applyUpdate).call(this, op);
|
|
176
|
+
return __classPrivateFieldGet(this, _LiveObject_instances, "m", _LiveObject_applyUpdate).call(this, op, isLocal);
|
|
161
177
|
}
|
|
162
178
|
else if (op.type === live_1.OpType.DeleteObjectKey) {
|
|
163
179
|
return __classPrivateFieldGet(this, _LiveObject_instances, "m", _LiveObject_applyDeleteObjectKey).call(this, op);
|
|
164
180
|
}
|
|
165
|
-
return super._apply(op);
|
|
181
|
+
return super._apply(op, isLocal);
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* INTERNAL
|
|
185
|
+
*/
|
|
186
|
+
_toSerializedCrdt() {
|
|
187
|
+
var _a;
|
|
188
|
+
return {
|
|
189
|
+
type: live_1.CrdtType.Object,
|
|
190
|
+
parentId: (_a = this._parent) === null || _a === void 0 ? void 0 : _a._id,
|
|
191
|
+
parentKey: this._parentKey,
|
|
192
|
+
data: this.toObject(),
|
|
193
|
+
};
|
|
166
194
|
}
|
|
167
195
|
/**
|
|
168
196
|
* Transform the LiveObject into a javascript object
|
|
@@ -218,7 +246,14 @@ class LiveObject extends AbstractCrdt_1.AbstractCrdt {
|
|
|
218
246
|
];
|
|
219
247
|
}
|
|
220
248
|
__classPrivateFieldGet(this, _LiveObject_map, "f").delete(keyAsString);
|
|
221
|
-
this._doc.dispatch([
|
|
249
|
+
this._doc.dispatch([
|
|
250
|
+
{
|
|
251
|
+
type: live_1.OpType.DeleteObjectKey,
|
|
252
|
+
key: keyAsString,
|
|
253
|
+
id: this._id,
|
|
254
|
+
opId: this._doc.generateOpId(),
|
|
255
|
+
},
|
|
256
|
+
], reverse, [this]);
|
|
222
257
|
}
|
|
223
258
|
/**
|
|
224
259
|
* Adds or updates multiple properties at once with an object.
|
|
@@ -265,7 +300,7 @@ class LiveObject extends AbstractCrdt_1.AbstractCrdt {
|
|
|
265
300
|
if (newValue instanceof AbstractCrdt_1.AbstractCrdt) {
|
|
266
301
|
newValue._setParentLink(this, key);
|
|
267
302
|
newValue._attach(this._doc.generateId(), this._doc);
|
|
268
|
-
ops.push(...newValue._serialize(this._id, key));
|
|
303
|
+
ops.push(...newValue._serialize(this._id, key, this._doc));
|
|
269
304
|
}
|
|
270
305
|
else {
|
|
271
306
|
updatedProps[key] = newValue;
|
|
@@ -287,7 +322,7 @@ class LiveObject extends AbstractCrdt_1.AbstractCrdt {
|
|
|
287
322
|
}
|
|
288
323
|
}
|
|
289
324
|
exports.LiveObject = LiveObject;
|
|
290
|
-
_LiveObject_map = new WeakMap(), _LiveObject_propToLastUpdate = new WeakMap(), _LiveObject_instances = new WeakSet(), _LiveObject_applyUpdate = function _LiveObject_applyUpdate(op) {
|
|
325
|
+
_LiveObject_map = new WeakMap(), _LiveObject_propToLastUpdate = new WeakMap(), _LiveObject_instances = new WeakSet(), _LiveObject_applyUpdate = function _LiveObject_applyUpdate(op, isLocal) {
|
|
291
326
|
let isModified = false;
|
|
292
327
|
const reverse = [];
|
|
293
328
|
const reverseUpdate = {
|
|
@@ -309,11 +344,6 @@ _LiveObject_map = new WeakMap(), _LiveObject_propToLastUpdate = new WeakMap(), _
|
|
|
309
344
|
reverse.push({ type: live_1.OpType.DeleteObjectKey, id: this._id, key });
|
|
310
345
|
}
|
|
311
346
|
}
|
|
312
|
-
let isLocal = false;
|
|
313
|
-
if (op.opId == null) {
|
|
314
|
-
isLocal = true;
|
|
315
|
-
op.opId = this._doc.generateOpId();
|
|
316
|
-
}
|
|
317
347
|
for (const key in op.data) {
|
|
318
348
|
if (isLocal) {
|
|
319
349
|
__classPrivateFieldGet(this, _LiveObject_propToLastUpdate, "f").set(key, op.opId);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { AbstractCrdt, Doc, ApplyResult } from "./AbstractCrdt";
|
|
2
|
-
import { SerializedCrdtWithId, Op } from "./live";
|
|
2
|
+
import { SerializedCrdtWithId, Op, SerializedCrdt } from "./live";
|
|
3
3
|
/**
|
|
4
4
|
* INTERNAL
|
|
5
5
|
*/
|
|
@@ -14,8 +14,12 @@ export declare class LiveRegister<TValue = any> extends AbstractCrdt {
|
|
|
14
14
|
/**
|
|
15
15
|
* INTERNAL
|
|
16
16
|
*/
|
|
17
|
-
_serialize(parentId: string, parentKey: string): Op[];
|
|
18
|
-
|
|
17
|
+
_serialize(parentId: string, parentKey: string, doc?: Doc): Op[];
|
|
18
|
+
/**
|
|
19
|
+
* INTERNAL
|
|
20
|
+
*/
|
|
21
|
+
_toSerializedCrdt(): SerializedCrdt;
|
|
22
|
+
_attachChild(id: string, key: string, crdt: AbstractCrdt, isLocal: boolean): ApplyResult;
|
|
19
23
|
_detachChild(crdt: AbstractCrdt): void;
|
|
20
|
-
_apply(op: Op): ApplyResult;
|
|
24
|
+
_apply(op: Op, isLocal: boolean): ApplyResult;
|
|
21
25
|
}
|
package/lib/cjs/LiveRegister.js
CHANGED
|
@@ -41,13 +41,14 @@ class LiveRegister extends AbstractCrdt_1.AbstractCrdt {
|
|
|
41
41
|
/**
|
|
42
42
|
* INTERNAL
|
|
43
43
|
*/
|
|
44
|
-
_serialize(parentId, parentKey) {
|
|
44
|
+
_serialize(parentId, parentKey, doc) {
|
|
45
45
|
if (this._id == null || parentId == null || parentKey == null) {
|
|
46
46
|
throw new Error("Cannot serialize register if parentId or parentKey is undefined");
|
|
47
47
|
}
|
|
48
48
|
return [
|
|
49
49
|
{
|
|
50
50
|
type: live_1.OpType.CreateRegister,
|
|
51
|
+
opId: doc === null || doc === void 0 ? void 0 : doc.generateOpId(),
|
|
51
52
|
id: this._id,
|
|
52
53
|
parentId,
|
|
53
54
|
parentKey,
|
|
@@ -55,14 +56,26 @@ class LiveRegister extends AbstractCrdt_1.AbstractCrdt {
|
|
|
55
56
|
},
|
|
56
57
|
];
|
|
57
58
|
}
|
|
58
|
-
|
|
59
|
+
/**
|
|
60
|
+
* INTERNAL
|
|
61
|
+
*/
|
|
62
|
+
_toSerializedCrdt() {
|
|
63
|
+
var _a;
|
|
64
|
+
return {
|
|
65
|
+
type: live_1.CrdtType.Register,
|
|
66
|
+
parentId: (_a = this._parent) === null || _a === void 0 ? void 0 : _a._id,
|
|
67
|
+
parentKey: this._parentKey,
|
|
68
|
+
data: this.data,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
_attachChild(id, key, crdt, isLocal) {
|
|
59
72
|
throw new Error("Method not implemented.");
|
|
60
73
|
}
|
|
61
74
|
_detachChild(crdt) {
|
|
62
75
|
throw new Error("Method not implemented.");
|
|
63
76
|
}
|
|
64
|
-
_apply(op) {
|
|
65
|
-
return super._apply(op);
|
|
77
|
+
_apply(op, isLocal) {
|
|
78
|
+
return super._apply(op, isLocal);
|
|
66
79
|
}
|
|
67
80
|
}
|
|
68
81
|
exports.LiveRegister = LiveRegister;
|
package/lib/cjs/client.js
CHANGED
|
@@ -29,11 +29,7 @@ const room_1 = require("./room");
|
|
|
29
29
|
*/
|
|
30
30
|
function createClient(options) {
|
|
31
31
|
const clientOptions = options;
|
|
32
|
-
|
|
33
|
-
if (clientOptions.throttle < 80 || clientOptions.throttle > 1000) {
|
|
34
|
-
throw new Error("Liveblocks client throttle should be between 80 and 1000 ms");
|
|
35
|
-
}
|
|
36
|
-
}
|
|
32
|
+
const throttleDelay = getThrottleDelayFromOptions(options);
|
|
37
33
|
const rooms = new Map();
|
|
38
34
|
function getRoom(roomId) {
|
|
39
35
|
const internalRoom = rooms.get(roomId);
|
|
@@ -44,9 +40,21 @@ function createClient(options) {
|
|
|
44
40
|
if (internalRoom) {
|
|
45
41
|
return internalRoom.room;
|
|
46
42
|
}
|
|
47
|
-
internalRoom = (0, room_1.createRoom)(
|
|
43
|
+
internalRoom = (0, room_1.createRoom)({
|
|
44
|
+
defaultPresence: options.defaultPresence,
|
|
45
|
+
defaultStorageRoot: options.defaultStorageRoot,
|
|
46
|
+
}, {
|
|
47
|
+
room: roomId,
|
|
48
|
+
throttleDelay,
|
|
49
|
+
WebSocketPolyfill: clientOptions.WebSocketPolyfill,
|
|
50
|
+
fetchPolyfill: clientOptions.fetchPolyfill,
|
|
51
|
+
liveblocksServer: clientOptions.liveblocksServer || "wss://liveblocks.net/v5",
|
|
52
|
+
authentication: prepareAuthentication(clientOptions),
|
|
53
|
+
});
|
|
48
54
|
rooms.set(roomId, internalRoom);
|
|
49
|
-
|
|
55
|
+
if (!options.DO_NOT_USE_withoutConnecting) {
|
|
56
|
+
internalRoom.connect();
|
|
57
|
+
}
|
|
50
58
|
return internalRoom.room;
|
|
51
59
|
}
|
|
52
60
|
function leave(roomId) {
|
|
@@ -78,3 +86,38 @@ function createClient(options) {
|
|
|
78
86
|
};
|
|
79
87
|
}
|
|
80
88
|
exports.createClient = createClient;
|
|
89
|
+
function getThrottleDelayFromOptions(options) {
|
|
90
|
+
if (options.throttle === undefined) {
|
|
91
|
+
return 100;
|
|
92
|
+
}
|
|
93
|
+
if (typeof options.throttle !== "number" ||
|
|
94
|
+
options.throttle < 80 ||
|
|
95
|
+
options.throttle > 1000) {
|
|
96
|
+
throw new Error("throttle should be a number between 80 and 1000.");
|
|
97
|
+
}
|
|
98
|
+
return options.throttle;
|
|
99
|
+
}
|
|
100
|
+
function prepareAuthentication(clientOptions) {
|
|
101
|
+
// TODO: throw descriptive errors for invalid options
|
|
102
|
+
if (typeof clientOptions.publicApiKey === "string") {
|
|
103
|
+
return {
|
|
104
|
+
type: "public",
|
|
105
|
+
publicApiKey: clientOptions.publicApiKey,
|
|
106
|
+
url: clientOptions.publicAuthorizeEndpoint ||
|
|
107
|
+
"https://liveblocks.io/api/public/authorize",
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
else if (typeof clientOptions.authEndpoint === "string") {
|
|
111
|
+
return {
|
|
112
|
+
type: "private",
|
|
113
|
+
url: clientOptions.authEndpoint,
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
else if (typeof clientOptions.authEndpoint === "function") {
|
|
117
|
+
return {
|
|
118
|
+
type: "custom",
|
|
119
|
+
callback: clientOptions.authEndpoint,
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
throw new Error("Invalid Liveblocks client options. For more information: https://liveblocks.io/docs/api-reference/liveblocks-client#createClient");
|
|
123
|
+
}
|