@zeitar/throttle 1.0.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/LICENSE.md +24 -0
- package/README.md +204 -0
- package/dist/CompoundLimiter.d.ts +33 -0
- package/dist/CompoundLimiter.d.ts.map +1 -0
- package/dist/CompoundLimiter.js +62 -0
- package/dist/CompoundLimiter.js.map +1 -0
- package/dist/CompoundRateLimiterFactory.d.ts +19 -0
- package/dist/CompoundRateLimiterFactory.d.ts.map +1 -0
- package/dist/CompoundRateLimiterFactory.js +29 -0
- package/dist/CompoundRateLimiterFactory.js.map +1 -0
- package/dist/LimiterInterface.d.ts +32 -0
- package/dist/LimiterInterface.d.ts.map +1 -0
- package/dist/LimiterInterface.js +3 -0
- package/dist/LimiterInterface.js.map +1 -0
- package/dist/LimiterStateInterface.d.ts +16 -0
- package/dist/LimiterStateInterface.d.ts.map +1 -0
- package/dist/LimiterStateInterface.js +3 -0
- package/dist/LimiterStateInterface.js.map +1 -0
- package/dist/RateLimit.d.ts +43 -0
- package/dist/RateLimit.d.ts.map +1 -0
- package/dist/RateLimit.js +68 -0
- package/dist/RateLimit.js.map +1 -0
- package/dist/RateLimiterFactory.d.ts +83 -0
- package/dist/RateLimiterFactory.d.ts.map +1 -0
- package/dist/RateLimiterFactory.js +115 -0
- package/dist/RateLimiterFactory.js.map +1 -0
- package/dist/RateLimiterFactoryInterface.d.ts +17 -0
- package/dist/RateLimiterFactoryInterface.d.ts.map +1 -0
- package/dist/RateLimiterFactoryInterface.js +3 -0
- package/dist/RateLimiterFactoryInterface.js.map +1 -0
- package/dist/Reservation.d.ts +29 -0
- package/dist/Reservation.d.ts.map +1 -0
- package/dist/Reservation.js +44 -0
- package/dist/Reservation.js.map +1 -0
- package/dist/__tests__/CompoundLimiter.test.d.ts +2 -0
- package/dist/__tests__/CompoundLimiter.test.d.ts.map +1 -0
- package/dist/__tests__/CompoundLimiter.test.js +231 -0
- package/dist/__tests__/CompoundLimiter.test.js.map +1 -0
- package/dist/__tests__/CompoundRateLimiterFactory.test.d.ts +2 -0
- package/dist/__tests__/CompoundRateLimiterFactory.test.d.ts.map +1 -0
- package/dist/__tests__/CompoundRateLimiterFactory.test.js +213 -0
- package/dist/__tests__/CompoundRateLimiterFactory.test.js.map +1 -0
- package/dist/__tests__/RateLimit.test.d.ts +2 -0
- package/dist/__tests__/RateLimit.test.d.ts.map +1 -0
- package/dist/__tests__/RateLimit.test.js +108 -0
- package/dist/__tests__/RateLimit.test.js.map +1 -0
- package/dist/__tests__/RateLimiterFactory.test.d.ts +2 -0
- package/dist/__tests__/RateLimiterFactory.test.d.ts.map +1 -0
- package/dist/__tests__/RateLimiterFactory.test.js +323 -0
- package/dist/__tests__/RateLimiterFactory.test.js.map +1 -0
- package/dist/__tests__/Reservation.test.d.ts +2 -0
- package/dist/__tests__/Reservation.test.d.ts.map +1 -0
- package/dist/__tests__/Reservation.test.js +110 -0
- package/dist/__tests__/Reservation.test.js.map +1 -0
- package/dist/errors/InvalidIntervalError.d.ts +10 -0
- package/dist/errors/InvalidIntervalError.d.ts.map +1 -0
- package/dist/errors/InvalidIntervalError.js +18 -0
- package/dist/errors/InvalidIntervalError.js.map +1 -0
- package/dist/errors/MaxWaitDurationExceededError.d.ts +15 -0
- package/dist/errors/MaxWaitDurationExceededError.d.ts.map +1 -0
- package/dist/errors/MaxWaitDurationExceededError.js +24 -0
- package/dist/errors/MaxWaitDurationExceededError.js.map +1 -0
- package/dist/errors/RateLimitExceededError.d.ts +27 -0
- package/dist/errors/RateLimitExceededError.d.ts.map +1 -0
- package/dist/errors/RateLimitExceededError.js +42 -0
- package/dist/errors/RateLimitExceededError.js.map +1 -0
- package/dist/errors/ReserveNotSupportedError.d.ts +10 -0
- package/dist/errors/ReserveNotSupportedError.d.ts.map +1 -0
- package/dist/errors/ReserveNotSupportedError.js +18 -0
- package/dist/errors/ReserveNotSupportedError.js.map +1 -0
- package/dist/index.d.ts +35 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +58 -0
- package/dist/index.js.map +1 -0
- package/dist/policy/FixedWindowLimiter.d.ts +36 -0
- package/dist/policy/FixedWindowLimiter.d.ts.map +1 -0
- package/dist/policy/FixedWindowLimiter.js +105 -0
- package/dist/policy/FixedWindowLimiter.js.map +1 -0
- package/dist/policy/NoLimiter.d.ts +23 -0
- package/dist/policy/NoLimiter.d.ts.map +1 -0
- package/dist/policy/NoLimiter.js +34 -0
- package/dist/policy/NoLimiter.js.map +1 -0
- package/dist/policy/Rate.d.ts +69 -0
- package/dist/policy/Rate.d.ts.map +1 -0
- package/dist/policy/Rate.js +121 -0
- package/dist/policy/Rate.js.map +1 -0
- package/dist/policy/SlidingWindow.d.ts +74 -0
- package/dist/policy/SlidingWindow.d.ts.map +1 -0
- package/dist/policy/SlidingWindow.js +130 -0
- package/dist/policy/SlidingWindow.js.map +1 -0
- package/dist/policy/SlidingWindowLimiter.d.ts +41 -0
- package/dist/policy/SlidingWindowLimiter.d.ts.map +1 -0
- package/dist/policy/SlidingWindowLimiter.js +127 -0
- package/dist/policy/SlidingWindowLimiter.js.map +1 -0
- package/dist/policy/TokenBucket.d.ts +63 -0
- package/dist/policy/TokenBucket.d.ts.map +1 -0
- package/dist/policy/TokenBucket.js +92 -0
- package/dist/policy/TokenBucket.js.map +1 -0
- package/dist/policy/TokenBucketLimiter.d.ts +38 -0
- package/dist/policy/TokenBucketLimiter.d.ts.map +1 -0
- package/dist/policy/TokenBucketLimiter.js +114 -0
- package/dist/policy/TokenBucketLimiter.js.map +1 -0
- package/dist/policy/Window.d.ts +58 -0
- package/dist/policy/Window.d.ts.map +1 -0
- package/dist/policy/Window.js +105 -0
- package/dist/policy/Window.js.map +1 -0
- package/dist/policy/__tests__/FixedWindowLimiter.test.d.ts +2 -0
- package/dist/policy/__tests__/FixedWindowLimiter.test.d.ts.map +1 -0
- package/dist/policy/__tests__/FixedWindowLimiter.test.js +180 -0
- package/dist/policy/__tests__/FixedWindowLimiter.test.js.map +1 -0
- package/dist/policy/__tests__/NoLimiter.test.d.ts +2 -0
- package/dist/policy/__tests__/NoLimiter.test.d.ts.map +1 -0
- package/dist/policy/__tests__/NoLimiter.test.js +40 -0
- package/dist/policy/__tests__/NoLimiter.test.js.map +1 -0
- package/dist/policy/__tests__/Rate.test.d.ts +2 -0
- package/dist/policy/__tests__/Rate.test.d.ts.map +1 -0
- package/dist/policy/__tests__/Rate.test.js +162 -0
- package/dist/policy/__tests__/Rate.test.js.map +1 -0
- package/dist/policy/__tests__/SlidingWindow.test.d.ts +2 -0
- package/dist/policy/__tests__/SlidingWindow.test.d.ts.map +1 -0
- package/dist/policy/__tests__/SlidingWindow.test.js +257 -0
- package/dist/policy/__tests__/SlidingWindow.test.js.map +1 -0
- package/dist/policy/__tests__/SlidingWindowLimiter.test.d.ts +2 -0
- package/dist/policy/__tests__/SlidingWindowLimiter.test.d.ts.map +1 -0
- package/dist/policy/__tests__/SlidingWindowLimiter.test.js +201 -0
- package/dist/policy/__tests__/SlidingWindowLimiter.test.js.map +1 -0
- package/dist/policy/__tests__/TokenBucket.test.d.ts +2 -0
- package/dist/policy/__tests__/TokenBucket.test.d.ts.map +1 -0
- package/dist/policy/__tests__/TokenBucket.test.js +171 -0
- package/dist/policy/__tests__/TokenBucket.test.js.map +1 -0
- package/dist/policy/__tests__/TokenBucketLimiter.test.d.ts +2 -0
- package/dist/policy/__tests__/TokenBucketLimiter.test.d.ts.map +1 -0
- package/dist/policy/__tests__/TokenBucketLimiter.test.js +175 -0
- package/dist/policy/__tests__/TokenBucketLimiter.test.js.map +1 -0
- package/dist/policy/__tests__/Window.test.d.ts +2 -0
- package/dist/policy/__tests__/Window.test.d.ts.map +1 -0
- package/dist/policy/__tests__/Window.test.js +193 -0
- package/dist/policy/__tests__/Window.test.js.map +1 -0
- package/dist/storage/InMemoryStorage.d.ts +34 -0
- package/dist/storage/InMemoryStorage.d.ts.map +1 -0
- package/dist/storage/InMemoryStorage.js +62 -0
- package/dist/storage/InMemoryStorage.js.map +1 -0
- package/dist/storage/LockInterface.d.ts +41 -0
- package/dist/storage/LockInterface.d.ts.map +1 -0
- package/dist/storage/LockInterface.js +19 -0
- package/dist/storage/LockInterface.js.map +1 -0
- package/dist/storage/StorageInterface.d.ts +29 -0
- package/dist/storage/StorageInterface.d.ts.map +1 -0
- package/dist/storage/StorageInterface.js +3 -0
- package/dist/storage/StorageInterface.js.map +1 -0
- package/dist/storage/__tests__/InMemoryStorage.test.d.ts +2 -0
- package/dist/storage/__tests__/InMemoryStorage.test.d.ts.map +1 -0
- package/dist/storage/__tests__/InMemoryStorage.test.js +154 -0
- package/dist/storage/__tests__/InMemoryStorage.test.js.map +1 -0
- package/dist/util/TimeUtil.d.ts +35 -0
- package/dist/util/TimeUtil.d.ts.map +1 -0
- package/dist/util/TimeUtil.js +87 -0
- package/dist/util/TimeUtil.js.map +1 -0
- package/dist/util/__tests__/TimeUtil.test.d.ts +2 -0
- package/dist/util/__tests__/TimeUtil.test.d.ts.map +1 -0
- package/dist/util/__tests__/TimeUtil.test.js +132 -0
- package/dist/util/__tests__/TimeUtil.test.js.map +1 -0
- package/package.json +59 -0
|
@@ -0,0 +1,213 @@
|
|
|
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
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CompoundRateLimiterFactory.test.js","sourceRoot":"","sources":["../../src/__tests__/CompoundRateLimiterFactory.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RateLimit.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/RateLimit.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,108 @@
|
|
|
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
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RateLimit.test.js","sourceRoot":"","sources":["../../src/__tests__/RateLimit.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RateLimiterFactory.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/RateLimiterFactory.test.ts"],"names":[],"mappings":""}
|