Skip to content

ThreeTierEvaluator

Defined in: packages/engine/src/engine/ThreeTierEvaluator.ts:108

Orchestrates three-tier evaluation over a persistent DocumentModel.

── Tier assignment ───────────────────────────────────────────────── | Tier | Condition | Action | |───────|────────────────────────────────────|───────────────────────────────| | 1 | Visible + Dirty (new/changed) | Full pipeline: lex→parse→compile→execute | | 2 | Visible + Cached (scroll into view)| Execute from cached bytecode | | 3 | Invisible + Dirty | Compile-only; execute only variable defs | | Skip | Clean, empty, or non-evaluable | No action |

── Evaluation order ───────────────────────────────────────────────── Lines are always processed in ascending document order (line 1 → end) so that variable assignments flow correctly through the shared VM. Tier 2 relies on this: by the time a clean cached line is reached, the VM already contains all variables from preceding Tier-1 lines.

── Thread safety ──────────────────────────────────────────────────── Tier 1 (visible+dirty) compilation runs synchronously on the main thread for immediate rendering. Tier 3 (invisible+dirty) compilation can be dispatched to a Web Worker via dispatchBackgroundCompiles(). Worker- compiled bytecode is stored in the DocumentModel and validated via isBytecodeValid() to ensure the line text hasn’t changed between dispatch and response.

new ThreeTierEvaluator(
doc,
engine,
checkpointer?): ThreeTierEvaluator;

Defined in: packages/engine/src/engine/ThreeTierEvaluator.ts:130

ParameterTypeDescription
docDocumentModelThe persistent document model.
engineExpressionEngineThe expression engine (shared VM is accessed via engine.getVM()).
checkpointer?VMCheckpointerOptional VM state checkpointer. If provided, the evaluator will create checkpoints after variable-definition lines and support fast VM restoration via restoreTo(). If omitted, checkpointing is disabled.

ThreeTierEvaluator

applyTransaction(changes): {
inserted: number[];
removed: number[];
};

Defined in: packages/engine/src/engine/ThreeTierEvaluator.ts:445

Apply incremental line-level changes to the document model.

Phase 5.2f: Replaces the O(N) setDocument() + full re-evaluation with O(changed) incremental updates. Key benefits:

  1. Unchanged lines retain their persistent lineIds → bytecode survives
  2. Only changed + DAG-downstream lines are marked dirty → Tier 1 re-evaluation
  3. Clean lines in viewport use Tier 2 (cached bytecode execution)
  4. Clean lines outside viewport are skipped entirely

The DAG is fully cleared after propagation: shifted lines would have stale entries keyed by old line numbers, so the DAG is rebuilt from scratch during the subsequent evaluate() call.

Caller should follow up with evaluate(viewport) to re-evaluate dirty lines from line 1 and rebuild the DAG + checkpoints.

ParameterTypeDescription
changesLineChange[]Line-level changes to apply. Must be non-overlapping.
{
inserted: number[];
removed: number[];
}

Metadata about the applied changes.

inserted: number[];
removed: number[];

backgroundCompile(viewport): EvalLineResult[];

Defined in: packages/engine/src/engine/ThreeTierEvaluator.ts:253

Background-compile invisible dirty lines beyond the viewport (Tier 3 only).

Compiles expressions to discover reads/writes for the dependency graph without executing display-only expressions. Variable definitions are executed to maintain VM state for future Tier-2 executions.

This is intended to be called after evaluate() so visible lines are rendered first, then background work fills in the dependency graph.

Phase 5.2h: This synchronous method is retained for environments without Worker support. Prefer dispatchBackgroundCompiles() which offloads compilation to a Web Worker with Transferable bytecode.

ParameterType
viewportViewportRange

EvalLineResult[]


dispatchBackgroundCompiles(viewport): void;

Defined in: packages/engine/src/engine/ThreeTierEvaluator.ts:299

Dispatch background compilation to a Web Worker (Phase 5.2h).

Collects invisible dirty lines beyond the viewport that need compilation, sends them to the compilation worker, and asynchronously stores the transferred bytecode in the DocumentModel when the worker responds.

This is the non-blocking alternative to backgroundCompile(). The worker compiles expressions with Transferable ArrayBuffers (zero-copy postMessage), so bytecode appears on the main thread without serialization overhead.

Lines that already have cached bytecode (from a previous worker pass or synchronous compile) are skipped, only truly uncompiled dirty lines are sent to the worker.

