react-realtime-hooks 1.4.3 → 2.0.1

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
@@ -3,6 +3,8 @@
3
3
  [![npm version](https://img.shields.io/npm/v/react-realtime-hooks?color=0f766e)](https://www.npmjs.com/package/react-realtime-hooks)
4
4
  [![Quality Gate](https://img.shields.io/github/actions/workflow/status/volkov85/react-realtime-hooks/quality-gate.yml?branch=main&label=quality%20gate)](https://github.com/volkov85/react-realtime-hooks/actions/workflows/quality-gate.yml)
5
5
  [![Demo](https://img.shields.io/github/actions/workflow/status/volkov85/react-realtime-hooks/pages.yml?branch=main&label=demo)](https://github.com/volkov85/react-realtime-hooks/actions/workflows/pages.yml)
6
+ [![bundle size](https://img.shields.io/bundlephobia/minzip/react-realtime-hooks?label=min%20%2B%20gzip&color=0f766e)](https://bundlephobia.com/package/react-realtime-hooks)
7
+ [![dependencies](https://img.shields.io/badge/dependencies-zero-0f766e)](https://github.com/volkov85/react-realtime-hooks/blob/main/package.json)
6
8
  [![license](https://img.shields.io/npm/l/react-realtime-hooks)](https://github.com/volkov85/react-realtime-hooks/blob/main/LICENSE)
7
9
  [![TypeScript](https://img.shields.io/badge/TypeScript-typed-3178c6)](https://www.typescriptlang.org/)
8
10
  [![react](https://img.shields.io/badge/react-18%20%7C%2019-149eca)](https://www.npmjs.com/package/react)
@@ -88,7 +90,6 @@ export function NotificationsPanel() {
88
90
  parseMessage: (event) => JSON.parse(String(event.data)) as IncomingMessage,
89
91
  reconnect: {
90
92
  initialDelayMs: 1_000,
91
- maxAttempts: null,
92
93
  },
93
94
  heartbeat: {
94
95
  intervalMs: 10_000,
@@ -239,7 +240,6 @@ export function ChatSocket() {
239
240
  parseMessage: (event) => JSON.parse(String(event.data)) as IncomingMessage,
240
241
  reconnect: {
241
242
  initialDelayMs: 1_000,
242
- maxAttempts: null,
243
243
  },
244
244
  heartbeat: {
245
245
  intervalMs: 10_000,
@@ -393,6 +393,8 @@ export function GatedNotifications() {
393
393
  initialDelayMs: 1_000,
394
394
  maxAttempts: null,
395
395
  },
396
+ // ^ pass `null` explicitly to opt back into unlimited reconnect attempts;
397
+ // the default in 2.0 caps retries at 10.
396
398
  url: "ws://localhost:8080/notifications",
397
399
  });
398
400
 
@@ -508,7 +510,7 @@ retry loop.
508
510
  | `maxDelayMs` | `number` | `30000` | Delay cap |
509
511
  | `backoffFactor` | `number` | `2` | Exponential multiplier |
510
512
  | `jitterRatio` | `number` | `0.2` | Randomized variance ratio |
511
- | `maxAttempts` | `number \| null` | `null` | Max attempts, `null` means unlimited |
513
+ | `maxAttempts` | `number \| null` | `10` | Max attempts before `"stopped"`; pass `null` for unlimited |
512
514
  | `getDelayMs` | `ReconnectDelayStrategy` | `undefined` | Custom delay strategy |
513
515
  | `resetOnSuccess` | `boolean` | `true` | Resets attempt count after success |
514
516
  | `onSchedule` | `(attempt) => void` | `undefined` | Called when an attempt is scheduled |
@@ -540,7 +542,7 @@ retry loop.
540
542
  | -------------- | --------------------------------------------------- | ----------- | ------------------------------------------- |
541
543
  | `enabled` | `boolean` | `true` | Enables the heartbeat loop |
542
544
  | `intervalMs` | `number` | Required | Beat interval |
543
- | `timeoutMs` | `number` | `undefined` | Timeout before `hasTimedOut` becomes `true` |
545
+ | `timeoutMs` | `number \| null` | `10_000` | Timeout in ms before `hasTimedOut` becomes `true`; pass `null` to disable |
544
546
  | `message` | `TOutgoing \| (() => TOutgoing)` | `undefined` | Optional heartbeat payload |
545
547
  | `beat` | `() => void \| boolean \| Promise<void \| boolean>` | `undefined` | Custom beat side effect |
546
548
  | `matchesAck` | `(message) => boolean` | `undefined` | Ack matcher |
@@ -694,6 +696,12 @@ Run the local playground:
694
696
  npm run demo
695
697
  ```
696
698
 
699
+ ## Migrating from 1.x
700
+
701
+ Two defaults change in 2.0 (`reconnect.maxAttempts` → `10`,
702
+ `heartbeat.timeoutMs` → `10_000`). See [MIGRATING.md](./MIGRATING.md) for the
703
+ exact diff and how to restore 1.x behaviour.
704
+
697
705
  ## Contributing
698
706
 
699
707
  Development and release workflow live in [CONTRIBUTING.md](./CONTRIBUTING.md).
package/dist/index.cjs CHANGED
@@ -315,6 +315,7 @@ var DEFAULT_RECONNECT_OPTIONS = {
315
315
  enabled: true,
316
316
  initialDelayMs: 1e3,
317
317
  jitterRatio: 0.2,
318
+ maxAttempts: 10,
318
319
  maxDelayMs: 3e4,
319
320
  resetOnSuccess: true
320
321
  };
@@ -366,7 +367,7 @@ var normalizeReconnectOptions = (options) => {
366
367
  jitterRatio: sanitizeJitterRatio(
367
368
  options?.jitterRatio ?? DEFAULT_RECONNECT_OPTIONS.jitterRatio
368
369
  ),
369
- maxAttempts: sanitizeMaxAttempts(options?.maxAttempts),
370
+ maxAttempts: options?.maxAttempts === void 0 ? DEFAULT_RECONNECT_OPTIONS.maxAttempts : sanitizeMaxAttempts(options.maxAttempts),
370
371
  maxDelayMs,
371
372
  resetOnSuccess: options?.resetOnSuccess ?? DEFAULT_RECONNECT_OPTIONS.resetOnSuccess
372
373
  };
@@ -584,6 +585,7 @@ var useReconnect = (options = {}) => {
584
585
  status: state.status
585
586
  };
586
587
  };
588
+ var DEFAULT_HEARTBEAT_TIMEOUT_MS = 1e4;
587
589
  var createInitialState2 = (isRunning) => ({
588
590
  hasTimedOut: false,
589
591
  isRunning,
@@ -617,13 +619,14 @@ var useHeartbeat = (options) => {
617
619
  options.onTimeout?.();
618
620
  });
619
621
  const scheduleTimeout = useStableCallback(() => {
620
- if (options.timeoutMs === void 0) {
622
+ const timeoutMs = options.timeoutMs === void 0 ? DEFAULT_HEARTBEAT_TIMEOUT_MS : options.timeoutMs;
623
+ if (timeoutMs === null) {
621
624
  timeoutRef.current.cancel();
622
625
  return;
623
626
  }
624
627
  timeoutRef.current.schedule(() => {
625
628
  handleTimeout();
626
- }, options.timeoutMs);
629
+ }, timeoutMs);
627
630
  });
628
631
  const handleBeatSuccess = useStableCallback((performedAt) => {
629
632
  commitState((current) => ({
@@ -986,7 +989,7 @@ var useWebSocket = (options) => {
986
989
  startOnMount: false
987
990
  };
988
991
  if (heartbeatConfig !== null && heartbeatConfig.timeoutMs !== void 0) {
989
- heartbeatHookOptions.timeoutMs = heartbeatConfig.timeoutMs;
992
+ heartbeatHookOptions.timeoutMs = heartbeatConfig.timeoutMs ?? null;
990
993
  }
991
994
  if (heartbeatConfig !== null && heartbeatConfig.matchesAck !== void 0) {
992
995
  heartbeatHookOptions.matchesAck = heartbeatConfig.matchesAck;