@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,140 @@
1
+ import { areFormulaValuesEqual, coerceFormulaValueToBoolean, isFormulaErrorValue, isFormulaValueBlank, } from "../values.js";
2
+ import { booleanResult, defaultIfEmpty, defineFormulaFunctions, expandFormulaArgs, expandFormulaValue, formulaValueMatchesCriterion, normalizeTextSearch, } from "../functionHelpers.js";
3
+ export const DATAGRID_LOGIC_FORMULA_FUNCTIONS = defineFormulaFunctions({
4
+ AND: {
5
+ arity: { min: 1 },
6
+ compute: args => booleanResult(args.every(value => coerceFormulaValueToBoolean(value !== null && value !== void 0 ? value : null))),
7
+ },
8
+ CONTAINS: {
9
+ arity: 2,
10
+ compute: args => {
11
+ var _a, _b;
12
+ const needle = normalizeTextSearch((_a = args[0]) !== null && _a !== void 0 ? _a : null);
13
+ if (needle.length === 0) {
14
+ return false;
15
+ }
16
+ return expandFormulaValue((_b = args[1]) !== null && _b !== void 0 ? _b : null)
17
+ .some(value => normalizeTextSearch(value).includes(needle));
18
+ },
19
+ },
20
+ HAS: {
21
+ arity: 2,
22
+ compute: args => {
23
+ var _a;
24
+ return expandFormulaValue((_a = args[0]) !== null && _a !== void 0 ? _a : null)
25
+ .some(value => { var _a; return areFormulaValuesEqual(value, (_a = args[1]) !== null && _a !== void 0 ? _a : null); });
26
+ },
27
+ },
28
+ IF: {
29
+ arity: 3,
30
+ compute: args => { var _a, _b, _c; return (coerceFormulaValueToBoolean((_a = args[0]) !== null && _a !== void 0 ? _a : null) ? (_b = args[1]) !== null && _b !== void 0 ? _b : 0 : (_c = args[2]) !== null && _c !== void 0 ? _c : 0); },
31
+ },
32
+ IFERROR: {
33
+ arity: 2,
34
+ compute: args => { var _a, _b, _c; return (isFormulaErrorValue((_a = args[0]) !== null && _a !== void 0 ? _a : null) ? (_b = args[1]) !== null && _b !== void 0 ? _b : 0 : (_c = args[0]) !== null && _c !== void 0 ? _c : 0); },
35
+ },
36
+ IFS: {
37
+ arity: { min: 2 },
38
+ compute: args => {
39
+ var _a, _b;
40
+ for (let index = 0; index < args.length; index += 2) {
41
+ if (coerceFormulaValueToBoolean((_a = args[index]) !== null && _a !== void 0 ? _a : null)) {
42
+ return (_b = args[index + 1]) !== null && _b !== void 0 ? _b : 0;
43
+ }
44
+ }
45
+ return 0;
46
+ },
47
+ },
48
+ COALESCE: {
49
+ arity: { min: 1 },
50
+ compute: args => {
51
+ for (const value of args) {
52
+ if (!isFormulaValueBlank(value !== null && value !== void 0 ? value : null)) {
53
+ return value;
54
+ }
55
+ }
56
+ return 0;
57
+ },
58
+ },
59
+ IN: {
60
+ arity: { min: 2 },
61
+ compute: args => expandFormulaArgs(args.slice(1)).some(value => { var _a; return areFormulaValuesEqual((_a = args[0]) !== null && _a !== void 0 ? _a : null, value); }) ? 1 : 0,
62
+ },
63
+ ISBLANK: {
64
+ arity: 1,
65
+ compute: args => { var _a; return isFormulaValueBlank((_a = args[0]) !== null && _a !== void 0 ? _a : null); },
66
+ },
67
+ ISBOOLEAN: {
68
+ arity: 1,
69
+ compute: args => typeof defaultIfEmpty(args[0], null) === "boolean",
70
+ },
71
+ ISDATE: {
72
+ arity: 1,
73
+ compute: args => {
74
+ var _a;
75
+ const value = (_a = args[0]) !== null && _a !== void 0 ? _a : null;
76
+ if (Array.isArray(value)) {
77
+ return value[0] instanceof Date;
78
+ }
79
+ return value instanceof Date;
80
+ },
81
+ },
82
+ ISERROR: {
83
+ arity: 1,
84
+ compute: args => { var _a; return isFormulaErrorValue((_a = args[0]) !== null && _a !== void 0 ? _a : null); },
85
+ },
86
+ ISEVEN: {
87
+ arity: 1,
88
+ compute: args => {
89
+ var _a;
90
+ const value = Number((_a = args[0]) !== null && _a !== void 0 ? _a : 0);
91
+ return Number.isInteger(value) && value % 2 === 0;
92
+ },
93
+ },
94
+ ISNUMBER: {
95
+ arity: 1,
96
+ compute: args => {
97
+ var _a;
98
+ const value = (_a = args[0]) !== null && _a !== void 0 ? _a : null;
99
+ if (Array.isArray(value)) {
100
+ return typeof value[0] === "number";
101
+ }
102
+ return typeof value === "number";
103
+ },
104
+ },
105
+ ISODD: {
106
+ arity: 1,
107
+ compute: args => {
108
+ var _a;
109
+ const value = Number((_a = args[0]) !== null && _a !== void 0 ? _a : 0);
110
+ return Number.isInteger(value) && Math.abs(value % 2) === 1;
111
+ },
112
+ },
113
+ ISTEXT: {
114
+ arity: 1,
115
+ compute: args => {
116
+ var _a;
117
+ const value = (_a = args[0]) !== null && _a !== void 0 ? _a : null;
118
+ if (Array.isArray(value)) {
119
+ return typeof value[0] === "string";
120
+ }
121
+ return typeof value === "string";
122
+ },
123
+ },
124
+ NOT: {
125
+ arity: 1,
126
+ compute: args => { var _a; return !coerceFormulaValueToBoolean((_a = args[0]) !== null && _a !== void 0 ? _a : null); },
127
+ },
128
+ OR: {
129
+ arity: { min: 1 },
130
+ compute: args => args.some(value => coerceFormulaValueToBoolean(value !== null && value !== void 0 ? value : null)),
131
+ },
132
+ COUNTIF: {
133
+ arity: 2,
134
+ compute: args => {
135
+ var _a;
136
+ return expandFormulaValue((_a = args[0]) !== null && _a !== void 0 ? _a : null)
137
+ .filter(value => { var _a; return formulaValueMatchesCriterion(value, (_a = args[1]) !== null && _a !== void 0 ? _a : null); }).length;
138
+ },
139
+ },
140
+ });
@@ -0,0 +1,2 @@
1
+ export declare const DATAGRID_NUMERIC_FORMULA_FUNCTIONS: Readonly<Record<string, import("../types.js").DataGridFormulaFunctionDefinition>>;
2
+ //# sourceMappingURL=numericFunctions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"numericFunctions.d.ts","sourceRoot":"","sources":["../../../src/syntax/functionGroups/numericFunctions.ts"],"names":[],"mappings":"AA2CA,eAAO,MAAM,kCAAkC,mFAsO7C,CAAA"}
@@ -0,0 +1,268 @@
1
+ import { coerceFormulaValueToNumber, } from "../values.js";
2
+ import { collectValuesFromArgs, computeAverage, computeMedian, computePercentile, computeStdDev, countPresentValues, defineFormulaFunctions, expandFormulaArgs, expandFormulaValue, toNumericFormulaValues, } from "../functionHelpers.js";
3
+ function ceilToMultiple(value, multiple) {
4
+ if (!Number.isFinite(multiple) || multiple === 0) {
5
+ return 0;
6
+ }
7
+ const significance = Math.abs(multiple);
8
+ return Math.sign(value || 1) * Math.ceil(Math.abs(value) / significance) * significance;
9
+ }
10
+ function floorToMultiple(value, multiple) {
11
+ if (!Number.isFinite(multiple) || multiple === 0) {
12
+ return 0;
13
+ }
14
+ const significance = Math.abs(multiple);
15
+ if (value >= 0) {
16
+ return Math.floor(value / significance) * significance;
17
+ }
18
+ return -Math.floor(Math.abs(value) / significance) * significance;
19
+ }
20
+ function roundToMultiple(value, multiple) {
21
+ if (!Number.isFinite(multiple) || multiple === 0) {
22
+ return 0;
23
+ }
24
+ const significance = Math.abs(multiple);
25
+ return Math.round(value / significance) * significance;
26
+ }
27
+ export const DATAGRID_NUMERIC_FORMULA_FUNCTIONS = defineFormulaFunctions({
28
+ ABS: {
29
+ arity: 1,
30
+ compute: args => { var _a; return Math.abs(coerceFormulaValueToNumber((_a = args[0]) !== null && _a !== void 0 ? _a : null)); },
31
+ },
32
+ AVG: {
33
+ compute: args => computeAverage(expandFormulaArgs(args)),
34
+ },
35
+ AVERAGE: {
36
+ compute: args => computeAverage(expandFormulaArgs(args)),
37
+ },
38
+ AVGW: {
39
+ arity: 2,
40
+ compute: args => {
41
+ var _a, _b, _c, _d;
42
+ const values = toNumericFormulaValues(expandFormulaValue((_a = args[0]) !== null && _a !== void 0 ? _a : null));
43
+ const weights = toNumericFormulaValues(expandFormulaValue((_b = args[1]) !== null && _b !== void 0 ? _b : null));
44
+ const length = Math.min(values.length, weights.length);
45
+ if (length === 0) {
46
+ return 0;
47
+ }
48
+ let weightedTotal = 0;
49
+ let weightTotal = 0;
50
+ for (let index = 0; index < length; index += 1) {
51
+ const weight = (_c = weights[index]) !== null && _c !== void 0 ? _c : 0;
52
+ weightedTotal += ((_d = values[index]) !== null && _d !== void 0 ? _d : 0) * weight;
53
+ weightTotal += weight;
54
+ }
55
+ return weightTotal === 0 ? 0 : weightedTotal / weightTotal;
56
+ },
57
+ },
58
+ CEIL: {
59
+ arity: { min: 1, max: 2 },
60
+ compute: args => {
61
+ var _a, _b;
62
+ return ceilToMultiple(coerceFormulaValueToNumber((_a = args[0]) !== null && _a !== void 0 ? _a : null), Math.abs(coerceFormulaValueToNumber((_b = args[1]) !== null && _b !== void 0 ? _b : 1)));
63
+ },
64
+ },
65
+ CEILING: {
66
+ arity: { min: 1, max: 2 },
67
+ compute: args => {
68
+ var _a, _b;
69
+ return ceilToMultiple(coerceFormulaValueToNumber((_a = args[0]) !== null && _a !== void 0 ? _a : null), Math.abs(coerceFormulaValueToNumber((_b = args[1]) !== null && _b !== void 0 ? _b : 1)));
70
+ },
71
+ },
72
+ CHAR: {
73
+ arity: 1,
74
+ compute: args => { var _a; return String.fromCharCode(Math.trunc(coerceFormulaValueToNumber((_a = args[0]) !== null && _a !== void 0 ? _a : null))); },
75
+ },
76
+ COUNT: {
77
+ compute: args => countPresentValues(expandFormulaArgs(args)),
78
+ },
79
+ COUNTM: {
80
+ compute: args => countPresentValues(expandFormulaArgs(args)),
81
+ },
82
+ DECTOHEX: {
83
+ arity: 1,
84
+ compute: args => { var _a; return Math.trunc(coerceFormulaValueToNumber((_a = args[0]) !== null && _a !== void 0 ? _a : null)).toString(16).toUpperCase(); },
85
+ },
86
+ FLOOR: {
87
+ arity: { min: 1, max: 2 },
88
+ compute: args => {
89
+ var _a, _b;
90
+ return floorToMultiple(coerceFormulaValueToNumber((_a = args[0]) !== null && _a !== void 0 ? _a : null), Math.abs(coerceFormulaValueToNumber((_b = args[1]) !== null && _b !== void 0 ? _b : 1)));
91
+ },
92
+ },
93
+ HEXTODEC: {
94
+ arity: 1,
95
+ compute: args => {
96
+ var _a;
97
+ const raw = String((_a = args[0]) !== null && _a !== void 0 ? _a : "").trim();
98
+ if (raw.length === 0) {
99
+ return 0;
100
+ }
101
+ const parsed = Number.parseInt(raw, 16);
102
+ return Number.isFinite(parsed) ? parsed : 0;
103
+ },
104
+ },
105
+ INT: {
106
+ arity: 1,
107
+ compute: args => { var _a; return Math.trunc(coerceFormulaValueToNumber((_a = args[0]) !== null && _a !== void 0 ? _a : null)); },
108
+ },
109
+ LARGE: {
110
+ arity: 2,
111
+ compute: args => {
112
+ var _a, _b, _c;
113
+ const values = [...toNumericFormulaValues(expandFormulaValue((_a = args[0]) !== null && _a !== void 0 ? _a : null))].sort((left, right) => right - left);
114
+ const rank = Math.trunc(coerceFormulaValueToNumber((_b = args[1]) !== null && _b !== void 0 ? _b : null));
115
+ return rank < 1 || rank > values.length ? 0 : ((_c = values[rank - 1]) !== null && _c !== void 0 ? _c : 0);
116
+ },
117
+ },
118
+ MAX: {
119
+ compute: args => {
120
+ const values = toNumericFormulaValues(expandFormulaArgs(args));
121
+ return values.length === 0 ? 0 : Math.max(...values);
122
+ },
123
+ },
124
+ MEDIAN: {
125
+ compute: args => computeMedian(expandFormulaArgs(args)),
126
+ },
127
+ MIN: {
128
+ compute: args => {
129
+ const values = toNumericFormulaValues(expandFormulaArgs(args));
130
+ return values.length === 0 ? 0 : Math.min(...values);
131
+ },
132
+ },
133
+ MOD: {
134
+ arity: 2,
135
+ compute: args => {
136
+ var _a, _b;
137
+ const left = coerceFormulaValueToNumber((_a = args[0]) !== null && _a !== void 0 ? _a : null);
138
+ const right = coerceFormulaValueToNumber((_b = args[1]) !== null && _b !== void 0 ? _b : null);
139
+ return right === 0 ? 0 : left % right;
140
+ },
141
+ },
142
+ MROUND: {
143
+ arity: 2,
144
+ compute: args => {
145
+ var _a, _b;
146
+ return roundToMultiple(coerceFormulaValueToNumber((_a = args[0]) !== null && _a !== void 0 ? _a : null), Math.abs(coerceFormulaValueToNumber((_b = args[1]) !== null && _b !== void 0 ? _b : null)));
147
+ },
148
+ },
149
+ NPV: {
150
+ arity: { min: 2 },
151
+ compute: args => {
152
+ var _a;
153
+ const rate = coerceFormulaValueToNumber((_a = args[0]) !== null && _a !== void 0 ? _a : null);
154
+ const cashFlows = toNumericFormulaValues(collectValuesFromArgs(args, 1));
155
+ return cashFlows.reduce((sum, value, index) => sum + (value / ((1 + rate) ** (index + 1))), 0);
156
+ },
157
+ },
158
+ PERCENTILE: {
159
+ arity: 2,
160
+ compute: args => {
161
+ var _a, _b;
162
+ return computePercentile(expandFormulaValue((_a = args[0]) !== null && _a !== void 0 ? _a : null), coerceFormulaValueToNumber((_b = args[1]) !== null && _b !== void 0 ? _b : null));
163
+ },
164
+ },
165
+ POW: {
166
+ arity: 2,
167
+ compute: args => {
168
+ var _a, _b;
169
+ return Math.pow(coerceFormulaValueToNumber((_a = args[0]) !== null && _a !== void 0 ? _a : null), coerceFormulaValueToNumber((_b = args[1]) !== null && _b !== void 0 ? _b : null));
170
+ },
171
+ },
172
+ RANKAVG: {
173
+ arity: { min: 2, max: 3 },
174
+ compute: args => {
175
+ var _a, _b, _c;
176
+ const target = coerceFormulaValueToNumber((_a = args[0]) !== null && _a !== void 0 ? _a : null);
177
+ const values = [...toNumericFormulaValues(expandFormulaValue((_b = args[1]) !== null && _b !== void 0 ? _b : null))];
178
+ const descending = coerceFormulaValueToNumber((_c = args[2]) !== null && _c !== void 0 ? _c : 0) !== 1;
179
+ const sorted = [...values].sort((left, right) => descending ? right - left : left - right);
180
+ const matchingRanks = sorted
181
+ .map((value, index) => (value === target ? index + 1 : null))
182
+ .filter((value) => value !== null);
183
+ if (matchingRanks.length === 0) {
184
+ return 0;
185
+ }
186
+ return matchingRanks.reduce((sum, value) => sum + value, 0) / matchingRanks.length;
187
+ },
188
+ },
189
+ RANKEQ: {
190
+ arity: { min: 2, max: 3 },
191
+ compute: args => {
192
+ var _a, _b, _c;
193
+ const target = coerceFormulaValueToNumber((_a = args[0]) !== null && _a !== void 0 ? _a : null);
194
+ const values = [...toNumericFormulaValues(expandFormulaValue((_b = args[1]) !== null && _b !== void 0 ? _b : null))];
195
+ const descending = coerceFormulaValueToNumber((_c = args[2]) !== null && _c !== void 0 ? _c : 0) !== 1;
196
+ const sorted = [...values].sort((left, right) => descending ? right - left : left - right);
197
+ const rank = sorted.findIndex(value => value === target);
198
+ return rank < 0 ? 0 : rank + 1;
199
+ },
200
+ },
201
+ ROUND: {
202
+ arity: { min: 1, max: 2 },
203
+ compute: args => {
204
+ var _a, _b;
205
+ const value = coerceFormulaValueToNumber((_a = args[0]) !== null && _a !== void 0 ? _a : null);
206
+ const digits = Math.trunc(coerceFormulaValueToNumber((_b = args[1]) !== null && _b !== void 0 ? _b : null));
207
+ const factor = 10 ** Math.abs(digits);
208
+ if (digits >= 0) {
209
+ return Math.round(value * factor) / factor;
210
+ }
211
+ return Math.round(value / factor) * factor;
212
+ },
213
+ },
214
+ ROUNDDOWN: {
215
+ arity: { min: 1, max: 2 },
216
+ compute: args => {
217
+ var _a, _b;
218
+ const value = coerceFormulaValueToNumber((_a = args[0]) !== null && _a !== void 0 ? _a : null);
219
+ const digits = Math.trunc(coerceFormulaValueToNumber((_b = args[1]) !== null && _b !== void 0 ? _b : null));
220
+ const factor = 10 ** Math.abs(digits);
221
+ if (digits >= 0) {
222
+ return Math.trunc(value * factor) / factor;
223
+ }
224
+ return Math.trunc(value / factor) * factor;
225
+ },
226
+ },
227
+ ROUNDUP: {
228
+ arity: { min: 1, max: 2 },
229
+ compute: args => {
230
+ var _a, _b;
231
+ const value = coerceFormulaValueToNumber((_a = args[0]) !== null && _a !== void 0 ? _a : null);
232
+ const digits = Math.trunc(coerceFormulaValueToNumber((_b = args[1]) !== null && _b !== void 0 ? _b : null));
233
+ const factor = 10 ** Math.abs(digits);
234
+ if (digits >= 0) {
235
+ return Math.sign(value || 1) * Math.ceil(Math.abs(value) * factor) / factor;
236
+ }
237
+ return Math.sign(value || 1) * Math.ceil(Math.abs(value) / factor) * factor;
238
+ },
239
+ },
240
+ SMALL: {
241
+ arity: 2,
242
+ compute: args => {
243
+ var _a, _b, _c;
244
+ const values = [...toNumericFormulaValues(expandFormulaValue((_a = args[0]) !== null && _a !== void 0 ? _a : null))].sort((left, right) => left - right);
245
+ const rank = Math.trunc(coerceFormulaValueToNumber((_b = args[1]) !== null && _b !== void 0 ? _b : null));
246
+ return rank < 1 || rank > values.length ? 0 : ((_c = values[rank - 1]) !== null && _c !== void 0 ? _c : 0);
247
+ },
248
+ },
249
+ STDEVA: {
250
+ compute: args => computeStdDev(expandFormulaArgs(args), "sample"),
251
+ },
252
+ STDEVP: {
253
+ compute: args => computeStdDev(expandFormulaArgs(args), "population"),
254
+ },
255
+ STDEVPA: {
256
+ compute: args => computeStdDev(expandFormulaArgs(args), "population"),
257
+ },
258
+ STDEVS: {
259
+ compute: args => computeStdDev(expandFormulaArgs(args), "sample"),
260
+ },
261
+ SUM: {
262
+ compute: args => toNumericFormulaValues(expandFormulaArgs(args)).reduce((sum, value) => sum + value, 0),
263
+ },
264
+ UNICHAR: {
265
+ arity: 1,
266
+ compute: args => { var _a; return String.fromCodePoint(Math.trunc(coerceFormulaValueToNumber((_a = args[0]) !== null && _a !== void 0 ? _a : null))); },
267
+ },
268
+ });
@@ -0,0 +1,2 @@
1
+ export declare const DATAGRID_TEXT_FORMULA_FUNCTIONS: Readonly<Record<string, import("../types.js").DataGridFormulaFunctionDefinition>>;
2
+ //# sourceMappingURL=textFunctions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"textFunctions.d.ts","sourceRoot":"","sources":["../../../src/syntax/functionGroups/textFunctions.ts"],"names":[],"mappings":"AAYA,eAAO,MAAM,+BAA+B,mFA2G1C,CAAA"}
@@ -0,0 +1,118 @@
1
+ import { coerceFormulaValueToNumber, } from "../values.js";
2
+ import { defineFormulaFunctions, expandFormulaArgs, stringifyFormulaScalarValue, } from "../functionHelpers.js";
3
+ export const DATAGRID_TEXT_FORMULA_FUNCTIONS = defineFormulaFunctions({
4
+ CONCAT: {
5
+ compute: args => expandFormulaArgs(args)
6
+ .map(value => stringifyFormulaScalarValue(value))
7
+ .join(""),
8
+ },
9
+ FIND: {
10
+ arity: { min: 2, max: 3 },
11
+ compute: args => {
12
+ var _a, _b, _c;
13
+ const searchFor = String((_a = args[0]) !== null && _a !== void 0 ? _a : "");
14
+ const text = String((_b = args[1]) !== null && _b !== void 0 ? _b : "");
15
+ const startPosition = Math.max(1, Math.trunc(coerceFormulaValueToNumber((_c = args[2]) !== null && _c !== void 0 ? _c : 1)));
16
+ const index = text.indexOf(searchFor, startPosition - 1);
17
+ return index < 0 ? 0 : index + 1;
18
+ },
19
+ },
20
+ JOIN: {
21
+ arity: { min: 1, max: 2 },
22
+ compute: args => {
23
+ var _a, _b;
24
+ const delimiter = args.length > 1 ? String((_a = args[1]) !== null && _a !== void 0 ? _a : "") : "";
25
+ return expandFormulaArgs([(_b = args[0]) !== null && _b !== void 0 ? _b : null]).map(value => stringifyFormulaScalarValue(value)).join(delimiter);
26
+ },
27
+ },
28
+ LEFT: {
29
+ arity: { min: 1, max: 2 },
30
+ compute: args => {
31
+ var _a, _b;
32
+ const text = String((_a = args[0]) !== null && _a !== void 0 ? _a : "");
33
+ const count = Math.max(0, Math.trunc(coerceFormulaValueToNumber((_b = args[1]) !== null && _b !== void 0 ? _b : text.length)));
34
+ return text.slice(0, count);
35
+ },
36
+ },
37
+ LEN: {
38
+ arity: 1,
39
+ compute: args => {
40
+ var _a;
41
+ const value = (_a = args[0]) !== null && _a !== void 0 ? _a : null;
42
+ if (Array.isArray(value)) {
43
+ return value.length;
44
+ }
45
+ return stringifyFormulaScalarValue((value !== null && value !== void 0 ? value : null)).length;
46
+ },
47
+ },
48
+ LOWER: {
49
+ arity: 1,
50
+ compute: args => { var _a; return String((_a = args[0]) !== null && _a !== void 0 ? _a : "").toLowerCase(); },
51
+ },
52
+ MID: {
53
+ arity: 3,
54
+ compute: args => {
55
+ var _a, _b, _c;
56
+ const text = String((_a = args[0]) !== null && _a !== void 0 ? _a : "");
57
+ const start = Math.max(1, Math.trunc(coerceFormulaValueToNumber((_b = args[1]) !== null && _b !== void 0 ? _b : 1)));
58
+ const count = Math.max(0, Math.trunc(coerceFormulaValueToNumber((_c = args[2]) !== null && _c !== void 0 ? _c : 0)));
59
+ return text.slice(start - 1, start - 1 + count);
60
+ },
61
+ },
62
+ REPLACE: {
63
+ arity: 4,
64
+ compute: args => {
65
+ var _a, _b, _c, _d;
66
+ const text = String((_a = args[0]) !== null && _a !== void 0 ? _a : "");
67
+ const start = Math.max(1, Math.trunc(coerceFormulaValueToNumber((_b = args[1]) !== null && _b !== void 0 ? _b : 1)));
68
+ const count = Math.max(0, Math.trunc(coerceFormulaValueToNumber((_c = args[2]) !== null && _c !== void 0 ? _c : 0)));
69
+ const nextText = String((_d = args[3]) !== null && _d !== void 0 ? _d : "");
70
+ return `${text.slice(0, start - 1)}${nextText}${text.slice(start - 1 + count)}`;
71
+ },
72
+ },
73
+ RIGHT: {
74
+ arity: { min: 1, max: 2 },
75
+ compute: args => {
76
+ var _a, _b;
77
+ const text = String((_a = args[0]) !== null && _a !== void 0 ? _a : "");
78
+ const count = Math.max(0, Math.trunc(coerceFormulaValueToNumber((_b = args[1]) !== null && _b !== void 0 ? _b : text.length)));
79
+ return count >= text.length ? text : text.slice(text.length - count);
80
+ },
81
+ },
82
+ SUBSTITUTE: {
83
+ arity: { min: 3, max: 4 },
84
+ compute: args => {
85
+ var _a, _b, _c, _d;
86
+ const text = String((_a = args[0]) !== null && _a !== void 0 ? _a : "");
87
+ const oldText = String((_b = args[1]) !== null && _b !== void 0 ? _b : "");
88
+ const newText = String((_c = args[2]) !== null && _c !== void 0 ? _c : "");
89
+ const replaceNum = Math.trunc(coerceFormulaValueToNumber((_d = args[3]) !== null && _d !== void 0 ? _d : 0));
90
+ if (oldText.length === 0) {
91
+ return text;
92
+ }
93
+ if (replaceNum <= 0) {
94
+ return text.split(oldText).join(newText);
95
+ }
96
+ let seen = 0;
97
+ return text.split(oldText).join("\u0000").split("\u0000").reduce((result, part, index) => {
98
+ if (index === 0) {
99
+ return part;
100
+ }
101
+ seen += 1;
102
+ return `${result}${seen === replaceNum ? newText : oldText}${part}`;
103
+ }, "");
104
+ },
105
+ },
106
+ TRIM: {
107
+ arity: 1,
108
+ compute: args => { var _a; return String((_a = args[0]) !== null && _a !== void 0 ? _a : "").trim(); },
109
+ },
110
+ UPPER: {
111
+ arity: 1,
112
+ compute: args => { var _a; return String((_a = args[0]) !== null && _a !== void 0 ? _a : "").toUpperCase(); },
113
+ },
114
+ VALUE: {
115
+ arity: 1,
116
+ compute: args => { var _a; return coerceFormulaValueToNumber((_a = args[0]) !== null && _a !== void 0 ? _a : null); },
117
+ },
118
+ });
@@ -0,0 +1,45 @@
1
+ import type { DataGridFormulaAstNode, DataGridFormulaFunctionDefinition } from "./types.js";
2
+ import type { DataGridFormulaScalarValue, DataGridFormulaValue } from "../coreTypes.js";
3
+ export type { DataGridFormulaFunctionDefinition, };
4
+ export interface FormulaCriterionEntry {
5
+ range: readonly DataGridFormulaScalarValue[];
6
+ criterion: DataGridFormulaValue;
7
+ }
8
+ export declare function normalizeFormulaTableName(value: DataGridFormulaValue): string;
9
+ export declare function coerceFormulaValueToText(value: DataGridFormulaValue): string;
10
+ export declare function createFormulaTableContextKey(tableName: string): string;
11
+ export declare function resolveFormulaLiteralText(node: DataGridFormulaAstNode | undefined): string | null;
12
+ export declare function defineFormulaFunctions(entries: Readonly<Record<string, DataGridFormulaFunctionDefinition>>): Readonly<Record<string, DataGridFormulaFunctionDefinition>>;
13
+ export declare function collectFormulaTableValues(rowsInput: unknown, fieldValue: DataGridFormulaValue | undefined): readonly DataGridFormulaScalarValue[];
14
+ export declare function findFormulaTableRelatedRows(rowsInput: unknown, keyFieldValue: DataGridFormulaValue | undefined, lookupValue: DataGridFormulaValue): readonly unknown[];
15
+ export declare function collectFormulaTableRelatedValues(rowsInput: unknown, keyFieldValue: DataGridFormulaValue | undefined, lookupValue: DataGridFormulaValue, returnFieldValue: DataGridFormulaValue | undefined): readonly DataGridFormulaScalarValue[];
16
+ export declare function expandFormulaValue(value: DataGridFormulaValue): readonly DataGridFormulaScalarValue[];
17
+ export declare function expandFormulaArgs(args: readonly DataGridFormulaValue[]): readonly DataGridFormulaScalarValue[];
18
+ export declare function coerceFormulaValueToDate(value: DataGridFormulaValue): Date | null;
19
+ export declare function stringifyFormulaScalarValue(value: DataGridFormulaScalarValue): string;
20
+ export declare function flattenFormulaValuesToStrings(values: readonly DataGridFormulaValue[]): readonly string[];
21
+ export declare function formulaValueMatchesCriterion(candidate: DataGridFormulaValue, criterion: DataGridFormulaValue): boolean;
22
+ export declare function collectFilteredValues(values: readonly DataGridFormulaScalarValue[], criteria: ReadonlyArray<{
23
+ range: readonly DataGridFormulaScalarValue[];
24
+ criterion: DataGridFormulaValue;
25
+ }>): readonly DataGridFormulaScalarValue[];
26
+ export declare function toDistinctFormulaValues(values: readonly DataGridFormulaScalarValue[]): readonly DataGridFormulaScalarValue[];
27
+ export declare function toNumericFormulaValues(values: readonly DataGridFormulaScalarValue[]): readonly number[];
28
+ export declare function toStrictNumericFormulaValues(values: readonly DataGridFormulaScalarValue[]): readonly number[];
29
+ export declare function computeAverage(values: readonly DataGridFormulaScalarValue[]): number;
30
+ export declare function computeMedian(values: readonly DataGridFormulaScalarValue[]): number;
31
+ export declare function computePercentile(values: readonly DataGridFormulaScalarValue[], percentile: number): number;
32
+ export declare function computeStdDev(values: readonly DataGridFormulaScalarValue[], mode: "sample" | "population"): number;
33
+ export declare function isWeekday(date: Date): boolean;
34
+ export declare function normalizeHolidayTimes(values: readonly DataGridFormulaValue[]): ReadonlySet<number>;
35
+ export declare function addCalendarDays(date: Date, days: number): Date;
36
+ export declare function countDaysBetween(start: Date, end: Date, inclusive: boolean): number;
37
+ export declare function countWorkingDays(start: Date, end: Date, holidays: ReadonlySet<number>): number;
38
+ export declare function addWorkingDays(start: Date, days: number, holidays: ReadonlySet<number>): Date;
39
+ export declare function countPresentValues(values: readonly DataGridFormulaScalarValue[]): number;
40
+ export declare function booleanResult(value: boolean): boolean;
41
+ export declare function normalizeTextSearch(value: DataGridFormulaValue): string;
42
+ export declare function collectValuesFromArgs(args: readonly DataGridFormulaValue[], startIndex?: number): readonly DataGridFormulaScalarValue[];
43
+ export declare function defaultIfEmpty<T>(value: T | undefined, fallback: T): T;
44
+ export declare function parseTimeLikeValue(value: DataGridFormulaValue): Date | null;
45
+ //# sourceMappingURL=functionHelpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"functionHelpers.d.ts","sourceRoot":"","sources":["../../src/syntax/functionHelpers.ts"],"names":[],"mappings":"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"}