@liveblocks/client 0.13.0 → 0.13.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -53,6 +53,11 @@ export declare class LiveObject<T extends Record<string, any> = Record<string, a
53
53
  * @param key The key of the property to get
54
54
  */
55
55
  get<TKey extends keyof T>(key: TKey): T[TKey];
56
+ /**
57
+ * Deletes a key from the LiveObject
58
+ * @param key The key of the property to delete
59
+ */
60
+ delete(key: keyof T): void;
56
61
  /**
57
62
  * Adds or updates multiple properties at once with an object.
58
63
  * @param overrides The object used to overrides properties
@@ -186,6 +186,40 @@ class LiveObject extends AbstractCrdt_1.AbstractCrdt {
186
186
  get(key) {
187
187
  return __classPrivateFieldGet(this, _LiveObject_map, "f").get(key);
188
188
  }
189
+ /**
190
+ * Deletes a key from the LiveObject
191
+ * @param key The key of the property to delete
192
+ */
193
+ delete(key) {
194
+ const keyAsString = key;
195
+ const oldValue = __classPrivateFieldGet(this, _LiveObject_map, "f").get(keyAsString);
196
+ if (oldValue === undefined) {
197
+ return;
198
+ }
199
+ if (this._doc == null || this._id == null) {
200
+ if (oldValue instanceof AbstractCrdt_1.AbstractCrdt) {
201
+ oldValue._detach();
202
+ }
203
+ __classPrivateFieldGet(this, _LiveObject_map, "f").delete(keyAsString);
204
+ return;
205
+ }
206
+ let reverse;
207
+ if (oldValue instanceof AbstractCrdt_1.AbstractCrdt) {
208
+ oldValue._detach();
209
+ reverse = oldValue._serialize(this._id, keyAsString);
210
+ }
211
+ else {
212
+ reverse = [
213
+ {
214
+ type: live_1.OpType.UpdateObject,
215
+ data: { [keyAsString]: oldValue },
216
+ id: this._id,
217
+ },
218
+ ];
219
+ }
220
+ __classPrivateFieldGet(this, _LiveObject_map, "f").delete(keyAsString);
221
+ this._doc.dispatch([{ type: live_1.OpType.DeleteObjectKey, key: keyAsString, id: this._id }], reverse, [this]);
222
+ }
189
223
  /**
190
224
  * Adds or updates multiple properties at once with an object.
191
225
  * @param overrides The object used to overrides properties
@@ -310,6 +344,10 @@ _LiveObject_map = new WeakMap(), _LiveObject_propToLastUpdate = new WeakMap(), _
310
344
  return isModified ? { modified: this, reverse } : { modified: false };
311
345
  }, _LiveObject_applyDeleteObjectKey = function _LiveObject_applyDeleteObjectKey(op) {
312
346
  const key = op.key;
347
+ // If property does not exist, exit without notifying
348
+ if (__classPrivateFieldGet(this, _LiveObject_map, "f").has(key) === false) {
349
+ return { modified: false };
350
+ }
313
351
  const oldValue = __classPrivateFieldGet(this, _LiveObject_map, "f").get(key);
314
352
  let reverse = [];
315
353
  if ((0, utils_1.isCrdt)(oldValue)) {
@@ -277,25 +277,57 @@ export declare type Room = {
277
277
  }): () => void;
278
278
  };
279
279
  /**
280
- * Room's history contains function that let you undo and redo operation made on by the current client on the presence and storage.
280
+ * Room's history contains functions that let you undo and redo operation made on by the current client on the presence and storage.
281
281
  */
