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
text/typescript
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