Files
cnc_wams/wasm-port/runtime/sdk/README.md

14 KiB

LinuxCNC WASM SDK

This SDK exposes browser/Node JavaScript wrappers for standalone WASM modules built from vendored LinuxCNC source.

Boundary

The SDK is a host-boundary layer only. It may:

  • load generated Emscripten modules;
  • allocate and free C strings;
  • write text files into the Emscripten filesystem;
  • call exported C ABI functions;
  • return LinuxCNC-produced text output to JavaScript callers.

The SDK must not implement G-code interpretation, canonical motion behavior, tool semantics, parameter semantics, kinematics, or planner behavior. Those behaviors must continue to come from vendored LinuxCNC source through the C ABI.

Entrypoints

Use src/index.js for stable imports:

import {
  INI_PANEL_ENTRIES,
  analyzeIniRuntimeBoundaries,
  createControlPageBrowserApiManifest,
  createControlPageBrowserApiMethods,
  createControlPageBrowserApiSchema,
  createIniPanelLaunchApiManifest,
  createIniPanelLauncherLinkViewModel,
  createIniPanelShellApiSurfaceInventory,
  createIniPanelShellControlPageContract,
  createIniPanelShellIntegrationManifest,
  createIniPanelShellIntegrationReadiness,
  createIniPanelShellIntegrationSchema,
  createIniPanelShellIntegrationWorkflowPlan,
  createIniPanelShellSessionReadinessWorkflowReport,
  createIniPanelShellViewModel,
  createIniPanelShellWorkflowOverviewContract,
  createIniPanelShellWorkflowOverviewEmbeddingMountDomContract,
  createIniPanelShellWorkflowOverviewEmbeddingMountDomReadiness,
  createIniPanelShellWorkflowOverviewReleaseReadinessArtifactDisplayViewModel,
  createIniPanelShellWorkflowOverviewReleaseReadinessArtifactDomContract,
  createIniPanelShellWorkflowOverviewReleaseReadinessArtifactDomReadiness,
  createIniPanelShellWorkflowOverviewReleaseReadinessArtifactRenderState,
  createLinuxCncIniSdk,
  createLinuxCncInterpSdk,
  createMachineSessionPersistenceDisplayViewModel,
  createMachineSessionPersistenceRenderState,
  createMachineSessionPersistenceSummary,
  createMachineSessionSnapshotPayload,
  createProjectReleaseReadinessArtifactValidation,
  createProjectReleaseReadinessReport,
  createSessionSnapshot,
  defaultMachinePaths,
  gcodeFilenameFromProgramPath,
  gcodeProgramPath,
  getIniPanelEntryByHref,
  getIniPanelEntryManifest,
  getOpfsRoot,
  getVisibleIniPanelEntries,
  isSupportedIniPanelControlPageApiManifest,
  isSupportedIniPanelLaunchApiManifest,
  isSupportedIniPanelShellIntegrationManifest,
  loadMachineSessionFromOpfs,
  loadMachineSessionSnapshot,
  loadMachineTextFiles,
  loadMachineToolTableFromOpfs,
  loadTextFile,
  machineFilePaths,
  machineIniPath,
  mountIniPanelShellWorkflowOverviewEmbeddingMountState,
  mountIniPanelShellWorkflowOverviewReleaseReadinessArtifactState,
  normalizeOpfsPath,
  parameterFilePath,
  parseProjectReleaseReadinessArtifactJson,
  planIniFileContextStaging,
  planSimConfigStaging,
  readMachineSessionReadiness,
  renderIniPanelShellWorkflowOverviewEmbeddingMountState,
  renderIniPanelShellWorkflowOverviewReleaseReadinessArtifactState,
  restoreMachineParametersFromOpfs,
  saveMachineSessionSnapshot,
  saveMachineTextFiles,
  saveSessionSnapshot,
  saveTextFile,
  sessionSnapshotPath,
  toolTablePath,
  validateIniPanelShellWorkflowOverviewReleaseReadinessArtifactJson,
  validateSessionSnapshot,
} from "./src/index.js";

createLinuxCncIniSdk() wraps the INI parser module built from vendored LinuxCNC inifile.cc and exposes getString() plus getBool(). Boolean conversion is performed by vendored LinuxCNC iniFindBool().

createLinuxCncInterpSdk() wraps the interpreter-core module built from vendored LinuxCNC RS274NGC sources and exposes:

  • runProgram(programText)
  • runProgramWithIni(programText, iniPath)
  • runFile(path)
  • runFileWithIni(path, iniPath)
  • runFileWithIniContinueOnError(path, iniPath)
  • runSimConfigProgram({ iniPath, programPath, files, executionMode })
  • runFiveAxisRemapFile(path, iniPath)
  • runRemapFile(path, iniPath)
  • runRemapIoMdiSequence(iniPath)
  • restoreParameters(path)
  • saveParameters(path, values)
  • loadToolTable(path, options)
  • saveToolTable(path)
  • writeTextFile(path, text)
  • readTextFile(path)

