@liveblocks/core 3.21.0-exp9 → 3.21.0-private2

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.21.0-exp9";
9
+ var PKG_VERSION = "3.21.0-private2";
10
10
  var PKG_FORMAT = "cjs";
11
11
 
12
12
  // src/dupe-detection.ts
@@ -1567,6 +1567,15 @@ function isUrl(string) {
1567
1567
  }
1568
1568
 
1569
1569
  // src/api-client.ts
1570
+ function commentsResourceForVisibility(visibility) {
1571
+ if (visibility === "private") {
1572
+ return "comments:private";
1573
+ }
1574
+ if (visibility === "public") {
1575
+ return "comments:public";
1576
+ }
1577
+ return "comments";
1578
+ }
1570
1579
  function createApiClient({
1571
1580
  baseUrl,
1572
1581
  authManager,
@@ -1618,7 +1627,7 @@ function createApiClient({
1618
1627
  url`/v2/c/rooms/${options.roomId}/threads`,
1619
1628
  await authManager.getAuthValue({
1620
1629
  roomId: options.roomId,
1621
- resource: "comments",
1630
+ resource: commentsResourceForVisibility(_optionalChain([options, 'access', _15 => _15.query, 'optionalAccess', _16 => _16.visibility])),
1622
1631
  access: "read"
1623
1632
  }),
1624
1633
  {
@@ -1676,7 +1685,7 @@ function createApiClient({
1676
1685
  hasMentions: options.query.hasMentions
1677
1686
  })
1678
1687
  },
1679
- { signal: _optionalChain([requestOptions, 'optionalAccess', _15 => _15.signal]) }
1688
+ { signal: _optionalChain([requestOptions, 'optionalAccess', _17 => _17.signal]) }
1680
1689
  );
1681
1690
  return result;
1682
1691
  }
@@ -1687,11 +1696,12 @@ function createApiClient({
1687
1696
  url`/v2/c/rooms/${options.roomId}/threads`,
1688
1697
  await authManager.getAuthValue({
1689
1698
  roomId: options.roomId,
1690
- resource: "comments",
1699
+ resource: commentsResourceForVisibility(_nullishCoalesce(options.visibility, () => ( "public"))),
1691
1700
  access: "write"
1692
1701
  }),
1693
1702
  {
1694
1703
  id: threadId,
1704
+ visibility: options.visibility,
1695
1705
  comment: {
1696
1706
  id: commentId,
1697
1707
  body: options.body,
@@ -1708,7 +1718,7 @@ function createApiClient({
1708
1718
  url`/v2/c/rooms/${options.roomId}/threads/${options.threadId}`,
1709
1719
  await authManager.getAuthValue({
1710
1720
  roomId: options.roomId,
1711
- resource: "comments",
1721
+ resource: commentsResourceForVisibility(options.visibility),
1712
1722
  access: "write"
1713
1723
  })
1714
1724
  );
@@ -1746,7 +1756,7 @@ function createApiClient({
1746
1756
  url`/v2/c/rooms/${options.roomId}/threads/${options.threadId}/metadata`,
1747
1757
  await authManager.getAuthValue({
1748
1758
  roomId: options.roomId,
1749
- resource: "comments",
1759
+ resource: commentsResourceForVisibility(options.visibility),
1750
1760
  access: "write"
1751
1761
  }),
1752
1762
  options.metadata
@@ -1757,7 +1767,7 @@ function createApiClient({
1757
1767
  url`/v2/c/rooms/${options.roomId}/threads/${options.threadId}/comments/${options.commentId}/metadata`,
1758
1768
  await authManager.getAuthValue({
1759
1769
  roomId: options.roomId,
1760
- resource: "comments",
1770
+ resource: commentsResourceForVisibility(options.visibility),
1761
1771
  access: "write"
1762
1772
  }),
1763
1773
  options.metadata
@@ -1769,7 +1779,7 @@ function createApiClient({
1769
1779
  url`/v2/c/rooms/${options.roomId}/threads/${options.threadId}/comments`,
1770
1780
  await authManager.getAuthValue({
1771
1781
  roomId: options.roomId,
1772
- resource: "comments",
1782
+ resource: commentsResourceForVisibility(options.visibility),
1773
1783
  access: "write"
1774
1784
  }),
1775
1785
  {
@@ -1786,7 +1796,7 @@ function createApiClient({
1786
1796
  url`/v2/c/rooms/${options.roomId}/threads/${options.threadId}/comments/${options.commentId}`,
1787
1797
  await authManager.getAuthValue({
1788
1798
  roomId: options.roomId,
1789
- resource: "comments",
1799
+ resource: commentsResourceForVisibility(options.visibility),
1790
1800
  access: "write"
1791
1801
  }),
1792
1802
  {
@@ -1802,7 +1812,7 @@ function createApiClient({
1802
1812
  url`/v2/c/rooms/${options.roomId}/threads/${options.threadId}/comments/${options.commentId}`,
1803
1813
  await authManager.getAuthValue({
1804
1814
  roomId: options.roomId,
1805
- resource: "comments",
1815
+ resource: commentsResourceForVisibility(options.visibility),
1806
1816
  access: "write"
1807
1817
  })
1808
1818
  );
@@ -1812,7 +1822,7 @@ function createApiClient({
1812
1822
  url`/v2/c/rooms/${options.roomId}/threads/${options.threadId}/comments/${options.commentId}/reactions`,
1813
1823
  await authManager.getAuthValue({
1814
1824
  roomId: options.roomId,
1815
- resource: "comments",
1825
+ resource: commentsResourceForVisibility(options.visibility),
1816
1826
  access: "write"
1817
1827
  }),
1818
1828
  { emoji: options.emoji }
@@ -1824,7 +1834,7 @@ function createApiClient({
1824
1834
  url`/v2/c/rooms/${options.roomId}/threads/${options.threadId}/comments/${options.commentId}/reactions/${options.emoji}`,
1825
1835
  await authManager.getAuthValue({
1826
1836
  roomId: options.roomId,
1827
- resource: "comments",
1837
+ resource: commentsResourceForVisibility(options.visibility),
1828
1838
  access: "write"
1829
1839
  })
1830
1840
  );
@@ -1834,7 +1844,7 @@ function createApiClient({
1834
1844
  url`/v2/c/rooms/${options.roomId}/threads/${options.threadId}/mark-as-resolved`,
1835
1845
  await authManager.getAuthValue({
1836
1846
  roomId: options.roomId,
1837
- resource: "comments",
1847
+ resource: commentsResourceForVisibility(options.visibility),
1838
1848
  access: "write"
1839
1849
  })
1840
1850
  );
@@ -1844,7 +1854,7 @@ function createApiClient({
1844
1854
  url`/v2/c/rooms/${options.roomId}/threads/${options.threadId}/mark-as-unresolved`,
1845
1855
  await authManager.getAuthValue({
1846
1856
  roomId: options.roomId,
1847
- resource: "comments",
1857
+ resource: commentsResourceForVisibility(options.visibility),
1848
1858
  access: "write"
1849
1859
  })
1850
1860
  );
@@ -1878,11 +1888,11 @@ function createApiClient({
1878
1888
  `Upload of attachment ${options.attachment.id} was aborted.`,
1879
1889
  "AbortError"
1880
1890
  ) : void 0;
1881
- if (_optionalChain([abortSignal, 'optionalAccess', _16 => _16.aborted])) {
1891
+ if (_optionalChain([abortSignal, 'optionalAccess', _18 => _18.aborted])) {
1882
1892
  throw abortError;
1883
1893
  }
1884
1894
  const handleRetryError = (err) => {
1885
- if (_optionalChain([abortSignal, 'optionalAccess', _17 => _17.aborted])) {
1895
+ if (_optionalChain([abortSignal, 'optionalAccess', _19 => _19.aborted])) {
1886
1896
  throw abortError;
1887
1897
  }
1888
1898
  if (err instanceof HttpError && err.status === 413) {
@@ -1956,7 +1966,7 @@ function createApiClient({
1956
1966
  try {
1957
1967
  uploadId = createMultiPartUpload.uploadId;
1958
1968
  const parts = splitFileIntoParts(attachment.file);
1959
- if (_optionalChain([abortSignal, 'optionalAccess', _18 => _18.aborted])) {
1969
+ if (_optionalChain([abortSignal, 'optionalAccess', _20 => _20.aborted])) {
1960
1970
  throw abortError;
1961
1971
  }
1962
1972
  const batches = chunk(parts, 5);
@@ -1984,7 +1994,7 @@ function createApiClient({
1984
1994
  }
1985
1995
  uploadedParts.push(...await Promise.all(uploadedPartsPromises));
1986
1996
  }
1987
- if (_optionalChain([abortSignal, 'optionalAccess', _19 => _19.aborted])) {
1997
+ if (_optionalChain([abortSignal, 'optionalAccess', _21 => _21.aborted])) {
1988
1998
  throw abortError;
1989
1999
  }
1990
2000
  const sortedUploadedParts = uploadedParts.sort(
@@ -2001,7 +2011,7 @@ function createApiClient({
2001
2011
  { signal: abortSignal }
2002
2012
  );
2003
2013
  } catch (error3) {
2004
- if (uploadId && _optionalChain([error3, 'optionalAccess', _20 => _20.name]) && (error3.name === "AbortError" || error3.name === "TimeoutError")) {
2014
+ if (uploadId && _optionalChain([error3, 'optionalAccess', _22 => _22.name]) && (error3.name === "AbortError" || error3.name === "TimeoutError")) {
2005
2015
  try {
2006
2016
  await httpClient.rawDelete(
2007
2017
  url`/v2/c/rooms/${roomId}/attachments/${attachment.id}/multipart/${uploadId}`,
@@ -2234,14 +2244,14 @@ function createApiClient({
2234
2244
  async function getInboxNotifications(options) {
2235
2245
  const PAGE_SIZE = 50;
2236
2246
  let query;
2237
- if (_optionalChain([options, 'optionalAccess', _21 => _21.query])) {
2247
+ if (_optionalChain([options, 'optionalAccess', _23 => _23.query])) {
2238
2248
  query = objectToQuery(options.query);
2239
2249
  }
2240
2250
  const json = await httpClient.get(
2241
2251
  url`/v2/c/inbox-notifications`,
2242
2252
  await authManager.getAuthValue({ resource: "personal", access: "write" }),
2243
2253
  {
2244
- cursor: _optionalChain([options, 'optionalAccess', _22 => _22.cursor]),
2254
+ cursor: _optionalChain([options, 'optionalAccess', _24 => _24.cursor]),
2245
2255
  limit: PAGE_SIZE,
2246
2256
  query
2247
2257
  }
@@ -2260,7 +2270,7 @@ function createApiClient({
2260
2270
  }
2261
2271
  async function getInboxNotificationsSince(options) {
2262
2272
  let query;
2263
- if (_optionalChain([options, 'optionalAccess', _23 => _23.query])) {
2273
+ if (_optionalChain([options, 'optionalAccess', _25 => _25.query])) {
2264
2274
  query = objectToQuery(options.query);
2265
2275
  }
2266
2276
  const json = await httpClient.get(
@@ -2289,14 +2299,14 @@ function createApiClient({
2289
2299
  }
2290
2300
  async function getUnreadInboxNotificationsCount(options) {
2291
2301
  let query;
2292
- if (_optionalChain([options, 'optionalAccess', _24 => _24.query])) {
2302
+ if (_optionalChain([options, 'optionalAccess', _26 => _26.query])) {
2293
2303
  query = objectToQuery(options.query);
2294
2304
  }
2295
2305
  const { count } = await httpClient.get(
2296
2306
  url`/v2/c/inbox-notifications/count`,
2297
2307
  await authManager.getAuthValue({ resource: "personal", access: "write" }),
2298
2308
  { query },
2299
- { signal: _optionalChain([options, 'optionalAccess', _25 => _25.signal]) }
2309
+ { signal: _optionalChain([options, 'optionalAccess', _27 => _27.signal]) }
2300
2310
  );
2301
2311
  return count;
2302
2312
  }
@@ -2346,7 +2356,7 @@ function createApiClient({
2346
2356
  url`/v2/c/notification-settings`,
2347
2357
  await authManager.getAuthValue({ resource: "personal", access: "write" }),
2348
2358
  void 0,
2349
- { signal: _optionalChain([options, 'optionalAccess', _26 => _26.signal]) }
2359
+ { signal: _optionalChain([options, 'optionalAccess', _28 => _28.signal]) }
2350
2360
  );
2351
2361
  }
2352
2362
  async function updateNotificationSettings(settings) {
@@ -2358,7 +2368,7 @@ function createApiClient({
2358
2368
  }
2359
2369
  async function getUserThreads_experimental(options) {
2360
2370
  let query;
2361
- if (_optionalChain([options, 'optionalAccess', _27 => _27.query])) {
2371
+ if (_optionalChain([options, 'optionalAccess', _29 => _29.query])) {
2362
2372
  query = objectToQuery(options.query);
2363
2373
  }
2364
2374
  const PAGE_SIZE = 50;
@@ -2366,7 +2376,7 @@ function createApiClient({
2366
2376
  url`/v2/c/threads`,
2367
2377
  await authManager.getAuthValue({ resource: "personal", access: "write" }),
2368
2378
  {
2369
- cursor: _optionalChain([options, 'optionalAccess', _28 => _28.cursor]),
2379
+ cursor: _optionalChain([options, 'optionalAccess', _30 => _30.cursor]),
2370
2380
  query,
2371
2381
  limit: PAGE_SIZE
2372
2382
  }
@@ -2539,7 +2549,7 @@ var HttpClient = class {
2539
2549
  // These headers are default, but can be overriden by custom headers
2540
2550
  "Content-Type": "application/json; charset=utf-8",
2541
2551
  // Possible header overrides
2542
- ..._optionalChain([options, 'optionalAccess', _29 => _29.headers]),
2552
+ ..._optionalChain([options, 'optionalAccess', _31 => _31.headers]),
2543
2553
  // Cannot be overriden by custom headers
2544
2554
  Authorization: `Bearer ${getBearerTokenFromAuthValue(authValue)}`,
2545
2555
  "X-LB-Client": PKG_VERSION || "dev"
@@ -2547,7 +2557,7 @@ var HttpClient = class {
2547
2557
  });
2548
2558
  const xwarn = response.headers.get("X-LB-Warn");
2549
2559
  if (xwarn) {
2550
- const method = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _30 => _30.method, 'optionalAccess', _31 => _31.toUpperCase, 'call', _32 => _32()]), () => ( "GET"));
2560
+ const method = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _32 => _32.method, 'optionalAccess', _33 => _33.toUpperCase, 'call', _34 => _34()]), () => ( "GET"));
2551
2561
  const msg = `${xwarn} (${method} ${endpoint})`;
2552
2562
  if (response.ok) {
2553
2563
  warn(msg);
@@ -3029,7 +3039,7 @@ var FSM = class {
3029
3039
  });
3030
3040
  }
3031
3041
  #getTargetFn(eventName) {
3032
- return _optionalChain([this, 'access', _33 => _33.#allowedTransitions, 'access', _34 => _34.get, 'call', _35 => _35(this.currentState), 'optionalAccess', _36 => _36.get, 'call', _37 => _37(eventName)]);
3042
+ return _optionalChain([this, 'access', _35 => _35.#allowedTransitions, 'access', _36 => _36.get, 'call', _37 => _37(this.currentState), 'optionalAccess', _38 => _38.get, 'call', _39 => _39(eventName)]);
3033
3043
  }
3034
3044
  /**
3035
3045
  * Exits the current state, and executes any necessary cleanup functions.
@@ -3048,7 +3058,7 @@ var FSM = class {
3048
3058
  this.#currentContext.allowPatching((patchableContext) => {
3049
3059
  levels = _nullishCoalesce(levels, () => ( this.#cleanupStack.length));
3050
3060
  for (let i = 0; i < levels; i++) {
3051
- _optionalChain([this, 'access', _38 => _38.#cleanupStack, 'access', _39 => _39.pop, 'call', _40 => _40(), 'optionalCall', _41 => _41(patchableContext)]);
3061
+ _optionalChain([this, 'access', _40 => _40.#cleanupStack, 'access', _41 => _41.pop, 'call', _42 => _42(), 'optionalCall', _43 => _43(patchableContext)]);
3052
3062
  const entryTime = this.#entryTimesStack.pop();
3053
3063
  if (entryTime !== void 0 && // ...but avoid computing state names if nobody is listening
3054
3064
  this.#eventHub.didExitState.count() > 0) {
@@ -3076,7 +3086,7 @@ var FSM = class {
3076
3086
  this.#currentContext.allowPatching((patchableContext) => {
3077
3087
  for (const pattern of enterPatterns) {
3078
3088
  const enterFn = this.#enterFns.get(pattern);
3079
- const cleanupFn = _optionalChain([enterFn, 'optionalCall', _42 => _42(patchableContext)]);
3089
+ const cleanupFn = _optionalChain([enterFn, 'optionalCall', _44 => _44(patchableContext)]);
3080
3090
  if (typeof cleanupFn === "function") {
3081
3091
  this.#cleanupStack.push(cleanupFn);
3082
3092
  } else {
@@ -3503,7 +3513,7 @@ function createConnectionStateMachine(delegates, options) {
3503
3513
  }
3504
3514
  function waitForActorId(event) {
3505
3515
  const serverMsg = tryParseJson(event.data);
3506
- if (_optionalChain([serverMsg, 'optionalAccess', _43 => _43.type]) === ServerMsgCode.ROOM_STATE) {
3516
+ if (_optionalChain([serverMsg, 'optionalAccess', _45 => _45.type]) === ServerMsgCode.ROOM_STATE) {
3507
3517
  if (options.enableDebugLogging && socketOpenAt !== null) {
3508
3518
  const elapsed = performance.now() - socketOpenAt;
3509
3519
  warn(
@@ -3631,12 +3641,12 @@ function createConnectionStateMachine(delegates, options) {
3631
3641
  const sendHeartbeat = {
3632
3642
  target: "@ok.awaiting-pong",
3633
3643
  effect: (ctx) => {
3634
- _optionalChain([ctx, 'access', _44 => _44.socket, 'optionalAccess', _45 => _45.send, 'call', _46 => _46("ping")]);
3644
+ _optionalChain([ctx, 'access', _46 => _46.socket, 'optionalAccess', _47 => _47.send, 'call', _48 => _48("ping")]);
3635
3645
  }
3636
3646
  };
3637
3647
  const maybeHeartbeat = () => {
3638
3648
  const doc = typeof document !== "undefined" ? document : void 0;
3639
- const canZombie = _optionalChain([doc, 'optionalAccess', _47 => _47.visibilityState]) === "hidden" && delegates.canZombie();
3649
+ const canZombie = _optionalChain([doc, 'optionalAccess', _49 => _49.visibilityState]) === "hidden" && delegates.canZombie();
3640
3650
  return canZombie ? "@idle.zombie" : sendHeartbeat;
3641
3651
  };
3642
3652
  machine.addTimedTransition("@ok.connected", HEARTBEAT_INTERVAL, maybeHeartbeat).addTransitions("@ok.connected", {
@@ -3676,7 +3686,7 @@ function createConnectionStateMachine(delegates, options) {
3676
3686
  // socket, or not. So always check to see if the socket is still OPEN or
3677
3687
  // not. When still OPEN, don't transition.
3678
3688
  EXPLICIT_SOCKET_ERROR: (_, context) => {
3679
- if (_optionalChain([context, 'access', _48 => _48.socket, 'optionalAccess', _49 => _49.readyState]) === 1) {
3689
+ if (_optionalChain([context, 'access', _50 => _50.socket, 'optionalAccess', _51 => _51.readyState]) === 1) {
3680
3690
  return IGNORE;
3681
3691
  }
3682
3692
  return {
@@ -3728,17 +3738,17 @@ function createConnectionStateMachine(delegates, options) {
3728
3738
  machine.send({ type: "NAVIGATOR_ONLINE" });
3729
3739
  }
3730
3740
  function onVisibilityChange() {
3731
- if (_optionalChain([doc, 'optionalAccess', _50 => _50.visibilityState]) === "visible") {
3741
+ if (_optionalChain([doc, 'optionalAccess', _52 => _52.visibilityState]) === "visible") {
3732
3742
  machine.send({ type: "WINDOW_GOT_FOCUS" });
3733
3743
  }
3734
3744
  }
3735
- _optionalChain([win, 'optionalAccess', _51 => _51.addEventListener, 'call', _52 => _52("online", onNetworkBackOnline)]);
3736
- _optionalChain([win, 'optionalAccess', _53 => _53.addEventListener, 'call', _54 => _54("offline", onNetworkOffline)]);
3737
- _optionalChain([root, 'optionalAccess', _55 => _55.addEventListener, 'call', _56 => _56("visibilitychange", onVisibilityChange)]);
3745
+ _optionalChain([win, 'optionalAccess', _53 => _53.addEventListener, 'call', _54 => _54("online", onNetworkBackOnline)]);
3746
+ _optionalChain([win, 'optionalAccess', _55 => _55.addEventListener, 'call', _56 => _56("offline", onNetworkOffline)]);
3747
+ _optionalChain([root, 'optionalAccess', _57 => _57.addEventListener, 'call', _58 => _58("visibilitychange", onVisibilityChange)]);
3738
3748
  return () => {
3739
- _optionalChain([root, 'optionalAccess', _57 => _57.removeEventListener, 'call', _58 => _58("visibilitychange", onVisibilityChange)]);
3740
- _optionalChain([win, 'optionalAccess', _59 => _59.removeEventListener, 'call', _60 => _60("online", onNetworkBackOnline)]);
3741
- _optionalChain([win, 'optionalAccess', _61 => _61.removeEventListener, 'call', _62 => _62("offline", onNetworkOffline)]);
3749
+ _optionalChain([root, 'optionalAccess', _59 => _59.removeEventListener, 'call', _60 => _60("visibilitychange", onVisibilityChange)]);
3750
+ _optionalChain([win, 'optionalAccess', _61 => _61.removeEventListener, 'call', _62 => _62("online", onNetworkBackOnline)]);
3751
+ _optionalChain([win, 'optionalAccess', _63 => _63.removeEventListener, 'call', _64 => _64("offline", onNetworkOffline)]);
3742
3752
  teardownSocket(ctx.socket);
3743
3753
  };
3744
3754
  });
@@ -3827,7 +3837,7 @@ var ManagedSocket = class {
3827
3837
  * message if this is somehow impossible.
3828
3838
  */
3829
3839
  send(data) {
3830
- const socket = _optionalChain([this, 'access', _63 => _63.#machine, 'access', _64 => _64.context, 'optionalAccess', _65 => _65.socket]);
3840
+ const socket = _optionalChain([this, 'access', _65 => _65.#machine, 'access', _66 => _66.context, 'optionalAccess', _67 => _67.socket]);
3831
3841
  if (socket === null) {
3832
3842
  warn("Cannot send: not connected yet", data);
3833
3843
  } else if (socket.readyState !== 1) {
@@ -3847,7 +3857,6 @@ var ManagedSocket = class {
3847
3857
 
3848
3858
  // src/internal.ts
3849
3859
  var kInternal = /* @__PURE__ */ Symbol();
3850
- var kStorageUpdateSource = /* @__PURE__ */ Symbol();
3851
3860
 
3852
3861
  // src/lib/IncrementalJsonParser.ts
3853
3862
  var EMPTY_OBJECT = Object.freeze({});
@@ -4290,7 +4299,7 @@ function createStore_forKnowledge() {
4290
4299
  }
4291
4300
  function getKnowledgeForChat(chatId) {
4292
4301
  const globalKnowledge = knowledgeByChatId.getOrCreate(kWILDCARD).get();
4293
- const scopedKnowledge = _nullishCoalesce(_optionalChain([knowledgeByChatId, 'access', _66 => _66.get, 'call', _67 => _67(chatId), 'optionalAccess', _68 => _68.get, 'call', _69 => _69()]), () => ( []));
4302
+ const scopedKnowledge = _nullishCoalesce(_optionalChain([knowledgeByChatId, 'access', _68 => _68.get, 'call', _69 => _69(chatId), 'optionalAccess', _70 => _70.get, 'call', _71 => _71()]), () => ( []));
4294
4303
  return [...globalKnowledge, ...scopedKnowledge];
4295
4304
  }
4296
4305
  return {
@@ -4315,7 +4324,7 @@ function createStore_forTools() {
4315
4324
  return DerivedSignal.from(() => {
4316
4325
  return (
4317
4326
  // A tool that's registered and scoped to a specific chat ID...
4318
- _nullishCoalesce(_optionalChain([(chatId !== void 0 ? toolsByChatId\u03A3.getOrCreate(chatId).getOrCreate(name) : void 0), 'optionalAccess', _70 => _70.get, 'call', _71 => _71()]), () => ( // ...or a globally registered tool
4327
+ _nullishCoalesce(_optionalChain([(chatId !== void 0 ? toolsByChatId\u03A3.getOrCreate(chatId).getOrCreate(name) : void 0), 'optionalAccess', _72 => _72.get, 'call', _73 => _73()]), () => ( // ...or a globally registered tool
4319
4328
  toolsByChatId\u03A3.getOrCreate(kWILDCARD).getOrCreate(name).get()))
4320
4329
  );
4321
4330
  });
@@ -4345,8 +4354,8 @@ function createStore_forTools() {
4345
4354
  const globalTools\u03A3 = toolsByChatId\u03A3.get(kWILDCARD);
4346
4355
  const scopedTools\u03A3 = toolsByChatId\u03A3.get(chatId);
4347
4356
  return Array.from([
4348
- ..._nullishCoalesce(_optionalChain([globalTools\u03A3, 'optionalAccess', _72 => _72.entries, 'call', _73 => _73()]), () => ( [])),
4349
- ..._nullishCoalesce(_optionalChain([scopedTools\u03A3, 'optionalAccess', _74 => _74.entries, 'call', _75 => _75()]), () => ( []))
4357
+ ..._nullishCoalesce(_optionalChain([globalTools\u03A3, 'optionalAccess', _74 => _74.entries, 'call', _75 => _75()]), () => ( [])),
4358
+ ..._nullishCoalesce(_optionalChain([scopedTools\u03A3, 'optionalAccess', _76 => _76.entries, 'call', _77 => _77()]), () => ( []))
4350
4359
  ]).flatMap(([name, tool\u03A3]) => {
4351
4360
  const tool = tool\u03A3.get();
4352
4361
  return tool && (_nullishCoalesce(tool.enabled, () => ( true))) ? [{ name, description: tool.description, parameters: tool.parameters }] : [];
@@ -4449,7 +4458,7 @@ function createStore_forChatMessages(toolsStore, setToolResultFn) {
4449
4458
  } else {
4450
4459
  continue;
4451
4460
  }
4452
- const executeFn = _optionalChain([toolsStore, 'access', _76 => _76.getTool\u03A3, 'call', _77 => _77(toolInvocation.name, message.chatId), 'access', _78 => _78.get, 'call', _79 => _79(), 'optionalAccess', _80 => _80.execute]);
4461
+ const executeFn = _optionalChain([toolsStore, 'access', _78 => _78.getTool\u03A3, 'call', _79 => _79(toolInvocation.name, message.chatId), 'access', _80 => _80.get, 'call', _81 => _81(), 'optionalAccess', _82 => _82.execute]);
4453
4462
  if (executeFn) {
4454
4463
  (async () => {
4455
4464
  const result = await executeFn(toolInvocation.args, {
@@ -4548,8 +4557,8 @@ function createStore_forChatMessages(toolsStore, setToolResultFn) {
4548
4557
  const spine = [];
4549
4558
  let lastVisitedMessage = null;
4550
4559
  for (const message2 of pool.walkUp(leaf.id)) {
4551
- const prev = _nullishCoalesce(_optionalChain([first, 'call', _81 => _81(pool.walkLeft(message2.id, isAlive)), 'optionalAccess', _82 => _82.id]), () => ( null));
4552
- const next = _nullishCoalesce(_optionalChain([first, 'call', _83 => _83(pool.walkRight(message2.id, isAlive)), 'optionalAccess', _84 => _84.id]), () => ( null));
4560
+ const prev = _nullishCoalesce(_optionalChain([first, 'call', _83 => _83(pool.walkLeft(message2.id, isAlive)), 'optionalAccess', _84 => _84.id]), () => ( null));
4561
+ const next = _nullishCoalesce(_optionalChain([first, 'call', _85 => _85(pool.walkRight(message2.id, isAlive)), 'optionalAccess', _86 => _86.id]), () => ( null));
4553
4562
  if (!message2.deletedAt || prev || next) {
4554
4563
  const node = {
4555
4564
  ...message2,
@@ -4615,7 +4624,7 @@ function createStore_forChatMessages(toolsStore, setToolResultFn) {
4615
4624
  const latest = pool.sorted.findRight(
4616
4625
  (m) => m.role === "assistant" && !m.deletedAt
4617
4626
  );
4618
- return _optionalChain([latest, 'optionalAccess', _85 => _85.copilotId]);
4627
+ return _optionalChain([latest, 'optionalAccess', _87 => _87.copilotId]);
4619
4628
  }
4620
4629
  return {
4621
4630
  // Readers
@@ -4646,11 +4655,11 @@ function createStore_forChatMessages(toolsStore, setToolResultFn) {
4646
4655
  *getAutoExecutingMessageIds() {
4647
4656
  for (const messageId of myMessages) {
4648
4657
  const message = getMessageById(messageId);
4649
- if (_optionalChain([message, 'optionalAccess', _86 => _86.role]) === "assistant" && message.status === "awaiting-tool") {
4658
+ if (_optionalChain([message, 'optionalAccess', _88 => _88.role]) === "assistant" && message.status === "awaiting-tool") {
4650
4659
  const isAutoExecuting = message.contentSoFar.some((part) => {
4651
4660
  if (part.type === "tool-invocation" && part.stage === "executing") {
4652
4661
  const tool = toolsStore.getTool\u03A3(part.name, message.chatId).get();
4653
- return typeof _optionalChain([tool, 'optionalAccess', _87 => _87.execute]) === "function";
4662
+ return typeof _optionalChain([tool, 'optionalAccess', _89 => _89.execute]) === "function";
4654
4663
  }
4655
4664
  return false;
4656
4665
  });
@@ -4798,7 +4807,7 @@ function createAi(config) {
4798
4807
  flushPendingDeltas();
4799
4808
  switch (msg.event) {
4800
4809
  case "cmd-failed":
4801
- _optionalChain([pendingCmd, 'optionalAccess', _88 => _88.reject, 'call', _89 => _89(new Error(msg.error))]);
4810
+ _optionalChain([pendingCmd, 'optionalAccess', _90 => _90.reject, 'call', _91 => _91(new Error(msg.error))]);
4802
4811
  break;
4803
4812
  case "settle": {
4804
4813
  context.messagesStore.upsert(msg.message);
@@ -4875,7 +4884,7 @@ function createAi(config) {
4875
4884
  return assertNever(msg, "Unhandled case");
4876
4885
  }
4877
4886
  }
4878
- _optionalChain([pendingCmd, 'optionalAccess', _90 => _90.resolve, 'call', _91 => _91(msg)]);
4887
+ _optionalChain([pendingCmd, 'optionalAccess', _92 => _92.resolve, 'call', _93 => _93(msg)]);
4879
4888
  }
4880
4889
  managedSocket.events.onMessage.subscribe(handleServerMessage);
4881
4890
  managedSocket.events.statusDidChange.subscribe(onStatusDidChange);
@@ -4951,9 +4960,9 @@ function createAi(config) {
4951
4960
  invocationId,
4952
4961
  result,
4953
4962
  generationOptions: {
4954
- copilotId: _optionalChain([options, 'optionalAccess', _92 => _92.copilotId]),
4955
- stream: _optionalChain([options, 'optionalAccess', _93 => _93.stream]),
4956
- timeout: _optionalChain([options, 'optionalAccess', _94 => _94.timeout]),
4963
+ copilotId: _optionalChain([options, 'optionalAccess', _94 => _94.copilotId]),
4964
+ stream: _optionalChain([options, 'optionalAccess', _95 => _95.stream]),
4965
+ timeout: _optionalChain([options, 'optionalAccess', _96 => _96.timeout]),
4957
4966
  // Knowledge and tools aren't coming from the options, but retrieved
4958
4967
  // from the global context
4959
4968
  knowledge: knowledge.length > 0 ? knowledge : void 0,
@@ -4971,7 +4980,7 @@ function createAi(config) {
4971
4980
  }
4972
4981
  }
4973
4982
  const win = typeof window !== "undefined" ? window : void 0;
4974
- _optionalChain([win, 'optionalAccess', _95 => _95.addEventListener, 'call', _96 => _96("beforeunload", handleBeforeUnload, { once: true })]);
4983
+ _optionalChain([win, 'optionalAccess', _97 => _97.addEventListener, 'call', _98 => _98("beforeunload", handleBeforeUnload, { once: true })]);
4975
4984
  return Object.defineProperty(
4976
4985
  {
4977
4986
  [kInternal]: {
@@ -4990,7 +4999,7 @@ function createAi(config) {
4990
4999
  clearChat: (chatId) => sendClientMsgWithResponse({ cmd: "clear-chat", chatId }),
4991
5000
  askUserMessageInChat: async (chatId, userMessage, targetMessageId, options) => {
4992
5001
  const knowledge = context.knowledgeStore.getKnowledgeForChat(chatId);
4993
- const requestKnowledge = _optionalChain([options, 'optionalAccess', _97 => _97.knowledge]) || [];
5002
+ const requestKnowledge = _optionalChain([options, 'optionalAccess', _99 => _99.knowledge]) || [];
4994
5003
  const combinedKnowledge = [...knowledge, ...requestKnowledge];
4995
5004
  const tools = context.toolsStore.getToolDescriptions(chatId);
4996
5005
  messagesStore.markMine(targetMessageId);
@@ -5000,9 +5009,9 @@ function createAi(config) {
5000
5009
  sourceMessage: userMessage,
5001
5010
  targetMessageId,
5002
5011
  generationOptions: {
5003
- copilotId: _optionalChain([options, 'optionalAccess', _98 => _98.copilotId]),
5004
- stream: _optionalChain([options, 'optionalAccess', _99 => _99.stream]),
5005
- timeout: _optionalChain([options, 'optionalAccess', _100 => _100.timeout]),
5012
+ copilotId: _optionalChain([options, 'optionalAccess', _100 => _100.copilotId]),
5013
+ stream: _optionalChain([options, 'optionalAccess', _101 => _101.stream]),
5014
+ timeout: _optionalChain([options, 'optionalAccess', _102 => _102.timeout]),
5006
5015
  // Combine global knowledge with request-specific knowledge
5007
5016
  knowledge: combinedKnowledge.length > 0 ? combinedKnowledge : void 0,
5008
5017
  tools: tools.length > 0 ? tools : void 0
@@ -5074,7 +5083,7 @@ function replaceOrAppend(content, newItem, keyFn, now2) {
5074
5083
  }
5075
5084
  }
5076
5085
  function closePart(prevPart, endedAt) {
5077
- if (_optionalChain([prevPart, 'optionalAccess', _101 => _101.type]) === "reasoning") {
5086
+ if (_optionalChain([prevPart, 'optionalAccess', _103 => _103.type]) === "reasoning") {
5078
5087
  prevPart.endedAt ??= endedAt;
5079
5088
  }
5080
5089
  }
@@ -5089,7 +5098,7 @@ function patchContentWithDelta(content, delta) {
5089
5098
  const lastPart = parts[parts.length - 1];
5090
5099
  switch (delta.type) {
5091
5100
  case "text-delta":
5092
- if (_optionalChain([lastPart, 'optionalAccess', _102 => _102.type]) === "text") {
5101
+ if (_optionalChain([lastPart, 'optionalAccess', _104 => _104.type]) === "text") {
5093
5102
  lastPart.text += delta.textDelta;
5094
5103
  } else {
5095
5104
  closePart(lastPart, now2);
@@ -5097,7 +5106,7 @@ function patchContentWithDelta(content, delta) {
5097
5106
  }
5098
5107
  break;
5099
5108
  case "reasoning-delta":
5100
- if (_optionalChain([lastPart, 'optionalAccess', _103 => _103.type]) === "reasoning") {
5109
+ if (_optionalChain([lastPart, 'optionalAccess', _105 => _105.type]) === "reasoning") {
5101
5110
  lastPart.text += delta.textDelta;
5102
5111
  } else {
5103
5112
  closePart(lastPart, now2);
@@ -5117,8 +5126,8 @@ function patchContentWithDelta(content, delta) {
5117
5126
  break;
5118
5127
  }
5119
5128
  case "tool-delta": {
5120
- if (_optionalChain([lastPart, 'optionalAccess', _104 => _104.type]) === "tool-invocation" && lastPart.stage === "receiving") {
5121
- _optionalChain([lastPart, 'access', _105 => _105.__appendDelta, 'optionalCall', _106 => _106(delta.delta)]);
5129
+ if (_optionalChain([lastPart, 'optionalAccess', _106 => _106.type]) === "tool-invocation" && lastPart.stage === "receiving") {
5130
+ _optionalChain([lastPart, 'access', _107 => _107.__appendDelta, 'optionalCall', _108 => _108(delta.delta)]);
5122
5131
  }
5123
5132
  break;
5124
5133
  }
@@ -5192,6 +5201,12 @@ var Permission = {
5192
5201
  CommentsWrite: "comments:write",
5193
5202
  CommentsRead: "comments:read",
5194
5203
  CommentsNone: "comments:none",
5204
+ CommentsPublicWrite: "comments:public:write",
5205
+ CommentsPublicRead: "comments:public:read",
5206
+ CommentsPublicNone: "comments:public:none",
5207
+ CommentsPrivateWrite: "comments:private:write",
5208
+ CommentsPrivateRead: "comments:private:read",
5209
+ CommentsPrivateNone: "comments:private:none",
5195
5210
  /**
5196
5211
  * Feeds
5197
5212
  */
@@ -5204,12 +5219,6 @@ var Permission = {
5204
5219
  LegacyRoomPresenceWrite: "room:presence:write"
5205
5220
  };
5206
5221
  var ACCESS_LEVELS = ["none", "read", "write"];
5207
- var basePermissionScopes = /* @__PURE__ */ new Set([
5208
- Permission.Read,
5209
- Permission.Write,
5210
- Permission.RoomRead,
5211
- Permission.RoomWrite
5212
- ]);
5213
5222
  var ACCESS_LEVEL_RANKS = {
5214
5223
  none: 0,
5215
5224
  read: 1,
@@ -5220,9 +5229,6 @@ var PERMISSIONS_BY_RESOURCE = {
5220
5229
  read: [Permission.Read, Permission.RoomRead],
5221
5230
  write: [Permission.Write, Permission.RoomWrite]
5222
5231
  },
5223
- personal: {
5224
- write: []
5225
- },
5226
5232
  storage: {
5227
5233
  write: [Permission.StorageWrite],
5228
5234
  read: [Permission.StorageRead],
@@ -5233,6 +5239,16 @@ var PERMISSIONS_BY_RESOURCE = {
5233
5239
  read: [Permission.CommentsRead],
5234
5240
  none: [Permission.CommentsNone]
5235
5241
  },
5242
+ "comments:public": {
5243
+ write: [Permission.CommentsPublicWrite],
5244
+ read: [Permission.CommentsPublicRead],
5245
+ none: [Permission.CommentsPublicNone]
5246
+ },
5247
+ "comments:private": {
5248
+ write: [Permission.CommentsPrivateWrite],
5249
+ read: [Permission.CommentsPrivateRead],
5250
+ none: [Permission.CommentsPrivateNone]
5251
+ },
5236
5252
  feeds: {
5237
5253
  write: [Permission.FeedsWrite],
5238
5254
  read: [Permission.FeedsRead],
@@ -5243,6 +5259,8 @@ var NO_PERMISSION_MATRIX = {
5243
5259
  room: "none",
5244
5260
  storage: "none",
5245
5261
  comments: "none",
5262
+ "comments:public": "none",
5263
+ "comments:private": "none",
5246
5264
  feeds: "none",
5247
5265
  personal: "none"
5248
5266
  };
@@ -5250,8 +5268,20 @@ var BASE_PERMISSION_RESOURCE = "room";
5250
5268
  var ROOM_PERMISSION_RESOURCES = [
5251
5269
  "storage",
5252
5270
  "comments",
5271
+ "comments:public",
5272
+ "comments:private",
5253
5273
  "feeds"
5254
5274
  ];
5275
+ var COMMENT_VISIBILITY_RESOURCES = [
5276
+ "comments:public",
5277
+ "comments:private"
5278
+ ];
5279
+ var basePermissionScopes = /* @__PURE__ */ new Set([
5280
+ Permission.Read,
5281
+ Permission.Write,
5282
+ Permission.RoomRead,
5283
+ Permission.RoomWrite
5284
+ ]);
5255
5285
  var VALID_PERMISSIONS = new Set(Object.values(Permission));
5256
5286
  function isPermission(permission) {
5257
5287
  return VALID_PERMISSIONS.has(permission);
@@ -5267,34 +5297,40 @@ function resolveResourceAccess(scopes, resource) {
5267
5297
  }
5268
5298
  return resourceAccess;
5269
5299
  }
5270
- function permissionMatrixFromResolvedScopes(resolved) {
5271
- if (!resolved.hasDefaultPermission) {
5272
- return { ...NO_PERMISSION_MATRIX };
5273
- }
5274
- const matrix = {
5275
- ...NO_PERMISSION_MATRIX,
5276
- [BASE_PERMISSION_RESOURCE]: resolved.baseAccess,
5277
- personal: "write"
5278
- };
5279
- for (const resource of ROOM_PERMISSION_RESOURCES) {
5280
- matrix[resource] = _nullishCoalesce(resolved.matrix[resource], () => ( resolved.baseAccess));
5281
- }
5282
- return matrix;
5283
- }
5284
- function permissionMatrixFromScopes(scopes) {
5285
- return permissionMatrixFromResolvedScopes(resolvePermissionScopes(scopes));
5286
- }
5287
- function resolvePermissionScopes(scopes) {
5288
- const hasDefaultPermission = scopes.includes(Permission.Write) || scopes.includes(Permission.Read) || scopes.includes(Permission.RoomWrite) || scopes.includes(Permission.RoomRead);
5289
- const baseAccess = scopes.includes(Permission.Write) || scopes.includes(Permission.RoomWrite) ? "write" : scopes.includes(Permission.Read) || scopes.includes(Permission.RoomRead) ? "read" : "none";
5300
+ function explicitPermissionMatrixFromScopes(scopes) {
5290
5301
  const matrix = {};
5302
+ const baseAccess = resolveResourceAccess(scopes, BASE_PERMISSION_RESOURCE);
5303
+ if (baseAccess !== void 0) {
5304
+ matrix.room = baseAccess;
5305
+ }
5291
5306
  for (const resource of ROOM_PERMISSION_RESOURCES) {
5292
5307
  const access = resolveResourceAccess(scopes, resource);
5293
5308
  if (access !== void 0) {
5294
5309
  matrix[resource] = access;
5295
5310
  }
5296
5311
  }
5297
- return { hasDefaultPermission, baseAccess, matrix };
5312
+ return matrix;
5313
+ }
5314
+ function permissionMatrixFromExplicitPermissions(explicitMatrix) {
5315
+ const baseAccess = explicitMatrix.room;
5316
+ if (baseAccess === void 0) {
5317
+ return { ...NO_PERMISSION_MATRIX };
5318
+ }
5319
+ const commentsAccess = _nullishCoalesce(explicitMatrix.comments, () => ( baseAccess));
5320
+ return {
5321
+ room: baseAccess,
5322
+ storage: _nullishCoalesce(explicitMatrix.storage, () => ( baseAccess)),
5323
+ comments: commentsAccess,
5324
+ "comments:public": _nullishCoalesce(explicitMatrix["comments:public"], () => ( commentsAccess)),
5325
+ "comments:private": _nullishCoalesce(explicitMatrix["comments:private"], () => ( commentsAccess)),
5326
+ feeds: _nullishCoalesce(explicitMatrix.feeds, () => ( baseAccess)),
5327
+ personal: "write"
5328
+ };
5329
+ }
5330
+ function permissionMatrixFromScopes(scopes) {
5331
+ return permissionMatrixFromExplicitPermissions(
5332
+ explicitPermissionMatrixFromScopes(scopes)
5333
+ );
5298
5334
  }
5299
5335
  function hasPermissionAccess(matrix, resource, requiredAccess) {
5300
5336
  const access = _nullishCoalesce(matrix[resource], () => ( "none"));
@@ -5307,38 +5343,29 @@ function resolveRoomPermissionMatrix(permissions, roomId) {
5307
5343
  if (matchedPermissions.length === 0) {
5308
5344
  return void 0;
5309
5345
  }
5310
- let hasDefaultPermission = false;
5311
- let baseAccess = "none";
5312
- const explicitMatrix = {};
5313
- const explicitSpecificity = {};
5346
+ const matrix = {};
5347
+ const specificityByResource = {};
5314
5348
  for (const entry of matchedPermissions) {
5315
- const resolved = resolvePermissionScopes(entry.scopes);
5349
+ const explicitMatrix = explicitPermissionMatrixFromScopes(entry.scopes);
5316
5350
  const specificity = roomPatternSpecificity(entry.pattern);
5317
- if (resolved.hasDefaultPermission) {
5318
- hasDefaultPermission = true;
5319
- baseAccess = strongestAccess(baseAccess, resolved.baseAccess);
5351
+ if (explicitMatrix.room !== void 0) {
5352
+ matrix.room = strongestAccess(_nullishCoalesce(matrix.room, () => ( "none")), explicitMatrix.room);
5320
5353
  }
5321
5354
  for (const resource of ROOM_PERMISSION_RESOURCES) {
5322
- const access = resolved.matrix[resource];
5323
- if (access !== void 0) {
5324
- const currentSpecificity = _nullishCoalesce(explicitSpecificity[resource], () => ( -1));
5325
- if (specificity > currentSpecificity) {
5326
- explicitMatrix[resource] = access;
5327
- explicitSpecificity[resource] = specificity;
5328
- } else if (specificity === currentSpecificity) {
5329
- explicitMatrix[resource] = strongestAccess(
5330
- _nullishCoalesce(explicitMatrix[resource], () => ( "none")),
5331
- access
5332
- );
5333
- }
5355
+ const access = explicitAccessForResource(explicitMatrix, resource);
5356
+ if (access === void 0) {
5357
+ continue;
5358
+ }
5359
+ const currentSpecificity = _nullishCoalesce(specificityByResource[resource], () => ( -1));
5360
+ if (specificity > currentSpecificity) {
5361
+ matrix[resource] = access;
5362
+ specificityByResource[resource] = specificity;
5363
+ } else if (specificity === currentSpecificity) {
5364
+ matrix[resource] = strongestAccess(_nullishCoalesce(matrix[resource], () => ( "none")), access);
5334
5365
  }
5335
5366
  }
5336
5367
  }
5337
- return permissionMatrixFromResolvedScopes({
5338
- hasDefaultPermission,
5339
- baseAccess,
5340
- matrix: explicitMatrix
5341
- });
5368
+ return permissionMatrixFromExplicitPermissions(matrix);
5342
5369
  }
5343
5370
  function normalizeRoomPermissions(permissions) {
5344
5371
  if (!Array.isArray(permissions)) {
@@ -5381,12 +5408,21 @@ function permissionMatrixToScopes(matrix) {
5381
5408
  if (baseAccess !== "none") {
5382
5409
  scopes.push(permissionForAccessLevel(BASE_PERMISSION_RESOURCE, baseAccess));
5383
5410
  }
5384
- for (const resource of ROOM_PERMISSION_RESOURCES) {
5385
- const access = matrix[resource];
5386
- if (access !== baseAccess) {
5387
- scopes.push(permissionForAccessLevel(resource, access));
5411
+ if (matrix.storage !== baseAccess) {
5412
+ scopes.push(permissionForAccessLevel("storage", matrix.storage));
5413
+ }
5414
+ const commentsAccess = matrix.comments;
5415
+ if (commentsAccess !== baseAccess) {
5416
+ scopes.push(permissionForAccessLevel("comments", commentsAccess));
5417
+ }
5418
+ for (const resource of COMMENT_VISIBILITY_RESOURCES) {
5419
+ if (matrix[resource] !== commentsAccess) {
5420
+ scopes.push(permissionForAccessLevel(resource, matrix[resource]));
5388
5421
  }
5389
5422
  }
5423
+ if (matrix.feeds !== baseAccess) {
5424
+ scopes.push(permissionForAccessLevel("feeds", matrix.feeds));
5425
+ }
5390
5426
  return scopes;
5391
5427
  }
5392
5428
  function mergeRoomPermissionScopes({
@@ -5395,63 +5431,55 @@ function mergeRoomPermissionScopes({
5395
5431
  userAccesses
5396
5432
  }) {
5397
5433
  const sources = [
5398
- resolvePermissionScopes(defaultAccesses),
5399
- mergeResolvedScopesByHighestAccess(
5400
- groupsAccesses.map(resolvePermissionScopes)
5434
+ explicitPermissionMatrixFromScopes(defaultAccesses),
5435
+ mergeExplicitPermissionMatricesByHighestAccess(
5436
+ groupsAccesses.map(explicitPermissionMatrixFromScopes)
5401
5437
  ),
5402
- resolvePermissionScopes(userAccesses)
5438
+ explicitPermissionMatrixFromScopes(userAccesses)
5403
5439
  ];
5404
- const merged = {
5405
- hasDefaultPermission: false,
5406
- baseAccess: "none",
5407
- matrix: {}
5408
- };
5440
+ const merged = {};
5409
5441
  for (const source of sources) {
5410
- if (source.hasDefaultPermission) {
5411
- merged.hasDefaultPermission = true;
5412
- merged.baseAccess = source.baseAccess;
5442
+ if (source.room !== void 0) {
5443
+ merged.room = source.room;
5413
5444
  }
5414
5445
  for (const resource of ROOM_PERMISSION_RESOURCES) {
5415
- const access = source.matrix[resource];
5446
+ const access = explicitAccessForResource(source, resource);
5416
5447
  if (access !== void 0) {
5417
- merged.matrix[resource] = access;
5448
+ merged[resource] = access;
5418
5449
  }
5419
5450
  }
5420
5451
  }
5421
- return permissionMatrixToScopes(permissionMatrixFromResolvedScopes(merged));
5452
+ return permissionMatrixToScopes(
5453
+ permissionMatrixFromExplicitPermissions(merged)
5454
+ );
5422
5455
  }
5423
- function mergeResolvedScopesByHighestAccess(sources) {
5424
- const merged = {
5425
- hasDefaultPermission: false,
5426
- baseAccess: "none",
5427
- matrix: {}
5428
- };
5456
+ function mergeExplicitPermissionMatricesByHighestAccess(sources) {
5457
+ const merged = {};
5429
5458
  for (const source of sources) {
5430
- if (source.hasDefaultPermission) {
5431
- merged.hasDefaultPermission = true;
5432
- merged.baseAccess = strongestAccess(merged.baseAccess, source.baseAccess);
5459
+ if (source.room !== void 0) {
5460
+ merged.room = strongestAccess(_nullishCoalesce(merged.room, () => ( "none")), source.room);
5433
5461
  }
5434
5462
  for (const resource of ROOM_PERMISSION_RESOURCES) {
5435
- const access = source.matrix[resource];
5463
+ const access = explicitAccessForResource(source, resource);
5436
5464
  if (access !== void 0) {
5437
- merged.matrix[resource] = strongestAccess(
5438
- _nullishCoalesce(merged.matrix[resource], () => ( "none")),
5439
- access
5440
- );
5465
+ merged[resource] = strongestAccess(_nullishCoalesce(merged[resource], () => ( "none")), access);
5441
5466
  }
5442
5467
  }
5443
5468
  }
5444
5469
  return merged;
5445
5470
  }
5471
+ function explicitAccessForResource(source, resource) {
5472
+ return _nullishCoalesce(source[resource], () => ( (isCommentVisibilityResource(resource) ? source.comments : void 0)));
5473
+ }
5446
5474
  function permissionForAccessLevel(resource, access, field = resource) {
5447
- const levels = PERMISSIONS_BY_RESOURCE[resource];
5448
- const permissions = levels[access];
5449
- if (permissions === void 0 || permissions.length === 0) {
5450
- throw new Error(
5451
- `Invalid permission level for ${field}: ${_nullishCoalesce(JSON.stringify(access), () => ( String(access)))}`
5452
- );
5475
+ const permissions = PERMISSIONS_BY_RESOURCE[resource][access];
5476
+ const permission = _optionalChain([permissions, 'optionalAccess', _109 => _109[0]]);
5477
+ if (permission !== void 0) {
5478
+ return permission;
5453
5479
  }
5454
- return permissions[0];
5480
+ throw new Error(
5481
+ `Invalid permission level for ${field}: ${_nullishCoalesce(JSON.stringify(access), () => ( String(access)))}`
5482
+ );
5455
5483
  }
5456
5484
  function strongestAccess(left, right) {
5457
5485
  return ACCESS_LEVEL_RANKS[right] > ACCESS_LEVEL_RANKS[left] ? right : left;
@@ -5479,7 +5507,7 @@ function validatePermissionsSet(scopes) {
5479
5507
  if (basePermissionScopes.has(scope) || scope === Permission.LegacyRoomPresenceWrite) {
5480
5508
  continue;
5481
5509
  }
5482
- const feature = scope.slice(0, scope.indexOf(":"));
5510
+ const feature = permissionFeature(scope);
5483
5511
  if (seenFeatures.has(feature)) {
5484
5512
  return `Permissions can include at most one scope per feature, got multiple "${feature}" scopes`;
5485
5513
  }
@@ -5487,6 +5515,13 @@ function validatePermissionsSet(scopes) {
5487
5515
  }
5488
5516
  return true;
5489
5517
  }
5518
+ function permissionFeature(scope) {
5519
+ const accessSeparatorIndex = scope.lastIndexOf(":");
5520
+ return accessSeparatorIndex === -1 ? scope : scope.slice(0, accessSeparatorIndex);
5521
+ }
5522
+ function isCommentVisibilityResource(resource) {
5523
+ return resource.startsWith("comments:");
5524
+ }
5490
5525
 
5491
5526
  // src/protocol/AuthToken.ts
5492
5527
  function isValidAuthTokenPayload(data) {
@@ -5548,7 +5583,7 @@ function createAuthManager(authOptions, onAuthenticate) {
5548
5583
  return void 0;
5549
5584
  }
5550
5585
  async function makeAuthRequest(options) {
5551
- const fetcher = _nullishCoalesce(_optionalChain([authOptions, 'access', _107 => _107.polyfills, 'optionalAccess', _108 => _108.fetch]), () => ( (typeof window === "undefined" ? void 0 : window.fetch)));
5586
+ const fetcher = _nullishCoalesce(_optionalChain([authOptions, 'access', _110 => _110.polyfills, 'optionalAccess', _111 => _111.fetch]), () => ( (typeof window === "undefined" ? void 0 : window.fetch)));
5552
5587
  if (authentication.type === "private") {
5553
5588
  if (fetcher === void 0) {
5554
5589
  throw new StopRetrying(
@@ -5561,14 +5596,14 @@ function createAuthManager(authOptions, onAuthenticate) {
5561
5596
  const parsed = parseAuthToken(response.token);
5562
5597
  if (seenTokens.has(parsed.raw)) {
5563
5598
  const cachedToken = getCachedToken(options);
5564
- if (_optionalChain([cachedToken, 'optionalAccess', _109 => _109.raw]) === parsed.raw) {
5599
+ if (_optionalChain([cachedToken, 'optionalAccess', _112 => _112.raw]) === parsed.raw) {
5565
5600
  return cachedToken;
5566
5601
  }
5567
5602
  throw new StopRetrying(
5568
5603
  "The same Liveblocks auth token was issued from the backend before. Caching Liveblocks tokens is not supported."
5569
5604
  );
5570
5605
  }
5571
- _optionalChain([onAuthenticate, 'optionalCall', _110 => _110(parsed.parsed)]);
5606
+ _optionalChain([onAuthenticate, 'optionalCall', _113 => _113(parsed.parsed)]);
5572
5607
  return parsed;
5573
5608
  }
5574
5609
  if (authentication.type === "custom") {
@@ -5576,7 +5611,7 @@ function createAuthManager(authOptions, onAuthenticate) {
5576
5611
  if (response && typeof response === "object") {
5577
5612
  if (typeof response.token === "string") {
5578
5613
  const parsed = parseAuthToken(response.token);
5579
- _optionalChain([onAuthenticate, 'optionalCall', _111 => _111(parsed.parsed)]);
5614
+ _optionalChain([onAuthenticate, 'optionalCall', _114 => _114(parsed.parsed)]);
5580
5615
  return parsed;
5581
5616
  } else if (typeof response.error === "string") {
5582
5617
  const reason = `Authentication failed: ${"reason" in response && typeof response.reason === "string" ? response.reason : "Forbidden"}`;
@@ -5674,7 +5709,13 @@ function cachedTokenSatisfiesRequest(cachedToken, request) {
5674
5709
  _nullishCoalesce(cachedToken.permissions, () => ( [])),
5675
5710
  request.roomId
5676
5711
  );
5677
- return matrix !== void 0 && hasPermissionAccess(matrix, request.resource, request.access);
5712
+ if (matrix === void 0) {
5713
+ return false;
5714
+ }
5715
+ if (request.resource === "comments" && request.access === "read") {
5716
+ return hasPermissionAccess(matrix, "comments", "read") || hasPermissionAccess(matrix, "comments:public", "read") || hasPermissionAccess(matrix, "comments:private", "read");
5717
+ }
5718
+ return hasPermissionAccess(matrix, request.resource, request.access);
5678
5719
  }
5679
5720
  function prepareAuthentication(authOptions) {
5680
5721
  const { publicApiKey, authEndpoint } = authOptions;
@@ -5768,15 +5809,13 @@ var OpCode = Object.freeze({
5768
5809
  DELETE_CRDT: 5,
5769
5810
  DELETE_OBJECT_KEY: 6,
5770
5811
  CREATE_MAP: 7,
5771
- CREATE_REGISTER: 8,
5772
- CREATE_TEXT: 9,
5773
- UPDATE_TEXT: 10
5812
+ CREATE_REGISTER: 8
5774
5813
  });
5775
5814
  function isIgnoredOp(op) {
5776
5815
  return op.type === OpCode.DELETE_CRDT && op.id === "ACK";
5777
5816
  }
5778
5817
  function isCreateOp(op) {
5779
- return op.type === OpCode.CREATE_OBJECT || op.type === OpCode.CREATE_REGISTER || op.type === OpCode.CREATE_MAP || op.type === OpCode.CREATE_LIST || op.type === OpCode.CREATE_TEXT;
5818
+ return op.type === OpCode.CREATE_OBJECT || op.type === OpCode.CREATE_REGISTER || op.type === OpCode.CREATE_MAP || op.type === OpCode.CREATE_LIST;
5780
5819
  }
5781
5820
 
5782
5821
  // src/protocol/StorageNode.ts
@@ -5784,8 +5823,7 @@ var CrdtType = Object.freeze({
5784
5823
  OBJECT: 0,
5785
5824
  LIST: 1,
5786
5825
  MAP: 2,
5787
- REGISTER: 3,
5788
- TEXT: 4
5826
+ REGISTER: 3
5789
5827
  });
5790
5828
  function isRootStorageNode(node) {
5791
5829
  return node[0] === "root";
@@ -5802,9 +5840,6 @@ function isMapStorageNode(node) {
5802
5840
  function isRegisterStorageNode(node) {
5803
5841
  return node[1].type === CrdtType.REGISTER;
5804
5842
  }
5805
- function isTextStorageNode(node) {
5806
- return node[1].type === CrdtType.TEXT;
5807
- }
5808
5843
  function isCompactRootNode(node) {
5809
5844
  return node[0] === "root";
5810
5845
  }
@@ -5827,9 +5862,6 @@ function* compactNodesToNodeStream(compactNodes) {
5827
5862
  case CrdtType.REGISTER:
5828
5863
  yield [cnode[0], { type: CrdtType.REGISTER, parentId: cnode[2], parentKey: cnode[3], data: cnode[4] }];
5829
5864
  break;
5830
- case CrdtType.TEXT:
5831
- yield [cnode[0], { type: CrdtType.TEXT, parentId: cnode[2], parentKey: cnode[3], data: cnode[4], version: cnode[5] }];
5832
- break;
5833
5865
  default:
5834
5866
  }
5835
5867
  }
@@ -5858,17 +5890,6 @@ function* nodeStreamToCompactNodes(nodes) {
5858
5890
  const id = node[0];
5859
5891
  const crdt = node[1];
5860
5892
  yield [id, CrdtType.REGISTER, crdt.parentId, crdt.parentKey, crdt.data];
5861
- } else if (isTextStorageNode(node)) {
5862
- const id = node[0];
5863
- const crdt = node[1];
5864
- yield [
5865
- id,
5866
- CrdtType.TEXT,
5867
- crdt.parentId,
5868
- crdt.parentKey,
5869
- crdt.data,
5870
- crdt.version
5871
- ];
5872
5893
  } else {
5873
5894
  }
5874
5895
  }
@@ -6071,10 +6092,6 @@ ${parentKey}`;
6071
6092
  get size() {
6072
6093
  return this.#byOpId.size;
6073
6094
  }
6074
- /** The still-unacknowledged op with the given opId, if any. */
6075
- get(opId) {
6076
- return this.#byOpId.get(opId);
6077
- }
6078
6095
  /**
6079
6096
  * Mark the given Op as still unacknowledged.
6080
6097
  */
@@ -6111,12 +6128,12 @@ ${parentKey}`;
6111
6128
  if (isCreateOp(op)) {
6112
6129
  const posKey = this.#posKey(op.parentId, op.parentKey);
6113
6130
  const atPosition = this.#createOpsByPosition.get(posKey);
6114
- _optionalChain([atPosition, 'optionalAccess', _112 => _112.delete, 'call', _113 => _113(opId)]);
6131
+ _optionalChain([atPosition, 'optionalAccess', _115 => _115.delete, 'call', _116 => _116(opId)]);
6115
6132
  if (atPosition !== void 0 && atPosition.size === 0) {
6116
6133
  this.#createOpsByPosition.delete(posKey);
6117
6134
  }
6118
6135
  const inParent = this.#createOpsByParent.get(op.parentId);
6119
- _optionalChain([inParent, 'optionalAccess', _114 => _114.delete, 'call', _115 => _115(opId)]);
6136
+ _optionalChain([inParent, 'optionalAccess', _117 => _117.delete, 'call', _118 => _118(opId)]);
6120
6137
  if (inParent !== void 0 && inParent.size === 0) {
6121
6138
  this.#createOpsByParent.delete(op.parentId);
6122
6139
  }
@@ -6128,14 +6145,14 @@ ${parentKey}`;
6128
6145
  * Empty if none.
6129
6146
  */
6130
6147
  getByParentIdAndKey(parentId, parentKey) {
6131
- return _nullishCoalesce(_optionalChain([this, 'access', _116 => _116.#createOpsByPosition, 'access', _117 => _117.get, 'call', _118 => _118(this.#posKey(parentId, parentKey)), 'optionalAccess', _119 => _119.values, 'call', _120 => _120()]), () => ( []));
6148
+ return _nullishCoalesce(_optionalChain([this, 'access', _119 => _119.#createOpsByPosition, 'access', _120 => _120.get, 'call', _121 => _121(this.#posKey(parentId, parentKey)), 'optionalAccess', _122 => _122.values, 'call', _123 => _123()]), () => ( []));
6132
6149
  }
6133
6150
  /**
6134
6151
  * The still-unacknowledged Create ops with the given `parentId` (across all
6135
6152
  * positions), in dispatch order. O(1) lookup. Empty if none.
6136
6153
  */
6137
6154
  getByParentId(parentId) {
6138
- return _nullishCoalesce(_optionalChain([this, 'access', _121 => _121.#createOpsByParent, 'access', _122 => _122.get, 'call', _123 => _123(parentId), 'optionalAccess', _124 => _124.values, 'call', _125 => _125()]), () => ( []));
6155
+ return _nullishCoalesce(_optionalChain([this, 'access', _124 => _124.#createOpsByParent, 'access', _125 => _125.get, 'call', _126 => _126(parentId), 'optionalAccess', _127 => _127.values, 'call', _128 => _128()]), () => ( []));
6139
6156
  }
6140
6157
  /** All still-unacknowledged ops, in dispatch order. */
6141
6158
  values() {
@@ -6175,8 +6192,8 @@ function createManagedPool(roomId, options) {
6175
6192
  deleteNode: (id) => void nodes.delete(id),
6176
6193
  generateId: () => `${getCurrentConnectionId()}:${clock++}`,
6177
6194
  generateOpId: () => `${getCurrentConnectionId()}:${opClock++}`,
6178
- dispatch(ops, reverse, storageUpdates, options2) {
6179
- _optionalChain([onDispatch, 'optionalCall', _126 => _126(ops, reverse, storageUpdates, options2)]);
6195
+ dispatch(ops, reverse, storageUpdates) {
6196
+ _optionalChain([onDispatch, 'optionalCall', _129 => _129(ops, reverse, storageUpdates)]);
6180
6197
  },
6181
6198
  assertStorageIsWritable: () => {
6182
6199
  if (!isStorageWritable()) {
@@ -6900,7 +6917,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
6900
6917
  #applyInsertUndoRedo(op) {
6901
6918
  const { id, parentKey: key } = op;
6902
6919
  const child = creationOpToLiveNode(op);
6903
- if (_optionalChain([this, 'access', _127 => _127._pool, 'optionalAccess', _128 => _128.getNode, 'call', _129 => _129(id)]) !== void 0) {
6920
+ if (_optionalChain([this, 'access', _130 => _130._pool, 'optionalAccess', _131 => _131.getNode, 'call', _132 => _132(id)]) !== void 0) {
6904
6921
  return { modified: false };
6905
6922
  }
6906
6923
  child._attach(id, nn(this._pool));
@@ -6908,8 +6925,8 @@ var LiveList = class _LiveList extends AbstractCrdt {
6908
6925
  const existingItemIndex = this._indexOfPosition(key);
6909
6926
  let newKey = key;
6910
6927
  if (existingItemIndex !== -1) {
6911
- const before2 = _optionalChain([this, 'access', _130 => _130.#items, 'access', _131 => _131.at, 'call', _132 => _132(existingItemIndex), 'optionalAccess', _133 => _133._parentPos]);
6912
- const after2 = _optionalChain([this, 'access', _134 => _134.#items, 'access', _135 => _135.at, 'call', _136 => _136(existingItemIndex + 1), 'optionalAccess', _137 => _137._parentPos]);
6928
+ const before2 = _optionalChain([this, 'access', _133 => _133.#items, 'access', _134 => _134.at, 'call', _135 => _135(existingItemIndex), 'optionalAccess', _136 => _136._parentPos]);
6929
+ const after2 = _optionalChain([this, 'access', _137 => _137.#items, 'access', _138 => _138.at, 'call', _139 => _139(existingItemIndex + 1), 'optionalAccess', _140 => _140._parentPos]);
6913
6930
  newKey = makePosition(before2, after2);
6914
6931
  child._setParentLink(this, newKey);
6915
6932
  }
@@ -6923,7 +6940,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
6923
6940
  #applySetUndoRedo(op) {
6924
6941
  const { id, parentKey: key } = op;
6925
6942
  const child = creationOpToLiveNode(op);
6926
- if (_optionalChain([this, 'access', _138 => _138._pool, 'optionalAccess', _139 => _139.getNode, 'call', _140 => _140(id)]) !== void 0) {
6943
+ if (_optionalChain([this, 'access', _141 => _141._pool, 'optionalAccess', _142 => _142.getNode, 'call', _143 => _143(id)]) !== void 0) {
6927
6944
  return { modified: false };
6928
6945
  }
6929
6946
  const indexOfItemWithSameKey = this._indexOfPosition(key);
@@ -7044,7 +7061,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
7044
7061
  } else {
7045
7062
  this.#updateItemPositionAt(
7046
7063
  existingItemIndex,
7047
- makePosition(newKey, _optionalChain([this, 'access', _141 => _141.#items, 'access', _142 => _142.at, 'call', _143 => _143(existingItemIndex + 1), 'optionalAccess', _144 => _144._parentPos]))
7064
+ makePosition(newKey, _optionalChain([this, 'access', _144 => _144.#items, 'access', _145 => _145.at, 'call', _146 => _146(existingItemIndex + 1), 'optionalAccess', _147 => _147._parentPos]))
7048
7065
  );
7049
7066
  const previousIndex = this.#items.findIndex((item) => item === child);
7050
7067
  this.#updateItemPosition(child, newKey);
@@ -7071,7 +7088,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
7071
7088
  this,
7072
7089
  makePosition(
7073
7090
  newKey,
7074
- _optionalChain([this, 'access', _145 => _145.#items, 'access', _146 => _146.at, 'call', _147 => _147(existingItemIndex + 1), 'optionalAccess', _148 => _148._parentPos])
7091
+ _optionalChain([this, 'access', _148 => _148.#items, 'access', _149 => _149.at, 'call', _150 => _150(existingItemIndex + 1), 'optionalAccess', _151 => _151._parentPos])
7075
7092
  )
7076
7093
  );
7077
7094
  this.#items.reposition(existingItem);
@@ -7095,7 +7112,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
7095
7112
  existingItemIndex,
7096
7113
  makePosition(
7097
7114
  newKey,
7098
- _optionalChain([this, 'access', _149 => _149.#items, 'access', _150 => _150.at, 'call', _151 => _151(existingItemIndex + 1), 'optionalAccess', _152 => _152._parentPos])
7115
+ _optionalChain([this, 'access', _152 => _152.#items, 'access', _153 => _153.at, 'call', _154 => _154(existingItemIndex + 1), 'optionalAccess', _155 => _155._parentPos])
7099
7116
  )
7100
7117
  );
7101
7118
  }
@@ -7123,7 +7140,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
7123
7140
  if (existingItemIndex !== -1) {
7124
7141
  actualNewKey = makePosition(
7125
7142
  newKey,
7126
- _optionalChain([this, 'access', _153 => _153.#items, 'access', _154 => _154.at, 'call', _155 => _155(existingItemIndex + 1), 'optionalAccess', _156 => _156._parentPos])
7143
+ _optionalChain([this, 'access', _156 => _156.#items, 'access', _157 => _157.at, 'call', _158 => _158(existingItemIndex + 1), 'optionalAccess', _159 => _159._parentPos])
7127
7144
  );
7128
7145
  }
7129
7146
  this.#updateItemPosition(child, actualNewKey);
@@ -7197,14 +7214,14 @@ var LiveList = class _LiveList extends AbstractCrdt {
7197
7214
  * instead of resolving its position against the client's stale view.
7198
7215
  */
7199
7216
  #injectAt(element, index, intent) {
7200
- _optionalChain([this, 'access', _157 => _157._pool, 'optionalAccess', _158 => _158.assertStorageIsWritable, 'call', _159 => _159()]);
7217
+ _optionalChain([this, 'access', _160 => _160._pool, 'optionalAccess', _161 => _161.assertStorageIsWritable, 'call', _162 => _162()]);
7201
7218
  if (index < 0 || index > this.#items.length) {
7202
7219
  throw new Error(
7203
7220
  `Cannot insert list item at index "${index}". index should be between 0 and ${this.#items.length}`
7204
7221
  );
7205
7222
  }
7206
- const before2 = _optionalChain([this, 'access', _160 => _160.#items, 'access', _161 => _161.at, 'call', _162 => _162(index - 1), 'optionalAccess', _163 => _163._parentPos]);
7207
- const after2 = _optionalChain([this, 'access', _164 => _164.#items, 'access', _165 => _165.at, 'call', _166 => _166(index), 'optionalAccess', _167 => _167._parentPos]);
7223
+ const before2 = _optionalChain([this, 'access', _163 => _163.#items, 'access', _164 => _164.at, 'call', _165 => _165(index - 1), 'optionalAccess', _166 => _166._parentPos]);
7224
+ const after2 = _optionalChain([this, 'access', _167 => _167.#items, 'access', _168 => _168.at, 'call', _169 => _169(index), 'optionalAccess', _170 => _170._parentPos]);
7208
7225
  const position = makePosition(before2, after2);
7209
7226
  const value = lsonToLiveNode(element);
7210
7227
  value._setParentLink(this, position);
@@ -7228,7 +7245,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
7228
7245
  * @param targetIndex The index where the element should be after moving.
7229
7246
  */
7230
7247
  move(index, targetIndex) {
7231
- _optionalChain([this, 'access', _168 => _168._pool, 'optionalAccess', _169 => _169.assertStorageIsWritable, 'call', _170 => _170()]);
7248
+ _optionalChain([this, 'access', _171 => _171._pool, 'optionalAccess', _172 => _172.assertStorageIsWritable, 'call', _173 => _173()]);
7232
7249
  if (targetIndex < 0) {
7233
7250
  throw new Error("targetIndex cannot be less than 0");
7234
7251
  }
@@ -7246,11 +7263,11 @@ var LiveList = class _LiveList extends AbstractCrdt {
7246
7263
  let beforePosition = null;
7247
7264
  let afterPosition = null;
7248
7265
  if (index < targetIndex) {
7249
- afterPosition = targetIndex === this.#items.length - 1 ? void 0 : _optionalChain([this, 'access', _171 => _171.#items, 'access', _172 => _172.at, 'call', _173 => _173(targetIndex + 1), 'optionalAccess', _174 => _174._parentPos]);
7266
+ afterPosition = targetIndex === this.#items.length - 1 ? void 0 : _optionalChain([this, 'access', _174 => _174.#items, 'access', _175 => _175.at, 'call', _176 => _176(targetIndex + 1), 'optionalAccess', _177 => _177._parentPos]);
7250
7267
  beforePosition = this.#items.at(targetIndex)._parentPos;
7251
7268
  } else {
7252
7269
  afterPosition = this.#items.at(targetIndex)._parentPos;
7253
- beforePosition = targetIndex === 0 ? void 0 : _optionalChain([this, 'access', _175 => _175.#items, 'access', _176 => _176.at, 'call', _177 => _177(targetIndex - 1), 'optionalAccess', _178 => _178._parentPos]);
7270
+ beforePosition = targetIndex === 0 ? void 0 : _optionalChain([this, 'access', _178 => _178.#items, 'access', _179 => _179.at, 'call', _180 => _180(targetIndex - 1), 'optionalAccess', _181 => _181._parentPos]);
7254
7271
  }
7255
7272
  const position = makePosition(beforePosition, afterPosition);
7256
7273
  const item = this.#items.at(index);
@@ -7285,7 +7302,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
7285
7302
  * @param index The index of the element to delete
7286
7303
  */
7287
7304
  delete(index) {
7288
- _optionalChain([this, 'access', _179 => _179._pool, 'optionalAccess', _180 => _180.assertStorageIsWritable, 'call', _181 => _181()]);
7305
+ _optionalChain([this, 'access', _182 => _182._pool, 'optionalAccess', _183 => _183.assertStorageIsWritable, 'call', _184 => _184()]);
7289
7306
  if (index < 0 || index >= this.#items.length) {
7290
7307
  throw new Error(
7291
7308
  `Cannot delete list item at index "${index}". index should be between 0 and ${this.#items.length - 1}`
@@ -7318,7 +7335,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
7318
7335
  }
7319
7336
  }
7320
7337
  clear() {
7321
- _optionalChain([this, 'access', _182 => _182._pool, 'optionalAccess', _183 => _183.assertStorageIsWritable, 'call', _184 => _184()]);
7338
+ _optionalChain([this, 'access', _185 => _185._pool, 'optionalAccess', _186 => _186.assertStorageIsWritable, 'call', _187 => _187()]);
7322
7339
  if (this._pool) {
7323
7340
  const ops = [];
7324
7341
  const reverseOps = [];
@@ -7352,7 +7369,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
7352
7369
  }
7353
7370
  }
7354
7371
  set(index, item) {
7355
- _optionalChain([this, 'access', _185 => _185._pool, 'optionalAccess', _186 => _186.assertStorageIsWritable, 'call', _187 => _187()]);
7372
+ _optionalChain([this, 'access', _188 => _188._pool, 'optionalAccess', _189 => _189.assertStorageIsWritable, 'call', _190 => _190()]);
7356
7373
  if (index < 0 || index >= this.#items.length) {
7357
7374
  throw new Error(
7358
7375
  `Cannot set list item at index "${index}". index should be between 0 and ${this.#items.length - 1}`
@@ -7511,7 +7528,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
7511
7528
  #shiftItemPosition(index, key) {
7512
7529
  const shiftedPosition = makePosition(
7513
7530
  key,
7514
- this.#items.length > index + 1 ? _optionalChain([this, 'access', _188 => _188.#items, 'access', _189 => _189.at, 'call', _190 => _190(index + 1), 'optionalAccess', _191 => _191._parentPos]) : void 0
7531
+ this.#items.length > index + 1 ? _optionalChain([this, 'access', _191 => _191.#items, 'access', _192 => _192.at, 'call', _193 => _193(index + 1), 'optionalAccess', _194 => _194._parentPos]) : void 0
7515
7532
  );
7516
7533
  this.#updateItemPositionAt(index, shiftedPosition);
7517
7534
  }
@@ -7760,7 +7777,7 @@ var LiveMap = class _LiveMap extends AbstractCrdt {
7760
7777
  * @param value The value of the element to add. Should be serializable to JSON.
7761
7778
  */
7762
7779
  set(key, value) {
7763
- _optionalChain([this, 'access', _192 => _192._pool, 'optionalAccess', _193 => _193.assertStorageIsWritable, 'call', _194 => _194()]);
7780
+ _optionalChain([this, 'access', _195 => _195._pool, 'optionalAccess', _196 => _196.assertStorageIsWritable, 'call', _197 => _197()]);
7764
7781
  const oldValue = this.#map.get(key);
7765
7782
  if (oldValue) {
7766
7783
  oldValue._detach();
@@ -7806,7 +7823,7 @@ var LiveMap = class _LiveMap extends AbstractCrdt {
7806
7823
  * @returns true if an element existed and has been removed, or false if the element does not exist.
7807
7824
  */
7808
7825
  delete(key) {
7809
- _optionalChain([this, 'access', _195 => _195._pool, 'optionalAccess', _196 => _196.assertStorageIsWritable, 'call', _197 => _197()]);
7826
+ _optionalChain([this, 'access', _198 => _198._pool, 'optionalAccess', _199 => _199.assertStorageIsWritable, 'call', _200 => _200()]);
7810
7827
  const item = this.#map.get(key);
7811
7828
  if (item === void 0) {
7812
7829
  return false;
@@ -8418,20 +8435,20 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
8418
8435
  * Caveat: this method will not add changes to the undo/redo stack.
8419
8436
  */
8420
8437
  setLocal(key, value) {
8421
- _optionalChain([this, 'access', _198 => _198._pool, 'optionalAccess', _199 => _199.assertStorageIsWritable, 'call', _200 => _200()]);
8438
+ _optionalChain([this, 'access', _201 => _201._pool, 'optionalAccess', _202 => _202.assertStorageIsWritable, 'call', _203 => _203()]);
8422
8439
  const deleteResult = this.#prepareDelete(key);
8423
8440
  this.#local.set(key, value);
8424
8441
  this.invalidate();
8425
8442
  if (this._pool !== void 0 && this._id !== void 0) {
8426
- const ops = _nullishCoalesce(_optionalChain([deleteResult, 'optionalAccess', _201 => _201[0]]), () => ( []));
8427
- const reverse = _nullishCoalesce(_optionalChain([deleteResult, 'optionalAccess', _202 => _202[1]]), () => ( []));
8428
- const storageUpdates = _nullishCoalesce(_optionalChain([deleteResult, 'optionalAccess', _203 => _203[2]]), () => ( /* @__PURE__ */ new Map()));
8443
+ const ops = _nullishCoalesce(_optionalChain([deleteResult, 'optionalAccess', _204 => _204[0]]), () => ( []));
8444
+ const reverse = _nullishCoalesce(_optionalChain([deleteResult, 'optionalAccess', _205 => _205[1]]), () => ( []));
8445
+ const storageUpdates = _nullishCoalesce(_optionalChain([deleteResult, 'optionalAccess', _206 => _206[2]]), () => ( /* @__PURE__ */ new Map()));
8429
8446
  const existing = storageUpdates.get(this._id);
8430
8447
  storageUpdates.set(this._id, {
8431
8448
  node: this,
8432
8449
  type: "LiveObject",
8433
8450
  updates: {
8434
- ..._optionalChain([existing, 'optionalAccess', _204 => _204.updates]),
8451
+ ..._optionalChain([existing, 'optionalAccess', _207 => _207.updates]),
8435
8452
  [key]: { type: "update" }
8436
8453
  }
8437
8454
  });
@@ -8451,7 +8468,7 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
8451
8468
  * #synced or pool/id are unavailable. Does NOT dispatch.
8452
8469
  */
8453
8470
  #prepareDelete(key) {
8454
- _optionalChain([this, 'access', _205 => _205._pool, 'optionalAccess', _206 => _206.assertStorageIsWritable, 'call', _207 => _207()]);
8471
+ _optionalChain([this, 'access', _208 => _208._pool, 'optionalAccess', _209 => _209.assertStorageIsWritable, 'call', _210 => _210()]);
8455
8472
  const k = key;
8456
8473
  if (this.#local.has(k) && !this.#synced.has(k)) {
8457
8474
  const oldValue2 = this.#local.get(k);
@@ -8527,7 +8544,7 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
8527
8544
  const result = this.#prepareDelete(key);
8528
8545
  if (result) {
8529
8546
  const [ops, reverse, storageUpdates] = result;
8530
- _optionalChain([this, 'access', _208 => _208._pool, 'optionalAccess', _209 => _209.dispatch, 'call', _210 => _210(ops, reverse, storageUpdates)]);
8547
+ _optionalChain([this, 'access', _211 => _211._pool, 'optionalAccess', _212 => _212.dispatch, 'call', _213 => _213(ops, reverse, storageUpdates)]);
8531
8548
  }
8532
8549
  }
8533
8550
  /**
@@ -8535,7 +8552,7 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
8535
8552
  * @param patch The object used to overrides properties
8536
8553
  */
8537
8554
  update(patch) {
8538
- _optionalChain([this, 'access', _211 => _211._pool, 'optionalAccess', _212 => _212.assertStorageIsWritable, 'call', _213 => _213()]);
8555
+ _optionalChain([this, 'access', _214 => _214._pool, 'optionalAccess', _215 => _215.assertStorageIsWritable, 'call', _216 => _216()]);
8539
8556
  if (_LiveObject.detectLargeObjects) {
8540
8557
  const data = {};
8541
8558
  for (const [key, value] of this.#synced) {
@@ -8556,7 +8573,7 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
8556
8573
  const preciseSize = new TextEncoder().encode(jsonString).length;
8557
8574
  if (preciseSize > MAX_LIVE_OBJECT_SIZE) {
8558
8575
  throw new Error(
8559
- `LiveObject size exceeded limit: ${preciseSize} bytes > ${MAX_LIVE_OBJECT_SIZE} bytes. See https://liveblocks.io/docs/platform/limits#Liveblocks-Storage-limits`
8576
+ `LiveObject size exceeded limit: ${preciseSize} bytes > ${MAX_LIVE_OBJECT_SIZE} bytes. See https://liveblocks.io/docs/pricing/limits#Other-limits`
8560
8577
  );
8561
8578
  }
8562
8579
  }
@@ -8735,1269 +8752,149 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
8735
8752
  }
8736
8753
  }, _class2.__initStatic(), _class2);
8737
8754
 
8738
- // src/crdts/liveTextOps.ts
8739
- function attributesEqual(left, right) {
8740
- if (left === right) {
8755
+ // src/crdts/liveblocks-helpers.ts
8756
+ function creationOpToLiveNode(op) {
8757
+ return lsonToLiveNode(creationOpToLson(op));
8758
+ }
8759
+ function creationOpToLson(op) {
8760
+ switch (op.type) {
8761
+ case OpCode.CREATE_REGISTER:
8762
+ return op.data;
8763
+ case OpCode.CREATE_OBJECT:
8764
+ return new LiveObject(op.data);
8765
+ case OpCode.CREATE_MAP:
8766
+ return new LiveMap();
8767
+ case OpCode.CREATE_LIST:
8768
+ return new LiveList([]);
8769
+ default:
8770
+ return assertNever(op, "Unknown creation Op");
8771
+ }
8772
+ }
8773
+ function isSameNodeOrChildOf(node, parent) {
8774
+ if (node === parent) {
8741
8775
  return true;
8742
8776
  }
8743
- if (left === void 0 || right === void 0) {
8744
- return false;
8777
+ if (node.parent.type === "HasParent") {
8778
+ return isSameNodeOrChildOf(node.parent.node, parent);
8745
8779
  }
8746
- const leftKeys = Object.keys(left);
8747
- const rightKeys = Object.keys(right);
8748
- if (leftKeys.length !== rightKeys.length) {
8749
- return false;
8780
+ return false;
8781
+ }
8782
+ function deserialize(node, parentToChildren, pool) {
8783
+ if (isObjectStorageNode(node)) {
8784
+ return LiveObject._deserialize(node, parentToChildren, pool);
8785
+ } else if (isListStorageNode(node)) {
8786
+ return LiveList._deserialize(node, parentToChildren, pool);
8787
+ } else if (isMapStorageNode(node)) {
8788
+ return LiveMap._deserialize(node, parentToChildren, pool);
8789
+ } else if (isRegisterStorageNode(node)) {
8790
+ return LiveRegister._deserialize(node, parentToChildren, pool);
8791
+ } else {
8792
+ throw new Error("Unexpected CRDT type");
8750
8793
  }
8751
- for (const key of leftKeys) {
8752
- if (left[key] !== right[key]) {
8753
- return false;
8754
- }
8794
+ }
8795
+ function deserializeToLson(node, parentToChildren, pool) {
8796
+ if (isObjectStorageNode(node)) {
8797
+ return LiveObject._deserialize(node, parentToChildren, pool);
8798
+ } else if (isListStorageNode(node)) {
8799
+ return LiveList._deserialize(node, parentToChildren, pool);
8800
+ } else if (isMapStorageNode(node)) {
8801
+ return LiveMap._deserialize(node, parentToChildren, pool);
8802
+ } else if (isRegisterStorageNode(node)) {
8803
+ return node[1].data;
8804
+ } else {
8805
+ throw new Error("Unexpected CRDT type");
8755
8806
  }
8756
- return true;
8757
8807
  }
8758
- function cloneAttributes(attributes) {
8759
- return attributes === void 0 ? void 0 : freeze({ ...attributes });
8808
+ function isLiveStructure(value) {
8809
+ return isLiveList(value) || isLiveMap(value) || isLiveObject(value);
8760
8810
  }
8761
- function normalizeSegments(segments) {
8762
- const normalized = [];
8763
- for (const segment of segments) {
8764
- if (segment.text.length === 0) {
8765
- continue;
8766
- }
8767
- const last = normalized.at(-1);
8768
- const attributes = cloneAttributes(segment.attributes);
8769
- if (last !== void 0 && attributesEqual(last.attributes, attributes)) {
8770
- last.text += segment.text;
8771
- } else {
8772
- normalized.push({ text: segment.text, attributes });
8773
- }
8774
- }
8775
- return normalized;
8811
+ function isLiveNode(value) {
8812
+ return isLiveStructure(value) || isLiveRegister(value);
8776
8813
  }
8777
- function dataToSegments(data) {
8778
- return normalizeSegments(
8779
- data.map(([text, attributes]) => ({
8780
- text,
8781
- attributes
8782
- }))
8783
- );
8814
+ function isLiveList(value) {
8815
+ return value instanceof LiveList;
8784
8816
  }
8785
- function segmentsToData(segments) {
8786
- return segments.map(
8787
- (segment) => segment.attributes === void 0 ? [segment.text] : [segment.text, { ...segment.attributes }]
8788
- );
8817
+ function isLiveMap(value) {
8818
+ return value instanceof LiveMap;
8789
8819
  }
8790
- function textLength(segments) {
8791
- return segments.reduce((sum, segment) => sum + segment.text.length, 0);
8820
+ function isLiveObject(value) {
8821
+ return value instanceof LiveObject;
8792
8822
  }
8793
- function splitSegmentsAt(segments, index) {
8794
- const result = [];
8795
- let offset = 0;
8796
- for (const segment of segments) {
8797
- const end = offset + segment.text.length;
8798
- if (index > offset && index < end) {
8799
- const before2 = segment.text.slice(0, index - offset);
8800
- const after2 = segment.text.slice(index - offset);
8801
- result.push({ text: before2, attributes: segment.attributes });
8802
- result.push({ text: after2, attributes: segment.attributes });
8803
- } else {
8804
- result.push({ text: segment.text, attributes: segment.attributes });
8805
- }
8806
- offset = end;
8807
- }
8808
- return result;
8823
+ function isLiveRegister(value) {
8824
+ return value instanceof LiveRegister;
8809
8825
  }
8810
- function clipRange(index, length, contentLength) {
8811
- const clippedIndex = Math.max(0, Math.min(index, contentLength));
8812
- const clippedEnd = Math.max(
8813
- clippedIndex,
8814
- Math.min(index + length, contentLength)
8815
- );
8816
- return { index: clippedIndex, length: clippedEnd - clippedIndex };
8826
+ function cloneLson(value) {
8827
+ return value === void 0 ? void 0 : isLiveStructure(value) ? value.clone() : deepClone(value);
8817
8828
  }
8818
- function applyInsert(segments, index, text, attributes) {
8819
- if (text.length === 0) {
8820
- return normalizeSegments(segments);
8821
- }
8822
- const split = splitSegmentsAt(segments, index);
8823
- const result = [];
8824
- let offset = 0;
8825
- let inserted = false;
8826
- for (const segment of split) {
8827
- if (!inserted && offset === index) {
8828
- result.push({ text, attributes });
8829
- inserted = true;
8830
- }
8831
- result.push(segment);
8832
- offset += segment.text.length;
8833
- }
8834
- if (!inserted) {
8835
- result.push({ text, attributes });
8829
+ function liveNodeToLson(obj) {
8830
+ if (obj instanceof LiveRegister) {
8831
+ return obj.data;
8832
+ } else if (obj instanceof LiveList || obj instanceof LiveMap || obj instanceof LiveObject) {
8833
+ return obj;
8834
+ } else {
8835
+ return assertNever(obj, "Unknown AbstractCrdt");
8836
8836
  }
8837
- return normalizeSegments(result);
8838
8837
  }
8839
- function extractDeletedSegments(segments, index, length) {
8840
- const split = splitSegmentsAt(
8841
- splitSegmentsAt(segments, index),
8842
- index + length
8843
- );
8844
- const deleted = [];
8845
- let offset = 0;
8846
- for (const segment of split) {
8847
- const end = offset + segment.text.length;
8848
- if (offset >= index && end <= index + length) {
8849
- deleted.push({
8850
- text: segment.text,
8851
- attributes: segment.attributes
8852
- });
8853
- }
8854
- offset = end;
8838
+ function lsonToLiveNode(value) {
8839
+ if (value instanceof LiveObject || value instanceof LiveMap || value instanceof LiveList) {
8840
+ return value;
8841
+ } else {
8842
+ return new LiveRegister(value);
8855
8843
  }
8856
- return normalizeSegments(deleted);
8857
8844
  }
8858
- function applyDelete(segments, index, length) {
8859
- const deletedSegments = extractDeletedSegments(segments, index, length);
8860
- const split = splitSegmentsAt(
8861
- splitSegmentsAt(segments, index),
8862
- index + length
8863
- );
8864
- const result = [];
8865
- let offset = 0;
8866
- let deletedText = "";
8867
- for (const segment of split) {
8868
- const end = offset + segment.text.length;
8869
- if (offset >= index && end <= index + length) {
8870
- deletedText += segment.text;
8845
+ function dumpPool(pool) {
8846
+ const rows = Array.from(pool.nodes.values(), (node) => {
8847
+ const parent = node.parent;
8848
+ const parentId = parent.type === "HasParent" ? _nullishCoalesce(parent.node._id, () => ( "?")) : parent.type === "Orphaned" ? "<orphaned>" : "-";
8849
+ let value;
8850
+ if (node instanceof LiveRegister) {
8851
+ value = stringifyOrLog(node.data);
8852
+ } else if (node instanceof LiveList) {
8853
+ value = "<LiveList>";
8854
+ } else if (node instanceof LiveMap) {
8855
+ value = "<LiveMap>";
8871
8856
  } else {
8872
- result.push(segment);
8857
+ value = "<LiveObject>";
8873
8858
  }
8874
- offset = end;
8875
- }
8876
- return {
8877
- segments: normalizeSegments(result),
8878
- deletedText,
8879
- deletedSegments
8880
- };
8859
+ return { id: nn(node._id), parentId, key: _nullishCoalesce(node._parentKey, () => ( "")), value };
8860
+ });
8861
+ rows.sort((a, b) => {
8862
+ if (a.parentId !== b.parentId) return a.parentId < b.parentId ? -1 : 1;
8863
+ if (a.key !== b.key) return a.key < b.key ? -1 : 1;
8864
+ return 0;
8865
+ });
8866
+ return rows.map(
8867
+ (r) => ` ${r.id} parent=${r.parentId} key=${r.key || "\u2014"} ${r.value}`
8868
+ ).join("\n");
8881
8869
  }
8882
- function applyFormat(segments, index, length, attributes) {
8883
- const split = splitSegmentsAt(
8884
- splitSegmentsAt(segments, index),
8885
- index + length
8886
- );
8887
- const result = [];
8888
- let offset = 0;
8889
- for (const segment of split) {
8890
- const end = offset + segment.text.length;
8891
- if (offset >= index && end <= index + length) {
8892
- const nextAttributes = {
8893
- ..._nullishCoalesce(segment.attributes, () => ( {}))
8894
- };
8895
- for (const [key, value] of Object.entries(attributes)) {
8896
- if (value === null) {
8897
- delete nextAttributes[key];
8898
- } else {
8899
- nextAttributes[key] = value;
8900
- }
8901
- }
8902
- result.push({
8903
- text: segment.text,
8904
- attributes: Object.keys(nextAttributes).length === 0 ? void 0 : freeze(nextAttributes)
8905
- });
8906
- } else {
8907
- result.push(segment);
8908
- }
8909
- offset = end;
8870
+ function isJsonEq(a, b) {
8871
+ if (a === b) {
8872
+ return true;
8910
8873
  }
8911
- return normalizeSegments(result);
8912
- }
8913
- function formatReverseOperations(segments, index, length, patch) {
8914
- const split = splitSegmentsAt(
8915
- splitSegmentsAt(segments, index),
8916
- index + length
8917
- );
8918
- const result = [];
8919
- let offset = 0;
8920
- for (const segment of split) {
8921
- const end = offset + segment.text.length;
8922
- if (offset >= index && end <= index + length) {
8923
- const attributes = {};
8924
- for (const key of Object.keys(patch)) {
8925
- attributes[key] = _nullishCoalesce(_optionalChain([segment, 'access', _214 => _214.attributes, 'optionalAccess', _215 => _215[key]]), () => ( null));
8874
+ if (typeof a !== "object" || a === null || typeof b !== "object" || b === null) {
8875
+ return false;
8876
+ }
8877
+ if (Array.isArray(a) || Array.isArray(b)) {
8878
+ if (!Array.isArray(a) || !Array.isArray(b) || a.length !== b.length) {
8879
+ return false;
8880
+ }
8881
+ for (let i = 0; i < a.length; i++) {
8882
+ if (!isJsonEq(a[i], b[i])) {
8883
+ return false;
8926
8884
  }
8927
- result.push({
8928
- type: "format",
8929
- index: offset,
8930
- length: segment.text.length,
8931
- attributes
8932
- });
8933
8885
  }
8934
- offset = end;
8886
+ return true;
8935
8887
  }
8936
- return result;
8937
- }
8938
- function mapIndexThroughOperation(index, op) {
8939
- if (op.type === "insert") {
8940
- return op.index <= index ? index + op.text.length : index;
8941
- } else if (op.type === "delete") {
8942
- if (op.index >= index) {
8943
- return index;
8888
+ const aKeys = Object.keys(a);
8889
+ if (aKeys.length !== Object.keys(b).length) {
8890
+ return false;
8891
+ }
8892
+ for (const key of aKeys) {
8893
+ if (!isJsonEq(a[key], b[key])) {
8894
+ return false;
8944
8895
  }
8945
- return Math.max(op.index, index - op.length);
8946
- } else {
8947
- return index;
8948
8896
  }
8949
- }
8950
- function mapTextIndexThroughOperations(index, ops) {
8951
- let mapped = index;
8952
- for (const op of ops) {
8953
- mapped = mapIndexThroughOperation(mapped, op);
8954
- }
8955
- return mapped;
8956
- }
8957
- function inverseMapIndexThroughOperation(index, op) {
8958
- if (op.type === "insert") {
8959
- if (index <= op.index) {
8960
- return index;
8961
- }
8962
- return Math.max(op.index, index - op.text.length);
8963
- } else if (op.type === "delete") {
8964
- return op.index <= index ? index + op.length : index;
8965
- } else {
8966
- return index;
8967
- }
8968
- }
8969
- function inverseMapTextIndexThroughOperations(index, ops) {
8970
- let mapped = index;
8971
- for (let i = ops.length - 1; i >= 0; i--) {
8972
- mapped = inverseMapIndexThroughOperation(mapped, ops[i]);
8973
- }
8974
- return mapped;
8975
- }
8976
- function oppositeOrder(order) {
8977
- return order === "before" ? "after" : "before";
8978
- }
8979
- function mapIndexOverDelete(index, deleteIndex, deleteLength) {
8980
- if (deleteIndex >= index) {
8981
- return index;
8982
- }
8983
- return Math.max(deleteIndex, index - deleteLength);
8984
- }
8985
- function transformInsert(op, over, order) {
8986
- if (over.type === "insert") {
8987
- const shifts = over.index < op.index || over.index === op.index && order === "after";
8988
- return [shifts ? { ...op, index: op.index + over.text.length } : { ...op }];
8989
- } else if (over.type === "delete") {
8990
- return [
8991
- { ...op, index: mapIndexOverDelete(op.index, over.index, over.length) }
8992
- ];
8993
- } else {
8994
- return [{ ...op }];
8995
- }
8996
- }
8997
- function transformDelete(op, over) {
8998
- const start = op.index;
8999
- const end = op.index + op.length;
9000
- if (over.type === "insert") {
9001
- const at = over.index;
9002
- const len = over.text.length;
9003
- if (at <= start) {
9004
- return [{ ...op, index: start + len }];
9005
- }
9006
- if (at >= end) {
9007
- return [{ ...op }];
9008
- }
9009
- return [
9010
- { type: "delete", index: start, length: at - start },
9011
- { type: "delete", index: start + len, length: end - at }
9012
- ];
9013
- } else if (over.type === "delete") {
9014
- const newStart = mapIndexOverDelete(start, over.index, over.length);
9015
- const newEnd = mapIndexOverDelete(end, over.index, over.length);
9016
- return newEnd - newStart > 0 ? [{ type: "delete", index: newStart, length: newEnd - newStart }] : [];
9017
- } else {
9018
- return [{ ...op }];
9019
- }
9020
- }
9021
- function transformFormat(op, over, order) {
9022
- const start = op.index;
9023
- const end = op.index + op.length;
9024
- if (over.type === "insert") {
9025
- const at = over.index;
9026
- const len = over.text.length;
9027
- if (at <= start) {
9028
- return [{ ...op, index: start + len }];
9029
- }
9030
- if (at >= end) {
9031
- return [{ ...op }];
9032
- }
9033
- return [
9034
- {
9035
- type: "format",
9036
- index: start,
9037
- length: at - start,
9038
- attributes: op.attributes
9039
- },
9040
- {
9041
- type: "format",
9042
- index: at + len,
9043
- length: end - at,
9044
- attributes: op.attributes
9045
- }
9046
- ];
9047
- } else if (over.type === "delete") {
9048
- const newStart = mapIndexOverDelete(start, over.index, over.length);
9049
- const newEnd = mapIndexOverDelete(end, over.index, over.length);
9050
- return newEnd - newStart > 0 ? [
9051
- {
9052
- type: "format",
9053
- index: newStart,
9054
- length: newEnd - newStart,
9055
- attributes: op.attributes
9056
- }
9057
- ] : [];
9058
- } else {
9059
- if (order === "after") {
9060
- return [{ ...op }];
9061
- }
9062
- const overlapStart = Math.max(start, over.index);
9063
- const overlapEnd = Math.min(end, over.index + over.length);
9064
- if (overlapStart >= overlapEnd) {
9065
- return [{ ...op }];
9066
- }
9067
- const hasConflict = Object.keys(op.attributes).some(
9068
- (key) => key in over.attributes
9069
- );
9070
- if (!hasConflict) {
9071
- return [{ ...op }];
9072
- }
9073
- const reduced = {};
9074
- for (const [key, value] of Object.entries(op.attributes)) {
9075
- if (!(key in over.attributes)) {
9076
- reduced[key] = value;
9077
- }
9078
- }
9079
- const pieces = [];
9080
- if (start < overlapStart) {
9081
- pieces.push({
9082
- type: "format",
9083
- index: start,
9084
- length: overlapStart - start,
9085
- attributes: op.attributes
9086
- });
9087
- }
9088
- if (Object.keys(reduced).length > 0) {
9089
- pieces.push({
9090
- type: "format",
9091
- index: overlapStart,
9092
- length: overlapEnd - overlapStart,
9093
- attributes: reduced
9094
- });
9095
- }
9096
- if (overlapEnd < end) {
9097
- pieces.push({
9098
- type: "format",
9099
- index: overlapEnd,
9100
- length: end - overlapEnd,
9101
- attributes: op.attributes
9102
- });
9103
- }
9104
- return pieces;
9105
- }
9106
- }
9107
- function transformSingle(op, over, order) {
9108
- switch (op.type) {
9109
- case "insert":
9110
- return transformInsert(op, over, order);
9111
- case "delete":
9112
- return transformDelete(op, over);
9113
- case "format":
9114
- return transformFormat(op, over, order);
9115
- }
9116
- }
9117
- function transformTextOperationsX(a, b, order) {
9118
- if (a.length === 0 || b.length === 0) {
9119
- return [[...a], [...b]];
9120
- }
9121
- if (a.length === 1 && b.length === 1) {
9122
- return [
9123
- transformSingle(a[0], b[0], order),
9124
- transformSingle(b[0], a[0], oppositeOrder(order))
9125
- ];
9126
- }
9127
- if (a.length > 1) {
9128
- const [headA1, b1] = transformTextOperationsX([a[0]], b, order);
9129
- const [restA1, b2] = transformTextOperationsX(a.slice(1), b1, order);
9130
- return [[...headA1, ...restA1], b2];
9131
- }
9132
- const [a1, headB1] = transformTextOperationsX(a, [b[0]], order);
9133
- const [a2, restB1] = transformTextOperationsX(a1, b.slice(1), order);
9134
- return [a2, [...headB1, ...restB1]];
9135
- }
9136
- function transformTextOperations(ops, over, order) {
9137
- return transformTextOperationsX(ops, over, order)[0];
9138
- }
9139
- function textOperationsEqual(a, b) {
9140
- return a === b || stableStringify(a) === stableStringify(b);
9141
- }
9142
- function applyTextOperationsToSegments(segments, ops) {
9143
- let next = [...segments];
9144
- for (const op of ops) {
9145
- if (op.type === "insert") {
9146
- const index = Math.max(0, Math.min(op.index, textLength(next)));
9147
- next = applyInsert(next, index, op.text, op.attributes);
9148
- } else if (op.type === "delete") {
9149
- const index = Math.max(0, Math.min(op.index, textLength(next)));
9150
- const clipped = clipRange(index, op.length, textLength(next));
9151
- next = applyDelete(next, clipped.index, clipped.length).segments;
9152
- } else {
9153
- const index = Math.max(0, Math.min(op.index, textLength(next)));
9154
- const clipped = clipRange(index, op.length, textLength(next));
9155
- next = applyFormat(next, clipped.index, clipped.length, op.attributes);
9156
- }
9157
- }
9158
- return next;
9159
- }
9160
- function applyLiveTextOperations(data, ops) {
9161
- return segmentsToData(
9162
- applyTextOperationsToSegments(dataToSegments(data), ops)
9163
- );
9164
- }
9165
- function invertTextOperations(segments, ops) {
9166
- let shadow = [...segments];
9167
- const reverse = [];
9168
- for (const op of ops) {
9169
- if (op.type === "insert") {
9170
- shadow = applyInsert(shadow, op.index, op.text, op.attributes);
9171
- reverse.unshift({
9172
- type: "delete",
9173
- index: op.index,
9174
- length: op.text.length
9175
- });
9176
- } else if (op.type === "delete") {
9177
- const deletedSegments = extractDeletedSegments(
9178
- shadow,
9179
- op.index,
9180
- op.length
9181
- );
9182
- shadow = applyDelete(shadow, op.index, op.length).segments;
9183
- const inserts = [];
9184
- let insertIndex = op.index;
9185
- for (const segment of deletedSegments) {
9186
- inserts.push({
9187
- type: "insert",
9188
- index: insertIndex,
9189
- text: segment.text,
9190
- attributes: segment.attributes
9191
- });
9192
- insertIndex += segment.text.length;
9193
- }
9194
- for (let index = inserts.length - 1; index >= 0; index--) {
9195
- reverse.unshift(inserts[index]);
9196
- }
9197
- } else {
9198
- const inverse = formatReverseOperations(
9199
- shadow,
9200
- op.index,
9201
- op.length,
9202
- op.attributes
9203
- );
9204
- shadow = applyFormat(shadow, op.index, op.length, op.attributes);
9205
- reverse.unshift(...inverse.reverse());
9206
- }
9207
- }
9208
- return reverse;
9209
- }
9210
-
9211
- // src/crdts/LiveText.ts
9212
- var ACCEPTED_OPS_HISTORY_LIMIT = 1e3;
9213
- var LiveText = class _LiveText extends AbstractCrdt {
9214
- /** The local document: #confirmed ⊕ #inFlightOps ⊕ #queuedOps. */
9215
- #segments;
9216
- /** The server-confirmed document (only authoritative ops applied). */
9217
- #confirmed;
9218
- #version;
9219
- /** The op currently awaiting server acknowledgement (at most one). */
9220
- #inFlightOpId;
9221
- /** Its ops, continuously re-expressed against current server state. */
9222
- #inFlightOps = [];
9223
- /** Local edits made while an op is in flight; sent after the ack. */
9224
- #queuedOps = [];
9225
- #acceptedOps = [];
9226
- /**
9227
- * Creates a new LiveText document.
9228
- *
9229
- * @param textOrData Initial plain text, or an array of `[text]` /
9230
- * `[text, attributes]` segments. Defaults to an empty document.
9231
- *
9232
- * @example
9233
- * new LiveText();
9234
- * new LiveText("Hello world");
9235
- * new LiveText([["Hello ", { bold: true }], ["world"]]);
9236
- */
9237
- constructor(textOrData = "", version = 0) {
9238
- super();
9239
- this.#segments = typeof textOrData === "string" ? textOrData.length === 0 ? [] : [{ text: textOrData }] : dataToSegments(textOrData);
9240
- this.#confirmed = [...this.#segments];
9241
- this.#version = version;
9242
- Object.defineProperty(this, kInternal, {
9243
- value: {
9244
- encodeIndex: (localIndex) => this.#encodeIndex(localIndex),
9245
- decodeIndex: (index, fromVersion) => this.#decodeIndex(index, fromVersion)
9246
- },
9247
- enumerable: false
9248
- });
9249
- }
9250
- get version() {
9251
- return this.#version;
9252
- }
9253
- get length() {
9254
- return textLength(this.#segments);
9255
- }
9256
- /** @internal */
9257
- static _deserialize([id, item], _parentToChildren, pool) {
9258
- const text = new _LiveText(item.data, item.version);
9259
- text._attach(id, pool);
9260
- return text;
9261
- }
9262
- /** @internal */
9263
- _toOps(parentId, parentKey) {
9264
- if (this._id === void 0) {
9265
- throw new Error("Cannot serialize LiveText if it is not attached");
9266
- }
9267
- return [
9268
- {
9269
- type: OpCode.CREATE_TEXT,
9270
- id: this._id,
9271
- parentId,
9272
- parentKey,
9273
- data: this.toJSON(),
9274
- version: this.#version
9275
- }
9276
- ];
9277
- }
9278
- /** @internal */
9279
- _serialize() {
9280
- if (this.parent.type !== "HasParent") {
9281
- throw new Error("Cannot serialize LiveText if parent is missing");
9282
- }
9283
- return {
9284
- type: CrdtType.TEXT,
9285
- parentId: nn(this.parent.node._id, "Parent node expected to have ID"),
9286
- parentKey: this.parent.key,
9287
- data: this.toJSON(),
9288
- version: this.#version
9289
- };
9290
- }
9291
- /** @internal */
9292
- _attachChild(_op) {
9293
- throw new Error("LiveText cannot contain child nodes");
9294
- }
9295
- /** @internal */
9296
- _detachChild(_crdt) {
9297
- throw new Error("LiveText cannot contain child nodes");
9298
- }
9299
- /** @internal */
9300
- _apply(op, isLocal) {
9301
- if (op.type !== OpCode.UPDATE_TEXT) {
9302
- return super._apply(op, isLocal);
9303
- }
9304
- if (isLocal) {
9305
- return this.#applyLocal(op);
9306
- }
9307
- if (op.opId !== void 0 && op.opId === this.#inFlightOpId) {
9308
- return this.#applyAck(op);
9309
- }
9310
- if (op.opId !== void 0 && this.#acceptedOps.some((entry) => entry.opId === op.opId)) {
9311
- this.#version = Math.max(this.#version, _nullishCoalesce(op.version, () => ( op.baseVersion + 1)));
9312
- return { modified: false };
9313
- }
9314
- return this.#applyRemote(op);
9315
- }
9316
- /**
9317
- * Inserts text at the given index.
9318
- *
9319
- * @param index Character index at which to insert. Values outside the
9320
- * document range are clipped.
9321
- * @param text Text to insert.
9322
- * @param attributes Optional inline attributes for the inserted text.
9323
- *
9324
- * @example
9325
- * const text = new LiveText("Hello");
9326
- * text.insert(5, " world");
9327
- * text.insert(0, "Say: ", { italic: true });
9328
- */
9329
- insert(index, text, attributes) {
9330
- const clippedIndex = Math.max(0, Math.min(index, this.length));
9331
- this.#dispatch([{ type: "insert", index: clippedIndex, text, attributes }]);
9332
- }
9333
- /**
9334
- * Deletes `length` characters starting at `index`.
9335
- *
9336
- * @example
9337
- * const text = new LiveText("Hello world");
9338
- * text.delete(5, 6); // "Hello"
9339
- */
9340
- delete(index, length) {
9341
- const clipped = clipRange(index, length, this.length);
9342
- if (clipped.length === 0) {
9343
- return;
9344
- }
9345
- this.#dispatch([
9346
- { type: "delete", index: clipped.index, length: clipped.length }
9347
- ]);
9348
- }
9349
- /**
9350
- * Replaces a range of text with new text.
9351
- *
9352
- * @example
9353
- * const text = new LiveText("Hello world");
9354
- * text.replace(0, 5, "Hi"); // "Hi world"
9355
- */
9356
- replace(index, length, text, attributes) {
9357
- const clipped = clipRange(index, length, this.length);
9358
- const ops = [];
9359
- if (clipped.length > 0) {
9360
- ops.push({
9361
- type: "delete",
9362
- index: clipped.index,
9363
- length: clipped.length
9364
- });
9365
- }
9366
- if (text.length > 0) {
9367
- ops.push({ type: "insert", index: clipped.index, text, attributes });
9368
- }
9369
- this.#dispatch(ops);
9370
- }
9371
- /**
9372
- * Encode a local-document index (an offset into this LiveText's current
9373
- * #segments, which CodeMirror or any consumer mirrors as its document)
9374
- * into server-confirmed coordinates suitable for broadcasting to peers via
9375
- * presence or any other side channel.
9376
- *
9377
- * The returned index is in this LiveText's current #confirmed coordinates
9378
- * — that is, with this client's local pending ops inverse-mapped out.
9379
- * Pair it with the current {@link LiveText.version} when sending so the
9380
- * receiver can call {@link PrivateLiveTextApi.decodeIndex} to land the
9381
- * position in their own local document coordinates regardless of their
9382
- * private pending ops.
9383
- *
9384
- * Index ambiguity at boundaries is resolved by an inverse-of-forward
9385
- * convention: a position at or before a local insertion is reported as
9386
- * the position right before the insertion in #confirmed; a position past
9387
- * the insertion shifts left by the insertion's length. Positions inside
9388
- * an own-pending insertion collapse to the insertion point.
9389
- */
9390
- #encodeIndex(localIndex) {
9391
- let mapped = Math.max(0, Math.min(localIndex, this.length));
9392
- mapped = inverseMapTextIndexThroughOperations(mapped, this.#queuedOps);
9393
- mapped = inverseMapTextIndexThroughOperations(mapped, this.#inFlightOps);
9394
- return mapped;
9395
- }
9396
- /**
9397
- * Decode an `(index, fromVersion)` pair produced by
9398
- * {@link PrivateLiveTextApi.encodeIndex} — typically on a peer — into an
9399
- * offset in this LiveText's current local document (an index suitable for
9400
- * placing a CodeMirror marker, an annotation anchor, or anything else that
9401
- * lives over #segments).
9402
- *
9403
- * Composes the accepted ops applied since `fromVersion` (drawn from
9404
- * #acceptedOps in locally-applied form) with this client's own local
9405
- * pending ops, in that order. The result is in current #segments
9406
- * coordinates.
9407
- *
9408
- * Returns `null` when the position cannot be decoded against the current
9409
- * state:
9410
- * - `fromVersion` is greater than this LiveText's current version: the
9411
- * peer is ahead of us. The caller should park the message and retry
9412
- * after more accepted ops arrive.
9413
- * - `fromVersion` falls outside the retained accepted-ops history. This
9414
- * only happens after very long-lived disconnections; the caller can
9415
- * fall back to using the raw index and letting subsequent local
9416
- * transactions map it (with bounded drift).
9417
- */
9418
- #decodeIndex(index, fromVersion) {
9419
- if (fromVersion > this.#version) {
9420
- return null;
9421
- }
9422
- if (fromVersion < this.#version) {
9423
- const oldest = _optionalChain([this, 'access', _216 => _216.#acceptedOps, 'access', _217 => _217[0], 'optionalAccess', _218 => _218.version]);
9424
- if (oldest === void 0 || oldest > fromVersion + 1) {
9425
- return null;
9426
- }
9427
- }
9428
- let mapped = index;
9429
- for (const entry of this.#acceptedOps) {
9430
- if (entry.version <= fromVersion) continue;
9431
- if (entry.version > this.#version) break;
9432
- if (entry.ops.length === 0) continue;
9433
- mapped = mapTextIndexThroughOperations(mapped, entry.ops);
9434
- }
9435
- mapped = mapTextIndexThroughOperations(mapped, this.#inFlightOps);
9436
- mapped = mapTextIndexThroughOperations(mapped, this.#queuedOps);
9437
- return Math.max(0, Math.min(mapped, this.length));
9438
- }
9439
- /**
9440
- * Applies or removes inline attributes on a range of text.
9441
- *
9442
- * Set an attribute to `null` to remove it from the range.
9443
- *
9444
- * @example
9445
- * const text = new LiveText("Hello world");
9446
- * text.format(0, 5, { bold: true });
9447
- * text.format(0, 5, { bold: null });
9448
- */
9449
- format(index, length, attributes) {
9450
- const clipped = clipRange(index, length, this.length);
9451
- if (clipped.length === 0) {
9452
- return;
9453
- }
9454
- this.#dispatch([
9455
- {
9456
- type: "format",
9457
- index: clipped.index,
9458
- length: clipped.length,
9459
- attributes
9460
- }
9461
- ]);
9462
- }
9463
- /** Local edits made through the public API. */
9464
- #dispatch(ops) {
9465
- if (ops.length === 0) {
9466
- return;
9467
- }
9468
- _optionalChain([this, 'access', _219 => _219._pool, 'optionalAccess', _220 => _220.assertStorageIsWritable, 'call', _221 => _221()]);
9469
- const attached = this._pool !== void 0 && this._id !== void 0;
9470
- const reverse = attached ? this.#invertOperations(ops) : [];
9471
- const changes = this.#applyOperationsLocally(ops);
9472
- if (!attached) {
9473
- return;
9474
- }
9475
- const pool = nn(this._pool);
9476
- const id = nn(this._id);
9477
- const updates = /* @__PURE__ */ new Map([
9478
- [
9479
- id,
9480
- {
9481
- type: "LiveText",
9482
- node: this,
9483
- version: this.#version,
9484
- updates: changes
9485
- }
9486
- ]
9487
- ]);
9488
- if (this.#inFlightOpId === void 0) {
9489
- const opId = pool.generateOpId();
9490
- this.#inFlightOpId = opId;
9491
- this.#inFlightOps = [...ops];
9492
- pool.dispatch(
9493
- [
9494
- {
9495
- type: OpCode.UPDATE_TEXT,
9496
- id,
9497
- opId,
9498
- baseVersion: this.#version,
9499
- ops: [...ops]
9500
- }
9501
- ],
9502
- reverse,
9503
- updates
9504
- );
9505
- } else {
9506
- this.#queuedOps.push(...ops);
9507
- pool.dispatch([], reverse, updates, { clearRedoStack: true });
9508
- }
9509
- }
9510
- /**
9511
- * A local replay of an existing wire op: an undo/redo frame, or an
9512
- * unacknowledged op re-sent after a reconnect.
9513
- */
9514
- #applyLocal(op) {
9515
- const mutableOp = op;
9516
- if (op.opId !== void 0 && op.opId === this.#inFlightOpId) {
9517
- this.#inFlightOps = [...this.#inFlightOps, ...this.#queuedOps];
9518
- this.#queuedOps = [];
9519
- mutableOp.baseVersion = this.#version;
9520
- mutableOp.ops = [...this.#inFlightOps];
9521
- return { modified: false };
9522
- }
9523
- let ops = op.ops;
9524
- for (const entry of this.#acceptedOps) {
9525
- if (entry.version > op.baseVersion && entry.ops.length > 0) {
9526
- ops = transformTextOperations(ops, entry.ops, "after");
9527
- }
9528
- }
9529
- const reverse = this.#invertOperations(ops);
9530
- const changes = this.#applyOperationsLocally(ops);
9531
- if (this.#inFlightOpId === void 0 && ops.length > 0) {
9532
- this.#inFlightOpId = nn(op.opId, "Local ops must have an opId");
9533
- this.#inFlightOps = [...ops];
9534
- mutableOp.baseVersion = this.#version;
9535
- mutableOp.ops = [...ops];
9536
- } else {
9537
- this.#queuedOps.push(...ops);
9538
- mutableOp.baseVersion = this.#version;
9539
- mutableOp.ops = [];
9540
- }
9541
- if (changes.length === 0) {
9542
- return { modified: false };
9543
- }
9544
- return {
9545
- reverse,
9546
- modified: {
9547
- type: "LiveText",
9548
- node: this,
9549
- version: this.#version,
9550
- updates: changes
9551
- }
9552
- };
9553
- }
9554
- /** Server acknowledgement of our in-flight op. */
9555
- #applyAck(op) {
9556
- const ackedVersion = _nullishCoalesce(op.version, () => ( Math.max(this.#version, op.baseVersion + 1)));
9557
- const predicted = this.#inFlightOps;
9558
- const opId = this.#inFlightOpId;
9559
- this.#confirmed = applyTextOperationsToSegments(this.#confirmed, op.ops);
9560
- this.#inFlightOpId = void 0;
9561
- this.#inFlightOps = [];
9562
- let appliedOps = [];
9563
- let result = { modified: false };
9564
- if (!textOperationsEqual(op.ops, predicted)) {
9565
- error2(
9566
- "LiveText: acknowledgement did not match the local prediction; resynchronizing"
9567
- );
9568
- const rebuilt = this.#rebuildLocalFromConfirmed();
9569
- appliedOps = rebuilt.appliedOps;
9570
- if (rebuilt.changes.length > 0) {
9571
- result = {
9572
- reverse: [],
9573
- modified: {
9574
- type: "LiveText",
9575
- node: this,
9576
- version: ackedVersion,
9577
- updates: rebuilt.changes
9578
- }
9579
- };
9580
- }
9581
- }
9582
- this.#version = Math.max(this.#version, ackedVersion);
9583
- this.#recordAccepted(ackedVersion, appliedOps, opId);
9584
- this.#flushQueued();
9585
- return result;
9586
- }
9587
- /** An accepted op from another client (or a server-fabricated fix op). */
9588
- #applyRemote(op) {
9589
- const version = _nullishCoalesce(op.version, () => ( this.#version + 1));
9590
- this.#confirmed = applyTextOperationsToSegments(this.#confirmed, op.ops);
9591
- const [overInFlight, inFlight] = transformTextOperationsX(
9592
- op.ops,
9593
- this.#inFlightOps,
9594
- "before"
9595
- );
9596
- const [applied, queued] = transformTextOperationsX(
9597
- overInFlight,
9598
- this.#queuedOps,
9599
- "before"
9600
- );
9601
- this.#inFlightOps = inFlight;
9602
- this.#queuedOps = queued;
9603
- this.#recordAccepted(version, applied, op.opId);
9604
- if (applied.length === 0) {
9605
- this.#version = Math.max(this.#version, version);
9606
- return { modified: false };
9607
- }
9608
- const reverse = this.#invertOperations(applied);
9609
- const changes = this.#applyOperationsLocally(applied);
9610
- this.#version = Math.max(this.#version, version);
9611
- return {
9612
- reverse,
9613
- modified: {
9614
- type: "LiveText",
9615
- node: this,
9616
- version: this.#version,
9617
- updates: changes
9618
- }
9619
- };
9620
- }
9621
- /** Send the queued ops as the next in-flight op (after an ack). */
9622
- #flushQueued() {
9623
- if (this.#queuedOps.length === 0 || this._pool === void 0 || this._id === void 0) {
9624
- return;
9625
- }
9626
- const opId = this._pool.generateOpId();
9627
- this.#inFlightOpId = opId;
9628
- this.#inFlightOps = this.#queuedOps;
9629
- this.#queuedOps = [];
9630
- this._pool.dispatch(
9631
- [
9632
- {
9633
- type: OpCode.UPDATE_TEXT,
9634
- id: this._id,
9635
- opId,
9636
- baseVersion: this.#version,
9637
- ops: [...this.#inFlightOps]
9638
- }
9639
- ],
9640
- [],
9641
- /* @__PURE__ */ new Map(),
9642
- // The local content was already applied (and made undoable) when the
9643
- // edits happened; this is purely an outbound flush.
9644
- { clearRedoStack: false }
9645
- );
9646
- }
9647
- /**
9648
- * Rebuild the local document as confirmed ⊕ queued ops, returning the
9649
- * coarse delta that was applied. Only used by defensive recovery paths.
9650
- */
9651
- #rebuildLocalFromConfirmed() {
9652
- const before2 = this.#segments;
9653
- const after2 = applyTextOperationsToSegments(this.#confirmed, [
9654
- ...this.#inFlightOps,
9655
- ...this.#queuedOps
9656
- ]);
9657
- if (stableStringify(segmentsToData(before2)) === stableStringify(segmentsToData(after2))) {
9658
- this.#segments = after2;
9659
- return { appliedOps: [], changes: [] };
9660
- }
9661
- const beforeText = before2.map((segment) => segment.text).join("");
9662
- this.#segments = after2;
9663
- this.invalidate();
9664
- const appliedOps = [];
9665
- const changes = [];
9666
- if (beforeText.length > 0) {
9667
- appliedOps.push({ type: "delete", index: 0, length: beforeText.length });
9668
- changes.push({
9669
- type: "delete",
9670
- index: 0,
9671
- length: beforeText.length,
9672
- deletedText: beforeText
9673
- });
9674
- }
9675
- let index = 0;
9676
- for (const segment of after2) {
9677
- appliedOps.push({
9678
- type: "insert",
9679
- index,
9680
- text: segment.text,
9681
- attributes: segment.attributes
9682
- });
9683
- changes.push({
9684
- type: "insert",
9685
- index,
9686
- text: segment.text,
9687
- attributes: segment.attributes
9688
- });
9689
- index += segment.text.length;
9690
- }
9691
- return { appliedOps, changes };
9692
- }
9693
- /**
9694
- * Reconcile this node against an authoritative storage snapshot (e.g.
9695
- * after a reconnect). The confirmed state and version are replaced by the
9696
- * snapshot's; pending (in-flight + queued) ops are preserved on top and
9697
- * will be re-sent by the offline-ops replay.
9698
- *
9699
- * @internal
9700
- */
9701
- _resyncText(data, version) {
9702
- this.#confirmed = dataToSegments(data);
9703
- this.#version = version;
9704
- this.#acceptedOps = [];
9705
- const rebuilt = this.#rebuildLocalFromConfirmed();
9706
- if (rebuilt.changes.length === 0) {
9707
- return void 0;
9708
- }
9709
- return {
9710
- type: "LiveText",
9711
- node: this,
9712
- version: this.#version,
9713
- updates: rebuilt.changes
9714
- };
9715
- }
9716
- /**
9717
- * Called when the server rejected one of our ops. Drops all pending state
9718
- * for this node (edits queued behind a rejected op cannot be trusted
9719
- * either); the room follows up with a storage resync.
9720
- *
9721
- * @internal
9722
- */
9723
- _rejectPendingOp(opId) {
9724
- if (opId !== this.#inFlightOpId) {
9725
- return;
9726
- }
9727
- this.#inFlightOpId = void 0;
9728
- this.#inFlightOps = [];
9729
- this.#queuedOps = [];
9730
- }
9731
- #recordAccepted(version, ops, opId) {
9732
- if (this.#acceptedOps.some((entry) => entry.version === version)) {
9733
- return;
9734
- }
9735
- this.#acceptedOps.push({ version, opId, ops: [...ops] });
9736
- this.#acceptedOps.sort((left, right) => left.version - right.version);
9737
- if (this.#acceptedOps.length > ACCEPTED_OPS_HISTORY_LIMIT) {
9738
- this.#acceptedOps.splice(
9739
- 0,
9740
- this.#acceptedOps.length - ACCEPTED_OPS_HISTORY_LIMIT
9741
- );
9742
- }
9743
- }
9744
- #applyOperationsLocally(ops) {
9745
- const changes = [];
9746
- for (const op of ops) {
9747
- if (op.type === "insert") {
9748
- this.#segments = applyInsert(
9749
- this.#segments,
9750
- op.index,
9751
- op.text,
9752
- op.attributes
9753
- );
9754
- changes.push({
9755
- type: "insert",
9756
- index: op.index,
9757
- text: op.text,
9758
- attributes: op.attributes
9759
- });
9760
- } else if (op.type === "delete") {
9761
- const result = applyDelete(this.#segments, op.index, op.length);
9762
- this.#segments = result.segments;
9763
- changes.push({
9764
- type: "delete",
9765
- index: op.index,
9766
- length: op.length,
9767
- deletedText: result.deletedText
9768
- });
9769
- } else {
9770
- this.#segments = applyFormat(
9771
- this.#segments,
9772
- op.index,
9773
- op.length,
9774
- op.attributes
9775
- );
9776
- changes.push({
9777
- type: "format",
9778
- index: op.index,
9779
- length: op.length,
9780
- attributes: op.attributes
9781
- });
9782
- }
9783
- }
9784
- this.invalidate();
9785
- return changes;
9786
- }
9787
- #invertOperations(ops) {
9788
- return [
9789
- {
9790
- type: OpCode.UPDATE_TEXT,
9791
- id: nn(this._id),
9792
- baseVersion: this.#version,
9793
- ops: invertTextOperations(this.#segments, ops)
9794
- }
9795
- ];
9796
- }
9797
- /** Returns the plain text content without attributes. Equivalent to joining the text from each segment in {@link LiveText.toJSON}. */
9798
- toString() {
9799
- return this.#segments.map((segment) => segment.text).join("");
9800
- }
9801
- /**
9802
- * Returns a JSON-compatible snapshot of the document as a {@link LiveTextData}
9803
- * array.
9804
- *
9805
- * @example
9806
- * new LiveText([["Hello ", { bold: true }], ["world"]]).toJSON();
9807
- * // [["Hello ", { bold: true }], ["world"]]
9808
- */
9809
- toJSON() {
9810
- return super.toJSON();
9811
- }
9812
- /** @internal */
9813
- _toJSON() {
9814
- return segmentsToData(this.#segments);
9815
- }
9816
- /** @internal */
9817
- toTreeNode(key) {
9818
- return super.toTreeNode(key);
9819
- }
9820
- /** @internal */
9821
- _toTreeNode(key) {
9822
- const nodeId = _nullishCoalesce(this._id, () => ( nanoid()));
9823
- const payload = this.toJSON().map(
9824
- (segment, index) => ({
9825
- type: "Json",
9826
- id: `${nodeId}:${index}`,
9827
- key: String(index),
9828
- payload: segment
9829
- })
9830
- );
9831
- payload.push({
9832
- type: "Json",
9833
- id: `${nodeId}:version`,
9834
- key: "version",
9835
- payload: this.version
9836
- });
9837
- return {
9838
- type: "LiveText",
9839
- id: nodeId,
9840
- key,
9841
- payload
9842
- };
9843
- }
9844
- clone() {
9845
- return new _LiveText(this.toJSON(), this.#version);
9846
- }
9847
- };
9848
-
9849
- // src/crdts/liveblocks-helpers.ts
9850
- function creationOpToLiveNode(op) {
9851
- return lsonToLiveNode(creationOpToLson(op));
9852
- }
9853
- function creationOpToLson(op) {
9854
- switch (op.type) {
9855
- case OpCode.CREATE_REGISTER:
9856
- return op.data;
9857
- case OpCode.CREATE_OBJECT:
9858
- return new LiveObject(op.data);
9859
- case OpCode.CREATE_MAP:
9860
- return new LiveMap();
9861
- case OpCode.CREATE_LIST:
9862
- return new LiveList([]);
9863
- case OpCode.CREATE_TEXT:
9864
- return new LiveText(op.data, op.version);
9865
- default:
9866
- return assertNever(op, "Unknown creation Op");
9867
- }
9868
- }
9869
- function isSameNodeOrChildOf(node, parent) {
9870
- if (node === parent) {
9871
- return true;
9872
- }
9873
- if (node.parent.type === "HasParent") {
9874
- return isSameNodeOrChildOf(node.parent.node, parent);
9875
- }
9876
- return false;
9877
- }
9878
- function deserialize(node, parentToChildren, pool) {
9879
- if (isObjectStorageNode(node)) {
9880
- return LiveObject._deserialize(node, parentToChildren, pool);
9881
- } else if (isListStorageNode(node)) {
9882
- return LiveList._deserialize(node, parentToChildren, pool);
9883
- } else if (isMapStorageNode(node)) {
9884
- return LiveMap._deserialize(node, parentToChildren, pool);
9885
- } else if (isRegisterStorageNode(node)) {
9886
- return LiveRegister._deserialize(node, parentToChildren, pool);
9887
- } else if (isTextStorageNode(node)) {
9888
- return LiveText._deserialize(node, parentToChildren, pool);
9889
- } else {
9890
- throw new Error("Unexpected CRDT type");
9891
- }
9892
- }
9893
- function deserializeToLson(node, parentToChildren, pool) {
9894
- if (isObjectStorageNode(node)) {
9895
- return LiveObject._deserialize(node, parentToChildren, pool);
9896
- } else if (isListStorageNode(node)) {
9897
- return LiveList._deserialize(node, parentToChildren, pool);
9898
- } else if (isMapStorageNode(node)) {
9899
- return LiveMap._deserialize(node, parentToChildren, pool);
9900
- } else if (isRegisterStorageNode(node)) {
9901
- return node[1].data;
9902
- } else if (isTextStorageNode(node)) {
9903
- return LiveText._deserialize(node, parentToChildren, pool);
9904
- } else {
9905
- throw new Error("Unexpected CRDT type");
9906
- }
9907
- }
9908
- function isLiveStructure(value) {
9909
- return isLiveList(value) || isLiveMap(value) || isLiveObject(value) || isLiveText(value);
9910
- }
9911
- function isLiveNode(value) {
9912
- return isLiveStructure(value) || isLiveRegister(value);
9913
- }
9914
- function isLiveList(value) {
9915
- return value instanceof LiveList;
9916
- }
9917
- function isLiveMap(value) {
9918
- return value instanceof LiveMap;
9919
- }
9920
- function isLiveObject(value) {
9921
- return value instanceof LiveObject;
9922
- }
9923
- function isLiveText(value) {
9924
- return value instanceof LiveText;
9925
- }
9926
- function isLiveRegister(value) {
9927
- return value instanceof LiveRegister;
9928
- }
9929
- function cloneLson(value) {
9930
- return value === void 0 ? void 0 : isLiveStructure(value) ? value.clone() : deepClone(value);
9931
- }
9932
- function liveNodeToLson(obj) {
9933
- if (obj instanceof LiveRegister) {
9934
- return obj.data;
9935
- } else if (obj instanceof LiveList || obj instanceof LiveMap || obj instanceof LiveObject || obj instanceof LiveText) {
9936
- return obj;
9937
- } else {
9938
- return assertNever(obj, "Unknown AbstractCrdt");
9939
- }
9940
- }
9941
- function lsonToLiveNode(value) {
9942
- if (value instanceof LiveObject || value instanceof LiveMap || value instanceof LiveList || value instanceof LiveText) {
9943
- return value;
9944
- } else {
9945
- return new LiveRegister(value);
9946
- }
9947
- }
9948
- function dumpPool(pool) {
9949
- const rows = Array.from(pool.nodes.values(), (node) => {
9950
- const parent = node.parent;
9951
- const parentId = parent.type === "HasParent" ? _nullishCoalesce(parent.node._id, () => ( "?")) : parent.type === "Orphaned" ? "<orphaned>" : "-";
9952
- let value;
9953
- if (node instanceof LiveRegister) {
9954
- value = stringifyOrLog(node.data);
9955
- } else if (node instanceof LiveList) {
9956
- value = "<LiveList>";
9957
- } else if (node instanceof LiveMap) {
9958
- value = "<LiveMap>";
9959
- } else {
9960
- value = "<LiveObject>";
9961
- }
9962
- return { id: nn(node._id), parentId, key: _nullishCoalesce(node._parentKey, () => ( "")), value };
9963
- });
9964
- rows.sort((a, b) => {
9965
- if (a.parentId !== b.parentId) return a.parentId < b.parentId ? -1 : 1;
9966
- if (a.key !== b.key) return a.key < b.key ? -1 : 1;
9967
- return 0;
9968
- });
9969
- return rows.map(
9970
- (r) => ` ${r.id} parent=${r.parentId} key=${r.key || "\u2014"} ${r.value}`
9971
- ).join("\n");
9972
- }
9973
- function isJsonEq(a, b) {
9974
- if (a === b) {
9975
- return true;
9976
- }
9977
- if (typeof a !== "object" || a === null || typeof b !== "object" || b === null) {
9978
- return false;
9979
- }
9980
- if (Array.isArray(a) || Array.isArray(b)) {
9981
- if (!Array.isArray(a) || !Array.isArray(b) || a.length !== b.length) {
9982
- return false;
9983
- }
9984
- for (let i = 0; i < a.length; i++) {
9985
- if (!isJsonEq(a[i], b[i])) {
9986
- return false;
9987
- }
9988
- }
9989
- return true;
9990
- }
9991
- const aKeys = Object.keys(a);
9992
- if (aKeys.length !== Object.keys(b).length) {
9993
- return false;
9994
- }
9995
- for (const key of aKeys) {
9996
- if (!isJsonEq(a[key], b[key])) {
9997
- return false;
9998
- }
9999
- }
10000
- return true;
8897
+ return true;
10001
8898
  }
10002
8899
  function diffNodeMap(prev, next) {
10003
8900
  const ops = [];
@@ -10082,16 +8979,6 @@ function diffNodeMap(prev, next) {
10082
8979
  parentKey: crdt.parentKey
10083
8980
  });
10084
8981
  break;
10085
- case CrdtType.TEXT:
10086
- ops.push({
10087
- type: OpCode.CREATE_TEXT,
10088
- id,
10089
- parentId: crdt.parentId,
10090
- parentKey: crdt.parentKey,
10091
- data: crdt.data,
10092
- version: crdt.version
10093
- });
10094
- break;
10095
8982
  }
10096
8983
  }
10097
8984
  });
@@ -10124,43 +9011,19 @@ function mergeListStorageUpdates(first, second) {
10124
9011
  updates: updates.concat(second.updates)
10125
9012
  };
10126
9013
  }
10127
- function mergeTextStorageUpdates(first, second) {
10128
- return {
10129
- ...second,
10130
- updates: first.updates.concat(second.updates)
10131
- };
10132
- }
10133
9014
  function mergeStorageUpdates(first, second) {
10134
9015
  if (first === void 0) {
10135
9016
  return second;
10136
9017
  }
10137
- let merged;
10138
9018
  if (first.type === "LiveObject" && second.type === "LiveObject") {
10139
- merged = mergeObjectStorageUpdates(first, second);
9019
+ return mergeObjectStorageUpdates(first, second);
10140
9020
  } else if (first.type === "LiveMap" && second.type === "LiveMap") {
10141
- merged = mergeMapStorageUpdates(first, second);
9021
+ return mergeMapStorageUpdates(first, second);
10142
9022
  } else if (first.type === "LiveList" && second.type === "LiveList") {
10143
- merged = mergeListStorageUpdates(first, second);
10144
- } else if (first.type === "LiveText" && second.type === "LiveText") {
10145
- merged = mergeTextStorageUpdates(first, second);
9023
+ return mergeListStorageUpdates(first, second);
10146
9024
  } else {
10147
- merged = second;
10148
- }
10149
- const sa = first[kStorageUpdateSource];
10150
- const sb = second[kStorageUpdateSource];
10151
- if (sa !== void 0 || sb !== void 0) {
10152
- if (_optionalChain([sa, 'optionalAccess', _222 => _222.origin]) === "remote" || _optionalChain([sb, 'optionalAccess', _223 => _223.origin]) === "remote") {
10153
- merged[kStorageUpdateSource] = { origin: "remote" };
10154
- } else if (_optionalChain([sa, 'optionalAccess', _224 => _224.via]) === "history" || _optionalChain([sb, 'optionalAccess', _225 => _225.via]) === "history") {
10155
- const historySource = _optionalChain([sb, 'optionalAccess', _226 => _226.via]) === "history" ? sb : _optionalChain([sa, 'optionalAccess', _227 => _227.via]) === "history" ? sa : void 0;
10156
- if (_optionalChain([historySource, 'optionalAccess', _228 => _228.via]) === "history") {
10157
- merged[kStorageUpdateSource] = historySource;
10158
- }
10159
- } else {
10160
- merged[kStorageUpdateSource] = { origin: "local", via: "mutation" };
10161
- }
10162
9025
  }
10163
- return merged;
9026
+ return second;
10164
9027
  }
10165
9028
 
10166
9029
  // src/devtools/bridge.ts
@@ -10176,7 +9039,7 @@ function sendToPanel(message, options) {
10176
9039
  ...message,
10177
9040
  source: "liveblocks-devtools-client"
10178
9041
  };
10179
- if (!(_optionalChain([options, 'optionalAccess', _229 => _229.force]) || _bridgeActive)) {
9042
+ if (!(_optionalChain([options, 'optionalAccess', _217 => _217.force]) || _bridgeActive)) {
10180
9043
  return;
10181
9044
  }
10182
9045
  window.postMessage(fullMsg, "*");
@@ -10184,7 +9047,7 @@ function sendToPanel(message, options) {
10184
9047
  var eventSource = makeEventSource();
10185
9048
  if (process.env.NODE_ENV !== "production" && typeof window !== "undefined") {
10186
9049
  window.addEventListener("message", (event) => {
10187
- if (event.source === window && _optionalChain([event, 'access', _230 => _230.data, 'optionalAccess', _231 => _231.source]) === "liveblocks-devtools-panel") {
9050
+ if (event.source === window && _optionalChain([event, 'access', _218 => _218.data, 'optionalAccess', _219 => _219.source]) === "liveblocks-devtools-panel") {
10188
9051
  eventSource.notify(event.data);
10189
9052
  } else {
10190
9053
  }
@@ -10326,7 +9189,7 @@ function fullSync(room) {
10326
9189
  msg: "room::sync::full",
10327
9190
  roomId: room.id,
10328
9191
  status: room.getStatus(),
10329
- storage: _nullishCoalesce(_optionalChain([root, 'optionalAccess', _232 => _232.toTreeNode, 'call', _233 => _233("root"), 'access', _234 => _234.payload]), () => ( null)),
9192
+ storage: _nullishCoalesce(_optionalChain([root, 'optionalAccess', _220 => _220.toTreeNode, 'call', _221 => _221("root"), 'access', _222 => _222.payload]), () => ( null)),
10330
9193
  me,
10331
9194
  others
10332
9195
  });
@@ -11013,15 +9876,15 @@ function installBackgroundTabSpy() {
11013
9876
  const doc = typeof document !== "undefined" ? document : void 0;
11014
9877
  const inBackgroundSince = { current: null };
11015
9878
  function onVisibilityChange() {
11016
- if (_optionalChain([doc, 'optionalAccess', _235 => _235.visibilityState]) === "hidden") {
9879
+ if (_optionalChain([doc, 'optionalAccess', _223 => _223.visibilityState]) === "hidden") {
11017
9880
  inBackgroundSince.current = _nullishCoalesce(inBackgroundSince.current, () => ( Date.now()));
11018
9881
  } else {
11019
9882
  inBackgroundSince.current = null;
11020
9883
  }
11021
9884
  }
11022
- _optionalChain([doc, 'optionalAccess', _236 => _236.addEventListener, 'call', _237 => _237("visibilitychange", onVisibilityChange)]);
9885
+ _optionalChain([doc, 'optionalAccess', _224 => _224.addEventListener, 'call', _225 => _225("visibilitychange", onVisibilityChange)]);
11023
9886
  const unsub = () => {
11024
- _optionalChain([doc, 'optionalAccess', _238 => _238.removeEventListener, 'call', _239 => _239("visibilitychange", onVisibilityChange)]);
9887
+ _optionalChain([doc, 'optionalAccess', _226 => _226.removeEventListener, 'call', _227 => _227("visibilitychange", onVisibilityChange)]);
11025
9888
  };
11026
9889
  return [inBackgroundSince, unsub];
11027
9890
  }
@@ -11104,8 +9967,6 @@ function createRoom(options, config) {
11104
9967
  activeBatch: null,
11105
9968
  unacknowledgedOps
11106
9969
  };
11107
- let nextHistoryItemId = 0;
11108
- let historyDisabled = 0;
11109
9970
  const nodeMapBuffer = makeNodeMapBuffer();
11110
9971
  const stopwatch = config.enableDebugLogging ? makeStopWatch() : void 0;
11111
9972
  let lastTokenKey;
@@ -11190,10 +10051,7 @@ function createRoom(options, config) {
11190
10051
  }
11191
10052
  }
11192
10053
  });
11193
- function onDispatch(ops, reverse, storageUpdates, options2) {
11194
- for (const value of storageUpdates.values()) {
11195
- value[kStorageUpdateSource] = { origin: "local", via: "mutation" };
11196
- }
10054
+ function onDispatch(ops, reverse, storageUpdates) {
11197
10055
  if (context.activeBatch) {
11198
10056
  for (const op of ops) {
11199
10057
  context.activeBatch.ops.push(op);
@@ -11212,17 +10070,15 @@ function createRoom(options, config) {
11212
10070
  if (reverse.length > 0) {
11213
10071
  addToUndoStack(reverse);
11214
10072
  }
11215
- if (_nullishCoalesce(_optionalChain([options2, 'optionalAccess', _240 => _240.clearRedoStack]), () => ( ops.length > 0))) {
11216
- clearRedoStack();
11217
- }
11218
10073
  if (ops.length > 0) {
10074
+ context.redoStack.length = 0;
11219
10075
  dispatchOps(ops);
11220
10076
  }
11221
10077
  notify({ storageUpdates });
11222
10078
  }
11223
10079
  }
11224
10080
  function isStorageWritable() {
11225
- const permissionMatrix = _optionalChain([context, 'access', _241 => _241.dynamicSessionInfoSig, 'access', _242 => _242.get, 'call', _243 => _243(), 'optionalAccess', _244 => _244.permissionMatrix]);
10081
+ const permissionMatrix = _optionalChain([context, 'access', _228 => _228.dynamicSessionInfoSig, 'access', _229 => _229.get, 'call', _230 => _230(), 'optionalAccess', _231 => _231.permissionMatrix]);
11226
10082
  return permissionMatrix !== void 0 ? hasPermissionAccess(permissionMatrix, "storage", "write") : true;
11227
10083
  }
11228
10084
  const eventHub = {
@@ -11235,7 +10091,6 @@ function createRoom(options, config) {
11235
10091
  others: makeEventSource(),
11236
10092
  storageBatch: makeEventSource(),
11237
10093
  history: makeEventSource(),
11238
- privateHistory: makeEventSource(),
11239
10094
  storageDidLoad: makeEventSource(),
11240
10095
  storageStatus: makeEventSource(),
11241
10096
  ydoc: makeEventSource(),
@@ -11328,23 +10183,6 @@ function createRoom(options, config) {
11328
10183
  }
11329
10184
  const ops = diffNodeMap(currentItems, nodes);
11330
10185
  const result = applyRemoteOps(ops);
11331
- for (const [id, crdt] of nodes) {
11332
- if (crdt.type === CrdtType.TEXT) {
11333
- const node = context.pool.nodes.get(id);
11334
- if (node !== void 0 && isLiveText(node)) {
11335
- const update = node._resyncText(crdt.data, crdt.version);
11336
- if (update !== void 0) {
11337
- result.updates.storageUpdates.set(
11338
- id,
11339
- mergeStorageUpdates(
11340
- result.updates.storageUpdates.get(id),
11341
- update
11342
- )
11343
- );
11344
- }
11345
- }
11346
- }
11347
- }
11348
10186
  notify(result.updates);
11349
10187
  } else {
11350
10188
  context.root = LiveObject._fromItems(
@@ -11352,7 +10190,7 @@ function createRoom(options, config) {
11352
10190
  context.pool
11353
10191
  );
11354
10192
  }
11355
- const canWrite = _nullishCoalesce(_optionalChain([self, 'access', _245 => _245.get, 'call', _246 => _246(), 'optionalAccess', _247 => _247.canWrite]), () => ( true));
10193
+ const canWrite = _nullishCoalesce(_optionalChain([self, 'access', _232 => _232.get, 'call', _233 => _233(), 'optionalAccess', _234 => _234.canWrite]), () => ( true));
11356
10194
  const root = context.root;
11357
10195
  disableHistory(() => {
11358
10196
  for (const key in context.initialStorage) {
@@ -11368,26 +10206,11 @@ function createRoom(options, config) {
11368
10206
  }
11369
10207
  });
11370
10208
  }
11371
- function notifyPrivateHistory(event) {
11372
- if (historyDisabled > 0) return;
11373
- eventHub.privateHistory.notify(event);
11374
- }
11375
- function clearRedoStack() {
11376
- if (context.redoStack.length === 0) return;
11377
- const ids = context.redoStack.map((item) => item.id);
11378
- context.redoStack.length = 0;
11379
- notifyPrivateHistory({ action: "discard", ids });
11380
- }
11381
10209
  function _addToRealUndoStack(frames) {
11382
10210
  if (context.undoStack.length >= 50) {
11383
- const evicted = context.undoStack.shift();
11384
- if (evicted !== void 0) {
11385
- notifyPrivateHistory({ action: "discard", ids: [evicted.id] });
11386
- }
10211
+ context.undoStack.shift();
11387
10212
  }
11388
- const id = nextHistoryItemId++;
11389
- context.undoStack.push({ id, frames });
11390
- notifyPrivateHistory({ action: "push", id });
10213
+ context.undoStack.push(frames);
11391
10214
  onHistoryChange();
11392
10215
  }
11393
10216
  function addToUndoStack(frames) {
@@ -11425,7 +10248,7 @@ function createRoom(options, config) {
11425
10248
  "Internal. Tried to get connection id but connection was never open"
11426
10249
  );
11427
10250
  }
11428
- function applyLocalOps(frames, localStorageUpdateSource = { origin: "local", via: "mutation" }) {
10251
+ function applyLocalOps(frames) {
11429
10252
  const [pframes, ops] = partition(
11430
10253
  frames,
11431
10254
  (f) => f.type === "presence"
@@ -11437,8 +10260,7 @@ function createRoom(options, config) {
11437
10260
  pframes,
11438
10261
  opsWithOpIds,
11439
10262
  /* isLocal */
11440
- true,
11441
- localStorageUpdateSource
10263
+ true
11442
10264
  );
11443
10265
  return { opsToEmit: opsWithOpIds, reverse, updates };
11444
10266
  }
@@ -11450,7 +10272,7 @@ function createRoom(options, config) {
11450
10272
  false
11451
10273
  );
11452
10274
  }
11453
- function applyOps(pframes, ops, isLocal, localStorageUpdateSource = { origin: "local", via: "mutation" }) {
10275
+ function applyOps(pframes, ops, isLocal) {
11454
10276
  const output = {
11455
10277
  reverse: new Deque(),
11456
10278
  storageUpdates: /* @__PURE__ */ new Map(),
@@ -11488,7 +10310,6 @@ function createRoom(options, config) {
11488
10310
  }
11489
10311
  const applyOpResult = applyOp(op, source);
11490
10312
  if (applyOpResult.modified) {
11491
- applyOpResult.modified[kStorageUpdateSource] = source === 1 /* THEIRS */ ? { origin: "remote" } : localStorageUpdateSource;
11492
10313
  const nodeId = applyOpResult.modified.node._id;
11493
10314
  if (!(nodeId && createdNodeIds.has(nodeId))) {
11494
10315
  output.storageUpdates.set(
@@ -11500,7 +10321,7 @@ function createRoom(options, config) {
11500
10321
  );
11501
10322
  output.reverse.pushLeft(applyOpResult.reverse);
11502
10323
  }
11503
- if (op.type === OpCode.CREATE_LIST || op.type === OpCode.CREATE_MAP || op.type === OpCode.CREATE_OBJECT || op.type === OpCode.CREATE_TEXT) {
10324
+ if (op.type === OpCode.CREATE_LIST || op.type === OpCode.CREATE_MAP || op.type === OpCode.CREATE_OBJECT) {
11504
10325
  createdNodeIds.add(op.id);
11505
10326
  }
11506
10327
  }
@@ -11520,7 +10341,6 @@ function createRoom(options, config) {
11520
10341
  switch (op.type) {
11521
10342
  case OpCode.DELETE_OBJECT_KEY:
11522
10343
  case OpCode.UPDATE_OBJECT:
11523
- case OpCode.UPDATE_TEXT:
11524
10344
  case OpCode.DELETE_CRDT: {
11525
10345
  const node = context.pool.nodes.get(op.id);
11526
10346
  if (node === void 0) {
@@ -11545,7 +10365,6 @@ function createRoom(options, config) {
11545
10365
  case OpCode.CREATE_OBJECT:
11546
10366
  case OpCode.CREATE_LIST:
11547
10367
  case OpCode.CREATE_MAP:
11548
- case OpCode.CREATE_TEXT:
11549
10368
  case OpCode.CREATE_REGISTER: {
11550
10369
  if (op.parentId === void 0) {
11551
10370
  return { modified: false };
@@ -11576,7 +10395,7 @@ function createRoom(options, config) {
11576
10395
  }
11577
10396
  context.myPresence.patch(patch);
11578
10397
  if (context.activeBatch) {
11579
- if (_optionalChain([options2, 'optionalAccess', _248 => _248.addToHistory])) {
10398
+ if (_optionalChain([options2, 'optionalAccess', _235 => _235.addToHistory])) {
11580
10399
  context.activeBatch.reverseOps.pushLeft({
11581
10400
  type: "presence",
11582
10401
  data: oldValues
@@ -11585,7 +10404,7 @@ function createRoom(options, config) {
11585
10404
  context.activeBatch.updates.presence = true;
11586
10405
  } else {
11587
10406
  flushNowOrSoon();
11588
- if (_optionalChain([options2, 'optionalAccess', _249 => _249.addToHistory])) {
10407
+ if (_optionalChain([options2, 'optionalAccess', _236 => _236.addToHistory])) {
11589
10408
  addToUndoStack([{ type: "presence", data: oldValues }]);
11590
10409
  }
11591
10410
  notify({ presence: true });
@@ -11764,11 +10583,11 @@ function createRoom(options, config) {
11764
10583
  break;
11765
10584
  }
11766
10585
  case ServerMsgCode.STORAGE_CHUNK:
11767
- _optionalChain([stopwatch, 'optionalAccess', _250 => _250.lap, 'call', _251 => _251()]);
10586
+ _optionalChain([stopwatch, 'optionalAccess', _237 => _237.lap, 'call', _238 => _238()]);
11768
10587
  nodeMapBuffer.append(compactNodesToNodeStream(message.nodes));
11769
10588
  break;
11770
10589
  case ServerMsgCode.STORAGE_STREAM_END: {
11771
- const timing = _optionalChain([stopwatch, 'optionalAccess', _252 => _252.stop, 'call', _253 => _253()]);
10590
+ const timing = _optionalChain([stopwatch, 'optionalAccess', _239 => _239.stop, 'call', _240 => _240()]);
11772
10591
  if (timing) {
11773
10592
  const ms = (v) => `${v.toFixed(1)}ms`;
11774
10593
  const rest = timing.laps.slice(1);
@@ -11795,37 +10614,16 @@ function createRoom(options, config) {
11795
10614
  }
11796
10615
  break;
11797
10616
  }
11798
- // Receiving a RejectedOps message means the server refused some of
11799
- // our ops, so our optimistic local state is out of sync with the
11800
- // server. For LiveText ops this is a normal (if rare) situation
11801
- // e.g. a client that was offline long enough to fall outside the
11802
- // server's retained history window — and we can recover: drop the
11803
- // rejected pending state and re-fetch the authoritative storage
11804
- // snapshot. For other ops (e.g. permission rejections), rolling back
11805
- // particular Ops is hard/impossible, so we keep the old behavior of
11806
- // accepting the out-of-sync reality and surfacing an error.
10617
+ // Receiving a RejectedOps message in the client means that the server is no
10618
+ // longer in sync with the client. Trying to synchronize the client again by
10619
+ // rolling back particular Ops may be hard/impossible. It's fine to not try and
10620
+ // accept the out-of-sync reality and throw an error.
11807
10621
  case ServerMsgCode.REJECT_STORAGE_OP: {
11808
10622
  errorWithTitle(
11809
10623
  "Storage mutation rejection error",
11810
10624
  message.reason
11811
10625
  );
11812
- let needsStorageResync = false;
11813
- for (const opId of message.opIds) {
11814
- const rejectedOp = context.unacknowledgedOps.get(opId);
11815
- context.unacknowledgedOps.delete(opId);
11816
- context.buffer.storageOperations = context.buffer.storageOperations.filter((op) => op.opId !== opId);
11817
- if (rejectedOp !== void 0 && rejectedOp.type === OpCode.UPDATE_TEXT) {
11818
- const node = context.pool.nodes.get(rejectedOp.id);
11819
- if (node !== void 0 && isLiveText(node)) {
11820
- node._rejectPendingOp(opId);
11821
- needsStorageResync = true;
11822
- }
11823
- }
11824
- }
11825
- if (needsStorageResync) {
11826
- refreshStorage();
11827
- flushNowOrSoon();
11828
- } else if (process.env.NODE_ENV !== "production") {
10626
+ if (process.env.NODE_ENV !== "production") {
11829
10627
  throw new Error(
11830
10628
  `Storage mutations rejected by server: ${message.reason}`
11831
10629
  );
@@ -11924,11 +10722,11 @@ function createRoom(options, config) {
11924
10722
  } else if (pendingFeedsRequests.has(requestId)) {
11925
10723
  const pending = pendingFeedsRequests.get(requestId);
11926
10724
  pendingFeedsRequests.delete(requestId);
11927
- _optionalChain([pending, 'optionalAccess', _254 => _254.reject, 'call', _255 => _255(err)]);
10725
+ _optionalChain([pending, 'optionalAccess', _241 => _241.reject, 'call', _242 => _242(err)]);
11928
10726
  } else if (pendingFeedMessagesRequests.has(requestId)) {
11929
10727
  const pending = pendingFeedMessagesRequests.get(requestId);
11930
10728
  pendingFeedMessagesRequests.delete(requestId);
11931
- _optionalChain([pending, 'optionalAccess', _256 => _256.reject, 'call', _257 => _257(err)]);
10729
+ _optionalChain([pending, 'optionalAccess', _243 => _243.reject, 'call', _244 => _244(err)]);
11932
10730
  }
11933
10731
  eventHub.feeds.notify(message);
11934
10732
  break;
@@ -12082,10 +10880,10 @@ function createRoom(options, config) {
12082
10880
  timeoutId,
12083
10881
  kind,
12084
10882
  feedId,
12085
- messageId: _optionalChain([options2, 'optionalAccess', _258 => _258.messageId]),
12086
- expectedClientMessageId: _optionalChain([options2, 'optionalAccess', _259 => _259.expectedClientMessageId])
10883
+ messageId: _optionalChain([options2, 'optionalAccess', _245 => _245.messageId]),
10884
+ expectedClientMessageId: _optionalChain([options2, 'optionalAccess', _246 => _246.expectedClientMessageId])
12087
10885
  });
12088
- if (kind === "add-message" && _optionalChain([options2, 'optionalAccess', _260 => _260.expectedClientMessageId]) === void 0) {
10886
+ if (kind === "add-message" && _optionalChain([options2, 'optionalAccess', _247 => _247.expectedClientMessageId]) === void 0) {
12089
10887
  const q = _nullishCoalesce(pendingAddMessageFifoByFeed.get(feedId), () => ( []));
12090
10888
  q.push(requestId);
12091
10889
  pendingAddMessageFifoByFeed.set(feedId, q);
@@ -12136,10 +10934,10 @@ function createRoom(options, config) {
12136
10934
  }
12137
10935
  if (!matched) {
12138
10936
  const q = pendingAddMessageFifoByFeed.get(message.feedId);
12139
- const headId = _optionalChain([q, 'optionalAccess', _261 => _261[0]]);
10937
+ const headId = _optionalChain([q, 'optionalAccess', _248 => _248[0]]);
12140
10938
  if (headId !== void 0) {
12141
10939
  const pending = pendingFeedMutations.get(headId);
12142
- if (_optionalChain([pending, 'optionalAccess', _262 => _262.kind]) === "add-message" && pending.expectedClientMessageId === void 0) {
10940
+ if (_optionalChain([pending, 'optionalAccess', _249 => _249.kind]) === "add-message" && pending.expectedClientMessageId === void 0) {
12143
10941
  settleFeedMutation(headId, "ok");
12144
10942
  }
12145
10943
  }
@@ -12175,7 +10973,7 @@ function createRoom(options, config) {
12175
10973
  const unacknowledgedOps2 = [...context.unacknowledgedOps.values()];
12176
10974
  createOrUpdateRootFromMessage(nodes);
12177
10975
  applyAndSendOfflineOps(unacknowledgedOps2);
12178
- _optionalChain([_resolveStoragePromise, 'optionalCall', _263 => _263()]);
10976
+ _optionalChain([_resolveStoragePromise, 'optionalCall', _250 => _250()]);
12179
10977
  notifyStorageStatus();
12180
10978
  eventHub.storageDidLoad.notify();
12181
10979
  }
@@ -12184,7 +10982,7 @@ function createRoom(options, config) {
12184
10982
  if (!messages.some((msg) => msg.type === ClientMsgCode.FETCH_STORAGE)) {
12185
10983
  messages.push({ type: ClientMsgCode.FETCH_STORAGE });
12186
10984
  nodeMapBuffer.take();
12187
- _optionalChain([stopwatch, 'optionalAccess', _264 => _264.start, 'call', _265 => _265()]);
10985
+ _optionalChain([stopwatch, 'optionalAccess', _251 => _251.start, 'call', _252 => _252()]);
12188
10986
  }
12189
10987
  }
12190
10988
  function startLoadingStorage() {
@@ -12238,10 +11036,10 @@ function createRoom(options, config) {
12238
11036
  const message = {
12239
11037
  type: ClientMsgCode.FETCH_FEEDS,
12240
11038
  requestId,
12241
- cursor: _optionalChain([options2, 'optionalAccess', _266 => _266.cursor]),
12242
- since: _optionalChain([options2, 'optionalAccess', _267 => _267.since]),
12243
- limit: _optionalChain([options2, 'optionalAccess', _268 => _268.limit]),
12244
- metadata: _optionalChain([options2, 'optionalAccess', _269 => _269.metadata])
11039
+ cursor: _optionalChain([options2, 'optionalAccess', _253 => _253.cursor]),
11040
+ since: _optionalChain([options2, 'optionalAccess', _254 => _254.since]),
11041
+ limit: _optionalChain([options2, 'optionalAccess', _255 => _255.limit]),
11042
+ metadata: _optionalChain([options2, 'optionalAccess', _256 => _256.metadata])
12245
11043
  };
12246
11044
  context.buffer.messages.push(message);
12247
11045
  flushNowOrSoon();
@@ -12261,9 +11059,9 @@ function createRoom(options, config) {
12261
11059
  type: ClientMsgCode.FETCH_FEED_MESSAGES,
12262
11060
  requestId,
12263
11061
  feedId,
12264
- cursor: _optionalChain([options2, 'optionalAccess', _270 => _270.cursor]),
12265
- since: _optionalChain([options2, 'optionalAccess', _271 => _271.since]),
12266
- limit: _optionalChain([options2, 'optionalAccess', _272 => _272.limit])
11062
+ cursor: _optionalChain([options2, 'optionalAccess', _257 => _257.cursor]),
11063
+ since: _optionalChain([options2, 'optionalAccess', _258 => _258.since]),
11064
+ limit: _optionalChain([options2, 'optionalAccess', _259 => _259.limit])
12267
11065
  };
12268
11066
  context.buffer.messages.push(message);
12269
11067
  flushNowOrSoon();
@@ -12282,8 +11080,8 @@ function createRoom(options, config) {
12282
11080
  type: ClientMsgCode.ADD_FEED,
12283
11081
  requestId,
12284
11082
  feedId,
12285
- metadata: _optionalChain([options2, 'optionalAccess', _273 => _273.metadata]),
12286
- createdAt: _optionalChain([options2, 'optionalAccess', _274 => _274.createdAt])
11083
+ metadata: _optionalChain([options2, 'optionalAccess', _260 => _260.metadata]),
11084
+ createdAt: _optionalChain([options2, 'optionalAccess', _261 => _261.createdAt])
12287
11085
  };
12288
11086
  context.buffer.messages.push(message);
12289
11087
  flushNowOrSoon();
@@ -12317,15 +11115,15 @@ function createRoom(options, config) {
12317
11115
  function addFeedMessage(feedId, data, options2) {
12318
11116
  const requestId = nanoid();
12319
11117
  const promise = registerFeedMutation(requestId, "add-message", feedId, {
12320
- expectedClientMessageId: _optionalChain([options2, 'optionalAccess', _275 => _275.id])
11118
+ expectedClientMessageId: _optionalChain([options2, 'optionalAccess', _262 => _262.id])
12321
11119
  });
12322
11120
  const message = {
12323
11121
  type: ClientMsgCode.ADD_FEED_MESSAGE,
12324
11122
  requestId,
12325
11123
  feedId,
12326
11124
  data,
12327
- id: _optionalChain([options2, 'optionalAccess', _276 => _276.id]),
12328
- createdAt: _optionalChain([options2, 'optionalAccess', _277 => _277.createdAt])
11125
+ id: _optionalChain([options2, 'optionalAccess', _263 => _263.id]),
11126
+ createdAt: _optionalChain([options2, 'optionalAccess', _264 => _264.createdAt])
12329
11127
  };
12330
11128
  context.buffer.messages.push(message);
12331
11129
  flushNowOrSoon();
@@ -12342,7 +11140,7 @@ function createRoom(options, config) {
12342
11140
  feedId,
12343
11141
  messageId,
12344
11142
  data,
12345
- updatedAt: _optionalChain([options2, 'optionalAccess', _278 => _278.updatedAt])
11143
+ updatedAt: _optionalChain([options2, 'optionalAccess', _265 => _265.updatedAt])
12346
11144
  };
12347
11145
  context.buffer.messages.push(message);
12348
11146
  flushNowOrSoon();
@@ -12367,19 +11165,14 @@ function createRoom(options, config) {
12367
11165
  if (context.activeBatch) {
12368
11166
  throw new Error("undo is not allowed during a batch");
12369
11167
  }
12370
- const item = context.undoStack.pop();
12371
- if (item === void 0) {
11168
+ const frames = context.undoStack.pop();
11169
+ if (frames === void 0) {
12372
11170
  return;
12373
11171
  }
12374
11172
  context.pausedHistory = null;
12375
- const result = applyLocalOps(item.frames, {
12376
- origin: "local",
12377
- via: "history",
12378
- action: "undo"
12379
- });
12380
- context.redoStack.push({ id: item.id, frames: result.reverse });
12381
- notifyPrivateHistory({ action: "undo", id: item.id });
11173
+ const result = applyLocalOps(frames);
12382
11174
  notify(result.updates);
11175
+ context.redoStack.push(result.reverse);
12383
11176
  onHistoryChange();
12384
11177
  for (const op of result.opsToEmit) {
12385
11178
  context.buffer.storageOperations.push(op);
@@ -12390,19 +11183,14 @@ function createRoom(options, config) {
12390
11183
  if (context.activeBatch) {
12391
11184
  throw new Error("redo is not allowed during a batch");
12392
11185
  }
12393
- const item = context.redoStack.pop();
12394
- if (item === void 0) {
11186
+ const frames = context.redoStack.pop();
11187
+ if (frames === void 0) {
12395
11188
  return;
12396
11189
  }
12397
11190
  context.pausedHistory = null;
12398
- const result = applyLocalOps(item.frames, {
12399
- origin: "local",
12400
- via: "history",
12401
- action: "redo"
12402
- });
12403
- context.undoStack.push({ id: item.id, frames: result.reverse });
12404
- notifyPrivateHistory({ action: "redo", id: item.id });
11191
+ const result = applyLocalOps(frames);
12405
11192
  notify(result.updates);
11193
+ context.undoStack.push(result.reverse);
12406
11194
  onHistoryChange();
12407
11195
  for (const op of result.opsToEmit) {
12408
11196
  context.buffer.storageOperations.push(op);
@@ -12412,8 +11200,6 @@ function createRoom(options, config) {
12412
11200
  function clear() {
12413
11201
  context.undoStack.length = 0;
12414
11202
  context.redoStack.length = 0;
12415
- notifyPrivateHistory({ action: "clear" });
12416
- onHistoryChange();
12417
11203
  }
12418
11204
  function batch2(callback) {
12419
11205
  if (context.activeBatch) {
@@ -12442,7 +11228,7 @@ function createRoom(options, config) {
12442
11228
  commitPausedHistoryToUndoStack();
12443
11229
  }
12444
11230
  if (currentBatch.ops.length > 0) {
12445
- clearRedoStack();
11231
+ context.redoStack.length = 0;
12446
11232
  }
12447
11233
  if (currentBatch.ops.length > 0) {
12448
11234
  dispatchOps(currentBatch.ops);
@@ -12471,6 +11257,7 @@ function createRoom(options, config) {
12471
11257
  }
12472
11258
  commitPausedHistoryToUndoStack();
12473
11259
  }
11260
+ let historyDisabled = 0;
12474
11261
  function disableHistory(fn) {
12475
11262
  const origUndo = context.undoStack;
12476
11263
  const origRedo = context.redoStack;
@@ -12560,8 +11347,8 @@ function createRoom(options, config) {
12560
11347
  async function getThreads(options2) {
12561
11348
  return httpClient.getThreads({
12562
11349
  roomId,
12563
- query: _optionalChain([options2, 'optionalAccess', _279 => _279.query]),
12564
- cursor: _optionalChain([options2, 'optionalAccess', _280 => _280.cursor])
11350
+ query: _optionalChain([options2, 'optionalAccess', _266 => _266.query]),
11351
+ cursor: _optionalChain([options2, 'optionalAccess', _267 => _267.cursor])
12565
11352
  });
12566
11353
  }
12567
11354
  async function getThread(threadId) {
@@ -12572,6 +11359,7 @@ function createRoom(options, config) {
12572
11359
  roomId,
12573
11360
  threadId: options2.threadId,
12574
11361
  commentId: options2.commentId,
11362
+ visibility: options2.visibility,
12575
11363
  metadata: options2.metadata,
12576
11364
  body: options2.body,
12577
11365
  commentMetadata: options2.commentMetadata,
@@ -12683,7 +11471,7 @@ function createRoom(options, config) {
12683
11471
  function getSubscriptionSettings(options2) {
12684
11472
  return httpClient.getSubscriptionSettings({
12685
11473
  roomId,
12686
- signal: _optionalChain([options2, 'optionalAccess', _281 => _281.signal])
11474
+ signal: _optionalChain([options2, 'optionalAccess', _268 => _268.signal])
12687
11475
  });
12688
11476
  }
12689
11477
  function updateSubscriptionSettings(settings) {
@@ -12705,44 +11493,30 @@ function createRoom(options, config) {
12705
11493
  {
12706
11494
  [kInternal]: {
12707
11495
  get presenceBuffer() {
12708
- return deepClone(_nullishCoalesce(_optionalChain([context, 'access', _282 => _282.buffer, 'access', _283 => _283.presenceUpdates, 'optionalAccess', _284 => _284.data]), () => ( null)));
11496
+ return deepClone(_nullishCoalesce(_optionalChain([context, 'access', _269 => _269.buffer, 'access', _270 => _270.presenceUpdates, 'optionalAccess', _271 => _271.data]), () => ( null)));
12709
11497
  },
12710
11498
  // prettier-ignore
12711
11499
  get undoStack() {
12712
- return structuredClone(
12713
- context.undoStack.map((item) => ({
12714
- id: item.id,
12715
- frames: item.frames
12716
- }))
12717
- );
12718
- },
12719
- // prettier-ignore
12720
- get redoStack() {
12721
- return structuredClone(
12722
- context.redoStack.map((item) => ({
12723
- id: item.id,
12724
- frames: item.frames
12725
- }))
12726
- );
11500
+ return deepClone(context.undoStack);
12727
11501
  },
12728
11502
  // prettier-ignore
12729
11503
  get nodeCount() {
12730
11504
  return context.pool.nodes.size;
12731
11505
  },
12732
11506
  // prettier-ignore
12733
- history: eventHub.privateHistory.observable,
12734
11507
  getYjsProvider() {
12735
11508
  return context.yjsProvider;
12736
11509
  },
12737
11510
  setYjsProvider(newProvider) {
12738
- _optionalChain([context, 'access', _285 => _285.yjsProvider, 'optionalAccess', _286 => _286.off, 'call', _287 => _287("status", yjsStatusDidChange)]);
11511
+ _optionalChain([context, 'access', _272 => _272.yjsProvider, 'optionalAccess', _273 => _273.off, 'call', _274 => _274("status", yjsStatusDidChange)]);
12739
11512
  context.yjsProvider = newProvider;
12740
- _optionalChain([newProvider, 'optionalAccess', _288 => _288.on, 'call', _289 => _289("status", yjsStatusDidChange)]);
11513
+ _optionalChain([newProvider, 'optionalAccess', _275 => _275.on, 'call', _276 => _276("status", yjsStatusDidChange)]);
12741
11514
  context.yjsProviderDidChange.notify();
12742
11515
  },
12743
11516
  yjsProviderDidChange: context.yjsProviderDidChange.observable,
12744
11517
  // send metadata when using a text editor
12745
11518
  reportTextEditor,
11519
+ getPermissionMatrix: () => _optionalChain([context, 'access', _277 => _277.dynamicSessionInfoSig, 'access', _278 => _278.get, 'call', _279 => _279(), 'optionalAccess', _280 => _280.permissionMatrix]),
12746
11520
  // create a text mention when using a text editor
12747
11521
  createTextMention,
12748
11522
  // delete a text mention when using a text editor
@@ -12797,7 +11571,7 @@ ${dumpPool(
12797
11571
  source.dispose();
12798
11572
  }
12799
11573
  eventHub.roomWillDestroy.notify();
12800
- _optionalChain([context, 'access', _290 => _290.yjsProvider, 'optionalAccess', _291 => _291.off, 'call', _292 => _292("status", yjsStatusDidChange)]);
11574
+ _optionalChain([context, 'access', _281 => _281.yjsProvider, 'optionalAccess', _282 => _282.off, 'call', _283 => _283("status", yjsStatusDidChange)]);
12801
11575
  syncSourceForStorage.destroy();
12802
11576
  syncSourceForYjs.destroy();
12803
11577
  uninstallBgTabSpy();
@@ -12959,7 +11733,7 @@ function makeClassicSubscribeFn(roomId, events, errorEvents) {
12959
11733
  }
12960
11734
  if (isLiveNode(first)) {
12961
11735
  const node = first;
12962
- if (_optionalChain([options, 'optionalAccess', _293 => _293.isDeep])) {
11736
+ if (_optionalChain([options, 'optionalAccess', _284 => _284.isDeep])) {
12963
11737
  const storageCallback = second;
12964
11738
  return subscribeToLiveStructureDeeply(node, storageCallback);
12965
11739
  } else {
@@ -13049,8 +11823,8 @@ function createClient(options) {
13049
11823
  const authManager = createAuthManager(options, (token) => {
13050
11824
  currentUserId.set(() => token.uid);
13051
11825
  });
13052
- const fetchPolyfill = _optionalChain([clientOptions, 'access', _294 => _294.polyfills, 'optionalAccess', _295 => _295.fetch]) || /* istanbul ignore next */
13053
- _optionalChain([globalThis, 'access', _296 => _296.fetch, 'optionalAccess', _297 => _297.bind, 'call', _298 => _298(globalThis)]);
11826
+ const fetchPolyfill = _optionalChain([clientOptions, 'access', _285 => _285.polyfills, 'optionalAccess', _286 => _286.fetch]) || /* istanbul ignore next */
11827
+ _optionalChain([globalThis, 'access', _287 => _287.fetch, 'optionalAccess', _288 => _288.bind, 'call', _289 => _289(globalThis)]);
13054
11828
  const httpClient = createApiClient({
13055
11829
  baseUrl,
13056
11830
  fetchPolyfill,
@@ -13067,7 +11841,7 @@ function createClient(options) {
13067
11841
  delegates: {
13068
11842
  createSocket: makeCreateSocketDelegateForAi(
13069
11843
  baseUrl,
13070
- _optionalChain([clientOptions, 'access', _299 => _299.polyfills, 'optionalAccess', _300 => _300.WebSocket])
11844
+ _optionalChain([clientOptions, 'access', _290 => _290.polyfills, 'optionalAccess', _291 => _291.WebSocket])
13071
11845
  ),
13072
11846
  authenticate: async () => {
13073
11847
  const resp = await authManager.getAuthValue({
@@ -13138,7 +11912,7 @@ function createClient(options) {
13138
11912
  createSocket: makeCreateSocketDelegateForRoom(
13139
11913
  roomId,
13140
11914
  baseUrl,
13141
- _optionalChain([clientOptions, 'access', _301 => _301.polyfills, 'optionalAccess', _302 => _302.WebSocket])
11915
+ _optionalChain([clientOptions, 'access', _292 => _292.polyfills, 'optionalAccess', _293 => _293.WebSocket])
13142
11916
  ),
13143
11917
  authenticate: makeAuthDelegateForRoom(roomId, authManager)
13144
11918
  })),
@@ -13160,7 +11934,7 @@ function createClient(options) {
13160
11934
  const shouldConnect = _nullishCoalesce(options2.autoConnect, () => ( true));
13161
11935
  if (shouldConnect) {
13162
11936
  if (typeof atob === "undefined") {
13163
- if (_optionalChain([clientOptions, 'access', _303 => _303.polyfills, 'optionalAccess', _304 => _304.atob]) === void 0) {
11937
+ if (_optionalChain([clientOptions, 'access', _294 => _294.polyfills, 'optionalAccess', _295 => _295.atob]) === void 0) {
13164
11938
  throw new Error(
13165
11939
  "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"
13166
11940
  );
@@ -13172,7 +11946,7 @@ function createClient(options) {
13172
11946
  return leaseRoom(newRoomDetails);
13173
11947
  }
13174
11948
  function getRoom(roomId) {
13175
- const room = _optionalChain([roomsById, 'access', _305 => _305.get, 'call', _306 => _306(roomId), 'optionalAccess', _307 => _307.room]);
11949
+ const room = _optionalChain([roomsById, 'access', _296 => _296.get, 'call', _297 => _297(roomId), 'optionalAccess', _298 => _298.room]);
13176
11950
  return room ? room : null;
13177
11951
  }
13178
11952
  function logout() {
@@ -13188,7 +11962,7 @@ function createClient(options) {
13188
11962
  const batchedResolveUsers = new Batch(
13189
11963
  async (batchedUserIds) => {
13190
11964
  const userIds = batchedUserIds.flat();
13191
- const users = await _optionalChain([resolveUsers, 'optionalCall', _308 => _308({ userIds })]);
11965
+ const users = await _optionalChain([resolveUsers, 'optionalCall', _299 => _299({ userIds })]);
13192
11966
  warnOnceIf(
13193
11967
  !resolveUsers,
13194
11968
  "Set the resolveUsers option in createClient to specify user info."
@@ -13205,7 +11979,7 @@ function createClient(options) {
13205
11979
  const batchedResolveRoomsInfo = new Batch(
13206
11980
  async (batchedRoomIds) => {
13207
11981
  const roomIds = batchedRoomIds.flat();
13208
- const roomsInfo = await _optionalChain([resolveRoomsInfo, 'optionalCall', _309 => _309({ roomIds })]);
11982
+ const roomsInfo = await _optionalChain([resolveRoomsInfo, 'optionalCall', _300 => _300({ roomIds })]);
13209
11983
  warnOnceIf(
13210
11984
  !resolveRoomsInfo,
13211
11985
  "Set the resolveRoomsInfo option in createClient to specify room info."
@@ -13222,7 +11996,7 @@ function createClient(options) {
13222
11996
  const batchedResolveGroupsInfo = new Batch(
13223
11997
  async (batchedGroupIds) => {
13224
11998
  const groupIds = batchedGroupIds.flat();
13225
- const groupsInfo = await _optionalChain([resolveGroupsInfo, 'optionalCall', _310 => _310({ groupIds })]);
11999
+ const groupsInfo = await _optionalChain([resolveGroupsInfo, 'optionalCall', _301 => _301({ groupIds })]);
13226
12000
  warnOnceIf(
13227
12001
  !resolveGroupsInfo,
13228
12002
  "Set the resolveGroupsInfo option in createClient to specify group info."
@@ -13281,7 +12055,7 @@ function createClient(options) {
13281
12055
  }
13282
12056
  };
13283
12057
  const win = typeof window !== "undefined" ? window : void 0;
13284
- _optionalChain([win, 'optionalAccess', _311 => _311.addEventListener, 'call', _312 => _312("beforeunload", maybePreventClose)]);
12058
+ _optionalChain([win, 'optionalAccess', _302 => _302.addEventListener, 'call', _303 => _303("beforeunload", maybePreventClose)]);
13285
12059
  }
13286
12060
  async function getNotificationSettings(options2) {
13287
12061
  const plainSettings = await httpClient.getNotificationSettings(options2);
@@ -13409,7 +12183,7 @@ var commentBodyElementsTypes = {
13409
12183
  mention: "inline"
13410
12184
  };
13411
12185
  function traverseCommentBody(body, elementOrVisitor, possiblyVisitor) {
13412
- if (!body || !_optionalChain([body, 'optionalAccess', _313 => _313.content])) {
12186
+ if (!body || !_optionalChain([body, 'optionalAccess', _304 => _304.content])) {
13413
12187
  return;
13414
12188
  }
13415
12189
  const element = typeof elementOrVisitor === "string" ? elementOrVisitor : void 0;
@@ -13419,13 +12193,13 @@ function traverseCommentBody(body, elementOrVisitor, possiblyVisitor) {
13419
12193
  for (const block of body.content) {
13420
12194
  if (type === "all" || type === "block") {
13421
12195
  if (guard(block)) {
13422
- _optionalChain([visitor, 'optionalCall', _314 => _314(block)]);
12196
+ _optionalChain([visitor, 'optionalCall', _305 => _305(block)]);
13423
12197
  }
13424
12198
  }
13425
12199
  if (type === "all" || type === "inline") {
13426
12200
  for (const inline of block.children) {
13427
12201
  if (guard(inline)) {
13428
- _optionalChain([visitor, 'optionalCall', _315 => _315(inline)]);
12202
+ _optionalChain([visitor, 'optionalCall', _306 => _306(inline)]);
13429
12203
  }
13430
12204
  }
13431
12205
  }
@@ -13595,7 +12369,7 @@ var stringifyCommentBodyPlainElements = {
13595
12369
  text: ({ element }) => element.text,
13596
12370
  link: ({ element }) => _nullishCoalesce(element.text, () => ( element.url)),
13597
12371
  mention: ({ element, user, group }) => {
13598
- return `@${_nullishCoalesce(_nullishCoalesce(_optionalChain([user, 'optionalAccess', _316 => _316.name]), () => ( _optionalChain([group, 'optionalAccess', _317 => _317.name]))), () => ( element.id))}`;
12372
+ return `@${_nullishCoalesce(_nullishCoalesce(_optionalChain([user, 'optionalAccess', _307 => _307.name]), () => ( _optionalChain([group, 'optionalAccess', _308 => _308.name]))), () => ( element.id))}`;
13599
12373
  }
13600
12374
  };
13601
12375
  var stringifyCommentBodyHtmlElements = {
@@ -13625,7 +12399,7 @@ var stringifyCommentBodyHtmlElements = {
13625
12399
  return html`<a href="${href}" target="_blank" rel="noopener noreferrer">${element.text ? html`${element.text}` : element.url}</a>`;
13626
12400
  },
13627
12401
  mention: ({ element, user, group }) => {
13628
- return html`<span data-mention>@${_optionalChain([user, 'optionalAccess', _318 => _318.name]) ? html`${_optionalChain([user, 'optionalAccess', _319 => _319.name])}` : _optionalChain([group, 'optionalAccess', _320 => _320.name]) ? html`${_optionalChain([group, 'optionalAccess', _321 => _321.name])}` : element.id}</span>`;
12402
+ return html`<span data-mention>@${_optionalChain([user, 'optionalAccess', _309 => _309.name]) ? html`${_optionalChain([user, 'optionalAccess', _310 => _310.name])}` : _optionalChain([group, 'optionalAccess', _311 => _311.name]) ? html`${_optionalChain([group, 'optionalAccess', _312 => _312.name])}` : element.id}</span>`;
13629
12403
  }
13630
12404
  };
13631
12405
  var stringifyCommentBodyMarkdownElements = {
@@ -13655,20 +12429,20 @@ var stringifyCommentBodyMarkdownElements = {
13655
12429
  return markdown`[${_nullishCoalesce(element.text, () => ( element.url))}](${href})`;
13656
12430
  },
13657
12431
  mention: ({ element, user, group }) => {
13658
- return markdown`@${_nullishCoalesce(_nullishCoalesce(_optionalChain([user, 'optionalAccess', _322 => _322.name]), () => ( _optionalChain([group, 'optionalAccess', _323 => _323.name]))), () => ( element.id))}`;
12432
+ return markdown`@${_nullishCoalesce(_nullishCoalesce(_optionalChain([user, 'optionalAccess', _313 => _313.name]), () => ( _optionalChain([group, 'optionalAccess', _314 => _314.name]))), () => ( element.id))}`;
13659
12433
  }
13660
12434
  };
13661
12435
  async function stringifyCommentBody(body, options) {
13662
- const format = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _324 => _324.format]), () => ( "plain"));
13663
- const separator = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _325 => _325.separator]), () => ( (format === "markdown" ? "\n\n" : "\n")));
12436
+ const format = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _315 => _315.format]), () => ( "plain"));
12437
+ const separator = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _316 => _316.separator]), () => ( (format === "markdown" ? "\n\n" : "\n")));
13664
12438
  const elements = {
13665
12439
  ...format === "html" ? stringifyCommentBodyHtmlElements : format === "markdown" ? stringifyCommentBodyMarkdownElements : stringifyCommentBodyPlainElements,
13666
- ..._optionalChain([options, 'optionalAccess', _326 => _326.elements])
12440
+ ..._optionalChain([options, 'optionalAccess', _317 => _317.elements])
13667
12441
  };
13668
12442
  const { users: resolvedUsers, groups: resolvedGroupsInfo } = await resolveMentionsInCommentBody(
13669
12443
  body,
13670
- _optionalChain([options, 'optionalAccess', _327 => _327.resolveUsers]),
13671
- _optionalChain([options, 'optionalAccess', _328 => _328.resolveGroupsInfo])
12444
+ _optionalChain([options, 'optionalAccess', _318 => _318.resolveUsers]),
12445
+ _optionalChain([options, 'optionalAccess', _319 => _319.resolveGroupsInfo])
13672
12446
  );
13673
12447
  const blocks = body.content.flatMap((block, blockIndex) => {
13674
12448
  switch (block.type) {
@@ -13750,12 +12524,6 @@ function toPlainLson(lson) {
13750
12524
  liveblocksType: "LiveList",
13751
12525
  data: [...lson].map((item) => toPlainLson(item))
13752
12526
  };
13753
- } else if (lson instanceof LiveText) {
13754
- return {
13755
- liveblocksType: "LiveText",
13756
- data: lson.toJSON(),
13757
- version: lson.version
13758
- };
13759
12527
  } else {
13760
12528
  return lson;
13761
12529
  }
@@ -13809,9 +12577,9 @@ function makePoller(callback, intervalMs, options) {
13809
12577
  const startTime = performance.now();
13810
12578
  const doc = typeof document !== "undefined" ? document : void 0;
13811
12579
  const win = typeof window !== "undefined" ? window : void 0;
13812
- const maxStaleTimeMs = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _329 => _329.maxStaleTimeMs]), () => ( Number.POSITIVE_INFINITY));
12580
+ const maxStaleTimeMs = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _320 => _320.maxStaleTimeMs]), () => ( Number.POSITIVE_INFINITY));
13813
12581
  const context = {
13814
- inForeground: _optionalChain([doc, 'optionalAccess', _330 => _330.visibilityState]) !== "hidden",
12582
+ inForeground: _optionalChain([doc, 'optionalAccess', _321 => _321.visibilityState]) !== "hidden",
13815
12583
  lastSuccessfulPollAt: startTime,
13816
12584
  count: 0,
13817
12585
  backoff: 0
@@ -13892,11 +12660,11 @@ function makePoller(callback, intervalMs, options) {
13892
12660
  pollNowIfStale();
13893
12661
  }
13894
12662
  function onVisibilityChange() {
13895
- setInForeground(_optionalChain([doc, 'optionalAccess', _331 => _331.visibilityState]) !== "hidden");
12663
+ setInForeground(_optionalChain([doc, 'optionalAccess', _322 => _322.visibilityState]) !== "hidden");
13896
12664
  }
13897
- _optionalChain([doc, 'optionalAccess', _332 => _332.addEventListener, 'call', _333 => _333("visibilitychange", onVisibilityChange)]);
13898
- _optionalChain([win, 'optionalAccess', _334 => _334.addEventListener, 'call', _335 => _335("online", onVisibilityChange)]);
13899
- _optionalChain([win, 'optionalAccess', _336 => _336.addEventListener, 'call', _337 => _337("focus", pollNowIfStale)]);
12665
+ _optionalChain([doc, 'optionalAccess', _323 => _323.addEventListener, 'call', _324 => _324("visibilitychange", onVisibilityChange)]);
12666
+ _optionalChain([win, 'optionalAccess', _325 => _325.addEventListener, 'call', _326 => _326("online", onVisibilityChange)]);
12667
+ _optionalChain([win, 'optionalAccess', _327 => _327.addEventListener, 'call', _328 => _328("focus", pollNowIfStale)]);
13900
12668
  fsm.start();
13901
12669
  return {
13902
12670
  inc,
@@ -14041,10 +12809,5 @@ detectDupes(PKG_NAME, PKG_VERSION, PKG_FORMAT);
14041
12809
 
14042
12810
 
14043
12811
 
14044
-
14045
-
14046
-
14047
-
14048
-
14049
- exports.ClientMsgCode = ClientMsgCode; exports.CrdtType = CrdtType; exports.DefaultMap = DefaultMap; exports.Deque = Deque; exports.DerivedSignal = DerivedSignal; exports.FeedRequestErrorCode = FeedRequestErrorCode; exports.HttpError = HttpError; exports.LiveList = LiveList; exports.LiveMap = LiveMap; exports.LiveObject = LiveObject; exports.LiveText = LiveText; exports.LiveblocksError = LiveblocksError; exports.MENTION_CHARACTER = MENTION_CHARACTER; exports.MutableSignal = MutableSignal; exports.OpCode = OpCode; exports.Permission = Permission; exports.Promise_withResolvers = Promise_withResolvers; exports.ServerMsgCode = ServerMsgCode; exports.Signal = Signal; exports.SortedList = SortedList; exports.TextEditorType = TextEditorType; exports.WebsocketCloseCodes = WebsocketCloseCodes; exports.applyLiveTextOperations = applyLiveTextOperations; exports.asPos = asPos; exports.assert = assert; exports.assertNever = assertNever; exports.autoRetry = autoRetry; exports.b64decode = b64decode; exports.batch = batch; exports.checkBounds = checkBounds; exports.chunk = chunk; exports.cloneLson = cloneLson; exports.compactNodesToNodeStream = compactNodesToNodeStream; exports.compactObject = compactObject; exports.console = fancy_console_exports; exports.convertToCommentData = convertToCommentData; exports.convertToCommentUserReaction = convertToCommentUserReaction; exports.convertToGroupData = convertToGroupData; exports.convertToInboxNotificationData = convertToInboxNotificationData; exports.convertToSubscriptionData = convertToSubscriptionData; exports.convertToThreadData = convertToThreadData; exports.convertToUserSubscriptionData = convertToUserSubscriptionData; exports.createClient = createClient; exports.createCommentAttachmentId = createCommentAttachmentId; exports.createCommentId = createCommentId; exports.createInboxNotificationId = createInboxNotificationId; exports.createManagedPool = createManagedPool; exports.createNotificationSettings = createNotificationSettings; exports.createThreadId = createThreadId; exports.deepLiveify = deepLiveify; exports.defineAiTool = defineAiTool; exports.deprecate = deprecate; exports.deprecateIf = deprecateIf; exports.detectDupes = detectDupes; exports.entries = entries; exports.errorIf = errorIf; exports.findLastIndex = findLastIndex; exports.freeze = freeze; exports.generateUrl = generateUrl; exports.getMentionsFromCommentBody = getMentionsFromCommentBody; exports.getSubscriptionKey = getSubscriptionKey; exports.hasPermissionAccess = hasPermissionAccess; exports.html = html; exports.htmlSafe = htmlSafe; exports.isCommentBodyLink = isCommentBodyLink; exports.isCommentBodyMention = isCommentBodyMention; exports.isCommentBodyText = isCommentBodyText; exports.isJsonArray = isJsonArray; exports.isJsonObject = isJsonObject; exports.isJsonScalar = isJsonScalar; exports.isListStorageNode = isListStorageNode; exports.isLiveNode = isLiveNode; exports.isMapStorageNode = isMapStorageNode; exports.isNotificationChannelEnabled = isNotificationChannelEnabled; exports.isNumberOperator = isNumberOperator; exports.isObjectStorageNode = isObjectStorageNode; exports.isPlainObject = isPlainObject; exports.isRegisterStorageNode = isRegisterStorageNode; exports.isRootStorageNode = isRootStorageNode; exports.isStartsWithOperator = isStartsWithOperator; exports.isTextStorageNode = isTextStorageNode; exports.isUrl = isUrl; exports.kInternal = kInternal; exports.kStorageUpdateSource = kStorageUpdateSource; exports.keys = keys; exports.makeAbortController = makeAbortController; exports.makeEventSource = makeEventSource; exports.makePoller = makePoller; exports.makePosition = makePosition; exports.mapValues = mapValues; exports.memoizeOnSuccess = memoizeOnSuccess; exports.mergeRoomPermissionScopes = mergeRoomPermissionScopes; exports.nanoid = nanoid; exports.nn = nn; exports.nodeStreamToCompactNodes = nodeStreamToCompactNodes; exports.normalizeRoomAccesses = normalizeRoomAccesses; exports.normalizeRoomPermissions = normalizeRoomPermissions; exports.normalizeUpdateRoomAccesses = normalizeUpdateRoomAccesses; exports.objectToQuery = objectToQuery; exports.patchNotificationSettings = patchNotificationSettings; exports.permissionMatrixFromScopes = permissionMatrixFromScopes; exports.raise = raise; exports.resolveMentionsInCommentBody = resolveMentionsInCommentBody; exports.sanitizeUrl = sanitizeUrl; exports.shallow = shallow; exports.shallow2 = shallow2; exports.stableStringify = stableStringify; exports.stringifyCommentBody = stringifyCommentBody; exports.throwUsageError = throwUsageError; exports.toPlainLson = toPlainLson; exports.transformTextOperations = transformTextOperations; exports.tryParseJson = tryParseJson; exports.url = url; exports.urljoin = urljoin; exports.validatePermissionsSet = validatePermissionsSet; exports.wait = wait; exports.warnOnce = warnOnce; exports.warnOnceIf = warnOnceIf; exports.withTimeout = withTimeout;
12812
+ exports.ClientMsgCode = ClientMsgCode; exports.CrdtType = CrdtType; exports.DefaultMap = DefaultMap; exports.Deque = Deque; exports.DerivedSignal = DerivedSignal; exports.FeedRequestErrorCode = FeedRequestErrorCode; exports.HttpError = HttpError; exports.LiveList = LiveList; exports.LiveMap = LiveMap; exports.LiveObject = LiveObject; exports.LiveblocksError = LiveblocksError; exports.MENTION_CHARACTER = MENTION_CHARACTER; exports.MutableSignal = MutableSignal; exports.OpCode = OpCode; exports.Permission = Permission; exports.Promise_withResolvers = Promise_withResolvers; exports.ServerMsgCode = ServerMsgCode; exports.Signal = Signal; exports.SortedList = SortedList; exports.TextEditorType = TextEditorType; exports.WebsocketCloseCodes = WebsocketCloseCodes; exports.asPos = asPos; exports.assert = assert; exports.assertNever = assertNever; exports.autoRetry = autoRetry; exports.b64decode = b64decode; exports.batch = batch; exports.checkBounds = checkBounds; exports.chunk = chunk; exports.cloneLson = cloneLson; exports.compactNodesToNodeStream = compactNodesToNodeStream; exports.compactObject = compactObject; exports.console = fancy_console_exports; exports.convertToCommentData = convertToCommentData; exports.convertToCommentUserReaction = convertToCommentUserReaction; exports.convertToGroupData = convertToGroupData; exports.convertToInboxNotificationData = convertToInboxNotificationData; exports.convertToSubscriptionData = convertToSubscriptionData; exports.convertToThreadData = convertToThreadData; exports.convertToUserSubscriptionData = convertToUserSubscriptionData; exports.createClient = createClient; exports.createCommentAttachmentId = createCommentAttachmentId; exports.createCommentId = createCommentId; exports.createInboxNotificationId = createInboxNotificationId; exports.createManagedPool = createManagedPool; exports.createNotificationSettings = createNotificationSettings; exports.createThreadId = createThreadId; exports.deepLiveify = deepLiveify; exports.defineAiTool = defineAiTool; exports.deprecate = deprecate; exports.deprecateIf = deprecateIf; exports.detectDupes = detectDupes; exports.entries = entries; exports.errorIf = errorIf; exports.findLastIndex = findLastIndex; exports.freeze = freeze; exports.generateUrl = generateUrl; exports.getMentionsFromCommentBody = getMentionsFromCommentBody; exports.getSubscriptionKey = getSubscriptionKey; exports.hasPermissionAccess = hasPermissionAccess; exports.html = html; exports.htmlSafe = htmlSafe; exports.isCommentBodyLink = isCommentBodyLink; exports.isCommentBodyMention = isCommentBodyMention; exports.isCommentBodyText = isCommentBodyText; exports.isJsonArray = isJsonArray; exports.isJsonObject = isJsonObject; exports.isJsonScalar = isJsonScalar; exports.isListStorageNode = isListStorageNode; exports.isLiveNode = isLiveNode; exports.isMapStorageNode = isMapStorageNode; exports.isNotificationChannelEnabled = isNotificationChannelEnabled; exports.isNumberOperator = isNumberOperator; exports.isObjectStorageNode = isObjectStorageNode; exports.isPlainObject = isPlainObject; exports.isRegisterStorageNode = isRegisterStorageNode; exports.isRootStorageNode = isRootStorageNode; exports.isStartsWithOperator = isStartsWithOperator; exports.isUrl = isUrl; exports.kInternal = kInternal; exports.keys = keys; exports.makeAbortController = makeAbortController; exports.makeEventSource = makeEventSource; exports.makePoller = makePoller; exports.makePosition = makePosition; exports.mapValues = mapValues; exports.memoizeOnSuccess = memoizeOnSuccess; exports.mergeRoomPermissionScopes = mergeRoomPermissionScopes; exports.nanoid = nanoid; exports.nn = nn; exports.nodeStreamToCompactNodes = nodeStreamToCompactNodes; exports.normalizeRoomAccesses = normalizeRoomAccesses; exports.normalizeRoomPermissions = normalizeRoomPermissions; exports.normalizeUpdateRoomAccesses = normalizeUpdateRoomAccesses; exports.objectToQuery = objectToQuery; exports.patchNotificationSettings = patchNotificationSettings; exports.permissionMatrixFromScopes = permissionMatrixFromScopes; exports.raise = raise; exports.resolveMentionsInCommentBody = resolveMentionsInCommentBody; exports.sanitizeUrl = sanitizeUrl; exports.shallow = shallow; exports.shallow2 = shallow2; exports.stableStringify = stableStringify; exports.stringifyCommentBody = stringifyCommentBody; exports.throwUsageError = throwUsageError; exports.toPlainLson = toPlainLson; exports.tryParseJson = tryParseJson; exports.url = url; exports.urljoin = urljoin; exports.validatePermissionsSet = validatePermissionsSet; exports.wait = wait; exports.warnOnce = warnOnce; exports.warnOnceIf = warnOnceIf; exports.withTimeout = withTimeout;
14050
12813
  //# sourceMappingURL=index.cjs.map