@ricsam/formula-engine 0.2.8 → 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 +515 -166
  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 +529 -207
  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 -135
  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";
58
- import {
59
- AddNamedExpressionCommand,
60
- RemoveNamedExpressionCommand,
61
- UpdateNamedExpressionCommand,
62
- RenameNamedExpressionCommand,
63
- SetNamedExpressionsCommand
64
- } from "./commands/named-expression-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";
65
34
  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,46 +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);
133
- }
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;
82
+ static buildEmpty() {
83
+ return new FormulaEngine;
139
84
  }
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;
145
- }
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;
151
- }
152
- removeTableSchema(namespace) {
153
- return this.removeSchemaOfType(namespace, "table");
85
+ emitMutation(footprint) {
86
+ this.evaluationManager.invalidateFromMutation(footprint);
87
+ this.eventManager.emitUpdate();
154
88
  }
155
- removeCellSchema(namespace) {
156
- return this.removeSchemaOfType(namespace, "cell");
89
+ emitUpdate() {
90
+ this.eventManager.emitUpdate();
157
91
  }
158
- removeGridSchema(namespace) {
159
- return this.removeSchemaOfType(namespace, "grid");
92
+ getExistingSheetContent(opts) {
93
+ const sheet = this.workbookManager.getSheet(opts);
94
+ return sheet ? new Map(sheet.content) : undefined;
160
95
  }
161
- removeSchemaOfType(namespace, type) {
162
- const schema = this.schemaManager.getSchema(namespace);
163
- if (!schema || schema.type !== type) {
164
- return false;
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 }));
165
100
  }
166
- const removed = this.schemaManager.removeSchema(namespace);
167
- if (removed) {
168
- delete this.schema[namespace];
101
+ for (const tableName of this.tableManager.getTables(workbookName).keys()) {
102
+ resourceKeys.add(getTableResourceKey({ workbookName, tableName }));
169
103
  }
170
- return removed;
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);
171
139
  }
172
140
  getCellEvaluationResult(cellAddress) {
173
141
  return this.evaluationManager.getCellEvaluationResult(cellAddress);
@@ -180,7 +148,8 @@ class FormulaEngine {
180
148
  return this.evaluationManager.evaluationResultToSerializedValue(result, cellAddress, debug);
181
149
  }
182
150
  setCellMetadata(address, metadata) {
183
- this.commandExecutor.execute(new SetCellMetadataCommand(this.workbookManager, address, metadata));
151
+ this.workbookManager.setCellMetadata(address, metadata);
152
+ this.emitUpdate();
184
153
  }
185
154
  getCellMetadata(address) {
186
155
  const metadata = this.workbookManager.getCellMetadata(address);
@@ -190,13 +159,15 @@ class FormulaEngine {
190
159
  return this.workbookManager.getSheetMetadataSerialized(opts);
191
160
  }
192
161
  setSheetMetadata(opts, metadata) {
193
- this.commandExecutor.execute(new SetSheetMetadataCommand(this.workbookManager, opts, metadata));
162
+ this.workbookManager.setSheetMetadata(opts, metadata);
163
+ this.emitUpdate();
194
164
  }
195
165
  getSheetMetadata(opts) {
196
166
  return this.workbookManager.getSheetMetadata(opts);
197
167
  }
198
168
  setWorkbookMetadata(workbookName, metadata) {
199
- this.commandExecutor.execute(new SetWorkbookMetadataCommand(this.workbookManager, workbookName, metadata));
169
+ this.workbookManager.setWorkbookMetadata(workbookName, metadata);
170
+ this.emitUpdate();
200
171
  }
201
172
  getWorkbookMetadata(workbookName) {
202
173
  return this.workbookManager.getWorkbookMetadata(workbookName);
@@ -223,10 +194,20 @@ class FormulaEngine {
223
194
  throw new Error("Not implemented");
224
195
  }
225
196
  addNamedExpression(opts) {
226
- 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
+ });
227
202
  }
228
203
  removeNamedExpression(opts) {
229
- 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
+ }
230
211
  }
231
212
  hasNamedExpression(opts) {
232
213
  const scope = opts.sheetName && opts.workbookName ? {
@@ -240,25 +221,154 @@ class FormulaEngine {
240
221
  });
241
222
  }
242
223
  updateNamedExpression(opts) {
243
- 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
+ });
244
229
  }
