{
  "version": 3,
  "sources": ["../../../src/evaluator/evaluation-context.ts"],
  "sourcesContent": [
    "import type { DependencyNode } from \"../core/managers/dependency-node.cjs\";\nimport type { TableManager } from \"../core/managers/table-manager.cjs\";\nimport type { CellAddress } from \"../core/types.cjs\";\n\nexport const NO_TABLE_CONTEXT_NAME = \"__no_current_table__\";\n\nexport class EvaluationContext {\n  private _cellAddress: CellAddress;\n  private _tableName: string | undefined;\n  private _cacheTableName: string;\n  /**\n   * Can be a range or a cell\n   */\n  private _dependencyNode: DependencyNode;\n  constructor(\n    tableManager: TableManager,\n    dependencyNode: DependencyNode,\n    cellAddress: CellAddress\n  ) {\n    this._dependencyNode = dependencyNode;\n    this._cellAddress = cellAddress;\n    const table = tableManager.isCellInTable(cellAddress);\n    this._tableName = table?.name;\n    this._cacheTableName = table?.name ?? NO_TABLE_CONTEXT_NAME;\n  }\n\n  get dependencyNode() {\n    return this._dependencyNode;\n  }\n\n  private _contextDependency: ContextDependency = {};\n\n  getContextDependency() {\n    return this._contextDependency;\n  }\n\n  /**\n   * The cell context, the address of the cell being evaluated\n   * and the context in which results should be stored\n   */\n  get cellAddress() {\n    return this._cellAddress;\n  }\n\n  get tableName() {\n    return this._tableName;\n  }\n\n  get cacheTableName() {\n    return this._cacheTableName;\n  }\n\n  addContextDependency(...types: ContextDependencyType[]) {\n    for (const type of types) {\n      switch (type) {\n        case \"row\":\n          this._contextDependency.rowIndex = this._cellAddress.rowIndex;\n          break;\n        case \"col\":\n          this._contextDependency.colIndex = this._cellAddress.colIndex;\n          break;\n        case \"workbook\":\n          this._contextDependency.workbookName = this._cellAddress.workbookName;\n          break;\n        case \"sheet\":\n          this._contextDependency.sheetName = this._cellAddress.sheetName;\n          break;\n        case \"table\":\n          this._contextDependency.tableName = this.cacheTableName;\n          break;\n        default:\n          throw new Error(`Invalid context dependency type: ${type}`);\n      }\n    }\n  }\n\n  /**\n   * When evaluating an AST node,\n   * we need to append the subtree context\n   * dependencies to the current context dependency\n   */\n  appendContextDependency(contextDependency: ContextDependency) {\n    this._contextDependency = {\n      ...this._contextDependency,\n      ...Object.fromEntries(\n        Object.entries(contextDependency).filter(\n          ([key, value]) => value !== undefined\n        )\n      ),\n    };\n  }\n}\n\n/**\n * Each value has the same value as the origin cell\n * the defined keys are the ones the ast node is dependent on\n * e.g. A3=ROW() will have a context dependency of { rowIndex: 3 }\n *\n * The keys are ANDed together, e.g. { workbookName: \"Sheet1\", sheetName: \"Sheet2\" }\n * means the ast node is dependent on the workbook \"Sheet1\" and the sheet \"Sheet2\"\n */\nexport type ContextDependency = {\n  workbookName?: string;\n  sheetName?: string;\n  tableName?: string;\n  rowIndex?: number;\n  colIndex?: number;\n};\n\nexport const contextDependencyKeys = [\n  \"workbookName\",\n  \"sheetName\",\n  \"tableName\",\n  \"rowIndex\",\n  \"colIndex\",\n] as const;\n\n/**\n * These are some distinct scenarios where context dependencies are added\n */\nexport type ContextDependencyType =\n  | \"row\"\n  | \"col\"\n  | \"workbook\"\n  | \"sheet\"\n  | \"table\";\n\n// *  [astKey], // `=1+1`\n// *  [astKey, sheetKey, workbookKey], // `B3`\n// *  [astKey, workbookKey], // `Table1[Column1]`\n// *  [astKey, workbookKey], // `Sheet1!B3`\n// *  [astKey, cellAddress.rowIndex], // `ROW()`\n// *  [astKey, cellAddress.colIndex], // `COL()`\n// *  [astKey, cellAddress.rowIndex, cellAddress.colIndex] // `CELL(\"address\")`\n// *  [astKey, tableKey, cellAddress.rowIndex], // `@Column1`\n// *  [astKey, workbookKey, cellAddress.rowIndex], // `Table1[@Column1]`\n\ntype Dim = \"workbookName\" | \"sheetName\" | \"tableName\" | \"rowIndex\" | \"colIndex\";\nconst DIM_ORDER: readonly Dim[] = [\n  \"workbookName\",\n  \"sheetName\",\n  \"tableName\",\n  \"rowIndex\",\n  \"colIndex\",\n] as const;\n\n/** Build the canonical cache key string for a dependency. */\nexport function keyFromDependency(dep: ContextDependency): string {\n  return DIM_ORDER.map((k) =>\n    dep[k] !== undefined ? `${k}:[${(dep as any)[k]}]` : `${k}:*`\n  ).join(\",\");\n}\n\ntype Context = {\n  workbookName: string;\n  sheetName: string;\n  tableName?: string;\n  rowIndex: number;\n  colIndex: number;\n};\n\n/** True if `dep` matches `ctx` (i.e., every specified field equals the context’s field). */\nexport function dependencyMatchesContext(\n  ctx: Context,\n  dep: ContextDependency\n): boolean {\n  return DIM_ORDER.every(\n    (k) => dep[k] === undefined || (dep as any)[k] === (ctx as any)[k]\n  );\n}\n\nconst contextCacheKey = new Map<string, string[]>();\n\n/**\n * Generate every cache key that would be eligible for `ctx`.\n * By default returns keys ordered from most-specific to least-specific.\n */\nexport function eligibleKeysForContext(ctx: Context): string[] {\n  const mostRestrictiveKey = keyFromDependency(ctx);\n  const cachedKeys = contextCacheKey.get(mostRestrictiveKey);\n  if (cachedKeys) {\n    return cachedKeys;\n  }\n\n  const results: Array<{ key: string; specificity: number; mask: number }> = [];\n  const n = DIM_ORDER.length;\n\n  // If tableName is undefined in the context, the lookup is not modeling table\n  // membership at all, so we cannot generate keys that specify it.\n  const tableIdx = DIM_ORDER.indexOf(\"tableName\");\n\n  const totalMasks = 1 << n; // 2^n\n  for (let mask = 0; mask < totalMasks; mask++) {\n    // Skip combos that specify tableName when ctx.tableName is undefined.\n    if (ctx.tableName === undefined && ((mask >> tableIdx) & 1) === 1) continue;\n\n    const dep: ContextDependency = {};\n    let specificity = 0;\n    for (let i = 0; i < n; i++) {\n      if (((mask >> i) & 1) === 1) {\n        const k = DIM_ORDER[i];\n        const v = (ctx as any)[k!];\n        // Only assign when the dimension participates in the context.\n        if (v !== undefined) {\n          (dep as any)[k!] = v;\n          specificity++;\n        }\n      }\n    }\n    results.push({\n      key: keyFromDependency(dep),\n      specificity,\n      mask,\n    });\n  }\n\n  results.sort(\n    (left, right) =>\n      right.specificity - left.specificity || right.mask - left.mask\n  );\n\n  const orderedKeys = results.map((result) => result.key);\n\n  contextCacheKey.set(mostRestrictiveKey, orderedKeys);\n\n  return orderedKeys;\n}\n\nexport function getContextDependencyKey(contextDependency: ContextDependency) {\n  const keys: (string | number)[] = [];\n  contextDependencyKeys.forEach((key) => {\n    if (contextDependency[key] !== undefined) {\n      keys.push(`${key}:[${contextDependency[key]}]`);\n    } else {\n      keys.push(`${key}:*`);\n    }\n  });\n  return keys.join(\",\");\n}\n"
  ],
  "mappings": "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",
  "debugId": "5F0D924C23ED7CD864756E2164756E21",
  "names": []
}