@liveblocks/core 3.14.0-pre6 → 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-pre6";
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,
@@ -8744,6 +8730,29 @@ function isJsonObject(data) {
8744
8730
  return !isJsonScalar(data) && !isJsonArray(data);
8745
8731
  }
8746
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
+
8747
8756
  // src/protocol/ClientMsg.ts
8748
8757
  var ClientMsgCode = Object.freeze({
8749
8758
  // For Presence
@@ -8996,7 +9005,6 @@ function defaultMessageFromContext(context) {
8996
9005
  }
8997
9006
 
8998
9007
  // src/room.ts
8999
- var MAX_SOCKET_MESSAGE_SIZE = 1024 * 1024 - 512;
9000
9008
  function makeIdFactory(connectionId) {
9001
9009
  let count = 0;
9002
9010
  return () => `${connectionId}:${count++}`;
@@ -9109,6 +9117,7 @@ function createRoom(options, config) {
9109
9117
  unacknowledgedOps: /* @__PURE__ */ new Map()
9110
9118
  };
9111
9119
  const nodeMapBuffer = makeNodeMapBuffer();
9120
+ const stopwatch = config.enableDebugLogging ? makeStopWatch() : void 0;
9112
9121
  let lastTokenKey;
9113
9122
  function onStatusDidChange(newStatus) {
9114
9123
  const authValue = managedSocket.authValue;
@@ -9263,100 +9272,8 @@ function createRoom(options, config) {
9263
9272
  ...options2
9264
9273
  });
9265
9274
  }
9266
- function* chunkOps(msg) {
9267
- const { ops, ...rest } = msg;
9268
- if (ops.length < 2) {
9269
- throw new Error("Cannot split ops into smaller chunks");
9270
- }
9271
- const mid = Math.floor(ops.length / 2);
9272
- const firstHalf = ops.slice(0, mid);
9273
- const secondHalf = ops.slice(mid);
9274
- for (const halfOps of [firstHalf, secondHalf]) {
9275
- const half = { ops: halfOps, ...rest };
9276
- const text = stringifyOrLog([half]);
9277
- if (!isTooBigForWebSocket(text)) {
9278
- yield text;
9279
- } else {
9280
- yield* chunkOps(half);
9281
- }
9282
- }
9283
- }
9284
- function* chunkMessages(messages) {
9285
- if (messages.length < 2) {
9286
- if (messages[0].type === ClientMsgCode.UPDATE_STORAGE) {
9287
- yield* chunkOps(messages[0]);
9288
- return;
9289
- } else {
9290
- throw new Error(
9291
- "Cannot split into chunks smaller than the allowed message size"
9292
- );
9293
- }
9294
- }
9295
- const mid = Math.floor(messages.length / 2);
9296
- const firstHalf = messages.slice(0, mid);
9297
- const secondHalf = messages.slice(mid);
9298
- for (const half of [firstHalf, secondHalf]) {
9299
- const text = stringifyOrLog(half);
9300
- if (!isTooBigForWebSocket(text)) {
9301
- yield text;
9302
- } else {
9303
- yield* chunkMessages(half);
9304
- }
9305
- }
9306
- }
9307
- function isTooBigForWebSocket(text) {
9308
- if (text.length * 4 < MAX_SOCKET_MESSAGE_SIZE) {
9309
- return false;
9310
- }
9311
- return new TextEncoder().encode(text).length >= MAX_SOCKET_MESSAGE_SIZE;
9312
- }
9313
9275
  function sendMessages(messages) {
9314
- const strategy = _nullishCoalesce(config.largeMessageStrategy, () => ( "default"));
9315
- const text = stringifyOrLog(messages);
9316
- if (!isTooBigForWebSocket(text)) {
9317
- return managedSocket.send(text);
9318
- }
9319
- switch (strategy) {
9320
- case "default": {
9321
- const type = "LARGE_MESSAGE_ERROR";
9322
- const err = new LiveblocksError("Message is too large for websockets", {
9323
- type
9324
- });
9325
- const didNotify = config.errorEventSource.notify(err);
9326
- if (!didNotify) {
9327
- error2(
9328
- "Message is too large for websockets. Configure largeMessageStrategy option or useErrorListener to handle this."
9329
- );
9330
- }
9331
- return;
9332
- }
9333
- case "split": {
9334
- warn("Message is too large for websockets, splitting into smaller chunks");
9335
- for (const chunk2 of chunkMessages(messages)) {
9336
- managedSocket.send(chunk2);
9337
- }
9338
- return;
9339
- }
9340
- // NOTE: This strategy is experimental as it will not work in all situations.
9341
- // It should only be used for broadcasting, presence updates, but isn't suitable
9342
- // for Storage or Yjs updates yet (because through this channel the server does
9343
- // not respond with acks or rejections, causing the client's reported status to
9344
- // be stuck in "synchronizing" forever).
9345
- case "experimental-fallback-to-http": {
9346
- warn("Message is too large for websockets, so sending over HTTP instead");
9347
- 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")));
9348
- void httpClient.sendMessagesOverHTTP({ roomId, nonce, messages }).then((resp) => {
9349
- if (!resp.ok && resp.status === 403) {
9350
- managedSocket.reconnect();
9351
- }
9352
- }).catch((err) => {
9353
- error2(
9354
- `Failed to deliver message over HTTP: ${String(err)}`
9355
- );
9356
- });
9357
- return;
9358
- }
9359
- }
9276
+ managedSocket.send(stringifyOrLog(messages));
9360
9277
  }
9361
9278
  const self = DerivedSignal.from(
9362
9279
  context.staticSessionInfoSig,
@@ -9408,7 +9325,7 @@ function createRoom(options, config) {
9408
9325
  context.pool
9409
9326
  );
9410
9327
  }
9411
- 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));
9412
9329
  const stackSizeBefore = context.undoStack.length;
