@liveblocks/react 2.17.0-channels1 → 2.17.0-rc1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -130,9 +130,7 @@ var config = {
130
130
  HISTORY_VERSIONS_POLL_INTERVAL: 1 * MINUTES,
131
131
  HISTORY_VERSIONS_MAX_STALE_TIME: 5 * SECONDS,
132
132
  NOTIFICATION_SETTINGS_POLL_INTERVAL: 1 * MINUTES,
133
- NOTIFICATION_SETTINGS_MAX_STALE_TIME: 5 * SECONDS,
134
- CHANNEL_NOTIFICATION_SETTINGS_INTERVAL: 5 * MINUTES,
135
- CHANNEL_NOTIFICATION_SETTINGS_MAX_STALE_TIME: 1 * MINUTES
133
+ NOTIFICATION_SETTINGS_MAX_STALE_TIME: 5 * SECONDS
136
134
  };
137
135
 
138
136
  // src/lib/AsyncResult.ts
@@ -161,6 +159,15 @@ function count(it, predicate) {
161
159
  return total;
162
160
  }
163
161
 
162
+ // src/lib/ssr.ts
163
+ function ensureNotServerSide() {
164
+ if (typeof window === "undefined") {
165
+ throw new Error(
166
+ "You cannot use the Suspense version of Liveblocks hooks server side. Make sure to only call them client side by using a ClientSideSuspense wrapper.\nFor tips, see https://liveblocks.io/docs/api-reference/liveblocks-react#ClientSideSuspense"
167
+ );
168
+ }
169
+ }
170
+
164
171
  // src/lib/use-initial.ts
165
172
  import { useCallback, useReducer } from "react";
166
173
 
@@ -226,17 +233,13 @@ import {
226
233
  console as console2,
227
234
  DefaultMap,
228
235
  DerivedSignal,
229
- entries,
230
- HttpError,
231
- keys,
232
236
  kInternal,
233
237
  MutableSignal as MutableSignal2,
234
238
  nanoid,
235
239
  nn,
236
240
  shallow as shallow3,
237
241
  Signal,
238
- stringify,
239
- unstringify
242
+ stringify
240
243
  } from "@liveblocks/core";
241
244
 
242
245
  // src/lib/autobind.ts
@@ -286,16 +289,16 @@ function matchesMetadata(thread, q) {
286
289
  const metadata = thread.metadata;
287
290
  return q.metadata === void 0 || Object.entries(q.metadata).every(
288
291
  ([key, op]) => (
289
- // NOTE: `op` can be explicitly-`undefined` here, which ideally would not
290
- // mean "filter for absence" like it does now, as this does not match the
291
- // backend behavior at the moment. For an in-depth discussion, see
292
- // https://liveblocks.slack.com/archives/C02PZL7QAAW/p1728546988505989
293
- matchesOperator(metadata[key], op)
292
+ // Ignore explicit-undefined filters
293
+ // Boolean logic: op? => value matches the operator
294
+ op === void 0 || matchesOperator(metadata[key], op)
294
295
  )
295
296
  );
296
297
  }
