import type { CatalogInfo, Evaluation, Filters, Heatmap, ProjectionPoint, SearchResponse, Robustness, SimilarResponse, } from "./types"; async function get(path: string): Promise { const res = await fetch(path); if (!res.ok) throw new Error(`${path} -> ${res.status} ${res.statusText}`); return res.json() as Promise; } export const getCatalog = () => get("/api/catalog"); export const getEvaluation = () => get("/api/evaluation"); export const getRobustness = () => get("/api/robustness"); export const getProjection = () => get<{ points: ProjectionPoint[] }>("/api/projection").then((d) => d.points); export const getSimilar = (id: string, k = 6) => get(`/api/voices/${id}/similar?k=${k}`); export async function search( query: string, topN = 12, filters: Filters = {}, ): Promise { const res = await fetch("/api/search", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ query, topN, filters }), }); if (!res.ok) { const detail = await res.json().catch(() => null); throw new Error(detail?.detail ?? `search failed (${res.status})`); } return res.json(); } export async function heatmap(query: string, topN = 10): Promise { const res = await fetch("/api/heatmap", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ query, topN }), }); if (!res.ok) { const detail = await res.json().catch(() => null); throw new Error(detail?.detail ?? `heatmap failed (${res.status})`); } return res.json(); }