throttlers
Version:
[](https://www.npmjs.com/package/throttlers) [](https://github.com/havelessbemore/throttlers/graphs/commit-activity) [ • 11.9 kB
text/typescript
export { TimeoutError } from 'wait-utils';
/**
* Options to control the behavior of {@link Throttler.acquire}.
*/
interface AcquireOptions {
/**
* An {@link AbortSignal} that allows cancellation.
*/
signal?: AbortSignal;
/**
* Maximum duration to wait before timing out, in milliseconds.
*
* If acqisition exceeds this duration, a {@link TimeoutError} is thrown.
*/
timeout?: number;
}
/**
* An interface for throttlers that regulate the pacing
* of operations to conform to a specified rate.
*/
interface Throttler {
/**
* Attempts to acquire permission immediately.
*
* @returns `true` if allowed immediately, `false` otherwise.
* If `false`, the caller may retry later or call {@link acquire}.
*/
tryAcquire(): boolean;
/**
* Asynchronously acquires the ability to proceed.
*
* @param options - Optional {@link AcquireOptions} to control behavior.
* @returns A promise that resolves once permission is granted.
* @throws An `AbortError` if the signal is aborted before acquisition.
* @throws A {@link TimeoutError} if the wait time exceeds {@link AcquireOptions.timeout}.
*/
acquire(options?: AcquireOptions): Promise<void>;
}
/**
* Indicates a successful attempt to acquire a permit.
*/
interface TryAcquireSuccess {
/**
* Not defined on successful acquisition.
*/
retryAfterMs?: undefined;
/**
* Always `true` when acquisition is successful.
*/
success: true;
}
/**
* Indicates a failed attempt to acquire a permit.
*/
interface TryAcquireFailure {
/**
* Recommended wait time before the next attempt, in milliseconds.
*/
retryAfterMs: number;
/**
* Always `false` when acquisition fails.
*/
success: false;
}
/**
* Result of an attempt to acquire a permit.
*
* Discriminated union: either success or failure with a recommended retry delay.
*/
type TryAcquireResult = TryAcquireSuccess | TryAcquireFailure;
/**
* Strategy interface defining throttler behavior.
*/
interface ThrottlerStrategy {
/**
* Attempts to acquire a permit.
*
* @returns A {@link TryAcquireResult | result} indicating success or failure.
*/
tryAcquire(): TryAcquireResult;
}
interface StrategyThrottlerConfig {
strategy: ThrottlerStrategy;
}
declare class StrategyThrottler implements Throttler {
readonly strategy: ThrottlerStrategy;
constructor({ strategy }: StrategyThrottlerConfig);
tryAcquire(): boolean;
acquire({ signal, timeout }?: AcquireOptions): Promise<void>;
}
/**
* Configuration options for creating a {@link FixedWindowStrategy}.
*
* @example
* // 5 requests per second
* {
* duration: 1000, // milliseconds
* limit: 5
* }
*/
interface FixedWindowConfig {
/**
* The size of the window in milliseconds.
*/
duration: number;
/**
* The number of requests allowed per window.
*
* Requests above this limit will be delayed.
*/
limit: number;
}
/**
* A throttler that uses the fixed window algorithm.
*
* This throttler counts the number of requests within
* each fixed-duration window. Once the limit is reached,
* additional requests are delayed until future windows.
*
* Note: This approach can cause bursts of traffic at
* window boundaries.
*/
declare class FixedWindowStrategy implements ThrottlerStrategy {
/**
* The size of the window in milliseconds.
*/
readonly duration: number;
/**
* The number of requests allowed per window.
*/
readonly limit: number;
/**
* Timestamp marking the end of the current window.
*/
private windowEnd;
/**
* Number of accepted requests in the current window.
*/
private count;
constructor({ duration, limit }: FixedWindowConfig);
/**
* Attempts to acquire permission to proceed with a request.
*
* If the current window has capacity, returns <= 0.
*
* Otherwise, returns the number of milliseconds to wait
* before the caller should retry.
*/
tryAcquire(): TryAcquireResult;
}
declare class FixedWindowThrottler extends StrategyThrottler {
constructor(config: FixedWindowConfig);
}
/**
* Configuration options for creating a {@link LeakyBucketStrategy}.
*
* @example
* // Allow bursts of up to 10 requests, with a drain of 5 per second
* {
* capacity: 10,
* leakRate: 5
* }
*/
interface LeakyBucketConfig {
/**
* Maximum number of tokens the bucket can hold.
*
* This defines the burst capacity. Requests beyond this
* limit are throttled until enough leakage has occurred.
*/
capacity: number;
/**
* Rate at which tokens leak per second.
*
* A higher rate allows faster throughput.
*/
leakRate: number;
}
/**
* A throttler that uses the leaky bucket algorithm.
*
* Tokens are added to a "bucket" which drains at a steady rate
* defined by `leakRate`. If the bucket overflows (`capacity` exceeded),
* further requests are throttled until enough leakage has occurred.
*
* This method smooths bursts over time, providing a steady output rate.
*/
declare class LeakyBucketStrategy implements ThrottlerStrategy {
/**
* Maximum capacity of the bucket.
*/
readonly capacity: number;
/**
* Timestamp of the last leakage calculation.
*/
private leakedAt;
/**
* Rate at which tokens are leaked, per second.
*/
readonly leakRate: number;
/**
* Current number of tokens in the bucket.
*/
private tokens;
constructor({ capacity, leakRate }: LeakyBucketConfig);
/**
* Attempts to acquire permission to proceed with a request.
*
* First, the number of leaked tokens since the last check
* is calculated and the bucket's level is updated accordingly.
*
* If the bucket has capacity, the request is accepted.
*
* Otherwise, returns the timestamp of when enough leakage
* will occur to allow the request.
*/
tryAcquire(): TryAcquireResult;
}
declare class LeakyBucketThrottler extends StrategyThrottler {
constructor(config: LeakyBucketConfig);
}
/**
* Configuration options for creating a {@link LinearStrategy}.
*
* @example
* // Allow one request every 500 milliseconds
* {
* duration: 500
* }
*/
interface LinearConfig {
/**
* The minimum duration between requests, in milliseconds.
*/
duration: number;
}
/**
* A throttler that enforces a fixed delay between requests.
*
* This throttler ensures that each request occurs at least
* `duration` milliseconds after the previous one, providing
* consistent pacing without bursts.
*/
declare class LinearStrategy implements ThrottlerStrategy {
/**
* The minimum duration between requests, in milliseconds.
*/
readonly duration: number;
/**
* Timestamp of when the next request is allowed.
*/
private slot;
constructor({ duration }: LinearConfig);
/**
* Attempts to acquire permission to proceed with the operation.
*
* Allows the request if the current time is past `slot`.
*
* Otherwise, returns the timestamp when the next
* request is allowed to indicate how long the caller
* should wait before retrying.
*/
tryAcquire(): TryAcquireResult;
}
declare class LinearThrottler extends StrategyThrottler {
constructor(config: LinearConfig);
}
/**
* Configuration options for creating a {@link SlidingWindowStrategy}.
*
* @example
* // 5 requests per second
* {
* duration: 1000, // milliseconds
* limit: 5
* }
*/
interface SlidingWindowConfig {
/**
* The size of the window in milliseconds.
*/
duration: number;
/**
* The number of requests allowed per window.
*
* Requests above this limit will be delayed.
*/
limit: number;
}
/**
* A throttler that uses the sliding window algorithm.
*
* This throttler spreads requests across a moving time window,
* tracking the timestamps of accepted requests and ensuring
* no more than a fixed number occur within any given interval.
*/
declare class SlidingWindowStrategy implements ThrottlerStrategy {
/**
* The size of the window in milliseconds.
*/
readonly duration: number;
/**
* Points to the oldest slot in the current window.
*/
private index;
/**
* The number of requests allowed per window.
*/
readonly limit: number;
/**
* Timestamps of the last `limit` accepted requests.
*
* These are used to determine if a new request falls
* within the allowed window, and to delay if necessary.
*/
private slots;
constructor({ duration, limit }: SlidingWindowConfig);
/**
* Attempts to acquire permission to proceed with a request.
*
* If the number of requests within the sliding window is
* below the limit, the request is accepted and its expiration
* timestamp (i.e. when it falls out of the window) is
* recorded in the current slot.
*
* If the limit has been reached, the expiration time of the
* oldest request is returned to indicate how long the caller
* should wait before retrying.
*/
tryAcquire(): TryAcquireResult;
}
declare class SlidingWindowThrottler extends StrategyThrottler {
constructor(config: SlidingWindowConfig);
}
/**
* Configuration options for creating a {@link TokenBucketStrategy}.
*
* @example
*
* // Allow bursts of up to 10 requests, refilling at 5 per second
* {
* capacity: 10,
* refillRate: 5
* }
*/
interface TokenBucketConfig {
/**
* Maximum number of tokens the bucket can hold.
*
* This defines the burst capacity. Requests beyond this
* limit are throttled until enough refill has occurred.
*/
capacity: number;
/**
* Rate at which tokens refill per second.
*
* A higher rate allows faster throughput.
*/
refillRate: number;
}
/**
* A throttler that uses the token bucket algorithm.
*
* Allows requests to be made at a steady rate, while
* still supporting occasional bursts.
*
* Each request consumes one token. Tokens are added
* continuously over time based on the configured refill rate.
*/
declare class TokenBucketStrategy implements ThrottlerStrategy {
/**
* Maximum number of tokens in the bucket.
*/
readonly capacity: number;
/**
* Timestamp of the last refill calculation.
*/
private refilledAt;
/**
* Rate at which tokens are added, per second.
*/
readonly refillRate: number;
/**
* Current number of tokens in the bucket.
*/
private tokens;
constructor({ capacity, refillRate }: TokenBucketConfig);
/**
* Attempts to acquire permission to proceed with a request.
*
* First, the number of refilled tokens since the last check
* is calculated and the bucket's level is updated accordingly.
*
* If at least one token is available, the request is accepted.
*
* Otherwise, returns the timestamp when a token will become
* available to allow the request.
*/
tryAcquire(): TryAcquireResult;
}
declare class TokenBucketThrottler extends StrategyThrottler {
constructor(config: TokenBucketConfig);
}
export { type AcquireOptions, type FixedWindowConfig, FixedWindowStrategy, FixedWindowThrottler, type LeakyBucketConfig, LeakyBucketStrategy, LeakyBucketThrottler, type LinearConfig, LinearStrategy, LinearThrottler, type SlidingWindowConfig, SlidingWindowStrategy, SlidingWindowThrottler, StrategyThrottler, type StrategyThrottlerConfig, type Throttler, type ThrottlerStrategy, type TokenBucketConfig, TokenBucketStrategy, TokenBucketThrottler, type TryAcquireFailure, type TryAcquireResult, type TryAcquireSuccess };