webcrawlerapi-js 2.2.5 → 2.2.6

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.
@@ -29,6 +29,8 @@ export interface ScrapeResponse {
29
29
  page_title?: string;
30
30
  structured_data?: any;
31
31
  links?: string[];
32
+ /** Server-recommended delay before the next status poll, if provided */
33
+ recommended_pull_delay_ms?: number;
32
34
  }
33
35
  export interface ScrapeResponseError {
34
36
  success: boolean;
package/dist/api.js CHANGED
@@ -24,6 +24,9 @@ const BASE_PATH = "https://api.webcrawlerapi.com";
24
24
  const initialPullDelayMs = 2000;
25
25
  const MaxPullRetries = 100;
26
26
  const DEFAULT_POLL_DELAY_SECONDS = 2;
27
+ const SCRAPE_MAX_WAIT_MS = 400 * 1000;
28
+ // Effectively unbounded by count at the 2s default; elapsed time is the real limit
29
+ const SCRAPE_MAX_POLLS = 1000;
27
30
  const AgentTerminalStatuses = ["done", "error", "canceled"];
28
31
  __exportStar(require("./model"), exports);
29
32
  const SCRAPE_VERSION = "v2";
@@ -183,17 +186,21 @@ class WebcrawlerClient {
183
186
  return {
184
187
  success: false,
185
188
  status: status,
186
- page_status_code: 0
189
+ page_status_code: 0,
190
+ recommended_pull_delay_ms: responseData.recommended_pull_delay_ms
187
191
  };
188
192
  }
189
193
  }
190
- async scrape(request, maxPolls = 100) {
194
+ async scrape(request, maxPolls = SCRAPE_MAX_POLLS) {
191
195
  // Start the scraping job
192
196
  const scrapeIdResponse = await this.scrapeAsync(request);
193
197
  const scrapeId = scrapeIdResponse.id;
198
+ const startedAt = Date.now();
194
199
  let polls = 0;
200
+ let delayMs = DEFAULT_POLL_DELAY_SECONDS * 1000;
195
201
  let result;
196
- while (polls < maxPolls) {
202
+ // Bounded by both elapsed time (SCRAPE_MAX_WAIT_MS) and maxPolls
203
+ while (polls < maxPolls && Date.now() - startedAt < SCRAPE_MAX_WAIT_MS) {
197
204
  result = await this.getScrape(scrapeId);
198
205
  // Return immediately if scrape is done
199
206
  if ('status' in result && result.status === "done") {
@@ -203,12 +210,17 @@ class WebcrawlerClient {
203
210
  if ('error_code' in result) {
204
211
  return result;
205
212
  }
206
- // Continue polling if status is in_progress or any other non-terminal status
207
- // Wait before next poll
208
- await new Promise(resolve => setTimeout(resolve, DEFAULT_POLL_DELAY_SECONDS * 1000));
213
+ // Use server-recommended delay when present, otherwise keep the default
214
+ const recommended = result.recommended_pull_delay_ms;
215
+ delayMs = recommended && recommended > 0 ? recommended : DEFAULT_POLL_DELAY_SECONDS * 1000;
216
+ // Don't sleep past the overall deadline
217
+ const remainingMs = SCRAPE_MAX_WAIT_MS - (Date.now() - startedAt);
218
+ if (remainingMs <= 0)
219
+ break;
220
+ await new Promise(resolve => setTimeout(resolve, Math.min(delayMs, remainingMs)));
209
221
  polls++;
210
222
  }
211
- // Return the last known state if maxPolls is reached
223
+ // Return the last known state on timeout
212
224
  return result;
213
225
  }
214
226
  async crawl(crawlRequest, maxPolls = MaxPullRetries) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "webcrawlerapi-js",
3
- "version": "2.2.5",
3
+ "version": "2.2.6",
4
4
  "description": "JS client for WebcrawlerAPI",
5
5
  "main": "./dist/api.js",
6
6
  "types": "./dist/@types/api.d.ts",