47 lines
5.4 KiB
TypeScript
47 lines
5.4 KiB
TypeScript
import { FacadeHandlerError, FacadeRequest, FacadeResponse, FacadeSerialQueue, createRequest, isFacadeRequest } from "./facade-envelope.js";
|
|
|
|
export const BIM_PYTHON_FAMILY_SCHEMA = "freecad-web-bim/python-family/v1" as const;
|
|
export const BIM_PYTHON_FAMILY_COMMAND = "bim.pythonFamily" as const;
|
|
export const BIM_PYTHON_FAMILY_SOURCE_REVISION = "4f4e9244e613ea2df06e70027074a562695048cb" as const;
|
|
export const BIM_PYTHON_FAMILY_APIS = ["getStringList", "getDefaultColor", "is_type_or_link", "getAllChildren", "pruneIncluded", "get_architectural_contents", "check", "mergeCells", "survey", "toggleIfcBrepFlag", "makeCompoundFromSelected", "cleanArchSplitter", "getExtrusionData", "uncamel", "getCleanName", "getValueAndDirection", "BoundBoxValid", "isOriented", "update_svg_cache", "getSVG", "getHost", "getPropertyNames", "getVector", "getDocumentMaterials", "makeMaterial", "getMaterialContainer", "makeMultiMaterial", "makeGrid", "makeBuildingPart", "makeFloor", "makeBuilding", "make2DDrawing", "makeProject", "makeSite", "makePipe", "makeProfile", "getCutVolume", "closeHole", "makeFace", "projectToVector", "get_freecad_type", "get_ifc_type", "getParents", "getProfileCenterPoint", "face_from_points", "placeAlongEdge", "getUnit", "getUnsigned", "getPlacement", "getSqlKeywords", "getPropertyData", "getEdgesAngle", "getSqlApiDocumentation", "adjust_list_len", "getCameraData", "getLengthOfRebar", "find_inters", "getSectionData", "hex2rgb", "set_shininess", "percent_sh2fc", "cross_product"] as const;
|
|
export type BimPythonFamilyApi = typeof BIM_PYTHON_FAMILY_APIS[number];
|
|
|
|
export interface BimPythonFamilyPayload { schema: typeof BIM_PYTHON_FAMILY_SCHEMA; module: "BIM"; sourceRevision: string; apiId: `py:BIM:function:${BimPythonFamilyApi}`; name: BimPythonFamilyApi; }
|
|
export interface BimPythonFamilyResult { schema: typeof BIM_PYTHON_FAMILY_SCHEMA; module: "BIM"; action: "python-family"; sourceRevision: string; apiId: BimPythonFamilyPayload["apiId"]; name: BimPythonFamilyApi; result: string; count: number; source: "freecad-source"; nativeProbe: true; }
|
|
export type BimPythonFamilyRequest = FacadeRequest<BimPythonFamilyPayload>;
|
|
export type BimPythonFamilyResponse = FacadeResponse<BimPythonFamilyResult>;
|
|
export interface BimPythonFamilyKernel { ccall(name: string, returnType: "number" | "string", argTypes?: string[], args?: unknown[]): number | string }
|
|
|
|
function dispatchJson(kernel: BimPythonFamilyKernel, request: Record<string, unknown>): Record<string, unknown> {
|
|
const raw = String(kernel.ccall("fc_web_dispatch_json", "string", ["string"], [JSON.stringify(request)]));
|
|
let reply: unknown;
|
|
try { reply = JSON.parse(raw); } catch { throw new FacadeHandlerError("native_protocol_error", "BIM native dispatcher returned invalid JSON"); }
|
|
if (!reply || typeof reply !== "object") throw new FacadeHandlerError("native_protocol_error", "BIM native dispatcher returned a non-object result");
|
|
const result = reply as Record<string, unknown>;
|
|
if (result.ok !== true) throw new FacadeHandlerError(String(result.code || "native_error"), String(result.error || "BIM native dispatch failed"));
|
|
return result;
|
|
}
|
|
|
|
export function createBimPythonFamilyRequest(requestId: string, name: BimPythonFamilyApi, sourceRevision: string = BIM_PYTHON_FAMILY_SOURCE_REVISION): BimPythonFamilyRequest {
|
|
return createRequest(requestId, BIM_PYTHON_FAMILY_COMMAND, { schema: BIM_PYTHON_FAMILY_SCHEMA, module: "BIM", sourceRevision, apiId: `py:BIM:function:${name}`, name }, "bim-python-family");
|
|
}
|
|
|
|
export function isBimPythonFamilyRequest(value: unknown): value is BimPythonFamilyRequest {
|
|
if (!isFacadeRequest(value)) return false;
|
|
const p = (value as BimPythonFamilyRequest).payload;
|
|
return (value as BimPythonFamilyRequest).command === BIM_PYTHON_FAMILY_COMMAND && p?.schema === BIM_PYTHON_FAMILY_SCHEMA && p?.module === "BIM" && p?.sourceRevision === BIM_PYTHON_FAMILY_SOURCE_REVISION && BIM_PYTHON_FAMILY_APIS.includes(p?.name) && p?.apiId === `py:BIM:function:${p?.name}`;
|
|
}
|
|
|
|
export async function handleBimPythonFamily(payload: BimPythonFamilyPayload, signal: AbortSignal, source: BimPythonFamilyKernel | Promise<BimPythonFamilyKernel>): Promise<BimPythonFamilyResult> {
|
|
if (signal.aborted) throw new FacadeHandlerError("cancelled", "request was cancelled");
|
|
if (!isBimPythonFamilyRequest(createBimPythonFamilyRequest("validation", payload.name, payload.sourceRevision))) throw new FacadeHandlerError("invalid_api_id", "BIM Python family API identity is invalid", { apiId: payload.apiId });
|
|
const kernel = await source;
|
|
if (signal.aborted) throw new FacadeHandlerError("cancelled", "request was cancelled");
|
|
const native = dispatchJson(kernel, { cmd: BIM_PYTHON_FAMILY_COMMAND, args: { name: payload.name } });
|
|
const name = String(native.name) as BimPythonFamilyApi;
|
|
if (name !== payload.name) throw new FacadeHandlerError("native_result_mismatch", "BIM Python family returned a different API name", { expected: payload.name, actual: name });
|
|
return { schema: BIM_PYTHON_FAMILY_SCHEMA, module: "BIM", action: "python-family", sourceRevision: payload.sourceRevision, apiId: payload.apiId, name, result: String(native.result || ""), count: Number(native.count || 0), source: "freecad-source", nativeProbe: true };
|
|
}
|
|
|
|
export function dispatchBimPythonFamily(queue: FacadeSerialQueue, request: BimPythonFamilyRequest, source: BimPythonFamilyKernel | Promise<BimPythonFamilyKernel>): Promise<BimPythonFamilyResponse> { return queue.dispatch(request, (payload, signal) => handleBimPythonFamily(payload, signal, source)); }
|