Files
rods/gui-ts/src/api/client.ts
Conner Majic 725a72a773 Initial commit: establish deterministic rod-string solver stack.
Set up the C solver core, Node API orchestration, TS GUI workflow, and engineering documentation with cleaned repo hygiene for private Git hosting.

Made-with: Cursor
2026-04-16 21:59:42 -06:00

87 lines
2.5 KiB
TypeScript

import type { ParsedCase, SolveResponse } from "../types";
const API_BASE =
(import.meta as unknown as { env?: { VITE_API_BASE?: string } }).env?.VITE_API_BASE ||
"http://localhost:4400";
export type SolverModel = "fdm" | "fea" | "both";
export type Workflow = "predictive" | "diagnostic";
export type SurfaceCard = {
position: number[];
load: number[];
time?: number[];
};
async function handleJson<T>(resp: Response): Promise<T> {
const body = await resp.json().catch(() => ({}));
if (!resp.ok) {
const message =
(body && typeof body === "object" && "error" in body && typeof body.error === "string"
? body.error
: null) || `Request failed: HTTP ${resp.status}`;
throw new Error(message);
}
return body as T;
}
export async function fetchDefaultCase(signal?: AbortSignal): Promise<ParsedCase> {
const resp = await fetch(`${API_BASE}/case/default`, { signal });
return handleJson<ParsedCase>(resp);
}
export async function parseCaseXmlApi(xml: string, signal?: AbortSignal): Promise<ParsedCase> {
const resp = await fetch(`${API_BASE}/case/parse`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ xml }),
signal
});
return handleJson<ParsedCase>(resp);
}
export type SolveArgs = {
xml: string;
solverModel: SolverModel;
workflow?: Workflow;
surfaceCard?: SurfaceCard;
options?: {
enableProfiles?: boolean;
enableDiagnosticsDetail?: boolean;
enableFourierBaseline?: boolean;
fourierHarmonics?: number;
};
};
export async function solveCase(args: SolveArgs, signal?: AbortSignal): Promise<SolveResponse> {
const body: Record<string, unknown> = {
xml: args.xml,
solverModel: args.solverModel
};
if (args.workflow) body.workflow = args.workflow;
if (args.surfaceCard) body.surfaceCard = args.surfaceCard;
if (args.options) body.options = args.options;
const resp = await fetch(`${API_BASE}/solve`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(body),
signal
});
return handleJson<SolveResponse>(resp);
}
export async function validateSurfaceCard(
surfaceCard: SurfaceCard,
signal?: AbortSignal
): Promise<{ ok: boolean; qa: Record<string, unknown>; schemaVersion: number }> {
const resp = await fetch(`${API_BASE}/solve/validate-card`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ surfaceCard }),
signal
});
return handleJson(resp);
}
export { API_BASE };