29 lines
1.3 KiB
TypeScript
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 || '错误');
|
|
}
|