@liveblocks/core 3.13.0-vincent2 → 3.13.0

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/dist/index.cjs CHANGED
@@ -6,7 +6,7 @@ var __export = (target, all) => {
6
6
 
7
7
  // src/version.ts
8
8
  var PKG_NAME = "@liveblocks/core";
9
- var PKG_VERSION = "3.13.0-vincent2";
9
+ var PKG_VERSION = "3.13.0";
10
10
  var PKG_FORMAT = "cjs";
11
11
 
12
12
  // src/dupe-detection.ts
@@ -251,6 +251,19 @@ function findLastIndex(arr, predicate) {
251
251
  }
252
252
  return -1;
253
253
  }
254
+ function partition(iterable, predicate) {
255
+ const good = [];
256
+ const bad = [];
257
+ let index = 0;
258
+ for (const item of iterable) {
259
+ if (predicate(item, index++)) {
260
+ good.push(item);
261
+ } else {
262
+ bad.push(item);
263
+ }
264
+ }
265
+ return [good, bad];
266
+ }
254
267
 
255
268
  // src/lib/signals.ts
256
269
  var kSinks = Symbol("kSinks");
@@ -1606,6 +1619,7 @@ function createApiClient({
1606
1619
  comment: {
1607
1620
  id: commentId,
1608
1621
  body: options.body,
1622
+ metadata: options.commentMetadata,
1609
1623
  attachmentIds: options.attachmentIds
1610
1624
  },
1611
1625
  metadata: options.metadata
@@ -1659,6 +1673,16 @@ function createApiClient({
1659
1673
  options.metadata
1660
1674
  );
1661
1675
  }
1676
+ async function editCommentMetadata(options) {
1677
+ return await httpClient.post(
1678
+ url`/v2/c/rooms/${options.roomId}/threads/${options.threadId}/comments/${options.commentId}/metadata`,
1679
+ await authManager.getAuthValue({
1680
+ requestedScope: "comments:read",
1681
+ roomId: options.roomId
1682
+ }),
1683
+ options.metadata
1684
+ );
1685
+ }
1662
1686
  async function createComment(options) {
1663
1687
  const commentId = _nullishCoalesce(options.commentId, () => ( createCommentId()));
1664
1688
  const comment = await httpClient.post(
@@ -1670,6 +1694,7 @@ function createApiClient({
1670
1694
  {
1671
1695
  id: commentId,
1672
1696
  body: options.body,
1697
+ metadata: options.metadata,
1673
1698
  attachmentIds: options.attachmentIds
1674
1699
  }
1675
1700
  );
@@ -1684,7 +1709,8 @@ function createApiClient({
1684
1709
  }),
1685
1710
  {
1686
1711
  body: options.body,
1687
- attachmentIds: options.attachmentIds
1712
+ attachmentIds: options.attachmentIds,
1713
+ metadata: options.metadata
1688
1714
  }
1689
1715
  );
1690
1716
  return convertToCommentData(comment);
@@ -2426,6 +2452,7 @@ function createApiClient({
2426
2452
  editThreadMetadata,
2427
2453
  createComment,
2428
2454
  editComment,
2455
+ editCommentMetadata,
2429
2456
  deleteComment,
2430
2457
  addReaction,
2431
2458
  removeReaction,
@@ -3090,10 +3117,7 @@ var ServerMsgCode = Object.freeze({
3090
3117
  BROADCASTED_EVENT: 103,
3091
3118
  ROOM_STATE: 104,
3092
3119
  // For Storage
3093
- STORAGE_STATE_V7: 200,
3094
- // Only sent in V7
3095
- STORAGE_CHUNK: 210,
3096
- // Used in V8+
3120
+ STORAGE_STATE: 200,
3097
3121
  UPDATE_STORAGE: 201,
3098
3122
  // For Yjs Docs
3099
3123
  UPDATE_YDOC: 300,
@@ -3107,6 +3131,7 @@ var ServerMsgCode = Object.freeze({
3107
3131
  COMMENT_DELETED: 404,
3108
3132
  COMMENT_REACTION_ADDED: 405,
3109
3133
  COMMENT_REACTION_REMOVED: 406,
3134
+ COMMENT_METADATA_UPDATED: 409,
3110
3135
  // Error codes
3111
3136
  REJECT_STORAGE_OP: 299
3112
3137
  // Sent if a mutation was not allowed on the server (i.e. due to permissions, limit exceeded, etc)
@@ -6092,6 +6117,19 @@ var AbstractCrdt = class {
6092
6117
  }
6093
6118
  this.#pool = void 0;
6094
6119
  }
6120
+ /**
6121
+ * Serializes this CRDT and all its children into a list of creation ops
6122
+ * with opIds. Used for forward operations that will be sent over the wire
6123
+ * immediately. Each op gets a unique opId for server acknowledgement.
6124
+ *
6125
+ * @internal
6126
+ */
6127
+ _toOpsWithOpId(parentId, parentKey, pool) {
6128
+ return this._toOps(parentId, parentKey).map((op) => ({
6129
+ opId: pool.generateOpId(),
6130
+ ...op
6131
+ }));
6132
+ }
6095
6133
  /** This caches the result of the last .toImmutable() call for this Live node. */
6096
6134
  #cachedImmutable;
6097
6135
  #cachedTreeNodeKey;
@@ -6143,57 +6181,6 @@ var CrdtType = Object.freeze({
6143
6181
  MAP: 2,
6144
6182
  REGISTER: 3
6145
6183
  });
6146
- function isRootNode(node) {
6147
- return node[0] === "root";
6148
- }
6149
- function isRootCrdt(id, _) {
6150
- return id === "root";
6151
- }
6152
- function* compactNodesToNodeStream(nodes) {
6153
- for (const node of nodes) {
6154
- const id = node[0];
6155
- if (isRootNode(node)) {
6156
- yield [id, { type: CrdtType.OBJECT, data: node[1] }];
6157
- continue;
6158
- }
6159
- switch (node[1]) {
6160
- case CrdtType.OBJECT:
6161
- yield [id, { type: CrdtType.OBJECT, parentId: node[2], parentKey: node[3], data: node[4] }];
6162
- break;
6163
- case CrdtType.LIST:
6164
- yield [id, { type: CrdtType.LIST, parentId: node[2], parentKey: node[3] }];
6165
- break;
6166
- case CrdtType.MAP:
6167
- yield [id, { type: CrdtType.MAP, parentId: node[2], parentKey: node[3] }];
6168
- break;
6169
- case CrdtType.REGISTER:
6170
- yield [id, { type: CrdtType.REGISTER, parentId: node[2], parentKey: node[3], data: node[4] }];
6171
- break;
6172
- }
6173
- }
6174
- }
6175
- function* nodeStreamToCompactNodes(nodes) {
6176
- for (const [id, node] of nodes) {
6177
- switch (node.type) {
6178
- case CrdtType.OBJECT:
6179
- if (isRootCrdt(id, node)) {
6180
- yield [id, node.data];
6181
- } else {
6182
- yield [id, CrdtType.OBJECT, node.parentId, node.parentKey, node.data];
6183
- }
6184
- break;
6185
- case CrdtType.LIST:
6186
- yield [id, CrdtType.LIST, node.parentId, node.parentKey];
6187
- break;
6188
- case CrdtType.MAP:
6189
- yield [id, CrdtType.MAP, node.parentId, node.parentKey];
6190
- break;
6191
- case CrdtType.REGISTER:
6192
- yield [id, CrdtType.REGISTER, node.parentId, node.parentKey, node.data];
6193
- break;
6194
- }
6195
- }
6196
- }
6197
6184
 
6198
6185
  // src/crdts/LiveRegister.ts
6199
6186
  var LiveRegister = class _LiveRegister extends AbstractCrdt {
@@ -6212,7 +6199,7 @@ var LiveRegister = class _LiveRegister extends AbstractCrdt {
6212
6199
  return register;
6213
6200
  }
6214
6201
  /** @internal */
6215
- _toOps(parentId, parentKey, pool) {
6202
+ _toOps(parentId, parentKey) {
6216
6203
  if (this._id === void 0) {
6217
6204
  throw new Error(
6218
6205
  "Cannot serialize register if parentId or parentKey is undefined"
@@ -6221,7 +6208,6 @@ var LiveRegister = class _LiveRegister extends AbstractCrdt {
6221
6208
  return [
6222
6209
  {
6223
6210
  type: OpCode.CREATE_REGISTER,
6224
- opId: _optionalChain([pool, 'optionalAccess', _115 => _115.generateOpId, 'call', _116 => _116()]),
6225
6211
  id: this._id,
6226
6212
  parentId,
6227
6213
  parentKey,
@@ -6320,14 +6306,13 @@ var LiveList = class _LiveList extends AbstractCrdt {
6320
6306
  * This is quite unintuitive and should disappear as soon as
6321
6307
  * we introduce an explicit LiveList.Set operation
6322
6308
  */
6323
- _toOps(parentId, parentKey, pool) {
6309
+ _toOps(parentId, parentKey) {
6324
6310
  if (this._id === void 0) {
6325
6311
  throw new Error("Cannot serialize item is not attached");
6326
6312
  }
6327
6313
  const ops = [];
6328
6314
  const op = {
6329
6315
  id: this._id,
6330
- opId: _optionalChain([pool, 'optionalAccess', _117 => _117.generateOpId, 'call', _118 => _118()]),
6331
6316
  type: OpCode.CREATE_LIST,
6332
6317
  parentId,
6333
6318
  parentKey
@@ -6336,13 +6321,9 @@ var LiveList = class _LiveList extends AbstractCrdt {
6336
6321
  for (const item of this.#items) {
6337
6322
  const parentKey2 = item._getParentKeyOrThrow();
6338
6323
  const childOps = HACK_addIntentAndDeletedIdToOperation(
6339
- item._toOps(this._id, parentKey2, pool),
6324
+ item._toOps(this._id, parentKey2),
6340
6325
  void 0
6341
6326
  );
6342
- const childOpId = childOps[0].opId;
6343
- if (childOpId !== void 0) {
6344
- this.#unacknowledgedSets.set(parentKey2, childOpId);
6345
- }
6346
6327
  ops.push(...childOps);
6347
6328
  }
6348
6329
  return ops;
@@ -6598,7 +6579,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
6598
6579
  #applyInsertUndoRedo(op) {
6599
6580
  const { id, parentKey: key } = op;
6600
6581
  const child = creationOpToLiveNode(op);
6601
- if (_optionalChain([this, 'access', _119 => _119._pool, 'optionalAccess', _120 => _120.getNode, 'call', _121 => _121(id)]) !== void 0) {
6582
+ if (_optionalChain([this, 'access', _115 => _115._pool, 'optionalAccess', _116 => _116.getNode, 'call', _117 => _117(id)]) !== void 0) {
6602
6583
  return { modified: false };
6603
6584
  }
6604
6585
  child._attach(id, nn(this._pool));
@@ -6606,8 +6587,8 @@ var LiveList = class _LiveList extends AbstractCrdt {
6606
6587
  const existingItemIndex = this._indexOfPosition(key);
6607
6588
  let newKey = key;
6608
6589
  if (existingItemIndex !== -1) {
6609
- const before2 = _optionalChain([this, 'access', _122 => _122.#items, 'access', _123 => _123[existingItemIndex], 'optionalAccess', _124 => _124._parentPos]);
6610
- const after2 = _optionalChain([this, 'access', _125 => _125.#items, 'access', _126 => _126[existingItemIndex + 1], 'optionalAccess', _127 => _127._parentPos]);
6590
+ const before2 = _optionalChain([this, 'access', _118 => _118.#items, 'access', _119 => _119[existingItemIndex], 'optionalAccess', _120 => _120._parentPos]);
6591
+ const after2 = _optionalChain([this, 'access', _121 => _121.#items, 'access', _122 => _122[existingItemIndex + 1], 'optionalAccess', _123 => _123._parentPos]);
6611
6592
  newKey = makePosition(before2, after2);
6612
6593
  child._setParentLink(this, newKey);
6613
6594
  }
@@ -6621,7 +6602,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
6621
6602
  #applySetUndoRedo(op) {
6622
6603
  const { id, parentKey: key } = op;
6623
6604
  const child = creationOpToLiveNode(op);
6624
- if (_optionalChain([this, 'access', _128 => _128._pool, 'optionalAccess', _129 => _129.getNode, 'call', _130 => _130(id)]) !== void 0) {
6605
+ if (_optionalChain([this, 'access', _124 => _124._pool, 'optionalAccess', _125 => _125.getNode, 'call', _126 => _126(id)]) !== void 0) {
6625
6606
  return { modified: false };
6626
6607
  }
6627
6608
  this.#unacknowledgedSets.set(key, nn(op.opId));
@@ -6634,7 +6615,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
6634
6615
  existingItem._detach();
6635
6616
  this.#items[indexOfItemWithSameKey] = child;
6636
6617
  const reverse = HACK_addIntentAndDeletedIdToOperation(
6637
- existingItem._toOps(nn(this._id), key, this._pool),
6618
+ existingItem._toOps(nn(this._id), key),
6638
6619
  op.id
6639
6620
  );
6640
6621
  const delta = [setDelta(indexOfItemWithSameKey, child)];
@@ -6690,7 +6671,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
6690
6671
  _detachChild(child) {
6691
6672
  if (child) {
6692
6673
  const parentKey = nn(child._parentKey);
6693
- const reverse = child._toOps(nn(this._id), parentKey, this._pool);
6674
+ const reverse = child._toOps(nn(this._id), parentKey);
6694
6675
  const indexToDelete = this.#items.indexOf(child);
6695
6676
  if (indexToDelete === -1) {
6696
6677
  return {
@@ -6742,7 +6723,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
6742
6723
  } else {
6743
6724
  this.#items[existingItemIndex]._setParentLink(
6744
6725
  this,
6745
- makePosition(newKey, _optionalChain([this, 'access', _131 => _131.#items, 'access', _132 => _132[existingItemIndex + 1], 'optionalAccess', _133 => _133._parentPos]))
6726
+ makePosition(newKey, _optionalChain([this, 'access', _127 => _127.#items, 'access', _128 => _128[existingItemIndex + 1], 'optionalAccess', _129 => _129._parentPos]))
6746
6727
  );
6747
6728
  const previousIndex = this.#items.indexOf(child);
6748
6729
  child._setParentLink(this, newKey);
@@ -6767,7 +6748,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
6767
6748
  if (existingItemIndex !== -1) {
6768
6749
  this.#items[existingItemIndex]._setParentLink(
6769
6750
  this,
6770
- makePosition(newKey, _optionalChain([this, 'access', _134 => _134.#items, 'access', _135 => _135[existingItemIndex + 1], 'optionalAccess', _136 => _136._parentPos]))
6751
+ makePosition(newKey, _optionalChain([this, 'access', _130 => _130.#items, 'access', _131 => _131[existingItemIndex + 1], 'optionalAccess', _132 => _132._parentPos]))
6771
6752
  );
6772
6753
  }
6773
6754
  child._setParentLink(this, newKey);
@@ -6786,7 +6767,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
6786
6767
  if (existingItemIndex !== -1) {
6787
6768
  this.#items[existingItemIndex]._setParentLink(
6788
6769
  this,
6789
- makePosition(newKey, _optionalChain([this, 'access', _137 => _137.#items, 'access', _138 => _138[existingItemIndex + 1], 'optionalAccess', _139 => _139._parentPos]))
6770
+ makePosition(newKey, _optionalChain([this, 'access', _133 => _133.#items, 'access', _134 => _134[existingItemIndex + 1], 'optionalAccess', _135 => _135._parentPos]))
6790
6771
  );
6791
6772
  }
6792
6773
  child._setParentLink(this, newKey);
@@ -6814,7 +6795,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
6814
6795
  if (existingItemIndex !== -1) {
6815
6796
  actualNewKey = makePosition(
6816
6797
  newKey,
6817
- _optionalChain([this, 'access', _140 => _140.#items, 'access', _141 => _141[existingItemIndex + 1], 'optionalAccess', _142 => _142._parentPos])
6798
+ _optionalChain([this, 'access', _136 => _136.#items, 'access', _137 => _137[existingItemIndex + 1], 'optionalAccess', _138 => _138._parentPos])
6818
6799
  );
6819
6800
  }
6820
6801
  child._setParentLink(this, actualNewKey);
@@ -6872,7 +6853,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
6872
6853
  * @param element The element to add to the end of the LiveList.
6873
6854
  */
6874
6855
  push(element) {
6875
- _optionalChain([this, 'access', _143 => _143._pool, 'optionalAccess', _144 => _144.assertStorageIsWritable, 'call', _145 => _145()]);
6856
+ _optionalChain([this, 'access', _139 => _139._pool, 'optionalAccess', _140 => _140.assertStorageIsWritable, 'call', _141 => _141()]);
6876
6857
  return this.insert(element, this.length);
6877
6858
  }
6878
6859
  /**
@@ -6881,7 +6862,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
6881
6862
  * @param index The index at which you want to insert the element.
6882
6863
  */
6883
6864
  insert(element, index) {
6884
- _optionalChain([this, 'access', _146 => _146._pool, 'optionalAccess', _147 => _147.assertStorageIsWritable, 'call', _148 => _148()]);
6865
+ _optionalChain([this, 'access', _142 => _142._pool, 'optionalAccess', _143 => _143.assertStorageIsWritable, 'call', _144 => _144()]);
6885
6866
  if (index < 0 || index > this.#items.length) {
6886
6867
  throw new Error(
6887
6868
  `Cannot insert list item at index "${index}". index should be between 0 and ${this.#items.length}`
@@ -6897,7 +6878,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
6897
6878
  const id = this._pool.generateId();
6898
6879
  value._attach(id, this._pool);
6899
6880
  this._pool.dispatch(
6900
- value._toOps(this._id, position, this._pool),
6881
+ value._toOpsWithOpId(this._id, position, this._pool),
6901
6882
  [{ type: OpCode.DELETE_CRDT, id }],
6902
6883
  /* @__PURE__ */ new Map([
6903
6884
  [this._id, makeUpdate(this, [insertDelta(index, value)])]
@@ -6911,7 +6892,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
6911
6892
  * @param targetIndex The index where the element should be after moving.
6912
6893
  */
6913
6894
  move(index, targetIndex) {
6914
- _optionalChain([this, 'access', _149 => _149._pool, 'optionalAccess', _150 => _150.assertStorageIsWritable, 'call', _151 => _151()]);
6895
+ _optionalChain([this, 'access', _145 => _145._pool, 'optionalAccess', _146 => _146.assertStorageIsWritable, 'call', _147 => _147()]);
6915
6896
  if (targetIndex < 0) {
6916
6897
  throw new Error("targetIndex cannot be less than 0");
6917
6898
  }
@@ -6969,7 +6950,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
6969
6950
  * @param index The index of the element to delete
6970
6951
  */
6971
6952
  delete(index) {
6972
- _optionalChain([this, 'access', _152 => _152._pool, 'optionalAccess', _153 => _153.assertStorageIsWritable, 'call', _154 => _154()]);
6953
+ _optionalChain([this, 'access', _148 => _148._pool, 'optionalAccess', _149 => _149.assertStorageIsWritable, 'call', _150 => _150()]);
6973
6954
  if (index < 0 || index >= this.#items.length) {
6974
6955
  throw new Error(
6975
6956
  `Cannot delete list item at index "${index}". index should be between 0 and ${this.#items.length - 1}`
@@ -7002,7 +6983,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
7002
6983
  }
7003
6984
  }
7004
6985
  clear() {
7005
- _optionalChain([this, 'access', _155 => _155._pool, 'optionalAccess', _156 => _156.assertStorageIsWritable, 'call', _157 => _157()]);
6986
+ _optionalChain([this, 'access', _151 => _151._pool, 'optionalAccess', _152 => _152.assertStorageIsWritable, 'call', _153 => _153()]);
7006
6987
  if (this._pool) {
7007
6988
  const ops = [];
7008
6989
  const reverseOps = [];
@@ -7036,7 +7017,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
7036
7017
  }
7037
7018
  }
7038
7019
  set(index, item) {
7039
- _optionalChain([this, 'access', _158 => _158._pool, 'optionalAccess', _159 => _159.assertStorageIsWritable, 'call', _160 => _160()]);
7020
+ _optionalChain([this, 'access', _154 => _154._pool, 'optionalAccess', _155 => _155.assertStorageIsWritable, 'call', _156 => _156()]);
7040
7021
  if (index < 0 || index >= this.#items.length) {
7041
7022
  throw new Error(
7042
7023
  `Cannot set list item at index "${index}". index should be between 0 and ${this.#items.length - 1}`
@@ -7056,12 +7037,12 @@ var LiveList = class _LiveList extends AbstractCrdt {
7056
7037
  const storageUpdates = /* @__PURE__ */ new Map();
7057
7038
  storageUpdates.set(this._id, makeUpdate(this, [setDelta(index, value)]));
7058
7039
  const ops = HACK_addIntentAndDeletedIdToOperation(
7059
- value._toOps(this._id, position, this._pool),
7040
+ value._toOpsWithOpId(this._id, position, this._pool),
7060
7041
  existingId
7061
7042
  );
7062
7043
  this.#unacknowledgedSets.set(position, nn(ops[0].opId));
7063
7044
  const reverseOps = HACK_addIntentAndDeletedIdToOperation(
7064
- existingItem._toOps(this._id, position, void 0),
7045
+ existingItem._toOps(this._id, position),
7065
7046
  id
7066
7047
  );
7067
7048
  this._pool.dispatch(ops, reverseOps, storageUpdates);
@@ -7182,7 +7163,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
7182
7163
  #shiftItemPosition(index, key) {
7183
7164
  const shiftedPosition = makePosition(
7184
7165
  key,
7185
- this.#items.length > index + 1 ? _optionalChain([this, 'access', _161 => _161.#items, 'access', _162 => _162[index + 1], 'optionalAccess', _163 => _163._parentPos]) : void 0
7166
+ this.#items.length > index + 1 ? _optionalChain([this, 'access', _157 => _157.#items, 'access', _158 => _158[index + 1], 'optionalAccess', _159 => _159._parentPos]) : void 0
7186
7167
  );
7187
7168
  this.#items[index]._setParentLink(this, shiftedPosition);
7188
7169
  }
@@ -7300,21 +7281,20 @@ var LiveMap = class _LiveMap extends AbstractCrdt {
7300
7281
  }
7301
7282
  }
7302
7283
  /** @internal */
7303
- _toOps(parentId, parentKey, pool) {
7284
+ _toOps(parentId, parentKey) {
7304
7285
  if (this._id === void 0) {
7305
7286
  throw new Error("Cannot serialize item is not attached");
7306
7287
  }
7307
7288
  const ops = [];
7308
7289
  const op = {
7309
7290
  id: this._id,
7310
- opId: _optionalChain([pool, 'optionalAccess', _164 => _164.generateOpId, 'call', _165 => _165()]),
7311
7291
  type: OpCode.CREATE_MAP,
7312
7292
  parentId,
7313
7293
  parentKey
7314
7294
  };
7315
7295
  ops.push(op);
7316
7296
  for (const [key, value] of this.#map) {
7317
- ops.push(...value._toOps(this._id, key, pool));
7297
+ ops.push(...value._toOps(this._id, key));
7318
7298
  }
7319
7299
  return ops;
7320
7300
  }
@@ -7398,7 +7378,7 @@ var LiveMap = class _LiveMap extends AbstractCrdt {
7398
7378
  _detachChild(child) {
7399
7379
  const id = nn(this._id);
7400
7380
  const parentKey = nn(child._parentKey);
7401
- const reverse = child._toOps(id, parentKey, this._pool);
7381
+ const reverse = child._toOps(id, parentKey);
7402
7382
  for (const [key, value] of this.#map) {
7403
7383
  if (value === child) {
7404
7384
  this.#map.delete(key);
@@ -7447,7 +7427,7 @@ var LiveMap = class _LiveMap extends AbstractCrdt {
7447
7427
  * @param value The value of the element to add. Should be serializable to JSON.
7448
7428
  */
7449
7429
  set(key, value) {
7450
- _optionalChain([this, 'access', _166 => _166._pool, 'optionalAccess', _167 => _167.assertStorageIsWritable, 'call', _168 => _168()]);
7430
+ _optionalChain([this, 'access', _160 => _160._pool, 'optionalAccess', _161 => _161.assertStorageIsWritable, 'call', _162 => _162()]);
7451
7431
  const oldValue = this.#map.get(key);
7452
7432
  if (oldValue) {
7453
7433
  oldValue._detach();
@@ -7465,10 +7445,10 @@ var LiveMap = class _LiveMap extends AbstractCrdt {
7465
7445
  type: "LiveMap",
7466
7446
  updates: { [key]: { type: "update" } }
7467
7447
  });
7468
- const ops = item._toOps(this._id, key, this._pool);
7448
+ const ops = item._toOpsWithOpId(this._id, key, this._pool);
7469
7449
  this.#unacknowledgedSet.set(key, nn(ops[0].opId));
7470
7450
  this._pool.dispatch(
7471
- item._toOps(this._id, key, this._pool),
7451
+ ops,
7472
7452
  oldValue ? oldValue._toOps(this._id, key) : [{ type: OpCode.DELETE_CRDT, id }],
7473
7453
  storageUpdates
7474
7454
  );
@@ -7493,7 +7473,7 @@ var LiveMap = class _LiveMap extends AbstractCrdt {
7493
7473
  * @returns true if an element existed and has been removed, or false if the element does not exist.
7494
7474
  */
7495
7475
  delete(key) {
7496
- _optionalChain([this, 'access', _169 => _169._pool, 'optionalAccess', _170 => _170.assertStorageIsWritable, 'call', _171 => _171()]);
7476
+ _optionalChain([this, 'access', _163 => _163._pool, 'optionalAccess', _164 => _164.assertStorageIsWritable, 'call', _165 => _165()]);
7497
7477
  const item = this.#map.get(key);
7498
7478
  if (item === void 0) {
7499
7479
  return false;
@@ -7628,12 +7608,25 @@ var LiveMap = class _LiveMap extends AbstractCrdt {
7628
7608
 
7629
7609
  // src/crdts/LiveObject.ts
7630
7610
  var MAX_LIVE_OBJECT_SIZE = 128 * 1024;
7631
- function isRootCrdt2(id, _) {
7611
+ function isRootCrdt(id, _) {
7632
7612
  return id === "root";
7633
7613
  }
7634
7614
  var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
7635
7615
  #map;
7636
- #propToLastUpdate;
7616
+ /**
7617
+ * Tracks unacknowledged local changes per property to preserve optimistic
7618
+ * updates. Maps property keys to their pending operation IDs.
7619
+ *
7620
+ * INVARIANT: Only locally-generated opIds are ever stored here. Remote opIds
7621
+ * are only compared against (to detect ACKs), never stored.
7622
+ *
7623
+ * When a local change is made, the opId is stored here. When a remote op
7624
+ * arrives for the same key:
7625
+ * - If no entry exists → apply remote op
7626
+ * - If opId matches → it's an ACK, clear the entry
7627
+ * - If opId differs → ignore remote op to preserve optimistic update
7628
+ */
7629
+ #unackedOpsByKey;
7637
7630
  /**
7638
7631
  * Enable or disable detection of too large LiveObjects.
7639
7632
  * When enabled, throws an error if LiveObject static data exceeds 128KB, which
@@ -7648,7 +7641,7 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
7648
7641
  const parentToChildren = /* @__PURE__ */ new Map();
7649
7642
  let root = null;
7650
7643
  for (const [id, crdt] of items) {
7651
- if (isRootCrdt2(id, crdt)) {
7644
+ if (isRootCrdt(id, crdt)) {
7652
7645
  root = crdt;
7653
7646
  } else {
7654
7647
  const tuple = [id, crdt];
@@ -7666,8 +7659,8 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
7666
7659
  return [root, parentToChildren];
7667
7660
  }
7668
7661
  /** @private Do not use this API directly */
7669
- static _fromItems(nodes, pool) {
7670
- const [root, parentToChildren] = _LiveObject.#buildRootAndParentToChildren(nodes);
7662
+ static _fromItems(items, pool) {
7663
+ const [root, parentToChildren] = _LiveObject.#buildRootAndParentToChildren(items);
7671
7664
  return _LiveObject._deserialize(
7672
7665
  ["root", root],
7673
7666
  parentToChildren,
@@ -7676,7 +7669,7 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
7676
7669
  }
7677
7670
  constructor(obj = {}) {
7678
7671
  super();
7679
- this.#propToLastUpdate = /* @__PURE__ */ new Map();
7672
+ this.#unackedOpsByKey = /* @__PURE__ */ new Map();
7680
7673
  const o = compactObject(obj);
7681
7674
  for (const key of Object.keys(o)) {
7682
7675
  const value = o[key];
@@ -7687,16 +7680,14 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
7687
7680
  this.#map = new Map(Object.entries(o));
7688
7681
  }
7689
7682
  /** @internal */
7690
- _toOps(parentId, parentKey, pool) {
7683
+ _toOps(parentId, parentKey) {
7691
7684
  if (this._id === void 0) {
7692
7685
  throw new Error("Cannot serialize item is not attached");
7693
7686
  }
7694
- const opId = _optionalChain([pool, 'optionalAccess', _172 => _172.generateOpId, 'call', _173 => _173()]);
7695
7687
  const ops = [];
7696
7688
  const op = {
7697
7689
  type: OpCode.CREATE_OBJECT,
7698
7690
  id: this._id,
7699
- opId,
7700
7691
  parentId,
7701
7692
  parentKey,
7702
7693
  data: {}
@@ -7704,7 +7695,7 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
7704
7695
  ops.push(op);
7705
7696
  for (const [key, value] of this.#map) {
7706
7697
  if (isLiveNode(value)) {
7707
- ops.push(...value._toOps(this._id, key, pool));
7698
+ ops.push(...value._toOps(this._id, key));
7708
7699
  } else {
7709
7700
  op.data[key] = value;
7710
7701
  }
@@ -7750,16 +7741,16 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
7750
7741
  const { id, opId, parentKey: key } = op;
7751
7742
  const child = creationOpToLson(op);
7752
7743
  if (this._pool.getNode(id) !== void 0) {
7753
- if (this.#propToLastUpdate.get(key) === opId) {
7754
- this.#propToLastUpdate.delete(key);
7744
+ if (this.#unackedOpsByKey.get(key) === opId) {
7745
+ this.#unackedOpsByKey.delete(key);
7755
7746
  }
7756
7747
  return { modified: false };
7757
7748
  }
7758
7749
  if (source === 0 /* LOCAL */) {
7759
- this.#propToLastUpdate.set(key, nn(opId));
7760
- } else if (this.#propToLastUpdate.get(key) === void 0) {
7761
- } else if (this.#propToLastUpdate.get(key) === opId) {
7762
- this.#propToLastUpdate.delete(key);
7750
+ this.#unackedOpsByKey.set(key, nn(opId));
7751
+ } else if (this.#unackedOpsByKey.get(key) === void 0) {
7752
+ } else if (this.#unackedOpsByKey.get(key) === opId) {
7753
+ this.#unackedOpsByKey.delete(key);
7763
7754
  return { modified: false };
7764
7755
  } else {
7765
7756
  return { modified: false };
@@ -7801,7 +7792,7 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
7801
7792
  if (child) {
7802
7793
  const id = nn(this._id);
7803
7794
  const parentKey = nn(child._parentKey);
7804
- const reverse = child._toOps(id, parentKey, this._pool);
7795
+ const reverse = child._toOps(id, parentKey);
7805
7796
  for (const [key, value] of this.#map) {
7806
7797
  if (value === child) {
7807
7798
  this.#map.delete(key);
@@ -7887,11 +7878,11 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
7887
7878
  continue;
7888
7879
  }
7889
7880
  if (isLocal) {
7890
- this.#propToLastUpdate.set(key, nn(op.opId));
7891
- } else if (this.#propToLastUpdate.get(key) === void 0) {
7881
+ this.#unackedOpsByKey.set(key, nn(op.opId));
7882
+ } else if (this.#unackedOpsByKey.get(key) === void 0) {
7892
7883
  isModified = true;
7893
- } else if (this.#propToLastUpdate.get(key) === op.opId) {
7894
- this.#propToLastUpdate.delete(key);
7884
+ } else if (this.#unackedOpsByKey.get(key) === op.opId) {
7885
+ this.#unackedOpsByKey.delete(key);
7895
7886
  continue;
7896
7887
  } else {
7897
7888
  continue;
@@ -7923,7 +7914,7 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
7923
7914
  if (oldValue === void 0) {
7924
7915
  return { modified: false };
7925
7916
  }
7926
- if (!isLocal && this.#propToLastUpdate.get(key) !== void 0) {
7917
+ if (!isLocal && this.#unackedOpsByKey.get(key) !== void 0) {
7927
7918
  return { modified: false };
7928
7919
  }
7929
7920
  const id = nn(this._id);
@@ -7965,7 +7956,7 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
7965
7956
  * @param value The value of the property to add
7966
7957
  */
7967
7958
  set(key, value) {
7968
- _optionalChain([this, 'access', _174 => _174._pool, 'optionalAccess', _175 => _175.assertStorageIsWritable, 'call', _176 => _176()]);
7959
+ _optionalChain([this, 'access', _166 => _166._pool, 'optionalAccess', _167 => _167.assertStorageIsWritable, 'call', _168 => _168()]);
7969
7960
  this.update({ [key]: value });
7970
7961
  }
7971
7962
  /**
@@ -7980,7 +7971,7 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
7980
7971
  * @param key The key of the property to delete
7981
7972
  */
7982
7973
  delete(key) {
7983
- _optionalChain([this, 'access', _177 => _177._pool, 'optionalAccess', _178 => _178.assertStorageIsWritable, 'call', _179 => _179()]);
7974
+ _optionalChain([this, 'access', _169 => _169._pool, 'optionalAccess', _170 => _170.assertStorageIsWritable, 'call', _171 => _171()]);
7984
7975
  const keyAsString = key;
7985
7976
  const oldValue = this.#map.get(keyAsString);
7986
7977
  if (oldValue === void 0) {
@@ -8035,7 +8026,7 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
8035
8026
  * @param patch The object used to overrides properties
8036
8027
  */
8037
8028
  update(patch) {
8038
- _optionalChain([this, 'access', _180 => _180._pool, 'optionalAccess', _181 => _181.assertStorageIsWritable, 'call', _182 => _182()]);
8029
+ _optionalChain([this, 'access', _172 => _172._pool, 'optionalAccess', _173 => _173.assertStorageIsWritable, 'call', _174 => _174()]);
8039
8030
  if (_LiveObject.detectLargeObjects) {
8040
8031
  const data = {};
8041
8032
  for (const [key, value] of this.#map) {
@@ -8106,17 +8097,21 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
8106
8097
  if (isLiveNode(newValue)) {
8107
8098
  newValue._setParentLink(this, key);
8108
8099
  newValue._attach(this._pool.generateId(), this._pool);
8109
- const newAttachChildOps = newValue._toOps(this._id, key, this._pool);
8100
+ const newAttachChildOps = newValue._toOpsWithOpId(
8101
+ this._id,
8102
+ key,
8103
+ this._pool
8104
+ );
8110
8105
  const createCrdtOp = newAttachChildOps.find(
8111
8106
  (op) => op.parentId === this._id
8112
8107
  );
8113
8108
  if (createCrdtOp) {
8114
- this.#propToLastUpdate.set(key, nn(createCrdtOp.opId));
8109
+ this.#unackedOpsByKey.set(key, nn(createCrdtOp.opId));
8115
8110
  }
8116
8111
  ops.push(...newAttachChildOps);
8117
8112
  } else {
8118
8113
  updatedProps[key] = newValue;
8119
- this.#propToLastUpdate.set(key, opId);
8114
+ this.#unackedOpsByKey.set(key, opId);
8120
8115
  }
8121
8116
  this.#map.set(key, newValue);
8122
8117
  this.invalidate();
@@ -8286,7 +8281,10 @@ function getTreesDiffOperations(currentItems, newItems) {
8286
8281
  const ops = [];
8287
8282
  currentItems.forEach((_, id) => {
8288
8283
  if (!newItems.get(id)) {
8289
- ops.push({ type: OpCode.DELETE_CRDT, id });
8284
+ ops.push({
8285
+ type: OpCode.DELETE_CRDT,
8286
+ id
8287
+ });
8290
8288
  }
8291
8289
  });
8292
8290
  newItems.forEach((crdt, id) => {
@@ -8711,6 +8709,8 @@ function defaultMessageFromContext(context) {
8711
8709
  return "Could not delete thread";
8712
8710
  case "EDIT_THREAD_METADATA_ERROR":
8713
8711
  return "Could not edit thread metadata";
8712
+ case "EDIT_COMMENT_METADATA_ERROR":
8713
+ return "Could not edit comment metadata";
8714
8714
  case "MARK_THREAD_AS_RESOLVED_ERROR":
8715
8715
  return "Could not mark thread as resolved";
8716
8716
  case "MARK_THREAD_AS_UNRESOLVED_ERROR":
@@ -8772,33 +8772,18 @@ function installBackgroundTabSpy() {
8772
8772
  const doc = typeof document !== "undefined" ? document : void 0;
8773
8773
  const inBackgroundSince = { current: null };
8774
8774
  function onVisibilityChange() {
8775
- if (_optionalChain([doc, 'optionalAccess', _183 => _183.visibilityState]) === "hidden") {
8775
+ if (_optionalChain([doc, 'optionalAccess', _175 => _175.visibilityState]) === "hidden") {
8776
8776
  inBackgroundSince.current = _nullishCoalesce(inBackgroundSince.current, () => ( Date.now()));
8777
8777
  } else {
8778
8778
  inBackgroundSince.current = null;
8779
8779
  }
8780
8780
  }
8781
- _optionalChain([doc, 'optionalAccess', _184 => _184.addEventListener, 'call', _185 => _185("visibilitychange", onVisibilityChange)]);
8781
+ _optionalChain([doc, 'optionalAccess', _176 => _176.addEventListener, 'call', _177 => _177("visibilitychange", onVisibilityChange)]);
8782
8782
  const unsub = () => {
8783
- _optionalChain([doc, 'optionalAccess', _186 => _186.removeEventListener, 'call', _187 => _187("visibilitychange", onVisibilityChange)]);
8783
+ _optionalChain([doc, 'optionalAccess', _178 => _178.removeEventListener, 'call', _179 => _179("visibilitychange", onVisibilityChange)]);
8784
8784
  };
8785
8785
  return [inBackgroundSince, unsub];
8786
8786
  }
8787
- function makePartialNodeMap() {
8788
- let map = /* @__PURE__ */ new Map();
8789
- return {
8790
- append(chunk2) {
8791
- for (const [id, node] of chunk2) {
8792
- map.set(id, node);
8793
- }
8794
- },
8795
- clear() {
8796
- const result = map;
8797
- map = /* @__PURE__ */ new Map();
8798
- return result;
8799
- }
8800
- };
8801
- }
8802
8787
  function createRoom(options, config) {
8803
8788
  const roomId = config.roomId;
8804
8789
  const initialPresence = options.initialPresence;
@@ -8859,7 +8844,6 @@ function createRoom(options, config) {
8859
8844
  activeBatch: null,
8860
8845
  unacknowledgedOps: /* @__PURE__ */ new Map()
8861
8846
  };
8862
- const partialNodes = makePartialNodeMap();
8863
8847
  let lastTokenKey;
8864
8848
  function onStatusDidChange(newStatus) {
8865
8849
  const authValue = managedSocket.authValue;
@@ -8964,7 +8948,7 @@ function createRoom(options, config) {
8964
8948
  }
8965
8949
  }
8966
8950
  function isStorageWritable() {
8967
- const scopes = _optionalChain([context, 'access', _188 => _188.dynamicSessionInfoSig, 'access', _189 => _189.get, 'call', _190 => _190(), 'optionalAccess', _191 => _191.scopes]);
8951
+ const scopes = _optionalChain([context, 'access', _180 => _180.dynamicSessionInfoSig, 'access', _181 => _181.get, 'call', _182 => _182(), 'optionalAccess', _183 => _183.scopes]);
8968
8952
  return scopes !== void 0 ? canWriteStorage(scopes) : true;
8969
8953
  }
8970
8954
  const eventHub = {
@@ -9095,7 +9079,7 @@ function createRoom(options, config) {
9095
9079
  // be stuck in "synchronizing" forever).
9096
9080
  case "experimental-fallback-to-http": {
9097
9081
  warn("Message is too large for websockets, so sending over HTTP instead");
9098
- const nonce = _nullishCoalesce(_optionalChain([context, 'access', _192 => _192.dynamicSessionInfoSig, 'access', _193 => _193.get, 'call', _194 => _194(), 'optionalAccess', _195 => _195.nonce]), () => ( raise("Session is not authorized to send message over HTTP")));
9082
+ const nonce = _nullishCoalesce(_optionalChain([context, 'access', _184 => _184.dynamicSessionInfoSig, 'access', _185 => _185.get, 'call', _186 => _186(), 'optionalAccess', _187 => _187.nonce]), () => ( raise("Session is not authorized to send message over HTTP")));
9099
9083
  void httpClient.sendMessagesOverHTTP({ roomId, nonce, messages }).then((resp) => {
9100
9084
  if (!resp.ok && resp.status === 403) {
9101
9085
  managedSocket.reconnect();
@@ -9141,13 +9125,16 @@ function createRoom(options, config) {
9141
9125
  self,
9142
9126
  (me) => me !== null ? userToTreeNode("Me", me) : null
9143
9127
  );
9144
- function createOrUpdateRootFromMessage(nodes) {
9128
+ function createOrUpdateRootFromMessage(message) {
9129
+ if (message.items.length === 0) {
9130
+ throw new Error("Internal error: cannot load storage without items");
9131
+ }
9145
9132
  if (context.root !== void 0) {
9146
- updateRoot(new Map(nodes));
9133
+ updateRoot(message.items);
9147
9134
  } else {
9148
- context.root = LiveObject._fromItems(nodes, context.pool);
9135
+ context.root = LiveObject._fromItems(message.items, context.pool);
9149
9136
  }
9150
- const canWrite = _nullishCoalesce(_optionalChain([self, 'access', _196 => _196.get, 'call', _197 => _197(), 'optionalAccess', _198 => _198.canWrite]), () => ( true));
9137
+ const canWrite = _nullishCoalesce(_optionalChain([self, 'access', _188 => _188.get, 'call', _189 => _189(), 'optionalAccess', _190 => _190.canWrite]), () => ( true));
9151
9138
  const stackSizeBefore = context.undoStack.length;
9152
9139
  for (const key in context.initialStorage) {
9153
9140
  if (context.root.get(key) === void 0) {
@@ -9162,10 +9149,7 @@ function createRoom(options, config) {
9162
9149
  }
9163
9150
  context.undoStack.length = stackSizeBefore;
9164
9151
  }
9165
- function updateRoot(nodes) {
9166
- if (nodes.size === 0) {
9167
- throw new Error("Internal error: cannot load storage without items");
9168
- }
9152
+ function updateRoot(items) {
9169
9153
  if (context.root === void 0) {
9170
9154
  return;
9171
9155
  }
@@ -9173,26 +9157,22 @@ function createRoom(options, config) {
9173
9157
  for (const [id, node] of context.pool.nodes) {
9174
9158
  currentItems.set(id, node._serialize());
9175
9159
  }
9176
- const ops = getTreesDiffOperations(currentItems, nodes);
9177
- const result = applyOps(
9178
- ops,
9179
- /* isLocal */
9180
- false
9181
- );
9160
+ const ops = getTreesDiffOperations(currentItems, new Map(items));
9161
+ const result = applyRemoteOps(ops);
9182
9162
  notify(result.updates);
9183
9163
  }
9184
- function _addToRealUndoStack(historyOps) {
9164
+ function _addToRealUndoStack(frames) {
9185
9165
  if (context.undoStack.length >= 50) {
9186
9166
  context.undoStack.shift();
9187
9167
  }
9188
- context.undoStack.push(historyOps);
9168
+ context.undoStack.push(frames);
9189
9169
  onHistoryChange();
9190
9170
  }
9191
- function addToUndoStack(historyOps) {
9171
+ function addToUndoStack(frames) {
9192
9172
  if (context.pausedHistory !== null) {
9193
- context.pausedHistory.pushLeft(historyOps);
9173
+ context.pausedHistory.pushLeft(frames);
9194
9174
  } else {
9195
- _addToRealUndoStack(historyOps);
9175
+ _addToRealUndoStack(frames);
9196
9176
  }
9197
9177
  }
9198
9178
  function notify(updates) {
@@ -9223,69 +9203,85 @@ function createRoom(options, config) {
9223
9203
  "Internal. Tried to get connection id but connection was never open"
9224
9204
  );
9225
9205
  }
9226
- function applyOps(rawOps, isLocal) {
9206
+ function applyLocalOps(frames) {
9207
+ const [pframes, ops] = partition(
9208
+ frames,
9209
+ (f) => f.type === "presence"
9210
+ );
9211
+ const opsWithOpIds = ops.map(
9212
+ (op) => op.opId === void 0 ? { ...op, opId: context.pool.generateOpId() } : op
9213
+ );
9214
+ const { reverse, updates } = applyOps(
9215
+ pframes,
9216
+ opsWithOpIds,
9217
+ /* isLocal */
9218
+ true
9219
+ );
9220
+ return { opsToEmit: opsWithOpIds, reverse, updates };
9221
+ }
9222
+ function applyRemoteOps(ops) {
9223
+ return applyOps(
9224
+ [],
9225
+ ops,
9226
+ /* isLocal */
9227
+ false
9228
+ );
9229
+ }
9230
+ function applyOps(pframes, ops, isLocal) {
9227
9231
  const output = {
9228
9232
  reverse: new Deque(),
9229
9233
  storageUpdates: /* @__PURE__ */ new Map(),
9230
9234
  presence: false
9231
9235
  };
9232
- const createdNodeIds = /* @__PURE__ */ new Set();
9233
- const ops = rawOps.map((op) => {
9234
- if (op.type !== "presence" && !op.opId) {
9235
- return { ...op, opId: context.pool.generateOpId() };
9236
+ for (const pf of pframes) {
9237
+ const reverse = {
9238
+ type: "presence",
9239
+ data: {}
9240
+ };
9241
+ for (const key in pf.data) {
9242
+ reverse.data[key] = context.myPresence.get()[key];
9243
+ }
9244
+ context.myPresence.patch(pf.data);
9245
+ if (context.buffer.presenceUpdates === null) {
9246
+ context.buffer.presenceUpdates = { type: "partial", data: pf.data };
9236
9247
  } else {
9237
- return op;
9248
+ for (const key in pf.data) {
9249
+ context.buffer.presenceUpdates.data[key] = pf.data[key];
9250
+ }
9238
9251
  }
9239
- });
9252
+ output.reverse.pushLeft(reverse);
9253
+ output.presence = true;
9254
+ }
9255
+ const createdNodeIds = /* @__PURE__ */ new Set();
9240
9256
  for (const op of ops) {
9241
- if (op.type === "presence") {
9242
- const reverse = {
9243
- type: "presence",
9244
- data: {}
9245
- };
9246
- for (const key in op.data) {
9247
- reverse.data[key] = context.myPresence.get()[key];
9248
- }
9249
- context.myPresence.patch(op.data);
9250
- if (context.buffer.presenceUpdates === null) {
9251
- context.buffer.presenceUpdates = { type: "partial", data: op.data };
9252
- } else {
9253
- for (const key in op.data) {
9254
- context.buffer.presenceUpdates.data[key] = op.data[key];
9255
- }
9256
- }
9257
- output.reverse.pushLeft(reverse);
9258
- output.presence = true;
9257
+ let source;
9258
+ if (isLocal) {
9259
+ source = 0 /* LOCAL */;
9260
+ } else if (op.opId !== void 0) {
9261
+ context.unacknowledgedOps.delete(op.opId);
9262
+ source = 2 /* OURS */;
9259
9263
  } else {
9260
- let source;
9261
- if (isLocal) {
9262
- source = 0 /* LOCAL */;
9263
- } else {
9264
- const opId = nn(op.opId);
9265
- const deleted = context.unacknowledgedOps.delete(opId);
9266
- source = deleted ? 2 /* OURS */ : 1 /* THEIRS */;
9264
+ source = 1 /* THEIRS */;
9265
+ }
9266
+ const applyOpResult = applyOp(op, source);
9267
+ if (applyOpResult.modified) {
9268
+ const nodeId = applyOpResult.modified.node._id;
9269
+ if (!(nodeId && createdNodeIds.has(nodeId))) {
9270
+ output.storageUpdates.set(
9271
+ nn(applyOpResult.modified.node._id),
9272
+ mergeStorageUpdates(
9273
+ output.storageUpdates.get(nn(applyOpResult.modified.node._id)),
9274
+ applyOpResult.modified
9275
+ )
9276
+ );
9277
+ output.reverse.pushLeft(applyOpResult.reverse);
9267
9278
  }
9268
- const applyOpResult = applyOp(op, source);
9269
- if (applyOpResult.modified) {
9270
- const nodeId = applyOpResult.modified.node._id;
9271
- if (!(nodeId && createdNodeIds.has(nodeId))) {
9272
- output.storageUpdates.set(
9273
- nn(applyOpResult.modified.node._id),
9274
- mergeStorageUpdates(
9275
- output.storageUpdates.get(nn(applyOpResult.modified.node._id)),
9276
- applyOpResult.modified
9277
- )
9278
- );
9279
- output.reverse.pushLeft(applyOpResult.reverse);
9280
- }
9281
- if (op.type === OpCode.CREATE_LIST || op.type === OpCode.CREATE_MAP || op.type === OpCode.CREATE_OBJECT) {
9282
- createdNodeIds.add(nn(op.id));
9283
- }
9279
+ if (op.type === OpCode.CREATE_LIST || op.type === OpCode.CREATE_MAP || op.type === OpCode.CREATE_OBJECT) {
9280
+ createdNodeIds.add(op.id);
9284
9281
  }
9285
9282
  }
9286
9283
  }
9287
9284
  return {
9288
- ops,
9289
9285
  reverse: Array.from(output.reverse),
9290
9286
  updates: {
9291
9287
  storageUpdates: output.storageUpdates,
@@ -9354,7 +9350,7 @@ function createRoom(options, config) {
9354
9350
  }
9355
9351
  context.myPresence.patch(patch);
9356
9352
  if (context.activeBatch) {
9357
- if (_optionalChain([options2, 'optionalAccess', _199 => _199.addToHistory])) {
9353
+ if (_optionalChain([options2, 'optionalAccess', _191 => _191.addToHistory])) {
9358
9354
  context.activeBatch.reverseOps.pushLeft({
9359
9355
  type: "presence",
9360
9356
  data: oldValues
@@ -9363,7 +9359,7 @@ function createRoom(options, config) {
9363
9359
  context.activeBatch.updates.presence = true;
9364
9360
  } else {
9365
9361
  flushNowOrSoon();
9366
- if (_optionalChain([options2, 'optionalAccess', _200 => _200.addToHistory])) {
9362
+ if (_optionalChain([options2, 'optionalAccess', _192 => _192.addToHistory])) {
9367
9363
  addToUndoStack([{ type: "presence", data: oldValues }]);
9368
9364
  }
9369
9365
  notify({ presence: true });
@@ -9470,20 +9466,16 @@ function createRoom(options, config) {
9470
9466
  return compact([parseServerMessage(data)]);
9471
9467
  }
9472
9468
  }
9473
- function applyAndSendOps(offlineOps) {
9474
- if (offlineOps.size === 0) {
9469
+ function applyAndSendOfflineOps(unackedOps) {
9470
+ if (unackedOps.size === 0) {
9475
9471
  return;
9476
9472
  }
9477
9473
  const messages = [];
9478
- const inOps = Array.from(offlineOps.values());
9479
- const result = applyOps(
9480
- inOps,
9481
- /* isLocal */
9482
- true
9483
- );
9474
+ const inOps = Array.from(unackedOps.values());
9475
+ const result = applyLocalOps(inOps);
9484
9476
  messages.push({
9485
9477
  type: ClientMsgCode.UPDATE_STORAGE,
9486
- ops: result.ops
9478
+ ops: result.opsToEmit
9487
9479
  });
9488
9480
  notify(result.updates);
9489
9481
  sendMessages(messages);
@@ -9540,19 +9532,12 @@ function createRoom(options, config) {
9540
9532
  updates.others.push(onRoomStateMessage(message));
9541
9533
  break;
9542
9534
  }
9543
- case ServerMsgCode.STORAGE_CHUNK: {
9544
- partialNodes.append(compactNodesToNodeStream(message.nodes));
9545
- if (message.done) {
9546
- processInitialStorage(partialNodes.clear());
9547
- }
9535
+ case ServerMsgCode.STORAGE_STATE: {
9536
+ processInitialStorage(message);
9548
9537
  break;
9549
9538
  }
9550
9539
  case ServerMsgCode.UPDATE_STORAGE: {
9551
- const applyResult = applyOps(
9552
- message.ops,
9553
- /* isLocal */
9554
- false
9555
- );
9540
+ const applyResult = applyRemoteOps(message.ops);
9556
9541
  for (const [key, value] of applyResult.updates.storageUpdates) {
9557
9542
  updates.storageUpdates.set(
9558
9543
  key,
@@ -9585,12 +9570,11 @@ function createRoom(options, config) {
9585
9570
  case ServerMsgCode.COMMENT_REACTION_REMOVED:
9586
9571
  case ServerMsgCode.COMMENT_CREATED:
9587
9572
  case ServerMsgCode.COMMENT_EDITED:
9588
- case ServerMsgCode.COMMENT_DELETED: {
9573
+ case ServerMsgCode.COMMENT_DELETED:
9574
+ case ServerMsgCode.COMMENT_METADATA_UPDATED: {
9589
9575
  eventHub.comments.notify(message);
9590
9576
  break;
9591
9577
  }
9592
- case ServerMsgCode.STORAGE_STATE_V7:
9593
- // No longer used in V8
9594
9578
  default:
9595
9579
  break;
9596
9580
  }
@@ -9601,7 +9585,7 @@ function createRoom(options, config) {
9601
9585
  const storageOps = context.buffer.storageOperations;
9602
9586
  if (storageOps.length > 0) {
9603
9587
  for (const op of storageOps) {
9604
- context.unacknowledgedOps.set(nn(op.opId), op);
9588
+ context.unacknowledgedOps.set(op.opId, op);
9605
9589
  }
9606
9590
  notifyStorageStatus();
9607
9591
  }
@@ -9692,18 +9676,18 @@ function createRoom(options, config) {
9692
9676
  }
9693
9677
  let _getStorage$ = null;
9694
9678
  let _resolveStoragePromise = null;
9695
- function processInitialStorage(nodes) {
9679
+ function processInitialStorage(message) {
9696
9680
  const unacknowledgedOps = new Map(context.unacknowledgedOps);
9697
- createOrUpdateRootFromMessage(nodes);
9698
- applyAndSendOps(unacknowledgedOps);
9699
- _optionalChain([_resolveStoragePromise, 'optionalCall', _201 => _201()]);
9681
+ createOrUpdateRootFromMessage(message);
9682
+ applyAndSendOfflineOps(unacknowledgedOps);
9683
+ _optionalChain([_resolveStoragePromise, 'optionalCall', _193 => _193()]);
9700
9684
  notifyStorageStatus();
9701
9685
  eventHub.storageDidLoad.notify();
9702
9686
  }
9703
9687
  async function streamStorage() {
9704
9688
  if (!managedSocket.authValue) return;
9705
- const nodes = new Map(await httpClient.streamStorage({ roomId }));
9706
- processInitialStorage(nodes);
9689
+ const items = await httpClient.streamStorage({ roomId });
9690
+ processInitialStorage({ type: ServerMsgCode.STORAGE_STATE, items });
9707
9691
  }
9708
9692
  function refreshStorage(options2) {
9709
9693
  const messages = context.buffer.messages;
@@ -9711,7 +9695,6 @@ function createRoom(options, config) {
9711
9695
  void streamStorage();
9712
9696
  } else if (!messages.some((msg) => msg.type === ClientMsgCode.FETCH_STORAGE)) {
9713
9697
  messages.push({ type: ClientMsgCode.FETCH_STORAGE });
9714
- partialNodes.clear();
9715
9698
  }
9716
9699
  if (options2.flush) {
9717
9700
  flushNowOrSoon();
@@ -9764,23 +9747,17 @@ function createRoom(options, config) {
9764
9747
  if (context.activeBatch) {
9765
9748
  throw new Error("undo is not allowed during a batch");
9766
9749
  }
9767
- const historyOps = context.undoStack.pop();
9768
- if (historyOps === void 0) {
9750
+ const frames = context.undoStack.pop();
9751
+ if (frames === void 0) {
9769
9752
  return;
9770
9753
  }
9771
9754
  context.pausedHistory = null;
9772
- const result = applyOps(
9773
- historyOps,
9774
- /* isLocal */
9775
- true
9776
- );
9755
+ const result = applyLocalOps(frames);
9777
9756
  notify(result.updates);
9778
9757
  context.redoStack.push(result.reverse);
9779
9758
  onHistoryChange();
9780
- for (const op of result.ops) {
9781
- if (op.type !== "presence") {
9782
- context.buffer.storageOperations.push(op);
9783
- }
9759
+ for (const op of result.opsToEmit) {
9760
+ context.buffer.storageOperations.push(op);
9784
9761
  }
9785
9762
  flushNowOrSoon();
9786
9763
  }
@@ -9788,23 +9765,17 @@ function createRoom(options, config) {
9788
9765
  if (context.activeBatch) {
9789
9766
  throw new Error("redo is not allowed during a batch");
9790
9767
  }
9791
- const historyOps = context.redoStack.pop();
9792
- if (historyOps === void 0) {
9768
+ const frames = context.redoStack.pop();
9769
+ if (frames === void 0) {
9793
9770
  return;
9794
9771
  }
9795
9772
  context.pausedHistory = null;
9796
- const result = applyOps(
9797
- historyOps,
9798
- /* isLocal */
9799
- true
9800
- );
9773
+ const result = applyLocalOps(frames);
9801
9774
  notify(result.updates);
9802
9775
  context.undoStack.push(result.reverse);
9803
9776
  onHistoryChange();
9804
- for (const op of result.ops) {
9805
- if (op.type !== "presence") {
9806
- context.buffer.storageOperations.push(op);
9807
- }
9777
+ for (const op of result.opsToEmit) {
9778
+ context.buffer.storageOperations.push(op);
9808
9779
  }
9809
9780
  flushNowOrSoon();
9810
9781
  }
@@ -9851,10 +9822,10 @@ function createRoom(options, config) {
9851
9822
  }
9852
9823
  }
9853
9824
  function resumeHistory() {
9854
- const historyOps = context.pausedHistory;
9825
+ const frames = context.pausedHistory;
9855
9826
  context.pausedHistory = null;
9856
- if (historyOps !== null && historyOps.length > 0) {
9857
- _addToRealUndoStack(Array.from(historyOps));
9827
+ if (frames !== null && frames.length > 0) {
9828
+ _addToRealUndoStack(Array.from(frames));
9858
9829
  }
9859
9830
  }
9860
9831
  const syncSourceForStorage = config.createSyncSource();
@@ -9926,8 +9897,8 @@ function createRoom(options, config) {
9926
9897
  async function getThreads(options2) {
9927
9898
  return httpClient.getThreads({
9928
9899
  roomId,
9929
- query: _optionalChain([options2, 'optionalAccess', _202 => _202.query]),
9930
- cursor: _optionalChain([options2, 'optionalAccess', _203 => _203.cursor])
9900
+ query: _optionalChain([options2, 'optionalAccess', _194 => _194.query]),
9901
+ cursor: _optionalChain([options2, 'optionalAccess', _195 => _195.cursor])
9931
9902
  });
9932
9903
  }
9933
9904
  async function getThread(threadId) {
@@ -9940,6 +9911,7 @@ function createRoom(options, config) {
9940
9911
  commentId: options2.commentId,
9941
9912
  metadata: options2.metadata,
9942
9913
  body: options2.body,
9914
+ commentMetadata: options2.commentMetadata,
9943
9915
  attachmentIds: options2.attachmentIds
9944
9916
  });
9945
9917
  }
@@ -9952,6 +9924,18 @@ function createRoom(options, config) {
9952
9924
  }) {
9953
9925
  return httpClient.editThreadMetadata({ roomId, threadId, metadata });
9954
9926
  }
9927
+ async function editCommentMetadata({
9928
+ threadId,
9929
+ commentId,
9930
+ metadata
9931
+ }) {
9932
+ return httpClient.editCommentMetadata({
9933
+ roomId,
9934
+ threadId,
9935
+ commentId,
9936
+ metadata
9937
+ });
9938
+ }
9955
9939
  async function markThreadAsResolved(threadId) {
9956
9940
  return httpClient.markThreadAsResolved({ roomId, threadId });
9957
9941
  }
@@ -9973,6 +9957,7 @@ function createRoom(options, config) {
9973
9957
  threadId: options2.threadId,
9974
9958
  commentId: options2.commentId,
9975
9959
  body: options2.body,
9960
+ metadata: options2.metadata,
9976
9961
  attachmentIds: options2.attachmentIds
9977
9962
  });
9978
9963
  }
@@ -9982,6 +9967,7 @@ function createRoom(options, config) {
9982
9967
  threadId: options2.threadId,
9983
9968
  commentId: options2.commentId,
9984
9969
  body: options2.body,
9970
+ metadata: options2.metadata,
9985
9971
  attachmentIds: options2.attachmentIds
9986
9972
  });
9987
9973
  }
@@ -10034,7 +10020,7 @@ function createRoom(options, config) {
10034
10020
  function getSubscriptionSettings(options2) {
10035
10021
  return httpClient.getSubscriptionSettings({
10036
10022
  roomId,
10037
- signal: _optionalChain([options2, 'optionalAccess', _204 => _204.signal])
10023
+ signal: _optionalChain([options2, 'optionalAccess', _196 => _196.signal])
10038
10024
  });
10039
10025
  }
10040
10026
  function updateSubscriptionSettings(settings) {
@@ -10056,7 +10042,7 @@ function createRoom(options, config) {
10056
10042
  {
10057
10043
  [kInternal]: {
10058
10044
  get presenceBuffer() {
10059
- return deepClone(_nullishCoalesce(_optionalChain([context, 'access', _205 => _205.buffer, 'access', _206 => _206.presenceUpdates, 'optionalAccess', _207 => _207.data]), () => ( null)));
10045
+ return deepClone(_nullishCoalesce(_optionalChain([context, 'access', _197 => _197.buffer, 'access', _198 => _198.presenceUpdates, 'optionalAccess', _199 => _199.data]), () => ( null)));
10060
10046
  },
10061
10047
  // prettier-ignore
10062
10048
  get undoStack() {
@@ -10071,9 +10057,9 @@ function createRoom(options, config) {
10071
10057
  return context.yjsProvider;
10072
10058
  },
10073
10059
  setYjsProvider(newProvider) {
10074
- _optionalChain([context, 'access', _208 => _208.yjsProvider, 'optionalAccess', _209 => _209.off, 'call', _210 => _210("status", yjsStatusDidChange)]);
10060
+ _optionalChain([context, 'access', _200 => _200.yjsProvider, 'optionalAccess', _201 => _201.off, 'call', _202 => _202("status", yjsStatusDidChange)]);
10075
10061
  context.yjsProvider = newProvider;
10076
- _optionalChain([newProvider, 'optionalAccess', _211 => _211.on, 'call', _212 => _212("status", yjsStatusDidChange)]);
10062
+ _optionalChain([newProvider, 'optionalAccess', _203 => _203.on, 'call', _204 => _204("status", yjsStatusDidChange)]);
10077
10063
  context.yjsProviderDidChange.notify();
10078
10064
  },
10079
10065
  yjsProviderDidChange: context.yjsProviderDidChange.observable,
@@ -10119,7 +10105,7 @@ function createRoom(options, config) {
10119
10105
  source.dispose();
10120
10106
  }
10121
10107
  eventHub.roomWillDestroy.notify();
10122
- _optionalChain([context, 'access', _213 => _213.yjsProvider, 'optionalAccess', _214 => _214.off, 'call', _215 => _215("status", yjsStatusDidChange)]);
10108
+ _optionalChain([context, 'access', _205 => _205.yjsProvider, 'optionalAccess', _206 => _206.off, 'call', _207 => _207("status", yjsStatusDidChange)]);
10123
10109
  syncSourceForStorage.destroy();
10124
10110
  syncSourceForYjs.destroy();
10125
10111
  uninstallBgTabSpy();
@@ -10169,6 +10155,7 @@ function createRoom(options, config) {
10169
10155
  unsubscribeFromThread,
10170
10156
  createComment,
10171
10157
  editComment,
10158
+ editCommentMetadata,
10172
10159
  deleteComment,
10173
10160
  addReaction,
10174
10161
  removeReaction,
@@ -10269,7 +10256,7 @@ function makeClassicSubscribeFn(roomId, events, errorEvents) {
10269
10256
  }
10270
10257
  if (isLiveNode(first)) {
10271
10258
  const node = first;
10272
- if (_optionalChain([options, 'optionalAccess', _216 => _216.isDeep])) {
10259
+ if (_optionalChain([options, 'optionalAccess', _208 => _208.isDeep])) {
10273
10260
  const storageCallback = second;
10274
10261
  return subscribeToLiveStructureDeeply(node, storageCallback);
10275
10262
  } else {
@@ -10301,7 +10288,7 @@ function makeCreateSocketDelegateForRoom(roomId, baseUrl, WebSocketPolyfill, eng
10301
10288
  }
10302
10289
  const url2 = new URL(baseUrl);
10303
10290
  url2.protocol = url2.protocol === "http:" ? "ws" : "wss";
10304
- url2.pathname = "/v8";
10291
+ url2.pathname = "/v7";
10305
10292
  url2.searchParams.set("roomId", roomId);
10306
10293
  if (authValue.type === "secret") {
10307
10294
  url2.searchParams.set("tok", authValue.token.raw);
@@ -10352,8 +10339,8 @@ function createClient(options) {
10352
10339
  const userId = token.k === "sec-legacy" /* SECRET_LEGACY */ ? token.id : token.uid;
10353
10340
  currentUserId.set(() => userId);
10354
10341
  });
10355
- const fetchPolyfill = _optionalChain([clientOptions, 'access', _217 => _217.polyfills, 'optionalAccess', _218 => _218.fetch]) || /* istanbul ignore next */
10356
- _optionalChain([globalThis, 'access', _219 => _219.fetch, 'optionalAccess', _220 => _220.bind, 'call', _221 => _221(globalThis)]);
10342
+ const fetchPolyfill = _optionalChain([clientOptions, 'access', _209 => _209.polyfills, 'optionalAccess', _210 => _210.fetch]) || /* istanbul ignore next */
10343
+ _optionalChain([globalThis, 'access', _211 => _211.fetch, 'optionalAccess', _212 => _212.bind, 'call', _213 => _213(globalThis)]);
10357
10344
  const httpClient = createApiClient({
10358
10345
  baseUrl,
10359
10346
  fetchPolyfill,
@@ -10371,7 +10358,7 @@ function createClient(options) {
10371
10358
  delegates: {
10372
10359
  createSocket: makeCreateSocketDelegateForAi(
10373
10360
  baseUrl,
10374
- _optionalChain([clientOptions, 'access', _222 => _222.polyfills, 'optionalAccess', _223 => _223.WebSocket])
10361
+ _optionalChain([clientOptions, 'access', _214 => _214.polyfills, 'optionalAccess', _215 => _215.WebSocket])
10375
10362
  ),
10376
10363
  authenticate: async () => {
10377
10364
  const resp = await authManager.getAuthValue({
@@ -10433,7 +10420,7 @@ function createClient(options) {
10433
10420
  createSocket: makeCreateSocketDelegateForRoom(
10434
10421
  roomId,
10435
10422
  baseUrl,
10436
- _optionalChain([clientOptions, 'access', _224 => _224.polyfills, 'optionalAccess', _225 => _225.WebSocket]),
10423
+ _optionalChain([clientOptions, 'access', _216 => _216.polyfills, 'optionalAccess', _217 => _217.WebSocket]),
10437
10424
  options2.engine
10438
10425
  ),
10439
10426
  authenticate: makeAuthDelegateForRoom(roomId, authManager)
@@ -10458,7 +10445,7 @@ function createClient(options) {
10458
10445
  const shouldConnect = _nullishCoalesce(options2.autoConnect, () => ( true));
10459
10446
  if (shouldConnect) {
10460
10447
  if (typeof atob === "undefined") {
10461
- if (_optionalChain([clientOptions, 'access', _226 => _226.polyfills, 'optionalAccess', _227 => _227.atob]) === void 0) {
10448
+ if (_optionalChain([clientOptions, 'access', _218 => _218.polyfills, 'optionalAccess', _219 => _219.atob]) === void 0) {
10462
10449
  throw new Error(
10463
10450
  "You need to polyfill atob to use the client in your environment. Please follow the instructions at https://liveblocks.io/docs/errors/liveblocks-client/atob-polyfill"
10464
10451
  );
@@ -10470,7 +10457,7 @@ function createClient(options) {
10470
10457
  return leaseRoom(newRoomDetails);
10471
10458
  }
10472
10459
  function getRoom(roomId) {
10473
- const room = _optionalChain([roomsById, 'access', _228 => _228.get, 'call', _229 => _229(roomId), 'optionalAccess', _230 => _230.room]);
10460
+ const room = _optionalChain([roomsById, 'access', _220 => _220.get, 'call', _221 => _221(roomId), 'optionalAccess', _222 => _222.room]);
10474
10461
  return room ? room : null;
10475
10462
  }
10476
10463
  function logout() {
@@ -10486,7 +10473,7 @@ function createClient(options) {
10486
10473
  const batchedResolveUsers = new Batch(
10487
10474
  async (batchedUserIds) => {
10488
10475
  const userIds = batchedUserIds.flat();
10489
- const users = await _optionalChain([resolveUsers, 'optionalCall', _231 => _231({ userIds })]);
10476
+ const users = await _optionalChain([resolveUsers, 'optionalCall', _223 => _223({ userIds })]);
10490
10477
  warnOnceIf(
10491
10478
  !resolveUsers,
10492
10479
  "Set the resolveUsers option in createClient to specify user info."
@@ -10503,7 +10490,7 @@ function createClient(options) {
10503
10490
  const batchedResolveRoomsInfo = new Batch(
10504
10491
  async (batchedRoomIds) => {
10505
10492
  const roomIds = batchedRoomIds.flat();
10506
- const roomsInfo = await _optionalChain([resolveRoomsInfo, 'optionalCall', _232 => _232({ roomIds })]);
10493
+ const roomsInfo = await _optionalChain([resolveRoomsInfo, 'optionalCall', _224 => _224({ roomIds })]);
10507
10494
  warnOnceIf(
10508
10495
  !resolveRoomsInfo,
10509
10496
  "Set the resolveRoomsInfo option in createClient to specify room info."
@@ -10520,7 +10507,7 @@ function createClient(options) {
10520
10507
  const batchedResolveGroupsInfo = new Batch(
10521
10508
  async (batchedGroupIds) => {
10522
10509
  const groupIds = batchedGroupIds.flat();
10523
- const groupsInfo = await _optionalChain([resolveGroupsInfo, 'optionalCall', _233 => _233({ groupIds })]);
10510
+ const groupsInfo = await _optionalChain([resolveGroupsInfo, 'optionalCall', _225 => _225({ groupIds })]);
10524
10511
  warnOnceIf(
10525
10512
  !resolveGroupsInfo,
10526
10513
  "Set the resolveGroupsInfo option in createClient to specify group info."
@@ -10576,7 +10563,7 @@ function createClient(options) {
10576
10563
  }
10577
10564
  };
10578
10565
  const win = typeof window !== "undefined" ? window : void 0;
10579
- _optionalChain([win, 'optionalAccess', _234 => _234.addEventListener, 'call', _235 => _235("beforeunload", maybePreventClose)]);
10566
+ _optionalChain([win, 'optionalAccess', _226 => _226.addEventListener, 'call', _227 => _227("beforeunload", maybePreventClose)]);
10580
10567
  }
10581
10568
  async function getNotificationSettings(options2) {
10582
10569
  const plainSettings = await httpClient.getNotificationSettings(options2);
@@ -10703,7 +10690,7 @@ var commentBodyElementsTypes = {
10703
10690
  mention: "inline"
10704
10691
  };
10705
10692
  function traverseCommentBody(body, elementOrVisitor, possiblyVisitor) {
10706
- if (!body || !_optionalChain([body, 'optionalAccess', _236 => _236.content])) {
10693
+ if (!body || !_optionalChain([body, 'optionalAccess', _228 => _228.content])) {
10707
10694
  return;
10708
10695
  }
10709
10696
  const element = typeof elementOrVisitor === "string" ? elementOrVisitor : void 0;
@@ -10713,13 +10700,13 @@ function traverseCommentBody(body, elementOrVisitor, possiblyVisitor) {
10713
10700
  for (const block of body.content) {
10714
10701
  if (type === "all" || type === "block") {
10715
10702
  if (guard(block)) {
10716
- _optionalChain([visitor, 'optionalCall', _237 => _237(block)]);
10703
+ _optionalChain([visitor, 'optionalCall', _229 => _229(block)]);
10717
10704
  }
10718
10705
  }
10719
10706
  if (type === "all" || type === "inline") {
10720
10707
  for (const inline of block.children) {
10721
10708
  if (guard(inline)) {
10722
- _optionalChain([visitor, 'optionalCall', _238 => _238(inline)]);
10709
+ _optionalChain([visitor, 'optionalCall', _230 => _230(inline)]);
10723
10710
  }
10724
10711
  }
10725
10712
  }
@@ -10889,7 +10876,7 @@ var stringifyCommentBodyPlainElements = {
10889
10876
  text: ({ element }) => element.text,
10890
10877
  link: ({ element }) => _nullishCoalesce(element.text, () => ( element.url)),
10891
10878
  mention: ({ element, user, group }) => {
10892
- return `@${_nullishCoalesce(_nullishCoalesce(_optionalChain([user, 'optionalAccess', _239 => _239.name]), () => ( _optionalChain([group, 'optionalAccess', _240 => _240.name]))), () => ( element.id))}`;
10879
+ return `@${_nullishCoalesce(_nullishCoalesce(_optionalChain([user, 'optionalAccess', _231 => _231.name]), () => ( _optionalChain([group, 'optionalAccess', _232 => _232.name]))), () => ( element.id))}`;
10893
10880
  }
10894
10881
  };
10895
10882
  var stringifyCommentBodyHtmlElements = {
@@ -10919,7 +10906,7 @@ var stringifyCommentBodyHtmlElements = {
10919
10906
  return html`<a href="${href}" target="_blank" rel="noopener noreferrer">${element.text ? html`${element.text}` : element.url}</a>`;
10920
10907
  },
10921
10908
  mention: ({ element, user, group }) => {
10922
- return html`<span data-mention>@${_optionalChain([user, 'optionalAccess', _241 => _241.name]) ? html`${_optionalChain([user, 'optionalAccess', _242 => _242.name])}` : _optionalChain([group, 'optionalAccess', _243 => _243.name]) ? html`${_optionalChain([group, 'optionalAccess', _244 => _244.name])}` : element.id}</span>`;
10909
+ return html`<span data-mention>@${_optionalChain([user, 'optionalAccess', _233 => _233.name]) ? html`${_optionalChain([user, 'optionalAccess', _234 => _234.name])}` : _optionalChain([group, 'optionalAccess', _235 => _235.name]) ? html`${_optionalChain([group, 'optionalAccess', _236 => _236.name])}` : element.id}</span>`;
10923
10910
  }
10924
10911
  };
10925
10912
  var stringifyCommentBodyMarkdownElements = {
@@ -10949,20 +10936,20 @@ var stringifyCommentBodyMarkdownElements = {
10949
10936
  return markdown`[${_nullishCoalesce(element.text, () => ( element.url))}](${href})`;
10950
10937
  },
10951
10938
  mention: ({ element, user, group }) => {
10952
- return markdown`@${_nullishCoalesce(_nullishCoalesce(_optionalChain([user, 'optionalAccess', _245 => _245.name]), () => ( _optionalChain([group, 'optionalAccess', _246 => _246.name]))), () => ( element.id))}`;
10939
+ return markdown`@${_nullishCoalesce(_nullishCoalesce(_optionalChain([user, 'optionalAccess', _237 => _237.name]), () => ( _optionalChain([group, 'optionalAccess', _238 => _238.name]))), () => ( element.id))}`;
10953
10940
  }
10954
10941
  };
10955
10942
  async function stringifyCommentBody(body, options) {
10956
- const format = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _247 => _247.format]), () => ( "plain"));
10957
- const separator = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _248 => _248.separator]), () => ( (format === "markdown" ? "\n\n" : "\n")));
10943
+ const format = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _239 => _239.format]), () => ( "plain"));
10944
+ const separator = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _240 => _240.separator]), () => ( (format === "markdown" ? "\n\n" : "\n")));
10958
10945
  const elements = {
10959
10946
  ...format === "html" ? stringifyCommentBodyHtmlElements : format === "markdown" ? stringifyCommentBodyMarkdownElements : stringifyCommentBodyPlainElements,
10960
- ..._optionalChain([options, 'optionalAccess', _249 => _249.elements])
10947
+ ..._optionalChain([options, 'optionalAccess', _241 => _241.elements])
10961
10948
  };
10962
10949
  const { users: resolvedUsers, groups: resolvedGroupsInfo } = await resolveMentionsInCommentBody(
10963
10950
  body,
10964
- _optionalChain([options, 'optionalAccess', _250 => _250.resolveUsers]),
10965
- _optionalChain([options, 'optionalAccess', _251 => _251.resolveGroupsInfo])
10951
+ _optionalChain([options, 'optionalAccess', _242 => _242.resolveUsers]),
10952
+ _optionalChain([options, 'optionalAccess', _243 => _243.resolveGroupsInfo])
10966
10953
  );
10967
10954
  const blocks = body.content.flatMap((block, blockIndex) => {
10968
10955
  switch (block.type) {
@@ -11249,12 +11236,12 @@ function legacy_patchImmutableNode(state, path, update) {
11249
11236
  }
11250
11237
  const newState = Object.assign({}, state);
11251
11238
  for (const key in update.updates) {
11252
- if (_optionalChain([update, 'access', _252 => _252.updates, 'access', _253 => _253[key], 'optionalAccess', _254 => _254.type]) === "update") {
11239
+ if (_optionalChain([update, 'access', _244 => _244.updates, 'access', _245 => _245[key], 'optionalAccess', _246 => _246.type]) === "update") {
11253
11240
  const val = update.node.get(key);
11254
11241
  if (val !== void 0) {
11255
11242
  newState[key] = lsonToJson(val);
11256
11243
  }
11257
- } else if (_optionalChain([update, 'access', _255 => _255.updates, 'access', _256 => _256[key], 'optionalAccess', _257 => _257.type]) === "delete") {
11244
+ } else if (_optionalChain([update, 'access', _247 => _247.updates, 'access', _248 => _248[key], 'optionalAccess', _249 => _249.type]) === "delete") {
11258
11245
  delete newState[key];
11259
11246
  }
11260
11247
  }
@@ -11315,12 +11302,12 @@ function legacy_patchImmutableNode(state, path, update) {
11315
11302
  }
11316
11303
  const newState = Object.assign({}, state);
11317
11304
  for (const key in update.updates) {
11318
- if (_optionalChain([update, 'access', _258 => _258.updates, 'access', _259 => _259[key], 'optionalAccess', _260 => _260.type]) === "update") {
11305
+ if (_optionalChain([update, 'access', _250 => _250.updates, 'access', _251 => _251[key], 'optionalAccess', _252 => _252.type]) === "update") {
11319
11306
  const value = update.node.get(key);
11320
11307
  if (value !== void 0) {
11321
11308
  newState[key] = lsonToJson(value);
11322
11309
  }
11323
- } else if (_optionalChain([update, 'access', _261 => _261.updates, 'access', _262 => _262[key], 'optionalAccess', _263 => _263.type]) === "delete") {
11310
+ } else if (_optionalChain([update, 'access', _253 => _253.updates, 'access', _254 => _254[key], 'optionalAccess', _255 => _255.type]) === "delete") {
11324
11311
  delete newState[key];
11325
11312
  }
11326
11313
  }
@@ -11400,9 +11387,9 @@ function makePoller(callback, intervalMs, options) {
11400
11387
  const startTime = performance.now();
11401
11388
  const doc = typeof document !== "undefined" ? document : void 0;
11402
11389
  const win = typeof window !== "undefined" ? window : void 0;
11403
- const maxStaleTimeMs = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _264 => _264.maxStaleTimeMs]), () => ( Number.POSITIVE_INFINITY));
11390
+ const maxStaleTimeMs = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _256 => _256.maxStaleTimeMs]), () => ( Number.POSITIVE_INFINITY));
11404
11391
  const context = {
11405
- inForeground: _optionalChain([doc, 'optionalAccess', _265 => _265.visibilityState]) !== "hidden",
11392
+ inForeground: _optionalChain([doc, 'optionalAccess', _257 => _257.visibilityState]) !== "hidden",
11406
11393
  lastSuccessfulPollAt: startTime,
11407
11394
  count: 0,
11408
11395
  backoff: 0
@@ -11483,11 +11470,11 @@ function makePoller(callback, intervalMs, options) {
11483
11470
  pollNowIfStale();
11484
11471
  }
11485
11472
  function onVisibilityChange() {
11486
- setInForeground(_optionalChain([doc, 'optionalAccess', _266 => _266.visibilityState]) !== "hidden");
11473
+ setInForeground(_optionalChain([doc, 'optionalAccess', _258 => _258.visibilityState]) !== "hidden");
11487
11474
  }
11488
- _optionalChain([doc, 'optionalAccess', _267 => _267.addEventListener, 'call', _268 => _268("visibilitychange", onVisibilityChange)]);
11489
- _optionalChain([win, 'optionalAccess', _269 => _269.addEventListener, 'call', _270 => _270("online", onVisibilityChange)]);
11490
- _optionalChain([win, 'optionalAccess', _271 => _271.addEventListener, 'call', _272 => _272("focus", pollNowIfStale)]);
11475
+ _optionalChain([doc, 'optionalAccess', _259 => _259.addEventListener, 'call', _260 => _260("visibilitychange", onVisibilityChange)]);
11476
+ _optionalChain([win, 'optionalAccess', _261 => _261.addEventListener, 'call', _262 => _262("online", onVisibilityChange)]);
11477
+ _optionalChain([win, 'optionalAccess', _263 => _263.addEventListener, 'call', _264 => _264("focus", pollNowIfStale)]);
11491
11478
  fsm.start();
11492
11479
  return {
11493
11480
  inc,
@@ -11619,6 +11606,5 @@ detectDupes(PKG_NAME, PKG_VERSION, PKG_FORMAT);
11619
11606
 
11620
11607
 
11621
11608
 
11622
-
11623
- exports.ClientMsgCode = ClientMsgCode; exports.CrdtType = CrdtType; exports.DefaultMap = DefaultMap; exports.Deque = Deque; exports.DerivedSignal = DerivedSignal; exports.HttpError = HttpError; exports.LiveList = LiveList; exports.LiveMap = LiveMap; exports.LiveObject = LiveObject; exports.LiveblocksError = LiveblocksError; exports.MENTION_CHARACTER = MENTION_CHARACTER; exports.MutableSignal = MutableSignal; exports.OpCode = OpCode; exports.Permission = Permission; exports.Promise_withResolvers = Promise_withResolvers; exports.ServerMsgCode = ServerMsgCode; exports.Signal = Signal; exports.SortedList = SortedList; exports.TextEditorType = TextEditorType; exports.WebsocketCloseCodes = WebsocketCloseCodes; exports.asPos = asPos; exports.assert = assert; exports.assertNever = assertNever; exports.autoRetry = autoRetry; exports.b64decode = b64decode; exports.batch = batch; exports.checkBounds = checkBounds; exports.chunk = chunk; exports.cloneLson = cloneLson; exports.compactObject = compactObject; exports.console = fancy_console_exports; exports.convertToCommentData = convertToCommentData; exports.convertToCommentUserReaction = convertToCommentUserReaction; exports.convertToGroupData = convertToGroupData; exports.convertToInboxNotificationData = convertToInboxNotificationData; exports.convertToSubscriptionData = convertToSubscriptionData; exports.convertToThreadData = convertToThreadData; exports.convertToUserSubscriptionData = convertToUserSubscriptionData; exports.createClient = createClient; exports.createCommentAttachmentId = createCommentAttachmentId; exports.createCommentId = createCommentId; exports.createInboxNotificationId = createInboxNotificationId; exports.createManagedPool = createManagedPool; exports.createNotificationSettings = createNotificationSettings; exports.createThreadId = createThreadId; exports.defineAiTool = defineAiTool; exports.deprecate = deprecate; exports.deprecateIf = deprecateIf; exports.detectDupes = detectDupes; exports.entries = entries; exports.errorIf = errorIf; exports.findLastIndex = findLastIndex; exports.freeze = freeze; exports.generateUrl = generateUrl; exports.getMentionsFromCommentBody = getMentionsFromCommentBody; exports.getSubscriptionKey = getSubscriptionKey; exports.html = html; exports.htmlSafe = htmlSafe; exports.isCommentBodyLink = isCommentBodyLink; exports.isCommentBodyMention = isCommentBodyMention; exports.isCommentBodyText = isCommentBodyText; exports.isJsonArray = isJsonArray; exports.isJsonObject = isJsonObject; exports.isJsonScalar = isJsonScalar; exports.isLiveNode = isLiveNode; exports.isNotificationChannelEnabled = isNotificationChannelEnabled; exports.isNumberOperator = isNumberOperator; exports.isPlainObject = isPlainObject; exports.isStartsWithOperator = isStartsWithOperator; exports.isUrl = isUrl; exports.kInternal = kInternal; exports.keys = keys; exports.legacy_patchImmutableObject = legacy_patchImmutableObject; exports.lsonToJson = lsonToJson; exports.makeAbortController = makeAbortController; exports.makeEventSource = makeEventSource; exports.makePoller = makePoller; exports.makePosition = makePosition; exports.mapValues = mapValues; exports.memoizeOnSuccess = memoizeOnSuccess; exports.nanoid = nanoid; exports.nn = nn; exports.nodeStreamToCompactNodes = nodeStreamToCompactNodes; exports.objectToQuery = objectToQuery; exports.patchLiveObjectKey = patchLiveObjectKey; exports.patchNotificationSettings = patchNotificationSettings; exports.raise = raise; exports.resolveMentionsInCommentBody = resolveMentionsInCommentBody; exports.sanitizeUrl = sanitizeUrl; exports.shallow = shallow; exports.shallow2 = shallow2; exports.stableStringify = stableStringify; exports.stringifyCommentBody = stringifyCommentBody; exports.throwUsageError = throwUsageError; exports.toPlainLson = toPlainLson; exports.tryParseJson = tryParseJson; exports.url = url; exports.urljoin = urljoin; exports.wait = wait; exports.warnOnce = warnOnce; exports.warnOnceIf = warnOnceIf; exports.withTimeout = withTimeout;
11609
+ exports.ClientMsgCode = ClientMsgCode; exports.CrdtType = CrdtType; exports.DefaultMap = DefaultMap; exports.Deque = Deque; exports.DerivedSignal = DerivedSignal; exports.HttpError = HttpError; exports.LiveList = LiveList; exports.LiveMap = LiveMap; exports.LiveObject = LiveObject; exports.LiveblocksError = LiveblocksError; exports.MENTION_CHARACTER = MENTION_CHARACTER; exports.MutableSignal = MutableSignal; exports.OpCode = OpCode; exports.Permission = Permission; exports.Promise_withResolvers = Promise_withResolvers; exports.ServerMsgCode = ServerMsgCode; exports.Signal = Signal; exports.SortedList = SortedList; exports.TextEditorType = TextEditorType; exports.WebsocketCloseCodes = WebsocketCloseCodes; exports.asPos = asPos; exports.assert = assert; exports.assertNever = assertNever; exports.autoRetry = autoRetry; exports.b64decode = b64decode; exports.batch = batch; exports.checkBounds = checkBounds; exports.chunk = chunk; exports.cloneLson = cloneLson; exports.compactObject = compactObject; exports.console = fancy_console_exports; exports.convertToCommentData = convertToCommentData; exports.convertToCommentUserReaction = convertToCommentUserReaction; exports.convertToGroupData = convertToGroupData; exports.convertToInboxNotificationData = convertToInboxNotificationData; exports.convertToSubscriptionData = convertToSubscriptionData; exports.convertToThreadData = convertToThreadData; exports.convertToUserSubscriptionData = convertToUserSubscriptionData; exports.createClient = createClient; exports.createCommentAttachmentId = createCommentAttachmentId; exports.createCommentId = createCommentId; exports.createInboxNotificationId = createInboxNotificationId; exports.createManagedPool = createManagedPool; exports.createNotificationSettings = createNotificationSettings; exports.createThreadId = createThreadId; exports.defineAiTool = defineAiTool; exports.deprecate = deprecate; exports.deprecateIf = deprecateIf; exports.detectDupes = detectDupes; exports.entries = entries; exports.errorIf = errorIf; exports.findLastIndex = findLastIndex; exports.freeze = freeze; exports.generateUrl = generateUrl; exports.getMentionsFromCommentBody = getMentionsFromCommentBody; exports.getSubscriptionKey = getSubscriptionKey; exports.html = html; exports.htmlSafe = htmlSafe; exports.isCommentBodyLink = isCommentBodyLink; exports.isCommentBodyMention = isCommentBodyMention; exports.isCommentBodyText = isCommentBodyText; exports.isJsonArray = isJsonArray; exports.isJsonObject = isJsonObject; exports.isJsonScalar = isJsonScalar; exports.isLiveNode = isLiveNode; exports.isNotificationChannelEnabled = isNotificationChannelEnabled; exports.isNumberOperator = isNumberOperator; exports.isPlainObject = isPlainObject; exports.isStartsWithOperator = isStartsWithOperator; exports.isUrl = isUrl; exports.kInternal = kInternal; exports.keys = keys; exports.legacy_patchImmutableObject = legacy_patchImmutableObject; exports.lsonToJson = lsonToJson; exports.makeAbortController = makeAbortController; exports.makeEventSource = makeEventSource; exports.makePoller = makePoller; exports.makePosition = makePosition; exports.mapValues = mapValues; exports.memoizeOnSuccess = memoizeOnSuccess; exports.nanoid = nanoid; exports.nn = nn; exports.objectToQuery = objectToQuery; exports.patchLiveObjectKey = patchLiveObjectKey; exports.patchNotificationSettings = patchNotificationSettings; exports.raise = raise; exports.resolveMentionsInCommentBody = resolveMentionsInCommentBody; exports.sanitizeUrl = sanitizeUrl; exports.shallow = shallow; exports.shallow2 = shallow2; exports.stableStringify = stableStringify; exports.stringifyCommentBody = stringifyCommentBody; exports.throwUsageError = throwUsageError; exports.toPlainLson = toPlainLson; exports.tryParseJson = tryParseJson; exports.url = url; exports.urljoin = urljoin; exports.wait = wait; exports.warnOnce = warnOnce; exports.warnOnceIf = warnOnceIf; exports.withTimeout = withTimeout;
11624
11610
  //# sourceMappingURL=index.cjs.map