@crawlee/basic 4.0.0-beta.143 → 4.0.0-beta.144

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.
@@ -1,4 +1,4 @@
1
- import type { AddRequestsBatchedOptions, AddRequestsBatchedResult, ConcurrencySystemOptions, CrawleeLogger, CrawlingContext, DatasetExportOptions, EnqueueUrlsOptions, FinalStatistics, GetUserDataFromRequest, IConcurrencySystem, IProxyConfiguration, IRequestLoader, IRequestManager, IStatistics, RequestsLike, RouterHandler, RouterRoutes, SkippedRequestCallback, Source, StatisticState, StorageIdentifier, StorageWritePolicy, TaskLoopPredicates, TypedRequestsLike } from '@crawlee/core';
1
+ import type { AddRequestsBatchedOptions, AddRequestsBatchedResult, ConcurrencySystemOptions, CrawleeLogger, CrawlingContext, DatasetExportOptions, EnqueueUrlsOptions, FinalStatistics, GetUserDataFromRequest, IConcurrencySystem, IProxyConfiguration, IRequestLoader, IRequestManager, IStatistics, RequestsLike, RouterHandler, RouterRoutes, SkippedRequestCallback, Source, StatisticState, StorageIdentifier, StorageWritePolicy, TaskLoopOptions, TypedRequestsLike } from '@crawlee/core';
2
2
  import { ConcurrencySystem, Configuration, ContextPipeline, Request, Dataset, EventManager, RequestQueue } from '@crawlee/core';
3
3
  import { BaseHttpClient } from '@crawlee/http-client';
4
4
  import type { Awaitable, Dictionary, ISession, ISessionPool, ProxyInfo, SetStatusMessageOptions, StorageBackend } from '@crawlee/types';
@@ -165,7 +165,7 @@ export interface BasicCrawlerOptions<Context extends CrawlingContext = CrawlingC
165
165
  * Concurrency is configured elsewhere — through the `minConcurrency`/`maxConcurrency`/`maxRequestsPerMinute`
166
166
  * shortcuts, or a {@link BasicCrawlerOptions.concurrencySystem|`concurrencySystem`} for finer control.
167
167
  */
168
- taskLoopOptions?: TaskLoopPredicates;
168
+ taskLoopOptions?: TaskLoopOptions;
169
169
  /**
170
170
  * A pre-configured concurrency governor — the component that decides whether there is free compute for one more
171
171
  * task. Typically a {@link ConcurrencySystem}, though any {@link IConcurrencySystem} is accepted. All
@@ -430,18 +430,10 @@ export declare class BasicCrawler<Context extends CrawlingContext = CrawlingCont
430
430
  hasFinishedBefore: boolean;
431
431
  get log(): CrawleeLogger;
432
432
  protected readonly requestHandler: RequestHandler<ExtendedContext>;
433
- private requestHandlerTimeoutMillis;
434
433
  protected readonly internalTimeoutMillis: number;
435
434
  private get handledRequestsCount();
436
435
  protected blockedStatusCodes: Set<number>;
437
436
  protected readonly additionalHttpErrorStatusCodes: Set<number>;
438
- /**
439
- * The resolved options for the crawler's own task loop — the crawler-owned `runTaskFunction`, the (possibly
440
- * user-overridden) ready/finished predicates and cadence/logging. Concurrency configuration lives on the
441
- * {@link ConcurrencySystem} instead, and the loop's `consumer` identity is the crawler's own, so neither is
442
- * settable here.
443
- */
444
- private taskLoopOptions;
445
437
  protected readonly httpClient: BaseHttpClient;
446
438
  protected readonly retryOnBlocked: boolean;
