rezo 1.0.44 → 1.0.46

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.
Files changed (37) hide show
  1. package/dist/adapters/entries/curl.d.ts +115 -0
  2. package/dist/adapters/entries/fetch.d.ts +115 -0
  3. package/dist/adapters/entries/http.d.ts +115 -0
  4. package/dist/adapters/entries/http2.d.ts +115 -0
  5. package/dist/adapters/entries/react-native.d.ts +115 -0
  6. package/dist/adapters/entries/xhr.d.ts +115 -0
  7. package/dist/adapters/fetch.cjs +18 -0
  8. package/dist/adapters/fetch.js +18 -0
  9. package/dist/adapters/http.cjs +22 -4
  10. package/dist/adapters/http.js +22 -4
  11. package/dist/adapters/http2.cjs +21 -0
  12. package/dist/adapters/http2.js +21 -0
  13. package/dist/adapters/index.cjs +6 -6
  14. package/dist/adapters/xhr.cjs +19 -0
  15. package/dist/adapters/xhr.js +19 -0
  16. package/dist/cache/index.cjs +9 -9
  17. package/dist/core/hooks.cjs +4 -2
  18. package/dist/core/hooks.js +4 -2
  19. package/dist/crawler/index.cjs +40 -40
  20. package/dist/crawler.d.ts +115 -0
  21. package/dist/entries/crawler.cjs +5 -5
  22. package/dist/index.cjs +27 -27
  23. package/dist/index.d.ts +115 -0
  24. package/dist/internal/agents/index.cjs +10 -10
  25. package/dist/platform/browser.d.ts +115 -0
  26. package/dist/platform/bun.d.ts +115 -0
  27. package/dist/platform/deno.d.ts +115 -0
  28. package/dist/platform/node.d.ts +115 -0
  29. package/dist/platform/react-native.d.ts +115 -0
  30. package/dist/platform/worker.d.ts +115 -0
  31. package/dist/proxy/index.cjs +5 -5
  32. package/dist/proxy/index.js +1 -1
  33. package/dist/queue/index.cjs +8 -8
  34. package/dist/responses/universal/index.cjs +11 -11
  35. package/dist/utils/rate-limit-wait.cjs +217 -0
  36. package/dist/utils/rate-limit-wait.js +208 -0
  37. package/package.json +1 -1
