@stimulcross/rate-limiter 0.0.2 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (147) hide show
  1. package/lib/core/cancellable.d.ts +5 -0
  2. package/lib/core/cancellable.js +1 -0
  3. package/lib/core/clock.d.ts +10 -0
  4. package/lib/core/clock.js +1 -0
  5. package/lib/core/decision.d.ts +23 -0
  6. package/lib/core/decision.js +1 -0
  7. package/lib/core/rate-limit-policy.d.ts +14 -0
  8. package/lib/core/rate-limit-policy.js +1 -0
  9. package/lib/core/rate-limiter-status.d.ts +14 -0
  10. package/lib/core/rate-limiter-status.js +1 -0
  11. package/lib/core/rate-limiter.d.ts +34 -0
  12. package/lib/core/rate-limiter.js +1 -0
  13. package/lib/core/state-storage.d.ts +46 -0
  14. package/lib/core/state-storage.js +1 -0
  15. package/lib/enums/rate-limit-error-code.d.ts +26 -0
  16. package/lib/enums/rate-limit-error-code.js +1 -0
  17. package/lib/errors/custom.error.d.ts +6 -0
  18. package/lib/errors/custom.error.js +1 -0
  19. package/lib/errors/invalid-cost.error.d.ts +16 -0
  20. package/lib/errors/invalid-cost.error.js +1 -0
  21. package/lib/errors/rate-limit.error.d.ts +37 -0
  22. package/lib/errors/rate-limit.error.js +1 -0
  23. package/lib/errors/rate-limiter-destroyed.error.d.ts +7 -0
  24. package/lib/errors/rate-limiter-destroyed.error.js +1 -0
  25. package/lib/index.d.ts +12 -0
  26. package/lib/index.js +1 -0
  27. package/lib/interfaces/rate-limiter-options.d.ts +76 -0
  28. package/lib/interfaces/rate-limiter-options.js +1 -0
  29. package/lib/interfaces/rate-limiter-queue-options.d.ts +42 -0
  30. package/lib/interfaces/rate-limiter-queue-options.js +1 -0
  31. package/lib/interfaces/rate-limiter-run-options.d.ts +52 -0
  32. package/lib/interfaces/rate-limiter-run-options.js +1 -0
  33. package/lib/limiters/abstract-rate-limiter.d.ts +44 -0
  34. package/lib/limiters/abstract-rate-limiter.js +1 -0
  35. package/lib/limiters/composite.policy.d.ts +15 -0
  36. package/lib/limiters/composite.policy.js +1 -0
  37. package/lib/limiters/fixed-window/fixed-window.limiter.d.ts +33 -0
  38. package/lib/limiters/fixed-window/fixed-window.limiter.js +1 -0
  39. package/lib/limiters/fixed-window/fixed-window.options.d.ts +27 -0
  40. package/lib/limiters/fixed-window/fixed-window.options.js +1 -0
  41. package/lib/limiters/fixed-window/fixed-window.policy.d.ts +19 -0
  42. package/lib/limiters/fixed-window/fixed-window.policy.js +1 -0
  43. package/lib/limiters/fixed-window/fixed-window.state.d.ts +11 -0
  44. package/lib/limiters/fixed-window/fixed-window.state.js +1 -0
  45. package/lib/limiters/fixed-window/fixed-window.status.d.ts +39 -0
  46. package/lib/limiters/fixed-window/fixed-window.status.js +1 -0
  47. package/lib/limiters/fixed-window/index.d.ts +5 -0
  48. package/lib/limiters/fixed-window/index.js +1 -0
  49. package/lib/limiters/generic-cell/generic-cell.limiter.d.ts +30 -0
  50. package/lib/limiters/generic-cell/generic-cell.limiter.js +1 -0
  51. package/lib/limiters/generic-cell/generic-cell.options.d.ts +22 -0
  52. package/lib/limiters/generic-cell/generic-cell.options.js +1 -0
  53. package/lib/limiters/generic-cell/generic-cell.policy.d.ts +18 -0
  54. package/lib/limiters/generic-cell/generic-cell.policy.js +1 -0
  55. package/lib/limiters/generic-cell/generic-cell.state.d.ts +9 -0
  56. package/lib/limiters/generic-cell/generic-cell.state.js +1 -0
  57. package/lib/limiters/generic-cell/generic-cell.status.d.ts +49 -0
  58. package/lib/limiters/generic-cell/generic-cell.status.js +1 -0
  59. package/lib/limiters/generic-cell/index.d.ts +5 -0
  60. package/lib/limiters/generic-cell/index.js +1 -0
  61. package/lib/limiters/http-response-based/http-limit-info.extractor.d.ts +16 -0
  62. package/lib/limiters/http-response-based/http-limit-info.extractor.js +1 -0
  63. package/lib/limiters/http-response-based/http-limit.info.d.ts +39 -0
  64. package/lib/limiters/http-response-based/http-limit.info.js +1 -0
  65. package/lib/limiters/http-response-based/http-response-based-limiter.options.d.ts +17 -0
  66. package/lib/limiters/http-response-based/http-response-based-limiter.options.js +1 -0
  67. package/lib/limiters/http-response-based/http-response-based-limiter.state.d.ts +14 -0
  68. package/lib/limiters/http-response-based/http-response-based-limiter.state.js +1 -0
  69. package/lib/limiters/http-response-based/http-response-based-limiter.status.d.ts +70 -0
  70. package/lib/limiters/http-response-based/http-response-based-limiter.status.js +1 -0
  71. package/lib/limiters/http-response-based/http-response-based.limiter.d.ts +56 -0
  72. package/lib/limiters/http-response-based/http-response-based.limiter.js +13 -6
  73. package/lib/limiters/http-response-based/index.d.ts +7 -0
  74. package/lib/limiters/http-response-based/index.js +1 -0
  75. package/lib/limiters/leaky-bucket/index.d.ts +5 -0
  76. package/lib/limiters/leaky-bucket/index.js +1 -0
  77. package/lib/limiters/leaky-bucket/leaky-bucket.limiter.d.ts +30 -0
  78. package/lib/limiters/leaky-bucket/leaky-bucket.limiter.js +1 -0
  79. package/lib/limiters/leaky-bucket/leaky-bucket.options.d.ts +22 -0
  80. package/lib/limiters/leaky-bucket/leaky-bucket.options.js +1 -0
  81. package/lib/limiters/leaky-bucket/leaky-bucket.policy.d.ts +19 -0
  82. package/lib/limiters/leaky-bucket/leaky-bucket.policy.js +1 -0
  83. package/lib/limiters/leaky-bucket/leaky-bucket.state.d.ts +10 -0
  84. package/lib/limiters/leaky-bucket/leaky-bucket.state.js +1 -0
  85. package/lib/limiters/leaky-bucket/leaky-bucket.status.d.ts +31 -0
  86. package/lib/limiters/leaky-bucket/leaky-bucket.status.js +1 -0
  87. package/lib/limiters/sliding-window-counter/index.d.ts +5 -0
  88. package/lib/limiters/sliding-window-counter/index.js +1 -0
  89. package/lib/limiters/sliding-window-counter/sliding-window-counter.limiter.d.ts +28 -0
  90. package/lib/limiters/sliding-window-counter/sliding-window-counter.limiter.js +1 -0
  91. package/lib/limiters/sliding-window-counter/sliding-window-counter.options.d.ts +16 -0
  92. package/lib/limiters/sliding-window-counter/sliding-window-counter.options.js +1 -0
  93. package/lib/limiters/sliding-window-counter/sliding-window-counter.policy.d.ts +18 -0
  94. package/lib/limiters/sliding-window-counter/sliding-window-counter.policy.js +1 -0
  95. package/lib/limiters/sliding-window-counter/sliding-window-counter.state.d.ts +11 -0
  96. package/lib/limiters/sliding-window-counter/sliding-window-counter.state.js +1 -0
  97. package/lib/limiters/sliding-window-counter/sliding-window-counter.status.d.ts +45 -0
  98. package/lib/limiters/sliding-window-counter/sliding-window-counter.status.js +1 -0
  99. package/lib/limiters/sliding-window-log/index.d.ts +5 -0
  100. package/lib/limiters/sliding-window-log/index.js +1 -0
  101. package/lib/limiters/sliding-window-log/sliding-window-log.limiter.d.ts +27 -0
  102. package/lib/limiters/sliding-window-log/sliding-window-log.limiter.js +1 -0
  103. package/lib/limiters/sliding-window-log/sliding-window-log.options.d.ts +16 -0
  104. package/lib/limiters/sliding-window-log/sliding-window-log.options.js +1 -0
  105. package/lib/limiters/sliding-window-log/sliding-window-log.policy.d.ts +18 -0
  106. package/lib/limiters/sliding-window-log/sliding-window-log.policy.js +1 -0
  107. package/lib/limiters/sliding-window-log/sliding-window-log.state.d.ts +18 -0
  108. package/lib/limiters/sliding-window-log/sliding-window-log.state.js +1 -0
  109. package/lib/limiters/sliding-window-log/sliding-window-log.status.d.ts +39 -0
  110. package/lib/limiters/sliding-window-log/sliding-window-log.status.js +1 -0
  111. package/lib/limiters/token-bucket/index.d.ts +5 -0
  112. package/lib/limiters/token-bucket/index.js +1 -0
  113. package/lib/limiters/token-bucket/token-bucket.limiter.d.ts +30 -0
  114. package/lib/limiters/token-bucket/token-bucket.limiter.js +1 -0
  115. package/lib/limiters/token-bucket/token-bucket.options.d.ts +16 -0
  116. package/lib/limiters/token-bucket/token-bucket.options.js +1 -0
  117. package/lib/limiters/token-bucket/token-bucket.policy.d.ts +19 -0
  118. package/lib/limiters/token-bucket/token-bucket.policy.js +1 -0
  119. package/lib/limiters/token-bucket/token-bucket.state.d.ts +11 -0
  120. package/lib/limiters/token-bucket/token-bucket.state.js +1 -0
  121. package/lib/limiters/token-bucket/token-bucket.status.d.ts +31 -0
  122. package/lib/limiters/token-bucket/token-bucket.status.js +1 -0
  123. package/lib/runtime/default-clock.d.ts +4 -0
  124. package/lib/runtime/default-clock.js +1 -0
  125. package/lib/runtime/execution-tickets.d.ts +12 -0
  126. package/lib/runtime/execution-tickets.js +1 -0
  127. package/lib/runtime/in-memory-state-store.d.ts +19 -0
  128. package/lib/runtime/in-memory-state-store.js +1 -0
  129. package/lib/runtime/rate-limiter.executor.d.ts +47 -0
  130. package/lib/runtime/rate-limiter.executor.js +1 -0
  131. package/lib/runtime/semaphore.d.ts +9 -0
  132. package/lib/runtime/semaphore.js +1 -0
  133. package/lib/runtime/task.d.ts +41 -0
  134. package/lib/runtime/task.js +1 -0
  135. package/lib/types/limit-behavior.d.ts +9 -0
  136. package/lib/types/limit-behavior.js +1 -0
  137. package/lib/utils/generate-random-string.d.ts +3 -0
  138. package/lib/utils/generate-random-string.js +1 -0
  139. package/lib/utils/promise-with-resolvers.d.ts +9 -0
  140. package/lib/utils/promise-with-resolvers.js +1 -0
  141. package/lib/utils/sanitize-error.d.ts +3 -0
  142. package/lib/utils/sanitize-error.js +1 -0
  143. package/lib/utils/sanitize-priority.d.ts +4 -0
  144. package/lib/utils/sanitize-priority.js +1 -0
  145. package/lib/utils/validate-cost.d.ts +3 -0
  146. package/lib/utils/validate-cost.js +1 -0
  147. package/package.json +3 -2
