@liveblocks/client 0.13.0-beta.1 → 0.14.0-beta.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/README.md +8 -8
- package/lib/cjs/AbstractCrdt.d.ts +8 -4
- package/lib/cjs/AbstractCrdt.js +2 -2
- package/lib/cjs/LiveList.d.ts +8 -4
- package/lib/cjs/LiveList.js +36 -9
- package/lib/cjs/LiveMap.d.ts +7 -3
- package/lib/cjs/LiveMap.js +23 -5
- package/lib/cjs/LiveObject.d.ts +22 -7
- package/lib/cjs/LiveObject.js +82 -14
- package/lib/cjs/LiveRegister.d.ts +8 -4
- package/lib/cjs/LiveRegister.js +17 -4
- package/lib/cjs/live.d.ts +7 -0
- package/lib/cjs/room.d.ts +8 -0
- package/lib/cjs/room.js +104 -24
- package/lib/cjs/types.d.ts +47 -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 +8 -4
- package/lib/esm/LiveList.js +37 -10
- package/lib/esm/LiveMap.d.ts +7 -3
- package/lib/esm/LiveMap.js +23 -5
- package/lib/esm/LiveObject.d.ts +22 -7
- package/lib/esm/LiveObject.js +82 -14
- package/lib/esm/LiveRegister.d.ts +8 -4
- package/lib/esm/LiveRegister.js +18 -5
- package/lib/esm/live.d.ts +7 -0
- package/lib/esm/room.d.ts +8 -0
- package/lib/esm/room.js +105 -25
- package/lib/esm/types.d.ts +47 -1
- package/lib/esm/utils.d.ts +2 -1
- package/lib/esm/utils.js +75 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -8,17 +8,17 @@
|
|
|
8
8
|
|
|
9
9
|
**At [Liveblocks](https://liveblocks.io), we’re building tools to help companies create world-class collaborative products that attract, engage and retain users.** This repository is a set of open-source packages for building performant and reliable multiplayer experiences.
|
|
10
10
|
|
|
11
|
+
## Installation
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
npm install @liveblocks/client
|
|
15
|
+
```
|
|
16
|
+
|
|
11
17
|
## Examples
|
|
12
18
|
|
|
13
19
|
- Browse our gallery of collaborative UI patterns. [View examples gallery](https://liveblocks.io/examples)
|
|
14
20
|
- Explore and clone any of our open-source examples. [View code examples](https://github.com/liveblocks/liveblocks/tree/main/examples)
|
|
15
21
|
|
|
16
|
-
## Packages
|
|
17
|
-
|
|
18
|
-
- [@liveblocks/client](https://github.com/liveblocks/liveblocks/tree/main/packages/liveblocks)
|
|
19
|
-
- [@liveblocks/react](https://github.com/liveblocks/liveblocks/tree/main/packages/liveblocks-react)
|
|
20
|
-
- [@liveblocks/node](https://github.com/liveblocks/liveblocks/tree/main/packages/liveblocks-node)
|
|
21
|
-
|
|
22
22
|
## Documentation
|
|
23
23
|
|
|
24
24
|
[Read the documentation](https://liveblocks.io/docs) to start using Liveblocks.
|
|
@@ -35,11 +35,11 @@ For changelog, visit [https://github.com/liveblocks/liveblocks/releases](https:/
|
|
|
35
35
|
|
|
36
36
|
## Community
|
|
37
37
|
|
|
38
|
-
- [
|
|
38
|
+
- [Discord](https://discord.gg/X4YWJuH9VY) - To get involved with the Liveblocks community, ask questions and share tips.
|
|
39
39
|
- [Twitter](https://twitter.com/liveblocks) - To receive updates, announcements, blog posts, and general Liveblocks tips.
|
|
40
40
|
|
|
41
41
|
## License
|
|
42
42
|
|
|
43
43
|
Licensed under the Apache License 2.0, Copyright © 2021-present [Liveblocks](https://liveblocks.io).
|
|
44
44
|
|
|
45
|
-
See [LICENSE](
|
|
45
|
+
See [LICENSE](../../LICENSE) for more information.
|
|
@@ -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
|
*/
|
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,6 +276,7 @@ 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]);
|
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
|
*/
|
|
@@ -53,6 +63,11 @@ export declare class LiveObject<T extends Record<string, any> = Record<string, a
|
|
|
53
63
|
* @param key The key of the property to get
|
|
54
64
|
*/
|
|
55
65
|
get<TKey extends keyof T>(key: TKey): T[TKey];
|
|
66
|
+
/**
|
|
67
|
+
* Deletes a key from the LiveObject
|
|
68
|
+
* @param key The key of the property to delete
|
|
69
|
+
*/
|
|
70
|
+
delete(key: keyof T): void;
|
|
56
71
|
/**
|
|
57
72
|
* Adds or updates multiple properties at once with an object.
|
|
58
73
|
* @param overrides The object used to overrides properties
|
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
|
|
@@ -186,6 +214,47 @@ class LiveObject extends AbstractCrdt_1.AbstractCrdt {
|
|
|
186
214
|
get(key) {
|
|
187
215
|
return __classPrivateFieldGet(this, _LiveObject_map, "f").get(key);
|
|
188
216
|
}
|
|
217
|
+
/**
|
|
218
|
+
* Deletes a key from the LiveObject
|
|
219
|
+
* @param key The key of the property to delete
|
|
220
|
+
*/
|
|
221
|
+
delete(key) {
|
|
222
|
+
const keyAsString = key;
|
|
223
|
+
const oldValue = __classPrivateFieldGet(this, _LiveObject_map, "f").get(keyAsString);
|
|
224
|
+
if (oldValue === undefined) {
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
if (this._doc == null || this._id == null) {
|
|
228
|
+
if (oldValue instanceof AbstractCrdt_1.AbstractCrdt) {
|
|
229
|
+
oldValue._detach();
|
|
230
|
+
}
|
|
231
|
+
__classPrivateFieldGet(this, _LiveObject_map, "f").delete(keyAsString);
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
let reverse;
|
|
235
|
+
if (oldValue instanceof AbstractCrdt_1.AbstractCrdt) {
|
|
236
|
+
oldValue._detach();
|
|
237
|
+
reverse = oldValue._serialize(this._id, keyAsString);
|
|
238
|
+
}
|
|
239
|
+
else {
|
|
240
|
+
reverse = [
|
|
241
|
+
{
|
|
242
|
+
type: live_1.OpType.UpdateObject,
|
|
243
|
+
data: { [keyAsString]: oldValue },
|
|
244
|
+
id: this._id,
|
|
245
|
+
},
|
|
246
|
+
];
|
|
247
|
+
}
|
|
248
|
+
__classPrivateFieldGet(this, _LiveObject_map, "f").delete(keyAsString);
|
|
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]);
|
|
257
|
+
}
|
|
189
258
|
/**
|
|
190
259
|
* Adds or updates multiple properties at once with an object.
|
|
191
260
|
* @param overrides The object used to overrides properties
|
|
@@ -231,7 +300,7 @@ class LiveObject extends AbstractCrdt_1.AbstractCrdt {
|
|
|
231
300
|
if (newValue instanceof AbstractCrdt_1.AbstractCrdt) {
|
|
232
301
|
newValue._setParentLink(this, key);
|
|
233
302
|
newValue._attach(this._doc.generateId(), this._doc);
|
|
234
|
-
ops.push(...newValue._serialize(this._id, key));
|
|
303
|
+
ops.push(...newValue._serialize(this._id, key, this._doc));
|
|
235
304
|
}
|
|
236
305
|
else {
|
|
237
306
|
updatedProps[key] = newValue;
|
|
@@ -253,7 +322,7 @@ class LiveObject extends AbstractCrdt_1.AbstractCrdt {
|
|
|
253
322
|
}
|
|
254
323
|
}
|
|
255
324
|
exports.LiveObject = LiveObject;
|
|
256
|
-
_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) {
|
|
257
326
|
let isModified = false;
|
|
258
327
|
const reverse = [];
|
|
259
328
|
const reverseUpdate = {
|
|
@@ -275,11 +344,6 @@ _LiveObject_map = new WeakMap(), _LiveObject_propToLastUpdate = new WeakMap(), _
|
|
|
275
344
|
reverse.push({ type: live_1.OpType.DeleteObjectKey, id: this._id, key });
|
|
276
345
|
}
|
|
277
346
|
}
|
|
278
|
-
let isLocal = false;
|
|
279
|
-
if (op.opId == null) {
|
|
280
|
-
isLocal = true;
|
|
281
|
-
op.opId = this._doc.generateOpId();
|
|
282
|
-
}
|
|
283
347
|
for (const key in op.data) {
|
|
284
348
|
if (isLocal) {
|
|
285
349
|
__classPrivateFieldGet(this, _LiveObject_propToLastUpdate, "f").set(key, op.opId);
|
|
@@ -310,6 +374,10 @@ _LiveObject_map = new WeakMap(), _LiveObject_propToLastUpdate = new WeakMap(), _
|
|
|
310
374
|
return isModified ? { modified: this, reverse } : { modified: false };
|
|
311
375
|
}, _LiveObject_applyDeleteObjectKey = function _LiveObject_applyDeleteObjectKey(op) {
|
|
312
376
|
const key = op.key;
|
|
377
|
+
// If property does not exist, exit without notifying
|
|
378
|
+
if (__classPrivateFieldGet(this, _LiveObject_map, "f").has(key) === false) {
|
|
379
|
+
return { modified: false };
|
|
380
|
+
}
|
|
313
381
|
const oldValue = __classPrivateFieldGet(this, _LiveObject_map, "f").get(key);
|
|
314
382
|
let reverse = [];
|
|
315
383
|
if ((0, utils_1.isCrdt)(oldValue)) {
|
|
@@ -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;
|