245
230
  renameNamedExpression(opts) {
246
- 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
+ });
247
250
  }
248
251
  setNamedExpressions(opts) {
249
- 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
+ });
250
274
  }
251
275
  addTable(props) {
252
- 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
+ });
253
290
  }
254
291
  renameTable(workbookName, names) {
255
- 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
+ });
256
319
  }
257
320
  updateTable(opts) {
258
- 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
+ });
259
344
  }
260
345
  removeTable(opts) {
261
- 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
+ })));
262
372
  }
263
373
  hasTable(opts) {
264
374
  return !!this.tableManager.getTable({
@@ -273,7 +383,21 @@ class FormulaEngine {
273
383
  });
274
384
  }
275
385
  resetTables(tables) {
276
- 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
+ });
277
401
  }
278
402
  getTables(workbookName) {
279
403
  return this.tableManager.getTables(workbookName);
@@ -281,28 +405,15 @@ class FormulaEngine {
281
405
  isCellInTable(cellAddress) {
282
406
  return this.tableManager.isCellInTable(cellAddress);
283
407
  }
284
- getTableDataCells(table) {
285
- const { start, endRow, headers } = table;
286
- const dataStartRow = start.rowIndex + 1;
287
- const endColIndex = start.colIndex + headers.size - 1;
288
- const rangeAddress = {
289
- workbookName: table.workbookName,
290
- sheetName: table.sheetName,
291
- range: {
292
- start: { col: start.colIndex, row: dataStartRow },
293
- end: {
294
- col: { type: "number", value: endColIndex },
295
- row: endRow
296
- }
297
- }
298
- };
299
- return this.workbookManager.getCellsInRange(rangeAddress);
300
- }
301
408
  addConditionalStyle(style) {
302
- this.commandExecutor.execute(new AddConditionalStyleCommand(this.styleManager, style));
409
+ this.styleManager.addConditionalStyle(style);
410
+ this.emitUpdate();
303
411
  }
304
412
  removeConditionalStyle(workbookName, index) {
305
- this.commandExecutor.execute(new RemoveConditionalStyleCommand(this.styleManager, workbookName, index));
413
+ const removed = this.styleManager.removeConditionalStyle(workbookName, index);
414
+ if (removed) {
415
+ this.emitUpdate();
416
+ }
306
417
  }
307
418
  getConditionalStyleCount(workbookName) {
308
419
  const allStyles = this.styleManager.getAllConditionalStyles();
@@ -321,10 +432,14 @@ class FormulaEngine {
321
432
  return this.styleManager.getAllConditionalStyles();
322
433
  }
323
434
  addCellStyle(style) {
324
- this.commandExecutor.execute(new AddCellStyleCommand(this.styleManager, style));
435
+ this.styleManager.addCellStyle(style);
436
+ this.emitUpdate();
325
437
  }
326
438
  removeCellStyle(workbookName, index) {
327
- this.commandExecutor.execute(new RemoveCellStyleCommand(this.styleManager, workbookName, index));
439
+ const removed = this.styleManager.removeCellStyle(workbookName, index);
440
+ if (removed) {
441
+ this.emitUpdate();
442
+ }
328
443
  }
329
444
  getCellStyleCount(workbookName) {
330
445
  const allStyles = this.styleManager.getAllCellStyles();
@@ -337,13 +452,69 @@ class FormulaEngine {
337
452
  return this.styleManager.getStyleForRange(range);
338
453
  }
339
454
  clearCellStyles(range) {
340
- 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);
341
484
  }
342
485
  pasteCells(source, target, options) {
343
- 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
+ });
344
501
  }
345
502
  fillAreas(seedRange, targetRanges, options) {
346
- 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
+ });
347
518
  }
348
519
  smartPaste(sourceCells, pasteSelection, options) {
349
520
  if (sourceCells.length === 0) {
@@ -424,17 +595,27 @@ class FormulaEngine {
424
595
  return { minCol, minRow, maxCol, maxRow };
425
596
  }
426
597
  moveCell(source, target) {
427
- 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
+ });
428
603
  }
429
604
  moveRange(sourceRange, target) {
430
- 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
+ });
431
611
  }
