@zeitar/throttle 1.0.0 → 1.1.0
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.
- package/README.md +17 -0
- package/dist/CompoundLimiter.d.ts +0 -1
- package/dist/CompoundLimiter.js +0 -1
- package/dist/CompoundRateLimiterFactory.d.ts +0 -1
- package/dist/CompoundRateLimiterFactory.js +0 -1
- package/dist/LimiterInterface.d.ts +0 -1
- package/dist/LimiterInterface.js +0 -1
- package/dist/LimiterStateInterface.d.ts +0 -1
- package/dist/LimiterStateInterface.js +0 -1
- package/dist/RateLimit.d.ts +0 -1
- package/dist/RateLimit.js +0 -1
- package/dist/RateLimiterFactory.d.ts +0 -1
- package/dist/RateLimiterFactory.js +0 -1
- package/dist/RateLimiterFactoryInterface.d.ts +0 -1
- package/dist/RateLimiterFactoryInterface.js +0 -1
- package/dist/Reservation.d.ts +0 -1
- package/dist/Reservation.js +0 -1
- package/dist/errors/InvalidIntervalError.d.ts +0 -1
- package/dist/errors/InvalidIntervalError.js +0 -1
- package/dist/errors/MaxWaitDurationExceededError.d.ts +0 -1
- package/dist/errors/MaxWaitDurationExceededError.js +0 -1
- package/dist/errors/RateLimitExceededError.d.ts +0 -1
- package/dist/errors/RateLimitExceededError.js +0 -1
- package/dist/errors/ReserveNotSupportedError.d.ts +0 -1
- package/dist/errors/ReserveNotSupportedError.js +0 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.js +0 -1
- package/dist/policy/FixedWindowLimiter.d.ts +0 -1
- package/dist/policy/FixedWindowLimiter.js +0 -1
- package/dist/policy/NoLimiter.d.ts +0 -1
- package/dist/policy/NoLimiter.js +0 -1
- package/dist/policy/Rate.d.ts +0 -1
- package/dist/policy/Rate.js +0 -1
- package/dist/policy/SlidingWindow.d.ts +0 -1
- package/dist/policy/SlidingWindow.js +0 -1
- package/dist/policy/SlidingWindowLimiter.d.ts +0 -1
- package/dist/policy/SlidingWindowLimiter.js +0 -1
- package/dist/policy/TokenBucket.d.ts +0 -1
- package/dist/policy/TokenBucket.js +0 -1
- package/dist/policy/TokenBucketLimiter.d.ts +0 -1
- package/dist/policy/TokenBucketLimiter.js +0 -1
- package/dist/policy/Window.d.ts +0 -1
- package/dist/policy/Window.js +0 -1
- package/dist/storage/InMemoryStorage.d.ts +0 -1
- package/dist/storage/InMemoryStorage.js +0 -1
- package/dist/storage/LockInterface.d.ts +0 -1
- package/dist/storage/LockInterface.js +0 -1
- package/dist/storage/StorageInterface.d.ts +0 -1
- package/dist/storage/StorageInterface.js +0 -1
- package/dist/util/TimeUtil.d.ts +0 -1
- package/dist/util/TimeUtil.js +0 -1
- package/package.json +1 -2
- package/dist/CompoundLimiter.d.ts.map +0 -1
- package/dist/CompoundLimiter.js.map +0 -1
- package/dist/CompoundRateLimiterFactory.d.ts.map +0 -1
- package/dist/CompoundRateLimiterFactory.js.map +0 -1
- package/dist/LimiterInterface.d.ts.map +0 -1
- package/dist/LimiterInterface.js.map +0 -1
- package/dist/LimiterStateInterface.d.ts.map +0 -1
- package/dist/LimiterStateInterface.js.map +0 -1
- package/dist/RateLimit.d.ts.map +0 -1
- package/dist/RateLimit.js.map +0 -1
- package/dist/RateLimiterFactory.d.ts.map +0 -1
- package/dist/RateLimiterFactory.js.map +0 -1
- package/dist/RateLimiterFactoryInterface.d.ts.map +0 -1
- package/dist/RateLimiterFactoryInterface.js.map +0 -1
- package/dist/Reservation.d.ts.map +0 -1
- package/dist/Reservation.js.map +0 -1
- package/dist/__tests__/CompoundLimiter.test.d.ts +0 -2
- package/dist/__tests__/CompoundLimiter.test.d.ts.map +0 -1
- package/dist/__tests__/CompoundLimiter.test.js +0 -231
- package/dist/__tests__/CompoundLimiter.test.js.map +0 -1
- package/dist/__tests__/CompoundRateLimiterFactory.test.d.ts +0 -2
- package/dist/__tests__/CompoundRateLimiterFactory.test.d.ts.map +0 -1
- package/dist/__tests__/CompoundRateLimiterFactory.test.js +0 -213
- package/dist/__tests__/CompoundRateLimiterFactory.test.js.map +0 -1
- package/dist/__tests__/RateLimit.test.d.ts +0 -2
- package/dist/__tests__/RateLimit.test.d.ts.map +0 -1
- package/dist/__tests__/RateLimit.test.js +0 -108
- package/dist/__tests__/RateLimit.test.js.map +0 -1
- package/dist/__tests__/RateLimiterFactory.test.d.ts +0 -2
- package/dist/__tests__/RateLimiterFactory.test.d.ts.map +0 -1
- package/dist/__tests__/RateLimiterFactory.test.js +0 -323
- package/dist/__tests__/RateLimiterFactory.test.js.map +0 -1
- package/dist/__tests__/Reservation.test.d.ts +0 -2
- package/dist/__tests__/Reservation.test.d.ts.map +0 -1
- package/dist/__tests__/Reservation.test.js +0 -110
- package/dist/__tests__/Reservation.test.js.map +0 -1
- package/dist/errors/InvalidIntervalError.d.ts.map +0 -1
- package/dist/errors/InvalidIntervalError.js.map +0 -1
- package/dist/errors/MaxWaitDurationExceededError.d.ts.map +0 -1
- package/dist/errors/MaxWaitDurationExceededError.js.map +0 -1
- package/dist/errors/RateLimitExceededError.d.ts.map +0 -1
- package/dist/errors/RateLimitExceededError.js.map +0 -1
- package/dist/errors/ReserveNotSupportedError.d.ts.map +0 -1
- package/dist/errors/ReserveNotSupportedError.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/policy/FixedWindowLimiter.d.ts.map +0 -1
- package/dist/policy/FixedWindowLimiter.js.map +0 -1
- package/dist/policy/NoLimiter.d.ts.map +0 -1
- package/dist/policy/NoLimiter.js.map +0 -1
- package/dist/policy/Rate.d.ts.map +0 -1
- package/dist/policy/Rate.js.map +0 -1
- package/dist/policy/SlidingWindow.d.ts.map +0 -1
- package/dist/policy/SlidingWindow.js.map +0 -1
- package/dist/policy/SlidingWindowLimiter.d.ts.map +0 -1
- package/dist/policy/SlidingWindowLimiter.js.map +0 -1
- package/dist/policy/TokenBucket.d.ts.map +0 -1
- package/dist/policy/TokenBucket.js.map +0 -1
- package/dist/policy/TokenBucketLimiter.d.ts.map +0 -1
- package/dist/policy/TokenBucketLimiter.js.map +0 -1
- package/dist/policy/Window.d.ts.map +0 -1
- package/dist/policy/Window.js.map +0 -1
- package/dist/policy/__tests__/FixedWindowLimiter.test.d.ts +0 -2
- package/dist/policy/__tests__/FixedWindowLimiter.test.d.ts.map +0 -1
- package/dist/policy/__tests__/FixedWindowLimiter.test.js +0 -180
- package/dist/policy/__tests__/FixedWindowLimiter.test.js.map +0 -1
- package/dist/policy/__tests__/NoLimiter.test.d.ts +0 -2
- package/dist/policy/__tests__/NoLimiter.test.d.ts.map +0 -1
- package/dist/policy/__tests__/NoLimiter.test.js +0 -40
- package/dist/policy/__tests__/NoLimiter.test.js.map +0 -1
- package/dist/policy/__tests__/Rate.test.d.ts +0 -2
- package/dist/policy/__tests__/Rate.test.d.ts.map +0 -1
- package/dist/policy/__tests__/Rate.test.js +0 -162
- package/dist/policy/__tests__/Rate.test.js.map +0 -1
- package/dist/policy/__tests__/SlidingWindow.test.d.ts +0 -2
- package/dist/policy/__tests__/SlidingWindow.test.d.ts.map +0 -1
- package/dist/policy/__tests__/SlidingWindow.test.js +0 -257
- package/dist/policy/__tests__/SlidingWindow.test.js.map +0 -1
- package/dist/policy/__tests__/SlidingWindowLimiter.test.d.ts +0 -2
- package/dist/policy/__tests__/SlidingWindowLimiter.test.d.ts.map +0 -1
- package/dist/policy/__tests__/SlidingWindowLimiter.test.js +0 -201
- package/dist/policy/__tests__/SlidingWindowLimiter.test.js.map +0 -1
- package/dist/policy/__tests__/TokenBucket.test.d.ts +0 -2
- package/dist/policy/__tests__/TokenBucket.test.d.ts.map +0 -1
- package/dist/policy/__tests__/TokenBucket.test.js +0 -171
- package/dist/policy/__tests__/TokenBucket.test.js.map +0 -1
- package/dist/policy/__tests__/TokenBucketLimiter.test.d.ts +0 -2
- package/dist/policy/__tests__/TokenBucketLimiter.test.d.ts.map +0 -1
- package/dist/policy/__tests__/TokenBucketLimiter.test.js +0 -175
- package/dist/policy/__tests__/TokenBucketLimiter.test.js.map +0 -1
- package/dist/policy/__tests__/Window.test.d.ts +0 -2
- package/dist/policy/__tests__/Window.test.d.ts.map +0 -1
- package/dist/policy/__tests__/Window.test.js +0 -193
- package/dist/policy/__tests__/Window.test.js.map +0 -1
- package/dist/storage/InMemoryStorage.d.ts.map +0 -1
- package/dist/storage/InMemoryStorage.js.map +0 -1
- package/dist/storage/LockInterface.d.ts.map +0 -1
- package/dist/storage/LockInterface.js.map +0 -1
- package/dist/storage/StorageInterface.d.ts.map +0 -1
- package/dist/storage/StorageInterface.js.map +0 -1
- package/dist/storage/__tests__/InMemoryStorage.test.d.ts +0 -2
- package/dist/storage/__tests__/InMemoryStorage.test.d.ts.map +0 -1
- package/dist/storage/__tests__/InMemoryStorage.test.js +0 -154
- package/dist/storage/__tests__/InMemoryStorage.test.js.map +0 -1
- package/dist/util/TimeUtil.d.ts.map +0 -1
- package/dist/util/TimeUtil.js.map +0 -1
- package/dist/util/__tests__/TimeUtil.test.d.ts +0 -2
- package/dist/util/__tests__/TimeUtil.test.d.ts.map +0 -1
- package/dist/util/__tests__/TimeUtil.test.js +0 -132
- package/dist/util/__tests__/TimeUtil.test.js.map +0 -1
|
@@ -1,231 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const CompoundLimiter_1 = require("../CompoundLimiter");
|
|
4
|
-
const NoLimiter_1 = require("../policy/NoLimiter");
|
|
5
|
-
const FixedWindowLimiter_1 = require("../policy/FixedWindowLimiter");
|
|
6
|
-
const TokenBucketLimiter_1 = require("../policy/TokenBucketLimiter");
|
|
7
|
-
const InMemoryStorage_1 = require("../storage/InMemoryStorage");
|
|
8
|
-
const Rate_1 = require("../policy/Rate");
|
|
9
|
-
const ReserveNotSupportedError_1 = require("../errors/ReserveNotSupportedError");
|
|
10
|
-
describe('CompoundLimiter', () => {
|
|
11
|
-
describe('constructor', () => {
|
|
12
|
-
it('should create a compound limiter with multiple limiters', () => {
|
|
13
|
-
const limiters = [new NoLimiter_1.NoLimiter(), new NoLimiter_1.NoLimiter()];
|
|
14
|
-
const compound = new CompoundLimiter_1.CompoundLimiter(limiters);
|
|
15
|
-
expect(compound).toBeInstanceOf(CompoundLimiter_1.CompoundLimiter);
|
|
16
|
-
});
|
|
17
|
-
it('should throw error when no limiters provided', () => {
|
|
18
|
-
expect(() => new CompoundLimiter_1.CompoundLimiter([])).toThrow('CompoundLimiter requires at least one limiter');
|
|
19
|
-
});
|
|
20
|
-
});
|
|
21
|
-
describe('reserve', () => {
|
|
22
|
-
it('should always throw ReserveNotSupportedError with descriptive message', async () => {
|
|
23
|
-
const compound = new CompoundLimiter_1.CompoundLimiter([new NoLimiter_1.NoLimiter()]);
|
|
24
|
-
await expect(compound.reserve(1)).rejects.toThrow(ReserveNotSupportedError_1.ReserveNotSupportedError);
|
|
25
|
-
await expect(compound.reserve(1)).rejects.toThrow('CompoundLimiter does not support the reserve() method');
|
|
26
|
-
await expect(compound.reserve(1, 10)).rejects.toThrow(ReserveNotSupportedError_1.ReserveNotSupportedError);
|
|
27
|
-
});
|
|
28
|
-
});
|
|
29
|
-
describe('consume', () => {
|
|
30
|
-
it('should accept when all limiters accept', async () => {
|
|
31
|
-
const compound = new CompoundLimiter_1.CompoundLimiter([
|
|
32
|
-
new NoLimiter_1.NoLimiter(),
|
|
33
|
-
new NoLimiter_1.NoLimiter(),
|
|
34
|
-
]);
|
|
35
|
-
const result = await compound.consume(5);
|
|
36
|
-
expect(result.isAccepted()).toBe(true);
|
|
37
|
-
});
|
|
38
|
-
it('should reject when any limiter rejects', async () => {
|
|
39
|
-
const storage = new InMemoryStorage_1.InMemoryStorage();
|
|
40
|
-
const limiters = [
|
|
41
|
-
new NoLimiter_1.NoLimiter(),
|
|
42
|
-
new FixedWindowLimiter_1.FixedWindowLimiter('test', 5, 60, storage),
|
|
43
|
-
];
|
|
44
|
-
const compound = new CompoundLimiter_1.CompoundLimiter(limiters);
|
|
45
|
-
// Exhaust the fixed window limiter
|
|
46
|
-
await limiters[1].consume(5);
|
|
47
|
-
const result = await compound.consume(1);
|
|
48
|
-
expect(result.isAccepted()).toBe(false);
|
|
49
|
-
});
|
|
50
|
-
it('should return most restrictive result when all accept', async () => {
|
|
51
|
-
const storage1 = new InMemoryStorage_1.InMemoryStorage();
|
|
52
|
-
const storage2 = new InMemoryStorage_1.InMemoryStorage();
|
|
53
|
-
const limiters = [
|
|
54
|
-
new TokenBucketLimiter_1.TokenBucketLimiter('test1', 10, Rate_1.Rate.perSecond(1), storage1),
|
|
55
|
-
new TokenBucketLimiter_1.TokenBucketLimiter('test2', 20, Rate_1.Rate.perSecond(1), storage2),
|
|
56
|
-
];
|
|
57
|
-
const compound = new CompoundLimiter_1.CompoundLimiter(limiters);
|
|
58
|
-
await limiters[0].consume(5); // 5 remaining
|
|
59
|
-
await limiters[1].consume(10); // 10 remaining
|
|
60
|
-
const result = await compound.consume(1);
|
|
61
|
-
expect(result.isAccepted()).toBe(true);
|
|
62
|
-
expect(result.getRemainingTokens()).toBe(4); // Most restrictive (fewer tokens)
|
|
63
|
-
});
|
|
64
|
-
it('should return longest retry time when all reject', async () => {
|
|
65
|
-
jest.useFakeTimers();
|
|
66
|
-
const storage1 = new InMemoryStorage_1.InMemoryStorage();
|
|
67
|
-
const storage2 = new InMemoryStorage_1.InMemoryStorage();
|
|
68
|
-
const limiters = [
|
|
69
|
-
new FixedWindowLimiter_1.FixedWindowLimiter('test1', 5, 60, storage1),
|
|
70
|
-
new FixedWindowLimiter_1.FixedWindowLimiter('test2', 5, 120, storage2),
|
|
71
|
-
];
|
|
72
|
-
const compound = new CompoundLimiter_1.CompoundLimiter(limiters);
|
|
73
|
-
// Exhaust both limiters
|
|
74
|
-
await limiters[0].consume(5);
|
|
75
|
-
await limiters[1].consume(5);
|
|
76
|
-
const result = await compound.consume(1);
|
|
77
|
-
expect(result.isAccepted()).toBe(false);
|
|
78
|
-
// Should return the limiter with longer retry time (120s window)
|
|
79
|
-
const retryAfter = result.getRetryAfter();
|
|
80
|
-
expect(retryAfter.getTime()).toBeGreaterThan(Date.now());
|
|
81
|
-
jest.useRealTimers();
|
|
82
|
-
});
|
|
83
|
-
it('should prefer rejected over accepted', async () => {
|
|
84
|
-
const storage = new InMemoryStorage_1.InMemoryStorage();
|
|
85
|
-
const limiters = [
|
|
86
|
-
new NoLimiter_1.NoLimiter(),
|
|
87
|
-
new FixedWindowLimiter_1.FixedWindowLimiter('test', 5, 60, storage),
|
|
88
|
-
];
|
|
89
|
-
const compound = new CompoundLimiter_1.CompoundLimiter(limiters);
|
|
90
|
-
await limiters[1].consume(5);
|
|
91
|
-
const result = await compound.consume(1);
|
|
92
|
-
expect(result.isAccepted()).toBe(false);
|
|
93
|
-
});
|
|
94
|
-
it('should handle default token parameter', async () => {
|
|
95
|
-
const compound = new CompoundLimiter_1.CompoundLimiter([new NoLimiter_1.NoLimiter()]);
|
|
96
|
-
const result = await compound.consume(); // Default 1 token
|
|
97
|
-
expect(result.isAccepted()).toBe(true);
|
|
98
|
-
});
|
|
99
|
-
it('should evaluate all limiters', async () => {
|
|
100
|
-
const storage1 = new InMemoryStorage_1.InMemoryStorage();
|
|
101
|
-
const storage2 = new InMemoryStorage_1.InMemoryStorage();
|
|
102
|
-
const storage3 = new InMemoryStorage_1.InMemoryStorage();
|
|
103
|
-
const limiters = [
|
|
104
|
-
new FixedWindowLimiter_1.FixedWindowLimiter('test1', 10, 60, storage1),
|
|
105
|
-
new FixedWindowLimiter_1.FixedWindowLimiter('test2', 10, 60, storage2),
|
|
106
|
-
new FixedWindowLimiter_1.FixedWindowLimiter('test3', 10, 60, storage3),
|
|
107
|
-
];
|
|
108
|
-
const compound = new CompoundLimiter_1.CompoundLimiter(limiters);
|
|
109
|
-
const result = await compound.consume(5);
|
|
110
|
-
expect(result.isAccepted()).toBe(true);
|
|
111
|
-
// Verify all limiters were updated
|
|
112
|
-
const r1 = await limiters[0].consume(1);
|
|
113
|
-
const r2 = await limiters[1].consume(1);
|
|
114
|
-
const r3 = await limiters[2].consume(1);
|
|
115
|
-
expect(r1.getRemainingTokens()).toBe(4); // 10 - 5 - 1
|
|
116
|
-
expect(r2.getRemainingTokens()).toBe(4);
|
|
117
|
-
expect(r3.getRemainingTokens()).toBe(4);
|
|
118
|
-
});
|
|
119
|
-
});
|
|
120
|
-
describe('reset', () => {
|
|
121
|
-
it('should reset all limiters', async () => {
|
|
122
|
-
const storage1 = new InMemoryStorage_1.InMemoryStorage();
|
|
123
|
-
const storage2 = new InMemoryStorage_1.InMemoryStorage();
|
|
124
|
-
const limiters = [
|
|
125
|
-
new FixedWindowLimiter_1.FixedWindowLimiter('test1', 10, 60, storage1),
|
|
126
|
-
new FixedWindowLimiter_1.FixedWindowLimiter('test2', 10, 60, storage2),
|
|
127
|
-
];
|
|
128
|
-
const compound = new CompoundLimiter_1.CompoundLimiter(limiters);
|
|
129
|
-
await compound.consume(5);
|
|
130
|
-
await compound.reset();
|
|
131
|
-
const result = await compound.consume(1);
|
|
132
|
-
expect(result.isAccepted()).toBe(true);
|
|
133
|
-
expect(result.getRemainingTokens()).toBe(9);
|
|
134
|
-
});
|
|
135
|
-
it('should handle reset with single limiter', async () => {
|
|
136
|
-
const storage = new InMemoryStorage_1.InMemoryStorage();
|
|
137
|
-
const compound = new CompoundLimiter_1.CompoundLimiter([
|
|
138
|
-
new FixedWindowLimiter_1.FixedWindowLimiter('test', 10, 60, storage),
|
|
139
|
-
]);
|
|
140
|
-
await compound.consume(10);
|
|
141
|
-
await compound.reset();
|
|
142
|
-
const result = await compound.consume(5);
|
|
143
|
-
expect(result.isAccepted()).toBe(true);
|
|
144
|
-
});
|
|
145
|
-
});
|
|
146
|
-
describe('complex scenarios', () => {
|
|
147
|
-
it('should enforce multiple rate limits simultaneously', async () => {
|
|
148
|
-
const storage1 = new InMemoryStorage_1.InMemoryStorage();
|
|
149
|
-
const storage2 = new InMemoryStorage_1.InMemoryStorage();
|
|
150
|
-
// Per-second and per-minute limits
|
|
151
|
-
const limiters = [
|
|
152
|
-
new TokenBucketLimiter_1.TokenBucketLimiter('per-second', 5, Rate_1.Rate.perSecond(5), storage1),
|
|
153
|
-
new TokenBucketLimiter_1.TokenBucketLimiter('per-minute', 50, Rate_1.Rate.perMinute(50), storage2),
|
|
154
|
-
];
|
|
155
|
-
const compound = new CompoundLimiter_1.CompoundLimiter(limiters);
|
|
156
|
-
// Should be limited by per-second limit
|
|
157
|
-
for (let i = 0; i < 5; i++) {
|
|
158
|
-
const result = await compound.consume(1);
|
|
159
|
-
expect(result.isAccepted()).toBe(true);
|
|
160
|
-
}
|
|
161
|
-
const result = await compound.consume(1);
|
|
162
|
-
expect(result.isAccepted()).toBe(false);
|
|
163
|
-
});
|
|
164
|
-
it('should handle mix of limiter types', async () => {
|
|
165
|
-
const storage1 = new InMemoryStorage_1.InMemoryStorage();
|
|
166
|
-
const storage2 = new InMemoryStorage_1.InMemoryStorage();
|
|
167
|
-
const limiters = [
|
|
168
|
-
new NoLimiter_1.NoLimiter(),
|
|
169
|
-
new FixedWindowLimiter_1.FixedWindowLimiter('fixed', 10, 60, storage1),
|
|
170
|
-
new TokenBucketLimiter_1.TokenBucketLimiter('token', 15, Rate_1.Rate.perSecond(1), storage2),
|
|
171
|
-
];
|
|
172
|
-
const compound = new CompoundLimiter_1.CompoundLimiter(limiters);
|
|
173
|
-
const result = await compound.consume(5);
|
|
174
|
-
expect(result.isAccepted()).toBe(true);
|
|
175
|
-
expect(result.getRemainingTokens()).toBe(5); // Limited by FixedWindowLimiter
|
|
176
|
-
});
|
|
177
|
-
it('should handle progressive consumption', async () => {
|
|
178
|
-
const storage1 = new InMemoryStorage_1.InMemoryStorage();
|
|
179
|
-
const storage2 = new InMemoryStorage_1.InMemoryStorage();
|
|
180
|
-
const limiters = [
|
|
181
|
-
new FixedWindowLimiter_1.FixedWindowLimiter('test1', 10, 60, storage1),
|
|
182
|
-
new FixedWindowLimiter_1.FixedWindowLimiter('test2', 20, 60, storage2),
|
|
183
|
-
];
|
|
184
|
-
const compound = new CompoundLimiter_1.CompoundLimiter(limiters);
|
|
185
|
-
// Consume progressively
|
|
186
|
-
const results = [];
|
|
187
|
-
for (let i = 0; i < 15; i++) {
|
|
188
|
-
results.push(await compound.consume(1));
|
|
189
|
-
}
|
|
190
|
-
const accepted = results.filter(r => r.isAccepted()).length;
|
|
191
|
-
const rejected = results.filter(r => !r.isAccepted()).length;
|
|
192
|
-
expect(accepted).toBe(10); // Limited by first limiter
|
|
193
|
-
expect(rejected).toBe(5);
|
|
194
|
-
});
|
|
195
|
-
});
|
|
196
|
-
describe('edge cases', () => {
|
|
197
|
-
it('should handle single limiter compound', async () => {
|
|
198
|
-
const storage = new InMemoryStorage_1.InMemoryStorage();
|
|
199
|
-
const compound = new CompoundLimiter_1.CompoundLimiter([
|
|
200
|
-
new FixedWindowLimiter_1.FixedWindowLimiter('test', 10, 60, storage),
|
|
201
|
-
]);
|
|
202
|
-
const result = await compound.consume(5);
|
|
203
|
-
expect(result.isAccepted()).toBe(true);
|
|
204
|
-
expect(result.getRemainingTokens()).toBe(5);
|
|
205
|
-
});
|
|
206
|
-
it('should handle many limiters', async () => {
|
|
207
|
-
const limiters = Array(10).fill(null).map(() => new NoLimiter_1.NoLimiter());
|
|
208
|
-
const compound = new CompoundLimiter_1.CompoundLimiter(limiters);
|
|
209
|
-
const result = await compound.consume(100);
|
|
210
|
-
expect(result.isAccepted()).toBe(true);
|
|
211
|
-
});
|
|
212
|
-
});
|
|
213
|
-
describe('AND logic', () => {
|
|
214
|
-
it('should require all limiters to accept', async () => {
|
|
215
|
-
const storage1 = new InMemoryStorage_1.InMemoryStorage();
|
|
216
|
-
const storage2 = new InMemoryStorage_1.InMemoryStorage();
|
|
217
|
-
const storage3 = new InMemoryStorage_1.InMemoryStorage();
|
|
218
|
-
const limiters = [
|
|
219
|
-
new FixedWindowLimiter_1.FixedWindowLimiter('test1', 10, 60, storage1),
|
|
220
|
-
new FixedWindowLimiter_1.FixedWindowLimiter('test2', 10, 60, storage2),
|
|
221
|
-
new FixedWindowLimiter_1.FixedWindowLimiter('test3', 10, 60, storage3),
|
|
222
|
-
];
|
|
223
|
-
const compound = new CompoundLimiter_1.CompoundLimiter(limiters);
|
|
224
|
-
// Exhaust just one limiter
|
|
225
|
-
await limiters[1].consume(10);
|
|
226
|
-
const result = await compound.consume(1);
|
|
227
|
-
expect(result.isAccepted()).toBe(false);
|
|
228
|
-
});
|
|
229
|
-
});
|
|
230
|
-
});
|
|
231
|
-
//# sourceMappingURL=CompoundLimiter.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"CompoundLimiter.test.js","sourceRoot":"","sources":["../../src/__tests__/CompoundLimiter.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"CompoundRateLimiterFactory.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/CompoundRateLimiterFactory.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,213 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const CompoundRateLimiterFactory_1 = require("../CompoundRateLimiterFactory");
|
|
4
|
-
const RateLimiterFactory_1 = require("../RateLimiterFactory");
|
|
5
|
-
const InMemoryStorage_1 = require("../storage/InMemoryStorage");
|
|
6
|
-
const CompoundLimiter_1 = require("../CompoundLimiter");
|
|
7
|
-
describe('CompoundRateLimiterFactory', () => {
|
|
8
|
-
let storage;
|
|
9
|
-
beforeEach(() => {
|
|
10
|
-
storage = new InMemoryStorage_1.InMemoryStorage();
|
|
11
|
-
});
|
|
12
|
-
describe('constructor', () => {
|
|
13
|
-
it('should create factory with multiple factories', () => {
|
|
14
|
-
const factories = [
|
|
15
|
-
new RateLimiterFactory_1.RateLimiterFactory({ policy: 'fixed_window', id: 'test1', limit: 10, interval: '60 seconds' }, storage),
|
|
16
|
-
new RateLimiterFactory_1.RateLimiterFactory({ policy: 'token_bucket', id: 'test2', limit: 5, rate: { interval: '1 second', amount: 1 } }, storage),
|
|
17
|
-
];
|
|
18
|
-
const compound = new CompoundRateLimiterFactory_1.CompoundRateLimiterFactory(factories);
|
|
19
|
-
expect(compound).toBeInstanceOf(CompoundRateLimiterFactory_1.CompoundRateLimiterFactory);
|
|
20
|
-
});
|
|
21
|
-
it('should throw error when no factories provided', () => {
|
|
22
|
-
expect(() => new CompoundRateLimiterFactory_1.CompoundRateLimiterFactory([])).toThrow('CompoundRateLimiterFactory requires at least one factory');
|
|
23
|
-
});
|
|
24
|
-
it('should accept single factory', () => {
|
|
25
|
-
const factory = new RateLimiterFactory_1.RateLimiterFactory({ policy: 'fixed_window', id: 'test', limit: 10, interval: '60 seconds' }, storage);
|
|
26
|
-
const compound = new CompoundRateLimiterFactory_1.CompoundRateLimiterFactory([factory]);
|
|
27
|
-
expect(compound).toBeInstanceOf(CompoundRateLimiterFactory_1.CompoundRateLimiterFactory);
|
|
28
|
-
});
|
|
29
|
-
});
|
|
30
|
-
describe('create', () => {
|
|
31
|
-
it('should create CompoundLimiter', () => {
|
|
32
|
-
const factories = [
|
|
33
|
-
new RateLimiterFactory_1.RateLimiterFactory({ policy: 'fixed_window', id: 'test1', limit: 10, interval: '60 seconds' }, storage),
|
|
34
|
-
new RateLimiterFactory_1.RateLimiterFactory({ policy: 'token_bucket', id: 'test2', limit: 5, rate: { interval: '1 second', amount: 1 } }, storage),
|
|
35
|
-
];
|
|
36
|
-
const compound = new CompoundRateLimiterFactory_1.CompoundRateLimiterFactory(factories);
|
|
37
|
-
const limiter = compound.create();
|
|
38
|
-
expect(limiter).toBeInstanceOf(CompoundLimiter_1.CompoundLimiter);
|
|
39
|
-
});
|
|
40
|
-
it('should pass key to all underlying factories', async () => {
|
|
41
|
-
const factories = [
|
|
42
|
-
new RateLimiterFactory_1.RateLimiterFactory({ policy: 'fixed_window', id: 'limit1', limit: 10, interval: '60 seconds' }, storage),
|
|
43
|
-
new RateLimiterFactory_1.RateLimiterFactory({ policy: 'fixed_window', id: 'limit2', limit: 20, interval: '60 seconds' }, storage),
|
|
44
|
-
];
|
|
45
|
-
const compound = new CompoundRateLimiterFactory_1.CompoundRateLimiterFactory(factories);
|
|
46
|
-
const limiter1 = compound.create('user1');
|
|
47
|
-
const limiter2 = compound.create('user2');
|
|
48
|
-
// Consume from limiter1
|
|
49
|
-
await limiter1.consume(5);
|
|
50
|
-
// limiter2 should have full capacity
|
|
51
|
-
const result = await limiter2.consume(1);
|
|
52
|
-
expect(result.getRemainingTokens()).toBe(9);
|
|
53
|
-
});
|
|
54
|
-
it('should create independent limiters for different keys', async () => {
|
|
55
|
-
const factories = [
|
|
56
|
-
new RateLimiterFactory_1.RateLimiterFactory({ policy: 'token_bucket', id: 'api', limit: 5, rate: { interval: '1 second', amount: 1 } }, storage),
|
|
57
|
-
];
|
|
58
|
-
const compound = new CompoundRateLimiterFactory_1.CompoundRateLimiterFactory(factories);
|
|
59
|
-
const limiter1 = compound.create('user1');
|
|
60
|
-
const limiter2 = compound.create('user2');
|
|
61
|
-
await limiter1.consume(5);
|
|
62
|
-
const r1 = await limiter1.consume(1);
|
|
63
|
-
const r2 = await limiter2.consume(1);
|
|
64
|
-
expect(r1.isAccepted()).toBe(false);
|
|
65
|
-
expect(r2.isAccepted()).toBe(true);
|
|
66
|
-
});
|
|
67
|
-
it('should handle null key', async () => {
|
|
68
|
-
const factories = [
|
|
69
|
-
new RateLimiterFactory_1.RateLimiterFactory({ policy: 'fixed_window', id: 'test', limit: 10, interval: '60 seconds' }, storage),
|
|
70
|
-
];
|
|
71
|
-
const compound = new CompoundRateLimiterFactory_1.CompoundRateLimiterFactory(factories);
|
|
72
|
-
const limiter = compound.create(null);
|
|
73
|
-
const result = await limiter.consume(5);
|
|
74
|
-
expect(result.isAccepted()).toBe(true);
|
|
75
|
-
});
|
|
76
|
-
it('should handle undefined key', async () => {
|
|
77
|
-
const factories = [
|
|
78
|
-
new RateLimiterFactory_1.RateLimiterFactory({ policy: 'fixed_window', id: 'test', limit: 10, interval: '60 seconds' }, storage),
|
|
79
|
-
];
|
|
80
|
-
const compound = new CompoundRateLimiterFactory_1.CompoundRateLimiterFactory(factories);
|
|
81
|
-
const limiter = compound.create();
|
|
82
|
-
const result = await limiter.consume(5);
|
|
83
|
-
expect(result.isAccepted()).toBe(true);
|
|
84
|
-
});
|
|
85
|
-
});
|
|
86
|
-
describe('compound behavior', () => {
|
|
87
|
-
it('should enforce all rate limits', async () => {
|
|
88
|
-
const factories = [
|
|
89
|
-
new RateLimiterFactory_1.RateLimiterFactory({ policy: 'fixed_window', id: 'per-minute', limit: 100, interval: '60 seconds' }, storage),
|
|
90
|
-
new RateLimiterFactory_1.RateLimiterFactory({ policy: 'token_bucket', id: 'per-second', limit: 5, rate: { interval: '1 second', amount: 5 } }, storage),
|
|
91
|
-
];
|
|
92
|
-
const compound = new CompoundRateLimiterFactory_1.CompoundRateLimiterFactory(factories);
|
|
93
|
-
const limiter = compound.create();
|
|
94
|
-
// Should be limited by per-second limit
|
|
95
|
-
for (let i = 0; i < 5; i++) {
|
|
96
|
-
const result = await limiter.consume(1);
|
|
97
|
-
expect(result.isAccepted()).toBe(true);
|
|
98
|
-
}
|
|
99
|
-
const result = await limiter.consume(1);
|
|
100
|
-
expect(result.isAccepted()).toBe(false);
|
|
101
|
-
});
|
|
102
|
-
it('should return most restrictive result', async () => {
|
|
103
|
-
const storage1 = new InMemoryStorage_1.InMemoryStorage();
|
|
104
|
-
const storage2 = new InMemoryStorage_1.InMemoryStorage();
|
|
105
|
-
const factories = [
|
|
106
|
-
new RateLimiterFactory_1.RateLimiterFactory({ policy: 'fixed_window', id: 'limit1', limit: 10, interval: '60 seconds' }, storage1),
|
|
107
|
-
new RateLimiterFactory_1.RateLimiterFactory({ policy: 'fixed_window', id: 'limit2', limit: 20, interval: '60 seconds' }, storage2),
|
|
108
|
-
];
|
|
109
|
-
const compound = new CompoundRateLimiterFactory_1.CompoundRateLimiterFactory(factories);
|
|
110
|
-
const limiter = compound.create();
|
|
111
|
-
const result = await limiter.consume(5);
|
|
112
|
-
expect(result.isAccepted()).toBe(true);
|
|
113
|
-
expect(result.getRemainingTokens()).toBe(5); // Limited by first limiter (10 - 5 = 5)
|
|
114
|
-
});
|
|
115
|
-
it('should combine different policy types', async () => {
|
|
116
|
-
const factories = [
|
|
117
|
-
new RateLimiterFactory_1.RateLimiterFactory({ policy: 'token_bucket', id: 'burst', limit: 10, rate: { interval: '1 second', amount: 1 } }, storage),
|
|
118
|
-
new RateLimiterFactory_1.RateLimiterFactory({ policy: 'sliding_window', id: 'smooth', limit: 50, interval: '60 seconds' }, storage),
|
|
119
|
-
new RateLimiterFactory_1.RateLimiterFactory({ policy: 'fixed_window', id: 'window', limit: 100, interval: '3600 seconds' }, storage),
|
|
120
|
-
];
|
|
121
|
-
const compound = new CompoundRateLimiterFactory_1.CompoundRateLimiterFactory(factories);
|
|
122
|
-
const limiter = compound.create();
|
|
123
|
-
const result = await limiter.consume(5);
|
|
124
|
-
expect(result.isAccepted()).toBe(true);
|
|
125
|
-
});
|
|
126
|
-
});
|
|
127
|
-
describe('multiple compound limiters', () => {
|
|
128
|
-
it('should maintain separate state per key', async () => {
|
|
129
|
-
const factories = [
|
|
130
|
-
new RateLimiterFactory_1.RateLimiterFactory({ policy: 'fixed_window', id: 'limit1', limit: 10, interval: '60 seconds' }, storage),
|
|
131
|
-
new RateLimiterFactory_1.RateLimiterFactory({ policy: 'fixed_window', id: 'limit2', limit: 5, interval: '60 seconds' }, storage),
|
|
132
|
-
];
|
|
133
|
-
const compound = new CompoundRateLimiterFactory_1.CompoundRateLimiterFactory(factories);
|
|
134
|
-
const limiter1 = compound.create('user1');
|
|
135
|
-
const limiter2 = compound.create('user2');
|
|
136
|
-
const limiter3 = compound.create('user3');
|
|
137
|
-
// Exhaust user1's limits
|
|
138
|
-
await limiter1.consume(5);
|
|
139
|
-
// user2 and user3 should have full capacity
|
|
140
|
-
const r2 = await limiter2.consume(1);
|
|
141
|
-
const r3 = await limiter3.consume(1);
|
|
142
|
-
expect(r2.isAccepted()).toBe(true);
|
|
143
|
-
expect(r3.isAccepted()).toBe(true);
|
|
144
|
-
});
|
|
145
|
-
});
|
|
146
|
-
describe('no limit policy in compound', () => {
|
|
147
|
-
it('should work with no_limit policy', async () => {
|
|
148
|
-
const factories = [
|
|
149
|
-
new RateLimiterFactory_1.RateLimiterFactory({ policy: 'no_limit', id: 'unlimited' }, storage),
|
|
150
|
-
new RateLimiterFactory_1.RateLimiterFactory({ policy: 'fixed_window', id: 'limited', limit: 10, interval: '60 seconds' }, storage),
|
|
151
|
-
];
|
|
152
|
-
const compound = new CompoundRateLimiterFactory_1.CompoundRateLimiterFactory(factories);
|
|
153
|
-
const limiter = compound.create();
|
|
154
|
-
const result = await limiter.consume(5);
|
|
155
|
-
expect(result.isAccepted()).toBe(true);
|
|
156
|
-
expect(result.getRemainingTokens()).toBe(5); // Limited by fixed_window
|
|
157
|
-
});
|
|
158
|
-
});
|
|
159
|
-
describe('factory reuse', () => {
|
|
160
|
-
it('should allow creating multiple compound limiters from same factory instance', async () => {
|
|
161
|
-
const factories = [
|
|
162
|
-
new RateLimiterFactory_1.RateLimiterFactory({ policy: 'fixed_window', id: 'api', limit: 10, interval: '60 seconds' }, storage),
|
|
163
|
-
];
|
|
164
|
-
const compound = new CompoundRateLimiterFactory_1.CompoundRateLimiterFactory(factories);
|
|
165
|
-
const limiter1 = compound.create('user1');
|
|
166
|
-
const limiter2 = compound.create('user2');
|
|
167
|
-
const limiter3 = compound.create('user3');
|
|
168
|
-
await limiter1.consume(10);
|
|
169
|
-
await limiter2.consume(5);
|
|
170
|
-
const r1 = await limiter1.consume(1);
|
|
171
|
-
const r2 = await limiter2.consume(1);
|
|
172
|
-
const r3 = await limiter3.consume(1);
|
|
173
|
-
expect(r1.isAccepted()).toBe(false);
|
|
174
|
-
expect(r2.isAccepted()).toBe(true);
|
|
175
|
-
expect(r3.isAccepted()).toBe(true);
|
|
176
|
-
});
|
|
177
|
-
});
|
|
178
|
-
describe('edge cases', () => {
|
|
179
|
-
it('should handle single factory', async () => {
|
|
180
|
-
const factory = new RateLimiterFactory_1.RateLimiterFactory({ policy: 'fixed_window', id: 'test', limit: 10, interval: '60 seconds' }, storage);
|
|
181
|
-
const compound = new CompoundRateLimiterFactory_1.CompoundRateLimiterFactory([factory]);
|
|
182
|
-
const limiter = compound.create();
|
|
183
|
-
const result = await limiter.consume(5);
|
|
184
|
-
expect(result.isAccepted()).toBe(true);
|
|
185
|
-
});
|
|
186
|
-
it('should handle many factories', async () => {
|
|
187
|
-
const factories = Array(5).fill(null).map((_, i) => new RateLimiterFactory_1.RateLimiterFactory({ policy: 'fixed_window', id: `limit${i}`, limit: 100, interval: '60 seconds' }, storage));
|
|
188
|
-
const compound = new CompoundRateLimiterFactory_1.CompoundRateLimiterFactory(factories);
|
|
189
|
-
const limiter = compound.create();
|
|
190
|
-
const result = await limiter.consume(10);
|
|
191
|
-
expect(result.isAccepted()).toBe(true);
|
|
192
|
-
});
|
|
193
|
-
});
|
|
194
|
-
describe('real-world scenarios', () => {
|
|
195
|
-
it('should implement per-second and per-minute limits', async () => {
|
|
196
|
-
const factories = [
|
|
197
|
-
new RateLimiterFactory_1.RateLimiterFactory({ policy: 'token_bucket', id: 'per-second', limit: 10, rate: { interval: '1 second', amount: 10 } }, storage),
|
|
198
|
-
new RateLimiterFactory_1.RateLimiterFactory({ policy: 'fixed_window', id: 'per-minute', limit: 100, interval: '60 seconds' }, storage),
|
|
199
|
-
];
|
|
200
|
-
const compound = new CompoundRateLimiterFactory_1.CompoundRateLimiterFactory(factories);
|
|
201
|
-
const limiter = compound.create('api-key-123');
|
|
202
|
-
// Burst up to per-second limit
|
|
203
|
-
for (let i = 0; i < 10; i++) {
|
|
204
|
-
const result = await limiter.consume(1);
|
|
205
|
-
expect(result.isAccepted()).toBe(true);
|
|
206
|
-
}
|
|
207
|
-
// Should be rate limited
|
|
208
|
-
const result = await limiter.consume(1);
|
|
209
|
-
expect(result.isAccepted()).toBe(false);
|
|
210
|
-
});
|
|
211
|
-
});
|
|
212
|
-
});
|
|
213
|
-
//# sourceMappingURL=CompoundRateLimiterFactory.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"CompoundRateLimiterFactory.test.js","sourceRoot":"","sources":["../../src/__tests__/CompoundRateLimiterFactory.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"RateLimit.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/RateLimit.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const RateLimit_1 = require("../RateLimit");
|
|
4
|
-
const RateLimitExceededError_1 = require("../errors/RateLimitExceededError");
|
|
5
|
-
describe('RateLimit', () => {
|
|
6
|
-
describe('constructor', () => {
|
|
7
|
-
it('should create a RateLimit instance with correct values', () => {
|
|
8
|
-
const retryAfter = new Date(Date.now() + 5000);
|
|
9
|
-
const rateLimit = new RateLimit_1.RateLimit(5, retryAfter, true, 10);
|
|
10
|
-
expect(rateLimit.getRemainingTokens()).toBe(5);
|
|
11
|
-
expect(rateLimit.getRetryAfter()).toBe(retryAfter);
|
|
12
|
-
expect(rateLimit.isAccepted()).toBe(true);
|
|
13
|
-
expect(rateLimit.getLimit()).toBe(10);
|
|
14
|
-
});
|
|
15
|
-
it('should handle zero remaining tokens', () => {
|
|
16
|
-
const retryAfter = new Date();
|
|
17
|
-
const rateLimit = new RateLimit_1.RateLimit(0, retryAfter, false, 10);
|
|
18
|
-
expect(rateLimit.getRemainingTokens()).toBe(0);
|
|
19
|
-
expect(rateLimit.isAccepted()).toBe(false);
|
|
20
|
-
});
|
|
21
|
-
});
|
|
22
|
-
describe('ensureAccepted', () => {
|
|
23
|
-
it('should return this when accepted', () => {
|
|
24
|
-
const rateLimit = new RateLimit_1.RateLimit(5, new Date(), true, 10);
|
|
25
|
-
expect(rateLimit.ensureAccepted()).toBe(rateLimit);
|
|
26
|
-
});
|
|
27
|
-
it('should throw RateLimitExceededError when rejected', () => {
|
|
28
|
-
const retryAfter = new Date();
|
|
29
|
-
const rateLimit = new RateLimit_1.RateLimit(0, retryAfter, false, 10);
|
|
30
|
-
expect(() => rateLimit.ensureAccepted()).toThrow(RateLimitExceededError_1.RateLimitExceededError);
|
|
31
|
-
});
|
|
32
|
-
it('should throw error with correct RateLimit object', () => {
|
|
33
|
-
const retryAfter = new Date();
|
|
34
|
-
const rateLimit = new RateLimit_1.RateLimit(0, retryAfter, false, 10);
|
|
35
|
-
try {
|
|
36
|
-
rateLimit.ensureAccepted();
|
|
37
|
-
fail('Should have thrown');
|
|
38
|
-
}
|
|
39
|
-
catch (e) {
|
|
40
|
-
expect(e).toBeInstanceOf(RateLimitExceededError_1.RateLimitExceededError);
|
|
41
|
-
expect(e.getRateLimit()).toBe(rateLimit);
|
|
42
|
-
}
|
|
43
|
-
});
|
|
44
|
-
it('should allow chaining on success', () => {
|
|
45
|
-
const rateLimit = new RateLimit_1.RateLimit(5, new Date(), true, 10);
|
|
46
|
-
expect(() => {
|
|
47
|
-
rateLimit.ensureAccepted().ensureAccepted();
|
|
48
|
-
}).not.toThrow();
|
|
49
|
-
});
|
|
50
|
-
});
|
|
51
|
-
describe('getRetryAfter', () => {
|
|
52
|
-
it('should return the retry date', () => {
|
|
53
|
-
const retryAfter = new Date(Date.now() + 10000);
|
|
54
|
-
const rateLimit = new RateLimit_1.RateLimit(0, retryAfter, false, 10);
|
|
55
|
-
expect(rateLimit.getRetryAfter()).toBe(retryAfter);
|
|
56
|
-
});
|
|
57
|
-
});
|
|
58
|
-
describe('getRemainingTokens', () => {
|
|
59
|
-
it('should return correct remaining tokens including zero', () => {
|
|
60
|
-
const rl1 = new RateLimit_1.RateLimit(7, new Date(), true, 10);
|
|
61
|
-
const rl2 = new RateLimit_1.RateLimit(0, new Date(), false, 10);
|
|
62
|
-
expect(rl1.getRemainingTokens()).toBe(7);
|
|
63
|
-
expect(rl2.getRemainingTokens()).toBe(0);
|
|
64
|
-
});
|
|
65
|
-
});
|
|
66
|
-
describe('getLimit', () => {
|
|
67
|
-
it('should return the rate limit maximum', () => {
|
|
68
|
-
const rateLimit = new RateLimit_1.RateLimit(5, new Date(), true, 10);
|
|
69
|
-
expect(rateLimit.getLimit()).toBe(10);
|
|
70
|
-
});
|
|
71
|
-
});
|
|
72
|
-
describe('wait', () => {
|
|
73
|
-
it('should resolve immediately when retry time is in the past', async () => {
|
|
74
|
-
const retryAfter = new Date(Date.now() - 1000);
|
|
75
|
-
const rateLimit = new RateLimit_1.RateLimit(5, retryAfter, true, 10);
|
|
76
|
-
const start = Date.now();
|
|
77
|
-
await rateLimit.wait();
|
|
78
|
-
const elapsed = Date.now() - start;
|
|
79
|
-
expect(elapsed).toBeLessThan(100); // Should be nearly instant
|
|
80
|
-
});
|
|
81
|
-
it('should wait until retry time', async () => {
|
|
82
|
-
const retryAfter = new Date(Date.now() + 100);
|
|
83
|
-
const rateLimit = new RateLimit_1.RateLimit(0, retryAfter, false, 10);
|
|
84
|
-
const start = Date.now();
|
|
85
|
-
await rateLimit.wait();
|
|
86
|
-
const elapsed = Date.now() - start;
|
|
87
|
-
expect(elapsed).toBeGreaterThanOrEqual(90);
|
|
88
|
-
expect(elapsed).toBeLessThan(200);
|
|
89
|
-
});
|
|
90
|
-
it('should work when retry time is now', async () => {
|
|
91
|
-
const retryAfter = new Date();
|
|
92
|
-
const rateLimit = new RateLimit_1.RateLimit(5, retryAfter, true, 10);
|
|
93
|
-
const start = Date.now();
|
|
94
|
-
await rateLimit.wait();
|
|
95
|
-
const elapsed = Date.now() - start;
|
|
96
|
-
expect(elapsed).toBeLessThan(100);
|
|
97
|
-
});
|
|
98
|
-
});
|
|
99
|
-
describe('usage patterns', () => {
|
|
100
|
-
it('should support throw-on-reject pattern', () => {
|
|
101
|
-
const accepted = new RateLimit_1.RateLimit(5, new Date(), true, 10);
|
|
102
|
-
const rejected = new RateLimit_1.RateLimit(0, new Date(Date.now() + 1000), false, 10);
|
|
103
|
-
expect(() => accepted.ensureAccepted()).not.toThrow();
|
|
104
|
-
expect(() => rejected.ensureAccepted()).toThrow();
|
|
105
|
-
});
|
|
106
|
-
});
|
|
107
|
-
});
|
|
108
|
-
//# sourceMappingURL=RateLimit.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"RateLimit.test.js","sourceRoot":"","sources":["../../src/__tests__/RateLimit.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"RateLimiterFactory.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/RateLimiterFactory.test.ts"],"names":[],"mappings":""}
|