vite-plugin-smart-prefetch 0.1.0 → 0.3.0
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.
- package/dist/index.cjs +76 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +8 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +76 -2
- package/dist/index.js.map +1 -1
- package/dist/react/index.cjs +58 -11
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +55 -1
- package/dist/react/index.d.ts +55 -1
- package/dist/react/index.js +50 -6
- package/dist/react/index.js.map +1 -1
- package/dist/runtime/index.d.cts +6 -0
- package/dist/runtime/index.d.ts +6 -0
- package/package.json +6 -2
package/dist/react/index.cjs
CHANGED
|
@@ -33,7 +33,10 @@ __export(index_exports, {
|
|
|
33
33
|
PrefetchDebugPanel: () => PrefetchDebugPanel,
|
|
34
34
|
PrefetchLink: () => PrefetchLink,
|
|
35
35
|
getPrefetchManager: () => getPrefetchManager,
|
|
36
|
-
|
|
36
|
+
getPrefetchManagerTanStack: () => getPrefetchManagerTanStack,
|
|
37
|
+
matchPrefetchPattern: () => matchPrefetchPattern,
|
|
38
|
+
usePrefetch: () => usePrefetch,
|
|
39
|
+
usePrefetchTanStack: () => usePrefetchTanStack
|
|
37
40
|
});
|
|
38
41
|
module.exports = __toCommonJS(index_exports);
|
|
39
42
|
|
|
@@ -582,16 +585,57 @@ function getPrefetchManager() {
|
|
|
582
585
|
return managerInstance;
|
|
583
586
|
}
|
|
584
587
|
|
|
588
|
+
// src/frameworks/react/usePrefetchTanStack.ts
|
|
589
|
+
var import_react2 = require("react");
|
|
590
|
+
var import_react_router = require("@tanstack/react-router");
|
|
591
|
+
var managerInstance2 = null;
|
|
592
|
+
function usePrefetchTanStack() {
|
|
593
|
+
const location = (0, import_react_router.useLocation)();
|
|
594
|
+
const initialized = (0, import_react2.useRef)(false);
|
|
595
|
+
(0, import_react2.useEffect)(() => {
|
|
596
|
+
if (!initialized.current) {
|
|
597
|
+
const config = window.__SMART_PREFETCH__ || {};
|
|
598
|
+
const strategy = config.strategy || "hybrid";
|
|
599
|
+
const debug = config.debug || false;
|
|
600
|
+
managerInstance2 = new PrefetchManager(strategy, debug);
|
|
601
|
+
managerInstance2.init();
|
|
602
|
+
window.__FARMART_PREFETCH_MANAGER__ = managerInstance2;
|
|
603
|
+
initialized.current = true;
|
|
604
|
+
if (debug) {
|
|
605
|
+
console.log("\u2705 usePrefetchTanStack initialized");
|
|
606
|
+
console.log("\u2705 Prefetch manager exposed as window.__FARMART_PREFETCH_MANAGER__");
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
}, []);
|
|
610
|
+
(0, import_react2.useEffect)(() => {
|
|
611
|
+
if (managerInstance2) {
|
|
612
|
+
const pathname = location.pathname.split("?")[0].split("#")[0];
|
|
613
|
+
managerInstance2.prefetch(pathname);
|
|
614
|
+
}
|
|
615
|
+
}, [location.pathname]);
|
|
616
|
+
return managerInstance2;
|
|
617
|
+
}
|
|
618
|
+
function getPrefetchManagerTanStack() {
|
|
619
|
+
return managerInstance2;
|
|
620
|
+
}
|
|
621
|
+
function matchPrefetchPattern(pathname, pattern) {
|
|
622
|
+
const patternRegex = new RegExp(
|
|
623
|
+
"^" + pattern.replace(/:[^/]+/g, "[^/]+").replace(/\$[^/]+/g, "[^/]+").replace(/\*/g, ".*") + // Match wildcard
|
|
624
|
+
"$"
|
|
625
|
+
);
|
|
626
|
+
return patternRegex.test(pathname);
|
|
627
|
+
}
|
|
628
|
+
|
|
585
629
|
// src/frameworks/react/PrefetchLink.tsx
|
|
586
|
-
var
|
|
630
|
+
var import_react3 = __toESM(require("react"), 1);
|
|
587
631
|
var import_react_router_dom2 = require("react-router-dom");
|
|
588
632
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
589
|
-
var PrefetchLink =
|
|
633
|
+
var PrefetchLink = import_react3.default.forwardRef(
|
|
590
634
|
({ prefetch, to, children, onMouseEnter, ...props }, forwardedRef) => {
|
|
591
|
-
const linkRef = (0,
|
|
635
|
+
const linkRef = (0, import_react3.useRef)(null);
|
|
592
636
|
const manager = getPrefetchManager();
|
|
593
637
|
const route = typeof to === "string" ? to : to.pathname || "";
|
|
594
|
-
(0,
|
|
638
|
+
(0, import_react3.useEffect)(() => {
|
|
595
639
|
if (prefetch === "visible" && linkRef.current && manager) {
|
|
596
640
|
manager.observeLink(linkRef.current, route);
|
|
597
641
|
}
|
|
@@ -628,17 +672,17 @@ var PrefetchLink = import_react2.default.forwardRef(
|
|
|
628
672
|
PrefetchLink.displayName = "PrefetchLink";
|
|
629
673
|
|
|
630
674
|
// src/frameworks/react/PrefetchDebugPanel.tsx
|
|
631
|
-
var
|
|
675
|
+
var import_react4 = require("react");
|
|
632
676
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
633
677
|
function PrefetchDebugPanel({
|
|
634
678
|
manager,
|
|
635
679
|
position = "bottom-right",
|
|
636
680
|
defaultOpen = false
|
|
637
681
|
}) {
|
|
638
|
-
const [isOpen, setIsOpen] = (0,
|
|
639
|
-
const [stats, setStats] = (0,
|
|
640
|
-
const [links, setLinks] = (0,
|
|
641
|
-
(0,
|
|
682
|
+
const [isOpen, setIsOpen] = (0, import_react4.useState)(defaultOpen);
|
|
683
|
+
const [stats, setStats] = (0, import_react4.useState)(null);
|
|
684
|
+
const [links, setLinks] = (0, import_react4.useState)([]);
|
|
685
|
+
(0, import_react4.useEffect)(() => {
|
|
642
686
|
if (!manager) return;
|
|
643
687
|
const updateStats = () => {
|
|
644
688
|
setStats(manager.getStats());
|
|
@@ -793,6 +837,9 @@ function PrefetchDebugPanel({
|
|
|
793
837
|
PrefetchDebugPanel,
|
|
794
838
|
PrefetchLink,
|
|
795
839
|
getPrefetchManager,
|
|
796
|
-
|
|
840
|
+
getPrefetchManagerTanStack,
|
|
841
|
+
matchPrefetchPattern,
|
|
842
|
+
usePrefetch,
|
|
843
|
+
usePrefetchTanStack
|
|
797
844
|
});
|
|
798
845
|
//# sourceMappingURL=index.cjs.map
|
package/dist/react/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/frameworks/react/index.ts","../../src/frameworks/react/usePrefetch.ts","../../src/runtime/prefetch-manager.ts","../../src/frameworks/react/PrefetchLink.tsx","../../src/frameworks/react/PrefetchDebugPanel.tsx"],"sourcesContent":["/**\n * React Framework Integration\n * Exports all React-specific components and hooks\n */\n\nexport { usePrefetch, getPrefetchManager } from './usePrefetch';\nexport { PrefetchLink } from './PrefetchLink';\nexport type { PrefetchLinkProps } from './PrefetchLink';\nexport { PrefetchDebugPanel } from './PrefetchDebugPanel';\nexport type { PrefetchDebugPanelProps } from './PrefetchDebugPanel';\n","/**\n * React Hook for Smart Prefetch\n * Automatically prefetches routes based on navigation\n */\n\nimport { useEffect, useRef } from 'react';\nimport { useLocation } from 'react-router-dom';\nimport { PrefetchManager } from '../../runtime/prefetch-manager';\nimport type { PrefetchStrategy } from '../../types';\n\n// Singleton instance\nlet managerInstance: PrefetchManager | null = null;\n\n/**\n * React hook to enable smart prefetching\n * Call this once in your root App component\n *\n * @example\n * ```tsx\n * function App() {\n * usePrefetch();\n * return <Routes>...</Routes>;\n * }\n * ```\n */\nexport function usePrefetch(): PrefetchManager | null {\n const location = useLocation();\n const initialized = useRef(false);\n\n // Initialize manager once\n useEffect(() => {\n if (!initialized.current) {\n // Read config from window (injected by plugin)\n const config = (window as any).__SMART_PREFETCH__ || {};\n const strategy: PrefetchStrategy = config.strategy || 'hybrid';\n const debug: boolean = config.debug || false;\n\n managerInstance = new PrefetchManager(strategy, debug);\n managerInstance.init();\n\n // Expose manager globally for debugging and external use\n (window as any).__FARMART_PREFETCH_MANAGER__ = managerInstance;\n\n initialized.current = true;\n\n if (debug) {\n console.log('✅ usePrefetch initialized');\n console.log('✅ Prefetch manager exposed as window.__FARMART_PREFETCH_MANAGER__');\n }\n }\n }, []);\n\n // Prefetch on route change\n useEffect(() => {\n if (managerInstance) {\n managerInstance.prefetch(location.pathname);\n }\n }, [location.pathname]);\n\n return managerInstance;\n}\n\n/**\n * Get the prefetch manager instance\n * Useful for manual prefetch control\n */\nexport function getPrefetchManager(): PrefetchManager | null {\n return managerInstance;\n}\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 * Enhanced Link Component with Prefetch Support\n * Extends React Router Link with smart prefetching\n */\n\nimport React, { useRef, useEffect } from 'react';\nimport { Link, type LinkProps } from 'react-router-dom';\nimport { getPrefetchManager } from './usePrefetch';\n\nexport interface PrefetchLinkProps extends Omit<LinkProps, 'prefetch'> {\n /**\n * Prefetch behavior\n * - 'hover': Prefetch on mouse enter\n * - 'visible': Prefetch when link becomes visible\n * - 'manual': No automatic prefetch (use onClick)\n * - undefined: Use default strategy from config\n */\n prefetch?: 'hover' | 'visible' | 'manual';\n}\n\n/**\n * Enhanced Link component with prefetching\n *\n * @example\n * ```tsx\n * // Prefetch on hover\n * <PrefetchLink to=\"/orders\" prefetch=\"hover\">\n * View Orders\n * </PrefetchLink>\n *\n * // Prefetch when visible\n * <PrefetchLink to=\"/dispatch-order\" prefetch=\"visible\">\n * Create Dispatch\n * </PrefetchLink>\n * ```\n */\nexport const PrefetchLink = React.forwardRef<HTMLAnchorElement, PrefetchLinkProps>(\n ({ prefetch, to, children, onMouseEnter, ...props }, forwardedRef) => {\n const linkRef = useRef<HTMLAnchorElement>(null);\n const manager = getPrefetchManager();\n\n const route = typeof to === 'string' ? to : to.pathname || '';\n\n // Handle visibility-based prefetch\n useEffect(() => {\n if (prefetch === 'visible' && linkRef.current && manager) {\n manager.observeLink(linkRef.current, route);\n }\n }, [prefetch, route, manager]);\n\n // Handle hover-based prefetch\n const handleMouseEnter = (e: React.MouseEvent<HTMLAnchorElement>) => {\n if (prefetch === 'hover' && manager) {\n manager.prefetchRoute(route);\n }\n\n // Call original onMouseEnter if provided\n if (onMouseEnter) {\n onMouseEnter(e);\n }\n };\n\n return (\n <Link\n ref={(node) => {\n // Handle both forwarded ref and internal ref\n if (node) {\n (linkRef as React.MutableRefObject<HTMLAnchorElement>).current = node;\n if (typeof forwardedRef === 'function') {\n forwardedRef(node);\n } else if (forwardedRef) {\n forwardedRef.current = node;\n }\n }\n }}\n to={to}\n onMouseEnter={handleMouseEnter}\n {...props}\n >\n {children}\n </Link>\n );\n }\n);\n\nPrefetchLink.displayName = 'PrefetchLink';\n","/**\n * Debug Panel Component for Smart Prefetch Plugin\n * Shows real-time prefetch status and link tags\n */\n\nimport { useEffect, useState } from 'react';\nimport type { PrefetchManager } from '../../runtime/prefetch-manager';\n\nexport interface PrefetchDebugPanelProps {\n manager: PrefetchManager | null;\n position?: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';\n defaultOpen?: boolean;\n}\n\ninterface LinkInfo {\n route: string;\n href: string;\n priority: string;\n probability: string;\n}\n\nexport function PrefetchDebugPanel({\n manager,\n position = 'bottom-right',\n defaultOpen = false,\n}: PrefetchDebugPanelProps) {\n const [isOpen, setIsOpen] = useState(defaultOpen);\n const [stats, setStats] = useState<ReturnType<PrefetchManager['getStats']> | null>(null);\n const [links, setLinks] = useState<LinkInfo[]>([]);\n\n useEffect(() => {\n if (!manager) return;\n\n const updateStats = () => {\n setStats(manager.getStats());\n const linkElements = manager.getActivePrefetchLinks();\n setLinks(\n linkElements.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 }))\n );\n };\n\n // Update stats immediately\n updateStats();\n\n // Update stats every second\n const interval = setInterval(updateStats, 1000);\n\n return () => clearInterval(interval);\n }, [manager]);\n\n if (!manager) {\n return null;\n }\n\n const positionStyles: Record<string, React.CSSProperties> = {\n 'top-left': { top: 10, left: 10 },\n 'top-right': { top: 10, right: 10 },\n 'bottom-left': { bottom: 10, left: 10 },\n 'bottom-right': { bottom: 10, right: 10 },\n };\n\n const containerStyle: React.CSSProperties = {\n position: 'fixed',\n ...positionStyles[position],\n zIndex: 99999,\n fontFamily: 'system-ui, -apple-system, sans-serif',\n fontSize: '12px',\n };\n\n const buttonStyle: React.CSSProperties = {\n background: '#4CAF50',\n color: 'white',\n border: 'none',\n borderRadius: '50%',\n width: '48px',\n height: '48px',\n cursor: 'pointer',\n boxShadow: '0 4px 8px rgba(0,0,0,0.2)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontSize: '20px',\n };\n\n const panelStyle: React.CSSProperties = {\n background: 'white',\n border: '1px solid #ddd',\n borderRadius: '8px',\n boxShadow: '0 4px 12px rgba(0,0,0,0.15)',\n padding: '12px',\n minWidth: '320px',\n maxWidth: '400px',\n maxHeight: '500px',\n overflow: 'auto',\n marginBottom: '8px',\n };\n\n const headerStyle: React.CSSProperties = {\n fontWeight: 'bold',\n marginBottom: '8px',\n color: '#333',\n borderBottom: '2px solid #4CAF50',\n paddingBottom: '4px',\n };\n\n const statStyle: React.CSSProperties = {\n display: 'flex',\n justifyContent: 'space-between',\n padding: '4px 0',\n borderBottom: '1px solid #eee',\n };\n\n const linkStyle: React.CSSProperties = {\n background: '#f5f5f5',\n padding: '8px',\n borderRadius: '4px',\n marginBottom: '8px',\n fontSize: '11px',\n };\n\n return (\n <div style={containerStyle}>\n {isOpen && stats && (\n <div style={panelStyle}>\n <div style={headerStyle}>🚀 Smart Prefetch Debug</div>\n\n <div style={{ marginBottom: '12px' }}>\n <div style={statStyle}>\n <span>Strategy:</span>\n <strong>{stats.strategy}</strong>\n </div>\n <div style={statStyle}>\n <span>Config Loaded:</span>\n <strong>{stats.configLoaded ? '✅' : '❌'}</strong>\n </div>\n <div style={statStyle}>\n <span>Total Prefetched:</span>\n <strong>{stats.totalPrefetched}</strong>\n </div>\n <div style={statStyle}>\n <span>Link Tags in DOM:</span>\n <strong>{links.length}</strong>\n </div>\n </div>\n\n {stats.prefetchedRoutes.length > 0 && (\n <div>\n <div style={{ ...headerStyle, fontSize: '11px' }}>Prefetched Routes:</div>\n <div style={{ fontSize: '11px', color: '#666', marginBottom: '8px' }}>\n {stats.prefetchedRoutes.join(', ')}\n </div>\n </div>\n )}\n\n {links.length > 0 && (\n <div>\n <div style={{ ...headerStyle, fontSize: '11px' }}>Active Link Tags:</div>\n {links.map((link, i) => (\n <div key={i} style={linkStyle}>\n <div>\n <strong>{link.route}</strong>\n </div>\n <div style={{ color: '#666', marginTop: '4px' }}>\n Priority: {link.priority} | Prob: {(parseFloat(link.probability) * 100).toFixed(1)}%\n </div>\n <div style={{ color: '#999', marginTop: '2px', wordBreak: 'break-all' }}>\n {link.href.split('/').pop()}\n </div>\n </div>\n ))}\n </div>\n )}\n\n <button\n onClick={() => {\n manager.logDebugInfo();\n }}\n style={{\n width: '100%',\n padding: '8px',\n background: '#2196F3',\n color: 'white',\n border: 'none',\n borderRadius: '4px',\n cursor: 'pointer',\n marginTop: '8px',\n }}\n >\n Log Debug Info to Console\n </button>\n </div>\n )}\n\n <button\n style={buttonStyle}\n onClick={() => setIsOpen(!isOpen)}\n title=\"Smart Prefetch Debug Panel\"\n >\n 🔗\n </button>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACKA,mBAAkC;AAClC,8BAA4B;;;ACCrB,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;;;ADxoBA,IAAI,kBAA0C;AAcvC,SAAS,cAAsC;AACpD,QAAM,eAAW,qCAAY;AAC7B,QAAM,kBAAc,qBAAO,KAAK;AAGhC,8BAAU,MAAM;AACd,QAAI,CAAC,YAAY,SAAS;AAExB,YAAM,SAAU,OAAe,sBAAsB,CAAC;AACtD,YAAM,WAA6B,OAAO,YAAY;AACtD,YAAM,QAAiB,OAAO,SAAS;AAEvC,wBAAkB,IAAI,gBAAgB,UAAU,KAAK;AACrD,sBAAgB,KAAK;AAGrB,MAAC,OAAe,+BAA+B;AAE/C,kBAAY,UAAU;AAEtB,UAAI,OAAO;AACT,gBAAQ,IAAI,gCAA2B;AACvC,gBAAQ,IAAI,wEAAmE;AAAA,MACjF;AAAA,IACF;AAAA,EACF,GAAG,CAAC,CAAC;AAGL,8BAAU,MAAM;AACd,QAAI,iBAAiB;AACnB,sBAAgB,SAAS,SAAS,QAAQ;AAAA,IAC5C;AAAA,EACF,GAAG,CAAC,SAAS,QAAQ,CAAC;AAEtB,SAAO;AACT;AAMO,SAAS,qBAA6C;AAC3D,SAAO;AACT;;;AE/DA,IAAAA,gBAAyC;AACzC,IAAAC,2BAAqC;AAyD/B;AA3BC,IAAM,eAAe,cAAAC,QAAM;AAAA,EAChC,CAAC,EAAE,UAAU,IAAI,UAAU,cAAc,GAAG,MAAM,GAAG,iBAAiB;AACpE,UAAM,cAAU,sBAA0B,IAAI;AAC9C,UAAM,UAAU,mBAAmB;AAEnC,UAAM,QAAQ,OAAO,OAAO,WAAW,KAAK,GAAG,YAAY;AAG3D,iCAAU,MAAM;AACd,UAAI,aAAa,aAAa,QAAQ,WAAW,SAAS;AACxD,gBAAQ,YAAY,QAAQ,SAAS,KAAK;AAAA,MAC5C;AAAA,IACF,GAAG,CAAC,UAAU,OAAO,OAAO,CAAC;AAG7B,UAAM,mBAAmB,CAAC,MAA2C;AACnE,UAAI,aAAa,WAAW,SAAS;AACnC,gBAAQ,cAAc,KAAK;AAAA,MAC7B;AAGA,UAAI,cAAc;AAChB,qBAAa,CAAC;AAAA,MAChB;AAAA,IACF;AAEA,WACE;AAAA,MAAC;AAAA;AAAA,QACC,KAAK,CAAC,SAAS;AAEb,cAAI,MAAM;AACR,YAAC,QAAsD,UAAU;AACjE,gBAAI,OAAO,iBAAiB,YAAY;AACtC,2BAAa,IAAI;AAAA,YACnB,WAAW,cAAc;AACvB,2BAAa,UAAU;AAAA,YACzB;AAAA,UACF;AAAA,QACF;AAAA,QACA;AAAA,QACA,cAAc;AAAA,QACb,GAAG;AAAA,QAEH;AAAA;AAAA,IACH;AAAA,EAEJ;AACF;AAEA,aAAa,cAAc;;;AChF3B,IAAAC,gBAAoC;AA4H1B,IAAAC,sBAAA;AA5GH,SAAS,mBAAmB;AAAA,EACjC;AAAA,EACA,WAAW;AAAA,EACX,cAAc;AAChB,GAA4B;AAC1B,QAAM,CAAC,QAAQ,SAAS,QAAI,wBAAS,WAAW;AAChD,QAAM,CAAC,OAAO,QAAQ,QAAI,wBAAyD,IAAI;AACvF,QAAM,CAAC,OAAO,QAAQ,QAAI,wBAAqB,CAAC,CAAC;AAEjD,+BAAU,MAAM;AACd,QAAI,CAAC,QAAS;AAEd,UAAM,cAAc,MAAM;AACxB,eAAS,QAAQ,SAAS,CAAC;AAC3B,YAAM,eAAe,QAAQ,uBAAuB;AACpD;AAAA,QACE,aAAa,IAAI,CAAC,UAAU;AAAA,UAC1B,OAAO,KAAK,aAAa,qBAAqB,KAAK;AAAA,UACnD,MAAM,KAAK;AAAA,UACX,UAAU,KAAK,aAAa,wBAAwB,KAAK;AAAA,UACzD,aAAa,KAAK,aAAa,2BAA2B,KAAK;AAAA,QACjE,EAAE;AAAA,MACJ;AAAA,IACF;AAGA,gBAAY;AAGZ,UAAM,WAAW,YAAY,aAAa,GAAI;AAE9C,WAAO,MAAM,cAAc,QAAQ;AAAA,EACrC,GAAG,CAAC,OAAO,CAAC;AAEZ,MAAI,CAAC,SAAS;AACZ,WAAO;AAAA,EACT;AAEA,QAAM,iBAAsD;AAAA,IAC1D,YAAY,EAAE,KAAK,IAAI,MAAM,GAAG;AAAA,IAChC,aAAa,EAAE,KAAK,IAAI,OAAO,GAAG;AAAA,IAClC,eAAe,EAAE,QAAQ,IAAI,MAAM,GAAG;AAAA,IACtC,gBAAgB,EAAE,QAAQ,IAAI,OAAO,GAAG;AAAA,EAC1C;AAEA,QAAM,iBAAsC;AAAA,IAC1C,UAAU;AAAA,IACV,GAAG,eAAe,QAAQ;AAAA,IAC1B,QAAQ;AAAA,IACR,YAAY;AAAA,IACZ,UAAU;AAAA,EACZ;AAEA,QAAM,cAAmC;AAAA,IACvC,YAAY;AAAA,IACZ,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,cAAc;AAAA,IACd,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAW;AAAA,IACX,SAAS;AAAA,IACT,YAAY;AAAA,IACZ,gBAAgB;AAAA,IAChB,UAAU;AAAA,EACZ;AAEA,QAAM,aAAkC;AAAA,IACtC,YAAY;AAAA,IACZ,QAAQ;AAAA,IACR,cAAc;AAAA,IACd,WAAW;AAAA,IACX,SAAS;AAAA,IACT,UAAU;AAAA,IACV,UAAU;AAAA,IACV,WAAW;AAAA,IACX,UAAU;AAAA,IACV,cAAc;AAAA,EAChB;AAEA,QAAM,cAAmC;AAAA,IACvC,YAAY;AAAA,IACZ,cAAc;AAAA,IACd,OAAO;AAAA,IACP,cAAc;AAAA,IACd,eAAe;AAAA,EACjB;AAEA,QAAM,YAAiC;AAAA,IACrC,SAAS;AAAA,IACT,gBAAgB;AAAA,IAChB,SAAS;AAAA,IACT,cAAc;AAAA,EAChB;AAEA,QAAM,YAAiC;AAAA,IACrC,YAAY;AAAA,IACZ,SAAS;AAAA,IACT,cAAc;AAAA,IACd,cAAc;AAAA,IACd,UAAU;AAAA,EACZ;AAEA,SACE,8CAAC,SAAI,OAAO,gBACT;AAAA,cAAU,SACT,8CAAC,SAAI,OAAO,YACV;AAAA,mDAAC,SAAI,OAAO,aAAa,4CAAuB;AAAA,MAEhD,8CAAC,SAAI,OAAO,EAAE,cAAc,OAAO,GACjC;AAAA,sDAAC,SAAI,OAAO,WACV;AAAA,uDAAC,UAAK,uBAAS;AAAA,UACf,6CAAC,YAAQ,gBAAM,UAAS;AAAA,WAC1B;AAAA,QACA,8CAAC,SAAI,OAAO,WACV;AAAA,uDAAC,UAAK,4BAAc;AAAA,UACpB,6CAAC,YAAQ,gBAAM,eAAe,WAAM,UAAI;AAAA,WAC1C;AAAA,QACA,8CAAC,SAAI,OAAO,WACV;AAAA,uDAAC,UAAK,+BAAiB;AAAA,UACvB,6CAAC,YAAQ,gBAAM,iBAAgB;AAAA,WACjC;AAAA,QACA,8CAAC,SAAI,OAAO,WACV;AAAA,uDAAC,UAAK,+BAAiB;AAAA,UACvB,6CAAC,YAAQ,gBAAM,QAAO;AAAA,WACxB;AAAA,SACF;AAAA,MAEC,MAAM,iBAAiB,SAAS,KAC/B,8CAAC,SACC;AAAA,qDAAC,SAAI,OAAO,EAAE,GAAG,aAAa,UAAU,OAAO,GAAG,gCAAkB;AAAA,QACpE,6CAAC,SAAI,OAAO,EAAE,UAAU,QAAQ,OAAO,QAAQ,cAAc,MAAM,GAChE,gBAAM,iBAAiB,KAAK,IAAI,GACnC;AAAA,SACF;AAAA,MAGD,MAAM,SAAS,KACd,8CAAC,SACC;AAAA,qDAAC,SAAI,OAAO,EAAE,GAAG,aAAa,UAAU,OAAO,GAAG,+BAAiB;AAAA,QAClE,MAAM,IAAI,CAAC,MAAM,MAChB,8CAAC,SAAY,OAAO,WAClB;AAAA,uDAAC,SACC,uDAAC,YAAQ,eAAK,OAAM,GACtB;AAAA,UACA,8CAAC,SAAI,OAAO,EAAE,OAAO,QAAQ,WAAW,MAAM,GAAG;AAAA;AAAA,YACpC,KAAK;AAAA,YAAS;AAAA,aAAW,WAAW,KAAK,WAAW,IAAI,KAAK,QAAQ,CAAC;AAAA,YAAE;AAAA,aACrF;AAAA,UACA,6CAAC,SAAI,OAAO,EAAE,OAAO,QAAQ,WAAW,OAAO,WAAW,YAAY,GACnE,eAAK,KAAK,MAAM,GAAG,EAAE,IAAI,GAC5B;AAAA,aATQ,CAUV,CACD;AAAA,SACH;AAAA,MAGF;AAAA,QAAC;AAAA;AAAA,UACC,SAAS,MAAM;AACb,oBAAQ,aAAa;AAAA,UACvB;AAAA,UACA,OAAO;AAAA,YACL,OAAO;AAAA,YACP,SAAS;AAAA,YACT,YAAY;AAAA,YACZ,OAAO;AAAA,YACP,QAAQ;AAAA,YACR,cAAc;AAAA,YACd,QAAQ;AAAA,YACR,WAAW;AAAA,UACb;AAAA,UACD;AAAA;AAAA,MAED;AAAA,OACF;AAAA,IAGF;AAAA,MAAC;AAAA;AAAA,QACC,OAAO;AAAA,QACP,SAAS,MAAM,UAAU,CAAC,MAAM;AAAA,QAChC,OAAM;AAAA,QACP;AAAA;AAAA,IAED;AAAA,KACF;AAEJ;","names":["import_react","import_react_router_dom","React","import_react","import_jsx_runtime"]}
|
|
1
|
+
{"version":3,"sources":["../../src/frameworks/react/index.ts","../../src/frameworks/react/usePrefetch.ts","../../src/runtime/prefetch-manager.ts","../../src/frameworks/react/usePrefetchTanStack.ts","../../src/frameworks/react/PrefetchLink.tsx","../../src/frameworks/react/PrefetchDebugPanel.tsx"],"sourcesContent":["/**\n * React Framework Integration\n * Exports all React-specific components and hooks\n */\n\n// React Router DOM support\nexport { usePrefetch, getPrefetchManager } from './usePrefetch';\n\n// TanStack Router support (NEW)\nexport { usePrefetchTanStack, getPrefetchManagerTanStack, matchPrefetchPattern } from './usePrefetchTanStack';\n\n// Common components\nexport { PrefetchLink } from './PrefetchLink';\nexport type { PrefetchLinkProps } from './PrefetchLink';\nexport { PrefetchDebugPanel } from './PrefetchDebugPanel';\nexport type { PrefetchDebugPanelProps } from './PrefetchDebugPanel';\n","/**\n * React Hook for Smart Prefetch\n * Automatically prefetches routes based on navigation\n */\n\nimport { useEffect, useRef } from 'react';\nimport { useLocation } from 'react-router-dom';\nimport { PrefetchManager } from '../../runtime/prefetch-manager';\nimport type { PrefetchStrategy } from '../../types';\n\n// Singleton instance\nlet managerInstance: PrefetchManager | null = null;\n\n/**\n * React hook to enable smart prefetching\n * Call this once in your root App component\n *\n * @example\n * ```tsx\n * function App() {\n * usePrefetch();\n * return <Routes>...</Routes>;\n * }\n * ```\n */\nexport function usePrefetch(): PrefetchManager | null {\n const location = useLocation();\n const initialized = useRef(false);\n\n // Initialize manager once\n useEffect(() => {\n if (!initialized.current) {\n // Read config from window (injected by plugin)\n const config = (window as any).__SMART_PREFETCH__ || {};\n const strategy: PrefetchStrategy = config.strategy || 'hybrid';\n const debug: boolean = config.debug || false;\n\n managerInstance = new PrefetchManager(strategy, debug);\n managerInstance.init();\n\n // Expose manager globally for debugging and external use\n (window as any).__FARMART_PREFETCH_MANAGER__ = managerInstance;\n\n initialized.current = true;\n\n if (debug) {\n console.log('✅ usePrefetch initialized');\n console.log('✅ Prefetch manager exposed as window.__FARMART_PREFETCH_MANAGER__');\n }\n }\n }, []);\n\n // Prefetch on route change\n useEffect(() => {\n if (managerInstance) {\n managerInstance.prefetch(location.pathname);\n }\n }, [location.pathname]);\n\n return managerInstance;\n}\n\n/**\n * Get the prefetch manager instance\n * Useful for manual prefetch control\n */\nexport function getPrefetchManager(): PrefetchManager | null {\n return managerInstance;\n}\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 * TanStack Router Hook for Smart Prefetch\n * Automatically prefetches routes based on navigation\n *\n * @example\n * ```tsx\n * import { usePrefetchTanStack } from 'vite-plugin-smart-prefetch/react';\n *\n * export function RootLayout() {\n * usePrefetchTanStack();\n * return <Outlet />;\n * }\n * ```\n */\n\nimport { useEffect, useRef } from 'react';\n// @ts-ignore - optional peer dependency\nimport { useLocation } from '@tanstack/react-router';\nimport { PrefetchManager } from '../../runtime/prefetch-manager';\n\n// Singleton instance\nlet managerInstance: PrefetchManager | null = null;\n\n/**\n * React hook to enable smart prefetching with TanStack Router\n * Call this once in your root layout component\n *\n * Supports dynamic routes with patterns:\n * - Static routes: /dashboard, /orders\n * - Dynamic routes: /orders/:id, /users/$userId\n *\n * @example\n * ```tsx\n * function RootLayout() {\n * usePrefetchTanStack();\n * return <Outlet />;\n * }\n * ```\n */\nexport function usePrefetchTanStack(): PrefetchManager | null {\n const location = useLocation();\n const initialized = useRef(false);\n\n // Initialize manager once\n useEffect(() => {\n if (!initialized.current) {\n // Read config from window (injected by plugin)\n const config = (window as any).__SMART_PREFETCH__ || {};\n const strategy = config.strategy || 'hybrid';\n const debug: boolean = config.debug || false;\n\n managerInstance = new PrefetchManager(strategy, debug);\n managerInstance.init();\n\n // Expose manager globally for debugging and external use\n (window as any).__FARMART_PREFETCH_MANAGER__ = managerInstance;\n\n initialized.current = true;\n\n if (debug) {\n console.log('✅ usePrefetchTanStack initialized');\n console.log('✅ Prefetch manager exposed as window.__FARMART_PREFETCH_MANAGER__');\n }\n }\n }, []);\n\n // Prefetch on route change - works with both static and dynamic routes\n useEffect(() => {\n if (managerInstance) {\n const pathname = location.pathname.split('?')[0].split('#')[0];\n managerInstance.prefetch(pathname);\n }\n }, [location.pathname]);\n\n return managerInstance;\n}\n\n/**\n * Get the prefetch manager instance\n * Useful for manual prefetch control\n *\n * @example\n * ```tsx\n * const manager = getPrefetchManager();\n * manager?.setSegment('premium');\n * ```\n */\nexport function getPrefetchManagerTanStack(): PrefetchManager | null {\n return managerInstance;\n}\n\n/**\n * Advanced: Use route pattern matching directly\n * Useful if you need to manually check pattern matching logic\n *\n * @example\n * ```tsx\n * const matchesPattern = matchPrefetchPattern('/orders/123', '/orders/:id');\n * ```\n */\nexport function matchPrefetchPattern(pathname: string, pattern: string): boolean {\n // Convert route pattern to regex\n // Supports both React Router (:param) and TanStack Router ($param) styles\n const patternRegex = new RegExp(\n '^' + pattern\n .replace(/:[^/]+/g, '[^/]+') // Match :param style\n .replace(/\\$[^/]+/g, '[^/]+') // Match $param style (TanStack Router)\n .replace(/\\*/g, '.*') + // Match wildcard\n '$'\n );\n return patternRegex.test(pathname);\n}\n","/**\n * Enhanced Link Component with Prefetch Support\n * Extends React Router Link with smart prefetching\n */\n\nimport React, { useRef, useEffect } from 'react';\nimport { Link, type LinkProps } from 'react-router-dom';\nimport { getPrefetchManager } from './usePrefetch';\n\nexport interface PrefetchLinkProps extends Omit<LinkProps, 'prefetch'> {\n /**\n * Prefetch behavior\n * - 'hover': Prefetch on mouse enter\n * - 'visible': Prefetch when link becomes visible\n * - 'manual': No automatic prefetch (use onClick)\n * - undefined: Use default strategy from config\n */\n prefetch?: 'hover' | 'visible' | 'manual';\n}\n\n/**\n * Enhanced Link component with prefetching\n *\n * @example\n * ```tsx\n * // Prefetch on hover\n * <PrefetchLink to=\"/orders\" prefetch=\"hover\">\n * View Orders\n * </PrefetchLink>\n *\n * // Prefetch when visible\n * <PrefetchLink to=\"/dispatch-order\" prefetch=\"visible\">\n * Create Dispatch\n * </PrefetchLink>\n * ```\n */\nexport const PrefetchLink = React.forwardRef<HTMLAnchorElement, PrefetchLinkProps>(\n ({ prefetch, to, children, onMouseEnter, ...props }, forwardedRef) => {\n const linkRef = useRef<HTMLAnchorElement>(null);\n const manager = getPrefetchManager();\n\n const route = typeof to === 'string' ? to : to.pathname || '';\n\n // Handle visibility-based prefetch\n useEffect(() => {\n if (prefetch === 'visible' && linkRef.current && manager) {\n manager.observeLink(linkRef.current, route);\n }\n }, [prefetch, route, manager]);\n\n // Handle hover-based prefetch\n const handleMouseEnter = (e: React.MouseEvent<HTMLAnchorElement>) => {\n if (prefetch === 'hover' && manager) {\n manager.prefetchRoute(route);\n }\n\n // Call original onMouseEnter if provided\n if (onMouseEnter) {\n onMouseEnter(e);\n }\n };\n\n return (\n <Link\n ref={(node) => {\n // Handle both forwarded ref and internal ref\n if (node) {\n (linkRef as React.MutableRefObject<HTMLAnchorElement>).current = node;\n if (typeof forwardedRef === 'function') {\n forwardedRef(node);\n } else if (forwardedRef) {\n forwardedRef.current = node;\n }\n }\n }}\n to={to}\n onMouseEnter={handleMouseEnter}\n {...props}\n >\n {children}\n </Link>\n );\n }\n);\n\nPrefetchLink.displayName = 'PrefetchLink';\n","/**\n * Debug Panel Component for Smart Prefetch Plugin\n * Shows real-time prefetch status and link tags\n */\n\nimport { useEffect, useState } from 'react';\nimport type { PrefetchManager } from '../../runtime/prefetch-manager';\n\nexport interface PrefetchDebugPanelProps {\n manager: PrefetchManager | null;\n position?: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';\n defaultOpen?: boolean;\n}\n\ninterface LinkInfo {\n route: string;\n href: string;\n priority: string;\n probability: string;\n}\n\nexport function PrefetchDebugPanel({\n manager,\n position = 'bottom-right',\n defaultOpen = false,\n}: PrefetchDebugPanelProps) {\n const [isOpen, setIsOpen] = useState(defaultOpen);\n const [stats, setStats] = useState<ReturnType<PrefetchManager['getStats']> | null>(null);\n const [links, setLinks] = useState<LinkInfo[]>([]);\n\n useEffect(() => {\n if (!manager) return;\n\n const updateStats = () => {\n setStats(manager.getStats());\n const linkElements = manager.getActivePrefetchLinks();\n setLinks(\n linkElements.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 }))\n );\n };\n\n // Update stats immediately\n updateStats();\n\n // Update stats every second\n const interval = setInterval(updateStats, 1000);\n\n return () => clearInterval(interval);\n }, [manager]);\n\n if (!manager) {\n return null;\n }\n\n const positionStyles: Record<string, React.CSSProperties> = {\n 'top-left': { top: 10, left: 10 },\n 'top-right': { top: 10, right: 10 },\n 'bottom-left': { bottom: 10, left: 10 },\n 'bottom-right': { bottom: 10, right: 10 },\n };\n\n const containerStyle: React.CSSProperties = {\n position: 'fixed',\n ...positionStyles[position],\n zIndex: 99999,\n fontFamily: 'system-ui, -apple-system, sans-serif',\n fontSize: '12px',\n };\n\n const buttonStyle: React.CSSProperties = {\n background: '#4CAF50',\n color: 'white',\n border: 'none',\n borderRadius: '50%',\n width: '48px',\n height: '48px',\n cursor: 'pointer',\n boxShadow: '0 4px 8px rgba(0,0,0,0.2)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontSize: '20px',\n };\n\n const panelStyle: React.CSSProperties = {\n background: 'white',\n border: '1px solid #ddd',\n borderRadius: '8px',\n boxShadow: '0 4px 12px rgba(0,0,0,0.15)',\n padding: '12px',\n minWidth: '320px',\n maxWidth: '400px',\n maxHeight: '500px',\n overflow: 'auto',\n marginBottom: '8px',\n };\n\n const headerStyle: React.CSSProperties = {\n fontWeight: 'bold',\n marginBottom: '8px',\n color: '#333',\n borderBottom: '2px solid #4CAF50',\n paddingBottom: '4px',\n };\n\n const statStyle: React.CSSProperties = {\n display: 'flex',\n justifyContent: 'space-between',\n padding: '4px 0',\n borderBottom: '1px solid #eee',\n };\n\n const linkStyle: React.CSSProperties = {\n background: '#f5f5f5',\n padding: '8px',\n borderRadius: '4px',\n marginBottom: '8px',\n fontSize: '11px',\n };\n\n return (\n <div style={containerStyle}>\n {isOpen && stats && (\n <div style={panelStyle}>\n <div style={headerStyle}>🚀 Smart Prefetch Debug</div>\n\n <div style={{ marginBottom: '12px' }}>\n <div style={statStyle}>\n <span>Strategy:</span>\n <strong>{stats.strategy}</strong>\n </div>\n <div style={statStyle}>\n <span>Config Loaded:</span>\n <strong>{stats.configLoaded ? '✅' : '❌'}</strong>\n </div>\n <div style={statStyle}>\n <span>Total Prefetched:</span>\n <strong>{stats.totalPrefetched}</strong>\n </div>\n <div style={statStyle}>\n <span>Link Tags in DOM:</span>\n <strong>{links.length}</strong>\n </div>\n </div>\n\n {stats.prefetchedRoutes.length > 0 && (\n <div>\n <div style={{ ...headerStyle, fontSize: '11px' }}>Prefetched Routes:</div>\n <div style={{ fontSize: '11px', color: '#666', marginBottom: '8px' }}>\n {stats.prefetchedRoutes.join(', ')}\n </div>\n </div>\n )}\n\n {links.length > 0 && (\n <div>\n <div style={{ ...headerStyle, fontSize: '11px' }}>Active Link Tags:</div>\n {links.map((link, i) => (\n <div key={i} style={linkStyle}>\n <div>\n <strong>{link.route}</strong>\n </div>\n <div style={{ color: '#666', marginTop: '4px' }}>\n Priority: {link.priority} | Prob: {(parseFloat(link.probability) * 100).toFixed(1)}%\n </div>\n <div style={{ color: '#999', marginTop: '2px', wordBreak: 'break-all' }}>\n {link.href.split('/').pop()}\n </div>\n </div>\n ))}\n </div>\n )}\n\n <button\n onClick={() => {\n manager.logDebugInfo();\n }}\n style={{\n width: '100%',\n padding: '8px',\n background: '#2196F3',\n color: 'white',\n border: 'none',\n borderRadius: '4px',\n cursor: 'pointer',\n marginTop: '8px',\n }}\n >\n Log Debug Info to Console\n </button>\n </div>\n )}\n\n <button\n style={buttonStyle}\n onClick={() => setIsOpen(!isOpen)}\n title=\"Smart Prefetch Debug Panel\"\n >\n 🔗\n </button>\n </div>\n );\n}\n"],"mappings":"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","names":["import_react","managerInstance","import_react","import_react_router_dom","React","import_react","import_jsx_runtime"]}
|
package/dist/react/index.d.cts
CHANGED
|
@@ -132,6 +132,60 @@ declare function usePrefetch(): PrefetchManager | null;
|
|
|
132
132
|
*/
|
|
133
133
|
declare function getPrefetchManager(): PrefetchManager | null;
|
|
134
134
|
|
|
135
|
+
/**
|
|
136
|
+
* TanStack Router Hook for Smart Prefetch
|
|
137
|
+
* Automatically prefetches routes based on navigation
|
|
138
|
+
*
|
|
139
|
+
* @example
|
|
140
|
+
* ```tsx
|
|
141
|
+
* import { usePrefetchTanStack } from 'vite-plugin-smart-prefetch/react';
|
|
142
|
+
*
|
|
143
|
+
* export function RootLayout() {
|
|
144
|
+
* usePrefetchTanStack();
|
|
145
|
+
* return <Outlet />;
|
|
146
|
+
* }
|
|
147
|
+
* ```
|
|
148
|
+
*/
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* React hook to enable smart prefetching with TanStack Router
|
|
152
|
+
* Call this once in your root layout component
|
|
153
|
+
*
|
|
154
|
+
* Supports dynamic routes with patterns:
|
|
155
|
+
* - Static routes: /dashboard, /orders
|
|
156
|
+
* - Dynamic routes: /orders/:id, /users/$userId
|
|
157
|
+
*
|
|
158
|
+
* @example
|
|
159
|
+
* ```tsx
|
|
160
|
+
* function RootLayout() {
|
|
161
|
+
* usePrefetchTanStack();
|
|
162
|
+
* return <Outlet />;
|
|
163
|
+
* }
|
|
164
|
+
* ```
|
|
165
|
+
*/
|
|
166
|
+
declare function usePrefetchTanStack(): PrefetchManager | null;
|
|
167
|
+
/**
|
|
168
|
+
* Get the prefetch manager instance
|
|
169
|
+
* Useful for manual prefetch control
|
|
170
|
+
*
|
|
171
|
+
* @example
|
|
172
|
+
* ```tsx
|
|
173
|
+
* const manager = getPrefetchManager();
|
|
174
|
+
* manager?.setSegment('premium');
|
|
175
|
+
* ```
|
|
176
|
+
*/
|
|
177
|
+
declare function getPrefetchManagerTanStack(): PrefetchManager | null;
|
|
178
|
+
/**
|
|
179
|
+
* Advanced: Use route pattern matching directly
|
|
180
|
+
* Useful if you need to manually check pattern matching logic
|
|
181
|
+
*
|
|
182
|
+
* @example
|
|
183
|
+
* ```tsx
|
|
184
|
+
* const matchesPattern = matchPrefetchPattern('/orders/123', '/orders/:id');
|
|
185
|
+
* ```
|
|
186
|
+
*/
|
|
187
|
+
declare function matchPrefetchPattern(pathname: string, pattern: string): boolean;
|
|
188
|
+
|
|
135
189
|
/**
|
|
136
190
|
* Enhanced Link Component with Prefetch Support
|
|
137
191
|
* Extends React Router Link with smart prefetching
|
|
@@ -172,4 +226,4 @@ interface PrefetchDebugPanelProps {
|
|
|
172
226
|
}
|
|
173
227
|
declare function PrefetchDebugPanel({ manager, position, defaultOpen, }: PrefetchDebugPanelProps): react_jsx_runtime.JSX.Element | null;
|
|
174
228
|
|
|
175
|
-
export { PrefetchDebugPanel, type PrefetchDebugPanelProps, PrefetchLink, type PrefetchLinkProps, getPrefetchManager, usePrefetch };
|
|
229
|
+
export { PrefetchDebugPanel, type PrefetchDebugPanelProps, PrefetchLink, type PrefetchLinkProps, getPrefetchManager, getPrefetchManagerTanStack, matchPrefetchPattern, usePrefetch, usePrefetchTanStack };
|
package/dist/react/index.d.ts
CHANGED
|
@@ -132,6 +132,60 @@ declare function usePrefetch(): PrefetchManager | null;
|
|
|
132
132
|
*/
|
|
133
133
|
declare function getPrefetchManager(): PrefetchManager | null;
|
|
134
134
|
|
|
135
|
+
/**
|
|
136
|
+
* TanStack Router Hook for Smart Prefetch
|
|
137
|
+
* Automatically prefetches routes based on navigation
|
|
138
|
+
*
|
|
139
|
+
* @example
|
|
140
|
+
* ```tsx
|
|
141
|
+
* import { usePrefetchTanStack } from 'vite-plugin-smart-prefetch/react';
|
|
142
|
+
*
|
|
143
|
+
* export function RootLayout() {
|
|
144
|
+
* usePrefetchTanStack();
|
|
145
|
+
* return <Outlet />;
|
|
146
|
+
* }
|
|
147
|
+
* ```
|
|
148
|
+
*/
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* React hook to enable smart prefetching with TanStack Router
|
|
152
|
+
* Call this once in your root layout component
|
|
153
|
+
*
|
|
154
|
+
* Supports dynamic routes with patterns:
|
|
155
|
+
* - Static routes: /dashboard, /orders
|
|
156
|
+
* - Dynamic routes: /orders/:id, /users/$userId
|
|
157
|
+
*
|
|
158
|
+
* @example
|
|
159
|
+
* ```tsx
|
|
160
|
+
* function RootLayout() {
|
|
161
|
+
* usePrefetchTanStack();
|
|
162
|
+
* return <Outlet />;
|
|
163
|
+
* }
|
|
164
|
+
* ```
|
|
165
|
+
*/
|
|
166
|
+
declare function usePrefetchTanStack(): PrefetchManager | null;
|
|
167
|
+
/**
|
|
168
|
+
* Get the prefetch manager instance
|
|
169
|
+
* Useful for manual prefetch control
|
|
170
|
+
*
|
|
171
|
+
* @example
|
|
172
|
+
* ```tsx
|
|
173
|
+
* const manager = getPrefetchManager();
|
|
174
|
+
* manager?.setSegment('premium');
|
|
175
|
+
* ```
|
|
176
|
+
*/
|
|
177
|
+
declare function getPrefetchManagerTanStack(): PrefetchManager | null;
|
|
178
|
+
/**
|
|
179
|
+
* Advanced: Use route pattern matching directly
|
|
180
|
+
* Useful if you need to manually check pattern matching logic
|
|
181
|
+
*
|
|
182
|
+
* @example
|
|
183
|
+
* ```tsx
|
|
184
|
+
* const matchesPattern = matchPrefetchPattern('/orders/123', '/orders/:id');
|
|
185
|
+
* ```
|
|
186
|
+
*/
|
|
187
|
+
declare function matchPrefetchPattern(pathname: string, pattern: string): boolean;
|
|
188
|
+
|
|
135
189
|
/**
|
|
136
190
|
* Enhanced Link Component with Prefetch Support
|
|
137
191
|
* Extends React Router Link with smart prefetching
|
|
@@ -172,4 +226,4 @@ interface PrefetchDebugPanelProps {
|
|
|
172
226
|
}
|
|
173
227
|
declare function PrefetchDebugPanel({ manager, position, defaultOpen, }: PrefetchDebugPanelProps): react_jsx_runtime.JSX.Element | null;
|
|
174
228
|
|
|
175
|
-
export { PrefetchDebugPanel, type PrefetchDebugPanelProps, PrefetchLink, type PrefetchLinkProps, getPrefetchManager, usePrefetch };
|
|
229
|
+
export { PrefetchDebugPanel, type PrefetchDebugPanelProps, PrefetchLink, type PrefetchLinkProps, getPrefetchManager, getPrefetchManagerTanStack, matchPrefetchPattern, usePrefetch, usePrefetchTanStack };
|
package/dist/react/index.js
CHANGED
|
@@ -543,16 +543,57 @@ function getPrefetchManager() {
|
|
|
543
543
|
return managerInstance;
|
|
544
544
|
}
|
|
545
545
|
|
|
546
|
+
// src/frameworks/react/usePrefetchTanStack.ts
|
|
547
|
+
import { useEffect as useEffect2, useRef as useRef2 } from "react";
|
|
548
|
+
import { useLocation as useLocation2 } from "@tanstack/react-router";
|
|
549
|
+
var managerInstance2 = null;
|
|
550
|
+
function usePrefetchTanStack() {
|
|
551
|
+
const location = useLocation2();
|
|
552
|
+
const initialized = useRef2(false);
|
|
553
|
+
useEffect2(() => {
|
|
554
|
+
if (!initialized.current) {
|
|
555
|
+
const config = window.__SMART_PREFETCH__ || {};
|
|
556
|
+
const strategy = config.strategy || "hybrid";
|
|
557
|
+
const debug = config.debug || false;
|
|
558
|
+
managerInstance2 = new PrefetchManager(strategy, debug);
|
|
559
|
+
managerInstance2.init();
|
|
560
|
+
window.__FARMART_PREFETCH_MANAGER__ = managerInstance2;
|
|
561
|
+
initialized.current = true;
|
|
562
|
+
if (debug) {
|
|
563
|
+
console.log("\u2705 usePrefetchTanStack initialized");
|
|
564
|
+
console.log("\u2705 Prefetch manager exposed as window.__FARMART_PREFETCH_MANAGER__");
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
}, []);
|
|
568
|
+
useEffect2(() => {
|
|
569
|
+
if (managerInstance2) {
|
|
570
|
+
const pathname = location.pathname.split("?")[0].split("#")[0];
|
|
571
|
+
managerInstance2.prefetch(pathname);
|
|
572
|
+
}
|
|
573
|
+
}, [location.pathname]);
|
|
574
|
+
return managerInstance2;
|
|
575
|
+
}
|
|
576
|
+
function getPrefetchManagerTanStack() {
|
|
577
|
+
return managerInstance2;
|
|
578
|
+
}
|
|
579
|
+
function matchPrefetchPattern(pathname, pattern) {
|
|
580
|
+
const patternRegex = new RegExp(
|
|
581
|
+
"^" + pattern.replace(/:[^/]+/g, "[^/]+").replace(/\$[^/]+/g, "[^/]+").replace(/\*/g, ".*") + // Match wildcard
|
|
582
|
+
"$"
|
|
583
|
+
);
|
|
584
|
+
return patternRegex.test(pathname);
|
|
585
|
+
}
|
|
586
|
+
|
|
546
587
|
// src/frameworks/react/PrefetchLink.tsx
|
|
547
|
-
import React, { useRef as
|
|
588
|
+
import React, { useRef as useRef3, useEffect as useEffect3 } from "react";
|
|
548
589
|
import { Link } from "react-router-dom";
|
|
549
590
|
import { jsx } from "react/jsx-runtime";
|
|
550
591
|
var PrefetchLink = React.forwardRef(
|
|
551
592
|
({ prefetch, to, children, onMouseEnter, ...props }, forwardedRef) => {
|
|
552
|
-
const linkRef =
|
|
593
|
+
const linkRef = useRef3(null);
|
|
553
594
|
const manager = getPrefetchManager();
|
|
554
595
|
const route = typeof to === "string" ? to : to.pathname || "";
|
|
555
|
-
|
|
596
|
+
useEffect3(() => {
|
|
556
597
|
if (prefetch === "visible" && linkRef.current && manager) {
|
|
557
598
|
manager.observeLink(linkRef.current, route);
|
|
558
599
|
}
|
|
@@ -589,7 +630,7 @@ var PrefetchLink = React.forwardRef(
|
|
|
589
630
|
PrefetchLink.displayName = "PrefetchLink";
|
|
590
631
|
|
|
591
632
|
// src/frameworks/react/PrefetchDebugPanel.tsx
|
|
592
|
-
import { useEffect as
|
|
633
|
+
import { useEffect as useEffect4, useState } from "react";
|
|
593
634
|
import { jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
594
635
|
function PrefetchDebugPanel({
|
|
595
636
|
manager,
|
|
@@ -599,7 +640,7 @@ function PrefetchDebugPanel({
|
|
|
599
640
|
const [isOpen, setIsOpen] = useState(defaultOpen);
|
|
600
641
|
const [stats, setStats] = useState(null);
|
|
601
642
|
const [links, setLinks] = useState([]);
|
|
602
|
-
|
|
643
|
+
useEffect4(() => {
|
|
603
644
|
if (!manager) return;
|
|
604
645
|
const updateStats = () => {
|
|
605
646
|
setStats(manager.getStats());
|
|
@@ -753,6 +794,9 @@ export {
|
|
|
753
794
|
PrefetchDebugPanel,
|
|
754
795
|
PrefetchLink,
|
|
755
796
|
getPrefetchManager,
|
|
756
|
-
|
|
797
|
+
getPrefetchManagerTanStack,
|
|
798
|
+
matchPrefetchPattern,
|
|
799
|
+
usePrefetch,
|
|
800
|
+
usePrefetchTanStack
|
|
757
801
|
};
|
|
758
802
|
//# sourceMappingURL=index.js.map
|