@liveblocks/react 1.10.0 → 1.10.2

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.mjs CHANGED
@@ -5,7 +5,7 @@ import { detectDupes } from "@liveblocks/core";
5
5
 
6
6
  // src/version.ts
7
7
  var PKG_NAME = "@liveblocks/react";
8
- var PKG_VERSION = "1.10.0";
8
+ var PKG_VERSION = "1.10.2";
9
9
  var PKG_FORMAT = "esm";
10
10
 
11
11
  // src/ClientSideSuspense.tsx
@@ -40,6 +40,18 @@ function selectedInboxNotifications(state) {
40
40
  );
41
41
  }
42
42
 
43
+ // src/lib/retry-error.ts
44
+ var MAX_ERROR_RETRY_COUNT = 5;
45
+ var ERROR_RETRY_INTERVAL = 5e3;
46
+ function retryError(action, retryCount) {
47
+ if (retryCount >= MAX_ERROR_RETRY_COUNT)
48
+ return;
49
+ const timeout = Math.pow(2, retryCount) * ERROR_RETRY_INTERVAL;
50
+ setTimeout(() => {
51
+ void action();
52
+ }, timeout);
53
+ }
54
+
43
55
  // src/shared.ts
44
56
  import { kInternal as kInternal2 } from "@liveblocks/core";
45
57
  import { useCallback as useCallback2, useContext as useContext2, useEffect as useEffect4 } from "react";
