Spaces:
Running
Running
File size: 2,934 Bytes
b03f016 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 | import type { Experiment, ExperimentDetail, SubExperiment, ExperimentNote, ActivityLogEntry, Artifact } from "./types";
const BASE = "/api/experiments";
async function fetchJSON<T>(url: string, opts?: RequestInit): Promise<T> {
const res = await fetch(url, {
headers: { "Content-Type": "application/json" },
...opts,
});
if (!res.ok) {
const err = await res.json().catch(() => ({ error: res.statusText }));
throw new Error(err.error || res.statusText);
}
return res.json();
}
export const experimentsApi = {
list() {
return fetchJSON<Experiment[]>(`${BASE}/`);
},
get(id: string) {
return fetchJSON<ExperimentDetail>(`${BASE}/${id}`);
},
create(data: Partial<Experiment>) {
return fetchJSON<Experiment>(`${BASE}/`, {
method: "POST",
body: JSON.stringify(data),
});
},
update(id: string, data: Partial<Experiment>) {
return fetchJSON<Experiment>(`${BASE}/${id}`, {
method: "PUT",
body: JSON.stringify(data),
});
},
delete(id: string) {
return fetchJSON<{ status: string }>(`${BASE}/${id}`, { method: "DELETE" });
},
createSub(expId: string, data: Partial<SubExperiment>) {
return fetchJSON<SubExperiment>(`${BASE}/${expId}/subs`, {
method: "POST",
body: JSON.stringify(data),
});
},
updateSub(expId: string, subId: string, data: Partial<SubExperiment>) {
return fetchJSON<SubExperiment>(`${BASE}/${expId}/subs/${subId}`, {
method: "PUT",
body: JSON.stringify(data),
});
},
deleteSub(expId: string, subId: string) {
return fetchJSON<{ status: string }>(`${BASE}/${expId}/subs/${subId}`, { method: "DELETE" });
},
// Notes
createNote(expId: string, data: Partial<ExperimentNote>) {
return fetchJSON<ExperimentNote>(`${BASE}/${expId}/notes`, {
method: "POST",
body: JSON.stringify(data),
});
},
updateNote(expId: string, noteId: string, data: Partial<ExperimentNote>) {
return fetchJSON<ExperimentNote>(`${BASE}/${expId}/notes/${noteId}`, {
method: "PUT",
body: JSON.stringify(data),
});
},
deleteNote(expId: string, noteId: string) {
return fetchJSON<{ status: string }>(`${BASE}/${expId}/notes/${noteId}`, { method: "DELETE" });
},
sync() {
return fetchJSON<{ status: string }>(`${BASE}/sync`, { method: "POST" });
},
getSummary() {
return fetchJSON<{ content_md: string; updated: string }>(`${BASE}/summary`);
},
getActivityLog(expId: string, filters?: { scope?: string; type?: string }) {
const params = new URLSearchParams();
if (filters?.scope) params.set("scope", filters.scope);
if (filters?.type) params.set("type", filters.type);
const qs = params.toString();
return fetchJSON<ActivityLogEntry[]>(`${BASE}/${expId}/activity-log${qs ? `?${qs}` : ""}`);
},
getArtifacts(expId: string) {
return fetchJSON<Artifact[]>(`${BASE}/${expId}/artifacts`);
},
};
|