feat: Implement configuration caching mechanism and force-refresh feature**

 **New Features**:

* Added API and frontend support for forcibly refreshing Clash configuration cache
* Implemented a configuration cache TTL mechanism (60 seconds) to reduce redundant requests
* Introduced `ProxyRequestCache` system to manage backend data caching
* Automatically refresh frontend state after core operations to enhance user experience

🚀 **Performance Optimizations**:

* Increased Clash configuration refresh interval from 5 seconds to 60 seconds
* Force refresh cache after configuration updates to resolve data inconsistency
* Automatically trigger state refresh after core switch, start, stop, and restart actions

🔧 **Technical Improvements**:

* Removed unused dependencies: `ab_glyph`, `owned_ttf_parser`, `ttf-parser`
* Simplified WebSocket dependency management, unified `tungstenite` version
* Refactored configuration save validation process, improved merge file handling
* Improved error handling and overall user experience
This commit is contained in:
Tunglies
2025-07-24 01:56:18 +08:00
parent 27535c7bb7
commit 3048a2ae08
10 changed files with 83 additions and 99 deletions

View File

@@ -18,7 +18,11 @@ import {
ListItemText,
} from "@mui/material";
import { changeClashCore, restartCore } from "@/services/cmds";
import { closeAllConnections, upgradeCore } from "@/services/cmds";
import {
closeAllConnections,
upgradeCore,
forceRefreshClashConfig,
} from "@/services/cmds";
import { showNotice } from "@/services/noticeService";
const VALID_CORE = [
@@ -58,7 +62,9 @@ export const ClashCoreViewer = forwardRef<DialogRef>((props, ref) => {
}
mutateVerge();
setTimeout(() => {
setTimeout(async () => {
// 核心切换后强制刷新配置缓存
await forceRefreshClashConfig();
mutate("getClashConfig");
mutate("getVersion");
setChangingCore(null);

View File

@@ -5,6 +5,7 @@ import {
getClashInfo,
patchClashConfig,
getRuntimeConfig,
forceRefreshClashConfig,
} from "@/services/cmds";
export const useClash = () => {
@@ -121,6 +122,8 @@ export const useClashInfo = () => {
await patchClashConfig(patch);
mutateInfo();
// 配置修改后强制刷新缓存
await forceRefreshClashConfig();
mutate("getClashConfig");
// IPC调用不需要刷新axios实例
};

View File

@@ -9,6 +9,7 @@ import { List, Paper, ThemeProvider, SvgIcon } from "@mui/material";
import { getCurrentWebviewWindow } from "@tauri-apps/api/webviewWindow";
import { routers } from "./_routers";
import { getAxios } from "@/services/api";
import { forceRefreshClashConfig } from "@/services/cmds";
import { useVerge } from "@/hooks/use-verge";
import LogoSvg from "@/assets/image/logo.svg?react";
import iconLight from "@/assets/image/icon_light.svg?react";
@@ -192,6 +193,8 @@ const Layout = () => {
const listeners = [
addListener("verge://refresh-clash-config", async () => {
await getAxios(true);
// 后端配置变更事件触发,强制刷新配置缓存
await forceRefreshClashConfig();
mutate("getProxies");
mutate("getVersion");
mutate("getClashConfig");

View File

@@ -185,7 +185,7 @@ export const AppDataProvider = ({
"getClashConfig",
getClashConfig,
{
refreshInterval: 5000,
refreshInterval: 60000, // 60秒刷新间隔减少频繁请求
revalidateOnFocus: false,
suspense: false,
errorRetryCount: 3,

View File

@@ -107,6 +107,10 @@ export async function getClashConfig() {
return invoke<IConfigData>("get_clash_config");
}
export async function forceRefreshClashConfig() {
return invoke<IConfigData>("force_refresh_clash_config");
}
export async function updateGeoData() {
return invoke<void>("update_geo_data");
}