{"version":3,"file":"resilience.mjs","sources":["../../../src/lib/utils/resilience.ts"],"sourcesContent":["/**\n * @file Resilience Utilities\n * @description Enterprise-grade retry policies, circuit breakers, and fault tolerance patterns\n */\n\n/**\n * Retry policy configuration\n */\nexport interface RetryConfig {\n  /** Maximum retry attempts */\n  maxAttempts?: number;\n  /** Initial delay between retries (ms) */\n  initialDelay?: number;\n  /** Maximum delay between retries (ms) */\n  maxDelay?: number;\n  /** Delay multiplier for exponential backoff */\n  backoffMultiplier?: number;\n  /** Whether to add jitter to delays */\n  jitter?: boolean;\n  /** Predicate to determine if error is retryable */\n  retryOn?: (error: unknown, attempt: number) => boolean;\n  /** Callback on each retry attempt */\n  onRetry?: (error: unknown, attempt: number, delay: number) => void;\n  /** Abort signal for cancellation */\n  signal?: AbortSignal;\n}\n\n/**\n * Default retry configuration\n */\nconst DEFAULT_RETRY_CONFIG: Required<Omit<RetryConfig, 'signal' | 'onRetry'>> = {\n  maxAttempts: 3,\n  initialDelay: 1000,\n  maxDelay: 30000,\n  backoffMultiplier: 2,\n  jitter: true,\n  retryOn: () => true,\n};\n\n/**\n * Calculate delay with exponential backoff and optional jitter\n */\nfunction calculateDelay(\n  attempt: number,\n  config: Pick<Required<RetryConfig>, 'initialDelay' | 'maxDelay' | 'backoffMultiplier' | 'jitter'>\n): number {\n  const exponentialDelay =\n    config.initialDelay * Math.pow(config.backoffMultiplier, attempt - 1);\n  const boundedDelay = Math.min(exponentialDelay, config.maxDelay);\n\n  if (config.jitter) {\n    // Add random jitter (±25%)\n    const jitterRange = boundedDelay * 0.25;\n    return boundedDelay + (Math.random() * 2 - 1) * jitterRange;\n  }\n\n  return boundedDelay;\n}\n\n/**\n * Sleep for a specified duration\n */\nasync function sleep(ms: number, signal?: AbortSignal): Promise<void> {\n  return new Promise((resolve, reject) => {\n    if (signal?.aborted === true) {\n      reject(new Error('Aborted'));\n      return;\n    }\n\n    const timeoutId = setTimeout(resolve, ms);\n\n    signal?.addEventListener('abort', () => {\n      clearTimeout(timeoutId);\n      reject(new Error('Aborted'));\n    });\n  });\n}\n\n/**\n * Execute function with retry logic\n */\nexport async function withRetry<T>(\n  fn: () => Promise<T>,\n  config: RetryConfig = {}\n): Promise<T> {\n  const resolvedConfig = { ...DEFAULT_RETRY_CONFIG, ...config };\n  let lastError: unknown;\n\n  for (let attempt = 1; attempt <= resolvedConfig.maxAttempts; attempt++) {\n    try {\n      // Check for abort before attempting\n      if (config.signal?.aborted === true) {\n        throw new Error('Aborted');\n      }\n\n      return await fn();\n    } catch (error) {\n      lastError = error;\n\n      // Check if we should retry\n      const shouldRetry =\n        attempt < resolvedConfig.maxAttempts &&\n        resolvedConfig.retryOn(error, attempt) === true;\n\n      if (!shouldRetry) {\n        break;\n      }\n\n      // Calculate and wait for delay\n      const delay = calculateDelay(attempt, resolvedConfig);\n      config.onRetry?.(error, attempt, delay);\n\n      await sleep(delay, config.signal);\n    }\n  }\n\n  throw lastError;\n}\n\n/**\n * Retry policy builder for fluent configuration\n */\nexport class RetryPolicy {\n  private readonly config: RetryConfig;\n\n  constructor(config: RetryConfig = {}) {\n    this.config = config;\n  }\n\n  /**\n   * Set max attempts\n   */\n  attempts(max: number): RetryPolicy {\n    return new RetryPolicy({ ...this.config, maxAttempts: max });\n  }\n\n  /**\n   * Set delays\n   */\n  delays(initial: number, max?: number): RetryPolicy {\n    return new RetryPolicy({\n      ...this.config,\n      initialDelay: initial,\n      maxDelay: max ?? initial * 10,\n    });\n  }\n\n  /**\n   * Set backoff multiplier\n   */\n  backoff(multiplier: number): RetryPolicy {\n    return new RetryPolicy({ ...this.config, backoffMultiplier: multiplier });\n  }\n\n  /**\n   * Enable/disable jitter\n   */\n  withJitter(enabled = true): RetryPolicy {\n    return new RetryPolicy({ ...this.config, jitter: enabled });\n  }\n\n  /**\n   * Set retry condition\n   */\n  retryIf(predicate: (error: unknown, attempt: number) => boolean): RetryPolicy {\n    return new RetryPolicy({ ...this.config, retryOn: predicate });\n  }\n\n  /**\n   * Set retry callback\n   */\n  onRetry(callback: (error: unknown, attempt: number, delay: number) => void): RetryPolicy {\n    return new RetryPolicy({ ...this.config, onRetry: callback });\n  }\n\n  /**\n   * Execute with this policy\n   */\n  async execute<T>(fn: () => Promise<T>, signal?: AbortSignal): Promise<T> {\n    return withRetry(fn, { ...this.config, signal });\n  }\n}\n\n/**\n * Circuit breaker states\n */\nexport type CircuitState = 'closed' | 'open' | 'half-open';\n\n/**\n * Circuit breaker configuration\n */\nexport interface CircuitBreakerConfig {\n  /** Failure threshold before opening */\n  failureThreshold?: number;\n  /** Success threshold for half-open to close */\n  successThreshold?: number;\n  /** Time to wait before trying half-open (ms) */\n  resetTimeout?: number;\n  /** Time window for failure counting (ms) */\n  failureWindow?: number;\n  /** Callback on state change */\n  onStateChange?: (from: CircuitState, to: CircuitState) => void;\n}\n\n/**\n * Circuit breaker for fault isolation\n */\nexport class CircuitBreaker {\n  private state: CircuitState = 'closed';\n  private failures: number[] = [];\n  private successes = 0;\n  private lastFailureTime = 0;\n  private config: Required<Omit<CircuitBreakerConfig, 'onStateChange'>> & {\n    onStateChange?: CircuitBreakerConfig['onStateChange'];\n  };\n\n  constructor(config: CircuitBreakerConfig = {}) {\n    this.config = {\n      failureThreshold: config.failureThreshold ?? 5,\n      successThreshold: config.successThreshold ?? 2,\n      resetTimeout: config.resetTimeout ?? 30000, // 30 seconds\n      failureWindow: config.failureWindow ?? 60000, // 1 minute\n      onStateChange: config.onStateChange,\n    };\n  }\n\n  /**\n   * Get current circuit state\n   */\n  getState(): CircuitState {\n    if (this.state === 'open' && this.shouldAttemptReset()) {\n      this.transition('half-open');\n    }\n    return this.state;\n  }\n\n  /**\n   * Record success\n   */\n  success(): void {\n    if (this.state === 'half-open') {\n      this.successes++;\n      if (this.successes >= this.config.successThreshold) {\n        this.transition('closed');\n      }\n    } else if (this.state === 'closed') {\n      // Clean up old failures\n      this.cleanOldFailures();\n    }\n  }\n\n  /**\n   * Record failure\n   */\n  failure(): void {\n    this.lastFailureTime = Date.now();\n\n    if (this.state === 'half-open') {\n      this.transition('open');\n    } else if (this.state === 'closed') {\n      this.failures.push(Date.now());\n      this.cleanOldFailures();\n\n      if (this.failures.length >= this.config.failureThreshold) {\n        this.transition('open');\n      }\n    }\n  }\n\n  /**\n   * Execute function through circuit breaker\n   */\n  async execute<T>(fn: () => Promise<T>): Promise<T> {\n    const state = this.getState();\n\n    if (state === 'open') {\n      throw new CircuitOpenError('Circuit breaker is open');\n    }\n\n    try {\n      const result = await fn();\n      this.success();\n      return result;\n    } catch (error) {\n      this.failure();\n      throw error;\n    }\n  }\n\n  /**\n   * Get circuit statistics\n   */\n  getStats(): {\n    state: CircuitState;\n    failures: number;\n    successesInHalfOpen: number;\n    lastFailure: Date | null;\n  } {\n    return {\n      state: this.state,\n      failures: this.failures.length,\n      successesInHalfOpen: this.successes,\n      lastFailure: this.lastFailureTime ? new Date(this.lastFailureTime) : null,\n    };\n  }\n\n  /**\n   * Force reset the circuit\n   */\n  reset(): void {\n    this.transition('closed');\n    this.failures = [];\n    this.successes = 0;\n    this.lastFailureTime = 0;\n  }\n\n  /**\n   * Check if reset should be attempted\n   */\n  private shouldAttemptReset(): boolean {\n    return Date.now() - this.lastFailureTime >= this.config.resetTimeout;\n  }\n\n  /**\n   * Transition to new state\n   */\n  private transition(newState: CircuitState): void {\n    if (this.state !== newState) {\n      const oldState = this.state;\n      this.state = newState;\n\n      if (newState === 'closed') {\n        this.failures = [];\n        this.successes = 0;\n      } else if (newState === 'half-open') {\n        this.successes = 0;\n      }\n\n      this.config.onStateChange?.(oldState, newState);\n    }\n  }\n\n  /**\n   * Clean failures outside window\n   */\n  private cleanOldFailures(): void {\n    const cutoff = Date.now() - this.config.failureWindow;\n    this.failures = this.failures.filter((time) => time > cutoff);\n  }\n}\n\n/**\n * Error thrown when circuit is open\n */\nexport class CircuitOpenError extends Error {\n  readonly isCircuitOpen = true;\n\n  constructor(message = 'Circuit breaker is open') {\n    super(message);\n    this.name = 'CircuitOpenError';\n  }\n}\n\n/**\n * Bulkhead pattern for resource isolation\n */\nexport class Bulkhead {\n  private running = 0;\n  private queue: Array<{\n    resolve: () => void;\n    reject: (error: Error) => void;\n  }> = [];\n  private readonly maxConcurrent: number;\n  private readonly maxQueue: number;\n\n  constructor(maxConcurrent: number, maxQueue = 100) {\n    this.maxConcurrent = maxConcurrent;\n    this.maxQueue = maxQueue;\n  }\n\n  /**\n   * Execute function with bulkhead isolation\n   */\n  async execute<T>(fn: () => Promise<T>): Promise<T> {\n    // Wait for available slot\n    if (this.running >= this.maxConcurrent) {\n      if (this.queue.length >= this.maxQueue) {\n        throw new BulkheadFullError('Bulkhead queue is full');\n      }\n\n      await new Promise<void>((resolve, reject) => {\n        this.queue.push({ resolve, reject });\n      });\n    }\n\n    this.running++;\n\n    try {\n      return await fn();\n    } finally {\n      this.running--;\n\n      // Release next queued request\n      const next = this.queue.shift();\n      if (next) {\n        next.resolve();\n      }\n    }\n  }\n\n  /**\n   * Get bulkhead statistics\n   */\n  getStats(): {\n    running: number;\n    queued: number;\n    maxConcurrent: number;\n    maxQueue: number;\n    available: number;\n  } {\n    return {\n      running: this.running,\n      queued: this.queue.length,\n      maxConcurrent: this.maxConcurrent,\n      maxQueue: this.maxQueue,\n      available: Math.max(0, this.maxConcurrent - this.running),\n    };\n  }\n\n  /**\n   * Clear the queue (reject all pending)\n   */\n  clearQueue(): void {\n    const error = new BulkheadFullError('Queue cleared');\n    for (const item of this.queue) {\n      item.reject(error);\n    }\n    this.queue = [];\n  }\n}\n\n/**\n * Error thrown when bulkhead is full\n */\nexport class BulkheadFullError extends Error {\n  readonly isBulkheadFull = true;\n\n  constructor(message = 'Bulkhead is full') {\n    super(message);\n    this.name = 'BulkheadFullError';\n  }\n}\n\n/**\n * Timeout wrapper\n */\nexport async function withTimeout<T>(\n  fn: () => Promise<T>,\n  timeout: number,\n  timeoutError?: Error\n): Promise<T> {\n  return Promise.race([\n    fn(),\n    new Promise<never>((_, reject) =>\n      setTimeout(\n        () => reject(timeoutError ?? new TimeoutError(`Operation timed out after ${timeout}ms`)),\n        timeout\n      )\n    ),\n  ]);\n}\n\n/**\n * Timeout error\n */\nexport class TimeoutError extends Error {\n  readonly isTimeout = true;\n\n  constructor(message = 'Operation timed out') {\n    super(message);\n    this.name = 'TimeoutError';\n  }\n}\n\n/**\n * Fallback wrapper\n */\nexport async function withFallback<T>(\n  fn: () => Promise<T>,\n  fallback: T | (() => T | Promise<T>)\n): Promise<T> {\n  try {\n    return await fn();\n  } catch {\n    return typeof fallback === 'function' ? (fallback as () => T | Promise<T>)() : fallback;\n  }\n}\n\n/**\n * Compose multiple resilience patterns\n */\nexport function compose<T>(\n  fn: () => Promise<T>,\n  ...wrappers: Array<(fn: () => Promise<T>) => Promise<T>>\n): () => Promise<T> {\n  return wrappers.reduceRight<() => Promise<T>>(\n    (wrapped, wrapper) => async () => wrapper(wrapped),\n    fn\n  );\n}\n\n/**\n * Create a resilient function with all patterns\n */\nexport function createResilientFn<Args extends unknown[], Result>(\n  fn: (...args: Args) => Promise<Result>,\n  options: {\n    retry?: RetryConfig;\n    circuitBreaker?: CircuitBreaker;\n    bulkhead?: Bulkhead;\n    timeout?: number;\n    fallback?: Result | (() => Result | Promise<Result>);\n  } = {}\n): (...args: Args) => Promise<Result> {\n  return async (...args: Args): Promise<Result> => {\n    const execute = async (): Promise<Result> => {\n      let operation: () => Promise<Result> = async () => fn(...args);\n\n      // Apply timeout\n      const { timeout } = options;\n      if (timeout !== undefined && timeout > 0) {\n        const originalOp = operation;\n        operation = async () => withTimeout(originalOp, timeout);\n      }\n\n      // Apply circuit breaker\n      if (options.circuitBreaker !== undefined) {\n        const cb = options.circuitBreaker;\n        const originalOp = operation;\n        operation = async () => cb.execute(originalOp);\n      }\n\n      // Apply bulkhead\n      if (options.bulkhead !== undefined) {\n        const bh = options.bulkhead;\n        const originalOp = operation;\n        operation = async () => bh.execute(originalOp);\n      }\n\n      // Apply retry\n      if (options.retry !== undefined) {\n        return withRetry(operation, options.retry);\n      }\n\n      return operation();\n    };\n\n    // Apply fallback\n    if (options.fallback !== undefined) {\n      return withFallback(execute, options.fallback);\n    }\n\n    return execute();\n  };\n}\n\n/**\n * Predefined retry policies\n */\nexport const retryPolicies = {\n  /** No retry */\n  none: new RetryPolicy().attempts(1),\n\n  /** Quick retry (3 attempts, 100ms start) */\n  quick: new RetryPolicy().attempts(3).delays(100, 1000),\n\n  /** Standard retry (3 attempts, 1s start) */\n  standard: new RetryPolicy().attempts(3).delays(1000, 10000),\n\n  /** Extended retry (5 attempts, 2s start) */\n  extended: new RetryPolicy().attempts(5).delays(2000, 30000),\n\n  /** Network retry (retry on network errors) */\n  network: new RetryPolicy()\n    .attempts(3)\n    .delays(1000, 10000)\n    .retryIf((error) => {\n      if (error instanceof Error) {\n        return (\n          error.message.includes('network') ||\n          error.message.includes('fetch') ||\n          error.message.includes('ECONNREFUSED')\n        );\n      }\n      return false;\n    }),\n};\n"],"names":["DEFAULT_RETRY_CONFIG","calculateDelay","attempt","config","exponentialDelay","boundedDelay","jitterRange","sleep","ms","signal","resolve","reject","timeoutId","withRetry","fn","resolvedConfig","lastError","error","delay","RetryPolicy","max","initial","multiplier","enabled","predicate","callback","CircuitBreaker","CircuitOpenError","result","newState","oldState","cutoff","time","message","Bulkhead","maxConcurrent","maxQueue","BulkheadFullError","next","item","withTimeout","timeout","timeoutError","_","TimeoutError","withFallback","fallback","compose","wrappers","wrapped","wrapper","createResilientFn","options","args","execute","operation","originalOp","cb","bh","retryPolicies"],"mappings":"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"}