import { type Clock } from '../../utils/clock.ts';
/**
 * Spaces calls that share a key to at most `rate` per second.
 *
 * For an API that meters requests per second per resource and answers a
 * burst with a penalty window rather than a queue (Airtable allows 5 per
 * base, then refuses everything for 30 seconds), spacing the calls up front
 * is cheaper than any retry. Each call reserves the next free slot for its
 * key before it awaits anything, so concurrent callers queue in arrival
 * order with no lock. A caller woken late (a blocked event loop, a throttled
 * browser timer) moves every slot behind it back by as much, so a stall
 * cannot release the callers queued behind it in one burst.
 */
export declare class RateLimiter {
    private readonly interval;
    private clock;
    private readonly next;
    private readonly shift;
    private schedule;
    private readonly holders;
    /**
     * @param clock what slots are read and waited on; omitted means the system
     *   clock until `bindClock` names the workspace's.
     */
    constructor(rate: number, clock?: Clock);
    /**
     * Read and wait on `clock` while `owner` holds the limiter. Slots taken on
     * another clock mean nothing on this one, so they are dropped; binding the
     * clock already in use keeps them, so a second mount of one accessor cannot
     * release a burst. Slots can follow one clock only, so while another owner
     * holds the limiter a different clock is refused; two system clocks agree.
     *
     * @param owner who holds it, released by the same key.
     * @throws Error when another owner holds the limiter on another clock.
     */
    bindClock(clock: Clock, owner: unknown): void;
    /** Let `owner` go; once none holds, another clock may bind. */
    releaseClock(owner: unknown): void;
    /**
     * Wait for this key's next slot (an Airtable base id). A caller waits out its
     * slot on the clock it took it on; once another clock is bound, even one it
     * then returns to, that slot means nothing on the new schedule, so the caller
     * leaves it alone.
     */
    acquire(key: string): Promise<void>;
}
//# sourceMappingURL=rate_limit.d.ts.map