432
612
  addSheet(opts) {
433
- this.commandExecutor.execute(new AddSheetCommand(this.getStructureCommandDeps(), opts), { validate: this.schemaManager.hasSchemas() });
434
- const sheet = this.workbookManager.getSheet(opts);
435
- if (!sheet) {
436
- throw new Error(`Failed to create sheet '${opts.sheetName}'`);
437
- }
613
+ const sheet = this.workbookManager.addSheet(opts);
614
+ this.namedExpressionManager.addSheet(opts);
615
+ this.emitMutation({
616
+ touchedCells: [],
617
+ resourceKeys: [getSheetResourceKey(opts)]
618
+ });
438
619
  return sheet;
439
620
  }
440
621
  createSheet(opts) {
@@ -445,10 +626,40 @@ class FormulaEngine {
445
626
  });
446
627
  }
447
628
  removeSheet(opts) {
448
- 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
+ });
449
640
  }
450
641
  renameSheet(opts) {
451
- 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
+ });
452
663
  }
453
664
  hasSheet(opts) {
454
665
  return !!this.workbookManager.getSheet(opts);
@@ -475,34 +686,197 @@ class FormulaEngine {
475
686
  return this.workbookManager.getSheetSerialized(opts);
476
687
  }
477
688
  addWorkbook(workbookName) {
478
- 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
+ });
479
696
  }
480
697
  removeWorkbook(workbookName) {
481
- 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
+ });
482
709
  }
483
710
  hasWorkbook(workbookName) {
484
711
  return this.workbookManager.getWorkbooks().has(workbookName);
485
712
  }
486
713
  cloneWorkbook(fromWorkbookName, toWorkbookName) {
487
- 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
+ });
488
804
  }
489
805
  renameWorkbook(opts) {
490
- 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
+ });
491
824
  }
492
825
  getWorkbooks() {
493
826
  return this.workbookManager.getWorkbooks();
494
827
  }
495
828
  setSheetContent(opts, content) {
496
- 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
+ });
497
835
  }
498
836
  setCellContent(address, content) {
499
- 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
+ });
500
849
  }
501
850
  autoFill(opts, seedRange, fillRanges, direction) {
502
- 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
+ });
503
867
  }
504
868
  clearSpreadsheetRange(address) {
505
- 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
+ });
506
880
  }
507
881
  getState() {
508
882
  return {
@@ -558,63 +932,11 @@ class FormulaEngine {
558
932
  dependency: deserialized.managers.dependency,
559
933
  cache: deserialized.managers.cache
560
934
  }, this.evaluationManager);
561
- this.commandExecutor.clearHistory();
562
- this.commandExecutor.clearActionLog();
563
935
  this.eventManager.emitUpdate();
564
936
  }
565
- undo() {
566
- return this.commandExecutor.undo();
567
- }
568
- redo() {
569
- return this.commandExecutor.redo();
570
- }
571
- canUndo() {
572
- return this.commandExecutor.canUndo();
573
- }
574
- canRedo() {
575
- return this.commandExecutor.canRedo();
576
- }
577
- getActionLog() {
578
- return this.commandExecutor.getActionLog();
579
- }
580
- clearActionLog() {
581
- this.commandExecutor.clearActionLog();
582
- }
583
- clearHistory() {
584
- this.commandExecutor.clearHistory();
585
- }
586
- getStructureCommandDeps() {
587
- return {
588
- workbookManager: this.workbookManager,
589
- namedExpressionManager: this.namedExpressionManager,
590
- tableManager: this.tableManager,
591
- styleManager: this.styleManager,
592
- referenceManager: this.referenceManager,
593
- apiSchemaManager: this.schemaManager,
594
- renameSheetInFormula,
595
- renameWorkbookInFormula
596
- };
597
- }
598
- getTableCommandDeps() {
599
- return {
600
- tableManager: this.tableManager,
601
- namedExpressionManager: this.namedExpressionManager,
602
- workbookManager: this.workbookManager,
603
- apiSchemaManager: this.schemaManager,
604
- getCellValue: (cell) => this.getCellValue(cell),
605
- renameTableInFormula
606
- };
607
- }
608
- getNamedExpressionCommandDeps() {
609
- return {
610
- namedExpressionManager: this.namedExpressionManager,
611
- workbookManager: this.workbookManager,
612
- renameNamedExpressionInFormula
613
- };
614
- }
615
937
  }
616
938
  export {
617
939
  FormulaEngine
618
940
  };
619
941
 
620
- //# debugId=613601FAC854C5A464756E2164756E21
942
+ //# debugId=1DF8797947659AB164756E2164756E21