Skip to content

Commit

Permalink
feat(console): support data source patch method
Browse files Browse the repository at this point in the history
  • Loading branch information
shigma committed Jan 21, 2022
1 parent c13d4be commit deb3d49
Show file tree
Hide file tree
Showing 13 changed files with 74 additions and 40 deletions.
2 changes: 1 addition & 1 deletion packages/cli/src/addons/watcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ export default class FileWatcher extends Service {
// attempt to load entry files
const attempts = {}
try {
for (const [_, filename] of reloads) {
for (const [, filename] of reloads) {
attempts[filename] = unwrap(require(filename))
}
} catch (err) {
Expand Down
2 changes: 1 addition & 1 deletion plugins/frontend/commands/src/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ function traverse(command: Command): CommandData {

export default class CommandProvider extends DataSource<CommandData[]> {
cached: CommandData[]
update = debounce(0, () => this.broadcast())
update = debounce(0, () => this.refresh())

constructor(ctx: Context) {
super(ctx, 'commands')
Expand Down
8 changes: 8 additions & 0 deletions plugins/frontend/console/client/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,14 @@ receive('data', ({ key, value }) => {
store[key] = value
})

receive('patch', ({ key, value }) => {
if (Array.isArray(store[key])) {
store[key].push(...value)
} else {
Object.assign(store[key], value)
}
})

receive('response', ({ id, value }) => {
const callback = responseHooks[id]
delete responseHooks[id]
Expand Down
15 changes: 10 additions & 5 deletions plugins/frontend/console/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,16 @@ export abstract class DataSource<T = any> {
})
}

async broadcast(value?: T) {
this.ctx.console.broadcast('data', {
key: this.name,
value: value || await this.get(true),
})
protected broadcast(type: string, value: any) {
this.ctx.console.broadcast(type, { key: this.name, value })
}

async refresh() {
this.broadcast('data', await this.get(true))
}

patch(value: T) {
this.broadcast('patch', value)
}
}

Expand Down
28 changes: 23 additions & 5 deletions plugins/frontend/insight/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { camelize, capitalize, Context, Dict, Plugin } from 'koishi'
import { debounce } from 'throttle-debounce'
import { DataSource } from '@koishijs/plugin-console'
import { resolve } from 'path'

declare module '@koishijs/plugin-console' {
interface Sources {
Expand All @@ -12,15 +13,13 @@ export default class RegistryProvider extends DataSource<Dict<PluginData>> {
static using = ['console'] as const

private cache: Dict<PluginData>
private timer = setInterval(() => this.update(), 1000)
private update = debounce(0, () => {
this.broadcast()
this.timer.refresh()
})

constructor(ctx: Context) {
super(ctx, 'registry')

const filename = ctx.console.config.devMode ? '../client/index.ts' : '../dist/index.js'
ctx.console.addEntry(resolve(__dirname, filename))

ctx.on('plugin-added', this.update)
ctx.on('plugin-removed', this.update)
ctx.on('service', this.update)
Expand All @@ -31,6 +30,25 @@ export default class RegistryProvider extends DataSource<Dict<PluginData>> {
clearInterval(this.timer)
}

private update = debounce(0, () => {
this.timer.refresh()
this.refresh()
})

private timer = setInterval(() => {
if (!this.cache) return
const patch: Dict<PluginData> = {}
for (const [, state] of this.ctx.app.registry) {
const data = this.cache[state.id]
if (!data) continue
if (state.disposables.length !== data.disposables) {
data.disposables = state.disposables.length
patch[state.id] = data
}
}
if (Object.keys(patch).length) this.patch(patch)
}, 1000)

async get(forced = false) {
if (this.cache && !forced) return this.cache
this.cache = {}
Expand Down
2 changes: 0 additions & 2 deletions plugins/frontend/logger/client/logs.vue
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@
import { store, receive } from '~/client'
import Converter from 'ansi_up'
receive('logs/data', data => store.logs.push(data))
const hint = `app\u001b[0m \u001b[38;5;15;1mKoishi/`
const converter = new Converter()
Expand Down
2 changes: 1 addition & 1 deletion plugins/frontend/logger/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ class LogProvider extends DataSource<string[]> {
this.createFile()
}
this.writer.write(text)
this.ctx.console.broadcast('logs/data', text)
this.patch([text])
}

async get() {
Expand Down
2 changes: 1 addition & 1 deletion plugins/frontend/manager/src/bots.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ class BotProvider extends DataSource<BotProvider.Data[]> {
})

ctx.on('bot-status-updated', () => {
this.broadcast()
this.refresh()
})
}

Expand Down
32 changes: 17 additions & 15 deletions plugins/frontend/manager/src/market.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,11 @@ function supports(command: string, args: string[] = []) {
}

class MarketProvider extends DataSource<Dict<MarketProvider.Data>> {
dataCache: Dict<MarketProvider.Data> = {}
http: Quester
_timestamp = 0
_agentCache: Promise<Manager>
private http: Quester
private timestamp = 0
private agentTask: Promise<Manager>
private fullCache: Dict<MarketProvider.Data> = {}
private tempCache: Dict<MarketProvider.Data> = {}

constructor(ctx: Context, private config: MarketProvider.Config) {
super(ctx, 'market')
Expand All @@ -52,9 +53,10 @@ class MarketProvider extends DataSource<Dict<MarketProvider.Data>> {

flushData() {
const now = Date.now()
if (now - this._timestamp < 100) return
this._timestamp = now
this.broadcast()
if (now - this.timestamp < 100) return
this.timestamp = now
this.patch(this.tempCache)
this.tempCache = {}
}

private async search(offset = 0) {
Expand All @@ -75,16 +77,16 @@ class MarketProvider extends DataSource<Dict<MarketProvider.Data>> {
const community = name.startsWith('koishi-plugin-')
if (!official && !community) return

const data = await this.http.get<Package.Registry>(`/${name}`)
const versions = Object.values(data.versions).filter((remote) => {
const registry = await this.http.get<Package.Registry>(`/${name}`)
const versions = Object.values(registry.versions).filter((remote) => {
const { dependencies, peerDependencies, deprecated } = remote
const declaredVersion = { ...dependencies, ...peerDependencies }['koishi']
return !deprecated && declaredVersion && satisfies(currentVersion, declaredVersion)
}).map(Package.Meta.from).reverse()
if (!versions.length) return

const shortname = official ? name.slice(17) : name.slice(14)
this.dataCache[name] = {
this.tempCache[name] = this.fullCache[name] = {
...item,
shortname,
official,
Expand All @@ -103,7 +105,7 @@ class MarketProvider extends DataSource<Dict<MarketProvider.Data>> {
}

async get() {
return this.dataCache
return this.fullCache
}

get cwd() {
Expand Down Expand Up @@ -146,15 +148,15 @@ class MarketProvider extends DataSource<Dict<MarketProvider.Data>> {
}

install = async (name: string) => {
const agent = await (this._agentCache ||= this.getAgent())
const agent = await (this.agentTask ||= this.getAgent())
await this.exec(agent, [agent === 'yarn' ? 'add' : 'install', name, '--loglevel', 'error'])
this.ctx.console.services.packages.broadcast()
this.ctx.console.services.packages.refresh()
}

uninstall = async (name: string) => {
const agent = await (this._agentCache ||= this.getAgent())
const agent = await (this.agentTask ||= this.getAgent())
await this.exec(agent, ['remove', name, '--loglevel', 'error'])
this.ctx.console.services.packages.broadcast()
this.ctx.console.services.packages.refresh()
}
}

Expand Down
4 changes: 2 additions & 2 deletions plugins/frontend/manager/src/packages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ class PackageProvider extends DataSource<Dict<PackageProvider.Data>> {
if (!this.cache[entry]) return
const local = await this.cache[entry]
local.id = id
this.broadcast()
this.refresh()
}

async prepare() {
Expand Down Expand Up @@ -121,7 +121,7 @@ class PackageProvider extends DataSource<Dict<PackageProvider.Data>> {
const oldLength = Object.keys(Adapter.library).length
const exports = getExports(name)
const newLength = Object.keys(Adapter.library).length
if (newLength > oldLength) this.ctx.console.services.protocols.broadcast()
if (newLength > oldLength) this.ctx.console.services.protocols.refresh()

// check plugin dependencies
Object.assign(result, Package.Meta.from(data))
Expand Down
2 changes: 1 addition & 1 deletion plugins/frontend/manager/src/protocols.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export default class AdapterProvider extends DataSource<Dict<Schema>> {
super(ctx, 'protocols')

ctx.on('adapter', () => {
this.broadcast()
this.refresh()
})
}

Expand Down
13 changes: 8 additions & 5 deletions plugins/frontend/manager/src/services.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,21 @@ import { DataSource } from '@koishijs/plugin-console'
import { Context, Dict } from 'koishi'

export default class ServiceProvider extends DataSource<Dict<string>> {
private cache: Dict<string>

constructor(ctx: Context) {
super(ctx, 'services')

ctx.on('service', () => this.broadcast())
ctx.on('service', () => this.refresh())
}

async get() {
const result: Dict<string> = {}
async get(forced = false) {
if (!forced) return this.cache
this.cache = {}
for (const name of Context.Services) {
const value = this.ctx[name]?.['ctx']?.state.id
if (value) result[name] = value
if (value) this.cache[name] = value
}
return result
return this.cache
}
}
2 changes: 1 addition & 1 deletion plugins/frontend/status/src/profile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ export class ProfileProvider extends DataSource<ProfileProvider.Payload> {
ctx.on('ready', () => {
ctx.setInterval(() => {
updateCpuUsage()
this.broadcast()
this.refresh()
}, tickInterval)
})
}
Expand Down

0 comments on commit deb3d49

Please sign in to comment.