@@ -1,40 +1,40 @@
1
- const _mod_uzdw07 = require('./crawler.cjs');
2
- exports.Crawler = _mod_uzdw07.Crawler;;
3
- const _mod_fk2i9s = require('./crawler-options.cjs');
4
- exports.CrawlerOptions = _mod_fk2i9s.CrawlerOptions;;
5
- const _mod_y9972f = require('./plugin/robots-txt.cjs');
6
- exports.RobotsTxt = _mod_y9972f.RobotsTxt;;
7
- const _mod_y7t1zo = require('./plugin/file-cacher.cjs');
8
- exports.FileCacher = _mod_y7t1zo.FileCacher;;
9
- const _mod_ecu03i = require('./plugin/url-store.cjs');
10
- exports.UrlStore = _mod_ecu03i.UrlStore;;
11
- const _mod_kxfnq7 = require('./plugin/navigation-history.cjs');
12
- exports.NavigationHistory = _mod_kxfnq7.NavigationHistory;;
13
- const _mod_bg9vts = require('./addon/oxylabs/index.cjs');
14
- exports.Oxylabs = _mod_bg9vts.Oxylabs;;
15
- const _mod_zd2i1t = require('./addon/oxylabs/options.cjs');
16
- exports.OXYLABS_BROWSER_TYPES = _mod_zd2i1t.OXYLABS_BROWSER_TYPES;
17
- exports.OXYLABS_COMMON_LOCALES = _mod_zd2i1t.OXYLABS_COMMON_LOCALES;
18
- exports.OXYLABS_COMMON_GEO_LOCATIONS = _mod_zd2i1t.OXYLABS_COMMON_GEO_LOCATIONS;
19
- exports.OXYLABS_US_STATES = _mod_zd2i1t.OXYLABS_US_STATES;
20
- exports.OXYLABS_EUROPEAN_COUNTRIES = _mod_zd2i1t.OXYLABS_EUROPEAN_COUNTRIES;
21
- exports.OXYLABS_ASIAN_COUNTRIES = _mod_zd2i1t.OXYLABS_ASIAN_COUNTRIES;
22
- exports.getRandomOxylabsBrowserType = _mod_zd2i1t.getRandomBrowserType;
23
- exports.getRandomOxylabsLocale = _mod_zd2i1t.getRandomLocale;
24
- exports.getRandomOxylabsGeoLocation = _mod_zd2i1t.getRandomGeoLocation;;
25
- const _mod_gr8483 = require('./addon/decodo/index.cjs');
26
- exports.Decodo = _mod_gr8483.Decodo;;
27
- const _mod_km63k6 = require('./addon/decodo/options.cjs');
28
- exports.DECODO_DEVICE_TYPES = _mod_km63k6.DECODO_DEVICE_TYPES;
29
- exports.DECODO_HEADLESS_MODES = _mod_km63k6.DECODO_HEADLESS_MODES;
30
- exports.DECODO_COMMON_LOCALES = _mod_km63k6.DECODO_COMMON_LOCALES;
31
- exports.DECODO_COMMON_COUNTRIES = _mod_km63k6.DECODO_COMMON_COUNTRIES;
32
- exports.DECODO_EUROPEAN_COUNTRIES = _mod_km63k6.DECODO_EUROPEAN_COUNTRIES;
33
- exports.DECODO_ASIAN_COUNTRIES = _mod_km63k6.DECODO_ASIAN_COUNTRIES;
34
- exports.DECODO_US_STATES = _mod_km63k6.DECODO_US_STATES;
35
- exports.DECODO_COMMON_CITIES = _mod_km63k6.DECODO_COMMON_CITIES;
36
- exports.getRandomDecodoDeviceType = _mod_km63k6.getRandomDeviceType;
37
- exports.getRandomDecodoLocale = _mod_km63k6.getRandomLocale;
38
- exports.getRandomDecodoCountry = _mod_km63k6.getRandomCountry;
39
- exports.getRandomDecodoCity = _mod_km63k6.getRandomCity;
40
- exports.generateDecodoSessionId = _mod_km63k6.generateSessionId;;
1
+ const _mod_33fvzd = require('./crawler.cjs');
2
+ exports.Crawler = _mod_33fvzd.Crawler;;
3
+ const _mod_1ldv58 = require('./crawler-options.cjs');
4
+ exports.CrawlerOptions = _mod_1ldv58.CrawlerOptions;;
5
+ const _mod_imehct = require('./plugin/robots-txt.cjs');
6
+ exports.RobotsTxt = _mod_imehct.RobotsTxt;;
7
+ const _mod_u0gyun = require('./plugin/file-cacher.cjs');
8
+ exports.FileCacher = _mod_u0gyun.FileCacher;;
9
+ const _mod_9wk5ke = require('./plugin/url-store.cjs');
10
+ exports.UrlStore = _mod_9wk5ke.UrlStore;;
11
+ const _mod_yqhjwv = require('./plugin/navigation-history.cjs');
12
+ exports.NavigationHistory = _mod_yqhjwv.NavigationHistory;;
13
+ const _mod_klxadq = require('./addon/oxylabs/index.cjs');
14
+ exports.Oxylabs = _mod_klxadq.Oxylabs;;
15
+ const _mod_n6jnu4 = require('./addon/oxylabs/options.cjs');
16
+ exports.OXYLABS_BROWSER_TYPES = _mod_n6jnu4.OXYLABS_BROWSER_TYPES;
17
+ exports.OXYLABS_COMMON_LOCALES = _mod_n6jnu4.OXYLABS_COMMON_LOCALES;
18
+ exports.OXYLABS_COMMON_GEO_LOCATIONS = _mod_n6jnu4.OXYLABS_COMMON_GEO_LOCATIONS;
19
+ exports.OXYLABS_US_STATES = _mod_n6jnu4.OXYLABS_US_STATES;
20
+ exports.OXYLABS_EUROPEAN_COUNTRIES = _mod_n6jnu4.OXYLABS_EUROPEAN_COUNTRIES;
21
+ exports.OXYLABS_ASIAN_COUNTRIES = _mod_n6jnu4.OXYLABS_ASIAN_COUNTRIES;
22
+ exports.getRandomOxylabsBrowserType = _mod_n6jnu4.getRandomBrowserType;
23
+ exports.getRandomOxylabsLocale = _mod_n6jnu4.getRandomLocale;
24
+ exports.getRandomOxylabsGeoLocation = _mod_n6jnu4.getRandomGeoLocation;;
25
+ const _mod_sjw00p = require('./addon/decodo/index.cjs');
26
+ exports.Decodo = _mod_sjw00p.Decodo;;
27
+ const _mod_f5prd7 = require('./addon/decodo/options.cjs');
28
+ exports.DECODO_DEVICE_TYPES = _mod_f5prd7.DECODO_DEVICE_TYPES;
29
+ exports.DECODO_HEADLESS_MODES = _mod_f5prd7.DECODO_HEADLESS_MODES;
30
+ exports.DECODO_COMMON_LOCALES = _mod_f5prd7.DECODO_COMMON_LOCALES;
31
+ exports.DECODO_COMMON_COUNTRIES = _mod_f5prd7.DECODO_COMMON_COUNTRIES;
32
+ exports.DECODO_EUROPEAN_COUNTRIES = _mod_f5prd7.DECODO_EUROPEAN_COUNTRIES;
33
+ exports.DECODO_ASIAN_COUNTRIES = _mod_f5prd7.DECODO_ASIAN_COUNTRIES;
34
+ exports.DECODO_US_STATES = _mod_f5prd7.DECODO_US_STATES;
35
+ exports.DECODO_COMMON_CITIES = _mod_f5prd7.DECODO_COMMON_CITIES;
36
+ exports.getRandomDecodoDeviceType = _mod_f5prd7.getRandomDeviceType;
37
+ exports.getRandomDecodoLocale = _mod_f5prd7.getRandomLocale;
38
+ exports.getRandomDecodoCountry = _mod_f5prd7.getRandomCountry;
39
+ exports.getRandomDecodoCity = _mod_f5prd7.getRandomCity;
40
+ exports.generateDecodoSessionId = _mod_f5prd7.generateSessionId;;
package/dist/crawler.d.ts CHANGED
@@ -1528,6 +1528,35 @@ export type OnTimeoutHook = (event: TimeoutEvent, config: RezoConfig) => void;
1528
1528
  * Use for cleanup, logging
