import { useLocalStorage } from "foxact/use-local-storage"; import { useEffect, useRef } from "react"; import { mutate } from "swr"; import useSWRSubscription from "swr/subscription"; import { MihomoWebSocket } from "tauri-plugin-mihomo-api"; export interface IMemoryUsageItem { inuse: number; oslimit?: number; } export const useMemoryData = () => { const [date, setDate] = useLocalStorage("mihomo_memory_date", Date.now()); const subscriptKey = `getClashMemory-${date}`; const ws = useRef(null); const wsFirstConnection = useRef(true); const timeoutRef = useRef>(null); const response = useSWRSubscription( subscriptKey, (_key, { next }) => { const reconnect = async () => { await ws.current?.close(); ws.current = null; timeoutRef.current = setTimeout(async () => await connect(), 500); }; const connect = () => MihomoWebSocket.connect_memory() .then((ws_) => { ws.current = ws_; if (timeoutRef.current) clearTimeout(timeoutRef.current); ws_.addListener(async (msg) => { if (msg.type === "Text") { if (msg.data.startsWith("Websocket error")) { next(msg.data, { inuse: 0 }); await reconnect(); } else { const data = JSON.parse(msg.data) as IMemoryUsageItem; next(null, data); } } }); }) .catch((_) => { if (!ws.current) { timeoutRef.current = setTimeout(async () => await connect(), 500); } }); if ( wsFirstConnection.current || (ws.current && !wsFirstConnection.current) ) { wsFirstConnection.current = false; if (ws.current) { ws.current.close(); ws.current = null; } connect(); } return () => { ws.current?.close(); }; }, { fallbackData: { inuse: 0 }, keepPreviousData: true, }, ); useEffect(() => { mutate(`$sub$${subscriptKey}`); }, [date, subscriptKey]); const refreshGetClashMemory = () => { setDate(Date.now()); }; return { response, refreshGetClashMemory }; };