@affino/datagrid-formula-engine 0.1.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 (124) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +38 -0
  3. package/dist/analysis/index.d.ts +2 -0
  4. package/dist/analysis/index.d.ts.map +1 -0
  5. package/dist/analysis/index.js +1 -0
  6. package/dist/analysis/types.d.ts +44 -0
  7. package/dist/analysis/types.d.ts.map +1 -0
  8. package/dist/analysis/types.js +1 -0
  9. package/dist/contracts.d.ts +177 -0
  10. package/dist/contracts.d.ts.map +1 -0
  11. package/dist/contracts.js +140 -0
  12. package/dist/coreTypes.d.ts +2 -0
  13. package/dist/coreTypes.d.ts.map +1 -0
  14. package/dist/coreTypes.js +1 -0
  15. package/dist/dependency/index.d.ts +2 -0
  16. package/dist/dependency/index.d.ts.map +1 -0
  17. package/dist/dependency/index.js +1 -0
  18. package/dist/evaluators/columnar.d.ts +6 -0
  19. package/dist/evaluators/columnar.d.ts.map +1 -0
  20. package/dist/evaluators/columnar.js +39 -0
  21. package/dist/evaluators/index.d.ts +5 -0
  22. package/dist/evaluators/index.d.ts.map +1 -0
  23. package/dist/evaluators/index.js +4 -0
  24. package/dist/evaluators/interpreter.d.ts +6 -0
  25. package/dist/evaluators/interpreter.d.ts.map +1 -0
  26. package/dist/evaluators/interpreter.js +156 -0
  27. package/dist/evaluators/jit.d.ts +7 -0
  28. package/dist/evaluators/jit.d.ts.map +1 -0
  29. package/dist/evaluators/jit.js +158 -0
  30. package/dist/evaluators/shared.d.ts +36 -0
  31. package/dist/evaluators/shared.d.ts.map +1 -0
  32. package/dist/evaluators/shared.js +242 -0
  33. package/dist/evaluators/vector.d.ts +6 -0
  34. package/dist/evaluators/vector.d.ts.map +1 -0
  35. package/dist/evaluators/vector.js +228 -0
  36. package/dist/formulaEngine/compile.d.ts +2 -0
  37. package/dist/formulaEngine/compile.d.ts.map +1 -0
  38. package/dist/formulaEngine/compile.js +1 -0
  39. package/dist/formulaEngine/core.d.ts +2 -0
  40. package/dist/formulaEngine/core.d.ts.map +1 -0
  41. package/dist/formulaEngine/core.js +1 -0
  42. package/dist/formulaEngine/evaluators.d.ts +2 -0
  43. package/dist/formulaEngine/evaluators.d.ts.map +1 -0
  44. package/dist/formulaEngine/evaluators.js +1 -0
  45. package/dist/formulaEngine/index.d.ts +5 -0
  46. package/dist/formulaEngine/index.d.ts.map +1 -0
  47. package/dist/formulaEngine/index.js +2 -0
  48. package/dist/formulaExecutionPlan.d.ts +2 -0
  49. package/dist/formulaExecutionPlan.d.ts.map +1 -0
  50. package/dist/formulaExecutionPlan.js +1 -0
  51. package/dist/graph/executionPlan.d.ts +66 -0
  52. package/dist/graph/executionPlan.d.ts.map +1 -0
  53. package/dist/graph/executionPlan.js +534 -0
  54. package/dist/graph/index.d.ts +2 -0
  55. package/dist/graph/index.d.ts.map +1 -0
  56. package/dist/graph/index.js +3 -0
  57. package/dist/index.d.ts +8 -0
  58. package/dist/index.d.ts.map +1 -0
  59. package/dist/index.js +4 -0
  60. package/dist/runtime/compile.d.ts +7 -0
  61. package/dist/runtime/compile.d.ts.map +1 -0
  62. package/dist/runtime/compile.js +453 -0
  63. package/dist/runtime/evaluators.d.ts +5 -0
  64. package/dist/runtime/evaluators.d.ts.map +1 -0
  65. package/dist/runtime/evaluators.js +6 -0
  66. package/dist/runtime/index.d.ts +3 -0
  67. package/dist/runtime/index.d.ts.map +1 -0
  68. package/dist/runtime/index.js +2 -0
  69. package/dist/runtime/types.d.ts +63 -0
  70. package/dist/runtime/types.d.ts.map +1 -0
  71. package/dist/runtime/types.js +1 -0
  72. package/dist/syntax/analysis.d.ts +14 -0
  73. package/dist/syntax/analysis.d.ts.map +1 -0
  74. package/dist/syntax/analysis.js +159 -0
  75. package/dist/syntax/ast.d.ts +18 -0
  76. package/dist/syntax/ast.d.ts.map +1 -0
  77. package/dist/syntax/ast.js +54 -0
  78. package/dist/syntax/core.d.ts +4 -0
  79. package/dist/syntax/core.d.ts.map +1 -0
  80. package/dist/syntax/core.js +1 -0
  81. package/dist/syntax/functionGroups/advancedFunctions.d.ts +2 -0
  82. package/dist/syntax/functionGroups/advancedFunctions.d.ts.map +1 -0
  83. package/dist/syntax/functionGroups/advancedFunctions.js +252 -0
  84. package/dist/syntax/functionGroups/dateFunctions.d.ts +2 -0
  85. package/dist/syntax/functionGroups/dateFunctions.d.ts.map +1 -0
  86. package/dist/syntax/functionGroups/dateFunctions.js +144 -0
  87. package/dist/syntax/functionGroups/logicFunctions.d.ts +2 -0
  88. package/dist/syntax/functionGroups/logicFunctions.d.ts.map +1 -0
  89. package/dist/syntax/functionGroups/logicFunctions.js +140 -0
  90. package/dist/syntax/functionGroups/numericFunctions.d.ts +2 -0
  91. package/dist/syntax/functionGroups/numericFunctions.d.ts.map +1 -0
  92. package/dist/syntax/functionGroups/numericFunctions.js +268 -0
  93. package/dist/syntax/functionGroups/textFunctions.d.ts +2 -0
  94. package/dist/syntax/functionGroups/textFunctions.d.ts.map +1 -0
  95. package/dist/syntax/functionGroups/textFunctions.js +118 -0
  96. package/dist/syntax/functionHelpers.d.ts +45 -0
  97. package/dist/syntax/functionHelpers.d.ts.map +1 -0
  98. package/dist/syntax/functionHelpers.js +553 -0
  99. package/dist/syntax/functions.d.ts +9 -0
  100. package/dist/syntax/functions.d.ts.map +1 -0
  101. package/dist/syntax/functions.js +139 -0
  102. package/dist/syntax/index.d.ts +10 -0
  103. package/dist/syntax/index.d.ts.map +1 -0
  104. package/dist/syntax/index.js +7 -0
  105. package/dist/syntax/legacy.d.ts +29 -0
  106. package/dist/syntax/legacy.d.ts.map +1 -0
  107. package/dist/syntax/legacy.js +188 -0
  108. package/dist/syntax/optimizer.d.ts +6 -0
  109. package/dist/syntax/optimizer.d.ts.map +1 -0
  110. package/dist/syntax/optimizer.js +362 -0
  111. package/dist/syntax/parser.d.ts +7 -0
  112. package/dist/syntax/parser.d.ts.map +1 -0
  113. package/dist/syntax/parser.js +239 -0
  114. package/dist/syntax/tokenizer.d.ts +14 -0
  115. package/dist/syntax/tokenizer.d.ts.map +1 -0
  116. package/dist/syntax/tokenizer.js +852 -0
  117. package/dist/syntax/types.d.ts +120 -0
  118. package/dist/syntax/types.d.ts.map +1 -0
  119. package/dist/syntax/types.js +1 -0
  120. package/dist/syntax/values.d.ts +25 -0
  121. package/dist/syntax/values.d.ts.map +1 -0
  122. package/dist/syntax/values.js +270 -0
  123. package/dist/tsconfig.tsbuildinfo +1 -0
  124. package/package.json +42 -0
