import { createMachineSessionLoadSummary, machineSessionLoadLogLines, } from "./session-load-summary.js"; import { createSessionSnapshotSummary, sessionSnapshotSummaryLogLines, } from "./session-summary.js"; export function createSessionSnapshotFieldState(summary) { return { sessionIni: summary.iniOpfsPath, sessionParameters: summary.parameterOpfsPath, sessionToolTable: summary.toolTableOpfsPath, sessionGcode: summary.gcodeOpfsPath, sessionSnapshot: summary.snapshotLabel, }; } export function sessionSnapshotSaveLogLines(summary) { return [ ...sessionSnapshotSummaryLogLines(summary), `INI: ${summary.iniOpfsPath}`, `Parameter file: ${summary.parameterOpfsPath}`, `Tool table file: ${summary.toolTableOpfsPath}`, `G-code: ${summary.gcodeOpfsPath}`, ]; } export function sessionSnapshotRestoreLogLines(summary) { return [ ...sessionSnapshotSummaryLogLines(summary), `INI: ${summary.iniOpfsPath}`, `Parameter file: ${summary.parameterOpfsPath}`, `Tool table file: ${summary.toolTableOpfsPath}`, `G-code: ${summary.gcodeOpfsPath ?? "-"}`, ]; } export function createMachineSessionLoadFieldState(summary) { return { sessionIni: summary.iniWasmPath, sessionParameters: summary.parameterWasmPath, sessionToolTable: summary.toolTableWasmPath, }; } export function machineSessionLoadWorkflowLogLines(summary) { return [ "Loaded machine session into the interpreter WASM filesystem.", ...machineSessionLoadLogLines(summary), ]; } export function createMachineSessionReadinessFieldState(readiness) { return { sessionReadinessPhase: readiness.phase, sessionReadinessReady: readiness.ready ? "ready" : "blocked", sessionReadinessMissing: readiness.missing.length === 0 ? "none" : readiness.missing.join(", "), }; } export function machineSessionReadinessLogLines(readiness) { const checks = Array.isArray(readiness.checks) ? readiness.checks : []; return [ `Session readiness: ${readiness.ready ? "ready" : "blocked"}`, ...checks.map((check) => { const status = check.ok ? "ok" : `blocked (${check.error})`; return `${check.name}: ${check.path} -> ${status}`; }), ...(readiness.snapshotCheck ? [ `snapshot: ${readiness.snapshotCheck.path} -> ${ readiness.snapshotCheck.ok ? "ok" : `blocked (${readiness.snapshotCheck.error})` }`, ] : []), ]; } export async function readMachineSessionReadinessWorkflow({ readiness, readReadiness, } = {}) { const sessionReadiness = readiness ?? await readReadiness?.(); if (!sessionReadiness) { throw new Error("A machine session readiness reader is required."); } return { readiness: sessionReadiness, fields: createMachineSessionReadinessFieldState(sessionReadiness), logLines: machineSessionReadinessLogLines(sessionReadiness), }; } export async function loadMachineSessionIntoWasmWorkflow({ loadSession }) { if (typeof loadSession !== "function") { throw new Error("A machine session loader is required."); } const loadedSession = await loadSession(); const loadSummary = createMachineSessionLoadSummary(loadedSession); return { loadedSession, loadSummary, fields: createMachineSessionLoadFieldState(loadSummary), logLines: machineSessionLoadWorkflowLogLines(loadSummary), }; } export async function saveMachineSessionSnapshotWorkflow({ machineId, snapshotId, snapshotFilename, snapshotLabel, iniText, toolTableText, parameterText, gcodeFilename, gcodeText, metadata, saveMachineTextFiles, saveGcodeProgram, saveMachineSessionSnapshot, }) { await Promise.all([ saveMachineTextFiles(machineId, { ini: iniText, toolTable: toolTableText, parameters: parameterText, }), saveGcodeProgram(gcodeFilename, gcodeText), ]); const snapshot = await saveMachineSessionSnapshot( snapshotId, machineId, { filename: snapshotFilename, gcodeFilename, metadata, }, ); const summary = createSessionSnapshotSummary(snapshot, snapshotLabel); return { snapshot, summary, fields: createSessionSnapshotFieldState(summary), logLines: sessionSnapshotSaveLogLines(summary), }; } export async function restoreMachineSessionSnapshotWorkflow({ machineId, snapshotId, snapshotFilename, snapshotLabel, loadMachineSessionSnapshot, loadMachineTextFiles, readReadiness = null, loadSession = null, }) { const snapshot = await loadMachineSessionSnapshot( snapshotId, machineId, { filename: snapshotFilename }, ); const files = await loadMachineTextFiles(machineId); const summary = createSessionSnapshotSummary(snapshot, snapshotLabel ?? snapshotLabelFromSession(snapshot)); const fields = createSessionSnapshotFieldState(summary); const result = { snapshot, editorIniText: files.ini, summary, fields, readiness: null, loadSummary: null, loadedSession: null, logLines: sessionSnapshotRestoreLogLines(summary), }; if (readReadiness) { const readinessWorkflow = await readMachineSessionReadinessWorkflow({ readReadiness }); result.readiness = readinessWorkflow.readiness; result.fields = { ...result.fields, ...readinessWorkflow.fields, }; result.logLines = [ ...result.logLines, ...readinessWorkflow.logLines, ]; } if (loadSession) { const loadWorkflow = await loadMachineSessionIntoWasmWorkflow({ loadSession }); result.loadedSession = loadWorkflow.loadedSession; result.loadSummary = loadWorkflow.loadSummary; result.fields = { ...fields, ...(result.readiness ? createMachineSessionReadinessFieldState(result.readiness) : {}), ...loadWorkflow.fields, sessionGcode: summary.gcodeOpfsPath, }; result.logLines = [ ...sessionSnapshotSummaryLogLines(summary), ...(result.readiness ? machineSessionReadinessLogLines(result.readiness) : []), ...loadWorkflow.logLines, `G-code: ${summary.gcodeOpfsPath ?? "-"}`, ]; } return result; } function snapshotLabelFromSession(snapshot) { return snapshot?.metadata?.snapshotLabel ?? snapshot?.sessionId ?? null; }