Spaces:
Sleeping
Sleeping
File size: 1,179 Bytes
1c7b998 ef84ace 1c7b998 ef84ace 1c7b998 ef84ace 1c7b998 ef84ace b11153a ef84ace | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | /** Above this many tracked keys, prune stale entries on the next `allow` before inserting. */
const MAX_TRACKED_KEYS = 10_000;
/** Sliding-window limiter: at most `max` allowed calls per key within `windowMs`. In-memory only. */
export class RateLimiter {
private hits = new Map<string, number[]>();
constructor(
private readonly max: number,
private readonly windowMs: number,
private readonly now: () => number = Date.now
) {}
/** Number of keys currently tracked. Exposed for tests. */
get size(): number {
return this.hits.size;
}
allow(key: string): boolean {
const t = this.now();
const recent = (this.hits.get(key) ?? []).filter((h) => t - h < this.windowMs);
if (recent.length >= this.max) {
if (recent.length === 0) this.hits.delete(key);
else this.hits.set(key, recent);
return false;
}
if (this.hits.size > MAX_TRACKED_KEYS) {
for (const [k, hs] of this.hits) {
const mostRecent = hs.length > 0 ? Math.max(...hs) : -Infinity;
if (t - mostRecent >= this.windowMs) this.hits.delete(k);
}
}
recent.push(t);
this.hits.set(key, recent);
return true;
}
reset(key: string): void {
this.hits.delete(key);
}
}
|