react-realtime-hooks 1.0.3 → 1.1.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.
package/dist/index.js CHANGED
@@ -6,6 +6,7 @@ import { useSyncExternalStore, useRef, useState, useEffect, useEffectEvent, useM
6
6
  var isWebSocketSupported = () => typeof WebSocket !== "undefined";
7
7
  var isEventSourceSupported = () => typeof EventSource !== "undefined";
8
8
  var hasNavigatorOnLineSupport = () => typeof navigator !== "undefined" && typeof navigator.onLine === "boolean";
9
+ var hasDocumentVisibilitySupport = () => typeof document !== "undefined" && typeof document.visibilityState === "string";
9
10
  var readOnlineStatus = (initialOnline = true) => {
10
11
  if (!hasNavigatorOnLineSupport()) {
11
12
  return {
@@ -18,6 +19,20 @@ var readOnlineStatus = (initialOnline = true) => {
18
19
  isSupported: true
19
20
  };
20
21
  };
22
+ var readPageVisibility = (initialVisible = true) => {
23
+ if (!hasDocumentVisibilitySupport()) {
24
+ return {
25
+ isVisible: initialVisible,
26
+ isSupported: false,
27
+ visibilityState: initialVisible ? "visible" : "hidden"
28
+ };
29
+ }
30
+ return {
31
+ isVisible: document.visibilityState === "visible",
32
+ isSupported: true,
33
+ visibilityState: document.visibilityState
34
+ };
35
+ };
21
36
 
22
37
  // src/hooks/useOnlineStatus.ts
23
38
  var subscribeToOnlineStatus = (onStoreChange) => {
@@ -70,6 +85,56 @@ var useOnlineStatus = (options = {}) => {
70
85
  ...transitions
71
86
  };
72
87
  };
88
+ var subscribeToPageVisibility = (onStoreChange) => {
89
+ if (typeof document === "undefined" || !hasDocumentVisibilitySupport()) {
90
+ return () => {
91
+ };
92
+ }
93
+ document.addEventListener("visibilitychange", onStoreChange);
94
+ return () => {
95
+ document.removeEventListener("visibilitychange", onStoreChange);
96
+ };
97
+ };
98
+ var createEmptyTransitionState2 = () => ({
99
+ lastChangedAt: null,
100
+ becameHiddenAt: null,
101
+ becameVisibleAt: null
102
+ });
103
+ var usePageVisibility = (options = {}) => {
104
+ const initialVisible = options.initialVisible ?? true;
105
+ const trackTransitions = options.trackTransitions ?? true;
106
+ const visibilityState = useSyncExternalStore(
107
+ subscribeToPageVisibility,
108
+ () => readPageVisibility(initialVisible).visibilityState,
109
+ () => initialVisible ? "visible" : "hidden"
110
+ );
111
+ const isVisible = visibilityState === "visible";
112
+ const previousVisibleRef = useRef(isVisible);
113
+ const [transitions, setTransitions] = useState(createEmptyTransitionState2);
114
+ useEffect(() => {
115
+ if (!trackTransitions) {
116
+ previousVisibleRef.current = isVisible;
117
+ setTransitions(createEmptyTransitionState2);
118
+ return;
119
+ }
120
+ if (previousVisibleRef.current === isVisible) {
121
+ return;
122
+ }
123
+ const changedAt = Date.now();
124
+ previousVisibleRef.current = isVisible;
125
+ setTransitions((current) => ({
126
+ lastChangedAt: changedAt,
127
+ becameHiddenAt: isVisible ? current.becameHiddenAt : changedAt,
128
+ becameVisibleAt: isVisible ? changedAt : current.becameVisibleAt
129
+ }));
130
+ }, [isVisible, trackTransitions]);
131
+ return {
132
+ isSupported: hasDocumentVisibilitySupport(),
133
+ isVisible,
134
+ visibilityState,
135
+ ...transitions
136
+ };
137
+ };
73
138
 
74
139
  // src/core/reconnect.ts
75
140
  var DEFAULT_RECONNECT_OPTIONS = {
@@ -486,11 +551,7 @@ var useHeartbeat = (options) => {
486
551
  generationRef.current += 1;
487
552
  intervalRef.current.cancel();
488
553
  timeoutRef.current.cancel();
489
- commitState((current) => ({
490
- ...current,
491
- hasTimedOut: false,
492
- isRunning: false
493
- }));
554
+ commitState(createInitialState2(false));
494
555
  };
495
556
  const beat = () => {
496
557
  if (!enabled) {
@@ -745,6 +806,7 @@ var useWebSocket = (options) => {
745
806
  const applyHeartbeatAction = useEffectEvent(
746
807
  (action, error, reconnectTrigger) => {
747
808
  heartbeat.stop();
809
+ options.onError?.(error);
748
810
  if (action === "none") {
749
811
  commitState((current) => ({
750
812
  ...current,
@@ -822,6 +884,7 @@ var useWebSocket = (options) => {
822
884
  suppressReconnectRef.current = true;
823
885
  reconnect.cancel();
824
886
  heartbeat.stop();
887
+ options.onError?.(parseError);
825
888
  commitState((current) => ({
826
889
  ...current,
827
890
  lastChangedAt: Date.now(),
@@ -835,6 +898,7 @@ var useWebSocket = (options) => {
835
898
  heartbeat.stop();
836
899
  commitState((current) => ({
837
900
  ...current,
901
+ lastChangedAt: Date.now(),
838
902
  lastError: event,
839
903
  status: "error"
840
904
  }));
@@ -1181,6 +1245,7 @@ var useEventSource = (options) => {
1181
1245
  suppressReconnectRef.current = true;
1182
1246
  reconnect.cancel();
1183
1247
  closeEventSource();
1248
+ options.onError?.(parseError);
1184
1249
  commitState((current) => ({
1185
1250
  ...current,
1186
1251
  lastChangedAt: Date.now(),
@@ -1393,6 +1458,6 @@ var useEventSource = (options) => {
1393
1458
  };
1394
1459
  };
1395
1460
 
1396
- export { useEventSource, useHeartbeat, useOnlineStatus, useReconnect, useWebSocket };
1461
+ export { useEventSource, useHeartbeat, useOnlineStatus, usePageVisibility, useReconnect, useWebSocket };
1397
1462
  //# sourceMappingURL=index.js.map
1398
1463
  //# sourceMappingURL=index.js.map