gitscope
https://dev.kronoz.win/r/marzneshin.git
dashboard/src/features/nodes/services/logs.socket.ts · v0.5.3
Source
1 b15ff05 Mrdn 2y ago import { NodeType } from "@marzneshin/features/nodes";
2 b15ff05 Mrdn 2y ago import useWebSocket, { ReadyState } from "react-use-websocket";
3 b15ff05 Mrdn 2y ago import { useAuth } from "@marzneshin/features/auth";
4 b15ff05 Mrdn 2y ago import { joinPaths } from "@tanstack/react-router";
5 b15ff05 Mrdn 2y ago import { useCallback, useEffect, useRef, useState } from "react";
6 b15ff05 Mrdn 2y ago
7 f5c168d Mardin 2y ago export const MAX_NUMBER_OF_LOGS = 500;
8 b15ff05 Mrdn 2y ago
9 b15ff05 Mrdn 2y ago export const getStatus = (status: string) => {
10 f5c168d Mardin 2y ago return {
11 f5c168d Mardin 2y ago [ReadyState.CONNECTING]: "connecting",
12 f5c168d Mardin 2y ago [ReadyState.OPEN]: "connected",
13 f5c168d Mardin 2y ago [ReadyState.CLOSING]: "closed",
14 f5c168d Mardin 2y ago [ReadyState.CLOSED]: "closed",
15 f5c168d Mardin 2y ago [ReadyState.UNINSTANTIATED]: "closed",
16 f5c168d Mardin 2y ago }[status];
17 b15ff05 Mrdn 2y ago };
18 b15ff05 Mrdn 2y ago
19 f5c168d Mardin 2y ago export const getWebsocketUrl = (nodeId: number, backend: string) => {
20 f5c168d Mardin 2y ago try {
21 f5c168d Mardin 2y ago const baseURL = new URL(
22 f5c168d Mardin 2y ago import.meta.env.VITE_BASE_API.startsWith("/")
23 f5c168d Mardin 2y ago ? window.location.origin + import.meta.env.VITE_BASE_API
24 f5c168d Mardin 2y ago : import.meta.env.VITE_BASE_API,
25 f5c168d Mardin 2y ago );
26 f5c168d Mardin 2y ago const protocol = baseURL.protocol === "https:" ? "wss://" : "ws://";
27 f5c168d Mardin 2y ago return `${protocol}${joinPaths([baseURL.host + baseURL.pathname, `/nodes/${nodeId}/${backend}/logs`])}?interval=1&token=${useAuth.getState().getAuthToken()}`;
28 f5c168d Mardin 2y ago } catch (e) {
29 f5c168d Mardin 2y ago console.error("Unable to generate websocket url");
30 f5c168d Mardin 2y ago console.error(e);
31 f5c168d Mardin 2y ago return null;
32 f5c168d Mardin 2y ago }
33 b15ff05 Mrdn 2y ago };
34 b15ff05 Mrdn 2y ago
35 f5c168d Mardin 2y ago export const useNodesLog = (node: NodeType, backend: string) => {
36 f5c168d Mardin 2y ago const [logs, setLogs] = useState<string[]>([]);
37 f5c168d Mardin 2y ago const logsDiv = useRef<HTMLDivElement | null>(null);
38 f5c168d Mardin 2y ago const scrollShouldStayOnEnd = useRef(true);
39 b15ff05 Mrdn 2y ago
40 f5c168d Mardin 2y ago const updateLogs = useCallback(
41 f5c168d Mardin 2y ago (callback: (prevLogs: string[]) => string[]) => {
42 f5c168d Mardin 2y ago setLogs((prevLogs) => {
43 f5c168d Mardin 2y ago const newLogs = callback(prevLogs);
44 f5c168d Mardin 2y ago return newLogs.length > MAX_NUMBER_OF_LOGS
45 f5c168d Mardin 2y ago ? newLogs.slice(-MAX_NUMBER_OF_LOGS)
46 f5c168d Mardin 2y ago : newLogs;
47 f5c168d Mardin 2y ago });
48 f5c168d Mardin 2y ago },
49 f5c168d Mardin 2y ago [],
50 f5c168d Mardin 2y ago );
51 b15ff05 Mrdn 2y ago
52 f5c168d Mardin 2y ago const { readyState } = useWebSocket(
53 f5c168d Mardin 2y ago node?.id ? getWebsocketUrl(node.id, backend) : "",
54 f5c168d Mardin 2y ago {
55 f5c168d Mardin 2y ago onMessage: (e: any) => {
56 f5c168d Mardin 2y ago updateLogs((prevLogs) => [...prevLogs, e.data]);
57 f5c168d Mardin 2y ago },
58 f5c168d Mardin 2y ago shouldReconnect: () => true,
59 f5c168d Mardin 2y ago reconnectAttempts: 10,
60 f5c168d Mardin 2y ago reconnectInterval: 1000,
61 f5c168d Mardin 2y ago },
62 f5c168d Mardin 2y ago );
63 b15ff05 Mrdn 2y ago
64 f5c168d Mardin 2y ago useEffect(() => {
65 f5c168d Mardin 2y ago if (logsDiv.current && scrollShouldStayOnEnd.current) {
66 f5c168d Mardin 2y ago logsDiv.current.scrollTop = logsDiv.current.scrollHeight;
67 f5c168d Mardin 2y ago }
68 f5c168d Mardin 2y ago }, [logs]);
69 b15ff05 Mrdn 2y ago
70 f5c168d Mardin 2y ago useEffect(() => {
71 f5c168d Mardin 2y ago return () => {
72 f5c168d Mardin 2y ago // Cleanup
73 f5c168d Mardin 2y ago setLogs([]);
74 f5c168d Mardin 2y ago };
75 f5c168d Mardin 2y ago }, []);
76 b15ff05 Mrdn 2y ago
77 f5c168d Mardin 2y ago const status = getStatus(readyState.toString());
78 b15ff05 Mrdn 2y ago
79 f5c168d Mardin 2y ago return { status, readyState, logs, logsDiv };
80 b15ff05 Mrdn 2y ago };