@sheetxl/sdk 0.7.28-beta.4 → 0.8.0-beta.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/browser/cjs/{CD2RXdnfqSYNc6gX.cjs → BatsV2UUraVDCRXm.cjs} +1 -1
- package/browser/cjs/CUz53T65cRGQRgvv.cjs +33 -0
- package/browser/cjs/{BXtvdT1Z-MsB_o5F.cjs → DU0kYUtdFa3jK-im.cjs} +1 -1
- package/browser/cjs/{DcLpXGexEtOxi-dD.cjs → Dv4yIPLV98M5zLHa.cjs} +1 -1
- package/browser/cjs/a0Z-SXs_N71CtqYb.cjs +1 -0
- package/browser/cjs/index.cjs +2 -2
- package/browser/esm/{CoA-sUxjiIUIpTUF.mjs → 6JKSOvc5czaQB2Bj.mjs} +3 -3
- package/browser/esm/{DBIu6NUHIcxOOBQp.mjs → B0HS42a7lga1k1U_.mjs} +1 -1
- package/browser/esm/{Dy4Sdpju1T2icURu.mjs → BtuJ9AGzeURtAsGo.mjs} +5797 -5410
- package/browser/esm/{0Mj5WKM362q6CECb.mjs → DGU6sM25u0EWCKl1.mjs} +3 -3
- package/browser/esm/{CKk58ZLcrllMzfou.mjs → DlPMeIyxT9tG_WDk.mjs} +2 -2
- package/browser/esm/{CPTtL2f6_4iblmFM.mjs → f2G3QRgEbvFJcoa2.mjs} +2 -2
- package/browser/esm/index.mjs +6 -6
- package/browser/esm/{CHSahmMFYNB0Ajkf.mjs → uyWBMSIxMlt8n5Z3.mjs} +2 -2
- package/node/esm/{DqgWsVXROpSgKq6c.mjs → -pxdn3M3tc6PLHs7.mjs} +20 -20
- package/node/esm/{BtGxbEbBm79YvF_k.mjs → 0n5bslM9jhO1JnI2.mjs} +1 -1
- package/node/esm/{DUYP6faJJHCaW1Xf.mjs → Cku7XiUvw1xrRasi.mjs} +1 -1
- package/node/esm/index.mjs +8279 -7901
- package/package.json +6 -6
- package/types/scripting-enums.json +4 -0
- package/types/scripting.d.ts +321 -19
- package/types/src/calculation/Calculation.d.ts +5 -0
- package/types/src/calculation/executor/CalcExecutor.d.ts +112 -3
- package/types/src/calculation/state/CalcNode.d.ts +20 -0
- package/types/src/calculation/state/CalculationContext.d.ts +3 -1
- package/types/src/calculation/state/IContextContainer.d.ts +31 -0
- package/types/src/cellRange/ICellRange.d.ts +39 -18
- package/types/src/lib/utils/_Utils.d.ts +7 -0
- package/types/src/primitives/PrimitiveUtils.d.ts +4 -2
- package/types/src/primitives/Range.d.ts +3 -1
- package/types/src/scripting/FunctionArguments.d.ts +22 -0
- package/types/src/scripting/TypedFunction.d.ts +60 -0
- package/types/src/sheet/Sheet.d.ts +8 -0
- package/types/src/sheet/SheetRange.d.ts +3 -0
- package/types/src/sheet/_SheetAutoFitUtils.d.ts +28 -0
- package/browser/cjs/BF14ZEAnaqxXroSj.cjs +0 -1
- package/browser/cjs/Bc4JjVVZfFo3R4He.cjs +0 -33
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sheetxl/sdk",
|
|
3
3
|
"description": "SDK - A high-performance, embeddable spreadsheet engine.",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.8.0-beta.1",
|
|
5
5
|
"license": "SEE LICENSE IN <LICENSE>",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"exports": {
|
|
@@ -43,11 +43,11 @@
|
|
|
43
43
|
"automation"
|
|
44
44
|
],
|
|
45
45
|
"dependencies": {
|
|
46
|
-
"@sheetxl/formulas": "^0.
|
|
47
|
-
"@sheetxl/formulas-extended": "^0.
|
|
48
|
-
"@sheetxl/primitives": "^0.
|
|
49
|
-
"@sheetxl/scripting": "^0.
|
|
50
|
-
"@sheetxl/utils": "^0.
|
|
46
|
+
"@sheetxl/formulas": "^0.8.0-beta.1",
|
|
47
|
+
"@sheetxl/formulas-extended": "^0.8.0-beta.1",
|
|
48
|
+
"@sheetxl/primitives": "^0.8.0-beta.1",
|
|
49
|
+
"@sheetxl/scripting": "^0.8.0-beta.1",
|
|
50
|
+
"@sheetxl/utils": "^0.8.0-beta.1",
|
|
51
51
|
"bahttext": "^2.4.0",
|
|
52
52
|
"bessel": "^1.0.2",
|
|
53
53
|
"chalk": "^6.0.0",
|
|
@@ -58,6 +58,10 @@
|
|
|
58
58
|
"Column": "column",
|
|
59
59
|
"Row": "row"
|
|
60
60
|
},
|
|
61
|
+
"CompatFeatures": {
|
|
62
|
+
"noMemberFilter": "Members of a repeating scalar parameter are coerced rather than filtered; one that cannot be is #VALUE!.",
|
|
63
|
+
"noReferenceLift": "A multi-cell reference at a non-repeating scalar parameter is #VALUE! rather than a broadcast."
|
|
64
|
+
},
|
|
61
65
|
"DateUnit": {
|
|
62
66
|
"Day": "d",
|
|
63
67
|
"Month": "m",
|
package/types/scripting.d.ts
CHANGED
|
@@ -639,6 +639,65 @@ declare global {
|
|
|
639
639
|
}
|
|
640
640
|
}
|
|
641
641
|
|
|
642
|
+
/**
|
|
643
|
+
* Family aliases: one name an author writes that expands to several {@link CompatFeatures}.
|
|
644
|
+
*
|
|
645
|
+
* @remarks
|
|
646
|
+
* Excel's Analysis-ToolPak heritage is ONE measured rule with two halves that act on disjoint
|
|
647
|
+
* parameter kinds — `noReferenceLift` at a non-repeating scalar slot, `noMemberFilter` at a
|
|
648
|
+
* repeating one — so every function in the family carries the same two bits and `@compat atp`
|
|
649
|
+
* says so in one word. The alias is expanded by the linter; only the atomic features are ever
|
|
650
|
+
* stored, so `@compat atp` and `@compat noReferenceLift noMemberFilter` emit the same declaration.
|
|
651
|
+
* The atomic names stay available for the day a function measures as disagreeing on one half.
|
|
652
|
+
*/
|
|
653
|
+
export const CompatAliases: Readonly<Record<string, readonly CompatFeature[]>>;
|
|
654
|
+
|
|
655
|
+
/**
|
|
656
|
+
* One of the {@link CompatFeatures} names.
|
|
657
|
+
*/
|
|
658
|
+
export type CompatFeature = keyof typeof CompatFeatures;
|
|
659
|
+
|
|
660
|
+
/**
|
|
661
|
+
* The behaviors `@compat` can turn on, and what each one does.
|
|
662
|
+
*
|
|
663
|
+
* @remarks
|
|
664
|
+
* A feature earns a place here only if the BODY cannot do it — the decision happens before the
|
|
665
|
+
* body runs, or instead of running it. Everything a body can decide for itself belongs in the
|
|
666
|
+
* body, where `FormulaContext.getArgs()` and `Omittable` already reach.
|
|
667
|
+
*
|
|
668
|
+
* Function-level until a measurement forces otherwise: `noReferenceLift` is per-function in
|
|
669
|
+
* Excel, and no function is known whose parameters disagree.
|
|
670
|
+
*
|
|
671
|
+
* @see {@link https://www.sheetxl.com/docs/guides/concepts/udf | UDF authoring guide}
|
|
672
|
+
*/
|
|
673
|
+
export const CompatFeatures: {
|
|
674
|
+
/**
|
|
675
|
+
* A multi-cell REFERENCE at a non-repeating scalar parameter is `#VALUE!` rather than a
|
|
676
|
+
* broadcast.
|
|
677
|
+
*
|
|
678
|
+
* Excel's Analysis-ToolPak family answers `CUMIPMT(G1:G2,120,100000,13,24,0)` with `#VALUE!`
|
|
679
|
+
* where the native `ROUND(B1:B3,3)` spills three results. A multi-cell reference has no way to
|
|
680
|
+
* become a scalar there, because these functions never intersect. An ARRAY at the same slot
|
|
681
|
+
* still lifts (`MROUND({3,4,5},5)` spills), so the refusal is about references specifically,
|
|
682
|
+
* and a REPEATING slot absorbs a container as members either way (`GCD(C1:C3)` is 4) — so this
|
|
683
|
+
* never applies to one.
|
|
684
|
+
*/
|
|
685
|
+
readonly noReferenceLift: "A multi-cell reference at a non-repeating scalar parameter is #VALUE! rather than a broadcast.";
|
|
686
|
+
/**
|
|
687
|
+
* Members of a REPEATING scalar parameter are coerced rather than filtered: numeric text
|
|
688
|
+
* parses, a blank inside a multi-cell range reads 0, and a boolean or non-numeric text member
|
|
689
|
+
* is `#VALUE!` for the whole call.
|
|
690
|
+
*
|
|
691
|
+
* The native family FILTERS — `SUM({1,"8",TRUE})` is 1, the text and the boolean skipped, and a
|
|
692
|
+
* blank cell contributes nothing. Excel's Analysis-ToolPak family coerces instead:
|
|
693
|
+
* `GCD({6,"8",12})` is 2, `GCD({6,TRUE,12})` is `#VALUE!`, `LCM(6,A1:A2)` over two blank cells
|
|
694
|
+
* is 0. A direct argument follows the same rule (`GCD(6,TRUE,12)` is `#VALUE!` where
|
|
695
|
+
* `SUM(6,TRUE,12)` is 19), and a one-cell blank reference or an omitted argument is still
|
|
696
|
+
* skipped — it never became a member.
|
|
697
|
+
*/
|
|
698
|
+
readonly noMemberFilter: "Members of a repeating scalar parameter are coerced rather than filtered; one that cannot be is #VALUE!.";
|
|
699
|
+
};
|
|
700
|
+
|
|
642
701
|
/**
|
|
643
702
|
* A compiled collection of functions — the serialized form of one module.
|
|
644
703
|
*
|
|
@@ -5770,6 +5829,22 @@ declare global {
|
|
|
5770
5829
|
* Returns the absolute bounds for the range.
|
|
5771
5830
|
*/
|
|
5772
5831
|
getBounds(): Bounds;
|
|
5832
|
+
/**
|
|
5833
|
+
* The size this range's content needs — what {@link getBounds} would report if the range had
|
|
5834
|
+
* been {@link autoFit}. A pure query: nothing is measured onto the model and nothing is committed.
|
|
5835
|
+
*
|
|
5836
|
+
* @param options Measurement options. Default `{ axes: IRange.AxisSelection.Both }`.
|
|
5837
|
+
*
|
|
5838
|
+
* @remarks
|
|
5839
|
+
* - The width is the sum of the per-column best fits and the height the sum of the per-row best
|
|
5840
|
+
* fits, so a single-column range answers "how wide must this list be" directly.
|
|
5841
|
+
* - An axis left out of {@link BestFitOptions.axes} reports its current size.
|
|
5842
|
+
* - Only the range's own content is measured, so the answer never depends on cells outside it.
|
|
5843
|
+
* (`autoFit` also scans outside the range, to prove a shrink is safe.)
|
|
5844
|
+
* - Sheet protection is not consulted: reading a size cannot violate it, and a protected sheet
|
|
5845
|
+
* answers the same as an unprotected one.
|
|
5846
|
+
*/
|
|
5847
|
+
getBestFit(options?: ICellRange.BestFitOptions): Size;
|
|
5773
5848
|
/**
|
|
5774
5849
|
* Indicates if the range is readonly only.
|
|
5775
5850
|
*
|
|
@@ -6256,9 +6331,9 @@ declare global {
|
|
|
6256
6331
|
includeMergeOverflow?: boolean;
|
|
6257
6332
|
}
|
|
6258
6333
|
/**
|
|
6259
|
-
* Options for {@link ICellRange.
|
|
6334
|
+
* Options for {@link ICellRange.getBestFit} — measurement only.
|
|
6260
6335
|
*/
|
|
6261
|
-
interface
|
|
6336
|
+
interface BestFitOptions {
|
|
6262
6337
|
/**
|
|
6263
6338
|
* Best fit using the minimum amount of space required.
|
|
6264
6339
|
*
|
|
@@ -6269,21 +6344,6 @@ declare global {
|
|
|
6269
6344
|
* For example allowing numbers to round or use scientific notation.
|
|
6270
6345
|
*/
|
|
6271
6346
|
minContent?: boolean;
|
|
6272
|
-
/**
|
|
6273
|
-
* Restricts autoFit to only grow, never shrink.
|
|
6274
|
-
*
|
|
6275
|
-
* @defaultValue false - adjust in both directions.
|
|
6276
|
-
*
|
|
6277
|
-
* @remarks
|
|
6278
|
-
* This is useful when adjusting fonts and wan the columns to resize but not the rows.
|
|
6279
|
-
*/
|
|
6280
|
-
expandOnly?: boolean | IRange.Axis;
|
|
6281
|
-
/**
|
|
6282
|
-
* If this is set to `true` then any headers that have custom sizes will be ignored.
|
|
6283
|
-
*
|
|
6284
|
-
* @defaultValue false
|
|
6285
|
-
*/
|
|
6286
|
-
skipCustomSize?: boolean;
|
|
6287
6347
|
/**
|
|
6288
6348
|
* The axes to autoFit.
|
|
6289
6349
|
*
|
|
@@ -6305,6 +6365,26 @@ declare global {
|
|
|
6305
6365
|
*/
|
|
6306
6366
|
formulaView?: boolean;
|
|
6307
6367
|
}
|
|
6368
|
+
/**
|
|
6369
|
+
* Options for {@link ICellRange.autoFit}.
|
|
6370
|
+
*/
|
|
6371
|
+
interface AutoFitOptions extends BestFitOptions, ITransaction.OperationOptions {
|
|
6372
|
+
/**
|
|
6373
|
+
* Restricts autoFit to only grow, never shrink.
|
|
6374
|
+
*
|
|
6375
|
+
* @defaultValue false - adjust in both directions.
|
|
6376
|
+
*
|
|
6377
|
+
* @remarks
|
|
6378
|
+
* This is useful when adjusting fonts and wan the columns to resize but not the rows.
|
|
6379
|
+
*/
|
|
6380
|
+
expandOnly?: boolean | IRange.Axis;
|
|
6381
|
+
/**
|
|
6382
|
+
* If this is set to `true` then any headers that have custom sizes will be ignored.
|
|
6383
|
+
*
|
|
6384
|
+
* @defaultValue false
|
|
6385
|
+
*/
|
|
6386
|
+
skipCustomSize?: boolean;
|
|
6387
|
+
}
|
|
6308
6388
|
/**
|
|
6309
6389
|
* Options for {@link ICellRanges.getFlattened}.
|
|
6310
6390
|
*/
|
|
@@ -12500,6 +12580,7 @@ declare global {
|
|
|
12500
12580
|
* | Category | Key methods |
|
|
12501
12581
|
* |---|---|
|
|
12502
12582
|
* | Evaluation lifecycle | `markVolatile`, `getRow`, `getColumn`, `getEntireCoords` |
|
|
12583
|
+
* | Argument reflection | `getArgs` |
|
|
12503
12584
|
* | Output hints | `formatResults` |
|
|
12504
12585
|
* | Range construction | `createRange`, `filterHidden` |
|
|
12505
12586
|
* | Dynamic references | `getReference`, `getValueAt`, `getFormulaAt`, `getSpillAt` |
|
|
@@ -12954,6 +13035,22 @@ declare global {
|
|
|
12954
13035
|
* Mostly for diagnostics; the built-in `INFO` function is built on it.
|
|
12955
13036
|
*/
|
|
12956
13037
|
getRuntime(): IRuntime;
|
|
13038
|
+
/**
|
|
13039
|
+
* The current call's arguments — how many the caller supplied, in which positions, of what kind,
|
|
13040
|
+
* and what each value was BEFORE coercion.
|
|
13041
|
+
*
|
|
13042
|
+
* @remarks
|
|
13043
|
+
* Argument REFLECTION, for the one thing a declaration cannot say: what happened at *this* call.
|
|
13044
|
+
* It exists to serve Excel's declared `any`, which means "no contract, the body decides" — every
|
|
13045
|
+
* other Excel type maps onto a type we already have and the marshaller handles it.
|
|
13046
|
+
*
|
|
13047
|
+
* The returned view is valid ONLY while the body that asked for it is running. Views are pooled
|
|
13048
|
+
* by dispatch depth, so retaining one across an `await`, a callback, or a nested evaluation hands
|
|
13049
|
+
* you another call's arguments.
|
|
13050
|
+
*
|
|
13051
|
+
* @throws If called outside a function dispatch — there are no arguments to reflect on.
|
|
13052
|
+
*/
|
|
13053
|
+
getArgs(): IFunctionArguments;
|
|
12957
13054
|
}
|
|
12958
13055
|
|
|
12959
13056
|
/**
|
|
@@ -13615,9 +13712,164 @@ declare global {
|
|
|
13615
13712
|
* @defaultValue false
|
|
13616
13713
|
*/
|
|
13617
13714
|
cancelable?: boolean;
|
|
13715
|
+
/**
|
|
13716
|
+
* Named engine behaviors this function opts into, from the `@compat` doc tag.
|
|
13717
|
+
*
|
|
13718
|
+
* @remarks
|
|
13719
|
+
* Canonical spellings, deduplicated and in declaration order; a family alias the author wrote
|
|
13720
|
+
* (`@compat atp`) has already been expanded to its atomic features. An unknown name never
|
|
13721
|
+
* reaches here — the linter fails the build on one, deliberately: a compatibility rule that
|
|
13722
|
+
* silently no-ops is the worst failure available, because the fixtures keep passing and the
|
|
13723
|
+
* behavior is simply absent.
|
|
13724
|
+
*
|
|
13725
|
+
* @see {@link CompatFeatures}
|
|
13726
|
+
* @see {@link CompatAliases}
|
|
13727
|
+
*/
|
|
13728
|
+
compat?: CompatFeature[];
|
|
13618
13729
|
}
|
|
13619
13730
|
}
|
|
13620
13731
|
|
|
13732
|
+
/**
|
|
13733
|
+
* The current call's arguments, as the body sees them — argument **reflection**.
|
|
13734
|
+
*
|
|
13735
|
+
* @remarks
|
|
13736
|
+
* A declaration answers "what does this parameter mean?", and the marshaller coerces every
|
|
13737
|
+
* argument to it. That is right for the overwhelming majority of parameters. What it cannot answer
|
|
13738
|
+
* is anything about *this particular call*:
|
|
13739
|
+
*
|
|
13740
|
+
* - What did the caller write there — a value, a cell, an array, nothing at all?
|
|
13741
|
+
* - What was the value BEFORE the parameter's type coerced it?
|
|
13742
|
+
* - Was that empty slot an omission, or a blank cell the caller pointed at?
|
|
13743
|
+
*
|
|
13744
|
+
* Excel has measured behaviors that turn on exactly those questions, and they cluster at the
|
|
13745
|
+
* parameters Excel declares `any` — where there is nothing to express as a type, because Excel
|
|
13746
|
+
* declined to express one. `CUMIPMT` refuses a boolean at every slot while `FV` coerces one at
|
|
13747
|
+
* every slot; the difference is not the values, it is that `CUMIPMT`'s slots are `any` and its
|
|
13748
|
+
* body decides.
|
|
13749
|
+
*
|
|
13750
|
+
* It is REFLECTION and nothing else — two questions, and no third:
|
|
13751
|
+
*
|
|
13752
|
+
* | question | answers |
|
|
13753
|
+
* | --- | --- |
|
|
13754
|
+
* | *what was supplied* | {@link getLength}, {@link isOmittedAt} |
|
|
13755
|
+
* | *what it is* | {@link getRawAt} |
|
|
13756
|
+
*
|
|
13757
|
+
* Coercion is deliberately absent. A body that wants a number calls
|
|
13758
|
+
* {@link IFormulaContext.parseAsNumber} on the value this hands it — that already takes a value,
|
|
13759
|
+
* already propagates an incoming error with its identity, and already answers `#VALUE!` for a
|
|
13760
|
+
* boolean, which IS the rule an `any` slot needs. There is no coercion an index can do that a
|
|
13761
|
+
* value cannot.
|
|
13762
|
+
*
|
|
13763
|
+
* Obtained from `FormulaContext.getArgs()`, and valid ONLY while the body that asked for it is
|
|
13764
|
+
* running. A body must not retain it across an `await`, a callback, or a nested evaluation — the
|
|
13765
|
+
* views are pooled by dispatch depth, so the one at your depth is handed to the next call at that
|
|
13766
|
+
* depth.
|
|
13767
|
+
*
|
|
13768
|
+
* ```typescript
|
|
13769
|
+
* export function CUMIPMT(rate: Scalar, nper: Scalar): number {
|
|
13770
|
+
* const args = FormulaContext.getArgs();
|
|
13771
|
+
* if (args.isOmittedAt(0)) return FormulaError.BuiltIn.NA; // `CUMIPMT(,120,…)` is #N/A
|
|
13772
|
+
* const asNumber = FormulaContext.parseAsNumber(args.getRawAt(0) as Scalar); // TRUE is #VALUE!
|
|
13773
|
+
* // …
|
|
13774
|
+
* }
|
|
13775
|
+
* ```
|
|
13776
|
+
*
|
|
13777
|
+
* @see {@link IFormulaContext.getArgs}
|
|
13778
|
+
*/
|
|
13779
|
+
export interface IFunctionArguments {
|
|
13780
|
+
/**
|
|
13781
|
+
* How many PARAMETERS the caller supplied.
|
|
13782
|
+
*
|
|
13783
|
+
* @remarks
|
|
13784
|
+
* Indexing throughout matches the BODY's own signature, never the raw call positions
|
|
13785
|
+
* (see {@link getRawAt}). `index >= getLength()` is an ABSENT argument — one the caller never
|
|
13786
|
+
* wrote, whose own JS initializer supplied the value. That is a different thing from an OMITTED
|
|
13787
|
+
* one; see {@link isOmittedAt}.
|
|
13788
|
+
*/
|
|
13789
|
+
getLength(): number;
|
|
13790
|
+
/**
|
|
13791
|
+
* This invocation's value at `index`, uncoerced.
|
|
13792
|
+
*
|
|
13793
|
+
* @param index The PARAMETER index — the position in the body's own signature.
|
|
13794
|
+
*
|
|
13795
|
+
* @remarks
|
|
13796
|
+
* A `Scalar` means the argument IS a value; an {@link IRange} means a container whose members
|
|
13797
|
+
* the body reads itself (a reference materializes on demand); a {@link Lambda} means a callable.
|
|
13798
|
+
*
|
|
13799
|
+
* At a REPEATING parameter (`Repeating<T>`, or a rest parameter) this is the ARRAY of that
|
|
13800
|
+
* group's values — one entry per argument the caller wrote — and {@link getRepeatingArgsAt} is the
|
|
13801
|
+
* per-argument view of the same thing. Indexing by parameter rather than by call position is
|
|
13802
|
+
* what lets a body ask its questions in the vocabulary it declared:
|
|
13803
|
+
*
|
|
13804
|
+
* ```typescript
|
|
13805
|
+
* // IFS(condition: Repeating<[logicalTest: boolean, logicalTrue: AcceptError<any>]>)
|
|
13806
|
+
* args.getRawAt(0); // [test1, value1, test2, value2, …]
|
|
13807
|
+
* args.getRepeatingArgsAt(0).getRawAt(0); // test1
|
|
13808
|
+
* ```
|
|
13809
|
+
*
|
|
13810
|
+
* **Under a lift** the call broadcasts and the body runs once per output cell; this reports the
|
|
13811
|
+
* value for THIS invocation — the member at the current broadcast position for a lifted argument,
|
|
13812
|
+
* the whole argument for one that is not lifting. That is what every identified caller wants: a
|
|
13813
|
+
* body checking for a boolean must see the member, not the array around it.
|
|
13814
|
+
*
|
|
13815
|
+
* One boundary is worth knowing: under a lift at a parameter that declares a CONCRETE scalar
|
|
13816
|
+
* type, the member has already been converted by that declaration, so the raw and coerced answers
|
|
13817
|
+
* coincide there. At the `Scalar` slots this interface exists for, nothing coerces and the value
|
|
13818
|
+
* is the member exactly as the caller's range holds it.
|
|
13819
|
+
*/
|
|
13820
|
+
getRawAt(index: number): IFunctionArguments.RawArg | IFunctionArguments.RawArg[];
|
|
13821
|
+
/**
|
|
13822
|
+
* A nested view over one REPEATING parameter's arguments, so a body can ask the same questions
|
|
13823
|
+
* one level down — `getRepeatingArgsAt(0).isOmittedAt(1)`.
|
|
13824
|
+
*
|
|
13825
|
+
* @param index The PARAMETER index of the repeating group (or rest parameter).
|
|
13826
|
+
*
|
|
13827
|
+
* @remarks
|
|
13828
|
+
* The nested view is FLAT over the group's arguments: a period-2 group repeated three times reads
|
|
13829
|
+
* as six, in call order. That is where "which one was omitted" has an answer at all — the group
|
|
13830
|
+
* as a whole cannot be omitted, only one of its arguments can.
|
|
13831
|
+
*
|
|
13832
|
+
* At a non-repeating parameter this returns an EMPTY view (`getLength()` of 0) rather than
|
|
13833
|
+
* throwing, so a body that folds over its groups needs no special case.
|
|
13834
|
+
*/
|
|
13835
|
+
getRepeatingArgsAt(index: number): IFunctionArguments;
|
|
13836
|
+
/**
|
|
13837
|
+
* True for an OMITTED argument — one the caller supplied EMPTY, as the trailing comma of
|
|
13838
|
+
* `CUMIPMT(,120,100000,13,24,0)`.
|
|
13839
|
+
*
|
|
13840
|
+
* @remarks
|
|
13841
|
+
* There are THREE positions, not two, and Excel answers each differently:
|
|
13842
|
+
*
|
|
13843
|
+
* | form | position | Excel |
|
|
13844
|
+
* | --- | --- | --- |
|
|
13845
|
+
* | `CUMIPMT(0.01,120,100000,13,24)` | ABSENT | refused at entry |
|
|
13846
|
+
* | `CUMIPMT(,120,100000,13,24,0)` | **OMITTED** | `#N/A` |
|
|
13847
|
+
* | `CUMIPMT(0.01,120,100000,13,24,E1)`, E1 blank | a blank CELL | the ordinary answer |
|
|
13848
|
+
*
|
|
13849
|
+
* This separates the middle row from the other two. ABSENT is `index >= getLength()`; a blank
|
|
13850
|
+
* cell is an ordinary value the caller pointed at and is not omitted.
|
|
13851
|
+
*/
|
|
13852
|
+
isOmittedAt(index: number): boolean;
|
|
13853
|
+
}
|
|
13854
|
+
|
|
13855
|
+
/**
|
|
13856
|
+
* {@inheritDoc IFunctionArguments}
|
|
13857
|
+
*
|
|
13858
|
+
* @see
|
|
13859
|
+
* ### **Interface**
|
|
13860
|
+
*
|
|
13861
|
+
* {@link IFunctionArguments}
|
|
13862
|
+
*/
|
|
13863
|
+
export namespace IFunctionArguments {
|
|
13864
|
+
/**
|
|
13865
|
+
* One argument as the caller wrote it — a value, a container, a callable, or nothing.
|
|
13866
|
+
*
|
|
13867
|
+
* @remarks
|
|
13868
|
+
* `undefined` is an OMITTED or ABSENT argument; `null` is a blank, which is a value.
|
|
13869
|
+
*/
|
|
13870
|
+
type RawArg = Scalar | IRange | Lambda | undefined;
|
|
13871
|
+
}
|
|
13872
|
+
|
|
13621
13873
|
/**
|
|
13622
13874
|
* Collections of {@link IFunction}.
|
|
13623
13875
|
*/
|
|
@@ -17052,11 +17304,28 @@ declare global {
|
|
|
17052
17304
|
*/
|
|
17053
17305
|
filter<TS extends Scalar = T>(callbackFn: (value: TS, coords: IRange.CellCoords, range: IRange<T>) => MaybeError<boolean>, options?: IRange.TraversalAxis | IRange.IteratorOptions): this;
|
|
17054
17306
|
/**
|
|
17055
|
-
*
|
|
17307
|
+
* Linearizes the range into a single column by flattened ordinal — the member at ordinal `i`
|
|
17308
|
+
* lands at row `i`, column 0.
|
|
17056
17309
|
*
|
|
17057
17310
|
* @param options {@link IRange.IteratorOptions}
|
|
17311
|
+
*
|
|
17312
|
+
* @remarks
|
|
17313
|
+
* `options.axis` is the TRAVERSAL order feeding the ordinal, not the orientation of the result:
|
|
17314
|
+
* the result is always Nx1, and a row is `flatten().transpose()`. The default is row-major,
|
|
17315
|
+
* which is the order Excel pairs two range operands in.
|
|
17316
|
+
*
|
|
17317
|
+
* `options.type` carries a read type onto the result, so a member the type filters out becomes
|
|
17318
|
+
* a HOLE at its ordinal rather than compacting the column. That is what lets two operands be
|
|
17319
|
+
* paired position by position — see {@link alignValues}.
|
|
17320
|
+
*
|
|
17321
|
+
* `options.includeEmpty` has no meaning here and is ignored: a range is inherently sparse, so
|
|
17322
|
+
* an empty position is simply absent. Sparsity is preserved and nothing is materialized.
|
|
17323
|
+
*
|
|
17324
|
+
* Equivalent to `reshape(rows * columns, 1)`, which is where the ordinal rule is stated.
|
|
17325
|
+
*
|
|
17326
|
+
* @see {@link getValuesFlat} for the same linearization as a JS array.
|
|
17058
17327
|
*/
|
|
17059
|
-
flatten
|
|
17328
|
+
flatten(options?: IRange.IteratorOptions): this;
|
|
17060
17329
|
/**
|
|
17061
17330
|
* Iterates over the cells within the range, applying the provided callback function to each cell.
|
|
17062
17331
|
*
|
|
@@ -17134,6 +17403,16 @@ declare global {
|
|
|
17134
17403
|
* @param options {@link IRange.ValueOptions}
|
|
17135
17404
|
*/
|
|
17136
17405
|
getValueAt<TS extends Scalar = T>(rowIndex: number, colIndex: number, options?: IRange.ValueOptions): TS;
|
|
17406
|
+
/**
|
|
17407
|
+
* Returns the members as a flat JS array.
|
|
17408
|
+
*
|
|
17409
|
+
* @param options {@link IRange.IteratorOptions}
|
|
17410
|
+
*
|
|
17411
|
+
* @remarks
|
|
17412
|
+
* The array form of {@link flatten}. Skips empty members unless `includeEmpty` is set, where
|
|
17413
|
+
* `flatten` keeps them as holes in a range.
|
|
17414
|
+
*/
|
|
17415
|
+
getValuesFlat<TS extends Scalar = T>(options?: IRange.IteratorOptions): TS[];
|
|
17137
17416
|
/**
|
|
17138
17417
|
* Returns the number of columns of the range.
|
|
17139
17418
|
*/
|
|
@@ -28563,6 +28842,7 @@ declare global {
|
|
|
28563
28842
|
c?: boolean;
|
|
28564
28843
|
p?: MinifiedParameter[];
|
|
28565
28844
|
r?: MinifiedValue;
|
|
28845
|
+
x?: CompatFeature[];
|
|
28566
28846
|
}
|
|
28567
28847
|
|
|
28568
28848
|
export type MinifiedDeclarations = {
|
|
@@ -29473,6 +29753,28 @@ declare global {
|
|
|
29473
29753
|
*/
|
|
29474
29754
|
export type Repeating<T> = T[];
|
|
29475
29755
|
|
|
29756
|
+
/**
|
|
29757
|
+
* Resolves a `@compat` feature name, CASE-INSENSITIVELY, to its canonical spelling.
|
|
29758
|
+
*
|
|
29759
|
+
* @param name The name as the author wrote it.
|
|
29760
|
+
* @returns The canonical name, or `null` when no feature goes by it.
|
|
29761
|
+
*
|
|
29762
|
+
* @remarks
|
|
29763
|
+
* Authors write `@compat noReferenceLift`; `@Compat NOREFERENCELIFT` means the same thing. Only
|
|
29764
|
+
* the canonical spelling is ever stored, so the declaration a build emits does not depend on how
|
|
29765
|
+
* the tag was typed.
|
|
29766
|
+
*/
|
|
29767
|
+
export function resolveCompatFeature(name: string): CompatFeature | null;
|
|
29768
|
+
|
|
29769
|
+
/**
|
|
29770
|
+
* Resolves a `@compat` name — a feature or a family alias — CASE-INSENSITIVELY, to the canonical
|
|
29771
|
+
* features it turns on.
|
|
29772
|
+
*
|
|
29773
|
+
* @param name The name as the author wrote it.
|
|
29774
|
+
* @returns The canonical features, or `null` when no feature or alias goes by that name.
|
|
29775
|
+
*/
|
|
29776
|
+
export function resolveCompatFeatures(name: string): readonly CompatFeature[] | null;
|
|
29777
|
+
|
|
29476
29778
|
/**
|
|
29477
29779
|
* Flatten a locale's declared `inherit` into a concrete lookup order, most-specific first.
|
|
29478
29780
|
*
|
|
@@ -38,6 +38,11 @@ export declare class Calculation extends AbstractModel<State, ICalculation.JSON,
|
|
|
38
38
|
protected _getRanges: (address: ICellRanges.Address, options?: ICellRange.GetRangeOptions) => ICellRanges;
|
|
39
39
|
protected _calcExecutor: CalcExecutor;
|
|
40
40
|
protected _cycleId: number;
|
|
41
|
+
protected _staticEpoch: number;
|
|
42
|
+
protected _precedentEpoch: number;
|
|
43
|
+
protected _epochSeenFormulas: ISpatialMap3D<FormulaSpatialValue> | null;
|
|
44
|
+
protected _epochSeenPrecedents: ISpatialMap3D<PrecedentSpatialValue> | null;
|
|
45
|
+
protected _epochSeenDynamics: Map<FormulaSpatialValue, ISpatialMap.Entry<PrecedentSpatialValue>[]> | null;
|
|
41
46
|
protected _volatiles: Set<CalcNode>;
|
|
42
47
|
protected _calculatedCommitId: string | null;
|
|
43
48
|
protected _pendingActions: (() => Promise<unknown>)[] | null;
|
|
@@ -17,7 +17,9 @@ export declare class CalcExecutor {
|
|
|
17
17
|
protected _container: IContextContainer;
|
|
18
18
|
protected _context: IFormulaContext;
|
|
19
19
|
private readonly _requestCalculate;
|
|
20
|
-
protected _pendingCalcs:
|
|
20
|
+
protected _pendingCalcs: Map<CalcNode, number>;
|
|
21
|
+
/** Debounced drain of {@link _pendingCalcs} into the volatile set; one instance for the executor's lifetime. */
|
|
22
|
+
private readonly _flushPendingCalcs;
|
|
21
23
|
/**
|
|
22
24
|
* The last pass's circular roster: every node it evaluated by demand (a `doMarkAndPlan` that
|
|
23
25
|
* could not order, or the iteration guard's hand-over) plus every node whose dynamic read
|
|
@@ -90,6 +92,54 @@ export declare class CalcExecutor {
|
|
|
90
92
|
evaluations: number;
|
|
91
93
|
retries: number;
|
|
92
94
|
};
|
|
95
|
+
/**
|
|
96
|
+
* Counters and per-phase timings over every plan since construction — the measurement rig the
|
|
97
|
+
* performance plan's §1.6 rollout asks for, and what validates the §1.2/§1.3 caches while
|
|
98
|
+
* {@link planCacheMode} is `'assert'`.
|
|
99
|
+
*/
|
|
100
|
+
protected _planStats: CalcExecutor.PlanStats;
|
|
101
|
+
/**
|
|
102
|
+
* The plan caches of CALC-PERFORMANCE-PLAN.md §1.2/§1.3.
|
|
103
|
+
*
|
|
104
|
+
* - `'on'` (default): an eligible pass skips the in-degree + Kahn phases (plan = affected set
|
|
105
|
+
* sorted by order stamp) and discovery reuses cached `dependents`.
|
|
106
|
+
* - `'assert'` (the §1.6 rollout mode; the diagnostic to flip back to if values ever look
|
|
107
|
+
* stale — `__sxlCalc.mode('assert')`): stamps are written and eligibility computed, but every
|
|
108
|
+
* pass still runs the full search + Kahn phases; the fast path's order and the cached
|
|
109
|
+
* `dependents` are VERIFIED against them, mismatches counted in
|
|
110
|
+
* `planAssertFailures`/`dependentsAssertFailures` and logged. Costs the old planning price
|
|
111
|
+
* plus epsilon.
|
|
112
|
+
* - `'off'`: stamps are neither written nor consulted.
|
|
113
|
+
*/
|
|
114
|
+
planCacheMode: 'off' | 'assert' | 'on';
|
|
115
|
+
/** Next order-stamp plan id to hand out; ids are unique across passes. */
|
|
116
|
+
protected _planIdNext: number;
|
|
117
|
+
/** Id of the last fully-ordered plan that stamped (§1.2); `0` = none yet. */
|
|
118
|
+
protected _lastPlanId: number;
|
|
119
|
+
/** Length of the last stamped plan — the `orderIndex` range the fast path's bucket order spans. */
|
|
120
|
+
protected _lastStampedLength: number;
|
|
121
|
+
/**
|
|
122
|
+
* Whole-closure reuse (§1.4): remembered fully-ordered passes — seeds, plan, and the
|
|
123
|
+
* `precedentEpoch` each was planned at (`-1` = empty). A pass with the identical seed set at
|
|
124
|
+
* the same epoch has the identical affected closure and the same valid order, so discovery and
|
|
125
|
+
* the sort are skipped outright: the plan is reused verbatim and each node gets only its
|
|
126
|
+
* per-pass reset. TWO slots, because one was not enough for the common workflow — "type a value,
|
|
127
|
+
* then fill it down": the single-cell pass overwrote the remembered bulk plan every time. Slots
|
|
128
|
+
* are recycled least-recently-USED (a hit refreshes a memo's clock), so the two plans in play
|
|
129
|
+
* both stay resident: bulk → small edits → same bulk hits, and two alternating bulk edits both
|
|
130
|
+
* hit. NOT "keep the largest": a full calc's plan is the same size as a bulk edit's over the
|
|
131
|
+
* same sheet, and that tie evicted the bulk memo on the very next small edit. Per executor, not
|
|
132
|
+
* module scope (§1.5).
|
|
133
|
+
*/
|
|
134
|
+
protected _planMemos: [CalcExecutor.PlanMemo, CalcExecutor.PlanMemo];
|
|
135
|
+
/** The memos' LRU clock. Its own counter, NOT `PlanStats.passes`: a stats reset must not reorder the slots. */
|
|
136
|
+
protected _planMemoClock: number;
|
|
137
|
+
/**
|
|
138
|
+
* Nodes with an async promise in flight. Per executor, NOT module scope — module scope would
|
|
139
|
+
* cross-pollute workbook instances (undo to 0 formulas needs to clear these; TODO - revisit
|
|
140
|
+
* how we manage promises).
|
|
141
|
+
*/
|
|
142
|
+
protected _pendingPromises: Set<CalcNode>;
|
|
93
143
|
_gridUpdates: Map<string, ICalcGrid.IncrementalUpdates> | null;
|
|
94
144
|
_addDynamicPrecedent: ((node: CalcNode, range: IRange.Coords | undefined, kind: PrecedentKind) => void) | null;
|
|
95
145
|
constructor(container: IContextContainer, context: IFormulaContext, requestCalculate: () => void);
|
|
@@ -221,11 +271,17 @@ export declare class CalcExecutor {
|
|
|
221
271
|
* carrying the {@link CycleRole} its reads gave it. Describes the last pass only.
|
|
222
272
|
*/
|
|
223
273
|
getCircularNodes(): readonly CalcNode[];
|
|
224
|
-
/**
|
|
274
|
+
/**
|
|
275
|
+
* @internal
|
|
276
|
+
* Demand-pass counters since construction — evaluations and `NeedsFirst` retries — plus the
|
|
277
|
+
* plan-phase counters and timings (see {@link _planStats}).
|
|
278
|
+
*/
|
|
225
279
|
getDemandStats(): {
|
|
226
280
|
evaluations: number;
|
|
227
281
|
retries: number;
|
|
228
|
-
};
|
|
282
|
+
} & CalcExecutor.PlanStats;
|
|
283
|
+
/** @internal Zeroes every counter/timing so a measurement window starts clean (`__sxlCalc.reset()`). */
|
|
284
|
+
resetStats(): void;
|
|
229
285
|
/**
|
|
230
286
|
* Collects and marks all volatile CalcNodes.
|
|
231
287
|
*
|
|
@@ -253,6 +309,17 @@ export declare class CalcExecutor {
|
|
|
253
309
|
* Uses Kahn's algorithm.
|
|
254
310
|
*/
|
|
255
311
|
doMarkAndPlan(cycleId: number, markId: number, initial: FixedPackedArray<CalcNode>, plan: FixedPackedArray<CalcNode>, forceDemand?: boolean): boolean;
|
|
312
|
+
/**
|
|
313
|
+
* The remembered plan whose seed set is exactly this pass's, at this epoch — or `null`. The
|
|
314
|
+
* length check first: it is what rejects the common miss (a single-cell pass against a bulk
|
|
315
|
+
* memo) before any node is touched.
|
|
316
|
+
*/
|
|
317
|
+
private _matchPlanMemo;
|
|
318
|
+
/**
|
|
319
|
+
* Records this pass's seeds and plan for whole-closure reuse (§1.4). The victim slot is a stale
|
|
320
|
+
* one if there is one, else the least recently used.
|
|
321
|
+
*/
|
|
322
|
+
private _rememberPlan;
|
|
256
323
|
doEvaluate(cycleId: number, getUpdates: (scope: string) => ICalcGrid.IncrementalUpdates, scheduleRecalculation: (cycleId: number, calcNode?: CalcNode) => void, commit: (calcNodes: CalcNode[], calcNodesLength: number) => void, forceFull: boolean, plan: FixedPackedArray<CalcNode>): ISpatialMap | undefined;
|
|
257
324
|
}
|
|
258
325
|
export declare namespace CalcExecutor {
|
|
@@ -296,6 +363,48 @@ export declare namespace CalcExecutor {
|
|
|
296
363
|
/** Volatiles accumulated before this cycle — drained and cleared by execute() */
|
|
297
364
|
oldVolatiles: Set<CalcNode>;
|
|
298
365
|
}
|
|
366
|
+
/** A remembered fully-ordered pass for whole-closure reuse (§1.4) — see `CalcExecutor._planMemos`. */
|
|
367
|
+
interface PlanMemo {
|
|
368
|
+
seeds: CalcNode[];
|
|
369
|
+
seedsLength: number;
|
|
370
|
+
plan: CalcNode[];
|
|
371
|
+
planLength: number;
|
|
372
|
+
/** The `precedentEpoch` the plan was made at; `-1` = empty. */
|
|
373
|
+
epoch: number;
|
|
374
|
+
/** `CalcExecutor._planMemoClock` when last written or matched — the LRU key for slot recycling. */
|
|
375
|
+
used: number;
|
|
376
|
+
}
|
|
377
|
+
/** Plan-phase counters and timings — see `CalcExecutor.planCacheMode` and performance plan §1.6. */
|
|
378
|
+
interface PlanStats {
|
|
379
|
+
/** In-degree formula lookups answered by the single-entry block cache. */
|
|
380
|
+
formulaCacheHits: number;
|
|
381
|
+
formulaCacheMisses: number;
|
|
382
|
+
/** doMarkAndPlan invocations. */
|
|
383
|
+
passes: number;
|
|
384
|
+
/** Passes whose whole affected set carried valid order stamps (fast-path candidates). */
|
|
385
|
+
fastEligible: number;
|
|
386
|
+
/** Eligible passes that actually skipped in-degree + Kahn (`'on'` mode only). */
|
|
387
|
+
fastHits: number;
|
|
388
|
+
/** Passes whose seed set and precedent epoch matched the last plan (§1.4 candidates). */
|
|
389
|
+
closureEligible: number;
|
|
390
|
+
/** Closure-eligible passes that reused the last plan verbatim, skipping discovery too (`'on'` only). */
|
|
391
|
+
closureHits: number;
|
|
392
|
+
/** `'assert'` mode: closure-eligible passes whose fresh affected set differed from the last plan. */
|
|
393
|
+
closureAssertFailures: number;
|
|
394
|
+
/** Fully-ordered plans that wrote order stamps. */
|
|
395
|
+
stampedPlans: number;
|
|
396
|
+
/** `'assert'` mode: eligible passes whose stamp order contradicted a real static edge. */
|
|
397
|
+
planAssertFailures: number;
|
|
398
|
+
/** `'assert'` mode: cached `dependents` that did not match a fresh search. */
|
|
399
|
+
dependentsAssertFailures: number;
|
|
400
|
+
/** Discovery searches skipped (or verified) because `dependentsEpoch` was current. */
|
|
401
|
+
dependentsCacheHits: number;
|
|
402
|
+
dependentsCacheMisses: number;
|
|
403
|
+
discoveryMs: number;
|
|
404
|
+
inDegreeMs: number;
|
|
405
|
+
kahnMs: number;
|
|
406
|
+
evaluateMs: number;
|
|
407
|
+
}
|
|
299
408
|
/** Updated spatial maps and committed grid batches returned to Calculation */
|
|
300
409
|
interface ExecuteResult {
|
|
301
410
|
precedentSpatial: ISpatialMap3D<PrecedentSpatialValue>;
|
|
@@ -63,6 +63,26 @@ export interface CalcNode {
|
|
|
63
63
|
* {@link cycleGroup}; the role it shows is the `CalcState.ShownRoleMask` field of {@link state}.
|
|
64
64
|
*/
|
|
65
65
|
shownGroup: number;
|
|
66
|
+
/**
|
|
67
|
+
* Position of this node in the last FULLY-ORDERED plan that stamped it (CALC-PERFORMANCE-PLAN.md
|
|
68
|
+
* §1.2). Meaningful only when {@link planId} and {@link planEpoch} match the executor's current
|
|
69
|
+
* plan id and the container's static epoch; `-1` until first stamped.
|
|
70
|
+
*/
|
|
71
|
+
orderIndex: number;
|
|
72
|
+
/**
|
|
73
|
+
* Id of the Kahn pass that stamped {@link orderIndex}; `0` = never stamped. Stamps from
|
|
74
|
+
* different passes are NOT mutually comparable — the fast path requires every affected node to
|
|
75
|
+
* carry the executor's `_lastPlanId`.
|
|
76
|
+
*/
|
|
77
|
+
planId: number;
|
|
78
|
+
/** The container's `staticEpoch` when {@link orderIndex} was stamped; stale under a newer epoch. */
|
|
79
|
+
planEpoch: number;
|
|
80
|
+
/**
|
|
81
|
+
* The container's `precedentEpoch` when {@link dependents} was last computed
|
|
82
|
+
* (CALC-PERFORMANCE-PLAN.md §1.3). Discovery reuses the cached array while this matches;
|
|
83
|
+
* `0` = never computed.
|
|
84
|
+
*/
|
|
85
|
+
dependentsEpoch: number;
|
|
66
86
|
/**
|
|
67
87
|
* Bit mask, laid out by `CalcState`: the pending flags, `Skip`, `Circular`, and the
|
|
68
88
|
* `DemandState`/`CycleRole` fields of the current pass.
|