297
298
  function matchesOperator(value, op) {
298
- if (isStartsWithOperator(op)) {
299
+ if (op === null) {
300
+ return value === void 0;
301
+ } else if (isStartsWithOperator(op)) {
299
302
  return typeof value === "string" && value.startsWith(op.startsWith);
300
303
  } else {
301
304
  return value === op;
@@ -720,26 +723,6 @@ function createStore_forPermissionHints() {
720
723
  update
721
724
  };
722
725
  }
723
- function createStore_forChannelsNotificationSettings(updates) {
724
- const signal = new Signal({});
725
- function update(settings) {
726
- signal.set((prevSettings) => {
727
- return {
728
- ...prevSettings,
729
- ...settings
730
- };
731
- });
732
- }
733
- return {
734
- signal: DerivedSignal.from(
735
- signal,
736
- updates,
737
- (base, updates2) => applyOptimisticUpdates_forChannelNotificationSettings(base, updates2)
738
- ),
739
- // Mutations
740
- update
741
- };
742
- }
743
726
  function createStore_forOptimistic(client) {
744
727
  const signal = new Signal([]);
745
728
  const syncSource = client[kInternal].createSyncSource();
@@ -779,11 +762,9 @@ var UmbrellaStore = class {
779
762
  // \ | | | | & notifications by ID
780
763
  // | \ | | Apply | |
781
764
  // | `-> OptimisticUpdates --+--+--> Optimistic --+-+--> Notification Settings (Part 2)
782
- // \ | Updates | |
783
- // `------- etc etc ---------+ | +--> History Versions (Part 3)
784
- // ^ |
785
- // | +-----> Channels Notification Settings (Part 4)
786
- // |
765
+ // \ | Updates |
766
+ // `------- etc etc ---------+ +--> History Versions (Part 3)
767
+ // ^
787
768
  // |
788
769
  // | ^ ^
789
770
  // Signal | |
@@ -804,7 +785,6 @@ var UmbrellaStore = class {
804
785
  // prettier-ignore
805
786
  historyVersions;
806
787
  permissionHints;
807
- channelNotificationSettings;
808
788
  optimisticUpdates;
809
789
  //
810
790
  // Output signals.
@@ -825,8 +805,6 @@ var UmbrellaStore = class {
825
805
  #userThreadsLastRequestedAt = null;
826
806
  // Room versions
827
807
  #roomVersionsLastRequestedAtByRoom = /* @__PURE__ */ new Map();
828
- // Channels Notification Settings
829
- #channelsNotificationSettings;
830
808
  constructor(client) {
831
809
  this.#client = client[kInternal].as();
832
810
  this.optimisticUpdates = createStore_forOptimistic(this.#client);
@@ -842,16 +820,6 @@ var UmbrellaStore = class {
842
820
  return nextCursor;
843
821
  }
844
822
  );
845
- const channelsNotificationSettingsFetcher = async () => {
846
- const result = await this.#client.getChannelsNotificationSettings();
847
- this.channelNotificationSettings.update(result);
848
- };
849
- this.channelNotificationSettings = createStore_forChannelsNotificationSettings(
850
- this.optimisticUpdates.signal
851
- );
852
- this.#channelsNotificationSettings = new SinglePageResource(
853
- channelsNotificationSettingsFetcher
854
- );
855
823
  this.threads = new ThreadDB();
856
824
  this.notifications = createStore_forNotifications();
857
825
  this.roomNotificationSettings = createStore_forRoomNotificationSettings(
@@ -875,7 +843,7 @@ var UmbrellaStore = class {
875
843
  );
876
844
  const loadingUserThreads = new DefaultMap(
877
845
  (queryKey) => {
878
- const query = unstringify(queryKey);
846
+ const query = JSON.parse(queryKey);
879
847
  const resource = new PaginatedResource(async (cursor) => {
880
848
  const result = await this.#client[kInternal].httpClient.getUserThreads_experimental({
881
849
  cursor,
@@ -917,7 +885,7 @@ var UmbrellaStore = class {
917
885
  );
918
886
  const loadingRoomThreads = new DefaultMap(
919
887
  (queryKey) => {
920
- const [roomId, query] = unstringify(queryKey);
888
+ const [roomId, query] = JSON.parse(queryKey);
921
889
  const resource = new PaginatedResource(async (cursor) => {
922
890
  const result = await this.#client[kInternal].httpClient.getThreads({
923
891
  roomId,
@@ -980,10 +948,7 @@ var UmbrellaStore = class {
980
948
  const resource = new SinglePageResource(async () => {
981
949
  const room = this.#client.getRoom(roomId);
982
950
  if (room === null) {
983
- throw new HttpError(
984
- `Room '${roomId}' is not available on client`,
985
- 479
986
- );
951
+ throw new Error(`Room '${roomId}' is not available on client`);
987
952
  }
988
953
  const result = await room.getNotificationSettings();
989
954
  this.roomNotificationSettings.update(roomId, result);
@@ -1006,10 +971,7 @@ var UmbrellaStore = class {
1006
971
  const resource = new SinglePageResource(async () => {
1007
972
  const room = this.#client.getRoom(roomId);
1008
973
  if (room === null) {
1009
- throw new HttpError(
1010
- `Room '${roomId}' is not available on client`,
1011
- 479
1012
- );
974
+ throw new Error(`Room '${roomId}' is not available on client`);
1013
975
  }
1014
976
  const result = await room[kInternal].listTextVersions();
1015
977
  this.historyVersions.update(roomId, result.versions);
@@ -1035,22 +997,6 @@ var UmbrellaStore = class {
1035
997
  return { signal, waitUntilLoaded: resource.waitUntilLoaded };
1036
998
  }
1037
999
  );
1038
- const channelNotificationSettings = {
1039
- signal: DerivedSignal.from(
1040
- () => {
1041
- const result = this.#channelsNotificationSettings.get();
1042
- if (result.isLoading || result.error) {
1043
- return result;
1044
- }
1045
- return ASYNC_OK(
1046
- "settings",
1047
- nn(this.channelNotificationSettings.signal.get())
1048
- );
1049
- },
1050
- shallow3
1051
- ),
1052
- waitUntilLoaded: this.#channelsNotificationSettings.waitUntilLoaded
1053
- };
1054
1000
  this.outputs = {
1055
1001
  threadifications,
1056
1002
  threads,
@@ -1059,8 +1005,7 @@ var UmbrellaStore = class {
1059
1005
  notifications,
1060
1006
  loadingNotifications,
1061
1007
  settingsByRoomId,
1062
- versionsByRoomId,
1063
- channelNotificationSettings
1008
+ versionsByRoomId
1064
1009
  };
1065
1010
  autobind(this);
1066
1011
  }
@@ -1305,25 +1250,6 @@ var UmbrellaStore = class {
1305
1250
  const result = await room.getNotificationSettings({ signal });
1306
1251
  this.roomNotificationSettings.update(roomId, result);
1307
1252
  }
1308
- /**
1309
- * Refresh Channels Notification Settings from poller
1310
- */
1311
- async refreshChannelsNotificationSettings(signal) {
1312
- const result = await this.#client.getChannelsNotificationSettings({
1313
- signal
1314
- });
1315
- this.channelNotificationSettings.update(result);
1316
- }
1317
- /**
1318
- * Updates channels notification settings with a new value, replacing the
1319
- * corresponding optimistic update.
1320
- */
1321
- updateChannelsNotificationSettings_confirmOptimisticUpdate(settings, optimisticUpdateId) {
1322
- batch2(() => {
1323
- this.optimisticUpdates.remove(optimisticUpdateId);
1324
- this.channelNotificationSettings.update(settings);
1325
- });
1326
- }
1327
1253
  };
1328
1254
  function applyOptimisticUpdates_forThreadifications(baseThreadsDB, notificationsLUT, optimisticUpdates) {
1329
1255
  const threadsDB = baseThreadsDB.clone();
@@ -1498,33 +1424,6 @@ function applyOptimisticUpdates_forSettings(settingsLUT, optimisticUpdates) {
1498
1424
  }
1499
1425
  return settingsByRoomId;
1500
1426
  }
1501
- function applyOptimisticUpdates_forChannelNotificationSettings(baseChannelsNotificationSettings, optimisticUpdates) {
1502
- const outcomingSettings = { ...baseChannelsNotificationSettings };
1503
- for (const optimisticUpdate of optimisticUpdates) {
1504
- switch (optimisticUpdate.type) {
1505
- case "update-channels-notification-settings": {
1506
- const incomingSettings = optimisticUpdate.settings;
1507
- for (const channelKey of keys(incomingSettings)) {
1508
- const key = channelKey;
1509
- const channelUpdates = incomingSettings[key];
1510
- if (channelUpdates) {
1511
- const realChannelUpdates = Object.fromEntries(
1512
- entries(channelUpdates).filter(
1513
- ([_, value]) => value !== void 0
1514
- )
1515
- );
1516
- outcomingSettings[key] = {
1517
- ...outcomingSettings[key],
1518
- ...realChannelUpdates
1519
- };
1520
- }
1521
- }
1522
- break;
1523
- }
1524
- }
1525
- }
1526
- return outcomingSettings;
1527
- }
1528
1427
  function compareInboxNotifications(inboxNotificationA, inboxNotificationB) {
1529
1428
  if (inboxNotificationA.notifiedAt > inboxNotificationB.notifiedAt) {
1530
1429
  return 1;
@@ -1818,25 +1717,10 @@ function makeLiveblocksExtrasForClient(client) {
1818
1717
  config.USER_THREADS_POLL_INTERVAL,
1819
1718
  { maxStaleTimeMs: config.USER_THREADS_MAX_STALE_TIME }
1820
1719
  );
1821
- const channelNotificationSettingsPoller = makePoller(
1822
- async (signal) => {
1823
- try {
1824
- return await store.refreshChannelsNotificationSettings(signal);
1825
- } catch (err) {
1826
- console.warn(
1827
- `Polling new channel notification settings failed: ${String(err)}`
1828
- );
1829
- throw err;
1830
- }
1831
- },
1832
- config.CHANNEL_NOTIFICATION_SETTINGS_INTERVAL,
1833
- { maxStaleTimeMs: config.CHANNEL_NOTIFICATION_SETTINGS_MAX_STALE_TIME }
1834
- );
1835
1720
  return {
1836
1721
  store,
1837
1722
  notificationsPoller,
1838
- userThreadsPoller,
1839
- channelNotificationSettingsPoller
1723
+ userThreadsPoller
1840
1724
  };
1841
1725
  }
1842
1726
  function makeLiveblocksContextBundle(client) {
@@ -1845,7 +1729,6 @@ function makeLiveblocksContextBundle(client) {
1845
1729
  const useMarkAllInboxNotificationsAsRead2 = () => useMarkAllInboxNotificationsAsRead_withClient(client);
1846
1730
  const useDeleteInboxNotification2 = () => useDeleteInboxNotification_withClient(client);
1847
1731
  const useDeleteAllInboxNotifications2 = () => useDeleteAllInboxNotifications_withClient(client);
1848
- const useUpdateChannelsNotificationSettings2 = () => useUpdateChannelsNotificationSettings_withClient(client);
1849
1732
  function LiveblocksProvider2(props) {
1850
1733
  useEnsureNoLiveblocksProvider();
1851
1734
  return /* @__PURE__ */ jsx(ClientContext.Provider, { value: client, children: props.children });
@@ -1859,8 +1742,6 @@ function makeLiveblocksContextBundle(client) {
1859
1742
  useMarkAllInboxNotificationsAsRead: useMarkAllInboxNotificationsAsRead2,
1860
1743
  useDeleteInboxNotification: useDeleteInboxNotification2,
1861
1744
  useDeleteAllInboxNotifications: useDeleteAllInboxNotifications2,
1862
- useChannelsNotificationSettings: () => useChannelsNotificationSettings_withClient(client),
1863
- useUpdateChannelsNotificationSettings: useUpdateChannelsNotificationSettings2,
1864
1745
  useInboxNotificationThread: useInboxNotificationThread2,
1865
1746
  useUserThreads_experimental,
1866
1747
  ...shared.classic,
@@ -1873,8 +1754,6 @@ function makeLiveblocksContextBundle(client) {
1873
1754
  useDeleteInboxNotification: useDeleteInboxNotification2,
1874
1755
  useDeleteAllInboxNotifications: useDeleteAllInboxNotifications2,
1875
1756
  useInboxNotificationThread: useInboxNotificationThread2,
1876
- useChannelsNotificationSettings: () => useChannelsNotificationSettingsSuspense_withClient(client),
1877
- useUpdateChannelsNotificationSettings: useUpdateChannelsNotificationSettings2,
1878
1757
  useUserThreads_experimental: useUserThreadsSuspense_experimental,
1879
1758
  ...shared.suspense
1880
1759
  }
@@ -1908,6 +1787,7 @@ function useInboxNotifications_withClient(client, selector, isEqual) {
1908
1787
  );
1909
1788
  }
1910
1789
  function useInboxNotificationsSuspense_withClient(client) {
1790
+ ensureNotServerSide();
1911
1791
  const store = getLiveblocksExtrasForClient(client).store;
1912
1792
  use(store.outputs.loadingNotifications.waitUntilLoaded());
1913
1793
  const result = useInboxNotifications_withClient(client, identity2, shallow4);
@@ -1923,6 +1803,7 @@ function useUnreadInboxNotificationsCount_withClient(client) {
1923
1803
  );
1924
1804
  }
1925
1805
  function useUnreadInboxNotificationsCountSuspense_withClient(client) {
1806
+ ensureNotServerSide();
1926
1807
  const store = getLiveblocksExtrasForClient(client).store;
1927
1808
  use(store.outputs.loadingNotifications.waitUntilLoaded());
1928
1809
  const result = useUnreadInboxNotificationsCount_withClient(client);
@@ -1948,8 +1829,15 @@ function useMarkInboxNotificationAsRead_withClient(client) {
1948
1829
  optimisticId
1949
1830
  );
1950
1831
  },
1951
- () => {
1832
+ (err) => {
1952
1833
  store.optimisticUpdates.remove(optimisticId);
1834
+ client[kInternal2].emitError(
1835
+ {
1836
+ type: "MARK_INBOX_NOTIFICATION_AS_READ_ERROR",
1837
+ inboxNotificationId
1838
+ },
1839
+ err
1840
+ );
1953
1841
  }
1954
1842
  );
1955
1843
  },
@@ -1968,8 +1856,13 @@ function useMarkAllInboxNotificationsAsRead_withClient(client) {
1968
1856
  () => {
1969
1857
  store.markAllInboxNotificationsRead(optimisticId, readAt);
1970
1858
  },
1971
- () => {
1859
+ (err) => {
1972
1860
  store.optimisticUpdates.remove(optimisticId);
1861
+ client[kInternal2].emitError(
1862
+ // No roomId, threadId, commentId to include for this error
1863
+ { type: "MARK_ALL_INBOX_NOTIFICATIONS_AS_READ_ERROR" },
1864
+ err
1865
+ );
1973
1866
  }
1974
1867
  );
1975
1868
  }, [client]);
@@ -1988,8 +1881,12 @@ function useDeleteInboxNotification_withClient(client) {
1988
1881
  () => {
1989
1882
  store.deleteInboxNotification(inboxNotificationId, optimisticId);
1990
1883
  },
1991
- () => {
1884
+ (err) => {
1992
1885
  store.optimisticUpdates.remove(optimisticId);
1886
+ client[kInternal2].emitError(
1887
+ { type: "DELETE_INBOX_NOTIFICATION_ERROR", inboxNotificationId },
1888
+ err
1889
+ );
1993
1890
  }
1994
1891
  );
1995
1892
  },
@@ -2008,8 +1905,12 @@ function useDeleteAllInboxNotifications_withClient(client) {
2008
1905
  () => {
2009
1906
  store.deleteAllInboxNotifications(optimisticId);
2010
1907
  },
2011
- () => {
1908
+ (err) => {
2012
1909
  store.optimisticUpdates.remove(optimisticId);
1910
+ client[kInternal2].emitError(
1911
+ { type: "DELETE_ALL_INBOX_NOTIFICATIONS_ERROR" },
1912
+ err
1913
+ );
2013
1914
  }
2014
1915
  );
2015
1916
  }, [client]);
@@ -2037,57 +1938,6 @@ function useInboxNotificationThread_withClient(client, inboxNotificationId) {
2037
1938
  )
2038
1939
  );
2039
1940
  }
2040
- function useUpdateChannelsNotificationSettings_withClient(client) {
2041
- return useCallback2(
2042
- (settings) => {
2043
- const { store } = getLiveblocksExtrasForClient(client);
2044
- const optimisticUpdateId = store.optimisticUpdates.add({
2045
- type: "update-channels-notification-settings",
2046
- settings
2047
- });
2048
- client.updateChannelsNotificationSettings(settings).then(
2049
- (settings2) => {
2050
- store.updateChannelsNotificationSettings_confirmOptimisticUpdate(
2051
- settings2,
2052
- optimisticUpdateId
2053
- );
2054
- },
2055
- () => {
2056
- store.optimisticUpdates.remove(optimisticUpdateId);
2057
- }
2058
- );
2059
- },
2060
- [client]
2061
- );
2062
- }
2063
- function useChannelsNotificationSettings_withClient(client) {
2064
- const updateChannelsNotificationSettings = useUpdateChannelsNotificationSettings_withClient(client);
2065
- const { store, channelNotificationSettingsPoller: poller } = getLiveblocksExtrasForClient(client);
2066
- useEffect3(() => {
2067
- void store.outputs.channelNotificationSettings.waitUntilLoaded();
2068
- });
2069
- useEffect3(() => {
2070
- poller.inc();
2071
- poller.pollNowIfStale();
2072
- return () => {
2073
- poller.dec();
2074
- };
2075
- }, [poller]);
2076
- const settings = useSignal(store.outputs.channelNotificationSettings.signal);
2077
- return useMemo2(() => {
2078
- return [settings, updateChannelsNotificationSettings];
2079
- }, [settings, updateChannelsNotificationSettings]);
2080
- }
2081
- function useChannelsNotificationSettingsSuspense_withClient(client) {
2082
- const store = getLiveblocksExtrasForClient(client).store;
2083
- use(store.outputs.channelNotificationSettings.waitUntilLoaded());
2084
- const [settings, updateChannelsNotificationSettings] = useChannelsNotificationSettings_withClient(client);
2085
- assert(!settings.error, "Did not expect error");
2086
- assert(!settings.isLoading, "Did not expect loading");
2087
- return useMemo2(() => {
2088
- return [settings, updateChannelsNotificationSettings];
2089
- }, [settings, updateChannelsNotificationSettings]);
2090
- }
2091
1941
  function useUser_withClient(client, userId) {
2092
1942
  const usersStore = client[kInternal2].usersStore;
2093
1943
  const getUserState = useCallback2(
@@ -2222,6 +2072,7 @@ function createSharedContext(client) {
2222
2072
  useUser: (userId) => useUser_withClient(client, userId),
2223
2073
  useRoomInfo: (roomId) => useRoomInfo_withClient(client, roomId),
2224
2074
  useIsInsideRoom,
2075
+ useErrorListener,
2225
2076
  useSyncStatus: useSyncStatus2
2226
2077
  },
2227
2078
  suspense: {
@@ -2229,6 +2080,7 @@ function createSharedContext(client) {
2229
2080
  useUser: (userId) => useUserSuspense_withClient(client, userId),
2230
2081
  useRoomInfo: (roomId) => useRoomInfoSuspense_withClient(client, roomId),
2231
2082
  useIsInsideRoom,
2083
+ useErrorListener,
2232
2084
  useSyncStatus: useSyncStatus2
2233
2085
  }
2234
2086
  };
@@ -2259,6 +2111,7 @@ function LiveblocksProvider(props) {
2259
2111
  lostConnectionTimeout: useInitial(o.lostConnectionTimeout),
2260
2112
  backgroundKeepAliveTimeout: useInitial(o.backgroundKeepAliveTimeout),
2261
2113
  polyfills: useInitial(o.polyfills),
2114
+ largeMessageStrategy: useInitial(o.largeMessageStrategy),
2262
2115
  unstable_fallbackToHTTP: useInitial(o.unstable_fallbackToHTTP),
2263
2116
  unstable_streamData: useInitial(o.unstable_streamData),
2264
2117
  preventUnsavedChanges: useInitial(o.preventUnsavedChanges),
@@ -2310,6 +2163,7 @@ function useUserThreads_experimental(options = {}) {
2310
2163
  );
2311
2164
  }
2312
2165
  function useUserThreadsSuspense_experimental(options = {}) {
2166
+ ensureNotServerSide();
2313
2167
  const client = useClient();
2314
2168
  const { store } = getLiveblocksExtrasForClient(client);
2315
2169
  const queryKey = makeUserThreadsQueryKey(options.query);
@@ -2349,15 +2203,6 @@ function useUnreadInboxNotificationsCount() {
2349
2203
  function useUnreadInboxNotificationsCountSuspense() {
2350
2204
  return useUnreadInboxNotificationsCountSuspense_withClient(useClient());
2351
2205
  }
2352
- function useChannelsNotificationSettings() {
2353
- return useChannelsNotificationSettings_withClient(useClient());
2354
- }
2355
- function useChannelsNotificationSettingsSuspense() {
2356
- return useChannelsNotificationSettingsSuspense_withClient(useClient());
2357
- }
2358
- function useUpdateChannelsNotificationSettings() {
2359
- return useUpdateChannelsNotificationSettings_withClient(useClient());
2360
- }
2361
2206
  function useUser(userId) {
2362
2207
  const client = useClient();
2363
2208
  return useUser_withClient(client, userId);
@@ -2417,104 +2262,14 @@ function useSyncStatusSmooth_withClient(client) {
2417
2262
  function useSyncStatus(options) {
2418
2263
  return useSyncStatus_withClient(useClient(), options);
2419
2264
  }
2420
-
2421
- // src/types/errors.ts
2422
- var CreateThreadError = class extends Error {
2423
- constructor(cause, context) {
2424
- super("Create thread failed.");
2425
- this.cause = cause;
2426
- this.context = context;
2427
- this.name = "CreateThreadError";
2428
- }
2429
- };
2430
- var DeleteThreadError = class extends Error {
2431
- constructor(cause, context) {
2432
- super("Delete thread failed.");
2433
- this.cause = cause;
2434
- this.context = context;
2435
- this.name = "DeleteThreadError";
2436
- }
2437
- };
2438
- var EditThreadMetadataError = class extends Error {
2439
- constructor(cause, context) {
2440
- super("Edit thread metadata failed.");
2441
- this.cause = cause;
2442
- this.context = context;
2443
- this.name = "EditThreadMetadataError";
2444
- }
2445
- };
2446
- var MarkThreadAsResolvedError = class extends Error {
2447
- constructor(cause, context) {
2448
- super("Mark thread as resolved failed.");
2449
- this.cause = cause;
2450
- this.context = context;
2451
- this.name = "MarkThreadAsResolvedError";
2452
- }
2453
- };
2454
- var MarkThreadAsUnresolvedError = class extends Error {
2455
- constructor(cause, context) {
2456
- super("Mark thread as unresolved failed.");
2457
- this.cause = cause;
2458
- this.context = context;
2459
- this.name = "MarkThreadAsUnresolvedError";
2460
- }
2461
- };
2462
- var CreateCommentError = class extends Error {
2463
- constructor(cause, context) {
2464
- super("Create comment failed.");
2465
- this.cause = cause;
2466
- this.context = context;
2467
- this.name = "CreateCommentError";
2468
- }
2469
- };
2470
- var EditCommentError = class extends Error {
2471
- constructor(cause, context) {
2472
- super("Edit comment failed.");
2473
- this.cause = cause;
2474
- this.context = context;
2475
- this.name = "EditCommentError";
2476
- }
2477
- };
2478
- var DeleteCommentError = class extends Error {
2479
- constructor(cause, context) {
2480
- super("Delete comment failed.");
2481
- this.cause = cause;
2482
- this.context = context;
2483
- this.name = "DeleteCommentError";
2484
- }
2485
- };
2486
- var AddReactionError = class extends Error {
2487
- constructor(cause, context) {
2488
- super("Add reaction failed.");
2489
- this.cause = cause;
2490
- this.context = context;
2491
- this.name = "AddReactionError";
2492
- }
2493
- };
2494
- var RemoveReactionError = class extends Error {
2495
- constructor(cause, context) {
2496
- super("Remove reaction failed.");
2497
- this.cause = cause;
2498
- this.context = context;
2499
- this.name = "RemoveReactionError";
2500
- }
2501
- };
2502
- var MarkInboxNotificationAsReadError = class extends Error {
2503
- constructor(cause, context) {
2504
- super("Mark inbox notification as read failed.");
2505
- this.cause = cause;
2506
- this.context = context;
2507
- this.name = "MarkInboxNotificationAsReadError";
2508
- }
2509
- };
2510
- var UpdateNotificationSettingsError = class extends Error {
2511
- constructor(cause, context) {
2512
- super("Update notification settings failed.");
2513
- this.cause = cause;
2514
- this.context = context;
2515
- this.name = "UpdateNotificationSettingsError";
2516
- }
2517
- };
2265
+ function useErrorListener(callback) {
2266
+ const client = useClient();
2267
+ const savedCallback = useLatest(callback);
2268
+ useEffect3(
2269
+ () => client.events.error.subscribe((e) => savedCallback.current(e)),
2270
+ [client, savedCallback]
2271
+ );
2272
+ }
2518
2273
 
2519
2274
  // src/room.tsx
2520
2275
  import { shallow as shallow5 } from "@liveblocks/client";
@@ -2525,9 +2280,8 @@ import {
2525
2280
  createThreadId,
2526
2281
  DefaultMap as DefaultMap2,
2527
2282
  errorIf,
2528
- HttpError as HttpError2,
2283
+ HttpError,
2529
2284
  kInternal as kInternal3,
2530
- makeEventSource,
2531
2285
  makePoller as makePoller2,
2532
2286
  ServerMsgCode
2533
2287
  } from "@liveblocks/core";
@@ -2621,14 +2375,6 @@ function getCurrentUserId(client) {
2621
2375
  }
2622
2376
  return userId;
2623
2377
  }
2624
- function handleApiError(err) {
2625
- const message = `Request failed with status ${err.status}: ${err.message}`;
2626
- if (err.details?.error === "FORBIDDEN") {
2627
- const detailedMessage = [message, err.details.suggestion, err.details.docs].filter(Boolean).join("\n");
2628
- console3.error(detailedMessage);
2629
- }
2630
- return new Error(message);
2631
- }
2632
2378
  var _extras2 = /* @__PURE__ */ new WeakMap();
2633
2379
  var _bundles2 = /* @__PURE__ */ new WeakMap();
2634
2380
  function getOrCreateRoomContextBundle(client) {
@@ -2649,19 +2395,21 @@ function getRoomExtrasForClient(client) {
2649
2395
  }
2650
2396
  function makeRoomExtrasForClient(client) {
2651
2397
  const store = getUmbrellaStoreForClient(client);
2652
- const commentsErrorEventSource = makeEventSource();
2653
- function onMutationFailure(innerError, optimisticId, createPublicError) {
2398
+ function onMutationFailure(optimisticId, context, innerError) {
2654
2399
  store.optimisticUpdates.remove(optimisticId);
2655
- if (innerError instanceof HttpError2) {
2656
- const error = handleApiError(innerError);
2657
- commentsErrorEventSource.notify(createPublicError(error));
2658
- return;
2659
- }
2660
- if (innerError instanceof HttpError2) {
2661
- handleApiError(innerError);
2662
- return;
2400
+ if (innerError instanceof HttpError) {
2401
+ if (innerError.status === 403) {
2402
+ const detailedMessage = [
2403
+ innerError.message,
2404
+ innerError.details?.suggestion,
2405
+ innerError.details?.docs
2406
+ ].filter(Boolean).join("\n");
2407
+ console3.error(detailedMessage);
2408
+ }
2409
+ client[kInternal3].emitError(context, innerError);
2410
+ } else {
2411
+ throw innerError;
2663
2412
  }
2664
- throw innerError;
2665
2413
  }
2666
2414
  const threadsPollersByRoomId = new DefaultMap2(
2667
2415
  (roomId) => makePoller2(
@@ -2707,7 +2455,6 @@ function makeRoomExtrasForClient(client) {
2707
2455
  );
2708
2456
  return {
2709
2457
  store,
2710
- commentsErrorEventSource: commentsErrorEventSource.observable,
2711
2458
  onMutationFailure,
2712
2459
  getOrCreateThreadsPollerForRoomId: threadsPollersByRoomId.getOrCreate.bind(
2713
2460
  threadsPollersByRoomId
@@ -2733,7 +2480,6 @@ function makeRoomContextBundle(client) {
2733
2480
  useBroadcastEvent,
2734
2481
  useOthersListener,
2735
2482
  useLostConnectionListener,
2736
- useErrorListener,
2737
2483
  useEventListener,
2738
2484
  useHistory,
2739
2485
  useUndo,
@@ -2779,7 +2525,6 @@ function makeRoomContextBundle(client) {
2779
2525
  useBroadcastEvent,
2780
2526
  useOthersListener,
2781
2527
  useLostConnectionListener,
2782
- useErrorListener,
2783
2528
  useEventListener,
2784
2529
  useHistory,
2785
2530
  useUndo,
@@ -2815,8 +2560,7 @@ function makeRoomContextBundle(client) {
2815
2560
  useRoomNotificationSettings: useRoomNotificationSettingsSuspense,
2816
2561
  useUpdateRoomNotificationSettings,
2817
2562
  ...shared.suspense
2818
- },
2819
- useCommentsErrorListener
2563
+ }
2820
2564
  };
2821
2565
  return Object.defineProperty(bundle, kInternal3, {
2822
2566
  enumerable: false
@@ -3077,14 +2821,6 @@ function useLostConnectionListener(callback) {
3077
2821
  [room, savedCallback]
3078
2822
  );
3079
2823
  }
3080
- function useErrorListener(callback) {
3081
- const room = useRoom();
3082
- const savedCallback = useLatest(callback);
3083
- useEffect5(
3084
- () => room.events.error.subscribe((e) => savedCallback.current(e)),
3085
- [room, savedCallback]
3086
- );
3087
- }
3088
2824
  function useEventListener(callback) {
3089
2825
  const room = useRoom();
3090
2826
  const savedCallback = useLatest(callback);
@@ -3294,14 +3030,6 @@ function useThreads(options = {}) {
3294
3030
  useScrollToCommentOnLoadEffect(scrollOnLoad, result);
3295
3031
  return result;
3296
3032
  }
3297
- function useCommentsErrorListener(callback) {
3298
- const client = useClient();
3299
- const savedCallback = useLatest(callback);
3300
- const { commentsErrorEventSource } = getRoomExtrasForClient(client);
3301
- useEffect5(() => {
3302
- return commentsErrorEventSource.subscribe(savedCallback.current);
3303
- }, [savedCallback, commentsErrorEventSource]);
3304
- }
3305
3033
  function useCreateThread() {
3306
3034
  return useCreateRoomThread(useRoom().id);
3307
3035
  }
@@ -3355,15 +3083,16 @@ function useCreateRoomThread(roomId) {
3355
3083
  store.createThread(optimisticId, thread);
3356
3084
  },
3357
3085
  (err) => onMutationFailure(
3358
- err,
3359
3086
  optimisticId,
3360
- (err2) => new CreateThreadError(err2, {
3087
+ {
3088
+ type: "CREATE_THREAD_ERROR",
3361
3089
  roomId,
3362
3090
  threadId,
3363
3091
  commentId,
3364
3092
  body,
3365
3093
  metadata
3366
- })
3094
+ },
3095
+ err
3367
3096
  )
3368
3097
  );
3369
3098
  return newThread;
@@ -3395,9 +3124,9 @@ function useDeleteRoomThread(roomId) {
3395
3124
  store.deleteThread(threadId, optimisticId);
3396
3125
  },
3397
3126
  (err) => onMutationFailure(
3398
- err,
3399
3127
  optimisticId,
3400
- (err2) => new DeleteThreadError(err2, { roomId, threadId })
3128
+ { type: "DELETE_THREAD_ERROR", roomId, threadId },
3129
+ err
3401
3130
  )
3402
3131
  );
3403
3132
  },
@@ -3430,13 +3159,14 @@ function useEditRoomThreadMetadata(roomId) {
3430
3159
  store.patchThread(threadId, optimisticId, { metadata: metadata2 }, updatedAt)
3431
3160
  ),
3432
3161
  (err) => onMutationFailure(
3433
- err,
3434
3162
  optimisticId,
3435
- (error) => new EditThreadMetadataError(error, {
3163
+ {
3164
+ type: "EDIT_THREAD_METADATA_ERROR",
3436
3165
  roomId,
3437
3166
  threadId,
3438
3167
  metadata
3439
- })
3168
+ },
3169
+ err
3440
3170
  )
3441
3171
  );
3442
3172
  },
@@ -3474,14 +3204,15 @@ function useCreateRoomComment(roomId) {
3474
3204
  store.createComment(newComment, optimisticId);
3475
3205
  },
3476
3206
  (err) => onMutationFailure(
3477
- err,
3478
3207
  optimisticId,
3479
- (err2) => new CreateCommentError(err2, {
3208
+ {
3209
+ type: "CREATE_COMMENT_ERROR",
3480
3210
  roomId,
3481
3211
  threadId,
3482
3212
  commentId,
3483
3213
  body
3484
- })
3214
+ },
3215
+ err
3485
3216
  )
3486
3217
  );
3487
3218
  return comment;
@@ -3529,14 +3260,9 @@ function useEditRoomComment(roomId) {
3529
3260
  store.editComment(threadId, optimisticId, editedComment);
3530
3261
  },
3531
3262
  (err) => onMutationFailure(
3532
- err,
3533
3263
  optimisticId,
3534
- (error) => new EditCommentError(error, {
3535
- roomId,
3536
- threadId,
3537
- commentId,
3538
- body
3539
- })
3264
+ { type: "EDIT_COMMENT_ERROR", roomId, threadId, commentId, body },
3265
+ err
3540
3266
  )
3541
3267
  );
3542
3268
  },
@@ -3564,13 +3290,9 @@ function useDeleteRoomComment(roomId) {
3564
3290
  store.deleteComment(threadId, optimisticId, commentId, deletedAt);
3565
3291
  },
3566
3292
  (err) => onMutationFailure(
3567
- err,
3568
3293
  optimisticId,
3569
- (error) => new DeleteCommentError(error, {
3570
- roomId,
3571
- threadId,
3572
- commentId
3573
- })
3294
+ { type: "DELETE_COMMENT_ERROR", roomId, threadId, commentId },
3295
+ err
3574
3296
  )
3575
3297
  );
3576
3298
  },
@@ -3608,14 +3330,15 @@ function useAddRoomCommentReaction(roomId) {
3608
3330
  );
3609
3331
  },
3610
3332
  (err) => onMutationFailure(
3611
- err,
3612
3333
  optimisticId,
3613
- (error) => new AddReactionError(error, {
3334
+ {
3335
+ type: "ADD_REACTION_ERROR",
3614
3336
  roomId,
3615
3337
  threadId,
3616
3338
  commentId,
3617
3339
  emoji
3618
- })
3340
+ },
3341
+ err
3619
3342
  )
3620
3343
  );
3621
3344
  },
@@ -3652,14 +3375,15 @@ function useRemoveRoomCommentReaction(roomId) {
3652
3375
  );
3653
3376
  },
3654
3377
  (err) => onMutationFailure(
3655
- err,
3656
3378
  optimisticId,
3657
- (error) => new RemoveReactionError(error, {
3379
+ {
3380
+ type: "REMOVE_REACTION_ERROR",
3658
3381
  roomId,
3659
3382
  threadId,
3660
3383
  commentId,
3661
3384
  emoji
3662
- })
3385
+ },
3386
+ err
3663
3387
  )
3664
3388
  );
3665
3389
  },
@@ -3699,11 +3423,13 @@ function useMarkRoomThreadAsRead(roomId) {
3699
3423
  },
3700
3424
  (err) => {
3701
3425
  onMutationFailure(
3702
- err,
3703
3426
  optimisticId,
3704
- (error) => new MarkInboxNotificationAsReadError(error, {
3427
+ {
3428
+ type: "MARK_INBOX_NOTIFICATION_AS_READ_ERROR",
3429
+ roomId,
3705
3430
  inboxNotificationId: inboxNotification.id
3706
- })
3431
+ },
3432
+ err
3707
3433
  );
3708
3434
  return;
3709
3435
  }
@@ -3736,12 +3462,9 @@ function useMarkRoomThreadAsResolved(roomId) {
3736
3462
  );
3737
3463
  },
3738
3464
  (err) => onMutationFailure(
3739
- err,
3740
3465
  optimisticId,
3741
- (error) => new MarkThreadAsResolvedError(error, {
3742
- roomId,
3743
- threadId
3744
- })
3466
+ { type: "MARK_THREAD_AS_RESOLVED_ERROR", roomId, threadId },
3467
+ err
3745
3468
  )
3746
3469
  );
3747
3470
  },
@@ -3772,12 +3495,9 @@ function useMarkRoomThreadAsUnresolved(roomId) {
3772
3495
  );
3773
3496
  },
3774
3497
  (err) => onMutationFailure(
3775
- err,
3776
3498
  optimisticId,
3777
- (error) => new MarkThreadAsUnresolvedError(error, {
3778
- roomId,
3779
- threadId
3780
- })
3499
+ { type: "MARK_THREAD_AS_UNRESOLVED_ERROR", roomId, threadId },
3500
+ err
3781
3501
  )
3782
3502
  );
3783
3503
  },
@@ -3838,6 +3558,7 @@ function useRoomNotificationSettings() {
3838
3558
  }, [settings, updateRoomNotificationSettings]);
3839
3559
  }
3840
3560
  function useRoomNotificationSettingsSuspense() {
3561
+ ensureNotServerSide();
3841
3562
  const client = useClient();
3842
3563
  const store = getRoomExtrasForClient(client).store;
3843
3564
  const room = useRoom();
@@ -3902,6 +3623,7 @@ function useHistoryVersions() {
3902
3623
  return useSignal(store.outputs.versionsByRoomId.getOrCreate(room.id).signal);
3903
3624
  }
3904
3625
  function useHistoryVersionsSuspense() {
3626
+ ensureNotServerSide();
3905
3627
  const client = useClient();
3906
3628
  const room = useRoom();
3907
3629
  const store = getRoomExtrasForClient(client).store;
@@ -3927,24 +3649,15 @@ function useUpdateRoomNotificationSettings() {
3927
3649
  store.updateRoomNotificationSettings(room.id, optimisticId, settings2);
3928
3650
  },
3929
3651
  (err) => onMutationFailure(
3930
- err,
3931
3652
  optimisticId,
3932
- (error) => new UpdateNotificationSettingsError(error, {
3933
- roomId: room.id
3934
- })
3653
+ { type: "UPDATE_NOTIFICATION_SETTINGS_ERROR", roomId: room.id },
3654
+ err
3935
3655
  )
3936
3656
  );
3937
3657
  },
3938
3658
  [client, room]
3939
3659
  );
3940
3660
  }
3941
- function ensureNotServerSide() {
3942
- if (typeof window === "undefined") {
3943
- throw new Error(
3944
- "You cannot use the Suspense version of this hook on the server side. Make sure to only call them on the client side.\nFor tips, see https://liveblocks.io/docs/api-reference/liveblocks-react#suspense-avoid-ssr"
3945
- );
3946
- }
3947
- }
3948
3661
  function useSuspendUntilPresenceReady() {
3949
3662
  ensureNotServerSide();
3950
3663
  const room = useRoom();
@@ -3993,6 +3706,7 @@ function useStorageStatusSuspense(options) {
3993
3706
  return useStorageStatus(options);
3994
3707
  }
3995
3708
  function useThreadsSuspense(options = {}) {
3709
+ ensureNotServerSide();
3996
3710
  const client = useClient();
3997
3711
  const room = useRoom();
3998
3712
  const { store } = getRoomExtrasForClient(client);
@@ -4136,9 +3850,6 @@ export {
4136
3850
  useDeleteInboxNotification,
4137
3851
  useUnreadInboxNotificationsCount,
4138
3852
  useUnreadInboxNotificationsCountSuspense,
4139
- useChannelsNotificationSettings,
4140
- useChannelsNotificationSettingsSuspense,
4141
- useUpdateChannelsNotificationSettings,
4142
3853
  useRoomInfo,
4143
3854
  useRoomInfoSuspense,
4144
3855
  _useInboxNotificationThread,
@@ -4147,7 +3858,7 @@ export {
4147
3858
  _useUserThreads_experimental,
4148
3859
  _useUserThreadsSuspense_experimental,
4149
3860
  useSyncStatus,
4150
- CreateThreadError,
3861
+ useErrorListener,
4151
3862
  useStatus,
4152
3863
  useReportTextEditor,
4153
3864
  useYjsProvider,
@@ -4158,14 +3869,12 @@ export {
4158
3869
  useStorageStatus,
4159
3870
  useBatch,
4160
3871
  useLostConnectionListener,
4161
- useErrorListener,
4162
3872
  useHistory,
4163
3873
  useUndo,
4164
3874
  useRedo,
4165
3875
  useCanUndo,
4166
3876
  useCanRedo,
4167
3877
  useOthersConnectionIds,
4168
- useCommentsErrorListener,
4169
3878
  useCreateRoomThread,
4170
3879
  useDeleteRoomThread,
4171
3880
  useEditRoomThreadMetadata,
@@ -4225,4 +3934,4 @@ export {
4225
3934
  _useStorageRoot,
4226
3935
  _useUpdateMyPresence
4227
3936
  };
4228
- //# sourceMappingURL=chunk-VX6Y3GQO.mjs.map
3937
+ //# sourceMappingURL=chunk-4KNGHD4I.mjs.map