// WebSocket 进度(可被 node --test 单测的纯逻辑部分) export interface ProgressEvent { type?: string; step?: string; detail?: string; } export interface WsHandlers { onProgress?: (e: ProgressEvent) => void; onClose?: () => void; } export type RenderFn = (role: string, text: string) => void; export function connectProgressWs(sid: string, handlers: WsHandlers): WebSocket | null { const proto = location.protocol === 'https:' ? 'wss' : 'ws'; let ws: WebSocket; try { ws = new WebSocket(proto + '://' + location.host + '/api/sessions/' + encodeURIComponent(sid) + '/ws'); } catch (err) { if (handlers.onClose) handlers.onClose(); return null; } ws.onmessage = (ev: MessageEvent) => { let e: ProgressEvent; try { e = JSON.parse(ev.data as string) as ProgressEvent; } catch { return; } if (handlers.onProgress) handlers.onProgress(e); }; ws.onerror = () => { try { ws.close(); } catch { /* ignore */ } }; ws.onclose = () => { if (handlers.onClose) handlers.onClose(); }; return ws; } export function applyProgressEvent(e: ProgressEvent, render: RenderFn): void { if (e.type === 'progress') render('progress', (e.step || '') + ': ' + (e.detail || '')); else if (e.type === 'error') render('error', e.detail || '错误'); }