@crawlee/browser-pool 4.0.0-rc.0 → 4.0.0-rc.1
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.
- package/README.md +1 -1
- package/abstract-classes/browser-controller.d.ts +30 -16
- package/abstract-classes/browser-controller.js +50 -3
- package/abstract-classes/browser-plugin.d.ts +7 -9
- package/abstract-classes/browser-plugin.js +8 -4
- package/anonymize-proxy.d.ts +1 -0
- package/browser-pool.d.ts +28 -37
- package/browser-pool.js +171 -112
- package/events.d.ts +0 -1
- package/events.js +0 -1
- package/fingerprinting/types.d.ts +1 -31
- package/fingerprinting/types.js +0 -1
- package/index.d.ts +1 -1
- package/launch-context.d.ts +1 -0
- package/package.json +8 -7
- package/playwright/playwright-browser.d.ts +1 -0
- package/playwright/playwright-browser.js +1 -0
- package/playwright/playwright-controller.d.ts +1 -0
- package/playwright/playwright-controller.js +4 -3
- package/playwright/playwright-plugin.d.ts +2 -1
- package/playwright/playwright-plugin.js +5 -3
- package/puppeteer/puppeteer-controller.d.ts +1 -0
- package/puppeteer/puppeteer-controller.js +13 -11
- package/puppeteer/puppeteer-plugin.d.ts +5 -1
- package/puppeteer/puppeteer-plugin.js +5 -1
- package/remote-browser-pool.d.ts +16 -10
- package/remote-browser-pool.js +19 -5
- package/container-proxy-server.d.ts +0 -11
- package/container-proxy-server.js +0 -42
package/README.md
CHANGED
|
@@ -34,7 +34,7 @@ Crawlee is available as the [`crawlee`](https://www.npmjs.com/package/crawlee) N
|
|
|
34
34
|
|
|
35
35
|
We recommend visiting the [Introduction tutorial](https://crawlee.dev/js/docs/introduction) in Crawlee documentation for more information.
|
|
36
36
|
|
|
37
|
-
> Crawlee requires **Node.js
|
|
37
|
+
> Crawlee requires **Node.js 22.13 or higher**.
|
|
38
38
|
|
|
39
39
|
### With Crawlee CLI
|
|
40
40
|
|
|
@@ -82,6 +82,12 @@ export interface BrowserControllerEvents<Library extends CommonLibrary, LibraryO
|
|
|
82
82
|
export declare abstract class BrowserController<Library extends CommonLibrary = CommonLibrary, LibraryOptions extends Dictionary | undefined = Parameters<Library['launch']>[0], LaunchResult extends CommonBrowser = UnwrapPromise<ReturnType<Library['launch']>>, NewPageOptions = Parameters<LaunchResult['newPage']>[0], NewPageResult = UnwrapPromise<ReturnType<LaunchResult['newPage']>>> extends TypedEmitter<BrowserControllerEvents<Library, LibraryOptions, LaunchResult, NewPageOptions, NewPageResult>> implements IBrowserController<NewPageResult> {
|
|
83
83
|
#private;
|
|
84
84
|
readonly id: string;
|
|
85
|
+
/**
|
|
86
|
+
* Kept `protected` rather than `#private` because the concrete controllers in this package are
|
|
87
|
+
* separate classes — an ES private field would not be visible to them.
|
|
88
|
+
*
|
|
89
|
+
* @internal
|
|
90
|
+
*/
|
|
85
91
|
protected readonly log: CrawleeLogger;
|
|
86
92
|
/**
|
|
87
93
|
* The `BrowserPlugin` instance used to launch the browser.
|
|
@@ -100,11 +106,17 @@ export declare abstract class BrowserController<Library extends CommonLibrary =
|
|
|
100
106
|
* `undefined` if no proxy is used
|
|
101
107
|
*/
|
|
102
108
|
proxyUrl?: string;
|
|
109
|
+
/** @internal */
|
|
103
110
|
isActive: boolean;
|
|
104
111
|
activePages: number;
|
|
112
|
+
/** @internal */
|
|
105
113
|
totalPages: number;
|
|
114
|
+
/** @internal */
|
|
106
115
|
lastPageOpenedAt: number;
|
|
107
|
-
|
|
116
|
+
/**
|
|
117
|
+
* Returns a promise that resolves once the browser controller has been activated.
|
|
118
|
+
*/
|
|
119
|
+
waitForActive(): Promise<void>;
|
|
108
120
|
constructor(browserPlugin: BrowserPlugin<Library, LibraryOptions, LaunchResult, NewPageOptions, NewPageResult>);
|
|
109
121
|
/**
|
|
110
122
|
* Activates the BrowserController. If you try to open new pages before
|
|
@@ -135,30 +147,32 @@ export declare abstract class BrowserController<Library extends CommonLibrary =
|
|
|
135
147
|
* @ignore
|
|
136
148
|
*/
|
|
137
149
|
newPage(pageOptions?: NewPageOptions): Promise<NewPageResult>;
|
|
138
|
-
setCookies(page: NewPageResult, cookies: Cookie[]): Promise<void>;
|
|
139
|
-
getCookies(page: NewPageResult): Promise<Cookie[]>;
|
|
140
150
|
/**
|
|
141
|
-
*
|
|
151
|
+
* Accounts for a page no longer being open. Callable from either side and safe to call twice:
|
|
152
|
+
* the page's own `close` event, or the pool when it gives up on a close that never settles.
|
|
153
|
+
* Tracked in a `WeakSet` rather than via `isClosed()`, because that reports the same event.
|
|
154
|
+
* @internal
|
|
142
155
|
*/
|
|
143
|
-
|
|
156
|
+
registerPageClosed(page: NewPageResult): void;
|
|
144
157
|
/**
|
|
145
|
-
*
|
|
158
|
+
* Registers cleanup belonging to a single page: an anonymizing proxy server, an incognito
|
|
159
|
+
* context. It runs from `registerPageClosed`, so it happens whether the page closed on its own
|
|
160
|
+
* or the pool gave up on a close that never settled, and it runs at most once.
|
|
161
|
+
*
|
|
162
|
+
* Hanging it off the page's `close` event instead leaks it in exactly the case this controller
|
|
163
|
+
* now handles, because that event does not arrive for a page the browser never destroyed.
|
|
164
|
+
* @ignore
|
|
146
165
|
*/
|
|
166
|
+
protected registerPageTeardown(page: NewPageResult, teardown: () => Promise<void>): void;
|
|
167
|
+
setCookies(page: NewPageResult, cookies: Cookie[]): Promise<void>;
|
|
168
|
+
getCookies(page: NewPageResult): Promise<Cookie[]>;
|
|
169
|
+
protected abstract _close(): Promise<void>;
|
|
147
170
|
protected abstract _kill(): Promise<void>;
|
|
148
|
-
/**
|
|
149
|
-
* @private
|
|
150
|
-
*/
|
|
151
171
|
protected abstract _newPage(pageOptions?: NewPageOptions): Promise<NewPageResult>;
|
|
152
|
-
/**
|
|
153
|
-
* @private
|
|
154
|
-
*/
|
|
155
172
|
protected abstract _setCookies(page: NewPageResult, cookies: Cookie[]): Promise<void>;
|
|
156
|
-
/**
|
|
157
|
-
* @private
|
|
158
|
-
*/
|
|
159
173
|
protected abstract _getCookies(page: NewPageResult): Promise<Cookie[]>;
|
|
160
174
|
/**
|
|
161
|
-
* @
|
|
175
|
+
* @internal
|
|
162
176
|
*/
|
|
163
177
|
abstract normalizeProxyOptions(proxyUrl: string | undefined, pageOptions: any): Record<string, unknown>;
|
|
164
178
|
}
|
|
@@ -14,6 +14,12 @@ const PROCESS_KILL_TIMEOUT_MILLIS = 5000;
|
|
|
14
14
|
*/
|
|
15
15
|
export class BrowserController extends TypedEmitter {
|
|
16
16
|
id = nanoid();
|
|
17
|
+
/**
|
|
18
|
+
* Kept `protected` rather than `#private` because the concrete controllers in this package are
|
|
19
|
+
* separate classes — an ES private field would not be visible to them.
|
|
20
|
+
*
|
|
21
|
+
* @internal
|
|
22
|
+
*/
|
|
17
23
|
log;
|
|
18
24
|
/**
|
|
19
25
|
* The `BrowserPlugin` instance used to launch the browser.
|
|
@@ -32,15 +38,25 @@ export class BrowserController extends TypedEmitter {
|
|
|
32
38
|
* `undefined` if no proxy is used
|
|
33
39
|
*/
|
|
34
40
|
proxyUrl;
|
|
41
|
+
/** @internal */
|
|
35
42
|
isActive = false;
|
|
36
43
|
activePages = 0;
|
|
44
|
+
#closedPages = new WeakSet();
|
|
45
|
+
#pageTeardowns = new WeakMap();
|
|
46
|
+
/** @internal */
|
|
37
47
|
totalPages = 0;
|
|
48
|
+
/** @internal */
|
|
38
49
|
lastPageOpenedAt = Date.now();
|
|
39
50
|
#activate;
|
|
40
|
-
|
|
41
|
-
isActivePromise = new Promise((resolve) => {
|
|
51
|
+
#isActivePromise = new Promise((resolve) => {
|
|
42
52
|
this.#activate = resolve;
|
|
43
53
|
});
|
|
54
|
+
/**
|
|
55
|
+
* Returns a promise that resolves once the browser controller has been activated.
|
|
56
|
+
*/
|
|
57
|
+
async waitForActive() {
|
|
58
|
+
await this.#isActivePromise;
|
|
59
|
+
}
|
|
44
60
|
#commitBrowser;
|
|
45
61
|
#hasBrowserPromise = new Promise((resolve) => {
|
|
46
62
|
this.#commitBrowser = resolve;
|
|
@@ -115,12 +131,43 @@ export class BrowserController extends TypedEmitter {
|
|
|
115
131
|
async newPage(pageOptions) {
|
|
116
132
|
this.activePages++;
|
|
117
133
|
this.totalPages++;
|
|
118
|
-
await this
|
|
134
|
+
await this.#isActivePromise;
|
|
119
135
|
const page = await this._newPage(pageOptions);
|
|
120
136
|
tryCancel();
|
|
121
137
|
this.lastPageOpenedAt = Date.now();
|
|
122
138
|
return page;
|
|
123
139
|
}
|
|
140
|
+
/**
|
|
141
|
+
* Accounts for a page no longer being open. Callable from either side and safe to call twice:
|
|
142
|
+
* the page's own `close` event, or the pool when it gives up on a close that never settles.
|
|
143
|
+
* Tracked in a `WeakSet` rather than via `isClosed()`, because that reports the same event.
|
|
144
|
+
* @internal
|
|
145
|
+
*/
|
|
146
|
+
registerPageClosed(page) {
|
|
147
|
+
if (this.#closedPages.has(page))
|
|
148
|
+
return;
|
|
149
|
+
this.#closedPages.add(page);
|
|
150
|
+
this.activePages--;
|
|
151
|
+
const teardown = this.#pageTeardowns.get(page);
|
|
152
|
+
if (!teardown)
|
|
153
|
+
return;
|
|
154
|
+
this.#pageTeardowns.delete(page);
|
|
155
|
+
teardown().catch((error) => {
|
|
156
|
+
this.log.debug(`Could not clean up after a closed page.\nCause:${error.message}`, { id: this.id });
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Registers cleanup belonging to a single page: an anonymizing proxy server, an incognito
|
|
161
|
+
* context. It runs from `registerPageClosed`, so it happens whether the page closed on its own
|
|
162
|
+
* or the pool gave up on a close that never settled, and it runs at most once.
|
|
163
|
+
*
|
|
164
|
+
* Hanging it off the page's `close` event instead leaks it in exactly the case this controller
|
|
165
|
+
* now handles, because that event does not arrive for a page the browser never destroyed.
|
|
166
|
+
* @ignore
|
|
167
|
+
*/
|
|
168
|
+
registerPageTeardown(page, teardown) {
|
|
169
|
+
this.#pageTeardowns.set(page, teardown);
|
|
170
|
+
}
|
|
124
171
|
async setCookies(page, cookies) {
|
|
125
172
|
return this._setCookies(page, cookies);
|
|
126
173
|
}
|
|
@@ -12,8 +12,6 @@ import type { BrowserController } from './browser-controller.js';
|
|
|
12
12
|
* - without using a fingerprint,
|
|
13
13
|
* - without specifying a user agent.
|
|
14
14
|
* Last updated on 2022-05-05.
|
|
15
|
-
*
|
|
16
|
-
* After you update it here, please update it also in jsdom-crawler.ts
|
|
17
15
|
*/
|
|
18
16
|
export declare 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";
|
|
19
17
|
/**
|
|
@@ -83,7 +81,14 @@ export interface CreateLaunchContextOptions<Library extends CommonLibrary, Libra
|
|
|
83
81
|
* feed them to {@link BrowserPool} for use.
|
|
84
82
|
*/
|
|
85
83
|
export declare abstract class BrowserPlugin<Library extends CommonLibrary = CommonLibrary, LibraryOptions extends Dictionary | undefined = Parameters<Library['launch']>[0], LaunchResult extends CommonBrowser = UnwrapPromise<ReturnType<Library['launch']>>, NewPageOptions = Parameters<LaunchResult['newPage']>[0], NewPageResult = UnwrapPromise<ReturnType<LaunchResult['newPage']>>> {
|
|
84
|
+
#private;
|
|
86
85
|
readonly name: string;
|
|
86
|
+
/**
|
|
87
|
+
* Kept `protected` rather than `#private` because the concrete plugins in this package are separate
|
|
88
|
+
* classes — an ES private field would not be visible to them.
|
|
89
|
+
*
|
|
90
|
+
* @internal
|
|
91
|
+
*/
|
|
87
92
|
protected readonly log: CrawleeLogger;
|
|
88
93
|
readonly library: Library;
|
|
89
94
|
readonly launchOptions: LibraryOptions;
|
|
@@ -132,16 +137,9 @@ export declare abstract class BrowserPlugin<Library extends CommonLibrary = Comm
|
|
|
132
137
|
* Launches the browser using provided launch context.
|
|
133
138
|
*/
|
|
134
139
|
launch(launchContext?: LaunchContext<Library, LibraryOptions, LaunchResult, NewPageOptions, NewPageResult>): Promise<LaunchResult>;
|
|
135
|
-
private mergeArgsToHideWebdriver;
|
|
136
140
|
protected throwAugmentedLaunchError(cause: unknown, executablePath: string | undefined, dockerImage: string, moduleInstallCommand: string): never;
|
|
137
|
-
/**
|
|
138
|
-
* @private
|
|
139
|
-
*/
|
|
140
141
|
protected abstract addProxyToLaunchOptions(launchContext: LaunchContext<Library, LibraryOptions, LaunchResult, NewPageOptions, NewPageResult>): Promise<void>;
|
|
141
142
|
protected abstract isChromiumBasedBrowser(launchContext: LaunchContext<Library, LibraryOptions, LaunchResult, NewPageOptions, NewPageResult>): boolean;
|
|
142
|
-
/**
|
|
143
|
-
* @private
|
|
144
|
-
*/
|
|
145
143
|
protected abstract _launch(launchContext: LaunchContext<Library, LibraryOptions, LaunchResult, NewPageOptions, NewPageResult>): Promise<LaunchResult>;
|
|
146
144
|
}
|
|
147
145
|
export declare class BrowserLaunchError extends CriticalError {
|
|
@@ -9,8 +9,6 @@ import { sanitizeEndpointForLog } from '../utils.js';
|
|
|
9
9
|
* - without using a fingerprint,
|
|
10
10
|
* - without specifying a user agent.
|
|
11
11
|
* Last updated on 2022-05-05.
|
|
12
|
-
*
|
|
13
|
-
* After you update it here, please update it also in jsdom-crawler.ts
|
|
14
12
|
*/
|
|
15
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';
|
|
16
14
|
/**
|
|
@@ -21,6 +19,12 @@ export const DEFAULT_USER_AGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_
|
|
|
21
19
|
*/
|
|
22
20
|
export class BrowserPlugin {
|
|
23
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
|
+
*/
|
|
24
28
|
log;
|
|
25
29
|
library;
|
|
26
30
|
launchOptions;
|
|
@@ -121,7 +125,7 @@ export class BrowserPlugin {
|
|
|
121
125
|
}
|
|
122
126
|
if (!launchContext.isRemote && this.isChromiumBasedBrowser(launchContext)) {
|
|
123
127
|
// This will set the args for chromium based browsers to hide the webdriver.
|
|
124
|
-
launchOptions.args = this
|
|
128
|
+
launchOptions.args = this.#mergeArgsToHideWebdriver(launchOptions.args);
|
|
125
129
|
// When User-Agent is not set, and we're using Chromium in headless mode,
|
|
126
130
|
// it is better to use DEFAULT_USER_AGENT to reduce chance of detection,
|
|
127
131
|
// as otherwise 'HeadlessChrome' is present in User-Agent string.
|
|
@@ -135,7 +139,7 @@ export class BrowserPlugin {
|
|
|
135
139
|
}
|
|
136
140
|
return this._launch(launchContext);
|
|
137
141
|
}
|
|
138
|
-
mergeArgsToHideWebdriver(originalArgs) {
|
|
142
|
+
#mergeArgsToHideWebdriver(originalArgs) {
|
|
139
143
|
if (!originalArgs?.length) {
|
|
140
144
|
return ['--disable-blink-features=AutomationControlled'];
|
|
141
145
|
}
|
package/anonymize-proxy.d.ts
CHANGED
package/browser-pool.d.ts
CHANGED
|
@@ -250,29 +250,18 @@ export interface BrowserPoolHooks<BC extends BrowserController, LC extends Launc
|
|
|
250
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
251
|
#private;
|
|
252
252
|
browserPlugins: BrowserPlugins;
|
|
253
|
-
|
|
253
|
+
/** @internal */
|
|
254
254
|
maxOpenBrowsers: number;
|
|
255
|
-
|
|
256
|
-
operationTimeoutMillis: number;
|
|
257
|
-
closeInactiveBrowserAfterMillis: number;
|
|
258
|
-
useFingerprints?: boolean;
|
|
255
|
+
/** @internal */
|
|
259
256
|
fingerprintOptions: FingerprintOptions;
|
|
260
|
-
|
|
261
|
-
postLaunchHooks: PostLaunchHook<BrowserControllerReturn>[];
|
|
262
|
-
prePageCreateHooks: PrePageCreateHook<BrowserControllerReturn, PageOptions>[];
|
|
263
|
-
postPageCreateHooks: PostPageCreateHook<BrowserControllerReturn, PageReturn>[];
|
|
264
|
-
prePageCloseHooks: PrePageCloseHook<BrowserControllerReturn, PageReturn>[];
|
|
265
|
-
postPageCloseHooks: PostPageCloseHook<BrowserControllerReturn>[];
|
|
266
|
-
pageCounter: number;
|
|
267
|
-
pages: Map<string, PageReturn>;
|
|
268
|
-
pageIds: WeakMap<PageReturn, string>;
|
|
269
|
-
startingBrowserControllers: Set<BrowserControllerReturn>;
|
|
270
|
-
activeBrowserControllers: Set<BrowserControllerReturn>;
|
|
271
|
-
retiredBrowserControllers: Set<BrowserControllerReturn>;
|
|
272
|
-
pageToBrowserController: WeakMap<PageReturn, BrowserControllerReturn>;
|
|
257
|
+
/** @internal */
|
|
273
258
|
fingerprintInjector?: FingerprintInjector;
|
|
274
259
|
fingerprintGenerator?: FingerprintGenerator;
|
|
260
|
+
/** @internal */
|
|
275
261
|
fingerprintCache?: QuickLRU<string, BrowserFingerprintWithHeaders>;
|
|
262
|
+
private pages;
|
|
263
|
+
private activeBrowserControllers;
|
|
264
|
+
private retiredBrowserControllers;
|
|
276
265
|
private browserKillerInterval?;
|
|
277
266
|
constructor(options: Options & BrowserPoolHooks<BrowserControllerReturn, LaunchContextReturn, PageReturn>);
|
|
278
267
|
/**
|
|
@@ -348,7 +337,6 @@ export declare class BrowserPool<Options extends BrowserPoolOptions = BrowserPoo
|
|
|
348
337
|
* until it's closed.
|
|
349
338
|
*/
|
|
350
339
|
getPageId(page: PageReturn): string | undefined;
|
|
351
|
-
private createPageForBrowser;
|
|
352
340
|
/**
|
|
353
341
|
* Removes a browser controller from the pool. The underlying
|
|
354
342
|
* browser will be closed after all its pages are closed.
|
|
@@ -362,8 +350,9 @@ export declare class BrowserPool<Options extends BrowserPoolOptions = BrowserPoo
|
|
|
362
350
|
retireBrowserByPage(page: PageReturn): void;
|
|
363
351
|
/**
|
|
364
352
|
* Releases a page back to the pool. The page is closed and, if the
|
|
365
|
-
* optional `error` is a {@link SessionError}
|
|
366
|
-
*
|
|
353
|
+
* optional `error` is a {@link SessionError} (including
|
|
354
|
+
* {@link SessionRetiredError}), the browser controller that served
|
|
355
|
+
* the page is retired so that the finished session's state (cookies,
|
|
367
356
|
* storage, etc.) cannot leak into future sessions.
|
|
368
357
|
*
|
|
369
358
|
* This is the primary way the crawler should return pages to the pool.
|
|
@@ -407,34 +396,36 @@ export declare class BrowserPool<Options extends BrowserPoolOptions = BrowserPoo
|
|
|
407
396
|
* @return {Promise<void>}
|
|
408
397
|
*/
|
|
409
398
|
closeAllBrowsers(): Promise<void>;
|
|
399
|
+
[Symbol.asyncDispose](): Promise<void>;
|
|
410
400
|
/**
|
|
411
|
-
* Closes
|
|
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.
|
|
412
403
|
*/
|
|
413
|
-
|
|
414
|
-
private teardown;
|
|
415
|
-
private getAllBrowserControllers;
|
|
416
|
-
private launchBrowser;
|
|
404
|
+
releaseAllBrowsers(): Promise<void>;
|
|
417
405
|
/**
|
|
418
|
-
*
|
|
419
|
-
*
|
|
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.
|
|
420
408
|
*/
|
|
421
|
-
|
|
422
|
-
private pickBrowserWithFreeCapacity;
|
|
409
|
+
destroy(): Promise<void>;
|
|
423
410
|
private closeInactiveRetiredBrowsers;
|
|
424
|
-
private overridePageClose;
|
|
425
|
-
private executeHooks;
|
|
426
|
-
private closeRetiredBrowserWithNoPages;
|
|
427
411
|
/**
|
|
428
|
-
* Returns `true` if the pool can accept a new browser launch without exceeding
|
|
429
|
-
*
|
|
412
|
+
* Returns `true` if the pool can accept a new browser launch without exceeding `maxOpenBrowsers`.
|
|
413
|
+
* Counts starting, active, and retired browsers.
|
|
414
|
+
*
|
|
415
|
+
* A plain `BrowserPool` leaves `maxOpenBrowsers` at `Infinity`, so this only returns `false` when something
|
|
416
|
+
* has set a cap — {@link RemoteBrowserPool} does, from its own
|
|
417
|
+
* {@link RemoteBrowserPoolOptions.maxOpenBrowsers|`maxOpenBrowsers`} option. There is no
|
|
418
|
+
* `BrowserPoolOptions` key for it.
|
|
419
|
+
*
|
|
420
|
+
* @internal
|
|
430
421
|
*/
|
|
431
422
|
hasFreeBrowserSlot(): boolean;
|
|
432
423
|
/**
|
|
433
424
|
* Returns `true` if any active browser has room for another page.
|
|
425
|
+
*
|
|
426
|
+
* @internal
|
|
434
427
|
*/
|
|
435
428
|
hasActiveBrowserWithFreeCapacity(): boolean;
|
|
436
|
-
private initializeFingerprinting;
|
|
437
|
-
private addFingerprintHooks;
|
|
438
429
|
}
|
|
439
430
|
export interface BrowserPoolNewPageOptions<PageOptions, BP extends BrowserPlugin> extends NewPageOptions {
|
|
440
431
|
/**
|