Skip to content

Commit

Permalink
fix(core): re-add missing context apis
Browse files Browse the repository at this point in the history
  • Loading branch information
shigma committed Jun 21, 2022
1 parent bd3114e commit 733a0f9
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 58 deletions.
2 changes: 1 addition & 1 deletion packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
},
"dependencies": {
"@koishijs/utils": "^5.4.5",
"cordis": "^1.5.5",
"cordis": "^1.6.0",
"fastest-levenshtein": "^1.0.12",
"minato": "^1.2.1"
}
Expand Down
9 changes: 5 additions & 4 deletions packages/core/src/command/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ interface CommandMap extends Map<string, Command> {
}

declare module 'cordis' {
interface Context extends Commander.Delegates {
interface Context extends Commander.Mixin {
$commander: Commander
}

Expand All @@ -35,7 +35,7 @@ declare module 'cordis' {
export namespace Commander {
export interface Config {}

export interface Delegates {
export interface Mixin {
command<D extends string>(def: D, config?: Command.Config): Command<never, never, Argv.ArgumentType<D>>
command<D extends string>(def: D, desc: string, config?: Command.Config): Command<never, never, Argv.ArgumentType<D>>
}
Expand All @@ -49,12 +49,13 @@ export class Commander {
_shortcuts: Command.Shortcut[] = []

constructor(private ctx: Context, private config: Commander.Config = {}) {
this[Context.current] = ctx
ctx.plugin(runtime)
ctx.plugin(validate)
}

protected get caller(): Context {
return this[Context.current] || this.ctx
protected get caller() {
return this[Context.current]
}

resolve(key: string) {
Expand Down
46 changes: 34 additions & 12 deletions packages/core/src/database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ declare module 'cordis' {
'model'(name: keyof Tables): void
}

interface Context {
interface Context extends DatabaseService.Mixin {
database: DatabaseService
model: DatabaseService
}
Expand Down Expand Up @@ -59,14 +59,17 @@ export interface Tables {
}

export namespace DatabaseService {
export interface Delegates {
export interface Mixin {
getSelfIds(type?: string, assignees?: string[]): Dict<string[]>
broadcast(content: string, forced?: boolean): Promise<string[]>
broadcast(channels: readonly string[], content: string, forced?: boolean): Promise<string[]>
}
}

export class DatabaseService extends Database<Tables> {
constructor(protected ctx: Context) {
constructor(protected app: Context) {
super()
this[Context.current] = app

this.extend('user', {
// TODO v5: change to number
Expand All @@ -91,10 +94,6 @@ export class DatabaseService extends Database<Tables> {
})
}

get caller(): Context {
return this[Context.current] || this.ctx
}

getUser<T extends string, K extends User.Field>(platform: T, id: string, modifier?: Driver.Cursor<K>): Promise<Result<User, K> & Record<T, string>>
getUser<T extends string, K extends User.Field>(platform: T, ids: string[], modifier?: Driver.Cursor<K>): Promise<Result<User, K>[]>
async getUser(platform: string, id: MaybeArray<string>, modifier?: Driver.Cursor<User.Field>) {
Expand Down Expand Up @@ -123,11 +122,11 @@ export class DatabaseService extends Database<Tables> {

getSelfIds(type?: string, assignees?: string[]): Dict<string[]> {
if (type) {
assignees ||= this.ctx.bots.filter(bot => bot.platform === type).map(bot => bot.selfId)
assignees ||= this.app.bots.filter(bot => bot.platform === type).map(bot => bot.selfId)
return { [type]: assignees }
}
const platforms: Dict<string[]> = {}
for (const bot of this.ctx.bots) {
for (const bot of this.app.bots) {
(platforms[bot.platform] ||= []).push(bot.selfId)
}
return platforms
Expand All @@ -147,20 +146,43 @@ export class DatabaseService extends Database<Tables> {
createChannel(platform: string, id: string, data: Partial<Channel>) {
return this.create('channel', { platform, id, ...data })
}

async broadcast(...args: [string, boolean?] | [readonly string[], string, boolean?]) {
let channels: string[]
if (Array.isArray(args[0])) channels = args.shift() as any
const [content, forced] = args as [string, boolean]
if (!content) return []

const data = await this.getAssignedChannels(['id', 'assignee', 'flag', 'platform', 'guildId'])
const assignMap: Dict<Dict<[string, string][]>> = {}
for (const { id, assignee, flag, platform, guildId } of data) {
if (channels && !channels.includes(`${platform}:${id}`)) continue
if (!forced && (flag & Channel.Flag.silent)) continue
((assignMap[platform] ||= {})[assignee] ||= []).push([id, guildId])
}

return (await Promise.all(Object.entries(assignMap).flatMap(([platform, map]) => {
return this.app.bots.map((bot) => {
if (bot.platform !== platform) return Promise.resolve([])
return bot.broadcast(map[bot.selfId] || [], content)
})
}))).flat(1)
}
}

// workaround typings
DatabaseService.prototype.extend = function extend(this: DatabaseService, name, fields, config) {
Database.prototype.extend.call(this, name, fields, {
...config,
driver: this.caller.mapping.database,
driver: this[Context.current].mapping.database,
})
this.ctx.emit('model', name)
this.app.emit('model', name)
}

Context.service('database')
Context.service('model', {
constructor: DatabaseService,
methods: ['getSelfIds', 'broadcast'],
})

export const defineDriver = <T>(constructor: Driver.Constructor<T>, schema?: utils.Schema<T>, prepare?: Plugin.Function<T>): Plugin.Object<T> => ({
Expand All @@ -170,7 +192,7 @@ export const defineDriver = <T>(constructor: Driver.Constructor<T>, schema?: uti
apply(ctx, config) {
prepare?.(ctx, config)
const driver = new constructor(ctx.model, config)
const key = ctx.state.uid
const key = ctx.mapping.database || 'default'

ctx.on('ready', async () => {
await driver.start()
Expand Down
9 changes: 5 additions & 4 deletions packages/core/src/protocol/adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,12 +142,13 @@ export namespace Adapter {
export class BotList extends Array<Bot> {
adapters: Dict<Adapter> = {}

get caller(): Context {
return this[Context.current] || this.ctx
constructor(private app: Context) {
super()
this[Context.current] = app
}

constructor(private ctx: Context) {
super()
protected get caller() {
return this[Context.current]
}

get(sid: string) {
Expand Down
9 changes: 5 additions & 4 deletions packages/core/src/protocol/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export * from './bot'
export * from './session'

declare module 'cordis' {
interface Context extends Internal.Delegates {
interface Context extends Internal.Mixin {
$internal: Internal
}

Expand Down Expand Up @@ -49,7 +49,7 @@ export namespace Internal {
prefix?: Computed<string | string[]>
}

export interface Delegates {
export interface Mixin {
middleware(middleware: Middleware, prepend?: boolean): () => boolean
}
}
Expand All @@ -62,6 +62,7 @@ export class Internal {
_channelCache = new SharedCache<Channel.Observed<any>>()

constructor(private ctx: Context, private config: Internal.Config) {
this[Context.current] = ctx
this.prepare()

// bind built-in event listeners
Expand All @@ -83,8 +84,8 @@ export class Internal {
})
}

protected get caller(): Context {
return this[Context.current] || this.ctx
protected get caller() {
return this[Context.current]
}

middleware(middleware: Middleware, prepend = false) {
Expand Down
41 changes: 9 additions & 32 deletions packages/core/src/selector.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import { Dict, Logger, Promisify, remove } from '@koishijs/utils'
import { Logger, Promisify, remove } from '@koishijs/utils'
import { Context, Events } from 'cordis'
import { Channel } from './database'
import { Session } from './protocol/session'

declare module 'cordis' {
interface Context extends SelectorService.Delegates {
$selector: SelectorService
interface Context extends SelectorService.Mixin {
selector: SelectorService
}

namespace Context {
Expand All @@ -18,7 +17,7 @@ declare module 'cordis' {
export type Filter = (session: Session) => boolean

export namespace SelectorService {
export interface Delegates {
export interface Mixin {
logger(name: string): Logger
any(): Context
never(): Context
Expand All @@ -38,8 +37,6 @@ export namespace SelectorService {
before<K extends BeforeEventName>(name: K, listener: BeforeEventMap[K], append?: boolean): () => boolean
setTimeout(callback: (...args: any[]) => void, ms: number, ...args: any[]): () => boolean
setInterval(callback: (...args: any[]) => void, ms: number, ...args: any[]): () => boolean
broadcast(content: string, forced?: boolean): Promise<string[]>
broadcast(channels: readonly string[], content: string, forced?: boolean): Promise<string[]>
}
}

Expand All @@ -56,6 +53,8 @@ function property<K extends keyof Session>(ctx: Context, key: K, ...values: Sess

export class SelectorService {
constructor(private app: Context) {
this[Context.current] = app

app.filter = () => true

app.on('internal/warning', (format, ...args) => {
Expand All @@ -70,8 +69,8 @@ export class SelectorService {
})
}

protected get caller(): Context {
return this[Context.current] || this.app
protected get caller() {
return this[Context.current]
}

any() {
Expand Down Expand Up @@ -175,31 +174,9 @@ export class SelectorService {
setInterval(callback: (...args: any[]) => void, ms: number, ...args: any[]) {
return this.createTimerDispose(setInterval(callback, ms, ...args))
}

async broadcast(...args: [string, boolean?] | [readonly string[], string, boolean?]) {
let channels: string[]
if (Array.isArray(args[0])) channels = args.shift() as any
const [content, forced] = args as [string, boolean]
if (!content) return []

const data = await this.caller.database.getAssignedChannels(['id', 'assignee', 'flag', 'platform', 'guildId'])
const assignMap: Dict<Dict<[string, string][]>> = {}
for (const { id, assignee, flag, platform, guildId } of data) {
if (channels && !channels.includes(`${platform}:${id}`)) continue
if (!forced && (flag & Channel.Flag.silent)) continue
((assignMap[platform] ||= {})[assignee] ||= []).push([id, guildId])
}

return (await Promise.all(Object.entries(assignMap).flatMap(([platform, map]) => {
return this.caller.bots.map((bot) => {
if (bot.platform !== platform) return Promise.resolve([])
return bot.broadcast(map[bot.selfId] || [], content)
})
}))).flat(1)
}
}

Context.service('$selector', {
Context.service('selector', {
constructor: SelectorService,
methods: [
'any', 'never', 'union', 'intersect', 'exclude', 'select',
Expand Down
2 changes: 1 addition & 1 deletion packages/koishi/src/patch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ declare module '@koishijs/core' {
}

namespace Registry {
interface Delegates {
interface Mixin {
plugin(path: string, config?: any): Fork
}
}
Expand Down

0 comments on commit 733a0f9

Please sign in to comment.