282
282
  history: {
283
283
  /**
284
284
  * Undoes the last operation executed by the current client.
285
285
  * It does not impact operations made by other clients.
286
+ *
287
+ * @example
288
+ * room.updatePresence({ selectedId: "xxx" }, { addToHistory: true });
289
+ * room.updatePresence({ selectedId: "yyy" }, { addToHistory: true });
290
+ * room.history.undo();
291
+ * // room.getPresence() equals { selectedId: "xxx" }
286
292
  */
287
293
  undo: () => void;
288
294
  /**
289
295
  * Redoes the last operation executed by the current client.
290
296
  * It does not impact operations made by other clients.
297
+ *
298
+ * @example
299
+ * room.updatePresence({ selectedId: "xxx" }, { addToHistory: true });
300
+ * room.updatePresence({ selectedId: "yyy" }, { addToHistory: true });
301
+ * room.history.undo();
302
+ * // room.getPresence() equals { selectedId: "xxx" }
303
+ * room.history.redo();
304
+ * // room.getPresence() equals { selectedId: "yyy" }
291
305
  */
292
306
  redo: () => void;
293
307
  /**
294
308
  * All future modifications made on the Room will be merged together to create a single history item until resume is called.
309
+ *
310
+ * @example
311
+ * room.updatePresence({ cursor: { x: 0, y: 0 } }, { addToHistory: true });
312
+ * room.history.pause();
313
+ * room.updatePresence({ cursor: { x: 1, y: 1 } }, { addToHistory: true });
314
+ * room.updatePresence({ cursor: { x: 2, y: 2 } }, { addToHistory: true });
315
+ * room.history.resume();
316
+ * room.history.undo();
317
+ * // room.getPresence() equals { cursor: { x: 0, y: 0 } }
295
318
  */
296
319
  pause: () => void;
297
320
  /**
298
321
  * Resumes history. Modifications made on the Room are not merged into a single history item anymore.
322
+ *
323
+ * @example
324
+ * room.updatePresence({ cursor: { x: 0, y: 0 } }, { addToHistory: true });
325
+ * room.history.pause();
326
+ * room.updatePresence({ cursor: { x: 1, y: 1 } }, { addToHistory: true });
327
+ * room.updatePresence({ cursor: { x: 2, y: 2 } }, { addToHistory: true });
328
+ * room.history.resume();
329
+ * room.history.undo();
330
+ * // room.getPresence() equals { cursor: { x: 0, y: 0 } }
299
331
  */
300
332
  resume: () => void;
301
333
  };
@@ -392,6 +424,13 @@ export declare type Room = {
392
424
  * });
393
425
  */
394
426
  broadcastEvent: (event: any) => void;
427
+ /**
428
+ * Get the room's storage asynchronously.
429
+ * The storage's root is a {@link LiveObject}.
430
+ *
431
+ * @example
432
+ * const { root } = await room.getStorage();
433
+ */
395
434
  getStorage: <TRoot>() => Promise<{
396
435
  root: LiveObject<TRoot>;
397
436
  }>;
@@ -400,6 +439,13 @@ export declare type Room = {
400
439
  * All the modifications are sent to other clients in a single message.
401
440
  * All the subscribers are called only after the batch is over.
402
441
  * All the modifications are merged in a single history item (undo/redo).
442
+ *
443
+ * @example
444
+ * const { root } = await room.getStorage();
445
+ * room.batch(() => {
446
+ * root.set("x", 0);
447
+ * room.updatePresence({ cursor: { x: 100, y: 100 }});
448
+ * });
403
449
  */
404
450
  batch: (fn: () => void) => void;
405
451
  };
@@ -53,6 +53,11 @@ export declare class LiveObject<T extends Record<string, any> = Record<string, a
53
53
  * @param key The key of the property to get
54
54
  */
55
55
  get<TKey extends keyof T>(key: TKey): T[TKey];
56
+ /**
57
+ * Deletes a key from the LiveObject
58
+ * @param key The key of the property to delete
59
+ */
60
+ delete(key: keyof T): void;
56
61
  /**
57
62
  * Adds or updates multiple properties at once with an object.
58
63
  * @param overrides The object used to overrides properties
@@ -183,6 +183,40 @@ export class LiveObject extends AbstractCrdt {
183
183
  get(key) {
184
184
  return __classPrivateFieldGet(this, _LiveObject_map, "f").get(key);
185
185
  }
186
+ /**
187
+ * Deletes a key from the LiveObject
188
+ * @param key The key of the property to delete
189
+ */
190
+ delete(key) {
191
+ const keyAsString = key;
192
+ const oldValue = __classPrivateFieldGet(this, _LiveObject_map, "f").get(keyAsString);
193
+ if (oldValue === undefined) {
194
+ return;
195
+ }
196
+ if (this._doc == null || this._id == null) {
197
+ if (oldValue instanceof AbstractCrdt) {
198
+ oldValue._detach();
199
+ }
200
+ __classPrivateFieldGet(this, _LiveObject_map, "f").delete(keyAsString);
201
+ return;
202
+ }
203
+ let reverse;
204
+ if (oldValue instanceof AbstractCrdt) {
205
+ oldValue._detach();
206
+ reverse = oldValue._serialize(this._id, keyAsString);
207
+ }
208
+ else {
209
+ reverse = [
210
+ {
211
+ type: OpType.UpdateObject,
212
+ data: { [keyAsString]: oldValue },
213
+ id: this._id,
214
+ },
215
+ ];
216
+ }
217
+ __classPrivateFieldGet(this, _LiveObject_map, "f").delete(keyAsString);
218
+ this._doc.dispatch([{ type: OpType.DeleteObjectKey, key: keyAsString, id: this._id }], reverse, [this]);
219
+ }
186
220
  /**
187
221
  * Adds or updates multiple properties at once with an object.
188
222
  * @param overrides The object used to overrides properties
@@ -306,6 +340,10 @@ _LiveObject_map = new WeakMap(), _LiveObject_propToLastUpdate = new WeakMap(), _
306
340
  return isModified ? { modified: this, reverse } : { modified: false };
307
341
  }, _LiveObject_applyDeleteObjectKey = function _LiveObject_applyDeleteObjectKey(op) {
308
342
  const key = op.key;
343
+ // If property does not exist, exit without notifying
344
+ if (__classPrivateFieldGet(this, _LiveObject_map, "f").has(key) === false) {
345
+ return { modified: false };
346
+ }
309
347
  const oldValue = __classPrivateFieldGet(this, _LiveObject_map, "f").get(key);
310
348
  let reverse = [];
311
349
  if (isCrdt(oldValue)) {
@@ -277,25 +277,57 @@ export declare type Room = {
277
277
  }): () => void;
278
278
  };
279
279
  /**
280
- * Room's history contains function that let you undo and redo operation made on by the current client on the presence and storage.
280
+ * Room's history contains functions that let you undo and redo operation made on by the current client on the presence and storage.
281
281
  */
