@sheetxl/primitives 0.8.0-beta.1 → 0.8.0-beta.3
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/index.cjs +1 -1
- package/browser/esm/index.mjs +88 -73
- package/node/esm/index.mjs +98 -83
- package/package.json +1 -1
- package/types/src/ErrorPolicy.d.ts +48 -57
- package/types/src/Flatten.d.ts +6 -3
- package/types/src/FormulaContext.d.ts +19 -5
- package/types/src/IFormulaContext.d.ts +83 -7
- package/types/src/IFunction.d.ts +339 -44
- package/types/src/IFunctionArguments.d.ts +64 -15
- package/types/src/IRange.d.ts +152 -38
- package/types/src/IRangeStats.d.ts +32 -2
- package/types/src/IRuntime.d.ts +24 -1
- package/types/src/Lazy.d.ts +76 -0
- package/types/src/NoFilter.d.ts +34 -0
- package/types/src/NoLift.d.ts +31 -0
- package/types/src/Repeating.d.ts +24 -4
- package/types/src/ReportType.d.ts +42 -0
- package/types/src/Scalar.d.ts +1 -1
- package/types/src/ValueKind.d.ts +43 -0
- package/types/src/Volatile.d.ts +12 -0
- package/types/src/WildCard.d.ts +13 -9
- package/types/src/index.d.ts +6 -1
- package/types/src/Compat.d.ts +0 -77
package/types/src/Repeating.d.ts
CHANGED
|
@@ -48,19 +48,39 @@
|
|
|
48
48
|
* "the final element of the final group may be omitted" rule; that rule would accept a formula
|
|
49
49
|
* Excel refuses. An optional slot anywhere else in the group is a compiler error.
|
|
50
50
|
*
|
|
51
|
+
* ### The maximum, `Max`
|
|
52
|
+
*
|
|
53
|
+
* The second type argument is the largest number of arguments the WHOLE CALL accepts, which is
|
|
54
|
+
* how Excel states it: one number per NAME, compared against the call's total argument count and
|
|
55
|
+
* refused at entry (`Excess_function_arguments`), never a count of this parameter's own share.
|
|
56
|
+
* `SWITCH`'s 254 therefore covers its `expression` and its trailing `default` as well as the
|
|
57
|
+
* pairs, and `CHOOSEROWS`' covers its `array`.
|
|
58
|
+
*
|
|
59
|
+
* It defaults to **255**, which is the ceiling for most names and the highest any name carries.
|
|
60
|
+
* Declare it only where a name draws the line lower — `XOR`, `IFS`, `SWITCH`, `LAMBDA`, `LET`,
|
|
61
|
+
* `AGGREGATE`, `SORTBY`, `MAXIFS`, `MINIFS`, `CONCAT`, `TEXTJOIN`, `HSTACK`, `VSTACK`,
|
|
62
|
+
* `CHOOSEROWS`, `CHOOSECOLS` and every DOTTED
|
|
63
|
+
* descriptive spelling (`STDEV.S`, `VAR.P`, `MODE.MULT`, …) all stop at 254 where their legacy
|
|
64
|
+
* twins take 255. It cannot be derived from the shape, so it belongs to the declaration.
|
|
65
|
+
*
|
|
66
|
+
* A REST parameter is the one place `Repeating` may be written alongside `...`, and only with an
|
|
67
|
+
* explicit `Max`: `...rest: Repeating<T, 254>` keeps the rest parameter's own 0-or-more meaning
|
|
68
|
+
* and adds nothing but the ceiling. A bare `Repeating<T>` on a rest parameter stays an error —
|
|
69
|
+
* that is the spelling collision the marker exists to avoid.
|
|
70
|
+
*
|
|
51
71
|
* @example
|
|
52
72
|
* ```ts
|
|
53
73
|
* export function SUMIFS(
|
|
54
|
-
* sumRange:
|
|
55
|
-
* criteria: Repeating<[criteriaRange:
|
|
74
|
+
* sumRange: IRange,
|
|
75
|
+
* criteria: Repeating<[criteriaRange: IReferenceRange, criteria: AcceptError<Scalar>]>
|
|
56
76
|
* ): IRange {
|
|
57
77
|
* for (const [range, test] of criteria) { ... }
|
|
58
78
|
* }
|
|
59
79
|
*
|
|
60
|
-
* export function HSTACK(array: Repeating<
|
|
80
|
+
* export function HSTACK(array: Repeating<IRange, 254>): IRange {
|
|
61
81
|
* return array.reduce((acc, next) => acc.concat(next, IRange.Axis.Column));
|
|
62
82
|
* }
|
|
63
83
|
* ```
|
|
64
84
|
*/
|
|
65
|
-
export type Repeating<T> = T[];
|
|
85
|
+
export type Repeating<T, Max extends number = 255> = T[];
|
|
66
86
|
//# sourceMappingURL=Repeating.d.ts.map
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Declares the parameter's type as ADVISORY: the engine delivers it when it can, and hands the
|
|
3
|
+
* body whatever actually arrived when it cannot, instead of answering `#VALUE!` on the body's
|
|
4
|
+
* behalf.
|
|
5
|
+
*
|
|
6
|
+
* @remarks
|
|
7
|
+
* Excel has no marshalling contract. A function there is called with the operands as they are and
|
|
8
|
+
* calls library helpers for whatever it needs — `LARGE` asks for a range's values and gets every
|
|
9
|
+
* area of a union, `ROWS` never dereferences at all and answers `#REF!` when it sees two areas,
|
|
10
|
+
* `SUMPRODUCT` demands one rectangle and fails on the same argument. Three answers, no rule: the
|
|
11
|
+
* body's own access pattern is the whole of it.
|
|
12
|
+
*
|
|
13
|
+
* A declared surface cannot express that, and modelling it would mean a marker per behavior. This
|
|
14
|
+
* is the boundary instead — ONE marker saying "the type is what the caller is told, not a
|
|
15
|
+
* guarantee to the body". The declared `T` still reaches the function help, the wizard and the
|
|
16
|
+
* linter, because that IS what the slot means to a user; it just stops being a gate.
|
|
17
|
+
*
|
|
18
|
+
* | argument | plain `IRange` | `ReportType<IRange>` |
|
|
19
|
+
* | --- | --- | --- |
|
|
20
|
+
* | `A1:A5` | the range | the range |
|
|
21
|
+
* | `(A1:A5,B1:B2)` — a union | `#VALUE!`, the call never runs | the areas, as `IRange[]` |
|
|
22
|
+
* | a value, an error | `#VALUE!` / propagates | the value, the error |
|
|
23
|
+
*
|
|
24
|
+
* At the type level it is `T` — like {@link AcceptError}, and for the same reason: the marker is a
|
|
25
|
+
* RULE, not a type. A body that declares it and then assumes `T` will crash on the argument the
|
|
26
|
+
* marker exists to deliver, so narrow first. {@link IFunctionArguments.getKindAt} is total over
|
|
27
|
+
* what can arrive and {@link IFunctionArguments.getAreaCountAt} answers the union question the
|
|
28
|
+
* kind cannot — a plain reference is one area, a union is more.
|
|
29
|
+
*
|
|
30
|
+
* Its use is meant to stay countable: a slot earns it with a rule Excel actually shows, never
|
|
31
|
+
* with a guess.
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* ```ts
|
|
35
|
+
* export function ROWS(array: ReportType<IRange>): Scalar {
|
|
36
|
+
* if (FormulaContext.getArgs().getAreaCountAt(0) > 1) return FormulaError.BuiltIn.Ref!;
|
|
37
|
+
* return array.getRowCount();
|
|
38
|
+
* }
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
export type ReportType<T> = T;
|
|
42
|
+
//# sourceMappingURL=ReportType.d.ts.map
|
package/types/src/Scalar.d.ts
CHANGED
|
@@ -42,7 +42,7 @@ export declare namespace Scalar {
|
|
|
42
42
|
* text's shape (decimal places, grouping) survives for format inference.
|
|
43
43
|
*
|
|
44
44
|
* @remarks
|
|
45
|
-
* Callers apply this to every text→number path and to nothing else
|
|
45
|
+
* Callers apply this to every text→number path and to nothing else. It is
|
|
46
46
|
* truncation, not rounding: `1234567890.123456789` stores `…345`, never `…346`.
|
|
47
47
|
*/
|
|
48
48
|
function truncateNumberText(text: string): string;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The KIND of one value — the total discriminator over {@link IFunctionArguments.RawArg}, and the
|
|
3
|
+
* vocabulary a RETURN declaration speaks ({@link IFunction.IReturnType.getKind}).
|
|
4
|
+
*
|
|
5
|
+
* @remarks
|
|
6
|
+
* A value's kind and its extent are different axes: `{10}`, `A1` and a bare `10` all reach a
|
|
7
|
+
* range-typed parameter as a 1x1 container, yet Excel separates them:
|
|
8
|
+
* `VLOOKUP(10,10,1,TRUE)` is `#N/A` while `VLOOKUP(10,{10},1,TRUE)` is 10, and `TYPE` answers
|
|
9
|
+
* 1 vs 64. The kind is what the CALLER supplied; the extent is merely its size.
|
|
10
|
+
*
|
|
11
|
+
* The scalar kinds ARE {@link ScalarType} values — one vocabulary, so
|
|
12
|
+
* `getKindAt(i) === ScalarType.Boolean` reads naturally — extended with the four kinds only an
|
|
13
|
+
* argument can be: a reference, a non-reference array, a callable, and no argument at all. As an
|
|
14
|
+
* argument kind, {@link ScalarType.Null} means a BLANK value.
|
|
15
|
+
*
|
|
16
|
+
* The names and values are ours. The numeric codes Excel's `TYPE` function answers are a
|
|
17
|
+
* PROJECTION of this kind (see `TYPE`'s implementation), not the kind itself.
|
|
18
|
+
*
|
|
19
|
+
* @see {@link IFunctionArguments.getKindAt}
|
|
20
|
+
*/
|
|
21
|
+
export declare const ValueKind: {
|
|
22
|
+
/** A reference — `A1`, `A1:B3`, or a reference-returning call (`INDEX`, `OFFSET`, `TAKE`). */
|
|
23
|
+
readonly Reference: "reference";
|
|
24
|
+
/** An ARRAY that is not a reference — `{1,2}`, or a computed one (`SEQUENCE`, `TRANSPOSE(…)`). */
|
|
25
|
+
readonly Array: "array";
|
|
26
|
+
/** A callable — `LAMBDA(…)`, an eta-reduced function name, or a lambda-valued binding. */
|
|
27
|
+
readonly Lambda: "lambda";
|
|
28
|
+
/**
|
|
29
|
+
* OMITTED — nothing at this position: the empty comma of `CUMIPMT(,120,…)`, or a position
|
|
30
|
+
* past what the caller wrote. A blank CELL is a `Reference` (blankness is the cell's value).
|
|
31
|
+
* ABSENT-vs-omitted — whether the position exists in the call at all — is not a kind; it is
|
|
32
|
+
* `index >= getLength()`.
|
|
33
|
+
*/
|
|
34
|
+
readonly Omitted: "omitted";
|
|
35
|
+
readonly Number: "number";
|
|
36
|
+
readonly String: "string";
|
|
37
|
+
readonly Boolean: "boolean";
|
|
38
|
+
readonly Error: "error";
|
|
39
|
+
readonly RichData: "richData";
|
|
40
|
+
readonly Null: "null";
|
|
41
|
+
};
|
|
42
|
+
export type ValueKind = typeof ValueKind[keyof typeof ValueKind];
|
|
43
|
+
//# sourceMappingURL=ValueKind.d.ts.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Declares that a function's RESULT can change with nothing dirty, so a cell naming it
|
|
3
|
+
* recalculates on every pass.
|
|
4
|
+
*
|
|
5
|
+
* ```ts
|
|
6
|
+
* export function NOW(): Volatile<number> { ... }
|
|
7
|
+
* ```
|
|
8
|
+
*
|
|
9
|
+
* @see {@link IFunction.ReturnTypeJSON.volatile}
|
|
10
|
+
*/
|
|
11
|
+
export type Volatile<T> = T;
|
|
12
|
+
//# sourceMappingURL=Volatile.d.ts.map
|
package/types/src/WildCard.d.ts
CHANGED
|
@@ -10,17 +10,21 @@ export declare const WildCard: {
|
|
|
10
10
|
/**
|
|
11
11
|
* Compiles Excel wildcard text into a regex.
|
|
12
12
|
*
|
|
13
|
-
* @param anchor
|
|
14
|
-
*
|
|
13
|
+
* @param anchor Where the pattern has to line up: `true` for the WHOLE string, `'start'` for a
|
|
14
|
+
* PREFIX, `false` for anywhere in it. Excel matches a whole cell, so every lookup and criteria
|
|
15
|
+
* caller anchors; `SEARCH`, which looks for a substring, does not; and a `D` function's criteria
|
|
16
|
+
* table is the prefix form — `DSUM` with the criterion `appl` takes the row whose value is
|
|
17
|
+
* `Apple`, where `COUNTIF` with the same criterion takes none.
|
|
15
18
|
*
|
|
16
19
|
* @remarks
|
|
17
|
-
* `~` escapes the next `*`, `?` or `~`;
|
|
18
|
-
* "
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
20
|
+
* `~` escapes the next `*`, `?` or `~`; before anything else it is dropped, not kept —
|
|
21
|
+
* `SEARCH("~b","abc")` is 2 and `MATCH("a~b",…)` finds the text `ab`. A caller that reaches this
|
|
22
|
+
* compiler only when the pattern holds a `*` or `?` — which is what COUNTIF and its family do —
|
|
23
|
+
* therefore still compares `"a~b"` literally, because that criteria never becomes a pattern.
|
|
24
|
+
*
|
|
25
|
+
* One left-to-right pass; chained replaces cannot express the escape, since by the time a pass
|
|
26
|
+
* could unescape `~*` the `*` has already become `.*`.
|
|
23
27
|
*/
|
|
24
|
-
toRegex: (lookupText: string, flags?: any, anchor?: boolean) => RegExp;
|
|
28
|
+
toRegex: (lookupText: string, flags?: any, anchor?: boolean | "start") => RegExp;
|
|
25
29
|
};
|
|
26
30
|
//# sourceMappingURL=WildCard.d.ts.map
|
package/types/src/index.d.ts
CHANGED
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
export * from './Scalar';
|
|
2
2
|
export * from './ScalarType';
|
|
3
|
+
export * from './ValueKind';
|
|
3
4
|
export * from './WildCard';
|
|
4
5
|
export * from './Lambda';
|
|
5
6
|
export * from './ErrorPolicy';
|
|
6
7
|
export * from './Repeating';
|
|
7
8
|
export * from './Flatten';
|
|
9
|
+
export * from './NoLift';
|
|
10
|
+
export * from './NoFilter';
|
|
11
|
+
export * from './ReportType';
|
|
8
12
|
export * from './Omittable';
|
|
9
|
-
export * from './
|
|
13
|
+
export * from './Lazy';
|
|
14
|
+
export * from './Volatile';
|
|
10
15
|
export * from './IRange';
|
|
11
16
|
export * from './IReferenceRange';
|
|
12
17
|
export * from './IRichData';
|
package/types/src/Compat.d.ts
DELETED
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The behaviors `@compat` can turn on, and what each one does.
|
|
3
|
-
*
|
|
4
|
-
* @remarks
|
|
5
|
-
* A feature earns a place here only if the BODY cannot do it — the decision happens before the
|
|
6
|
-
* body runs, or instead of running it. Everything a body can decide for itself belongs in the
|
|
7
|
-
* body, where `FormulaContext.getArgs()` and `Omittable` already reach.
|
|
8
|
-
*
|
|
9
|
-
* Function-level until a measurement forces otherwise: `noReferenceLift` is per-function in
|
|
10
|
-
* Excel, and no function is known whose parameters disagree.
|
|
11
|
-
*
|
|
12
|
-
* @see {@link https://www.sheetxl.com/docs/guides/concepts/udf | UDF authoring guide}
|
|
13
|
-
*/
|
|
14
|
-
export declare const CompatFeatures: {
|
|
15
|
-
/**
|
|
16
|
-
* A multi-cell REFERENCE at a non-repeating scalar parameter is `#VALUE!` rather than a
|
|
17
|
-
* broadcast.
|
|
18
|
-
*
|
|
19
|
-
* Excel's Analysis-ToolPak family answers `CUMIPMT(G1:G2,120,100000,13,24,0)` with `#VALUE!`
|
|
20
|
-
* where the native `ROUND(B1:B3,3)` spills three results. A multi-cell reference has no way to
|
|
21
|
-
* become a scalar there, because these functions never intersect. An ARRAY at the same slot
|
|
22
|
-
* still lifts (`MROUND({3,4,5},5)` spills), so the refusal is about references specifically,
|
|
23
|
-
* and a REPEATING slot absorbs a container as members either way (`GCD(C1:C3)` is 4) — so this
|
|
24
|
-
* never applies to one.
|
|
25
|
-
*/
|
|
26
|
-
readonly noReferenceLift: "A multi-cell reference at a non-repeating scalar parameter is #VALUE! rather than a broadcast.";
|
|
27
|
-
/**
|
|
28
|
-
* Members of a REPEATING scalar parameter are coerced rather than filtered: numeric text
|
|
29
|
-
* parses, a blank inside a multi-cell range reads 0, and a boolean or non-numeric text member
|
|
30
|
-
* is `#VALUE!` for the whole call.
|
|
31
|
-
*
|
|
32
|
-
* The native family FILTERS — `SUM({1,"8",TRUE})` is 1, the text and the boolean skipped, and a
|
|
33
|
-
* blank cell contributes nothing. Excel's Analysis-ToolPak family coerces instead:
|
|
34
|
-
* `GCD({6,"8",12})` is 2, `GCD({6,TRUE,12})` is `#VALUE!`, `LCM(6,A1:A2)` over two blank cells
|
|
35
|
-
* is 0. A direct argument follows the same rule (`GCD(6,TRUE,12)` is `#VALUE!` where
|
|
36
|
-
* `SUM(6,TRUE,12)` is 19), and a one-cell blank reference or an omitted argument is still
|
|
37
|
-
* skipped — it never became a member.
|
|
38
|
-
*/
|
|
39
|
-
readonly noMemberFilter: "Members of a repeating scalar parameter are coerced rather than filtered; one that cannot be is #VALUE!.";
|
|
40
|
-
};
|
|
41
|
-
/**
|
|
42
|
-
* One of the {@link CompatFeatures} names.
|
|
43
|
-
*/
|
|
44
|
-
export type CompatFeature = keyof typeof CompatFeatures;
|
|
45
|
-
/**
|
|
46
|
-
* Family aliases: one name an author writes that expands to several {@link CompatFeatures}.
|
|
47
|
-
*
|
|
48
|
-
* @remarks
|
|
49
|
-
* Excel's Analysis-ToolPak heritage is ONE measured rule with two halves that act on disjoint
|
|
50
|
-
* parameter kinds — `noReferenceLift` at a non-repeating scalar slot, `noMemberFilter` at a
|
|
51
|
-
* repeating one — so every function in the family carries the same two bits and `@compat atp`
|
|
52
|
-
* says so in one word. The alias is expanded by the linter; only the atomic features are ever
|
|
53
|
-
* stored, so `@compat atp` and `@compat noReferenceLift noMemberFilter` emit the same declaration.
|
|
54
|
-
* The atomic names stay available for the day a function measures as disagreeing on one half.
|
|
55
|
-
*/
|
|
56
|
-
export declare const CompatAliases: Readonly<Record<string, readonly CompatFeature[]>>;
|
|
57
|
-
/**
|
|
58
|
-
* Resolves a `@compat` name — a feature or a family alias — CASE-INSENSITIVELY, to the canonical
|
|
59
|
-
* features it turns on.
|
|
60
|
-
*
|
|
61
|
-
* @param name The name as the author wrote it.
|
|
62
|
-
* @returns The canonical features, or `null` when no feature or alias goes by that name.
|
|
63
|
-
*/
|
|
64
|
-
export declare function resolveCompatFeatures(name: string): readonly CompatFeature[] | null;
|
|
65
|
-
/**
|
|
66
|
-
* Resolves a `@compat` feature name, CASE-INSENSITIVELY, to its canonical spelling.
|
|
67
|
-
*
|
|
68
|
-
* @param name The name as the author wrote it.
|
|
69
|
-
* @returns The canonical name, or `null` when no feature goes by it.
|
|
70
|
-
*
|
|
71
|
-
* @remarks
|
|
72
|
-
* Authors write `@compat noReferenceLift`; `@Compat NOREFERENCELIFT` means the same thing. Only
|
|
73
|
-
* the canonical spelling is ever stored, so the declaration a build emits does not depend on how
|
|
74
|
-
* the tag was typed.
|
|
75
|
-
*/
|
|
76
|
-
export declare function resolveCompatFeature(name: string): CompatFeature | null;
|
|
77
|
-
//# sourceMappingURL=Compat.d.ts.map
|