import { existsSync, readFileSync } from "node:fs"; import { join, resolve } from "node:path"; interface BuildReport { frameworkVersion: string; generatedAt: string; adapter: string; routes: Array<{ path: string; source: string; sourceBytes: number; dynamicParams: string[]; optimization?: { staticNodes: number; reactiveRegions: number; eliminatedBranches: number; unusedState: string[]; unusedHandlers: string[]; constantProps: string[]; unusedLocalCssClasses: string[]; batchableStateUpdates: number; memoizableComponents: string[]; preloadDependencies: string[]; serverOnlyModules: string[]; }; }>; assets: Array<{ file: string; bytes: number }>; measurements: Record; budgetViolations: Array<{ metric: string; budget: number; actual: number; overBy: number }>; } function bytes(value: number): string { if (value < 1024) return `${value} B`; if (value < 1024 * 1024) return `${(value / 1024).toFixed(1)} KB`; return `${(value / 1024 / 1024).toFixed(2)} MB`; } export function runAnalyze(appRoot: string, args: string[]): boolean { const root = resolve(appRoot); const path = join(root, "dist", "build-report.json"); if (!existsSync(path)) { console.error("WRN-BUILD-REPORT-MISSING: run `wrnexus build` before `wrnexus analyze`."); return false; } const report = JSON.parse(readFileSync(path, "utf8")) as BuildReport; if (args.includes("--json")) { console.log(JSON.stringify(report, null, 2)); return report.budgetViolations.length === 0; } console.log(`WRNexus build analysis (${report.frameworkVersion})`); console.log(` Generated: ${report.generatedAt}`); console.log(` Adapter: ${report.adapter}`); console.log(` Routes: ${report.routes.length}`); console.log("\nMeasurements:"); for (const [metric, value] of Object.entries(report.measurements)) { console.log(` ${metric.padEnd(18)} ${bytes(value)}`); } console.log("\nLargest assets:"); for (const asset of report.assets.slice(0, 12)) { console.log(` ${bytes(asset.bytes).padStart(10)} ${asset.file}`); } console.log("\nCompiler optimizations:"); for (const route of report.routes.filter((item) => item.optimization)) { const optimization = route.optimization!; console.log( ` ${route.path}: ${optimization.staticNodes} static nodes, ${optimization.reactiveRegions} reactive regions, ${optimization.eliminatedBranches} branches removed`, ); if ( optimization.unusedState.length || optimization.unusedHandlers.length || optimization.unusedLocalCssClasses.length ) console.log( ` candidates: ${[...optimization.unusedState, ...optimization.unusedHandlers, ...optimization.unusedLocalCssClasses].join(", ")}`, ); } if (report.budgetViolations.length) { console.log("\nBudget violations:"); for (const violation of report.budgetViolations) { console.log( ` ✗ ${violation.metric}: ${bytes(violation.actual)} > ${bytes(violation.budget)}`, ); } } else { console.log("\n ✓ No configured performance budget violations."); } return report.budgetViolations.length === 0; }