@@ -0,0 +1,159 @@
1
+ import { collectFormulaContextKeys, normalizeFormulaFieldName, normalizeFormulaFunctionRegistry, normalizeFormulaText, } from "./functions.js";
2
+ import { normalizeFormulaDiagnostic, } from "./ast.js";
3
+ import { parseFormula } from "./parser.js";
4
+ import { tokenizeFormula } from "./tokenizer.js";
5
+ import { collectFormulaIdentifiers, validateFormulaFunctions, foldFormulaConstants, } from "./optimizer.js";
6
+ import { parseDataGridComputedDependencyToken as parseDependencyToken } from "../contracts.js";
7
+ function dedupeFormulaIdentifiers(root) {
8
+ const references = [];
9
+ collectFormulaIdentifiers(root, references);
10
+ const identifiers = [];
11
+ const seenIdentifiers = new Set();
12
+ for (const reference of references) {
13
+ const normalized = reference.trim();
14
+ if (normalized.length === 0 || seenIdentifiers.has(normalized)) {
15
+ continue;
16
+ }
17
+ seenIdentifiers.add(normalized);
18
+ identifiers.push(normalized);
19
+ }
20
+ return Object.freeze(identifiers);
21
+ }
22
+ function normalizeFormulaExplainDependency(identifier, token) {
23
+ const parsedToken = parseDependencyToken(token);
24
+ if (parsedToken) {
25
+ return {
26
+ identifier,
27
+ token,
28
+ domain: parsedToken.domain,
29
+ value: parsedToken.name,
30
+ ...(parsedToken.rowDomain.kind === "current"
31
+ ? null
32
+ : { rowSelector: parsedToken.rowDomain }),
33
+ };
34
+ }
35
+ const normalizedToken = typeof token === "string" ? token.trim() : "";
36
+ if (normalizedToken.startsWith("field:")) {
37
+ return { identifier, token, domain: "field", value: normalizedToken.slice("field:".length) };
38
+ }
39
+ if (normalizedToken.startsWith("computed:")) {
40
+ return { identifier, token, domain: "computed", value: normalizedToken.slice("computed:".length) };
41
+ }
42
+ if (normalizedToken.startsWith("meta:")) {
43
+ return { identifier, token, domain: "meta", value: normalizedToken.slice("meta:".length) };
44
+ }
45
+ return {
46
+ identifier,
47
+ token,
48
+ domain: "unknown",
49
+ value: normalizedToken.length > 0 ? normalizedToken : String(token),
50
+ };
51
+ }
52
+ function createFormulaExplainNode(root) {
53
+ var _a;
54
+ if (root.kind === "number") {
55
+ return { kind: root.kind, label: String(root.value), span: root.span, children: [], value: root.value };
56
+ }
57
+ if (root.kind === "literal") {
58
+ return { kind: root.kind, label: "literal", span: root.span, children: [], value: root.value };
59
+ }
60
+ if (root.kind === "identifier") {
61
+ return {
62
+ kind: root.kind,
63
+ label: root.name,
64
+ span: root.span,
65
+ children: [],
66
+ name: root.name,
67
+ sheetReference: root.sheetReference,
68
+ referenceName: root.referenceName,
69
+ rangeReferenceName: (_a = root.rangeReferenceName) !== null && _a !== void 0 ? _a : null,
70
+ rowSelector: root.rowSelector,
71
+ };
72
+ }
73
+ if (root.kind === "call") {
74
+ return {
75
+ kind: root.kind,
76
+ label: `${root.name}()`,
77
+ span: root.span,
78
+ children: root.args.map(createFormulaExplainNode),
79
+ name: root.name,
80
+ operator: "CALL",
81
+ };
82
+ }
83
+ if (root.kind === "unary") {
84
+ return {
85
+ kind: root.kind,
86
+ label: root.operator,
87
+ span: root.span,
88
+ children: [createFormulaExplainNode(root.value)],
89
+ operator: root.operator,
90
+ };
91
+ }
92
+ return {
93
+ kind: root.kind,
94
+ label: root.operator,
95
+ span: root.span,
96
+ children: [createFormulaExplainNode(root.left), createFormulaExplainNode(root.right)],
97
+ operator: root.operator,
98
+ };
99
+ }
100
+ function dedupeFormulaContextKeys(root, functionRegistry) {
101
+ const contextKeys = [];
102
+ collectFormulaContextKeys(root, functionRegistry, contextKeys);
103
+ return Object.freeze(Array.from(new Set(contextKeys.map(key => key.trim()).filter(key => key.length > 0))));
104
+ }
105
+ export function parseDataGridFormulaExpression(formula, options = {}) {
106
+ const normalizedFormula = normalizeFormulaText(formula);
107
+ const tokens = tokenizeFormula(normalizedFormula, options.referenceParserOptions);
108
+ const ast = parseFormula(tokens, options.referenceParserOptions);
109
+ return { formula: normalizedFormula, tokens, ast };
110
+ }
111
+ export function diagnoseDataGridFormulaExpression(formula, options = {}) {
112
+ const normalizedFormula = normalizeFormulaText(formula);
113
+ try {
114
+ const tokens = tokenizeFormula(normalizedFormula, options.referenceParserOptions);
115
+ const ast = parseFormula(tokens, options.referenceParserOptions);
116
+ const functionRegistry = normalizeFormulaFunctionRegistry(options.functionRegistry, {
117
+ onFunctionOverride: options.onFunctionOverride,
118
+ });
119
+ validateFormulaFunctions(ast, functionRegistry);
120
+ return { ok: true, formula: normalizedFormula, diagnostics: [], tokens, ast };
121
+ }
122
+ catch (error) {
123
+ return { ok: false, formula: normalizedFormula, diagnostics: [normalizeFormulaDiagnostic(error)] };
124
+ }
125
+ }
126
+ export function explainDataGridFormulaExpression(formula, options = {}) {
127
+ var _a;
128
+ const normalizedFormula = normalizeFormulaText(formula);
129
+ const tokens = tokenizeFormula(normalizedFormula, options.referenceParserOptions);
130
+ const ast = parseFormula(tokens, options.referenceParserOptions);
131
+ const optimizedAst = foldFormulaConstants(ast);
132
+ const identifiers = dedupeFormulaIdentifiers(optimizedAst);
133
+ const functionRegistry = normalizeFormulaFunctionRegistry(options.functionRegistry, {
134
+ onFunctionOverride: options.onFunctionOverride,
135
+ });
136
+ validateFormulaFunctions(optimizedAst, functionRegistry);
137
+ const resolveDependencyToken = (_a = options.resolveDependencyToken) !== null && _a !== void 0 ? _a : ((identifier) => `field:${identifier}`);
138
+ const dependencies = identifiers.map(identifier => normalizeFormulaExplainDependency(identifier, resolveDependencyToken(identifier)));
139
+ return {
140
+ formula: normalizedFormula,
141
+ tokens,
142
+ ast: optimizedAst,
143
+ identifiers,
144
+ dependencies,
145
+ contextKeys: dedupeFormulaContextKeys(optimizedAst, functionRegistry),
146
+ tree: createFormulaExplainNode(optimizedAst),
147
+ };
148
+ }
149
+ export function explainDataGridFormulaFieldDefinition(definition, options = {}) {
150
+ var _a;
151
+ const name = normalizeFormulaFieldName(definition.name, "Formula name");
152
+ const field = normalizeFormulaFieldName((_a = definition.field) !== null && _a !== void 0 ? _a : name, "Formula target field");
153
+ const explained = explainDataGridFormulaExpression(definition.formula, options);
154
+ return {
155
+ name,
156
+ field,
157
+ ...explained,
158
+ };
159
+ }
@@ -0,0 +1,18 @@
1
+ import type { DataGridFormulaRuntimeError } from "../coreTypes.js";
2
+ import type { DataGridFormulaAstNode, DataGridFormulaDiagnostic, DataGridFormulaSourceSpan } from "./types.js";
3
+ export type { DataGridFormulaSourceSpan, DataGridFormulaOperator, DataGridFormulaToken, DataGridFormulaAstNode, DataGridFormulaDiagnostic, } from "./types.js";
4
+ export type { DataGridFormulaExplainNode } from "../analysis/types.js";
5
+ export declare class DataGridFormulaEvaluationError extends Error {
6
+ readonly runtimeError: DataGridFormulaRuntimeError;
7
+ constructor(runtimeError: DataGridFormulaRuntimeError);
8
+ }
9
+ export declare class DataGridFormulaSyntaxError extends Error {
10
+ readonly span: DataGridFormulaSourceSpan;
11
+ constructor(message: string, span: DataGridFormulaSourceSpan);
12
+ }
13
+ export declare function createFormulaSourceSpan(start: number, end: number): DataGridFormulaSourceSpan;
14
+ export declare function getFormulaNodeSpan(node: DataGridFormulaAstNode): DataGridFormulaSourceSpan;
15
+ export declare function throwFormulaError(message: string, span?: DataGridFormulaSourceSpan): never;
16
+ export declare function createFormulaDiagnostic(message: string, span: DataGridFormulaSourceSpan): DataGridFormulaDiagnostic;
17
+ export declare function normalizeFormulaDiagnostic(error: unknown): DataGridFormulaDiagnostic;
18
+ //# sourceMappingURL=ast.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ast.d.ts","sourceRoot":"","sources":["../../src/syntax/ast.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,iBAAiB,CAAA;AAClE,OAAO,KAAK,EACV,sBAAsB,EACtB,yBAAyB,EACzB,yBAAyB,EAC1B,MAAM,YAAY,CAAA;AACnB,YAAY,EACV,yBAAyB,EACzB,uBAAuB,EACvB,oBAAoB,EACpB,sBAAsB,EACtB,yBAAyB,GAC1B,MAAM,YAAY,CAAA;AACnB,YAAY,EAAE,0BAA0B,EAAE,MAAM,sBAAsB,CAAA;AAEtE,qBAAa,8BAA+B,SAAQ,KAAK;IACvD,QAAQ,CAAC,YAAY,EAAE,2BAA2B,CAAA;gBAEtC,YAAY,EAAE,2BAA2B;CAKtD;AAED,qBAAa,0BAA2B,SAAQ,KAAK;IACnD,QAAQ,CAAC,IAAI,EAAE,yBAAyB,CAAA;gBAE5B,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,yBAAyB;CAK7D;AAED,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,yBAAyB,CAI7F;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,sBAAsB,GAAG,yBAAyB,CAE1F;AAED,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,yBAAyD,GAC9D,KAAK,CAEP;AAED,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,yBAAyB,GAC9B,yBAAyB,CAM3B;AAED,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,OAAO,GAAG,yBAAyB,CASpF"}
@@ -0,0 +1,54 @@
1
+ export class DataGridFormulaEvaluationError extends Error {
2
+ constructor(runtimeError) {
3
+ super(runtimeError.message);
4
+ Object.defineProperty(this, "runtimeError", {
5
+ enumerable: true,
6
+ configurable: true,
7
+ writable: true,
8
+ value: void 0
9
+ });
10
+ this.name = "DataGridFormulaEvaluationError";
11
+ this.runtimeError = runtimeError;
12
+ }
13
+ }
14
+ export class DataGridFormulaSyntaxError extends Error {
15
+ constructor(message, span) {
16
+ super(message);
17
+ Object.defineProperty(this, "span", {
18
+ enumerable: true,
19
+ configurable: true,
20
+ writable: true,
21
+ value: void 0
22
+ });
23
+ this.name = "DataGridFormulaSyntaxError";
24
+ this.span = span;
25
+ }
26
+ }
27
+ export function createFormulaSourceSpan(start, end) {
28
+ const normalizedStart = Math.max(0, Math.trunc(start));
29
+ const normalizedEnd = Math.max(normalizedStart, Math.trunc(end));
30
+ return { start: normalizedStart, end: normalizedEnd };
31
+ }
32
+ export function getFormulaNodeSpan(node) {
33
+ return node.span;
34
+ }
35
+ export function throwFormulaError(message, span = createFormulaSourceSpan(0, 0)) {
36
+ throw new DataGridFormulaSyntaxError(`[DataGridFormula] ${message}`, span);
37
+ }
38
+ export function createFormulaDiagnostic(message, span) {
39
+ return {
40
+ severity: "error",
41
+ message,
42
+ span,
43
+ };
44
+ }
45
+ export function normalizeFormulaDiagnostic(error) {
46
+ if (error instanceof DataGridFormulaSyntaxError) {
47
+ return createFormulaDiagnostic(error.message, error.span);
48
+ }
49
+ if (error instanceof DataGridFormulaEvaluationError) {
50
+ return createFormulaDiagnostic(error.runtimeError.message, createFormulaSourceSpan(0, 0));
51
+ }
52
+ const message = error instanceof Error ? error.message : String(error !== null && error !== void 0 ? error : "Formula diagnostics failed.");
53
+ return createFormulaDiagnostic(message, createFormulaSourceSpan(0, 0));
54
+ }
@@ -0,0 +1,4 @@
1
+ export * from "./analysis.js";
2
+ export type { DataGridCompiledFormulaArtifact, DataGridCompiledFormulaBatchContext, DataGridCompiledFormulaBatchExecutionMode, DataGridCompiledFormulaField, DataGridFormulaBatchEvaluator, DataGridFormulaColumnarBatchEvaluator, DataGridFormulaCompileOptions, DataGridFormulaCompileStrategy, DataGridFormulaEvaluator, DataGridFormulaEvaluatorForToken, DataGridFormulaExpressionAnalysis, DataGridFormulaFunctionRuntime, DataGridFormulaParseResult, DataGridFormulaRuntimeErrorPolicy, DataGridFormulaTokenIndexEvaluator, DataGridFormulaTokenValueReader, } from "../runtime/types.js";
3
+ export type { DataGridFormulaDiagnosticsResult, DataGridFormulaExplainDependency, DataGridFormulaExplainDependencyDomain, DataGridFormulaExplainNode, DataGridFormulaExplainResult, DataGridFormulaFieldExplainResult, } from "../analysis/types.js";
4
+ //# sourceMappingURL=core.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../../src/syntax/core.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAA;AAE7B,YAAY,EACX,+BAA+B,EAC/B,mCAAmC,EACnC,yCAAyC,EACzC,4BAA4B,EAC5B,6BAA6B,EAC7B,qCAAqC,EACrC,6BAA6B,EAC7B,8BAA8B,EAC9B,wBAAwB,EACxB,gCAAgC,EAChC,iCAAiC,EACjC,8BAA8B,EAC9B,0BAA0B,EAC1B,iCAAiC,EACjC,kCAAkC,EAClC,+BAA+B,GAC/B,MAAM,qBAAqB,CAAA;AAE5B,YAAY,EACX,gCAAgC,EAChC,gCAAgC,EAChC,sCAAsC,EACtC,0BAA0B,EAC1B,4BAA4B,EAC5B,iCAAiC,GACjC,MAAM,sBAAsB,CAAA"}
@@ -0,0 +1 @@
1
+ export * from "./analysis.js";
@@ -0,0 +1,2 @@
1
+ export declare const DATAGRID_ADVANCED_FORMULA_FUNCTIONS: Readonly<Record<string, import("../types.js").DataGridFormulaFunctionDefinition>>;
2
+ //# sourceMappingURL=advancedFunctions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"advancedFunctions.d.ts","sourceRoot":"","sources":["../../../src/syntax/functionGroups/advancedFunctions.ts"],"names":[],"mappings":"AAkEA,eAAO,MAAM,mCAAmC,mFAgN9C,CAAA"}
@@ -0,0 +1,252 @@
1
+ import { areFormulaValuesEqual, coerceFormulaValueToNumber, compareFormulaValues, } from "../values.js";
2
+ import { collectFilteredValues, collectFormulaTableRelatedValues, collectFormulaTableValues, collectValuesFromArgs, computeAverage, createFormulaTableContextKey, defineFormulaFunctions, expandFormulaValue, formulaValueMatchesCriterion, normalizeFormulaTableName, resolveFormulaLiteralText, stringifyFormulaScalarValue, toDistinctFormulaValues, toNumericFormulaValues, } from "../functionHelpers.js";
3
+ function resolveFormulaRelationAggregateMethod(value) {
4
+ var _a;
5
+ if (Array.isArray(value)) {
6
+ return resolveFormulaRelationAggregateMethod((_a = value[0]) !== null && _a !== void 0 ? _a : "");
7
+ }
8
+ return String(value !== null && value !== void 0 ? value : "").trim().toLowerCase();
9
+ }
10
+ function computeFormulaRelationRollupValue(values, methodValue, emptyValue) {
11
+ var _a, _b, _c;
12
+ const method = resolveFormulaRelationAggregateMethod(methodValue);
13
+ switch (method) {
14
+ case "count":
15
+ return values.length;
16
+ case "sum":
17
+ return toNumericFormulaValues(values).reduce((sum, value) => sum + value, 0);
18
+ case "avg":
19
+ case "average":
20
+ return computeAverage(values);
21
+ case "min":
22
+ if (values.length === 0) {
23
+ return emptyValue !== null && emptyValue !== void 0 ? emptyValue : 0;
24
+ }
25
+ return (_a = [...values].sort((left, right) => compareFormulaValues(left, right))[0]) !== null && _a !== void 0 ? _a : (emptyValue !== null && emptyValue !== void 0 ? emptyValue : 0);
26
+ case "max":
27
+ if (values.length === 0) {
28
+ return emptyValue !== null && emptyValue !== void 0 ? emptyValue : 0;
29
+ }
30
+ return (_b = [...values].sort((left, right) => compareFormulaValues(right, left))[0]) !== null && _b !== void 0 ? _b : (emptyValue !== null && emptyValue !== void 0 ? emptyValue : 0);
31
+ case "join":
32
+ return values
33
+ .map(value => stringifyFormulaScalarValue(value))
34
+ .filter(value => value.length > 0)
35
+ .join(", ");
36
+ case "first":
37
+ default:
38
+ return (_c = values[0]) !== null && _c !== void 0 ? _c : (emptyValue !== null && emptyValue !== void 0 ? emptyValue : null);
39
+ }
40
+ }
41
+ export const DATAGRID_ADVANCED_FORMULA_FUNCTIONS = defineFormulaFunctions({
42
+ ARRAY: {
43
+ compute: args => Object.freeze([...collectValuesFromArgs(args)]),
44
+ },
45
+ AVERAGEIF: {
46
+ arity: { min: 2, max: 3 },
47
+ compute: args => {
48
+ var _a, _b, _c, _d;
49
+ const criteriaRange = expandFormulaValue((_a = args[0]) !== null && _a !== void 0 ? _a : null);
50
+ const criterion = (_b = args[1]) !== null && _b !== void 0 ? _b : null;
51
+ const averageRange = expandFormulaValue((_d = (_c = args[2]) !== null && _c !== void 0 ? _c : args[0]) !== null && _d !== void 0 ? _d : null);
52
+ return computeAverage(collectFilteredValues(averageRange, [{ range: criteriaRange, criterion }]));
53
+ },
54
+ },
55
+ CHOOSE: {
56
+ arity: { min: 2 },
57
+ compute: args => {
58
+ var _a, _b;
59
+ const index = Math.trunc(coerceFormulaValueToNumber((_a = args[0]) !== null && _a !== void 0 ? _a : null));
60
+ if (index < 1 || index >= args.length) {
61
+ return 0;
62
+ }
63
+ return (_b = args[index]) !== null && _b !== void 0 ? _b : 0;
64
+ },
65
+ },
66
+ COLLECT: {
67
+ arity: { min: 3 },
68
+ compute: args => {
69
+ var _a, _b, _c;
70
+ const values = expandFormulaValue((_a = args[0]) !== null && _a !== void 0 ? _a : null);
71
+ const criteria = [];
72
+ for (let index = 1; index < args.length; index += 2) {
73
+ criteria.push({
74
+ range: expandFormulaValue((_b = args[index]) !== null && _b !== void 0 ? _b : null),
75
+ criterion: ((_c = args[index + 1]) !== null && _c !== void 0 ? _c : null),
76
+ });
77
+ }
78
+ return Object.freeze([...collectFilteredValues(values, criteria)]);
79
+ },
80
+ },
81
+ COUNTIFS: {
82
+ arity: { min: 2 },
83
+ compute: args => {
84
+ var _a, _b, _c;
85
+ const firstRange = expandFormulaValue((_a = args[0]) !== null && _a !== void 0 ? _a : null);
86
+ const criteria = [];
87
+ for (let index = 0; index < args.length; index += 2) {
88
+ criteria.push({
89
+ range: expandFormulaValue((_b = args[index]) !== null && _b !== void 0 ? _b : null),
90
+ criterion: ((_c = args[index + 1]) !== null && _c !== void 0 ? _c : null),
91
+ });
92
+ }
93
+ return collectFilteredValues(firstRange, criteria).length;
94
+ },
95
+ },
96
+ DISTINCT: {
97
+ arity: 1,
98
+ compute: args => { var _a; return toDistinctFormulaValues(expandFormulaValue((_a = args[0]) !== null && _a !== void 0 ? _a : null)); },
99
+ },
100
+ INDEX: {
101
+ arity: { min: 2, max: 3 },
102
+ compute: args => {
103
+ var _a, _b, _c, _d, _e;
104
+ const source = expandFormulaValue((_a = args[0]) !== null && _a !== void 0 ? _a : null);
105
+ const index = Math.trunc(coerceFormulaValueToNumber((_b = args[1]) !== null && _b !== void 0 ? _b : null));
106
+ if (index < 1 || index > source.length) {
107
+ return (_c = args[2]) !== null && _c !== void 0 ? _c : 0;
108
+ }
109
+ return (_d = source[index - 1]) !== null && _d !== void 0 ? _d : ((_e = args[2]) !== null && _e !== void 0 ? _e : 0);
110
+ },
111
+ },
112
+ MATCH: {
113
+ arity: { min: 2, max: 3 },
114
+ compute: args => {
115
+ var _a, _b, _c, _d;
116
+ const needle = (_a = args[0]) !== null && _a !== void 0 ? _a : null;
117
+ const haystack = expandFormulaValue((_b = args[1]) !== null && _b !== void 0 ? _b : null);
118
+ const matchMode = Math.trunc(coerceFormulaValueToNumber((_c = args[2]) !== null && _c !== void 0 ? _c : 0));
119
+ if (matchMode !== 0) {
120
+ return 0;
121
+ }
122
+ for (let index = 0; index < haystack.length; index += 1) {
123
+ if (areFormulaValuesEqual(needle, (_d = haystack[index]) !== null && _d !== void 0 ? _d : null)) {
124
+ return index + 1;
125
+ }
126
+ }
127
+ return 0;
128
+ },
129
+ },
130
+ RANGE: {
131
+ compute: args => Object.freeze([...collectValuesFromArgs(args)]),
132
+ },
133
+ SUMIF: {
134
+ arity: { min: 2, max: 3 },
135
+ compute: args => {
136
+ var _a, _b, _c, _d;
137
+ const criteriaRange = expandFormulaValue((_a = args[0]) !== null && _a !== void 0 ? _a : null);
138
+ const criterion = (_b = args[1]) !== null && _b !== void 0 ? _b : null;
139
+ const sumRange = expandFormulaValue((_d = (_c = args[2]) !== null && _c !== void 0 ? _c : args[0]) !== null && _d !== void 0 ? _d : null);
140
+ return toNumericFormulaValues(collectFilteredValues(sumRange, [{ range: criteriaRange, criterion }]))
141
+ .reduce((sum, value) => sum + value, 0);
142
+ },
143
+ },
144
+ SUMIFS: {
145
+ arity: { min: 3 },
146
+ compute: args => {
147
+ var _a, _b, _c;
148
+ const sumRange = expandFormulaValue((_a = args[0]) !== null && _a !== void 0 ? _a : null);
149
+ const criteria = [];
150
+ for (let index = 1; index < args.length; index += 2) {
151
+ criteria.push({
152
+ range: expandFormulaValue((_b = args[index]) !== null && _b !== void 0 ? _b : null),
153
+ criterion: ((_c = args[index + 1]) !== null && _c !== void 0 ? _c : null),
154
+ });
155
+ }
156
+ return toNumericFormulaValues(collectFilteredValues(sumRange, criteria))
157
+ .reduce((sum, value) => sum + value, 0);
158
+ },
159
+ },
160
+ TABLE: {
161
+ arity: { min: 1, max: 2 },
162
+ requiresRuntimeContext: true,
163
+ resolveContextKeys: (args) => {
164
+ const literalTableName = resolveFormulaLiteralText(args[0]);
165
+ return [literalTableName ? createFormulaTableContextKey(literalTableName) : "tables"];
166
+ },
167
+ compute: (args, context) => {
168
+ var _a, _b;
169
+ const tableName = normalizeFormulaTableName((_a = args[0]) !== null && _a !== void 0 ? _a : null);
170
+ if (tableName.length === 0) {
171
+ return Object.freeze([]);
172
+ }
173
+ return collectFormulaTableValues((_b = context === null || context === void 0 ? void 0 : context.getContextValue) === null || _b === void 0 ? void 0 : _b.call(context, createFormulaTableContextKey(tableName)), args[1]);
174
+ },
175
+ },
176
+ RELATED: {
177
+ arity: { min: 4, max: 5 },
178
+ requiresRuntimeContext: true,
179
+ resolveContextKeys: (args) => {
180
+ const literalTableName = resolveFormulaLiteralText(args[0]);
181
+ return [literalTableName ? createFormulaTableContextKey(literalTableName) : "tables"];
182
+ },
183
+ compute: (args, context) => {
184
+ var _a, _b, _c, _d, _e, _f;
185
+ const tableName = normalizeFormulaTableName((_a = args[0]) !== null && _a !== void 0 ? _a : null);
186
+ if (tableName.length === 0) {
187
+ return (_b = args[4]) !== null && _b !== void 0 ? _b : null;
188
+ }
189
+ const values = collectFormulaTableRelatedValues((_c = context === null || context === void 0 ? void 0 : context.getContextValue) === null || _c === void 0 ? void 0 : _c.call(context, createFormulaTableContextKey(tableName)), args[2], (_d = args[1]) !== null && _d !== void 0 ? _d : null, args[3]);
190
+ return (_e = values[0]) !== null && _e !== void 0 ? _e : ((_f = args[4]) !== null && _f !== void 0 ? _f : null);
191
+ },
192
+ },
193
+ ROLLUP: {
194
+ arity: { min: 5, max: 6 },
195
+ requiresRuntimeContext: true,
196
+ resolveContextKeys: (args) => {
197
+ const literalTableName = resolveFormulaLiteralText(args[0]);
198
+ return [literalTableName ? createFormulaTableContextKey(literalTableName) : "tables"];
199
+ },
200
+ compute: (args, context) => {
201
+ var _a, _b, _c, _d, _e;
202
+ const tableName = normalizeFormulaTableName((_a = args[0]) !== null && _a !== void 0 ? _a : null);
203
+ if (tableName.length === 0) {
204
+ return (_b = args[5]) !== null && _b !== void 0 ? _b : 0;
205
+ }
206
+ const values = collectFormulaTableRelatedValues((_c = context === null || context === void 0 ? void 0 : context.getContextValue) === null || _c === void 0 ? void 0 : _c.call(context, createFormulaTableContextKey(tableName)), args[1], (_d = args[2]) !== null && _d !== void 0 ? _d : null, args[3]);
207
+ return computeFormulaRelationRollupValue(values, (_e = args[4]) !== null && _e !== void 0 ? _e : "first", args[5]);
208
+ },
209
+ },
210
+ XLOOKUP: {
211
+ arity: { min: 3, max: 5 },
212
+ compute: args => {
213
+ var _a, _b, _c, _d, _e, _f, _g;
214
+ const needle = (_a = args[0]) !== null && _a !== void 0 ? _a : null;
215
+ const lookupValues = expandFormulaValue((_b = args[1]) !== null && _b !== void 0 ? _b : null);
216
+ const returnValues = expandFormulaValue((_c = args[2]) !== null && _c !== void 0 ? _c : null);
217
+ const notFound = (_d = args[3]) !== null && _d !== void 0 ? _d : 0;
218
+ const matchMode = Math.trunc(coerceFormulaValueToNumber((_e = args[4]) !== null && _e !== void 0 ? _e : 0));
219
+ if (matchMode !== 0) {
220
+ return notFound;
221
+ }
222
+ for (let index = 0; index < lookupValues.length; index += 1) {
223
+ if (areFormulaValuesEqual(needle, (_f = lookupValues[index]) !== null && _f !== void 0 ? _f : null)) {
224
+ return (_g = returnValues[index]) !== null && _g !== void 0 ? _g : notFound;
225
+ }
226
+ }
227
+ return notFound;
228
+ },
229
+ },
230
+ COUNTIF: {
231
+ arity: 2,
232
+ compute: args => {
233
+ var _a;
234
+ return expandFormulaValue((_a = args[0]) !== null && _a !== void 0 ? _a : null)
235
+ .filter(value => { var _a; return formulaValueMatchesCriterion(value, (_a = args[1]) !== null && _a !== void 0 ? _a : null); }).length;
236
+ },
237
+ },
238
+ VLOOKUP: {
239
+ arity: { min: 3, max: 4 },
240
+ compute: args => {
241
+ var _a, _b, _c, _d, _e;
242
+ const needle = (_a = args[0]) !== null && _a !== void 0 ? _a : null;
243
+ const lookupValues = expandFormulaValue((_b = args[1]) !== null && _b !== void 0 ? _b : null);
244
+ const columnNumber = Math.trunc(coerceFormulaValueToNumber((_c = args[2]) !== null && _c !== void 0 ? _c : null));
245
+ const exact = Math.trunc(coerceFormulaValueToNumber((_d = args[3]) !== null && _d !== void 0 ? _d : 0)) === 0;
246
+ if (!exact || columnNumber !== 1) {
247
+ return 0;
248
+ }
249
+ return (_e = lookupValues.find(value => areFormulaValuesEqual(value, needle))) !== null && _e !== void 0 ? _e : 0;
250
+ },
251
+ },
252
+ });
@@ -0,0 +1,2 @@
1
+ export declare const DATAGRID_DATE_FORMULA_FUNCTIONS: Readonly<Record<string, import("../types.js").DataGridFormulaFunctionDefinition>>;
2
+ //# sourceMappingURL=dateFunctions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dateFunctions.d.ts","sourceRoot":"","sources":["../../../src/syntax/functionGroups/dateFunctions.ts"],"names":[],"mappings":"AAwBA,eAAO,MAAM,+BAA+B,mFAwH1C,CAAA"}
@@ -0,0 +1,144 @@
1
+ import { coerceFormulaValueToNumber, } from "../values.js";
2
+ import { addCalendarDays, addWorkingDays, coerceFormulaValueToDate, countDaysBetween, countWorkingDays, defineFormulaFunctions, normalizeHolidayTimes, parseTimeLikeValue, } from "../functionHelpers.js";
3
+ function stripTime(date) {
4
+ return new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate()));
5
+ }
6
+ function resolveWeekNumber(date) {
7
+ const startOfYear = Date.UTC(date.getUTCFullYear(), 0, 1);
8
+ const current = Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate());
9
+ return Math.floor((current - startOfYear) / 86400000 / 7) + 1;
10
+ }
11
+ export const DATAGRID_DATE_FORMULA_FUNCTIONS = defineFormulaFunctions({
12
+ DATE: {
13
+ arity: 3,
14
+ compute: args => {
15
+ var _a, _b, _c;
16
+ const year = Math.trunc(coerceFormulaValueToNumber((_a = args[0]) !== null && _a !== void 0 ? _a : null));
17
+ const month = Math.trunc(coerceFormulaValueToNumber((_b = args[1]) !== null && _b !== void 0 ? _b : null));
18
+ const day = Math.trunc(coerceFormulaValueToNumber((_c = args[2]) !== null && _c !== void 0 ? _c : null));
19
+ return new Date(Date.UTC(year, month - 1, day));
20
+ },
21
+ },
22
+ DATEONLY: {
23
+ arity: 1,
24
+ compute: args => {
25
+ var _a;
26
+ const date = coerceFormulaValueToDate((_a = args[0]) !== null && _a !== void 0 ? _a : null);
27
+ return date ? stripTime(date) : null;
28
+ },
29
+ },
30
+ DAY: {
31
+ arity: 1,
32
+ compute: args => {
33
+ var _a;
34
+ const date = coerceFormulaValueToDate((_a = args[0]) !== null && _a !== void 0 ? _a : null);
35
+ return date ? date.getUTCDate() : 0;
36
+ },
37
+ },
38
+ MONTH: {
39
+ arity: 1,
40
+ compute: args => {
41
+ var _a;
42
+ const date = coerceFormulaValueToDate((_a = args[0]) !== null && _a !== void 0 ? _a : null);
43
+ return date ? date.getUTCMonth() + 1 : 0;
44
+ },
45
+ },
46
+ NETDAYS: {
47
+ arity: 2,
48
+ compute: args => {
49
+ var _a, _b;
50
+ const start = coerceFormulaValueToDate((_a = args[0]) !== null && _a !== void 0 ? _a : null);
51
+ const end = coerceFormulaValueToDate((_b = args[1]) !== null && _b !== void 0 ? _b : null);
52
+ if (!start || !end) {
53
+ return 0;
54
+ }
55
+ return countDaysBetween(start, end, false);
56
+ },
57
+ },
58
+ NETWORKDAY: {
59
+ arity: { min: 2 },
60
+ compute: args => {
61
+ var _a, _b;
62
+ const start = coerceFormulaValueToDate((_a = args[0]) !== null && _a !== void 0 ? _a : null);
63
+ const end = coerceFormulaValueToDate((_b = args[1]) !== null && _b !== void 0 ? _b : null);
64
+ if (!start || !end) {
65
+ return 0;
66
+ }
67
+ return countWorkingDays(start, end, normalizeHolidayTimes(args.slice(2)));
68
+ },
69
+ },
70
+ NETWORKDAYS: {
71
+ arity: { min: 2 },
72
+ compute: args => {
73
+ var _a, _b;
74
+ const start = coerceFormulaValueToDate((_a = args[0]) !== null && _a !== void 0 ? _a : null);
75
+ const end = coerceFormulaValueToDate((_b = args[1]) !== null && _b !== void 0 ? _b : null);
76
+ if (!start || !end) {
77
+ return 0;
78
+ }
79
+ return countWorkingDays(start, end, normalizeHolidayTimes(args.slice(2)));
80
+ },
81
+ },
82
+ TIME: {
83
+ arity: { min: 1, max: 3 },
84
+ compute: args => { var _a; return parseTimeLikeValue((_a = args[0]) !== null && _a !== void 0 ? _a : null); },
85
+ },
86
+ TODAY: {
87
+ arity: { min: 0, max: 1 },
88
+ compute: args => {
89
+ var _a;
90
+ const now = new Date();
91
+ const base = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate()));
92
+ const offset = Math.trunc(coerceFormulaValueToNumber((_a = args[0]) !== null && _a !== void 0 ? _a : 0));
93
+ return addCalendarDays(base, offset);
94
+ },
95
+ },
96
+ WEEKDAY: {
97
+ arity: 1,
98
+ compute: args => {
99
+ var _a;
100
+ const date = coerceFormulaValueToDate((_a = args[0]) !== null && _a !== void 0 ? _a : null);
101
+ return date ? date.getUTCDay() + 1 : 0;
102
+ },
103
+ },
104
+ WEEKNUMBER: {
105
+ arity: 1,
106
+ compute: args => {
107
+ var _a;
108
+ const date = coerceFormulaValueToDate((_a = args[0]) !== null && _a !== void 0 ? _a : null);
109
+ return date ? resolveWeekNumber(date) : 0;
110
+ },
111
+ },
112
+ WORKDAY: {
113
+ arity: { min: 2 },
114
+ compute: args => {
115
+ var _a, _b;
116
+ const date = coerceFormulaValueToDate((_a = args[0]) !== null && _a !== void 0 ? _a : null);
117
+ if (!date) {
118
+ return null;
119
+ }
120
+ return addWorkingDays(date, coerceFormulaValueToNumber((_b = args[1]) !== null && _b !== void 0 ? _b : 0), normalizeHolidayTimes(args.slice(2)));
121
+ },
122
+ },
123
+ YEAR: {
124
+ arity: 1,
125
+ compute: args => {
126
+ var _a;
127
+ const date = coerceFormulaValueToDate((_a = args[0]) !== null && _a !== void 0 ? _a : null);
128
+ return date ? date.getUTCFullYear() : 0;
129
+ },
130
+ },
131
+ YEARDAY: {
132
+ arity: 1,
133
+ compute: args => {
134
+ var _a;
135
+ const date = coerceFormulaValueToDate((_a = args[0]) !== null && _a !== void 0 ? _a : null);
136
+ if (!date) {
137
+ return 0;
138
+ }
139
+ const start = Date.UTC(date.getUTCFullYear(), 0, 1);
140
+ const current = Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate());
141
+ return Math.floor((current - start) / 86400000) + 1;
142
+ },
143
+ },
144
+ });
@@ -0,0 +1,2 @@
1
+ export declare const DATAGRID_LOGIC_FORMULA_FUNCTIONS: Readonly<Record<string, import("../types.js").DataGridFormulaFunctionDefinition>>;
2
+ //# sourceMappingURL=logicFunctions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logicFunctions.d.ts","sourceRoot":"","sources":["../../../src/syntax/functionGroups/logicFunctions.ts"],"names":[],"mappings":"AAgBA,eAAO,MAAM,gCAAgC,mFA4H3C,CAAA"}