ttc-rate-limit 0.1.3 → 0.1.7

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 CHANGED
@@ -1,16 +1,11 @@
1
1
  # ttc_rate_limit
2
2
 
3
- A rate limiting library with worker pool support for parallel timeout management and multi-provider LLM routing.
3
+ A rate limiting library with worker pool support for parallel timeout management.
4
4
 
5
5
  ## Features
6
6
 
7
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
8
+ - **Cluster Management**: Coordinate multiple rate limiters with `Cluster` for load balancing and failover
14
9
 
15
10
  ## Installation
16
11
 
@@ -30,7 +25,7 @@ const apiLimiter = new RateLimiter({
30
25
  id: 'api-limiter',
31
26
  request: 100, // 100 requests
32
27
  per: 'minute', // per minute
33
- mode: 'spread', // spread evenly
28
+ mode: 'spread', // spread evenly over time
34
29
  cb: async (params) => {
35
30
  // Your API call here
36
31
  return await fetch('https://api.example.com', params);
@@ -41,90 +36,90 @@ const apiLimiter = new RateLimiter({
41
36
  const result = await apiLimiter.invoke({ url: '/api/data' });
42
37
  ```
43
38
 
44
- ### Multi-Provider LLM Provisioning
39
+ #### Rate Limiting Modes
40
+
41
+ - **`spread`**: Distributes requests evenly over the time period. For 100 requests per minute, sends ~1.67 requests per second.
42
+ - **`burst`**: Allows requests up to the limit instantly, then waits for the full time window to reset. For 100/minute, sends 100 requests at once, then waits 60 seconds.
43
+ - **`hybrid`**: Combines burst and spread. Uses `hybridRatio` to divide the limit into smaller bursts. For 100/minute with `hybridRatio: 10`, sends 10 requests every 6 seconds.
45
44
 
46
45
  ```typescript
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',
46
+ // Burst mode example
47
+ const burstLimiter = new RateLimiter({
48
+ id: 'burst-limiter',
49
+ request: 100,
50
+ per: 'minute',
51
+ mode: 'burst',
52
+ cb: async (input) => apiCall(input),
63
53
  });
64
54
 
65
- const response = await provisioner.complete({
66
- messages: [{ role: 'user', content: 'Hello!' }],
55
+ // Hybrid mode example
56
+ const hybridLimiter = new RateLimiter({
57
+ id: 'hybrid-limiter',
58
+ request: 100,
59
+ per: 'minute',
60
+ mode: 'hybrid',
61
+ hybridRatio: 10, // 10 bursts per 6 seconds
62
+ cb: async (input) => apiCall(input),
67
63
  });
68
-
69
- console.log(response.content);
70
64
  ```
71
65
 
72
- ## Supported LLM Providers
73
66
 
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 |
67
+ ### Cluster Management
82
68
 
83
- ## Routing Strategies
69
+ Use `Cluster` to manage multiple rate limiters and distribute tasks among them using load balancing strategies.
84
70
 
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 |
71
+ ```typescript
72
+ import { Cluster } from 'ttc_rate_limit';
73
+
74
+ type Task = { modelId: string; chatId: string; };
75
+
76
+ const cluster = new Cluster<Task, string>('roundrobin');
77
+
78
+ // Add multiple rate limiters
79
+ cluster.addOption({
80
+ id: 'api-1',
81
+ request: 100,
82
+ per: 'minute',
83
+ mode: 'hybrid',
84
+ hybridRatio: 10,
85
+ cb: async (task) => {
86
+ // Process task with API 1
87
+ return `Processed by API 1: ${task.modelId} - ${task.chatId}`;
88
+ },
89
+ });
94
90
 
95
- ## API Reference
91
+ cluster.addOption({
92
+ id: 'api-2',
93
+ request: 50,
94
+ per: 'minute',
95
+ mode: 'spread',
96
+ cb: async (task) => {
97
+ // Process task with API 2
98
+ return `Processed by API 2: ${task.modelId} - ${task.chatId}`;
99
+ },
100
+ });
96
101
 
97
- ### LLMProvisioner
102
+ // Listen for events
103
+ cluster.on('completed', (data) => {
104
+ console.log('Task completed:', data.response);
105
+ });
98
106
 
99
- ```typescript
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>
107
+ cluster.on('error', (data) => {
108
+ console.error('Task error:', data.response);
109
+ });
110
+
111
+ // Invoke tasks (will be distributed among limiters)
112
+ for (let i = 0; i < 10; i++) {
113
+ cluster.invoke({ modelId: 'gpt-4', chatId: `chat-${i}` });
120
114
  }
121
115
  ```
122
116
 
123
- ## Building
117
+ #### Cluster Strategies
124
118
 
125
- ```bash
126
- npm run build
127
- ```
119
+ - **`random`**: Randomly select a limiter for each task.
120
+ - **`roundrobin`**: Cycle through limiters sequentially.
121
+
122
+ ## License
128
123
 
129
124
  ## License
130
125
 
package/dist/cluster.d.ts CHANGED
@@ -2,18 +2,18 @@ import { RateLimiter, RateLimiterConfig } from "./ratelimit";
2
2
  import { EventEmitter } from 'events';
3
3
  export declare class Cluster<T, R> {
4
4
  config: {
5
- type: 'random' | 'roundrobin' | 'prefered';
5
+ type: 'random' | 'roundrobin';
6
6
  perferedLimiter?: string;
7
7
  };
8
8
  emitter: EventEmitter;
9
9
  limiters: RateLimiter<T, R>[];
10
- constructor(type: 'random' | 'roundrobin' | 'prefered');
10
+ constructor(type: 'random' | 'roundrobin');
11
11
  on: (event: "completed" | "error", listener: (data: {
12
12
  request: T;
13
13
  response: any;
14
14
  }) => void) => void;
15
15
  addOption: (config: RateLimiterConfig<T, R>, specific?: boolean) => this;
16
- invoke: (item: T) => Promise<void>;
16
+ invoke: (item: T, preferredLimiterId?: string, retryCount?: number) => Promise<void>;
17
17
  randomLimiter: () => RateLimiter<T, R>;
18
18
  }
19
19
  //# sourceMappingURL=cluster.d.ts.map
@@ -1 +1 @@
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,EAAE,CAAC;IAErB,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,EAAE,CAAC,CAAC,EAAE,CAAM;gBAEvB,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,EAAE,CAAC,CAAC,EAAE,WAAU,OAAe,UAWtE;IAED,MAAM,GAAU,MAAM,CAAC,mBAmBtB;IAED,aAAa,QAAO,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,CAGpC;CACJ"}
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,EAAE,CAAC;IAErB,MAAM,EAAE;QACJ,IAAI,EAAE,QAAQ,GAAG,YAAY,CAAC;QAC9B,eAAe,CAAC,EAAE,MAAM,CAAC;KAC5B,CAAsB;IAEvB,OAAO,EAAE,YAAY,CAAsB;IAE3C,QAAQ,EAAE,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAM;gBAEvB,IAAI,EAAE,QAAQ,GAAG,YAAY;IAMzC,EAAE,GAAI,OAAO,WAAW,GAAG,OAAO,EAAE,UAAU,CAAC,IAAI,EAAE;QAAE,OAAO,EAAE,CAAC,CAAC;QAAC,QAAQ,EAAE,GAAG,CAAA;KAAE,KAAK,IAAI,UAE1F;IAED,SAAS,GAAI,QAAQ,iBAAiB,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,WAAU,OAAe,UAWtE;IAED,MAAM,GAAU,MAAM,CAAC,EAAE,qBAAqB,MAAM,EAAE,aAAY,MAAU,KAAG,OAAO,CAAC,IAAI,CAAC,CA0B3F;IAED,aAAa,QAAO,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,CAGpC;CACJ"}
package/dist/cluster.js CHANGED
@@ -23,10 +23,16 @@ class Cluster {
23
23
  });
24
24
  return this;
25
25
  };
26
- this.invoke = async (item) => {
26
+ this.invoke = async (item, preferredLimiterId, retryCount = 0) => {
27
27
  try {
28
28
  let limiter;
29
- if (this.config.type === 'random') {
29
+ if (preferredLimiterId) {
30
+ limiter = this.limiters.find(l => l.config.id === preferredLimiterId);
31
+ if (!limiter) {
32
+ limiter = this.randomLimiter();
33
+ }
34
+ }
35
+ else if (this.config.type === 'random') {
30
36
  limiter = this.randomLimiter();
31
37
  }
32
38
  else if (this.config.type === 'roundrobin') {
@@ -34,15 +40,16 @@ class Cluster {
34
40
  this.limiters.push(limiter);
35
41
  }
36
42
  else {
37
- limiter = this.limiters.find(l => l.config.id === this.config.perferedLimiter);
38
- if (!limiter) {
39
- limiter = this.randomLimiter();
40
- }
43
+ limiter = this.limiters[0];
41
44
  }
42
45
  await limiter.invoke(item);
43
46
  }
44
47
  catch (error) {
45
- throw error;
48
+ if (retryCount >= 3) {
49
+ this.emitter.emit('error', { request: item, response: error });
50
+ return;
51
+ }
52
+ return await this.invoke(item, preferredLimiterId, retryCount + 1);
46
53
  }
47
54
  };
48
55
  this.randomLimiter = () => {
@@ -1 +1 @@
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"}
1
+ {"version":3,"file":"cluster.js","sourceRoot":"","sources":["../src/cluster.ts"],"names":[],"mappings":"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"}
@@ -6,11 +6,12 @@ export interface RateLimiterConfig<T, R> {
6
6
  request: number;
7
7
  per: 'second' | 'minute' | 'hour' | 'day';
8
8
  interval?: number;
9
- cb: (input: T) => Promise<R>;
9
+ cb: (input: T, limiterId: string) => Promise<R>;
10
10
  _count?: number;
11
11
  rps?: number;
12
12
  _Tmarker?: number;
13
- mode: 'spread' | 'burst';
13
+ mode: 'spread' | 'burst' | 'hybrid';
14
+ hybridRatio?: number;
14
15
  }
15
16
  export type queueData<T> = {
16
17
  data: T;
@@ -1 +1 @@
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,EAAE,CAAC;IACnC,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,CAAC,CAAC,CAAC;IAC7B,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,EAAE,CAAC;IAEzB,MAAM,EAAE,iBAAiB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;IAC/B,KAAK,EAAE,CAAC,EAAE,CAAM;IAChB,YAAY,EAAE,YAAY,CAAC;gBACf,MAAM,EAAE,iBAAiB,CAAC,CAAC,EAAE,CAAC,CAAC;IAM3C,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"}
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,EAAE,CAAC;IACnC,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,EAAE,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;IAChD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,QAAQ,GAAG,OAAO,GAAG,QAAQ,CAAC;IACpC,WAAW,CAAC,EAAE,MAAM,CAAC;CACxB;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,EAAE,CAAC;IAEzB,MAAM,EAAE,iBAAiB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;IAC/B,KAAK,EAAE,CAAC,EAAE,CAAM;IAChB,YAAY,EAAE,YAAY,CAAC;gBACf,MAAM,EAAE,iBAAiB,CAAC,CAAC,EAAE,CAAC,CAAC;IAM3C,QAAQ;IAqBR,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;IA+DI,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;CAoBL"}
package/dist/ratelimit.js CHANGED
@@ -23,7 +23,16 @@ class RateLimiter {
23
23
  };
24
24
  const interval = intervals[this.config.per] ?? 1;
25
25
  this.config.rps = Math.ceil(this.config.request / interval);
26
- this.config.interval = interval / this.config.request;
26
+ if (this.config.mode === 'spread') {
27
+ this.config.interval = interval / this.config.request;
28
+ }
29
+ else if (this.config.mode === 'burst') {
30
+ this.config.interval = interval;
31
+ }
32
+ else if (this.config.mode === 'hybrid') {
33
+ this.config.interval = interval / (this.config.hybridRatio ?? 2);
34
+ this.config.request = Math.ceil(this.config.request / (this.config.hybridRatio ?? 2));
35
+ }
27
36
  this.config._count = 0;
28
37
  console.log(this.config);
29
38
  }
@@ -65,7 +74,7 @@ class RateLimiter {
65
74
  }, this.config.interval);
66
75
  }
67
76
  try {
68
- const response = await this.config.cb(input);
77
+ const response = await this.config.cb(input, this.config.id);
69
78
  this.eventManager.emit('completed', {
70
79
  request: input,
71
80
  response
@@ -91,6 +100,7 @@ class RateLimiter {
91
100
  async burstAlgorithm(input) {
92
101
  const now = Date.now();
93
102
  const windowMs = this.config.interval * 1000;
103
+ // console.log(windowMs, 'windowMs');
94
104
  // Reset count if window has passed
95
105
  if (this.config._Tmarker && now - this.config._Tmarker >= windowMs) {
96
106
  this.config._count = 0;
@@ -118,13 +128,14 @@ class RateLimiter {
118
128
  // If this request hits the limit, schedule reset after remaining time
119
129
  if (this.config._count === this.config.request && timeRemaining > 0) {
120
130
  const waitSeconds = timeRemaining / 1000;
131
+ console.log(timeRemaining, waitSeconds);
121
132
  await exports.time.waitFor(async () => {
122
133
  this.config._count = 0;
123
134
  await this.processQueue();
124
135
  }, waitSeconds);
125
136
  }
126
137
  try {
127
- const response = await this.config.cb(input);
138
+ const response = await this.config.cb(input, this.config.id);
128
139
  this.eventManager.emit('completed', {
129
140
  request: input,
130
141
  response
@@ -142,6 +153,7 @@ class RateLimiter {
142
153
  }
143
154
  async invoke(input) {
144
155
  let response = null;
156
+ // we need to ensure that the parametes are not in the queue
145
157
  try {
146
158
  if (this.config.mode === 'spread') {
147
159
  response = await this.spreadAlgorithm(input);
@@ -1 +1 @@
1
- {"version":3,"file":"ratelimit.js","sourceRoot":"","sources":["../src/ratelimit.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ratelimit.js","sourceRoot":"","sources":["../src/ratelimit.ts"],"names":[],"mappings":"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"}
package/dist/test.js CHANGED
@@ -6,7 +6,8 @@ cluster.addOption({
6
6
  id: 'deepseek',
7
7
  request: 100,
8
8
  per: 'minute',
9
- mode: 'spread',
9
+ mode: 'hybrid',
10
+ hybridRatio: 10,
10
11
  cb: async (input) => {
11
12
  return `Processed: ${input.modelId} - ${input.chatId} by Deepseek`;
12
13
  }
package/dist/test.js.map CHANGED
@@ -1 +1 @@
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"}
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,WAAW,EAAE,EAAE;IACf,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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ttc-rate-limit",
3
- "version": "0.1.3",
3
+ "version": "0.1.7",
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 src/llm/example.ts",
16
+ "test": "bun src/test.ts",
17
17
  "prepublishOnly": "npm run build"
18
18
  },
19
19
  "keywords": [