import type { AstNode } from '../parser/types'; import type { Continuation, SnapshotState } from '../evaluator/effectTypes'; import type { CallStackEntry } from '../evaluator/callStack'; import type { Any } from '../interface'; export type StopReason = 'breakpoint' | 'step'; export interface DebugStoppedEvent { reason: StopReason; node: AstNode; continuation: Continuation; } export interface Variable { name: string; value: Any; } export type StepCommand = 'continue' | 'stepOver' | 'stepInto' | 'stepOut'; /** * Evaluate a condition expression using the current scope's bindings. * Returns the result value, or undefined if evaluation failed. */ export type ConditionEvaluator = (expression: string, continuation: Continuation) => Promise; /** * Core debugger — runtime-agnostic controller that uses the `onNodeEval` hook * to implement breakpoints, stepping, and variable inspection. * * Usage: * 1. Create a Debugger instance with a `onStopped` callback * 2. Pass `debugger.onNodeEval` as the `onNodeEval` option to `dvala.runAsync()` * 3. When execution hits a breakpoint or step, `onStopped` fires * 4. Call `debugger.continue()`, `stepOver()`, `stepInto()`, or `stepOut()` * to resume execution */ export declare class Debugger { private breakpoints; private onStopped; private conditionEvaluator; private pendingResolve; private stepCommand; private stepDepth; constructor(onStopped: (event: DebugStoppedEvent) => void, conditionEvaluator?: ConditionEvaluator); setBreakpoint(nodeId: number, condition?: string): void; removeBreakpoint(nodeId: number): void; clearBreakpoints(): void; getBreakpoints(): Set; /** Resume execution until next breakpoint. */ continue(): void; /** Step to next node at the same or shallower depth (skip over function calls). */ stepOver(): void; /** Step to the very next evaluated node (descend into function calls). */ stepInto(): void; /** Step until we return to a shallower depth (exit current function). */ stepOut(): void; /** * Get visible variables at the current stop point. * Walks the context chain from innermost to outermost scope. */ static getVariables(continuation: Continuation): Variable[]; /** Get the call stack at the current stop point. */ static getCallStack(continuation: Continuation): CallStackEntry[]; /** * Extract visible variable bindings as a plain record — suitable for passing * to `dvala.runAsync(expr, { bindings })` for expression evaluation. */ static extractBindings(continuation: Continuation): Record; /** Count call depth by counting FnBody frames in the continuation stack. */ static countCallDepth(continuation: Continuation): number; /** * The `onNodeEval` hook function. Pass as `onNodeEval` in run options. * * Determines whether to stop based on breakpoints and step commands. * For stepOver/stepOut, calls getContinuation() to measure call depth. */ readonly onNodeEval: SnapshotState['onNodeEval']; private evaluateCondition; private stop; private resume; }