@ricsam/formula-engine 0.2.7 → 0.2.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. package/README.md +1 -3
  2. package/dist/cjs/core/engine.cjs +518 -149
  3. package/dist/cjs/core/engine.cjs.map +3 -3
  4. package/dist/cjs/core/managers/dependency-manager.cjs.map +2 -2
  5. package/dist/cjs/core/managers/evaluation-manager.cjs.map +1 -1
  6. package/dist/cjs/core/mutation-invalidation.cjs +241 -0
  7. package/dist/cjs/core/mutation-invalidation.cjs.map +10 -0
  8. package/dist/cjs/lib.cjs +2 -13
  9. package/dist/cjs/lib.cjs.map +3 -3
  10. package/dist/cjs/package.json +1 -1
  11. package/dist/mjs/core/engine.mjs +532 -190
  12. package/dist/mjs/core/engine.mjs.map +3 -3
  13. package/dist/mjs/core/managers/dependency-manager.mjs.map +2 -2
  14. package/dist/mjs/core/managers/evaluation-manager.mjs.map +1 -1
  15. package/dist/mjs/core/mutation-invalidation.mjs +201 -0
  16. package/dist/mjs/core/mutation-invalidation.mjs.map +10 -0
  17. package/dist/mjs/lib.mjs +2 -13
  18. package/dist/mjs/lib.mjs.map +3 -3
  19. package/dist/mjs/package.json +1 -1
  20. package/dist/types/core/engine.d.ts +17 -116
  21. package/dist/types/core/managers/dependency-manager.d.ts +1 -1
  22. package/dist/types/core/managers/evaluation-manager.d.ts +1 -1
  23. package/dist/types/core/mutation-invalidation.d.ts +46 -0
  24. package/dist/types/lib.d.ts +0 -8
  25. package/package.json +1 -1
  26. package/dist/cjs/core/commands/command-executor.cjs +0 -149
  27. package/dist/cjs/core/commands/command-executor.cjs.map +0 -10
  28. package/dist/cjs/core/commands/content-commands.cjs +0 -857
  29. package/dist/cjs/core/commands/content-commands.cjs.map +0 -10
  30. package/dist/cjs/core/commands/metadata-commands.cjs +0 -160
  31. package/dist/cjs/core/commands/metadata-commands.cjs.map +0 -10
  32. package/dist/cjs/core/commands/named-expression-commands.cjs +0 -363
  33. package/dist/cjs/core/commands/named-expression-commands.cjs.map +0 -10
  34. package/dist/cjs/core/commands/structure-commands.cjs +0 -696
  35. package/dist/cjs/core/commands/structure-commands.cjs.map +0 -10
  36. package/dist/cjs/core/commands/style-commands.cjs +0 -229
  37. package/dist/cjs/core/commands/style-commands.cjs.map +0 -10
  38. package/dist/cjs/core/commands/table-commands.cjs +0 -495
  39. package/dist/cjs/core/commands/table-commands.cjs.map +0 -10
  40. package/dist/cjs/core/commands/types.cjs +0 -99
  41. package/dist/cjs/core/commands/types.cjs.map +0 -10
  42. package/dist/cjs/core/managers/schema-manager.cjs +0 -374
  43. package/dist/cjs/core/managers/schema-manager.cjs.map +0 -10
  44. package/dist/cjs/core/schema/cell-orm.cjs +0 -76
  45. package/dist/cjs/core/schema/cell-orm.cjs.map +0 -10
  46. package/dist/cjs/core/schema/grid-orm.cjs +0 -125
  47. package/dist/cjs/core/schema/grid-orm.cjs.map +0 -10
  48. package/dist/cjs/core/schema/schema-builder.cjs +0 -74
  49. package/dist/cjs/core/schema/schema-builder.cjs.map +0 -10
  50. package/dist/cjs/core/schema/schema-helpers.cjs +0 -200
  51. package/dist/cjs/core/schema/schema-helpers.cjs.map +0 -10
  52. package/dist/cjs/core/schema/schema.cjs +0 -91
  53. package/dist/cjs/core/schema/schema.cjs.map +0 -10
  54. package/dist/cjs/core/schema/table-orm.cjs +0 -189
  55. package/dist/cjs/core/schema/table-orm.cjs.map +0 -10
  56. package/dist/mjs/core/commands/command-executor.mjs +0 -109
  57. package/dist/mjs/core/commands/command-executor.mjs.map +0 -10
  58. package/dist/mjs/core/commands/content-commands.mjs +0 -821
  59. package/dist/mjs/core/commands/content-commands.mjs.map +0 -10
  60. package/dist/mjs/core/commands/metadata-commands.mjs +0 -120
  61. package/dist/mjs/core/commands/metadata-commands.mjs.map +0 -10
  62. package/dist/mjs/core/commands/named-expression-commands.mjs +0 -323
  63. package/dist/mjs/core/commands/named-expression-commands.mjs.map +0 -10
  64. package/dist/mjs/core/commands/structure-commands.mjs +0 -661
  65. package/dist/mjs/core/commands/structure-commands.mjs.map +0 -10
  66. package/dist/mjs/core/commands/style-commands.mjs +0 -189
  67. package/dist/mjs/core/commands/style-commands.mjs.map +0 -10
  68. package/dist/mjs/core/commands/table-commands.mjs +0 -459
  69. package/dist/mjs/core/commands/table-commands.mjs.map +0 -10
  70. package/dist/mjs/core/commands/types.mjs +0 -59
  71. package/dist/mjs/core/commands/types.mjs.map +0 -10
  72. package/dist/mjs/core/managers/schema-manager.mjs +0 -334
  73. package/dist/mjs/core/managers/schema-manager.mjs.map +0 -10
  74. package/dist/mjs/core/schema/cell-orm.mjs +0 -35
  75. package/dist/mjs/core/schema/cell-orm.mjs.map +0 -10
  76. package/dist/mjs/core/schema/grid-orm.mjs +0 -84
  77. package/dist/mjs/core/schema/grid-orm.mjs.map +0 -10
  78. package/dist/mjs/core/schema/schema-builder.mjs +0 -34
  79. package/dist/mjs/core/schema/schema-builder.mjs.map +0 -10
  80. package/dist/mjs/core/schema/schema-helpers.mjs +0 -160
  81. package/dist/mjs/core/schema/schema-helpers.mjs.map +0 -10
  82. package/dist/mjs/core/schema/schema.mjs +0 -51
  83. package/dist/mjs/core/schema/schema.mjs.map +0 -10
  84. package/dist/mjs/core/schema/table-orm.mjs +0 -156
  85. package/dist/mjs/core/schema/table-orm.mjs.map +0 -10
  86. package/dist/types/core/commands/command-executor.d.ts +0 -81
  87. package/dist/types/core/commands/content-commands.d.ts +0 -172
  88. package/dist/types/core/commands/metadata-commands.d.ts +0 -55
  89. package/dist/types/core/commands/named-expression-commands.d.ts +0 -130
  90. package/dist/types/core/commands/structure-commands.d.ts +0 -155
  91. package/dist/types/core/commands/style-commands.d.ts +0 -76
  92. package/dist/types/core/commands/table-commands.d.ts +0 -119
  93. package/dist/types/core/commands/types.d.ts +0 -143
  94. package/dist/types/core/managers/schema-manager.d.ts +0 -142
  95. package/dist/types/core/schema/cell-orm.d.ts +0 -33
  96. package/dist/types/core/schema/grid-orm.d.ts +0 -63
  97. package/dist/types/core/schema/schema-builder.d.ts +0 -16
  98. package/dist/types/core/schema/schema-helpers.d.ts +0 -49
  99. package/dist/types/core/schema/schema.d.ts +0 -167
  100. package/dist/types/core/schema/schema.type-test.d.ts +0 -1
  101. package/dist/types/core/schema/table-orm.d.ts +0 -46
