@turing-machine-js/machine 7.0.0-alpha.5 → 7.0.0-alpha.7
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.
- package/CHANGELOG.md +42 -0
- package/README.md +151 -61
- package/dist/classes/DebugSession.d.ts +119 -0
- package/dist/classes/State.d.ts +50 -4
- package/dist/classes/TuringMachine.d.ts +86 -71
- package/dist/index.cjs +721 -307
- package/dist/index.d.ts +3 -2
- package/dist/index.mjs +720 -308
- package/package.json +2 -2
|
@@ -1,9 +1,63 @@
|
|
|
1
|
-
import State from './State';
|
|
1
|
+
import State, { type DebugConfig } from './State';
|
|
2
2
|
import TapeBlock from './TapeBlock';
|
|
3
3
|
type RunParameter = {
|
|
4
4
|
initialState: State;
|
|
5
5
|
stepsLimit?: number;
|
|
6
6
|
};
|
|
7
|
+
/**
|
|
8
|
+
* Descriptor attached to a `DebugSession` `pause` event. Lives ONLY on the
|
|
9
|
+
* pause-event payload (`PausedMachineState`) — never on a raw `runStepByStep`
|
|
10
|
+
* yield, which is a minimal `MachineState` with no debug concern.
|
|
11
|
+
*
|
|
12
|
+
* - `side` — exactly one of `'before'` / `'after'`. DebugSession dispatches the
|
|
13
|
+
* two timings as separate `pause` events, so a single descriptor is always
|
|
14
|
+
* one-sided (the v6 "both timings on one yield" set no longer exists, because
|
|
15
|
+
* detection moved out of the generator).
|
|
16
|
+
* - `cause` — pause origin:
|
|
17
|
+
* - `'breakpoint'` — a `state.debug[when]` filter or `haltState.debug === true` matched.
|
|
18
|
+
* - `'step'` — a step-mode endpoint fired (stepIn / stepOver / stepOut).
|
|
19
|
+
* - `'manual'` — a `DebugSession.pause()` call fired.
|
|
20
|
+
*
|
|
21
|
+
* Precedence when an iter satisfies more than one trigger: `breakpoint > step >
|
|
22
|
+
* manual`. `'step'` / `'manual'` only ever fire on the `'before'` side.
|
|
23
|
+
*/
|
|
24
|
+
export type PauseInfo = {
|
|
25
|
+
side: 'before' | 'after';
|
|
26
|
+
cause: 'breakpoint' | 'step' | 'manual';
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* @internal — directive returned from a DebugSession's internal pause coordination
|
|
30
|
+
* to drive step-mode bookkeeping. NOT part of the public API; exported only for
|
|
31
|
+
* sibling-module use inside `packages/machine/src/classes/DebugSession.ts`.
|
|
32
|
+
*/
|
|
33
|
+
export type ResumeDirective = 'continue' | 'step-in' | 'step-over' | 'step-out';
|
|
34
|
+
/**
|
|
35
|
+
* @internal — package-private accessor key for `MachineState` instances yielded
|
|
36
|
+
* by `runStepByStep`. Calling `machineState[MACHINE_STATE_INTERNAL]()` returns a
|
|
37
|
+
* frozen snapshot of the engine's halt-stack at yield time (BEFORE this iter's
|
|
38
|
+
* applyCommand / pop / push). Consumed by `DebugSession` for step-over /
|
|
39
|
+
* step-out endpoint detection without exposing the stack to public API.
|
|
40
|
+
*
|
|
41
|
+
* Re-exported from this module so the sibling `DebugSession` module can import
|
|
42
|
+
* it; intentionally NOT re-exported from the package's public `index.ts` —
|
|
43
|
+
* downstream consumers shouldn't reach for the stack. Same pattern as
|
|
44
|
+
* `STATE_INTERNAL` (#180).
|
|
45
|
+
*/
|
|
46
|
+
export declare const MACHINE_STATE_INTERNAL: unique symbol;
|
|
47
|
+
export type MachineStateInternal = {
|
|
48
|
+
/** Frozen pre-iter halt-stack snapshot. Consumers must not mutate. */
|
|
49
|
+
stack: readonly State[];
|
|
50
|
+
/** The interned symbol the engine matched for this iter (the result of
|
|
51
|
+
* `state.getSymbol(tapeBlock)`). DebugSession uses it to evaluate
|
|
52
|
+
* `state.debug` filters without re-reading the tape. */
|
|
53
|
+
matchedSymbol: symbol;
|
|
54
|
+
/** Whether this iter's transition leads to halt — computed on the RAW
|
|
55
|
+
* next-state (before any halt-pop redirect to a continuation). The yielded
|
|
56
|
+
* `MachineState.nextState` shows the post-pop continuation, so consumers
|
|
57
|
+
* can't recover halt-imminence from it; DebugSession reads this flag to
|
|
58
|
+
* honor `haltState.debug` on subroutine-return (halt-pop) iters. */
|
|
59
|
+
haltImminent: boolean;
|
|
60
|
+
};
|
|
7
61
|
export type MachineState = {
|
|
8
62
|
step: number;
|
|
9
63
|
state: State;
|
|
@@ -11,21 +65,6 @@ export type MachineState = {
|
|
|
11
65
|
nextSymbols: string[];
|
|
12
66
|
movements: symbol[];
|
|
13
67
|
nextState: State;
|
|
14
|
-
/**
|
|
15
|
-
* Set only when this iteration is a debug break point.
|
|
16
|
-
* Field is OMITTED entirely when no break fires (no `debugBreak: undefined`).
|
|
17
|
-
* At least one of `before` / `after` is `true` when the field is present.
|
|
18
|
-
*
|
|
19
|
-
* Both flags refer to THIS iter — `before` means the iter's `state.debug.before`
|
|
20
|
-
* matched, `after` means the iter's `state.debug.after` matched. `run()`
|
|
21
|
-
* dispatches the two timings as separate `onPause` calls (before-call has
|
|
22
|
-
* `debugBreak: {before: true}` only; after-call has `debugBreak: {after: true}`
|
|
23
|
-
* only) so consumers can distinguish without ambiguity.
|
|
24
|
-
*/
|
|
25
|
-
debugBreak?: {
|
|
26
|
-
before?: true;
|
|
27
|
-
after?: true;
|
|
28
|
-
};
|
|
29
68
|
/**
|
|
30
69
|
* The transition the engine picked for this iter (#205). Always present
|
|
31
70
|
* — `runStepByStep` resolves it at the very start of every iter via
|
|
@@ -50,67 +89,43 @@ export type MachineState = {
|
|
|
50
89
|
matchKinds: ('wildcard' | 'literal')[];
|
|
51
90
|
};
|
|
52
91
|
};
|
|
92
|
+
/**
|
|
93
|
+
* The payload of a `DebugSession` `pause` event: a `MachineState` plus the
|
|
94
|
+
* one-sided `pause` descriptor. Raw `runStepByStep` yields are plain
|
|
95
|
+
* `MachineState` (no `pause` field) — only DebugSession produces this shape.
|
|
96
|
+
*/
|
|
97
|
+
export type PausedMachineState = MachineState & {
|
|
98
|
+
pause: PauseInfo;
|
|
99
|
+
};
|
|
100
|
+
/**
|
|
101
|
+
* @internal — true iff `filter` matches `symbol` per the DebugConfig semantics.
|
|
102
|
+
* undefined / [] -> never; true -> always; symbol[] -> exact membership.
|
|
103
|
+
* Exported for sibling-module use in `DebugSession` (which now owns breakpoint
|
|
104
|
+
* detection); NOT re-exported from the package's public `index.ts`.
|
|
105
|
+
*/
|
|
106
|
+
export declare function matchFilter(filter: DebugConfig['before'], symbol: symbol): boolean;
|
|
53
107
|
export default class TuringMachine {
|
|
54
108
|
#private;
|
|
55
109
|
constructor({ tapeBlock, }?: {
|
|
56
110
|
tapeBlock?: TapeBlock;
|
|
57
111
|
});
|
|
58
112
|
get tapeBlock(): TapeBlock;
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
* Renamed from `onDebugBreak` in v5.0.0. In v6.0.0 the dispatch order
|
|
76
|
-
* was changed so that `before` and `after` for the SAME iter fire on the
|
|
77
|
-
* same yield (per-iter lifecycle: before → step → after); previously the
|
|
78
|
-
* `after` of iter K fired on iter K+1's tick with a substituted source
|
|
79
|
-
* view. The `m.debugBreak` payload field keeps its name (it describes the
|
|
80
|
-
* engine's reason for pausing).
|
|
81
|
-
*/
|
|
82
|
-
onPause?: (machineState: MachineState) => void | Promise<void>;
|
|
83
|
-
/**
|
|
84
|
-
* Awaited hook fired ONCE at the end of every iteration (v6.4.0+), AFTER
|
|
85
|
-
* any `onPause(after, K)` dispatch on the same yield. Use for per-iter
|
|
86
|
-
* coordination that needs to suspend the run loop — throttling between
|
|
87
|
-
* iters (interactive debugger UIs), prev-state bookkeeping that must
|
|
88
|
-
* observe iter K's final state once all `onPause` hooks have read their
|
|
89
|
-
* own snapshots, yield-to-other-work in batched runs.
|
|
90
|
-
*
|
|
91
|
-
* Three-hook contract recap:
|
|
92
|
-
* - `onStep`: sync, microtask-free — tracing/logging during the iter
|
|
93
|
-
* - `onPause`: awaited, conditional on `state.debug[when]` match — user
|
|
94
|
-
* breakpoints with iter-correct payload
|
|
95
|
-
* - `onIter`: awaited, unconditional — once per iter, at end-of-iter
|
|
96
|
-
*
|
|
97
|
-
* `onIter` is unaffected by the `debug` master switch — it fires on
|
|
98
|
-
* every iter regardless. Sync consumers should prefer `onStep` to avoid
|
|
99
|
-
* the per-iter microtask boundary `onIter` carries.
|
|
100
|
-
*/
|
|
101
|
-
onIter?: (machineState: MachineState) => void | Promise<void>;
|
|
102
|
-
/**
|
|
103
|
-
* Master switch for `onPause` dispatch. When `false`, suppresses all
|
|
104
|
-
* pause-fires (before and after) regardless of `state.debug` assignments.
|
|
105
|
-
* `onStep` is unaffected. Defaults to `true`.
|
|
106
|
-
*
|
|
107
|
-
* The `m.debugBreak` field is still populated on yields by the underlying
|
|
108
|
-
* generator (it's a property of the iteration, not of the consumer); only
|
|
109
|
-
* `run()`'s hook dispatch is gated. Direct `runStepByStep` consumers see
|
|
110
|
-
* the metadata regardless.
|
|
111
|
-
*/
|
|
112
|
-
debug?: boolean;
|
|
113
|
-
}): Promise<void>;
|
|
113
|
+
/**
|
|
114
|
+
* Run the machine to halt. Pure execution — synchronous, no observation
|
|
115
|
+
* callbacks, no debug overhead. For breakpoint-driven interactive debugging
|
|
116
|
+
* use `DebugSession`; for per-iter tracing use `runStepByStep`'s generator
|
|
117
|
+
* directly.
|
|
118
|
+
*
|
|
119
|
+
* Breakpoint metadata (`state.debug` / `haltState.debug` matches) is still
|
|
120
|
+
* resolved and attached to each yielded MachineState by the underlying
|
|
121
|
+
* generator — `run()` simply doesn't dispatch on it. A consumer that wants
|
|
122
|
+
* to dispatch on it constructs a `DebugSession` instead.
|
|
123
|
+
*
|
|
124
|
+
* Symmetric reversal of v4's `run` → `async run` change: v4 made the method
|
|
125
|
+
* async to support awaited `onPause`; with callbacks moved to `DebugSession`
|
|
126
|
+
* there's no async work left, so the method returns `void` again.
|
|
127
|
+
*/
|
|
128
|
+
run({ initialState, stepsLimit }: RunParameter): void;
|
|
114
129
|
runStepByStep({ initialState, stepsLimit }: RunParameter): Generator<MachineState>;
|
|
115
130
|
}
|
|
116
131
|
export {};
|