{
  "version": 3,
  "sources": ["../../../../src/core/managers/dependency-manager.ts"],
  "sourcesContent": [
    "import {\n  getAstNodeSnapshotId,\n  type CacheManagerSnapshot,\n  type DependencyManagerSnapshot,\n  type NodeSnapshotId,\n  type SerializedAstNodeSnapshot,\n  type SerializedResourceNodeSnapshot,\n  type SerializedDependencyNodeSnapshot,\n  type SerializedEmptyCellNodeSnapshot,\n  type SerializedRangeNodeSnapshot,\n  type SerializedSpillMetaNodeSnapshot,\n  type SerializedCellValueNodeSnapshot,\n} from \"../engine-snapshot.mjs\";\nimport {\n  eligibleKeysForContext,\n  getContextDependencyKey,\n  type ContextDependency,\n} from \"../../evaluator/evaluation-context.mjs\";\nimport {\n  type CellAddress,\n  type EvaluationOrder,\n  type RangeAddress,\n  type SerializedCellValue,\n  type SingleEvaluationResult,\n  type SpilledValue,\n} from \"../types.mjs\";\nimport {\n  cellAddressToKey,\n  checkRangeIntersection,\n  isCellInRange,\n  keyToCellAddress,\n} from \"../utils.mjs\";\n\nimport { AstEvaluationNode } from \"../../evaluator/dependency-nodes/ast-evaluation-node.mjs\";\nimport { CellValueNode } from \"../../evaluator/dependency-nodes/cell-value-node.mjs\";\nimport { EmptyCellEvaluationNode } from \"../../evaluator/dependency-nodes/empty-cell-evaluation-node.mjs\";\nimport { SpillMetaNode } from \"../../evaluator/dependency-nodes/spill-meta-node.mjs\";\nimport { RangeEvaluationNode } from \"../../evaluator/range-evaluation-node.mjs\";\nimport type { ASTNode } from \"../../parser/ast.mjs\";\nimport {\n  astToString,\n  normalizeSerializedCellValue,\n} from \"../../parser/formatter.mjs\";\nimport { CacheManager } from \"./cache-manager.mjs\";\nimport type {\n  CellNodeKeyDictionary,\n  CellNodeType,\n  DependencyNode,\n} from \"./dependency-node.mjs\";\nimport { WorkbookManager } from \"./workbook-manager.mjs\";\nimport { VirtualCellValueNode } from \"../../evaluator/dependency-nodes/virtual-cell-value-node.mjs\";\nimport { parseFormula } from \"../../parser/parser.mjs\";\nimport type { EvaluationManager } from \"./evaluation-manager.mjs\";\nimport type {\n  MutationInvalidation,\n  RemovedScope,\n} from \"../mutation-invalidation.mjs\";\nimport { ResourceDependencyNode } from \"../../evaluator/dependency-nodes/resource-dependency-node.mjs\";\n\nexport interface DependencyTreeNode {\n  type: \"cell\" | \"range\" | \"empty\";\n  circular?: boolean;\n  key: string;\n  directDepsUpdated?: boolean;\n  resolved?: boolean;\n  canResolve: boolean;\n  resultType:\n    | \"awaiting-evaluation\"\n    | \"spilled-values\"\n    | \"value\"\n    | \"range\"\n    | \"error\"\n    | \"does-not-spill\"\n    | \"resource\";\n  deps?: DependencyTreeNode[];\n  frontierDependencies?: DependencyTreeNode[];\n  self?: boolean;\n  _debug?: {\n    rawFrontierDependencies?: string[];\n    discardedFrontierDependencies?: string[];\n    activeFrontierDependencies?: string[];\n  };\n}\n\ntype FrontierWatcherNode = RangeEvaluationNode | EmptyCellEvaluationNode;\ntype SnapshotEligibleNode =\n  | CellValueNode\n  | SpillMetaNode\n  | EmptyCellEvaluationNode\n  | RangeEvaluationNode\n  | AstEvaluationNode\n  | ResourceDependencyNode;\n\n/**\n * The DependencyManager is responsible for storing the evaluated values and their dependencies.\n */\nexport class DependencyManager {\n  /**\n   * The dependency graph AKA cellNodes\n   */\n  private cellNodes: Map<\n    /**\n     * key is the cell key, from cellAddressToKey\n     */\n    string,\n    CellValueNode\n  > = new Map();\n\n  private spillMetaNodes: Map<string, SpillMetaNode> = new Map();\n\n  private emptyCells: Map<string, EmptyCellEvaluationNode> = new Map();\n\n  private virtualCellValueNodes: Map<string, VirtualCellValueNode> = new Map();\n\n  /**\n   * registry of spilled values\n   */\n  private _spilledValues: Map<\n    /**\n     * key is the dependency node key, from dependencyNodeToKey for the origin cell\n     */\n    string,\n    SpilledValue\n  > = new Map();\n\n  /**\n   * Key is workbook:sheetName:rangeKey, e.g. Workbook1:Sheet1:A1:D10, from rangeAddressToKey\n   */\n  private ranges: Map<string, RangeEvaluationNode> = new Map();\n\n  private resourceNodes: Map<string, ResourceDependencyNode> = new Map();\n\n  private hardDependents: Map<DependencyNode, Set<DependencyNode>> = new Map();\n\n  private frontierDependents: Map<DependencyNode, Set<DependencyNode>> =\n    new Map();\n\n  private registeredDependencies: Map<\n    DependencyNode,\n    {\n      hard: Set<DependencyNode>;\n      frontier: Set<DependencyNode>;\n    }\n  > = new Map();\n\n  private coverageWatchersBySheet: Map<string, Set<FrontierWatcherNode>> =\n    new Map();\n\n  private frontierWatchersBySheet: Map<string, Set<FrontierWatcherNode>> =\n    new Map();\n\n  constructor(\n    private cacheManager: CacheManager,\n    private workbookManager: WorkbookManager\n  ) {}\n\n  private getSnapshotEligibilityState(node: SnapshotEligibleNode): {\n    eligible: boolean;\n    reason: string;\n  } {\n    if (node instanceof ResourceDependencyNode) {\n      return {\n        eligible: true,\n        reason: \"resource nodes are always snapshot eligible\",\n      };\n    }\n\n    if (node instanceof RangeEvaluationNode) {\n      return node.result.type === \"awaiting-evaluation\"\n        ? {\n            eligible: false,\n            reason: \"range result is still awaiting evaluation\",\n          }\n        : {\n            eligible: true,\n            reason: `range result type is ${node.result.type}`,\n          };\n    }\n\n    return node.evaluationResult.type === \"awaiting-evaluation\"\n      ? {\n          eligible: false,\n          reason: \"evaluation result is still awaiting evaluation\",\n        }\n      : {\n          eligible: true,\n          reason: `evaluation result type is ${node.evaluationResult.type}`,\n        };\n  }\n\n  private logSnapshotRestoreWarning(\n    message: string,\n    payload: Record<string, unknown>\n  ) {\n    console.warn(\"[FormulaEngine snapshot]\", message, payload);\n  }\n\n  private getLogicalNodeSnapshotId(node: DependencyNode): NodeSnapshotId {\n    if (node instanceof AstEvaluationNode) {\n      return getAstNodeSnapshotId(node);\n    }\n\n    return node.key;\n  }\n\n  private resetRestoredNodeToColdState(node: DependencyNode) {\n    this.unregisterNode(node);\n\n    if (node instanceof ResourceDependencyNode) {\n      return;\n    }\n\n    if (node instanceof CellValueNode) {\n      node.clearSpillMetaNode();\n    }\n\n    node.invalidate();\n  }\n\n  private getSheetWatcherKey(address: {\n    workbookName: string;\n    sheetName: string;\n  }): string {\n    return `${address.workbookName}:${address.sheetName}`;\n  }\n\n  private addReverseEdge(\n    map: Map<DependencyNode, Set<DependencyNode>>,\n    dependency: DependencyNode,\n    dependent: DependencyNode\n  ) {\n    const dependents = map.get(dependency) ?? new Set<DependencyNode>();\n    dependents.add(dependent);\n    map.set(dependency, dependents);\n  }\n\n  private removeReverseEdge(\n    map: Map<DependencyNode, Set<DependencyNode>>,\n    dependency: DependencyNode,\n    dependent: DependencyNode\n  ) {\n    const dependents = map.get(dependency);\n    if (!dependents) {\n      return;\n    }\n    dependents.delete(dependent);\n    if (dependents.size === 0) {\n      map.delete(dependency);\n    }\n  }\n\n  private getWatcherRange(node: FrontierWatcherNode): RangeAddress {\n    return node instanceof RangeEvaluationNode\n      ? node.address\n      : node.getFrontierRange();\n  }\n\n  private addWatcher(\n    map: Map<string, Set<FrontierWatcherNode>>,\n    node: FrontierWatcherNode\n  ) {\n    const watcherKey = this.getSheetWatcherKey(this.getWatcherRange(node));\n    const watchers = map.get(watcherKey) ?? new Set<FrontierWatcherNode>();\n    watchers.add(node);\n    map.set(watcherKey, watchers);\n  }\n\n  private removeWatcher(\n    map: Map<string, Set<FrontierWatcherNode>>,\n    node: FrontierWatcherNode\n  ) {\n    const watcherKey = this.getSheetWatcherKey(this.getWatcherRange(node));\n    const watchers = map.get(watcherKey);\n    if (!watchers) {\n      return;\n    }\n    watchers.delete(node);\n    if (watchers.size === 0) {\n      map.delete(watcherKey);\n    }\n  }\n\n  private registerWatcherNode(node: FrontierWatcherNode) {\n    this.addWatcher(this.coverageWatchersBySheet, node);\n    this.addWatcher(this.frontierWatchersBySheet, node);\n  }\n\n  private unregisterWatcherNode(node: FrontierWatcherNode) {\n    this.removeWatcher(this.coverageWatchersBySheet, node);\n    this.removeWatcher(this.frontierWatchersBySheet, node);\n  }\n\n  private isWatcherNodeResolved(node: FrontierWatcherNode): boolean {\n    return node instanceof RangeEvaluationNode\n      ? node.result.type !== \"awaiting-evaluation\"\n      : node.evaluationResult.type !== \"awaiting-evaluation\";\n  }\n\n  private getAllPersistentNodes(): DependencyNode[] {\n    const astNodes: AstEvaluationNode[] = [];\n    for (const astEntries of this.asts.values()) {\n      for (const astEntry of astEntries.entries.values()) {\n        astNodes.push(astEntry.evalNode);\n      }\n    }\n\n    return [\n      ...this.cellNodes.values(),\n      ...this.spillMetaNodes.values(),\n      ...this.emptyCells.values(),\n      ...this.ranges.values(),\n      ...this.resourceNodes.values(),\n      ...astNodes,\n    ];\n  }\n\n  private getExistingCellValueNode(nodeKey: string): CellValueNode | undefined {\n    return this.cellNodes.get(nodeKey);\n  }\n\n  private getExistingSpillMetaNode(nodeKey: string): SpillMetaNode | undefined {\n    return this.spillMetaNodes.get(nodeKey);\n  }\n\n  private getExistingEmptyCellNode(\n    nodeKey: string\n  ): EmptyCellEvaluationNode | undefined {\n    return this.emptyCells.get(nodeKey);\n  }\n\n  private collectExistingNodesForCell(address: CellAddress): DependencyNode[] {\n    const baseKey = cellAddressToKey(address);\n    const nodes: Array<\n      CellValueNode | EmptyCellEvaluationNode | SpillMetaNode | undefined\n    > = [\n      this.getExistingCellValueNode(baseKey),\n      this.getExistingEmptyCellNode(baseKey.replace(/^cell-value:/, \"empty:\")),\n      this.getExistingSpillMetaNode(\n        baseKey.replace(/^cell-value:/, \"spill-meta:\")\n      ),\n    ];\n    return nodes.filter(\n      (\n        node\n      ): node is CellValueNode | EmptyCellEvaluationNode | SpillMetaNode =>\n        node !== undefined\n    );\n  }\n\n  private collectExistingAstNodesForCell(\n    address: CellAddress\n  ): AstEvaluationNode[] {\n    const cellNode = this.getExistingCellValueNode(cellAddressToKey(address));\n    if (!cellNode) {\n      return [];\n    }\n\n    const collected = new Set<AstEvaluationNode>();\n    const stack = Array.from(cellNode.getDependencies()).filter(\n      (dependency): dependency is AstEvaluationNode =>\n        dependency instanceof AstEvaluationNode\n    );\n\n    while (stack.length > 0) {\n      const dependency = stack.pop();\n      if (!dependency) {\n        continue;\n      }\n\n      if (collected.has(dependency)) {\n        continue;\n      }\n      collected.add(dependency);\n\n      for (const nestedDependency of dependency.getDependencies()) {\n        if (nestedDependency instanceof AstEvaluationNode) {\n          stack.push(nestedDependency);\n        }\n      }\n    }\n\n    return Array.from(collected);\n  }\n\n  private collectExistingAstNodesForCells(\n    addresses: CellAddress[]\n  ): AstEvaluationNode[] {\n    const collected = new Set<AstEvaluationNode>();\n\n    for (const address of addresses) {\n      for (const astNode of this.collectExistingAstNodesForCell(address)) {\n        collected.add(astNode);\n      }\n    }\n\n    return Array.from(collected);\n  }\n\n  private astNodeHasExternalDependents(\n    node: AstEvaluationNode,\n    formulaAstNodes: Set<AstEvaluationNode>,\n    removedDependents: Set<DependencyNode>\n  ): boolean {\n    for (const dependent of this.getNodeDependents(node)) {\n      if (removedDependents.has(dependent)) {\n        continue;\n      }\n\n      if (dependent instanceof AstEvaluationNode && formulaAstNodes.has(dependent)) {\n        continue;\n      }\n\n      return true;\n    }\n\n    return false;\n  }\n\n  private collectOrphanedOldFormulaAstNodesForCell(\n    address: CellAddress\n  ): AstEvaluationNode[] {\n    return this.collectOrphanedOldFormulaAstNodesForCells([address]);\n  }\n\n  private collectOrphanedOldFormulaAstNodesForCells(\n    addresses: CellAddress[]\n  ): AstEvaluationNode[] {\n    const astNodes = this.collectExistingAstNodesForCells(addresses);\n    if (astNodes.length === 0) {\n      return [];\n    }\n\n    const formulaAstNodes = new Set(astNodes);\n    const removedDependents = new Set<DependencyNode>(\n      addresses.flatMap((address) => this.collectExistingNodesForCell(address))\n    );\n    const keptAstNodes = new Set<AstEvaluationNode>();\n    const stack = astNodes.filter((node) =>\n      this.astNodeHasExternalDependents(node, formulaAstNodes, removedDependents)\n    );\n\n    while (stack.length > 0) {\n      const node = stack.pop();\n      if (!node || keptAstNodes.has(node)) {\n        continue;\n      }\n      keptAstNodes.add(node);\n\n      for (const dependency of node.getDependencies()) {\n        if (dependency instanceof AstEvaluationNode && formulaAstNodes.has(dependency)) {\n          stack.push(dependency);\n        }\n      }\n    }\n\n    return astNodes.filter((node) => !keptAstNodes.has(node));\n  }\n\n  private removeAstNodeFromCache(node: AstEvaluationNode): void {\n    const astEntries = this.asts.get(node.key);\n    if (!astEntries) {\n      return;\n    }\n\n    for (const [contextKey, astEntry] of Array.from(astEntries.entries.entries())) {\n      if (astEntry.evalNode === node) {\n        astEntries.entries.delete(contextKey);\n      }\n    }\n\n    if (astEntries.entries.size === 0) {\n      this.asts.delete(node.key);\n    }\n  }\n\n  private collectSpillOriginsAffectingCell(\n    address: CellAddress\n  ): Set<DependencyNode> {\n    const affected = new Set<DependencyNode>();\n\n    for (const [spillOriginKey, spilledValue] of this._spilledValues.entries()) {\n      if (\n        spilledValue.origin.workbookName !== address.workbookName ||\n        spilledValue.origin.sheetName !== address.sheetName\n      ) {\n        continue;\n      }\n\n      const isOriginCell =\n        spilledValue.origin.colIndex === address.colIndex &&\n        spilledValue.origin.rowIndex === address.rowIndex;\n      if (isOriginCell || !isCellInRange(address, spilledValue.spillOnto)) {\n        continue;\n      }\n\n      const cellValueNode = this.cellNodes.get(`cell-value:${spillOriginKey}`);\n      if (cellValueNode) {\n        affected.add(cellValueNode);\n      }\n\n      const spillMetaNode = this.spillMetaNodes.get(\n        `spill-meta:${spillOriginKey}`\n      );\n      if (spillMetaNode) {\n        affected.add(spillMetaNode);\n      }\n    }\n\n    return affected;\n  }\n\n  private getLinkedSpillMetaNode(\n    node: CellValueNode | SpillMetaNode\n  ): SpillMetaNode | undefined {\n    if (node instanceof SpillMetaNode) {\n      return node;\n    }\n\n    return this.spillMetaNodes.get(\n      node.key.replace(/^cell-value:/, \"spill-meta:\")\n    );\n  }\n\n  private getLinkedCellValueNode(\n    node: CellValueNode | SpillMetaNode\n  ): CellValueNode | undefined {\n    if (node instanceof CellValueNode) {\n      return node;\n    }\n\n    return this.cellNodes.get(node.key.replace(/^spill-meta:/, \"cell-value:\"));\n  }\n\n  public registerNode(node: DependencyNode): void {\n    this.unregisterNode(node);\n\n    const hardDependencies = new Set(node.getDependencies());\n    const frontierDependencies =\n      node instanceof RangeEvaluationNode || node instanceof EmptyCellEvaluationNode\n        ? new Set(node.getFrontierDependencies())\n        : new Set<DependencyNode>();\n\n    this.registeredDependencies.set(node, {\n      hard: hardDependencies,\n      frontier: frontierDependencies,\n    });\n\n    for (const dependency of hardDependencies) {\n      this.addReverseEdge(this.hardDependents, dependency, node);\n    }\n\n    for (const dependency of frontierDependencies) {\n      this.addReverseEdge(this.frontierDependents, dependency, node);\n    }\n\n    if (\n      (node instanceof RangeEvaluationNode ||\n        node instanceof EmptyCellEvaluationNode) &&\n      this.isWatcherNodeResolved(node)\n    ) {\n      this.registerWatcherNode(node);\n    }\n  }\n\n  public unregisterNode(node: DependencyNode): void {\n    const registration = this.registeredDependencies.get(node);\n    if (registration) {\n      for (const dependency of registration.hard) {\n        this.removeReverseEdge(this.hardDependents, dependency, node);\n      }\n\n      for (const dependency of registration.frontier) {\n        this.removeReverseEdge(this.frontierDependents, dependency, node);\n      }\n\n      this.registeredDependencies.delete(node);\n    }\n\n    if (node instanceof RangeEvaluationNode || node instanceof EmptyCellEvaluationNode) {\n      this.unregisterWatcherNode(node);\n    }\n  }\n\n  private rebuildRuntimeIndexes() {\n    this.hardDependents.clear();\n    this.frontierDependents.clear();\n    this.registeredDependencies.clear();\n    this.coverageWatchersBySheet.clear();\n    this.frontierWatchersBySheet.clear();\n\n    for (const node of this.getAllPersistentNodes()) {\n      this.registerNode(node);\n    }\n  }\n\n  public get spilledValues(): IterableIterator<SpilledValue> {\n    return this._spilledValues.values();\n  }\n\n  isSpillOrigin(cellAddress: CellAddress): boolean {\n    for (const spilledValue of this._spilledValues.values()) {\n      if (\n        spilledValue.origin.sheetName !== cellAddress.sheetName ||\n        spilledValue.origin.workbookName !== cellAddress.workbookName\n      ) {\n        continue;\n      }\n      if (\n        spilledValue.origin.colIndex === cellAddress.colIndex &&\n        spilledValue.origin.rowIndex === cellAddress.rowIndex\n      ) {\n        return true;\n      }\n    }\n    return false;\n  }\n\n  getSpillValue(cellAddress: CellAddress): SpilledValue | undefined {\n    for (const spilledValue of this._spilledValues.values()) {\n      if (\n        spilledValue.origin.sheetName !== cellAddress.sheetName ||\n        spilledValue.origin.workbookName !== cellAddress.workbookName\n      ) {\n        continue;\n      }\n      if (\n        spilledValue.origin.colIndex === cellAddress.colIndex &&\n        spilledValue.origin.rowIndex === cellAddress.rowIndex\n      ) {\n        return undefined;\n      }\n      if (isCellInRange(cellAddress, spilledValue.spillOnto)) {\n        return spilledValue;\n      }\n    }\n    return undefined;\n  }\n\n  getSpilledAddress(\n    cellAddress: CellAddress,\n    /**\n     * if the spilled value is already available, we can use it to get the source address\n     */\n    passedSpilledValue?: SpilledValue\n  ): { address: CellAddress; spillOffset: { x: number; y: number } } {\n    const spilledValue = passedSpilledValue ?? this.getSpillValue(cellAddress);\n    if (!spilledValue) {\n      throw new Error(\"Cell is not spilled\");\n    }\n    const offsetLeft = cellAddress.colIndex - spilledValue.origin.colIndex;\n    const offsetTop = cellAddress.rowIndex - spilledValue.origin.rowIndex;\n    const address: CellAddress = {\n      ...cellAddress,\n      colIndex: spilledValue.origin.colIndex + offsetLeft,\n      rowIndex: spilledValue.origin.rowIndex + offsetTop,\n    };\n    if (offsetLeft === 0 && offsetTop === 0) {\n      throw new Error(\n        \"Spilled value is the same as the cell address! The origin has a pre-calculated value that can be used\"\n      );\n    }\n    return { address, spillOffset: { x: offsetLeft, y: offsetTop } };\n  }\n\n  clearEvaluationCache(): void {\n    this.cacheManager.clear();\n    this.cellNodes.clear();\n    this.emptyCells.clear();\n    this.virtualCellValueNodes.clear();\n    this.asts.clear();\n    this.spillMetaNodes.clear();\n    this.ranges.clear();\n    this.resourceNodes.clear();\n    this._spilledValues.clear();\n    this.hardDependents.clear();\n    this.frontierDependents.clear();\n    this.registeredDependencies.clear();\n    this.coverageWatchersBySheet.clear();\n    this.frontierWatchersBySheet.clear();\n  }\n\n  toSnapshot(evaluationManager: EvaluationManager): {\n    dependency: DependencyManagerSnapshot;\n    cache: CacheManagerSnapshot;\n  } {\n    const isNodeSnapshotEligible = (\n      node: SnapshotEligibleNode\n    ) => {\n      return this.getSnapshotEligibilityState(node).eligible;\n    };\n\n    const astNodes = new Set<AstEvaluationNode>();\n    for (const astEntries of this.asts.values()) {\n      for (const { evalNode } of astEntries.entries.values()) {\n        if (isNodeSnapshotEligible(evalNode)) {\n          astNodes.add(evalNode);\n        }\n      }\n    }\n\n    const snapshotSeedNodes: Array<\n      | CellValueNode\n      | SpillMetaNode\n      | EmptyCellEvaluationNode\n      | RangeEvaluationNode\n      | AstEvaluationNode\n      | ResourceDependencyNode\n    > = [\n      ...Array.from(this.cellNodes.values()).filter(isNodeSnapshotEligible),\n      ...Array.from(this.spillMetaNodes.values()).filter(isNodeSnapshotEligible),\n      ...Array.from(this.emptyCells.values()).filter(isNodeSnapshotEligible),\n      ...Array.from(this.ranges.values()).filter(isNodeSnapshotEligible),\n      ...Array.from(this.resourceNodes.values()).filter(isNodeSnapshotEligible),\n      ...Array.from(astNodes.values()),\n    ];\n\n    const resolvedNodesSet = new Set<\n      | CellValueNode\n      | SpillMetaNode\n      | EmptyCellEvaluationNode\n      | RangeEvaluationNode\n      | AstEvaluationNode\n      | ResourceDependencyNode\n    >();\n    const stack = [...snapshotSeedNodes];\n\n    while (stack.length > 0) {\n      const node = stack.pop();\n      if (!node || resolvedNodesSet.has(node)) {\n        continue;\n      }\n\n      resolvedNodesSet.add(node);\n\n      if (\n        node instanceof CellValueNode &&\n        node.spillMeta &&\n        isNodeSnapshotEligible(node.spillMeta)\n      ) {\n        stack.push(node.spillMeta);\n      }\n\n      for (const dependency of node.getDependencies()) {\n        if (!isNodeSnapshotEligible(dependency)) {\n          continue;\n        }\n        stack.push(dependency);\n      }\n    }\n\n    const resolvedNodes = Array.from(resolvedNodesSet);\n\n    const allNodeSnapshotIds = new Map<DependencyNode, NodeSnapshotId>();\n    const availableSnapshotIds = new Set<NodeSnapshotId>();\n    for (const node of resolvedNodes) {\n      const snapshotId = this.getLogicalNodeSnapshotId(node);\n      allNodeSnapshotIds.set(node, snapshotId);\n      availableSnapshotIds.add(snapshotId);\n    }\n\n    const getAllNodeSnapshotId = (\n      node: DependencyNode,\n      _context?: {\n        sourceNode?: DependencyNode;\n        relation?: string;\n      }\n    ): NodeSnapshotId => {\n      const snapshotId =\n        allNodeSnapshotIds.get(node) ??\n        (() => {\n          const logicalSnapshotId = this.getLogicalNodeSnapshotId(node);\n          return availableSnapshotIds.has(logicalSnapshotId)\n            ? logicalSnapshotId\n            : undefined;\n        })();\n      if (!snapshotId) {\n        throw new Error(`Missing snapshot id for dependency node ${node.key}`);\n      }\n      return snapshotId;\n    };\n\n    const nodeSnapshots: SerializedDependencyNodeSnapshot[] = [];\n    const includedSnapshotIds = new Set<NodeSnapshotId>();\n\n    for (const node of resolvedNodes) {\n      const snapshot = this.serializeNodeSnapshot(\n        node,\n        evaluationManager,\n        getAllNodeSnapshotId,\n        allNodeSnapshotIds\n      );\n      if (!snapshot) {\n        continue;\n      }\n      includedSnapshotIds.add(snapshot.snapshotId);\n      nodeSnapshots.push(snapshot);\n    }\n\n    const filteredNodeSnapshots = nodeSnapshots.map((snapshot) => {\n      const dependencies = snapshot.dependencies.filter((dependency) =>\n        includedSnapshotIds.has(dependency)\n      );\n\n      if (snapshot.kind === \"cell-value\") {\n        return {\n          ...snapshot,\n          dependencies,\n          spillMetaSnapshotId:\n            snapshot.spillMetaSnapshotId &&\n            includedSnapshotIds.has(snapshot.spillMetaSnapshotId)\n              ? snapshot.spillMetaSnapshotId\n              : undefined,\n        };\n      }\n\n      return {\n        ...snapshot,\n        dependencies,\n      };\n    });\n\n    const dependency: DependencyManagerSnapshot = {\n      nodes: filteredNodeSnapshots,\n      spilledValues: Array.from(this._spilledValues.entries()),\n    };\n\n    const cache = this.cacheManager.toSnapshot((node) => {\n      const snapshotId = allNodeSnapshotIds.get(node);\n      if (!snapshotId || !includedSnapshotIds.has(snapshotId)) {\n        return undefined;\n      }\n      return snapshotId;\n    });\n\n    return { dependency, cache };\n  }\n\n  restoreFromSnapshot(\n    snapshots: {\n      dependency: DependencyManagerSnapshot;\n      cache: CacheManagerSnapshot;\n    },\n    evaluationManager: EvaluationManager\n  ) {\n    this.clearEvaluationCache();\n\n    const nodesBySnapshotId = new Map<NodeSnapshotId, DependencyNode>();\n    let hadRestoreFailures = false;\n\n    for (const snapshot of snapshots.dependency.nodes) {\n      try {\n        const node = this.createNodeFromSnapshot(snapshot);\n        nodesBySnapshotId.set(snapshot.snapshotId, node);\n      } catch (error) {\n        hadRestoreFailures = true;\n        this.logSnapshotRestoreWarning(\n          \"Failed to create warm snapshot node; discarding warm dependency state\",\n          {\n            phase: \"create-node\",\n            snapshotId: snapshot.snapshotId,\n            kind: snapshot.kind,\n            key: snapshot.key,\n            error:\n              error instanceof Error\n                ? { name: error.name, message: error.message }\n                : { message: String(error) },\n          }\n        );\n      }\n    }\n\n    if (hadRestoreFailures) {\n      this.clearEvaluationCache();\n      return;\n    }\n\n    const resolveNodeSnapshotId = (snapshotId: NodeSnapshotId) =>\n      nodesBySnapshotId.get(snapshotId);\n    const resolveRequiredNodeSnapshotId = (\n      snapshotId: NodeSnapshotId\n    ): DependencyNode => {\n      const node = resolveNodeSnapshotId(snapshotId);\n      if (!node) {\n        throw new Error(`Unknown node snapshot id: ${snapshotId}`);\n      }\n      return node;\n    };\n\n    for (const snapshot of snapshots.dependency.nodes) {\n      const targetNode = nodesBySnapshotId.get(snapshot.snapshotId);\n      if (!targetNode) {\n        hadRestoreFailures = true;\n        continue;\n      }\n\n      const dependencies = new Set(\n        snapshot.dependencies\n          .map(resolveNodeSnapshotId)\n          .filter((node): node is DependencyNode => node !== undefined)\n      );\n\n      try {\n        if (snapshot.kind === \"cell-value\") {\n          const node = targetNode as CellValueNode;\n          node.restoreResolvedSnapshot({\n            dependencies,\n            evaluationResult:\n              evaluationManager.deserializeSingleEvaluationResultSnapshot(\n                snapshot.evaluationResult,\n                resolveRequiredNodeSnapshotId\n              ),\n          });\n          if (snapshot.spillMetaSnapshotId) {\n            const spillMetaNode = resolveNodeSnapshotId(\n              snapshot.spillMetaSnapshotId\n            );\n            if (spillMetaNode instanceof SpillMetaNode) {\n              node.setSpillMetaNode(spillMetaNode);\n            }\n          }\n          continue;\n        }\n\n        if (snapshot.kind === \"spill-meta\") {\n          const node = targetNode as SpillMetaNode;\n          node.restoreResolvedSnapshot({\n            dependencies,\n            evaluationResult:\n              evaluationManager.deserializeSpillMetaEvaluationResultSnapshot(\n                snapshot.evaluationResult,\n                resolveRequiredNodeSnapshotId\n              ),\n          });\n          continue;\n        }\n\n        if (snapshot.kind === \"empty\") {\n          const node = targetNode as EmptyCellEvaluationNode;\n          node.restoreResolvedSnapshot({\n            dependencies,\n            evaluationResult:\n              evaluationManager.deserializeSingleEvaluationResultSnapshot(\n                snapshot.evaluationResult,\n                resolveRequiredNodeSnapshotId\n              ),\n          });\n          continue;\n        }\n\n        if (snapshot.kind === \"range\") {\n          const node = targetNode as RangeEvaluationNode;\n          node.restoreResolvedSnapshot({\n            dependencies,\n            result: evaluationManager.deserializeEvaluateAllCellsResultSnapshot(\n              snapshot.result,\n              resolveRequiredNodeSnapshotId\n            ),\n          });\n          continue;\n        }\n\n        if (snapshot.kind === \"resource\") {\n          continue;\n        }\n\n        const node = targetNode as AstEvaluationNode;\n        node.restoreResolvedSnapshot({\n          dependencies,\n          evaluationResult:\n            evaluationManager.deserializeFunctionEvaluationResultSnapshot(\n              snapshot.evaluationResult,\n              resolveRequiredNodeSnapshotId\n            ),\n        });\n        this.saveAstNode(node, snapshot.contextDependency);\n      } catch (error) {\n        hadRestoreFailures = true;\n        this.resetRestoredNodeToColdState(targetNode);\n        this.logSnapshotRestoreWarning(\n          \"Failed to deserialize warm snapshot node; discarding warm dependency state\",\n          {\n            phase: \"restore-node\",\n            snapshotId: snapshot.snapshotId,\n            kind: snapshot.kind,\n            key: snapshot.key,\n            error:\n              error instanceof Error\n                ? { name: error.name, message: error.message }\n                : { message: String(error) },\n          }\n        );\n      }\n    }\n\n    this._spilledValues = new Map(snapshots.dependency.spilledValues);\n    this.rebuildRuntimeIndexes();\n    this.cacheManager.restoreFromSnapshot(\n      snapshots.cache,\n      resolveNodeSnapshotId\n    );\n  }\n\n  private serializeNodeSnapshot(\n    node: SnapshotEligibleNode,\n    evaluationManager: EvaluationManager,\n    getNodeSnapshotId: (\n      node: DependencyNode,\n      context?: {\n        sourceNode?: DependencyNode;\n        relation?: string;\n      }\n    ) => NodeSnapshotId,\n    allNodeSnapshotIds: Map<DependencyNode, NodeSnapshotId>\n  ): SerializedDependencyNodeSnapshot | undefined {\n    const snapshotId = getNodeSnapshotId(node);\n    const getKnownSnapshotId = (dependency: DependencyNode) => {\n      const directSnapshotId = allNodeSnapshotIds.get(dependency);\n      if (directSnapshotId) {\n        return directSnapshotId;\n      }\n\n      const logicalSnapshotId = this.getLogicalNodeSnapshotId(dependency);\n      return allNodeSnapshotIds\n        .values()\n        .some((knownSnapshotId) => knownSnapshotId === logicalSnapshotId)\n        ? logicalSnapshotId\n        : undefined;\n    };\n\n    const dependencies: NodeSnapshotId[] = [];\n    for (const dependency of node.getDependencies()) {\n      const dependencySnapshotId = getKnownSnapshotId(dependency);\n      if (!dependencySnapshotId) {\n        return undefined;\n      }\n      dependencies.push(dependencySnapshotId);\n    }\n\n    const getReferencedNodeSnapshotId = (dependency: DependencyNode) =>\n      getNodeSnapshotId(dependency, {\n        sourceNode: node,\n        relation: \"evaluation result errAddress\",\n      });\n\n    if (node instanceof CellValueNode) {\n      const spillMetaSnapshotId = node.spillMeta\n        ? getKnownSnapshotId(node.spillMeta)\n        : undefined;\n      if (node.spillMeta && !spillMetaSnapshotId) {\n        return undefined;\n      }\n\n      const evaluationResult =\n        evaluationManager.serializeSingleEvaluationResultSnapshot(\n          node.evaluationResult,\n          getReferencedNodeSnapshotId\n        );\n      if (!evaluationResult) {\n        return undefined;\n      }\n      return {\n        kind: \"cell-value\",\n        snapshotId,\n        key: node.key,\n        dependencies,\n        evaluationResult,\n        spillMetaSnapshotId,\n      };\n    }\n\n    if (node instanceof SpillMetaNode) {\n      const evaluationResult =\n        evaluationManager.serializeSpillMetaEvaluationResultSnapshot(\n          node.evaluationResult,\n          {\n            sourceNode: node,\n            getNodeSnapshotId: getReferencedNodeSnapshotId,\n          }\n        );\n      if (!evaluationResult) {\n        return undefined;\n      }\n      return {\n        kind: \"spill-meta\",\n        snapshotId,\n        key: node.key,\n        dependencies,\n        evaluationResult,\n      };\n    }\n\n    if (node instanceof EmptyCellEvaluationNode) {\n      const evaluationResult =\n        evaluationManager.serializeSingleEvaluationResultSnapshot(\n          node.evaluationResult,\n          getReferencedNodeSnapshotId\n        );\n      if (!evaluationResult) {\n        return undefined;\n      }\n      return {\n        kind: \"empty\",\n        snapshotId,\n        key: node.key,\n        dependencies,\n        evaluationResult,\n      };\n    }\n\n    if (node instanceof RangeEvaluationNode) {\n      const result = evaluationManager.serializeEvaluateAllCellsResultSnapshot(\n        node.result,\n        getReferencedNodeSnapshotId\n      );\n      if (!result) {\n        return undefined;\n      }\n      return {\n        kind: \"range\",\n        snapshotId,\n        key: node.key,\n        dependencies,\n        result,\n      };\n    }\n\n    if (node instanceof ResourceDependencyNode) {\n      return {\n        kind: \"resource\",\n        snapshotId,\n        key: node.key,\n        dependencies,\n      };\n    }\n\n    const evaluationResult =\n      evaluationManager.serializeFunctionEvaluationResultSnapshot(\n        node.evaluationResult,\n        {\n          sourceNode: node,\n          getNodeSnapshotId: getReferencedNodeSnapshotId,\n        }\n      );\n    if (!evaluationResult) {\n      return undefined;\n    }\n    return {\n      kind: \"ast\",\n      snapshotId,\n      key: node.key,\n      dependencies,\n      contextDependency: node.getContextDependency(),\n      evaluationResult,\n    };\n  }\n\n  private createNodeFromSnapshot(\n    snapshot: SerializedDependencyNodeSnapshot\n  ): DependencyNode {\n    if (snapshot.kind === \"cell-value\") {\n      const node = new CellValueNode(snapshot.key);\n      this.cellNodes.set(snapshot.key, node);\n      return node;\n    }\n\n    if (snapshot.kind === \"spill-meta\") {\n      const node = new SpillMetaNode(snapshot.key);\n      this.spillMetaNodes.set(snapshot.key, node);\n      return node;\n    }\n\n    if (snapshot.kind === \"empty\") {\n      const node = new EmptyCellEvaluationNode(\n        snapshot.key,\n        this,\n        this.workbookManager,\n        { skipInitialBuild: true }\n      );\n      this.emptyCells.set(snapshot.key, node);\n      return node;\n    }\n\n    if (snapshot.kind === \"range\") {\n      const node = new RangeEvaluationNode(\n        snapshot.key,\n        this,\n        this.workbookManager,\n        { skipInitialBuild: true }\n      );\n      this.ranges.set(snapshot.key, node);\n      return node;\n    }\n\n    if (snapshot.kind === \"resource\") {\n      const node = new ResourceDependencyNode(snapshot.key);\n      this.resourceNodes.set(snapshot.key, node);\n      return node;\n    }\n\n    const node = new AstEvaluationNode(\n      parseFormula(snapshot.key.slice(4)),\n      snapshot.contextDependency\n    );\n    return node;\n  }\n\n  setSpilledValue(nodeKey: string, spilledValue: SpilledValue): void {\n    this._spilledValues.set(nodeKey.replace(/^[^:]+:/, \"\"), spilledValue);\n  }\n\n  getSpilledValue(nodeKey: string): SpilledValue | undefined {\n    return this._spilledValues.get(nodeKey.replace(/^[^:]+:/, \"\"));\n  }\n\n  deleteSpilledValue(nodeKey: string): void {\n    this._spilledValues.delete(nodeKey.replace(/^[^:]+:/, \"\"));\n  }\n\n  getEmptyCellNode(nodeKey: string): EmptyCellEvaluationNode {\n    if (!nodeKey.startsWith(\"empty:\")) {\n      throw new Error(\"Invalid empty cell node key: \" + nodeKey);\n    }\n    if (!this.emptyCells.has(nodeKey)) {\n      const node = new EmptyCellEvaluationNode(\n        nodeKey,\n        this,\n        this.workbookManager\n      );\n      this.emptyCells.set(nodeKey, node);\n      return node;\n    }\n    return this.emptyCells.get(nodeKey)!;\n  }\n\n  getSpillMetaNode(nodeKey: string): SpillMetaNode {\n    if (!nodeKey.startsWith(\"spill-meta:\")) {\n      throw new Error(\"Invalid spill meta node key: \" + nodeKey);\n    }\n    if (!this.spillMetaNodes.has(nodeKey)) {\n      const node = new SpillMetaNode(nodeKey);\n      this.spillMetaNodes.set(nodeKey, node);\n      return node;\n    }\n    return this.spillMetaNodes.get(nodeKey)!;\n  }\n\n  getCellValueNode(nodeKey: string): CellValueNode {\n    if (!nodeKey.startsWith(\"cell-value:\")) {\n      throw new Error(\"Invalid cell value node key: \" + nodeKey);\n    }\n    if (!this.cellNodes.has(nodeKey)) {\n      const node = new CellValueNode(nodeKey);\n      this.cellNodes.set(nodeKey, node);\n      return node;\n    }\n    return this.cellNodes.get(nodeKey)!;\n  }\n\n  getResourceNode(resourceKey: string): ResourceDependencyNode {\n    if (!this.resourceNodes.has(resourceKey)) {\n      const node = new ResourceDependencyNode(resourceKey);\n      this.resourceNodes.set(resourceKey, node);\n      return node;\n    }\n    return this.resourceNodes.get(resourceKey)!;\n  }\n\n  getCellValueOrEmptyCellNode(\n    nodeKey: string\n  ): CellValueNode | EmptyCellEvaluationNode {\n    const cellAddress = keyToCellAddress(nodeKey);\n\n    const emptyKey = nodeKey.replace(/^[^:]+:/, \"empty:\");\n    const cellValueKey = nodeKey.replace(/^[^:]+:/, \"cell-value:\");\n\n    if (this.workbookManager.isCellEmpty(cellAddress)) {\n      return this.getEmptyCellNode(emptyKey);\n    }\n\n    return this.getCellValueNode(cellValueKey);\n  }\n\n  getSpillMetaOrEmptySpillMetaNode(\n    nodeKey: string\n  ): SpillMetaNode | EmptyCellEvaluationNode {\n    const cellAddress = keyToCellAddress(nodeKey);\n\n    const emptyKey = nodeKey.replace(/^[^:]+:/, \"empty:\");\n    const spillMetaKey = nodeKey.replace(/^[^:]+:/, \"spill-meta:\");\n\n    if (this.workbookManager.isCellEmpty(cellAddress)) {\n      return this.getEmptyCellNode(emptyKey);\n    }\n\n    return this.getSpillMetaNode(spillMetaKey);\n  }\n\n  getVirtualCellValueNode(\n    cellAddress: CellAddress,\n    cellValue: SerializedCellValue\n  ): VirtualCellValueNode {\n    let nodeKey = cellAddressToKey(cellAddress).replace(/^[^:]+:/, \"virtual:\");\n    nodeKey += \":\";\n    const normalizedCellValue = normalizeSerializedCellValue(cellValue);\n\n    if (\n      typeof normalizedCellValue === \"string\" &&\n      normalizedCellValue.startsWith(\"=\")\n    ) {\n      const ast = parseFormula(normalizedCellValue.slice(1));\n      nodeKey += \"ast:\" + astToString(ast);\n    } else if (\n      typeof normalizedCellValue === \"string\" &&\n      normalizedCellValue !== \"\"\n    ) {\n      nodeKey += \"string:\" + normalizedCellValue;\n    } else if (typeof normalizedCellValue === \"number\") {\n      nodeKey += \"number:\" + normalizedCellValue;\n    } else if (typeof normalizedCellValue === \"boolean\") {\n      nodeKey += \"boolean:\" + normalizedCellValue;\n    } else if (normalizedCellValue === undefined) {\n      nodeKey += \"string:\";\n    } else {\n      throw new Error(\"Invalid cell value: \" + normalizedCellValue);\n    }\n\n    if (!this.virtualCellValueNodes.has(nodeKey)) {\n      const node = new VirtualCellValueNode(nodeKey, cellAddress, cellValue);\n      this.virtualCellValueNodes.set(nodeKey, node);\n      return node;\n    }\n    return this.virtualCellValueNodes.get(nodeKey)!;\n  }\n\n  getRangeNode(rangeKey: string): RangeEvaluationNode {\n    if (!rangeKey.startsWith(\"range:\")) {\n      throw new Error(\"Invalid range node key: \" + rangeKey);\n    }\n    if (!this.ranges.has(rangeKey)) {\n      const node = new RangeEvaluationNode(\n        rangeKey,\n        this,\n        this.workbookManager\n      );\n      this.ranges.set(rangeKey, node);\n      return node;\n    }\n    return this.ranges.get(rangeKey)!;\n  }\n\n  asts: Map<\n    /**\n     * ast key\n     */\n    string,\n    {\n      entries: Map<\n        /**\n         * context dependency key\n         */\n        string,\n        {\n          evalNode: AstEvaluationNode;\n          contextDependency: ContextDependency;\n        }\n      >;\n    }\n  > = new Map();\n\n  getAstNode(\n    ast: ASTNode,\n    currentContext: Omit<Required<ContextDependency>, \"tableName\"> & {\n      tableName?: string;\n    }\n  ): AstEvaluationNode {\n    const astKey = `ast:${astToString(ast)}`; // cache normalize this later\n    const astEntries = this.asts.get(astKey);\n\n    // if any of the ast entries match the current context, then we can return the ast node\n    // otherwise we have to evalute the ast node to understand if it is context dependent\n    // and later it will be saved using saveAstNode\n    // eligibleKeysForContext returns keys ordered from most-specific to least-specific\n    const keys = eligibleKeysForContext(currentContext);\n\n    for (const key of keys) {\n      const astEntry = astEntries?.entries.get(key);\n      if (!astEntry) {\n        continue;\n      }\n\n      if (astEntry) {\n        return astEntry.evalNode;\n      }\n    }\n\n    // by default the ast node is cell specific\n    // but later, setContextDependency is called with a more open context dependency\n    const node = new AstEvaluationNode(ast, currentContext);\n    // initially we store it as a cell, sheet, workbook and table dependent node\n    // but later, once resolved, we can store it under a looser dependency key, e.g. only sheet, workbook and table dependent\n    this.saveAstNode(node, currentContext);\n    return node;\n  }\n\n\n  /**\n   * Once an AST node is evaluated, we know if it is context dependent\n   * and will thus save it under the correct cache key according to its\n   * contextDependency\n   *\n   * only resolved ast nodes can be saved\n   */\n  private saveAstNode(\n    ast: AstEvaluationNode,\n    contextDependency: ContextDependency\n  ) {\n    const astKey = ast.key;\n    const contextDependencyKey = getContextDependencyKey(contextDependency);\n    this.removeAstNodeFromCache(ast);\n    const astEntries = this.asts.get(astKey);\n\n    if (astEntries) {\n      // if we don't already have an entry, then let's add it\n      astEntries.entries.set(contextDependencyKey, {\n        evalNode: ast,\n        contextDependency,\n      });\n    } else {\n      this.asts.set(astKey, {\n        entries: new Map([\n          [contextDependencyKey, { evalNode: ast, contextDependency }],\n        ]),\n      });\n    }\n  }\n\n  private isFiniteEndAfter(value: number, end: RangeAddress[\"range\"][\"end\"][\"row\"]) {\n    return end.type === \"infinity\" || value < end.value;\n  }\n\n  private doesAddressAffectWatcherFrontier(\n    address: CellAddress,\n    watcher: FrontierWatcherNode\n  ): boolean {\n    const watcherRange = this.getWatcherRange(watcher).range;\n    const rowWithinRange =\n      address.rowIndex >= watcherRange.start.row &&\n      (watcherRange.end.row.type === \"infinity\" ||\n        address.rowIndex <= watcherRange.end.row.value);\n    const colWithinRange =\n      address.colIndex >= watcherRange.start.col &&\n      (watcherRange.end.col.type === \"infinity\" ||\n        address.colIndex <= watcherRange.end.col.value);\n    const canReachFurtherRows = this.isFiniteEndAfter(\n      address.rowIndex,\n      watcherRange.end.row\n    );\n    const canReachFurtherCols = this.isFiniteEndAfter(\n      address.colIndex,\n      watcherRange.end.col\n    );\n\n    return (\n      (rowWithinRange && canReachFurtherCols) ||\n      (colWithinRange && canReachFurtherRows) ||\n      (canReachFurtherRows && canReachFurtherCols)\n    );\n  }\n\n  private collectCoverageWatchers(address: CellAddress): Set<FrontierWatcherNode> {\n    const watchers =\n      this.coverageWatchersBySheet.get(this.getSheetWatcherKey(address)) ??\n      new Set<FrontierWatcherNode>();\n    const affected = new Set<FrontierWatcherNode>();\n\n    for (const watcher of watchers) {\n      if (isCellInRange(address, this.getWatcherRange(watcher).range)) {\n        affected.add(watcher);\n      }\n    }\n\n    return affected;\n  }\n\n  private collectFrontierWatchers(address: CellAddress): Set<FrontierWatcherNode> {\n    const watchers =\n      this.frontierWatchersBySheet.get(this.getSheetWatcherKey(address)) ??\n      new Set<FrontierWatcherNode>();\n    const affected = new Set<FrontierWatcherNode>();\n\n    for (const watcher of watchers) {\n      if (this.doesAddressAffectWatcherFrontier(address, watcher)) {\n        affected.add(watcher);\n      }\n    }\n\n    return affected;\n  }\n\n  private collectWatchersIntersectingRange(address: RangeAddress): Set<FrontierWatcherNode> {\n    const watchers =\n      this.coverageWatchersBySheet.get(this.getSheetWatcherKey(address)) ??\n      new Set<FrontierWatcherNode>();\n    const affected = new Set<FrontierWatcherNode>();\n\n    for (const watcher of watchers) {\n      if (\n        checkRangeIntersection(\n          address.range,\n          this.getWatcherRange(watcher).range\n        )\n      ) {\n        affected.add(watcher);\n      }\n    }\n\n    return affected;\n  }\n\n  private getNodeDependents(node: DependencyNode): Set<DependencyNode> {\n    return (this.hardDependents.get(node) ?? new Set()).union(\n      this.frontierDependents.get(node) ?? new Set()\n    );\n  }\n\n  private collectInvalidationExtras(node: DependencyNode): Set<DependencyNode> {\n    const extras = new Set<DependencyNode>();\n\n    if (node instanceof CellValueNode || node instanceof SpillMetaNode) {\n      const spillMetaNode = this.getLinkedSpillMetaNode(node);\n      if (spillMetaNode) {\n        extras.add(spillMetaNode);\n      }\n\n      const cellNode = this.getLinkedCellValueNode(node);\n      if (cellNode) {\n        extras.add(cellNode);\n      }\n\n      const spill = this.getSpilledValue(node.key);\n      if (spill) {\n        for (const watcher of this.collectWatchersIntersectingRange({\n          workbookName: spill.origin.workbookName,\n          sheetName: spill.origin.sheetName,\n          range: spill.spillOnto,\n        })) {\n          extras.add(watcher);\n        }\n      }\n\n      const cellAddress = node.cellAddress;\n      for (const watcher of this.collectCoverageWatchers(cellAddress)) {\n        extras.add(watcher);\n      }\n      for (const watcher of this.collectFrontierWatchers(cellAddress)) {\n        extras.add(watcher);\n      }\n    }\n\n    return extras;\n  }\n\n  private invalidateNodeState(node: DependencyNode, invalidatedKeys: Set<string>) {\n    this.unregisterNode(node);\n    invalidatedKeys.add(node.key);\n\n    if (node instanceof CellValueNode) {\n      node.clearSpillMetaNode();\n      this.deleteSpilledValue(node.key);\n      node.invalidate();\n      return;\n    }\n\n    if (node instanceof SpillMetaNode) {\n      this.deleteSpilledValue(node.key);\n      this.getLinkedCellValueNode(node)?.clearSpillMetaNode();\n      node.invalidate();\n      return;\n    }\n\n    if (\n      node instanceof EmptyCellEvaluationNode ||\n      node instanceof RangeEvaluationNode ||\n      node instanceof AstEvaluationNode\n    ) {\n      node.invalidate();\n      return;\n    }\n\n    if (node instanceof ResourceDependencyNode) {\n      return;\n    }\n  }\n\n  private isResourceNodeInRemovedScope(\n    resourceKey: string,\n    scope: RemovedScope\n  ): boolean {\n    if (scope.type === \"workbook\") {\n      return (\n        resourceKey === `resource:workbook:${scope.workbookName}` ||\n        resourceKey.startsWith(`resource:sheet:${scope.workbookName}:`) ||\n        resourceKey.startsWith(`resource:table:${scope.workbookName}:`) ||\n        resourceKey.startsWith(\n          `resource:named:workbook:${scope.workbookName}:`\n        ) ||\n        resourceKey.startsWith(`resource:named:sheet:${scope.workbookName}:`)\n      );\n    }\n\n    return (\n      resourceKey ===\n        `resource:sheet:${scope.workbookName}:${scope.sheetName}` ||\n      resourceKey.startsWith(\n        `resource:named:sheet:${scope.workbookName}:${scope.sheetName}:`\n      )\n    );\n  }\n\n  private isNodeInRemovedScope(node: DependencyNode, scope: RemovedScope): boolean {\n    if (node instanceof ResourceDependencyNode) {\n      return this.isResourceNodeInRemovedScope(node.key, scope);\n    }\n\n    if (node instanceof AstEvaluationNode) {\n      const contextDependency = node.getContextDependency();\n      if (scope.type === \"workbook\") {\n        return contextDependency.workbookName === scope.workbookName;\n      }\n      return (\n        contextDependency.workbookName === scope.workbookName &&\n        contextDependency.sheetName === scope.sheetName\n      );\n    }\n\n    const workbookName =\n      node instanceof RangeEvaluationNode\n        ? node.address.workbookName\n        : node.cellAddress.workbookName;\n    const sheetName =\n      node instanceof RangeEvaluationNode\n        ? node.address.sheetName\n        : node.cellAddress.sheetName;\n\n    if (scope.type === \"workbook\") {\n      return workbookName === scope.workbookName;\n    }\n\n    return workbookName === scope.workbookName && sheetName === scope.sheetName;\n  }\n\n  private collectNodesForRemovedScopes(\n    removedScopes: RemovedScope[]\n  ): Set<DependencyNode> {\n    const affected = new Set<DependencyNode>();\n\n    for (const node of this.getAllPersistentNodes()) {\n      if (removedScopes.some((scope) => this.isNodeInRemovedScope(node, scope))) {\n        affected.add(node);\n      }\n    }\n\n    return affected;\n  }\n\n  private purgeRemovedScopes(removedScopes: RemovedScope[]) {\n    const shouldRemoveAddress = (\n      address: Pick<CellAddress, \"workbookName\" | \"sheetName\">\n    ) =>\n      removedScopes.some((scope) =>\n        scope.type === \"workbook\"\n          ? address.workbookName === scope.workbookName\n          : address.workbookName === scope.workbookName &&\n            address.sheetName === scope.sheetName\n      );\n\n    for (const [key, node] of Array.from(this.cellNodes.entries())) {\n      if (shouldRemoveAddress(node.cellAddress)) {\n        this.unregisterNode(node);\n        this.cellNodes.delete(key);\n      }\n    }\n\n    for (const [key, node] of Array.from(this.spillMetaNodes.entries())) {\n      if (shouldRemoveAddress(node.cellAddress)) {\n        this.unregisterNode(node);\n        this.spillMetaNodes.delete(key);\n      }\n    }\n\n    for (const [key, node] of Array.from(this.emptyCells.entries())) {\n      if (shouldRemoveAddress(node.cellAddress)) {\n        this.unregisterNode(node);\n        this.emptyCells.delete(key);\n      }\n    }\n\n    for (const [key, node] of Array.from(this.ranges.entries())) {\n      if (\n        shouldRemoveAddress({\n          workbookName: node.address.workbookName,\n          sheetName: node.address.sheetName,\n        })\n      ) {\n        this.unregisterNode(node);\n        this.ranges.delete(key);\n      }\n    }\n\n    for (const [key, node] of Array.from(this.resourceNodes.entries())) {\n      if (removedScopes.some((scope) => this.isResourceNodeInRemovedScope(key, scope))) {\n        this.unregisterNode(node);\n        this.resourceNodes.delete(key);\n      }\n    }\n\n    for (const [astKey, astEntries] of Array.from(this.asts.entries())) {\n      for (const [contextKey, astEntry] of Array.from(astEntries.entries.entries())) {\n        if (\n          removedScopes.some((scope) =>\n            this.isNodeInRemovedScope(astEntry.evalNode, scope)\n          )\n        ) {\n          this.unregisterNode(astEntry.evalNode);\n          astEntries.entries.delete(contextKey);\n        }\n      }\n\n      if (astEntries.entries.size === 0) {\n        this.asts.delete(astKey);\n      }\n    }\n\n    for (const [spillOriginKey, spilledValue] of Array.from(this._spilledValues.entries())) {\n      if (\n        shouldRemoveAddress({\n          workbookName: spilledValue.origin.workbookName,\n          sheetName: spilledValue.origin.sheetName,\n        })\n      ) {\n        this._spilledValues.delete(spillOriginKey);\n      }\n    }\n  }\n\n  public invalidateFromMutation(footprint: MutationInvalidation): void {\n    const queue: DependencyNode[] = [];\n    const visited = new Set<DependencyNode>();\n    const invalidatedNodeKeys = new Set<string>();\n    const invalidatedAstNodes = new Set<AstEvaluationNode>();\n    const evictedAstNodes = new Set<AstEvaluationNode>();\n\n    const evictAstNodeFromCache = (astNode: AstEvaluationNode) => {\n      if (evictedAstNodes.has(astNode)) {\n        return;\n      }\n      evictedAstNodes.add(astNode);\n      this.removeAstNodeFromCache(astNode);\n      invalidatedNodeKeys.add(astNode.key);\n    };\n\n    const invalidateAstNode = (astNode: AstEvaluationNode) => {\n      if (invalidatedAstNodes.has(astNode)) {\n        return;\n      }\n      invalidatedAstNodes.add(astNode);\n      evictAstNodeFromCache(astNode);\n      this.unregisterNode(astNode);\n      astNode.invalidate();\n    };\n\n    const tableContextChangedCells = Array.from(\n      new Map(\n        (footprint.tableContextChangedCells ?? []).map((address) => [\n          cellAddressToKey(address),\n          address,\n        ])\n      ).values()\n    );\n\n    for (const astNode of this.collectExistingAstNodesForCells(\n      tableContextChangedCells\n    )) {\n      evictAstNodeFromCache(astNode);\n    }\n\n    for (const astNode of this.collectOrphanedOldFormulaAstNodesForCells(\n      tableContextChangedCells\n    )) {\n      invalidateAstNode(astNode);\n    }\n\n    for (const touchedCell of footprint.touchedCells) {\n      if (touchedCell.beforeKind === \"formula\") {\n        for (const astNode of this.collectOrphanedOldFormulaAstNodesForCell(\n          touchedCell.address\n        )) {\n          invalidateAstNode(astNode);\n        }\n      }\n\n      for (const node of this.collectExistingNodesForCell(touchedCell.address)) {\n        queue.push(node);\n      }\n\n      for (const node of this.collectSpillOriginsAffectingCell(touchedCell.address)) {\n        queue.push(node);\n      }\n\n      for (const watcher of this.collectCoverageWatchers(touchedCell.address)) {\n        queue.push(watcher);\n      }\n      for (const watcher of this.collectFrontierWatchers(touchedCell.address)) {\n        queue.push(watcher);\n      }\n    }\n\n    for (const resourceKey of footprint.resourceKeys) {\n      const resourceNode = this.resourceNodes.get(resourceKey);\n      if (resourceNode) {\n        queue.push(resourceNode);\n      }\n    }\n\n    if (footprint.removedScopes?.length) {\n      for (const node of this.collectNodesForRemovedScopes(footprint.removedScopes)) {\n        queue.push(node);\n      }\n    }\n\n    while (queue.length > 0) {\n      const node = queue.pop();\n      if (!node || visited.has(node)) {\n        continue;\n      }\n      visited.add(node);\n\n      for (const dependent of this.getNodeDependents(node)) {\n        queue.push(dependent);\n      }\n\n      for (const extra of this.collectInvalidationExtras(node)) {\n        queue.push(extra);\n      }\n\n      this.invalidateNodeState(node, invalidatedNodeKeys);\n    }\n\n    this.cacheManager.deleteEvaluationOrders(invalidatedNodeKeys);\n    this.cacheManager.clearSCCCache();\n\n    if (footprint.removedScopes?.length) {\n      this.purgeRemovedScopes(footprint.removedScopes);\n    }\n  }\n\n  //#region dependency graph methods\n\n  /**\n   * Get transitive dependencies and transitive frontier dependencies\n   * This is only used by buildEvaluationOrder, so we'll optimize it there\n   */\n  getTransitiveDepsForEvalOrder(\n    node: DependencyNode,\n    visited: Set<DependencyNode> = new Set()\n  ): Set<DependencyNode> {\n    // Prevent infinite recursion\n    if (visited.has(node)) {\n      return new Set();\n    }\n\n    // If the node is resolved, then we don't need to evaluate it\n    if (node && node.resolved) {\n      return new Set();\n    }\n\n    // Mark this node as visited for cycle detection\n    visited.add(node);\n\n    const allNodes = new Set<DependencyNode>();\n    allNodes.add(node);\n\n    // Get direct dependencies (regular + frontier)\n    const directDeps = node.getDependencies();\n\n    // Recursively get transitive dependencies for each direct dependency\n    for (const dep of directDeps) {\n      if (!visited.has(dep)) {\n        const depTransitiveDeps = this.getTransitiveDepsForEvalOrder(\n          dep,\n          visited\n        );\n        for (const transitiveDep of depTransitiveDeps) {\n          allNodes.add(transitiveDep);\n        }\n      }\n    }\n\n    // Remove this node from visited set for other branches\n    visited.delete(node);\n\n    return allNodes;\n  }\n\n  /**\n   * Build evaluation order for a cell using SCC-based condensation DAG approach\n   *\n   * Algorithm:\n   * 1. Discover all transitive dependencies (skipping resolved nodes)\n   * 2. Find SCCs using Tarjan's algorithm\n   * 3. Create condensation DAG from SCCs\n   * 4. Topologically sort the condensation DAG using Kahn's algorithm\n   * 5. For each SCC, create internal evaluation order with cycle breaking\n   * 6. Join the sorted SCC evaluation orders to create final evaluation order\n   */\n  buildEvaluationOrder(\n    node: CellValueNode | EmptyCellEvaluationNode | VirtualCellValueNode\n  ): EvaluationOrder {\n    if (node.resolved && this.cacheManager.getEvaluationOrder(node.key)) {\n      return this.cacheManager.getEvaluationOrder(node.key)!;\n    }\n\n    // Phase 1: Discover all transitive dependencies (skipping resolved nodes)\n    const allNodes = new Map<string, DependencyNode>();\n    const visitedForDiscovery = new Set<DependencyNode>();\n\n    const discoverNodes = (currentNode: DependencyNode) => {\n      if (currentNode && currentNode.resolved) {\n        return;\n      }\n\n      if (!allNodes.has(currentNode.key)) {\n        allNodes.set(currentNode.key, currentNode);\n      }\n\n      if (visitedForDiscovery.has(currentNode)) {\n        return;\n      }\n\n      visitedForDiscovery.add(currentNode);\n\n      const allDeps = currentNode.getAllDependencies();\n      for (const dep of allDeps) {\n        discoverNodes(dep);\n      }\n    };\n\n    discoverNodes(node);\n\n    if (allNodes.size === 0 && node && node.resolved) {\n      const result: EvaluationOrder = {\n        evaluationOrder: new Set([node]),\n        hasCycle: false,\n        hash: this.computeHash(new Set([node])),\n      };\n\n      if (node && node.resolved) {\n        this.cacheManager.setEvaluationOrder(node.key, result);\n      }\n\n      return result;\n    }\n\n    // Phase 2: Find SCCs using Tarjan's algorithm\n    // Build SCCs considering ALL dependencies (soft + hard edges)\n    const sccs = this.findSCCs(allNodes, true);\n\n    // Phase 3: Create condensation DAG and check for cached SCCs\n    const nodeToSCCId = new Map<DependencyNode, number>();\n    const sccList: import(\"../types.mjs\").SCC[] = [];\n\n    for (let i = 0; i < sccs.length; i++) {\n      const sccNodes = sccs[i]!;\n\n      // Check if all nodes in this SCC are resolved\n      const allResolved = Array.from(sccNodes).every((n) => n.resolved);\n\n      // Create SCC hash for caching\n      const sccHash = Array.from(sccNodes)\n        .map((n) => n.key)\n        .sort()\n        .join(\"|\");\n\n      // Try to get cached SCC if it's resolved\n      let scc: import(\"../types.mjs\").SCC;\n      const cachedSCC = allResolved\n        ? this.cacheManager.getSCC(sccHash)\n        : undefined;\n\n      if (cachedSCC) {\n        scc = cachedSCC;\n      } else {\n        // Build evaluation order for this SCC with cycle breaking\n        const sccEvalOrder = this.buildSCCEvaluationOrder(sccNodes);\n\n        // Find hard-edge SCCs within this soft-edge SCC\n        // Hard-edge SCCs are formed by only regular dependencies\n        const hardEdgeSCCs = this.findSCCs(\n          new Map(Array.from(sccNodes).map((n) => [n.key, n])),\n          false // Use only hard edges (regular dependencies)\n        );\n\n        scc = {\n          id: i,\n          nodes: sccNodes,\n          evaluationOrder: sccEvalOrder,\n          resolved: allResolved,\n          hardEdgeSCCs,\n        };\n\n        // Cache if resolved\n        if (allResolved) {\n          this.cacheManager.setSCC(sccHash, scc);\n        }\n      }\n\n      sccList.push(scc);\n\n      for (const n of sccNodes) {\n        nodeToSCCId.set(n, i);\n      }\n    }\n\n    // Build SCC dependency graph\n    // Edge from A to B means A depends on B, so B must be evaluated before A\n    const sccGraph = new Map<number, Set<number>>();\n    for (let i = 0; i < sccList.length; i++) {\n      sccGraph.set(i, new Set());\n    }\n\n    for (const [_, n] of allNodes) {\n      const nSCCId = nodeToSCCId.get(n)!;\n      // Use ALL dependencies (regular + frontier) for the condensation DAG\n      // This ensures proper evaluation order even with frontier dependencies\n      const deps = n.getAllDependencies();\n\n      for (const dep of deps) {\n        if (!allNodes.has(dep.key)) continue;\n\n        const depSCCId = nodeToSCCId.get(dep)!;\n        // n depends on dep, so dep's SCC must come before n's SCC\n        // Add edge from dep's SCC to n's SCC\n        if (nSCCId !== depSCCId) {\n          sccGraph.get(depSCCId)!.add(nSCCId);\n        }\n      }\n    }\n\n    // Phase 4: Topologically sort SCCs using Kahn's algorithm\n    const inDegree = new Map<number, number>();\n    for (let i = 0; i < sccList.length; i++) {\n      inDegree.set(i, 0);\n    }\n\n    for (const [_, deps] of sccGraph) {\n      for (const toId of deps) {\n        inDegree.set(toId, inDegree.get(toId)! + 1);\n      }\n    }\n\n    const queue: number[] = [];\n    for (let i = 0; i < sccList.length; i++) {\n      if (inDegree.get(i) === 0) {\n        queue.push(i);\n      }\n    }\n\n    const sortedSCCIds: number[] = [];\n    while (queue.length > 0) {\n      const sccId = queue.shift()!;\n      sortedSCCIds.push(sccId);\n\n      const deps = sccGraph.get(sccId)!;\n      for (const depId of deps) {\n        const newInDegree = inDegree.get(depId)! - 1;\n        inDegree.set(depId, newInDegree);\n        if (newInDegree === 0) {\n          queue.push(depId);\n        }\n      }\n    }\n\n    // Phase 5: Join evaluation orders from sorted SCCs\n    const evaluationOrderArray: DependencyNode[] = [];\n    for (const sccId of sortedSCCIds) {\n      const scc = sccList[sccId]!;\n      evaluationOrderArray.push(...scc.evaluationOrder);\n    }\n\n    const evaluationOrder = new Set(evaluationOrderArray);\n\n    // Identify cycle nodes from hard-edge SCCs\n    const cycleNodes = new Set<DependencyNode>();\n    for (const scc of sccList) {\n      for (const hardEdgeSCC of scc.hardEdgeSCCs) {\n        // A hard-edge SCC with multiple nodes or a self-loop indicates a real cycle\n        if (hardEdgeSCC.size > 1) {\n          for (const n of hardEdgeSCC) {\n            cycleNodes.add(n);\n          }\n        } else if (hardEdgeSCC.size === 1) {\n          const node = Array.from(hardEdgeSCC)[0]!;\n          if (node.getDependencies().has(node)) {\n            cycleNodes.add(node);\n          }\n        }\n      }\n    }\n\n    const hasCycle = cycleNodes.size > 0;\n    const result: EvaluationOrder = {\n      evaluationOrder,\n      hasCycle,\n      ...(hasCycle && { cycleNodes }),\n      hash: this.computeGraphHash(allNodes, sccList),\n      sccDAG: {\n        sccList,\n        sccGraph,\n      },\n    };\n\n    if (node && node.resolved) {\n      this.cacheManager.setEvaluationOrder(node.key, result);\n    }\n\n    return result;\n  }\n\n  /**\n   * Find strongly connected components using Tarjan's algorithm\n   * @param nodes - Map of nodes to analyze\n   * @param includeFrontier - If true, use getAllDependencies(); if false, use getDependencies()\n   * @returns Array of SCCs (each SCC is a Set of nodes)\n   */\n  private findSCCs(\n    nodes: Map<string, DependencyNode>,\n    includeFrontier: boolean\n  ): Set<DependencyNode>[] {\n    const index = new Map<DependencyNode, number>();\n    const lowlink = new Map<DependencyNode, number>();\n    const onStack = new Set<DependencyNode>();\n    const stack: DependencyNode[] = [];\n    const sccs: Set<DependencyNode>[] = [];\n    let currentIndex = 0;\n\n    const strongConnect = (v: DependencyNode) => {\n      index.set(v, currentIndex);\n      lowlink.set(v, currentIndex);\n      currentIndex++;\n      stack.push(v);\n      onStack.add(v);\n\n      // Use either all dependencies or just regular dependencies\n      const successors = includeFrontier\n        ? v.getAllDependencies()\n        : v.getDependencies();\n\n      for (const w of successors) {\n        if (!nodes.has(w.key)) {\n          continue;\n        }\n\n        if (!index.has(w)) {\n          strongConnect(w);\n          lowlink.set(v, Math.min(lowlink.get(v)!, lowlink.get(w)!));\n        } else if (onStack.has(w)) {\n          lowlink.set(v, Math.min(lowlink.get(v)!, index.get(w)!));\n        }\n      }\n\n      if (lowlink.get(v) === index.get(v)) {\n        const scc = new Set<DependencyNode>();\n        let w: DependencyNode;\n        do {\n          w = stack.pop()!;\n          onStack.delete(w);\n          scc.add(w);\n        } while (w !== v);\n\n        sccs.push(scc);\n      }\n    };\n\n    for (const [_, n] of nodes) {\n      if (!index.has(n)) {\n        strongConnect(n);\n      }\n    }\n\n    return sccs;\n  }\n\n  /**\n   * Build evaluation order within a single SCC using DFS with cycle breaking\n   * Uses all dependencies (including frontier) for proper evaluation ordering\n   */\n  private buildSCCEvaluationOrder(\n    sccNodes: Set<DependencyNode>\n  ): DependencyNode[] {\n    const visited = new Set<DependencyNode>();\n    const visiting = new Set<DependencyNode>();\n    const result: DependencyNode[] = [];\n\n    const dfs = (n: DependencyNode) => {\n      if (visited.has(n)) {\n        return;\n      }\n\n      if (visiting.has(n)) {\n        // Cycle detected (from any edge type), break it\n        return;\n      }\n\n      visiting.add(n);\n\n      // Use all dependencies for evaluation ordering (regular + frontier)\n      const deps = n.getAllDependencies();\n      for (const dep of deps) {\n        if (sccNodes.has(dep) && !visited.has(dep)) {\n          dfs(dep);\n        }\n      }\n\n      visiting.delete(n);\n      visited.add(n);\n      result.push(n);\n    };\n\n    // Sort nodes by key for deterministic ordering\n    const sortedNodes = Array.from(sccNodes).sort((a, b) =>\n      a.key.localeCompare(b.key)\n    );\n\n    for (const n of sortedNodes) {\n      if (!visited.has(n)) {\n        dfs(n);\n      }\n    }\n\n    return result;\n  }\n\n  /**\n   * Compute hash representing the graph structure including SCC information\n   */\n  private computeGraphHash(\n    allNodes: Map<string, DependencyNode>,\n    sccList: import(\"../types.mjs\").SCC[]\n  ): string {\n    const parts: string[] = [];\n\n    // Hash nodes and their dependencies\n    for (const [key, node] of Array.from(allNodes.entries()).sort()) {\n      const deps = Array.from(node.getAllDependencies())\n        .map((d) => d.key)\n        .sort()\n        .join(\",\");\n      parts.push(`${key}:[${deps}]`);\n    }\n\n    // Add SCC structure\n    for (const scc of sccList) {\n      const nodeKeys = Array.from(scc.nodes)\n        .map((n) => n.key)\n        .sort()\n        .join(\",\");\n      parts.push(`SCC${scc.id}:{${nodeKeys}}`);\n    }\n\n    return parts.join(\"|\");\n  }\n\n  /**\n   * Compute a hash representing the current state of evaluated nodes\n   * This hash changes when dependencies, frontier dependencies, or discarded frontier dependencies change\n   */\n  private computeHash(allNodes: Set<DependencyNode>): string {\n    const nodeStates: string[] = [];\n\n    for (const node of Array.from(allNodes).sort()) {\n      if (node) {\n        const deps = Array.from(node.getDependencies() || [])\n          .map((dep) => dep.key)\n          .sort()\n          .join(\",\");\n\n        // Handle frontier dependencies (Map<string, Set<string>>)\n        const frontierDeps: string = Array.from(node.getFrontierDependencies())\n          .map((dep) => dep.key)\n          .sort()\n          .join(\";\");\n\n        const nodeState = `${node.key}:{deps:[${deps}],frontier:[${frontierDeps}]}`;\n        nodeStates.push(nodeState);\n      }\n    }\n\n    return nodeStates.join(\"|\");\n  }\n\n  /**\n   * Get a hierarchical dependency tree for a node\n   */\n  getDependencyTree(node: DependencyNode): DependencyTreeNode {\n    const visited = new Set<DependencyNode>();\n\n    const nodeToType = (node: DependencyNode): \"cell\" | \"range\" | \"empty\" => {\n      if (node instanceof RangeEvaluationNode) {\n        return \"range\";\n      }\n      if (node instanceof EmptyCellEvaluationNode) {\n        return \"empty\";\n      }\n      return \"cell\";\n    };\n\n    const buildTree = (\n      node: DependencyNode,\n      isSelf = false\n    ): DependencyTreeNode => {\n      const cellRef: string = node.toString();\n\n      // Handle self-reference to avoid infinite recursion\n      if (isSelf) {\n        return {\n          type: nodeToType(node),\n          resultType:\n            node instanceof RangeEvaluationNode\n              ? \"range\"\n              : node.evaluationResult\n              ? node.evaluationResult.type\n              : \"awaiting-evaluation\",\n          canResolve: node.canResolve(),\n          key: cellRef,\n          directDepsUpdated: node.directDepsUpdated,\n          resolved: node.resolved,\n          self: true,\n          circular: true,\n        };\n      }\n\n      // Avoid infinite recursion for circular dependencies\n      if (visited.has(node)) {\n        return {\n          type: nodeToType(node),\n          resultType:\n            node instanceof RangeEvaluationNode\n              ? \"range\"\n              : node.evaluationResult\n              ? node.evaluationResult.type\n              : \"awaiting-evaluation\",\n          canResolve: node.canResolve(),\n          key: cellRef,\n          directDepsUpdated: node.directDepsUpdated,\n          resolved: node.resolved,\n          circular: true,\n        };\n      }\n\n      visited.add(node);\n\n      const directDeps = Array.from(node.getDependencies());\n      let frontierDeps = Array.from(node.getFrontierDependencies());\n\n      // Get regular dependencies\n      const deps: DependencyTreeNode[] = directDeps.map((dep) =>\n        buildTree(dep, dep.key === node.key)\n      );\n\n      const frontierDependencies: DependencyTreeNode[] = frontierDeps.map(\n        (dep) => buildTree(dep, false)\n      );\n\n      visited.delete(node);\n\n      const result: DependencyTreeNode = {\n        type: nodeToType(node),\n        resultType:\n          node instanceof RangeEvaluationNode\n            ? \"range\"\n            : node.evaluationResult\n            ? node.evaluationResult.type\n            : \"awaiting-evaluation\",\n        canResolve: node.canResolve(),\n        key: cellRef,\n        directDepsUpdated: node.directDepsUpdated,\n        resolved: node.resolved,\n      };\n\n      // Only include deps and frontierDependencies if they have content\n      if (deps.length > 0) {\n        result.deps = deps;\n      }\n      if (frontierDependencies.length > 0) {\n        result.frontierDependencies = frontierDependencies;\n      }\n\n      return result;\n    };\n\n    return buildTree(node);\n  }\n  //#endregion\n\n  markResolvedNodes(node: DependencyNode): void {\n    // Track visited nodes to avoid infinite loops in circular dependencies\n    const visited = new Set<DependencyNode>();\n    visited.add(node); // Don't revisit the current cell\n\n    const areTransitiveDepsResolved = (nodes: Set<DependencyNode>): boolean => {\n      let canResolve = true;\n      for (const node of nodes) {\n        if (visited.has(node) || node.resolved) {\n          continue;\n        }\n        visited.add(node);\n\n        // Check the node's dependencies to not cause cycles with frontier dependencies\n        const directDeps = node.getDependencies();\n\n        const a = areTransitiveDepsResolved(directDeps);\n        const b = node.canResolve();\n\n        if (!a || !b) {\n          canResolve = false;\n        }\n        if (a && b) {\n          node.resolve();\n          // if an ast node is resolved, it will get removed from the dependency graph\n          // and thus never reach evaluateNode in formula evaluator\n          // so we need to save it here. The latest context dependency is the correct one.\n          if (node instanceof AstEvaluationNode) {\n            this.saveAstNode(node, node.getContextDependency());\n          }\n        }\n      }\n      return canResolve;\n    };\n\n    if (\n      areTransitiveDepsResolved(node.getDependencies()) &&\n      node.canResolve()\n    ) {\n      node.resolve();\n      if (node instanceof AstEvaluationNode) {\n        this.saveAstNode(node, node.getContextDependency());\n      }\n    }\n  }\n\n  /**\n   * Update SCCs in cache to mark them as resolved if all their nodes are resolved\n   */\n  public updateResolvedSCCs(evalOrder: EvaluationOrder): void {\n    if (!evalOrder.sccDAG) {\n      return;\n    }\n\n    // Check each SCC and update cache if all nodes are resolved\n    for (const scc of evalOrder.sccDAG.sccList) {\n      const allResolved = Array.from(scc.nodes).every((n) => n.resolved);\n\n      if (allResolved && !scc.resolved) {\n        // Create updated SCC with resolved flag\n        const updatedSCC: import(\"../types.mjs\").SCC = {\n          ...scc,\n          resolved: true,\n        };\n\n        // Update cache\n        const sccHash = Array.from(scc.nodes)\n          .map((n) => n.key)\n          .sort()\n          .join(\"|\");\n\n        this.cacheManager.setSCC(sccHash, updatedSCC);\n      }\n    }\n  }\n\n}\n"
  ],
  "mappings": "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",
  "debugId": "3C6CF47C62ED503A64756E2164756E21",
  "names": []
}