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

225 lines • 6.84 kB
// Lazy Handler Registry - Performance Optimization // Implements on-demand handler loading for 30% startup improvement /** * LazyHandlerRegistry - Implements lazy loading for MCP handlers * Target: 30% startup time improvement through on-demand loading */ export class LazyHandlerRegistry { lazyHandlers = new Map(); loadedHandlers = new Map(); loadingErrors = []; fallbackConfig = { retryAttempts: 1, fallbackToEager: false, notifyOnFailure: true }; /** * Register a handler for lazy loading */ registerLazyHandler(name, constructor, config = {}) { this.lazyHandlers.set(name, { constructor, config: { priority: 'medium', loadOnDemand: true, ...config }, loaded: false }); } /** * Check if a handler is loaded */ isHandlerLoaded(name) { return this.loadedHandlers.has(name); } /** * Get count of loaded handlers */ getLoadedHandlerCount() { return this.loadedHandlers.size; } /** * Get total registered handler count */ getTotalHandlerCount() { return this.lazyHandlers.size; } /** * Load a specific handler on demand */ async loadHandler(name) { // Return if already loaded if (this.loadedHandlers.has(name)) { return this.loadedHandlers.get(name); } const lazyHandler = this.lazyHandlers.get(name); if (!lazyHandler) { return null; } try { // Attempt to load with retry logic let lastError = null; for (let attempt = 0; attempt < this.fallbackConfig.retryAttempts + 1; attempt++) { try { const instance = lazyHandler.constructor(); // Mark as loaded lazyHandler.loaded = true; lazyHandler.instance = instance; this.loadedHandlers.set(name, instance); return instance; } catch (error) { lastError = error; if (attempt < this.fallbackConfig.retryAttempts) { // Wait before retry await new Promise(resolve => setTimeout(resolve, 100)); } } } // All attempts failed if (lastError) { this.recordLoadingError(name, lastError); } return null; } catch (error) { this.recordLoadingError(name, error); return null; } } /** * Get all available tools from loaded and lazy handlers */ async getAllAvailableTools() { const tools = []; // Load all handlers to get their tools for (const handlerName of this.lazyHandlers.keys()) { const handler = await this.loadHandler(handlerName); if (handler && handler.tools) { tools.push(...handler.tools); } } return tools; } /** * Get available tool names without loading handlers (fast discovery) */ getAvailableToolNames() { const toolNames = []; for (const [, handlerInfo] of this.lazyHandlers) { if (handlerInfo.config.toolNames) { toolNames.push(...handlerInfo.config.toolNames); } } return toolNames; } /** * Execute a tool from a specific handler (loads handler if needed) */ async executeToolFromHandler(handlerName, toolName, args) { const handler = await this.loadHandler(handlerName); if (!handler) { throw new Error(`Handler ${handlerName} could not be loaded`); } if (typeof handler.handle === 'function') { return await handler.handle(toolName, args, new Map()); } throw new Error(`Handler ${handlerName} does not implement handle method`); } /** * Configure fallback behavior */ configureFallback(config) { this.fallbackConfig = { ...this.fallbackConfig, ...config }; } /** * Get loading errors */ getLoadingErrors() { return [...this.loadingErrors]; } /** * Get failure notifications */ getFailureNotifications() { return this.loadingErrors .filter(error => this.fallbackConfig.notifyOnFailure) .map(error => ({ handlerName: error.handlerName, message: error.error.message, timestamp: error.timestamp })); } /** * Clear all handlers and reset registry */ clear() { this.lazyHandlers.clear(); this.loadedHandlers.clear(); this.loadingErrors.length = 0; } /** * Get handler categories */ getHandlersByCategory(category) { const handlers = []; for (const [name, info] of this.lazyHandlers) { if (info.config.category === category) { handlers.push(name); } } return handlers; } /** * Load handlers by priority */ async loadHandlersByPriority(priority) { const loadedHandlers = []; for (const [name, info] of this.lazyHandlers) { if (info.config.priority === priority) { const handler = await this.loadHandler(name); if (handler) { loadedHandlers.push(name); } } } return loadedHandlers; } /** * Get performance metrics */ getPerformanceMetrics() { const totalRegistered = this.lazyHandlers.size; const totalLoaded = this.loadedHandlers.size; const totalErrors = this.loadingErrors.length; return { totalRegistered, totalLoaded, loadingEfficiency: totalRegistered > 0 ? (totalLoaded / totalRegistered) : 0, failureRate: totalRegistered > 0 ? (totalErrors / totalRegistered) : 0 }; } /** * Record loading error */ recordLoadingError(handlerName, error) { const existingError = this.loadingErrors.find(e => e.handlerName === handlerName); if (existingError) { existingError.retryCount++; } else { this.loadingErrors.push({ handlerName, error, timestamp: new Date(), retryCount: 0 }); } } } /** * Global lazy handler registry instance */ export const globalLazyHandlerRegistry = new LazyHandlerRegistry(); //# sourceMappingURL=lazy-handler-registry.js.map