UNPKG

@zerothrow/resilience

Version:

Production-grade resilience patterns for ZeroThrow

1 lines 21.1 kB
{"version":3,"sources":["../src/index.ts","../src/types.ts","../src/policies/retry.ts","../src/policy.ts","../src/clock.ts","../src/policies/circuit.ts","../src/policies/timeout.ts","../src/compose.ts","../src/policy-factory.ts"],"sourcesContent":["// Core types\nexport type {\n Policy,\n RetryPolicy as RetryPolicyInterface,\n CircuitBreakerPolicy as CircuitBreakerPolicyInterface,\n TimeoutPolicy as TimeoutPolicyInterface,\n AnyPolicy,\n RetryOptions,\n CircuitOptions,\n TimeoutOptions,\n PolicyError,\n PolicyErrorType\n} from './types.js'\n\n// Error classes\nexport {\n RetryExhaustedError,\n CircuitOpenError,\n TimeoutError\n} from './types.js'\n\n// Policy implementations\nexport { RetryPolicy } from './policies/retry.js'\nexport { CircuitBreakerPolicy } from './policies/circuit.js'\nexport { TimeoutPolicy } from './policies/timeout.js'\n\n// Composition utilities\nexport { wrap, compose } from './compose.js'\n\n// Main factory\nexport { Policy as PolicyFactory } from './policy-factory.js'\n\n// Clock utilities (for testing)\nexport type { Clock } from './clock.js'\nexport { SystemClock, TestClock } from './clock.js'","import type { Result } from '@zerothrow/core'\n\nexport interface Policy {\n execute<T>(\n operation: () => Promise<T>\n ): Promise<Result<T, Error>>\n}\n\nexport interface RetryPolicy extends Policy {\n onRetry(callback: (attempt: number, error: unknown, delay: number) => void): RetryPolicy\n}\n\nexport interface CircuitBreakerPolicy extends Policy {\n onCircuitStateChange(callback: (state: 'open' | 'closed' | 'half-open') => void): CircuitBreakerPolicy\n}\n\n// TimeoutPolicy is just a Policy with no additional methods\n// Using a type alias instead of an empty interface\nexport type TimeoutPolicy = Policy\n\n// Union type for all policies\nexport type AnyPolicy = RetryPolicy | CircuitBreakerPolicy | TimeoutPolicy | Policy\n\nexport interface RetryOptions {\n backoff?: 'constant' | 'linear' | 'exponential'\n delay?: number // Base delay in ms\n maxDelay?: number // Cap for exponential\n handle?: (error: Error) => boolean\n}\n\nexport interface CircuitOptions {\n threshold: number // Failures to open\n duration: number // Time to stay open\n onOpen?: () => void\n onClose?: () => void\n}\n\nexport interface TimeoutOptions {\n timeout: number // Ms before timeout\n}\n\n// Policy error types\nexport interface PolicyError extends Error {\n type: PolicyErrorType\n policyName: string\n context?: unknown\n}\n\nexport type PolicyErrorType =\n | 'retry-exhausted'\n | 'circuit-open'\n | 'timeout'\n\nexport class RetryExhaustedError extends Error implements PolicyError {\n readonly type = 'retry-exhausted' as const\n \n constructor(\n public readonly policyName: string,\n public readonly attempts: number,\n public readonly lastError: Error,\n public readonly context?: unknown\n ) {\n super(`Retry exhausted after ${attempts} attempts`)\n this.name = 'RetryExhaustedError'\n }\n}\n\nexport class CircuitOpenError extends Error implements PolicyError {\n readonly type = 'circuit-open' as const\n \n constructor(\n public readonly policyName: string,\n public readonly openedAt: Date,\n public readonly failureCount: number,\n public readonly context?: unknown\n ) {\n super(`Circuit breaker is open`)\n this.name = 'CircuitOpenError'\n }\n}\n\nexport class TimeoutError extends Error implements PolicyError {\n readonly type = 'timeout' as const\n \n constructor(\n public readonly policyName: string,\n public readonly timeout: number,\n public readonly elapsed: number,\n public readonly context?: unknown\n ) {\n super(`Operation timed out after ${elapsed}ms (limit: ${timeout}ms)`)\n this.name = 'TimeoutError'\n }\n}","import { ZT, type Result } from '@zerothrow/core'\nimport { BasePolicy } from '../policy.js'\nimport { RetryExhaustedError, type RetryOptions, type RetryPolicy as IRetryPolicy } from '../types.js'\nimport type { Clock } from '../clock.js'\n\nexport class RetryPolicy extends BasePolicy implements IRetryPolicy {\n private retryCallback?: (attempt: number, error: unknown, delay: number) => void\n constructor(\n private readonly count: number,\n private readonly options: RetryOptions = {},\n clock?: Clock\n ) {\n super('retry', clock)\n }\n\n async execute<T>(\n operation: () => Promise<T>\n ): Promise<Result<T, Error>> {\n let lastError: Error | undefined\n \n for (let attempt = 0; attempt <= this.count; attempt++) {\n const result = await this.runOperation(operation)\n \n if (result.ok) {\n return result\n }\n \n lastError = result.error\n \n // Check if we should handle this error\n if (this.options.handle && !this.options.handle(result.error)) {\n return result\n }\n \n // If this is the last attempt, don't delay\n if (attempt < this.count) {\n const delayTime = this.calculateDelay(attempt + 1)\n if (this.retryCallback) {\n this.retryCallback(attempt + 1, lastError, delayTime)\n }\n await this.clock.sleep(delayTime)\n }\n }\n \n return ZT.err(new RetryExhaustedError(\n this.name,\n this.count + 1,\n lastError as Error\n ))\n }\n\n onRetry(callback: (attempt: number, error: unknown, delay: number) => void): IRetryPolicy {\n this.retryCallback = callback\n return this\n }\n\n\n private calculateDelay(attempt: number): number {\n const { backoff = 'constant', delay = 1000, maxDelay = 30000 } = this.options\n \n let calculatedDelay: number\n \n switch (backoff) {\n case 'constant':\n calculatedDelay = delay\n break\n case 'linear':\n calculatedDelay = delay * attempt\n break\n case 'exponential':\n calculatedDelay = delay * Math.pow(2, attempt - 1)\n break\n default:\n calculatedDelay = delay\n }\n \n return Math.min(calculatedDelay, maxDelay)\n }\n}","import { ZT, type Result } from '@zerothrow/core'\nimport type { Policy } from './types.js'\nimport { SystemClock, type Clock } from './clock.js'\n\nexport abstract class BasePolicy implements Policy {\n constructor(\n protected readonly name: string,\n protected readonly clock: Clock = new SystemClock()\n ) {}\n\n abstract execute<T>(\n operation: () => Promise<T>\n ): Promise<Result<T, Error>>\n\n protected async runOperation<T>(\n operation: () => Promise<T>\n ): Promise<Result<T, Error>> {\n return ZT.tryAsync(operation)\n }\n}","export interface Clock {\n now(): Date\n sleep(ms: number): Promise<void>\n}\n\nexport class SystemClock implements Clock {\n now(): Date {\n return new Date()\n }\n\n async sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms))\n }\n}\n\nexport class TestClock implements Clock {\n private currentTime = Date.now()\n private sleepers: Array<{\n wakeTime: number\n resolve: () => void\n }> = []\n\n now(): Date {\n return new Date(this.currentTime)\n }\n\n async sleep(ms: number): Promise<void> {\n const wakeTime = this.currentTime + ms\n return new Promise(resolve => {\n this.sleepers.push({ wakeTime, resolve })\n this.sleepers.sort((a, b) => a.wakeTime - b.wakeTime)\n })\n }\n\n advance(ms: number): void {\n this.currentTime += ms\n \n // Wake up sleepers\n while (this.sleepers.length > 0) {\n const nextSleeper = this.sleepers[0]\n if (nextSleeper && nextSleeper.wakeTime <= this.currentTime) {\n this.sleepers.shift()\n nextSleeper.resolve()\n } else {\n break\n }\n }\n }\n\n setTime(time: Date | number): void {\n this.currentTime = typeof time === 'number' ? time : time.getTime()\n }\n}","import { ZT, type Result } from '@zerothrow/core'\nimport { BasePolicy } from '../policy.js'\nimport { CircuitOpenError, type CircuitOptions, type CircuitBreakerPolicy as ICircuitBreakerPolicy } from '../types.js'\nimport type { Clock } from '../clock.js'\n\ntype CircuitState = 'closed' | 'open' | 'half-open'\n\nexport class CircuitBreakerPolicy extends BasePolicy implements ICircuitBreakerPolicy {\n private state: CircuitState = 'closed'\n private failures = 0\n private lastFailureTime?: number\n private nextAllowedTime?: number\n private stateChangeCallback?: (state: CircuitState) => void\n \n constructor(\n private readonly options: CircuitOptions,\n clock?: Clock\n ) {\n super('circuit-breaker', clock)\n }\n\n async execute<T>(\n operation: () => Promise<T>\n ): Promise<Result<T, Error>> {\n // Check if circuit is open\n if (this.state === 'open') {\n const now = this.clock.now().getTime()\n \n // Check if we should try half-open\n if (this.nextAllowedTime && now >= this.nextAllowedTime) {\n this.setState('half-open')\n } else {\n return ZT.err(new CircuitOpenError(\n this.name,\n new Date(this.lastFailureTime || now),\n this.failures\n ))\n }\n }\n \n // Try the operation\n const result = await this.runOperation(operation)\n \n if (result.ok) {\n this.onSuccess()\n return result\n } else {\n // At this point, state is either 'closed' or 'half-open'\n this.onFailure()\n \n // After onFailure(), check if circuit is now open\n // This cast is safe because onFailure() may have changed the state\n const currentState = this.state as CircuitState\n if (currentState === 'open') {\n // Circuit just opened, return circuit error instead of original error\n return ZT.err(new CircuitOpenError(\n this.name,\n new Date(this.lastFailureTime || Date.now()),\n this.failures\n ))\n }\n \n return result\n }\n }\n \n private onSuccess(): void {\n if (this.state === 'half-open') {\n // Circuit recovery successful\n this.reset()\n this.options.onClose?.()\n }\n // In closed state, success doesn't change anything\n }\n \n private onFailure(): void {\n this.failures++\n this.lastFailureTime = this.clock.now().getTime()\n \n if (this.state === 'half-open') {\n // Failed during recovery, reopen immediately\n this.open()\n } else if (this.failures >= this.options.threshold) {\n // Threshold reached, open circuit\n this.open()\n }\n }\n \n private open(): void {\n this.setState('open')\n this.nextAllowedTime = this.clock.now().getTime() + this.options.duration\n this.options.onOpen?.()\n }\n \n private reset(): void {\n this.setState('closed')\n this.failures = 0\n delete this.lastFailureTime\n delete this.nextAllowedTime\n }\n\n private setState(newState: CircuitState): void {\n if (this.state !== newState) {\n this.state = newState\n this.stateChangeCallback?.(newState)\n }\n }\n\n onCircuitStateChange(callback: (state: CircuitState) => void): ICircuitBreakerPolicy {\n this.stateChangeCallback = callback\n return this\n }\n}","import { ZT, type Result } from '@zerothrow/core'\nimport { BasePolicy } from '../policy.js'\nimport { TimeoutError, type TimeoutOptions } from '../types.js'\nimport type { Clock } from '../clock.js'\n\nexport class TimeoutPolicy extends BasePolicy {\n constructor(\n private readonly options: TimeoutOptions,\n clock?: Clock\n ) {\n super('timeout', clock)\n }\n\n async execute<T>(\n operation: () => Promise<T>\n ): Promise<Result<T, Error>> {\n const startTime = this.clock.now().getTime()\n \n // Create a timeout promise that rejects after the specified time\n const timeoutPromise = new Promise<never>((_, reject) => {\n setTimeout(() => {\n const elapsed = this.clock.now().getTime() - startTime\n reject(new TimeoutError(\n this.name,\n this.options.timeout,\n elapsed\n ))\n }, this.options.timeout)\n })\n \n try {\n // Race the operation against the timeout\n const result = await Promise.race([\n operation(),\n timeoutPromise\n ])\n \n return ZT.ok(result)\n } catch (error) {\n // Check if it's our timeout error\n if (error instanceof TimeoutError) {\n return ZT.err(error)\n }\n \n // Otherwise it's an error from the operation\n return ZT.err(error instanceof Error ? error : new Error(String(error)))\n }\n }\n}","import type { Result } from '@zerothrow/core'\nimport type { Policy } from './types.js'\n\n/**\n * Wraps one policy with another, creating a composed policy.\n * The outer policy executes first and passes its operation to the inner policy.\n * \n * Example: Policy.wrap(retry, timeout) creates a policy that retries with timeouts\n */\nexport function wrap(outer: Policy, inner: Policy): Policy {\n return {\n async execute<T>(\n operation: () => Promise<T>\n ): Promise<Result<T, Error>> {\n // The outer policy wraps the inner policy's execution\n return outer.execute(() => \n // The inner policy executes the actual operation\n inner.execute(operation).then(result => {\n // If inner policy returns an error Result, we need to throw\n // so the outer policy can handle it (e.g., retry on error)\n if (!result.ok) {\n throw result.error\n }\n return result.value\n })\n )\n }\n }\n}\n\n/**\n * Composes multiple policies from left to right.\n * The leftmost policy is the outermost wrapper.\n * \n * Example: compose(retry, circuit, timeout) \n * Results in: retry wraps (circuit wraps (timeout wraps operation))\n */\nexport function compose(...policies: Policy[]): Policy {\n if (policies.length === 0) {\n throw new Error('compose requires at least one policy')\n }\n \n if (policies.length === 1) {\n return policies[0] as Policy\n }\n \n return policies.reduce((acc, policy) => wrap(policy, acc))\n}","import { RetryPolicy } from './policies/retry.js'\nimport { CircuitBreakerPolicy } from './policies/circuit.js'\nimport { TimeoutPolicy } from './policies/timeout.js'\nimport { wrap, compose } from './compose.js'\nimport type { RetryOptions, CircuitOptions, TimeoutOptions } from './types.js'\nimport type { Clock } from './clock.js'\n\n/**\n * Main factory for creating resilience policies\n */\nexport const Policy = {\n /**\n * Creates a retry policy\n */\n retry(count: number, options?: RetryOptions, clock?: Clock) {\n return new RetryPolicy(count, options, clock)\n },\n\n /**\n * Creates a circuit breaker policy\n */\n circuitBreaker(options: CircuitOptions, clock?: Clock) {\n return new CircuitBreakerPolicy(options, clock)\n },\n\n /**\n * Creates a timeout policy\n */\n timeout(options: TimeoutOptions | number, clock?: Clock) {\n const opts = typeof options === 'number' \n ? { timeout: options } \n : options\n return new TimeoutPolicy(opts, clock)\n },\n\n /**\n * Wraps one policy with another\n * The outer policy executes first\n */\n wrap,\n\n /**\n * Composes multiple policies from left to right\n * The leftmost policy is the outermost wrapper\n */\n compose\n} as const"],"mappings":"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","names":["import_core","import_core","import_core"]}