mirror of
https://github.com/farion1231/cc-switch.git
synced 2026-07-25 13:45:03 +08:00
refactor: replace JSON deep copy with deepClone helper and extract useTauriEvent hook (#3140)
* refactor: replace JSON.parse(JSON.stringify()) with structuredClone and extract useTauriEvent hook Replace all `JSON.parse(JSON.stringify())` deep copy patterns with native `structuredClone()` across production source (9 occurrences), tests (11 occurrences), and a hand-rolled `deepClone` utility in providerConfigUtils.ts. Add "ES2022" to tsconfig lib for type support. Extract a `useTauriEvent` hook to eliminate the repeated Tauri event listener boilerplate (`useEffect` + `active/disposed` flag + async `listen`) that was duplicated across App.tsx (3 listeners) and useUsageCacheBridge.ts. The hook handles async registration, race-condition guards, and cleanup automatically. * fix: add compatible deepClone helper - Add a shared deepClone helper with a structuredClone runtime guard and fallback. - Route clone call sites through the helper. - Preserve universal-provider-synced listener ordering and drop the dead-directory diff. * fix: harden Tauri event handling - Guard WebDAV sync status events against missing payloads. - Preserve settings query invalidation ordering before showing auto-sync errors. - Simplify useTauriEvent subscriptions to avoid dependency-driven re-listens. --------- Co-authored-by: zcb <zhangchongbiao@qiyuanlab.com> Co-authored-by: Jason <farion1231@gmail.com>
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
export function deepClone<T>(value: T): T {
|
||||
if (typeof globalThis.structuredClone === "function") {
|
||||
return globalThis.structuredClone(value);
|
||||
}
|
||||
|
||||
return deepCloneFallback(value);
|
||||
}
|
||||
|
||||
function deepCloneFallback<T>(value: T): T {
|
||||
if (value === null || typeof value !== "object") return value;
|
||||
if (value instanceof Date) return new Date(value.getTime()) as T;
|
||||
if (Array.isArray(value)) {
|
||||
return value.map((item) => deepCloneFallback(item)) as T;
|
||||
}
|
||||
|
||||
const cloned = {} as T;
|
||||
Object.keys(value).forEach((key) => {
|
||||
cloned[key as keyof T] = deepCloneFallback(value[key as keyof T]);
|
||||
});
|
||||
return cloned;
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
// 供应商配置处理工具函数
|
||||
|
||||
import type { TemplateValueConfig } from "../config/claudeProviderPresets";
|
||||
import { deepClone } from "@/utils/deepClone";
|
||||
import { normalizeTomlText } from "@/utils/textNormalization";
|
||||
import { parse as parseToml, stringify as stringifyToml } from "smol-toml";
|
||||
|
||||
@@ -62,23 +63,6 @@ const isSubset = (target: any, source: any): boolean => {
|
||||
return target === source;
|
||||
};
|
||||
|
||||
// 深拷贝函数
|
||||
const deepClone = <T>(obj: T): T => {
|
||||
if (obj === null || typeof obj !== "object") return obj;
|
||||
if (obj instanceof Date) return new Date(obj.getTime()) as T;
|
||||
if (obj instanceof Array) return obj.map((item) => deepClone(item)) as T;
|
||||
if (obj instanceof Object) {
|
||||
const clonedObj = {} as T;
|
||||
for (const key in obj) {
|
||||
if (obj.hasOwnProperty(key)) {
|
||||
clonedObj[key] = deepClone(obj[key]);
|
||||
}
|
||||
}
|
||||
return clonedObj;
|
||||
}
|
||||
return obj;
|
||||
};
|
||||
|
||||
export interface UpdateCommonConfigResult {
|
||||
updatedConfig: string;
|
||||
error?: string;
|
||||
|
||||
Reference in New Issue
Block a user