@sheetxl/primitives 0.7.22 → 0.7.23-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/browser/cjs/index.cjs +1 -6
  2. package/browser/esm/index.mjs +683 -307
  3. package/node/esm/index.mjs +684 -307
  4. package/package.json +1 -1
  5. package/types/index.d.ts +2 -1622
  6. package/types/src/ErrorPolicy.d.ts +78 -0
  7. package/types/src/ErrorPolicy.d.ts.map +1 -0
  8. package/types/src/Flatten.d.ts +34 -0
  9. package/types/src/Flatten.d.ts.map +1 -0
  10. package/types/src/FormulaContext.d.ts +227 -0
  11. package/types/src/FormulaContext.d.ts.map +1 -0
  12. package/types/src/FormulaError.d.ts +328 -0
  13. package/types/src/FormulaError.d.ts.map +1 -0
  14. package/types/src/IFormulaContext.d.ts +533 -0
  15. package/types/src/IFormulaContext.d.ts.map +1 -0
  16. package/types/src/IFunction.d.ts +608 -0
  17. package/types/src/IFunction.d.ts.map +1 -0
  18. package/types/src/IRange.d.ts +1091 -0
  19. package/types/src/IRange.d.ts.map +1 -0
  20. package/types/src/IRangeStats.d.ts +478 -0
  21. package/types/src/IRangeStats.d.ts.map +1 -0
  22. package/types/src/IReferenceRange.d.ts +22 -0
  23. package/types/src/IReferenceRange.d.ts.map +1 -0
  24. package/types/src/IRichData.d.ts +37 -0
  25. package/types/src/IRichData.d.ts.map +1 -0
  26. package/types/src/IRuntime.d.ts +65 -0
  27. package/types/src/IRuntime.d.ts.map +1 -0
  28. package/types/src/Lambda.d.ts +17 -0
  29. package/types/src/Lambda.d.ts.map +1 -0
  30. package/types/src/LocaleProfile.d.ts +79 -0
  31. package/types/src/LocaleProfile.d.ts.map +1 -0
  32. package/types/src/Observable.d.ts +46 -0
  33. package/types/src/Observable.d.ts.map +1 -0
  34. package/types/src/Omittable.d.ts +50 -0
  35. package/types/src/Omittable.d.ts.map +1 -0
  36. package/types/src/Repeating.d.ts +66 -0
  37. package/types/src/Repeating.d.ts.map +1 -0
  38. package/types/src/Scalar.d.ts +67 -0
  39. package/types/src/Scalar.d.ts.map +1 -0
  40. package/types/src/ScalarType.d.ts +109 -0
  41. package/types/src/ScalarType.d.ts.map +1 -0
  42. package/types/src/WildCard.d.ts +26 -0
  43. package/types/src/WildCard.d.ts.map +1 -0
  44. package/types/src/index.d.ts +20 -0
  45. package/types/src/index.d.ts.map +1 -0