@@ -0,0 +1,30 @@
1
+ import { type LeakyBucketOptions } from './leaky-bucket.options.js';
2
+ import { LeakyBucketPolicy } from './leaky-bucket.policy.js';
3
+ import { type LeakyBucketState } from './leaky-bucket.state.js';
4
+ import { type LeakyBucketStatus } from './leaky-bucket.status.js';
5
+ import { AbstractRateLimiter, type ExecutionContext } from '../abstract-rate-limiter.js';
6
+ /**
7
+ * Leaky Bucket rate limiter.
8
+ *
9
+ * Designed primarily for client-side use to respect third-party limits or protect resources.
10
+ * While this can be used as a server-side limiter with custom distributed storage
11
+ * (e.g., Redis), it is best-effort and not recommended due to high network round-trip latency.
12
+ *
13
+ * Key features:
14
+ * - **Queueing & overflow** - optionally enqueues excess requests up to a maximum allowed overflow capacity
15
+ * - **Concurrency** - limits how many requests can be executed simultaneously
16
+ * - **Priority** - supports task priorities (with fairness and custom policy) to execute critical requests first
17
+ * - **Cancellation** - supports `AbortSignal` to safely remove pending requests from the queue
18
+ * - **Expiration** - automatically drops queued requests that wait longer than the allowed `maxWaitMs`
19
+ * - **Auto-rollback** - reverts spent quota if an enqueued task is canceled or expired
20
+ */
21
+ export declare class LeakyBucketLimiter extends AbstractRateLimiter<LeakyBucketState, LeakyBucketStatus> {
22
+ private readonly _defaultLimitBehaviour;
23
+ private readonly _maxWaitMs;
24
+ protected readonly _policy: LeakyBucketPolicy;
25
+ constructor(options: LeakyBucketOptions);
26
+ protected _runInternal<T>(fn: () => T | Promise<T>, ctx: ExecutionContext): Promise<T>;
27
+ protected _getDebugStateString(state: LeakyBucketState): string;
28
+ private _printDebug;
29
+ }
30
+ //# sourceMappingURL=leaky-bucket.limiter.d.ts.map
@@ -72,3 +72,4 @@ export class LeakyBucketLimiter extends AbstractRateLimiter {
72
72
  }
