@liveblocks/core 3.20.0-pre1 → 3.20.0-rc1

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.20.0-pre1";
9
+ var PKG_VERSION = "3.20.0-rc1";
10
10
  var PKG_FORMAT = "cjs";
11
11
 
12
12
  // src/dupe-detection.ts
@@ -701,6 +701,20 @@ var SortedList = class _SortedList {
701
701
  get length() {
702
702
  return this.#data.length;
703
703
  }
704
+ /**
705
+ * Whether the given value is present, by identity. O(log n) plus the length
706
+ * of any run of items that share its sort key (normally 1). Bisects on the
707
+ * value's own key, so it only finds values sitting at their sorted position,
708
+ * which is true for any item currently in the list.
709
+ */
710
+ includes(value) {
711
+ for (let i = bisectRight(this.#data, value, this.#lt) - 1; i >= 0 && !this.#lt(this.#data[i], value); i--) {
712
+ if (this.#data[i] === value) {
713
+ return true;
714
+ }
715
+ }
716
+ return false;
717
+ }
704
718
  *filter(predicate) {
705
719
  for (const item of this.#data) {
706
720
  if (predicate(item)) {
@@ -5502,6 +5516,9 @@ var OpCode = Object.freeze({
5502
5516
  function isIgnoredOp(op) {
5503
5517
  return op.type === OpCode.DELETE_CRDT && op.id === "ACK";
5504
5518
  }
5519
+ function isCreateOp(op) {
5520
+ return op.type === OpCode.CREATE_OBJECT || op.type === OpCode.CREATE_REGISTER || op.type === OpCode.CREATE_MAP || op.type === OpCode.CREATE_LIST;
5521
+ }
5505
5522
 
5506
5523
  // src/protocol/StorageNode.ts
5507
5524
  var CrdtType = Object.freeze({
@@ -5759,12 +5776,95 @@ function asPos(str) {
5759
5776
  return isPos(str) ? str : convertToPos(str);
5760
5777
  }
5761
5778
 
5779
+ // src/crdts/UnacknowledgedOps.ts
5780
+ var UnacknowledgedOps = class {
5781
+ // opId -> op
5782
+ #byOpId = /* @__PURE__ */ new Map();
5783
+ // position -> (opId -> Create op)
5784
+ #createOpsByPosition = /* @__PURE__ */ new Map();
5785
+ // parentId -> (opId -> Create op)
5786
+ #createOpsByParent = /* @__PURE__ */ new Map();
5787
+ #posKey(parentId, parentKey) {
5788
+ return `${parentId}
5789
+ ${parentKey}`;
5790
+ }
5791
+ get size() {
5792
+ return this.#byOpId.size;
5793
+ }
5794
+ /**
5795
+ * Mark the given Op as still unacknowledged.
5796
+ */
5797
+ add(op) {
5798
+ this.#byOpId.set(op.opId, op);
5799
+ if (isCreateOp(op)) {
5800
+ const posKey = this.#posKey(op.parentId, op.parentKey);
5801
+ let atPosition = this.#createOpsByPosition.get(posKey);
5802
+ if (atPosition === void 0) {
5803
+ atPosition = /* @__PURE__ */ new Map();
5804
+ this.#createOpsByPosition.set(posKey, atPosition);
5805
+ }
5806
+ atPosition.set(op.opId, op);
5807
+ let inParent = this.#createOpsByParent.get(op.parentId);
5808
+ if (inParent === void 0) {
5809
+ inParent = /* @__PURE__ */ new Map();
5810
+ this.#createOpsByParent.set(op.parentId, inParent);
5811
+ }
5812
+ inParent.set(op.opId, op);
5813
+ }
5814
+ }
5815
+ /**
5816
+ * Drop the op with the given opId from the set, because the server has
5817
+ * acknowledged it (confirmed our own op, or signalled it was seen but
5818
+ * ignored).
5819
+ */
5820
+ delete(opId) {
5821
+ const op = this.#byOpId.get(opId);
5822
+ if (op === void 0) {
5823
+ return;
5824
+ }
5825
+ this.#byOpId.delete(opId);
5826
+ if (isCreateOp(op)) {
5827
+ const posKey = this.#posKey(op.parentId, op.parentKey);
5828
+ const atPosition = this.#createOpsByPosition.get(posKey);
5829
+ _optionalChain([atPosition, 'optionalAccess', _111 => _111.delete, 'call', _112 => _112(opId)]);
5830
+ if (atPosition !== void 0 && atPosition.size === 0) {
5831
+ this.#createOpsByPosition.delete(posKey);
5832
+ }
5833
+ const inParent = this.#createOpsByParent.get(op.parentId);
5834
+ _optionalChain([inParent, 'optionalAccess', _113 => _113.delete, 'call', _114 => _114(opId)]);
5835
+ if (inParent !== void 0 && inParent.size === 0) {
5836
+ this.#createOpsByParent.delete(op.parentId);
5837
+ }
5838
+ }
5839
+ }
5840
+ /**
5841
+ * The still-unacknowledged Create ops with the given `parentId` and
5842
+ * `parentKey` (targeting one exact position), in dispatch order. O(1) lookup.
5843
+ * Empty if none.
5844
+ */
5845
+ getByParentIdAndKey(parentId, parentKey) {
5846
+ return _nullishCoalesce(_optionalChain([this, 'access', _115 => _115.#createOpsByPosition, 'access', _116 => _116.get, 'call', _117 => _117(this.#posKey(parentId, parentKey)), 'optionalAccess', _118 => _118.values, 'call', _119 => _119()]), () => ( []));
5847
+ }
5848
+ /**
5849
+ * The still-unacknowledged Create ops with the given `parentId` (across all
5850
+ * positions), in dispatch order. O(1) lookup. Empty if none.
5851
+ */
5852
+ getByParentId(parentId) {
5853
+ return _nullishCoalesce(_optionalChain([this, 'access', _120 => _120.#createOpsByParent, 'access', _121 => _121.get, 'call', _122 => _122(parentId), 'optionalAccess', _123 => _123.values, 'call', _124 => _124()]), () => ( []));
5854
+ }
5855
+ /** All still-unacknowledged ops, in dispatch order. */
5856
+ values() {
5857
+ return this.#byOpId.values();
5858
+ }
5859
+ };
5860
+
5762
5861
  // src/crdts/AbstractCrdt.ts
5763
5862
  function createManagedPool(roomId, options) {
5764
5863
  const {
5765
5864
  getCurrentConnectionId,
5766
5865
  onDispatch,
5767
- isStorageWritable = () => true
5866
+ isStorageWritable = () => true,
5867
+ unacknowledgedOps = new UnacknowledgedOps()
5768
5868
  } = options;
5769
5869
  let clock = 0;
5770
5870
  let opClock = 0;
@@ -5778,7 +5878,7 @@ function createManagedPool(roomId, options) {
5778
5878
  generateId: () => `${getCurrentConnectionId()}:${clock++}`,
5779
5879
  generateOpId: () => `${getCurrentConnectionId()}:${opClock++}`,
5780
5880
  dispatch(ops, reverse, storageUpdates) {
5781
- _optionalChain([onDispatch, 'optionalCall', _111 => _111(ops, reverse, storageUpdates)]);
5881
+ _optionalChain([onDispatch, 'optionalCall', _125 => _125(ops, reverse, storageUpdates)]);
5782
5882
  },
5783
5883
  assertStorageIsWritable: () => {
5784
5884
  if (!isStorageWritable()) {
@@ -5786,7 +5886,8 @@ function createManagedPool(roomId, options) {
5786
5886
  "Cannot write to storage with a read only user, please ensure the user has write permissions"
5787
5887
  );
5788
5888
  }
5789
- }
5889
+ },
5890
+ unacknowledgedOps
5790
5891
  };
5791
5892
  }
5792
5893
  function crdtAsLiveNode(value) {
@@ -6068,11 +6169,9 @@ function childNodeLt(a, b) {
6068
6169
  var LiveList = class _LiveList extends AbstractCrdt {
6069
6170
  #items;
6070
6171
  #implicitlyDeletedItems;
6071
- #unacknowledgedSets;
6072
6172
  constructor(items) {
6073
6173
  super();
6074
6174
  this.#implicitlyDeletedItems = /* @__PURE__ */ new WeakSet();
6075
- this.#unacknowledgedSets = /* @__PURE__ */ new Map();
6076
6175
  const nodes = [];
6077
6176
  let lastPos;
6078
6177
  for (const item of items) {
@@ -6102,12 +6201,13 @@ var LiveList = class _LiveList extends AbstractCrdt {
6102
6201
  }
6103
6202
  /**
6104
6203
  * @internal
6105
- * This function assumes that the resulting ops will be sent to the server if they have an 'opId'
6106
- * so we mutate _unacknowledgedSets to avoid potential flickering
6107
- * https://github.com/liveblocks/liveblocks/pull/1177
6204
+ * Serializes this list (and its children) into Create ops. Each child's
6205
+ * create is tagged with the "set" intent (in the loop below) so that a list
6206
+ * created and immediately mutated doesn't transiently re-show its initial
6207
+ * items (flicker, https://github.com/liveblocks/liveblocks/pull/1177).
6108
6208
  *
6109
- * This is quite unintuitive and should disappear as soon as
6110
- * we introduce an explicit LiveList.Set operation
6209
+ * This is quite unintuitive and should disappear as soon as we introduce an
6210
+ * explicit LiveList.Set operation.
6111
6211
  */
6112
6212
  _toOps(parentId, parentKey) {
6113
6213
  if (this._id === void 0) {
@@ -6123,7 +6223,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
6123
6223
  ops.push(op);
6124
6224
  for (const item of this.#items) {
6125
6225
  const parentKey2 = item._getParentKeyOrThrow();
6126
- const childOps = addIntentToOpTree(
6226
+ const childOps = addIntentToRootOp(
6127
6227
  item._toOps(this._id, parentKey2),
6128
6228
  "set"
6129
6229
  );
@@ -6167,6 +6267,28 @@ var LiveList = class _LiveList extends AbstractCrdt {
6167
6267
  (item) => item._getParentKeyOrThrow() === position
6168
6268
  );
6169
6269
  }
6270
+ /**
6271
+ * The opId of this list's still-unacknowledged "set" op at the given position,
6272
+ * or undefined if none. Derived from the room's unacknowledgedOps (the single
6273
+ * source of truth) rather than tracked in a per-instance map. The pool's
6274
+ * position index already scopes to this list's (parentId, position); the last
6275
+ * match wins, matching the original last-write-wins map semantics.
6276
+ */
6277
+ #unacknowledgedSetOpIdAt(position) {
6278
+ if (this._pool === void 0 || this._id === void 0) {
6279
+ return void 0;
6280
+ }
6281
+ let opId;
6282
+ for (const op of this._pool.unacknowledgedOps.getByParentIdAndKey(
6283
+ this._id,
6284
+ position
6285
+ )) {
6286
+ if (op.intent === "set") {
6287
+ opId = op.opId;
6288
+ }
6289
+ }
6290
+ return opId;
6291
+ }
6170
6292
  /** @internal */
6171
6293
  _attach(id, pool) {
6172
6294
  super._attach(id, pool);
@@ -6247,13 +6369,9 @@ var LiveList = class _LiveList extends AbstractCrdt {
6247
6369
  if (deletedDelta) {
6248
6370
  delta.push(deletedDelta);
6249
6371
  }
6250
- const unacknowledgedOpId = this.#unacknowledgedSets.get(op.parentKey);
6251
- if (unacknowledgedOpId !== void 0) {
6252
- if (unacknowledgedOpId !== op.opId) {
6253
- return delta.length === 0 ? { modified: false } : { modified: makeUpdate(this, delta), reverse: [] };
6254
- } else {
6255
- this.#unacknowledgedSets.delete(op.parentKey);
6256
- }
6372
+ const unacknowledgedOpId = this.#unacknowledgedSetOpIdAt(op.parentKey);
6373
+ if (unacknowledgedOpId !== void 0 && unacknowledgedOpId !== op.opId) {
6374
+ return delta.length === 0 ? { modified: false } : { modified: makeUpdate(this, delta), reverse: [] };
6257
6375
  }
6258
6376
  const indexOfItemWithSamePosition = this._indexOfPosition(op.parentKey);
6259
6377
  const existingItem = this.#items.find((item) => item._id === op.id);
@@ -6334,7 +6452,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
6334
6452
  }
6335
6453
  return result.modified.updates[0];
6336
6454
  }
6337
- #applyRemoteInsert(op) {
6455
+ #applyRemoteInsert(op, fromSnapshot) {
6338
6456
  if (this._pool === void 0) {
6339
6457
  throw new Error("Can't attach child if managed pool is not present");
6340
6458
  }
@@ -6344,11 +6462,82 @@ var LiveList = class _LiveList extends AbstractCrdt {
6344
6462
  this.#shiftItemPosition(existingItemIndex, key);
6345
6463
  }
6346
6464
  const { newItem, newIndex } = this.#createAttachItemAndSort(op, key);
6465
+ const bumpDeltas = fromSnapshot ? [] : this.#bumpUnackedPushesAbove(key);
6347
6466
  return {
6348
- modified: makeUpdate(this, [insertDelta(newIndex, newItem)]),
6467
+ modified: makeUpdate(this, [
6468
+ insertDelta(newIndex, newItem),
6469
+ ...bumpDeltas
6470
+ ]),
6349
6471
  reverse: []
6350
6472
  };
6351
6473
  }
6474
+ /**
6475
+ * This list's own still-unacknowledged pushed items (their `intent: "push"`
6476
+ * Create op is still pending in the room's unacknowledgedOps). Derived from
6477
+ * the single source of truth, so an item drops out the instant its op is
6478
+ * acked, with no per-instance membership to leak. Yielded in push order.
6479
+ *
6480
+ * Restricted to items currently in `#items`: a pushed node whose op is still
6481
+ * pending may have been pulled out of the list (e.g. implicitly deleted by a
6482
+ * remote set, or removed by an undo) while still living in the pool, and such
6483
+ * a node must not be repositioned.
6484
+ */
6485
+ *#unackedPushNodes() {
6486
+ if (this._pool === void 0 || this._id === void 0) {
6487
+ return;
6488
+ }
6489
+ for (const op of this._pool.unacknowledgedOps.getByParentId(this._id)) {
6490
+ if (op.intent !== "push") {
6491
+ continue;
6492
+ }
6493
+ const node = this._pool.getNode(op.id);
6494
+ if (node !== void 0 && this.#items.includes(node)) {
6495
+ yield node;
6496
+ }
6497
+ }
6498
+ }
6499
+ /**
6500
+ * Optimistic no-flip for pushed items. When a remote op lands at or below my
6501
+ * still-unacked pushed items, those items must end up *after* it: FIFO plus
6502
+ * the room's serial processing guarantee the remote was processed first, so
6503
+ * my unacked pushes belong behind it. Re-chain the whole unacked-push block,
6504
+ * in push order, to sit after the highest confirmed sibling, so it keeps
6505
+ * rendering as a contiguous tail instead of getting interleaved. Local-only;
6506
+ * the real acks overwrite these keys with the (identical) server keys.
6507
+ */
6508
+ #bumpUnackedPushesAbove(remoteKey) {
6509
+ const pending = new Set(this.#unackedPushNodes());
6510
+ if (pending.size === 0) {
6511
+ return [];
6512
+ }
6513
+ let minPending;
6514
+ for (const node of pending) {
6515
+ const pos = node._parentPos;
6516
+ if (minPending === void 0 || pos < minPending) {
6517
+ minPending = pos;
6518
+ }
6519
+ }
6520
+ if (remoteKey < nn(minPending)) {
6521
+ return [];
6522
+ }
6523
+ let base;
6524
+ for (const item of this.#items) {
6525
+ if (!pending.has(item)) {
6526
+ base = item._parentPos;
6527
+ }
6528
+ }
6529
+ const deltas = [];
6530
+ for (const node of pending) {
6531
+ const previousIndex = this.#items.findIndex((item) => item === node);
6532
+ base = makePosition(base);
6533
+ this.#updateItemPosition(node, base);
6534
+ const index = this.#items.findIndex((item) => item === node);
6535
+ if (index !== previousIndex) {
6536
+ deltas.push(moveDelta(previousIndex, index, node));
6537
+ }
6538
+ }
6539
+ return deltas;
6540
+ }
6352
6541
  #applyInsertAck(op) {
6353
6542
  const existingItem = this.#items.find((item) => item._id === op.id);
6354
6543
  const key = asPos(op.parentKey);
@@ -6403,7 +6592,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
6403
6592
  #applyInsertUndoRedo(op) {
6404
6593
  const { id, parentKey: key } = op;
6405
6594
  const child = creationOpToLiveNode(op);
6406
- if (_optionalChain([this, 'access', _112 => _112._pool, 'optionalAccess', _113 => _113.getNode, 'call', _114 => _114(id)]) !== void 0) {
6595
+ if (_optionalChain([this, 'access', _126 => _126._pool, 'optionalAccess', _127 => _127.getNode, 'call', _128 => _128(id)]) !== void 0) {
6407
6596
  return { modified: false };
6408
6597
  }
6409
6598
  child._attach(id, nn(this._pool));
@@ -6411,8 +6600,8 @@ var LiveList = class _LiveList extends AbstractCrdt {
6411
6600
  const existingItemIndex = this._indexOfPosition(key);
6412
6601
  let newKey = key;
6413
6602
  if (existingItemIndex !== -1) {
6414
- const before2 = _optionalChain([this, 'access', _115 => _115.#items, 'access', _116 => _116.at, 'call', _117 => _117(existingItemIndex), 'optionalAccess', _118 => _118._parentPos]);
6415
- const after2 = _optionalChain([this, 'access', _119 => _119.#items, 'access', _120 => _120.at, 'call', _121 => _121(existingItemIndex + 1), 'optionalAccess', _122 => _122._parentPos]);
6603
+ const before2 = _optionalChain([this, 'access', _129 => _129.#items, 'access', _130 => _130.at, 'call', _131 => _131(existingItemIndex), 'optionalAccess', _132 => _132._parentPos]);
6604
+ const after2 = _optionalChain([this, 'access', _133 => _133.#items, 'access', _134 => _134.at, 'call', _135 => _135(existingItemIndex + 1), 'optionalAccess', _136 => _136._parentPos]);
6416
6605
  newKey = makePosition(before2, after2);
6417
6606
  child._setParentLink(this, newKey);
6418
6607
  }
@@ -6426,10 +6615,9 @@ var LiveList = class _LiveList extends AbstractCrdt {
6426
6615
  #applySetUndoRedo(op) {
6427
6616
  const { id, parentKey: key } = op;
6428
6617
  const child = creationOpToLiveNode(op);
6429
- if (_optionalChain([this, 'access', _123 => _123._pool, 'optionalAccess', _124 => _124.getNode, 'call', _125 => _125(id)]) !== void 0) {
6618
+ if (_optionalChain([this, 'access', _137 => _137._pool, 'optionalAccess', _138 => _138.getNode, 'call', _139 => _139(id)]) !== void 0) {
6430
6619
  return { modified: false };
6431
6620
  }
6432
- this.#unacknowledgedSets.set(key, nn(op.opId));
6433
6621
  const indexOfItemWithSameKey = this._indexOfPosition(key);
6434
6622
  child._attach(id, nn(this._pool));
6435
6623
  child._setParentLink(this, key);
@@ -6439,7 +6627,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
6439
6627
  existingItem._detach();
6440
6628
  this.#items.remove(existingItem);
6441
6629
  this.#items.add(child);
6442
- const reverse = addIntentToOpTree(
6630
+ const reverse = addIntentToRootOp(
6443
6631
  existingItem._toOps(nn(this._id), key),
6444
6632
  "set",
6445
6633
  op.id
@@ -6466,7 +6654,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
6466
6654
  }
6467
6655
  }
6468
6656
  /** @internal */
6469
- _attachChild(op, source) {
6657
+ _attachChild(op, source, fromSnapshot = false) {
6470
6658
  if (this._pool === void 0) {
6471
6659
  throw new Error("Can't attach child if managed pool is not present");
6472
6660
  }
@@ -6481,7 +6669,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
6481
6669
  }
6482
6670
  } else {
6483
6671
  if (source === 1 /* THEIRS */) {
6484
- result = this.#applyRemoteInsert(op);
6672
+ result = this.#applyRemoteInsert(op, fromSnapshot);
6485
6673
  } else if (source === 2 /* OURS */) {
6486
6674
  result = this.#applyInsertAck(op);
6487
6675
  } else {
@@ -6548,7 +6736,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
6548
6736
  } else {
6549
6737
  this.#updateItemPositionAt(
6550
6738
  existingItemIndex,
6551
- makePosition(newKey, _optionalChain([this, 'access', _126 => _126.#items, 'access', _127 => _127.at, 'call', _128 => _128(existingItemIndex + 1), 'optionalAccess', _129 => _129._parentPos]))
6739
+ makePosition(newKey, _optionalChain([this, 'access', _140 => _140.#items, 'access', _141 => _141.at, 'call', _142 => _142(existingItemIndex + 1), 'optionalAccess', _143 => _143._parentPos]))
6552
6740
  );
6553
6741
  const previousIndex = this.#items.findIndex((item) => item === child);
6554
6742
  this.#updateItemPosition(child, newKey);
@@ -6575,7 +6763,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
6575
6763
  this,
6576
6764
  makePosition(
6577
6765
  newKey,
6578
- _optionalChain([this, 'access', _130 => _130.#items, 'access', _131 => _131.at, 'call', _132 => _132(existingItemIndex + 1), 'optionalAccess', _133 => _133._parentPos])
6766
+ _optionalChain([this, 'access', _144 => _144.#items, 'access', _145 => _145.at, 'call', _146 => _146(existingItemIndex + 1), 'optionalAccess', _147 => _147._parentPos])
6579
6767
  )
6580
6768
  );
6581
6769
  this.#items.reposition(existingItem);
@@ -6599,7 +6787,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
6599
6787
  existingItemIndex,
6600
6788
  makePosition(
6601
6789
  newKey,
6602
- _optionalChain([this, 'access', _134 => _134.#items, 'access', _135 => _135.at, 'call', _136 => _136(existingItemIndex + 1), 'optionalAccess', _137 => _137._parentPos])
6790
+ _optionalChain([this, 'access', _148 => _148.#items, 'access', _149 => _149.at, 'call', _150 => _150(existingItemIndex + 1), 'optionalAccess', _151 => _151._parentPos])
6603
6791
  )
6604
6792
  );
6605
6793
  }
@@ -6627,7 +6815,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
6627
6815
  if (existingItemIndex !== -1) {
6628
6816
  actualNewKey = makePosition(
6629
6817
  newKey,
6630
- _optionalChain([this, 'access', _138 => _138.#items, 'access', _139 => _139.at, 'call', _140 => _140(existingItemIndex + 1), 'optionalAccess', _141 => _141._parentPos])
6818
+ _optionalChain([this, 'access', _152 => _152.#items, 'access', _153 => _153.at, 'call', _154 => _154(existingItemIndex + 1), 'optionalAccess', _155 => _155._parentPos])
6631
6819
  );
6632
6820
  }
6633
6821
  this.#updateItemPosition(child, actualNewKey);
@@ -6701,14 +6889,14 @@ var LiveList = class _LiveList extends AbstractCrdt {
6701
6889
  * instead of resolving its position against the client's stale view.
6702
6890
  */
6703
6891
  #injectAt(element, index, intent) {
6704
- _optionalChain([this, 'access', _142 => _142._pool, 'optionalAccess', _143 => _143.assertStorageIsWritable, 'call', _144 => _144()]);
6892
+ _optionalChain([this, 'access', _156 => _156._pool, 'optionalAccess', _157 => _157.assertStorageIsWritable, 'call', _158 => _158()]);
6705
6893
  if (index < 0 || index > this.#items.length) {
6706
6894
  throw new Error(
6707
6895
  `Cannot insert list item at index "${index}". index should be between 0 and ${this.#items.length}`
6708
6896
  );
6709
6897
  }
6710
- const before2 = _optionalChain([this, 'access', _145 => _145.#items, 'access', _146 => _146.at, 'call', _147 => _147(index - 1), 'optionalAccess', _148 => _148._parentPos]);
6711
- const after2 = _optionalChain([this, 'access', _149 => _149.#items, 'access', _150 => _150.at, 'call', _151 => _151(index), 'optionalAccess', _152 => _152._parentPos]);
6898
+ const before2 = _optionalChain([this, 'access', _159 => _159.#items, 'access', _160 => _160.at, 'call', _161 => _161(index - 1), 'optionalAccess', _162 => _162._parentPos]);
6899
+ const after2 = _optionalChain([this, 'access', _163 => _163.#items, 'access', _164 => _164.at, 'call', _165 => _165(index), 'optionalAccess', _166 => _166._parentPos]);
6712
6900
  const position = makePosition(before2, after2);
6713
6901
  const value = lsonToLiveNode(element);
6714
6902
  value._setParentLink(this, position);
@@ -6718,7 +6906,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
6718
6906
  value._attach(id, this._pool);
6719
6907
  const ops = value._toOpsWithOpId(this._id, position, this._pool);
6720
6908
  this._pool.dispatch(
6721
- intent === "push" ? addIntentToOpTree(ops, "push") : ops,
6909
+ intent === "push" ? addIntentToRootOp(ops, "push") : ops,
6722
6910
  [{ type: OpCode.DELETE_CRDT, id }],
6723
6911
  /* @__PURE__ */ new Map([
6724
6912
  [this._id, makeUpdate(this, [insertDelta(index, value)])]
@@ -6732,7 +6920,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
6732
6920
  * @param targetIndex The index where the element should be after moving.
6733
6921
  */
6734
6922
  move(index, targetIndex) {
6735
- _optionalChain([this, 'access', _153 => _153._pool, 'optionalAccess', _154 => _154.assertStorageIsWritable, 'call', _155 => _155()]);
6923
+ _optionalChain([this, 'access', _167 => _167._pool, 'optionalAccess', _168 => _168.assertStorageIsWritable, 'call', _169 => _169()]);
6736
6924
  if (targetIndex < 0) {
6737
6925
  throw new Error("targetIndex cannot be less than 0");
6738
6926
  }
@@ -6750,11 +6938,11 @@ var LiveList = class _LiveList extends AbstractCrdt {
6750
6938
  let beforePosition = null;
6751
6939
  let afterPosition = null;
6752
6940
  if (index < targetIndex) {
6753
- afterPosition = targetIndex === this.#items.length - 1 ? void 0 : _optionalChain([this, 'access', _156 => _156.#items, 'access', _157 => _157.at, 'call', _158 => _158(targetIndex + 1), 'optionalAccess', _159 => _159._parentPos]);
6941
+ afterPosition = targetIndex === this.#items.length - 1 ? void 0 : _optionalChain([this, 'access', _170 => _170.#items, 'access', _171 => _171.at, 'call', _172 => _172(targetIndex + 1), 'optionalAccess', _173 => _173._parentPos]);
6754
6942
  beforePosition = this.#items.at(targetIndex)._parentPos;
6755
6943
  } else {
6756
6944
  afterPosition = this.#items.at(targetIndex)._parentPos;
6757
- beforePosition = targetIndex === 0 ? void 0 : _optionalChain([this, 'access', _160 => _160.#items, 'access', _161 => _161.at, 'call', _162 => _162(targetIndex - 1), 'optionalAccess', _163 => _163._parentPos]);
6945
+ beforePosition = targetIndex === 0 ? void 0 : _optionalChain([this, 'access', _174 => _174.#items, 'access', _175 => _175.at, 'call', _176 => _176(targetIndex - 1), 'optionalAccess', _177 => _177._parentPos]);
6758
6946
  }
6759
6947
  const position = makePosition(beforePosition, afterPosition);
6760
6948
  const item = this.#items.at(index);
@@ -6789,7 +6977,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
6789
6977
  * @param index The index of the element to delete
6790
6978
  */
6791
6979
  delete(index) {
6792
- _optionalChain([this, 'access', _164 => _164._pool, 'optionalAccess', _165 => _165.assertStorageIsWritable, 'call', _166 => _166()]);
6980
+ _optionalChain([this, 'access', _178 => _178._pool, 'optionalAccess', _179 => _179.assertStorageIsWritable, 'call', _180 => _180()]);
6793
6981
  if (index < 0 || index >= this.#items.length) {
6794
6982
  throw new Error(
6795
6983
  `Cannot delete list item at index "${index}". index should be between 0 and ${this.#items.length - 1}`
@@ -6822,7 +7010,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
6822
7010
  }
6823
7011
  }
6824
7012
  clear() {
6825
- _optionalChain([this, 'access', _167 => _167._pool, 'optionalAccess', _168 => _168.assertStorageIsWritable, 'call', _169 => _169()]);
7013
+ _optionalChain([this, 'access', _181 => _181._pool, 'optionalAccess', _182 => _182.assertStorageIsWritable, 'call', _183 => _183()]);
6826
7014
  if (this._pool) {
6827
7015
  const ops = [];
6828
7016
  const reverseOps = [];
@@ -6856,7 +7044,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
6856
7044
  }
6857
7045
  }
6858
7046
  set(index, item) {
6859
- _optionalChain([this, 'access', _170 => _170._pool, 'optionalAccess', _171 => _171.assertStorageIsWritable, 'call', _172 => _172()]);
7047
+ _optionalChain([this, 'access', _184 => _184._pool, 'optionalAccess', _185 => _185.assertStorageIsWritable, 'call', _186 => _186()]);
6860
7048
  if (index < 0 || index >= this.#items.length) {
6861
7049
  throw new Error(
6862
7050
  `Cannot set list item at index "${index}". index should be between 0 and ${this.#items.length - 1}`
@@ -6876,13 +7064,12 @@ var LiveList = class _LiveList extends AbstractCrdt {
6876
7064
  value._attach(id, this._pool);
6877
7065
  const storageUpdates = /* @__PURE__ */ new Map();
6878
7066
  storageUpdates.set(this._id, makeUpdate(this, [setDelta(index, value)]));
6879
- const ops = addIntentToOpTree(
7067
+ const ops = addIntentToRootOp(
6880
7068
  value._toOpsWithOpId(this._id, position, this._pool),
6881
7069
  "set",
6882
7070
  existingId
6883
7071
  );
6884
- this.#unacknowledgedSets.set(position, nn(ops[0].opId));
6885
- const reverseOps = addIntentToOpTree(
7072
+ const reverseOps = addIntentToRootOp(
6886
7073
  existingItem._toOps(this._id, position),
6887
7074
  "set",
6888
7075
  id
@@ -7016,7 +7203,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
7016
7203
  #shiftItemPosition(index, key) {
7017
7204
  const shiftedPosition = makePosition(
7018
7205
  key,
7019
- this.#items.length > index + 1 ? _optionalChain([this, 'access', _173 => _173.#items, 'access', _174 => _174.at, 'call', _175 => _175(index + 1), 'optionalAccess', _176 => _176._parentPos]) : void 0
7206
+ this.#items.length > index + 1 ? _optionalChain([this, 'access', _187 => _187.#items, 'access', _188 => _188.at, 'call', _189 => _189(index + 1), 'optionalAccess', _190 => _190._parentPos]) : void 0
7020
7207
  );
7021
7208
  this.#updateItemPositionAt(index, shiftedPosition);
7022
7209
  }
@@ -7085,7 +7272,7 @@ function moveDelta(previousIndex, index, item) {
7085
7272
  previousIndex
7086
7273
  };
7087
7274
  }
7088
- function addIntentToOpTree(ops, intent, deletedId) {
7275
+ function addIntentToRootOp(ops, intent, deletedId) {
7089
7276
  return ops.map((op, index) => {
7090
7277
  if (index === 0) {
7091
7278
  const firstOp = op;
@@ -7265,7 +7452,7 @@ var LiveMap = class _LiveMap extends AbstractCrdt {
7265
7452
  * @param value The value of the element to add. Should be serializable to JSON.
7266
7453
  */
7267
7454
  set(key, value) {
7268
- _optionalChain([this, 'access', _177 => _177._pool, 'optionalAccess', _178 => _178.assertStorageIsWritable, 'call', _179 => _179()]);
7455
+ _optionalChain([this, 'access', _191 => _191._pool, 'optionalAccess', _192 => _192.assertStorageIsWritable, 'call', _193 => _193()]);
7269
7456
  const oldValue = this.#map.get(key);
7270
7457
  if (oldValue) {
7271
7458
  oldValue._detach();
@@ -7311,7 +7498,7 @@ var LiveMap = class _LiveMap extends AbstractCrdt {
7311
7498
  * @returns true if an element existed and has been removed, or false if the element does not exist.
7312
7499
  */
7313
7500
  delete(key) {
7314
- _optionalChain([this, 'access', _180 => _180._pool, 'optionalAccess', _181 => _181.assertStorageIsWritable, 'call', _182 => _182()]);
7501
+ _optionalChain([this, 'access', _194 => _194._pool, 'optionalAccess', _195 => _195.assertStorageIsWritable, 'call', _196 => _196()]);
7315
7502
  const item = this.#map.get(key);
7316
7503
  if (item === void 0) {
7317
7504
  return false;
@@ -7922,20 +8109,20 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
7922
8109
  * Caveat: this method will not add changes to the undo/redo stack.
7923
8110
  */
7924
8111
  setLocal(key, value) {
7925
- _optionalChain([this, 'access', _183 => _183._pool, 'optionalAccess', _184 => _184.assertStorageIsWritable, 'call', _185 => _185()]);
8112
+ _optionalChain([this, 'access', _197 => _197._pool, 'optionalAccess', _198 => _198.assertStorageIsWritable, 'call', _199 => _199()]);
7926
8113
  const deleteResult = this.#prepareDelete(key);
7927
8114
  this.#local.set(key, value);
7928
8115
  this.invalidate();
7929
8116
  if (this._pool !== void 0 && this._id !== void 0) {
7930
- const ops = _nullishCoalesce(_optionalChain([deleteResult, 'optionalAccess', _186 => _186[0]]), () => ( []));
7931
- const reverse = _nullishCoalesce(_optionalChain([deleteResult, 'optionalAccess', _187 => _187[1]]), () => ( []));
7932
- const storageUpdates = _nullishCoalesce(_optionalChain([deleteResult, 'optionalAccess', _188 => _188[2]]), () => ( /* @__PURE__ */ new Map()));
8117
+ const ops = _nullishCoalesce(_optionalChain([deleteResult, 'optionalAccess', _200 => _200[0]]), () => ( []));
8118
+ const reverse = _nullishCoalesce(_optionalChain([deleteResult, 'optionalAccess', _201 => _201[1]]), () => ( []));
8119
+ const storageUpdates = _nullishCoalesce(_optionalChain([deleteResult, 'optionalAccess', _202 => _202[2]]), () => ( /* @__PURE__ */ new Map()));
7933
8120
  const existing = storageUpdates.get(this._id);
7934
8121
  storageUpdates.set(this._id, {
7935
8122
  node: this,
7936
8123
  type: "LiveObject",
7937
8124
  updates: {
7938
- ..._optionalChain([existing, 'optionalAccess', _189 => _189.updates]),
8125
+ ..._optionalChain([existing, 'optionalAccess', _203 => _203.updates]),
7939
8126
  [key]: { type: "update" }
7940
8127
  }
7941
8128
  });
@@ -7955,7 +8142,7 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
7955
8142
  * #synced or pool/id are unavailable. Does NOT dispatch.
7956
8143
  */
7957
8144
  #prepareDelete(key) {
7958
- _optionalChain([this, 'access', _190 => _190._pool, 'optionalAccess', _191 => _191.assertStorageIsWritable, 'call', _192 => _192()]);
8145
+ _optionalChain([this, 'access', _204 => _204._pool, 'optionalAccess', _205 => _205.assertStorageIsWritable, 'call', _206 => _206()]);
7959
8146
  const k = key;
7960
8147
  if (this.#local.has(k) && !this.#synced.has(k)) {
7961
8148
  const oldValue2 = this.#local.get(k);
@@ -8031,7 +8218,7 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
8031
8218
  const result = this.#prepareDelete(key);
8032
8219
  if (result) {
8033
8220
  const [ops, reverse, storageUpdates] = result;
8034
- _optionalChain([this, 'access', _193 => _193._pool, 'optionalAccess', _194 => _194.dispatch, 'call', _195 => _195(ops, reverse, storageUpdates)]);
8221
+ _optionalChain([this, 'access', _207 => _207._pool, 'optionalAccess', _208 => _208.dispatch, 'call', _209 => _209(ops, reverse, storageUpdates)]);
8035
8222
  }
8036
8223
  }
8037
8224
  /**
@@ -8039,7 +8226,7 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
8039
8226
  * @param patch The object used to overrides properties
8040
8227
  */
8041
8228
  update(patch) {
8042
- _optionalChain([this, 'access', _196 => _196._pool, 'optionalAccess', _197 => _197.assertStorageIsWritable, 'call', _198 => _198()]);
8229
+ _optionalChain([this, 'access', _210 => _210._pool, 'optionalAccess', _211 => _211.assertStorageIsWritable, 'call', _212 => _212()]);
8043
8230
  if (_LiveObject.detectLargeObjects) {
8044
8231
  const data = {};
8045
8232
  for (const [key, value] of this.#synced) {
@@ -8329,6 +8516,31 @@ function lsonToLiveNode(value) {
8329
8516
  return new LiveRegister(value);
8330
8517
  }
8331
8518
  }
8519
+ function dumpPool(pool) {
8520
+ const rows = Array.from(pool.nodes.values(), (node) => {
8521
+ const parent = node.parent;
8522
+ const parentId = parent.type === "HasParent" ? _nullishCoalesce(parent.node._id, () => ( "?")) : parent.type === "Orphaned" ? "<orphaned>" : "-";
8523
+ let value;
8524
+ if (node instanceof LiveRegister) {
8525
+ value = stringifyOrLog(node.data);
8526
+ } else if (node instanceof LiveList) {
8527
+ value = "<LiveList>";
8528
+ } else if (node instanceof LiveMap) {
8529
+ value = "<LiveMap>";
8530
+ } else {
8531
+ value = "<LiveObject>";
8532
+ }
8533
+ return { id: nn(node._id), parentId, key: _nullishCoalesce(node._parentKey, () => ( "")), value };
8534
+ });
8535
+ rows.sort((a, b) => {
8536
+ if (a.parentId !== b.parentId) return a.parentId < b.parentId ? -1 : 1;
8537
+ if (a.key !== b.key) return a.key < b.key ? -1 : 1;
8538
+ return 0;
8539
+ });
8540
+ return rows.map(
8541
+ (r) => ` ${r.id} parent=${r.parentId} key=${r.key || "\u2014"} ${r.value}`
8542
+ ).join("\n");
8543
+ }
8332
8544
  function getTreesDiffOperations(currentItems, newItems) {
8333
8545
  const ops = [];
8334
8546
  currentItems.forEach((_, id) => {
@@ -8456,7 +8668,7 @@ function sendToPanel(message, options) {
8456
8668
  ...message,
8457
8669
  source: "liveblocks-devtools-client"
8458
8670
  };
8459
- if (!(_optionalChain([options, 'optionalAccess', _199 => _199.force]) || _bridgeActive)) {
8671
+ if (!(_optionalChain([options, 'optionalAccess', _213 => _213.force]) || _bridgeActive)) {
8460
8672
  return;
8461
8673
  }
8462
8674
  window.postMessage(fullMsg, "*");
@@ -8464,7 +8676,7 @@ function sendToPanel(message, options) {
8464
8676
  var eventSource = makeEventSource();
8465
8677
  if (process.env.NODE_ENV !== "production" && typeof window !== "undefined") {
8466
8678
  window.addEventListener("message", (event) => {
8467
- if (event.source === window && _optionalChain([event, 'access', _200 => _200.data, 'optionalAccess', _201 => _201.source]) === "liveblocks-devtools-panel") {
8679
+ if (event.source === window && _optionalChain([event, 'access', _214 => _214.data, 'optionalAccess', _215 => _215.source]) === "liveblocks-devtools-panel") {
8468
8680
  eventSource.notify(event.data);
8469
8681
  } else {
8470
8682
  }
@@ -8606,7 +8818,7 @@ function fullSync(room) {
8606
8818
  msg: "room::sync::full",
8607
8819
  roomId: room.id,
8608
8820
  status: room.getStatus(),
8609
- storage: _nullishCoalesce(_optionalChain([root, 'optionalAccess', _202 => _202.toTreeNode, 'call', _203 => _203("root"), 'access', _204 => _204.payload]), () => ( null)),
8821
+ storage: _nullishCoalesce(_optionalChain([root, 'optionalAccess', _216 => _216.toTreeNode, 'call', _217 => _217("root"), 'access', _218 => _218.payload]), () => ( null)),
8610
8822
  me,
8611
8823
  others
8612
8824
  });
@@ -9285,15 +9497,15 @@ function installBackgroundTabSpy() {
9285
9497
  const doc = typeof document !== "undefined" ? document : void 0;
9286
9498
  const inBackgroundSince = { current: null };
9287
9499
  function onVisibilityChange() {
9288
- if (_optionalChain([doc, 'optionalAccess', _205 => _205.visibilityState]) === "hidden") {
9500
+ if (_optionalChain([doc, 'optionalAccess', _219 => _219.visibilityState]) === "hidden") {
9289
9501
  inBackgroundSince.current = _nullishCoalesce(inBackgroundSince.current, () => ( Date.now()));
9290
9502
  } else {
9291
9503
  inBackgroundSince.current = null;
9292
9504
  }
9293
9505
  }
9294
- _optionalChain([doc, 'optionalAccess', _206 => _206.addEventListener, 'call', _207 => _207("visibilitychange", onVisibilityChange)]);
9506
+ _optionalChain([doc, 'optionalAccess', _220 => _220.addEventListener, 'call', _221 => _221("visibilitychange", onVisibilityChange)]);
9295
9507
  const unsub = () => {
9296
- _optionalChain([doc, 'optionalAccess', _208 => _208.removeEventListener, 'call', _209 => _209("visibilitychange", onVisibilityChange)]);
9508
+ _optionalChain([doc, 'optionalAccess', _222 => _222.removeEventListener, 'call', _223 => _223("visibilitychange", onVisibilityChange)]);
9297
9509
  };
9298
9510
  return [inBackgroundSince, unsub];
9299
9511
  }
@@ -9338,6 +9550,7 @@ function createRoom(options, config) {
9338
9550
  delegates,
9339
9551
  config.enableDebugLogging
9340
9552
  );
9553
+ const unacknowledgedOps = new UnacknowledgedOps();
9341
9554
  const context = {
9342
9555
  buffer: {
9343
9556
  flushTimerID: void 0,
@@ -9365,14 +9578,15 @@ function createRoom(options, config) {
9365
9578
  pool: createManagedPool(roomId, {
9366
9579
  getCurrentConnectionId,
9367
9580
  onDispatch,
9368
- isStorageWritable
9581
+ isStorageWritable,
9582
+ unacknowledgedOps
9369
9583
  }),
9370
9584
  root: void 0,
9371
9585
  undoStack: [],
9372
9586
  redoStack: [],
9373
9587
  pausedHistory: null,
9374
9588
  activeBatch: null,
9375
- unacknowledgedOps: /* @__PURE__ */ new Map()
9589
+ unacknowledgedOps
9376
9590
  };
9377
9591
  const nodeMapBuffer = makeNodeMapBuffer();
9378
9592
  const stopwatch = config.enableDebugLogging ? makeStopWatch() : void 0;
@@ -9484,7 +9698,7 @@ function createRoom(options, config) {
9484
9698
  }
9485
9699
  }
9486
9700
  function isStorageWritable() {
9487
- const scopes = _optionalChain([context, 'access', _210 => _210.dynamicSessionInfoSig, 'access', _211 => _211.get, 'call', _212 => _212(), 'optionalAccess', _213 => _213.scopes]);
9701
+ const scopes = _optionalChain([context, 'access', _224 => _224.dynamicSessionInfoSig, 'access', _225 => _225.get, 'call', _226 => _226(), 'optionalAccess', _227 => _227.scopes]);
9488
9702
  return scopes !== void 0 ? canWriteStorage(scopes) : true;
9489
9703
  }
9490
9704
  const eventHub = {
@@ -9580,7 +9794,11 @@ function createRoom(options, config) {
9580
9794
  currentItems.set(id, crdt._serialize());
9581
9795
  }
9582
9796
  const ops = getTreesDiffOperations(currentItems, nodes);
9583
- const result = applyRemoteOps(ops);
9797
+ const result = applyRemoteOps(
9798
+ ops,
9799
+ /* fromSnapshot */
9800
+ true
9801
+ );
9584
9802
  notify(result.updates);
9585
9803
  } else {
9586
9804
  context.root = LiveObject._fromItems(
@@ -9588,7 +9806,7 @@ function createRoom(options, config) {
9588
9806
  context.pool
9589
9807
  );
9590
9808
  }
9591
- const canWrite = _nullishCoalesce(_optionalChain([self, 'access', _214 => _214.get, 'call', _215 => _215(), 'optionalAccess', _216 => _216.canWrite]), () => ( true));
9809
+ const canWrite = _nullishCoalesce(_optionalChain([self, 'access', _228 => _228.get, 'call', _229 => _229(), 'optionalAccess', _230 => _230.canWrite]), () => ( true));
9592
9810
  const root = context.root;
9593
9811
  disableHistory(() => {
9594
9812
  for (const key in context.initialStorage) {
@@ -9662,15 +9880,16 @@ function createRoom(options, config) {
9662
9880
  );
9663
9881
  return { opsToEmit: opsWithOpIds, reverse, updates };
9664
9882
  }
9665
- function applyRemoteOps(ops) {
9883
+ function applyRemoteOps(ops, fromSnapshot = false) {
9666
9884
  return applyOps(
9667
9885
  [],
9668
9886
  ops,
9669
9887
  /* isLocal */
9670
- false
9888
+ false,
9889
+ fromSnapshot
9671
9890
  );
9672
9891
  }
9673
- function applyOps(pframes, ops, isLocal) {
9892
+ function applyOps(pframes, ops, isLocal, fromSnapshot = false) {
9674
9893
  const output = {
9675
9894
  reverse: new Deque(),
9676
9895
  storageUpdates: /* @__PURE__ */ new Map(),
@@ -9706,7 +9925,7 @@ function createRoom(options, config) {
9706
9925
  } else {
9707
9926
  source = 1 /* THEIRS */;
9708
9927
  }
9709
- const applyOpResult = applyOp(op, source);
9928
+ const applyOpResult = applyOp(op, source, fromSnapshot);
9710
9929
  if (applyOpResult.modified) {
9711
9930
  const nodeId = applyOpResult.modified.node._id;
9712
9931
  if (!(nodeId && createdNodeIds.has(nodeId))) {
@@ -9732,7 +9951,7 @@ function createRoom(options, config) {
9732
9951
  }
9733
9952
  };
9734
9953
  }
9735
- function applyOp(op, source) {
9954
+ function applyOp(op, source, fromSnapshot = false) {
9736
9955
  if (isIgnoredOp(op)) {
9737
9956
  return { modified: false };
9738
9957
  }
@@ -9771,7 +9990,7 @@ function createRoom(options, config) {
9771
9990
  if (parentNode === void 0) {
9772
9991
  return { modified: false };
9773
9992
  }
9774
- return parentNode._attachChild(op, source);
9993
+ return parentNode._attachChild(op, source, fromSnapshot);
9775
9994
  }
9776
9995
  }
9777
9996
  }
@@ -9793,7 +10012,7 @@ function createRoom(options, config) {
9793
10012
  }
9794
10013
  context.myPresence.patch(patch);
9795
10014
  if (context.activeBatch) {
9796
- if (_optionalChain([options2, 'optionalAccess', _217 => _217.addToHistory])) {
10015
+ if (_optionalChain([options2, 'optionalAccess', _231 => _231.addToHistory])) {
9797
10016
  context.activeBatch.reverseOps.pushLeft({
9798
10017
  type: "presence",
9799
10018
  data: oldValues
@@ -9802,7 +10021,7 @@ function createRoom(options, config) {
9802
10021
  context.activeBatch.updates.presence = true;
9803
10022
  } else {
9804
10023
  flushNowOrSoon();
9805
- if (_optionalChain([options2, 'optionalAccess', _218 => _218.addToHistory])) {
10024
+ if (_optionalChain([options2, 'optionalAccess', _232 => _232.addToHistory])) {
9806
10025
  addToUndoStack([{ type: "presence", data: oldValues }]);
9807
10026
  }
9808
10027
  notify({ presence: true });
@@ -9911,12 +10130,11 @@ function createRoom(options, config) {
9911
10130
  }
9912
10131
  }
9913
10132
  function applyAndSendOfflineOps(unackedOps) {
9914
- if (unackedOps.size === 0) {
10133
+ if (unackedOps.length === 0) {
9915
10134
  return;
9916
10135
  }
9917
10136
  const messages = [];
9918
- const inOps = Array.from(unackedOps.values());
9919
- const result = applyLocalOps(inOps);
10137
+ const result = applyLocalOps(unackedOps);
9920
10138
  messages.push({
9921
10139
  type: ClientMsgCode.UPDATE_STORAGE,
9922
10140
  ops: result.opsToEmit
@@ -9980,11 +10198,11 @@ function createRoom(options, config) {
9980
10198
  break;
9981
10199
  }
9982
10200
  case ServerMsgCode.STORAGE_CHUNK:
9983
- _optionalChain([stopwatch, 'optionalAccess', _219 => _219.lap, 'call', _220 => _220()]);
10201
+ _optionalChain([stopwatch, 'optionalAccess', _233 => _233.lap, 'call', _234 => _234()]);
9984
10202
  nodeMapBuffer.append(compactNodesToNodeStream(message.nodes));
9985
10203
  break;
9986
10204
  case ServerMsgCode.STORAGE_STREAM_END: {
9987
- const timing = _optionalChain([stopwatch, 'optionalAccess', _221 => _221.stop, 'call', _222 => _222()]);
10205
+ const timing = _optionalChain([stopwatch, 'optionalAccess', _235 => _235.stop, 'call', _236 => _236()]);
9988
10206
  if (timing) {
9989
10207
  const ms = (v) => `${v.toFixed(1)}ms`;
9990
10208
  const rest = timing.laps.slice(1);
@@ -10119,11 +10337,11 @@ function createRoom(options, config) {
10119
10337
  } else if (pendingFeedsRequests.has(requestId)) {
10120
10338
  const pending = pendingFeedsRequests.get(requestId);
10121
10339
  pendingFeedsRequests.delete(requestId);
10122
- _optionalChain([pending, 'optionalAccess', _223 => _223.reject, 'call', _224 => _224(err)]);
10340
+ _optionalChain([pending, 'optionalAccess', _237 => _237.reject, 'call', _238 => _238(err)]);
10123
10341
  } else if (pendingFeedMessagesRequests.has(requestId)) {
10124
10342
  const pending = pendingFeedMessagesRequests.get(requestId);
10125
10343
  pendingFeedMessagesRequests.delete(requestId);
10126
- _optionalChain([pending, 'optionalAccess', _225 => _225.reject, 'call', _226 => _226(err)]);
10344
+ _optionalChain([pending, 'optionalAccess', _239 => _239.reject, 'call', _240 => _240(err)]);
10127
10345
  }
10128
10346
  eventHub.feeds.notify(message);
10129
10347
  break;
@@ -10140,7 +10358,7 @@ function createRoom(options, config) {
10140
10358
  const storageOps = context.buffer.storageOperations;
10141
10359
  if (storageOps.length > 0) {
10142
10360
  for (const op of storageOps) {
10143
- context.unacknowledgedOps.set(op.opId, op);
10361
+ context.unacknowledgedOps.add(op);
10144
10362
  }
10145
10363
  notifyStorageStatus();
10146
10364
  }
@@ -10277,10 +10495,10 @@ function createRoom(options, config) {
10277
10495
  timeoutId,
10278
10496
  kind,
10279
10497
  feedId,
10280
- messageId: _optionalChain([options2, 'optionalAccess', _227 => _227.messageId]),
10281
- expectedClientMessageId: _optionalChain([options2, 'optionalAccess', _228 => _228.expectedClientMessageId])
10498
+ messageId: _optionalChain([options2, 'optionalAccess', _241 => _241.messageId]),
10499
+ expectedClientMessageId: _optionalChain([options2, 'optionalAccess', _242 => _242.expectedClientMessageId])
10282
10500
  });
10283
- if (kind === "add-message" && _optionalChain([options2, 'optionalAccess', _229 => _229.expectedClientMessageId]) === void 0) {
10501
+ if (kind === "add-message" && _optionalChain([options2, 'optionalAccess', _243 => _243.expectedClientMessageId]) === void 0) {
10284
10502
  const q = _nullishCoalesce(pendingAddMessageFifoByFeed.get(feedId), () => ( []));
10285
10503
  q.push(requestId);
10286
10504
  pendingAddMessageFifoByFeed.set(feedId, q);
@@ -10331,10 +10549,10 @@ function createRoom(options, config) {
10331
10549
  }
10332
10550
  if (!matched) {
10333
10551
  const q = pendingAddMessageFifoByFeed.get(message.feedId);
10334
- const headId = _optionalChain([q, 'optionalAccess', _230 => _230[0]]);
10552
+ const headId = _optionalChain([q, 'optionalAccess', _244 => _244[0]]);
10335
10553
  if (headId !== void 0) {
10336
10554
  const pending = pendingFeedMutations.get(headId);
10337
- if (_optionalChain([pending, 'optionalAccess', _231 => _231.kind]) === "add-message" && pending.expectedClientMessageId === void 0) {
10555
+ if (_optionalChain([pending, 'optionalAccess', _245 => _245.kind]) === "add-message" && pending.expectedClientMessageId === void 0) {
10338
10556
  settleFeedMutation(headId, "ok");
10339
10557
  }
10340
10558
  }
@@ -10367,10 +10585,10 @@ function createRoom(options, config) {
10367
10585
  }
10368
10586
  }
10369
10587
  function processInitialStorage(nodes) {
10370
- const unacknowledgedOps = new Map(context.unacknowledgedOps);
10588
+ const unacknowledgedOps2 = [...context.unacknowledgedOps.values()];
10371
10589
  createOrUpdateRootFromMessage(nodes);
10372
- applyAndSendOfflineOps(unacknowledgedOps);
10373
- _optionalChain([_resolveStoragePromise, 'optionalCall', _232 => _232()]);
10590
+ applyAndSendOfflineOps(unacknowledgedOps2);
10591
+ _optionalChain([_resolveStoragePromise, 'optionalCall', _246 => _246()]);
10374
10592
  notifyStorageStatus();
10375
10593
  eventHub.storageDidLoad.notify();
10376
10594
  }
@@ -10388,7 +10606,7 @@ function createRoom(options, config) {
10388
10606
  } else if (!messages.some((msg) => msg.type === ClientMsgCode.FETCH_STORAGE)) {
10389
10607
  messages.push({ type: ClientMsgCode.FETCH_STORAGE });
10390
10608
  nodeMapBuffer.take();
10391
- _optionalChain([stopwatch, 'optionalAccess', _233 => _233.start, 'call', _234 => _234()]);
10609
+ _optionalChain([stopwatch, 'optionalAccess', _247 => _247.start, 'call', _248 => _248()]);
10392
10610
  }
10393
10611
  if (options2.flush) {
10394
10612
  flushNowOrSoon();
@@ -10444,10 +10662,10 @@ function createRoom(options, config) {
10444
10662
  const message = {
10445
10663
  type: ClientMsgCode.FETCH_FEEDS,
10446
10664
  requestId,
10447
- cursor: _optionalChain([options2, 'optionalAccess', _235 => _235.cursor]),
10448
- since: _optionalChain([options2, 'optionalAccess', _236 => _236.since]),
10449
- limit: _optionalChain([options2, 'optionalAccess', _237 => _237.limit]),
10450
- metadata: _optionalChain([options2, 'optionalAccess', _238 => _238.metadata])
10665
+ cursor: _optionalChain([options2, 'optionalAccess', _249 => _249.cursor]),
10666
+ since: _optionalChain([options2, 'optionalAccess', _250 => _250.since]),
10667
+ limit: _optionalChain([options2, 'optionalAccess', _251 => _251.limit]),
10668
+ metadata: _optionalChain([options2, 'optionalAccess', _252 => _252.metadata])
10451
10669
  };
10452
10670
  context.buffer.messages.push(message);
10453
10671
  flushNowOrSoon();
@@ -10467,9 +10685,9 @@ function createRoom(options, config) {
10467
10685
  type: ClientMsgCode.FETCH_FEED_MESSAGES,
10468
10686
  requestId,
10469
10687
  feedId,
10470
- cursor: _optionalChain([options2, 'optionalAccess', _239 => _239.cursor]),
10471
- since: _optionalChain([options2, 'optionalAccess', _240 => _240.since]),
10472
- limit: _optionalChain([options2, 'optionalAccess', _241 => _241.limit])
10688
+ cursor: _optionalChain([options2, 'optionalAccess', _253 => _253.cursor]),
10689
+ since: _optionalChain([options2, 'optionalAccess', _254 => _254.since]),
10690
+ limit: _optionalChain([options2, 'optionalAccess', _255 => _255.limit])
10473
10691
  };
10474
10692
  context.buffer.messages.push(message);
10475
10693
  flushNowOrSoon();
@@ -10488,8 +10706,8 @@ function createRoom(options, config) {
10488
10706
  type: ClientMsgCode.ADD_FEED,
10489
10707
  requestId,
10490
10708
  feedId,
10491
- metadata: _optionalChain([options2, 'optionalAccess', _242 => _242.metadata]),
10492
- createdAt: _optionalChain([options2, 'optionalAccess', _243 => _243.createdAt])
10709
+ metadata: _optionalChain([options2, 'optionalAccess', _256 => _256.metadata]),
10710
+ createdAt: _optionalChain([options2, 'optionalAccess', _257 => _257.createdAt])
10493
10711
  };
10494
10712
  context.buffer.messages.push(message);
10495
10713
  flushNowOrSoon();
@@ -10523,15 +10741,15 @@ function createRoom(options, config) {
10523
10741
  function addFeedMessage(feedId, data, options2) {
10524
10742
  const requestId = nanoid();
10525
10743
  const promise = registerFeedMutation(requestId, "add-message", feedId, {
10526
- expectedClientMessageId: _optionalChain([options2, 'optionalAccess', _244 => _244.id])
10744
+ expectedClientMessageId: _optionalChain([options2, 'optionalAccess', _258 => _258.id])
10527
10745
  });
10528
10746
  const message = {
10529
10747
  type: ClientMsgCode.ADD_FEED_MESSAGE,
10530
10748
  requestId,
10531
10749
  feedId,
10532
10750
  data,
10533
- id: _optionalChain([options2, 'optionalAccess', _245 => _245.id]),
10534
- createdAt: _optionalChain([options2, 'optionalAccess', _246 => _246.createdAt])
10751
+ id: _optionalChain([options2, 'optionalAccess', _259 => _259.id]),
10752
+ createdAt: _optionalChain([options2, 'optionalAccess', _260 => _260.createdAt])
10535
10753
  };
10536
10754
  context.buffer.messages.push(message);
10537
10755
  flushNowOrSoon();
@@ -10548,7 +10766,7 @@ function createRoom(options, config) {
10548
10766
  feedId,
10549
10767
  messageId,
10550
10768
  data,
10551
- updatedAt: _optionalChain([options2, 'optionalAccess', _247 => _247.updatedAt])
10769
+ updatedAt: _optionalChain([options2, 'optionalAccess', _261 => _261.updatedAt])
10552
10770
  };
10553
10771
  context.buffer.messages.push(message);
10554
10772
  flushNowOrSoon();
@@ -10755,8 +10973,8 @@ function createRoom(options, config) {
10755
10973
  async function getThreads(options2) {
10756
10974
  return httpClient.getThreads({
10757
10975
  roomId,
10758
- query: _optionalChain([options2, 'optionalAccess', _248 => _248.query]),
10759
- cursor: _optionalChain([options2, 'optionalAccess', _249 => _249.cursor])
10976
+ query: _optionalChain([options2, 'optionalAccess', _262 => _262.query]),
10977
+ cursor: _optionalChain([options2, 'optionalAccess', _263 => _263.cursor])
10760
10978
  });
10761
10979
  }
10762
10980
  async function getThread(threadId) {
@@ -10878,7 +11096,7 @@ function createRoom(options, config) {
10878
11096
  function getSubscriptionSettings(options2) {
10879
11097
  return httpClient.getSubscriptionSettings({
10880
11098
  roomId,
10881
- signal: _optionalChain([options2, 'optionalAccess', _250 => _250.signal])
11099
+ signal: _optionalChain([options2, 'optionalAccess', _264 => _264.signal])
10882
11100
  });
10883
11101
  }
10884
11102
  function updateSubscriptionSettings(settings) {
@@ -10900,7 +11118,7 @@ function createRoom(options, config) {
10900
11118
  {
10901
11119
  [kInternal]: {
10902
11120
  get presenceBuffer() {
10903
- return deepClone(_nullishCoalesce(_optionalChain([context, 'access', _251 => _251.buffer, 'access', _252 => _252.presenceUpdates, 'optionalAccess', _253 => _253.data]), () => ( null)));
11121
+ return deepClone(_nullishCoalesce(_optionalChain([context, 'access', _265 => _265.buffer, 'access', _266 => _266.presenceUpdates, 'optionalAccess', _267 => _267.data]), () => ( null)));
10904
11122
  },
10905
11123
  // prettier-ignore
10906
11124
  get undoStack() {
@@ -10915,9 +11133,9 @@ function createRoom(options, config) {
10915
11133
  return context.yjsProvider;
10916
11134
  },
10917
11135
  setYjsProvider(newProvider) {
10918
- _optionalChain([context, 'access', _254 => _254.yjsProvider, 'optionalAccess', _255 => _255.off, 'call', _256 => _256("status", yjsStatusDidChange)]);
11136
+ _optionalChain([context, 'access', _268 => _268.yjsProvider, 'optionalAccess', _269 => _269.off, 'call', _270 => _270("status", yjsStatusDidChange)]);
10919
11137
  context.yjsProvider = newProvider;
10920
- _optionalChain([newProvider, 'optionalAccess', _257 => _257.on, 'call', _258 => _258("status", yjsStatusDidChange)]);
11138
+ _optionalChain([newProvider, 'optionalAccess', _271 => _271.on, 'call', _272 => _272("status", yjsStatusDidChange)]);
10921
11139
  context.yjsProviderDidChange.notify();
10922
11140
  },
10923
11141
  yjsProviderDidChange: context.yjsProviderDidChange.observable,
@@ -10958,6 +11176,11 @@ function createRoom(options, config) {
10958
11176
  connect: () => managedSocket.connect(),
10959
11177
  reconnect: () => managedSocket.reconnect(),
10960
11178
  disconnect: () => managedSocket.disconnect(),
11179
+ _dump: () => {
11180
+ const n = context.pool.nodes.size;
11181
+ return `Room "${roomId}" (${n} node${n === 1 ? "" : "s"}):
11182
+ ${dumpPool(context.pool)}`;
11183
+ },
10961
11184
  destroy: () => {
10962
11185
  pendingFeedsRequests.forEach(
10963
11186
  (request) => request.reject(new Error("Room destroyed"))
@@ -10970,7 +11193,7 @@ function createRoom(options, config) {
10970
11193
  source.dispose();
10971
11194
  }
10972
11195
  eventHub.roomWillDestroy.notify();
10973
- _optionalChain([context, 'access', _259 => _259.yjsProvider, 'optionalAccess', _260 => _260.off, 'call', _261 => _261("status", yjsStatusDidChange)]);
11196
+ _optionalChain([context, 'access', _273 => _273.yjsProvider, 'optionalAccess', _274 => _274.off, 'call', _275 => _275("status", yjsStatusDidChange)]);
10974
11197
  syncSourceForStorage.destroy();
10975
11198
  syncSourceForYjs.destroy();
10976
11199
  uninstallBgTabSpy();
@@ -11130,7 +11353,7 @@ function makeClassicSubscribeFn(roomId, events, errorEvents) {
11130
11353
  }
11131
11354
  if (isLiveNode(first)) {
11132
11355
  const node = first;
11133
- if (_optionalChain([options, 'optionalAccess', _262 => _262.isDeep])) {
11356
+ if (_optionalChain([options, 'optionalAccess', _276 => _276.isDeep])) {
11134
11357
  const storageCallback = second;
11135
11358
  return subscribeToLiveStructureDeeply(node, storageCallback);
11136
11359
  } else {
@@ -11216,8 +11439,8 @@ function createClient(options) {
11216
11439
  const authManager = createAuthManager(options, (token) => {
11217
11440
  currentUserId.set(() => token.uid);
11218
11441
  });
11219
- const fetchPolyfill = _optionalChain([clientOptions, 'access', _263 => _263.polyfills, 'optionalAccess', _264 => _264.fetch]) || /* istanbul ignore next */
11220
- _optionalChain([globalThis, 'access', _265 => _265.fetch, 'optionalAccess', _266 => _266.bind, 'call', _267 => _267(globalThis)]);
11442
+ const fetchPolyfill = _optionalChain([clientOptions, 'access', _277 => _277.polyfills, 'optionalAccess', _278 => _278.fetch]) || /* istanbul ignore next */
11443
+ _optionalChain([globalThis, 'access', _279 => _279.fetch, 'optionalAccess', _280 => _280.bind, 'call', _281 => _281(globalThis)]);
11221
11444
  const httpClient = createApiClient({
11222
11445
  baseUrl,
11223
11446
  fetchPolyfill,
@@ -11235,7 +11458,7 @@ function createClient(options) {
11235
11458
  delegates: {
11236
11459
  createSocket: makeCreateSocketDelegateForAi(
11237
11460
  baseUrl,
11238
- _optionalChain([clientOptions, 'access', _268 => _268.polyfills, 'optionalAccess', _269 => _269.WebSocket])
11461
+ _optionalChain([clientOptions, 'access', _282 => _282.polyfills, 'optionalAccess', _283 => _283.WebSocket])
11239
11462
  ),
11240
11463
  authenticate: async () => {
11241
11464
  const resp = await authManager.getAuthValue({
@@ -11305,7 +11528,7 @@ function createClient(options) {
11305
11528
  createSocket: makeCreateSocketDelegateForRoom(
11306
11529
  roomId,
11307
11530
  baseUrl,
11308
- _optionalChain([clientOptions, 'access', _270 => _270.polyfills, 'optionalAccess', _271 => _271.WebSocket])
11531
+ _optionalChain([clientOptions, 'access', _284 => _284.polyfills, 'optionalAccess', _285 => _285.WebSocket])
11309
11532
  ),
11310
11533
  authenticate: makeAuthDelegateForRoom(roomId, authManager)
11311
11534
  })),
@@ -11328,7 +11551,7 @@ function createClient(options) {
11328
11551
  const shouldConnect = _nullishCoalesce(options2.autoConnect, () => ( true));
11329
11552
  if (shouldConnect) {
11330
11553
  if (typeof atob === "undefined") {
11331
- if (_optionalChain([clientOptions, 'access', _272 => _272.polyfills, 'optionalAccess', _273 => _273.atob]) === void 0) {
11554
+ if (_optionalChain([clientOptions, 'access', _286 => _286.polyfills, 'optionalAccess', _287 => _287.atob]) === void 0) {
11332
11555
  throw new Error(
11333
11556
  "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"
11334
11557
  );
@@ -11340,7 +11563,7 @@ function createClient(options) {
11340
11563
  return leaseRoom(newRoomDetails);
11341
11564
  }
11342
11565
  function getRoom(roomId) {
11343
- const room = _optionalChain([roomsById, 'access', _274 => _274.get, 'call', _275 => _275(roomId), 'optionalAccess', _276 => _276.room]);
11566
+ const room = _optionalChain([roomsById, 'access', _288 => _288.get, 'call', _289 => _289(roomId), 'optionalAccess', _290 => _290.room]);
11344
11567
  return room ? room : null;
11345
11568
  }
11346
11569
  function logout() {
@@ -11356,7 +11579,7 @@ function createClient(options) {
11356
11579
  const batchedResolveUsers = new Batch(
11357
11580
  async (batchedUserIds) => {
11358
11581
  const userIds = batchedUserIds.flat();
11359
- const users = await _optionalChain([resolveUsers, 'optionalCall', _277 => _277({ userIds })]);
11582
+ const users = await _optionalChain([resolveUsers, 'optionalCall', _291 => _291({ userIds })]);
11360
11583
  warnOnceIf(
11361
11584
  !resolveUsers,
11362
11585
  "Set the resolveUsers option in createClient to specify user info."
@@ -11373,7 +11596,7 @@ function createClient(options) {
11373
11596
  const batchedResolveRoomsInfo = new Batch(
11374
11597
  async (batchedRoomIds) => {
11375
11598
  const roomIds = batchedRoomIds.flat();
11376
- const roomsInfo = await _optionalChain([resolveRoomsInfo, 'optionalCall', _278 => _278({ roomIds })]);
11599
+ const roomsInfo = await _optionalChain([resolveRoomsInfo, 'optionalCall', _292 => _292({ roomIds })]);
11377
11600
  warnOnceIf(
11378
11601
  !resolveRoomsInfo,
11379
11602
  "Set the resolveRoomsInfo option in createClient to specify room info."
@@ -11390,7 +11613,7 @@ function createClient(options) {
11390
11613
  const batchedResolveGroupsInfo = new Batch(
11391
11614
  async (batchedGroupIds) => {
11392
11615
  const groupIds = batchedGroupIds.flat();
11393
- const groupsInfo = await _optionalChain([resolveGroupsInfo, 'optionalCall', _279 => _279({ groupIds })]);
11616
+ const groupsInfo = await _optionalChain([resolveGroupsInfo, 'optionalCall', _293 => _293({ groupIds })]);
11394
11617
  warnOnceIf(
11395
11618
  !resolveGroupsInfo,
11396
11619
  "Set the resolveGroupsInfo option in createClient to specify group info."
@@ -11449,7 +11672,7 @@ function createClient(options) {
11449
11672
  }
11450
11673
  };
11451
11674
  const win = typeof window !== "undefined" ? window : void 0;
11452
- _optionalChain([win, 'optionalAccess', _280 => _280.addEventListener, 'call', _281 => _281("beforeunload", maybePreventClose)]);
11675
+ _optionalChain([win, 'optionalAccess', _294 => _294.addEventListener, 'call', _295 => _295("beforeunload", maybePreventClose)]);
11453
11676
  }
11454
11677
  async function getNotificationSettings(options2) {
11455
11678
  const plainSettings = await httpClient.getNotificationSettings(options2);
@@ -11465,6 +11688,7 @@ function createClient(options) {
11465
11688
  {
11466
11689
  enterRoom,
11467
11690
  getRoom,
11691
+ _dump: () => Array.from(roomsById.values(), ({ room }) => room._dump()).join("\n\n"),
11468
11692
  logout,
11469
11693
  // Public inbox notifications API
11470
11694
  getInboxNotifications: httpClient.getInboxNotifications,
@@ -11576,7 +11800,7 @@ var commentBodyElementsTypes = {
11576
11800
  mention: "inline"
11577
11801
  };
11578
11802
  function traverseCommentBody(body, elementOrVisitor, possiblyVisitor) {
11579
- if (!body || !_optionalChain([body, 'optionalAccess', _282 => _282.content])) {
11803
+ if (!body || !_optionalChain([body, 'optionalAccess', _296 => _296.content])) {
11580
11804
  return;
11581
11805
  }
11582
11806
  const element = typeof elementOrVisitor === "string" ? elementOrVisitor : void 0;
@@ -11586,13 +11810,13 @@ function traverseCommentBody(body, elementOrVisitor, possiblyVisitor) {
11586
11810
  for (const block of body.content) {
11587
11811
  if (type === "all" || type === "block") {
11588
11812
  if (guard(block)) {
11589
- _optionalChain([visitor, 'optionalCall', _283 => _283(block)]);
11813
+ _optionalChain([visitor, 'optionalCall', _297 => _297(block)]);
11590
11814
  }
11591
11815
  }
11592
11816
  if (type === "all" || type === "inline") {
11593
11817
  for (const inline of block.children) {
11594
11818
  if (guard(inline)) {
11595
- _optionalChain([visitor, 'optionalCall', _284 => _284(inline)]);
11819
+ _optionalChain([visitor, 'optionalCall', _298 => _298(inline)]);
11596
11820
  }
11597
11821
  }
11598
11822
  }
@@ -11762,7 +11986,7 @@ var stringifyCommentBodyPlainElements = {
11762
11986
  text: ({ element }) => element.text,
11763
11987
  link: ({ element }) => _nullishCoalesce(element.text, () => ( element.url)),
11764
11988
  mention: ({ element, user, group }) => {
11765
- return `@${_nullishCoalesce(_nullishCoalesce(_optionalChain([user, 'optionalAccess', _285 => _285.name]), () => ( _optionalChain([group, 'optionalAccess', _286 => _286.name]))), () => ( element.id))}`;
11989
+ return `@${_nullishCoalesce(_nullishCoalesce(_optionalChain([user, 'optionalAccess', _299 => _299.name]), () => ( _optionalChain([group, 'optionalAccess', _300 => _300.name]))), () => ( element.id))}`;
11766
11990
  }
11767
11991
  };
11768
11992
  var stringifyCommentBodyHtmlElements = {
@@ -11792,7 +12016,7 @@ var stringifyCommentBodyHtmlElements = {
11792
12016
  return html`<a href="${href}" target="_blank" rel="noopener noreferrer">${element.text ? html`${element.text}` : element.url}</a>`;
11793
12017
  },
11794
12018
  mention: ({ element, user, group }) => {
11795
- return html`<span data-mention>@${_optionalChain([user, 'optionalAccess', _287 => _287.name]) ? html`${_optionalChain([user, 'optionalAccess', _288 => _288.name])}` : _optionalChain([group, 'optionalAccess', _289 => _289.name]) ? html`${_optionalChain([group, 'optionalAccess', _290 => _290.name])}` : element.id}</span>`;
12019
+ return html`<span data-mention>@${_optionalChain([user, 'optionalAccess', _301 => _301.name]) ? html`${_optionalChain([user, 'optionalAccess', _302 => _302.name])}` : _optionalChain([group, 'optionalAccess', _303 => _303.name]) ? html`${_optionalChain([group, 'optionalAccess', _304 => _304.name])}` : element.id}</span>`;
11796
12020
  }
11797
12021
  };
11798
12022
  var stringifyCommentBodyMarkdownElements = {
@@ -11822,20 +12046,20 @@ var stringifyCommentBodyMarkdownElements = {
11822
12046
  return markdown`[${_nullishCoalesce(element.text, () => ( element.url))}](${href})`;
11823
12047
  },
11824
12048
  mention: ({ element, user, group }) => {
11825
- return markdown`@${_nullishCoalesce(_nullishCoalesce(_optionalChain([user, 'optionalAccess', _291 => _291.name]), () => ( _optionalChain([group, 'optionalAccess', _292 => _292.name]))), () => ( element.id))}`;
12049
+ return markdown`@${_nullishCoalesce(_nullishCoalesce(_optionalChain([user, 'optionalAccess', _305 => _305.name]), () => ( _optionalChain([group, 'optionalAccess', _306 => _306.name]))), () => ( element.id))}`;
11826
12050
  }
11827
12051
  };
11828
12052
  async function stringifyCommentBody(body, options) {
11829
- const format = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _293 => _293.format]), () => ( "plain"));
11830
- const separator = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _294 => _294.separator]), () => ( (format === "markdown" ? "\n\n" : "\n")));
12053
+ const format = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _307 => _307.format]), () => ( "plain"));
12054
+ const separator = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _308 => _308.separator]), () => ( (format === "markdown" ? "\n\n" : "\n")));
11831
12055
  const elements = {
11832
12056
  ...format === "html" ? stringifyCommentBodyHtmlElements : format === "markdown" ? stringifyCommentBodyMarkdownElements : stringifyCommentBodyPlainElements,
11833
- ..._optionalChain([options, 'optionalAccess', _295 => _295.elements])
12057
+ ..._optionalChain([options, 'optionalAccess', _309 => _309.elements])
11834
12058
  };
11835
12059
  const { users: resolvedUsers, groups: resolvedGroupsInfo } = await resolveMentionsInCommentBody(
11836
12060
  body,
11837
- _optionalChain([options, 'optionalAccess', _296 => _296.resolveUsers]),
11838
- _optionalChain([options, 'optionalAccess', _297 => _297.resolveGroupsInfo])
12061
+ _optionalChain([options, 'optionalAccess', _310 => _310.resolveUsers]),
12062
+ _optionalChain([options, 'optionalAccess', _311 => _311.resolveGroupsInfo])
11839
12063
  );
11840
12064
  const blocks = body.content.flatMap((block, blockIndex) => {
11841
12065
  switch (block.type) {
@@ -11970,9 +12194,9 @@ function makePoller(callback, intervalMs, options) {
11970
12194
  const startTime = performance.now();
11971
12195
  const doc = typeof document !== "undefined" ? document : void 0;
11972
12196
  const win = typeof window !== "undefined" ? window : void 0;
11973
- const maxStaleTimeMs = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _298 => _298.maxStaleTimeMs]), () => ( Number.POSITIVE_INFINITY));
12197
+ const maxStaleTimeMs = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _312 => _312.maxStaleTimeMs]), () => ( Number.POSITIVE_INFINITY));
11974
12198
  const context = {
11975
- inForeground: _optionalChain([doc, 'optionalAccess', _299 => _299.visibilityState]) !== "hidden",
12199
+ inForeground: _optionalChain([doc, 'optionalAccess', _313 => _313.visibilityState]) !== "hidden",
11976
12200
  lastSuccessfulPollAt: startTime,
11977
12201
  count: 0,
11978
12202
  backoff: 0
@@ -12053,11 +12277,11 @@ function makePoller(callback, intervalMs, options) {
12053
12277
  pollNowIfStale();
12054
12278
  }
12055
12279
  function onVisibilityChange() {
12056
- setInForeground(_optionalChain([doc, 'optionalAccess', _300 => _300.visibilityState]) !== "hidden");
12280
+ setInForeground(_optionalChain([doc, 'optionalAccess', _314 => _314.visibilityState]) !== "hidden");
12057
12281
  }
12058
- _optionalChain([doc, 'optionalAccess', _301 => _301.addEventListener, 'call', _302 => _302("visibilitychange", onVisibilityChange)]);
12059
- _optionalChain([win, 'optionalAccess', _303 => _303.addEventListener, 'call', _304 => _304("online", onVisibilityChange)]);
12060
- _optionalChain([win, 'optionalAccess', _305 => _305.addEventListener, 'call', _306 => _306("focus", pollNowIfStale)]);
12282
+ _optionalChain([doc, 'optionalAccess', _315 => _315.addEventListener, 'call', _316 => _316("visibilitychange", onVisibilityChange)]);
12283
+ _optionalChain([win, 'optionalAccess', _317 => _317.addEventListener, 'call', _318 => _318("online", onVisibilityChange)]);
12284
+ _optionalChain([win, 'optionalAccess', _319 => _319.addEventListener, 'call', _320 => _320("focus", pollNowIfStale)]);
12061
12285
  fsm.start();
12062
12286
  return {
12063
12287
  inc,