@liveblocks/react 2.11.1 → 2.12.0

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.
Files changed (33) hide show
  1. package/dist/_private.d.mts +8 -3
  2. package/dist/_private.d.ts +8 -3
  3. package/dist/_private.js +20 -4
  4. package/dist/_private.js.map +1 -1
  5. package/dist/_private.mjs +18 -2
  6. package/dist/_private.mjs.map +1 -1
  7. package/dist/{chunk-OVU4MAZA.js → chunk-6WXPZPS2.js} +2 -2
  8. package/dist/{chunk-A7GJNN4L.mjs → chunk-CX62YECU.mjs} +60 -15
  9. package/dist/chunk-CX62YECU.mjs.map +1 -0
  10. package/dist/{chunk-3MM4G6XB.js → chunk-IACZPXTY.js} +68 -23
  11. package/dist/chunk-IACZPXTY.js.map +1 -0
  12. package/dist/{chunk-JF4QXLDE.mjs → chunk-IX5CKQGZ.mjs} +2 -2
  13. package/dist/index.d.mts +2 -2
  14. package/dist/index.d.ts +2 -2
  15. package/dist/index.js +6 -4
  16. package/dist/index.js.map +1 -1
  17. package/dist/index.mjs +4 -2
  18. package/dist/index.mjs.map +1 -1
  19. package/dist/{liveblocks-SAVcXwMX.d.mts → liveblocks-1ujmr05d.d.mts} +53 -7
  20. package/dist/{liveblocks-SAVcXwMX.d.ts → liveblocks-1ujmr05d.d.ts} +53 -7
  21. package/dist/{suspense-W7Cp9ygn.d.ts → suspense-560_K0iP.d.ts} +5 -1
  22. package/dist/{suspense-vGJE9Mgq.d.mts → suspense-TeBnnKGw.d.mts} +5 -1
  23. package/dist/suspense.d.mts +2 -2
  24. package/dist/suspense.d.ts +2 -2
  25. package/dist/suspense.js +6 -4
  26. package/dist/suspense.js.map +1 -1
  27. package/dist/suspense.mjs +4 -2
  28. package/dist/suspense.mjs.map +1 -1
  29. package/package.json +3 -3
  30. package/dist/chunk-3MM4G6XB.js.map +0 -1
  31. package/dist/chunk-A7GJNN4L.mjs.map +0 -1
  32. /package/dist/{chunk-OVU4MAZA.js.map → chunk-6WXPZPS2.js.map} +0 -0
  33. /package/dist/{chunk-JF4QXLDE.mjs.map → chunk-IX5CKQGZ.mjs.map} +0 -0
@@ -32,6 +32,7 @@ var _withselectorjs = require('use-sync-external-store/shim/with-selector.js');
32
32
  var SECONDS = 1e3;
33
33
  var MINUTES = 60 * SECONDS;
