vite-plugin-smart-prefetch 0.1.0 → 0.3.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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/runtime/index.ts","../../src/runtime/prefetch-manager.ts","../../src/runtime/debug-utils.ts"],"sourcesContent":["/**\n * Runtime exports for client-side code\n * These exports have NO dependencies on server-side packages like firebase-admin\n */\n\nexport { PrefetchManager } from './prefetch-manager';\n\n// Debug utilities\nexport {\n getPrefetchLinks,\n getPluginPrefetchLinks,\n logPrefetchLinks,\n monitorPrefetchActivity,\n checkPluginConfiguration,\n exposeDebugUtils,\n} from './debug-utils';\n\n// Re-export types that are safe for client-side use\nexport type {\n PrefetchStrategy,\n PrefetchConfig,\n PrefetchTarget,\n} from '../types';\n","/**\n * Prefetch Manager (Runtime)\n * Manages route prefetching in the browser\n */\n\nimport type { PrefetchConfig, PrefetchStrategy, PrefetchTarget } from '../types';\n\nexport class PrefetchManager {\n private config: PrefetchConfig | null = null;\n private prefetched = new Set<string>();\n private strategy: PrefetchStrategy;\n private observer: IntersectionObserver | null = null;\n private debug: boolean;\n private currentSegment: string | null = null;\n private fallbackToDefault: boolean = true;\n\n constructor(strategy: PrefetchStrategy = 'hybrid', debug = false) {\n this.strategy = strategy;\n this.debug = debug;\n }\n\n /**\n * Initialize the prefetch manager\n * Loads configuration and sets up observers\n */\n async init(): Promise<void> {\n if (this.debug) {\n console.log('šŸš€ Smart Prefetch Manager - Initializing...');\n console.log(' Strategy:', this.strategy);\n console.log(' Debug mode: enabled');\n }\n\n try {\n // Load prefetch configuration\n if (this.debug) {\n console.log('šŸ“„ Fetching prefetch-config.json...');\n }\n\n const response = await fetch('/prefetch-config.json');\n\n // Gracefully handle missing config file (common in development)\n if (!response.ok) {\n if (response.status === 404) {\n if (this.debug) {\n console.warn('āš ļø Prefetch config not found (404)');\n console.log(' This is expected if:');\n console.log(' 1. You haven\\'t built the app yet (run `pnpm build`)');\n console.log(' 2. The plugin failed to generate the config during build');\n console.log(' Prefetch manager will be inactive until config is available');\n }\n return;\n }\n throw new Error(`Failed to load prefetch config: ${response.statusText}`);\n }\n\n this.config = await response.json();\n\n if (this.debug && this.config) {\n console.log('āœ… Config loaded successfully');\n console.log(` Routes with prefetch rules: ${Object.keys(this.config.routes).length} ${typeof this.config.routes}`);\n console.log(` Environment: ${this.config.environment}`);\n console.log(` Config version: ${this.config.version || 'N/A'}`);\n\n // List all routes with prefetch rules\n console.groupCollapsed('šŸ“‹ Available prefetch rules:');\n Object.entries(this.config.routes).forEach(([source, data]: [string, any]) => {\n console.log(`${source} → ${data.prefetch.length} target(s)`,\n data.prefetch.map((t: any) => t.route));\n });\n console.groupEnd();\n }\n\n // Set up intersection observer for 'visible' strategy\n if (this.strategy === 'visible' || this.strategy === 'hybrid') {\n this.initIntersectionObserver();\n if (this.debug) {\n console.log('šŸ‘ļø IntersectionObserver initialized for visibility-based prefetching');\n }\n }\n\n if (this.debug) {\n console.log('āœ… Prefetch Manager fully initialized');\n console.log('šŸ’” Run window.__PREFETCH_DEBUG__() to see current state');\n\n // Expose debug helper globally\n (window as any).__PREFETCH_DEBUG__ = () => this.logDebugInfo();\n }\n } catch (error) {\n // Only log error if debug mode is enabled\n if (this.debug) {\n console.error('āŒ Failed to initialize Prefetch Manager:', error);\n }\n }\n }\n\n /**\n * Set the user segment for segment-based prefetch rules\n * @param segment - The user's segment (e.g., 'premium', 'free', 'admin')\n * @param fallbackToDefault - Use default rules if segment rules unavailable\n */\n setSegment(segment: string | null, fallbackToDefault: boolean = true): void {\n this.currentSegment = segment;\n this.fallbackToDefault = fallbackToDefault;\n\n if (this.debug) {\n console.log(`šŸ”„ Segment updated: ${segment || '(none)'}`);\n console.log(` Fallback to default: ${fallbackToDefault}`);\n }\n }\n\n /**\n * Get the current segment\n */\n getSegment(): string | null {\n return this.currentSegment;\n }\n\n /**\n * Prefetch routes based on current route\n */\n prefetch(currentRoute: string): void {\n // Strip query parameters and hash from the route\n const cleanRoute = currentRoute.split('?')[0].split('#')[0];\n\n if (this.debug) {\n console.log(`šŸ“ Checking prefetch for route: ${currentRoute}`);\n if (currentRoute !== cleanRoute) {\n console.log(` Clean route: ${cleanRoute}`);\n }\n }\n\n if (!this.config) {\n if (this.debug) {\n console.warn('āš ļø Config not loaded yet - cannot prefetch');\n console.log(' Make sure the app was built with the plugin enabled');\n }\n return;\n }\n\n // Check network conditions\n if (!this.shouldPrefetch()) {\n if (this.debug) {\n console.log('ā­ļø Skipping prefetch due to network conditions');\n }\n return;\n }\n\n // Try to find route config (try both clean and original route)\n let routeConfig = this.config.routes[cleanRoute] || this.config.routes[currentRoute];\n const matchedRoute = routeConfig ? (this.config.routes[cleanRoute] ? cleanRoute : currentRoute) : null;\n\n if (!routeConfig) {\n if (this.debug) {\n console.warn(`āš ļø No prefetch rules configured for route: ${cleanRoute}`);\n console.groupCollapsed('Available routes in config:');\n Object.keys(this.config.routes).forEach(route => {\n const targets = this.config!.routes[route].prefetch;\n console.log(` ${route} → ${targets.length} target(s)`, targets.map(t => t.route));\n });\n console.groupEnd();\n console.log(`šŸ’” Tip: Make sure your manualRules key matches exactly: \"${cleanRoute}\"`);\n }\n return;\n }\n\n // Determine which rules to use: segment-specific or default\n let prefetchTargets = routeConfig.prefetch;\n let ruleSource = 'default';\n\n // Check if segment-specific rules are available and configured\n if (this.currentSegment && routeConfig.segments?.[this.currentSegment]) {\n prefetchTargets = routeConfig.segments[this.currentSegment];\n ruleSource = `segment (${this.currentSegment})`;\n } else if (this.currentSegment && !routeConfig.segments?.[this.currentSegment] && !this.fallbackToDefault) {\n // Segment specified but no rules for it and fallback disabled\n if (this.debug) {\n console.warn(`āš ļø No prefetch rules for segment \"${this.currentSegment}\" and fallback disabled`);\n }\n return;\n }\n\n // Always log when a route is found and prefetch is about to happen\n console.log(`āœ… Found prefetch rule for: ${matchedRoute}`);\n console.log(` Total targets to prefetch: ${prefetchTargets.length}`);\n console.log(` Using: ${ruleSource} rules`);\n console.log(` Strategy: ${this.strategy}`);\n\n if (this.debug) {\n console.groupCollapsed(`šŸ“Š Prefetch Rules for: ${matchedRoute} (${ruleSource})`);\n prefetchTargets.forEach((target, index) => {\n console.log(` ${index + 1}. ${target.route} (${target.priority} priority, ${(target.probability * 100).toFixed(1)}%)`);\n });\n console.groupEnd();\n }\n\n // Prefetch based on strategy\n prefetchTargets.forEach((target) => {\n this.prefetchTarget(target);\n });\n }\n\n /**\n * Prefetch a specific target\n */\n private prefetchTarget(target: any): void {\n // Check if already prefetched\n if (this.prefetched.has(target.route)) {\n console.log(` ā­ļø Already prefetched: ${target.route}`);\n return;\n }\n\n console.log(` šŸ”— Prefetch target: ${target.route}, chunk: ${target.chunk}`);\n\n try {\n // Apply strategy-based prefetching\n switch (this.strategy) {\n case 'auto':\n this.injectPrefetchLink(target);\n break;\n\n case 'hover':\n // Hover is handled by link components\n break;\n\n case 'visible':\n // Visible is handled by IntersectionObserver\n break;\n\n case 'idle':\n this.prefetchOnIdle(target);\n break;\n\n case 'hybrid':\n this.prefetchHybrid(target);\n break;\n\n default:\n console.warn(`āš ļø Unknown strategy: ${this.strategy}`);\n }\n } catch (error) {\n console.error(`āŒ Error prefetching ${target.route}:`, error);\n }\n }\n\n /**\n * Hybrid strategy: prioritize based on probability\n * FOR TESTING: Fetch all priorities to verify chunks are correct\n */\n private prefetchHybrid(target: PrefetchTarget & { chunk: string }): void {\n if (target.priority === 'high' || target.probability >= 0.7) {\n // High priority: prefetch immediately\n console.log(` ⚔ High priority (${(target.probability * 100).toFixed(1)}%) - Prefetching immediately`);\n this.injectPrefetchLink(target);\n } else if (target.priority === 'medium' || target.probability >= 0.4) {\n // Medium priority: prefetch on idle (FOR TESTING: fetch immediately)\n console.log(` ā±ļø Medium priority (${(target.probability * 100).toFixed(1)}%) - Fetching immediately (TESTING MODE)`);\n this.injectPrefetchLink(target); // Changed from prefetchOnIdle to immediate for testing\n } else {\n // Low priority: wait for visibility or hover (FOR TESTING: fetch immediately)\n console.log(` šŸ”” Low priority (${(target.probability * 100).toFixed(1)}%) - Fetching immediately (TESTING MODE)`);\n this.injectPrefetchLink(target); // Changed from deferred to immediate for testing\n }\n }\n\n /**\n * Prefetch during idle time\n */\n private prefetchOnIdle(target: PrefetchTarget & { chunk: string }): void {\n if ('requestIdleCallback' in window) {\n requestIdleCallback(() => {\n this.injectPrefetchLink(target);\n });\n } else {\n // Fallback for browsers without requestIdleCallback\n setTimeout(() => {\n this.injectPrefetchLink(target);\n }, 1000);\n }\n }\n\n /**\n * Resolve chunk path for the current environment\n * In production: chunks are built with hashes (e.g., chunks/Privacy-D5qJZu-O.js or js/index-CJMMxcQV.js)\n * In dev mode: need to resolve to the actual module or use a proxy\n */\n private resolveChunkPath(chunkPath: string, route: string): string {\n const isDev = window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1';\n\n if (!isDev) {\n // Production: use the chunk path as-is (it has real hashes from the build)\n return `/${chunkPath}`;\n }\n\n // Dev mode: Try to map chunk to component and use source files\n // Extract component name from chunk path\n // Examples:\n // - chunks/Privacy-D5qJZu-O.js → Privacy\n // - js/index-CJMMxcQV.js → index\n // - chunks/chunk-user-profile-JNr_q4Gn.js → (can't map, use original)\n\n // Try to extract component name from various chunk name patterns\n let componentName: string | null = null;\n\n // Pattern 1: Individual component chunks (e.g., Privacy-D5qJZu-O.js)\n const match1 = chunkPath.match(/\\/([A-Z][a-zA-Z]*)-[a-zA-Z0-9_-]+\\.js$/);\n if (match1) {\n componentName = match1[1];\n }\n\n // Pattern 2: Main/index chunks (e.g., js/index-CJMMxcQV.js)\n const match2 = chunkPath.match(/\\/(index)-[a-zA-Z0-9_-]+\\.js$/);\n if (match2) {\n componentName = match2[1];\n }\n\n if (componentName) {\n // Map component name to source file\n // This works because Vite's dev server resolves source files dynamically\n const sourceFile = componentName === 'index' ? '/src/main.tsx' : `/src/pages/${componentName}.tsx`;\n if (this.debug) {\n console.log(` šŸ“ Dev mode: Resolved ${chunkPath} → ${sourceFile}`);\n }\n return sourceFile;\n }\n\n // Fallback: use original chunk path with leading slash\n if (this.debug) {\n console.log(` āš ļø Dev mode: Could not extract component name from ${chunkPath}, using as-is`);\n }\n return `/${chunkPath}`;\n }\n\n /**\n * Inject prefetch link into DOM\n */\n private injectPrefetchLink(target: PrefetchTarget & { chunk: string }): void {\n if (this.prefetched.has(target.route)) {\n if (this.debug) {\n console.log(` ā­ļø Already prefetched: ${target.route}`);\n }\n return;\n }\n\n // Resolve the actual chunk path for the current environment\n // In production: use the chunk hash from config (e.g., chunks/Privacy-D5qJZu-O.js)\n // In dev mode: chunks don't exist as files, Vite handles them at request time\n const chunkPath = this.resolveChunkPath(target.chunk, target.route);\n\n // Create main chunk link\n const link = document.createElement('link');\n // Use modulepreload for better ES module support (triggers actual fetch)\n link.rel = 'modulepreload';\n link.href = chunkPath;\n link.setAttribute('data-prefetch-route', target.route);\n link.setAttribute('data-prefetch-priority', target.priority);\n link.setAttribute('data-prefetch-probability', target.probability.toString());\n\n // Always log prefetch with details\n console.groupCollapsed(`šŸ”— PREFETCH: ${target.route}`);\n console.log(` šŸ“„ Page/Route: ${target.route}`);\n console.log(` šŸ“¦ Main Chunk: ${target.chunk}`);\n console.log(` 🌐 Resolved URL: ${window.location.origin}${chunkPath}`);\n console.log(` ⭐ Priority: ${target.priority}`);\n console.log(` šŸ“Š Probability: ${(target.probability * 100).toFixed(1)}%`);\n\n // Track total chunks being fetched\n let totalChunksForThisRoute = 1; // Main chunk\n const injectedLinks: string[] = [];\n\n // Try to append the main link - CRITICAL: this must happen first\n try {\n document.head.appendChild(link);\n injectedLinks.push(target.chunk);\n console.log(` āœ… Main chunk link injected: ${target.chunk}`);\n } catch (e) {\n console.error(` āŒ Failed to inject main chunk link:`, e);\n console.groupEnd();\n return;\n }\n\n // Also prefetch all dependency chunks (imports)\n if (target.imports && target.imports.length > 0) {\n console.log(` šŸ“š Dependencies (${target.imports.length}):`);\n target.imports.forEach((importChunk, index) => {\n // Skip if already prefetched by another route\n const importId = `import:${importChunk}`;\n if (this.prefetched.has(importId)) {\n console.log(` ${index + 1}. ${importChunk} (already prefetched)`);\n return;\n }\n\n try {\n const importLink = document.createElement('link');\n importLink.rel = 'modulepreload';\n importLink.href = `/${importChunk}`;\n importLink.setAttribute('data-prefetch-import', 'true');\n importLink.setAttribute('data-prefetch-parent', target.route);\n document.head.appendChild(importLink);\n this.prefetched.add(importId);\n totalChunksForThisRoute++;\n injectedLinks.push(importChunk);\n\n console.log(` ${index + 1}. ${importChunk} āœ…`);\n } catch (e) {\n console.error(` ${index + 1}. ${importChunk} āŒ Error:`, e);\n }\n });\n }\n\n // Mark as prefetched\n this.prefetched.add(target.route);\n\n console.log(` āœ… Total chunks injected: ${totalChunksForThisRoute}`);\n console.log(` šŸ“ˆ Overall prefetched count: ${this.prefetched.size}`);\n\n if (this.debug) {\n console.log(` DOM Status: ${injectedLinks.length} link tag(s) added to document.head`);\n console.log(` Injected URLs:`, injectedLinks.map(c => `/${c}`));\n\n // Verify the link was actually added and check if it loaded\n setTimeout(() => {\n const addedLink = document.querySelector(`link[data-prefetch-route=\"${target.route}\"]`);\n if (addedLink) {\n console.log(` āœ”ļø DOM Verification: Link exists`);\n console.log(` href:`, (addedLink as HTMLLinkElement).href);\n console.log(` as:`, (addedLink as HTMLLinkElement).getAttribute('as'));\n console.log(` rel:`, (addedLink as HTMLLinkElement).rel);\n\n // Check if link actually triggered a fetch\n if ((addedLink as any).relList?.contains('modulepreload')) {\n console.log(` šŸ”„ Link has modulepreload rel (will fetch)`);\n }\n } else {\n console.error(` āŒ ERROR: Link tag not found in DOM after 100ms`);\n }\n\n // Verify ALL injected links exist\n console.log(` šŸ“‹ Verifying all injected links in head:`);\n document.querySelectorAll('link[data-prefetch-route], link[data-prefetch-import]').forEach((el, idx) => {\n const isMain = el.hasAttribute('data-prefetch-route');\n const parent = isMain ? el.getAttribute('data-prefetch-route') : el.getAttribute('data-prefetch-parent');\n console.log(` ${idx + 1}. ${(el as HTMLLinkElement).href} (parent: ${parent})`);\n });\n }, 50);\n }\n\n console.groupEnd();\n }\n\n /**\n * Check if prefetching should be performed based on network conditions\n */\n private shouldPrefetch(): boolean {\n // Check if Network Information API is available\n const nav = navigator as any;\n const connection = nav.connection || nav.mozConnection || nav.webkitConnection;\n\n if (!connection) {\n // API not available, assume prefetch is OK\n return true;\n }\n\n // Respect Data Saver mode\n if (connection.saveData) {\n if (this.debug) console.log(' āš ļø Data Saver enabled');\n return false;\n }\n\n // Check connection speed\n const slowConnections = ['slow-2g', '2g'];\n if (slowConnections.includes(connection.effectiveType)) {\n if (this.debug) console.log(` āš ļø Slow connection: ${connection.effectiveType}`);\n return false;\n }\n\n // Check if metered connection (conservative approach)\n if (connection.type === 'cellular' && connection.effectiveType !== '4g') {\n if (this.debug) console.log(' āš ļø Metered connection');\n return false;\n }\n\n return true;\n }\n\n /**\n * Initialize IntersectionObserver for 'visible' strategy\n */\n private initIntersectionObserver(): void {\n this.observer = new IntersectionObserver(\n (entries) => {\n entries.forEach((entry) => {\n if (entry.isIntersecting) {\n const route = entry.target.getAttribute('data-prefetch-route');\n if (route && this.config) {\n // Find the target in config\n Object.values(this.config.routes).forEach((routeConfig) => {\n const target = routeConfig.prefetch.find((t) => t.route === route);\n if (target) {\n this.injectPrefetchLink(target);\n }\n });\n }\n }\n });\n },\n {\n rootMargin: '50px', // Start prefetch 50px before element is visible\n }\n );\n }\n\n /**\n * Observe an element for visibility-based prefetching\n */\n observeLink(element: HTMLElement, route: string): void {\n if (this.observer) {\n element.setAttribute('data-prefetch-route', route);\n this.observer.observe(element);\n }\n }\n\n /**\n * Manually trigger prefetch for a specific route\n * Useful for hover events\n */\n prefetchRoute(route: string): void {\n if (!this.config) return;\n\n // Find this route in all route configs\n Object.values(this.config.routes).forEach((routeConfig) => {\n const target = routeConfig.prefetch.find((t) => t.route === route);\n if (target) {\n this.injectPrefetchLink(target);\n }\n });\n }\n\n /**\n * Get prefetch statistics\n */\n getStats(): {\n totalPrefetched: number;\n prefetchedRoutes: string[];\n configLoaded: boolean;\n strategy: PrefetchStrategy;\n } {\n return {\n totalPrefetched: this.prefetched.size,\n prefetchedRoutes: Array.from(this.prefetched),\n configLoaded: this.config !== null,\n strategy: this.strategy,\n };\n }\n\n /**\n * Check if a route has been prefetched\n */\n isPrefetched(route: string): boolean {\n return this.prefetched.has(route);\n }\n\n /**\n * Clear all prefetch state\n */\n clear(): void {\n this.prefetched.clear();\n if (this.observer) {\n this.observer.disconnect();\n }\n }\n\n /**\n * Get all prefetch link elements currently in the DOM\n */\n getActivePrefetchLinks(): HTMLLinkElement[] {\n return Array.from(document.querySelectorAll('link[rel=\"modulepreload\"][data-prefetch-route]'));\n }\n\n /**\n * Log current state for debugging\n */\n logDebugInfo(): void {\n console.group('šŸ› Smart Prefetch Debug Info');\n console.log('Strategy:', this.strategy);\n console.log('Config loaded:', this.config !== null);\n console.log('Total prefetch entries:', this.prefetched.size);\n console.log('Prefetched items:', Array.from(this.prefetched));\n\n const links = this.getActivePrefetchLinks();\n console.log('\\nšŸ”— Active Link Tags in DOM:', links.length);\n\n if (links.length > 0) {\n console.table(links.map(link => ({\n route: link.getAttribute('data-prefetch-route'),\n chunk: link.href.replace(window.location.origin + '/', ''),\n priority: link.getAttribute('data-prefetch-priority'),\n probability: link.getAttribute('data-prefetch-probability'),\n })));\n }\n\n if (this.config) {\n console.log('\\nšŸ“Š Configuration Summary:');\n console.log('Available routes in config:', Object.keys(this.config.routes).length);\n console.log('Config environment:', this.config.environment);\n\n console.group('šŸ“‹ All configured routes with prefetch targets:');\n Object.entries(this.config.routes).forEach(([route, data]: [string, any]) => {\n console.group(`${route}`);\n data.prefetch.forEach((t: any, idx: number) => {\n console.log(` ${idx + 1}. ${t.route} (${t.priority}, ${(t.probability * 100).toFixed(1)}%) → ${t.chunk}`);\n });\n console.groupEnd();\n });\n console.groupEnd();\n\n console.log('\\nšŸ’” Current location:', window.location.pathname);\n console.log('šŸ’” Clean route:', window.location.pathname.split('?')[0].split('#')[0]);\n }\n\n console.groupEnd();\n }\n\n /**\n * Log all prefetched pages and chunks (summary view)\n */\n logPrefetchSummary(): void {\n const links = this.getActivePrefetchLinks();\n const routeLinks = links.filter(l => !l.getAttribute('data-prefetch-import'));\n const dependencyLinks = links.filter(l => l.getAttribute('data-prefetch-import'));\n\n console.group('šŸ“Š PREFETCH SUMMARY');\n console.log(`Total pages prefetched: ${routeLinks.length}`);\n console.log(`Total dependency chunks: ${dependencyLinks.length}`);\n console.log(`Total overall entries: ${this.prefetched.size}`);\n\n if (routeLinks.length > 0) {\n console.group('šŸ“„ Pages/Routes Prefetched:');\n const pageTable = routeLinks.map(link => ({\n route: link.getAttribute('data-prefetch-route'),\n chunk: link.href.replace(window.location.origin + '/', ''),\n priority: link.getAttribute('data-prefetch-priority'),\n probability: `${link.getAttribute('data-prefetch-probability')}`,\n }));\n console.table(pageTable);\n console.groupEnd();\n }\n\n if (dependencyLinks.length > 0) {\n console.group('šŸ“¦ Dependency Chunks Prefetched:');\n const depsTable = dependencyLinks.map(link => ({\n parentRoute: link.getAttribute('data-prefetch-parent'),\n chunk: link.href.replace(window.location.origin + '/', ''),\n }));\n console.table(depsTable);\n console.groupEnd();\n }\n\n console.groupEnd();\n }\n}\n","/**\n * Debug Utilities for Smart Prefetch Plugin\n * Helper functions to inspect and debug prefetch behavior\n */\n\n/**\n * Get all prefetch link elements from the DOM\n */\nexport function getPrefetchLinks(): HTMLLinkElement[] {\n return Array.from(document.querySelectorAll('link[rel=\"prefetch\"]'));\n}\n\n/**\n * Get prefetch links added by our plugin (with data attributes)\n */\nexport function getPluginPrefetchLinks(): HTMLLinkElement[] {\n return Array.from(document.querySelectorAll('link[rel=\"prefetch\"][data-prefetch-route]'));\n}\n\n/**\n * Log all prefetch links in a formatted way\n */\nexport function logPrefetchLinks(): void {\n const allLinks = getPrefetchLinks();\n const pluginLinks = getPluginPrefetchLinks();\n\n console.group('šŸ”— Prefetch Link Tags in DOM');\n console.log(`Total prefetch links: ${allLinks.length}`);\n console.log(`Plugin-managed links: ${pluginLinks.length}`);\n\n if (pluginLinks.length > 0) {\n console.group('Plugin-managed links:');\n console.table(\n pluginLinks.map((link) => ({\n route: link.getAttribute('data-prefetch-route'),\n href: link.href,\n priority: link.getAttribute('data-prefetch-priority'),\n probability: link.getAttribute('data-prefetch-probability'),\n loaded: link.hasAttribute('data-loaded'),\n }))\n );\n console.groupEnd();\n }\n\n const otherLinks = allLinks.filter((link) => !link.hasAttribute('data-prefetch-route'));\n if (otherLinks.length > 0) {\n console.group('Other prefetch links:');\n console.table(\n otherLinks.map((link) => ({\n href: link.href,\n as: link.getAttribute('as'),\n }))\n );\n console.groupEnd();\n }\n\n console.groupEnd();\n}\n\n/**\n * Monitor prefetch activity in real-time\n */\nexport function monitorPrefetchActivity(): () => void {\n console.log('šŸ” Monitoring prefetch activity...');\n console.log('Press the returned stop function to stop monitoring');\n\n const observer = new MutationObserver((mutations) => {\n mutations.forEach((mutation) => {\n mutation.addedNodes.forEach((node) => {\n if (node.nodeName === 'LINK') {\n const link = node as HTMLLinkElement;\n if (link.rel === 'prefetch') {\n console.log('āž• New prefetch link added:', {\n route: link.getAttribute('data-prefetch-route') || 'N/A',\n href: link.href,\n priority: link.getAttribute('data-prefetch-priority'),\n });\n }\n }\n });\n\n mutation.removedNodes.forEach((node) => {\n if (node.nodeName === 'LINK') {\n const link = node as HTMLLinkElement;\n if (link.rel === 'prefetch') {\n console.log('āž– Prefetch link removed:', {\n route: link.getAttribute('data-prefetch-route') || 'N/A',\n href: link.href,\n });\n }\n }\n });\n });\n });\n\n observer.observe(document.head, {\n childList: true,\n subtree: true,\n });\n\n return () => {\n console.log('šŸ›‘ Stopped monitoring prefetch activity');\n observer.disconnect();\n };\n}\n\n/**\n * Check if the smart prefetch plugin is properly configured\n */\nexport function checkPluginConfiguration(): void {\n console.group('šŸ”§ Smart Prefetch Plugin Configuration Check');\n\n // Check global config\n const globalConfig = (window as any).__SMART_PREFETCH__;\n if (globalConfig) {\n console.log('āœ… Global config found:', globalConfig);\n } else {\n console.warn('āŒ Global config not found on window.__SMART_PREFETCH__');\n console.log(' The plugin may not be properly configured in vite.config');\n }\n\n // Check if config file is accessible\n fetch('/prefetch-config.json')\n .then((res) => {\n if (res.ok) {\n console.log('āœ… prefetch-config.json is accessible');\n return res.json();\n } else {\n throw new Error(`HTTP ${res.status}: ${res.statusText}`);\n }\n })\n .then((config) => {\n console.log('šŸ“‹ Config content:', config);\n console.log(` Routes: ${Object.keys(config.routes).length}`);\n console.log(` Environment: ${config.environment}`);\n })\n .catch((error) => {\n console.error('āŒ Cannot access prefetch-config.json:', error.message);\n console.log(' Make sure to build the app first: pnpm build');\n })\n .finally(() => {\n console.groupEnd();\n });\n\n // Check debug function\n if (typeof (window as any).__PREFETCH_DEBUG__ === 'function') {\n console.log('āœ… Debug function available: window.__PREFETCH_DEBUG__()');\n } else {\n console.warn('āš ļø Debug function not available (may not be initialized yet)');\n }\n}\n\n/**\n * Expose all debug utilities globally for console access\n */\nexport function exposeDebugUtils(): void {\n const w = window as any;\n w.__PREFETCH_UTILS__ = {\n getPrefetchLinks,\n getPluginPrefetchLinks,\n logPrefetchLinks,\n monitorPrefetchActivity,\n checkPluginConfiguration,\n };\n\n console.log('šŸ’” Debug utilities exposed:');\n console.log(' window.__PREFETCH_UTILS__.getPrefetchLinks()');\n console.log(' window.__PREFETCH_UTILS__.logPrefetchLinks()');\n console.log(' window.__PREFETCH_UTILS__.monitorPrefetchActivity()');\n console.log(' window.__PREFETCH_UTILS__.checkPluginConfiguration()');\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACOO,IAAM,kBAAN,MAAsB;AAAA,EAS3B,YAAY,WAA6B,UAAU,QAAQ,OAAO;AARlE,SAAQ,SAAgC;AACxC,SAAQ,aAAa,oBAAI,IAAY;AAErC,SAAQ,WAAwC;AAEhD,SAAQ,iBAAgC;AACxC,SAAQ,oBAA6B;AAGnC,SAAK,WAAW;AAChB,SAAK,QAAQ;AAAA,EACf;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,OAAsB;AAC1B,QAAI,KAAK,OAAO;AACd,cAAQ,IAAI,oDAA6C;AACzD,cAAQ,IAAI,gBAAgB,KAAK,QAAQ;AACzC,cAAQ,IAAI,wBAAwB;AAAA,IACtC;AAEA,QAAI;AAEF,UAAI,KAAK,OAAO;AACd,gBAAQ,IAAI,4CAAqC;AAAA,MACnD;AAEA,YAAM,WAAW,MAAM,MAAM,uBAAuB;AAGpD,UAAI,CAAC,SAAS,IAAI;AAChB,YAAI,SAAS,WAAW,KAAK;AAC3B,cAAI,KAAK,OAAO;AACd,oBAAQ,KAAK,+CAAqC;AAClD,oBAAQ,IAAI,yBAAyB;AACrC,oBAAQ,IAAI,wDAAyD;AACrE,oBAAQ,IAAI,6DAA6D;AACzE,oBAAQ,IAAI,gEAAgE;AAAA,UAC9E;AACA;AAAA,QACF;AACA,cAAM,IAAI,MAAM,mCAAmC,SAAS,UAAU,EAAE;AAAA,MAC1E;AAEA,WAAK,SAAS,MAAM,SAAS,KAAK;AAElC,UAAI,KAAK,SAAS,KAAK,QAAQ;AAC7B,gBAAQ,IAAI,mCAA8B;AAC1C,gBAAQ,IAAI,kCAAkC,OAAO,KAAK,KAAK,OAAO,MAAM,EAAE,MAAM,IAAI,OAAO,KAAK,OAAO,MAAM,EAAE;AACnH,gBAAQ,IAAI,mBAAmB,KAAK,OAAO,WAAW,EAAE;AACxD,gBAAQ,IAAI,sBAAsB,KAAK,OAAO,WAAW,KAAK,EAAE;AAGhE,gBAAQ,eAAe,qCAA8B;AACrD,eAAO,QAAQ,KAAK,OAAO,MAAM,EAAE,QAAQ,CAAC,CAAC,QAAQ,IAAI,MAAqB;AAC5E,kBAAQ;AAAA,YAAI,GAAG,MAAM,WAAM,KAAK,SAAS,MAAM;AAAA,YAC7C,KAAK,SAAS,IAAI,CAAC,MAAW,EAAE,KAAK;AAAA,UAAC;AAAA,QAC1C,CAAC;AACD,gBAAQ,SAAS;AAAA,MACnB;AAGA,UAAI,KAAK,aAAa,aAAa,KAAK,aAAa,UAAU;AAC7D,aAAK,yBAAyB;AAC9B,YAAI,KAAK,OAAO;AACd,kBAAQ,IAAI,oFAAwE;AAAA,QACtF;AAAA,MACF;AAEA,UAAI,KAAK,OAAO;AACd,gBAAQ,IAAI,2CAAsC;AAClD,gBAAQ,IAAI,gEAAyD;AAGrE,QAAC,OAAe,qBAAqB,MAAM,KAAK,aAAa;AAAA,MAC/D;AAAA,IACF,SAAS,OAAO;AAEd,UAAI,KAAK,OAAO;AACd,gBAAQ,MAAM,iDAA4C,KAAK;AAAA,MACjE;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,WAAW,SAAwB,oBAA6B,MAAY;AAC1E,SAAK,iBAAiB;AACtB,SAAK,oBAAoB;AAEzB,QAAI,KAAK,OAAO;AACd,cAAQ,IAAI,8BAAuB,WAAW,QAAQ,EAAE;AACxD,cAAQ,IAAI,2BAA2B,iBAAiB,EAAE;AAAA,IAC5D;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,aAA4B;AAC1B,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,SAAS,cAA4B;AAEnC,UAAM,aAAa,aAAa,MAAM,GAAG,EAAE,CAAC,EAAE,MAAM,GAAG,EAAE,CAAC;AAE1D,QAAI,KAAK,OAAO;AACd,cAAQ,IAAI,0CAAmC,YAAY,EAAE;AAC7D,UAAI,iBAAiB,YAAY;AAC/B,gBAAQ,IAAI,mBAAmB,UAAU,EAAE;AAAA,MAC7C;AAAA,IACF;AAEA,QAAI,CAAC,KAAK,QAAQ;AAChB,UAAI,KAAK,OAAO;AACd,gBAAQ,KAAK,uDAA6C;AAC1D,gBAAQ,IAAI,wDAAwD;AAAA,MACtE;AACA;AAAA,IACF;AAGA,QAAI,CAAC,KAAK,eAAe,GAAG;AAC1B,UAAI,KAAK,OAAO;AACd,gBAAQ,IAAI,2DAAiD;AAAA,MAC/D;AACA;AAAA,IACF;AAGA,QAAI,cAAc,KAAK,OAAO,OAAO,UAAU,KAAK,KAAK,OAAO,OAAO,YAAY;AACnF,UAAM,eAAe,cAAe,KAAK,OAAO,OAAO,UAAU,IAAI,aAAa,eAAgB;AAElG,QAAI,CAAC,aAAa;AAChB,UAAI,KAAK,OAAO;AACd,gBAAQ,KAAK,yDAA+C,UAAU,EAAE;AACxE,gBAAQ,eAAe,6BAA6B;AACpD,eAAO,KAAK,KAAK,OAAO,MAAM,EAAE,QAAQ,WAAS;AAC/C,gBAAM,UAAU,KAAK,OAAQ,OAAO,KAAK,EAAE;AAC3C,kBAAQ,IAAI,MAAM,KAAK,WAAM,QAAQ,MAAM,cAAc,QAAQ,IAAI,OAAK,EAAE,KAAK,CAAC;AAAA,QACpF,CAAC;AACD,gBAAQ,SAAS;AACjB,gBAAQ,IAAI,mEAA4D,UAAU,GAAG;AAAA,MACvF;AACA;AAAA,IACF;AAGA,QAAI,kBAAkB,YAAY;AAClC,QAAI,aAAa;AAGjB,QAAI,KAAK,kBAAkB,YAAY,WAAW,KAAK,cAAc,GAAG;AACtE,wBAAkB,YAAY,SAAS,KAAK,cAAc;AAC1D,mBAAa,YAAY,KAAK,cAAc;AAAA,IAC9C,WAAW,KAAK,kBAAkB,CAAC,YAAY,WAAW,KAAK,cAAc,KAAK,CAAC,KAAK,mBAAmB;AAEzG,UAAI,KAAK,OAAO;AACd,gBAAQ,KAAK,gDAAsC,KAAK,cAAc,yBAAyB;AAAA,MACjG;AACA;AAAA,IACF;AAGA,YAAQ,IAAI,mCAA8B,YAAY,EAAE;AACxD,YAAQ,IAAI,iCAAiC,gBAAgB,MAAM,EAAE;AACrE,YAAQ,IAAI,aAAa,UAAU,QAAQ;AAC3C,YAAQ,IAAI,gBAAgB,KAAK,QAAQ,EAAE;AAE3C,QAAI,KAAK,OAAO;AACd,cAAQ,eAAe,iCAA0B,YAAY,KAAK,UAAU,GAAG;AAC/E,sBAAgB,QAAQ,CAAC,QAAQ,UAAU;AACzC,gBAAQ,IAAI,MAAM,QAAQ,CAAC,KAAK,OAAO,KAAK,KAAK,OAAO,QAAQ,eAAe,OAAO,cAAc,KAAK,QAAQ,CAAC,CAAC,IAAI;AAAA,MACzH,CAAC;AACD,cAAQ,SAAS;AAAA,IACnB;AAGA,oBAAgB,QAAQ,CAAC,WAAW;AAClC,WAAK,eAAe,MAAM;AAAA,IAC5B,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKQ,eAAe,QAAmB;AAExC,QAAI,KAAK,WAAW,IAAI,OAAO,KAAK,GAAG;AACrC,cAAQ,IAAI,wCAA8B,OAAO,KAAK,EAAE;AACxD;AAAA,IACF;AAEA,YAAQ,IAAI,iCAA0B,OAAO,KAAK,YAAY,OAAO,KAAK,EAAE;AAE5E,QAAI;AAEF,cAAQ,KAAK,UAAU;AAAA,QACrB,KAAK;AACH,eAAK,mBAAmB,MAAM;AAC9B;AAAA,QAEF,KAAK;AAEH;AAAA,QAEF,KAAK;AAEH;AAAA,QAEF,KAAK;AACH,eAAK,eAAe,MAAM;AAC1B;AAAA,QAEF,KAAK;AACH,eAAK,eAAe,MAAM;AAC1B;AAAA,QAEF;AACE,kBAAQ,KAAK,mCAAyB,KAAK,QAAQ,EAAE;AAAA,MACzD;AAAA,IACF,SAAS,OAAO;AACd,cAAQ,MAAM,4BAAuB,OAAO,KAAK,KAAK,KAAK;AAAA,IAC7D;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,eAAe,QAAkD;AACvE,QAAI,OAAO,aAAa,UAAU,OAAO,eAAe,KAAK;AAE3D,cAAQ,IAAI,6BAAwB,OAAO,cAAc,KAAK,QAAQ,CAAC,CAAC,8BAA8B;AACtG,WAAK,mBAAmB,MAAM;AAAA,IAChC,WAAW,OAAO,aAAa,YAAY,OAAO,eAAe,KAAK;AAEpE,cAAQ,IAAI,sCAA4B,OAAO,cAAc,KAAK,QAAQ,CAAC,CAAC,0CAA0C;AACtH,WAAK,mBAAmB,MAAM;AAAA,IAChC,OAAO;AAEL,cAAQ,IAAI,+BAAwB,OAAO,cAAc,KAAK,QAAQ,CAAC,CAAC,0CAA0C;AAClH,WAAK,mBAAmB,MAAM;AAAA,IAChC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,eAAe,QAAkD;AACvE,QAAI,yBAAyB,QAAQ;AACnC,0BAAoB,MAAM;AACxB,aAAK,mBAAmB,MAAM;AAAA,MAChC,CAAC;AAAA,IACH,OAAO;AAEL,iBAAW,MAAM;AACf,aAAK,mBAAmB,MAAM;AAAA,MAChC,GAAG,GAAI;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOQ,iBAAiB,WAAmB,OAAuB;AACjE,UAAM,QAAQ,OAAO,SAAS,aAAa,eAAe,OAAO,SAAS,aAAa;AAEvF,QAAI,CAAC,OAAO;AAEV,aAAO,IAAI,SAAS;AAAA,IACtB;AAUA,QAAI,gBAA+B;AAGnC,UAAM,SAAS,UAAU,MAAM,wCAAwC;AACvE,QAAI,QAAQ;AACV,sBAAgB,OAAO,CAAC;AAAA,IAC1B;AAGA,UAAM,SAAS,UAAU,MAAM,+BAA+B;AAC9D,QAAI,QAAQ;AACV,sBAAgB,OAAO,CAAC;AAAA,IAC1B;AAEA,QAAI,eAAe;AAGjB,YAAM,aAAa,kBAAkB,UAAU,kBAAkB,cAAc,aAAa;AAC5F,UAAI,KAAK,OAAO;AACd,gBAAQ,IAAI,mCAA4B,SAAS,WAAM,UAAU,EAAE;AAAA,MACrE;AACA,aAAO;AAAA,IACT;AAGA,QAAI,KAAK,OAAO;AACd,cAAQ,IAAI,oEAA0D,SAAS,eAAe;AAAA,IAChG;AACA,WAAO,IAAI,SAAS;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA,EAKQ,mBAAmB,QAAkD;AAC3E,QAAI,KAAK,WAAW,IAAI,OAAO,KAAK,GAAG;AACrC,UAAI,KAAK,OAAO;AACd,gBAAQ,IAAI,wCAA8B,OAAO,KAAK,EAAE;AAAA,MAC1D;AACA;AAAA,IACF;AAKA,UAAM,YAAY,KAAK,iBAAiB,OAAO,OAAO,OAAO,KAAK;AAGlE,UAAM,OAAO,SAAS,cAAc,MAAM;AAE1C,SAAK,MAAM;AACX,SAAK,OAAO;AACZ,SAAK,aAAa,uBAAuB,OAAO,KAAK;AACrD,SAAK,aAAa,0BAA0B,OAAO,QAAQ;AAC3D,SAAK,aAAa,6BAA6B,OAAO,YAAY,SAAS,CAAC;AAG5E,YAAQ,eAAe,uBAAgB,OAAO,KAAK,EAAE;AACrD,YAAQ,IAAI,4BAAqB,OAAO,KAAK,EAAE;AAC/C,YAAQ,IAAI,4BAAqB,OAAO,KAAK,EAAE;AAC/C,YAAQ,IAAI,8BAAuB,OAAO,SAAS,MAAM,GAAG,SAAS,EAAE;AACvE,YAAQ,IAAI,uBAAkB,OAAO,QAAQ,EAAE;AAC/C,YAAQ,IAAI,8BAAuB,OAAO,cAAc,KAAK,QAAQ,CAAC,CAAC,GAAG;AAG1E,QAAI,0BAA0B;AAC9B,UAAM,gBAA0B,CAAC;AAGjC,QAAI;AACF,eAAS,KAAK,YAAY,IAAI;AAC9B,oBAAc,KAAK,OAAO,KAAK;AAC/B,cAAQ,IAAI,uCAAkC,OAAO,KAAK,EAAE;AAAA,IAC9D,SAAS,GAAG;AACV,cAAQ,MAAM,+CAA0C,CAAC;AACzD,cAAQ,SAAS;AACjB;AAAA,IACF;AAGA,QAAI,OAAO,WAAW,OAAO,QAAQ,SAAS,GAAG;AAC/C,cAAQ,IAAI,8BAAuB,OAAO,QAAQ,MAAM,IAAI;AAC5D,aAAO,QAAQ,QAAQ,CAAC,aAAa,UAAU;AAE7C,cAAM,WAAW,UAAU,WAAW;AACtC,YAAI,KAAK,WAAW,IAAI,QAAQ,GAAG;AACjC,kBAAQ,IAAI,SAAS,QAAQ,CAAC,KAAK,WAAW,uBAAuB;AACrE;AAAA,QACF;AAEA,YAAI;AACF,gBAAM,aAAa,SAAS,cAAc,MAAM;AAChD,qBAAW,MAAM;AACjB,qBAAW,OAAO,IAAI,WAAW;AACjC,qBAAW,aAAa,wBAAwB,MAAM;AACtD,qBAAW,aAAa,wBAAwB,OAAO,KAAK;AAC5D,mBAAS,KAAK,YAAY,UAAU;AACpC,eAAK,WAAW,IAAI,QAAQ;AAC5B;AACA,wBAAc,KAAK,WAAW;AAE9B,kBAAQ,IAAI,SAAS,QAAQ,CAAC,KAAK,WAAW,SAAI;AAAA,QACpD,SAAS,GAAG;AACV,kBAAQ,MAAM,SAAS,QAAQ,CAAC,KAAK,WAAW,kBAAa,CAAC;AAAA,QAChE;AAAA,MACF,CAAC;AAAA,IACH;AAGA,SAAK,WAAW,IAAI,OAAO,KAAK;AAEhC,YAAQ,IAAI,oCAA+B,uBAAuB,EAAE;AACpE,YAAQ,IAAI,0CAAmC,KAAK,WAAW,IAAI,EAAE;AAErE,QAAI,KAAK,OAAO;AACd,cAAQ,IAAI,kBAAkB,cAAc,MAAM,qCAAqC;AACvF,cAAQ,IAAI,qBAAqB,cAAc,IAAI,OAAK,IAAI,CAAC,EAAE,CAAC;AAGhE,iBAAW,MAAM;AACf,cAAM,YAAY,SAAS,cAAc,6BAA6B,OAAO,KAAK,IAAI;AACtF,YAAI,WAAW;AACb,kBAAQ,IAAI,gDAAsC;AAClD,kBAAQ,IAAI,YAAa,UAA8B,IAAI;AAC3D,kBAAQ,IAAI,UAAW,UAA8B,aAAa,IAAI,CAAC;AACvE,kBAAQ,IAAI,WAAY,UAA8B,GAAG;AAGzD,cAAK,UAAkB,SAAS,SAAS,eAAe,GAAG;AACzD,oBAAQ,IAAI,sDAA+C;AAAA,UAC7D;AAAA,QACF,OAAO;AACL,kBAAQ,MAAM,wDAAmD;AAAA,QACnE;AAGA,gBAAQ,IAAI,oDAA6C;AACzD,iBAAS,iBAAiB,uDAAuD,EAAE,QAAQ,CAAC,IAAI,QAAQ;AACtG,gBAAM,SAAS,GAAG,aAAa,qBAAqB;AACpD,gBAAM,SAAS,SAAS,GAAG,aAAa,qBAAqB,IAAI,GAAG,aAAa,sBAAsB;AACvG,kBAAQ,IAAI,SAAS,MAAM,CAAC,KAAM,GAAuB,IAAI,aAAa,MAAM,GAAG;AAAA,QACrF,CAAC;AAAA,MACH,GAAG,EAAE;AAAA,IACP;AAEA,YAAQ,SAAS;AAAA,EACnB;AAAA;AAAA;AAAA;AAAA,EAKQ,iBAA0B;AAEhC,UAAM,MAAM;AACZ,UAAM,aAAa,IAAI,cAAc,IAAI,iBAAiB,IAAI;AAE9D,QAAI,CAAC,YAAY;AAEf,aAAO;AAAA,IACT;AAGA,QAAI,WAAW,UAAU;AACvB,UAAI,KAAK,MAAO,SAAQ,IAAI,qCAA2B;AACvD,aAAO;AAAA,IACT;AAGA,UAAM,kBAAkB,CAAC,WAAW,IAAI;AACxC,QAAI,gBAAgB,SAAS,WAAW,aAAa,GAAG;AACtD,UAAI,KAAK,MAAO,SAAQ,IAAI,qCAA2B,WAAW,aAAa,EAAE;AACjF,aAAO;AAAA,IACT;AAGA,QAAI,WAAW,SAAS,cAAc,WAAW,kBAAkB,MAAM;AACvE,UAAI,KAAK,MAAO,SAAQ,IAAI,qCAA2B;AACvD,aAAO;AAAA,IACT;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKQ,2BAAiC;AACvC,SAAK,WAAW,IAAI;AAAA,MAClB,CAAC,YAAY;AACX,gBAAQ,QAAQ,CAAC,UAAU;AACzB,cAAI,MAAM,gBAAgB;AACxB,kBAAM,QAAQ,MAAM,OAAO,aAAa,qBAAqB;AAC7D,gBAAI,SAAS,KAAK,QAAQ;AAExB,qBAAO,OAAO,KAAK,OAAO,MAAM,EAAE,QAAQ,CAAC,gBAAgB;AACzD,sBAAM,SAAS,YAAY,SAAS,KAAK,CAAC,MAAM,EAAE,UAAU,KAAK;AACjE,oBAAI,QAAQ;AACV,uBAAK,mBAAmB,MAAM;AAAA,gBAChC;AAAA,cACF,CAAC;AAAA,YACH;AAAA,UACF;AAAA,QACF,CAAC;AAAA,MACH;AAAA,MACA;AAAA,QACE,YAAY;AAAA;AAAA,MACd;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,YAAY,SAAsB,OAAqB;AACrD,QAAI,KAAK,UAAU;AACjB,cAAQ,aAAa,uBAAuB,KAAK;AACjD,WAAK,SAAS,QAAQ,OAAO;AAAA,IAC/B;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,cAAc,OAAqB;AACjC,QAAI,CAAC,KAAK,OAAQ;AAGlB,WAAO,OAAO,KAAK,OAAO,MAAM,EAAE,QAAQ,CAAC,gBAAgB;AACzD,YAAM,SAAS,YAAY,SAAS,KAAK,CAAC,MAAM,EAAE,UAAU,KAAK;AACjE,UAAI,QAAQ;AACV,aAAK,mBAAmB,MAAM;AAAA,MAChC;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,WAKE;AACA,WAAO;AAAA,MACL,iBAAiB,KAAK,WAAW;AAAA,MACjC,kBAAkB,MAAM,KAAK,KAAK,UAAU;AAAA,MAC5C,cAAc,KAAK,WAAW;AAAA,MAC9B,UAAU,KAAK;AAAA,IACjB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,aAAa,OAAwB;AACnC,WAAO,KAAK,WAAW,IAAI,KAAK;AAAA,EAClC;AAAA;AAAA;AAAA;AAAA,EAKA,QAAc;AACZ,SAAK,WAAW,MAAM;AACtB,QAAI,KAAK,UAAU;AACjB,WAAK,SAAS,WAAW;AAAA,IAC3B;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,yBAA4C;AAC1C,WAAO,MAAM,KAAK,SAAS,iBAAiB,gDAAgD,CAAC;AAAA,EAC/F;AAAA;AAAA;AAAA;AAAA,EAKA,eAAqB;AACnB,YAAQ,MAAM,qCAA8B;AAC5C,YAAQ,IAAI,aAAa,KAAK,QAAQ;AACtC,YAAQ,IAAI,kBAAkB,KAAK,WAAW,IAAI;AAClD,YAAQ,IAAI,2BAA2B,KAAK,WAAW,IAAI;AAC3D,YAAQ,IAAI,qBAAqB,MAAM,KAAK,KAAK,UAAU,CAAC;AAE5D,UAAM,QAAQ,KAAK,uBAAuB;AAC1C,YAAQ,IAAI,wCAAiC,MAAM,MAAM;AAEzD,QAAI,MAAM,SAAS,GAAG;AACpB,cAAQ,MAAM,MAAM,IAAI,WAAS;AAAA,QAC/B,OAAO,KAAK,aAAa,qBAAqB;AAAA,QAC9C,OAAO,KAAK,KAAK,QAAQ,OAAO,SAAS,SAAS,KAAK,EAAE;AAAA,QACzD,UAAU,KAAK,aAAa,wBAAwB;AAAA,QACpD,aAAa,KAAK,aAAa,2BAA2B;AAAA,MAC5D,EAAE,CAAC;AAAA,IACL;AAEA,QAAI,KAAK,QAAQ;AACf,cAAQ,IAAI,oCAA6B;AACzC,cAAQ,IAAI,+BAA+B,OAAO,KAAK,KAAK,OAAO,MAAM,EAAE,MAAM;AACjF,cAAQ,IAAI,uBAAuB,KAAK,OAAO,WAAW;AAE1D,cAAQ,MAAM,wDAAiD;AAC/D,aAAO,QAAQ,KAAK,OAAO,MAAM,EAAE,QAAQ,CAAC,CAAC,OAAO,IAAI,MAAqB;AAC3E,gBAAQ,MAAM,GAAG,KAAK,EAAE;AACxB,aAAK,SAAS,QAAQ,CAAC,GAAQ,QAAgB;AAC7C,kBAAQ,IAAI,KAAK,MAAM,CAAC,KAAK,EAAE,KAAK,KAAK,EAAE,QAAQ,MAAM,EAAE,cAAc,KAAK,QAAQ,CAAC,CAAC,aAAQ,EAAE,KAAK,EAAE;AAAA,QAC3G,CAAC;AACD,gBAAQ,SAAS;AAAA,MACnB,CAAC;AACD,cAAQ,SAAS;AAEjB,cAAQ,IAAI,iCAA0B,OAAO,SAAS,QAAQ;AAC9D,cAAQ,IAAI,0BAAmB,OAAO,SAAS,SAAS,MAAM,GAAG,EAAE,CAAC,EAAE,MAAM,GAAG,EAAE,CAAC,CAAC;AAAA,IACrF;AAEA,YAAQ,SAAS;AAAA,EACnB;AAAA;AAAA;AAAA;AAAA,EAKA,qBAA2B;AACzB,UAAM,QAAQ,KAAK,uBAAuB;AAC1C,UAAM,aAAa,MAAM,OAAO,OAAK,CAAC,EAAE,aAAa,sBAAsB,CAAC;AAC5E,UAAM,kBAAkB,MAAM,OAAO,OAAK,EAAE,aAAa,sBAAsB,CAAC;AAEhF,YAAQ,MAAM,4BAAqB;AACnC,YAAQ,IAAI,2BAA2B,WAAW,MAAM,EAAE;AAC1D,YAAQ,IAAI,4BAA4B,gBAAgB,MAAM,EAAE;AAChE,YAAQ,IAAI,0BAA0B,KAAK,WAAW,IAAI,EAAE;AAE5D,QAAI,WAAW,SAAS,GAAG;AACzB,cAAQ,MAAM,oCAA6B;AAC3C,YAAM,YAAY,WAAW,IAAI,WAAS;AAAA,QACxC,OAAO,KAAK,aAAa,qBAAqB;AAAA,QAC9C,OAAO,KAAK,KAAK,QAAQ,OAAO,SAAS,SAAS,KAAK,EAAE;AAAA,QACzD,UAAU,KAAK,aAAa,wBAAwB;AAAA,QACpD,aAAa,GAAG,KAAK,aAAa,2BAA2B,CAAC;AAAA,MAChE,EAAE;AACF,cAAQ,MAAM,SAAS;AACvB,cAAQ,SAAS;AAAA,IACnB;AAEA,QAAI,gBAAgB,SAAS,GAAG;AAC9B,cAAQ,MAAM,yCAAkC;AAChD,YAAM,YAAY,gBAAgB,IAAI,WAAS;AAAA,QAC7C,aAAa,KAAK,aAAa,sBAAsB;AAAA,QACrD,OAAO,KAAK,KAAK,QAAQ,OAAO,SAAS,SAAS,KAAK,EAAE;AAAA,MAC3D,EAAE;AACF,cAAQ,MAAM,SAAS;AACvB,cAAQ,SAAS;AAAA,IACnB;AAEA,YAAQ,SAAS;AAAA,EACnB;AACF;;;AC3oBO,SAAS,mBAAsC;AACpD,SAAO,MAAM,KAAK,SAAS,iBAAiB,sBAAsB,CAAC;AACrE;AAKO,SAAS,yBAA4C;AAC1D,SAAO,MAAM,KAAK,SAAS,iBAAiB,2CAA2C,CAAC;AAC1F;AAKO,SAAS,mBAAyB;AACvC,QAAM,WAAW,iBAAiB;AAClC,QAAM,cAAc,uBAAuB;AAE3C,UAAQ,MAAM,qCAA8B;AAC5C,UAAQ,IAAI,yBAAyB,SAAS,MAAM,EAAE;AACtD,UAAQ,IAAI,yBAAyB,YAAY,MAAM,EAAE;AAEzD,MAAI,YAAY,SAAS,GAAG;AAC1B,YAAQ,MAAM,uBAAuB;AACrC,YAAQ;AAAA,MACN,YAAY,IAAI,CAAC,UAAU;AAAA,QACzB,OAAO,KAAK,aAAa,qBAAqB;AAAA,QAC9C,MAAM,KAAK;AAAA,QACX,UAAU,KAAK,aAAa,wBAAwB;AAAA,QACpD,aAAa,KAAK,aAAa,2BAA2B;AAAA,QAC1D,QAAQ,KAAK,aAAa,aAAa;AAAA,MACzC,EAAE;AAAA,IACJ;AACA,YAAQ,SAAS;AAAA,EACnB;AAEA,QAAM,aAAa,SAAS,OAAO,CAAC,SAAS,CAAC,KAAK,aAAa,qBAAqB,CAAC;AACtF,MAAI,WAAW,SAAS,GAAG;AACzB,YAAQ,MAAM,uBAAuB;AACrC,YAAQ;AAAA,MACN,WAAW,IAAI,CAAC,UAAU;AAAA,QACxB,MAAM,KAAK;AAAA,QACX,IAAI,KAAK,aAAa,IAAI;AAAA,MAC5B,EAAE;AAAA,IACJ;AACA,YAAQ,SAAS;AAAA,EACnB;AAEA,UAAQ,SAAS;AACnB;AAKO,SAAS,0BAAsC;AACpD,UAAQ,IAAI,2CAAoC;AAChD,UAAQ,IAAI,qDAAqD;AAEjE,QAAM,WAAW,IAAI,iBAAiB,CAAC,cAAc;AACnD,cAAU,QAAQ,CAAC,aAAa;AAC9B,eAAS,WAAW,QAAQ,CAAC,SAAS;AACpC,YAAI,KAAK,aAAa,QAAQ;AAC5B,gBAAM,OAAO;AACb,cAAI,KAAK,QAAQ,YAAY;AAC3B,oBAAQ,IAAI,mCAA8B;AAAA,cACxC,OAAO,KAAK,aAAa,qBAAqB,KAAK;AAAA,cACnD,MAAM,KAAK;AAAA,cACX,UAAU,KAAK,aAAa,wBAAwB;AAAA,YACtD,CAAC;AAAA,UACH;AAAA,QACF;AAAA,MACF,CAAC;AAED,eAAS,aAAa,QAAQ,CAAC,SAAS;AACtC,YAAI,KAAK,aAAa,QAAQ;AAC5B,gBAAM,OAAO;AACb,cAAI,KAAK,QAAQ,YAAY;AAC3B,oBAAQ,IAAI,iCAA4B;AAAA,cACtC,OAAO,KAAK,aAAa,qBAAqB,KAAK;AAAA,cACnD,MAAM,KAAK;AAAA,YACb,CAAC;AAAA,UACH;AAAA,QACF;AAAA,MACF,CAAC;AAAA,IACH,CAAC;AAAA,EACH,CAAC;AAED,WAAS,QAAQ,SAAS,MAAM;AAAA,IAC9B,WAAW;AAAA,IACX,SAAS;AAAA,EACX,CAAC;AAED,SAAO,MAAM;AACX,YAAQ,IAAI,gDAAyC;AACrD,aAAS,WAAW;AAAA,EACtB;AACF;AAKO,SAAS,2BAAiC;AAC/C,UAAQ,MAAM,qDAA8C;AAG5D,QAAM,eAAgB,OAAe;AACrC,MAAI,cAAc;AAChB,YAAQ,IAAI,+BAA0B,YAAY;AAAA,EACpD,OAAO;AACL,YAAQ,KAAK,6DAAwD;AACrE,YAAQ,IAAI,6DAA6D;AAAA,EAC3E;AAGA,QAAM,uBAAuB,EAC1B,KAAK,CAAC,QAAQ;AACb,QAAI,IAAI,IAAI;AACV,cAAQ,IAAI,2CAAsC;AAClD,aAAO,IAAI,KAAK;AAAA,IAClB,OAAO;AACL,YAAM,IAAI,MAAM,QAAQ,IAAI,MAAM,KAAK,IAAI,UAAU,EAAE;AAAA,IACzD;AAAA,EACF,CAAC,EACA,KAAK,CAAC,WAAW;AAChB,YAAQ,IAAI,6BAAsB,MAAM;AACxC,YAAQ,IAAI,cAAc,OAAO,KAAK,OAAO,MAAM,EAAE,MAAM,EAAE;AAC7D,YAAQ,IAAI,mBAAmB,OAAO,WAAW,EAAE;AAAA,EACrD,CAAC,EACA,MAAM,CAAC,UAAU;AAChB,YAAQ,MAAM,8CAAyC,MAAM,OAAO;AACpE,YAAQ,IAAI,iDAAiD;AAAA,EAC/D,CAAC,EACA,QAAQ,MAAM;AACb,YAAQ,SAAS;AAAA,EACnB,CAAC;AAGH,MAAI,OAAQ,OAAe,uBAAuB,YAAY;AAC5D,YAAQ,IAAI,8DAAyD;AAAA,EACvE,OAAO;AACL,YAAQ,KAAK,yEAA+D;AAAA,EAC9E;AACF;AAKO,SAAS,mBAAyB;AACvC,QAAM,IAAI;AACV,IAAE,qBAAqB;AAAA,IACrB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,UAAQ,IAAI,oCAA6B;AACzC,UAAQ,IAAI,iDAAiD;AAC7D,UAAQ,IAAI,iDAAiD;AAC7D,UAAQ,IAAI,wDAAwD;AACpE,UAAQ,IAAI,yDAAyD;AACvE;","names":[]}
1
+ {"version":3,"sources":["../../src/runtime/index.ts","../../src/runtime/prefetch-manager.ts","../../src/runtime/debug-utils.ts"],"sourcesContent":["/**\n * Runtime exports for client-side code\n * These exports have NO dependencies on server-side packages like firebase-admin\n */\n\nexport { PrefetchManager } from './prefetch-manager';\n\n// Debug utilities\nexport {\n getPrefetchLinks,\n getPluginPrefetchLinks,\n logPrefetchLinks,\n monitorPrefetchActivity,\n checkPluginConfiguration,\n exposeDebugUtils,\n} from './debug-utils';\n\n// Re-export types that are safe for client-side use\nexport type {\n PrefetchStrategy,\n PrefetchConfig,\n PrefetchTarget,\n} from '../types';\n","/**\n * Prefetch Manager (Runtime)\n * Manages route prefetching in the browser\n */\n\nimport type { PrefetchConfig, PrefetchStrategy, PrefetchTarget } from '../types';\n\nexport class PrefetchManager {\n private config: PrefetchConfig | null = null;\n private prefetched = new Set<string>();\n private strategy: PrefetchStrategy;\n private observer: IntersectionObserver | null = null;\n private debug: boolean;\n private currentSegment: string | null = null;\n private fallbackToDefault: boolean = true;\n\n constructor(strategy: PrefetchStrategy = 'hybrid', debug = false) {\n this.strategy = strategy;\n this.debug = debug;\n }\n\n /**\n * Initialize the prefetch manager\n * Loads configuration and sets up observers\n */\n async init(): Promise<void> {\n if (this.debug) {\n console.log('šŸš€ Smart Prefetch Manager - Initializing...');\n console.log(' Strategy:', this.strategy);\n console.log(' Debug mode: enabled');\n }\n\n try {\n // Load prefetch configuration\n if (this.debug) {\n console.log('šŸ“„ Fetching prefetch-config.json...');\n }\n\n const response = await fetch('/prefetch-config.json');\n\n // Gracefully handle missing config file (common in development)\n if (!response.ok) {\n if (response.status === 404) {\n if (this.debug) {\n console.warn('āš ļø Prefetch config not found (404)');\n console.log(' This is expected if:');\n console.log(' 1. You haven\\'t built the app yet (run `pnpm build`)');\n console.log(' 2. The plugin failed to generate the config during build');\n console.log(' Prefetch manager will be inactive until config is available');\n }\n return;\n }\n throw new Error(`Failed to load prefetch config: ${response.statusText}`);\n }\n\n this.config = await response.json();\n\n if (this.debug && this.config) {\n console.log('āœ… Config loaded successfully');\n console.log(` Routes with prefetch rules: ${Object.keys(this.config.routes).length} ${typeof this.config.routes}`);\n console.log(` Environment: ${this.config.environment}`);\n console.log(` Config version: ${this.config.version || 'N/A'}`);\n\n // List all routes with prefetch rules\n console.groupCollapsed('šŸ“‹ Available prefetch rules:');\n Object.entries(this.config.routes).forEach(([source, data]: [string, any]) => {\n console.log(`${source} → ${data.prefetch.length} target(s)`,\n data.prefetch.map((t: any) => t.route));\n });\n console.groupEnd();\n }\n\n // Set up intersection observer for 'visible' strategy\n if (this.strategy === 'visible' || this.strategy === 'hybrid') {\n this.initIntersectionObserver();\n if (this.debug) {\n console.log('šŸ‘ļø IntersectionObserver initialized for visibility-based prefetching');\n }\n }\n\n if (this.debug) {\n console.log('āœ… Prefetch Manager fully initialized');\n console.log('šŸ’” Run window.__PREFETCH_DEBUG__() to see current state');\n\n // Expose debug helper globally\n (window as any).__PREFETCH_DEBUG__ = () => this.logDebugInfo();\n }\n } catch (error) {\n // Only log error if debug mode is enabled\n if (this.debug) {\n console.error('āŒ Failed to initialize Prefetch Manager:', error);\n }\n }\n }\n\n /**\n * Set the user segment for segment-based prefetch rules\n * @param segment - The user's segment (e.g., 'premium', 'free', 'admin')\n * @param fallbackToDefault - Use default rules if segment rules unavailable\n */\n setSegment(segment: string | null, fallbackToDefault: boolean = true): void {\n this.currentSegment = segment;\n this.fallbackToDefault = fallbackToDefault;\n\n if (this.debug) {\n console.log(`šŸ”„ Segment updated: ${segment || '(none)'}`);\n console.log(` Fallback to default: ${fallbackToDefault}`);\n }\n }\n\n /**\n * Get the current segment\n */\n getSegment(): string | null {\n return this.currentSegment;\n }\n\n /**\n * Match pathname against a route pattern\n * Supports both React Router (:id) and TanStack Router ($id) syntax\n * Examples:\n * matchRoutePattern('/order/123', '/order/:id') → true\n * matchRoutePattern('/user/john', '/user/$name') → true\n * matchRoutePattern('/admin/settings', '/admin/*') → true\n */\n private matchRoutePattern(pathname: string, pattern: string): boolean {\n const patternRegex = new RegExp(\n '^' + pattern\n .replace(/:[^/]+/g, '[^/]+') // Match :param style (React Router)\n .replace(/\\$[^/]+/g, '[^/]+') // Match $param style (TanStack Router)\n .replace(/\\*/g, '.*') + // Match wildcard\n '$'\n );\n return patternRegex.test(pathname);\n }\n\n /**\n * Prefetch routes based on current route\n */\n prefetch(currentRoute: string): void {\n // Strip query parameters and hash from the route\n const cleanRoute = currentRoute.split('?')[0].split('#')[0];\n\n if (this.debug) {\n console.log(`šŸ“ Checking prefetch for route: ${currentRoute}`);\n if (currentRoute !== cleanRoute) {\n console.log(` Clean route: ${cleanRoute}`);\n }\n }\n\n if (!this.config) {\n if (this.debug) {\n console.warn('āš ļø Config not loaded yet - cannot prefetch');\n console.log(' Make sure the app was built with the plugin enabled');\n }\n return;\n }\n\n // Check network conditions\n if (!this.shouldPrefetch()) {\n if (this.debug) {\n console.log('ā­ļø Skipping prefetch due to network conditions');\n }\n return;\n }\n\n // Try to find route config with three strategies:\n // 1. Exact match on clean route\n // 2. Exact match on original route\n // 3. Pattern match (for dynamic routes like /order/:id or /order/$id)\n let routeConfig = this.config.routes[cleanRoute] || this.config.routes[currentRoute];\n let matchedRoute = routeConfig ? (this.config.routes[cleanRoute] ? cleanRoute : currentRoute) : null;\n\n // If no exact match, try pattern matching\n if (!routeConfig) {\n for (const [configRoute, config] of Object.entries(this.config.routes)) {\n // Check if the route has pattern information\n const patterns = (config as any).patterns || [configRoute];\n for (const pattern of patterns) {\n if (this.matchRoutePattern(cleanRoute, pattern)) {\n routeConfig = config as any;\n matchedRoute = configRoute;\n if (this.debug) {\n console.log(`āœ… Pattern matched: \"${cleanRoute}\" → pattern \"${pattern}\"`);\n }\n break;\n }\n }\n if (routeConfig) break;\n }\n }\n\n if (!routeConfig) {\n if (this.debug) {\n console.warn(`āš ļø No prefetch rules configured for route: ${cleanRoute}`);\n console.groupCollapsed('Available routes in config:');\n Object.keys(this.config.routes).forEach(route => {\n const targets = this.config!.routes[route].prefetch;\n console.log(` ${route} → ${targets.length} target(s)`, targets.map(t => t.route));\n });\n console.groupEnd();\n console.log(`šŸ’” Tip: Routes with dynamic segments like \"/order/:id\" or \"/order/$id\" should match automatically`);\n }\n return;\n }\n\n // Determine which rules to use: segment-specific or default\n let prefetchTargets = routeConfig.prefetch;\n let ruleSource = 'default';\n\n // Check if segment-specific rules are available and configured\n if (this.currentSegment && routeConfig.segments?.[this.currentSegment]) {\n prefetchTargets = routeConfig.segments[this.currentSegment];\n ruleSource = `segment (${this.currentSegment})`;\n } else if (this.currentSegment && !routeConfig.segments?.[this.currentSegment] && !this.fallbackToDefault) {\n // Segment specified but no rules for it and fallback disabled\n if (this.debug) {\n console.warn(`āš ļø No prefetch rules for segment \"${this.currentSegment}\" and fallback disabled`);\n }\n return;\n }\n\n // Always log when a route is found and prefetch is about to happen\n console.log(`āœ… Found prefetch rule for: ${matchedRoute}`);\n console.log(` Total targets to prefetch: ${prefetchTargets.length}`);\n console.log(` Using: ${ruleSource} rules`);\n console.log(` Strategy: ${this.strategy}`);\n\n if (this.debug) {\n console.groupCollapsed(`šŸ“Š Prefetch Rules for: ${matchedRoute} (${ruleSource})`);\n prefetchTargets.forEach((target, index) => {\n console.log(` ${index + 1}. ${target.route} (${target.priority} priority, ${(target.probability * 100).toFixed(1)}%)`);\n });\n console.groupEnd();\n }\n\n // Prefetch based on strategy\n prefetchTargets.forEach((target) => {\n this.prefetchTarget(target);\n });\n }\n\n /**\n * Prefetch a specific target\n */\n private prefetchTarget(target: any): void {\n // Check if already prefetched\n if (this.prefetched.has(target.route)) {\n console.log(` ā­ļø Already prefetched: ${target.route}`);\n return;\n }\n\n console.log(` šŸ”— Prefetch target: ${target.route}, chunk: ${target.chunk}`);\n\n try {\n // Apply strategy-based prefetching\n switch (this.strategy) {\n case 'auto':\n this.injectPrefetchLink(target);\n break;\n\n case 'hover':\n // Hover is handled by link components\n break;\n\n case 'visible':\n // Visible is handled by IntersectionObserver\n break;\n\n case 'idle':\n this.prefetchOnIdle(target);\n break;\n\n case 'hybrid':\n this.prefetchHybrid(target);\n break;\n\n default:\n console.warn(`āš ļø Unknown strategy: ${this.strategy}`);\n }\n } catch (error) {\n console.error(`āŒ Error prefetching ${target.route}:`, error);\n }\n }\n\n /**\n * Hybrid strategy: prioritize based on probability\n * FOR TESTING: Fetch all priorities to verify chunks are correct\n */\n private prefetchHybrid(target: PrefetchTarget & { chunk: string }): void {\n if (target.priority === 'high' || target.probability >= 0.7) {\n // High priority: prefetch immediately\n console.log(` ⚔ High priority (${(target.probability * 100).toFixed(1)}%) - Prefetching immediately`);\n this.injectPrefetchLink(target);\n } else if (target.priority === 'medium' || target.probability >= 0.4) {\n // Medium priority: prefetch on idle (FOR TESTING: fetch immediately)\n console.log(` ā±ļø Medium priority (${(target.probability * 100).toFixed(1)}%) - Fetching immediately (TESTING MODE)`);\n this.injectPrefetchLink(target); // Changed from prefetchOnIdle to immediate for testing\n } else {\n // Low priority: wait for visibility or hover (FOR TESTING: fetch immediately)\n console.log(` šŸ”” Low priority (${(target.probability * 100).toFixed(1)}%) - Fetching immediately (TESTING MODE)`);\n this.injectPrefetchLink(target); // Changed from deferred to immediate for testing\n }\n }\n\n /**\n * Prefetch during idle time\n */\n private prefetchOnIdle(target: PrefetchTarget & { chunk: string }): void {\n if ('requestIdleCallback' in window) {\n requestIdleCallback(() => {\n this.injectPrefetchLink(target);\n });\n } else {\n // Fallback for browsers without requestIdleCallback\n setTimeout(() => {\n this.injectPrefetchLink(target);\n }, 1000);\n }\n }\n\n /**\n * Resolve chunk path for the current environment\n * In production: chunks are built with hashes (e.g., chunks/Privacy-D5qJZu-O.js or js/index-CJMMxcQV.js)\n * In dev mode: need to resolve to the actual module or use a proxy\n */\n private resolveChunkPath(chunkPath: string, route: string): string {\n const isDev = window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1';\n\n if (!isDev) {\n // Production: use the chunk path as-is (it has real hashes from the build)\n return `/${chunkPath}`;\n }\n\n // Dev mode: Try to map chunk to component and use source files\n // Extract component name from chunk path\n // Examples:\n // - chunks/Privacy-D5qJZu-O.js → Privacy\n // - js/index-CJMMxcQV.js → index\n // - chunks/chunk-user-profile-JNr_q4Gn.js → (can't map, use original)\n\n // Try to extract component name from various chunk name patterns\n let componentName: string | null = null;\n\n // Pattern 1: Individual component chunks (e.g., Privacy-D5qJZu-O.js)\n const match1 = chunkPath.match(/\\/([A-Z][a-zA-Z]*)-[a-zA-Z0-9_-]+\\.js$/);\n if (match1) {\n componentName = match1[1];\n }\n\n // Pattern 2: Main/index chunks (e.g., js/index-CJMMxcQV.js)\n const match2 = chunkPath.match(/\\/(index)-[a-zA-Z0-9_-]+\\.js$/);\n if (match2) {\n componentName = match2[1];\n }\n\n if (componentName) {\n // Map component name to source file\n // This works because Vite's dev server resolves source files dynamically\n const sourceFile = componentName === 'index' ? '/src/main.tsx' : `/src/pages/${componentName}.tsx`;\n if (this.debug) {\n console.log(` šŸ“ Dev mode: Resolved ${chunkPath} → ${sourceFile}`);\n }\n return sourceFile;\n }\n\n // Fallback: use original chunk path with leading slash\n if (this.debug) {\n console.log(` āš ļø Dev mode: Could not extract component name from ${chunkPath}, using as-is`);\n }\n return `/${chunkPath}`;\n }\n\n /**\n * Inject prefetch link into DOM\n */\n private injectPrefetchLink(target: PrefetchTarget & { chunk: string }): void {\n if (this.prefetched.has(target.route)) {\n if (this.debug) {\n console.log(` ā­ļø Already prefetched: ${target.route}`);\n }\n return;\n }\n\n // Resolve the actual chunk path for the current environment\n // In production: use the chunk hash from config (e.g., chunks/Privacy-D5qJZu-O.js)\n // In dev mode: chunks don't exist as files, Vite handles them at request time\n const chunkPath = this.resolveChunkPath(target.chunk, target.route);\n\n // Create main chunk link\n const link = document.createElement('link');\n // Use modulepreload for better ES module support (triggers actual fetch)\n link.rel = 'modulepreload';\n link.href = chunkPath;\n link.setAttribute('data-prefetch-route', target.route);\n link.setAttribute('data-prefetch-priority', target.priority);\n link.setAttribute('data-prefetch-probability', target.probability.toString());\n\n // Always log prefetch with details\n console.groupCollapsed(`šŸ”— PREFETCH: ${target.route}`);\n console.log(` šŸ“„ Page/Route: ${target.route}`);\n console.log(` šŸ“¦ Main Chunk: ${target.chunk}`);\n console.log(` 🌐 Resolved URL: ${window.location.origin}${chunkPath}`);\n console.log(` ⭐ Priority: ${target.priority}`);\n console.log(` šŸ“Š Probability: ${(target.probability * 100).toFixed(1)}%`);\n\n // Track total chunks being fetched\n let totalChunksForThisRoute = 1; // Main chunk\n const injectedLinks: string[] = [];\n\n // Try to append the main link - CRITICAL: this must happen first\n try {\n document.head.appendChild(link);\n injectedLinks.push(target.chunk);\n console.log(` āœ… Main chunk link injected: ${target.chunk}`);\n } catch (e) {\n console.error(` āŒ Failed to inject main chunk link:`, e);\n console.groupEnd();\n return;\n }\n\n // Also prefetch all dependency chunks (imports)\n if (target.imports && target.imports.length > 0) {\n console.log(` šŸ“š Dependencies (${target.imports.length}):`);\n target.imports.forEach((importChunk, index) => {\n // Skip if already prefetched by another route\n const importId = `import:${importChunk}`;\n if (this.prefetched.has(importId)) {\n console.log(` ${index + 1}. ${importChunk} (already prefetched)`);\n return;\n }\n\n try {\n const importLink = document.createElement('link');\n importLink.rel = 'modulepreload';\n importLink.href = `/${importChunk}`;\n importLink.setAttribute('data-prefetch-import', 'true');\n importLink.setAttribute('data-prefetch-parent', target.route);\n document.head.appendChild(importLink);\n this.prefetched.add(importId);\n totalChunksForThisRoute++;\n injectedLinks.push(importChunk);\n\n console.log(` ${index + 1}. ${importChunk} āœ…`);\n } catch (e) {\n console.error(` ${index + 1}. ${importChunk} āŒ Error:`, e);\n }\n });\n }\n\n // Mark as prefetched\n this.prefetched.add(target.route);\n\n console.log(` āœ… Total chunks injected: ${totalChunksForThisRoute}`);\n console.log(` šŸ“ˆ Overall prefetched count: ${this.prefetched.size}`);\n\n if (this.debug) {\n console.log(` DOM Status: ${injectedLinks.length} link tag(s) added to document.head`);\n console.log(` Injected URLs:`, injectedLinks.map(c => `/${c}`));\n\n // Verify the link was actually added and check if it loaded\n setTimeout(() => {\n const addedLink = document.querySelector(`link[data-prefetch-route=\"${target.route}\"]`);\n if (addedLink) {\n console.log(` āœ”ļø DOM Verification: Link exists`);\n console.log(` href:`, (addedLink as HTMLLinkElement).href);\n console.log(` as:`, (addedLink as HTMLLinkElement).getAttribute('as'));\n console.log(` rel:`, (addedLink as HTMLLinkElement).rel);\n\n // Check if link actually triggered a fetch\n if ((addedLink as any).relList?.contains('modulepreload')) {\n console.log(` šŸ”„ Link has modulepreload rel (will fetch)`);\n }\n } else {\n console.error(` āŒ ERROR: Link tag not found in DOM after 100ms`);\n }\n\n // Verify ALL injected links exist\n console.log(` šŸ“‹ Verifying all injected links in head:`);\n document.querySelectorAll('link[data-prefetch-route], link[data-prefetch-import]').forEach((el, idx) => {\n const isMain = el.hasAttribute('data-prefetch-route');\n const parent = isMain ? el.getAttribute('data-prefetch-route') : el.getAttribute('data-prefetch-parent');\n console.log(` ${idx + 1}. ${(el as HTMLLinkElement).href} (parent: ${parent})`);\n });\n }, 50);\n }\n\n console.groupEnd();\n }\n\n /**\n * Check if prefetching should be performed based on network conditions\n */\n private shouldPrefetch(): boolean {\n // Check if Network Information API is available\n const nav = navigator as any;\n const connection = nav.connection || nav.mozConnection || nav.webkitConnection;\n\n if (!connection) {\n // API not available, assume prefetch is OK\n return true;\n }\n\n // Respect Data Saver mode\n if (connection.saveData) {\n if (this.debug) console.log(' āš ļø Data Saver enabled');\n return false;\n }\n\n // Check connection speed\n const slowConnections = ['slow-2g', '2g'];\n if (slowConnections.includes(connection.effectiveType)) {\n if (this.debug) console.log(` āš ļø Slow connection: ${connection.effectiveType}`);\n return false;\n }\n\n // Check if metered connection (conservative approach)\n if (connection.type === 'cellular' && connection.effectiveType !== '4g') {\n if (this.debug) console.log(' āš ļø Metered connection');\n return false;\n }\n\n return true;\n }\n\n /**\n * Initialize IntersectionObserver for 'visible' strategy\n */\n private initIntersectionObserver(): void {\n this.observer = new IntersectionObserver(\n (entries) => {\n entries.forEach((entry) => {\n if (entry.isIntersecting) {\n const route = entry.target.getAttribute('data-prefetch-route');\n if (route && this.config) {\n // Find the target in config\n Object.values(this.config.routes).forEach((routeConfig) => {\n const target = routeConfig.prefetch.find((t) => t.route === route);\n if (target) {\n this.injectPrefetchLink(target);\n }\n });\n }\n }\n });\n },\n {\n rootMargin: '50px', // Start prefetch 50px before element is visible\n }\n );\n }\n\n /**\n * Observe an element for visibility-based prefetching\n */\n observeLink(element: HTMLElement, route: string): void {\n if (this.observer) {\n element.setAttribute('data-prefetch-route', route);\n this.observer.observe(element);\n }\n }\n\n /**\n * Manually trigger prefetch for a specific route\n * Useful for hover events\n */\n prefetchRoute(route: string): void {\n if (!this.config) return;\n\n // Find this route in all route configs\n Object.values(this.config.routes).forEach((routeConfig) => {\n const target = routeConfig.prefetch.find((t) => t.route === route);\n if (target) {\n this.injectPrefetchLink(target);\n }\n });\n }\n\n /**\n * Get prefetch statistics\n */\n getStats(): {\n totalPrefetched: number;\n prefetchedRoutes: string[];\n configLoaded: boolean;\n strategy: PrefetchStrategy;\n } {\n return {\n totalPrefetched: this.prefetched.size,\n prefetchedRoutes: Array.from(this.prefetched),\n configLoaded: this.config !== null,\n strategy: this.strategy,\n };\n }\n\n /**\n * Check if a route has been prefetched\n */\n isPrefetched(route: string): boolean {\n return this.prefetched.has(route);\n }\n\n /**\n * Clear all prefetch state\n */\n clear(): void {\n this.prefetched.clear();\n if (this.observer) {\n this.observer.disconnect();\n }\n }\n\n /**\n * Get all prefetch link elements currently in the DOM\n */\n getActivePrefetchLinks(): HTMLLinkElement[] {\n return Array.from(document.querySelectorAll('link[rel=\"modulepreload\"][data-prefetch-route]'));\n }\n\n /**\n * Log current state for debugging\n */\n logDebugInfo(): void {\n console.group('šŸ› Smart Prefetch Debug Info');\n console.log('Strategy:', this.strategy);\n console.log('Config loaded:', this.config !== null);\n console.log('Total prefetch entries:', this.prefetched.size);\n console.log('Prefetched items:', Array.from(this.prefetched));\n\n const links = this.getActivePrefetchLinks();\n console.log('\\nšŸ”— Active Link Tags in DOM:', links.length);\n\n if (links.length > 0) {\n console.table(links.map(link => ({\n route: link.getAttribute('data-prefetch-route'),\n chunk: link.href.replace(window.location.origin + '/', ''),\n priority: link.getAttribute('data-prefetch-priority'),\n probability: link.getAttribute('data-prefetch-probability'),\n })));\n }\n\n if (this.config) {\n console.log('\\nšŸ“Š Configuration Summary:');\n console.log('Available routes in config:', Object.keys(this.config.routes).length);\n console.log('Config environment:', this.config.environment);\n\n console.group('šŸ“‹ All configured routes with prefetch targets:');\n Object.entries(this.config.routes).forEach(([route, data]: [string, any]) => {\n console.group(`${route}`);\n data.prefetch.forEach((t: any, idx: number) => {\n console.log(` ${idx + 1}. ${t.route} (${t.priority}, ${(t.probability * 100).toFixed(1)}%) → ${t.chunk}`);\n });\n console.groupEnd();\n });\n console.groupEnd();\n\n console.log('\\nšŸ’” Current location:', window.location.pathname);\n console.log('šŸ’” Clean route:', window.location.pathname.split('?')[0].split('#')[0]);\n }\n\n console.groupEnd();\n }\n\n /**\n * Log all prefetched pages and chunks (summary view)\n */\n logPrefetchSummary(): void {\n const links = this.getActivePrefetchLinks();\n const routeLinks = links.filter(l => !l.getAttribute('data-prefetch-import'));\n const dependencyLinks = links.filter(l => l.getAttribute('data-prefetch-import'));\n\n console.group('šŸ“Š PREFETCH SUMMARY');\n console.log(`Total pages prefetched: ${routeLinks.length}`);\n console.log(`Total dependency chunks: ${dependencyLinks.length}`);\n console.log(`Total overall entries: ${this.prefetched.size}`);\n\n if (routeLinks.length > 0) {\n console.group('šŸ“„ Pages/Routes Prefetched:');\n const pageTable = routeLinks.map(link => ({\n route: link.getAttribute('data-prefetch-route'),\n chunk: link.href.replace(window.location.origin + '/', ''),\n priority: link.getAttribute('data-prefetch-priority'),\n probability: `${link.getAttribute('data-prefetch-probability')}`,\n }));\n console.table(pageTable);\n console.groupEnd();\n }\n\n if (dependencyLinks.length > 0) {\n console.group('šŸ“¦ Dependency Chunks Prefetched:');\n const depsTable = dependencyLinks.map(link => ({\n parentRoute: link.getAttribute('data-prefetch-parent'),\n chunk: link.href.replace(window.location.origin + '/', ''),\n }));\n console.table(depsTable);\n console.groupEnd();\n }\n\n console.groupEnd();\n }\n}\n","/**\n * Debug Utilities for Smart Prefetch Plugin\n * Helper functions to inspect and debug prefetch behavior\n */\n\n/**\n * Get all prefetch link elements from the DOM\n */\nexport function getPrefetchLinks(): HTMLLinkElement[] {\n return Array.from(document.querySelectorAll('link[rel=\"prefetch\"]'));\n}\n\n/**\n * Get prefetch links added by our plugin (with data attributes)\n */\nexport function getPluginPrefetchLinks(): HTMLLinkElement[] {\n return Array.from(document.querySelectorAll('link[rel=\"prefetch\"][data-prefetch-route]'));\n}\n\n/**\n * Log all prefetch links in a formatted way\n */\nexport function logPrefetchLinks(): void {\n const allLinks = getPrefetchLinks();\n const pluginLinks = getPluginPrefetchLinks();\n\n console.group('šŸ”— Prefetch Link Tags in DOM');\n console.log(`Total prefetch links: ${allLinks.length}`);\n console.log(`Plugin-managed links: ${pluginLinks.length}`);\n\n if (pluginLinks.length > 0) {\n console.group('Plugin-managed links:');\n console.table(\n pluginLinks.map((link) => ({\n route: link.getAttribute('data-prefetch-route'),\n href: link.href,\n priority: link.getAttribute('data-prefetch-priority'),\n probability: link.getAttribute('data-prefetch-probability'),\n loaded: link.hasAttribute('data-loaded'),\n }))\n );\n console.groupEnd();\n }\n\n const otherLinks = allLinks.filter((link) => !link.hasAttribute('data-prefetch-route'));\n if (otherLinks.length > 0) {\n console.group('Other prefetch links:');\n console.table(\n otherLinks.map((link) => ({\n href: link.href,\n as: link.getAttribute('as'),\n }))\n );\n console.groupEnd();\n }\n\n console.groupEnd();\n}\n\n/**\n * Monitor prefetch activity in real-time\n */\nexport function monitorPrefetchActivity(): () => void {\n console.log('šŸ” Monitoring prefetch activity...');\n console.log('Press the returned stop function to stop monitoring');\n\n const observer = new MutationObserver((mutations) => {\n mutations.forEach((mutation) => {\n mutation.addedNodes.forEach((node) => {\n if (node.nodeName === 'LINK') {\n const link = node as HTMLLinkElement;\n if (link.rel === 'prefetch') {\n console.log('āž• New prefetch link added:', {\n route: link.getAttribute('data-prefetch-route') || 'N/A',\n href: link.href,\n priority: link.getAttribute('data-prefetch-priority'),\n });\n }\n }\n });\n\n mutation.removedNodes.forEach((node) => {\n if (node.nodeName === 'LINK') {\n const link = node as HTMLLinkElement;\n if (link.rel === 'prefetch') {\n console.log('āž– Prefetch link removed:', {\n route: link.getAttribute('data-prefetch-route') || 'N/A',\n href: link.href,\n });\n }\n }\n });\n });\n });\n\n observer.observe(document.head, {\n childList: true,\n subtree: true,\n });\n\n return () => {\n console.log('šŸ›‘ Stopped monitoring prefetch activity');\n observer.disconnect();\n };\n}\n\n/**\n * Check if the smart prefetch plugin is properly configured\n */\nexport function checkPluginConfiguration(): void {\n console.group('šŸ”§ Smart Prefetch Plugin Configuration Check');\n\n // Check global config\n const globalConfig = (window as any).__SMART_PREFETCH__;\n if (globalConfig) {\n console.log('āœ… Global config found:', globalConfig);\n } else {\n console.warn('āŒ Global config not found on window.__SMART_PREFETCH__');\n console.log(' The plugin may not be properly configured in vite.config');\n }\n\n // Check if config file is accessible\n fetch('/prefetch-config.json')\n .then((res) => {\n if (res.ok) {\n console.log('āœ… prefetch-config.json is accessible');\n return res.json();\n } else {\n throw new Error(`HTTP ${res.status}: ${res.statusText}`);\n }\n })\n .then((config) => {\n console.log('šŸ“‹ Config content:', config);\n console.log(` Routes: ${Object.keys(config.routes).length}`);\n console.log(` Environment: ${config.environment}`);\n })\n .catch((error) => {\n console.error('āŒ Cannot access prefetch-config.json:', error.message);\n console.log(' Make sure to build the app first: pnpm build');\n })\n .finally(() => {\n console.groupEnd();\n });\n\n // Check debug function\n if (typeof (window as any).__PREFETCH_DEBUG__ === 'function') {\n console.log('āœ… Debug function available: window.__PREFETCH_DEBUG__()');\n } else {\n console.warn('āš ļø Debug function not available (may not be initialized yet)');\n }\n}\n\n/**\n * Expose all debug utilities globally for console access\n */\nexport function exposeDebugUtils(): void {\n const w = window as any;\n w.__PREFETCH_UTILS__ = {\n getPrefetchLinks,\n getPluginPrefetchLinks,\n logPrefetchLinks,\n monitorPrefetchActivity,\n checkPluginConfiguration,\n };\n\n console.log('šŸ’” Debug utilities exposed:');\n console.log(' window.__PREFETCH_UTILS__.getPrefetchLinks()');\n console.log(' window.__PREFETCH_UTILS__.logPrefetchLinks()');\n console.log(' window.__PREFETCH_UTILS__.monitorPrefetchActivity()');\n console.log(' window.__PREFETCH_UTILS__.checkPluginConfiguration()');\n}\n"],"mappings":"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","names":[]}
@@ -28,6 +28,8 @@ interface PrefetchTarget {
28
28
  count: number;
29
29
  /** Chunk file to prefetch (set by config generator) */
30
30
  chunk?: string;
31
+ /** Production chunk file path (for production builds) */
32
+ chunk_prod?: string;
31
33
  /** Dependency chunks to prefetch (extracted from Vite manifest imports) */
32
34
  imports?: string[];
33
35
  /** Priority level */
@@ -59,9 +61,13 @@ interface PrefetchConfig {
59
61
  maxPrefetch: number;
60
62
  accuracy?: number;
61
63
  };
64
+ /** Global route patterns for dynamic route matching */
65
+ routePatterns?: Record<string, string[]>;
62
66
  /** Route predictions with chunk mappings */
63
67
  routes: {
64
68
  [sourceRoute: string]: {
69
+ /** Route pattern variants (for matching dynamic routes like /order/:id) */
70
+ patterns?: string[];
65
71
  /** Default/common prefetch rules (works for all users) */
66
72
  prefetch: Array<PrefetchTarget & {
67
73
  chunk: string;
@@ -116,6 +122,15 @@ declare class PrefetchManager {
116
122
  * Get the current segment
117
123
  */
118
124
  getSegment(): string | null;
125
+ /**
126
+ * Match pathname against a route pattern
127
+ * Supports both React Router (:id) and TanStack Router ($id) syntax
128
+ * Examples:
129
+ * matchRoutePattern('/order/123', '/order/:id') → true
130
+ * matchRoutePattern('/user/john', '/user/$name') → true
131
+ * matchRoutePattern('/admin/settings', '/admin/*') → true
132
+ */
133
+ private matchRoutePattern;
119
134
  /**
120
135
  * Prefetch routes based on current route
121
136
  */
@@ -28,6 +28,8 @@ interface PrefetchTarget {
28
28
  count: number;
29
29
  /** Chunk file to prefetch (set by config generator) */
30
30
  chunk?: string;
31
+ /** Production chunk file path (for production builds) */
32
+ chunk_prod?: string;
31
33
  /** Dependency chunks to prefetch (extracted from Vite manifest imports) */
32
34
  imports?: string[];
33
35
  /** Priority level */
@@ -59,9 +61,13 @@ interface PrefetchConfig {
59
61
  maxPrefetch: number;
60
62
  accuracy?: number;
61
63
  };
64
+ /** Global route patterns for dynamic route matching */
65
+ routePatterns?: Record<string, string[]>;
62
66
  /** Route predictions with chunk mappings */
63
67
  routes: {
64
68
  [sourceRoute: string]: {
69
+ /** Route pattern variants (for matching dynamic routes like /order/:id) */
70
+ patterns?: string[];
65
71
  /** Default/common prefetch rules (works for all users) */
66
72
  prefetch: Array<PrefetchTarget & {
67
73
  chunk: string;
@@ -116,6 +122,15 @@ declare class PrefetchManager {
116
122
  * Get the current segment
117
123
  */
118
124
  getSegment(): string | null;
125
+ /**
126
+ * Match pathname against a route pattern
127
+ * Supports both React Router (:id) and TanStack Router ($id) syntax
128
+ * Examples:
129
+ * matchRoutePattern('/order/123', '/order/:id') → true
130
+ * matchRoutePattern('/user/john', '/user/$name') → true
131
+ * matchRoutePattern('/admin/settings', '/admin/*') → true
132
+ */
133
+ private matchRoutePattern;
119
134
  /**
120
135
  * Prefetch routes based on current route
121
136
  */
@@ -88,6 +88,21 @@ var PrefetchManager = class {
88
88
  getSegment() {
89
89
  return this.currentSegment;
90
90
  }
91
+ /**
92
+ * Match pathname against a route pattern
93
+ * Supports both React Router (:id) and TanStack Router ($id) syntax
94
+ * Examples:
95
+ * matchRoutePattern('/order/123', '/order/:id') → true
96
+ * matchRoutePattern('/user/john', '/user/$name') → true
97
+ * matchRoutePattern('/admin/settings', '/admin/*') → true
98
+ */
99
+ matchRoutePattern(pathname, pattern) {
100
+ const patternRegex = new RegExp(
101
+ "^" + pattern.replace(/:[^/]+/g, "[^/]+").replace(/\$[^/]+/g, "[^/]+").replace(/\*/g, ".*") + // Match wildcard
102
+ "$"
103
+ );
104
+ return patternRegex.test(pathname);
105
+ }
91
106
  /**
92
107
  * Prefetch routes based on current route
93
108
  */
@@ -113,7 +128,23 @@ var PrefetchManager = class {
113
128
  return;
114
129
  }
115
130
  let routeConfig = this.config.routes[cleanRoute] || this.config.routes[currentRoute];
116
- const matchedRoute = routeConfig ? this.config.routes[cleanRoute] ? cleanRoute : currentRoute : null;
131
+ let matchedRoute = routeConfig ? this.config.routes[cleanRoute] ? cleanRoute : currentRoute : null;
132
+ if (!routeConfig) {
133
+ for (const [configRoute, config] of Object.entries(this.config.routes)) {
134
+ const patterns = config.patterns || [configRoute];
135
+ for (const pattern of patterns) {
136
+ if (this.matchRoutePattern(cleanRoute, pattern)) {
137
+ routeConfig = config;
138
+ matchedRoute = configRoute;
139
+ if (this.debug) {
140
+ console.log(`\u2705 Pattern matched: "${cleanRoute}" \u2192 pattern "${pattern}"`);
141
+ }
142
+ break;
143
+ }
144
+ }
145
+ if (routeConfig) break;
146
+ }
147
+ }
117
148
  if (!routeConfig) {
118
149
  if (this.debug) {
119
150
  console.warn(`\u26A0\uFE0F No prefetch rules configured for route: ${cleanRoute}`);
@@ -123,7 +154,7 @@ var PrefetchManager = class {
123
154
  console.log(` ${route} \u2192 ${targets.length} target(s)`, targets.map((t) => t.route));
124
155
  });
125
156
  console.groupEnd();
126
- console.log(`\u{1F4A1} Tip: Make sure your manualRules key matches exactly: "${cleanRoute}"`);
157
+ console.log(`\u{1F4A1} Tip: Routes with dynamic segments like "/order/:id" or "/order/$id" should match automatically`);
127
158
  }
128
159
  return;
129
160
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/runtime/prefetch-manager.ts","../../src/runtime/debug-utils.ts"],"sourcesContent":["/**\n * Prefetch Manager (Runtime)\n * Manages route prefetching in the browser\n */\n\nimport type { PrefetchConfig, PrefetchStrategy, PrefetchTarget } from '../types';\n\nexport class PrefetchManager {\n private config: PrefetchConfig | null = null;\n private prefetched = new Set<string>();\n private strategy: PrefetchStrategy;\n private observer: IntersectionObserver | null = null;\n private debug: boolean;\n private currentSegment: string | null = null;\n private fallbackToDefault: boolean = true;\n\n constructor(strategy: PrefetchStrategy = 'hybrid', debug = false) {\n this.strategy = strategy;\n this.debug = debug;\n }\n\n /**\n * Initialize the prefetch manager\n * Loads configuration and sets up observers\n */\n async init(): Promise<void> {\n if (this.debug) {\n console.log('šŸš€ Smart Prefetch Manager - Initializing...');\n console.log(' Strategy:', this.strategy);\n console.log(' Debug mode: enabled');\n }\n\n try {\n // Load prefetch configuration\n if (this.debug) {\n console.log('šŸ“„ Fetching prefetch-config.json...');\n }\n\n const response = await fetch('/prefetch-config.json');\n\n // Gracefully handle missing config file (common in development)\n if (!response.ok) {\n if (response.status === 404) {\n if (this.debug) {\n console.warn('āš ļø Prefetch config not found (404)');\n console.log(' This is expected if:');\n console.log(' 1. You haven\\'t built the app yet (run `pnpm build`)');\n console.log(' 2. The plugin failed to generate the config during build');\n console.log(' Prefetch manager will be inactive until config is available');\n }\n return;\n }\n throw new Error(`Failed to load prefetch config: ${response.statusText}`);\n }\n\n this.config = await response.json();\n\n if (this.debug && this.config) {\n console.log('āœ… Config loaded successfully');\n console.log(` Routes with prefetch rules: ${Object.keys(this.config.routes).length} ${typeof this.config.routes}`);\n console.log(` Environment: ${this.config.environment}`);\n console.log(` Config version: ${this.config.version || 'N/A'}`);\n\n // List all routes with prefetch rules\n console.groupCollapsed('šŸ“‹ Available prefetch rules:');\n Object.entries(this.config.routes).forEach(([source, data]: [string, any]) => {\n console.log(`${source} → ${data.prefetch.length} target(s)`,\n data.prefetch.map((t: any) => t.route));\n });\n console.groupEnd();\n }\n\n // Set up intersection observer for 'visible' strategy\n if (this.strategy === 'visible' || this.strategy === 'hybrid') {\n this.initIntersectionObserver();\n if (this.debug) {\n console.log('šŸ‘ļø IntersectionObserver initialized for visibility-based prefetching');\n }\n }\n\n if (this.debug) {\n console.log('āœ… Prefetch Manager fully initialized');\n console.log('šŸ’” Run window.__PREFETCH_DEBUG__() to see current state');\n\n // Expose debug helper globally\n (window as any).__PREFETCH_DEBUG__ = () => this.logDebugInfo();\n }\n } catch (error) {\n // Only log error if debug mode is enabled\n if (this.debug) {\n console.error('āŒ Failed to initialize Prefetch Manager:', error);\n }\n }\n }\n\n /**\n * Set the user segment for segment-based prefetch rules\n * @param segment - The user's segment (e.g., 'premium', 'free', 'admin')\n * @param fallbackToDefault - Use default rules if segment rules unavailable\n */\n setSegment(segment: string | null, fallbackToDefault: boolean = true): void {\n this.currentSegment = segment;\n this.fallbackToDefault = fallbackToDefault;\n\n if (this.debug) {\n console.log(`šŸ”„ Segment updated: ${segment || '(none)'}`);\n console.log(` Fallback to default: ${fallbackToDefault}`);\n }\n }\n\n /**\n * Get the current segment\n */\n getSegment(): string | null {\n return this.currentSegment;\n }\n\n /**\n * Prefetch routes based on current route\n */\n prefetch(currentRoute: string): void {\n // Strip query parameters and hash from the route\n const cleanRoute = currentRoute.split('?')[0].split('#')[0];\n\n if (this.debug) {\n console.log(`šŸ“ Checking prefetch for route: ${currentRoute}`);\n if (currentRoute !== cleanRoute) {\n console.log(` Clean route: ${cleanRoute}`);\n }\n }\n\n if (!this.config) {\n if (this.debug) {\n console.warn('āš ļø Config not loaded yet - cannot prefetch');\n console.log(' Make sure the app was built with the plugin enabled');\n }\n return;\n }\n\n // Check network conditions\n if (!this.shouldPrefetch()) {\n if (this.debug) {\n console.log('ā­ļø Skipping prefetch due to network conditions');\n }\n return;\n }\n\n // Try to find route config (try both clean and original route)\n let routeConfig = this.config.routes[cleanRoute] || this.config.routes[currentRoute];\n const matchedRoute = routeConfig ? (this.config.routes[cleanRoute] ? cleanRoute : currentRoute) : null;\n\n if (!routeConfig) {\n if (this.debug) {\n console.warn(`āš ļø No prefetch rules configured for route: ${cleanRoute}`);\n console.groupCollapsed('Available routes in config:');\n Object.keys(this.config.routes).forEach(route => {\n const targets = this.config!.routes[route].prefetch;\n console.log(` ${route} → ${targets.length} target(s)`, targets.map(t => t.route));\n });\n console.groupEnd();\n console.log(`šŸ’” Tip: Make sure your manualRules key matches exactly: \"${cleanRoute}\"`);\n }\n return;\n }\n\n // Determine which rules to use: segment-specific or default\n let prefetchTargets = routeConfig.prefetch;\n let ruleSource = 'default';\n\n // Check if segment-specific rules are available and configured\n if (this.currentSegment && routeConfig.segments?.[this.currentSegment]) {\n prefetchTargets = routeConfig.segments[this.currentSegment];\n ruleSource = `segment (${this.currentSegment})`;\n } else if (this.currentSegment && !routeConfig.segments?.[this.currentSegment] && !this.fallbackToDefault) {\n // Segment specified but no rules for it and fallback disabled\n if (this.debug) {\n console.warn(`āš ļø No prefetch rules for segment \"${this.currentSegment}\" and fallback disabled`);\n }\n return;\n }\n\n // Always log when a route is found and prefetch is about to happen\n console.log(`āœ… Found prefetch rule for: ${matchedRoute}`);\n console.log(` Total targets to prefetch: ${prefetchTargets.length}`);\n console.log(` Using: ${ruleSource} rules`);\n console.log(` Strategy: ${this.strategy}`);\n\n if (this.debug) {\n console.groupCollapsed(`šŸ“Š Prefetch Rules for: ${matchedRoute} (${ruleSource})`);\n prefetchTargets.forEach((target, index) => {\n console.log(` ${index + 1}. ${target.route} (${target.priority} priority, ${(target.probability * 100).toFixed(1)}%)`);\n });\n console.groupEnd();\n }\n\n // Prefetch based on strategy\n prefetchTargets.forEach((target) => {\n this.prefetchTarget(target);\n });\n }\n\n /**\n * Prefetch a specific target\n */\n private prefetchTarget(target: any): void {\n // Check if already prefetched\n if (this.prefetched.has(target.route)) {\n console.log(` ā­ļø Already prefetched: ${target.route}`);\n return;\n }\n\n console.log(` šŸ”— Prefetch target: ${target.route}, chunk: ${target.chunk}`);\n\n try {\n // Apply strategy-based prefetching\n switch (this.strategy) {\n case 'auto':\n this.injectPrefetchLink(target);\n break;\n\n case 'hover':\n // Hover is handled by link components\n break;\n\n case 'visible':\n // Visible is handled by IntersectionObserver\n break;\n\n case 'idle':\n this.prefetchOnIdle(target);\n break;\n\n case 'hybrid':\n this.prefetchHybrid(target);\n break;\n\n default:\n console.warn(`āš ļø Unknown strategy: ${this.strategy}`);\n }\n } catch (error) {\n console.error(`āŒ Error prefetching ${target.route}:`, error);\n }\n }\n\n /**\n * Hybrid strategy: prioritize based on probability\n * FOR TESTING: Fetch all priorities to verify chunks are correct\n */\n private prefetchHybrid(target: PrefetchTarget & { chunk: string }): void {\n if (target.priority === 'high' || target.probability >= 0.7) {\n // High priority: prefetch immediately\n console.log(` ⚔ High priority (${(target.probability * 100).toFixed(1)}%) - Prefetching immediately`);\n this.injectPrefetchLink(target);\n } else if (target.priority === 'medium' || target.probability >= 0.4) {\n // Medium priority: prefetch on idle (FOR TESTING: fetch immediately)\n console.log(` ā±ļø Medium priority (${(target.probability * 100).toFixed(1)}%) - Fetching immediately (TESTING MODE)`);\n this.injectPrefetchLink(target); // Changed from prefetchOnIdle to immediate for testing\n } else {\n // Low priority: wait for visibility or hover (FOR TESTING: fetch immediately)\n console.log(` šŸ”” Low priority (${(target.probability * 100).toFixed(1)}%) - Fetching immediately (TESTING MODE)`);\n this.injectPrefetchLink(target); // Changed from deferred to immediate for testing\n }\n }\n\n /**\n * Prefetch during idle time\n */\n private prefetchOnIdle(target: PrefetchTarget & { chunk: string }): void {\n if ('requestIdleCallback' in window) {\n requestIdleCallback(() => {\n this.injectPrefetchLink(target);\n });\n } else {\n // Fallback for browsers without requestIdleCallback\n setTimeout(() => {\n this.injectPrefetchLink(target);\n }, 1000);\n }\n }\n\n /**\n * Resolve chunk path for the current environment\n * In production: chunks are built with hashes (e.g., chunks/Privacy-D5qJZu-O.js or js/index-CJMMxcQV.js)\n * In dev mode: need to resolve to the actual module or use a proxy\n */\n private resolveChunkPath(chunkPath: string, route: string): string {\n const isDev = window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1';\n\n if (!isDev) {\n // Production: use the chunk path as-is (it has real hashes from the build)\n return `/${chunkPath}`;\n }\n\n // Dev mode: Try to map chunk to component and use source files\n // Extract component name from chunk path\n // Examples:\n // - chunks/Privacy-D5qJZu-O.js → Privacy\n // - js/index-CJMMxcQV.js → index\n // - chunks/chunk-user-profile-JNr_q4Gn.js → (can't map, use original)\n\n // Try to extract component name from various chunk name patterns\n let componentName: string | null = null;\n\n // Pattern 1: Individual component chunks (e.g., Privacy-D5qJZu-O.js)\n const match1 = chunkPath.match(/\\/([A-Z][a-zA-Z]*)-[a-zA-Z0-9_-]+\\.js$/);\n if (match1) {\n componentName = match1[1];\n }\n\n // Pattern 2: Main/index chunks (e.g., js/index-CJMMxcQV.js)\n const match2 = chunkPath.match(/\\/(index)-[a-zA-Z0-9_-]+\\.js$/);\n if (match2) {\n componentName = match2[1];\n }\n\n if (componentName) {\n // Map component name to source file\n // This works because Vite's dev server resolves source files dynamically\n const sourceFile = componentName === 'index' ? '/src/main.tsx' : `/src/pages/${componentName}.tsx`;\n if (this.debug) {\n console.log(` šŸ“ Dev mode: Resolved ${chunkPath} → ${sourceFile}`);\n }\n return sourceFile;\n }\n\n // Fallback: use original chunk path with leading slash\n if (this.debug) {\n console.log(` āš ļø Dev mode: Could not extract component name from ${chunkPath}, using as-is`);\n }\n return `/${chunkPath}`;\n }\n\n /**\n * Inject prefetch link into DOM\n */\n private injectPrefetchLink(target: PrefetchTarget & { chunk: string }): void {\n if (this.prefetched.has(target.route)) {\n if (this.debug) {\n console.log(` ā­ļø Already prefetched: ${target.route}`);\n }\n return;\n }\n\n // Resolve the actual chunk path for the current environment\n // In production: use the chunk hash from config (e.g., chunks/Privacy-D5qJZu-O.js)\n // In dev mode: chunks don't exist as files, Vite handles them at request time\n const chunkPath = this.resolveChunkPath(target.chunk, target.route);\n\n // Create main chunk link\n const link = document.createElement('link');\n // Use modulepreload for better ES module support (triggers actual fetch)\n link.rel = 'modulepreload';\n link.href = chunkPath;\n link.setAttribute('data-prefetch-route', target.route);\n link.setAttribute('data-prefetch-priority', target.priority);\n link.setAttribute('data-prefetch-probability', target.probability.toString());\n\n // Always log prefetch with details\n console.groupCollapsed(`šŸ”— PREFETCH: ${target.route}`);\n console.log(` šŸ“„ Page/Route: ${target.route}`);\n console.log(` šŸ“¦ Main Chunk: ${target.chunk}`);\n console.log(` 🌐 Resolved URL: ${window.location.origin}${chunkPath}`);\n console.log(` ⭐ Priority: ${target.priority}`);\n console.log(` šŸ“Š Probability: ${(target.probability * 100).toFixed(1)}%`);\n\n // Track total chunks being fetched\n let totalChunksForThisRoute = 1; // Main chunk\n const injectedLinks: string[] = [];\n\n // Try to append the main link - CRITICAL: this must happen first\n try {\n document.head.appendChild(link);\n injectedLinks.push(target.chunk);\n console.log(` āœ… Main chunk link injected: ${target.chunk}`);\n } catch (e) {\n console.error(` āŒ Failed to inject main chunk link:`, e);\n console.groupEnd();\n return;\n }\n\n // Also prefetch all dependency chunks (imports)\n if (target.imports && target.imports.length > 0) {\n console.log(` šŸ“š Dependencies (${target.imports.length}):`);\n target.imports.forEach((importChunk, index) => {\n // Skip if already prefetched by another route\n const importId = `import:${importChunk}`;\n if (this.prefetched.has(importId)) {\n console.log(` ${index + 1}. ${importChunk} (already prefetched)`);\n return;\n }\n\n try {\n const importLink = document.createElement('link');\n importLink.rel = 'modulepreload';\n importLink.href = `/${importChunk}`;\n importLink.setAttribute('data-prefetch-import', 'true');\n importLink.setAttribute('data-prefetch-parent', target.route);\n document.head.appendChild(importLink);\n this.prefetched.add(importId);\n totalChunksForThisRoute++;\n injectedLinks.push(importChunk);\n\n console.log(` ${index + 1}. ${importChunk} āœ…`);\n } catch (e) {\n console.error(` ${index + 1}. ${importChunk} āŒ Error:`, e);\n }\n });\n }\n\n // Mark as prefetched\n this.prefetched.add(target.route);\n\n console.log(` āœ… Total chunks injected: ${totalChunksForThisRoute}`);\n console.log(` šŸ“ˆ Overall prefetched count: ${this.prefetched.size}`);\n\n if (this.debug) {\n console.log(` DOM Status: ${injectedLinks.length} link tag(s) added to document.head`);\n console.log(` Injected URLs:`, injectedLinks.map(c => `/${c}`));\n\n // Verify the link was actually added and check if it loaded\n setTimeout(() => {\n const addedLink = document.querySelector(`link[data-prefetch-route=\"${target.route}\"]`);\n if (addedLink) {\n console.log(` āœ”ļø DOM Verification: Link exists`);\n console.log(` href:`, (addedLink as HTMLLinkElement).href);\n console.log(` as:`, (addedLink as HTMLLinkElement).getAttribute('as'));\n console.log(` rel:`, (addedLink as HTMLLinkElement).rel);\n\n // Check if link actually triggered a fetch\n if ((addedLink as any).relList?.contains('modulepreload')) {\n console.log(` šŸ”„ Link has modulepreload rel (will fetch)`);\n }\n } else {\n console.error(` āŒ ERROR: Link tag not found in DOM after 100ms`);\n }\n\n // Verify ALL injected links exist\n console.log(` šŸ“‹ Verifying all injected links in head:`);\n document.querySelectorAll('link[data-prefetch-route], link[data-prefetch-import]').forEach((el, idx) => {\n const isMain = el.hasAttribute('data-prefetch-route');\n const parent = isMain ? el.getAttribute('data-prefetch-route') : el.getAttribute('data-prefetch-parent');\n console.log(` ${idx + 1}. ${(el as HTMLLinkElement).href} (parent: ${parent})`);\n });\n }, 50);\n }\n\n console.groupEnd();\n }\n\n /**\n * Check if prefetching should be performed based on network conditions\n */\n private shouldPrefetch(): boolean {\n // Check if Network Information API is available\n const nav = navigator as any;\n const connection = nav.connection || nav.mozConnection || nav.webkitConnection;\n\n if (!connection) {\n // API not available, assume prefetch is OK\n return true;\n }\n\n // Respect Data Saver mode\n if (connection.saveData) {\n if (this.debug) console.log(' āš ļø Data Saver enabled');\n return false;\n }\n\n // Check connection speed\n const slowConnections = ['slow-2g', '2g'];\n if (slowConnections.includes(connection.effectiveType)) {\n if (this.debug) console.log(` āš ļø Slow connection: ${connection.effectiveType}`);\n return false;\n }\n\n // Check if metered connection (conservative approach)\n if (connection.type === 'cellular' && connection.effectiveType !== '4g') {\n if (this.debug) console.log(' āš ļø Metered connection');\n return false;\n }\n\n return true;\n }\n\n /**\n * Initialize IntersectionObserver for 'visible' strategy\n */\n private initIntersectionObserver(): void {\n this.observer = new IntersectionObserver(\n (entries) => {\n entries.forEach((entry) => {\n if (entry.isIntersecting) {\n const route = entry.target.getAttribute('data-prefetch-route');\n if (route && this.config) {\n // Find the target in config\n Object.values(this.config.routes).forEach((routeConfig) => {\n const target = routeConfig.prefetch.find((t) => t.route === route);\n if (target) {\n this.injectPrefetchLink(target);\n }\n });\n }\n }\n });\n },\n {\n rootMargin: '50px', // Start prefetch 50px before element is visible\n }\n );\n }\n\n /**\n * Observe an element for visibility-based prefetching\n */\n observeLink(element: HTMLElement, route: string): void {\n if (this.observer) {\n element.setAttribute('data-prefetch-route', route);\n this.observer.observe(element);\n }\n }\n\n /**\n * Manually trigger prefetch for a specific route\n * Useful for hover events\n */\n prefetchRoute(route: string): void {\n if (!this.config) return;\n\n // Find this route in all route configs\n Object.values(this.config.routes).forEach((routeConfig) => {\n const target = routeConfig.prefetch.find((t) => t.route === route);\n if (target) {\n this.injectPrefetchLink(target);\n }\n });\n }\n\n /**\n * Get prefetch statistics\n */\n getStats(): {\n totalPrefetched: number;\n prefetchedRoutes: string[];\n configLoaded: boolean;\n strategy: PrefetchStrategy;\n } {\n return {\n totalPrefetched: this.prefetched.size,\n prefetchedRoutes: Array.from(this.prefetched),\n configLoaded: this.config !== null,\n strategy: this.strategy,\n };\n }\n\n /**\n * Check if a route has been prefetched\n */\n isPrefetched(route: string): boolean {\n return this.prefetched.has(route);\n }\n\n /**\n * Clear all prefetch state\n */\n clear(): void {\n this.prefetched.clear();\n if (this.observer) {\n this.observer.disconnect();\n }\n }\n\n /**\n * Get all prefetch link elements currently in the DOM\n */\n getActivePrefetchLinks(): HTMLLinkElement[] {\n return Array.from(document.querySelectorAll('link[rel=\"modulepreload\"][data-prefetch-route]'));\n }\n\n /**\n * Log current state for debugging\n */\n logDebugInfo(): void {\n console.group('šŸ› Smart Prefetch Debug Info');\n console.log('Strategy:', this.strategy);\n console.log('Config loaded:', this.config !== null);\n console.log('Total prefetch entries:', this.prefetched.size);\n console.log('Prefetched items:', Array.from(this.prefetched));\n\n const links = this.getActivePrefetchLinks();\n console.log('\\nšŸ”— Active Link Tags in DOM:', links.length);\n\n if (links.length > 0) {\n console.table(links.map(link => ({\n route: link.getAttribute('data-prefetch-route'),\n chunk: link.href.replace(window.location.origin + '/', ''),\n priority: link.getAttribute('data-prefetch-priority'),\n probability: link.getAttribute('data-prefetch-probability'),\n })));\n }\n\n if (this.config) {\n console.log('\\nšŸ“Š Configuration Summary:');\n console.log('Available routes in config:', Object.keys(this.config.routes).length);\n console.log('Config environment:', this.config.environment);\n\n console.group('šŸ“‹ All configured routes with prefetch targets:');\n Object.entries(this.config.routes).forEach(([route, data]: [string, any]) => {\n console.group(`${route}`);\n data.prefetch.forEach((t: any, idx: number) => {\n console.log(` ${idx + 1}. ${t.route} (${t.priority}, ${(t.probability * 100).toFixed(1)}%) → ${t.chunk}`);\n });\n console.groupEnd();\n });\n console.groupEnd();\n\n console.log('\\nšŸ’” Current location:', window.location.pathname);\n console.log('šŸ’” Clean route:', window.location.pathname.split('?')[0].split('#')[0]);\n }\n\n console.groupEnd();\n }\n\n /**\n * Log all prefetched pages and chunks (summary view)\n */\n logPrefetchSummary(): void {\n const links = this.getActivePrefetchLinks();\n const routeLinks = links.filter(l => !l.getAttribute('data-prefetch-import'));\n const dependencyLinks = links.filter(l => l.getAttribute('data-prefetch-import'));\n\n console.group('šŸ“Š PREFETCH SUMMARY');\n console.log(`Total pages prefetched: ${routeLinks.length}`);\n console.log(`Total dependency chunks: ${dependencyLinks.length}`);\n console.log(`Total overall entries: ${this.prefetched.size}`);\n\n if (routeLinks.length > 0) {\n console.group('šŸ“„ Pages/Routes Prefetched:');\n const pageTable = routeLinks.map(link => ({\n route: link.getAttribute('data-prefetch-route'),\n chunk: link.href.replace(window.location.origin + '/', ''),\n priority: link.getAttribute('data-prefetch-priority'),\n probability: `${link.getAttribute('data-prefetch-probability')}`,\n }));\n console.table(pageTable);\n console.groupEnd();\n }\n\n if (dependencyLinks.length > 0) {\n console.group('šŸ“¦ Dependency Chunks Prefetched:');\n const depsTable = dependencyLinks.map(link => ({\n parentRoute: link.getAttribute('data-prefetch-parent'),\n chunk: link.href.replace(window.location.origin + '/', ''),\n }));\n console.table(depsTable);\n console.groupEnd();\n }\n\n console.groupEnd();\n }\n}\n","/**\n * Debug Utilities for Smart Prefetch Plugin\n * Helper functions to inspect and debug prefetch behavior\n */\n\n/**\n * Get all prefetch link elements from the DOM\n */\nexport function getPrefetchLinks(): HTMLLinkElement[] {\n return Array.from(document.querySelectorAll('link[rel=\"prefetch\"]'));\n}\n\n/**\n * Get prefetch links added by our plugin (with data attributes)\n */\nexport function getPluginPrefetchLinks(): HTMLLinkElement[] {\n return Array.from(document.querySelectorAll('link[rel=\"prefetch\"][data-prefetch-route]'));\n}\n\n/**\n * Log all prefetch links in a formatted way\n */\nexport function logPrefetchLinks(): void {\n const allLinks = getPrefetchLinks();\n const pluginLinks = getPluginPrefetchLinks();\n\n console.group('šŸ”— Prefetch Link Tags in DOM');\n console.log(`Total prefetch links: ${allLinks.length}`);\n console.log(`Plugin-managed links: ${pluginLinks.length}`);\n\n if (pluginLinks.length > 0) {\n console.group('Plugin-managed links:');\n console.table(\n pluginLinks.map((link) => ({\n route: link.getAttribute('data-prefetch-route'),\n href: link.href,\n priority: link.getAttribute('data-prefetch-priority'),\n probability: link.getAttribute('data-prefetch-probability'),\n loaded: link.hasAttribute('data-loaded'),\n }))\n );\n console.groupEnd();\n }\n\n const otherLinks = allLinks.filter((link) => !link.hasAttribute('data-prefetch-route'));\n if (otherLinks.length > 0) {\n console.group('Other prefetch links:');\n console.table(\n otherLinks.map((link) => ({\n href: link.href,\n as: link.getAttribute('as'),\n }))\n );\n console.groupEnd();\n }\n\n console.groupEnd();\n}\n\n/**\n * Monitor prefetch activity in real-time\n */\nexport function monitorPrefetchActivity(): () => void {\n console.log('šŸ” Monitoring prefetch activity...');\n console.log('Press the returned stop function to stop monitoring');\n\n const observer = new MutationObserver((mutations) => {\n mutations.forEach((mutation) => {\n mutation.addedNodes.forEach((node) => {\n if (node.nodeName === 'LINK') {\n const link = node as HTMLLinkElement;\n if (link.rel === 'prefetch') {\n console.log('āž• New prefetch link added:', {\n route: link.getAttribute('data-prefetch-route') || 'N/A',\n href: link.href,\n priority: link.getAttribute('data-prefetch-priority'),\n });\n }\n }\n });\n\n mutation.removedNodes.forEach((node) => {\n if (node.nodeName === 'LINK') {\n const link = node as HTMLLinkElement;\n if (link.rel === 'prefetch') {\n console.log('āž– Prefetch link removed:', {\n route: link.getAttribute('data-prefetch-route') || 'N/A',\n href: link.href,\n });\n }\n }\n });\n });\n });\n\n observer.observe(document.head, {\n childList: true,\n subtree: true,\n });\n\n return () => {\n console.log('šŸ›‘ Stopped monitoring prefetch activity');\n observer.disconnect();\n };\n}\n\n/**\n * Check if the smart prefetch plugin is properly configured\n */\nexport function checkPluginConfiguration(): void {\n console.group('šŸ”§ Smart Prefetch Plugin Configuration Check');\n\n // Check global config\n const globalConfig = (window as any).__SMART_PREFETCH__;\n if (globalConfig) {\n console.log('āœ… Global config found:', globalConfig);\n } else {\n console.warn('āŒ Global config not found on window.__SMART_PREFETCH__');\n console.log(' The plugin may not be properly configured in vite.config');\n }\n\n // Check if config file is accessible\n fetch('/prefetch-config.json')\n .then((res) => {\n if (res.ok) {\n console.log('āœ… prefetch-config.json is accessible');\n return res.json();\n } else {\n throw new Error(`HTTP ${res.status}: ${res.statusText}`);\n }\n })\n .then((config) => {\n console.log('šŸ“‹ Config content:', config);\n console.log(` Routes: ${Object.keys(config.routes).length}`);\n console.log(` Environment: ${config.environment}`);\n })\n .catch((error) => {\n console.error('āŒ Cannot access prefetch-config.json:', error.message);\n console.log(' Make sure to build the app first: pnpm build');\n })\n .finally(() => {\n console.groupEnd();\n });\n\n // Check debug function\n if (typeof (window as any).__PREFETCH_DEBUG__ === 'function') {\n console.log('āœ… Debug function available: window.__PREFETCH_DEBUG__()');\n } else {\n console.warn('āš ļø Debug function not available (may not be initialized yet)');\n }\n}\n\n/**\n * Expose all debug utilities globally for console access\n */\nexport function exposeDebugUtils(): void {\n const w = window as any;\n w.__PREFETCH_UTILS__ = {\n getPrefetchLinks,\n getPluginPrefetchLinks,\n logPrefetchLinks,\n monitorPrefetchActivity,\n checkPluginConfiguration,\n };\n\n console.log('šŸ’” Debug utilities exposed:');\n console.log(' window.__PREFETCH_UTILS__.getPrefetchLinks()');\n console.log(' window.__PREFETCH_UTILS__.logPrefetchLinks()');\n console.log(' window.__PREFETCH_UTILS__.monitorPrefetchActivity()');\n console.log(' window.__PREFETCH_UTILS__.checkPluginConfiguration()');\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/runtime/prefetch-manager.ts","../../src/runtime/debug-utils.ts"],"sourcesContent":["/**\n * Prefetch Manager (Runtime)\n * Manages route prefetching in the browser\n */\n\nimport type { PrefetchConfig, PrefetchStrategy, PrefetchTarget } from '../types';\n\nexport class PrefetchManager {\n private config: PrefetchConfig | null = null;\n private prefetched = new Set<string>();\n private strategy: PrefetchStrategy;\n private observer: IntersectionObserver | null = null;\n private debug: boolean;\n private currentSegment: string | null = null;\n private fallbackToDefault: boolean = true;\n\n constructor(strategy: PrefetchStrategy = 'hybrid', debug = false) {\n this.strategy = strategy;\n this.debug = debug;\n }\n\n /**\n * Initialize the prefetch manager\n * Loads configuration and sets up observers\n */\n async init(): Promise<void> {\n if (this.debug) {\n console.log('šŸš€ Smart Prefetch Manager - Initializing...');\n console.log(' Strategy:', this.strategy);\n console.log(' Debug mode: enabled');\n }\n\n try {\n // Load prefetch configuration\n if (this.debug) {\n console.log('šŸ“„ Fetching prefetch-config.json...');\n }\n\n const response = await fetch('/prefetch-config.json');\n\n // Gracefully handle missing config file (common in development)\n if (!response.ok) {\n if (response.status === 404) {\n if (this.debug) {\n console.warn('āš ļø Prefetch config not found (404)');\n console.log(' This is expected if:');\n console.log(' 1. You haven\\'t built the app yet (run `pnpm build`)');\n console.log(' 2. The plugin failed to generate the config during build');\n console.log(' Prefetch manager will be inactive until config is available');\n }\n return;\n }\n throw new Error(`Failed to load prefetch config: ${response.statusText}`);\n }\n\n this.config = await response.json();\n\n if (this.debug && this.config) {\n console.log('āœ… Config loaded successfully');\n console.log(` Routes with prefetch rules: ${Object.keys(this.config.routes).length} ${typeof this.config.routes}`);\n console.log(` Environment: ${this.config.environment}`);\n console.log(` Config version: ${this.config.version || 'N/A'}`);\n\n // List all routes with prefetch rules\n console.groupCollapsed('šŸ“‹ Available prefetch rules:');\n Object.entries(this.config.routes).forEach(([source, data]: [string, any]) => {\n console.log(`${source} → ${data.prefetch.length} target(s)`,\n data.prefetch.map((t: any) => t.route));\n });\n console.groupEnd();\n }\n\n // Set up intersection observer for 'visible' strategy\n if (this.strategy === 'visible' || this.strategy === 'hybrid') {\n this.initIntersectionObserver();\n if (this.debug) {\n console.log('šŸ‘ļø IntersectionObserver initialized for visibility-based prefetching');\n }\n }\n\n if (this.debug) {\n console.log('āœ… Prefetch Manager fully initialized');\n console.log('šŸ’” Run window.__PREFETCH_DEBUG__() to see current state');\n\n // Expose debug helper globally\n (window as any).__PREFETCH_DEBUG__ = () => this.logDebugInfo();\n }\n } catch (error) {\n // Only log error if debug mode is enabled\n if (this.debug) {\n console.error('āŒ Failed to initialize Prefetch Manager:', error);\n }\n }\n }\n\n /**\n * Set the user segment for segment-based prefetch rules\n * @param segment - The user's segment (e.g., 'premium', 'free', 'admin')\n * @param fallbackToDefault - Use default rules if segment rules unavailable\n */\n setSegment(segment: string | null, fallbackToDefault: boolean = true): void {\n this.currentSegment = segment;\n this.fallbackToDefault = fallbackToDefault;\n\n if (this.debug) {\n console.log(`šŸ”„ Segment updated: ${segment || '(none)'}`);\n console.log(` Fallback to default: ${fallbackToDefault}`);\n }\n }\n\n /**\n * Get the current segment\n */\n getSegment(): string | null {\n return this.currentSegment;\n }\n\n /**\n * Match pathname against a route pattern\n * Supports both React Router (:id) and TanStack Router ($id) syntax\n * Examples:\n * matchRoutePattern('/order/123', '/order/:id') → true\n * matchRoutePattern('/user/john', '/user/$name') → true\n * matchRoutePattern('/admin/settings', '/admin/*') → true\n */\n private matchRoutePattern(pathname: string, pattern: string): boolean {\n const patternRegex = new RegExp(\n '^' + pattern\n .replace(/:[^/]+/g, '[^/]+') // Match :param style (React Router)\n .replace(/\\$[^/]+/g, '[^/]+') // Match $param style (TanStack Router)\n .replace(/\\*/g, '.*') + // Match wildcard\n '$'\n );\n return patternRegex.test(pathname);\n }\n\n /**\n * Prefetch routes based on current route\n */\n prefetch(currentRoute: string): void {\n // Strip query parameters and hash from the route\n const cleanRoute = currentRoute.split('?')[0].split('#')[0];\n\n if (this.debug) {\n console.log(`šŸ“ Checking prefetch for route: ${currentRoute}`);\n if (currentRoute !== cleanRoute) {\n console.log(` Clean route: ${cleanRoute}`);\n }\n }\n\n if (!this.config) {\n if (this.debug) {\n console.warn('āš ļø Config not loaded yet - cannot prefetch');\n console.log(' Make sure the app was built with the plugin enabled');\n }\n return;\n }\n\n // Check network conditions\n if (!this.shouldPrefetch()) {\n if (this.debug) {\n console.log('ā­ļø Skipping prefetch due to network conditions');\n }\n return;\n }\n\n // Try to find route config with three strategies:\n // 1. Exact match on clean route\n // 2. Exact match on original route\n // 3. Pattern match (for dynamic routes like /order/:id or /order/$id)\n let routeConfig = this.config.routes[cleanRoute] || this.config.routes[currentRoute];\n let matchedRoute = routeConfig ? (this.config.routes[cleanRoute] ? cleanRoute : currentRoute) : null;\n\n // If no exact match, try pattern matching\n if (!routeConfig) {\n for (const [configRoute, config] of Object.entries(this.config.routes)) {\n // Check if the route has pattern information\n const patterns = (config as any).patterns || [configRoute];\n for (const pattern of patterns) {\n if (this.matchRoutePattern(cleanRoute, pattern)) {\n routeConfig = config as any;\n matchedRoute = configRoute;\n if (this.debug) {\n console.log(`āœ… Pattern matched: \"${cleanRoute}\" → pattern \"${pattern}\"`);\n }\n break;\n }\n }\n if (routeConfig) break;\n }\n }\n\n if (!routeConfig) {\n if (this.debug) {\n console.warn(`āš ļø No prefetch rules configured for route: ${cleanRoute}`);\n console.groupCollapsed('Available routes in config:');\n Object.keys(this.config.routes).forEach(route => {\n const targets = this.config!.routes[route].prefetch;\n console.log(` ${route} → ${targets.length} target(s)`, targets.map(t => t.route));\n });\n console.groupEnd();\n console.log(`šŸ’” Tip: Routes with dynamic segments like \"/order/:id\" or \"/order/$id\" should match automatically`);\n }\n return;\n }\n\n // Determine which rules to use: segment-specific or default\n let prefetchTargets = routeConfig.prefetch;\n let ruleSource = 'default';\n\n // Check if segment-specific rules are available and configured\n if (this.currentSegment && routeConfig.segments?.[this.currentSegment]) {\n prefetchTargets = routeConfig.segments[this.currentSegment];\n ruleSource = `segment (${this.currentSegment})`;\n } else if (this.currentSegment && !routeConfig.segments?.[this.currentSegment] && !this.fallbackToDefault) {\n // Segment specified but no rules for it and fallback disabled\n if (this.debug) {\n console.warn(`āš ļø No prefetch rules for segment \"${this.currentSegment}\" and fallback disabled`);\n }\n return;\n }\n\n // Always log when a route is found and prefetch is about to happen\n console.log(`āœ… Found prefetch rule for: ${matchedRoute}`);\n console.log(` Total targets to prefetch: ${prefetchTargets.length}`);\n console.log(` Using: ${ruleSource} rules`);\n console.log(` Strategy: ${this.strategy}`);\n\n if (this.debug) {\n console.groupCollapsed(`šŸ“Š Prefetch Rules for: ${matchedRoute} (${ruleSource})`);\n prefetchTargets.forEach((target, index) => {\n console.log(` ${index + 1}. ${target.route} (${target.priority} priority, ${(target.probability * 100).toFixed(1)}%)`);\n });\n console.groupEnd();\n }\n\n // Prefetch based on strategy\n prefetchTargets.forEach((target) => {\n this.prefetchTarget(target);\n });\n }\n\n /**\n * Prefetch a specific target\n */\n private prefetchTarget(target: any): void {\n // Check if already prefetched\n if (this.prefetched.has(target.route)) {\n console.log(` ā­ļø Already prefetched: ${target.route}`);\n return;\n }\n\n console.log(` šŸ”— Prefetch target: ${target.route}, chunk: ${target.chunk}`);\n\n try {\n // Apply strategy-based prefetching\n switch (this.strategy) {\n case 'auto':\n this.injectPrefetchLink(target);\n break;\n\n case 'hover':\n // Hover is handled by link components\n break;\n\n case 'visible':\n // Visible is handled by IntersectionObserver\n break;\n\n case 'idle':\n this.prefetchOnIdle(target);\n break;\n\n case 'hybrid':\n this.prefetchHybrid(target);\n break;\n\n default:\n console.warn(`āš ļø Unknown strategy: ${this.strategy}`);\n }\n } catch (error) {\n console.error(`āŒ Error prefetching ${target.route}:`, error);\n }\n }\n\n /**\n * Hybrid strategy: prioritize based on probability\n * FOR TESTING: Fetch all priorities to verify chunks are correct\n */\n private prefetchHybrid(target: PrefetchTarget & { chunk: string }): void {\n if (target.priority === 'high' || target.probability >= 0.7) {\n // High priority: prefetch immediately\n console.log(` ⚔ High priority (${(target.probability * 100).toFixed(1)}%) - Prefetching immediately`);\n this.injectPrefetchLink(target);\n } else if (target.priority === 'medium' || target.probability >= 0.4) {\n // Medium priority: prefetch on idle (FOR TESTING: fetch immediately)\n console.log(` ā±ļø Medium priority (${(target.probability * 100).toFixed(1)}%) - Fetching immediately (TESTING MODE)`);\n this.injectPrefetchLink(target); // Changed from prefetchOnIdle to immediate for testing\n } else {\n // Low priority: wait for visibility or hover (FOR TESTING: fetch immediately)\n console.log(` šŸ”” Low priority (${(target.probability * 100).toFixed(1)}%) - Fetching immediately (TESTING MODE)`);\n this.injectPrefetchLink(target); // Changed from deferred to immediate for testing\n }\n }\n\n /**\n * Prefetch during idle time\n */\n private prefetchOnIdle(target: PrefetchTarget & { chunk: string }): void {\n if ('requestIdleCallback' in window) {\n requestIdleCallback(() => {\n this.injectPrefetchLink(target);\n });\n } else {\n // Fallback for browsers without requestIdleCallback\n setTimeout(() => {\n this.injectPrefetchLink(target);\n }, 1000);\n }\n }\n\n /**\n * Resolve chunk path for the current environment\n * In production: chunks are built with hashes (e.g., chunks/Privacy-D5qJZu-O.js or js/index-CJMMxcQV.js)\n * In dev mode: need to resolve to the actual module or use a proxy\n */\n private resolveChunkPath(chunkPath: string, route: string): string {\n const isDev = window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1';\n\n if (!isDev) {\n // Production: use the chunk path as-is (it has real hashes from the build)\n return `/${chunkPath}`;\n }\n\n // Dev mode: Try to map chunk to component and use source files\n // Extract component name from chunk path\n // Examples:\n // - chunks/Privacy-D5qJZu-O.js → Privacy\n // - js/index-CJMMxcQV.js → index\n // - chunks/chunk-user-profile-JNr_q4Gn.js → (can't map, use original)\n\n // Try to extract component name from various chunk name patterns\n let componentName: string | null = null;\n\n // Pattern 1: Individual component chunks (e.g., Privacy-D5qJZu-O.js)\n const match1 = chunkPath.match(/\\/([A-Z][a-zA-Z]*)-[a-zA-Z0-9_-]+\\.js$/);\n if (match1) {\n componentName = match1[1];\n }\n\n // Pattern 2: Main/index chunks (e.g., js/index-CJMMxcQV.js)\n const match2 = chunkPath.match(/\\/(index)-[a-zA-Z0-9_-]+\\.js$/);\n if (match2) {\n componentName = match2[1];\n }\n\n if (componentName) {\n // Map component name to source file\n // This works because Vite's dev server resolves source files dynamically\n const sourceFile = componentName === 'index' ? '/src/main.tsx' : `/src/pages/${componentName}.tsx`;\n if (this.debug) {\n console.log(` šŸ“ Dev mode: Resolved ${chunkPath} → ${sourceFile}`);\n }\n return sourceFile;\n }\n\n // Fallback: use original chunk path with leading slash\n if (this.debug) {\n console.log(` āš ļø Dev mode: Could not extract component name from ${chunkPath}, using as-is`);\n }\n return `/${chunkPath}`;\n }\n\n /**\n * Inject prefetch link into DOM\n */\n private injectPrefetchLink(target: PrefetchTarget & { chunk: string }): void {\n if (this.prefetched.has(target.route)) {\n if (this.debug) {\n console.log(` ā­ļø Already prefetched: ${target.route}`);\n }\n return;\n }\n\n // Resolve the actual chunk path for the current environment\n // In production: use the chunk hash from config (e.g., chunks/Privacy-D5qJZu-O.js)\n // In dev mode: chunks don't exist as files, Vite handles them at request time\n const chunkPath = this.resolveChunkPath(target.chunk, target.route);\n\n // Create main chunk link\n const link = document.createElement('link');\n // Use modulepreload for better ES module support (triggers actual fetch)\n link.rel = 'modulepreload';\n link.href = chunkPath;\n link.setAttribute('data-prefetch-route', target.route);\n link.setAttribute('data-prefetch-priority', target.priority);\n link.setAttribute('data-prefetch-probability', target.probability.toString());\n\n // Always log prefetch with details\n console.groupCollapsed(`šŸ”— PREFETCH: ${target.route}`);\n console.log(` šŸ“„ Page/Route: ${target.route}`);\n console.log(` šŸ“¦ Main Chunk: ${target.chunk}`);\n console.log(` 🌐 Resolved URL: ${window.location.origin}${chunkPath}`);\n console.log(` ⭐ Priority: ${target.priority}`);\n console.log(` šŸ“Š Probability: ${(target.probability * 100).toFixed(1)}%`);\n\n // Track total chunks being fetched\n let totalChunksForThisRoute = 1; // Main chunk\n const injectedLinks: string[] = [];\n\n // Try to append the main link - CRITICAL: this must happen first\n try {\n document.head.appendChild(link);\n injectedLinks.push(target.chunk);\n console.log(` āœ… Main chunk link injected: ${target.chunk}`);\n } catch (e) {\n console.error(` āŒ Failed to inject main chunk link:`, e);\n console.groupEnd();\n return;\n }\n\n // Also prefetch all dependency chunks (imports)\n if (target.imports && target.imports.length > 0) {\n console.log(` šŸ“š Dependencies (${target.imports.length}):`);\n target.imports.forEach((importChunk, index) => {\n // Skip if already prefetched by another route\n const importId = `import:${importChunk}`;\n if (this.prefetched.has(importId)) {\n console.log(` ${index + 1}. ${importChunk} (already prefetched)`);\n return;\n }\n\n try {\n const importLink = document.createElement('link');\n importLink.rel = 'modulepreload';\n importLink.href = `/${importChunk}`;\n importLink.setAttribute('data-prefetch-import', 'true');\n importLink.setAttribute('data-prefetch-parent', target.route);\n document.head.appendChild(importLink);\n this.prefetched.add(importId);\n totalChunksForThisRoute++;\n injectedLinks.push(importChunk);\n\n console.log(` ${index + 1}. ${importChunk} āœ…`);\n } catch (e) {\n console.error(` ${index + 1}. ${importChunk} āŒ Error:`, e);\n }\n });\n }\n\n // Mark as prefetched\n this.prefetched.add(target.route);\n\n console.log(` āœ… Total chunks injected: ${totalChunksForThisRoute}`);\n console.log(` šŸ“ˆ Overall prefetched count: ${this.prefetched.size}`);\n\n if (this.debug) {\n console.log(` DOM Status: ${injectedLinks.length} link tag(s) added to document.head`);\n console.log(` Injected URLs:`, injectedLinks.map(c => `/${c}`));\n\n // Verify the link was actually added and check if it loaded\n setTimeout(() => {\n const addedLink = document.querySelector(`link[data-prefetch-route=\"${target.route}\"]`);\n if (addedLink) {\n console.log(` āœ”ļø DOM Verification: Link exists`);\n console.log(` href:`, (addedLink as HTMLLinkElement).href);\n console.log(` as:`, (addedLink as HTMLLinkElement).getAttribute('as'));\n console.log(` rel:`, (addedLink as HTMLLinkElement).rel);\n\n // Check if link actually triggered a fetch\n if ((addedLink as any).relList?.contains('modulepreload')) {\n console.log(` šŸ”„ Link has modulepreload rel (will fetch)`);\n }\n } else {\n console.error(` āŒ ERROR: Link tag not found in DOM after 100ms`);\n }\n\n // Verify ALL injected links exist\n console.log(` šŸ“‹ Verifying all injected links in head:`);\n document.querySelectorAll('link[data-prefetch-route], link[data-prefetch-import]').forEach((el, idx) => {\n const isMain = el.hasAttribute('data-prefetch-route');\n const parent = isMain ? el.getAttribute('data-prefetch-route') : el.getAttribute('data-prefetch-parent');\n console.log(` ${idx + 1}. ${(el as HTMLLinkElement).href} (parent: ${parent})`);\n });\n }, 50);\n }\n\n console.groupEnd();\n }\n\n /**\n * Check if prefetching should be performed based on network conditions\n */\n private shouldPrefetch(): boolean {\n // Check if Network Information API is available\n const nav = navigator as any;\n const connection = nav.connection || nav.mozConnection || nav.webkitConnection;\n\n if (!connection) {\n // API not available, assume prefetch is OK\n return true;\n }\n\n // Respect Data Saver mode\n if (connection.saveData) {\n if (this.debug) console.log(' āš ļø Data Saver enabled');\n return false;\n }\n\n // Check connection speed\n const slowConnections = ['slow-2g', '2g'];\n if (slowConnections.includes(connection.effectiveType)) {\n if (this.debug) console.log(` āš ļø Slow connection: ${connection.effectiveType}`);\n return false;\n }\n\n // Check if metered connection (conservative approach)\n if (connection.type === 'cellular' && connection.effectiveType !== '4g') {\n if (this.debug) console.log(' āš ļø Metered connection');\n return false;\n }\n\n return true;\n }\n\n /**\n * Initialize IntersectionObserver for 'visible' strategy\n */\n private initIntersectionObserver(): void {\n this.observer = new IntersectionObserver(\n (entries) => {\n entries.forEach((entry) => {\n if (entry.isIntersecting) {\n const route = entry.target.getAttribute('data-prefetch-route');\n if (route && this.config) {\n // Find the target in config\n Object.values(this.config.routes).forEach((routeConfig) => {\n const target = routeConfig.prefetch.find((t) => t.route === route);\n if (target) {\n this.injectPrefetchLink(target);\n }\n });\n }\n }\n });\n },\n {\n rootMargin: '50px', // Start prefetch 50px before element is visible\n }\n );\n }\n\n /**\n * Observe an element for visibility-based prefetching\n */\n observeLink(element: HTMLElement, route: string): void {\n if (this.observer) {\n element.setAttribute('data-prefetch-route', route);\n this.observer.observe(element);\n }\n }\n\n /**\n * Manually trigger prefetch for a specific route\n * Useful for hover events\n */\n prefetchRoute(route: string): void {\n if (!this.config) return;\n\n // Find this route in all route configs\n Object.values(this.config.routes).forEach((routeConfig) => {\n const target = routeConfig.prefetch.find((t) => t.route === route);\n if (target) {\n this.injectPrefetchLink(target);\n }\n });\n }\n\n /**\n * Get prefetch statistics\n */\n getStats(): {\n totalPrefetched: number;\n prefetchedRoutes: string[];\n configLoaded: boolean;\n strategy: PrefetchStrategy;\n } {\n return {\n totalPrefetched: this.prefetched.size,\n prefetchedRoutes: Array.from(this.prefetched),\n configLoaded: this.config !== null,\n strategy: this.strategy,\n };\n }\n\n /**\n * Check if a route has been prefetched\n */\n isPrefetched(route: string): boolean {\n return this.prefetched.has(route);\n }\n\n /**\n * Clear all prefetch state\n */\n clear(): void {\n this.prefetched.clear();\n if (this.observer) {\n this.observer.disconnect();\n }\n }\n\n /**\n * Get all prefetch link elements currently in the DOM\n */\n getActivePrefetchLinks(): HTMLLinkElement[] {\n return Array.from(document.querySelectorAll('link[rel=\"modulepreload\"][data-prefetch-route]'));\n }\n\n /**\n * Log current state for debugging\n */\n logDebugInfo(): void {\n console.group('šŸ› Smart Prefetch Debug Info');\n console.log('Strategy:', this.strategy);\n console.log('Config loaded:', this.config !== null);\n console.log('Total prefetch entries:', this.prefetched.size);\n console.log('Prefetched items:', Array.from(this.prefetched));\n\n const links = this.getActivePrefetchLinks();\n console.log('\\nšŸ”— Active Link Tags in DOM:', links.length);\n\n if (links.length > 0) {\n console.table(links.map(link => ({\n route: link.getAttribute('data-prefetch-route'),\n chunk: link.href.replace(window.location.origin + '/', ''),\n priority: link.getAttribute('data-prefetch-priority'),\n probability: link.getAttribute('data-prefetch-probability'),\n })));\n }\n\n if (this.config) {\n console.log('\\nšŸ“Š Configuration Summary:');\n console.log('Available routes in config:', Object.keys(this.config.routes).length);\n console.log('Config environment:', this.config.environment);\n\n console.group('šŸ“‹ All configured routes with prefetch targets:');\n Object.entries(this.config.routes).forEach(([route, data]: [string, any]) => {\n console.group(`${route}`);\n data.prefetch.forEach((t: any, idx: number) => {\n console.log(` ${idx + 1}. ${t.route} (${t.priority}, ${(t.probability * 100).toFixed(1)}%) → ${t.chunk}`);\n });\n console.groupEnd();\n });\n console.groupEnd();\n\n console.log('\\nšŸ’” Current location:', window.location.pathname);\n console.log('šŸ’” Clean route:', window.location.pathname.split('?')[0].split('#')[0]);\n }\n\n console.groupEnd();\n }\n\n /**\n * Log all prefetched pages and chunks (summary view)\n */\n logPrefetchSummary(): void {\n const links = this.getActivePrefetchLinks();\n const routeLinks = links.filter(l => !l.getAttribute('data-prefetch-import'));\n const dependencyLinks = links.filter(l => l.getAttribute('data-prefetch-import'));\n\n console.group('šŸ“Š PREFETCH SUMMARY');\n console.log(`Total pages prefetched: ${routeLinks.length}`);\n console.log(`Total dependency chunks: ${dependencyLinks.length}`);\n console.log(`Total overall entries: ${this.prefetched.size}`);\n\n if (routeLinks.length > 0) {\n console.group('šŸ“„ Pages/Routes Prefetched:');\n const pageTable = routeLinks.map(link => ({\n route: link.getAttribute('data-prefetch-route'),\n chunk: link.href.replace(window.location.origin + '/', ''),\n priority: link.getAttribute('data-prefetch-priority'),\n probability: `${link.getAttribute('data-prefetch-probability')}`,\n }));\n console.table(pageTable);\n console.groupEnd();\n }\n\n if (dependencyLinks.length > 0) {\n console.group('šŸ“¦ Dependency Chunks Prefetched:');\n const depsTable = dependencyLinks.map(link => ({\n parentRoute: link.getAttribute('data-prefetch-parent'),\n chunk: link.href.replace(window.location.origin + '/', ''),\n }));\n console.table(depsTable);\n console.groupEnd();\n }\n\n console.groupEnd();\n }\n}\n","/**\n * Debug Utilities for Smart Prefetch Plugin\n * Helper functions to inspect and debug prefetch behavior\n */\n\n/**\n * Get all prefetch link elements from the DOM\n */\nexport function getPrefetchLinks(): HTMLLinkElement[] {\n return Array.from(document.querySelectorAll('link[rel=\"prefetch\"]'));\n}\n\n/**\n * Get prefetch links added by our plugin (with data attributes)\n */\nexport function getPluginPrefetchLinks(): HTMLLinkElement[] {\n return Array.from(document.querySelectorAll('link[rel=\"prefetch\"][data-prefetch-route]'));\n}\n\n/**\n * Log all prefetch links in a formatted way\n */\nexport function logPrefetchLinks(): void {\n const allLinks = getPrefetchLinks();\n const pluginLinks = getPluginPrefetchLinks();\n\n console.group('šŸ”— Prefetch Link Tags in DOM');\n console.log(`Total prefetch links: ${allLinks.length}`);\n console.log(`Plugin-managed links: ${pluginLinks.length}`);\n\n if (pluginLinks.length > 0) {\n console.group('Plugin-managed links:');\n console.table(\n pluginLinks.map((link) => ({\n route: link.getAttribute('data-prefetch-route'),\n href: link.href,\n priority: link.getAttribute('data-prefetch-priority'),\n probability: link.getAttribute('data-prefetch-probability'),\n loaded: link.hasAttribute('data-loaded'),\n }))\n );\n console.groupEnd();\n }\n\n const otherLinks = allLinks.filter((link) => !link.hasAttribute('data-prefetch-route'));\n if (otherLinks.length > 0) {\n console.group('Other prefetch links:');\n console.table(\n otherLinks.map((link) => ({\n href: link.href,\n as: link.getAttribute('as'),\n }))\n );\n console.groupEnd();\n }\n\n console.groupEnd();\n}\n\n/**\n * Monitor prefetch activity in real-time\n */\nexport function monitorPrefetchActivity(): () => void {\n console.log('šŸ” Monitoring prefetch activity...');\n console.log('Press the returned stop function to stop monitoring');\n\n const observer = new MutationObserver((mutations) => {\n mutations.forEach((mutation) => {\n mutation.addedNodes.forEach((node) => {\n if (node.nodeName === 'LINK') {\n const link = node as HTMLLinkElement;\n if (link.rel === 'prefetch') {\n console.log('āž• New prefetch link added:', {\n route: link.getAttribute('data-prefetch-route') || 'N/A',\n href: link.href,\n priority: link.getAttribute('data-prefetch-priority'),\n });\n }\n }\n });\n\n mutation.removedNodes.forEach((node) => {\n if (node.nodeName === 'LINK') {\n const link = node as HTMLLinkElement;\n if (link.rel === 'prefetch') {\n console.log('āž– Prefetch link removed:', {\n route: link.getAttribute('data-prefetch-route') || 'N/A',\n href: link.href,\n });\n }\n }\n });\n });\n });\n\n observer.observe(document.head, {\n childList: true,\n subtree: true,\n });\n\n return () => {\n console.log('šŸ›‘ Stopped monitoring prefetch activity');\n observer.disconnect();\n };\n}\n\n/**\n * Check if the smart prefetch plugin is properly configured\n */\nexport function checkPluginConfiguration(): void {\n console.group('šŸ”§ Smart Prefetch Plugin Configuration Check');\n\n // Check global config\n const globalConfig = (window as any).__SMART_PREFETCH__;\n if (globalConfig) {\n console.log('āœ… Global config found:', globalConfig);\n } else {\n console.warn('āŒ Global config not found on window.__SMART_PREFETCH__');\n console.log(' The plugin may not be properly configured in vite.config');\n }\n\n // Check if config file is accessible\n fetch('/prefetch-config.json')\n .then((res) => {\n if (res.ok) {\n console.log('āœ… prefetch-config.json is accessible');\n return res.json();\n } else {\n throw new Error(`HTTP ${res.status}: ${res.statusText}`);\n }\n })\n .then((config) => {\n console.log('šŸ“‹ Config content:', config);\n console.log(` Routes: ${Object.keys(config.routes).length}`);\n console.log(` Environment: ${config.environment}`);\n })\n .catch((error) => {\n console.error('āŒ Cannot access prefetch-config.json:', error.message);\n console.log(' Make sure to build the app first: pnpm build');\n })\n .finally(() => {\n console.groupEnd();\n });\n\n // Check debug function\n if (typeof (window as any).__PREFETCH_DEBUG__ === 'function') {\n console.log('āœ… Debug function available: window.__PREFETCH_DEBUG__()');\n } else {\n console.warn('āš ļø Debug function not available (may not be initialized yet)');\n }\n}\n\n/**\n * Expose all debug utilities globally for console access\n */\nexport function exposeDebugUtils(): void {\n const w = window as any;\n w.__PREFETCH_UTILS__ = {\n getPrefetchLinks,\n getPluginPrefetchLinks,\n logPrefetchLinks,\n monitorPrefetchActivity,\n checkPluginConfiguration,\n };\n\n console.log('šŸ’” Debug utilities exposed:');\n console.log(' window.__PREFETCH_UTILS__.getPrefetchLinks()');\n console.log(' window.__PREFETCH_UTILS__.logPrefetchLinks()');\n console.log(' window.__PREFETCH_UTILS__.monitorPrefetchActivity()');\n console.log(' window.__PREFETCH_UTILS__.checkPluginConfiguration()');\n}\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "vite-plugin-smart-prefetch",
3
- "version": "0.1.0",
4
- "description": "Smart prefetch plugin for Vite applications using BigQuery GA4 analytics",
3
+ "version": "0.3.1",
4
+ "description": "Smart prefetch plugin for Vite with BigQuery GA4 analytics. Supports React Router DOM and TanStack Router with intelligent dynamic route matching.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
7
7
  "module": "./dist/index.js",
@@ -46,6 +46,7 @@
46
46
  "peerDependencies": {
47
47
  "react": "^18.0.0",
48
48
  "react-router-dom": "^6.0.0",
49
+ "@tanstack/react-router": "^1.0.0",
49
50
  "vite": "^5.0.0"
50
51
  },
51
52
  "peerDependenciesMeta": {
@@ -54,6 +55,9 @@
54
55
  },
55
56
  "react-router-dom": {
56
57
  "optional": true
58
+ },
59
+ "@tanstack/react-router": {
60
+ "optional": true
57
61
  }
58
62
  },
59
63
  "devDependencies": {