import { logger } from "@pkg/logger"; export class RateLimiter { private requestTimestamps: number[] = []; private readonly callsPerMinute: number; constructor(callsPerMinute: number = 60) { this.callsPerMinute = Math.min(callsPerMinute, 60); } async checkRateLimit(): Promise { const currentTime = Date.now(); const oneMinuteAgo = currentTime - 60000; // 60 seconds in milliseconds // Remove timestamps older than 1 minute this.requestTimestamps = this.requestTimestamps.filter( (timestamp) => timestamp > oneMinuteAgo, ); // If we're approaching the limit, wait until we have capacity if (this.requestTimestamps.length >= this.callsPerMinute) { const oldestRequest = this.requestTimestamps[0]; const waitTime = oldestRequest + 60000 - currentTime; if (waitTime > 0) { logger.warn( `Rate limit approaching (${this.requestTimestamps.length} requests in last minute). Sleeping for ${waitTime}ms`, ); await new Promise((resolve) => setTimeout(resolve, waitTime)); // After waiting, some timestamps may have expired this.requestTimestamps = this.requestTimestamps.filter( (timestamp) => timestamp > Date.now() - 60000, ); } } // Add current request to timestamps this.requestTimestamps.push(Date.now()); } }