mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2026-01-28 06:32:08 +08:00
refactor: improve type safety and documentation in PluginManager and PluginEngine
This commit is contained in:
parent
3c23c32232
commit
9ee15ceec9
@ -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
|
||||
})
|
||||
|
||||
@ -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,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user