1529
1529
  */
1530
1530
  export type OnAbortHook = (event: AbortEvent, config: RezoConfig) => void;
1531
+ /**
1532
+ * Rate limit wait event data - fired when waiting due to rate limiting
1533
+ */
1534
+ export interface RateLimitWaitEvent {
1535
+ /** HTTP status code that triggered the wait (e.g., 429, 503) */
1536
+ status: number;
1537
+ /** Time to wait in milliseconds */
1538
+ waitTime: number;
1539
+ /** Current wait attempt number (1-indexed) */
1540
+ attempt: number;
1541
+ /** Maximum wait attempts configured */
1542
+ maxAttempts: number;
1543
+ /** Where the wait time was extracted from */
1544
+ source: "header" | "body" | "function" | "default";
1545
+ /** The header or body path used (if applicable) */
1546
+ sourcePath?: string;
1547
+ /** URL being requested */
1548
+ url: string;
1549
+ /** HTTP method of the request */
1550
+ method: string;
1551
+ /** Timestamp when the wait started */
1552
+ timestamp: number;
1553
+ }
1554
+ /**
1555
+ * Hook called when rate limit wait occurs
1556
+ * Informational only - cannot abort the wait
1557
+ * Use for logging, monitoring, alerting
1558
+ */
1559
+ export type OnRateLimitWaitHook = (event: RateLimitWaitEvent, config: RezoConfig) => void | Promise<void>;
1531
1560
  /**
1532
1561
  * Hook called before a proxy is selected
1533
1562
  * Can return a specific proxy to override selection
@@ -1608,6 +1637,7 @@ export interface RezoHooks {
1608
1637
  onTls: OnTlsHook[];
1609
1638
  onTimeout: OnTimeoutHook[];
1610
1639
  onAbort: OnAbortHook[];
1640
+ onRateLimitWait: OnRateLimitWaitHook[];
1611
1641
  }
1612
1642
  /**
1613
1643
  * Configuration object that encapsulates comprehensive request execution metadata and response processing information.
@@ -2433,6 +2463,91 @@ export interface RezoRequestConfig<D = any> {
2433
2463
  /** Weather to stop or continue retry when certain condition is met*/
2434
2464
  condition?: (error: RezoError) => boolean | Promise<boolean>;
2435
2465
  };
