Skip to content

Commit 79ff94c

Browse files
committed
docs(RateLimiter): add JSDoc to RateLimiter class and rateLimit function
1 parent d020cf4 commit 79ff94c

1 file changed

Lines changed: 41 additions & 7 deletions

File tree

lib/rate-limit.ts

Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,48 @@
11
import { TTLCache } from './cache';
22

3-
// In-memory rate limiter to prevent basic DoS/spam (Denial of Wallet).
4-
// Note: In a serverless environment, this resets per cold-start/instance,
5-
// but it is highly effective at stopping aggressive single-instance spikes.
6-
// For multi-instance strict syncing, a Redis store (Vercel KV/Upstash) should be used.
3+
/**
4+
* In-memory rate limiter to prevent basic DoS/spam (Denial of Wallet).
5+
*
6+
* Note: In a serverless environment, this resets per cold-start/instance,
7+
* but it is highly effective at stopping aggressive single-instance spikes.
8+
* For multi-instance strict syncing, a Redis store (Vercel KV/Upstash) should be used.
9+
*/
710
export class RateLimiter {
811
private cache: TTLCache<number>;
912
private limit: number;
1013
private windowMs: number;
1114

15+
/**
16+
* Creates a new RateLimiter instance.
17+
*
18+
* @param limit - Maximum number of requests allowed per window. Defaults to 5.
19+
* @param windowMs - Time window in milliseconds. Defaults to 60000 (1 minute).
20+
*/
1221
constructor(limit = 5, windowMs = 60000) {
1322
this.limit = limit;
1423
this.windowMs = windowMs;
15-
// Set max capacity to 10000 IPs to prevent memory leaks from the rate limiter itself
1624
this.cache = new TTLCache<number>(10000, windowMs);
1725
}
1826

19-
// Returns true if allowed, false if rate limited
27+
/**
28+
* Checks whether a request from the given IP is allowed.
29+
*
30+
* Increments the request count for the IP and resets the TTL on each call,
31+
* behaving similarly to a sliding window timeout.
32+
*
33+
* @param ip - The IP address to check.
34+
* @returns `true` if the request is allowed, `false` if rate limited.
35+
*
36+
* @example
37+
* if (!rateLimiter.check(ip)) {
38+
* return new Response("Too Many Requests", { status: 429 });
39+
* }
40+
*/
2041
check(ip: string): boolean {
2142
const current = this.cache.get(ip) || 0;
2243
if (current >= this.limit) {
2344
return false;
2445
}
25-
// We increment the count and reset the TTL, behaving similarly to a sliding window timeout.
2646
this.cache.set(ip, current + 1, this.windowMs);
2747
return true;
2848
}
@@ -47,6 +67,20 @@ interface RateLimitResult {
4767

4868
const trackers = new TTLCache<{ count: number }>(2000, 60000);
4969

70+
/**
71+
* Checks if a request from a given IP should be rate limited.
72+
*
73+
* @param ip - The IP address to track.
74+
* @param limit - Maximum number of requests allowed in the window. Defaults to 60.
75+
* @param windowMs - Time window in milliseconds. Defaults to 60000 (1 minute).
76+
* @returns A {@link RateLimitResult} containing success status, limit, remaining count, and reset time.
77+
*
78+
* @example
79+
* const result = rateLimit(ip);
80+
* if (!result.success) {
81+
* return new Response("Too Many Requests", { status: 429 });
82+
* }
83+
*/
5084
export function rateLimit(
5185
ip: string,
5286
limit: number = 60,

0 commit comments

Comments
 (0)