UNPKG

fortify2-js

Version:

MOST POWERFUL JavaScript Security Library! Military-grade cryptography + 19 enhanced object methods + quantum-resistant algorithms + perfect TypeScript support. More powerful than Lodash with built-in security.

340 lines (336 loc) 12.4 kB
'use strict'; var events = require('events'); var index = require('../../../../components/fortified-function/index.js'); var PluginTypes = require('./types/PluginTypes.js'); /** * Ultra-Fast Plugin Registry * * Central registry for managing plugins with <0.1ms registration overhead * and intelligent lifecycle management for optimal performance. */ /** * Ultra-fast plugin registry with intelligent management */ class PluginRegistry extends events.EventEmitter { constructor(cache, cluster, config) { super(); this.plugins = new Map(); this.pluginsByType = new Map(); this.pluginStats = new Map(); this.isInitialized = false; // Performance optimization: Pre-sorted plugin arrays by priority this.sortedPluginCache = new Map(); this.lastCacheUpdate = 0; this.CACHE_TTL = 5000; // 5 seconds this.cache = cache; this.cluster = cluster; this.config = { maxPlugins: 100, enableHotReload: true, enableProfiling: true, performanceThresholds: { maxExecutionTime: 10, // 10ms max maxMemoryUsage: 50 * 1024 * 1024, // 50MB maxCpuUsage: 80, // 80% }, ...config, }; this.logger = this.createLogger(); this.initializePluginTypes(); } /** * Initialize plugin type maps for ultra-fast lookups */ initializePluginTypes() { Object.values(PluginTypes.PluginType).forEach((type) => { this.pluginsByType.set(type, []); this.sortedPluginCache.set(type, []); }); } /** * Create optimized logger for plugin operations */ createLogger() { const fortifiedLogger = index.func((level, message, data) => { new Date().toISOString(); if (level === "error") { console.error(`[PluginRegistry] ${message}`, data); } else if (level === "warn") { console.warn(`[PluginRegistry] ${message}`, data); } else if (level === "debug" && process.env.NODE_ENV === "development") { console.debug(`[PluginRegistry] ${message}`, data); } else { console.log(`[PluginRegistry] ${message}`, data); } }, { ultraFast: "maximum", auditLog: false }); return { debug: (message, data) => fortifiedLogger("debug", message, data), info: (message, data) => fortifiedLogger("info", message, data), warn: (message, data) => fortifiedLogger("warn", message, data), error: (message, error) => fortifiedLogger("error", message, error), performance: (pluginId, executionTime) => { if (this.config.enableProfiling) { fortifiedLogger("performance", `Plugin ${pluginId} executed in ${executionTime}ms`); } }, }; } /** * Register a plugin with ultra-fast registration (<0.1ms) */ async register(plugin) { const startTime = performance.now(); try { // Validate plugin this.validatePlugin(plugin); // Check if plugin already exists if (this.plugins.has(plugin.id)) { throw new Error(`Plugin ${plugin.id} is already registered`); } // Check plugin limit if (this.plugins.size >= this.config.maxPlugins) { throw new Error(`Maximum plugin limit (${this.config.maxPlugins}) reached`); } // Initialize plugin if needed if (plugin.initialize) { const initContext = { cache: this.cache, cluster: this.cluster, config: { maxExecutionTime: plugin.maxExecutionTime, enableProfiling: this.config.enableProfiling, enableCaching: plugin.isCacheable, enableEncryption: false, enableAuditLogging: false, securityLevel: "basic", customSettings: {}, }, logger: this.logger, }; await plugin.initialize(initContext); } // Precompile plugin if supported if (plugin.precompile) { await plugin.precompile(); } // Register plugin this.plugins.set(plugin.id, plugin); // Add to type-specific collection const typePlugins = this.pluginsByType.get(plugin.type) || []; typePlugins.push(plugin); this.pluginsByType.set(plugin.type, typePlugins); // Initialize stats this.pluginStats.set(plugin.id, { pluginId: plugin.id, executionCount: 0, totalExecutionTime: 0, averageExecutionTime: 0, errorCount: 0, lastExecuted: new Date(), performanceScore: 100, }); // Invalidate sorted cache this.invalidateSortedCache(); const registrationTime = performance.now() - startTime; this.logger.info(`Plugin ${plugin.id} registered in ${registrationTime.toFixed(3)}ms`); // Emit event this.emitPluginEvent(PluginTypes.PluginEventType.PLUGIN_REGISTERED, plugin.id, { type: plugin.type, priority: plugin.priority, registrationTime, }); } catch (error) { this.logger.error(`Failed to register plugin ${plugin.id}`, error); throw error; } } /** * Unregister a plugin */ async unregister(pluginId) { const plugin = this.plugins.get(pluginId); if (!plugin) { throw new Error(`Plugin ${pluginId} not found`); } try { // Cleanup plugin if supported if (plugin.cleanup) { // Create minimal context for cleanup const cleanupContext = { pluginData: new Map(), security: { isAuthenticated: false, roles: [], permissions: [], }, metrics: { requestStartTime: Date.now(), pluginExecutionTimes: new Map(), cacheHits: 0, cacheMisses: 0, }, }; await plugin.cleanup(cleanupContext); } // Remove from collections this.plugins.delete(pluginId); this.pluginStats.delete(pluginId); // Remove from type-specific collection const typePlugins = this.pluginsByType.get(plugin.type) || []; const filteredPlugins = typePlugins.filter((p) => p.id !== pluginId); this.pluginsByType.set(plugin.type, filteredPlugins); // Invalidate sorted cache this.invalidateSortedCache(); this.logger.info(`Plugin ${pluginId} unregistered`); // Emit event this.emitPluginEvent(PluginTypes.PluginEventType.PLUGIN_UNREGISTERED, pluginId); } catch (error) { this.logger.error(`Failed to unregister plugin ${pluginId}`, error); throw error; } } /** * Get plugins by type with ultra-fast sorted lookup */ getPluginsByType(type) { const now = Date.now(); // Check if cache is valid if (now - this.lastCacheUpdate < this.CACHE_TTL) { return this.sortedPluginCache.get(type) || []; } // Rebuild sorted cache const plugins = this.pluginsByType.get(type) || []; const sortedPlugins = plugins.sort((a, b) => a.priority - b.priority); this.sortedPluginCache.set(type, sortedPlugins); this.lastCacheUpdate = now; return sortedPlugins; } /** * Get plugin by ID */ getPlugin(pluginId) { return this.plugins.get(pluginId); } /** * Get all registered plugins */ getAllPlugins() { return Array.from(this.plugins.values()); } /** * Get plugin execution statistics */ getPluginStats(pluginId) { return this.pluginStats.get(pluginId); } /** * Get all plugin statistics */ getAllStats() { return Array.from(this.pluginStats.values()); } /** * Update plugin execution statistics */ updateStats(pluginId, executionTime, success) { const stats = this.pluginStats.get(pluginId); if (!stats) return; stats.executionCount++; stats.totalExecutionTime += executionTime; stats.averageExecutionTime = stats.totalExecutionTime / stats.executionCount; stats.lastExecuted = new Date(); if (!success) { stats.errorCount++; } // Calculate performance score (0-100) const errorRate = stats.errorCount / stats.executionCount; const timeScore = Math.max(0, 100 - (stats.averageExecutionTime / 10) * 100); const errorScore = Math.max(0, 100 - errorRate * 100); stats.performanceScore = (timeScore + errorScore) / 2; // Check performance thresholds if (executionTime > this.config.performanceThresholds.maxExecutionTime) { this.emitPluginEvent(PluginTypes.PluginEventType.PERFORMANCE_THRESHOLD_EXCEEDED, pluginId, { executionTime, threshold: this.config.performanceThresholds.maxExecutionTime, }); } } /** * Validate plugin before registration */ validatePlugin(plugin) { if (!plugin.id || typeof plugin.id !== "string") { throw new Error("Plugin must have a valid string ID"); } if (!plugin.name || typeof plugin.name !== "string") { throw new Error("Plugin must have a valid string name"); } if (!plugin.version || typeof plugin.version !== "string") { throw new Error("Plugin must have a valid string version"); } if (!Object.values(PluginTypes.PluginType).includes(plugin.type)) { throw new Error(`Invalid plugin type: ${plugin.type}`); } if (!Object.values(PluginTypes.PluginPriority).includes(plugin.priority)) { throw new Error(`Invalid plugin priority: ${plugin.priority}`); } if (typeof plugin.execute !== "function") { throw new Error("Plugin must have an execute method"); } if (plugin.maxExecutionTime <= 0) { throw new Error("Plugin maxExecutionTime must be positive"); } } /** * Invalidate sorted plugin cache */ invalidateSortedCache() { this.lastCacheUpdate = 0; } /** * Emit plugin event */ emitPluginEvent(type, pluginId, data) { const event = { type, pluginId, timestamp: new Date(), data, }; this.emit(type, event); } /** * Get registry statistics (ultra-fast optimized) */ getRegistryStats() { const totalPlugins = this.plugins.size; const pluginsByType = {}; let totalExecutions = 0; let totalExecutionTime = 0; // Ultra-fast: Only count plugins that actually exist (avoid iterating all enum values) this.pluginsByType.forEach((plugins, type) => { pluginsByType[type] = plugins.length; }); // Ultra-fast: Single iteration through stats this.pluginStats.forEach((stats) => { totalExecutions += stats.executionCount; totalExecutionTime += stats.totalExecutionTime; }); return { totalPlugins, pluginsByType, averageExecutionTime: totalExecutions > 0 ? totalExecutionTime / totalExecutions : 0, totalExecutions, }; } } exports.PluginRegistry = PluginRegistry; //# sourceMappingURL=PluginRegistry.js.map