forked from EduCraft/curriculum-project-hub
26 lines
936 B
TypeScript
26 lines
936 B
TypeScript
export class SiloFixedWindowRateLimiter {
|
|
private windowStartedAt: number;
|
|
private used = 0;
|
|
|
|
constructor(readonly limit: number, readonly windowMs: number, now = Date.now()) {
|
|
if (!Number.isSafeInteger(limit) || limit <= 0) throw new Error("rate limit must be a positive integer");
|
|
if (!Number.isSafeInteger(windowMs) || windowMs <= 0) throw new Error("rate window must be a positive integer");
|
|
this.windowStartedAt = now;
|
|
}
|
|
|
|
consume(now = Date.now()): { readonly allowed: true } | { readonly allowed: false; readonly retryAfterSeconds: number } {
|
|
if (now >= this.windowStartedAt + this.windowMs) {
|
|
this.windowStartedAt = now;
|
|
this.used = 0;
|
|
}
|
|
if (this.used >= this.limit) {
|
|
return {
|
|
allowed: false,
|
|
retryAfterSeconds: Math.max(1, Math.ceil((this.windowStartedAt + this.windowMs - now) / 1000)),
|
|
};
|
|
}
|
|
this.used += 1;
|
|
return { allowed: true };
|
|
}
|
|
}
|