73
73
  }
74
74
  }
75
+ //# sourceMappingURL=leaky-bucket.limiter.js.map
@@ -0,0 +1,22 @@
1
+ import { type LeakyBucketState } from './leaky-bucket.state.js';
2
+ import { type RateLimiterOptions } from '../../interfaces/rate-limiter-options.js';
3
+ /**
4
+ * Options for the Leaky Bucket rate limiter.
5
+ */
6
+ export interface LeakyBucketOptions extends RateLimiterOptions<LeakyBucketState> {
7
+ /**
8
+ * The maximum number of requests that can be queued in the bucket.
9
+ *
10
+ * In the Leaky Bucket algorithm, this represents the maximum depth of the bucket
11
+ * that holds incoming requests before they leak out at a constant rate.
12
+ */
13
+ capacity: number;
14
+ /**
15
+ * The rate at which requests are processed from the bucket (requests per second).
16
+ *
17
+ * This defines the constant rate at which requests "leak" out of the bucket
18
+ * and are allowed to proceed.
19
+ */
20
+ leakRate: number;
21
+ }
22
+ //# sourceMappingURL=leaky-bucket.options.d.ts.map
@@ -1 +1,2 @@
1
1
  export {};
2
+ //# sourceMappingURL=leaky-bucket.options.js.map
@@ -0,0 +1,19 @@
1
+ import { type LeakyBucketState } from './leaky-bucket.state.js';
2
+ import { type LeakyBucketStatus } from './leaky-bucket.status.js';
3
+ import { type RateLimitPolicy, type RateLimitPolicyResult } from '../../core/rate-limit-policy.js';
4
+ /** @internal */
5
+ export declare class LeakyBucketPolicy implements RateLimitPolicy<LeakyBucketState, LeakyBucketStatus> {
6
+ private readonly _capacity;
7
+ private readonly _leakRate;
8
+ private readonly _maxOverflow;
9
+ constructor(_capacity: number, _leakRate: number, _maxOverflow?: number);
10
+ get capacity(): number;
11
+ get leakRate(): number;
12
+ getInitialState(): LeakyBucketState;
13
+ getStatus(state: LeakyBucketState, now: number): LeakyBucketStatus;
14
+ evaluate(state: LeakyBucketState, now: number, cost: number, shouldReserve?: boolean): RateLimitPolicyResult<LeakyBucketState>;
15
+ revert(state: LeakyBucketState, cost: number, now: number): LeakyBucketState;
16
+ private _deny;
17
+ private _syncState;
18
+ }
19
+ //# sourceMappingURL=leaky-bucket.policy.d.ts.map
@@ -98,3 +98,4 @@ export class LeakyBucketPolicy {
98
98
  };
