@ricsam/formula-engine 0.0.17 → 0.0.19
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.
- package/dist/cjs/core/api/api-builder.cjs +67 -0
- package/dist/cjs/core/api/api-builder.cjs.map +10 -0
- package/dist/cjs/core/api/api-helpers.cjs +191 -0
- package/dist/cjs/core/api/api-helpers.cjs.map +10 -0
- package/dist/cjs/core/api/api.cjs +65 -0
- package/dist/cjs/core/api/api.cjs.map +10 -0
- package/dist/cjs/core/api/cell-orm.cjs +80 -0
- package/dist/cjs/core/api/cell-orm.cjs.map +10 -0
- package/dist/cjs/core/api/table-orm.cjs +171 -0
- package/dist/cjs/core/api/table-orm.cjs.map +10 -0
- package/dist/cjs/core/autofill-utils.cjs +3 -5
- package/dist/cjs/core/autofill-utils.cjs.map +3 -3
- package/dist/cjs/core/commands/command-executor.cjs +140 -0
- package/dist/cjs/core/commands/command-executor.cjs.map +10 -0
- package/dist/cjs/core/commands/content-commands.cjs +574 -0
- package/dist/cjs/core/commands/content-commands.cjs.map +10 -0
- package/dist/cjs/core/commands/metadata-commands.cjs +150 -0
- package/dist/cjs/core/commands/metadata-commands.cjs.map +10 -0
- package/dist/cjs/core/commands/named-expression-commands.cjs +238 -0
- package/dist/cjs/core/commands/named-expression-commands.cjs.map +10 -0
- package/dist/cjs/core/commands/structure-commands.cjs +495 -0
- package/dist/cjs/core/commands/structure-commands.cjs.map +10 -0
- package/dist/cjs/core/commands/style-commands.cjs +219 -0
- package/dist/cjs/core/commands/style-commands.cjs.map +10 -0
- package/dist/cjs/core/commands/table-commands.cjs +226 -0
- package/dist/cjs/core/commands/table-commands.cjs.map +10 -0
- package/dist/cjs/core/commands/types.cjs +72 -0
- package/dist/cjs/core/commands/types.cjs.map +10 -0
- package/dist/cjs/core/engine.cjs +170 -297
- package/dist/cjs/core/engine.cjs.map +3 -3
- package/dist/cjs/core/managers/api-schema-manager.cjs +304 -0
- package/dist/cjs/core/managers/api-schema-manager.cjs.map +10 -0
- package/dist/cjs/core/managers/copy-manager.cjs +1 -2
- package/dist/cjs/core/managers/copy-manager.cjs.map +3 -3
- package/dist/cjs/core/types.cjs.map +2 -2
- package/dist/cjs/lib.cjs +13 -2
- package/dist/cjs/lib.cjs.map +3 -3
- package/dist/cjs/package.json +1 -1
- package/dist/mjs/core/api/api-builder.mjs +37 -0
- package/dist/mjs/core/api/api-builder.mjs.map +10 -0
- package/dist/mjs/core/api/api-helpers.mjs +161 -0
- package/dist/mjs/core/api/api-helpers.mjs.map +10 -0
- package/dist/mjs/core/api/api.mjs +35 -0
- package/dist/mjs/core/api/api.mjs.map +10 -0
- package/dist/mjs/core/api/cell-orm.mjs +49 -0
- package/dist/mjs/core/api/cell-orm.mjs.map +10 -0
- package/dist/mjs/core/api/table-orm.mjs +148 -0
- package/dist/mjs/core/api/table-orm.mjs.map +10 -0
- package/dist/mjs/core/autofill-utils.mjs +3 -5
- package/dist/mjs/core/autofill-utils.mjs.map +3 -3
- package/dist/mjs/core/commands/command-executor.mjs +109 -0
- package/dist/mjs/core/commands/command-executor.mjs.map +10 -0
- package/dist/mjs/core/commands/content-commands.mjs +544 -0
- package/dist/mjs/core/commands/content-commands.mjs.map +10 -0
- package/dist/mjs/core/commands/metadata-commands.mjs +120 -0
- package/dist/mjs/core/commands/metadata-commands.mjs.map +10 -0
- package/dist/mjs/core/commands/named-expression-commands.mjs +208 -0
- package/dist/mjs/core/commands/named-expression-commands.mjs.map +10 -0
- package/dist/mjs/core/commands/structure-commands.mjs +465 -0
- package/dist/mjs/core/commands/structure-commands.mjs.map +10 -0
- package/dist/mjs/core/commands/style-commands.mjs +189 -0
- package/dist/mjs/core/commands/style-commands.mjs.map +10 -0
- package/dist/mjs/core/commands/table-commands.mjs +196 -0
- package/dist/mjs/core/commands/table-commands.mjs.map +10 -0
- package/dist/mjs/core/commands/types.mjs +42 -0
- package/dist/mjs/core/commands/types.mjs.map +10 -0
- package/dist/mjs/core/engine.mjs +213 -297
- package/dist/mjs/core/engine.mjs.map +3 -3
- package/dist/mjs/core/managers/api-schema-manager.mjs +274 -0
- package/dist/mjs/core/managers/api-schema-manager.mjs.map +10 -0
- package/dist/mjs/core/managers/copy-manager.mjs +1 -2
- package/dist/mjs/core/managers/copy-manager.mjs.map +3 -3
- package/dist/mjs/core/types.mjs.map +2 -2
- package/dist/mjs/lib.mjs +13 -2
- package/dist/mjs/lib.mjs.map +3 -3
- package/dist/mjs/package.json +1 -1
- package/dist/types/core/api/api-builder.d.ts +16 -0
- package/dist/types/core/api/api-helpers.d.ts +37 -0
- package/dist/types/core/api/api.d.ts +83 -0
- package/dist/types/core/api/api.type-test.d.ts +1 -0
- package/dist/types/core/api/cell-orm.d.ts +29 -0
- package/dist/types/core/api/table-orm.d.ts +46 -0
- package/dist/types/core/autofill-utils.d.ts +2 -9
- package/dist/types/core/commands/command-executor.d.ts +83 -0
- package/dist/types/core/commands/content-commands.d.ts +142 -0
- package/dist/types/core/commands/metadata-commands.d.ts +55 -0
- package/dist/types/core/commands/named-expression-commands.d.ts +115 -0
- package/dist/types/core/commands/structure-commands.d.ts +132 -0
- package/dist/types/core/commands/style-commands.d.ts +76 -0
- package/dist/types/core/commands/table-commands.d.ts +104 -0
- package/dist/types/core/commands/types.d.ts +114 -0
- package/dist/types/core/engine.d.ts +130 -26
- package/dist/types/core/managers/api-schema-manager.d.ts +121 -0
- package/dist/types/core/types.d.ts +1 -1
- package/dist/types/lib.d.ts +8 -0
- package/package.json +1 -1
|
@@ -119,7 +119,6 @@ class CopyManager {
|
|
|
119
119
|
rowIndex: targetCell.rowIndex
|
|
120
120
|
});
|
|
121
121
|
}
|
|
122
|
-
console.log("targetContent", targetContent);
|
|
123
122
|
this.workbookManager.setCellContent(targetCell, targetContent);
|
|
124
123
|
}
|
|
125
124
|
if (this.shouldInclude(options, "metadata")) {
|
|
@@ -818,4 +817,4 @@ class CopyManager {
|
|
|
818
817
|
}
|
|
819
818
|
}
|
|
820
819
|
|
|
821
|
-
//# debugId=
|
|
820
|
+
//# debugId=566F5D8EB2A3D66C64756E2164756E21
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/core/managers/copy-manager.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"/**\n * CopyManager - Manages cell copy/paste operations\n */\n\nimport type {\n CellAddress,\n CopyCellsOptions,\n ConditionalStyle,\n DirectCellStyle,\n LocalCellAddress,\n RangeAddress,\n SerializedCellValue,\n SpreadsheetRange,\n} from \"../types.cjs\";\nimport type { WorkbookManager } from \"./workbook-manager.cjs\";\nimport type { EvaluationManager } from \"./evaluation-manager.cjs\";\nimport type { StyleManager } from \"./style-manager.cjs\";\nimport { parseFormula } from \"../../parser/parser.cjs\";\nimport { astToString } from \"../../parser/formatter.cjs\";\nimport { transformAST } from \"../ast-traverser.cjs\";\nimport type { ReferenceNode, RangeNode } from \"../../parser/ast.cjs\";\nimport { getCellReference, isCellInRange } from \"../utils.cjs\";\nimport { intersectRanges } from \"../utils/range-utils.cjs\";\nimport {\n updateReferencesForMovedCells,\n type MovedCellsInfo,\n} from \"../cell-mover.cjs\";\n\n/**\n * Snapshot of a cell's content, metadata, and styles\n */\ninterface CellSnapshot {\n address: CellAddress;\n content: SerializedCellValue | undefined;\n metadata: unknown | undefined;\n matchingCellStyles?: DirectCellStyle[];\n matchingConditionalStyles?: ConditionalStyle[];\n}\n\nexport class CopyManager {\n constructor(\n private workbookManager: WorkbookManager,\n private evaluationManager: EvaluationManager,\n private styleManager: StyleManager\n ) {}\n\n /**\n * Normalize the include option to an array of parts to copy\n */\n private normalizeInclude(\n include: CopyCellsOptions[\"include\"]\n ): (\"content\" | \"style\" | \"metadata\")[] {\n if (!include || include === \"all\") {\n return [\"content\", \"style\", \"metadata\"];\n }\n return include;\n }\n\n /**\n * Check if a specific part should be included in the copy operation\n */\n private shouldInclude(\n options: CopyCellsOptions,\n part: \"content\" | \"style\" | \"metadata\"\n ): boolean {\n const normalized = this.normalizeInclude(options.include);\n return normalized.includes(part);\n }\n\n /**\n * Paste cells from source to target\n * Delegates to cutCells for move operations or copyOnlyCells for copy operations\n */\n pasteCells(\n source: CellAddress[],\n target: CellAddress,\n options: CopyCellsOptions\n ): void {\n if (source.length === 0) {\n return;\n }\n\n if (options.cut === true) {\n return this.cutCells(source, target, options);\n } else {\n return this.copyOnlyCells(source, target, options);\n }\n }\n\n /**\n * Cut cells: Proper snapshot flow for move operations\n * 1. Snapshot source cells (with styles)\n * 2. Remove source cells and punch holes in style areas\n * 3. Update references in OTHER cells (not in moved set)\n * 4. Update formulas in snapshot and apply to target\n */\n private cutCells(\n source: CellAddress[],\n target: CellAddress,\n options: CopyCellsOptions\n ): void {\n const topLeft = this.findTopLeft(source);\n const rowOffset = target.rowIndex - topLeft.rowIndex;\n const colOffset = target.colIndex - topLeft.colIndex;\n\n // 1. Snapshot source cells (with styles)\n const snapshot = this.snapshotCellsWithStyles(source);\n\n // 2. Remove source cells (content) and punch holes in styles\n this.clearSourceCells(source);\n\n // Punch holes in style areas for each cut cell\n if (this.shouldInclude(options, \"style\")) {\n for (const cell of source) {\n const cellRange: RangeAddress = {\n workbookName: cell.workbookName,\n sheetName: cell.sheetName,\n range: {\n start: { col: cell.colIndex, row: cell.rowIndex },\n end: {\n col: { type: \"number\", value: cell.colIndex },\n row: { type: \"number\", value: cell.rowIndex },\n },\n },\n };\n this.styleManager.clearCellStylesInRange(cellRange);\n }\n }\n\n // 3. Update references in OTHER cells (not in moved set)\n const movedCellsSet = new Set(\n source.map(\n (c) => `${c.workbookName}:${c.sheetName}:${c.colIndex}:${c.rowIndex}`\n )\n );\n\n const movedCellsInfo: MovedCellsInfo = {\n cellsSet: movedCellsSet,\n workbookName: topLeft.workbookName,\n sheetName: topLeft.sheetName,\n rowOffset,\n colOffset,\n };\n\n this.workbookManager.updateFormulasExcluding(movedCellsSet, (formula) =>\n updateReferencesForMovedCells(formula, movedCellsInfo)\n );\n\n // 4. Update formulas in snapshot and apply to target\n for (let i = 0; i < snapshot.length; i++) {\n const snap = snapshot[i]!;\n const sourceCell = source[i]!;\n const targetCell: CellAddress = {\n workbookName: target.workbookName,\n sheetName: target.sheetName,\n colIndex: sourceCell.colIndex + colOffset,\n rowIndex: sourceCell.rowIndex + rowOffset,\n };\n\n // Apply content (with formula adjustment)\n if (this.shouldInclude(options, \"content\") && snap.content) {\n let targetContent = snap.content;\n\n if (typeof snap.content === \"string\" && snap.content.startsWith(\"=\")) {\n // Adjust formula references relative to new position\n targetContent = this.adjustFormulaReferences(\n snap.content,\n {\n colIndex: snap.address.colIndex,\n rowIndex: snap.address.rowIndex,\n },\n {\n colIndex: targetCell.colIndex,\n rowIndex: targetCell.rowIndex,\n }\n );\n }\n\n console.log(\"targetContent\", targetContent);\n\n // Use setCellContent to ensure proper cache invalidation and dependency tracking\n this.workbookManager.setCellContent(targetCell, targetContent);\n }\n\n // Apply metadata\n if (this.shouldInclude(options, \"metadata\")) {\n if (snap.metadata) {\n this.workbookManager.setCellMetadata(targetCell, {\n ...snap.metadata,\n });\n } else {\n this.workbookManager.setCellMetadata(targetCell, undefined);\n }\n }\n\n // Apply styles from snapshot to new location\n if (this.shouldInclude(options, \"style\")) {\n this.applyStylesFromSnapshot(snap, targetCell);\n }\n }\n }\n\n /**\n * Copy cells: Standard copy operation (not cut/move)\n * Snapshot → Copy with adjustment → Copy formatting\n */\n private copyOnlyCells(\n source: CellAddress[],\n target: CellAddress,\n options: CopyCellsOptions\n ): void {\n const topLeft = this.findTopLeft(source);\n const rowOffset = target.rowIndex - topLeft.rowIndex;\n const colOffset = target.colIndex - topLeft.colIndex;\n\n // SNAPSHOT source cells (handles overlapping ranges)\n const snapshot = this.snapshotCells(source);\n\n // Copy cell contents if requested (from snapshot, not live cells)\n if (this.shouldInclude(options, \"content\")) {\n for (let i = 0; i < source.length; i++) {\n const sourceCell = source[i]!;\n const cellSnapshot = snapshot[i]!;\n const targetCell: CellAddress = {\n workbookName: target.workbookName,\n sheetName: target.sheetName,\n colIndex: sourceCell.colIndex + colOffset,\n rowIndex: sourceCell.rowIndex + rowOffset,\n };\n\n this.copyCellContentFromSnapshot(\n cellSnapshot,\n targetCell,\n topLeft,\n options\n );\n }\n }\n\n // Copy formatting if requested\n if (this.shouldInclude(options, \"style\")) {\n this.copyFormatting(source, topLeft, target, rowOffset, colOffset);\n }\n }\n\n /**\n * Find the top-left cell (minimum row/col indices)\n */\n private findTopLeft(cells: CellAddress[]): CellAddress {\n let minRow = Infinity;\n let minCol = Infinity;\n let topLeftCell = cells[0]!;\n\n for (const cell of cells) {\n if (\n cell.rowIndex < minRow ||\n (cell.rowIndex === minRow && cell.colIndex < minCol)\n ) {\n minRow = cell.rowIndex;\n minCol = cell.colIndex;\n topLeftCell = cell;\n }\n }\n\n return topLeftCell;\n }\n\n /**\n * Create a snapshot of cells' content and metadata\n * This prevents issues with overlapping ranges where source and target overlap\n * Used for copy operations (not cut)\n */\n private snapshotCells(cells: CellAddress[]): CellSnapshot[] {\n return cells.map((cell) => {\n const sheet = this.workbookManager.getSheet({\n workbookName: cell.workbookName,\n sheetName: cell.sheetName,\n });\n\n const key = `${String.fromCharCode(65 + cell.colIndex)}${\n cell.rowIndex + 1\n }`;\n const content = sheet?.content.get(key);\n const metadata = this.workbookManager.getCellMetadata(cell);\n\n return {\n address: cell,\n content,\n metadata,\n };\n });\n }\n\n /**\n * Create a snapshot of cells with content, metadata, AND styles\n * Used for cut operations to preserve all cell information\n */\n private snapshotCellsWithStyles(cells: CellAddress[]): CellSnapshot[] {\n const allCellStyles = this.styleManager.getAllCellStyles();\n const allConditionalStyles = this.styleManager.getAllConditionalStyles();\n\n return cells.map((cell) => {\n const sheet = this.workbookManager.getSheet({\n workbookName: cell.workbookName,\n sheetName: cell.sheetName,\n });\n\n const key = getCellReference(cell);\n const content = sheet?.content.get(key);\n const metadata = this.workbookManager.getCellMetadata(cell);\n\n // Find all styles that apply to this cell\n const matchingCellStyles = allCellStyles.filter((style) =>\n style.areas.some(\n (area) =>\n area.workbookName === cell.workbookName &&\n area.sheetName === cell.sheetName &&\n isCellInRange(cell, area.range)\n )\n );\n\n const matchingConditionalStyles = allConditionalStyles.filter((style) =>\n style.areas.some(\n (area) =>\n area.workbookName === cell.workbookName &&\n area.sheetName === cell.sheetName &&\n isCellInRange(cell, area.range)\n )\n );\n\n return {\n address: cell,\n content,\n metadata,\n matchingCellStyles,\n matchingConditionalStyles,\n };\n });\n }\n\n /**\n * Apply styles from a snapshot to a target cell\n * Creates new style areas at the target location\n */\n private applyStylesFromSnapshot(\n snapshot: CellSnapshot,\n targetCell: CellAddress\n ): void {\n // Apply cell styles\n if (snapshot.matchingCellStyles) {\n for (const style of snapshot.matchingCellStyles) {\n const newStyle: DirectCellStyle = {\n areas: [\n {\n workbookName: targetCell.workbookName,\n sheetName: targetCell.sheetName,\n range: {\n start: { col: targetCell.colIndex, row: targetCell.rowIndex },\n end: {\n col: { type: \"number\", value: targetCell.colIndex },\n row: { type: \"number\", value: targetCell.rowIndex },\n },\n },\n },\n ],\n style: style.style,\n };\n this.styleManager.addCellStyle(newStyle);\n }\n }\n\n // Apply conditional styles\n if (snapshot.matchingConditionalStyles) {\n for (const style of snapshot.matchingConditionalStyles) {\n const newStyle: ConditionalStyle = {\n areas: [\n {\n workbookName: targetCell.workbookName,\n sheetName: targetCell.sheetName,\n range: {\n start: { col: targetCell.colIndex, row: targetCell.rowIndex },\n end: {\n col: { type: \"number\", value: targetCell.colIndex },\n row: { type: \"number\", value: targetCell.rowIndex },\n },\n },\n },\n ],\n condition: style.condition,\n };\n this.styleManager.addConditionalStyle(newStyle);\n }\n }\n }\n\n /**\n * Copy content from a cell snapshot to a target cell\n */\n private copyCellContentFromSnapshot(\n snapshot: CellSnapshot,\n targetCell: CellAddress,\n sourceTopLeft: CellAddress,\n options: CopyCellsOptions\n ): void {\n if (!snapshot.content) {\n // Source cell was empty\n return;\n }\n\n let targetContent: SerializedCellValue;\n const copyType = options.type ?? \"formula\";\n\n if (copyType === \"value\") {\n // Copy evaluated value\n const evalResult = this.evaluationManager.getCellEvaluationResult(\n snapshot.address\n );\n\n if (!evalResult || evalResult.type !== \"value\") {\n // If evaluation failed or is not a value, copy as-is\n targetContent = snapshot.content;\n } else {\n // Convert to literal value\n const result = evalResult.result;\n if (result.type === \"number\") {\n targetContent = result.value;\n } else if (result.type === \"string\") {\n targetContent = result.value;\n } else if (result.type === \"boolean\") {\n targetContent = result.value;\n } else {\n // Error or other type, copy as-is\n targetContent = snapshot.content;\n }\n }\n } else {\n // Copy formula\n if (\n typeof snapshot.content === \"string\" &&\n snapshot.content.startsWith(\"=\")\n ) {\n // Adjust formula references\n targetContent = this.adjustFormulaReferences(\n snapshot.content,\n {\n colIndex: snapshot.address.colIndex,\n rowIndex: snapshot.address.rowIndex,\n },\n {\n colIndex: targetCell.colIndex,\n rowIndex: targetCell.rowIndex,\n }\n );\n } else {\n // Not a formula, copy as-is\n targetContent = snapshot.content;\n }\n }\n\n // Set target cell content\n const targetSheet = this.workbookManager.getSheet({\n workbookName: targetCell.workbookName,\n sheetName: targetCell.sheetName,\n });\n\n if (targetSheet) {\n const targetKey = `${String.fromCharCode(65 + targetCell.colIndex)}${\n targetCell.rowIndex + 1\n }`;\n targetSheet.content.set(targetKey, targetContent);\n }\n\n // Copy metadata if requested\n if (this.shouldInclude(options, \"metadata\")) {\n if (snapshot.metadata) {\n this.workbookManager.setCellMetadata(targetCell, {\n ...snapshot.metadata,\n });\n } else {\n // Clear target metadata if source has none\n this.workbookManager.setCellMetadata(targetCell, undefined);\n }\n }\n }\n\n /**\n * Update all formula references when cells are cut (moved)\n */\n /**\n * Copy content from one cell to another\n */\n private copyCellContent(\n sourceCell: CellAddress,\n targetCell: CellAddress,\n sourceTopLeft: CellAddress,\n options: CopyCellsOptions\n ): void {\n const sheet = this.workbookManager.getSheet({\n workbookName: sourceCell.workbookName,\n sheetName: sourceCell.sheetName,\n });\n\n if (!sheet) {\n return;\n }\n\n const key = `${String.fromCharCode(65 + sourceCell.colIndex)}${\n sourceCell.rowIndex + 1\n }`;\n const cellContent = sheet.content.get(key);\n\n if (!cellContent) {\n // Source cell is empty\n return;\n }\n\n let targetContent: SerializedCellValue;\n const copyType = options.type ?? \"formula\";\n\n if (copyType === \"value\") {\n // Copy evaluated value\n const evalResult =\n this.evaluationManager.getCellEvaluationResult(sourceCell);\n\n if (!evalResult || evalResult.type !== \"value\") {\n // If evaluation failed or is not a value, copy as-is\n targetContent = cellContent;\n } else {\n // Convert to literal value\n const result = evalResult.result;\n if (result.type === \"number\") {\n targetContent = result.value;\n } else if (result.type === \"string\") {\n targetContent = result.value;\n } else if (result.type === \"boolean\") {\n targetContent = result.value;\n } else {\n // Error or other type, copy as-is\n targetContent = cellContent;\n }\n }\n } else {\n // Copy formula\n if (typeof cellContent === \"string\" && cellContent.startsWith(\"=\")) {\n // Adjust formula references\n targetContent = this.adjustFormulaReferences(\n cellContent,\n {\n colIndex: sourceCell.colIndex,\n rowIndex: sourceCell.rowIndex,\n },\n {\n colIndex: targetCell.colIndex,\n rowIndex: targetCell.rowIndex,\n }\n );\n } else {\n // Not a formula, copy as-is\n targetContent = cellContent;\n }\n }\n\n // Set target cell content (using the engine's method through workbook manager)\n const targetSheet = this.workbookManager.getSheet({\n workbookName: targetCell.workbookName,\n sheetName: targetCell.sheetName,\n });\n\n if (targetSheet) {\n const targetKey = `${String.fromCharCode(65 + targetCell.colIndex)}${\n targetCell.rowIndex + 1\n }`;\n targetSheet.content.set(targetKey, targetContent);\n }\n\n // Copy metadata if requested\n if (this.shouldInclude(options, \"metadata\")) {\n const sourceMetadata = this.workbookManager.getCellMetadata(sourceCell);\n if (sourceMetadata) {\n this.workbookManager.setCellMetadata(targetCell, { ...sourceMetadata });\n } else {\n // Clear target metadata if source has none\n this.workbookManager.setCellMetadata(targetCell, undefined);\n }\n }\n }\n\n /**\n * Adjust formula references when copying\n * Based on autofill-utils.ts adjustFormulaReferences\n */\n private adjustFormulaReferences(\n formula: string,\n sourceAddress: LocalCellAddress,\n targetAddress: LocalCellAddress\n ): string {\n try {\n const ast = parseFormula(formula.slice(1)); // Remove the \"=\" sign\n\n const rowDelta = targetAddress.rowIndex - sourceAddress.rowIndex;\n const colDelta = targetAddress.colIndex - sourceAddress.colIndex;\n\n const adjustedAst = transformAST(ast, (node) => {\n if (node.type === \"reference\") {\n const refNode = node as ReferenceNode;\n return {\n ...refNode,\n address: {\n colIndex: refNode.isAbsolute.col\n ? refNode.address.colIndex\n : refNode.address.colIndex + colDelta,\n rowIndex: refNode.isAbsolute.row\n ? refNode.address.rowIndex\n : refNode.address.rowIndex + rowDelta,\n },\n };\n } else if (node.type === \"range\") {\n const rangeNode = node as RangeNode;\n return {\n ...rangeNode,\n range: {\n start: {\n col: rangeNode.isAbsolute.start.col\n ? rangeNode.range.start.col\n : rangeNode.range.start.col + colDelta,\n row: rangeNode.isAbsolute.start.row\n ? rangeNode.range.start.row\n : rangeNode.range.start.row + rowDelta,\n },\n end: {\n col:\n rangeNode.range.end.col.type === \"number\"\n ? rangeNode.isAbsolute.end.col\n ? rangeNode.range.end.col\n : {\n type: \"number\" as const,\n value: rangeNode.range.end.col.value + colDelta,\n }\n : rangeNode.range.end.col,\n row:\n rangeNode.range.end.row.type === \"number\"\n ? rangeNode.isAbsolute.end.row\n ? rangeNode.range.end.row\n : {\n type: \"number\" as const,\n value: rangeNode.range.end.row.value + rowDelta,\n }\n : rangeNode.range.end.row,\n },\n },\n };\n }\n return node;\n });\n\n return `=${astToString(adjustedAst)}`;\n } catch (error) {\n // If parsing fails, return the original formula\n console.warn(\"Failed to adjust formula references:\", error);\n return formula;\n }\n }\n\n /**\n * Copy formatting (cellStyles and conditionalStyles) from source to target\n * Clears existing cell styles in target range first (Excel behavior)\n */\n private copyFormatting(\n sourceCells: CellAddress[],\n sourceTopLeft: CellAddress,\n target: CellAddress,\n rowOffset: number,\n colOffset: number\n ): void {\n // STEP 1: Clear existing cell styles in target range (Excel-like replacement)\n const sourceRange = this.getBoundingBox(sourceCells);\n const targetRange: RangeAddress = {\n workbookName: target.workbookName,\n sheetName: target.sheetName,\n range: this.adjustRange(sourceRange, rowOffset, colOffset),\n };\n\n this.styleManager.clearCellStylesInRange(targetRange);\n\n // Get all styles for the source workbook\n const allConditionalStyles = this.styleManager.getAllConditionalStyles();\n const allCellStyles = this.styleManager.getAllCellStyles();\n\n // STEP 2: Copy conditional styles\n for (const style of allConditionalStyles) {\n for (const area of style.areas) {\n if (\n area.workbookName === sourceTopLeft.workbookName &&\n area.sheetName === sourceTopLeft.sheetName\n ) {\n // Calculate intersection of style range with source bounding box\n const intersection = intersectRanges(area.range, sourceRange);\n if (intersection) {\n // Copy only the intersection, offset to target\n const newStyle: ConditionalStyle = {\n areas: [\n {\n workbookName: target.workbookName,\n sheetName: target.sheetName,\n range: this.adjustRange(intersection, rowOffset, colOffset),\n },\n ],\n condition: style.condition,\n };\n this.styleManager.addConditionalStyle(newStyle);\n }\n }\n }\n }\n\n // STEP 3: Copy cell styles\n for (const style of allCellStyles) {\n for (const area of style.areas) {\n if (\n area.workbookName === sourceTopLeft.workbookName &&\n area.sheetName === sourceTopLeft.sheetName\n ) {\n // Calculate intersection of style range with source bounding box\n const intersection = intersectRanges(area.range, sourceRange);\n if (intersection) {\n // Copy only the intersection, offset to target\n const newStyle: DirectCellStyle = {\n areas: [\n {\n workbookName: target.workbookName,\n sheetName: target.sheetName,\n range: this.adjustRange(intersection, rowOffset, colOffset),\n },\n ],\n style: style.style,\n };\n this.styleManager.addCellStyle(newStyle);\n }\n }\n }\n }\n }\n\n /**\n * Get bounding box for a set of cells\n */\n private getBoundingBox(cells: CellAddress[]): SpreadsheetRange {\n let minRow = Infinity;\n let maxRow = -Infinity;\n let minCol = Infinity;\n let maxCol = -Infinity;\n\n for (const cell of cells) {\n minRow = Math.min(minRow, cell.rowIndex);\n maxRow = Math.max(maxRow, cell.rowIndex);\n minCol = Math.min(minCol, cell.colIndex);\n maxCol = Math.max(maxCol, cell.colIndex);\n }\n\n return {\n start: { col: minCol, row: minRow },\n end: {\n col: { type: \"number\", value: maxCol },\n row: { type: \"number\", value: maxRow },\n },\n };\n }\n\n /**\n * Adjust a range by row and column offsets\n */\n private adjustRange(\n range: SpreadsheetRange,\n rowOffset: number,\n colOffset: number\n ): SpreadsheetRange {\n return {\n start: {\n col: range.start.col + colOffset,\n row: range.start.row + rowOffset,\n },\n end: {\n col:\n range.end.col.type === \"number\"\n ? { type: \"number\", value: range.end.col.value + colOffset }\n : range.end.col,\n row:\n range.end.row.type === \"number\"\n ? { type: \"number\", value: range.end.row.value + rowOffset }\n : range.end.row,\n },\n };\n }\n\n /**\n * Clear source cells (for cut operation)\n */\n private clearSourceCells(cells: CellAddress[]): void {\n for (const cell of cells) {\n // Use setCellContent with empty string to properly clear the cell\n // This ensures indexes are updated and caches are properly managed\n this.workbookManager.setCellContent(cell, \"\");\n }\n }\n\n /**\n * Fill one or more areas with a seed range's content/style\n * Uses column-first strategy: fills down, then replicates right\n * Formulas are adjusted based on each target cell's offset from the seed\n */\n fillAreas(\n seedRange: RangeAddress,\n targetRanges: RangeAddress[],\n options: CopyCellsOptions\n ): void {\n for (const targetRange of targetRanges) {\n this.fillRangeWithSeed(seedRange, targetRange, {\n copyContent: this.shouldInclude(options, \"content\"),\n copyStyles: this.shouldInclude(options, \"style\"),\n contentType: options.type ?? \"formula\",\n adjustFormulas: true,\n });\n }\n\n // Clear seed range if cut operation\n if (options.cut) {\n const seedCells = this.expandRangeToCells(seedRange);\n this.clearSourceCells(seedCells);\n }\n }\n\n /**\n * Fill a target range with a seed range using column-first strategy\n * Step 0: Clear existing cell styles in target (Excel behavior)\n * Step 1: Fill down - extend seed pattern vertically to match target height\n * Step 2: Replicate right - copy filled columns horizontally\n */\n private fillRangeWithSeed(\n seedRange: RangeAddress,\n targetRange: RangeAddress,\n options: {\n copyContent: boolean;\n copyStyles: boolean;\n contentType: \"value\" | \"formula\";\n adjustFormulas: boolean;\n }\n ): void {\n // Step 0: Clear existing cell styles in target range (Excel-like replacement)\n if (options.copyStyles) {\n this.styleManager.clearCellStylesInRange(targetRange);\n }\n\n const seedCells = this.expandRangeToCells(seedRange);\n const seedWidth = this.getRangeWidth(seedRange);\n const seedHeight = this.getRangeHeight(seedRange);\n const targetWidth = this.getRangeWidth(targetRange);\n const targetHeight = this.getRangeHeight(targetRange);\n\n // Step 1: Fill down - replicate seed pattern vertically\n const filledColumns: Map<\n string,\n { cell: CellAddress; content: SerializedCellValue }\n > = new Map();\n\n for (let col = 0; col < seedWidth; col++) {\n for (let row = 0; row < targetHeight; row++) {\n const seedRow = row % seedHeight;\n const seedCell = seedCells.find(\n (c) =>\n c.colIndex === seedRange.range.start.col + col &&\n c.rowIndex === seedRange.range.start.row + seedRow\n );\n\n if (seedCell) {\n const targetCell: CellAddress = {\n workbookName: targetRange.workbookName,\n sheetName: targetRange.sheetName,\n colIndex: targetRange.range.start.col + col,\n rowIndex: targetRange.range.start.row + row,\n };\n\n const rowDelta = targetCell.rowIndex - seedCell.rowIndex;\n const colDelta = targetCell.colIndex - seedCell.colIndex;\n\n if (options.copyContent) {\n this.copyCellContentWithOffset(\n seedCell,\n targetCell,\n rowDelta,\n colDelta,\n {\n type: options.contentType,\n cut: false,\n include: [\"content\"],\n }\n );\n }\n\n if (options.copyStyles) {\n this.copyCellFormatting(seedCell, targetCell);\n }\n\n // Store filled column for horizontal replication\n const key = `${targetCell.colIndex}-${targetCell.rowIndex}`;\n const sheet = this.workbookManager.getSheet({\n workbookName: targetCell.workbookName,\n sheetName: targetCell.sheetName,\n });\n const cellKey = `${String.fromCharCode(65 + targetCell.colIndex)}${\n targetCell.rowIndex + 1\n }`;\n const content = sheet?.content.get(cellKey) || \"\";\n filledColumns.set(key, { cell: targetCell, content });\n }\n }\n }\n\n // Step 2: Replicate right - copy filled columns horizontally\n if (targetWidth > seedWidth) {\n for (let col = seedWidth; col < targetWidth; col++) {\n const sourceCol = col % seedWidth;\n\n for (let row = 0; row < targetHeight; row++) {\n const sourceCell: CellAddress = {\n workbookName: targetRange.workbookName,\n sheetName: targetRange.sheetName,\n colIndex: targetRange.range.start.col + sourceCol,\n rowIndex: targetRange.range.start.row + row,\n };\n\n const targetCell: CellAddress = {\n workbookName: targetRange.workbookName,\n sheetName: targetRange.sheetName,\n colIndex: targetRange.range.start.col + col,\n rowIndex: targetRange.range.start.row + row,\n };\n\n const colDelta = targetCell.colIndex - sourceCell.colIndex;\n\n if (options.copyContent) {\n this.copyCellContentWithOffset(\n sourceCell,\n targetCell,\n 0,\n colDelta,\n {\n type: options.contentType,\n cut: false,\n include: [\"content\"],\n }\n );\n }\n\n if (options.copyStyles) {\n this.copyCellFormatting(sourceCell, targetCell);\n }\n }\n }\n }\n }\n\n /**\n * Get the width of a range (number of columns)\n */\n private getRangeWidth(range: RangeAddress): number {\n if (range.range.end.col.type === \"infinity\") {\n return 100; // Default for infinite\n }\n return range.range.end.col.value - range.range.start.col + 1;\n }\n\n /**\n * Get the height of a range (number of rows)\n */\n private getRangeHeight(range: RangeAddress): number {\n if (range.range.end.row.type === \"infinity\") {\n return 100; // Default for infinite\n }\n return range.range.end.row.value - range.range.start.row + 1;\n }\n\n /**\n * Expand a RangeAddress into an array of CellAddress\n * Handles finite ranges, row-bounded, and column-bounded ranges\n */\n public expandRangeToCells(rangeAddress: RangeAddress): CellAddress[] {\n const { workbookName, sheetName, range } = rangeAddress;\n const cells: CellAddress[] = [];\n\n const startCol = range.start.col;\n const startRow = range.start.row;\n\n // Determine end column\n let endCol: number;\n if (range.end.col.type === \"infinity\") {\n // Limit infinite column ranges to a reasonable size (e.g., 100 columns)\n endCol = startCol + 99;\n } else {\n endCol = range.end.col.value;\n }\n\n // Determine end row\n let endRow: number;\n if (range.end.row.type === \"infinity\") {\n // Limit infinite row ranges to a reasonable size (e.g., 100 rows)\n endRow = startRow + 99;\n } else {\n endRow = range.end.row.value;\n }\n\n // Generate all cells in the range\n for (let row = startRow; row <= endRow; row++) {\n for (let col = startCol; col <= endCol; col++) {\n cells.push({\n workbookName,\n sheetName,\n colIndex: col,\n rowIndex: row,\n });\n }\n }\n\n return cells;\n }\n\n /**\n * Copy cell content with explicit row/column offset for fill operations\n */\n private copyCellContentWithOffset(\n sourceCell: CellAddress,\n targetCell: CellAddress,\n rowDelta: number,\n colDelta: number,\n options: CopyCellsOptions\n ): void {\n const sheet = this.workbookManager.getSheet({\n workbookName: sourceCell.workbookName,\n sheetName: sourceCell.sheetName,\n });\n\n if (!sheet) {\n return;\n }\n\n const key = `${String.fromCharCode(65 + sourceCell.colIndex)}${\n sourceCell.rowIndex + 1\n }`;\n const cellContent = sheet.content.get(key);\n\n if (!cellContent) {\n // Source cell is empty - clear target\n const targetSheet = this.workbookManager.getSheet({\n workbookName: targetCell.workbookName,\n sheetName: targetCell.sheetName,\n });\n if (targetSheet) {\n const targetKey = `${String.fromCharCode(65 + targetCell.colIndex)}${\n targetCell.rowIndex + 1\n }`;\n targetSheet.content.delete(targetKey);\n }\n return;\n }\n\n let targetContent: SerializedCellValue;\n const copyType = options.type ?? \"formula\";\n\n if (copyType === \"value\") {\n // Copy evaluated value\n const evalResult =\n this.evaluationManager.getCellEvaluationResult(sourceCell);\n\n if (!evalResult || evalResult.type !== \"value\") {\n // If evaluation failed or is not a value, copy as-is\n targetContent = cellContent;\n } else {\n // Convert to literal value\n const result = evalResult.result;\n if (result.type === \"number\") {\n targetContent = result.value;\n } else if (result.type === \"string\") {\n targetContent = result.value;\n } else if (result.type === \"boolean\") {\n targetContent = result.value;\n } else {\n // Error or other type, copy as-is\n targetContent = cellContent;\n }\n }\n } else {\n // Copy formula with offset adjustment\n if (typeof cellContent === \"string\" && cellContent.startsWith(\"=\")) {\n // Adjust formula references based on offset\n targetContent = this.adjustFormulaWithOffset(\n cellContent,\n rowDelta,\n colDelta\n );\n } else {\n // Not a formula, copy as-is\n targetContent = cellContent;\n }\n }\n\n // Set target cell content\n const targetSheet = this.workbookManager.getSheet({\n workbookName: targetCell.workbookName,\n sheetName: targetCell.sheetName,\n });\n\n if (targetSheet) {\n const targetKey = `${String.fromCharCode(65 + targetCell.colIndex)}${\n targetCell.rowIndex + 1\n }`;\n targetSheet.content.set(targetKey, targetContent);\n }\n\n // Copy metadata if requested\n if (this.shouldInclude(options, \"metadata\")) {\n const sourceMetadata = this.workbookManager.getCellMetadata(sourceCell);\n if (sourceMetadata) {\n this.workbookManager.setCellMetadata(targetCell, { ...sourceMetadata });\n } else {\n // Clear target metadata if source has none\n this.workbookManager.setCellMetadata(targetCell, undefined);\n }\n }\n }\n\n /**\n * Adjust formula references by a specific row/column offset\n */\n private adjustFormulaWithOffset(\n formula: string,\n rowDelta: number,\n colDelta: number\n ): string {\n try {\n const ast = parseFormula(formula.slice(1)); // Remove the \"=\" sign\n\n const adjustedAst = transformAST(ast, (node) => {\n if (node.type === \"reference\") {\n const refNode = node as ReferenceNode;\n return {\n ...refNode,\n address: {\n colIndex: refNode.isAbsolute.col\n ? refNode.address.colIndex\n : refNode.address.colIndex + colDelta,\n rowIndex: refNode.isAbsolute.row\n ? refNode.address.rowIndex\n : refNode.address.rowIndex + rowDelta,\n },\n };\n } else if (node.type === \"range\") {\n const rangeNode = node as RangeNode;\n return {\n ...rangeNode,\n range: {\n start: {\n col: rangeNode.isAbsolute.start.col\n ? rangeNode.range.start.col\n : rangeNode.range.start.col + colDelta,\n row: rangeNode.isAbsolute.start.row\n ? rangeNode.range.start.row\n : rangeNode.range.start.row + rowDelta,\n },\n end: {\n col:\n rangeNode.range.end.col.type === \"number\"\n ? rangeNode.isAbsolute.end.col\n ? rangeNode.range.end.col\n : {\n type: \"number\" as const,\n value: rangeNode.range.end.col.value + colDelta,\n }\n : rangeNode.range.end.col,\n row:\n rangeNode.range.end.row.type === \"number\"\n ? rangeNode.isAbsolute.end.row\n ? rangeNode.range.end.row\n : {\n type: \"number\" as const,\n value: rangeNode.range.end.row.value + rowDelta,\n }\n : rangeNode.range.end.row,\n },\n },\n };\n }\n return node;\n });\n\n return `=${astToString(adjustedAst)}`;\n } catch (error) {\n // If parsing fails, return the original formula\n console.warn(\"Failed to adjust formula with offset:\", error);\n return formula;\n }\n }\n\n /**\n * Copy formatting from one cell to another\n * Clears existing cell styles at target (Excel behavior) before copying new ones\n */\n private copyCellFormatting(\n sourceCell: CellAddress,\n targetCell: CellAddress\n ): void {\n // STEP 1: Clear existing cell styles at target cell (Excel-like replacement)\n const targetCellRange: RangeAddress = {\n workbookName: targetCell.workbookName,\n sheetName: targetCell.sheetName,\n range: {\n start: { col: targetCell.colIndex, row: targetCell.rowIndex },\n end: {\n col: { type: \"number\", value: targetCell.colIndex },\n row: { type: \"number\", value: targetCell.rowIndex },\n },\n },\n };\n\n this.styleManager.clearCellStylesInRange(targetCellRange);\n\n // Get all styles that intersect with the source cell\n const allConditionalStyles = this.styleManager.getAllConditionalStyles();\n const allCellStyles = this.styleManager.getAllCellStyles();\n\n const sourceCellRange: SpreadsheetRange = {\n start: { col: sourceCell.colIndex, row: sourceCell.rowIndex },\n end: {\n col: { type: \"number\", value: sourceCell.colIndex },\n row: { type: \"number\", value: sourceCell.rowIndex },\n },\n };\n\n // STEP 2: Copy conditional styles that apply to source cell\n for (const style of allConditionalStyles) {\n for (const area of style.areas) {\n if (\n area.workbookName === sourceCell.workbookName &&\n area.sheetName === sourceCell.sheetName\n ) {\n const intersection = intersectRanges(area.range, sourceCellRange);\n if (intersection) {\n // Apply style to target cell\n const newStyle: ConditionalStyle = {\n areas: [\n {\n workbookName: targetCell.workbookName,\n sheetName: targetCell.sheetName,\n range: {\n start: {\n col: targetCell.colIndex,\n row: targetCell.rowIndex,\n },\n end: {\n col: { type: \"number\", value: targetCell.colIndex },\n row: { type: \"number\", value: targetCell.rowIndex },\n },\n },\n },\n ],\n condition: style.condition,\n };\n this.styleManager.addConditionalStyle(newStyle);\n }\n }\n }\n }\n\n // STEP 3: Copy cell styles that apply to source cell\n for (const style of allCellStyles) {\n for (const area of style.areas) {\n if (\n area.workbookName === sourceCell.workbookName &&\n area.sheetName === sourceCell.sheetName\n ) {\n const intersection = intersectRanges(area.range, sourceCellRange);\n if (intersection) {\n // Apply style to target cell\n const newStyle: DirectCellStyle = {\n areas: [\n {\n workbookName: targetCell.workbookName,\n sheetName: targetCell.sheetName,\n range: {\n start: {\n col: targetCell.colIndex,\n row: targetCell.rowIndex,\n },\n end: {\n col: { type: \"number\", value: targetCell.colIndex },\n row: { type: \"number\", value: targetCell.rowIndex },\n },\n },\n },\n ],\n style: style.style,\n };\n this.styleManager.addCellStyle(newStyle);\n }\n }\n }\n }\n }\n}\n"
|
|
5
|
+
"/**\n * CopyManager - Manages cell copy/paste operations\n */\n\nimport type {\n CellAddress,\n CopyCellsOptions,\n ConditionalStyle,\n DirectCellStyle,\n LocalCellAddress,\n RangeAddress,\n SerializedCellValue,\n SpreadsheetRange,\n} from \"../types.cjs\";\nimport type { WorkbookManager } from \"./workbook-manager.cjs\";\nimport type { EvaluationManager } from \"./evaluation-manager.cjs\";\nimport type { StyleManager } from \"./style-manager.cjs\";\nimport { parseFormula } from \"../../parser/parser.cjs\";\nimport { astToString } from \"../../parser/formatter.cjs\";\nimport { transformAST } from \"../ast-traverser.cjs\";\nimport type { ReferenceNode, RangeNode } from \"../../parser/ast.cjs\";\nimport { getCellReference, isCellInRange } from \"../utils.cjs\";\nimport { intersectRanges } from \"../utils/range-utils.cjs\";\nimport {\n updateReferencesForMovedCells,\n type MovedCellsInfo,\n} from \"../cell-mover.cjs\";\n\n/**\n * Snapshot of a cell's content, metadata, and styles\n */\ninterface CellSnapshot {\n address: CellAddress;\n content: SerializedCellValue | undefined;\n metadata: unknown | undefined;\n matchingCellStyles?: DirectCellStyle[];\n matchingConditionalStyles?: ConditionalStyle[];\n}\n\nexport class CopyManager {\n constructor(\n private workbookManager: WorkbookManager,\n private evaluationManager: EvaluationManager,\n private styleManager: StyleManager\n ) {}\n\n /**\n * Normalize the include option to an array of parts to copy\n */\n private normalizeInclude(\n include: CopyCellsOptions[\"include\"]\n ): (\"content\" | \"style\" | \"metadata\")[] {\n if (!include || include === \"all\") {\n return [\"content\", \"style\", \"metadata\"];\n }\n return include;\n }\n\n /**\n * Check if a specific part should be included in the copy operation\n */\n private shouldInclude(\n options: CopyCellsOptions,\n part: \"content\" | \"style\" | \"metadata\"\n ): boolean {\n const normalized = this.normalizeInclude(options.include);\n return normalized.includes(part);\n }\n\n /**\n * Paste cells from source to target\n * Delegates to cutCells for move operations or copyOnlyCells for copy operations\n */\n pasteCells(\n source: CellAddress[],\n target: CellAddress,\n options: CopyCellsOptions\n ): void {\n if (source.length === 0) {\n return;\n }\n\n if (options.cut === true) {\n return this.cutCells(source, target, options);\n } else {\n return this.copyOnlyCells(source, target, options);\n }\n }\n\n /**\n * Cut cells: Proper snapshot flow for move operations\n * 1. Snapshot source cells (with styles)\n * 2. Remove source cells and punch holes in style areas\n * 3. Update references in OTHER cells (not in moved set)\n * 4. Update formulas in snapshot and apply to target\n */\n private cutCells(\n source: CellAddress[],\n target: CellAddress,\n options: CopyCellsOptions\n ): void {\n const topLeft = this.findTopLeft(source);\n const rowOffset = target.rowIndex - topLeft.rowIndex;\n const colOffset = target.colIndex - topLeft.colIndex;\n\n // 1. Snapshot source cells (with styles)\n const snapshot = this.snapshotCellsWithStyles(source);\n\n // 2. Remove source cells (content) and punch holes in styles\n this.clearSourceCells(source);\n\n // Punch holes in style areas for each cut cell\n if (this.shouldInclude(options, \"style\")) {\n for (const cell of source) {\n const cellRange: RangeAddress = {\n workbookName: cell.workbookName,\n sheetName: cell.sheetName,\n range: {\n start: { col: cell.colIndex, row: cell.rowIndex },\n end: {\n col: { type: \"number\", value: cell.colIndex },\n row: { type: \"number\", value: cell.rowIndex },\n },\n },\n };\n this.styleManager.clearCellStylesInRange(cellRange);\n }\n }\n\n // 3. Update references in OTHER cells (not in moved set)\n const movedCellsSet = new Set(\n source.map(\n (c) => `${c.workbookName}:${c.sheetName}:${c.colIndex}:${c.rowIndex}`\n )\n );\n\n const movedCellsInfo: MovedCellsInfo = {\n cellsSet: movedCellsSet,\n workbookName: topLeft.workbookName,\n sheetName: topLeft.sheetName,\n rowOffset,\n colOffset,\n };\n\n this.workbookManager.updateFormulasExcluding(movedCellsSet, (formula) =>\n updateReferencesForMovedCells(formula, movedCellsInfo)\n );\n\n // 4. Update formulas in snapshot and apply to target\n for (let i = 0; i < snapshot.length; i++) {\n const snap = snapshot[i]!;\n const sourceCell = source[i]!;\n const targetCell: CellAddress = {\n workbookName: target.workbookName,\n sheetName: target.sheetName,\n colIndex: sourceCell.colIndex + colOffset,\n rowIndex: sourceCell.rowIndex + rowOffset,\n };\n\n // Apply content (with formula adjustment)\n if (this.shouldInclude(options, \"content\") && snap.content) {\n let targetContent = snap.content;\n\n if (typeof snap.content === \"string\" && snap.content.startsWith(\"=\")) {\n // Adjust formula references relative to new position\n targetContent = this.adjustFormulaReferences(\n snap.content,\n {\n colIndex: snap.address.colIndex,\n rowIndex: snap.address.rowIndex,\n },\n {\n colIndex: targetCell.colIndex,\n rowIndex: targetCell.rowIndex,\n }\n );\n }\n\n // Use setCellContent to ensure proper cache invalidation and dependency tracking\n this.workbookManager.setCellContent(targetCell, targetContent);\n }\n\n // Apply metadata\n if (this.shouldInclude(options, \"metadata\")) {\n if (snap.metadata) {\n this.workbookManager.setCellMetadata(targetCell, {\n ...snap.metadata,\n });\n } else {\n this.workbookManager.setCellMetadata(targetCell, undefined);\n }\n }\n\n // Apply styles from snapshot to new location\n if (this.shouldInclude(options, \"style\")) {\n this.applyStylesFromSnapshot(snap, targetCell);\n }\n }\n }\n\n /**\n * Copy cells: Standard copy operation (not cut/move)\n * Snapshot → Copy with adjustment → Copy formatting\n */\n private copyOnlyCells(\n source: CellAddress[],\n target: CellAddress,\n options: CopyCellsOptions\n ): void {\n const topLeft = this.findTopLeft(source);\n const rowOffset = target.rowIndex - topLeft.rowIndex;\n const colOffset = target.colIndex - topLeft.colIndex;\n\n // SNAPSHOT source cells (handles overlapping ranges)\n const snapshot = this.snapshotCells(source);\n\n // Copy cell contents if requested (from snapshot, not live cells)\n if (this.shouldInclude(options, \"content\")) {\n for (let i = 0; i < source.length; i++) {\n const sourceCell = source[i]!;\n const cellSnapshot = snapshot[i]!;\n const targetCell: CellAddress = {\n workbookName: target.workbookName,\n sheetName: target.sheetName,\n colIndex: sourceCell.colIndex + colOffset,\n rowIndex: sourceCell.rowIndex + rowOffset,\n };\n\n this.copyCellContentFromSnapshot(\n cellSnapshot,\n targetCell,\n topLeft,\n options\n );\n }\n }\n\n // Copy formatting if requested\n if (this.shouldInclude(options, \"style\")) {\n this.copyFormatting(source, topLeft, target, rowOffset, colOffset);\n }\n }\n\n /**\n * Find the top-left cell (minimum row/col indices)\n */\n private findTopLeft(cells: CellAddress[]): CellAddress {\n let minRow = Infinity;\n let minCol = Infinity;\n let topLeftCell = cells[0]!;\n\n for (const cell of cells) {\n if (\n cell.rowIndex < minRow ||\n (cell.rowIndex === minRow && cell.colIndex < minCol)\n ) {\n minRow = cell.rowIndex;\n minCol = cell.colIndex;\n topLeftCell = cell;\n }\n }\n\n return topLeftCell;\n }\n\n /**\n * Create a snapshot of cells' content and metadata\n * This prevents issues with overlapping ranges where source and target overlap\n * Used for copy operations (not cut)\n */\n private snapshotCells(cells: CellAddress[]): CellSnapshot[] {\n return cells.map((cell) => {\n const sheet = this.workbookManager.getSheet({\n workbookName: cell.workbookName,\n sheetName: cell.sheetName,\n });\n\n const key = `${String.fromCharCode(65 + cell.colIndex)}${\n cell.rowIndex + 1\n }`;\n const content = sheet?.content.get(key);\n const metadata = this.workbookManager.getCellMetadata(cell);\n\n return {\n address: cell,\n content,\n metadata,\n };\n });\n }\n\n /**\n * Create a snapshot of cells with content, metadata, AND styles\n * Used for cut operations to preserve all cell information\n */\n private snapshotCellsWithStyles(cells: CellAddress[]): CellSnapshot[] {\n const allCellStyles = this.styleManager.getAllCellStyles();\n const allConditionalStyles = this.styleManager.getAllConditionalStyles();\n\n return cells.map((cell) => {\n const sheet = this.workbookManager.getSheet({\n workbookName: cell.workbookName,\n sheetName: cell.sheetName,\n });\n\n const key = getCellReference(cell);\n const content = sheet?.content.get(key);\n const metadata = this.workbookManager.getCellMetadata(cell);\n\n // Find all styles that apply to this cell\n const matchingCellStyles = allCellStyles.filter((style) =>\n style.areas.some(\n (area) =>\n area.workbookName === cell.workbookName &&\n area.sheetName === cell.sheetName &&\n isCellInRange(cell, area.range)\n )\n );\n\n const matchingConditionalStyles = allConditionalStyles.filter((style) =>\n style.areas.some(\n (area) =>\n area.workbookName === cell.workbookName &&\n area.sheetName === cell.sheetName &&\n isCellInRange(cell, area.range)\n )\n );\n\n return {\n address: cell,\n content,\n metadata,\n matchingCellStyles,\n matchingConditionalStyles,\n };\n });\n }\n\n /**\n * Apply styles from a snapshot to a target cell\n * Creates new style areas at the target location\n */\n private applyStylesFromSnapshot(\n snapshot: CellSnapshot,\n targetCell: CellAddress\n ): void {\n // Apply cell styles\n if (snapshot.matchingCellStyles) {\n for (const style of snapshot.matchingCellStyles) {\n const newStyle: DirectCellStyle = {\n areas: [\n {\n workbookName: targetCell.workbookName,\n sheetName: targetCell.sheetName,\n range: {\n start: { col: targetCell.colIndex, row: targetCell.rowIndex },\n end: {\n col: { type: \"number\", value: targetCell.colIndex },\n row: { type: \"number\", value: targetCell.rowIndex },\n },\n },\n },\n ],\n style: style.style,\n };\n this.styleManager.addCellStyle(newStyle);\n }\n }\n\n // Apply conditional styles\n if (snapshot.matchingConditionalStyles) {\n for (const style of snapshot.matchingConditionalStyles) {\n const newStyle: ConditionalStyle = {\n areas: [\n {\n workbookName: targetCell.workbookName,\n sheetName: targetCell.sheetName,\n range: {\n start: { col: targetCell.colIndex, row: targetCell.rowIndex },\n end: {\n col: { type: \"number\", value: targetCell.colIndex },\n row: { type: \"number\", value: targetCell.rowIndex },\n },\n },\n },\n ],\n condition: style.condition,\n };\n this.styleManager.addConditionalStyle(newStyle);\n }\n }\n }\n\n /**\n * Copy content from a cell snapshot to a target cell\n */\n private copyCellContentFromSnapshot(\n snapshot: CellSnapshot,\n targetCell: CellAddress,\n sourceTopLeft: CellAddress,\n options: CopyCellsOptions\n ): void {\n if (!snapshot.content) {\n // Source cell was empty\n return;\n }\n\n let targetContent: SerializedCellValue;\n const copyType = options.type ?? \"formula\";\n\n if (copyType === \"value\") {\n // Copy evaluated value\n const evalResult = this.evaluationManager.getCellEvaluationResult(\n snapshot.address\n );\n\n if (!evalResult || evalResult.type !== \"value\") {\n // If evaluation failed or is not a value, copy as-is\n targetContent = snapshot.content;\n } else {\n // Convert to literal value\n const result = evalResult.result;\n if (result.type === \"number\") {\n targetContent = result.value;\n } else if (result.type === \"string\") {\n targetContent = result.value;\n } else if (result.type === \"boolean\") {\n targetContent = result.value;\n } else {\n // Error or other type, copy as-is\n targetContent = snapshot.content;\n }\n }\n } else {\n // Copy formula\n if (\n typeof snapshot.content === \"string\" &&\n snapshot.content.startsWith(\"=\")\n ) {\n // Adjust formula references\n targetContent = this.adjustFormulaReferences(\n snapshot.content,\n {\n colIndex: snapshot.address.colIndex,\n rowIndex: snapshot.address.rowIndex,\n },\n {\n colIndex: targetCell.colIndex,\n rowIndex: targetCell.rowIndex,\n }\n );\n } else {\n // Not a formula, copy as-is\n targetContent = snapshot.content;\n }\n }\n\n // Set target cell content\n const targetSheet = this.workbookManager.getSheet({\n workbookName: targetCell.workbookName,\n sheetName: targetCell.sheetName,\n });\n\n if (targetSheet) {\n const targetKey = `${String.fromCharCode(65 + targetCell.colIndex)}${\n targetCell.rowIndex + 1\n }`;\n targetSheet.content.set(targetKey, targetContent);\n }\n\n // Copy metadata if requested\n if (this.shouldInclude(options, \"metadata\")) {\n if (snapshot.metadata) {\n this.workbookManager.setCellMetadata(targetCell, {\n ...snapshot.metadata,\n });\n } else {\n // Clear target metadata if source has none\n this.workbookManager.setCellMetadata(targetCell, undefined);\n }\n }\n }\n\n /**\n * Update all formula references when cells are cut (moved)\n */\n /**\n * Copy content from one cell to another\n */\n private copyCellContent(\n sourceCell: CellAddress,\n targetCell: CellAddress,\n sourceTopLeft: CellAddress,\n options: CopyCellsOptions\n ): void {\n const sheet = this.workbookManager.getSheet({\n workbookName: sourceCell.workbookName,\n sheetName: sourceCell.sheetName,\n });\n\n if (!sheet) {\n return;\n }\n\n const key = `${String.fromCharCode(65 + sourceCell.colIndex)}${\n sourceCell.rowIndex + 1\n }`;\n const cellContent = sheet.content.get(key);\n\n if (!cellContent) {\n // Source cell is empty\n return;\n }\n\n let targetContent: SerializedCellValue;\n const copyType = options.type ?? \"formula\";\n\n if (copyType === \"value\") {\n // Copy evaluated value\n const evalResult =\n this.evaluationManager.getCellEvaluationResult(sourceCell);\n\n if (!evalResult || evalResult.type !== \"value\") {\n // If evaluation failed or is not a value, copy as-is\n targetContent = cellContent;\n } else {\n // Convert to literal value\n const result = evalResult.result;\n if (result.type === \"number\") {\n targetContent = result.value;\n } else if (result.type === \"string\") {\n targetContent = result.value;\n } else if (result.type === \"boolean\") {\n targetContent = result.value;\n } else {\n // Error or other type, copy as-is\n targetContent = cellContent;\n }\n }\n } else {\n // Copy formula\n if (typeof cellContent === \"string\" && cellContent.startsWith(\"=\")) {\n // Adjust formula references\n targetContent = this.adjustFormulaReferences(\n cellContent,\n {\n colIndex: sourceCell.colIndex,\n rowIndex: sourceCell.rowIndex,\n },\n {\n colIndex: targetCell.colIndex,\n rowIndex: targetCell.rowIndex,\n }\n );\n } else {\n // Not a formula, copy as-is\n targetContent = cellContent;\n }\n }\n\n // Set target cell content (using the engine's method through workbook manager)\n const targetSheet = this.workbookManager.getSheet({\n workbookName: targetCell.workbookName,\n sheetName: targetCell.sheetName,\n });\n\n if (targetSheet) {\n const targetKey = `${String.fromCharCode(65 + targetCell.colIndex)}${\n targetCell.rowIndex + 1\n }`;\n targetSheet.content.set(targetKey, targetContent);\n }\n\n // Copy metadata if requested\n if (this.shouldInclude(options, \"metadata\")) {\n const sourceMetadata = this.workbookManager.getCellMetadata(sourceCell);\n if (sourceMetadata) {\n this.workbookManager.setCellMetadata(targetCell, { ...sourceMetadata });\n } else {\n // Clear target metadata if source has none\n this.workbookManager.setCellMetadata(targetCell, undefined);\n }\n }\n }\n\n /**\n * Adjust formula references when copying\n * Based on autofill-utils.ts adjustFormulaReferences\n */\n private adjustFormulaReferences(\n formula: string,\n sourceAddress: LocalCellAddress,\n targetAddress: LocalCellAddress\n ): string {\n try {\n const ast = parseFormula(formula.slice(1)); // Remove the \"=\" sign\n\n const rowDelta = targetAddress.rowIndex - sourceAddress.rowIndex;\n const colDelta = targetAddress.colIndex - sourceAddress.colIndex;\n\n const adjustedAst = transformAST(ast, (node) => {\n if (node.type === \"reference\") {\n const refNode = node as ReferenceNode;\n return {\n ...refNode,\n address: {\n colIndex: refNode.isAbsolute.col\n ? refNode.address.colIndex\n : refNode.address.colIndex + colDelta,\n rowIndex: refNode.isAbsolute.row\n ? refNode.address.rowIndex\n : refNode.address.rowIndex + rowDelta,\n },\n };\n } else if (node.type === \"range\") {\n const rangeNode = node as RangeNode;\n return {\n ...rangeNode,\n range: {\n start: {\n col: rangeNode.isAbsolute.start.col\n ? rangeNode.range.start.col\n : rangeNode.range.start.col + colDelta,\n row: rangeNode.isAbsolute.start.row\n ? rangeNode.range.start.row\n : rangeNode.range.start.row + rowDelta,\n },\n end: {\n col:\n rangeNode.range.end.col.type === \"number\"\n ? rangeNode.isAbsolute.end.col\n ? rangeNode.range.end.col\n : {\n type: \"number\" as const,\n value: rangeNode.range.end.col.value + colDelta,\n }\n : rangeNode.range.end.col,\n row:\n rangeNode.range.end.row.type === \"number\"\n ? rangeNode.isAbsolute.end.row\n ? rangeNode.range.end.row\n : {\n type: \"number\" as const,\n value: rangeNode.range.end.row.value + rowDelta,\n }\n : rangeNode.range.end.row,\n },\n },\n };\n }\n return node;\n });\n\n return `=${astToString(adjustedAst)}`;\n } catch (error) {\n // If parsing fails, return the original formula\n console.warn(\"Failed to adjust formula references:\", error);\n return formula;\n }\n }\n\n /**\n * Copy formatting (cellStyles and conditionalStyles) from source to target\n * Clears existing cell styles in target range first (Excel behavior)\n */\n private copyFormatting(\n sourceCells: CellAddress[],\n sourceTopLeft: CellAddress,\n target: CellAddress,\n rowOffset: number,\n colOffset: number\n ): void {\n // STEP 1: Clear existing cell styles in target range (Excel-like replacement)\n const sourceRange = this.getBoundingBox(sourceCells);\n const targetRange: RangeAddress = {\n workbookName: target.workbookName,\n sheetName: target.sheetName,\n range: this.adjustRange(sourceRange, rowOffset, colOffset),\n };\n\n this.styleManager.clearCellStylesInRange(targetRange);\n\n // Get all styles for the source workbook\n const allConditionalStyles = this.styleManager.getAllConditionalStyles();\n const allCellStyles = this.styleManager.getAllCellStyles();\n\n // STEP 2: Copy conditional styles\n for (const style of allConditionalStyles) {\n for (const area of style.areas) {\n if (\n area.workbookName === sourceTopLeft.workbookName &&\n area.sheetName === sourceTopLeft.sheetName\n ) {\n // Calculate intersection of style range with source bounding box\n const intersection = intersectRanges(area.range, sourceRange);\n if (intersection) {\n // Copy only the intersection, offset to target\n const newStyle: ConditionalStyle = {\n areas: [\n {\n workbookName: target.workbookName,\n sheetName: target.sheetName,\n range: this.adjustRange(intersection, rowOffset, colOffset),\n },\n ],\n condition: style.condition,\n };\n this.styleManager.addConditionalStyle(newStyle);\n }\n }\n }\n }\n\n // STEP 3: Copy cell styles\n for (const style of allCellStyles) {\n for (const area of style.areas) {\n if (\n area.workbookName === sourceTopLeft.workbookName &&\n area.sheetName === sourceTopLeft.sheetName\n ) {\n // Calculate intersection of style range with source bounding box\n const intersection = intersectRanges(area.range, sourceRange);\n if (intersection) {\n // Copy only the intersection, offset to target\n const newStyle: DirectCellStyle = {\n areas: [\n {\n workbookName: target.workbookName,\n sheetName: target.sheetName,\n range: this.adjustRange(intersection, rowOffset, colOffset),\n },\n ],\n style: style.style,\n };\n this.styleManager.addCellStyle(newStyle);\n }\n }\n }\n }\n }\n\n /**\n * Get bounding box for a set of cells\n */\n private getBoundingBox(cells: CellAddress[]): SpreadsheetRange {\n let minRow = Infinity;\n let maxRow = -Infinity;\n let minCol = Infinity;\n let maxCol = -Infinity;\n\n for (const cell of cells) {\n minRow = Math.min(minRow, cell.rowIndex);\n maxRow = Math.max(maxRow, cell.rowIndex);\n minCol = Math.min(minCol, cell.colIndex);\n maxCol = Math.max(maxCol, cell.colIndex);\n }\n\n return {\n start: { col: minCol, row: minRow },\n end: {\n col: { type: \"number\", value: maxCol },\n row: { type: \"number\", value: maxRow },\n },\n };\n }\n\n /**\n * Adjust a range by row and column offsets\n */\n private adjustRange(\n range: SpreadsheetRange,\n rowOffset: number,\n colOffset: number\n ): SpreadsheetRange {\n return {\n start: {\n col: range.start.col + colOffset,\n row: range.start.row + rowOffset,\n },\n end: {\n col:\n range.end.col.type === \"number\"\n ? { type: \"number\", value: range.end.col.value + colOffset }\n : range.end.col,\n row:\n range.end.row.type === \"number\"\n ? { type: \"number\", value: range.end.row.value + rowOffset }\n : range.end.row,\n },\n };\n }\n\n /**\n * Clear source cells (for cut operation)\n */\n private clearSourceCells(cells: CellAddress[]): void {\n for (const cell of cells) {\n // Use setCellContent with empty string to properly clear the cell\n // This ensures indexes are updated and caches are properly managed\n this.workbookManager.setCellContent(cell, \"\");\n }\n }\n\n /**\n * Fill one or more areas with a seed range's content/style\n * Uses column-first strategy: fills down, then replicates right\n * Formulas are adjusted based on each target cell's offset from the seed\n */\n fillAreas(\n seedRange: RangeAddress,\n targetRanges: RangeAddress[],\n options: CopyCellsOptions\n ): void {\n for (const targetRange of targetRanges) {\n this.fillRangeWithSeed(seedRange, targetRange, {\n copyContent: this.shouldInclude(options, \"content\"),\n copyStyles: this.shouldInclude(options, \"style\"),\n contentType: options.type ?? \"formula\",\n adjustFormulas: true,\n });\n }\n\n // Clear seed range if cut operation\n if (options.cut) {\n const seedCells = this.expandRangeToCells(seedRange);\n this.clearSourceCells(seedCells);\n }\n }\n\n /**\n * Fill a target range with a seed range using column-first strategy\n * Step 0: Clear existing cell styles in target (Excel behavior)\n * Step 1: Fill down - extend seed pattern vertically to match target height\n * Step 2: Replicate right - copy filled columns horizontally\n */\n private fillRangeWithSeed(\n seedRange: RangeAddress,\n targetRange: RangeAddress,\n options: {\n copyContent: boolean;\n copyStyles: boolean;\n contentType: \"value\" | \"formula\";\n adjustFormulas: boolean;\n }\n ): void {\n // Step 0: Clear existing cell styles in target range (Excel-like replacement)\n if (options.copyStyles) {\n this.styleManager.clearCellStylesInRange(targetRange);\n }\n\n const seedCells = this.expandRangeToCells(seedRange);\n const seedWidth = this.getRangeWidth(seedRange);\n const seedHeight = this.getRangeHeight(seedRange);\n const targetWidth = this.getRangeWidth(targetRange);\n const targetHeight = this.getRangeHeight(targetRange);\n\n // Step 1: Fill down - replicate seed pattern vertically\n const filledColumns: Map<\n string,\n { cell: CellAddress; content: SerializedCellValue }\n > = new Map();\n\n for (let col = 0; col < seedWidth; col++) {\n for (let row = 0; row < targetHeight; row++) {\n const seedRow = row % seedHeight;\n const seedCell = seedCells.find(\n (c) =>\n c.colIndex === seedRange.range.start.col + col &&\n c.rowIndex === seedRange.range.start.row + seedRow\n );\n\n if (seedCell) {\n const targetCell: CellAddress = {\n workbookName: targetRange.workbookName,\n sheetName: targetRange.sheetName,\n colIndex: targetRange.range.start.col + col,\n rowIndex: targetRange.range.start.row + row,\n };\n\n const rowDelta = targetCell.rowIndex - seedCell.rowIndex;\n const colDelta = targetCell.colIndex - seedCell.colIndex;\n\n if (options.copyContent) {\n this.copyCellContentWithOffset(\n seedCell,\n targetCell,\n rowDelta,\n colDelta,\n {\n type: options.contentType,\n cut: false,\n include: [\"content\"],\n }\n );\n }\n\n if (options.copyStyles) {\n this.copyCellFormatting(seedCell, targetCell);\n }\n\n // Store filled column for horizontal replication\n const key = `${targetCell.colIndex}-${targetCell.rowIndex}`;\n const sheet = this.workbookManager.getSheet({\n workbookName: targetCell.workbookName,\n sheetName: targetCell.sheetName,\n });\n const cellKey = `${String.fromCharCode(65 + targetCell.colIndex)}${\n targetCell.rowIndex + 1\n }`;\n const content = sheet?.content.get(cellKey) || \"\";\n filledColumns.set(key, { cell: targetCell, content });\n }\n }\n }\n\n // Step 2: Replicate right - copy filled columns horizontally\n if (targetWidth > seedWidth) {\n for (let col = seedWidth; col < targetWidth; col++) {\n const sourceCol = col % seedWidth;\n\n for (let row = 0; row < targetHeight; row++) {\n const sourceCell: CellAddress = {\n workbookName: targetRange.workbookName,\n sheetName: targetRange.sheetName,\n colIndex: targetRange.range.start.col + sourceCol,\n rowIndex: targetRange.range.start.row + row,\n };\n\n const targetCell: CellAddress = {\n workbookName: targetRange.workbookName,\n sheetName: targetRange.sheetName,\n colIndex: targetRange.range.start.col + col,\n rowIndex: targetRange.range.start.row + row,\n };\n\n const colDelta = targetCell.colIndex - sourceCell.colIndex;\n\n if (options.copyContent) {\n this.copyCellContentWithOffset(\n sourceCell,\n targetCell,\n 0,\n colDelta,\n {\n type: options.contentType,\n cut: false,\n include: [\"content\"],\n }\n );\n }\n\n if (options.copyStyles) {\n this.copyCellFormatting(sourceCell, targetCell);\n }\n }\n }\n }\n }\n\n /**\n * Get the width of a range (number of columns)\n */\n private getRangeWidth(range: RangeAddress): number {\n if (range.range.end.col.type === \"infinity\") {\n return 100; // Default for infinite\n }\n return range.range.end.col.value - range.range.start.col + 1;\n }\n\n /**\n * Get the height of a range (number of rows)\n */\n private getRangeHeight(range: RangeAddress): number {\n if (range.range.end.row.type === \"infinity\") {\n return 100; // Default for infinite\n }\n return range.range.end.row.value - range.range.start.row + 1;\n }\n\n /**\n * Expand a RangeAddress into an array of CellAddress\n * Handles finite ranges, row-bounded, and column-bounded ranges\n */\n public expandRangeToCells(rangeAddress: RangeAddress): CellAddress[] {\n const { workbookName, sheetName, range } = rangeAddress;\n const cells: CellAddress[] = [];\n\n const startCol = range.start.col;\n const startRow = range.start.row;\n\n // Determine end column\n let endCol: number;\n if (range.end.col.type === \"infinity\") {\n // Limit infinite column ranges to a reasonable size (e.g., 100 columns)\n endCol = startCol + 99;\n } else {\n endCol = range.end.col.value;\n }\n\n // Determine end row\n let endRow: number;\n if (range.end.row.type === \"infinity\") {\n // Limit infinite row ranges to a reasonable size (e.g., 100 rows)\n endRow = startRow + 99;\n } else {\n endRow = range.end.row.value;\n }\n\n // Generate all cells in the range\n for (let row = startRow; row <= endRow; row++) {\n for (let col = startCol; col <= endCol; col++) {\n cells.push({\n workbookName,\n sheetName,\n colIndex: col,\n rowIndex: row,\n });\n }\n }\n\n return cells;\n }\n\n /**\n * Copy cell content with explicit row/column offset for fill operations\n */\n private copyCellContentWithOffset(\n sourceCell: CellAddress,\n targetCell: CellAddress,\n rowDelta: number,\n colDelta: number,\n options: CopyCellsOptions\n ): void {\n const sheet = this.workbookManager.getSheet({\n workbookName: sourceCell.workbookName,\n sheetName: sourceCell.sheetName,\n });\n\n if (!sheet) {\n return;\n }\n\n const key = `${String.fromCharCode(65 + sourceCell.colIndex)}${\n sourceCell.rowIndex + 1\n }`;\n const cellContent = sheet.content.get(key);\n\n if (!cellContent) {\n // Source cell is empty - clear target\n const targetSheet = this.workbookManager.getSheet({\n workbookName: targetCell.workbookName,\n sheetName: targetCell.sheetName,\n });\n if (targetSheet) {\n const targetKey = `${String.fromCharCode(65 + targetCell.colIndex)}${\n targetCell.rowIndex + 1\n }`;\n targetSheet.content.delete(targetKey);\n }\n return;\n }\n\n let targetContent: SerializedCellValue;\n const copyType = options.type ?? \"formula\";\n\n if (copyType === \"value\") {\n // Copy evaluated value\n const evalResult =\n this.evaluationManager.getCellEvaluationResult(sourceCell);\n\n if (!evalResult || evalResult.type !== \"value\") {\n // If evaluation failed or is not a value, copy as-is\n targetContent = cellContent;\n } else {\n // Convert to literal value\n const result = evalResult.result;\n if (result.type === \"number\") {\n targetContent = result.value;\n } else if (result.type === \"string\") {\n targetContent = result.value;\n } else if (result.type === \"boolean\") {\n targetContent = result.value;\n } else {\n // Error or other type, copy as-is\n targetContent = cellContent;\n }\n }\n } else {\n // Copy formula with offset adjustment\n if (typeof cellContent === \"string\" && cellContent.startsWith(\"=\")) {\n // Adjust formula references based on offset\n targetContent = this.adjustFormulaWithOffset(\n cellContent,\n rowDelta,\n colDelta\n );\n } else {\n // Not a formula, copy as-is\n targetContent = cellContent;\n }\n }\n\n // Set target cell content\n const targetSheet = this.workbookManager.getSheet({\n workbookName: targetCell.workbookName,\n sheetName: targetCell.sheetName,\n });\n\n if (targetSheet) {\n const targetKey = `${String.fromCharCode(65 + targetCell.colIndex)}${\n targetCell.rowIndex + 1\n }`;\n targetSheet.content.set(targetKey, targetContent);\n }\n\n // Copy metadata if requested\n if (this.shouldInclude(options, \"metadata\")) {\n const sourceMetadata = this.workbookManager.getCellMetadata(sourceCell);\n if (sourceMetadata) {\n this.workbookManager.setCellMetadata(targetCell, { ...sourceMetadata });\n } else {\n // Clear target metadata if source has none\n this.workbookManager.setCellMetadata(targetCell, undefined);\n }\n }\n }\n\n /**\n * Adjust formula references by a specific row/column offset\n */\n private adjustFormulaWithOffset(\n formula: string,\n rowDelta: number,\n colDelta: number\n ): string {\n try {\n const ast = parseFormula(formula.slice(1)); // Remove the \"=\" sign\n\n const adjustedAst = transformAST(ast, (node) => {\n if (node.type === \"reference\") {\n const refNode = node as ReferenceNode;\n return {\n ...refNode,\n address: {\n colIndex: refNode.isAbsolute.col\n ? refNode.address.colIndex\n : refNode.address.colIndex + colDelta,\n rowIndex: refNode.isAbsolute.row\n ? refNode.address.rowIndex\n : refNode.address.rowIndex + rowDelta,\n },\n };\n } else if (node.type === \"range\") {\n const rangeNode = node as RangeNode;\n return {\n ...rangeNode,\n range: {\n start: {\n col: rangeNode.isAbsolute.start.col\n ? rangeNode.range.start.col\n : rangeNode.range.start.col + colDelta,\n row: rangeNode.isAbsolute.start.row\n ? rangeNode.range.start.row\n : rangeNode.range.start.row + rowDelta,\n },\n end: {\n col:\n rangeNode.range.end.col.type === \"number\"\n ? rangeNode.isAbsolute.end.col\n ? rangeNode.range.end.col\n : {\n type: \"number\" as const,\n value: rangeNode.range.end.col.value + colDelta,\n }\n : rangeNode.range.end.col,\n row:\n rangeNode.range.end.row.type === \"number\"\n ? rangeNode.isAbsolute.end.row\n ? rangeNode.range.end.row\n : {\n type: \"number\" as const,\n value: rangeNode.range.end.row.value + rowDelta,\n }\n : rangeNode.range.end.row,\n },\n },\n };\n }\n return node;\n });\n\n return `=${astToString(adjustedAst)}`;\n } catch (error) {\n // If parsing fails, return the original formula\n console.warn(\"Failed to adjust formula with offset:\", error);\n return formula;\n }\n }\n\n /**\n * Copy formatting from one cell to another\n * Clears existing cell styles at target (Excel behavior) before copying new ones\n */\n private copyCellFormatting(\n sourceCell: CellAddress,\n targetCell: CellAddress\n ): void {\n // STEP 1: Clear existing cell styles at target cell (Excel-like replacement)\n const targetCellRange: RangeAddress = {\n workbookName: targetCell.workbookName,\n sheetName: targetCell.sheetName,\n range: {\n start: { col: targetCell.colIndex, row: targetCell.rowIndex },\n end: {\n col: { type: \"number\", value: targetCell.colIndex },\n row: { type: \"number\", value: targetCell.rowIndex },\n },\n },\n };\n\n this.styleManager.clearCellStylesInRange(targetCellRange);\n\n // Get all styles that intersect with the source cell\n const allConditionalStyles = this.styleManager.getAllConditionalStyles();\n const allCellStyles = this.styleManager.getAllCellStyles();\n\n const sourceCellRange: SpreadsheetRange = {\n start: { col: sourceCell.colIndex, row: sourceCell.rowIndex },\n end: {\n col: { type: \"number\", value: sourceCell.colIndex },\n row: { type: \"number\", value: sourceCell.rowIndex },\n },\n };\n\n // STEP 2: Copy conditional styles that apply to source cell\n for (const style of allConditionalStyles) {\n for (const area of style.areas) {\n if (\n area.workbookName === sourceCell.workbookName &&\n area.sheetName === sourceCell.sheetName\n ) {\n const intersection = intersectRanges(area.range, sourceCellRange);\n if (intersection) {\n // Apply style to target cell\n const newStyle: ConditionalStyle = {\n areas: [\n {\n workbookName: targetCell.workbookName,\n sheetName: targetCell.sheetName,\n range: {\n start: {\n col: targetCell.colIndex,\n row: targetCell.rowIndex,\n },\n end: {\n col: { type: \"number\", value: targetCell.colIndex },\n row: { type: \"number\", value: targetCell.rowIndex },\n },\n },\n },\n ],\n condition: style.condition,\n };\n this.styleManager.addConditionalStyle(newStyle);\n }\n }\n }\n }\n\n // STEP 3: Copy cell styles that apply to source cell\n for (const style of allCellStyles) {\n for (const area of style.areas) {\n if (\n area.workbookName === sourceCell.workbookName &&\n area.sheetName === sourceCell.sheetName\n ) {\n const intersection = intersectRanges(area.range, sourceCellRange);\n if (intersection) {\n // Apply style to target cell\n const newStyle: DirectCellStyle = {\n areas: [\n {\n workbookName: targetCell.workbookName,\n sheetName: targetCell.sheetName,\n range: {\n start: {\n col: targetCell.colIndex,\n row: targetCell.rowIndex,\n },\n end: {\n col: { type: \"number\", value: targetCell.colIndex },\n row: { type: \"number\", value: targetCell.rowIndex },\n },\n },\n },\n ],\n style: style.style,\n };\n this.styleManager.addCellStyle(newStyle);\n }\n }\n }\n }\n }\n}\n"
|
|
6
6
|
],
|
|
7
|
-
"mappings": "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",
|
|
8
|
-
"debugId": "
|
|
7
|
+
"mappings": "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",
|
|
8
|
+
"debugId": "566F5D8EB2A3D66C64756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/core/types.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"/**\n * Core type definitions for FormulaEngine\n * This file contains all fundamental types used throughout the engine\n */\n\nimport type { EvaluationContext } from \"../evaluator/evaluation-context.cjs\";\nimport type { FormulaEvaluator } from \"../evaluator/formula-evaluator.cjs\";\nimport type { FunctionNode } from \"../parser/ast.cjs\";\nimport type { DependencyNode } from \"./managers/dependency-node.cjs\";\nimport type { LookupOrder } from \"./managers/range-eval-order-builder.cjs\";\n\n// Cell addressing types\nexport interface CellAddress {\n sheetName: string;\n workbookName: string;\n colIndex: number;\n rowIndex: number;\n}\n\nexport interface RangeAddress {\n sheetName: string;\n workbookName: string;\n range: SpreadsheetRange;\n}\n\nexport interface LocalCellAddress {\n colIndex: number;\n rowIndex: number;\n}\n\nexport type ArethmeticEvaluator = (\n left: CellValue,\n right: CellValue,\n context: EvaluationContext\n) => CellValue | ErrorEvaluationResult;\n\nexport type PositiveInfinity = {\n type: \"infinity\";\n sign: \"positive\";\n};\n\nexport type CellInfinity = {\n type: \"infinity\";\n sign: \"positive\" | \"negative\";\n};\n\nexport type CellNumber = {\n type: \"number\";\n value: number;\n};\n\nexport type SpreadsheetRangeEnd = CellNumber | PositiveInfinity;\n\nexport type SpreadsheetRange = {\n start: {\n col: number;\n row: number;\n };\n end: {\n col: SpreadsheetRangeEnd;\n row: SpreadsheetRangeEnd;\n };\n};\n\nexport type RelativeRange = {\n start: {\n col: number;\n row: number;\n };\n width: SpreadsheetRangeEnd;\n height: SpreadsheetRangeEnd;\n};\n\nexport type FiniteSpreadsheetRange = {\n start: {\n col: number;\n row: number;\n };\n end: {\n col: number;\n row: number;\n };\n};\n\nexport type CellString = {\n type: \"string\";\n value: string;\n};\n\nexport type CellBoolean = {\n type: \"boolean\";\n value: boolean;\n};\n\n// Cell value types\nexport type CellValue = CellNumber | CellString | CellBoolean | CellInfinity;\n/**\n * undefined and \"\" are considered empty values\n * undefineds are converted to \"\" in the engine\n *\n * any empty values are deleted from the sheet content\n */\nexport type SerializedCellValue = string | number | boolean | undefined;\n\n\n// Named expressions\nexport interface NamedExpression {\n name: string;\n expression: string;\n}\n\nexport interface TableDefinition {\n name: string;\n start: {\n rowIndex: number;\n colIndex: number;\n };\n headers: Map<string, { name: string; index: number }>;\n endRow: SpreadsheetRangeEnd;\n sheetName: string;\n workbookName: string;\n}\n\n// Formula errors\nexport enum FormulaError {\n DIV0 = \"#DIV/0!\",\n NA = \"#N/A\",\n NAME = \"#NAME?\",\n NUM = \"#NUM!\",\n REF = \"#REF!\",\n VALUE = \"#VALUE!\",\n CYCLE = \"#CYCLE!\",\n ERROR = \"#ERROR!\",\n SPILL = \"#SPILL!\",\n}\n\n// Sheet structure\nexport interface Sheet<TCellMetadata = unknown, TSheetMetadata = unknown> {\n name: string;\n index: number; // 0-based index of the sheet\n content: Map<string, SerializedCellValue>;\n /**\n * Cell metadata - arbitrary consumer-defined data per cell\n * Examples: rich text content, links, comments, custom app data\n * The engine stores and copies this data but doesn't interpret it\n * Keyed by cell reference (e.g., \"A1\")\n */\n metadata: Map<string, TCellMetadata>;\n /**\n * Sheet-level metadata - arbitrary consumer-defined data for the entire sheet\n * Examples: text boxes, drawings, frozen panes, print settings\n * The engine stores and copies this data but doesn't interpret it\n */\n sheetMetadata: TSheetMetadata;\n}\n\nexport interface Workbook<TCellMetadata = unknown, TSheetMetadata = unknown, TWorkbookMetadata = unknown> {\n name: string;\n sheets: Map<string, Sheet<TCellMetadata, TSheetMetadata>>;\n /**\n * Workbook-level metadata - arbitrary consumer-defined data for the entire workbook\n * Examples: themes, custom ribbons, document properties, workbook settings\n * The engine stores and copies this data but doesn't interpret it\n */\n workbookMetadata: TWorkbookMetadata;\n}\n\n/**\n * Tracked reference - a stable reference to a range that updates automatically\n * when workbooks/sheets are renamed and becomes invalid when they're deleted\n */\nexport interface TrackedReference {\n id: string; // UUID\n address: RangeAddress; // The range being tracked\n isValid: boolean; // False if sheet/workbook deleted\n}\n\nexport type ValueEvaluationResult = {\n type: \"value\";\n result: CellValue;\n /**\n * If the terminating evaluation result is a reference (see evaluateReference)\n * then we store information about the source cell for context dependent functions like CELL\n */\n sourceCell?: CellAddress;\n};\n\nexport type AwaitingEvaluationResult = {\n type: \"awaiting-evaluation\";\n waitingFor: DependencyNode;\n errAddress: DependencyNode;\n /**\n * If the terminating evaluation result is a reference (see evaluateReference)\n * then we store information about the source cell for context dependent functions like CELL\n */\n sourceCell?: CellAddress;\n};\n\nexport type DoesNotSpillResult = {\n type: \"does-not-spill\";\n};\n\nexport type ErrorEvaluationResult =\n | {\n type: \"error\";\n err: FormulaError;\n errAddress: DependencyNode;\n message: string;\n /**\n * If the terminating evaluation result is a reference (see evaluateReference)\n * then we store information about the source cell for context dependent functions like CELL\n */\n sourceCell?: CellAddress;\n }\n | AwaitingEvaluationResult;\n\nexport type SingleEvaluationResult =\n | ValueEvaluationResult\n | ErrorEvaluationResult;\n\nexport type SpilledValuesEvaluator = (\n spillOffset: { x: number; y: number },\n context: EvaluationContext\n) => SingleEvaluationResult;\n\nexport type SpilledValuesEvaluationResult = {\n type: \"spilled-values\";\n\n /**\n * When a raw range is evaluated, we will add it to the sourceRange so it can be used e.g. for context dependent functions\n */\n sourceRange?: RangeAddress;\n\n /**\n * If the terminating evaluation result is a reference (see evaluateReference)\n * then we store information about the source cell for context dependent functions like CELL\n * sourceCell will only be defined on a spilledValue when a single value is looked up,\n */\n sourceCell?: CellAddress;\n\n spillArea: (origin: CellAddress) => SpreadsheetRange;\n /**\n * for debugging we add a source string to denote where the spilled values were created\n */\n source: string;\n evaluate: SpilledValuesEvaluator;\n /**\n * evaluateAllCells evaluates all non-empty cells in the spilled range.\n * Because a spilled range can be open-ended, we need to have logic for which cells we should evaluate.\n * e.g. when evaluating a range such as D:D only the cells in the current sheet residing in\n * column D should be evaluated and cells producing spilled values that spill onto D:D.\n *\n * In order to evaluate spilled cells in D:D the range evaluateAllCells need to get all cells in the\n * the intersection of the spilled range and D:D, for that reason evaluateAllCells gets an intersection parameter,\n * where the intersection is relative to the origin.\n *\n * #### Producers:\n * In e.g. SEQUENCE and evaluateRange we have logic for which cells in a spilled range we should evaluate,\n *\n * #### Nesting:\n * e.g. evaluation of scalar operators where we want to nest e.g. `5 * right.evaluate()`\n * can be implemented by calling\n * ```ts\n * const vals = child.evaluateAllCells.call(this, options);\n * return vals.map(val => ({ ...val, result: 5 * val.result }));\n * ```\n *\n * #### Consumers:\n * Only functions that need access to all spilled values in a range end up calling evaluateAllCells, e.g.\n * SUM, MIN, MAX, MATCH. Other types of functions like INDEX doesn't need to evaluate all cells in a range,\n * but does a lookup into a spilled range using the evaluate method.\n *\n */\n evaluateAllCells: (\n this: FormulaEvaluator,\n options: {\n /**\n * an intersection relative to the origin\n */\n intersection?: SpreadsheetRange;\n evaluate: SpilledValuesEvaluator;\n context: EvaluationContext;\n /**\n * origin is the cell address that the spilled range is spilled from\n * e.g. in A3=B2:B4 the origin is A3\n */\n origin: CellAddress;\n\n lookupOrder: LookupOrder;\n }\n ) => EvaluateAllCellsResult;\n};\n\nexport type EvaluateAllCellsResult =\n | ErrorEvaluationResult\n | {\n type: \"values\";\n values: CellInRangeResult[];\n };\n\nexport type CellInRangeResult = {\n result: SingleEvaluationResult;\n relativePos: { x: number; y: number };\n};\n\nexport type FunctionEvaluationResult =\n | SingleEvaluationResult\n | SpilledValuesEvaluationResult;\n\nexport type SpilledValue = {\n /**\n * spillOnto is the range that the spilled value is spilled onto\n */\n spillOnto: SpreadsheetRange;\n /**\n * origin is the cell address that the spilled value is spilled from\n */\n origin: CellAddress;\n};\n\n/**\n * Function definition\n */\nexport interface FunctionDefinition {\n name: string;\n evaluate: (\n this: FormulaEvaluator,\n node: FunctionNode,\n context: EvaluationContext\n ) => FunctionEvaluationResult;\n aliases?: string[];\n}\n\n/**\n * Evaluation result\n */\nexport type EvaluationResult = {\n dependencies: Set<string>;\n} & FunctionEvaluationResult;\n\nexport type SCC = {\n id: number;\n nodes: Set<DependencyNode>; // All nodes considering soft + hard edges\n evaluationOrder: DependencyNode[]; // Flat topologically ordered list\n resolved: boolean;\n hardEdgeSCCs: Set<DependencyNode>[]; // SCCs formed by only hard edges (regular dependencies)\n};\n\nexport type SCCDAG = {\n sccList: SCC[];\n sccGraph: Map<number, Set<number>>; // Adjacency list of SCC dependencies\n};\n\nexport type EvaluationOrder = {\n evaluationOrder: Set<DependencyNode>;\n hasCycle: boolean;\n cycleNodes?: Set<DependencyNode>;\n hash: string;\n sccDAG?: SCCDAG;\n};\n\n// Conditional Styling types\nexport interface LCHColor {\n l: number; // Lightness: 0-100\n c: number; // Chroma: 0-150+\n h: number; // Hue: 0-360\n}\n\nexport interface FormulaStyleCondition {\n type: \"formula\";\n formula: string;\n color: LCHColor;\n}\n\nexport interface GradientStyleCondition {\n type: \"gradient\";\n min:\n | { type: \"lowest_value\"; color: LCHColor }\n | { type: \"number\"; color: LCHColor; valueFormula: string };\n max:\n | { type: \"highest_value\"; color: LCHColor }\n | { type: \"number\"; color: LCHColor; valueFormula: string };\n}\n\nexport type StyleCondition = FormulaStyleCondition | GradientStyleCondition;\n\nexport interface ConditionalStyle {\n areas: RangeAddress[];\n condition: StyleCondition;\n}\n\nexport interface DirectCellStyle {\n areas: RangeAddress[];\n style: CellStyle\n}\n\nexport interface CellStyle {\n backgroundColor?: string; // Hex color format\n color?: string; // Text color in hex format\n fontSize?: number; // Font size in pixels\n bold?: boolean;\n italic?: boolean;\n underline?: boolean;\n}\n\nexport interface CopyCellsOptions {\n /**\n * Whether this is a cut operation (clears source cells after copying)\n * @default false\n */\n cut?: boolean;\n /**\n * What to include in the copy operation.\n * - Use 'all' as shorthand for ['content', 'style', 'metadata']\n * - Use array for fine-grained control over what to copy:\n * - ['content'] - copy only values/formulas\n * - ['style'] - copy only formatting\n * - ['metadata'] - copy only metadata (rich text, links, etc.)\n * - ['content', 'style'] - copy content and formatting\n * - ['content', 'metadata'] - copy content and metadata\n * - ['style', 'metadata'] - copy formatting and metadata\n * - ['content', 'style', 'metadata'] - same as 'all'\n * @default 'all'\n */\n include?: 'all' | ('content' | 'style' | 'metadata')[];\n /**\n * The type of the content to copy\n * value: Copy the value from the source to the target,\n * e.g. if the cell has the formula =123 + 123 then the value is 246\n * formula: Copy the formula from the source to the target,\n * e.g. if the cell has the formula =123 + 123 then the formula is =123 + 123 is copied\n * @default 'formula'\n */\n type?: \"value\" | \"formula\";\n}\n"
|
|
5
|
+
"/**\n * Core type definitions for FormulaEngine\n * This file contains all fundamental types used throughout the engine\n */\n\nimport type { EvaluationContext } from \"../evaluator/evaluation-context.cjs\";\nimport type { FormulaEvaluator } from \"../evaluator/formula-evaluator.cjs\";\nimport type { FunctionNode } from \"../parser/ast.cjs\";\nimport type { DependencyNode } from \"./managers/dependency-node.cjs\";\nimport type { LookupOrder } from \"./managers/range-eval-order-builder.cjs\";\n\n// Cell addressing types\nexport interface CellAddress {\n sheetName: string;\n workbookName: string;\n colIndex: number;\n rowIndex: number;\n}\n\nexport interface RangeAddress {\n sheetName: string;\n workbookName: string;\n range: SpreadsheetRange;\n}\n\nexport interface LocalCellAddress {\n colIndex: number;\n rowIndex: number;\n}\n\nexport type ArethmeticEvaluator = (\n left: CellValue,\n right: CellValue,\n context: EvaluationContext\n) => CellValue | ErrorEvaluationResult;\n\nexport type PositiveInfinity = {\n type: \"infinity\";\n sign: \"positive\";\n};\n\nexport type CellInfinity = {\n type: \"infinity\";\n sign: \"positive\" | \"negative\";\n};\n\nexport type CellNumber = {\n type: \"number\";\n value: number;\n};\n\nexport type SpreadsheetRangeEnd = CellNumber | PositiveInfinity;\n\nexport type SpreadsheetRange = {\n start: {\n col: number;\n row: number;\n };\n end: {\n col: SpreadsheetRangeEnd;\n row: SpreadsheetRangeEnd;\n };\n};\n\nexport type RelativeRange = {\n start: {\n col: number;\n row: number;\n };\n width: SpreadsheetRangeEnd;\n height: SpreadsheetRangeEnd;\n};\n\nexport type FiniteSpreadsheetRange = {\n start: {\n col: number;\n row: number;\n };\n end: {\n col: number;\n row: number;\n };\n};\n\nexport type CellString = {\n type: \"string\";\n value: string;\n};\n\nexport type CellBoolean = {\n type: \"boolean\";\n value: boolean;\n};\n\n// Cell value types\nexport type CellValue = CellNumber | CellString | CellBoolean | CellInfinity;\n/**\n * undefined and \"\" are considered empty values\n * undefineds are converted to \"\" in the engine\n *\n * any empty values are deleted from the sheet content\n */\nexport type SerializedCellValue = string | number | boolean | undefined;\n\n// Named expressions\nexport interface NamedExpression {\n name: string;\n expression: string;\n}\n\nexport interface TableDefinition {\n name: string;\n start: {\n rowIndex: number;\n colIndex: number;\n };\n headers: Map<string, { name: string; index: number }>;\n endRow: SpreadsheetRangeEnd;\n sheetName: string;\n workbookName: string;\n}\n\n// Formula errors\nexport enum FormulaError {\n DIV0 = \"#DIV/0!\",\n NA = \"#N/A\",\n NAME = \"#NAME?\",\n NUM = \"#NUM!\",\n REF = \"#REF!\",\n VALUE = \"#VALUE!\",\n CYCLE = \"#CYCLE!\",\n ERROR = \"#ERROR!\",\n SPILL = \"#SPILL!\",\n}\n\n// Sheet structure\nexport interface Sheet<TCellMetadata = unknown, TSheetMetadata = unknown> {\n name: string;\n index: number; // 0-based index of the sheet\n content: Map<string, SerializedCellValue>;\n /**\n * Cell metadata - arbitrary consumer-defined data per cell\n * Examples: rich text content, links, comments, custom app data\n * The engine stores and copies this data but doesn't interpret it\n * Keyed by cell reference (e.g., \"A1\")\n */\n metadata: Map<string, TCellMetadata>;\n /**\n * Sheet-level metadata - arbitrary consumer-defined data for the entire sheet\n * Examples: text boxes, drawings, frozen panes, print settings\n * The engine stores and copies this data but doesn't interpret it\n */\n sheetMetadata: TSheetMetadata;\n}\n\nexport interface Workbook<\n TCellMetadata = unknown,\n TSheetMetadata = unknown,\n TWorkbookMetadata = unknown\n> {\n name: string;\n sheets: Map<string, Sheet<TCellMetadata, TSheetMetadata>>;\n /**\n * Workbook-level metadata - arbitrary consumer-defined data for the entire workbook\n * Examples: themes, custom ribbons, document properties, workbook settings\n * The engine stores and copies this data but doesn't interpret it\n */\n workbookMetadata: TWorkbookMetadata;\n}\n\n/**\n * Tracked reference - a stable reference to a range that updates automatically\n * when workbooks/sheets are renamed and becomes invalid when they're deleted\n */\nexport interface TrackedReference {\n id: string; // UUID\n address: RangeAddress; // The range being tracked\n isValid: boolean; // False if sheet/workbook deleted\n}\n\nexport type ValueEvaluationResult = {\n type: \"value\";\n result: CellValue;\n /**\n * If the terminating evaluation result is a reference (see evaluateReference)\n * then we store information about the source cell for context dependent functions like CELL\n */\n sourceCell?: CellAddress;\n};\n\nexport type AwaitingEvaluationResult = {\n type: \"awaiting-evaluation\";\n waitingFor: DependencyNode;\n errAddress: DependencyNode;\n /**\n * If the terminating evaluation result is a reference (see evaluateReference)\n * then we store information about the source cell for context dependent functions like CELL\n */\n sourceCell?: CellAddress;\n};\n\nexport type DoesNotSpillResult = {\n type: \"does-not-spill\";\n};\n\nexport type ErrorEvaluationResult =\n | {\n type: \"error\";\n err: FormulaError;\n errAddress: DependencyNode;\n message: string;\n /**\n * If the terminating evaluation result is a reference (see evaluateReference)\n * then we store information about the source cell for context dependent functions like CELL\n */\n sourceCell?: CellAddress;\n }\n | AwaitingEvaluationResult;\n\nexport type SingleEvaluationResult =\n | ValueEvaluationResult\n | ErrorEvaluationResult;\n\nexport type SpilledValuesEvaluator = (\n spillOffset: { x: number; y: number },\n context: EvaluationContext\n) => SingleEvaluationResult;\n\nexport type SpilledValuesEvaluationResult = {\n type: \"spilled-values\";\n\n /**\n * When a raw range is evaluated, we will add it to the sourceRange so it can be used e.g. for context dependent functions\n */\n sourceRange?: RangeAddress;\n\n /**\n * If the terminating evaluation result is a reference (see evaluateReference)\n * then we store information about the source cell for context dependent functions like CELL\n * sourceCell will only be defined on a spilledValue when a single value is looked up,\n */\n sourceCell?: CellAddress;\n\n spillArea: (origin: CellAddress) => SpreadsheetRange;\n /**\n * for debugging we add a source string to denote where the spilled values were created\n */\n source: string;\n evaluate: SpilledValuesEvaluator;\n /**\n * evaluateAllCells evaluates all non-empty cells in the spilled range.\n * Because a spilled range can be open-ended, we need to have logic for which cells we should evaluate.\n * e.g. when evaluating a range such as D:D only the cells in the current sheet residing in\n * column D should be evaluated and cells producing spilled values that spill onto D:D.\n *\n * In order to evaluate spilled cells in D:D the range evaluateAllCells need to get all cells in the\n * the intersection of the spilled range and D:D, for that reason evaluateAllCells gets an intersection parameter,\n * where the intersection is relative to the origin.\n *\n * #### Producers:\n * In e.g. SEQUENCE and evaluateRange we have logic for which cells in a spilled range we should evaluate,\n *\n * #### Nesting:\n * e.g. evaluation of scalar operators where we want to nest e.g. `5 * right.evaluate()`\n * can be implemented by calling\n * ```ts\n * const vals = child.evaluateAllCells.call(this, options);\n * return vals.map(val => ({ ...val, result: 5 * val.result }));\n * ```\n *\n * #### Consumers:\n * Only functions that need access to all spilled values in a range end up calling evaluateAllCells, e.g.\n * SUM, MIN, MAX, MATCH. Other types of functions like INDEX doesn't need to evaluate all cells in a range,\n * but does a lookup into a spilled range using the evaluate method.\n *\n */\n evaluateAllCells: (\n this: FormulaEvaluator,\n options: {\n /**\n * an intersection relative to the origin\n */\n intersection?: SpreadsheetRange;\n evaluate: SpilledValuesEvaluator;\n context: EvaluationContext;\n /**\n * origin is the cell address that the spilled range is spilled from\n * e.g. in A3=B2:B4 the origin is A3\n */\n origin: CellAddress;\n\n lookupOrder: LookupOrder;\n }\n ) => EvaluateAllCellsResult;\n};\n\nexport type EvaluateAllCellsResult =\n | ErrorEvaluationResult\n | {\n type: \"values\";\n values: CellInRangeResult[];\n };\n\nexport type CellInRangeResult = {\n result: SingleEvaluationResult;\n relativePos: { x: number; y: number };\n};\n\nexport type FunctionEvaluationResult =\n | SingleEvaluationResult\n | SpilledValuesEvaluationResult;\n\nexport type SpilledValue = {\n /**\n * spillOnto is the range that the spilled value is spilled onto\n */\n spillOnto: SpreadsheetRange;\n /**\n * origin is the cell address that the spilled value is spilled from\n */\n origin: CellAddress;\n};\n\n/**\n * Function definition\n */\nexport interface FunctionDefinition {\n name: string;\n evaluate: (\n this: FormulaEvaluator,\n node: FunctionNode,\n context: EvaluationContext\n ) => FunctionEvaluationResult;\n aliases?: string[];\n}\n\n/**\n * Evaluation result\n */\nexport type EvaluationResult = {\n dependencies: Set<string>;\n} & FunctionEvaluationResult;\n\nexport type SCC = {\n id: number;\n nodes: Set<DependencyNode>; // All nodes considering soft + hard edges\n evaluationOrder: DependencyNode[]; // Flat topologically ordered list\n resolved: boolean;\n hardEdgeSCCs: Set<DependencyNode>[]; // SCCs formed by only hard edges (regular dependencies)\n};\n\nexport type SCCDAG = {\n sccList: SCC[];\n sccGraph: Map<number, Set<number>>; // Adjacency list of SCC dependencies\n};\n\nexport type EvaluationOrder = {\n evaluationOrder: Set<DependencyNode>;\n hasCycle: boolean;\n cycleNodes?: Set<DependencyNode>;\n hash: string;\n sccDAG?: SCCDAG;\n};\n\n// Conditional Styling types\nexport interface LCHColor {\n l: number; // Lightness: 0-100\n c: number; // Chroma: 0-150+\n h: number; // Hue: 0-360\n}\n\nexport interface FormulaStyleCondition {\n type: \"formula\";\n formula: string;\n color: LCHColor;\n}\n\nexport interface GradientStyleCondition {\n type: \"gradient\";\n min:\n | { type: \"lowest_value\"; color: LCHColor }\n | { type: \"number\"; color: LCHColor; valueFormula: string };\n max:\n | { type: \"highest_value\"; color: LCHColor }\n | { type: \"number\"; color: LCHColor; valueFormula: string };\n}\n\nexport type StyleCondition = FormulaStyleCondition | GradientStyleCondition;\n\nexport interface ConditionalStyle {\n areas: RangeAddress[];\n condition: StyleCondition;\n}\n\nexport interface DirectCellStyle {\n areas: RangeAddress[];\n style: CellStyle;\n}\n\nexport interface CellStyle {\n backgroundColor?: string; // Hex color format\n color?: string; // Text color in hex format\n fontSize?: number; // Font size in pixels\n bold?: boolean;\n italic?: boolean;\n underline?: boolean;\n}\n\nexport interface CopyCellsOptions {\n /**\n * Whether this is a cut operation (clears source cells after copying)\n * @default false\n */\n cut?: boolean;\n /**\n * What to include in the copy operation.\n * - Use 'all' as shorthand for ['content', 'style', 'metadata']\n * - Use array for fine-grained control over what to copy:\n * - ['content'] - copy only values/formulas\n * - ['style'] - copy only formatting\n * - ['metadata'] - copy only metadata (rich text, links, etc.)\n * - ['content', 'style'] - copy content and formatting\n * - ['content', 'metadata'] - copy content and metadata\n * - ['style', 'metadata'] - copy formatting and metadata\n * - ['content', 'style', 'metadata'] - same as 'all'\n * @default 'all'\n */\n include?: \"all\" | (\"content\" | \"style\" | \"metadata\")[];\n /**\n * The type of the content to copy\n * value: Copy the value from the source to the target,\n * e.g. if the cell has the formula =123 + 123 then the value is 246\n * formula: Copy the formula from the source to the target,\n * e.g. if the cell has the formula =123 + 123 then the formula is =123 + 123 is copied\n * @default 'formula'\n */\n type?: \"value\" | \"formula\";\n}\n"
|
|
6
6
|
],
|
|
7
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
7
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2HO,IAAK;AAAA,CAAL,CAAK,kBAAL;AAAA,EACL,wBAAO;AAAA,EACP,sBAAK;AAAA,EACL,wBAAO;AAAA,EACP,uBAAM;AAAA,EACN,uBAAM;AAAA,EACN,yBAAQ;AAAA,EACR,yBAAQ;AAAA,EACR,yBAAQ;AAAA,EACR,yBAAQ;AAAA,GATE;",
|
|
8
8
|
"debugId": "F54C7C141D21E24164756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|
package/dist/cjs/lib.cjs
CHANGED
|
@@ -46,12 +46,23 @@ var __export = (target, all) => {
|
|
|
46
46
|
// src/lib.ts
|
|
47
47
|
var exports_lib = {};
|
|
48
48
|
__export(exports_lib, {
|
|
49
|
-
|
|
49
|
+
defineApi: () => import_api.defineApi,
|
|
50
|
+
createApi: () => import_api.createApi,
|
|
51
|
+
TableOrm: () => import_table_orm.TableOrm,
|
|
52
|
+
SchemaValidationError: () => import_api_schema_manager.SchemaValidationError,
|
|
53
|
+
SchemaIntegrityError: () => import_command_executor.SchemaIntegrityError,
|
|
54
|
+
FormulaEngine: () => import_engine.FormulaEngine,
|
|
55
|
+
CellOrm: () => import_cell_orm.CellOrm
|
|
50
56
|
});
|
|
51
57
|
module.exports = __toCommonJS(exports_lib);
|
|
52
58
|
var import_engine = require("./core/engine.cjs");
|
|
53
59
|
__reExport(exports_lib, require("./core/types.cjs"), module.exports);
|
|
54
60
|
__reExport(exports_lib, require("./core/utils.cjs"), module.exports);
|
|
55
61
|
__reExport(exports_lib, require("./core/utils/color-utils.cjs"), module.exports);
|
|
62
|
+
var import_api = require("./core/api/api.cjs");
|
|
63
|
+
var import_table_orm = require("./core/api/table-orm.cjs");
|
|
64
|
+
var import_cell_orm = require("./core/api/cell-orm.cjs");
|
|
65
|
+
var import_api_schema_manager = require("./core/managers/api-schema-manager.cjs");
|
|
66
|
+
var import_command_executor = require("./core/commands/command-executor.cjs");
|
|
56
67
|
|
|
57
|
-
//# debugId=
|
|
68
|
+
//# debugId=D4C7FF28839214A564756E2164756E21
|
package/dist/cjs/lib.cjs.map
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/lib.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"export { FormulaEngine } from \"./core/engine.cjs\";\nexport * from \"./core/types.cjs\";\nexport * from \"./core/utils.cjs\";\nexport * from \"./core/utils/color-utils.cjs\";\n"
|
|
5
|
+
"export { FormulaEngine } from \"./core/engine.cjs\";\nexport * from \"./core/types.cjs\";\nexport * from \"./core/utils.cjs\";\nexport * from \"./core/utils/color-utils.cjs\";\n\n// API Schema exports\nexport { defineApi, createApi } from \"./core/api/api.cjs\";\nexport type { CreateApi, Declaration, Api, TableApi, CellApi } from \"./core/api/api.cjs\";\nexport { TableOrm } from \"./core/api/table-orm.cjs\";\nexport { CellOrm } from \"./core/api/cell-orm.cjs\";\nexport { SchemaValidationError } from \"./core/managers/api-schema-manager.cjs\";\nexport type { ValidationResult } from \"./core/managers/api-schema-manager.cjs\";\n\n// Command Pattern exports\nexport { SchemaIntegrityError } from \"./core/commands/command-executor.cjs\";\nexport type { EngineAction, EngineCommand } from \"./core/commands/types.cjs\";\n"
|
|
6
6
|
],
|
|
7
|
-
"mappings": "
|
|
8
|
-
"debugId": "
|
|
7
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAA8B,IAA9B;AACA;AACA;AACA;AAGqC,IAArC;AAEyB,IAAzB;AACwB,IAAxB;AACsC,IAAtC;AAIqC,IAArC;",
|
|
8
|
+
"debugId": "D4C7FF28839214A564756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|
package/dist/cjs/package.json
CHANGED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
// src/core/api/api-builder.ts
|
|
2
|
+
import { TableOrm } from "./table-orm.mjs";
|
|
3
|
+
import { CellOrm } from "./cell-orm.mjs";
|
|
4
|
+
function buildApiFromDeclaration(engine, declaration, schemaManager) {
|
|
5
|
+
const api = {};
|
|
6
|
+
for (const [namespace, def] of Object.entries(declaration)) {
|
|
7
|
+
if (def.type === "table") {
|
|
8
|
+
api[namespace] = buildTableApi(engine, namespace, def, schemaManager);
|
|
9
|
+
} else if (def.type === "cell") {
|
|
10
|
+
api[namespace] = buildCellApi(engine, namespace, def, schemaManager);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
return api;
|
|
14
|
+
}
|
|
15
|
+
function buildTableApi(engine, namespace, def, schemaManager) {
|
|
16
|
+
schemaManager.registerTableSchema(namespace, def.workbookName, def.tableName, def.headers);
|
|
17
|
+
const orm = new TableOrm(engine, def.workbookName, def.tableName, def.headers, namespace);
|
|
18
|
+
const boundMethods = {};
|
|
19
|
+
for (const [methodName, methodFn] of Object.entries(def.methods)) {
|
|
20
|
+
boundMethods[methodName] = methodFn.bind(orm);
|
|
21
|
+
}
|
|
22
|
+
return boundMethods;
|
|
23
|
+
}
|
|
24
|
+
function buildCellApi(engine, namespace, def, schemaManager) {
|
|
25
|
+
schemaManager.registerCellSchema(namespace, def.cellAddress, def.parse);
|
|
26
|
+
const orm = new CellOrm(engine, def.cellAddress, def.parse, namespace);
|
|
27
|
+
const boundMethods = {};
|
|
28
|
+
for (const [methodName, methodFn] of Object.entries(def.methods)) {
|
|
29
|
+
boundMethods[methodName] = methodFn.bind(orm);
|
|
30
|
+
}
|
|
31
|
+
return boundMethods;
|
|
32
|
+
}
|
|
33
|
+
export {
|
|
34
|
+
buildApiFromDeclaration
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
//# debugId=D8642EAD6BFC352164756E2164756E21
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/core/api/api-builder.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"/**\n * API Builder - Constructs the working API from declarations\n *\n * This module is responsible for creating the actual working API\n * from the schema declarations when attached to a FormulaEngine.\n */\n\nimport type { FormulaEngine } from \"../engine.mjs\";\nimport type { Declaration, TableApi, CellApi, Api } from \"./api.mjs\";\nimport { TableOrm } from \"./table-orm.mjs\";\nimport { CellOrm } from \"./cell-orm.mjs\";\nimport type { ApiSchemaManager } from \"../managers/api-schema-manager.mjs\";\n\n/**\n * Build the working API surface from declarations\n *\n * This creates TableOrm and CellOrm instances for each declared schema\n * and binds the custom methods to them.\n */\nexport function buildApiFromDeclaration(\n engine: FormulaEngine<any, any>,\n declaration: Declaration,\n schemaManager: ApiSchemaManager\n): Api {\n const api: Api = {};\n\n for (const [namespace, def] of Object.entries(declaration)) {\n if (def.type === \"table\") {\n api[namespace] = buildTableApi(engine, namespace, def, schemaManager);\n } else if (def.type === \"cell\") {\n api[namespace] = buildCellApi(engine, namespace, def, schemaManager);\n }\n }\n\n return api;\n}\n\n/**\n * Build API methods for a table schema\n */\nfunction buildTableApi(\n engine: FormulaEngine<any, any>,\n namespace: string,\n def: TableApi,\n schemaManager: ApiSchemaManager\n): Record<string, (...args: any[]) => any> {\n // Register the schema with the schema manager\n schemaManager.registerTableSchema(\n namespace,\n def.workbookName,\n def.tableName,\n def.headers\n );\n\n // Create the ORM instance\n const orm = new TableOrm(\n engine,\n def.workbookName,\n def.tableName,\n def.headers,\n namespace\n );\n\n // Bind all custom methods to the ORM instance\n const boundMethods: Record<string, (...args: any[]) => any> = {};\n\n for (const [methodName, methodFn] of Object.entries(def.methods)) {\n boundMethods[methodName] = methodFn.bind(orm);\n }\n\n return boundMethods;\n}\n\n/**\n * Build API methods for a cell schema\n */\nfunction buildCellApi(\n engine: FormulaEngine<any, any>,\n namespace: string,\n def: CellApi,\n schemaManager: ApiSchemaManager\n): Record<string, (...args: any[]) => any> {\n // Register the schema with the schema manager\n schemaManager.registerCellSchema(namespace, def.cellAddress, def.parse);\n\n // Create the ORM instance\n const orm = new CellOrm(engine, def.cellAddress, def.parse, namespace);\n\n // Bind all custom methods to the ORM instance\n const boundMethods: Record<string, (...args: any[]) => any> = {};\n\n for (const [methodName, methodFn] of Object.entries(def.methods)) {\n boundMethods[methodName] = methodFn.bind(orm);\n }\n\n return boundMethods;\n}\n\n"
|
|
6
|
+
],
|
|
7
|
+
"mappings": ";AASA;AACA;AASO,SAAS,uBAAuB,CACrC,QACA,aACA,eACK;AAAA,EACL,MAAM,MAAW,CAAC;AAAA,EAElB,YAAY,WAAW,QAAQ,OAAO,QAAQ,WAAW,GAAG;AAAA,IAC1D,IAAI,IAAI,SAAS,SAAS;AAAA,MACxB,IAAI,aAAa,cAAc,QAAQ,WAAW,KAAK,aAAa;AAAA,IACtE,EAAO,SAAI,IAAI,SAAS,QAAQ;AAAA,MAC9B,IAAI,aAAa,aAAa,QAAQ,WAAW,KAAK,aAAa;AAAA,IACrE;AAAA,EACF;AAAA,EAEA,OAAO;AAAA;AAMT,SAAS,aAAa,CACpB,QACA,WACA,KACA,eACyC;AAAA,EAEzC,cAAc,oBACZ,WACA,IAAI,cACJ,IAAI,WACJ,IAAI,OACN;AAAA,EAGA,MAAM,MAAM,IAAI,SACd,QACA,IAAI,cACJ,IAAI,WACJ,IAAI,SACJ,SACF;AAAA,EAGA,MAAM,eAAwD,CAAC;AAAA,EAE/D,YAAY,YAAY,aAAa,OAAO,QAAQ,IAAI,OAAO,GAAG;AAAA,IAChE,aAAa,cAAc,SAAS,KAAK,GAAG;AAAA,EAC9C;AAAA,EAEA,OAAO;AAAA;AAMT,SAAS,YAAY,CACnB,QACA,WACA,KACA,eACyC;AAAA,EAEzC,cAAc,mBAAmB,WAAW,IAAI,aAAa,IAAI,KAAK;AAAA,EAGtE,MAAM,MAAM,IAAI,QAAQ,QAAQ,IAAI,aAAa,IAAI,OAAO,SAAS;AAAA,EAGrE,MAAM,eAAwD,CAAC;AAAA,EAE/D,YAAY,YAAY,aAAa,OAAO,QAAQ,IAAI,OAAO,GAAG;AAAA,IAChE,aAAa,cAAc,SAAS,KAAK,GAAG;AAAA,EAC9C;AAAA,EAEA,OAAO;AAAA;",
|
|
8
|
+
"debugId": "D8642EAD6BFC352164756E2164756E21",
|
|
9
|
+
"names": []
|
|
10
|
+
}
|