From 2c5c553e6dde32a459780e905caa1943895f3379 Mon Sep 17 00:00:00 2001 From: Ruslan Gilmullin Date: Tue, 2 Jun 2026 10:44:24 +0300 Subject: [PATCH] docs: catch up engine + visuals docs to v7.0.0-alpha.8 (#227 closure, TapeSnapshot home) Engine README: - Add TapeSnapshot type + tapeViewport helper to the Tape section - Versioning notes section catches up alpha.5/6/7/8 (was at alpha.4); v7 milestone marked feature-complete with #102 Engine CLAUDE.md: - visuals package bullet: TapeSnapshot listed as re-exported from engine (not native); version mentions updated to 7.0.0-alpha.8 Visuals README: - TapeSnapshot type def line annotated 're-exported from @turing-machine-js/machine (alpha.8+); canonical home is engine' --- CLAUDE.md | 2 +- packages/machine/README.md | 22 +++++++++++++++++++++- packages/visuals/README.md | 2 +- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 6099276..f0ea25f 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -22,7 +22,7 @@ This is an npm-workspaces + Lerna monorepo (`packages/*`). Versioning is **locks - **`@turing-machine-js/builder`** — declarative state-table → machine builder; depends on `machine`. Soft-deprecated; see its README. - **`@turing-machine-js/library-binary-numbers`** — prebuilt states for `^…$`-delimited binary arithmetic on a 5-symbol alphabet; depends on `machine`. - **`@turing-machine-js/library-binary-numbers-bare`** — same operations on a 3-symbol alphabet (no markers, single number per tape, much smaller state graphs); depends on `machine`. Side-by-side with the marker-based library to make the alphabet-vs-graph-size trade-off visible. -- **`@turing-machine-js/visuals`** (v7-only, [#204](https://github.com/mellonis/turing-machine-js/issues/204)) — pure highlight + graph-indexing logic for the engine `Graph`. Peer dep on `machine`, no runtime deps. Exposes `applyHighlight` / `applyIndicator` / `indexGraph` / `bareIdOf` / `highlightExpand` / `equivalentIds` / `recordingOps` (renderer-agnostic ops contract via `HighlightOps` / `IndicatorOps`), plus the `recordSnippet` artifact recorder (`Snippet` / `Frame` / `StepCommand` / `TapeSnapshot`) and the engine-edge-label formatter primitives (`formatStepNotation` / `tokenizeStep` / `formatTape`, the latter shipped in alpha.6.1). 16-rule contract for `applyHighlight` lives at `packages/visuals/docs/graph-highlight-and-breakpoints.md` (moved there from machines-demo). Used by machines-demo for graph highlight + step-log rendering; designed to be reusable by article embeds and any future Graph consumer that wants byte-identical edge-label notation to `toMermaid`. **Engine + libraries are at `7.0.0-alpha.6`; visuals at `7.0.0-alpha.6.1`** (visuals-only patch added formatter primitives + tokens). +- **`@turing-machine-js/visuals`** (v7-only, [#204](https://github.com/mellonis/turing-machine-js/issues/204)) — pure highlight + graph-indexing logic for the engine `Graph`. Peer dep on `machine`, no runtime deps. Exposes `applyHighlight` / `applyIndicator` / `indexGraph` / `bareIdOf` / `highlightExpand` / `equivalentIds` / `recordingOps` (renderer-agnostic ops contract via `HighlightOps` / `IndicatorOps`), the `recordSnippet` artifact recorder + `SnippetPlayer` class (`Snippet` / `Frame` / `StepCommand`), and the engine-edge-label formatter primitives (`formatStepNotation` / `tokenizeStep` / `formatTape`, shipped in alpha.6.1). **`TapeSnapshot` + `tapeViewport` are re-exported from `@turing-machine-js/machine`** ([#227](https://github.com/mellonis/turing-machine-js/issues/227), v7.0.0-alpha.8 onward) — they live next to the `Tape` class in the engine; visuals re-exports for consumer-import stability. 16-rule contract for `applyHighlight` lives at `packages/visuals/docs/graph-highlight-and-breakpoints.md` (moved there from machines-demo). Used by machines-demo for graph highlight + step-log rendering; designed to be reusable by article embeds and any future Graph consumer that wants byte-identical edge-label notation to `toMermaid`. **Engine + libraries are at `7.0.0-alpha.8`; visuals at `7.0.0-alpha.8`** (re-aligned to lockstep after alpha.7.1 visuals-only patch). ### Versioning convention diff --git a/packages/machine/README.md b/packages/machine/README.md index f0bd58d..f328f6e 100644 --- a/packages/machine/README.md +++ b/packages/machine/README.md @@ -191,6 +191,18 @@ tape.viewportWidth; // 7 (the constructor bumps even values to the next odd) `viewportWidth` defaults to `1` and must be ≥ 1; `tape.viewport` always has exactly `viewportWidth` cells regardless of how many symbols the tape actually holds. Useful for rendering a sliding window in a UI; ignore if you only need `tape.symbols` / `tape.position`. +For wire-data tape transmission (worker boundaries, snippet recording, snapshot tests), the package exports the **`TapeSnapshot`** type (`{ symbols: string[]; position: number }`) and a pure-function equivalent of `Tape.viewport`: + +```javascript +import { tapeViewport } from '@turing-machine-js/machine'; + +const snapshot = { symbols: ['a', 'b', 'c'], position: 1 }; +const { cells, headIndex } = tapeViewport(snapshot, 7, ' '); +// cells: [' ',' ','a','b','c',' ',' '], headIndex: 3 +``` + +`tapeViewport(snapshot, width, blank)` returns `{ cells, headIndex }` with `cells.length === width` (out-of-bounds positions padded with `blank`) and `headIndex === Math.floor(width / 2)`. Throws `RangeError` on non-positive or non-integer width. `Tape.viewport` and `tapeViewport` share an internal centering core, so the two routes produce identical results when given equivalent inputs. (`TapeSnapshot` + `tapeViewport` are also re-exported from `@turing-machine-js/visuals` for backwards-compatible imports from earlier alphas; canonical home is `@turing-machine-js/machine` as of v7.0.0-alpha.8, [#227](https://github.com/mellonis/turing-machine-js/issues/227).) + ### TapeBlock A bundle of one or more `Tape`s that the machine reads/writes together in lock-step. Construct via either factory: @@ -840,7 +852,15 @@ API surface changes since v3, in past tense so the timing of each piece is expli - **v6.2** *(superseded by v6.3.0)* — widened `onStep`'s signature to `(m) => void | Promise` and added an inline `await onStep(...)` in the run loop, enabling throttle-in-`onStep` patterns. This overturned the docstring-stated contract that `onStep` is sync (microtask-free); the right place for per-iter throttling is `onPause` with self-rearm (see [Throttle pattern](#throttle-pattern)). Restored in v6.3.0. - **v6.3** — `onStep` reverted to its v6.0–v6.1 sync contract — `(m) => void`, called synchronously inside the run loop. The Throttle pattern section documents the engine-native shape for per-iter throttle / "wait between iters" UIs. No other API changes. - **v6.4** — New **`onIter`** hook on `run()`: awaited, fires once at the end of every iter (after both `onPause` dispatches on the same yield), unaffected by the `debug` master switch. Use for per-iter throttle / animation / coordination needing a suspend point; complements the existing sync `onStep` (tracing) and conditional `onPause` (user breakpoints). Three-hook contract is now `onStep` (sync, mid-iter) / `onPause` (awaited, on `state.debug` match) / `onIter` (awaited, end-of-iter). Additive — peer-deps unchanged. The v6.3.0 README's `onPause`-rearm throttle workaround is superseded. -- **v7** *(latest alpha: alpha.4, 2026-05-23)* — Composition-representation overhaul + first-class state tags + id-keyed `State.collectStates` lookup. **Pre-release on the `next` dist-tag:** `npm install @turing-machine-js/machine@next` (or pin `@7.0.0-alpha.4`). Stable v7.0.0 still pending [#102](https://github.com/mellonis/turing-machine-js/issues/102) (debugger step-in/over/out primitives). Highlights across alphas: +- **v7** *(latest alpha: alpha.8, 2026-06-02)* — Composition-representation overhaul + first-class state tags + id-keyed `State.collectStates` lookup + `DebugSession` step controls + `CallFrame` + `tapeViewport`/`TapeSnapshot`. **Pre-release on the `next` dist-tag:** `npm install @turing-machine-js/machine@next` (or pin `@7.0.0-alpha.8`). **v7 milestone is feature-complete with #102**; the stable v7.0.0 cut is the only remaining step. Highlights across alphas: + + **alpha.8** — **`TapeSnapshot` type + `tapeViewport` helper** ([#227](https://github.com/mellonis/turing-machine-js/issues/227)) moved into the engine from `@turing-machine-js/visuals`, next to the live `Tape` class (visuals re-exports for consumer-import stability). `Tape.viewport` getter refactored to share its centering loop with `tapeViewport` via an internal core — the centering math now lives once; the two public surfaces supply their own data-shape-appropriate `cellAt` lambdas. See [§Tape](#tape). + + **alpha.7** — **`CallFrame` extraction** ([#213](https://github.com/mellonis/turing-machine-js/issues/213)) — `withOverriddenHaltState`'s wrapper is now a first-class `CallFrame extends State` subclass that delegates transition lookups + `debug` to its bare; `instanceof State` preserved (additive), `instanceof CallFrame` discriminates wrappers. Plus **`toMermaid` framed-wrapper emit fix** ([#223](https://github.com/mellonis/turing-machine-js/issues/223)) — `toGraph`'s reach-set now tunnels through wrappers AND captures the wrappers themselves, so framed-wrapper-continuations (e.g. `library-binary-numbers/minusOne`'s `goToNumberStart(invertNumberGoToNumberWithInversion)` inside `invertNumber`'s callable subtree) render inside the owner subgraph rather than escaping to the top level. `library-binary-numbers/states.md` regenerated under the new emit. + + **alpha.6** — **Debugger step controls** ([#102](https://github.com/mellonis/turing-machine-js/issues/102)) — full reshape of the debug surface. `run()` is now **sync + callback-free**; `runStepByStep` is the **pure-iteration primitive** (no `state.debug` filter evaluation); a new **`DebugSession`** class (`new DebugSession(machine, {initialState})`) owns all interactive debugging via `pause` / `step` / `iter` / `halt` events, depth-based `stepIn` / `stepOver` / `stepOut`, external `pause()` / `stop()` / `setRunInterval(ms)`. Per-yield `m.debugBreak: {before?, after?, cause}` **replaced by one-sided `m.pause: {side, cause}`** on `pause` events only. See [§Debugging](#debugging). + + **alpha.5** — Per-iter **`matchedTransition`** ([#205](https://github.com/mellonis/turing-machine-js/issues/205)) on every `MachineState` yield (`{id, matchKinds}`, `id` is `${stateId}.${ix}` resolvable in `toGraph`). **`haltState.debug` collapsed to a `boolean`** ([#207](https://github.com/mellonis/turing-machine-js/issues/207)) — object-shaped writes throw; halt pause fires on the AFTER side of the halt-triggering iter with `m.state` = the triggering state. `HaltState` typed alias narrows `debug` to `boolean` at the canonical access path. **alpha.4** — **`State.collectStates(initial, tapeBlock)`** ([#195](https://github.com/mellonis/turing-machine-js/issues/195)) returns a `Map` keyed by `GraphNode.id` so downstream tooling can mutate `state.debug` by numeric id and set per-pattern breakpoints by `GraphTransition.id`. Graph serialization extracted to `utilities/stateGraph.ts` with a Symbol-keyed `@internal` accessor on `State` ([#180](https://github.com/mellonis/turing-machine-js/issues/180); no public-API change — the `State.toGraph` / `.fromGraph` statics remain as thin delegates). Two upstream fixes: `toMermaid` HTML-entity-escapes user content in labels so alphabets containing `"`, `<`, etc. parse correctly ([#194](https://github.com/mellonis/turing-machine-js/issues/194)); `runStepByStep`'s halt stack is now run-scoped, fixing a memory leak / ghost-iteration when the same `TuringMachine` instance is reused across calls ([#196](https://github.com/mellonis/turing-machine-js/issues/196)). See [§Setting breakpoints by graph id](#setting-breakpoints-by-graph-id). diff --git a/packages/visuals/README.md b/packages/visuals/README.md index 286efcc..b20e776 100644 --- a/packages/visuals/README.md +++ b/packages/visuals/README.md @@ -49,7 +49,7 @@ type GraphHighlight = { type GraphIndexes = { /* node→frame, frame→wrappers, frame→label, etc. */ }; // Recording artifact -type TapeSnapshot = { symbols: string[]; position: number }; +type TapeSnapshot = { symbols: string[]; position: number }; // re-exported from @turing-machine-js/machine (alpha.8+); canonical home is the engine package, next to the Tape class type StepCommand = { movement: 'L' | 'R' | 'S'; symbol: string | null }; type Frame = { step: number;