@crawlee/browser-pool 4.0.0-beta.2 → 4.0.0-beta.200

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 (83) hide show
  1. package/README.md +17 -13
  2. package/abstract-classes/browser-controller.d.ts +100 -29
  3. package/abstract-classes/browser-controller.js +70 -24
  4. package/abstract-classes/browser-plugin.d.ts +54 -23
  5. package/abstract-classes/browser-plugin.js +75 -13
  6. package/anonymize-proxy.d.ts +6 -2
  7. package/anonymize-proxy.js +9 -5
  8. package/browser-pool.d.ts +122 -48
  9. package/browser-pool.js +326 -143
  10. package/events.d.ts +2 -4
  11. package/events.js +0 -2
  12. package/fingerprinting/hooks.d.ts +0 -1
  13. package/fingerprinting/hooks.js +26 -10
  14. package/fingerprinting/types.d.ts +3 -34
  15. package/fingerprinting/types.js +0 -2
  16. package/fingerprinting/utils.d.ts +0 -1
  17. package/fingerprinting/utils.js +5 -6
  18. package/index.d.ts +14 -7
  19. package/index.js +5 -3
  20. package/launch-context.d.ts +21 -5
  21. package/launch-context.js +21 -10
  22. package/package.json +11 -11
  23. package/playwright/playwright-browser.d.ts +3 -6
  24. package/playwright/playwright-browser.js +17 -17
  25. package/playwright/playwright-controller.d.ts +1 -1
  26. package/playwright/playwright-controller.js +24 -13
  27. package/playwright/playwright-plugin.d.ts +12 -7
  28. package/playwright/playwright-plugin.js +42 -16
  29. package/proxy-server.d.ts +0 -1
  30. package/proxy-server.js +0 -1
  31. package/puppeteer/puppeteer-controller.d.ts +1 -1
  32. package/puppeteer/puppeteer-controller.js +29 -20
  33. package/puppeteer/puppeteer-plugin.d.ts +9 -3
  34. package/puppeteer/puppeteer-plugin.js +87 -46
  35. package/remote-browser-pool.d.ts +178 -0
  36. package/remote-browser-pool.js +206 -0
  37. package/remote-browser-provider.d.ts +83 -0
  38. package/remote-browser-provider.js +67 -0
  39. package/utils.d.ts +7 -1
  40. package/utils.js +19 -1
  41. package/abstract-classes/browser-controller.d.ts.map +0 -1
  42. package/abstract-classes/browser-controller.js.map +0 -1
  43. package/abstract-classes/browser-plugin.d.ts.map +0 -1
  44. package/abstract-classes/browser-plugin.js.map +0 -1
  45. package/anonymize-proxy.d.ts.map +0 -1
  46. package/anonymize-proxy.js.map +0 -1
  47. package/browser-pool.d.ts.map +0 -1
  48. package/browser-pool.js.map +0 -1
  49. package/container-proxy-server.d.ts +0 -12
  50. package/container-proxy-server.d.ts.map +0 -1
  51. package/container-proxy-server.js +0 -43
  52. package/container-proxy-server.js.map +0 -1
  53. package/events.d.ts.map +0 -1
  54. package/events.js.map +0 -1
  55. package/fingerprinting/hooks.d.ts.map +0 -1
  56. package/fingerprinting/hooks.js.map +0 -1
  57. package/fingerprinting/types.d.ts.map +0 -1
  58. package/fingerprinting/types.js.map +0 -1
  59. package/fingerprinting/utils.d.ts.map +0 -1
  60. package/fingerprinting/utils.js.map +0 -1
  61. package/index.d.ts.map +0 -1
  62. package/index.js.map +0 -1
  63. package/launch-context.d.ts.map +0 -1
  64. package/launch-context.js.map +0 -1
  65. package/logger.d.ts +0 -3
  66. package/logger.d.ts.map +0 -1
  67. package/logger.js +0 -5
  68. package/logger.js.map +0 -1
  69. package/playwright/playwright-browser.d.ts.map +0 -1
  70. package/playwright/playwright-browser.js.map +0 -1
  71. package/playwright/playwright-controller.d.ts.map +0 -1
  72. package/playwright/playwright-controller.js.map +0 -1
  73. package/playwright/playwright-plugin.d.ts.map +0 -1
  74. package/playwright/playwright-plugin.js.map +0 -1
  75. package/proxy-server.d.ts.map +0 -1
  76. package/proxy-server.js.map +0 -1
  77. package/puppeteer/puppeteer-controller.d.ts.map +0 -1
  78. package/puppeteer/puppeteer-controller.js.map +0 -1
  79. package/puppeteer/puppeteer-plugin.d.ts.map +0 -1
  80. package/puppeteer/puppeteer-plugin.js.map +0 -1
  81. package/tsconfig.build.tsbuildinfo +0 -1
  82. package/utils.d.ts.map +0 -1
  83. package/utils.js.map +0 -1
