/** * Module Manager - Centralized dynamic import management * Handles loading and caching of ES modules to reduce memory overhead */ class ModuleManager { constructor() { this._cache = new Map(); this._loadingPromises = new Map(); } /** * Initialize all commonly used ES modules at once * @returns {Promise} Object containing all loaded modules */ async initializeCommonModules() { const modules = await Promise.all([ this.getModule('chalk'), this.getModule('ora'), this.getModule('inquirer') ]); return { chalk: modules[0], ora: modules[1], inquirer: modules[2] }; } /** * Get a module by name, with caching * @param {string} moduleName - Name of the module to load * @returns {Promise} The loaded module */ async getModule(moduleName) { // Return from cache if available if (this._cache.has(moduleName)) { return this._cache.get(moduleName); } // If already loading, return the existing promise if (this._loadingPromises.has(moduleName)) { return this._loadingPromises.get(moduleName); } // Start loading the module const loadPromise = this._loadModule(moduleName); this._loadingPromises.set(moduleName, loadPromise); try { const module = await loadPromise; this._cache.set(moduleName, module); this._loadingPromises.delete(moduleName); return module; } catch (error) { this._loadingPromises.delete(moduleName); throw error; } } /** * Internal method to load a specific module * @private */ async _loadModule(moduleName) { switch (moduleName) { case 'chalk': return (await import('chalk')).default; case 'ora': return (await import('ora')).default; case 'inquirer': return (await import('inquirer')).default; case 'glob': return (await import('glob')).glob; case 'globSync': return (await import('glob')).globSync; default: throw new Error(`Unknown module: ${moduleName}`); } } /** * Clear the module cache to free memory */ clearCache() { this._cache.clear(); this._loadingPromises.clear(); } /** * Get multiple modules at once * @param {string[]} moduleNames - Array of module names * @returns {Promise} Object with module names as keys */ async getModules(moduleNames) { const modules = await Promise.all( moduleNames.map(name => this.getModule(name)) ); return moduleNames.reduce((acc, name, index) => { acc[name] = modules[index]; return acc; }, {}); } } // Singleton instance const moduleManager = new ModuleManager(); module.exports = moduleManager;