@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,534 @@
1
+ import { parseFormulaReferenceSegments } from "../syntax/tokenizer.js";
2
+ function normalizeName(value, label) {
3
+ const normalized = value.trim();
4
+ if (normalized.length === 0) {
5
+ throw new Error(`[DataGridFormulaExecutionPlan] ${label} must be non-empty.`);
6
+ }
7
+ return normalized;
8
+ }
9
+ function normalizeDependency(dependency) {
10
+ return {
11
+ domain: dependency.domain,
12
+ value: normalizeName(dependency.value, "Dependency name"),
13
+ };
14
+ }
15
+ function splitFieldPathSegments(field) {
16
+ return parseFormulaReferenceSegments(field)
17
+ .map(segment => String(segment).trim())
18
+ .filter(segment => segment.length > 0);
19
+ }
20
+ function collectFieldPathAncestors(field) {
21
+ const segments = splitFieldPathSegments(field);
22
+ if (segments.length === 0) {
23
+ return [];
24
+ }
25
+ const ancestors = [];
26
+ for (let index = 0; index < segments.length; index += 1) {
27
+ ancestors.push(segments.slice(0, index + 1).join("."));
28
+ }
29
+ return ancestors;
30
+ }
31
+ function mergeValueSetIntoMap(target, key, values) {
32
+ var _a;
33
+ if (values.size === 0) {
34
+ return;
35
+ }
36
+ const bucket = (_a = target.get(key)) !== null && _a !== void 0 ? _a : new Set();
37
+ for (const value of values) {
38
+ bucket.add(value);
39
+ }
40
+ target.set(key, bucket);
41
+ }
42
+ function addMapValues(target, source, key) {
43
+ const values = source.get(key);
44
+ if (!values || values.size === 0) {
45
+ return;
46
+ }
47
+ for (const value of values) {
48
+ target.add(value);
49
+ }
50
+ }
51
+ export function createDataGridFormulaExecutionPlan(input, options = {}) {
52
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z;
53
+ const cyclePolicy = options.cyclePolicy === "iterative"
54
+ ? "iterative"
55
+ : "error";
56
+ const nodeByName = new Map();
57
+ const nodeIndexByName = new Map();
58
+ for (const rawNode of input) {
59
+ const name = normalizeName(rawNode.name, "Node name");
60
+ const field = normalizeName(rawNode.field, `Field for node '${name}'`);
61
+ if (nodeByName.has(name)) {
62
+ throw new Error(`[DataGridFormulaExecutionPlan] Duplicate node '${name}'.`);
63
+ }
64
+ const deps = Array.isArray(rawNode.deps)
65
+ ? rawNode.deps.map(normalizeDependency)
66
+ : [];
67
+ nodeByName.set(name, { name, field, deps });
68
+ nodeIndexByName.set(name, nodeIndexByName.size);
69
+ }
70
+ const adjacency = new Map();
71
+ for (const [name, node] of nodeByName) {
72
+ const deps = [];
73
+ for (const dependency of node.deps) {
74
+ if (dependency.domain !== "computed") {
75
+ continue;
76
+ }
77
+ if (!nodeByName.has(dependency.value)) {
78
+ throw new Error(`[DataGridFormulaExecutionPlan] Missing computed dependency '${dependency.value}' for '${name}'.`);
79
+ }
80
+ deps.push(dependency.value);
81
+ }
82
+ adjacency.set(name, deps);
83
+ }
84
+ const indexByName = new Map();
85
+ const lowLinkByName = new Map();
86
+ const stack = [];
87
+ const onStack = new Set();
88
+ const components = [];
89
+ let indexCounter = 0;
90
+ const strongConnect = (name) => {
91
+ var _a, _b, _c, _d, _e, _f, _g;
92
+ indexByName.set(name, indexCounter);
93
+ lowLinkByName.set(name, indexCounter);
94
+ indexCounter += 1;
95
+ stack.push(name);
96
+ onStack.add(name);
97
+ const deps = (_a = adjacency.get(name)) !== null && _a !== void 0 ? _a : [];
98
+ for (const dependencyName of deps) {
99
+ if (!indexByName.has(dependencyName)) {
100
+ strongConnect(dependencyName);
101
+ lowLinkByName.set(name, Math.min((_b = lowLinkByName.get(name)) !== null && _b !== void 0 ? _b : 0, (_c = lowLinkByName.get(dependencyName)) !== null && _c !== void 0 ? _c : 0));
102
+ continue;
103
+ }
104
+ if (onStack.has(dependencyName)) {
105
+ lowLinkByName.set(name, Math.min((_d = lowLinkByName.get(name)) !== null && _d !== void 0 ? _d : 0, (_e = indexByName.get(dependencyName)) !== null && _e !== void 0 ? _e : 0));
106
+ }
107
+ }
108
+ if (((_f = lowLinkByName.get(name)) !== null && _f !== void 0 ? _f : -1) !== ((_g = indexByName.get(name)) !== null && _g !== void 0 ? _g : -2)) {
109
+ return;
110
+ }
111
+ const component = [];
112
+ while (stack.length > 0) {
113
+ const entry = stack.pop();
114
+ if (!entry) {
115
+ break;
116
+ }
117
+ onStack.delete(entry);
118
+ component.push(entry);
119
+ if (entry === name) {
120
+ break;
121
+ }
122
+ }
123
+ component.sort((left, right) => { var _a, _b; return ((_a = nodeIndexByName.get(left)) !== null && _a !== void 0 ? _a : 0) - ((_b = nodeIndexByName.get(right)) !== null && _b !== void 0 ? _b : 0); });
124
+ components.push(component);
125
+ };
126
+ for (const name of nodeByName.keys()) {
127
+ if (!indexByName.has(name)) {
128
+ strongConnect(name);
129
+ }
130
+ }
131
+ const componentIndexByName = new Map();
132
+ for (let componentIndex = 0; componentIndex < components.length; componentIndex += 1) {
133
+ for (const name of (_a = components[componentIndex]) !== null && _a !== void 0 ? _a : []) {
134
+ componentIndexByName.set(name, componentIndex);
135
+ }
136
+ }
137
+ const isIterativeComponent = (component) => {
138
+ var _a;
139
+ if (component.length > 1) {
140
+ return true;
141
+ }
142
+ const name = component[0];
143
+ if (!name) {
144
+ return false;
145
+ }
146
+ return ((_a = adjacency.get(name)) !== null && _a !== void 0 ? _a : []).includes(name);
147
+ };
148
+ const iterativeGroups = components
149
+ .filter(component => isIterativeComponent(component))
150
+ .map(component => Object.freeze([...component]));
151
+ if (cyclePolicy === "error" && iterativeGroups.length > 0) {
152
+ throw new Error(`[DataGridFormulaExecutionPlan] Cycle detected at '${(_c = (_b = iterativeGroups[0]) === null || _b === void 0 ? void 0 : _b[0]) !== null && _c !== void 0 ? _c : "unknown"}'.`);
153
+ }
154
+ const componentDeps = new Map();
155
+ const componentDependents = new Map();
156
+ const indegreeByComponent = new Uint32Array(components.length);
157
+ for (let componentIndex = 0; componentIndex < components.length; componentIndex += 1) {
158
+ const component = (_d = components[componentIndex]) !== null && _d !== void 0 ? _d : [];
159
+ const deps = (_e = componentDeps.get(componentIndex)) !== null && _e !== void 0 ? _e : new Set();
160
+ for (const name of component) {
161
+ for (const dependencyName of (_f = adjacency.get(name)) !== null && _f !== void 0 ? _f : []) {
162
+ const dependencyComponentIndex = componentIndexByName.get(dependencyName);
163
+ if (typeof dependencyComponentIndex !== "number" || dependencyComponentIndex === componentIndex) {
164
+ continue;
165
+ }
166
+ if (!deps.has(dependencyComponentIndex)) {
167
+ deps.add(dependencyComponentIndex);
168
+ indegreeByComponent[componentIndex] = ((_g = indegreeByComponent[componentIndex]) !== null && _g !== void 0 ? _g : 0) + 1;
169
+ }
170
+ const dependents = (_h = componentDependents.get(dependencyComponentIndex)) !== null && _h !== void 0 ? _h : new Set();
171
+ dependents.add(componentIndex);
172
+ componentDependents.set(dependencyComponentIndex, dependents);
173
+ }
174
+ }
175
+ componentDeps.set(componentIndex, deps);
176
+ }
177
+ const availableComponents = [];
178
+ for (let componentIndex = 0; componentIndex < components.length; componentIndex += 1) {
179
+ if (((_j = indegreeByComponent[componentIndex]) !== null && _j !== void 0 ? _j : 0) === 0) {
180
+ availableComponents.push(componentIndex);
181
+ }
182
+ }
183
+ availableComponents.sort((left, right) => {
184
+ var _a, _b;
185
+ const leftOrder = Math.min(...((_a = components[left]) !== null && _a !== void 0 ? _a : []).map(name => { var _a; return (_a = nodeIndexByName.get(name)) !== null && _a !== void 0 ? _a : Number.MAX_SAFE_INTEGER; }));
186
+ const rightOrder = Math.min(...((_b = components[right]) !== null && _b !== void 0 ? _b : []).map(name => { var _a; return (_a = nodeIndexByName.get(name)) !== null && _a !== void 0 ? _a : Number.MAX_SAFE_INTEGER; }));
187
+ return leftOrder - rightOrder;
188
+ });
189
+ const componentOrder = [];
190
+ const componentLevelByIndex = new Map();
191
+ while (availableComponents.length > 0) {
192
+ const componentIndex = availableComponents.shift();
193
+ if (typeof componentIndex !== "number") {
194
+ continue;
195
+ }
196
+ componentOrder.push(componentIndex);
197
+ const deps = (_k = componentDeps.get(componentIndex)) !== null && _k !== void 0 ? _k : new Set();
198
+ let level = 0;
199
+ for (const dependencyComponentIndex of deps) {
200
+ level = Math.max(level, ((_l = componentLevelByIndex.get(dependencyComponentIndex)) !== null && _l !== void 0 ? _l : 0) + 1);
201
+ }
202
+ componentLevelByIndex.set(componentIndex, level);
203
+ for (const dependentComponentIndex of (_m = componentDependents.get(componentIndex)) !== null && _m !== void 0 ? _m : []) {
204
+ indegreeByComponent[dependentComponentIndex] = ((_o = indegreeByComponent[dependentComponentIndex]) !== null && _o !== void 0 ? _o : 0) - 1;
205
+ if (indegreeByComponent[dependentComponentIndex] === 0) {
206
+ availableComponents.push(dependentComponentIndex);
207
+ availableComponents.sort((left, right) => {
208
+ var _a, _b;
209
+ const leftOrder = Math.min(...((_a = components[left]) !== null && _a !== void 0 ? _a : []).map(name => { var _a; return (_a = nodeIndexByName.get(name)) !== null && _a !== void 0 ? _a : Number.MAX_SAFE_INTEGER; }));
210
+ const rightOrder = Math.min(...((_b = components[right]) !== null && _b !== void 0 ? _b : []).map(name => { var _a; return (_a = nodeIndexByName.get(name)) !== null && _a !== void 0 ? _a : Number.MAX_SAFE_INTEGER; }));
211
+ return leftOrder - rightOrder;
212
+ });
213
+ }
214
+ }
215
+ }
216
+ const order = componentOrder.flatMap(componentIndex => { var _a; return (_a = components[componentIndex]) !== null && _a !== void 0 ? _a : []; });
217
+ const levelByName = new Map();
218
+ for (const name of order) {
219
+ const node = nodeByName.get(name);
220
+ if (!node) {
221
+ continue;
222
+ }
223
+ const componentIndex = componentIndexByName.get(name);
224
+ let level = typeof componentIndex === "number"
225
+ ? ((_p = componentLevelByIndex.get(componentIndex)) !== null && _p !== void 0 ? _p : 0)
226
+ : 0;
227
+ levelByName.set(name, level);
228
+ }
229
+ const levelBuckets = new Map();
230
+ const orderIndexByName = new Map();
231
+ for (const name of order) {
232
+ orderIndexByName.set(name, orderIndexByName.size);
233
+ const level = (_q = levelByName.get(name)) !== null && _q !== void 0 ? _q : 0;
234
+ const bucket = (_r = levelBuckets.get(level)) !== null && _r !== void 0 ? _r : [];
235
+ bucket.push(name);
236
+ levelBuckets.set(level, bucket);
237
+ }
238
+ const levels = Array.from(levelBuckets.entries())
239
+ .sort((left, right) => left[0] - right[0])
240
+ .map(([, names]) => Object.freeze([...names]));
241
+ const edges = Object.freeze(order.flatMap((name) => {
242
+ const node = nodeByName.get(name);
243
+ if (!node) {
244
+ return [];
245
+ }
246
+ return node.deps.map((dependency) => Object.freeze({
247
+ from: dependency.value,
248
+ to: name,
249
+ domain: dependency.domain,
250
+ value: dependency.value,
251
+ }));
252
+ }));
253
+ const nodes = new Map();
254
+ const dependentsByField = new Map();
255
+ const dependentsByComputed = new Map();
256
+ const fieldDepsByName = new Map();
257
+ const computedDepsByName = new Map();
258
+ for (const name of order) {
259
+ const node = nodeByName.get(name);
260
+ if (!node) {
261
+ continue;
262
+ }
263
+ const fieldDeps = new Set();
264
+ const computedDeps = new Set();
265
+ for (const dependency of node.deps) {
266
+ if (dependency.domain === "meta") {
267
+ continue;
268
+ }
269
+ if (dependency.domain === "field") {
270
+ fieldDeps.add(dependency.value);
271
+ continue;
272
+ }
273
+ const dependencyNode = nodeByName.get(dependency.value);
274
+ if (!dependencyNode) {
275
+ continue;
276
+ }
277
+ computedDeps.add(dependency.value);
278
+ fieldDeps.add(dependencyNode.field);
279
+ const computedDependents = (_s = dependentsByComputed.get(dependency.value)) !== null && _s !== void 0 ? _s : new Set();
280
+ computedDependents.add(name);
281
+ dependentsByComputed.set(dependency.value, computedDependents);
282
+ }
283
+ for (const field of fieldDeps) {
284
+ const fieldDependents = (_t = dependentsByField.get(field)) !== null && _t !== void 0 ? _t : new Set();
285
+ fieldDependents.add(name);
286
+ dependentsByField.set(field, fieldDependents);
287
+ }
288
+ const orderedFieldDeps = Array.from(fieldDeps);
289
+ const sortedComputedDeps = Array.from(computedDeps)
290
+ .sort((left, right) => {
291
+ var _a, _b;
292
+ const leftIndex = (_a = orderIndexByName.get(left)) !== null && _a !== void 0 ? _a : Number.MAX_SAFE_INTEGER;
293
+ const rightIndex = (_b = orderIndexByName.get(right)) !== null && _b !== void 0 ? _b : Number.MAX_SAFE_INTEGER;
294
+ return leftIndex - rightIndex;
295
+ });
296
+ fieldDepsByName.set(name, Object.freeze(orderedFieldDeps));
297
+ computedDepsByName.set(name, Object.freeze(sortedComputedDeps));
298
+ }
299
+ for (const name of order) {
300
+ const node = nodeByName.get(name);
301
+ if (!node) {
302
+ continue;
303
+ }
304
+ const componentIndex = componentIndexByName.get(name);
305
+ const cycleGroup = typeof componentIndex === "number" && isIterativeComponent((_u = components[componentIndex]) !== null && _u !== void 0 ? _u : [])
306
+ ? Object.freeze([...((_v = components[componentIndex]) !== null && _v !== void 0 ? _v : [])])
307
+ : null;
308
+ const sortedDependents = Array.from((_w = dependentsByComputed.get(name)) !== null && _w !== void 0 ? _w : [])
309
+ .sort((left, right) => {
310
+ var _a, _b;
311
+ const leftIndex = (_a = orderIndexByName.get(left)) !== null && _a !== void 0 ? _a : Number.MAX_SAFE_INTEGER;
312
+ const rightIndex = (_b = orderIndexByName.get(right)) !== null && _b !== void 0 ? _b : Number.MAX_SAFE_INTEGER;
313
+ return leftIndex - rightIndex;
314
+ });
315
+ nodes.set(name, Object.freeze({
316
+ name,
317
+ field: node.field,
318
+ level: (_x = levelByName.get(name)) !== null && _x !== void 0 ? _x : 0,
319
+ fieldDeps: (_y = fieldDepsByName.get(name)) !== null && _y !== void 0 ? _y : Object.freeze([]),
320
+ computedDeps: (_z = computedDepsByName.get(name)) !== null && _z !== void 0 ? _z : Object.freeze([]),
321
+ dependents: Object.freeze(sortedDependents),
322
+ ...(cycleGroup
323
+ ? {
324
+ iterative: true,
325
+ cycleGroup,
326
+ }
327
+ : {}),
328
+ }));
329
+ }
330
+ const affectedByComputedClosure = new Map();
331
+ for (let index = order.length - 1; index >= 0; index -= 1) {
332
+ const name = order[index];
333
+ if (!name) {
334
+ continue;
335
+ }
336
+ const closure = new Set([name]);
337
+ const dependents = dependentsByComputed.get(name);
338
+ if (dependents && dependents.size > 0) {
339
+ for (const dependentName of dependents) {
340
+ const dependentClosure = affectedByComputedClosure.get(dependentName);
341
+ if (!dependentClosure) {
342
+ closure.add(dependentName);
343
+ continue;
344
+ }
345
+ for (const computedName of dependentClosure) {
346
+ closure.add(computedName);
347
+ }
348
+ }
349
+ }
350
+ affectedByComputedClosure.set(name, closure);
351
+ }
352
+ const affectedByFieldClosure = new Map();
353
+ for (const [field, directDependents] of dependentsByField) {
354
+ const closure = new Set();
355
+ for (const dependentName of directDependents) {
356
+ const dependentClosure = affectedByComputedClosure.get(dependentName);
357
+ if (!dependentClosure) {
358
+ closure.add(dependentName);
359
+ continue;
360
+ }
361
+ for (const computedName of dependentClosure) {
362
+ closure.add(computedName);
363
+ }
364
+ }
365
+ affectedByFieldClosure.set(field, closure);
366
+ }
367
+ const directByFieldPrefixClosure = new Map();
368
+ for (const [field, directDependents] of dependentsByField) {
369
+ const ancestors = collectFieldPathAncestors(field);
370
+ if (ancestors.length === 0) {
371
+ continue;
372
+ }
373
+ for (const ancestor of ancestors) {
374
+ mergeValueSetIntoMap(directByFieldPrefixClosure, ancestor, directDependents);
375
+ }
376
+ }
377
+ const affectedByFieldPrefixClosure = new Map();
378
+ for (const [field, closure] of affectedByFieldClosure) {
379
+ const ancestors = collectFieldPathAncestors(field);
380
+ if (ancestors.length === 0) {
381
+ continue;
382
+ }
383
+ for (const ancestor of ancestors) {
384
+ mergeValueSetIntoMap(affectedByFieldPrefixClosure, ancestor, closure);
385
+ }
386
+ }
387
+ const directByFields = (changedFields) => {
388
+ const affectedNames = new Set();
389
+ for (const rawField of changedFields) {
390
+ const field = rawField.trim();
391
+ if (field.length === 0) {
392
+ continue;
393
+ }
394
+ addMapValues(affectedNames, directByFieldPrefixClosure, field);
395
+ const ancestors = collectFieldPathAncestors(field);
396
+ for (const ancestor of ancestors) {
397
+ const directDependents = dependentsByField.get(ancestor);
398
+ if (!directDependents || directDependents.size === 0) {
399
+ continue;
400
+ }
401
+ for (const dependentName of directDependents) {
402
+ affectedNames.add(dependentName);
403
+ }
404
+ }
405
+ }
406
+ return affectedNames;
407
+ };
408
+ const affectedByFields = (changedFields) => {
409
+ const affectedNames = new Set();
410
+ for (const rawField of changedFields) {
411
+ const field = rawField.trim();
412
+ if (field.length === 0) {
413
+ continue;
414
+ }
415
+ addMapValues(affectedNames, affectedByFieldPrefixClosure, field);
416
+ const ancestors = collectFieldPathAncestors(field);
417
+ for (const ancestor of ancestors) {
418
+ addMapValues(affectedNames, affectedByFieldClosure, ancestor);
419
+ }
420
+ }
421
+ return affectedNames;
422
+ };
423
+ const affectedByComputed = (changedComputed) => {
424
+ const affectedNames = new Set();
425
+ for (const rawComputed of changedComputed) {
426
+ const computed = rawComputed.trim();
427
+ if (computed.length === 0) {
428
+ continue;
429
+ }
430
+ const affectedByComputedValue = affectedByComputedClosure.get(computed);
431
+ if (!affectedByComputedValue) {
432
+ continue;
433
+ }
434
+ for (const name of affectedByComputedValue) {
435
+ affectedNames.add(name);
436
+ }
437
+ }
438
+ return affectedNames;
439
+ };
440
+ const iterativeGroupSetByName = new Map();
441
+ for (const group of iterativeGroups) {
442
+ for (const name of group) {
443
+ iterativeGroupSetByName.set(name, group);
444
+ }
445
+ }
446
+ const levelDetails = Object.freeze(levels.map((level, index) => {
447
+ const cycleGroups = level
448
+ .map(name => iterativeGroupSetByName.get(name))
449
+ .filter((group, groupIndex, allGroups) => {
450
+ if (!group) {
451
+ return false;
452
+ }
453
+ return allGroups.indexOf(group) === groupIndex;
454
+ });
455
+ return Object.freeze({
456
+ index,
457
+ nodes: Object.freeze([...level]),
458
+ ...(cycleGroups.length > 0
459
+ ? {
460
+ iterative: true,
461
+ cycleGroups: Object.freeze(cycleGroups.map(group => Object.freeze([...group]))),
462
+ }
463
+ : {}),
464
+ });
465
+ }));
466
+ return {
467
+ order: Object.freeze([...order]),
468
+ levels: Object.freeze([...levels]),
469
+ levelDetails,
470
+ nodes,
471
+ edges,
472
+ iterativeGroups: Object.freeze(iterativeGroups.map(group => Object.freeze([...group]))),
473
+ directByFields,
474
+ affectedByFields,
475
+ affectedByComputed,
476
+ };
477
+ }
478
+ export const createDataGridFormulaGraph = createDataGridFormulaExecutionPlan;
479
+ export function snapshotDataGridFormulaExecutionPlan(plan) {
480
+ const order = Object.freeze([...plan.order]);
481
+ const levels = Object.freeze(plan.levels.map(level => Object.freeze([...level])));
482
+ const nodes = Object.freeze(order.reduce((accumulator, name) => {
483
+ const node = plan.nodes.get(name);
484
+ if (!node) {
485
+ return accumulator;
486
+ }
487
+ accumulator.push({
488
+ name: node.name,
489
+ field: node.field,
490
+ level: node.level,
491
+ fieldDeps: Object.freeze([...node.fieldDeps]),
492
+ computedDeps: Object.freeze([...node.computedDeps]),
493
+ dependents: Object.freeze([...node.dependents]),
494
+ ...(node.iterative ? { iterative: true } : {}),
495
+ ...(node.cycleGroup ? { cycleGroup: Object.freeze([...node.cycleGroup]) } : {}),
496
+ });
497
+ return accumulator;
498
+ }, []));
499
+ return {
500
+ order,
501
+ levels,
502
+ nodes,
503
+ ...(plan.iterativeGroups.length > 0
504
+ ? {
505
+ iterativeGroups: Object.freeze(plan.iterativeGroups.map(group => Object.freeze([...group]))),
506
+ }
507
+ : {}),
508
+ };
509
+ }
510
+ export function snapshotDataGridFormulaGraph(plan) {
511
+ const executionPlanSnapshot = snapshotDataGridFormulaExecutionPlan(plan);
512
+ return {
513
+ order: executionPlanSnapshot.order,
514
+ levels: executionPlanSnapshot.levels,
515
+ levelDetails: plan.levelDetails.map(level => ({
516
+ index: level.index,
517
+ nodes: [...level.nodes],
518
+ ...(level.iterative ? { iterative: true } : {}),
519
+ ...(level.cycleGroups
520
+ ? { cycleGroups: level.cycleGroups.map(group => [...group]) }
521
+ : {}),
522
+ })),
523
+ nodes: executionPlanSnapshot.nodes,
524
+ edges: plan.edges.map(edge => ({
525
+ from: edge.from,
526
+ to: edge.to,
527
+ domain: edge.domain,
528
+ value: edge.value,
529
+ })),
530
+ ...(executionPlanSnapshot.iterativeGroups
531
+ ? { iterativeGroups: executionPlanSnapshot.iterativeGroups.map(group => [...group]) }
532
+ : {}),
533
+ };
534
+ }
@@ -0,0 +1,2 @@
1
+ export * from "./executionPlan.js";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/graph/index.ts"],"names":[],"mappings":"AAEA,cAAc,oBAAoB,CAAA"}
@@ -0,0 +1,3 @@
1
+ // Dependency/execution-plan ownership. Runtime and host integrations should
2
+ // depend on this surface rather than the internal graph file layout.
3
+ export * from "./executionPlan.js";
@@ -0,0 +1,8 @@
1
+ export type { DataGridComputedDependencyToken, DataGridFormulaReferenceDescriptor, DataGridFormulaReferenceDomain, DataGridFormulaReferenceRowDomain, DataGridComputedFieldComputeContext, DataGridComputedFieldDefinition, DataGridComputedFieldSnapshot, DataGridFormulaMetaField, DataGridFormulaContextRecomputeRequest, DataGridFormulaCyclePolicy, DataGridFormulaFieldDefinition, DataGridFormulaFieldSnapshot, DataGridFormulaTableRowsSource, DataGridFormulaTableSource, DataGridFormulaArrayValue, DataGridFormulaErrorValue, DataGridFormulaIterativeCalculationOptions, DataGridFormulaScalarValue, DataGridFormulaValue, DataGridFormulaRuntimeErrorCode, DataGridFormulaRuntimeError, DataGridFormulaDirtyCause, DataGridFormulaDirtyRowCause, DataGridProjectionFormulaDiagnostics, DataGridFormulaComputeStageDiagnostics, DataGridFormulaNodeComputeDiagnostics, DataGridFormulaRowNodeRecomputeDiagnostics, DataGridFormulaRowRecomputeDiagnosticsEntry, DataGridFormulaRowRecomputeDiagnostics, DataGridFormulaRuntimeIntegration, DataGridRowId, } from "./coreTypes.js";
2
+ export type { DataGridCompiledFormulaArtifact, DataGridCompiledFormulaBatchContext, DataGridCompiledFormulaBatchExecutionMode, DataGridCompiledFormulaField, DataGridFormulaAstNode, DataGridFormulaDiagnostic, DataGridFormulaExpressionAnalysis, DataGridFormulaExplainDependency, DataGridFormulaExplainDependencyDomain, DataGridFormulaExplainNode, DataGridFormulaExplainResult, DataGridFormulaFieldExplainResult, DataGridFormulaCompileOptions, DataGridFormulaCompileStrategy, DataGridFormulaFunctionArity, DataGridFormulaFunctionDefinition, DataGridFormulaFunctionRegistry, DataGridFormulaParseResult, DataGridFormulaReferenceParserOptions, DataGridFormulaReferenceSyntax, DataGridFormulaRowSelector, DataGridFormulaRuntimeErrorPolicy, DataGridFormulaDiagnosticsResult, DataGridFormulaSourceSpan, } from "./syntax/index.js";
3
+ export type { DataGridFormulaExecutionDependencyDomain, DataGridFormulaExecutionDependency, DataGridFormulaGraphEdgeSnapshot, DataGridFormulaGraphLevelSnapshot, DataGridFormulaGraphSnapshot, DataGridFormulaExecutionPlanNode, DataGridFormulaExecutionPlanNodeSnapshot, DataGridFormulaExecutionPlan, DataGridFormulaExecutionPlanSnapshot, } from "./graph/index.js";
4
+ export { DATAGRID_FORMULA_META_FIELDS, isDataGridFormulaMetaField, parseDataGridComputedDependencyToken, serializeDataGridComputedDependencyToken, } from "./contracts.js";
5
+ export { DATAGRID_DEFAULT_FORMULA_FUNCTIONS, normalizeFormulaFunctionRegistry, collectFormulaContextKeys, explainDataGridFormulaExpression, explainDataGridFormulaFieldDefinition, createFormulaErrorValue, createFormulaSourceSpan, createFormulaDiagnostic, diagnoseDataGridFormulaExpression, findFormulaErrorValue, getFormulaNodeSpan, isFormulaErrorValue, isFormulaValueBlank, isFormulaValueEmptyText, normalizeFormulaValue, normalizeFormulaDiagnostic, parseDataGridFormulaExpression, parseDataGridFormulaIdentifier, parseFormulaReferenceSegments, normalizeFormulaReference, coerceFormulaValueToNumber, coerceFormulaValueToBoolean, areFormulaValuesEqual, compareFormulaValues, } from "./syntax/index.js";
6
+ export { analyzeDataGridFormulaFieldDefinition, bindCompiledFormulaArtifactToFieldDefinition, compileDataGridFormulaFieldArtifact, compileDataGridFormulaFieldDefinition, } from "./runtime/index.js";
7
+ export { createDataGridFormulaGraph, createDataGridFormulaExecutionPlan, snapshotDataGridFormulaGraph, snapshotDataGridFormulaExecutionPlan, } from "./graph/index.js";
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,YAAY,EACV,+BAA+B,EAC/B,kCAAkC,EAClC,8BAA8B,EAC9B,iCAAiC,EACjC,mCAAmC,EACnC,+BAA+B,EAC/B,6BAA6B,EAC7B,wBAAwB,EACxB,sCAAsC,EACtC,0BAA0B,EAC1B,8BAA8B,EAC9B,4BAA4B,EAC5B,8BAA8B,EAC9B,0BAA0B,EAC1B,yBAAyB,EACzB,yBAAyB,EACzB,0CAA0C,EAC1C,0BAA0B,EAC1B,oBAAoB,EACpB,+BAA+B,EAC/B,2BAA2B,EAC3B,yBAAyB,EACzB,4BAA4B,EAC5B,oCAAoC,EACpC,sCAAsC,EACtC,qCAAqC,EACrC,0CAA0C,EAC1C,2CAA2C,EAC3C,sCAAsC,EACtC,iCAAiC,EACjC,aAAa,GACd,MAAM,gBAAgB,CAAA;AAEvB,YAAY,EACV,+BAA+B,EAC/B,mCAAmC,EACnC,yCAAyC,EACzC,4BAA4B,EAC5B,sBAAsB,EACtB,yBAAyB,EACzB,iCAAiC,EACjC,gCAAgC,EAChC,sCAAsC,EACtC,0BAA0B,EAC1B,4BAA4B,EAC5B,iCAAiC,EACjC,6BAA6B,EAC7B,8BAA8B,EAC9B,4BAA4B,EAC5B,iCAAiC,EACjC,+BAA+B,EAC/B,0BAA0B,EAC1B,qCAAqC,EACrC,8BAA8B,EAC9B,0BAA0B,EAC1B,iCAAiC,EACjC,gCAAgC,EAChC,yBAAyB,GAC1B,MAAM,mBAAmB,CAAA;AAE1B,YAAY,EACV,wCAAwC,EACxC,kCAAkC,EAClC,gCAAgC,EAChC,iCAAiC,EACjC,4BAA4B,EAC5B,gCAAgC,EAChC,wCAAwC,EACxC,4BAA4B,EAC5B,oCAAoC,GACrC,MAAM,kBAAkB,CAAA;AAEzB,OAAO,EACL,4BAA4B,EAC5B,0BAA0B,EAC1B,oCAAoC,EACpC,wCAAwC,GACzC,MAAM,gBAAgB,CAAA;AAEvB,OAAO,EACL,kCAAkC,EAClC,gCAAgC,EAChC,yBAAyB,EACzB,gCAAgC,EAChC,qCAAqC,EACrC,uBAAuB,EACvB,uBAAuB,EACvB,uBAAuB,EACvB,iCAAiC,EACjC,qBAAqB,EACrB,kBAAkB,EAClB,mBAAmB,EACnB,mBAAmB,EACnB,uBAAuB,EACvB,qBAAqB,EACrB,0BAA0B,EAC1B,8BAA8B,EAC9B,8BAA8B,EAC9B,6BAA6B,EAC7B,yBAAyB,EACzB,0BAA0B,EAC1B,2BAA2B,EAC3B,qBAAqB,EACrB,oBAAoB,GACrB,MAAM,mBAAmB,CAAA;AAE1B,OAAO,EACL,qCAAqC,EACrC,4CAA4C,EAC5C,mCAAmC,EACnC,qCAAqC,GACtC,MAAM,oBAAoB,CAAA;AAE3B,OAAO,EACL,0BAA0B,EAC1B,kCAAkC,EAClC,4BAA4B,EAC5B,oCAAoC,GACrC,MAAM,kBAAkB,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,4 @@
1
+ export { DATAGRID_FORMULA_META_FIELDS, isDataGridFormulaMetaField, parseDataGridComputedDependencyToken, serializeDataGridComputedDependencyToken, } from "./contracts.js";
2
+ export { DATAGRID_DEFAULT_FORMULA_FUNCTIONS, normalizeFormulaFunctionRegistry, collectFormulaContextKeys, explainDataGridFormulaExpression, explainDataGridFormulaFieldDefinition, createFormulaErrorValue, createFormulaSourceSpan, createFormulaDiagnostic, diagnoseDataGridFormulaExpression, findFormulaErrorValue, getFormulaNodeSpan, isFormulaErrorValue, isFormulaValueBlank, isFormulaValueEmptyText, normalizeFormulaValue, normalizeFormulaDiagnostic, parseDataGridFormulaExpression, parseDataGridFormulaIdentifier, parseFormulaReferenceSegments, normalizeFormulaReference, coerceFormulaValueToNumber, coerceFormulaValueToBoolean, areFormulaValuesEqual, compareFormulaValues, } from "./syntax/index.js";
3
+ export { analyzeDataGridFormulaFieldDefinition, bindCompiledFormulaArtifactToFieldDefinition, compileDataGridFormulaFieldArtifact, compileDataGridFormulaFieldDefinition, } from "./runtime/index.js";
4
+ export { createDataGridFormulaGraph, createDataGridFormulaExecutionPlan, snapshotDataGridFormulaGraph, snapshotDataGridFormulaExecutionPlan, } from "./graph/index.js";
@@ -0,0 +1,7 @@
1
+ import type { DataGridFormulaFieldDefinition } from "../coreTypes.js";
2
+ import { type DataGridCompiledFormulaArtifact, type DataGridCompiledFormulaField, type DataGridFormulaExpressionAnalysis, type DataGridFormulaCompileOptions } from "../syntax/core.js";
3
+ export declare function analyzeDataGridFormulaFieldDefinition(definition: DataGridFormulaFieldDefinition, options?: DataGridFormulaCompileOptions): DataGridFormulaExpressionAnalysis;
4
+ export declare function bindCompiledFormulaArtifactToFieldDefinition<TRow = unknown>(artifact: DataGridCompiledFormulaArtifact<TRow>, definition: DataGridFormulaFieldDefinition, options?: Pick<DataGridFormulaCompileOptions, "runtimeErrorPolicy" | "onRuntimeError">): DataGridCompiledFormulaField<TRow>;
5
+ export declare function compileDataGridFormulaFieldArtifact<TRow = unknown>(definition: DataGridFormulaFieldDefinition, options?: DataGridFormulaCompileOptions): DataGridCompiledFormulaArtifact<TRow>;
6
+ export declare function compileDataGridFormulaFieldDefinition<TRow = unknown>(definition: DataGridFormulaFieldDefinition, options?: DataGridFormulaCompileOptions): DataGridCompiledFormulaField<TRow>;
7
+ //# sourceMappingURL=compile.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compile.d.ts","sourceRoot":"","sources":["../../src/runtime/compile.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAGV,8BAA8B,EAG/B,MAAM,iBAAiB,CAAA;AACxB,OAAO,EAEL,KAAK,+BAA+B,EACpC,KAAK,4BAA4B,EAGjC,KAAK,iCAAiC,EACtC,KAAK,6BAA6B,EAInC,MAAM,mBAAmB,CAAA;AAwN1B,wBAAgB,qCAAqC,CACnD,UAAU,EAAE,8BAA8B,EAC1C,OAAO,GAAE,6BAAkC,GAC1C,iCAAiC,CASnC;AAED,wBAAgB,4CAA4C,CAAC,IAAI,GAAG,OAAO,EACzE,QAAQ,EAAE,+BAA+B,CAAC,IAAI,CAAC,EAC/C,UAAU,EAAE,8BAA8B,EAC1C,OAAO,GAAE,IAAI,CAAC,6BAA6B,EAAE,oBAAoB,GAAG,gBAAgB,CAAM,GACzF,4BAA4B,CAAC,IAAI,CAAC,CAEpC;AAED,wBAAgB,mCAAmC,CAAC,IAAI,GAAG,OAAO,EAChE,UAAU,EAAE,8BAA8B,EAC1C,OAAO,GAAE,6BAAkC,GAC1C,+BAA+B,CAAC,IAAI,CAAC,CA8WvC;AAED,wBAAgB,qCAAqC,CAAC,IAAI,GAAG,OAAO,EAClE,UAAU,EAAE,8BAA8B,EAC1C,OAAO,GAAE,6BAAkC,GAC1C,4BAA4B,CAAC,IAAI,CAAC,CAGpC"}