447
439
  /**
@@ -7,7 +7,7 @@ import { RobotsTxtFile } from '@crawlee/utils';
7
7
  import { getDomain } from 'tldts';
8
8
  import { z } from 'zod';
9
9
  import { LruCache } from '@apify/datastructures';
10
- import { addTimeoutToPromise, extendTimeout, TimeoutError } from '@apify/timeout';
10
+ import { addTimeoutToPromise, extendTimeout, TimeoutError, tryCancel } from '@apify/timeout';
11
11
  import { cryptoRandomObjectId } from '@apify/utilities';
12
12
  import { extendTimeoutKey, navigationDeadlineKey, raceWithTimeout, timeoutExpiredKey, } from './request-timeout.js';
13
13
  import { createSendRequest } from './send-request.js';
@@ -193,8 +193,7 @@ export class BasicCrawler {
193
193
  requestHandler;
194
194
  #errorHandler;
195
195
  #failedRequestHandler;
196
- // kept as TS-private: tests read it at runtime
197
- requestHandlerTimeoutMillis;
196
+ #requestHandlerTimeoutMillis;
198
197
  internalTimeoutMillis;
199
198
  #maxRequestRetries;
200
199
  #maxCrawlDepth;
@@ -214,8 +213,7 @@ export class BasicCrawler {
214
213
  * {@link ConcurrencySystem} instead, and the loop's `consumer` identity is the crawler's own, so neither is
215
214
  * settable here.
216
215
  */
217
- // kept as TS-private: tests mutate it at runtime
218
- taskLoopOptions;
216
+ #taskLoopOptions;
219
217
  httpClient;
220
218
  retryOnBlocked;
221
219
  #respectRobotsTxtFile;
