@ricsam/formula-engine 0.0.4 → 0.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/dist/cjs/core/engine.cjs +62 -2
  2. package/dist/cjs/core/engine.cjs.map +3 -3
  3. package/dist/cjs/core/managers/dependency-manager.cjs +32 -39
  4. package/dist/cjs/core/managers/dependency-manager.cjs.map +3 -3
  5. package/dist/cjs/core/managers/evaluation-manager.cjs +31 -34
  6. package/dist/cjs/core/managers/evaluation-manager.cjs.map +3 -3
  7. package/dist/cjs/core/managers/style-manager.cjs +341 -0
  8. package/dist/cjs/core/managers/style-manager.cjs.map +10 -0
  9. package/dist/cjs/core/types.cjs.map +1 -1
  10. package/dist/cjs/core/utils/color-utils.cjs +137 -0
  11. package/dist/cjs/core/utils/color-utils.cjs.map +10 -0
  12. package/dist/cjs/evaluator/dependency-nodes/virtual-cell-value-node.cjs +55 -0
  13. package/dist/cjs/evaluator/dependency-nodes/virtual-cell-value-node.cjs.map +10 -0
  14. package/dist/cjs/evaluator/formula-evaluator.cjs +3 -3
  15. package/dist/cjs/evaluator/formula-evaluator.cjs.map +3 -3
  16. package/dist/cjs/functions/{index.cjs → function-registry.cjs} +5 -5
  17. package/dist/cjs/functions/{index.cjs.map → function-registry.cjs.map} +2 -2
  18. package/dist/cjs/package.json +1 -1
  19. package/dist/mjs/core/engine.mjs +62 -2
  20. package/dist/mjs/core/engine.mjs.map +3 -3
  21. package/dist/mjs/core/managers/dependency-manager.mjs +37 -41
  22. package/dist/mjs/core/managers/dependency-manager.mjs.map +3 -3
  23. package/dist/mjs/core/managers/evaluation-manager.mjs +31 -34
  24. package/dist/mjs/core/managers/evaluation-manager.mjs.map +3 -3
  25. package/dist/mjs/core/managers/style-manager.mjs +315 -0
  26. package/dist/mjs/core/managers/style-manager.mjs.map +10 -0
  27. package/dist/mjs/core/types.mjs.map +1 -1
  28. package/dist/mjs/core/utils/color-utils.mjs +107 -0
  29. package/dist/mjs/core/utils/color-utils.mjs.map +10 -0
  30. package/dist/mjs/evaluator/dependency-nodes/virtual-cell-value-node.mjs +25 -0
  31. package/dist/mjs/evaluator/dependency-nodes/virtual-cell-value-node.mjs.map +10 -0
  32. package/dist/mjs/evaluator/formula-evaluator.mjs +2 -2
  33. package/dist/mjs/evaluator/formula-evaluator.mjs.map +2 -2
  34. package/dist/mjs/functions/{index.mjs → function-registry.mjs} +2 -2
  35. package/dist/mjs/functions/{index.mjs.map → function-registry.mjs.map} +2 -2
  36. package/dist/mjs/package.json +1 -1
  37. package/dist/types/core/engine.d.ts +39 -1
  38. package/dist/types/core/managers/dependency-manager.d.ts +8 -7
  39. package/dist/types/core/managers/evaluation-manager.d.ts +13 -3
  40. package/dist/types/core/managers/style-manager.d.ts +92 -0
  41. package/dist/types/core/types.d.ts +42 -0
  42. package/dist/types/core/utils/color-utils.d.ts +32 -0
  43. package/dist/types/evaluator/dependency-nodes/virtual-cell-value-node.d.ts +11 -0
  44. package/package.json +1 -1
  45. /package/dist/types/functions/{index.d.ts → function-registry.d.ts} +0 -0
@@ -22,6 +22,7 @@ import {
22
22
  } from "../utils.mjs";
23
23
  import { SpillMetaNode } from "../../evaluator/dependency-nodes/spill-meta-node.mjs";
24
24
  import { EmptyCellEvaluationNode } from "../../evaluator/dependency-nodes/empty-cell-evaluation-node.mjs";
25
+ import { VirtualCellValueNode } from "../../evaluator/dependency-nodes/virtual-cell-value-node.mjs";
25
26
 