2466
+ /**
2467
+ * Rate limit wait configuration - wait and retry when receiving rate limit responses.
2468
+ *
2469
+ * This feature runs BEFORE the retry system. When a rate-limiting status code is received,
2470
+ * the client will wait for the specified time and automatically retry the request.
2471
+ *
2472
+ * **Basic Usage:**
2473
+ * - `waitOnStatus: true` - Enable waiting on 429 status (default behavior)
2474
+ * - `waitOnStatus: [429, 503]` - Enable waiting on specific status codes
2475
+ *
2476
+ * **Wait Time Sources:**
2477
+ * - `'retry-after'` - Use standard Retry-After header (default)
2478
+ * - `{ header: 'X-RateLimit-Reset' }` - Use custom header
2479
+ * - `{ body: 'retry_after' }` - Extract from JSON response body
2480
+ * - Custom function for complex logic
2481
+ *
2482
+ * @example
2483
+ * ```typescript
2484
+ * // Wait on 429 using Retry-After header
2485
+ * await rezo.get(url, { waitOnStatus: true });
2486
+ *
2487
+ * // Wait on 429 using custom header
2488
+ * await rezo.get(url, {
2489
+ * waitOnStatus: true,
2490
+ * waitTimeSource: { header: 'X-RateLimit-Reset' }
2491
+ * });
2492
+ *
2493
+ * // Wait on 429 extracting time from JSON body
2494
+ * await rezo.get(url, {
2495
+ * waitOnStatus: true,
2496
+ * waitTimeSource: { body: 'data.retry_after' }
2497
+ * });
2498
+ *
2499
+ * // Custom function for complex APIs
2500
+ * await rezo.get(url, {
2501
+ * waitOnStatus: [429, 503],
2502
+ * waitTimeSource: (response) => {
2503
+ * const reset = response.headers.get('x-ratelimit-reset');
2504
+ * return reset ? parseInt(reset) - Math.floor(Date.now() / 1000) : null;
2505
+ * }
2506
+ * });
2507
+ * ```
2508
+ */
2509
+ waitOnStatus?: boolean | number[];
2510
+ /**
2511
+ * Where to extract the wait time from when rate-limited.
2512
+ *
2513
+ * - `'retry-after'` - Standard Retry-After header (default)
2514
+ * - `{ header: string }` - Custom header name (e.g., 'X-RateLimit-Reset')
2515
+ * - `{ body: string }` - JSON path in response body (e.g., 'data.retry_after', 'wait_seconds')
2516
+ * - Function - Custom logic receiving the response, return seconds to wait or null
2517
+ *
2518
+ * @default 'retry-after'
2519
+ */
2520
+ waitTimeSource?: "retry-after" | {
2521
+ header: string;
2522
+ } | {
2523
+ body: string;
2524
+ } | ((response: {
2525
+ status: number;
2526
+ headers: RezoHeaders;
2527
+ data?: any;
2528
+ }) => number | null);
2529
+ /**
2530
+ * Maximum time to wait for rate limit in milliseconds.
2531
+ * If the extracted wait time exceeds this, the request will fail instead of waiting.
2532
+ * Set to 0 for unlimited wait time.
2533
+ *
2534
+ * @default 60000 (60 seconds)
2535
+ */
2536
+ maxWaitTime?: number;
2537
+ /**
2538
+ * Default wait time in milliseconds if the wait time source returns nothing.
2539
+ * Used as fallback when Retry-After header or body path is not present.
2540
+ *
2541
+ * @default 1000 (1 second)
2542
+ */
2543
+ defaultWaitTime?: number;
2544
+ /**
2545
+ * Maximum number of wait attempts before giving up.
2546
+ * After this many waits, the request will proceed to retry logic or fail.
2547
+ *
2548
+ * @default 3
2549
+ */
2550
+ maxWaitAttempts?: number;
2436
2551
  /** Whether to use a secure context for HTTPS requests */
2437
2552
  useSecureContext?: boolean;
2438
2553
  /** Custom secure context for TLS connections */
