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
87 lines
2.5 KiB
TypeScript
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 };
|