@turing-machine-js/machine 6.3.0 → 7.0.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -33,22 +33,14 @@ export default class TuringMachine {
33
33
  tapeBlock?: TapeBlock;
34
34
  });
35
35
  get tapeBlock(): TapeBlock;
36
- run({ initialState, stepsLimit, onStep, onPause, debug, }: RunParameter & {
36
+ run({ initialState, stepsLimit, onStep, onPause, onIter, debug, }: RunParameter & {
37
37
  /**
38
38
  * Sync, ~free hook fired on every iteration. Use for logging/tracing —
39
39
  * the hot loop runs this without a microtask boundary, so it must not
40
40
  * be async.
41
41
  *
42
42
  * For per-iter throttle / coordination ("wait between iters" UIs):
43
- * arm `state.debug.after = true` on each visited state and do the
44
- * throttle inside `onPause` (which IS awaited). See the README's
45
- * Throttle pattern section for a worked example.
46
- *
47
- * (v6.2.0 widened this to `void | Promise<void>` and added an inline
48
- * `await`. That was a mistake — it drove the awaited contract into a
49
- * hook that was deliberately documented as sync. Restored in v6.3.0;
50
- * consumers needing per-iter await belong on the `onPause`-rearm
51
- * pattern, not this hook.)
43
+ * use `onIter` (v6.4.0+, awaited at end-of-iter).
52
44
  */
53
45
  onStep?: (machineState: MachineState) => void;
54
46
  /**
@@ -65,6 +57,25 @@ export default class TuringMachine {
65
57
  * engine's reason for pausing).
66
58
  */
67
59
  onPause?: (machineState: MachineState) => void | Promise<void>;
60
+ /**
61
+ * Awaited hook fired ONCE at the end of every iteration (v6.4.0+), AFTER
62
+ * any `onPause(after, K)` dispatch on the same yield. Use for per-iter
63
+ * coordination that needs to suspend the run loop — throttling between
64
+ * iters (interactive debugger UIs), prev-state bookkeeping that must
65
+ * observe iter K's final state once all `onPause` hooks have read their
66
+ * own snapshots, yield-to-other-work in batched runs.
67
+ *
68
+ * Three-hook contract recap:
69
+ * - `onStep`: sync, microtask-free — tracing/logging during the iter
70
+ * - `onPause`: awaited, conditional on `state.debug[when]` match — user
71
+ * breakpoints with iter-correct payload
72
+ * - `onIter`: awaited, unconditional — once per iter, at end-of-iter
73
+ *
74
+ * `onIter` is unaffected by the `debug` master switch — it fires on
75
+ * every iter regardless. Sync consumers should prefer `onStep` to avoid
76
+ * the per-iter microtask boundary `onIter` carries.
77
+ */
78
+ onIter?: (machineState: MachineState) => void | Promise<void>;
68
79
  /**
69
80
  * Master switch for `onPause` dispatch. When `false`, suppresses all
70
81
  * pause-fires (before and after) regardless of `state.debug` assignments.