@liveblocks/core 3.14.0-pre5 → 3.14.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.14.0-pre5";
9
+ var PKG_VERSION = "3.14.0-rc1";
10
10
  var PKG_FORMAT = "cjs";
11
11
 
12
12
  // src/dupe-detection.ts
@@ -2280,19 +2280,6 @@ function createApiClient({
2280
2280
  );
2281
2281
  return await result.json();
2282
2282
  }
2283
- async function sendMessagesOverHTTP(options) {
2284
- return httpClient.rawPost(
2285
- url`/v2/c/rooms/${options.roomId}/send-message`,
2286
- await authManager.getAuthValue({
2287
- requestedScope: "room:read",
2288
- roomId: options.roomId
2289
- }),
2290
- {
2291
- nonce: options.nonce,
2292
- messages: options.messages
2293
- }
2294
- );
2295
- }
2296
2283
  async function getInboxNotifications(options) {
2297
2284
  const PAGE_SIZE = 50;
2298
2285
  let query;
@@ -2541,7 +2528,6 @@ function createApiClient({
2541
2528
  getChatAttachmentUrl,
2542
2529
  // Room storage
2543
2530
  streamStorage,
2544
- sendMessagesOverHTTP,
2545
2531
  // Notifications
2546
2532
  getInboxNotifications,
2547
2533
  getInboxNotificationsSince,
@@ -6544,7 +6530,9 @@ var LiveList = class _LiveList extends AbstractCrdt {
6544
6530
  item._toOps(this._id, parentKey2),
6545
6531
  void 0
6546
6532
  );
6547
- ops.push(...childOps);
6533
+ for (const childOp of childOps) {
6534
+ ops.push(childOp);
6535
+ }
6548
6536
  }
6549
6537
  return ops;
6550
6538
  }
@@ -7545,7 +7533,9 @@ var LiveMap = class _LiveMap extends AbstractCrdt {
7545
7533
  };
7546
7534
  ops.push(op);
7547
7535
  for (const [key, value] of this.#map) {
7548
- ops.push(...value._toOps(this._id, key));
7536
+ for (const childOp of value._toOps(this._id, key)) {
7537
+ ops.push(childOp);
7538
+ }
7549
7539
  }
7550
7540
  return ops;
7551
7541
  }
@@ -7944,7 +7934,9 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
7944
7934
  ops.push(op);
