// 工具类代理管理器 import LCCScript from '@/core/script/LCCScript.ts' export default class ToolProxyManager { // 存储所有活跃的 MessageChannel 端口 private activePorts = new WeakMap() /** * 为 Worker 创建工具代理 */ createToolProxyForWorker(worker: Worker): MessagePort { // 创建 MessageChannel 用于通信 const channel = new MessageChannel() // 存储 port2 用于后续通信 this.activePorts.set(worker, channel.port2) // 设置 port2 的消息监听器 channel.port2.onmessage = (event) => { this.handleWorkerCall(worker, event) } channel.port2.start() // 返回 port1 供 Worker 使用 return channel.port1 } /** * 处理来自 Worker 的调用请求 */ handleWorkerCall(worker: Worker, event: MessageEvent): void { const { data } = event if (data?.type !== 'call') return const { tool, method, callId, args } = data const port = this.activePorts.get(worker) if (!port) { console.error(`[ToolProxy] 找不到 worker 的端口`, worker) return } // 获取主线程中的工具实例 const toolInstance = (window as any)[tool] if (!toolInstance) { console.error(`[ToolProxy] 工具未找到: ${tool}`) port.postMessage({ type: 'error', tool, method, callId, error: { name: 'ToolNotFound', message: `${tool} is not available` } }) return } if (typeof toolInstance[method] !== 'function') { console.error(`[ToolProxy] 方法未找到: ${tool}.${method}`) port.postMessage({ type: 'error', tool, method, callId, error: { name: 'MethodNotFound', message: `${tool}.${method} is not a function` } }) return } try { // 执行工具方法 let result if (toolInstance instanceof LCCScript && method === 'log') { // 特殊处理 LCCScript 的 log 方法 result = toolInstance[method]('Script-' + worker['name'], ...args) } else { result = toolInstance[method](...args) } // 处理异步函数 if (result instanceof Promise) { result.then( resolved => { port.postMessage({ type: 'result', tool, method, callId, result: resolved }) }, error => { port.postMessage({ type: 'error', tool, method, callId, error: { name: error.name || 'PromiseRejection', message: error.message, stack: error.stack } }) } ) } // 处理同步函数 else { port.postMessage({ type: 'result', tool, method, callId, result }) } } catch (error) { console.error(`[ToolProxy] 执行错误: ${tool}.${method}`, error) port.postMessage({ type: 'error', tool, method, callId, error: { name: error.name || 'ExecutionError', message: error.message, stack: error.stack } }) } } /** * 清理 Worker 资源 */ cleanupWorker(worker: Worker) { const port = this.activePorts.get(worker) if (port) { port.close() this.activePorts.delete(worker) } } }