@ricsam/formula-engine 0.0.5 → 0.0.7
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/engine.cjs +62 -2
- package/dist/cjs/core/engine.cjs.map +3 -3
- package/dist/cjs/core/managers/dependency-manager.cjs +32 -39
- package/dist/cjs/core/managers/dependency-manager.cjs.map +3 -3
- package/dist/cjs/core/managers/evaluation-manager.cjs +31 -34
- package/dist/cjs/core/managers/evaluation-manager.cjs.map +3 -3
- package/dist/cjs/core/managers/style-manager.cjs +341 -0
- package/dist/cjs/core/managers/style-manager.cjs.map +10 -0
- package/dist/cjs/core/types.cjs.map +1 -1
- package/dist/cjs/core/utils/color-utils.cjs +137 -0
- package/dist/cjs/core/utils/color-utils.cjs.map +10 -0
- package/dist/cjs/evaluator/dependency-nodes/virtual-cell-value-node.cjs +55 -0
- package/dist/cjs/evaluator/dependency-nodes/virtual-cell-value-node.cjs.map +10 -0
- package/dist/cjs/lib.cjs +2 -1
- package/dist/cjs/lib.cjs.map +3 -3
- package/dist/cjs/package.json +1 -1
- package/dist/mjs/core/engine.mjs +62 -2
- package/dist/mjs/core/engine.mjs.map +3 -3
- package/dist/mjs/core/managers/dependency-manager.mjs +37 -41
- package/dist/mjs/core/managers/dependency-manager.mjs.map +3 -3
- package/dist/mjs/core/managers/evaluation-manager.mjs +31 -34
- package/dist/mjs/core/managers/evaluation-manager.mjs.map +3 -3
- package/dist/mjs/core/managers/style-manager.mjs +315 -0
- package/dist/mjs/core/managers/style-manager.mjs.map +10 -0
- package/dist/mjs/core/types.mjs.map +1 -1
- package/dist/mjs/core/utils/color-utils.mjs +107 -0
- package/dist/mjs/core/utils/color-utils.mjs.map +10 -0
- package/dist/mjs/evaluator/dependency-nodes/virtual-cell-value-node.mjs +25 -0
- package/dist/mjs/evaluator/dependency-nodes/virtual-cell-value-node.mjs.map +10 -0
- package/dist/mjs/lib.mjs +2 -1
- package/dist/mjs/lib.mjs.map +3 -3
- package/dist/mjs/package.json +1 -1
- package/dist/types/core/engine.d.ts +39 -1
- package/dist/types/core/managers/dependency-manager.d.ts +8 -7
- package/dist/types/core/managers/evaluation-manager.d.ts +13 -3
- package/dist/types/core/managers/style-manager.d.ts +92 -0
- package/dist/types/core/types.d.ts +42 -0
- package/dist/types/core/utils/color-utils.d.ts +32 -0
- package/dist/types/evaluator/dependency-nodes/virtual-cell-value-node.d.ts +11 -0
- package/dist/types/lib.d.ts +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __moduleCache = /* @__PURE__ */ new WeakMap;
|
|
6
|
+
var __toCommonJS = (from) => {
|
|
7
|
+
var entry = __moduleCache.get(from), desc;
|
|
8
|
+
if (entry)
|
|
9
|
+
return entry;
|
|
10
|
+
entry = __defProp({}, "__esModule", { value: true });
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function")
|
|
12
|
+
__getOwnPropNames(from).map((key) => !__hasOwnProp.call(entry, key) && __defProp(entry, key, {
|
|
13
|
+
get: () => from[key],
|
|
14
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
15
|
+
}));
|
|
16
|
+
__moduleCache.set(from, entry);
|
|
17
|
+
return entry;
|
|
18
|
+
};
|
|
19
|
+
var __export = (target, all) => {
|
|
20
|
+
for (var name in all)
|
|
21
|
+
__defProp(target, name, {
|
|
22
|
+
get: all[name],
|
|
23
|
+
enumerable: true,
|
|
24
|
+
configurable: true,
|
|
25
|
+
set: (newValue) => all[name] = () => newValue
|
|
26
|
+
});
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
// src/evaluator/dependency-nodes/virtual-cell-value-node.ts
|
|
30
|
+
var exports_virtual_cell_value_node = {};
|
|
31
|
+
__export(exports_virtual_cell_value_node, {
|
|
32
|
+
VirtualCellValueNode: () => VirtualCellValueNode
|
|
33
|
+
});
|
|
34
|
+
module.exports = __toCommonJS(exports_virtual_cell_value_node);
|
|
35
|
+
var import_utils = require("../../core/utils.cjs");
|
|
36
|
+
var import_base_eval_node = require("./base-eval-node.cjs");
|
|
37
|
+
|
|
38
|
+
class VirtualCellValueNode extends import_base_eval_node.BaseEvalNode {
|
|
39
|
+
cellAddress;
|
|
40
|
+
cellValue;
|
|
41
|
+
constructor(key, cellAddress, cellValue) {
|
|
42
|
+
super(key);
|
|
43
|
+
this.cellAddress = cellAddress;
|
|
44
|
+
this.cellValue = cellValue;
|
|
45
|
+
}
|
|
46
|
+
toString() {
|
|
47
|
+
return "virtual:" + import_utils.getCellReference(this.cellAddress);
|
|
48
|
+
}
|
|
49
|
+
spillMeta;
|
|
50
|
+
setSpillMetaNode(node) {
|
|
51
|
+
this.spillMeta = node;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
//# debugId=BDF930D67603C56864756E2164756E21
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/evaluator/dependency-nodes/virtual-cell-value-node.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import type {\n CellAddress,\n SerializedCellValue,\n SingleEvaluationResult,\n} from \"../../core/types.cjs\";\nimport { getCellReference } from \"../../core/utils.cjs\";\nimport { BaseEvalNode } from \"./base-eval-node.cjs\";\nimport type { SpillMetaNode } from \"./spill-meta-node.cjs\";\n\nexport class VirtualCellValueNode extends BaseEvalNode<SingleEvaluationResult> {\n public readonly cellAddress: CellAddress;\n public readonly cellValue: SerializedCellValue;\n\n constructor(\n key: string,\n cellAddress: CellAddress,\n cellValue: SerializedCellValue\n ) {\n super(key);\n\n this.cellAddress = cellAddress;\n this.cellValue = cellValue;\n }\n\n public override toString(): string {\n return \"virtual:\" + getCellReference(this.cellAddress);\n }\n\n spillMeta: SpillMetaNode | undefined;\n\n setSpillMetaNode(node: SpillMetaNode) {\n this.spillMeta = node;\n }\n}\n"
|
|
6
|
+
],
|
|
7
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAKiC,IAAjC;AAC6B,IAA7B;AAAA;AAGO,MAAM,6BAA6B,mCAAqC;AAAA,EAC7D;AAAA,EACA;AAAA,EAEhB,WAAW,CACT,KACA,aACA,WACA;AAAA,IACA,MAAM,GAAG;AAAA,IAET,KAAK,cAAc;AAAA,IACnB,KAAK,YAAY;AAAA;AAAA,EAGH,QAAQ,GAAW;AAAA,IACjC,OAAO,aAAa,8BAAiB,KAAK,WAAW;AAAA;AAAA,EAGvD;AAAA,EAEA,gBAAgB,CAAC,MAAqB;AAAA,IACpC,KAAK,YAAY;AAAA;AAErB;",
|
|
8
|
+
"debugId": "BDF930D67603C56864756E2164756E21",
|
|
9
|
+
"names": []
|
|
10
|
+
}
|
package/dist/cjs/lib.cjs
CHANGED
|
@@ -52,5 +52,6 @@ module.exports = __toCommonJS(exports_lib);
|
|
|
52
52
|
var import_engine = require("./core/engine.cjs");
|
|
53
53
|
__reExport(exports_lib, require("./core/types.cjs"), module.exports);
|
|
54
54
|
__reExport(exports_lib, require("./core/utils.cjs"), module.exports);
|
|
55
|
+
__reExport(exports_lib, require("./core/utils/color-utils.cjs"), module.exports);
|
|
55
56
|
|
|
56
|
-
//# debugId=
|
|
57
|
+
//# debugId=DE8C7DD7D3ED6E6764756E2164756E21
|
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\";\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"
|
|
6
6
|
],
|
|
7
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAA8B,IAA9B;AACA;AACA;",
|
|
8
|
-
"debugId": "
|
|
7
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAA8B,IAA9B;AACA;AACA;AACA;",
|
|
8
|
+
"debugId": "DE8C7DD7D3ED6E6764756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|
package/dist/cjs/package.json
CHANGED
package/dist/mjs/core/engine.mjs
CHANGED
|
@@ -13,6 +13,7 @@ import { TableManager } from "./managers/table-manager.mjs";
|
|
|
13
13
|
import { EventManager } from "./managers/event-manager.mjs";
|
|
14
14
|
import { EvaluationManager } from "./managers/evaluation-manager.mjs";
|
|
15
15
|
import { DependencyManager } from "./managers/dependency-manager.mjs";
|
|
16
|
+
import { StyleManager } from "./managers/style-manager.mjs";
|
|
16
17
|
|
|
17
18
|
class FormulaEngine {
|
|
18
19
|
workbookManager;
|
|
@@ -22,6 +23,7 @@ class FormulaEngine {
|
|
|
22
23
|
evaluationManager;
|
|
23
24
|
autoFillManager;
|
|
24
25
|
dependencyManager;
|
|
26
|
+
styleManager;
|
|
25
27
|
_workbookManager;
|
|
26
28
|
_namedExpressionManager;
|
|
27
29
|
_tableManager;
|
|
@@ -29,6 +31,7 @@ class FormulaEngine {
|
|
|
29
31
|
_evaluationManager;
|
|
30
32
|
_autoFillManager;
|
|
31
33
|
_dependencyManager;
|
|
34
|
+
_styleManager;
|
|
32
35
|
constructor() {
|
|
33
36
|
this.eventManager = new EventManager;
|
|
34
37
|
this.workbookManager = new WorkbookManager;
|
|
@@ -38,6 +41,7 @@ class FormulaEngine {
|
|
|
38
41
|
this.dependencyManager = new DependencyManager(cacheManager, this.workbookManager);
|
|
39
42
|
const formulaEvaluator = new FormulaEvaluator(this.tableManager, this.dependencyManager, this.namedExpressionManager);
|
|
40
43
|
this.evaluationManager = new EvaluationManager(this.workbookManager, this.tableManager, formulaEvaluator, this.dependencyManager);
|
|
44
|
+
this.styleManager = new StyleManager(this.workbookManager, this.evaluationManager);
|
|
41
45
|
this.autoFillManager = new AutoFill(this.workbookManager, this);
|
|
42
46
|
this._workbookManager = this.workbookManager;
|
|
43
47
|
this._namedExpressionManager = this.namedExpressionManager;
|
|
@@ -46,6 +50,7 @@ class FormulaEngine {
|
|
|
46
50
|
this._evaluationManager = this.evaluationManager;
|
|
47
51
|
this._autoFillManager = this.autoFillManager;
|
|
48
52
|
this._dependencyManager = this.dependencyManager;
|
|
53
|
+
this._styleManager = this.styleManager;
|
|
49
54
|
}
|
|
50
55
|
static buildEmpty() {
|
|
51
56
|
return new FormulaEngine;
|
|
@@ -60,6 +65,9 @@ class FormulaEngine {
|
|
|
60
65
|
}
|
|
61
66
|
return this.evaluationManager.evaluationResultToSerializedValue(result, cellAddress, debug);
|
|
62
67
|
}
|
|
68
|
+
evaluateFormula(formula, cellAddress) {
|
|
69
|
+
return this.evaluationManager.evaluateFormula(formula, cellAddress);
|
|
70
|
+
}
|
|
63
71
|
getCellDependents(address) {
|
|
64
72
|
throw new Error("Not implemented");
|
|
65
73
|
}
|
|
@@ -178,6 +186,37 @@ class FormulaEngine {
|
|
|
178
186
|
isCellInTable(cellAddress) {
|
|
179
187
|
return this.tableManager.isCellInTable(cellAddress);
|
|
180
188
|
}
|
|
189
|
+
addConditionalStyle(style) {
|
|
190
|
+
this.styleManager.addConditionalStyle(style);
|
|
191
|
+
this.eventManager.emitUpdate();
|
|
192
|
+
}
|
|
193
|
+
removeConditionalStyle(workbookName, index) {
|
|
194
|
+
const removed = this.styleManager.removeConditionalStyle(workbookName, index);
|
|
195
|
+
if (removed) {
|
|
196
|
+
this.eventManager.emitUpdate();
|
|
197
|
+
}
|
|
198
|
+
return removed;
|
|
199
|
+
}
|
|
200
|
+
getConditionalStyles(workbookName) {
|
|
201
|
+
return this.styleManager.getConditionalStyles(workbookName);
|
|
202
|
+
}
|
|
203
|
+
getCellStyle(cellAddress) {
|
|
204
|
+
return this.styleManager.getCellStyle(cellAddress);
|
|
205
|
+
}
|
|
206
|
+
addCellStyle(style) {
|
|
207
|
+
this.styleManager.addCellStyle(style);
|
|
208
|
+
this.eventManager.emitUpdate();
|
|
209
|
+
}
|
|
210
|
+
removeCellStyle(workbookName, index) {
|
|
211
|
+
const removed = this.styleManager.removeCellStyle(workbookName, index);
|
|
212
|
+
if (removed) {
|
|
213
|
+
this.eventManager.emitUpdate();
|
|
214
|
+
}
|
|
215
|
+
return removed;
|
|
216
|
+
}
|
|
217
|
+
getCellStyles(workbookName) {
|
|
218
|
+
return this.styleManager.getCellStyles(workbookName);
|
|
219
|
+
}
|
|
181
220
|
addSheet(opts) {
|
|
182
221
|
const newSheet = this.workbookManager.addSheet(opts);
|
|
183
222
|
const wbLevel = this.namedExpressionManager.addSheet(opts);
|
|
@@ -189,6 +228,7 @@ class FormulaEngine {
|
|
|
189
228
|
const sheet = this.workbookManager.removeSheet(opts);
|
|
190
229
|
this.namedExpressionManager.removeSheet(opts);
|
|
191
230
|
this.tableManager.removeSheet(opts);
|
|
231
|
+
this.styleManager.removeSheetStyles(opts.workbookName, opts.sheetName);
|
|
192
232
|
this.reevaluate();
|
|
193
233
|
this.eventManager.emitUpdate();
|
|
194
234
|
return sheet;
|
|
@@ -197,6 +237,7 @@ class FormulaEngine {
|
|
|
197
237
|
const sheet = this.workbookManager.renameSheet(opts);
|
|
198
238
|
this.namedExpressionManager.renameSheet(opts);
|
|
199
239
|
this.tableManager.updateTablesForSheetRename(opts);
|
|
240
|
+
this.styleManager.updateSheetName(opts.workbookName, opts.sheetName, opts.newSheetName);
|
|
200
241
|
this.workbookManager.updateAllFormulas((formula) => renameSheetInFormula({
|
|
201
242
|
formula,
|
|
202
243
|
oldSheetName: opts.sheetName,
|
|
@@ -229,6 +270,7 @@ class FormulaEngine {
|
|
|
229
270
|
this.workbookManager.removeWorkbook(workbookName);
|
|
230
271
|
this.namedExpressionManager.removeWorkbook(workbookName);
|
|
231
272
|
this.tableManager.removeWorkbook(workbookName);
|
|
273
|
+
this.styleManager.removeWorkbookStyles(workbookName);
|
|
232
274
|
this.reevaluate();
|
|
233
275
|
this.eventManager.emitUpdate();
|
|
234
276
|
}
|
|
@@ -293,6 +335,7 @@ class FormulaEngine {
|
|
|
293
335
|
this.workbookManager.renameWorkbook(opts);
|
|
294
336
|
this.namedExpressionManager.renameWorkbook(opts);
|
|
295
337
|
this.tableManager.updateTablesForWorkbookRename(opts);
|
|
338
|
+
this.styleManager.updateWorkbookName(opts.workbookName, opts.newWorkbookName);
|
|
296
339
|
this.workbookManager.updateAllFormulas((formula) => renameWorkbookInFormula({
|
|
297
340
|
formula,
|
|
298
341
|
oldWorkbookName: opts.workbookName,
|
|
@@ -329,7 +372,9 @@ class FormulaEngine {
|
|
|
329
372
|
return {
|
|
330
373
|
workbooks: this.workbookManager.getWorkbooks(),
|
|
331
374
|
namedExpressions: this.namedExpressionManager.getNamedExpressions(),
|
|
332
|
-
tables: this.tableManager.tables
|
|
375
|
+
tables: this.tableManager.tables,
|
|
376
|
+
conditionalStyles: this.styleManager.getAllConditionalStyles(),
|
|
377
|
+
cellStyles: this.styleManager.getAllCellStyles()
|
|
333
378
|
};
|
|
334
379
|
}
|
|
335
380
|
onUpdate(listener) {
|
|
@@ -353,6 +398,21 @@ class FormulaEngine {
|
|
|
353
398
|
});
|
|
354
399
|
this.namedExpressionManager.resetNamedExpressions(deserialized.namedExpressions);
|
|
355
400
|
this.tableManager.resetTables(deserialized.tables);
|
|
401
|
+
let conditionalStylesArray;
|
|
402
|
+
let cellStylesArray;
|
|
403
|
+
if (deserialized.conditionalStyles) {
|
|
404
|
+
if (deserialized.conditionalStyles instanceof Map) {
|
|
405
|
+
conditionalStylesArray = Array.from(deserialized.conditionalStyles.values()).flat();
|
|
406
|
+
} else if (Array.isArray(deserialized.conditionalStyles)) {
|
|
407
|
+
conditionalStylesArray = deserialized.conditionalStyles;
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
if (deserialized.cellStyles) {
|
|
411
|
+
if (Array.isArray(deserialized.cellStyles)) {
|
|
412
|
+
cellStylesArray = deserialized.cellStyles;
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
this.styleManager.resetStyles(conditionalStylesArray, cellStylesArray);
|
|
356
416
|
this.reevaluate();
|
|
357
417
|
this.eventManager.emitUpdate();
|
|
358
418
|
}
|
|
@@ -361,4 +421,4 @@ export {
|
|
|
361
421
|
FormulaEngine
|
|
362
422
|
};
|
|
363
423
|
|
|
364
|
-
//# debugId=
|
|
424
|
+
//# debugId=E903EB04E40DB1E764756E2164756E21
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/core/engine.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"/**\n * Main FormulaEngine class\n * Core API implementation for spreadsheet calculations\n */\n\nimport {\n type CellAddress,\n type NamedExpression,\n type RangeAddress,\n type SerializedCellValue,\n type SingleEvaluationResult,\n type SpreadsheetRange,\n type SpreadsheetRangeEnd,\n type TableDefinition,\n} from \"./types.mjs\";\n\nimport type { FillDirection } from \"@ricsam/selection-manager\";\nimport { FormulaEvaluator } from \"../evaluator/formula-evaluator.mjs\";\nimport { AutoFill } from \"./autofill-utils.mjs\";\nimport { WorkbookManager } from \"./managers/workbook-manager.mjs\";\nimport { deserialize, serialize } from \"./map-serializer.mjs\";\nimport { renameNamedExpressionInFormula } from \"./named-expression-renamer.mjs\";\nimport { renameSheetInFormula } from \"./sheet-renamer.mjs\";\nimport { renameTableInFormula } from \"./table-renamer.mjs\";\nimport { renameWorkbookInFormula } from \"./workbook-renamer.mjs\";\nimport { cellAddressToKey, keyToCellAddress } from \"./utils.mjs\";\nimport { CacheManager } from \"./managers/cache-manager.mjs\";\nimport { NamedExpressionManager } from \"./managers/named-expression-manager.mjs\";\nimport { TableManager } from \"./managers/table-manager.mjs\";\nimport { EventManager } from \"./managers/event-manager.mjs\";\nimport { EvaluationManager } from \"./managers/evaluation-manager.mjs\";\nimport { DependencyManager } from \"./managers/dependency-manager.mjs\";\n\n/**\n * Main FormulaEngine class\n */\nexport class FormulaEngine {\n private workbookManager: WorkbookManager;\n private namedExpressionManager: NamedExpressionManager;\n private tableManager: TableManager;\n private eventManager: EventManager;\n private evaluationManager: EvaluationManager;\n private autoFillManager: AutoFill;\n private dependencyManager: DependencyManager;\n\n /**\n * Public access to the store manager for testing\n */\n public _workbookManager: WorkbookManager;\n public _namedExpressionManager: NamedExpressionManager;\n public _tableManager: TableManager;\n public _eventManager: EventManager;\n public _evaluationManager: EvaluationManager;\n public _autoFillManager: AutoFill;\n public _dependencyManager: DependencyManager;\n\n constructor() {\n this.eventManager = new EventManager();\n this.workbookManager = new WorkbookManager();\n this.namedExpressionManager = new NamedExpressionManager();\n this.tableManager = new TableManager(this.workbookManager);\n const cacheManager = new CacheManager();\n this.dependencyManager = new DependencyManager(\n cacheManager,\n this.workbookManager\n );\n\n const formulaEvaluator = new FormulaEvaluator(\n this.tableManager,\n this.dependencyManager,\n this.namedExpressionManager,\n );\n\n this.evaluationManager = new EvaluationManager(\n this.workbookManager,\n this.tableManager,\n formulaEvaluator,\n this.dependencyManager\n );\n\n this.autoFillManager = new AutoFill(this.workbookManager, this);\n\n this._workbookManager = this.workbookManager;\n this._namedExpressionManager = this.namedExpressionManager;\n this._tableManager = this.tableManager;\n this._eventManager = this.eventManager;\n this._evaluationManager = this.evaluationManager;\n this._autoFillManager = this.autoFillManager;\n this._dependencyManager = this.dependencyManager;\n }\n\n /**\n * Static factory method to build an empty engine\n */\n static buildEmpty(): FormulaEngine {\n return new FormulaEngine();\n }\n\n //#region Cell\n getCellEvaluationResult(\n cellAddress: CellAddress\n ): SingleEvaluationResult | undefined {\n return this.evaluationManager.getCellEvaluationResult(cellAddress);\n }\n\n getCellValue(cellAddress: CellAddress, debug?: boolean): SerializedCellValue {\n const result = this.getCellEvaluationResult(cellAddress);\n if (!result) {\n return \"\";\n }\n\n return this.evaluationManager.evaluationResultToSerializedValue(\n result,\n cellAddress,\n debug\n );\n }\n\n getCellDependents(\n address: CellAddress | SpreadsheetRange\n ): (SpreadsheetRange | CellAddress)[] {\n throw new Error(\"Not implemented\");\n }\n\n getCellPrecedents(\n address: CellAddress | SpreadsheetRange\n ): (SpreadsheetRange | CellAddress)[] {\n throw new Error(\"Not implemented\");\n }\n\n //#endregion\n\n //#region Named Expressions\n addNamedExpression({\n expression,\n expressionName,\n sheetName,\n workbookName,\n }: {\n expression: string;\n expressionName: string;\n sheetName?: string;\n workbookName?: string;\n }) {\n this.namedExpressionManager.addNamedExpression({\n expression,\n expressionName,\n sheetName,\n workbookName,\n });\n\n // Re-evaluate all sheets since named expressions can be referenced from anywhere\n this.reevaluate();\n this.eventManager.emitUpdate();\n }\n\n removeNamedExpression({\n expressionName,\n sheetName,\n workbookName,\n }: {\n expressionName: string;\n sheetName?: string;\n workbookName?: string;\n }) {\n const found = this.namedExpressionManager.removeNamedExpression({\n expressionName,\n sheetName,\n workbookName,\n });\n\n if (found) {\n // Re-evaluate all sheets since named expressions can be referenced from anywhere\n this.reevaluate();\n this.eventManager.emitUpdate();\n }\n\n return found;\n }\n\n updateNamedExpression({\n expression,\n expressionName,\n sheetName,\n workbookName,\n }: {\n expression: string;\n expressionName: string;\n sheetName?: string;\n workbookName?: string;\n }) {\n this.namedExpressionManager.updateNamedExpression({\n expression,\n expressionName,\n sheetName,\n workbookName,\n });\n\n // Re-evaluate all sheets since named expressions can be referenced from anywhere\n this.reevaluate();\n this.eventManager.emitUpdate();\n }\n\n renameNamedExpression({\n expressionName,\n sheetName,\n workbookName,\n newName,\n }: {\n expressionName: string;\n sheetName?: string;\n workbookName?: string;\n newName: string;\n }) {\n const result = this.namedExpressionManager.renameNamedExpression({\n expressionName,\n sheetName,\n workbookName,\n newName,\n });\n\n // Update all formulas that reference this named expression in sheet cells\n this.workbookManager.updateAllFormulas((formula) =>\n renameNamedExpressionInFormula(formula, expressionName, newName)\n );\n\n // Update named expressions that reference this named expression\n this.namedExpressionManager.updateAllNamedExpressions((formula) =>\n renameNamedExpressionInFormula(formula, expressionName, newName)\n );\n\n // Re-evaluate all sheets since named expressions can be referenced from anywhere\n this.reevaluate();\n this.eventManager.emitUpdate();\n\n return result;\n }\n\n setNamedExpressions(\n opts: (\n | {\n type: \"global\";\n }\n | {\n type: \"sheet\";\n sheetName: string;\n workbookName: string;\n }\n | {\n type: \"workbook\";\n workbookName: string;\n }\n ) & {\n expressions: Map<string, NamedExpression>;\n }\n ) {\n this.namedExpressionManager.setNamedExpressions(opts);\n\n this.reevaluate();\n this.eventManager.emitUpdate();\n }\n //#endregion\n\n //#region Tables\n addTable(props: {\n tableName: string;\n sheetName: string;\n workbookName: string;\n start: string;\n numRows: SpreadsheetRangeEnd;\n numCols: number;\n }) {\n const table = this.tableManager.addTable({\n ...props,\n getCellValue: (cellAddress: CellAddress) =>\n this.getCellValue(cellAddress),\n });\n\n // Re-evaluate all sheets since structured references might depend on this table\n this.reevaluate();\n this.eventManager.emitUpdate();\n\n return table;\n }\n\n renameTable(\n workbookName: string,\n names: { oldName: string; newName: string }\n ) {\n this.tableManager.renameTable(workbookName, names);\n\n // Update all formulas that reference this table in sheet cells\n this.workbookManager.updateAllFormulas((formula) =>\n renameTableInFormula(formula, names.oldName, names.newName)\n );\n\n // Update named expressions that reference this table\n this.namedExpressionManager.updateAllNamedExpressions((formula) =>\n renameTableInFormula(formula, names.oldName, names.newName)\n );\n\n // Re-evaluate all sheets since structured references might depend on this table\n this.reevaluate();\n this.eventManager.emitUpdate();\n }\n\n updateTable(opts: {\n tableName: string;\n sheetName?: string;\n start?: string;\n numRows?: SpreadsheetRangeEnd;\n numCols?: number;\n workbookName: string;\n }) {\n this.tableManager.updateTable({\n ...opts,\n getCellValue: (cellAddress: CellAddress) =>\n this.getCellValue(cellAddress),\n });\n\n // Re-evaluate all sheets since structured references might depend on this table\n this.reevaluate();\n this.eventManager.emitUpdate();\n }\n\n removeTable(opts: { tableName: string; workbookName: string }) {\n const found = this.tableManager.removeTable(opts);\n\n if (found) {\n // Re-evaluate all sheets since structured references might depend on this table\n this.reevaluate();\n this.eventManager.emitUpdate();\n }\n\n return found;\n }\n\n resetTables(tables: Map<string, Map<string, TableDefinition>>) {\n this.tableManager.resetTables(tables);\n this.reevaluate();\n this.eventManager.emitUpdate();\n }\n\n getTables(workbookName: string) {\n return this.tableManager.getTables(workbookName);\n }\n\n isCellInTable(cellAddress: CellAddress): TableDefinition | undefined {\n return this.tableManager.isCellInTable(cellAddress);\n }\n\n //#endregion\n\n //#region Sheets\n addSheet(opts: { workbookName: string; sheetName: string }) {\n const newSheet = this.workbookManager.addSheet(opts);\n const wbLevel = this.namedExpressionManager.addSheet(opts);\n this.reevaluate();\n this.eventManager.emitUpdate();\n return newSheet;\n }\n\n removeSheet(opts: { workbookName: string; sheetName: string }) {\n const sheet = this.workbookManager.removeSheet(opts);\n\n // Clean up related data\n this.namedExpressionManager.removeSheet(opts);\n this.tableManager.removeSheet(opts);\n\n // Add engine-specific logic: re-evaluate since references might be affected\n this.reevaluate();\n this.eventManager.emitUpdate();\n\n return sheet;\n }\n\n renameSheet(opts: {\n sheetName: string;\n newSheetName: string;\n workbookName: string;\n }) {\n const sheet = this.workbookManager.renameSheet(opts);\n\n // Update scoped named expressions\n this.namedExpressionManager.renameSheet(opts);\n\n // Update tables that belong to the renamed sheet\n this.tableManager.updateTablesForSheetRename(opts);\n\n // Update all formulas that reference this sheet\n this.workbookManager.updateAllFormulas((formula) =>\n renameSheetInFormula({\n formula,\n oldSheetName: opts.sheetName,\n newSheetName: opts.newSheetName,\n })\n );\n\n // Add engine-specific logic: re-evaluate since references might be affected\n this.reevaluate();\n this.eventManager.emitUpdate();\n\n return sheet;\n }\n\n getSheets(workbookName: string) {\n return this.workbookManager.getSheets(workbookName);\n }\n\n getSheet({\n workbookName,\n sheetName,\n }: {\n workbookName: string;\n sheetName: string;\n }) {\n return this.workbookManager.getSheet({ workbookName, sheetName });\n }\n\n getSheetSerialized(opts: {\n sheetName: string;\n workbookName: string;\n }): Map<string, SerializedCellValue> {\n return this.workbookManager.getSheetSerialized(opts);\n }\n\n //#endregion\n\n //#region Workbook\n addWorkbook(workbookName: string) {\n this.workbookManager.addWorkbook(workbookName);\n this.namedExpressionManager.addWorkbook(workbookName);\n this.tableManager.addWorkbook(workbookName);\n\n this.reevaluate();\n this.eventManager.emitUpdate();\n }\n\n removeWorkbook(workbookName: string) {\n this.workbookManager.removeWorkbook(workbookName);\n this.namedExpressionManager.removeWorkbook(workbookName);\n this.tableManager.removeWorkbook(workbookName);\n\n this.reevaluate();\n this.eventManager.emitUpdate();\n }\n\n cloneWorkbook(fromWorkbookName: string, toWorkbookName: string) {\n // Check if source workbook exists\n const sourceWorkbook = this.workbookManager\n .getWorkbooks()\n .get(fromWorkbookName);\n if (!sourceWorkbook) {\n throw new Error(`Source workbook \"${fromWorkbookName}\" not found`);\n }\n\n // Check if target workbook name already exists\n if (this.workbookManager.getWorkbooks().has(toWorkbookName)) {\n throw new Error(`Target workbook \"${toWorkbookName}\" already exists`);\n }\n\n // Create new workbook\n this.addWorkbook(toWorkbookName);\n\n // Clone all sheets from source workbook\n for (const [sheetName, sheet] of sourceWorkbook.sheets) {\n // Add sheet to target workbook\n this.addSheet({\n workbookName: toWorkbookName,\n sheetName: sheetName,\n });\n\n // Copy all cell content using setSheetContent for efficiency\n this.setSheetContent(\n {\n workbookName: toWorkbookName,\n sheetName: sheetName,\n },\n new Map(sheet.content)\n );\n }\n\n // Clone workbook-scoped named expressions\n const sourceWorkbookExpressions = this.namedExpressionManager\n .getNamedExpressions()\n .workbookExpressions.get(fromWorkbookName);\n if (sourceWorkbookExpressions) {\n for (const [name, expression] of sourceWorkbookExpressions) {\n this.addNamedExpression({\n expressionName: name,\n expression: expression.expression,\n workbookName: toWorkbookName,\n });\n }\n }\n\n // Clone sheet-scoped named expressions\n const sourceSheetExpressions = this.namedExpressionManager\n .getNamedExpressions()\n .sheetExpressions.get(fromWorkbookName);\n if (sourceSheetExpressions) {\n for (const [sheetName, sheetExpressions] of sourceSheetExpressions) {\n for (const [name, expression] of sheetExpressions) {\n this.addNamedExpression({\n expressionName: name,\n expression: expression.expression,\n workbookName: toWorkbookName,\n sheetName: sheetName,\n });\n }\n }\n }\n\n // Clone tables\n const sourceTables = this.tableManager.tables.get(fromWorkbookName);\n if (sourceTables) {\n for (const [tableName, table] of sourceTables) {\n this.tableManager.copyTable(\n {\n workbookName: fromWorkbookName,\n tableName: tableName,\n },\n {\n workbookName: toWorkbookName,\n tableName: tableName,\n }\n );\n }\n }\n\n this.reevaluate();\n this.eventManager.emitUpdate();\n }\n\n renameWorkbook(opts: { workbookName: string; newWorkbookName: string }) {\n this.workbookManager.renameWorkbook(opts);\n\n // Update scoped named expressions\n this.namedExpressionManager.renameWorkbook(opts);\n\n // Update tables that belong to the renamed sheet\n this.tableManager.updateTablesForWorkbookRename(opts);\n\n // Update all formulas that reference this workbook\n this.workbookManager.updateAllFormulas((formula) =>\n renameWorkbookInFormula({\n formula,\n oldWorkbookName: opts.workbookName,\n newWorkbookName: opts.newWorkbookName,\n })\n );\n\n this.reevaluate();\n this.eventManager.emitUpdate();\n }\n\n getWorkbooks() {\n return this.workbookManager.getWorkbooks();\n }\n //#endregion\n\n //#region CRUD Operations\n /**\n * Overrides the content of a sheet.\n * @param sheetName - The name of the sheet to set the content of\n * @param content - A map of cell addresses to their serialized values\n * @remarks This method is used to set the content of a sheet. It will re-evaluate all sheets to ensure all dependencies are resolved correctly.\n */\n setSheetContent(\n opts: { sheetName: string; workbookName: string },\n content: Map<string, SerializedCellValue>\n ) {\n this.workbookManager.setSheetContent(opts, content);\n\n // Re-evaluate all sheets to ensure all dependencies are resolved correctly\n this.reevaluate();\n this.eventManager.emitUpdate();\n }\n\n setCellContent(address: CellAddress, content: SerializedCellValue) {\n this.workbookManager.setCellContent(address, content);\n\n // Re-evaluate all sheets to ensure all dependencies are resolved correctly\n this.reevaluate();\n this.eventManager.emitUpdate();\n }\n //#endregion\n\n //#region Evaluation\n\n /**\n * Re-evaluates all sheets to ensure all dependencies are resolved correctly\n *\n * but just clears the evaluation cache\n */\n reevaluate() {\n this.evaluationManager.clearEvaluationCache();\n }\n //#endregion\n\n //#region Auto-fill\n /**\n * Auto-fills the fillRange based on the seedRange and the direction.\n */\n autoFill(\n opts: { sheetName: string; workbookName: string },\n /**\n * The user's original selection that defines the pattern/series.\n */\n seedRange: SpreadsheetRange,\n /**\n * the new cells populated by the drag, excluding the seed\n */\n fillRange: SpreadsheetRange,\n /**\n * The direction of the fill.\n */\n direction: FillDirection\n ) {\n this.autoFillManager.fill(opts, seedRange, fillRange, direction);\n }\n\n /**\n * Removes the content in the spreadsheet that is inside the range.\n */\n clearSpreadsheetRange(address: RangeAddress) {\n this.workbookManager.clearSpreadsheetRange(address);\n\n // Re-evaluate all sheets to ensure all dependencies are resolved correctly\n this.reevaluate();\n this.eventManager.emitUpdate();\n }\n //#endregion\n\n //#region State - UI library integration\n getState() {\n return {\n workbooks: this.workbookManager.getWorkbooks(),\n namedExpressions: this.namedExpressionManager.getNamedExpressions(),\n tables: this.tableManager.tables,\n };\n }\n\n onUpdate(listener: () => void) {\n return this.eventManager.onUpdate(listener);\n }\n\n serializeEngine(): string {\n return serialize(this.getState());\n }\n\n resetToSerializedEngine(data: string) {\n const deserialized = deserialize(data) as ReturnType<typeof this.getState>;\n\n this.workbookManager.resetWorkbooks(deserialized.workbooks);\n\n deserialized.workbooks.forEach((workbook) => {\n this.namedExpressionManager.addWorkbook(workbook.name);\n this.tableManager.addWorkbook(workbook.name);\n workbook.sheets.forEach((sheet) => {\n this.namedExpressionManager.addSheet({\n workbookName: workbook.name,\n sheetName: sheet.name,\n });\n });\n });\n\n this.namedExpressionManager.resetNamedExpressions(\n deserialized.namedExpressions\n );\n this.tableManager.resetTables(deserialized.tables);\n\n // Re-evaluate all sheets to ensure all dependencies are resolved correctly\n this.reevaluate();\n this.eventManager.emitUpdate();\n }\n //#endregion\n}\n"
|
|
5
|
+
"/**\n * Main FormulaEngine class\n * Core API implementation for spreadsheet calculations\n */\n\nimport {\n type CellAddress,\n type CellStyle,\n type ConditionalStyle,\n type DirectCellStyle,\n type NamedExpression,\n type RangeAddress,\n type SerializedCellValue,\n type SingleEvaluationResult,\n type SpreadsheetRange,\n type SpreadsheetRangeEnd,\n type TableDefinition,\n} from \"./types.mjs\";\n\nimport type { FillDirection } from \"@ricsam/selection-manager\";\nimport { FormulaEvaluator } from \"../evaluator/formula-evaluator.mjs\";\nimport { AutoFill } from \"./autofill-utils.mjs\";\nimport { WorkbookManager } from \"./managers/workbook-manager.mjs\";\nimport { deserialize, serialize } from \"./map-serializer.mjs\";\nimport { renameNamedExpressionInFormula } from \"./named-expression-renamer.mjs\";\nimport { renameSheetInFormula } from \"./sheet-renamer.mjs\";\nimport { renameTableInFormula } from \"./table-renamer.mjs\";\nimport { renameWorkbookInFormula } from \"./workbook-renamer.mjs\";\nimport { cellAddressToKey, keyToCellAddress } from \"./utils.mjs\";\nimport { CacheManager } from \"./managers/cache-manager.mjs\";\nimport { NamedExpressionManager } from \"./managers/named-expression-manager.mjs\";\nimport { TableManager } from \"./managers/table-manager.mjs\";\nimport { EventManager } from \"./managers/event-manager.mjs\";\nimport { EvaluationManager } from \"./managers/evaluation-manager.mjs\";\nimport { DependencyManager } from \"./managers/dependency-manager.mjs\";\nimport { StyleManager } from \"./managers/style-manager.mjs\";\n\n/**\n * Main FormulaEngine class\n */\nexport class FormulaEngine {\n private workbookManager: WorkbookManager;\n private namedExpressionManager: NamedExpressionManager;\n private tableManager: TableManager;\n private eventManager: EventManager;\n private evaluationManager: EvaluationManager;\n private autoFillManager: AutoFill;\n private dependencyManager: DependencyManager;\n private styleManager: StyleManager;\n\n /**\n * Public access to the store manager for testing\n */\n public _workbookManager: WorkbookManager;\n public _namedExpressionManager: NamedExpressionManager;\n public _tableManager: TableManager;\n public _eventManager: EventManager;\n public _evaluationManager: EvaluationManager;\n public _autoFillManager: AutoFill;\n public _dependencyManager: DependencyManager;\n public _styleManager: StyleManager;\n\n constructor() {\n this.eventManager = new EventManager();\n this.workbookManager = new WorkbookManager();\n this.namedExpressionManager = new NamedExpressionManager();\n this.tableManager = new TableManager(this.workbookManager);\n const cacheManager = new CacheManager();\n this.dependencyManager = new DependencyManager(\n cacheManager,\n this.workbookManager\n );\n\n const formulaEvaluator = new FormulaEvaluator(\n this.tableManager,\n this.dependencyManager,\n this.namedExpressionManager,\n );\n\n this.evaluationManager = new EvaluationManager(\n this.workbookManager,\n this.tableManager,\n formulaEvaluator,\n this.dependencyManager\n );\n\n this.styleManager = new StyleManager(\n this.workbookManager,\n this.evaluationManager\n );\n\n this.autoFillManager = new AutoFill(this.workbookManager, this);\n\n this._workbookManager = this.workbookManager;\n this._namedExpressionManager = this.namedExpressionManager;\n this._tableManager = this.tableManager;\n this._eventManager = this.eventManager;\n this._evaluationManager = this.evaluationManager;\n this._autoFillManager = this.autoFillManager;\n this._dependencyManager = this.dependencyManager;\n this._styleManager = this.styleManager;\n }\n\n /**\n * Static factory method to build an empty engine\n */\n static buildEmpty(): FormulaEngine {\n return new FormulaEngine();\n }\n\n //#region Cell\n getCellEvaluationResult(\n cellAddress: CellAddress\n ): SingleEvaluationResult | undefined {\n return this.evaluationManager.getCellEvaluationResult(cellAddress);\n }\n\n getCellValue(cellAddress: CellAddress, debug?: boolean): SerializedCellValue {\n const result = this.getCellEvaluationResult(cellAddress);\n if (!result) {\n return \"\";\n }\n\n return this.evaluationManager.evaluationResultToSerializedValue(\n result,\n cellAddress,\n debug\n );\n }\n\n evaluateFormula(\n /**\n * formula without the leading = sign\n */\n formula: string, cellAddress: CellAddress): SerializedCellValue {\n return this.evaluationManager.evaluateFormula(formula, cellAddress);\n }\n\n getCellDependents(\n address: CellAddress | SpreadsheetRange\n ): (SpreadsheetRange | CellAddress)[] {\n throw new Error(\"Not implemented\");\n }\n\n getCellPrecedents(\n address: CellAddress | SpreadsheetRange\n ): (SpreadsheetRange | CellAddress)[] {\n throw new Error(\"Not implemented\");\n }\n\n //#endregion\n\n //#region Named Expressions\n addNamedExpression({\n expression,\n expressionName,\n sheetName,\n workbookName,\n }: {\n expression: string;\n expressionName: string;\n sheetName?: string;\n workbookName?: string;\n }) {\n this.namedExpressionManager.addNamedExpression({\n expression,\n expressionName,\n sheetName,\n workbookName,\n });\n\n // Re-evaluate all sheets since named expressions can be referenced from anywhere\n this.reevaluate();\n this.eventManager.emitUpdate();\n }\n\n removeNamedExpression({\n expressionName,\n sheetName,\n workbookName,\n }: {\n expressionName: string;\n sheetName?: string;\n workbookName?: string;\n }) {\n const found = this.namedExpressionManager.removeNamedExpression({\n expressionName,\n sheetName,\n workbookName,\n });\n\n if (found) {\n // Re-evaluate all sheets since named expressions can be referenced from anywhere\n this.reevaluate();\n this.eventManager.emitUpdate();\n }\n\n return found;\n }\n\n updateNamedExpression({\n expression,\n expressionName,\n sheetName,\n workbookName,\n }: {\n expression: string;\n expressionName: string;\n sheetName?: string;\n workbookName?: string;\n }) {\n this.namedExpressionManager.updateNamedExpression({\n expression,\n expressionName,\n sheetName,\n workbookName,\n });\n\n // Re-evaluate all sheets since named expressions can be referenced from anywhere\n this.reevaluate();\n this.eventManager.emitUpdate();\n }\n\n renameNamedExpression({\n expressionName,\n sheetName,\n workbookName,\n newName,\n }: {\n expressionName: string;\n sheetName?: string;\n workbookName?: string;\n newName: string;\n }) {\n const result = this.namedExpressionManager.renameNamedExpression({\n expressionName,\n sheetName,\n workbookName,\n newName,\n });\n\n // Update all formulas that reference this named expression in sheet cells\n this.workbookManager.updateAllFormulas((formula) =>\n renameNamedExpressionInFormula(formula, expressionName, newName)\n );\n\n // Update named expressions that reference this named expression\n this.namedExpressionManager.updateAllNamedExpressions((formula) =>\n renameNamedExpressionInFormula(formula, expressionName, newName)\n );\n\n // Re-evaluate all sheets since named expressions can be referenced from anywhere\n this.reevaluate();\n this.eventManager.emitUpdate();\n\n return result;\n }\n\n setNamedExpressions(\n opts: (\n | {\n type: \"global\";\n }\n | {\n type: \"sheet\";\n sheetName: string;\n workbookName: string;\n }\n | {\n type: \"workbook\";\n workbookName: string;\n }\n ) & {\n expressions: Map<string, NamedExpression>;\n }\n ) {\n this.namedExpressionManager.setNamedExpressions(opts);\n\n this.reevaluate();\n this.eventManager.emitUpdate();\n }\n //#endregion\n\n //#region Tables\n addTable(props: {\n tableName: string;\n sheetName: string;\n workbookName: string;\n start: string;\n numRows: SpreadsheetRangeEnd;\n numCols: number;\n }) {\n const table = this.tableManager.addTable({\n ...props,\n getCellValue: (cellAddress: CellAddress) =>\n this.getCellValue(cellAddress),\n });\n\n // Re-evaluate all sheets since structured references might depend on this table\n this.reevaluate();\n this.eventManager.emitUpdate();\n\n return table;\n }\n\n renameTable(\n workbookName: string,\n names: { oldName: string; newName: string }\n ) {\n this.tableManager.renameTable(workbookName, names);\n\n // Update all formulas that reference this table in sheet cells\n this.workbookManager.updateAllFormulas((formula) =>\n renameTableInFormula(formula, names.oldName, names.newName)\n );\n\n // Update named expressions that reference this table\n this.namedExpressionManager.updateAllNamedExpressions((formula) =>\n renameTableInFormula(formula, names.oldName, names.newName)\n );\n\n // Re-evaluate all sheets since structured references might depend on this table\n this.reevaluate();\n this.eventManager.emitUpdate();\n }\n\n updateTable(opts: {\n tableName: string;\n sheetName?: string;\n start?: string;\n numRows?: SpreadsheetRangeEnd;\n numCols?: number;\n workbookName: string;\n }) {\n this.tableManager.updateTable({\n ...opts,\n getCellValue: (cellAddress: CellAddress) =>\n this.getCellValue(cellAddress),\n });\n\n // Re-evaluate all sheets since structured references might depend on this table\n this.reevaluate();\n this.eventManager.emitUpdate();\n }\n\n removeTable(opts: { tableName: string; workbookName: string }) {\n const found = this.tableManager.removeTable(opts);\n\n if (found) {\n // Re-evaluate all sheets since structured references might depend on this table\n this.reevaluate();\n this.eventManager.emitUpdate();\n }\n\n return found;\n }\n\n resetTables(tables: Map<string, Map<string, TableDefinition>>) {\n this.tableManager.resetTables(tables);\n this.reevaluate();\n this.eventManager.emitUpdate();\n }\n\n getTables(workbookName: string) {\n return this.tableManager.getTables(workbookName);\n }\n\n isCellInTable(cellAddress: CellAddress): TableDefinition | undefined {\n return this.tableManager.isCellInTable(cellAddress);\n }\n\n //#endregion\n\n //#region Conditional Styling\n /**\n * Add a conditional style rule\n */\n addConditionalStyle(style: ConditionalStyle): void {\n this.styleManager.addConditionalStyle(style);\n this.eventManager.emitUpdate();\n }\n\n /**\n * Remove a conditional style rule by index\n */\n removeConditionalStyle(workbookName: string, index: number): boolean {\n const removed = this.styleManager.removeConditionalStyle(workbookName, index);\n if (removed) {\n this.eventManager.emitUpdate();\n }\n return removed;\n }\n\n /**\n * Get all conditional styles for a workbook\n */\n getConditionalStyles(workbookName: string): ConditionalStyle[] {\n return this.styleManager.getConditionalStyles(workbookName);\n }\n\n /**\n * Get the computed style for a specific cell\n */\n getCellStyle(cellAddress: CellAddress): CellStyle | undefined {\n return this.styleManager.getCellStyle(cellAddress);\n }\n\n /**\n * Add a direct cell style rule\n */\n addCellStyle(style: DirectCellStyle): void {\n this.styleManager.addCellStyle(style);\n this.eventManager.emitUpdate();\n }\n\n /**\n * Remove a direct cell style rule by index\n */\n removeCellStyle(workbookName: string, index: number): boolean {\n const removed = this.styleManager.removeCellStyle(workbookName, index);\n if (removed) {\n this.eventManager.emitUpdate();\n }\n return removed;\n }\n\n /**\n * Get all direct cell styles for a workbook\n */\n getCellStyles(workbookName: string): DirectCellStyle[] {\n return this.styleManager.getCellStyles(workbookName);\n }\n\n //#endregion\n\n //#region Sheets\n addSheet(opts: { workbookName: string; sheetName: string }) {\n const newSheet = this.workbookManager.addSheet(opts);\n const wbLevel = this.namedExpressionManager.addSheet(opts);\n this.reevaluate();\n this.eventManager.emitUpdate();\n return newSheet;\n }\n\n removeSheet(opts: { workbookName: string; sheetName: string }) {\n const sheet = this.workbookManager.removeSheet(opts);\n\n // Clean up related data\n this.namedExpressionManager.removeSheet(opts);\n this.tableManager.removeSheet(opts);\n this.styleManager.removeSheetStyles(opts.workbookName, opts.sheetName);\n\n // Add engine-specific logic: re-evaluate since references might be affected\n this.reevaluate();\n this.eventManager.emitUpdate();\n\n return sheet;\n }\n\n renameSheet(opts: {\n sheetName: string;\n newSheetName: string;\n workbookName: string;\n }) {\n const sheet = this.workbookManager.renameSheet(opts);\n\n // Update scoped named expressions\n this.namedExpressionManager.renameSheet(opts);\n\n // Update tables that belong to the renamed sheet\n this.tableManager.updateTablesForSheetRename(opts);\n\n // Update conditional styles that reference this sheet\n this.styleManager.updateSheetName(\n opts.workbookName,\n opts.sheetName,\n opts.newSheetName\n );\n\n // Update all formulas that reference this sheet\n this.workbookManager.updateAllFormulas((formula) =>\n renameSheetInFormula({\n formula,\n oldSheetName: opts.sheetName,\n newSheetName: opts.newSheetName,\n })\n );\n\n // Add engine-specific logic: re-evaluate since references might be affected\n this.reevaluate();\n this.eventManager.emitUpdate();\n\n return sheet;\n }\n\n getSheets(workbookName: string) {\n return this.workbookManager.getSheets(workbookName);\n }\n\n getSheet({\n workbookName,\n sheetName,\n }: {\n workbookName: string;\n sheetName: string;\n }) {\n return this.workbookManager.getSheet({ workbookName, sheetName });\n }\n\n getSheetSerialized(opts: {\n sheetName: string;\n workbookName: string;\n }): Map<string, SerializedCellValue> {\n return this.workbookManager.getSheetSerialized(opts);\n }\n\n //#endregion\n\n //#region Workbook\n addWorkbook(workbookName: string) {\n this.workbookManager.addWorkbook(workbookName);\n this.namedExpressionManager.addWorkbook(workbookName);\n this.tableManager.addWorkbook(workbookName);\n\n this.reevaluate();\n this.eventManager.emitUpdate();\n }\n\n removeWorkbook(workbookName: string) {\n this.workbookManager.removeWorkbook(workbookName);\n this.namedExpressionManager.removeWorkbook(workbookName);\n this.tableManager.removeWorkbook(workbookName);\n this.styleManager.removeWorkbookStyles(workbookName);\n\n this.reevaluate();\n this.eventManager.emitUpdate();\n }\n\n cloneWorkbook(fromWorkbookName: string, toWorkbookName: string) {\n // Check if source workbook exists\n const sourceWorkbook = this.workbookManager\n .getWorkbooks()\n .get(fromWorkbookName);\n if (!sourceWorkbook) {\n throw new Error(`Source workbook \"${fromWorkbookName}\" not found`);\n }\n\n // Check if target workbook name already exists\n if (this.workbookManager.getWorkbooks().has(toWorkbookName)) {\n throw new Error(`Target workbook \"${toWorkbookName}\" already exists`);\n }\n\n // Create new workbook\n this.addWorkbook(toWorkbookName);\n\n // Clone all sheets from source workbook\n for (const [sheetName, sheet] of sourceWorkbook.sheets) {\n // Add sheet to target workbook\n this.addSheet({\n workbookName: toWorkbookName,\n sheetName: sheetName,\n });\n\n // Copy all cell content using setSheetContent for efficiency\n this.setSheetContent(\n {\n workbookName: toWorkbookName,\n sheetName: sheetName,\n },\n new Map(sheet.content)\n );\n }\n\n // Clone workbook-scoped named expressions\n const sourceWorkbookExpressions = this.namedExpressionManager\n .getNamedExpressions()\n .workbookExpressions.get(fromWorkbookName);\n if (sourceWorkbookExpressions) {\n for (const [name, expression] of sourceWorkbookExpressions) {\n this.addNamedExpression({\n expressionName: name,\n expression: expression.expression,\n workbookName: toWorkbookName,\n });\n }\n }\n\n // Clone sheet-scoped named expressions\n const sourceSheetExpressions = this.namedExpressionManager\n .getNamedExpressions()\n .sheetExpressions.get(fromWorkbookName);\n if (sourceSheetExpressions) {\n for (const [sheetName, sheetExpressions] of sourceSheetExpressions) {\n for (const [name, expression] of sheetExpressions) {\n this.addNamedExpression({\n expressionName: name,\n expression: expression.expression,\n workbookName: toWorkbookName,\n sheetName: sheetName,\n });\n }\n }\n }\n\n // Clone tables\n const sourceTables = this.tableManager.tables.get(fromWorkbookName);\n if (sourceTables) {\n for (const [tableName, table] of sourceTables) {\n this.tableManager.copyTable(\n {\n workbookName: fromWorkbookName,\n tableName: tableName,\n },\n {\n workbookName: toWorkbookName,\n tableName: tableName,\n }\n );\n }\n }\n\n this.reevaluate();\n this.eventManager.emitUpdate();\n }\n\n renameWorkbook(opts: { workbookName: string; newWorkbookName: string }) {\n this.workbookManager.renameWorkbook(opts);\n\n // Update scoped named expressions\n this.namedExpressionManager.renameWorkbook(opts);\n\n // Update tables that belong to the renamed sheet\n this.tableManager.updateTablesForWorkbookRename(opts);\n\n // Update conditional styles that reference this workbook\n this.styleManager.updateWorkbookName(\n opts.workbookName,\n opts.newWorkbookName\n );\n\n // Update all formulas that reference this workbook\n this.workbookManager.updateAllFormulas((formula) =>\n renameWorkbookInFormula({\n formula,\n oldWorkbookName: opts.workbookName,\n newWorkbookName: opts.newWorkbookName,\n })\n );\n\n this.reevaluate();\n this.eventManager.emitUpdate();\n }\n\n getWorkbooks() {\n return this.workbookManager.getWorkbooks();\n }\n //#endregion\n\n //#region CRUD Operations\n /**\n * Overrides the content of a sheet.\n * @param sheetName - The name of the sheet to set the content of\n * @param content - A map of cell addresses to their serialized values\n * @remarks This method is used to set the content of a sheet. It will re-evaluate all sheets to ensure all dependencies are resolved correctly.\n */\n setSheetContent(\n opts: { sheetName: string; workbookName: string },\n content: Map<string, SerializedCellValue>\n ) {\n this.workbookManager.setSheetContent(opts, content);\n\n // Re-evaluate all sheets to ensure all dependencies are resolved correctly\n this.reevaluate();\n this.eventManager.emitUpdate();\n }\n\n setCellContent(address: CellAddress, content: SerializedCellValue) {\n this.workbookManager.setCellContent(address, content);\n\n // Re-evaluate all sheets to ensure all dependencies are resolved correctly\n this.reevaluate();\n this.eventManager.emitUpdate();\n }\n //#endregion\n\n //#region Evaluation\n\n /**\n * Re-evaluates all sheets to ensure all dependencies are resolved correctly\n *\n * but just clears the evaluation cache\n */\n reevaluate() {\n this.evaluationManager.clearEvaluationCache();\n }\n //#endregion\n\n //#region Auto-fill\n /**\n * Auto-fills the fillRange based on the seedRange and the direction.\n */\n autoFill(\n opts: { sheetName: string; workbookName: string },\n /**\n * The user's original selection that defines the pattern/series.\n */\n seedRange: SpreadsheetRange,\n /**\n * the new cells populated by the drag, excluding the seed\n */\n fillRange: SpreadsheetRange,\n /**\n * The direction of the fill.\n */\n direction: FillDirection\n ) {\n this.autoFillManager.fill(opts, seedRange, fillRange, direction);\n }\n\n /**\n * Removes the content in the spreadsheet that is inside the range.\n */\n clearSpreadsheetRange(address: RangeAddress) {\n this.workbookManager.clearSpreadsheetRange(address);\n\n // Re-evaluate all sheets to ensure all dependencies are resolved correctly\n this.reevaluate();\n this.eventManager.emitUpdate();\n }\n //#endregion\n\n //#region State - UI library integration\n getState() {\n return {\n workbooks: this.workbookManager.getWorkbooks(),\n namedExpressions: this.namedExpressionManager.getNamedExpressions(),\n tables: this.tableManager.tables,\n conditionalStyles: this.styleManager.getAllConditionalStyles(),\n cellStyles: this.styleManager.getAllCellStyles(),\n };\n }\n\n onUpdate(listener: () => void) {\n return this.eventManager.onUpdate(listener);\n }\n\n serializeEngine(): string {\n return serialize(this.getState());\n }\n\n resetToSerializedEngine(data: string) {\n const deserialized = deserialize(data) as ReturnType<typeof this.getState>;\n\n this.workbookManager.resetWorkbooks(deserialized.workbooks);\n\n deserialized.workbooks.forEach((workbook) => {\n this.namedExpressionManager.addWorkbook(workbook.name);\n this.tableManager.addWorkbook(workbook.name);\n workbook.sheets.forEach((sheet) => {\n this.namedExpressionManager.addSheet({\n workbookName: workbook.name,\n sheetName: sheet.name,\n });\n });\n });\n\n this.namedExpressionManager.resetNamedExpressions(\n deserialized.namedExpressions\n );\n this.tableManager.resetTables(deserialized.tables);\n \n // Reset styles if present\n // Handle backward compatibility: if conditionalStyles is a Map, convert it\n let conditionalStylesArray: ConditionalStyle[] | undefined;\n let cellStylesArray: DirectCellStyle[] | undefined;\n \n if (deserialized.conditionalStyles) {\n if (deserialized.conditionalStyles instanceof Map) {\n // Old format: Map<string, ConditionalStyle[]>\n conditionalStylesArray = Array.from(deserialized.conditionalStyles.values()).flat();\n } else if (Array.isArray(deserialized.conditionalStyles)) {\n // New format: ConditionalStyle[]\n conditionalStylesArray = deserialized.conditionalStyles;\n }\n }\n \n if (deserialized.cellStyles) {\n if (Array.isArray(deserialized.cellStyles)) {\n cellStylesArray = deserialized.cellStyles;\n }\n }\n \n this.styleManager.resetStyles(conditionalStylesArray, cellStylesArray);\n\n // Re-evaluate all sheets to ensure all dependencies are resolved correctly\n this.reevaluate();\n this.eventManager.emitUpdate();\n }\n //#endregion\n}\n"
|
|
6
6
|
],
|
|
7
|
-
"mappings": ";
|
|
8
|
-
"debugId": "
|
|
7
|
+
"mappings": "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",
|
|
8
|
+
"debugId": "E903EB04E40DB1E764756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|
|
@@ -3,20 +3,26 @@ import {
|
|
|
3
3
|
eligibleKeysForContext,
|
|
4
4
|
getContextDependencyKey
|
|
5
5
|
} from "../../evaluator/evaluation-context.mjs";
|
|
6
|
-
import { isCellInRange, keyToCellAddress } from "../utils.mjs";
|
|
6
|
+
import { cellAddressToKey, isCellInRange, keyToCellAddress } from "../utils.mjs";
|
|
7
7
|
import { AstEvaluationNode } from "../../evaluator/dependency-nodes/ast-evaluation-node.mjs";
|
|
8
8
|
import { CellValueNode } from "../../evaluator/dependency-nodes/cell-value-node.mjs";
|
|
9
9
|
import { EmptyCellEvaluationNode } from "../../evaluator/dependency-nodes/empty-cell-evaluation-node.mjs";
|
|
10
10
|
import { SpillMetaNode } from "../../evaluator/dependency-nodes/spill-meta-node.mjs";
|
|
11
11
|
import { RangeEvaluationNode } from "../../evaluator/range-evaluation-node.mjs";
|
|
12
|
-
import {
|
|
12
|
+
import {
|
|
13
|
+
astToString,
|
|
14
|
+
normalizeSerializedCellValue
|
|
15
|
+
} from "../../parser/formatter.mjs";
|
|
16
|
+
import { VirtualCellValueNode } from "../../evaluator/dependency-nodes/virtual-cell-value-node.mjs";
|
|
17
|
+
import { parseFormula } from "../../parser/parser.mjs";
|
|
13
18
|
|
|
14
19
|
class DependencyManager {
|
|
15
20
|
cacheManager;
|
|
16
21
|
workbookManager;
|
|
17
|
-
|
|
22
|
+
cellNodes = new Map;
|
|
18
23
|
spillMetaNodes = new Map;
|
|
19
24
|
emptyCells = new Map;
|
|
25
|
+
virtualCellValueNodes = new Map;
|
|
20
26
|
_spilledValues = new Map;
|
|
21
27
|
ranges = new Map;
|
|
22
28
|
constructor(cacheManager, workbookManager) {
|
|
@@ -70,8 +76,9 @@ class DependencyManager {
|
|
|
70
76
|
}
|
|
71
77
|
clearEvaluationCache() {
|
|
72
78
|
this.cacheManager.clear();
|
|
73
|
-
this.
|
|
79
|
+
this.cellNodes.clear();
|
|
74
80
|
this.emptyCells.clear();
|
|
81
|
+
this.virtualCellValueNodes.clear();
|
|
75
82
|
this.asts.clear();
|
|
76
83
|
this.spillMetaNodes.clear();
|
|
77
84
|
this.ranges.clear();
|
|
@@ -109,12 +116,12 @@ class DependencyManager {
|
|
|
109
116
|
if (!nodeKey.startsWith("cell-value:")) {
|
|
110
117
|
throw new Error("Invalid cell value node key: " + nodeKey);
|
|
111
118
|
}
|
|
112
|
-
if (!this.
|
|
119
|
+
if (!this.cellNodes.has(nodeKey)) {
|
|
113
120
|
const node = new CellValueNode(nodeKey);
|
|
114
|
-
this.
|
|
121
|
+
this.cellNodes.set(nodeKey, node);
|
|
115
122
|
return node;
|
|
116
123
|
}
|
|
117
|
-
return this.
|
|
124
|
+
return this.cellNodes.get(nodeKey);
|
|
118
125
|
}
|
|
119
126
|
getCellValueOrEmptyCellNode(nodeKey) {
|
|
120
127
|
const cellAddress = keyToCellAddress(nodeKey);
|
|
@@ -134,38 +141,30 @@ class DependencyManager {
|
|
|
134
141
|
}
|
|
135
142
|
return this.getSpillMetaNode(spillMetaKey);
|
|
136
143
|
}
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
const
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
if (
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
results.push(cellValueNode);
|
|
155
|
-
} else {
|
|
156
|
-
results.push(this.getCellValueNode(cellValueKey));
|
|
157
|
-
}
|
|
144
|
+
getVirtualCellValueNode(cellAddress, cellValue) {
|
|
145
|
+
let nodeKey = cellAddressToKey(cellAddress).replace(/^[^:]+:/, "virtual:");
|
|
146
|
+
nodeKey += ":";
|
|
147
|
+
const normalizedCellValue = normalizeSerializedCellValue(cellValue);
|
|
148
|
+
if (typeof normalizedCellValue === "string" && normalizedCellValue.startsWith("=")) {
|
|
149
|
+
const ast = parseFormula(normalizedCellValue.slice(1));
|
|
150
|
+
nodeKey += "ast:" + astToString(ast);
|
|
151
|
+
} else if (typeof normalizedCellValue === "string" && normalizedCellValue !== "") {
|
|
152
|
+
nodeKey += "string:" + normalizedCellValue;
|
|
153
|
+
} else if (typeof normalizedCellValue === "number") {
|
|
154
|
+
nodeKey += "number:" + normalizedCellValue;
|
|
155
|
+
} else if (typeof normalizedCellValue === "boolean") {
|
|
156
|
+
nodeKey += "boolean:" + normalizedCellValue;
|
|
157
|
+
} else if (normalizedCellValue === undefined) {
|
|
158
|
+
nodeKey += "string:";
|
|
159
|
+
} else {
|
|
160
|
+
throw new Error("Invalid cell value: " + normalizedCellValue);
|
|
158
161
|
}
|
|
159
|
-
if (this.
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
} else {
|
|
164
|
-
results.push(this.getSpillMetaNode(cellValueKey));
|
|
165
|
-
}
|
|
166
|
-
}
|
|
162
|
+
if (!this.virtualCellValueNodes.has(nodeKey)) {
|
|
163
|
+
const node = new VirtualCellValueNode(nodeKey, cellAddress, cellValue);
|
|
164
|
+
this.virtualCellValueNodes.set(nodeKey, node);
|
|
165
|
+
return node;
|
|
167
166
|
}
|
|
168
|
-
return
|
|
167
|
+
return this.virtualCellValueNodes.get(nodeKey);
|
|
169
168
|
}
|
|
170
169
|
getRangeNode(rangeKey) {
|
|
171
170
|
if (!rangeKey.startsWith("range:")) {
|
|
@@ -210,9 +209,6 @@ class DependencyManager {
|
|
|
210
209
|
});
|
|
211
210
|
}
|
|
212
211
|
}
|
|
213
|
-
getEvaluatedNodes() {
|
|
214
|
-
return this.evaluatedNodes;
|
|
215
|
-
}
|
|
216
212
|
getTransitiveDepsForEvalOrder(node, visited = new Set) {
|
|
217
213
|
if (visited.has(node)) {
|
|
218
214
|
return new Set;
|
|
@@ -590,4 +586,4 @@ export {
|
|
|
590
586
|
DependencyManager
|
|
591
587
|
};
|
|
592
588
|
|
|
593
|
-
//# debugId=
|
|
589
|
+
//# debugId=E85B3068E2F7410364756E2164756E21
|