/** * Configuration for exponential reconnect backoff. */export interface ReconnectBackoffConfig { /** Base delay in milliseconds before the first retry. */ readonly initialDelayMs: number; /** Multiplier applied per retry (exponential factor). */ readonly backoffFactor: number; /** Hard upper bound on delay in milliseconds. */ readonly maxDelayMs: number; /** Maximum number of retries (0-based). `null` means unlimited. */ readonly maxRetries: number | null;} /** * Sensible defaults for WebSocket reconnect backoff. * * - 1 s initial delay, doubling each retry, capped at 64 s, up to 7 retries. */export const DEFAULT_RECONNECT_BACKOFF: ReconnectBackoffConfig = { initialDelayMs: 1_000, backoffFactor: 2, maxDelayMs: 64_000, maxRetries: 7,}; /** * Calculate the reconnect delay for a given retry index using exponential * backoff. Returns `null` when `retryIndex` exceeds the configured maximum. */export function getReconnectDelayMs( retryIndex: number, config: ReconnectBackoffConfig = DEFAULT_RECONNECT_BACKOFF,): number | null { if (!Number.isInteger(retryIndex) || retryIndex < 0) { return null; } if (config.maxRetries !== null && retryIndex >= config.maxRetries) { return null; } return Math.min( Math.round(config.initialDelayMs * config.backoffFactor ** retryIndex), config.maxDelayMs, );}
/**
* Configuration for exponential reconnect backoff.
*/
export interface ReconnectBackoffConfig {
/** Base delay in milliseconds before the first retry. */
readonly initialDelayMs: number;
/** Multiplier applied per retry (exponential factor). */
readonly backoffFactor: number;
/** Hard upper bound on delay in milliseconds. */
readonly maxDelayMs: number;
/** Maximum number of retries (0-based). `null` means unlimited. */
readonly maxRetries: number | null;
}
/**
* Sensible defaults for WebSocket reconnect backoff.
*
* - 1 s initial delay, doubling each retry, capped at 64 s, up to 7 retries.
*/
export const DEFAULT_RECONNECT_BACKOFF: ReconnectBackoffConfig = {
initialDelayMs: 1_000,
backoffFactor: 2,
maxDelayMs: 64_000,
maxRetries: 7,
};
/**
* Calculate the reconnect delay for a given retry index using exponential
* backoff. Returns `null` when `retryIndex` exceeds the configured maximum.
*/
export function getReconnectDelayMs(
retryIndex: number,
config: ReconnectBackoffConfig = DEFAULT_RECONNECT_BACKOFF,
): number | null {
if (!Number.isInteger(retryIndex) || retryIndex < 0) {
return null;
}
if (config.maxRetries !== null && retryIndex >= config.maxRetries) {
return null;
}
return Math.min(
Math.round(config.initialDelayMs * config.backoffFactor ** retryIndex),
config.maxDelayMs,
);
}