/** * Pagination API Discovery (GAP-005) * * Learns pagination API patterns from network requests during browsing: * 1. Monitors network traffic when pagination occurs (page change, load more) * 2. Detects API endpoints that return paginated data * 3. Learns parameter patterns (page, offset, cursor, limit) * 4. Enables direct API calls for subsequent pages (bypasses rendering) * * Expected result: 10-100x speedup for multi-page scraping */ import type { NetworkRequest, PaginationPattern } from '../types/index.js'; /** * Discovered pagination API pattern */ export interface PaginationApiPattern { /** Unique identifier */ id: string; /** Domain this pattern applies to */ domain: string; /** Base URL for the pagination API (without pagination params) */ baseUrl: string; /** The parameter used for pagination */ paginationParam: PaginationParam; /** HTTP method for the API call */ method: 'GET' | 'POST'; /** Required headers for the API call */ headers: Record; /** Response structure information */ responseStructure: PaginationResponseStructure; /** Metrics tracking pattern usage */ metrics: PaginationPatternMetrics; /** When pattern was discovered */ discoveredAt: number; /** When pattern was last successfully used */ lastUsedAt: number; /** Whether this pattern is validated and ready for use */ isValidated: boolean; } /** * Pagination parameter configuration */ export interface PaginationParam { /** Parameter name (page, offset, cursor, after, etc.) */ name: string; /** Parameter type */ type: 'page' | 'offset' | 'cursor' | 'token'; /** Starting value for first page */ startValue: number | string; /** Increment for page/offset types */ increment?: number; /** Location of parameter */ location: 'query' | 'path' | 'body'; /** For cursor/token: path to next cursor in response */ nextValuePath?: string; } /** * Response structure for pagination API */ export interface PaginationResponseStructure { /** Path to data array in response */ dataPath: string; /** Path to total count (optional) */ totalCountPath?: string; /** Path to has-more indicator (optional) */ hasMorePath?: string; /** Path to next page token/cursor (optional) */ nextCursorPath?: string; /** Number of items typically returned per page */ itemsPerPage: number; } /** * Metrics for pagination pattern usage */ export interface PaginationPatternMetrics { /** Times pattern was used */ timesUsed: number; /** Successful usages */ successCount: number; /** Failed usages */ failureCount: number; /** Average response time (ms) */ avgResponseTime: number; /** Total items fetched via this pattern */ totalItemsFetched: number; /** Time saved by using API vs rendering (ms) */ timeSaved: number; } /** * Result from pagination analysis */ export interface PaginationAnalysisResult { /** Whether pagination API was detected */ detected: boolean; /** Detected pattern (if any) */ pattern?: PaginationApiPattern; /** Confidence in the detection (0-1) */ confidence: number; /** Reasons for detection/non-detection */ reasons: string[]; } /** * Context for pagination detection */ export interface PaginationContext { /** Original page URL */ originalUrl: string; /** URLs accessed during pagination */ pageUrls: string[]; /** Network requests during pagination */ networkRequests: NetworkRequest[]; /** UI pagination pattern detected (if any) */ uiPattern?: PaginationPattern; } export declare class PaginationDiscovery { private patterns; private patternsByDomain; private presetPatterns; /** * Analyze network requests to discover pagination API patterns * First checks for domain presets, then falls back to discovery */ analyze(context: PaginationContext): Promise; /** * Check if a network request is a JSON API request */ private isApiRequest; /** * Find requests that look like pagination API calls */ private findPaginationCandidates; /** * Check if response body contains array data */ private hasArrayData; /** * Check if response has pagination metadata */ private hasPaginationMetadata; /** * Analyze a pagination candidate request */ private analyzePaginationCandidate; /** * Detect pagination parameter from URL */ private detectPaginationParam; /** * Infer pagination parameter type */ private inferParamType; /** * Infer start value for pagination */ private inferStartValue; /** * Infer increment for pagination */ private inferIncrement; /** * Analyze response structure to understand pagination data */ private analyzeResponseStructure; /** * Build base URL without pagination parameter */ private buildBaseUrl; /** * Extract relevant headers for API calls */ private extractRelevantHeaders; /** * Parse response body if it's a string */ private parseResponseBody; /** * Get value by dot-notation path */ private getValueByPath; /** * Generate unique pattern ID */ private generatePatternId; /** * Create empty metrics object */ private createEmptyMetrics; /** * Store a discovered pattern */ private storePattern; /** * Get pattern by ID */ getPattern(id: string): PaginationApiPattern | undefined; /** * Get patterns for a domain */ getPatternsForDomain(domain: string): PaginationApiPattern[]; /** * Find matching pattern for a URL */ findMatchingPattern(url: string): PaginationApiPattern | null; /** * Check if URL matches a pattern */ private urlMatchesPattern; /** * Record pattern usage result */ recordUsage(patternId: string, success: boolean, responseTime: number, itemsFetched: number, timeSaved: number): void; /** * Update running average */ private updateRunningAverage; /** * Generate URL for a specific page using a pattern */ generatePageUrl(pattern: PaginationApiPattern, pageValue: number | string): string; /** * Get the next page value based on current value and pattern */ getNextPageValue(pattern: PaginationApiPattern, currentValue: number | string): number | string; /** * Get discovery statistics */ getStatistics(): { totalPatterns: number; validatedPatterns: number; byDomain: Record; totalTimeSaved: number; totalItemsFetched: number; }; /** * Clear all patterns */ clear(): void; /** * Try to use a domain preset for pagination configuration */ tryPreset(url: string): PaginationAnalysisResult; /** * Create a PaginationApiPattern from a preset configuration */ private createPatternFromPreset; /** * Get preset pattern for a domain (if available) */ getPresetPattern(url: string): PaginationApiPattern | undefined; /** * Check if a URL has a pagination preset available */ hasPreset(url: string): boolean; /** * Get all domains with pagination presets loaded */ getPresetDomains(): string[]; } /** Default pagination discovery instance */ export declare const paginationDiscovery: PaginationDiscovery; //# sourceMappingURL=pagination-discovery.d.ts.map