diff --git a/apps/desktop/main/ipc/chat.ts b/apps/desktop/main/ipc/chat.ts index 544ff0a9..566a4cd3 100644 --- a/apps/desktop/main/ipc/chat.ts +++ b/apps/desktop/main/ipc/chat.ts @@ -234,6 +234,14 @@ export function registerChatHandlers(ctx: IpcContext): void { } }) + /** + * 仅保留图表插件计算的 worker 卸载路径。 + * 其他数据查询已迁移到 HTTP,但这些计算会处理大数组,放在 renderer 会冻结 UI。 + */ + ipcMain.handle('chat:pluginCompute', async (_, fnString: string, input: unknown) => { + return worker.pluginCompute(fnString, input) + }) + // Session index and summary IPC handlers have been removed. // All session-index operations now go through shared HTTP routes // (FetchSessionIndexAdapter via /_web/sessions/* endpoints). diff --git a/apps/desktop/preload/apis/chat.ts b/apps/desktop/preload/apis/chat.ts index bc051f4c..5f0d448b 100644 --- a/apps/desktop/preload/apis/chat.ts +++ b/apps/desktop/preload/apis/chat.ts @@ -78,6 +78,13 @@ export const chatApi = { ): Promise<{ success: boolean; newMessageCount: number; error?: string }> => ipcRenderer.invoke('chat:incrementalImport', sessionId, filePath), + /** + * 图表插件计算会处理大量消息数组,Electron 下必须卸载到 worker, + * 避免 renderer 主线程同步执行造成窗口卡顿。 + */ + pluginCompute: (fnString: string, input: unknown): Promise => + ipcRenderer.invoke('chat:pluginCompute', fnString, input), + // ==================== Demo ==================== importDemo: ( diff --git a/apps/desktop/preload/index.d.ts b/apps/desktop/preload/index.d.ts index b15d7caf..f9bf551f 100644 --- a/apps/desktop/preload/index.d.ts +++ b/apps/desktop/preload/index.d.ts @@ -73,6 +73,7 @@ interface ChatApi { sessionId: string, filePath: string ) => Promise<{ success: boolean; newMessageCount: number; error?: string }> + pluginCompute: (fnString: string, input: unknown) => Promise importDemo: (locale: string) => Promise<{ success: boolean groupSessionId?: string diff --git a/src/services/data/electron.ts b/src/services/data/electron.ts new file mode 100644 index 00000000..b83d7775 --- /dev/null +++ b/src/services/data/electron.ts @@ -0,0 +1,14 @@ +/** + * ElectronDataAdapter — Electron 专用 DataAdapter + * + * 普通数据查询继续复用共享 HTTP 路由;计算密集型 pluginCompute + * 通过 Electron worker 执行,避免在 renderer 主线程同步阻塞图表交互。 + */ + +import { FetchDataAdapter } from './fetch' + +export class ElectronDataAdapter extends FetchDataAdapter { + async pluginCompute(fnString: string, input: unknown): Promise { + return window.chatApi.pluginCompute(fnString, input) + } +} diff --git a/src/services/registry.ts b/src/services/registry.ts index b2757178..cbe0ff30 100644 --- a/src/services/registry.ts +++ b/src/services/registry.ts @@ -65,8 +65,8 @@ export async function initServices(): Promise { * data/message/preferences/ai-streaming use Fetch/SSE; import stays on IPC. */ async function initElectronAdapters(): Promise { - const { FetchDataAdapter } = await import('./data/fetch') - registerAdapter('data', new FetchDataAdapter()) + const { ElectronDataAdapter } = await import('./data/electron') + registerAdapter('data', new ElectronDataAdapter()) const { ElectronImportAdapter } = await import('./import/electron') registerAdapter('import', new ElectronImportAdapter())