@ricsam/formula-engine 0.0.16 → 0.0.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/core/api/api-builder.cjs +67 -0
- package/dist/cjs/core/api/api-builder.cjs.map +10 -0
- package/dist/cjs/core/api/api-helpers.cjs +191 -0
- package/dist/cjs/core/api/api-helpers.cjs.map +10 -0
- package/dist/cjs/core/api/api.cjs +65 -0
- package/dist/cjs/core/api/api.cjs.map +10 -0
- package/dist/cjs/core/api/cell-orm.cjs +80 -0
- package/dist/cjs/core/api/cell-orm.cjs.map +10 -0
- package/dist/cjs/core/api/table-orm.cjs +171 -0
- package/dist/cjs/core/api/table-orm.cjs.map +10 -0
- package/dist/cjs/core/autofill-utils.cjs +75 -39
- package/dist/cjs/core/autofill-utils.cjs.map +3 -3
- package/dist/cjs/core/cell-mover.cjs +178 -0
- package/dist/cjs/core/cell-mover.cjs.map +10 -0
- package/dist/cjs/core/commands/command-executor.cjs +140 -0
- package/dist/cjs/core/commands/command-executor.cjs.map +10 -0
- package/dist/cjs/core/commands/content-commands.cjs +574 -0
- package/dist/cjs/core/commands/content-commands.cjs.map +10 -0
- package/dist/cjs/core/commands/index.cjs +95 -0
- package/dist/cjs/core/commands/index.cjs.map +10 -0
- package/dist/cjs/core/commands/metadata-commands.cjs +150 -0
- package/dist/cjs/core/commands/metadata-commands.cjs.map +10 -0
- package/dist/cjs/core/commands/named-expression-commands.cjs +238 -0
- package/dist/cjs/core/commands/named-expression-commands.cjs.map +10 -0
- package/dist/cjs/core/commands/structure-commands.cjs +495 -0
- package/dist/cjs/core/commands/structure-commands.cjs.map +10 -0
- package/dist/cjs/core/commands/style-commands.cjs +219 -0
- package/dist/cjs/core/commands/style-commands.cjs.map +10 -0
- package/dist/cjs/core/commands/table-commands.cjs +226 -0
- package/dist/cjs/core/commands/table-commands.cjs.map +10 -0
- package/dist/cjs/core/commands/types.cjs +72 -0
- package/dist/cjs/core/commands/types.cjs.map +10 -0
- package/dist/cjs/core/engine.cjs +218 -263
- package/dist/cjs/core/engine.cjs.map +3 -3
- package/dist/cjs/core/managers/api-schema-manager.cjs +304 -0
- package/dist/cjs/core/managers/api-schema-manager.cjs.map +10 -0
- package/dist/cjs/core/managers/copy-manager.cjs +336 -82
- package/dist/cjs/core/managers/copy-manager.cjs.map +3 -3
- package/dist/cjs/core/managers/reference-manager.cjs +124 -0
- package/dist/cjs/core/managers/reference-manager.cjs.map +10 -0
- package/dist/cjs/core/managers/style-manager.cjs +115 -147
- package/dist/cjs/core/managers/style-manager.cjs.map +3 -3
- package/dist/cjs/core/managers/workbook-manager.cjs +87 -3
- package/dist/cjs/core/managers/workbook-manager.cjs.map +3 -3
- package/dist/cjs/core/types.cjs.map +1 -1
- package/dist/cjs/lib.cjs +13 -2
- package/dist/cjs/lib.cjs.map +3 -3
- package/dist/cjs/package.json +1 -1
- package/dist/mjs/core/api/api-builder.mjs +37 -0
- package/dist/mjs/core/api/api-builder.mjs.map +10 -0
- package/dist/mjs/core/api/api-helpers.mjs +161 -0
- package/dist/mjs/core/api/api-helpers.mjs.map +10 -0
- package/dist/mjs/core/api/api.mjs +35 -0
- package/dist/mjs/core/api/api.mjs.map +10 -0
- package/dist/mjs/core/api/cell-orm.mjs +49 -0
- package/dist/mjs/core/api/cell-orm.mjs.map +10 -0
- package/dist/mjs/core/api/table-orm.mjs +148 -0
- package/dist/mjs/core/api/table-orm.mjs.map +10 -0
- package/dist/mjs/core/autofill-utils.mjs +75 -39
- package/dist/mjs/core/autofill-utils.mjs.map +3 -3
- package/dist/mjs/core/cell-mover.mjs +148 -0
- package/dist/mjs/core/cell-mover.mjs.map +10 -0
- package/dist/mjs/core/commands/command-executor.mjs +109 -0
- package/dist/mjs/core/commands/command-executor.mjs.map +10 -0
- package/dist/mjs/core/commands/content-commands.mjs +544 -0
- package/dist/mjs/core/commands/content-commands.mjs.map +10 -0
- package/dist/mjs/core/commands/index.mjs +87 -0
- package/dist/mjs/core/commands/index.mjs.map +10 -0
- package/dist/mjs/core/commands/metadata-commands.mjs +120 -0
- package/dist/mjs/core/commands/metadata-commands.mjs.map +10 -0
- package/dist/mjs/core/commands/named-expression-commands.mjs +208 -0
- package/dist/mjs/core/commands/named-expression-commands.mjs.map +10 -0
- package/dist/mjs/core/commands/structure-commands.mjs +465 -0
- package/dist/mjs/core/commands/structure-commands.mjs.map +10 -0
- package/dist/mjs/core/commands/style-commands.mjs +189 -0
- package/dist/mjs/core/commands/style-commands.mjs.map +10 -0
- package/dist/mjs/core/commands/table-commands.mjs +196 -0
- package/dist/mjs/core/commands/table-commands.mjs.map +10 -0
- package/dist/mjs/core/commands/types.mjs +42 -0
- package/dist/mjs/core/commands/types.mjs.map +10 -0
- package/dist/mjs/core/engine.mjs +253 -263
- package/dist/mjs/core/engine.mjs.map +3 -3
- package/dist/mjs/core/managers/api-schema-manager.mjs +274 -0
- package/dist/mjs/core/managers/api-schema-manager.mjs.map +10 -0
- package/dist/mjs/core/managers/copy-manager.mjs +338 -82
- package/dist/mjs/core/managers/copy-manager.mjs.map +3 -3
- package/dist/mjs/core/managers/reference-manager.mjs +93 -0
- package/dist/mjs/core/managers/reference-manager.mjs.map +10 -0
- package/dist/mjs/core/managers/style-manager.mjs +115 -147
- package/dist/mjs/core/managers/style-manager.mjs.map +3 -3
- package/dist/mjs/core/managers/workbook-manager.mjs +87 -3
- package/dist/mjs/core/managers/workbook-manager.mjs.map +3 -3
- package/dist/mjs/core/types.mjs.map +1 -1
- package/dist/mjs/lib.mjs +13 -2
- package/dist/mjs/lib.mjs.map +3 -3
- package/dist/mjs/package.json +1 -1
- package/dist/types/core/api/api-builder.d.ts +16 -0
- package/dist/types/core/api/api-helpers.d.ts +37 -0
- package/dist/types/core/api/api.d.ts +83 -0
- package/dist/types/core/api/api.type-test.d.ts +1 -0
- package/dist/types/core/api/cell-orm.d.ts +29 -0
- package/dist/types/core/api/table-orm.d.ts +46 -0
- package/dist/types/core/autofill-utils.d.ts +6 -9
- package/dist/types/core/cell-mover.d.ts +63 -0
- package/dist/types/core/commands/command-executor.d.ts +83 -0
- package/dist/types/core/commands/content-commands.d.ts +142 -0
- package/dist/types/core/commands/index.d.ts +16 -0
- package/dist/types/core/commands/metadata-commands.d.ts +55 -0
- package/dist/types/core/commands/named-expression-commands.d.ts +115 -0
- package/dist/types/core/commands/structure-commands.d.ts +132 -0
- package/dist/types/core/commands/style-commands.d.ts +76 -0
- package/dist/types/core/commands/table-commands.d.ts +104 -0
- package/dist/types/core/commands/types.d.ts +114 -0
- package/dist/types/core/engine.d.ts +241 -23
- package/dist/types/core/managers/api-schema-manager.d.ts +121 -0
- package/dist/types/core/managers/copy-manager.d.ts +47 -2
- package/dist/types/core/managers/reference-manager.d.ts +54 -0
- package/dist/types/core/managers/style-manager.d.ts +6 -6
- package/dist/types/core/managers/workbook-manager.d.ts +39 -1
- package/dist/types/core/types.d.ts +52 -11
- package/dist/types/lib.d.ts +8 -0
- package/package.json +1 -1
|
@@ -12,10 +12,21 @@ import { EventManager } from "./managers/event-manager";
|
|
|
12
12
|
import { EvaluationManager } from "./managers/evaluation-manager";
|
|
13
13
|
import { DependencyManager } from "./managers/dependency-manager";
|
|
14
14
|
import { StyleManager } from "./managers/style-manager";
|
|
15
|
+
import type { Api, CreateApi, Declaration } from "./api/api";
|
|
16
|
+
import { type EngineAction } from "./commands";
|
|
17
|
+
type Metadata = {
|
|
18
|
+
cell?: unknown;
|
|
19
|
+
sheet?: unknown;
|
|
20
|
+
workbook?: unknown;
|
|
21
|
+
};
|
|
22
|
+
type MetadataType<TMetadata extends Metadata, TKey extends keyof Metadata> = TMetadata[TKey];
|
|
15
23
|
/**
|
|
16
24
|
* Main FormulaEngine class
|
|
25
|
+
* @template TCellMetadata - Consumer-defined type for cell metadata (rich text, links, custom data, etc.)
|
|
26
|
+
* @template TSheetMetadata - Consumer-defined type for sheet metadata (text boxes, frozen panes, etc.)
|
|
27
|
+
* @template TWorkbookMetadata - Consumer-defined type for workbook metadata (themes, document properties, etc.)
|
|
17
28
|
*/
|
|
18
|
-
export declare class FormulaEngine {
|
|
29
|
+
export declare class FormulaEngine<TMetadata extends Metadata = Metadata, TCreateApi extends CreateApi<MetadataType<TMetadata, "cell">, Api, Declaration> | undefined = undefined> {
|
|
19
30
|
private workbookManager;
|
|
20
31
|
private namedExpressionManager;
|
|
21
32
|
private tableManager;
|
|
@@ -25,6 +36,11 @@ export declare class FormulaEngine {
|
|
|
25
36
|
private dependencyManager;
|
|
26
37
|
private styleManager;
|
|
27
38
|
private copyManager;
|
|
39
|
+
private referenceManager;
|
|
40
|
+
private apiSchemaManager;
|
|
41
|
+
private commandExecutor;
|
|
42
|
+
api: TCreateApi extends CreateApi<MetadataType<TMetadata, "cell">, Api, Declaration> ? TCreateApi["api"] : undefined;
|
|
43
|
+
private apiDeclaration;
|
|
28
44
|
/**
|
|
29
45
|
* Public access to the store manager for testing
|
|
30
46
|
*/
|
|
@@ -36,13 +52,77 @@ export declare class FormulaEngine {
|
|
|
36
52
|
_autoFillManager: AutoFill;
|
|
37
53
|
_dependencyManager: DependencyManager;
|
|
38
54
|
_styleManager: StyleManager;
|
|
39
|
-
constructor();
|
|
55
|
+
constructor(api?: TCreateApi);
|
|
40
56
|
/**
|
|
41
57
|
* Static factory method to build an empty engine
|
|
58
|
+
* @template TC - Consumer-defined cell metadata type
|
|
59
|
+
* @template TS - Consumer-defined sheet metadata type
|
|
60
|
+
* @template TW - Consumer-defined workbook metadata type
|
|
42
61
|
*/
|
|
43
|
-
static buildEmpty(): FormulaEngine
|
|
62
|
+
static buildEmpty<TMetadata extends Metadata = Metadata, TApiDeclaration extends CreateApi<MetadataType<TMetadata, "cell">, any, any> | undefined = undefined>(api?: TApiDeclaration): FormulaEngine<TMetadata, TApiDeclaration>;
|
|
44
63
|
getCellEvaluationResult(cellAddress: CellAddress): SingleEvaluationResult | undefined;
|
|
45
64
|
getCellValue(cellAddress: CellAddress, debug?: boolean): SerializedCellValue;
|
|
65
|
+
/**
|
|
66
|
+
* Set metadata for a cell
|
|
67
|
+
* Metadata can contain rich text, links, comments, or any consumer-defined data
|
|
68
|
+
*/
|
|
69
|
+
setCellMetadata(address: CellAddress, metadata: MetadataType<TMetadata, "cell"> | undefined): void;
|
|
70
|
+
/**
|
|
71
|
+
* Get metadata for a cell
|
|
72
|
+
*/
|
|
73
|
+
getCellMetadata(address: CellAddress): MetadataType<TMetadata, "cell"> | undefined;
|
|
74
|
+
/**
|
|
75
|
+
* Get all cell metadata for a sheet (serialized as Map)
|
|
76
|
+
*/
|
|
77
|
+
getSheetMetadataSerialized(opts: {
|
|
78
|
+
sheetName: string;
|
|
79
|
+
workbookName: string;
|
|
80
|
+
}): Map<string, MetadataType<TMetadata, "sheet">>;
|
|
81
|
+
/**
|
|
82
|
+
* Set metadata for a sheet
|
|
83
|
+
* Sheet metadata can contain text boxes, frozen panes, print settings, or any consumer-defined data
|
|
84
|
+
*/
|
|
85
|
+
setSheetMetadata(opts: {
|
|
86
|
+
workbookName: string;
|
|
87
|
+
sheetName: string;
|
|
88
|
+
}, metadata: MetadataType<TMetadata, "sheet">): void;
|
|
89
|
+
/**
|
|
90
|
+
* Get metadata for a sheet
|
|
91
|
+
*/
|
|
92
|
+
getSheetMetadata(opts: {
|
|
93
|
+
workbookName: string;
|
|
94
|
+
sheetName: string;
|
|
95
|
+
}): MetadataType<TMetadata, "sheet"> | undefined;
|
|
96
|
+
/**
|
|
97
|
+
* Set metadata for a workbook
|
|
98
|
+
* Workbook metadata can contain themes, document properties, settings, or any consumer-defined data
|
|
99
|
+
*/
|
|
100
|
+
setWorkbookMetadata(workbookName: string, metadata: MetadataType<TMetadata, "workbook">): void;
|
|
101
|
+
/**
|
|
102
|
+
* Get metadata for a workbook
|
|
103
|
+
*/
|
|
104
|
+
getWorkbookMetadata(workbookName: string): MetadataType<TMetadata, "workbook"> | undefined;
|
|
105
|
+
/**
|
|
106
|
+
* Create a tracked reference to a range
|
|
107
|
+
* Returns a stable UUID that can be used to retrieve the address later
|
|
108
|
+
* The reference automatically updates when sheets/workbooks are renamed
|
|
109
|
+
*/
|
|
110
|
+
createRef(address: RangeAddress): string;
|
|
111
|
+
/**
|
|
112
|
+
* Get the current address for a tracked reference
|
|
113
|
+
* Returns undefined if reference doesn't exist or has been invalidated
|
|
114
|
+
*/
|
|
115
|
+
getRefAddress(refId: string): RangeAddress | undefined;
|
|
116
|
+
/**
|
|
117
|
+
* Delete a tracked reference
|
|
118
|
+
* Returns true if the reference was deleted, false if it didn't exist
|
|
119
|
+
*/
|
|
120
|
+
deleteRef(refId: string): boolean;
|
|
121
|
+
/**
|
|
122
|
+
* Get all invalid reference IDs
|
|
123
|
+
* Useful for cleanup after sheet/workbook deletions
|
|
124
|
+
*/
|
|
125
|
+
getInvalidRefs(): string[];
|
|
46
126
|
evaluateFormula(
|
|
47
127
|
/**
|
|
48
128
|
* formula without the leading = sign
|
|
@@ -50,29 +130,37 @@ export declare class FormulaEngine {
|
|
|
50
130
|
formula: string, cellAddress: CellAddress): SerializedCellValue;
|
|
51
131
|
getCellDependents(address: CellAddress | SpreadsheetRange): (SpreadsheetRange | CellAddress)[];
|
|
52
132
|
getCellPrecedents(address: CellAddress | SpreadsheetRange): (SpreadsheetRange | CellAddress)[];
|
|
53
|
-
addNamedExpression(
|
|
133
|
+
addNamedExpression(opts: {
|
|
54
134
|
expression: string;
|
|
55
135
|
expressionName: string;
|
|
56
136
|
sheetName?: string;
|
|
57
137
|
workbookName?: string;
|
|
58
138
|
}): void;
|
|
59
|
-
removeNamedExpression(
|
|
139
|
+
removeNamedExpression(opts: {
|
|
140
|
+
expressionName: string;
|
|
141
|
+
sheetName?: string;
|
|
142
|
+
workbookName?: string;
|
|
143
|
+
}): void;
|
|
144
|
+
/**
|
|
145
|
+
* Check if a named expression exists
|
|
146
|
+
*/
|
|
147
|
+
hasNamedExpression(opts: {
|
|
60
148
|
expressionName: string;
|
|
61
149
|
sheetName?: string;
|
|
62
150
|
workbookName?: string;
|
|
63
151
|
}): boolean;
|
|
64
|
-
updateNamedExpression(
|
|
152
|
+
updateNamedExpression(opts: {
|
|
65
153
|
expression: string;
|
|
66
154
|
expressionName: string;
|
|
67
155
|
sheetName?: string;
|
|
68
156
|
workbookName?: string;
|
|
69
157
|
}): void;
|
|
70
|
-
renameNamedExpression(
|
|
158
|
+
renameNamedExpression(opts: {
|
|
71
159
|
expressionName: string;
|
|
72
160
|
sheetName?: string;
|
|
73
161
|
workbookName?: string;
|
|
74
162
|
newName: string;
|
|
75
|
-
}):
|
|
163
|
+
}): void;
|
|
76
164
|
setNamedExpressions(opts: ({
|
|
77
165
|
type: "global";
|
|
78
166
|
} | {
|
|
@@ -92,7 +180,7 @@ export declare class FormulaEngine {
|
|
|
92
180
|
start: string;
|
|
93
181
|
numRows: SpreadsheetRangeEnd;
|
|
94
182
|
numCols: number;
|
|
95
|
-
}):
|
|
183
|
+
}): void;
|
|
96
184
|
renameTable(workbookName: string, names: {
|
|
97
185
|
oldName: string;
|
|
98
186
|
newName: string;
|
|
@@ -108,10 +196,29 @@ export declare class FormulaEngine {
|
|
|
108
196
|
removeTable(opts: {
|
|
109
197
|
tableName: string;
|
|
110
198
|
workbookName: string;
|
|
199
|
+
}): void;
|
|
200
|
+
/**
|
|
201
|
+
* Check if a table exists
|
|
202
|
+
*/
|
|
203
|
+
hasTable(opts: {
|
|
204
|
+
tableName: string;
|
|
205
|
+
workbookName: string;
|
|
111
206
|
}): boolean;
|
|
207
|
+
/**
|
|
208
|
+
* Get a table definition by name
|
|
209
|
+
*/
|
|
210
|
+
getTable(opts: {
|
|
211
|
+
tableName: string;
|
|
212
|
+
workbookName: string;
|
|
213
|
+
}): TableDefinition | undefined;
|
|
112
214
|
resetTables(tables: Map<string, Map<string, TableDefinition>>): void;
|
|
113
215
|
getTables(workbookName: string): Map<string, TableDefinition>;
|
|
114
216
|
isCellInTable(cellAddress: CellAddress): TableDefinition | undefined;
|
|
217
|
+
/**
|
|
218
|
+
* Get all data cells in a table (excluding header row).
|
|
219
|
+
* Uses workbook indexes to efficiently handle infinite tables.
|
|
220
|
+
*/
|
|
221
|
+
private getTableDataCells;
|
|
115
222
|
/**
|
|
116
223
|
* Add a conditional style rule
|
|
117
224
|
*/
|
|
@@ -119,7 +226,11 @@ export declare class FormulaEngine {
|
|
|
119
226
|
/**
|
|
120
227
|
* Remove a conditional style rule by index
|
|
121
228
|
*/
|
|
122
|
-
removeConditionalStyle(workbookName: string, index: number):
|
|
229
|
+
removeConditionalStyle(workbookName: string, index: number): void;
|
|
230
|
+
/**
|
|
231
|
+
* Get the count of conditional styles for a workbook
|
|
232
|
+
*/
|
|
233
|
+
getConditionalStyleCount(workbookName: string): number;
|
|
123
234
|
/**
|
|
124
235
|
* Get all conditional styles intersecting with a range
|
|
125
236
|
*/
|
|
@@ -128,6 +239,14 @@ export declare class FormulaEngine {
|
|
|
128
239
|
* Get the computed style for a specific cell
|
|
129
240
|
*/
|
|
130
241
|
getCellStyle(cellAddress: CellAddress): CellStyle | undefined;
|
|
242
|
+
/**
|
|
243
|
+
* Get all cell styles (for testing and serialization)
|
|
244
|
+
*/
|
|
245
|
+
getAllCellStyles(): DirectCellStyle[];
|
|
246
|
+
/**
|
|
247
|
+
* Get all conditional styles (for testing and serialization)
|
|
248
|
+
*/
|
|
249
|
+
getAllConditionalStyles(): ConditionalStyle[];
|
|
131
250
|
/**
|
|
132
251
|
* Add a direct cell style rule
|
|
133
252
|
*/
|
|
@@ -135,7 +254,11 @@ export declare class FormulaEngine {
|
|
|
135
254
|
/**
|
|
136
255
|
* Remove a direct cell style rule by index
|
|
137
256
|
*/
|
|
138
|
-
removeCellStyle(workbookName: string, index: number):
|
|
257
|
+
removeCellStyle(workbookName: string, index: number): void;
|
|
258
|
+
/**
|
|
259
|
+
* Get the count of direct cell styles for a workbook
|
|
260
|
+
*/
|
|
261
|
+
getCellStyleCount(workbookName: string): number;
|
|
139
262
|
/**
|
|
140
263
|
* Get all direct cell styles intersecting with a range
|
|
141
264
|
*/
|
|
@@ -221,53 +344,100 @@ export declare class FormulaEngine {
|
|
|
221
344
|
* Get bounds (min/max row/col) from an array of cell addresses
|
|
222
345
|
*/
|
|
223
346
|
private getBoundsFromCells;
|
|
347
|
+
/**
|
|
348
|
+
* Move a single cell to a new location
|
|
349
|
+
* Updates all formula references that point to the moved cell
|
|
350
|
+
*
|
|
351
|
+
* @param source - The cell to move
|
|
352
|
+
* @param target - The destination cell address
|
|
353
|
+
*
|
|
354
|
+
* @example
|
|
355
|
+
* // Move A1 to D5. If B1 contains =A1, it will be updated to =D5
|
|
356
|
+
* engine.moveCell(
|
|
357
|
+
* { workbookName, sheetName, colIndex: 0, rowIndex: 0 },
|
|
358
|
+
* { workbookName, sheetName, colIndex: 3, rowIndex: 4 }
|
|
359
|
+
* );
|
|
360
|
+
*/
|
|
361
|
+
moveCell(source: CellAddress, target: CellAddress): void;
|
|
362
|
+
/**
|
|
363
|
+
* Move a range of cells to a new location
|
|
364
|
+
* Updates all formula references that point to the moved cells
|
|
365
|
+
*
|
|
366
|
+
* @param sourceRange - The range to move
|
|
367
|
+
* @param target - The top-left destination cell address
|
|
368
|
+
*
|
|
369
|
+
* @example
|
|
370
|
+
* // Move A1:D5 to F10. If E1 contains =SUM(A1:D5), it will be updated to =SUM(F10:I14)
|
|
371
|
+
* engine.moveRange(
|
|
372
|
+
* {
|
|
373
|
+
* workbookName,
|
|
374
|
+
* sheetName,
|
|
375
|
+
* range: {
|
|
376
|
+
* start: { col: 0, row: 0 },
|
|
377
|
+
* end: { col: { type: "number", value: 3 }, row: { type: "number", value: 4 } }
|
|
378
|
+
* }
|
|
379
|
+
* },
|
|
380
|
+
* { workbookName, sheetName, colIndex: 5, rowIndex: 9 }
|
|
381
|
+
* );
|
|
382
|
+
*/
|
|
383
|
+
moveRange(sourceRange: RangeAddress, target: CellAddress): void;
|
|
224
384
|
addSheet(opts: {
|
|
225
385
|
workbookName: string;
|
|
226
386
|
sheetName: string;
|
|
227
|
-
}):
|
|
387
|
+
}): void;
|
|
228
388
|
removeSheet(opts: {
|
|
229
389
|
workbookName: string;
|
|
230
390
|
sheetName: string;
|
|
231
|
-
}):
|
|
391
|
+
}): void;
|
|
232
392
|
renameSheet(opts: {
|
|
233
393
|
sheetName: string;
|
|
234
394
|
newSheetName: string;
|
|
235
395
|
workbookName: string;
|
|
236
|
-
}):
|
|
237
|
-
|
|
396
|
+
}): void;
|
|
397
|
+
/**
|
|
398
|
+
* Check if a sheet exists
|
|
399
|
+
*/
|
|
400
|
+
hasSheet(opts: {
|
|
401
|
+
workbookName: string;
|
|
402
|
+
sheetName: string;
|
|
403
|
+
}): boolean;
|
|
404
|
+
getSheets(workbookName: string): Map<string, import("./types").Sheet<unknown, unknown>>;
|
|
238
405
|
getSheet({ workbookName, sheetName, }: {
|
|
239
406
|
workbookName: string;
|
|
240
407
|
sheetName: string;
|
|
241
|
-
}): import("./types").Sheet | undefined;
|
|
408
|
+
}): import("./types").Sheet<unknown, unknown> | undefined;
|
|
242
409
|
getSheetSerialized(opts: {
|
|
243
410
|
sheetName: string;
|
|
244
411
|
workbookName: string;
|
|
245
412
|
}): Map<string, SerializedCellValue>;
|
|
246
413
|
addWorkbook(workbookName: string): void;
|
|
247
414
|
removeWorkbook(workbookName: string): void;
|
|
415
|
+
/**
|
|
416
|
+
* Check if a workbook exists
|
|
417
|
+
*/
|
|
418
|
+
hasWorkbook(workbookName: string): boolean;
|
|
248
419
|
cloneWorkbook(fromWorkbookName: string, toWorkbookName: string): void;
|
|
249
420
|
renameWorkbook(opts: {
|
|
250
421
|
workbookName: string;
|
|
251
422
|
newWorkbookName: string;
|
|
252
423
|
}): void;
|
|
253
|
-
getWorkbooks(): Map<string, import("./types").Workbook
|
|
424
|
+
getWorkbooks(): Map<string, import("./types").Workbook<unknown, unknown, unknown>>;
|
|
254
425
|
/**
|
|
255
426
|
* Overrides the content of a sheet.
|
|
256
427
|
* @param sheetName - The name of the sheet to set the content of
|
|
257
428
|
* @param content - A map of cell addresses to their serialized values
|
|
258
429
|
* @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.
|
|
430
|
+
* @throws SchemaIntegrityError if any evaluated cell value violates a schema constraint
|
|
259
431
|
*/
|
|
260
432
|
setSheetContent(opts: {
|
|
261
433
|
sheetName: string;
|
|
262
434
|
workbookName: string;
|
|
263
435
|
}, content: Map<string, SerializedCellValue>): void;
|
|
264
|
-
setCellContent(address: CellAddress, content: SerializedCellValue): void;
|
|
265
436
|
/**
|
|
266
|
-
*
|
|
267
|
-
*
|
|
268
|
-
* but just clears the evaluation cache
|
|
437
|
+
* Set the content of a single cell.
|
|
438
|
+
* @throws SchemaIntegrityError if the evaluated value violates a schema constraint
|
|
269
439
|
*/
|
|
270
|
-
|
|
440
|
+
setCellContent(address: CellAddress, content: SerializedCellValue): void;
|
|
271
441
|
/**
|
|
272
442
|
* Auto-fills one or more ranges based on the seedRange and the direction.
|
|
273
443
|
* Supports pattern detection and style copying.
|
|
@@ -293,7 +463,7 @@ export declare class FormulaEngine {
|
|
|
293
463
|
*/
|
|
294
464
|
clearSpreadsheetRange(address: RangeAddress): void;
|
|
295
465
|
getState(): {
|
|
296
|
-
workbooks: Map<string, import("./types").Workbook
|
|
466
|
+
workbooks: Map<string, import("./types").Workbook<unknown, unknown, unknown>>;
|
|
297
467
|
namedExpressions: {
|
|
298
468
|
sheetExpressions: Map<string, Map<string, Map<string, NamedExpression>>>;
|
|
299
469
|
workbookExpressions: Map<string, Map<string, NamedExpression>>;
|
|
@@ -302,8 +472,56 @@ export declare class FormulaEngine {
|
|
|
302
472
|
tables: Map<string, Map<string, TableDefinition>>;
|
|
303
473
|
conditionalStyles: ConditionalStyle[];
|
|
304
474
|
cellStyles: DirectCellStyle[];
|
|
475
|
+
references: Map<string, import("./types").TrackedReference>;
|
|
305
476
|
};
|
|
306
477
|
onUpdate(listener: () => void): () => void;
|
|
307
478
|
serializeEngine(): string;
|
|
308
479
|
resetToSerializedEngine(data: string): void;
|
|
480
|
+
/**
|
|
481
|
+
* Undo the last command.
|
|
482
|
+
* @returns true if undo was performed, false if nothing to undo
|
|
483
|
+
*/
|
|
484
|
+
undo(): boolean;
|
|
485
|
+
/**
|
|
486
|
+
* Redo the last undone command.
|
|
487
|
+
* @returns true if redo was performed, false if nothing to redo
|
|
488
|
+
*/
|
|
489
|
+
redo(): boolean;
|
|
490
|
+
/**
|
|
491
|
+
* Check if undo is available.
|
|
492
|
+
*/
|
|
493
|
+
canUndo(): boolean;
|
|
494
|
+
/**
|
|
495
|
+
* Check if redo is available.
|
|
496
|
+
*/
|
|
497
|
+
canRedo(): boolean;
|
|
498
|
+
/**
|
|
499
|
+
* Get the action log for persistence/collaboration.
|
|
500
|
+
* Actions can be serialized and replayed to reconstruct state.
|
|
501
|
+
*/
|
|
502
|
+
getActionLog(): EngineAction[];
|
|
503
|
+
/**
|
|
504
|
+
* Clear the action log.
|
|
505
|
+
*/
|
|
506
|
+
clearActionLog(): void;
|
|
507
|
+
/**
|
|
508
|
+
* Clear undo/redo history.
|
|
509
|
+
*/
|
|
510
|
+
clearHistory(): void;
|
|
511
|
+
/**
|
|
512
|
+
* Get dependencies for structure commands.
|
|
513
|
+
* @internal
|
|
514
|
+
*/
|
|
515
|
+
private getStructureCommandDeps;
|
|
516
|
+
/**
|
|
517
|
+
* Get dependencies for table commands.
|
|
518
|
+
* @internal
|
|
519
|
+
*/
|
|
520
|
+
private getTableCommandDeps;
|
|
521
|
+
/**
|
|
522
|
+
* Get dependencies for named expression commands.
|
|
523
|
+
* @internal
|
|
524
|
+
*/
|
|
525
|
+
private getNamedExpressionCommandDeps;
|
|
309
526
|
}
|
|
527
|
+
export {};
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ApiSchemaManager - Manages API schema definitions and validation
|
|
3
|
+
*
|
|
4
|
+
* Tracks registered schemas and provides validation for cell writes,
|
|
5
|
+
* spill operations, and copy/paste operations.
|
|
6
|
+
*/
|
|
7
|
+
import type { CellAddress, SerializedCellValue, SpreadsheetRange, TableDefinition } from "../types";
|
|
8
|
+
import type { TableManager } from "./table-manager";
|
|
9
|
+
export type ParseFunction<TCellMetadata = unknown> = (value: unknown, metadata: TCellMetadata) => unknown;
|
|
10
|
+
export type TableSchemaHeaders<TCellMetadata = unknown> = Record<string, {
|
|
11
|
+
parse: ParseFunction<TCellMetadata>;
|
|
12
|
+
index: number;
|
|
13
|
+
}>;
|
|
14
|
+
export interface RegisteredTableSchema {
|
|
15
|
+
type: "table";
|
|
16
|
+
namespace: string;
|
|
17
|
+
workbookName: string;
|
|
18
|
+
tableName: string;
|
|
19
|
+
headers: TableSchemaHeaders;
|
|
20
|
+
}
|
|
21
|
+
export interface RegisteredCellSchema {
|
|
22
|
+
type: "cell";
|
|
23
|
+
namespace: string;
|
|
24
|
+
cellAddress: CellAddress;
|
|
25
|
+
parse: ParseFunction;
|
|
26
|
+
}
|
|
27
|
+
export type RegisteredSchema = RegisteredTableSchema | RegisteredCellSchema;
|
|
28
|
+
export interface ValidationResult {
|
|
29
|
+
valid: boolean;
|
|
30
|
+
error?: string;
|
|
31
|
+
originalError?: Error;
|
|
32
|
+
}
|
|
33
|
+
export declare class SchemaValidationError extends Error {
|
|
34
|
+
cellAddress?: CellAddress | undefined;
|
|
35
|
+
originalError?: Error | undefined;
|
|
36
|
+
constructor(message: string, cellAddress?: CellAddress | undefined, originalError?: Error | undefined);
|
|
37
|
+
}
|
|
38
|
+
export declare class ApiSchemaManager {
|
|
39
|
+
private tableManager;
|
|
40
|
+
private schemas;
|
|
41
|
+
constructor(tableManager: TableManager);
|
|
42
|
+
/**
|
|
43
|
+
* Register a table schema
|
|
44
|
+
*/
|
|
45
|
+
registerTableSchema(namespace: string, workbookName: string, tableName: string, headers: TableSchemaHeaders): void;
|
|
46
|
+
/**
|
|
47
|
+
* Register a cell schema
|
|
48
|
+
*/
|
|
49
|
+
registerCellSchema(namespace: string, cellAddress: CellAddress, parse: ParseFunction): void;
|
|
50
|
+
/**
|
|
51
|
+
* Get a schema by namespace
|
|
52
|
+
*/
|
|
53
|
+
getSchema(namespace: string): RegisteredSchema | undefined;
|
|
54
|
+
/**
|
|
55
|
+
* Remove a schema
|
|
56
|
+
*/
|
|
57
|
+
removeSchema(namespace: string): boolean;
|
|
58
|
+
/**
|
|
59
|
+
* Check if a cell is protected by a schema
|
|
60
|
+
* Returns the schema info if protected, null otherwise
|
|
61
|
+
*/
|
|
62
|
+
isCellProtected(cell: CellAddress): {
|
|
63
|
+
schema: RegisteredSchema;
|
|
64
|
+
columnName?: string;
|
|
65
|
+
} | null;
|
|
66
|
+
/**
|
|
67
|
+
* Check if a cell is within a table's data range (excluding header row)
|
|
68
|
+
*/
|
|
69
|
+
private isCellInTableDataRange;
|
|
70
|
+
/**
|
|
71
|
+
* Get column name by index from headers
|
|
72
|
+
*/
|
|
73
|
+
private getColumnNameByIndex;
|
|
74
|
+
/**
|
|
75
|
+
* Validate a cell write against schemas
|
|
76
|
+
*/
|
|
77
|
+
validateCellWrite(cell: CellAddress, value: SerializedCellValue, metadata?: unknown): ValidationResult;
|
|
78
|
+
/**
|
|
79
|
+
* Validate a spill area against schemas
|
|
80
|
+
* Returns validation result - if invalid, spill should produce #SPILL! error
|
|
81
|
+
*/
|
|
82
|
+
validateSpillArea(origin: CellAddress, spillArea: SpreadsheetRange, getSpillValue: (row: number, col: number) => SerializedCellValue, getMetadata?: (cell: CellAddress) => unknown): ValidationResult;
|
|
83
|
+
/**
|
|
84
|
+
* Update schemas when a table is renamed
|
|
85
|
+
*/
|
|
86
|
+
updateForTableRename(workbookName: string, oldTableName: string, newTableName: string): void;
|
|
87
|
+
/**
|
|
88
|
+
* Update schemas when a sheet is renamed
|
|
89
|
+
*/
|
|
90
|
+
updateForSheetRename(workbookName: string, oldSheetName: string, newSheetName: string): void;
|
|
91
|
+
/**
|
|
92
|
+
* Update schemas when a workbook is renamed
|
|
93
|
+
*/
|
|
94
|
+
updateForWorkbookRename(oldWorkbookName: string, newWorkbookName: string): void;
|
|
95
|
+
/**
|
|
96
|
+
* Get all schemas (for debugging/testing)
|
|
97
|
+
*/
|
|
98
|
+
getAllSchemas(): Map<string, RegisteredSchema>;
|
|
99
|
+
/**
|
|
100
|
+
* Validate all schema constraints using evaluated cell values.
|
|
101
|
+
*
|
|
102
|
+
* This is the key method for schema validation with rollback:
|
|
103
|
+
* - It validates EVALUATED values, not raw content
|
|
104
|
+
* - A cell with "=123+123" validates as number (246), not string
|
|
105
|
+
* - Called after re-evaluation to check all schema-constrained cells
|
|
106
|
+
*
|
|
107
|
+
* @param getCellValue - Function to get the evaluated value of a cell
|
|
108
|
+
* @param getCellMetadata - Optional function to get cell metadata
|
|
109
|
+
* @returns Validation result with all errors found
|
|
110
|
+
*/
|
|
111
|
+
validateAllSchemaConstraints(getCellValue: (cell: CellAddress) => SerializedCellValue, getCellMetadata?: (cell: CellAddress) => unknown, getTableDataCells?: (table: TableDefinition) => CellAddress[]): {
|
|
112
|
+
valid: boolean;
|
|
113
|
+
errors: Array<{
|
|
114
|
+
message: string;
|
|
115
|
+
cellAddress?: CellAddress;
|
|
116
|
+
schemaNamespace?: string;
|
|
117
|
+
columnName?: string;
|
|
118
|
+
originalError?: Error;
|
|
119
|
+
}>;
|
|
120
|
+
};
|
|
121
|
+
}
|
|
@@ -10,14 +10,59 @@ export declare class CopyManager {
|
|
|
10
10
|
private evaluationManager;
|
|
11
11
|
private styleManager;
|
|
12
12
|
constructor(workbookManager: WorkbookManager, evaluationManager: EvaluationManager, styleManager: StyleManager);
|
|
13
|
+
/**
|
|
14
|
+
* Normalize the include option to an array of parts to copy
|
|
15
|
+
*/
|
|
16
|
+
private normalizeInclude;
|
|
17
|
+
/**
|
|
18
|
+
* Check if a specific part should be included in the copy operation
|
|
19
|
+
*/
|
|
20
|
+
private shouldInclude;
|
|
13
21
|
/**
|
|
14
22
|
* Paste cells from source to target
|
|
23
|
+
* Delegates to cutCells for move operations or copyOnlyCells for copy operations
|
|
15
24
|
*/
|
|
16
|
-
|
|
25
|
+
pasteCells(source: CellAddress[], target: CellAddress, options: CopyCellsOptions): void;
|
|
26
|
+
/**
|
|
27
|
+
* Cut cells: Proper snapshot flow for move operations
|
|
28
|
+
* 1. Snapshot source cells (with styles)
|
|
29
|
+
* 2. Remove source cells and punch holes in style areas
|
|
30
|
+
* 3. Update references in OTHER cells (not in moved set)
|
|
31
|
+
* 4. Update formulas in snapshot and apply to target
|
|
32
|
+
*/
|
|
33
|
+
private cutCells;
|
|
34
|
+
/**
|
|
35
|
+
* Copy cells: Standard copy operation (not cut/move)
|
|
36
|
+
* Snapshot → Copy with adjustment → Copy formatting
|
|
37
|
+
*/
|
|
38
|
+
private copyOnlyCells;
|
|
17
39
|
/**
|
|
18
40
|
* Find the top-left cell (minimum row/col indices)
|
|
19
41
|
*/
|
|
20
42
|
private findTopLeft;
|
|
43
|
+
/**
|
|
44
|
+
* Create a snapshot of cells' content and metadata
|
|
45
|
+
* This prevents issues with overlapping ranges where source and target overlap
|
|
46
|
+
* Used for copy operations (not cut)
|
|
47
|
+
*/
|
|
48
|
+
private snapshotCells;
|
|
49
|
+
/**
|
|
50
|
+
* Create a snapshot of cells with content, metadata, AND styles
|
|
51
|
+
* Used for cut operations to preserve all cell information
|
|
52
|
+
*/
|
|
53
|
+
private snapshotCellsWithStyles;
|
|
54
|
+
/**
|
|
55
|
+
* Apply styles from a snapshot to a target cell
|
|
56
|
+
* Creates new style areas at the target location
|
|
57
|
+
*/
|
|
58
|
+
private applyStylesFromSnapshot;
|
|
59
|
+
/**
|
|
60
|
+
* Copy content from a cell snapshot to a target cell
|
|
61
|
+
*/
|
|
62
|
+
private copyCellContentFromSnapshot;
|
|
63
|
+
/**
|
|
64
|
+
* Update all formula references when cells are cut (moved)
|
|
65
|
+
*/
|
|
21
66
|
/**
|
|
22
67
|
* Copy content from one cell to another
|
|
23
68
|
*/
|
|
@@ -69,7 +114,7 @@ export declare class CopyManager {
|
|
|
69
114
|
* Expand a RangeAddress into an array of CellAddress
|
|
70
115
|
* Handles finite ranges, row-bounded, and column-bounded ranges
|
|
71
116
|
*/
|
|
72
|
-
|
|
117
|
+
expandRangeToCells(rangeAddress: RangeAddress): CellAddress[];
|
|
73
118
|
/**
|
|
74
119
|
* Copy cell content with explicit row/column offset for fill operations
|
|
75
120
|
*/
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ReferenceManager - Manages tracked references for external elements
|
|
3
|
+
*
|
|
4
|
+
* Allows consumers to create stable references to ranges that automatically
|
|
5
|
+
* update when sheets/workbooks are renamed and become invalid when deleted.
|
|
6
|
+
*/
|
|
7
|
+
import type { RangeAddress, TrackedReference } from "../types";
|
|
8
|
+
export declare class ReferenceManager {
|
|
9
|
+
private references;
|
|
10
|
+
constructor();
|
|
11
|
+
/**
|
|
12
|
+
* Create a new tracked reference
|
|
13
|
+
* Returns UUID for the reference
|
|
14
|
+
*/
|
|
15
|
+
createRef(address: RangeAddress): string;
|
|
16
|
+
/**
|
|
17
|
+
* Get the current address for a reference
|
|
18
|
+
* Returns undefined if reference doesn't exist or is invalid
|
|
19
|
+
*/
|
|
20
|
+
getRefAddress(refId: string): RangeAddress | undefined;
|
|
21
|
+
/**
|
|
22
|
+
* Delete a reference
|
|
23
|
+
* Returns true if reference was deleted, false if it didn't exist
|
|
24
|
+
*/
|
|
25
|
+
deleteRef(refId: string): boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Get all invalid reference IDs
|
|
28
|
+
*/
|
|
29
|
+
getInvalidRefs(): string[];
|
|
30
|
+
/**
|
|
31
|
+
* Update references when sheet is renamed
|
|
32
|
+
*/
|
|
33
|
+
updateSheetName(workbookName: string, oldSheetName: string, newSheetName: string): void;
|
|
34
|
+
/**
|
|
35
|
+
* Update references when workbook is renamed
|
|
36
|
+
*/
|
|
37
|
+
updateWorkbookName(oldWorkbookName: string, newWorkbookName: string): void;
|
|
38
|
+
/**
|
|
39
|
+
* Mark references as invalid when sheet is removed
|
|
40
|
+
*/
|
|
41
|
+
invalidateSheet(workbookName: string, sheetName: string): void;
|
|
42
|
+
/**
|
|
43
|
+
* Mark references as invalid when workbook is removed
|
|
44
|
+
*/
|
|
45
|
+
invalidateWorkbook(workbookName: string): void;
|
|
46
|
+
/**
|
|
47
|
+
* Get all references for serialization
|
|
48
|
+
*/
|
|
49
|
+
getAllReferences(): Map<string, TrackedReference>;
|
|
50
|
+
/**
|
|
51
|
+
* Restore references from serialization
|
|
52
|
+
*/
|
|
53
|
+
resetReferences(refs: Map<string, TrackedReference>): void;
|
|
54
|
+
}
|
|
@@ -34,7 +34,7 @@ export declare class StyleManager {
|
|
|
34
34
|
getStylesIntersectingWithRange(range: RangeAddress): DirectCellStyle[];
|
|
35
35
|
/**
|
|
36
36
|
* Get the style for a range if all cells in the range have the same style
|
|
37
|
-
* Returns the DirectCellStyle if the range is completely contained within a single style's
|
|
37
|
+
* Returns the DirectCellStyle if the range is completely contained within a single style's areas
|
|
38
38
|
* Returns undefined if multiple styles, partial coverage, or no styles apply
|
|
39
39
|
*/
|
|
40
40
|
getStyleForRange(range: RangeAddress): DirectCellStyle | undefined;
|
|
@@ -100,12 +100,12 @@ export declare class StyleManager {
|
|
|
100
100
|
clearCellStyles(range: RangeAddress): void;
|
|
101
101
|
/**
|
|
102
102
|
* Clear cell styles in a range using subtraction
|
|
103
|
-
* For each intersecting style, subtract the cleared range:
|
|
104
|
-
* - If
|
|
105
|
-
* - If
|
|
106
|
-
* - If no intersection: keep unchanged
|
|
103
|
+
* For each intersecting style, subtract the cleared range from its areas:
|
|
104
|
+
* - If an area is completely contained: remove that area
|
|
105
|
+
* - If an area partially overlaps: split into remaining rectangles (hole punching)
|
|
106
|
+
* - If no intersection: keep area unchanged
|
|
107
107
|
*
|
|
108
|
-
* This matches Excel's behavior where pasting
|
|
108
|
+
* This matches Excel's behavior where cutting/pasting creates multi-area styles
|
|
109
109
|
*/
|
|
110
110
|
clearCellStylesInRange(range: RangeAddress): void;
|
|
111
111
|
}
|