@sheetxl/primitives 0.8.0-beta.11 → 0.8.0-beta.13
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/esm/index.mjs +80 -36
- package/node/esm/index.mjs +102 -56
- package/package.json +1 -1
- package/types/src/ErrorPolicy.d.ts +2 -2
- package/types/src/Flatten.d.ts +2 -2
- package/types/src/FormulaContext.d.ts +15 -6
- package/types/src/FormulaError.d.ts +1 -1
- package/types/src/IFormulaContext.d.ts +218 -13
- package/types/src/IFunction.d.ts +13 -44
- package/types/src/IFunctionArguments.d.ts +3 -4
- package/types/src/IRange.d.ts +4 -4
- package/types/src/IRangeStats.d.ts +6 -6
- package/types/src/IRichData.d.ts +33 -10
- package/types/src/IRichType.d.ts +139 -0
- package/types/src/Repeating.d.ts +3 -3
- package/types/src/ReportType.d.ts +2 -2
- package/types/src/Scalar.d.ts +53 -2
- package/types/src/ValueKind.d.ts +2 -2
- package/types/src/WildCard.d.ts +1 -1
- package/types/src/index.d.ts +1 -0
|
@@ -6,6 +6,7 @@ import { IFunction } from './IFunction';
|
|
|
6
6
|
import { IFunctionArguments } from './IFunctionArguments';
|
|
7
7
|
import { IFormulaContext } from './IFormulaContext';
|
|
8
8
|
import { IRuntime } from './IRuntime';
|
|
9
|
+
import { IRichData } from './IRichData';
|
|
9
10
|
import { LocaleProfile } from './LocaleProfile';
|
|
10
11
|
/**
|
|
11
12
|
* Default implementation of the IFormulaContext interface.
|
|
@@ -63,6 +64,8 @@ export declare class StubbedFormulaContext implements IFormulaContext {
|
|
|
63
64
|
getSheetCount(): number | null;
|
|
64
65
|
/** @inheritdoc IFormulaContext.markVolatile */
|
|
65
66
|
markVolatile(): void;
|
|
67
|
+
/** @inheritdoc IFormulaContext.defer */
|
|
68
|
+
defer(_executor: IFormulaContext.DeferExecutor, _payload?: unknown): unknown;
|
|
66
69
|
/** @inheritdoc IFormulaContext.formatResults */
|
|
67
70
|
formatResults(numFmt: string): void;
|
|
68
71
|
/** @inheritdoc IFormulaContext.filterHidden */
|
|
@@ -94,7 +97,7 @@ export declare class StubbedFormulaContext implements IFormulaContext {
|
|
|
94
97
|
* Unimplemented. See {@link IFormulaContext.createGrouping}.
|
|
95
98
|
*
|
|
96
99
|
* @remarks
|
|
97
|
-
* Grouping needs
|
|
100
|
+
* Grouping needs the engine's key equality, which this stub does not have.
|
|
98
101
|
*/
|
|
99
102
|
createGrouping(keys: IRange, options?: IFormulaContext.GroupingOptions): IFormulaContext.Grouping;
|
|
100
103
|
/**
|
|
@@ -112,15 +115,15 @@ export declare class StubbedFormulaContext implements IFormulaContext {
|
|
|
112
115
|
* Renders a scalar as text. See {@link IFormulaContext.toText}.
|
|
113
116
|
*
|
|
114
117
|
* @remarks
|
|
115
|
-
* A BASIC rendering, deliberately NOT
|
|
118
|
+
* A BASIC rendering, deliberately NOT the engine's. The engine's rule -- coercion General (15
|
|
116
119
|
* significant digits, plain decimal while the rendering fits 20 characters, else
|
|
117
120
|
* scientific) written with the workbook LOCALE's decimal separator -- is
|
|
118
121
|
* `formatNumberGeneral` in `@sheetxl/sdk`, and every evaluation path reaches it through
|
|
119
122
|
* the calculation context rather than through this stub. Numbers here get the plain JS
|
|
120
|
-
* rendering, which diverges from
|
|
123
|
+
* rendering, which diverges from the engine on both precision and separator.
|
|
121
124
|
*
|
|
122
125
|
* This exists so authoring, type defs and other non-runtime access get usable text
|
|
123
|
-
* instead of throwing. Anything that needs
|
|
126
|
+
* instead of throwing. Anything that needs the full rule is running in the engine, and
|
|
124
127
|
* the engine never lands here.
|
|
125
128
|
*/
|
|
126
129
|
toText(value: Scalar | undefined): string;
|
|
@@ -128,14 +131,14 @@ export declare class StubbedFormulaContext implements IFormulaContext {
|
|
|
128
131
|
* Orders two scalars. See {@link IFormulaContext.compare}.
|
|
129
132
|
*
|
|
130
133
|
* @remarks
|
|
131
|
-
* A BASIC total order, deliberately NOT
|
|
134
|
+
* A BASIC total order, deliberately NOT the engine's. The engine's rule -- locale collation, the word
|
|
132
135
|
* sort, a blank taking the other operand's type, 11-decimal numeric normalization -- is
|
|
133
136
|
* `ScalarCollation` in `@sheetxl/sdk`, and every evaluation path reaches it through the
|
|
134
137
|
* calculation context rather than through this stub. `options` is ignored: strength is a
|
|
135
138
|
* collation concept and nothing here collates.
|
|
136
139
|
*
|
|
137
140
|
* This exists so authoring, type defs and other non-runtime access get a usable ordering
|
|
138
|
-
* instead of throwing. Anything that needs
|
|
141
|
+
* instead of throwing. Anything that needs the full rule is running in the engine, and the
|
|
139
142
|
* engine never lands here.
|
|
140
143
|
*/
|
|
141
144
|
compare(a: Scalar, b: Scalar, options?: Intl.CollatorOptions): number;
|
|
@@ -143,6 +146,8 @@ export declare class StubbedFormulaContext implements IFormulaContext {
|
|
|
143
146
|
getRuntime(): IRuntime;
|
|
144
147
|
/** @inheritdoc IFormulaContext.getArgs */
|
|
145
148
|
getArgs(): IFunctionArguments;
|
|
149
|
+
/** @inheritdoc IFormulaContext.createRichData */
|
|
150
|
+
createRichData(_type: string, _data?: any): IRichData;
|
|
146
151
|
}
|
|
147
152
|
/**
|
|
148
153
|
* The single, shared {@link IFormulaContext} that formula implementations use (via
|
|
@@ -231,6 +236,8 @@ export declare class ScopedFormulaContext implements IFormulaContext {
|
|
|
231
236
|
getSheetCount(): number | null;
|
|
232
237
|
/** @inheritdoc IFormulaContext.markVolatile */
|
|
233
238
|
markVolatile(): void;
|
|
239
|
+
/** @inheritdoc IFormulaContext.defer */
|
|
240
|
+
defer(executor: IFormulaContext.DeferExecutor, payload?: unknown): unknown;
|
|
234
241
|
/** @inheritdoc IFormulaContext.formatResults */
|
|
235
242
|
formatResults(numFmt: string): void;
|
|
236
243
|
/** @inheritdoc IFormulaContext.filterHidden */
|
|
@@ -245,6 +252,8 @@ export declare class ScopedFormulaContext implements IFormulaContext {
|
|
|
245
252
|
compare(a: Scalar, b: Scalar, options?: Intl.CollatorOptions): number;
|
|
246
253
|
/** @inheritdoc IFormulaContext.getRuntime */
|
|
247
254
|
getRuntime(): IRuntime;
|
|
255
|
+
/** @inheritdoc IFormulaContext.createRichData */
|
|
256
|
+
createRichData(type: string, data?: any): IRichData;
|
|
248
257
|
/** @inheritdoc IFormulaContext.getArgs */
|
|
249
258
|
getArgs(): IFunctionArguments;
|
|
250
259
|
get [Symbol.toStringTag](): string;
|
|
@@ -20,7 +20,7 @@ import { IReferenceRange } from './IReferenceRange';
|
|
|
20
20
|
*
|
|
21
21
|
* SpillErrorScalarSubType | "Unknown" | "Collision" | "IndeterminateSize" | "WorksheetEdge" | "OutOfMemoryWhileCalc" | "Table" | "MergedCell"
|
|
22
22
|
* # Office 2023
|
|
23
|
-
* 10. #CONNECT! This occurs when a data type is used that is not currently supported
|
|
23
|
+
* 10. #CONNECT! This occurs when a data type is used that is not currently supported.
|
|
24
24
|
* 11. #BLOCKED! Indicates that an action or feature is blocked, possibly due to security settings, protected view, or other restrictions. Often related to online features, external links, or macros.
|
|
25
25
|
* 12. #UNKNOWN! May be returned in the case of a protected workbook.
|
|
26
26
|
* 13. #FIELD! Invalid field name for a data type.
|
|
@@ -5,6 +5,7 @@ import { IReferenceRange } from './IReferenceRange';
|
|
|
5
5
|
import { IFunction } from './IFunction';
|
|
6
6
|
import { IFunctionArguments } from './IFunctionArguments';
|
|
7
7
|
import { IRuntime } from './IRuntime';
|
|
8
|
+
import { IRichData } from './IRichData';
|
|
8
9
|
/**
|
|
9
10
|
* Everything a formula function is allowed to know about the world outside its arguments.
|
|
10
11
|
*
|
|
@@ -29,6 +30,7 @@ import { IRuntime } from './IRuntime';
|
|
|
29
30
|
* | Category | Key methods |
|
|
30
31
|
* |---|---|
|
|
31
32
|
* | Evaluation lifecycle | `markVolatile`, `getRow`, `getColumn`, `getEntireCoords`, `getRandom` |
|
|
33
|
+
* | Answering later | `defer` |
|
|
32
34
|
* | Argument reflection | `getArgs` |
|
|
33
35
|
* | Output hints | `formatResults` |
|
|
34
36
|
* | Range construction | `createRange`, `flattenAreas`, `filterHidden` |
|
|
@@ -65,8 +67,8 @@ export interface IFormulaContext {
|
|
|
65
67
|
* A union `(A1:A5,B1:B2)` reaches a {@link IFunction.ParameterTypeJSON.reportType} slot as one
|
|
66
68
|
* `IRange` per area. Functions that answer over it do so because they walk MEMBERS and a union
|
|
67
69
|
* simply has more of them — `LARGE((DA1:DA5,DK1:DK2),2)` is the second largest of all seven
|
|
68
|
-
* cells. This is that walk, and it is a helper rather than a marshalling step on purpose:
|
|
69
|
-
*
|
|
70
|
+
* cells. This is that walk, and it is a helper rather than a marshalling step on purpose:
|
|
71
|
+
* flattening is a shared reducer the bodies opt into, which is why the
|
|
70
72
|
* same union is flattened by `LARGE`, refused by `SUMPRODUCT` and answered `#REF!` by `ROWS`.
|
|
71
73
|
*
|
|
72
74
|
* The result is a single column in area order, row-major within each area. SHAPE IS NOT
|
|
@@ -115,7 +117,7 @@ export interface IFormulaContext {
|
|
|
115
117
|
*/
|
|
116
118
|
getColumn(): number;
|
|
117
119
|
/**
|
|
118
|
-
* Whether the call being evaluated is in
|
|
120
|
+
* Whether the call being evaluated is in VALUE mode, where a multi-cell reference at a
|
|
119
121
|
* slot that reads ONE value is implicitly intersected with the formula's cell (the `@` rule);
|
|
120
122
|
* `false` is ARRAY mode, where such a slot reads the reference's first cell.
|
|
121
123
|
*
|
|
@@ -154,7 +156,7 @@ export interface IFormulaContext {
|
|
|
154
156
|
* A few arguments honor only their top-left corner and are re-sized to the shape of the range
|
|
155
157
|
* that drives them — `SUMIF`'s `sum_range`, `LOOKUP`'s `result_vector`. The window can therefore
|
|
156
158
|
* run off the bottom or right of the grid: `SUMIF(A1:A5,">0",A1048574)` asks for five rows
|
|
157
|
-
* starting three from the end.
|
|
159
|
+
* starting three from the end. The part that fits is read and the rest is blank, which
|
|
158
160
|
* is what this returns; positions past the clamp read as `undefined` from `getValueAt`.
|
|
159
161
|
*
|
|
160
162
|
* @param anchor The coords of the argument as written; only its top-left corner is honored.
|
|
@@ -558,12 +560,11 @@ export interface IFormulaContext {
|
|
|
558
560
|
* want the raw carry above — `DATEDIF("2020-01-31","2020-03-01","md")` is `-1`
|
|
559
561
|
* because Jan 31 rolls into March. `EDATE`/`EOMONTH` want the opposite and CLAMP to
|
|
560
562
|
* the target month's length, so they pre-clamp before calling here. One conversion,
|
|
561
|
-
* two opposite rules
|
|
563
|
+
* two opposite rules. Baking either one in breaks the other.
|
|
562
564
|
* * **Results may legitimately leave the calendar.** `YEARFRAC` basis 1 anchors a year
|
|
563
565
|
* length on January 1 of `laterYear + 1`, which at the top of the calendar is
|
|
564
|
-
* `10000-01-01`;
|
|
565
|
-
* `
|
|
566
|
-
* here would break it.
|
|
566
|
+
* `10000-01-01`; `YEARFRAC(DATE(9998,1,1),DATE(9999,12,31),1)` is
|
|
567
|
+
* `1.9972602739726026`, not `#NUM!`. A range check here would break it.
|
|
567
568
|
* * **The 16-bit argument limits are per-function.** `DATE`'s month errors outside
|
|
568
569
|
* `[-32767, 32766]` while its day saturates to `32767`, and `TIME` errors outside
|
|
569
570
|
* `[0, 32767]` on every argument — same magic number, three different rules.
|
|
@@ -571,8 +572,8 @@ export interface IFormulaContext {
|
|
|
571
572
|
* Note the asymmetry with {@link getDateParts}, which DOES throw `#NUM!` outside the
|
|
572
573
|
* calendar because it answers a user-facing question. An internal intermediate that
|
|
573
574
|
* steps one day past the end must therefore not be round-tripped through it; compute
|
|
574
|
-
* on the fields instead
|
|
575
|
-
*
|
|
575
|
+
* on the fields instead, or `YEARFRAC(DATE(9999,1,1),DATE(9999,12,31),0)` becomes `#NUM!`
|
|
576
|
+
* rather than `1`.
|
|
576
577
|
*/
|
|
577
578
|
getSerialDate(year: number, month: number, day: number, hour?: number, minute?: number, second?: number, millis?: number): number;
|
|
578
579
|
/**
|
|
@@ -588,8 +589,8 @@ export interface IFormulaContext {
|
|
|
588
589
|
*
|
|
589
590
|
* @remarks
|
|
590
591
|
* Argument REFLECTION, for the one thing a declaration cannot say: what happened at *this* call.
|
|
591
|
-
* It exists to serve
|
|
592
|
-
* other
|
|
592
|
+
* It exists to serve a declared `any`, which means "no contract, the body decides" — every
|
|
593
|
+
* other declared type maps onto a type we already have and the marshaller handles it.
|
|
593
594
|
*
|
|
594
595
|
* The returned view is valid ONLY while the body that asked for it is running. Views are pooled
|
|
595
596
|
* by dispatch depth, so retaining one across an `await`, a callback, or a nested evaluation hands
|
|
@@ -598,6 +599,65 @@ export interface IFormulaContext {
|
|
|
598
599
|
* @throws If called outside a function dispatch — there are no arguments to reflect on.
|
|
599
600
|
*/
|
|
600
601
|
getArgs(): IFunctionArguments;
|
|
602
|
+
/**
|
|
603
|
+
* Answers this call later: hands `executor` a call to settle, and leaves the cell showing what
|
|
604
|
+
* the function returns now.
|
|
605
|
+
*
|
|
606
|
+
* @param executor Runs once at the end of the recalculation with every call made against it.
|
|
607
|
+
* Pass a module-level function by name: calls join one batch when they name the same function.
|
|
608
|
+
* @param payload Everything the executor needs to answer this call, and how a later evaluation
|
|
609
|
+
* recognizes it: while the call is still waiting, a recalculation with
|
|
610
|
+
* an equal payload leaves it be rather than asking again. Once it has stopped, a recalculation
|
|
611
|
+
* calls the function again; what it fetched is answered from the workbook's cache
|
|
612
|
+
* (`IDeferContext.fetch`).
|
|
613
|
+
* @returns The last answer this call gave for the same question, when the function is being
|
|
614
|
+
* called again (a recalculation); `undefined` on a first call or a changed question. Return it
|
|
615
|
+
* to keep showing it until the new answer arrives, or return something else to show that the
|
|
616
|
+
* cell is waiting.
|
|
617
|
+
*
|
|
618
|
+
* @remarks
|
|
619
|
+
* The function still returns a value: what this call answers until its result arrives (nothing
|
|
620
|
+
* returned reads as blank), and it is what every formula over the cell calculates
|
|
621
|
+
* from meanwhile: return `#BUSY!` when they should wait as an error, or text such as
|
|
622
|
+
* `'Fetching…'` when that is what they should show.
|
|
623
|
+
*
|
|
624
|
+
* The executor runs after the recalculation, outside any cell, so the ambient `FormulaContext`
|
|
625
|
+
* is not its own: it reads the workbook through `ctx.getFormulaContext()`. Whatever the body
|
|
626
|
+
* knows about its cell goes in the payload.
|
|
627
|
+
*
|
|
628
|
+
* @example
|
|
629
|
+
* ```typescript
|
|
630
|
+
* function fetchAll(
|
|
631
|
+
* calls: readonly IFormulaContext.DeferredCall<string>[],
|
|
632
|
+
* ctx: IFormulaContext.IDeferContext
|
|
633
|
+
* ): void {
|
|
634
|
+
* for (const call of calls) {
|
|
635
|
+
* ctx.fetch(call.payload as string)
|
|
636
|
+
* .then((response) => response.text())
|
|
637
|
+
* .then((text) => call.resolve(text), (error) => call.reject(error));
|
|
638
|
+
* }
|
|
639
|
+
* }
|
|
640
|
+
*
|
|
641
|
+
* export function FETCHTEXT(url: string): string {
|
|
642
|
+
* FormulaContext.defer(fetchAll, url);
|
|
643
|
+
* return 'Fetching…';
|
|
644
|
+
* }
|
|
645
|
+
* ```
|
|
646
|
+
*/
|
|
647
|
+
defer(executor: IFormulaContext.DeferExecutor, payload?: unknown): unknown;
|
|
648
|
+
/**
|
|
649
|
+
* A rich value of a registered type, made from its data as the type's JSON holds it, for the
|
|
650
|
+
* workbook being calculated.
|
|
651
|
+
*
|
|
652
|
+
* @param type The name of the value's kind (`'hyperlink'`): what its `getKind().getName()`
|
|
653
|
+
* will answer.
|
|
654
|
+
* @param data The value's data, as its JSON's `data`.
|
|
655
|
+
*
|
|
656
|
+
* @remarks
|
|
657
|
+
* A type nobody has registered still makes a value: one that carries the data and reads as
|
|
658
|
+
* nothing.
|
|
659
|
+
*/
|
|
660
|
+
createRichData(type: string, data?: any): IRichData;
|
|
601
661
|
}
|
|
602
662
|
/**
|
|
603
663
|
* {@inheritDoc IFormulaContext}
|
|
@@ -623,7 +683,7 @@ export declare namespace IFormulaContext {
|
|
|
623
683
|
* then `range` is returned as it is, hidden rows included.
|
|
624
684
|
*
|
|
625
685
|
* @remarks
|
|
626
|
-
* This is `SUBTOTAL` 1-11 (
|
|
686
|
+
* This is `SUBTOTAL` 1-11 (they include manually hidden rows, which is what an
|
|
627
687
|
* unfiltered sheet reads as). `SUBTOTAL` 101-111 and `AGGREGATE` leave it off and skip
|
|
628
688
|
* always.
|
|
629
689
|
* @defaultValue false
|
|
@@ -748,5 +808,150 @@ export declare namespace IFormulaContext {
|
|
|
748
808
|
*/
|
|
749
809
|
readonly dow: number;
|
|
750
810
|
}
|
|
811
|
+
/**
|
|
812
|
+
* Answers the calls made by {@link IFormulaContext.defer} against it. Invoked once at the end of
|
|
813
|
+
* a recalculation with every such call; how many requests that becomes is the executor's choice.
|
|
814
|
+
*/
|
|
815
|
+
type DeferExecutor<T = any> = (calls: readonly DeferredCall<T>[], ctx: IDeferContext) => void | Promise<void>;
|
|
816
|
+
/**
|
|
817
|
+
* One call made by {@link IFormulaContext.defer}, as its executor receives it.
|
|
818
|
+
*
|
|
819
|
+
* @remarks
|
|
820
|
+
* Settle each call itself, never by its position in a response. An executor that returns a
|
|
821
|
+
* promise which rejects fails every call it has not settled.
|
|
822
|
+
*/
|
|
823
|
+
interface DeferredCall<T = any> {
|
|
824
|
+
/** What the function passed to `defer`. */
|
|
825
|
+
readonly payload: unknown;
|
|
826
|
+
/** Settles the call with its result. */
|
|
827
|
+
resolve(value: T, options?: DeferredCall.ResolveOptions): void;
|
|
828
|
+
/** Settles the call with an error: a `FormulaError` as itself, anything else as `#VALUE!`. */
|
|
829
|
+
reject(error: unknown): void;
|
|
830
|
+
/** Runs `fn` when the result is no longer wanted. */
|
|
831
|
+
onCancel(fn: () => void): void;
|
|
832
|
+
/**
|
|
833
|
+
* Whether the result is no longer wanted. Only an executor that holds calls to settle later
|
|
834
|
+
* needs it; a result for a cancelled call is dropped.
|
|
835
|
+
*/
|
|
836
|
+
readonly cancelled: boolean;
|
|
837
|
+
}
|
|
838
|
+
namespace DeferredCall {
|
|
839
|
+
/**
|
|
840
|
+
* Options for {@link DeferredCall.resolve}.
|
|
841
|
+
*/
|
|
842
|
+
interface ResolveOptions {
|
|
843
|
+
/**
|
|
844
|
+
* Whether the blanks of an array result stay blank when it spills. Omitted, they read as
|
|
845
|
+
* `0`, as any spilled array's blanks do.
|
|
846
|
+
*
|
|
847
|
+
* @remarks
|
|
848
|
+
* For data whose empty fields mean "nothing here", such as an imported file. The result
|
|
849
|
+
* keeps them while a formula passes it on as it is (`IF(c, result, …)`). A function that
|
|
850
|
+
* answers element by element builds a new array, whose blanks read as `0`
|
|
851
|
+
* (`IFERROR(result, …)`, `result & ""`).
|
|
852
|
+
* @defaultValue false
|
|
853
|
+
*/
|
|
854
|
+
keepBlanks?: boolean;
|
|
855
|
+
}
|
|
856
|
+
}
|
|
857
|
+
/**
|
|
858
|
+
* What an executor is given beside its calls.
|
|
859
|
+
*/
|
|
860
|
+
interface IDeferContext {
|
|
861
|
+
/** A random number in `[0, 1)` from the calculation's source, which a test can seed. */
|
|
862
|
+
getRandom(): number;
|
|
863
|
+
/**
|
|
864
|
+
* State kept for this executor across recalculations, made by `init` on first ask. Keep data
|
|
865
|
+
* here (maps, numbers, strings, buffers), not connections or sockets.
|
|
866
|
+
*/
|
|
867
|
+
getState<S>(init: () => S): S;
|
|
868
|
+
/**
|
|
869
|
+
* Groups `calls` by payload and runs `answer` once per distinct payload with every call that
|
|
870
|
+
* asked it: one request per question, however many cells asked.
|
|
871
|
+
*
|
|
872
|
+
* @param calls The calls to group, usually every call the executor was handed.
|
|
873
|
+
* @param answer Settles one group. When it throws, or the promise it returns rejects, the
|
|
874
|
+
* group's calls it has not settled fail with that error; the other groups are not affected.
|
|
875
|
+
* @returns Resolves once every group has been answered. It never rejects.
|
|
876
|
+
*
|
|
877
|
+
* @remarks
|
|
878
|
+
* Payloads are equal as `defer` compares them: the same primitive, or plain objects or arrays
|
|
879
|
+
* whose own values are the same one level deep. Groups are answered concurrently, in the
|
|
880
|
+
* order their first call appears.
|
|
881
|
+
*
|
|
882
|
+
* @example
|
|
883
|
+
* ```typescript
|
|
884
|
+
* async function fetchQuotes(
|
|
885
|
+
* calls: readonly IFormulaContext.DeferredCall<number>[],
|
|
886
|
+
* ctx: IFormulaContext.IDeferContext
|
|
887
|
+
* ): Promise<void> {
|
|
888
|
+
* await ctx.byPayload(calls, async (ticker: string, group) => {
|
|
889
|
+
* const response = await ctx.fetch(`https://api.example.com/quote/${ticker}`);
|
|
890
|
+
* const price: number = (await response.json()).price;
|
|
891
|
+
* for (const call of group) call.resolve(price);
|
|
892
|
+
* });
|
|
893
|
+
* }
|
|
894
|
+
* ```
|
|
895
|
+
*/
|
|
896
|
+
byPayload<T = any, P = unknown>(calls: readonly DeferredCall<T>[], answer: (payload: P, group: readonly DeferredCall<T>[]) => void | Promise<void>): Promise<void>;
|
|
897
|
+
/**
|
|
898
|
+
* A rich value of a registered type, for the workbook being calculated: what
|
|
899
|
+
* {@link IFormulaContext.createRichData} makes inside a cell, made here for a call's result.
|
|
900
|
+
*/
|
|
901
|
+
createRichData(type: string, data?: any): IRichData;
|
|
902
|
+
/**
|
|
903
|
+
* Adds bytes to the workbook being calculated as a resource (an `IResource`), for a rich value
|
|
904
|
+
* to hold: pass it in {@link createRichData}'s data. The workbook saves it while a value holds
|
|
905
|
+
* it. With `fetchedFrom` it is the workbook's copy of that URL: {@link fetch} answers the URL
|
|
906
|
+
* from it, and adding the same URL again answers the resource already added.
|
|
907
|
+
*/
|
|
908
|
+
addResource(buffer: ArrayBuffer, options?: {
|
|
909
|
+
fetchedFrom?: string;
|
|
910
|
+
}): object;
|
|
911
|
+
/**
|
|
912
|
+
* Fetches through the workbook being calculated: the standard `fetch`, answered by the
|
|
913
|
+
* fetchers the host registered for the URL's scheme, with the host's authentication. An
|
|
914
|
+
* answer the workbook already has for the URL (a picture it keeps, or anything fetched while
|
|
915
|
+
* it is open) answers from the workbook, and two calls for one URL share one request. In an
|
|
916
|
+
* external calculation (*Refresh All*) it goes to the source.
|
|
917
|
+
*
|
|
918
|
+
* Rejects when the URL cannot be reached, with a `FormulaError.Blocked` when the site responded
|
|
919
|
+
* but the browser would not let the page read it.
|
|
920
|
+
*/
|
|
921
|
+
fetch(input: string, init?: RequestInit): Promise<Response>;
|
|
922
|
+
/**
|
|
923
|
+
* The formula context of the workbook being calculated, with no cell: its parsing, text,
|
|
924
|
+
* comparison and dates, read with the workbook's locale and date system.
|
|
925
|
+
*
|
|
926
|
+
* @remarks
|
|
927
|
+
* Valid for as long as the executor runs, across every `await`. The ambient `FormulaContext`
|
|
928
|
+
* is not: it belongs to the cell being evaluated, and an executor runs after that evaluation
|
|
929
|
+
* ends. What needs a cell (`getRow`, `getReference`, `getValueAt`, `defer`, `markVolatile`,
|
|
930
|
+
* `formatResults`, `getRandom`) throws here; {@link getRandom} is the executor's own.
|
|
931
|
+
*/
|
|
932
|
+
getFormulaContext(): IFormulaContext;
|
|
933
|
+
/**
|
|
934
|
+
* Reads delimited text (CSV, TSV) into rows of values, each field read the way the workbook
|
|
935
|
+
* reads typed entry: numbers, dates, booleans and error labels become values, anything else
|
|
936
|
+
* stays text, and an empty field is blank.
|
|
937
|
+
*
|
|
938
|
+
* @param text The delimited text.
|
|
939
|
+
* @param options How the text is split.
|
|
940
|
+
* @returns The rows, padded with blanks to the widest row.
|
|
941
|
+
*/
|
|
942
|
+
parseText(text: string, options?: IDeferContext.ParseTextOptions): Promise<Scalar[][]>;
|
|
943
|
+
}
|
|
944
|
+
namespace IDeferContext {
|
|
945
|
+
/**
|
|
946
|
+
* Options for {@link IDeferContext.parseText}.
|
|
947
|
+
*/
|
|
948
|
+
interface ParseTextOptions {
|
|
949
|
+
/**
|
|
950
|
+
* The character between fields.
|
|
951
|
+
* @defaultValue `','`
|
|
952
|
+
*/
|
|
953
|
+
delimiter?: string;
|
|
954
|
+
}
|
|
955
|
+
}
|
|
751
956
|
}
|
|
752
957
|
//# sourceMappingURL=IFormulaContext.d.ts.map
|
package/types/src/IFunction.d.ts
CHANGED
|
@@ -284,11 +284,9 @@ export declare namespace IFunction {
|
|
|
284
284
|
getMembers(): readonly IFunction.IEnumMember[];
|
|
285
285
|
}
|
|
286
286
|
/**
|
|
287
|
-
* Describes the runtime return behavior of a function, including modifiers like
|
|
288
|
-
* async resolution, streaming data, or volatility.
|
|
287
|
+
* Describes the runtime return behavior of a function, including modifiers like volatility.
|
|
289
288
|
*
|
|
290
289
|
* @remarks
|
|
291
|
-
* All return type modifiers are mutually exclusive.
|
|
292
290
|
* If none are specified, The value will be returned with no special behavior.
|
|
293
291
|
*/
|
|
294
292
|
interface IReturnType extends IValueType {
|
|
@@ -300,26 +298,13 @@ export declare namespace IFunction {
|
|
|
300
298
|
* @see {@link ReturnTypeJSON.kind}
|
|
301
299
|
*/
|
|
302
300
|
getKind(): ValueKind | null;
|
|
303
|
-
/**
|
|
304
|
-
* Indicates the return value is a Promise or Promise-like (i.e., async).
|
|
305
|
-
* The system will mark the result as pending and re-trigger evaluation once resolved.
|
|
306
|
-
*
|
|
307
|
-
* Can be combined with any scalar, array, or range return type.
|
|
308
|
-
*/
|
|
309
|
-
isAsync(): boolean;
|
|
310
|
-
/**
|
|
311
|
-
* Indicates whether the function produces a continuous stream of output (e.g., real-time data).
|
|
312
|
-
*
|
|
313
|
-
* @defaultValue `false`
|
|
314
|
-
*/
|
|
315
|
-
isStreaming(): boolean;
|
|
316
301
|
/**
|
|
317
302
|
* True when the result can change with nothing dirty, so a cell naming this function
|
|
318
303
|
* recalculates on every pass — the `Volatile<T>` marker.
|
|
319
304
|
*
|
|
320
305
|
* @remarks
|
|
321
306
|
* STATIC, and read from the formula text at compile time: it is true of the call whether or
|
|
322
|
-
* not the call runs, which is what a lazy argument
|
|
307
|
+
* not the call runs, which is what a lazy argument requires.
|
|
323
308
|
*
|
|
324
309
|
* @see {@link ReturnTypeJSON.volatile}
|
|
325
310
|
*/
|
|
@@ -358,7 +343,7 @@ export declare namespace IFunction {
|
|
|
358
343
|
* @remarks
|
|
359
344
|
* Only meaningful for a VARIADIC function; a fixed parameter list is already its own maximum.
|
|
360
345
|
* The number is the whole CALL's argument count, prefix and optional suffix included, and it
|
|
361
|
-
* is refused
|
|
346
|
+
* is refused at entry, before evaluation.
|
|
362
347
|
*
|
|
363
348
|
* @see {@link Repeating}
|
|
364
349
|
*/
|
|
@@ -660,8 +645,8 @@ export declare namespace IFunction {
|
|
|
660
645
|
* Generated from the `NoLift<T>` marker.
|
|
661
646
|
*
|
|
662
647
|
* @remarks
|
|
663
|
-
* Per parameter, because Excel
|
|
664
|
-
* and lifts one at `weekend`. An ARRAY at the slot still lifts, a one-cell reference is an
|
|
648
|
+
* Per parameter, because Excel's built-ins differ by slot: `NETWORKDAYS.INTL` refuses a
|
|
649
|
+
* reference at its date slots and lifts one at `weekend`. An ARRAY at the slot still lifts, a one-cell reference is an
|
|
665
650
|
* ordinary argument, and a repeating slot absorbs a container as members, so the marker only
|
|
666
651
|
* ever applies to a non-repeating scalar parameter.
|
|
667
652
|
*/
|
|
@@ -701,7 +686,7 @@ export declare namespace IFunction {
|
|
|
701
686
|
* union is the range arm, handed over whole. The slot never lifts.
|
|
702
687
|
*
|
|
703
688
|
* @remarks
|
|
704
|
-
*
|
|
689
|
+
* Some array slots read a one-cell argument as THE ARGUMENT rather than as a
|
|
705
690
|
* one-cell container: `SORT(<#N/A cell>,1,1,<#DIV/0! cell>)` is `#N/A` where
|
|
706
691
|
* `TAKE(<#N/A cell>,<#DIV/0! cell>)` is `#DIV/0!`. The engine's default
|
|
707
692
|
* for a range slot is TAKE's; this flag is SORT's. {@link scalar} and {@link range} each carry
|
|
@@ -738,8 +723,7 @@ export declare namespace IFunction {
|
|
|
738
723
|
members: [name: string, value: number | string, deprecated?: string | true][];
|
|
739
724
|
}
|
|
740
725
|
/**
|
|
741
|
-
* Describes the runtime return behavior of a function, including modifiers like
|
|
742
|
-
* async resolution, streaming data, or volatility.
|
|
726
|
+
* Describes the runtime return behavior of a function, including modifiers like volatility.
|
|
743
727
|
*
|
|
744
728
|
* @remarks
|
|
745
729
|
* If none are specified, The value will be returned with no special behavior.
|
|
@@ -763,29 +747,15 @@ export declare namespace IFunction {
|
|
|
763
747
|
* is a scalar is its member value downstream.
|
|
764
748
|
*/
|
|
765
749
|
kind?: ValueKind;
|
|
766
|
-
/**
|
|
767
|
-
* Indicates the return value is a Promise or Promise-like (i.e., async).
|
|
768
|
-
* The system will mark the result as pending and re-trigger evaluation once resolved.
|
|
769
|
-
*
|
|
770
|
-
* Can be combined with any scalar, array, or range return type.
|
|
771
|
-
*/
|
|
772
|
-
async?: boolean;
|
|
773
|
-
/**
|
|
774
|
-
* Indicates whether the function produces a continuous stream of output (e.g., real-time data).
|
|
775
|
-
*
|
|
776
|
-
* @defaultValue `false`
|
|
777
|
-
*/
|
|
778
|
-
stream?: boolean;
|
|
779
750
|
/**
|
|
780
751
|
* The result can change with nothing dirty — a cell naming this function recalculates on
|
|
781
752
|
* every pass. Generated from the `Volatile<T>` marker.
|
|
782
753
|
*
|
|
783
754
|
* @remarks
|
|
784
755
|
* Collected at COMPILE time from the formula text (`CompiledFormula.hasVolatile`), because
|
|
785
|
-
* that is where
|
|
756
|
+
* that is where volatility is decided: `=IF(TRUE,1,RAND())` recalculates on every idle pass though
|
|
786
757
|
* no branch selects the arm, and with lazy arguments the call never happens for the engine to
|
|
787
|
-
* observe.
|
|
788
|
-
* result arrives rather than what it is.
|
|
758
|
+
* observe.
|
|
789
759
|
*
|
|
790
760
|
* @see {@link Volatile}
|
|
791
761
|
*/
|
|
@@ -806,11 +776,10 @@ export declare namespace IFunction {
|
|
|
806
776
|
* parameter. Omitted at the default of 255.
|
|
807
777
|
*
|
|
808
778
|
* @remarks
|
|
809
|
-
*
|
|
810
|
-
*
|
|
811
|
-
*
|
|
812
|
-
*
|
|
813
|
-
* takes 254.
|
|
779
|
+
* The cap is one number per NAME, compared against the whole call's argument count, so a call
|
|
780
|
+
* past it is refused AT ENTRY rather than answered — which is why the cap lives on the
|
|
781
|
+
* declaration and not in a body. It is not derivable from the shape: in Excel `STDEV` takes 255
|
|
782
|
+
* arguments and `STDEV.S`, the same function under its dotted name, takes 254.
|
|
814
783
|
*
|
|
815
784
|
* @defaultValue 255
|
|
816
785
|
*/
|
|
@@ -15,9 +15,8 @@ import { IFunction } from './IFunction';
|
|
|
15
15
|
* - What was the value BEFORE the parameter's type coerced it?
|
|
16
16
|
* - Was that empty slot an omission, or a blank cell the caller pointed at?
|
|
17
17
|
*
|
|
18
|
-
*
|
|
19
|
-
* parameters
|
|
20
|
-
* declined to express one. `CUMIPMT` refuses a boolean at every slot while `FV` coerces one at
|
|
18
|
+
* Some functions have behaviors that turn on exactly those questions, and they cluster at
|
|
19
|
+
* parameters declared `any` — where there is nothing to express as a type. `CUMIPMT` refuses a boolean at every slot while `FV` coerces one at
|
|
21
20
|
* every slot; the difference is not the values, it is that `CUMIPMT`'s slots are `any` and its
|
|
22
21
|
* body decides.
|
|
23
22
|
*
|
|
@@ -142,7 +141,7 @@ export interface IFunctionArguments {
|
|
|
142
141
|
*/
|
|
143
142
|
getKindAt(index: number): ValueKind;
|
|
144
143
|
/**
|
|
145
|
-
* True when the argument at `index` is DIRECT —
|
|
144
|
+
* True when the argument at `index` is DIRECT — typed into the list of arguments:
|
|
146
145
|
* the evaluated value IS a value, not a container or a callable.
|
|
147
146
|
*
|
|
148
147
|
* @param index The PARAMETER index — the position in the body's own signature.
|
package/types/src/IRange.d.ts
CHANGED
|
@@ -255,7 +255,7 @@ export interface IRange<T extends Scalar = Scalar> {
|
|
|
255
255
|
* @remarks
|
|
256
256
|
* Errors INSIDE a range are the body's to judge: the engine hands a valid range over whole and
|
|
257
257
|
* never looks inside, so a function whose answer depends on every member says so with this
|
|
258
|
-
* line, placed before its own validation where
|
|
258
|
+
* line, placed before its own validation where the member's error outranks it. A reshaper or a
|
|
259
259
|
* lookup, whose members pass through or are never read, needs no line at all.
|
|
260
260
|
*/
|
|
261
261
|
firstError(): FormulaError.Known | null;
|
|
@@ -268,7 +268,7 @@ export interface IRange<T extends Scalar = Scalar> {
|
|
|
268
268
|
* @remarks
|
|
269
269
|
* `options.axis` is the TRAVERSAL order feeding the ordinal, not the orientation of the result:
|
|
270
270
|
* the result is always Nx1, and a row is `flatten().transpose()`. The default is row-major,
|
|
271
|
-
* which is the order
|
|
271
|
+
* which is the order two range operands pair in.
|
|
272
272
|
*
|
|
273
273
|
* `options.type` carries a read type onto the result, so a member the type filters out becomes
|
|
274
274
|
* a HOLE at its ordinal rather than compacting the column. That is what lets two operands be
|
|
@@ -916,7 +916,7 @@ export declare namespace IRange {
|
|
|
916
916
|
*
|
|
917
917
|
* - By default, `broadcast()` follows strict alignment rules like NumPy and will
|
|
918
918
|
* throw an error if the input ranges cannot be broadcasted together.
|
|
919
|
-
* - When `misalignValue` is provided, `broadcast()` will instead
|
|
919
|
+
* - When `misalignValue` is provided, `broadcast()` will instead follow Excel's behavior:
|
|
920
920
|
* - It finds the **largest valid intersection** of the ranges.
|
|
921
921
|
* - It expands the result to the **union of both range sizes**.
|
|
922
922
|
* - Any cells that do not have valid corresponding values from the inputs
|
|
@@ -974,7 +974,7 @@ export declare namespace IRange {
|
|
|
974
974
|
*
|
|
975
975
|
* @remarks
|
|
976
976
|
* Off, a dimension of 1 is a short dimension like any other and pads `misalignValue` past
|
|
977
|
-
* its one position:
|
|
977
|
+
* its one position: the `MAP` rule, where a 1-row array is not stretched.
|
|
978
978
|
*/
|
|
979
979
|
tile?: boolean;
|
|
980
980
|
/**
|
|
@@ -71,7 +71,7 @@ export interface IRangeStats {
|
|
|
71
71
|
*/
|
|
72
72
|
getAggregates(options?: IRange.IteratorOptions): Readonly<IRangeStats.Aggregates>;
|
|
73
73
|
/**
|
|
74
|
-
* Returns the sum as
|
|
74
|
+
* Returns the sum as `SUM` reports it — {@link getAggregates}'s `sum` with Excel's
|
|
75
75
|
* cancellation-to-zero rule applied.
|
|
76
76
|
*
|
|
77
77
|
* @param total A total the caller accumulated across SEVERAL stats instances. Omit for a
|
|
@@ -82,7 +82,7 @@ export interface IRangeStats {
|
|
|
82
82
|
* @remarks
|
|
83
83
|
* Collapses a total to exactly zero when it lands at least 50 binary exponents below the
|
|
84
84
|
* operands that produced it, so `SUM(0.1,0.2,-0.3)` is `0` rather than `5.55111512312578E-17`.
|
|
85
|
-
* Use this wherever you mean "the number
|
|
85
|
+
* Use this wherever you mean "the number SUM shows" — a status bar, a report
|
|
86
86
|
* total, a formula. Use `getAggregates().sum` where you mean the true total of the data.
|
|
87
87
|
*
|
|
88
88
|
* The two genuinely differ, and neither is a rounding of the other:
|
|
@@ -92,12 +92,12 @@ export interface IRangeStats {
|
|
|
92
92
|
* and `PERCENTOF`, and to NOTHING else — `SUMIF`, `SUMPRODUCT`, `SERIESSUM`, `DSUM`, the
|
|
93
93
|
* `SUMX2MY2` family and every binary operator all keep the residue over the same values.
|
|
94
94
|
* That is why this is a method you call and not a change to `getAggregates`.
|
|
95
|
-
* - `AVERAGE` divides THIS, not the raw sum: snapping the mean instead is
|
|
95
|
+
* - `AVERAGE` divides THIS, not the raw sum: snapping the mean instead is wrong.
|
|
96
96
|
*
|
|
97
97
|
* It is also cheap when it does not fire: a bound derived from `min`/`max` rejects any
|
|
98
98
|
* ordinary total without re-reading the range.
|
|
99
99
|
*
|
|
100
|
-
* **Multiple ranges.**
|
|
100
|
+
* **Multiple ranges.** The rule applies on the *final* accumulation step, so a total
|
|
101
101
|
* spanning several ranges must be judged against the range holding the LAST value — pass the
|
|
102
102
|
* running total as `total` and call this on that range. (Snapping each range separately gets
|
|
103
103
|
* `SUM(A1:A3,0)` and `SUM(A1:A1,A2:A2,A3:A3)` wrong in opposite directions.) A composite
|
|
@@ -245,7 +245,7 @@ export declare namespace IRangeStats {
|
|
|
245
245
|
* Sorting requires materializing the full numeric population (O(n log n), one allocation).
|
|
246
246
|
* Unlike `Aggregates`, sorted views are **not composable across sub-ranges**.
|
|
247
247
|
*
|
|
248
|
-
* Covers the following
|
|
248
|
+
* Covers the following functions (all share one sort per coords per calc cycle):
|
|
249
249
|
* - `LARGE`, `SMALL`
|
|
250
250
|
* - `MEDIAN`, `PERCENTILE`, `PERCENTILE.INC`, `PERCENTILE.EXC`
|
|
251
251
|
* - `QUARTILE`, `QUARTILE.INC`, `QUARTILE.EXC` (q1 = k=0.25, q3 = k=0.75)
|
|
@@ -310,7 +310,7 @@ export declare namespace IRangeStats {
|
|
|
310
310
|
* one outside the population is not found.
|
|
311
311
|
* @param exclusive If true, uses exclusive formula (0 and 1 are excluded).
|
|
312
312
|
* @param significance Number of DECIMAL PLACES to TRUNCATE the result to — despite what
|
|
313
|
-
* Excel's
|
|
313
|
+
* Excel's help calls the argument, it is not significant digits and it does not round.
|
|
314
314
|
* Truncated toward zero first (1.9 places means 1), and must be at least 1. Omit it for the
|
|
315
315
|
* exact untruncated rank, which is also the only form that cannot fail.
|
|
316
316
|
* @returns The percent rank of x; `null` if x is not found or there are no numbers in range.
|