9413
9330
  for (const key in context.initialStorage) {
9414
9331
  if (context.root.get(key) === void 0) {
@@ -9612,7 +9529,7 @@ function createRoom(options, config) {
9612
9529
  }
9613
9530
  context.myPresence.patch(patch);
9614
9531
  if (context.activeBatch) {
9615
- if (_optionalChain([options2, 'optionalAccess', _214 => _214.addToHistory])) {
9532
+ if (_optionalChain([options2, 'optionalAccess', _210 => _210.addToHistory])) {
9616
9533
  context.activeBatch.reverseOps.pushLeft({
9617
9534
  type: "presence",
9618
9535
  data: oldValues
@@ -9621,7 +9538,7 @@ function createRoom(options, config) {
9621
9538
  context.activeBatch.updates.presence = true;
9622
9539
  } else {
9623
9540
  flushNowOrSoon();
9624
- if (_optionalChain([options2, 'optionalAccess', _215 => _215.addToHistory])) {
9541
+ if (_optionalChain([options2, 'optionalAccess', _211 => _211.addToHistory])) {
9625
9542
  addToUndoStack([{ type: "presence", data: oldValues }]);
9626
9543
  }
9627
9544
  notify({ presence: true });
@@ -9795,11 +9712,27 @@ function createRoom(options, config) {
9795
9712
  break;
9796
9713
  }
9797
9714
  case ServerMsgCode.STORAGE_CHUNK:
9715
+ _optionalChain([stopwatch, 'optionalAccess', _212 => _212.lap, 'call', _213 => _213()]);
9798
9716
  nodeMapBuffer.append(compactNodesToNodeStream(message.nodes));
9799
9717
  break;
9800
- 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
+ }
9801
9733
  processInitialStorage(nodeMapBuffer.take());
9802
9734
  break;
9735
+ }
9803
9736
  case ServerMsgCode.UPDATE_STORAGE: {
9804
9737
  const applyResult = applyRemoteOps(message.ops);
9805
9738
  for (const [key, value] of applyResult.updates.storageUpdates) {
@@ -9964,6 +9897,7 @@ function createRoom(options, config) {
9964
9897
  } else if (!messages.some((msg) => msg.type === ClientMsgCode.FETCH_STORAGE)) {
9965
9898
  messages.push({ type: ClientMsgCode.FETCH_STORAGE });
9966
9899
  nodeMapBuffer.take();
9900
+ _optionalChain([stopwatch, 'optionalAccess', _217 => _217.start, 'call', _218 => _218()]);
9967
9901
  }
9968
9902
  if (options2.flush) {
9969
9903
  flushNowOrSoon();
@@ -10166,8 +10100,8 @@ function createRoom(options, config) {
10166
10100
  async function getThreads(options2) {
10167
10101
  return httpClient.getThreads({
10168
10102
  roomId,
10169
- query: _optionalChain([options2, 'optionalAccess', _217 => _217.query]),
10170
- cursor: _optionalChain([options2, 'optionalAccess', _218 => _218.cursor])
10103
+ query: _optionalChain([options2, 'optionalAccess', _219 => _219.query]),
10104
+ cursor: _optionalChain([options2, 'optionalAccess', _220 => _220.cursor])
10171
10105
  });
10172
10106
  }
10173
10107
  async function getThread(threadId) {
@@ -10289,7 +10223,7 @@ function createRoom(options, config) {
10289
10223
  function getSubscriptionSettings(options2) {
10290
10224
  return httpClient.getSubscriptionSettings({
10291
10225
  roomId,
10292
- signal: _optionalChain([options2, 'optionalAccess', _219 => _219.signal])
10226
+ signal: _optionalChain([options2, 'optionalAccess', _221 => _221.signal])
10293
10227
  });
10294
10228
  }
10295
10229
  function updateSubscriptionSettings(settings) {
@@ -10311,7 +10245,7 @@ function createRoom(options, config) {
10311
10245
  {
10312
10246
  [kInternal]: {
10313
10247
  get presenceBuffer() {
10314
- 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)));
10315
10249
  },
10316
10250
  // prettier-ignore
10317
10251
  get undoStack() {
@@ -10326,9 +10260,9 @@ function createRoom(options, config) {
10326
10260
  return context.yjsProvider;
10327
10261
  },
10328
10262
  setYjsProvider(newProvider) {
10329
- _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)]);
10330
10264
  context.yjsProvider = newProvider;
10331
- _optionalChain([newProvider, 'optionalAccess', _226 => _226.on, 'call', _227 => _227("status", yjsStatusDidChange)]);
10265
+ _optionalChain([newProvider, 'optionalAccess', _228 => _228.on, 'call', _229 => _229("status", yjsStatusDidChange)]);
10332
10266
  context.yjsProviderDidChange.notify();
10333
10267
  },
10334
10268
  yjsProviderDidChange: context.yjsProviderDidChange.observable,
@@ -10374,7 +10308,7 @@ function createRoom(options, config) {
10374
10308
  source.dispose();
10375
10309
  }
10376
10310
  eventHub.roomWillDestroy.notify();
10377
- _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)]);
10378
10312
  syncSourceForStorage.destroy();
10379
10313
  syncSourceForYjs.destroy();
10380
10314
  uninstallBgTabSpy();
@@ -10525,7 +10459,7 @@ function makeClassicSubscribeFn(roomId, events, errorEvents) {
10525
10459
  }
10526
10460
  if (isLiveNode(first)) {
10527
10461
  const node = first;
10528
- if (_optionalChain([options, 'optionalAccess', _231 => _231.isDeep])) {
10462
+ if (_optionalChain([options, 'optionalAccess', _233 => _233.isDeep])) {
10529
10463
  const storageCallback = second;
10530
10464
  return subscribeToLiveStructureDeeply(node, storageCallback);
10531
10465
  } else {
@@ -10607,8 +10541,8 @@ function createClient(options) {
10607
10541
  const authManager = createAuthManager(options, (token) => {
10608
10542
  currentUserId.set(() => token.uid);
10609
10543
  });
10610
- const fetchPolyfill = _optionalChain([clientOptions, 'access', _232 => _232.polyfills, 'optionalAccess', _233 => _233.fetch]) || /* istanbul ignore next */
10611
- _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)]);
10612
10546
  const httpClient = createApiClient({
10613
10547
  baseUrl,
10614
10548
  fetchPolyfill,
@@ -10626,7 +10560,7 @@ function createClient(options) {
10626
10560
  delegates: {
10627
10561
  createSocket: makeCreateSocketDelegateForAi(
10628
10562
  baseUrl,
10629
- _optionalChain([clientOptions, 'access', _237 => _237.polyfills, 'optionalAccess', _238 => _238.WebSocket])
10563
+ _optionalChain([clientOptions, 'access', _239 => _239.polyfills, 'optionalAccess', _240 => _240.WebSocket])
10630
10564
  ),
10631
10565
  authenticate: async () => {
10632
10566
  const resp = await authManager.getAuthValue({
@@ -10686,7 +10620,7 @@ function createClient(options) {
10686
10620
  createSocket: makeCreateSocketDelegateForRoom(
10687
10621
  roomId,
10688
10622
  baseUrl,
10689
- _optionalChain([clientOptions, 'access', _239 => _239.polyfills, 'optionalAccess', _240 => _240.WebSocket]),
10623
+ _optionalChain([clientOptions, 'access', _241 => _241.polyfills, 'optionalAccess', _242 => _242.WebSocket]),
10690
10624
  options2.engine
10691
10625
  ),
10692
10626
  authenticate: makeAuthDelegateForRoom(roomId, authManager)
@@ -10694,7 +10628,6 @@ function createClient(options) {
10694
10628
  enableDebugLogging: clientOptions.enableDebugLogging,
10695
10629
  baseUrl,
10696
10630
  errorEventSource: liveblocksErrorSource,
10697
- largeMessageStrategy: clientOptions.largeMessageStrategy,
10698
10631
  unstable_streamData: !!clientOptions.unstable_streamData,
10699
10632
  roomHttpClient: httpClient,
10700
10633
  createSyncSource,
@@ -10711,7 +10644,7 @@ function createClient(options) {
10711
10644
  const shouldConnect = _nullishCoalesce(options2.autoConnect, () => ( true));
10712
10645
  if (shouldConnect) {
10713
10646
  if (typeof atob === "undefined") {
10714
- 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) {
10715
10648
  throw new Error(
10716
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"
10717
10650
  );
@@ -10723,7 +10656,7 @@ function createClient(options) {
10723
10656
  return leaseRoom(newRoomDetails);
10724
10657
  }
10725
10658
  function getRoom(roomId) {
10726
- 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]);
10727
10660
  return room ? room : null;
10728
10661
  }
10729
10662
  function logout() {
@@ -10739,7 +10672,7 @@ function createClient(options) {
10739
10672
  const batchedResolveUsers = new Batch(
10740
10673
  async (batchedUserIds) => {
10741
10674
  const userIds = batchedUserIds.flat();
10742
- const users = await _optionalChain([resolveUsers, 'optionalCall', _246 => _246({ userIds })]);
10675
+ const users = await _optionalChain([resolveUsers, 'optionalCall', _248 => _248({ userIds })]);
10743
10676
  warnOnceIf(
10744
10677
  !resolveUsers,
10745
10678
  "Set the resolveUsers option in createClient to specify user info."
@@ -10756,7 +10689,7 @@ function createClient(options) {
10756
10689
  const batchedResolveRoomsInfo = new Batch(
10757
10690
  async (batchedRoomIds) => {
10758
10691
  const roomIds = batchedRoomIds.flat();
10759
- const roomsInfo = await _optionalChain([resolveRoomsInfo, 'optionalCall', _247 => _247({ roomIds })]);
10692
+ const roomsInfo = await _optionalChain([resolveRoomsInfo, 'optionalCall', _249 => _249({ roomIds })]);
10760
10693
  warnOnceIf(
10761
10694
  !resolveRoomsInfo,
10762
10695
  "Set the resolveRoomsInfo option in createClient to specify room info."
@@ -10773,7 +10706,7 @@ function createClient(options) {
10773
10706
  const batchedResolveGroupsInfo = new Batch(
10774
10707
  async (batchedGroupIds) => {
10775
10708
  const groupIds = batchedGroupIds.flat();
10776
- const groupsInfo = await _optionalChain([resolveGroupsInfo, 'optionalCall', _248 => _248({ groupIds })]);
10709
+ const groupsInfo = await _optionalChain([resolveGroupsInfo, 'optionalCall', _250 => _250({ groupIds })]);
10777
10710
  warnOnceIf(
10778
10711
  !resolveGroupsInfo,
10779
10712
  "Set the resolveGroupsInfo option in createClient to specify group info."
@@ -10829,7 +10762,7 @@ function createClient(options) {
10829
10762
  }
10830
10763
  };
10831
10764
  const win = typeof window !== "undefined" ? window : void 0;
10832
- _optionalChain([win, 'optionalAccess', _249 => _249.addEventListener, 'call', _250 => _250("beforeunload", maybePreventClose)]);
10765
+ _optionalChain([win, 'optionalAccess', _251 => _251.addEventListener, 'call', _252 => _252("beforeunload", maybePreventClose)]);
10833
10766
  }
10834
10767
  async function getNotificationSettings(options2) {
10835
10768
  const plainSettings = await httpClient.getNotificationSettings(options2);
@@ -10956,7 +10889,7 @@ var commentBodyElementsTypes = {
10956
10889
  mention: "inline"
10957
10890
  };
10958
10891
  function traverseCommentBody(body, elementOrVisitor, possiblyVisitor) {
10959
- if (!body || !_optionalChain([body, 'optionalAccess', _251 => _251.content])) {
10892
+ if (!body || !_optionalChain([body, 'optionalAccess', _253 => _253.content])) {
10960
10893
  return;
10961
10894
  }
10962
10895
  const element = typeof elementOrVisitor === "string" ? elementOrVisitor : void 0;
@@ -10966,13 +10899,13 @@ function traverseCommentBody(body, elementOrVisitor, possiblyVisitor) {
10966
10899
  for (const block of body.content) {
10967
10900
  if (type === "all" || type === "block") {
10968
10901
  if (guard(block)) {
10969
- _optionalChain([visitor, 'optionalCall', _252 => _252(block)]);
10902
+ _optionalChain([visitor, 'optionalCall', _254 => _254(block)]);
10970
10903
  }
10971
10904
  }
10972
10905
  if (type === "all" || type === "inline") {
10973
10906
  for (const inline of block.children) {
10974
10907
  if (guard(inline)) {
10975
- _optionalChain([visitor, 'optionalCall', _253 => _253(inline)]);
10908
+ _optionalChain([visitor, 'optionalCall', _255 => _255(inline)]);
10976
10909
  }
10977
10910
  }
10978
10911
  }
@@ -11142,7 +11075,7 @@ var stringifyCommentBodyPlainElements = {
11142
11075
  text: ({ element }) => element.text,
11143
11076
  link: ({ element }) => _nullishCoalesce(element.text, () => ( element.url)),
11144
11077
  mention: ({ element, user, group }) => {
11145
- 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))}`;
11146
11079
  }
11147
11080
  };
11148
11081
  var stringifyCommentBodyHtmlElements = {
@@ -11172,7 +11105,7 @@ var stringifyCommentBodyHtmlElements = {
11172
11105
  return html`<a href="${href}" target="_blank" rel="noopener noreferrer">${element.text ? html`${element.text}` : element.url}</a>`;
11173
11106
  },
11174
11107
  mention: ({ element, user, group }) => {
11175
- 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>`;
11176
11109
  }
11177
11110
  };
11178
11111
  var stringifyCommentBodyMarkdownElements = {
@@ -11202,20 +11135,20 @@ var stringifyCommentBodyMarkdownElements = {
11202
11135
  return markdown`[${_nullishCoalesce(element.text, () => ( element.url))}](${href})`;
11203
11136
  },
11204
11137
  mention: ({ element, user, group }) => {
11205
- 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))}`;
11206
11139
  }
11207
11140
  };
11208
11141
  async function stringifyCommentBody(body, options) {
11209
- const format = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _262 => _262.format]), () => ( "plain"));
11210
- 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")));
11211
11144
  const elements = {
11212
11145
  ...format === "html" ? stringifyCommentBodyHtmlElements : format === "markdown" ? stringifyCommentBodyMarkdownElements : stringifyCommentBodyPlainElements,
11213
- ..._optionalChain([options, 'optionalAccess', _264 => _264.elements])
11146
+ ..._optionalChain([options, 'optionalAccess', _266 => _266.elements])
11214
11147
  };
11215
11148
  const { users: resolvedUsers, groups: resolvedGroupsInfo } = await resolveMentionsInCommentBody(
11216
11149
  body,
11217
- _optionalChain([options, 'optionalAccess', _265 => _265.resolveUsers]),
11218
- _optionalChain([options, 'optionalAccess', _266 => _266.resolveGroupsInfo])
11150
+ _optionalChain([options, 'optionalAccess', _267 => _267.resolveUsers]),
11151
+ _optionalChain([options, 'optionalAccess', _268 => _268.resolveGroupsInfo])
11219
11152
  );
11220
11153
  const blocks = body.content.flatMap((block, blockIndex) => {
11221
11154
  switch (block.type) {
@@ -11502,12 +11435,12 @@ function legacy_patchImmutableNode(state, path, update) {
11502
11435
  }
11503
11436
  const newState = Object.assign({}, state);
11504
11437
  for (const key in update.updates) {
11505
- 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") {
11506
11439
  const val = update.node.get(key);
11507
11440
  if (val !== void 0) {
11508
11441
  newState[key] = lsonToJson(val);
11509
11442
  }
11510
- } 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") {
11511
11444
  delete newState[key];
11512
11445
  }
11513
11446
  }
@@ -11568,12 +11501,12 @@ function legacy_patchImmutableNode(state, path, update) {
11568
11501
  }
11569
11502
  const newState = Object.assign({}, state);
11570
11503
  for (const key in update.updates) {
11571
- 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") {
11572
11505
  const value = update.node.get(key);
11573
11506
  if (value !== void 0) {
11574
11507
  newState[key] = lsonToJson(value);
11575
11508
  }
11576
- } 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") {
11577
11510
  delete newState[key];
11578
11511
  }
11579
11512
  }
@@ -11653,9 +11586,9 @@ function makePoller(callback, intervalMs, options) {
11653
11586
  const startTime = performance.now();
11654
11587
  const doc = typeof document !== "undefined" ? document : void 0;
11655
11588
  const win = typeof window !== "undefined" ? window : void 0;
11656
- 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));
11657
11590
  const context = {
11658
- inForeground: _optionalChain([doc, 'optionalAccess', _280 => _280.visibilityState]) !== "hidden",
11591
+ inForeground: _optionalChain([doc, 'optionalAccess', _282 => _282.visibilityState]) !== "hidden",
11659
11592
  lastSuccessfulPollAt: startTime,
11660
11593
  count: 0,
11661
11594
  backoff: 0
@@ -11736,11 +11669,11 @@ function makePoller(callback, intervalMs, options) {
11736
11669
  pollNowIfStale();
11737
11670
  }
11738
11671
  function onVisibilityChange() {
11739
- setInForeground(_optionalChain([doc, 'optionalAccess', _281 => _281.visibilityState]) !== "hidden");
11672
+ setInForeground(_optionalChain([doc, 'optionalAccess', _283 => _283.visibilityState]) !== "hidden");
11740
11673
  }
11741
- _optionalChain([doc, 'optionalAccess', _282 => _282.addEventListener, 'call', _283 => _283("visibilitychange", onVisibilityChange)]);
11742
- _optionalChain([win, 'optionalAccess', _284 => _284.addEventListener, 'call', _285 => _285("online", onVisibilityChange)]);
11743
- _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)]);
11744
11677
  fsm.start();
11745
11678
  return {
11746
11679
  inc,