import { createFailure, createSuccess, type FacadeResponse } from "./facade-envelope.js"; import type { WebModuleRouter } from "./module-router.js"; import { viewEndpoint, type ViewOwner } from "./part-view-facade.js"; export type WindowPanel = { objectName: string; title: string; visible: boolean; enabled?: boolean }; export type WindowLayout = { windows: Array<{ documentId: string; label: string }>; columns: number; rows: number; activeDocument: string | null; }; export type WindowHostResult = Partial & { command: string; documentId: string; items?: WindowPanel[]; locked?: boolean; }; type Host = { snapshot(): { panels: WindowPanel[]; toolbar: string }; apply(value: WindowHostResult, owner: ViewOwner): void; }; let host: Host | undefined; export function registerWebWindowHost(value: Host) { host = value; return () => { if (host === value) host = undefined; }; } export function executeWebWindowHost(router: WebModuleRouter, command: string, args: Record, documentId: string): Promise | undefined { if (!["Std_DockViewMenu", "Std_TileWindows", "Std_ToggleToolBarLock"].includes(command)) return; const mounted = host; if (!mounted) return Promise.resolve(createFailure("desktop-Web", "window_host_unavailable", "The workbench window host is not mounted")); const owner = args.runtimeOwner ?? "PartBox"; if (owner !== "PartBox" && owner !== "DocumentProbe") return Promise.resolve(createFailure("desktop-Web", "wrong_document_owner", "Select the document's native runtime")); if (!documentId.trim() || (args.documentId !== undefined && args.documentId !== documentId)) return Promise.resolve(createFailure("desktop-Web", "document_mismatch", "Command document identifiers differ")); return router.request("Part", viewEndpoint(owner), { schema: "freecad-web/document-view/v1", owner, document: documentId, command, parameters: { ...args, documentId, host: mounted.snapshot() }, }, documentId).then(response => { if (response.kind !== "result") return response; const value = response.result as WindowHostResult; if (!value || value.command !== command || value.documentId !== documentId) return createFailure(response.requestId, "native_protocol_error", "Window response identity mismatch"); if (command === "Std_DockViewMenu" && (!Array.isArray(value.items) || value.items.some(item => !item || typeof item.objectName !== "string" || typeof item.title !== "string" || typeof item.visible !== "boolean" || typeof item.enabled !== "boolean"))) return createFailure(response.requestId, "native_protocol_error", "Invalid native dock actions"); if (command === "Std_ToggleToolBarLock" && typeof value.locked !== "boolean") return createFailure(response.requestId, "native_protocol_error", "Invalid native toolbar lock state"); if (command === "Std_TileWindows" && (!Array.isArray(value.windows) || !value.windows.length || value.windows.some(item => !item || typeof item.documentId !== "string" || !item.documentId || typeof item.label !== "string") || !Number.isInteger(value.columns) || (value.columns ?? 0) < 1 || !Number.isInteger(value.rows) || (value.rows ?? 0) < 1 || !(value.activeDocument === null || typeof value.activeDocument === "string"))) return createFailure(response.requestId, "native_protocol_error", "Invalid native window layout"); if (host !== mounted) return createFailure(response.requestId, "window_host_unavailable", "The workbench window host changed during the command"); mounted.apply(value, owner); return createSuccess(response.requestId, { schema: "freecad-web/document-view-batch/v1", owner, documentId, records: [{ apiId: `Web:desktop:${command}`, name: command, status: "success", native: true, result: value }], count: 1, }); }); }