{"version":3,"sources":["../src/cache/stores/MemoryStore.ts","../src/cache/SmartCache.ts","../src/cache/stores/RedisStore.ts","../src/logger/types.ts","../src/logger/SmartLogger.ts","../src/logger/middleware/express.ts","../src/retry/CircuitBreaker.ts","../src/retry/SmartRetry.ts"],"names":["AsyncLocalStorage","randomUUID"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { CacheStore } from '../types.js';\n\ninterface MemoryEntry {\n  value: string;\n  expiresAt: number;\n}\n\n/**\n * In-memory cache store with automatic TTL expiry.\n * Uses a simple Map — no external dependencies required.\n */\nexport class MemoryStore implements CacheStore {\n  private readonly store = new Map<string, MemoryEntry>();\n  private sweepInterval: ReturnType<typeof setInterval> | null = null;\n\n  constructor(private readonly sweepIntervalMs = 30_000) {\n    // Periodic cleanup of expired entries to prevent memory leaks\n    this.sweepInterval = setInterval(() => this.sweep(), sweepIntervalMs).unref();\n  }\n\n  async get(key: string): Promise<string | null> {\n    const entry = this.store.get(key);\n    if (!entry) return null;\n    if (Date.now() > entry.expiresAt) {\n      this.store.delete(key);\n      return null;\n    }\n    return entry.value;\n  }\n\n  async set(key: string, value: string, ttlMs: number): Promise<void> {\n    if (ttlMs <= 0) throw new Error(`[rezilia/cache] TTL must be positive, got ${ttlMs}`);\n    this.store.set(key, { value, expiresAt: Date.now() + ttlMs });\n  }\n\n  async delete(key: string): Promise<void> {\n    this.store.delete(key);\n  }\n\n  async clear(): Promise<void> {\n    this.store.clear();\n  }\n\n  /** Number of entries currently in store (including possibly expired) */\n  get size(): number {\n    return this.store.size;\n  }\n\n  /** Stop the background sweep timer — call when you no longer need this store */\n  destroy(): void {\n    if (this.sweepInterval) {\n      clearInterval(this.sweepInterval);\n      this.sweepInterval = null;\n    }\n  }\n\n  private sweep(): void {\n    const now = Date.now();\n    for (const [key, entry] of this.store) {\n      if (now > entry.expiresAt) this.store.delete(key);\n    }\n  }\n}\n","import { MemoryStore } from './stores/MemoryStore.js';\nimport type { CacheStore, SmartCacheOptions, GetOptions, CacheEntry } from './types.js';\n\n/**\n * SmartCache — eliminates the two hardest caching problems in Node.js:\n *\n * 1. **Cache Stampede** (a.k.a. thundering herd): when a hot key expires,\n *    thousands of requests hit the database simultaneously. SmartCache uses\n *    the *singleflight* pattern — only ONE request fetches; the rest wait\n *    and share the result.\n *\n * 2. **Stale-While-Revalidate**: instead of blocking on a cache miss, serve\n *    the stale value instantly and refresh in the background.\n *\n * @example\n * const cache = new SmartCache({ defaultTtl: 60_000 });\n *\n * const user = await cache.get('user:42', () => db.findUser(42));\n * // Second call returns from cache instantly — no DB hit.\n */\nexport class SmartCache {\n  private readonly store: CacheStore;\n  private readonly defaultTtl: number;\n  private readonly jitterFactor: number;\n  private readonly staleWhileRevalidate: boolean;\n  private readonly staleTtl: number;\n\n  /** In-flight requests — key → pending Promise (singleflight map) */\n  private readonly inflight = new Map<string, Promise<unknown>>();\n\n  /** Local in-process cache — avoids JSON parse on every hit */\n  private readonly localCache = new Map<string, CacheEntry<unknown>>();\n\n  constructor(options: SmartCacheOptions = {}) {\n    this.store = options.store ?? new MemoryStore();\n    this.defaultTtl = options.defaultTtl ?? 60_000;\n    this.jitterFactor = this.validateJitter(options.jitterFactor ?? 0.1);\n    this.staleWhileRevalidate = options.staleWhileRevalidate ?? true;\n    this.staleTtl = options.staleTtl ?? 5_000;\n  }\n\n  /**\n   * Get a value from cache, or call `fetcher` to populate it.\n   *\n   * - Concurrent calls with the same key share ONE fetcher call (singleflight).\n   * - Stale values are served immediately while a background refresh runs.\n   *\n   * @param key   Cache key\n   * @param fetcher Function that returns the fresh value (called at most once per stampede window)\n   * @param options Per-key TTL / jitter overrides\n   */\n  async get<T>(key: string, fetcher: () => Promise<T>, options: GetOptions = {}): Promise<T> {\n    this.validateKey(key);\n\n    const ttl = options.ttl ?? this.defaultTtl;\n    const jitter = options.jitterFactor ?? this.jitterFactor;\n    const now = Date.now();\n\n    // 1. Check local in-process cache first (fast path — no async)\n    const local = this.localCache.get(key) as CacheEntry<T> | undefined;\n    if (local) {\n      if (now < local.expiresAt) return local.value;\n\n      // Stale-while-revalidate: serve stale immediately, refresh in background\n      if (this.staleWhileRevalidate && now < local.staleUntil) {\n        void this.revalidate(key, fetcher, ttl, jitter);\n        return local.value;\n      }\n    }\n\n    // 2. Check backing store (handles multi-instance / Redis)\n    const stored = await this.store.get(key);\n    if (stored !== null) {\n      const parsed = JSON.parse(stored) as CacheEntry<T>;\n      if (now < parsed.expiresAt) {\n        this.localCache.set(key, parsed); // warm local cache\n        return parsed.value;\n      }\n\n      if (this.staleWhileRevalidate && now < parsed.staleUntil) {\n        this.localCache.set(key, parsed);\n        void this.revalidate(key, fetcher, ttl, jitter);\n        return parsed.value;\n      }\n    }\n\n    // 3. Cache miss — use singleflight to prevent stampede\n    return this.singleflight(key, fetcher, ttl, jitter);\n  }\n\n  /**\n   * Explicitly set a value in cache.\n   */\n  async set<T>(key: string, value: T, options: GetOptions = {}): Promise<void> {\n    this.validateKey(key);\n    const ttl = options.ttl ?? this.defaultTtl;\n    const jitter = options.jitterFactor ?? this.jitterFactor;\n    await this.writeToStore(key, value, ttl, jitter);\n  }\n\n  /**\n   * Delete a key from cache.\n   */\n  async invalidate(key: string): Promise<void> {\n    this.validateKey(key);\n    this.localCache.delete(key);\n    await this.store.delete(key);\n  }\n\n  /**\n   * Clear all cached values.\n   */\n  async clear(): Promise<void> {\n    this.localCache.clear();\n    await this.store.clear();\n  }\n\n  /** Returns number of in-flight requests (useful for monitoring) */\n  get inflightCount(): number {\n    return this.inflight.size;\n  }\n\n  // ─── Private helpers ────────────────────────────────────────────────────────\n\n  /**\n   * Singleflight: if there's already a fetch in progress for this key,\n   * return that same promise. Otherwise start a new one.\n   */\n  private singleflight<T>(\n    key: string,\n    fetcher: () => Promise<T>,\n    ttl: number,\n    jitter: number,\n  ): Promise<T> {\n    const existing = this.inflight.get(key);\n    if (existing) return existing as Promise<T>;\n\n    const promise = (async () => {\n      try {\n        const value = await fetcher();\n        await this.writeToStore(key, value, ttl, jitter);\n        return value;\n      } finally {\n        this.inflight.delete(key);\n      }\n    })();\n\n    this.inflight.set(key, promise);\n    return promise;\n  }\n\n  /**\n   * Background revalidation for stale-while-revalidate.\n   * Errors are swallowed so they don't surface to the caller.\n   */\n  private async revalidate<T>(\n    key: string,\n    fetcher: () => Promise<T>,\n    ttl: number,\n    jitter: number,\n  ): Promise<void> {\n    // Avoid multiple concurrent revalidations for the same key\n    if (this.inflight.has(key)) return;\n\n    const promise = (async () => {\n      try {\n        const value = await fetcher();\n        await this.writeToStore(key, value, ttl, jitter);\n      } catch {\n        // Revalidation failure is non-fatal — stale value was already returned\n      } finally {\n        this.inflight.delete(key);\n      }\n    })();\n\n    this.inflight.set(key, promise);\n    await promise;\n  }\n\n  private async writeToStore<T>(\n    key: string,\n    value: T,\n    ttl: number,\n    jitter: number,\n  ): Promise<void> {\n    const jitteredTtl = this.applyJitter(ttl, jitter);\n    const now = Date.now();\n    const entry: CacheEntry<T> = {\n      value,\n      expiresAt: now + jitteredTtl,\n      staleUntil: now + jitteredTtl + this.staleTtl,\n    };\n    this.localCache.set(key, entry);\n    await this.store.set(key, JSON.stringify(entry), jitteredTtl + this.staleTtl);\n  }\n\n  /** Apply ±jitter% randomness to TTL to spread out expirations */\n  private applyJitter(ttl: number, jitter: number): number {\n    const delta = ttl * jitter;\n    return Math.round(ttl + (Math.random() * 2 - 1) * delta);\n  }\n\n  private validateJitter(jitter: number): number {\n    if (jitter < 0 || jitter > 1) {\n      throw new RangeError(`[rezilia/cache] jitterFactor must be between 0 and 1, got ${jitter}`);\n    }\n    return jitter;\n  }\n\n  private validateKey(key: string): void {\n    if (!key || typeof key !== 'string') {\n      throw new TypeError(`[rezilia/cache] Cache key must be a non-empty string`);\n    }\n    if (key.length > 512) {\n      throw new RangeError(`[rezilia/cache] Cache key too long (max 512 chars)`);\n    }\n  }\n}\n","import type { CacheStore } from '../types.js';\n\n/**\n * Minimal interface we need from ioredis — keeps the dependency optional.\n * If you use ioredis, pass the client directly; it satisfies this interface.\n */\nexport interface RedisClient {\n  get(key: string): Promise<string | null>;\n  set(key: string, value: string, ex: 'PX', ttl: number): Promise<unknown>;\n  del(key: string): Promise<unknown>;\n  flushdb(): Promise<unknown>;\n}\n\n/**\n * Redis-backed cache store using ioredis (peer dependency).\n *\n * @example\n * import Redis from 'ioredis';\n * import { SmartCache, RedisStore } from 'rezilia/cache';\n *\n * const client = new Redis({ host: 'localhost', port: 6379 });\n * const cache = new SmartCache({ store: new RedisStore(client) });\n */\nexport class RedisStore implements CacheStore {\n  constructor(private readonly client: RedisClient) {}\n\n  async get(key: string): Promise<string | null> {\n    return this.client.get(key);\n  }\n\n  async set(key: string, value: string, ttlMs: number): Promise<void> {\n    if (ttlMs <= 0) throw new Error(`[rezilia/cache] TTL must be positive, got ${ttlMs}`);\n    await this.client.set(key, value, 'PX', ttlMs);\n  }\n\n  async delete(key: string): Promise<void> {\n    await this.client.del(key);\n  }\n\n  async clear(): Promise<void> {\n    await this.client.flushdb();\n  }\n}\n","export type LogLevel = 'debug' | 'info' | 'warn' | 'error' | 'silent';\n\nexport const LOG_LEVELS: Record<LogLevel, number> = {\n  debug: 0,\n  info: 1,\n  warn: 2,\n  error: 3,\n  silent: 4,\n};\n\nexport interface LogContext {\n  requestId?: string;\n  userId?: string;\n  traceId?: string;\n  [key: string]: unknown;\n}\n\nexport interface LogEntry {\n  level: LogLevel;\n  message: string;\n  timestamp: string;\n  context: LogContext;\n  error?: SerializedError;\n  data?: Record<string, unknown>;\n}\n\nexport interface SerializedError {\n  name: string;\n  message: string;\n  stack: string | undefined;\n  code: string | number | undefined;\n}\n\nexport interface Transport {\n  write(entry: LogEntry): void;\n}\n\nexport interface SmartLoggerOptions {\n  /** Minimum log level to output (default: 'info') */\n  level?: LogLevel;\n  /** Service/app name added to every log entry */\n  serviceName?: string;\n  /** Custom transports (default: console JSON transport) */\n  transports?: Transport[];\n  /**\n   * Fields to automatically redact from log output.\n   * Values are replaced with '[REDACTED]'.\n   * Default: ['password', 'token', 'secret', 'authorization', 'cookie', 'apiKey', 'api_key']\n   */\n  redactFields?: string[];\n  /** Pretty-print logs (useful in development, never in production) */\n  prettyPrint?: boolean;\n}\n","import { AsyncLocalStorage } from 'node:async_hooks';\nimport { randomUUID } from 'node:crypto';\nimport type {\n  LogLevel,\n  LogContext,\n  LogEntry,\n  SerializedError,\n  SmartLoggerOptions,\n  Transport,\n} from './types.js';\nimport { LOG_LEVELS } from './types.js';\n\n// Default fields to redact — prevent secrets from leaking into logs\nconst DEFAULT_REDACT_FIELDS = [\n  'password',\n  'passwd',\n  'token',\n  'accessToken',\n  'access_token',\n  'refreshToken',\n  'refresh_token',\n  'secret',\n  'authorization',\n  'cookie',\n  'apiKey',\n  'api_key',\n  'privateKey',\n  'private_key',\n  'cvv',\n  'cardNumber',\n  'card_number',\n];\n\n/**\n * Console transport — outputs structured JSON (or pretty-printed) logs.\n */\nclass ConsoleTransport implements Transport {\n  constructor(private readonly pretty: boolean) {}\n\n  write(entry: LogEntry): void {\n    const output = this.pretty ? JSON.stringify(entry, null, 2) : JSON.stringify(entry);\n    if (entry.level === 'error' || entry.level === 'warn') {\n      process.stderr.write(output + '\\n');\n    } else {\n      process.stdout.write(output + '\\n');\n    }\n  }\n}\n\n/**\n * SmartLogger — structured, context-aware logging for Node.js backends.\n *\n * Key features:\n * - **Async context propagation**: request ID automatically flows through\n *   all async calls without manual passing — powered by AsyncLocalStorage.\n * - **Automatic redaction**: sensitive fields (passwords, tokens, etc.) are\n *   replaced with '[REDACTED]' before writing to any transport.\n * - **Structured JSON output**: machine-parseable logs, OpenTelemetry-ready.\n * - **Child loggers**: create scoped loggers that inherit parent context.\n *\n * @example\n * const logger = new SmartLogger({ serviceName: 'api', level: 'info' });\n *\n * // In Express middleware:\n * app.use((req, res, next) => {\n *   logger.runWithContext({ requestId: req.headers['x-request-id'] ?? randomUUID() }, next);\n * });\n *\n * // Anywhere in the async call chain:\n * logger.info('User created', { userId: '123' });\n * // → {\"level\":\"info\",\"message\":\"User created\",\"context\":{\"requestId\":\"abc-123\"},\"data\":{\"userId\":\"123\"}}\n */\nexport class SmartLogger {\n  private readonly level: LogLevel;\n  private readonly serviceName: string | undefined;\n  private readonly transports: Transport[];\n  private readonly redactFields: Set<string>;\n  private readonly storage = new AsyncLocalStorage<LogContext>();\n  private readonly baseContext: LogContext;\n\n  constructor(options: SmartLoggerOptions = {}) {\n    this.level = options.level ?? 'info';\n    this.serviceName = options.serviceName;\n    this.transports =\n      options.transports ?? [new ConsoleTransport(options.prettyPrint ?? false)];\n    this.redactFields = new Set([\n      ...DEFAULT_REDACT_FIELDS,\n      ...(options.redactFields ?? []),\n    ]);\n    this.baseContext = this.serviceName ? { service: this.serviceName } : {};\n  }\n\n  // ─── Context management ─────────────────────────────────────────────────────\n\n  /**\n   * Run `fn` with the given context available to all nested async calls.\n   * Use this in middleware to inject requestId, userId, traceId, etc.\n   */\n  runWithContext<T>(context: LogContext, fn: () => T): T {\n    const merged = { ...this.currentContext, ...context };\n    return this.storage.run(merged, fn);\n  }\n\n  /**\n   * Generate a new requestId and run `fn` within that context.\n   * Convenience wrapper for runWithContext.\n   */\n  withRequestId<T>(fn: () => T, extraContext: LogContext = {}): T {\n    return this.runWithContext({ requestId: randomUUID(), ...extraContext }, fn);\n  }\n\n  /** Get the context bound to the current async scope */\n  get currentContext(): LogContext {\n    return this.storage.getStore() ?? this.baseContext;\n  }\n\n  // ─── Logging methods ─────────────────────────────────────────────────────────\n\n  debug(message: string, data?: Record<string, unknown>): void {\n    this.write('debug', message, data);\n  }\n\n  info(message: string, data?: Record<string, unknown>): void {\n    this.write('info', message, data);\n  }\n\n  warn(message: string, data?: Record<string, unknown>): void {\n    this.write('warn', message, data);\n  }\n\n  error(message: string, error?: unknown, data?: Record<string, unknown>): void {\n    const serialized = error ? this.serializeError(error) : undefined;\n    this.write('error', message, data, serialized);\n  }\n\n  // ─── Child logger ────────────────────────────────────────────────────────────\n\n  /**\n   * Create a child logger that merges `context` into every log entry.\n   * The child shares the parent's transports and settings.\n   *\n   * @example\n   * const reqLogger = logger.child({ requestId: req.id, userId: req.user.id });\n   * reqLogger.info('Payment started'); // includes requestId + userId automatically\n   */\n  child(context: LogContext): SmartLogger {\n    const childOpts: SmartLoggerOptions = {\n      level: this.level,\n      transports: this.transports,\n      redactFields: [...this.redactFields],\n    };\n    if (this.serviceName !== undefined) childOpts.serviceName = this.serviceName;\n    const child = new SmartLogger(childOpts);\n    // Bind the extra context into the child by hijacking currentContext\n    Object.assign(child.baseContext, this.currentContext, context);\n    return child;\n  }\n\n  // ─── Private ─────────────────────────────────────────────────────────────────\n\n  private write(\n    level: LogLevel,\n    message: string,\n    data?: Record<string, unknown>,\n    error?: SerializedError,\n  ): void {\n    if (LOG_LEVELS[level] < LOG_LEVELS[this.level]) return;\n\n    const entry: LogEntry = {\n      level,\n      message,\n      timestamp: new Date().toISOString(),\n      context: { ...this.baseContext, ...this.currentContext },\n      ...(error ? { error } : {}),\n      ...(data ? { data: this.redact(data) } : {}),\n    };\n\n    for (const transport of this.transports) {\n      transport.write(entry);\n    }\n  }\n\n  private redact(obj: Record<string, unknown>): Record<string, unknown> {\n    const result: Record<string, unknown> = {};\n    for (const [key, value] of Object.entries(obj)) {\n      if (this.redactFields.has(key)) {\n        result[key] = '[REDACTED]';\n      } else if (value !== null && typeof value === 'object' && !Array.isArray(value)) {\n        result[key] = this.redact(value as Record<string, unknown>);\n      } else {\n        result[key] = value;\n      }\n    }\n    return result;\n  }\n\n  private serializeError(error: unknown): SerializedError {\n    if (error instanceof Error) {\n      const nodeErr = error as NodeJS.ErrnoException;\n      return {\n        name: error.name,\n        message: error.message,\n        stack: error.stack,\n        code: nodeErr.code,\n      };\n    }\n    return { name: 'UnknownError', message: String(error), stack: undefined, code: undefined };\n  }\n}\n","import { randomUUID } from 'node:crypto';\nimport type { SmartLogger } from '../SmartLogger.js';\n\n/**\n * Minimal Express-compatible types — avoids hard dependency on @types/express.\n */\ninterface Request {\n  headers: Record<string, string | string[] | undefined>;\n  method: string;\n  url: string;\n  [key: string]: unknown;\n}\n\ninterface Response {\n  statusCode: number;\n  on(event: string, listener: () => void): void;\n  setHeader(name: string, value: string): void;\n  [key: string]: unknown;\n}\n\ntype NextFunction = () => void;\n\n/**\n * Express middleware that:\n * 1. Attaches a requestId to every incoming request (from header or generated).\n * 2. Runs the rest of the chain inside a logging context — so every log\n *    call inside a request handler automatically includes the requestId.\n * 3. Logs request start and completion with duration.\n *\n * @example\n * import express from 'express';\n * import { SmartLogger } from 'rezilia/logger';\n * import { requestLogger } from 'rezilia/logger/middleware/express';\n *\n * const app = express();\n * const logger = new SmartLogger({ serviceName: 'api' });\n * app.use(requestLogger(logger));\n */\nexport function requestLogger(logger: SmartLogger) {\n  return (req: Request, res: Response, next: NextFunction): void => {\n    const requestId =\n      (Array.isArray(req.headers['x-request-id'])\n        ? req.headers['x-request-id'][0]\n        : req.headers['x-request-id']) ?? randomUUID();\n\n    const startedAt = Date.now();\n\n    // Expose requestId to the client\n    res.setHeader('x-request-id', requestId);\n\n    logger.runWithContext({ requestId }, () => {\n      logger.info('Request started', { method: req.method, url: req.url });\n\n      res.on('finish', () => {\n        const duration = Date.now() - startedAt;\n        const level = res.statusCode >= 500 ? 'error' : res.statusCode >= 400 ? 'warn' : 'info';\n        logger[level]('Request completed', {\n          method: req.method,\n          url: req.url,\n          status: res.statusCode,\n          durationMs: duration,\n        });\n      });\n\n      next();\n    });\n  };\n}\n","import type { CircuitBreakerOptions, CircuitState } from './types.js';\n\n/**\n * Circuit Breaker — protects your app from cascading failures.\n *\n * States:\n * - **CLOSED** (normal): requests flow through; failures are counted.\n * - **OPEN** (tripped): all requests fail fast — no upstream calls made.\n * - **HALF_OPEN** (testing): a limited number of requests probe if recovery happened.\n *\n * @example\n * const breaker = new CircuitBreaker({ threshold: 5, resetAfter: 30_000 });\n * await breaker.execute(() => fetch('/api/payments'));\n */\nexport class CircuitBreaker {\n  private state: CircuitState = 'CLOSED';\n  private failureCount = 0;\n  private successCount = 0;\n  private openedAt = 0;\n\n  private readonly threshold: number;\n  private readonly resetAfter: number;\n  private readonly halfOpenSuccesses: number;\n\n  constructor(options: CircuitBreakerOptions = {}) {\n    this.threshold = options.threshold ?? 5;\n    this.resetAfter = options.resetAfter ?? 30_000;\n    this.halfOpenSuccesses = options.halfOpenSuccesses ?? 2;\n  }\n\n  /** Current state of the circuit */\n  get currentState(): CircuitState {\n    return this.state;\n  }\n\n  /**\n   * Execute `fn` through the circuit breaker.\n   * Throws `CircuitOpenError` when the circuit is OPEN.\n   */\n  async execute<T>(fn: () => Promise<T>): Promise<T> {\n    this.transitionIfNeeded();\n\n    if (this.state === 'OPEN') {\n      throw new CircuitOpenError(\n        `Circuit is OPEN — upstream failures: ${this.failureCount}. ` +\n        `Will retry after ${Math.round((this.resetAfter - (Date.now() - this.openedAt)) / 1000)}s.`,\n      );\n    }\n\n    try {\n      const result = await fn();\n      this.onSuccess();\n      return result;\n    } catch (error) {\n      this.onFailure();\n      throw error;\n    }\n  }\n\n  /** Reset the circuit to CLOSED (useful in tests or manual recovery) */\n  reset(): void {\n    this.state = 'CLOSED';\n    this.failureCount = 0;\n    this.successCount = 0;\n  }\n\n  // ─── Private ─────────────────────────────────────────────────────────────────\n\n  private onSuccess(): void {\n    this.failureCount = 0;\n    if (this.state === 'HALF_OPEN') {\n      this.successCount++;\n      if (this.successCount >= this.halfOpenSuccesses) {\n        this.state = 'CLOSED';\n        this.successCount = 0;\n      }\n    }\n  }\n\n  private onFailure(): void {\n    this.failureCount++;\n    if (this.state === 'HALF_OPEN') {\n      // Probe failed — reopen immediately\n      this.trip();\n    } else if (this.failureCount >= this.threshold) {\n      this.trip();\n    }\n  }\n\n  private trip(): void {\n    this.state = 'OPEN';\n    this.openedAt = Date.now();\n    this.successCount = 0;\n  }\n\n  private transitionIfNeeded(): void {\n    if (this.state === 'OPEN' && Date.now() - this.openedAt >= this.resetAfter) {\n      this.state = 'HALF_OPEN';\n      this.failureCount = 0;\n    }\n  }\n}\n\n/**\n * Thrown when a call is rejected because the circuit is open.\n */\nexport class CircuitOpenError extends Error {\n  override readonly name = 'CircuitOpenError';\n  constructor(message: string) {\n    super(message);\n  }\n}\n","import { CircuitBreaker } from './CircuitBreaker.js';\nimport type { SmartRetryOptions } from './types.js';\n\n/**\n * Error thrown when all retry attempts are exhausted.\n */\nexport class RetryExhaustedError extends Error {\n  override readonly name = 'RetryExhaustedError';\n  readonly attempts: number;\n  readonly lastError: unknown;\n\n  constructor(attempts: number, lastError: unknown) {\n    const msg = lastError instanceof Error ? lastError.message : String(lastError);\n    super(`All ${attempts} attempt(s) failed. Last error: ${msg}`);\n    this.attempts = attempts;\n    this.lastError = lastError;\n  }\n}\n\n/**\n * Error thrown when a single attempt exceeds the configured timeout.\n */\nexport class TimeoutError extends Error {\n  override readonly name = 'TimeoutError';\n  constructor(timeoutMs: number) {\n    super(`Operation timed out after ${timeoutMs}ms`);\n  }\n}\n\n/**\n * SmartRetry — production-grade retry logic with exponential backoff, jitter,\n * per-attempt timeouts, and an optional circuit breaker.\n *\n * @example\n * // Simple: 3 attempts, exponential backoff\n * const data = await retry(() => fetch('/api/data').then(r => r.json()));\n *\n * // Advanced: with circuit breaker\n * const retry = new SmartRetry({\n *   attempts: 5,\n *   timeout: 5_000,\n *   circuitBreaker: { threshold: 5, resetAfter: 30_000 },\n * });\n * const result = await retry.execute(() => callExternalApi());\n */\nexport class SmartRetry {\n  private readonly attempts: number;\n  private readonly baseDelay: number;\n  private readonly maxDelay: number;\n  private readonly jitter: number;\n  private readonly timeout: number;\n  private readonly shouldRetry: (error: unknown, attempt: number) => boolean;\n  private readonly onRetry: ((error: unknown, attempt: number, delayMs: number) => void) | undefined;\n  private readonly breaker: CircuitBreaker | undefined;\n\n  constructor(options: SmartRetryOptions = {}) {\n    this.attempts = options.attempts ?? 3;\n    this.baseDelay = options.baseDelay ?? 500;\n    this.maxDelay = options.maxDelay ?? 30_000;\n    this.jitter = options.jitter ?? 0.2;\n    this.timeout = options.timeout ?? 0;\n    this.shouldRetry = options.shouldRetry ?? (() => true);\n    this.onRetry = options.onRetry;\n    this.breaker = options.circuitBreaker\n      ? new CircuitBreaker(options.circuitBreaker)\n      : undefined;\n  }\n\n  /**\n   * Execute `fn` with retry logic applied.\n   */\n  async execute<T>(fn: () => Promise<T>): Promise<T> {\n    let lastError: unknown;\n\n    for (let attempt = 1; attempt <= this.attempts; attempt++) {\n      try {\n        const result = await this.runWithTimeout(\n          this.breaker ? () => this.breaker!.execute(fn) : fn,\n        );\n        return result;\n      } catch (error) {\n        lastError = error;\n\n        const isLastAttempt = attempt === this.attempts;\n        if (isLastAttempt || !this.shouldRetry(error, attempt)) {\n          break;\n        }\n\n        const delay = this.calculateDelay(attempt);\n        this.onRetry?.(error, attempt, delay);\n        await this.sleep(delay);\n      }\n    }\n\n    throw new RetryExhaustedError(this.attempts, lastError);\n  }\n\n  /** Current circuit breaker state (undefined if no breaker configured) */\n  get circuitState(): string | undefined {\n    return this.breaker?.currentState;\n  }\n\n  /** Manually reset the circuit breaker */\n  resetCircuit(): void {\n    this.breaker?.reset();\n  }\n\n  // ─── Private ─────────────────────────────────────────────────────────────────\n\n  private async runWithTimeout<T>(fn: () => Promise<T>): Promise<T> {\n    if (!this.timeout) return fn();\n\n    return new Promise<T>((resolve, reject) => {\n      const timer = setTimeout(\n        () => reject(new TimeoutError(this.timeout)),\n        this.timeout,\n      );\n\n      fn().then(\n        (value) => { clearTimeout(timer); resolve(value); },\n        (error: unknown) => { clearTimeout(timer); reject(error); },\n      );\n    });\n  }\n\n  /**\n   * Exponential backoff with jitter:\n   * delay = clamp(baseDelay * 2^(attempt-1) ± jitter%, 0, maxDelay)\n   */\n  private calculateDelay(attempt: number): number {\n    const exponential = this.baseDelay * Math.pow(2, attempt - 1);\n    const capped = Math.min(exponential, this.maxDelay);\n    const delta = capped * this.jitter;\n    const jittered = capped + (Math.random() * 2 - 1) * delta;\n    return Math.max(0, Math.round(jittered));\n  }\n\n  private sleep(ms: number): Promise<void> {\n    return new Promise((resolve) => setTimeout(resolve, ms));\n  }\n}\n\n/**\n * Convenience function for one-off retries.\n *\n * @example\n * const data = await retry(() => api.getData(), { attempts: 3, timeout: 5000 });\n */\nexport async function retry<T>(\n  fn: () => Promise<T>,\n  options: SmartRetryOptions = {},\n): Promise<T> {\n  return new SmartRetry(options).execute(fn);\n}\n"]}