solve-engine 1.0.0-beta.0 → 1.0.0-beta.2
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/dist/BytecodeBuilder-3egMyuDi.d.cts +274 -0
- package/dist/BytecodeBuilder-3egMyuDi.d.ts +274 -0
- package/dist/Configuration-fVpd-HC-.d.cts +228 -0
- package/dist/Configuration-fVpd-HC-.d.ts +228 -0
- package/dist/EngineError-DvPSnhZi.d.cts +304 -0
- package/dist/EngineError-DvPSnhZi.d.ts +304 -0
- package/dist/Lexer-BJdhlnej.d.cts +531 -0
- package/dist/Lexer-D9l4Yrk2.d.ts +531 -0
- package/dist/NormalizerRule-BrVoVjmP.d.cts +163 -0
- package/dist/NormalizerRule-CEjf1FyD.d.ts +163 -0
- package/dist/PackageRegistry-D-Tv_7ca.d.cts +2572 -0
- package/dist/PackageRegistry-DaH4aIKP.d.ts +2572 -0
- package/dist/Parselet-CK8cQu2a.d.cts +299 -0
- package/dist/Parselet-ConOIdRO.d.ts +299 -0
- package/dist/ScopeManager-B5k0nk05.d.ts +559 -0
- package/dist/ScopeManager-CKfQtl7l.d.cts +559 -0
- package/dist/Token-0jpvUdPY.d.cts +245 -0
- package/dist/Token-0jpvUdPY.d.ts +245 -0
- package/dist/VMCheckpoints-BmDwIXgK.d.ts +171 -0
- package/dist/VMCheckpoints-CqFuLwrT.d.cts +171 -0
- package/dist/Value-KtAQNHur.d.cts +295 -0
- package/dist/Value-KtAQNHur.d.ts +295 -0
- package/dist/chunk-2RWAXT6O.js +3 -0
- package/dist/chunk-2RWAXT6O.js.map +1 -0
- package/dist/chunk-34RRD7PC.js +1492 -0
- package/dist/chunk-34RRD7PC.js.map +1 -0
- package/dist/chunk-3PPFLFH4.js +5097 -0
- package/dist/chunk-3PPFLFH4.js.map +1 -0
- package/dist/chunk-3VGDNEE3.js +84 -0
- package/dist/chunk-3VGDNEE3.js.map +1 -0
- package/dist/chunk-3YNVWKR2.cjs +370 -0
- package/dist/chunk-3YNVWKR2.cjs.map +1 -0
- package/dist/chunk-47LRVGOT.cjs +316 -0
- package/dist/chunk-47LRVGOT.cjs.map +1 -0
- package/dist/chunk-4MG4XKO2.js +1644 -0
- package/dist/chunk-4MG4XKO2.js.map +1 -0
- package/dist/chunk-4QADQTWS.js +2392 -0
- package/dist/chunk-4QADQTWS.js.map +1 -0
- package/dist/chunk-53B6KDDJ.cjs +1651 -0
- package/dist/chunk-53B6KDDJ.cjs.map +1 -0
- package/dist/chunk-5X2PTP6F.cjs +104 -0
- package/dist/chunk-5X2PTP6F.cjs.map +1 -0
- package/dist/chunk-5YEMOYSE.js +264 -0
- package/dist/chunk-5YEMOYSE.js.map +1 -0
- package/dist/chunk-64W6GLLZ.js +481 -0
- package/dist/chunk-64W6GLLZ.js.map +1 -0
- package/dist/chunk-6BKTCEUP.cjs +233 -0
- package/dist/chunk-6BKTCEUP.cjs.map +1 -0
- package/dist/chunk-6NTVRDQV.cjs +1642 -0
- package/dist/chunk-6NTVRDQV.cjs.map +1 -0
- package/dist/chunk-6RDSQURE.js +290 -0
- package/dist/chunk-6RDSQURE.js.map +1 -0
- package/dist/chunk-75JP4BZX.js +93 -0
- package/dist/chunk-75JP4BZX.js.map +1 -0
- package/dist/chunk-B7LXJ6LC.cjs +36 -0
- package/dist/chunk-B7LXJ6LC.cjs.map +1 -0
- package/dist/chunk-BVAR5J2F.js +257 -0
- package/dist/chunk-BVAR5J2F.js.map +1 -0
- package/dist/chunk-C4XZV6E7.cjs +269 -0
- package/dist/chunk-C4XZV6E7.cjs.map +1 -0
- package/dist/chunk-CCJPSHGI.cjs +40 -0
- package/dist/chunk-CCJPSHGI.cjs.map +1 -0
- package/dist/chunk-CLL7RUQV.cjs +316 -0
- package/dist/chunk-CLL7RUQV.cjs.map +1 -0
- package/dist/chunk-DM3LMRBC.js +329 -0
- package/dist/chunk-DM3LMRBC.js.map +1 -0
- package/dist/chunk-DUEZFTK2.js +38 -0
- package/dist/chunk-DUEZFTK2.js.map +1 -0
- package/dist/chunk-EBSPLUW4.cjs +489 -0
- package/dist/chunk-EBSPLUW4.cjs.map +1 -0
- package/dist/chunk-EHAHVROS.cjs +261 -0
- package/dist/chunk-EHAHVROS.cjs.map +1 -0
- package/dist/chunk-EIGTWK5N.js +167 -0
- package/dist/chunk-EIGTWK5N.js.map +1 -0
- package/dist/chunk-EPOXXJBK.js +96 -0
- package/dist/chunk-EPOXXJBK.js.map +1 -0
- package/dist/chunk-FEAIOR7N.cjs +91 -0
- package/dist/chunk-FEAIOR7N.cjs.map +1 -0
- package/dist/chunk-G535KJEG.js +312 -0
- package/dist/chunk-G535KJEG.js.map +1 -0
- package/dist/chunk-GCM5JHMX.js +88 -0
- package/dist/chunk-GCM5JHMX.js.map +1 -0
- package/dist/chunk-GOLDJNMZ.js +368 -0
- package/dist/chunk-GOLDJNMZ.js.map +1 -0
- package/dist/chunk-GW32KPCU.cjs +360 -0
- package/dist/chunk-GW32KPCU.cjs.map +1 -0
- package/dist/chunk-HTXVVJRA.cjs +1549 -0
- package/dist/chunk-HTXVVJRA.cjs.map +1 -0
- package/dist/chunk-HWSZJQCI.js +311 -0
- package/dist/chunk-HWSZJQCI.js.map +1 -0
- package/dist/chunk-IF532O7C.js +101 -0
- package/dist/chunk-IF532O7C.js.map +1 -0
- package/dist/chunk-J73SJHR3.cjs +2415 -0
- package/dist/chunk-J73SJHR3.cjs.map +1 -0
- package/dist/chunk-JBSYC7BB.cjs +7473 -0
- package/dist/chunk-JBSYC7BB.cjs.map +1 -0
- package/dist/chunk-KVILKGMS.js +228 -0
- package/dist/chunk-KVILKGMS.js.map +1 -0
- package/dist/chunk-LIPPNDBE.js +258 -0
- package/dist/chunk-LIPPNDBE.js.map +1 -0
- package/dist/chunk-LR7YASZF.cjs +172 -0
- package/dist/chunk-LR7YASZF.cjs.map +1 -0
- package/dist/chunk-M4N5GA5Z.cjs +309 -0
- package/dist/chunk-M4N5GA5Z.cjs.map +1 -0
- package/dist/chunk-M5LX5AOO.js +7459 -0
- package/dist/chunk-M5LX5AOO.js.map +1 -0
- package/dist/chunk-MZOVP3WI.cjs +96 -0
- package/dist/chunk-MZOVP3WI.cjs.map +1 -0
- package/dist/chunk-N5YFR4UP.cjs +10 -0
- package/dist/chunk-N5YFR4UP.cjs.map +1 -0
- package/dist/chunk-NGBBNL4K.cjs +4 -0
- package/dist/chunk-NGBBNL4K.cjs.map +1 -0
- package/dist/chunk-NH2O2AUR.js +146 -0
- package/dist/chunk-NH2O2AUR.js.map +1 -0
- package/dist/chunk-NLNDMWZC.js +31 -0
- package/dist/chunk-NLNDMWZC.js.map +1 -0
- package/dist/chunk-NMCRQP3Z.cjs +778 -0
- package/dist/chunk-NMCRQP3Z.cjs.map +1 -0
- package/dist/chunk-NMD5VRN4.cjs +1327 -0
- package/dist/chunk-NMD5VRN4.cjs.map +1 -0
- package/dist/chunk-OC6LTXYS.cjs +286 -0
- package/dist/chunk-OC6LTXYS.cjs.map +1 -0
- package/dist/chunk-OT6OJY7C.cjs +114 -0
- package/dist/chunk-OT6OJY7C.cjs.map +1 -0
- package/dist/chunk-PFSDGGYL.js +8 -0
- package/dist/chunk-PFSDGGYL.js.map +1 -0
- package/dist/chunk-QNJ4ACRT.cjs +155 -0
- package/dist/chunk-QNJ4ACRT.cjs.map +1 -0
- package/dist/chunk-QWY3VEZN.js +1637 -0
- package/dist/chunk-QWY3VEZN.js.map +1 -0
- package/dist/chunk-RFYD5TJE.js +111 -0
- package/dist/chunk-RFYD5TJE.js.map +1 -0
- package/dist/chunk-RIN643A3.js +354 -0
- package/dist/chunk-RIN643A3.js.map +1 -0
- package/dist/chunk-RZCWSXTA.cjs +5122 -0
- package/dist/chunk-RZCWSXTA.cjs.map +1 -0
- package/dist/chunk-SDGRK7EP.js +774 -0
- package/dist/chunk-SDGRK7EP.js.map +1 -0
- package/dist/chunk-VEKIWQ3F.cjs +39 -0
- package/dist/chunk-VEKIWQ3F.cjs.map +1 -0
- package/dist/chunk-WQTTOGXC.cjs +99 -0
- package/dist/chunk-WQTTOGXC.cjs.map +1 -0
- package/dist/chunk-X6K3HUOY.cjs +86 -0
- package/dist/chunk-X6K3HUOY.cjs.map +1 -0
- package/dist/chunk-XJCMXB2E.cjs +333 -0
- package/dist/chunk-XJCMXB2E.cjs.map +1 -0
- package/dist/chunk-XVWCOTR6.js +1324 -0
- package/dist/chunk-XVWCOTR6.js.map +1 -0
- package/dist/chunk-YLJ4XMA6.js +33 -0
- package/dist/chunk-YLJ4XMA6.js.map +1 -0
- package/dist/chunk-Z2XP767T.cjs +35 -0
- package/dist/chunk-Z2XP767T.cjs.map +1 -0
- package/dist/chunk-Z4X2RWOF.js +37 -0
- package/dist/chunk-Z4X2RWOF.js.map +1 -0
- package/dist/constants.cjs +22 -0
- package/dist/constants.cjs.map +1 -0
- package/dist/constants.d.cts +12 -0
- package/dist/constants.d.ts +12 -0
- package/dist/constants.js +5 -0
- package/dist/constants.js.map +1 -0
- package/dist/engine.cjs +79 -0
- package/dist/engine.cjs.map +1 -0
- package/dist/engine.d.cts +587 -0
- package/dist/engine.d.ts +587 -0
- package/dist/engine.js +34 -0
- package/dist/engine.js.map +1 -0
- package/dist/errors.cjs +81 -0
- package/dist/errors.cjs.map +1 -0
- package/dist/errors.d.cts +95 -0
- package/dist/errors.d.ts +95 -0
- package/dist/errors.js +4 -0
- package/dist/errors.js.map +1 -0
- package/dist/format.cjs +171 -0
- package/dist/format.cjs.map +1 -0
- package/dist/format.d.cts +51 -0
- package/dist/format.d.ts +51 -0
- package/dist/format.js +168 -0
- package/dist/format.js.map +1 -0
- package/dist/index.cjs +97 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +152 -0
- package/dist/index.d.ts +152 -0
- package/dist/index.js +75 -0
- package/dist/index.js.map +1 -0
- package/dist/language.cjs +308 -0
- package/dist/language.cjs.map +1 -0
- package/dist/language.d.cts +110 -0
- package/dist/language.d.ts +110 -0
- package/dist/language.js +287 -0
- package/dist/language.js.map +1 -0
- package/dist/lexer.cjs +64 -0
- package/dist/lexer.cjs.map +1 -0
- package/dist/lexer.d.cts +56 -0
- package/dist/lexer.d.ts +56 -0
- package/dist/lexer.js +11 -0
- package/dist/lexer.js.map +1 -0
- package/dist/normalizer.cjs +40 -0
- package/dist/normalizer.cjs.map +1 -0
- package/dist/normalizer.d.cts +364 -0
- package/dist/normalizer.d.ts +364 -0
- package/dist/normalizer.js +11 -0
- package/dist/normalizer.js.map +1 -0
- package/dist/packages.cjs +121 -0
- package/dist/packages.cjs.map +1 -0
- package/dist/packages.d.cts +691 -0
- package/dist/packages.d.ts +691 -0
- package/dist/packages.js +24 -0
- package/dist/packages.js.map +1 -0
- package/dist/parser.cjs +55 -0
- package/dist/parser.cjs.map +1 -0
- package/dist/parser.d.cts +46 -0
- package/dist/parser.d.ts +46 -0
- package/dist/parser.js +10 -0
- package/dist/parser.js.map +1 -0
- package/dist/pipeline-CrsRPmsv.d.ts +285 -0
- package/dist/pipeline-DPUQt7yL.d.cts +285 -0
- package/dist/resolvers.cjs +13 -0
- package/dist/resolvers.cjs.map +1 -0
- package/dist/resolvers.d.cts +111 -0
- package/dist/resolvers.d.ts +111 -0
- package/dist/resolvers.js +4 -0
- package/dist/resolvers.js.map +1 -0
- package/dist/services.cjs +21 -0
- package/dist/services.cjs.map +1 -0
- package/dist/services.d.cts +30 -0
- package/dist/services.d.ts +30 -0
- package/dist/services.js +4 -0
- package/dist/services.js.map +1 -0
- package/dist/uom.cjs +56 -0
- package/dist/uom.cjs.map +1 -0
- package/dist/uom.d.cts +224 -0
- package/dist/uom.d.ts +224 -0
- package/dist/uom.js +11 -0
- package/dist/uom.js.map +1 -0
- package/dist/utilities.cjs +32 -0
- package/dist/utilities.cjs.map +1 -0
- package/dist/utilities.d.cts +113 -0
- package/dist/utilities.d.ts +113 -0
- package/dist/utilities.js +7 -0
- package/dist/utilities.js.map +1 -0
- package/dist/variables.cjs +17 -0
- package/dist/variables.cjs.map +1 -0
- package/dist/variables.d.cts +87 -0
- package/dist/variables.d.ts +87 -0
- package/dist/variables.js +4 -0
- package/dist/variables.js.map +1 -0
- package/dist/vm.cjs +284 -0
- package/dist/vm.cjs.map +1 -0
- package/dist/vm.d.cts +68 -0
- package/dist/vm.d.ts +68 -0
- package/dist/vm.js +194 -0
- package/dist/vm.js.map +1 -0
- package/package.json +4 -4
|
@@ -0,0 +1,587 @@
|
|
|
1
|
+
import { D as DocumentModel, a as ExpressionEngine, V as ViewportRange, c as LineChange, d as InlineSolvePosition } from './PackageRegistry-D-Tv_7ca.cjs';
|
|
2
|
+
export { A as ApplyChangesResult, e as AsyncCachePackageInfo, f as AsyncErrorEvent, g as AsyncResolutionBatcher, h as AsyncResolutionEvent, B as BatcherMetrics, i as BytecodeCacheEntry, C as CacheSnapshot, j as CheckpointSnapshot, E as EvalResults, k as LineCacheEntryInfo, L as LineEvaluation, l as LineState, m as LinesUpdatedEvent } from './PackageRegistry-D-Tv_7ca.cjs';
|
|
3
|
+
import { V as Value } from './Value-KtAQNHur.cjs';
|
|
4
|
+
import { a as VMCheckpointer } from './VMCheckpoints-CqFuLwrT.cjs';
|
|
5
|
+
import { T as Token } from './Token-0jpvUdPY.cjs';
|
|
6
|
+
import { E as EngineError } from './EngineError-DvPSnhZi.cjs';
|
|
7
|
+
import { a as BytecodeProgram } from './BytecodeBuilder-3egMyuDi.cjs';
|
|
8
|
+
export { a as DagSnapshot } from './ScopeManager-CKfQtl7l.cjs';
|
|
9
|
+
import './Parselet-CK8cQu2a.cjs';
|
|
10
|
+
import './pipeline-DPUQt7yL.cjs';
|
|
11
|
+
import './variables.cjs';
|
|
12
|
+
import './Lexer-BJdhlnej.cjs';
|
|
13
|
+
import './resolvers.cjs';
|
|
14
|
+
import '@tanstack/query-core';
|
|
15
|
+
import './NormalizerRule-BrVoVjmP.cjs';
|
|
16
|
+
import './Configuration-fVpd-HC-.cjs';
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* PageManager, page-based LRU eviction + directional preloading.
|
|
20
|
+
*
|
|
21
|
+
* Groups document lines into fixed-size pages (128 lines each) and manages
|
|
22
|
+
* three temperature tiers:
|
|
23
|
+
* • Hot (viewport ± 3 pages): Keep bytecode + results
|
|
24
|
+
* • Warm (viewport ± 6 pages): Keep bytecode, evict results
|
|
25
|
+
* • Cold (beyond ± 6 pages): Evict bytecode + results (except variable defs)
|
|
26
|
+
*
|
|
27
|
+
* Variable definition bytecode is **never evicted** because it forms the
|
|
28
|
+
* backbone of the dependency graph and VM checkpoints.
|
|
29
|
+
*
|
|
30
|
+
* Preloading: When the user scrolls in a consistent direction, the next
|
|
31
|
+
* 1–2 pages are pre-compiled via the background worker so bytecode is
|
|
32
|
+
* cache-hot by the time those lines scroll into view.
|
|
33
|
+
*
|
|
34
|
+
* Usage:
|
|
35
|
+
* const pm = new PageManager();
|
|
36
|
+
* // After evaluation:
|
|
37
|
+
* pm.maintainAfterEval(viewport, doc);
|
|
38
|
+
* // After scroll (viewport-only change):
|
|
39
|
+
* pm.maintainAfterEval(viewport, doc);
|
|
40
|
+
* const targets = pm.getPreloadTargets(viewport, doc);
|
|
41
|
+
* // dispatch targets to compilation worker
|
|
42
|
+
*/
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Splits a long document into pages so only what is near the viewport is held
|
|
46
|
+
* in full.
|
|
47
|
+
*
|
|
48
|
+
* A document is edited constantly and most of it is off screen. Paging keeps
|
|
49
|
+
* the cost of a keystroke proportional to what is visible rather than to the
|
|
50
|
+
* length of the document.
|
|
51
|
+
*/
|
|
52
|
+
declare class PageManager {
|
|
53
|
+
/** Previous viewport for scroll direction detection. null = no previous viewport. */
|
|
54
|
+
private lastViewportStart;
|
|
55
|
+
/** Saved scroll direction from the most recent maintainAfterEval call. */
|
|
56
|
+
private savedDirection;
|
|
57
|
+
/** Per-page access counter for LRU tracking. */
|
|
58
|
+
private pageAccess;
|
|
59
|
+
/** Monotonically increasing access sequence number. */
|
|
60
|
+
private accessSeq;
|
|
61
|
+
/** Get the page number for a 1-based line number (0-based page index). */
|
|
62
|
+
static pageForLine(lineNumber: number): number;
|
|
63
|
+
/** Get the 1-based inclusive line range for a page. */
|
|
64
|
+
static pageRange(pageNum: number, docLineCount: number): {
|
|
65
|
+
startLine: number;
|
|
66
|
+
endLine: number;
|
|
67
|
+
};
|
|
68
|
+
/**
|
|
69
|
+
* Detect scroll direction from viewport movement.
|
|
70
|
+
* Returns null on first call (no previous viewport) or no movement.
|
|
71
|
+
*/
|
|
72
|
+
detectDirection(newViewport: {
|
|
73
|
+
startLine: number;
|
|
74
|
+
}): "down" | "up" | null;
|
|
75
|
+
/**
|
|
76
|
+
* Maintain page tiers after evaluation.
|
|
77
|
+
*
|
|
78
|
+
* 1. Records the new viewport position
|
|
79
|
+
* 2. Touches hot pages (viewport ± HOT_PAGE_RADIUS) for LRU
|
|
80
|
+
* 3. Evicts cold/warm pages based on distance from viewport
|
|
81
|
+
*
|
|
82
|
+
* Call this after every `evaluate()`, `setViewport()`, or `evaluateAll()`.
|
|
83
|
+
*/
|
|
84
|
+
maintainAfterEval(viewport: {
|
|
85
|
+
startLine: number;
|
|
86
|
+
endLine: number;
|
|
87
|
+
}, doc: DocumentModel): void;
|
|
88
|
+
/**
|
|
89
|
+
* Get lines ahead of the viewport that should be pre-compiled.
|
|
90
|
+
*
|
|
91
|
+
* Looks PRELOAD_PAGE_COUNT pages ahead of the current scroll direction.
|
|
92
|
+
* Only returns lines that are dirty, don't already have bytecode,
|
|
93
|
+
* and are not empty/markdown-only.
|
|
94
|
+
*
|
|
95
|
+
* @param viewport The current viewport.
|
|
96
|
+
* @param doc The document model.
|
|
97
|
+
* @returns Items ready to send to the compilation worker.
|
|
98
|
+
*/
|
|
99
|
+
getPreloadTargets(viewport: {
|
|
100
|
+
startLine: number;
|
|
101
|
+
endLine: number;
|
|
102
|
+
}, doc: DocumentModel): Array<{
|
|
103
|
+
lineId: number;
|
|
104
|
+
expression: string;
|
|
105
|
+
textHash: number;
|
|
106
|
+
}>;
|
|
107
|
+
/**
|
|
108
|
+
* Reset internal state (e.g., after document switch).
|
|
109
|
+
*/
|
|
110
|
+
clear(): void;
|
|
111
|
+
/** Record a page access with a monotonic sequence number. */
|
|
112
|
+
private touchPage;
|
|
113
|
+
/**
|
|
114
|
+
* Evict results from all non-variable-def lines in a page.
|
|
115
|
+
* Bytecode is preserved so Tier 2 execution works on scroll-back.
|
|
116
|
+
*/
|
|
117
|
+
private evictPageResults;
|
|
118
|
+
/**
|
|
119
|
+
* Evict bytecode + results from all non-variable-def lines in a page.
|
|
120
|
+
* Variable definition bytecode is **never** evicted, it forms the
|
|
121
|
+
* backbone of the DAG and VM checkpoints.
|
|
122
|
+
*
|
|
123
|
+
* Evicted lines are marked dirty so they get Tier 1 re-evaluation
|
|
124
|
+
* when scrolled back into view.
|
|
125
|
+
*/
|
|
126
|
+
private evictPageBytecode;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* How much work a line's evaluation required.
|
|
131
|
+
*
|
|
132
|
+
* The tiers exist because most lines in a document have not changed. A line
|
|
133
|
+
* that is clean and cached costs far less than one being compiled fresh, and
|
|
134
|
+
* knowing which happened is how a slow document gets diagnosed.
|
|
135
|
+
*/
|
|
136
|
+
declare enum EvalTier {
|
|
137
|
+
/** Full pipeline: Lex → Parse → Compile → Execute (visible + dirty). */
|
|
138
|
+
Tier1 = 1,
|
|
139
|
+
/** Execute-only from cached bytecode (visible + cached). */
|
|
140
|
+
Tier2 = 2,
|
|
141
|
+
/** Compile-only for dependency tracking (invisible). Executes only variable assignments. */
|
|
142
|
+
Tier3 = 3,
|
|
143
|
+
/** Skipped, already clean or non-evaluable. */
|
|
144
|
+
Skipped = 0
|
|
145
|
+
}
|
|
146
|
+
/** Outcome for one line, including which tier handled it. */
|
|
147
|
+
interface EvalLineResult {
|
|
148
|
+
/** The line's persistent ID from DocumentModel. */
|
|
149
|
+
lineId: number;
|
|
150
|
+
/** 1-based line position. */
|
|
151
|
+
lineNumber: number;
|
|
152
|
+
/** Which tier was used. */
|
|
153
|
+
tier: EvalTier;
|
|
154
|
+
/** The first evaluation result, or null on error / non-evaluable. */
|
|
155
|
+
result: Value | null;
|
|
156
|
+
/** All result groups (one per expression/inline-solve), or undefined if skipped. */
|
|
157
|
+
results?: Value[][];
|
|
158
|
+
/** Error message, or null. */
|
|
159
|
+
error: string | null;
|
|
160
|
+
}
|
|
161
|
+
/** Outcome for a whole evaluation pass, with per-tier counts. */
|
|
162
|
+
interface EvalResult {
|
|
163
|
+
/** Per-line evaluation results. */
|
|
164
|
+
lines: EvalLineResult[];
|
|
165
|
+
/** Map of line numbers → flattened results for quick lookup. */
|
|
166
|
+
resultMap: Map<number, Value[]>;
|
|
167
|
+
/** Number of lines processed at each tier. */
|
|
168
|
+
tierCounts: {
|
|
169
|
+
tier1: number;
|
|
170
|
+
tier2: number;
|
|
171
|
+
tier3: number;
|
|
172
|
+
skipped: number;
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Orchestrates three-tier evaluation over a persistent DocumentModel.
|
|
177
|
+
*
|
|
178
|
+
* ── Tier assignment ─────────────────────────────────────────────────
|
|
179
|
+
* | Tier | Condition | Action |
|
|
180
|
+
* |───────|────────────────────────────────────|───────────────────────────────|
|
|
181
|
+
* | **1** | Visible + Dirty (new/changed) | Full pipeline: lex→parse→compile→execute |
|
|
182
|
+
* | **2** | Visible + Cached (scroll into view)| Execute from cached bytecode |
|
|
183
|
+
* | **3** | Invisible + Dirty | Compile-only; execute only variable defs |
|
|
184
|
+
* | Skip | Clean, empty, or non-evaluable | No action |
|
|
185
|
+
*
|
|
186
|
+
* ── Evaluation order ─────────────────────────────────────────────────
|
|
187
|
+
* Lines are always processed in ascending document order (line 1 → end)
|
|
188
|
+
* so that variable assignments flow correctly through the shared VM.
|
|
189
|
+
* Tier 2 relies on this: by the time a clean cached line is reached,
|
|
190
|
+
* the VM already contains all variables from preceding Tier-1 lines.
|
|
191
|
+
*
|
|
192
|
+
* ── Thread safety ────────────────────────────────────────────────────
|
|
193
|
+
* Tier 1 (visible+dirty) compilation runs synchronously on the main thread
|
|
194
|
+
* for immediate rendering. Tier 3 (invisible+dirty) compilation can be
|
|
195
|
+
* dispatched to a Web Worker via `dispatchBackgroundCompiles()`. Worker-
|
|
196
|
+
* compiled bytecode is stored in the DocumentModel and validated via
|
|
197
|
+
* `isBytecodeValid()` to ensure the line text hasn't changed between
|
|
198
|
+
* dispatch and response.
|
|
199
|
+
*/
|
|
200
|
+
declare class ThreeTierEvaluator {
|
|
201
|
+
private doc;
|
|
202
|
+
private engine;
|
|
203
|
+
private dag;
|
|
204
|
+
private checkpointer;
|
|
205
|
+
private compilationWorker;
|
|
206
|
+
private pageManager;
|
|
207
|
+
/**
|
|
208
|
+
* Unsubscribe from sharedGlobalVariableStore, set in the constructor
|
|
209
|
+
* called from terminateWorker(). See the subscription itself below for
|
|
210
|
+
* why this only marks lines dirty and never re-evaluates synchronously.
|
|
211
|
+
*/
|
|
212
|
+
private globalUnsubscribe;
|
|
213
|
+
/**
|
|
214
|
+
* @param doc The persistent document model.
|
|
215
|
+
* @param engine The expression engine (shared VM is accessed via engine.getVM()).
|
|
216
|
+
* @param checkpointer Optional VM state checkpointer. If provided, the evaluator
|
|
217
|
+
* will create checkpoints after variable-definition lines and support fast VM
|
|
218
|
+
* restoration via `restoreTo()`. If omitted, checkpointing is disabled.
|
|
219
|
+
*/
|
|
220
|
+
constructor(doc: DocumentModel, engine: ExpressionEngine, checkpointer?: VMCheckpointer);
|
|
221
|
+
/**
|
|
222
|
+
* Evaluate all lines needed to render the given viewport.
|
|
223
|
+
*
|
|
224
|
+
* Processes lines from 1 to `viewport.endLine` in document order.
|
|
225
|
+
* Dirty lines in the viewport get Tier-1 full pipeline; clean cached
|
|
226
|
+
* lines get Tier-2 bytecode execution. Lines after the viewport
|
|
227
|
+
* get Tier-3 compile-only (with variable-def execution).
|
|
228
|
+
*
|
|
229
|
+
* @returns Results for all processed lines, including tier metadata.
|
|
230
|
+
*/
|
|
231
|
+
evaluate(viewport: ViewportRange, signal?: AbortSignal): EvalResult;
|
|
232
|
+
/**
|
|
233
|
+
* Background-compile invisible dirty lines beyond the viewport (Tier 3 only).
|
|
234
|
+
*
|
|
235
|
+
* Compiles expressions to discover reads/writes for the dependency graph
|
|
236
|
+
* without executing display-only expressions. Variable definitions are
|
|
237
|
+
* executed to maintain VM state for future Tier-2 executions.
|
|
238
|
+
*
|
|
239
|
+
* This is intended to be called after evaluate() so visible lines are
|
|
240
|
+
* rendered first, then background work fills in the dependency graph.
|
|
241
|
+
*
|
|
242
|
+
* **Phase 5.2h:** This synchronous method is retained for environments
|
|
243
|
+
* without Worker support. Prefer `dispatchBackgroundCompiles()` which
|
|
244
|
+
* offloads compilation to a Web Worker with Transferable bytecode.
|
|
245
|
+
*/
|
|
246
|
+
backgroundCompile(viewport: ViewportRange): EvalLineResult[];
|
|
247
|
+
/**
|
|
248
|
+
* Dispatch background compilation to a Web Worker (Phase 5.2h).
|
|
249
|
+
*
|
|
250
|
+
* Collects invisible dirty lines beyond the viewport that need compilation,
|
|
251
|
+
* sends them to the compilation worker, and asynchronously stores the
|
|
252
|
+
* transferred bytecode in the DocumentModel when the worker responds.
|
|
253
|
+
*
|
|
254
|
+
* This is the non-blocking alternative to `backgroundCompile()`. The worker
|
|
255
|
+
* compiles expressions with Transferable ArrayBuffers (zero-copy postMessage),
|
|
256
|
+
* so bytecode appears on the main thread without serialization overhead.
|
|
257
|
+
*
|
|
258
|
+
* Lines that already have cached bytecode (from a previous worker pass or
|
|
259
|
+
* synchronous compile) are skipped, only truly uncompiled dirty lines are
|
|
260
|
+
* sent to the worker.
|
|
261
|
+
*
|
|
262
|
+
* **Usage:** Call after `evaluate()` so visible lines render first, then
|
|
263
|
+
* this fills the bytecode cache for future Tier-2 scrolls.
|
|
264
|
+
*
|
|
265
|
+
* @param viewport The current visible range. Lines beyond viewport.endLine
|
|
266
|
+
* that are dirty and don't have bytecode are dispatched.
|
|
267
|
+
*/
|
|
268
|
+
dispatchBackgroundCompiles(viewport: ViewportRange): void;
|
|
269
|
+
/**
|
|
270
|
+
* Terminate the compilation worker if active, and unsubscribe from
|
|
271
|
+
* sharedGlobalVariableStore. Call this when the evaluator is no longer
|
|
272
|
+
* needed to clean up resources, every call site that retires a
|
|
273
|
+
* ThreeTierEvaluator (document switch, pane destroy()) already calls
|
|
274
|
+
* this unconditionally, so folding the global-store unsubscribe in here
|
|
275
|
+
* needs no new call sites anywhere.
|
|
276
|
+
*/
|
|
277
|
+
terminateWorker(): void;
|
|
278
|
+
/**
|
|
279
|
+
* Get the DocumentModel (read-only access for decoration building).
|
|
280
|
+
*/
|
|
281
|
+
getDoc(): DocumentModel;
|
|
282
|
+
/**
|
|
283
|
+
* Evaluate all dirty lines in the document, regardless of viewport.
|
|
284
|
+
* Used for full re-evaluation after plugin register/unregister.
|
|
285
|
+
*/
|
|
286
|
+
evaluateAll(signal?: AbortSignal): EvalResult;
|
|
287
|
+
/**
|
|
288
|
+
* Zero-allocation viewport evaluation, the Phase 5.2e "holy grail."
|
|
289
|
+
*
|
|
290
|
+
* **Key insight:** When the user scrolls (viewport-only change, no edits),
|
|
291
|
+
* we don't need to re-evaluate from line 1. Instead:
|
|
292
|
+
*
|
|
293
|
+
* 1. Restore the VM to just before the viewport via the nearest checkpoint.
|
|
294
|
+
* 2. Evaluate ONLY the visible lines (Tier 2 for clean cached, Tier 1 for dirty).
|
|
295
|
+
* 3. Lines before the viewport are completely skipped, their state lives in
|
|
296
|
+
* the VM checkpointer's prototypal chain.
|
|
297
|
+
*
|
|
298
|
+
* **Correctness guard:** If any variable-definition line before the viewport
|
|
299
|
+
* is dirty (e.g., the user edited a variable def that hasn't been
|
|
300
|
+
* re-evaluated yet), we clear stale checkpoints and fall back to `evaluate()`
|
|
301
|
+
* which processes from line 1 and rebuilds fresh checkpoints. This
|
|
302
|
+
* guarantees that stale checkpoints are never used as restoration targets.
|
|
303
|
+
* Only variable-def lines matter here, `VMCheckpointer.snapshot()` only
|
|
304
|
+
* records state for lines that write a variable, so a dirty plain-expression
|
|
305
|
+
* line before the viewport has no checkpoint to invalidate (see
|
|
306
|
+
* `DocumentModel.hasAnyDirtyVariableDefLineBefore()`).
|
|
307
|
+
*
|
|
308
|
+
* **Performance:** O(visible lines) instead of O(document length). Target:
|
|
309
|
+
* < 1ms for a typical ~30-line viewport, independent of document size.
|
|
310
|
+
*
|
|
311
|
+
* @param viewport The visible line range.
|
|
312
|
+
* @returns Results for visible lines only. Lines before the viewport are
|
|
313
|
+
* not included in `lines[]` or `resultMap`.
|
|
314
|
+
*/
|
|
315
|
+
setViewport(viewport: ViewportRange, signal?: AbortSignal): EvalResult;
|
|
316
|
+
/**
|
|
317
|
+
* Apply incremental line-level changes to the document model.
|
|
318
|
+
*
|
|
319
|
+
* **Phase 5.2f:** Replaces the O(N) `setDocument()` + full re-evaluation
|
|
320
|
+
* with O(changed) incremental updates. Key benefits:
|
|
321
|
+
*
|
|
322
|
+
* 1. Unchanged lines retain their persistent lineIds → bytecode survives
|
|
323
|
+
* 2. Only changed + DAG-downstream lines are marked dirty → Tier 1 re-evaluation
|
|
324
|
+
* 3. Clean lines in viewport use Tier 2 (cached bytecode execution)
|
|
325
|
+
* 4. Clean lines outside viewport are skipped entirely
|
|
326
|
+
*
|
|
327
|
+
* The DAG is fully cleared after propagation: shifted lines would have
|
|
328
|
+
* stale entries keyed by old line numbers, so the DAG is rebuilt from
|
|
329
|
+
* scratch during the subsequent `evaluate()` call.
|
|
330
|
+
*
|
|
331
|
+
* **Caller should follow up with `evaluate(viewport)`** to re-evaluate
|
|
332
|
+
* dirty lines from line 1 and rebuild the DAG + checkpoints.
|
|
333
|
+
*
|
|
334
|
+
* @param changes Line-level changes to apply. Must be non-overlapping.
|
|
335
|
+
* @returns Metadata about the applied changes.
|
|
336
|
+
*/
|
|
337
|
+
applyTransaction(changes: LineChange[]): {
|
|
338
|
+
inserted: number[];
|
|
339
|
+
removed: number[];
|
|
340
|
+
};
|
|
341
|
+
/**
|
|
342
|
+
* Collect evaluation results for a contiguous range of lines.
|
|
343
|
+
*
|
|
344
|
+
* Used by both `evaluate()` (startLine=1) and `setViewport()` (any start).
|
|
345
|
+
* All lines in the range are treated as in-viewport (visible), callers that
|
|
346
|
+
* need the invisible/dirty → Tier 3 handling should use `evaluate()` instead.
|
|
347
|
+
*
|
|
348
|
+
* @param startLine First line to evaluate (1-based, inclusive).
|
|
349
|
+
* @param endLine Last line to evaluate (1-based, inclusive). Clamped to docEnd.
|
|
350
|
+
*/
|
|
351
|
+
private collectEvalResults;
|
|
352
|
+
/**
|
|
353
|
+
* Check whether any **variable-definition** line before `position`
|
|
354
|
+
* (1-based, exclusive) is dirty.
|
|
355
|
+
*
|
|
356
|
+
* Used by `setViewport()` to decide whether to fall back to `evaluate()`:
|
|
357
|
+
* if a variable-def before the viewport is dirty, the checkpoint state
|
|
358
|
+
* `restoreTo()` would use may be stale and we need to reprocess from
|
|
359
|
+
* line 1 to rebuild checkpoints correctly.
|
|
360
|
+
*
|
|
361
|
+
* Deliberately narrower than `DocumentModel.hasAnyDirtyLineBefore()`:
|
|
362
|
+
* checkpoints only snapshot variable-def lines (see VMCheckpointer), so a
|
|
363
|
+
* dirty plain-expression line before the viewport can't have invalidated
|
|
364
|
+
* one, there's nothing checkpointed for it to invalidate. Using the
|
|
365
|
+
* broader check here previously caused a real perf bug: `PageManager`'s
|
|
366
|
+
* cold-page eviction marks evicted non-variable-def lines dirty, so
|
|
367
|
+
* scrolling far into a large, variable-def-free document would trip this
|
|
368
|
+
* guard, fall back to `evaluate()`, which recompiles those lines via
|
|
369
|
+
* Tier 3 (never clearing their dirty flag by design), causing the very
|
|
370
|
+
* next `maintainAfterEval()` to re-evict and re-dirty them, a
|
|
371
|
+
* self-sustaining loop that pinned every subsequent `setViewport()` call
|
|
372
|
+
* to the cost of a full re-evaluation instead of O(visible lines).
|
|
373
|
+
*
|
|
374
|
+
* Delegates to DocumentModel.hasAnyDirtyVariableDefLineBefore(), which
|
|
375
|
+
* tracks dirty lineIds incrementally instead of scanning every line up to
|
|
376
|
+
* `position` on every call. This used to be a real per-scroll cost
|
|
377
|
+
* (benchmarked at ~10ms scrolled near the bottom of a 20k-line document)
|
|
378
|
+
* since it fired on every viewport change, not just edits.
|
|
379
|
+
*/
|
|
380
|
+
private hasDirtyLinesBefore;
|
|
381
|
+
/**
|
|
382
|
+
* Evaluate a single line using the appropriate tier.
|
|
383
|
+
*
|
|
384
|
+
* Tier assignment logic:
|
|
385
|
+
* - Empty/markdown-only lines → skipped
|
|
386
|
+
* - Dirty + in-viewport → Tier 1 (full pipeline)
|
|
387
|
+
* - Dirty + not in viewport → Tier 3 (compile-only, execute variable defs)
|
|
388
|
+
* - Clean + has bytecode + in viewport → Tier 2 (execute from cache)
|
|
389
|
+
* - Clean + no bytecode → skipped (non-evaluable)
|
|
390
|
+
*/
|
|
391
|
+
private evaluateSingleLine;
|
|
392
|
+
/**
|
|
393
|
+
* Tier 1: Full pipeline, lex, parse, compile, execute.
|
|
394
|
+
* Uses the engine's existing evaluateLine() which handles all pipeline
|
|
395
|
+
* stages including DAG updates and LineCache population.
|
|
396
|
+
*
|
|
397
|
+
* Supports multiple expressions per line (inline solves). Evaluates each
|
|
398
|
+
* expression left-to-right through the engine so variable definitions in
|
|
399
|
+
* earlier solves update the VM state before later solves are evaluated.
|
|
400
|
+
* Reads/writes are aggregated across all expressions for the DAG.
|
|
401
|
+
*/
|
|
402
|
+
private evaluateTier1;
|
|
403
|
+
/**
|
|
404
|
+
* Tier 2: Execute from cached bytecode only.
|
|
405
|
+
* Skips lexing, parsing, and compiling, runs the pre-compiled bytecode
|
|
406
|
+
* against the engine's shared VM. Supports multiple bytecodes per line
|
|
407
|
+
* (inline solves), each is executed left-to-right so variable definitions
|
|
408
|
+
* in earlier bytecodes update the VM before later ones run.
|
|
409
|
+
* Assumes the VM already has correct variable state from preceding
|
|
410
|
+
* Tier-1 evaluations.
|
|
411
|
+
*/
|
|
412
|
+
private evaluateTier2;
|
|
413
|
+
/**
|
|
414
|
+
* Tier 3: Compile-only for invisible lines.
|
|
415
|
+
* Lex → Parse → Compile to discover reads/writes for the dependency graph.
|
|
416
|
+
* Executes the bytecode ONLY if the line defines a variable (isVariableDef
|
|
417
|
+
* or writes.length > 0), because variable assignments affect VM state
|
|
418
|
+
* that other lines depend on. Pure expression lines are compiled but NOT
|
|
419
|
+
* executed, saving CPU for large documents.
|
|
420
|
+
*
|
|
421
|
+
* Supports multiple expressions per line (inline solves). Each is compiled
|
|
422
|
+
* separately; variable-def expressions are also executed.
|
|
423
|
+
*/
|
|
424
|
+
private evaluateTier3;
|
|
425
|
+
/**
|
|
426
|
+
* Restore the VM to the state at or just after the given line number.
|
|
427
|
+
*
|
|
428
|
+
* Finds the nearest checkpoint at or before `lineNumber` and replays
|
|
429
|
+
* all variable definitions from the checkpoint chain into the VM.
|
|
430
|
+
* After calling this, the VM is ready to evaluate lines starting at
|
|
431
|
+
* `lineNumber + 1` without re-evaluating all preceding lines.
|
|
432
|
+
*
|
|
433
|
+
* **Usage:** Phase 5.2e's `setViewport()` calls `restoreTo(viewport.startLine - 1)`
|
|
434
|
+
* before evaluating only the newly visible lines. This is the key to
|
|
435
|
+
* O(visible lines) scrolling.
|
|
436
|
+
*
|
|
437
|
+
* @param lineNumber The line number to restore to. Variables defined
|
|
438
|
+
* at lines ≤ this number will be available in the VM.
|
|
439
|
+
*/
|
|
440
|
+
restoreTo(lineNumber: number): void;
|
|
441
|
+
/**
|
|
442
|
+
* Get the VM checkpointer, or null if checkpointing is disabled.
|
|
443
|
+
*/
|
|
444
|
+
getCheckpointer(): VMCheckpointer | null;
|
|
445
|
+
/**
|
|
446
|
+
* Get the PageManager (Phase 5.2g).
|
|
447
|
+
* Exposed for testing.
|
|
448
|
+
*/
|
|
449
|
+
getPageManager(): PageManager;
|
|
450
|
+
/**
|
|
451
|
+
* Preload the next 1–2 pages in the current scroll direction.
|
|
452
|
+
*
|
|
453
|
+
* Called during `setViewport()` (scroll-only path). Collects dirty
|
|
454
|
+
* uncompiled lines in pages just beyond the viewport and dispatches
|
|
455
|
+
* them to the background compilation worker so bytecode is ready
|
|
456
|
+
* before the user scrolls those lines into view.
|
|
457
|
+
*/
|
|
458
|
+
private preloadNextPages;
|
|
459
|
+
/**
|
|
460
|
+
* Collect invisible dirty lines that need background compilation.
|
|
461
|
+
*
|
|
462
|
+
* Iterates lines beyond `viewport.endLine`, filtering for:
|
|
463
|
+
* - Dirty lines (need re-compilation)
|
|
464
|
+
* - Non-empty, non-markdown lines
|
|
465
|
+
* - No existing bytecode (skip already-compiled Tier 3 lines)
|
|
466
|
+
*
|
|
467
|
+
* Returns CompileRequestItem[] suitable for CompilationWorkerManager.
|
|
468
|
+
*/
|
|
469
|
+
private collectInvisibleCompileTargets;
|
|
470
|
+
/**
|
|
471
|
+
* Extract all evaluable expressions from a LineState.
|
|
472
|
+
*
|
|
473
|
+
* For full-line expressions: returns `{ expressions: [trimmedText], inlineSolveCount: 0 }`.
|
|
474
|
+
* For inline solve lines: returns `{ expressions: [...allSolves], inlineSolveCount: N }`.
|
|
475
|
+
* For pre-extracted (cached) expressions: returns the cached array.
|
|
476
|
+
*
|
|
477
|
+
* Inline solves are extracted left-to-right via the sharedLexer, so variable
|
|
478
|
+
* definitions in earlier solves (e.g., `s\`x = 5\` more text s\`x + 1\``)
|
|
479
|
+
* correctly update the VM state before later solves are evaluated.
|
|
480
|
+
*/
|
|
481
|
+
private extractExpressions;
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
/** Bounds applied to input before parsing: length and nesting depth. */
|
|
485
|
+
interface ValidationConfig {
|
|
486
|
+
maxExpressionLength: number;
|
|
487
|
+
maxComplexity: number;
|
|
488
|
+
}
|
|
489
|
+
/** Whether input passed the safety bounds, and which one it failed. */
|
|
490
|
+
interface SafetyCheckResult {
|
|
491
|
+
passed: boolean;
|
|
492
|
+
/**
|
|
493
|
+
* `error.error` (a plain string) exists purely because it's spread
|
|
494
|
+
* directly into `evaluateExpressionWithDiagnostic()`'s own return shape
|
|
495
|
+
* (`{value, tokens, program, error?: string, ...}`), which deliberately
|
|
496
|
+
* keeps errors as display strings for the debug/diagnostic pipeline
|
|
497
|
+
* see that method's own doc comment. `error.engineError` is additive
|
|
498
|
+
* (doesn't replace the string field, so existing consumers of this
|
|
499
|
+
* exported type are unaffected): it carries the real EngineError this
|
|
500
|
+
* check constructed internally, so callers that DO want the original
|
|
501
|
+
* code/category/expected/found/suggestion (prepareExpression(), not the
|
|
502
|
+
* diagnostic pipeline) don't have to reconstruct a generic one from just
|
|
503
|
+
* the flattened message.
|
|
504
|
+
*/
|
|
505
|
+
error?: {
|
|
506
|
+
value: Value;
|
|
507
|
+
tokens: Token[];
|
|
508
|
+
program: BytecodeProgram;
|
|
509
|
+
error: string;
|
|
510
|
+
engineError?: EngineError;
|
|
511
|
+
};
|
|
512
|
+
}
|
|
513
|
+
/**
|
|
514
|
+
* Check that the expression doesn't exceed the maximum allowed length.
|
|
515
|
+
*/
|
|
516
|
+
declare function checkExpressionLength(expression: string, config: ValidationConfig): SafetyCheckResult;
|
|
517
|
+
/**
|
|
518
|
+
* Score expression complexity based on token count, function calls, and nesting depth.
|
|
519
|
+
* Returns the complexity score and whether it exceeds the configured maximum.
|
|
520
|
+
*/
|
|
521
|
+
declare function checkExpressionComplexity(tokens: Token[], config: ValidationConfig): {
|
|
522
|
+
passed: boolean;
|
|
523
|
+
complexityScore: number;
|
|
524
|
+
errorMessage?: string;
|
|
525
|
+
engineError?: EngineError;
|
|
526
|
+
};
|
|
527
|
+
/**
|
|
528
|
+
* Extract variable reads and writes from a token stream.
|
|
529
|
+
*
|
|
530
|
+
* Handles both IDENT and UNIT tokens as potential variable references.
|
|
531
|
+
* UNIT tokens occur when the variable name collides with a known unit
|
|
532
|
+
* (e.g., "b" for bits, "s" for seconds). The colon prefix unambiguously
|
|
533
|
+
* signals a variable definition context (handled by VariableParselet).
|
|
534
|
+
* A standalone UNIT token is only a real variable reference when it
|
|
535
|
+
* isn't in unit-literal position (see {@link isUnitLiteralContext})
|
|
536
|
+
* otherwise it's a quantity/conversion unit name, never LOAD_VAR'd.
|
|
537
|
+
*
|
|
538
|
+
* Also detects user-defined-function DEFINITIONS (`name(params) = body`)
|
|
539
|
+
* as a read+write of the function's own name, mirroring `:name = value`'s
|
|
540
|
+
* existing convention of registering the defined name as both, and
|
|
541
|
+
* excludes the definition's own PARAMETER names from reads/writes
|
|
542
|
+
* entirely (see {@link collectFunctionParamNames}). A function CALL
|
|
543
|
+
* (`name(args)`, no trailing `=`) needs no special detection: the call's
|
|
544
|
+
* own name falls through to the ordinary bare-identifier read-tracking
|
|
545
|
+
* below, the same as any other `LOAD_VAR`-producing identifier. This is
|
|
546
|
+
* already correct once calls compile successfully, no change needed.
|
|
547
|
+
*/
|
|
548
|
+
declare function extractReadsAndWrites(tokens: Token[]): {
|
|
549
|
+
reads: string[];
|
|
550
|
+
writes: string[];
|
|
551
|
+
};
|
|
552
|
+
/**
|
|
553
|
+
* Check if a line is effectively empty (whitespace only or only markdown syntax).
|
|
554
|
+
*
|
|
555
|
+
* Phase B: Delegates to the ExpressionLexer's character-by-character
|
|
556
|
+
* markdown line scanner, replacing the old regex-based heuristics.
|
|
557
|
+
*
|
|
558
|
+
* Skips lines that contain no evaluable expression:
|
|
559
|
+
* - Whitespace-only lines
|
|
560
|
+
* - Markdown structural markers (headings, blockquotes, lists without inline solves)
|
|
561
|
+
* - Code block fences (```)
|
|
562
|
+
* - MathJax block fences ($$)
|
|
563
|
+
* - Table separator rows (|---|)
|
|
564
|
+
* - Horizontal rules (---, ***, ___)
|
|
565
|
+
* - Standalone wikilinks / embeds ([[...]], ![[...]])
|
|
566
|
+
* - Whole-line comments (a line whose first non-whitespace characters are `//`)
|
|
567
|
+
*
|
|
568
|
+
* Lines containing inline solves (s\`...\`) are never considered empty.
|
|
569
|
+
*
|
|
570
|
+
* Note: a trailing `#`/`//` comment in the MIDDLE of an otherwise-evaluable
|
|
571
|
+
* line does NOT make isEmptyLine() return true, that line is still an
|
|
572
|
+
* "expression" line (skip: false). The comment is instead stripped at
|
|
573
|
+
* tokenization time (ExpressionLexer's HASH/`//` handling emits a COMMENT
|
|
574
|
+
* token for the rest of the line) and then filtered out of the token
|
|
575
|
+
* stream by ExpressionEngine.prepareExpression() before parsing, so
|
|
576
|
+
* `<expr> // note` evaluates identically to `<expr>` alone.
|
|
577
|
+
*/
|
|
578
|
+
declare function isEmptyLine(lineText: string): boolean;
|
|
579
|
+
/**
|
|
580
|
+
* Find all inline solves in a line with precise coordinate mapping.
|
|
581
|
+
*
|
|
582
|
+
* Phase B: Delegates to the ExpressionLexer's character-by-character
|
|
583
|
+
* scanner (no regex, handles escaped backticks).
|
|
584
|
+
*/
|
|
585
|
+
declare function findInlineSolvesInLine(lineText: string, lineNumber: number): InlineSolvePosition[];
|
|
586
|
+
|
|
587
|
+
export { DocumentModel, type EvalLineResult, type EvalResult, EvalTier, ExpressionEngine, InlineSolvePosition, LineChange, type SafetyCheckResult, ThreeTierEvaluator, type ValidationConfig, ViewportRange, checkExpressionComplexity, checkExpressionLength, extractReadsAndWrites, findInlineSolvesInLine, isEmptyLine };
|