@struktoai/mirage-core
Version:
A Unified Virtual Filesystem For AI Agents
47 lines • 2.19 kB
TypeScript
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