import { EventLoopDelaySampler } from "./event-loop-delay-sampler";
export class RateLimiter {
    thresholds;
    handleRateLimiterStateChange;
    refreshInterval;
    lastObservedState = 1;
    isFlagUp = false;
    intervalId;
    eventLoopDelaySampler = new EventLoopDelaySampler();
    constructor(thresholds, handleRateLimiterStateChange, refreshInterval = 1000) {
        this.thresholds = thresholds;
        this.handleRateLimiterStateChange = handleRateLimiterStateChange;
        this.refreshInterval = refreshInterval;
        // Sort thresholds by descending delay cap
        // This way we can find the first threshold that is lower than the current event loop delay easily
        this.thresholds = thresholds.sort((a, b) => b.delayCap - a.delayCap);
        this.intervalId = setInterval(() => {
            this.refreshRateLimiterState();
        }, refreshInterval);
    }
    dispose() {
        this.eventLoopDelaySampler.dispose();
        clearInterval(this.intervalId);
    }
    refreshRateLimiterState() {
        // If we don't know about event loop delay, we can't do anything and return 1
        if (!this.eventLoopDelaySampler.getDelay()) {
            return this.updateModuloCoefficient(1);
        }
        // Find the first threshold which is smaller than the current event loop delay
        const threshold = this.thresholds.find((threshold) => threshold.delayCap <= this.eventLoopDelaySampler.getDelay());
        // If all caps are higher than the current event loop delay, Viewer is managing the traffic fine -> return 1
        if (!threshold) {
            return this.updateModuloCoefficient(1);
        }
        this.updateModuloCoefficient(threshold.moduloCoefficient);
    }
    updateModuloCoefficient(newRecommendedModuloCoefficient) {
        // If previous value is the same do nothing or the flag is not up yet
        if (this.lastObservedState === newRecommendedModuloCoefficient || !this.isFlagUp) {
            return;
        }
        // When we first encounter modulo coefficient > 1, we need to set the flag to true as a warning for next time
        this.isFlagUp = newRecommendedModuloCoefficient > 1;
        // Else update the value and notify the listeners about the new recommended modulo coefficient
        this.lastObservedState = newRecommendedModuloCoefficient;
        this.handleRateLimiterStateChange(newRecommendedModuloCoefficient);
    }
}
//# sourceMappingURL=rate-limiter.js.map