@@ -370,10 +368,10 @@ export class BasicCrawler {
370
368
  this.#failedRequestHandler = failedRequestHandler;
371
369
  this.#errorHandler = errorHandler;
372
370
  if (requestHandlerTimeoutSecs) {
373
- this.requestHandlerTimeoutMillis = requestHandlerTimeoutSecs * 1000;
371
+ this.#requestHandlerTimeoutMillis = requestHandlerTimeoutSecs * 1000;
374
372
  }
375
373
  else {
376
- this.requestHandlerTimeoutMillis = 60_000;
374
+ this.#requestHandlerTimeoutMillis = 60_000;
377
375
  }
378
376
  this.retryOnBlocked = retryOnBlocked;
379
377
  this.#respectRobotsTxtFile = respectRobotsTxtFile;
@@ -385,7 +383,7 @@ export class BasicCrawler {
385
383
  // allow at least 5min for internal timeouts
386
384
  this.internalTimeoutMillis =
387
385
  serviceLocator.getConfiguration().internalTimeoutMillis ??
388
- Math.max(this.requestHandlerTimeoutMillis * 2, 300e3);
386
+ Math.max(this.#requestHandlerTimeoutMillis * 2, 300e3);
389
387
  this.#maxRequestRetries = maxRequestRetries;
390
388
  this.#maxCrawlDepth = maxCrawlDepth;
391
389
  this.#sameDomainDelaySecs = sameDomainDelaySecs;
@@ -412,10 +410,10 @@ export class BasicCrawler {
412
410
  }));
413
411
  this.blockedStatusCodes = new Set(blockedStatusCodesInput ?? BLOCKED_STATUS_CODES);
414
412
  const maxSignedInteger = 2 ** 31 - 1;
415
- if (this.requestHandlerTimeoutMillis > maxSignedInteger) {
416
- this.log.warning(`requestHandlerTimeoutMillis ${this.requestHandlerTimeoutMillis}` +
413
+ if (this.#requestHandlerTimeoutMillis > maxSignedInteger) {
414
+ this.log.warning(`requestHandlerTimeoutMillis ${this.#requestHandlerTimeoutMillis}` +
417
415
  ` does not fit a signed 32-bit integer. Limiting the value to ${maxSignedInteger}`);
418
- this.requestHandlerTimeoutMillis = maxSignedInteger;
416
+ this.#requestHandlerTimeoutMillis = maxSignedInteger;
419
417
  }
420
418
  this.internalTimeoutMillis = Math.min(this.internalTimeoutMillis, maxSignedInteger);
421
419
  this.#maxRequestsPerCrawl = maxRequestsPerCrawl;
@@ -525,7 +523,7 @@ export class BasicCrawler {
525
523
  },
526
524
  log: this.log,
527
525
  };
528
- this.taskLoopOptions = { ...taskLoopOptions, ...crawlerOwnedTaskLoopConfiguration };
526
+ this.#taskLoopOptions = { ...taskLoopOptions, ...crawlerOwnedTaskLoopConfiguration };
529
527
  this.#resolveConcurrencySystem = () => OwnedOrInjected.resolve(concurrencySystem, () => this.createDefaultConcurrencySystem({
530
528
  minConcurrency,
531
529
  maxConcurrency,
@@ -975,7 +973,7 @@ export class BasicCrawler {
975
973
  // which routes a run will hit, so reserve for the longest one any route asked for. The hint is
976
974
  // raise-only, so erring high here is safe.
977
975
  const maxRouteTimeoutSecs = this.requestHandler.getMaxTimeoutSecs?.() ?? 0;
978
- const handlerTimeoutSecs = Math.max(this.requestHandlerTimeoutMillis / 1000, maxRouteTimeoutSecs);
976
+ const handlerTimeoutSecs = Math.max(this.#requestHandlerTimeoutMillis / 1000, maxRouteTimeoutSecs);
979
977
  await requestManager.setExpectedRequestProcessingTimeSecs?.(Math.max(handlerTimeoutSecs + 5, 60));
980
978
  }
981
979
  /**
@@ -1167,6 +1165,7 @@ export class BasicCrawler {
1167
1165
  * Pushes data to the specified {@link Dataset}, or the default crawler {@link Dataset} by calling {@link Dataset.pushData}.
1168
1166
  */
1169
1167
  async pushData(data, datasetIdentifier) {
1168
+ tryCancel();
1170
1169
  const dataset = await this.getDataset(datasetIdentifier);
1171
1170
  return dataset.pushData(data);
1172
1171
  }
@@ -1256,7 +1255,7 @@ export class BasicCrawler {
1256
1255
  this.#concurrencySystemDep = this.#resolveConcurrencySystem();
1257
1256
  await this.#concurrencySystemDep.ifOwned((system) => system.start());
1258
1257
  this.#autoscaledPool = new AutoscaledPool({
1259
- ...this.taskLoopOptions,
1258
+ ...this.#taskLoopOptions,
1260
1259
  concurrencySystem: this.#concurrencySystemDep.value,
1261
1260
  consumer: this.#identity,
1262
1261
  });
@@ -1289,7 +1288,7 @@ export class BasicCrawler {
1289
1288
  * @param label The request's route label, or `undefined` for the default route / no specific request.
1290
1289
  * @param fallbackMillis Timeout to use when no route overrides it.
1291
1290
  */
1292
- resolveRequestHandlerTimeoutMillis(label, fallbackMillis = this.requestHandlerTimeoutMillis) {
1291
+ resolveRequestHandlerTimeoutMillis(label, fallbackMillis = this.#requestHandlerTimeoutMillis) {
1293
1292
  return this.getRouteTimeoutMillis(label) ?? fallbackMillis;
1294
1293
  }
1295
1294
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crawlee/basic",
3
- "version": "4.0.0-beta.143",
3
+ "version": "4.0.0-beta.144",
4
4
  "description": "The scalable web crawling and scraping library for JavaScript/Node.js. Enables development of data extraction and web automation jobs (not only) with headless Chrome and Puppeteer.",
5
5
  "engines": {
6
6
  "node": ">=22.0.0"
@@ -42,10 +42,10 @@
42
42
  "@apify/datastructures": "^2.0.0",
43
43
  "@apify/timeout": "^0.4.4",
44
44
  "@apify/utilities": "^2.15.5",
45
- "@crawlee/core": "4.0.0-beta.143",
46
- "@crawlee/http-client": "4.0.0-beta.143",
47
- "@crawlee/types": "4.0.0-beta.143",
48
- "@crawlee/utils": "4.0.0-beta.143",
45
+ "@crawlee/core": "4.0.0-beta.144",
46
+ "@crawlee/http-client": "4.0.0-beta.144",
47
+ "@crawlee/types": "4.0.0-beta.144",
48
+ "@crawlee/utils": "4.0.0-beta.144",
49
49
  "csv-stringify": "^6.5.2",
50
50
  "tldts": "^7.0.6",
51
51
  "tslib": "^2.8.1",
@@ -53,7 +53,7 @@
53
53
  "zod": "^4.4.3"
54
54
  },
55
55
  "optionalDependencies": {
56
- "@crawlee/impit-client": "^4.0.0-beta.143"
56
+ "@crawlee/impit-client": "^4.0.0-beta.144"
57
57
  },
58
58
  "lerna": {
59
59
  "command": {
@@ -62,5 +62,5 @@
62
62
  }
63
63
  }
64
64
  },
65
- "gitHead": "d44b4c37b5acd824c2093542f878266feb6214ea"
65
+ "gitHead": "4acf68a225909523047f872cbdeb87428bfc560d"
66
66
  }