99
99
  }
100
100
  }
101
+ //# sourceMappingURL=leaky-bucket.policy.js.map
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Leaky Bucket rate limiter state.
3
+ *
4
+ * When using a distributed state store, make sure it properly serializes and deserializes the state.
5
+ */
6
+ export interface LeakyBucketState {
7
+ level: number;
8
+ lastUpdate: number;
9
+ }
10
+ //# sourceMappingURL=leaky-bucket.state.d.ts.map
@@ -1 +1,2 @@
1
1
  export {};
2
+ //# sourceMappingURL=leaky-bucket.state.js.map
@@ -0,0 +1,31 @@
1
+ import { type RateLimiterStatus } from '../../core/rate-limiter-status.js';
2
+ /**
3
+ * The status of the Leaky Bucket rate limiter.
4
+ */
5
+ export interface LeakyBucketStatus extends RateLimiterStatus {
6
+ /**
7
+ * The maximum capacity of the bucket (maximum number of requests that can be queued).
8
+ */
9
+ capacity: number;
10
+ /**
11
+ * The rate at which requests leak from the bucket (requests per second).
12
+ */
13
+ leakRate: number;
14
+ /**
15
+ * The current number of requests in the bucket waiting to be processed.
16
+ */
17
+ level: number;
18
+ /**
19
+ * The number of requests that can still be added to the bucket before reaching capacity.
20
+ */
21
+ remaining: number;
22
+ /**
23
+ * Timestamp (in milliseconds) when the next request slot will become available.
24
+ */
25
+ nextAvailableAt: number;
26
+ /**
27
+ * Timestamp (in milliseconds) when all queued requests will have leaked (bucket becomes empty).
28
+ */
29
+ resetAt: number;
30
+ }
31
+ //# sourceMappingURL=leaky-bucket.status.d.ts.map
@@ -1 +1,2 @@
1
1
  export {};
2
+ //# sourceMappingURL=leaky-bucket.status.js.map
@@ -0,0 +1,5 @@
1
+ export type { SlidingWindowCounterState } from './sliding-window-counter.state.js';
2
+ export type { SlidingWindowCounterStatus } from './sliding-window-counter.status.js';
3
+ export type { SlidingWindowCounterOptions } from './sliding-window-counter.options.js';
4
+ export { type SlidingWindowCounterLimiterRunOptions, SlidingWindowCounterLimiter, } from './sliding-window-counter.limiter.js';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -1 +1,2 @@
1
1
  export { SlidingWindowCounterLimiter, } from './sliding-window-counter.limiter.js';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,28 @@
1
+ import { type SlidingWindowCounterOptions } from './sliding-window-counter.options.js';
2
+ import { SlidingWindowCounterPolicy } from './sliding-window-counter.policy.js';
3
+ import { type SlidingWindowCounterState } from './sliding-window-counter.state.js';
4
+ import { type SlidingWindowCounterStatus } from './sliding-window-counter.status.js';
5
+ import { type RateLimiterRunOptions } from '../../interfaces/rate-limiter-run-options.js';
6
+ import { AbstractRateLimiter, type ExecutionContext } from '../abstract-rate-limiter.js';
7
+ /**
8
+ * The options for running a task in the Sliding Window Counter rate limiter.
9
+ */
10
+ export type SlidingWindowCounterLimiterRunOptions = Omit<RateLimiterRunOptions, 'limitBehavior' | 'priority' | 'maxWaitMs'>;
11
+ /**
12
+ * Sliding Window Counter rate limiter.
13
+ *
14
+ * Designed primarily for client-side use to respect third-party limits or protect resources.
15
+ * While this can be used as a server-side limiter with custom distributed storage
16
+ * (e.g., Redis), it is best-effort and not recommended due to high network round-trip latency.
17
+ *
18
+ * Note: Unlike queue-based limiters, this implementation operates in strict immediate mode.
19
+ * It does not support request queueing, delays, priorities, or task cancellation.
20
+ */
21
+ export declare class SlidingWindowCounterLimiter extends AbstractRateLimiter<SlidingWindowCounterState, SlidingWindowCounterStatus> {
22
+ protected readonly _policy: SlidingWindowCounterPolicy;
23
+ private readonly _storeTtl;
24
+ constructor(options: SlidingWindowCounterOptions);
25
+ protected _runInternal<T>(fn: () => T | Promise<T>, ctx: ExecutionContext): Promise<T>;
26
+ protected _getDebugStateString(state: SlidingWindowCounterState): string;
27
+ }
28
+ //# sourceMappingURL=sliding-window-counter.limiter.d.ts.map
@@ -44,3 +44,4 @@ export class SlidingWindowCounterLimiter extends AbstractRateLimiter {
44
44
  return `lim: ${this._policy.limit}; c/p: ${state.currentCount}/${state.previousCount}`;
45
45
  }
