All files / hooks/use-polling/src utils.ts

100% Statements 10/10
100% Branches 18/18
100% Functions 1/1
100% Lines 9/9

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48          1x                                                       53x   14x 4x 4x     10x   53x   53x 53x    
import type { PollingBackoff } from "./types";
 
/**
 * The default base polling interval (ms) when `options.interval` is omitted.
 */
export const DEFAULT_POLLING_INTERVAL = 1000;
 
/**
 * Compute the delay (in ms) to wait before the next poll, given how many polls
 * have failed **consecutively** so far and the configured backoff strategy.
 *
 * Pure and side-effect free — exported so the backoff behaviour can be unit
 * tested (and previewed) in isolation.
 *
 * - `failureCount <= 0` (a success, or the very first poll) or a falsy `backoff`
 *   → the plain `baseInterval`.
 * - `backoff === true` → exponential: `baseInterval * 2 ** failureCount`, no ceiling.
 * - {@link BackoffOptions} → exponential with a custom `factor` (default `2`),
 *   clamped to `maxInterval` (default `Infinity`).
 * - {@link BackoffFn} → whatever the function returns, falling back to
 *   `baseInterval` for a non-finite / negative result.
 *
 * @param failureCount - Number of consecutive failed polls (reset to 0 on success).
 * @param baseInterval - The configured base interval in ms.
 * @param backoff - The backoff strategy (see {@link PollingBackoff}).
 * @returns The delay in ms before the next poll.
 */
export function computePollingDelay(
  failureCount: number,
  baseInterval: number,
  backoff?: PollingBackoff,
): number {
  // No consecutive failures (or backoff disabled) → the plain base interval.
  if (failureCount <= 0 || !backoff) return baseInterval;
 
  if (typeof backoff === "function") {
    const delay = backoff(failureCount, baseInterval);
    return Number.isFinite(delay) && delay >= 0 ? delay : baseInterval;
  }
 
  const factor = backoff === true ? 2 : (backoff.factor ?? 2);
  const maxInterval =
    backoff === true ? Infinity : (backoff.maxInterval ?? Infinity);
 
  const delay = baseInterval * factor ** failureCount;
  return Math.min(delay, maxInterval);
}