{"version":3,"sources":["../../src/index.ts","../../src/abortError.ts","../../src/retryError.ts","../../src/timeoutError.ts","../../src/wait.ts","../../src/throttler.ts","../../src/fixedWindowThrottler.ts","../../src/leakyBucketThrottler.ts","../../src/linearThrottler.ts","../../src/slidingWindowThrottler.ts","../../src/tokenBucketThrottler.ts"],"sourcesContent":["export { AbortError } from \"./abortError\";\n\nexport {\n type FixedWindowThrottlerConfig,\n FixedWindowThrottler,\n} from \"./fixedWindowThrottler\";\n\nexport {\n type LeakyBucketThrottlerConfig,\n LeakyBucketThrottler,\n} from \"./leakyBucketThrottler\";\n\nexport { type LinearThrottlerConfig, LinearThrottler } from \"./linearThrottler\";\n\nexport { RetryError } from \"./retryError\";\n\nexport {\n type SlidingWindowThrottlerConfig,\n SlidingWindowThrottler,\n} from \"./slidingWindowThrottler\";\n\nexport {\n type Throttler,\n type ThrottlerWaitOptions,\n} from \"./throttler\";\n\nexport { TimeoutError } from \"./timeoutError\";\n\nexport {\n type TokenBucketThrottlerConfig,\n TokenBucketThrottler,\n} from \"./tokenBucketThrottler\";\n","/**\n * Error thrown when an operation is aborted via an `AbortSignal`.\n *\n * This error is used in asynchronous operations\n * to indicate that the caller explicitly cancelled\n * the request by invoking `AbortController.abort()`.\n */\nexport class AbortError extends Error {\n constructor(message = \"Operation aborted\") {\n super(message);\n this.name = \"AbortError\";\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n","/**\n * Error thrown when a retry loop is explicitly cancelled.\n *\n * This error is used to indicate that a retry was cancelled\n * from an `onRetry` callback returning `false`.\n */\nexport class RetryError extends Error {\n constructor(message?: string) {\n super(message);\n this.name = \"RetryError\";\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n","/**\n * Error thrown when an operation exceeds its allowed time limit.\n *\n * This error is used in asynchronous operations to indicate\n * that the operation took too long to complete and was\n * terminated based on a timeout setting.\n */\nexport class TimeoutError extends Error {\n constructor(message?: string) {\n super(message);\n this.name = \"TimeoutError\";\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n","import { AbortError } from \"./abortError\";\nimport { RetryError } from \"./retryError\";\nimport { TimeoutError } from \"./timeoutError\";\nimport * as self from \"./wait\";\n\n/**\n * Optional settings that control the behavior of a wait operation.\n */\nexport interface WaitForOptions {\n /**\n * An `AbortSignal` that allows the wait to be cancelled early.\n *\n * If the signal is already aborted or is aborted before the wait completes,\n * the returned promise will reject with an `AbortError`.\n */\n signal?: AbortSignal;\n\n /**\n * A callback invoked before each retry.\n *\n * Receives the time to wait before the operation will be retried, \n * in milliseconds. If the callback returns `false`, the wait will be \n * aborted and a `RetryError` will be thrown.\n *\n * @param ms - The time to wait for the next retry attempt, in milliseconds.\n *\n * @returns `false` to cancel the retry; any other value continues retrying.\n */\n onRetry?: (ms: number) => unknown;\n\n /**\n * Maximum duration to wait before timing out, in milliseconds.\n *\n * If the wait has not completed within this duration, the returned promise\n * will reject with a `TimeoutError`.\n */\n timeout?: number;\n}\n\n/**\n * Waits for the specified number of milliseconds.\n *\n * Supports cancellation via `AbortSignal`.\n *\n * @param ms - The number of milliseconds to wait.\n * @param signal - Optional abort signal to cancel the wait early.\n *\n * @returns A promise that resolves after the delay, or rejects with\n * `AbortError` if cancelled.\n */\nexport function wait(ms: number, signal?: AbortSignal): Promise {\n return new Promise((resolve, reject) => {\n if (signal?.aborted) {\n reject(new AbortError());\n return;\n }\n\n let timeoutId: ReturnType;\n\n const cleanup = () => {\n clearTimeout(timeoutId);\n signal?.removeEventListener(\"abort\", onReject);\n };\n\n const onReject = () => {\n cleanup();\n reject(new AbortError());\n };\n\n const onResolve = () => {\n cleanup();\n resolve();\n };\n\n signal?.addEventListener(\"abort\", onReject, { once: true });\n timeoutId = setTimeout(onResolve, ms);\n });\n}\n\n/**\n * Waits until the specified high-resolution timestamp is reached.\n *\n * This function uses repeated calls to `wait()` and `performance.now()`\n * to align execution with the given target time.\n *\n * @param ts - Target timestamp (in milliseconds) relative to `performance.now()`.\n * @param signal - Optional abort signal to cancel the wait.\n *\n * @returns A promise that resolves when the current time is at or beyond `ts`,\n * or rejects with `AbortError` if cancelled.\n */\nexport async function waitUntil(\n ts: number,\n signal?: AbortSignal,\n): Promise {\n if (signal?.aborted) {\n throw new AbortError();\n }\n\n let now = performance.now();\n while (now < ts) {\n await self.wait(ts - now, signal);\n now = performance.now();\n }\n}\n\n/**\n * Repeatedly evaluates a callback until it returns a non-positive number,\n * indicating that no further wait is needed.\n *\n * This function is useful for polling-based logic where the caller provides\n * a dynamic wait duration (in milliseconds) before retrying.\n *\n * Supports cancellation, retry control, and timeouts.\n *\n * @param callbackfn A function that returns the time to wait before retrying, in milliseconds.\n * A value <= 0 indicates the wait is complete.\n *\n * @param options Optional controls for timeout, aborting, and retry logic.\n *\n * @returns A promise that resolves when the condition is met,\n * or rejects if aborted, timed out, or the retry is cancelled.\n *\n * @throws {AbortError} if the provided signal is aborted before resolution.\n * @throws {RetryError} if the retry is cancelled by the `onRetry` callback returning `false`.\n * @throws {TimeoutError} if the wait exceeds the specified timeout.\n */\nexport async function waitFor(\n callbackfn: () => number,\n { signal, onRetry, timeout }: WaitForOptions = {},\n): Promise {\n if (signal?.aborted) {\n throw new AbortError();\n }\n\n // Optional timeout setup\n let timeoutId: ReturnType | undefined;\n let timeoutSignal: AbortSignal | undefined;\n if (timeout != null) {\n const controller = new AbortController();\n timeoutSignal = controller.signal;\n timeoutId = setTimeout(() => controller.abort(), timeout);\n }\n\n // Combine signals if needed\n const signals = [signal, timeoutSignal].filter(signal => signal != null);\n const combinedSignal = (signals.length > 0) ? AbortSignal.any(signals) : undefined;\n\n try {\n while (true) {\n const ms = callbackfn();\n if (ms <= 0) {\n return;\n }\n if (onRetry?.(ms) === false) {\n throw new RetryError();\n }\n await wait(ms, combinedSignal);\n }\n } catch (error) {\n throw (timeoutSignal?.aborted) ? new TimeoutError() : error;\n } finally {\n if (timeoutId != null) {\n clearTimeout(timeoutId);\n }\n }\n}\n","import { AbortError } from \"./abortError\";\nimport { ACQUIRED } from \"./constants\";\nimport { RetryError } from \"./retryError\";\nimport { waitUntil } from \"./wait\";\nimport { TimeoutError } from \"./timeoutError\";\n\n/**\n * Optional settings that control the behavior of a wait operation.\n */\nexport interface ThrottlerWaitOptions {\n /**\n * An `AbortSignal` that allows the wait to be cancelled early.\n *\n * If the signal is already aborted or is aborted before the wait completes,\n * the returned promise will reject with an `AbortError`.\n */\n signal?: AbortSignal;\n\n /**\n * A callback invoked before each retry.\n *\n * Receives the time to wait before the operation will be retried, \n * in milliseconds. If the callback returns `false`, the wait will be \n * aborted and a `RetryError` will be thrown.\n *\n * @param ms - The time to wait for the next retry attempt, in milliseconds.\n *\n * @returns `false` to cancel the retry; any other value continues retrying.\n */\n onRetry?: (ms: number, throttler: T) => unknown;\n\n /**\n * Maximum duration to wait before timing out, in milliseconds.\n *\n * If the wait has not completed within this duration, the returned promise\n * will reject with a `TimeoutError`.\n */\n timeout?: number;\n}\n\n/**\n * An interface for throttlers that regulate the pacing\n * of operations to conform to a specified rate.\n */\nexport abstract class Throttler {\n /**\n * Attempts to acquire permission to proceed with a request.\n *\n * If the request is allowed, this should return {@link ACQUIRED}.\n *\n * Otherwise, it should return a timestamp (from `performance.now()`)\n * indicating when the caller should retry.\n */\n protected abstract tryAcquire(): number;\n\n /**\n * Attempts to proceed immediately without waiting.\n *\n * Performs a non-blocking check to determine whether the operation\n * can be executed immediately based on the throttler's state.\n *\n * @returns `true` if the operation can proceed immediately,\n * `false` if it must be delayed.\n */\n tryWait(): boolean {\n return this.tryAcquire() === ACQUIRED;\n }\n\n /**\n * Waits until the operation is allowed to proceed.\n *\n * Blocks until the throttler permits execution based on its\n * rate-limiting logic. Supports optional timeout, abort signal,\n * and a retry callback that can cancel retries.\n *\n * @param options Optional settings for aborting, timing out, or\n * controlling retry behavior.\n *\n * @returns A promise that resolves when the caller is permitted to proceed,\n * or rejects if aborted, timed out, or the retry is cancelled.\n *\n * @throws {AbortError} if the provided signal is aborted before resolution.\n *\n * @throws {RetryError} if the retry is cancelled by the `onRetry` callback returning `false`.\n *\n * @throws {TimeoutError} if the wait exceeds the specified timeout.\n */\n async wait({ signal, onRetry, timeout }: ThrottlerWaitOptions = {}): Promise {\n let timeoutId: ReturnType;\n\n const cleanup = () => {\n if (timeoutId !== undefined) {\n clearTimeout(timeoutId);\n }\n signal?.removeEventListener(\"abort\", onAbort);\n };\n\n const onAbort = () => {\n cleanup();\n throw new AbortError();\n };\n\n const onTimeout = () => {\n cleanup();\n throw new TimeoutError();\n };\n\n if (signal?.aborted) {\n throw new AbortError();\n }\n\n signal?.addEventListener(\"abort\", onAbort);\n if (timeout != null) {\n timeoutId = setTimeout(onTimeout, timeout);\n }\n\n try {\n while (true) {\n const ts = this.tryAcquire();\n if (ts === ACQUIRED) {\n break;\n }\n if (onRetry?.(ts, this) === false) {\n throw new RetryError();\n }\n await waitUntil(ts);\n }\n } finally {\n cleanup();\n }\n }\n}\n","import { ACQUIRED } from \"./constants\";\nimport { Throttler } from \"./throttler\";\n\n/**\n * Configuration options for creating a {@link FixedWindowThrottler}.\n *\n * @example\n * // 5 requests per second\n * {\n * duration: 1000, // milliseconds\n * limit: 5\n * }\n */\nexport interface FixedWindowThrottlerConfig {\n /**\n * The size of the window in milliseconds.\n */\n duration: number;\n\n /**\n * The number of requests allowed per window.\n *\n * Requests above this limit will be delayed.\n */\n limit: number;\n}\n\n/**\n * A throttler that uses the fixed window algorithm.\n *\n * This throttler counts the number of requests within\n * each fixed-duration window. Once the limit is reached,\n * additional requests are delayed until future windows.\n *\n * Note: This approach can cause bursts of traffic at\n * window boundaries.\n */\nexport class FixedWindowThrottler extends Throttler {\n /**\n * The size of the window in milliseconds.\n */\n readonly duration: number;\n\n /**\n * The number of requests allowed per window.\n */\n readonly limit: number;\n\n /**\n * Timestamp marking the end of the current window.\n */\n private windowEnd: number;\n\n /**\n * Number of accepted requests in the current window.\n */\n private count: number;\n\n constructor({ duration, limit }: FixedWindowThrottlerConfig) {\n if (duration < 0) {\n throw new RangeError(\"Invalid duration\");\n }\n if (limit < 1) {\n throw new RangeError(\"Invalid limit\");\n }\n\n super();\n this.count = 0;\n this.duration = duration;\n this.limit = limit;\n this.windowEnd = 0;\n }\n\n /**\n * Attempts to acquire permission to proceed with a request.\n *\n * If the current window has capacity, the request is accepted.\n *\n * Otherwise, returns the timestamp marking the end of the\n * current window to indicate how long the caller should\n * wait before retrying.\n */\n protected tryAcquire(): number {\n const now = performance.now();\n\n if (now >= this.windowEnd) {\n this.windowEnd = now + this.duration;\n this.count = 0;\n }\n\n if (this.count + 1 > this.limit) {\n return this.windowEnd;\n }\n\n ++this.count;\n return ACQUIRED;\n }\n}\n","import { ACQUIRED } from \"./constants\";\nimport { Throttler } from \"./throttler\";\n\n/**\n * Configuration options for creating a {@link LeakyBucketThrottler}.\n *\n * @example\n * // Allow bursts of up to 10 requests, with a drain of 5 per second\n * {\n * capacity: 10,\n * leakRate: 5\n * }\n */\nexport interface LeakyBucketThrottlerConfig {\n /**\n * Maximum number of tokens the bucket can hold.\n *\n * This defines the burst capacity. Requests beyond this\n * limit are throttled until enough leakage has occurred.\n */\n capacity: number;\n\n /**\n * Rate at which tokens leak per second.\n *\n * A higher rate allows faster throughput.\n */\n leakRate: number;\n}\n\n/**\n * A throttler that uses the leaky bucket algorithm.\n *\n * Tokens are added to a \"bucket\" which drains at a steady rate\n * defined by `leakRate`. If the bucket overflows (`capacity` exceeded),\n * further requests are throttled until enough leakage has occurred.\n *\n * This method smooths bursts over time, providing a steady output rate.\n */\nexport class LeakyBucketThrottler extends Throttler {\n /**\n * Maximum capacity of the bucket.\n */\n readonly capacity: number;\n /**\n * Timestamp of the last leakage calculation.\n */\n private leakedAt: number;\n\n /**\n * Rate at which tokens are leaked, per second.\n */\n readonly leakRate: number;\n\n /**\n * Current number of tokens in the bucket.\n */\n private tokens: number;\n\n constructor({ capacity, leakRate }: LeakyBucketThrottlerConfig) {\n if (capacity < 1) {\n throw new RangeError(\"Invalid capacity\");\n }\n if (leakRate <= 0) {\n throw new RangeError(\"Invalid leak rate\");\n }\n super();\n this.capacity = capacity;\n this.leakedAt = performance.now();\n this.leakRate = leakRate;\n this.tokens = 0;\n }\n\n /**\n * Attempts to acquire permission to proceed with a request.\n *\n * First, the number of leaked tokens since the last check\n * is calculated and the bucket's level is updated accordingly.\n *\n * If the bucket has capacity, the request is accepted.\n *\n * Otherwise, returns the timestamp of when enough leakage\n * will occur to allow the request.\n */\n protected tryAcquire(): number {\n const now = performance.now();\n\n // Calculate tokens leaked since the last check\n const elapsed = (now - this.leakedAt) / 1000;\n const leaked = elapsed * this.leakRate;\n this.tokens = Math.max(0, this.tokens - leaked);\n this.leakedAt = now;\n\n // If full, calculate how long until capacity\n if (this.tokens > this.capacity - 1) {\n const delta = this.tokens - this.capacity + 1;\n const duration = (1000 * delta) / this.leakRate;\n return now + duration;\n }\n\n // Accept the request\n ++this.tokens;\n return ACQUIRED;\n }\n}\n","import { ACQUIRED } from \"./constants\";\nimport { Throttler } from \"./throttler\";\n\n/**\n * Configuration options for creating a {@link LinearThrottler}.\n *\n * @example\n * // Allow one request every 500 milliseconds\n * {\n * duration: 500\n * }\n */\nexport interface LinearThrottlerConfig {\n /**\n * The minimum duration between requests, in milliseconds.\n */\n duration: number;\n}\n\n/**\n * A throttler that enforces a fixed delay between requests.\n *\n * This throttler ensures that each request occurs at least\n * `duration` milliseconds after the previous one, providing\n * consistent pacing without bursts.\n */\nexport class LinearThrottler extends Throttler {\n /**\n * The minimum duration between requests, in milliseconds.\n */\n readonly duration: number;\n\n /**\n * Timestamp of when the next request is allowed.\n */\n private slot: number;\n\n constructor({ duration }: LinearThrottlerConfig) {\n if (duration < 0) {\n throw new RangeError(\"Duration must be non-negative\");\n }\n super();\n this.duration = duration;\n this.slot = 0;\n }\n\n /**\n * Attempts to acquire permission to proceed with the operation.\n *\n * Allows the request if the current time is past `slot`.\n *\n * Otherwise, returns the timestamp when the next\n * request is allowed to indicate how long the caller\n * should wait before retrying.\n */\n protected tryAcquire(): number {\n const now = performance.now();\n if (now < this.slot) {\n return this.slot;\n }\n this.slot = now + this.duration;\n return ACQUIRED;\n }\n}\n","import { ACQUIRED } from \"./constants\";\nimport { Throttler } from \"./throttler\";\n\n/**\n * Configuration options for creating a {@link SlidingWindowThrottler}.\n *\n * @example\n * // 5 requests per second\n * {\n * duration: 1000, // milliseconds\n * limit: 5\n * }\n */\nexport interface SlidingWindowThrottlerConfig {\n /**\n * The size of the window in milliseconds.\n */\n duration: number;\n\n /**\n * The number of requests allowed per window.\n *\n * Requests above this limit will be delayed.\n */\n limit: number;\n}\n\n/**\n * A throttler that uses the sliding window algorithm.\n *\n * This throttler spreads requests across a moving time window,\n * tracking the timestamps of accepted requests and ensuring\n * no more than a fixed number occur within any given interval.\n */\nexport class SlidingWindowThrottler extends Throttler {\n /**\n * The size of the window in milliseconds.\n */\n readonly duration: number;\n\n /**\n * Points to the oldest slot in the current window.\n */\n private index: number;\n\n /**\n * The number of requests allowed per window.\n */\n readonly limit: number;\n\n /**\n * Timestamps of the last `limit` accepted requests.\n *\n * These are used to determine if a new request falls\n * within the allowed window, and to delay if necessary.\n */\n private slots: number[];\n\n constructor({ duration, limit }: SlidingWindowThrottlerConfig) {\n if (duration < 0) {\n throw new RangeError(\"Invalid duration\");\n }\n if (!Number.isInteger(limit) || limit < 1) {\n throw new RangeError(\"Invalid limit\");\n }\n super();\n this.duration = duration;\n this.index = 0;\n this.limit = limit;\n this.slots = new Array(limit).fill(0);\n }\n\n /**\n * Attempts to acquire permission to proceed with a request.\n *\n * If the number of requests within the sliding window is\n * below the limit, the request is accepted and its expiration\n * timestamp (i.e. when it falls out of the window) is\n * recorded in the current slot.\n *\n * If the limit has been reached, the expiration time of the\n * oldest request is returned to indicate how long the caller\n * should wait before retrying.\n */\n protected tryAcquire(): number {\n const now = performance.now();\n if (now < this.slots[this.index]) {\n return this.slots[this.index];\n }\n this.slots[this.index] = now + this.duration;\n this.index = (this.index + 1) % this.limit;\n return ACQUIRED;\n }\n}\n","import { ACQUIRED } from \"./constants\";\nimport { Throttler } from \"./throttler\";\n\n/**\n * Configuration options for creating a {@link TokenBucketThrottler}.\n *\n * @example\n *\n * // Allow bursts of up to 10 requests, refilling at 5 per second\n * {\n * capacity: 10,\n * refillRate: 5\n * }\n */\nexport interface TokenBucketThrottlerConfig {\n /**\n * Maximum number of tokens the bucket can hold.\n *\n * This defines the burst capacity. Requests beyond this\n * limit are throttled until enough refill has occurred.\n */\n capacity: number;\n\n /**\n * Rate at which tokens refill per second.\n *\n * A higher rate allows faster throughput.\n */\n refillRate: number;\n}\n\n/**\n * A throttler that uses the token bucket algorithm.\n *\n * Allows requests to be made at a steady rate, while\n * still supporting occasional bursts.\n *\n * Each request consumes one token. Tokens are added\n * continuously over time based on the configured refill rate.\n */\nexport class TokenBucketThrottler extends Throttler {\n /**\n * Maximum number of tokens in the bucket.\n */\n readonly capacity: number;\n\n /**\n * Timestamp of the last refill calculation.\n */\n private refilledAt: number;\n\n /**\n * Rate at which tokens are added, per second.\n */\n readonly refillRate: number;\n\n /**\n * Current number of tokens in the bucket.\n */\n private tokens: number;\n\n constructor({ capacity, refillRate }: TokenBucketThrottlerConfig) {\n if (capacity < 1) {\n throw new RangeError(\"Invalid capacity\");\n }\n if (refillRate <= 0) {\n throw new RangeError(\"Invalid refill rate\");\n }\n super();\n this.capacity = capacity;\n this.refilledAt = performance.now();\n this.refillRate = refillRate;\n this.tokens = capacity;\n }\n\n /**\n * Attempts to acquire permission to proceed with a request.\n *\n * First, the number of refilled tokens since the last check\n * is calculated and the bucket's level is updated accordingly.\n *\n * If at least one token is available, the request is accepted.\n *\n * Otherwise, returns the timestamp when a token will become\n * available to allow the request.\n */\n protected tryAcquire(): number {\n const now = performance.now();\n\n // Calculate tokens refilled since the last check\n const elapsed = (now - this.refilledAt) / 1000;\n const added = elapsed * this.refillRate;\n this.tokens = Math.min(this.capacity, this.tokens + added);\n this.refilledAt = now;\n\n // If empty, calculate how long for the next token\n if (this.tokens < 1) {\n const delta = 1 - this.tokens;\n const duration = (1000 * delta) / this.refillRate;\n return now + duration;\n }\n\n // Accept the request\n --this.tokens;\n return ACQUIRED;\n }\n}\n"],"mappings":"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","names":["index_exports","__export","AbortError","FixedWindowThrottler","LeakyBucketThrottler","LinearThrottler","RetryError","SlidingWindowThrottler","TimeoutError","TokenBucketThrottler","__toCommonJS","AbortError","message","RetryError","message","TimeoutError","message","wait","ms","signal","resolve","reject","AbortError","timeoutId","cleanup","onReject","onResolve","waitUntil","ts","now","Throttler","signal","onRetry","timeout","timeoutId","cleanup","onAbort","AbortError","onTimeout","TimeoutError","ts","RetryError","waitUntil","FixedWindowThrottler","Throttler","duration","limit","__publicField","now","LeakyBucketThrottler","Throttler","capacity","leakRate","__publicField","now","leaked","duration","LinearThrottler","Throttler","duration","__publicField","now","SlidingWindowThrottler","Throttler","duration","limit","__publicField","now","TokenBucketThrottler","Throttler","capacity","refillRate","__publicField","now","added","duration"]}