feat: add RPCPlugin interface and abstract class with hook context definitions

This commit is contained in:
2025-11-27 21:25:27 +08:00
parent 99c673a8dc
commit 24a14a8e1c

76
src/core/RPCPlugin.ts Normal file
View File

@@ -0,0 +1,76 @@
import { RPCSession } from "./RPCSession";
// interface BaseHookRuntimeCtx {
// nexts: RPCPlugin[];
// setNextPlugins: (plugins: RPCPlugin[]) => void
// }
export interface BaseHookCtx {
}
export interface CallOutgoingBeforeCtx extends BaseHookCtx {
session: RPCSession;
options: {
fnPath: string;
args: any[];
};
}
export interface CallOutgoingCtx extends CallOutgoingBeforeCtx {
result: any;
setResult: (data: any) => void;
}
export interface CallIncomingBeforeCtx extends BaseHookCtx {
}
export interface CallIncomingCtx extends CallIncomingBeforeCtx {
}
export type NormalMethodReturn = Promise<void> | void;
export type HookFn<Ctx> = (ctx: Ctx) => NormalMethodReturn;
export interface RPCPluginHooksCtx {
onCallOutgoingBefore: CallOutgoingBeforeCtx;
onCallOutgoing: CallOutgoingCtx;
onCallIncomingBefore: CallIncomingBeforeCtx;
onCallIncoming: CallIncomingCtx;
}
export type RPCPluginHooks = {
[K in keyof RPCPluginHooksCtx]?: HookFn<RPCPluginHooksCtx[K]>;
};
export interface RPCPlugin extends RPCPluginHooks {
onInit?(): void;
onDestroy?(): void;
}
export abstract class AbstractRPCPlugin implements RPCPlugin {
abstract onInit?(): void;
abstract onDestroy?(): void;
abstract onCallOutgoingBefore?(ctx: CallOutgoingBeforeCtx): NormalMethodReturn;
abstract onCallOutgoing?(ctx: CallOutgoingCtx): NormalMethodReturn;
abstract onCallIncomingBefore?(ctx: CallIncomingBeforeCtx): NormalMethodReturn;
abstract onCallIncoming?(ctx: CallIncomingCtx): NormalMethodReturn;
}
type HookName = keyof RPCPluginHooksCtx;
export class HookChainInterruptedError extends Error { };
type HookRunner<Ctx> = (ctx: Ctx) => Promise<void>;
export function createHookRunner<K extends HookName>(
plugins: RPCPlugin[],
hookName: K,
): HookRunner<RPCPluginHooksCtx[K]> {
return async (ctx: RPCPluginHooksCtx[K]) => {
for (const plugin of plugins) {
await (plugin[hookName] as HookFn<RPCPluginHooksCtx[K]> | undefined)?.(ctx);
}
};
}