Skip to content

Commit

Permalink
feat(core): support accessor command.parent for better disposables
Browse files Browse the repository at this point in the history
  • Loading branch information
shigma committed Sep 7, 2023
1 parent f6dd0d2 commit 3d674a0
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 19 deletions.
21 changes: 17 additions & 4 deletions packages/core/src/command/command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ export namespace Command {
export class Command<U extends User.Field = never, G extends Channel.Field = never, A extends any[] = any[], O extends {} = {}> extends Argv.CommandBase {
config: Command.Config
children: Command[] = []
parent: Command = null

_parent: Command = null
_aliases: string[] = []
_examples: string[] = []
_usage?: Command.Usage
Expand Down Expand Up @@ -90,6 +90,21 @@ export class Command<U extends User.Field = never, G extends Channel.Field = nev
this._registerAlias(name, true)
}

get parent() {
return this._parent
}

set parent(parent: Command) {
if (this._parent === parent) return
if (this._parent) {
remove(this._parent.children, this)
}
this._parent = parent
if (!parent?.children.includes(this)) {
parent?.children.push(this)
}
}

private _registerAlias(name: string, prepend = false) {
name = name.toLowerCase()
if (name.startsWith('.')) name = this.parent.name + name
Expand Down Expand Up @@ -320,9 +335,7 @@ export class Command<U extends User.Field = never, G extends Channel.Field = nev
this.ctx.$commander.delete(name)
}
remove(this.ctx.$commander._commandList, this)
if (this.parent) {
remove(this.parent.children, this)
}
this.parent = null
}

toJSON(): Universal.Command {
Expand Down
25 changes: 14 additions & 11 deletions packages/core/src/command/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -179,8 +179,11 @@ export class Commander extends Map<string, Command> {
const segments = path.split(/(?=[./])/g)
const caller = this.caller

let parent: Command, root: Command
const extra: Command[] = []
/** parent command in the chain */
let parent: Command
/** the first created command */
let root: Command
const created: Command[] = []
segments.forEach((segment, index) => {
const code = segment.charCodeAt(0)
const name = code === 46 ? parent.name + segment : code === 47 ? segment.slice(1) : segment
Expand All @@ -196,28 +199,28 @@ export class Commander extends Map<string, Command> {
}
} else {
command.parent = parent
parent.children.push(command)
}
}
return parent = command
}
command = new Command(name, index === segments.length - 1 ? decl : '', caller)
caller.i18n.define('', `commands.${command.name}.$`, '')
caller.i18n.define('', `commands.${command.name}.description`, index === segments.length - 1 ? desc : '')
extra.push(command)
if (!root) root = command
command._disposables.push(caller.i18n.define('', {
[`commands.${command.name}.$`]: '',
[`commands.${command.name}.description`]: index === segments.length - 1 ? desc : '',
}))
created.push(command)
root ||= command
if (parent) {
command.parent = parent
parent.children.push(command)
}
parent = command
})

Object.assign(parent.config, config)
extra.forEach(command => caller.emit('command-added', command))
created.forEach(command => caller.emit('command-added', command))
parent[Context.current] = caller
this.caller.permissions.config(`command.${parent.name}`, parent.config, 1)
if (root) caller.state.disposables.unshift(() => root.dispose())
parent._disposables.push(this.caller.permissions.config(`command.${parent.name}`, parent.config, 1))
if (root) caller.collect(`command <${root.name}>`, () => root.dispose())
return parent
}
}
Expand Down
6 changes: 3 additions & 3 deletions packages/core/src/i18n.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,15 +103,15 @@ export class I18n {
}
}

define(locale: string, dict: I18n.Store): void
define(locale: string, key: string, value: I18n.Node): void
define(locale: string, dict: I18n.Store): () => void
define(locale: string, key: string, value: I18n.Node): () => void
define(locale: string, ...args: [I18n.Store] | [string, I18n.Node]) {
const dict = this._data[locale] ||= {}
const paths = [...typeof args[0] === 'string'
? this.set(locale, args[0] + '.', args[1])
: this.set(locale, '', args[0])]
this.ctx.emit('internal/i18n')
this[Context.current]?.on('dispose', () => {
return this[Context.current]?.collect('i18n', () => {
for (const path of paths) {
delete dict[path]
}
Expand Down
2 changes: 1 addition & 1 deletion packages/koishi/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
"@koishijs/core": "4.14.4",
"@koishijs/loader": "4.1.4",
"@koishijs/utils": "^7.0.5",
"@satorijs/satori": "^2.7.1",
"@satorijs/satori": "^2.7.3",
"cac": "^6.7.14",
"kleur": "^4.1.5",
"ns-require": "^1.1.4"
Expand Down

0 comments on commit 3d674a0

Please sign in to comment.