46
46
  }
47
+ //# sourceMappingURL=sliding-window-counter.limiter.js.map
@@ -0,0 +1,16 @@
1
+ import { type SlidingWindowCounterState } from './sliding-window-counter.state.js';
2
+ import { type RateLimiterOptions } from '../../interfaces/rate-limiter-options.js';
3
+ /**
4
+ * Options for the Sliding Window Counter rate limiter.
5
+ */
6
+ export interface SlidingWindowCounterOptions extends Omit<RateLimiterOptions<SlidingWindowCounterState>, 'queue' | 'limitBehavior'> {
7
+ /**
8
+ * Maximum number of requests allowed within the time window.
9
+ */
10
+ limit: number;
11
+ /**
12
+ * Duration of the time window in milliseconds.
13
+ */
14
+ windowMs: number;
15
+ }
16
+ //# sourceMappingURL=sliding-window-counter.options.d.ts.map
@@ -1 +1,2 @@
1
1
  export {};
2
+ //# sourceMappingURL=sliding-window-counter.options.js.map
@@ -0,0 +1,18 @@
1
+ import { type SlidingWindowCounterState } from './sliding-window-counter.state.js';
2
+ import { type SlidingWindowCounterStatus } from './sliding-window-counter.status.js';
3
+ import { type RateLimitPolicy, type RateLimitPolicyResult } from '../../core/rate-limit-policy.js';
4
+ /** @internal */
5
+ export declare class SlidingWindowCounterPolicy implements RateLimitPolicy<SlidingWindowCounterState, SlidingWindowCounterStatus> {
6
+ private readonly _limit;
7
+ private readonly _windowMs;
8
+ constructor(_limit: number, _windowMs: number);
9
+ get limit(): number;
10
+ get windowMs(): number;
11
+ getInitialState(): SlidingWindowCounterState;
12
+ getStatus(state: SlidingWindowCounterState, now: number): SlidingWindowCounterStatus;
13
+ evaluate(state: SlidingWindowCounterState, now: number, cost: number): RateLimitPolicyResult<SlidingWindowCounterState>;
14
+ revert(state: SlidingWindowCounterState, cost: number, now: number): SlidingWindowCounterState;
15
+ private _syncState;
16
+ private _calculateAvailableAt;
17
+ }
18
+ //# sourceMappingURL=sliding-window-counter.policy.d.ts.map
@@ -125,3 +125,4 @@ export class SlidingWindowCounterPolicy {
125
125
  return Math.max(now, absoluteTime);
126
126
  }
127
127
  }
128
+ //# sourceMappingURL=sliding-window-counter.policy.js.map
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Sliding Window Counter rate limiter state.
3
+ *
4
+ * When using a distributed state store, make sure it properly serializes and deserializes the state.
5
+ */
6
+ export interface SlidingWindowCounterState {
7
+ windowStart: number;
8
+ currentCount: number;
9
+ previousCount: number;
10
+ }
11
+ //# sourceMappingURL=sliding-window-counter.state.d.ts.map
@@ -1 +1,2 @@
1
1
  export {};
2
+ //# sourceMappingURL=sliding-window-counter.state.js.map
@@ -0,0 +1,45 @@
1
+ import { type RateLimiterStatus } from '../../core/rate-limiter-status.js';
2
+ /**
3
+ * The status of the Sliding Window Counter rate limiter.
4
+ */
5
+ export interface SlidingWindowCounterStatus extends RateLimiterStatus {
6
+ /**
7
+ * Maximum number of requests allowed within the time window.
8
+ */
9
+ limit: number;
10
+ /**
11
+ * Duration of the time window in milliseconds.
12
+ */
13
+ windowMs: number;
14
+ /**
15
+ * Timestamp (in milliseconds) when the current window started.
16
+ */
17
+ windowStart: number;
18
+ /**
19
+ * Number of requests made in the current window.
20
+ */
21
+ currentCount: number;
22
+ /**
23
+ * Number of requests made in the previous window.
24
+ */
25
+ previousCount: number;
26
+ /**
27
+ * Estimated request count based on the sliding window algorithm.
28
+ *
29
+ * Calculated by combining current and previous window counts proportionally.
30
+ */
31
+ estimatedCount: number;
32
+ /**
33
+ * Number of requests remaining before hitting the limit.
34
+ */
35
+ remaining: number;
36
+ /**
37
+ * Timestamp (in milliseconds) when the next request slot becomes available.
38
+ */
39
+ nextAvailableAt: number;
40
+ /**
41
+ * Timestamp (in milliseconds) when the current window resets.
42
+ */
43
+ resetAt: number;
44
+ }
45
+ //# sourceMappingURL=sliding-window-counter.status.d.ts.map
@@ -1 +1,2 @@
1
1
  export {};