282
282
  history: {
283
283
  /**
284
284
  * Undoes the last operation executed by the current client.
285
285
  * It does not impact operations made by other clients.
286
+ *
287
+ * @example
288
+ * room.updatePresence({ selectedId: "xxx" }, { addToHistory: true });
289
+ * room.updatePresence({ selectedId: "yyy" }, { addToHistory: true });
290
+ * room.history.undo();
291
+ * // room.getPresence() equals { selectedId: "xxx" }
286
292
  */
287
293
  undo: () => void;
288
294
  /**
289
295
  * Redoes the last operation executed by the current client.
290
296
  * It does not impact operations made by other clients.
297
+ *
298
+ * @example
299
+ * room.updatePresence({ selectedId: "xxx" }, { addToHistory: true });
300
+ * room.updatePresence({ selectedId: "yyy" }, { addToHistory: true });
301
+ * room.history.undo();
302
+ * // room.getPresence() equals { selectedId: "xxx" }
303
+ * room.history.redo();
304
+ * // room.getPresence() equals { selectedId: "yyy" }
291
305
  */
292
306
  redo: () => void;
293
307
  /**
294
308
  * All future modifications made on the Room will be merged together to create a single history item until resume is called.
309
+ *
310
+ * @example
311
+ * room.updatePresence({ cursor: { x: 0, y: 0 } }, { addToHistory: true });
312
+ * room.history.pause();
313
+ * room.updatePresence({ cursor: { x: 1, y: 1 } }, { addToHistory: true });
314
+ * room.updatePresence({ cursor: { x: 2, y: 2 } }, { addToHistory: true });
315
+ * room.history.resume();
316
+ * room.history.undo();
317
+ * // room.getPresence() equals { cursor: { x: 0, y: 0 } }
295
318
  */
296
319
  pause: () => void;
297
320
  /**
298
321
  * Resumes history. Modifications made on the Room are not merged into a single history item anymore.
322
+ *
323
+ * @example
324
+ * room.updatePresence({ cursor: { x: 0, y: 0 } }, { addToHistory: true });
325
+ * room.history.pause();
326
+ * room.updatePresence({ cursor: { x: 1, y: 1 } }, { addToHistory: true });
327
+ * room.updatePresence({ cursor: { x: 2, y: 2 } }, { addToHistory: true });
328
+ * room.history.resume();
329
+ * room.history.undo();
330
+ * // room.getPresence() equals { cursor: { x: 0, y: 0 } }
299
331
  */
300
332
  resume: () => void;
301
333
  };
@@ -392,6 +424,13 @@ export declare type Room = {
392
424
  * });
393
425
  */
394
426
  broadcastEvent: (event: any) => void;
427
+ /**
428
+ * Get the room's storage asynchronously.
429
+ * The storage's root is a {@link LiveObject}.
430
+ *
431
+ * @example
432
+ * const { root } = await room.getStorage();
433
+ */
395
434
  getStorage: <TRoot>() => Promise<{
396
435
  root: LiveObject<TRoot>;
397
436
  }>;
@@ -400,6 +439,13 @@ export declare type Room = {
400
439
  * All the modifications are sent to other clients in a single message.
401
440
  * All the subscribers are called only after the batch is over.
402
441
  * All the modifications are merged in a single history item (undo/redo).
442
+ *
443
+ * @example
444
+ * const { root } = await room.getStorage();
445
+ * room.batch(() => {
446
+ * root.set("x", 0);
447
+ * room.updatePresence({ cursor: { x: 100, y: 100 }});
448
+ * });
403
449
  */
404
450
  batch: (fn: () => void) => void;
405
451
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@liveblocks/client",
3
- "version": "0.13.0",
3
+ "version": "0.13.1",
4
4
  "description": "",
5
5
  "main": "./lib/cjs/index.js",
6
6
  "module": "./lib/esm/index.js",