diff --git a/README.md b/README.md index eda2e6e..506cc53 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ This repository contains the following packages: * [@turing-machine-js/library-binary-numbers](https://github.com/mellonis/turing-machine-js/tree/master/packages/library-binary-numbers) — binary arithmetic on a 5-symbol alphabet (` ^$01`) supporting multiple numbers per tape, with `plusOne`, `minusOne`, `minusOneFast`, `invertNumber`, `normalizeNumber`, and inter-number navigation. * [@turing-machine-js/library-binary-numbers-bare](https://github.com/mellonis/turing-machine-js/tree/master/packages/library-binary-numbers-bare) — the same arithmetic on a 3-symbol alphabet (` 01`), single-number-per-tape. Side-by-side with the marker-based library to make the alphabet-size vs state-graph-size trade-off visible. * [@turing-machine-js/builder](https://github.com/mellonis/turing-machine-js/tree/master/packages/builder) — declarative state-table construction. Not actively developed; the same pattern is shown inline in `@turing-machine-js/machine`'s README. -* [@turing-machine-js/visuals](https://github.com/mellonis/turing-machine-js/tree/v7/packages/visuals) (v7+, prerelease) — pure highlight + graph-indexing logic for the engine `Graph`: `applyHighlight` / `applyIndicator` against a renderer-agnostic `HighlightOps` interface, `bareIdOf` / `highlightExpand` for wrapper/bare canonicalization, `formatStepNotation` / `tokenizeStep` / `formatTape` for engine-edge-label rendering (byte-identical to `toMermaid`), `recordSnippet` for prerecorded-playback artifacts. No DOM, no Svelte, no Mermaid — consumers bring their own renderer. +* [@turing-machine-js/visuals](https://github.com/mellonis/turing-machine-js/tree/master/packages/visuals) (v7+) — pure highlight + graph-indexing logic for the engine `Graph`: `applyHighlight` / `applyIndicator` against a renderer-agnostic `HighlightOps` interface, `bareIdOf` / `highlightExpand` for wrapper/bare canonicalization, `formatStepNotation` / `tokenizeStep` / `formatTape` for engine-edge-label rendering (byte-identical to `toMermaid`), `recordSnippet` for prerecorded-playback artifacts. No DOM, no Svelte, no Mermaid — consumers bring their own renderer. # An example diff --git a/lerna.json b/lerna.json index a123db3..e9b371b 100644 --- a/lerna.json +++ b/lerna.json @@ -3,6 +3,6 @@ "packages": [ "packages/*" ], - "version": "7.0.0-alpha.8", + "version": "7.0.0", "$schema": "node_modules/lerna/schemas/lerna-schema.json" } \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index db25187..21e0729 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10393,40 +10393,40 @@ }, "packages/builder": { "name": "@turing-machine-js/builder", - "version": "7.0.0-alpha.8", + "version": "7.0.0", "license": "GPL-3.0-or-later", "engines": { "npm": ">=7.0.0" }, "peerDependencies": { - "@turing-machine-js/machine": "^7.0.0-alpha.8" + "@turing-machine-js/machine": "^7.0.0" } }, "packages/library-binary-numbers": { "name": "@turing-machine-js/library-binary-numbers", - "version": "7.0.0-alpha.8", + "version": "7.0.0", "license": "GPL-3.0-or-later", "engines": { "npm": ">=7.0.0" }, "peerDependencies": { - "@turing-machine-js/machine": "^7.0.0-alpha.8" + "@turing-machine-js/machine": "^7.0.0" } }, "packages/library-binary-numbers-bare": { "name": "@turing-machine-js/library-binary-numbers-bare", - "version": "7.0.0-alpha.8", + "version": "7.0.0", "license": "GPL-3.0-or-later", "engines": { "npm": ">=7.0.0" }, "peerDependencies": { - "@turing-machine-js/machine": "^7.0.0-alpha.8" + "@turing-machine-js/machine": "^7.0.0" } }, "packages/machine": { "name": "@turing-machine-js/machine", - "version": "7.0.0-alpha.8", + "version": "7.0.0", "license": "GPL-3.0-or-later", "engines": { "npm": ">=7.0.0" @@ -10434,13 +10434,13 @@ }, "packages/visuals": { "name": "@turing-machine-js/visuals", - "version": "7.0.0-alpha.8", + "version": "7.0.0", "license": "GPL-3.0-or-later", "engines": { "npm": ">=7.0.0" }, "peerDependencies": { - "@turing-machine-js/machine": "^7.0.0-alpha.8" + "@turing-machine-js/machine": "^7.0.0" } } } diff --git a/packages/builder/CHANGELOG.md b/packages/builder/CHANGELOG.md index 5cd086a..5055de6 100644 --- a/packages/builder/CHANGELOG.md +++ b/packages/builder/CHANGELOG.md @@ -4,6 +4,14 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [7.0.0] - 2026-06-03 + +Stable v7. Lockstep release with `@turing-machine-js/machine` 7.0.0. See the machine package CHANGELOG for the cumulative v7 trajectory. + +### Changed + +- Peer dep `@turing-machine-js/machine` widened `^7.0.0-alpha.8` → `^7.0.0`. + ## [7.0.0-alpha.8] - 2026-06-02 Released in lockstep with `@turing-machine-js/machine` 7.0.0-alpha.8 — lifts `TapeSnapshot` + `tapeViewport` from `@turing-machine-js/visuals` into the engine ([#227](https://github.com/mellonis/turing-machine-js/issues/227)). No source or behavior changes in this package. Peer dep `@turing-machine-js/machine` widened `^7.0.0-alpha.7` → `^7.0.0-alpha.8`. diff --git a/packages/builder/package.json b/packages/builder/package.json index 1a8bd77..f92bf6c 100644 --- a/packages/builder/package.json +++ b/packages/builder/package.json @@ -1,6 +1,6 @@ { "name": "@turing-machine-js/builder", - "version": "7.0.0-alpha.8", + "version": "7.0.0", "description": "A turing machine builder — declarative state-table construction. Not actively developed by the author; the same state-table pattern is also shown as an inline example in @turing-machine-js/machine's README. Contributions welcome.", "engines": { "npm": ">=7.0.0" @@ -25,7 +25,7 @@ "builder" ], "peerDependencies": { - "@turing-machine-js/machine": "^7.0.0-alpha.8" + "@turing-machine-js/machine": "^7.0.0" }, "scripts": { "build": "tsc --build --verbose tsconfig.build.json && node ../../scripts/build-node-entries.mjs --package=@turing-machine-js/builder", diff --git a/packages/library-binary-numbers-bare/CHANGELOG.md b/packages/library-binary-numbers-bare/CHANGELOG.md index 9daa243..7cb2a5b 100644 --- a/packages/library-binary-numbers-bare/CHANGELOG.md +++ b/packages/library-binary-numbers-bare/CHANGELOG.md @@ -4,6 +4,14 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [7.0.0] - 2026-06-03 + +Stable v7. Lockstep release with `@turing-machine-js/machine` 7.0.0. See the machine package CHANGELOG for the cumulative v7 trajectory. + +### Changed + +- Peer dep `@turing-machine-js/machine` widened `^7.0.0-alpha.8` → `^7.0.0`. + ## [7.0.0-alpha.8] - 2026-06-02 Released in lockstep with `@turing-machine-js/machine` 7.0.0-alpha.8 — lifts `TapeSnapshot` + `tapeViewport` from `@turing-machine-js/visuals` into the engine ([#227](https://github.com/mellonis/turing-machine-js/issues/227)). No source or behavior changes in this package. Peer dep `@turing-machine-js/machine` widened `^7.0.0-alpha.7` → `^7.0.0-alpha.8`. diff --git a/packages/library-binary-numbers-bare/package.json b/packages/library-binary-numbers-bare/package.json index f579b9c..6a70b47 100644 --- a/packages/library-binary-numbers-bare/package.json +++ b/packages/library-binary-numbers-bare/package.json @@ -1,6 +1,6 @@ { "name": "@turing-machine-js/library-binary-numbers-bare", - "version": "7.0.0-alpha.8", + "version": "7.0.0", "description": "Single-number binary arithmetic on a 3-symbol alphabet (blank, 0, 1) — same operations as @turing-machine-js/library-binary-numbers but without ^/$ markers. Side-by-side with the marker-based library for learning the trade-off.", "engines": { "npm": ">=7.0.0" @@ -28,7 +28,7 @@ "teaching" ], "peerDependencies": { - "@turing-machine-js/machine": "^7.0.0-alpha.8" + "@turing-machine-js/machine": "^7.0.0" }, "scripts": { "build": "tsc --build --verbose tsconfig.build.json && node ../../scripts/build-node-entries.mjs --package=@turing-machine-js/library-binary-numbers-bare", diff --git a/packages/library-binary-numbers/CHANGELOG.md b/packages/library-binary-numbers/CHANGELOG.md index 926499d..98c8c74 100644 --- a/packages/library-binary-numbers/CHANGELOG.md +++ b/packages/library-binary-numbers/CHANGELOG.md @@ -4,6 +4,14 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [7.0.0] - 2026-06-03 + +Stable v7. Lockstep release with `@turing-machine-js/machine` 7.0.0. See the machine package CHANGELOG for the cumulative v7 trajectory. + +### Changed + +- Peer dep `@turing-machine-js/machine` widened `^7.0.0-alpha.8` → `^7.0.0`. + ## [7.0.0-alpha.8] - 2026-06-02 Released in lockstep with `@turing-machine-js/machine` 7.0.0-alpha.8 — lifts `TapeSnapshot` + `tapeViewport` from `@turing-machine-js/visuals` into the engine ([#227](https://github.com/mellonis/turing-machine-js/issues/227)). No source or behavior changes in this package. Peer dep `@turing-machine-js/machine` widened `^7.0.0-alpha.7` → `^7.0.0-alpha.8`. diff --git a/packages/library-binary-numbers/package.json b/packages/library-binary-numbers/package.json index a3960c3..bcb8fb7 100644 --- a/packages/library-binary-numbers/package.json +++ b/packages/library-binary-numbers/package.json @@ -1,6 +1,6 @@ { "name": "@turing-machine-js/library-binary-numbers", - "version": "7.0.0-alpha.8", + "version": "7.0.0", "description": "A standard library for working with binary numbers", "engines": { "npm": ">=7.0.0" @@ -27,7 +27,7 @@ "numbers" ], "peerDependencies": { - "@turing-machine-js/machine": "^7.0.0-alpha.8" + "@turing-machine-js/machine": "^7.0.0" }, "scripts": { "build": "tsc --build --verbose tsconfig.build.json && node ../../scripts/build-node-entries.mjs --package=@turing-machine-js/library-binary-numbers", diff --git a/packages/machine/CHANGELOG.md b/packages/machine/CHANGELOG.md index 42fb271..1e951ae 100644 --- a/packages/machine/CHANGELOG.md +++ b/packages/machine/CHANGELOG.md @@ -4,6 +4,87 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [7.0.0] - 2026-06-03 + +Stable v7. The composition-representation overhaul. See alpha.1 through alpha.8 entries below for the detailed step-by-step trajectory; this entry summarizes the cumulative API changes from v6.4.0. + +### Added + +- **`DebugSession`** — `new DebugSession(machine, { initialState })`. The sole interactive-debugging surface (there is no `debugRun()` factory on `TuringMachine`). Emits `pause` / `step` / `iter` / `halt` events via `session.on(event, listener)`; `iter` listeners are awaited (the per-iter throttle / coordination point), `pause` / `step` / `halt` are fire-and-forget. Drive controls: `continue()`, `stepIn()`, `stepOver()`, `stepOut()`, external `pause()`, `stop()`, and `setRunInterval(ms)` for a per-iter throttle. Breakpoint detection (`state.debug` filters, `haltState.debug`) lives entirely here. Concurrent sessions on one machine are rejected (the underlying `TapeBlock` lock is single-active-run). Depth-based step controls mirror Chrome DevTools: `stepIn` = next iter at any depth; `stepOver` = next iter at `depth ≤ click-time depth`; `stepOut` = next iter at `depth < click-time depth` (throws at depth 0). +- **`CallFrame extends State`** — `withOverriddenHaltState`'s wrapper is now a first-class `State` subclass instead of an instance aliasing the bare's private `#symbolToDataMap` / `#debugRef`. Transition lookups and `debug` access delegate to the bare. `instanceof State` is preserved; `instanceof CallFrame` is the wrapper discriminator. Exported additively from the package root. +- **`TapeSnapshot` type + `tapeViewport` helper** — the per-tape wire-data shape `{ symbols: string[]; position: number }` and a pure helper providing a fixed-width centered window over it. Live next to the `Tape` class; `@turing-machine-js/visuals` re-exports both for consumer-import stability. +- **First-class State tags** — `state.tag(...) / .untag(...) / .tags` for attaching string metadata. Out-of-band — no effect on transition lookup, `equivalentOn`, or runtime semantics. Live on the State instance, so memoized wrappers don't leak tags across sharers of a bare. `GraphNode.tags: string[]` survives `toGraph` / `fromGraph` round-trip; `toMermaid` emits tags inline (`
`) AND as `classDef` + `class` color-group lines. +- **`withOverriddenHaltState` memoization** — calls with the same `(bare, override)` pair return the literally-same `State` instance. Backed by a `WeakMap` keyed by the bare with `WeakRef`-valued entries. +- **`MachineState.matchedTransition`** — every yielded `MachineState` carries `{ id: string, matchKinds: ('wildcard' | 'literal')[] }`. `id` is `${stateId}.${transitionIx}` and resolves directly in `toGraph` output. `matchKinds` is per-tape; `'wildcard'` iff the winning alternative held `ifOtherSymbol` at that position. Eliminates `(source, nextState)` resolution ambiguity for exact-edge highlighting and per-transition coverage maps. +- **`State.getMatchedTransition(symbol)`** — returns `{ nextState, matchedSymbol, ix }`, exposing the index used by `matchedTransition.id`. +- **`State.collectStates(initialState, tapeBlock)`** — returns `Map` keyed by engine `GraphNode.id`. The K-th `transitionSymbols` slot is positionally aligned with the GraphTransition whose id is `${stateId}.${K}`. `StateMap` and `StateMapEntry` types exported. +- **`TapeBlock.patternKinds(symbol, currentSymbols?)`** — per-tape `'wildcard' | 'literal'` for the matched alternative's selector. +- **`HaltState` typed alias** — narrows `haltState.debug` to `boolean` at the canonical access path. +- **`@turing-machine-js/visuals` companion package** — pure highlight + graph-indexing logic for the engine `Graph` (peer dep on `machine`, no runtime deps). Includes `applyHighlight` / `applyIndicator` / `indexGraph` / `bareIdOf` / `highlightExpand` / `equivalentIds` / `recordingOps`, the engine-edge-label formatter primitives (`formatStepNotation` / `tokenizeStep` / `formatTape`), the snippet-recording surface (`recordSnippet` + `SnippetPlayer`), and a 16-rule contract doc. + +### Changed + +- **`State.prototype.withOverrodeHaltState` renamed to `withOverriddenHaltState`** — grammar fix. Hard cutover, no deprecated alias. Renames in lockstep: public method, `state.overriddenHaltState` getter, the `#overriddenHaltState` private field, and the serialized `Graph` field `node.overriddenHaltStateId`. +- **Wrapped-state composite name format flipped from `bare>override` to `bare(override)`** — paren-nested keeps structurally-distinct wrap-trees distinct (`A.with(B.with(A))` is `A(B(A))`; `A.with(B).with(A)` is `A(B)(A)`). As a consequence, **user-provided state names must not contain `(` or `)`** (the constructor throws). `>` is no longer reserved. +- **`run()` is synchronous and callback-free** — signature is `run({ initialState, stepsLimit? }): void` (was `async … : Promise` with `onPause` / `onStep` / `onIter` callbacks). All callback machinery has moved to `DebugSession`. **Breaking** for callers awaiting `run()` or passing callbacks. +- **`runStepByStep` is the minimal pure-iteration primitive** — advances the machine and yields a plain `MachineState`. Evaluates no `state.debug` filters and stamps no pause field. Breakpoint detection moved to `DebugSession`. **Breaking** for consumers that read a pause / breakpoint field off raw yields. +- **`haltState.debug` is a `boolean`** — was `DebugConfig` with per-side `{ before?, after? }`. `haltState.debug = true` enables (pauses on every halt entry); `false` / `null` disables. Object-shaped writes throw. The pause fires on the AFTER side of the iter whose transition leads to halt — `m.state` is the triggering state. **Breaking** — pre-v7 consumers using `haltState.debug = { before: true }` / `{ after: true }` must switch to `haltState.debug = true`. ⚠️ Chained-form `haltState.debug.before = true` silently no-ops in non-strict mode (primitive-property assignment). Use the whole-object form. +- **`toMermaid` callable-subtree emit** — wrapper and bare are separate graph nodes. Wrapper sits OUTSIDE any subgraph as `[[composite-name]]` (call site). Bare lives INSIDE its callable subtree subgraph as a regular `[name]` node. Subgraph label is `"callable subtree of NAME"` (single bare) or `"callable scope: A ∪ B"` (multi-bare union frame computed via union-find on bare-reachability). Halt marker is per-frame. Arrow vocabulary: solid `-->` for regular transitions AND wrapper's post-return `--> override`; bold `==> "call"` is RESERVED for wrapper-to-bare (`&` ribbon collapses multiple wrappers sharing a bare); dotted `-.->` is reserved for frame-level dispatch (`w_N -. "return" .-> wrapper`, `w_N -. "halt" .-> s0`, `idle -. enter .-> sN`). `GraphNode` field changes: `isWrapper: boolean`, `bareStateId: number | null`, `frameId: number | null`; `overriddenHaltStateId` lives on wrapper nodes only. Bytewise round-trip stability holds for all wrapped states, including shared-bare cases. +- **`toMermaid` framed-wrapper emit fix** — `toGraph`'s reach-set now pushes the wrapper itself AND tunnels through `overriddenHaltStateId`, so framed-wrapper-continuations join the caller's frame instead of emitting at the top level. +- **`toMermaid` user-content escape** — alphabet symbols, state names, tag names, and frame bare names are HTML-entity-escaped at the leaf (`&`, `"`, `<`, `>` to named entities; statement terminators, C0 controls, DEL, bidi controls, lone surrogates to numeric entities). `fromMermaid` mirrors with a single-pass entity decoder. Fixes parse errors on alphabets containing literal `"`, `<`, `>`, etc. +- **Edge-label vocabulary rewritten** — `[reads] → [writes]/[moves]`, each role wrapped in `[…]` (tape-block indicator; always present, even single-tape). Read cells: `'X'` literal-quoted, `*` (ifOtherSymbol catch-all), `B` (tape's blank). Write cells: literal-quoted, `K` (keep), `E` (erase). Move cells: `L` / `R` / `S`. Alternation per-pattern bracket (`['^']|['1']`, never compact in-bracket form). +- **`GraphTransition.id` separator: `-` → `.`** — was `${stateId}-${patternIx}`, now `${stateId}.${patternIx}`. Aligns with `matchedTransition.id` and makes the id splittable without colliding with user-defined state names containing `-`. +- **Nested `.wohs()` chain collapse** — `A.wohs(t1).wohs(t2)` is equivalent to `A.wohs(t2)` (the inner override is dead at runtime). Composite name now reflects runtime behavior: `A(t2)`, not the misleading `A(t1)(t2)`. +- **`runStepByStep` halt-stack is run-scoped, not machine-scoped** — fixes a "ghost iteration" / memory leak on consecutive `runStepByStep` calls when the previous generator wasn't drained to halt. +- **Graph serialization extracted to `utilities/stateGraph.ts`** — `State.toGraph` / `State.fromGraph` / `State.collectStates` live in a sibling module. Public surface preserved via thin static delegates. +- **`Tape.viewport` getter shares its centering loop with `tapeViewport`** via an internal `tapeViewportFromAccess` core — the centering math lives once. +- **`summarize().stateCount` filters `isHaltMarker` nodes** — halt markers are visualization sentinels (all map back to singleton `haltState` at runtime). + +### Removed + +- **`MachineState.debugBreak`** — the per-yield `{ before?, after?, cause }` descriptor from the v4–v6 debugger. Replaced by the one-sided `m.pause: { side: 'before' | 'after', cause: 'breakpoint' | 'step' | 'manual' }` carried ONLY on a `DebugSession` `pause` event (`PausedMachineState`); raw `runStepByStep` yields carry no pause field. +- **`withOverrodeHaltState` (the misspelled alias)** — no deprecated alias retained. +- **The `-. onHalt .->` Mermaid arrow** — wrapper-to-override is now an ordinary solid `--> override` arrow; dotted `-.->` is reserved for frame-level dispatch. +- **`GraphNode.isWrapped`** — replaced by `isWrapper: boolean`, `bareStateId: number | null`, `frameId: number | null`. +- **`run()` callbacks (`onPause`, `onStep`, `onIter`)** — moved to `DebugSession` events. +- **Hand-drawn pedagogical Mermaid blocks in READMEs** — the v7 `toMermaid` output is the primary illustration; no more vocabulary mismatch between hand-drawn and engine-rendered diagrams. + +### Migration + +Mechanical identifier rename: + +```sh +git grep -l 'OverrodeHaltState\|overrodeHaltState' | xargs sed -i '' \ + -e 's/OverrodeHaltState/OverriddenHaltState/g' \ + -e 's/overrodeHaltState/overriddenHaltState/g' +``` + +`await`-on-`run()` and callback users move to `DebugSession`: + +```ts +// before +await machine.run({ initialState, onPause: (m) => { ... } }); + +// after +const session = new DebugSession(machine, { initialState }); +session.on('pause', (m) => { /* m.pause.side, m.pause.cause */ }); +await session.continue(); +``` + +`m.debugBreak.before` / `.after` / `.cause` consumers move to `m.pause.side` / `m.pause.cause` on `DebugSession` `pause` events. + +`haltState.debug = { after: true }` writes throw — use `haltState.debug = true` (always after-side). + +Code that pattern-matches `state.name` for wrapper composites switches from `>`-split to paren-parse: `'A>B'` is now `'A(B)'`. + +If you render `toMermaid` output programmatically, the edge-label vocabulary changed completely — see the engine README's §Diagram conventions. + +If you store serialized `Graph` JSON: `node.overrodeHaltStateId` → `node.overriddenHaltStateId`, `GraphNode.isWrapped` → `isWrapper` + `bareStateId` + `frameId`, `GraphTransition.id` separator `-` → `.`. + +### Compatibility + +- Peer dep `@turing-machine-js/machine` widened `^7.0.0-alpha.8` → `^7.0.0` on `@turing-machine-js/builder`, `@turing-machine-js/library-binary-numbers`, `@turing-machine-js/library-binary-numbers-bare`, `@turing-machine-js/visuals`. + ## [7.0.0-alpha.8] - 2026-06-02 Eighth v7 pre-release. Lifts `TapeSnapshot` (the per-tape wire-data shape `{symbols, position}`) and `tapeViewport` (fixed-width centered window over a `TapeSnapshot`) from `@turing-machine-js/visuals` into the engine, next to the `Tape` class. Resolves [#227](https://github.com/mellonis/turing-machine-js/issues/227). Published under the `next` dist-tag: `npm install @turing-machine-js/machine@next`. diff --git a/packages/machine/README.md b/packages/machine/README.md index 68585a2..dd8ff76 100644 --- a/packages/machine/README.md +++ b/packages/machine/README.md @@ -852,7 +852,7 @@ 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.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: +- **v7** *(2026-06-03)* — Composition-representation overhaul + first-class state tags + id-keyed `State.collectStates` lookup + `DebugSession` step controls + `CallFrame` + `tapeViewport`/`TapeSnapshot`. Stable release on the `latest` dist-tag: `npm install @turing-machine-js/machine`. Highlights across the v7 alpha cycle: **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). diff --git a/packages/machine/package.json b/packages/machine/package.json index d22c306..aa823f4 100644 --- a/packages/machine/package.json +++ b/packages/machine/package.json @@ -1,6 +1,6 @@ { "name": "@turing-machine-js/machine", - "version": "7.0.0-alpha.8", + "version": "7.0.0", "description": "A convenient Turing machine", "engines": { "npm": ">=7.0.0" diff --git a/packages/visuals/CHANGELOG.md b/packages/visuals/CHANGELOG.md index 8eb8fd2..302b2ce 100644 --- a/packages/visuals/CHANGELOG.md +++ b/packages/visuals/CHANGELOG.md @@ -4,6 +4,21 @@ All notable changes to this package will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [7.0.0] - 2026-06-03 + +Stable v7. Lockstep release with `@turing-machine-js/machine` 7.0.0. First stable cut of the visuals companion package. See the machine package CHANGELOG for the cumulative v7 trajectory. + +### Added (cumulative across the v7 alpha cycle) + +- **Highlight + graph-indexing surface** (alpha.6): `applyHighlight`, `applyIndicator`, `indexGraph`, `bareIdOf`, `highlightExpand`, `equivalentIds`, `recordingOps`, plus types `HighlightOps` / `IndicatorOps` / `RecordedOp` / `NodeKey` / `HighlightClass` / `GraphIndexes` / `GraphHighlight`. 16-rule contract doc at `docs/graph-highlight-and-breakpoints.md`. +- **Snippet recording + playback** (alpha.6, alpha.7.1): `recordSnippet({ machine, initialState, graph, alphabets, name?, maxSteps?, log? }) => Snippet` (engine-agnostic — works with `@turing-machine-js/machine` or `@post-machine-js/machine`), `SnippetPlayer` class with `currentFrame` / `frameIndex` / `done` getters + `forward()` / `back()` / `reset()` / `goTo(idx)`. `Frame.commands` carries per-tape `{ movement, read, write }` so consumers step bi-directionally without recomputing deltas. Types: `Snippet`, `Frame`, `StepCommand`, `RecordSnippetOptions`. +- **Engine-edge-label formatter primitives** (alpha.6.1): `formatStepNotation(reads, commands, blanks, matchKinds?)` (byte-identical to `toMermaid` edge labels, with `'X'` / `B` / `*='X'` / `K='X'` / `K=B` / `E` shortcuts), `tokenizeStep(...) → StepTokens` (renderer-agnostic structured tokens — discriminated-union `ReadToken` / `WriteToken` per cell, moves as letters; consumers wanting non-string rendering walk tokens themselves), `formatTape(snapshot)` (head bracketed in place, `a[b]c`). Earlier `formatCommand` / `formatStep` continue to work. +- **`TapeSnapshot` + `tapeViewport` re-exports** (alpha.8) — moved into `@turing-machine-js/machine` and re-exported from visuals for consumer-import stability. `import { TapeSnapshot, tapeViewport } from '@turing-machine-js/visuals'` keeps working. + +### Changed + +- Peer dep `@turing-machine-js/machine` widened `^7.0.0-alpha.8` → `^7.0.0`. + ## [7.0.0-alpha.8] - 2026-06-02 `TapeSnapshot` type and `tapeViewport` helper moved to `@turing-machine-js/machine` ([#227](https://github.com/mellonis/turing-machine-js/issues/227)) — they live next to the live `Tape` class now. **Consumers importing them from `@turing-machine-js/visuals` are unaffected**: visuals re-exports both from the engine, so existing `import { TapeSnapshot, tapeViewport } from '@turing-machine-js/visuals'` continues to work. diff --git a/packages/visuals/README.md b/packages/visuals/README.md index b20e776..6b50ec9 100644 --- a/packages/visuals/README.md +++ b/packages/visuals/README.md @@ -14,13 +14,7 @@ Pure highlight + graph-indexing logic for [`@turing-machine-js/machine`](../mach npm install @turing-machine-js/visuals @turing-machine-js/machine ``` -Both prereleases on npm `next`: - -```sh -npm install @turing-machine-js/visuals@next @turing-machine-js/machine@next -``` - -Peer-deps on `@turing-machine-js/machine@^7.0.0-alpha.6` — visuals follows engine v7 alphas with occasional visuals-only patches (`7.0.0-alpha.6.1` added the formatter primitives + token surface on top of the lockstep alpha.6 engine release). +Peer-deps on `@turing-machine-js/machine@^7.0.0`. First published as v7-only — released alongside the engine v7.0.0 stable cut. Visuals follows the engine in lockstep with occasional visuals-only patches (e.g. `7.0.0-alpha.6.1` and `7.0.0-alpha.7.1` during the v7 prerelease cycle). ## Public API diff --git a/packages/visuals/package.json b/packages/visuals/package.json index 728a4c0..baeef84 100644 --- a/packages/visuals/package.json +++ b/packages/visuals/package.json @@ -1,6 +1,6 @@ { "name": "@turing-machine-js/visuals", - "version": "7.0.0-alpha.8", + "version": "7.0.0", "description": "Pure highlight + graph-indexing logic for @turing-machine-js/machine — no DOM, no renderer.", "engines": { "npm": ">=7.0.0" @@ -25,7 +25,7 @@ "visualization" ], "peerDependencies": { - "@turing-machine-js/machine": "^7.0.0-alpha.8" + "@turing-machine-js/machine": "^7.0.0" }, "scripts": { "build": "tsc --build --verbose tsconfig.build.json && node ../../scripts/build-node-entries.mjs --package=@turing-machine-js/visuals",