UNPKG

ai-debug-local-mcp

Version:

🎯 ENHANCED AI GUIDANCE v4.1.2: Dramatically improved tool descriptions help AI users choose the right tools instead of 'close enough' options. Ultra-fast keyboard automation (10x speed), universal recording, multi-ecosystem debugging support, and compreh

230 lines • 9.73 kB
/** * Analysis Module * Handles analysis and auditing of meta-framework performance and patterns */ export class MetaFrameworkAnalysis { dataCollection; constructor(dataCollection) { this.dataCollection = dataCollection; } /** * Analyze Remix loader performance and patterns */ async analyzeRemixLoaders(page) { const loaderData = await this.dataCollection.getRemixLoaderData(page); const routeModules = await this.dataCollection.getRemixRouteModules(page); if (loaderData.length === 0) { return { totalLoaders: 0, slowLoaders: 0, averageLoadTime: 0, recommendations: ['No loader data available - ensure monitoring is active'] }; } const totalLoaders = loaderData.length; const slowLoaders = loaderData.filter(loader => loader.duration > 1000).length; const averageLoadTime = loaderData.reduce((sum, loader) => sum + loader.duration, 0) / totalLoaders; const cachedLoaders = loaderData.filter(loader => loader.cached).length; const recommendations = []; if (slowLoaders > 0) { recommendations.push(`${slowLoaders} slow loaders detected (>1s). Consider caching or optimization.`); } if (cachedLoaders / totalLoaders < 0.3) { recommendations.push('Low cache hit rate. Consider implementing better caching strategies.'); } if (averageLoadTime > 500) { recommendations.push('High average load time. Consider parallel data fetching.'); } // Analyze route complexity const routeComplexity = Object.values(routeModules).filter((route) => route.hasLoader && route.hasAction).length; if (routeComplexity > totalLoaders * 0.8) { recommendations.push('Many routes have both loaders and actions. Consider separation of concerns.'); } return { totalLoaders, slowLoaders, averageLoadTime: Math.round(averageLoadTime), cachedLoaders, cacheHitRate: Math.round((cachedLoaders / totalLoaders) * 100), routeComplexity, recommendations, routes: Object.keys(routeModules) }; } /** * Audit Astro island hydration patterns */ async auditAstroIslands(page) { const islands = await this.dataCollection.getAstroIslands(page); if (islands.length === 0) { return { totalIslands: 0, heavyIslands: 0, hydrationStrategy: 'none', recommendations: ['No islands detected - static site or monitoring not active'] }; } const totalIslands = islands.length; const heavyIslands = islands.filter(island => island.hydrationDirective === 'load' && island.loading === 'eager').length; const hydrationStrategies = islands.reduce((acc, island) => { acc[island.hydrationDirective || 'load'] = (acc[island.hydrationDirective || 'load'] || 0) + 1; return acc; }, {}); const recommendations = []; if (heavyIslands > totalIslands * 0.5) { recommendations.push('Many islands use eager loading. Consider lazy hydration for better performance.'); } if (hydrationStrategies.load > totalIslands * 0.7) { recommendations.push('Most islands use immediate hydration. Consider client:idle or client:visible.'); } if (!hydrationStrategies.visible && totalIslands > 5) { recommendations.push('Consider using client:visible for below-the-fold components.'); } const hydrationStrategy = heavyIslands < totalIslands * 0.3 ? 'optimal' : heavyIslands < totalIslands * 0.7 ? 'moderate' : 'aggressive'; return { totalIslands, heavyIslands, hydrationStrategy, hydrationStrategies, recommendations, components: islands.map(i => i.component) }; } /** * Analyze Nuxt payload and performance */ async analyzeNuxtPayload(page) { const nuxtData = await this.dataCollection.getNuxtPayload(page); const payloadSize = JSON.stringify(nuxtData.payload).length; const routeCount = nuxtData.routes.length; const navigationCount = nuxtData.navigationTimes.length; const recommendations = []; if (payloadSize > 100000) { // 100KB recommendations.push('Large payload detected. Consider reducing initial data or using lazy loading.'); } if (navigationCount > 0) { const avgNavigationTime = nuxtData.navigationTimes.reduce((sum, nav) => sum + (nav.timestamp || 0), 0) / navigationCount; if (avgNavigationTime > 1000) { recommendations.push('Slow navigation detected. Consider route-level code splitting.'); } } return { payloadSize, routeCount, navigationCount, serverRendered: nuxtData.payload.serverRendered, version: nuxtData.version, recommendations }; } /** * Check Qwik resumability performance */ async checkQwikResumability(page) { const qwikData = await this.dataCollection.getQwikResumability(page); if (!qwikData) { return { resumable: false, recommendations: ['Qwik resumability not detected or monitoring not active'] }; } const recommendations = []; if (qwikData.serializedState > 1000) { recommendations.push('Large serialized state. Consider optimizing state management.'); } if (qwikData.qrlCount > 500) { recommendations.push('Many QRL functions detected. Monitor bundle impact.'); } if (qwikData.resumeTime > 100) { recommendations.push('Slow resume time. Check for blocking operations in resumability.'); } const resumabilityScore = Math.max(0, 100 - Math.floor(qwikData.resumeTime / 10) - Math.floor(qwikData.serializedState / 100)); return { resumable: true, serializedState: qwikData.serializedState, qrlCount: qwikData.qrlCount, symbolsLoaded: qwikData.symbolsLoaded, resumeTime: qwikData.resumeTime, resumabilityScore, recommendations }; } /** * Monitor Vite HMR performance */ async monitorViteHMR(page) { const hmrEvents = await this.dataCollection.getViteHMREvents(page); if (hmrEvents.length === 0) { return { active: false, recommendations: ['No HMR events detected - check Vite development server'] }; } const updateEvents = hmrEvents.filter(event => event.type === 'update'); const errorEvents = hmrEvents.filter(event => event.type === 'error'); const reloadEvents = hmrEvents.filter(event => event.type === 'full-reload'); const recommendations = []; if (errorEvents.length > updateEvents.length * 0.1) { recommendations.push('High HMR error rate. Check for syntax or type errors.'); } if (reloadEvents.length > updateEvents.length * 0.2) { recommendations.push('Frequent full reloads. Check HMR boundary configuration.'); } const errorRate = updateEvents.length > 0 ? (errorEvents.length / updateEvents.length) * 100 : 0; const reloadRate = updateEvents.length > 0 ? (reloadEvents.length / updateEvents.length) * 100 : 0; return { active: true, totalEvents: hmrEvents.length, updateEvents: updateEvents.length, errorEvents: errorEvents.length, reloadEvents: reloadEvents.length, errorRate: Math.round(errorRate), reloadRate: Math.round(reloadRate), recommendations }; } /** * General framework performance analysis */ async analyzeFrameworkPerformance(page, framework) { const info = await this.dataCollection.getMetaFrameworkInfo(page); const analysis = { framework, timestamp: info.timestamp, url: info.url, performance: {}, recommendations: [] }; // Framework-specific performance analysis switch (framework) { case 'remix': analysis.performance = await this.analyzeRemixLoaders(page); break; case 'astro': analysis.performance = await this.auditAstroIslands(page); break; case 'nuxt': analysis.performance = await this.analyzeNuxtPayload(page); break; case 'qwik': analysis.performance = await this.checkQwikResumability(page); break; default: analysis.performance = { message: `No specific analysis available for ${framework}` }; } // General recommendations if (info[framework]) { const frameworkInfo = info[framework]; if (frameworkInfo.version) { analysis.version = frameworkInfo.version; } // Add framework-specific recommendations analysis.recommendations.push(`Consider monitoring ${framework} specific metrics for better insights.`); } return analysis; } } //# sourceMappingURL=meta-framework-analysis.js.map