2
+ //# sourceMappingURL=sliding-window-counter.status.js.map
@@ -0,0 +1,5 @@
1
+ export type { SlidingWindowLogEntry, SlidingWindowLogState } from './sliding-window-log.state.js';
2
+ export type { SlidingWindowLogStatus } from './sliding-window-log.status.js';
3
+ export type { SlidingWindowLogOptions } from './sliding-window-log.options.js';
4
+ export { type SlidingWindowLogLimiterRunOptions, SlidingWindowLogLimiter } from './sliding-window-log.limiter.js';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -1 +1,2 @@
1
1
  export { SlidingWindowLogLimiter } from './sliding-window-log.limiter.js';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,27 @@
1
+ import { type SlidingWindowLogOptions } from './sliding-window-log.options.js';
2
+ import { SlidingWindowLogPolicy } from './sliding-window-log.policy.js';
3
+ import { type SlidingWindowLogState } from './sliding-window-log.state.js';
4
+ import { type SlidingWindowLogStatus } from './sliding-window-log.status.js';
5
+ import { type RateLimiterRunOptions } from '../../interfaces/rate-limiter-run-options.js';
6
+ import { AbstractRateLimiter, type ExecutionContext } from '../abstract-rate-limiter.js';
7
+ /**
8
+ * The options for running a task in the Sliding Window Log rate limiter.
9
+ */
10
+ export type SlidingWindowLogLimiterRunOptions = Omit<RateLimiterRunOptions, 'limitBehavior' | 'priority'>;
11
+ /**
12
+ * Sliding Window Log rate limiter.
13
+ *
14
+ * Designed primarily for client-side use to respect third-party limits or protect resources.
15
+ * While this can be used as a server-side limiter with custom distributed storage
16
+ * (e.g., Redis), it is best-effort and not recommended due to high network round-trip latency.
17
+ *
18
+ * Note: Unlike queue-based limiters, this implementation operates in strict immediate mode.
19
+ * It does not support request queueing, delays, priorities, or task cancellation.
20
+ */
21
+ export declare class SlidingWindowLogLimiter extends AbstractRateLimiter<SlidingWindowLogState, SlidingWindowLogStatus> {
22
+ protected readonly _policy: SlidingWindowLogPolicy;
23
+ constructor(options: SlidingWindowLogOptions);
24
+ protected _runInternal<T>(fn: () => T | Promise<T>, ctx: ExecutionContext): Promise<T>;
25
+ protected _getDebugStateString(state: SlidingWindowLogState): string;
26
+ }
27
+ //# sourceMappingURL=sliding-window-log.limiter.d.ts.map
@@ -41,3 +41,4 @@ export class SlidingWindowLogLimiter extends AbstractRateLimiter {
41
41
  return `used/lim: ${state.totalUsed}/${this._policy.limit} logs: ${state.logs.size}`;
42
42
  }
43
43
  }
44
+ //# sourceMappingURL=sliding-window-log.limiter.js.map
@@ -0,0 +1,16 @@
1
+ import { type SlidingWindowLogState } from './sliding-window-log.state.js';
2
+ import { type RateLimiterOptions } from '../../interfaces/rate-limiter-options.js';
3
+ /**
4
+ * Options for the Sliding Window Log rate limiter.
5
+ */
6
+ export interface SlidingWindowLogOptions extends Omit<RateLimiterOptions<SlidingWindowLogState>, 'queue' | 'limitBehavior'> {
7
+ /**
8
+ * Maximum number of requests allowed within the time window.
9
+ */
10
+ limit: number;
11
+ /**
12
+ * Duration of the time window in milliseconds.
13
+ */
14
+ windowMs: number;
15
+ }
16
+ //# sourceMappingURL=sliding-window-log.options.d.ts.map
@@ -1 +1,2 @@
1
1
  export {};
2
+ //# sourceMappingURL=sliding-window-log.options.js.map
@@ -0,0 +1,18 @@
1
+ import { type SlidingWindowLogState } from './sliding-window-log.state.js';
2
+ import { type SlidingWindowLogStatus } from './sliding-window-log.status.js';
3
+ import { type RateLimitPolicy, type RateLimitPolicyResult } from '../../core/rate-limit-policy.js';
4
+ /** @internal */
5
+ export declare class SlidingWindowLogPolicy implements RateLimitPolicy<SlidingWindowLogState, SlidingWindowLogStatus> {
6
+ private readonly _limit;
7
+ private readonly _windowMs;
8
+ constructor(_limit: number, _windowMs: number);
9
+ get limit(): number;
10
+ get windowMs(): number;
11
+ getInitialState(): SlidingWindowLogState;
12
+ getStatus(state: SlidingWindowLogState, now: number): SlidingWindowLogStatus;
13
+ evaluate(state: SlidingWindowLogState, now: number, cost: number): RateLimitPolicyResult<SlidingWindowLogState>;
14
+ revert(state: SlidingWindowLogState, cost: number, now: number): SlidingWindowLogState;
15
+ private _syncState;
16
+ private _calculateAvailableAt;
17
+ }
18
+ //# sourceMappingURL=sliding-window-log.policy.d.ts.map
@@ -121,3 +121,4 @@ export class SlidingWindowLogPolicy {
121
121
  return Math.max(now, availableAt);
122
122
  }
