71 lines
1.9 KiB
TypeScript
71 lines
1.9 KiB
TypeScript
import { LOCAL_API_BASE } from 'shared/config/api';
|
|
import { TaskInfo } from 'shared/domain/librarian/task';
|
|
|
|
export class TaskWebSocket {
|
|
private ws: WebSocket | null = null;
|
|
private taskId: string;
|
|
private taskType: string;
|
|
private onUpdate: (taskInfo: TaskInfo) => void;
|
|
private onError: (error: any) => void;
|
|
|
|
constructor(
|
|
taskId: string,
|
|
taskType: string,
|
|
onUpdate: (taskInfo: TaskInfo) => void,
|
|
onError: (error: any) => void
|
|
) {
|
|
this.taskId = taskId;
|
|
this.taskType = taskType;
|
|
this.onUpdate = onUpdate;
|
|
this.onError = onError;
|
|
}
|
|
|
|
connect() {
|
|
this.ws = new WebSocket(
|
|
`ws://${LOCAL_API_BASE.replace(/^http/, 'ws')}/${this.taskType}/ws/${this.taskId}`
|
|
);
|
|
|
|
this.ws.onmessage = (event) => {
|
|
try {
|
|
const taskInfo = JSON.parse(event.data);
|
|
this.onUpdate(taskInfo);
|
|
|
|
if (
|
|
taskInfo.state === 'success' ||
|
|
taskInfo.state === 'error'
|
|
) {
|
|
this.disconnect();
|
|
}
|
|
} catch (e) {
|
|
this.onError(new Error('Failed to parse WebSocket message'));
|
|
this.disconnect();
|
|
}
|
|
};
|
|
|
|
this.ws.onerror = (errorEvent) => {
|
|
const error = new Error('WebSocket error');
|
|
(error as any).event = errorEvent;
|
|
this.onError(error);
|
|
this.disconnect();
|
|
};
|
|
|
|
this.ws.onclose = (event) => {
|
|
if (event.wasClean === false) {
|
|
this.onError(
|
|
new Error(
|
|
`WebSocket closed unexpectedly: ${event.code} ${event.reason || ''}`.trim()
|
|
)
|
|
);
|
|
}
|
|
this.ws = null;
|
|
};
|
|
}
|
|
|
|
disconnect() {
|
|
if (this.ws) {
|
|
this.ws.close();
|
|
this.ws = null;
|
|
}
|
|
}
|
|
}
|