refactor: improve type safety and documentation in PluginManager and PluginEngine

This commit is contained in:
suyao 2025-12-29 19:22:12 +08:00
parent 3c23c32232
commit 9ee15ceec9
No known key found for this signature in database
2 changed files with 18 additions and 9 deletions

View File

@ -1,8 +1,7 @@
import type { AiPlugin, AiRequestContext } from './types'
/**
*
*
*
*/
export class PluginManager<TParams = unknown, TResult = unknown> {
private plugins: AiPlugin<TParams, TResult>[] = []
@ -12,7 +11,7 @@ export class PluginManager<TParams = unknown, TResult = unknown> {
}
/**
* AiPlugin<unknown> AiPlugin<TParams>
*
*/
use(plugin: AiPlugin<TParams, TResult>): this {
this.plugins = this.sortPlugins([...this.plugins, plugin])
@ -131,12 +130,12 @@ export class PluginManager<TParams = unknown, TResult = unknown> {
const hook = plugin[hookName]
if (!hook) return null
if (hookName === 'onError' && error) {
return (hook as any)(error, context)
if (hookName === 'onError' && error !== undefined) {
return (hook as NonNullable<typeof plugin.onError>)(error, context)
} else if (hookName === 'onRequestEnd' && result !== undefined) {
return (hook as any)(context, result)
return (hook as NonNullable<typeof plugin.onRequestEnd>)(context, result)
} else if (hookName === 'onRequestStart') {
return (hook as any)(context)
return (hook as NonNullable<typeof plugin.onRequestStart>)(context)
}
return null
})

View File

@ -20,8 +20,18 @@ import { type ProviderId } from '../providers/types'
* API
*/
export class PluginEngine<T extends ProviderId = ProviderId> {
// ✅ 存储为非泛型数组(允许混合不同类型的插件)
private basePlugins: AiPlugin[] = []
/**
* Plugin storage with explicit any/any generics
*
* SAFETY: Plugins are contravariant in TParams and covariant in TResult.
* The cast to AiPlugin<TParams, TResult>[] in PluginManager is safe due to variance rules:
* - A plugin accepting any params (TParams = any) can handle specific params
* - A plugin returning any result (TResult = any) can be used as any specific result type
*
* Using AiPlugin<any, any> instead of AiPlugin preserves generic type information
* and makes the variance relationship explicit for type checking.
*/
private basePlugins: AiPlugin<any, any>[] = []
constructor(
private readonly providerId: T,