feat: harden runtime readiness and session workflow
This commit is contained in:
@@ -12,7 +12,11 @@ export async function apiFetch<T>(path: string, init?: RequestInit): Promise<T>
|
||||
}
|
||||
const res = await fetch(joinBackendPath(BASE, path), { ...init, headers });
|
||||
if (!res.ok) throw new Error(`${res.status} ${await res.text().catch(() => "")}`);
|
||||
return res.status === 204 ? (undefined as T) : ((await res.json()) as T);
|
||||
if (res.status === 204) return undefined as T;
|
||||
// Accepted fire-and-forget endpoints may legitimately return 202 with no
|
||||
// representation. Keep apiFetch useful for both 202 and 204 contracts.
|
||||
const body = await res.text();
|
||||
return body ? (JSON.parse(body) as T) : (undefined as T);
|
||||
}
|
||||
|
||||
export { BASE };
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { http, HttpResponse } from "msw";
|
||||
import { server } from "../test/msw";
|
||||
import { createSession, listSessions } from "./sessions";
|
||||
import { createSession, listSessions, prewarmRuntime } from "./sessions";
|
||||
import {
|
||||
renameSession, setSessionGroup, archiveSession, unarchiveSession,
|
||||
deleteSession, getSessionDocuments,
|
||||
@@ -18,6 +18,18 @@ test("createSession POSTs only {question} and returns the id", async () => {
|
||||
expect(body).toEqual({ question: "q" });
|
||||
});
|
||||
|
||||
test.each([202, 204])("prewarmRuntime accepts a body-less %s response", async (status) => {
|
||||
let called = false;
|
||||
server.use(
|
||||
http.post("http://localhost:8787/runtime/prewarm", () => {
|
||||
called = true;
|
||||
return new HttpResponse(null, { status });
|
||||
}),
|
||||
);
|
||||
await expect(prewarmRuntime()).resolves.toBeUndefined();
|
||||
expect(called).toBe(true);
|
||||
});
|
||||
|
||||
test("listSessions GETs the array", async () => {
|
||||
server.use(http.get("http://localhost:8787/sessions", () => HttpResponse.json([{ id: "s1", status: "open", question: "q", summary: null, created_at: "t", updated_at: null, author: null }])));
|
||||
const rows = await listSessions();
|
||||
|
||||
@@ -4,6 +4,10 @@ import type { SessionSummary, SessionDocument, UiResponse } from "./types";
|
||||
export const createSession = (i: { question: string; name?: string }) =>
|
||||
apiFetch<{ id: string }>("/sessions", { method: "POST", body: JSON.stringify(i) });
|
||||
|
||||
/** Best-effort warm-up; callers must not await it before showing the composer. */
|
||||
export const prewarmRuntime = () =>
|
||||
apiFetch<void>("/runtime/prewarm", { method: "POST" });
|
||||
|
||||
export const listSessions = () => apiFetch<SessionSummary[]>("/sessions");
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
|
||||
Reference in New Issue
Block a user