LΓͺ Phi Nam
Deploy to HF Space
94004a2
Raw
History Blame Contribute Delete
6.06 kB
// ── TanStack Query hooks ─────────────────────────────────────────────────
// Central place for all query/mutation hooks. Components import from here
// instead of calling api/* + useEffect + useState manually.
// Deduplication is automatic β€” two components using useSysinfo() share one
// network request and one cache entry.
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import * as systemApi from './system';
import * as setupApi from './setup';
import * as galleryApi from './gallery';
// ── Keys (prevents typos, enables targeted invalidation) ─────────────────
export const queryKeys = {
sysinfo: ['sysinfo'] as const,
modelStatus: ['model-status'] as const,
systemInfo: ['system-info'] as const,
systemLogs: (tail?: number) => ['system-logs', tail ?? 300] as const,
tauriLogs: (tail?: number) => ['tauri-logs', tail ?? 300] as const,
models: ['models'] as const,
recommendations: ['recommendations'] as const,
preflight: ['preflight'] as const,
setupStatus: ['setup-status'] as const,
galleryVoices: (params?: any) => ['gallery-voices', params] as const,
galleryCategories: ['gallery-categories'] as const,
};
// ── Polling queries (sysinfo, model status, logs) ────────────────────────
export function useSysinfo(enabled = true) {
return useQuery({
queryKey: queryKeys.sysinfo,
queryFn: systemApi.sysinfo,
refetchInterval: 5_000,
refetchIntervalInBackground: true,
retry: Infinity,
retryDelay: 1_500,
enabled,
});
}
export function useModelStatus(enabled = true) {
return useQuery({
queryKey: queryKeys.modelStatus,
queryFn: systemApi.modelStatus,
// Poll every 2s while model is loading for near-real-time sub-stage
// updates in the floating pill; 10s when idle/ready to save bandwidth.
refetchInterval: (query) => {
const status = query.state?.data?.status;
return status === 'loading' ? 2_000 : 10_000;
},
refetchIntervalInBackground: false,
retry: Infinity,
retryDelay: 1_500,
enabled,
});
}
export function useSystemLogs(tail = 300, enabled = true) {
return useQuery({
queryKey: queryKeys.systemLogs(tail),
queryFn: () => systemApi.systemLogs(tail),
refetchInterval: 10_000,
refetchIntervalInBackground: false,
enabled,
});
}
export function useTauriLogs(tail = 300, enabled = true) {
return useQuery({
queryKey: queryKeys.tauriLogs(tail),
queryFn: () => systemApi.systemLogsTauri(tail),
refetchInterval: 10_000,
refetchIntervalInBackground: false,
enabled,
});
}
// ── One-shot queries ─────────────────────────────────────────────────────
export function useSystemInfo() {
return useQuery({
queryKey: queryKeys.systemInfo,
queryFn: systemApi.systemInfo,
staleTime: 60_000,
retry: Infinity,
retryDelay: 2_000,
});
}
export function useModels() {
return useQuery({
queryKey: queryKeys.models,
queryFn: setupApi.listModels,
staleTime: 30_000,
});
}
export function useRecommendations() {
return useQuery({
queryKey: queryKeys.recommendations,
queryFn: setupApi.getRecommendations,
staleTime: 30_000,
});
}
export function usePreflight() {
return useQuery({
queryKey: queryKeys.preflight,
queryFn: setupApi.preflight,
staleTime: 60_000,
});
}
export function useSetupStatus() {
return useQuery({
queryKey: queryKeys.setupStatus,
queryFn: setupApi.setupStatus,
staleTime: 10_000,
});
}
export function useGalleryCategories() {
return useQuery({
queryKey: queryKeys.galleryCategories,
queryFn: galleryApi.listCategories,
staleTime: 60_000,
});
}
export function useGalleryVoices(params?: any) {
return useQuery({
queryKey: queryKeys.galleryVoices(params),
queryFn: () => galleryApi.listGalleryVoices(params),
staleTime: 30_000,
});
}
// ── Mutations ────────────────────────────────────────────────────────────
export function useInstallModel() {
const qc = useQueryClient();
return useMutation({
mutationFn: (repo_id: string) => setupApi.installModel(repo_id),
onSuccess: () => {
qc.invalidateQueries({ queryKey: queryKeys.models });
qc.invalidateQueries({ queryKey: queryKeys.setupStatus });
qc.invalidateQueries({ queryKey: queryKeys.recommendations });
},
});
}
export function useDeleteModel() {
const qc = useQueryClient();
return useMutation({
mutationFn: (repo_id: string) => setupApi.deleteModel(repo_id),
onSuccess: () => {
qc.invalidateQueries({ queryKey: queryKeys.models });
qc.invalidateQueries({ queryKey: queryKeys.setupStatus });
qc.invalidateQueries({ queryKey: queryKeys.recommendations });
},
});
}
export function useFlushMemory() {
const qc = useQueryClient();
return useMutation({
mutationFn: (unloadModel: boolean) => systemApi.flushMemory(unloadModel),
onSuccess: () => {
qc.invalidateQueries({ queryKey: queryKeys.sysinfo });
qc.invalidateQueries({ queryKey: queryKeys.modelStatus });
},
});
}
export function useClearLogs() {
const qc = useQueryClient();
return useMutation({
mutationFn: () => systemApi.clearSystemLogs(),
onSuccess: () => {
qc.invalidateQueries({ queryKey: queryKeys.systemLogs() });
},
});
}
export function useClearTauriLogs() {
const qc = useQueryClient();
return useMutation({
mutationFn: () => systemApi.clearTauriLogs(),
onSuccess: () => {
qc.invalidateQueries({ queryKey: queryKeys.tauriLogs() });
},
});
}