import { type BrowserContext } from 'playwright'; import { type SelectionStrategy } from './browser-selector.js'; import type { RawFetchResult, BrowserType, BrowserAction } from '../types.js'; /** * Thrown when the browser tier lands on a hard bot-protection challenge page * that does not clear within the settle window. Carries a structured code so * the router can map it to a `blocked_by_challenge` stage error instead of * hanging on the full navigation timeout. Message + hint use capability * language (never vendor internals). */ export declare class ChallengeBlockedError extends Error { readonly targetUrl: string; readonly code: "blocked_by_challenge"; readonly hint: string; constructor(targetUrl: string, message?: string, hint?: string); } export interface BrowserFetchOptions { timeoutMs?: number; storageStatePath?: string; userDataDir?: string; headers?: Record; screenshot?: boolean; actions?: BrowserAction[]; cdpUrl?: string; browserType?: BrowserType; signal?: AbortSignal; /** * When true, the fetch uses a DEDICATED per-fetch context with anti-bot * fingerprint hardening (a distinct UA + locale/timezone + an init script * that patches high-signal automation leaks), closed at end-of-fetch rather * than returned to the shared pool. Bounded by a separate semaphore so N * concurrent hardened fetches cannot exceed the browser cap. Ignored for the * CDP path (an external browser owns its own fingerprint). */ stealth?: boolean; /** * Anti-bot clearance cookies to seed into the context BEFORE navigation * (S-A2 reuse). Each is applied via `context.addCookies(...)` scoped to its * own host, so it is dropped on any cross-host redirect hop. The router * populates this from a stored, unexpired, UA-matching clearance so a solved * challenge is replayed instead of re-solved. */ injectedCookies?: Array<{ name: string; value: string; domain: string; path?: string; }>; } export interface BrowserPoolOptions { browserType?: BrowserType; } export interface MultiBrowserPoolOptions { browserTypes?: BrowserType[]; selectionStrategy?: SelectionStrategy; } export interface PoolTypeStat { type: BrowserType; activeCount: number; pooledCount: number; } export declare class MultiBrowserPool { private readonly pools; private readonly selector; private readonly configuredTypes; private shutdownCalled; private stealthActive; private readonly stealthWaitQueue; constructor(options?: MultiBrowserPoolOptions); getConfiguredTypes(): BrowserType[]; getStats(): PoolTypeStat[]; protected resolveType(requested?: BrowserType, url?: string): BrowserType; private launchBrowser; /** * Pre-launch the browser engine for the default (first configured) type so a * later fetch does not pay the browser cold-start inline. Idempotent — a * no-op when the browser is already launched — and best-effort: a launch * failure is swallowed (the lazy path on first fetch surfaces it honestly). * Latency-only; does not touch the context pool, so it never disturbs * in-flight fetches, downloads, or the idle-eviction bookkeeping. */ warm(): Promise; protected acquireForType(type: BrowserType): Promise; protected releaseForType(type: BrowserType, ctx: BrowserContext): void; private acquireStealthSlot; private releaseStealthSlot; fetchWithBrowser(url: string, options?: BrowserFetchOptions): Promise; shutdown(): Promise; } export declare class BrowserPool extends MultiBrowserPool { private readonly singleType; constructor(options?: BrowserPoolOptions); acquire(): Promise; release(ctx: BrowserContext): void; } //# sourceMappingURL=browser-pool.d.ts.map