solve-engine 1.0.2 → 1.1.1
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-B0xskcv5.d.cts → BytecodeBuilder-Bp9xeTmX.d.cts} +4 -0
- package/dist/{BytecodeBuilder-B0xskcv5.d.ts → BytecodeBuilder-Bp9xeTmX.d.ts} +4 -0
- package/dist/{Configuration-B-G5gTRn.d.cts → Configuration-C9W8tJv_.d.cts} +53 -1
- package/dist/{Configuration-B-G5gTRn.d.ts → Configuration-C9W8tJv_.d.ts} +53 -1
- package/dist/{EngineError-LU7W7AgI.d.cts → EngineError-B61GS1jp.d.cts} +14 -0
- package/dist/{EngineError-LU7W7AgI.d.ts → EngineError-B61GS1jp.d.ts} +14 -0
- package/dist/FormattingSettings-CJHyxcYu.d.cts +27 -0
- package/dist/FormattingSettings-CJHyxcYu.d.ts +27 -0
- package/dist/{Lexer-DpjdaQ98.d.cts → Lexer-BOs7euZe.d.cts} +28 -1
- package/dist/{Lexer-CNmWxabg.d.ts → Lexer-CSI_lwbW.d.ts} +28 -1
- package/dist/PackageCompatibility-B-7rK1TD.d.cts +76 -0
- package/dist/PackageCompatibility-Dh59eF-X.d.ts +76 -0
- package/dist/{PackageRegistry-zuzqt51V.d.cts → PackageRegistry-BHWJP83F.d.cts} +449 -11
- package/dist/{PackageRegistry-ClIFXxAe.d.ts → PackageRegistry-_8rDlvxI.d.ts} +449 -11
- package/dist/{Parselet-BaySkMV3.d.ts → Parselet-BBT8riYh.d.ts} +12 -3
- package/dist/{Parselet-DuI1Pjiq.d.cts → Parselet-BHcgK9S7.d.cts} +12 -3
- package/dist/{ScopeManager-B6GzdhVG.d.cts → ScopeManager-8vf02dwj.d.cts} +56 -5
- package/dist/{ScopeManager-udv4Twwq.d.ts → ScopeManager-CxA24W5n.d.ts} +56 -5
- package/dist/{Token-BzG5G4ja.d.cts → Token-B1hdkedD.d.cts} +9 -0
- package/dist/{Token-BzG5G4ja.d.ts → Token-B1hdkedD.d.ts} +9 -0
- package/dist/{TokenNormalizer-t_GotBxr.d.ts → TokenNormalizer-C6VzZgHa.d.ts} +1 -1
- package/dist/{TokenNormalizer-DGVa24Q-.d.cts → TokenNormalizer-DRc1Js1V.d.cts} +1 -1
- package/dist/{VMCheckpoints-DwLjivM7.d.cts → VMCheckpoints-ELYqITdF.d.cts} +3 -3
- package/dist/{VMCheckpoints-BiaIlOOY.d.ts → VMCheckpoints-MK--EBH2.d.ts} +3 -3
- package/dist/{Value-CXJqDH9J.d.cts → Value-BUi1RA3S.d.cts} +124 -5
- package/dist/{Value-CXJqDH9J.d.ts → Value-BUi1RA3S.d.ts} +124 -5
- package/dist/WorkerError-_-RkoQ5P.d.ts +75 -0
- package/dist/WorkerError-gzmaopj2.d.cts +75 -0
- package/dist/{chunk-GQCOSXMG.js → chunk-267JPOTF.js} +43 -5
- package/dist/chunk-267JPOTF.js.map +1 -0
- package/dist/{chunk-JMXUNXQS.cjs → chunk-2TZKENDH.cjs} +51 -8
- package/dist/chunk-2TZKENDH.cjs.map +1 -0
- package/dist/chunk-3OWCDIPN.js +215 -0
- package/dist/chunk-3OWCDIPN.js.map +1 -0
- package/dist/{chunk-VB37OC6I.js → chunk-4D6NIHE2.js} +40 -3
- package/dist/chunk-4D6NIHE2.js.map +1 -0
- package/dist/{chunk-YXCTLWOH.js → chunk-4HQKTMWG.js} +1530 -57
- package/dist/chunk-4HQKTMWG.js.map +1 -0
- package/dist/{chunk-TY3TLZAW.cjs → chunk-536WPM2V.cjs} +18 -2
- package/dist/chunk-536WPM2V.cjs.map +1 -0
- package/dist/chunk-5HRB36DK.js +405 -0
- package/dist/chunk-5HRB36DK.js.map +1 -0
- package/dist/chunk-5ON7PUAZ.js +12 -0
- package/dist/chunk-5ON7PUAZ.js.map +1 -0
- package/dist/{chunk-KV7UW6T6.js → chunk-7KYSUDQO.js} +12 -5
- package/dist/chunk-7KYSUDQO.js.map +1 -0
- package/dist/{chunk-6WFMPTGB.cjs → chunk-7ZX6B7SY.cjs} +774 -528
- package/dist/chunk-7ZX6B7SY.cjs.map +1 -0
- package/dist/chunk-ALYRJ72W.cjs +434 -0
- package/dist/chunk-ALYRJ72W.cjs.map +1 -0
- package/dist/{chunk-5KMIY374.cjs → chunk-B4HBEFTB.cjs} +17 -2
- package/dist/chunk-B4HBEFTB.cjs.map +1 -0
- package/dist/chunk-B7NLZMQ3.cjs +74 -0
- package/dist/chunk-B7NLZMQ3.cjs.map +1 -0
- package/dist/{chunk-UQ3UIZJC.js → chunk-BLI4NIQY.js} +6 -2
- package/dist/chunk-BLI4NIQY.js.map +1 -0
- package/dist/{chunk-IP7ASJEW.js → chunk-BYJBUL7U.js} +5 -5
- package/dist/{chunk-IP7ASJEW.js.map → chunk-BYJBUL7U.js.map} +1 -1
- package/dist/{chunk-G535KJEG.js → chunk-CCBZZQAE.js} +2 -2
- package/dist/{chunk-G535KJEG.js.map → chunk-CCBZZQAE.js.map} +1 -1
- package/dist/chunk-CKQMXMHR.cjs +219 -0
- package/dist/chunk-CKQMXMHR.cjs.map +1 -0
- package/dist/{chunk-T556MJDZ.cjs → chunk-CUR2WLI4.cjs} +11 -11
- package/dist/{chunk-T556MJDZ.cjs.map → chunk-CUR2WLI4.cjs.map} +1 -1
- package/dist/{chunk-AA3KTWTX.js → chunk-DLEBSLF4.js} +4 -4
- package/dist/{chunk-AA3KTWTX.js.map → chunk-DLEBSLF4.js.map} +1 -1
- package/dist/{chunk-524F3ATQ.cjs → chunk-E23GZEWL.cjs} +15 -9
- package/dist/chunk-E23GZEWL.cjs.map +1 -0
- package/dist/{chunk-PFUESQTW.cjs → chunk-EJ3ILXX6.cjs} +48 -2
- package/dist/chunk-EJ3ILXX6.cjs.map +1 -0
- package/dist/{chunk-526PMQOA.js → chunk-ENKKJYD3.js} +10 -4
- package/dist/chunk-ENKKJYD3.js.map +1 -0
- package/dist/{chunk-5X2PTP6F.cjs → chunk-ENRIK36Q.cjs} +2 -12
- package/dist/chunk-ENRIK36Q.cjs.map +1 -0
- package/dist/{chunk-3D7V24DG.js → chunk-ERCOHGXD.js} +17 -2
- package/dist/chunk-ERCOHGXD.js.map +1 -0
- package/dist/{chunk-IF532O7C.js → chunk-FD5ZZHEU.js} +3 -12
- package/dist/chunk-FD5ZZHEU.js.map +1 -0
- package/dist/{chunk-7FSDNNNC.js → chunk-GLA4JXBO.js} +11 -5
- package/dist/chunk-GLA4JXBO.js.map +1 -0
- package/dist/{chunk-UM6BVY2S.cjs → chunk-HIQ5HSZL.cjs} +175 -43
- package/dist/chunk-HIQ5HSZL.cjs.map +1 -0
- package/dist/{chunk-HVQFNJKE.cjs → chunk-HVRVSI2Z.cjs} +104 -86
- package/dist/chunk-HVRVSI2Z.cjs.map +1 -0
- package/dist/{chunk-3LAEG75D.js → chunk-I4GAWIPW.js} +24 -6
- package/dist/chunk-I4GAWIPW.js.map +1 -0
- package/dist/{chunk-PA4VC73I.cjs → chunk-J45BCEZ4.cjs} +33 -27
- package/dist/chunk-J45BCEZ4.cjs.map +1 -0
- package/dist/{chunk-FQGX2PA2.js → chunk-JG6ZJ2WU.js} +128 -4
- package/dist/chunk-JG6ZJ2WU.js.map +1 -0
- package/dist/chunk-L2TE7PMO.cjs +14 -0
- package/dist/chunk-L2TE7PMO.cjs.map +1 -0
- package/dist/chunk-LHZ6VOA7.js +1764 -0
- package/dist/chunk-LHZ6VOA7.js.map +1 -0
- package/dist/{chunk-SESSWASV.cjs → chunk-MN3LHRGV.cjs} +1868 -393
- package/dist/chunk-MN3LHRGV.cjs.map +1 -0
- package/dist/{chunk-R3PY4G7J.js → chunk-MVTOCRV2.js} +48 -3
- package/dist/chunk-MVTOCRV2.js.map +1 -0
- package/dist/{chunk-FE23VSSA.cjs → chunk-N5NNW4VG.cjs} +6 -6
- package/dist/{chunk-FE23VSSA.cjs.map → chunk-N5NNW4VG.cjs.map} +1 -1
- package/dist/{chunk-Y7FT4IQT.js → chunk-NKW7LKYU.js} +266 -28
- package/dist/chunk-NKW7LKYU.js.map +1 -0
- package/dist/{chunk-O3ANBHSA.js → chunk-NNQ2TYDF.js} +123 -5
- package/dist/chunk-NNQ2TYDF.js.map +1 -0
- package/dist/{chunk-NG2JHZHE.js → chunk-NNZAEUDW.js} +1853 -2640
- package/dist/chunk-NNZAEUDW.js.map +1 -0
- package/dist/{chunk-5LI5EPGJ.cjs → chunk-QFTDTX6K.cjs} +40 -3
- package/dist/chunk-QFTDTX6K.cjs.map +1 -0
- package/dist/{chunk-HDP7VK3C.cjs → chunk-SRGQ72IR.cjs} +649 -349
- package/dist/chunk-SRGQ72IR.cjs.map +1 -0
- package/dist/{chunk-4B2CNWQU.cjs → chunk-SSV46KFA.cjs} +14 -7
- package/dist/chunk-SSV46KFA.cjs.map +1 -0
- package/dist/{chunk-HBVFFBRR.cjs → chunk-T6ZYQJ63.cjs} +1962 -2748
- package/dist/chunk-T6ZYQJ63.cjs.map +1 -0
- package/dist/{chunk-AJA6LUI7.js → chunk-UO6BUV6K.js} +18 -2
- package/dist/chunk-UO6BUV6K.js.map +1 -0
- package/dist/chunk-WWQEY7BV.js +67 -0
- package/dist/chunk-WWQEY7BV.js.map +1 -0
- package/dist/{chunk-5WVP4YHP.js → chunk-WXEHD6TT.js} +333 -33
- package/dist/chunk-WXEHD6TT.js.map +1 -0
- package/dist/{chunk-47LRVGOT.cjs → chunk-XA4CKRML.cjs} +2 -2
- package/dist/{chunk-47LRVGOT.cjs.map → chunk-XA4CKRML.cjs.map} +1 -1
- package/dist/{chunk-6KFYJ6TD.cjs → chunk-XIYYHA65.cjs} +6 -2
- package/dist/chunk-XIYYHA65.cjs.map +1 -0
- package/dist/chunk-YRIKITGF.cjs +1768 -0
- package/dist/chunk-YRIKITGF.cjs.map +1 -0
- package/dist/{chunk-TMA4RCEN.js → chunk-Z7XGGLI2.js} +3 -3
- package/dist/{chunk-TMA4RCEN.js.map → chunk-Z7XGGLI2.js.map} +1 -1
- package/dist/{chunk-R7YVBHCV.cjs → chunk-ZMW6NU2K.cjs} +197 -73
- package/dist/chunk-ZMW6NU2K.cjs.map +1 -0
- package/dist/{chunk-A2N2GFCG.cjs → chunk-ZVTWQLK4.cjs} +10 -10
- package/dist/{chunk-A2N2GFCG.cjs.map → chunk-ZVTWQLK4.cjs.map} +1 -1
- package/dist/constants.cjs +5 -5
- package/dist/constants.d.cts +1 -1
- package/dist/constants.d.ts +1 -1
- package/dist/constants.js +2 -2
- package/dist/engine.cjs +52 -35
- package/dist/engine.d.cts +13 -13
- package/dist/engine.d.ts +13 -13
- package/dist/engine.js +26 -21
- package/dist/errors.cjs +44 -19
- package/dist/errors.d.cts +3 -2
- package/dist/errors.d.ts +3 -2
- package/dist/errors.js +2 -1
- package/dist/format.cjs +19 -169
- package/dist/format.cjs.map +1 -1
- package/dist/format.d.cts +18 -26
- package/dist/format.d.ts +18 -26
- package/dist/format.js +7 -171
- package/dist/format.js.map +1 -1
- package/dist/index.cjs +250 -31
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +110 -74
- package/dist/index.d.ts +110 -74
- package/dist/index.js +228 -23
- package/dist/index.js.map +1 -1
- package/dist/language.cjs +9 -9
- package/dist/language.d.cts +12 -12
- package/dist/language.d.ts +12 -12
- package/dist/language.js +3 -3
- package/dist/lexer.cjs +16 -16
- package/dist/lexer.d.cts +3 -3
- package/dist/lexer.d.ts +3 -3
- package/dist/lexer.js +5 -5
- package/dist/normalizer.cjs +10 -10
- package/dist/normalizer.d.cts +3 -3
- package/dist/normalizer.d.ts +3 -3
- package/dist/normalizer.js +4 -4
- package/dist/packages.cjs +45 -36
- package/dist/packages.d.cts +135 -31
- package/dist/packages.d.ts +135 -31
- package/dist/packages.js +14 -13
- package/dist/parser.cjs +16 -16
- package/dist/parser.d.cts +6 -5
- package/dist/parser.d.ts +6 -5
- package/dist/parser.js +6 -6
- package/dist/{pipeline-BEb3hujr.d.cts → pipeline-CtfJtPQc.d.cts} +3 -3
- package/dist/{pipeline-B6k5lCB7.d.ts → pipeline-DCd5M6Gk.d.ts} +3 -3
- package/dist/resolvers.d.cts +3 -3
- package/dist/resolvers.d.ts +3 -3
- package/dist/testing.cjs +478 -0
- package/dist/testing.cjs.map +1 -0
- package/dist/testing.d.cts +271 -0
- package/dist/testing.d.ts +271 -0
- package/dist/testing.js +470 -0
- package/dist/testing.js.map +1 -0
- package/dist/uom.cjs +16 -16
- package/dist/uom.d.cts +3 -3
- package/dist/uom.d.ts +3 -3
- package/dist/uom.js +6 -6
- package/dist/utilities.cjs +6 -5
- package/dist/utilities.js +2 -1
- package/dist/vm.cjs +34 -34
- package/dist/vm.d.cts +8 -8
- package/dist/vm.d.ts +8 -8
- package/dist/vm.js +9 -9
- package/dist/worker.cjs +493 -0
- package/dist/worker.cjs.map +1 -0
- package/dist/worker.d.cts +509 -0
- package/dist/worker.d.ts +509 -0
- package/dist/worker.js +484 -0
- package/dist/worker.js.map +1 -0
- package/package.json +21 -1
- package/dist/chunk-3D7V24DG.js.map +0 -1
- package/dist/chunk-3LAEG75D.js.map +0 -1
- package/dist/chunk-4B2CNWQU.cjs.map +0 -1
- package/dist/chunk-524F3ATQ.cjs.map +0 -1
- package/dist/chunk-526PMQOA.js.map +0 -1
- package/dist/chunk-5KMIY374.cjs.map +0 -1
- package/dist/chunk-5LI5EPGJ.cjs.map +0 -1
- package/dist/chunk-5WVP4YHP.js.map +0 -1
- package/dist/chunk-5X2PTP6F.cjs.map +0 -1
- package/dist/chunk-6KFYJ6TD.cjs.map +0 -1
- package/dist/chunk-6WFMPTGB.cjs.map +0 -1
- package/dist/chunk-7FSDNNNC.js.map +0 -1
- package/dist/chunk-AJA6LUI7.js.map +0 -1
- package/dist/chunk-FQGX2PA2.js.map +0 -1
- package/dist/chunk-GQCOSXMG.js.map +0 -1
- package/dist/chunk-HBVFFBRR.cjs.map +0 -1
- package/dist/chunk-HDP7VK3C.cjs.map +0 -1
- package/dist/chunk-HVQFNJKE.cjs.map +0 -1
- package/dist/chunk-IF532O7C.js.map +0 -1
- package/dist/chunk-JMXUNXQS.cjs.map +0 -1
- package/dist/chunk-KV7UW6T6.js.map +0 -1
- package/dist/chunk-NG2JHZHE.js.map +0 -1
- package/dist/chunk-O3ANBHSA.js.map +0 -1
- package/dist/chunk-PA4VC73I.cjs.map +0 -1
- package/dist/chunk-PFUESQTW.cjs.map +0 -1
- package/dist/chunk-R3PY4G7J.js.map +0 -1
- package/dist/chunk-R7YVBHCV.cjs.map +0 -1
- package/dist/chunk-SESSWASV.cjs.map +0 -1
- package/dist/chunk-TY3TLZAW.cjs.map +0 -1
- package/dist/chunk-UM6BVY2S.cjs.map +0 -1
- package/dist/chunk-UQ3UIZJC.js.map +0 -1
- package/dist/chunk-VB37OC6I.js.map +0 -1
- package/dist/chunk-Y7FT4IQT.js.map +0 -1
- package/dist/chunk-YXCTLWOH.js.map +0 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { V as Value } from './Value-
|
|
2
|
-
import { U as UserFunctionDef, A as AnonymousBodyDef, a as BytecodeProgram } from './BytecodeBuilder-
|
|
3
|
-
import { E as EngineError } from './EngineError-
|
|
4
|
-
import { D as DiagnosticPipeline } from './pipeline-
|
|
1
|
+
import { V as Value } from './Value-BUi1RA3S.cjs';
|
|
2
|
+
import { U as UserFunctionDef, A as AnonymousBodyDef, a as BytecodeProgram } from './BytecodeBuilder-Bp9xeTmX.cjs';
|
|
3
|
+
import { E as EngineError } from './EngineError-B61GS1jp.cjs';
|
|
4
|
+
import { D as DiagnosticPipeline } from './pipeline-CtfJtPQc.cjs';
|
|
5
5
|
import { VariableResolver } from './variables.cjs';
|
|
6
6
|
|
|
7
7
|
/**
|
|
@@ -39,7 +39,7 @@ import { VariableResolver } from './variables.cjs';
|
|
|
39
39
|
* -100).
|
|
40
40
|
* @param context - Registries belonging to the engine that created this VM.
|
|
41
41
|
*/
|
|
42
|
-
declare function createVM(registry: OpRegistry, maxStackDepth?: number, maxInstructions?: number, maxFunctionRecursionDepth?: number, maxCollectionSize?: number, maxAllocatedElements?: number, maxFunctionCalls?: number, maxDateOffsetYears?: number, minDateOffsetYears?: number, context?: EngineContext): VM;
|
|
42
|
+
declare function createVM(registry: OpRegistry, maxStackDepth?: number, maxInstructions?: number, maxFunctionRecursionDepth?: number, maxCollectionSize?: number, maxAllocatedElements?: number, maxFunctionCalls?: number, maxDateOffsetYears?: number, minDateOffsetYears?: number, context?: EngineContext, holidayPredicate?: (epochMs: number) => boolean): VM;
|
|
43
43
|
/**
|
|
44
44
|
* Compiled bytecode ready for VM execution.
|
|
45
45
|
*
|
|
@@ -81,6 +81,44 @@ interface LineExecutionContext {
|
|
|
81
81
|
getLineResult?: (lineNumber: number) => Value | undefined;
|
|
82
82
|
/** Whether line `lineNumber` is a blank line or a `#` heading, the stopping condition for "total above"/"sum above"/"average above" aggregation. */
|
|
83
83
|
isLineBoundary?: (lineNumber: number) => boolean;
|
|
84
|
+
/**
|
|
85
|
+
* The variables another line's expression reads, by 1-based line number, or
|
|
86
|
+
* `undefined` when the line has no evaluated expression (forward reference,
|
|
87
|
+
* out of range, or markdown). Goal seek (`packages/goalseek/`) uses it to
|
|
88
|
+
* refuse up front when the variable it was asked to vary is one the target
|
|
89
|
+
* line never reads, rather than searching a relationship that cannot move.
|
|
90
|
+
*/
|
|
91
|
+
getLineReads?: (lineNumber: number) => string[] | undefined;
|
|
92
|
+
/**
|
|
93
|
+
* Re-evaluate another line's already-compiled expression with `variable`
|
|
94
|
+
* bound to `bound` for that one evaluation, without disturbing the
|
|
95
|
+
* document's own value for it. This is the primitive goal seek
|
|
96
|
+
* (`packages/goalseek/`) drives: binding a numeric candidate probes the
|
|
97
|
+
* relationship, binding a symbolic placeholder (with `symbolicTolerant`)
|
|
98
|
+
* reads it back in closed form. Returns an error Value when there is no
|
|
99
|
+
* document, the line is not a plain expression ready to run, or its
|
|
100
|
+
* re-evaluation itself faults. The binding is a call frame, so it shadows
|
|
101
|
+
* the document's value exactly the way a function parameter does and is
|
|
102
|
+
* gone the moment the probe returns.
|
|
103
|
+
*/
|
|
104
|
+
evaluateLineWithBinding?: (lineNumber: number, variable: string, bound: Value, symbolicTolerant: boolean) => Value;
|
|
105
|
+
/**
|
|
106
|
+
* The hard ceiling on goal seek's bisection steps, from
|
|
107
|
+
* `config.vm.maxGoalSeekIterations`. Carried on the context so the search,
|
|
108
|
+
* which runs as a plugin function with no other view of engine config, is
|
|
109
|
+
* bounded by the host's configured limit rather than a hardcoded one.
|
|
110
|
+
*/
|
|
111
|
+
goalSeekMaxIterations?: number;
|
|
112
|
+
/**
|
|
113
|
+
* The RAW markdown text of line `lineNumber` (1-based), or `undefined`
|
|
114
|
+
* when there is no real document or the line is out of range. Distinct
|
|
115
|
+
* from `getLineResult`, which returns a line's evaluated Value: a
|
|
116
|
+
* markdown table's rows are skipped by the evaluator and hold no result,
|
|
117
|
+
* so reading a column as data has to go back to the source text. Backs
|
|
118
|
+
* the tables package (`packages/tables/`), which walks upward from the
|
|
119
|
+
* current line to find the nearest table and read one of its columns.
|
|
120
|
+
*/
|
|
121
|
+
getLineText?: (lineNumber: number) => string | undefined;
|
|
84
122
|
}
|
|
85
123
|
/**
|
|
86
124
|
* Discriminated union returned by {@link executeBytecode}.
|
|
@@ -389,6 +427,17 @@ interface VM {
|
|
|
389
427
|
defineUserFunction(name: string, params: string[], program: BytecodeProgram): void;
|
|
390
428
|
getUserFunction(name: string): UserFunctionDef | undefined;
|
|
391
429
|
hasUserFunction(name: string): boolean;
|
|
430
|
+
/**
|
|
431
|
+
* Every session-scoped variable currently defined, as `[name, value]` pairs,
|
|
432
|
+
* for snapshotting the VM's state (see `engine/EngineSnapshot.ts`). The
|
|
433
|
+
* returned array is a fresh copy, so mutating it does not touch the store,
|
|
434
|
+
* and it reads the flat document-variable table only, never a transient
|
|
435
|
+
* user-function call frame (those are call-scoped and gone by the time any
|
|
436
|
+
* snapshot is taken).
|
|
437
|
+
*/
|
|
438
|
+
getVariableEntries(): [string, Value][];
|
|
439
|
+
/** Every user-defined function currently defined, as a fresh array copy, for snapshotting (see {@link getVariableEntries}). */
|
|
440
|
+
getUserFunctionDefs(): UserFunctionDef[];
|
|
392
441
|
/** Register (or redefine) a bare equation (`a*x = rhs`), keyed by its free variable. See {@link EquationDef}. */
|
|
393
442
|
defineEquation(variable: string, factorNames: string[], rhsProgram: BytecodeProgram): void;
|
|
394
443
|
getEquation(variable: string): EquationDef | undefined;
|
|
@@ -431,6 +480,8 @@ interface VM {
|
|
|
431
480
|
getMaxDateOffsetYears(): number;
|
|
432
481
|
/** The same bound backwards, as a negative number of years. */
|
|
433
482
|
getMinDateOffsetYears(): number;
|
|
483
|
+
/** Whether the host's public-holiday calendar marks `epochMs` a holiday, for working-day arithmetic. Always `false` when no calendar is configured (weekends-only). Set from `constants/Configuration.ts`'s `date.holidays`; see `vm/HolidayCalendar.ts`. */
|
|
484
|
+
isHoliday(epochMs: number): boolean;
|
|
434
485
|
getInstructionCount(): number;
|
|
435
486
|
incrementInstructions(n: number): void;
|
|
436
487
|
/** Active AbortSignal for the current expression evaluation. Checked before cache writes. */
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { V as Value } from './Value-
|
|
2
|
-
import { U as UserFunctionDef, A as AnonymousBodyDef, a as BytecodeProgram } from './BytecodeBuilder-
|
|
3
|
-
import { E as EngineError } from './EngineError-
|
|
4
|
-
import { D as DiagnosticPipeline } from './pipeline-
|
|
1
|
+
import { V as Value } from './Value-BUi1RA3S.js';
|
|
2
|
+
import { U as UserFunctionDef, A as AnonymousBodyDef, a as BytecodeProgram } from './BytecodeBuilder-Bp9xeTmX.js';
|
|
3
|
+
import { E as EngineError } from './EngineError-B61GS1jp.js';
|
|
4
|
+
import { D as DiagnosticPipeline } from './pipeline-DCd5M6Gk.js';
|
|
5
5
|
import { VariableResolver } from './variables.js';
|
|
6
6
|
|
|
7
7
|
/**
|
|
@@ -39,7 +39,7 @@ import { VariableResolver } from './variables.js';
|
|
|
39
39
|
* -100).
|
|
40
40
|
* @param context - Registries belonging to the engine that created this VM.
|
|
41
41
|
*/
|
|
42
|
-
declare function createVM(registry: OpRegistry, maxStackDepth?: number, maxInstructions?: number, maxFunctionRecursionDepth?: number, maxCollectionSize?: number, maxAllocatedElements?: number, maxFunctionCalls?: number, maxDateOffsetYears?: number, minDateOffsetYears?: number, context?: EngineContext): VM;
|
|
42
|
+
declare function createVM(registry: OpRegistry, maxStackDepth?: number, maxInstructions?: number, maxFunctionRecursionDepth?: number, maxCollectionSize?: number, maxAllocatedElements?: number, maxFunctionCalls?: number, maxDateOffsetYears?: number, minDateOffsetYears?: number, context?: EngineContext, holidayPredicate?: (epochMs: number) => boolean): VM;
|
|
43
43
|
/**
|
|
44
44
|
* Compiled bytecode ready for VM execution.
|
|
45
45
|
*
|
|
@@ -81,6 +81,44 @@ interface LineExecutionContext {
|
|
|
81
81
|
getLineResult?: (lineNumber: number) => Value | undefined;
|
|
82
82
|
/** Whether line `lineNumber` is a blank line or a `#` heading, the stopping condition for "total above"/"sum above"/"average above" aggregation. */
|
|
83
83
|
isLineBoundary?: (lineNumber: number) => boolean;
|
|
84
|
+
/**
|
|
85
|
+
* The variables another line's expression reads, by 1-based line number, or
|
|
86
|
+
* `undefined` when the line has no evaluated expression (forward reference,
|
|
87
|
+
* out of range, or markdown). Goal seek (`packages/goalseek/`) uses it to
|
|
88
|
+
* refuse up front when the variable it was asked to vary is one the target
|
|
89
|
+
* line never reads, rather than searching a relationship that cannot move.
|
|
90
|
+
*/
|
|
91
|
+
getLineReads?: (lineNumber: number) => string[] | undefined;
|
|
92
|
+
/**
|
|
93
|
+
* Re-evaluate another line's already-compiled expression with `variable`
|
|
94
|
+
* bound to `bound` for that one evaluation, without disturbing the
|
|
95
|
+
* document's own value for it. This is the primitive goal seek
|
|
96
|
+
* (`packages/goalseek/`) drives: binding a numeric candidate probes the
|
|
97
|
+
* relationship, binding a symbolic placeholder (with `symbolicTolerant`)
|
|
98
|
+
* reads it back in closed form. Returns an error Value when there is no
|
|
99
|
+
* document, the line is not a plain expression ready to run, or its
|
|
100
|
+
* re-evaluation itself faults. The binding is a call frame, so it shadows
|
|
101
|
+
* the document's value exactly the way a function parameter does and is
|
|
102
|
+
* gone the moment the probe returns.
|
|
103
|
+
*/
|
|
104
|
+
evaluateLineWithBinding?: (lineNumber: number, variable: string, bound: Value, symbolicTolerant: boolean) => Value;
|
|
105
|
+
/**
|
|
106
|
+
* The hard ceiling on goal seek's bisection steps, from
|
|
107
|
+
* `config.vm.maxGoalSeekIterations`. Carried on the context so the search,
|
|
108
|
+
* which runs as a plugin function with no other view of engine config, is
|
|
109
|
+
* bounded by the host's configured limit rather than a hardcoded one.
|
|
110
|
+
*/
|
|
111
|
+
goalSeekMaxIterations?: number;
|
|
112
|
+
/**
|
|
113
|
+
* The RAW markdown text of line `lineNumber` (1-based), or `undefined`
|
|
114
|
+
* when there is no real document or the line is out of range. Distinct
|
|
115
|
+
* from `getLineResult`, which returns a line's evaluated Value: a
|
|
116
|
+
* markdown table's rows are skipped by the evaluator and hold no result,
|
|
117
|
+
* so reading a column as data has to go back to the source text. Backs
|
|
118
|
+
* the tables package (`packages/tables/`), which walks upward from the
|
|
119
|
+
* current line to find the nearest table and read one of its columns.
|
|
120
|
+
*/
|
|
121
|
+
getLineText?: (lineNumber: number) => string | undefined;
|
|
84
122
|
}
|
|
85
123
|
/**
|
|
86
124
|
* Discriminated union returned by {@link executeBytecode}.
|
|
@@ -389,6 +427,17 @@ interface VM {
|
|
|
389
427
|
defineUserFunction(name: string, params: string[], program: BytecodeProgram): void;
|
|
390
428
|
getUserFunction(name: string): UserFunctionDef | undefined;
|
|
391
429
|
hasUserFunction(name: string): boolean;
|
|
430
|
+
/**
|
|
431
|
+
* Every session-scoped variable currently defined, as `[name, value]` pairs,
|
|
432
|
+
* for snapshotting the VM's state (see `engine/EngineSnapshot.ts`). The
|
|
433
|
+
* returned array is a fresh copy, so mutating it does not touch the store,
|
|
434
|
+
* and it reads the flat document-variable table only, never a transient
|
|
435
|
+
* user-function call frame (those are call-scoped and gone by the time any
|
|
436
|
+
* snapshot is taken).
|
|
437
|
+
*/
|
|
438
|
+
getVariableEntries(): [string, Value][];
|
|
439
|
+
/** Every user-defined function currently defined, as a fresh array copy, for snapshotting (see {@link getVariableEntries}). */
|
|
440
|
+
getUserFunctionDefs(): UserFunctionDef[];
|
|
392
441
|
/** Register (or redefine) a bare equation (`a*x = rhs`), keyed by its free variable. See {@link EquationDef}. */
|
|
393
442
|
defineEquation(variable: string, factorNames: string[], rhsProgram: BytecodeProgram): void;
|
|
394
443
|
getEquation(variable: string): EquationDef | undefined;
|
|
@@ -431,6 +480,8 @@ interface VM {
|
|
|
431
480
|
getMaxDateOffsetYears(): number;
|
|
432
481
|
/** The same bound backwards, as a negative number of years. */
|
|
433
482
|
getMinDateOffsetYears(): number;
|
|
483
|
+
/** Whether the host's public-holiday calendar marks `epochMs` a holiday, for working-day arithmetic. Always `false` when no calendar is configured (weekends-only). Set from `constants/Configuration.ts`'s `date.holidays`; see `vm/HolidayCalendar.ts`. */
|
|
484
|
+
isHoliday(epochMs: number): boolean;
|
|
434
485
|
getInstructionCount(): number;
|
|
435
486
|
incrementInstructions(n: number): void;
|
|
436
487
|
/** Active AbortSignal for the current expression evaluation. Checked before cache writes. */
|
|
@@ -48,6 +48,7 @@ declare const TokenTypes: {
|
|
|
48
48
|
readonly MINUS: "MINUS";
|
|
49
49
|
readonly STAR: "STAR";
|
|
50
50
|
readonly SLASH: "SLASH";
|
|
51
|
+
readonly PLUS_MINUS: "PLUS_MINUS";
|
|
51
52
|
readonly CARET: "CARET";
|
|
52
53
|
readonly PERCENT: "PERCENT";
|
|
53
54
|
readonly LSHIFT: "LSHIFT";
|
|
@@ -163,6 +164,8 @@ declare const TokenTypes: {
|
|
|
163
164
|
readonly IS: "IS";
|
|
164
165
|
readonly PCT_ON: "PCT_ON";
|
|
165
166
|
readonly PCT_OFF: "PCT_OFF";
|
|
167
|
+
readonly PCT_UP: "PCT_UP";
|
|
168
|
+
readonly PCT_DOWN: "PCT_DOWN";
|
|
166
169
|
readonly OF_WHAT: "OF_WHAT";
|
|
167
170
|
readonly OFF_WHAT: "OFF_WHAT";
|
|
168
171
|
readonly ON_WHAT: "ON_WHAT";
|
|
@@ -192,6 +195,8 @@ declare const TokenTypes: {
|
|
|
192
195
|
readonly BACKTICK_OPEN: "BACKTICK_OPEN";
|
|
193
196
|
readonly INLINE_SOLVE_START: "INLINE_SOLVE_START";
|
|
194
197
|
readonly COMMENT: "COMMENT";
|
|
198
|
+
readonly HEX_COLOUR: "HEX_COLOUR";
|
|
199
|
+
readonly COLOUR_CALL: "COLOUR_CALL";
|
|
195
200
|
readonly VEC2: "VEC2";
|
|
196
201
|
readonly VEC3: "VEC3";
|
|
197
202
|
readonly VEC4: "VEC4";
|
|
@@ -241,6 +246,9 @@ declare const TokenTypes: {
|
|
|
241
246
|
readonly AT_RATE: "AT_RATE";
|
|
242
247
|
readonly WEEK_IN: "WEEK_IN";
|
|
243
248
|
readonly BETWEEN_UNIT: "BETWEEN_UNIT";
|
|
249
|
+
readonly WORKDAYS_AFTER: "WORKDAYS_AFTER";
|
|
250
|
+
readonly WORKDAYS_BEFORE: "WORKDAYS_BEFORE";
|
|
251
|
+
readonly WORKDAYS_BETWEEN: "WORKDAYS_BETWEEN";
|
|
244
252
|
readonly IS_WEEKEND: "IS_WEEKEND";
|
|
245
253
|
readonly IS_WORKDAY: "IS_WORKDAY";
|
|
246
254
|
readonly VIDEO_TIMECODE: "VIDEO_TIMECODE";
|
|
@@ -254,6 +262,7 @@ declare const TokenTypes: {
|
|
|
254
262
|
readonly TOTAL_ABOVE: "TOTAL_ABOVE";
|
|
255
263
|
readonly SUM_ABOVE: "SUM_ABOVE";
|
|
256
264
|
readonly AVERAGE_ABOVE: "AVERAGE_ABOVE";
|
|
265
|
+
readonly GOAL_SEEK: "GOAL_SEEK";
|
|
257
266
|
};
|
|
258
267
|
/**
|
|
259
268
|
* A token's kind, as a string.
|
|
@@ -48,6 +48,7 @@ declare const TokenTypes: {
|
|
|
48
48
|
readonly MINUS: "MINUS";
|
|
49
49
|
readonly STAR: "STAR";
|
|
50
50
|
readonly SLASH: "SLASH";
|
|
51
|
+
readonly PLUS_MINUS: "PLUS_MINUS";
|
|
51
52
|
readonly CARET: "CARET";
|
|
52
53
|
readonly PERCENT: "PERCENT";
|
|
53
54
|
readonly LSHIFT: "LSHIFT";
|
|
@@ -163,6 +164,8 @@ declare const TokenTypes: {
|
|
|
163
164
|
readonly IS: "IS";
|
|
164
165
|
readonly PCT_ON: "PCT_ON";
|
|
165
166
|
readonly PCT_OFF: "PCT_OFF";
|
|
167
|
+
readonly PCT_UP: "PCT_UP";
|
|
168
|
+
readonly PCT_DOWN: "PCT_DOWN";
|
|
166
169
|
readonly OF_WHAT: "OF_WHAT";
|
|
167
170
|
readonly OFF_WHAT: "OFF_WHAT";
|
|
168
171
|
readonly ON_WHAT: "ON_WHAT";
|
|
@@ -192,6 +195,8 @@ declare const TokenTypes: {
|
|
|
192
195
|
readonly BACKTICK_OPEN: "BACKTICK_OPEN";
|
|
193
196
|
readonly INLINE_SOLVE_START: "INLINE_SOLVE_START";
|
|
194
197
|
readonly COMMENT: "COMMENT";
|
|
198
|
+
readonly HEX_COLOUR: "HEX_COLOUR";
|
|
199
|
+
readonly COLOUR_CALL: "COLOUR_CALL";
|
|
195
200
|
readonly VEC2: "VEC2";
|
|
196
201
|
readonly VEC3: "VEC3";
|
|
197
202
|
readonly VEC4: "VEC4";
|
|
@@ -241,6 +246,9 @@ declare const TokenTypes: {
|
|
|
241
246
|
readonly AT_RATE: "AT_RATE";
|
|
242
247
|
readonly WEEK_IN: "WEEK_IN";
|
|
243
248
|
readonly BETWEEN_UNIT: "BETWEEN_UNIT";
|
|
249
|
+
readonly WORKDAYS_AFTER: "WORKDAYS_AFTER";
|
|
250
|
+
readonly WORKDAYS_BEFORE: "WORKDAYS_BEFORE";
|
|
251
|
+
readonly WORKDAYS_BETWEEN: "WORKDAYS_BETWEEN";
|
|
244
252
|
readonly IS_WEEKEND: "IS_WEEKEND";
|
|
245
253
|
readonly IS_WORKDAY: "IS_WORKDAY";
|
|
246
254
|
readonly VIDEO_TIMECODE: "VIDEO_TIMECODE";
|
|
@@ -254,6 +262,7 @@ declare const TokenTypes: {
|
|
|
254
262
|
readonly TOTAL_ABOVE: "TOTAL_ABOVE";
|
|
255
263
|
readonly SUM_ABOVE: "SUM_ABOVE";
|
|
256
264
|
readonly AVERAGE_ABOVE: "AVERAGE_ABOVE";
|
|
265
|
+
readonly GOAL_SEEK: "GOAL_SEEK";
|
|
257
266
|
};
|
|
258
267
|
/**
|
|
259
268
|
* A token's kind, as a string.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { V as Value } from './Value-
|
|
2
|
-
import { V as VM } from './ScopeManager-
|
|
3
|
-
import { U as UserFunctionDef } from './BytecodeBuilder-
|
|
1
|
+
import { V as Value } from './Value-BUi1RA3S.cjs';
|
|
2
|
+
import { V as VM } from './ScopeManager-8vf02dwj.cjs';
|
|
3
|
+
import { U as UserFunctionDef } from './BytecodeBuilder-Bp9xeTmX.cjs';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* A point-in-time snapshot of VM variable state.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { V as Value } from './Value-
|
|
2
|
-
import { V as VM } from './ScopeManager-
|
|
3
|
-
import { U as UserFunctionDef } from './BytecodeBuilder-
|
|
1
|
+
import { V as Value } from './Value-BUi1RA3S.js';
|
|
2
|
+
import { V as VM } from './ScopeManager-CxA24W5n.js';
|
|
3
|
+
import { U as UserFunctionDef } from './BytecodeBuilder-Bp9xeTmX.js';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* A point-in-time snapshot of VM variable state.
|
|
@@ -136,6 +136,28 @@ type SymbolicNode = {
|
|
|
136
136
|
args: readonly SymbolicNode[];
|
|
137
137
|
};
|
|
138
138
|
|
|
139
|
+
/**
|
|
140
|
+
* An exact base-ten number, held as an integer coefficient and a scale.
|
|
141
|
+
*
|
|
142
|
+
* The value is `coef * 10^(-scale)`, so `Decimal(30n, 2)` is exactly `0.30` and
|
|
143
|
+
* `Decimal(1005n, 3)` is exactly `1.005`. `scale` is a non-negative integer
|
|
144
|
+
* count of fractional digits, the sign lives on `coef`, and zero is
|
|
145
|
+
* `Decimal(0n, s)` for any `s`.
|
|
146
|
+
*
|
|
147
|
+
* This is the representation money is carried in so that two prices a user
|
|
148
|
+
* typed add and multiply without the binary-floating-point error a double
|
|
149
|
+
* introduces (`0.1 + 0.2` is `0.30000000000000004` as a double, `0.30` here).
|
|
150
|
+
* It is deliberately dependency-free: a bigint coefficient plus an integer
|
|
151
|
+
* scale needs nothing the runtime does not already have, which keeps the
|
|
152
|
+
* engine's single-runtime-dependency contract intact.
|
|
153
|
+
*/
|
|
154
|
+
interface DecimalData {
|
|
155
|
+
/** The integer coefficient, carrying the sign. */
|
|
156
|
+
readonly coef: bigint;
|
|
157
|
+
/** The number of fractional digits, a non-negative integer. */
|
|
158
|
+
readonly scale: number;
|
|
159
|
+
}
|
|
160
|
+
|
|
139
161
|
/**
|
|
140
162
|
* A single matrix cell. `boolean` covers element-wise comparison results
|
|
141
163
|
* (`[1,6;3,8] < [5,2;7,4]` produces a Matrix of booleans, not numbers). A
|
|
@@ -169,6 +191,33 @@ interface RangeData {
|
|
|
169
191
|
readonly min: number;
|
|
170
192
|
readonly max: number;
|
|
171
193
|
}
|
|
194
|
+
/**
|
|
195
|
+
* How a colour was authored, and therefore how it should display. It never
|
|
196
|
+
* changes the channels: a colour is always stored as canonical sRGB (`r`,`g`,`b`
|
|
197
|
+
* integers 0-255, `a` in 0-1), and `format` only decides whether `formatValue`
|
|
198
|
+
* renders it as `#rrggbb`, `rgb(...)`, `hsl(...)` or a named keyword.
|
|
199
|
+
*/
|
|
200
|
+
type ColourFormat = "hex" | "rgb" | "rgba" | "hsl" | "hsla" | "named";
|
|
201
|
+
/**
|
|
202
|
+
* A colour value. Canonical channels are sRGB (`r`,`g`,`b` are integers 0-255,
|
|
203
|
+
* `a` is 0-1); HSL is never stored, it is derived on demand for display and for
|
|
204
|
+
* hue/saturation/lightness operations, then re-quantised back to RGBA. A
|
|
205
|
+
* `lighten` followed by an equal `darken` returns to within one rounding step of
|
|
206
|
+
* the original (integer channels re-quantise each way), and does not drift on
|
|
207
|
+
* repetition, rather than storing both HSL and RGB and letting them disagree.
|
|
208
|
+
* `format`
|
|
209
|
+
* records the authored/display form; `name` carries the CSS keyword only when
|
|
210
|
+
* `format === "named"` (e.g. `"rebeccapurple"`). Lives in a {@link Value}'s
|
|
211
|
+
* `value` slot exactly as {@link MatrixData}/{@link RangeData} do.
|
|
212
|
+
*/
|
|
213
|
+
interface ColourData {
|
|
214
|
+
readonly r: number;
|
|
215
|
+
readonly g: number;
|
|
216
|
+
readonly b: number;
|
|
217
|
+
readonly a: number;
|
|
218
|
+
readonly format: ColourFormat;
|
|
219
|
+
readonly name?: string;
|
|
220
|
+
}
|
|
172
221
|
/**
|
|
173
222
|
* Discriminated union tag for {@link Value} objects.
|
|
174
223
|
*
|
|
@@ -198,7 +247,9 @@ declare enum ValueType {
|
|
|
198
247
|
/** Async result pending resolution. Value stores the queryKey string. */
|
|
199
248
|
Pending = 12,
|
|
200
249
|
/** Plugin-raised error propagated through the DAG. Value stores error code, unit stores message. */
|
|
201
|
-
Error = 13
|
|
250
|
+
Error = 13,
|
|
251
|
+
/** A colour (hex/rgb/hsl/named). Value is {@link ColourData}. */
|
|
252
|
+
Colour = 14
|
|
202
253
|
}
|
|
203
254
|
/**
|
|
204
255
|
* Universal runtime value for the solve-js VM.
|
|
@@ -214,16 +265,81 @@ declare enum ValueType {
|
|
|
214
265
|
declare class Value {
|
|
215
266
|
private _cachedNumber;
|
|
216
267
|
type: ValueType;
|
|
217
|
-
value: number | bigint | string | boolean | MatrixData | RangeData | SymbolicNode;
|
|
268
|
+
value: number | bigint | string | boolean | MatrixData | RangeData | ColourData | SymbolicNode;
|
|
218
269
|
unit?: string;
|
|
219
270
|
/** Set by async resolvers when a fetch timed out, the result is a fallback (typically 0). */
|
|
220
271
|
timedOut?: boolean;
|
|
221
|
-
|
|
272
|
+
/**
|
|
273
|
+
* The exact base-ten value this Value stands for, when it has one.
|
|
274
|
+
*
|
|
275
|
+
* A sidecar rather than a replacement for `value`: money and decimal-point
|
|
276
|
+
* literals set it to a {@link DecimalData} so that same-currency arithmetic
|
|
277
|
+
* and display can be exact ("$0.10 + $0.20" is "$0.30", not
|
|
278
|
+
* "$0.30000000000000004"), while `value` stays the nearest double so every
|
|
279
|
+
* existing consumer that reads `.value` or `toNumber()` is unchanged. The
|
|
280
|
+
* plain Number-times-Number fast paths deliberately ignore it, which is why
|
|
281
|
+
* a bare "0.1 + 0.2" still answers the double it always did: exactness is
|
|
282
|
+
* carried only where a unit-bearing operand asks for it. Cleared by
|
|
283
|
+
* {@link recycle} so a reused arena Value never inherits a stale exact.
|
|
284
|
+
*/
|
|
285
|
+
exact?: DecimalData;
|
|
286
|
+
/**
|
|
287
|
+
* The exact rational value this Value stands for, when it has one.
|
|
288
|
+
*
|
|
289
|
+
* The second sidecar, the same shape as {@link exact} and for the same
|
|
290
|
+
* reason: a fraction has no exact base-ten form (`1/3` is not any decimal),
|
|
291
|
+
* so exact fraction arithmetic needs a numerator/denominator pair rather
|
|
292
|
+
* than a coefficient and a scale. Integer division seeds it ("1/3" carries
|
|
293
|
+
* the {@link Rational} 1/3), and `+`, `-`, `*`, `/` between rational-bearing
|
|
294
|
+
* numbers keep it reduced, so "1/49 * 49" is exactly 1 and "5/6 - 1/6 - 1/6
|
|
295
|
+
* - 1/6 - 1/6 - 1/6" is exactly 0 rather than the 1.6e-16 the doubles drift
|
|
296
|
+
* to. `value` still holds the nearest double, recomputed from the exact
|
|
297
|
+
* rational so accumulation error never creeps in, which is why the default
|
|
298
|
+
* display and every `.value`/`toNumber()` reader are unchanged. Only a
|
|
299
|
+
* fraction written with "/" carries it, so a decimal literal ("0.1") and a
|
|
300
|
+
* transcendental result ("sqrt(2)") stay the plain doubles they were.
|
|
301
|
+
* Cleared by {@link recycle} alongside {@link exact}.
|
|
302
|
+
*/
|
|
303
|
+
rational?: Rational;
|
|
304
|
+
/**
|
|
305
|
+
* The one-sigma uncertainty (standard error) this value carries, when it
|
|
306
|
+
* has one.
|
|
307
|
+
*
|
|
308
|
+
* The third sidecar, the same shape as {@link exact} and {@link rational}
|
|
309
|
+
* and for the same reason: a measurement written `12.3 ± 0.5` is still the
|
|
310
|
+
* number 12.3 everywhere it is read as one, so the type stays
|
|
311
|
+
* {@link ValueType.Number} and `value` stays the center, while this non
|
|
312
|
+
* negative field carries the tolerance. The `±` (or ASCII `+/-`) operator
|
|
313
|
+
* seeds it, and `+`, `-`, `*`, `/` propagate it in quadrature for
|
|
314
|
+
* independent errors (see `vm/VMConversion.ts`'s `uncertainOp`). Everything
|
|
315
|
+
* else (a comparison, a transcendental function, a unit conversion) reads
|
|
316
|
+
* the center through `toNumber()` and drops the tolerance, which is why a
|
|
317
|
+
* value with no uncertainty behaves exactly as a plain number always did.
|
|
318
|
+
* Cleared by {@link recycle} alongside the other two sidecars.
|
|
319
|
+
*/
|
|
320
|
+
uncertainty?: number;
|
|
321
|
+
/**
|
|
322
|
+
* The number of decimal places this value should DISPLAY at, when it has been
|
|
323
|
+
* given an explicit precision.
|
|
324
|
+
*
|
|
325
|
+
* A display sidecar, not a value one: `value` is unchanged, so every
|
|
326
|
+
* `.value`/`toNumber()` reader and all arithmetic behave exactly as before,
|
|
327
|
+
* and a value with no `decimalPlaces` formats the way it always did (the
|
|
328
|
+
* global two-place default with trailing zeros trimmed). It is set only by an
|
|
329
|
+
* explicit precision request, `<x> to N dp` and `round(x, N)`, so that
|
|
330
|
+
* `3.14159 to 4 dp` shows `3.1416` and `1.5 to 2 dp` shows `1.50` rather than
|
|
331
|
+
* the value being rounded but then displayed at the default two places. It is
|
|
332
|
+
* NOT propagated through arithmetic (a later `+ 1` re-decides precision),
|
|
333
|
+
* which is why nothing that did not ask for a precision is affected. Cleared
|
|
334
|
+
* by {@link recycle} alongside the other sidecars.
|
|
335
|
+
*/
|
|
336
|
+
decimalPlaces?: number;
|
|
337
|
+
constructor(type: ValueType, value: number | bigint | string | boolean | MatrixData | RangeData | ColourData | SymbolicNode, unit?: string);
|
|
222
338
|
/**
|
|
223
339
|
* Phase 5.3: Reset all fields for arena reuse.
|
|
224
340
|
* Called by ValueArena.acquire(), zero allocation, just field assignment.
|
|
225
341
|
*/
|
|
226
|
-
recycle(type: ValueType, value: number | bigint | string | boolean | MatrixData | RangeData | SymbolicNode, unit?: string): void;
|
|
342
|
+
recycle(type: ValueType, value: number | bigint | string | boolean | MatrixData | RangeData | ColourData | SymbolicNode, unit?: string): void;
|
|
227
343
|
isNumber(): this is Value & {
|
|
228
344
|
value: number;
|
|
229
345
|
};
|
|
@@ -244,6 +360,9 @@ declare class Value {
|
|
|
244
360
|
isRange(): this is Value & {
|
|
245
361
|
value: RangeData;
|
|
246
362
|
};
|
|
363
|
+
isColour(): this is Value & {
|
|
364
|
+
value: ColourData;
|
|
365
|
+
};
|
|
247
366
|
isSymbolic(): this is Value & {
|
|
248
367
|
value: SymbolicNode;
|
|
249
368
|
};
|
|
@@ -295,4 +414,4 @@ declare function colVectorValue(data: readonly number[]): Value;
|
|
|
295
414
|
/** Create a Range value, a first-class integer range `min:max`, both bounds inclusive. */
|
|
296
415
|
declare function rangeValue(min: number, max: number): Value;
|
|
297
416
|
|
|
298
|
-
export { type MatrixData as M, type RangeData as R, type SymbolicNode as S, Value as V, type MatrixEntry as a, ValueType as b, bigIntValue as c, colVectorValue as d, rowVectorValue as e, hexValue as h, matrixValue as m, numberValue as n, rangeValue as r, stringValue as s, uomValue as u };
|
|
417
|
+
export { type ColourData as C, type MatrixData as M, type RangeData as R, type SymbolicNode as S, Value as V, type MatrixEntry as a, ValueType as b, bigIntValue as c, colVectorValue as d, rowVectorValue as e, type ColourFormat as f, hexValue as h, matrixValue as m, numberValue as n, rangeValue as r, stringValue as s, uomValue as u };
|
|
@@ -136,6 +136,28 @@ type SymbolicNode = {
|
|
|
136
136
|
args: readonly SymbolicNode[];
|
|
137
137
|
};
|
|
138
138
|
|
|
139
|
+
/**
|
|
140
|
+
* An exact base-ten number, held as an integer coefficient and a scale.
|
|
141
|
+
*
|
|
142
|
+
* The value is `coef * 10^(-scale)`, so `Decimal(30n, 2)` is exactly `0.30` and
|
|
143
|
+
* `Decimal(1005n, 3)` is exactly `1.005`. `scale` is a non-negative integer
|
|
144
|
+
* count of fractional digits, the sign lives on `coef`, and zero is
|
|
145
|
+
* `Decimal(0n, s)` for any `s`.
|
|
146
|
+
*
|
|
147
|
+
* This is the representation money is carried in so that two prices a user
|
|
148
|
+
* typed add and multiply without the binary-floating-point error a double
|
|
149
|
+
* introduces (`0.1 + 0.2` is `0.30000000000000004` as a double, `0.30` here).
|
|
150
|
+
* It is deliberately dependency-free: a bigint coefficient plus an integer
|
|
151
|
+
* scale needs nothing the runtime does not already have, which keeps the
|
|
152
|
+
* engine's single-runtime-dependency contract intact.
|
|
153
|
+
*/
|
|
154
|
+
interface DecimalData {
|
|
155
|
+
/** The integer coefficient, carrying the sign. */
|
|
156
|
+
readonly coef: bigint;
|
|
157
|
+
/** The number of fractional digits, a non-negative integer. */
|
|
158
|
+
readonly scale: number;
|
|
159
|
+
}
|
|
160
|
+
|
|
139
161
|
/**
|
|
140
162
|
* A single matrix cell. `boolean` covers element-wise comparison results
|
|
141
163
|
* (`[1,6;3,8] < [5,2;7,4]` produces a Matrix of booleans, not numbers). A
|
|
@@ -169,6 +191,33 @@ interface RangeData {
|
|
|
169
191
|
readonly min: number;
|
|
170
192
|
readonly max: number;
|
|
171
193
|
}
|
|
194
|
+
/**
|
|
195
|
+
* How a colour was authored, and therefore how it should display. It never
|
|
196
|
+
* changes the channels: a colour is always stored as canonical sRGB (`r`,`g`,`b`
|
|
197
|
+
* integers 0-255, `a` in 0-1), and `format` only decides whether `formatValue`
|
|
198
|
+
* renders it as `#rrggbb`, `rgb(...)`, `hsl(...)` or a named keyword.
|
|
199
|
+
*/
|
|
200
|
+
type ColourFormat = "hex" | "rgb" | "rgba" | "hsl" | "hsla" | "named";
|
|
201
|
+
/**
|
|
202
|
+
* A colour value. Canonical channels are sRGB (`r`,`g`,`b` are integers 0-255,
|
|
203
|
+
* `a` is 0-1); HSL is never stored, it is derived on demand for display and for
|
|
204
|
+
* hue/saturation/lightness operations, then re-quantised back to RGBA. A
|
|
205
|
+
* `lighten` followed by an equal `darken` returns to within one rounding step of
|
|
206
|
+
* the original (integer channels re-quantise each way), and does not drift on
|
|
207
|
+
* repetition, rather than storing both HSL and RGB and letting them disagree.
|
|
208
|
+
* `format`
|
|
209
|
+
* records the authored/display form; `name` carries the CSS keyword only when
|
|
210
|
+
* `format === "named"` (e.g. `"rebeccapurple"`). Lives in a {@link Value}'s
|
|
211
|
+
* `value` slot exactly as {@link MatrixData}/{@link RangeData} do.
|
|
212
|
+
*/
|
|
213
|
+
interface ColourData {
|
|
214
|
+
readonly r: number;
|
|
215
|
+
readonly g: number;
|
|
216
|
+
readonly b: number;
|
|
217
|
+
readonly a: number;
|
|
218
|
+
readonly format: ColourFormat;
|
|
219
|
+
readonly name?: string;
|
|
220
|
+
}
|
|
172
221
|
/**
|
|
173
222
|
* Discriminated union tag for {@link Value} objects.
|
|
174
223
|
*
|
|
@@ -198,7 +247,9 @@ declare enum ValueType {
|
|
|
198
247
|
/** Async result pending resolution. Value stores the queryKey string. */
|
|
199
248
|
Pending = 12,
|
|
200
249
|
/** Plugin-raised error propagated through the DAG. Value stores error code, unit stores message. */
|
|
201
|
-
Error = 13
|
|
250
|
+
Error = 13,
|
|
251
|
+
/** A colour (hex/rgb/hsl/named). Value is {@link ColourData}. */
|
|
252
|
+
Colour = 14
|
|
202
253
|
}
|
|
203
254
|
/**
|
|
204
255
|
* Universal runtime value for the solve-js VM.
|
|
@@ -214,16 +265,81 @@ declare enum ValueType {
|
|
|
214
265
|
declare class Value {
|
|
215
266
|
private _cachedNumber;
|
|
216
267
|
type: ValueType;
|
|
217
|
-
value: number | bigint | string | boolean | MatrixData | RangeData | SymbolicNode;
|
|
268
|
+
value: number | bigint | string | boolean | MatrixData | RangeData | ColourData | SymbolicNode;
|
|
218
269
|
unit?: string;
|
|
219
270
|
/** Set by async resolvers when a fetch timed out, the result is a fallback (typically 0). */
|
|
220
271
|
timedOut?: boolean;
|
|
221
|
-
|
|
272
|
+
/**
|
|
273
|
+
* The exact base-ten value this Value stands for, when it has one.
|
|
274
|
+
*
|
|
275
|
+
* A sidecar rather than a replacement for `value`: money and decimal-point
|
|
276
|
+
* literals set it to a {@link DecimalData} so that same-currency arithmetic
|
|
277
|
+
* and display can be exact ("$0.10 + $0.20" is "$0.30", not
|
|
278
|
+
* "$0.30000000000000004"), while `value` stays the nearest double so every
|
|
279
|
+
* existing consumer that reads `.value` or `toNumber()` is unchanged. The
|
|
280
|
+
* plain Number-times-Number fast paths deliberately ignore it, which is why
|
|
281
|
+
* a bare "0.1 + 0.2" still answers the double it always did: exactness is
|
|
282
|
+
* carried only where a unit-bearing operand asks for it. Cleared by
|
|
283
|
+
* {@link recycle} so a reused arena Value never inherits a stale exact.
|
|
284
|
+
*/
|
|
285
|
+
exact?: DecimalData;
|
|
286
|
+
/**
|
|
287
|
+
* The exact rational value this Value stands for, when it has one.
|
|
288
|
+
*
|
|
289
|
+
* The second sidecar, the same shape as {@link exact} and for the same
|
|
290
|
+
* reason: a fraction has no exact base-ten form (`1/3` is not any decimal),
|
|
291
|
+
* so exact fraction arithmetic needs a numerator/denominator pair rather
|
|
292
|
+
* than a coefficient and a scale. Integer division seeds it ("1/3" carries
|
|
293
|
+
* the {@link Rational} 1/3), and `+`, `-`, `*`, `/` between rational-bearing
|
|
294
|
+
* numbers keep it reduced, so "1/49 * 49" is exactly 1 and "5/6 - 1/6 - 1/6
|
|
295
|
+
* - 1/6 - 1/6 - 1/6" is exactly 0 rather than the 1.6e-16 the doubles drift
|
|
296
|
+
* to. `value` still holds the nearest double, recomputed from the exact
|
|
297
|
+
* rational so accumulation error never creeps in, which is why the default
|
|
298
|
+
* display and every `.value`/`toNumber()` reader are unchanged. Only a
|
|
299
|
+
* fraction written with "/" carries it, so a decimal literal ("0.1") and a
|
|
300
|
+
* transcendental result ("sqrt(2)") stay the plain doubles they were.
|
|
301
|
+
* Cleared by {@link recycle} alongside {@link exact}.
|
|
302
|
+
*/
|
|
303
|
+
rational?: Rational;
|
|
304
|
+
/**
|
|
305
|
+
* The one-sigma uncertainty (standard error) this value carries, when it
|
|
306
|
+
* has one.
|
|
307
|
+
*
|
|
308
|
+
* The third sidecar, the same shape as {@link exact} and {@link rational}
|
|
309
|
+
* and for the same reason: a measurement written `12.3 ± 0.5` is still the
|
|
310
|
+
* number 12.3 everywhere it is read as one, so the type stays
|
|
311
|
+
* {@link ValueType.Number} and `value` stays the center, while this non
|
|
312
|
+
* negative field carries the tolerance. The `±` (or ASCII `+/-`) operator
|
|
313
|
+
* seeds it, and `+`, `-`, `*`, `/` propagate it in quadrature for
|
|
314
|
+
* independent errors (see `vm/VMConversion.ts`'s `uncertainOp`). Everything
|
|
315
|
+
* else (a comparison, a transcendental function, a unit conversion) reads
|
|
316
|
+
* the center through `toNumber()` and drops the tolerance, which is why a
|
|
317
|
+
* value with no uncertainty behaves exactly as a plain number always did.
|
|
318
|
+
* Cleared by {@link recycle} alongside the other two sidecars.
|
|
319
|
+
*/
|
|
320
|
+
uncertainty?: number;
|
|
321
|
+
/**
|
|
322
|
+
* The number of decimal places this value should DISPLAY at, when it has been
|
|
323
|
+
* given an explicit precision.
|
|
324
|
+
*
|
|
325
|
+
* A display sidecar, not a value one: `value` is unchanged, so every
|
|
326
|
+
* `.value`/`toNumber()` reader and all arithmetic behave exactly as before,
|
|
327
|
+
* and a value with no `decimalPlaces` formats the way it always did (the
|
|
328
|
+
* global two-place default with trailing zeros trimmed). It is set only by an
|
|
329
|
+
* explicit precision request, `<x> to N dp` and `round(x, N)`, so that
|
|
330
|
+
* `3.14159 to 4 dp` shows `3.1416` and `1.5 to 2 dp` shows `1.50` rather than
|
|
331
|
+
* the value being rounded but then displayed at the default two places. It is
|
|
332
|
+
* NOT propagated through arithmetic (a later `+ 1` re-decides precision),
|
|
333
|
+
* which is why nothing that did not ask for a precision is affected. Cleared
|
|
334
|
+
* by {@link recycle} alongside the other sidecars.
|
|
335
|
+
*/
|
|
336
|
+
decimalPlaces?: number;
|
|
337
|
+
constructor(type: ValueType, value: number | bigint | string | boolean | MatrixData | RangeData | ColourData | SymbolicNode, unit?: string);
|
|
222
338
|
/**
|
|
223
339
|
* Phase 5.3: Reset all fields for arena reuse.
|
|
224
340
|
* Called by ValueArena.acquire(), zero allocation, just field assignment.
|
|
225
341
|
*/
|
|
226
|
-
recycle(type: ValueType, value: number | bigint | string | boolean | MatrixData | RangeData | SymbolicNode, unit?: string): void;
|
|
342
|
+
recycle(type: ValueType, value: number | bigint | string | boolean | MatrixData | RangeData | ColourData | SymbolicNode, unit?: string): void;
|
|
227
343
|
isNumber(): this is Value & {
|
|
228
344
|
value: number;
|
|
229
345
|
};
|
|
@@ -244,6 +360,9 @@ declare class Value {
|
|
|
244
360
|
isRange(): this is Value & {
|
|
245
361
|
value: RangeData;
|
|
246
362
|
};
|
|
363
|
+
isColour(): this is Value & {
|
|
364
|
+
value: ColourData;
|
|
365
|
+
};
|
|
247
366
|
isSymbolic(): this is Value & {
|
|
248
367
|
value: SymbolicNode;
|
|
249
368
|
};
|
|
@@ -295,4 +414,4 @@ declare function colVectorValue(data: readonly number[]): Value;
|
|
|
295
414
|
/** Create a Range value, a first-class integer range `min:max`, both bounds inclusive. */
|
|
296
415
|
declare function rangeValue(min: number, max: number): Value;
|
|
297
416
|
|
|
298
|
-
export { type MatrixData as M, type RangeData as R, type SymbolicNode as S, Value as V, type MatrixEntry as a, ValueType as b, bigIntValue as c, colVectorValue as d, rowVectorValue as e, hexValue as h, matrixValue as m, numberValue as n, rangeValue as r, stringValue as s, uomValue as u };
|
|
417
|
+
export { type ColourData as C, type MatrixData as M, type RangeData as R, type SymbolicNode as S, Value as V, type MatrixEntry as a, ValueType as b, bigIntValue as c, colVectorValue as d, rowVectorValue as e, type ColourFormat as f, hexValue as h, matrixValue as m, numberValue as n, rangeValue as r, stringValue as s, uomValue as u };
|