mirror of
https://github.com/clash-verge-rev/clash-verge-rev.git
synced 2026-11-05 16:22:08 +08:00
feat(mutate): single funnel for user-intent commands and invoke gate
Adds src/services/mutate.ts: one path for optimistic apply, services-layer invoke, Busy handling, failure rollback, and the error toast, with busy bookkeeping mirrored into the app store. The patch hooks (verge, clash, profiles) now route through it. Moves the remaining direct invokes (unlock ×3, DNS ×4) into cmds.ts and turns on the invoke-only-in-services architecture gate in CI.
This commit is contained in:
@@ -8,6 +8,7 @@ import {
|
||||
getRuntimeConfig,
|
||||
patchClashConfig,
|
||||
} from '@/services/cmds'
|
||||
import { mutate } from '@/services/mutate'
|
||||
import {
|
||||
revalidateQuery,
|
||||
setCacheData,
|
||||
@@ -104,8 +105,10 @@ export const useClash = () => {
|
||||
}
|
||||
|
||||
const patchClash = useLockFn(async (patch: Partial<IConfigData>) => {
|
||||
await patchClashConfig(patch)
|
||||
mutateClash()
|
||||
await mutate(() => patchClashConfig(patch), {
|
||||
id: 'patch-clash-config',
|
||||
revalidate: [['getRuntimeConfig']],
|
||||
})
|
||||
})
|
||||
|
||||
const version = versionData?.meta
|
||||
@@ -132,9 +135,10 @@ export const useClashInfo = () => {
|
||||
|
||||
validatePorts(patch)
|
||||
|
||||
await patchClashConfig(patch)
|
||||
mutateInfo()
|
||||
revalidateQuery(['getClashConfig'])
|
||||
await mutate(() => patchClashConfig(patch), {
|
||||
id: 'patch-clash-info',
|
||||
revalidate: [['getClashInfo'], ['getClashConfig']],
|
||||
})
|
||||
})
|
||||
|
||||
const invalidateClashConfig = () => revalidateQuery(['getClashConfig'])
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { useCallback, useRef } from 'react'
|
||||
|
||||
import { getProfiles, patchProfile, patchProfilesConfig } from '@/services/cmds'
|
||||
import { mutate } from '@/services/mutate'
|
||||
import { fetchCacheData, setCacheData, useQuery } from '@/services/query-client'
|
||||
import { debugLog } from '@/utils/debug'
|
||||
|
||||
@@ -42,16 +43,25 @@ export const useProfiles = () => {
|
||||
const patchProfiles = useCallback(
|
||||
async (value: Partial<IProfilesConfig>) => {
|
||||
try {
|
||||
const outcome = await patchProfilesConfig(value)
|
||||
const result = await mutate(() => patchProfilesConfig(value), {
|
||||
id: 'patch-profiles-config',
|
||||
onFulfilled: (outcome) => {
|
||||
if (outcome.status === 'valid') {
|
||||
void setCacheData<IProfilesConfig>(profilesQueryKey, (current) =>
|
||||
current ? { ...current, ...value } : current,
|
||||
)
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
if (outcome.status === 'valid') {
|
||||
await setCacheData<IProfilesConfig>(profilesQueryKey, (current) =>
|
||||
current ? { ...current, ...value } : current,
|
||||
)
|
||||
} else if (outcome.status !== 'busy') {
|
||||
if (!result.ok) {
|
||||
// Backend Busy keeps local state untouched, as before.
|
||||
return result.value ?? { status: 'busy' }
|
||||
}
|
||||
const outcome = result.value
|
||||
if (outcome.status !== 'valid' && outcome.status !== 'busy') {
|
||||
await mutateProfiles()
|
||||
}
|
||||
|
||||
return outcome
|
||||
} catch (error) {
|
||||
await mutateProfiles()
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { useCallback } from 'react'
|
||||
|
||||
import { getVergeConfig, patchVergeConfig } from '@/services/cmds'
|
||||
import { mutate } from '@/services/mutate'
|
||||
import { getPreloadConfig, setPreloadConfig } from '@/services/preload'
|
||||
import { setCacheData, useQuery } from '@/services/query-client'
|
||||
|
||||
@@ -38,13 +39,12 @@ export const useVerge = () => {
|
||||
)
|
||||
}
|
||||
|
||||
const patchVerge = useCallback(
|
||||
async (value: Partial<IVergeConfig>) => {
|
||||
await patchVergeConfig(value)
|
||||
await refetch()
|
||||
},
|
||||
[refetch],
|
||||
)
|
||||
const patchVerge = useCallback(async (value: Partial<IVergeConfig>) => {
|
||||
await mutate(() => patchVergeConfig(value), {
|
||||
id: 'patch-verge-config',
|
||||
revalidate: [['getVergeConfig']],
|
||||
})
|
||||
}, [])
|
||||
|
||||
return {
|
||||
verge,
|
||||
|
||||
Reference in New Issue
Block a user