89 lines
4.3 KiB
TypeScript
89 lines
4.3 KiB
TypeScript
import { FacadeHandlerError, FacadeRequest, FacadeResponse, FacadeSerialQueue, createRequest, isFacadeRequest } from "./facade-envelope.js";
|
|
import type { JtReaderKernelModule } from "./jtreader-facade.js";
|
|
|
|
export const JTREADER_PERSISTENCE_SCHEMA = "freecad-web-jtreader/save-reopen/v1" as const;
|
|
export const JTREADER_PERSISTENCE_COMMAND = "jtreader.saveReopen" as const;
|
|
export const JTREADER_PERSISTENCE_PATH = "/tmp/JtReaderKernel.FCStd" as const;
|
|
|
|
export interface JtReaderPersistencePayload {
|
|
schema: typeof JTREADER_PERSISTENCE_SCHEMA;
|
|
module: "JtReader";
|
|
action: "save/reopen";
|
|
path: string;
|
|
}
|
|
|
|
export interface JtReaderPersistenceResult {
|
|
schema: typeof JTREADER_PERSISTENCE_SCHEMA;
|
|
module: "JtReader";
|
|
action: "save/reopen";
|
|
format: ".fcstd";
|
|
path: typeof JTREADER_PERSISTENCE_PATH;
|
|
size: number;
|
|
objectCount: 1;
|
|
objectType: "App::InventorObject";
|
|
roundTrip: true;
|
|
resourcesReleased: true;
|
|
}
|
|
|
|
export type JtReaderPersistenceRequest = FacadeRequest<JtReaderPersistencePayload>;
|
|
export type JtReaderPersistenceResponse = FacadeResponse<JtReaderPersistenceResult>;
|
|
|
|
export const JTREADER_PERSISTENCE_FIXTURE: JtReaderPersistencePayload = {
|
|
schema: JTREADER_PERSISTENCE_SCHEMA,
|
|
module: "JtReader",
|
|
action: "save/reopen",
|
|
path: JTREADER_PERSISTENCE_PATH,
|
|
};
|
|
|
|
export function createJtReaderPersistenceRequest(requestId: string, payload: JtReaderPersistencePayload = JTREADER_PERSISTENCE_FIXTURE): JtReaderPersistenceRequest {
|
|
return createRequest(requestId, JTREADER_PERSISTENCE_COMMAND, payload, "jtreader-persistence-doc");
|
|
}
|
|
|
|
export function isJtReaderPersistenceRequest(value: unknown): value is JtReaderPersistenceRequest {
|
|
if (!isFacadeRequest(value)) return false;
|
|
const request = value as JtReaderPersistenceRequest;
|
|
const payload = request.payload;
|
|
return request.command === JTREADER_PERSISTENCE_COMMAND
|
|
&& payload?.schema === JTREADER_PERSISTENCE_SCHEMA
|
|
&& payload?.module === "JtReader"
|
|
&& payload?.action === "save/reopen"
|
|
&& typeof payload?.path === "string";
|
|
}
|
|
|
|
const kernelString = (kernel: JtReaderKernelModule, name: string) => kernel.ccall(name, "string") as string;
|
|
const kernelNumber = (kernel: JtReaderKernelModule, name: string) => kernel.ccall(name, "number") as number;
|
|
|
|
export async function handleJtReaderPersistence(payload: JtReaderPersistencePayload, signal: AbortSignal, kernelSource: JtReaderKernelModule | Promise<JtReaderKernelModule>): Promise<JtReaderPersistenceResult> {
|
|
if (signal.aborted) throw new FacadeHandlerError("cancelled", "request was cancelled");
|
|
if (!isJtReaderPersistenceRequest(createJtReaderPersistenceRequest("validation", payload)) || payload.schema !== JTREADER_PERSISTENCE_SCHEMA || payload.module !== "JtReader" || payload.action !== "save/reopen") {
|
|
throw new FacadeHandlerError("invalid_fixture", "JtReader persistence fixture is invalid", { field: "action" });
|
|
}
|
|
if (payload.path !== JTREADER_PERSISTENCE_PATH) {
|
|
throw new FacadeHandlerError("invalid_path", "JtReader FCStd path is not writable", { path: payload.path });
|
|
}
|
|
const kernel = await kernelSource;
|
|
if (signal.aborted) throw new FacadeHandlerError("cancelled", "request was cancelled");
|
|
if (kernelNumber(kernel, "fc_web_jtreader_save_reopen") !== 1) {
|
|
throw new FacadeHandlerError(
|
|
kernelString(kernel, "fc_web_jtreader_error_code") || "save_reopen_failed",
|
|
kernelString(kernel, "fc_web_jtreader_error_message") || "JtReader FCStd save/reopen failed",
|
|
);
|
|
}
|
|
return {
|
|
schema: JTREADER_PERSISTENCE_SCHEMA,
|
|
module: "JtReader",
|
|
action: "save/reopen",
|
|
format: ".fcstd",
|
|
path: kernelString(kernel, "fc_web_jtreader_persistence_path") as typeof JTREADER_PERSISTENCE_PATH,
|
|
size: kernelNumber(kernel, "fc_web_jtreader_persistence_size"),
|
|
objectCount: kernelNumber(kernel, "fc_web_jtreader_persistence_object_count") as 1,
|
|
objectType: kernelString(kernel, "fc_web_jtreader_persistence_object_type") as "App::InventorObject",
|
|
roundTrip: true,
|
|
resourcesReleased: true,
|
|
};
|
|
}
|
|
|
|
export function dispatchJtReaderPersistence(queue: FacadeSerialQueue, request: JtReaderPersistenceRequest, kernelSource: JtReaderKernelModule | Promise<JtReaderKernelModule>): Promise<JtReaderPersistenceResponse> {
|
|
return queue.dispatch(request, (payload, signal) => handleJtReaderPersistence(payload, signal, kernelSource));
|
|
}
|