vite-plugin-smart-prefetch 0.4.0 → 0.4.2
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 +23 -191
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -19
- package/dist/index.d.ts +2 -19
- package/dist/index.js +23 -191
- package/dist/index.js.map +1 -1
- package/dist/react/index.cjs +70 -211
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +112 -127
- package/dist/react/index.d.ts +112 -127
- package/dist/react/index.js +55 -181
- package/dist/react/index.js.map +1 -1
- package/dist/runtime/index.cjs +35 -35
- package/dist/runtime/index.cjs.map +1 -1
- package/dist/runtime/index.d.cts +30 -25
- package/dist/runtime/index.d.ts +30 -25
- package/dist/runtime/index.js +35 -35
- package/dist/runtime/index.js.map +1 -1
- package/package.json +4 -8
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/plugin/analytics/bigquery-connector.ts","../src/plugin/model/guessjs-ml-trainer.ts","../src/plugin/config-generator.ts","../src/plugin/cache-manager.ts","../src/plugin/index.ts"],"sourcesContent":["/**\n * BigQuery Analytics Connector\n * Queries GA4 event data from BigQuery to extract real navigation transitions\n */\n\nimport { BigQuery } from '@google-cloud/bigquery';\nimport { writeFileSync, mkdirSync } from 'fs';\nimport { join } from 'path';\nimport type { NavigationData, DataRangeConfig } from '../../types';\n\nexport class BigQueryAnalyticsConnector {\n private bigquery: BigQuery;\n private projectId: string;\n private datasetId: string;\n private location: string;\n private debug: boolean;\n\n constructor(projectId: string, datasetId: string, location = 'asia-south1', debug = false, keyFilePath?: string) {\n this.projectId = projectId;\n this.datasetId = datasetId;\n // Ensure location is properly formatted (handle 'asia' → 'asia-south1', etc.)\n this.location = location && location !== 'asia' ? location : 'asia-south1';\n this.debug = debug;\n\n // Initialize BigQuery client with service account credentials\n const bigqueryConfig: any = {\n projectId: projectId,\n };\n\n // If keyFilePath provided, use service account file\n // Otherwise, use default Application Default Credentials\n if (keyFilePath) {\n bigqueryConfig.keyFilename = keyFilePath;\n }\n\n this.bigquery = new BigQuery(bigqueryConfig);\n\n if (this.debug) {\n console.log('✅ BigQuery Analytics connector initialized');\n console.log(` Project ID: ${projectId}`);\n console.log(` Dataset ID: ${datasetId}`);\n console.log(` Location: ${this.location}`);\n console.log(` Authentication: ${keyFilePath ? `Service Account (${keyFilePath})` : 'Application Default Credentials'}`);\n console.log(` Querying daily events tables: ${projectId}.${datasetId}.events_*`);\n }\n }\n\n /**\n * Fetch real navigation transitions from BigQuery GA4 export\n * Queries the events table for page_view events with previous_page_path parameter\n */\n async fetchNavigationSequences(config: DataRangeConfig = {}): Promise<NavigationData[]> {\n const { days = 30 } = config;\n const minSessions = 1;\n\n console.log(`\\n${'═'.repeat(60)}`);\n console.log(`📊 STAGE 1: PREPARING BIGQUERY QUERY`);\n console.log(`${'═'.repeat(60)}`);\n console.log(` Project ID: ${this.projectId}`);\n console.log(` Dataset ID: ${this.datasetId}`);\n console.log(` Location: ${this.location}`);\n console.log(` Date range: Last ${days} days`);\n console.log(` Daily tables pattern: events_*`);\n console.log(` Event type filter: page_view`);\n console.log(` Expected fields: user_pseudo_id, ga_session_id, page_path`);\n\n try {\n // Query GA4 events for page transitions\n // Strategy: Use user_pseudo_id and session_id to reconstruct user sessions and page transitions\n // This groups pages viewed by the same user in the same session to infer navigation flow\n const query = `\n WITH page_sessions AS (\n SELECT\n user_pseudo_id,\n (SELECT value.int_value FROM UNNEST(event_params) WHERE KEY = 'ga_session_id' LIMIT 1) as session_id,\n (SELECT value.string_value FROM UNNEST(event_params) WHERE KEY = 'page_path' LIMIT 1) as page_path,\n event_timestamp,\n ROW_NUMBER() OVER (\n PARTITION BY user_pseudo_id, (SELECT value.int_value FROM UNNEST(event_params) WHERE KEY = 'ga_session_id' LIMIT 1)\n ORDER BY event_timestamp\n ) as page_sequence\n FROM \\`${this.projectId}.${this.datasetId}.events_*\\`\n WHERE\n event_name = 'page_view'\n AND _TABLE_SUFFIX BETWEEN FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE(), INTERVAL ${days} DAY))\n AND FORMAT_DATE('%Y%m%d', CURRENT_DATE())\n AND (SELECT value.string_value FROM UNNEST(event_params) WHERE KEY = 'page_path' LIMIT 1) IS NOT NULL\n ),\n transitions AS (\n SELECT\n COALESCE(curr.page_path, '(direct)') as from_page,\n LEAD(curr.page_path) OVER (\n PARTITION BY curr.user_pseudo_id, curr.session_id\n ORDER BY curr.page_sequence\n ) as to_page\n FROM page_sessions curr\n WHERE curr.page_sequence > 0\n )\n SELECT\n from_page as previous_page_path,\n to_page as page_path,\n COUNT(*) as transition_count\n FROM transitions\n WHERE to_page IS NOT NULL\n GROUP BY previous_page_path, page_path\n ORDER BY transition_count DESC\n LIMIT 10000\n `;\n\n if (this.debug) {\n console.log(`\\n📤 Full BigQuery Query:`);\n console.log(`${'─'.repeat(60)}`);\n console.log(query);\n console.log(`${'─'.repeat(60)}`);\n }\n\n console.log(`\\n${'═'.repeat(60)}`);\n console.log(`📊 STAGE 2: EXECUTING QUERY`);\n console.log(`${'═'.repeat(60)}`);\n console.log(` ⏳ Querying BigQuery...`);\n\n const [rows] = await this.bigquery.query({\n query,\n location: this.location,\n });\n\n console.log(` ✅ Query executed successfully`);\n console.log(` 📈 Total transitions returned: ${rows.length}`);\n\n if (rows.length === 0) {\n console.log(`\\n${'═'.repeat(60)}`);\n console.log(`⚠️ STAGE 2: NO DATA RETURNED!`);\n console.log(`${'═'.repeat(60)}`);\n console.log(` ❌ BigQuery returned 0 rows`);\n console.log(`\\n Possible causes:`);\n console.log(` 1. No event tables in date range (events_YYYYMMDD)`);\n console.log(` 2. No page_view events in those tables`);\n console.log(` 3. page_path parameter not being tracked`);\n console.log(` 4. Wrong location (currently: ${this.location})`);\n console.log(` 5. Wrong dataset name: ${this.datasetId}`);\n console.log(`\\n Troubleshooting:`);\n console.log(` • Check BigQuery console for available event tables`);\n console.log(` • Verify GA4 property is exporting to BigQuery`);\n console.log(` • Confirm page_path is being captured in GA4`);\n console.log(`${'═'.repeat(60)}\\n`);\n return [];\n }\n\n console.log(`\\n${'═'.repeat(60)}`);\n console.log(`📊 STAGE 3: PROCESSING RAW DATA`);\n console.log(`${'═'.repeat(60)}`);\n console.log(` Processing ${rows.length} raw transitions...`);\n\n const navigationData: NavigationData[] = [];\n let processedCount = 0;\n let filteredCount = 0;\n let emptyPathCount = 0;\n let lowCountCount = 0;\n let selfTransitionCount = 0;\n\n // IMPORTANT: Save RAW rows for inspection\n const rawData = rows.map((row: any) => ({\n previous_page_path: row.previous_page_path,\n page_path: row.page_path,\n transition_count: row.transition_count\n }));\n\n console.log(`\\n ${'─'.repeat(56)}`);\n console.log(` Processing each transition row...`);\n console.log(` ${'─'.repeat(56)}`);\n\n // Process rows and convert to NavigationData format\n rows.forEach((row: any, index: number) => {\n const previousPage = row.previous_page_path || '(direct)';\n const currentPage = row.page_path || '';\n const transitionCount = parseInt(row.transition_count || '0');\n\n if (this.debug && index < 5) {\n console.log(`\\n Row ${index + 1}:`);\n console.log(` Raw: \"${previousPage}\" → \"${currentPage}\" (count: ${transitionCount})`);\n }\n\n // Normalize page paths\n const normalizedPrevious = previousPage === '(direct)' || previousPage === '(not set)' ? '(direct)' : this.normalizeRoute(previousPage);\n const normalizedCurrent = this.normalizeRoute(currentPage);\n\n if (this.debug && index < 5) {\n console.log(` Normalized: \"${normalizedPrevious}\" → \"${normalizedCurrent}\"`);\n }\n\n // Only add valid transitions (exclude self-to-self transitions)\n if (normalizedCurrent && transitionCount >= minSessions && normalizedPrevious !== normalizedCurrent) {\n navigationData.push({\n from: normalizedPrevious,\n to: normalizedCurrent,\n count: transitionCount,\n });\n processedCount++;\n\n if (this.debug && index < 5) {\n console.log(` ✅ ACCEPTED`);\n }\n } else {\n filteredCount++;\n\n if (!normalizedCurrent) {\n emptyPathCount++;\n if (this.debug && index < 5) {\n console.log(` ❌ FILTERED: normalized to empty path (likely build artifact)`);\n }\n } else if (transitionCount < minSessions) {\n lowCountCount++;\n if (this.debug && index < 5) {\n console.log(` ❌ FILTERED: transition count ${transitionCount} < minSessions ${minSessions}`);\n }\n } else if (normalizedPrevious === normalizedCurrent) {\n selfTransitionCount++;\n if (this.debug && index < 5) {\n console.log(` ❌ FILTERED: self-to-self transition (user stayed on same page)`);\n }\n }\n }\n });\n\n console.log(`\\n ${'─'.repeat(56)}`);\n console.log(` Processing Summary:`);\n console.log(` ✅ Accepted: ${processedCount}`);\n console.log(` ❌ Filtered out: ${filteredCount}`);\n console.log(` • Empty paths: ${emptyPathCount}`);\n console.log(` • Low transition count: ${lowCountCount}`);\n console.log(` • Self-to-self transitions: ${selfTransitionCount}`);\n\n // Save raw and processed data to files for inspection\n this.saveDataForInspection(rawData, navigationData);\n\n console.log(`\\n${'═'.repeat(60)}`);\n console.log(`📊 STAGE 4: FINAL RESULTS`);\n console.log(`${'═'.repeat(60)}`);\n console.log(` Total valid transitions: ${navigationData.length}`);\n\n if (navigationData.length === 0) {\n console.log(`\\n ⚠️ WARNING: All transitions were filtered out!`);\n console.log(` Check the logs above to see why rows were rejected.`);\n console.log(` Raw data saved to: .bigquery-raw-data/raw-bigquery-response.json`);\n } else {\n // Show top 5 transitions\n console.log(`\\n Top 5 transitions:`);\n navigationData.slice(0, 5).forEach((nav, i) => {\n console.log(` ${i + 1}. ${nav.from} → ${nav.to} (${nav.count})`);\n });\n\n // Show unique routes\n const uniqueRoutes = new Set<string>();\n navigationData.forEach((nav) => {\n if (nav.from !== '(direct)') uniqueRoutes.add(nav.from);\n uniqueRoutes.add(nav.to);\n });\n console.log(`\\n 📊 Unique routes: ${uniqueRoutes.size}`);\n console.log(` Routes: ${Array.from(uniqueRoutes).sort().join(', ')}`);\n\n console.log(`\\n 📁 Data inspection files created:`);\n console.log(` • .bigquery-raw-data/raw-bigquery-response.json`);\n console.log(` • .bigquery-raw-data/processed-navigation-data.json`);\n console.log(` • .bigquery-raw-data/data-transformation-summary.json`);\n }\n\n console.log(`${'═'.repeat(60)}\\n`);\n\n return navigationData;\n } catch (error: unknown) {\n const errorMessage = error instanceof Error ? error.message : String(error) || 'Unknown error';\n\n console.log(`\\n${'═'.repeat(60)}`);\n console.log(`❌ ERROR: QUERY EXECUTION FAILED`);\n console.log(`${'═'.repeat(60)}`);\n\n // Check if this is a permission error\n if (errorMessage.includes('bigquery.jobs.create') || errorMessage.includes('PERMISSION_DENIED')) {\n console.error(` ❌ Permission Denied`);\n console.error(` Service account needs BigQuery Job User role in project: ${this.projectId}`);\n console.error(` Error: ${errorMessage}`);\n } else if (errorMessage.includes('was not found')) {\n console.error(` ❌ Dataset not found`);\n console.error(` Cannot find dataset: ${this.projectId}.${this.datasetId}`);\n console.error(` Try a different location or check dataset name`);\n console.error(` Current location: ${this.location}`);\n console.error(` Error: ${errorMessage}`);\n } else {\n const errorType = error instanceof Error ? error.constructor.name : 'Unknown';\n console.error(` Error type: ${errorType}`);\n console.error(` Message: ${errorMessage}`);\n }\n\n console.log(`${'═'.repeat(60)}\\n`);\n\n throw new Error(\n `BigQuery Analytics error: ${errorMessage}`\n );\n }\n }\n\n\n /**\n * Normalize route paths\n * Converts dynamic segments to parameters and standardizes format\n */\n private normalizeRoute(path: string): string {\n // Filter out build artifacts and non-route paths\n const buildArtifacts = [\n /\\.(js|css|jpg|jpeg|png|gif|svg|webp|woff|woff2|ttf|eot|map)(\\?|#|$)/i,\n /\\[hash\\]/i,\n /\\/chunks\\//i,\n /\\/vendor\\//i,\n /\\/assets\\//i,\n /\\.vite\\//i,\n ];\n\n if (buildArtifacts.some((pattern) => pattern.test(path))) {\n return '';\n }\n\n let normalized = path;\n\n // Remove query parameters and hash\n normalized = normalized.split('?')[0].split('#')[0];\n\n // Remove trailing slash (except for root /)\n if (normalized.length > 1 && normalized.endsWith('/')) {\n normalized = normalized.slice(0, -1);\n }\n\n // Ensure lowercase for consistency (convert spaces to hyphens)\n if (normalized !== '/') {\n normalized = normalized.toLowerCase().replace(/ +/g, '-');\n }\n\n // Replace common ID patterns with :id\n normalized = normalized\n .replace(/\\/[0-9a-f]{24}(?=\\/|$)/gi, '/:id')\n .replace(/\\/[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}(?=\\/|$)/gi, '/:id')\n .replace(/\\/\\d+(?=\\/|$)/g, '/:id')\n .replace(/\\/[\\w.-]+@[\\w.-]+\\.[\\w]+(?=\\/|$)/gi, '/:email')\n .replace(/\\/\\d{4}-\\d{2}-\\d{2}(?=\\/|$)/g, '/:date');\n\n return normalized;\n }\n\n /**\n * Save raw and processed data for inspection\n * Helps identify issues in data transformation pipeline\n */\n private saveDataForInspection(rawData: any[], processedData: NavigationData[]): void {\n try {\n const outputDir = '.bigquery-raw-data';\n const outputPath = join(process.cwd(), outputDir);\n\n // Create directory if it doesn't exist\n mkdirSync(outputPath, { recursive: true });\n\n // Raw data: exactly as it comes from BigQuery\n const rawFile = join(outputPath, 'raw-bigquery-response.json');\n writeFileSync(rawFile, JSON.stringify(rawData, null, 2));\n\n // Processed data: after normalization and filtering\n const processedFile = join(outputPath, 'processed-navigation-data.json');\n writeFileSync(processedFile, JSON.stringify(processedData, null, 2));\n\n // Summary statistics\n const summary = {\n timestamp: new Date().toISOString(),\n rawRowCount: rawData.length,\n processedRowCount: processedData.length,\n dataLoss: rawData.length - processedData.length,\n dataLossPercentage: ((rawData.length - processedData.length) / rawData.length * 100).toFixed(2) + '%',\n totalTransitions: processedData.reduce((sum, d) => sum + d.count, 0),\n uniqueFromRoutes: new Set(processedData.map(d => d.from)).size,\n uniqueToRoutes: new Set(processedData.map(d => d.to)).size,\n topTransitions: processedData.slice(0, 10)\n };\n\n const summaryFile = join(outputPath, 'data-transformation-summary.json');\n writeFileSync(summaryFile, JSON.stringify(summary, null, 2));\n\n if (this.debug) {\n console.log(`\\n📊 Data Inspection Summary:`);\n console.log(` Raw rows from BigQuery: ${summary.rawRowCount}`);\n console.log(` Processed rows (after filtering): ${summary.processedRowCount}`);\n console.log(` Data loss: ${summary.dataLoss} rows (${summary.dataLossPercentage})`);\n console.log(` Total transitions count: ${summary.totalTransitions}`);\n console.log(` Unique source routes: ${summary.uniqueFromRoutes}`);\n console.log(` Unique destination routes: ${summary.uniqueToRoutes}`);\n console.log(`\\n Files saved:`);\n console.log(` • ${rawFile}`);\n console.log(` • ${processedFile}`);\n console.log(` • ${summaryFile}`);\n }\n } catch (error) {\n console.warn(`⚠️ Could not save inspection data:`, error instanceof Error ? error.message : error);\n }\n }\n\n /**\n * Fetch navigation data WITH optional segment information\n * Only includes segment/grouping field when explicitly requested\n * @param config - Data range configuration with optional segmentField\n * @returns Navigation data, optionally with segment field included\n */\n async fetchNavigationWithSegments(config: DataRangeConfig & { segmentField?: string } = {}): Promise<any[]> {\n const { days = 30, segmentField } = config;\n\n // If no segment field is specified, use the base method without segments\n if (!segmentField) {\n console.log(`\\n${'═'.repeat(60)}`);\n console.log(`📊 STAGE 1: PREPARING BIGQUERY QUERY (SEGMENTED)`);\n console.log(`${'═'.repeat(60)}`);\n console.log(` ⚠️ No segment field specified`);\n console.log(` Falling back to fetchNavigationSequences (base data only)`);\n console.log(` To include segments, pass: { segmentField: 'field_name' }`);\n console.log(`${'═'.repeat(60)}\\n`);\n return this.fetchNavigationSequences(config);\n }\n\n console.log(`\\n${'═'.repeat(60)}`);\n console.log(`📊 STAGE 1: PREPARING SEGMENTED BIGQUERY QUERY`);\n console.log(`${'═'.repeat(60)}`);\n console.log(` Project ID: ${this.projectId}`);\n console.log(` Dataset ID: ${this.datasetId}`);\n console.log(` Location: ${this.location}`);\n console.log(` Date range: Last ${days} days`);\n console.log(` Daily tables pattern: events_*`);\n console.log(` Event type filter: page_view`);\n console.log(` Segment field: ${segmentField}`);\n console.log(` Expected fields: user_pseudo_id, ga_session_id, page_path, ${segmentField}`);\n\n try {\n // Query GA4 events for page transitions with optional segment field\n // Only extracts the segment field that was explicitly requested\n const segmentParam = `(SELECT value.string_value FROM UNNEST(event_params) WHERE KEY = '${segmentField}' LIMIT 1) as segment_value`;\n\n const query = `\n WITH page_sessions AS (\n SELECT\n user_pseudo_id,\n (SELECT value.int_value FROM UNNEST(event_params) WHERE KEY = 'ga_session_id' LIMIT 1) as session_id,\n (SELECT value.string_value FROM UNNEST(event_params) WHERE KEY = 'page_path' LIMIT 1) as page_path,\n ${segmentParam},\n event_timestamp,\n ROW_NUMBER() OVER (\n PARTITION BY user_pseudo_id, (SELECT value.int_value FROM UNNEST(event_params) WHERE KEY = 'ga_session_id' LIMIT 1)\n ORDER BY event_timestamp\n ) as page_sequence\n FROM \\`${this.projectId}.${this.datasetId}.events_*\\`\n WHERE\n event_name = 'page_view'\n AND _TABLE_SUFFIX BETWEEN FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE(), INTERVAL ${days} DAY))\n AND FORMAT_DATE('%Y%m%d', CURRENT_DATE())\n AND (SELECT value.string_value FROM UNNEST(event_params) WHERE KEY = 'page_path' LIMIT 1) IS NOT NULL\n ),\n transitions AS (\n SELECT\n COALESCE(curr.page_path, '(direct)') as from_page,\n LEAD(curr.page_path) OVER (\n PARTITION BY curr.user_pseudo_id, curr.session_id\n ORDER BY curr.page_sequence\n ) as to_page,\n COALESCE(curr.segment_value, 'unknown') as segment\n FROM page_sessions curr\n WHERE curr.page_sequence > 0\n )\n SELECT\n from_page as previous_page_path,\n to_page as page_path,\n segment,\n COUNT(*) as transition_count\n FROM transitions\n WHERE to_page IS NOT NULL\n GROUP BY previous_page_path, page_path, segment\n ORDER BY segment, transition_count DESC\n LIMIT 50000\n `;\n\n if (this.debug) {\n console.log(`\\n📤 Full Query with segment field (${segmentField}):`);\n console.log(`${'─'.repeat(60)}`);\n console.log(query);\n console.log(`${'─'.repeat(60)}`);\n }\n\n console.log(`\\n${'═'.repeat(60)}`);\n console.log(`📊 STAGE 2: EXECUTING QUERY`);\n console.log(`${'═'.repeat(60)}`);\n console.log(` ⏳ Querying BigQuery with segment field: ${segmentField}`);\n\n const [rows] = await this.bigquery.query({\n query,\n location: this.location,\n });\n\n console.log(` ✅ Query executed successfully`);\n console.log(` 📈 Total transitions returned: ${rows.length}`);\n\n if (rows.length === 0) {\n console.log(`\\n${'═'.repeat(60)}`);\n console.log(`⚠️ STAGE 2: NO DATA RETURNED!`);\n console.log(`${'═'.repeat(60)}`);\n console.log(` ❌ BigQuery returned 0 rows for segmented query`);\n console.log(` Segment field: ${segmentField}`);\n console.log(` Check if this field exists in your GA4 event_params`);\n console.log(`${'═'.repeat(60)}\\n`);\n return [];\n }\n\n console.log(`\\n${'═'.repeat(60)}`);\n console.log(`📊 STAGE 3: PROCESSING SEGMENTED DATA`);\n console.log(`${'═'.repeat(60)}`);\n console.log(` Processing ${rows.length} raw transitions with segments...`);\n\n const navigationData: any[] = [];\n let processedCount = 0;\n let filteredCount = 0;\n let selfTransitionCount = 0;\n const segmentCounts: Map<string, number> = new Map();\n\n console.log(`\\n ${'─'.repeat(56)}`);\n console.log(` Processing each transition row...`);\n console.log(` ${'─'.repeat(56)}`);\n\n rows.forEach((row: any, index: number) => {\n const previousPage = row.previous_page_path || '(direct)';\n const currentPage = row.page_path || '';\n const transitionCount = parseInt(row.transition_count || '0');\n const segment = row.segment || 'unknown';\n\n if (this.debug && index < 3) {\n console.log(`\\n Row ${index + 1}:`);\n console.log(` Raw: \"${previousPage}\" → \"${currentPage}\" | segment: \"${segment}\" (count: ${transitionCount})`);\n }\n\n const normalizedPrevious = previousPage === '(direct)' || previousPage === '(not set)' ? '(direct)' : this.normalizeRoute(previousPage);\n const normalizedCurrent = this.normalizeRoute(currentPage);\n\n if (this.debug && index < 3) {\n console.log(` Normalized: \"${normalizedPrevious}\" → \"${normalizedCurrent}\" | segment: \"${segment}\"`);\n }\n\n if (normalizedCurrent && transitionCount >= 1 && normalizedPrevious !== normalizedCurrent) {\n navigationData.push({\n from: normalizedPrevious,\n to: normalizedCurrent,\n count: transitionCount,\n segment: segment,\n });\n processedCount++;\n segmentCounts.set(segment, (segmentCounts.get(segment) || 0) + 1);\n\n if (this.debug && index < 3) {\n console.log(` ✅ ACCEPTED`);\n }\n } else {\n filteredCount++;\n if (normalizedPrevious === normalizedCurrent) {\n selfTransitionCount++;\n }\n if (this.debug && index < 3) {\n console.log(` ❌ FILTERED`);\n }\n }\n });\n\n console.log(`\\n ${'─'.repeat(56)}`);\n console.log(` Processing Summary:`);\n console.log(` ✅ Accepted: ${processedCount}`);\n console.log(` ❌ Filtered out: ${filteredCount}`);\n console.log(` • Self-to-self transitions: ${selfTransitionCount}`);\n\n console.log(`\\n${'═'.repeat(60)}`);\n console.log(`📊 STAGE 4: FINAL RESULTS (SEGMENTED)`);\n console.log(`${'═'.repeat(60)}`);\n console.log(` Total valid transitions: ${navigationData.length}`);\n\n if (navigationData.length > 0) {\n // Show detected segments\n const uniqueSegments = Array.from(segmentCounts.keys()).sort();\n console.log(`\\n 📊 Detected segments: ${uniqueSegments.length}`);\n uniqueSegments.forEach(seg => {\n console.log(` • ${seg} (${segmentCounts.get(seg)} transitions)`);\n });\n\n // Show top transitions per segment\n const bySegment = new Map();\n navigationData.forEach((d: any) => {\n if (!bySegment.has(d.segment)) {\n bySegment.set(d.segment, []);\n }\n bySegment.get(d.segment).push(d);\n });\n\n bySegment.forEach((transitions: any[], segment: string) => {\n console.log(`\\n Top 3 transitions for segment \"${segment}\":`);\n transitions\n .sort((a, b) => b.count - a.count)\n .slice(0, 3)\n .forEach((nav: any, i: number) => {\n console.log(` ${i + 1}. ${nav.from} → ${nav.to} (${nav.count})`);\n });\n });\n } else {\n console.log(` ⚠️ WARNING: All transitions were filtered out!`);\n }\n\n console.log(`${'═'.repeat(60)}\\n`);\n\n return navigationData;\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Unknown error';\n\n console.log(`\\n${'═'.repeat(60)}`);\n console.log(`❌ ERROR: SEGMENTED QUERY EXECUTION FAILED`);\n console.log(`${'═'.repeat(60)}`);\n console.log(` Segment field: ${segmentField}`);\n console.log(` Error: ${errorMessage}`);\n console.log(`${'═'.repeat(60)}\\n`);\n\n console.warn(`⚠️ Failed to fetch navigation data with segments: ${errorMessage}`);\n return [];\n }\n }\n\n}\n","/**\n * Markov Chain Model Trainer\n * Builds a Markov chain from user navigation data\n * Probability: P(dest | src) = count(src→dest) / total_transitions_from_src\n */\n\nimport type {\n NavigationData,\n PrefetchModel,\n ModelConfig,\n PrefetchTarget,\n RouteMetadata,\n} from '../../types';\n\nexport class MarkovChainTrainer {\n private config: ModelConfig;\n private debug: boolean;\n\n constructor(config: ModelConfig, debug = false) {\n this.config = config;\n this.debug = debug;\n }\n\n /**\n * Train Markov chain model from navigation data\n * Calculates transition probabilities: P(dest | src) = transitions(src→dest) / total_from_src\n */\n trainMLModel(\n navigationData: NavigationData[],\n environment: string\n ): PrefetchModel {\n if (this.debug) {\n console.log(`\\n🤖 Training Markov Chain Model...`);\n console.log(` Model type: ${this.config.type}`);\n console.log(` Threshold: ${this.config.threshold * 100}%`);\n console.log(` Max prefetch per route: ${this.config.maxPrefetch}`);\n console.log(` Input transitions: ${navigationData.length}`);\n }\n\n // Build navigation graph: sourceRoute -> { targetRoute: count }\n const navigationGraph = this.buildNavigationGraph(navigationData);\n const routes = this.extractRoutes(navigationData);\n\n if (this.debug) {\n console.log(`\\n 📊 Analysis:`);\n console.log(` Unique routes: ${routes.size}`);\n console.log(` Routes: ${Array.from(routes).sort().join(', ')}`);\n console.log(` Source routes: ${navigationGraph.size}`);\n }\n\n // Calculate Markov probabilities: P(dest | src) = count(src→dest) / total_from_src\n const predictions = this.calculateMarkovProbabilities(navigationGraph);\n\n if (this.debug) {\n console.log(`\\n Predictions generated:`);\n console.log(` Routes with predictions: ${predictions.size}`);\n const totalTargets = Array.from(predictions.values()).reduce(\n (sum, targets) => sum + targets.length,\n 0\n );\n console.log(` Total prefetch targets: ${totalTargets}`);\n }\n\n // Build PrefetchModel\n const model: PrefetchModel = {\n version: '1.0.0',\n generatedAt: new Date().toISOString(),\n environment,\n config: this.config,\n dataSource: {\n provider: 'markov-chain',\n dateRange: this.getDateRange(30),\n totalSessions: navigationData.reduce((sum, d) => sum + d.count, 0),\n totalRoutes: routes.size,\n },\n routes: {},\n };\n\n // Populate predictions\n predictions.forEach((targets, source) => {\n model.routes[source] = {\n prefetch: targets,\n metadata: this.calculateMetadata(navigationGraph, source),\n };\n });\n\n if (this.debug) {\n console.log(`\\n ✅ Model trained successfully`);\n const sampleRoutes = Array.from(predictions.entries()).slice(0, 3);\n if (sampleRoutes.length > 0) {\n console.log(`\\n Sample predictions:`);\n sampleRoutes.forEach(([source, targets]) => {\n console.log(` ${source}:`);\n targets.forEach((target) => {\n console.log(\n ` → ${target.route} (${(target.probability * 100).toFixed(1)}%, ${target.priority})`\n );\n });\n });\n }\n }\n\n return model;\n }\n\n /**\n * Extract all unique routes from navigation data\n */\n private extractRoutes(data: NavigationData[]): Set<string> {\n const routes = new Set<string>();\n\n data.forEach((d) => {\n routes.add(d.from);\n routes.add(d.to);\n });\n\n return routes;\n }\n\n /**\n * Build navigation graph from user navigation patterns\n * Graph represents: sourceRoute -> { targetRoute: transitionCount }\n */\n private buildNavigationGraph(\n data: NavigationData[]\n ): Map<string, Map<string, number>> {\n const graph = new Map<string, Map<string, number>>();\n\n data.forEach(({ from, to, count }) => {\n if (!graph.has(from)) {\n graph.set(from, new Map());\n }\n\n const targets = graph.get(from)!;\n targets.set(to, (targets.get(to) || 0) + count);\n });\n\n return graph;\n }\n\n /**\n * Calculate Markov probabilities with normalization\n * P(dest | src) = count(src→dest) / total_transitions_from_src\n * Then normalizes scores to 0-1 range\n */\n private calculateMarkovProbabilities(\n navigationGraph: Map<string, Map<string, number>>\n ): Map<string, PrefetchTarget[]> {\n const predictions = new Map<string, PrefetchTarget[]>();\n\n navigationGraph.forEach((targets, source) => {\n const targetArray: PrefetchTarget[] = [];\n\n // Calculate total transitions from this source\n const totalFromSource = Array.from(targets.values()).reduce(\n (sum, count) => sum + count,\n 0\n );\n\n if (totalFromSource === 0) return;\n\n // Calculate base probability for each destination: P(dest | src) = count / total\n const probabilities = new Map<string, number>();\n targets.forEach((count, destination) => {\n probabilities.set(destination, count / totalFromSource);\n });\n\n // Normalize probabilities to 0-1 range\n const maxProb = Math.max(...Array.from(probabilities.values()));\n if (maxProb > 0) {\n probabilities.forEach((prob, dest) => {\n probabilities.set(dest, prob / maxProb);\n });\n }\n\n // Sort by probability (descending)\n const sorted = Array.from(probabilities.entries())\n .sort((a, b) => b[1] - a[1])\n .slice(0, this.config.maxPrefetch);\n\n // Apply threshold and create targets\n sorted.forEach(([route, probability]) => {\n if (probability >= this.config.threshold) {\n targetArray.push({\n route,\n probability,\n count: targets.get(route) || 0,\n priority: this.getPriority(probability),\n });\n }\n });\n\n if (targetArray.length > 0) {\n predictions.set(source, targetArray);\n }\n });\n\n return predictions;\n }\n\n /**\n * Determine priority based on ML confidence score\n */\n private getPriority(score: number): 'high' | 'medium' | 'low' {\n if (score >= 0.7) return 'high';\n if (score >= 0.4) return 'medium';\n return 'low';\n }\n\n /**\n * Calculate metadata for a route\n */\n private calculateMetadata(\n navigationGraph: Map<string, Map<string, number>>,\n route: string\n ): RouteMetadata {\n const targets = navigationGraph.get(route);\n\n if (!targets || targets.size === 0) {\n return {\n totalTransitions: 0,\n topDestination: '',\n };\n }\n\n const totalTransitions = Array.from(targets.values()).reduce(\n (sum, count) => sum + count,\n 0\n );\n\n // Find top destination\n let topDestination = '';\n let maxCount = 0;\n targets.forEach((count, targetRoute) => {\n if (count > maxCount) {\n maxCount = count;\n topDestination = targetRoute;\n }\n });\n\n return {\n totalTransitions,\n topDestination,\n };\n }\n\n /**\n * Train segment-specific Markov models from navigation data with segment field\n * Creates separate models for each user segment/role\n */\n trainSegmentedModels(\n navigationDataWithSegments: any[],\n environment: string\n ): Map<string, PrefetchModel> {\n if (this.debug) {\n console.log(`\\n🤖 Training Segment-Specific Markov Models...`);\n }\n\n // Group data by segment\n const dataBySegment = new Map<string, NavigationData[]>();\n\n navigationDataWithSegments.forEach((data) => {\n const segment = data.segment || 'default';\n if (!dataBySegment.has(segment)) {\n dataBySegment.set(segment, []);\n }\n dataBySegment.get(segment)!.push({\n from: data.from,\n to: data.to,\n count: data.count,\n });\n });\n\n if (this.debug) {\n console.log(`\\n 📊 Detected segments:`);\n dataBySegment.forEach((data, segment) => {\n console.log(` • ${segment}: ${data.length} transitions`);\n });\n }\n\n // Train a model for each segment\n const segmentModels = new Map<string, PrefetchModel>();\n dataBySegment.forEach((navigationData, segment) => {\n if (this.debug) {\n console.log(`\\n 🔄 Training model for segment: \"${segment}\"`);\n }\n\n const model = this.trainMLModel(navigationData, environment);\n\n // Add segment info to model\n model.dataSource!.provider = `markov-chain[${segment}]`;\n\n segmentModels.set(segment, model);\n\n if (this.debug) {\n const totalTargets = Object.values(model.routes).reduce(\n (sum, route) => sum + (route.prefetch?.length || 0),\n 0\n );\n console.log(` ✅ Model for \"${segment}\" trained with ${totalTargets} prefetch targets`);\n }\n });\n\n if (this.debug) {\n console.log(`\\n ✅ All ${segmentModels.size} segment models trained successfully`);\n }\n\n return segmentModels;\n }\n\n /**\n * Get date range string\n */\n private getDateRange(days: number): string {\n const end = new Date();\n const start = new Date();\n start.setDate(start.getDate() - days);\n\n return `${start.toISOString().split('T')[0]} to ${end.toISOString().split('T')[0]}`;\n }\n}\n\n// Export with old name for backward compatibility\nexport { MarkovChainTrainer as GuessJSMLTrainer };\n","/**\n * Configuration Generator\n * Maps routes to Vite chunks and generates final prefetch configuration\n */\n\nimport type {\n PrefetchModel,\n PrefetchConfig,\n ViteManifest,\n ManualRules,\n PrefetchTarget,\n} from '../types';\n\nexport class ConfigGenerator {\n private manifest: ViteManifest;\n private manualRules: ManualRules;\n private debug: boolean;\n private vite: any = null;\n private isDev: boolean = false;\n\n /**\n * NOTE: Hardcoded route/component mappings have been REMOVED to make the plugin generic.\n * The plugin now uses dynamic strategies (direct match, pattern match, fuzzy match)\n * to discover routes from the Vite manifest and actual file structure.\n *\n * This allows the plugin to work with ANY project structure without project-specific\n * configuration hardcoded in the plugin code.\n */\n\n constructor(manifest: ViteManifest, manualRules: ManualRules = {}, debug = false, vite?: any) {\n this.manifest = manifest;\n this.manualRules = manualRules;\n this.debug = debug;\n this.vite = vite || null;\n this.isDev = !!vite; // If vite is provided, we're in dev mode\n }\n\n /**\n * Generate final prefetch configuration with chunk mappings\n * Includes common prefetch rules and segment-specific rules if available\n */\n generate(model: PrefetchModel): PrefetchConfig {\n if (this.debug) {\n console.log(`\\n📦 Generating prefetch configuration...`);\n console.log(` Manifest entries: ${Object.keys(this.manifest).length}`);\n console.log(` Model routes: ${Object.keys(model.routes).length}`);\n console.log(` Manual rules: ${Object.keys(this.manualRules).length}`);\n if (Object.values(model.routes).some(r => r.segments)) {\n console.log(` ℹ️ Segment-based rules detected`);\n }\n }\n\n // Merge manual rules into model\n const mergedModel = this.mergeManualRules(model);\n\n // Extract route patterns for dynamic route matching (TanStack Router support)\n const routePatterns = this.extractRoutePatterns(Object.keys(mergedModel.routes));\n\n // Map routes to chunks\n const config: PrefetchConfig = {\n version: model.version,\n generatedAt: model.generatedAt,\n environment: model.environment,\n dataSource: model.dataSource!,\n model: {\n type: model.config!.type,\n threshold: model.config!.threshold,\n maxPrefetch: model.config!.maxPrefetch,\n },\n routePatterns, // NEW: Include route patterns for dynamic matching\n routes: {},\n chunks: {},\n };\n\n let mappedRoutes = 0;\n let unmappedRoutes = 0;\n let totalSegmentRules = 0;\n\n // Process each route\n Object.entries(mergedModel.routes).forEach(([sourceRoute, prediction]) => {\n const prefetchTargets: Array<PrefetchTarget & { chunk: string }> = [];\n const segmentConfigs: Record<string, Array<PrefetchTarget & { chunk: string }>> = {};\n\n // Also map the source route's own chunk (so it can be used as a destination elsewhere)\n const sourceChunk = this.routeToChunk(sourceRoute);\n if (sourceChunk && !config.chunks[sourceRoute]) {\n config.chunks[sourceRoute] = sourceChunk;\n }\n\n // Process common prefetch rules\n prediction.prefetch.forEach((target) => {\n const chunkFile = this.routeToChunk(target.route);\n\n if (chunkFile) {\n // Get the manifest entry for this chunk to extract imports\n const manifestEntry = this.getManifestEntryByFile(chunkFile);\n const importChunkIds = manifestEntry?.imports || [];\n\n // Resolve import chunk IDs to actual file paths\n const imports = importChunkIds\n .map((chunkId) => {\n const entry = this.manifest[chunkId];\n return entry?.file;\n })\n .filter((file): file is string => !!file);\n\n prefetchTargets.push({\n ...target,\n chunk: chunkFile,\n chunk_prod: chunkFile, // NEW: Include production chunk path\n imports: imports, // Include dependency chunks (resolved to file paths)\n });\n\n // Add to chunks lookup\n config.chunks[target.route] = chunkFile;\n mappedRoutes++;\n\n // Enhanced debug logging\n if (this.debug) {\n console.log(` ✅ ${sourceRoute} → ${target.route}`);\n console.log(` Chunk: ${chunkFile}`);\n if (imports.length > 0) {\n console.log(` Dependencies: ${imports.join(', ')}`);\n }\n }\n } else {\n if (this.debug) {\n console.log(` ⚠️ No chunk found for route: ${target.route}`);\n console.log(` Attempted to map using routeToChunk()`);\n }\n unmappedRoutes++;\n }\n });\n\n // Process segment-specific rules if available\n if (prediction.segments) {\n Object.entries(prediction.segments).forEach(([segment, segmentTargets]) => {\n const segmentPrefetchTargets: Array<PrefetchTarget & { chunk: string }> = [];\n\n segmentTargets.forEach((target) => {\n const chunkFile = this.routeToChunk(target.route);\n\n if (chunkFile) {\n const manifestEntry = this.getManifestEntryByFile(chunkFile);\n const importChunkIds = manifestEntry?.imports || [];\n\n const imports = importChunkIds\n .map((chunkId) => {\n const entry = this.manifest[chunkId];\n return entry?.file;\n })\n .filter((file): file is string => !!file);\n\n segmentPrefetchTargets.push({\n ...target,\n chunk: chunkFile,\n chunk_prod: chunkFile, // NEW: Include production chunk path\n imports: imports,\n });\n\n config.chunks[target.route] = chunkFile;\n totalSegmentRules++;\n }\n });\n\n if (segmentPrefetchTargets.length > 0) {\n segmentConfigs[segment] = segmentPrefetchTargets;\n }\n });\n\n if (this.debug && Object.keys(segmentConfigs).length > 0) {\n console.log(` 👥 Segment configs for ${sourceRoute}: ${Object.keys(segmentConfigs).join(', ')}`);\n }\n }\n\n // Get patterns for this route for dynamic matching (TanStack Router support)\n const patterns = routePatterns[sourceRoute] || [sourceRoute];\n\n // Only include routes with valid chunk mappings\n if (prefetchTargets.length > 0 || Object.keys(segmentConfigs).length > 0) {\n config.routes[sourceRoute] = {\n patterns, // NEW: Include patterns for dynamic route matching\n prefetch: prefetchTargets,\n ...(Object.keys(segmentConfigs).length > 0 && {\n segments: segmentConfigs,\n }),\n metadata: prediction.metadata,\n };\n }\n });\n\n if (this.debug) {\n console.log(`✅ Configuration generated`);\n console.log(` Routes with prefetch: ${Object.keys(config.routes).length}`);\n console.log(` Mapped chunks: ${mappedRoutes}`);\n console.log(` Segment-specific rules: ${totalSegmentRules}`);\n console.log(` Unmapped routes: ${unmappedRoutes}`);\n }\n\n // Add segment info if any routes have segments\n const allSegments = new Set<string>();\n Object.values(config.routes).forEach(route => {\n if (route.segments) {\n Object.keys(route.segments).forEach(seg => allSegments.add(seg));\n }\n });\n\n if (allSegments.size > 0) {\n config.segmentInfo = {\n available: Array.from(allSegments),\n description: 'Load segment-specific config based on user role/segment'\n };\n }\n\n return config;\n }\n\n /**\n * Merge manual rules into model\n * Manual rules take precedence over ML predictions\n */\n private mergeManualRules(model: PrefetchModel): PrefetchModel {\n const merged = { ...model, routes: { ...model.routes } };\n\n Object.entries(this.manualRules).forEach(([sourceRoute, targetRoutes]) => {\n if (!merged.routes[sourceRoute]) {\n merged.routes[sourceRoute] = {\n prefetch: [],\n };\n }\n\n // Add manual rules with high priority\n targetRoutes.forEach((targetRoute) => {\n // Check if this rule already exists\n const existing = merged.routes[sourceRoute].prefetch.find(\n (t) => t.route === targetRoute\n );\n\n if (existing) {\n // Update existing with manual flag and high priority\n existing.manual = true;\n existing.priority = 'high';\n existing.probability = 1.0;\n } else {\n // Add new manual rule\n merged.routes[sourceRoute].prefetch.unshift({\n route: targetRoute,\n probability: 1.0,\n count: 0, // Not from analytics\n priority: 'high',\n manual: true,\n });\n }\n });\n\n if (this.debug) {\n console.log(` ✅ Added manual rule: ${sourceRoute} → [${targetRoutes.join(', ')}]`);\n }\n });\n\n return merged;\n }\n\n /**\n * Map BigQuery route to Vite manifest chunk file\n *\n * The routes come from BigQuery navigation data (e.g., /purchase-order, /dispatch-order/:id)\n * We match them directly to manifest entries without trying to discover routes.\n *\n * Strategy: Match route segments against manifest file paths, ignoring hash suffixes\n * Example:\n * Route: /purchase-order/:id\n * Normalized: /purchase-order\n * Manifest: src/pages/purchase-order/index.tsx → {file: assets/purchase-order-abc123.js}\n * Match: YES → return assets/purchase-order-abc123.js\n */\n private routeToChunk(route: string): string | null {\n // Step 1: Normalize route - remove dynamic parameters (:id, $id, etc)\n const normalizedRoute = route.replace(/\\/[:$]\\w+/g, '');\n\n // Step 2: Extract route segments for matching\n // /purchase-order/search → ['purchase-order', 'search']\n const routeSegments = normalizedRoute.split('/').filter(Boolean);\n\n if (routeSegments.length === 0) {\n // Root route - look for src/pages/index.tsx or src/app.tsx\n const candidates = Object.entries(this.manifest).filter(([path]) =>\n path === 'src/pages/index.tsx' ||\n path === 'src/app.tsx' ||\n path === 'src/App.tsx' ||\n path === 'src/main.tsx'\n );\n if (candidates.length > 0) return candidates[0][1].file;\n return null;\n }\n\n // Step 3: Search manifest for entries matching these segments\n // Priority:\n // 1. Exact path match: src/pages/purchase-order/index.tsx\n // 2. Segment match: any manifest entry containing all route segments\n const candidates = Object.entries(this.manifest)\n .filter(([path]) => {\n // Only consider source files, not dependencies\n if (path.startsWith('node_modules') || path.startsWith('_')) {\n return false;\n }\n\n const pathLower = path.toLowerCase();\n\n // Check if path contains ALL route segments in order\n // For route /purchase-order/search:\n // - src/pages/purchase-order/search/index.tsx ✓\n // - src/pages/purchase-order/search.tsx ✓\n // - src/features/purchase-order/search/index.tsx ✓\n return routeSegments.every(segment =>\n pathLower.includes(segment.toLowerCase())\n );\n })\n .sort(([pathA], [pathB]) => {\n // Scoring: higher score = better match\n let scoreA = 0;\n let scoreB = 0;\n\n // Prefer src/pages/ over src/features/\n if (pathA.includes('/pages/')) scoreA += 10;\n if (pathB.includes('/pages/')) scoreB += 10;\n\n // Prefer index.tsx (entry point)\n if (pathA.includes('index.tsx')) scoreA += 8;\n if (pathB.includes('index.tsx')) scoreB += 8;\n\n if (pathA.includes('index.ts')) scoreA += 7;\n if (pathB.includes('index.ts')) scoreB += 7;\n\n // Prefer exact segment structure\n // Route: /purchase-order/search\n // src/pages/purchase-order/search/index.tsx is better than src/pages/purchase-order-search/index.tsx\n const pathASegments = pathA.split('/').map(s => s.toLowerCase()).filter(s => s && !s.startsWith('.'));\n const pathBSegments = pathB.split('/').map(s => s.toLowerCase()).filter(s => s && !s.startsWith('.'));\n\n const matchCountA = routeSegments.filter(seg =>\n pathASegments.some(ps => ps.includes(seg.toLowerCase()))\n ).length;\n const matchCountB = routeSegments.filter(seg =>\n pathBSegments.some(ps => ps.includes(seg.toLowerCase()))\n ).length;\n\n scoreA += matchCountA * 5;\n scoreB += matchCountB * 5;\n\n return scoreB - scoreA; // Higher score first\n });\n\n if (candidates.length > 0) {\n const manifestEntry = candidates[0][1];\n if (this.debug) {\n console.log(` ✅ Found chunk for route ${route}`);\n console.log(` Manifest: ${candidates[0][0]}`);\n console.log(` Chunk file: ${manifestEntry.file}`);\n }\n return manifestEntry.file;\n }\n\n if (this.debug) {\n console.log(` ⚠️ No chunk found for route: ${route}`);\n console.log(` Searched for segments: ${routeSegments.join(', ')}`);\n }\n\n return null;\n }\n\n\n /**\n * Get manifest entry by file name\n */\n private getManifestEntryByFile(fileName: string) {\n return Object.values(this.manifest).find((entry) => entry.file === fileName);\n }\n\n /**\n * Get all chunks referenced in config\n */\n getReferencedChunks(config: PrefetchConfig): string[] {\n return Object.values(config.chunks);\n }\n\n /**\n * Validate that all chunks exist in manifest\n */\n validateChunks(config: PrefetchConfig): {\n valid: boolean;\n missing: string[];\n } {\n const missing: string[] = [];\n const manifestFiles = new Set(Object.values(this.manifest).map((e) => e.file));\n\n Object.entries(config.chunks).forEach(([route, chunk]) => {\n if (!manifestFiles.has(chunk)) {\n missing.push(`${route} -> ${chunk}`);\n }\n });\n\n return {\n valid: missing.length === 0,\n missing,\n };\n }\n\n /**\n * Extract route patterns for dynamic route matching\n * Groups routes by their base path and includes pattern variants\n * E.g., /purchase-order and /purchase-order/:id become patterns for matching\n */\n private extractRoutePatterns(routes: string[]): Record<string, string[]> {\n const patterns: Record<string, string[]> = {};\n\n for (const route of routes) {\n // Check if route contains dynamic parameters (:param or $param for TanStack)\n if (route.includes(':') || route.includes('$')) {\n // This is a dynamic route pattern - keep as-is\n patterns[route] = [route];\n\n // Also add the base route if it exists and is different\n const base = route.split(/[:$]/)[0];\n if (base && base !== route) {\n // Ensure base route also gets patterns\n if (!patterns[base]) {\n patterns[base] = [base, route];\n } else if (!patterns[base].includes(route)) {\n patterns[base].push(route);\n }\n }\n } else {\n // Static route - just use itself\n patterns[route] = [route];\n }\n }\n\n if (this.debug && Object.keys(patterns).length > 0) {\n console.log(`\\n🔍 Extracted route patterns for dynamic matching:`);\n Object.entries(patterns).forEach(([route, patternList]) => {\n if (patternList.length > 1) {\n console.log(` ${route} → [${patternList.join(', ')}]`);\n }\n });\n }\n\n return patterns;\n }\n\n /**\n * Match a pathname against route patterns\n * Supports both static routes and dynamic routes with parameters\n */\n private matchRoutePattern(pathname: string, pattern: string): boolean {\n // Convert route pattern to regex\n // E.g., /purchase-order/:id → /purchase-order/[^/]+\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 /**\n * Find matching route pattern for a given pathname\n * Used by hooks to match actual navigation paths to config routes\n */\n findMatchingPattern(\n pathname: string,\n routes: Record<string, any>\n ): string | null {\n for (const [route, config] of Object.entries(routes)) {\n const patterns = (config as any).patterns || [route];\n for (const pattern of patterns) {\n if (this.matchRoutePattern(pathname, pattern)) {\n return route;\n }\n }\n }\n return null;\n }\n\n /**\n * Generate segment-specific prefetch configurations\n * Creates one config per user segment/role\n */\n generateSegmentConfigs(\n segmentModels: Map<string, PrefetchModel>\n ): Map<string, PrefetchConfig> {\n const segmentConfigs = new Map<string, PrefetchConfig>();\n\n segmentModels.forEach((model, segment) => {\n if (this.debug) {\n console.log(`\\n📦 Generating config for segment: \"${segment}\"`);\n }\n\n const config = this.generate(model);\n\n // Add segment metadata to config\n (config as any).segment = segment;\n\n segmentConfigs.set(segment, config);\n\n if (this.debug) {\n console.log(` ✅ Config generated for \"${segment}\"`);\n console.log(` Routes: ${Object.keys(config.routes).length}`);\n console.log(` Chunks: ${Object.keys(config.chunks).length}`);\n }\n });\n\n if (this.debug) {\n console.log(`\\n✅ Generated ${segmentConfigs.size} segment-specific configurations`);\n }\n\n return segmentConfigs;\n }\n}\n","/**\n * Cache Manager\n * Manages caching of trained models to avoid redundant GA API calls\n * Uses Node.js fs to cache models locally during build time\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport type { PrefetchModel, CacheConfig } from '../types';\n\nexport class CacheManager {\n private cacheDir: string;\n private ttl: number;\n private enabled: boolean;\n private debug: boolean;\n\n constructor(config: CacheConfig = {}, debug = false) {\n this.enabled = config.enabled ?? true; // Enabled by default\n this.ttl = config.ttl ?? 24 * 60 * 60 * 1000; // Default: 24 hours\n this.cacheDir = config.path ?? path.join(process.cwd(), '.prefetch-cache');\n this.debug = debug;\n\n if (this.enabled && !fs.existsSync(this.cacheDir)) {\n fs.mkdirSync(this.cacheDir, { recursive: true });\n if (this.debug) {\n console.log(`📁 Created cache directory: ${this.cacheDir}`);\n }\n }\n }\n\n /**\n * Get cached model for environment\n * Returns null if cache doesn't exist or is expired\n */\n async get(environment: string): Promise<PrefetchModel | null> {\n if (!this.enabled) {\n if (this.debug) console.log('⏭️ Cache disabled, skipping cache lookup');\n return null;\n }\n\n try {\n const cacheFile = path.join(this.cacheDir, `${environment}.json`);\n\n if (!fs.existsSync(cacheFile)) {\n if (this.debug) console.log(`📦 Cache miss for environment: ${environment}`);\n return null;\n }\n\n const stats = fs.statSync(cacheFile);\n const cacheAge = Date.now() - stats.mtimeMs;\n\n if (cacheAge > this.ttl) {\n if (this.debug) console.log(`⏰ Cache expired for ${environment} (${Math.round(cacheAge / 1000 / 60)} minutes old)`);\n fs.unlinkSync(cacheFile);\n return null;\n }\n\n const cachedData = fs.readFileSync(cacheFile, 'utf-8');\n const model: PrefetchModel = JSON.parse(cachedData);\n\n if (this.debug) {\n console.log(`✅ Cache hit for environment: ${environment} (${Math.round(cacheAge / 1000)} seconds old)`);\n console.log(` Cached model has ${Object.keys(model.routes).length} routes`);\n }\n\n return model;\n } catch (error) {\n console.error(`❌ Error reading cache for ${environment}:`, error);\n return null;\n }\n }\n\n /**\n * Save model to cache\n */\n async set(environment: string, model: PrefetchModel): Promise<void> {\n if (!this.enabled) {\n if (this.debug) console.log('⏭️ Cache disabled, skipping cache write');\n return;\n }\n\n try {\n const cacheFile = path.join(this.cacheDir, `${environment}.json`);\n fs.writeFileSync(cacheFile, JSON.stringify(model, null, 2), 'utf-8');\n\n if (this.debug) {\n console.log(`💾 Cached model for ${environment}`);\n console.log(` Location: ${cacheFile}`);\n console.log(` Routes: ${Object.keys(model.routes).length}`);\n }\n } catch (error) {\n console.error(`❌ Error writing cache for ${environment}:`, error);\n }\n }\n\n /**\n * Invalidate cache for specific environment or all environments\n */\n async invalidate(environment?: string): Promise<void> {\n if (!this.enabled) return;\n\n try {\n if (environment) {\n const cacheFile = path.join(this.cacheDir, `${environment}.json`);\n if (fs.existsSync(cacheFile)) {\n fs.unlinkSync(cacheFile);\n if (this.debug) {\n console.log(`🗑️ Invalidated cache for ${environment}`);\n }\n }\n } else {\n // Clear all cache files\n const files = fs.readdirSync(this.cacheDir);\n files.forEach((file) => {\n if (file.endsWith('.json')) {\n fs.unlinkSync(path.join(this.cacheDir, file));\n }\n });\n if (this.debug) {\n console.log(`🗑️ Cleared all cache files`);\n }\n }\n } catch (error) {\n console.error(`❌ Error invalidating cache:`, error);\n }\n }\n\n /**\n * Get cache statistics\n */\n getStats(): {\n enabled: boolean;\n cacheDir: string;\n ttl: number;\n cachedEnvironments: string[];\n totalSize: number;\n } {\n const cachedEnvironments: string[] = [];\n let totalSize = 0;\n\n if (this.enabled && fs.existsSync(this.cacheDir)) {\n const files = fs.readdirSync(this.cacheDir);\n files.forEach((file) => {\n if (file.endsWith('.json')) {\n const filePath = path.join(this.cacheDir, file);\n const stats = fs.statSync(filePath);\n cachedEnvironments.push(file.replace('.json', ''));\n totalSize += stats.size;\n }\n });\n }\n\n return {\n enabled: this.enabled,\n cacheDir: this.cacheDir,\n ttl: this.ttl,\n cachedEnvironments,\n totalSize,\n };\n }\n\n /**\n * Check if cache exists and is valid for environment\n */\n async isValid(environment: string): Promise<boolean> {\n if (!this.enabled) return false;\n\n try {\n const cacheFile = path.join(this.cacheDir, `${environment}.json`);\n\n if (!fs.existsSync(cacheFile)) {\n return false;\n }\n\n const stats = fs.statSync(cacheFile);\n const cacheAge = Date.now() - stats.mtimeMs;\n\n return cacheAge <= this.ttl;\n } catch {\n return false;\n }\n }\n\n /**\n * Get cache age in milliseconds\n */\n async getCacheAge(environment: string): Promise<number | null> {\n if (!this.enabled) return null;\n\n try {\n const cacheFile = path.join(this.cacheDir, `${environment}.json`);\n\n if (!fs.existsSync(cacheFile)) {\n return null;\n }\n\n const stats = fs.statSync(cacheFile);\n return Date.now() - stats.mtimeMs;\n } catch {\n return null;\n }\n }\n}\n","/**\n * Main Vite Plugin\n * Integrates all components and provides Vite hooks\n */\n\nimport type { Plugin, ResolvedConfig } from 'vite';\nimport { BigQueryAnalyticsConnector } from './analytics/bigquery-connector';\nimport { GuessJSMLTrainer } from './model/guessjs-ml-trainer';\nimport { ConfigGenerator } from './config-generator';\nimport { CacheManager } from './cache-manager';\nimport type {\n PluginOptions,\n PrefetchModel,\n ViteManifest,\n} from '../types';\n\nexport function smartPrefetch(options: PluginOptions = {}): Plugin {\n const {\n framework = 'react',\n strategy = 'hybrid',\n analytics,\n manualRules = {},\n cache = {},\n advanced = {},\n } = options;\n\n const debug = advanced.debug ?? false;\n\n let config: ResolvedConfig;\n let cacheManager: CacheManager;\n let prefetchModel: PrefetchModel | null = null;\n let segmentModels: Map<string, PrefetchModel> | null = null;\n\n return {\n name: '@farmart/vite-plugin-smart-prefetch',\n enforce: 'post',\n\n async configResolved(resolvedConfig) {\n config = resolvedConfig;\n\n // Ensure Vite manifest is enabled\n if (!config.build.manifest) {\n config.build.manifest = true;\n if (debug) {\n console.log('✅ Enabled Vite manifest generation');\n }\n }\n\n // Initialize cache manager\n cacheManager = new CacheManager(cache, debug);\n\n if (debug) {\n console.log('\\n🚀 Smart Prefetch Plugin Initialized');\n console.log(` Framework: ${framework}`);\n console.log(` Strategy: ${strategy}`);\n console.log(` Analytics: ${analytics ? 'enabled' : 'disabled'}`);\n console.log(` Manual rules: ${Object.keys(manualRules).length}`);\n console.log(` Cache: ${cache.enabled !== false ? 'enabled' : 'disabled'}`);\n }\n\n // In development mode, generate prefetch config for testing\n if (config.command === 'serve' && debug) {\n // Create a simple dev-time manifest for testing\n const devManifest: ViteManifest = {};\n\n // Create entries for all manual rules\n Object.keys(manualRules).forEach((route) => {\n const routeKey = `src/features${route}/index.tsx`;\n devManifest[routeKey] = {\n file: `features${route.replace(/\\//g, '-')}.js`,\n imports: [],\n };\n });\n\n // Also try to discover routes from src/pages directory\n const fs = await import('node:fs');\n const path = await import('node:path');\n const pagesDir = path.join(config.root, 'src/pages');\n\n if (fs.existsSync(pagesDir)) {\n const files = fs.readdirSync(pagesDir);\n files.forEach((file) => {\n if (file.endsWith('.tsx') || file.endsWith('.ts')) {\n const pageName = file.replace(/\\.(tsx|ts)$/, '');\n const routeKey = `src/pages/${file}`;\n devManifest[routeKey] = {\n file: `chunks/${pageName}-[hash].js`,\n imports: [],\n };\n }\n });\n }\n\n // Store for use in transformIndexHtml\n (config as any).__smartPrefetchDevManifest = devManifest;\n }\n },\n\n configureServer(server) {\n // In development mode, serve the prefetch-config.json dynamically\n // This ensures we always use the latest model instead of stale [hash] placeholders\n return () => {\n server.middlewares.use('/prefetch-config.json', async (req, res, next) => {\n if (req.method !== 'GET') {\n next();\n return;\n }\n\n try {\n // In dev mode, always generate a fresh config with current model\n if (!prefetchModel) {\n if (debug) {\n console.warn('⚠️ No prefetch model available yet');\n }\n res.statusCode = 503;\n res.end(JSON.stringify({ error: 'Prefetch model not ready, still loading analytics data...' }));\n return;\n }\n\n // Generate config dynamically on each request (dev only)\n // Create a minimal manifest for dev mode - just file paths without real hashes\n const devManifest: ViteManifest = {};\n\n // Map model routes to dev manifest entries\n Object.keys(prefetchModel.routes).forEach((route) => {\n // Create a fake but consistent manifest entry for dev\n const routeKey = `src/pages${route}/index.tsx`;\n const routeName = route.split('/').filter(Boolean).pop() || 'index';\n const devHash = 'dev-' + routeName.slice(0, 6).padEnd(8, '0');\n devManifest[routeKey] = {\n file: `chunks/${routeName}-${devHash}.js`,\n imports: [],\n };\n });\n\n // Generate final config with dev manifest and Vite server instance for chunk discovery\n const generator = new ConfigGenerator(devManifest as ViteManifest, manualRules, debug, server);\n const finalConfig = generator.generate(prefetchModel);\n\n res.setHeader('Content-Type', 'application/json');\n res.setHeader('Access-Control-Allow-Origin', '*');\n res.setHeader('Cache-Control', 'no-cache, no-store, must-revalidate'); // Never cache in dev\n res.end(JSON.stringify(finalConfig, null, 2));\n\n if (debug) {\n console.log('📤 Serving fresh prefetch-config.json from development server');\n }\n return;\n } catch (error) {\n if (debug) {\n console.error('Error serving prefetch-config.json:', error);\n }\n res.statusCode = 500;\n res.end(JSON.stringify({ error: 'Internal server error', details: String(error) }));\n }\n });\n };\n },\n\n async buildStart() {\n if (!analytics) {\n if (debug) {\n console.log('\\n⏭️ Analytics disabled, using manual rules only');\n }\n // Create model from manual rules only\n prefetchModel = createManualModel(manualRules, config.command === 'serve' ? 'development' : 'production');\n return;\n }\n\n const environment = analytics.environment || (config.command === 'serve' ? 'development' : 'production');\n\n // Check cache first\n const cached = await cacheManager.get(environment);\n if (cached) {\n prefetchModel = cached;\n return;\n }\n\n // Fetch and train model\n try {\n if (debug) {\n console.log(`\\n📊 Fetching ${analytics.provider} data and training model...`);\n }\n\n // Initialize BigQuery Analytics connector\n const bqConnector = new BigQueryAnalyticsConnector(\n (analytics.credentials as any).projectId,\n (analytics.credentials as any).datasetId,\n (analytics.credentials as any).region || 'asia-south1',\n debug,\n (analytics.credentials as any).keyFilePath\n );\n\n console.log('\\n🎯 Using real navigation data from BigQuery GA4 export...');\n\n // Fetch navigation data\n const navigationData = await bqConnector.fetchNavigationSequences(analytics.dataRange);\n\n if (navigationData.length === 0) {\n console.warn('⚠️ No navigation data found, using manual rules only');\n prefetchModel = createManualModel(manualRules, environment);\n return;\n }\n\n // Train model using Markov chain ML with Bayesian probability\n // Uses real navigation data to predict likely route transitions\n console.log(`\\n🤖 Training model using Markov Chain ML...`);\n const mlTrainer = new GuessJSMLTrainer(analytics.model, debug);\n const prefetchModelResult = mlTrainer.trainMLModel(navigationData, environment);\n prefetchModel = prefetchModelResult;\n\n // Cache model\n await cacheManager.set(environment, prefetchModel);\n\n // Try to train segment-specific models if segment data is available\n try {\n const navigationWithSegments = await bqConnector.fetchNavigationWithSegments(analytics.dataRange);\n\n if (navigationWithSegments.length > 0) {\n console.log(`\\n👥 Training segment-specific models...`);\n segmentModels = mlTrainer.trainSegmentedModels(navigationWithSegments, environment);\n\n if (debug && segmentModels.size > 0) {\n console.log(` ✅ Trained ${segmentModels.size} segment-specific models`);\n }\n }\n } catch (error) {\n if (debug) {\n console.warn(`⚠️ Could not train segment models:`, error instanceof Error ? error.message : 'Unknown error');\n }\n // Segment training is optional, don't fail the build\n }\n } catch (error) {\n console.error('❌ Failed to fetch analytics data:', error);\n console.log('⚠️ Falling back to manual rules only');\n\n // Fallback to manual rules\n prefetchModel = createManualModel(manualRules, environment);\n \n // Don't fail the build, just warn\n if (debug) {\n console.error('Error details:', error);\n }\n }\n },\n\n async writeBundle(outputOptions) {\n if (!prefetchModel) {\n console.warn('⚠️ No prefetch model available, skipping config generation');\n return;\n }\n\n // Read manifest from disk instead of bundle\n const fs = await import('node:fs');\n const path = await import('node:path');\n\n const outDir = outputOptions.dir || 'dist';\n const manifestPath = path.join(outDir, '.vite', 'manifest.json');\n\n if (!fs.existsSync(manifestPath)) {\n console.warn('⚠️ Vite manifest not found at:', manifestPath);\n return;\n }\n\n const manifestContent = fs.readFileSync(manifestPath, 'utf-8');\n const manifest: ViteManifest = JSON.parse(manifestContent);\n\n if (debug) {\n console.log(`\\n📦 Vite manifest loaded: ${Object.keys(manifest).length} entries`);\n }\n\n // Generate final config with chunk mappings\n const generator = new ConfigGenerator(manifest, manualRules, debug);\n const finalConfig = generator.generate(prefetchModel);\n\n // Validate chunks\n const validation = generator.validateChunks(finalConfig);\n if (!validation.valid) {\n console.warn('⚠️ Some chunks could not be mapped:');\n validation.missing.forEach((m) => console.warn(` ${m}`));\n } else {\n console.log(`✅ All ${Object.keys(finalConfig.chunks).length} chunks successfully mapped with real build hashes`);\n }\n\n // Write prefetch-config.json to disk\n const configPath = path.join(outDir, 'prefetch-config.json');\n fs.writeFileSync(configPath, JSON.stringify(finalConfig, null, 2));\n\n // Save model routes for testing purposes\n const modelRoutesPath = path.join(outDir, 'model-routes.json');\n fs.writeFileSync(modelRoutesPath, JSON.stringify(prefetchModel.routes, null, 2));\n\n if (debug) {\n console.log('✅ Emitted prefetch-config.json with real chunk hashes');\n console.log('✅ Emitted model-routes.json');\n console.log(`📊 Total routes configured: ${Object.keys(finalConfig.routes).length}`);\n console.log(`📦 Total chunks: ${Object.keys(finalConfig.chunks).length}`);\n }\n\n // Generate and write segment-specific configs\n if (segmentModels && segmentModels.size > 0) {\n console.log(`\\n📁 Generating segment-specific prefetch configurations...`);\n\n const segmentGenerator = new ConfigGenerator(manifest, manualRules, debug);\n const segmentConfigs = segmentGenerator.generateSegmentConfigs(segmentModels);\n\n // Create segment configs directory\n const segmentDir = path.join(outDir, 'prefetch-configs');\n if (!fs.existsSync(segmentDir)) {\n fs.mkdirSync(segmentDir, { recursive: true });\n }\n\n // Write each segment config\n segmentConfigs.forEach((segConfig, segment) => {\n const segmentPath = path.join(segmentDir, `${segment}.json`);\n fs.writeFileSync(segmentPath, JSON.stringify(segConfig, null, 2));\n\n if (debug) {\n console.log(` ✅ Emitted ${segment}.json (${Object.keys(segConfig.routes).length} routes)`);\n }\n });\n\n // Write segment index/manifest\n const segmentIndex = {\n generatedAt: new Date().toISOString(),\n environment: analytics?.environment || (config.command === 'serve' ? 'development' : 'production'),\n segments: Array.from(segmentConfigs.keys()),\n description: 'Segment-specific prefetch configurations. Use based on user role/segment.'\n };\n\n const segmentIndexPath = path.join(segmentDir, 'index.json');\n fs.writeFileSync(segmentIndexPath, JSON.stringify(segmentIndex, null, 2));\n\n if (debug) {\n console.log(`\\n✅ Emitted ${segmentConfigs.size} segment-specific configurations`);\n console.log(` Location: ${segmentDir}`);\n console.log(` Segments: ${Array.from(segmentConfigs.keys()).join(', ')}`);\n }\n }\n\n // Generate analytics dashboard if requested\n if (analytics?.dashboard) {\n const dashboardHtml = generateDashboard(finalConfig);\n const dashboardPath = path.join(outDir, 'prefetch-report.html');\n fs.writeFileSync(dashboardPath, dashboardHtml);\n\n if (debug) {\n console.log('✅ Emitted prefetch-report.html');\n }\n }\n },\n\n transformIndexHtml() {\n // Inject runtime configuration and initialize prefetch manager\n return [\n {\n tag: 'script',\n attrs: { type: 'module' },\n children: `\n // Smart Prefetch Plugin Runtime Config\n window.__SMART_PREFETCH__ = {\n strategy: '${strategy}',\n framework: '${framework}',\n debug: ${debug},\n };\n\n // Initialize prefetch manager after page load\n // This allows the app to be built first, then PrefetchManager can load the config\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', initPrefetch);\n } else {\n initPrefetch();\n }\n\n async function initPrefetch() {\n try {\n // Dynamically import PrefetchManager from the bundled app\n // The app should have @farmart/vite-plugin-smart-prefetch/runtime in its dependencies\n const { PrefetchManager } = await import('@farmart/vite-plugin-smart-prefetch/runtime');\n const manager = new PrefetchManager('${strategy}', ${debug});\n await manager.init();\n\n // Expose manager globally for debugging\n window.__PREFETCH_MANAGER__ = manager;\n if (${debug}) {\n console.log('✅ Smart Prefetch Manager initialized');\n }\n } catch (error) {\n if (${debug}) {\n console.warn('⚠️ Could not initialize Smart Prefetch Manager:', error);\n console.log('This is expected if:');\n console.log('1. @farmart/vite-plugin-smart-prefetch/runtime is not installed');\n console.log('2. prefetch-config.json was not generated (BigQuery data fetch failed)');\n }\n }\n }\n `,\n injectTo: 'head',\n },\n ];\n },\n };\n}\n\n/**\n * Create a model from manual rules only (no analytics)\n */\nfunction createManualModel(\n manualRules: Record<string, string[]>,\n environment: string\n): PrefetchModel {\n const model: PrefetchModel = {\n version: '1.0.0',\n generatedAt: new Date().toISOString(),\n environment,\n routes: {},\n dataSource: {\n provider: 'manual',\n dateRange: 'N/A',\n totalSessions: 0,\n totalRoutes: Object.keys(manualRules).length,\n },\n config: {\n type: 'probability',\n threshold: 1.0,\n maxPrefetch: 10,\n },\n };\n\n Object.entries(manualRules).forEach(([source, targets]) => {\n model.routes[source] = {\n prefetch: targets.map((target) => ({\n route: target,\n probability: 1.0,\n count: 0,\n priority: 'high',\n manual: true,\n })),\n };\n });\n\n return model;\n}\n\n/**\n * Generate analytics dashboard HTML\n */\nfunction generateDashboard(config: any): string {\n const totalRoutes = Object.keys(config.routes).length;\n const totalPrefetches = Object.values(config.routes).reduce(\n (sum: number, route: any) => sum + route.prefetch.length,\n 0\n );\n\n return `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>Smart Prefetch Report</title>\n <style>\n body {\n font-family: system-ui, -apple-system, sans-serif;\n max-width: 1200px;\n margin: 0 auto;\n padding: 2rem;\n background: #f5f5f5;\n }\n h1 { color: #333; }\n .stats {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n gap: 1rem;\n margin: 2rem 0;\n }\n .stat-card {\n background: white;\n padding: 1.5rem;\n border-radius: 8px;\n box-shadow: 0 2px 4px rgba(0,0,0,0.1);\n }\n .stat-value { font-size: 2rem; font-weight: bold; color: #4CAF50; }\n .stat-label { color: #666; margin-top: 0.5rem; }\n .route-list {\n background: white;\n padding: 1.5rem;\n border-radius: 8px;\n box-shadow: 0 2px 4px rgba(0,0,0,0.1);\n }\n .route-item {\n padding: 1rem;\n border-bottom: 1px solid #eee;\n }\n .route-item:last-child { border-bottom: none; }\n .route-source { font-weight: bold; color: #333; }\n .prefetch-target {\n margin-left: 2rem;\n padding: 0.5rem;\n color: #666;\n }\n .priority-high { color: #4CAF50; }\n .priority-medium { color: #FF9800; }\n .priority-low { color: #9E9E9E; }\n </style>\n</head>\n<body>\n <h1>🚀 Smart Prefetch Report</h1>\n <p>Generated: ${config.generatedAt}</p>\n <p>Environment: ${config.environment}</p>\n\n <div class=\"stats\">\n <div class=\"stat-card\">\n <div class=\"stat-value\">${totalRoutes}</div>\n <div class=\"stat-label\">Routes with Prefetch</div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-value\">${totalPrefetches}</div>\n <div class=\"stat-label\">Total Prefetch Targets</div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-value\">${config.dataSource?.totalSessions?.toLocaleString() || 'N/A'}</div>\n <div class=\"stat-label\">Sessions Analyzed</div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-value\">${(config.model.threshold * 100).toFixed(0)}%</div>\n <div class=\"stat-label\">Probability Threshold</div>\n </div>\n </div>\n\n <div class=\"route-list\">\n <h2>Prefetch Configuration</h2>\n ${Object.entries(config.routes)\n .map(\n ([source, data]: [string, any]) => `\n <div class=\"route-item\">\n <div class=\"route-source\">${source}</div>\n ${data.prefetch\n .map(\n (target: any) => `\n <div class=\"prefetch-target\">\n → ${target.route}\n <span class=\"priority-${target.priority}\">\n (${(target.probability * 100).toFixed(1)}%, ${target.priority})\n </span>\n </div>\n `\n )\n .join('')}\n </div>\n `\n )\n .join('')}\n </div>\n</body>\n</html>`;\n}\n"],"mappings":"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","names":["path","candidates","path","fs","path"]}
|
|
1
|
+
{"version":3,"sources":["../src/plugin/analytics/bigquery-connector.ts","../src/plugin/model/prefetch-ml-trainer.ts","../src/plugin/config-generator.ts","../src/plugin/cache-manager.ts","../src/plugin/index.ts"],"sourcesContent":["/**\n * BigQuery Analytics Connector\n * Queries GA4 event data from BigQuery to extract real navigation transitions\n */\n\nimport { BigQuery } from '@google-cloud/bigquery';\nimport { writeFileSync, mkdirSync } from 'fs';\nimport { join } from 'path';\nimport type { NavigationData, DataRangeConfig } from '../../types';\n\nexport class BigQueryAnalyticsConnector {\n private bigquery: BigQuery;\n private projectId: string;\n private datasetId: string;\n private location: string;\n private debug: boolean;\n\n constructor(projectId: string, datasetId: string, location = 'asia-south1', debug = false, keyFilePath?: string) {\n this.projectId = projectId;\n this.datasetId = datasetId;\n // Ensure location is properly formatted (handle 'asia' → 'asia-south1', etc.)\n this.location = location && location !== 'asia' ? location : 'asia-south1';\n this.debug = debug;\n\n // Initialize BigQuery client with service account credentials\n const bigqueryConfig: any = {\n projectId: projectId,\n };\n\n // If keyFilePath provided, use service account file\n // Otherwise, use default Application Default Credentials\n if (keyFilePath) {\n bigqueryConfig.keyFilename = keyFilePath;\n }\n\n this.bigquery = new BigQuery(bigqueryConfig);\n\n if (this.debug) {\n console.log('✅ BigQuery Analytics connector initialized');\n console.log(` Project ID: ${projectId}`);\n console.log(` Dataset ID: ${datasetId}`);\n console.log(` Location: ${this.location}`);\n console.log(` Authentication: ${keyFilePath ? `Service Account (${keyFilePath})` : 'Application Default Credentials'}`);\n console.log(` Querying daily events tables: ${projectId}.${datasetId}.events_*`);\n }\n }\n\n /**\n * Fetch real navigation transitions from BigQuery GA4 export\n * Queries the events table for page_view events with previous_page_path parameter\n */\n async fetchNavigationSequences(config: DataRangeConfig = {}): Promise<NavigationData[]> {\n const { days = 30 } = config;\n const minSessions = 1;\n\n console.log(`\\n${'═'.repeat(60)}`);\n console.log(`📊 STAGE 1: PREPARING BIGQUERY QUERY`);\n console.log(`${'═'.repeat(60)}`);\n console.log(` Project ID: ${this.projectId}`);\n console.log(` Dataset ID: ${this.datasetId}`);\n console.log(` Location: ${this.location}`);\n console.log(` Date range: Last ${days} days`);\n console.log(` Daily tables pattern: events_*`);\n console.log(` Event type filter: page_view`);\n console.log(` Expected fields: user_pseudo_id, ga_session_id, page_path`);\n\n try {\n // Query GA4 events for page transitions\n // Strategy: Use user_pseudo_id and session_id to reconstruct user sessions and page transitions\n // This groups pages viewed by the same user in the same session to infer navigation flow\n const query = `\n WITH page_sessions AS (\n SELECT\n user_pseudo_id,\n (SELECT value.int_value FROM UNNEST(event_params) WHERE KEY = 'ga_session_id' LIMIT 1) as session_id,\n (SELECT value.string_value FROM UNNEST(event_params) WHERE KEY = 'page_path' LIMIT 1) as page_path,\n event_timestamp,\n ROW_NUMBER() OVER (\n PARTITION BY user_pseudo_id, (SELECT value.int_value FROM UNNEST(event_params) WHERE KEY = 'ga_session_id' LIMIT 1)\n ORDER BY event_timestamp\n ) as page_sequence\n FROM \\`${this.projectId}.${this.datasetId}.events_*\\`\n WHERE\n event_name = 'page_view'\n AND _TABLE_SUFFIX BETWEEN FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE(), INTERVAL ${days} DAY))\n AND FORMAT_DATE('%Y%m%d', CURRENT_DATE())\n AND (SELECT value.string_value FROM UNNEST(event_params) WHERE KEY = 'page_path' LIMIT 1) IS NOT NULL\n ),\n transitions AS (\n SELECT\n COALESCE(curr.page_path, '(direct)') as from_page,\n LEAD(curr.page_path) OVER (\n PARTITION BY curr.user_pseudo_id, curr.session_id\n ORDER BY curr.page_sequence\n ) as to_page\n FROM page_sessions curr\n WHERE curr.page_sequence > 0\n )\n SELECT\n from_page as previous_page_path,\n to_page as page_path,\n COUNT(*) as transition_count\n FROM transitions\n WHERE to_page IS NOT NULL\n GROUP BY previous_page_path, page_path\n ORDER BY transition_count DESC\n LIMIT 10000\n `;\n\n if (this.debug) {\n console.log(`\\n📤 Full BigQuery Query:`);\n console.log(`${'─'.repeat(60)}`);\n console.log(query);\n console.log(`${'─'.repeat(60)}`);\n }\n\n console.log(`\\n${'═'.repeat(60)}`);\n console.log(`📊 STAGE 2: EXECUTING QUERY`);\n console.log(`${'═'.repeat(60)}`);\n console.log(` ⏳ Querying BigQuery...`);\n\n const [rows] = await this.bigquery.query({\n query,\n location: this.location,\n });\n\n console.log(` ✅ Query executed successfully`);\n console.log(` 📈 Total transitions returned: ${rows.length}`);\n\n if (rows.length === 0) {\n console.log(`\\n${'═'.repeat(60)}`);\n console.log(`⚠️ STAGE 2: NO DATA RETURNED!`);\n console.log(`${'═'.repeat(60)}`);\n console.log(` ❌ BigQuery returned 0 rows`);\n console.log(`\\n Possible causes:`);\n console.log(` 1. No event tables in date range (events_YYYYMMDD)`);\n console.log(` 2. No page_view events in those tables`);\n console.log(` 3. page_path parameter not being tracked`);\n console.log(` 4. Wrong location (currently: ${this.location})`);\n console.log(` 5. Wrong dataset name: ${this.datasetId}`);\n console.log(`\\n Troubleshooting:`);\n console.log(` • Check BigQuery console for available event tables`);\n console.log(` • Verify GA4 property is exporting to BigQuery`);\n console.log(` • Confirm page_path is being captured in GA4`);\n console.log(`${'═'.repeat(60)}\\n`);\n return [];\n }\n\n console.log(`\\n${'═'.repeat(60)}`);\n console.log(`📊 STAGE 3: PROCESSING RAW DATA`);\n console.log(`${'═'.repeat(60)}`);\n console.log(` Processing ${rows.length} raw transitions...`);\n\n const navigationData: NavigationData[] = [];\n let processedCount = 0;\n let filteredCount = 0;\n let emptyPathCount = 0;\n let lowCountCount = 0;\n let selfTransitionCount = 0;\n\n // IMPORTANT: Save RAW rows for inspection\n const rawData = rows.map((row: any) => ({\n previous_page_path: row.previous_page_path,\n page_path: row.page_path,\n transition_count: row.transition_count\n }));\n\n console.log(`\\n ${'─'.repeat(56)}`);\n console.log(` Processing each transition row...`);\n console.log(` ${'─'.repeat(56)}`);\n\n // Process rows and convert to NavigationData format\n rows.forEach((row: any, index: number) => {\n const previousPage = row.previous_page_path || '(direct)';\n const currentPage = row.page_path || '';\n const transitionCount = parseInt(row.transition_count || '0');\n\n if (this.debug && index < 5) {\n console.log(`\\n Row ${index + 1}:`);\n console.log(` Raw: \"${previousPage}\" → \"${currentPage}\" (count: ${transitionCount})`);\n }\n\n // Normalize page paths\n const normalizedPrevious = previousPage === '(direct)' || previousPage === '(not set)' ? '(direct)' : this.normalizeRoute(previousPage);\n const normalizedCurrent = this.normalizeRoute(currentPage);\n\n if (this.debug && index < 5) {\n console.log(` Normalized: \"${normalizedPrevious}\" → \"${normalizedCurrent}\"`);\n }\n\n // Only add valid transitions (exclude self-to-self transitions)\n if (normalizedCurrent && transitionCount >= minSessions && normalizedPrevious !== normalizedCurrent) {\n navigationData.push({\n from: normalizedPrevious,\n to: normalizedCurrent,\n count: transitionCount,\n });\n processedCount++;\n\n if (this.debug && index < 5) {\n console.log(` ✅ ACCEPTED`);\n }\n } else {\n filteredCount++;\n\n if (!normalizedCurrent) {\n emptyPathCount++;\n if (this.debug && index < 5) {\n console.log(` ❌ FILTERED: normalized to empty path (likely build artifact)`);\n }\n } else if (transitionCount < minSessions) {\n lowCountCount++;\n if (this.debug && index < 5) {\n console.log(` ❌ FILTERED: transition count ${transitionCount} < minSessions ${minSessions}`);\n }\n } else if (normalizedPrevious === normalizedCurrent) {\n selfTransitionCount++;\n if (this.debug && index < 5) {\n console.log(` ❌ FILTERED: self-to-self transition (user stayed on same page)`);\n }\n }\n }\n });\n\n console.log(`\\n ${'─'.repeat(56)}`);\n console.log(` Processing Summary:`);\n console.log(` ✅ Accepted: ${processedCount}`);\n console.log(` ❌ Filtered out: ${filteredCount}`);\n console.log(` • Empty paths: ${emptyPathCount}`);\n console.log(` • Low transition count: ${lowCountCount}`);\n console.log(` • Self-to-self transitions: ${selfTransitionCount}`);\n\n // Save raw and processed data to files for inspection\n this.saveDataForInspection(rawData, navigationData);\n\n console.log(`\\n${'═'.repeat(60)}`);\n console.log(`📊 STAGE 4: FINAL RESULTS`);\n console.log(`${'═'.repeat(60)}`);\n console.log(` Total valid transitions: ${navigationData.length}`);\n\n if (navigationData.length === 0) {\n console.log(`\\n ⚠️ WARNING: All transitions were filtered out!`);\n console.log(` Check the logs above to see why rows were rejected.`);\n console.log(` Raw data saved to: .bigquery-raw-data/raw-bigquery-response.json`);\n } else {\n // Show top 5 transitions\n console.log(`\\n Top 5 transitions:`);\n navigationData.slice(0, 5).forEach((nav, i) => {\n console.log(` ${i + 1}. ${nav.from} → ${nav.to} (${nav.count})`);\n });\n\n // Show unique routes\n const uniqueRoutes = new Set<string>();\n navigationData.forEach((nav) => {\n if (nav.from !== '(direct)') uniqueRoutes.add(nav.from);\n uniqueRoutes.add(nav.to);\n });\n console.log(`\\n 📊 Unique routes: ${uniqueRoutes.size}`);\n console.log(` Routes: ${Array.from(uniqueRoutes).sort().join(', ')}`);\n\n console.log(`\\n 📁 Data inspection files created:`);\n console.log(` • .bigquery-raw-data/raw-bigquery-response.json`);\n console.log(` • .bigquery-raw-data/processed-navigation-data.json`);\n console.log(` • .bigquery-raw-data/data-transformation-summary.json`);\n }\n\n console.log(`${'═'.repeat(60)}\\n`);\n\n return navigationData;\n } catch (error: unknown) {\n const errorMessage = error instanceof Error ? error.message : String(error) || 'Unknown error';\n\n console.log(`\\n${'═'.repeat(60)}`);\n console.log(`❌ ERROR: QUERY EXECUTION FAILED`);\n console.log(`${'═'.repeat(60)}`);\n\n // Check if this is a permission error\n if (errorMessage.includes('bigquery.jobs.create') || errorMessage.includes('PERMISSION_DENIED')) {\n console.error(` ❌ Permission Denied`);\n console.error(` Service account needs BigQuery Job User role in project: ${this.projectId}`);\n console.error(` Error: ${errorMessage}`);\n } else if (errorMessage.includes('was not found')) {\n console.error(` ❌ Dataset not found`);\n console.error(` Cannot find dataset: ${this.projectId}.${this.datasetId}`);\n console.error(` Try a different location or check dataset name`);\n console.error(` Current location: ${this.location}`);\n console.error(` Error: ${errorMessage}`);\n } else {\n const errorType = error instanceof Error ? error.constructor.name : 'Unknown';\n console.error(` Error type: ${errorType}`);\n console.error(` Message: ${errorMessage}`);\n }\n\n console.log(`${'═'.repeat(60)}\\n`);\n\n throw new Error(\n `BigQuery Analytics error: ${errorMessage}`\n );\n }\n }\n\n\n /**\n * Normalize route paths\n * Converts dynamic segments to parameters and standardizes format\n */\n private normalizeRoute(path: string): string {\n // Filter out build artifacts and non-route paths\n const buildArtifacts = [\n /\\.(js|css|jpg|jpeg|png|gif|svg|webp|woff|woff2|ttf|eot|map)(\\?|#|$)/i,\n /\\[hash\\]/i,\n /\\/chunks\\//i,\n /\\/vendor\\//i,\n /\\/assets\\//i,\n /\\.vite\\//i,\n ];\n\n if (buildArtifacts.some((pattern) => pattern.test(path))) {\n return '';\n }\n\n let normalized = path;\n\n // Remove query parameters and hash\n normalized = normalized.split('?')[0].split('#')[0];\n\n // Remove trailing slash (except for root /)\n if (normalized.length > 1 && normalized.endsWith('/')) {\n normalized = normalized.slice(0, -1);\n }\n\n // Ensure lowercase for consistency (convert spaces to hyphens)\n if (normalized !== '/') {\n normalized = normalized.toLowerCase().replace(/ +/g, '-');\n }\n\n // Replace common ID patterns with :id\n normalized = normalized\n .replace(/\\/[0-9a-f]{24}(?=\\/|$)/gi, '/:id')\n .replace(/\\/[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}(?=\\/|$)/gi, '/:id')\n .replace(/\\/\\d+(?=\\/|$)/g, '/:id')\n .replace(/\\/[\\w.-]+@[\\w.-]+\\.[\\w]+(?=\\/|$)/gi, '/:email')\n .replace(/\\/\\d{4}-\\d{2}-\\d{2}(?=\\/|$)/g, '/:date');\n\n return normalized;\n }\n\n /**\n * Save raw and processed data for inspection\n * Helps identify issues in data transformation pipeline\n */\n private saveDataForInspection(rawData: any[], processedData: NavigationData[]): void {\n try {\n const outputDir = '.bigquery-raw-data';\n const outputPath = join(process.cwd(), outputDir);\n\n // Create directory if it doesn't exist\n mkdirSync(outputPath, { recursive: true });\n\n // Raw data: exactly as it comes from BigQuery\n const rawFile = join(outputPath, 'raw-bigquery-response.json');\n writeFileSync(rawFile, JSON.stringify(rawData, null, 2));\n\n // Processed data: after normalization and filtering\n const processedFile = join(outputPath, 'processed-navigation-data.json');\n writeFileSync(processedFile, JSON.stringify(processedData, null, 2));\n\n // Summary statistics\n const summary = {\n timestamp: new Date().toISOString(),\n rawRowCount: rawData.length,\n processedRowCount: processedData.length,\n dataLoss: rawData.length - processedData.length,\n dataLossPercentage: ((rawData.length - processedData.length) / rawData.length * 100).toFixed(2) + '%',\n totalTransitions: processedData.reduce((sum, d) => sum + d.count, 0),\n uniqueFromRoutes: new Set(processedData.map(d => d.from)).size,\n uniqueToRoutes: new Set(processedData.map(d => d.to)).size,\n topTransitions: processedData.slice(0, 10)\n };\n\n const summaryFile = join(outputPath, 'data-transformation-summary.json');\n writeFileSync(summaryFile, JSON.stringify(summary, null, 2));\n\n if (this.debug) {\n console.log(`\\n📊 Data Inspection Summary:`);\n console.log(` Raw rows from BigQuery: ${summary.rawRowCount}`);\n console.log(` Processed rows (after filtering): ${summary.processedRowCount}`);\n console.log(` Data loss: ${summary.dataLoss} rows (${summary.dataLossPercentage})`);\n console.log(` Total transitions count: ${summary.totalTransitions}`);\n console.log(` Unique source routes: ${summary.uniqueFromRoutes}`);\n console.log(` Unique destination routes: ${summary.uniqueToRoutes}`);\n console.log(`\\n Files saved:`);\n console.log(` • ${rawFile}`);\n console.log(` • ${processedFile}`);\n console.log(` • ${summaryFile}`);\n }\n } catch (error) {\n console.warn(`⚠️ Could not save inspection data:`, error instanceof Error ? error.message : error);\n }\n }\n\n /**\n * Fetch navigation data WITH optional segment information\n * Only includes segment/grouping field when explicitly requested\n * @param config - Data range configuration with optional segmentField\n * @returns Navigation data, optionally with segment field included\n */\n async fetchNavigationWithSegments(config: DataRangeConfig & { segmentField?: string } = {}): Promise<any[]> {\n const { days = 30, segmentField } = config;\n\n // If no segment field is specified, use the base method without segments\n if (!segmentField) {\n console.log(`\\n${'═'.repeat(60)}`);\n console.log(`📊 STAGE 1: PREPARING BIGQUERY QUERY (SEGMENTED)`);\n console.log(`${'═'.repeat(60)}`);\n console.log(` ⚠️ No segment field specified`);\n console.log(` Falling back to fetchNavigationSequences (base data only)`);\n console.log(` To include segments, pass: { segmentField: 'field_name' }`);\n console.log(`${'═'.repeat(60)}\\n`);\n return this.fetchNavigationSequences(config);\n }\n\n console.log(`\\n${'═'.repeat(60)}`);\n console.log(`📊 STAGE 1: PREPARING SEGMENTED BIGQUERY QUERY`);\n console.log(`${'═'.repeat(60)}`);\n console.log(` Project ID: ${this.projectId}`);\n console.log(` Dataset ID: ${this.datasetId}`);\n console.log(` Location: ${this.location}`);\n console.log(` Date range: Last ${days} days`);\n console.log(` Daily tables pattern: events_*`);\n console.log(` Event type filter: page_view`);\n console.log(` Segment field: ${segmentField}`);\n console.log(` Expected fields: user_pseudo_id, ga_session_id, page_path, ${segmentField}`);\n\n try {\n // Query GA4 events for page transitions with optional segment field\n // Only extracts the segment field that was explicitly requested\n const segmentParam = `(SELECT value.string_value FROM UNNEST(event_params) WHERE KEY = '${segmentField}' LIMIT 1) as segment_value`;\n\n const query = `\n WITH page_sessions AS (\n SELECT\n user_pseudo_id,\n (SELECT value.int_value FROM UNNEST(event_params) WHERE KEY = 'ga_session_id' LIMIT 1) as session_id,\n (SELECT value.string_value FROM UNNEST(event_params) WHERE KEY = 'page_path' LIMIT 1) as page_path,\n ${segmentParam},\n event_timestamp,\n ROW_NUMBER() OVER (\n PARTITION BY user_pseudo_id, (SELECT value.int_value FROM UNNEST(event_params) WHERE KEY = 'ga_session_id' LIMIT 1)\n ORDER BY event_timestamp\n ) as page_sequence\n FROM \\`${this.projectId}.${this.datasetId}.events_*\\`\n WHERE\n event_name = 'page_view'\n AND _TABLE_SUFFIX BETWEEN FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE(), INTERVAL ${days} DAY))\n AND FORMAT_DATE('%Y%m%d', CURRENT_DATE())\n AND (SELECT value.string_value FROM UNNEST(event_params) WHERE KEY = 'page_path' LIMIT 1) IS NOT NULL\n ),\n transitions AS (\n SELECT\n COALESCE(curr.page_path, '(direct)') as from_page,\n LEAD(curr.page_path) OVER (\n PARTITION BY curr.user_pseudo_id, curr.session_id\n ORDER BY curr.page_sequence\n ) as to_page,\n COALESCE(curr.segment_value, 'unknown') as segment\n FROM page_sessions curr\n WHERE curr.page_sequence > 0\n )\n SELECT\n from_page as previous_page_path,\n to_page as page_path,\n segment,\n COUNT(*) as transition_count\n FROM transitions\n WHERE to_page IS NOT NULL\n GROUP BY previous_page_path, page_path, segment\n ORDER BY segment, transition_count DESC\n LIMIT 50000\n `;\n\n if (this.debug) {\n console.log(`\\n📤 Full Query with segment field (${segmentField}):`);\n console.log(`${'─'.repeat(60)}`);\n console.log(query);\n console.log(`${'─'.repeat(60)}`);\n }\n\n console.log(`\\n${'═'.repeat(60)}`);\n console.log(`📊 STAGE 2: EXECUTING QUERY`);\n console.log(`${'═'.repeat(60)}`);\n console.log(` ⏳ Querying BigQuery with segment field: ${segmentField}`);\n\n const [rows] = await this.bigquery.query({\n query,\n location: this.location,\n });\n\n console.log(` ✅ Query executed successfully`);\n console.log(` 📈 Total transitions returned: ${rows.length}`);\n\n if (rows.length === 0) {\n console.log(`\\n${'═'.repeat(60)}`);\n console.log(`⚠️ STAGE 2: NO DATA RETURNED!`);\n console.log(`${'═'.repeat(60)}`);\n console.log(` ❌ BigQuery returned 0 rows for segmented query`);\n console.log(` Segment field: ${segmentField}`);\n console.log(` Check if this field exists in your GA4 event_params`);\n console.log(`${'═'.repeat(60)}\\n`);\n return [];\n }\n\n console.log(`\\n${'═'.repeat(60)}`);\n console.log(`📊 STAGE 3: PROCESSING SEGMENTED DATA`);\n console.log(`${'═'.repeat(60)}`);\n console.log(` Processing ${rows.length} raw transitions with segments...`);\n\n const navigationData: any[] = [];\n let processedCount = 0;\n let filteredCount = 0;\n let selfTransitionCount = 0;\n const segmentCounts: Map<string, number> = new Map();\n\n console.log(`\\n ${'─'.repeat(56)}`);\n console.log(` Processing each transition row...`);\n console.log(` ${'─'.repeat(56)}`);\n\n rows.forEach((row: any, index: number) => {\n const previousPage = row.previous_page_path || '(direct)';\n const currentPage = row.page_path || '';\n const transitionCount = parseInt(row.transition_count || '0');\n const segment = row.segment || 'unknown';\n\n if (this.debug && index < 3) {\n console.log(`\\n Row ${index + 1}:`);\n console.log(` Raw: \"${previousPage}\" → \"${currentPage}\" | segment: \"${segment}\" (count: ${transitionCount})`);\n }\n\n const normalizedPrevious = previousPage === '(direct)' || previousPage === '(not set)' ? '(direct)' : this.normalizeRoute(previousPage);\n const normalizedCurrent = this.normalizeRoute(currentPage);\n\n if (this.debug && index < 3) {\n console.log(` Normalized: \"${normalizedPrevious}\" → \"${normalizedCurrent}\" | segment: \"${segment}\"`);\n }\n\n if (normalizedCurrent && transitionCount >= 1 && normalizedPrevious !== normalizedCurrent) {\n navigationData.push({\n from: normalizedPrevious,\n to: normalizedCurrent,\n count: transitionCount,\n segment: segment,\n });\n processedCount++;\n segmentCounts.set(segment, (segmentCounts.get(segment) || 0) + 1);\n\n if (this.debug && index < 3) {\n console.log(` ✅ ACCEPTED`);\n }\n } else {\n filteredCount++;\n if (normalizedPrevious === normalizedCurrent) {\n selfTransitionCount++;\n }\n if (this.debug && index < 3) {\n console.log(` ❌ FILTERED`);\n }\n }\n });\n\n console.log(`\\n ${'─'.repeat(56)}`);\n console.log(` Processing Summary:`);\n console.log(` ✅ Accepted: ${processedCount}`);\n console.log(` ❌ Filtered out: ${filteredCount}`);\n console.log(` • Self-to-self transitions: ${selfTransitionCount}`);\n\n console.log(`\\n${'═'.repeat(60)}`);\n console.log(`📊 STAGE 4: FINAL RESULTS (SEGMENTED)`);\n console.log(`${'═'.repeat(60)}`);\n console.log(` Total valid transitions: ${navigationData.length}`);\n\n if (navigationData.length > 0) {\n // Show detected segments\n const uniqueSegments = Array.from(segmentCounts.keys()).sort();\n console.log(`\\n 📊 Detected segments: ${uniqueSegments.length}`);\n uniqueSegments.forEach(seg => {\n console.log(` • ${seg} (${segmentCounts.get(seg)} transitions)`);\n });\n\n // Show top transitions per segment\n const bySegment = new Map();\n navigationData.forEach((d: any) => {\n if (!bySegment.has(d.segment)) {\n bySegment.set(d.segment, []);\n }\n bySegment.get(d.segment).push(d);\n });\n\n bySegment.forEach((transitions: any[], segment: string) => {\n console.log(`\\n Top 3 transitions for segment \"${segment}\":`);\n transitions\n .sort((a, b) => b.count - a.count)\n .slice(0, 3)\n .forEach((nav: any, i: number) => {\n console.log(` ${i + 1}. ${nav.from} → ${nav.to} (${nav.count})`);\n });\n });\n } else {\n console.log(` ⚠️ WARNING: All transitions were filtered out!`);\n }\n\n console.log(`${'═'.repeat(60)}\\n`);\n\n return navigationData;\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Unknown error';\n\n console.log(`\\n${'═'.repeat(60)}`);\n console.log(`❌ ERROR: SEGMENTED QUERY EXECUTION FAILED`);\n console.log(`${'═'.repeat(60)}`);\n console.log(` Segment field: ${segmentField}`);\n console.log(` Error: ${errorMessage}`);\n console.log(`${'═'.repeat(60)}\\n`);\n\n console.warn(`⚠️ Failed to fetch navigation data with segments: ${errorMessage}`);\n return [];\n }\n }\n\n}\n","/**\n * Markov Chain Model Trainer\n * Builds a Markov chain from user navigation data\n * Probability: P(dest | src) = count(src→dest) / total_transitions_from_src\n */\n\nimport type {\n NavigationData,\n PrefetchModel,\n ModelConfig,\n PrefetchTarget,\n RouteMetadata,\n} from '../../types';\n\nexport class MarkovChainTrainer {\n private config: ModelConfig;\n private debug: boolean;\n\n constructor(config: ModelConfig, debug = false) {\n this.config = config;\n this.debug = debug;\n }\n\n /**\n * Train Markov chain model from navigation data\n * Calculates transition probabilities: P(dest | src) = transitions(src→dest) / total_from_src\n */\n trainMLModel(\n navigationData: NavigationData[],\n environment: string\n ): PrefetchModel {\n if (this.debug) {\n console.log(`\\n🤖 Training Markov Chain Model...`);\n console.log(` Model type: ${this.config.type}`);\n console.log(` Threshold: ${this.config.threshold * 100}%`);\n console.log(` Max prefetch per route: ${this.config.maxPrefetch}`);\n console.log(` Input transitions: ${navigationData.length}`);\n }\n\n // Build navigation graph: sourceRoute -> { targetRoute: count }\n const navigationGraph = this.buildNavigationGraph(navigationData);\n const routes = this.extractRoutes(navigationData);\n\n if (this.debug) {\n console.log(`\\n 📊 Analysis:`);\n console.log(` Unique routes: ${routes.size}`);\n console.log(` Routes: ${Array.from(routes).sort().join(', ')}`);\n console.log(` Source routes: ${navigationGraph.size}`);\n }\n\n // Calculate Markov probabilities: P(dest | src) = count(src→dest) / total_from_src\n const predictions = this.calculateMarkovProbabilities(navigationGraph);\n\n if (this.debug) {\n console.log(`\\n Predictions generated:`);\n console.log(` Routes with predictions: ${predictions.size}`);\n const totalTargets = Array.from(predictions.values()).reduce(\n (sum, targets) => sum + targets.length,\n 0\n );\n console.log(` Total prefetch targets: ${totalTargets}`);\n }\n\n // Build PrefetchModel\n const model: PrefetchModel = {\n version: '1.0.0',\n generatedAt: new Date().toISOString(),\n environment,\n config: this.config,\n dataSource: {\n provider: 'markov-chain',\n dateRange: this.getDateRange(30),\n totalSessions: navigationData.reduce((sum, d) => sum + d.count, 0),\n totalRoutes: routes.size,\n },\n routes: {},\n };\n\n // Populate predictions\n predictions.forEach((targets, source) => {\n model.routes[source] = {\n prefetch: targets,\n metadata: this.calculateMetadata(navigationGraph, source),\n };\n });\n\n if (this.debug) {\n console.log(`\\n ✅ Model trained successfully`);\n const sampleRoutes = Array.from(predictions.entries()).slice(0, 3);\n if (sampleRoutes.length > 0) {\n console.log(`\\n Sample predictions:`);\n sampleRoutes.forEach(([source, targets]) => {\n console.log(` ${source}:`);\n targets.forEach((target) => {\n console.log(\n ` → ${target.route} (${(target.probability * 100).toFixed(1)}%, ${target.priority})`\n );\n });\n });\n }\n }\n\n return model;\n }\n\n /**\n * Extract all unique routes from navigation data\n */\n private extractRoutes(data: NavigationData[]): Set<string> {\n const routes = new Set<string>();\n\n data.forEach((d) => {\n routes.add(d.from);\n routes.add(d.to);\n });\n\n return routes;\n }\n\n /**\n * Build navigation graph from user navigation patterns\n * Graph represents: sourceRoute -> { targetRoute: transitionCount }\n */\n private buildNavigationGraph(\n data: NavigationData[]\n ): Map<string, Map<string, number>> {\n const graph = new Map<string, Map<string, number>>();\n\n data.forEach(({ from, to, count }) => {\n if (!graph.has(from)) {\n graph.set(from, new Map());\n }\n\n const targets = graph.get(from)!;\n targets.set(to, (targets.get(to) || 0) + count);\n });\n\n return graph;\n }\n\n /**\n * Calculate Markov probabilities with normalization\n * P(dest | src) = count(src→dest) / total_transitions_from_src\n * Then normalizes scores to 0-1 range\n */\n private calculateMarkovProbabilities(\n navigationGraph: Map<string, Map<string, number>>\n ): Map<string, PrefetchTarget[]> {\n const predictions = new Map<string, PrefetchTarget[]>();\n\n navigationGraph.forEach((targets, source) => {\n const targetArray: PrefetchTarget[] = [];\n\n // Calculate total transitions from this source\n const totalFromSource = Array.from(targets.values()).reduce(\n (sum, count) => sum + count,\n 0\n );\n\n if (totalFromSource === 0) return;\n\n // Calculate base probability for each destination: P(dest | src) = count / total\n const probabilities = new Map<string, number>();\n targets.forEach((count, destination) => {\n probabilities.set(destination, count / totalFromSource);\n });\n\n // Normalize probabilities to 0-1 range\n const maxProb = Math.max(...Array.from(probabilities.values()));\n if (maxProb > 0) {\n probabilities.forEach((prob, dest) => {\n probabilities.set(dest, prob / maxProb);\n });\n }\n\n // Sort by probability (descending)\n const sorted = Array.from(probabilities.entries())\n .sort((a, b) => b[1] - a[1])\n .slice(0, this.config.maxPrefetch);\n\n // Apply threshold and create targets\n sorted.forEach(([route, probability]) => {\n if (probability >= this.config.threshold) {\n targetArray.push({\n route,\n probability,\n count: targets.get(route) || 0,\n priority: this.getPriority(probability),\n });\n }\n });\n\n if (targetArray.length > 0) {\n predictions.set(source, targetArray);\n }\n });\n\n return predictions;\n }\n\n /**\n * Determine priority based on ML confidence score\n */\n private getPriority(score: number): 'high' | 'medium' | 'low' {\n if (score >= 0.7) return 'high';\n if (score >= 0.4) return 'medium';\n return 'low';\n }\n\n /**\n * Calculate metadata for a route\n */\n private calculateMetadata(\n navigationGraph: Map<string, Map<string, number>>,\n route: string\n ): RouteMetadata {\n const targets = navigationGraph.get(route);\n\n if (!targets || targets.size === 0) {\n return {\n totalTransitions: 0,\n topDestination: '',\n };\n }\n\n const totalTransitions = Array.from(targets.values()).reduce(\n (sum, count) => sum + count,\n 0\n );\n\n // Find top destination\n let topDestination = '';\n let maxCount = 0;\n targets.forEach((count, targetRoute) => {\n if (count > maxCount) {\n maxCount = count;\n topDestination = targetRoute;\n }\n });\n\n return {\n totalTransitions,\n topDestination,\n };\n }\n\n /**\n * Get date range string\n */\n private getDateRange(days: number): string {\n const end = new Date();\n const start = new Date();\n start.setDate(start.getDate() - days);\n\n return `${start.toISOString().split('T')[0]} to ${end.toISOString().split('T')[0]}`;\n }\n}\n","/**\n * Configuration Generator\n * Maps routes to Vite chunks and generates final prefetch configuration\n */\n\nimport type {\n PrefetchModel,\n PrefetchConfig,\n ViteManifest,\n ManualRules,\n PrefetchTarget,\n} from '../types';\n\nexport class ConfigGenerator {\n private manifest: ViteManifest;\n private manualRules: ManualRules;\n private debug: boolean;\n private vite: any = null;\n private isDev: boolean = false;\n\n /**\n * NOTE: Hardcoded route/component mappings have been REMOVED to make the plugin generic.\n * The plugin now uses dynamic strategies (direct match, pattern match, fuzzy match)\n * to discover routes from the Vite manifest and actual file structure.\n *\n * This allows the plugin to work with ANY project structure without project-specific\n * configuration hardcoded in the plugin code.\n */\n\n constructor(manifest: ViteManifest, manualRules: ManualRules = {}, debug = false, vite?: any) {\n this.manifest = manifest;\n this.manualRules = manualRules;\n this.debug = debug;\n this.vite = vite || null;\n this.isDev = !!vite; // If vite is provided, we're in dev mode\n }\n\n /**\n * Generate final prefetch configuration with chunk mappings\n */\n generate(model: PrefetchModel): PrefetchConfig {\n if (this.debug) {\n console.log(`\\n📦 Generating prefetch configuration...`);\n console.log(` Manifest entries: ${Object.keys(this.manifest).length}`);\n console.log(` Model routes: ${Object.keys(model.routes).length}`);\n console.log(` Manual rules: ${Object.keys(this.manualRules).length}`);\n }\n\n // Merge manual rules into model\n const mergedModel = this.mergeManualRules(model);\n\n // Extract route patterns for dynamic route matching (TanStack Router support)\n const routePatterns = this.extractRoutePatterns(Object.keys(mergedModel.routes));\n\n // Map routes to chunks\n const config: PrefetchConfig = {\n version: model.version,\n generatedAt: model.generatedAt,\n environment: model.environment,\n dataSource: model.dataSource!,\n model: {\n type: model.config!.type,\n threshold: model.config!.threshold,\n maxPrefetch: model.config!.maxPrefetch,\n },\n routePatterns, // NEW: Include route patterns for dynamic matching\n routes: {},\n chunks: {},\n };\n\n let mappedRoutes = 0;\n let unmappedRoutes = 0;\n\n // Process each route\n Object.entries(mergedModel.routes).forEach(([sourceRoute, prediction]) => {\n const prefetchTargets: Array<PrefetchTarget & { chunk: string }> = [];\n\n // Also map the source route's own chunk (so it can be used as a destination elsewhere)\n const sourceChunk = this.routeToChunk(sourceRoute);\n if (sourceChunk && !config.chunks[sourceRoute]) {\n config.chunks[sourceRoute] = sourceChunk;\n }\n\n // Process common prefetch rules\n prediction.prefetch.forEach((target) => {\n const chunkFile = this.routeToChunk(target.route);\n\n if (chunkFile) {\n // Get the manifest entry for this chunk to extract imports\n const manifestEntry = this.getManifestEntryByFile(chunkFile);\n const importChunkIds = manifestEntry?.imports || [];\n\n // Resolve import chunk IDs to actual file paths\n const imports = importChunkIds\n .map((chunkId) => {\n const entry = this.manifest[chunkId];\n return entry?.file;\n })\n .filter((file): file is string => !!file);\n\n prefetchTargets.push({\n ...target,\n chunk: chunkFile,\n chunk_prod: chunkFile, // NEW: Include production chunk path\n imports: imports, // Include dependency chunks (resolved to file paths)\n });\n\n // Add to chunks lookup\n config.chunks[target.route] = chunkFile;\n mappedRoutes++;\n\n // Enhanced debug logging\n if (this.debug) {\n console.log(` ✅ ${sourceRoute} → ${target.route}`);\n console.log(` Chunk: ${chunkFile}`);\n if (imports.length > 0) {\n console.log(` Dependencies: ${imports.join(', ')}`);\n }\n }\n } else {\n if (this.debug) {\n console.log(` ⚠️ No chunk found for route: ${target.route}`);\n console.log(` Attempted to map using routeToChunk()`);\n }\n unmappedRoutes++;\n }\n });\n\n // Get patterns for this route for dynamic matching (TanStack Router support)\n const patterns = routePatterns[sourceRoute] || [sourceRoute];\n\n // Only include routes with valid chunk mappings\n if (prefetchTargets.length > 0) {\n config.routes[sourceRoute] = {\n patterns, // Include patterns for dynamic route matching\n prefetch: prefetchTargets,\n metadata: prediction.metadata,\n };\n }\n });\n\n if (this.debug) {\n console.log(`✅ Configuration generated`);\n console.log(` Routes with prefetch: ${Object.keys(config.routes).length}`);\n console.log(` Mapped chunks: ${mappedRoutes}`);\n console.log(` Unmapped routes: ${unmappedRoutes}`);\n }\n\n return config;\n }\n\n /**\n * Merge manual rules into model\n * Manual rules take precedence over ML predictions\n */\n private mergeManualRules(model: PrefetchModel): PrefetchModel {\n const merged = { ...model, routes: { ...model.routes } };\n\n Object.entries(this.manualRules).forEach(([sourceRoute, targetRoutes]) => {\n if (!merged.routes[sourceRoute]) {\n merged.routes[sourceRoute] = {\n prefetch: [],\n };\n }\n\n // Add manual rules with high priority\n targetRoutes.forEach((targetRoute) => {\n // Check if this rule already exists\n const existing = merged.routes[sourceRoute].prefetch.find(\n (t) => t.route === targetRoute\n );\n\n if (existing) {\n // Update existing with manual flag and high priority\n existing.manual = true;\n existing.priority = 'high';\n existing.probability = 1.0;\n } else {\n // Add new manual rule\n merged.routes[sourceRoute].prefetch.unshift({\n route: targetRoute,\n probability: 1.0,\n count: 0, // Not from analytics\n priority: 'high',\n manual: true,\n });\n }\n });\n\n if (this.debug) {\n console.log(` ✅ Added manual rule: ${sourceRoute} → [${targetRoutes.join(', ')}]`);\n }\n });\n\n return merged;\n }\n\n /**\n * Map BigQuery route to Vite manifest chunk file\n *\n * The routes come from BigQuery navigation data (e.g., /purchase-order, /dispatch-order/:id)\n * We match them directly to manifest entries without trying to discover routes.\n *\n * Strategy: Match route segments against manifest file paths, ignoring hash suffixes\n * Example:\n * Route: /purchase-order/:id\n * Normalized: /purchase-order\n * Manifest: src/pages/purchase-order/index.tsx → {file: assets/purchase-order-abc123.js}\n * Match: YES → return assets/purchase-order-abc123.js\n */\n private routeToChunk(route: string): string | null {\n // Step 1: Normalize route - remove dynamic parameters (:id, $id, etc)\n const normalizedRoute = route.replace(/\\/[:$]\\w+/g, '');\n\n // Step 2: Extract route segments for matching\n // /purchase-order/search → ['purchase-order', 'search']\n const routeSegments = normalizedRoute.split('/').filter(Boolean);\n\n if (routeSegments.length === 0) {\n // Root route - look for src/pages/index.tsx or src/app.tsx\n const candidates = Object.entries(this.manifest).filter(([path]) =>\n path === 'src/pages/index.tsx' ||\n path === 'src/app.tsx' ||\n path === 'src/App.tsx' ||\n path === 'src/main.tsx'\n );\n if (candidates.length > 0) return candidates[0][1].file;\n return null;\n }\n\n // Step 3: Search manifest for entries matching these segments\n // Priority:\n // 1. Exact path match: src/pages/purchase-order/index.tsx\n // 2. Segment match: any manifest entry containing all route segments\n const candidates = Object.entries(this.manifest)\n .filter(([path]) => {\n // Only consider source files, not dependencies\n if (path.startsWith('node_modules') || path.startsWith('_')) {\n return false;\n }\n\n const pathLower = path.toLowerCase();\n\n // Check if path contains ALL route segments in order\n // For route /purchase-order/search:\n // - src/pages/purchase-order/search/index.tsx ✓\n // - src/pages/purchase-order/search.tsx ✓\n // - src/features/purchase-order/search/index.tsx ✓\n return routeSegments.every(segment =>\n pathLower.includes(segment.toLowerCase())\n );\n })\n .sort(([pathA], [pathB]) => {\n // Scoring: higher score = better match\n let scoreA = 0;\n let scoreB = 0;\n\n // Prefer src/pages/ over src/features/\n if (pathA.includes('/pages/')) scoreA += 10;\n if (pathB.includes('/pages/')) scoreB += 10;\n\n // Prefer index.tsx (entry point)\n if (pathA.includes('index.tsx')) scoreA += 8;\n if (pathB.includes('index.tsx')) scoreB += 8;\n\n if (pathA.includes('index.ts')) scoreA += 7;\n if (pathB.includes('index.ts')) scoreB += 7;\n\n // Prefer exact segment structure\n // Route: /purchase-order/search\n // src/pages/purchase-order/search/index.tsx is better than src/pages/purchase-order-search/index.tsx\n const pathASegments = pathA.split('/').map(s => s.toLowerCase()).filter(s => s && !s.startsWith('.'));\n const pathBSegments = pathB.split('/').map(s => s.toLowerCase()).filter(s => s && !s.startsWith('.'));\n\n const matchCountA = routeSegments.filter(seg =>\n pathASegments.some(ps => ps.includes(seg.toLowerCase()))\n ).length;\n const matchCountB = routeSegments.filter(seg =>\n pathBSegments.some(ps => ps.includes(seg.toLowerCase()))\n ).length;\n\n scoreA += matchCountA * 5;\n scoreB += matchCountB * 5;\n\n return scoreB - scoreA; // Higher score first\n });\n\n if (candidates.length > 0) {\n const manifestEntry = candidates[0][1];\n if (this.debug) {\n console.log(` ✅ Found chunk for route ${route}`);\n console.log(` Manifest: ${candidates[0][0]}`);\n console.log(` Chunk file: ${manifestEntry.file}`);\n }\n return manifestEntry.file;\n }\n\n if (this.debug) {\n console.log(` ⚠️ No chunk found for route: ${route}`);\n console.log(` Searched for segments: ${routeSegments.join(', ')}`);\n }\n\n return null;\n }\n\n\n /**\n * Get manifest entry by file name\n */\n private getManifestEntryByFile(fileName: string) {\n return Object.values(this.manifest).find((entry) => entry.file === fileName);\n }\n\n /**\n * Get all chunks referenced in config\n */\n getReferencedChunks(config: PrefetchConfig): string[] {\n return Object.values(config.chunks);\n }\n\n /**\n * Validate that all chunks exist in manifest\n */\n validateChunks(config: PrefetchConfig): {\n valid: boolean;\n missing: string[];\n } {\n const missing: string[] = [];\n const manifestFiles = new Set(Object.values(this.manifest).map((e) => e.file));\n\n Object.entries(config.chunks).forEach(([route, chunk]) => {\n if (!manifestFiles.has(chunk)) {\n missing.push(`${route} -> ${chunk}`);\n }\n });\n\n return {\n valid: missing.length === 0,\n missing,\n };\n }\n\n /**\n * Extract route patterns for dynamic route matching\n * Groups routes by their base path and includes pattern variants\n * E.g., /purchase-order and /purchase-order/:id become patterns for matching\n */\n private extractRoutePatterns(routes: string[]): Record<string, string[]> {\n const patterns: Record<string, string[]> = {};\n\n for (const route of routes) {\n // Check if route contains dynamic parameters (:param or $param for TanStack)\n if (route.includes(':') || route.includes('$')) {\n // This is a dynamic route pattern - keep as-is\n patterns[route] = [route];\n\n // Also add the base route if it exists and is different\n const base = route.split(/[:$]/)[0];\n if (base && base !== route) {\n // Ensure base route also gets patterns\n if (!patterns[base]) {\n patterns[base] = [base, route];\n } else if (!patterns[base].includes(route)) {\n patterns[base].push(route);\n }\n }\n } else {\n // Static route - just use itself\n patterns[route] = [route];\n }\n }\n\n if (this.debug && Object.keys(patterns).length > 0) {\n console.log(`\\n🔍 Extracted route patterns for dynamic matching:`);\n Object.entries(patterns).forEach(([route, patternList]) => {\n if (patternList.length > 1) {\n console.log(` ${route} → [${patternList.join(', ')}]`);\n }\n });\n }\n\n return patterns;\n }\n\n /**\n * Match a pathname against route patterns\n * Supports both static routes and dynamic routes with parameters\n */\n private matchRoutePattern(pathname: string, pattern: string): boolean {\n // Convert route pattern to regex\n // E.g., /purchase-order/:id → /purchase-order/[^/]+\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 /**\n * Find matching route pattern for a given pathname\n * Used by hooks to match actual navigation paths to config routes\n */\n findMatchingPattern(\n pathname: string,\n routes: Record<string, any>\n ): string | null {\n for (const [route, config] of Object.entries(routes)) {\n const patterns = (config as any).patterns || [route];\n for (const pattern of patterns) {\n if (this.matchRoutePattern(pathname, pattern)) {\n return route;\n }\n }\n }\n return null;\n }\n\n}\n","/**\n * Cache Manager\n * Manages caching of trained models to avoid redundant GA API calls\n * Uses Node.js fs to cache models locally during build time\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport type { PrefetchModel, CacheConfig } from '../types';\n\nexport class CacheManager {\n private cacheDir: string;\n private ttl: number;\n private enabled: boolean;\n private debug: boolean;\n\n constructor(config: CacheConfig = {}, debug = false) {\n this.enabled = config.enabled ?? true; // Enabled by default\n this.ttl = config.ttl ?? 24 * 60 * 60 * 1000; // Default: 24 hours\n this.cacheDir = config.path ?? path.join(process.cwd(), '.prefetch-cache');\n this.debug = debug;\n\n if (this.enabled && !fs.existsSync(this.cacheDir)) {\n fs.mkdirSync(this.cacheDir, { recursive: true });\n if (this.debug) {\n console.log(`📁 Created cache directory: ${this.cacheDir}`);\n }\n }\n }\n\n /**\n * Get cached model for environment\n * Returns null if cache doesn't exist or is expired\n */\n async get(environment: string): Promise<PrefetchModel | null> {\n if (!this.enabled) {\n if (this.debug) console.log('⏭️ Cache disabled, skipping cache lookup');\n return null;\n }\n\n try {\n const cacheFile = path.join(this.cacheDir, `${environment}.json`);\n\n if (!fs.existsSync(cacheFile)) {\n if (this.debug) console.log(`📦 Cache miss for environment: ${environment}`);\n return null;\n }\n\n const stats = fs.statSync(cacheFile);\n const cacheAge = Date.now() - stats.mtimeMs;\n\n if (cacheAge > this.ttl) {\n if (this.debug) console.log(`⏰ Cache expired for ${environment} (${Math.round(cacheAge / 1000 / 60)} minutes old)`);\n fs.unlinkSync(cacheFile);\n return null;\n }\n\n const cachedData = fs.readFileSync(cacheFile, 'utf-8');\n const model: PrefetchModel = JSON.parse(cachedData);\n\n if (this.debug) {\n console.log(`✅ Cache hit for environment: ${environment} (${Math.round(cacheAge / 1000)} seconds old)`);\n console.log(` Cached model has ${Object.keys(model.routes).length} routes`);\n }\n\n return model;\n } catch (error) {\n console.error(`❌ Error reading cache for ${environment}:`, error);\n return null;\n }\n }\n\n /**\n * Save model to cache\n */\n async set(environment: string, model: PrefetchModel): Promise<void> {\n if (!this.enabled) {\n if (this.debug) console.log('⏭️ Cache disabled, skipping cache write');\n return;\n }\n\n try {\n const cacheFile = path.join(this.cacheDir, `${environment}.json`);\n fs.writeFileSync(cacheFile, JSON.stringify(model, null, 2), 'utf-8');\n\n if (this.debug) {\n console.log(`💾 Cached model for ${environment}`);\n console.log(` Location: ${cacheFile}`);\n console.log(` Routes: ${Object.keys(model.routes).length}`);\n }\n } catch (error) {\n console.error(`❌ Error writing cache for ${environment}:`, error);\n }\n }\n\n /**\n * Invalidate cache for specific environment or all environments\n */\n async invalidate(environment?: string): Promise<void> {\n if (!this.enabled) return;\n\n try {\n if (environment) {\n const cacheFile = path.join(this.cacheDir, `${environment}.json`);\n if (fs.existsSync(cacheFile)) {\n fs.unlinkSync(cacheFile);\n if (this.debug) {\n console.log(`🗑️ Invalidated cache for ${environment}`);\n }\n }\n } else {\n // Clear all cache files\n const files = fs.readdirSync(this.cacheDir);\n files.forEach((file) => {\n if (file.endsWith('.json')) {\n fs.unlinkSync(path.join(this.cacheDir, file));\n }\n });\n if (this.debug) {\n console.log(`🗑️ Cleared all cache files`);\n }\n }\n } catch (error) {\n console.error(`❌ Error invalidating cache:`, error);\n }\n }\n\n /**\n * Get cache statistics\n */\n getStats(): {\n enabled: boolean;\n cacheDir: string;\n ttl: number;\n cachedEnvironments: string[];\n totalSize: number;\n } {\n const cachedEnvironments: string[] = [];\n let totalSize = 0;\n\n if (this.enabled && fs.existsSync(this.cacheDir)) {\n const files = fs.readdirSync(this.cacheDir);\n files.forEach((file) => {\n if (file.endsWith('.json')) {\n const filePath = path.join(this.cacheDir, file);\n const stats = fs.statSync(filePath);\n cachedEnvironments.push(file.replace('.json', ''));\n totalSize += stats.size;\n }\n });\n }\n\n return {\n enabled: this.enabled,\n cacheDir: this.cacheDir,\n ttl: this.ttl,\n cachedEnvironments,\n totalSize,\n };\n }\n\n /**\n * Check if cache exists and is valid for environment\n */\n async isValid(environment: string): Promise<boolean> {\n if (!this.enabled) return false;\n\n try {\n const cacheFile = path.join(this.cacheDir, `${environment}.json`);\n\n if (!fs.existsSync(cacheFile)) {\n return false;\n }\n\n const stats = fs.statSync(cacheFile);\n const cacheAge = Date.now() - stats.mtimeMs;\n\n return cacheAge <= this.ttl;\n } catch {\n return false;\n }\n }\n\n /**\n * Get cache age in milliseconds\n */\n async getCacheAge(environment: string): Promise<number | null> {\n if (!this.enabled) return null;\n\n try {\n const cacheFile = path.join(this.cacheDir, `${environment}.json`);\n\n if (!fs.existsSync(cacheFile)) {\n return null;\n }\n\n const stats = fs.statSync(cacheFile);\n return Date.now() - stats.mtimeMs;\n } catch {\n return null;\n }\n }\n}\n","/**\n * Main Vite Plugin\n * Integrates all components and provides Vite hooks\n */\n\nimport type { Plugin, ResolvedConfig } from 'vite';\nimport { BigQueryAnalyticsConnector } from './analytics/bigquery-connector';\nimport { MarkovChainTrainer } from './model/prefetch-ml-trainer';\nimport { ConfigGenerator } from './config-generator';\nimport { CacheManager } from './cache-manager';\nimport type {\n PluginOptions,\n PrefetchModel,\n ViteManifest,\n} from '../types';\n\nexport function smartPrefetch(options: PluginOptions = {}): Plugin {\n const {\n framework = 'react',\n strategy = 'hybrid',\n analytics,\n manualRules = {},\n cache = {},\n advanced = {},\n } = options;\n\n const debug = advanced.debug ?? false;\n\n let config: ResolvedConfig;\n let cacheManager: CacheManager;\n let prefetchModel: PrefetchModel | null = null;\n\n return {\n name: '@farmart/vite-plugin-smart-prefetch',\n enforce: 'post',\n\n async configResolved(resolvedConfig) {\n config = resolvedConfig;\n\n // Ensure Vite manifest is enabled\n if (!config.build.manifest) {\n config.build.manifest = true;\n if (debug) {\n console.log('✅ Enabled Vite manifest generation');\n }\n }\n\n // Initialize cache manager\n cacheManager = new CacheManager(cache, debug);\n\n if (debug) {\n console.log('\\n🚀 Smart Prefetch Plugin Initialized');\n console.log(` Framework: ${framework}`);\n console.log(` Strategy: ${strategy}`);\n console.log(` Analytics: ${analytics ? 'enabled' : 'disabled'}`);\n console.log(` Manual rules: ${Object.keys(manualRules).length}`);\n console.log(` Cache: ${cache.enabled !== false ? 'enabled' : 'disabled'}`);\n }\n\n // In development mode, generate prefetch config for testing\n if (config.command === 'serve' && debug) {\n // Create a simple dev-time manifest for testing\n const devManifest: ViteManifest = {};\n\n // Create entries for all manual rules\n Object.keys(manualRules).forEach((route) => {\n const routeKey = `src/features${route}/index.tsx`;\n devManifest[routeKey] = {\n file: `features${route.replace(/\\//g, '-')}.js`,\n imports: [],\n };\n });\n\n // Also try to discover routes from src/pages directory\n const fs = await import('node:fs');\n const path = await import('node:path');\n const pagesDir = path.join(config.root, 'src/pages');\n\n if (fs.existsSync(pagesDir)) {\n const files = fs.readdirSync(pagesDir);\n files.forEach((file) => {\n if (file.endsWith('.tsx') || file.endsWith('.ts')) {\n const pageName = file.replace(/\\.(tsx|ts)$/, '');\n const routeKey = `src/pages/${file}`;\n devManifest[routeKey] = {\n file: `chunks/${pageName}-[hash].js`,\n imports: [],\n };\n }\n });\n }\n\n // Store for use in transformIndexHtml\n (config as any).__smartPrefetchDevManifest = devManifest;\n }\n },\n\n configureServer(server) {\n // In development mode, serve the prefetch-config.json dynamically\n // This ensures we always use the latest model instead of stale [hash] placeholders\n return () => {\n server.middlewares.use('/prefetch-config.json', async (req, res, next) => {\n if (req.method !== 'GET') {\n next();\n return;\n }\n\n try {\n // In dev mode, always generate a fresh config with current model\n if (!prefetchModel) {\n if (debug) {\n console.warn('⚠️ No prefetch model available yet');\n }\n res.statusCode = 503;\n res.end(JSON.stringify({ error: 'Prefetch model not ready, still loading analytics data...' }));\n return;\n }\n\n // Generate config dynamically on each request (dev only)\n // Create a minimal manifest for dev mode - just file paths without real hashes\n const devManifest: ViteManifest = {};\n\n // Map model routes to dev manifest entries\n Object.keys(prefetchModel.routes).forEach((route) => {\n // Create a fake but consistent manifest entry for dev\n const routeKey = `src/pages${route}/index.tsx`;\n const routeName = route.split('/').filter(Boolean).pop() || 'index';\n const devHash = 'dev-' + routeName.slice(0, 6).padEnd(8, '0');\n devManifest[routeKey] = {\n file: `chunks/${routeName}-${devHash}.js`,\n imports: [],\n };\n });\n\n // Generate final config with dev manifest and Vite server instance for chunk discovery\n const generator = new ConfigGenerator(devManifest as ViteManifest, manualRules, debug, server);\n const finalConfig = generator.generate(prefetchModel);\n\n res.setHeader('Content-Type', 'application/json');\n res.setHeader('Access-Control-Allow-Origin', '*');\n res.setHeader('Cache-Control', 'no-cache, no-store, must-revalidate'); // Never cache in dev\n res.end(JSON.stringify(finalConfig, null, 2));\n return;\n } catch (error) {\n if (debug) {\n console.error('Error serving prefetch-config.json:', error);\n }\n res.statusCode = 500;\n res.end(JSON.stringify({ error: 'Internal server error', details: String(error) }));\n }\n });\n };\n },\n\n async buildStart() {\n if (!analytics) {\n if (debug) {\n console.log('\\n⏭️ Analytics disabled, using manual rules only');\n }\n // Create model from manual rules only\n prefetchModel = createManualModel(manualRules, config.command === 'serve' ? 'development' : 'production');\n return;\n }\n\n const environment = analytics.environment || (config.command === 'serve' ? 'development' : 'production');\n\n // Check cache first\n const cached = await cacheManager.get(environment);\n if (cached) {\n prefetchModel = cached;\n return;\n }\n\n // Fetch and train model\n try {\n if (debug) {\n console.log(`\\n📊 Fetching ${analytics.provider} data and training model...`);\n }\n\n // Initialize BigQuery Analytics connector\n const bqConnector = new BigQueryAnalyticsConnector(\n (analytics.credentials as any).projectId,\n (analytics.credentials as any).datasetId,\n (analytics.credentials as any).region || 'asia-south1',\n debug,\n (analytics.credentials as any).keyFilePath\n );\n\n if (debug) {\n console.log('\\n🎯 Using real navigation data from BigQuery GA4 export...');\n }\n\n // Fetch navigation data\n const navigationData = await bqConnector.fetchNavigationSequences(analytics.dataRange);\n\n if (navigationData.length === 0) {\n console.warn('⚠️ No navigation data found, using manual rules only');\n prefetchModel = createManualModel(manualRules, environment);\n return;\n }\n\n // Train model using Markov chain ML with Bayesian probability\n // Uses real navigation data to predict likely route transitions\n if (debug) {\n console.log(`\\n🤖 Training model using Markov Chain ML...`);\n }\n const mlTrainer = new MarkovChainTrainer(analytics.model, debug);\n const prefetchModelResult = mlTrainer.trainMLModel(navigationData, environment);\n prefetchModel = prefetchModelResult;\n\n // Cache model\n await cacheManager.set(environment, prefetchModel);\n } catch (error) {\n if (debug) {\n console.error('❌ Failed to fetch analytics data:', error);\n }\n if (debug) {\n console.log('⚠️ Falling back to manual rules only');\n }\n\n // Fallback to manual rules\n prefetchModel = createManualModel(manualRules, environment);\n\n // Don't fail the build, just warn\n if (debug) {\n console.error('Error details:', error);\n }\n }\n },\n\n async writeBundle(outputOptions) {\n if (!prefetchModel) {\n if (debug) {\n console.warn('⚠️ No prefetch model available, skipping config generation');\n }\n return;\n }\n\n // Read manifest from disk instead of bundle\n const fs = await import('node:fs');\n const path = await import('node:path');\n\n const outDir = outputOptions.dir || 'dist';\n const manifestPath = path.join(outDir, '.vite', 'manifest.json');\n\n if (!fs.existsSync(manifestPath)) {\n if (debug) {\n console.warn('⚠️ Vite manifest not found at:', manifestPath);\n }\n return;\n }\n\n const manifestContent = fs.readFileSync(manifestPath, 'utf-8');\n const manifest: ViteManifest = JSON.parse(manifestContent);\n\n if (debug) {\n console.log(`\\n📦 Vite manifest loaded: ${Object.keys(manifest).length} entries`);\n }\n\n // Generate final config with chunk mappings\n const generator = new ConfigGenerator(manifest, manualRules, debug);\n const finalConfig = generator.generate(prefetchModel);\n\n // Validate chunks\n const validation = generator.validateChunks(finalConfig);\n if (!validation.valid && debug) {\n console.warn('⚠️ Some chunks could not be mapped:');\n validation.missing.forEach((m) => console.warn(` ${m}`));\n } else if (debug) {\n console.log(`✅ All ${Object.keys(finalConfig.chunks).length} chunks successfully mapped with real build hashes`);\n }\n\n // Write prefetch-config.json to disk\n const configPath = path.join(outDir, 'prefetch-config.json');\n fs.writeFileSync(configPath, JSON.stringify(finalConfig, null, 2));\n\n // Save model routes for testing purposes\n const modelRoutesPath = path.join(outDir, 'model-routes.json');\n fs.writeFileSync(modelRoutesPath, JSON.stringify(prefetchModel.routes, null, 2));\n\n if (debug) {\n console.log('✅ Emitted prefetch-config.json with real chunk hashes');\n console.log('✅ Emitted model-routes.json');\n console.log(`📊 Total routes configured: ${Object.keys(finalConfig.routes).length}`);\n console.log(`📦 Total chunks: ${Object.keys(finalConfig.chunks).length}`);\n }\n\n // Generate analytics dashboard if requested\n if (analytics?.dashboard) {\n const dashboardHtml = generateDashboard(finalConfig);\n const dashboardPath = path.join(outDir, 'prefetch-report.html');\n fs.writeFileSync(dashboardPath, dashboardHtml);\n\n if (debug) {\n console.log('✅ Emitted prefetch-report.html');\n }\n }\n },\n\n transformIndexHtml() {\n // Inject runtime configuration and initialize prefetch manager\n return [\n {\n tag: 'script',\n attrs: { type: 'module' },\n children: `\n // Smart Prefetch Plugin Runtime Config\n window.__SMART_PREFETCH__ = {\n strategy: '${strategy}',\n framework: '${framework}',\n debug: ${debug},\n };\n\n // Initialize prefetch manager after page load\n // This allows the app to be built first, then PrefetchManager can load the config\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', initPrefetch);\n } else {\n initPrefetch();\n }\n\n async function initPrefetch() {\n try {\n // Dynamically import PrefetchManager from the bundled app\n // The app should have @farmart/vite-plugin-smart-prefetch/runtime in its dependencies\n const { PrefetchManager } = await import('@farmart/vite-plugin-smart-prefetch/runtime');\n const manager = new PrefetchManager('${strategy}', ${debug});\n await manager.init();\n\n // Expose manager globally for debugging\n window.__PREFETCH_MANAGER__ = manager;\n if (${debug}) {\n console.log('✅ Smart Prefetch Manager initialized');\n }\n } catch (error) {\n if (${debug}) {\n console.warn('⚠️ Could not initialize Smart Prefetch Manager:', error);\n console.log('This is expected if:');\n console.log('1. @farmart/vite-plugin-smart-prefetch/runtime is not installed');\n console.log('2. prefetch-config.json was not generated (BigQuery data fetch failed)');\n }\n }\n }\n `,\n injectTo: 'head',\n },\n ];\n },\n };\n}\n\n/**\n * Create a model from manual rules only (no analytics)\n */\nfunction createManualModel(\n manualRules: Record<string, string[]>,\n environment: string\n): PrefetchModel {\n const model: PrefetchModel = {\n version: '1.0.0',\n generatedAt: new Date().toISOString(),\n environment,\n routes: {},\n dataSource: {\n provider: 'manual',\n dateRange: 'N/A',\n totalSessions: 0,\n totalRoutes: Object.keys(manualRules).length,\n },\n config: {\n type: 'probability',\n threshold: 1.0,\n maxPrefetch: 10,\n },\n };\n\n Object.entries(manualRules).forEach(([source, targets]) => {\n model.routes[source] = {\n prefetch: targets.map((target) => ({\n route: target,\n probability: 1.0,\n count: 0,\n priority: 'high',\n manual: true,\n })),\n };\n });\n\n return model;\n}\n\n/**\n * Generate analytics dashboard HTML\n */\nfunction generateDashboard(config: any): string {\n const totalRoutes = Object.keys(config.routes).length;\n const totalPrefetches = Object.values(config.routes).reduce(\n (sum: number, route: any) => sum + route.prefetch.length,\n 0\n );\n\n return `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>Smart Prefetch Report</title>\n <style>\n body {\n font-family: system-ui, -apple-system, sans-serif;\n max-width: 1200px;\n margin: 0 auto;\n padding: 2rem;\n background: #f5f5f5;\n }\n h1 { color: #333; }\n .stats {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n gap: 1rem;\n margin: 2rem 0;\n }\n .stat-card {\n background: white;\n padding: 1.5rem;\n border-radius: 8px;\n box-shadow: 0 2px 4px rgba(0,0,0,0.1);\n }\n .stat-value { font-size: 2rem; font-weight: bold; color: #4CAF50; }\n .stat-label { color: #666; margin-top: 0.5rem; }\n .route-list {\n background: white;\n padding: 1.5rem;\n border-radius: 8px;\n box-shadow: 0 2px 4px rgba(0,0,0,0.1);\n }\n .route-item {\n padding: 1rem;\n border-bottom: 1px solid #eee;\n }\n .route-item:last-child { border-bottom: none; }\n .route-source { font-weight: bold; color: #333; }\n .prefetch-target {\n margin-left: 2rem;\n padding: 0.5rem;\n color: #666;\n }\n .priority-high { color: #4CAF50; }\n .priority-medium { color: #FF9800; }\n .priority-low { color: #9E9E9E; }\n </style>\n</head>\n<body>\n <h1>🚀 Smart Prefetch Report</h1>\n <p>Generated: ${config.generatedAt}</p>\n <p>Environment: ${config.environment}</p>\n\n <div class=\"stats\">\n <div class=\"stat-card\">\n <div class=\"stat-value\">${totalRoutes}</div>\n <div class=\"stat-label\">Routes with Prefetch</div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-value\">${totalPrefetches}</div>\n <div class=\"stat-label\">Total Prefetch Targets</div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-value\">${config.dataSource?.totalSessions?.toLocaleString() || 'N/A'}</div>\n <div class=\"stat-label\">Sessions Analyzed</div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-value\">${(config.model.threshold * 100).toFixed(0)}%</div>\n <div class=\"stat-label\">Probability Threshold</div>\n </div>\n </div>\n\n <div class=\"route-list\">\n <h2>Prefetch Configuration</h2>\n ${Object.entries(config.routes)\n .map(\n ([source, data]: [string, any]) => `\n <div class=\"route-item\">\n <div class=\"route-source\">${source}</div>\n ${data.prefetch\n .map(\n (target: any) => `\n <div class=\"prefetch-target\">\n → ${target.route}\n <span class=\"priority-${target.priority}\">\n (${(target.probability * 100).toFixed(1)}%, ${target.priority})\n </span>\n </div>\n `\n )\n .join('')}\n </div>\n `\n )\n .join('')}\n </div>\n</body>\n</html>`;\n}\n"],"mappings":"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","names":["path","candidates","path","fs","path"]}
|