From cfd91517f74854bddfe24d2ed35c5b910ba4da8b Mon Sep 17 00:00:00 2001 From: Shigma <1700011071@pku.edu.cn> Date: Wed, 31 Mar 2021 01:19:54 +0800 Subject: [PATCH] feat(core): teleport plugin under another plugin --- packages/koishi-core/src/context.ts | 36 ++++++++++++++++++-------- packages/plugin-teach/src/index.ts | 7 +++-- packages/plugin-webui/server/data.ts | 9 ++++--- packages/plugin-webui/server/server.ts | 1 - 4 files changed, 34 insertions(+), 19 deletions(-) diff --git a/packages/koishi-core/src/context.ts b/packages/koishi-core/src/context.ts index 8a52bfea93..634c78edf5 100644 --- a/packages/koishi-core/src/context.ts +++ b/packages/koishi-core/src/context.ts @@ -153,14 +153,27 @@ export class Context { } } - addDependency(plugin: string | Plugin) { - if (typeof plugin === 'string') { - plugin = require(plugin) as Plugin - } - const parent = this.app.registry.get(plugin) - if (!parent) throw new Error('dependency has not been installed') - this.state.dependencies.add(parent) - if (this.state.sideEffect) this.addSideEffect(parent) + private teleport(parent: Plugin, callback: Plugin) { + const state = this.app.registry.get(parent) + if (!state) return + this.plugin(callback) + const dispose = () => this.dispose(callback) + state.disposables.push(dispose) + this.before('disconnect', () => { + remove(state.disposables, dispose) + }) + } + + with(dependency: string, callback: Plugin) { + let parent: Plugin + try { + parent = require(dependency) + } catch {} + if (!parent) return + this.teleport(parent, callback) + this.on('plugin-added', (added) => { + if (added === parent) this.teleport(parent, callback) + }) } plugin(plugin: T, options?: Plugin.Config): this @@ -194,7 +207,7 @@ export class Context { } this.state.children.push(plugin) - this.emit('registry', this.app.registry) + this.emit('plugin-added', plugin, this.app.registry) return this } @@ -208,7 +221,7 @@ export class Context { ]).finally(() => { this.app.registry.delete(plugin) remove(state.parent.children, plugin) - this.emit('registry', this.app.registry) + this.emit('plugin-removed', plugin, this.app.registry) }) } @@ -524,7 +537,8 @@ export interface EventMap extends SessionEventMap { 'before-command'(argv: Argv): Awaitable 'command'(argv: Argv): Awaitable 'middleware'(session: Session): void - 'registry'(registry: Map): void + 'plugin-added'(plugin: Plugin, registry: Map): void + 'plugin-removed'(plugin: Plugin, registry: Map): void 'before-connect'(): Awaitable 'connect'(): void 'before-disconnect'(): Awaitable diff --git a/packages/plugin-teach/src/index.ts b/packages/plugin-teach/src/index.ts index f9f3480db4..f996307402 100644 --- a/packages/plugin-teach/src/index.ts +++ b/packages/plugin-teach/src/index.ts @@ -205,10 +205,9 @@ export function apply(ctx: Context, config: Config = {}) { ctx.plugin(time, config) ctx.plugin(writer, config) - const webui = ctx.app.webui - if (webui) { + ctx.with('koishi-plugin-webui', (ctx) => { + const { webui } = ctx.app const { stats, meta } = webui.sources - ctx.addDependency('koishi-plugin-webui') ctx.on('dialogue/before-send', ({ session, dialogue }) => { session._sendType = 'dialogue' @@ -243,5 +242,5 @@ export function apply(ctx: Context, config: Config = {}) { ctx.before('disconnect', () => { delete webui.entries['teach.js'] }) - } + }) } diff --git a/packages/plugin-webui/server/data.ts b/packages/plugin-webui/server/data.ts index 3840d64c10..915e53dfa2 100644 --- a/packages/plugin-webui/server/data.ts +++ b/packages/plugin-webui/server/data.ts @@ -182,9 +182,12 @@ export class Registry implements DataSource { payload: Registry.Payload constructor(private ctx: Context, public config: Registry.Config) { - ctx.on('registry', async () => { - this.ctx.app.webui.adapter?.broadcast('registry', await this.get(true)) - }) + ctx.on('plugin-added', this.update) + ctx.on('plugin-removed', this.update) + } + + update = async () => { + this.ctx.app.webui.adapter?.broadcast('registry', await this.get(true)) } async get(forced = false) { diff --git a/packages/plugin-webui/server/server.ts b/packages/plugin-webui/server/server.ts index 1a2f84b7bd..246efa608a 100644 --- a/packages/plugin-webui/server/server.ts +++ b/packages/plugin-webui/server/server.ts @@ -71,7 +71,6 @@ export class WebServer { } const stats = await fs.stat(filename).catch(noop) if (stats?.isFile()) return sendFile(filename) - console.log(ctx.path, stats) let template = await fs.readFile(resolve(this.root, 'index.html'), 'utf8') if (vite) template = await vite.transformIndexHtml(uiPath, template) ctx.type = 'html'