/** * Lightweight Renderer - JS-capable HTML renderer without full browser overhead * * This module provides a middle ground between static HTML parsing (like justjshtml) * and full browser automation (Playwright). It can execute JavaScript in a sandboxed * environment using linkedom for DOM and Node's vm module for script execution. * * Use cases: * - Sites that need basic JS execution to render content * - Server-rendered pages with light client hydration * - Pages that fetch data via API and inject into DOM * * Does NOT handle: * - Heavy anti-bot protection (Cloudflare, reCAPTCHA) * - Complex user interactions (hover states, drag-drop) * - WebGL/Canvas rendering * - WebSocket connections */ import { Cookie } from 'tough-cookie'; export interface LightweightRenderOptions { timeout?: number; scriptTimeout?: number; executeScripts?: boolean; asyncWaitTime?: number; headers?: Record; userAgent?: string; followRedirects?: boolean; maxRedirects?: number; skipScriptPatterns?: RegExp[]; cookies?: Cookie[]; simulateScroll?: boolean; maxScrolls?: number; scrollDelay?: number; scrollDistance?: number; } export interface LightweightRenderResult { html: string; finalUrl: string; jsExecuted: boolean; scriptsExecuted: number; scriptsSkipped: number; scriptErrors: Array<{ src?: string; error: string; }>; networkRequests: Array<{ url: string; method: string; status?: number; contentType?: string; requestHeaders?: Record; responseHeaders?: Record; responseBody?: unknown; timestamp: number; duration?: number; }>; cookies: Cookie[]; timing: { fetchTime: number; parseTime: number; scriptTime: number; totalTime: number; scrollTime?: number; }; detection: { isJSHeavy: boolean; hasAsyncContent: boolean; needsFullBrowser: boolean; reason?: string; lazyLoad?: { detected: boolean; patterns: string[]; confidence: 'low' | 'medium' | 'high'; }; }; scrollSimulation?: { enabled: boolean; scrollsPerformed: number; contentGrowth: number; reachedBottom: boolean; }; } export declare class LightweightRenderer { private cookieJar; private options; constructor(options?: Partial); /** * Render a URL with optional JavaScript execution */ render(url: string, options?: Partial): Promise; /** * Quick static render without JS execution (fastest) */ renderStatic(url: string, options?: Partial): Promise; /** * Fetch URL with cookie handling and redirects */ private fetchWithCookies; /** * Create a sandboxed execution context for JavaScript */ private createExecutionContext; /** * Execute a script with timeout */ private executeScript; /** * Wait for async content to settle - OWL-008 enhancement * * Replaces fixed timeout with smart content stabilization detection. * Waits for DOM changes to stabilize (500ms no changes) with 5s max timeout. */ private waitForAsyncContent; /** * OWL-010: Simulate scrolling to trigger lazy-loaded content * * Scrolls the page incrementally, waiting for new content to load after each scroll. * Stops when no new content appears or max scrolls reached. * * Returns metrics about the scrolling session. */ private simulateScrolling; /** * Check if a script should be skipped */ private shouldSkipScript; /** * Detect page characteristics to determine if full browser is needed */ private detectPageCharacteristics; /** * OWL-009: Detect lazy-loading patterns that require scroll simulation * * Returns object with: * - hasLazyLoad: boolean indicating if lazy loading detected * - patterns: array of detected pattern types * - confidence: 'low' | 'medium' | 'high' */ private detectLazyLoadPatterns; /** * Check if the page looks like a challenge/verification page rather than * a normal page that happens to have a captcha widget */ private looksLikeChallengePage; /** * Get cookies for a domain */ getCookies(url: string): Promise; /** * Set cookies for a domain */ setCookies(cookies: Cookie[], url: string): Promise; /** * Clear all cookies */ clearCookies(): Promise; } export declare const lightweightRenderer: LightweightRenderer; //# sourceMappingURL=lightweight-renderer.d.ts.map