@@ -1,5 +1,5 @@
1
- const _mod_398eir = require('../crawler/crawler.cjs');
2
- exports.Crawler = _mod_398eir.Crawler;;
3
- const _mod_m4xc57 = require('../crawler/crawler-options.cjs');
4
- exports.CrawlerOptions = _mod_m4xc57.CrawlerOptions;
5
- exports.Domain = _mod_m4xc57.Domain;;
1
+ const _mod_jqo3a7 = require('../crawler/crawler.cjs');
2
+ exports.Crawler = _mod_jqo3a7.Crawler;;
3
+ const _mod_5y7u4a = require('../crawler/crawler-options.cjs');
4
+ exports.CrawlerOptions = _mod_5y7u4a.CrawlerOptions;
5
+ exports.Domain = _mod_5y7u4a.Domain;;
package/dist/index.cjs CHANGED
@@ -1,30 +1,30 @@
1
- const _mod_y77uk1 = require('./core/rezo.cjs');
2
- exports.Rezo = _mod_y77uk1.Rezo;
3
- exports.createRezoInstance = _mod_y77uk1.createRezoInstance;
4
- exports.createDefaultInstance = _mod_y77uk1.createDefaultInstance;;
5
- const _mod_dc3jgu = require('./errors/rezo-error.cjs');
6
- exports.RezoError = _mod_dc3jgu.RezoError;
7
- exports.RezoErrorCode = _mod_dc3jgu.RezoErrorCode;;
8
- const _mod_o16xti = require('./utils/headers.cjs');
9
- exports.RezoHeaders = _mod_o16xti.RezoHeaders;;
10
- const _mod_y43k9y = require('./utils/form-data.cjs');
11
- exports.RezoFormData = _mod_y43k9y.RezoFormData;;
12
- const _mod_n8l01e = require('./utils/cookies.cjs');
13
- exports.RezoCookieJar = _mod_n8l01e.RezoCookieJar;
14
- exports.Cookie = _mod_n8l01e.Cookie;;
15
- const _mod_3ypli0 = require('./utils/curl.cjs');
16
- exports.toCurl = _mod_3ypli0.toCurl;
17
- exports.fromCurl = _mod_3ypli0.fromCurl;;
18
- const _mod_1mlx0a = require('./core/hooks.cjs');
19
- exports.createDefaultHooks = _mod_1mlx0a.createDefaultHooks;
20
- exports.mergeHooks = _mod_1mlx0a.mergeHooks;;
21
- const _mod_xo1ifa = require('./proxy/manager.cjs');
22
- exports.ProxyManager = _mod_xo1ifa.ProxyManager;;
23
- const _mod_77x7bf = require('./queue/index.cjs');
24
- exports.RezoQueue = _mod_77x7bf.RezoQueue;
25
- exports.HttpQueue = _mod_77x7bf.HttpQueue;
26
- exports.Priority = _mod_77x7bf.Priority;
27
- exports.HttpMethodPriority = _mod_77x7bf.HttpMethodPriority;;
1
+ const _mod_vh18hs = require('./core/rezo.cjs');
2
+ exports.Rezo = _mod_vh18hs.Rezo;
3
+ exports.createRezoInstance = _mod_vh18hs.createRezoInstance;
4
+ exports.createDefaultInstance = _mod_vh18hs.createDefaultInstance;;
5
+ const _mod_o1tm8z = require('./errors/rezo-error.cjs');
6
+ exports.RezoError = _mod_o1tm8z.RezoError;
7
+ exports.RezoErrorCode = _mod_o1tm8z.RezoErrorCode;;
8
+ const _mod_qs57sl = require('./utils/headers.cjs');
9
+ exports.RezoHeaders = _mod_qs57sl.RezoHeaders;;
10
+ const _mod_bcveiy = require('./utils/form-data.cjs');
11
+ exports.RezoFormData = _mod_bcveiy.RezoFormData;;
12
+ const _mod_j7t4t9 = require('./utils/cookies.cjs');
13
+ exports.RezoCookieJar = _mod_j7t4t9.RezoCookieJar;
14
+ exports.Cookie = _mod_j7t4t9.Cookie;;
15
+ const _mod_cuuq7u = require('./utils/curl.cjs');
16
+ exports.toCurl = _mod_cuuq7u.toCurl;
17
+ exports.fromCurl = _mod_cuuq7u.fromCurl;;
18
+ const _mod_psm01k = require('./core/hooks.cjs');
19
+ exports.createDefaultHooks = _mod_psm01k.createDefaultHooks;
20
+ exports.mergeHooks = _mod_psm01k.mergeHooks;;
21
+ const _mod_x2anu4 = require('./proxy/manager.cjs');
22
+ exports.ProxyManager = _mod_x2anu4.ProxyManager;;
23
+ const _mod_tnhdd0 = require('./queue/index.cjs');
24
+ exports.RezoQueue = _mod_tnhdd0.RezoQueue;
25
+ exports.HttpQueue = _mod_tnhdd0.HttpQueue;
26
+ exports.Priority = _mod_tnhdd0.Priority;
27
+ exports.HttpMethodPriority = _mod_tnhdd0.HttpMethodPriority;;
28
28
  const { RezoError } = require('./errors/rezo-error.cjs');
29
29
  const isRezoError = exports.isRezoError = RezoError.isRezoError;
30
30
  const Cancel = exports.Cancel = RezoError;
package/dist/index.d.ts CHANGED
@@ -1416,6 +1416,35 @@ export type OnTimeoutHook = (event: TimeoutEvent, config: RezoConfig) => void;
1416
1416
  * Use for cleanup, logging
1417
1417
  */
1418
1418
  export type OnAbortHook = (event: AbortEvent, config: RezoConfig) => void;
