Skip to content

Commit

Permalink
feat: 完整类型声明,setup全支持
Browse files Browse the repository at this point in the history
  • Loading branch information
class-liu-fullstack committed Feb 11, 2025
1 parent d29ac3f commit 600f577
Show file tree
Hide file tree
Showing 42 changed files with 636 additions and 780 deletions.
41 changes: 20 additions & 21 deletions core/src/adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,25 @@ export class Adapter<P extends keyof App.Adapters> extends EventEmitter {
bots: Adapter.Bot<P>[] = [];
elements: Element[] = [];
private [adapterKey] = true;
#is_started: boolean = false;
app: App | null = null;
#configs: Adapter.BotConfig<P>[] = [];
static isAdapter(obj: any): obj is Adapter {
return typeof obj === 'object' && !!obj[adapterKey];
}

start(app: App, config: Adapter.BotConfig<P>[]) {
this.app = app;
this.emit('start', config);
this.#configs = config;
this.#is_started = true;
}
onReady(callback: (config: Adapter.BotConfig<P>[]) => void) {
if (this.#is_started) {
callback(this.#configs);
} else {
this.once('start', callback);
}
}
schemas: Schema = Schema.object({
unique_id: Schema.string('请输入机器人唯一标识'),
master: Schema.string('请输入主人id'),
Expand Down Expand Up @@ -70,17 +84,6 @@ export class Adapter<P extends keyof App.Adapters> extends EventEmitter {
this.elements.push(element);
return this;
}
mount(app: App) {
this.emit('before-mount');
this.logger.level = app.config.log_level;
this.app = app;
this.emit('mounted', app);
}
unmount() {
this.emit('before-unmount', this.app!);
this.app = null;
this.emit('unmounted');
}
}

export interface Adapter<P extends keyof App.Adapters = keyof App.Adapters> {
Expand Down Expand Up @@ -140,23 +143,21 @@ export interface Adapter<P extends keyof App.Adapters = keyof App.Adapters> {
export namespace Adapter {
export interface EventMap<P extends keyof App.Adapters> {
'bot-ready'(bot: Bot<P>): void;
'before-mount'(): void;
'before-unmount'(app: App): void;
'mounted'(app: App): void;
'unmounted'(): void;
'start'(configs: BotConfig<P>[]): void;
'stop'(): void;
}
export abstract class Bot<P extends Adapters = Adapters> {
export type Bot<P extends Adapters = Adapters> = BaseBot<P> & App.Clients[P];
export abstract class BaseBot<P extends Adapters = Adapters> {
protected constructor(
public adapter: Adapter<P>,
public unique_id: string,
public internal: App.Bots[P],
public client: App.Clients[P],
) {
const _this = this;
return new Proxy(_this, {
get(target, prop, receiver) {
if (prop in target) return Reflect.get(target, prop, receiver);
return Reflect.get(_this.internal, prop, receiver);
return Reflect.get(_this.client, prop, receiver);
},
});
}
Expand Down Expand Up @@ -203,6 +204,4 @@ export namespace Adapter {
forward_length?: number;
quote_self?: boolean;
} & App.Adapters[T];
export type InferAdapterPlatform<T extends Adapter> = T extends Adapter<infer P> ? P : never;
export type InternalBot<P extends keyof App.Adapters> = App.Bots[P];
}
59 changes: 5 additions & 54 deletions core/src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { Plugin, PluginMap } from './plugin';
import { LogLevel } from './types';
import { loadModule } from './utils';
import { remove, sleep } from '@zhinjs/shared';
import { APP_KEY, CONFIG_DIR, REQUIRED_KEY, WORK_DIR } from './constans';
import { APP_KEY, CONFIG_DIR, serviceCallbacksKey, WORK_DIR } from './constans';
import path from 'path';
import { Adapter } from './adapter';
import { Message } from './message';
Expand Down Expand Up @@ -56,7 +56,6 @@ export class App extends EventEmitter {
if (!adapter) throw new Error(`cannot find adapter ${name}`);
return adapter.schemas;
}

async renderMessage<T extends Message = Message>(template: string, message?: T) {
for (const render of this.renders) {
try {
Expand Down Expand Up @@ -145,16 +144,8 @@ export class App extends EventEmitter {
}

plugin(plugin: Plugin): this {
this.emit('plugin-beforeMount', plugin);
plugin[APP_KEY] = this;
plugin.mounted(() => {
for (const [name, service] of (plugin as Plugin).services) {
this.logger.debug(`new service(${name.toString()}) register from from(${plugin.display_name})`);
this.emit('service-register', name, service);
}
this.logger.info(`plugin:${plugin.display_name} loaded。`);
plugin.isMounted = true;
});
this.logger.info(`plugin:${plugin.display_name} loaded。`);
this.emit('plugin-mounted', plugin);
return this;
}
Expand Down Expand Up @@ -186,15 +177,6 @@ export class App extends EventEmitter {
}

emit(event: string, ...args: any[]) {
if (['plugin-beforeMount', 'plugin-mounted', 'plugin-beforeUnmount', 'plugin-unmounted'].includes(event)) {
const plugin: Plugin = args[0];
const method = event.split('-')[1];
if (plugin && plugin?.['lifecycle']?.[method]?.length) {
for (const lifecycle of plugin['lifecycle'][method]) {
lifecycle(this);
}
}
}
const result = super.emit(event, ...args);
for (const plugin of this.pluginList) {
plugin.emit(event, ...args);
Expand Down Expand Up @@ -239,33 +221,7 @@ export class App extends EventEmitter {
}
this.plugins.set(plugin.id, plugin);
if (this.config.disable_plugins.indexOf(plugin.id) >= 0) return this.disable(plugin);
if (plugin[REQUIRED_KEY].length) {
const requiredServices = plugin[REQUIRED_KEY];
const mountFn = () => {
if (requiredServices.every(key => !!this[key])) {
this.plugin(plugin);
this.off('service-register', mountFn);
}
};
const serviceDestroyListener = (name: string) => {
if (
requiredServices.some(s => {
return name === s;
})
)
this.emit('plugin-beforeUnmount', plugin);
};
this.on('service-register', mountFn);
this.on('service-destroy', serviceDestroyListener);
plugin.beforeUnmount(() => {
this.off('service-register', mountFn);
this.off('service-destroy', serviceDestroyListener);
(plugin as Plugin).isMounted = false;
});
mountFn();
} else {
this.plugin(plugin);
}
this.plugin(plugin);
return this;
}

Expand Down Expand Up @@ -299,8 +255,7 @@ export class App extends EventEmitter {
const bots = this.config.bots.filter(
bot => bot?.adapter === adapter.name && !this.config.disable_bots.includes(bot.unique_id),
);
adapter.app = this;
adapter.emit('start', bots);
adapter.start(this, bots);
this.logger.mark(`adapter: ${name} started`);
}
this.emit('start');
Expand Down Expand Up @@ -404,14 +359,10 @@ export namespace App {
export interface EventMap {
'start'(): void;

'plugin-beforeMount'(plugin: Plugin): void;

'plugin-mounted'(plugin: Plugin): void;

'plugin-beforeUnmount'(plugin: Plugin): void;

'plugin-unmounted'(plugin: Plugin): void;

'ready'(): void;

'message': <P extends keyof Adapters>(adapter: Adapter<P>, bot: Adapter.Bot<P>, message: Message<P>) => void;
Expand Down Expand Up @@ -443,7 +394,7 @@ export namespace App {
title: string;
};
}
export interface Bots {
export interface Clients {
process: NodeJS.Process;
}
export interface Services {}
Expand Down
5 changes: 2 additions & 3 deletions core/src/command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -413,17 +413,16 @@ export class Command<A extends any[] = [], O = {}> {

type MayBePromise<T> = T | Promise<T>;

// @ts-ignore
export function defineCommand<S extends string>(decl: S, initialValue?: ArgsType<S>): Command<ArgsType<S>>;
export function defineCommand<S extends string>(decl: S, config?: Command.Config): Command<ArgsType<S>>;
export function defineCommand<S extends string>(
decl: S,
initialValue?: ArgsType<S>,
initialValue: ArgsType<S>,
config?: Command.Config,
): Command<ArgsType<S>>;
export function defineCommand<S extends string>(
decl: S,
...args: [ArgsType<S> | Command.Config, Command.Config?]
...args: ([(ArgsType<S> | Command.Config)?]|[ArgsType<S>, Command.Config?])
): Command<ArgsType<S>> {
const initialValue: ArgsType<S> | undefined = Array.isArray(args[0]) ? undefined : (args.shift() as ArgsType<S>);
const command = new Command<ArgsType<S>>(...(args as [Command.Config]));
Expand Down
2 changes: 2 additions & 0 deletions core/src/constans.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,5 @@ export const HOME_DIR = os.homedir();
export const TEMP_DIR = os.tmpdir();
export const WORK_DIR = process.env.PWD || process.cwd();
export const CONFIG_DIR = path.join(WORK_DIR, 'config');
export const pluginKey = `__ZHIN_PLUGIN__`;
export const serviceCallbacksKey = `__ZHIN_SERVICE_CALLBACKS__`;
Loading

0 comments on commit 600f577

Please sign in to comment.