@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,139 @@
1
+ import {} from "./values.js";
2
+ import { throwFormulaError } from "./ast.js";
3
+ import { DATAGRID_ADVANCED_FORMULA_FUNCTIONS } from "./functionGroups/advancedFunctions.js";
4
+ import { DATAGRID_DATE_FORMULA_FUNCTIONS } from "./functionGroups/dateFunctions.js";
5
+ import { DATAGRID_LOGIC_FORMULA_FUNCTIONS } from "./functionGroups/logicFunctions.js";
6
+ import { DATAGRID_NUMERIC_FORMULA_FUNCTIONS } from "./functionGroups/numericFunctions.js";
7
+ import { DATAGRID_TEXT_FORMULA_FUNCTIONS } from "./functionGroups/textFunctions.js";
8
+ export function normalizeFormulaText(value) {
9
+ if (typeof value !== "string") {
10
+ throwFormulaError("Formula must be a string.");
11
+ }
12
+ const normalized = value.trim();
13
+ if (normalized.length === 0) {
14
+ throwFormulaError("Formula must be non-empty.");
15
+ }
16
+ return normalized.startsWith("=") ? normalized.slice(1).trim() : normalized;
17
+ }
18
+ export function normalizeFormulaFieldName(value, label) {
19
+ if (typeof value !== "string") {
20
+ throwFormulaError(`${label} must be a string.`);
21
+ }
22
+ const normalized = value.trim();
23
+ if (normalized.length === 0) {
24
+ throwFormulaError(`${label} must be non-empty.`);
25
+ }
26
+ return normalized;
27
+ }
28
+ export function normalizeFormulaFunctionName(value) {
29
+ return value.trim().toUpperCase();
30
+ }
31
+ function normalizeFormulaFunctionArity(arity, functionName) {
32
+ if (typeof arity === "undefined") {
33
+ return undefined;
34
+ }
35
+ if (typeof arity === "number") {
36
+ if (!Number.isInteger(arity) || arity < 0) {
37
+ throwFormulaError(`Function '${functionName}' has invalid arity definition.`);
38
+ }
39
+ return arity;
40
+ }
41
+ const min = Math.trunc(arity.min);
42
+ const max = typeof arity.max === "number" ? Math.trunc(arity.max) : undefined;
43
+ if (!Number.isFinite(min) || min < 0) {
44
+ throwFormulaError(`Function '${functionName}' has invalid minimum arity.`);
45
+ }
46
+ if (typeof max === "number") {
47
+ if (!Number.isFinite(max) || max < min) {
48
+ throwFormulaError(`Function '${functionName}' has invalid maximum arity.`);
49
+ }
50
+ return { min, max };
51
+ }
52
+ return { min };
53
+ }
54
+ function normalizeFormulaContextKeys(value) {
55
+ if (!Array.isArray(value)) {
56
+ return [];
57
+ }
58
+ const normalized = [];
59
+ const seen = new Set();
60
+ for (const entry of value) {
61
+ if (typeof entry !== "string") {
62
+ continue;
63
+ }
64
+ const nextValue = entry.trim();
65
+ if (nextValue.length === 0 || seen.has(nextValue)) {
66
+ continue;
67
+ }
68
+ seen.add(nextValue);
69
+ normalized.push(nextValue);
70
+ }
71
+ return normalized;
72
+ }
73
+ export function normalizeFormulaFunctionRegistry(input, options = {}) {
74
+ const normalized = new Map();
75
+ const registerEntry = (key, definition, source) => {
76
+ var _a;
77
+ const normalizedName = normalizeFormulaFunctionName(key);
78
+ if (normalizedName.length === 0) {
79
+ throwFormulaError("Function name must be non-empty.");
80
+ }
81
+ const runtimeDefinition = typeof definition === "function"
82
+ ? { compute: definition }
83
+ : definition;
84
+ if (typeof runtimeDefinition.compute !== "function") {
85
+ throwFormulaError(`Function '${normalizedName}' must provide a compute implementation.`);
86
+ }
87
+ if (source === "user" && normalized.has(normalizedName)) {
88
+ (_a = options.onFunctionOverride) === null || _a === void 0 ? void 0 : _a.call(options, normalizedName);
89
+ }
90
+ normalized.set(normalizedName, {
91
+ name: normalizedName,
92
+ arity: normalizeFormulaFunctionArity(runtimeDefinition.arity, normalizedName),
93
+ contextKeys: normalizeFormulaContextKeys(runtimeDefinition.contextKeys),
94
+ resolveContextKeys: typeof runtimeDefinition.resolveContextKeys === "function"
95
+ ? runtimeDefinition.resolveContextKeys
96
+ : undefined,
97
+ requiresRuntimeContext: runtimeDefinition.requiresRuntimeContext === true,
98
+ compute: runtimeDefinition.compute,
99
+ });
100
+ };
101
+ for (const [key, definition] of Object.entries(DATAGRID_DEFAULT_FORMULA_FUNCTIONS)) {
102
+ registerEntry(key, definition, "default");
103
+ }
104
+ for (const [key, definition] of Object.entries(input !== null && input !== void 0 ? input : {})) {
105
+ registerEntry(key, definition, "user");
106
+ }
107
+ return normalized;
108
+ }
109
+ export function collectFormulaContextKeys(root, functionRegistry, output) {
110
+ if (root.kind === "call") {
111
+ const functionName = normalizeFormulaFunctionName(root.name);
112
+ const functionDefinition = functionRegistry.get(functionName);
113
+ if (functionDefinition) {
114
+ output.push(...functionDefinition.contextKeys);
115
+ if (typeof functionDefinition.resolveContextKeys === "function") {
116
+ output.push(...functionDefinition.resolveContextKeys(root.args));
117
+ }
118
+ }
119
+ for (const arg of root.args) {
120
+ collectFormulaContextKeys(arg, functionRegistry, output);
121
+ }
122
+ return;
123
+ }
124
+ if (root.kind === "unary") {
125
+ collectFormulaContextKeys(root.value, functionRegistry, output);
126
+ return;
127
+ }
128
+ if (root.kind === "binary") {
129
+ collectFormulaContextKeys(root.left, functionRegistry, output);
130
+ collectFormulaContextKeys(root.right, functionRegistry, output);
131
+ }
132
+ }
133
+ export const DATAGRID_DEFAULT_FORMULA_FUNCTIONS = {
134
+ ...DATAGRID_NUMERIC_FORMULA_FUNCTIONS,
135
+ ...DATAGRID_LOGIC_FORMULA_FUNCTIONS,
136
+ ...DATAGRID_TEXT_FORMULA_FUNCTIONS,
137
+ ...DATAGRID_DATE_FORMULA_FUNCTIONS,
138
+ ...DATAGRID_ADVANCED_FORMULA_FUNCTIONS,
139
+ };
@@ -0,0 +1,10 @@
1
+ export * from "./types.js";
2
+ export * from "./ast.js";
3
+ export * from "./values.js";
4
+ export * from "./functions.js";
5
+ export * from "./tokenizer.js";
6
+ export * from "./parser.js";
7
+ export * from "./optimizer.js";
8
+ export type { DataGridFormulaCompileOptions, DataGridFormulaCompileStrategy, DataGridCompiledFormulaField, DataGridFormulaExpressionAnalysis, DataGridCompiledFormulaArtifact, DataGridCompiledFormulaBatchContext, DataGridCompiledFormulaBatchExecutionMode, DataGridFormulaFunctionRuntime, DataGridFormulaTokenValueReader, DataGridFormulaEvaluatorForToken, DataGridFormulaEvaluator, DataGridFormulaTokenIndexEvaluator, DataGridFormulaBatchEvaluator, DataGridFormulaColumnarBatchEvaluator, DataGridFormulaParseResult, } from "../runtime/types.js";
9
+ export type { DataGridFormulaDiagnosticsResult, DataGridFormulaExplainDependencyDomain, DataGridFormulaExplainDependency, DataGridFormulaExplainNode, DataGridFormulaExplainResult, DataGridFormulaFieldExplainResult, } from "../analysis/types.js";
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/syntax/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAA;AAC1B,cAAc,UAAU,CAAA;AACxB,cAAc,aAAa,CAAA;AAC3B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,aAAa,CAAA;AAC3B,cAAc,gBAAgB,CAAA;AAE9B,YAAY,EACV,6BAA6B,EAC7B,8BAA8B,EAC9B,4BAA4B,EAC5B,iCAAiC,EACjC,+BAA+B,EAC/B,mCAAmC,EACnC,yCAAyC,EACzC,8BAA8B,EAC9B,+BAA+B,EAC/B,gCAAgC,EAChC,wBAAwB,EACxB,kCAAkC,EAClC,6BAA6B,EAC7B,qCAAqC,EACrC,0BAA0B,GAC3B,MAAM,qBAAqB,CAAA;AAC5B,YAAY,EACV,gCAAgC,EAChC,sCAAsC,EACtC,gCAAgC,EAChC,0BAA0B,EAC1B,4BAA4B,EAC5B,iCAAiC,GAClC,MAAM,sBAAsB,CAAA"}
@@ -0,0 +1,7 @@
1
+ export * from "./types.js";
2
+ export * from "./ast.js";
3
+ export * from "./values.js";
4
+ export * from "./functions.js";
5
+ export * from "./tokenizer.js";
6
+ export * from "./parser.js";
7
+ export * from "./optimizer.js";
@@ -0,0 +1,29 @@
1
+ import type { DataGridFormulaRuntimeError } from "../coreTypes.js";
2
+ import type { DataGridFormulaDiagnosticsResult, DataGridFormulaExplainResult, DataGridFormulaFieldExplainResult } from "../analysis/types.js";
3
+ export type { DataGridFormulaDiagnosticsResult, DataGridFormulaExplainDependency, DataGridFormulaExplainDependencyDomain, DataGridFormulaExplainNode, DataGridFormulaExplainResult, DataGridFormulaFieldExplainResult, } from "../analysis/types.js";
4
+ import type { DataGridFormulaCompileOptions, DataGridFormulaParseResult } from "../runtime/types.js";
5
+ export type { DataGridCompiledFormulaArtifact, DataGridCompiledFormulaBatchContext, DataGridCompiledFormulaBatchExecutionMode, DataGridCompiledFormulaField, DataGridFormulaBatchEvaluator, DataGridFormulaColumnarBatchEvaluator, DataGridFormulaCompileOptions, DataGridFormulaCompileStrategy, DataGridFormulaEvaluator, DataGridFormulaEvaluatorForToken, DataGridFormulaExpressionAnalysis, DataGridFormulaFunctionRuntime, DataGridFormulaParseResult, DataGridFormulaRuntimeErrorPolicy, DataGridFormulaTokenIndexEvaluator, DataGridFormulaTokenValueReader, } from "../runtime/types.js";
6
+ import type { DataGridFormulaAstNode, DataGridFormulaDiagnostic, DataGridFormulaSourceSpan } from "./types.js";
7
+ export type { DataGridFormulaAstNode, DataGridFormulaDiagnostic, DataGridFormulaFunctionArity, DataGridFormulaFunctionDefinition, DataGridFormulaFunctionRegistry, DataGridFormulaOperator, DataGridFormulaReferenceSegment, DataGridFormulaSourceSpan, DataGridFormulaToken, } from "./types.js";
8
+ export declare class DataGridFormulaEvaluationError extends Error {
9
+ readonly runtimeError: DataGridFormulaRuntimeError;
10
+ constructor(runtimeError: DataGridFormulaRuntimeError);
11
+ }
12
+ export declare class DataGridFormulaSyntaxError extends Error {
13
+ readonly span: DataGridFormulaSourceSpan;
14
+ constructor(message: string, span: DataGridFormulaSourceSpan);
15
+ }
16
+ export declare function createFormulaSourceSpan(start: number, end: number): DataGridFormulaSourceSpan;
17
+ export declare function getFormulaNodeSpan(node: DataGridFormulaAstNode): DataGridFormulaSourceSpan;
18
+ export declare function throwFormulaError(message: string, span?: DataGridFormulaSourceSpan): never;
19
+ export declare function createFormulaDiagnostic(message: string, span: DataGridFormulaSourceSpan): DataGridFormulaDiagnostic;
20
+ export declare function normalizeFormulaDiagnostic(error: unknown): DataGridFormulaDiagnostic;
21
+ export declare function parseDataGridFormulaExpression(formula: string): DataGridFormulaParseResult;
22
+ export declare function diagnoseDataGridFormulaExpression(formula: string, options?: Pick<DataGridFormulaCompileOptions, "functionRegistry" | "onFunctionOverride">): DataGridFormulaDiagnosticsResult;
23
+ export declare function explainDataGridFormulaExpression(formula: string, options?: Pick<DataGridFormulaCompileOptions, "resolveDependencyToken" | "functionRegistry" | "onFunctionOverride">): DataGridFormulaExplainResult;
24
+ export declare function explainDataGridFormulaFieldDefinition(definition: {
25
+ name: string;
26
+ field?: string;
27
+ formula: string;
28
+ }, options?: Pick<DataGridFormulaCompileOptions, "resolveDependencyToken" | "functionRegistry" | "onFunctionOverride">): DataGridFormulaFieldExplainResult;
29
+ //# sourceMappingURL=legacy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"legacy.d.ts","sourceRoot":"","sources":["../../src/syntax/legacy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAIV,2BAA2B,EAE5B,MAAM,iBAAiB,CAAA;AACxB,OAAO,KAAK,EACV,gCAAgC,EAIhC,4BAA4B,EAC5B,iCAAiC,EAClC,MAAM,sBAAsB,CAAA;AAC7B,YAAY,EACV,gCAAgC,EAChC,gCAAgC,EAChC,sCAAsC,EACtC,0BAA0B,EAC1B,4BAA4B,EAC5B,iCAAiC,GAClC,MAAM,sBAAsB,CAAA;AAC7B,OAAO,KAAK,EAOV,6BAA6B,EAM7B,0BAA0B,EAI3B,MAAM,qBAAqB,CAAA;AAC5B,YAAY,EACV,+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,GAChC,MAAM,qBAAqB,CAAA;AAO5B,OAAO,KAAK,EACV,sBAAsB,EACtB,yBAAyB,EAMzB,yBAAyB,EAE1B,MAAM,YAAY,CAAA;AACnB,YAAY,EACV,sBAAsB,EACtB,yBAAyB,EACzB,4BAA4B,EAC5B,iCAAiC,EACjC,+BAA+B,EAC/B,uBAAuB,EACvB,+BAA+B,EAC/B,yBAAyB,EACzB,oBAAoB,GACrB,MAAM,YAAY,CAAA;AASnB,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;AAuFD,wBAAgB,8BAA8B,CAAC,OAAO,EAAE,MAAM,GAAG,0BAA0B,CAK1F;AAED,wBAAgB,iCAAiC,CAC/C,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,IAAI,CAAC,6BAA6B,EAAE,kBAAkB,GAAG,oBAAoB,CAAM,GAC3F,gCAAgC,CAalC;AAED,wBAAgB,gCAAgC,CAC9C,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,IAAI,CAAC,6BAA6B,EAAE,wBAAwB,GAAG,kBAAkB,GAAG,oBAAoB,CAAM,GACtH,4BAA4B,CAyB9B;AAED,wBAAgB,qCAAqC,CACnD,UAAU,EAAE;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,MAAM,CAAA;CAChB,EACD,OAAO,GAAE,IAAI,CAAC,6BAA6B,EAAE,wBAAwB,GAAG,kBAAkB,GAAG,oBAAoB,CAAM,GACtH,iCAAiC,CASnC"}
@@ -0,0 +1,188 @@
1
+ import { collectFormulaContextKeys, normalizeFormulaFieldName, normalizeFormulaFunctionRegistry, normalizeFormulaText, } from "./functions.js";
2
+ import { parseFormula } from "./parser.js";
3
+ import { tokenizeFormula } from "./tokenizer.js";
4
+ import { collectFormulaIdentifiers, validateFormulaFunctions, foldFormulaConstants, } from "./optimizer.js";
5
+ export class DataGridFormulaEvaluationError extends Error {
6
+ constructor(runtimeError) {
7
+ super(runtimeError.message);
8
+ Object.defineProperty(this, "runtimeError", {
9
+ enumerable: true,
10
+ configurable: true,
11
+ writable: true,
12
+ value: void 0
13
+ });
14
+ this.name = "DataGridFormulaEvaluationError";
15
+ this.runtimeError = runtimeError;
16
+ }
17
+ }
18
+ export class DataGridFormulaSyntaxError extends Error {
19
+ constructor(message, span) {
20
+ super(message);
21
+ Object.defineProperty(this, "span", {
22
+ enumerable: true,
23
+ configurable: true,
24
+ writable: true,
25
+ value: void 0
26
+ });
27
+ this.name = "DataGridFormulaSyntaxError";
28
+ this.span = span;
29
+ }
30
+ }
31
+ export function createFormulaSourceSpan(start, end) {
32
+ const normalizedStart = Math.max(0, Math.trunc(start));
33
+ const normalizedEnd = Math.max(normalizedStart, Math.trunc(end));
34
+ return { start: normalizedStart, end: normalizedEnd };
35
+ }
36
+ export function getFormulaNodeSpan(node) {
37
+ return node.span;
38
+ }
39
+ export function throwFormulaError(message, span = createFormulaSourceSpan(0, 0)) {
40
+ throw new DataGridFormulaSyntaxError(`[DataGridFormula] ${message}`, span);
41
+ }
42
+ export function createFormulaDiagnostic(message, span) {
43
+ return {
44
+ severity: "error",
45
+ message,
46
+ span,
47
+ };
48
+ }
49
+ export function normalizeFormulaDiagnostic(error) {
50
+ if (error instanceof DataGridFormulaSyntaxError) {
51
+ return createFormulaDiagnostic(error.message, error.span);
52
+ }
53
+ if (error instanceof DataGridFormulaEvaluationError) {
54
+ return createFormulaDiagnostic(error.runtimeError.message, createFormulaSourceSpan(0, 0));
55
+ }
56
+ const message = error instanceof Error ? error.message : String(error !== null && error !== void 0 ? error : "Formula diagnostics failed.");
57
+ return createFormulaDiagnostic(message, createFormulaSourceSpan(0, 0));
58
+ }
59
+ function dedupeFormulaIdentifiers(root) {
60
+ const references = [];
61
+ collectFormulaIdentifiers(root, references);
62
+ const identifiers = [];
63
+ const seenIdentifiers = new Set();
64
+ for (const reference of references) {
65
+ const normalized = reference.trim();
66
+ if (normalized.length === 0 || seenIdentifiers.has(normalized)) {
67
+ continue;
68
+ }
69
+ seenIdentifiers.add(normalized);
70
+ identifiers.push(normalized);
71
+ }
72
+ return Object.freeze(identifiers);
73
+ }
74
+ function normalizeFormulaExplainDependency(identifier, token) {
75
+ const normalizedToken = typeof token === "string" ? token.trim() : "";
76
+ if (normalizedToken.startsWith("field:")) {
77
+ return { identifier, token, domain: "field", value: normalizedToken.slice("field:".length) };
78
+ }
79
+ if (normalizedToken.startsWith("computed:")) {
80
+ return { identifier, token, domain: "computed", value: normalizedToken.slice("computed:".length) };
81
+ }
82
+ if (normalizedToken.startsWith("meta:")) {
83
+ return { identifier, token, domain: "meta", value: normalizedToken.slice("meta:".length) };
84
+ }
85
+ return {
86
+ identifier,
87
+ token,
88
+ domain: "unknown",
89
+ value: normalizedToken.length > 0 ? normalizedToken : String(token),
90
+ };
91
+ }
92
+ function createFormulaExplainNode(root) {
93
+ if (root.kind === "number") {
94
+ return { kind: root.kind, label: String(root.value), span: root.span, children: [], value: root.value };
95
+ }
96
+ if (root.kind === "literal") {
97
+ return { kind: root.kind, label: "literal", span: root.span, children: [], value: root.value };
98
+ }
99
+ if (root.kind === "identifier") {
100
+ return { kind: root.kind, label: root.name, span: root.span, children: [], name: root.name };
101
+ }
102
+ if (root.kind === "call") {
103
+ return {
104
+ kind: root.kind,
105
+ label: `${root.name}()`,
106
+ span: root.span,
107
+ children: root.args.map(createFormulaExplainNode),
108
+ name: root.name,
109
+ operator: "CALL",
110
+ };
111
+ }
112
+ if (root.kind === "unary") {
113
+ return {
114
+ kind: root.kind,
115
+ label: root.operator,
116
+ span: root.span,
117
+ children: [createFormulaExplainNode(root.value)],
118
+ operator: root.operator,
119
+ };
120
+ }
121
+ return {
122
+ kind: root.kind,
123
+ label: root.operator,
124
+ span: root.span,
125
+ children: [createFormulaExplainNode(root.left), createFormulaExplainNode(root.right)],
126
+ operator: root.operator,
127
+ };
128
+ }
129
+ function dedupeFormulaContextKeys(root, functionRegistry) {
130
+ const contextKeys = [];
131
+ collectFormulaContextKeys(root, functionRegistry, contextKeys);
132
+ return Object.freeze(Array.from(new Set(contextKeys.map(key => key.trim()).filter(key => key.length > 0))));
133
+ }
134
+ export function parseDataGridFormulaExpression(formula) {
135
+ const normalizedFormula = normalizeFormulaText(formula);
136
+ const tokens = tokenizeFormula(normalizedFormula);
137
+ const ast = parseFormula(tokens);
138
+ return { formula: normalizedFormula, tokens, ast };
139
+ }
140
+ export function diagnoseDataGridFormulaExpression(formula, options = {}) {
141
+ const normalizedFormula = normalizeFormulaText(formula);
142
+ try {
143
+ const tokens = tokenizeFormula(normalizedFormula);
144
+ const ast = parseFormula(tokens);
145
+ const functionRegistry = normalizeFormulaFunctionRegistry(options.functionRegistry, {
146
+ onFunctionOverride: options.onFunctionOverride,
147
+ });
148
+ validateFormulaFunctions(ast, functionRegistry);
149
+ return { ok: true, formula: normalizedFormula, diagnostics: [], tokens, ast };
150
+ }
151
+ catch (error) {
152
+ return { ok: false, formula: normalizedFormula, diagnostics: [normalizeFormulaDiagnostic(error)] };
153
+ }
154
+ }
155
+ export function explainDataGridFormulaExpression(formula, options = {}) {
156
+ var _a;
157
+ const normalizedFormula = normalizeFormulaText(formula);
158
+ const tokens = tokenizeFormula(normalizedFormula);
159
+ const ast = parseFormula(tokens);
160
+ const optimizedAst = foldFormulaConstants(ast);
161
+ const identifiers = dedupeFormulaIdentifiers(optimizedAst);
162
+ const functionRegistry = normalizeFormulaFunctionRegistry(options.functionRegistry, {
163
+ onFunctionOverride: options.onFunctionOverride,
164
+ });
165
+ validateFormulaFunctions(optimizedAst, functionRegistry);
166
+ const resolveDependencyToken = (_a = options.resolveDependencyToken) !== null && _a !== void 0 ? _a : ((identifier) => `field:${identifier}`);
167
+ const dependencies = identifiers.map(identifier => normalizeFormulaExplainDependency(identifier, resolveDependencyToken(identifier)));
168
+ return {
169
+ formula: normalizedFormula,
170
+ tokens,
171
+ ast: optimizedAst,
172
+ identifiers,
173
+ dependencies,
174
+ contextKeys: dedupeFormulaContextKeys(optimizedAst, functionRegistry),
175
+ tree: createFormulaExplainNode(optimizedAst),
176
+ };
177
+ }
178
+ export function explainDataGridFormulaFieldDefinition(definition, options = {}) {
179
+ var _a;
180
+ const name = normalizeFormulaFieldName(definition.name, "Formula name");
181
+ const field = normalizeFormulaFieldName((_a = definition.field) !== null && _a !== void 0 ? _a : name, "Formula target field");
182
+ const explained = explainDataGridFormulaExpression(definition.formula, options);
183
+ return {
184
+ name,
185
+ field,
186
+ ...explained,
187
+ };
188
+ }
@@ -0,0 +1,6 @@
1
+ import type { DataGridFormulaAstNode } from "./ast.js";
2
+ import type { DataGridFormulaFunctionRuntime } from "./functions.js";
3
+ export declare function collectFormulaIdentifiers(root: DataGridFormulaAstNode, output: string[]): void;
4
+ export declare function validateFormulaFunctions(root: DataGridFormulaAstNode, functionRegistry: ReadonlyMap<string, DataGridFormulaFunctionRuntime>): void;
5
+ export declare function foldFormulaConstants(root: DataGridFormulaAstNode): DataGridFormulaAstNode;
6
+ //# sourceMappingURL=optimizer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"optimizer.d.ts","sourceRoot":"","sources":["../../src/syntax/optimizer.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,sBAAsB,EAEvB,MAAM,UAAU,CAAA;AACjB,OAAO,KAAK,EACV,8BAA8B,EAC/B,MAAM,gBAAgB,CAAA;AA+CvB,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,sBAAsB,EAC5B,MAAM,EAAE,MAAM,EAAE,GACf,IAAI,CAmBN;AAED,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,sBAAsB,EAC5B,gBAAgB,EAAE,WAAW,CAAC,MAAM,EAAE,8BAA8B,CAAC,GACpE,IAAI,CA2BN;AA0ED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,sBAAsB,GAAG,sBAAsB,CAwRzF"}