machines-demo
Interactive in-browser playground for Turing and Post machines.
Live demo: demo.machines.mellonis.ru
Two tabs (Turing, Post) where you write JavaScript that builds a machine — using the published @turing-machine-js/machine and @post-machine-js/machine libraries — and watch it execute on an animated tape. Auto-running demo on first load, manual control of the tape head via a movement/symbol/Apply panel, single-step and paused-auto-step execution, and a log of every command applied.
Running locally
npm install
npm run dev
The dev server prints a URL; open it in a browser.
Scripts
npm run dev # Vite dev server
npm run build # type-check + production build into dist/
npm run preview # preview the built bundle
npm run check # svelte-check + tsc (no emit)
npm run lint # ESLint flat config
Static bundle emitted to dist/. Serve with any static host. The build references hashed assets, so far-future caching is safe.
Tech
- Vite + Svelte 5 (runes mode) + TypeScript
-
CodeMirror 6 via
svelte-codemirror-editor; Lezer-based syntax preflight before Load -
Tabler Icons (SVG
?rawimports) - User code runs inside a Web Worker — terminate-on-timeout sandbox, with
'unsafe-eval'only at the worker level so the worker is the actual security boundary -
@turing-machine-js/machineand@post-machine-js/machine(peer-dependency relationship preserved)
Layout
src/
├── App.svelte # header + tab nav + popstate routing
├── app.ts # entry; mounts <App>
├── app.css # global tokens + base styles
├── components/
│ ├── MachineView.svelte # per-engine orchestrator (one $state, derived disabled flags)
│ ├── Tape.svelte # virtualized belt with prep-shift slide trick
│ ├── ControlPanel.svelte # L/S/R + alphabet chips + Apply
│ ├── Editor.svelte # CodeMirror wrapper + localStorage persist
│ ├── Log.svelte # entries list (desktop) / latest line (mobile)
│ └── IconButton.svelte # icon + optional label
└── lib/
├── types.ts # Engine, Command, WorkerRequest/Response, ...
├── runner.ts # main-thread worker wrapper, 5s timeout
├── worker.ts # spawns user code via new Function inside worker
├── demoLoop.ts # idle-mode random-command loop
├── autoStep.ts # paused-auto-step controller
├── completions.ts # CodeMirror autocomplete from machine namespace
├── syntaxLinter.ts # Lezer-based syntax-error markers
├── persist.ts # localStorage helpers per engine
├── defaultCode.ts # starter Turing / Post snippets
├── format.ts # describeCommand / formatTape / formatAlphabet
└── icons.ts # Tabler icon namespace