@@ -16,64 +16,27 @@ import { DependencyManager } from "./managers/dependency-manager.mjs";
16
16
  import { StyleManager } from "./managers/style-manager.mjs";
17
17
  import { CopyManager } from "./managers/copy-manager.mjs";
18
18
  import { ReferenceManager } from "./managers/reference-manager.mjs";
19
- import {
20
- SchemaManager
21
- } from "./managers/schema-manager.mjs";
22
- import { buildSchemaFromDeclaration } from "./schema/schema-builder.mjs";
23
- import { TableOrm } from "./schema/table-orm.mjs";
24
- import { CellOrm } from "./schema/cell-orm.mjs";
25
- import { GridOrm } from "./schema/grid-orm.mjs";
26
19
  import {
27
20
  ENGINE_SNAPSHOT_VERSION
28
21
  } from "./engine-snapshot.mjs";
29
22
  import {
30
- CommandExecutor
31
- } from "./commands/command-executor.mjs";
32
- import {
33
- SetCellContentCommand,
34
- SetSheetContentCommand,
35
- ClearRangeCommand,
36
- PasteCellsCommand,
37
- FillAreasCommand,
38
- MoveCellCommand,
39
- MoveRangeCommand,
40
- AutoFillCommand
41
- } from "./commands/content-commands.mjs";
42
- import {
43
- AddWorkbookCommand,
44
- RemoveWorkbookCommand,
45
- RenameWorkbookCommand,
46
- CloneWorkbookCommand,
47
- AddSheetCommand,
48
- RemoveSheetCommand,
49
- RenameSheetCommand
50
- } from "./commands/structure-commands.mjs";
51
- import {
52
- AddTableCommand,
53
- RemoveTableCommand,
54
- RenameTableCommand,
55
- UpdateTableCommand,
56
- ResetTablesCommand
57
- } from "./commands/table-commands.mjs";
23
+ buildFormulaTouchedCells,
24
+ buildSheetContentTouchedCells,
25
+ buildTableContextChangedCells,
26
+ buildTableTouchedCells,
27
+ buildTouchedCells,
28
+ captureCellContents,
29
+ getFiniteRangeAddresses,
30
+ getMutationAddressKey,
31
+ getNamedExpressionScopeResourceKeys,
32
+ mergeTouchedCells
33
+ } from "./mutation-invalidation.mjs";
58
34
  import {
59
- AddNamedExpressionCommand,
60
- RemoveNamedExpressionCommand,
61
- UpdateNamedExpressionCommand,
62
- RenameNamedExpressionCommand,
63
- SetNamedExpressionsCommand
64
- } from "./commands/named-expression-commands.mjs";
65
- import {
66
- SetCellMetadataCommand,
67
- SetSheetMetadataCommand,
68
- SetWorkbookMetadataCommand
69
- } from "./commands/metadata-commands.mjs";
70
- import {
71
- AddConditionalStyleCommand,
72
- RemoveConditionalStyleCommand,
73
- AddCellStyleCommand,
74
- RemoveCellStyleCommand,
75
- ClearCellStylesCommand
76
- } from "./commands/style-commands.mjs";
35
+ getNamedExpressionResourceKey,
36
+ getSheetResourceKey,
37
+ getTableResourceKey,
38
+ getWorkbookResourceKey
39
+ } from "./resource-keys.mjs";
77
40
 