@@ -0,0 +1,533 @@
1
+ import { Scalar } from './Scalar';
2
+ import { FormulaError } from './FormulaError';
3
+ import { IRange } from './IRange';
4
+ import { IReferenceRange } from './IReferenceRange';
5
+ import { IFunction } from './IFunction';
6
+ import { IRuntime } from './IRuntime';
7
+ /**
8
+ * Everything a formula function is allowed to know about the world outside its arguments.
9
+ *
10
+ * @remarks
11
+ * Formula functions are pure — they cannot reach the workbook, the sheet they sit on, or
12
+ * the clock. `FormulaContext` is the one channel that gives them sheet data, cell
13
+ * coordinates, date and number parsing, and evaluation hints without giving up that purity.
14
+ *
15
+ * Import it and call its methods directly; there is nothing to construct or thread through
16
+ * arguments. Every call is already scoped to the cell being evaluated:
17
+ *
18
+ * ```typescript
19
+ * import { FormulaContext } from '@sheetxl/primitives';
20
+ *
21
+ * export function ROWNUMBER(): number {
22
+ * return FormulaContext.getRow() + 1;
23
+ * }
24
+ * ```
25
+ *
26
+ * ### Capabilities
27
+ *
28
+ * | Category | Key methods |
29
+ * |---|---|
30
+ * | Evaluation lifecycle | `markVolatile`, `getRow`, `getColumn`, `getEntireCoords` |
31
+ * | Output hints | `formatResults` |
32
+ * | Range construction | `createRange`, `filterHidden` |
33
+ * | Dynamic references | `getReference`, `getValueAt`, `getFormulaAt`, `getSpillAt` |
34
+ * | Function lookup | `getFunction` |
35
+ * | Dates | `getNow`, `toSerialDate`, `fromSerialDate`, `getDateParts`, `getSerialDate`, `parseAsDate`, `parseAsSerialDate`, `isValidDate` |
36
+ * | Coercion | `parseAsNumber`, `parseAsLiteral`, `toText`, `compare` |
37
+ * | Criteria | `createCriteria` |
38
+ * | Sheet introspection | `getSheetCount`, `getSheetIndex`, `getAddress`, `getNumberFormat` |
39
+ *
40
+ * ### Implementors
41
+ *
42
+ * The calculation engine provides the implementation. Third-party code (UDF packages, test
43
+ * harnesses) may supply its own for isolated evaluation or unit testing.
44
+ */
45
+ export interface IFormulaContext {
46
+ /**
47
+ * Creates a range to return as a dynamic array result.
48
+ *
49
+ * @param rows The number of rows of the range. Default is 0.
50
+ * @param columns The number of columns of the range. Default is 0.
51
+ * @param values A single value to fill the range with, a grid of values, or a callback
52
+ * invoked per cell. Default is `null` (an empty range).
53
+ */
54
+ createRange<TS extends Scalar = Scalar>(rows?: number, columns?: number, values?: Scalar | Scalar[][] | ((value: TS, coords: IRange.CellCoords, range: IRange<TS>) => TS)): IRange;
55
+ /**
56
+ * Returns coordinates as an address string.
57
+ *
58
+ * @param coords The coordinates to get the address for. If not provided the current position is used.
59
+ * @param r1c1 If `true`, the address will be in R1C1 format. Default is `false` (A1 format).
60
+ */
61
+ getAddress(coords?: Readonly<IRange.FixableCoords | IRange.FixableCellCoords>, r1c1?: boolean): string;
62
+ /**
63
+ * Looks up another formula function so it can be called from yours.
64
+ *
65
+ * @param name The name of the function. Case-insensitive.
66
+ * @returns The function, or `null` if no function is registered under that name.
67
+ */
68
+ getFunction(name: string): IFunction | null;
69
+ /**
70
+ * Returns the coordinates of the entire sheet.
71
+ *
72
+ * @remarks
73
+ * Useful for bounds-checking a range before building it.
74
+ */
75
+ getEntireCoords(): IRange.Coords;
76
+ /**
77
+ * Formats a value with a number format, as a cell would display it.
78
+ *
79
+ * @param formatText The number format to apply.
80
+ * @param value The value to format.
81
+ * @returns The formatted text, or `null` if the format cannot be applied.
82
+ *
83
+ * @remarks
84
+ * This backs the `TEXT` function. For plain coercion to text use {@link toText}.
85
+ */
86
+ getNumberFormat(formatText: string, value: Scalar): string | null;
87
+ /**
88
+ * Returns the 0-based row of the cell being evaluated.
89
+ */
90
+ getRow(): number;
91
+ /**
92
+ * Returns the 0-based column of the cell being evaluated.
93
+ */
94
+ getColumn(): number;
95
+ /**
96
+ * Resolves a range reference at runtime, returning an {@link IReferenceRange}.
97
+ *
98
+ * Use this when the address is computed from arguments rather than known at parse time,
99
+ * as `INDIRECT`, `OFFSET`, and `SUMIF` do.
100
+ *
101
+ * @param coords The coordinates or address string of the range to resolve. If not provided
102
+ * the current location is used.
103
+ * @param r1c1 If `true`, the string is interpreted in R1C1 format.
104
+ * @returns An {@link IReferenceRange} representing the resolved range.
105
+ * @throws `#REF!` If the range cannot be parsed or resolved.
106
+ * @throws `#NAME?` If the string resolves to an unknown named formula or sheet.
107
+ *
108
+ * @remarks
109
+ * Each call adds a tracked dependency: the function is re-evaluated whenever the resolved
110
+ * range's data changes or its address moves. Prefer {@link getValueAt} when a plain value
111
+ * will do.
112
+ */
113
+ getReference(coords?: Readonly<IRange.Coords> | string, r1c1?: boolean): IReferenceRange<any>;
114
+ /**
115
+ * Resolves an ANCHOR-PLUS-LENGTH argument at runtime, returning an {@link IReferenceRange}
116
+ * clamped to the grid.
117
+ *
118
+ * A few arguments honor only their top-left corner and are re-sized to the shape of the range
119
+ * that drives them — `SUMIF`'s `sum_range`, `LOOKUP`'s `result_vector`. The window can therefore
120
+ * run off the bottom or right of the grid: `SUMIF(A1:A5,">0",A1048574)` asks for five rows
121
+ * starting three from the end. Excel reads the part that fits and treats the rest as blank, which
122
+ * is what this returns; positions past the clamp read as `undefined` from `getValueAt`.
123
+ *
124
+ * @param anchor The coords of the argument as written; only its top-left corner is honored.
125
+ * @param rowCount The height the driving range gives the window.
126
+ * @param colCount The width the driving range gives the window.
127
+ *
128
+ * @remarks
129
+ * Use {@link getReference} for a reference that is the function's RESULT: an unformable window is
130
+ * `#REF!` there rather than a short read. The clamp belongs to this handful of arguments only.
131
+ *
132
+ * The extent clamped against is the ANCHOR's sheet, which is not necessarily the sheet being
133
+ * evaluated — {@link getEntireCoords} answers for the latter.
134
+ */
135
+ getResizedReference(anchor: Readonly<IRange.Coords>, rowCount: number, colCount: number): IReferenceRange<any>;
136
+ /**
137
+ * Reads the formula text of a cell.
138
+ *
139
+ * @param row The row of the cell.
140
+ * @param column The column of the cell.
141
+ * @param sheetName The name of the sheet. If not provided the current sheet is used.
142
+ * @returns The formula text, or `null` if the cell has no formula.
143
+ */
144
+ getFormulaAt(row: number, column: number, sheetName?: string): string | null;
145
+ /**
146
+ * Returns the spill range anchored at a cell.
147
+ *
148
+ * @param row The row where the spill starts.
149
+ * @param column The column where the spill starts.
150
+ * @param sheetName The name of the sheet. If not provided the current sheet is used.
151
+ * @returns The spilled range, or `null` if nothing spills from that cell.
152
+ */
153
+ getSpillAt(row: number, column: number, sheetName?: string): IReferenceRange | null;
154
+ /**
155
+ * Reads the value of a cell.
156
+ *
157
+ * @param row The row of the cell.
158
+ * @param column The column of the cell.
159
+ * @param sheetName The name of the sheet. If not provided the current sheet is used.
160
+ * @param options Optional parameters for retrieving the value.
161
+ * @returns The value at the cell, or `null` if the cell is empty.
162
+ *
163
+ * @remarks
164
+ * Unlike {@link getReference}, this does not add a tracked dependency.
165
+ */
166
+ getValueAt(row: number, column: number, sheetName?: string, options?: IRange.ValueOptions): Scalar | null;
167
+ /**
168
+ * Returns the number of sheets in the workbook.
169
+ */
170
+ getSheetCount(): number | null;
171
+ /**
172
+ * Returns the 0-based index of a sheet.
173
+ *
174
+ * @param sheet The name of a sheet, or a reference to resolve to the sheet it is on.
175
+ * If not provided the current sheet is used.
176
+ * @returns -1 If the sheet does not exist.
177
+ */
178
+ getSheetIndex(sheet?: string | IReferenceRange): number;
179
+ /**
180
+ * Returns a copy of a range with hidden rows or columns removed.
181
+ *
182
+ * @param range The range to filter.
183
+ * @param axes Which axis to filter on. Default is `IRange.AxisSelection.Row`.
184
+ * @returns A new range without the hidden rows or columns.
185
+ *
186
+ * @remarks
187
+ * Use this for functions that ignore hidden data, such as `SUBTOTAL`.
188
+ */
189
+ filterHidden(range: IRange, axes?: IRange.AxisSelection): IRange;
190
+ /**
191
+ * Returns a copy of a range with any cell whose formula is a nested total removed.
192
+ *
193
+ * @param range The range to filter.
194
+ * @returns A new range without the nested totals, or `range` itself when there are none.
195
+ *
196
+ * @remarks
197
+ * Use this for functions that must not double-count a total that sits inside their own data —
198
+ * `SUBTOTAL` and `AGGREGATE`, which is also the pair being looked for. Excluding a cell and
199
+ * blanking it are equivalent for every code either function offers (all are order-independent
200
+ * and all ignore blanks), so removal is the simpler contract.
201
+ *
202
+ * A cell qualifies when its formula CALLS `SUBTOTAL` or `AGGREGATE` anywhere in its tree —
203
+ * `=SUM(SUBTOTAL(9,A1:A3))` is excluded — and not when it merely references one: `=A4`, where A4
204
+ * holds a subtotal, is ordinary data. `function_num` is irrelevant, and the two functions are
205
+ * symmetric (either excludes either).
206
+ *
207
+ * Exclusion is per CELL, not per row: with a subtotal in `A4` and a plain `99` in `B4`,
208
+ * `SUBTOTAL(9,A1:B4)` drops only `A4` and keeps the 99.
209
+ */
210
+ filterTotals(range: IRange): IRange;
211
+ /**
212
+ * Suggests a number format for this function's result.
213
+ *
214
+ * @param numFmt The number format to apply to the result.
215
+ *
216
+ * @remarks
217
+ * A hint, not a command — the format is applied only where the user has not already
218
+ * chosen one. When a range is returned every cell takes the same format.
219
+ */
220
+ formatResults(numFmt: string): void;
221
+ /**
222
+ * Marks this function as volatile, so it re-evaluates on every calculation.
223
+ *
224
+ * @remarks
225
+ * Call this when the result depends on something outside the arguments, such as the clock.
226
+ * A function can also be declared volatile in its registration instead.
227
+ */
228
+ markVolatile(): void;
229
+ /**
230
+ * Coerces a value to a serial date.
231
+ *
232
+ * @param textOrNumber The text or number to parse.
233
+ * @param requireDate If `true`, text must carry a date component; a time alone is rejected.
234
+ * @returns The serial date.
235
+ * @throws `#VALUE!` If the value cannot be read as a date.
236
+ * @throws The original error, unchanged, if the value is already an error (`#N/A` stays `#N/A`).
237
+ */
238
+ parseAsSerialDate(textOrNumber: Scalar, requireDate?: boolean): number;
239
+ /**
240
+ * Coerces a value to a JavaScript `Date`.
241
+ *
242
+ * @param serialOrString The serial number, text, or `Date` to parse.
243
+ * @param requireDate If `true`, text must carry a date component; a time alone is rejected.
244
+ * @returns The date.
245
+ * @throws `#VALUE!` If the value cannot be read as a date.
246
+ * @throws The original error, unchanged, if the value is already an error (`#N/A` stays `#N/A`).
247
+ *
248
+ * @remarks
249
+ * Prefer {@link getDateParts} for calendar arithmetic — see the note there.
250
+ */
251
+ parseAsDate(serialOrString: string | number | Date | any, requireDate?: boolean): Date;
252
+ /**
253
+ * Coerces a value to a number.
254
+ *
255
+ * @param textOrNumber The text or number to parse.
256
+ * @param options Additional parsing options.
257
+ * @returns The number.
258
+ * @throws `#VALUE!` If the value cannot be read as a number.
259
+ * @throws The original error, unchanged, if the value is already an error (`#N/A` stays `#N/A`).
260
+ */
261
+ parseAsNumber(textOrNumber: Scalar, options?: IFormulaContext.ParseNumberOptions): number;
262
+ /**
263
+ * `undefined` passes straight through, so an optional argument that was omitted stays omitted.
264
+ */
265
+ parseAsNumber(textOrNumber: Scalar | undefined, options?: IFormulaContext.ParseNumberOptions): number | undefined;
266
+ /**
267
+ * Compiles criteria text into a predicate.
268
+ *
269
+ * @param criteria The criteria, exactly as the user wrote it — a comparison (`">10"`, `"<>x"`),
270
+ * a wildcard pattern (`"a*"`), or a literal of any type.
271
+ * @returns A predicate to test cell values with. Call it once per cell.
272
+ *
273
+ * @remarks
274
+ * This is the rule behind `COUNTIF`/`SUMIF`/`AVERAGEIF`, their `*IFS` forms, and the `D`
275
+ * functions' criteria table, so reach for it in any function that takes a criteria rather than
276
+ * parsing one — a criteria touches all three localization planes at once (a number in the
277
+ * workbook's locale, a boolean word or error label in its language, text in its collation), and
278
+ * they are easy to get subtly wrong one at a time.
279
+ *
280
+ * Compile ONCE and apply the predicate across the range; the parse is not free, and a criteria
281
+ * does not vary per cell.
282
+ *
283
+ * Offer BLANK cells to the predicate rather than skipping them — a blank is what `""` and `"<>"`
284
+ * select, and `"<>x"` matches one too.
285
+ *
286
+ * @example
287
+ * ```typescript
288
+ * const matches = FormulaContext.createCriteria(">10");
289
+ * const count = range.reduce((total, value) => matches(value) ? total + 1 : total, 0);
290
+ * ```
291
+ */
292
+ createCriteria(criteria: Scalar): IFormulaContext.CriteriaEvaluator;
293
+ /**
294
+ * Reads a typed literal in the workbook's language — the parse side of {@link toText}.
295
+ *
296
+ * @param text The text to read.
297
+ * @returns The boolean or error the text spells, or `undefined` when it spells neither and is
298
+ * therefore just text.
299
+ *
300
+ * @remarks
301
+ * Booleans and error labels are the two values whose SPELLING follows the spreadsheet language
302
+ * rather than the workbook locale — `WAHR` is `TRUE` and `#WERT!` is `#VALUE!` in a German
303
+ * workbook, the same plane {@link toText} writes them on. Reach for this wherever a function
304
+ * interprets text the user typed; criteria (`COUNTIF(range, "WAHR")`) is the built-in case.
305
+ *
306
+ * The canonical English spelling is ALWAYS accepted alongside the localized one, so text that
307
+ * came from storage or an API reads the same under every language. This is how the formula
308
+ * compiler reads a typed literal, and matching it is the point.
309
+ *
310
+ * Numbers are not literals here. They follow the workbook LOCALE (the decimal separator) rather
311
+ * than the language, and belong to {@link parseAsNumber}.
312
+ */
313
+ parseAsLiteral(text: string): boolean | FormulaError.Known | undefined;
314
+ /**
315
+ * Coerces a value to text — the same rendering `&` and `CONCAT` produce.
316
+ *
317
+ * @param value The value to render. Text passes through unchanged, a blank
318
+ * (`null`/`undefined`) becomes `''`, and a boolean takes the workbook language's word
319
+ * (`TRUE`, `WAHR`). Numbers get 15 significant digits, plain decimal while the digits fit
320
+ * in 20 characters and scientific beyond that, using the workbook's decimal separator.
321
+ * @returns The rendered text.
322
+
323
+ * @remarks
324
+ * Reach for this whenever a function needs to treat an argument as text.
325
+ *
326
+ * This is coercion, not display. A cell's General format and `TEXT(value, "General")` are
327
+ * fitted to the column and round much harder — `TEXT(2^0.5, "General")` is `1.414213562`
328
+ * where coercion gives `1.4142135623731`. Use {@link getNumberFormat} when you want what
329
+ * the user sees.
330
+ */
331
+ toText(value: Scalar | undefined): string;
332
+ /**
333
+ * Orders two values the way the comparison operators do.
334
+ *
335
+ * @param a The left value.
336
+ * @param b The right value.
337
+ * @param options Overrides the collator strength. Text only — see remarks.
338
+ * @returns Negative, zero, or positive, like any JS comparator.
339
+ *
340
+ * @remarks
341
+ * This is the single rule behind `=`, `<>`, `<`, `<=`, `>`, `>=`, so use it for any
342
+ * comparison, equality included (`compare(a, b) === 0`). It ranks across types
343
+ * (`number` &lt; `text` &lt; `FALSE` &lt; `TRUE`) rather than coercing, reads a blank as
344
+ * the other operand's zero value, rounds numbers before comparing, and collates text
345
+ * case-insensitively in the workbook locale.
346
+ *
347
+ * Do not reach for `localeCompare` instead: it uses the host's locale rather than the
348
+ * workbook's, and does not sort the way a spreadsheet does.
349
+ *
350
+ * Errors order last so the comparator stays total, though operators never see that case —
351
+ * an error operand propagates first.
352
+ *
353
+ * `options` is for functions like `SORT` and `SORTBY` that expose case sensitivity as a
354
+ * user-facing toggle. It affects the text branch only; ranking, blanks, and numeric
355
+ * rounding are fixed.
356
+ */
357
+ compare(a: Scalar, b: Scalar, options?: Intl.CollatorOptions): number;
358
+ /**
359
+ * Returns the current date and time as a serial date.
360
+ *
361
+ * @returns The current date-time as a serial number.
362
+ *
363
+ * @remarks
364
+ * Always read the clock through this, never `Date.now()`. The time is fixed for the whole
365
+ * calculation pass, so every cell in one pass agrees, collaborators evaluating the same
366
+ * workbook agree, and tests can pin it. Pair it with {@link markVolatile} so the function
367
+ * picks up a fresh time on the next pass.
368
+ *
369
+ * This is a calendar clock, not a stopwatch — use `performance.now()` to measure elapsed time.
370
+ *
371
+ * @example
372
+ * ```typescript
373
+ * export function NOW(): number {
374
+ * FormulaContext.markVolatile();
375
+ * return FormulaContext.getNow();
376
+ * }
377
+ * ```
378
+ */
379
+ getNow(): number;
380
+ /**
381
+ * Returns `true` if the value is a usable date — either a `Date` or a number in the
382
+ * workbook's serial date range.
383
+ *
384
+ * @param value Any value to check.
385
+ * @param jsDateOnly If `true`, only a `Date` without a time component is accepted.
386
+ */
387
+ isValidDate(value: any, jsDateOnly?: boolean): boolean;
388
+ /**
389
+ * Converts a `Date` to a serial date.
390
+ *
391
+ * @param date The date to convert.
392
+ * @param dateOnly If `true`, the time of day is dropped and a whole-day serial is returned.
393
+ * Use this for calendar arithmetic (day counts, coupon schedules) so a stray time component
394
+ * cannot leak into the result.
395
+ *
396
+ * @remarks
397
+ * Serial dates are wall-clock: the date's local fields become the serial and no timezone
398
+ * enters the conversion. Read such dates back with `getFullYear`/`getMonth`/`getDate`,
399
+ * never the `getUTC*` accessors.
400
+ */
401
+ toSerialDate(date: Date, dateOnly?: boolean): number;
402
+ /**
403
+ * Converts a serial date to a `Date`.
404
+ *
405
+ * @param serialDate The serial date to convert.
406
+ * @param dateOnly If `true`, the fractional part is dropped and the time is midnight.
407
+ *
408
+ * @remarks
409
+ * The serial becomes the date's local fields — see {@link toSerialDate}. For date
410
+ * arithmetic prefer {@link getDateParts}.
411
+ */
412
+ fromSerialDate(serialDate: number, dateOnly?: boolean): Date;
413
+ /**
414
+ * Splits a serial date into its calendar and clock fields.
415
+ *
416
+ * @param serialDate The serial date to split.
417
+ * @param reuseParts Avoids allocating a fresh {@link IFormulaContext.DateParts}:
418
+ * - An object: the fields are written into THIS object, which is returned. The caller owns
419
+ * the buffer's lifetime — do not hold onto a previous result across a reused call, each
420
+ * call overwrites it in place. For code that calls this once per cell over a large range.
421
+ * - `true`: the fields are written into a shared scratch object and returned — for a
422
+ * one-off caller (a single-value function like `YEAR`/`MONTH`/`DAY`) that just wants to
423
+ * avoid the allocation without owning a buffer itself. The result must be consumed
424
+ * immediately (read a field, done) — a second `true` call anywhere overwrites it.
425
+ * @throws `#NUM!` If the serial falls outside the workbook's calendar.
426
+ *
427
+ * @remarks
428
+ * Prefer this to {@link fromSerialDate} inside date functions. The spreadsheet calendar
429
+ * has two days a JS `Date` cannot hold — serial 0 (`1900-01-00`) and the legacy
430
+ * `1900-02-29` at serial 60 — and converting to a `Date` silently shifts them.
431
+ * {@link IFormulaContext.DateParts} is plain numbers and represents both.
432
+ */
433
+ getDateParts(serialDate: number, reuseParts?: IFormulaContext.DateParts | boolean): IFormulaContext.DateParts;
434
+ /**
435
+ * Builds a serial date from calendar and clock fields — the inverse of {@link getDateParts}.
436
+ *
437
+ * @remarks
438
+ * Fields may fall outside their normal range and carry, which is what makes `DATE` and
439
+ * `TIME` arithmetic work: month 13 is January of the next year, hour 50 is two days plus
440
+ * two hours, and `getSerialDate(1900, 1, 0)` is serial 0. The `day` carries in SERIAL
441
+ * space, so it runs through the phantom `1900-02-29` — measured 25/25 by
442
+ * `probe-date-1900-day-overflow.ps1`.
443
+ *
444
+ * **This validates nothing, and that is deliberate — a caller MUST choose its own
445
+ * policy.** No range check, no clamping, no bounds on any field, and no `DATE`-style
446
+ * `0..1899 -> +1900` year offset. Those belong to `DATE`'s ARGUMENTS, not to the
447
+ * calendar, and the three things that prove it were measured together
448
+ * (`probe-date-arg-layer.ps1`, 2026-08-20):
449
+ *
450
+ * * **The day policy is the caller's.** `DATE` and `DATEDIF`'s `md`/`yd` re-anchoring
451
+ * want the raw carry above — `DATEDIF("2020-01-31","2020-03-01","md")` is `-1`
452
+ * because Jan 31 rolls into March. `EDATE`/`EOMONTH` want the opposite and CLAMP to
453
+ * the target month's length, so they pre-clamp before calling here. One conversion,
454
+ * two opposite rules, both matching Excel. Baking either one in breaks the other.
455
+ * * **Results may legitimately leave the calendar.** `YEARFRAC` basis 1 anchors a year
456
+ * length on January 1 of `laterYear + 1`, which at the top of the calendar is
457
+ * `10000-01-01`; Excel answers `1.9972602739726026` for
458
+ * `YEARFRAC(DATE(9998,1,1),DATE(9999,12,31),1)` rather than `#NUM!`. A range check
459
+ * here would break it.
460
+ * * **The 16-bit argument limits are per-function.** `DATE`'s month errors outside
461
+ * `[-32767, 32766]` while its day saturates to `32767`, and `TIME` errors outside
462
+ * `[0, 32767]` on every argument — same magic number, three different rules.
463
+ *
464
+ * Note the asymmetry with {@link getDateParts}, which DOES throw `#NUM!` outside the
465
+ * calendar because it answers a user-facing question. An internal intermediate that
466
+ * steps one day past the end must therefore not be round-tripped through it; compute
467
+ * on the fields instead. That mistake made `YEARFRAC(DATE(9999,1,1),DATE(9999,12,31),0)`
468
+ * `#NUM!` where Excel says `1`.
469
+ */
470
+ getSerialDate(year: number, month: number, day: number, hour?: number, minute?: number, second?: number, millis?: number): number;
471
+ /**
472
+ * Returns information about the environment the formula is running in.
473
+ *
474
+ * @remarks
475
+ * Mostly for diagnostics; the built-in `INFO` function is built on it.
476
+ */
477
+ getRuntime(): IRuntime;
478
+ }
479
+ /**
480
+ * {@inheritDoc IFormulaContext}
481
+ *
482
+ * @see
483
+ * ### **Interface**
484
+ *
485
+ * {@link IFormulaContext}
486
+ */
487
+ export declare namespace IFormulaContext {
488
+ /**
489
+ * Options for {@link IFormulaContext.parseAsNumber}.
490
+ */
491
+ interface ParseNumberOptions {
492
+ }
493
+ /**
494
+ * The predicate {@link IFormulaContext.createCriteria} returns.
495
+ *
496
+ * @remarks
497
+ * A blank cell arrives as `null` and is a meaningful input, not a value to skip — see the note
498
+ * there.
499
+ */
500
+ type CriteriaEvaluator = (value: Scalar) => boolean;
501
+ /**
502
+ * A serial date split into fields — see {@link IFormulaContext.getDateParts}.
503
+ *
504
+ * @remarks
505
+ * These are the spreadsheet calendar's fields, not the Gregorian one's: `day` may be
506
+ * `0` (`1900-01-00`) and February 1900 has 29 days.
507
+ */
508
+ interface DateParts {
509
+ /** Full year. */
510
+ readonly year: number;
511
+ /** 1 = January ... 12 = December. */
512
+ readonly month: number;
513
+ /** Day of month, 1-based. `0` for `1900-01-00`. */
514
+ readonly day: number;
515
+ /** Hour on a 24-hour clock. */
516
+ readonly hour: number;
517
+ /** Minute of the hour. */
518
+ readonly minute: number;
519
+ /** Second of the minute. */
520
+ readonly second: number;
521
+ /** Milliseconds. */
522
+ readonly millis: number;
523
+ /**
524
+ * Day of week, 1 = Monday ... 7 = Sunday.
525
+ *
526
+ * @remarks
527
+ * Derived from the serial throughout, so below serial 61 it follows the legacy
528
+ * calendar rather than the real one. This is the same value `ddd`/`dddd` render.
529
+ */
530
+ readonly dow: number;
531
+ }
532
+ }
533
+ //# sourceMappingURL=IFormulaContext.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IFormulaContext.d.ts","sourceRoot":"","sources":["../../../src/IFormulaContext.ts"],"names":[],"mappings":"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"}