26
27
  class EvaluationManager {
27
28
  workbookManager;
@@ -170,7 +171,11 @@ class EvaluationManager {
170
171
  }
171
172
  let content;
172
173
  try {
173
- content = this.workbookManager.getSerializedCellValue(node.cellAddress);
174
+ if (node instanceof VirtualCellValueNode) {
175
+ content = node.cellValue;
176
+ } else {
177
+ content = this.workbookManager.getSerializedCellValue(node.cellAddress);
178
+ }
174
179
  } catch (err) {
175
180
  const evaluationResult = {
176
181
  type: "error",
@@ -240,48 +245,44 @@ class EvaluationManager {
240
245
  }
241
246
  node.setEvaluationResult(evaluation);
242
247
  }
243
- evaluateDependencyNode(dependencyKey) {
244
- if (dependencyKey.startsWith("empty:")) {
245
- this.evaluateEmptyCell(this.dependencyManager.getEmptyCellNode(dependencyKey));
248
+ evaluateDependencyNode(dependency) {
249
+ if (dependency instanceof EmptyCellEvaluationNode) {
250
+ this.evaluateEmptyCell(dependency);
246
251
  return;
247
252
  }
248
- if (dependencyKey.startsWith("range:")) {
249
- this.evaluateRangeNode(this.dependencyManager.getRangeNode(dependencyKey));
253
+ if (dependency instanceof RangeEvaluationNode) {
254
+ this.evaluateRangeNode(dependency);
250
255
  return;
251
256
  }
252
- if (dependencyKey.startsWith("cell-value:")) {
253
- const node = this.dependencyManager.getCellValueOrEmptyCellNode(dependencyKey);
254
- if (node instanceof EmptyCellEvaluationNode) {
255
- this.evaluateEmptyCell(node);
256
- return;
257
- }
258
- this.evaluateCellNode(node);
257
+ if (dependency instanceof CellValueNode || dependency instanceof VirtualCellValueNode) {
258
+ this.evaluateCellNode(dependency);
259
259
  return;
260
260
  }
261
- if (dependencyKey.startsWith("ast:")) {
261
+ if (dependency instanceof AstEvaluationNode) {
262
262
  return;
263
263
  }
264
- if (dependencyKey.startsWith("spill-meta:")) {
265
- const node = this.dependencyManager.getSpillMetaOrEmptySpillMetaNode(dependencyKey);
266
- if (node instanceof EmptyCellEvaluationNode) {
267
- this.evaluateEmptyCell(node);
268
- return;
269
- }
270
- this.evaluateCellNode(node);
264
+ if (dependency instanceof SpillMetaNode) {
265
+ this.evaluateCellNode(dependency);
271
266
  return;
272
267
  }
273
- throw new Error("Invalid dependency key: " + dependencyKey);
268
+ throw new Error("Invalid dependency: " + dependency.key);
269
+ }
270
+ evaluateFormula(cellValue, cellAddress) {
271
+ if (this.isEvaluating) {
272
+ throw new Error("Evaluation in progress");
273
+ }
274
+ const node = this.dependencyManager.getVirtualCellValueNode(cellAddress, cellValue);
275
+ if (node.evaluationResult.type === "awaiting-evaluation") {
276
+ this.evaluateCell(node);
277
+ }
278
+ const result = node.evaluationResult;
279
+ return this.evaluationResultToSerializedValue(result, cellAddress);
274
280
  }
275
281
  evaluateCell(node) {
276
282
  if (this.isEvaluating) {
277
283
  throw new Error("Evaluation in progress");
278
284
  }
279
285
  this.isEvaluating = true;
280
- const sheet = this.workbookManager.getSheet(node.cellAddress);
281
- if (!sheet) {
282
- this.isEvaluating = false;
283
- throw new SheetNotFoundError(node.cellAddress.sheetName);
284
- }
285
286
  let precalculatedPlan;
286
287
  let requiresReRun = true;
287
288
  while (requiresReRun) {
@@ -297,11 +298,7 @@ class EvaluationManager {
297
298
  if (evaluationPlan.cycleNodes) {
298
299
  for (const node2 of evaluationPlan.cycleNodes) {
299
300
  if (!(node2 instanceof RangeEvaluationNode)) {
300
- if (node2 instanceof AstEvaluationNode) {
301
- node2.setEvaluationResult(evaluationResult);
302
- } else {
303
- node2.setEvaluationResult(evaluationResult);
304
- }
301
+ node2.setEvaluationResult(evaluationResult);
305
302
  }
306
303
  }
307
304
  }
@@ -316,7 +313,7 @@ class EvaluationManager {
316
313
  if (dependency.resolved) {
317
314
  numResolved++;
318
315
  }
319
- this.evaluateDependencyNode(dependency.key);
316
+ this.evaluateDependencyNode(dependency);
320
317
  const end = performance.now();
321
318
  if (flags.isProfiling && evaluationPlan.evaluationOrder.size > -1) {
322
319
  durations.push({ duration: end - start, key: dependency.key });
@@ -412,4 +409,4 @@ export {
412
409
  EvaluationManager
413
410
  };
414
411
 
415
- //# debugId=CBD41BDE565D9B5964756E2164756E21
412
+ //# debugId=0649B69F38BEDF9864756E2164756E21
@@ -2,9 +2,9 @@
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/core/managers/evaluation-manager.ts"],
4
4
  "sourcesContent": [
5
- "import { flags } from \"../../debug/flags.mjs\";\nimport { AstEvaluationNode } from \"../../evaluator/dependency-nodes/ast-evaluation-node.mjs\";\nimport { CellValueNode } from \"../../evaluator/dependency-nodes/cell-value-node.mjs\";\nimport { EvaluationContext } from \"../../evaluator/evaluation-context.mjs\";\nimport {\n EvaluationError,\n SheetNotFoundError,\n} from \"../../evaluator/evaluation-error.mjs\";\nimport { RangeEvaluationNode } from \"../../evaluator/range-evaluation-node.mjs\";\nimport { normalizeSerializedCellValue } from \"../../parser/formatter.mjs\";\nimport { FormulaEvaluator } from \"../../evaluator/formula-evaluator.mjs\";\nimport {\n FormulaError,\n type CellAddress,\n type CellInRangeResult,\n type CellValue,\n type ErrorEvaluationResult,\n type EvaluateAllCellsResult,\n type EvaluationOrder,\n type FunctionEvaluationResult,\n type SerializedCellValue,\n type SingleEvaluationResult,\n type SpreadsheetRange,\n type TableDefinition,\n type ValueEvaluationResult,\n} from \"../types.mjs\";\nimport {\n captureEvaluationErrors,\n cellAddressToKey,\n checkRangeIntersection,\n getCellReference,\n isCellInRange,\n isRangeOneCell,\n keyToCellAddress,\n parseCellReference,\n} from \"../utils.mjs\";\nimport type { DependencyManager } from \"./dependency-manager.mjs\";\nimport type { WorkbookManager } from \"./workbook-manager.mjs\";\nimport { SpillMetaNode } from \"../../evaluator/dependency-nodes/spill-meta-node.mjs\";\nimport { EmptyCellEvaluationNode } from \"../../evaluator/dependency-nodes/empty-cell-evaluation-node.mjs\";\nimport type { TableManager } from \"./table-manager.mjs\";\n\nexport class EvaluationManager {\n private isEvaluating = false;\n\n constructor(\n private workbookManager: WorkbookManager,\n private tableManager: TableManager,\n private formulaEvaluator: FormulaEvaluator,\n private dependencyManager: DependencyManager\n ) {}\n\n clearEvaluationCache(): void {\n this.dependencyManager.clearEvaluationCache();\n }\n\n evaluationResultToSerializedValue(\n evaluation: SingleEvaluationResult,\n cellAddress: CellAddress,\n debug?: boolean\n ): SerializedCellValue {\n if (\n evaluation.type !== \"error\" &&\n evaluation.type !== \"awaiting-evaluation\"\n ) {\n const value = evaluation.result;\n\n return value.type === \"infinity\"\n ? value.sign === \"positive\"\n ? \"INFINITY\"\n : \"-INFINITY\"\n : value.value;\n }\n\n if (evaluation.type === \"awaiting-evaluation\") {\n return (\n evaluation.errAddress.key +\n \" is awaiting evaluation of \" +\n evaluation.waitingFor.key\n );\n }\n\n if (debug) {\n const errAddress = evaluation.errAddress.key;\n if (errAddress === cellAddressToKey(cellAddress)) {\n return evaluation.err + \" \" + evaluation.message;\n }\n return (\n evaluation.err +\n \" in \" +\n evaluation.errAddress.key +\n \" \" +\n evaluation.message\n );\n }\n\n return evaluation.err;\n }\n\n evaluateEmptyCell(node: EmptyCellEvaluationNode): void {\n node.resetDirectDepsUpdated();\n\n if (node.resolved) {\n const result = node.evaluationResult;\n if (result && result.type !== \"awaiting-evaluation\") {\n return;\n }\n }\n\n const ctx = new EvaluationContext(\n this.tableManager,\n node,\n node.cellAddress\n );\n const inSpilled = this.dependencyManager.getSpillValue(node.cellAddress);\n\n if (inSpilled) {\n // if we are spilling then we can just add the spill origin as a dependency and evaluate the spilled value\n const spillTarget = this.dependencyManager.getSpilledAddress(\n node.cellAddress,\n inSpilled\n );\n const spillOriginKey = cellAddressToKey(inSpilled.origin).replace(\n /^[^:]+:/,\n \"spill-meta:\"\n );\n const spillMetaNode =\n this.dependencyManager.getSpillMetaNode(spillOriginKey);\n node.addDependency(spillMetaNode);\n const result = spillMetaNode.evaluationResult;\n if (result.type === \"spilled-values\") {\n // let's evaluate the spilled value to extract dependencies\n const evaluation = captureEvaluationErrors(spillMetaNode, () => {\n return result.evaluate(spillTarget.spillOffset, ctx);\n });\n node.setEvaluationResult(evaluation);\n }\n } else {\n // upgrade any frontier dependencies that spill into the range\n node.upgradeFrontierDependencies();\n\n const evaluationResult: SingleEvaluationResult = {\n type: \"value\",\n result: this.convertScalarValueToCellValue(\"\"),\n };\n // for now let's just store the empty value, the next time the cell is evaluated isSpilled will be true and the spilled value will be evaluated\n node.setEvaluationResult(evaluationResult);\n }\n }\n\n evaluateRangeNode(node: RangeEvaluationNode): void {\n if (node.resolved) {\n return;\n }\n\n node.resetDirectDepsUpdated();\n\n const result = captureEvaluationErrors(node, (): EvaluateAllCellsResult => {\n node.upgradeFrontierDependencies();\n\n const evalOrder = node.getRangeEvalOrder();\n\n const results: CellInRangeResult[] = [];\n\n for (const entry of evalOrder) {\n if (entry.type === \"value\") {\n const entryAddress = entry.address;\n const result = entry.node.evaluationResult;\n\n const relativePos = {\n x: entryAddress.colIndex - node.address.range.start.col,\n y: entryAddress.rowIndex - node.address.range.start.row,\n };\n\n results.push({ result: result, relativePos });\n } else if (\n entry.type === \"empty_cell\" ||\n entry.type === \"empty_range\"\n ) {\n for (const candidateNode of entry.candidates) {\n if (candidateNode.evaluationResult.type === \"spilled-values\") {\n const spillArea = candidateNode.evaluationResult.spillArea(\n candidateNode.cellAddress\n );\n if (entry.type === \"empty_range\") {\n const intersects = checkRangeIntersection(\n spillArea,\n entry.address.range\n );\n if (intersects) {\n // When a spilled range intersects with our target range, we need to evaluate\n // only the cells that fall within the intersection area.\n //\n // Example: If cell A10 contains a spilled range that covers A10:B11,\n // and our target range is B10:INFINITY, then we only want to evaluate\n // the intersection B10:B11 from the spilled range.\n //\n // The evaluateAllCells method expects the intersection to be passed\n // so it can limit evaluation to only the relevant cells.\n const ctx = new EvaluationContext(\n this.tableManager,\n node,\n candidateNode.cellAddress\n );\n const spilledResults =\n candidateNode.evaluationResult.evaluateAllCells.call(\n this.formulaEvaluator,\n {\n context: ctx,\n evaluate: candidateNode.evaluationResult.evaluate,\n intersection: entry.address.range,\n origin: candidateNode.cellAddress,\n lookupOrder: \"col-major\",\n }\n );\n\n if (spilledResults.type === \"values\") {\n results.push(...spilledResults.values);\n } else {\n return spilledResults;\n }\n }\n } else {\n const intersects = isCellInRange(entry.address, spillArea);\n if (intersects) {\n // When a spilled range intersects with our target range, we need to evaluate\n // only the cells that fall within the intersection area.\n //\n // Example: If cell A10 contains a spilled range that covers A10:B11,\n // and our target range is B10:INFINITY, then we only want to evaluate\n // the intersection B10:B11 from the spilled range.\n //\n // The evaluateAllCells method expects the intersection to be passed\n // so it can limit evaluation to only the relevant cells.\n\n const relativePos = {\n x:\n entry.address.colIndex -\n candidateNode.cellAddress.colIndex,\n y:\n entry.address.rowIndex -\n candidateNode.cellAddress.rowIndex,\n };\n const ctx = new EvaluationContext(\n this.tableManager,\n node,\n candidateNode.cellAddress\n );\n const spilledResult = candidateNode.evaluationResult.evaluate(\n relativePos,\n ctx\n );\n\n results.push({\n relativePos: {\n x: entry.address.colIndex - node.address.range.start.col,\n y: entry.address.rowIndex - node.address.range.start.row,\n },\n result: spilledResult,\n });\n }\n }\n }\n }\n }\n }\n\n return {\n type: \"values\",\n values: results,\n };\n });\n\n node.setResult(result);\n }\n\n evaluateCellNode(node: CellValueNode | SpillMetaNode): void {\n // Enable caching for resolved nodes\n if (node.resolved) {\n return;\n }\n\n node.resetDirectDepsUpdated();\n\n const ctx = new EvaluationContext(\n this.tableManager,\n node,\n node.cellAddress\n );\n\n if (node instanceof CellValueNode && node.spillMeta) {\n // we are evaluating a e.g. A1 in A1=SEQUENCE(10), where we want the value in the cell in A1, i.e. 1\n // As A1 is already pointing to a spill meta node, everything has been setup already,\n // we just need to evaluate the spill origin and assign the result to the currentDepNode\n const spillOrigin = node.spillMeta;\n if (spillOrigin.evaluationResult.type === \"spilled-values\") {\n const result = spillOrigin.evaluationResult.evaluate(\n { x: 0, y: 0 },\n ctx\n );\n node.setEvaluationResult(result);\n return;\n }\n }\n\n let content: SerializedCellValue;\n try {\n content = this.workbookManager.getSerializedCellValue(node.cellAddress);\n } catch (err) {\n const evaluationResult: ErrorEvaluationResult = {\n type: \"error\",\n err: FormulaError.ERROR,\n message: \"Syntax error\",\n errAddress: node,\n };\n node.setEvaluationResult(evaluationResult);\n return;\n }\n\n if (typeof content !== \"string\" || !content.startsWith(\"=\")) {\n if (node instanceof SpillMetaNode) {\n node.setEvaluationResult({\n type: \"does-not-spill\",\n });\n return;\n }\n // Static value cells cannot have frontier dependencies\n const result: ValueEvaluationResult = {\n type: \"value\",\n result: this.convertScalarValueToCellValue(content),\n };\n node.setEvaluationResult(result);\n return;\n }\n\n let evaluation: FunctionEvaluationResult = captureEvaluationErrors(\n node,\n () => this.formulaEvaluator.evaluateFormula(content.slice(1), ctx)\n );\n\n // the evaluated cell IS A spilling formula, e.g. if dependencyKey points to A1, then the formula is e.g. A1=SEQUENCE(10), or A1=A3:B5\n if (evaluation.type === \"spilled-values\") {\n const spillArea = evaluation.spillArea(node.cellAddress);\n\n if (!this.canSpill(node.cellAddress, spillArea)) {\n // Override evaluation with SPILL error, but continue execution to set up nodes\n evaluation = {\n type: \"error\",\n err: FormulaError.SPILL,\n message: \"Cannot spill - area is blocked\",\n errAddress: node,\n };\n } else {\n // Spill succeeds - register it\n this.dependencyManager.setSpilledValue(node.key, {\n spillOnto: spillArea,\n origin: node.cellAddress,\n });\n }\n\n // Set up spill meta node and evaluation results (even if spill failed)\n if (node instanceof SpillMetaNode) {\n // we have already setup an origin/spill meta node relationship,\n // so we are just reevaluating the spill meta node here\n node.setEvaluationResult(evaluation);\n } else {\n const spillMetaNode = this.dependencyManager.getSpillMetaNode(\n node.key.replace(/^[^:]+:/, \"spill-meta:\")\n );\n\n node.addDependency(spillMetaNode);\n node.setSpillMetaNode(spillMetaNode);\n spillMetaNode.setEvaluationResult(evaluation);\n\n if (evaluation.type === \"spilled-values\") {\n const originResult = evaluation.evaluate({ x: 0, y: 0 }, ctx);\n node.setEvaluationResult(originResult);\n } else {\n // Spill failed - set error on origin cell\n node.setEvaluationResult(evaluation);\n }\n }\n return;\n }\n\n if (evaluation.type === \"value\") {\n if (node instanceof SpillMetaNode) {\n node.setEvaluationResult({\n type: \"does-not-spill\",\n });\n return;\n } else {\n node.setEvaluationResult(evaluation);\n return;\n }\n }\n\n node.setEvaluationResult(evaluation);\n }\n\n evaluateDependencyNode(dependencyKey: string): void {\n if (dependencyKey.startsWith(\"empty:\")) {\n this.evaluateEmptyCell(\n this.dependencyManager.getEmptyCellNode(dependencyKey)\n );\n return;\n }\n if (dependencyKey.startsWith(\"range:\")) {\n this.evaluateRangeNode(\n this.dependencyManager.getRangeNode(dependencyKey)\n );\n return;\n }\n if (dependencyKey.startsWith(\"cell-value:\")) {\n const node =\n this.dependencyManager.getCellValueOrEmptyCellNode(dependencyKey);\n if (node instanceof EmptyCellEvaluationNode) {\n this.evaluateEmptyCell(node);\n return;\n }\n this.evaluateCellNode(node);\n return;\n }\n if (dependencyKey.startsWith(\"ast:\")) {\n // let the evaluateCellNode handle the evaluation\n // through formulaEvaluator.evaluateNode,\n // because an AST node must be evaluated in the context of the cell it is in\n return;\n }\n if (dependencyKey.startsWith(\"spill-meta:\")) {\n const node =\n this.dependencyManager.getSpillMetaOrEmptySpillMetaNode(dependencyKey);\n if (node instanceof EmptyCellEvaluationNode) {\n this.evaluateEmptyCell(node);\n return;\n }\n this.evaluateCellNode(node);\n return;\n }\n throw new Error(\"Invalid dependency key: \" + dependencyKey);\n }\n\n /**\n * Evaluates a cell by building the evaluation order and evaluating the dependencies in order\n */\n evaluateCell(node: CellValueNode | EmptyCellEvaluationNode): void {\n if (this.isEvaluating) {\n throw new Error(\"Evaluation in progress\");\n }\n this.isEvaluating = true;\n const sheet = this.workbookManager.getSheet(node.cellAddress);\n if (!sheet) {\n this.isEvaluating = false;\n throw new SheetNotFoundError(node.cellAddress.sheetName);\n }\n\n let precalculatedPlan: EvaluationOrder | undefined;\n\n let requiresReRun = true;\n while (requiresReRun) {\n requiresReRun = false;\n\n // Use DependencyManager to build evaluation order\n const evaluationPlan =\n precalculatedPlan ?? this.dependencyManager.buildEvaluationOrder(node);\n\n if (evaluationPlan.hasCycle) {\n const evaluationResult: ErrorEvaluationResult = {\n type: \"error\",\n err: FormulaError.CYCLE,\n message: Array.from(evaluationPlan.cycleNodes ?? [])\n .map((node) => node.key)\n .join(\" -> \"),\n errAddress: node,\n };\n // cycle detected\n if (evaluationPlan.cycleNodes) {\n for (const node of evaluationPlan.cycleNodes) {\n if (!(node instanceof RangeEvaluationNode)) {\n if (node instanceof AstEvaluationNode) {\n node.setEvaluationResult(evaluationResult);\n } else {\n node.setEvaluationResult(evaluationResult);\n }\n }\n }\n }\n this.isEvaluating = false;\n }\n\n // Evaluate all dependencies in order\n const timeStart = performance.now();\n const durations: { duration: number; key: string }[] = [];\n let numResolved = 0;\n if (flags.isProfiling && evaluationPlan.evaluationOrder.size > -1) {\n // console.profile();\n }\n evaluationPlan.evaluationOrder.forEach((dependency) => {\n const start = performance.now();\n if (dependency.resolved) {\n numResolved++;\n }\n this.evaluateDependencyNode(dependency.key);\n\n const end = performance.now();\n if (flags.isProfiling && evaluationPlan.evaluationOrder.size > -1) {\n durations.push({ duration: end - start, key: dependency.key });\n }\n });\n if (flags.isProfiling && evaluationPlan.evaluationOrder.size > -1) {\n // console.profileEnd();\n }\n if (flags.isProfiling && evaluationPlan.evaluationOrder.size > -1) {\n const percentResolved = Math.round(\n (100 * numResolved) / evaluationPlan.evaluationOrder.size\n );\n const avgDuration =\n durations.reduce((a, b) => a + b.duration, 0) / durations.length || 0;\n console.log(\n `%c[Evaluation] %c${evaluationPlan.evaluationOrder.size} deps | %c${(performance.now() - timeStart).toFixed(1)}ms | %c${percentResolved}% resolved | %c${avgDuration.toFixed(2)}ms avg`,\n \"color:#83aaff;font-weight:bold;\",\n \"color:#fff;font-weight:bold;\",\n \"color:#7fff9e\",\n \"color:#85baff\",\n \"color:#ffdfa3\"\n );\n }\n\n this.dependencyManager.markResolvedNodes(node);\n\n const nextEvaluationPlan =\n this.dependencyManager.buildEvaluationOrder(node);\n\n this.dependencyManager.updateResolvedSCCs(nextEvaluationPlan);\n\n precalculatedPlan = nextEvaluationPlan;\n\n // Check if new dependencies were discovered during evaluation\n if (nextEvaluationPlan.hash !== evaluationPlan.hash) {\n requiresReRun = true;\n } else {\n this.isEvaluating = false;\n return;\n }\n }\n this.isEvaluating = false;\n }\n\n convertScalarValueToCellValue(val: SerializedCellValue): CellValue {\n if (typeof val === \"number\") {\n return { type: \"number\", value: val };\n }\n if (typeof val === \"boolean\") {\n return { type: \"boolean\", value: val };\n }\n if (typeof val === \"undefined\") {\n return { type: \"string\", value: \"\" };\n }\n return { type: \"string\", value: val };\n }\n\n // todo optimize using workbook manager\n canSpill(spillCandidate: CellAddress, spillArea: SpreadsheetRange): boolean {\n const sheet = this.workbookManager.getSheet(spillCandidate);\n if (!sheet) {\n throw new SheetNotFoundError(spillCandidate.sheetName);\n }\n const cellId = getCellReference(spillCandidate);\n const content = sheet.content.get(cellId);\n if (!content) {\n throw new EvaluationError(FormulaError.REF, `Cell not found: ${cellId}`);\n }\n for (const spilledValue of this.dependencyManager.spilledValues) {\n if (\n spilledValue.origin.workbookName !== spillCandidate.workbookName ||\n spilledValue.origin.sheetName !== spillCandidate.sheetName\n ) {\n continue;\n }\n if (\n spilledValue.origin.colIndex === spillCandidate.colIndex &&\n spilledValue.origin.rowIndex === spillCandidate.rowIndex\n ) {\n // we are already have a spill, this one will be replaced\n continue;\n }\n\n if (checkRangeIntersection(spillArea, spilledValue.spillOnto)) {\n return false;\n }\n }\n // let's just check the raw data if there is something in the range\n for (const key of sheet.content.keys()) {\n const cellAddress = parseCellReference(key);\n const endCol = spillArea.end.col;\n const endRow = spillArea.end.row;\n\n if (\n cellAddress.colIndex === spillCandidate.colIndex &&\n cellAddress.rowIndex === spillCandidate.rowIndex\n ) {\n continue;\n }\n\n if (endCol.type === \"number\" && endRow.type === \"number\") {\n if (\n cellAddress.colIndex >= spillArea.start.col &&\n cellAddress.colIndex <= endCol.value &&\n cellAddress.rowIndex >= spillArea.start.row &&\n cellAddress.rowIndex <= endRow.value\n ) {\n if (\n normalizeSerializedCellValue(sheet.content.get(key)) !== undefined\n ) {\n // there is something in the range, so we can't spill\n return false;\n }\n }\n }\n }\n\n return true;\n }\n\n getCellEvaluationResult(\n cellAddress: CellAddress\n ): SingleEvaluationResult | undefined {\n if (this.isEvaluating) {\n throw new Error(\"Evaluation in progress\");\n }\n\n const nodeKey = cellAddressToKey(cellAddress);\n const node = this.dependencyManager.getCellValueOrEmptyCellNode(nodeKey);\n\n const sheet = this.workbookManager.getSheet(cellAddress);\n if (!sheet) {\n throw new SheetNotFoundError(cellAddress.sheetName);\n }\n\n if (node.evaluationResult.type === \"awaiting-evaluation\") {\n // if (cellAddressToKey(cellAddress).includes(\"G10\")) {\n // console.group(\"Evaluation of G10\");\n // flags.isProfiling = true;\n // console.time(\"Evaluation of G10\");\n // console.profile(\"Evaluation of G10\");\n // }\n this.evaluateCell(node);\n // if (flags.isProfiling) {\n // flags.isProfiling = false;\n // console.timeEnd(\"Evaluation of G10\");\n // console.profileEnd(\"Evaluation of G10\");\n // console.groupEnd();\n // }\n }\n\n const result = node.evaluationResult;\n\n return result;\n }\n}\n"
5
+ "import { flags } from \"../../debug/flags.mjs\";\nimport { AstEvaluationNode } from \"../../evaluator/dependency-nodes/ast-evaluation-node.mjs\";\nimport { CellValueNode } from \"../../evaluator/dependency-nodes/cell-value-node.mjs\";\nimport { EvaluationContext } from \"../../evaluator/evaluation-context.mjs\";\nimport {\n EvaluationError,\n SheetNotFoundError,\n} from \"../../evaluator/evaluation-error.mjs\";\nimport { RangeEvaluationNode } from \"../../evaluator/range-evaluation-node.mjs\";\nimport { normalizeSerializedCellValue } from \"../../parser/formatter.mjs\";\nimport { FormulaEvaluator } from \"../../evaluator/formula-evaluator.mjs\";\nimport {\n FormulaError,\n type CellAddress,\n type CellInRangeResult,\n type CellValue,\n type ErrorEvaluationResult,\n type EvaluateAllCellsResult,\n type EvaluationOrder,\n type FunctionEvaluationResult,\n type SerializedCellValue,\n type SingleEvaluationResult,\n type SpreadsheetRange,\n type TableDefinition,\n type ValueEvaluationResult,\n} from \"../types.mjs\";\nimport {\n captureEvaluationErrors,\n cellAddressToKey,\n checkRangeIntersection,\n getCellReference,\n isCellInRange,\n isRangeOneCell,\n keyToCellAddress,\n parseCellReference,\n} from \"../utils.mjs\";\nimport type { DependencyManager } from \"./dependency-manager.mjs\";\nimport type { WorkbookManager } from \"./workbook-manager.mjs\";\nimport { SpillMetaNode } from \"../../evaluator/dependency-nodes/spill-meta-node.mjs\";\nimport { EmptyCellEvaluationNode } from \"../../evaluator/dependency-nodes/empty-cell-evaluation-node.mjs\";\nimport type { TableManager } from \"./table-manager.mjs\";\nimport { parseFormula } from \"../../parser/parser.mjs\";\nimport type { DependencyNode } from \"./dependency-node.mjs\";\nimport { VirtualCellValueNode } from \"../../evaluator/dependency-nodes/virtual-cell-value-node.mjs\";\n\nexport class EvaluationManager {\n private isEvaluating = false;\n\n constructor(\n private workbookManager: WorkbookManager,\n private tableManager: TableManager,\n private formulaEvaluator: FormulaEvaluator,\n private dependencyManager: DependencyManager\n ) {}\n\n clearEvaluationCache(): void {\n this.dependencyManager.clearEvaluationCache();\n }\n\n evaluationResultToSerializedValue(\n evaluation: SingleEvaluationResult,\n cellAddress: CellAddress,\n debug?: boolean\n ): SerializedCellValue {\n if (\n evaluation.type !== \"error\" &&\n evaluation.type !== \"awaiting-evaluation\"\n ) {\n const value = evaluation.result;\n\n return value.type === \"infinity\"\n ? value.sign === \"positive\"\n ? \"INFINITY\"\n : \"-INFINITY\"\n : value.value;\n }\n\n if (evaluation.type === \"awaiting-evaluation\") {\n return (\n evaluation.errAddress.key +\n \" is awaiting evaluation of \" +\n evaluation.waitingFor.key\n );\n }\n\n if (debug) {\n const errAddress = evaluation.errAddress.key;\n if (errAddress === cellAddressToKey(cellAddress)) {\n return evaluation.err + \" \" + evaluation.message;\n }\n return (\n evaluation.err +\n \" in \" +\n evaluation.errAddress.key +\n \" \" +\n evaluation.message\n );\n }\n\n return evaluation.err;\n }\n\n evaluateEmptyCell(node: EmptyCellEvaluationNode): void {\n node.resetDirectDepsUpdated();\n\n if (node.resolved) {\n const result = node.evaluationResult;\n if (result && result.type !== \"awaiting-evaluation\") {\n return;\n }\n }\n\n const ctx = new EvaluationContext(\n this.tableManager,\n node,\n node.cellAddress\n );\n const inSpilled = this.dependencyManager.getSpillValue(node.cellAddress);\n\n if (inSpilled) {\n // if we are spilling then we can just add the spill origin as a dependency and evaluate the spilled value\n const spillTarget = this.dependencyManager.getSpilledAddress(\n node.cellAddress,\n inSpilled\n );\n const spillOriginKey = cellAddressToKey(inSpilled.origin).replace(\n /^[^:]+:/,\n \"spill-meta:\"\n );\n const spillMetaNode =\n this.dependencyManager.getSpillMetaNode(spillOriginKey);\n node.addDependency(spillMetaNode);\n const result = spillMetaNode.evaluationResult;\n if (result.type === \"spilled-values\") {\n // let's evaluate the spilled value to extract dependencies\n const evaluation = captureEvaluationErrors(spillMetaNode, () => {\n return result.evaluate(spillTarget.spillOffset, ctx);\n });\n node.setEvaluationResult(evaluation);\n }\n } else {\n // upgrade any frontier dependencies that spill into the range\n node.upgradeFrontierDependencies();\n\n const evaluationResult: SingleEvaluationResult = {\n type: \"value\",\n result: this.convertScalarValueToCellValue(\"\"),\n };\n // for now let's just store the empty value, the next time the cell is evaluated isSpilled will be true and the spilled value will be evaluated\n node.setEvaluationResult(evaluationResult);\n }\n }\n\n evaluateRangeNode(node: RangeEvaluationNode): void {\n if (node.resolved) {\n return;\n }\n\n node.resetDirectDepsUpdated();\n\n const result = captureEvaluationErrors(node, (): EvaluateAllCellsResult => {\n node.upgradeFrontierDependencies();\n\n const evalOrder = node.getRangeEvalOrder();\n\n const results: CellInRangeResult[] = [];\n\n for (const entry of evalOrder) {\n if (entry.type === \"value\") {\n const entryAddress = entry.address;\n const result = entry.node.evaluationResult;\n\n const relativePos = {\n x: entryAddress.colIndex - node.address.range.start.col,\n y: entryAddress.rowIndex - node.address.range.start.row,\n };\n\n results.push({ result: result, relativePos });\n } else if (\n entry.type === \"empty_cell\" ||\n entry.type === \"empty_range\"\n ) {\n for (const candidateNode of entry.candidates) {\n if (candidateNode.evaluationResult.type === \"spilled-values\") {\n const spillArea = candidateNode.evaluationResult.spillArea(\n candidateNode.cellAddress\n );\n if (entry.type === \"empty_range\") {\n const intersects = checkRangeIntersection(\n spillArea,\n entry.address.range\n );\n if (intersects) {\n // When a spilled range intersects with our target range, we need to evaluate\n // only the cells that fall within the intersection area.\n //\n // Example: If cell A10 contains a spilled range that covers A10:B11,\n // and our target range is B10:INFINITY, then we only want to evaluate\n // the intersection B10:B11 from the spilled range.\n //\n // The evaluateAllCells method expects the intersection to be passed\n // so it can limit evaluation to only the relevant cells.\n const ctx = new EvaluationContext(\n this.tableManager,\n node,\n candidateNode.cellAddress\n );\n const spilledResults =\n candidateNode.evaluationResult.evaluateAllCells.call(\n this.formulaEvaluator,\n {\n context: ctx,\n evaluate: candidateNode.evaluationResult.evaluate,\n intersection: entry.address.range,\n origin: candidateNode.cellAddress,\n lookupOrder: \"col-major\",\n }\n );\n\n if (spilledResults.type === \"values\") {\n results.push(...spilledResults.values);\n } else {\n return spilledResults;\n }\n }\n } else {\n const intersects = isCellInRange(entry.address, spillArea);\n if (intersects) {\n // When a spilled range intersects with our target range, we need to evaluate\n // only the cells that fall within the intersection area.\n //\n // Example: If cell A10 contains a spilled range that covers A10:B11,\n // and our target range is B10:INFINITY, then we only want to evaluate\n // the intersection B10:B11 from the spilled range.\n //\n // The evaluateAllCells method expects the intersection to be passed\n // so it can limit evaluation to only the relevant cells.\n\n const relativePos = {\n x:\n entry.address.colIndex -\n candidateNode.cellAddress.colIndex,\n y:\n entry.address.rowIndex -\n candidateNode.cellAddress.rowIndex,\n };\n const ctx = new EvaluationContext(\n this.tableManager,\n node,\n candidateNode.cellAddress\n );\n const spilledResult = candidateNode.evaluationResult.evaluate(\n relativePos,\n ctx\n );\n\n results.push({\n relativePos: {\n x: entry.address.colIndex - node.address.range.start.col,\n y: entry.address.rowIndex - node.address.range.start.row,\n },\n result: spilledResult,\n });\n }\n }\n }\n }\n }\n }\n\n return {\n type: \"values\",\n values: results,\n };\n });\n\n node.setResult(result);\n }\n\n evaluateCellNode(\n node: CellValueNode | SpillMetaNode | VirtualCellValueNode\n ): void {\n // Enable caching for resolved nodes\n if (node.resolved) {\n return;\n }\n\n node.resetDirectDepsUpdated();\n\n const ctx = new EvaluationContext(\n this.tableManager,\n node,\n node.cellAddress\n );\n\n if (node instanceof CellValueNode && node.spillMeta) {\n // we are evaluating a e.g. A1 in A1=SEQUENCE(10), where we want the value in the cell in A1, i.e. 1\n // As A1 is already pointing to a spill meta node, everything has been setup already,\n // we just need to evaluate the spill origin and assign the result to the currentDepNode\n const spillOrigin = node.spillMeta;\n if (spillOrigin.evaluationResult.type === \"spilled-values\") {\n const result = spillOrigin.evaluationResult.evaluate(\n { x: 0, y: 0 },\n ctx\n );\n node.setEvaluationResult(result);\n return;\n }\n }\n\n let content: SerializedCellValue;\n try {\n if (node instanceof VirtualCellValueNode) {\n content = node.cellValue;\n } else {\n content = this.workbookManager.getSerializedCellValue(node.cellAddress);\n }\n } catch (err) {\n const evaluationResult: ErrorEvaluationResult = {\n type: \"error\",\n err: FormulaError.ERROR,\n message: \"Syntax error\",\n errAddress: node,\n };\n node.setEvaluationResult(evaluationResult);\n return;\n }\n\n if (typeof content !== \"string\" || !content.startsWith(\"=\")) {\n if (node instanceof SpillMetaNode) {\n node.setEvaluationResult({\n type: \"does-not-spill\",\n });\n return;\n }\n // Static value cells cannot have frontier dependencies\n const result: ValueEvaluationResult = {\n type: \"value\",\n result: this.convertScalarValueToCellValue(content),\n };\n node.setEvaluationResult(result);\n return;\n }\n\n let evaluation: FunctionEvaluationResult = captureEvaluationErrors(\n node,\n () => this.formulaEvaluator.evaluateFormula(content.slice(1), ctx)\n );\n\n // the evaluated cell IS A spilling formula, e.g. if dependencyKey points to A1, then the formula is e.g. A1=SEQUENCE(10), or A1=A3:B5\n if (evaluation.type === \"spilled-values\") {\n const spillArea = evaluation.spillArea(node.cellAddress);\n\n if (!this.canSpill(node.cellAddress, spillArea)) {\n // Override evaluation with SPILL error, but continue execution to set up nodes\n evaluation = {\n type: \"error\",\n err: FormulaError.SPILL,\n message: \"Cannot spill - area is blocked\",\n errAddress: node,\n };\n } else {\n // Spill succeeds - register it\n this.dependencyManager.setSpilledValue(node.key, {\n spillOnto: spillArea,\n origin: node.cellAddress,\n });\n }\n\n // Set up spill meta node and evaluation results (even if spill failed)\n if (node instanceof SpillMetaNode) {\n // we have already setup an origin/spill meta node relationship,\n // so we are just reevaluating the spill meta node here\n node.setEvaluationResult(evaluation);\n } else {\n const spillMetaNode = this.dependencyManager.getSpillMetaNode(\n node.key.replace(/^[^:]+:/, \"spill-meta:\")\n );\n\n node.addDependency(spillMetaNode);\n node.setSpillMetaNode(spillMetaNode);\n spillMetaNode.setEvaluationResult(evaluation);\n\n if (evaluation.type === \"spilled-values\") {\n const originResult = evaluation.evaluate({ x: 0, y: 0 }, ctx);\n node.setEvaluationResult(originResult);\n } else {\n // Spill failed - set error on origin cell\n node.setEvaluationResult(evaluation);\n }\n }\n return;\n }\n\n if (evaluation.type === \"value\") {\n if (node instanceof SpillMetaNode) {\n node.setEvaluationResult({\n type: \"does-not-spill\",\n });\n return;\n } else {\n node.setEvaluationResult(evaluation);\n return;\n }\n }\n\n node.setEvaluationResult(evaluation);\n }\n\n evaluateDependencyNode(dependency: DependencyNode): void {\n if (dependency instanceof EmptyCellEvaluationNode) {\n this.evaluateEmptyCell(dependency);\n return;\n }\n if (dependency instanceof RangeEvaluationNode) {\n this.evaluateRangeNode(dependency);\n return;\n }\n if (\n dependency instanceof CellValueNode ||\n dependency instanceof VirtualCellValueNode\n ) {\n this.evaluateCellNode(dependency);\n return;\n }\n if (dependency instanceof AstEvaluationNode) {\n return;\n }\n if (dependency instanceof SpillMetaNode) {\n this.evaluateCellNode(dependency);\n return;\n }\n throw new Error(\"Invalid dependency: \" + (dependency as any).key);\n }\n\n /**\n * User exposed method to evaluate a formula\n */\n evaluateFormula(\n /**\n * formula for example\n */\n cellValue: SerializedCellValue,\n cellAddress: CellAddress\n ): SerializedCellValue {\n if (this.isEvaluating) {\n throw new Error(\"Evaluation in progress\");\n }\n\n const node = this.dependencyManager.getVirtualCellValueNode(\n cellAddress,\n cellValue\n );\n\n if (node.evaluationResult.type === \"awaiting-evaluation\") {\n this.evaluateCell(node);\n }\n\n const result = node.evaluationResult;\n\n return this.evaluationResultToSerializedValue(result, cellAddress);\n }\n\n /**\n * Evaluates a cell by building the evaluation order and evaluating the dependencies in order\n */\n evaluateCell(\n node: CellValueNode | EmptyCellEvaluationNode | VirtualCellValueNode\n ): void {\n if (this.isEvaluating) {\n throw new Error(\"Evaluation in progress\");\n }\n this.isEvaluating = true;\n\n let precalculatedPlan: EvaluationOrder | undefined;\n\n let requiresReRun = true;\n while (requiresReRun) {\n requiresReRun = false;\n\n // Use DependencyManager to build evaluation order\n const evaluationPlan =\n precalculatedPlan ?? this.dependencyManager.buildEvaluationOrder(node);\n\n if (evaluationPlan.hasCycle) {\n const evaluationResult: ErrorEvaluationResult = {\n type: \"error\",\n err: FormulaError.CYCLE,\n message: Array.from(evaluationPlan.cycleNodes ?? [])\n .map((node) => node.key)\n .join(\" -> \"),\n errAddress: node,\n };\n // cycle detected\n if (evaluationPlan.cycleNodes) {\n for (const node of evaluationPlan.cycleNodes) {\n if (!(node instanceof RangeEvaluationNode)) {\n node.setEvaluationResult(evaluationResult);\n }\n }\n }\n this.isEvaluating = false;\n }\n\n // Evaluate all dependencies in order\n const timeStart = performance.now();\n const durations: { duration: number; key: string }[] = [];\n let numResolved = 0;\n if (flags.isProfiling && evaluationPlan.evaluationOrder.size > -1) {\n // console.profile();\n }\n evaluationPlan.evaluationOrder.forEach((dependency) => {\n const start = performance.now();\n if (dependency.resolved) {\n numResolved++;\n }\n this.evaluateDependencyNode(dependency);\n\n const end = performance.now();\n if (flags.isProfiling && evaluationPlan.evaluationOrder.size > -1) {\n durations.push({ duration: end - start, key: dependency.key });\n }\n });\n if (flags.isProfiling && evaluationPlan.evaluationOrder.size > -1) {\n // console.profileEnd();\n }\n if (flags.isProfiling && evaluationPlan.evaluationOrder.size > -1) {\n const percentResolved = Math.round(\n (100 * numResolved) / evaluationPlan.evaluationOrder.size\n );\n const avgDuration =\n durations.reduce((a, b) => a + b.duration, 0) / durations.length || 0;\n console.log(\n `%c[Evaluation] %c${evaluationPlan.evaluationOrder.size} deps | %c${(\n performance.now() - timeStart\n ).toFixed(\n 1\n )}ms | %c${percentResolved}% resolved | %c${avgDuration.toFixed(\n 2\n )}ms avg`,\n \"color:#83aaff;font-weight:bold;\",\n \"color:#fff;font-weight:bold;\",\n \"color:#7fff9e\",\n \"color:#85baff\",\n \"color:#ffdfa3\"\n );\n }\n\n this.dependencyManager.markResolvedNodes(node);\n\n const nextEvaluationPlan =\n this.dependencyManager.buildEvaluationOrder(node);\n\n this.dependencyManager.updateResolvedSCCs(nextEvaluationPlan);\n\n precalculatedPlan = nextEvaluationPlan;\n\n // Check if new dependencies were discovered during evaluation\n if (nextEvaluationPlan.hash !== evaluationPlan.hash) {\n requiresReRun = true;\n } else {\n this.isEvaluating = false;\n return;\n }\n }\n this.isEvaluating = false;\n }\n\n convertScalarValueToCellValue(val: SerializedCellValue): CellValue {\n if (typeof val === \"number\") {\n return { type: \"number\", value: val };\n }\n if (typeof val === \"boolean\") {\n return { type: \"boolean\", value: val };\n }\n if (typeof val === \"undefined\") {\n return { type: \"string\", value: \"\" };\n }\n return { type: \"string\", value: val };\n }\n\n // todo optimize using workbook manager\n canSpill(spillCandidate: CellAddress, spillArea: SpreadsheetRange): boolean {\n const sheet = this.workbookManager.getSheet(spillCandidate);\n if (!sheet) {\n throw new SheetNotFoundError(spillCandidate.sheetName);\n }\n const cellId = getCellReference(spillCandidate);\n const content = sheet.content.get(cellId);\n if (!content) {\n throw new EvaluationError(FormulaError.REF, `Cell not found: ${cellId}`);\n }\n for (const spilledValue of this.dependencyManager.spilledValues) {\n if (\n spilledValue.origin.workbookName !== spillCandidate.workbookName ||\n spilledValue.origin.sheetName !== spillCandidate.sheetName\n ) {\n continue;\n }\n if (\n spilledValue.origin.colIndex === spillCandidate.colIndex &&\n spilledValue.origin.rowIndex === spillCandidate.rowIndex\n ) {\n // we are already have a spill, this one will be replaced\n continue;\n }\n\n if (checkRangeIntersection(spillArea, spilledValue.spillOnto)) {\n return false;\n }\n }\n // let's just check the raw data if there is something in the range\n for (const key of sheet.content.keys()) {\n const cellAddress = parseCellReference(key);\n const endCol = spillArea.end.col;\n const endRow = spillArea.end.row;\n\n if (\n cellAddress.colIndex === spillCandidate.colIndex &&\n cellAddress.rowIndex === spillCandidate.rowIndex\n ) {\n continue;\n }\n\n if (endCol.type === \"number\" && endRow.type === \"number\") {\n if (\n cellAddress.colIndex >= spillArea.start.col &&\n cellAddress.colIndex <= endCol.value &&\n cellAddress.rowIndex >= spillArea.start.row &&\n cellAddress.rowIndex <= endRow.value\n ) {\n if (\n normalizeSerializedCellValue(sheet.content.get(key)) !== undefined\n ) {\n // there is something in the range, so we can't spill\n return false;\n }\n }\n }\n }\n\n return true;\n }\n\n getCellEvaluationResult(\n cellAddress: CellAddress\n ): SingleEvaluationResult | undefined {\n if (this.isEvaluating) {\n throw new Error(\"Evaluation in progress\");\n }\n\n const nodeKey = cellAddressToKey(cellAddress);\n const node = this.dependencyManager.getCellValueOrEmptyCellNode(nodeKey);\n\n const sheet = this.workbookManager.getSheet(cellAddress);\n if (!sheet) {\n throw new SheetNotFoundError(cellAddress.sheetName);\n }\n\n if (node.evaluationResult.type === \"awaiting-evaluation\") {\n // if (cellAddressToKey(cellAddress).includes(\"G10\")) {\n // console.group(\"Evaluation of G10\");\n // flags.isProfiling = true;\n // console.time(\"Evaluation of G10\");\n // console.profile(\"Evaluation of G10\");\n // }\n this.evaluateCell(node);\n // if (flags.isProfiling) {\n // flags.isProfiling = false;\n // console.timeEnd(\"Evaluation of G10\");\n // console.profileEnd(\"Evaluation of G10\");\n // console.groupEnd();\n // }\n }\n\n const result = node.evaluationResult;\n\n return result;\n }\n}\n"
6
6
  ],
7
- "mappings": "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",
8
- "debugId": "CBD41BDE565D9B5964756E2164756E21",
7
+ "mappings": "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",
8
+ "debugId": "0649B69F38BEDF9864756E2164756E21",
9
9
  "names": []
10
10
  }
@@ -0,0 +1,315 @@
1
+ // src/core/managers/style-manager.ts
2
+ import { isCellInRange } from "../utils.mjs";
3
+ import {
4
+ calculateGradientFactor,
5
+ interpolateLCH,
6
+ lchToHex
7
+ } from "../utils/color-utils.mjs";
8
+
9
+ class StyleManager {
10
+ workbookManager;
11
+ evaluationManager;
12
+ conditionalStyles = [];
13
+ cellStyles = [];
14
+ constructor(workbookManager, evaluationManager) {
15
+ this.workbookManager = workbookManager;
16
+ this.evaluationManager = evaluationManager;
17
+ }
18
+ addConditionalStyle(style) {
19
+ this.conditionalStyles.push(style);
20
+ }
21
+ removeConditionalStyle(workbookName, index) {
22
+ const workbookStyles = this.conditionalStyles.filter((style) => style.area.workbookName === workbookName);
23
+ if (index < 0 || index >= workbookStyles.length) {
24
+ return false;
25
+ }
26
+ let currentIndex = 0;
27
+ for (let i = 0;i < this.conditionalStyles.length; i++) {
28
+ const style = this.conditionalStyles[i];
29
+ if (style && style.area.workbookName === workbookName) {
30
+ if (currentIndex === index) {
31
+ this.conditionalStyles.splice(i, 1);
32
+ return true;
33
+ }
34
+ currentIndex++;
35
+ }
36
+ }
37
+ return false;
38
+ }
39
+ getConditionalStyles(workbookName) {
40
+ return this.conditionalStyles.filter((style) => style && style.area && style.area.workbookName === workbookName);
41
+ }
42
+ addCellStyle(style) {
43
+ this.cellStyles.push(style);
44
+ }
45
+ removeCellStyle(workbookName, index) {
46
+ const workbookStyles = this.cellStyles.filter((style) => style && style.area && style.area.workbookName === workbookName);
47
+ if (index < 0 || index >= workbookStyles.length) {
48
+ return false;
49
+ }
50
+ let currentIndex = 0;
51
+ for (let i = 0;i < this.cellStyles.length; i++) {
52
+ const style = this.cellStyles[i];
53
+ if (style && style.area && style.area.workbookName === workbookName) {
54
+ if (currentIndex === index) {
55
+ this.cellStyles.splice(i, 1);
56
+ return true;
57
+ }
58
+ currentIndex++;
59
+ }
60
+ }
61
+ return false;
62
+ }
63
+ getCellStyles(workbookName) {
64
+ return this.cellStyles.filter((style) => style && style.area && style.area.workbookName === workbookName);
65
+ }
66
+ getAllConditionalStyles() {
67
+ return [...this.conditionalStyles];
68
+ }
69
+ getAllCellStyles() {
70
+ return [...this.cellStyles];
71
+ }
72
+ resetStyles(conditionalStyles, cellStyles) {
73
+ this.conditionalStyles = conditionalStyles ? [...conditionalStyles] : [];
74
+ this.cellStyles = cellStyles ? [...cellStyles] : [];
75
+ }
76
+ removeWorkbookStyles(workbookName) {
77
+ this.conditionalStyles = this.conditionalStyles.filter((style) => style.area.workbookName !== workbookName);
78
+ this.cellStyles = this.cellStyles.filter((style) => style.area.workbookName !== workbookName);
79
+ }
80
+ updateWorkbookName(oldName, newName) {
81
+ this.conditionalStyles = this.conditionalStyles.map((style) => {
82
+ if (style.area.workbookName === oldName) {
83
+ return {
84
+ ...style,
85
+ area: {
86
+ ...style.area,
87
+ workbookName: newName
88
+ }
89
+ };
90
+ }
91
+ return style;
92
+ });
93
+ this.cellStyles = this.cellStyles.map((style) => {
94
+ if (style.area.workbookName === oldName) {
95
+ return {
96
+ ...style,
97
+ area: {
98
+ ...style.area,
99
+ workbookName: newName
100
+ }
101
+ };
102
+ }
103
+ return style;
104
+ });
105
+ }
106
+ updateSheetName(workbookName, oldSheetName, newSheetName) {
107
+ this.conditionalStyles = this.conditionalStyles.map((style) => {
108
+ if (style.area.workbookName === workbookName && style.area.sheetName === oldSheetName) {
109
+ return {
110
+ ...style,
111
+ area: {
112
+ ...style.area,
113
+ sheetName: newSheetName
114
+ }
115
+ };
116
+ }
117
+ return style;
118
+ });
119
+ this.cellStyles = this.cellStyles.map((style) => {
120
+ if (style.area.workbookName === workbookName && style.area.sheetName === oldSheetName) {
121
+ return {
122
+ ...style,
123
+ area: {
124
+ ...style.area,
125
+ sheetName: newSheetName
126
+ }
127
+ };
128
+ }
129
+ return style;
130
+ });
131
+ }
132
+ removeSheetStyles(workbookName, sheetName) {
133
+ this.conditionalStyles = this.conditionalStyles.filter((style) => !(style.area.workbookName === workbookName && style.area.sheetName === sheetName));
134
+ this.cellStyles = this.cellStyles.filter((style) => !(style.area.workbookName === workbookName && style.area.sheetName === sheetName));
135
+ }
136
+ getCellStyle(cellAddress) {
137
+ for (const cellStyle of this.cellStyles) {
138
+ if (!cellStyle || !cellStyle.area) {
139
+ continue;
140
+ }
141
+ if (cellStyle.area.workbookName === cellAddress.workbookName && cellStyle.area.sheetName === cellAddress.sheetName && isCellInRange(cellAddress, cellStyle.area.range)) {
142
+ return {
143
+ backgroundColor: cellStyle.style.backgroundColor,
144
+ color: cellStyle.style.color
145
+ };
146
+ }
147
+ }
148
+ for (const style of this.conditionalStyles) {
149
+ if (!style || !style.area) {
150
+ continue;
151
+ }
152
+ if (style.area.sheetName !== cellAddress.sheetName || style.area.workbookName !== cellAddress.workbookName) {
153
+ continue;
154
+ }
155
+ if (!isCellInRange(cellAddress, style.area.range)) {
156
+ continue;
157
+ }
158
+ if (style.condition.type === "formula") {
159
+ const result = this.evaluateFormulaCondition(cellAddress, style);
160
+ if (result)
161
+ return result;
162
+ } else {
163
+ const result = this.evaluateGradientCondition(cellAddress, style);
164
+ if (result)
165
+ return result;
166
+ }
167
+ }
168
+ return;
169
+ }
170
+ evaluateFormulaCondition(cellAddress, style) {
171
+ if (style.condition.type !== "formula") {
172
+ return;
173
+ }
174
+ try {
175
+ const formula = style.condition.formula.startsWith("=") ? style.condition.formula : `=${style.condition.formula}`;
176
+ const result = this.evaluationManager.evaluateFormula(formula, cellAddress);
177
+ const isTruthy = result === true || result === "TRUE" || typeof result === "number" && result !== 0;
178
+ if (isTruthy) {
179
+ return {
180
+ backgroundColor: lchToHex(style.condition.color)
181
+ };
182
+ }
183
+ } catch (error) {
184
+ console.warn("Failed to evaluate formula condition:", error);
185
+ }
186
+ return;
187
+ }
188
+ evaluateGradientCondition(cellAddress, style) {
189
+ if (style.condition.type !== "gradient") {
190
+ return;
191
+ }
192
+ try {
193
+ const evalResult = this.evaluationManager.getCellEvaluationResult(cellAddress);
194
+ if (!evalResult || evalResult.type !== "value") {
195
+ return;
196
+ }
197
+ if (evalResult.result.type !== "number") {
198
+ return;
199
+ }
200
+ const cellValue = evalResult.result.value;
201
+ const { min: minValue, max: maxValue } = this.calculateGradientBounds(style, cellAddress);
202
+ if (minValue === null || maxValue === null) {
203
+ return;
204
+ }
205
+ const factor = calculateGradientFactor(cellValue, minValue, maxValue);
206
+ const minColor = style.condition.min.color;
207
+ const maxColor = style.condition.max.color;
208
+ const interpolatedColor = interpolateLCH(minColor, maxColor, factor);
209
+ return {
210
+ backgroundColor: lchToHex(interpolatedColor)
211
+ };
212
+ } catch (error) {
213
+ console.warn("Failed to evaluate gradient condition:", error);
214
+ return;
215
+ }
216
+ }
217
+ calculateGradientBounds(style, cellAddress) {
218
+ if (style.condition.type !== "gradient") {
219
+ return { min: null, max: null };
220
+ }
221
+ const { min: minConfig, max: maxConfig } = style.condition;
222
+ const topLeftCell = {
223
+ workbookName: style.area.workbookName,
224
+ sheetName: style.area.sheetName,
225
+ colIndex: style.area.range.start.col,
226
+ rowIndex: style.area.range.start.row
227
+ };
228
+ let minValue = null;
229
+ if (minConfig.type === "lowest_value") {
230
+ try {
231
+ const rangeRef = this.getRangeReference(style.area);
232
+ const result = this.evaluationManager.evaluateFormula(`=MIN(${rangeRef})`, topLeftCell);
233
+ if (typeof result === "number") {
234
+ minValue = result;
235
+ }
236
+ } catch (error) {
237
+ console.warn("Failed to calculate MIN:", error);
238
+ }
239
+ } else {
240
+ const formula = minConfig.valueFormula.startsWith("=") ? minConfig.valueFormula : `=${minConfig.valueFormula}`;
241
+ const result = this.evaluationManager.evaluateFormula(formula, topLeftCell);
242
+ if (typeof result === "number") {
243
+ minValue = result;
244
+ }
245
+ }
246
+ let maxValue = null;
247
+ if (maxConfig.type === "highest_value") {
248
+ try {
249
+ const rangeRef = this.getRangeReference(style.area);
250
+ const result = this.evaluationManager.evaluateFormula(`=MAX(${rangeRef})`, topLeftCell);
251
+ if (typeof result === "number") {
252
+ maxValue = result;
253
+ }
254
+ } catch (error) {
255
+ console.warn("Failed to calculate MAX:", error);
256
+ }
257
+ } else {
258
+ const formula = maxConfig.valueFormula.startsWith("=") ? maxConfig.valueFormula : `=${maxConfig.valueFormula}`;
259
+ const result = this.evaluationManager.evaluateFormula(formula, topLeftCell);
260
+ if (typeof result === "number") {
261
+ maxValue = result;
262
+ }
263
+ }
264
+ return { min: minValue, max: maxValue };
265
+ }
266
+ getRangeReference(area) {
267
+ const colToLetter = (col) => {
268
+ let result = "";
269
+ let c = col;
270
+ while (c >= 0) {
271
+ result = String.fromCharCode(65 + c % 26) + result;
272
+ c = Math.floor(c / 26) - 1;
273
+ }
274
+ return result;
275
+ };
276
+ const startCol = colToLetter(area.range.start.col);
277
+ const startRow = area.range.start.row + 1;
278
+ const isColInfinity = area.range.end.col.type === "infinity";
279
+ const isRowInfinity = area.range.end.row.type === "infinity";
280
+ let rangeStr;
281
+ if (isColInfinity && isRowInfinity) {
282
+ rangeStr = `${startCol}${startRow}:INFINITY`;
283
+ } else if (isColInfinity) {
284
+ if (area.range.end.row.type === "number") {
285
+ const endRow = area.range.end.row.value + 1;
286
+ rangeStr = `${startCol}${startRow}:${endRow}`;
287
+ } else {
288
+ rangeStr = `${startCol}${startRow}:INFINITY`;
289
+ }
290
+ } else if (isRowInfinity) {
291
+ if (area.range.end.col.type === "number") {
292
+ const endCol = colToLetter(area.range.end.col.value);
293
+ rangeStr = `${startCol}${startRow}:${endCol}`;
294
+ } else {
295
+ rangeStr = `${startCol}${startRow}:INFINITY`;
296
+ }
297
+ } else {
298
+ if (area.range.end.col.type === "number" && area.range.end.row.type === "number") {
299
+ const endCol = colToLetter(area.range.end.col.value);
300
+ const endRow = area.range.end.row.value + 1;
301
+ rangeStr = `${startCol}${startRow}:${endCol}${endRow}`;
302
+ } else {
303
+ rangeStr = `${startCol}${startRow}:INFINITY`;
304
+ }
305
+ }
306
+ const needsQuotes = /[ '!]/.test(area.sheetName);
307
+ const sheetRef = needsQuotes ? `'${area.sheetName.replace(/'/g, "''")}'` : area.sheetName;
308
+ return `[${area.workbookName}]${sheetRef}!${rangeStr}`;
309
+ }
310
+ }
311
+ export {
312
+ StyleManager
313
+ };
314
+
315
+ //# debugId=DB5713E9E5C6BAC564756E2164756E21