1419
+ /**
1420
+ * Rate limit wait event data - fired when waiting due to rate limiting
1421
+ */
1422
+ export interface RateLimitWaitEvent {
1423
+ /** HTTP status code that triggered the wait (e.g., 429, 503) */
1424
+ status: number;
1425
+ /** Time to wait in milliseconds */
1426
+ waitTime: number;
1427
+ /** Current wait attempt number (1-indexed) */
1428
+ attempt: number;
1429
+ /** Maximum wait attempts configured */
1430
+ maxAttempts: number;
1431
+ /** Where the wait time was extracted from */
1432
+ source: "header" | "body" | "function" | "default";
1433
+ /** The header or body path used (if applicable) */
1434
+ sourcePath?: string;
1435
+ /** URL being requested */
1436
+ url: string;
1437
+ /** HTTP method of the request */
1438
+ method: string;
1439
+ /** Timestamp when the wait started */
1440
+ timestamp: number;
1441
+ }
1442
+ /**
1443
+ * Hook called when rate limit wait occurs
1444
+ * Informational only - cannot abort the wait
1445
+ * Use for logging, monitoring, alerting
1446
+ */
1447
+ export type OnRateLimitWaitHook = (event: RateLimitWaitEvent, config: RezoConfig) => void | Promise<void>;
1419
1448
  /**
1420
1449
  * Hook called before a proxy is selected
1421
1450
  * Can return a specific proxy to override selection
@@ -1496,6 +1525,7 @@ export interface RezoHooks {
1496
1525
  onTls: OnTlsHook[];
1497
1526
  onTimeout: OnTimeoutHook[];
1498
1527
  onAbort: OnAbortHook[];
1528
+ onRateLimitWait: OnRateLimitWaitHook[];
1499
1529
  }
1500
1530
  /**
1501
1531
  * Create empty hooks object with all arrays initialized
@@ -2552,6 +2582,91 @@ export interface RezoRequestConfig<D = any> {
2552
2582
  /** Weather to stop or continue retry when certain condition is met*/
2553
2583
  condition?: (error: RezoError) => boolean | Promise<boolean>;
2554
2584
  };
2585
+ /**
2586
+ * Rate limit wait configuration - wait and retry when receiving rate limit responses.
2587
+ *
2588
+ * This feature runs BEFORE the retry system. When a rate-limiting status code is received,
2589
+ * the client will wait for the specified time and automatically retry the request.
2590
+ *
2591
+ * **Basic Usage:**
2592
+ * - `waitOnStatus: true` - Enable waiting on 429 status (default behavior)
2593
+ * - `waitOnStatus: [429, 503]` - Enable waiting on specific status codes
2594
+ *
2595
+ * **Wait Time Sources:**
2596
+ * - `'retry-after'` - Use standard Retry-After header (default)
2597
+ * - `{ header: 'X-RateLimit-Reset' }` - Use custom header
2598
+ * - `{ body: 'retry_after' }` - Extract from JSON response body
2599
+ * - Custom function for complex logic
2600
+ *
2601
+ * @example
2602
+ * ```typescript
2603
+ * // Wait on 429 using Retry-After header
2604
+ * await rezo.get(url, { waitOnStatus: true });
2605
+ *
2606
+ * // Wait on 429 using custom header
2607
+ * await rezo.get(url, {
2608
+ * waitOnStatus: true,
2609
+ * waitTimeSource: { header: 'X-RateLimit-Reset' }
2610
+ * });
2611
+ *
2612
+ * // Wait on 429 extracting time from JSON body
2613
+ * await rezo.get(url, {
2614
+ * waitOnStatus: true,
2615
+ * waitTimeSource: { body: 'data.retry_after' }
2616
+ * });
2617
+ *
2618
+ * // Custom function for complex APIs
2619
+ * await rezo.get(url, {
2620
+ * waitOnStatus: [429, 503],
2621
+ * waitTimeSource: (response) => {
2622
+ * const reset = response.headers.get('x-ratelimit-reset');
2623
+ * return reset ? parseInt(reset) - Math.floor(Date.now() / 1000) : null;
2624
+ * }
2625
+ * });
2626
+ * ```
2627
+ */
2628
+ waitOnStatus?: boolean | number[];
2629
+ /**
2630
+ * Where to extract the wait time from when rate-limited.
2631
+ *
2632
+ * - `'retry-after'` - Standard Retry-After header (default)
2633
+ * - `{ header: string }` - Custom header name (e.g., 'X-RateLimit-Reset')
2634
+ * - `{ body: string }` - JSON path in response body (e.g., 'data.retry_after', 'wait_seconds')
2635
+ * - Function - Custom logic receiving the response, return seconds to wait or null
2636
+ *
2637
+ * @default 'retry-after'
2638
+ */
2639
+ waitTimeSource?: "retry-after" | {
2640
+ header: string;
2641
+ } | {
2642
+ body: string;
2643
+ } | ((response: {
2644
+ status: number;
2645
+ headers: RezoHeaders;
2646
+ data?: any;
2647
+ }) => number | null);
2648
+ /**
2649
+ * Maximum time to wait for rate limit in milliseconds.
2650
+ * If the extracted wait time exceeds this, the request will fail instead of waiting.
2651
+ * Set to 0 for unlimited wait time.
2652
+ *
2653
+ * @default 60000 (60 seconds)
2654
+ */
2655
+ maxWaitTime?: number;
2656
+ /**
2657
+ * Default wait time in milliseconds if the wait time source returns nothing.
2658
+ * Used as fallback when Retry-After header or body path is not present.
2659
+ *
2660
+ * @default 1000 (1 second)
2661
+ */
2662
+ defaultWaitTime?: number;
2663
+ /**
2664
+ * Maximum number of wait attempts before giving up.
2665
+ * After this many waits, the request will proceed to retry logic or fail.
2666
+ *
2667
+ * @default 3
2668
+ */
2669
+ maxWaitAttempts?: number;
2555
2670
  /** Whether to use a secure context for HTTPS requests */