123
123
  }
124
+ //# sourceMappingURL=sliding-window-log.policy.js.map
@@ -0,0 +1,18 @@
1
+ import { type Deque } from '@stimulcross/ds-deque';
2
+ /**
3
+ * A log entry in the sliding window log rate limiter.
4
+ */
5
+ export interface SlidingWindowLogEntry {
6
+ ts: number;
7
+ count: number;
8
+ }
9
+ /**
10
+ * The state of the sliding window log rate limiter.
11
+ *
12
+ * When using a distributed state store, make sure it properly serializes and deserializes the state.
13
+ */
14
+ export interface SlidingWindowLogState {
15
+ logs: Deque<SlidingWindowLogEntry>;
16
+ totalUsed: number;
17
+ }
18
+ //# sourceMappingURL=sliding-window-log.state.d.ts.map
@@ -1 +1,2 @@
1
1
  export {};
2
+ //# sourceMappingURL=sliding-window-log.state.js.map
@@ -0,0 +1,39 @@
1
+ import { type RateLimiterStatus } from '../../core/rate-limiter-status.js';
2
+ /**
3
+ * The status of the Sliding Window Log rate limiter.
4
+ */
5
+ export interface SlidingWindowLogStatus extends RateLimiterStatus {
6
+ /**
7
+ * Maximum number of requests allowed within the time window.
8
+ */
9
+ limit: number;
10
+ /**
11
+ * The sliding time window duration in milliseconds.
12
+ */
13
+ windowMs: number;
14
+ /**
15
+ * Total number of requests consumed within the current sliding window.
16
+ *
17
+ * This count includes all requests that fall within the window period.
18
+ */
19
+ totalUsed: number;
20
+ /**
21
+ * Number of remaining requests available before hitting the limit.
22
+ */
23
+ remaining: number;
24
+ /**
25
+ * The timestamp (in milliseconds) when the next request slot will become available.
26
+ *
27
+ * This is based on when the oldest request in the window will expire.
28
+ */
29
+ nextAvailableAt: number;
30
+ /**
31
+ * The timestamp (in milliseconds) when the current window will fully reset.
32
+ *
33
+ * Represents when the last (most recent) request in the log will expire.
34
+ *
35
+ * After this time, all requests will have aged out of the sliding window.
36
+ */
37
+ resetAt: number;
38
+ }
39
+ //# sourceMappingURL=sliding-window-log.status.d.ts.map
@@ -1 +1,2 @@
1
1
  export {};
2
+ //# sourceMappingURL=sliding-window-log.status.js.map
@@ -0,0 +1,5 @@
1
+ export type { TokenBucketState } from './token-bucket.state.js';
2
+ export type { TokenBucketStatus } from './token-bucket.status.js';
3
+ export type { TokenBucketOptions } from './token-bucket.options.js';
4
+ export { TokenBucketLimiter } from './token-bucket.limiter.js';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -1 +1,2 @@
1
1
  export { TokenBucketLimiter } from './token-bucket.limiter.js';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,30 @@
1
+ import { type TokenBucketOptions } from './token-bucket.options.js';
2
+ import { TokenBucketPolicy } from './token-bucket.policy.js';
3
+ import { type TokenBucketState } from './token-bucket.state.js';
4
+ import { type TokenBucketStatus } from './token-bucket.status.js';
5
+ import { AbstractRateLimiter, type ExecutionContext } from '../abstract-rate-limiter.js';
6
+ /**
7
+ * Token Bucket rate limiter.
8
+ *
9
+ * Designed primarily for client-side use to respect third-party limits or protect resources.
10
+ * While this can be used as a server-side limiter with custom distributed storage
11
+ * (e.g., Redis), it is best-effort and not recommended due to high network round-trip latency.
12
+ *
13
+ * Key features:
14
+ * - **Queueing & overflow** - optionally enqueues excess requests up to a maximum allowed overflow capacity
15
+ * - **Concurrency** - limits how many requests can be executed simultaneously
16
+ * - **Priority** - supports task priorities (with fairness and custom policy) to execute critical requests first
17
+ * - **Cancellation** - supports `AbortSignal` to safely remove pending requests from the queue
18
+ * - **Expiration** - automatically drops queued requests that wait longer than the allowed `maxWaitMs`
19
+ * - **Auto-rollback** - reverts spent quota if an enqueued task is canceled or expired
20
+ */
21
+ export declare class TokenBucketLimiter extends AbstractRateLimiter<TokenBucketState, TokenBucketStatus> {
22
+ private readonly _defaultLimitBehaviour;
23
+ private readonly _maxWaitMs;
24
+ protected readonly _policy: TokenBucketPolicy;
25
+ constructor(options: TokenBucketOptions);
26
+ protected _runInternal<T>(fn: () => T | Promise<T>, ctx: ExecutionContext): Promise<T>;
27
+ protected _getDebugStateString(state: TokenBucketState): string;
28
+ private _printSuccessDebug;
29
+ }
30
+ //# sourceMappingURL=token-bucket.limiter.d.ts.map
@@ -72,3 +72,4 @@ export class TokenBucketLimiter extends AbstractRateLimiter {
72
72
  }
