UNPKG

@oxog/delay

Version:

A comprehensive, zero-dependency delay/timeout utility library with advanced timing features

78 lines 2.95 kB
import { DelayError, DelayErrorCode } from '../types/index.js'; import { validateRetryOptions, validateFunction } from '../utils/validation.js'; import { calculateBackoffDelay } from '../utils/random.js'; import { createBasicDelay } from './delay.js'; export async function retryDelay(fn, options) { validateFunction(fn, 'retry function'); validateRetryOptions(options); const { attempts, delay, backoff = 'linear', backoffFactor = 2, maxDelay = Infinity, onRetry, retryIf, } = options; let lastError; for (let attempt = 1; attempt <= attempts; attempt++) { try { const result = await fn(); return result; } catch (error) { lastError = error instanceof Error ? error : new Error(String(error)); // Check if we should retry this error if (retryIf && !retryIf(lastError)) { throw lastError; } // If this was the last attempt, throw the error if (attempt === attempts) { throw new DelayError(`Retry exhausted after ${attempts} attempts: ${lastError.message}`, DelayErrorCode.RETRY_EXHAUSTED, { attempts, lastError: lastError.message, originalError: lastError, }); } // Call the retry callback if provided if (onRetry) { try { onRetry(lastError, attempt); } catch (callbackError) { // Don't let callback errors break the retry logic console.error('Error in retry callback:', callbackError); } } // Calculate delay for next attempt let delayMs; if (typeof delay === 'function') { delayMs = delay(attempt); } else { delayMs = calculateBackoffDelay(delay, attempt, backoff, backoffFactor, maxDelay); } // Wait before next attempt if (delayMs > 0) { await createBasicDelay(delayMs); } } } // This should never be reached, but TypeScript needs it throw lastError; } export function createRetryWithDefaults(defaultOptions) { return function (fn, options) { const mergedOptions = { ...defaultOptions, ...options }; return retryDelay(fn, mergedOptions); }; } export function retryWithExponentialBackoff(fn, attempts = 3, baseDelay = 1000, maxDelay = 30000) { return retryDelay(fn, { attempts, delay: baseDelay, backoff: 'exponential', maxDelay, }); } export function retryWithLinearBackoff(fn, attempts = 3, baseDelay = 1000, maxDelay = 10000) { return retryDelay(fn, { attempts, delay: baseDelay, backoff: 'linear', maxDelay, }); } //# sourceMappingURL=retry.js.map