2556
2671
  useSecureContext?: boolean;
2557
2672
  /** Custom secure context for TLS connections */
@@ -1,10 +1,10 @@
1
- const _mod_ka4e3g = require('./base.cjs');
2
- exports.Agent = _mod_ka4e3g.Agent;;
3
- const _mod_nmerdf = require('./http-proxy.cjs');
4
- exports.HttpProxyAgent = _mod_nmerdf.HttpProxyAgent;;
5
- const _mod_do1bvj = require('./https-proxy.cjs');
6
- exports.HttpsProxyAgent = _mod_do1bvj.HttpsProxyAgent;;
7
- const _mod_1bn8q4 = require('./socks-proxy.cjs');
8
- exports.SocksProxyAgent = _mod_1bn8q4.SocksProxyAgent;;
9
- const _mod_wb9id7 = require('./socks-client.cjs');
10
- exports.SocksClient = _mod_wb9id7.SocksClient;;
1
+ const _mod_150zmc = require('./base.cjs');
2
+ exports.Agent = _mod_150zmc.Agent;;
3
+ const _mod_0kmp78 = require('./http-proxy.cjs');
4
+ exports.HttpProxyAgent = _mod_0kmp78.HttpProxyAgent;;
5
+ const _mod_4tvb7u = require('./https-proxy.cjs');
6
+ exports.HttpsProxyAgent = _mod_4tvb7u.HttpsProxyAgent;;
7
+ const _mod_wgeif4 = require('./socks-proxy.cjs');
8
+ exports.SocksProxyAgent = _mod_wgeif4.SocksProxyAgent;;
9
+ const _mod_3nqvg8 = require('./socks-client.cjs');
10
+ exports.SocksClient = _mod_3nqvg8.SocksClient;;
@@ -1416,6 +1416,35 @@ export type OnTimeoutHook = (event: TimeoutEvent, config: RezoConfig) => void;
1416
1416
  * Use for cleanup, logging
1417
1417
  */
1418
1418
  export type OnAbortHook = (event: AbortEvent, config: RezoConfig) => void;
1419
+ /**
1420
+ * Rate limit wait event data - fired when waiting due to rate limiting
1421
+ */
1422
+ export interface RateLimitWaitEvent {
1423
+ /** HTTP status code that triggered the wait (e.g., 429, 503) */
1424
+ status: number;
1425
+ /** Time to wait in milliseconds */
1426
+ waitTime: number;
1427
+ /** Current wait attempt number (1-indexed) */
1428
+ attempt: number;
1429
+ /** Maximum wait attempts configured */
1430
+ maxAttempts: number;
1431
+ /** Where the wait time was extracted from */
1432
+ source: "header" | "body" | "function" | "default";
1433
+ /** The header or body path used (if applicable) */
1434
+ sourcePath?: string;
1435
+ /** URL being requested */
1436
+ url: string;
1437
+ /** HTTP method of the request */
1438
+ method: string;
1439
+ /** Timestamp when the wait started */
1440
+ timestamp: number;
1441
+ }
1442
+ /**
1443
+ * Hook called when rate limit wait occurs
1444
+ * Informational only - cannot abort the wait
1445
+ * Use for logging, monitoring, alerting
1446
+ */
1447
+ export type OnRateLimitWaitHook = (event: RateLimitWaitEvent, config: RezoConfig) => void | Promise<void>;
1419
1448
  /**
1420
1449
  * Hook called before a proxy is selected
1421
1450
  * Can return a specific proxy to override selection
@@ -1496,6 +1525,7 @@ export interface RezoHooks {
1496
1525
  onTls: OnTlsHook[];
1497
1526
  onTimeout: OnTimeoutHook[];
1498
1527
  onAbort: OnAbortHook[];
1528
+ onRateLimitWait: OnRateLimitWaitHook[];
1499
1529
  }
1500
1530
  /**
1501
1531
  * Create empty hooks object with all arrays initialized
@@ -2426,6 +2456,91 @@ export interface RezoRequestConfig<D = any> {
2426
2456
  /** Weather to stop or continue retry when certain condition is met*/