78
41
  class FormulaEngine {
79
42
  workbookManager;
@@ -86,10 +49,6 @@ class FormulaEngine {
86
49
  styleManager;
87
50
  copyManager;
88
51
  referenceManager;
89
- schemaManager;
90
- commandExecutor;
91
- schema;
92
- schemaDeclaration;
93
52
  _workbookManager;
94
53
  _namedExpressionManager;
95
54
  _tableManager;
@@ -98,8 +57,7 @@ class FormulaEngine {
98
57
  _autoFillManager;
99
58
  _dependencyManager;
100
59
  _styleManager;
101
- constructor(schema) {
102
- this.schemaDeclaration = schema?.declaration;
60
+ constructor() {
103
61
  this.eventManager = new EventManager;
104
62
  this.workbookManager = new WorkbookManager;
105
63
  this.namedExpressionManager = new NamedExpressionManager;
@@ -112,13 +70,6 @@ class FormulaEngine {
112
70
  this.copyManager = new CopyManager(this.workbookManager, this.evaluationManager, this.styleManager);
113
71
  this.autoFillManager = new AutoFill(this.workbookManager, this.styleManager);
114
72
  this.referenceManager = new ReferenceManager;
115
- this.schemaManager = new SchemaManager(this.tableManager);
116
- this.commandExecutor = new CommandExecutor(this.evaluationManager, this.eventManager, () => this.schemaManager.validateAllSchemaConstraints((cell) => this.getCellValue(cell), (cell) => this.getCellMetadata(cell), (table) => this.getTableDataCells(table)));
117
- if (this.schemaDeclaration) {
118
- this.schema = buildSchemaFromDeclaration(this, this.schemaDeclaration, this.schemaManager);
119
- } else {
120
- this.schema = {};
121
- }
122
73
  this._workbookManager = this.workbookManager;
123
74
  this._namedExpressionManager = this.namedExpressionManager;
124
75
  this._tableManager = this.tableManager;
@@ -128,26 +79,63 @@ class FormulaEngine {
128
79
  this._dependencyManager = this.dependencyManager;
129
80
  this._styleManager = this.styleManager;
130
81
  }
131
- static buildEmpty(schema) {
132
- return new FormulaEngine(schema);
82
+ static buildEmpty() {
83
+ return new FormulaEngine;
133
84
  }
134
- addTableSchema(namespace, address, headers) {
135
- this.schemaManager.registerTableSchema(namespace, address.workbookName, address.tableName, headers);
136
- const orm = new TableOrm(this, address.workbookName, address.tableName, headers, namespace);
137
- this.schema[namespace] = orm;
138
- return orm;
85
+ emitMutation(footprint) {
86
+ this.evaluationManager.invalidateFromMutation(footprint);
87
+ this.eventManager.emitUpdate();
88
+ }
89
+ emitUpdate() {
90
+ this.eventManager.emitUpdate();
139
91
  }
140
- addCellSchema(namespace, cellAddress, parse, write = (value) => ({ value })) {
141
- this.schemaManager.registerCellSchema(namespace, cellAddress, parse);
142
- const orm = new CellOrm(this, cellAddress, parse, write, namespace);
143
- this.schema[namespace] = orm;
144
- return orm;
92
+ getExistingSheetContent(opts) {
93
+ const sheet = this.workbookManager.getSheet(opts);
94
+ return sheet ? new Map(sheet.content) : undefined;
145
95
  }
146
- addGridSchema(namespace, address, range, parse, write = (value) => ({ value })) {
147
- this.schemaManager.registerGridSchema(namespace, address.workbookName, address.sheetName, range, parse);
148
- const orm = new GridOrm(this, address.workbookName, address.sheetName, range, parse, write, namespace);
149
- this.schema[namespace] = orm;
150
- return orm;
96
+ getWorkbookResourceKeys(workbookName) {
97
+ const resourceKeys = new Set([getWorkbookResourceKey(workbookName)]);
98
+ for (const sheetName of this.workbookManager.getWorkbooks().get(workbookName)?.sheets.keys() ?? []) {
99
+ resourceKeys.add(getSheetResourceKey({ workbookName, sheetName }));
100
+ }
101
+ for (const tableName of this.tableManager.getTables(workbookName).keys()) {
102
+ resourceKeys.add(getTableResourceKey({ workbookName, tableName }));
103
+ }
104
+ const namedExpressions = this.namedExpressionManager.getNamedExpressions();
105
+ for (const name of namedExpressions.workbookExpressions.get(workbookName)?.keys() ?? []) {
106
+ resourceKeys.add(getNamedExpressionResourceKey({ expressionName: name, workbookName }));
107
+ }
108
+ for (const [sheetName, expressions] of namedExpressions.sheetExpressions.get(workbookName) ?? []) {
109
+ resourceKeys.add(getSheetResourceKey({ workbookName, sheetName }));
110
+ for (const name of expressions.keys()) {
111
+ resourceKeys.add(getNamedExpressionResourceKey({
112
+ expressionName: name,
113
+ workbookName,
114
+ sheetName
115
+ }));
116
+ }
117
+ }
118
+ return Array.from(resourceKeys);
119
+ }
120
+ getSheetResourceKeys(opts) {
121
+ const resourceKeys = new Set([
122
+ getWorkbookResourceKey(opts.workbookName),
123
+ getSheetResourceKey(opts)
124
+ ]);
125
+ for (const [tableName, table] of this.tableManager.getTables(opts.workbookName)) {
126
+ if (table.sheetName === opts.sheetName) {
127
+ resourceKeys.add(getTableResourceKey({ workbookName: opts.workbookName, tableName }));
128
+ }
129
+ }
130
+ const sheetExpressions = this.namedExpressionManager.getNamedExpressions().sheetExpressions.get(opts.workbookName)?.get(opts.sheetName);
131
+ for (const name of sheetExpressions?.keys() ?? []) {
132
+ resourceKeys.add(getNamedExpressionResourceKey({
133
+ expressionName: name,
134
+ workbookName: opts.workbookName,
135
+ sheetName: opts.sheetName
136
+ }));
137
+ }
138
+ return Array.from(resourceKeys);
151
139
  }
152
140
  getCellEvaluationResult(cellAddress) {
153
141
  return this.evaluationManager.getCellEvaluationResult(cellAddress);
@@ -160,7 +148,8 @@ class FormulaEngine {
160
148
  return this.evaluationManager.evaluationResultToSerializedValue(result, cellAddress, debug);
161
149
  }
162
150
  setCellMetadata(address, metadata) {
163
- this.commandExecutor.execute(new SetCellMetadataCommand(this.workbookManager, address, metadata));
151
+ this.workbookManager.setCellMetadata(address, metadata);
152
+ this.emitUpdate();
164
153
  }
165
154
  getCellMetadata(address) {
166
155
  const metadata = this.workbookManager.getCellMetadata(address);
@@ -170,13 +159,15 @@ class FormulaEngine {
170
159
  return this.workbookManager.getSheetMetadataSerialized(opts);
171
160
  }
172
161
  setSheetMetadata(opts, metadata) {
173
- this.commandExecutor.execute(new SetSheetMetadataCommand(this.workbookManager, opts, metadata));
162
+ this.workbookManager.setSheetMetadata(opts, metadata);
163
+ this.emitUpdate();
174
164
  }
175
165
  getSheetMetadata(opts) {
176
166
  return this.workbookManager.getSheetMetadata(opts);
177
167
  }
178
168
  setWorkbookMetadata(workbookName, metadata) {
179
- this.commandExecutor.execute(new SetWorkbookMetadataCommand(this.workbookManager, workbookName, metadata));
169
+ this.workbookManager.setWorkbookMetadata(workbookName, metadata);
170
+ this.emitUpdate();
180
171
  }
181
172
  getWorkbookMetadata(workbookName) {
182
173
  return this.workbookManager.getWorkbookMetadata(workbookName);
@@ -203,10 +194,20 @@ class FormulaEngine {
203
194
  throw new Error("Not implemented");
204
195
  }
205
196
  addNamedExpression(opts) {
206
- this.commandExecutor.execute(new AddNamedExpressionCommand(this.getNamedExpressionCommandDeps(), opts), { validate: this.schemaManager.hasSchemas() });
197
+ this.namedExpressionManager.addNamedExpression(opts);
198
+ this.emitMutation({
199
+ touchedCells: [],
200
+ resourceKeys: [getNamedExpressionResourceKey(opts)]
201
+ });
207
202
  }
208
203
  removeNamedExpression(opts) {
209
- this.commandExecutor.execute(new RemoveNamedExpressionCommand(this.getNamedExpressionCommandDeps(), opts), { validate: this.schemaManager.hasSchemas() });
204
+ const removed = this.namedExpressionManager.removeNamedExpression(opts);
205
+ if (removed) {
206
+ this.emitMutation({
207
+ touchedCells: [],
208
+ resourceKeys: [getNamedExpressionResourceKey(opts)]
209
+ });
210
+ }
210
211
  }
211
212
  hasNamedExpression(opts) {
212
213
  const scope = opts.sheetName && opts.workbookName ? {
@@ -220,25 +221,154 @@ class FormulaEngine {
220
221
  });
221
222
  }
222
223
  updateNamedExpression(opts) {
223
- this.commandExecutor.execute(new UpdateNamedExpressionCommand(this.getNamedExpressionCommandDeps(), opts), { validate: this.schemaManager.hasSchemas() });
224
+ this.namedExpressionManager.updateNamedExpression(opts);
225
+ this.emitMutation({
226
+ touchedCells: [],
227
+ resourceKeys: [getNamedExpressionResourceKey(opts)]
228
+ });
224
229
  }
225
230
  renameNamedExpression(opts) {
226
- this.commandExecutor.execute(new RenameNamedExpressionCommand(this.getNamedExpressionCommandDeps(), opts), { validate: this.schemaManager.hasSchemas() });
231
+ this.namedExpressionManager.renameNamedExpression(opts);
232
+ const changedCells = this.workbookManager.updateAllFormulas((formula) => renameNamedExpressionInFormula(formula, opts.expressionName, opts.newName));
233
+ const changedNamedExpressions = this.namedExpressionManager.updateAllNamedExpressions((formula) => renameNamedExpressionInFormula(formula, opts.expressionName, opts.newName));
234
+ this.emitMutation({
235
+ touchedCells: buildFormulaTouchedCells(changedCells),
236
+ resourceKeys: [
237
+ getNamedExpressionResourceKey({
238
+ expressionName: opts.expressionName,
239
+ workbookName: opts.workbookName,
240
+ sheetName: opts.sheetName
241
+ }),
242
+ getNamedExpressionResourceKey({
243
+ expressionName: opts.newName,
244
+ workbookName: opts.workbookName,
245
+ sheetName: opts.sheetName
246
+ }),
247
+ ...changedNamedExpressions
248
+ ]
249
+ });
227
250
  }
228
251
  setNamedExpressions(opts) {
229
- this.commandExecutor.execute(new SetNamedExpressionsCommand(this.getNamedExpressionCommandDeps(), opts), { validate: this.schemaManager.hasSchemas() });
252
+ const allExpressions = this.namedExpressionManager.getNamedExpressions();
253
+ let previousExpressions;
254
+ if (opts.type === "global") {
255
+ previousExpressions = new Map(allExpressions.globalExpressions);
256
+ } else if (opts.type === "workbook") {
257
+ previousExpressions = new Map(allExpressions.workbookExpressions.get(opts.workbookName) || []);
258
+ } else {
259
+ const sheetExpressions = allExpressions.sheetExpressions.get(opts.workbookName)?.get(opts.sheetName);
260
+ previousExpressions = new Map(sheetExpressions || []);
261
+ }
262
+ this.namedExpressionManager.setNamedExpressions(opts);
263
+ const scope = opts.type === "global" ? {} : opts.type === "workbook" ? { workbookName: opts.workbookName } : {
264
+ workbookName: opts.workbookName,
265
+ sheetName: opts.sheetName
266
+ };
267
+ this.emitMutation({
268
+ touchedCells: [],
269
+ resourceKeys: [
270
+ ...getNamedExpressionScopeResourceKeys(previousExpressions.keys(), scope),
271
+ ...getNamedExpressionScopeResourceKeys(opts.expressions.keys(), scope)
272
+ ]
273
+ });
230
274
  }
231
275
  addTable(props) {
232
- this.commandExecutor.execute(new AddTableCommand(this.getTableCommandDeps(), props), { validate: this.schemaManager.hasSchemas() });
276
+ const table = this.tableManager.addTable({
277
+ ...props,
278
+ getCellValue: (cellAddress) => this.getCellValue(cellAddress)
279
+ });
280
+ this.emitMutation({
281
+ touchedCells: buildTableTouchedCells(this.workbookManager, [table]),
282
+ tableContextChangedCells: buildTableContextChangedCells(this.workbookManager, [table]),
283
+ resourceKeys: [
284
+ getTableResourceKey({
285
+ workbookName: props.workbookName,
286
+ tableName: props.tableName
287
+ })
288
+ ]
289
+ });
233
290
  }
234
291
  renameTable(workbookName, names) {
235
- this.commandExecutor.execute(new RenameTableCommand(this.getTableCommandDeps(), workbookName, names.oldName, names.newName), { validate: this.schemaManager.hasSchemas() });
292
+ const oldTable = this.tableManager.getTable({
293
+ workbookName,
294
+ name: names.oldName
295
+ });
296
+ const oldTableSnapshot = oldTable ? { ...oldTable, headers: new Map(oldTable.headers) } : undefined;
297
+ this.tableManager.renameTable(workbookName, names);
298
+ const changedCells = this.workbookManager.updateAllFormulas((formula) => renameTableInFormula(formula, names.oldName, names.newName));
299
+ const changedNamedExpressions = this.namedExpressionManager.updateAllNamedExpressions((formula) => renameTableInFormula(formula, names.oldName, names.newName));
300
+ const newTable = this.tableManager.getTable({
301
+ workbookName,
302
+ name: names.newName
303
+ });
304
+ this.emitMutation({
305
+ touchedCells: mergeTouchedCells(buildTableTouchedCells(this.workbookManager, [oldTableSnapshot]), buildTableTouchedCells(this.workbookManager, [newTable]), buildFormulaTouchedCells(changedCells)),
306
+ tableContextChangedCells: buildTableContextChangedCells(this.workbookManager, [oldTableSnapshot, newTable]),
307
+ resourceKeys: [
308
+ getTableResourceKey({
309
+ workbookName,
310
+ tableName: names.oldName
311
+ }),
312
+ getTableResourceKey({
313
+ workbookName,
314
+ tableName: names.newName
315
+ }),
316
+ ...changedNamedExpressions
317
+ ]
318
+ });
236
319
  }
237
320
  updateTable(opts) {
238
- this.commandExecutor.execute(new UpdateTableCommand(this.getTableCommandDeps(), opts), { validate: this.schemaManager.hasSchemas() });
321
+ const oldTable = this.tableManager.getTable({
322
+ workbookName: opts.workbookName,
323
+ name: opts.tableName
324
+ });
325
+ const oldTableSnapshot = oldTable ? { ...oldTable, headers: new Map(oldTable.headers) } : undefined;
326
+ this.tableManager.updateTable({
327
+ ...opts,
328
+ getCellValue: (cellAddress) => this.getCellValue(cellAddress)
329
+ });
330
+ const newTable = this.tableManager.getTable({
331
+ workbookName: opts.workbookName,
332
+ name: opts.tableName
333
+ });
334
+ this.emitMutation({
335
+ touchedCells: mergeTouchedCells(buildTableTouchedCells(this.workbookManager, [oldTableSnapshot]), buildTableTouchedCells(this.workbookManager, [newTable])),
336
+ tableContextChangedCells: buildTableContextChangedCells(this.workbookManager, [oldTableSnapshot, newTable]),
337
+ resourceKeys: [
338
+ getTableResourceKey({
339
+ workbookName: opts.workbookName,
340
+ tableName: opts.tableName
341
+ })
342
+ ]
343
+ });
239
344
  }
240
345
  removeTable(opts) {
241
- this.commandExecutor.execute(new RemoveTableCommand(this.getTableCommandDeps(), opts), { validate: this.schemaManager.hasSchemas() });
346
+ const oldTable = this.tableManager.getTable({
347
+ workbookName: opts.workbookName,
348
+ name: opts.tableName
349
+ });
350
+ const oldTableSnapshot = oldTable ? { ...oldTable, headers: new Map(oldTable.headers) } : undefined;
351
+ const found = this.tableManager.removeTable(opts);
352
+ if (found) {
353
+ this.emitMutation({
354
+ touchedCells: buildTableTouchedCells(this.workbookManager, [
355
+ oldTableSnapshot
356
+ ]),
357
+ tableContextChangedCells: buildTableContextChangedCells(this.workbookManager, [oldTableSnapshot]),
358
+ resourceKeys: [
359
+ getTableResourceKey({
360
+ workbookName: opts.workbookName,
361
+ tableName: opts.tableName
362
+ })
363
+ ]
364
+ });
365
+ }
366
+ }
367
+ getAllTables() {
368
+ return Array.from(this.tableManager.tables.values()).flatMap((tables) => Array.from(tables.values()).map((table) => ({
369
+ ...table,
370
+ headers: new Map(table.headers)
371
+ })));
242
372
  }
243
373
  hasTable(opts) {
244
374
  return !!this.tableManager.getTable({
@@ -253,7 +383,21 @@ class FormulaEngine {
253
383
  });
254
384
  }
255
385
  resetTables(tables) {
256
- this.commandExecutor.execute(new ResetTablesCommand(this.getTableCommandDeps(), tables), { validate: this.schemaManager.hasSchemas() });
386
+ const oldTables = this.getAllTables();
387
+ const newTables = Array.from(tables.values()).flatMap((workbookTables) => Array.from(workbookTables.values()));
388
+ const resourceKeys = new Set;
389
+ for (const table of [...oldTables, ...newTables]) {
390
+ resourceKeys.add(getTableResourceKey({
391
+ workbookName: table.workbookName,
392
+ tableName: table.name
393
+ }));
394
+ }
395
+ this.tableManager.resetTables(tables);
396
+ this.emitMutation({
397
+ touchedCells: mergeTouchedCells(buildTableTouchedCells(this.workbookManager, oldTables), buildTableTouchedCells(this.workbookManager, newTables)),
398
+ tableContextChangedCells: buildTableContextChangedCells(this.workbookManager, [...oldTables, ...newTables]),
399
+ resourceKeys: Array.from(resourceKeys)
400
+ });
257
401
  }
258
402
  getTables(workbookName) {
259
403
  return this.tableManager.getTables(workbookName);
@@ -261,28 +405,15 @@ class FormulaEngine {
261
405
  isCellInTable(cellAddress) {
262
406
  return this.tableManager.isCellInTable(cellAddress);
263
407
  }
264
- getTableDataCells(table) {
265
- const { start, endRow, headers } = table;
266
- const dataStartRow = start.rowIndex + 1;
267
- const endColIndex = start.colIndex + headers.size - 1;
268
- const rangeAddress = {
269
- workbookName: table.workbookName,
270
- sheetName: table.sheetName,
271
- range: {
272
- start: { col: start.colIndex, row: dataStartRow },
273
- end: {
274
- col: { type: "number", value: endColIndex },
275
- row: endRow
276
- }
277
- }
278
- };
279
- return this.workbookManager.getCellsInRange(rangeAddress);
280
- }
281
408
  addConditionalStyle(style) {
282
- this.commandExecutor.execute(new AddConditionalStyleCommand(this.styleManager, style));
409
+ this.styleManager.addConditionalStyle(style);
410
+ this.emitUpdate();
283
411
  }
284
412
  removeConditionalStyle(workbookName, index) {
285
- this.commandExecutor.execute(new RemoveConditionalStyleCommand(this.styleManager, workbookName, index));
413
+ const removed = this.styleManager.removeConditionalStyle(workbookName, index);
414
+ if (removed) {
415
+ this.emitUpdate();
416
+ }
286
417
  }
287
418
  getConditionalStyleCount(workbookName) {
288
419
  const allStyles = this.styleManager.getAllConditionalStyles();
@@ -301,10 +432,14 @@ class FormulaEngine {
301
432
  return this.styleManager.getAllConditionalStyles();
302
433
  }
303
434
  addCellStyle(style) {
304
- this.commandExecutor.execute(new AddCellStyleCommand(this.styleManager, style));
435
+ this.styleManager.addCellStyle(style);
436
+ this.emitUpdate();
305
437
  }
306
438
  removeCellStyle(workbookName, index) {
307
- this.commandExecutor.execute(new RemoveCellStyleCommand(this.styleManager, workbookName, index));
439
+ const removed = this.styleManager.removeCellStyle(workbookName, index);
440
+ if (removed) {
441
+ this.emitUpdate();
442
+ }
308
443
  }
309
444
  getCellStyleCount(workbookName) {
310
445
  const allStyles = this.styleManager.getAllCellStyles();
@@ -317,13 +452,69 @@ class FormulaEngine {
317
452
  return this.styleManager.getStyleForRange(range);
318
453
  }
319
454
  clearCellStyles(range) {
320
- this.commandExecutor.execute(new ClearCellStylesCommand(this.styleManager, range));
455
+ this.styleManager.clearCellStyles(range);
456
+ this.emitUpdate();
457
+ }
458
+ getTopLeftCell(cells) {
459
+ let topLeft = cells[0];
460
+ for (const cell of cells) {
461
+ if (cell.rowIndex < topLeft.rowIndex || cell.rowIndex === topLeft.rowIndex && cell.colIndex < topLeft.colIndex) {
462
+ topLeft = cell;
463
+ }
464
+ }
465
+ return topLeft;
466
+ }
467
+ dedupeAddresses(addresses) {
468
+ return Array.from(new Map(addresses.map((address) => [getMutationAddressKey(address), address])).values());
469
+ }
470
+ getPasteTouchedAddresses(source, target, options) {
471
+ if (source.length === 0) {
472
+ return [];
473
+ }
474
+ const topLeft = this.getTopLeftCell(source);
475
+ const colOffset = target.colIndex - topLeft.colIndex;
476
+ const rowOffset = target.rowIndex - topLeft.rowIndex;
477
+ const targetCells = source.map((sourceCell) => ({
478
+ workbookName: target.workbookName,
479
+ sheetName: target.sheetName,
480
+ colIndex: sourceCell.colIndex + colOffset,
481
+ rowIndex: sourceCell.rowIndex + rowOffset
482
+ }));
483
+ return this.dedupeAddresses(options.cut ? [...source, ...targetCells] : targetCells);
321
484
  }
322
485
  pasteCells(source, target, options) {
323
- this.commandExecutor.execute(new PasteCellsCommand(this.workbookManager, this.copyManager, source, target, options), { validate: this.schemaManager.hasSchemas() });
486
+ if (source.length === 0) {
487
+ return;
488
+ }
489
+ const touchedAddresses = this.getPasteTouchedAddresses(source, target, options);
490
+ const before = captureCellContents(this.workbookManager, touchedAddresses);
491
+ this.copyManager.pasteCells(source, target, options);
492
+ const after = captureCellContents(this.workbookManager, touchedAddresses);
493
+ this.emitMutation({
494
+ touchedCells: buildTouchedCells(touchedAddresses.map((address) => ({
495
+ address,
496
+ before: before.get(getMutationAddressKey(address)),
497
+ after: after.get(getMutationAddressKey(address))
498
+ }))),
499
+ resourceKeys: []
500
+ });
324
501
  }
325
502
  fillAreas(seedRange, targetRanges, options) {
326
- this.commandExecutor.execute(new FillAreasCommand(this.workbookManager, this.copyManager, seedRange, targetRanges, options), { validate: this.schemaManager.hasSchemas() });
503
+ const touchedAddresses = this.dedupeAddresses([
504
+ ...targetRanges.flatMap((targetRange) => getFiniteRangeAddresses(targetRange)),
505
+ ...options.cut ? getFiniteRangeAddresses(seedRange) : []
506
+ ]);
507
+ const before = captureCellContents(this.workbookManager, touchedAddresses);
508
+ this.copyManager.fillAreas(seedRange, targetRanges, options);
509
+ const after = captureCellContents(this.workbookManager, touchedAddresses);
510
+ this.emitMutation({
511
+ touchedCells: buildTouchedCells(touchedAddresses.map((address) => ({
512
+ address,
513
+ before: before.get(getMutationAddressKey(address)),
514
+ after: after.get(getMutationAddressKey(address))
515
+ }))),
516
+ resourceKeys: []
517
+ });
327
518
  }
328
519
  smartPaste(sourceCells, pasteSelection, options) {
329
520
  if (sourceCells.length === 0) {
@@ -404,17 +595,27 @@ class FormulaEngine {
404
595
  return { minCol, minRow, maxCol, maxRow };
405
596
  }
406
597
  moveCell(source, target) {
407
- this.commandExecutor.execute(new MoveCellCommand(this.workbookManager, this.copyManager, source, target), { validate: this.schemaManager.hasSchemas() });
598
+ this.pasteCells([source], target, {
599
+ cut: true,
600
+ type: "formula",
601
+ include: "all"
602
+ });
408
603
  }
409
604
  moveRange(sourceRange, target) {
410
- this.commandExecutor.execute(new MoveRangeCommand(this.workbookManager, this.copyManager, sourceRange, target), { validate: this.schemaManager.hasSchemas() });
605
+ const cells = this.copyManager.expandRangeToCells(sourceRange);
606
+ this.pasteCells(cells, target, {
607
+ cut: true,
608
+ type: "formula",
609
+ include: "all"
610
+ });
411
611
  }
412
612
  addSheet(opts) {
413
- this.commandExecutor.execute(new AddSheetCommand(this.getStructureCommandDeps(), opts), { validate: this.schemaManager.hasSchemas() });
414
- const sheet = this.workbookManager.getSheet(opts);
415
- if (!sheet) {
416
- throw new Error(`Failed to create sheet '${opts.sheetName}'`);
417
- }
613
+ const sheet = this.workbookManager.addSheet(opts);
614
+ this.namedExpressionManager.addSheet(opts);
615
+ this.emitMutation({
616
+ touchedCells: [],
617
+ resourceKeys: [getSheetResourceKey(opts)]
618
+ });
418
619
  return sheet;
419
620
  }
420
621
  createSheet(opts) {
@@ -425,10 +626,40 @@ class FormulaEngine {
425
626
  });
426
627
  }
427
628
  removeSheet(opts) {
428
- this.commandExecutor.execute(new RemoveSheetCommand(this.getStructureCommandDeps(), opts), { validate: this.schemaManager.hasSchemas() });
629
+ const resourceKeys = this.getSheetResourceKeys(opts);
630
+ this.workbookManager.removeSheet(opts);
631
+ this.namedExpressionManager.removeSheet(opts);
632
+ this.tableManager.removeSheet(opts);
633
+ this.styleManager.removeSheetStyles(opts.workbookName, opts.sheetName);
634
+ this.referenceManager.invalidateSheet(opts.workbookName, opts.sheetName);
635
+ this.emitMutation({
636
+ touchedCells: [],
637
+ resourceKeys,
638
+ removedScopes: [{ type: "sheet", ...opts }]
639
+ });
429
640
  }
430
641
  renameSheet(opts) {
431
- this.commandExecutor.execute(new RenameSheetCommand(this.getStructureCommandDeps(), opts), { validate: this.schemaManager.hasSchemas() });
642
+ const oldResourceKeys = this.getSheetResourceKeys(opts);
643
+ this.workbookManager.renameSheet(opts);
644
+ this.namedExpressionManager.renameSheet(opts);
645
+ this.tableManager.updateTablesForSheetRename(opts);
646
+ this.styleManager.updateSheetName(opts.workbookName, opts.sheetName, opts.newSheetName);
647
+ const changedCells = this.workbookManager.updateAllFormulas((formula) => renameSheetInFormula({
648
+ formula,
649
+ oldSheetName: opts.sheetName,
650
+ newSheetName: opts.newSheetName
651
+ }));
652
+ this.referenceManager.updateSheetName(opts.workbookName, opts.sheetName, opts.newSheetName);
653
+ this.emitMutation({
654
+ touchedCells: buildFormulaTouchedCells(changedCells),
655
+ resourceKeys: Array.from(new Set([
656
+ ...oldResourceKeys,
657
+ ...this.getSheetResourceKeys({
658
+ workbookName: opts.workbookName,
659
+ sheetName: opts.newSheetName
660
+ })
661
+ ]))
662
+ });
432
663
  }
433
664
  hasSheet(opts) {
434
665
  return !!this.workbookManager.getSheet(opts);
@@ -455,34 +686,197 @@ class FormulaEngine {
455
686
  return this.workbookManager.getSheetSerialized(opts);
456
687
  }
457
688
  addWorkbook(workbookName) {
458
- this.commandExecutor.execute(new AddWorkbookCommand(this.getStructureCommandDeps(), workbookName), { validate: this.schemaManager.hasSchemas() });
689
+ this.workbookManager.addWorkbook(workbookName);
690
+ this.namedExpressionManager.addWorkbook(workbookName);
691
+ this.tableManager.addWorkbook(workbookName);
692
+ this.emitMutation({
693
+ touchedCells: [],
694
+ resourceKeys: [getWorkbookResourceKey(workbookName)]
695
+ });
459
696
  }
460
697
  removeWorkbook(workbookName) {
461
- this.commandExecutor.execute(new RemoveWorkbookCommand(this.getStructureCommandDeps(), workbookName), { validate: this.schemaManager.hasSchemas() });
698
+ const resourceKeys = this.getWorkbookResourceKeys(workbookName);
699
+ this.workbookManager.removeWorkbook(workbookName);
700
+ this.namedExpressionManager.removeWorkbook(workbookName);
701
+ this.tableManager.removeWorkbook(workbookName);
702
+ this.styleManager.removeWorkbookStyles(workbookName);
703
+ this.referenceManager.invalidateWorkbook(workbookName);
704
+ this.emitMutation({
705
+ touchedCells: [],
706
+ resourceKeys,
707
+ removedScopes: [{ type: "workbook", workbookName }]
708
+ });
462
709
  }
463
710
  hasWorkbook(workbookName) {
464
711
  return this.workbookManager.getWorkbooks().has(workbookName);
465
712
  }
466
713
  cloneWorkbook(fromWorkbookName, toWorkbookName) {
467
- this.commandExecutor.execute(new CloneWorkbookCommand(this.getStructureCommandDeps(), fromWorkbookName, toWorkbookName), { validate: this.schemaManager.hasSchemas() });
714
+ const sourceWorkbook = this.workbookManager.getWorkbooks().get(fromWorkbookName);
715
+ if (!sourceWorkbook) {
716
+ throw new Error(`Source workbook "${fromWorkbookName}" not found`);
717
+ }
718
+ if (this.workbookManager.getWorkbooks().has(toWorkbookName)) {
719
+ throw new Error(`Target workbook "${toWorkbookName}" already exists`);
720
+ }
721
+ this.workbookManager.addWorkbook(toWorkbookName);
722
+ this.namedExpressionManager.addWorkbook(toWorkbookName);
723
+ this.tableManager.addWorkbook(toWorkbookName);
724
+ for (const [sheetName, sheet] of sourceWorkbook.sheets) {
725
+ this.workbookManager.addSheet({
726
+ workbookName: toWorkbookName,
727
+ sheetName
728
+ });
729
+ this.namedExpressionManager.addSheet({
730
+ workbookName: toWorkbookName,
731
+ sheetName
732
+ });
733
+ this.workbookManager.setSheetContent({ workbookName: toWorkbookName, sheetName }, new Map(sheet.content));
734
+ const targetSheet = this.workbookManager.getSheet({
735
+ workbookName: toWorkbookName,
736
+ sheetName
737
+ });
738
+ if (targetSheet) {
739
+ targetSheet.metadata = new Map(sheet.metadata);
740
+ if (sheet.sheetMetadata !== undefined) {
741
+ targetSheet.sheetMetadata = structuredClone(sheet.sheetMetadata);
742
+ }
743
+ }
744
+ }
745
+ const targetWorkbook = this.workbookManager.getWorkbooks().get(toWorkbookName);
746
+ if (targetWorkbook && sourceWorkbook.workbookMetadata !== undefined) {
747
+ targetWorkbook.workbookMetadata = structuredClone(sourceWorkbook.workbookMetadata);
748
+ }
749
+ const namedExpressions = this.namedExpressionManager.getNamedExpressions();
750
+ const sourceWorkbookExpressions = namedExpressions.workbookExpressions.get(fromWorkbookName);
751
+ if (sourceWorkbookExpressions) {
752
+ for (const [expressionName, expression] of sourceWorkbookExpressions) {
753
+ this.namedExpressionManager.addNamedExpression({
754
+ expressionName,
755
+ expression: expression.expression,
756
+ workbookName: toWorkbookName
757
+ });
758
+ }
759
+ }
760
+ const sourceSheetExpressions = namedExpressions.sheetExpressions.get(fromWorkbookName);
761
+ if (sourceSheetExpressions) {
762
+ for (const [sheetName, expressions] of sourceSheetExpressions) {
763
+ for (const [expressionName, expression] of expressions) {
764
+ this.namedExpressionManager.addNamedExpression({
765
+ expressionName,
766
+ expression: expression.expression,
767
+ workbookName: toWorkbookName,
768
+ sheetName
769
+ });
770
+ }
771
+ }
772
+ }
773
+ const sourceTables = this.tableManager.tables.get(fromWorkbookName);
774
+ if (sourceTables) {
775
+ for (const [tableName] of sourceTables) {
776
+ this.tableManager.copyTable({ workbookName: fromWorkbookName, tableName }, { workbookName: toWorkbookName, tableName });
777
+ }
778
+ }
779
+ for (const style of this.styleManager.getAllConditionalStyles()) {
780
+ if (style.areas.some((area) => area.workbookName === fromWorkbookName)) {
781
+ this.styleManager.addConditionalStyle({
782
+ ...style,
783
+ areas: style.areas.map((area) => area.workbookName === fromWorkbookName ? { ...area, workbookName: toWorkbookName } : area)
784
+ });
785
+ }
786
+ }
787
+ for (const style of this.styleManager.getAllCellStyles()) {
788
+ if (style.areas.some((area) => area.workbookName === fromWorkbookName)) {
789
+ this.styleManager.addCellStyle({
790
+ ...style,
791
+ areas: style.areas.map((area) => area.workbookName === fromWorkbookName ? { ...area, workbookName: toWorkbookName } : area)
792
+ });
793
+ }
794
+ }
795
+ this.workbookManager.updateFormulasForWorkbook(toWorkbookName, (formula) => renameWorkbookInFormula({
796
+ formula,
797
+ oldWorkbookName: fromWorkbookName,
798
+ newWorkbookName: toWorkbookName
799
+ }));
800
+ this.emitMutation({
801
+ touchedCells: [],
802
+ resourceKeys: [getWorkbookResourceKey(toWorkbookName)]
803
+ });
468
804
  }
469
805
  renameWorkbook(opts) {
470
- this.commandExecutor.execute(new RenameWorkbookCommand(this.getStructureCommandDeps(), opts.workbookName, opts.newWorkbookName), { validate: this.schemaManager.hasSchemas() });
806
+ const oldResourceKeys = this.getWorkbookResourceKeys(opts.workbookName);
807
+ this.workbookManager.renameWorkbook(opts);
808
+ this.namedExpressionManager.renameWorkbook(opts);
809
+ this.tableManager.updateTablesForWorkbookRename(opts);
810
+ this.styleManager.updateWorkbookName(opts.workbookName, opts.newWorkbookName);
811
+ const changedCells = this.workbookManager.updateAllFormulas((formula) => renameWorkbookInFormula({
812
+ formula,
813
+ oldWorkbookName: opts.workbookName,
814
+ newWorkbookName: opts.newWorkbookName
815
+ }));
816
+ this.referenceManager.updateWorkbookName(opts.workbookName, opts.newWorkbookName);
817
+ this.emitMutation({
818
+ touchedCells: buildFormulaTouchedCells(changedCells),
819
+ resourceKeys: Array.from(new Set([
820
+ ...oldResourceKeys,
821
+ ...this.getWorkbookResourceKeys(opts.newWorkbookName)
822
+ ]))
823
+ });
471
824
  }
472
825
  getWorkbooks() {
473
826
  return this.workbookManager.getWorkbooks();
474
827
  }
475
828
  setSheetContent(opts, content) {
476
- this.commandExecutor.execute(new SetSheetContentCommand(this.workbookManager, opts, content), { validate: this.schemaManager.hasSchemas() });
829
+ const previousContent = this.getExistingSheetContent(opts);
830
+ this.workbookManager.setSheetContent(opts, content);
831
+ this.emitMutation({
832
+ touchedCells: buildSheetContentTouchedCells(opts, previousContent, content),
833
+ resourceKeys: []
834
+ });
477
835
  }
478
836
  setCellContent(address, content) {
479
- this.commandExecutor.execute(new SetCellContentCommand(this.workbookManager, address, content), { validate: this.schemaManager.hasSchemas() });
837
+ const previousValue = this.workbookManager.getCellContent(address);
838
+ this.workbookManager.setCellContent(address, content);
839
+ this.emitMutation({
840
+ touchedCells: buildTouchedCells([
841
+ {
842
+ address,
843
+ before: previousValue,
844
+ after: content
845
+ }
846
+ ]),
847
+ resourceKeys: []
848
+ });
480
849
  }
481
850
  autoFill(opts, seedRange, fillRanges, direction) {
482
- this.commandExecutor.execute(new AutoFillCommand(this.workbookManager, this.styleManager, this.autoFillManager, opts, seedRange, fillRanges, direction), { validate: this.schemaManager.hasSchemas() });
851
+ const touchedAddresses = this.dedupeAddresses(fillRanges.flatMap((range) => getFiniteRangeAddresses({
852
+ workbookName: opts.workbookName,
853
+ sheetName: opts.sheetName,
854
+ range
855
+ })));
856
+ const before = captureCellContents(this.workbookManager, touchedAddresses);
857
+ this.autoFillManager.fill(opts, seedRange, fillRanges, direction);
858
+ const after = captureCellContents(this.workbookManager, touchedAddresses);
859
+ this.emitMutation({
860
+ touchedCells: buildTouchedCells(touchedAddresses.map((address) => ({
861
+ address,
862
+ before: before.get(getMutationAddressKey(address)),
863
+ after: after.get(getMutationAddressKey(address))
864
+ }))),
865
+ resourceKeys: []
866
+ });
483
867
  }
484
868
  clearSpreadsheetRange(address) {
485
- this.commandExecutor.execute(new ClearRangeCommand(this.workbookManager, address), { validate: this.schemaManager.hasSchemas() });
869
+ const clearedCells = Array.from(this.workbookManager.iterateCellsInRange(address));
870
+ const before = captureCellContents(this.workbookManager, clearedCells);
871
+ this.workbookManager.clearSpreadsheetRange(address);
872
+ this.emitMutation({
873
+ touchedCells: buildTouchedCells(clearedCells.map((cellAddress) => ({
874
+ address: cellAddress,
875
+ before: before.get(getMutationAddressKey(cellAddress)),
876
+ after: undefined
877
+ }))),
878
+ resourceKeys: []
879
+ });
486
880
  }
487
881
  getState() {
488
882
  return {
@@ -538,63 +932,11 @@ class FormulaEngine {
538
932
  dependency: deserialized.managers.dependency,
539
933
  cache: deserialized.managers.cache
540
934
  }, this.evaluationManager);
541
- this.commandExecutor.clearHistory();
542
- this.commandExecutor.clearActionLog();
543
935
  this.eventManager.emitUpdate();
544
936
  }
545
- undo() {
546
- return this.commandExecutor.undo();
547
- }
548
- redo() {
549
- return this.commandExecutor.redo();
550
- }
551
- canUndo() {
552
- return this.commandExecutor.canUndo();
553
- }
554
- canRedo() {
555
- return this.commandExecutor.canRedo();
556
- }
557
- getActionLog() {
558
- return this.commandExecutor.getActionLog();
559
- }
560
- clearActionLog() {
561
- this.commandExecutor.clearActionLog();
562
- }
563
- clearHistory() {
564
- this.commandExecutor.clearHistory();
565
- }
566
- getStructureCommandDeps() {
567
- return {
568
- workbookManager: this.workbookManager,
569
- namedExpressionManager: this.namedExpressionManager,
570
- tableManager: this.tableManager,
571
- styleManager: this.styleManager,
572
- referenceManager: this.referenceManager,
573
- apiSchemaManager: this.schemaManager,
574
- renameSheetInFormula,
575
- renameWorkbookInFormula
576
- };
577
- }
578
- getTableCommandDeps() {
579
- return {
580
- tableManager: this.tableManager,
581
- namedExpressionManager: this.namedExpressionManager,
582
- workbookManager: this.workbookManager,
583
- apiSchemaManager: this.schemaManager,
584
- getCellValue: (cell) => this.getCellValue(cell),
585
- renameTableInFormula
586
- };
587
- }
588
- getNamedExpressionCommandDeps() {
589
- return {
590
- namedExpressionManager: this.namedExpressionManager,
591
- workbookManager: this.workbookManager,
592
- renameNamedExpressionInFormula
593
- };
594
- }
595
937
  }
596
938
  export {
597
939
  FormulaEngine
598
940
  };
599
941
 
600
- //# debugId=140E8246E7C976AF64756E2164756E21
942
+ //# debugId=1DF8797947659AB164756E2164756E21