7945
7935
  for (const [key, value] of this.#map) {
7946
7936
  if (isLiveNode(value)) {
7947
- ops.push(...value._toOps(this._id, key));
7937
+ for (const childOp of value._toOps(this._id, key)) {
7938
+ ops.push(childOp);
7939
+ }
7948
7940
  } else {
7949
7941
  op.data[key] = value;
7950
7942
  }
@@ -8113,7 +8105,9 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
8113
8105
  for (const key in op.data) {
8114
8106
  const oldValue = this.#map.get(key);
8115
8107
  if (isLiveNode(oldValue)) {
8116
- reverse.push(...oldValue._toOps(id, key));
8108
+ for (const childOp of oldValue._toOps(id, key)) {
8109
+ reverse.push(childOp);
8110
+ }
8117
8111
  oldValue._detach();
8118
8112
  } else if (oldValue !== void 0) {
8119
8113
  reverseUpdate.data[key] = oldValue;
@@ -8337,7 +8331,9 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
8337
8331
  }
8338
8332
  const oldValue = this.#map.get(key);
8339
8333
  if (isLiveNode(oldValue)) {
8340
- reverseOps.push(...oldValue._toOps(this._id, key));
8334
+ for (const childOp of oldValue._toOps(this._id, key)) {
8335
+ reverseOps.push(childOp);
8336
+ }
8341
8337
  oldValue._detach();
8342
8338
  } else if (oldValue === void 0) {
8343
8339
  reverseOps.push({ type: OpCode.DELETE_OBJECT_KEY, id: this._id, key });
@@ -8358,7 +8354,9 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
8358
8354
  if (createCrdtOp) {
8359
8355
  this.#unackedOpsByKey.set(key, nn(createCrdtOp.opId));
8360
8356
  }
8361
- ops.push(...newAttachChildOps);
8357
+ for (const childOp of newAttachChildOps) {
8358
+ ops.push(childOp);
8359
+ }
8362
8360
  } else {
8363
8361
  updatedProps[key] = newValue;
8364
8362
  this.#unackedOpsByKey.set(key, opId);
@@ -8732,6 +8730,29 @@ function isJsonObject(data) {
8732
8730
  return !isJsonScalar(data) && !isJsonArray(data);
8733
8731
  }
8734
8732
 
8733
+ // src/lib/stopwatch.ts
8734
+ function makeStopWatch() {
8735
+ let startTime = 0;
8736
+ let lastLapTime = 0;
8737
+ let laps;
8738
+ function start() {
8739
+ laps = [];
8740
+ startTime = performance.now();
8741
+ lastLapTime = startTime;
8742
+ }
8743
+ function lap(now2 = performance.now()) {
8744
+ laps.push(now2 - lastLapTime);
8745
+ lastLapTime = now2;
8746
+ }
8747
+ function stop() {
8748
+ const endTime = performance.now();
8749
+ lap(endTime);
8750
+ const total = endTime - startTime;
8751
+ return { total, laps };
8752
+ }
8753
+ return { start, lap, stop };
8754
+ }
8755
+
8735
8756
  // src/protocol/ClientMsg.ts
8736
8757
  var ClientMsgCode = Object.freeze({
8737
8758
  // For Presence
@@ -8984,7 +9005,6 @@ function defaultMessageFromContext(context) {
8984
9005
  }
8985
9006
 
8986
9007
  // src/room.ts
8987
- var MAX_SOCKET_MESSAGE_SIZE = 1024 * 1024 - 512;
8988
9008
  function makeIdFactory(connectionId) {
8989
9009
  let count = 0;
8990
9010
  return () => `${connectionId}:${count++}`;
@@ -9097,6 +9117,7 @@ function createRoom(options, config) {
9097
9117
  unacknowledgedOps: /* @__PURE__ */ new Map()
9098
9118
  };
9099
9119
  const nodeMapBuffer = makeNodeMapBuffer();
9120
+ const stopwatch = config.enableDebugLogging ? makeStopWatch() : void 0;
9100
9121
  let lastTokenKey;
9101
9122
  function onStatusDidChange(newStatus) {
9102
9123
  const authValue = managedSocket.authValue;
@@ -9251,100 +9272,8 @@ function createRoom(options, config) {
9251
9272
  ...options2
9252
9273
  });
9253
9274
  }
9254
- function* chunkOps(msg) {
9255
- const { ops, ...rest } = msg;
9256
- if (ops.length < 2) {
9257
- throw new Error("Cannot split ops into smaller chunks");
9258
- }
9259
- const mid = Math.floor(ops.length / 2);
9260
- const firstHalf = ops.slice(0, mid);
9261
- const secondHalf = ops.slice(mid);
9262
- for (const halfOps of [firstHalf, secondHalf]) {
9263
- const half = { ops: halfOps, ...rest };
9264
- const text = stringifyOrLog([half]);
9265
- if (!isTooBigForWebSocket(text)) {
9266
- yield text;
9267
- } else {
9268
- yield* chunkOps(half);
9269
- }
9270
- }
9271
- }
9272
- function* chunkMessages(messages) {
9273
- if (messages.length < 2) {
9274
- if (messages[0].type === ClientMsgCode.UPDATE_STORAGE) {
9275
- yield* chunkOps(messages[0]);
9276
- return;
9277
- } else {
9278
- throw new Error(
9279
- "Cannot split into chunks smaller than the allowed message size"
9280
- );
9281
- }
9282
- }
9283
- const mid = Math.floor(messages.length / 2);
9284
- const firstHalf = messages.slice(0, mid);
9285
- const secondHalf = messages.slice(mid);
9286
- for (const half of [firstHalf, secondHalf]) {
9287
- const text = stringifyOrLog(half);
9288
- if (!isTooBigForWebSocket(text)) {
9289
- yield text;
9290
- } else {
9291
- yield* chunkMessages(half);
9292
- }
9293
- }
9294
- }
9295
- function isTooBigForWebSocket(text) {
9296
- if (text.length * 4 < MAX_SOCKET_MESSAGE_SIZE) {
9297
- return false;
9298
- }
9299
- return new TextEncoder().encode(text).length >= MAX_SOCKET_MESSAGE_SIZE;
9300
- }
9301
9275
  function sendMessages(messages) {
9302
- const strategy = _nullishCoalesce(config.largeMessageStrategy, () => ( "default"));
9303
- const text = stringifyOrLog(messages);
9304
- if (!isTooBigForWebSocket(text)) {
9305
- return managedSocket.send(text);
9306
- }
9307
- switch (strategy) {
9308
- case "default": {
9309
- const type = "LARGE_MESSAGE_ERROR";
9310
- const err = new LiveblocksError("Message is too large for websockets", {
9311
- type
9312
- });
9313
- const didNotify = config.errorEventSource.notify(err);
9314
- if (!didNotify) {
9315
- error2(
9316
- "Message is too large for websockets. Configure largeMessageStrategy option or useErrorListener to handle this."
9317
- );
9318
- }
9319
- return;
9320
- }
9321
- case "split": {
9322
- warn("Message is too large for websockets, splitting into smaller chunks");
9323
- for (const chunk2 of chunkMessages(messages)) {
9324
- managedSocket.send(chunk2);
9325
- }
9326
- return;
9327
- }
9328
- // NOTE: This strategy is experimental as it will not work in all situations.
9329
- // It should only be used for broadcasting, presence updates, but isn't suitable
9330
- // for Storage or Yjs updates yet (because through this channel the server does
9331
- // not respond with acks or rejections, causing the client's reported status to
9332
- // be stuck in "synchronizing" forever).
9333
- case "experimental-fallback-to-http": {
9334
- warn("Message is too large for websockets, so sending over HTTP instead");
9335
- const nonce = _nullishCoalesce(_optionalChain([context, 'access', _207 => _207.dynamicSessionInfoSig, 'access', _208 => _208.get, 'call', _209 => _209(), 'optionalAccess', _210 => _210.nonce]), () => ( raise("Session is not authorized to send message over HTTP")));
9336
- void httpClient.sendMessagesOverHTTP({ roomId, nonce, messages }).then((resp) => {
9337
- if (!resp.ok && resp.status === 403) {
9338
- managedSocket.reconnect();
9339
- }
9340
- }).catch((err) => {
9341
- error2(
9342
- `Failed to deliver message over HTTP: ${String(err)}`
9343
- );
9344
- });
9345
- return;
9346
- }
9347
- }
9276
+ managedSocket.send(stringifyOrLog(messages));
9348
9277
  }
9349
9278
  const self = DerivedSignal.from(
9350
9279
  context.staticSessionInfoSig,
@@ -9396,7 +9325,7 @@ function createRoom(options, config) {
9396
9325
  context.pool
9397
9326
  );
9398
9327
  }
9399
- const canWrite = _nullishCoalesce(_optionalChain([self, 'access', _211 => _211.get, 'call', _212 => _212(), 'optionalAccess', _213 => _213.canWrite]), () => ( true));
9328
+ const canWrite = _nullishCoalesce(_optionalChain([self, 'access', _207 => _207.get, 'call', _208 => _208(), 'optionalAccess', _209 => _209.canWrite]), () => ( true));
9400
9329
  const stackSizeBefore = context.undoStack.length;
9401
9330
  for (const key in context.initialStorage) {
9402
9331
  if (context.root.get(key) === void 0) {
@@ -9600,7 +9529,7 @@ function createRoom(options, config) {
9600
9529
  }
9601
9530
  context.myPresence.patch(patch);
9602
9531
  if (context.activeBatch) {
9603
- if (_optionalChain([options2, 'optionalAccess', _214 => _214.addToHistory])) {
9532
+ if (_optionalChain([options2, 'optionalAccess', _210 => _210.addToHistory])) {
9604
9533
  context.activeBatch.reverseOps.pushLeft({
9605
9534
  type: "presence",
9606
9535
  data: oldValues
@@ -9609,7 +9538,7 @@ function createRoom(options, config) {
9609
9538
  context.activeBatch.updates.presence = true;
9610
9539
  } else {
9611
9540
  flushNowOrSoon();
9612
- if (_optionalChain([options2, 'optionalAccess', _215 => _215.addToHistory])) {
9541
+ if (_optionalChain([options2, 'optionalAccess', _211 => _211.addToHistory])) {
9613
9542
  addToUndoStack([{ type: "presence", data: oldValues }]);
9614
9543
  }
9615
9544
  notify({ presence: true });
@@ -9783,11 +9712,27 @@ function createRoom(options, config) {
9783
9712
  break;
9784
9713
  }
9785
9714
  case ServerMsgCode.STORAGE_CHUNK:
9715
+ _optionalChain([stopwatch, 'optionalAccess', _212 => _212.lap, 'call', _213 => _213()]);
9786
9716
  nodeMapBuffer.append(compactNodesToNodeStream(message.nodes));
9787
9717
  break;
9788
- case ServerMsgCode.STORAGE_STREAM_END:
9718
+ case ServerMsgCode.STORAGE_STREAM_END: {
9719
+ const timing = _optionalChain([stopwatch, 'optionalAccess', _214 => _214.stop, 'call', _215 => _215()]);
9720
+ if (timing) {
9721
+ const ms = (v) => `${v.toFixed(1)}ms`;
9722
+ const rest = timing.laps.slice(1);
9723
+ warn(
9724
+ `Storage chunk arrival: ${[
9725
+ `total=${ms(timing.total)}`,
9726
+ `first=${ms(timing.laps[0])}`,
9727
+ `rest.n=${rest.length}`,
9728
+ `rest.avg=${ms(rest.reduce((a, b) => a + b, 0) / rest.length)}`,
9729
+ `rest.max=${ms(rest.reduce((a, b) => Math.max(a, b), 0))}`
9730
+ ].join(", ")}`
9731
+ );
9732
+ }
9789
9733
  processInitialStorage(nodeMapBuffer.take());
9790
9734
  break;
9735
+ }
9791
9736
  case ServerMsgCode.UPDATE_STORAGE: {
9792
9737
  const applyResult = applyRemoteOps(message.ops);
9793
9738
  for (const [key, value] of applyResult.updates.storageUpdates) {
@@ -9952,6 +9897,7 @@ function createRoom(options, config) {
9952
9897
  } else if (!messages.some((msg) => msg.type === ClientMsgCode.FETCH_STORAGE)) {
9953
9898
  messages.push({ type: ClientMsgCode.FETCH_STORAGE });
9954
9899
  nodeMapBuffer.take();
9900
+ _optionalChain([stopwatch, 'optionalAccess', _217 => _217.start, 'call', _218 => _218()]);
9955
9901
  }
9956
9902
  if (options2.flush) {
9957
9903
  flushNowOrSoon();
@@ -10154,8 +10100,8 @@ function createRoom(options, config) {
10154
10100
  async function getThreads(options2) {
10155
10101
  return httpClient.getThreads({
10156
10102
  roomId,
10157
- query: _optionalChain([options2, 'optionalAccess', _217 => _217.query]),
10158
- cursor: _optionalChain([options2, 'optionalAccess', _218 => _218.cursor])
10103
+ query: _optionalChain([options2, 'optionalAccess', _219 => _219.query]),
10104
+ cursor: _optionalChain([options2, 'optionalAccess', _220 => _220.cursor])
10159
10105
  });
10160
10106
  }
10161
10107
  async function getThread(threadId) {
@@ -10277,7 +10223,7 @@ function createRoom(options, config) {
10277
10223
  function getSubscriptionSettings(options2) {
10278
10224
  return httpClient.getSubscriptionSettings({
10279
10225
  roomId,
10280
- signal: _optionalChain([options2, 'optionalAccess', _219 => _219.signal])
10226
+ signal: _optionalChain([options2, 'optionalAccess', _221 => _221.signal])
10281
10227
  });
10282
10228
  }
10283
10229
  function updateSubscriptionSettings(settings) {
@@ -10299,7 +10245,7 @@ function createRoom(options, config) {
10299
10245
  {
10300
10246
  [kInternal]: {
10301
10247
  get presenceBuffer() {
10302
- return deepClone(_nullishCoalesce(_optionalChain([context, 'access', _220 => _220.buffer, 'access', _221 => _221.presenceUpdates, 'optionalAccess', _222 => _222.data]), () => ( null)));
10248
+ return deepClone(_nullishCoalesce(_optionalChain([context, 'access', _222 => _222.buffer, 'access', _223 => _223.presenceUpdates, 'optionalAccess', _224 => _224.data]), () => ( null)));
10303
10249
  },
10304
10250
  // prettier-ignore
10305
10251
  get undoStack() {
@@ -10314,9 +10260,9 @@ function createRoom(options, config) {
10314
10260
  return context.yjsProvider;
10315
10261
  },
10316
10262
  setYjsProvider(newProvider) {
10317
- _optionalChain([context, 'access', _223 => _223.yjsProvider, 'optionalAccess', _224 => _224.off, 'call', _225 => _225("status", yjsStatusDidChange)]);
10263
+ _optionalChain([context, 'access', _225 => _225.yjsProvider, 'optionalAccess', _226 => _226.off, 'call', _227 => _227("status", yjsStatusDidChange)]);
10318
10264
  context.yjsProvider = newProvider;
10319
- _optionalChain([newProvider, 'optionalAccess', _226 => _226.on, 'call', _227 => _227("status", yjsStatusDidChange)]);
10265
+ _optionalChain([newProvider, 'optionalAccess', _228 => _228.on, 'call', _229 => _229("status", yjsStatusDidChange)]);
10320
10266
  context.yjsProviderDidChange.notify();
10321
10267
  },
10322
10268
  yjsProviderDidChange: context.yjsProviderDidChange.observable,
@@ -10362,7 +10308,7 @@ function createRoom(options, config) {
10362
10308
  source.dispose();
10363
10309
  }
10364
10310
  eventHub.roomWillDestroy.notify();
10365
- _optionalChain([context, 'access', _228 => _228.yjsProvider, 'optionalAccess', _229 => _229.off, 'call', _230 => _230("status", yjsStatusDidChange)]);
10311
+ _optionalChain([context, 'access', _230 => _230.yjsProvider, 'optionalAccess', _231 => _231.off, 'call', _232 => _232("status", yjsStatusDidChange)]);
10366
10312
  syncSourceForStorage.destroy();
10367
10313
  syncSourceForYjs.destroy();
10368
10314
  uninstallBgTabSpy();
@@ -10513,7 +10459,7 @@ function makeClassicSubscribeFn(roomId, events, errorEvents) {
10513
10459
  }
10514
10460
  if (isLiveNode(first)) {
10515
10461
  const node = first;
10516
- if (_optionalChain([options, 'optionalAccess', _231 => _231.isDeep])) {
10462
+ if (_optionalChain([options, 'optionalAccess', _233 => _233.isDeep])) {
10517
10463
  const storageCallback = second;
10518
10464
  return subscribeToLiveStructureDeeply(node, storageCallback);
10519
10465
  } else {
@@ -10595,8 +10541,8 @@ function createClient(options) {
10595
10541
  const authManager = createAuthManager(options, (token) => {
10596
10542
  currentUserId.set(() => token.uid);
10597
10543
  });
10598
- const fetchPolyfill = _optionalChain([clientOptions, 'access', _232 => _232.polyfills, 'optionalAccess', _233 => _233.fetch]) || /* istanbul ignore next */
10599
- _optionalChain([globalThis, 'access', _234 => _234.fetch, 'optionalAccess', _235 => _235.bind, 'call', _236 => _236(globalThis)]);
10544
+ const fetchPolyfill = _optionalChain([clientOptions, 'access', _234 => _234.polyfills, 'optionalAccess', _235 => _235.fetch]) || /* istanbul ignore next */
10545
+ _optionalChain([globalThis, 'access', _236 => _236.fetch, 'optionalAccess', _237 => _237.bind, 'call', _238 => _238(globalThis)]);
10600
10546
  const httpClient = createApiClient({
10601
10547
  baseUrl,
10602
10548
  fetchPolyfill,
@@ -10614,7 +10560,7 @@ function createClient(options) {
10614
10560
  delegates: {
10615
10561
  createSocket: makeCreateSocketDelegateForAi(
10616
10562
  baseUrl,
10617
- _optionalChain([clientOptions, 'access', _237 => _237.polyfills, 'optionalAccess', _238 => _238.WebSocket])
10563
+ _optionalChain([clientOptions, 'access', _239 => _239.polyfills, 'optionalAccess', _240 => _240.WebSocket])
10618
10564
  ),
10619
10565
  authenticate: async () => {
10620
10566
  const resp = await authManager.getAuthValue({
@@ -10674,7 +10620,7 @@ function createClient(options) {
10674
10620
  createSocket: makeCreateSocketDelegateForRoom(
10675
10621
  roomId,
10676
10622
  baseUrl,
10677
- _optionalChain([clientOptions, 'access', _239 => _239.polyfills, 'optionalAccess', _240 => _240.WebSocket]),
10623
+ _optionalChain([clientOptions, 'access', _241 => _241.polyfills, 'optionalAccess', _242 => _242.WebSocket]),
10678
10624
  options2.engine
10679
10625
  ),
10680
10626
  authenticate: makeAuthDelegateForRoom(roomId, authManager)
@@ -10682,7 +10628,6 @@ function createClient(options) {
10682
10628
  enableDebugLogging: clientOptions.enableDebugLogging,
10683
10629
  baseUrl,
10684
10630
  errorEventSource: liveblocksErrorSource,
10685
- largeMessageStrategy: clientOptions.largeMessageStrategy,
10686
10631
  unstable_streamData: !!clientOptions.unstable_streamData,
10687
10632
  roomHttpClient: httpClient,
10688
10633
  createSyncSource,
@@ -10699,7 +10644,7 @@ function createClient(options) {
10699
10644
  const shouldConnect = _nullishCoalesce(options2.autoConnect, () => ( true));
10700
10645
  if (shouldConnect) {
10701
10646
  if (typeof atob === "undefined") {
10702
- if (_optionalChain([clientOptions, 'access', _241 => _241.polyfills, 'optionalAccess', _242 => _242.atob]) === void 0) {
10647
+ if (_optionalChain([clientOptions, 'access', _243 => _243.polyfills, 'optionalAccess', _244 => _244.atob]) === void 0) {
10703
10648
  throw new Error(
10704
10649
  "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"
10705
10650
  );
@@ -10711,7 +10656,7 @@ function createClient(options) {
10711
10656
  return leaseRoom(newRoomDetails);
10712
10657
  }
10713
10658
  function getRoom(roomId) {
10714
- const room = _optionalChain([roomsById, 'access', _243 => _243.get, 'call', _244 => _244(roomId), 'optionalAccess', _245 => _245.room]);
10659
+ const room = _optionalChain([roomsById, 'access', _245 => _245.get, 'call', _246 => _246(roomId), 'optionalAccess', _247 => _247.room]);
10715
10660
  return room ? room : null;
10716
10661
  }
10717
10662
  function logout() {
@@ -10727,7 +10672,7 @@ function createClient(options) {
10727
10672
  const batchedResolveUsers = new Batch(
10728
10673
  async (batchedUserIds) => {
10729
10674
  const userIds = batchedUserIds.flat();
10730
- const users = await _optionalChain([resolveUsers, 'optionalCall', _246 => _246({ userIds })]);
10675
+ const users = await _optionalChain([resolveUsers, 'optionalCall', _248 => _248({ userIds })]);
10731
10676
  warnOnceIf(
10732
10677
  !resolveUsers,
10733
10678
  "Set the resolveUsers option in createClient to specify user info."
@@ -10744,7 +10689,7 @@ function createClient(options) {
10744
10689
  const batchedResolveRoomsInfo = new Batch(
10745
10690
  async (batchedRoomIds) => {
10746
10691
  const roomIds = batchedRoomIds.flat();
10747
- const roomsInfo = await _optionalChain([resolveRoomsInfo, 'optionalCall', _247 => _247({ roomIds })]);
10692
+ const roomsInfo = await _optionalChain([resolveRoomsInfo, 'optionalCall', _249 => _249({ roomIds })]);
10748
10693
  warnOnceIf(
10749
10694
  !resolveRoomsInfo,
10750
10695
  "Set the resolveRoomsInfo option in createClient to specify room info."
@@ -10761,7 +10706,7 @@ function createClient(options) {
10761
10706
  const batchedResolveGroupsInfo = new Batch(
10762
10707
  async (batchedGroupIds) => {
10763
10708
  const groupIds = batchedGroupIds.flat();
10764
- const groupsInfo = await _optionalChain([resolveGroupsInfo, 'optionalCall', _248 => _248({ groupIds })]);
10709
+ const groupsInfo = await _optionalChain([resolveGroupsInfo, 'optionalCall', _250 => _250({ groupIds })]);
10765
10710
  warnOnceIf(
10766
10711
  !resolveGroupsInfo,
10767
10712
  "Set the resolveGroupsInfo option in createClient to specify group info."
@@ -10817,7 +10762,7 @@ function createClient(options) {
10817
10762
  }
10818
10763
  };
10819
10764
  const win = typeof window !== "undefined" ? window : void 0;
10820
- _optionalChain([win, 'optionalAccess', _249 => _249.addEventListener, 'call', _250 => _250("beforeunload", maybePreventClose)]);
10765
+ _optionalChain([win, 'optionalAccess', _251 => _251.addEventListener, 'call', _252 => _252("beforeunload", maybePreventClose)]);
10821
10766
  }
10822
10767
  async function getNotificationSettings(options2) {
10823
10768
  const plainSettings = await httpClient.getNotificationSettings(options2);
@@ -10944,7 +10889,7 @@ var commentBodyElementsTypes = {
10944
10889
  mention: "inline"
10945
10890
  };
10946
10891
  function traverseCommentBody(body, elementOrVisitor, possiblyVisitor) {
10947
- if (!body || !_optionalChain([body, 'optionalAccess', _251 => _251.content])) {
10892
+ if (!body || !_optionalChain([body, 'optionalAccess', _253 => _253.content])) {
10948
10893
  return;
10949
10894
  }
10950
10895
  const element = typeof elementOrVisitor === "string" ? elementOrVisitor : void 0;
@@ -10954,13 +10899,13 @@ function traverseCommentBody(body, elementOrVisitor, possiblyVisitor) {
10954
10899
  for (const block of body.content) {
10955
10900
  if (type === "all" || type === "block") {
10956
10901
  if (guard(block)) {
10957
- _optionalChain([visitor, 'optionalCall', _252 => _252(block)]);
10902
+ _optionalChain([visitor, 'optionalCall', _254 => _254(block)]);
10958
10903
  }
10959
10904
  }
10960
10905
  if (type === "all" || type === "inline") {
10961
10906
  for (const inline of block.children) {
10962
10907
  if (guard(inline)) {
10963
- _optionalChain([visitor, 'optionalCall', _253 => _253(inline)]);
10908
+ _optionalChain([visitor, 'optionalCall', _255 => _255(inline)]);
10964
10909
  }
10965
10910
  }
10966
10911
  }
@@ -11130,7 +11075,7 @@ var stringifyCommentBodyPlainElements = {
11130
11075
  text: ({ element }) => element.text,
11131
11076
  link: ({ element }) => _nullishCoalesce(element.text, () => ( element.url)),
11132
11077
  mention: ({ element, user, group }) => {
11133
- return `@${_nullishCoalesce(_nullishCoalesce(_optionalChain([user, 'optionalAccess', _254 => _254.name]), () => ( _optionalChain([group, 'optionalAccess', _255 => _255.name]))), () => ( element.id))}`;
11078
+ return `@${_nullishCoalesce(_nullishCoalesce(_optionalChain([user, 'optionalAccess', _256 => _256.name]), () => ( _optionalChain([group, 'optionalAccess', _257 => _257.name]))), () => ( element.id))}`;
11134
11079
  }
11135
11080
  };
11136
11081
  var stringifyCommentBodyHtmlElements = {
@@ -11160,7 +11105,7 @@ var stringifyCommentBodyHtmlElements = {
11160
11105
  return html`<a href="${href}" target="_blank" rel="noopener noreferrer">${element.text ? html`${element.text}` : element.url}</a>`;
11161
11106
  },
11162
11107
  mention: ({ element, user, group }) => {
11163
- return html`<span data-mention>@${_optionalChain([user, 'optionalAccess', _256 => _256.name]) ? html`${_optionalChain([user, 'optionalAccess', _257 => _257.name])}` : _optionalChain([group, 'optionalAccess', _258 => _258.name]) ? html`${_optionalChain([group, 'optionalAccess', _259 => _259.name])}` : element.id}</span>`;
11108
+ return html`<span data-mention>@${_optionalChain([user, 'optionalAccess', _258 => _258.name]) ? html`${_optionalChain([user, 'optionalAccess', _259 => _259.name])}` : _optionalChain([group, 'optionalAccess', _260 => _260.name]) ? html`${_optionalChain([group, 'optionalAccess', _261 => _261.name])}` : element.id}</span>`;
11164
11109
  }
11165
11110
  };
11166
11111
  var stringifyCommentBodyMarkdownElements = {
@@ -11190,20 +11135,20 @@ var stringifyCommentBodyMarkdownElements = {
11190
11135
  return markdown`[${_nullishCoalesce(element.text, () => ( element.url))}](${href})`;
11191
11136
  },
11192
11137
  mention: ({ element, user, group }) => {
11193
- return markdown`@${_nullishCoalesce(_nullishCoalesce(_optionalChain([user, 'optionalAccess', _260 => _260.name]), () => ( _optionalChain([group, 'optionalAccess', _261 => _261.name]))), () => ( element.id))}`;
11138
+ return markdown`@${_nullishCoalesce(_nullishCoalesce(_optionalChain([user, 'optionalAccess', _262 => _262.name]), () => ( _optionalChain([group, 'optionalAccess', _263 => _263.name]))), () => ( element.id))}`;
11194
11139
  }
11195
11140
  };
11196
11141
  async function stringifyCommentBody(body, options) {
11197
- const format = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _262 => _262.format]), () => ( "plain"));
11198
- const separator = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _263 => _263.separator]), () => ( (format === "markdown" ? "\n\n" : "\n")));
11142
+ const format = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _264 => _264.format]), () => ( "plain"));
11143
+ const separator = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _265 => _265.separator]), () => ( (format === "markdown" ? "\n\n" : "\n")));
11199
11144
  const elements = {
11200
11145
  ...format === "html" ? stringifyCommentBodyHtmlElements : format === "markdown" ? stringifyCommentBodyMarkdownElements : stringifyCommentBodyPlainElements,
11201
- ..._optionalChain([options, 'optionalAccess', _264 => _264.elements])
11146
+ ..._optionalChain([options, 'optionalAccess', _266 => _266.elements])
11202
11147
  };
11203
11148
  const { users: resolvedUsers, groups: resolvedGroupsInfo } = await resolveMentionsInCommentBody(
11204
11149
  body,
11205
- _optionalChain([options, 'optionalAccess', _265 => _265.resolveUsers]),
11206
- _optionalChain([options, 'optionalAccess', _266 => _266.resolveGroupsInfo])
11150
+ _optionalChain([options, 'optionalAccess', _267 => _267.resolveUsers]),
11151
+ _optionalChain([options, 'optionalAccess', _268 => _268.resolveGroupsInfo])
11207
11152
  );
11208
11153
  const blocks = body.content.flatMap((block, blockIndex) => {
11209
11154
  switch (block.type) {
@@ -11490,12 +11435,12 @@ function legacy_patchImmutableNode(state, path, update) {
11490
11435
  }
11491
11436
  const newState = Object.assign({}, state);
11492
11437
  for (const key in update.updates) {
11493
- if (_optionalChain([update, 'access', _267 => _267.updates, 'access', _268 => _268[key], 'optionalAccess', _269 => _269.type]) === "update") {
11438
+ if (_optionalChain([update, 'access', _269 => _269.updates, 'access', _270 => _270[key], 'optionalAccess', _271 => _271.type]) === "update") {
11494
11439
  const val = update.node.get(key);
11495
11440
  if (val !== void 0) {
11496
11441
  newState[key] = lsonToJson(val);
11497
11442
  }
11498
- } else if (_optionalChain([update, 'access', _270 => _270.updates, 'access', _271 => _271[key], 'optionalAccess', _272 => _272.type]) === "delete") {
11443
+ } else if (_optionalChain([update, 'access', _272 => _272.updates, 'access', _273 => _273[key], 'optionalAccess', _274 => _274.type]) === "delete") {
11499
11444
  delete newState[key];
11500
11445
  }
11501
11446
  }
@@ -11556,12 +11501,12 @@ function legacy_patchImmutableNode(state, path, update) {
11556
11501
  }
11557
11502
  const newState = Object.assign({}, state);
11558
11503
  for (const key in update.updates) {
11559
- if (_optionalChain([update, 'access', _273 => _273.updates, 'access', _274 => _274[key], 'optionalAccess', _275 => _275.type]) === "update") {
11504
+ if (_optionalChain([update, 'access', _275 => _275.updates, 'access', _276 => _276[key], 'optionalAccess', _277 => _277.type]) === "update") {
11560
11505
  const value = update.node.get(key);
11561
11506
  if (value !== void 0) {
11562
11507
  newState[key] = lsonToJson(value);
11563
11508
  }
11564
- } else if (_optionalChain([update, 'access', _276 => _276.updates, 'access', _277 => _277[key], 'optionalAccess', _278 => _278.type]) === "delete") {
11509
+ } else if (_optionalChain([update, 'access', _278 => _278.updates, 'access', _279 => _279[key], 'optionalAccess', _280 => _280.type]) === "delete") {
11565
11510
  delete newState[key];
11566
11511
  }
11567
11512
  }
@@ -11641,9 +11586,9 @@ function makePoller(callback, intervalMs, options) {
11641
11586
  const startTime = performance.now();
11642
11587
  const doc = typeof document !== "undefined" ? document : void 0;
11643
11588
  const win = typeof window !== "undefined" ? window : void 0;
11644
- const maxStaleTimeMs = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _279 => _279.maxStaleTimeMs]), () => ( Number.POSITIVE_INFINITY));
11589
+ const maxStaleTimeMs = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _281 => _281.maxStaleTimeMs]), () => ( Number.POSITIVE_INFINITY));
11645
11590
  const context = {
11646
- inForeground: _optionalChain([doc, 'optionalAccess', _280 => _280.visibilityState]) !== "hidden",
11591
+ inForeground: _optionalChain([doc, 'optionalAccess', _282 => _282.visibilityState]) !== "hidden",
11647
11592
  lastSuccessfulPollAt: startTime,
11648
11593
  count: 0,
11649
11594
  backoff: 0
@@ -11724,11 +11669,11 @@ function makePoller(callback, intervalMs, options) {
11724
11669
  pollNowIfStale();
11725
11670
  }
11726
11671
  function onVisibilityChange() {
11727
- setInForeground(_optionalChain([doc, 'optionalAccess', _281 => _281.visibilityState]) !== "hidden");
11672
+ setInForeground(_optionalChain([doc, 'optionalAccess', _283 => _283.visibilityState]) !== "hidden");
11728
11673
  }
11729
- _optionalChain([doc, 'optionalAccess', _282 => _282.addEventListener, 'call', _283 => _283("visibilitychange", onVisibilityChange)]);
11730
- _optionalChain([win, 'optionalAccess', _284 => _284.addEventListener, 'call', _285 => _285("online", onVisibilityChange)]);
11731
- _optionalChain([win, 'optionalAccess', _286 => _286.addEventListener, 'call', _287 => _287("focus", pollNowIfStale)]);
11674
+ _optionalChain([doc, 'optionalAccess', _284 => _284.addEventListener, 'call', _285 => _285("visibilitychange", onVisibilityChange)]);
11675
+ _optionalChain([win, 'optionalAccess', _286 => _286.addEventListener, 'call', _287 => _287("online", onVisibilityChange)]);
11676
+ _optionalChain([win, 'optionalAccess', _288 => _288.addEventListener, 'call', _289 => _289("focus", pollNowIfStale)]);
11732
11677
  fsm.start();
11733
11678
  return {
11734
11679
  inc,