opencode-openai-codex-auth-multi 4.3.1 → 4.6.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 +20 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +34 -7
- package/dist/index.js.map +1 -1
- package/dist/lib/accounts.d.ts +7 -0
- package/dist/lib/accounts.d.ts.map +1 -1
- package/dist/lib/accounts.js +53 -0
- package/dist/lib/accounts.js.map +1 -1
- package/dist/lib/auth/auth.d.ts +9 -1
- package/dist/lib/auth/auth.d.ts.map +1 -1
- package/dist/lib/auth/auth.js +7 -1
- package/dist/lib/auth/auth.js.map +1 -1
- package/dist/lib/auto-update-checker.d.ts +10 -0
- package/dist/lib/auto-update-checker.d.ts.map +1 -0
- package/dist/lib/auto-update-checker.js +129 -0
- package/dist/lib/auto-update-checker.js.map +1 -0
- package/dist/lib/cli.d.ts.map +1 -1
- package/dist/lib/cli.js +1 -0
- package/dist/lib/cli.js.map +1 -1
- package/dist/lib/config.js +6 -6
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/context-overflow.d.ts +27 -0
- package/dist/lib/context-overflow.d.ts.map +1 -0
- package/dist/lib/context-overflow.js +124 -0
- package/dist/lib/context-overflow.js.map +1 -0
- package/dist/lib/logger.d.ts +13 -17
- package/dist/lib/logger.d.ts.map +1 -1
- package/dist/lib/logger.js +89 -24
- package/dist/lib/logger.js.map +1 -1
- package/dist/lib/refresh-queue.d.ts +100 -0
- package/dist/lib/refresh-queue.d.ts.map +1 -0
- package/dist/lib/refresh-queue.js +196 -0
- package/dist/lib/refresh-queue.js.map +1 -0
- package/dist/lib/request/fetch-helpers.js +2 -2
- package/dist/lib/request/fetch-helpers.js.map +1 -1
- package/dist/lib/request/helpers/input-utils.d.ts +1 -0
- package/dist/lib/request/helpers/input-utils.d.ts.map +1 -1
- package/dist/lib/request/helpers/input-utils.js +39 -0
- package/dist/lib/request/helpers/input-utils.js.map +1 -1
- package/dist/lib/request/rate-limit-backoff.d.ts +4 -0
- package/dist/lib/request/rate-limit-backoff.d.ts.map +1 -1
- package/dist/lib/request/rate-limit-backoff.js +20 -0
- package/dist/lib/request/rate-limit-backoff.js.map +1 -1
- package/dist/lib/request/request-transformer.d.ts.map +1 -1
- package/dist/lib/request/request-transformer.js +2 -1
- package/dist/lib/request/request-transformer.js.map +1 -1
- package/dist/lib/rotation.d.ts +121 -0
- package/dist/lib/rotation.d.ts.map +1 -0
- package/dist/lib/rotation.js +248 -0
- package/dist/lib/rotation.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rotation Strategy Module
|
|
3
|
+
*
|
|
4
|
+
* Implements health-based account selection with token bucket rate limiting.
|
|
5
|
+
* Ported from antigravity-auth rotation logic for optimal account rotation
|
|
6
|
+
* when rate limits are encountered.
|
|
7
|
+
*/
|
|
8
|
+
export interface HealthScoreConfig {
|
|
9
|
+
/** Points added on successful request */
|
|
10
|
+
successDelta: number;
|
|
11
|
+
/** Points deducted on rate limit (negative) */
|
|
12
|
+
rateLimitDelta: number;
|
|
13
|
+
/** Points deducted on other failures (negative) */
|
|
14
|
+
failureDelta: number;
|
|
15
|
+
/** Maximum health score */
|
|
16
|
+
maxScore: number;
|
|
17
|
+
/** Minimum health score */
|
|
18
|
+
minScore: number;
|
|
19
|
+
/** Points recovered per hour of inactivity */
|
|
20
|
+
passiveRecoveryPerHour: number;
|
|
21
|
+
}
|
|
22
|
+
export declare const DEFAULT_HEALTH_SCORE_CONFIG: HealthScoreConfig;
|
|
23
|
+
/**
|
|
24
|
+
* Tracks health scores for accounts to prioritize healthy accounts.
|
|
25
|
+
* Accounts with higher health scores are preferred for selection.
|
|
26
|
+
*/
|
|
27
|
+
export declare class HealthScoreTracker {
|
|
28
|
+
private entries;
|
|
29
|
+
private config;
|
|
30
|
+
constructor(config?: Partial<HealthScoreConfig>);
|
|
31
|
+
private getKey;
|
|
32
|
+
private applyPassiveRecovery;
|
|
33
|
+
getScore(accountIndex: number, quotaKey?: string): number;
|
|
34
|
+
getConsecutiveFailures(accountIndex: number, quotaKey?: string): number;
|
|
35
|
+
recordSuccess(accountIndex: number, quotaKey?: string): void;
|
|
36
|
+
recordRateLimit(accountIndex: number, quotaKey?: string): void;
|
|
37
|
+
recordFailure(accountIndex: number, quotaKey?: string): void;
|
|
38
|
+
reset(accountIndex: number, quotaKey?: string): void;
|
|
39
|
+
clear(): void;
|
|
40
|
+
}
|
|
41
|
+
export interface TokenBucketConfig {
|
|
42
|
+
/** Maximum tokens in bucket */
|
|
43
|
+
maxTokens: number;
|
|
44
|
+
/** Tokens regenerated per minute */
|
|
45
|
+
tokensPerMinute: number;
|
|
46
|
+
}
|
|
47
|
+
export declare const DEFAULT_TOKEN_BUCKET_CONFIG: TokenBucketConfig;
|
|
48
|
+
/**
|
|
49
|
+
* Client-side token bucket for rate limiting requests per account.
|
|
50
|
+
* Prevents sending requests to accounts that are likely to be rate-limited.
|
|
51
|
+
*/
|
|
52
|
+
export declare class TokenBucketTracker {
|
|
53
|
+
private buckets;
|
|
54
|
+
private config;
|
|
55
|
+
constructor(config?: Partial<TokenBucketConfig>);
|
|
56
|
+
private getKey;
|
|
57
|
+
private refillTokens;
|
|
58
|
+
getTokens(accountIndex: number, quotaKey?: string): number;
|
|
59
|
+
/**
|
|
60
|
+
* Attempt to consume a token. Returns true if successful, false if bucket is empty.
|
|
61
|
+
*/
|
|
62
|
+
tryConsume(accountIndex: number, quotaKey?: string): boolean;
|
|
63
|
+
/**
|
|
64
|
+
* Drain tokens on rate limit to prevent immediate retries.
|
|
65
|
+
*/
|
|
66
|
+
drain(accountIndex: number, quotaKey?: string, drainAmount?: number): void;
|
|
67
|
+
reset(accountIndex: number, quotaKey?: string): void;
|
|
68
|
+
clear(): void;
|
|
69
|
+
}
|
|
70
|
+
export interface AccountWithMetrics {
|
|
71
|
+
index: number;
|
|
72
|
+
isAvailable: boolean;
|
|
73
|
+
lastUsed: number;
|
|
74
|
+
}
|
|
75
|
+
export interface HybridSelectionConfig {
|
|
76
|
+
/** Weight for health score (default: 2) */
|
|
77
|
+
healthWeight: number;
|
|
78
|
+
/** Weight for token count (default: 5) */
|
|
79
|
+
tokenWeight: number;
|
|
80
|
+
/** Weight for freshness/last used (default: 0.1) */
|
|
81
|
+
freshnessWeight: number;
|
|
82
|
+
}
|
|
83
|
+
export declare const DEFAULT_HYBRID_SELECTION_CONFIG: HybridSelectionConfig;
|
|
84
|
+
/**
|
|
85
|
+
* Selects the best account using a hybrid scoring strategy.
|
|
86
|
+
*
|
|
87
|
+
* Score = (health * healthWeight) + (tokens * tokenWeight) + (freshness * freshnessWeight)
|
|
88
|
+
*
|
|
89
|
+
* Where:
|
|
90
|
+
* - health: Account health score (0-100)
|
|
91
|
+
* - tokens: Available tokens in bucket (0-maxTokens)
|
|
92
|
+
* - freshness: Hours since last used (higher = more fresh for rotation)
|
|
93
|
+
*/
|
|
94
|
+
export declare function selectHybridAccount(accounts: AccountWithMetrics[], healthTracker: HealthScoreTracker, tokenTracker: TokenBucketTracker, quotaKey?: string, config?: Partial<HybridSelectionConfig>): AccountWithMetrics | null;
|
|
95
|
+
/**
|
|
96
|
+
* Adds random jitter to a delay value.
|
|
97
|
+
* @param baseMs - Base delay in milliseconds
|
|
98
|
+
* @param jitterFactor - Jitter factor (0-1), default 0.1 (10%)
|
|
99
|
+
* @returns Delay with jitter applied
|
|
100
|
+
*/
|
|
101
|
+
export declare function addJitter(baseMs: number, jitterFactor?: number): number;
|
|
102
|
+
/**
|
|
103
|
+
* Returns a random delay within a range.
|
|
104
|
+
* @param minMs - Minimum delay in milliseconds
|
|
105
|
+
* @param maxMs - Maximum delay in milliseconds
|
|
106
|
+
* @returns Random delay within range
|
|
107
|
+
*/
|
|
108
|
+
export declare function randomDelay(minMs: number, maxMs: number): number;
|
|
109
|
+
/**
|
|
110
|
+
* Calculates exponential backoff with jitter.
|
|
111
|
+
* @param attempt - Attempt number (1-based)
|
|
112
|
+
* @param baseMs - Base delay in milliseconds
|
|
113
|
+
* @param maxMs - Maximum delay in milliseconds
|
|
114
|
+
* @param jitterFactor - Jitter factor (0-1)
|
|
115
|
+
* @returns Backoff delay with jitter
|
|
116
|
+
*/
|
|
117
|
+
export declare function exponentialBackoff(attempt: number, baseMs?: number, maxMs?: number, jitterFactor?: number): number;
|
|
118
|
+
export declare function getHealthTracker(config?: Partial<HealthScoreConfig>): HealthScoreTracker;
|
|
119
|
+
export declare function getTokenTracker(config?: Partial<TokenBucketConfig>): TokenBucketTracker;
|
|
120
|
+
export declare function resetTrackers(): void;
|
|
121
|
+
//# sourceMappingURL=rotation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rotation.d.ts","sourceRoot":"","sources":["../../lib/rotation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rotation Strategy Module
|
|
3
|
+
*
|
|
4
|
+
* Implements health-based account selection with token bucket rate limiting.
|
|
5
|
+
* Ported from antigravity-auth rotation logic for optimal account rotation
|
|
6
|
+
* when rate limits are encountered.
|
|
7
|
+
*/
|
|
8
|
+
export const DEFAULT_HEALTH_SCORE_CONFIG = {
|
|
9
|
+
successDelta: 1,
|
|
10
|
+
rateLimitDelta: -10,
|
|
11
|
+
failureDelta: -20,
|
|
12
|
+
maxScore: 100,
|
|
13
|
+
minScore: 0,
|
|
14
|
+
passiveRecoveryPerHour: 2,
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Tracks health scores for accounts to prioritize healthy accounts.
|
|
18
|
+
* Accounts with higher health scores are preferred for selection.
|
|
19
|
+
*/
|
|
20
|
+
export class HealthScoreTracker {
|
|
21
|
+
entries = new Map();
|
|
22
|
+
config;
|
|
23
|
+
constructor(config = {}) {
|
|
24
|
+
this.config = { ...DEFAULT_HEALTH_SCORE_CONFIG, ...config };
|
|
25
|
+
}
|
|
26
|
+
getKey(accountIndex, quotaKey) {
|
|
27
|
+
return quotaKey ? `${accountIndex}:${quotaKey}` : `${accountIndex}`;
|
|
28
|
+
}
|
|
29
|
+
applyPassiveRecovery(entry) {
|
|
30
|
+
const now = Date.now();
|
|
31
|
+
const hoursSinceUpdate = (now - entry.lastUpdated) / (1000 * 60 * 60);
|
|
32
|
+
const recovery = hoursSinceUpdate * this.config.passiveRecoveryPerHour;
|
|
33
|
+
return Math.min(entry.score + recovery, this.config.maxScore);
|
|
34
|
+
}
|
|
35
|
+
getScore(accountIndex, quotaKey) {
|
|
36
|
+
const key = this.getKey(accountIndex, quotaKey);
|
|
37
|
+
const entry = this.entries.get(key);
|
|
38
|
+
if (!entry)
|
|
39
|
+
return this.config.maxScore;
|
|
40
|
+
return this.applyPassiveRecovery(entry);
|
|
41
|
+
}
|
|
42
|
+
getConsecutiveFailures(accountIndex, quotaKey) {
|
|
43
|
+
const key = this.getKey(accountIndex, quotaKey);
|
|
44
|
+
const entry = this.entries.get(key);
|
|
45
|
+
return entry?.consecutiveFailures ?? 0;
|
|
46
|
+
}
|
|
47
|
+
recordSuccess(accountIndex, quotaKey) {
|
|
48
|
+
const key = this.getKey(accountIndex, quotaKey);
|
|
49
|
+
const entry = this.entries.get(key);
|
|
50
|
+
const baseScore = entry ? this.applyPassiveRecovery(entry) : this.config.maxScore;
|
|
51
|
+
const newScore = Math.min(baseScore + this.config.successDelta, this.config.maxScore);
|
|
52
|
+
this.entries.set(key, {
|
|
53
|
+
score: newScore,
|
|
54
|
+
lastUpdated: Date.now(),
|
|
55
|
+
consecutiveFailures: 0,
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
recordRateLimit(accountIndex, quotaKey) {
|
|
59
|
+
const key = this.getKey(accountIndex, quotaKey);
|
|
60
|
+
const entry = this.entries.get(key);
|
|
61
|
+
const baseScore = entry ? this.applyPassiveRecovery(entry) : this.config.maxScore;
|
|
62
|
+
const newScore = Math.max(baseScore + this.config.rateLimitDelta, this.config.minScore);
|
|
63
|
+
this.entries.set(key, {
|
|
64
|
+
score: newScore,
|
|
65
|
+
lastUpdated: Date.now(),
|
|
66
|
+
consecutiveFailures: (entry?.consecutiveFailures ?? 0) + 1,
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
recordFailure(accountIndex, quotaKey) {
|
|
70
|
+
const key = this.getKey(accountIndex, quotaKey);
|
|
71
|
+
const entry = this.entries.get(key);
|
|
72
|
+
const baseScore = entry ? this.applyPassiveRecovery(entry) : this.config.maxScore;
|
|
73
|
+
const newScore = Math.max(baseScore + this.config.failureDelta, this.config.minScore);
|
|
74
|
+
this.entries.set(key, {
|
|
75
|
+
score: newScore,
|
|
76
|
+
lastUpdated: Date.now(),
|
|
77
|
+
consecutiveFailures: (entry?.consecutiveFailures ?? 0) + 1,
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
reset(accountIndex, quotaKey) {
|
|
81
|
+
const key = this.getKey(accountIndex, quotaKey);
|
|
82
|
+
this.entries.delete(key);
|
|
83
|
+
}
|
|
84
|
+
clear() {
|
|
85
|
+
this.entries.clear();
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
export const DEFAULT_TOKEN_BUCKET_CONFIG = {
|
|
89
|
+
maxTokens: 50,
|
|
90
|
+
tokensPerMinute: 6,
|
|
91
|
+
};
|
|
92
|
+
/**
|
|
93
|
+
* Client-side token bucket for rate limiting requests per account.
|
|
94
|
+
* Prevents sending requests to accounts that are likely to be rate-limited.
|
|
95
|
+
*/
|
|
96
|
+
export class TokenBucketTracker {
|
|
97
|
+
buckets = new Map();
|
|
98
|
+
config;
|
|
99
|
+
constructor(config = {}) {
|
|
100
|
+
this.config = { ...DEFAULT_TOKEN_BUCKET_CONFIG, ...config };
|
|
101
|
+
}
|
|
102
|
+
getKey(accountIndex, quotaKey) {
|
|
103
|
+
return quotaKey ? `${accountIndex}:${quotaKey}` : `${accountIndex}`;
|
|
104
|
+
}
|
|
105
|
+
refillTokens(entry) {
|
|
106
|
+
const now = Date.now();
|
|
107
|
+
const minutesSinceRefill = (now - entry.lastRefill) / (1000 * 60);
|
|
108
|
+
const tokensToAdd = minutesSinceRefill * this.config.tokensPerMinute;
|
|
109
|
+
return Math.min(entry.tokens + tokensToAdd, this.config.maxTokens);
|
|
110
|
+
}
|
|
111
|
+
getTokens(accountIndex, quotaKey) {
|
|
112
|
+
const key = this.getKey(accountIndex, quotaKey);
|
|
113
|
+
const entry = this.buckets.get(key);
|
|
114
|
+
if (!entry)
|
|
115
|
+
return this.config.maxTokens;
|
|
116
|
+
return this.refillTokens(entry);
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Attempt to consume a token. Returns true if successful, false if bucket is empty.
|
|
120
|
+
*/
|
|
121
|
+
tryConsume(accountIndex, quotaKey) {
|
|
122
|
+
const key = this.getKey(accountIndex, quotaKey);
|
|
123
|
+
const entry = this.buckets.get(key);
|
|
124
|
+
const currentTokens = entry ? this.refillTokens(entry) : this.config.maxTokens;
|
|
125
|
+
if (currentTokens < 1) {
|
|
126
|
+
return false;
|
|
127
|
+
}
|
|
128
|
+
this.buckets.set(key, {
|
|
129
|
+
tokens: currentTokens - 1,
|
|
130
|
+
lastRefill: Date.now(),
|
|
131
|
+
});
|
|
132
|
+
return true;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Drain tokens on rate limit to prevent immediate retries.
|
|
136
|
+
*/
|
|
137
|
+
drain(accountIndex, quotaKey, drainAmount = 10) {
|
|
138
|
+
const key = this.getKey(accountIndex, quotaKey);
|
|
139
|
+
const entry = this.buckets.get(key);
|
|
140
|
+
const currentTokens = entry ? this.refillTokens(entry) : this.config.maxTokens;
|
|
141
|
+
this.buckets.set(key, {
|
|
142
|
+
tokens: Math.max(0, currentTokens - drainAmount),
|
|
143
|
+
lastRefill: Date.now(),
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
reset(accountIndex, quotaKey) {
|
|
147
|
+
const key = this.getKey(accountIndex, quotaKey);
|
|
148
|
+
this.buckets.delete(key);
|
|
149
|
+
}
|
|
150
|
+
clear() {
|
|
151
|
+
this.buckets.clear();
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
export const DEFAULT_HYBRID_SELECTION_CONFIG = {
|
|
155
|
+
healthWeight: 2,
|
|
156
|
+
tokenWeight: 5,
|
|
157
|
+
freshnessWeight: 0.1,
|
|
158
|
+
};
|
|
159
|
+
/**
|
|
160
|
+
* Selects the best account using a hybrid scoring strategy.
|
|
161
|
+
*
|
|
162
|
+
* Score = (health * healthWeight) + (tokens * tokenWeight) + (freshness * freshnessWeight)
|
|
163
|
+
*
|
|
164
|
+
* Where:
|
|
165
|
+
* - health: Account health score (0-100)
|
|
166
|
+
* - tokens: Available tokens in bucket (0-maxTokens)
|
|
167
|
+
* - freshness: Hours since last used (higher = more fresh for rotation)
|
|
168
|
+
*/
|
|
169
|
+
export function selectHybridAccount(accounts, healthTracker, tokenTracker, quotaKey, config = {}) {
|
|
170
|
+
const cfg = { ...DEFAULT_HYBRID_SELECTION_CONFIG, ...config };
|
|
171
|
+
const available = accounts.filter((a) => a.isAvailable);
|
|
172
|
+
if (available.length === 0)
|
|
173
|
+
return null;
|
|
174
|
+
if (available.length === 1)
|
|
175
|
+
return available[0];
|
|
176
|
+
const now = Date.now();
|
|
177
|
+
let bestAccount = null;
|
|
178
|
+
let bestScore = -Infinity;
|
|
179
|
+
for (const account of available) {
|
|
180
|
+
const health = healthTracker.getScore(account.index, quotaKey);
|
|
181
|
+
const tokens = tokenTracker.getTokens(account.index, quotaKey);
|
|
182
|
+
const hoursSinceUsed = (now - account.lastUsed) / (1000 * 60 * 60);
|
|
183
|
+
const score = health * cfg.healthWeight +
|
|
184
|
+
tokens * cfg.tokenWeight +
|
|
185
|
+
hoursSinceUsed * cfg.freshnessWeight;
|
|
186
|
+
if (score > bestScore) {
|
|
187
|
+
bestScore = score;
|
|
188
|
+
bestAccount = account;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
return bestAccount;
|
|
192
|
+
}
|
|
193
|
+
// ============================================================================
|
|
194
|
+
// Utility Functions
|
|
195
|
+
// ============================================================================
|
|
196
|
+
/**
|
|
197
|
+
* Adds random jitter to a delay value.
|
|
198
|
+
* @param baseMs - Base delay in milliseconds
|
|
199
|
+
* @param jitterFactor - Jitter factor (0-1), default 0.1 (10%)
|
|
200
|
+
* @returns Delay with jitter applied
|
|
201
|
+
*/
|
|
202
|
+
export function addJitter(baseMs, jitterFactor = 0.1) {
|
|
203
|
+
const jitter = baseMs * jitterFactor * (Math.random() * 2 - 1);
|
|
204
|
+
return Math.max(0, Math.floor(baseMs + jitter));
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Returns a random delay within a range.
|
|
208
|
+
* @param minMs - Minimum delay in milliseconds
|
|
209
|
+
* @param maxMs - Maximum delay in milliseconds
|
|
210
|
+
* @returns Random delay within range
|
|
211
|
+
*/
|
|
212
|
+
export function randomDelay(minMs, maxMs) {
|
|
213
|
+
return Math.floor(minMs + Math.random() * (maxMs - minMs));
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Calculates exponential backoff with jitter.
|
|
217
|
+
* @param attempt - Attempt number (1-based)
|
|
218
|
+
* @param baseMs - Base delay in milliseconds
|
|
219
|
+
* @param maxMs - Maximum delay in milliseconds
|
|
220
|
+
* @param jitterFactor - Jitter factor (0-1)
|
|
221
|
+
* @returns Backoff delay with jitter
|
|
222
|
+
*/
|
|
223
|
+
export function exponentialBackoff(attempt, baseMs = 1000, maxMs = 60000, jitterFactor = 0.1) {
|
|
224
|
+
const delay = Math.min(baseMs * Math.pow(2, attempt - 1), maxMs);
|
|
225
|
+
return addJitter(delay, jitterFactor);
|
|
226
|
+
}
|
|
227
|
+
// ============================================================================
|
|
228
|
+
// Singleton Instances
|
|
229
|
+
// ============================================================================
|
|
230
|
+
let healthTrackerInstance = null;
|
|
231
|
+
let tokenTrackerInstance = null;
|
|
232
|
+
export function getHealthTracker(config) {
|
|
233
|
+
if (!healthTrackerInstance) {
|
|
234
|
+
healthTrackerInstance = new HealthScoreTracker(config);
|
|
235
|
+
}
|
|
236
|
+
return healthTrackerInstance;
|
|
237
|
+
}
|
|
238
|
+
export function getTokenTracker(config) {
|
|
239
|
+
if (!tokenTrackerInstance) {
|
|
240
|
+
tokenTrackerInstance = new TokenBucketTracker(config);
|
|
241
|
+
}
|
|
242
|
+
return tokenTrackerInstance;
|
|
243
|
+
}
|
|
244
|
+
export function resetTrackers() {
|
|
245
|
+
healthTrackerInstance?.clear();
|
|
246
|
+
tokenTrackerInstance?.clear();
|
|
247
|
+
}
|
|
248
|
+
//# sourceMappingURL=rotation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rotation.js","sourceRoot":"","sources":["../../lib/rotation.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAqBH,MAAM,CAAC,MAAM,2BAA2B,GAAsB;IAC5D,YAAY,EAAE,CAAC;IACf,cAAc,EAAE,CAAC,EAAE;IACnB,YAAY,EAAE,CAAC,EAAE;IACjB,QAAQ,EAAE,GAAG;IACb,QAAQ,EAAE,CAAC;IACX,sBAAsB,EAAE,CAAC;CAC1B,CAAC;AAQF;;;GAGG;AACH,MAAM,OAAO,kBAAkB;IACrB,OAAO,GAA6B,IAAI,GAAG,EAAE,CAAC;IAC9C,MAAM,CAAoB;IAElC,YAAY,SAAqC,EAAE;QACjD,IAAI,CAAC,MAAM,GAAG,EAAE,GAAG,2BAA2B,EAAE,GAAG,MAAM,EAAE,CAAC;IAC9D,CAAC;IAEO,MAAM,CAAC,YAAoB,EAAE,QAAiB;QACpD,OAAO,QAAQ,CAAC,CAAC,CAAC,GAAG,YAAY,IAAI,QAAQ,EAAE,CAAC,CAAC,CAAC,GAAG,YAAY,EAAE,CAAC;IACtE,CAAC;IAEO,oBAAoB,CAAC,KAAkB;QAC7C,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,MAAM,gBAAgB,GAAG,CAAC,GAAG,GAAG,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC;QACtE,MAAM,QAAQ,GAAG,gBAAgB,GAAG,IAAI,CAAC,MAAM,CAAC,sBAAsB,CAAC;QACvE,OAAO,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,GAAG,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAChE,CAAC;IAED,QAAQ,CAAC,YAAoB,EAAE,QAAiB;QAC9C,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;QAChD,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACpC,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC;QACxC,OAAO,IAAI,CAAC,oBAAoB,CAAC,KAAK,CAAC,CAAC;IAC1C,CAAC;IAED,sBAAsB,CAAC,YAAoB,EAAE,QAAiB;QAC5D,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;QAChD,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACpC,OAAO,KAAK,EAAE,mBAAmB,IAAI,CAAC,CAAC;IACzC,CAAC;IAED,aAAa,CAAC,YAAoB,EAAE,QAAiB;QACnD,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;QAChD,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACpC,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,oBAAoB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC;QAClF,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QACtF,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE;YACpB,KAAK,EAAE,QAAQ;YACf,WAAW,EAAE,IAAI,CAAC,GAAG,EAAE;YACvB,mBAAmB,EAAE,CAAC;SACvB,CAAC,CAAC;IACL,CAAC;IAED,eAAe,CAAC,YAAoB,EAAE,QAAiB;QACrD,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;QAChD,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACpC,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,oBAAoB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC;QAClF,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,cAAc,EAAE,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QACxF,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE;YACpB,KAAK,EAAE,QAAQ;YACf,WAAW,EAAE,IAAI,CAAC,GAAG,EAAE;YACvB,mBAAmB,EAAE,CAAC,KAAK,EAAE,mBAAmB,IAAI,CAAC,CAAC,GAAG,CAAC;SAC3D,CAAC,CAAC;IACL,CAAC;IAED,aAAa,CAAC,YAAoB,EAAE,QAAiB;QACnD,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;QAChD,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACpC,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,oBAAoB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC;QAClF,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QACtF,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE;YACpB,KAAK,EAAE,QAAQ;YACf,WAAW,EAAE,IAAI,CAAC,GAAG,EAAE;YACvB,mBAAmB,EAAE,CAAC,KAAK,EAAE,mBAAmB,IAAI,CAAC,CAAC,GAAG,CAAC;SAC3D,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,YAAoB,EAAE,QAAiB;QAC3C,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;QAChD,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAC3B,CAAC;IAED,KAAK;QACH,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;IACvB,CAAC;CACF;AAaD,MAAM,CAAC,MAAM,2BAA2B,GAAsB;IAC5D,SAAS,EAAE,EAAE;IACb,eAAe,EAAE,CAAC;CACnB,CAAC;AAOF;;;GAGG;AACH,MAAM,OAAO,kBAAkB;IACrB,OAAO,GAAkC,IAAI,GAAG,EAAE,CAAC;IACnD,MAAM,CAAoB;IAElC,YAAY,SAAqC,EAAE;QACjD,IAAI,CAAC,MAAM,GAAG,EAAE,GAAG,2BAA2B,EAAE,GAAG,MAAM,EAAE,CAAC;IAC9D,CAAC;IAEO,MAAM,CAAC,YAAoB,EAAE,QAAiB;QACpD,OAAO,QAAQ,CAAC,CAAC,CAAC,GAAG,YAAY,IAAI,QAAQ,EAAE,CAAC,CAAC,CAAC,GAAG,YAAY,EAAE,CAAC;IACtE,CAAC;IAEO,YAAY,CAAC,KAAuB;QAC1C,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,MAAM,kBAAkB,GAAG,CAAC,GAAG,GAAG,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC;QAClE,MAAM,WAAW,GAAG,kBAAkB,GAAG,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC;QACrE,OAAO,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,GAAG,WAAW,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IACrE,CAAC;IAED,SAAS,CAAC,YAAoB,EAAE,QAAiB;QAC/C,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;QAChD,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACpC,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC;QACzC,OAAO,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;IAClC,CAAC;IAED;;OAEG;IACH,UAAU,CAAC,YAAoB,EAAE,QAAiB;QAChD,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;QAChD,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACpC,MAAM,aAAa,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC;QAE/E,IAAI,aAAa,GAAG,CAAC,EAAE,CAAC;YACtB,OAAO,KAAK,CAAC;QACf,CAAC;QAED,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE;YACpB,MAAM,EAAE,aAAa,GAAG,CAAC;YACzB,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE;SACvB,CAAC,CAAC;QACH,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,YAAoB,EAAE,QAAiB,EAAE,cAAsB,EAAE;QACrE,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;QAChD,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACpC,MAAM,aAAa,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC;QAC/E,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE;YACpB,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,aAAa,GAAG,WAAW,CAAC;YAChD,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE;SACvB,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,YAAoB,EAAE,QAAiB;QAC3C,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;QAChD,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAC3B,CAAC;IAED,KAAK;QACH,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;IACvB,CAAC;CACF;AAqBD,MAAM,CAAC,MAAM,+BAA+B,GAA0B;IACpE,YAAY,EAAE,CAAC;IACf,WAAW,EAAE,CAAC;IACd,eAAe,EAAE,GAAG;CACrB,CAAC;AAEF;;;;;;;;;GASG;AACH,MAAM,UAAU,mBAAmB,CACjC,QAA8B,EAC9B,aAAiC,EACjC,YAAgC,EAChC,QAAiB,EACjB,SAAyC,EAAE;IAE3C,MAAM,GAAG,GAAG,EAAE,GAAG,+BAA+B,EAAE,GAAG,MAAM,EAAE,CAAC;IAC9D,MAAM,SAAS,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;IAExD,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACxC,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC,CAAC,CAAC,CAAC;IAEhD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,IAAI,WAAW,GAA8B,IAAI,CAAC;IAClD,IAAI,SAAS,GAAG,CAAC,QAAQ,CAAC;IAE1B,KAAK,MAAM,OAAO,IAAI,SAAS,EAAE,CAAC;QAChC,MAAM,MAAM,GAAG,aAAa,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;QAC/D,MAAM,MAAM,GAAG,YAAY,CAAC,SAAS,CAAC,OAAO,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;QAC/D,MAAM,cAAc,GAAG,CAAC,GAAG,GAAG,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC;QAEnE,MAAM,KAAK,GACT,MAAM,GAAG,GAAG,CAAC,YAAY;YACzB,MAAM,GAAG,GAAG,CAAC,WAAW;YACxB,cAAc,GAAG,GAAG,CAAC,eAAe,CAAC;QAEvC,IAAI,KAAK,GAAG,SAAS,EAAE,CAAC;YACtB,SAAS,GAAG,KAAK,CAAC;YAClB,WAAW,GAAG,OAAO,CAAC;QACxB,CAAC;IACH,CAAC;IAED,OAAO,WAAW,CAAC;AACrB,CAAC;AAED,+EAA+E;AAC/E,oBAAoB;AACpB,+EAA+E;AAE/E;;;;;GAKG;AACH,MAAM,UAAU,SAAS,CAAC,MAAc,EAAE,eAAuB,GAAG;IAClE,MAAM,MAAM,GAAG,MAAM,GAAG,YAAY,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;IAC/D,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC;AAClD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CAAC,KAAa,EAAE,KAAa;IACtD,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC;AAC7D,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,kBAAkB,CAChC,OAAe,EACf,SAAiB,IAAI,EACrB,QAAgB,KAAK,EACrB,eAAuB,GAAG;IAE1B,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IACjE,OAAO,SAAS,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;AACxC,CAAC;AAED,+EAA+E;AAC/E,sBAAsB;AACtB,+EAA+E;AAE/E,IAAI,qBAAqB,GAA8B,IAAI,CAAC;AAC5D,IAAI,oBAAoB,GAA8B,IAAI,CAAC;AAE3D,MAAM,UAAU,gBAAgB,CAAC,MAAmC;IAClE,IAAI,CAAC,qBAAqB,EAAE,CAAC;QAC3B,qBAAqB,GAAG,IAAI,kBAAkB,CAAC,MAAM,CAAC,CAAC;IACzD,CAAC;IACD,OAAO,qBAAqB,CAAC;AAC/B,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,MAAmC;IACjE,IAAI,CAAC,oBAAoB,EAAE,CAAC;QAC1B,oBAAoB,GAAG,IAAI,kBAAkB,CAAC,MAAM,CAAC,CAAC;IACxD,CAAC;IACD,OAAO,oBAAoB,CAAC;AAC9B,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,qBAAqB,EAAE,KAAK,EAAE,CAAC;IAC/B,oBAAoB,EAAE,KAAK,EAAE,CAAC;AAChC,CAAC"}
|
package/package.json
CHANGED