0.16.1-1 release snapshot
This commit is contained in:
@@ -0,0 +1,104 @@
|
||||
import { useEffect, useRef } from 'react';
|
||||
|
||||
function buildWsUrl() {
|
||||
if (import.meta.env.VITE_WS_URL) {
|
||||
return import.meta.env.VITE_WS_URL;
|
||||
}
|
||||
|
||||
const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
|
||||
return `${protocol}//${window.location.host}/ws`;
|
||||
}
|
||||
|
||||
export function useWebSocket({ onMessage }) {
|
||||
const onMessageRef = useRef(onMessage);
|
||||
onMessageRef.current = onMessage;
|
||||
|
||||
useEffect(() => {
|
||||
let socket;
|
||||
let reconnectTimer;
|
||||
let progressFlushTimer = null;
|
||||
let progressFlushRaf = null;
|
||||
let latestProgressMessage = null;
|
||||
let isUnmounted = false;
|
||||
|
||||
const clearProgressFlush = () => {
|
||||
if (progressFlushRaf !== null && typeof window !== 'undefined' && typeof window.cancelAnimationFrame === 'function') {
|
||||
window.cancelAnimationFrame(progressFlushRaf);
|
||||
}
|
||||
if (progressFlushTimer) {
|
||||
clearTimeout(progressFlushTimer);
|
||||
}
|
||||
progressFlushRaf = null;
|
||||
progressFlushTimer = null;
|
||||
};
|
||||
|
||||
const flushProgressMessage = () => {
|
||||
progressFlushRaf = null;
|
||||
progressFlushTimer = null;
|
||||
const message = latestProgressMessage;
|
||||
latestProgressMessage = null;
|
||||
if (!message) {
|
||||
return;
|
||||
}
|
||||
onMessageRef.current?.(message);
|
||||
};
|
||||
|
||||
const scheduleProgressFlush = () => {
|
||||
if (progressFlushRaf !== null || progressFlushTimer) {
|
||||
return;
|
||||
}
|
||||
if (typeof window !== 'undefined' && typeof window.requestAnimationFrame === 'function') {
|
||||
progressFlushRaf = window.requestAnimationFrame(flushProgressMessage);
|
||||
return;
|
||||
}
|
||||
progressFlushTimer = setTimeout(flushProgressMessage, 16);
|
||||
};
|
||||
|
||||
const connect = () => {
|
||||
if (isUnmounted) {
|
||||
return;
|
||||
}
|
||||
|
||||
socket = new WebSocket(buildWsUrl());
|
||||
|
||||
socket.onmessage = (event) => {
|
||||
try {
|
||||
const message = JSON.parse(event.data);
|
||||
if (message?.type === 'PIPELINE_PROGRESS') {
|
||||
latestProgressMessage = message;
|
||||
scheduleProgressFlush();
|
||||
return;
|
||||
}
|
||||
onMessageRef.current?.(message);
|
||||
} catch (error) {
|
||||
// ignore invalid json
|
||||
}
|
||||
};
|
||||
|
||||
socket.onclose = () => {
|
||||
if (!isUnmounted) {
|
||||
reconnectTimer = setTimeout(connect, 1500);
|
||||
}
|
||||
};
|
||||
|
||||
socket.onerror = () => {
|
||||
if (socket && socket.readyState !== WebSocket.CLOSED) {
|
||||
socket.close();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
connect();
|
||||
|
||||
return () => {
|
||||
isUnmounted = true;
|
||||
clearProgressFlush();
|
||||
if (reconnectTimer) {
|
||||
clearTimeout(reconnectTimer);
|
||||
}
|
||||
if (socket && socket.readyState !== WebSocket.CLOSED) {
|
||||
socket.close();
|
||||
}
|
||||
};
|
||||
}, []);
|
||||
}
|
||||
Reference in New Issue
Block a user