@@ -1,6 +1,7 @@
1
- import { CriticalError } from '@crawlee/core';
1
+ import { CriticalError, serviceLocator } from '@crawlee/core';
2
2
  import merge from 'lodash.merge';
3
3
  import { LaunchContext } from '../launch-context.js';
4
+ import { sanitizeEndpointForLog } from '../utils.js';
4
5
  /**
5
6
  * The default User Agent used by `PlaywrightCrawler`, `launchPlaywright`, 'PuppeteerCrawler' and 'launchPuppeteer'
6
7
  * when Chromium/Chrome browser is launched:
@@ -8,8 +9,6 @@ import { LaunchContext } from '../launch-context.js';
8
9
  * - without using a fingerprint,
9
10
  * - without specifying a user agent.
10
11
  * Last updated on 2022-05-05.
11
- *
12
- * After you update it here, please update it also in jsdom-crawler.ts
13
12
  */
14
13
  export const DEFAULT_USER_AGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36';
15
14
  /**
@@ -20,20 +19,79 @@ export const DEFAULT_USER_AGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_
20
19
  */
21
20
  export class BrowserPlugin {
22
21
  name = this.constructor.name;
22
+ /**
23
+ * Kept `protected` rather than `#private` because the concrete plugins in this package are separate
24
+ * classes — an ES private field would not be visible to them.
25
+ *
26
+ * @internal
27
+ */
28
+ log;
23
29
  library;
24
30
  launchOptions;
25
31
  proxyUrl;
26
32
  userDataDir;
27
33
  useIncognitoPages;
28
34
  browserPerProxy;
35
+ ignoreProxyCertificate;
36
+ /**
37
+ * Set by {@link RemoteBrowserPool} when this plugin connects to a remote browser service instead of
38
+ * launching locally. Holds the bridge the plugin uses to resolve endpoints and release sessions; all
39
+ * remote-session policy lives in the pool, not here.
40
+ *
41
+ * @internal
42
+ */
43
+ remoteConnection;
44
+ /** Static connect() parameters for a remote connection (protocol, headers, …). @internal */
45
+ remoteConnectionParameters;
29
46
  constructor(library, options = {}) {
30
- const { launchOptions = {}, proxyUrl, userDataDir, useIncognitoPages = false, browserPerProxy = false, } = options;
47
+ const { launchOptions = {}, proxyUrl, userDataDir, useIncognitoPages = false, browserPerProxy = false, ignoreProxyCertificate = false, } = options;
48
+ this.log = serviceLocator.getLogger().child({ prefix: 'BrowserPool' });
31
49
  this.library = library;
32
50
  this.launchOptions = launchOptions;
33
51
  this.proxyUrl = proxyUrl && new URL(proxyUrl).href.slice(0, -1);
34
52
  this.userDataDir = userDataDir;
35
53
  this.useIncognitoPages = useIncognitoPages;
36
54
  this.browserPerProxy = browserPerProxy;
55
+ this.ignoreProxyCertificate = ignoreProxyCertificate;
56
+ }
57
+ /**
58
+ * Configures this plugin to connect to a remote browser using the given {@link RemoteConnection}.
59
+ * Called by {@link RemoteBrowserPool}; subclasses may override to apply library-specific defaults
60
+ * (e.g. forcing incognito pages).
61
+ *
62
+ * @internal
63
+ */
64
+ useRemoteConnection(connection, parameters = {}) {
65
+ this.remoteConnection = connection;
66
+ this.remoteConnectionParameters = parameters;
67
+ }
68
+ /**
69
+ * Resolves a remote endpoint via the injected {@link RemoteConnection}, stores the session token on
70
+ * the launch context (so the controller can release it on close), and runs the library-specific `connect`.
71
+ * On failure the session is released and the error is wrapped in a {@link BrowserLaunchError}.
72
+ *
73
+ * Subclasses implement only the `connect` callback — the resolve / token / release / error-wrap scaffolding
74
+ * lives here so it stays identical across plugins.
75
+ */
76
+ async connectToRemoteBrowser(launchContext, connect) {
77
+ const connection = this.remoteConnection;
78
+ let url;
79
+ let token;
80
+ try {
81
+ ({ url, token } = await connection.resolve({ proxyUrl: launchContext.proxyUrl }));
82
+ }
83
+ catch (cause) {
84
+ throw new BrowserLaunchError('Failed to resolve the remote browser endpoint.', { cause });
85
+ }
86
+ launchContext.remoteToken = token;
87
+ try {
88
+ return await connect(url);
89
+ }
90
+ catch (cause) {
91
+ await connection.release(token);
92
+ throw new BrowserLaunchError(`Failed to connect to remote browser at "${sanitizeEndpointForLog(url)}". ` +
93
+ 'Check that the endpoint is reachable and accepts the configured protocol.', { cause });
94
+ }
37
95
  }
38
96
  /**
39
97
  * Creates a `LaunchContext` with all the information needed
@@ -42,7 +100,7 @@ export class BrowserPlugin {
42
100
  * management of the pool and extra features.
43
101
  */
44
102
  createLaunchContext(options = {}) {
45
- const { id, launchOptions = {}, proxyUrl = this.proxyUrl, useIncognitoPages = this.useIncognitoPages, userDataDir = this.userDataDir, browserPerProxy = this.browserPerProxy, proxyTier, } = options;
103
+ const { id, launchOptions = {}, proxyUrl = this.proxyUrl, useIncognitoPages = this.useIncognitoPages, userDataDir = this.userDataDir, browserPerProxy = this.browserPerProxy, ignoreProxyCertificate = this.ignoreProxyCertificate, isRemote = !!this.remoteConnection, } = options;
46
104
  return new LaunchContext({
47
105
  id,
48
106
  launchOptions: merge({}, this.launchOptions, launchOptions),
@@ -51,21 +109,23 @@ export class BrowserPlugin {
51
109
  useIncognitoPages,
52
110
  userDataDir,
53
111
  browserPerProxy,
54
- proxyTier,
112
+ ignoreProxyCertificate,
113
+ isRemote,
55
114
  });
56
115
  }
57
116
  /**
58
117
  * Launches the browser using provided launch context.
59
118
  */
60
119
  async launch(launchContext = this.createLaunchContext()) {
120
+ // launchOptions is only used by the local launch path below — remote connections ignore it.
61
121
  launchContext.launchOptions ??= {};
62
122
  const { proxyUrl, launchOptions } = launchContext;
63
- if (proxyUrl) {
64
- await this._addProxyToLaunchOptions(launchContext);
123
+ if (proxyUrl && !launchContext.isRemote) {
124
+ await this.addProxyToLaunchOptions(launchContext);
65
125
  }
66
- if (this._isChromiumBasedBrowser(launchContext)) {
126
+ if (!launchContext.isRemote && this.isChromiumBasedBrowser(launchContext)) {
67
127
  // This will set the args for chromium based browsers to hide the webdriver.
68
- launchOptions.args = this._mergeArgsToHideWebdriver(launchOptions.args);
128
+ launchOptions.args = this.mergeArgsToHideWebdriver(launchOptions.args);
69
129
  // When User-Agent is not set, and we're using Chromium in headless mode,
70
130
  // it is better to use DEFAULT_USER_AGENT to reduce chance of detection,
71
131
  // as otherwise 'HeadlessChrome' is present in User-Agent string.
@@ -74,9 +134,12 @@ export class BrowserPlugin {
74
134
  launchOptions.args.push(`--user-agent=${DEFAULT_USER_AGENT}`);
75
135
  }
76
136
  }
137
+ if (launchContext.isRemote) {
138
+ this.log.info('Connecting to remote browser (skipping local proxy and webdriver stealth configuration).');
139
+ }
77
140
  return this._launch(launchContext);
78
141
  }
79
- _mergeArgsToHideWebdriver(originalArgs) {
142
+ mergeArgsToHideWebdriver(originalArgs) {
80
143
  if (!originalArgs?.length) {
81
144
  return ['--disable-blink-features=AutomationControlled'];
82
145
  }
@@ -89,7 +152,7 @@ export class BrowserPlugin {
89
152
  }
90
153
  return originalArgs;
91
154
  }
92
- _throwAugmentedLaunchError(cause, executablePath, dockerImage, moduleInstallCommand) {
155
+ throwAugmentedLaunchError(cause, executablePath, dockerImage, moduleInstallCommand) {
93
156
  const errorMessage = ['Failed to launch browser. Please check the following:'];
94
157
  if (executablePath) {
95
158
  errorMessage.push(`- Check whether the provided executable path "${executablePath}" is correct.`);
@@ -118,4 +181,3 @@ export class BrowserLaunchError extends CriticalError {
118
181
  });
119
182
  }
120
183
  }
121
- //# sourceMappingURL=browser-plugin.js.map
@@ -1,4 +1,8 @@
1
1
  type PromiseVoid = () => Promise<void>;
2
- export declare const anonymizeProxySugar: (proxyUrl?: string, username?: string, password?: string) => Promise<[string | undefined, PromiseVoid]>;
2
+ /** @internal */
3
+ export interface AnonymizeProxySugarOptions {
4
+ ignoreProxyCertificate?: boolean;
5
+ }
6
+ /** @internal */
7
+ export declare const anonymizeProxySugar: (proxyUrl?: string, username?: string, password?: string, options?: AnonymizeProxySugarOptions) => Promise<[string | undefined, PromiseVoid]>;
3
8
  export {};
4
- //# sourceMappingURL=anonymize-proxy.d.ts.map
@@ -1,15 +1,20 @@
1
- import { anonymizeProxy, closeAnonymizedProxy } from 'proxy-chain';
2
- export const anonymizeProxySugar = async (proxyUrl, username, password) => {
1
+ /** @internal */
2
+ export const anonymizeProxySugar = async (proxyUrl, username, password, options) => {
3
3
  if (proxyUrl) {
4
4
  const url = new URL(proxyUrl);
5
5
  if (username || password) {
6
6
  url.username = username ?? '';
7
7
  url.password = password ?? '';
8
8
  }
9
- if (url.username || url.password) {
9
+ if (url.username || url.password || options?.ignoreProxyCertificate) {
10
10
  // trim off trailing slash if it's present
11
11
  const proxyUrlString = url.href.endsWith('/') ? url.href.slice(0, -1) : url.href;
12
- const anonymized = await anonymizeProxy(proxyUrlString);
12
+ const { anonymizeProxy, closeAnonymizedProxy } = await import('proxy-chain');
13
+ const anonymized = await anonymizeProxy({
14
+ url: proxyUrlString,
15
+ port: 0,
16
+ ignoreProxyCertificate: options?.ignoreProxyCertificate ?? false,
17
+ });
13
18
  return [
14
19
  anonymized,
15
20
  async () => {
@@ -21,4 +26,3 @@ export const anonymizeProxySugar = async (proxyUrl, username, password) => {
21
26
  }
22
27
  return [undefined, async () => { }];
23
28
  };
24
- //# sourceMappingURL=anonymize-proxy.js.map
package/browser-pool.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import type { IBrowserPool, NewPageOptions, PageState } from '@crawlee/types';
1
2
  import type { BrowserFingerprintWithHeaders } from 'fingerprint-generator';
2
3
  import { FingerprintGenerator } from 'fingerprint-generator';
3
4
  import { FingerprintInjector } from 'fingerprint-injector';
@@ -246,37 +247,39 @@ export interface BrowserPoolHooks<BC extends BrowserController, LC extends Launc
246
247
  * });
247
248
  * ```
248
249
  */
249
- export declare class BrowserPool<Options extends BrowserPoolOptions = BrowserPoolOptions, BrowserPlugins extends BrowserPlugin[] = InferBrowserPluginArray<Options['browserPlugins']>, BrowserControllerReturn extends BrowserController = ReturnType<BrowserPlugins[number]['createController']>, LaunchContextReturn extends LaunchContext = ReturnType<BrowserPlugins[number]['createLaunchContext']>, PageOptions = Parameters<BrowserControllerReturn['newPage']>[0], PageReturn extends UnwrapPromise<ReturnType<BrowserControllerReturn['newPage']>> = UnwrapPromise<ReturnType<BrowserControllerReturn['newPage']>>> extends TypedEmitter<BrowserPoolEvents<BrowserControllerReturn, PageReturn>> {
250
+ export declare class BrowserPool<Options extends BrowserPoolOptions = BrowserPoolOptions, BrowserPlugins extends BrowserPlugin[] = InferBrowserPluginArray<Options['browserPlugins']>, BrowserControllerReturn extends BrowserController = ReturnType<BrowserPlugins[number]['createController']>, LaunchContextReturn extends LaunchContext = ReturnType<BrowserPlugins[number]['createLaunchContext']>, PageOptions = Parameters<BrowserControllerReturn['newPage']>[0], PageReturn extends UnwrapPromise<ReturnType<BrowserControllerReturn['newPage']>> = UnwrapPromise<ReturnType<BrowserControllerReturn['newPage']>>> extends TypedEmitter<BrowserPoolEvents<BrowserControllerReturn, PageReturn>> implements IBrowserPool<PageReturn> {
251
+ #private;
250
252
  browserPlugins: BrowserPlugins;
251
- maxOpenPagesPerBrowser: number;
252
- retireBrowserAfterPageCount: number;
253
- operationTimeoutMillis: number;
254
- closeInactiveBrowserAfterMillis: number;
255
- useFingerprints?: boolean;
253
+ /** @internal */
254
+ maxOpenBrowsers: number;
255
+ /** @internal */
256
256
  fingerprintOptions: FingerprintOptions;
257
- preLaunchHooks: PreLaunchHook<LaunchContextReturn>[];
258
- postLaunchHooks: PostLaunchHook<BrowserControllerReturn>[];
259
- prePageCreateHooks: PrePageCreateHook<BrowserControllerReturn, PageOptions>[];
260
- postPageCreateHooks: PostPageCreateHook<BrowserControllerReturn, PageReturn>[];
261
- prePageCloseHooks: PrePageCloseHook<BrowserControllerReturn, PageReturn>[];
262
- postPageCloseHooks: PostPageCloseHook<BrowserControllerReturn>[];
263
- pageCounter: number;
264
- pages: Map<string, PageReturn>;
265
- pageIds: WeakMap<PageReturn, string>;
266
- activeBrowserControllers: Set<BrowserControllerReturn>;
267
- retiredBrowserControllers: Set<BrowserControllerReturn>;
268
- pageToBrowserController: WeakMap<PageReturn, BrowserControllerReturn>;
257
+ /** @internal */
269
258
  fingerprintInjector?: FingerprintInjector;
270
259
  fingerprintGenerator?: FingerprintGenerator;
260
+ /** @internal */
271
261
  fingerprintCache?: QuickLRU<string, BrowserFingerprintWithHeaders>;
262
+ private pages;
263
+ private activeBrowserControllers;
264
+ private retiredBrowserControllers;
272
265
  private browserKillerInterval?;
273
- private browserRetireInterval?;
274
- private limiter;
275
266
  constructor(options: Options & BrowserPoolHooks<BrowserControllerReturn, LaunchContextReturn, PageReturn>);
276
267
  /**
277
268
  * Opens a new page in one of the running browsers or launches
278
269
  * a new browser and opens a page there, if no browsers are active,
279
270
  * or their page limits have been exceeded.
271
+ *
272
+ * **Session injection (best-effort):** When a {@link NewPageOptions.session|session} is
273
+ * provided, this implementation uses it as a cache key for browser fingerprints (when
274
+ * fingerprinting is enabled) and reads
275
+ * {@link ProxyInfo.url|session.proxyInfo.url} /
276
+ * {@link ProxyInfo.ignoreTlsErrors|session.proxyInfo.ignoreTlsErrors} as defaults
277
+ * for `proxyUrl` and `ignoreTlsErrors` respectively. Explicit `proxyUrl` /
278
+ * `ignoreTlsErrors` values in the options take precedence.
279
+ *
280
+ * Beyond fingerprint caching and proxy configuration, no other session
281
+ * properties are consumed — cookie and header injection remain the
282
+ * crawler's responsibility.
280
283
  */
281
284
  newPage(options?: BrowserPoolNewPageOptions<PageOptions, BrowserPlugins[number]>): Promise<PageReturn>;
282
285
  /**
@@ -334,7 +337,7 @@ export declare class BrowserPool<Options extends BrowserPoolOptions = BrowserPoo
334
337
  * until it's closed.
335
338
  */
336
339
  getPageId(page: PageReturn): string | undefined;
337
- private _createPageForBrowser;
340
+ private createPageForBrowser;
338
341
  /**
339
342
  * Removes a browser controller from the pool. The underlying
340
343
  * browser will be closed after all its pages are closed.
@@ -346,6 +349,43 @@ export declare class BrowserPool<Options extends BrowserPoolOptions = BrowserPoo
346
349
  * closed after all its pages are closed.
347
350
  */
348
351
  retireBrowserByPage(page: PageReturn): void;
352
+ /**
353
+ * Releases a page back to the pool. The page is closed and, if the
354
+ * optional `error` is a {@link SessionError}, the browser controller
355
+ * that served the page is retired so that its tainted state (cookies,
356
+ * storage, etc.) cannot leak into future sessions.
357
+ *
358
+ * This is the primary way the crawler should return pages to the pool.
359
+ *
360
+ * @param page The page to release.
361
+ * @param options.error The error that caused the page to be released, if any.
362
+ */
363
+ closePage(page: PageReturn, options?: {
364
+ error?: Error;
365
+ }): Promise<void>;
366
+ /**
367
+ * Extracts the relevant state (currently just cookies) from a page via its
368
+ * owning {@link BrowserController}. Returns empty state when the page is
369
+ * no longer associated with a controller.
370
+ *
371
+ * As with {@link BrowserPool.injectPageState}, cookies are isolated per
372
+ * page only when the pool is configured with `useIncognitoPages: true`.
373
+ * With the default `useIncognitoPages: false`, the extracted cookies
374
+ * include those set by any sibling page sharing the same browser.
375
+ */
376
+ extractPageState(page: PageReturn): Promise<PageState>;
377
+ /**
378
+ * Injects state into a page via its owning {@link BrowserController}.
379
+ *
380
+ * No-op when the page is no longer associated with a controller.
381
+ *
382
+ * Note that cookies are isolated per page only when the pool is configured
383
+ * with `useIncognitoPages: true` — each page then gets its own browser
384
+ * context. With the default `useIncognitoPages: false`, all pages in a
385
+ * browser share a single context, so injected cookies are visible to every
386
+ * page served by that browser.
387
+ */
388
+ injectPageState(page: PageReturn, state: PageState): Promise<void>;
349
389
  /**
350
390
  * Removes all active browsers from the pool. The browsers will be
351
391
  * closed after all their pages are closed.
@@ -356,32 +396,75 @@ export declare class BrowserPool<Options extends BrowserPoolOptions = BrowserPoo
356
396
  * @return {Promise<void>}
357
397
  */
358
398
  closeAllBrowsers(): Promise<void>;
399
+ [Symbol.asyncDispose](): Promise<void>;
359
400
  /**
360
- * Closes all managed browsers and tears down the pool.
401
+ * Closes every managed browser and empties the pool, which stays usable afterwards — a crawler releases its
402
+ * browsers when a run ends and may start another run on the same pool.
403
+ */
404
+ releaseAllBrowsers(): Promise<void>;
405
+ /**
406
+ * Closes all managed browsers and tears the pool down for good: its intervals are cleared without being
407
+ * re-armed and its listeners are dropped, so it cannot be used again.
361
408
  */
362
409
  destroy(): Promise<void>;
363
- private _teardown;
364
- private _getAllBrowserControllers;
365
- private _launchBrowser;
410
+ private getAllBrowserControllers;
411
+ private launchBrowser;
366
412
  /**
367
413
  * Picks plugins round robin.
368
- * @private
369
- */
370
- private _pickBrowserPlugin;
371
- private _pickBrowserWithFreeCapacity;
372
- private _closeInactiveRetiredBrowsers;
373
- private _overridePageClose;
374
- private _executeHooks;
375
- private _closeRetiredBrowserWithNoPages;
376
- private _initializeFingerprinting;
377
- private _addFingerprintHooks;
414
+ */
415
+ private pickBrowserPlugin;
416
+ private pickBrowserWithFreeCapacity;
417
+ private closeInactiveRetiredBrowsers;
418
+ private overridePageClose;
419
+ private executeHooks;
420
+ private closeRetiredBrowserWithNoPages;
421
+ /**
422
+ * Returns `true` if the pool can accept a new browser launch without exceeding `maxOpenBrowsers`.
423
+ * Counts starting, active, and retired browsers.
424
+ *
425
+ * A plain `BrowserPool` leaves `maxOpenBrowsers` at `Infinity`, so this only returns `false` when something
426
+ * has set a cap — {@link RemoteBrowserPool} does, from its own
427
+ * {@link RemoteBrowserPoolOptions.maxOpenBrowsers|`maxOpenBrowsers`} option. There is no
428
+ * `BrowserPoolOptions` key for it.
429
+ *
430
+ * @internal
431
+ */
432
+ hasFreeBrowserSlot(): boolean;
433
+ /**
434
+ * Returns `true` if any active browser has room for another page.
435
+ *
436
+ * @internal
437
+ */
438
+ hasActiveBrowserWithFreeCapacity(): boolean;
439
+ private initializeFingerprinting;
378
440
  }
379
- export interface BrowserPoolNewPageOptions<PageOptions, BP extends BrowserPlugin> {
441
+ export interface BrowserPoolNewPageOptions<PageOptions, BP extends BrowserPlugin> extends NewPageOptions {
442
+ /**
443
+ * The proxy URL the pool uses internally to route the page: it keys browser
444
+ * reuse (with `browserPerProxy`, only a browser already on this proxy is
445
+ * reused), configures the launched browser, and is applied to incognito
446
+ * pages. When omitted, it is derived from the
447
+ * {@link NewPageOptions.session|session}'s `proxyInfo`; an explicit value
448
+ * here takes precedence.
449
+ *
450
+ * This is an implementation detail of the built-in `BrowserPool`'s proxy
451
+ * handling and is intentionally not part of the {@link IBrowserPool}
452
+ * contract — through that interface the proxy is supplied via the session.
453
+ */
454
+ proxyUrl?: string;
380
455
  /**
381
- * Assign a custom ID to the page. If you don't a random string ID
382
- * will be generated.
456
+ * Disable TLS certificate verification for MITM proxies. Applied both when
457
+ * launching a new browser and when creating a page in an existing one. When
458
+ * omitted, it is derived from the
459
+ * {@link NewPageOptions.session|session}'s `proxyInfo`; an explicit value
460
+ * here takes precedence.
461
+ *
462
+ * This is an implementation detail of the built-in `BrowserPool` and is
463
+ * intentionally not part of the {@link IBrowserPool} contract — through
464
+ * that interface, configure it via the session's `proxyInfo` or through the
465
+ * browser's `launchOptions`.
383
466
  */
384
- id?: string;
467
+ ignoreTlsErrors?: boolean;
385
468
  /**
386
469
  * Some libraries (Playwright) allow you to open new pages with specific
387
470
  * options. Use this property to set those options.
@@ -396,14 +479,6 @@ export interface BrowserPoolNewPageOptions<PageOptions, BP extends BrowserPlugin
396
479
  * see the `newPageInNewBrowser` function.
397
480
  */
398
481
  browserPlugin?: BP;
399
- /**
400
- * Proxy URL.
401
- */
402
- proxyUrl?: string;
403
- /**
404
- * Proxy tier.
405
- */
406
- proxyTier?: number;
407
482
  }
408
483
  export interface BrowserPoolNewPageInNewBrowserOptions<PageOptions, BP extends BrowserPlugin> {
409
484
  /**
@@ -434,4 +509,3 @@ export interface BrowserPoolNewPageInNewBrowserOptions<PageOptions, BP extends B
434
509
  */
435
510
  launchOptions?: BP['launchOptions'];
436
511
  }
437
- //# sourceMappingURL=browser-pool.d.ts.map