Skip to content

Commit

Permalink
feat(core): support Context.delegate
Browse files Browse the repository at this point in the history
  • Loading branch information
shigma committed Mar 31, 2021
1 parent a9b4cf4 commit 84dc676
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 49 deletions.
30 changes: 14 additions & 16 deletions packages/koishi-core/src/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -487,25 +487,23 @@ export class Context {
})
}))).flat(1)
}
}

export function delegate(ctx: Context, key: string & keyof Context) {
const privateKey = Symbol(key)
Object.defineProperty(ctx, key, {
get() {
return this.app[privateKey]
},
set(value) {
if (this.app[privateKey] && this.app[privateKey] !== value) {
this.logger('app').warn('ctx.%s is overwritten', key)
}
this.app[privateKey] = value
},
})
static delegate(key: string & keyof Context) {
if (Object.prototype.hasOwnProperty.call(Context.prototype, key)) return
const privateKey = Symbol(key)
Object.defineProperty(Context.prototype, key, {
get() {
return this.app[privateKey]
},
set(value) {
this.app[privateKey] = value
},
})
}
}

delegate(Context.prototype, 'database')
delegate(Context.prototype, 'assets')
Context.delegate('database')
Context.delegate('assets')

type FlattenEvents<T> = {
[K in keyof T & string]: K | `${K}/${FlattenEvents<T[K]>}`
Expand Down
4 changes: 2 additions & 2 deletions packages/plugin-chat/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ export const name = 'chat'
export function apply(ctx: Context, options: Config = {}) {
ctx.plugin(debug, options)
ctx.with('koishi-plugin-webui', () => {
const { config, entries } = ctx.app.webui
const { config, entries } = ctx.webui

const filename = resolve(__dirname, config.devMode ? '../client' : '../dist/index.js')
const filename = resolve(__dirname, config.devMode ? '../client/index.ts' : '../dist/index.js')
entries.chat = filename
ctx.before('disconnect', () => {
delete entries.chat
Expand Down
6 changes: 3 additions & 3 deletions packages/plugin-teach/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -206,8 +206,8 @@ export function apply(ctx: Context, config: Config = {}) {
ctx.plugin(writer, config)

ctx.with('koishi-plugin-webui', (ctx) => {
const { config, entries } = ctx.app.webui
const { stats, meta } = ctx.app.webui.sources
const { config, entries } = ctx.webui
const { stats, meta } = ctx.webui.sources

ctx.on('dialogue/before-send', ({ session, dialogue }) => {
session._sendType = 'dialogue'
Expand Down Expand Up @@ -236,7 +236,7 @@ export function apply(ctx: Context, config: Config = {}) {
payload.questions = Object.values(questionMap)
})

const filename = resolve(__dirname, config.devMode ? '../client' : '../dist/index.js')
const filename = resolve(__dirname, config.devMode ? '../client/index.ts' : '../dist/index.js')
entries.teach = filename
ctx.before('disconnect', () => {
delete entries.teach
Expand Down
16 changes: 13 additions & 3 deletions packages/plugin-webui/build/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ function build(root: string, config: vite.UserConfig) {
} : undefined,
},
},
plugins: [pluginVue],
resolve: {
alias: {
'vue': root + '/vue.js',
Expand All @@ -50,7 +51,6 @@ function build(root: string, config: vite.UserConfig) {
// build for index.html
await build(root, {
base: './',
plugins: [pluginVue],
resolve: {
alias: {
'~/variables': root + '/index.scss',
Expand All @@ -76,15 +76,25 @@ function build(root: string, config: vite.UserConfig) {
},
})

// build for koishi-plugin-chat
const chat = resolve(__dirname, '../../plugin-chat/client')
await build(chat, {
build: {
assetsDir: '',
rollupOptions: {
input: chat + '/index.ts',
},
},
})

// build for koishi-plugin-teach
const teach = resolve(__dirname, '../../plugin-teach/client')
build(teach, {
await build(teach, {
build: {
assetsDir: '',
rollupOptions: {
input: teach + '/index.ts',
},
},
plugins: [pluginVue],
})
})()
12 changes: 8 additions & 4 deletions packages/plugin-webui/src/data.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Assets, Bot, Context, Platform, Plugin, Time } from 'koishi-core'
import { Argv, Assets, Bot, Context, Platform, Plugin, Time } from 'koishi-core'
import { cpus } from 'os'
import { mem } from 'systeminformation'

Expand Down Expand Up @@ -76,7 +76,7 @@ export class Profile implements DataSource<Profile.Payload> {
this.apply(ctx, config)

ctx.on('status/tick', async () => {
this.ctx.app.webui.adapter?.broadcast('profile', await this.get(true))
this.ctx.webui.adapter?.broadcast('profile', await this.get(true))
})
}

Expand Down Expand Up @@ -144,14 +144,18 @@ export class Meta implements DataSource<Meta.Payload> {
constructor(private ctx: Context, public config: Meta.Config) {
this.extend(() => ctx.assets?.stats())
this.extend(() => ctx.database?.getStats())

ctx.all().on('command', ({ session }: Argv<'lastCall'>) => {
session.user.lastCall = new Date()
})
}

async get(): Promise<Meta.Payload> {
const now = Date.now()
if (this.timestamp > now) return this.cachedMeta
this.timestamp = now + Time.hour
return this.cachedMeta = Promise
.all(this.callbacks.map(cb => cb()))
.all(this.callbacks.map(cb => cb().catch(() => ({}))))
.then(data => Object.assign({}, ...data))
}

Expand Down Expand Up @@ -187,7 +191,7 @@ export class Registry implements DataSource<Registry.Payload> {
}

update = async () => {
this.ctx.app.webui.adapter?.broadcast('registry', await this.get(true))
this.ctx.webui.adapter?.broadcast('registry', await this.get(true))
}

async get(forced = false) {
Expand Down
19 changes: 6 additions & 13 deletions packages/plugin-webui/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { interpolate, Time } from 'koishi-utils'
import { Meta } from './data'
import { Synchronizer } from './stats'
import { SandboxBot } from './adapter'
import { WebServer } from './server'
import { WebServer, Config } from './server'

import './mongo'
import './mysql'
Expand All @@ -16,7 +16,7 @@ export * from './server'
export type Activity = Record<number, number>

declare module 'koishi-core' {
interface App {
interface Context {
webui: WebServer
}

Expand Down Expand Up @@ -94,17 +94,10 @@ export const name = 'status'

export function apply(ctx: Context, config: Config = {}) {
config = Object.assign(defaultConfig, config)
const { apiPath, formatBot, format } = config

const webui = ctx.app.webui = new WebServer(ctx, config)
ctx.webui = new WebServer(ctx, config)

ctx.on('connect', () => webui.start())

ctx.all().on('command', ({ session }: Argv<'lastCall'>) => {
session.user.lastCall = new Date()
})

ctx.router.get(apiPath, async (koa) => {
ctx.router.get(config.apiPath, async (koa) => {
koa.set('Access-Control-Allow-Origin', '*')
koa.body = await getStatus()
})
Expand Down Expand Up @@ -132,8 +125,8 @@ export function apply(ctx: Context, config: Config = {}) {

async function getStatus() {
const [profile, meta] = await Promise.all([
webui.sources.profile.get(),
webui.sources.meta.get(),
ctx.webui.sources.profile.get(),
ctx.webui.sources.meta.get(),
])
return { ...profile, ...meta }
}
Expand Down
22 changes: 14 additions & 8 deletions packages/plugin-webui/src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,16 @@ import { Statistics } from './stats'
import type * as Vite from 'vite'
import type PluginVue from '@vitejs/plugin-vue'

export namespace WebServer {
export interface Config extends WebAdapter.Config, Profile.Config, Meta.Config, Registry.Config, Statistics.Config {
title?: string
selfUrl?: string
uiPath?: string
devMode?: boolean
}
Context.delegate('webui')

export interface Config extends WebAdapter.Config, Profile.Config, Meta.Config, Registry.Config, Statistics.Config {
title?: string
selfUrl?: string
uiPath?: string
devMode?: boolean
}

export namespace WebServer {
export interface Global {
title: string
uiPath: string
Expand All @@ -37,7 +39,7 @@ export class WebServer {
sources: WebServer.Sources
entries: Record<string, string> = {}

constructor(private ctx: Context, public config: WebServer.Config) {
constructor(private ctx: Context, public config: Config) {
this.root = resolve(__dirname, '..', config.devMode ? 'client' : 'dist')
const { apiPath, uiPath, devMode, selfUrl, title } = config
const endpoint = selfUrl + apiPath
Expand All @@ -48,6 +50,8 @@ export class WebServer {
registry: new Registry(ctx, config),
stats: new Statistics(ctx, config),
}

ctx.on('connect', () => this.start())
}

async start() {
Expand All @@ -71,6 +75,8 @@ export class WebServer {
}
const stats = await fs.stat(filename).catch<Stats>(noop)
if (stats?.isFile()) return sendFile(filename)
const ext = extname(filename)
if (ext && ext !== '.html') return ctx.status = 404
let template = await fs.readFile(resolve(this.root, 'index.html'), 'utf8')
if (vite) template = await vite.transformIndexHtml(uiPath, template)
ctx.type = 'html'
Expand Down

0 comments on commit 84dc676

Please sign in to comment.