Complete XYZAC LinuxCNC WASM parity and smooth 3D preview

This commit is contained in:
2026-08-28 06:24:50 +08:00
parent e8fe323aab
commit 1a7995fa9b
181 changed files with 36854 additions and 215 deletions

View File

@@ -1,6 +1,6 @@
import { AXIS_COMMANDS, axisGate } from "./axis-contract.mjs";
import { AXIS_COMMANDS, XYZAC_GATE_ACTIONS, axisGate, xyzacGate } from "./axis-contract.mjs";
export const COMMAND_ACTIONS = Object.freeze(Object.fromEntries(Object.entries(AXIS_COMMANDS).map(([action, command]) => [command, action])));
export const COMMAND_ACTIONS = Object.freeze({ ...Object.fromEntries(Object.entries(AXIS_COMMANDS).map(([action, command]) => [command, action])), VISUAL_CLEAR: "vismachClear" });
export class AxisGateError extends Error {
constructor(result) {
@@ -26,17 +26,18 @@ export class AxisOperationController {
async execute(kind, payload = {}, { state = {}, action = COMMAND_ACTIONS[kind] ?? null, gate = true } = {}) {
const operationId = this.nextOperationId(kind);
const gateResult = action ? axisGate(action, state) : { action: null, enabled: true, reason: "axis_unrestricted_internal_command" };
const gateResult = action ? (XYZAC_GATE_ACTIONS.includes(action) ? xyzacGate(action, state) : axisGate(action, state)) : { action: null, enabled: true, reason: "axis_unrestricted_internal_command" };
const authoritativeGate = action && state?.gates?.[action];
if (gate && !gateResult.enabled && !authoritativeGate) {
this.trace.push(Object.freeze({ operation_id: operationId, kind, action, phase: "blocked", reason: gateResult.reason }));
throw new AxisGateError(gateResult);
const effectiveGate = authoritativeGate ?? gateResult;
if (gate && !effectiveGate.enabled) {
this.trace.push(Object.freeze({ operation_id: operationId, kind, action, phase: "blocked", reason: effectiveGate.reason }));
throw new AxisGateError(effectiveGate);
}
this.trace.push(Object.freeze({ operation_id: operationId, kind, action, phase: "pending", reason: gateResult.reason }));
this.trace.push(Object.freeze({ operation_id: operationId, kind, action, phase: "pending", reason: effectiveGate.reason }));
try {
const response = await this.client.send(kind, payload, operationId);
this.trace.push(Object.freeze({ operation_id: operationId, kind, action, phase: "result", response_kind: response?.kind ?? null }));
return Object.freeze({ operationId, response, gate: gateResult });
return Object.freeze({ operationId, response, gate: effectiveGate });
} catch (error) {
this.trace.push(Object.freeze({ operation_id: operationId, kind, action, phase: "error", reason: error?.message ?? String(error) }));
throw error;