@liveblocks/core 3.13.0-vincent3 → 3.13.1-hackathon

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.js 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-vincent3";
9
+ var PKG_VERSION = "3.13.1-hackathon";
10
10
  var PKG_FORMAT = "esm";
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 = 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,12 +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+
3097
- STORAGE_STREAM_END: 211,
3098
- // Used in V8+
3120
+ STORAGE_STATE: 200,
3099
3121
  UPDATE_STORAGE: 201,
3100
3122
  // For Yjs Docs
3101
3123
  UPDATE_YDOC: 300,
@@ -3109,6 +3131,10 @@ var ServerMsgCode = Object.freeze({
3109
3131
  COMMENT_DELETED: 404,
3110
3132
  COMMENT_REACTION_ADDED: 405,
3111
3133
  COMMENT_REACTION_REMOVED: 406,
3134
+ COMMENT_METADATA_UPDATED: 409,
3135
+ // For Agent Sessions
3136
+ AGENT_SESSIONS: 501,
3137
+ AGENT_MESSAGES: 503,
3112
3138
  // Error codes
3113
3139
  REJECT_STORAGE_OP: 299
3114
3140
  // Sent if a mutation was not allowed on the server (i.e. due to permissions, limit exceeded, etc)
@@ -6094,6 +6120,19 @@ var AbstractCrdt = class {
6094
6120
  }
6095
6121
  this.#pool = void 0;
6096
6122
  }
6123
+ /**
6124
+ * Serializes this CRDT and all its children into a list of creation ops
6125
+ * with opIds. Used for forward operations that will be sent over the wire
6126
+ * immediately. Each op gets a unique opId for server acknowledgement.
6127
+ *
6128
+ * @internal
6129
+ */
6130
+ _toOpsWithOpId(parentId, parentKey, pool) {
6131
+ return this._toOps(parentId, parentKey).map((op) => ({
6132
+ opId: pool.generateOpId(),
6133
+ ...op
6134
+ }));
6135
+ }
6097
6136
  /** This caches the result of the last .toImmutable() call for this Live node. */
6098
6137
  #cachedImmutable;
6099
6138
  #cachedTreeNodeKey;
@@ -6145,57 +6184,6 @@ var CrdtType = Object.freeze({
6145
6184
  MAP: 2,
6146
6185
  REGISTER: 3
6147
6186
  });
6148
- function isRootNode(node) {
6149
- return node[0] === "root";
6150
- }
6151
- function isRootCrdt(id, _) {
6152
- return id === "root";
6153
- }
6154
- function* compactNodesToNodeStream(nodes) {
6155
- for (const node of nodes) {
6156
- const id = node[0];
6157
- if (isRootNode(node)) {
6158
- yield [id, { type: CrdtType.OBJECT, data: node[1] }];
6159
- continue;
6160
- }
6161
- switch (node[1]) {
6162
- case CrdtType.OBJECT:
6163
- yield [id, { type: CrdtType.OBJECT, parentId: node[2], parentKey: node[3], data: node[4] }];
6164
- break;
6165
- case CrdtType.LIST:
6166
- yield [id, { type: CrdtType.LIST, parentId: node[2], parentKey: node[3] }];
6167
- break;
6168
- case CrdtType.MAP:
6169
- yield [id, { type: CrdtType.MAP, parentId: node[2], parentKey: node[3] }];
6170
- break;
6171
- case CrdtType.REGISTER:
6172
- yield [id, { type: CrdtType.REGISTER, parentId: node[2], parentKey: node[3], data: node[4] }];
6173
- break;
6174
- }
6175
- }
6176
- }
6177
- function* nodeStreamToCompactNodes(nodes) {
6178
- for (const [id, node] of nodes) {
6179
- switch (node.type) {
6180
- case CrdtType.OBJECT:
6181
- if (isRootCrdt(id, node)) {
6182
- yield [id, node.data];
6183
- } else {
6184
- yield [id, CrdtType.OBJECT, node.parentId, node.parentKey, node.data];
6185
- }
6186
- break;
6187
- case CrdtType.LIST:
6188
- yield [id, CrdtType.LIST, node.parentId, node.parentKey];
6189
- break;
6190
- case CrdtType.MAP:
6191
- yield [id, CrdtType.MAP, node.parentId, node.parentKey];
6192
- break;
6193
- case CrdtType.REGISTER:
6194
- yield [id, CrdtType.REGISTER, node.parentId, node.parentKey, node.data];
6195
- break;
6196
- }
6197
- }
6198
- }
6199
6187
 
6200
6188
  // src/crdts/LiveRegister.ts
6201
6189
  var LiveRegister = class _LiveRegister extends AbstractCrdt {
@@ -6214,7 +6202,7 @@ var LiveRegister = class _LiveRegister extends AbstractCrdt {
6214
6202
  return register;
6215
6203
  }
6216
6204
  /** @internal */
6217
- _toOps(parentId, parentKey, pool) {
6205
+ _toOps(parentId, parentKey) {
6218
6206
  if (this._id === void 0) {
6219
6207
  throw new Error(
6220
6208
  "Cannot serialize register if parentId or parentKey is undefined"
@@ -6223,7 +6211,6 @@ var LiveRegister = class _LiveRegister extends AbstractCrdt {
6223
6211
  return [
6224
6212
  {
6225
6213
  type: OpCode.CREATE_REGISTER,
6226
- opId: pool?.generateOpId(),
6227
6214
  id: this._id,
6228
6215
  parentId,
6229
6216
  parentKey,
@@ -6322,14 +6309,13 @@ var LiveList = class _LiveList extends AbstractCrdt {
6322
6309
  * This is quite unintuitive and should disappear as soon as
6323
6310
  * we introduce an explicit LiveList.Set operation
6324
6311
  */
6325
- _toOps(parentId, parentKey, pool) {
6312
+ _toOps(parentId, parentKey) {
6326
6313
  if (this._id === void 0) {
6327
6314
  throw new Error("Cannot serialize item is not attached");
6328
6315
  }
6329
6316
  const ops = [];
6330
6317
  const op = {
6331
6318
  id: this._id,
6332
- opId: pool?.generateOpId(),
6333
6319
  type: OpCode.CREATE_LIST,
6334
6320
  parentId,
6335
6321
  parentKey
@@ -6338,13 +6324,9 @@ var LiveList = class _LiveList extends AbstractCrdt {
6338
6324
  for (const item of this.#items) {
6339
6325
  const parentKey2 = item._getParentKeyOrThrow();
6340
6326
  const childOps = HACK_addIntentAndDeletedIdToOperation(
6341
- item._toOps(this._id, parentKey2, pool),
6327
+ item._toOps(this._id, parentKey2),
6342
6328
  void 0
6343
6329
  );
6344
- const childOpId = childOps[0].opId;
6345
- if (childOpId !== void 0) {
6346
- this.#unacknowledgedSets.set(parentKey2, childOpId);
6347
- }
6348
6330
  ops.push(...childOps);
6349
6331
  }
6350
6332
  return ops;
@@ -6636,7 +6618,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
6636
6618
  existingItem._detach();
6637
6619
  this.#items[indexOfItemWithSameKey] = child;
6638
6620
  const reverse = HACK_addIntentAndDeletedIdToOperation(
6639
- existingItem._toOps(nn(this._id), key, this._pool),
6621
+ existingItem._toOps(nn(this._id), key),
6640
6622
  op.id
6641
6623
  );
6642
6624
  const delta = [setDelta(indexOfItemWithSameKey, child)];
@@ -6692,7 +6674,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
6692
6674
  _detachChild(child) {
6693
6675
  if (child) {
6694
6676
  const parentKey = nn(child._parentKey);
6695
- const reverse = child._toOps(nn(this._id), parentKey, this._pool);
6677
+ const reverse = child._toOps(nn(this._id), parentKey);
6696
6678
  const indexToDelete = this.#items.indexOf(child);
6697
6679
  if (indexToDelete === -1) {
6698
6680
  return {
@@ -6899,7 +6881,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
6899
6881
  const id = this._pool.generateId();
6900
6882
  value._attach(id, this._pool);
6901
6883
  this._pool.dispatch(
6902
- value._toOps(this._id, position, this._pool),
6884
+ value._toOpsWithOpId(this._id, position, this._pool),
6903
6885
  [{ type: OpCode.DELETE_CRDT, id }],
6904
6886
  /* @__PURE__ */ new Map([
6905
6887
  [this._id, makeUpdate(this, [insertDelta(index, value)])]
@@ -7058,12 +7040,12 @@ var LiveList = class _LiveList extends AbstractCrdt {
7058
7040
  const storageUpdates = /* @__PURE__ */ new Map();
7059
7041
  storageUpdates.set(this._id, makeUpdate(this, [setDelta(index, value)]));
7060
7042
  const ops = HACK_addIntentAndDeletedIdToOperation(
7061
- value._toOps(this._id, position, this._pool),
7043
+ value._toOpsWithOpId(this._id, position, this._pool),
7062
7044
  existingId
7063
7045
  );
7064
7046
  this.#unacknowledgedSets.set(position, nn(ops[0].opId));
7065
7047
  const reverseOps = HACK_addIntentAndDeletedIdToOperation(
7066
- existingItem._toOps(this._id, position, void 0),
7048
+ existingItem._toOps(this._id, position),
7067
7049
  id
7068
7050
  );
7069
7051
  this._pool.dispatch(ops, reverseOps, storageUpdates);
@@ -7302,21 +7284,20 @@ var LiveMap = class _LiveMap extends AbstractCrdt {
7302
7284
  }
7303
7285
  }
7304
7286
  /** @internal */
7305
- _toOps(parentId, parentKey, pool) {
7287
+ _toOps(parentId, parentKey) {
7306
7288
  if (this._id === void 0) {
7307
7289
  throw new Error("Cannot serialize item is not attached");
7308
7290
  }
7309
7291
  const ops = [];
7310
7292
  const op = {
7311
7293
  id: this._id,
7312
- opId: pool?.generateOpId(),
7313
7294
  type: OpCode.CREATE_MAP,
7314
7295
  parentId,
7315
7296
  parentKey
7316
7297
  };
7317
7298
  ops.push(op);
7318
7299
  for (const [key, value] of this.#map) {
7319
- ops.push(...value._toOps(this._id, key, pool));
7300
+ ops.push(...value._toOps(this._id, key));
7320
7301
  }
7321
7302
  return ops;
7322
7303
  }
@@ -7400,7 +7381,7 @@ var LiveMap = class _LiveMap extends AbstractCrdt {
7400
7381
  _detachChild(child) {
7401
7382
  const id = nn(this._id);
7402
7383
  const parentKey = nn(child._parentKey);
7403
- const reverse = child._toOps(id, parentKey, this._pool);
7384
+ const reverse = child._toOps(id, parentKey);
7404
7385
  for (const [key, value] of this.#map) {
7405
7386
  if (value === child) {
7406
7387
  this.#map.delete(key);
@@ -7467,10 +7448,10 @@ var LiveMap = class _LiveMap extends AbstractCrdt {
7467
7448
  type: "LiveMap",
7468
7449
  updates: { [key]: { type: "update" } }
7469
7450
  });
7470
- const ops = item._toOps(this._id, key, this._pool);
7451
+ const ops = item._toOpsWithOpId(this._id, key, this._pool);
7471
7452
  this.#unacknowledgedSet.set(key, nn(ops[0].opId));
7472
7453
  this._pool.dispatch(
7473
- item._toOps(this._id, key, this._pool),
7454
+ ops,
7474
7455
  oldValue ? oldValue._toOps(this._id, key) : [{ type: OpCode.DELETE_CRDT, id }],
7475
7456
  storageUpdates
7476
7457
  );
@@ -7630,12 +7611,25 @@ var LiveMap = class _LiveMap extends AbstractCrdt {
7630
7611
 
7631
7612
  // src/crdts/LiveObject.ts
7632
7613
  var MAX_LIVE_OBJECT_SIZE = 128 * 1024;
7633
- function isRootCrdt2(id, _) {
7614
+ function isRootCrdt(id, _) {
7634
7615
  return id === "root";
7635
7616
  }
7636
7617
  var LiveObject = class _LiveObject extends AbstractCrdt {
7637
7618
  #map;
7638
- #propToLastUpdate;
7619
+ /**
7620
+ * Tracks unacknowledged local changes per property to preserve optimistic
7621
+ * updates. Maps property keys to their pending operation IDs.
7622
+ *
7623
+ * INVARIANT: Only locally-generated opIds are ever stored here. Remote opIds
7624
+ * are only compared against (to detect ACKs), never stored.
7625
+ *
7626
+ * When a local change is made, the opId is stored here. When a remote op
7627
+ * arrives for the same key:
7628
+ * - If no entry exists → apply remote op
7629
+ * - If opId matches → it's an ACK, clear the entry
7630
+ * - If opId differs → ignore remote op to preserve optimistic update
7631
+ */
7632
+ #unackedOpsByKey;
7639
7633
  /**
7640
7634
  * Enable or disable detection of too large LiveObjects.
7641
7635
  * When enabled, throws an error if LiveObject static data exceeds 128KB, which
@@ -7650,7 +7644,7 @@ var LiveObject = class _LiveObject extends AbstractCrdt {
7650
7644
  const parentToChildren = /* @__PURE__ */ new Map();
7651
7645
  let root = null;
7652
7646
  for (const [id, crdt] of items) {
7653
- if (isRootCrdt2(id, crdt)) {
7647
+ if (isRootCrdt(id, crdt)) {
7654
7648
  root = crdt;
7655
7649
  } else {
7656
7650
  const tuple = [id, crdt];
@@ -7668,8 +7662,8 @@ var LiveObject = class _LiveObject extends AbstractCrdt {
7668
7662
  return [root, parentToChildren];
7669
7663
  }
7670
7664
  /** @private Do not use this API directly */
7671
- static _fromItems(nodes, pool) {
7672
- const [root, parentToChildren] = _LiveObject.#buildRootAndParentToChildren(nodes);
7665
+ static _fromItems(items, pool) {
7666
+ const [root, parentToChildren] = _LiveObject.#buildRootAndParentToChildren(items);
7673
7667
  return _LiveObject._deserialize(
7674
7668
  ["root", root],
7675
7669
  parentToChildren,
@@ -7678,7 +7672,7 @@ var LiveObject = class _LiveObject extends AbstractCrdt {
7678
7672
  }
7679
7673
  constructor(obj = {}) {
7680
7674
  super();
7681
- this.#propToLastUpdate = /* @__PURE__ */ new Map();
7675
+ this.#unackedOpsByKey = /* @__PURE__ */ new Map();
7682
7676
  const o = compactObject(obj);
7683
7677
  for (const key of Object.keys(o)) {
7684
7678
  const value = o[key];
@@ -7689,16 +7683,14 @@ var LiveObject = class _LiveObject extends AbstractCrdt {
7689
7683
  this.#map = new Map(Object.entries(o));
7690
7684
  }
7691
7685
  /** @internal */
7692
- _toOps(parentId, parentKey, pool) {
7686
+ _toOps(parentId, parentKey) {
7693
7687
  if (this._id === void 0) {
7694
7688
  throw new Error("Cannot serialize item is not attached");
7695
7689
  }
7696
- const opId = pool?.generateOpId();
7697
7690
  const ops = [];
7698
7691
  const op = {
7699
7692
  type: OpCode.CREATE_OBJECT,
7700
7693
  id: this._id,
7701
- opId,
7702
7694
  parentId,
7703
7695
  parentKey,
7704
7696
  data: {}
@@ -7706,7 +7698,7 @@ var LiveObject = class _LiveObject extends AbstractCrdt {
7706
7698
  ops.push(op);
7707
7699
  for (const [key, value] of this.#map) {
7708
7700
  if (isLiveNode(value)) {
7709
- ops.push(...value._toOps(this._id, key, pool));
7701
+ ops.push(...value._toOps(this._id, key));
7710
7702
  } else {
7711
7703
  op.data[key] = value;
7712
7704
  }
@@ -7752,16 +7744,16 @@ var LiveObject = class _LiveObject extends AbstractCrdt {
7752
7744
  const { id, opId, parentKey: key } = op;
7753
7745
  const child = creationOpToLson(op);
7754
7746
  if (this._pool.getNode(id) !== void 0) {
7755
- if (this.#propToLastUpdate.get(key) === opId) {
7756
- this.#propToLastUpdate.delete(key);
7747
+ if (this.#unackedOpsByKey.get(key) === opId) {
7748
+ this.#unackedOpsByKey.delete(key);
7757
7749
  }
7758
7750
  return { modified: false };
7759
7751
  }
7760
7752
  if (source === 0 /* LOCAL */) {
7761
- this.#propToLastUpdate.set(key, nn(opId));
7762
- } else if (this.#propToLastUpdate.get(key) === void 0) {
7763
- } else if (this.#propToLastUpdate.get(key) === opId) {
7764
- this.#propToLastUpdate.delete(key);
7753
+ this.#unackedOpsByKey.set(key, nn(opId));
7754
+ } else if (this.#unackedOpsByKey.get(key) === void 0) {
7755
+ } else if (this.#unackedOpsByKey.get(key) === opId) {
7756
+ this.#unackedOpsByKey.delete(key);
7765
7757
  return { modified: false };
7766
7758
  } else {
7767
7759
  return { modified: false };
@@ -7803,7 +7795,7 @@ var LiveObject = class _LiveObject extends AbstractCrdt {
7803
7795
  if (child) {
7804
7796
  const id = nn(this._id);
7805
7797
  const parentKey = nn(child._parentKey);
7806
- const reverse = child._toOps(id, parentKey, this._pool);
7798
+ const reverse = child._toOps(id, parentKey);
7807
7799
  for (const [key, value] of this.#map) {
7808
7800
  if (value === child) {
7809
7801
  this.#map.delete(key);
@@ -7889,11 +7881,11 @@ var LiveObject = class _LiveObject extends AbstractCrdt {
7889
7881
  continue;
7890
7882
  }
7891
7883
  if (isLocal) {
7892
- this.#propToLastUpdate.set(key, nn(op.opId));
7893
- } else if (this.#propToLastUpdate.get(key) === void 0) {
7884
+ this.#unackedOpsByKey.set(key, nn(op.opId));
7885
+ } else if (this.#unackedOpsByKey.get(key) === void 0) {
7894
7886
  isModified = true;
7895
- } else if (this.#propToLastUpdate.get(key) === op.opId) {
7896
- this.#propToLastUpdate.delete(key);
7887
+ } else if (this.#unackedOpsByKey.get(key) === op.opId) {
7888
+ this.#unackedOpsByKey.delete(key);
7897
7889
  continue;
7898
7890
  } else {
7899
7891
  continue;
@@ -7925,7 +7917,7 @@ var LiveObject = class _LiveObject extends AbstractCrdt {
7925
7917
  if (oldValue === void 0) {
7926
7918
  return { modified: false };
7927
7919
  }
7928
- if (!isLocal && this.#propToLastUpdate.get(key) !== void 0) {
7920
+ if (!isLocal && this.#unackedOpsByKey.get(key) !== void 0) {
7929
7921
  return { modified: false };
7930
7922
  }
7931
7923
  const id = nn(this._id);
@@ -8108,17 +8100,21 @@ var LiveObject = class _LiveObject extends AbstractCrdt {
8108
8100
  if (isLiveNode(newValue)) {
8109
8101
  newValue._setParentLink(this, key);
8110
8102
  newValue._attach(this._pool.generateId(), this._pool);
8111
- const newAttachChildOps = newValue._toOps(this._id, key, this._pool);
8103
+ const newAttachChildOps = newValue._toOpsWithOpId(
8104
+ this._id,
8105
+ key,
8106
+ this._pool
8107
+ );
8112
8108
  const createCrdtOp = newAttachChildOps.find(
8113
8109
  (op) => op.parentId === this._id
8114
8110
  );
8115
8111
  if (createCrdtOp) {
8116
- this.#propToLastUpdate.set(key, nn(createCrdtOp.opId));
8112
+ this.#unackedOpsByKey.set(key, nn(createCrdtOp.opId));
8117
8113
  }
8118
8114
  ops.push(...newAttachChildOps);
8119
8115
  } else {
8120
8116
  updatedProps[key] = newValue;
8121
- this.#propToLastUpdate.set(key, opId);
8117
+ this.#unackedOpsByKey.set(key, opId);
8122
8118
  }
8123
8119
  this.#map.set(key, newValue);
8124
8120
  this.invalidate();
@@ -8288,7 +8284,10 @@ function getTreesDiffOperations(currentItems, newItems) {
8288
8284
  const ops = [];
8289
8285
  currentItems.forEach((_, id) => {
8290
8286
  if (!newItems.get(id)) {
8291
- ops.push({ type: OpCode.DELETE_CRDT, id });
8287
+ ops.push({
8288
+ type: OpCode.DELETE_CRDT,
8289
+ id
8290
+ });
8292
8291
  }
8293
8292
  });
8294
8293
  newItems.forEach((crdt, id) => {
@@ -8511,7 +8510,10 @@ var ClientMsgCode = Object.freeze({
8511
8510
  UPDATE_STORAGE: 201,
8512
8511
  // For Yjs support
8513
8512
  FETCH_YDOC: 300,
8514
- UPDATE_YDOC: 301
8513
+ UPDATE_YDOC: 301,
8514
+ // For Agent Sessions
8515
+ FETCH_AGENT_SESSIONS: 500,
8516
+ FETCH_AGENT_MESSAGES: 502
8515
8517
  });
8516
8518
 
8517
8519
  // src/refs/ManagedOthers.ts
@@ -8713,6 +8715,8 @@ function defaultMessageFromContext(context) {
8713
8715
  return "Could not delete thread";
8714
8716
  case "EDIT_THREAD_METADATA_ERROR":
8715
8717
  return "Could not edit thread metadata";
8718
+ case "EDIT_COMMENT_METADATA_ERROR":
8719
+ return "Could not edit comment metadata";
8716
8720
  case "MARK_THREAD_AS_RESOLVED_ERROR":
8717
8721
  return "Could not mark thread as resolved";
8718
8722
  case "MARK_THREAD_AS_UNRESOLVED_ERROR":
@@ -8786,21 +8790,6 @@ function installBackgroundTabSpy() {
8786
8790
  };
8787
8791
  return [inBackgroundSince, unsub];
8788
8792
  }
8789
- function makePartialNodeMap() {
8790
- let map = /* @__PURE__ */ new Map();
8791
- return {
8792
- append(chunk2) {
8793
- for (const [id, node] of chunk2) {
8794
- map.set(id, node);
8795
- }
8796
- },
8797
- clear() {
8798
- const result = map;
8799
- map = /* @__PURE__ */ new Map();
8800
- return result;
8801
- }
8802
- };
8803
- }
8804
8793
  function createRoom(options, config) {
8805
8794
  const roomId = config.roomId;
8806
8795
  const initialPresence = options.initialPresence;
@@ -8861,7 +8850,6 @@ function createRoom(options, config) {
8861
8850
  activeBatch: null,
8862
8851
  unacknowledgedOps: /* @__PURE__ */ new Map()
8863
8852
  };
8864
- const partialNodes = makePartialNodeMap();
8865
8853
  let lastTokenKey;
8866
8854
  function onStatusDidChange(newStatus) {
8867
8855
  const authValue = managedSocket.authValue;
@@ -8983,6 +8971,7 @@ function createRoom(options, config) {
8983
8971
  storageStatus: makeEventSource(),
8984
8972
  ydoc: makeEventSource(),
8985
8973
  comments: makeEventSource(),
8974
+ agentSessions: makeEventSource(),
8986
8975
  roomWillDestroy: makeEventSource()
8987
8976
  };
8988
8977
  async function createTextMention(mentionId, mention) {
@@ -9143,11 +9132,14 @@ function createRoom(options, config) {
9143
9132
  self,
9144
9133
  (me) => me !== null ? userToTreeNode("Me", me) : null
9145
9134
  );
9146
- function createOrUpdateRootFromMessage(nodes) {
9135
+ function createOrUpdateRootFromMessage(message) {
9136
+ if (message.items.length === 0) {
9137
+ throw new Error("Internal error: cannot load storage without items");
9138
+ }
9147
9139
  if (context.root !== void 0) {
9148
- updateRoot(new Map(nodes));
9140
+ updateRoot(message.items);
9149
9141
  } else {
9150
- context.root = LiveObject._fromItems(nodes, context.pool);
9142
+ context.root = LiveObject._fromItems(message.items, context.pool);
9151
9143
  }
9152
9144
  const canWrite = self.get()?.canWrite ?? true;
9153
9145
  const stackSizeBefore = context.undoStack.length;
@@ -9164,10 +9156,7 @@ function createRoom(options, config) {
9164
9156
  }
9165
9157
  context.undoStack.length = stackSizeBefore;
9166
9158
  }
9167
- function updateRoot(nodes) {
9168
- if (nodes.size === 0) {
9169
- throw new Error("Internal error: cannot load storage without items");
9170
- }
9159
+ function updateRoot(items) {
9171
9160
  if (context.root === void 0) {
9172
9161
  return;
9173
9162
  }
@@ -9175,26 +9164,22 @@ function createRoom(options, config) {
9175
9164
  for (const [id, node] of context.pool.nodes) {
9176
9165
  currentItems.set(id, node._serialize());
9177
9166
  }
9178
- const ops = getTreesDiffOperations(currentItems, nodes);
9179
- const result = applyOps(
9180
- ops,
9181
- /* isLocal */
9182
- false
9183
- );
9167
+ const ops = getTreesDiffOperations(currentItems, new Map(items));
9168
+ const result = applyRemoteOps(ops);
9184
9169
  notify(result.updates);
9185
9170
  }
9186
- function _addToRealUndoStack(historyOps) {
9171
+ function _addToRealUndoStack(frames) {
9187
9172
  if (context.undoStack.length >= 50) {
9188
9173
  context.undoStack.shift();
9189
9174
  }
9190
- context.undoStack.push(historyOps);
9175
+ context.undoStack.push(frames);
9191
9176
  onHistoryChange();
9192
9177
  }
9193
- function addToUndoStack(historyOps) {
9178
+ function addToUndoStack(frames) {
9194
9179
  if (context.pausedHistory !== null) {
9195
- context.pausedHistory.pushLeft(historyOps);
9180
+ context.pausedHistory.pushLeft(frames);
9196
9181
  } else {
9197
- _addToRealUndoStack(historyOps);
9182
+ _addToRealUndoStack(frames);
9198
9183
  }
9199
9184
  }
9200
9185
  function notify(updates) {
@@ -9225,69 +9210,85 @@ function createRoom(options, config) {
9225
9210
  "Internal. Tried to get connection id but connection was never open"
9226
9211
  );
9227
9212
  }
9228
- function applyOps(rawOps, isLocal) {
9213
+ function applyLocalOps(frames) {
9214
+ const [pframes, ops] = partition(
9215
+ frames,
9216
+ (f) => f.type === "presence"
9217
+ );
9218
+ const opsWithOpIds = ops.map(
9219
+ (op) => op.opId === void 0 ? { ...op, opId: context.pool.generateOpId() } : op
9220
+ );
9221
+ const { reverse, updates } = applyOps(
9222
+ pframes,
9223
+ opsWithOpIds,
9224
+ /* isLocal */
9225
+ true
9226
+ );
9227
+ return { opsToEmit: opsWithOpIds, reverse, updates };
9228
+ }
9229
+ function applyRemoteOps(ops) {
9230
+ return applyOps(
9231
+ [],
9232
+ ops,
9233
+ /* isLocal */
9234
+ false
9235
+ );
9236
+ }
9237
+ function applyOps(pframes, ops, isLocal) {
9229
9238
  const output = {
9230
9239
  reverse: new Deque(),
9231
9240
  storageUpdates: /* @__PURE__ */ new Map(),
9232
9241
  presence: false
9233
9242
  };
9234
- const createdNodeIds = /* @__PURE__ */ new Set();
9235
- const ops = rawOps.map((op) => {
9236
- if (op.type !== "presence" && !op.opId) {
9237
- return { ...op, opId: context.pool.generateOpId() };
9243
+ for (const pf of pframes) {
9244
+ const reverse = {
9245
+ type: "presence",
9246
+ data: {}
9247
+ };
9248
+ for (const key in pf.data) {
9249
+ reverse.data[key] = context.myPresence.get()[key];
9250
+ }
9251
+ context.myPresence.patch(pf.data);
9252
+ if (context.buffer.presenceUpdates === null) {
9253
+ context.buffer.presenceUpdates = { type: "partial", data: pf.data };
9238
9254
  } else {
9239
- return op;
9255
+ for (const key in pf.data) {
9256
+ context.buffer.presenceUpdates.data[key] = pf.data[key];
9257
+ }
9240
9258
  }
9241
- });
9259
+ output.reverse.pushLeft(reverse);
9260
+ output.presence = true;
9261
+ }
9262
+ const createdNodeIds = /* @__PURE__ */ new Set();
9242
9263
  for (const op of ops) {
9243
- if (op.type === "presence") {
9244
- const reverse = {
9245
- type: "presence",
9246
- data: {}
9247
- };
9248
- for (const key in op.data) {
9249
- reverse.data[key] = context.myPresence.get()[key];
9250
- }
9251
- context.myPresence.patch(op.data);
9252
- if (context.buffer.presenceUpdates === null) {
9253
- context.buffer.presenceUpdates = { type: "partial", data: op.data };
9254
- } else {
9255
- for (const key in op.data) {
9256
- context.buffer.presenceUpdates.data[key] = op.data[key];
9257
- }
9258
- }
9259
- output.reverse.pushLeft(reverse);
9260
- output.presence = true;
9264
+ let source;
9265
+ if (isLocal) {
9266
+ source = 0 /* LOCAL */;
9267
+ } else if (op.opId !== void 0) {
9268
+ context.unacknowledgedOps.delete(op.opId);
9269
+ source = 2 /* OURS */;
9261
9270
  } else {
9262
- let source;
9263
- if (isLocal) {
9264
- source = 0 /* LOCAL */;
9265
- } else {
9266
- const opId = nn(op.opId);
9267
- const deleted = context.unacknowledgedOps.delete(opId);
9268
- source = deleted ? 2 /* OURS */ : 1 /* THEIRS */;
9271
+ source = 1 /* THEIRS */;
9272
+ }
9273
+ const applyOpResult = applyOp(op, source);
9274
+ if (applyOpResult.modified) {
9275
+ const nodeId = applyOpResult.modified.node._id;
9276
+ if (!(nodeId && createdNodeIds.has(nodeId))) {
9277
+ output.storageUpdates.set(
9278
+ nn(applyOpResult.modified.node._id),
9279
+ mergeStorageUpdates(
9280
+ output.storageUpdates.get(nn(applyOpResult.modified.node._id)),
9281
+ applyOpResult.modified
9282
+ )
9283
+ );
9284
+ output.reverse.pushLeft(applyOpResult.reverse);
9269
9285
  }
9270
- const applyOpResult = applyOp(op, source);
9271
- if (applyOpResult.modified) {
9272
- const nodeId = applyOpResult.modified.node._id;
9273
- if (!(nodeId && createdNodeIds.has(nodeId))) {
9274
- output.storageUpdates.set(
9275
- nn(applyOpResult.modified.node._id),
9276
- mergeStorageUpdates(
9277
- output.storageUpdates.get(nn(applyOpResult.modified.node._id)),
9278
- applyOpResult.modified
9279
- )
9280
- );
9281
- output.reverse.pushLeft(applyOpResult.reverse);
9282
- }
9283
- if (op.type === OpCode.CREATE_LIST || op.type === OpCode.CREATE_MAP || op.type === OpCode.CREATE_OBJECT) {
9284
- createdNodeIds.add(nn(op.id));
9285
- }
9286
+ if (op.type === OpCode.CREATE_LIST || op.type === OpCode.CREATE_MAP || op.type === OpCode.CREATE_OBJECT) {
9287
+ createdNodeIds.add(op.id);
9286
9288
  }
9287
9289
  }
9288
9290
  }
9289
9291
  return {
9290
- ops,
9291
9292
  reverse: Array.from(output.reverse),
9292
9293
  updates: {
9293
9294
  storageUpdates: output.storageUpdates,
@@ -9472,20 +9473,16 @@ function createRoom(options, config) {
9472
9473
  return compact([parseServerMessage(data)]);
9473
9474
  }
9474
9475
  }
9475
- function applyAndSendOps(offlineOps) {
9476
- if (offlineOps.size === 0) {
9476
+ function applyAndSendOfflineOps(unackedOps) {
9477
+ if (unackedOps.size === 0) {
9477
9478
  return;
9478
9479
  }
9479
9480
  const messages = [];
9480
- const inOps = Array.from(offlineOps.values());
9481
- const result = applyOps(
9482
- inOps,
9483
- /* isLocal */
9484
- true
9485
- );
9481
+ const inOps = Array.from(unackedOps.values());
9482
+ const result = applyLocalOps(inOps);
9486
9483
  messages.push({
9487
9484
  type: ClientMsgCode.UPDATE_STORAGE,
9488
- ops: result.ops
9485
+ ops: result.opsToEmit
9489
9486
  });
9490
9487
  notify(result.updates);
9491
9488
  sendMessages(messages);
@@ -9542,18 +9539,12 @@ function createRoom(options, config) {
9542
9539
  updates.others.push(onRoomStateMessage(message));
9543
9540
  break;
9544
9541
  }
9545
- case ServerMsgCode.STORAGE_CHUNK:
9546
- partialNodes.append(compactNodesToNodeStream(message.nodes));
9547
- break;
9548
- case ServerMsgCode.STORAGE_STREAM_END:
9549
- processInitialStorage(partialNodes.clear());
9542
+ case ServerMsgCode.STORAGE_STATE: {
9543
+ processInitialStorage(message);
9550
9544
  break;
9545
+ }
9551
9546
  case ServerMsgCode.UPDATE_STORAGE: {
9552
- const applyResult = applyOps(
9553
- message.ops,
9554
- /* isLocal */
9555
- false
9556
- );
9547
+ const applyResult = applyRemoteOps(message.ops);
9557
9548
  for (const [key, value] of applyResult.updates.storageUpdates) {
9558
9549
  updates.storageUpdates.set(
9559
9550
  key,
@@ -9586,12 +9577,50 @@ function createRoom(options, config) {
9586
9577
  case ServerMsgCode.COMMENT_REACTION_REMOVED:
9587
9578
  case ServerMsgCode.COMMENT_CREATED:
9588
9579
  case ServerMsgCode.COMMENT_EDITED:
9589
- case ServerMsgCode.COMMENT_DELETED: {
9580
+ case ServerMsgCode.COMMENT_DELETED:
9581
+ case ServerMsgCode.COMMENT_METADATA_UPDATED: {
9590
9582
  eventHub.comments.notify(message);
9591
9583
  break;
9592
9584
  }
9593
- case ServerMsgCode.STORAGE_STATE_V7:
9594
- // No longer used in V8
9585
+ case ServerMsgCode.AGENT_SESSIONS: {
9586
+ const agentSessionsMsg = message;
9587
+ if (agentSessionsMsg.operation === "list") {
9588
+ for (const [
9589
+ requestId,
9590
+ { resolve }
9591
+ ] of pendingAgentSessionsRequests) {
9592
+ resolve({
9593
+ sessions: agentSessionsMsg.sessions,
9594
+ nextCursor: agentSessionsMsg.nextCursor
9595
+ });
9596
+ pendingAgentSessionsRequests.delete(requestId);
9597
+ break;
9598
+ }
9599
+ }
9600
+ eventHub.agentSessions.notify(agentSessionsMsg);
9601
+ break;
9602
+ }
9603
+ case ServerMsgCode.AGENT_MESSAGES: {
9604
+ const agentMessagesMsg = message;
9605
+ if (agentMessagesMsg.operation === "list") {
9606
+ for (const [
9607
+ requestId,
9608
+ { resolve }
9609
+ ] of pendingAgentMessagesRequests) {
9610
+ const parsedRequestId = JSON.parse(requestId);
9611
+ if (parsedRequestId.sessionId === agentMessagesMsg.sessionId) {
9612
+ resolve({
9613
+ messages: agentMessagesMsg.messages,
9614
+ nextCursor: agentMessagesMsg.nextCursor
9615
+ });
9616
+ pendingAgentMessagesRequests.delete(requestId);
9617
+ break;
9618
+ }
9619
+ }
9620
+ }
9621
+ eventHub.agentSessions.notify(agentMessagesMsg);
9622
+ break;
9623
+ }
9595
9624
  default:
9596
9625
  break;
9597
9626
  }
@@ -9602,7 +9631,7 @@ function createRoom(options, config) {
9602
9631
  const storageOps = context.buffer.storageOperations;
9603
9632
  if (storageOps.length > 0) {
9604
9633
  for (const op of storageOps) {
9605
- context.unacknowledgedOps.set(nn(op.opId), op);
9634
+ context.unacknowledgedOps.set(op.opId, op);
9606
9635
  }
9607
9636
  notifyStorageStatus();
9608
9637
  }
@@ -9693,18 +9722,20 @@ function createRoom(options, config) {
9693
9722
  }
9694
9723
  let _getStorage$ = null;
9695
9724
  let _resolveStoragePromise = null;
9696
- function processInitialStorage(nodes) {
9725
+ const pendingAgentSessionsRequests = /* @__PURE__ */ new Map();
9726
+ const pendingAgentMessagesRequests = /* @__PURE__ */ new Map();
9727
+ function processInitialStorage(message) {
9697
9728
  const unacknowledgedOps = new Map(context.unacknowledgedOps);
9698
- createOrUpdateRootFromMessage(nodes);
9699
- applyAndSendOps(unacknowledgedOps);
9729
+ createOrUpdateRootFromMessage(message);
9730
+ applyAndSendOfflineOps(unacknowledgedOps);
9700
9731
  _resolveStoragePromise?.();
9701
9732
  notifyStorageStatus();
9702
9733
  eventHub.storageDidLoad.notify();
9703
9734
  }
9704
9735
  async function streamStorage() {
9705
9736
  if (!managedSocket.authValue) return;
9706
- const nodes = new Map(await httpClient.streamStorage({ roomId }));
9707
- processInitialStorage(nodes);
9737
+ const items = await httpClient.streamStorage({ roomId });
9738
+ processInitialStorage({ type: ServerMsgCode.STORAGE_STATE, items });
9708
9739
  }
9709
9740
  function refreshStorage(options2) {
9710
9741
  const messages = context.buffer.messages;
@@ -9712,7 +9743,6 @@ function createRoom(options, config) {
9712
9743
  void streamStorage();
9713
9744
  } else if (!messages.some((msg) => msg.type === ClientMsgCode.FETCH_STORAGE)) {
9714
9745
  messages.push({ type: ClientMsgCode.FETCH_STORAGE });
9715
- partialNodes.clear();
9716
9746
  }
9717
9747
  if (options2.flush) {
9718
9748
  flushNowOrSoon();
@@ -9761,27 +9791,80 @@ function createRoom(options, config) {
9761
9791
  }
9762
9792
  flushNowOrSoon();
9763
9793
  }
9794
+ async function fetchAgentSessions(options2) {
9795
+ const requestId = JSON.stringify({
9796
+ cursor: options2?.cursor,
9797
+ since: options2?.since,
9798
+ limit: options2?.limit,
9799
+ metadata: options2?.metadata
9800
+ });
9801
+ const { promise, resolve, reject } = Promise_withResolvers();
9802
+ pendingAgentSessionsRequests.set(requestId, { resolve, reject });
9803
+ const message = {
9804
+ type: ClientMsgCode.FETCH_AGENT_SESSIONS,
9805
+ cursor: options2?.cursor,
9806
+ since: options2?.since,
9807
+ limit: options2?.limit,
9808
+ metadata: options2?.metadata
9809
+ };
9810
+ context.buffer.messages.push(message);
9811
+ flushNowOrSoon();
9812
+ setTimeout(() => {
9813
+ if (pendingAgentSessionsRequests.has(requestId)) {
9814
+ pendingAgentSessionsRequests.delete(requestId);
9815
+ reject(new Error("Agent sessions fetch timeout"));
9816
+ }
9817
+ }, 3e4);
9818
+ return promise;
9819
+ }
9820
+ async function fetchAgentMessages(sessionId, options2) {
9821
+ const requestId = JSON.stringify({
9822
+ sessionId,
9823
+ cursor: options2?.cursor,
9824
+ since: options2?.since,
9825
+ limit: options2?.limit
9826
+ });
9827
+ const existingRequest = pendingAgentMessagesRequests.get(requestId);
9828
+ if (existingRequest) {
9829
+ return new Promise((resolve2, reject2) => {
9830
+ existingRequest.resolve = resolve2;
9831
+ existingRequest.reject = reject2;
9832
+ });
9833
+ }
9834
+ const { promise, resolve, reject } = Promise_withResolvers();
9835
+ pendingAgentMessagesRequests.set(requestId, { resolve, reject });
9836
+ const message = {
9837
+ type: ClientMsgCode.FETCH_AGENT_MESSAGES,
9838
+ sessionId,
9839
+ cursor: options2?.cursor,
9840
+ since: options2?.since,
9841
+ limit: options2?.limit
9842
+ };
9843
+ context.buffer.messages.push(message);
9844
+ flushNowOrSoon();
9845
+ setTimeout(() => {
9846
+ if (pendingAgentMessagesRequests.has(requestId)) {
9847
+ pendingAgentMessagesRequests.delete(requestId);
9848
+ reject(new Error("Agent messages fetch timeout"));
9849
+ }
9850
+ }, 3e4);
9851
+ return promise;
9852
+ }
9764
9853
  function undo() {
9765
9854
  if (context.activeBatch) {
9766
9855
  throw new Error("undo is not allowed during a batch");
9767
9856
  }
9768
- const historyOps = context.undoStack.pop();
9769
- if (historyOps === void 0) {
9857
+ const frames = context.undoStack.pop();
9858
+ if (frames === void 0) {
9770
9859
  return;
9771
9860
  }
9772
9861
  context.pausedHistory = null;
9773
- const result = applyOps(
9774
- historyOps,
9775
- /* isLocal */
9776
- true
9777
- );
9862
+ const result = applyLocalOps(frames);
9778
9863
  notify(result.updates);
9779
9864
  context.redoStack.push(result.reverse);
9780
9865
  onHistoryChange();
9781
- for (const op of result.ops) {
9782
- if (op.type !== "presence") {
9783
- context.buffer.storageOperations.push(op);
9784
- }
9866
+ for (const op of result.opsToEmit) {
9867
+ context.buffer.storageOperations.push(op);
9785
9868
  }
9786
9869
  flushNowOrSoon();
9787
9870
  }
@@ -9789,23 +9872,17 @@ function createRoom(options, config) {
9789
9872
  if (context.activeBatch) {
9790
9873
  throw new Error("redo is not allowed during a batch");
9791
9874
  }
9792
- const historyOps = context.redoStack.pop();
9793
- if (historyOps === void 0) {
9875
+ const frames = context.redoStack.pop();
9876
+ if (frames === void 0) {
9794
9877
  return;
9795
9878
  }
9796
9879
  context.pausedHistory = null;
9797
- const result = applyOps(
9798
- historyOps,
9799
- /* isLocal */
9800
- true
9801
- );
9880
+ const result = applyLocalOps(frames);
9802
9881
  notify(result.updates);
9803
9882
  context.undoStack.push(result.reverse);
9804
9883
  onHistoryChange();
9805
- for (const op of result.ops) {
9806
- if (op.type !== "presence") {
9807
- context.buffer.storageOperations.push(op);
9808
- }
9884
+ for (const op of result.opsToEmit) {
9885
+ context.buffer.storageOperations.push(op);
9809
9886
  }
9810
9887
  flushNowOrSoon();
9811
9888
  }
@@ -9852,10 +9929,10 @@ function createRoom(options, config) {
9852
9929
  }
9853
9930
  }
9854
9931
  function resumeHistory() {
9855
- const historyOps = context.pausedHistory;
9932
+ const frames = context.pausedHistory;
9856
9933
  context.pausedHistory = null;
9857
- if (historyOps !== null && historyOps.length > 0) {
9858
- _addToRealUndoStack(Array.from(historyOps));
9934
+ if (frames !== null && frames.length > 0) {
9935
+ _addToRealUndoStack(Array.from(frames));
9859
9936
  }
9860
9937
  }
9861
9938
  const syncSourceForStorage = config.createSyncSource();
@@ -9915,6 +9992,7 @@ function createRoom(options, config) {
9915
9992
  storageStatus: eventHub.storageStatus.observable,
9916
9993
  ydoc: eventHub.ydoc.observable,
9917
9994
  comments: eventHub.comments.observable,
9995
+ agentSessions: eventHub.agentSessions.observable,
9918
9996
  roomWillDestroy: eventHub.roomWillDestroy.observable
9919
9997
  };
9920
9998
  async function getThreadsSince(options2) {
@@ -9941,6 +10019,7 @@ function createRoom(options, config) {
9941
10019
  commentId: options2.commentId,
9942
10020
  metadata: options2.metadata,
9943
10021
  body: options2.body,
10022
+ commentMetadata: options2.commentMetadata,
9944
10023
  attachmentIds: options2.attachmentIds
9945
10024
  });
9946
10025
  }
@@ -9953,6 +10032,18 @@ function createRoom(options, config) {
9953
10032
  }) {
9954
10033
  return httpClient.editThreadMetadata({ roomId, threadId, metadata });
9955
10034
  }
10035
+ async function editCommentMetadata({
10036
+ threadId,
10037
+ commentId,
10038
+ metadata
10039
+ }) {
10040
+ return httpClient.editCommentMetadata({
10041
+ roomId,
10042
+ threadId,
10043
+ commentId,
10044
+ metadata
10045
+ });
10046
+ }
9956
10047
  async function markThreadAsResolved(threadId) {
9957
10048
  return httpClient.markThreadAsResolved({ roomId, threadId });
9958
10049
  }
@@ -9974,6 +10065,7 @@ function createRoom(options, config) {
9974
10065
  threadId: options2.threadId,
9975
10066
  commentId: options2.commentId,
9976
10067
  body: options2.body,
10068
+ metadata: options2.metadata,
9977
10069
  attachmentIds: options2.attachmentIds
9978
10070
  });
9979
10071
  }
@@ -9983,6 +10075,7 @@ function createRoom(options, config) {
9983
10075
  threadId: options2.threadId,
9984
10076
  commentId: options2.commentId,
9985
10077
  body: options2.body,
10078
+ metadata: options2.metadata,
9986
10079
  attachmentIds: options2.attachmentIds
9987
10080
  });
9988
10081
  }
@@ -10108,7 +10201,7 @@ function createRoom(options, config) {
10108
10201
  id: roomId,
10109
10202
  subscribe: makeClassicSubscribeFn(
10110
10203
  roomId,
10111
- events,
10204
+ eventHub,
10112
10205
  config.errorEventSource
10113
10206
  ),
10114
10207
  connect: () => managedSocket.connect(),
@@ -10143,6 +10236,8 @@ function createRoom(options, config) {
10143
10236
  resume: resumeHistory
10144
10237
  },
10145
10238
  fetchYDoc,
10239
+ fetchAgentSessions,
10240
+ fetchAgentMessages,
10146
10241
  getStorage,
10147
10242
  getStorageSnapshot,
10148
10243
  getStorageStatus,
@@ -10170,6 +10265,7 @@ function createRoom(options, config) {
10170
10265
  unsubscribeFromThread,
10171
10266
  createComment,
10172
10267
  editComment,
10268
+ editCommentMetadata,
10173
10269
  deleteComment,
10174
10270
  addReaction,
10175
10271
  removeReaction,
@@ -10302,7 +10398,7 @@ function makeCreateSocketDelegateForRoom(roomId, baseUrl, WebSocketPolyfill, eng
10302
10398
  }
10303
10399
  const url2 = new URL(baseUrl);
10304
10400
  url2.protocol = url2.protocol === "http:" ? "ws" : "wss";
10305
- url2.pathname = "/v8";
10401
+ url2.pathname = "/v7";
10306
10402
  url2.searchParams.set("roomId", roomId);
10307
10403
  if (authValue.type === "secret") {
10308
10404
  url2.searchParams.set("tok", authValue.token.raw);
@@ -11094,9 +11190,9 @@ function lsonToJson(value) {
11094
11190
  }
11095
11191
  return value;
11096
11192
  }
11097
- function deepLiveify(value) {
11193
+ function _deepLiveify(value) {
11098
11194
  if (Array.isArray(value)) {
11099
- return new LiveList(value.map(deepLiveify));
11195
+ return new LiveList(value.map(_deepLiveify));
11100
11196
  } else if (isPlainObject(value)) {
11101
11197
  const init = {};
11102
11198
  for (const key in value) {
@@ -11104,7 +11200,7 @@ function deepLiveify(value) {
11104
11200
  if (val === void 0) {
11105
11201
  continue;
11106
11202
  }
11107
- init[key] = deepLiveify(val);
11203
+ init[key] = _deepLiveify(val);
11108
11204
  }
11109
11205
  return new LiveObject(init);
11110
11206
  } else {
@@ -11141,7 +11237,7 @@ function patchLiveList(liveList, prev, next) {
11141
11237
  if (i > prevEnd) {
11142
11238
  if (i <= nextEnd) {
11143
11239
  while (i <= nextEnd) {
11144
- liveList.insert(deepLiveify(next[i]), i);
11240
+ liveList.insert(_deepLiveify(next[i]), i);
11145
11241
  i++;
11146
11242
  }
11147
11243
  }
@@ -11159,12 +11255,12 @@ function patchLiveList(liveList, prev, next) {
11159
11255
  if (isLiveObject(liveListNode) && isPlainObject(prevNode) && isPlainObject(nextNode)) {
11160
11256
  patchLiveObject(liveListNode, prevNode, nextNode);
11161
11257
  } else {
11162
- liveList.set(i, deepLiveify(nextNode));
11258
+ liveList.set(i, _deepLiveify(nextNode));
11163
11259
  }
11164
11260
  i++;
11165
11261
  }
11166
11262
  while (i <= nextEnd) {
11167
- liveList.insert(deepLiveify(next[i]), i);
11263
+ liveList.insert(_deepLiveify(next[i]), i);
11168
11264
  i++;
11169
11265
  }
11170
11266
  let localI = i;
@@ -11191,7 +11287,7 @@ Only serializable value can be synced with Liveblocks.`
11191
11287
  if (next === void 0) {
11192
11288
  liveObject.delete(key);
11193
11289
  } else if (value === void 0) {
11194
- liveObject.set(key, deepLiveify(next));
11290
+ liveObject.set(key, _deepLiveify(next));
11195
11291
  } else if (prev === next) {
11196
11292
  return;
11197
11293
  } else if (isLiveList(value) && Array.isArray(prev) && Array.isArray(next)) {
@@ -11199,7 +11295,7 @@ Only serializable value can be synced with Liveblocks.`
11199
11295
  } else if (isLiveObject(value) && isPlainObject(prev) && isPlainObject(next)) {
11200
11296
  patchLiveObject(value, prev, next);
11201
11297
  } else {
11202
- liveObject.set(key, deepLiveify(next));
11298
+ liveObject.set(key, _deepLiveify(next));
11203
11299
  }
11204
11300
  }
11205
11301
  function patchLiveObject(root, prev, next) {
@@ -11500,6 +11596,90 @@ function makePoller(callback, intervalMs, options) {
11500
11596
  };
11501
11597
  }
11502
11598
 
11599
+ // src/mutations.ts
11600
+ function generateOpsFromJson(nodes, mutation, actorId = 1) {
11601
+ const capturedOps = [];
11602
+ const pool = createManagedPool("mutation-temp", {
11603
+ getCurrentConnectionId: () => actorId,
11604
+ onDispatch: (ops) => {
11605
+ capturedOps.push(...ops);
11606
+ }
11607
+ });
11608
+ const root = LiveObject._fromItems(nodes, pool);
11609
+ if (isPlainObject(mutation)) {
11610
+ applyMutationToLiveObject(root, mutation);
11611
+ } else {
11612
+ throw new Error(
11613
+ "Root mutation must be an object. Use a nested key to update specific values."
11614
+ );
11615
+ }
11616
+ return capturedOps;
11617
+ }
11618
+ function applyMutationToLiveObject(target, mutation) {
11619
+ for (const key in mutation) {
11620
+ const mutationValue = mutation[key];
11621
+ if (mutationValue === void 0) {
11622
+ continue;
11623
+ }
11624
+ const existingValue = target.get(key);
11625
+ if (isLiveNode(mutationValue)) {
11626
+ target.set(key, mutationValue);
11627
+ continue;
11628
+ }
11629
+ if (isLiveObject(existingValue) && isPlainObject(mutationValue)) {
11630
+ applyMutationToLiveObject(
11631
+ existingValue,
11632
+ mutationValue
11633
+ );
11634
+ } else if (isLiveMap(existingValue) && isPlainObject(mutationValue)) {
11635
+ applyMutationToLiveMap(existingValue, mutationValue);
11636
+ } else if (isLiveList(existingValue) && Array.isArray(mutationValue)) {
11637
+ applyMutationToLiveList(existingValue, mutationValue);
11638
+ } else if (existingValue === void 0 && isPlainObject(mutationValue)) {
11639
+ const convertedValue = _deepLiveify(mutationValue);
11640
+ target.set(key, convertedValue);
11641
+ } else {
11642
+ target.set(key, mutationValue);
11643
+ }
11644
+ }
11645
+ }
11646
+ function applyMutationToLiveMap(target, mutation) {
11647
+ for (const key in mutation) {
11648
+ const mutationValue = mutation[key];
11649
+ if (mutationValue === void 0) {
11650
+ continue;
11651
+ }
11652
+ const existingValue = target.get(key);
11653
+ if (isLiveNode(mutationValue)) {
11654
+ target.set(key, mutationValue);
11655
+ continue;
11656
+ }
11657
+ if (isLiveObject(existingValue) && isPlainObject(mutationValue)) {
11658
+ applyMutationToLiveObject(
11659
+ existingValue,
11660
+ mutationValue
11661
+ );
11662
+ } else if (isLiveMap(existingValue) && isPlainObject(mutationValue)) {
11663
+ applyMutationToLiveMap(existingValue, mutationValue);
11664
+ } else if (isLiveList(existingValue) && Array.isArray(mutationValue)) {
11665
+ applyMutationToLiveList(existingValue, mutationValue);
11666
+ } else if (existingValue === void 0 && isPlainObject(mutationValue)) {
11667
+ const convertedValue = _deepLiveify(mutationValue);
11668
+ target.set(key, convertedValue);
11669
+ } else {
11670
+ const newValue = isLiveNode(mutationValue) ? mutationValue : mutationValue;
11671
+ target.set(key, newValue);
11672
+ }
11673
+ }
11674
+ }
11675
+ function applyMutationToLiveList(target, mutation) {
11676
+ target.clear();
11677
+ for (const item of mutation) {
11678
+ const liveItem = isLiveNode(item) ? item : item;
11679
+ target.push(liveItem);
11680
+ }
11681
+ }
11682
+
11503
11683
  // src/protocol/Subscriptions.ts
11504
11684
  function getSubscriptionKey(subscription, subjectId) {
11505
11685
  if (typeof subscription === "string") {
@@ -11572,6 +11752,7 @@ export {
11572
11752
  errorIf,
11573
11753
  findLastIndex,
11574
11754
  freeze,
11755
+ generateOpsFromJson,
11575
11756
  generateUrl,
11576
11757
  getMentionsFromCommentBody,
11577
11758
  getSubscriptionKey,
@@ -11601,7 +11782,6 @@ export {
11601
11782
  memoizeOnSuccess,
11602
11783
  nanoid,
11603
11784
  nn,
11604
- nodeStreamToCompactNodes,
11605
11785
  objectToQuery,
11606
11786
  patchLiveObjectKey,
11607
11787
  patchNotificationSettings,