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 +1 -0
- package/dist/index.cjs +18 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +18 -6
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
[](https://github.com/volkov85/react-realtime-hooks/blob/main/LICENSE)
|
|
9
9
|
[](https://www.typescriptlang.org/)
|
|
10
10
|
[](https://www.npmjs.com/package/react)
|
|
11
|
+
[](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
|
-
|
|
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
|
-
|
|
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;
|