loadToolTable() accepts { randomToolChanger: true } to select the LinuxCNC random-toolchanger branch before calling vendored tooldata_load(). The SDK only forwards that runtime boundary flag.

runFiveAxisRemapFile() is a narrow host boundary for vendored LinuxCNC sample-machine remap validation. Callers provide INI/remap/demo files in the WASM filesystem; the C ABI runs vendored LinuxCNC REMAP, O-word, file execution, and HAL adapter paths.

runRemapFile() is the generic remap-test equivalent for vendored LinuxCNC tests such as tests/remap/duplicate-o-word. It reads LinuxCNC INI SUBROUTINE_PATH and REMAP entries, then calls vendored LinuxCNC Interp::parse_remap(), open(), read(), and execute().

runRemapIoMdiSequence() is a narrow regression boundary for the NGC-only branch of vendored LinuxCNC tests/remap/remap-io/test-ngc.ini. The C ABI reads LinuxCNC REMAP entries, then feeds the upstream test driver's MDI command sequence into vendored Interp::execute(). JavaScript only copies the vendored INI/subroutine files into the WASM filesystem and forwards the INI path; it does not implement M62-M68, M66 input, or remap semantics.

runFileWithIni() is the plain interpreter-file equivalent for upstream tests that need LinuxCNC INI search paths, such as tests/interp/sub-call-from-sub. The C ABI reads LinuxCNC SUBROUTINE_PATH and then calls vendored Interp::open(), read(), and execute(); the SDK only copies files and forwards paths.

runSimConfigProgram() is a convenience host boundary for representative LinuxCNC configs/sim programs. Callers provide { path, text, executable } file entries, an INI path, and a program path. The SDK writes those text files into the Emscripten filesystem, applies executable bits for user M-code files, then forwards to runFileWithIni() by default or to runFiveAxisRemapFile() when executionMode: "fiveAxisRemap" is explicitly requested.

planIniFileContextStaging() is the generic file-staging planner for LinuxCNC INI-driven interpreter runs. Callers provide vendored source-manifest text, a source root, an INI file name, INI text, and a target WASM directory. The planner reads only INI file references and the manifest, then returns the INI, [DISPLAY]OPEN_FILE, [EMCIO]TOOL_TABLE, [RS274NGC]PARAMETER_FILE, [RS274NGC]SUBROUTINE_PATH, [RS274NGC]USER_M_PATH, and remap-NGC files that should be copied into the Emscripten filesystem. Each planned file includes sourceRel, wasmPath, the legacy alias path, and executable. It does not implement G-code, tool, parameter, remap, or user-M semantics.

planSimConfigStaging() is the companion convenience wrapper for representative LinuxCNC configs/sim programs. Callers provide the vendored source manifest text, machine relative path, INI file name, and INI text. It uses planIniFileContextStaging() with a configs/sim/<machine> source root and configs/sim upward-search boundary.

analyzeIniRuntimeBoundaries() is a host-boundary classifier for LinuxCNC INI-driven runs. It reads INI text plus optional execution text and manifest text, then reports declared HAL, UI, HALUI MDI, Python, tool-database, and external user-M process dependencies. User-M accounting is per execution code: executionCodes lists M100..M199 codes seen in the supplied execution text, while unstagedExecutionCodes lists the subset not backed by vendored USER_M_PATH files. Python accounting keeps UI/DB references separate from Python remap runtime references, so a UI handler or DB program does not imply Python-remap coverage. It also returns the currently recommended Layer 4 blocked kind for hard process boundaries such as L4-TOOL-DB and L4-USER-M-PROCESS. The classifier is policy/accounting only: it does not execute HAL, task, UI, Python, user-M, or tool-database behavior and does not change interpreter semantics.

runFileWithIniContinueOnError() uses the same LinuxCNC-backed file execution path but keeps the runner loop going after LinuxCNC reports an error, matching upstream rs274 -n 0 regression tests such as tests/interp/oword-unwind. It does not implement or reinterpret LinuxCNC error semantics.

Project release readiness export

createProjectReleaseReadinessReport() returns a machine-readable release readiness report for CI dashboards and external SDK callers. The report lists the required project release gate command, expected smoke outputs, the current sim-config inventory baseline, and blocked runtime families. It is evidence driven: the default report is ready: false until the caller supplies observed gate output such as project_release_gate=ok or explicit gate results.

This helper does not execute shell commands and does not inspect or implement CNC behavior. It only packages project-level release evidence and blocked runtime policy that are already documented in docs/project-release-handoff.md and ../PROJECT_COMPLETION_TRACKER.md.

The executable release gate uses the same helper to write build/project-release-readiness.json after all project checks pass, then validates that artifact with tests/host/verify_project_release_readiness_artifact.sh. External tools can load that JSON with parseProjectReleaseReadinessArtifactJson() and validate it with createProjectReleaseReadinessArtifactValidation() without copying the host test assertions.