@@ -392,6 +404,15 @@ function createRoomContext(client, options) {
392
404
  React2.useEffect(() => {
393
405
  void getThreadsUpdates(room.id);
394
406
  }, [room.id]);
407
+ React2.useEffect(() => {
408
+ function handleIsOnline() {
409
+ void getThreadsUpdates(room.id);
410
+ }
411
+ window.addEventListener("online", handleIsOnline);
412
+ return () => {
413
+ window.removeEventListener("online", handleIsOnline);
414
+ };
415
+ }, [room.id]);
395
416
  React2.useEffect(() => {
396
417
  const pair = stableEnterRoom(roomId, frozenProps);
397
418
  setRoomLeavePair(pair);
@@ -771,7 +792,8 @@ function createRoomContext(client, options) {
771
792
  }
772
793
  throw innerError;
773
794
  }
774
- const requestsCache = /* @__PURE__ */ new Map();
795
+ const subscribersByQuery = /* @__PURE__ */ new Map();
796
+ const requestsByQuery = /* @__PURE__ */ new Map();
775
797
  const poller = makePoller(refreshThreadsAndNotifications);
776
798
  async function refreshThreadsAndNotifications() {
777
799
  const requests = [];
@@ -779,85 +801,43 @@ function createRoomContext(client, options) {
779
801
  const room = client.getRoom(roomId);
780
802
  if (room === null)
781
803
  return;
782
- const notificationSettingsQuery = makeNotificationSettingsQueryKey(
783
- room.id
784
- );
785
- if (requestsCache.has(notificationSettingsQuery)) {
786
- requests.push(
787
- room[kInternal].notifications.getRoomNotificationSettings().then((settings) => {
788
- store.updateRoomInboxNotificationSettings(
789
- room.id,
790
- settings,
791
- notificationSettingsQuery
792
- );
793
- }).catch(() => {
794
- })
795
- );
796
- }
797
- const lastRequestedAt = lastRequestedAtByRoom.get(room.id);
798
- if (lastRequestedAt === void 0)
799
- return;
800
- requests.push(
801
- room[kInternal].comments.getThreads({ since: lastRequestedAt }).then((result) => {
802
- store.updateThreadsAndNotifications(
803
- result.threads,
804
- result.inboxNotifications,
805
- result.deletedThreads,
806
- result.deletedInboxNotifications
807
- );
808
- const room2 = client.getRoom(roomId);
809
- if (room2 === null)
810
- return;
811
- lastRequestedAtByRoom.set(room2.id, result.meta.requestedAt);
812
- }).catch(() => {
813
- })
814
- );
804
+ requests.push(getThreadsUpdates(room.id));
815
805
  });
816
806
  await Promise.allSettled(requests);
817
807
  }
818
808
  function incrementQuerySubscribers(queryKey) {
819
- const requestCache = requestsCache.get(queryKey);
820
- if (requestCache === void 0) {
821
- console2.warn(
822
- `Internal unexpected behavior. Cannot increase subscriber count for query "${queryKey}"`
823
- );
824
- return;
825
- }
826
- requestCache.subscribers++;
809
+ const subscribers = subscribersByQuery.get(queryKey) ?? 0;
810
+ subscribersByQuery.set(queryKey, subscribers + 1);
827
811
  poller.start(POLLING_INTERVAL);
828
812
  }
829
813
  function decrementQuerySubscribers(queryKey) {
830
- const requestCache = requestsCache.get(queryKey);
831
- if (requestCache === void 0 || requestCache.subscribers <= 0) {
814
+ const subscribers = subscribersByQuery.get(queryKey);
815
+ if (subscribers === void 0 || subscribers <= 0) {
832
816
  console2.warn(
833
817
  `Internal unexpected behavior. Cannot decrease subscriber count for query "${queryKey}"`
834
818
  );
835
819
  return;
836
820
  }
837
- requestCache.subscribers--;
821
+ subscribersByQuery.set(queryKey, subscribers - 1);
838
822
  let totalSubscribers = 0;
839
- for (const requestCache2 of requestsCache.values()) {
840
- totalSubscribers += requestCache2.subscribers;
823
+ for (const subscribers2 of subscribersByQuery.values()) {
824
+ totalSubscribers += subscribers2;
841
825
  }
842
826
  if (totalSubscribers <= 0) {
843
827
  poller.stop();
844
828
  }
845
829
  }
846
- async function getThreadsAndInboxNotifications(room, queryKey, options2) {
847
- const requestInfo = requestsCache.get(queryKey);
848
- if (requestInfo !== void 0) {
849
- return requestInfo.promise;
850
- }
851
- const promise = room[kInternal].comments.getThreads(options2);
852
- requestsCache.set(queryKey, {
853
- promise,
854
- subscribers: 0
855
- });
830
+ async function getThreadsAndInboxNotifications(room, queryKey, options2, { retryCount } = { retryCount: 0 }) {
831
+ const existingRequest = requestsByQuery.get(queryKey);
832
+ if (existingRequest !== void 0)
833
+ return existingRequest;
834
+ const request = room[kInternal].comments.getThreads(options2);
835
+ requestsByQuery.set(queryKey, request);
856
836
  store.setQueryState(queryKey, {
857
837
  isLoading: true
858
838
  });
859
839
  try {
860
- const result = await promise;
840
+ const result = await request;
861
841
  store.updateThreadsAndNotifications(
862
842
  result.threads,
863
843
  result.inboxNotifications,
@@ -869,17 +849,24 @@ function createRoomContext(client, options) {
869
849
  if (lastRequestedAt === void 0 || lastRequestedAt > result.meta.requestedAt) {
870
850
  lastRequestedAtByRoom.set(room.id, result.meta.requestedAt);
871
851
  }
852
+ poller.start(POLLING_INTERVAL);
872
853
  } catch (err) {
854
+ requestsByQuery.delete(queryKey);
855
+ retryError(() => {
856
+ void getThreadsAndInboxNotifications(room, queryKey, options2, {
857
+ retryCount: retryCount + 1
858
+ });
859
+ }, retryCount);
873
860
  store.setQueryState(queryKey, {
874
861
  isLoading: false,
875
862
  error: err
876
863
  });
864
+ return;
877
865
  }
878
- poller.start(POLLING_INTERVAL);
879
866
  }
880
867
  const DEFAULT_DEDUPING_INTERVAL = 2e3;
881
868
  const lastRequestedAtByRoom = /* @__PURE__ */ new Map();
882
- let isFetchingThreadsUpdates = false;
869
+ const requestStatusByRoom = /* @__PURE__ */ new Map();
883
870
  async function getThreadsUpdates(roomId) {
884
871
  const room = client.getRoom(roomId);
885
872
  if (room === null)
@@ -887,13 +874,14 @@ function createRoomContext(client, options) {
887
874
  const since = lastRequestedAtByRoom.get(room.id);
888
875
  if (since === void 0)
889
876
  return;
890
- if (isFetchingThreadsUpdates)
877
+ const isFetchingThreadsUpdates = requestStatusByRoom.get(room.id) ?? false;
878
+ if (isFetchingThreadsUpdates === true)
891
879
  return;
892
880
  try {
893
- isFetchingThreadsUpdates = true;
881
+ requestStatusByRoom.set(room.id, true);
894
882
  const updates = await room[kInternal].comments.getThreads({ since });
895
883
  setTimeout(() => {
896
- isFetchingThreadsUpdates = false;
884
+ requestStatusByRoom.set(room.id, false);
897
885
  }, DEFAULT_DEDUPING_INTERVAL);
898
886
  store.updateThreadsAndNotifications(
899
887
  updates.threads,
@@ -903,7 +891,8 @@ function createRoomContext(client, options) {
903
891
  );
904
892
  lastRequestedAtByRoom.set(room.id, updates.meta.requestedAt);
905
893
  } catch (err) {
906
- isFetchingThreadsUpdates = false;
894
+ requestStatusByRoom.set(room.id, false);
895
+ return;
907
896
  }
908
897
  }
909
898
  function useThreads(options2 = { query: { metadata: {} } }) {
@@ -1560,37 +1549,37 @@ function createRoomContext(client, options) {
1560
1549
  function makeNotificationSettingsQueryKey(roomId) {
1561
1550
  return `${roomId}:NOTIFICATION_SETTINGS`;
1562
1551
  }
1563
- async function getInboxNotificationSettings(room, queryKey) {
1564
- const requestInfo = requestsCache.get(queryKey);
1565
- if (requestInfo !== void 0) {
1566
- return requestInfo.promise;
1567
- }
1568
- const promise = room[kInternal].notifications.getRoomNotificationSettings();
1569
- requestsCache.set(queryKey, {
1570
- promise,
1571
- subscribers: 0
1572
- });
1573
- store.setQueryState(queryKey, {
1574
- isLoading: true
1575
- });
1552
+ async function getInboxNotificationSettings(room, queryKey, { retryCount } = { retryCount: 0 }) {
1553
+ const existingRequest = requestsByQuery.get(queryKey);
1554
+ if (existingRequest !== void 0)
1555
+ return existingRequest;
1576
1556
  try {
1577
- const settings = await promise;
1557
+ const request = room[kInternal].notifications.getRoomNotificationSettings();
1558
+ requestsByQuery.set(queryKey, request);
1559
+ store.setQueryState(queryKey, {
1560
+ isLoading: true
1561
+ });
1562
+ const settings = await request;
1578
1563
  store.updateRoomInboxNotificationSettings(room.id, settings, queryKey);
1579
1564
  } catch (err) {
1565
+ requestsByQuery.delete(queryKey);
1566
+ retryError(() => {
1567
+ void getInboxNotificationSettings(room, queryKey, {
1568
+ retryCount: retryCount + 1
1569
+ });
1570
+ }, retryCount);
1580
1571
  store.setQueryState(queryKey, {
1581
1572
  isLoading: false,
1582
1573
  error: err
1583
1574
  });
1575
+ return;
1584
1576
  }
1585
- poller.start(POLLING_INTERVAL);
1586
1577
  }
1587
1578
  function useRoomNotificationSettings() {
1588
1579
  const room = useRoom();
1589
1580
  React2.useEffect(() => {
1590
1581
  const queryKey = makeNotificationSettingsQueryKey(room.id);
1591
1582
  void getInboxNotificationSettings(room, queryKey);
1592
- incrementQuerySubscribers(queryKey);
1593
- return () => decrementQuerySubscribers(queryKey);
1594
1583
  }, [room]);
1595
1584
  const updateRoomNotificationSettings = useUpdateRoomNotificationSettings();
1596
1585
  const selector = React2.useCallback(
@@ -1630,11 +1619,6 @@ function createRoomContext(client, options) {
1630
1619
  if (query.error) {
1631
1620
  throw query.error;
1632
1621
  }
1633
- React2.useEffect(() => {
1634
- const queryKey2 = makeNotificationSettingsQueryKey(room.id);
1635
- incrementQuerySubscribers(queryKey2);
1636
- return () => decrementQuerySubscribers(queryKey2);
1637
- }, [room]);
1638
1622
  const selector = React2.useCallback(
1639
1623
  (state) => {
1640
1624
  return {
@@ -1977,8 +1961,8 @@ function createLiveblocksContext(client) {
1977
1961
  poller.stop();
1978
1962
  }
1979
1963
  }
1980
- async function fetchInboxNotifications() {
1981
- if (fetchInboxNotificationsRequest) {
1964
+ async function fetchInboxNotifications({ retryCount } = { retryCount: 0 }) {
1965
+ if (fetchInboxNotificationsRequest !== null) {
1982
1966
  return fetchInboxNotificationsRequest;
1983
1967
  }
1984
1968
  store.setQueryState(INBOX_NOTIFICATIONS_QUERY, {
@@ -1997,7 +1981,14 @@ function createLiveblocksContext(client) {
1997
1981
  if (lastRequestedAt === void 0 || lastRequestedAt > result.meta.requestedAt) {
1998
1982
  lastRequestedAt = result.meta.requestedAt;
1999
1983
  }
1984
+ poller.start(POLLING_INTERVAL2);
2000
1985
  } catch (er) {
1986
+ fetchInboxNotificationsRequest = null;
1987
+ retryError(() => {
1988
+ void fetchInboxNotifications({
1989
+ retryCount: retryCount + 1
1990
+ });
1991
+ }, retryCount);
2001
1992
  store.setQueryState(INBOX_NOTIFICATIONS_QUERY, {
2002
1993
  isLoading: false,
2003
1994
  error: er
@@ -2048,6 +2039,9 @@ function createLiveblocksContext(client) {
2048
2039
  if (query === void 0 || query.isLoading) {
2049
2040
  throw fetchInboxNotifications();
2050
2041
  }
2042
+ if (query.error !== void 0) {
2043
+ throw query.error;
2044
+ }
2051
2045
  React3.useEffect(() => {
2052
2046
  incrementInboxNotificationsSubscribers();
2053
2047
  return () => {