export default TinyRateLimiter;
/**
 * Callback triggered when a group's stored hit history exceeds
 * the configured memory limit.
 *
 * This callback is purely informational and does not block execution.
 */
export type OnMemoryExceeded = (groupId: string) => void;
/**
 * Callback triggered when a group is considered expired and removed
 * during the cleanup process.
 *
 * This usually happens when the group remains inactive longer than
 * its configured TTL or the global maxIdle value.
 */
export type OnGroupExpired = (groupId: string) => void;
/**
 * Callback triggered when a group's stored hit history exceeds
 * the configured memory limit.
 *
 * This callback is purely informational and does not block execution.
 *
 * @typedef {(groupId: string) => void} OnMemoryExceeded
 */
/**
 * Callback triggered when a group is considered expired and removed
 * during the cleanup process.
 *
 * This usually happens when the group remains inactive longer than
 * its configured TTL or the global maxIdle value.
 *
 * @typedef {(groupId: string) => void} OnGroupExpired
 */
/**
 * A lightweight and flexible rate limiter supporting both user-based
 * and group-based throttling.
 *
 * ## Core Concepts
 * - Every user belongs to a group.
 * - If no explicit group is assigned, the user acts as their own group.
 * - All users within the same group share the same hit history and limits.
 *
 * ## Supported Limiting Strategies
 * - Max number of hits
 * - Time-based sliding window
 * - Combination of both
 *
 * ## Extra Features
 * - Per-group TTL (time-to-live)
 * - Automatic cleanup of inactive groups
 * - Optional memory cap per group
 * - Runtime metrics and statistics
 *
 * ## Interval Window (Sliding Window) Behavior
 *
 * This rate limiter uses a **sliding time window** strategy when `interval`
 * is configured.
 *
 * ### How it works
 * - Each hit is stored as a timestamp (Date.now()).
 * - On every new hit and rate check, timestamps older than:
 *
 *   `now - interval`
 *
 *   are discarded.
 *
 * - Only hits that occurred within the last `interval` milliseconds
 *   are considered valid.
 *
 * ### Practical example
 * If:
 * - interval = 10_000 (10 seconds)
 * - maxHits = 5
 *
 * Then:
 * - Any group may perform **up to 5 hits in any rolling 10-second window**.
 * - The window moves continuously with time.
 *
 * This avoids burst issues common in fixed-window rate limiters.
 *
 * This class is designed to be deterministic, predictable,
 * and safe to use in long-running Node.js processes.
 */
declare class TinyRateLimiter {
    /**
     * Creates a new TinyRateLimiter instance.
     *
     * At least one of `maxHits` or `interval` must be provided.
     *
     * @param {Object} options
     * @param {number|null} [options.maxMemory=100000]
     *   Maximum timestamps stored per group (memory cap).
     * @param {number} [options.maxHits]
     *   Maximum number of allowed hits.
     * @param {number} [options.interval]
     *   Sliding time window in milliseconds.
     * @param {number} [options.cleanupInterval]
     *   Interval (ms) for automatic cleanup execution.
     * @param {number} [options.maxIdle=300000]
     *   Maximum inactivity time (ms) before a group expires.
     */
    constructor({ maxHits, interval, cleanupInterval, maxIdle, maxMemory }: {
        maxMemory?: number | null | undefined;
        maxHits?: number | undefined;
        interval?: number | undefined;
        cleanupInterval?: number | undefined;
        maxIdle?: number | undefined;
    });
    /**
     * Stores hit timestamps per group.
     *
     * Key: groupId
     * Value: array of timestamps (ms)
     *
     * @type {Map<string, number[]>}
     */
    groupData: Map<string, number[]>;
    /**
     * Stores the timestamp of the most recent activity per group.
     *
     * Used for expiration and cleanup logic.
     *
     * @type {Map<string, number>}
     */
    lastSeen: Map<string, number>;
    /**
     * Maps user IDs to their assigned group IDs.
     *
     * @type {Map<string, string>}
     */
    userToGroup: Map<string, string>;
    /**
     * Flags whether an ID represents a true group or an implicit user group.
     *
     * `true`  → explicit group
     * `false` → implicit (user acting as group)
     *
     * @type {Map<string, boolean>}
     */
    groupFlags: Map<string, boolean>;
    /**
     * Per-group TTL (time-to-live) overrides.
     *
     * If not defined for a group, `maxIdle` is used instead.
     *
     * @type {Map<string, number>}
     */
    groupTTL: Map<string, number>;
    /**
     * Assign a callback to be notified when a group's stored
     * hit history exceeds the configured memory limit.
     *
     * @param {OnMemoryExceeded} callback
     */
    setOnMemoryExceeded(callback: OnMemoryExceeded): void;
    /**
     * Removes the memory-exceeded 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;
    /**
     * Removes the group-expiration 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;
    /**
     * Assigns a user to a group.
     *
     * If the user already has recorded hits, those hits
     * are merged into the target group.
     *
     * @param {string} userId
     * @param {string} groupId
     * @throws {Error} If the user belongs to another group
     */
    assignToGroup(userId: string, groupId: string): void;
    /**
     * Resolves the effective group ID for a user.
     *
     * If the user is not explicitly assigned to a group,
     * the user ID itself is treated as the group ID.
     *
     * @param {string} userId
     * @returns {string}
     */
    getGroupId(userId: string): string;
    /**
     * Registers a hit for a user and applies the sliding window logic.
     *
     * ⚠️ **Important usage notice**
     * This method **must be called before** `isRateLimited(userId)`
     * in order for rate limit checks to work correctly.
     *
     * ### Sliding window cleanup
     * When `interval` is configured:
     * - The current timestamp is added to the group's history.
     * - All timestamps older than `now - interval` are immediately removed.
     *
     * This ensures that the stored history always represents
     * the **current active window**.
     *
     * ### Important notes
     * - Cleanup happens on every hit, not on a fixed schedule.
     * - The window continuously moves forward in time.
     * - Memory usage is naturally bounded by time, and optionally by `maxMemory`.
     *
     * @param {string} userId
     */
    hit(userId: string): void;
    /**
     * Checks whether a user is currently rate limited.
     *
     * ### Evaluation process
     * When `interval` is defined:
     * 1. The cutoff time is calculated as:
     *
     *    `Date.now() - interval`
     *
     * 2. Only hits newer than this cutoff are counted.
     * 3. If `maxHits` is defined:
     *    - The group is limited when the count exceeds `maxHits`.
     * 4. If `maxHits` is not defined:
     *    - Any hit within the window causes a limited state.
     *
     * This guarantees consistent behavior regardless of when hits occur.
     *
     * @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>;
    /**
     * Returns the configured sliding window size in milliseconds.
     *
     * This value represents how far back in time hits are considered
     * valid for rate limiting decisions.
     *
     * @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