Files
explore/ui/megaEth/uptime/useUptimeSocketData.ts
tom goriunovandGitHub 3d98f2d702 MegaETH: mini-blocks page (#3024)
* MegaETH: uptime dashboard

Fixes #2906

* basic implementation of mini-blocks

* update socket url and time format

* update mega eth preset

* customize flashblocks name

* clean up

* update color theme variable for mega eth

* [skip ci] don't show alert "scanning new mini-blocks"
2025-10-08 09:35:35 +02:00

92 lines
2.8 KiB
TypeScript

import React from 'react';
import type { UptimeHistoryFull, UptimeRealTimeData, UptimeSocketData } from 'types/api/megaEth';
import config from 'configs/app';
import { SECOND } from 'toolkit/utils/consts';
const megaEthFeature = config.features.megaEth;
export type Status = 'initial' | 'connected' | 'disconnected' | 'error';
export default function useUptimeSocketData() {
const websocketRef = React.useRef<WebSocket | null>(null);
const heartbeatRef = React.useRef<number | undefined>(undefined);
const [ status, setStatus ] = React.useState<Status>('initial');
const [ realtimeData, setRealtimeData ] = React.useState<UptimeRealTimeData | null>(null);
const [ historyData, setHistoryData ] = React.useState<UptimeHistoryFull | null>(null);
const connect = React.useCallback(() => {
if (!megaEthFeature.isEnabled || !megaEthFeature.socketUrl.metrics) {
return;
}
websocketRef.current = new WebSocket(megaEthFeature.socketUrl.metrics);
websocketRef.current.onmessage = async(event) => {
try {
const data = JSON.parse(event.data) as UptimeSocketData;
switch (data.type) {
case 'realtime_metrics':
setRealtimeData(data.realtime);
break;
case 'history_full':
setHistoryData(data.data);
break;
case 'history_delta':
setHistoryData((prev) => {
if (!prev) {
return null;
}
return Object.entries(data.data).reduce((acc, [ key, value ]) => {
acc[key as keyof UptimeHistoryFull] = [ ...(acc[key as keyof UptimeHistoryFull] || []), value ];
return acc;
}, { ...prev });
});
break;
}
} catch (error) {
// eslint-disable-next-line no-console
console.error(error);
}
};
websocketRef.current.onopen = () => {
setStatus('connected');
heartbeatRef.current = window.setInterval(() => {
if (websocketRef.current?.readyState === WebSocket.OPEN) {
websocketRef.current?.send('ping');
}
}, 10 * SECOND);
};
websocketRef.current.onerror = (error) => {
// eslint-disable-next-line no-console
console.error(error);
setStatus('error');
};
websocketRef.current.onclose = (event) => {
// eslint-disable-next-line no-console
console.error('WebSocket closed', event);
setStatus('disconnected');
};
}, []);
const onReconnect = React.useCallback(() => {
connect();
}, [ connect ]);
React.useEffect(() => {
connect();
return () => {
websocketRef.current?.close(4000, 'Component unmounted');
window.clearInterval(heartbeatRef.current);
};
}, [ connect ]);
return { status, realtimeData, historyData, onReconnect };
}