/**
 * Per-key fixed-window request-rate limiter. Every `consume()` counts toward
 * the limit; once the window's count hits `maxRequests`, subsequent consumes
 * return `allowed: false` until the window rolls over.
 *
 * Use this for *throughput* limiting (e.g. "15 req/min on /admin"). For
 * *failure-rate* limiting with lockout (e.g. brute-force protection), use
 * {@link FailureLimiter} instead.
 */
import { type Clock } from './keyed-store.js';
export type RateLimiterConfig = {
    maxRequests: number;
    windowMs: number;
    /** How long to retain idle keys before sweep. Defaults to 4× windowMs. */
    staleAfterMs?: number;
    clock?: Clock;
};
/**
 * Flat rather than tagged-union: project's tsconfig has `strict: false`, which
 * disables boolean discriminator narrowing through `if (!x.allowed)`. Both
 * fields are always populated — `retryAfterMs` is 0 on success, `remaining`
 * is 0 on block.
 */
export type RateLimitDecision = {
    allowed: boolean;
    remaining: number;
    retryAfterMs: number;
};
export declare class RateLimiter {
    private readonly store;
    private readonly clock;
    private readonly maxRequests;
    private readonly windowMs;
    constructor(cfg: RateLimiterConfig);
    consume(key: string): RateLimitDecision;
    /** @internal Test hook. */
    resetForTests(): void;
    destroy(): void;
}