OPFS/session persistence exports

The SDK entrypoint re-exports the OPFS/session persistence helpers used by the browser panel so external callers can stage the same files without importing private module paths:

  • getOpfsRoot(), saveTextFile(), and loadTextFile() for browser OPFS text persistence.
  • machineIniPath(), toolTablePath(), parameterFilePath(), gcodeProgramPath(), sessionSnapshotPath(), defaultMachinePaths(), and normalizeOpfsPath() for stable OPFS path construction.
  • createMachineSessionSnapshotPayload(), createSessionSnapshot(), saveSessionSnapshot(), saveMachineSessionSnapshot(), loadMachineSessionSnapshot(), and validateSessionSnapshot() for session snapshot persistence.
  • machineFilePaths(), saveMachineTextFiles(), loadMachineTextFiles(), and gcodeFilenameFromProgramPath() for machine-file and G-code file helpers.
  • readMachineSessionReadiness() for checking persisted INI, parameter, tool-table, optional G-code, and optional session snapshot files before loading a session.
  • restoreMachineParametersFromOpfs(), loadMachineToolTableFromOpfs(), and loadMachineSessionFromOpfs() for loading OPFS machine state into the LinuxCNC-backed interpreter SDK.

These helpers only move and validate host files. Parameter and tool-table effects still come from the LinuxCNC-backed interpreter SDK methods they call.

INI panel shell handoff exports

The SDK entrypoint also re-exports the stable INI panel shell handoff surface for external browser shells:

  • INI_PANEL_ENTRIES, getIniPanelEntryManifest(), getIniPanelEntryByHref(), getVisibleIniPanelEntries(), and createIniPanelLauncherLinkViewModel() for discovering launch pages and rendering shell-owned launcher links from the stable entry manifest.
  • createIniPanelLaunchApiManifest() and isSupportedIniPanelLaunchApiManifest() for launch API negotiation.
  • createControlPageBrowserApiSchema(), createControlPageBrowserApiManifest(), createControlPageBrowserApiMethods(), createIniPanelShellControlPageContract(), and isSupportedIniPanelControlPageApiManifest() for read-only control-page API negotiation.
  • createIniPanelShellIntegrationSchema(), createIniPanelShellIntegrationManifest(), createIniPanelShellIntegrationReadiness(), createIniPanelShellIntegrationWorkflowPlan(), and isSupportedIniPanelShellIntegrationManifest() for checking launch and control-page compatibility before embedding.
  • createIniPanelShellViewModel() for a complete read-only shell integration bundle.
  • createMachineSessionPersistenceSummary() for a machine-readable OPFS/session persistence summary covering machine files, session snapshot, session readiness, session load, readonly status, and shell handoff readiness rows. createMachineSessionPersistenceDisplayViewModel() and createMachineSessionPersistenceRenderState() turn the summary into stable display and render data. createIniPanelShellSessionHandoffWorkflowSummary() can include this as the read-only persistence-summary row.
  • createIniPanelShellWorkflowOverviewContract() for discovering the workflow overview iframe API contract.
  • validateIniPanelShellWorkflowOverviewReleaseReadinessArtifactJson() for the read-only workflow overview artifact validation wrapper exposed by workflow-overview.html. Use createIniPanelShellWorkflowOverviewReleaseReadinessArtifactDisplayViewModel(), createIniPanelShellWorkflowOverviewReleaseReadinessArtifactRenderState(), createIniPanelShellWorkflowOverviewReleaseReadinessArtifactDomContract(), createIniPanelShellWorkflowOverviewReleaseReadinessArtifactDomReadiness(), renderIniPanelShellWorkflowOverviewReleaseReadinessArtifactState(), and mountIniPanelShellWorkflowOverviewReleaseReadinessArtifactState() when an outer shell needs to render that validation into caller-owned DOM.
  • createIniPanelShellApiSurfaceInventory() for a machine-readable inventory of launch, control-page, workflow overview, persistence, and session readiness report API counts, including persistence summary row counts. createIniPanelShellViewModel() also includes this inventory as a read-only workflow summary row so browser overview pages and external shells can display API coverage without private imports.
  • createIniPanelShellSessionReadinessWorkflowReport() for a machine-readable session readiness workflow report with phase, missing reasons, status line, and stable rows.
  • createIniPanelShellWorkflowOverviewEmbeddingMountDomContract() and createIniPanelShellWorkflowOverviewEmbeddingMountDomReadiness() for workflow overview embedding mount DOM checks.
  • renderIniPanelShellWorkflowOverviewEmbeddingMountState() for rendering a mount render-state into caller-owned DOM.
  • mountIniPanelShellWorkflowOverviewEmbeddingMountState() for a non-throwing workflow overview embedding mount wrapper that returns structured blocked results when DOM nodes are missing.

The workflow overview embedding helpers are UI/runtime boundary helpers only. They render status and rows already produced by the shell view-model; they do not parse G-code, execute action plans, or implement CNC semantics.