declare enum CircuitBreakerState { CLOSED = "closed", OPEN = "open", HALF_OPEN = "half_open" } interface CircuitBreakerConfig { name: string; /** % of calls in the sliding window that must fail to open the circuit (0-100). Default: 50 */ failureThreshold: number; /** % of calls in the sliding window that are slow to open the circuit (0-100). Default: 100 (disabled) */ slowCallThreshold: number; /** Duration in ms above which a successful call is considered slow. Default: 60000 */ slowCallDurationMs: number; /** Minimum number of calls in the window before thresholds are evaluated. Default: 5 */ minimumCalls: number; /** Size of the count-based sliding window. Default: 10 */ slidingWindowSize: number; /** Number of test calls allowed in HALF_OPEN before deciding to close or reopen. Default: 3 */ halfOpenMaxCalls: number; /** Time in ms to wait in OPEN before transitioning to HALF_OPEN. Default: 60000 */ openTimeoutMs: number; /** * Classifies whether a thrown error counts as an infrastructure failure * (opens the circuit) or a business error (transparent pass-through). * * Return `true` -> infrastructure error -- counted against the circuit. * Return `false` -> business error -- the circuit treats the call as a success. * * Default: all errors count as infrastructure failures. * * @example * // Only HTTP 5xx and non-HTTP errors open the circuit * isFailure: (err) => !(err instanceof HttpException) || err.getStatus() >= 500 */ isFailure: (error: unknown) => boolean; /** * Called every time the circuit transitions between states. * Use it for logging, alerting, or updating external dashboards. * * @example * onStateChange: (from, to, metrics) => { * logger.warn(`Circuit ${metrics.name}: ${from} -> ${to}`); * if (to === CircuitBreakerState.OPEN) alerting.trigger(metrics); * } */ onStateChange?: (from: CircuitBreakerState, to: CircuitBreakerState, metrics: CircuitBreakerMetrics) => void; } interface CircuitBreakerMetrics { name: string; state: CircuitBreakerState; failureRate: number; slowCallRate: number; bufferedCalls: number; totalCalls: number; successfulCalls: number; failedCalls: number; slowCalls: number; notPermittedCalls: number; } declare class CircuitBreakerOpenError extends Error { constructor(name: string); } declare const DEFAULT_CIRCUIT_BREAKER_CONFIG: Omit; declare class CircuitBreaker { private config; private state; private window; private openedAt; private halfOpenCalls; private halfOpenSuccesses; private totalCalls; private successfulCalls; private failedCalls; private slowCalls; private notPermittedCalls; private readonly mutex; constructor(config: CircuitBreakerConfig); updateConfig(partial: Partial>): void; private validateConfig; /** * Executes a task inside the circuit breaker. * * @param task - The operation to protect. * @param fallback - Optional controlled exit when the circuit is OPEN or an * infrastructure error occurs. Receives the error so you can distinguish * between `CircuitBreakerOpenError` (circuit was already open) and an * actual failure. Business errors (where `isFailure` returns `false`) are * always re-thrown without invoking the fallback. * * @example * const data = await cb.execute( * () => fetchFromApi(id), * (err) => err instanceof CircuitBreakerOpenError * ? cache.get(id) // circuit open -> serve cache * : defaultResponse(id), // infra failure -> safe default * ); */ execute(task: () => Promise, fallback?: (error: unknown) => T | Promise): Promise; private onSuccess; private onError; private record; private evaluateThresholds; private syncState; private transitionTo; canAttempt(): boolean; getState(): CircuitBreakerState; getMetrics(): CircuitBreakerMetrics; reset(): void; } interface CircuitBreakerOptions extends Partial { name: string; } declare class CircuitBreakerRegistry { private readonly breakers; getOrCreate(options: CircuitBreakerOptions): CircuitBreaker; /** * For external HTTP calls. * Only HTTP 5xx and non-HTTP errors (network, timeout) open the circuit. * HTTP 4xx (business errors like 404, 401, 422) pass through transparently. */ getForHttpExternal(serviceName: string): CircuitBreaker; /** * For internal service-to-service calls. * All errors count — services should not throw business errors at each other. */ getForService(serviceName: string): CircuitBreaker; /** * For database operations. * All errors count. More sensitive threshold (30%) and shorter timeout. */ getForDatabase(schema: string): CircuitBreaker; getAllMetrics(): Record; getOpenBreakers(): CircuitBreakerMetrics[]; reset(name: string): void; resetAll(): void; } /** * Counts only HTTP 5xx and non-HTTP errors as infrastructure failures. * HTTP 4xx (404, 401, 403, 422…) are business errors — transparent to the circuit. * * Works with NestJS HttpException and any object with a `getStatus(): number` method. */ declare function isHttpServerError(error: unknown): boolean; export { CircuitBreaker, type CircuitBreakerConfig, type CircuitBreakerMetrics, CircuitBreakerOpenError, type CircuitBreakerOptions, CircuitBreakerRegistry, CircuitBreakerState, DEFAULT_CIRCUIT_BREAKER_CONFIG, isHttpServerError };