Add OPFS G-code staging and browser simulation checks

This commit is contained in:
2026-06-22 10:56:21 +08:00
parent 8321055934
commit 61e2fe8441
19 changed files with 1869 additions and 35 deletions

View File

@@ -324,7 +324,7 @@ function renderInfoTabs(element, state) {
<dt>Canonical:</dt><dd data-program-execution-summary="${state.programExecution?.summary?.motionEventCount ?? 0}">${state.programExecution?.summary?.motionEventCount ?? 0} motion / ${state.programExecution?.summary?.canonicalEventCount ?? 0} events</dd>
<dt>Switchkins:</dt><dd data-program-switchkins-summary="${state.programExecution?.summary?.switchkinsEventCount ?? 0}">${formatSwitchkinsSummary(state.programExecution)}</dd>
<dt>Machine run:</dt><dd data-machine-file-execution="status">${formatMachineFileExecution(state.machineFileExecution)}</dd>
<dt>Session:</dt><dd data-session-persistence="status">${state.sessionPersistence.status} / ${state.sessionPersistence.storageMode ?? "-"} / ${state.sessionPersistence.path ?? "-"}</dd>
<dt>Session:</dt><dd data-session-persistence="status">${formatSessionPersistence(state.sessionPersistence)}</dd>
<dt>Tool preview:</dt><dd data-tool-preview="detail">T${state.toolPreview.toolNumber} D${formatNumber(state.toolPreview.diameter, 2)} L${formatNumber(state.toolPreview.length, 3)} ${state.toolPreview.units}</dd>
<dt>Program time:</dt><dd data-program-timing="summary">${formatProgramTiming(state)}</dd>
<dt>Segment time:</dt><dd data-program-timing="segment">${formatProgramTimingSegment(state)}</dd>
@@ -348,6 +348,7 @@ function renderInfoTabs(element, state) {
<dt>Full boundary:</dt><dd data-full-execution-boundary="status">${formatFullExecutionBoundary(state.fullExecutionBoundary)}</dd>
<dt>Planner/task:</dt><dd data-full-execution-boundary="blockers">${formatFullExecutionBlockers(state.fullExecutionBoundary)}</dd>
<dt>Boundary evidence:</dt><dd data-full-execution-boundary="evidence">${formatFullExecutionEvidence(state.fullExecutionBoundary)}</dd>
<dt>Host/native:</dt><dd data-full-execution-boundary="host-native">${formatHostNativeBoundary(state.fullExecutionBoundary)}</dd>
<dt>LinuxCNC kins:</dt><dd data-rtcp-diagnostic="kinematics-ready">${frame.readiness.linuxCncKinematicsReady ? "ready" : "pending"}</dd>
<dt>Kins context:</dt><dd data-rtcp-diagnostic="execution-context">${state.kinematicsExecutionContext}</dd>
<dt>Interpreter:</dt><dd data-linuxcnc-boundary="interpreter">${state.interpreterRuntimeReadiness?.loaded ? state.interpreterRuntimeReadiness.semanticBoundary : "pending"}</dd>
@@ -427,7 +428,21 @@ function formatMachineFileStaging(machineFileStaging) {
if (machineFileStaging.status === "error") {
return `error ${machineFileStaging.lastError || "-"}`;
}
return `${machineFileStaging.status} ${machineFileStaging.fileCount || 0} files ${machineFileStaging.opfsRoot || "-"}`;
const storage = machineFileStaging.storageMode || machineFileStaging.save?.storageMode || "-";
const reason = machineFileStaging.storageCapability?.reason || machineFileStaging.save?.storageCapability?.reason || "-";
const gcodeFiles = machineFileStaging.save?.summary?.gcodeFileCount ?? 0;
return `${machineFileStaging.status} ${machineFileStaging.fileCount || 0} files ${gcodeFiles} gcode ${storage} ${reason} ${machineFileStaging.opfsRoot || "-"}`;
}
function formatSessionPersistence(sessionPersistence) {
const capability = sessionPersistence.storageCapability || {};
return [
sessionPersistence.status,
sessionPersistence.storageMode ?? "-",
capability.opfsUnavailable ? "opfs unavailable" : capability.opfsAvailable ? "opfs available" : "storage pending",
capability.reason || "-",
sessionPersistence.path ?? "-",
].join(" / ");
}
function formatMachineFileExecution(machineFileExecution) {
@@ -471,6 +486,16 @@ function formatFullExecutionEvidence(boundary) {
return `${boundary.satisfied.length} satisfied / ${boundary.missing.length} missing / ${boundary.semanticBoundary}`;
}
function formatHostNativeBoundary(boundary) {
if (!boundary) return "pending";
return [
boundary.hardwareDrive ? "hardware drive enabled" : "hardware drive false",
boundary.hostRealtimeKernel ? "host realtime enabled" : "host realtime false",
boundary.externalUserMProcessReady ? "external user-M ready" : "external user-M false",
boundary.toolDbProcessReady ? "tool DB ready" : "tool DB false",
].join(" / ");
}
function renderOverride(element, state, dispatch) {
element.innerHTML = `
<section class="meter-card">