34
34
  var config = {
35
+ SMOOTH_DELAY: 1 * SECONDS,
35
36
  NOTIFICATIONS_POLL_INTERVAL: 1 * MINUTES,
36
37
  NOTIFICATIONS_MAX_STALE_TIME: 5 * SECONDS,
37
38
  ROOM_THREADS_POLL_INTERVAL: 5 * MINUTES,
@@ -503,6 +504,7 @@ var UmbrellaStore = class {
503
504
  // Room notification settings
504
505
  this._roomNotificationSettings = /* @__PURE__ */ new Map();
505
506
  this._client = client[_core.kInternal].as();
507
+ this._syncSource = this._client[_core.kInternal].createSyncSource();
506
508
  const inboxFetcher = async (cursor) => {
507
509
  const result = await this._client.getInboxNotifications({ cursor });
508
510
  this.updateThreadsAndNotifications(
@@ -651,12 +653,6 @@ var UmbrellaStore = class {
651
653
  versions: Object.values(_nullishCoalesce(this.get().versionsByRoomId[roomId], () => ( {})))
652
654
  };
653
655
  }
654
- /**
655
- * @private Only used by the E2E test suite.
656
- */
657
- _hasOptimisticUpdates() {
658
- return this._store.get().optimisticUpdates.length > 0;
659
- }
660
656
  subscribe(callback) {
661
657
  return this._store.subscribe(callback);
662
658
  }
@@ -703,10 +699,13 @@ var UmbrellaStore = class {
703
699
  });
704
700
  }
705
701
  updateOptimisticUpdatesCache(mapFn) {
706
- this._store.set((state) => ({
707
- ...state,
708
- optimisticUpdates: mapFn(state.optimisticUpdates)
709
- }));
702
+ this._store.set((state) => {
703
+ const optimisticUpdates = mapFn(state.optimisticUpdates);
704
+ this._syncSource.setSyncStatus(
705
+ optimisticUpdates.length > 0 ? "synchronizing" : "synchronized"
706
+ );
707
+ return { ...state, optimisticUpdates };
708
+ });
710
709
  }
711
710
  // ---------------------------------------------------------------------------------- }}}
712
711
  /** @internal - Only call this method from unit tests. */
@@ -1952,18 +1951,23 @@ function useRoomInfoSuspense_withClient(client, roomId) {
1952
1951
  }
1953
1952
  function createSharedContext(client) {
1954
1953
  const useClient2 = () => client;
1954
+ function useSyncStatus2(options) {
1955
+ return useSyncStatus_withClient(client, options);
1956
+ }
1955
1957
  return {
1956
1958
  classic: {
1957
1959
  useClient: useClient2,
1958
1960
  useUser: (userId) => useUser_withClient(client, userId),
1959
1961
  useRoomInfo: (roomId) => useRoomInfo_withClient(client, roomId),
1960
- useIsInsideRoom
1962
+ useIsInsideRoom,
1963
+ useSyncStatus: useSyncStatus2
1961
1964
  },
1962
1965
  suspense: {
1963
1966
  useClient: useClient2,
1964
1967
  useUser: (userId) => useUserSuspense_withClient(client, userId),
1965
1968
  useRoomInfo: (roomId) => useRoomInfoSuspense_withClient(client, roomId),
1966
- useIsInsideRoom
1969
+ useIsInsideRoom,
1970
+ useSyncStatus: useSyncStatus2
1967
1971
  }
1968
1972
  };
1969
1973
  }
@@ -1995,6 +1999,7 @@ function LiveblocksProvider(props) {
1995
1999
  polyfills: useInitial(o.polyfills),
1996
2000
  unstable_fallbackToHTTP: useInitial(o.unstable_fallbackToHTTP),
1997
2001
  unstable_streamData: useInitial(o.unstable_streamData),
2002
+ preventUnsavedChanges: useInitial(o.preventUnsavedChanges),
1998
2003
  authEndpoint: useInitialUnlessFunction(o.authEndpoint),
1999
2004
  resolveMentionSuggestions: useInitialUnlessFunction(
2000
2005
  o.resolveMentionSuggestions
@@ -2118,6 +2123,46 @@ var _useUser = useUser;
2118
2123
  var _useUserSuspense = useUserSuspense;
2119
2124
  var _useUserThreads_experimental = useUserThreads_experimental;
2120
2125
  var _useUserThreadsSuspense_experimental = useUserThreadsSuspense_experimental;
2126
+ function useSyncStatus_withClient(client, options) {
2127
+ const smooth = useInitial(_nullishCoalesce(_optionalChain([options, 'optionalAccess', _11 => _11.smooth]), () => ( false)));
2128
+ if (smooth) {
2129
+ return useSyncStatusSmooth_withClient(client);
2130
+ } else {
2131
+ return useSyncStatusImmediate_withClient(client);
2132
+ }
2133
+ }
2134
+ function useSyncStatusImmediate_withClient(client) {
2135
+ return _indexjs.useSyncExternalStore.call(void 0,
2136
+ client.events.syncStatus.subscribe,
2137
+ client.getSyncStatus,
2138
+ client.getSyncStatus
2139
+ );
2140
+ }
2141
+ function useSyncStatusSmooth_withClient(client) {
2142
+ const getter = client.getSyncStatus;
2143
+ const [status, setStatus] = React.default.useState(getter);
2144
+ const oldStatus = useLatest(getter());
2145
+ React.default.useEffect(() => {
2146
+ let timeoutId;
2147
+ const unsub = client.events.syncStatus.subscribe(() => {
2148
+ const newStatus = getter();
2149
+ if (oldStatus.current === "synchronizing" && newStatus === "synchronized") {
2150
+ timeoutId = setTimeout(() => setStatus(newStatus), config.SMOOTH_DELAY);
2151
+ } else {
2152
+ clearTimeout(timeoutId);
2153
+ setStatus(newStatus);
2154
+ }
2155
+ });
2156
+ return () => {
2157
+ clearTimeout(timeoutId);
2158
+ unsub();
2159
+ };
2160
+ }, [client, getter, oldStatus]);
2161
+ return status;
2162
+ }
2163
+ function useSyncStatus(options) {
2164
+ return useSyncStatus_withClient(useClient(), options);
2165
+ }
2121
2166
 
2122
2167
  // src/types/errors.ts
2123
2168
  var CreateThreadError = class extends Error {
@@ -2265,7 +2310,6 @@ function useScrollToCommentOnLoadEffect(shouldScrollOnLoad, state) {
2265
2310
  }
2266
2311
 
2267
2312
  // src/room.tsx
2268
- var SMOOTH_DELAY = 1e3;
2269
2313
  var noop3 = () => {
2270
2314
  };
2271
2315
  var identity2 = (x) => x;
@@ -2333,7 +2377,7 @@ function getCurrentUserId(room) {
2333
2377
  }
2334
2378
  function handleApiError(err) {
2335
2379
  const message = `Request failed with status ${err.status}: ${err.message}`;
2336
- if (_optionalChain([err, 'access', _11 => _11.details, 'optionalAccess', _12 => _12.error]) === "FORBIDDEN") {
2380
+ if (_optionalChain([err, 'access', _12 => _12.details, 'optionalAccess', _13 => _13.error]) === "FORBIDDEN") {
2337
2381
  const detailedMessage = [message, err.details.suggestion, err.details.docs].filter(Boolean).join("\n");
2338
2382
  _core.console.error(detailedMessage);
2339
2383
  }
@@ -2673,7 +2717,7 @@ function useStatus() {
2673
2717
  return useSyncExternalStore2(subscribe, getSnapshot, getServerSnapshot);
2674
2718
  }
2675
2719
  function useStorageStatus(options) {
2676
- const smooth = useInitial(_nullishCoalesce(_optionalChain([options, 'optionalAccess', _13 => _13.smooth]), () => ( false)));
2720
+ const smooth = useInitial(_nullishCoalesce(_optionalChain([options, 'optionalAccess', _14 => _14.smooth]), () => ( false)));
2677
2721
  if (smooth) {
2678
2722
  return useStorageStatusSmooth();
2679
2723
  } else {
@@ -2695,7 +2739,7 @@ function useStorageStatusSmooth() {
2695
2739
  let timeoutId;
2696
2740
  const unsub = room.events.storageStatus.subscribe((newStatus) => {
2697
2741
  if (oldStatus.current === "synchronizing" && newStatus === "synchronized") {
2698
- timeoutId = setTimeout(() => setStatus(newStatus), SMOOTH_DELAY);
2742
+ timeoutId = setTimeout(() => setStatus(newStatus), config.SMOOTH_DELAY);
2699
2743
  } else {
2700
2744
  clearTimeout(timeoutId);
2701
2745
  setStatus(newStatus);
@@ -3013,7 +3057,7 @@ function useCreateThread() {
3013
3057
  thread: newThread,
3014
3058
  roomId: room.id
3015
3059
  });
3016
- const attachmentIds = _optionalChain([attachments, 'optionalAccess', _14 => _14.map, 'call', _15 => _15((attachment) => attachment.id)]);
3060
+ const attachmentIds = _optionalChain([attachments, 'optionalAccess', _15 => _15.map, 'call', _16 => _16((attachment) => attachment.id)]);
3017
3061
  room.createThread({ threadId, commentId, body, metadata, attachmentIds }).then(
3018
3062
  (thread) => {
3019
3063
  store.createThread(optimisticUpdateId, thread);
@@ -3043,7 +3087,7 @@ function useDeleteThread() {
3043
3087
  const { store, onMutationFailure } = getRoomExtrasForClient(client);
3044
3088
  const userId = getCurrentUserId(room);
3045
3089
  const existing = store.getFullState().threadsDB.get(threadId);
3046
- if (_optionalChain([existing, 'optionalAccess', _16 => _16.comments, 'optionalAccess', _17 => _17[0], 'optionalAccess', _18 => _18.userId]) !== userId) {
3090
+ if (_optionalChain([existing, 'optionalAccess', _17 => _17.comments, 'optionalAccess', _18 => _18[0], 'optionalAccess', _19 => _19.userId]) !== userId) {
3047
3091
  throw new Error("Only the thread creator can delete the thread");
3048
3092
  }
3049
3093
  const optimisticUpdateId = store.addOptimisticUpdate({
@@ -3131,7 +3175,7 @@ function useCreateComment() {
3131
3175
  type: "create-comment",
3132
3176
  comment
3133
3177
  });
3134
- const attachmentIds = _optionalChain([attachments, 'optionalAccess', _19 => _19.map, 'call', _20 => _20((attachment) => attachment.id)]);
3178
+ const attachmentIds = _optionalChain([attachments, 'optionalAccess', _20 => _20.map, 'call', _21 => _21((attachment) => attachment.id)]);
3135
3179
  room.createComment({ threadId, commentId, body, attachmentIds }).then(
3136
3180
  (newComment) => {
3137
3181
  store.createComment(newComment, optimisticUpdateId);
@@ -3184,7 +3228,7 @@ function useEditComment() {
3184
3228
  attachments: _nullishCoalesce(attachments, () => ( []))
3185
3229
  }
3186
3230
  });
3187
- const attachmentIds = _optionalChain([attachments, 'optionalAccess', _21 => _21.map, 'call', _22 => _22((attachment) => attachment.id)]);
3231
+ const attachmentIds = _optionalChain([attachments, 'optionalAccess', _22 => _22.map, 'call', _23 => _23((attachment) => attachment.id)]);
3188
3232
  room.editComment({ threadId, commentId, body, attachmentIds }).then(
3189
3233
  (editedComment) => {
3190
3234
  store.editComment(threadId, optimisticUpdateId, editedComment);
@@ -3687,7 +3731,7 @@ function useThreadsSuspense(options = {
3687
3731
  return result;
3688
3732
  }
3689
3733
  function selectorFor_useAttachmentUrl(state) {
3690
- if (state === void 0 || _optionalChain([state, 'optionalAccess', _23 => _23.isLoading])) {
3734
+ if (state === void 0 || _optionalChain([state, 'optionalAccess', _24 => _24.isLoading])) {
3691
3735
  return _nullishCoalesce(state, () => ( { isLoading: true }));
3692
3736
  }
3693
3737
  if (state.error) {
@@ -3867,5 +3911,6 @@ var _useUpdateMyPresence = useUpdateMyPresence;
3867
3911
 
3868
3912
 
3869
3913
 
3870
- exports.RoomContext = RoomContext; exports.ClientContext = ClientContext; exports.getUmbrellaStoreForClient = getUmbrellaStoreForClient; exports.useClient = useClient; exports.LiveblocksProvider = LiveblocksProvider; exports.createLiveblocksContext = createLiveblocksContext; exports.useInboxNotifications = useInboxNotifications; exports.useInboxNotificationsSuspense = useInboxNotificationsSuspense; exports.useMarkAllInboxNotificationsAsRead = useMarkAllInboxNotificationsAsRead; exports.useMarkInboxNotificationAsRead = useMarkInboxNotificationAsRead; exports.useDeleteAllInboxNotifications = useDeleteAllInboxNotifications; exports.useDeleteInboxNotification = useDeleteInboxNotification; exports.useUnreadInboxNotificationsCount = useUnreadInboxNotificationsCount; exports.useUnreadInboxNotificationsCountSuspense = useUnreadInboxNotificationsCountSuspense; exports.useRoomInfo = useRoomInfo; exports.useRoomInfoSuspense = useRoomInfoSuspense; exports._useInboxNotificationThread = _useInboxNotificationThread; exports._useUser = _useUser; exports._useUserSuspense = _useUserSuspense; exports._useUserThreads_experimental = _useUserThreads_experimental; exports._useUserThreadsSuspense_experimental = _useUserThreadsSuspense_experimental; exports.CreateThreadError = CreateThreadError; exports.useStatus = useStatus; exports.useStorageStatus = useStorageStatus; exports.useBatch = useBatch; exports.useLostConnectionListener = useLostConnectionListener; exports.useErrorListener = useErrorListener; exports.useHistory = useHistory; exports.useUndo = useUndo; exports.useRedo = useRedo; exports.useCanUndo = useCanUndo; exports.useCanRedo = useCanRedo; exports.useOthersConnectionIds = useOthersConnectionIds; exports.useCommentsErrorListener = useCommentsErrorListener; exports.useCreateComment = useCreateComment; exports.useEditComment = useEditComment; exports.useDeleteComment = useDeleteComment; exports.useRemoveReaction = useRemoveReaction; exports.useMarkThreadAsRead = useMarkThreadAsRead; exports.useMarkThreadAsResolved = useMarkThreadAsResolved; exports.useMarkThreadAsUnresolved = useMarkThreadAsUnresolved; exports.useThreadSubscription = useThreadSubscription; exports.useHistoryVersionData = useHistoryVersionData; exports.useUpdateRoomNotificationSettings = useUpdateRoomNotificationSettings; exports.useOthersConnectionIdsSuspense = useOthersConnectionIdsSuspense; exports.useStorageStatusSuspense = useStorageStatusSuspense; exports.useAttachmentUrl = useAttachmentUrl; exports.useAttachmentUrlSuspense = useAttachmentUrlSuspense; exports.createRoomContext = createRoomContext; exports._RoomProvider = _RoomProvider; exports._useBroadcastEvent = _useBroadcastEvent; exports._useOthersListener = _useOthersListener; exports._useRoom = _useRoom; exports._useIsInsideRoom = _useIsInsideRoom; exports._useAddReaction = _useAddReaction; exports._useMutation = _useMutation; exports._useCreateThread = _useCreateThread; exports._useDeleteThread = _useDeleteThread; exports._useEditThreadMetadata = _useEditThreadMetadata; exports._useEventListener = _useEventListener; exports._useMyPresence = _useMyPresence; exports._useOthersMapped = _useOthersMapped; exports._useOthersMappedSuspense = _useOthersMappedSuspense; exports._useThreads = _useThreads; exports._useThreadsSuspense = _useThreadsSuspense; exports._useRoomNotificationSettings = _useRoomNotificationSettings; exports._useRoomNotificationSettingsSuspense = _useRoomNotificationSettingsSuspense; exports._useHistoryVersions = _useHistoryVersions; exports._useHistoryVersionsSuspense = _useHistoryVersionsSuspense; exports._useOther = _useOther; exports._useOthers = _useOthers; exports._useOtherSuspense = _useOtherSuspense; exports._useOthersSuspense = _useOthersSuspense; exports._useStorage = _useStorage; exports._useStorageSuspense = _useStorageSuspense; exports._useSelf = _useSelf; exports._useSelfSuspense = _useSelfSuspense; exports._useStorageRoot = _useStorageRoot; exports._useUpdateMyPresence = _useUpdateMyPresence;
3871
- //# sourceMappingURL=chunk-3MM4G6XB.js.map
3914
+
3915
+ exports.RoomContext = RoomContext; exports.ClientContext = ClientContext; exports.getUmbrellaStoreForClient = getUmbrellaStoreForClient; exports.useClient = useClient; exports.LiveblocksProvider = LiveblocksProvider; exports.createLiveblocksContext = createLiveblocksContext; exports.useInboxNotifications = useInboxNotifications; exports.useInboxNotificationsSuspense = useInboxNotificationsSuspense; exports.useMarkAllInboxNotificationsAsRead = useMarkAllInboxNotificationsAsRead; exports.useMarkInboxNotificationAsRead = useMarkInboxNotificationAsRead; exports.useDeleteAllInboxNotifications = useDeleteAllInboxNotifications; exports.useDeleteInboxNotification = useDeleteInboxNotification; exports.useUnreadInboxNotificationsCount = useUnreadInboxNotificationsCount; exports.useUnreadInboxNotificationsCountSuspense = useUnreadInboxNotificationsCountSuspense; exports.useRoomInfo = useRoomInfo; exports.useRoomInfoSuspense = useRoomInfoSuspense; exports._useInboxNotificationThread = _useInboxNotificationThread; exports._useUser = _useUser; exports._useUserSuspense = _useUserSuspense; exports._useUserThreads_experimental = _useUserThreads_experimental; exports._useUserThreadsSuspense_experimental = _useUserThreadsSuspense_experimental; exports.useSyncStatus = useSyncStatus; exports.CreateThreadError = CreateThreadError; exports.useStatus = useStatus; exports.useStorageStatus = useStorageStatus; exports.useBatch = useBatch; exports.useLostConnectionListener = useLostConnectionListener; exports.useErrorListener = useErrorListener; exports.useHistory = useHistory; exports.useUndo = useUndo; exports.useRedo = useRedo; exports.useCanUndo = useCanUndo; exports.useCanRedo = useCanRedo; exports.useOthersConnectionIds = useOthersConnectionIds; exports.useCommentsErrorListener = useCommentsErrorListener; exports.useCreateComment = useCreateComment; exports.useEditComment = useEditComment; exports.useDeleteComment = useDeleteComment; exports.useRemoveReaction = useRemoveReaction; exports.useMarkThreadAsRead = useMarkThreadAsRead; exports.useMarkThreadAsResolved = useMarkThreadAsResolved; exports.useMarkThreadAsUnresolved = useMarkThreadAsUnresolved; exports.useThreadSubscription = useThreadSubscription; exports.useHistoryVersionData = useHistoryVersionData; exports.useUpdateRoomNotificationSettings = useUpdateRoomNotificationSettings; exports.useOthersConnectionIdsSuspense = useOthersConnectionIdsSuspense; exports.useStorageStatusSuspense = useStorageStatusSuspense; exports.useAttachmentUrl = useAttachmentUrl; exports.useAttachmentUrlSuspense = useAttachmentUrlSuspense; exports.createRoomContext = createRoomContext; exports._RoomProvider = _RoomProvider; exports._useBroadcastEvent = _useBroadcastEvent; exports._useOthersListener = _useOthersListener; exports._useRoom = _useRoom; exports._useIsInsideRoom = _useIsInsideRoom; exports._useAddReaction = _useAddReaction; exports._useMutation = _useMutation; exports._useCreateThread = _useCreateThread; exports._useDeleteThread = _useDeleteThread; exports._useEditThreadMetadata = _useEditThreadMetadata; exports._useEventListener = _useEventListener; exports._useMyPresence = _useMyPresence; exports._useOthersMapped = _useOthersMapped; exports._useOthersMappedSuspense = _useOthersMappedSuspense; exports._useThreads = _useThreads; exports._useThreadsSuspense = _useThreadsSuspense; exports._useRoomNotificationSettings = _useRoomNotificationSettings; exports._useRoomNotificationSettingsSuspense = _useRoomNotificationSettingsSuspense; exports._useHistoryVersions = _useHistoryVersions; exports._useHistoryVersionsSuspense = _useHistoryVersionsSuspense; exports._useOther = _useOther; exports._useOthers = _useOthers; exports._useOtherSuspense = _useOtherSuspense; exports._useOthersSuspense = _useOthersSuspense; exports._useStorage = _useStorage; exports._useStorageSuspense = _useStorageSuspense; exports._useSelf = _useSelf; exports._useSelfSuspense = _useSelfSuspense; exports._useStorageRoot = _useStorageRoot; exports._useUpdateMyPresence = _useUpdateMyPresence;
3916
+ //# sourceMappingURL=chunk-IACZPXTY.js.map