{"version":3,"file":"intelligent-prefetch.mjs","sources":["../../../../src/lib/performance/prefetch/intelligent-prefetch.ts"],"sourcesContent":["/**\n * @file Intelligent Prefetch Engine\n * @description ML-like prefetch prediction using user behavior patterns,\n * navigation history, and heuristics to predict and prefetch resources.\n *\n * Features:\n * - Behavior-based prediction\n * - Navigation pattern learning\n * - Viewport-based prefetching\n * - Network-aware decisions\n * - Probability scoring\n * - Prefetch budgeting\n */\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Navigation event for pattern learning\n */\nexport interface NavigationEvent {\n  from: string;\n  to: string;\n  timestamp: number;\n  duration: number;\n  interactionType: 'click' | 'hover' | 'focus' | 'scroll' | 'programmatic';\n}\n\n/**\n * Prefetch candidate\n */\nexport interface PrefetchCandidate {\n  url: string;\n  type: 'route' | 'data' | 'asset';\n  probability: number;\n  priority: 'high' | 'medium' | 'low';\n  size?: number;\n  reason: string[];\n}\n\n/**\n * Prediction result\n */\nexport interface PredictionResult {\n  candidates: PrefetchCandidate[];\n  confidence: number;\n  factors: PredictionFactor[];\n  timestamp: number;\n}\n\n/**\n * Prediction factor\n */\nexport interface PredictionFactor {\n  name: string;\n  weight: number;\n  value: number;\n  description: string;\n}\n\n/**\n * User behavior metrics\n */\nexport interface BehaviorMetrics {\n  sessionDuration: number;\n  pageViews: number;\n  avgTimeOnPage: number;\n  scrollDepth: number;\n  clickRate: number;\n  hoverPatterns: Map<string, number>;\n  navigationPatterns: Map<string, number>;\n}\n\n/**\n * Intelligent prefetch configuration\n */\nexport interface IntelligentPrefetchConfig {\n  /** Enable prediction */\n  enabled: boolean;\n  /** Minimum probability to trigger prefetch */\n  probabilityThreshold: number;\n  /** Maximum concurrent prefetches */\n  maxConcurrentPrefetches: number;\n  /** Prefetch budget in bytes */\n  prefetchBudget: number;\n  /** Enable network quality awareness */\n  networkAware: boolean;\n  /** Minimum network quality for prefetch */\n  minNetworkQuality: '4g' | '3g' | '2g' | 'slow-2g';\n  /** Enable data saver respect */\n  respectDataSaver: boolean;\n  /** Learning rate for pattern updates */\n  learningRate: number;\n  /** History size for pattern learning */\n  maxHistorySize: number;\n  /** Debug mode */\n  debug: boolean;\n}\n\n/**\n * Network information interface\n */\ninterface NetworkInformation {\n  effectiveType?: '4g' | '3g' | '2g' | 'slow-2g';\n  saveData?: boolean;\n  downlink?: number;\n  rtt?: number;\n}\n\n// ============================================================================\n// Constants\n// ============================================================================\n\nconst DEFAULT_CONFIG: IntelligentPrefetchConfig = {\n  enabled: true,\n  probabilityThreshold: 0.6,\n  maxConcurrentPrefetches: 3,\n  prefetchBudget: 5 * 1024 * 1024, // 5MB\n  networkAware: true,\n  minNetworkQuality: '3g',\n  respectDataSaver: true,\n  learningRate: 0.1,\n  maxHistorySize: 100,\n  debug: false,\n};\n\nconst NETWORK_QUALITY_SCORES: Record<string, number> = {\n  '4g': 4,\n  '3g': 3,\n  '2g': 2,\n  'slow-2g': 1,\n};\n\n// ============================================================================\n// Intelligent Prefetch Engine\n// ============================================================================\n\n/**\n * ML-like prefetch prediction engine\n */\nexport class IntelligentPrefetchEngine {\n  private config: IntelligentPrefetchConfig;\n  private navigationHistory: NavigationEvent[] = [];\n  private transitionProbabilities: Map<string, Map<string, number>> = new Map();\n  private hoverHistory: Map<string, number> = new Map();\n  private prefetchedUrls: Set<string> = new Set();\n  private currentBudgetUsed = 0;\n  private readonly sessionStartTime: number;\n  private pageViewCount = 0;\n  private listeners: Set<(prediction: PredictionResult) => void> = new Set();\n\n  constructor(config: Partial<IntelligentPrefetchConfig> = {}) {\n    this.config = { ...DEFAULT_CONFIG, ...config };\n    this.sessionStartTime = Date.now();\n    this.loadStoredPatterns();\n  }\n\n  /**\n   * Record a navigation event\n   */\n  recordNavigation(event: Omit<NavigationEvent, 'timestamp'>): void {\n    const fullEvent: NavigationEvent = {\n      ...event,\n      timestamp: Date.now(),\n    };\n\n    this.navigationHistory.push(fullEvent);\n    this.pageViewCount++;\n\n    // Trim history if needed\n    if (this.navigationHistory.length > this.config.maxHistorySize) {\n      this.navigationHistory.shift();\n    }\n\n    // Update transition probabilities\n    this.updateTransitionProbabilities(fullEvent);\n    this.persistPatterns();\n  }\n\n  /**\n   * Record a hover event\n   */\n  recordHover(url: string): void {\n    const count = this.hoverHistory.get(url) ?? 0;\n    this.hoverHistory.set(url, count + 1);\n  }\n\n  /**\n   * Get prefetch predictions for current page\n   */\n  predict(currentUrl: string, availableUrls: string[]): PredictionResult {\n    if (!this.config.enabled || !this.shouldPrefetch()) {\n      return this.emptyPrediction();\n    }\n\n    const candidates: PrefetchCandidate[] = [];\n    const factors: PredictionFactor[] = [];\n\n    for (const url of availableUrls) {\n      if (this.prefetchedUrls.has(url)) {\n        continue;\n      }\n\n      const probability = this.calculateProbability(currentUrl, url);\n      const candidateFactors = this.getPredictionFactors(currentUrl, url);\n\n      if (probability >= this.config.probabilityThreshold) {\n        candidates.push({\n          url,\n          type: this.inferResourceType(url),\n          probability,\n          priority: this.calculatePriority(probability),\n          reason: candidateFactors.map((f) => f.description),\n        });\n\n        factors.push(...candidateFactors);\n      }\n    }\n\n    // Sort by probability and priority\n    candidates.sort((a, b) => {\n      if (a.priority !== b.priority) {\n        const priorityOrder = { high: 0, medium: 1, low: 2 };\n        return priorityOrder[a.priority] - priorityOrder[b.priority];\n      }\n      return b.probability - a.probability;\n    });\n\n    // Limit to max concurrent\n    const limitedCandidates = candidates.slice(0, this.config.maxConcurrentPrefetches);\n\n    const result: PredictionResult = {\n      candidates: limitedCandidates,\n      confidence: this.calculateConfidence(),\n      factors: this.deduplicateFactors(factors),\n      timestamp: Date.now(),\n    };\n\n    // Notify listeners\n    this.notifyListeners(result);\n\n    return result;\n  }\n\n  /**\n   * Mark URL as prefetched\n   */\n  markPrefetched(url: string, size?: number): void {\n    this.prefetchedUrls.add(url);\n    if (size !== undefined && size > 0) {\n      this.currentBudgetUsed += size;\n    }\n  }\n\n  /**\n   * Check if URL was prefetched\n   */\n  wasPrefetched(url: string): boolean {\n    return this.prefetchedUrls.has(url);\n  }\n\n  /**\n   * Get behavior metrics\n   */\n  getBehaviorMetrics(): BehaviorMetrics {\n    const sessionDuration = Date.now() - this.sessionStartTime;\n    const avgTimeOnPage = this.pageViewCount > 0 ? sessionDuration / this.pageViewCount : 0;\n\n    return {\n      sessionDuration,\n      pageViews: this.pageViewCount,\n      avgTimeOnPage,\n      scrollDepth: this.calculateScrollDepth(),\n      clickRate: this.calculateClickRate(),\n      hoverPatterns: new Map(this.hoverHistory),\n      navigationPatterns: this.getNavigationPatterns(),\n    };\n  }\n\n  /**\n   * Subscribe to predictions\n   */\n  subscribe(callback: (prediction: PredictionResult) => void): () => void {\n    this.listeners.add(callback);\n    return () => this.listeners.delete(callback);\n  }\n\n  /**\n   * Reset learning data\n   */\n  reset(): void {\n    this.navigationHistory = [];\n    this.transitionProbabilities.clear();\n    this.hoverHistory.clear();\n    this.prefetchedUrls.clear();\n    this.currentBudgetUsed = 0;\n    this.pageViewCount = 0;\n    this.clearStoredPatterns();\n  }\n\n  /**\n   * Get remaining budget\n   */\n  getRemainingBudget(): number {\n    return Math.max(0, this.config.prefetchBudget - this.currentBudgetUsed);\n  }\n\n  // ============================================================================\n  // Private Methods\n  // ============================================================================\n\n  private calculateProbability(fromUrl: string, toUrl: string): number {\n    let probability = 0;\n    let weights = 0;\n\n    // Factor 1: Historical transition probability (weight: 0.4)\n    const transitionProb = this.getTransitionProbability(fromUrl, toUrl);\n    probability += transitionProb * 0.4;\n    weights += 0.4;\n\n    // Factor 2: Hover frequency (weight: 0.25)\n    const hoverScore = this.getHoverScore(toUrl);\n    probability += hoverScore * 0.25;\n    weights += 0.25;\n\n    // Factor 3: Recency bias (weight: 0.15)\n    const recencyScore = this.getRecencyScore(toUrl);\n    probability += recencyScore * 0.15;\n    weights += 0.15;\n\n    // Factor 4: URL similarity (weight: 0.1)\n    const similarityScore = this.getUrlSimilarity(fromUrl, toUrl);\n    probability += similarityScore * 0.1;\n    weights += 0.1;\n\n    // Factor 5: Time-based patterns (weight: 0.1)\n    const timeScore = this.getTimeBasedScore(toUrl);\n    probability += timeScore * 0.1;\n    weights += 0.1;\n\n    return Math.min(1, probability / weights);\n  }\n\n  private getPredictionFactors(fromUrl: string, toUrl: string): PredictionFactor[] {\n    const factors: PredictionFactor[] = [];\n\n    const transitionProb = this.getTransitionProbability(fromUrl, toUrl);\n    if (transitionProb > 0) {\n      factors.push({\n        name: 'historical_transition',\n        weight: 0.4,\n        value: transitionProb,\n        description: `Historical transition probability: ${(transitionProb * 100).toFixed(1)}%`,\n      });\n    }\n\n    const hoverScore = this.getHoverScore(toUrl);\n    if (hoverScore > 0) {\n      factors.push({\n        name: 'hover_frequency',\n        weight: 0.25,\n        value: hoverScore,\n        description: `Hover frequency score: ${(hoverScore * 100).toFixed(1)}%`,\n      });\n    }\n\n    const recencyScore = this.getRecencyScore(toUrl);\n    if (recencyScore > 0) {\n      factors.push({\n        name: 'recency',\n        weight: 0.15,\n        value: recencyScore,\n        description: `Recently visited similar pages`,\n      });\n    }\n\n    return factors;\n  }\n\n  private getTransitionProbability(fromUrl: string, toUrl: string): number {\n    const fromPath = this.normalizeUrl(fromUrl);\n    const toPath = this.normalizeUrl(toUrl);\n\n    const transitions = this.transitionProbabilities.get(fromPath);\n    if (!transitions) {\n      return 0;\n    }\n\n    return transitions.get(toPath) ?? 0;\n  }\n\n  private getHoverScore(url: string): number {\n    const hoverCount = this.hoverHistory.get(url) ?? 0;\n    const maxHover = Math.max(...Array.from(this.hoverHistory.values()), 1);\n    return hoverCount / maxHover;\n  }\n\n  private getRecencyScore(url: string): number {\n    const normalizedUrl = this.normalizeUrl(url);\n\n    // Check recent navigations\n    const recentNavs = this.navigationHistory.slice(-20);\n    let recencyScore = 0;\n\n    for (let i = 0; i < recentNavs.length; i++) {\n      const nav = recentNavs[i];\n      if (nav !== undefined && this.normalizeUrl(nav.to) === normalizedUrl) {\n        // More recent = higher score\n        recencyScore = Math.max(recencyScore, (i + 1) / recentNavs.length);\n      }\n    }\n\n    return recencyScore;\n  }\n\n  private getUrlSimilarity(url1: string, url2: string): number {\n    const path1 = this.normalizeUrl(url1).split('/');\n    const path2 = this.normalizeUrl(url2).split('/');\n\n    let matches = 0;\n    const maxLen = Math.max(path1.length, path2.length);\n\n    for (let i = 0; i < Math.min(path1.length, path2.length); i++) {\n      if (path1[i] === path2[i]) {\n        matches++;\n      }\n    }\n\n    return matches / maxLen;\n  }\n\n  private getTimeBasedScore(_url: string): number {\n    // Simplified time-based scoring\n    const hour = new Date().getHours();\n\n    // Peak usage hours (9-17) get higher scores\n    if (hour >= 9 && hour <= 17) {\n      return 0.8;\n    }\n\n    // Evening hours\n    if (hour >= 18 && hour <= 22) {\n      return 0.6;\n    }\n\n    return 0.4;\n  }\n\n  private updateTransitionProbabilities(event: NavigationEvent): void {\n    const fromPath = this.normalizeUrl(event.from);\n    const toPath = this.normalizeUrl(event.to);\n\n    if (!this.transitionProbabilities.has(fromPath)) {\n      this.transitionProbabilities.set(fromPath, new Map());\n    }\n\n    const transitions = this.transitionProbabilities.get(fromPath);\n    if (transitions === undefined) {\n      return;\n    }\n\n    const currentProb = transitions.get(toPath) ?? 0;\n\n    // Update using exponential moving average\n    const newProb = currentProb + this.config.learningRate * (1 - currentProb);\n    transitions.set(toPath, newProb);\n\n    // Decay other probabilities\n    for (const [path, prob] of transitions.entries()) {\n      if (path !== toPath) {\n        transitions.set(path, prob * (1 - this.config.learningRate / 2));\n      }\n    }\n  }\n\n  private shouldPrefetch(): boolean {\n    // Check network conditions\n    if (this.config.networkAware) {\n      const networkInfo = this.getNetworkInfo();\n\n      if (this.config.respectDataSaver && networkInfo?.saveData === true) {\n        this.log('Skipping prefetch: Data saver enabled');\n        return false;\n      }\n\n      if (networkInfo?.effectiveType !== undefined) {\n        const currentQuality = NETWORK_QUALITY_SCORES[networkInfo.effectiveType] ?? 0;\n        const minQuality = NETWORK_QUALITY_SCORES[this.config.minNetworkQuality] ?? 0;\n\n        if (currentQuality < minQuality) {\n          this.log(\n            `Skipping prefetch: Network quality ${networkInfo.effectiveType} below threshold`\n          );\n          return false;\n        }\n      }\n    }\n\n    // Check budget\n    if (this.currentBudgetUsed >= this.config.prefetchBudget) {\n      this.log('Skipping prefetch: Budget exhausted');\n      return false;\n    }\n\n    return true;\n  }\n\n  private calculatePriority(probability: number): 'high' | 'medium' | 'low' {\n    if (probability >= 0.8) return 'high';\n    if (probability >= 0.65) return 'medium';\n    return 'low';\n  }\n\n  private calculateConfidence(): number {\n    // Confidence based on data volume\n    const historySize = this.navigationHistory.length;\n    const minForConfidence = 10;\n    const maxForConfidence = 50;\n\n    if (historySize < minForConfidence) {\n      return (historySize / minForConfidence) * 0.5;\n    }\n\n    if (historySize >= maxForConfidence) {\n      return 1;\n    }\n\n    return 0.5 + ((historySize - minForConfidence) / (maxForConfidence - minForConfidence)) * 0.5;\n  }\n\n  private inferResourceType(url: string): 'route' | 'data' | 'asset' {\n    if (url.includes('/api/') || url.endsWith('.json')) {\n      return 'data';\n    }\n\n    if (url.match(/\\.(js|css|png|jpg|jpeg|gif|svg|woff|woff2|ico)(\\?|$)/)) {\n      return 'asset';\n    }\n\n    return 'route';\n  }\n\n  private normalizeUrl(url: string): string {\n    try {\n      const parsed = new URL(url, window.location.origin);\n      return parsed.pathname;\n    } catch {\n      return url;\n    }\n  }\n\n  private getNavigationPatterns(): Map<string, number> {\n    const patterns = new Map<string, number>();\n\n    for (const [from, transitions] of this.transitionProbabilities.entries()) {\n      for (const [to, prob] of transitions.entries()) {\n        const key = `${from} -> ${to}`;\n        patterns.set(key, prob);\n      }\n    }\n\n    return patterns;\n  }\n\n  private calculateScrollDepth(): number {\n    if (typeof window === 'undefined') return 0;\n\n    const windowHeight = window.innerHeight;\n    const documentHeight = document.documentElement.scrollHeight;\n    const scrollTop = window.scrollY;\n\n    return Math.min(1, (scrollTop + windowHeight) / documentHeight);\n  }\n\n  private calculateClickRate(): number {\n    // Simplified click rate calculation\n    const sessionMinutes = (Date.now() - this.sessionStartTime) / 60000;\n    if (sessionMinutes < 1) return 0;\n\n    return (\n      this.navigationHistory.filter((n) => n.interactionType === 'click').length / sessionMinutes\n    );\n  }\n\n  private getNetworkInfo(): NetworkInformation | null {\n    const nav = navigator as Navigator & {\n      connection?: NetworkInformation;\n    };\n    return nav.connection ?? null;\n  }\n\n  private deduplicateFactors(factors: PredictionFactor[]): PredictionFactor[] {\n    const seen = new Set<string>();\n    return factors.filter((f) => {\n      const key = `${f.name}-${f.value.toFixed(2)}`;\n      if (seen.has(key)) return false;\n      seen.add(key);\n      return true;\n    });\n  }\n\n  private emptyPrediction(): PredictionResult {\n    return {\n      candidates: [],\n      confidence: 0,\n      factors: [],\n      timestamp: Date.now(),\n    };\n  }\n\n  private notifyListeners(prediction: PredictionResult): void {\n    this.listeners.forEach((callback) => callback(prediction));\n  }\n\n  private loadStoredPatterns(): void {\n    try {\n      const stored = sessionStorage.getItem('prefetch-patterns');\n      if (stored !== null) {\n        const data = JSON.parse(stored) as { transitions?: Record<string, Record<string, number>> };\n        this.transitionProbabilities = new Map(\n          Object.entries(data.transitions ?? {}).map(([k, v]) => [k, new Map(Object.entries(v))])\n        );\n      }\n    } catch {\n      // Ignore storage errors\n    }\n  }\n\n  private persistPatterns(): void {\n    try {\n      const data = {\n        transitions: Object.fromEntries(\n          Array.from(this.transitionProbabilities.entries()).map(([k, v]) => [\n            k,\n            Object.fromEntries(v),\n          ])\n        ),\n      };\n      sessionStorage.setItem('prefetch-patterns', JSON.stringify(data));\n    } catch {\n      // Ignore storage errors\n    }\n  }\n\n  private clearStoredPatterns(): void {\n    try {\n      sessionStorage.removeItem('prefetch-patterns');\n    } catch {\n      // Ignore storage errors\n    }\n  }\n\n  private log(message: string, ...args: unknown[]): void {\n    if (this.config.debug) {\n      console.info(`[IntelligentPrefetch] ${message}`, ...args);\n    }\n  }\n}\n\n// ============================================================================\n// Singleton Instance\n// ============================================================================\n\nlet engineInstance: IntelligentPrefetchEngine | null = null;\n\n/**\n * Get or create the global intelligent prefetch engine\n */\nexport function getIntelligentPrefetchEngine(\n  config?: Partial<IntelligentPrefetchConfig>\n): IntelligentPrefetchEngine {\n  engineInstance ??= new IntelligentPrefetchEngine(config);\n  return engineInstance;\n}\n\n/**\n * Reset the engine instance\n */\nexport function resetIntelligentPrefetchEngine(): void {\n  if (engineInstance !== null) {\n    engineInstance.reset();\n    engineInstance = null;\n  }\n}\n"],"names":["DEFAULT_CONFIG","NETWORK_QUALITY_SCORES","IntelligentPrefetchEngine","config","event","fullEvent","url","count","currentUrl","availableUrls","candidates","factors","probability","candidateFactors","a","b","priorityOrder","result","size","sessionDuration","avgTimeOnPage","callback","fromUrl","toUrl","weights","transitionProb","hoverScore","recencyScore","similarityScore","timeScore","fromPath","toPath","transitions","hoverCount","maxHover","normalizedUrl","recentNavs","i","nav","url1","url2","path1","path2","matches","maxLen","_url","hour","currentProb","newProb","path","prob","networkInfo","currentQuality","minQuality","historySize","minForConfidence","maxForConfidence","patterns","from","to","key","windowHeight","documentHeight","scrollTop","sessionMinutes","n","seen","f","prediction","stored","data","k","v","message","args","engineInstance","getIntelligentPrefetchEngine","resetIntelligentPrefetchEngine"],"mappings":"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"}