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.
Files changed (253) hide show
  1. package/dist/BytecodeBuilder-3egMyuDi.d.cts +274 -0
  2. package/dist/BytecodeBuilder-3egMyuDi.d.ts +274 -0
  3. package/dist/Configuration-fVpd-HC-.d.cts +228 -0
  4. package/dist/Configuration-fVpd-HC-.d.ts +228 -0
  5. package/dist/EngineError-DvPSnhZi.d.cts +304 -0
  6. package/dist/EngineError-DvPSnhZi.d.ts +304 -0
  7. package/dist/Lexer-BJdhlnej.d.cts +531 -0
  8. package/dist/Lexer-D9l4Yrk2.d.ts +531 -0
  9. package/dist/NormalizerRule-BrVoVjmP.d.cts +163 -0
  10. package/dist/NormalizerRule-CEjf1FyD.d.ts +163 -0
  11. package/dist/PackageRegistry-D-Tv_7ca.d.cts +2572 -0
  12. package/dist/PackageRegistry-DaH4aIKP.d.ts +2572 -0
  13. package/dist/Parselet-CK8cQu2a.d.cts +299 -0
  14. package/dist/Parselet-ConOIdRO.d.ts +299 -0
  15. package/dist/ScopeManager-B5k0nk05.d.ts +559 -0
  16. package/dist/ScopeManager-CKfQtl7l.d.cts +559 -0
  17. package/dist/Token-0jpvUdPY.d.cts +245 -0
  18. package/dist/Token-0jpvUdPY.d.ts +245 -0
  19. package/dist/VMCheckpoints-BmDwIXgK.d.ts +171 -0
  20. package/dist/VMCheckpoints-CqFuLwrT.d.cts +171 -0
  21. package/dist/Value-KtAQNHur.d.cts +295 -0
  22. package/dist/Value-KtAQNHur.d.ts +295 -0
  23. package/dist/chunk-2RWAXT6O.js +3 -0
  24. package/dist/chunk-2RWAXT6O.js.map +1 -0
  25. package/dist/chunk-34RRD7PC.js +1492 -0
  26. package/dist/chunk-34RRD7PC.js.map +1 -0
  27. package/dist/chunk-3PPFLFH4.js +5097 -0
  28. package/dist/chunk-3PPFLFH4.js.map +1 -0
  29. package/dist/chunk-3VGDNEE3.js +84 -0
  30. package/dist/chunk-3VGDNEE3.js.map +1 -0
  31. package/dist/chunk-3YNVWKR2.cjs +370 -0
  32. package/dist/chunk-3YNVWKR2.cjs.map +1 -0
  33. package/dist/chunk-47LRVGOT.cjs +316 -0
  34. package/dist/chunk-47LRVGOT.cjs.map +1 -0
  35. package/dist/chunk-4MG4XKO2.js +1644 -0
  36. package/dist/chunk-4MG4XKO2.js.map +1 -0
  37. package/dist/chunk-4QADQTWS.js +2392 -0
  38. package/dist/chunk-4QADQTWS.js.map +1 -0
  39. package/dist/chunk-53B6KDDJ.cjs +1651 -0
  40. package/dist/chunk-53B6KDDJ.cjs.map +1 -0
  41. package/dist/chunk-5X2PTP6F.cjs +104 -0
  42. package/dist/chunk-5X2PTP6F.cjs.map +1 -0
  43. package/dist/chunk-5YEMOYSE.js +264 -0
  44. package/dist/chunk-5YEMOYSE.js.map +1 -0
  45. package/dist/chunk-64W6GLLZ.js +481 -0
  46. package/dist/chunk-64W6GLLZ.js.map +1 -0
  47. package/dist/chunk-6BKTCEUP.cjs +233 -0
  48. package/dist/chunk-6BKTCEUP.cjs.map +1 -0
  49. package/dist/chunk-6NTVRDQV.cjs +1642 -0
  50. package/dist/chunk-6NTVRDQV.cjs.map +1 -0
  51. package/dist/chunk-6RDSQURE.js +290 -0
  52. package/dist/chunk-6RDSQURE.js.map +1 -0
  53. package/dist/chunk-75JP4BZX.js +93 -0
  54. package/dist/chunk-75JP4BZX.js.map +1 -0
  55. package/dist/chunk-B7LXJ6LC.cjs +36 -0
  56. package/dist/chunk-B7LXJ6LC.cjs.map +1 -0
  57. package/dist/chunk-BVAR5J2F.js +257 -0
  58. package/dist/chunk-BVAR5J2F.js.map +1 -0
  59. package/dist/chunk-C4XZV6E7.cjs +269 -0
  60. package/dist/chunk-C4XZV6E7.cjs.map +1 -0
  61. package/dist/chunk-CCJPSHGI.cjs +40 -0
  62. package/dist/chunk-CCJPSHGI.cjs.map +1 -0
  63. package/dist/chunk-CLL7RUQV.cjs +316 -0
  64. package/dist/chunk-CLL7RUQV.cjs.map +1 -0
  65. package/dist/chunk-DM3LMRBC.js +329 -0
  66. package/dist/chunk-DM3LMRBC.js.map +1 -0
  67. package/dist/chunk-DUEZFTK2.js +38 -0
  68. package/dist/chunk-DUEZFTK2.js.map +1 -0
  69. package/dist/chunk-EBSPLUW4.cjs +489 -0
  70. package/dist/chunk-EBSPLUW4.cjs.map +1 -0
  71. package/dist/chunk-EHAHVROS.cjs +261 -0
  72. package/dist/chunk-EHAHVROS.cjs.map +1 -0
  73. package/dist/chunk-EIGTWK5N.js +167 -0
  74. package/dist/chunk-EIGTWK5N.js.map +1 -0
  75. package/dist/chunk-EPOXXJBK.js +96 -0
  76. package/dist/chunk-EPOXXJBK.js.map +1 -0
  77. package/dist/chunk-FEAIOR7N.cjs +91 -0
  78. package/dist/chunk-FEAIOR7N.cjs.map +1 -0
  79. package/dist/chunk-G535KJEG.js +312 -0
  80. package/dist/chunk-G535KJEG.js.map +1 -0
  81. package/dist/chunk-GCM5JHMX.js +88 -0
  82. package/dist/chunk-GCM5JHMX.js.map +1 -0
  83. package/dist/chunk-GOLDJNMZ.js +368 -0
  84. package/dist/chunk-GOLDJNMZ.js.map +1 -0
  85. package/dist/chunk-GW32KPCU.cjs +360 -0
  86. package/dist/chunk-GW32KPCU.cjs.map +1 -0
  87. package/dist/chunk-HTXVVJRA.cjs +1549 -0
  88. package/dist/chunk-HTXVVJRA.cjs.map +1 -0
  89. package/dist/chunk-HWSZJQCI.js +311 -0
  90. package/dist/chunk-HWSZJQCI.js.map +1 -0
  91. package/dist/chunk-IF532O7C.js +101 -0
  92. package/dist/chunk-IF532O7C.js.map +1 -0
  93. package/dist/chunk-J73SJHR3.cjs +2415 -0
  94. package/dist/chunk-J73SJHR3.cjs.map +1 -0
  95. package/dist/chunk-JBSYC7BB.cjs +7473 -0
  96. package/dist/chunk-JBSYC7BB.cjs.map +1 -0
  97. package/dist/chunk-KVILKGMS.js +228 -0
  98. package/dist/chunk-KVILKGMS.js.map +1 -0
  99. package/dist/chunk-LIPPNDBE.js +258 -0
  100. package/dist/chunk-LIPPNDBE.js.map +1 -0
  101. package/dist/chunk-LR7YASZF.cjs +172 -0
  102. package/dist/chunk-LR7YASZF.cjs.map +1 -0
  103. package/dist/chunk-M4N5GA5Z.cjs +309 -0
  104. package/dist/chunk-M4N5GA5Z.cjs.map +1 -0
  105. package/dist/chunk-M5LX5AOO.js +7459 -0
  106. package/dist/chunk-M5LX5AOO.js.map +1 -0
  107. package/dist/chunk-MZOVP3WI.cjs +96 -0
  108. package/dist/chunk-MZOVP3WI.cjs.map +1 -0
  109. package/dist/chunk-N5YFR4UP.cjs +10 -0
  110. package/dist/chunk-N5YFR4UP.cjs.map +1 -0
  111. package/dist/chunk-NGBBNL4K.cjs +4 -0
  112. package/dist/chunk-NGBBNL4K.cjs.map +1 -0
  113. package/dist/chunk-NH2O2AUR.js +146 -0
  114. package/dist/chunk-NH2O2AUR.js.map +1 -0
  115. package/dist/chunk-NLNDMWZC.js +31 -0
  116. package/dist/chunk-NLNDMWZC.js.map +1 -0
  117. package/dist/chunk-NMCRQP3Z.cjs +778 -0
  118. package/dist/chunk-NMCRQP3Z.cjs.map +1 -0
  119. package/dist/chunk-NMD5VRN4.cjs +1327 -0
  120. package/dist/chunk-NMD5VRN4.cjs.map +1 -0
  121. package/dist/chunk-OC6LTXYS.cjs +286 -0
  122. package/dist/chunk-OC6LTXYS.cjs.map +1 -0
  123. package/dist/chunk-OT6OJY7C.cjs +114 -0
  124. package/dist/chunk-OT6OJY7C.cjs.map +1 -0
  125. package/dist/chunk-PFSDGGYL.js +8 -0
  126. package/dist/chunk-PFSDGGYL.js.map +1 -0
  127. package/dist/chunk-QNJ4ACRT.cjs +155 -0
  128. package/dist/chunk-QNJ4ACRT.cjs.map +1 -0
  129. package/dist/chunk-QWY3VEZN.js +1637 -0
  130. package/dist/chunk-QWY3VEZN.js.map +1 -0
  131. package/dist/chunk-RFYD5TJE.js +111 -0
  132. package/dist/chunk-RFYD5TJE.js.map +1 -0
  133. package/dist/chunk-RIN643A3.js +354 -0
  134. package/dist/chunk-RIN643A3.js.map +1 -0
  135. package/dist/chunk-RZCWSXTA.cjs +5122 -0
  136. package/dist/chunk-RZCWSXTA.cjs.map +1 -0
  137. package/dist/chunk-SDGRK7EP.js +774 -0
  138. package/dist/chunk-SDGRK7EP.js.map +1 -0
  139. package/dist/chunk-VEKIWQ3F.cjs +39 -0
  140. package/dist/chunk-VEKIWQ3F.cjs.map +1 -0
  141. package/dist/chunk-WQTTOGXC.cjs +99 -0
  142. package/dist/chunk-WQTTOGXC.cjs.map +1 -0
  143. package/dist/chunk-X6K3HUOY.cjs +86 -0
  144. package/dist/chunk-X6K3HUOY.cjs.map +1 -0
  145. package/dist/chunk-XJCMXB2E.cjs +333 -0
  146. package/dist/chunk-XJCMXB2E.cjs.map +1 -0
  147. package/dist/chunk-XVWCOTR6.js +1324 -0
  148. package/dist/chunk-XVWCOTR6.js.map +1 -0
  149. package/dist/chunk-YLJ4XMA6.js +33 -0
  150. package/dist/chunk-YLJ4XMA6.js.map +1 -0
  151. package/dist/chunk-Z2XP767T.cjs +35 -0
  152. package/dist/chunk-Z2XP767T.cjs.map +1 -0
  153. package/dist/chunk-Z4X2RWOF.js +37 -0
  154. package/dist/chunk-Z4X2RWOF.js.map +1 -0
  155. package/dist/constants.cjs +22 -0
  156. package/dist/constants.cjs.map +1 -0
  157. package/dist/constants.d.cts +12 -0
  158. package/dist/constants.d.ts +12 -0
  159. package/dist/constants.js +5 -0
  160. package/dist/constants.js.map +1 -0
  161. package/dist/engine.cjs +79 -0
  162. package/dist/engine.cjs.map +1 -0
  163. package/dist/engine.d.cts +587 -0
  164. package/dist/engine.d.ts +587 -0
  165. package/dist/engine.js +34 -0
  166. package/dist/engine.js.map +1 -0
  167. package/dist/errors.cjs +81 -0
  168. package/dist/errors.cjs.map +1 -0
  169. package/dist/errors.d.cts +95 -0
  170. package/dist/errors.d.ts +95 -0
  171. package/dist/errors.js +4 -0
  172. package/dist/errors.js.map +1 -0
  173. package/dist/format.cjs +171 -0
  174. package/dist/format.cjs.map +1 -0
  175. package/dist/format.d.cts +51 -0
  176. package/dist/format.d.ts +51 -0
  177. package/dist/format.js +168 -0
  178. package/dist/format.js.map +1 -0
  179. package/dist/index.cjs +97 -0
  180. package/dist/index.cjs.map +1 -0
  181. package/dist/index.d.cts +152 -0
  182. package/dist/index.d.ts +152 -0
  183. package/dist/index.js +75 -0
  184. package/dist/index.js.map +1 -0
  185. package/dist/language.cjs +308 -0
  186. package/dist/language.cjs.map +1 -0
  187. package/dist/language.d.cts +110 -0
  188. package/dist/language.d.ts +110 -0
  189. package/dist/language.js +287 -0
  190. package/dist/language.js.map +1 -0
  191. package/dist/lexer.cjs +64 -0
  192. package/dist/lexer.cjs.map +1 -0
  193. package/dist/lexer.d.cts +56 -0
  194. package/dist/lexer.d.ts +56 -0
  195. package/dist/lexer.js +11 -0
  196. package/dist/lexer.js.map +1 -0
  197. package/dist/normalizer.cjs +40 -0
  198. package/dist/normalizer.cjs.map +1 -0
  199. package/dist/normalizer.d.cts +364 -0
  200. package/dist/normalizer.d.ts +364 -0
  201. package/dist/normalizer.js +11 -0
  202. package/dist/normalizer.js.map +1 -0
  203. package/dist/packages.cjs +121 -0
  204. package/dist/packages.cjs.map +1 -0
  205. package/dist/packages.d.cts +691 -0
  206. package/dist/packages.d.ts +691 -0
  207. package/dist/packages.js +24 -0
  208. package/dist/packages.js.map +1 -0
  209. package/dist/parser.cjs +55 -0
  210. package/dist/parser.cjs.map +1 -0
  211. package/dist/parser.d.cts +46 -0
  212. package/dist/parser.d.ts +46 -0
  213. package/dist/parser.js +10 -0
  214. package/dist/parser.js.map +1 -0
  215. package/dist/pipeline-CrsRPmsv.d.ts +285 -0
  216. package/dist/pipeline-DPUQt7yL.d.cts +285 -0
  217. package/dist/resolvers.cjs +13 -0
  218. package/dist/resolvers.cjs.map +1 -0
  219. package/dist/resolvers.d.cts +111 -0
  220. package/dist/resolvers.d.ts +111 -0
  221. package/dist/resolvers.js +4 -0
  222. package/dist/resolvers.js.map +1 -0
  223. package/dist/services.cjs +21 -0
  224. package/dist/services.cjs.map +1 -0
  225. package/dist/services.d.cts +30 -0
  226. package/dist/services.d.ts +30 -0
  227. package/dist/services.js +4 -0
  228. package/dist/services.js.map +1 -0
  229. package/dist/uom.cjs +56 -0
  230. package/dist/uom.cjs.map +1 -0
  231. package/dist/uom.d.cts +224 -0
  232. package/dist/uom.d.ts +224 -0
  233. package/dist/uom.js +11 -0
  234. package/dist/uom.js.map +1 -0
  235. package/dist/utilities.cjs +32 -0
  236. package/dist/utilities.cjs.map +1 -0
  237. package/dist/utilities.d.cts +113 -0
  238. package/dist/utilities.d.ts +113 -0
  239. package/dist/utilities.js +7 -0
  240. package/dist/utilities.js.map +1 -0
  241. package/dist/variables.cjs +17 -0
  242. package/dist/variables.cjs.map +1 -0
  243. package/dist/variables.d.cts +87 -0
  244. package/dist/variables.d.ts +87 -0
  245. package/dist/variables.js +4 -0
  246. package/dist/variables.js.map +1 -0
  247. package/dist/vm.cjs +284 -0
  248. package/dist/vm.cjs.map +1 -0
  249. package/dist/vm.d.cts +68 -0
  250. package/dist/vm.d.ts +68 -0
  251. package/dist/vm.js +194 -0
  252. package/dist/vm.js.map +1 -0
  253. package/package.json +4 -4
