-
Гильмуллин Руслан Ниязович создал
Full rewrite of the demo's main thread from vanilla JS classes-with-DOM to Svelte 5 components (runes mode), with a typed worker contract. Driven by an internal code-quality audit that flagged a 380-line god function, dual sources of truth for button-disabled state, drift between worker request/response shapes, and a silent mobile belt-width bug. Structural changes: - Typed worker contract via discriminated unions (lib/types.ts). Single canonical Command shape — symbol === null means "keep" everywhere — replacing the dual KEEP-Symbol vs null impedance mismatch. - MachineTab.svelte orchestrates per-engine state. executionMode is $state and every UI flag (panel/apply/take-control visibility, button-disabled) is a $derived line. The old applyMode switch and per-handler reset dance are gone. - One <MachineTab engine={...}> instantiated per active tab; switching tabs unmounts/remounts (via {#key activeEngine}) which cleanly tears down the worker, timers, and CodeMirror instance. - Editor lazy-loaded as a separate Vite chunk (~540 KB / 180 KB gz) so initial paint ships ~24 KB gz instead of ~200 KB gz; tape + control panel are visible immediately while CodeMirror loads in parallel. - Lezer-based syntax preflight in the editor (markers before Load) plus boost-99 priority for machine-namespace identifiers in autocomplete. - popstate listener so browser back/forward updates the active tab. - Mobile belt width fixed: CSS owns geometry, JS only owns indexing counts. Three responsive tiers (≤480px / ≤768px / desktop) replace the single phone-tuned breakpoint. - Surface tokens (--surface-*, --editor-bg) consolidate the duplicated panel-recipe CSS and align the log panel with CodeMirror's oneDark surface. - Favicon repainted as a head cell (yellow doubled border + ▲ glyph below). Tooling: TypeScript (strict), ESLint flat config (typescript-eslint + eslint-plugin-svelte), svelte-check, Vite 5 + @sveltejs/vite-plugin-svelte 4, svelte-codemirror-editor for the editor wrapper. Prettier and Vitest are deferred — tests can land in a follow-up. Multi-tape Turing display is tracked as https://github.com/mellonis/machines-demo/issues/1; the worker now asserts single-tape explicitly rather than silently dropping tapes ≥ 1. Note: workerLive isn't reset on the worker-timeout path. Currently masked because halted=true dominates the disabled-state gates; worth re-checking if those gates ever loosen.ea31182e