diff --git a/client/src/lib/api.ts b/client/src/lib/api.ts new file mode 100644 index 0000000..6b3012c --- /dev/null +++ b/client/src/lib/api.ts @@ -0,0 +1,21 @@ +// client/src/lib/api.ts +import type { MachineView, UpdateSnapshot, ActionType } from "@shared/types.js"; + +async function req(path: string, init?: RequestInit): Promise { + const res = await fetch(`/api${path}`, { + headers: { "content-type": "application/json" }, + ...init, + }); + if (!res.ok) throw new Error((await res.json().catch(() => ({}))).error ?? res.statusText); + return res.json() as Promise; +} + +export const api = { + listMachines: () => req("/machines"), + createMachine: (body: unknown) => req("/machines", { method: "POST", body: JSON.stringify(body) }), + refresh: (id: string) => req(`/machines/${id}/refresh`, { method: "POST" }), + snapshot: (id: string) => req(`/machines/${id}/snapshot`), + runAction: (id: string, action: ActionType) => + req<{ ok: boolean }>(`/machines/${id}/actions`, { method: "POST", body: JSON.stringify({ action }) }), + deleteMachine: (id: string) => req<{ ok: boolean }>(`/machines/${id}`, { method: "DELETE" }), +}; diff --git a/client/src/lib/ws.ts b/client/src/lib/ws.ts new file mode 100644 index 0000000..e0f7da3 --- /dev/null +++ b/client/src/lib/ws.ts @@ -0,0 +1,7 @@ +// client/src/lib/ws.ts +export function connectOutput(machineId: string, onChunk: (s: string) => void): () => void { + const proto = location.protocol === "https:" ? "wss" : "ws"; + const ws = new WebSocket(`${proto}://${location.host}/api/ws/machines/${machineId}/output`); + ws.onmessage = (ev) => onChunk(typeof ev.data === "string" ? ev.data : ""); + return () => ws.close(); +}