// A sliding-window count per key, for the doors a stranger can knock on. export class RateLimit { private hits = new Map(); constructor( private limit: number, private windowMs: number ) {} /** True if the key may act now; the act is recorded when it is allowed. */ allow(key: string, now = Date.now()): boolean { const since = now - this.windowMs; const recent = (this.hits.get(key) ?? []).filter((t) => t > since); if (recent.length >= this.limit) { this.hits.set(key, recent); return false; } recent.push(now); this.hits.set(key, recent); if (this.hits.size > 10000) this.prune(now); return true; } prune(now = Date.now()): void { const since = now - this.windowMs; for (const [key, times] of this.hits) { if (!times.some((t) => t > since)) this.hits.delete(key); } } }