@@ -0,0 +1,113 @@
1
+ /**
2
+ * Fast, non-cryptographic string hashing utilities.
3
+ *
4
+ * djb2 is chosen for its speed, simplicity, and excellent distribution
5
+ * for short strings (typical line lengths in markdown documents).
6
+ * It produces a 32-bit unsigned integer hash.
7
+ */
8
+ /**
9
+ * djb2 string hash, fast, simple, good distribution.
10
+ * Used for O(1) line text change detection in DocumentModel.
11
+ */
12
+ declare function djb2Hash(str: string): number;
13
+
14
+ /**
15
+ * Format `number` for display, branching on whether it's a whole number:
16
+ * integers are always rendered with zero decimal places (never padded to
17
+ * `decimalPlaces`), while non-integers are rendered with up to
18
+ * `decimalPlaces` fractional digits. `includeThousandSeparators` controls
19
+ * whether groups are separated (e.g. `"1,234"`) per `numberLocale`.
20
+ *
21
+ * @param number - The value to format.
22
+ * @param decimalPlaces - Max fractional digits for non-integer values (default 2).
23
+ * @param includeThousandSeparators - Whether to group digits (default false).
24
+ * @param numberLocale - `Intl`/`toLocaleString` locale to format with (default "en-US").
25
+ */
26
+ declare function autoFormatIntegerOrFloat(number: number, decimalPlaces?: number, includeThousandSeparators?: boolean, numberLocale?: string): string;
27
+
28
+ /**
29
+ * Strips a single layer of matching double quotes from a string, if present.
30
+ * Returns the input unchanged if it isn't fully wrapped in quotes.
31
+ *
32
+ * Used for STRING token values, which the lexer emits with their surrounding
33
+ * `"..."` quotes still attached.
34
+ */
35
+ declare function stripQuotes(value: string): string;
36
+
37
+ /**
38
+ * Multiplex an optional caller AbortSignal with a hard timeout into a single
39
+ * AbortSignal suitable for fetch().
40
+ *
41
+ * Implemented manually rather than with AbortSignal.any()/AbortSignal.timeout()
42
+ * (Chrome 116+) to stay compatible with the TypeScript lib targets used by
43
+ * this project.
44
+ *
45
+ * Handles the already-aborted caller: addEventListener("abort", …) on a signal
46
+ * that has already fired never invokes the listener, so without the upfront
47
+ * `aborted` check the fetch would proceed even though the caller cancelled.
48
+ */
49
+ declare function createTimeoutSignal(callerSignal: AbortSignal | undefined, timeoutMs: number, label: string): {
50
+ signal: AbortSignal;
51
+ cleanup: () => void;
52
+ };
53
+
54
+ /**
55
+ * Records abort-signal lifecycle for debugging cancellation.
56
+ *
57
+ * Keystroke cancellation is hard to reason about after the fact, because the
58
+ * evidence is gone by the time anything looks wrong. This keeps it.
59
+ */
60
+ declare const abortLogger: {
61
+ /** Whether debug logging is currently active. */
62
+ readonly enabled: boolean;
63
+ /**
64
+ * Log creation of the keystroke-level AbortController.
65
+ * Called in the plugin constructor and on each new keystroke.
66
+ */
67
+ keystrokeCreated(): void;
68
+ /**
69
+ * Log abortion of the keystroke-level AbortController.
70
+ * @param reason Why the keystroke was aborted (e.g. "New keystroke",
71
+ * "Document switch", "Plugin destroyed").
72
+ */
73
+ keystrokeAborted(reason: string): void;
74
+ /**
75
+ * Log creation of a local AbortController that is linked to the
76
+ * keystroke signal.
77
+ * @param source Which code path created the controller
78
+ * (e.g. "executeAndStore", "executeRaw", "preflight", "vm").
79
+ */
80
+ localControllerCreated(source: string): void;
81
+ /**
82
+ * Log that a local AbortController was linked to the keystroke signal.
83
+ * When the keystroke signal is aborted, this local controller will
84
+ * be aborted automatically.
85
+ * @param source The code path that created the controller.
86
+ */
87
+ signalLinked(source: string): void;
88
+ /**
89
+ * Log that a local AbortController's listener was removed from the
90
+ * keystroke signal (cleanup).
91
+ * @param source The code path.
92
+ */
93
+ signalUnlinked(source: string): void;
94
+ /**
95
+ * Log that the keystroke signal was propagated INTO the engine.
96
+ * @param isAborted Whether the signal was already aborted when set.
97
+ */
98
+ keystrokeSignalSet(isAborted: boolean): void;
99
+ /**
100
+ * Log that the keystroke signal was CLEARED from the engine
101
+ * (typically in the evaluator's finally block).
102
+ */
103
+ keystrokeSignalCleared(): void;
104
+ /**
105
+ * Log that a stale async result was discarded because its signal
106
+ * was aborted.
107
+ * @param queryKey The cache key for the discarded result.
108
+ * @param context Additional context (e.g. "after await", "after error").
109
+ */
110
+ staleDataDiscarded(queryKey: string, context: string): void;
111
+ };
112
+
113
+ export { abortLogger, autoFormatIntegerOrFloat, createTimeoutSignal, djb2Hash, stripQuotes };
@@ -0,0 +1,7 @@
1
+ export { abortLogger, djb2Hash } from './chunk-IF532O7C.js';
2
+ export { autoFormatIntegerOrFloat } from './chunk-DUEZFTK2.js';
3
+ export { stripQuotes } from './chunk-PFSDGGYL.js';
4
+ export { createTimeoutSignal } from './chunk-Z4X2RWOF.js';
5
+ import './chunk-YLJ4XMA6.js';
6
+ //# sourceMappingURL=utilities.js.map
7
+ //# sourceMappingURL=utilities.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"utilities.js"}
@@ -0,0 +1,17 @@
1
+ 'use strict';
2
+
3
+ var chunkFEAIOR7N_cjs = require('./chunk-FEAIOR7N.cjs');
4
+ require('./chunk-B7LXJ6LC.cjs');
5
+
6
+
7
+
8
+ Object.defineProperty(exports, "VariableResolver", {
9
+ enumerable: true,
10
+ get: function () { return chunkFEAIOR7N_cjs.VariableResolver; }
11
+ });
12
+ Object.defineProperty(exports, "sharedVariableResolver", {
13
+ enumerable: true,
14
+ get: function () { return chunkFEAIOR7N_cjs.sharedVariableResolver; }
15
+ });
16
+ //# sourceMappingURL=variables.cjs.map
17
+ //# sourceMappingURL=variables.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"variables.cjs"}
@@ -0,0 +1,87 @@
1
+ /**
2
+ * Interface for variable value providers.
3
+ *
4
+ * Implementations provide named variables to the {@link VariableResolver}.
5
+ * Each source has a priority, lower numbers are queried first.
6
+ *
7
+ * Sources can be backed by document variables, Obsidian frontmatter,
8
+ * plugin data, or any external data store.
9
+ */
10
+ interface IVariableSource {
11
+ /** Human-readable name for this source (e.g., "Document Variables", "Frontmatter"). */
12
+ name: string;
13
+ /**
14
+ * Priority for resolution order. Lower numbers = higher priority.
15
+ * Sources with the same priority are queried in registration order.
16
+ */
17
+ priority: number;
18
+ /**
19
+ * Get a variable's value.
20
+ * @param name - The variable name to look up
21
+ * @returns The value, or undefined if not found in this source
22
+ */
23
+ get(name: string): Promise<number | string | undefined>;
24
+ /**
25
+ * Set a variable's value in this source.
26
+ * @param name - The variable name
27
+ * @param value - The value to set
28
+ */
29
+ set(name: string, value: number | string): Promise<void>;
30
+ }
31
+
32
+ /**
33
+ * Resolves variable names by querying registered {@link IVariableSource} instances
34
+ * in priority order. Supports caching for repeated lookups.
35
+ *
36
+ * Sources are sorted by priority (lowest first) on registration. When resolving
37
+ * a variable, sources are queried in order and the first non-undefined result wins.
38
+ */
39
+ declare class VariableResolver {
40
+ private sources;
41
+ private cache;
42
+ private cacheEnabled;
43
+ /**
44
+ * Register a variable source with a given priority.
45
+ * Sources are sorted so lower-priority-number sources are queried first.
46
+ *
47
+ * @param source - The variable source to register
48
+ */
49
+ registerSource(source: IVariableSource): void;
50
+ /**
51
+ * Remove a previously registered variable source (identity match).
52
+ * The lookup cache is cleared because resolution results may change
53
+ * once the source no longer participates.
54
+ *
55
+ * @param source - The exact source instance passed to registerSource.
56
+ */
57
+ unregisterSource(source: IVariableSource): void;
58
+ /**
59
+ * Resolve a variable name to its value.
60
+ *
61
+ * Checks the cache first (if enabled), then queries registered sources
62
+ * in priority order. The first source returning a non-undefined value wins.
63
+ * Cached results are stored and returned on subsequent calls until invalidated.
64
+ *
65
+ * @param name - The variable name to resolve
66
+ * @returns The resolved value, or undefined if not found in any source
67
+ */
68
+ resolve(name: string): Promise<number | string | undefined>;
69
+ /**
70
+ * Set a variable value across all registered sources.
71
+ * Also updates the local cache so subsequent reads return the new value.
72
+ *
73
+ * @param name - The variable name
74
+ * @param value - The value to set
75
+ */
76
+ set(name: string, value: number | string): Promise<void>;
77
+ /** Invalidate a single variable in the cache, forcing re-resolution on next read. */
78
+ invalidate(name: string): void;
79
+ /** Invalidate all cached variable lookups. */
80
+ invalidateAll(): void;
81
+ /** Enable or disable the lookup cache. When disabled, every read queries sources directly. */
82
+ setCacheEnabled(enabled: boolean): void;
83
+ }
84
+ /** Shared singleton VariableResolver instance. */
85
+ declare const sharedVariableResolver: VariableResolver;
86
+
87
+ export { type IVariableSource, VariableResolver, sharedVariableResolver };
@@ -0,0 +1,87 @@
1
+ /**
2
+ * Interface for variable value providers.
3
+ *
4
+ * Implementations provide named variables to the {@link VariableResolver}.
5
+ * Each source has a priority, lower numbers are queried first.
6
+ *
7
+ * Sources can be backed by document variables, Obsidian frontmatter,
8
+ * plugin data, or any external data store.
9
+ */
10
+ interface IVariableSource {
11
+ /** Human-readable name for this source (e.g., "Document Variables", "Frontmatter"). */
12
+ name: string;
13
+ /**
14
+ * Priority for resolution order. Lower numbers = higher priority.
15
+ * Sources with the same priority are queried in registration order.
16
+ */
17
+ priority: number;
18
+ /**
19
+ * Get a variable's value.
20
+ * @param name - The variable name to look up
21
+ * @returns The value, or undefined if not found in this source
22
+ */
23
+ get(name: string): Promise<number | string | undefined>;
24
+ /**
25
+ * Set a variable's value in this source.
26
+ * @param name - The variable name
27
+ * @param value - The value to set
28
+ */
29
+ set(name: string, value: number | string): Promise<void>;
30
+ }
31
+
32
+ /**
33
+ * Resolves variable names by querying registered {@link IVariableSource} instances
34
+ * in priority order. Supports caching for repeated lookups.
35
+ *
36
+ * Sources are sorted by priority (lowest first) on registration. When resolving
37
+ * a variable, sources are queried in order and the first non-undefined result wins.
38
+ */
39
+ declare class VariableResolver {
40
+ private sources;
41
+ private cache;
42
+ private cacheEnabled;
43
+ /**
44
+ * Register a variable source with a given priority.
45
+ * Sources are sorted so lower-priority-number sources are queried first.
46
+ *
47
+ * @param source - The variable source to register
48
+ */
49
+ registerSource(source: IVariableSource): void;
50
+ /**
51
+ * Remove a previously registered variable source (identity match).
52
+ * The lookup cache is cleared because resolution results may change
53
+ * once the source no longer participates.
54
+ *
55
+ * @param source - The exact source instance passed to registerSource.
56
+ */
57
+ unregisterSource(source: IVariableSource): void;
58
+ /**
59
+ * Resolve a variable name to its value.
60
+ *
61
+ * Checks the cache first (if enabled), then queries registered sources
62
+ * in priority order. The first source returning a non-undefined value wins.
63
+ * Cached results are stored and returned on subsequent calls until invalidated.
64
+ *
65
+ * @param name - The variable name to resolve
66
+ * @returns The resolved value, or undefined if not found in any source
67
+ */
68
+ resolve(name: string): Promise<number | string | undefined>;
69
+ /**
70
+ * Set a variable value across all registered sources.
71
+ * Also updates the local cache so subsequent reads return the new value.
72
+ *
73
+ * @param name - The variable name
74
+ * @param value - The value to set
75
+ */
76
+ set(name: string, value: number | string): Promise<void>;
77
+ /** Invalidate a single variable in the cache, forcing re-resolution on next read. */
78
+ invalidate(name: string): void;
79
+ /** Invalidate all cached variable lookups. */
80
+ invalidateAll(): void;
81
+ /** Enable or disable the lookup cache. When disabled, every read queries sources directly. */
82
+ setCacheEnabled(enabled: boolean): void;
83
+ }
84
+ /** Shared singleton VariableResolver instance. */
85
+ declare const sharedVariableResolver: VariableResolver;
86
+
87
+ export { type IVariableSource, VariableResolver, sharedVariableResolver };
@@ -0,0 +1,4 @@
1
+ export { VariableResolver, sharedVariableResolver } from './chunk-GCM5JHMX.js';
2
+ import './chunk-YLJ4XMA6.js';
3
+ //# sourceMappingURL=variables.js.map
4
+ //# sourceMappingURL=variables.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"variables.js"}
package/dist/vm.cjs ADDED
@@ -0,0 +1,284 @@
1
+ 'use strict';
2
+
3
+ var chunk6NTVRDQV_cjs = require('./chunk-6NTVRDQV.cjs');
4
+ require('./chunk-47LRVGOT.cjs');
5
+ var chunkJ73SJHR3_cjs = require('./chunk-J73SJHR3.cjs');
6
+ require('./chunk-FEAIOR7N.cjs');
7
+ require('./chunk-XJCMXB2E.cjs');
8
+ require('./chunk-MZOVP3WI.cjs');
9
+ require('./chunk-VEKIWQ3F.cjs');
10
+ require('./chunk-HTXVVJRA.cjs');
11
+ var chunkOC6LTXYS_cjs = require('./chunk-OC6LTXYS.cjs');
12
+ require('./chunk-QNJ4ACRT.cjs');
13
+ require('./chunk-53B6KDDJ.cjs');
14
+ require('./chunk-M4N5GA5Z.cjs');
15
+ require('./chunk-B7LXJ6LC.cjs');
16
+
17
+ // src/vm/VMCheckpoints.ts
18
+ var VMCheckpointer = class {
19
+ constructor(vm) {
20
+ /** Ordered array of checkpoints (ascending lineNumber). */
21
+ this.checkpoints = [];
22
+ this.vm = vm;
23
+ }
24
+ // ── Snapshot ─────────────────────────────────────────────────────
25
+ /**
26
+ * Create a checkpoint at the current line, recording the VM values of
27
+ * the specified variables.
28
+ *
29
+ * Uses prototypal inheritance: `Object.create(parent.variables)` so
30
+ * that inherited variable lookups fall through to previous checkpoints
31
+ * without copying all variables into each checkpoint.
32
+ *
33
+ * @param lineNumber 1-based line position.
34
+ * @param lineId Persistent line ID from DocumentModel.
35
+ * @param variableNames Names of variables that were written at this line.
36
+ * @returns The new checkpoint, or null if no variable names provided.
37
+ */
38
+ snapshot(lineNumber, lineId, variableNames) {
39
+ if (variableNames.length === 0) return null;
40
+ const parent = this.checkpoints.length > 0 ? this.checkpoints[this.checkpoints.length - 1] : null;
41
+ const variables = Object.create(
42
+ parent?.variables ?? null
43
+ );
44
+ const functions = Object.create(
45
+ parent?.functions ?? null
46
+ );
47
+ for (const name of variableNames) {
48
+ if (this.vm.hasUserFunction(name)) {
49
+ const fn = this.vm.getUserFunction(name);
50
+ if (fn) functions[name] = fn;
51
+ continue;
52
+ }
53
+ const val = this.vm.getVar(name);
54
+ if (val !== void 0) {
55
+ variables[name] = val;
56
+ }
57
+ }
58
+ const checkpoint = {
59
+ lineNumber,
60
+ lineId,
61
+ variables,
62
+ functions,
63
+ parent
64
+ };
65
+ this.checkpoints.push(checkpoint);
66
+ return checkpoint;
67
+ }
68
+ // ── Restore ──────────────────────────────────────────────────────
69
+ /**
70
+ * Restore the VM to the state at or just after the given line number.
71
+ *
72
+ * Finds the nearest checkpoint whose `lineNumber <= targetLineNumber`,
73
+ * then replays all variable definitions from root → that checkpoint
74
+ * into the VM via `setVar()`. The VM's stack is also reset.
75
+ *
76
+ * If no checkpoint exists at or before the target line, the VM is
77
+ * fully reset (empty scope, empty stack).
78
+ *
79
+ * **Performance:** O(number of checkpoints × variables per checkpoint).
80
+ * With prototypal inheritance, `Object.keys()` on each checkpoint
81
+ * returns only the variables that were set at that checkpoint (not
82
+ * inherited ones), so the total work is O(total variable definitions
83
+ * in the document), which is < 100 for typical Obsidian documents.
84
+ *
85
+ * @param lineNumber Target 1-based line number. The VM will have the
86
+ * state that existed AFTER evaluating lines up to `lineNumber`.
87
+ */
88
+ restoreTo(lineNumber) {
89
+ const target = this.getNearestCheckpoint(lineNumber);
90
+ if (!target) {
91
+ this.vm.reset();
92
+ return;
93
+ }
94
+ const chain = [];
95
+ let current = target;
96
+ while (current) {
97
+ chain.unshift(current);
98
+ current = current.parent;
99
+ }
100
+ this.vm.reset();
101
+ for (const cp of chain) {
102
+ for (const key of Object.keys(cp.variables)) {
103
+ this.vm.setVar(key, cp.variables[key]);
104
+ }
105
+ for (const key of Object.keys(cp.functions)) {
106
+ const fn = cp.functions[key];
107
+ this.vm.defineUserFunction(fn.name, fn.params, fn.program);
108
+ }
109
+ }
110
+ }
111
+ // ── Queries ──────────────────────────────────────────────────────
112
+ /**
113
+ * Find the nearest checkpoint at or before the given line number.
114
+ *
115
+ * Uses linear scan (checkpoints are sorted by lineNumber and the list
116
+ * is short, typically < 20 for Obsidian documents). Can be upgraded
117
+ * to binary search if needed for documents with 1000+ variable defs.
118
+ *
119
+ * @returns The nearest checkpoint, or null if none exists before the line.
120
+ */
121
+ getNearestCheckpoint(lineNumber) {
122
+ let result = null;
123
+ for (const cp of this.checkpoints) {
124
+ if (cp.lineNumber <= lineNumber) {
125
+ result = cp;
126
+ } else {
127
+ break;
128
+ }
129
+ }
130
+ return result;
131
+ }
132
+ /**
133
+ * Get a specific checkpoint by its line number.
134
+ * @returns The checkpoint, or undefined if not found.
135
+ */
136
+ getCheckpointAt(lineNumber) {
137
+ return this.checkpoints.find((cp) => cp.lineNumber === lineNumber);
138
+ }
139
+ /**
140
+ * Get the entire checkpoint chain from root to the last checkpoint.
141
+ * Useful for debugging and serialization.
142
+ */
143
+ getAllCheckpoints() {
144
+ return this.checkpoints;
145
+ }
146
+ /**
147
+ * Look up a variable's value through the checkpoint chain.
148
+ *
149
+ * Walks the prototype chain starting from the most recent checkpoint,
150
+ * looking for the variable name as an own property. This is O(depth)
151
+ * where depth is the number of checkpoints since the variable was
152
+ * last set.
153
+ *
154
+ * **Note:** This queries the checkpointer's snapshot, not the VM.
155
+ * The VM may have been modified since the last snapshot (e.g., by
156
+ * Tier 2 execution of non-variable-def lines that don't create checkpoints).
157
+ *
158
+ * @returns The Value, or undefined if the variable was never set.
159
+ */
160
+ lookupVariable(name) {
161
+ if (this.checkpoints.length === 0) return void 0;
162
+ const latest = this.checkpoints[this.checkpoints.length - 1];
163
+ let scope = latest.variables;
164
+ while (scope) {
165
+ if (Object.prototype.hasOwnProperty.call(scope, name)) {
166
+ return scope[name];
167
+ }
168
+ scope = Object.getPrototypeOf(scope);
169
+ }
170
+ return void 0;
171
+ }
172
+ // ── Lifecycle ────────────────────────────────────────────────────
173
+ /**
174
+ * Clear all checkpoints. The underlying VM is NOT reset, call
175
+ * `vm.reset()` separately if needed.
176
+ */
177
+ clear() {
178
+ this.checkpoints = [];
179
+ }
180
+ /** Number of checkpoints stored. */
181
+ get count() {
182
+ return this.checkpoints.length;
183
+ }
184
+ /** Returns true if no checkpoints have been created. */
185
+ get isEmpty() {
186
+ return this.checkpoints.length === 0;
187
+ }
188
+ /** The associated VM instance. */
189
+ get vmInstance() {
190
+ return this.vm;
191
+ }
192
+ };
193
+
194
+ Object.defineProperty(exports, "DependencyGraph", {
195
+ enumerable: true,
196
+ get: function () { return chunk6NTVRDQV_cjs.DependencyGraph; }
197
+ });
198
+ Object.defineProperty(exports, "ScopeManager", {
199
+ enumerable: true,
200
+ get: function () { return chunk6NTVRDQV_cjs.ScopeManager; }
201
+ });
202
+ Object.defineProperty(exports, "createVM", {
203
+ enumerable: true,
204
+ get: function () { return chunk6NTVRDQV_cjs.createVM; }
205
+ });
206
+ Object.defineProperty(exports, "executeBytecode", {
207
+ enumerable: true,
208
+ get: function () { return chunk6NTVRDQV_cjs.executeBytecode; }
209
+ });
210
+ Object.defineProperty(exports, "OpRegistry", {
211
+ enumerable: true,
212
+ get: function () { return chunkJ73SJHR3_cjs.OpRegistry; }
213
+ });
214
+ Object.defineProperty(exports, "allocatePluginFunctionIndex", {
215
+ enumerable: true,
216
+ get: function () { return chunkJ73SJHR3_cjs.allocatePluginFunctionIndex; }
217
+ });
218
+ Object.defineProperty(exports, "binaryOp", {
219
+ enumerable: true,
220
+ get: function () { return chunkJ73SJHR3_cjs.binaryOp; }
221
+ });
222
+ Object.defineProperty(exports, "builtinFunctions", {
223
+ enumerable: true,
224
+ get: function () { return chunkJ73SJHR3_cjs.builtinFunctions; }
225
+ });
226
+ Object.defineProperty(exports, "pluginFunctionRegistry", {
227
+ enumerable: true,
228
+ get: function () { return chunkJ73SJHR3_cjs.pluginFunctionRegistry; }
229
+ });
230
+ Object.defineProperty(exports, "sharedOpRegistry", {
231
+ enumerable: true,
232
+ get: function () { return chunkJ73SJHR3_cjs.sharedOpRegistry; }
233
+ });
234
+ Object.defineProperty(exports, "unifyUom", {
235
+ enumerable: true,
236
+ get: function () { return chunkJ73SJHR3_cjs.unifyUom; }
237
+ });
238
+ Object.defineProperty(exports, "Value", {
239
+ enumerable: true,
240
+ get: function () { return chunkOC6LTXYS_cjs.Value; }
241
+ });
242
+ Object.defineProperty(exports, "ValueType", {
243
+ enumerable: true,
244
+ get: function () { return chunkOC6LTXYS_cjs.ValueType; }
245
+ });
246
+ Object.defineProperty(exports, "bigIntValue", {
247
+ enumerable: true,
248
+ get: function () { return chunkOC6LTXYS_cjs.bigIntValue; }
249
+ });
250
+ Object.defineProperty(exports, "colVectorValue", {
251
+ enumerable: true,
252
+ get: function () { return chunkOC6LTXYS_cjs.colVectorValue; }
253
+ });
254
+ Object.defineProperty(exports, "hexValue", {
255
+ enumerable: true,
256
+ get: function () { return chunkOC6LTXYS_cjs.hexValue; }
257
+ });
258
+ Object.defineProperty(exports, "matrixValue", {
259
+ enumerable: true,
260
+ get: function () { return chunkOC6LTXYS_cjs.matrixValue; }
261
+ });
262
+ Object.defineProperty(exports, "numberValue", {
263
+ enumerable: true,
264
+ get: function () { return chunkOC6LTXYS_cjs.numberValue; }
265
+ });
266
+ Object.defineProperty(exports, "rangeValue", {
267
+ enumerable: true,
268
+ get: function () { return chunkOC6LTXYS_cjs.rangeValue; }
269
+ });
270
+ Object.defineProperty(exports, "rowVectorValue", {
271
+ enumerable: true,
272
+ get: function () { return chunkOC6LTXYS_cjs.rowVectorValue; }
273
+ });
274
+ Object.defineProperty(exports, "stringValue", {
275
+ enumerable: true,
276
+ get: function () { return chunkOC6LTXYS_cjs.stringValue; }
277
+ });
278
+ Object.defineProperty(exports, "uomValue", {
279
+ enumerable: true,
280
+ get: function () { return chunkOC6LTXYS_cjs.uomValue; }
281
+ });
282
+ exports.VMCheckpointer = VMCheckpointer;
283
+ //# sourceMappingURL=vm.cjs.map
284
+ //# sourceMappingURL=vm.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/vm/VMCheckpoints.ts"],"names":[],"mappings":"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","file":"vm.cjs","sourcesContent":["import { Value } from \"@solve-js/vm/Value\";\nimport type { VM } from \"@solve-js/vm/OpRegistry\";\nimport type { UserFunctionDef } from \"@solve-js/parser/BytecodeBuilder\";\n\n// ── VMCheckpoint ────────────────────────────────────────────────────────\n\n/**\n * A point-in-time snapshot of VM variable state.\n *\n * Uses **prototypal inheritance** for memory efficiency: each checkpoint's\n * `variables` object has its parent checkpoint's `variables` as its\n * `__proto__`. This means a `getVar(\"x\")` lookup walks the prototype chain\n * until it finds `x`, and only variables that CHANGED at this checkpoint\n * consume heap space. Unchanged variables are inherited from the parent.\n *\n * ```text\n * Checkpoint 0 (root): {} // empty scope\n * Checkpoint 1 (:x=5): { x: 5 } __proto__ → 0\n * Checkpoint 2 (:y=8): { y: 8 } __proto__ → 1\n * Checkpoint 3 (:x=3): { x: 3 } __proto__ → 2 // shadows x=5\n * ```\n *\n * To look up `x` at checkpoint 3: find own `x=3` → done.\n * To look up `y` at checkpoint 3: not own → walk proto to checkpoint 2 → `y=8`.\n * To look up `z` at checkpoint 3: not found anywhere → undefined.\n *\n * **Memory:** O(number of variable definitions) heap, independent of\n * document length. Typical Obsidian documents have < 100 variable defs,\n * so total checkpoint heap is < 10 KB.\n */\nexport interface VMCheckpoint {\n\t/** 1-based line number where this checkpoint was created. */\n\tlineNumber: number;\n\t/** Persistent line ID from DocumentModel. */\n\tlineId: number;\n\t/**\n\t * Variable name → Value at this checkpoint.\n\t * Own properties are variables set/updated at this line.\n\t * The prototype chain provides inherited variables from parent checkpoints.\n\t */\n\tvariables: Record<string, Value>;\n\t/**\n\t * User-defined-function name → definition at this checkpoint. SEPARATE\n\t * from `variables` above (not prototypally chained the same way\n\t * `restoreTo()` replays every checkpoint in the chain in order, so a\n\t * later redefinition of the same function name naturally overwrites an\n\t * earlier one during replay, without needing its own prototype walk).\n\t *\n\t * Without this field, a function definition's checkpoint entry would be\n\t * SILENTLY LOST: `snapshot()` used to call `vm.getVar(name)` for every\n\t * written name, which returns `undefined` for a function name (function\n\t * defs live in `vm.userFunctions`, not the flat variable store), and a\n\t * `val !== undefined` guard silently skipped it. A scroll-triggered\n\t * `restoreTo()` would then reset the VM and replay only `variables`,\n\t * making a function defined above the new viewport vanish (calling it\n\t * would throw `UNDEFINED_FUNCTION`) even though the document still\n\t * shows its definition line as clean/cached.\n\t */\n\tfunctions: Record<string, UserFunctionDef>;\n\t/** Parent checkpoint (closer to document start), or null for root. */\n\tparent: VMCheckpoint | null;\n}\n\n// ── VMCheckpointer ──────────────────────────────────────────────────────\n\n/**\n * Manages VM state checkpoints for the three-tier evaluation strategy.\n *\n * **Checkpoint creation:** After a variable-definition line executes\n * (Tier 1 or Tier 3), `snapshot()` records the current values of the\n * written variables. The checkpoint is linked via prototypal inheritance\n * to the previous checkpoint, so only changed variables consume memory.\n *\n * **Checkpoint restoration:** Before evaluating a viewport whose start line\n * is not line 1, `restoreTo(lineNumber)` resets the VM and replays all\n * variable definitions up to and including that line. This avoids\n * re-evaluating the entire document from line 1 on every scroll.\n *\n * **Thread safety:** Checkpoints are created synchronously on the main\n * thread during evaluation. They are immutable after creation (Value is\n * an immutable type), so no synchronization is needed.\n *\n * **Integration with Phase 5.2e:** `setViewport()` will use `getNearestCheckpoint()`\n * to find the checkpoint just before the new viewport start, then call\n * `restoreTo()` to set up the VM before evaluating only the visible lines.\n * This is the key to O(visible lines) scrolling instead of O(document).\n */\nexport class VMCheckpointer {\n\t/** Ordered array of checkpoints (ascending lineNumber). */\n\tprivate checkpoints: VMCheckpoint[] = [];\n\t/** The VM instance whose variables are snapshotted/restored. */\n\tprivate vm: VM;\n\n\tconstructor(vm: VM) {\n\t\tthis.vm = vm;\n\t}\n\n\t// ── Snapshot ─────────────────────────────────────────────────────\n\n\t/**\n\t * Create a checkpoint at the current line, recording the VM values of\n\t * the specified variables.\n\t *\n\t * Uses prototypal inheritance: `Object.create(parent.variables)` so\n\t * that inherited variable lookups fall through to previous checkpoints\n\t * without copying all variables into each checkpoint.\n\t *\n\t * @param lineNumber 1-based line position.\n\t * @param lineId Persistent line ID from DocumentModel.\n\t * @param variableNames Names of variables that were written at this line.\n\t * @returns The new checkpoint, or null if no variable names provided.\n\t */\n\tsnapshot(\n\t\tlineNumber: number,\n\t\tlineId: number,\n\t\tvariableNames: string[]\n\t): VMCheckpoint | null {\n\t\tif (variableNames.length === 0) return null;\n\n\t\tconst parent =\n\t\t\tthis.checkpoints.length > 0\n\t\t\t\t? this.checkpoints[this.checkpoints.length - 1]\n\t\t\t\t: null;\n\n\t\t// Create prototypal chain: new checkpoint inherits from parent\n\t\tconst variables: Record<string, Value> = Object.create(\n\t\t\tparent?.variables ?? null\n\t\t) as Record<string, Value>;\n\t\tconst functions: Record<string, UserFunctionDef> = Object.create(\n\t\t\tparent?.functions ?? null\n\t\t) as Record<string, UserFunctionDef>;\n\n\t\t// Record current VM values for the written names, routing each into\n\t\t// the right bag (a name is either a variable or a user-defined\n\t\t// function, never both; see VMCheckpoint.functions's doc comment for\n\t\t// why this dispatch is required, not optional).\n\t\tfor (const name of variableNames) {\n\t\t\tif (this.vm.hasUserFunction(name)) {\n\t\t\t\tconst fn = this.vm.getUserFunction(name);\n\t\t\t\tif (fn) functions[name] = fn;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst val = this.vm.getVar(name);\n\t\t\tif (val !== undefined) {\n\t\t\t\tvariables[name] = val;\n\t\t\t}\n\t\t}\n\n\t\tconst checkpoint: VMCheckpoint = {\n\t\t\tlineNumber,\n\t\t\tlineId,\n\t\t\tvariables,\n\t\t\tfunctions,\n\t\t\tparent,\n\t\t};\n\t\tthis.checkpoints.push(checkpoint);\n\t\treturn checkpoint;\n\t}\n\n\t// ── Restore ──────────────────────────────────────────────────────\n\n\t/**\n\t * Restore the VM to the state at or just after the given line number.\n\t *\n\t * Finds the nearest checkpoint whose `lineNumber <= targetLineNumber`,\n\t * then replays all variable definitions from root → that checkpoint\n\t * into the VM via `setVar()`. The VM's stack is also reset.\n\t *\n\t * If no checkpoint exists at or before the target line, the VM is\n\t * fully reset (empty scope, empty stack).\n\t *\n\t * **Performance:** O(number of checkpoints × variables per checkpoint).\n\t * With prototypal inheritance, `Object.keys()` on each checkpoint\n\t * returns only the variables that were set at that checkpoint (not\n\t * inherited ones), so the total work is O(total variable definitions\n\t * in the document), which is < 100 for typical Obsidian documents.\n\t *\n\t * @param lineNumber Target 1-based line number. The VM will have the\n\t * state that existed AFTER evaluating lines up to `lineNumber`.\n\t */\n\trestoreTo(lineNumber: number): void {\n\t\tconst target = this.getNearestCheckpoint(lineNumber);\n\t\tif (!target) {\n\t\t\tthis.vm.reset();\n\t\t\treturn;\n\t\t}\n\n\t\t// Collect the checkpoint chain from root to target.\n\t\t// Walk parent links and reverse so root is first.\n\t\tconst chain: VMCheckpoint[] = [];\n\t\tlet current: VMCheckpoint | null = target;\n\t\twhile (current) {\n\t\t\tchain.unshift(current);\n\t\t\tcurrent = current.parent;\n\t\t}\n\n\t\tthis.vm.reset();\n\t\tfor (const cp of chain) {\n\t\t\t// Object.keys() returns only OWN enumerable properties\n\t\t\t// it does NOT include inherited properties from the prototype chain.\n\t\t\t// This means we only set variables that were defined/updated at this\n\t\t\t// specific checkpoint, not all variables from parent checkpoints.\n\t\t\tfor (const key of Object.keys(cp.variables)) {\n\t\t\t\tthis.vm.setVar(key, cp.variables[key]);\n\t\t\t}\n\t\t\t// Replay function definitions the same way, a later checkpoint's\n\t\t\t// redefinition of the same name naturally overwrites an earlier\n\t\t\t// one since the chain replays in root-to-target order.\n\t\t\tfor (const key of Object.keys(cp.functions)) {\n\t\t\t\tconst fn = cp.functions[key];\n\t\t\t\tthis.vm.defineUserFunction(fn.name, fn.params, fn.program);\n\t\t\t}\n\t\t}\n\t}\n\n\t// ── Queries ──────────────────────────────────────────────────────\n\n\t/**\n\t * Find the nearest checkpoint at or before the given line number.\n\t *\n\t * Uses linear scan (checkpoints are sorted by lineNumber and the list\n\t * is short, typically < 20 for Obsidian documents). Can be upgraded\n\t * to binary search if needed for documents with 1000+ variable defs.\n\t *\n\t * @returns The nearest checkpoint, or null if none exists before the line.\n\t */\n\tgetNearestCheckpoint(lineNumber: number): VMCheckpoint | null {\n\t\tlet result: VMCheckpoint | null = null;\n\t\tfor (const cp of this.checkpoints) {\n\t\t\tif (cp.lineNumber <= lineNumber) {\n\t\t\t\tresult = cp;\n\t\t\t} else {\n\t\t\t\tbreak; // checkpoints are sorted ascending\n\t\t\t}\n\t\t}\n\t\treturn result;\n\t}\n\n\t/**\n\t * Get a specific checkpoint by its line number.\n\t * @returns The checkpoint, or undefined if not found.\n\t */\n\tgetCheckpointAt(lineNumber: number): VMCheckpoint | undefined {\n\t\treturn this.checkpoints.find((cp) => cp.lineNumber === lineNumber);\n\t}\n\n\t/**\n\t * Get the entire checkpoint chain from root to the last checkpoint.\n\t * Useful for debugging and serialization.\n\t */\n\tgetAllCheckpoints(): readonly VMCheckpoint[] {\n\t\treturn this.checkpoints;\n\t}\n\n\t/**\n\t * Look up a variable's value through the checkpoint chain.\n\t *\n\t * Walks the prototype chain starting from the most recent checkpoint,\n\t * looking for the variable name as an own property. This is O(depth)\n\t * where depth is the number of checkpoints since the variable was\n\t * last set.\n\t *\n\t * **Note:** This queries the checkpointer's snapshot, not the VM.\n\t * The VM may have been modified since the last snapshot (e.g., by\n\t * Tier 2 execution of non-variable-def lines that don't create checkpoints).\n\t *\n\t * @returns The Value, or undefined if the variable was never set.\n\t */\n\tlookupVariable(name: string): Value | undefined {\n\t\tif (this.checkpoints.length === 0) return undefined;\n\n\t\tconst latest = this.checkpoints[this.checkpoints.length - 1];\n\t\tlet scope: Record<string, Value> | null = latest.variables;\n\t\twhile (scope) {\n\t\t\tif (Object.prototype.hasOwnProperty.call(scope, name)) {\n\t\t\t\treturn scope[name];\n\t\t\t}\n\t\t\tscope = Object.getPrototypeOf(scope) as Record<string, Value> | null;\n\t\t}\n\t\treturn undefined;\n\t}\n\n\t// ── Lifecycle ────────────────────────────────────────────────────\n\n\t/**\n\t * Clear all checkpoints. The underlying VM is NOT reset, call\n\t * `vm.reset()` separately if needed.\n\t */\n\tclear(): void {\n\t\tthis.checkpoints = [];\n\t}\n\n\t/** Number of checkpoints stored. */\n\tget count(): number {\n\t\treturn this.checkpoints.length;\n\t}\n\n\t/** Returns true if no checkpoints have been created. */\n\tget isEmpty(): boolean {\n\t\treturn this.checkpoints.length === 0;\n\t}\n\n\t/** The associated VM instance. */\n\tget vmInstance(): VM {\n\t\treturn this.vm;\n\t}\n}\n"]}