UNPKG

tiny-essentials

Version:

Collection of small, essential scripts designed to be used across various projects. These simple utilities are crafted for speed, ease of use, and versatility.

233 lines 7.24 kB
export default TinyRateLimiter; export type OnMemoryExceeded = (groupId: string) => void; export type OnGroupExpired = (groupId: string) => void; /** @typedef {(groupId: string) => void} OnMemoryExceeded */ /** @typedef {(groupId: string) => void} OnGroupExpired */ /** * Class representing a flexible rate limiter per user or group. * * This rate limiter supports limiting per user or per group by mapping * userIds to a common groupId. All users within the same group share * rate limits. */ declare class TinyRateLimiter { /** * @param {Object} options * @param {number|null} [options.maxMemory] - Max memory allowed * @param {number} [options.maxHits] - Max interactions allowed * @param {number} [options.interval] - Time window in milliseconds * @param {number} [options.cleanupInterval] - Interval for automatic cleanup (ms) * @param {number} [options.maxIdle=300000] - Max idle time for a user before being cleaned (ms) */ constructor({ maxHits, interval, cleanupInterval, maxIdle, maxMemory }: { maxMemory?: number | null | undefined; maxHits?: number | undefined; interval?: number | undefined; cleanupInterval?: number | undefined; maxIdle?: number | undefined; }); /** @type {Map<string, number[]>} */ groupData: Map<string, number[]>; /** @type {Map<string, number>} */ lastSeen: Map<string, number>; /** @type {Map<string, string>} */ userToGroup: Map<string, string>; /** @type {Map<string, boolean>} */ groupFlags: Map<string, boolean>; /** * @type {Map<string, number>} * Stores TTL (in ms) for each groupId individually */ groupTTL: Map<string, number>; /** * Set the callback to be triggered when a group exceeds its limit * @param {OnMemoryExceeded} callback */ setOnMemoryExceeded(callback: OnMemoryExceeded): void; /** * Clear the onMemoryExceeded callback */ clearOnMemoryExceeded(): void; /** * Set the callback to be triggered when a group expires and is removed. * * This callback is called automatically during cleanup when a group * becomes inactive for longer than its TTL. * * @param {OnGroupExpired} callback - A function that receives the expired groupId. */ setOnGroupExpired(callback: OnGroupExpired): void; /** * Clear the onGroupExpired callback */ clearOnGroupExpired(): void; /** * Check if a given ID is a groupId (not a userId) * @param {string} id * @returns {boolean} */ isGroupId(id: string): boolean; /** * Get all user IDs that belong to a given group. * @param {string} groupId * @returns {string[]} */ getUsersInGroup(groupId: string): string[]; /** * Set TTL (in milliseconds) for a specific group * @param {string} groupId * @param {number} ttl */ setGroupTTL(groupId: string, ttl: number): void; /** * Get TTL (in ms) for a specific group. * @param {string} groupId * @returns {number|null} */ getGroupTTL(groupId: string): number | null; /** * Delete the TTL setting for a specific group * @param {string} groupId */ deleteGroupTTL(groupId: string): void; /** * Assign a userId to a groupId, with merge if user has existing data. * @param {string} userId * @param {string} groupId * @throws {Error} If userId is already assigned to a different group */ assignToGroup(userId: string, groupId: string): void; /** * Get the groupId for a given userId * @param {string} userId * @returns {string} */ getGroupId(userId: string): string; /** * Register a hit for a specific user * @param {string} userId */ hit(userId: string): void; /** * Check if the user (via their group) is currently rate limited * @param {string} userId * @returns {boolean} */ isRateLimited(userId: string): boolean; /** * Manually reset group data * @param {string} groupId */ resetGroup(groupId: string): void; /** * Manually reset a user mapping * @param {string} userId */ resetUserGroup(userId: string): void; /** * Set custom timestamps to a group * @param {string} groupId * @param {number[]} timestamps */ setData(groupId: string, timestamps: number[]): void; /** * Check if a group has data * @param {string} groupId * @returns {boolean} */ hasData(groupId: string): boolean; /** * Get timestamps from a group * @param {string} groupId * @returns {number[]} */ getData(groupId: string): number[]; /** * Get the maximum idle time (in milliseconds) before a group is considered expired. * @returns {number} */ getMaxIdle(): number; /** * Set the maximum idle time (in milliseconds) before a group is considered expired. * @param {number} ms */ setMaxIdle(ms: number): void; /** * Cleanup old/inactive groups with individual TTLs * @private */ private _cleanup; /** * Get list of active group IDs * @returns {string[]} */ getActiveGroups(): string[]; /** * Get a shallow copy of all user-to-group mappings as a plain object * @returns {Record<string, string>} */ getAllUserMappings(): Record<string, string>; /** * Get the interval window in milliseconds. * @returns {number} */ getInterval(): number; /** * Get the maximum number of allowed hits. * @returns {number} */ getMaxHits(): number; /** * Get the total number of hits recorded for a group. * @param {string} groupId * @returns {number} */ getTotalHits(groupId: string): number; /** * Get the timestamp of the last hit for a group. * @param {string} groupId * @returns {number|null} */ getLastHit(groupId: string): number | null; /** * Get milliseconds since the last hit for a group. * @param {string} groupId * @returns {number|null} */ getTimeSinceLastHit(groupId: string): number | null; /** * Internal utility to compute average spacing * @private * @param {number[]|undefined} history * @returns {number|null} */ private _calculateAverageSpacing; /** * Get average time between hits for a group (ms). * @param {string} groupId * @returns {number|null} */ getAverageHitSpacing(groupId: string): number | null; /** * Get metrics about a group's activity. * @param {string} groupId * @returns {{ * totalHits: number, * lastHit: number|null, * timeSinceLastHit: number|null, * averageHitSpacing: number|null * }} */ getMetrics(groupId: string): { totalHits: number; lastHit: number | null; timeSinceLastHit: number | null; averageHitSpacing: number | null; }; /** * Destroy the rate limiter, stopping cleanup and clearing data */ destroy(): void; #private; } //# sourceMappingURL=TinyRateLimiter.d.mts.map