import { ApiModule, ModuleMetadata } from './types.js' import { ServiceContainer } from './container.js' export class ModuleManager { private modules = new Map() private activeModules = new Set() private container: ServiceContainer constructor(container: ServiceContainer) { this.container = container } async register(module: ApiModule): Promise { const { id, dependencies = [] } = module.metadata for (const dep of dependencies) { if (!this.modules.has(dep)) { throw new Error(`Module '${id}' depends on '${dep}' which is not registered`) } } this.modules.set(id, module) if (module.lifecycle?.onLoad) { await module.lifecycle.onLoad(this.container) } } async activate(id: string): Promise { const module = this.modules.get(id) if (!module) { throw new Error(`Module '${id}' not found`) } if (this.activeModules.has(id)) { return } const { dependencies = [] } = module.metadata for (const dep of dependencies) { await this.activate(dep) } if (module.lifecycle?.onActivate) { await module.lifecycle.onActivate(this.container) } this.activeModules.add(id) } async deactivate(id: string): Promise { const module = this.modules.get(id) if (!module) return if (!this.activeModules.has(id)) return if (module.lifecycle?.onDeactivate) { await module.lifecycle.onDeactivate(this.container) } this.activeModules.delete(id) } getModule(id: string): ApiModule | undefined { return this.modules.get(id) } getAllModules(): ApiModule[] { return Array.from(this.modules.values()) .sort((a, b) => (a.metadata.order || 0) - (b.metadata.order || 0)) } getActiveModules(): string[] { return Array.from(this.activeModules) } }