73
73
  }
74
74
  }
75
+ //# sourceMappingURL=token-bucket.limiter.js.map
@@ -0,0 +1,16 @@
1
+ import { type TokenBucketState } from './token-bucket.state.js';
2
+ import { type RateLimiterOptions } from '../../interfaces/rate-limiter-options.js';
3
+ /**
4
+ * Options for the Token Bucket rate limiter.
5
+ */
6
+ export interface TokenBucketOptions extends RateLimiterOptions<TokenBucketState> {
7
+ /**
8
+ * The maximum number of tokens that can be stored in the bucket.
9
+ */
10
+ capacity: number;
11
+ /**
12
+ * The rate, in seconds, at which tokens are refilled.
13
+ */
14
+ refillRate: number;
15
+ }
16
+ //# sourceMappingURL=token-bucket.options.d.ts.map
@@ -1 +1,2 @@
1
1
  export {};
2
+ //# sourceMappingURL=token-bucket.options.js.map
@@ -0,0 +1,19 @@
1
+ import { type TokenBucketState } from './token-bucket.state.js';
2
+ import { type TokenBucketStatus } from './token-bucket.status.js';
3
+ import { type RateLimitPolicy, type RateLimitPolicyResult } from '../../core/rate-limit-policy.js';
4
+ /** @internal */
5
+ export declare class TokenBucketPolicy implements RateLimitPolicy<TokenBucketState, TokenBucketStatus> {
6
+ private readonly _capacity;
7
+ private readonly _refillRate;
8
+ private readonly _maxDebt;
9
+ constructor(_capacity: number, _refillRate: number, _maxDebt?: number);
10
+ get capacity(): number;
11
+ get refillRate(): number;
12
+ getInitialState(): TokenBucketState;
13
+ getStatus(state: TokenBucketState, now: number): TokenBucketStatus;
14
+ evaluate(state: TokenBucketState, now: number, cost: number, shouldReserve?: boolean): RateLimitPolicyResult<TokenBucketState>;
15
+ revert(state: TokenBucketState, cost: number, now: number): TokenBucketState;
16
+ private _deny;
17
+ private _syncState;
18
+ }
19
+ //# sourceMappingURL=token-bucket.policy.d.ts.map
@@ -113,3 +113,4 @@ export class TokenBucketPolicy {
113
113
  return { tokens, debt, lastRefill: now };
114
114
  }
115
115
  }
116
+ //# sourceMappingURL=token-bucket.policy.js.map
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Token Bucket rate limiter state.
3
+ *
4
+ * When using a distributed state store, make sure it properly serializes and deserializes the state.
5
+ */
6
+ export interface TokenBucketState {
7
+ tokens: number;
8
+ debt: number;
9
+ lastRefill: number;
10
+ }
11
+ //# sourceMappingURL=token-bucket.state.d.ts.map
@@ -1 +1,2 @@
1
1
  export {};
2
+ //# sourceMappingURL=token-bucket.state.js.map
@@ -0,0 +1,31 @@
1
+ import { type RateLimiterStatus } from '../../core/rate-limiter-status.js';
2
+ /**
3
+ * The status of the Token Bucket rate limiter.
4
+ */
5
+ export interface TokenBucketStatus extends RateLimiterStatus {
6
+ /**
7
+ * The maximum number of tokens that can be stored in the bucket.
8
+ */
9
+ capacity: number;
10
+ /**
11
+ * The rate, in seconds, at which tokens are refilled.
12
+ */
13
+ refillRate: number;
14
+ /**
15
+ * The number of tokens available in the bucket.
16
+ */
17
+ tokens: number;
18
+ /**
19
+ * The number of tokens that have been reserved.
20
+ */
21
+ debt: number;
22
+ /**
23
+ * The timestamp (in milliseconds) at which next token will be available for use.
24
+ */
25
+ nextAvailableAt: number;
26
+ /**
27
+ * The timestamp (in milliseconds) at which the bucket will be reset.
28
+ */
29
+ resetAt: number;
30
+ }
31
+ //# sourceMappingURL=token-bucket.status.d.ts.map
@@ -1 +1,2 @@
1
1
  export {};
2
+ //# sourceMappingURL=token-bucket.status.js.map
@@ -0,0 +1,4 @@
1
+ import { type Clock } from '../core/clock.js';
2
+ /** @internal */
3
+ export declare const defaultClock: Clock;
4
+ //# sourceMappingURL=default-clock.d.ts.map
@@ -4,3 +4,4 @@ export const defaultClock = {
4
4
  return Date.now();
5
5
  },
6
6
  };
7
+ //# sourceMappingURL=default-clock.js.map