@http-client-toolkit/core 0.0.1

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/lib/index.cjs ADDED
@@ -0,0 +1,615 @@
1
+ 'use strict';
2
+
3
+ var axios = require('axios');
4
+ var zod = require('zod');
5
+ var crypto = require('crypto');
6
+
7
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
8
+
9
+ var axios__default = /*#__PURE__*/_interopDefault(axios);
10
+
11
+ var __async = (__this, __arguments, generator) => {
12
+ return new Promise((resolve, reject) => {
13
+ var fulfilled = (value) => {
14
+ try {
15
+ step(generator.next(value));
16
+ } catch (e) {
17
+ reject(e);
18
+ }
19
+ };
20
+ var rejected = (value) => {
21
+ try {
22
+ step(generator.throw(value));
23
+ } catch (e) {
24
+ reject(e);
25
+ }
26
+ };
27
+ var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
28
+ step((generator = generator.apply(__this, __arguments)).next());
29
+ });
30
+ };
31
+
32
+ // src/errors/http-client-error.ts
33
+ var HttpClientError = class extends Error {
34
+ constructor(message, statusCode) {
35
+ super(message);
36
+ this.name = "HttpClientError";
37
+ this.statusCode = statusCode;
38
+ Object.setPrototypeOf(this, new.target.prototype);
39
+ }
40
+ };
41
+ var AdaptiveConfigSchema = zod.z.object({
42
+ monitoringWindowMs: zod.z.number().positive().default(15 * 60 * 1e3),
43
+ // 15 minutes
44
+ highActivityThreshold: zod.z.number().min(0).default(10),
45
+ // requests per window
46
+ moderateActivityThreshold: zod.z.number().min(0).default(3),
47
+ recalculationIntervalMs: zod.z.number().positive().default(3e4),
48
+ // 30 seconds
49
+ sustainedInactivityThresholdMs: zod.z.number().positive().default(30 * 60 * 1e3),
50
+ // 30 minutes
51
+ backgroundPauseOnIncreasingTrend: zod.z.boolean().default(true),
52
+ maxUserScaling: zod.z.number().positive().default(2),
53
+ // don't exceed 2x capacity
54
+ minUserReserved: zod.z.number().min(0).default(5)
55
+ // requests minimum
56
+ }).refine(
57
+ (data) => {
58
+ return data.moderateActivityThreshold < data.highActivityThreshold;
59
+ },
60
+ {
61
+ message: "moderateActivityThreshold must be less than highActivityThreshold"
62
+ }
63
+ );
64
+ function hashRequest(endpoint, params = {}) {
65
+ const requestString = JSON.stringify({
66
+ endpoint,
67
+ params: sortObject(params)
68
+ });
69
+ return crypto.createHash("sha256").update(requestString).digest("hex");
70
+ }
71
+ function sortObject(obj) {
72
+ if (obj === null) {
73
+ return null;
74
+ }
75
+ const objType = typeof obj;
76
+ if (objType === "undefined" || objType === "string") {
77
+ return obj;
78
+ }
79
+ if (objType === "number" || objType === "boolean") {
80
+ return String(obj);
81
+ }
82
+ if (Array.isArray(obj)) {
83
+ return obj.map(sortObject);
84
+ }
85
+ const sorted = {};
86
+ const keys = Object.keys(obj).sort();
87
+ for (const key of keys) {
88
+ const value = obj[key];
89
+ const normalisedValue = sortObject(value);
90
+ if (normalisedValue !== void 0) {
91
+ sorted[key] = normalisedValue;
92
+ }
93
+ }
94
+ return sorted;
95
+ }
96
+
97
+ // src/stores/rate-limit-config.ts
98
+ var DEFAULT_RATE_LIMIT = {
99
+ limit: 60,
100
+ windowMs: 6e4
101
+ };
102
+
103
+ // src/stores/adaptive-capacity-calculator.ts
104
+ var AdaptiveCapacityCalculator = class {
105
+ constructor(config = {}) {
106
+ this.config = AdaptiveConfigSchema.parse(config);
107
+ }
108
+ calculateDynamicCapacity(resource, totalLimit, activityMetrics) {
109
+ const recentUserActivity = this.getRecentActivity(
110
+ activityMetrics.recentUserRequests
111
+ );
112
+ const activityTrend = this.calculateActivityTrend(
113
+ activityMetrics.recentUserRequests
114
+ );
115
+ if (recentUserActivity >= this.config.highActivityThreshold) {
116
+ const userCapacity = Math.min(
117
+ totalLimit * 0.9,
118
+ Math.floor(totalLimit * 0.5 * this.config.maxUserScaling)
119
+ // 50% base * scaling factor
120
+ );
121
+ return {
122
+ userReserved: userCapacity,
123
+ backgroundMax: totalLimit - userCapacity,
124
+ backgroundPaused: this.config.backgroundPauseOnIncreasingTrend && activityTrend === "increasing",
125
+ reason: `High user activity (${recentUserActivity} requests/${this.config.monitoringWindowMs / 6e4}min) - prioritizing users`
126
+ };
127
+ }
128
+ if (recentUserActivity >= this.config.moderateActivityThreshold) {
129
+ const userMultiplier = this.getUserMultiplier(
130
+ recentUserActivity,
131
+ activityTrend
132
+ );
133
+ const baseUserCapacity2 = Math.floor(totalLimit * 0.4);
134
+ const dynamicUserCapacity = Math.min(
135
+ totalLimit * 0.7,
136
+ baseUserCapacity2 * userMultiplier
137
+ );
138
+ return {
139
+ userReserved: dynamicUserCapacity,
140
+ backgroundMax: totalLimit - dynamicUserCapacity,
141
+ backgroundPaused: false,
142
+ reason: `Moderate user activity - dynamic scaling (${userMultiplier.toFixed(1)}x user capacity)`
143
+ };
144
+ }
145
+ if (recentUserActivity === 0) {
146
+ if (activityMetrics.recentUserRequests.length === 0 && activityMetrics.recentBackgroundRequests.length === 0) {
147
+ const baseUserCapacity2 = Math.floor(totalLimit * 0.3);
148
+ return {
149
+ userReserved: Math.max(baseUserCapacity2, this.config.minUserReserved),
150
+ backgroundMax: totalLimit - Math.max(baseUserCapacity2, this.config.minUserReserved),
151
+ backgroundPaused: false,
152
+ reason: "Initial state - default capacity allocation"
153
+ };
154
+ }
155
+ if (activityMetrics.recentUserRequests.length === 0) {
156
+ return {
157
+ userReserved: this.config.minUserReserved,
158
+ // Minimal safety buffer
159
+ backgroundMax: totalLimit - this.config.minUserReserved,
160
+ backgroundPaused: false,
161
+ reason: "No user activity yet - background scale up with minimal user buffer"
162
+ };
163
+ }
164
+ const sustainedInactivity = this.getSustainedInactivityPeriod(
165
+ activityMetrics.recentUserRequests
166
+ );
167
+ if (sustainedInactivity > this.config.sustainedInactivityThresholdMs) {
168
+ return {
169
+ userReserved: 0,
170
+ // No reservation - background gets everything!
171
+ backgroundMax: totalLimit,
172
+ // Full capacity available
173
+ backgroundPaused: false,
174
+ reason: `Sustained zero activity (${Math.floor(sustainedInactivity / 6e4)}+ min) - full capacity to background`
175
+ };
176
+ } else {
177
+ return {
178
+ userReserved: this.config.minUserReserved,
179
+ // Minimal safety buffer
180
+ backgroundMax: totalLimit - this.config.minUserReserved,
181
+ backgroundPaused: false,
182
+ reason: "Recent zero activity - background scale up with minimal user buffer"
183
+ };
184
+ }
185
+ }
186
+ const baseUserCapacity = Math.floor(totalLimit * 0.3);
187
+ return {
188
+ userReserved: Math.max(baseUserCapacity, this.config.minUserReserved),
189
+ backgroundMax: totalLimit - Math.max(baseUserCapacity, this.config.minUserReserved),
190
+ backgroundPaused: false,
191
+ reason: `Low user activity (${recentUserActivity} requests/${this.config.monitoringWindowMs / 6e4}min) - background scale up`
192
+ };
193
+ }
194
+ getRecentActivity(requests) {
195
+ const cutoff = Date.now() - this.config.monitoringWindowMs;
196
+ return requests.filter((timestamp) => timestamp > cutoff).length;
197
+ }
198
+ calculateActivityTrend(requests) {
199
+ const now = Date.now();
200
+ const windowSize = this.config.monitoringWindowMs / 3;
201
+ const recent = requests.filter((t) => t > now - windowSize).length;
202
+ const previous = requests.filter(
203
+ (t) => t > now - 2 * windowSize && t <= now - windowSize
204
+ ).length;
205
+ if (recent === 0 && previous === 0) return "none";
206
+ if (recent > previous * 1.5) return "increasing";
207
+ if (recent < previous * 0.5) return "decreasing";
208
+ return "stable";
209
+ }
210
+ getUserMultiplier(activity, trend) {
211
+ let base = Math.min(
212
+ this.config.maxUserScaling,
213
+ 1 + activity / this.config.highActivityThreshold
214
+ );
215
+ if (trend === "increasing") base *= 1.2;
216
+ if (trend === "decreasing") base *= 0.8;
217
+ return Math.max(1, base);
218
+ }
219
+ getSustainedInactivityPeriod(requests) {
220
+ if (requests.length === 0) {
221
+ return 0;
222
+ }
223
+ const lastRequest = Math.max(...requests);
224
+ return Date.now() - lastRequest;
225
+ }
226
+ };
227
+
228
+ // src/http-client/http-client.ts
229
+ var DEFAULT_RATE_LIMIT_HEADER_NAMES = {
230
+ retryAfter: ["retry-after"],
231
+ limit: ["ratelimit-limit", "x-ratelimit-limit", "rate-limit-limit"],
232
+ remaining: [
233
+ "ratelimit-remaining",
234
+ "x-ratelimit-remaining",
235
+ "rate-limit-remaining"
236
+ ],
237
+ reset: ["ratelimit-reset", "x-ratelimit-reset", "rate-limit-reset"],
238
+ combined: ["ratelimit"]
239
+ };
240
+ function wait(ms, signal) {
241
+ return new Promise((resolve, reject) => {
242
+ const timer = setTimeout(() => {
243
+ if (signal) {
244
+ signal.removeEventListener("abort", onAbort);
245
+ }
246
+ resolve();
247
+ }, ms);
248
+ function onAbort() {
249
+ clearTimeout(timer);
250
+ const err = new Error("Aborted");
251
+ err.name = "AbortError";
252
+ reject(err);
253
+ }
254
+ if (signal) {
255
+ if (signal.aborted) {
256
+ onAbort();
257
+ } else {
258
+ signal.addEventListener("abort", onAbort, { once: true });
259
+ }
260
+ }
261
+ });
262
+ }
263
+ var HttpClient = class {
264
+ constructor(stores = {}, options = {}) {
265
+ this.serverCooldowns = /* @__PURE__ */ new Map();
266
+ var _a, _b, _c;
267
+ this._http = axios__default.default.create();
268
+ this.stores = stores;
269
+ this.options = {
270
+ defaultCacheTTL: (_a = options.defaultCacheTTL) != null ? _a : 3600,
271
+ throwOnRateLimit: (_b = options.throwOnRateLimit) != null ? _b : true,
272
+ maxWaitTime: (_c = options.maxWaitTime) != null ? _c : 6e4,
273
+ responseTransformer: options.responseTransformer,
274
+ errorHandler: options.errorHandler,
275
+ responseHandler: options.responseHandler,
276
+ rateLimitHeaders: this.normalizeRateLimitHeaders(
277
+ options.rateLimitHeaders
278
+ )
279
+ };
280
+ }
281
+ normalizeRateLimitHeaders(customHeaders) {
282
+ return {
283
+ retryAfter: this.normalizeHeaderNames(
284
+ customHeaders == null ? void 0 : customHeaders.retryAfter,
285
+ DEFAULT_RATE_LIMIT_HEADER_NAMES.retryAfter
286
+ ),
287
+ limit: this.normalizeHeaderNames(
288
+ customHeaders == null ? void 0 : customHeaders.limit,
289
+ DEFAULT_RATE_LIMIT_HEADER_NAMES.limit
290
+ ),
291
+ remaining: this.normalizeHeaderNames(
292
+ customHeaders == null ? void 0 : customHeaders.remaining,
293
+ DEFAULT_RATE_LIMIT_HEADER_NAMES.remaining
294
+ ),
295
+ reset: this.normalizeHeaderNames(
296
+ customHeaders == null ? void 0 : customHeaders.reset,
297
+ DEFAULT_RATE_LIMIT_HEADER_NAMES.reset
298
+ ),
299
+ combined: this.normalizeHeaderNames(
300
+ customHeaders == null ? void 0 : customHeaders.combined,
301
+ DEFAULT_RATE_LIMIT_HEADER_NAMES.combined
302
+ )
303
+ };
304
+ }
305
+ normalizeHeaderNames(providedNames, defaultNames) {
306
+ if (!providedNames || providedNames.length === 0) {
307
+ return [...defaultNames];
308
+ }
309
+ const customNames = providedNames.map((name) => name.trim().toLowerCase()).filter(Boolean);
310
+ if (customNames.length === 0) {
311
+ return [...defaultNames];
312
+ }
313
+ return [.../* @__PURE__ */ new Set([...customNames, ...defaultNames])];
314
+ }
315
+ /**
316
+ * Infer the resource name from the endpoint URL
317
+ * @param url The full URL or endpoint path
318
+ * @returns The resource name for rate limiting
319
+ */
320
+ inferResource(url) {
321
+ try {
322
+ const urlObj = new URL(url);
323
+ const segments = urlObj.pathname.split("/").filter(Boolean);
324
+ return segments[segments.length - 1] || "unknown";
325
+ } catch (e) {
326
+ return "unknown";
327
+ }
328
+ }
329
+ /**
330
+ * Extract endpoint and params from URL for request hashing
331
+ * @param url The full URL
332
+ * @returns Object with endpoint and params for hashing
333
+ */
334
+ parseUrlForHashing(url) {
335
+ const urlObj = new URL(url);
336
+ const endpoint = `${urlObj.origin}${urlObj.pathname}`;
337
+ const params = {};
338
+ urlObj.searchParams.forEach((value, key) => {
339
+ const existing = params[key];
340
+ if (existing === void 0) {
341
+ params[key] = value;
342
+ return;
343
+ }
344
+ if (Array.isArray(existing)) {
345
+ existing.push(value);
346
+ return;
347
+ }
348
+ params[key] = [existing, value];
349
+ });
350
+ return { endpoint, params };
351
+ }
352
+ getOriginScope(url) {
353
+ try {
354
+ return new URL(url).origin;
355
+ } catch (e) {
356
+ return "unknown";
357
+ }
358
+ }
359
+ getHeaderValue(headers, names) {
360
+ var _a;
361
+ if (!headers) {
362
+ return void 0;
363
+ }
364
+ for (const rawName of names) {
365
+ const name = rawName.toLowerCase();
366
+ const value = (_a = headers[name]) != null ? _a : headers[rawName];
367
+ if (typeof value === "string") {
368
+ return value;
369
+ }
370
+ if (Array.isArray(value) && value.length > 0) {
371
+ const first = value.find((entry) => typeof entry === "string");
372
+ if (typeof first === "string") {
373
+ return first;
374
+ }
375
+ }
376
+ }
377
+ return void 0;
378
+ }
379
+ parseIntegerHeader(value) {
380
+ if (!value) {
381
+ return void 0;
382
+ }
383
+ const parsed = Number.parseInt(value.trim(), 10);
384
+ if (!Number.isFinite(parsed) || parsed < 0) {
385
+ return void 0;
386
+ }
387
+ return parsed;
388
+ }
389
+ parseRetryAfterMs(value) {
390
+ if (!value) {
391
+ return void 0;
392
+ }
393
+ const numeric = Number.parseInt(value.trim(), 10);
394
+ if (Number.isFinite(numeric) && numeric >= 0) {
395
+ return numeric * 1e3;
396
+ }
397
+ const dateMs = Date.parse(value);
398
+ if (!Number.isFinite(dateMs)) {
399
+ return void 0;
400
+ }
401
+ return Math.max(0, dateMs - Date.now());
402
+ }
403
+ parseResetMs(value) {
404
+ const parsed = this.parseIntegerHeader(value);
405
+ if (parsed === void 0) {
406
+ return void 0;
407
+ }
408
+ if (parsed === 0) {
409
+ return 0;
410
+ }
411
+ const nowSeconds = Math.floor(Date.now() / 1e3);
412
+ if (parsed > nowSeconds + 1) {
413
+ return Math.max(0, (parsed - nowSeconds) * 1e3);
414
+ }
415
+ return parsed * 1e3;
416
+ }
417
+ parseCombinedRateLimitHeader(value) {
418
+ if (!value) {
419
+ return {};
420
+ }
421
+ const remainingMatch = value.match(/(?:^|[;,])\s*r\s*=\s*(\d+)/i);
422
+ const resetMatch = value.match(/(?:^|[;,])\s*t\s*=\s*(\d+)/i);
423
+ return {
424
+ remaining: remainingMatch ? this.parseIntegerHeader(remainingMatch[1]) : void 0,
425
+ resetMs: resetMatch ? this.parseResetMs(resetMatch[1]) : void 0
426
+ };
427
+ }
428
+ applyServerRateLimitHints(url, headers, statusCode) {
429
+ if (!headers) {
430
+ return;
431
+ }
432
+ const config = this.options.rateLimitHeaders;
433
+ const retryAfterRaw = this.getHeaderValue(headers, config.retryAfter);
434
+ const resetRaw = this.getHeaderValue(headers, config.reset);
435
+ const remainingRaw = this.getHeaderValue(headers, config.remaining);
436
+ const combinedRaw = this.getHeaderValue(headers, config.combined);
437
+ const retryAfterMs = this.parseRetryAfterMs(retryAfterRaw);
438
+ const resetMs = this.parseResetMs(resetRaw);
439
+ const remaining = this.parseIntegerHeader(remainingRaw);
440
+ const combined = this.parseCombinedRateLimitHeader(combinedRaw);
441
+ const effectiveRemaining = remaining != null ? remaining : combined.remaining;
442
+ const effectiveResetMs = resetMs != null ? resetMs : combined.resetMs;
443
+ const hasRateLimitErrorStatus = statusCode === 429 || statusCode === 503;
444
+ let waitMs;
445
+ if (retryAfterMs !== void 0) {
446
+ waitMs = retryAfterMs;
447
+ } else if (effectiveResetMs !== void 0 && (hasRateLimitErrorStatus || effectiveRemaining !== void 0 && effectiveRemaining <= 0)) {
448
+ waitMs = effectiveResetMs;
449
+ }
450
+ if (waitMs === void 0 || waitMs <= 0) {
451
+ return;
452
+ }
453
+ const scope = this.getOriginScope(url);
454
+ this.serverCooldowns.set(scope, Date.now() + waitMs);
455
+ }
456
+ enforceServerCooldown(url, signal) {
457
+ return __async(this, null, function* () {
458
+ const scope = this.getOriginScope(url);
459
+ const startedAt = Date.now();
460
+ while (true) {
461
+ const cooldownUntil = this.serverCooldowns.get(scope);
462
+ if (!cooldownUntil) {
463
+ return;
464
+ }
465
+ const waitMs = cooldownUntil - Date.now();
466
+ if (waitMs <= 0) {
467
+ this.serverCooldowns.delete(scope);
468
+ return;
469
+ }
470
+ if (this.options.throwOnRateLimit) {
471
+ throw new Error(
472
+ `Rate limit exceeded for origin '${scope}'. Wait ${waitMs}ms before retrying.`
473
+ );
474
+ }
475
+ const elapsedMs = Date.now() - startedAt;
476
+ const remainingWaitBudgetMs = this.options.maxWaitTime - elapsedMs;
477
+ if (remainingWaitBudgetMs <= 0) {
478
+ throw new Error(
479
+ `Rate limit wait exceeded maxWaitTime (${this.options.maxWaitTime}ms) for origin '${scope}'.`
480
+ );
481
+ }
482
+ yield wait(Math.min(waitMs, remainingWaitBudgetMs), signal);
483
+ }
484
+ });
485
+ }
486
+ enforceStoreRateLimit(resource, priority, signal) {
487
+ return __async(this, null, function* () {
488
+ const rateLimit = this.stores.rateLimit;
489
+ const startedAt = Date.now();
490
+ if (this.options.throwOnRateLimit) {
491
+ const canProceed = yield rateLimit.canProceed(resource, priority);
492
+ if (!canProceed) {
493
+ const waitTime = yield rateLimit.getWaitTime(resource, priority);
494
+ throw new Error(
495
+ `Rate limit exceeded for resource '${resource}'. Wait ${waitTime}ms before retrying.`
496
+ );
497
+ }
498
+ return;
499
+ }
500
+ while (!(yield rateLimit.canProceed(resource, priority))) {
501
+ const suggestedWaitMs = yield rateLimit.getWaitTime(resource, priority);
502
+ const elapsedMs = Date.now() - startedAt;
503
+ const remainingWaitBudgetMs = this.options.maxWaitTime - elapsedMs;
504
+ if (remainingWaitBudgetMs <= 0) {
505
+ throw new Error(
506
+ `Rate limit wait exceeded maxWaitTime (${this.options.maxWaitTime}ms) for resource '${resource}'.`
507
+ );
508
+ }
509
+ const waitTime = suggestedWaitMs > 0 ? Math.min(suggestedWaitMs, remainingWaitBudgetMs) : Math.min(25, remainingWaitBudgetMs);
510
+ yield wait(waitTime, signal);
511
+ }
512
+ });
513
+ }
514
+ generateClientError(err) {
515
+ var _a, _b, _c;
516
+ if (this.options.errorHandler) {
517
+ return this.options.errorHandler(err);
518
+ }
519
+ if (err instanceof HttpClientError) {
520
+ return err;
521
+ }
522
+ const error = err;
523
+ const statusCode = (_a = error.response) == null ? void 0 : _a.status;
524
+ const errorMessage = (_c = (_b = error.response) == null ? void 0 : _b.data) == null ? void 0 : _c.message;
525
+ const message = `${error.message}${errorMessage ? `, ${errorMessage}` : ""}`;
526
+ return new HttpClientError(message, statusCode);
527
+ }
528
+ get(_0) {
529
+ return __async(this, arguments, function* (url, options = {}) {
530
+ const { signal, priority = "background" } = options;
531
+ const { endpoint, params } = this.parseUrlForHashing(url);
532
+ const hash = hashRequest(endpoint, params);
533
+ const resource = this.inferResource(url);
534
+ try {
535
+ yield this.enforceServerCooldown(url, signal);
536
+ if (this.stores.cache) {
537
+ const cachedResult = yield this.stores.cache.get(hash);
538
+ if (cachedResult !== void 0) {
539
+ return cachedResult;
540
+ }
541
+ }
542
+ if (this.stores.dedupe) {
543
+ const existingResult = yield this.stores.dedupe.waitFor(hash);
544
+ if (existingResult !== void 0) {
545
+ return existingResult;
546
+ }
547
+ if (this.stores.dedupe.registerOrJoin) {
548
+ const registration = yield this.stores.dedupe.registerOrJoin(hash);
549
+ if (!registration.isOwner) {
550
+ const joinedResult = yield this.stores.dedupe.waitFor(hash);
551
+ if (joinedResult !== void 0) {
552
+ return joinedResult;
553
+ }
554
+ }
555
+ } else {
556
+ yield this.stores.dedupe.register(hash);
557
+ }
558
+ }
559
+ if (this.stores.rateLimit) {
560
+ yield this.enforceStoreRateLimit(resource, priority, signal);
561
+ }
562
+ const response = yield this._http.get(url, { signal });
563
+ this.applyServerRateLimitHints(
564
+ url,
565
+ response.headers,
566
+ response.status
567
+ );
568
+ let data = response.data;
569
+ if (this.options.responseTransformer && data) {
570
+ data = this.options.responseTransformer(data);
571
+ }
572
+ if (this.options.responseHandler) {
573
+ data = this.options.responseHandler(data);
574
+ }
575
+ const result = data;
576
+ if (this.stores.rateLimit) {
577
+ const rateLimit = this.stores.rateLimit;
578
+ yield rateLimit.record(resource, priority);
579
+ }
580
+ if (this.stores.cache) {
581
+ yield this.stores.cache.set(hash, result, this.options.defaultCacheTTL);
582
+ }
583
+ if (this.stores.dedupe) {
584
+ yield this.stores.dedupe.complete(hash, result);
585
+ }
586
+ return result;
587
+ } catch (error) {
588
+ const axiosError = error;
589
+ if (axiosError.response) {
590
+ this.applyServerRateLimitHints(
591
+ url,
592
+ axiosError.response.headers,
593
+ axiosError.response.status
594
+ );
595
+ }
596
+ if (this.stores.dedupe) {
597
+ yield this.stores.dedupe.fail(hash, error);
598
+ }
599
+ if (error instanceof Error && error.name === "AbortError") {
600
+ throw error;
601
+ }
602
+ throw this.generateClientError(error);
603
+ }
604
+ });
605
+ }
606
+ };
607
+
608
+ exports.AdaptiveCapacityCalculator = AdaptiveCapacityCalculator;
609
+ exports.AdaptiveConfigSchema = AdaptiveConfigSchema;
610
+ exports.DEFAULT_RATE_LIMIT = DEFAULT_RATE_LIMIT;
611
+ exports.HttpClient = HttpClient;
612
+ exports.HttpClientError = HttpClientError;
613
+ exports.hashRequest = hashRequest;
614
+ //# sourceMappingURL=index.cjs.map
615
+ //# sourceMappingURL=index.cjs.map