export interface RateLimiterOptions { minIntervalMs: number; } export interface RateLimiter { schedule(operation: () => Promise): Promise; } export function createRateLimiter(options: RateLimiterOptions): RateLimiter { let lastStart = 0; let chain: Promise = Promise.resolve(); return { schedule(operation: () => Promise): Promise { const run = async (): Promise => { const now = Date.now(); const waitMs = Math.max(0, lastStart + options.minIntervalMs - now); if (waitMs > 0) await sleep(waitMs); lastStart = Date.now(); return operation(); }; const next = chain.then(run, run); chain = next.catch(() => undefined); return next; }, }; } function sleep(ms: number): Promise { return new Promise((resolve) => setTimeout(resolve, ms)); }