UNPKG

@ordojs/dev-tools

Version:

Advanced developer tools for OrdoJS with component inspector, AST explorer, and performance profiling

1,671 lines (1,661 loc) 54.8 kB
import { EventEmitter } from 'events'; var __defProp = Object.defineProperty; var __getOwnPropNames = Object.getOwnPropertyNames; var __esm = (fn, res) => function __init() { return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res; }; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; // src/ast-explorer/index.ts var ast_explorer_exports = {}; __export(ast_explorer_exports, { ASTExplorer: () => ASTExplorer }); var ASTExplorer; var init_ast_explorer = __esm({ "src/ast-explorer/index.ts"() { ASTExplorer = class extends EventEmitter { astNodes; isRunning; port; /** * Create a new ASTExplorer instance * * @param port - WebSocket port for AST explorer */ constructor(port = 24681) { super(); this.astNodes = /* @__PURE__ */ new Map(); this.isRunning = false; this.port = port; } /** * Start the AST explorer */ async start() { if (this.isRunning) { console.warn("AST explorer is already running"); return; } try { await this.startWebSocketServer(); this.isRunning = true; console.log(`AST explorer started on port ${this.port}`); this.emit("started"); } catch (error) { console.error("Failed to start AST explorer:", error); this.emit("error", error); throw error; } } /** * Stop the AST explorer */ async stop() { if (!this.isRunning) { console.warn("AST explorer is not running"); return; } try { await this.stopWebSocketServer(); this.isRunning = false; console.log("AST explorer stopped"); this.emit("stopped"); } catch (error) { console.error("Failed to stop AST explorer:", error); this.emit("error", error); throw error; } } /** * Parse source code and create AST * * @param sourceCode - Source code to parse * @param fileName - File name for the AST * @returns AST root node */ parseSourceCode(sourceCode, fileName) { try { const astNode = { type: "Program", position: { start: { line: 1, column: 1 }, end: { line: 1, column: sourceCode.length } }, children: [], value: sourceCode }; this.astNodes.set(fileName, astNode); this.emit("astParsed", { fileName, astNode }); return astNode; } catch (error) { console.error("Failed to parse source code:", error); this.emit("error", error); throw error; } } /** * Get AST for a file * * @param fileName - File name * @returns AST node or undefined */ getAST(fileName) { return this.astNodes.get(fileName); } /** * Get all ASTs * * @returns Map of all ASTs */ getAllASTs() { return new Map(this.astNodes); } /** * Find nodes by type * * @param fileName - File name * @param nodeType - Node type to search for * @returns Array of matching nodes */ findNodesByType(fileName, nodeType) { const ast = this.astNodes.get(fileName); if (!ast) { return []; } return this.findNodesRecursive(ast, nodeType); } /** * Find nodes by value * * @param fileName - File name * @param value - Value to search for * @returns Array of matching nodes */ findNodesByValue(fileName, value) { const ast = this.astNodes.get(fileName); if (!ast) { return []; } return this.findNodesByValueRecursive(ast, value); } /** * Get node path from root * * @param fileName - File name * @param targetNode - Target node * @returns Array of nodes from root to target */ getNodePath(fileName, targetNode) { const ast = this.astNodes.get(fileName); if (!ast) { return []; } return this.findNodePath(ast, targetNode); } /** * Get AST statistics * * @param fileName - File name * @returns AST statistics */ getASTStats(fileName) { const ast = this.astNodes.get(fileName); if (!ast) { return { totalNodes: 0, nodeTypes: {}, maxDepth: 0, averageDepth: 0 }; } const stats = this.calculateASTStats(ast); return stats; } /** * Clear all ASTs */ clearASTs() { this.astNodes.clear(); this.emit("astsCleared"); } /** * Recursively find nodes by type * * @param node - Current node * @param nodeType - Node type to search for * @returns Array of matching nodes */ findNodesRecursive(node, nodeType) { const results = []; if (node.type === nodeType) { results.push(node); } if (node.children) { for (const child of node.children) { results.push(...this.findNodesRecursive(child, nodeType)); } } return results; } /** * Recursively find nodes by value * * @param node - Current node * @param value - Value to search for * @returns Array of matching nodes */ findNodesByValueRecursive(node, value) { const results = []; if (node.value && node.value.includes(value)) { results.push(node); } if (node.children) { for (const child of node.children) { results.push(...this.findNodesByValueRecursive(child, value)); } } return results; } /** * Find path from root to target node * * @param node - Current node * @param targetNode - Target node * @param path - Current path * @returns Path to target node or empty array */ findNodePath(node, targetNode, path = []) { const currentPath = [...path, node]; if (node === targetNode) { return currentPath; } if (node.children) { for (const child of node.children) { const result = this.findNodePath(child, targetNode, currentPath); if (result.length > 0) { return result; } } } return []; } /** * Calculate AST statistics * * @param node - Root node * @param depth - Current depth * @returns AST statistics */ calculateASTStats(node, depth = 0) { let totalNodes = 1; const nodeTypes = { [node.type]: 1 }; let maxDepth = depth; let totalDepth = depth; if (node.children) { for (const child of node.children) { const childStats = this.calculateASTStats(child, depth + 1); totalNodes += childStats.totalNodes; maxDepth = Math.max(maxDepth, childStats.maxDepth); totalDepth += childStats.totalNodes * (depth + 1); for (const [type, count] of Object.entries(childStats.nodeTypes)) { nodeTypes[type] = (nodeTypes[type] || 0) + count; } } } return { totalNodes, nodeTypes, maxDepth, averageDepth: totalDepth / totalNodes }; } /** * Start WebSocket server for AST explorer communication */ async startWebSocketServer() { console.log("Starting WebSocket server for AST explorer..."); } /** * Stop WebSocket server */ async stopWebSocketServer() { console.log("Stopping WebSocket server for AST explorer..."); } }; } }); // src/bundle-analyzer/index.ts var bundle_analyzer_exports = {}; __export(bundle_analyzer_exports, { BundleAnalyzer: () => BundleAnalyzer }); var BundleAnalyzer; var init_bundle_analyzer = __esm({ "src/bundle-analyzer/index.ts"() { BundleAnalyzer = class extends EventEmitter { analyses; isRunning; port; /** * Create a new BundleAnalyzer instance * * @param port - WebSocket port for bundle analyzer */ constructor(port = 24682) { super(); this.analyses = /* @__PURE__ */ new Map(); this.isRunning = false; this.port = port; } /** * Start the bundle analyzer */ async start() { if (this.isRunning) { console.warn("Bundle analyzer is already running"); return; } try { await this.startWebSocketServer(); this.isRunning = true; console.log(`Bundle analyzer started on port ${this.port}`); this.emit("started"); } catch (error) { console.error("Failed to start bundle analyzer:", error); this.emit("error", error); throw error; } } /** * Stop the bundle analyzer */ async stop() { if (!this.isRunning) { console.warn("Bundle analyzer is not running"); return; } try { await this.stopWebSocketServer(); this.isRunning = false; console.log("Bundle analyzer stopped"); this.emit("stopped"); } catch (error) { console.error("Failed to stop bundle analyzer:", error); this.emit("error", error); throw error; } } /** * Analyze a bundle file * * @param bundlePath - Path to the bundle file * @param bundleName - Name for the bundle analysis * @returns Bundle analysis result */ async analyzeBundle(bundlePath, bundleName) { try { const analysis = { size: 0, gzippedSize: 0, modules: [], chunks: [], dependencies: [], warnings: [], errors: [] }; await this.simulateBundleAnalysis(bundlePath, analysis); this.analyses.set(bundleName, analysis); this.emit("bundleAnalyzed", { bundleName, analysis }); return analysis; } catch (error) { console.error("Failed to analyze bundle:", error); this.emit("error", error); throw error; } } /** * Get bundle analysis by name * * @param bundleName - Bundle name * @returns Bundle analysis or undefined */ getAnalysis(bundleName) { return this.analyses.get(bundleName); } /** * Get all bundle analyses * * @returns Array of all bundle analyses */ getAllAnalyses() { return Array.from(this.analyses.values()); } /** * Compare two bundle analyses * * @param bundleName1 - First bundle name * @param bundleName2 - Second bundle name * @returns Comparison result */ compareBundles(bundleName1, bundleName2) { const analysis1 = this.analyses.get(bundleName1); const analysis2 = this.analyses.get(bundleName2); if (!analysis1 || !analysis2) { throw new Error("One or both bundle analyses not found"); } const sizeDifference = analysis2.size - analysis1.size; const sizeDifferencePercent = sizeDifference / analysis1.size * 100; const moduleCountDifference = analysis2.modules.length - analysis1.modules.length; const dependencyCountDifference = analysis2.dependencies.length - analysis1.dependencies.length; const modules1 = new Set(analysis1.modules.map((m) => m.name)); const modules2 = new Set(analysis2.modules.map((m) => m.name)); const newModules = analysis2.modules.filter((m) => !modules1.has(m.name)).map((m) => m.name); const removedModules = analysis1.modules.filter((m) => !modules2.has(m.name)).map((m) => m.name); const deps1 = new Set(analysis1.dependencies.map((d) => d.name)); const deps2 = new Set(analysis2.dependencies.map((d) => d.name)); const newDependencies = analysis2.dependencies.filter((d) => !deps1.has(d.name)).map((d) => d.name); const removedDependencies = analysis1.dependencies.filter((d) => !deps2.has(d.name)).map((d) => d.name); return { sizeDifference, sizeDifferencePercent, moduleCountDifference, dependencyCountDifference, newModules, removedModules, newDependencies, removedDependencies }; } /** * Get bundle optimization suggestions * * @param bundleName - Bundle name * @returns Optimization suggestions */ getOptimizationSuggestions(bundleName) { const analysis = this.analyses.get(bundleName); if (!analysis) { throw new Error("Bundle analysis not found"); } const moduleCounts = /* @__PURE__ */ new Map(); for (const module of analysis.modules) { moduleCounts.set(module.name, (moduleCounts.get(module.name) || 0) + 1); } const duplicateModules = Array.from(moduleCounts.entries()).filter(([_, count]) => count > 1).map(([name, _]) => name); const largeModules = analysis.modules.filter((module) => module.size > 100 * 1024).map((module) => module.name); const unusedDependencies = []; const codeSplittingOpportunities = analysis.modules.filter((module) => module.size > 50 * 1024 && !module.name.includes("vendor")).map((module) => module.name); const compressionOpportunities = analysis.modules.filter((module) => module.size > 10 * 1024).map((module) => module.name); return { duplicateModules, largeModules, unusedDependencies, codeSplittingOpportunities, compressionOpportunities }; } /** * Get bundle statistics * * @param bundleName - Bundle name * @returns Bundle statistics */ getBundleStats(bundleName) { const analysis = this.analyses.get(bundleName); if (!analysis) { throw new Error("Bundle analysis not found"); } const totalSize = analysis.size; const gzippedSize = analysis.gzippedSize; const moduleCount = analysis.modules.length; const dependencyCount = analysis.dependencies.length; const averageModuleSize = totalSize / moduleCount || 0; const largestModule = analysis.modules.length > 0 ? analysis.modules.reduce( (largest, current) => current.size > largest.size ? current : largest ) : null; const largestModuleSize = largestModule ? largestModule.size : 0; return { totalSize, gzippedSize, moduleCount, dependencyCount, averageModuleSize, largestModule: largestModule ? largestModule.name : "", largestModuleSize }; } /** * Clear all bundle analyses */ clearAnalyses() { this.analyses.clear(); this.emit("analysesCleared"); } /** * Simulate bundle analysis (placeholder implementation) * * @param bundlePath - Path to bundle file * @param analysis - Analysis object to populate */ async simulateBundleAnalysis(bundlePath, analysis) { const fs = await import('fs/promises'); try { const stats = await fs.stat(bundlePath); analysis.size = stats.size; analysis.gzippedSize = Math.round(analysis.size * 0.3); analysis.modules = [ { name: "main.js", size: Math.round(analysis.size * 0.6), dependencies: ["react", "react-dom"], exports: ["App", "main"], path: bundlePath }, { name: "vendor.js", size: Math.round(analysis.size * 0.4), dependencies: ["lodash", "moment"], exports: ["vendor"], path: bundlePath } ]; analysis.chunks = [ { name: "main", size: analysis.modules[0]?.size || 0, modules: ["main.js"], entry: true }, { name: "vendor", size: analysis.modules[1]?.size || 0, modules: ["vendor.js"], entry: false } ]; analysis.dependencies = [ { name: "react", version: "18.2.0", size: 100 * 1024, type: "production" }, { name: "react-dom", version: "18.2.0", size: 150 * 1024, type: "production" }, { name: "lodash", version: "4.17.21", size: 70 * 1024, type: "production" } ]; } catch (error) { analysis.errors.push(`Failed to analyze bundle: ${error instanceof Error ? error.message : String(error)}`); } } /** * Start WebSocket server for bundle analyzer communication */ async startWebSocketServer() { console.log("Starting WebSocket server for bundle analyzer..."); } /** * Stop WebSocket server */ async stopWebSocketServer() { console.log("Stopping WebSocket server for bundle analyzer..."); } }; } }); // src/development-server/index.ts var development_server_exports = {}; __export(development_server_exports, { DevelopmentServer: () => DevelopmentServer }); var DevelopmentServer; var init_development_server = __esm({ "src/development-server/index.ts"() { DevelopmentServer = class extends EventEmitter { config; isRunning; server; // Express server instance /** * Create a new DevelopmentServer instance * * @param config - Development server configuration */ constructor(config) { super(); this.config = config; this.isRunning = false; this.server = null; } /** * Start the development server */ async start() { if (this.isRunning) { console.warn("Development server is already running"); return; } try { await this.initializeServer(); await this.startServer(); this.isRunning = true; console.log(`Development server started on http://${this.config.host}:${this.config.port}`); this.emit("started"); } catch (error) { console.error("Failed to start development server:", error); this.emit("error", error); throw error; } } /** * Stop the development server */ async stop() { if (!this.isRunning) { console.warn("Development server is not running"); return; } try { await this.stopServer(); this.isRunning = false; console.log("Development server stopped"); this.emit("stopped"); } catch (error) { console.error("Failed to stop development server:", error); this.emit("error", error); throw error; } } /** * Get server status * * @returns Server status information */ getStatus() { return { isRunning: this.isRunning, port: this.config.port, host: this.config.host, config: this.config }; } /** * Update server configuration * * @param newConfig - New configuration */ updateConfig(newConfig) { this.config = { ...this.config, ...newConfig }; this.emit("configUpdated", this.config); } /** * Initialize Express server */ async initializeServer() { try { const express = await import('express'); const cors = await import('cors'); const compression = await import('compression'); const serveStatic = await import('serve-static'); const morgan = await import('morgan'); const helmet = await import('helmet'); const app = express.default(); if (this.config.cors) { app.use(cors.default()); } if (this.config.compression) { app.use(compression.default()); } app.use(helmet.default()); app.use(morgan.default("combined")); app.use(serveStatic.default(this.config.staticDir)); this.setupDevToolsRoutes(app); app.use(this.errorHandler.bind(this)); this.server = app; } catch (error) { console.error("Failed to initialize Express server:", error); throw error; } } /** * Start the server */ async startServer() { return new Promise((resolve, reject) => { if (!this.server) { reject(new Error("Server not initialized")); return; } const server = this.server.listen(this.config.port, this.config.host, () => { console.log(`Development server listening on http://${this.config.host}:${this.config.port}`); resolve(); }); server.on("error", (error) => { console.error("Server error:", error); reject(error); }); }); } /** * Stop the server */ async stopServer() { return new Promise((resolve, reject) => { if (!this.server) { resolve(); return; } const server = this.server; server.close((error) => { if (error) { console.error("Error stopping server:", error); reject(error); } else { console.log("Server stopped"); resolve(); } }); }); } /** * Setup dev tools API routes * * @param app - Express app instance */ setupDevToolsRoutes(app) { app.get("/api/dev-tools/health", (req, res) => { res.json({ status: "healthy", timestamp: (/* @__PURE__ */ new Date()).toISOString(), config: this.config }); }); app.get("/api/dev-tools/inspector", (req, res) => { res.json({ components: [], stats: { totalComponents: 0, totalRenderCount: 0, averageRenderTime: 0, peakMemoryUsage: 0 } }); }); app.get("/api/dev-tools/profiler", (req, res) => { res.json({ profiles: [], stats: { totalProfiles: 0, activeProfiles: 0, totalMeasurements: 0, averageProfileDuration: 0 } }); }); app.get("/api/dev-tools/ast-explorer", (req, res) => { res.json({ asts: [], stats: { totalASTs: 0, totalNodes: 0, averageDepth: 0 } }); }); app.get("/api/dev-tools/bundle-analyzer", (req, res) => { res.json({ analyses: [], stats: { totalAnalyses: 0, totalSize: 0, averageSize: 0 } }); }); app.get("/api/dev-tools/error-overlay", (req, res) => { res.json({ errors: [], stats: { totalErrors: 0, errorsByType: {}, errorsByFile: {} } }); }); app.get("/api/dev-tools/hmr", (req, res) => { res.json({ updates: [], stats: { totalUpdates: 0, updatesByType: {}, updatesByFile: {}, averageUpdateTime: 0 } }); }); } /** * Error handling middleware * * @param err - Error object * @param req - Request object * @param res - Response object * @param next - Next function */ errorHandler(err, req, res, next) { console.error("Server error:", err); res.status(500).json({ error: { message: err.message, stack: process.env.NODE_ENV === "development" ? err.stack : void 0 } }); } }; } }); // src/error-overlay/index.ts var error_overlay_exports = {}; __export(error_overlay_exports, { ErrorOverlay: () => ErrorOverlay }); var ErrorOverlay; var init_error_overlay = __esm({ "src/error-overlay/index.ts"() { ErrorOverlay = class extends EventEmitter { errors; isRunning; port; /** * Create a new ErrorOverlay instance * * @param port - WebSocket port for error overlay */ constructor(port = 24683) { super(); this.errors = /* @__PURE__ */ new Map(); this.isRunning = false; this.port = port; } /** * Start the error overlay */ async start() { if (this.isRunning) { console.warn("Error overlay is already running"); return; } try { await this.startWebSocketServer(); this.isRunning = true; console.log(`Error overlay started on port ${this.port}`); this.emit("started"); } catch (error) { console.error("Failed to start error overlay:", error); this.emit("error", error); throw error; } } /** * Stop the error overlay */ async stop() { if (!this.isRunning) { console.warn("Error overlay is not running"); return; } try { await this.stopWebSocketServer(); this.isRunning = false; console.log("Error overlay stopped"); this.emit("stopped"); } catch (error) { console.error("Failed to stop error overlay:", error); this.emit("error", error); throw error; } } /** * Add an error to the overlay * * @param errorId - Unique error identifier * @param errorInfo - Error information */ addError(errorId, errorInfo) { this.errors.set(errorId, errorInfo); this.emit("errorAdded", { errorId, errorInfo }); } /** * Update an error * * @param errorId - Error identifier * @param updates - Error updates */ updateError(errorId, updates) { const error = this.errors.get(errorId); if (error) { const updatedError = { ...error, ...updates }; this.errors.set(errorId, updatedError); this.emit("errorUpdated", { errorId, errorInfo: updatedError }); } } /** * Remove an error * * @param errorId - Error identifier */ removeError(errorId) { const error = this.errors.get(errorId); if (error) { this.errors.delete(errorId); this.emit("errorRemoved", { errorId, errorInfo: error }); } } /** * Get error by ID * * @param errorId - Error identifier * @returns Error information or undefined */ getError(errorId) { return this.errors.get(errorId); } /** * Get all errors * * @returns Array of all errors */ getAllErrors() { return Array.from(this.errors.values()); } /** * Clear all errors */ clearErrors() { this.errors.clear(); this.emit("errorsCleared"); } /** * Get error statistics * * @returns Error statistics */ getErrorStats() { const errors = Array.from(this.errors.values()); const errorsByType = {}; const errorsByFile = {}; for (const error of errors) { const errorType = this.getErrorType(error); errorsByType[errorType] = (errorsByType[errorType] || 0) + 1; if (error.filePath) { errorsByFile[error.filePath] = (errorsByFile[error.filePath] || 0) + 1; } } return { totalErrors: errors.length, errorsByType, errorsByFile }; } /** * Generate error suggestions * * @param errorId - Error identifier * @returns Array of suggestions */ generateSuggestions(errorId) { const error = this.errors.get(errorId); if (!error) { return []; } const suggestions = []; if (error.message.includes("Cannot find module")) { suggestions.push("Check if the module is installed and imported correctly"); suggestions.push("Verify the module path is correct"); suggestions.push("Try running npm install or pnpm install"); } if (error.message.includes("Unexpected token")) { suggestions.push("Check for syntax errors in your code"); suggestions.push("Verify all brackets, parentheses, and quotes are properly closed"); suggestions.push("Check for missing semicolons or commas"); } if (error.message.includes("TypeError")) { suggestions.push("Check if the variable or property exists"); suggestions.push("Verify the data type is correct"); suggestions.push("Add proper null/undefined checks"); } if (error.message.includes("ReferenceError")) { suggestions.push("Check if the variable is declared before use"); suggestions.push("Verify the variable name is spelled correctly"); suggestions.push("Check the scope of the variable"); } suggestions.push("Check the browser console for more details"); suggestions.push("Try refreshing the page"); suggestions.push("Check the documentation for the correct usage"); return suggestions; } /** * Get error type from error message * * @param error - Error information * @returns Error type */ getErrorType(error) { if (error.message.includes("Cannot find module")) { return "ModuleNotFound"; } if (error.message.includes("Unexpected token")) { return "SyntaxError"; } if (error.message.includes("TypeError")) { return "TypeError"; } if (error.message.includes("ReferenceError")) { return "ReferenceError"; } if (error.message.includes("RangeError")) { return "RangeError"; } return "Unknown"; } /** * Start WebSocket server for error overlay communication */ async startWebSocketServer() { console.log("Starting WebSocket server for error overlay..."); } /** * Stop WebSocket server */ async stopWebSocketServer() { console.log("Stopping WebSocket server for error overlay..."); } }; } }); // src/hmr/index.ts var hmr_exports = {}; __export(hmr_exports, { EnhancedHMR: () => EnhancedHMR }); var EnhancedHMR; var init_hmr = __esm({ "src/hmr/index.ts"() { EnhancedHMR = class extends EventEmitter { updates; isRunning; port; statePreservation; /** * Create a new EnhancedHMR instance * * @param port - WebSocket port for enhanced HMR * @param statePreservation - Enable state preservation */ constructor(port = 24684, statePreservation = true) { super(); this.updates = /* @__PURE__ */ new Map(); this.isRunning = false; this.port = port; this.statePreservation = statePreservation; } /** * Start the enhanced HMR */ async start() { if (this.isRunning) { console.warn("Enhanced HMR is already running"); return; } try { await this.startWebSocketServer(); this.isRunning = true; console.log(`Enhanced HMR started on port ${this.port}`); this.emit("started"); } catch (error) { console.error("Failed to start enhanced HMR:", error); this.emit("error", error); throw error; } } /** * Stop the enhanced HMR */ async stop() { if (!this.isRunning) { console.warn("Enhanced HMR is not running"); return; } try { await this.stopWebSocketServer(); this.isRunning = false; console.log("Enhanced HMR stopped"); this.emit("stopped"); } catch (error) { console.error("Failed to stop enhanced HMR:", error); this.emit("error", error); throw error; } } /** * Send an HMR update * * @param update - HMR update information */ sendUpdate(update) { const updateId = this.generateUpdateId(update); this.updates.set(updateId, update); this.emit("updateSent", { updateId, update }); } /** * Get update by ID * * @param updateId - Update identifier * @returns HMR update or undefined */ getUpdate(updateId) { return this.updates.get(updateId); } /** * Get all updates * * @returns Array of all updates */ getAllUpdates() { return Array.from(this.updates.values()); } /** * Clear all updates */ clearUpdates() { this.updates.clear(); this.emit("updatesCleared"); } /** * Get HMR statistics * * @returns HMR statistics */ getHMRStats() { const updates = Array.from(this.updates.values()); const updatesByType = {}; const updatesByFile = {}; let totalUpdateTime = 0; for (const update of updates) { updatesByType[update.type] = (updatesByType[update.type] || 0) + 1; updatesByFile[update.filePath] = (updatesByFile[update.filePath] || 0) + 1; totalUpdateTime += Date.now() - update.timestamp; } const averageUpdateTime = updates.length > 0 ? totalUpdateTime / updates.length : 0; return { totalUpdates: updates.length, updatesByType, updatesByFile, averageUpdateTime }; } /** * Enable state preservation */ enableStatePreservation() { this.statePreservation = true; this.emit("statePreservationEnabled"); } /** * Disable state preservation */ disableStatePreservation() { this.statePreservation = false; this.emit("statePreservationDisabled"); } /** * Check if state preservation is enabled * * @returns True if state preservation is enabled */ isStatePreservationEnabled() { return this.statePreservation; } /** * Generate update ID * * @param update - HMR update * @returns Update ID */ generateUpdateId(update) { return `${update.type}-${update.filePath}-${update.timestamp}`; } /** * Start WebSocket server for enhanced HMR communication */ async startWebSocketServer() { console.log("Starting WebSocket server for enhanced HMR..."); } /** * Stop WebSocket server */ async stopWebSocketServer() { console.log("Stopping WebSocket server for enhanced HMR..."); } }; } }); // src/inspector/index.ts var inspector_exports = {}; __export(inspector_exports, { ComponentInspector: () => ComponentInspector }); var ComponentInspector; var init_inspector = __esm({ "src/inspector/index.ts"() { ComponentInspector = class extends EventEmitter { components; isRunning; port; /** * Create a new ComponentInspector instance * * @param port - WebSocket port for inspector */ constructor(port = 24679) { super(); this.components = /* @__PURE__ */ new Map(); this.isRunning = false; this.port = port; } /** * Start the component inspector */ async start() { if (this.isRunning) { console.warn("Component inspector is already running"); return; } try { await this.startWebSocketServer(); this.isRunning = true; console.log(`Component inspector started on port ${this.port}`); this.emit("started"); } catch (error) { console.error("Failed to start component inspector:", error); this.emit("error", error); throw error; } } /** * Stop the component inspector */ async stop() { if (!this.isRunning) { console.warn("Component inspector is not running"); return; } try { await this.stopWebSocketServer(); this.isRunning = false; console.log("Component inspector stopped"); this.emit("stopped"); } catch (error) { console.error("Failed to stop component inspector:", error); this.emit("error", error); throw error; } } /** * Register a component for inspection * * @param componentInfo - Component information */ registerComponent(componentInfo) { this.components.set(componentInfo.name, componentInfo); this.emit("componentRegistered", componentInfo); } /** * Update component information * * @param componentName - Component name * @param updates - Component updates */ updateComponent(componentName, updates) { const component = this.components.get(componentName); if (component) { const updatedComponent = { ...component, ...updates }; this.components.set(componentName, updatedComponent); this.emit("componentUpdated", updatedComponent); } } /** * Get component information * * @param componentName - Component name * @returns Component information or undefined */ getComponent(componentName) { return this.components.get(componentName); } /** * Get all components * * @returns Array of all component information */ getAllComponents() { return Array.from(this.components.values()); } /** * Get component tree * * @returns Component tree structure */ getComponentTree() { const rootComponents = []; const componentMap = new Map(this.components); for (const component of componentMap.values()) { if (!this.hasParent(component, componentMap)) { rootComponents.push(component); } } return rootComponents; } /** * Clear all components */ clearComponents() { this.components.clear(); this.emit("componentsCleared"); } /** * Get inspector statistics * * @returns Inspector statistics */ getStats() { const components = Array.from(this.components.values()); const totalRenderCount = components.reduce((sum, comp) => sum + comp.renderCount, 0); const averageRenderTime = components.reduce((sum, comp) => sum + comp.performance.averageRenderTime, 0) / components.length || 0; const peakMemoryUsage = Math.max(...components.map((comp) => comp.performance.peakMemoryUsage), 0); return { totalComponents: components.length, totalRenderCount, averageRenderTime, peakMemoryUsage }; } /** * Start WebSocket server for inspector communication */ async startWebSocketServer() { console.log("Starting WebSocket server for component inspector..."); } /** * Stop WebSocket server */ async stopWebSocketServer() { console.log("Stopping WebSocket server for component inspector..."); } /** * Check if component has a parent * * @param component - Component to check * @param componentMap - Map of all components * @returns True if component has a parent */ hasParent(component, componentMap) { for (const otherComponent of componentMap.values()) { if (otherComponent.children.some((child) => child.name === component.name)) { return true; } } return false; } }; } }); // src/profiler/index.ts var profiler_exports = {}; __export(profiler_exports, { PerformanceProfiler: () => PerformanceProfiler }); var PerformanceProfiler; var init_profiler = __esm({ "src/profiler/index.ts"() { PerformanceProfiler = class extends EventEmitter { profiles; activeProfiles; measurements; isRunning; port; /** * Create a new PerformanceProfiler instance * * @param port - WebSocket port for profiler */ constructor(port = 24680) { super(); this.profiles = /* @__PURE__ */ new Map(); this.activeProfiles = /* @__PURE__ */ new Map(); this.measurements = /* @__PURE__ */ new Map(); this.isRunning = false; this.port = port; } /** * Start the performance profiler */ async start() { if (this.isRunning) { console.warn("Performance profiler is already running"); return; } try { await this.startWebSocketServer(); this.isRunning = true; console.log(`Performance profiler started on port ${this.port}`); this.emit("started"); } catch (error) { console.error("Failed to start performance profiler:", error); this.emit("error", error); throw error; } } /** * Stop the performance profiler */ async stop() { if (!this.isRunning) { console.warn("Performance profiler is not running"); return; } try { for (const [name, profile] of this.activeProfiles) { await this.stopProfile(name); } await this.stopWebSocketServer(); this.isRunning = false; console.log("Performance profiler stopped"); this.emit("stopped"); } catch (error) { console.error("Failed to stop performance profiler:", error); this.emit("error", error); throw error; } } /** * Start a performance profile * * @param name - Profile name * @param metadata - Profile metadata * @returns Profile instance */ startProfile(name, metadata = {}) { if (this.activeProfiles.has(name)) { throw new Error(`Profile '${name}' is already active`); } const profile = { name, startTime: performance.now(), endTime: 0, duration: 0, measurements: [], metadata }; this.activeProfiles.set(name, profile); this.emit("profileStarted", profile); return profile; } /** * Stop a performance profile * * @param name - Profile name * @returns Completed profile */ stopProfile(name) { const profile = this.activeProfiles.get(name); if (!profile) { throw new Error(`Profile '${name}' is not active`); } profile.endTime = performance.now(); profile.duration = profile.endTime - profile.startTime; this.activeProfiles.delete(name); this.profiles.set(name, profile); this.emit("profileStopped", profile); return profile; } /** * Add a performance measurement * * @param profileName - Profile name * @param measurementName - Measurement name * @param category - Measurement category * @param metadata - Measurement metadata * @returns Measurement instance */ addMeasurement(profileName, measurementName, category = "general", metadata = {}) { const profile = this.activeProfiles.get(profileName); if (!profile) { throw new Error(`Profile '${profileName}' is not active`); } const measurement = { name: measurementName, startTime: performance.now(), endTime: 0, duration: 0, category, metadata }; if (!this.measurements.has(profileName)) { this.measurements.set(profileName, []); } this.measurements.get(profileName).push(measurement); profile.measurements.push(measurement); this.emit("measurementAdded", measurement); return measurement; } /** * End a performance measurement * * @param profileName - Profile name * @param measurementName - Measurement name * @returns Completed measurement */ endMeasurement(profileName, measurementName) { const profile = this.activeProfiles.get(profileName); if (!profile) { throw new Error(`Profile '${profileName}' is not active`); } const measurements = this.measurements.get(profileName); if (!measurements) { throw new Error(`No measurements found for profile '${profileName}'`); } const measurement = measurements.find((m) => m.name === measurementName); if (!measurement) { throw new Error(`Measurement '${measurementName}' not found in profile '${profileName}'`); } measurement.endTime = performance.now(); measurement.duration = measurement.endTime - measurement.startTime; this.emit("measurementEnded", measurement); return measurement; } /** * Get a profile by name * * @param name - Profile name * @returns Profile or undefined */ getProfile(name) { return this.profiles.get(name) || this.activeProfiles.get(name); } /** * Get all profiles * * @returns Array of all profiles */ getAllProfiles() { return Array.from(this.profiles.values()); } /** * Get active profiles * * @returns Array of active profiles */ getActiveProfiles() { return Array.from(this.activeProfiles.values()); } /** * Clear all profiles */ clearProfiles() { this.profiles.clear(); this.activeProfiles.clear(); this.measurements.clear(); this.emit("profilesCleared"); } /** * Get profiler statistics * * @returns Profiler statistics */ getStats() { const allProfiles = Array.from(this.profiles.values()); const totalMeasurements = allProfiles.reduce((sum, profile) => sum + profile.measurements.length, 0); const averageProfileDuration = allProfiles.reduce((sum, profile) => sum + profile.duration, 0) / allProfiles.length || 0; return { totalProfiles: allProfiles.length, activeProfiles: this.activeProfiles.size, totalMeasurements, averageProfileDuration }; } /** * Start WebSocket server for profiler communication */ async startWebSocketServer() { console.log("Starting WebSocket server for performance profiler..."); } /** * Stop WebSocket server */ async stopWebSocketServer() { console.log("Stopping WebSocket server for performance profiler..."); } }; } }); // src/index.ts init_ast_explorer(); init_bundle_analyzer(); init_development_server(); init_error_overlay(); init_hmr(); init_inspector(); init_profiler(); var DevToolsManager = class extends EventEmitter { config; isRunning; tools; /** * Create a new DevToolsManager instance * * @param config - Dev tools configuration */ constructor(config = {}) { super(); this.config = { inspector: true, profiler: true, astExplorer: true, bundleAnalyzer: true, errorOverlay: true, enhancedHMR: true, devServer: { port: 3e3, host: "localhost", hmr: true, https: false, compression: true, cors: true, staticDir: "dist" }, ...config }; this.isRunning = false; this.tools = /* @__PURE__ */ new Map(); } /** * Start all dev tools */ async start() { if (this.isRunning) { console.warn("Dev tools are already running"); return; }