"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CircuitBreaker = void 0;
class CircuitBreaker {
    failures = 0;
    state = 'closed';
    openedAt = 0;
    options;
    constructor(options) {
        this.options = {
            failureThreshold: options?.failureThreshold ?? 5,
            resetTimeoutMs: options?.resetTimeoutMs ?? 30_000,
        };
    }
    getState() {
        if (this.state === 'open' && Date.now() - this.openedAt >= this.options.resetTimeoutMs) {
            this.state = 'half_open';
        }
        return this.state;
    }
    async execute(fn) {
        const state = this.getState();
        if (state === 'open') {
            throw new Error('Circuit breaker open');
        }
        try {
            const result = await fn();
            this.onSuccess();
            return result;
        }
        catch (e) {
            this.onFailure();
            throw e;
        }
    }
    onSuccess() {
        this.failures = 0;
        this.state = 'closed';
    }
    onFailure() {
        this.failures += 1;
        if (this.failures >= this.options.failureThreshold) {
            this.state = 'open';
            this.openedAt = Date.now();
        }
    }
}
exports.CircuitBreaker = CircuitBreaker;
