/** * Module Registry * Manages module registration and dependency tracking */ export class ModuleRegistry { constructor() { this.modules = {}; this.readyPromises = {}; } /** * Register a module * @param {BaseModule} module - Module to register */ register(module) { if (!module || !module.id) { console.error('Invalid module - must have an id property'); return; } this.modules[module.id] = module; // Create a promise that will resolve when this module is ready this.readyPromises[module.id] = new Promise((resolve) => { // Set up a state change listener for this module document.addEventListener('module:stateChange', (event) => { if (event.detail.moduleId === module.id && (event.detail.state === 'FINISHED' || event.detail.state === 'ERROR')) { resolve(event.detail.state === 'FINISHED'); } }); // Check if already in finished state if (module.state === 'FINISHED') { resolve(true); } else if (module.state === 'ERROR') { resolve(false); } }); } /** * Get a module by id * @param {string} id - Module id * @returns {BaseModule} - The module, or null if not found */ getModule(id) { return this.modules[id] || null; } /** * Get all registered modules * @returns {Object} - Map of modules */ getAllModules() { return this.modules; } /** * Wait for a module to be ready (in FINISHED state) * @param {string} id - Module id to wait for * @param {number} timeout - Optional timeout in ms * @returns {Promise} - Resolves when the module is ready */ waitForModule(id, timeout = null) { if (!this.readyPromises[id]) { return Promise.resolve(false); } if (timeout) { // Add timeout logic return Promise.race([ this.readyPromises[id], new Promise(resolve => setTimeout(() => resolve(false), timeout)) ]); } return this.readyPromises[id]; } /** * Wait for multiple modules to be ready * @param {Array} ids - Array of module ids to wait for * @param {number} timeout - Optional timeout in ms * @returns {Promise} - Resolves when all modules are ready */ waitForModules(ids, timeout = null) { const promises = ids.map(id => this.waitForModule(id, timeout)); return Promise.all(promises); } } // Create and export a singleton instance export const moduleRegistry = new ModuleRegistry();