Files
XCDesktop/api/infra/moduleManager.ts

77 lines
1.8 KiB
TypeScript
Raw Permalink Normal View History

2026-03-08 01:34:54 +08:00
import { ApiModule, ModuleMetadata } from './types.js'
import { ServiceContainer } from './container.js'
export class ModuleManager {
private modules = new Map<string, ApiModule>()
private activeModules = new Set<string>()
private container: ServiceContainer
constructor(container: ServiceContainer) {
this.container = container
}
async register(module: ApiModule): Promise<void> {
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<void> {
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<void> {
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)
}
}