2427
2457
  condition?: (error: RezoError) => boolean | Promise<boolean>;
2428
2458
  };
2459
+ /**
2460
+ * Rate limit wait configuration - wait and retry when receiving rate limit responses.
2461
+ *
2462
+ * This feature runs BEFORE the retry system. When a rate-limiting status code is received,
2463
+ * the client will wait for the specified time and automatically retry the request.
2464
+ *
2465
+ * **Basic Usage:**
2466
+ * - `waitOnStatus: true` - Enable waiting on 429 status (default behavior)
2467
+ * - `waitOnStatus: [429, 503]` - Enable waiting on specific status codes
2468
+ *
2469
+ * **Wait Time Sources:**
2470
+ * - `'retry-after'` - Use standard Retry-After header (default)
2471
+ * - `{ header: 'X-RateLimit-Reset' }` - Use custom header
2472
+ * - `{ body: 'retry_after' }` - Extract from JSON response body
2473
+ * - Custom function for complex logic
2474
+ *
2475
+ * @example
2476
+ * ```typescript
2477
+ * // Wait on 429 using Retry-After header
2478
+ * await rezo.get(url, { waitOnStatus: true });
2479
+ *
2480
+ * // Wait on 429 using custom header
2481
+ * await rezo.get(url, {
2482
+ * waitOnStatus: true,
2483
+ * waitTimeSource: { header: 'X-RateLimit-Reset' }
2484
+ * });
2485
+ *
2486
+ * // Wait on 429 extracting time from JSON body
2487
+ * await rezo.get(url, {
2488
+ * waitOnStatus: true,
2489
+ * waitTimeSource: { body: 'data.retry_after' }
2490
+ * });
2491
+ *
2492
+ * // Custom function for complex APIs
2493
+ * await rezo.get(url, {
2494
+ * waitOnStatus: [429, 503],
2495
+ * waitTimeSource: (response) => {
2496
+ * const reset = response.headers.get('x-ratelimit-reset');
2497
+ * return reset ? parseInt(reset) - Math.floor(Date.now() / 1000) : null;
2498
+ * }
2499
+ * });
2500
+ * ```
2501
+ */
2502
+ waitOnStatus?: boolean | number[];
2503
+ /**
2504
+ * Where to extract the wait time from when rate-limited.
2505
+ *
2506
+ * - `'retry-after'` - Standard Retry-After header (default)
2507
+ * - `{ header: string }` - Custom header name (e.g., 'X-RateLimit-Reset')
2508
+ * - `{ body: string }` - JSON path in response body (e.g., 'data.retry_after', 'wait_seconds')
2509
+ * - Function - Custom logic receiving the response, return seconds to wait or null
2510
+ *
2511
+ * @default 'retry-after'
2512
+ */
2513
+ waitTimeSource?: "retry-after" | {
2514
+ header: string;
2515
+ } | {
2516
+ body: string;
2517
+ } | ((response: {
2518
+ status: number;
2519
+ headers: RezoHeaders;
2520
+ data?: any;
2521
+ }) => number | null);
2522
+ /**
2523
+ * Maximum time to wait for rate limit in milliseconds.
2524
+ * If the extracted wait time exceeds this, the request will fail instead of waiting.
2525
+ * Set to 0 for unlimited wait time.
2526
+ *
2527
+ * @default 60000 (60 seconds)
2528
+ */
2529
+ maxWaitTime?: number;
2530
+ /**
2531
+ * Default wait time in milliseconds if the wait time source returns nothing.
2532
+ * Used as fallback when Retry-After header or body path is not present.
2533
+ *
2534
+ * @default 1000 (1 second)
2535
+ */
2536
+ defaultWaitTime?: number;
2537
+ /**
2538
+ * Maximum number of wait attempts before giving up.
2539
+ * After this many waits, the request will proceed to retry logic or fail.
2540
+ *
2541
+ * @default 3
2542
+ */
2543
+ maxWaitAttempts?: number;
2429
2544
  /** Whether to use a secure context for HTTPS requests */
2430
2545
  useSecureContext?: boolean;
2431
2546
  /** Custom secure context for TLS connections */