@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/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,13 +61,14 @@ 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
|
}
|
|
@@ -92,7 +93,7 @@ export class LiveList extends AbstractCrdt {
|
|
|
92
93
|
/**
|
|
93
94
|
* INTERNAL
|
|
94
95
|
*/
|
|
95
|
-
_attachChild(id, key, child) {
|
|
96
|
+
_attachChild(id, key, child, isLocal) {
|
|
96
97
|
var _a;
|
|
97
98
|
if (this._doc == null) {
|
|
98
99
|
throw new Error("Can't attach child if doc is not present");
|
|
@@ -100,11 +101,24 @@ export class LiveList extends AbstractCrdt {
|
|
|
100
101
|
child._attach(id, this._doc);
|
|
101
102
|
child._setParentLink(this, key);
|
|
102
103
|
const index = __classPrivateFieldGet(this, _LiveList_items, "f").findIndex((entry) => entry[1] === key);
|
|
103
|
-
|
|
104
|
+
let newKey = key;
|
|
105
|
+
// If there is a conflict
|
|
104
106
|
if (index !== -1) {
|
|
105
|
-
|
|
107
|
+
if (isLocal) {
|
|
108
|
+
// If change is local => assign a temporary position to newly attached child
|
|
109
|
+
let before = __classPrivateFieldGet(this, _LiveList_items, "f")[index] ? __classPrivateFieldGet(this, _LiveList_items, "f")[index][1] : undefined;
|
|
110
|
+
let after = __classPrivateFieldGet(this, _LiveList_items, "f")[index + 1]
|
|
111
|
+
? __classPrivateFieldGet(this, _LiveList_items, "f")[index + 1][1]
|
|
112
|
+
: undefined;
|
|
113
|
+
newKey = makePosition(before, after);
|
|
114
|
+
child._setParentLink(this, newKey);
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
// If change is remote => assign a temporary position to existing child until we get the fix from the backend
|
|
118
|
+
__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]);
|
|
119
|
+
}
|
|
106
120
|
}
|
|
107
|
-
__classPrivateFieldGet(this, _LiveList_items, "f").push([child,
|
|
121
|
+
__classPrivateFieldGet(this, _LiveList_items, "f").push([child, newKey]);
|
|
108
122
|
__classPrivateFieldGet(this, _LiveList_items, "f").sort((itemA, itemB) => compare(itemA[1], itemB[1]));
|
|
109
123
|
return { reverse: [{ type: OpType.DeleteCrdt, id }], modified: this };
|
|
110
124
|
}
|
|
@@ -138,8 +152,19 @@ export class LiveList extends AbstractCrdt {
|
|
|
138
152
|
/**
|
|
139
153
|
* INTERNAL
|
|
140
154
|
*/
|
|
141
|
-
_apply(op) {
|
|
142
|
-
return super._apply(op);
|
|
155
|
+
_apply(op, isLocal) {
|
|
156
|
+
return super._apply(op, isLocal);
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* INTERNAL
|
|
160
|
+
*/
|
|
161
|
+
_toSerializedCrdt() {
|
|
162
|
+
var _a;
|
|
163
|
+
return {
|
|
164
|
+
type: CrdtType.List,
|
|
165
|
+
parentId: (_a = this._parent) === null || _a === void 0 ? void 0 : _a._id,
|
|
166
|
+
parentKey: this._parentKey,
|
|
167
|
+
};
|
|
143
168
|
}
|
|
144
169
|
/**
|
|
145
170
|
* Returns the number of elements.
|
|
@@ -173,7 +198,7 @@ export class LiveList extends AbstractCrdt {
|
|
|
173
198
|
if (this._doc && this._id) {
|
|
174
199
|
const id = this._doc.generateId();
|
|
175
200
|
value._attach(id, this._doc);
|
|
176
|
-
this._doc.dispatch(value._serialize(this._id, position), [{ type: OpType.DeleteCrdt, id }], [this]);
|
|
201
|
+
this._doc.dispatch(value._serialize(this._id, position, this._doc), [{ type: OpType.DeleteCrdt, id }], [this]);
|
|
177
202
|
}
|
|
178
203
|
}
|
|
179
204
|
/**
|
|
@@ -219,6 +244,7 @@ export class LiveList extends AbstractCrdt {
|
|
|
219
244
|
{
|
|
220
245
|
type: OpType.SetParentKey,
|
|
221
246
|
id: item[0]._id,
|
|
247
|
+
opId: this._doc.generateOpId(),
|
|
222
248
|
parentKey: position,
|
|
223
249
|
},
|
|
224
250
|
], [
|
|
@@ -247,6 +273,7 @@ export class LiveList extends AbstractCrdt {
|
|
|
247
273
|
this._doc.dispatch([
|
|
248
274
|
{
|
|
249
275
|
id: childRecordId,
|
|
276
|
+
opId: this._doc.generateOpId(),
|
|
250
277
|
type: OpType.DeleteCrdt,
|
|
251
278
|
},
|
|
252
279
|
], item[0]._serialize(this._id, item[1]), [this]);
|
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
|
*/
|
|
@@ -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/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
|
}
|
|
@@ -134,6 +135,17 @@ export class LiveMap extends AbstractCrdt {
|
|
|
134
135
|
}
|
|
135
136
|
child._detach();
|
|
136
137
|
}
|
|
138
|
+
/**
|
|
139
|
+
* INTERNAL
|
|
140
|
+
*/
|
|
141
|
+
_toSerializedCrdt() {
|
|
142
|
+
var _a;
|
|
143
|
+
return {
|
|
144
|
+
type: CrdtType.Map,
|
|
145
|
+
parentId: (_a = this._parent) === null || _a === void 0 ? void 0 : _a._id,
|
|
146
|
+
parentKey: this._parentKey,
|
|
147
|
+
};
|
|
148
|
+
}
|
|
137
149
|
/**
|
|
138
150
|
* Returns a specified element from the LiveMap.
|
|
139
151
|
* @param key The key of the element to return.
|
|
@@ -162,7 +174,7 @@ export class LiveMap extends AbstractCrdt {
|
|
|
162
174
|
if (this._doc && this._id) {
|
|
163
175
|
const id = this._doc.generateId();
|
|
164
176
|
item._attach(id, this._doc);
|
|
165
|
-
this._doc.dispatch(item._serialize(this._id, key), oldValue
|
|
177
|
+
this._doc.dispatch(item._serialize(this._id, key, this._doc), oldValue
|
|
166
178
|
? oldValue._serialize(this._id, key)
|
|
167
179
|
: [{ type: OpType.DeleteCrdt, id }], [this]);
|
|
168
180
|
}
|
|
@@ -192,7 +204,13 @@ export class LiveMap extends AbstractCrdt {
|
|
|
192
204
|
}
|
|
193
205
|
item._detach();
|
|
194
206
|
if (this._doc && item._id) {
|
|
195
|
-
this._doc.dispatch([
|
|
207
|
+
this._doc.dispatch([
|
|
208
|
+
{
|
|
209
|
+
type: OpType.DeleteCrdt,
|
|
210
|
+
id: item._id,
|
|
211
|
+
opId: this._doc.generateOpId(),
|
|
212
|
+
},
|
|
213
|
+
], item._serialize(this._id, key), [this]);
|
|
196
214
|
}
|
|
197
215
|
__classPrivateFieldGet(this, _LiveMap_map, "f").delete(key);
|
|
198
216
|
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;
|
|
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/esm/LiveObject.js
CHANGED
|
@@ -35,13 +35,14 @@ export class LiveObject extends AbstractCrdt {
|
|
|
35
35
|
/**
|
|
36
36
|
* INTERNAL
|
|
37
37
|
*/
|
|
38
|
-
_serialize(parentId, parentKey) {
|
|
38
|
+
_serialize(parentId, parentKey, doc) {
|
|
39
39
|
if (this._id == null) {
|
|
40
40
|
throw new Error("Cannot serialize item is not attached");
|
|
41
41
|
}
|
|
42
42
|
const ops = [];
|
|
43
43
|
const op = {
|
|
44
44
|
id: this._id,
|
|
45
|
+
opId: doc === null || doc === void 0 ? void 0 : doc.generateOpId(),
|
|
45
46
|
type: OpType.CreateObject,
|
|
46
47
|
parentId,
|
|
47
48
|
parentKey,
|
|
@@ -50,7 +51,7 @@ export class LiveObject extends AbstractCrdt {
|
|
|
50
51
|
ops.push(op);
|
|
51
52
|
for (const [key, value] of __classPrivateFieldGet(this, _LiveObject_map, "f")) {
|
|
52
53
|
if (value instanceof AbstractCrdt) {
|
|
53
|
-
ops.push(...value._serialize(this._id, key));
|
|
54
|
+
ops.push(...value._serialize(this._id, key, doc));
|
|
54
55
|
}
|
|
55
56
|
else {
|
|
56
57
|
op.data[key] = value;
|
|
@@ -67,7 +68,13 @@ export class LiveObject extends AbstractCrdt {
|
|
|
67
68
|
}
|
|
68
69
|
const object = new LiveObject(item.data);
|
|
69
70
|
object._attach(id, doc);
|
|
70
|
-
|
|
71
|
+
return this._deserializeChildren(object, parentToChildren, doc);
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* INTERNAL
|
|
75
|
+
*/
|
|
76
|
+
static _deserializeChildren(object, parentToChildren, doc) {
|
|
77
|
+
const children = parentToChildren.get(object._id);
|
|
71
78
|
if (children == null) {
|
|
72
79
|
return object;
|
|
73
80
|
}
|
|
@@ -96,7 +103,7 @@ export class LiveObject extends AbstractCrdt {
|
|
|
96
103
|
/**
|
|
97
104
|
* INTERNAL
|
|
98
105
|
*/
|
|
99
|
-
_attachChild(id, key, child) {
|
|
106
|
+
_attachChild(id, key, child, isLocal) {
|
|
100
107
|
if (this._doc == null) {
|
|
101
108
|
throw new Error("Can't attach child if doc is not present");
|
|
102
109
|
}
|
|
@@ -138,6 +145,15 @@ export class LiveObject extends AbstractCrdt {
|
|
|
138
145
|
child._detach();
|
|
139
146
|
}
|
|
140
147
|
}
|
|
148
|
+
/**
|
|
149
|
+
* INTERNAL
|
|
150
|
+
*/
|
|
151
|
+
_detachChildren() {
|
|
152
|
+
for (const [key, value] of __classPrivateFieldGet(this, _LiveObject_map, "f")) {
|
|
153
|
+
__classPrivateFieldGet(this, _LiveObject_map, "f").delete(key);
|
|
154
|
+
value._detach();
|
|
155
|
+
}
|
|
156
|
+
}
|
|
141
157
|
/**
|
|
142
158
|
* INTERNAL
|
|
143
159
|
*/
|
|
@@ -152,14 +168,26 @@ export class LiveObject extends AbstractCrdt {
|
|
|
152
168
|
/**
|
|
153
169
|
* INTERNAL
|
|
154
170
|
*/
|
|
155
|
-
_apply(op) {
|
|
171
|
+
_apply(op, isLocal) {
|
|
156
172
|
if (op.type === OpType.UpdateObject) {
|
|
157
|
-
return __classPrivateFieldGet(this, _LiveObject_instances, "m", _LiveObject_applyUpdate).call(this, op);
|
|
173
|
+
return __classPrivateFieldGet(this, _LiveObject_instances, "m", _LiveObject_applyUpdate).call(this, op, isLocal);
|
|
158
174
|
}
|
|
159
175
|
else if (op.type === OpType.DeleteObjectKey) {
|
|
160
176
|
return __classPrivateFieldGet(this, _LiveObject_instances, "m", _LiveObject_applyDeleteObjectKey).call(this, op);
|
|
161
177
|
}
|
|
162
|
-
return super._apply(op);
|
|
178
|
+
return super._apply(op, isLocal);
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* INTERNAL
|
|
182
|
+
*/
|
|
183
|
+
_toSerializedCrdt() {
|
|
184
|
+
var _a;
|
|
185
|
+
return {
|
|
186
|
+
type: CrdtType.Object,
|
|
187
|
+
parentId: (_a = this._parent) === null || _a === void 0 ? void 0 : _a._id,
|
|
188
|
+
parentKey: this._parentKey,
|
|
189
|
+
data: this.toObject(),
|
|
190
|
+
};
|
|
163
191
|
}
|
|
164
192
|
/**
|
|
165
193
|
* Transform the LiveObject into a javascript object
|
|
@@ -183,6 +211,47 @@ export class LiveObject extends AbstractCrdt {
|
|
|
183
211
|
get(key) {
|
|
184
212
|
return __classPrivateFieldGet(this, _LiveObject_map, "f").get(key);
|
|
185
213
|
}
|
|
214
|
+
/**
|
|
215
|
+
* Deletes a key from the LiveObject
|
|
216
|
+
* @param key The key of the property to delete
|
|
217
|
+
*/
|
|
218
|
+
delete(key) {
|
|
219
|
+
const keyAsString = key;
|
|
220
|
+
const oldValue = __classPrivateFieldGet(this, _LiveObject_map, "f").get(keyAsString);
|
|
221
|
+
if (oldValue === undefined) {
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
if (this._doc == null || this._id == null) {
|
|
225
|
+
if (oldValue instanceof AbstractCrdt) {
|
|
226
|
+
oldValue._detach();
|
|
227
|
+
}
|
|
228
|
+
__classPrivateFieldGet(this, _LiveObject_map, "f").delete(keyAsString);
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
let reverse;
|
|
232
|
+
if (oldValue instanceof AbstractCrdt) {
|
|
233
|
+
oldValue._detach();
|
|
234
|
+
reverse = oldValue._serialize(this._id, keyAsString);
|
|
235
|
+
}
|
|
236
|
+
else {
|
|
237
|
+
reverse = [
|
|
238
|
+
{
|
|
239
|
+
type: OpType.UpdateObject,
|
|
240
|
+
data: { [keyAsString]: oldValue },
|
|
241
|
+
id: this._id,
|
|
242
|
+
},
|
|
243
|
+
];
|
|
244
|
+
}
|
|
245
|
+
__classPrivateFieldGet(this, _LiveObject_map, "f").delete(keyAsString);
|
|
246
|
+
this._doc.dispatch([
|
|
247
|
+
{
|
|
248
|
+
type: OpType.DeleteObjectKey,
|
|
249
|
+
key: keyAsString,
|
|
250
|
+
id: this._id,
|
|
251
|
+
opId: this._doc.generateOpId(),
|
|
252
|
+
},
|
|
253
|
+
], reverse, [this]);
|
|
254
|
+
}
|
|
186
255
|
/**
|
|
187
256
|
* Adds or updates multiple properties at once with an object.
|
|
188
257
|
* @param overrides The object used to overrides properties
|
|
@@ -228,7 +297,7 @@ export class LiveObject extends AbstractCrdt {
|
|
|
228
297
|
if (newValue instanceof AbstractCrdt) {
|
|
229
298
|
newValue._setParentLink(this, key);
|
|
230
299
|
newValue._attach(this._doc.generateId(), this._doc);
|
|
231
|
-
ops.push(...newValue._serialize(this._id, key));
|
|
300
|
+
ops.push(...newValue._serialize(this._id, key, this._doc));
|
|
232
301
|
}
|
|
233
302
|
else {
|
|
234
303
|
updatedProps[key] = newValue;
|
|
@@ -249,7 +318,7 @@ export class LiveObject extends AbstractCrdt {
|
|
|
249
318
|
this._doc.dispatch(ops, reverseOps, [this]);
|
|
250
319
|
}
|
|
251
320
|
}
|
|
252
|
-
_LiveObject_map = new WeakMap(), _LiveObject_propToLastUpdate = new WeakMap(), _LiveObject_instances = new WeakSet(), _LiveObject_applyUpdate = function _LiveObject_applyUpdate(op) {
|
|
321
|
+
_LiveObject_map = new WeakMap(), _LiveObject_propToLastUpdate = new WeakMap(), _LiveObject_instances = new WeakSet(), _LiveObject_applyUpdate = function _LiveObject_applyUpdate(op, isLocal) {
|
|
253
322
|
let isModified = false;
|
|
254
323
|
const reverse = [];
|
|
255
324
|
const reverseUpdate = {
|
|
@@ -271,11 +340,6 @@ _LiveObject_map = new WeakMap(), _LiveObject_propToLastUpdate = new WeakMap(), _
|
|
|
271
340
|
reverse.push({ type: OpType.DeleteObjectKey, id: this._id, key });
|
|
272
341
|
}
|
|
273
342
|
}
|
|
274
|
-
let isLocal = false;
|
|
275
|
-
if (op.opId == null) {
|
|
276
|
-
isLocal = true;
|
|
277
|
-
op.opId = this._doc.generateOpId();
|
|
278
|
-
}
|
|
279
343
|
for (const key in op.data) {
|
|
280
344
|
if (isLocal) {
|
|
281
345
|
__classPrivateFieldGet(this, _LiveObject_propToLastUpdate, "f").set(key, op.opId);
|
|
@@ -306,6 +370,10 @@ _LiveObject_map = new WeakMap(), _LiveObject_propToLastUpdate = new WeakMap(), _
|
|
|
306
370
|
return isModified ? { modified: this, reverse } : { modified: false };
|
|
307
371
|
}, _LiveObject_applyDeleteObjectKey = function _LiveObject_applyDeleteObjectKey(op) {
|
|
308
372
|
const key = op.key;
|
|
373
|
+
// If property does not exist, exit without notifying
|
|
374
|
+
if (__classPrivateFieldGet(this, _LiveObject_map, "f").has(key) === false) {
|
|
375
|
+
return { modified: false };
|
|
376
|
+
}
|
|
309
377
|
const oldValue = __classPrivateFieldGet(this, _LiveObject_map, "f").get(key);
|
|
310
378
|
let reverse = [];
|
|
311
379
|
if (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/esm/LiveRegister.js
CHANGED
|
@@ -11,7 +11,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
11
11
|
};
|
|
12
12
|
var _LiveRegister_data;
|
|
13
13
|
import { AbstractCrdt } from "./AbstractCrdt";
|
|
14
|
-
import { CrdtType, OpType } from "./live";
|
|
14
|
+
import { CrdtType, OpType, } from "./live";
|
|
15
15
|
/**
|
|
16
16
|
* INTERNAL
|
|
17
17
|
*/
|
|
@@ -38,13 +38,14 @@ export class LiveRegister extends AbstractCrdt {
|
|
|
38
38
|
/**
|
|
39
39
|
* INTERNAL
|
|
40
40
|
*/
|
|
41
|
-
_serialize(parentId, parentKey) {
|
|
41
|
+
_serialize(parentId, parentKey, doc) {
|
|
42
42
|
if (this._id == null || parentId == null || parentKey == null) {
|
|
43
43
|
throw new Error("Cannot serialize register if parentId or parentKey is undefined");
|
|
44
44
|
}
|
|
45
45
|
return [
|
|
46
46
|
{
|
|
47
47
|
type: OpType.CreateRegister,
|
|
48
|
+
opId: doc === null || doc === void 0 ? void 0 : doc.generateOpId(),
|
|
48
49
|
id: this._id,
|
|
49
50
|
parentId,
|
|
50
51
|
parentKey,
|
|
@@ -52,14 +53,26 @@ export class LiveRegister extends AbstractCrdt {
|
|
|
52
53
|
},
|
|
53
54
|
];
|
|
54
55
|
}
|
|
55
|
-
|
|
56
|
+
/**
|
|
57
|
+
* INTERNAL
|
|
58
|
+
*/
|
|
59
|
+
_toSerializedCrdt() {
|
|
60
|
+
var _a;
|
|
61
|
+
return {
|
|
62
|
+
type: CrdtType.Register,
|
|
63
|
+
parentId: (_a = this._parent) === null || _a === void 0 ? void 0 : _a._id,
|
|
64
|
+
parentKey: this._parentKey,
|
|
65
|
+
data: this.data,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
_attachChild(id, key, crdt, isLocal) {
|
|
56
69
|
throw new Error("Method not implemented.");
|
|
57
70
|
}
|
|
58
71
|
_detachChild(crdt) {
|
|
59
72
|
throw new Error("Method not implemented.");
|
|
60
73
|
}
|
|
61
|
-
_apply(op) {
|
|
62
|
-
return super._apply(op);
|
|
74
|
+
_apply(op, isLocal) {
|
|
75
|
+
return super._apply(op, isLocal);
|
|
63
76
|
}
|
|
64
77
|
}
|
|
65
78
|
_LiveRegister_data = new WeakMap();
|
package/lib/esm/live.d.ts
CHANGED
|
@@ -122,6 +122,7 @@ export declare type UpdateObjectOp = {
|
|
|
122
122
|
};
|
|
123
123
|
};
|
|
124
124
|
export declare type CreateObjectOp = {
|
|
125
|
+
opId?: string;
|
|
125
126
|
id: string;
|
|
126
127
|
type: OpType.CreateObject;
|
|
127
128
|
parentId?: string;
|
|
@@ -131,18 +132,21 @@ export declare type CreateObjectOp = {
|
|
|
131
132
|
};
|
|
132
133
|
};
|
|
133
134
|
export declare type CreateListOp = {
|
|
135
|
+
opId?: string;
|
|
134
136
|
id: string;
|
|
135
137
|
type: OpType.CreateList;
|
|
136
138
|
parentId: string;
|
|
137
139
|
parentKey: string;
|
|
138
140
|
};
|
|
139
141
|
export declare type CreateMapOp = {
|
|
142
|
+
opId?: string;
|
|
140
143
|
id: string;
|
|
141
144
|
type: OpType.CreateMap;
|
|
142
145
|
parentId: string;
|
|
143
146
|
parentKey: string;
|
|
144
147
|
};
|
|
145
148
|
export declare type CreateRegisterOp = {
|
|
149
|
+
opId?: string;
|
|
146
150
|
id: string;
|
|
147
151
|
type: OpType.CreateRegister;
|
|
148
152
|
parentId: string;
|
|
@@ -150,15 +154,18 @@ export declare type CreateRegisterOp = {
|
|
|
150
154
|
data: any;
|
|
151
155
|
};
|
|
152
156
|
export declare type DeleteCrdtOp = {
|
|
157
|
+
opId?: string;
|
|
153
158
|
id: string;
|
|
154
159
|
type: OpType.DeleteCrdt;
|
|
155
160
|
};
|
|
156
161
|
export declare type SetParentKeyOp = {
|
|
162
|
+
opId?: string;
|
|
157
163
|
id: string;
|
|
158
164
|
type: OpType.SetParentKey;
|
|
159
165
|
parentKey: string;
|
|
160
166
|
};
|
|
161
167
|
export declare type DeleteObjectKeyOp = {
|
|
168
|
+
opId?: string;
|
|
162
169
|
id: string;
|
|
163
170
|
type: OpType.DeleteObjectKey;
|
|
164
171
|
key: string;
|
package/lib/esm/room.d.ts
CHANGED
|
@@ -11,6 +11,7 @@ declare type HistoryItem = Array<Op | {
|
|
|
11
11
|
declare type IdFactory = () => string;
|
|
12
12
|
export declare type State = {
|
|
13
13
|
connection: Connection;
|
|
14
|
+
lastConnectionId: number | null;
|
|
14
15
|
socket: WebSocket | null;
|
|
15
16
|
lastFlushTime: number;
|
|
16
17
|
buffer: {
|
|
@@ -62,6 +63,7 @@ export declare type State = {
|
|
|
62
63
|
nodes: Set<AbstractCrdt>;
|
|
63
64
|
};
|
|
64
65
|
};
|
|
66
|
+
offlineOperations: Map<string, Op>;
|
|
65
67
|
};
|
|
66
68
|
export declare type Effects = {
|
|
67
69
|
authenticate(): void;
|
|
@@ -89,6 +91,12 @@ export declare function makeStateMachine(state: State, context: Context, mockedE
|
|
|
89
91
|
authenticationSuccess: (token: AuthenticationToken, socket: WebSocket) => void;
|
|
90
92
|
heartbeat: () => void;
|
|
91
93
|
onNavigatorOnline: () => void;
|
|
94
|
+
simulateSocketClose: () => void;
|
|
95
|
+
simulateSendCloseEvent: (event: {
|
|
96
|
+
code: number;
|
|
97
|
+
wasClean: boolean;
|
|
98
|
+
reason: any;
|
|
99
|
+
}) => void;
|
|
92
100
|
onVisibilityChange: (visibilityState: VisibilityState) => void;
|
|
93
101
|
getUndoStack: () => HistoryItem[];
|
|
94
102
|
getItemsCount: () => number;
|