Usage: Call after evaluate() so visible lines render first, then this fills the bytecode cache for future Tier-2 scrolls.

ParameterTypeDescription
viewportViewportRangeThe current visible range. Lines beyond viewport.endLine that are dirty and don’t have bytecode are dispatched.

void


evaluate(viewport, signal?): EvalResult;

Defined in: packages/engine/src/engine/ThreeTierEvaluator.ts:181

Evaluate all lines needed to render the given viewport.

Processes lines from 1 to viewport.endLine in document order. Dirty lines in the viewport get Tier-1 full pipeline; clean cached lines get Tier-2 bytecode execution. Lines after the viewport get Tier-3 compile-only (with variable-def execution).

ParameterType
viewportViewportRange
signal?AbortSignal

EvalResult

Results for all processed lines, including tier metadata.


evaluateAll(signal?): EvalResult;

Defined in: packages/engine/src/engine/ThreeTierEvaluator.ts:348

Evaluate all dirty lines in the document, regardless of viewport. Used for full re-evaluation after plugin register/unregister.

ParameterType
signal?AbortSignal

EvalResult


getCheckpointer(): VMCheckpointer | null;

Defined in: packages/engine/src/engine/ThreeTierEvaluator.ts:1001

Get the VM checkpointer, or null if checkpointing is disabled.

VMCheckpointer | null


getDoc(): DocumentModel;

Defined in: packages/engine/src/engine/ThreeTierEvaluator.ts:340

Get the DocumentModel (read-only access for decoration building).

DocumentModel


getPageManager(): PageManager;

Defined in: packages/engine/src/engine/ThreeTierEvaluator.ts:1009

Get the PageManager (Phase 5.2g). Exposed for testing.

PageManager


restoreTo(lineNumber): void;

Defined in: packages/engine/src/engine/ThreeTierEvaluator.ts:992

Restore the VM to the state at or just after the given line number.

Finds the nearest checkpoint at or before lineNumber and replays all variable definitions from the checkpoint chain into the VM. After calling this, the VM is ready to evaluate lines starting at lineNumber + 1 without re-evaluating all preceding lines.

Usage: Phase 5.2e’s setViewport() calls restoreTo(viewport.startLine - 1) before evaluating only the newly visible lines. This is the key to O(visible lines) scrolling.

ParameterTypeDescription
lineNumbernumberThe line number to restore to. Variables defined at lines ≤ this number will be available in the VM.

void


setViewport(viewport, signal?): EvalResult;

Defined in: packages/engine/src/engine/ThreeTierEvaluator.ts:383

Zero-allocation viewport evaluation, the Phase 5.2e “holy grail.”

Key insight: When the user scrolls (viewport-only change, no edits), we don’t need to re-evaluate from line 1. Instead:

  1. Restore the VM to just before the viewport via the nearest checkpoint.
  2. Evaluate ONLY the visible lines (Tier 2 for clean cached, Tier 1 for dirty).
  3. Lines before the viewport are completely skipped, their state lives in the VM checkpointer’s prototypal chain.

Correctness guard: If any variable-definition line before the viewport is dirty (e.g., the user edited a variable def that hasn’t been re-evaluated yet), we clear stale checkpoints and fall back to evaluate() which processes from line 1 and rebuilds fresh checkpoints. This guarantees that stale checkpoints are never used as restoration targets. Only variable-def lines matter here, VMCheckpointer.snapshot() only records state for lines that write a variable, so a dirty plain-expression line before the viewport has no checkpoint to invalidate (see DocumentModel.hasAnyDirtyVariableDefLineBefore()).

Performance: O(visible lines) instead of O(document length). Target: < 1ms for a typical ~30-line viewport, independent of document size.

ParameterTypeDescription
viewportViewportRangeThe visible line range.
signal?AbortSignal-

EvalResult

Results for visible lines only. Lines before the viewport are not included in lines[] or resultMap.


terminateWorker(): void;

Defined in: packages/engine/src/engine/ThreeTierEvaluator.ts:326

Terminate the compilation worker if active, and unsubscribe from sharedGlobalVariableStore. Call this when the evaluator is no longer needed to clean up resources, every call site that retires a ThreeTierEvaluator (document switch, pane destroy()) already calls this unconditionally, so folding the global-store unsubscribe in here needs no new call sites anywhere.

void