@crawlee/browser 4.0.0-beta.105 → 4.0.0-beta.106

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.
@@ -227,8 +227,7 @@ export interface BrowserCrawlerOptions<Page extends CommonPage = CommonPage, Res
227
227
  * @category Crawlers
228
228
  */
229
229
  export declare abstract class BrowserCrawler<Page extends CommonPage = CommonPage, Response extends BaseResponse = BaseResponse, InternalBrowserPoolOptions extends BrowserPoolOptions = BrowserPoolOptions, LaunchOptions extends Dictionary | undefined = Dictionary, Context extends BrowserCrawlingContext<Page, Response> = BrowserCrawlingContext<Page, Response>, ContextExtension = Dictionary<never>, ExtendedContext extends Context = Context & ContextExtension, Routes extends Record<keyof Routes, Dictionary> = Record<string, GetUserDataFromRequest<Context['request']>>, GoToOptions extends Dictionary = Dictionary> extends BasicCrawler<Context, ContextExtension, ExtendedContext, Routes> {
230
- /** Backs the {@link BrowserCrawler.browserPool|`browserPool`} getter. */
231
- private browserPoolDep;
230
+ #private;
232
231
  /**
233
232
  * A reference to the underlying browser pool that manages the crawler's browsers. Typed as
234
233
  * {@link IBrowserPool} so custom implementations can be plugged in via the `browserPool` constructor option.
@@ -237,10 +236,6 @@ export declare abstract class BrowserCrawler<Page extends CommonPage = CommonPag
237
236
  launchContext: BrowserLaunchContext<LaunchOptions, unknown>;
238
237
  protected readonly ignoreShadowRoots: boolean;
239
238
  protected readonly ignoreIframes: boolean;
240
- private readonly navigationTimeoutMillis;
241
- private readonly preNavigationHooks;
242
- private readonly postNavigationHooks;
243
- private readonly saveResponseCookies;
244
239
  protected static optionsShape: {
245
240
  // @ts-ignore optional peer dependency or compatibility with es2022
246
241
  navigationTimeoutSecs: import("ow").NumberPredicate & import("ow").BasePredicate<number | undefined>;
@@ -367,7 +362,7 @@ export declare abstract class BrowserCrawler<Page extends CommonPage = CommonPag
367
362
  * Transforms proxy-related errors to `SessionError`.
368
363
  */
369
364
  private throwIfProxyError;
370
- protected abstract _navigationHandler(crawlingContext: BrowserCrawlingContext<Page, Response>, gotoOptions: GoToOptions): Promise<Context['response'] | null | undefined>;
365
+ protected abstract navigationHandler(crawlingContext: BrowserCrawlingContext<Page, Response>, gotoOptions: GoToOptions): Promise<Context['response'] | null | undefined>;
371
366
  private processResponse;
372
367
  /**
373
368
  * Function for cleaning up after all requests are processed.
@@ -58,21 +58,21 @@ function isNavigationTimeoutError(error) {
58
58
  */
59
59
  export class BrowserCrawler extends BasicCrawler {
60
60
  /** Backs the {@link BrowserCrawler.browserPool|`browserPool`} getter. */
61
- browserPoolDep;
61
+ #browserPoolDep;
62
62
  /**
63
63
  * A reference to the underlying browser pool that manages the crawler's browsers. Typed as
64
64
  * {@link IBrowserPool} so custom implementations can be plugged in via the `browserPool` constructor option.
65
65
  */
66
66
  get browserPool() {
67
- return this.browserPoolDep.value;
67
+ return this.#browserPoolDep.value;
68
68
  }
69
69
  launchContext;
70
70
  ignoreShadowRoots;
71
71
  ignoreIframes;
72
- navigationTimeoutMillis;
73
- preNavigationHooks;
74
- postNavigationHooks;
75
- saveResponseCookies;
72
+ #navigationTimeoutMillis;
73
+ #preNavigationHooks;
74
+ #postNavigationHooks;
75
+ #saveResponseCookies;
76
76
  static optionsShape = {
77
77
  ...BasicCrawler.optionsShape,
78
78
  navigationTimeoutSecs: ow.optional.number.greaterThan(0),
@@ -103,18 +103,18 @@ export class BrowserCrawler extends BasicCrawler {
103
103
  // hook eats into the same window the navigation uses. The navigation itself is bounded by
104
104
  // capping its `gotoOptions.timeout` to the remaining budget.
105
105
  const windowGuard = (step) => skipGuard(async (ctx) => {
106
- const remaining = remainingNavigationWindowMillis(ctx, this.navigationTimeoutMillis);
106
+ const remaining = remainingNavigationWindowMillis(ctx, this.#navigationTimeoutMillis);
107
107
  if (remaining <= 0) {
108
- throw new TimeoutError(`Navigation timed out after ${this.navigationTimeoutMillis / 1000} seconds.`);
108
+ throw new TimeoutError(`Navigation timed out after ${this.#navigationTimeoutMillis / 1000} seconds.`);
109
109
  }
110
- return addTimeoutToPromise(async () => step(ctx), remaining, `Navigation timed out after ${this.navigationTimeoutMillis / 1000} seconds.`);
110
+ return addTimeoutToPromise(async () => step(ctx), remaining, `Navigation timed out after ${this.#navigationTimeoutMillis / 1000} seconds.`);
111
111
  });
112
112
  let pipeline = contextPipelineBuilder().compose({ action: this.prepareNavigation.bind(this) });
113
- for (const hook of this.preNavigationHooks) {
113
+ for (const hook of this.#preNavigationHooks) {
114
114
  pipeline = pipeline.compose(windowGuard(hook));
115
115
  }
116
116
  pipeline = pipeline.compose(skipGuard(this.navigate.bind(this)));
117
- for (const hook of this.postNavigationHooks) {
117
+ for (const hook of this.#postNavigationHooks) {
118
118
  pipeline = pipeline.compose(windowGuard(hook));
119
119
  }
120
120
  return pipeline
@@ -125,23 +125,23 @@ export class BrowserCrawler extends BasicCrawler {
125
125
  extendContext,
126
126
  });
127
127
  this.launchContext = launchContext;
128
- this.navigationTimeoutMillis = navigationTimeoutSecs * 1000;
128
+ this.#navigationTimeoutMillis = navigationTimeoutSecs * 1000;
129
129
  // The public option hooks are extension-aware; internal storage uses the base context type
130
130
  // (the pipeline composes hooks against the concrete context, which does not statically carry
131
131
  // `ContextExtension`). The extension members are present at runtime regardless.
132
- this.preNavigationHooks = preNavigationHooks;
133
- this.postNavigationHooks = postNavigationHooks;
132
+ this.#preNavigationHooks = preNavigationHooks;
133
+ this.#postNavigationHooks = postNavigationHooks;
134
134
  this.ignoreIframes = ignoreIframes;
135
135
  this.ignoreShadowRoots = ignoreShadowRoots;
136
136
  if (headless != null) {
137
137
  this.launchContext.launchOptions ??= {};
138
138
  this.launchContext.launchOptions.headless = headless;
139
139
  }
140
- this.saveResponseCookies = saveResponseCookies;
140
+ this.#saveResponseCookies = saveResponseCookies;
141
141
  // `browserPool` wins over `remoteBrowser` — a passed-in pool is used as-is (borrowed), the sugar is ignored.
142
142
  // The default is only built when no pool was injected, so all the option/launchContext fiddling below stays
143
143
  // inside the factory.
144
- this.browserPoolDep = OwnedOrInjected.resolve(browserPool, () => {
144
+ this.#browserPoolDep = OwnedOrInjected.resolve(browserPool, () => {
145
145
  const resolvedBrowserPoolOptions = browserPoolOptions ?? {};
146
146
  if (launchContext?.userAgent) {
147
147
  if (resolvedBrowserPoolOptions.useFingerprints)
@@ -168,7 +168,7 @@ export class BrowserCrawler extends BasicCrawler {
168
168
  });
169
169
  }
170
170
  getNavigationTimeoutMillis() {
171
- return this.navigationTimeoutMillis;
171
+ return this.#navigationTimeoutMillis;
172
172
  }
173
173
  buildContextPipeline() {
174
174
  return ContextPipeline.create().compose({
@@ -263,31 +263,31 @@ export class BrowserCrawler extends BasicCrawler {
263
263
  return {
264
264
  // Default to the full navigation timeout so a pre-navigation hook can read it; `navigate` narrows it
265
265
  // to the remaining shared window unless a hook overrode it (see there).
266
- gotoOptions: { timeout: this.navigationTimeoutMillis },
267
- [COOKIES_BEFORE_HOOKS]: this._getCookieHeaderFromRequest(crawlingContext.request),
266
+ gotoOptions: { timeout: this.#navigationTimeoutMillis },
267
+ [COOKIES_BEFORE_HOOKS]: this.getCookieHeaderFromRequest(crawlingContext.request),
268
268
  };
269
269
  }
270
270
  async navigate(crawlingContext) {
271
271
  tryCancel();
272
272
  const gotoOptions = crawlingContext.gotoOptions;
273
- const remaining = remainingNavigationWindowMillis(crawlingContext, this.navigationTimeoutMillis);
273
+ const remaining = remainingNavigationWindowMillis(crawlingContext, this.#navigationTimeoutMillis);
274
274
  if (remaining <= 0) {
275
- throw new TimeoutError(`Navigation timed out after ${this.navigationTimeoutMillis / 1000} seconds.`);
275
+ throw new TimeoutError(`Navigation timed out after ${this.#navigationTimeoutMillis / 1000} seconds.`);
276
276
  }
277
277
  // If a hook left the default `navigationTimeoutMillis` in place, bound the goto to whatever is left of the
278
278
  // shared navigation window. If it overrode the value - including `0`, Playwright's "no timeout" - honour
279
279
  // that verbatim as the goto's own timeout. The driver enforces this natively (so a timed-out goto is
280
280
  // aborted, not left lingering) and `handleNavigationTimeout` turns its error into our own message.
281
281
  const gotoTimeout = gotoOptions;
282
- if (gotoTimeout.timeout === this.navigationTimeoutMillis) {
282
+ if (gotoTimeout.timeout === this.#navigationTimeoutMillis) {
283
283
  gotoTimeout.timeout = remaining;
284
284
  }
285
285
  const cookiesBeforeHooks = readContextField(crawlingContext, COOKIES_BEFORE_HOOKS);
286
- const cookiesAfterHooks = this._getCookieHeaderFromRequest(crawlingContext.request);
286
+ const cookiesAfterHooks = this.getCookieHeaderFromRequest(crawlingContext.request);
287
287
  await this.applyCookies(crawlingContext, cookiesBeforeHooks, cookiesAfterHooks);
288
288
  let response;
289
289
  try {
290
- response = (await this._navigationHandler(crawlingContext, gotoOptions)) ?? undefined;
290
+ response = (await this.navigationHandler(crawlingContext, gotoOptions)) ?? undefined;
291
291
  }
292
292
  catch (error) {
293
293
  await this.handleNavigationTimeout(crawlingContext, error);
@@ -320,7 +320,7 @@ export class BrowserCrawler extends BasicCrawler {
320
320
  * Copies cookies from the live browser page into the session cookie jar.
321
321
  */
322
322
  async persistCookiesFromPage(crawlingContext) {
323
- if (!this.saveResponseCookies || !crawlingContext.session) {
323
+ if (!this.#saveResponseCookies || !crawlingContext.session) {
324
324
  return;
325
325
  }
326
326
  const { cookies } = await this.browserPool.extractPageState(crawlingContext.page);
@@ -390,7 +390,7 @@ export class BrowserCrawler extends BasicCrawler {
390
390
  session?.markBad();
391
391
  // The driver was handed the remaining window (usually shorter than `navigationTimeoutSecs` once the
392
392
  // hooks have run), so it names that value in its own error; report the configured window instead.
393
- throw new TimeoutError(`Navigation timed out after ${this.navigationTimeoutMillis / 1000} seconds.`);
393
+ throw new TimeoutError(`Navigation timed out after ${this.#navigationTimeoutMillis / 1000} seconds.`);
394
394
  }
395
395
  }
396
396
  /**
@@ -398,7 +398,7 @@ export class BrowserCrawler extends BasicCrawler {
398
398
  */
399
399
  throwIfProxyError(error) {
400
400
  if (this.isProxyError(error)) {
401
- throw new SessionError(this._getMessageFromError(error));
401
+ throw new SessionError(this.getMessageFromError(error));
402
402
  }
403
403
  }
404
404
  async processResponse(response, crawlingContext) {
@@ -415,7 +415,7 @@ export class BrowserCrawler extends BasicCrawler {
415
415
  }
416
416
  if (this.sessionPool && response && session) {
417
417
  if (typeof response === 'object' && typeof response.status === 'function') {
418
- this._throwOnBlockedRequest(response.status());
418
+ this.throwOnBlockedRequest(response.status());
419
419
  }
420
420
  else {
421
421
  this.log.debug('Got a malformed Browser response.', { request, response });
@@ -428,7 +428,7 @@ export class BrowserCrawler extends BasicCrawler {
428
428
  * @ignore
429
429
  */
430
430
  async teardown() {
431
- await this.browserPoolDep.ifOwned((pool) => pool.destroy());
431
+ await this.#browserPoolDep.ifOwned((pool) => pool.destroy());
432
432
  await super.teardown();
433
433
  }
434
434
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crawlee/browser",
3
- "version": "4.0.0-beta.105",
3
+ "version": "4.0.0-beta.106",
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"
@@ -48,10 +48,10 @@
48
48
  },
49
49
  "dependencies": {
50
50
  "@apify/timeout": "^0.4.4",
51
- "@crawlee/basic": "4.0.0-beta.105",
52
- "@crawlee/browser-pool": "4.0.0-beta.105",
53
- "@crawlee/types": "4.0.0-beta.105",
54
- "@crawlee/utils": "4.0.0-beta.105",
51
+ "@crawlee/basic": "4.0.0-beta.106",
52
+ "@crawlee/browser-pool": "4.0.0-beta.106",
53
+ "@crawlee/types": "4.0.0-beta.106",
54
+ "@crawlee/utils": "4.0.0-beta.106",
55
55
  "ow": "^2.0.0",
56
56
  "tslib": "^2.8.1",
57
57
  "type-fest": "^4.41.0"
@@ -75,5 +75,5 @@
75
75
  }
76
76
  }
77
77
  },
78
- "gitHead": "26073a822c7699ac487931383a39192bc3daae7a"
78
+ "gitHead": "c622f1fc65e65221ea245817c58ecc0ffb4a5cb0"
79
79
  }