export function createIniPanelStateSummary({ badges = {}, machine = null, machineFiles = null, sessionSnapshot = null, sessionReadiness = null, sessionLoad = null, runReadiness = null, run = null, fiveaxisRemap = null, } = {}) { return { badges: { ini: badges.ini ?? null, interp: badges.interp ?? null, opfs: badges.opfs ?? null, }, machine, machineFiles, sessionSnapshot, sessionReadiness, sessionLoad, runReadiness, run, fiveaxisRemap: fiveaxisRemap ?? null, }; } export function createMachineSessionStateSnapshot({ badges = {}, machine = null, machineFiles = null, sessionSnapshot = null, sessionReadiness = null, sessionLoad = null, runReadiness = null, selectedProgram = null, run = null, fields = {}, lastAction = null, error = null, fiveaxisRemap = null, } = {}) { return { ...createIniPanelStateSummary({ badges, machine, machineFiles, sessionSnapshot, sessionReadiness, sessionLoad, runReadiness, run, fiveaxisRemap, }), selectedProgram, fields: { sessionIni: fields.sessionIni ?? null, sessionParameters: fields.sessionParameters ?? null, sessionToolTable: fields.sessionToolTable ?? null, sessionGcode: fields.sessionGcode ?? null, sessionSnapshot: fields.sessionSnapshot ?? null, runStatus: fields.runStatus ?? null, runSource: fields.runSource ?? null, runSnapshot: fields.runSnapshot ?? null, runWorkflow: fields.runWorkflow ?? null, runOpfsPath: fields.runOpfsPath ?? null, runWasmPath: fields.runWasmPath ?? null, }, lastAction: lastAction ?? null, error: error ?? null, }; } export function createMachineSessionStateReport(state = {}) { const badges = state.badges ?? {}; const fields = state.fields ?? {}; const sessionSnapshot = state.sessionSnapshot ?? {}; const sessionReadiness = state.sessionReadiness ?? null; const sessionLoad = state.sessionLoad ?? {}; const runReadiness = state.runReadiness ?? {}; const selectedProgram = state.selectedProgram ?? {}; const run = state.run ?? {}; return { readiness: { ini: badges.ini ?? null, interp: badges.interp ?? null, opfs: badges.opfs ?? null, }, session: { snapshotLabel: sessionSnapshot.snapshotLabel ?? fields.sessionSnapshot ?? null, workflow: sessionSnapshot.workflow ?? fields.runWorkflow ?? null, ini: fields.sessionIni ?? sessionSnapshot.iniOpfsPath ?? sessionLoad.iniWasmPath ?? null, parameters: fields.sessionParameters ?? sessionSnapshot.parameterOpfsPath ?? sessionLoad.parameterWasmPath ?? null, toolTable: fields.sessionToolTable ?? sessionSnapshot.toolTableOpfsPath ?? sessionLoad.toolTableWasmPath ?? null, gcode: fields.sessionGcode ?? sessionSnapshot.gcodeOpfsPath ?? null, }, sessionReadiness, loaded: { iniWasmPath: sessionLoad.iniWasmPath ?? null, parameterWasmPath: sessionLoad.parameterWasmPath ?? null, toolTableWasmPath: sessionLoad.toolTableWasmPath ?? null, }, program: { source: selectedProgram.source ?? run.programSource ?? fields.runSource ?? null, opfsPath: selectedProgram.opfsPath ?? run.programOpfsPath ?? fields.runOpfsPath ?? null, wasmPath: selectedProgram.wasmPath ?? run.programWasmPath ?? fields.runWasmPath ?? null, }, runReadiness: { phase: runReadiness.phase ?? null, canRun: Boolean(runReadiness.canRun), missing: Array.isArray(runReadiness.missing) ? runReadiness.missing : [], buttonEnabled: Boolean(runReadiness.runButton?.enabled), buttonReason: runReadiness.runButton?.reason ?? null, programSource: runReadiness.program?.source ?? null, programOpfsPath: runReadiness.program?.opfsPath ?? null, programWasmPath: runReadiness.program?.wasmPath ?? null, iniWasmPath: runReadiness.loadedSession?.iniWasmPath ?? null, }, run: { status: run.runStatus ?? fields.runStatus ?? null, canonicalEventCount: run.canonicalEventCount ?? 0, motionSnapshotCount: run.motionSnapshotCount ?? 0, iniWasmPath: run.iniWasmPath ?? null, }, status: { lastAction: state.lastAction ?? null, error: state.error ?? null, fiveaxisRemap: state.fiveaxisRemap ?? null, }, }; } export function createMachineSessionStateReportExport(state = {}, options = {}) { const report = createMachineSessionStateReport(state); return { filename: options.filename ?? "machine-session-state-report.json", mediaType: "application/json", report, text: `${JSON.stringify(report, null, 2)}\n`, }; } export function createMachineSessionWorkflowStatus(state = {}) { const report = createMachineSessionStateReport(state); const overview = createMachineSessionWorkflowOverview(report); return { readiness: report.readiness, overview, sessionReadiness: report.sessionReadiness ?? null, runReadiness: report.runReadiness, lastAction: report.status.lastAction, error: report.status.error, session: report.session, run: report.run, }; } export function createMachineSessionPersistenceSummary({ state = {}, report = createMachineSessionStateReport(state), workflowStatus = createMachineSessionWorkflowStatus(state), readonlyStatus = null, handoffSummary = null, handoffWorkflowSummary = null, } = {}) { const readiness = report.readiness ?? {}; const machineFiles = state.machineFiles ?? {}; const session = report.session ?? {}; const loaded = report.loaded ?? {}; const sessionReadiness = report.sessionReadiness ?? workflowStatus.sessionReadiness ?? null; const opfsReady = String(readiness.opfs ?? "").toLowerCase().includes("ready"); const machineFileLabels = [ machineFiles.iniOpfsPath || session.ini ? "ini" : null, machineFiles.parameterOpfsPath || session.parameters ? "parameters" : null, machineFiles.toolTableOpfsPath || session.toolTable ? "tool-table" : null, machineFiles.gcodeOpfsPath || session.gcode ? "g-code" : null, ].filter(Boolean); const machineFilesReady = machineFileLabels.length > 0; const snapshotReady = Boolean(session.snapshotLabel); const sessionReadinessReady = sessionReadiness?.ready === true; const sessionLoadReady = Boolean(loaded.iniWasmPath); const readonlyStatusValue = readonlyStatus ? (readonlyStatus.ready === true ? "ready" : readonlyStatus.phase ?? "available") : "not-provided"; const handoffValue = handoffWorkflowSummary ? (handoffWorkflowSummary.ready === true ? "ready" : handoffWorkflowSummary.phase ?? "blocked") : ( handoffSummary ? (handoffSummary.ready === true ? "ready" : handoffSummary.phase ?? "blocked") : "not-provided" ); const checks = { opfs: opfsReady, machineFiles: machineFilesReady, sessionSnapshot: snapshotReady, sessionReadiness: sessionReadinessReady, sessionLoad: sessionLoadReady, }; const missing = Object.entries(checks) .filter(([, passed]) => !passed) .map(([name]) => name); const ready = missing.length === 0; return { apiName: "machine-session-persistence-summary", summaryVersion: 1, phase: ready ? "ready" : "waiting", ready, checks, missing, counts: { machineFiles: machineFileLabels.length, missing: missing.length, }, rows: [ { id: "opfs", label: "OPFS", value: readiness.opfs ?? "missing", }, { id: "machine-files", label: "Machine files", value: machineFileLabels.length > 0 ? machineFileLabels.join(", ") : "missing", }, { id: "session-snapshot", label: "Session snapshot", value: session.snapshotLabel ?? "missing", }, { id: "session-readiness", label: "Session readiness", value: sessionReadiness ? (sessionReadiness.ready ? "ready" : `blocked: ${sessionReadiness.missing?.join(", ") || "unknown"}`) : "missing", }, { id: "session-load", label: "Session load", value: loaded.iniWasmPath ? `loaded: ${loaded.iniWasmPath}` : "missing", }, { id: "readonly-status", label: "Readonly status", value: readonlyStatusValue, }, { id: "handoff-readiness", label: "Handoff readiness", value: handoffValue, }, ], }; } export function createMachineSessionPersistenceDisplayViewModel( summary = createMachineSessionPersistenceSummary(), ) { const missing = Array.isArray(summary?.missing) ? summary.missing : []; const rows = Array.isArray(summary?.rows) ? summary.rows.map(({ id, label, value }) => ({ id, label, value: value == null ? "" : String(value), })) : []; return { phase: summary?.phase === "ready" ? "ready" : "waiting", title: "OPFS/session persistence", statusText: summary?.ready ? "Ready" : "Waiting", detailText: missing.length > 0 ? missing.join(", ") : "No missing persistence requirements", rows, }; } export function createMachineSessionPersistenceRenderState( displayViewModel = createMachineSessionPersistenceDisplayViewModel(), ) { const rows = Array.isArray(displayViewModel?.rows) ? displayViewModel.rows.map(({ id, label, value }) => ({ id, label, value: value == null ? "" : String(value), })) : []; const ready = displayViewModel?.phase === "ready" && displayViewModel?.statusText === "Ready"; const statusText = displayViewModel?.statusText ?? (ready ? "Ready" : "Waiting"); const detailText = displayViewModel?.detailText ?? "No missing persistence requirements"; return { apiName: "machine-session-persistence-render-state", renderStateVersion: 1, phase: ready ? "ready" : "waiting", ready, title: displayViewModel?.title ?? "OPFS/session persistence", statusText, detailText, statusLine: `${statusText}: ${detailText}`, rows, dataset: { persistencePhase: ready ? "ready" : "waiting", persistenceReady: ready ? "true" : "false", persistenceScope: "opfs-session", }, }; } export function createMachineSessionWorkflowOverview(report = {}) { const readiness = report.readiness ?? {}; const loaded = report.loaded ?? {}; const session = report.session ?? {}; const runReadiness = report.runReadiness ?? {}; const run = report.run ?? {}; const status = report.status ?? {}; const loadedIniWasmPath = loaded.iniWasmPath ?? runReadiness.iniWasmPath ?? null; const missing = []; if (!loadedIniWasmPath) { missing.push("loaded-session"); } if (!session.snapshotLabel) { missing.push("session-snapshot"); } if (!runReadiness.canRun) { missing.push("run-readiness"); } return { phase: run.status ? "ran" : (missing.length === 0 ? "ready" : "waiting"), missing, readiness, session: { snapshotLabel: session.snapshotLabel ?? null, workflow: session.workflow ?? null, ini: session.ini ?? null, gcode: session.gcode ?? null, }, loaded, runReadiness, run: { status: run.status ?? null, canonicalEventCount: run.canonicalEventCount ?? 0, motionSnapshotCount: run.motionSnapshotCount ?? 0, iniWasmPath: run.iniWasmPath ?? null, }, status: { lastAction: status.lastAction ?? null, error: status.error ?? null, }, }; } export function createMachineSessionStateBundle(state = {}, options = {}) { const report = createMachineSessionStateReport(state); const exportPayload = createMachineSessionStateReportExport(state, options); const workflowStatus = createMachineSessionWorkflowStatus(state); const overview = createMachineSessionWorkflowOverview(report); return { report, overview, export: exportPayload, workflowStatus, }; } export function createMachineSessionControlView(bundle = {}) { const report = bundle.report ?? {}; const workflowStatus = bundle.workflowStatus ?? {}; const overview = bundle.overview ?? workflowStatus.overview ?? {}; const session = workflowStatus.session ?? report.session ?? {}; const runReadiness = workflowStatus.runReadiness ?? report.runReadiness ?? {}; const run = workflowStatus.run ?? report.run ?? {}; return { status: { lastAction: workflowStatus.lastAction ?? report.status?.lastAction ?? null, error: workflowStatus.error ?? report.status?.error ?? null, runStatus: run.status ?? null, }, sections: [ { id: "readiness", title: "Readiness", rows: [ { label: "INI", value: workflowStatus.readiness?.ini ?? report.readiness?.ini ?? null }, { label: "Interpreter", value: workflowStatus.readiness?.interp ?? report.readiness?.interp ?? null }, { label: "OPFS", value: workflowStatus.readiness?.opfs ?? report.readiness?.opfs ?? null }, ], }, { id: "session", title: "Session", rows: [ { label: "Snapshot", value: session.snapshotLabel ?? null }, { label: "Workflow", value: session.workflow ?? null }, { label: "INI", value: session.ini ?? null }, { label: "G-code", value: session.gcode ?? null }, ], }, { id: "workflow", title: "Workflow", rows: [ { label: "Phase", value: overview.phase ?? null }, { label: "Missing", value: overview.missing?.join(", ") || null }, { label: "Last action", value: overview.status?.lastAction ?? null }, { label: "Error", value: overview.status?.error ?? null }, ], }, { id: "run", title: "Run", rows: [ { label: "Ready", value: runReadiness.phase ?? null }, { label: "Button", value: runReadiness.buttonEnabled ? "enabled" : "disabled" }, { label: "Status", value: run.status ?? null }, { label: "Canonical events", value: run.canonicalEventCount ?? 0 }, { label: "Motion snapshots", value: run.motionSnapshotCount ?? 0 }, { label: "INI WASM", value: run.iniWasmPath ?? null }, ], }, ], }; }