solve-engine 2.38.5 → 2.38.7
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/{PackageCompatibility-CuUVgjBW.d.cts → PackageCompatibility-rJfOPkuE.d.cts} +1 -1
- package/dist/{PackageCompatibility-DscVGabN.d.ts → PackageCompatibility-th5IHCuQ.d.ts} +1 -1
- package/dist/{PackageRegistry-G6qyHROU.d.cts → PackageRegistry-CDZch8VI.d.cts} +79 -1
- package/dist/{PackageRegistry-DJekaRdM.d.ts → PackageRegistry-yDMyorr3.d.ts} +79 -1
- package/dist/{VMBuiltins-BnE1KdV5.d.ts → VMBuiltins-CjuRXAOD.d.ts} +54 -6
- package/dist/{VMBuiltins-RpmR0yHh.d.cts → VMBuiltins-DR0PyI_g.d.cts} +54 -6
- package/dist/{VMCheckpoints-DpHlGjJ3.d.ts → VMCheckpoints-C2REEAxr.d.ts} +1 -1
- package/dist/{VMCheckpoints-D0_5-IIa.d.cts → VMCheckpoints-Ch3ElC4X.d.cts} +1 -1
- package/dist/chunk-4LSPMT2M.js +3 -0
- package/dist/chunk-4LSPMT2M.js.map +1 -0
- package/dist/chunk-62JRBFBM.cjs +3 -0
- package/dist/chunk-62JRBFBM.cjs.map +1 -0
- package/dist/{chunk-YXULZQCL.cjs → chunk-6ONIPE5L.cjs} +3 -3
- package/dist/{chunk-YXULZQCL.cjs.map → chunk-6ONIPE5L.cjs.map} +1 -1
- package/dist/chunk-AAUDBEC2.cjs +5 -0
- package/dist/chunk-AAUDBEC2.cjs.map +1 -0
- package/dist/{chunk-GIV7RB5F.cjs → chunk-CNOYGBBV.cjs} +2 -2
- package/dist/{chunk-GIV7RB5F.cjs.map → chunk-CNOYGBBV.cjs.map} +1 -1
- package/dist/chunk-JJ4BY6X6.cjs +2 -0
- package/dist/chunk-JJ4BY6X6.cjs.map +1 -0
- package/dist/chunk-KL2F3YIQ.js +2 -0
- package/dist/chunk-KL2F3YIQ.js.map +1 -0
- package/dist/{chunk-G6KM25AA.js → chunk-LZFH7CWS.js} +2 -2
- package/dist/{chunk-G6KM25AA.js.map → chunk-LZFH7CWS.js.map} +1 -1
- package/dist/chunk-QFZYS7CY.cjs +2 -0
- package/dist/chunk-QFZYS7CY.cjs.map +1 -0
- package/dist/chunk-RRI3ZOI3.js +2 -0
- package/dist/chunk-RRI3ZOI3.js.map +1 -0
- package/dist/chunk-UV6H33IZ.cjs +2 -0
- package/dist/chunk-UV6H33IZ.cjs.map +1 -0
- package/dist/chunk-WP2CO6BC.js +3 -0
- package/dist/chunk-WP2CO6BC.js.map +1 -0
- package/dist/chunk-X7556JAZ.js +2 -0
- package/dist/chunk-X7556JAZ.js.map +1 -0
- package/dist/chunk-Z4KZETIJ.js +5 -0
- package/dist/chunk-Z4KZETIJ.js.map +1 -0
- package/dist/constants.cjs +1 -1
- package/dist/constants.js +1 -1
- package/dist/engine.cjs +1 -1
- package/dist/engine.d.cts +12 -4
- package/dist/engine.d.ts +12 -4
- package/dist/engine.js +1 -1
- package/dist/engine.worker.cjs +1 -1
- package/dist/engine.worker.js +1 -1
- package/dist/engine.worker.js.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.js +1 -1
- package/dist/language.d.cts +3 -3
- package/dist/language.d.ts +3 -3
- package/dist/packages.cjs +1 -1
- package/dist/packages.d.cts +2 -2
- package/dist/packages.d.ts +2 -2
- package/dist/packages.js +1 -1
- package/dist/testing.cjs +2 -2
- package/dist/testing.d.cts +3 -3
- package/dist/testing.d.ts +3 -3
- package/dist/testing.js +1 -1
- package/dist/vm.cjs +1 -1
- package/dist/vm.d.cts +2 -2
- package/dist/vm.d.ts +2 -2
- package/dist/vm.js +1 -1
- package/dist/worker.cjs +2 -2
- package/dist/worker.d.cts +2 -2
- package/dist/worker.d.ts +2 -2
- package/dist/worker.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-BLTGR5AX.cjs +0 -5
- package/dist/chunk-BLTGR5AX.cjs.map +0 -1
- package/dist/chunk-D52DE6EY.js +0 -3
- package/dist/chunk-D52DE6EY.js.map +0 -1
- package/dist/chunk-GOHW34BB.js +0 -2
- package/dist/chunk-GOHW34BB.js.map +0 -1
- package/dist/chunk-LZUPPER4.js +0 -5
- package/dist/chunk-LZUPPER4.js.map +0 -1
- package/dist/chunk-M4UC2PB6.cjs +0 -2
- package/dist/chunk-M4UC2PB6.cjs.map +0 -1
- package/dist/chunk-MSOMMARC.cjs +0 -3
- package/dist/chunk-MSOMMARC.cjs.map +0 -1
- package/dist/chunk-O7IUJXOT.cjs +0 -2
- package/dist/chunk-O7IUJXOT.cjs.map +0 -1
- package/dist/chunk-QXKF3QOX.js +0 -3
- package/dist/chunk-QXKF3QOX.js.map +0 -1
- package/dist/chunk-TJKN466F.js +0 -2
- package/dist/chunk-TJKN466F.js.map +0 -1
- package/dist/chunk-UDBOAKLW.js +0 -2
- package/dist/chunk-UDBOAKLW.js.map +0 -1
- package/dist/chunk-WCYAFAUN.cjs +0 -2
- package/dist/chunk-WCYAFAUN.cjs.map +0 -1
|
@@ -2,7 +2,7 @@ import { a as PrecedenceParser, b as PrefixParselet, I as InfixParselet } from '
|
|
|
2
2
|
import { M as MarkdownLineType, L as Lexer, e as TokenCategory, c as LexerVocabulary } from './Lexer-DaWkCu84.cjs';
|
|
3
3
|
import { IAsyncResolver } from './resolvers.cjs';
|
|
4
4
|
import { T as TokenFusion, c as TokenNormalizer, a as NormalizerRule } from './TokenNormalizer-D382VSYh.cjs';
|
|
5
|
-
import { D as DependencyGraph, V as VM, f as DagSnapshot, g as EngineContext, S as ScopeManager, P as PluginFunctionHandler, A as AsConverter } from './VMBuiltins-
|
|
5
|
+
import { D as DependencyGraph, V as VM, f as DagSnapshot, g as EngineContext, S as ScopeManager, P as PluginFunctionHandler, A as AsConverter } from './VMBuiltins-DR0PyI_g.cjs';
|
|
6
6
|
import { V as Value, b as ValueType, D as DatetimeGrain } from './Value-B55Hvn3e.cjs';
|
|
7
7
|
import { a as BytecodeProgram } from './BytecodeBuilder-DSWKZi4f.cjs';
|
|
8
8
|
import { C as CalendarBackend } from './CalendarBackend-MdS3Bb4P.cjs';
|
|
@@ -261,6 +261,23 @@ declare class DocumentModel {
|
|
|
261
261
|
* bottom of a 20k-line document before this fix.
|
|
262
262
|
*/
|
|
263
263
|
private dirtyLineIds;
|
|
264
|
+
/**
|
|
265
|
+
* Lower-cased category tag to the ids of the lines carrying it, or `null`
|
|
266
|
+
* while nothing has asked.
|
|
267
|
+
*
|
|
268
|
+
* `total of #food` used to walk the whole document looking for `#food`, so a
|
|
269
|
+
* document of members and totals cost one walk per total: D aggregates over
|
|
270
|
+
* N lines is D x N, and a notepad of a few thousand tagged lines took
|
|
271
|
+
* minutes. This turns an aggregate into a lookup of its own members.
|
|
272
|
+
*
|
|
273
|
+
* Built on the first query rather than with the document, so a document with
|
|
274
|
+
* no tags in it, which is most of them, never scans for any. Once built it is
|
|
275
|
+
* kept in step by the four places that change a line's text: {@link setDocument},
|
|
276
|
+
* {@link applyChanges}, {@link editLine} and {@link clear}. Keyed by line id
|
|
277
|
+
* rather than position, so inserting or deleting a line above a tagged one
|
|
278
|
+
* does not touch it.
|
|
279
|
+
*/
|
|
280
|
+
private tagIndex;
|
|
264
281
|
/**
|
|
265
282
|
* Most lines this model will hold. See `constants/Configuration.ts`'s
|
|
266
283
|
* `performance.maxDocumentLines`, which is where the default comes from and
|
|
@@ -320,6 +337,27 @@ declare class DocumentModel {
|
|
|
320
337
|
* Returns true if the text actually changed (hash mismatch).
|
|
321
338
|
*/
|
|
322
339
|
editLine(lineNumber: number, newText: string): boolean;
|
|
340
|
+
/**
|
|
341
|
+
* The 1-based positions of the lines carrying `#tag`, in document order.
|
|
342
|
+
*
|
|
343
|
+
* What `total of #tag` reads. Case-insensitive, matching how a tag is read
|
|
344
|
+
* on a line, and it names membership only: a line that merely asks about the
|
|
345
|
+
* group (`total of #tag`) is not in it, and neither is a `#heading`.
|
|
346
|
+
*
|
|
347
|
+
* Ascending, because an aggregate reports the first line it cannot read and
|
|
348
|
+
* the line it names has to be the first one in the document, not whichever
|
|
349
|
+
* happened to be indexed first.
|
|
350
|
+
*
|
|
351
|
+
* @param tag - The tag name without its `#`.
|
|
352
|
+
* @returns Its lines' positions, ascending; empty when no line carries it.
|
|
353
|
+
*/
|
|
354
|
+
linesCarryingTag(tag: string): number[];
|
|
355
|
+
/** The tag index, built over every line the first time one is asked for. */
|
|
356
|
+
private ensureTagIndex;
|
|
357
|
+
/** Records `lineId` as a member of every group its text joins. */
|
|
358
|
+
private indexTags;
|
|
359
|
+
/** Drops `lineId` from every group the text it used to hold joined. */
|
|
360
|
+
private unindexTags;
|
|
323
361
|
/**
|
|
324
362
|
* Get the LineState at the given 1-based line position. O(1).
|
|
325
363
|
*/
|
|
@@ -1960,6 +1998,16 @@ declare class ExpressionEngine {
|
|
|
1960
1998
|
*/
|
|
1961
1999
|
private batchScanResults;
|
|
1962
2000
|
private batchParsedLines;
|
|
2001
|
+
/**
|
|
2002
|
+
* Lower-cased category tag to the 1-based lines carrying it, for the batch
|
|
2003
|
+
* pass, or `null` before anything has asked.
|
|
2004
|
+
*
|
|
2005
|
+
* The batch path has no document model to hold this, and the scan it does
|
|
2006
|
+
* have lives only for the pass, so the index does too: built over the scan
|
|
2007
|
+
* on the first aggregate and dropped with it. A document with no aggregate
|
|
2008
|
+
* in it never builds one.
|
|
2009
|
+
*/
|
|
2010
|
+
private batchTagIndex;
|
|
1963
2011
|
/**
|
|
1964
2012
|
* The context handed to every line of the current pass, its line number
|
|
1965
2013
|
* set by mutation before each execution. The closures inside read only
|
|
@@ -2378,6 +2426,23 @@ declare class ExpressionEngine {
|
|
|
2378
2426
|
* still cancels it), or null when nothing was linked.
|
|
2379
2427
|
*/
|
|
2380
2428
|
private armCancellation;
|
|
2429
|
+
/**
|
|
2430
|
+
* Register a line's edges, including the groups its text joins and asks about.
|
|
2431
|
+
*
|
|
2432
|
+
* A category tag is an edge like any other: a line carrying `#food` writes
|
|
2433
|
+
* that group, and `total of #food` reads it. Registering them here is what
|
|
2434
|
+
* lets an edit to a tagged line dirty only the aggregates over that tag.
|
|
2435
|
+
*
|
|
2436
|
+
* Membership is a property of the text rather than of the bytecode, so it
|
|
2437
|
+
* comes from the same scanner the aggregate itself reads with, which is what
|
|
2438
|
+
* keeps the two from ever disagreeing about what is in a group.
|
|
2439
|
+
*
|
|
2440
|
+
* @param lineNumber - 1-based line the edges belong to.
|
|
2441
|
+
* @param text - The line's expression, which is where its tags are.
|
|
2442
|
+
* @param reads - Variable keys the line reads.
|
|
2443
|
+
* @param writes - Variable keys the line writes.
|
|
2444
|
+
*/
|
|
2445
|
+
private registerLineWithTags;
|
|
2381
2446
|
/**
|
|
2382
2447
|
* Execute bytecode and handle the result.
|
|
2383
2448
|
*
|
|
@@ -2455,6 +2520,19 @@ declare class ExpressionEngine {
|
|
|
2455
2520
|
* bypassing the split→join roundtrip that this method performs.
|
|
2456
2521
|
*/
|
|
2457
2522
|
evaluateLines(lines: string[]): ParsedLine[];
|
|
2523
|
+
/**
|
|
2524
|
+
* The lines of the batch pass's scan carrying `#tag`, ascending.
|
|
2525
|
+
*
|
|
2526
|
+
* The batch counterpart of `DocumentModel.linesCarryingTag`, over the scan
|
|
2527
|
+
* this pass is walking rather than over a document model. Built once and
|
|
2528
|
+
* read by every aggregate in the pass, which is what makes the pass linear
|
|
2529
|
+
* in the document rather than linear per aggregate.
|
|
2530
|
+
*
|
|
2531
|
+
* @param scan - The pass's scanned lines, indexed from 0 for line 1.
|
|
2532
|
+
* @param tag - The tag name without its `#`.
|
|
2533
|
+
* @returns Its lines' 1-based positions, ascending; empty when none carry it.
|
|
2534
|
+
*/
|
|
2535
|
+
private batchLinesCarryingTag;
|
|
2458
2536
|
/**
|
|
2459
2537
|
* Process pre-scanned line results into ParsedLine objects.
|
|
2460
2538
|
*
|
|
@@ -2,7 +2,7 @@ import { a as PrecedenceParser, b as PrefixParselet, I as InfixParselet } from '
|
|
|
2
2
|
import { M as MarkdownLineType, L as Lexer, e as TokenCategory, c as LexerVocabulary } from './Lexer-DPn5dfCH.js';
|
|
3
3
|
import { IAsyncResolver } from './resolvers.js';
|
|
4
4
|
import { T as TokenFusion, c as TokenNormalizer, a as NormalizerRule } from './TokenNormalizer-DAzPp-j1.js';
|
|
5
|
-
import { D as DependencyGraph, V as VM, f as DagSnapshot, g as EngineContext, S as ScopeManager, P as PluginFunctionHandler, A as AsConverter } from './VMBuiltins-
|
|
5
|
+
import { D as DependencyGraph, V as VM, f as DagSnapshot, g as EngineContext, S as ScopeManager, P as PluginFunctionHandler, A as AsConverter } from './VMBuiltins-CjuRXAOD.js';
|
|
6
6
|
import { V as Value, b as ValueType, D as DatetimeGrain } from './Value-B55Hvn3e.js';
|
|
7
7
|
import { a as BytecodeProgram } from './BytecodeBuilder-DSWKZi4f.js';
|
|
8
8
|
import { C as CalendarBackend } from './CalendarBackend-MdS3Bb4P.js';
|
|
@@ -261,6 +261,23 @@ declare class DocumentModel {
|
|
|
261
261
|
* bottom of a 20k-line document before this fix.
|
|
262
262
|
*/
|
|
263
263
|
private dirtyLineIds;
|
|
264
|
+
/**
|
|
265
|
+
* Lower-cased category tag to the ids of the lines carrying it, or `null`
|
|
266
|
+
* while nothing has asked.
|
|
267
|
+
*
|
|
268
|
+
* `total of #food` used to walk the whole document looking for `#food`, so a
|
|
269
|
+
* document of members and totals cost one walk per total: D aggregates over
|
|
270
|
+
* N lines is D x N, and a notepad of a few thousand tagged lines took
|
|
271
|
+
* minutes. This turns an aggregate into a lookup of its own members.
|
|
272
|
+
*
|
|
273
|
+
* Built on the first query rather than with the document, so a document with
|
|
274
|
+
* no tags in it, which is most of them, never scans for any. Once built it is
|
|
275
|
+
* kept in step by the four places that change a line's text: {@link setDocument},
|
|
276
|
+
* {@link applyChanges}, {@link editLine} and {@link clear}. Keyed by line id
|
|
277
|
+
* rather than position, so inserting or deleting a line above a tagged one
|
|
278
|
+
* does not touch it.
|
|
279
|
+
*/
|
|
280
|
+
private tagIndex;
|
|
264
281
|
/**
|
|
265
282
|
* Most lines this model will hold. See `constants/Configuration.ts`'s
|
|
266
283
|
* `performance.maxDocumentLines`, which is where the default comes from and
|
|
@@ -320,6 +337,27 @@ declare class DocumentModel {
|
|
|
320
337
|
* Returns true if the text actually changed (hash mismatch).
|
|
321
338
|
*/
|
|
322
339
|
editLine(lineNumber: number, newText: string): boolean;
|
|
340
|
+
/**
|
|
341
|
+
* The 1-based positions of the lines carrying `#tag`, in document order.
|
|
342
|
+
*
|
|
343
|
+
* What `total of #tag` reads. Case-insensitive, matching how a tag is read
|
|
344
|
+
* on a line, and it names membership only: a line that merely asks about the
|
|
345
|
+
* group (`total of #tag`) is not in it, and neither is a `#heading`.
|
|
346
|
+
*
|
|
347
|
+
* Ascending, because an aggregate reports the first line it cannot read and
|
|
348
|
+
* the line it names has to be the first one in the document, not whichever
|
|
349
|
+
* happened to be indexed first.
|
|
350
|
+
*
|
|
351
|
+
* @param tag - The tag name without its `#`.
|
|
352
|
+
* @returns Its lines' positions, ascending; empty when no line carries it.
|
|
353
|
+
*/
|
|
354
|
+
linesCarryingTag(tag: string): number[];
|
|
355
|
+
/** The tag index, built over every line the first time one is asked for. */
|
|
356
|
+
private ensureTagIndex;
|
|
357
|
+
/** Records `lineId` as a member of every group its text joins. */
|
|
358
|
+
private indexTags;
|
|
359
|
+
/** Drops `lineId` from every group the text it used to hold joined. */
|
|
360
|
+
private unindexTags;
|
|
323
361
|
/**
|
|
324
362
|
* Get the LineState at the given 1-based line position. O(1).
|
|
325
363
|
*/
|
|
@@ -1960,6 +1998,16 @@ declare class ExpressionEngine {
|
|
|
1960
1998
|
*/
|
|
1961
1999
|
private batchScanResults;
|
|
1962
2000
|
private batchParsedLines;
|
|
2001
|
+
/**
|
|
2002
|
+
* Lower-cased category tag to the 1-based lines carrying it, for the batch
|
|
2003
|
+
* pass, or `null` before anything has asked.
|
|
2004
|
+
*
|
|
2005
|
+
* The batch path has no document model to hold this, and the scan it does
|
|
2006
|
+
* have lives only for the pass, so the index does too: built over the scan
|
|
2007
|
+
* on the first aggregate and dropped with it. A document with no aggregate
|
|
2008
|
+
* in it never builds one.
|
|
2009
|
+
*/
|
|
2010
|
+
private batchTagIndex;
|
|
1963
2011
|
/**
|
|
1964
2012
|
* The context handed to every line of the current pass, its line number
|
|
1965
2013
|
* set by mutation before each execution. The closures inside read only
|
|
@@ -2378,6 +2426,23 @@ declare class ExpressionEngine {
|
|
|
2378
2426
|
* still cancels it), or null when nothing was linked.
|
|
2379
2427
|
*/
|
|
2380
2428
|
private armCancellation;
|
|
2429
|
+
/**
|
|
2430
|
+
* Register a line's edges, including the groups its text joins and asks about.
|
|
2431
|
+
*
|
|
2432
|
+
* A category tag is an edge like any other: a line carrying `#food` writes
|
|
2433
|
+
* that group, and `total of #food` reads it. Registering them here is what
|
|
2434
|
+
* lets an edit to a tagged line dirty only the aggregates over that tag.
|
|
2435
|
+
*
|
|
2436
|
+
* Membership is a property of the text rather than of the bytecode, so it
|
|
2437
|
+
* comes from the same scanner the aggregate itself reads with, which is what
|
|
2438
|
+
* keeps the two from ever disagreeing about what is in a group.
|
|
2439
|
+
*
|
|
2440
|
+
* @param lineNumber - 1-based line the edges belong to.
|
|
2441
|
+
* @param text - The line's expression, which is where its tags are.
|
|
2442
|
+
* @param reads - Variable keys the line reads.
|
|
2443
|
+
* @param writes - Variable keys the line writes.
|
|
2444
|
+
*/
|
|
2445
|
+
private registerLineWithTags;
|
|
2381
2446
|
/**
|
|
2382
2447
|
* Execute bytecode and handle the result.
|
|
2383
2448
|
*
|
|
@@ -2455,6 +2520,19 @@ declare class ExpressionEngine {
|
|
|
2455
2520
|
* bypassing the split→join roundtrip that this method performs.
|
|
2456
2521
|
*/
|
|
2457
2522
|
evaluateLines(lines: string[]): ParsedLine[];
|
|
2523
|
+
/**
|
|
2524
|
+
* The lines of the batch pass's scan carrying `#tag`, ascending.
|
|
2525
|
+
*
|
|
2526
|
+
* The batch counterpart of `DocumentModel.linesCarryingTag`, over the scan
|
|
2527
|
+
* this pass is walking rather than over a document model. Built once and
|
|
2528
|
+
* read by every aggregate in the pass, which is what makes the pass linear
|
|
2529
|
+
* in the document rather than linear per aggregate.
|
|
2530
|
+
*
|
|
2531
|
+
* @param scan - The pass's scanned lines, indexed from 0 for line 1.
|
|
2532
|
+
* @param tag - The tag name without its `#`.
|
|
2533
|
+
* @returns Its lines' 1-based positions, ascending; empty when none carry it.
|
|
2534
|
+
*/
|
|
2535
|
+
private batchLinesCarryingTag;
|
|
2458
2536
|
/**
|
|
2459
2537
|
* Process pre-scanned line results into ParsedLine objects.
|
|
2460
2538
|
*
|
|
@@ -98,6 +98,16 @@ interface LineExecutionContext {
|
|
|
98
98
|
calendar?: CalendarBackend;
|
|
99
99
|
/** Look up another line's cached result by 1-based line number. `undefined` = not evaluated yet (or out of range), distinct from a line that evaluated to an actual `undefined`-like Value, which can't happen (every Value type has a concrete representation). */
|
|
100
100
|
getLineResult?: (lineNumber: number) => Value | undefined;
|
|
101
|
+
/**
|
|
102
|
+
* The 1-based positions of the lines carrying `#tag`, ascending, or
|
|
103
|
+
* `undefined` when this path keeps no index and the caller should walk the
|
|
104
|
+
* document itself.
|
|
105
|
+
*
|
|
106
|
+
* `total of #tag` used to look at every line of the document, so a notepad
|
|
107
|
+
* of tagged amounts and totals cost aggregates x lines per pass. Both
|
|
108
|
+
* document paths maintain an index instead, and answer from it here.
|
|
109
|
+
*/
|
|
110
|
+
getTaggedLines?: (tag: string) => readonly number[] | undefined;
|
|
101
111
|
/** Whether line `lineNumber` is a blank line or a `#` heading, the stopping condition for "total above"/"sum above"/"average above" aggregation. */
|
|
102
112
|
isLineBoundary?: (lineNumber: number) => boolean;
|
|
103
113
|
/**
|
|
@@ -591,6 +601,8 @@ declare const sharedOpRegistry: OpRegistry;
|
|
|
591
601
|
/** Serialized snapshot of the dependency graph for diagnostic rendering. */
|
|
592
602
|
interface DagSnapshot {
|
|
593
603
|
consumers: Record<string, number[]>;
|
|
604
|
+
/** key -> the lines that write it, the mirror of `consumers`. */
|
|
605
|
+
producers: Record<string, number[]>;
|
|
594
606
|
writes: Record<number, string[]>;
|
|
595
607
|
reads: Record<number, string[]>;
|
|
596
608
|
dataSourceDeps: Record<number, string[]>;
|
|
@@ -607,12 +619,36 @@ interface DagSnapshot {
|
|
|
607
619
|
* - Efficient removal of deleted lines (removeLine)
|
|
608
620
|
*/
|
|
609
621
|
declare class DependencyGraph {
|
|
622
|
+
/** key -> the lines that READ it. Answers "what does an edit to this affect". */
|
|
610
623
|
private consumers;
|
|
624
|
+
/**
|
|
625
|
+
* key -> the lines that WRITE it. Answers "what is in this group".
|
|
626
|
+
*
|
|
627
|
+
* The half that was missing. `consumers` alone can say which lines ask about
|
|
628
|
+
* `#food`; only this can say which lines are *in* it, which is what a
|
|
629
|
+
* category-tag aggregate needs and why it used to walk the whole document
|
|
630
|
+
* instead of asking.
|
|
631
|
+
*/
|
|
632
|
+
private producers;
|
|
611
633
|
private dependencies;
|
|
612
634
|
private writes;
|
|
613
635
|
private lineReads;
|
|
614
|
-
|
|
615
|
-
|
|
636
|
+
/**
|
|
637
|
+
* line -> the keys it reads that {@link registerLine} must not replace.
|
|
638
|
+
*
|
|
639
|
+
* Variable and tag edges are recovered from the line's text every time it is
|
|
640
|
+
* registered, so registering replaces them. A data-source edge is discovered
|
|
641
|
+
* at run time, after that registration, so replacing would drop it. Both live
|
|
642
|
+
* in the same {@link consumers} index; only the bookkeeping differs.
|
|
643
|
+
*/
|
|
644
|
+
private pinnedReads;
|
|
645
|
+
/**
|
|
646
|
+
* Whether this line already carries exactly these edges.
|
|
647
|
+
*
|
|
648
|
+
* Reads are compared against the stored set minus its pinned keys, since a
|
|
649
|
+
* pinned key (a data source) is not part of what a caller passes.
|
|
650
|
+
*/
|
|
651
|
+
private hasSameEdges;
|
|
616
652
|
/**
|
|
617
653
|
* Register a line's variable reads and writes in the dependency graph.
|
|
618
654
|
*
|
|
@@ -668,7 +704,7 @@ declare class DependencyGraph {
|
|
|
668
704
|
* @param queryKey - The query key that was updated
|
|
669
705
|
* @returns Set of line numbers that need re-evaluation
|
|
670
706
|
*/
|
|
671
|
-
getAffectedLinesByDataSource(dataSourceId: string, queryKey: string[]):
|
|
707
|
+
getAffectedLinesByDataSource(dataSourceId: string, queryKey: string[]): ReadonlySet<number>;
|
|
672
708
|
/**
|
|
673
709
|
* Remove a line from the dependency graph (e.g., when a line is deleted from the document).
|
|
674
710
|
*
|
|
@@ -684,21 +720,33 @@ declare class DependencyGraph {
|
|
|
684
720
|
* @param variable - The variable name
|
|
685
721
|
* @returns Set of line numbers that read this variable, or empty set if none
|
|
686
722
|
*/
|
|
687
|
-
getConsumers(variable: string):
|
|
723
|
+
getConsumers(variable: string): ReadonlySet<number>;
|
|
724
|
+
/**
|
|
725
|
+
* Get all line numbers that produce (write) a given key.
|
|
726
|
+
*
|
|
727
|
+
* The mirror of {@link getConsumers}, and the reason the producer index
|
|
728
|
+
* exists: for a category tag it is the group's membership, so an aggregate
|
|
729
|
+
* over `#food` costs the size of the group rather than the size of the
|
|
730
|
+
* document.
|
|
731
|
+
*
|
|
732
|
+
* @param key - The key, from {@link edgeKey}
|
|
733
|
+
* @returns Set of line numbers that write this key, or empty set if none
|
|
734
|
+
*/
|
|
735
|
+
getProducers(key: string): ReadonlySet<number>;
|
|
688
736
|
/**
|
|
689
737
|
* Get all variables that a line depends on (reads).
|
|
690
738
|
*
|
|
691
739
|
* @param lineNumber - The line number to query
|
|
692
740
|
* @returns Set of variable names this line reads, or empty set if none
|
|
693
741
|
*/
|
|
694
|
-
getDependencies(lineNumber: number):
|
|
742
|
+
getDependencies(lineNumber: number): ReadonlySet<string>;
|
|
695
743
|
/**
|
|
696
744
|
* Get all variables that a line writes (assigns to).
|
|
697
745
|
*
|
|
698
746
|
* @param lineNumber - The line number to query
|
|
699
747
|
* @returns Set of variable names this line writes, or empty set if none
|
|
700
748
|
*/
|
|
701
|
-
getWrites(lineNumber: number):
|
|
749
|
+
getWrites(lineNumber: number): ReadonlySet<string>;
|
|
702
750
|
/**
|
|
703
751
|
* Get a serializable snapshot of the entire dependency graph for diagnostics.
|
|
704
752
|
*
|
|
@@ -98,6 +98,16 @@ interface LineExecutionContext {
|
|
|
98
98
|
calendar?: CalendarBackend;
|
|
99
99
|
/** Look up another line's cached result by 1-based line number. `undefined` = not evaluated yet (or out of range), distinct from a line that evaluated to an actual `undefined`-like Value, which can't happen (every Value type has a concrete representation). */
|
|
100
100
|
getLineResult?: (lineNumber: number) => Value | undefined;
|
|
101
|
+
/**
|
|
102
|
+
* The 1-based positions of the lines carrying `#tag`, ascending, or
|
|
103
|
+
* `undefined` when this path keeps no index and the caller should walk the
|
|
104
|
+
* document itself.
|
|
105
|
+
*
|
|
106
|
+
* `total of #tag` used to look at every line of the document, so a notepad
|
|
107
|
+
* of tagged amounts and totals cost aggregates x lines per pass. Both
|
|
108
|
+
* document paths maintain an index instead, and answer from it here.
|
|
109
|
+
*/
|
|
110
|
+
getTaggedLines?: (tag: string) => readonly number[] | undefined;
|
|
101
111
|
/** Whether line `lineNumber` is a blank line or a `#` heading, the stopping condition for "total above"/"sum above"/"average above" aggregation. */
|
|
102
112
|
isLineBoundary?: (lineNumber: number) => boolean;
|
|
103
113
|
/**
|
|
@@ -591,6 +601,8 @@ declare const sharedOpRegistry: OpRegistry;
|
|
|
591
601
|
/** Serialized snapshot of the dependency graph for diagnostic rendering. */
|
|
592
602
|
interface DagSnapshot {
|
|
593
603
|
consumers: Record<string, number[]>;
|
|
604
|
+
/** key -> the lines that write it, the mirror of `consumers`. */
|
|
605
|
+
producers: Record<string, number[]>;
|
|
594
606
|
writes: Record<number, string[]>;
|
|
595
607
|
reads: Record<number, string[]>;
|
|
596
608
|
dataSourceDeps: Record<number, string[]>;
|
|
@@ -607,12 +619,36 @@ interface DagSnapshot {
|
|
|
607
619
|
* - Efficient removal of deleted lines (removeLine)
|
|
608
620
|
*/
|
|
609
621
|
declare class DependencyGraph {
|
|
622
|
+
/** key -> the lines that READ it. Answers "what does an edit to this affect". */
|
|
610
623
|
private consumers;
|
|
624
|
+
/**
|
|
625
|
+
* key -> the lines that WRITE it. Answers "what is in this group".
|
|
626
|
+
*
|
|
627
|
+
* The half that was missing. `consumers` alone can say which lines ask about
|
|
628
|
+
* `#food`; only this can say which lines are *in* it, which is what a
|
|
629
|
+
* category-tag aggregate needs and why it used to walk the whole document
|
|
630
|
+
* instead of asking.
|
|
631
|
+
*/
|
|
632
|
+
private producers;
|
|
611
633
|
private dependencies;
|
|
612
634
|
private writes;
|
|
613
635
|
private lineReads;
|
|
614
|
-
|
|
615
|
-
|
|
636
|
+
/**
|
|
637
|
+
* line -> the keys it reads that {@link registerLine} must not replace.
|
|
638
|
+
*
|
|
639
|
+
* Variable and tag edges are recovered from the line's text every time it is
|
|
640
|
+
* registered, so registering replaces them. A data-source edge is discovered
|
|
641
|
+
* at run time, after that registration, so replacing would drop it. Both live
|
|
642
|
+
* in the same {@link consumers} index; only the bookkeeping differs.
|
|
643
|
+
*/
|
|
644
|
+
private pinnedReads;
|
|
645
|
+
/**
|
|
646
|
+
* Whether this line already carries exactly these edges.
|
|
647
|
+
*
|
|
648
|
+
* Reads are compared against the stored set minus its pinned keys, since a
|
|
649
|
+
* pinned key (a data source) is not part of what a caller passes.
|
|
650
|
+
*/
|
|
651
|
+
private hasSameEdges;
|
|
616
652
|
/**
|
|
617
653
|
* Register a line's variable reads and writes in the dependency graph.
|
|
618
654
|
*
|
|
@@ -668,7 +704,7 @@ declare class DependencyGraph {
|
|
|
668
704
|
* @param queryKey - The query key that was updated
|
|
669
705
|
* @returns Set of line numbers that need re-evaluation
|
|
670
706
|
*/
|
|
671
|
-
getAffectedLinesByDataSource(dataSourceId: string, queryKey: string[]):
|
|
707
|
+
getAffectedLinesByDataSource(dataSourceId: string, queryKey: string[]): ReadonlySet<number>;
|
|
672
708
|
/**
|
|
673
709
|
* Remove a line from the dependency graph (e.g., when a line is deleted from the document).
|
|
674
710
|
*
|
|
@@ -684,21 +720,33 @@ declare class DependencyGraph {
|
|
|
684
720
|
* @param variable - The variable name
|
|
685
721
|
* @returns Set of line numbers that read this variable, or empty set if none
|
|
686
722
|
*/
|
|
687
|
-
getConsumers(variable: string):
|
|
723
|
+
getConsumers(variable: string): ReadonlySet<number>;
|
|
724
|
+
/**
|
|
725
|
+
* Get all line numbers that produce (write) a given key.
|
|
726
|
+
*
|
|
727
|
+
* The mirror of {@link getConsumers}, and the reason the producer index
|
|
728
|
+
* exists: for a category tag it is the group's membership, so an aggregate
|
|
729
|
+
* over `#food` costs the size of the group rather than the size of the
|
|
730
|
+
* document.
|
|
731
|
+
*
|
|
732
|
+
* @param key - The key, from {@link edgeKey}
|
|
733
|
+
* @returns Set of line numbers that write this key, or empty set if none
|
|
734
|
+
*/
|
|
735
|
+
getProducers(key: string): ReadonlySet<number>;
|
|
688
736
|
/**
|
|
689
737
|
* Get all variables that a line depends on (reads).
|
|
690
738
|
*
|
|
691
739
|
* @param lineNumber - The line number to query
|
|
692
740
|
* @returns Set of variable names this line reads, or empty set if none
|
|
693
741
|
*/
|
|
694
|
-
getDependencies(lineNumber: number):
|
|
742
|
+
getDependencies(lineNumber: number): ReadonlySet<string>;
|
|
695
743
|
/**
|
|
696
744
|
* Get all variables that a line writes (assigns to).
|
|
697
745
|
*
|
|
698
746
|
* @param lineNumber - The line number to query
|
|
699
747
|
* @returns Set of variable names this line writes, or empty set if none
|
|
700
748
|
*/
|
|
701
|
-
getWrites(lineNumber: number):
|
|
749
|
+
getWrites(lineNumber: number): ReadonlySet<string>;
|
|
702
750
|
/**
|
|
703
751
|
* Get a serializable snapshot of the entire dependency graph for diagnostics.
|
|
704
752
|
*
|