react-realtime-hooks 2.0.2 → 2.0.3

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/README.md CHANGED
@@ -8,6 +8,7 @@
8
8
  [![license](https://img.shields.io/npm/l/react-realtime-hooks)](https://github.com/volkov85/react-realtime-hooks/blob/main/LICENSE)
9
9
  [![TypeScript](https://img.shields.io/badge/TypeScript-typed-3178c6)](https://www.typescriptlang.org/)
10
10
  [![react](https://img.shields.io/badge/react-18%20%7C%2019-149eca)](https://www.npmjs.com/package/react)
11
+ [![React Doctor](https://www.react.doctor/share/badge?p=react-realtime-hooks&s=94&e=2&w=28&f=21)](https://www.react.doctor/share?p=react-realtime-hooks&s=94&e=2&w=28&f=21)
11
12
 
12
13
  Production-ready React hooks for WebSocket and SSE with auto-reconnect, heartbeat, typed connection state, and browser network awareness including page visibility and connection gating.
13
14
 
package/dist/index.cjs CHANGED
@@ -939,6 +939,7 @@ var useWebSocket = (options) => {
939
939
  [protocolsDependency]
940
940
  );
941
941
  const socketRef = react.useRef(null);
942
+ const detachSocketListenersRef = react.useRef(null);
942
943
  const socketKeyRef = react.useRef(null);
943
944
  const activeSocketEpochRef = react.useRef(null);
944
945
  const closingSocketEpochRef = react.useRef(null);
@@ -1051,6 +1052,10 @@ var useWebSocket = (options) => {
1051
1052
  socketKeyRef.current = null;
1052
1053
  activeSocketEpochRef.current = null;
1053
1054
  closingSocketEpochRef.current = config.trackClose ? socketEpoch : null;
1055
+ if (!config.trackClose) {
1056
+ detachSocketListenersRef.current?.();
1057
+ detachSocketListenersRef.current = null;
1058
+ }
1054
1059
  if (isSocketActive(socket2)) {
1055
1060
  socket2.close(config.code, config.reason);
1056
1061
  }
@@ -1162,6 +1167,8 @@ var useWebSocket = (options) => {
1162
1167
  if (!shouldHandleSocketClose(socketEpoch)) {
1163
1168
  return;
1164
1169
  }
1170
+ detachSocketListenersRef.current?.();
1171
+ detachSocketListenersRef.current = null;
1165
1172
  if (activeSocketEpochRef.current === socketEpoch) {
1166
1173
  socketRef.current = null;
1167
1174
  socketKeyRef.current = null;
@@ -1301,7 +1308,6 @@ var useWebSocket = (options) => {
1301
1308
  status: reconnect.status === "running" || reconnect.status === "scheduled" ? "reconnecting" : "connecting"
1302
1309
  }));
1303
1310
  let cancelled = false;
1304
- let detachListeners = null;
1305
1311
  queueMicrotask(() => {
1306
1312
  if (cancelled) {
1307
1313
  return;
@@ -1315,6 +1321,8 @@ var useWebSocket = (options) => {
1315
1321
  return;
1316
1322
  }
1317
1323
  const socket2 = new WebSocket(resolvedUrl, protocols);
1324
+ detachSocketListenersRef.current?.();
1325
+ detachSocketListenersRef.current = null;
1318
1326
  const socketEpoch = nextSocketEpochRef.current + 1;
1319
1327
  socketRef.current = socket2;
1320
1328
  socketKeyRef.current = nextSocketKey;
@@ -1348,7 +1356,7 @@ var useWebSocket = (options) => {
1348
1356
  socket2.addEventListener("message", handleSocketMessage);
1349
1357
  socket2.addEventListener("error", handleSocketError);
1350
1358
  socket2.addEventListener("close", handleSocketClose);
1351
- detachListeners = () => {
1359
+ detachSocketListenersRef.current = () => {
1352
1360
  socket2.removeEventListener("open", handleSocketOpen);
1353
1361
  socket2.removeEventListener("message", handleSocketMessage);
1354
1362
  socket2.removeEventListener("error", handleSocketError);
@@ -1357,7 +1365,6 @@ var useWebSocket = (options) => {
1357
1365
  });
1358
1366
  return () => {
1359
1367
  cancelled = true;
1360
- detachListeners?.();
1361
1368
  };
1362
1369
  }, [
1363
1370
  closeSocket,
@@ -1378,6 +1385,8 @@ var useWebSocket = (options) => {
1378
1385
  supported
1379
1386
  ]);
1380
1387
  react.useEffect(() => () => {
1388
+ detachSocketListenersRef.current?.();
1389
+ detachSocketListenersRef.current = null;
1381
1390
  controller.noteEffectInitiatedClose();
1382
1391
  socketKeyRef.current = null;
1383
1392
  activeSocketEpochRef.current = null;
@@ -1522,6 +1531,7 @@ var useEventSource = (options) => {
1522
1531
  [eventsDependency]
1523
1532
  );
1524
1533
  const eventSourceRef = react.useRef(null);
1534
+ const detachEventSourceListenersRef = react.useRef(null);
1525
1535
  const eventSourceKeyRef = react.useRef(null);
1526
1536
  const activeEventSourceEpochRef = react.useRef(null);
1527
1537
  const nextEventSourceEpochRef = react.useRef(0);
@@ -1559,6 +1569,8 @@ var useEventSource = (options) => {
1559
1569
  eventSourceRef.current = null;
1560
1570
  eventSourceKeyRef.current = null;
1561
1571
  activeEventSourceEpochRef.current = null;
1572
+ detachEventSourceListenersRef.current?.();
1573
+ detachEventSourceListenersRef.current = null;
1562
1574
  source.close();
1563
1575
  });
1564
1576
  const isActiveEventSourceEvent = useStableCallback((sourceEpoch) => {
@@ -1729,7 +1741,6 @@ var useEventSource = (options) => {
1729
1741
  status: reconnect.status === "running" || reconnect.status === "scheduled" ? "reconnecting" : "connecting"
1730
1742
  }));
1731
1743
  let cancelled = false;
1732
- let detachListeners = null;
1733
1744
  queueMicrotask(() => {
1734
1745
  if (cancelled) {
1735
1746
  return;
@@ -1779,7 +1790,7 @@ var useEventSource = (options) => {
1779
1790
  source.addEventListener(eventName, handler);
1780
1791
  }
1781
1792
  source.addEventListener("error", handleSourceError);
1782
- detachListeners = () => {
1793
+ detachEventSourceListenersRef.current = () => {
1783
1794
  source.removeEventListener("open", handleSourceOpen);
1784
1795
  source.removeEventListener("message", handleSourceMessage);
1785
1796
  for (const [eventName, handler] of namedEventHandlers) {
@@ -1790,7 +1801,6 @@ var useEventSource = (options) => {
1790
1801
  });
1791
1802
  return () => {
1792
1803
  cancelled = true;
1793
- detachListeners?.();
1794
1804
  };
1795
1805
  }, [
1796
1806
  closeEventSource,
@@ -1809,6 +1819,8 @@ var useEventSource = (options) => {
1809
1819
  supported
1810
1820
  ]);
1811
1821
  react.useEffect(() => () => {
1822
+ detachEventSourceListenersRef.current?.();
1823
+ detachEventSourceListenersRef.current = null;
1812
1824
  suppressReconnectRef.current = true;
1813
1825
  eventSourceKeyRef.current = null;
1814
1826
  activeEventSourceEpochRef.current = null;