Files
2026Technology-Competition/frontend/src/ws.ts
T

29 lines
1.3 KiB
TypeScript

// 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 || '错误');
}