import { ExportModuleData, SyncData } from '@/types/module' import router, { registerRouter } from 'common/utils/router' class RegisterModule { modules: Array<{ modulePath?: string, module: ExportModuleData, load: boolean }> = [] registed = false registedPromise = Promise.resolve() promises: Array<{ modulePath: string|undefined, module: Promise|ExportModuleData }> = [] registedHandlers: Array<(data: SyncData[]) => void> = [] constructor () { this.init() } init () { router.beforeEach(async (to, from, next) => { const path = to.path if (this.registed === false) await this.registedPromise const modules = this.modules const target = modules.find(item => item.modulePath && path.startsWith(item.modulePath)) if (target?.load === false) { const routes = await target.module.async() registerRouter(routes) target.load = true next(to.fullPath) } else { next(true) } }) } register (modulePath: string|undefined, module: () => Promise|ExportModuleData) { this.promises.push({ modulePath, module: module() }) } async registerEnd () { const handle = async () => { const datas = await Promise.allSettled(this.promises.map(module => module.module)) this.modules = datas.reduce((arr, item, index) => { if (item.status === 'fulfilled') { arr.push({ modulePath: this.promises[index].modulePath, module: item.value, load: false }) } return arr }, [] as Array<{ modulePath?: string, module: ExportModuleData, load: boolean }>) this.registedHandlers.forEach(handler => { try { handler(this.getSyncData()) } catch (error) { console.error(error) } }) } this.registedPromise = handle() this.registedPromise.finally(() => { this.registed = true }) } registedHandler (handler: (data: SyncData[]) => void) { if (this.registed) { try { handler(this.getSyncData()) } catch (error) { console.error(error) } } else { this.registedHandlers.push(handler) } } getSyncData () { return this.modules.map(item => item.module.sync) } } export default new RegisterModule()