@liveblocks/client 0.12.0-beta.8 → 0.12.2

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