ttc-rate-limit 0.1.0 → 0.1.2
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 +83 -145
- package/dist/cluster.js +51 -47
- package/dist/cluster.js.map +1 -1
- package/dist/index.js +9 -3
- package/dist/index.js.map +1 -1
- package/dist/ratelimit.js +15 -13
- package/dist/ratelimit.js.map +1 -1
- package/dist/test.js +5 -3
- package/dist/test.js.map +1 -1
- package/dist/time.js +17 -12
- package/dist/time.js.map +1 -1
- package/package.json +9 -3
- package/dist/cluster.d.ts +0 -19
- package/dist/cluster.d.ts.map +0 -1
- package/dist/index.d.ts +0 -4
- package/dist/index.d.ts.map +0 -1
- package/dist/ratelimit.d.ts +0 -43
- package/dist/ratelimit.d.ts.map +0 -1
- package/dist/test.d.ts +0 -2
- package/dist/test.d.ts.map +0 -1
- package/dist/time.d.ts +0 -11
- package/dist/time.d.ts.map +0 -1
package/README.md
CHANGED
|
@@ -1,6 +1,16 @@
|
|
|
1
1
|
# ttc_rate_limit
|
|
2
2
|
|
|
3
|
-
A rate limiting library with worker pool support for parallel timeout management.
|
|
3
|
+
A rate limiting library with worker pool support for parallel timeout management and multi-provider LLM routing.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Core Rate Limiting**: Token bucket and sliding window algorithms via `RateLimiter`
|
|
8
|
+
- **Time Clustering**: Group time-sensitive requests with `TimeCluster`
|
|
9
|
+
- **Cluster Management**: Coordinate multiple rate limiters with `Cluster`
|
|
10
|
+
- **Multi-Provider LLM Provisioning**: Route requests across 6 providers (OpenAI, Grok, Minimax, Kimi, DeepSeek, Anthropic)
|
|
11
|
+
- **7 Routing Strategies**: Random, round-robin, failover, load-balance, cost-optimized, latency-optimal, priority
|
|
12
|
+
- **Built-in Rate Limiting**: Each provider can have its own rate limits configured
|
|
13
|
+
- **Provider Metrics**: Track requests, latency, and success rates per provider
|
|
4
14
|
|
|
5
15
|
## Installation
|
|
6
16
|
|
|
@@ -8,14 +18,6 @@ A rate limiting library with worker pool support for parallel timeout management
|
|
|
8
18
|
npm install ttc_rate_limit
|
|
9
19
|
```
|
|
10
20
|
|
|
11
|
-
## Features
|
|
12
|
-
|
|
13
|
-
- **Rate Limiting**: Configurable rate limits per second, minute, hour, or day
|
|
14
|
-
- **Worker Pool Support**: Parallel timeout management using worker threads
|
|
15
|
-
- **Multiple Strategies**: Spread and burst modes for different use cases
|
|
16
|
-
- **Cluster Support**: Distribute rate limiting across multiple limiters
|
|
17
|
-
- **Event-Driven**: Listen for completion and error events
|
|
18
|
-
|
|
19
21
|
## Usage
|
|
20
22
|
|
|
21
23
|
### Single Rate Limiter
|
|
@@ -28,166 +30,102 @@ const apiLimiter = new RateLimiter({
|
|
|
28
30
|
id: 'api-limiter',
|
|
29
31
|
request: 100, // 100 requests
|
|
30
32
|
per: 'minute', // per minute
|
|
31
|
-
mode: 'spread', //
|
|
32
|
-
cb: async (
|
|
33
|
-
// Your
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
body: JSON.stringify(data)
|
|
37
|
-
});
|
|
38
|
-
return await response.json();
|
|
39
|
-
}
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
// Listen for completed requests
|
|
43
|
-
apiLimiter.on('completed', (data) => {
|
|
44
|
-
console.log('Request completed:', data.response);
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
// Listen for errors
|
|
48
|
-
apiLimiter.on('error', (data) => {
|
|
49
|
-
console.error('Request failed:', data.response);
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
// Make requests through the limiter
|
|
53
|
-
for (let i = 0; i < 150; i++) {
|
|
54
|
-
const result = await apiLimiter.invoke({
|
|
55
|
-
userId: 'user123',
|
|
56
|
-
action: `action-${i}`
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
// Result can be: { status: 'success' }, { status: 'queued' }, or { status: 'error', message: string }
|
|
60
|
-
console.log(`Request ${i}: ${result.status}`);
|
|
61
|
-
}
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
### Burst Mode Example
|
|
65
|
-
|
|
66
|
-
```typescript
|
|
67
|
-
import { RateLimiter } from 'ttc_rate_limit';
|
|
68
|
-
|
|
69
|
-
// Create a burst mode limiter for batch processing
|
|
70
|
-
const burstLimiter = new RateLimiter({
|
|
71
|
-
id: 'batch-processor',
|
|
72
|
-
request: 50, // 50 requests
|
|
73
|
-
per: 'second', // per second
|
|
74
|
-
mode: 'burst', // allow bursts up to limit
|
|
75
|
-
cb: async (batch) => {
|
|
76
|
-
// Process batch of data
|
|
77
|
-
return await processBatch(batch);
|
|
78
|
-
}
|
|
33
|
+
mode: 'spread', // spread evenly
|
|
34
|
+
cb: async (params) => {
|
|
35
|
+
// Your API call here
|
|
36
|
+
return await fetch('https://api.example.com', params);
|
|
37
|
+
},
|
|
79
38
|
});
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
### Time Cluster (Worker Pool)
|
|
83
|
-
|
|
84
|
-
```typescript
|
|
85
|
-
import { TimeCluster } from 'ttc_rate_limit';
|
|
86
|
-
|
|
87
|
-
// Create a time cluster with intervals
|
|
88
|
-
const timeCluster = new TimeCluster(20); // 20 intervals
|
|
89
39
|
|
|
90
|
-
//
|
|
91
|
-
await
|
|
92
|
-
console.log('Executed after 2.5 seconds');
|
|
93
|
-
}, 2.5); // 2.5 seconds timeout
|
|
40
|
+
// Make a request (automatically rate-limited)
|
|
41
|
+
const result = await apiLimiter.invoke({ url: '/api/data' });
|
|
94
42
|
```
|
|
95
43
|
|
|
96
|
-
###
|
|
44
|
+
### Multi-Provider LLM Provisioning
|
|
97
45
|
|
|
98
46
|
```typescript
|
|
99
|
-
import {
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
cb: async (input) => {
|
|
116
|
-
return `Processed by Model A: ${input.modelId} - ${input.chatId}`;
|
|
117
|
-
}
|
|
118
|
-
}, true); // true = add immediately
|
|
119
|
-
|
|
120
|
-
cluster.addOption({
|
|
121
|
-
id: 'model-b',
|
|
122
|
-
request: 200,
|
|
123
|
-
per: 'minute',
|
|
124
|
-
mode: 'burst',
|
|
125
|
-
cb: async (input) => {
|
|
126
|
-
return `Processed by Model B: ${input.modelId} - ${input.chatId}`;
|
|
127
|
-
}
|
|
128
|
-
}, true);
|
|
129
|
-
|
|
130
|
-
// Listen to cluster events
|
|
131
|
-
cluster.on('completed', (data) => {
|
|
132
|
-
console.log('Cluster completed:', data.response);
|
|
47
|
+
import { LLMProvisioner } from 'ttc_rate_limit/llm';
|
|
48
|
+
|
|
49
|
+
const provisioner = new LLMProvisioner({
|
|
50
|
+
providers: new Map([
|
|
51
|
+
['openai', {
|
|
52
|
+
apiKey: process.env.OPENAI_API_KEY!,
|
|
53
|
+
model: 'gpt-4',
|
|
54
|
+
rateLimit: { requests: 60, per: 60000 },
|
|
55
|
+
}],
|
|
56
|
+
['deepseek', {
|
|
57
|
+
apiKey: process.env.DEEPSEEK_API_KEY!,
|
|
58
|
+
model: 'deepseek-chat',
|
|
59
|
+
rateLimit: { requests: 1000, per: 60000 },
|
|
60
|
+
}],
|
|
61
|
+
]),
|
|
62
|
+
defaultStrategy: 'latency-optimal',
|
|
133
63
|
});
|
|
134
64
|
|
|
135
|
-
|
|
136
|
-
|
|
65
|
+
const response = await provisioner.complete({
|
|
66
|
+
messages: [{ role: 'user', content: 'Hello!' }],
|
|
137
67
|
});
|
|
138
68
|
|
|
139
|
-
|
|
140
|
-
for (let i = 0; i < 500; i++) {
|
|
141
|
-
await cluster.invoke({
|
|
142
|
-
modelId: 'gpt-4',
|
|
143
|
-
chatId: `chat-${i}`,
|
|
144
|
-
});
|
|
145
|
-
}
|
|
69
|
+
console.log(response.content);
|
|
146
70
|
```
|
|
147
71
|
|
|
148
|
-
##
|
|
72
|
+
## Supported LLM Providers
|
|
149
73
|
|
|
150
|
-
|
|
74
|
+
| Provider | Endpoint | API Compatibility |
|
|
75
|
+
|----------|----------|-------------------|
|
|
76
|
+
| OpenAI | api.openai.com/v1 | Native |
|
|
77
|
+
| Grok | api.x.ai/v1 | OpenAI-compatible |
|
|
78
|
+
| Minimax | api.minimax.chat/v1 | OpenAI-compatible |
|
|
79
|
+
| Kimi | api.moonshot.ai/v1 | OpenAI-compatible |
|
|
80
|
+
| DeepSeek | api.deepseek.com/v1 | OpenAI-compatible |
|
|
81
|
+
| Anthropic | api.anthropic.com/v1 | Native SDK |
|
|
151
82
|
|
|
152
|
-
|
|
83
|
+
## Routing Strategies
|
|
153
84
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
85
|
+
| Strategy | Description |
|
|
86
|
+
|----------|-------------|
|
|
87
|
+
| `random` | Randomly select a provider |
|
|
88
|
+
| `round-robin` | Cycle through providers sequentially |
|
|
89
|
+
| `failover` | Try primary first, then fall back to alternatives |
|
|
90
|
+
| `load-balance` | Route to provider with lowest current load |
|
|
91
|
+
| `cost-optimized` | Prefer cheaper providers (DeepSeek → Anthropic) |
|
|
92
|
+
| `latency-optimal` | Prefer providers with best average response time |
|
|
93
|
+
| `priority` | Use configured priority order |
|
|
158
94
|
|
|
159
|
-
|
|
160
|
-
- `invoke(input: T): Promise<{ status: 'success' | 'error' | 'queued', message?: string }>` - Process a request
|
|
161
|
-
- `on(event: 'completed' | 'error', listener): void` - Listen for events
|
|
95
|
+
## API Reference
|
|
162
96
|
|
|
163
|
-
###
|
|
97
|
+
### LLMProvisioner
|
|
164
98
|
|
|
165
|
-
Worker pool for managing parallel timeouts with callback registry.
|
|
166
|
-
|
|
167
|
-
**Constructor:**
|
|
168
99
|
```typescript
|
|
169
|
-
|
|
100
|
+
class LLMProvisioner {
|
|
101
|
+
constructor(config: ProvisionerConfig)
|
|
102
|
+
|
|
103
|
+
// Make a completion request
|
|
104
|
+
complete(params: LLMCompletionParams, strategy?: ProvisioningStrategy): Promise<LLMResponse>
|
|
105
|
+
|
|
106
|
+
// Streaming completion
|
|
107
|
+
completeStream(params: LLMCompletionParams, onChunk: (chunk: string) => void): Promise<void>
|
|
108
|
+
|
|
109
|
+
// Add/remove providers dynamically
|
|
110
|
+
addProvider(type: ProviderType, config: ProviderConfig): void
|
|
111
|
+
removeProvider(type: ProviderType): boolean
|
|
112
|
+
|
|
113
|
+
// Strategy management
|
|
114
|
+
setStrategy(strategy: ProvisioningStrategy): void
|
|
115
|
+
getStrategy(): ProvisioningStrategy
|
|
116
|
+
|
|
117
|
+
// Metrics
|
|
118
|
+
getProviderStats(): ProviderStats[]
|
|
119
|
+
getMetrics(): Map<ProviderType, ProviderMetrics>
|
|
120
|
+
}
|
|
170
121
|
```
|
|
171
122
|
|
|
172
|
-
|
|
173
|
-
- `setTimeout(callback: () => void, delayMs: number): string` - Schedule timeout
|
|
174
|
-
- `clearTimeout(timeoutId: string): void` - Cancel timeout
|
|
175
|
-
- `waitFor(callback: () => Promise<void>, delaySeconds: number): Promise<void>` - Wait with async callback
|
|
123
|
+
## Building
|
|
176
124
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
Cluster of rate limiters for distributed rate limiting.
|
|
180
|
-
|
|
181
|
-
**Constructor:**
|
|
182
|
-
```typescript
|
|
183
|
-
new Cluster<T>(strategy: 'roundrobin')
|
|
125
|
+
```bash
|
|
126
|
+
npm run build
|
|
184
127
|
```
|
|
185
128
|
|
|
186
|
-
**Methods:**
|
|
187
|
-
- `addOption(config: RateLimiterConfig<T>, addImmediately: boolean): void` - Add rate limiter option
|
|
188
|
-
- `invoke(input: T): Promise<any>` - Distribute request to cluster
|
|
189
|
-
- `on(event: 'completed' | 'error', listener): void` - Listen for cluster events
|
|
190
|
-
|
|
191
129
|
## License
|
|
192
130
|
|
|
193
131
|
MIT
|
package/dist/cluster.js
CHANGED
|
@@ -1,54 +1,58 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Cluster = void 0;
|
|
4
|
+
const ratelimit_1 = require("./ratelimit");
|
|
5
|
+
const events_1 = require("events");
|
|
6
|
+
class Cluster {
|
|
7
7
|
constructor(type) {
|
|
8
|
-
this.config = {
|
|
9
|
-
|
|
8
|
+
this.config = { type: 'random' };
|
|
9
|
+
this.emitter = new events_1.EventEmitter();
|
|
10
|
+
this.limiters = [];
|
|
11
|
+
this.on = (event, listener) => {
|
|
12
|
+
this.emitter.on(event, listener);
|
|
10
13
|
};
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
invoke = async (item) => {
|
|
28
|
-
try {
|
|
29
|
-
let limiter;
|
|
30
|
-
if (this.config.type === 'random') {
|
|
31
|
-
limiter = this.randomLimiter();
|
|
32
|
-
}
|
|
33
|
-
else if (this.config.type === 'roundrobin') {
|
|
34
|
-
limiter = this.limiters.shift();
|
|
35
|
-
this.limiters.push(limiter);
|
|
36
|
-
}
|
|
37
|
-
else {
|
|
38
|
-
limiter = this.limiters.find(l => l.config.id === this.config.perferedLimiter);
|
|
39
|
-
if (!limiter) {
|
|
14
|
+
this.addOption = (config, specific = false) => {
|
|
15
|
+
const rl = new ratelimit_1.RateLimiter(config);
|
|
16
|
+
this.limiters.push(rl);
|
|
17
|
+
this.config.perferedLimiter = specific ? rl.config.id : this.config.perferedLimiter;
|
|
18
|
+
rl.on('error', async (data) => {
|
|
19
|
+
this.emitter.emit('error', data);
|
|
20
|
+
});
|
|
21
|
+
rl.on('completed', async (data) => {
|
|
22
|
+
this.emitter.emit('completed', data);
|
|
23
|
+
});
|
|
24
|
+
return this;
|
|
25
|
+
};
|
|
26
|
+
this.invoke = async (item) => {
|
|
27
|
+
try {
|
|
28
|
+
let limiter;
|
|
29
|
+
if (this.config.type === 'random') {
|
|
40
30
|
limiter = this.randomLimiter();
|
|
41
31
|
}
|
|
32
|
+
else if (this.config.type === 'roundrobin') {
|
|
33
|
+
limiter = this.limiters.shift();
|
|
34
|
+
this.limiters.push(limiter);
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
limiter = this.limiters.find(l => l.config.id === this.config.perferedLimiter);
|
|
38
|
+
if (!limiter) {
|
|
39
|
+
limiter = this.randomLimiter();
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
await limiter.invoke(item);
|
|
42
43
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
44
|
+
catch (error) {
|
|
45
|
+
throw error;
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
this.randomLimiter = () => {
|
|
49
|
+
const idx = Math.floor(Math.random() * this.limiters.length);
|
|
50
|
+
return this.limiters[idx];
|
|
51
|
+
};
|
|
52
|
+
this.config = {
|
|
53
|
+
type
|
|
54
|
+
};
|
|
55
|
+
}
|
|
53
56
|
}
|
|
57
|
+
exports.Cluster = Cluster;
|
|
54
58
|
//# sourceMappingURL=cluster.js.map
|
package/dist/cluster.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cluster.js","sourceRoot":"","sources":["../src/cluster.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"cluster.js","sourceRoot":"","sources":["../src/cluster.ts"],"names":[],"mappings":";;;AAAA,2CAA6D;AAC7D,mCAAsC;AAEtC,MAAa,OAAO;IAWhB,YAAY,IAA0C;QATtD,WAAM,GAGF,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;QAEvB,YAAO,GAAiB,IAAI,qBAAY,EAAE,CAAC;QAE3C,aAAQ,GAAwB,EAAE,CAAC;QAQnC,OAAE,GAAG,CAAC,KAA4B,EAAE,QAAqD,EAAE,EAAE;YACzF,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;QACrC,CAAC,CAAA;QAED,cAAS,GAAG,CAAC,MAA+B,EAAE,WAAoB,KAAK,EAAE,EAAE;YACvE,MAAM,EAAE,GAAG,IAAI,uBAAW,CAAO,MAAM,CAAC,CAAC;YACzC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACvB,IAAI,CAAC,MAAM,CAAC,eAAe,GAAG,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC;YACpF,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;gBAC1B,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;YACrC,CAAC,CAAC,CAAA;YACF,EAAE,CAAC,EAAE,CAAC,WAAW,EAAC,KAAK,EAAE,IAAI,EAAE,EAAE;gBAC7B,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;YACzC,CAAC,CAAC,CAAC;YACH,OAAO,IAAI,CAAC;QAChB,CAAC,CAAA;QAED,WAAM,GAAG,KAAK,EAAE,IAAO,EAAE,EAAE;YACxB,IAAI,CAAC;gBACH,IAAI,OAA0B,CAAC;gBAC/B,IAAG,IAAI,CAAC,MAAM,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;oBAC/B,OAAO,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;gBACnC,CAAC;qBAAM,IAAG,IAAI,CAAC,MAAM,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;oBAC1C,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAG,CAAC;oBACjC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;gBAChC,CAAC;qBAAM,CAAC;oBACJ,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,KAAK,IAAI,CAAC,MAAM,CAAC,eAAe,CAAQ,CAAC;oBACtF,IAAG,CAAC,OAAO,EAAE,CAAC;wBACX,OAAO,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;oBAClC,CAAC;gBACL,CAAC;gBAED,MAAM,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YAC7B,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACZ,MAAM,KAAK,CAAC;YACjB,CAAC;QACJ,CAAC,CAAA;QAED,kBAAa,GAAG,GAAsB,EAAE;YACpC,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;YAC7D,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;QAC9B,CAAC,CAAA;QA9CG,IAAI,CAAC,MAAM,GAAG;YACV,IAAI;SACP,CAAA;IACL,CAAC;CA4CJ;AA3DD,0BA2DC"}
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Cluster = exports.TimeCluster = exports.RateLimiter = void 0;
|
|
4
|
+
var ratelimit_1 = require("./ratelimit");
|
|
5
|
+
Object.defineProperty(exports, "RateLimiter", { enumerable: true, get: function () { return ratelimit_1.RateLimiter; } });
|
|
6
|
+
var time_1 = require("./time");
|
|
7
|
+
Object.defineProperty(exports, "TimeCluster", { enumerable: true, get: function () { return time_1.TimeCluster; } });
|
|
8
|
+
var cluster_1 = require("./cluster");
|
|
9
|
+
Object.defineProperty(exports, "Cluster", { enumerable: true, get: function () { return cluster_1.Cluster; } });
|
|
4
10
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,yCAAkF;AAAzE,wGAAA,WAAW,OAAA;AACpB,+BAAqC;AAA5B,mGAAA,WAAW,OAAA;AACpB,qCAAoC;AAA3B,kGAAA,OAAO,OAAA"}
|
package/dist/ratelimit.js
CHANGED
|
@@ -1,14 +1,18 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RateLimiter = exports.time = void 0;
|
|
4
|
+
const events_1 = require("events");
|
|
5
|
+
const time_1 = require("./time");
|
|
6
|
+
exports.time = new time_1.TimeCluster(20);
|
|
7
|
+
class RateLimiter {
|
|
8
8
|
constructor(config) {
|
|
9
|
+
this.queue = [];
|
|
10
|
+
this.on = (event, listener) => {
|
|
11
|
+
this.eventManager.on(event, listener);
|
|
12
|
+
};
|
|
9
13
|
this.config = config;
|
|
10
14
|
this._resolve();
|
|
11
|
-
this.eventManager = new EventEmitter();
|
|
15
|
+
this.eventManager = new events_1.EventEmitter();
|
|
12
16
|
}
|
|
13
17
|
_resolve() {
|
|
14
18
|
const intervals = {
|
|
@@ -23,9 +27,6 @@ export class RateLimiter {
|
|
|
23
27
|
this.config._count = 0;
|
|
24
28
|
console.log(this.config);
|
|
25
29
|
}
|
|
26
|
-
on = (event, listener) => {
|
|
27
|
-
this.eventManager.on(event, listener);
|
|
28
|
-
};
|
|
29
30
|
async processQueue() {
|
|
30
31
|
if (this.config.mode === 'spread') {
|
|
31
32
|
while (this.queue.length > 0 && this.config._count < this.config.rps) {
|
|
@@ -58,7 +59,7 @@ export class RateLimiter {
|
|
|
58
59
|
if (this.config._count < this.config.rps) {
|
|
59
60
|
this.config._count++;
|
|
60
61
|
if (this.config._count >= this.config.rps) {
|
|
61
|
-
await time.waitFor(async () => {
|
|
62
|
+
await exports.time.waitFor(async () => {
|
|
62
63
|
this.config._count = 0;
|
|
63
64
|
await this.processQueue();
|
|
64
65
|
}, this.config.interval);
|
|
@@ -117,7 +118,7 @@ export class RateLimiter {
|
|
|
117
118
|
// If this request hits the limit, schedule reset after remaining time
|
|
118
119
|
if (this.config._count === this.config.request && timeRemaining > 0) {
|
|
119
120
|
const waitSeconds = timeRemaining / 1000;
|
|
120
|
-
await time.waitFor(async () => {
|
|
121
|
+
await exports.time.waitFor(async () => {
|
|
121
122
|
this.config._count = 0;
|
|
122
123
|
await this.processQueue();
|
|
123
124
|
}, waitSeconds);
|
|
@@ -158,4 +159,5 @@ export class RateLimiter {
|
|
|
158
159
|
}
|
|
159
160
|
}
|
|
160
161
|
}
|
|
162
|
+
exports.RateLimiter = RateLimiter;
|
|
161
163
|
//# sourceMappingURL=ratelimit.js.map
|
package/dist/ratelimit.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ratelimit.js","sourceRoot":"","sources":["../src/ratelimit.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"ratelimit.js","sourceRoot":"","sources":["../src/ratelimit.ts"],"names":[],"mappings":"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"}
|
package/dist/test.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const cluster_1 = require("./cluster");
|
|
4
|
+
const cluster = new cluster_1.Cluster('roundrobin');
|
|
3
5
|
cluster.addOption({
|
|
4
6
|
id: 'deepseek',
|
|
5
7
|
request: 100,
|
|
@@ -16,7 +18,7 @@ cluster.on('error', (data) => {
|
|
|
16
18
|
console.error('Error processing:', data.request, 'Error:', data.response);
|
|
17
19
|
});
|
|
18
20
|
for (let i = 0; i < 500; i++) {
|
|
19
|
-
|
|
21
|
+
cluster.invoke({
|
|
20
22
|
modelId: 'gpt-4',
|
|
21
23
|
chatId: `chat-${i}`,
|
|
22
24
|
});
|
package/dist/test.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"test.js","sourceRoot":"","sources":["../src/test.ts"],"names":[],"mappings":"AACA,
|
|
1
|
+
{"version":3,"file":"test.js","sourceRoot":"","sources":["../src/test.ts"],"names":[],"mappings":";;AACA,uCAAoC;AAQpC,MAAM,OAAO,GAAG,IAAI,iBAAO,CAAe,YAAY,CAAC,CAAC;AAExD,OAAO,CAAC,SAAS,CAAC;IACd,EAAE,EAAE,UAAU;IACd,OAAO,EAAE,GAAG;IACZ,GAAG,EAAE,QAAQ;IACb,IAAI,EAAE,QAAQ;IACd,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;QAChB,OAAO,cAAc,KAAK,CAAC,OAAO,MAAM,KAAK,CAAC,MAAM,cAAc,CAAC;IACvE,CAAC;CACJ,EAAE,IAAI,CAAC,CAAC;AAET,OAAO,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,EAAE;IAC7B,OAAO,CAAC,GAAG,CAAC,YAAY,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;AAC7C,CAAC,CAAC,CAAC;AAEH,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;IACzB,OAAO,CAAC,KAAK,CAAC,mBAAmB,EAAE,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;AAC9E,CAAC,CAAC,CAAC;AAEH,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;IAC3B,OAAO,CAAC,MAAM,CAAC;QACX,OAAO,EAAE,OAAO;QAChB,MAAM,EAAE,QAAQ,CAAC,EAAE;KACtB,CAAC,CAAC;AACP,CAAC"}
|
package/dist/time.js
CHANGED
|
@@ -1,6 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TimeCluster = exports.Interval = void 0;
|
|
4
|
+
class Interval {
|
|
3
5
|
constructor() {
|
|
6
|
+
this.callbacks = [];
|
|
7
|
+
this.add = (cb, timeout) => {
|
|
8
|
+
const target = Date.now() + timeout * 1000;
|
|
9
|
+
this.callbacks.push({ cb, target });
|
|
10
|
+
};
|
|
4
11
|
setInterval(async () => {
|
|
5
12
|
const time = Date.now();
|
|
6
13
|
for (let i = this.callbacks.length - 1; i >= 0; i--) {
|
|
@@ -12,21 +19,19 @@ export class Interval {
|
|
|
12
19
|
}
|
|
13
20
|
}, 250);
|
|
14
21
|
}
|
|
15
|
-
add = (cb, timeout) => {
|
|
16
|
-
const target = Date.now() + timeout * 1000;
|
|
17
|
-
this.callbacks.push({ cb, target });
|
|
18
|
-
};
|
|
19
22
|
}
|
|
20
|
-
|
|
21
|
-
|
|
23
|
+
exports.Interval = Interval;
|
|
24
|
+
class TimeCluster {
|
|
22
25
|
constructor(size) {
|
|
26
|
+
this.intervals = new Array();
|
|
27
|
+
this.waitFor = (cb, timeout) => {
|
|
28
|
+
const interval = this.intervals[Math.floor(Math.random() * this.intervals.length)];
|
|
29
|
+
interval.add(cb, timeout);
|
|
30
|
+
};
|
|
23
31
|
for (let i = 0; i < size; i++) {
|
|
24
32
|
this.intervals.push(new Interval());
|
|
25
33
|
}
|
|
26
34
|
}
|
|
27
|
-
waitFor = (cb, timeout) => {
|
|
28
|
-
const interval = this.intervals[Math.floor(Math.random() * this.intervals.length)];
|
|
29
|
-
interval.add(cb, timeout);
|
|
30
|
-
};
|
|
31
35
|
}
|
|
36
|
+
exports.TimeCluster = TimeCluster;
|
|
32
37
|
//# sourceMappingURL=time.js.map
|
package/dist/time.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"time.js","sourceRoot":"","sources":["../src/time.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,
|
|
1
|
+
{"version":3,"file":"time.js","sourceRoot":"","sources":["../src/time.ts"],"names":[],"mappings":";;;AAEA,MAAa,QAAQ;IAGjB;QAFA,cAAS,GAAU,EAAE,CAAC;QAetB,QAAG,GAAG,CAAC,EAAoC,EAAE,OAAe,EAAE,EAAE;YAC5D,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,GAAG,IAAI,CAAC;YAC3C,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;QACxC,CAAC,CAAA;QAfG,WAAW,CAAC,KAAK,IAAI,EAAE;YACnB,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YACxB,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;gBAClD,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;gBAC/B,IAAI,IAAI,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;oBACtB,MAAM,IAAI,CAAC,EAAE,EAAE,CAAC;oBAChB,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;gBAChC,CAAC;YACL,CAAC;QACL,CAAC,EAAE,GAAG,CAAC,CAAC;IACZ,CAAC;CAMJ;AApBD,4BAoBC;AAED,MAAa,WAAW;IAIpB,YAAY,IAAY;QAFxB,cAAS,GAAG,IAAI,KAAK,EAAY,CAAC;QAQlC,YAAO,GAAG,CAAC,EAAoC,EAAE,OAAe,EAAE,EAAE;YAChE,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;YACnF,QAAQ,CAAC,GAAG,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;QAC9B,CAAC,CAAA;QARG,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC;YAC5B,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,QAAQ,EAAE,CAAC,CAAC;QACxC,CAAC;IACL,CAAC;CAMJ;AAdD,kCAcC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ttc-rate-limit",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "A rate limiting library with worker pool support for parallel timeout management",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.js",
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"scripts": {
|
|
14
14
|
"build": "tsc",
|
|
15
15
|
"dev": "tsc --watch",
|
|
16
|
-
"test": "bun
|
|
16
|
+
"test": "bun src/llm/example.ts",
|
|
17
17
|
"prepublishOnly": "npm run build"
|
|
18
18
|
},
|
|
19
19
|
"keywords": [
|
|
@@ -33,7 +33,13 @@
|
|
|
33
33
|
"peerDependencies": {
|
|
34
34
|
"typescript": "^5.9.3"
|
|
35
35
|
},
|
|
36
|
+
"dependencies": {
|
|
37
|
+
"@anthropic-ai/sdk": "^0.39.0",
|
|
38
|
+
"dotenv": "^17.3.1",
|
|
39
|
+
"openai": "^4.0.0"
|
|
40
|
+
},
|
|
36
41
|
"engines": {
|
|
37
42
|
"node": ">=18.0.0"
|
|
38
|
-
}
|
|
43
|
+
},
|
|
44
|
+
"packageManager": "yarn@1.22.22+sha1.ac34549e6aa8e7ead463a7407e1c7390f61a6610"
|
|
39
45
|
}
|
package/dist/cluster.d.ts
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { RateLimiter, RateLimiterConfig } from "./ratelimit";
|
|
2
|
-
import { EventEmitter } from 'events';
|
|
3
|
-
export declare class Cluster<T> {
|
|
4
|
-
config: {
|
|
5
|
-
type: 'random' | 'roundrobin' | 'prefered';
|
|
6
|
-
perferedLimiter?: string;
|
|
7
|
-
};
|
|
8
|
-
emitter: EventEmitter;
|
|
9
|
-
limiters: RateLimiter<T>[];
|
|
10
|
-
constructor(type: 'random' | 'roundrobin' | 'prefered');
|
|
11
|
-
on: (event: "completed" | "error", listener: (data: {
|
|
12
|
-
request: T;
|
|
13
|
-
response: any;
|
|
14
|
-
}) => void) => void;
|
|
15
|
-
addOption: (config: RateLimiterConfig<T>, specific?: boolean) => this;
|
|
16
|
-
invoke: (item: T) => Promise<void>;
|
|
17
|
-
randomLimiter: () => RateLimiter<T>;
|
|
18
|
-
}
|
|
19
|
-
//# sourceMappingURL=cluster.d.ts.map
|
package/dist/cluster.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cluster.d.ts","sourceRoot":"","sources":["../src/cluster.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAEtC,qBAAa,OAAO,CAAC,CAAC;IAElB,MAAM,EAAE;QACJ,IAAI,EAAE,QAAQ,GAAG,YAAY,GAAG,UAAU,CAAC;QAC3C,eAAe,CAAC,EAAE,MAAM,CAAC;KAC5B,CAAsB;IAEvB,OAAO,EAAE,YAAY,CAAsB;IAE3C,QAAQ,EAAE,WAAW,CAAC,CAAC,CAAC,EAAE,CAAM;gBAEpB,IAAI,EAAE,QAAQ,GAAG,YAAY,GAAG,UAAU;IAMtD,EAAE,GAAI,OAAO,WAAW,GAAG,OAAO,EAAE,UAAU,CAAC,IAAI,EAAE;QAAC,OAAO,EAAE,CAAC,CAAC;QAAC,QAAQ,EAAE,GAAG,CAAA;KAAC,KAAK,IAAI,UAExF;IAED,SAAS,GAAI,QAAQ,iBAAiB,CAAC,CAAC,CAAC,EAAE,WAAU,OAAe,UAWnE;IAED,MAAM,GAAU,MAAM,CAAC,mBAmBtB;IAED,aAAa,QAAO,WAAW,CAAC,CAAC,CAAC,CAGjC;CACJ"}
|
package/dist/index.d.ts
DELETED
package/dist/index.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,KAAK,iBAAiB,EAAE,KAAK,SAAS,EAAE,MAAM,aAAa,CAAC;AAClF,OAAO,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC"}
|
package/dist/ratelimit.d.ts
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import { EventEmitter } from "events";
|
|
2
|
-
import { TimeCluster } from "./time";
|
|
3
|
-
export declare const time: TimeCluster;
|
|
4
|
-
export interface RateLimiterConfig<T> {
|
|
5
|
-
id: string;
|
|
6
|
-
request: number;
|
|
7
|
-
per: 'second' | 'minute' | 'hour' | 'day';
|
|
8
|
-
interval?: number;
|
|
9
|
-
cb: (input: T) => Promise<any>;
|
|
10
|
-
_count?: number;
|
|
11
|
-
rps?: number;
|
|
12
|
-
_Tmarker?: number;
|
|
13
|
-
mode: 'spread' | 'burst';
|
|
14
|
-
}
|
|
15
|
-
export type queueData<T> = {
|
|
16
|
-
data: T;
|
|
17
|
-
cb: (response: any) => Promise<any>;
|
|
18
|
-
};
|
|
19
|
-
export declare class RateLimiter<T> {
|
|
20
|
-
config: RateLimiterConfig<T>;
|
|
21
|
-
queue: T[];
|
|
22
|
-
eventManager: EventEmitter;
|
|
23
|
-
constructor(config: RateLimiterConfig<T>);
|
|
24
|
-
_resolve(): void;
|
|
25
|
-
on: (event: "completed" | "error", listener: (data: {
|
|
26
|
-
request: T;
|
|
27
|
-
response: any;
|
|
28
|
-
}) => void) => void;
|
|
29
|
-
processQueue(): Promise<void>;
|
|
30
|
-
spreadAlgorithm(input: T): Promise<{
|
|
31
|
-
status: 'success' | 'error' | 'queued';
|
|
32
|
-
message?: string | undefined;
|
|
33
|
-
}>;
|
|
34
|
-
burstAlgorithm(input: T): Promise<{
|
|
35
|
-
status: 'success' | 'error' | 'queued';
|
|
36
|
-
message?: string | undefined;
|
|
37
|
-
}>;
|
|
38
|
-
invoke(input: T): Promise<{
|
|
39
|
-
status: 'success' | 'error' | 'queued';
|
|
40
|
-
message?: string | undefined;
|
|
41
|
-
}>;
|
|
42
|
-
}
|
|
43
|
-
//# sourceMappingURL=ratelimit.d.ts.map
|
package/dist/ratelimit.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ratelimit.d.ts","sourceRoot":"","sources":["../src/ratelimit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAErC,eAAO,MAAM,IAAI,aAAsB,CAAC;AAExC,MAAM,WAAW,iBAAiB,CAAC,CAAC;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,QAAQ,GAAG,QAAQ,GAAG,MAAM,GAAG,KAAK,CAAC;IAC1C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,EAAE,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC;CAC5B;AAED,MAAM,MAAM,SAAS,CAAC,CAAC,IAAI;IACvB,IAAI,EAAE,CAAC,CAAC;IACR,EAAE,EAAE,CAAC,QAAQ,EAAE,GAAG,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;CACvC,CAAA;AAED,qBAAa,WAAW,CAAC,CAAC;IAEtB,MAAM,EAAE,iBAAiB,CAAC,CAAC,CAAC,CAAA;IAC5B,KAAK,EAAE,CAAC,EAAE,CAAM;IAChB,YAAY,EAAE,YAAY,CAAC;gBACf,MAAM,EAAE,iBAAiB,CAAC,CAAC,CAAC;IAMxC,QAAQ;IAcR,EAAE,GAAI,OAAO,WAAW,GAAG,OAAO,EAAE,UAAU,CAAC,IAAI,EAAE;QACjD,OAAO,EAAE,CAAC,CAAC;QAAC,QAAQ,EAAE,GAAG,CAAA;KAC5B,KAAK,IAAI,UAET;IAEK,YAAY;IA6BZ,eAAe,CAAC,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC;QACrC,MAAM,EAAE,SAAS,GAAG,OAAO,GAAG,QAAQ,CAAC;QACvC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;KAChC,CAAC;IAmCI,cAAc,CAAC,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC;QACpC,MAAM,EAAE,SAAS,GAAG,OAAO,GAAG,QAAQ,CAAC;QACvC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;KAChC,CAAC;IA4DI,MAAM,CAAC,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC;QAC5B,MAAM,EAAE,SAAS,GAAG,OAAO,GAAG,QAAQ,CAAC;QACvC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;KAChC,CAAC;CAiBL"}
|
package/dist/test.d.ts
DELETED
package/dist/test.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"test.d.ts","sourceRoot":"","sources":["../src/test.ts"],"names":[],"mappings":""}
|
package/dist/time.d.ts
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
export declare class Interval {
|
|
2
|
-
callbacks: any[];
|
|
3
|
-
constructor();
|
|
4
|
-
add: (cb: (...args: any[]) => Promise<any>, timeout: number) => void;
|
|
5
|
-
}
|
|
6
|
-
export declare class TimeCluster {
|
|
7
|
-
intervals: Interval[];
|
|
8
|
-
constructor(size: number);
|
|
9
|
-
waitFor: (cb: (...args: any[]) => Promise<any>, timeout: number) => void;
|
|
10
|
-
}
|
|
11
|
-
//# sourceMappingURL=time.d.ts.map
|
package/dist/time.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"time.d.ts","sourceRoot":"","sources":["../src/time.ts"],"names":[],"mappings":"AAEA,qBAAa,QAAQ;IACjB,SAAS,EAAE,GAAG,EAAE,CAAM;;IAetB,GAAG,GAAI,IAAI,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,GAAG,CAAC,EAAE,SAAS,MAAM,UAG3D;CACJ;AAED,qBAAa,WAAW;IAEpB,SAAS,aAAyB;gBAEtB,IAAI,EAAE,MAAM;IAMxB,OAAO,GAAI,IAAI,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,GAAG,CAAC,EAAE,SAAS,MAAM,UAG/D;CACJ"}
|