@crawlee/browser 4.0.0-beta.82 → 4.0.0-beta.84

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.
@@ -224,17 +224,13 @@ export interface BrowserCrawlerOptions<Page extends CommonPage = CommonPage, Res
224
224
  * @category Crawlers
225
225
  */
226
226
  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, Dictionary> = BrowserCrawlingContext<Page, Response, Dictionary>, ContextExtension = Dictionary<never>, ExtendedContext extends Context = Context & ContextExtension, GoToOptions extends Dictionary = Dictionary> extends BasicCrawler<Context, ContextExtension, ExtendedContext> {
227
+ /** Backs the {@link BrowserCrawler.browserPool|`browserPool`} getter. */
228
+ private browserPoolDep;
227
229
  /**
228
230
  * A reference to the underlying browser pool that manages the crawler's browsers. Typed as
229
231
  * {@link IBrowserPool} so custom implementations can be plugged in via the `browserPool` constructor option.
230
232
  */
231
- browserPool: IBrowserPool<Page>;
232
- /**
233
- * Set when the crawler constructed its own pool (a {@link BrowserPool}, or a {@link RemoteBrowserPool}
234
- * built from the `remoteBrowser` option). Holds the same instance as `browserPool` but is the only reference
235
- * the crawler tears down — a user-supplied `browserPool` is never owned and never destroyed by the crawler.
236
- */
237
- private ownedBrowserPool?;
233
+ get browserPool(): IBrowserPool<Page>;
238
234
  launchContext: BrowserLaunchContext<LaunchOptions, unknown>;
239
235
  protected readonly ignoreShadowRoots: boolean;
240
236
  protected readonly ignoreIframes: boolean;
@@ -1,4 +1,4 @@
1
- import { BasicCrawler, browserPoolCookieToToughCookie, ContextPipeline, cookieStringToToughCookie, enqueueLinks, handleRequestTimeout, NavigationSkippedError, RequestState, resolveBaseUrlForEnqueueLinksFiltering, SessionError, toughCookieToBrowserPoolCookie, tryAbsoluteURL, validators, } from '@crawlee/basic';
1
+ import { BasicCrawler, browserPoolCookieToToughCookie, ContextPipeline, cookieStringToToughCookie, enqueueLinks, handleRequestTimeout, NavigationSkippedError, OwnedOrInjected, RequestState, resolveBaseUrlForEnqueueLinksFiltering, SessionError, toughCookieToBrowserPoolCookie, tryAbsoluteURL, validators, } from '@crawlee/basic';
2
2
  import { BrowserPool, RemoteBrowserPool } from '@crawlee/browser-pool';
3
3
  import { CLOUDFLARE_RETRY_CSS_SELECTORS, RETRY_CSS_SELECTORS, sleep } from '@crawlee/utils';
4
4
  import ow from 'ow';
@@ -48,17 +48,15 @@ const readContextField = (ctx, key) => ctx[key];
48
48
  * @category Crawlers
49
49
  */
50
50
  export class BrowserCrawler extends BasicCrawler {
51
+ /** Backs the {@link BrowserCrawler.browserPool|`browserPool`} getter. */
52
+ browserPoolDep;
51
53
  /**
52
54
  * A reference to the underlying browser pool that manages the crawler's browsers. Typed as
53
55
  * {@link IBrowserPool} so custom implementations can be plugged in via the `browserPool` constructor option.
54
56
  */
55
- browserPool;
56
- /**
57
- * Set when the crawler constructed its own pool (a {@link BrowserPool}, or a {@link RemoteBrowserPool}
58
- * built from the `remoteBrowser` option). Holds the same instance as `browserPool` but is the only reference
59
- * the crawler tears down — a user-supplied `browserPool` is never owned and never destroyed by the crawler.
60
- */
61
- ownedBrowserPool;
57
+ get browserPool() {
58
+ return this.browserPoolDep.value;
59
+ }
62
60
  launchContext;
63
61
  ignoreShadowRoots;
64
62
  ignoreIframes;
@@ -120,35 +118,34 @@ export class BrowserCrawler extends BasicCrawler {
120
118
  this.launchContext.launchOptions.headless = headless;
121
119
  }
122
120
  this.saveResponseCookies = saveResponseCookies;
123
- // `browserPool` wins over `remoteBrowser` — a passed-in pool is used as-is, the sugar is ignored.
124
- if (browserPool) {
125
- this.browserPool = browserPool;
126
- return;
127
- }
128
- const resolvedBrowserPoolOptions = browserPoolOptions ?? {};
129
- if (launchContext?.userAgent) {
130
- if (resolvedBrowserPoolOptions.useFingerprints)
131
- this.log.info('Custom user agent provided, disabling automatic browser fingerprint injection!');
132
- resolvedBrowserPoolOptions.useFingerprints = false;
133
- }
134
- if (remoteBrowser) {
135
- // The crawler already built the right plugin for its browser hand it to a RemoteBrowserPool so the
136
- // remote connection is always for the matching browser (no plugin to construct, no way to mismatch).
137
- const { browserPlugins, ...remoteBrowserPoolOptions } = resolvedBrowserPoolOptions;
138
- const remotePool = new RemoteBrowserPool({
139
- browserPlugins: browserPlugins,
140
- ...remoteBrowser,
141
- browserPoolOptions: remoteBrowserPoolOptions,
121
+ // `browserPool` wins over `remoteBrowser` — a passed-in pool is used as-is (borrowed), the sugar is ignored.
122
+ // The default is only built when no pool was injected, so all the option/launchContext fiddling below stays
123
+ // inside the factory.
124
+ this.browserPoolDep = OwnedOrInjected.resolve(browserPool, () => {
125
+ const resolvedBrowserPoolOptions = browserPoolOptions ?? {};
126
+ if (launchContext?.userAgent) {
127
+ if (resolvedBrowserPoolOptions.useFingerprints)
128
+ this.log.info('Custom user agent provided, disabling automatic browser fingerprint injection!');
129
+ resolvedBrowserPoolOptions.useFingerprints = false;
130
+ }
131
+ if (remoteBrowser) {
132
+ // The crawler already built the right plugin for its browser — hand it to a RemoteBrowserPool so the
133
+ // remote connection is always for the matching browser (no plugin to construct, no way to mismatch).
134
+ const { browserPlugins, ...remoteBrowserPoolOptions } = resolvedBrowserPoolOptions;
135
+ return new RemoteBrowserPool({
136
+ browserPlugins: browserPlugins,
137
+ ...remoteBrowser,
138
+ browserPoolOptions: remoteBrowserPoolOptions,
139
+ });
140
+ }
141
+ // Double cast: `BrowserPool` implements `IBrowserPool<PageReturn>`, where `PageReturn` is derived from the
142
+ // plugin/controller generics and doesn't overlap with the crawler's free `Page` type param, so TS won't
143
+ // narrow it directly. The concrete pool does satisfy the `Page`/`destroy` contract at runtime — this is the
144
+ // long-standing `Page` variance gap, not a `destroy`-related hole.
145
+ return new BrowserPool({
146
+ ...resolvedBrowserPoolOptions,
142
147
  });
143
- this.ownedBrowserPool = remotePool;
144
- this.browserPool = remotePool;
145
- return;
146
- }
147
- const ownedBrowserPool = new BrowserPool({
148
- ...resolvedBrowserPoolOptions,
149
148
  });
150
- this.ownedBrowserPool = ownedBrowserPool;
151
- this.browserPool = ownedBrowserPool;
152
149
  }
153
150
  buildContextPipeline() {
154
151
  return ContextPipeline.create().compose({
@@ -363,7 +360,7 @@ export class BrowserCrawler extends BasicCrawler {
363
360
  * @ignore
364
361
  */
365
362
  async teardown() {
366
- await this.ownedBrowserPool?.destroy();
363
+ await this.browserPoolDep.ifOwned((pool) => pool.destroy());
367
364
  await super.teardown();
368
365
  }
369
366
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crawlee/browser",
3
- "version": "4.0.0-beta.82",
3
+ "version": "4.0.0-beta.84",
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.3.2",
51
- "@crawlee/basic": "4.0.0-beta.82",
52
- "@crawlee/browser-pool": "4.0.0-beta.82",
53
- "@crawlee/types": "4.0.0-beta.82",
54
- "@crawlee/utils": "4.0.0-beta.82",
51
+ "@crawlee/basic": "4.0.0-beta.84",
52
+ "@crawlee/browser-pool": "4.0.0-beta.84",
53
+ "@crawlee/types": "4.0.0-beta.84",
54
+ "@crawlee/utils": "4.0.0-beta.84",
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": "eb1096f7c7743d124375ef011fbbadb19476822e"
78
+ "gitHead": "5f8f4ae742975dc914c865c9766b93d274d7468f"
79
79
  }