@sheetxl/sdk 0.7.28-beta.3 → 0.7.28-beta.4
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/{D6cjnwWR_iUSe1f6.cjs → BF14ZEAnaqxXroSj.cjs} +1 -1
- package/browser/cjs/{CWCKcp58KidyndaL.cjs → BXtvdT1Z-MsB_o5F.cjs} +1 -1
- package/browser/cjs/Bc4JjVVZfFo3R4He.cjs +33 -0
- package/browser/cjs/{BX6A6xGDOr_td9mw.cjs → CD2RXdnfqSYNc6gX.cjs} +1 -1
- package/browser/cjs/{B4PKKgaDTG9aSO-f.cjs → DcLpXGexEtOxi-dD.cjs} +1 -1
- package/browser/cjs/index.cjs +2 -2
- package/browser/esm/{CX1NO_a1QPjXDvTU.mjs → 0Mj5WKM362q6CECb.mjs} +3 -3
- package/browser/esm/{Rj8e7SashcMlcdZJ.mjs → CHSahmMFYNB0Ajkf.mjs} +2 -2
- package/browser/esm/{B1gpnr-7kLU7jTy-.mjs → CKk58ZLcrllMzfou.mjs} +2 -2
- package/browser/esm/{CPgz9_iM7xyAcytg.mjs → CPTtL2f6_4iblmFM.mjs} +2 -2
- package/browser/esm/{Dv8FyXyeygJPXoHo.mjs → CoA-sUxjiIUIpTUF.mjs} +2 -2
- package/browser/esm/{DZfds6s3ayTZrozO.mjs → DBIu6NUHIcxOOBQp.mjs} +1 -1
- package/browser/esm/{C78IaCXqwCcraBPe.mjs → Dy4Sdpju1T2icURu.mjs} +6266 -5497
- package/browser/esm/index.mjs +17 -14
- package/node/esm/{BkY99r-c3BhlT_Kv.mjs → BtGxbEbBm79YvF_k.mjs} +1 -1
- package/node/esm/{DE3eIaqkk5xzmV1c.mjs → DUYP6faJJHCaW1Xf.mjs} +1 -1
- package/node/esm/{8VtzCFSmLPKxJjOa.mjs → DqgWsVXROpSgKq6c.mjs} +1 -1
- package/node/esm/index.mjs +8589 -7804
- package/package.json +6 -6
- package/types/scripting-enums.json +2 -0
- package/types/scripting.d.ts +265 -8
- package/types/src/anchored/IAnchored.d.ts +27 -0
- package/types/src/calculation/Calculation.d.ts +21 -12
- package/types/src/calculation/ICalculation.d.ts +178 -0
- package/types/src/calculation/executor/CalcExecutor.d.ts +204 -13
- package/types/src/calculation/executor/CalcExecutorUtils.d.ts +31 -0
- package/types/src/calculation/executor/CircularReference.d.ts +81 -0
- package/types/src/calculation/grid/CalcGrid.d.ts +3 -1
- package/types/src/calculation/grid/CalcGridUtils.d.ts +3 -2
- package/types/src/calculation/grid/ICalcGrid.d.ts +12 -1
- package/types/src/calculation/spatial/CircularEntry.d.ts +18 -0
- package/types/src/calculation/spatial/index.d.ts +1 -0
- package/types/src/calculation/state/CalcNode.d.ts +24 -17
- package/types/src/calculation/state/CalcState.d.ts +78 -15
- package/types/src/calculation/state/CalculationContext.d.ts +39 -0
- package/types/src/calculation/state/_ReadObservedGrid.d.ts +90 -0
- package/types/src/cell/ICell.d.ts +16 -0
- package/types/src/cellRange/ICellRange.d.ts +12 -3
- package/types/src/condition/AnchoredConditional.d.ts +26 -6
- package/types/src/conditionalFormat/ConditionalFormat.d.ts +8 -1
- package/types/src/conditionalFormat/IConditionalFormat.d.ts +4 -1
- package/types/src/conditionalFormat/IConditionalFormatCollection.d.ts +6 -2
- package/types/src/dataValidation/IDataValidationCollection.d.ts +6 -2
- package/types/src/hyperlink/IHyperlink.d.ts +3 -1
- package/types/src/hyperlink/_Hyperlink.d.ts +6 -0
- package/types/src/lib/utils/utils.browser.d.ts +5 -0
- package/types/src/license/LicenseDetails.d.ts +5 -0
- package/types/src/primitives/CalcSignal.d.ts +20 -0
- package/types/src/protectedRange/IProtectedRangeCollection.d.ts +7 -2
- package/types/src/scripting/_ScriptUtils.d.ts +13 -0
- package/types/src/sheet/Sheet.d.ts +33 -2
- package/types/src/sheet/SheetCell.d.ts +2 -0
- package/types/src/sheet/_SheetStateTypes.d.ts +14 -1
- package/types/src/style/IStyle.d.ts +5 -0
- package/types/src/table/AnchoredTable.d.ts +17 -1
- package/types/src/text/TextUtils.d.ts +18 -0
- package/browser/cjs/1mH2uhx_Dmceu88H.cjs +0 -33
|
@@ -77,6 +77,63 @@ export interface ICalculation extends IModel {
|
|
|
77
77
|
* This is similar convenience method for `getCalculation().createFormula(expression).evaluate(options)`.
|
|
78
78
|
*/
|
|
79
79
|
evaluate(expression: string, options?: number | ICalculation.EvaluateOptions & Partial<IRange.CellCoords>): Promise<Scalar | IRange>;
|
|
80
|
+
/**
|
|
81
|
+
* When the engine recalculates on its own — Excel's Calculation Options.
|
|
82
|
+
*
|
|
83
|
+
* @remarks
|
|
84
|
+
* In {@link ICalculation.CalculationMode.Automatic} every commit that dirties a formula
|
|
85
|
+
* schedules a pass. In {@link ICalculation.CalculationMode.Manual} an edit only marks its
|
|
86
|
+
* dependents out of date ({@link isCalculationRequired}) and nothing is recalculated — volatile
|
|
87
|
+
* functions (`NOW`, `RAND`) stop re-rolling too — until {@link calculate}: Excel's F9 (every
|
|
88
|
+
* sheet), Shift+F9 (`scope`) and Ctrl+Alt+F9 (`full`). {@link ready} resolves at once in manual
|
|
89
|
+
* mode; a caller that wants current values calls {@link calculate}.
|
|
90
|
+
*
|
|
91
|
+
* @defaultValue {@link ICalculation.CalculationMode.Automatic}
|
|
92
|
+
*/
|
|
93
|
+
getCalculationMode(): ICalculation.CalculationMode;
|
|
94
|
+
/**
|
|
95
|
+
* Sets the calculation mode.
|
|
96
|
+
*
|
|
97
|
+
* @remarks
|
|
98
|
+
* Leaving manual mode recalculates whatever is out of date, as Excel does.
|
|
99
|
+
* {@link ICalculation.CalculationMode.AutomaticExceptTables} is accepted for parity with the
|
|
100
|
+
* file format and Office Scripts; this engine has no what-if data tables, so it recalculates
|
|
101
|
+
* exactly as `Automatic` does.
|
|
102
|
+
*/
|
|
103
|
+
setCalculationMode(mode: ICalculation.CalculationMode): this;
|
|
104
|
+
/**
|
|
105
|
+
* Whether any formula is out of date — Excel's `Calculate` indicator in the status bar.
|
|
106
|
+
*
|
|
107
|
+
* @remarks
|
|
108
|
+
* Meaningful in manual mode, where edits accumulate until {@link calculate}. In automatic
|
|
109
|
+
* mode it is `true` only between an edit and the pass it schedules.
|
|
110
|
+
*/
|
|
111
|
+
isCalculationRequired(): boolean;
|
|
112
|
+
/**
|
|
113
|
+
* How a reference cycle is resolved — Excel's "Enable iterative calculation" and its limits.
|
|
114
|
+
*
|
|
115
|
+
* @see {@link ICalculation.IterativeCalculation}
|
|
116
|
+
*/
|
|
117
|
+
getIterativeCalculation(): ICalculation.IterativeCalculation;
|
|
118
|
+
/**
|
|
119
|
+
* Enables, disables or configures iterative calculation.
|
|
120
|
+
*
|
|
121
|
+
* @param options `true`/`false` toggles `enabled` alone; an object updates the fields given and
|
|
122
|
+
* keeps the rest.
|
|
123
|
+
*
|
|
124
|
+
* @remarks
|
|
125
|
+
* Every cell in a cycle is recalculated when this changes: turning iteration on resolves the
|
|
126
|
+
* cycles the workbook shows as unresolved, turning it off writes `0` to them again.
|
|
127
|
+
*/
|
|
128
|
+
setIterativeCalculation(options: boolean | Partial<ICalculation.IterativeCalculation>): this;
|
|
129
|
+
/**
|
|
130
|
+
* The calculation settings as JSON — what an xlsx carries in `calcPr`.
|
|
131
|
+
*
|
|
132
|
+
* @remarks
|
|
133
|
+
* Sparse: a setting at its default is omitted. Settings a file carried that this engine does
|
|
134
|
+
* not act on (`calcOnSave`, `fullCalcOnLoad`, `fullPrecision`, …) are kept and written back.
|
|
135
|
+
*/
|
|
136
|
+
toJSON(): ICalculation.JSON;
|
|
80
137
|
/**
|
|
81
138
|
* Add Listeners.
|
|
82
139
|
*
|
|
@@ -105,6 +162,87 @@ export declare namespace ICalculation {
|
|
|
105
162
|
* tokenizer, the AST, a formula input — is ever handed an expression of unbounded size.
|
|
106
163
|
*/
|
|
107
164
|
const MAX_EXPRESSION_LENGTH = 8192;
|
|
165
|
+
/**
|
|
166
|
+
* A reference cycle — the answer to "why is this cell `0`".
|
|
167
|
+
*
|
|
168
|
+
* @remarks
|
|
169
|
+
* A cell is in a cycle when calculating it opens its own value, directly or through other cells
|
|
170
|
+
* — `=A1+1` in A1, `=OFFSET(A1,0,0)` in A1, `=SUMIF(B1,C1,A1)` in A1 while B1 matches C1. With
|
|
171
|
+
* iterative calculation off (the default, and Excel's) every cell in a cycle, and every cell
|
|
172
|
+
* downstream of one, evaluates to `0`; nothing on the value says why. This does.
|
|
173
|
+
*
|
|
174
|
+
* Reached from a cell — {@link ICell.getCircularReference} answers it for members and for
|
|
175
|
+
* downstream cells alike — and carried by the `ICellRange.Feature.Circular` regions, so a
|
|
176
|
+
* range, a sheet or the workbook is asked the way any other error is asked:
|
|
177
|
+
* `getCounts(Feature.Circular)` for how many, `getRegions(Feature.Circular)` for which, with
|
|
178
|
+
* this object as each region's payload. There is no list of cycles on the calculation: nobody
|
|
179
|
+
* starts from the cycle; they start from a cell or a range and want to know more.
|
|
180
|
+
*
|
|
181
|
+
* Live, not a snapshot: it reads the engine's cycle table on every call and drops members whose
|
|
182
|
+
* formula has since been edited away, so a stale handle answers `getMemberCount() === 0`.
|
|
183
|
+
* Persists until the last member is edited away.
|
|
184
|
+
*/
|
|
185
|
+
interface ICircularReference {
|
|
186
|
+
/**
|
|
187
|
+
* The cell named for the cycle, the way Excel's status bar names one
|
|
188
|
+
* (`Worksheet.CircularReference` likewise answers a single cell): the first member in
|
|
189
|
+
* row-major order. `scope` is the sheet name, or `null` when the member lives in a named
|
|
190
|
+
* formula's body rather than on a sheet.
|
|
191
|
+
*/
|
|
192
|
+
getRepresentative(): IRange.CellCoords | null;
|
|
193
|
+
/**
|
|
194
|
+
* Every cell IN the cycle, in row-major order, `scope` set to the sheet name. Small — a cycle
|
|
195
|
+
* is the cells that read each other, not everything that reads them (that is
|
|
196
|
+
* {@link getDownstreamCount}).
|
|
197
|
+
*/
|
|
198
|
+
getMembers(): readonly IRange.CellCoords[];
|
|
199
|
+
/** How many cells are IN the cycle, the representative included. */
|
|
200
|
+
getMemberCount(): number;
|
|
201
|
+
/** How many cells read the cycle (transitively) and evaluate to `0` because of it. */
|
|
202
|
+
getDownstreamCount(): number;
|
|
203
|
+
/**
|
|
204
|
+
* Whether `coords` is IN the cycle, as opposed to downstream of it. A cell that reads a
|
|
205
|
+
* member's `0` answers `false` here but still resolves this cycle from
|
|
206
|
+
* {@link ICell.getCircularReference} — the tooltip for it says "reads a circular reference
|
|
207
|
+
* at A1", not "is one".
|
|
208
|
+
*/
|
|
209
|
+
isMember(coords: IRange.CellCoords): boolean;
|
|
210
|
+
/**
|
|
211
|
+
* The cycle as a walk of reads from `from` back to itself — each cell reads the next, and
|
|
212
|
+
* the last reads the first. A cycle has no start, so it is told from the cell that asks:
|
|
213
|
+
* with `A1 = B1+1` and `B1 = A1+1`, asked from A1 it is `[A1, B1]` (A1 → B1 → A1), asked
|
|
214
|
+
* from B1 it is `[B1, A1]`. A cycle of one is `[A1]`.
|
|
215
|
+
*
|
|
216
|
+
* @remarks
|
|
217
|
+
* Exact, not inferred from formula text: it is the order the engine found the cycle in,
|
|
218
|
+
* which is the order the reads happened — a dynamic read (`INDIRECT`, `OFFSET`) is a step
|
|
219
|
+
* like any other. Interlocking cycles share members; the walk follows the read that closed
|
|
220
|
+
* the cycle `from` was found in, so it is ONE loop through that cell, not every member
|
|
221
|
+
* ({@link getMembers} is every member).
|
|
222
|
+
*
|
|
223
|
+
* Empty when `from` is not a live member — a downstream cell asks from
|
|
224
|
+
* {@link getRepresentative}.
|
|
225
|
+
*/
|
|
226
|
+
getPath(from: IRange.CellCoords): readonly IRange.CellCoords[];
|
|
227
|
+
/**
|
|
228
|
+
* Whether iterative calculation was on when the cycle was last evaluated. When `false` the
|
|
229
|
+
* cycle is unresolved and every member and downstream cell is `0`; the iteration answers
|
|
230
|
+
* below are then meaningless (`0` sweeps, no change).
|
|
231
|
+
*/
|
|
232
|
+
isIterative(): boolean;
|
|
233
|
+
/**
|
|
234
|
+
* Whether iterative calculation settled it: every member moved by less than the workbook's
|
|
235
|
+
* `maxIterateChange` in the last sweep. Always `false` with iteration off.
|
|
236
|
+
*/
|
|
237
|
+
isConverged(): boolean;
|
|
238
|
+
/** How many sweeps the last evaluation ran — up to the workbook's `maxIterations`. */
|
|
239
|
+
getIterationCount(): number;
|
|
240
|
+
/**
|
|
241
|
+
* The largest change any member made in the last sweep — what stopped the iteration when
|
|
242
|
+
* {@link isConverged}, what it never got under when not. `0` with iteration off.
|
|
243
|
+
*/
|
|
244
|
+
getLastChange(): number;
|
|
245
|
+
}
|
|
108
246
|
/**
|
|
109
247
|
* Represents a formula that can be evaluated.
|
|
110
248
|
*/
|
|
@@ -783,8 +921,16 @@ export declare namespace ICalculation {
|
|
|
783
921
|
/**
|
|
784
922
|
* Called when the calculation has been updated and
|
|
785
923
|
* a calculation has not been started.
|
|
924
|
+
*
|
|
925
|
+
* @remarks
|
|
926
|
+
* In manual mode this is every edit that leaves a formula out of date — see
|
|
927
|
+
* {@link ICalculation.isCalculationRequired}.
|
|
786
928
|
*/
|
|
787
929
|
onStale?(source: ICalculation): void;
|
|
930
|
+
/**
|
|
931
|
+
* Called when the calculation mode or the iterative-calculation settings change.
|
|
932
|
+
*/
|
|
933
|
+
onOptionsChange?(source: ICalculation): void;
|
|
788
934
|
/**
|
|
789
935
|
* Called when a calculation is starting.
|
|
790
936
|
*/
|
|
@@ -868,6 +1014,38 @@ export declare namespace ICalculation {
|
|
|
868
1014
|
readonly AutomaticExceptTables: "automaticExceptTables";
|
|
869
1015
|
};
|
|
870
1016
|
type CalculationMode = typeof CalculationMode[keyof typeof CalculationMode];
|
|
1017
|
+
/**
|
|
1018
|
+
* Iterative calculation — Excel's "Enable iterative calculation" with its two limits.
|
|
1019
|
+
*
|
|
1020
|
+
* @remarks
|
|
1021
|
+
* With it off a reference cycle evaluates to `0` and is reported as unresolved. With it on the
|
|
1022
|
+
* cells of the cycle are re-evaluated in turn, each read seeing the latest value, until no cell
|
|
1023
|
+
* moved by {@link maxChange} or {@link maxIterations} sweeps ran — and the results persist into
|
|
1024
|
+
* the next recalculation, which re-runs every cycle the way it re-runs `NOW()`: `=A1+1` in A1 is
|
|
1025
|
+
* a counter that advances by `maxIterations` per recalc. A cycle that stops on the sweep cap is
|
|
1026
|
+
* still reported ({@link ICircularReference.isConverged}); a converged one is not.
|
|
1027
|
+
*
|
|
1028
|
+
* Office Scripts calls the count `maxIteration`; the file format `iterateCount` / `iterateDelta`.
|
|
1029
|
+
*/
|
|
1030
|
+
interface IterativeCalculation {
|
|
1031
|
+
/**
|
|
1032
|
+
* @defaultValue `false`
|
|
1033
|
+
*/
|
|
1034
|
+
enabled: boolean;
|
|
1035
|
+
/**
|
|
1036
|
+
* The most sweeps one recalculation runs over a cycle.
|
|
1037
|
+
*
|
|
1038
|
+
* @defaultValue `100`
|
|
1039
|
+
*/
|
|
1040
|
+
maxIterations: number;
|
|
1041
|
+
/**
|
|
1042
|
+
* Sweeps stop early once every cell in the cycle moved by less than this. A non-numeric
|
|
1043
|
+
* change (text, error) never counts as settled.
|
|
1044
|
+
*
|
|
1045
|
+
* @defaultValue `0.001`
|
|
1046
|
+
*/
|
|
1047
|
+
maxChange: number;
|
|
1048
|
+
}
|
|
871
1049
|
/**
|
|
872
1050
|
* Represents the status of a calculation result
|
|
873
1051
|
*/
|
|
@@ -4,6 +4,8 @@ import { ISpatialMap, ISpatialMap3D } from '../../collections';
|
|
|
4
4
|
import { FormulaSpatialValue, PrecedentSpatialValue, PrecedentKind } from '../spatial';
|
|
5
5
|
import { ICalcGrid } from '../grid';
|
|
6
6
|
import { IContextContainer, CalcNode } from '../state';
|
|
7
|
+
import { ReadHook } from '../state/_ReadObservedGrid';
|
|
8
|
+
import { CircularReference, CycleHost } from './CircularReference';
|
|
7
9
|
/**
|
|
8
10
|
* Executes a calculation cycle: collect → mark-and-plan → evaluate.
|
|
9
11
|
*
|
|
@@ -17,16 +19,77 @@ export declare class CalcExecutor {
|
|
|
17
19
|
private readonly _requestCalculate;
|
|
18
20
|
protected _pendingCalcs: Set<CalcNode>;
|
|
19
21
|
/**
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
+
* The last pass's circular roster: every node it evaluated by demand (a `doMarkAndPlan` that
|
|
23
|
+
* could not order, or the iteration guard's hand-over) plus every node whose dynamic read
|
|
24
|
+
* landed on its own cell, each carrying its `cycleRole`. The module scratch `_circularNodes`,
|
|
25
|
+
* this many; a node in it is flagged `CalcState.Rostered`. Emptied when a pass starts.
|
|
22
26
|
*/
|
|
23
|
-
protected
|
|
27
|
+
protected _circularNodesLength: number;
|
|
28
|
+
/** The nodes the current `doMarkAndPlan` handed to demand evaluation, in worklist order. */
|
|
29
|
+
protected _demandBatch: CalcNode[];
|
|
30
|
+
/** {@link _onPassRead} as a bound hook — one closure for the executor's lifetime. */
|
|
31
|
+
protected _passHook: ReadHook;
|
|
24
32
|
/**
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
33
|
+
* Marks a node downstream of the cycle `_taintGroup` names (design §2.1: every cell that reads
|
|
34
|
+
* a cycle, however it came to, is `0`). It skips evaluation — `Done` with a demand result of
|
|
35
|
+
* `0` — and taints its own dependents when the plan reaches it. A node already in a cycle keeps
|
|
36
|
+
* its role.
|
|
28
37
|
*/
|
|
29
|
-
protected
|
|
38
|
+
protected _taintDownstream: (calc: CalcNode) => void;
|
|
39
|
+
protected _taintGroup: number;
|
|
40
|
+
/**
|
|
41
|
+
* Iterative calculation for the pass in progress (design §6.3); `null` with it off. Under it a
|
|
42
|
+
* read of a `Waiting` node is not an abort: the reader goes on with the node's previous value
|
|
43
|
+
* and the slice is marked once the reader returns (`_iterHits`); a read of a member's result
|
|
44
|
+
* makes the reader downstream without aborting it either; and {@link _demandSweep}
|
|
45
|
+
* re-evaluates the members until they settle.
|
|
46
|
+
*/
|
|
47
|
+
protected _iterate: CalcExecutor.IterateOptions | null;
|
|
48
|
+
/** Inside {@link doDemandEvaluate} — where a `Waiting` read under iteration is marked in place. */
|
|
49
|
+
protected _demandActive: boolean;
|
|
50
|
+
/**
|
|
51
|
+
* Lengths of the module scratch lists of one {@link doDemandEvaluate}: `_iterHits`, the
|
|
52
|
+
* `Waiting` nodes the evaluation in progress read under iteration (each flagged
|
|
53
|
+
* `CalcState.IterHit`; consumed when it returns); `_iterMembers`, the members the call marked,
|
|
54
|
+
* in marking order — the sweep order; `_iterDownstream`, the nodes it marked downstream,
|
|
55
|
+
* evaluated once more after the sweeps. On the executor rather than local because the lists
|
|
56
|
+
* grow across the runs a sweep nests.
|
|
57
|
+
*/
|
|
58
|
+
protected _iterHitsLength: number;
|
|
59
|
+
protected _iterMembersLength: number;
|
|
60
|
+
protected _iterDownstreamLength: number;
|
|
61
|
+
/** The pass the hook answers for; inert otherwise. Set by `doMarkAndPlan`, released with `_gridUpdates`. */
|
|
62
|
+
protected _passActive: boolean;
|
|
63
|
+
protected _passCycleId: number;
|
|
64
|
+
protected _passMarkId: number;
|
|
65
|
+
/**
|
|
66
|
+
* Commits `doEvaluate`'s pending batch — installed for the length of a `doEvaluate`. A read
|
|
67
|
+
* that lands on a node evaluated but not yet committed needs nothing more than this: the
|
|
68
|
+
* value is right, it is just not in the grid yet.
|
|
69
|
+
*/
|
|
70
|
+
protected _flush: (() => void) | null;
|
|
71
|
+
/**
|
|
72
|
+
* The cycle table (design §7.3): per cycle id, one live {@link CircularReference} holding the
|
|
73
|
+
* nodes the sheet index currently shows as its members and as downstream of it — the object
|
|
74
|
+
* the index payloads carry and `ICell.getCircularReference()` answers. Persists across passes
|
|
75
|
+
* (a node moves when a commit writes its delta, `_trackCircular`) and is confirmed against the
|
|
76
|
+
* graph on read, since a deleted formula's node lingers here until something re-evaluates its
|
|
77
|
+
* cell. A cycle is created on first sight and dropped when its last node leaves.
|
|
78
|
+
*/
|
|
79
|
+
protected _cycles: Map<number, CircularReference>;
|
|
80
|
+
/** What a {@link CircularReference} may ask of this executor; built once, shared by all. */
|
|
81
|
+
protected _cycleHost: CycleHost;
|
|
82
|
+
/** Last cycle id handed out by a demand pass; ids are unique across passes. */
|
|
83
|
+
protected _cycleGroupNext: number;
|
|
84
|
+
/**
|
|
85
|
+
* Counters over every demand pass since construction: nodes evaluated by demand and
|
|
86
|
+
* `NeedsFirst` retries. A retry is the cost of the path (a formula run and thrown away), so a
|
|
87
|
+
* chain Kahn could not order should show about one per node at most.
|
|
88
|
+
*/
|
|
89
|
+
protected _demandStats: {
|
|
90
|
+
evaluations: number;
|
|
91
|
+
retries: number;
|
|
92
|
+
};
|
|
30
93
|
_gridUpdates: Map<string, ICalcGrid.IncrementalUpdates> | null;
|
|
31
94
|
_addDynamicPrecedent: ((node: CalcNode, range: IRange.Coords | undefined, kind: PrecedentKind) => void) | null;
|
|
32
95
|
constructor(container: IContextContainer, context: IFormulaContext, requestCalculate: () => void);
|
|
@@ -45,14 +108,124 @@ export declare class CalcExecutor {
|
|
|
45
108
|
*/
|
|
46
109
|
execute(cycleId: number, options: CalcExecutor.ExecuteOptions, state: CalcExecutor.ExecuteState): CalcExecutor.ExecuteResult | null;
|
|
47
110
|
/**
|
|
48
|
-
*
|
|
111
|
+
* The read hook of a pass (DESIGN-CIRCULAR-CALC.md §4.3, §5), shared by both paths: armed for
|
|
112
|
+
* every reference while a node is evaluated by demand, and for dynamic-branch references
|
|
113
|
+
* (`OFFSET`/`INDIRECT`/`INDEX` results) on the ordinary path. A read that lands on a node of
|
|
114
|
+
* THIS pass decides: `Waiting` (on the in-progress stack — transitively waiting on the reader)
|
|
115
|
+
* is a cycle; `Unevaluated` suspends the reader until it is done; `Evaluated` (in the pending
|
|
116
|
+
* batch) is committed on the spot and read; `Done` with a cycle role makes the reader
|
|
117
|
+
* downstream. Any other cell is a value. Inert outside a pass, so a reference built during one
|
|
118
|
+
* and read later (a spill committed afterwards) is plain values.
|
|
119
|
+
*/
|
|
120
|
+
private _onPassRead;
|
|
121
|
+
/**
|
|
122
|
+
* Under iteration, a read of a `Done` cycle node by the node being evaluated: the reader is
|
|
123
|
+
* downstream of that cycle (design §6.3) unless it is in one itself. Nothing is aborted — the
|
|
124
|
+
* reader goes on with the value — so the mark is made here, on the reader.
|
|
125
|
+
*/
|
|
126
|
+
private _iterRead;
|
|
127
|
+
/**
|
|
128
|
+
* The nodes of this pass inside `coords` that are still `Unevaluated`, written into `into` from
|
|
129
|
+
* slot `length` on; returns the new length.
|
|
130
|
+
*/
|
|
131
|
+
private _collectUnevaluated;
|
|
132
|
+
/**
|
|
133
|
+
* Evaluates `worklist` by demand (DESIGN-CIRCULAR-CALC.md §4.3): each node is evaluated with the
|
|
134
|
+
* read hook armed; a read that lands on one not yet evaluated suspends the reader and evaluates
|
|
135
|
+
* that one first (`NeedsFirst`); a read that lands on one already suspended — waiting,
|
|
136
|
+
* transitively, on the reader — is a cycle (`Circular`), and the in-progress stack from it up
|
|
137
|
+
* to the reader are the members, written `0`. A node that reads a member is downstream and
|
|
138
|
+
* writes `0` too. Everything else simply computes: an unorderable static edge that is never
|
|
139
|
+
* read (`OFFSET`'s anchor, `ROW`'s argument, an untaken `IF` branch) makes no cycle.
|
|
140
|
+
*
|
|
141
|
+
* @remarks
|
|
142
|
+
* Two callers: `doEvaluate` when the plan reaches the nodes `doMarkAndPlan` could not order
|
|
143
|
+
* (the batch, after everything ordered is committed), and `doEvaluate` again for a single
|
|
144
|
+
* ordered node whose dynamic read landed on a node not yet evaluated — the same suspension,
|
|
145
|
+
* on the ordinary path (§5). Every node evaluated here is flagged `circular`, so the plan
|
|
146
|
+
* takes its `demandValue` when it reaches it, and its finalized scalar is already in the grid
|
|
147
|
+
* for later lazy reads; `flush` commits the ordered path's pending batch when a read needs a
|
|
148
|
+
* value still sitting in it. Flat: the stack is an array, so a 1,560-row chain is 1,560
|
|
149
|
+
* evaluations, not 1,560 JS frames. A node is retried at most once per `NeedsFirst` it raises,
|
|
150
|
+
* and with the prefetch of its static precedents that is normally once.
|
|
151
|
+
*/
|
|
152
|
+
protected doDemandEvaluate(cycleId: number, getUpdates: (scope: string) => ICalcGrid.IncrementalUpdates, worklist: readonly CalcNode[], flush: () => void): void;
|
|
153
|
+
/**
|
|
154
|
+
* The finalized scalar goes into the grid now, so a later lazy read sees it; `doEvaluate`
|
|
155
|
+
* commits the same value with the notifications when it reaches the node.
|
|
156
|
+
*/
|
|
157
|
+
private _writeEarly;
|
|
158
|
+
/** The worklist loop of {@link doDemandEvaluate}; re-entered by a sweep for the nodes a read needs first. */
|
|
159
|
+
private _demandRun;
|
|
160
|
+
/**
|
|
161
|
+
* Marks the started (`Waiting`) nodes on the in-progress stack from `read` up to the top as one
|
|
162
|
+
* cycle — the slice a `Waiting` read names (design §4.3). A slice touching a member of an
|
|
163
|
+
* earlier cycle joins that cycle. The started nodes are on the stack in READ order — each is
|
|
164
|
+
* there because the one below it read it, and the reader on top read `read` — so the slice is
|
|
165
|
+
* the walk `getPath` answers: each member is linked to the next, the last back to the first.
|
|
166
|
+
* The demand state is left as it is: the caller finishes the members (iteration off) or lets
|
|
167
|
+
* them run on (iteration on). Returns the stack index of `read`.
|
|
168
|
+
*/
|
|
169
|
+
private _markCycleSlice;
|
|
170
|
+
/**
|
|
171
|
+
* Iterative calculation (design §6.3) over the members {@link _demandRun} marked, which it
|
|
172
|
+
* evaluated once each — sweep 1. Every further sweep re-evaluates them in marking order, each
|
|
173
|
+
* read seeing the latest value (Gauss–Seidel, as Excel: `probe-iterative.ps1`), until no member
|
|
174
|
+
* moved by `maxChange` or `maxIterations` sweeps ran. The limits are global, as in Excel — one
|
|
175
|
+
* unsettled member keeps every cycle of the pass sweeping. Downstream nodes read the members
|
|
176
|
+
* once more afterwards; they never feed a cycle, so they need no sweeping. The members are then
|
|
177
|
+
* registered as volatile so the next recalculation re-runs them, which is how `=A1+1` advances
|
|
178
|
+
* per recalc (Excel re-iterates every cycle on every `Calculate()`).
|
|
179
|
+
*/
|
|
180
|
+
private _demandSweep;
|
|
181
|
+
/** Clears the `IterHit` flags of the hits not consumed by {@link _demandRun}'s loop and empties the list. */
|
|
182
|
+
private _drainIterHits;
|
|
183
|
+
/**
|
|
184
|
+
* One evaluation of a `Done` node under iteration, with the read hook armed. A read that
|
|
185
|
+
* needs a node not yet evaluated (a handed-over node's sweep runs before the batch) runs those
|
|
186
|
+
* by demand and retries; a `Waiting` read cannot occur (nothing is waiting) and a member's
|
|
187
|
+
* result is a value (`_iterRead`), so nothing aborts.
|
|
188
|
+
*/
|
|
189
|
+
private _demandEvaluateOne;
|
|
190
|
+
/**
|
|
191
|
+
* @internal
|
|
192
|
+
* Every cell the sheets currently show in a cycle or downstream of one, as dirty regions — what
|
|
193
|
+
* a change of the iterative-calculation setting re-evaluates.
|
|
194
|
+
*/
|
|
195
|
+
getCycleCells(): ISpatialMap.Entry[];
|
|
196
|
+
/** Whether the pass in progress found a cycle member. */
|
|
197
|
+
protected _hasCycle(): boolean;
|
|
198
|
+
/** Adds `node` to the pass's circular roster, once. */
|
|
199
|
+
private _addCircular;
|
|
200
|
+
/** Empties the roster for a new pass, clearing each node's `Rostered` flag on the way out. */
|
|
201
|
+
private _resetCircular;
|
|
202
|
+
/**
|
|
203
|
+
* Records the difference between what the sheet's circular index shows for `node` and what
|
|
204
|
+
* this pass decided, in the cycle table and in the pass's conflating delta — the same path a
|
|
205
|
+
* pending status takes to the sheet (design §7.2). Called only when one of the two is set.
|
|
206
|
+
*/
|
|
207
|
+
protected _trackCircular(node: CalcNode, updates: ICalcGrid.IncrementalUpdates, major: number, minor: number, isColumn: boolean): void;
|
|
208
|
+
/** The public face of cycle `group`, created on first sight. */
|
|
209
|
+
private _cycleOf;
|
|
210
|
+
/**
|
|
211
|
+
* Whether `node` is still the node registered for its own cell.
|
|
49
212
|
*
|
|
50
213
|
* @remarks
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
|
|
214
|
+
* A `CalcNode` is a plain graph object reachable by identity long after the grid has replaced or
|
|
215
|
+
* dropped its block — the same hazard `doCollectVolatileCalcs` guards against with `isLiveBlock`.
|
|
216
|
+
*/
|
|
217
|
+
protected isLiveNode(node: CalcNode): boolean;
|
|
218
|
+
/**
|
|
219
|
+
* @internal
|
|
220
|
+
* A copy of the last pass's circular roster — see {@link _circularNodesLength} — each node
|
|
221
|
+
* carrying the {@link CycleRole} its reads gave it. Describes the last pass only.
|
|
54
222
|
*/
|
|
55
|
-
|
|
223
|
+
getCircularNodes(): readonly CalcNode[];
|
|
224
|
+
/** @internal Demand-pass counters since construction: evaluations and `NeedsFirst` retries. */
|
|
225
|
+
getDemandStats(): {
|
|
226
|
+
evaluations: number;
|
|
227
|
+
retries: number;
|
|
228
|
+
};
|
|
56
229
|
/**
|
|
57
230
|
* Collects and marks all volatile CalcNodes.
|
|
58
231
|
*
|
|
@@ -79,7 +252,7 @@ export declare class CalcExecutor {
|
|
|
79
252
|
* @remarks
|
|
80
253
|
* Uses Kahn's algorithm.
|
|
81
254
|
*/
|
|
82
|
-
doMarkAndPlan(cycleId: number, markId: number, initial: FixedPackedArray<CalcNode>, plan: FixedPackedArray<CalcNode
|
|
255
|
+
doMarkAndPlan(cycleId: number, markId: number, initial: FixedPackedArray<CalcNode>, plan: FixedPackedArray<CalcNode>, forceDemand?: boolean): boolean;
|
|
83
256
|
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;
|
|
84
257
|
}
|
|
85
258
|
export declare namespace CalcExecutor {
|
|
@@ -96,6 +269,24 @@ export declare namespace CalcExecutor {
|
|
|
96
269
|
* The grid to seed the pass FROM — `ICalculation.CalculateOptions.scope`, i.e. "Calculate Sheet".
|
|
97
270
|
*/
|
|
98
271
|
scopeGridId?: string;
|
|
272
|
+
/**
|
|
273
|
+
* Iterative calculation (design §6.3) for the pass; `null`/absent with it off.
|
|
274
|
+
*/
|
|
275
|
+
iterate?: IterateOptions | null;
|
|
276
|
+
}
|
|
277
|
+
/** The two limits of `ICalculation.IterativeCalculation`. */
|
|
278
|
+
interface IterateOptions {
|
|
279
|
+
maxIterations: number;
|
|
280
|
+
maxChange: number;
|
|
281
|
+
}
|
|
282
|
+
/** How a cycle's last iterated evaluation ended — what `ICircularReference` answers. */
|
|
283
|
+
interface IterationResult {
|
|
284
|
+
/** Every member moved by less than `maxChange` in the last sweep. */
|
|
285
|
+
converged: boolean;
|
|
286
|
+
/** Sweeps run, the first evaluation included. */
|
|
287
|
+
iterationCount: number;
|
|
288
|
+
/** The largest change any member made in the last sweep. */
|
|
289
|
+
lastChange: number;
|
|
99
290
|
}
|
|
100
291
|
/** Snapshot of Calculation's persistent state for one pass */
|
|
101
292
|
interface ExecuteState {
|
|
@@ -1,7 +1,38 @@
|
|
|
1
1
|
import { IRange, Scalar } from '@sheetxl/primitives';
|
|
2
2
|
import { Tuple, ISpatialMap } from '../../collections';
|
|
3
|
+
import { CalcSignal } from '../../primitives/CalcSignal';
|
|
3
4
|
import { CalcNode } from '../state';
|
|
4
5
|
import { PrecedentSpatialValue, FormulaSpatialValue } from '../spatial';
|
|
6
|
+
/**
|
|
7
|
+
* Raised from a read that landed on unorderable nodes not yet evaluated: the reader is suspended,
|
|
8
|
+
* `nodes` are evaluated first, and the reader is retried from scratch.
|
|
9
|
+
*/
|
|
10
|
+
export declare class NeedsFirstSignal extends CalcSignal {
|
|
11
|
+
readonly nodes: readonly CalcNode[];
|
|
12
|
+
readonly count: number;
|
|
13
|
+
/**
|
|
14
|
+
* @param nodes A scratch array the executor reuses across reads; only the first `count` slots
|
|
15
|
+
* belong to this read, and the catcher consumes them before the next read can overwrite them.
|
|
16
|
+
*/
|
|
17
|
+
constructor(nodes: readonly CalcNode[], count: number);
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Raised from a read that landed on a node already suspended — one that is, transitively,
|
|
21
|
+
* waiting on the reader. The in-progress stack from `node` up to the reader is a cycle.
|
|
22
|
+
*/
|
|
23
|
+
export declare class CircularSignal extends CalcSignal {
|
|
24
|
+
readonly node: CalcNode;
|
|
25
|
+
constructor(node: CalcNode);
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Raised from a read that landed on a cycle member or a cell downstream of one: the reader is
|
|
29
|
+
* downstream too and writes `0` without finishing (Excel, iterative calc off — `=A1+100` beside
|
|
30
|
+
* `=A1+1` in A1 is `0`, not `100`).
|
|
31
|
+
*/
|
|
32
|
+
export declare class DownstreamSignal extends CalcSignal {
|
|
33
|
+
readonly node: CalcNode;
|
|
34
|
+
constructor(node: CalcNode);
|
|
35
|
+
}
|
|
5
36
|
export declare function rangeToTuples(range: IRange, offsetMajor?: number, offsetMinor?: number): Tuple.BoundedTuples<Scalar>;
|
|
6
37
|
/**
|
|
7
38
|
* TODO - document and/or rationalize with visitPrecedentBlock
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { IRange } from '@sheetxl/primitives';
|
|
2
|
+
import { ICalculation } from '../ICalculation';
|
|
3
|
+
import { CalcNode } from '../state';
|
|
4
|
+
import { CircularEntry } from '../spatial';
|
|
5
|
+
import { CalcExecutor } from './CalcExecutor';
|
|
6
|
+
/**
|
|
7
|
+
* The two graph questions a {@link CircularReference} cannot answer on its own; built once by
|
|
8
|
+
* the executor, shared by every cycle.
|
|
9
|
+
*/
|
|
10
|
+
export interface CycleHost {
|
|
11
|
+
/** Whether `node` is still the node registered for its own cell (a deleted formula's is not). */
|
|
12
|
+
isLiveNode(node: CalcNode): boolean;
|
|
13
|
+
/** The sheet name for a grid id, or `undefined` for a virtual grid (a named formula's body). */
|
|
14
|
+
resolveScope(gridId: string): string | undefined;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* One reference cycle (DESIGN-CIRCULAR-CALC.md §7.3): the executor's record of it and its public
|
|
18
|
+
* face in one — the object a `Feature.Circular` region carries as its payload and
|
|
19
|
+
* `ICell.getCircularReference()` answers. It holds the nodes the sheet index currently shows as
|
|
20
|
+
* its members and as downstream of it, the interned index payloads, and how the sweep that
|
|
21
|
+
* settled it ended. It persists across passes — a node moves between cycles when a commit writes
|
|
22
|
+
* its delta (`_trackCircular`) — and is dropped when its last node leaves.
|
|
23
|
+
*
|
|
24
|
+
* @remarks
|
|
25
|
+
* Every read filters through {@link CycleHost.isLiveNode}: a pass that deletes the offending
|
|
26
|
+
* formula never plans, so the sets cannot clear themselves, and a member is counted only while
|
|
27
|
+
* its cell still holds the block the cycle was found in (design §7.3, trap 5).
|
|
28
|
+
*
|
|
29
|
+
* The iteration answers come from the sweep that settled the cycle (design §6.3). A cycle id is
|
|
30
|
+
* minted by the pass that finds it, so a cycle evaluated with iteration off is a different object
|
|
31
|
+
* with no record — `isIterative()` is exactly "a sweep settled this one".
|
|
32
|
+
*/
|
|
33
|
+
export declare class CircularReference implements ICalculation.ICircularReference {
|
|
34
|
+
protected readonly _host: CycleHost;
|
|
35
|
+
protected readonly _cycleId: number;
|
|
36
|
+
/** @internal The nodes the sheet index shows in the cycle; maintained by the executor. */
|
|
37
|
+
readonly members: Set<CalcNode>;
|
|
38
|
+
/** @internal The nodes the sheet index shows downstream of the cycle; maintained by the executor. */
|
|
39
|
+
readonly downstream: Set<CalcNode>;
|
|
40
|
+
/** One payload per kind, so equal payloads are one object and adjacent cells one region. */
|
|
41
|
+
protected _memberEntry: CircularEntry | null;
|
|
42
|
+
protected _downstreamEntry: CircularEntry | null;
|
|
43
|
+
protected _iteration: CalcExecutor.IterationResult | null;
|
|
44
|
+
constructor(host: CycleHost, cycleId: number);
|
|
45
|
+
/** @internal The executor's key for this cycle. */
|
|
46
|
+
getCycleId(): number;
|
|
47
|
+
/** @internal Whether the sheet index shows no cell in or downstream of the cycle any more. */
|
|
48
|
+
isEmpty(): boolean;
|
|
49
|
+
/** @internal The index payload for the cycle's members or for its downstream cells. */
|
|
50
|
+
getEntry(isMember: boolean): CircularEntry;
|
|
51
|
+
/** @internal How the sweep that settled this cycle ended; written by the executor. */
|
|
52
|
+
setIteration(result: CalcExecutor.IterationResult): void;
|
|
53
|
+
/** @inheritdoc ICalculation.ICircularReference.getRepresentative */
|
|
54
|
+
getRepresentative(): IRange.CellCoords | null;
|
|
55
|
+
/** @inheritdoc ICalculation.ICircularReference.getMembers */
|
|
56
|
+
getMembers(): readonly IRange.CellCoords[];
|
|
57
|
+
/** @inheritdoc ICalculation.ICircularReference.getMemberCount */
|
|
58
|
+
getMemberCount(): number;
|
|
59
|
+
/** @inheritdoc ICalculation.ICircularReference.getDownstreamCount */
|
|
60
|
+
getDownstreamCount(): number;
|
|
61
|
+
/** @inheritdoc ICalculation.ICircularReference.isMember */
|
|
62
|
+
isMember(coords: IRange.CellCoords): boolean;
|
|
63
|
+
/** @inheritdoc ICalculation.ICircularReference.getPath */
|
|
64
|
+
getPath(from: IRange.CellCoords): readonly IRange.CellCoords[];
|
|
65
|
+
/** The live member at `coords`, or `null`. */
|
|
66
|
+
protected _memberAt(coords: IRange.CellCoords): CalcNode | null;
|
|
67
|
+
/** @inheritdoc ICalculation.ICircularReference.isIterative */
|
|
68
|
+
isIterative(): boolean;
|
|
69
|
+
/** @inheritdoc ICalculation.ICircularReference.isConverged */
|
|
70
|
+
isConverged(): boolean;
|
|
71
|
+
/** @inheritdoc ICalculation.ICircularReference.getIterationCount */
|
|
72
|
+
getIterationCount(): number;
|
|
73
|
+
/** @inheritdoc ICalculation.ICircularReference.getLastChange */
|
|
74
|
+
getLastChange(): number;
|
|
75
|
+
/** The members still on the graph, in row-major order (virtual grids first, then by sheet). */
|
|
76
|
+
protected _liveMembers(): CalcNode[];
|
|
77
|
+
protected _countLive(nodes: Set<CalcNode>): number;
|
|
78
|
+
protected _scopeOf(node: CalcNode): string | null;
|
|
79
|
+
protected _toCoords(node: CalcNode): IRange.CellCoords;
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=CircularReference.d.ts.map
|
|
@@ -3,7 +3,7 @@ import { IListener } from '../../listener';
|
|
|
3
3
|
import { ListenerEmitter } from '../../listener/ListenerEmitter';
|
|
4
4
|
import { Tuple, ISpatialQuery, ISparseGrid, ISpatialMap, ISpatialMap3D } from '../../collections';
|
|
5
5
|
import { IContextContainer, CalcNode } from '../state';
|
|
6
|
-
import { SpillEntry, FormulaSpatialValue, ContentfulSpatialValue, PrecedentSpatialValue } from '../spatial';
|
|
6
|
+
import { SpillEntry, FormulaSpatialValue, ContentfulSpatialValue, PrecedentSpatialValue, CircularEntry } from '../spatial';
|
|
7
7
|
import { IFormulaBlock } from '../formula';
|
|
8
8
|
import { ReferenceCoords } from '../Types';
|
|
9
9
|
import { ICalculation } from '../ICalculation';
|
|
@@ -20,12 +20,14 @@ export declare class CalcGrid implements ICalcGrid {
|
|
|
20
20
|
_spillSpatial: ISpatialMap<SpillEntry>;
|
|
21
21
|
_errorSpatial: ISpatialMap<string>;
|
|
22
22
|
_pendingSpatial: ISpatialMap<boolean>;
|
|
23
|
+
_circularSpatial: ISpatialMap<CircularEntry>;
|
|
23
24
|
_contentfulSpatial: ISpatialMap<ContentfulSpatialValue>;
|
|
24
25
|
_notifyValues: ISpatialMap;
|
|
25
26
|
_notifySpillsInsert: ISpatialMap.Entry<SpillEntry>[];
|
|
26
27
|
_notifySpillsRemove: IRange.Coords[];
|
|
27
28
|
_notifyFormats: ISpatialMap;
|
|
28
29
|
_notifyPending: ISpatialMap<boolean>;
|
|
30
|
+
_notifyCircular: ISpatialMap<CircularEntry | false>;
|
|
29
31
|
_cloneKey?: CalcGrid;
|
|
30
32
|
_version: number;
|
|
31
33
|
_iterationId: number;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { IRange, Scalar } from '@sheetxl/primitives';
|
|
2
2
|
import { Tuple, ISparseGrid, ISpatialMap, ISpatialMap3D } from '../../collections';
|
|
3
3
|
import { CalcNode } from '../state';
|
|
4
|
-
import { ContentfulSpatialValue, FormulaSpatialValue, SpillEntry, PrecedentSpatialValue, PrecedentKind } from '../spatial';
|
|
4
|
+
import { ContentfulSpatialValue, FormulaSpatialValue, SpillEntry, PrecedentSpatialValue, CircularEntry, PrecedentKind } from '../spatial';
|
|
5
5
|
import { ReferenceCoords } from '../Types';
|
|
6
6
|
export declare function anchorCompareValues(a: ISpatialMap.Entry<FormulaSpatialValue>, removing: ISpatialMap.Entry<FormulaSpatialValue>): boolean;
|
|
7
7
|
/**
|
|
@@ -19,7 +19,8 @@ export declare function isTopLeft(rowIndex: number, colIndex: number, range: IRa
|
|
|
19
19
|
* This code will inline spill errors but spill results are handled in calculations.
|
|
20
20
|
*/
|
|
21
21
|
export declare function applyContentful(cycleId: number, removes: readonly IRange.Coords[] | null | undefined, inserts: ISpatialMap.Entry[] | null | undefined, contentfulSpatial: ISpatialMap<ContentfulSpatialValue>, spillSpatial: ISpatialMap<SpillEntry>, values: ISparseGrid<Scalar>, addDirty?: (colStart: number, rowStart: number, colEnd: number, rowEnd: number) => void, notifyValuesSpatial?: ISpatialMap, notifySpills?: (insert: ISpatialMap.Entry<SpillEntry>, remove: ISpatialMap.Entry<SpillEntry>) => void, notifyPending?: ISpatialMap<boolean>, errorSpatial?: ISpatialMap<string>, // notifyErrorSpatial,
|
|
22
|
-
isColumn?: boolean, notifyCalc?: boolean
|
|
22
|
+
isColumn?: boolean, notifyCalc?: boolean, // should notify. this is to differentiate between user set values and calc set values
|
|
23
|
+
circularSpatial?: ISpatialMap<CircularEntry>): IRange.Coords | null;
|
|
23
24
|
/**
|
|
24
25
|
* Creates a map from tuples
|
|
25
26
|
*
|