@liveblocks/client 0.12.0-beta.13 → 0.12.0-beta.14
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/doc.d.ts +179 -10
- package/lib/cjs/doc.js +466 -187
- package/lib/cjs/live.d.ts +1 -1
- package/lib/cjs/room.d.ts +2 -0
- package/lib/cjs/room.js +10 -0
- package/lib/cjs/storage.d.ts +2 -0
- package/lib/cjs/storage.js +9 -3
- package/lib/cjs/types.d.ts +2 -0
- package/lib/esm/doc.d.ts +179 -10
- package/lib/esm/doc.js +466 -187
- package/lib/esm/live.d.ts +1 -1
- package/lib/esm/room.d.ts +2 -0
- package/lib/esm/room.js +10 -0
- package/lib/esm/storage.d.ts +2 -0
- package/lib/esm/storage.js +9 -3
- package/lib/esm/types.d.ts +2 -0
- package/package.json +1 -1
package/lib/cjs/doc.js
CHANGED
|
@@ -10,13 +10,14 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
10
10
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
11
11
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
12
12
|
};
|
|
13
|
-
var _Doc_instances, _Doc_clock, _Doc_opClock, _Doc_items, _Doc_root, _Doc_actor, _Doc_dispatch,
|
|
13
|
+
var _Doc_instances, _Doc_clock, _Doc_opClock, _Doc_items, _Doc_root, _Doc_actor, _Doc_dispatch, _Doc_undoStack, _Doc_redoStack, _Doc_applyOp, _AbstractCrdt_instances, _AbstractCrdt_listeners, _AbstractCrdt_deepListeners, _AbstractCrdt_parent, _AbstractCrdt_doc, _AbstractCrdt_id, _AbstractCrdt_parentKey, _AbstractCrdt_applySetParentKey, _AbstractCrdt_applyRegister, _AbstractCrdt_applyCreateObject, _AbstractCrdt_applyCreateMap, _AbstractCrdt_applyCreateList, _LiveObject_instances, _LiveObject_map, _LiveObject_propToLastUpdate, _LiveObject_applyDeleteObjectKey, _LiveMap_map, _LiveRegister_data, _LiveList_items, _LiveListIterator_innerIterator;
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
15
|
exports.LiveList = exports.LiveMap = exports.LiveObject = exports.Doc = void 0;
|
|
16
16
|
const utils_1 = require("./utils");
|
|
17
17
|
const live_1 = require("./live");
|
|
18
18
|
const position_1 = require("./position");
|
|
19
19
|
function noOp() { }
|
|
20
|
+
const MAX_UNDO_STACK = 50;
|
|
20
21
|
class Doc {
|
|
21
22
|
constructor(root, actor = 0, dispatch = noOp) {
|
|
22
23
|
_Doc_instances.add(this);
|
|
@@ -26,6 +27,8 @@ class Doc {
|
|
|
26
27
|
_Doc_root.set(this, void 0);
|
|
27
28
|
_Doc_actor.set(this, void 0);
|
|
28
29
|
_Doc_dispatch.set(this, void 0);
|
|
30
|
+
_Doc_undoStack.set(this, []);
|
|
31
|
+
_Doc_redoStack.set(this, []);
|
|
29
32
|
__classPrivateFieldSet(this, _Doc_root, root, "f");
|
|
30
33
|
__classPrivateFieldSet(this, _Doc_actor, actor, "f");
|
|
31
34
|
__classPrivateFieldSet(this, _Doc_dispatch, dispatch, "f");
|
|
@@ -66,6 +69,7 @@ class Doc {
|
|
|
66
69
|
return doc;
|
|
67
70
|
}
|
|
68
71
|
dispatch(ops) {
|
|
72
|
+
__classPrivateFieldSet(this, _Doc_redoStack, [], "f");
|
|
69
73
|
__classPrivateFieldGet(this, _Doc_dispatch, "f").call(this, ops);
|
|
70
74
|
}
|
|
71
75
|
addItem(id, item) {
|
|
@@ -77,45 +81,38 @@ class Doc {
|
|
|
77
81
|
getItem(id) {
|
|
78
82
|
return __classPrivateFieldGet(this, _Doc_items, "f").get(id);
|
|
79
83
|
}
|
|
80
|
-
apply(
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
break;
|
|
85
|
-
}
|
|
86
|
-
case live_1.OpType.CreateObject: {
|
|
87
|
-
__classPrivateFieldGet(this, _Doc_instances, "m", _Doc_applyCreateObject).call(this, op);
|
|
88
|
-
break;
|
|
89
|
-
}
|
|
90
|
-
case live_1.OpType.CreateMap: {
|
|
91
|
-
__classPrivateFieldGet(this, _Doc_instances, "m", _Doc_applyCreateMap).call(this, op);
|
|
92
|
-
break;
|
|
93
|
-
}
|
|
94
|
-
case live_1.OpType.CreateList: {
|
|
95
|
-
__classPrivateFieldGet(this, _Doc_instances, "m", _Doc_applyCreateList).call(this, op);
|
|
96
|
-
break;
|
|
97
|
-
}
|
|
98
|
-
case live_1.OpType.DeleteCrdt: {
|
|
99
|
-
__classPrivateFieldGet(this, _Doc_instances, "m", _Doc_applyDeleteRecord).call(this, op);
|
|
100
|
-
break;
|
|
101
|
-
}
|
|
102
|
-
case live_1.OpType.SetParentKey: {
|
|
103
|
-
__classPrivateFieldGet(this, _Doc_instances, "m", _Doc_applySetParentKey).call(this, op);
|
|
104
|
-
break;
|
|
105
|
-
}
|
|
106
|
-
case live_1.OpType.DeleteObjectKey: {
|
|
107
|
-
__classPrivateFieldGet(this, _Doc_instances, "m", _Doc_applyDeleteRecordKey).call(this, op);
|
|
108
|
-
break;
|
|
109
|
-
}
|
|
110
|
-
case live_1.OpType.CreateRegister: {
|
|
111
|
-
__classPrivateFieldGet(this, _Doc_instances, "m", _Doc_applyCreateRegister).call(this, op);
|
|
112
|
-
break;
|
|
113
|
-
}
|
|
84
|
+
apply(ops) {
|
|
85
|
+
const reverse = [];
|
|
86
|
+
for (const op of ops) {
|
|
87
|
+
reverse.push(...__classPrivateFieldGet(this, _Doc_instances, "m", _Doc_applyOp).call(this, op));
|
|
114
88
|
}
|
|
89
|
+
return reverse;
|
|
115
90
|
}
|
|
116
91
|
get root() {
|
|
117
92
|
return __classPrivateFieldGet(this, _Doc_root, "f");
|
|
118
93
|
}
|
|
94
|
+
addToUndoStack(ops) {
|
|
95
|
+
if (__classPrivateFieldGet(this, _Doc_undoStack, "f").length >= MAX_UNDO_STACK) {
|
|
96
|
+
__classPrivateFieldGet(this, _Doc_undoStack, "f").shift();
|
|
97
|
+
}
|
|
98
|
+
__classPrivateFieldGet(this, _Doc_undoStack, "f").push(ops);
|
|
99
|
+
}
|
|
100
|
+
undo() {
|
|
101
|
+
const ops = __classPrivateFieldGet(this, _Doc_undoStack, "f").pop();
|
|
102
|
+
if (ops == null) {
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
__classPrivateFieldGet(this, _Doc_redoStack, "f").push(this.apply(ops));
|
|
106
|
+
__classPrivateFieldGet(this, _Doc_dispatch, "f").call(this, ops);
|
|
107
|
+
}
|
|
108
|
+
redo() {
|
|
109
|
+
const ops = __classPrivateFieldGet(this, _Doc_redoStack, "f").pop();
|
|
110
|
+
if (ops == null) {
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
__classPrivateFieldGet(this, _Doc_undoStack, "f").push(this.apply(ops));
|
|
114
|
+
__classPrivateFieldGet(this, _Doc_dispatch, "f").call(this, ops);
|
|
115
|
+
}
|
|
119
116
|
count() {
|
|
120
117
|
return __classPrivateFieldGet(this, _Doc_items, "f").size;
|
|
121
118
|
}
|
|
@@ -129,92 +126,42 @@ class Doc {
|
|
|
129
126
|
}
|
|
130
127
|
}
|
|
131
128
|
exports.Doc = Doc;
|
|
132
|
-
_Doc_clock = new WeakMap(), _Doc_opClock = new WeakMap(), _Doc_items = new WeakMap(), _Doc_root = new WeakMap(), _Doc_actor = new WeakMap(), _Doc_dispatch = new WeakMap(), _Doc_instances = new WeakSet(),
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
}, _Doc_applyCreateMap = function _Doc_applyCreateMap(op) {
|
|
156
|
-
if (__classPrivateFieldGet(this, _Doc_items, "f").has(op.id)) {
|
|
157
|
-
return;
|
|
158
|
-
}
|
|
159
|
-
const parent = __classPrivateFieldGet(this, _Doc_items, "f").get(op.parentId);
|
|
160
|
-
if (parent == null) {
|
|
161
|
-
return;
|
|
162
|
-
}
|
|
163
|
-
const newMap = new LiveMap();
|
|
164
|
-
parent._attachChild(op.id, op.parentKey, newMap);
|
|
165
|
-
}, _Doc_applyCreateList = function _Doc_applyCreateList(op) {
|
|
166
|
-
if (__classPrivateFieldGet(this, _Doc_items, "f").has(op.id)) {
|
|
167
|
-
return;
|
|
168
|
-
}
|
|
169
|
-
const parent = __classPrivateFieldGet(this, _Doc_items, "f").get(op.parentId);
|
|
170
|
-
if (parent == null) {
|
|
171
|
-
return;
|
|
172
|
-
}
|
|
173
|
-
const list = new LiveList();
|
|
174
|
-
parent._attachChild(op.id, op.parentKey, list);
|
|
175
|
-
}, _Doc_applyCreateObject = function _Doc_applyCreateObject(op) {
|
|
176
|
-
if (__classPrivateFieldGet(this, _Doc_items, "f").has(op.id)) {
|
|
177
|
-
return;
|
|
178
|
-
}
|
|
179
|
-
if (op.parentId && op.parentKey) {
|
|
180
|
-
const parent = __classPrivateFieldGet(this, _Doc_items, "f").get(op.parentId);
|
|
181
|
-
if (parent == null) {
|
|
182
|
-
return;
|
|
129
|
+
_Doc_clock = new WeakMap(), _Doc_opClock = new WeakMap(), _Doc_items = new WeakMap(), _Doc_root = new WeakMap(), _Doc_actor = new WeakMap(), _Doc_dispatch = new WeakMap(), _Doc_undoStack = new WeakMap(), _Doc_redoStack = new WeakMap(), _Doc_instances = new WeakSet(), _Doc_applyOp = function _Doc_applyOp(op) {
|
|
130
|
+
switch (op.type) {
|
|
131
|
+
case live_1.OpType.DeleteObjectKey:
|
|
132
|
+
case live_1.OpType.UpdateObject:
|
|
133
|
+
case live_1.OpType.DeleteCrdt:
|
|
134
|
+
case live_1.OpType.SetParentKey: {
|
|
135
|
+
const item = __classPrivateFieldGet(this, _Doc_items, "f").get(op.id);
|
|
136
|
+
if (item == null) {
|
|
137
|
+
return [];
|
|
138
|
+
}
|
|
139
|
+
return item._apply(op);
|
|
140
|
+
break;
|
|
141
|
+
}
|
|
142
|
+
case live_1.OpType.CreateList:
|
|
143
|
+
case live_1.OpType.CreateObject:
|
|
144
|
+
case live_1.OpType.CreateMap:
|
|
145
|
+
case live_1.OpType.CreateRegister: {
|
|
146
|
+
const parent = __classPrivateFieldGet(this, _Doc_items, "f").get(op.parentId);
|
|
147
|
+
if (parent == null) {
|
|
148
|
+
return [];
|
|
149
|
+
}
|
|
150
|
+
return parent._apply(op);
|
|
151
|
+
break;
|
|
183
152
|
}
|
|
184
|
-
const newObj = new LiveObject(op.data);
|
|
185
|
-
parent._attachChild(op.id, op.parentKey, newObj);
|
|
186
|
-
}
|
|
187
|
-
}, _Doc_applyDeleteRecord = function _Doc_applyDeleteRecord(op) {
|
|
188
|
-
const item = __classPrivateFieldGet(this, _Doc_items, "f").get(op.id);
|
|
189
|
-
if (item == null) {
|
|
190
|
-
return;
|
|
191
|
-
}
|
|
192
|
-
const parent = item._parent;
|
|
193
|
-
if (parent == null) {
|
|
194
|
-
return;
|
|
195
|
-
}
|
|
196
|
-
if (parent) {
|
|
197
|
-
parent._detachChild(item);
|
|
198
|
-
}
|
|
199
|
-
}, _Doc_applySetParentKey = function _Doc_applySetParentKey(op) {
|
|
200
|
-
const item = __classPrivateFieldGet(this, _Doc_items, "f").get(op.id);
|
|
201
|
-
if (item == null) {
|
|
202
|
-
return;
|
|
203
|
-
}
|
|
204
|
-
if (item._parent == null) {
|
|
205
|
-
return;
|
|
206
|
-
}
|
|
207
|
-
if (item._parent instanceof LiveList) {
|
|
208
|
-
item._parent._setChildKey(op.parentKey, item);
|
|
209
153
|
}
|
|
154
|
+
return [];
|
|
210
155
|
};
|
|
211
156
|
class AbstractCrdt {
|
|
212
157
|
constructor() {
|
|
158
|
+
_AbstractCrdt_instances.add(this);
|
|
213
159
|
_AbstractCrdt_listeners.set(this, []);
|
|
214
160
|
_AbstractCrdt_deepListeners.set(this, []);
|
|
215
161
|
_AbstractCrdt_parent.set(this, void 0);
|
|
216
162
|
_AbstractCrdt_doc.set(this, void 0);
|
|
217
163
|
_AbstractCrdt_id.set(this, void 0);
|
|
164
|
+
_AbstractCrdt_parentKey.set(this, void 0);
|
|
218
165
|
}
|
|
219
166
|
/**
|
|
220
167
|
* INTERNAL
|
|
@@ -237,10 +184,45 @@ class AbstractCrdt {
|
|
|
237
184
|
/**
|
|
238
185
|
* INTERNAL
|
|
239
186
|
*/
|
|
240
|
-
|
|
241
|
-
|
|
187
|
+
get _parentKey() {
|
|
188
|
+
return __classPrivateFieldGet(this, _AbstractCrdt_parentKey, "f");
|
|
189
|
+
}
|
|
190
|
+
_apply(op) {
|
|
191
|
+
switch (op.type) {
|
|
192
|
+
case live_1.OpType.DeleteCrdt: {
|
|
193
|
+
if (this._parent != null && this._parentKey != null) {
|
|
194
|
+
const reverse = this._serialize(this._parent._id, this._parentKey);
|
|
195
|
+
this._parent._detachChild(this);
|
|
196
|
+
return reverse;
|
|
197
|
+
}
|
|
198
|
+
return [];
|
|
199
|
+
}
|
|
200
|
+
case live_1.OpType.CreateObject: {
|
|
201
|
+
return __classPrivateFieldGet(this, _AbstractCrdt_instances, "m", _AbstractCrdt_applyCreateObject).call(this, op);
|
|
202
|
+
}
|
|
203
|
+
case live_1.OpType.CreateMap: {
|
|
204
|
+
return __classPrivateFieldGet(this, _AbstractCrdt_instances, "m", _AbstractCrdt_applyCreateMap).call(this, op);
|
|
205
|
+
}
|
|
206
|
+
case live_1.OpType.CreateRegister: {
|
|
207
|
+
return __classPrivateFieldGet(this, _AbstractCrdt_instances, "m", _AbstractCrdt_applyRegister).call(this, op);
|
|
208
|
+
}
|
|
209
|
+
case live_1.OpType.CreateList: {
|
|
210
|
+
return __classPrivateFieldGet(this, _AbstractCrdt_instances, "m", _AbstractCrdt_applyCreateList).call(this, op);
|
|
211
|
+
}
|
|
212
|
+
case live_1.OpType.SetParentKey: {
|
|
213
|
+
return __classPrivateFieldGet(this, _AbstractCrdt_instances, "m", _AbstractCrdt_applySetParentKey).call(this, op);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
return [];
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* INTERNAL
|
|
220
|
+
*/
|
|
221
|
+
_setParentLink(parent, key) {
|
|
222
|
+
if (__classPrivateFieldGet(this, _AbstractCrdt_parent, "f") != null && __classPrivateFieldGet(this, _AbstractCrdt_parent, "f") !== parent) {
|
|
242
223
|
throw new Error("Cannot attach parent if it already exist");
|
|
243
224
|
}
|
|
225
|
+
__classPrivateFieldSet(this, _AbstractCrdt_parentKey, key, "f");
|
|
244
226
|
__classPrivateFieldSet(this, _AbstractCrdt_parent, parent, "f");
|
|
245
227
|
}
|
|
246
228
|
/**
|
|
@@ -264,19 +246,34 @@ class AbstractCrdt {
|
|
|
264
246
|
__classPrivateFieldSet(this, _AbstractCrdt_parent, undefined, "f");
|
|
265
247
|
__classPrivateFieldSet(this, _AbstractCrdt_doc, undefined, "f");
|
|
266
248
|
}
|
|
249
|
+
/**
|
|
250
|
+
* Subscribes to updates.
|
|
251
|
+
*/
|
|
267
252
|
subscribe(listener) {
|
|
268
253
|
__classPrivateFieldGet(this, _AbstractCrdt_listeners, "f").push(listener);
|
|
269
254
|
}
|
|
255
|
+
/**
|
|
256
|
+
* Subscribes to updates and children updates.
|
|
257
|
+
*/
|
|
270
258
|
subscribeDeep(listener) {
|
|
271
259
|
__classPrivateFieldGet(this, _AbstractCrdt_deepListeners, "f").push(listener);
|
|
272
260
|
}
|
|
261
|
+
/**
|
|
262
|
+
* Unsubscribes to updates.
|
|
263
|
+
*/
|
|
273
264
|
unsubscribe(listener) {
|
|
274
265
|
(0, utils_1.remove)(__classPrivateFieldGet(this, _AbstractCrdt_listeners, "f"), listener);
|
|
275
266
|
}
|
|
267
|
+
/**
|
|
268
|
+
* Unsubscribes to updates and children updates.
|
|
269
|
+
*/
|
|
276
270
|
unsubscribeDeep(listener) {
|
|
277
271
|
(0, utils_1.remove)(__classPrivateFieldGet(this, _AbstractCrdt_deepListeners, "f"), listener);
|
|
278
272
|
}
|
|
279
|
-
|
|
273
|
+
/**
|
|
274
|
+
* INTERNAL
|
|
275
|
+
*/
|
|
276
|
+
_notify(onlyDeep = false) {
|
|
280
277
|
if (onlyDeep === false) {
|
|
281
278
|
for (const listener of __classPrivateFieldGet(this, _AbstractCrdt_listeners, "f")) {
|
|
282
279
|
listener();
|
|
@@ -286,20 +283,70 @@ class AbstractCrdt {
|
|
|
286
283
|
listener();
|
|
287
284
|
}
|
|
288
285
|
if (this._parent) {
|
|
289
|
-
this._parent.
|
|
286
|
+
this._parent._notify(true);
|
|
290
287
|
}
|
|
291
288
|
}
|
|
292
289
|
}
|
|
293
|
-
_AbstractCrdt_listeners = new WeakMap(), _AbstractCrdt_deepListeners = new WeakMap(), _AbstractCrdt_parent = new WeakMap(), _AbstractCrdt_doc = new WeakMap(), _AbstractCrdt_id = new WeakMap()
|
|
290
|
+
_AbstractCrdt_listeners = new WeakMap(), _AbstractCrdt_deepListeners = new WeakMap(), _AbstractCrdt_parent = new WeakMap(), _AbstractCrdt_doc = new WeakMap(), _AbstractCrdt_id = new WeakMap(), _AbstractCrdt_parentKey = new WeakMap(), _AbstractCrdt_instances = new WeakSet(), _AbstractCrdt_applySetParentKey = function _AbstractCrdt_applySetParentKey(op) {
|
|
291
|
+
if (this._parent == null) {
|
|
292
|
+
return [];
|
|
293
|
+
}
|
|
294
|
+
if (this._parent instanceof LiveList) {
|
|
295
|
+
const previousKey = this._parentKey;
|
|
296
|
+
this._parent._setChildKey(op.parentKey, this);
|
|
297
|
+
return [
|
|
298
|
+
{ type: live_1.OpType.SetParentKey, id: this._id, parentKey: previousKey },
|
|
299
|
+
];
|
|
300
|
+
}
|
|
301
|
+
return [];
|
|
302
|
+
}, _AbstractCrdt_applyRegister = function _AbstractCrdt_applyRegister(op) {
|
|
303
|
+
if (this._doc == null) {
|
|
304
|
+
throw new Error("Internal: doc should exist");
|
|
305
|
+
}
|
|
306
|
+
if (this._doc.getItem(op.id) != null) {
|
|
307
|
+
return [];
|
|
308
|
+
}
|
|
309
|
+
return this._attachChild(op.id, op.parentKey, new LiveRegister(op.data));
|
|
310
|
+
}, _AbstractCrdt_applyCreateObject = function _AbstractCrdt_applyCreateObject(op) {
|
|
311
|
+
if (this._doc == null) {
|
|
312
|
+
throw new Error("Internal: doc should exist");
|
|
313
|
+
}
|
|
314
|
+
if (this._doc.getItem(op.id) != null) {
|
|
315
|
+
return [];
|
|
316
|
+
}
|
|
317
|
+
return this._attachChild(op.id, op.parentKey, new LiveObject(op.data));
|
|
318
|
+
}, _AbstractCrdt_applyCreateMap = function _AbstractCrdt_applyCreateMap(op) {
|
|
319
|
+
if (this._doc == null) {
|
|
320
|
+
throw new Error("Internal: doc should exist");
|
|
321
|
+
}
|
|
322
|
+
if (this._doc.getItem(op.id) != null) {
|
|
323
|
+
return [];
|
|
324
|
+
}
|
|
325
|
+
return this._attachChild(op.id, op.parentKey, new LiveMap());
|
|
326
|
+
}, _AbstractCrdt_applyCreateList = function _AbstractCrdt_applyCreateList(op) {
|
|
327
|
+
if (this._doc == null) {
|
|
328
|
+
throw new Error("Internal: doc should exist");
|
|
329
|
+
}
|
|
330
|
+
if (this._doc.getItem(op.id) != null) {
|
|
331
|
+
return [];
|
|
332
|
+
}
|
|
333
|
+
return this._attachChild(op.id, op.parentKey, new LiveList());
|
|
334
|
+
};
|
|
335
|
+
/**
|
|
336
|
+
* The LiveObject class is similar to a JavaScript object that is synchronized on all clients.
|
|
337
|
+
* Keys should be a string, and values should be serializable to JSON.
|
|
338
|
+
* If multiple clients update the same property simultaneously, the last modification received by the Liveblocks servers is the winner.
|
|
339
|
+
*/
|
|
294
340
|
class LiveObject extends AbstractCrdt {
|
|
295
341
|
constructor(object = {}) {
|
|
296
342
|
super();
|
|
343
|
+
_LiveObject_instances.add(this);
|
|
297
344
|
_LiveObject_map.set(this, void 0);
|
|
298
345
|
_LiveObject_propToLastUpdate.set(this, new Map());
|
|
299
346
|
for (const key in object) {
|
|
300
347
|
const value = object[key];
|
|
301
348
|
if (value instanceof AbstractCrdt) {
|
|
302
|
-
value.
|
|
349
|
+
value._setParentLink(this, key);
|
|
303
350
|
}
|
|
304
351
|
}
|
|
305
352
|
__classPrivateFieldSet(this, _LiveObject_map, new Map(Object.entries(object)), "f");
|
|
@@ -349,7 +396,7 @@ class LiveObject extends AbstractCrdt {
|
|
|
349
396
|
throw new Error("Tried to deserialize a crdt but it does not have a parentKey and is not the root");
|
|
350
397
|
}
|
|
351
398
|
const child = deserialize(entry, parentToChildren, doc);
|
|
352
|
-
child.
|
|
399
|
+
child._setParentLink(object, crdt.parentKey);
|
|
353
400
|
__classPrivateFieldGet(object, _LiveObject_map, "f").set(crdt.parentKey, child);
|
|
354
401
|
}
|
|
355
402
|
return object;
|
|
@@ -373,13 +420,30 @@ class LiveObject extends AbstractCrdt {
|
|
|
373
420
|
throw new Error("Can't attach child if doc is not present");
|
|
374
421
|
}
|
|
375
422
|
const previousValue = __classPrivateFieldGet(this, _LiveObject_map, "f").get(key);
|
|
423
|
+
let result;
|
|
376
424
|
if (isCrdt(previousValue)) {
|
|
425
|
+
result = previousValue._serialize(this._id, key);
|
|
377
426
|
previousValue._detach();
|
|
378
427
|
}
|
|
428
|
+
else if (previousValue === undefined) {
|
|
429
|
+
result = [
|
|
430
|
+
{ type: live_1.OpType.DeleteObjectKey, id: this._id, key: key },
|
|
431
|
+
];
|
|
432
|
+
}
|
|
433
|
+
else {
|
|
434
|
+
result = [
|
|
435
|
+
{
|
|
436
|
+
type: live_1.OpType.UpdateObject,
|
|
437
|
+
id: this._id,
|
|
438
|
+
data: { [key]: previousValue },
|
|
439
|
+
},
|
|
440
|
+
];
|
|
441
|
+
}
|
|
379
442
|
__classPrivateFieldGet(this, _LiveObject_map, "f").set(key, child);
|
|
380
|
-
child.
|
|
443
|
+
child._setParentLink(this, key);
|
|
381
444
|
child._attach(id, this._doc);
|
|
382
|
-
this.
|
|
445
|
+
this._notify();
|
|
446
|
+
return result;
|
|
383
447
|
}
|
|
384
448
|
/**
|
|
385
449
|
* INTERNAL
|
|
@@ -393,7 +457,7 @@ class LiveObject extends AbstractCrdt {
|
|
|
393
457
|
if (child) {
|
|
394
458
|
child._detach();
|
|
395
459
|
}
|
|
396
|
-
this.
|
|
460
|
+
this._notify();
|
|
397
461
|
}
|
|
398
462
|
/**
|
|
399
463
|
* INTERNAL
|
|
@@ -410,11 +474,32 @@ class LiveObject extends AbstractCrdt {
|
|
|
410
474
|
* INTERNAL
|
|
411
475
|
*/
|
|
412
476
|
_apply(op) {
|
|
477
|
+
var _a;
|
|
413
478
|
if (op.type === live_1.OpType.UpdateObject) {
|
|
479
|
+
const reverse = [];
|
|
480
|
+
const reverseUpdate = {
|
|
481
|
+
type: live_1.OpType.UpdateObject,
|
|
482
|
+
id: this._id,
|
|
483
|
+
data: {},
|
|
484
|
+
};
|
|
485
|
+
reverse.push(reverseUpdate);
|
|
414
486
|
for (const key in op.data) {
|
|
487
|
+
const oldValue = __classPrivateFieldGet(this, _LiveObject_map, "f").get(key);
|
|
488
|
+
if (oldValue !== undefined) {
|
|
489
|
+
reverseUpdate.data[key] = oldValue;
|
|
490
|
+
}
|
|
491
|
+
else if (oldValue === undefined) {
|
|
492
|
+
reverse.push({ type: live_1.OpType.DeleteObjectKey, id: this._id, key });
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
for (const key in op.data) {
|
|
496
|
+
if (op.opId == null) {
|
|
497
|
+
op.opId = (_a = this._doc) === null || _a === void 0 ? void 0 : _a.generateOpId();
|
|
498
|
+
}
|
|
415
499
|
const lastOpId = __classPrivateFieldGet(this, _LiveObject_propToLastUpdate, "f").get(key);
|
|
416
500
|
if (lastOpId === op.opId) {
|
|
417
501
|
__classPrivateFieldGet(this, _LiveObject_propToLastUpdate, "f").delete(key);
|
|
502
|
+
continue;
|
|
418
503
|
}
|
|
419
504
|
else if (lastOpId != null) {
|
|
420
505
|
continue;
|
|
@@ -426,76 +511,128 @@ class LiveObject extends AbstractCrdt {
|
|
|
426
511
|
const value = op.data[key];
|
|
427
512
|
__classPrivateFieldGet(this, _LiveObject_map, "f").set(key, value);
|
|
428
513
|
}
|
|
429
|
-
this.
|
|
514
|
+
this._notify();
|
|
515
|
+
return reverse;
|
|
430
516
|
}
|
|
431
517
|
else if (op.type === live_1.OpType.DeleteObjectKey) {
|
|
432
|
-
|
|
433
|
-
const oldValue = __classPrivateFieldGet(this, _LiveObject_map, "f").get(key);
|
|
434
|
-
if (isCrdt(oldValue)) {
|
|
435
|
-
oldValue._detach();
|
|
436
|
-
}
|
|
437
|
-
__classPrivateFieldGet(this, _LiveObject_map, "f").delete(key);
|
|
438
|
-
this.notify();
|
|
518
|
+
return __classPrivateFieldGet(this, _LiveObject_instances, "m", _LiveObject_applyDeleteObjectKey).call(this, op);
|
|
439
519
|
}
|
|
520
|
+
return super._apply(op);
|
|
440
521
|
}
|
|
522
|
+
/**
|
|
523
|
+
* Transform the LiveObject into a javascript object
|
|
524
|
+
*/
|
|
441
525
|
toObject() {
|
|
442
526
|
return Object.fromEntries(__classPrivateFieldGet(this, _LiveObject_map, "f"));
|
|
443
527
|
}
|
|
528
|
+
/**
|
|
529
|
+
* Adds or updates a property with a specified key and a value.
|
|
530
|
+
* @param key The key of the property to add
|
|
531
|
+
* @param value The value of the property to add
|
|
532
|
+
*/
|
|
444
533
|
set(key, value) {
|
|
445
534
|
// TODO: Find out why typescript complains
|
|
446
535
|
this.update({ [key]: value });
|
|
447
536
|
}
|
|
537
|
+
/**
|
|
538
|
+
* Returns a specified property from the LiveObject.
|
|
539
|
+
* @param key The key of the property to get
|
|
540
|
+
*/
|
|
448
541
|
get(key) {
|
|
449
542
|
return __classPrivateFieldGet(this, _LiveObject_map, "f").get(key);
|
|
450
543
|
}
|
|
544
|
+
/**
|
|
545
|
+
* Adds or updates multiple properties at once with an object.
|
|
546
|
+
* @param overrides The object used to overrides properties
|
|
547
|
+
*/
|
|
451
548
|
update(overrides) {
|
|
452
|
-
if (this._doc
|
|
453
|
-
const ops = [];
|
|
454
|
-
const opId = this._doc.generateOpId();
|
|
455
|
-
const updateOp = {
|
|
456
|
-
opId,
|
|
457
|
-
id: this._id,
|
|
458
|
-
type: live_1.OpType.UpdateObject,
|
|
459
|
-
data: {},
|
|
460
|
-
};
|
|
461
|
-
ops.push(updateOp);
|
|
549
|
+
if (this._doc == null || this._id == null) {
|
|
462
550
|
for (const key in overrides) {
|
|
463
|
-
__classPrivateFieldGet(this, _LiveObject_propToLastUpdate, "f").set(key, opId);
|
|
464
551
|
const oldValue = __classPrivateFieldGet(this, _LiveObject_map, "f").get(key);
|
|
465
|
-
if (oldValue instanceof
|
|
552
|
+
if (oldValue instanceof AbstractCrdt) {
|
|
466
553
|
oldValue._detach();
|
|
467
554
|
}
|
|
468
555
|
const newValue = overrides[key];
|
|
469
556
|
if (newValue instanceof AbstractCrdt) {
|
|
470
|
-
newValue.
|
|
471
|
-
newValue._attach(this._doc.generateId(), this._doc);
|
|
472
|
-
ops.push(...newValue._serialize(this._id, key));
|
|
473
|
-
}
|
|
474
|
-
else {
|
|
475
|
-
updateOp.data[key] = newValue;
|
|
557
|
+
newValue._setParentLink(this, key);
|
|
476
558
|
}
|
|
477
559
|
__classPrivateFieldGet(this, _LiveObject_map, "f").set(key, newValue);
|
|
478
560
|
}
|
|
479
|
-
this.
|
|
480
|
-
this.notify();
|
|
561
|
+
this._notify();
|
|
481
562
|
return;
|
|
482
563
|
}
|
|
564
|
+
const ops = [];
|
|
565
|
+
const reverseOps = [];
|
|
566
|
+
const opId = this._doc.generateOpId();
|
|
567
|
+
const updateOp = {
|
|
568
|
+
opId,
|
|
569
|
+
id: this._id,
|
|
570
|
+
type: live_1.OpType.UpdateObject,
|
|
571
|
+
data: {},
|
|
572
|
+
};
|
|
573
|
+
ops.push(updateOp);
|
|
574
|
+
const reverseUpdateOp = {
|
|
575
|
+
id: this._id,
|
|
576
|
+
type: live_1.OpType.UpdateObject,
|
|
577
|
+
data: {},
|
|
578
|
+
};
|
|
579
|
+
reverseOps.push(reverseUpdateOp);
|
|
483
580
|
for (const key in overrides) {
|
|
581
|
+
__classPrivateFieldGet(this, _LiveObject_propToLastUpdate, "f").set(key, opId);
|
|
484
582
|
const oldValue = __classPrivateFieldGet(this, _LiveObject_map, "f").get(key);
|
|
485
583
|
if (oldValue instanceof AbstractCrdt) {
|
|
584
|
+
reverseOps.push(...oldValue._serialize(this._id, key));
|
|
486
585
|
oldValue._detach();
|
|
487
586
|
}
|
|
587
|
+
else if (oldValue === undefined) {
|
|
588
|
+
reverseOps.push({ type: live_1.OpType.DeleteObjectKey, id: this._id, key });
|
|
589
|
+
}
|
|
590
|
+
else {
|
|
591
|
+
reverseUpdateOp.data[key] = oldValue;
|
|
592
|
+
}
|
|
488
593
|
const newValue = overrides[key];
|
|
489
594
|
if (newValue instanceof AbstractCrdt) {
|
|
490
|
-
newValue.
|
|
595
|
+
newValue._setParentLink(this, key);
|
|
596
|
+
newValue._attach(this._doc.generateId(), this._doc);
|
|
597
|
+
ops.push(...newValue._serialize(this._id, key));
|
|
598
|
+
}
|
|
599
|
+
else {
|
|
600
|
+
updateOp.data[key] = newValue;
|
|
491
601
|
}
|
|
492
602
|
__classPrivateFieldGet(this, _LiveObject_map, "f").set(key, newValue);
|
|
493
603
|
}
|
|
494
|
-
this.
|
|
604
|
+
this._doc.addToUndoStack(reverseOps);
|
|
605
|
+
this._doc.dispatch(ops);
|
|
606
|
+
this._notify();
|
|
495
607
|
}
|
|
496
608
|
}
|
|
497
609
|
exports.LiveObject = LiveObject;
|
|
498
|
-
_LiveObject_map = new WeakMap(), _LiveObject_propToLastUpdate = new WeakMap()
|
|
610
|
+
_LiveObject_map = new WeakMap(), _LiveObject_propToLastUpdate = new WeakMap(), _LiveObject_instances = new WeakSet(), _LiveObject_applyDeleteObjectKey = function _LiveObject_applyDeleteObjectKey(op) {
|
|
611
|
+
const key = op.key;
|
|
612
|
+
const oldValue = __classPrivateFieldGet(this, _LiveObject_map, "f").get(key);
|
|
613
|
+
let result = [];
|
|
614
|
+
if (isCrdt(oldValue)) {
|
|
615
|
+
result = oldValue._serialize(this._id, op.key);
|
|
616
|
+
oldValue._detach();
|
|
617
|
+
}
|
|
618
|
+
else if (oldValue !== undefined) {
|
|
619
|
+
result = [
|
|
620
|
+
{
|
|
621
|
+
type: live_1.OpType.UpdateObject,
|
|
622
|
+
id: this._id,
|
|
623
|
+
data: { [key]: oldValue },
|
|
624
|
+
},
|
|
625
|
+
];
|
|
626
|
+
}
|
|
627
|
+
__classPrivateFieldGet(this, _LiveObject_map, "f").delete(key);
|
|
628
|
+
this._notify();
|
|
629
|
+
return result;
|
|
630
|
+
};
|
|
631
|
+
/**
|
|
632
|
+
* The LiveMap class is similar to a JavaScript Map that is synchronized on all clients.
|
|
633
|
+
* Keys should be a string, and values should be serializable to JSON.
|
|
634
|
+
* If multiple clients update the same property simultaneously, the last modification received by the Liveblocks servers is the winner.
|
|
635
|
+
*/
|
|
499
636
|
class LiveMap extends AbstractCrdt {
|
|
500
637
|
constructor(entries) {
|
|
501
638
|
super();
|
|
@@ -504,7 +641,7 @@ class LiveMap extends AbstractCrdt {
|
|
|
504
641
|
const mappedEntries = [];
|
|
505
642
|
for (const entry of entries) {
|
|
506
643
|
const value = selfOrRegister(entry[1]);
|
|
507
|
-
value.
|
|
644
|
+
value._setParentLink(this, entry[0]);
|
|
508
645
|
mappedEntries.push([entry[0], value]);
|
|
509
646
|
}
|
|
510
647
|
__classPrivateFieldSet(this, _LiveMap_map, new Map(mappedEntries), "f");
|
|
@@ -555,7 +692,7 @@ class LiveMap extends AbstractCrdt {
|
|
|
555
692
|
throw new Error("Tried to deserialize a crdt but it does not have a parentKey and is not the root");
|
|
556
693
|
}
|
|
557
694
|
const child = deserialize(entry, parentToChildren, doc);
|
|
558
|
-
child.
|
|
695
|
+
child._setParentLink(map, crdt.parentKey);
|
|
559
696
|
__classPrivateFieldGet(map, _LiveMap_map, "f").set(crdt.parentKey, child);
|
|
560
697
|
}
|
|
561
698
|
return map;
|
|
@@ -579,13 +716,19 @@ class LiveMap extends AbstractCrdt {
|
|
|
579
716
|
throw new Error("Can't attach child if doc is not present");
|
|
580
717
|
}
|
|
581
718
|
const previousValue = __classPrivateFieldGet(this, _LiveMap_map, "f").get(key);
|
|
719
|
+
let result;
|
|
582
720
|
if (previousValue) {
|
|
721
|
+
result = previousValue._serialize(this._id, key);
|
|
583
722
|
previousValue._detach();
|
|
584
723
|
}
|
|
585
|
-
|
|
724
|
+
else {
|
|
725
|
+
result = [{ type: live_1.OpType.DeleteCrdt, id }];
|
|
726
|
+
}
|
|
727
|
+
child._setParentLink(this, key);
|
|
586
728
|
child._attach(id, this._doc);
|
|
587
729
|
__classPrivateFieldGet(this, _LiveMap_map, "f").set(key, child);
|
|
588
|
-
this.
|
|
730
|
+
this._notify();
|
|
731
|
+
return result;
|
|
589
732
|
}
|
|
590
733
|
/**
|
|
591
734
|
* INTERNAL
|
|
@@ -606,8 +749,13 @@ class LiveMap extends AbstractCrdt {
|
|
|
606
749
|
}
|
|
607
750
|
}
|
|
608
751
|
child._detach();
|
|
609
|
-
this.
|
|
752
|
+
this._notify();
|
|
610
753
|
}
|
|
754
|
+
/**
|
|
755
|
+
* Returns a specified element from the LiveMap.
|
|
756
|
+
* @param key The key of the element to return.
|
|
757
|
+
* @returns The element associated with the specified key, or undefined if the key can't be found in the LiveMap.
|
|
758
|
+
*/
|
|
611
759
|
get(key) {
|
|
612
760
|
const value = __classPrivateFieldGet(this, _LiveMap_map, "f").get(key);
|
|
613
761
|
if (value == undefined) {
|
|
@@ -615,27 +763,47 @@ class LiveMap extends AbstractCrdt {
|
|
|
615
763
|
}
|
|
616
764
|
return selfOrRegisterValue(value);
|
|
617
765
|
}
|
|
766
|
+
/**
|
|
767
|
+
* Adds or updates an element with a specified key and a value.
|
|
768
|
+
* @param key The key of the element to add. Should be a string.
|
|
769
|
+
* @param value The value of the element to add. Should be serializable to JSON.
|
|
770
|
+
*/
|
|
618
771
|
set(key, value) {
|
|
619
772
|
const oldValue = __classPrivateFieldGet(this, _LiveMap_map, "f").get(key);
|
|
620
773
|
if (oldValue) {
|
|
621
774
|
oldValue._detach();
|
|
622
775
|
}
|
|
623
776
|
const item = selfOrRegister(value);
|
|
624
|
-
item.
|
|
777
|
+
item._setParentLink(this, key);
|
|
625
778
|
__classPrivateFieldGet(this, _LiveMap_map, "f").set(key, item);
|
|
626
779
|
if (this._doc && this._id) {
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
this._doc.
|
|
780
|
+
const id = this._doc.generateId();
|
|
781
|
+
item._attach(id, this._doc);
|
|
782
|
+
this._doc.addToUndoStack(oldValue
|
|
783
|
+
? oldValue._serialize(this._id, key)
|
|
784
|
+
: [{ type: live_1.OpType.DeleteCrdt, id }]);
|
|
785
|
+
this._doc.dispatch(item._serialize(this._id, key));
|
|
630
786
|
}
|
|
631
|
-
this.
|
|
787
|
+
this._notify();
|
|
632
788
|
}
|
|
789
|
+
/**
|
|
790
|
+
* Returns the number of elements in the LiveMap.
|
|
791
|
+
*/
|
|
633
792
|
get size() {
|
|
634
793
|
return __classPrivateFieldGet(this, _LiveMap_map, "f").size;
|
|
635
794
|
}
|
|
795
|
+
/**
|
|
796
|
+
* Returns a boolean indicating whether an element with the specified key exists or not.
|
|
797
|
+
* @param key The key of the element to test for presence.
|
|
798
|
+
*/
|
|
636
799
|
has(key) {
|
|
637
800
|
return __classPrivateFieldGet(this, _LiveMap_map, "f").has(key);
|
|
638
801
|
}
|
|
802
|
+
/**
|
|
803
|
+
* Removes the specified element by key.
|
|
804
|
+
* @param key The key of the element to remove.
|
|
805
|
+
* @returns true if an element existed and has been removed, or false if the element does not exist.
|
|
806
|
+
*/
|
|
639
807
|
delete(key) {
|
|
640
808
|
const item = __classPrivateFieldGet(this, _LiveMap_map, "f").get(key);
|
|
641
809
|
if (item == null) {
|
|
@@ -643,12 +811,16 @@ class LiveMap extends AbstractCrdt {
|
|
|
643
811
|
}
|
|
644
812
|
item._detach();
|
|
645
813
|
if (this._doc && item._id) {
|
|
814
|
+
this._doc.addToUndoStack(item._serialize(this._id, key));
|
|
646
815
|
this._doc.dispatch([{ type: live_1.OpType.DeleteCrdt, id: item._id }]);
|
|
647
816
|
}
|
|
648
817
|
__classPrivateFieldGet(this, _LiveMap_map, "f").delete(key);
|
|
649
|
-
this.
|
|
818
|
+
this._notify();
|
|
650
819
|
return true;
|
|
651
820
|
}
|
|
821
|
+
/**
|
|
822
|
+
* Returns a new Iterator object that contains the [key, value] pairs for each element.
|
|
823
|
+
*/
|
|
652
824
|
entries() {
|
|
653
825
|
const innerIterator = __classPrivateFieldGet(this, _LiveMap_map, "f").entries();
|
|
654
826
|
return {
|
|
@@ -670,12 +842,21 @@ class LiveMap extends AbstractCrdt {
|
|
|
670
842
|
},
|
|
671
843
|
};
|
|
672
844
|
}
|
|
845
|
+
/**
|
|
846
|
+
* Same function object as the initial value of the entries method.
|
|
847
|
+
*/
|
|
673
848
|
[(_LiveMap_map = new WeakMap(), Symbol.iterator)]() {
|
|
674
849
|
return this.entries();
|
|
675
850
|
}
|
|
851
|
+
/**
|
|
852
|
+
* Returns a new Iterator object that contains the keys for each element.
|
|
853
|
+
*/
|
|
676
854
|
keys() {
|
|
677
855
|
return __classPrivateFieldGet(this, _LiveMap_map, "f").keys();
|
|
678
856
|
}
|
|
857
|
+
/**
|
|
858
|
+
* Returns a new Iterator object that contains the values for each element.
|
|
859
|
+
*/
|
|
679
860
|
values() {
|
|
680
861
|
const innerIterator = __classPrivateFieldGet(this, _LiveMap_map, "f").values();
|
|
681
862
|
return {
|
|
@@ -696,6 +877,10 @@ class LiveMap extends AbstractCrdt {
|
|
|
696
877
|
},
|
|
697
878
|
};
|
|
698
879
|
}
|
|
880
|
+
/**
|
|
881
|
+
* Executes a provided function once per each key/value pair in the Map object, in insertion order.
|
|
882
|
+
* @param callback Function to execute for each entry in the map.
|
|
883
|
+
*/
|
|
699
884
|
forEach(callback) {
|
|
700
885
|
for (const entry of this) {
|
|
701
886
|
callback(entry[1], entry[0], this);
|
|
@@ -703,6 +888,9 @@ class LiveMap extends AbstractCrdt {
|
|
|
703
888
|
}
|
|
704
889
|
}
|
|
705
890
|
exports.LiveMap = LiveMap;
|
|
891
|
+
/**
|
|
892
|
+
* INTERNAL
|
|
893
|
+
*/
|
|
706
894
|
class LiveRegister extends AbstractCrdt {
|
|
707
895
|
constructor(data) {
|
|
708
896
|
super();
|
|
@@ -746,8 +934,14 @@ class LiveRegister extends AbstractCrdt {
|
|
|
746
934
|
_detachChild(crdt) {
|
|
747
935
|
throw new Error("Method not implemented.");
|
|
748
936
|
}
|
|
937
|
+
_apply(op) {
|
|
938
|
+
return super._apply(op);
|
|
939
|
+
}
|
|
749
940
|
}
|
|
750
941
|
_LiveRegister_data = new WeakMap();
|
|
942
|
+
/**
|
|
943
|
+
* The LiveList class represents an ordered collection of items that is synchorinized across clients.
|
|
944
|
+
*/
|
|
751
945
|
class LiveList extends AbstractCrdt {
|
|
752
946
|
constructor(items = []) {
|
|
753
947
|
super();
|
|
@@ -773,7 +967,7 @@ class LiveList extends AbstractCrdt {
|
|
|
773
967
|
}
|
|
774
968
|
for (const entry of children) {
|
|
775
969
|
const child = deserialize(entry, parentToChildren, doc);
|
|
776
|
-
child.
|
|
970
|
+
child._setParentLink(list, entry[1].parentKey);
|
|
777
971
|
__classPrivateFieldGet(list, _LiveList_items, "f").push([child, entry[1].parentKey]);
|
|
778
972
|
__classPrivateFieldGet(list, _LiveList_items, "f").sort((itemA, itemB) => (0, position_1.compare)(itemA[1], itemB[1]));
|
|
779
973
|
}
|
|
@@ -829,7 +1023,7 @@ class LiveList extends AbstractCrdt {
|
|
|
829
1023
|
throw new Error("Can't attach child if doc is not present");
|
|
830
1024
|
}
|
|
831
1025
|
child._attach(id, this._doc);
|
|
832
|
-
child.
|
|
1026
|
+
child._setParentLink(this, key);
|
|
833
1027
|
const index = __classPrivateFieldGet(this, _LiveList_items, "f").findIndex((entry) => entry[1] === key);
|
|
834
1028
|
// Assign a temporary position until we get the fix from the backend
|
|
835
1029
|
if (index !== -1) {
|
|
@@ -837,7 +1031,8 @@ class LiveList extends AbstractCrdt {
|
|
|
837
1031
|
}
|
|
838
1032
|
__classPrivateFieldGet(this, _LiveList_items, "f").push([child, key]);
|
|
839
1033
|
__classPrivateFieldGet(this, _LiveList_items, "f").sort((itemA, itemB) => (0, position_1.compare)(itemA[1], itemB[1]));
|
|
840
|
-
this.
|
|
1034
|
+
this._notify();
|
|
1035
|
+
return [{ type: live_1.OpType.DeleteCrdt, id }];
|
|
841
1036
|
}
|
|
842
1037
|
/**
|
|
843
1038
|
* INTERNAL
|
|
@@ -848,13 +1043,14 @@ class LiveList extends AbstractCrdt {
|
|
|
848
1043
|
if (child) {
|
|
849
1044
|
child._detach();
|
|
850
1045
|
}
|
|
851
|
-
this.
|
|
1046
|
+
this._notify();
|
|
852
1047
|
}
|
|
853
1048
|
/**
|
|
854
1049
|
* INTERNAL
|
|
855
1050
|
*/
|
|
856
1051
|
_setChildKey(key, child) {
|
|
857
1052
|
var _a;
|
|
1053
|
+
child._setParentLink(this, key);
|
|
858
1054
|
const index = __classPrivateFieldGet(this, _LiveList_items, "f").findIndex((entry) => entry[1] === key);
|
|
859
1055
|
// Assign a temporary position until we get the fix from the backend
|
|
860
1056
|
if (index !== -1) {
|
|
@@ -865,41 +1061,56 @@ class LiveList extends AbstractCrdt {
|
|
|
865
1061
|
item[1] = key;
|
|
866
1062
|
}
|
|
867
1063
|
__classPrivateFieldGet(this, _LiveList_items, "f").sort((itemA, itemB) => (0, position_1.compare)(itemA[1], itemB[1]));
|
|
868
|
-
this.
|
|
1064
|
+
this._notify();
|
|
869
1065
|
}
|
|
1066
|
+
/**
|
|
1067
|
+
* INTERNAL
|
|
1068
|
+
*/
|
|
1069
|
+
_apply(op) {
|
|
1070
|
+
return super._apply(op);
|
|
1071
|
+
}
|
|
1072
|
+
/**
|
|
1073
|
+
* Returns the number of elements.
|
|
1074
|
+
*/
|
|
870
1075
|
get length() {
|
|
871
1076
|
return __classPrivateFieldGet(this, _LiveList_items, "f").length;
|
|
872
1077
|
}
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
__classPrivateFieldGet(this, _LiveList_items, "f").push([value, position]);
|
|
880
|
-
this.notify();
|
|
881
|
-
if (this._doc && this._id) {
|
|
882
|
-
value._attach(this._doc.generateId(), this._doc);
|
|
883
|
-
this._doc.dispatch(value._serialize(this._id, position));
|
|
884
|
-
}
|
|
1078
|
+
/**
|
|
1079
|
+
* Adds one element to the end of the LiveList.
|
|
1080
|
+
* @param element The element to add to the end of the LiveList.
|
|
1081
|
+
*/
|
|
1082
|
+
push(element) {
|
|
1083
|
+
return this.insert(element, this.length);
|
|
885
1084
|
}
|
|
886
|
-
|
|
1085
|
+
/**
|
|
1086
|
+
* Inserts one element at a specified index.
|
|
1087
|
+
* @param element The element to insert.
|
|
1088
|
+
* @param index The index at which you want to insert the element.
|
|
1089
|
+
*/
|
|
1090
|
+
insert(element, index) {
|
|
887
1091
|
if (index < 0 || index > __classPrivateFieldGet(this, _LiveList_items, "f").length) {
|
|
888
1092
|
throw new Error(`Cannot delete list item at index "${index}". index should be between 0 and ${__classPrivateFieldGet(this, _LiveList_items, "f").length}`);
|
|
889
1093
|
}
|
|
890
1094
|
let before = __classPrivateFieldGet(this, _LiveList_items, "f")[index - 1] ? __classPrivateFieldGet(this, _LiveList_items, "f")[index - 1][1] : undefined;
|
|
891
1095
|
let after = __classPrivateFieldGet(this, _LiveList_items, "f")[index] ? __classPrivateFieldGet(this, _LiveList_items, "f")[index][1] : undefined;
|
|
892
1096
|
const position = (0, position_1.makePosition)(before, after);
|
|
893
|
-
const value = selfOrRegister(
|
|
894
|
-
value.
|
|
1097
|
+
const value = selfOrRegister(element);
|
|
1098
|
+
value._setParentLink(this, position);
|
|
895
1099
|
__classPrivateFieldGet(this, _LiveList_items, "f").push([value, position]);
|
|
896
1100
|
__classPrivateFieldGet(this, _LiveList_items, "f").sort((itemA, itemB) => (0, position_1.compare)(itemA[1], itemB[1]));
|
|
897
|
-
this.
|
|
1101
|
+
this._notify();
|
|
898
1102
|
if (this._doc && this._id) {
|
|
899
|
-
|
|
1103
|
+
const id = this._doc.generateId();
|
|
1104
|
+
value._attach(id, this._doc);
|
|
1105
|
+
this._doc.addToUndoStack([{ type: live_1.OpType.DeleteCrdt, id }]);
|
|
900
1106
|
this._doc.dispatch(value._serialize(this._id, position));
|
|
901
1107
|
}
|
|
902
1108
|
}
|
|
1109
|
+
/**
|
|
1110
|
+
* Move one element from one index to another.
|
|
1111
|
+
* @param index The index of the element to move
|
|
1112
|
+
* @param targetIndex The index where the element should be after moving.
|
|
1113
|
+
*/
|
|
903
1114
|
move(index, targetIndex) {
|
|
904
1115
|
if (targetIndex < 0) {
|
|
905
1116
|
throw new Error("targetIndex cannot be less than 0");
|
|
@@ -929,10 +1140,19 @@ class LiveList extends AbstractCrdt {
|
|
|
929
1140
|
}
|
|
930
1141
|
const position = (0, position_1.makePosition)(beforePosition, afterPosition);
|
|
931
1142
|
const item = __classPrivateFieldGet(this, _LiveList_items, "f")[index];
|
|
1143
|
+
const previousPosition = item[1];
|
|
932
1144
|
item[1] = position;
|
|
1145
|
+
item[0]._setParentLink(this, position);
|
|
933
1146
|
__classPrivateFieldGet(this, _LiveList_items, "f").sort((itemA, itemB) => (0, position_1.compare)(itemA[1], itemB[1]));
|
|
934
|
-
this.
|
|
1147
|
+
this._notify();
|
|
935
1148
|
if (this._doc && this._id) {
|
|
1149
|
+
this._doc.addToUndoStack([
|
|
1150
|
+
{
|
|
1151
|
+
type: live_1.OpType.SetParentKey,
|
|
1152
|
+
id: item[0]._id,
|
|
1153
|
+
parentKey: previousPosition,
|
|
1154
|
+
},
|
|
1155
|
+
]);
|
|
936
1156
|
this._doc.dispatch([
|
|
937
1157
|
{
|
|
938
1158
|
type: live_1.OpType.SetParentKey,
|
|
@@ -942,6 +1162,10 @@ class LiveList extends AbstractCrdt {
|
|
|
942
1162
|
]);
|
|
943
1163
|
}
|
|
944
1164
|
}
|
|
1165
|
+
/**
|
|
1166
|
+
* Deletes an element at the specified index
|
|
1167
|
+
* @param index The index of the element to delete
|
|
1168
|
+
*/
|
|
945
1169
|
delete(index) {
|
|
946
1170
|
if (index < 0 || index >= __classPrivateFieldGet(this, _LiveList_items, "f").length) {
|
|
947
1171
|
throw new Error(`Cannot delete list item at index "${index}". index should be between 0 and ${__classPrivateFieldGet(this, _LiveList_items, "f").length - 1}`);
|
|
@@ -952,6 +1176,7 @@ class LiveList extends AbstractCrdt {
|
|
|
952
1176
|
if (this._doc) {
|
|
953
1177
|
const childRecordId = item[0]._id;
|
|
954
1178
|
if (childRecordId) {
|
|
1179
|
+
this._doc.addToUndoStack(item[0]._serialize(this._id, item[1]));
|
|
955
1180
|
this._doc.dispatch([
|
|
956
1181
|
{
|
|
957
1182
|
id: childRecordId,
|
|
@@ -960,41 +1185,95 @@ class LiveList extends AbstractCrdt {
|
|
|
960
1185
|
]);
|
|
961
1186
|
}
|
|
962
1187
|
}
|
|
963
|
-
this.
|
|
1188
|
+
this._notify();
|
|
964
1189
|
}
|
|
1190
|
+
/**
|
|
1191
|
+
* Returns an Array of all the elements in the LiveList.
|
|
1192
|
+
*/
|
|
965
1193
|
toArray() {
|
|
966
1194
|
return __classPrivateFieldGet(this, _LiveList_items, "f").map((entry) => selfOrRegisterValue(entry[0]));
|
|
967
1195
|
}
|
|
1196
|
+
/**
|
|
1197
|
+
* Tests whether all elements pass the test implemented by the provided function.
|
|
1198
|
+
* @param predicate Function to test for each element, taking two arguments (the element and its index).
|
|
1199
|
+
* @returns true if the predicate function returns a truthy value for every element. Otherwise, false.
|
|
1200
|
+
*/
|
|
968
1201
|
every(predicate) {
|
|
969
1202
|
return this.toArray().every(predicate);
|
|
970
1203
|
}
|
|
1204
|
+
/**
|
|
1205
|
+
* Creates an array with all elements that pass the test implemented by the provided function.
|
|
1206
|
+
* @param predicate Function to test each element of the LiveList. Return a value that coerces to true to keep the element, or to false otherwise.
|
|
1207
|
+
* @returns An array with the elements that pass the test.
|
|
1208
|
+
*/
|
|
971
1209
|
filter(predicate) {
|
|
972
1210
|
return this.toArray().filter(predicate);
|
|
973
1211
|
}
|
|
1212
|
+
/**
|
|
1213
|
+
* Returns the first element that satisfies the provided testing function.
|
|
1214
|
+
* @param predicate Function to execute on each value.
|
|
1215
|
+
* @returns The value of the first element in the LiveList that satisfies the provided testing function. Otherwise, undefined is returned.
|
|
1216
|
+
*/
|
|
974
1217
|
find(predicate) {
|
|
975
1218
|
return this.toArray().find(predicate);
|
|
976
1219
|
}
|
|
1220
|
+
/**
|
|
1221
|
+
* Returns the index of the first element in the LiveList that satisfies the provided testing function.
|
|
1222
|
+
* @param predicate Function to execute on each value until the function returns true, indicating that the satisfying element was found.
|
|
1223
|
+
* @returns The index of the first element in the LiveList that passes the test. Otherwise, -1.
|
|
1224
|
+
*/
|
|
977
1225
|
findIndex(predicate) {
|
|
978
1226
|
return this.toArray().findIndex(predicate);
|
|
979
1227
|
}
|
|
1228
|
+
/**
|
|
1229
|
+
* Executes a provided function once for each element.
|
|
1230
|
+
* @param callbackfn Function to execute on each element.
|
|
1231
|
+
*/
|
|
980
1232
|
forEach(callbackfn) {
|
|
981
1233
|
return this.toArray().forEach(callbackfn);
|
|
982
1234
|
}
|
|
1235
|
+
/**
|
|
1236
|
+
* Get the element at the specified index.
|
|
1237
|
+
* @param index The index on the element to get.
|
|
1238
|
+
* @returns The element at the specified index or undefined.
|
|
1239
|
+
*/
|
|
983
1240
|
get(index) {
|
|
984
1241
|
if (index < 0 || index >= __classPrivateFieldGet(this, _LiveList_items, "f").length) {
|
|
985
1242
|
return undefined;
|
|
986
1243
|
}
|
|
987
1244
|
return selfOrRegisterValue(__classPrivateFieldGet(this, _LiveList_items, "f")[index][0]);
|
|
988
1245
|
}
|
|
1246
|
+
/**
|
|
1247
|
+
* Returns the first index at which a given element can be found in the LiveList, or -1 if it is not present.
|
|
1248
|
+
* @param searchElement Element to locate.
|
|
1249
|
+
* @param fromIndex The index to start the search at.
|
|
1250
|
+
* @returns The first index of the element in the LiveList; -1 if not found.
|
|
1251
|
+
*/
|
|
989
1252
|
indexOf(searchElement, fromIndex) {
|
|
990
1253
|
return this.toArray().indexOf(searchElement, fromIndex);
|
|
991
1254
|
}
|
|
1255
|
+
/**
|
|
1256
|
+
* Returns the last index at which a given element can be found in the LiveList, or -1 if it is not present. The LiveLsit is searched backwards, starting at fromIndex.
|
|
1257
|
+
* @param searchElement Element to locate.
|
|
1258
|
+
* @param fromIndex The index at which to start searching backwards.
|
|
1259
|
+
* @returns
|
|
1260
|
+
*/
|
|
992
1261
|
lastIndexOf(searchElement, fromIndex) {
|
|
993
1262
|
return this.toArray().lastIndexOf(searchElement, fromIndex);
|
|
994
1263
|
}
|
|
1264
|
+
/**
|
|
1265
|
+
* Creates an array populated with the results of calling a provided function on every element.
|
|
1266
|
+
* @param callback Function that is called for every element.
|
|
1267
|
+
* @returns An array with each element being the result of the callback function.
|
|
1268
|
+
*/
|
|
995
1269
|
map(callback) {
|
|
996
1270
|
return __classPrivateFieldGet(this, _LiveList_items, "f").map((entry, i) => callback(selfOrRegisterValue(entry[0]), i));
|
|
997
1271
|
}
|
|
1272
|
+
/**
|
|
1273
|
+
* Tests whether at least one element in the LiveList passes the test implemented by the provided function.
|
|
1274
|
+
* @param predicate Function to test for each element.
|
|
1275
|
+
* @returns true if the callback function returns a truthy value for at least one element. Otherwise, false.
|
|
1276
|
+
*/
|
|
998
1277
|
some(predicate) {
|
|
999
1278
|
return this.toArray().some(predicate);
|
|
1000
1279
|
}
|