@ricsam/formula-engine 0.2.11 → 0.2.12
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/autofill-utils.cjs +68 -2
- package/dist/cjs/core/autofill-utils.cjs.map +3 -3
- package/dist/cjs/core/engine-snapshot.cjs +2 -2
- package/dist/cjs/core/engine-snapshot.cjs.map +3 -3
- package/dist/cjs/core/engine.cjs +47 -3
- package/dist/cjs/core/engine.cjs.map +3 -3
- package/dist/cjs/core/managers/copy-manager.cjs +163 -14
- package/dist/cjs/core/managers/copy-manager.cjs.map +3 -3
- package/dist/cjs/core/managers/range-metadata-manager.cjs +135 -0
- package/dist/cjs/core/managers/range-metadata-manager.cjs.map +10 -0
- package/dist/cjs/core/types.cjs.map +1 -1
- package/dist/cjs/package.json +1 -1
- package/dist/mjs/core/autofill-utils.mjs +68 -2
- package/dist/mjs/core/autofill-utils.mjs.map +3 -3
- package/dist/mjs/core/engine-snapshot.mjs +2 -2
- package/dist/mjs/core/engine-snapshot.mjs.map +3 -3
- package/dist/mjs/core/engine.mjs +47 -3
- package/dist/mjs/core/engine.mjs.map +3 -3
- package/dist/mjs/core/managers/copy-manager.mjs +163 -14
- package/dist/mjs/core/managers/copy-manager.mjs.map +3 -3
- package/dist/mjs/core/managers/range-metadata-manager.mjs +95 -0
- package/dist/mjs/core/managers/range-metadata-manager.mjs.map +10 -0
- package/dist/mjs/core/types.mjs.map +1 -1
- package/dist/mjs/package.json +1 -1
- package/dist/types/core/autofill-utils.d.ts +7 -1
- package/dist/types/core/engine-snapshot.d.ts +4 -2
- package/dist/types/core/engine.d.ts +32 -1
- package/dist/types/core/managers/copy-manager.d.ts +11 -1
- package/dist/types/core/managers/range-metadata-manager.d.ts +22 -0
- package/dist/types/core/types.d.ts +19 -6
- package/package.json +1 -1
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
function __accessProp(key) {
|
|
6
|
+
return this[key];
|
|
7
|
+
}
|
|
8
|
+
var __toCommonJS = (from) => {
|
|
9
|
+
var entry = (__moduleCache ??= new WeakMap).get(from), desc;
|
|
10
|
+
if (entry)
|
|
11
|
+
return entry;
|
|
12
|
+
entry = __defProp({}, "__esModule", { value: true });
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (var key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(entry, key))
|
|
16
|
+
__defProp(entry, key, {
|
|
17
|
+
get: __accessProp.bind(from, key),
|
|
18
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
__moduleCache.set(from, entry);
|
|
22
|
+
return entry;
|
|
23
|
+
};
|
|
24
|
+
var __moduleCache;
|
|
25
|
+
var __returnValue = (v) => v;
|
|
26
|
+
function __exportSetter(name, newValue) {
|
|
27
|
+
this[name] = __returnValue.bind(null, newValue);
|
|
28
|
+
}
|
|
29
|
+
var __export = (target, all) => {
|
|
30
|
+
for (var name in all)
|
|
31
|
+
__defProp(target, name, {
|
|
32
|
+
get: all[name],
|
|
33
|
+
enumerable: true,
|
|
34
|
+
configurable: true,
|
|
35
|
+
set: __exportSetter.bind(all, name)
|
|
36
|
+
});
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
// src/core/managers/range-metadata-manager.ts
|
|
40
|
+
var exports_range_metadata_manager = {};
|
|
41
|
+
__export(exports_range_metadata_manager, {
|
|
42
|
+
RangeMetadataManager: () => RangeMetadataManager
|
|
43
|
+
});
|
|
44
|
+
module.exports = __toCommonJS(exports_range_metadata_manager);
|
|
45
|
+
var import_utils = require("../utils.cjs");
|
|
46
|
+
var import_range_utils = require("../utils/range-utils.cjs");
|
|
47
|
+
var cloneArea = (area) => ({
|
|
48
|
+
workbookName: area.workbookName,
|
|
49
|
+
sheetName: area.sheetName,
|
|
50
|
+
range: {
|
|
51
|
+
start: { ...area.range.start },
|
|
52
|
+
end: {
|
|
53
|
+
col: { ...area.range.end.col },
|
|
54
|
+
row: { ...area.range.end.row }
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
var cloneEntry = (entry) => ({
|
|
59
|
+
id: entry.id,
|
|
60
|
+
areas: entry.areas.map(cloneArea),
|
|
61
|
+
metadata: entry.metadata
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
class RangeMetadataManager {
|
|
65
|
+
rangeMetadata = [];
|
|
66
|
+
addRangeMetadata(entry) {
|
|
67
|
+
const id = entry.id ?? crypto.randomUUID();
|
|
68
|
+
if (this.rangeMetadata.some((existing) => existing.id === id)) {
|
|
69
|
+
throw new Error(`Range metadata with id "${id}" already exists`);
|
|
70
|
+
}
|
|
71
|
+
this.rangeMetadata.push({
|
|
72
|
+
id,
|
|
73
|
+
areas: entry.areas.map(cloneArea),
|
|
74
|
+
metadata: entry.metadata
|
|
75
|
+
});
|
|
76
|
+
return id;
|
|
77
|
+
}
|
|
78
|
+
removeRangeMetadata(id) {
|
|
79
|
+
const beforeLength = this.rangeMetadata.length;
|
|
80
|
+
this.rangeMetadata = this.rangeMetadata.filter((entry) => entry.id !== id);
|
|
81
|
+
return this.rangeMetadata.length !== beforeLength;
|
|
82
|
+
}
|
|
83
|
+
getAllRangeMetadata() {
|
|
84
|
+
return this.rangeMetadata.map(cloneEntry);
|
|
85
|
+
}
|
|
86
|
+
getRangeMetadataForCell(cellAddress) {
|
|
87
|
+
return this.rangeMetadata.filter((entry) => entry.areas.some((area) => area.workbookName === cellAddress.workbookName && area.sheetName === cellAddress.sheetName && import_utils.isCellInRange(cellAddress, area.range))).map(cloneEntry);
|
|
88
|
+
}
|
|
89
|
+
getRangeMetadataIntersectingWithRange(range) {
|
|
90
|
+
return this.rangeMetadata.filter((entry) => entry.areas.some((area) => area.workbookName === range.workbookName && area.sheetName === range.sheetName && import_range_utils.rangesIntersect(area.range, range.range))).map(cloneEntry);
|
|
91
|
+
}
|
|
92
|
+
clearRangeMetadataInRange(range) {
|
|
93
|
+
this.rangeMetadata = this.rangeMetadata.map((entry) => ({
|
|
94
|
+
...entry,
|
|
95
|
+
areas: entry.areas.flatMap((area) => {
|
|
96
|
+
if (area.workbookName !== range.workbookName || area.sheetName !== range.sheetName) {
|
|
97
|
+
return [area];
|
|
98
|
+
}
|
|
99
|
+
return import_range_utils.subtractRange(area.range, range.range).map((remainingRange) => ({
|
|
100
|
+
...area,
|
|
101
|
+
range: remainingRange
|
|
102
|
+
}));
|
|
103
|
+
})
|
|
104
|
+
})).filter((entry) => entry.areas.length > 0);
|
|
105
|
+
}
|
|
106
|
+
removeWorkbookRangeMetadata(workbookName) {
|
|
107
|
+
this.rangeMetadata = this.rangeMetadata.filter((entry) => !entry.areas.some((area) => area.workbookName === workbookName));
|
|
108
|
+
}
|
|
109
|
+
removeSheetRangeMetadata(workbookName, sheetName) {
|
|
110
|
+
this.rangeMetadata = this.rangeMetadata.filter((entry) => !entry.areas.some((area) => area.workbookName === workbookName && area.sheetName === sheetName));
|
|
111
|
+
}
|
|
112
|
+
updateWorkbookName(oldName, newName) {
|
|
113
|
+
this.rangeMetadata = this.rangeMetadata.map((entry) => ({
|
|
114
|
+
...entry,
|
|
115
|
+
areas: entry.areas.map((area) => area.workbookName === oldName ? { ...area, workbookName: newName } : area)
|
|
116
|
+
}));
|
|
117
|
+
}
|
|
118
|
+
updateSheetName(workbookName, oldSheetName, newSheetName) {
|
|
119
|
+
this.rangeMetadata = this.rangeMetadata.map((entry) => ({
|
|
120
|
+
...entry,
|
|
121
|
+
areas: entry.areas.map((area) => area.workbookName === workbookName && area.sheetName === oldSheetName ? { ...area, sheetName: newSheetName } : area)
|
|
122
|
+
}));
|
|
123
|
+
}
|
|
124
|
+
resetRangeMetadata(rangeMetadata) {
|
|
125
|
+
this.rangeMetadata = rangeMetadata ? rangeMetadata.map(cloneEntry) : [];
|
|
126
|
+
}
|
|
127
|
+
toSnapshot() {
|
|
128
|
+
return this.getAllRangeMetadata();
|
|
129
|
+
}
|
|
130
|
+
restoreFromSnapshot(snapshot) {
|
|
131
|
+
this.resetRangeMetadata(snapshot);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
//# debugId=ABB55529B9C3BEF664756E2164756E21
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/core/managers/range-metadata-manager.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"/**\n * RangeMetadataManager - Manages arbitrary consumer-defined metadata attached\n * to ranges rather than individual cells.\n */\n\nimport type {\n CellAddress,\n RangeAddress,\n RangeMetadata,\n RangeMetadataInput,\n} from \"../types.cjs\";\nimport type { RangeMetadataManagerSnapshot } from \"../engine-snapshot.cjs\";\nimport { isCellInRange } from \"../utils.cjs\";\nimport { rangesIntersect, subtractRange } from \"../utils/range-utils.cjs\";\n\nconst cloneArea = (area: RangeAddress): RangeAddress => ({\n workbookName: area.workbookName,\n sheetName: area.sheetName,\n range: {\n start: { ...area.range.start },\n end: {\n col: { ...area.range.end.col },\n row: { ...area.range.end.row },\n },\n },\n});\n\nconst cloneEntry = <TMetadata>(\n entry: RangeMetadata<TMetadata>\n): RangeMetadata<TMetadata> => ({\n id: entry.id,\n areas: entry.areas.map(cloneArea),\n metadata: entry.metadata,\n});\n\nexport class RangeMetadataManager<TMetadata = unknown> {\n private rangeMetadata: RangeMetadata<TMetadata>[] = [];\n\n addRangeMetadata(entry: RangeMetadataInput<TMetadata>): string {\n const id = entry.id ?? crypto.randomUUID();\n if (this.rangeMetadata.some((existing) => existing.id === id)) {\n throw new Error(`Range metadata with id \"${id}\" already exists`);\n }\n\n this.rangeMetadata.push({\n id,\n areas: entry.areas.map(cloneArea),\n metadata: entry.metadata,\n });\n\n return id;\n }\n\n removeRangeMetadata(id: string): boolean {\n const beforeLength = this.rangeMetadata.length;\n this.rangeMetadata = this.rangeMetadata.filter((entry) => entry.id !== id);\n return this.rangeMetadata.length !== beforeLength;\n }\n\n getAllRangeMetadata(): RangeMetadata<TMetadata>[] {\n return this.rangeMetadata.map(cloneEntry);\n }\n\n getRangeMetadataForCell(cellAddress: CellAddress): RangeMetadata<TMetadata>[] {\n return this.rangeMetadata\n .filter((entry) =>\n entry.areas.some(\n (area) =>\n area.workbookName === cellAddress.workbookName &&\n area.sheetName === cellAddress.sheetName &&\n isCellInRange(cellAddress, area.range)\n )\n )\n .map(cloneEntry);\n }\n\n getRangeMetadataIntersectingWithRange(\n range: RangeAddress\n ): RangeMetadata<TMetadata>[] {\n return this.rangeMetadata\n .filter((entry) =>\n entry.areas.some(\n (area) =>\n area.workbookName === range.workbookName &&\n area.sheetName === range.sheetName &&\n rangesIntersect(area.range, range.range)\n )\n )\n .map(cloneEntry);\n }\n\n clearRangeMetadataInRange(range: RangeAddress): void {\n this.rangeMetadata = this.rangeMetadata\n .map((entry) => ({\n ...entry,\n areas: entry.areas.flatMap((area) => {\n if (\n area.workbookName !== range.workbookName ||\n area.sheetName !== range.sheetName\n ) {\n return [area];\n }\n\n return subtractRange(area.range, range.range).map((remainingRange) => ({\n ...area,\n range: remainingRange,\n }));\n }),\n }))\n .filter((entry) => entry.areas.length > 0);\n }\n\n removeWorkbookRangeMetadata(workbookName: string): void {\n this.rangeMetadata = this.rangeMetadata.filter(\n (entry) => !entry.areas.some((area) => area.workbookName === workbookName)\n );\n }\n\n removeSheetRangeMetadata(workbookName: string, sheetName: string): void {\n this.rangeMetadata = this.rangeMetadata.filter(\n (entry) =>\n !entry.areas.some(\n (area) =>\n area.workbookName === workbookName && area.sheetName === sheetName\n )\n );\n }\n\n updateWorkbookName(oldName: string, newName: string): void {\n this.rangeMetadata = this.rangeMetadata.map((entry) => ({\n ...entry,\n areas: entry.areas.map((area) =>\n area.workbookName === oldName ? { ...area, workbookName: newName } : area\n ),\n }));\n }\n\n updateSheetName(\n workbookName: string,\n oldSheetName: string,\n newSheetName: string\n ): void {\n this.rangeMetadata = this.rangeMetadata.map((entry) => ({\n ...entry,\n areas: entry.areas.map((area) =>\n area.workbookName === workbookName && area.sheetName === oldSheetName\n ? { ...area, sheetName: newSheetName }\n : area\n ),\n }));\n }\n\n resetRangeMetadata(rangeMetadata?: RangeMetadata<TMetadata>[]): void {\n this.rangeMetadata = rangeMetadata ? rangeMetadata.map(cloneEntry) : [];\n }\n\n toSnapshot(): RangeMetadataManagerSnapshot {\n return this.getAllRangeMetadata();\n }\n\n restoreFromSnapshot(snapshot: RangeMetadataManagerSnapshot): void {\n this.resetRangeMetadata(snapshot as RangeMetadata<TMetadata>[]);\n }\n}\n"
|
|
6
|
+
],
|
|
7
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAY8B,IAA9B;AAC+C,IAA/C;AAEA,IAAM,YAAY,CAAC,UAAsC;AAAA,EACvD,cAAc,KAAK;AAAA,EACnB,WAAW,KAAK;AAAA,EAChB,OAAO;AAAA,IACL,OAAO,KAAK,KAAK,MAAM,MAAM;AAAA,IAC7B,KAAK;AAAA,MACH,KAAK,KAAK,KAAK,MAAM,IAAI,IAAI;AAAA,MAC7B,KAAK,KAAK,KAAK,MAAM,IAAI,IAAI;AAAA,IAC/B;AAAA,EACF;AACF;AAEA,IAAM,aAAa,CACjB,WAC8B;AAAA,EAC9B,IAAI,MAAM;AAAA,EACV,OAAO,MAAM,MAAM,IAAI,SAAS;AAAA,EAChC,UAAU,MAAM;AAClB;AAAA;AAEO,MAAM,qBAA0C;AAAA,EAC7C,gBAA4C,CAAC;AAAA,EAErD,gBAAgB,CAAC,OAA8C;AAAA,IAC7D,MAAM,KAAK,MAAM,MAAM,OAAO,WAAW;AAAA,IACzC,IAAI,KAAK,cAAc,KAAK,CAAC,aAAa,SAAS,OAAO,EAAE,GAAG;AAAA,MAC7D,MAAM,IAAI,MAAM,2BAA2B,oBAAoB;AAAA,IACjE;AAAA,IAEA,KAAK,cAAc,KAAK;AAAA,MACtB;AAAA,MACA,OAAO,MAAM,MAAM,IAAI,SAAS;AAAA,MAChC,UAAU,MAAM;AAAA,IAClB,CAAC;AAAA,IAED,OAAO;AAAA;AAAA,EAGT,mBAAmB,CAAC,IAAqB;AAAA,IACvC,MAAM,eAAe,KAAK,cAAc;AAAA,IACxC,KAAK,gBAAgB,KAAK,cAAc,OAAO,CAAC,UAAU,MAAM,OAAO,EAAE;AAAA,IACzE,OAAO,KAAK,cAAc,WAAW;AAAA;AAAA,EAGvC,mBAAmB,GAA+B;AAAA,IAChD,OAAO,KAAK,cAAc,IAAI,UAAU;AAAA;AAAA,EAG1C,uBAAuB,CAAC,aAAsD;AAAA,IAC5E,OAAO,KAAK,cACT,OAAO,CAAC,UACP,MAAM,MAAM,KACV,CAAC,SACC,KAAK,iBAAiB,YAAY,gBAClC,KAAK,cAAc,YAAY,aAC/B,2BAAc,aAAa,KAAK,KAAK,CACzC,CACF,EACC,IAAI,UAAU;AAAA;AAAA,EAGnB,qCAAqC,CACnC,OAC4B;AAAA,IAC5B,OAAO,KAAK,cACT,OAAO,CAAC,UACP,MAAM,MAAM,KACV,CAAC,SACC,KAAK,iBAAiB,MAAM,gBAC5B,KAAK,cAAc,MAAM,aACzB,mCAAgB,KAAK,OAAO,MAAM,KAAK,CAC3C,CACF,EACC,IAAI,UAAU;AAAA;AAAA,EAGnB,yBAAyB,CAAC,OAA2B;AAAA,IACnD,KAAK,gBAAgB,KAAK,cACvB,IAAI,CAAC,WAAW;AAAA,SACZ;AAAA,MACH,OAAO,MAAM,MAAM,QAAQ,CAAC,SAAS;AAAA,QACnC,IACE,KAAK,iBAAiB,MAAM,gBAC5B,KAAK,cAAc,MAAM,WACzB;AAAA,UACA,OAAO,CAAC,IAAI;AAAA,QACd;AAAA,QAEA,OAAO,iCAAc,KAAK,OAAO,MAAM,KAAK,EAAE,IAAI,CAAC,oBAAoB;AAAA,aAClE;AAAA,UACH,OAAO;AAAA,QACT,EAAE;AAAA,OACH;AAAA,IACH,EAAE,EACD,OAAO,CAAC,UAAU,MAAM,MAAM,SAAS,CAAC;AAAA;AAAA,EAG7C,2BAA2B,CAAC,cAA4B;AAAA,IACtD,KAAK,gBAAgB,KAAK,cAAc,OACtC,CAAC,UAAU,CAAC,MAAM,MAAM,KAAK,CAAC,SAAS,KAAK,iBAAiB,YAAY,CAC3E;AAAA;AAAA,EAGF,wBAAwB,CAAC,cAAsB,WAAyB;AAAA,IACtE,KAAK,gBAAgB,KAAK,cAAc,OACtC,CAAC,UACC,CAAC,MAAM,MAAM,KACX,CAAC,SACC,KAAK,iBAAiB,gBAAgB,KAAK,cAAc,SAC7D,CACJ;AAAA;AAAA,EAGF,kBAAkB,CAAC,SAAiB,SAAuB;AAAA,IACzD,KAAK,gBAAgB,KAAK,cAAc,IAAI,CAAC,WAAW;AAAA,SACnD;AAAA,MACH,OAAO,MAAM,MAAM,IAAI,CAAC,SACtB,KAAK,iBAAiB,UAAU,KAAK,MAAM,cAAc,QAAQ,IAAI,IACvE;AAAA,IACF,EAAE;AAAA;AAAA,EAGJ,eAAe,CACb,cACA,cACA,cACM;AAAA,IACN,KAAK,gBAAgB,KAAK,cAAc,IAAI,CAAC,WAAW;AAAA,SACnD;AAAA,MACH,OAAO,MAAM,MAAM,IAAI,CAAC,SACtB,KAAK,iBAAiB,gBAAgB,KAAK,cAAc,eACrD,KAAK,MAAM,WAAW,aAAa,IACnC,IACN;AAAA,IACF,EAAE;AAAA;AAAA,EAGJ,kBAAkB,CAAC,eAAkD;AAAA,IACnE,KAAK,gBAAgB,gBAAgB,cAAc,IAAI,UAAU,IAAI,CAAC;AAAA;AAAA,EAGxE,UAAU,GAAiC;AAAA,IACzC,OAAO,KAAK,oBAAoB;AAAA;AAAA,EAGlC,mBAAmB,CAAC,UAA8C;AAAA,IAChE,KAAK,mBAAmB,QAAsC;AAAA;AAElE;",
|
|
8
|
+
"debugId": "ABB55529B9C3BEF664756E2164756E21",
|
|
9
|
+
"names": []
|
|
10
|
+
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/core/types.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"/**\n * Core type definitions for FormulaEngine\n * This file contains all fundamental types used throughout the engine\n */\n\nimport type { EvaluationContext } from \"../evaluator/evaluation-context.cjs\";\nimport type { FormulaEvaluator } from \"../evaluator/formula-evaluator.cjs\";\nimport type { FunctionNode } from \"../parser/ast.cjs\";\nimport type { DependencyNode } from \"./managers/dependency-node.cjs\";\nimport type { LookupOrder } from \"./managers/range-eval-order-builder.cjs\";\n\n// Cell addressing types\nexport interface CellAddress {\n sheetName: string;\n workbookName: string;\n colIndex: number;\n rowIndex: number;\n}\n\nexport interface RangeAddress {\n sheetName: string;\n workbookName: string;\n range: SpreadsheetRange;\n}\n\nexport interface LocalCellAddress {\n colIndex: number;\n rowIndex: number;\n}\n\nexport type ArethmeticEvaluator = (\n left: CellValue,\n right: CellValue,\n context: EvaluationContext\n) => CellValue | ErrorEvaluationResult;\n\nexport type PositiveInfinity = {\n type: \"infinity\";\n sign: \"positive\";\n};\n\nexport type CellInfinity = {\n type: \"infinity\";\n sign: \"positive\" | \"negative\";\n};\n\nexport type CellNumber = {\n type: \"number\";\n value: number;\n};\n\nexport type SpreadsheetRangeEnd = CellNumber | PositiveInfinity;\n\nexport type SpreadsheetRange = {\n start: {\n col: number;\n row: number;\n };\n end: {\n col: SpreadsheetRangeEnd;\n row: SpreadsheetRangeEnd;\n };\n};\n\nexport type RelativeRange = {\n start: {\n col: number;\n row: number;\n };\n width: SpreadsheetRangeEnd;\n height: SpreadsheetRangeEnd;\n};\n\nexport type FiniteSpreadsheetRange = {\n start: {\n col: number;\n row: number;\n };\n end: {\n col: number;\n row: number;\n };\n};\n\nexport type CellString = {\n type: \"string\";\n value: string;\n};\n\nexport type CellBoolean = {\n type: \"boolean\";\n value: boolean;\n};\n\n// Cell value types\nexport type CellValue = CellNumber | CellString | CellBoolean | CellInfinity;\n/**\n * undefined and \"\" are considered empty values\n * undefineds are converted to \"\" in the engine\n *\n * any empty values are deleted from the sheet content\n */\nexport type SerializedCellValue = string | number | boolean | undefined;\n\nexport interface SearchOptions {\n workbookName?: string;\n sheetName?: string;\n caseSensitive?: boolean;\n}\n\nexport interface SearchMatch {\n workbookName: string;\n sheetName: string;\n cellReference: string;\n cellContent: string;\n contentKind: \"formula\" | \"text\";\n occurrenceIndex: number;\n startIndex: number;\n endIndexExclusive: number;\n matchedText: string;\n}\n\nexport interface ReplaceTarget {\n workbookName: string;\n sheetName: string;\n cellReference: string;\n occurrenceIndex: number;\n}\n\nexport interface ReplaceChange {\n workbookName: string;\n sheetName: string;\n cellReference: string;\n contentKind: \"formula\" | \"text\";\n occurrenceIndex: number;\n startIndex: number;\n endIndexExclusive: number;\n matchedText: string;\n replacementText: string;\n beforeContent: string;\n afterContent: string;\n}\n\n// Named expressions\nexport interface NamedExpression {\n name: string;\n expression: string;\n}\n\nexport interface TableDefinition {\n name: string;\n start: {\n rowIndex: number;\n colIndex: number;\n };\n headers: Map<string, { name: string; index: number }>;\n endRow: SpreadsheetRangeEnd;\n sheetName: string;\n workbookName: string;\n}\n\n// Formula errors\nexport enum FormulaError {\n DIV0 = \"#DIV/0!\",\n NA = \"#N/A\",\n NAME = \"#NAME?\",\n NUM = \"#NUM!\",\n REF = \"#REF!\",\n VALUE = \"#VALUE!\",\n CYCLE = \"#CYCLE!\",\n ERROR = \"#ERROR!\",\n SPILL = \"#SPILL!\",\n}\n\n// Sheet structure\nexport interface Sheet<TCellMetadata = unknown, TSheetMetadata = unknown> {\n name: string;\n index: number; // 0-based index of the sheet\n content: Map<string, SerializedCellValue>;\n /**\n * Cell metadata - arbitrary consumer-defined data per cell\n * Examples: rich text content, links, comments, custom app data\n * The engine stores and copies this data but doesn't interpret it\n * Keyed by cell reference (e.g., \"A1\")\n */\n metadata: Map<string, TCellMetadata>;\n /**\n * Sheet-level metadata - arbitrary consumer-defined data for the entire sheet\n * Examples: text boxes, drawings, frozen panes, print settings\n * The engine stores and copies this data but doesn't interpret it\n */\n sheetMetadata: TSheetMetadata;\n}\n\nexport interface Workbook<\n TCellMetadata = unknown,\n TSheetMetadata = unknown,\n TWorkbookMetadata = unknown\n> {\n name: string;\n sheets: Map<string, Sheet<TCellMetadata, TSheetMetadata>>;\n /**\n * Workbook-level metadata - arbitrary consumer-defined data for the entire workbook\n * Examples: themes, custom ribbons, document properties, workbook settings\n * The engine stores and copies this data but doesn't interpret it\n */\n workbookMetadata: TWorkbookMetadata;\n}\n\n/**\n * Tracked reference - a stable reference to a range that updates automatically\n * when workbooks/sheets are renamed and becomes invalid when they're deleted\n */\nexport interface TrackedReference {\n id: string; // UUID\n address: RangeAddress; // The range being tracked\n isValid: boolean; // False if sheet/workbook deleted\n}\n\nexport type ValueEvaluationResult = {\n type: \"value\";\n result: CellValue;\n /**\n * If the terminating evaluation result is a reference (see evaluateReference)\n * then we store information about the source cell for context dependent functions like CELL\n */\n sourceCell?: CellAddress;\n};\n\nexport type AwaitingEvaluationResult = {\n type: \"awaiting-evaluation\";\n waitingFor: DependencyNode;\n errAddress: DependencyNode;\n /**\n * If the terminating evaluation result is a reference (see evaluateReference)\n * then we store information about the source cell for context dependent functions like CELL\n */\n sourceCell?: CellAddress;\n};\n\nexport type DoesNotSpillResult = {\n type: \"does-not-spill\";\n};\n\nexport type ErrorEvaluationResult =\n | {\n type: \"error\";\n err: FormulaError;\n errAddress: DependencyNode;\n message: string;\n /**\n * If the terminating evaluation result is a reference (see evaluateReference)\n * then we store information about the source cell for context dependent functions like CELL\n */\n sourceCell?: CellAddress;\n }\n | AwaitingEvaluationResult;\n\nexport type SingleEvaluationResult =\n | ValueEvaluationResult\n | ErrorEvaluationResult;\n\nexport type SpilledValuesEvaluator = (\n spillOffset: { x: number; y: number },\n context: EvaluationContext\n) => SingleEvaluationResult;\n\nexport type SpilledValuesEvaluationResult = {\n type: \"spilled-values\";\n\n /**\n * When a raw range is evaluated, we will add it to the sourceRange so it can be used e.g. for context dependent functions\n */\n sourceRange?: RangeAddress;\n\n /**\n * If the terminating evaluation result is a reference (see evaluateReference)\n * then we store information about the source cell for context dependent functions like CELL\n * sourceCell will only be defined on a spilledValue when a single value is looked up,\n */\n sourceCell?: CellAddress;\n\n spillArea: (origin: CellAddress) => SpreadsheetRange;\n /**\n * for debugging we add a source string to denote where the spilled values were created\n */\n source: string;\n evaluate: SpilledValuesEvaluator;\n /**\n * evaluateAllCells evaluates all non-empty cells in the spilled range.\n * Because a spilled range can be open-ended, we need to have logic for which cells we should evaluate.\n * e.g. when evaluating a range such as D:D only the cells in the current sheet residing in\n * column D should be evaluated and cells producing spilled values that spill onto D:D.\n *\n * In order to evaluate spilled cells in D:D the range evaluateAllCells need to get all cells in the\n * the intersection of the spilled range and D:D, for that reason evaluateAllCells gets an intersection parameter,\n * where the intersection is relative to the origin.\n *\n * #### Producers:\n * In e.g. SEQUENCE and evaluateRange we have logic for which cells in a spilled range we should evaluate,\n *\n * #### Nesting:\n * e.g. evaluation of scalar operators where we want to nest e.g. `5 * right.evaluate()`\n * can be implemented by calling\n * ```ts\n * const vals = child.evaluateAllCells.call(this, options);\n * return vals.map(val => ({ ...val, result: 5 * val.result }));\n * ```\n *\n * #### Consumers:\n * Only functions that need access to all spilled values in a range end up calling evaluateAllCells, e.g.\n * SUM, MIN, MAX, MATCH. Other types of functions like INDEX doesn't need to evaluate all cells in a range,\n * but does a lookup into a spilled range using the evaluate method.\n *\n */\n evaluateAllCells: (\n this: FormulaEvaluator,\n options: {\n /**\n * an intersection relative to the origin\n */\n intersection?: SpreadsheetRange;\n evaluate: SpilledValuesEvaluator;\n context: EvaluationContext;\n /**\n * origin is the cell address that the spilled range is spilled from\n * e.g. in A3=B2:B4 the origin is A3\n */\n origin: CellAddress;\n\n lookupOrder: LookupOrder;\n }\n ) => EvaluateAllCellsResult;\n};\n\nexport type EvaluateAllCellsResult =\n | ErrorEvaluationResult\n | {\n type: \"values\";\n values: CellInRangeResult[];\n };\n\nexport type CellInRangeResult = {\n result: SingleEvaluationResult;\n relativePos: { x: number; y: number };\n};\n\nexport type FunctionEvaluationResult =\n | SingleEvaluationResult\n | SpilledValuesEvaluationResult;\n\nexport type SpilledValue = {\n /**\n * spillOnto is the range that the spilled value is spilled onto\n */\n spillOnto: SpreadsheetRange;\n /**\n * origin is the cell address that the spilled value is spilled from\n */\n origin: CellAddress;\n};\n\n/**\n * Function definition\n */\nexport interface FunctionDefinition {\n name: string;\n evaluate: (\n this: FormulaEvaluator,\n node: FunctionNode,\n context: EvaluationContext\n ) => FunctionEvaluationResult;\n aliases?: string[];\n}\n\n/**\n * Evaluation result\n */\nexport type EvaluationResult = {\n dependencies: Set<string>;\n} & FunctionEvaluationResult;\n\nexport type SCC = {\n id: number;\n nodes: Set<DependencyNode>; // All nodes considering soft + hard edges\n evaluationOrder: DependencyNode[]; // Flat topologically ordered list\n resolved: boolean;\n hardEdgeSCCs: Set<DependencyNode>[]; // SCCs formed by only hard edges (regular dependencies)\n};\n\nexport type SCCDAG = {\n sccList: SCC[];\n sccGraph: Map<number, Set<number>>; // Adjacency list of SCC dependencies\n};\n\nexport type EvaluationOrder = {\n evaluationOrder: Set<DependencyNode>;\n hasCycle: boolean;\n cycleNodes?: Set<DependencyNode>;\n hash: string;\n sccDAG?: SCCDAG;\n};\n\n// Conditional Styling types\nexport interface LCHColor {\n l: number; // Lightness: 0-100\n c: number; // Chroma: 0-150+\n h: number; // Hue: 0-360\n}\n\nexport interface FormulaStyleCondition {\n type: \"formula\";\n formula: string;\n color: LCHColor;\n}\n\nexport interface GradientStyleCondition {\n type: \"gradient\";\n min:\n | { type: \"lowest_value\"; color: LCHColor }\n | { type: \"number\"; color: LCHColor; valueFormula: string };\n max:\n | { type: \"highest_value\"; color: LCHColor }\n | { type: \"number\"; color: LCHColor; valueFormula: string };\n}\n\nexport type StyleCondition = FormulaStyleCondition | GradientStyleCondition;\n\nexport interface ConditionalStyle {\n areas: RangeAddress[];\n condition: StyleCondition;\n}\n\nexport interface DirectCellStyle {\n areas: RangeAddress[];\n style: CellStyle;\n}\n\nexport interface CellStyle {\n backgroundColor?: string; // Hex color format\n color?: string; // Text color in hex format\n fontSize?: number; // Font size in pixels\n bold?: boolean;\n italic?: boolean;\n underline?: boolean;\n}\n\nexport interface CopyCellsOptions {\n /**\n * Whether this is a cut operation (clears source cells after copying)\n * @default false\n */\n cut?: boolean;\n /**\n * What to include in the copy operation.\n * - Use 'all' as shorthand for ['content', 'style', 'metadata']\n * - Use array for fine-grained control over what to copy:\n * - ['content'] - copy only values/formulas\n * - ['style'] - copy only formatting\n * - ['metadata'] - copy only metadata (rich text, links, etc.)\n * - ['content', 'style'] - copy content and formatting\n * - ['content', 'metadata'] - copy content and metadata\n * - ['style', 'metadata'] - copy formatting and metadata\n * - ['content', 'style', 'metadata'] - same as 'all'\n * @default 'all'\n */\n include?: \"all\" | (\"content\" | \"style\" | \"metadata\")[];\n /**\n * The type of the content to copy\n * value: Copy the value from the source to the target,\n * e.g. if the cell has the formula =123 + 123 then the value is 246\n * formula: Copy the formula from the source to the target,\n * e.g. if the cell has the formula =123 + 123 then the formula is =123 + 123 is copied\n * @default 'formula'\n */\n type?: \"value\" | \"formula\";\n}\n"
|
|
5
|
+
"/**\n * Core type definitions for FormulaEngine\n * This file contains all fundamental types used throughout the engine\n */\n\nimport type { EvaluationContext } from \"../evaluator/evaluation-context.cjs\";\nimport type { FormulaEvaluator } from \"../evaluator/formula-evaluator.cjs\";\nimport type { FunctionNode } from \"../parser/ast.cjs\";\nimport type { DependencyNode } from \"./managers/dependency-node.cjs\";\nimport type { LookupOrder } from \"./managers/range-eval-order-builder.cjs\";\n\n// Cell addressing types\nexport interface CellAddress {\n sheetName: string;\n workbookName: string;\n colIndex: number;\n rowIndex: number;\n}\n\nexport interface RangeAddress {\n sheetName: string;\n workbookName: string;\n range: SpreadsheetRange;\n}\n\nexport interface LocalCellAddress {\n colIndex: number;\n rowIndex: number;\n}\n\nexport type ArethmeticEvaluator = (\n left: CellValue,\n right: CellValue,\n context: EvaluationContext\n) => CellValue | ErrorEvaluationResult;\n\nexport type PositiveInfinity = {\n type: \"infinity\";\n sign: \"positive\";\n};\n\nexport type CellInfinity = {\n type: \"infinity\";\n sign: \"positive\" | \"negative\";\n};\n\nexport type CellNumber = {\n type: \"number\";\n value: number;\n};\n\nexport type SpreadsheetRangeEnd = CellNumber | PositiveInfinity;\n\nexport type SpreadsheetRange = {\n start: {\n col: number;\n row: number;\n };\n end: {\n col: SpreadsheetRangeEnd;\n row: SpreadsheetRangeEnd;\n };\n};\n\nexport type RelativeRange = {\n start: {\n col: number;\n row: number;\n };\n width: SpreadsheetRangeEnd;\n height: SpreadsheetRangeEnd;\n};\n\nexport type FiniteSpreadsheetRange = {\n start: {\n col: number;\n row: number;\n };\n end: {\n col: number;\n row: number;\n };\n};\n\nexport type CellString = {\n type: \"string\";\n value: string;\n};\n\nexport type CellBoolean = {\n type: \"boolean\";\n value: boolean;\n};\n\n// Cell value types\nexport type CellValue = CellNumber | CellString | CellBoolean | CellInfinity;\n/**\n * undefined and \"\" are considered empty values\n * undefineds are converted to \"\" in the engine\n *\n * any empty values are deleted from the sheet content\n */\nexport type SerializedCellValue = string | number | boolean | undefined;\n\nexport interface SearchOptions {\n workbookName?: string;\n sheetName?: string;\n caseSensitive?: boolean;\n}\n\nexport interface SearchMatch {\n workbookName: string;\n sheetName: string;\n cellReference: string;\n cellContent: string;\n contentKind: \"formula\" | \"text\";\n occurrenceIndex: number;\n startIndex: number;\n endIndexExclusive: number;\n matchedText: string;\n}\n\nexport interface ReplaceTarget {\n workbookName: string;\n sheetName: string;\n cellReference: string;\n occurrenceIndex: number;\n}\n\nexport interface ReplaceChange {\n workbookName: string;\n sheetName: string;\n cellReference: string;\n contentKind: \"formula\" | \"text\";\n occurrenceIndex: number;\n startIndex: number;\n endIndexExclusive: number;\n matchedText: string;\n replacementText: string;\n beforeContent: string;\n afterContent: string;\n}\n\n// Named expressions\nexport interface NamedExpression {\n name: string;\n expression: string;\n}\n\nexport interface TableDefinition {\n name: string;\n start: {\n rowIndex: number;\n colIndex: number;\n };\n headers: Map<string, { name: string; index: number }>;\n endRow: SpreadsheetRangeEnd;\n sheetName: string;\n workbookName: string;\n}\n\n// Formula errors\nexport enum FormulaError {\n DIV0 = \"#DIV/0!\",\n NA = \"#N/A\",\n NAME = \"#NAME?\",\n NUM = \"#NUM!\",\n REF = \"#REF!\",\n VALUE = \"#VALUE!\",\n CYCLE = \"#CYCLE!\",\n ERROR = \"#ERROR!\",\n SPILL = \"#SPILL!\",\n}\n\n// Sheet structure\nexport interface Sheet<TCellMetadata = unknown, TSheetMetadata = unknown> {\n name: string;\n index: number; // 0-based index of the sheet\n content: Map<string, SerializedCellValue>;\n /**\n * Cell metadata - arbitrary consumer-defined data per cell\n * Examples: rich text content, links, comments, custom app data\n * The engine stores and copies this data but doesn't interpret it\n * Keyed by cell reference (e.g., \"A1\")\n */\n metadata: Map<string, TCellMetadata>;\n /**\n * Sheet-level metadata - arbitrary consumer-defined data for the entire sheet\n * Examples: text boxes, drawings, frozen panes, print settings\n * The engine stores and copies this data but doesn't interpret it\n */\n sheetMetadata: TSheetMetadata;\n}\n\nexport interface Workbook<\n TCellMetadata = unknown,\n TSheetMetadata = unknown,\n TWorkbookMetadata = unknown\n> {\n name: string;\n sheets: Map<string, Sheet<TCellMetadata, TSheetMetadata>>;\n /**\n * Workbook-level metadata - arbitrary consumer-defined data for the entire workbook\n * Examples: themes, custom ribbons, document properties, workbook settings\n * The engine stores and copies this data but doesn't interpret it\n */\n workbookMetadata: TWorkbookMetadata;\n}\n\n/**\n * Tracked reference - a stable reference to a range that updates automatically\n * when workbooks/sheets are renamed and becomes invalid when they're deleted\n */\nexport interface TrackedReference {\n id: string; // UUID\n address: RangeAddress; // The range being tracked\n isValid: boolean; // False if sheet/workbook deleted\n}\n\nexport type ValueEvaluationResult = {\n type: \"value\";\n result: CellValue;\n /**\n * If the terminating evaluation result is a reference (see evaluateReference)\n * then we store information about the source cell for context dependent functions like CELL\n */\n sourceCell?: CellAddress;\n};\n\nexport type AwaitingEvaluationResult = {\n type: \"awaiting-evaluation\";\n waitingFor: DependencyNode;\n errAddress: DependencyNode;\n /**\n * If the terminating evaluation result is a reference (see evaluateReference)\n * then we store information about the source cell for context dependent functions like CELL\n */\n sourceCell?: CellAddress;\n};\n\nexport type DoesNotSpillResult = {\n type: \"does-not-spill\";\n};\n\nexport type ErrorEvaluationResult =\n | {\n type: \"error\";\n err: FormulaError;\n errAddress: DependencyNode;\n message: string;\n /**\n * If the terminating evaluation result is a reference (see evaluateReference)\n * then we store information about the source cell for context dependent functions like CELL\n */\n sourceCell?: CellAddress;\n }\n | AwaitingEvaluationResult;\n\nexport type SingleEvaluationResult =\n | ValueEvaluationResult\n | ErrorEvaluationResult;\n\nexport type SpilledValuesEvaluator = (\n spillOffset: { x: number; y: number },\n context: EvaluationContext\n) => SingleEvaluationResult;\n\nexport type SpilledValuesEvaluationResult = {\n type: \"spilled-values\";\n\n /**\n * When a raw range is evaluated, we will add it to the sourceRange so it can be used e.g. for context dependent functions\n */\n sourceRange?: RangeAddress;\n\n /**\n * If the terminating evaluation result is a reference (see evaluateReference)\n * then we store information about the source cell for context dependent functions like CELL\n * sourceCell will only be defined on a spilledValue when a single value is looked up,\n */\n sourceCell?: CellAddress;\n\n spillArea: (origin: CellAddress) => SpreadsheetRange;\n /**\n * for debugging we add a source string to denote where the spilled values were created\n */\n source: string;\n evaluate: SpilledValuesEvaluator;\n /**\n * evaluateAllCells evaluates all non-empty cells in the spilled range.\n * Because a spilled range can be open-ended, we need to have logic for which cells we should evaluate.\n * e.g. when evaluating a range such as D:D only the cells in the current sheet residing in\n * column D should be evaluated and cells producing spilled values that spill onto D:D.\n *\n * In order to evaluate spilled cells in D:D the range evaluateAllCells need to get all cells in the\n * the intersection of the spilled range and D:D, for that reason evaluateAllCells gets an intersection parameter,\n * where the intersection is relative to the origin.\n *\n * #### Producers:\n * In e.g. SEQUENCE and evaluateRange we have logic for which cells in a spilled range we should evaluate,\n *\n * #### Nesting:\n * e.g. evaluation of scalar operators where we want to nest e.g. `5 * right.evaluate()`\n * can be implemented by calling\n * ```ts\n * const vals = child.evaluateAllCells.call(this, options);\n * return vals.map(val => ({ ...val, result: 5 * val.result }));\n * ```\n *\n * #### Consumers:\n * Only functions that need access to all spilled values in a range end up calling evaluateAllCells, e.g.\n * SUM, MIN, MAX, MATCH. Other types of functions like INDEX doesn't need to evaluate all cells in a range,\n * but does a lookup into a spilled range using the evaluate method.\n *\n */\n evaluateAllCells: (\n this: FormulaEvaluator,\n options: {\n /**\n * an intersection relative to the origin\n */\n intersection?: SpreadsheetRange;\n evaluate: SpilledValuesEvaluator;\n context: EvaluationContext;\n /**\n * origin is the cell address that the spilled range is spilled from\n * e.g. in A3=B2:B4 the origin is A3\n */\n origin: CellAddress;\n\n lookupOrder: LookupOrder;\n }\n ) => EvaluateAllCellsResult;\n};\n\nexport type EvaluateAllCellsResult =\n | ErrorEvaluationResult\n | {\n type: \"values\";\n values: CellInRangeResult[];\n };\n\nexport type CellInRangeResult = {\n result: SingleEvaluationResult;\n relativePos: { x: number; y: number };\n};\n\nexport type FunctionEvaluationResult =\n | SingleEvaluationResult\n | SpilledValuesEvaluationResult;\n\nexport type SpilledValue = {\n /**\n * spillOnto is the range that the spilled value is spilled onto\n */\n spillOnto: SpreadsheetRange;\n /**\n * origin is the cell address that the spilled value is spilled from\n */\n origin: CellAddress;\n};\n\n/**\n * Function definition\n */\nexport interface FunctionDefinition {\n name: string;\n evaluate: (\n this: FormulaEvaluator,\n node: FunctionNode,\n context: EvaluationContext\n ) => FunctionEvaluationResult;\n aliases?: string[];\n}\n\n/**\n * Evaluation result\n */\nexport type EvaluationResult = {\n dependencies: Set<string>;\n} & FunctionEvaluationResult;\n\nexport type SCC = {\n id: number;\n nodes: Set<DependencyNode>; // All nodes considering soft + hard edges\n evaluationOrder: DependencyNode[]; // Flat topologically ordered list\n resolved: boolean;\n hardEdgeSCCs: Set<DependencyNode>[]; // SCCs formed by only hard edges (regular dependencies)\n};\n\nexport type SCCDAG = {\n sccList: SCC[];\n sccGraph: Map<number, Set<number>>; // Adjacency list of SCC dependencies\n};\n\nexport type EvaluationOrder = {\n evaluationOrder: Set<DependencyNode>;\n hasCycle: boolean;\n cycleNodes?: Set<DependencyNode>;\n hash: string;\n sccDAG?: SCCDAG;\n};\n\n// Conditional Styling types\nexport interface LCHColor {\n l: number; // Lightness: 0-100\n c: number; // Chroma: 0-150+\n h: number; // Hue: 0-360\n}\n\nexport interface FormulaStyleCondition {\n type: \"formula\";\n formula: string;\n color: LCHColor;\n}\n\nexport interface GradientStyleCondition {\n type: \"gradient\";\n min:\n | { type: \"lowest_value\"; color: LCHColor }\n | { type: \"number\"; color: LCHColor; valueFormula: string };\n max:\n | { type: \"highest_value\"; color: LCHColor }\n | { type: \"number\"; color: LCHColor; valueFormula: string };\n}\n\nexport type StyleCondition = FormulaStyleCondition | GradientStyleCondition;\n\nexport interface ConditionalStyle {\n areas: RangeAddress[];\n condition: StyleCondition;\n}\n\nexport interface DirectCellStyle {\n areas: RangeAddress[];\n style: CellStyle;\n}\n\nexport interface RangeMetadata<TMetadata = unknown> {\n id: string;\n areas: RangeAddress[];\n metadata: TMetadata;\n}\n\nexport interface RangeMetadataInput<TMetadata = unknown> {\n id?: string;\n areas: RangeAddress[];\n metadata: TMetadata;\n}\n\nexport interface CellStyle {\n backgroundColor?: string; // Hex color format\n color?: string; // Text color in hex format\n fontSize?: number; // Font size in pixels\n bold?: boolean;\n italic?: boolean;\n underline?: boolean;\n wrapText?: boolean;\n}\n\nexport type CopyCellsIncludePart =\n | \"content\"\n | \"style\"\n | \"cellMetadata\"\n | \"rangeMetadata\";\n\nexport interface CopyCellsOptions {\n /**\n * Whether this is a cut operation (clears source cells after copying)\n * @default false\n */\n cut?: boolean;\n /**\n * What to include in the copy operation.\n * - Use 'all' as shorthand for ['content', 'style', 'cellMetadata', 'rangeMetadata']\n * - Use array for fine-grained control over what to copy:\n * - ['content'] - copy only values/formulas\n * - ['style'] - copy only formatting\n * - ['cellMetadata'] - copy only cell metadata (rich text, links, etc.)\n * - ['rangeMetadata'] - copy only range metadata\n * - ['content', 'style'] - copy content and formatting\n * - ['content', 'cellMetadata'] - copy content and cell metadata\n * - ['style', 'rangeMetadata'] - copy formatting and range metadata\n * - ['content', 'style', 'cellMetadata', 'rangeMetadata'] - same as 'all'\n * @default 'all'\n */\n include?: \"all\" | CopyCellsIncludePart[];\n /**\n * The type of the content to copy\n * value: Copy the value from the source to the target,\n * e.g. if the cell has the formula =123 + 123 then the value is 246\n * formula: Copy the formula from the source to the target,\n * e.g. if the cell has the formula =123 + 123 then the formula is =123 + 123 is copied\n * @default 'formula'\n */\n type?: \"value\" | \"formula\";\n}\n"
|
|
6
6
|
],
|
|
7
7
|
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkKO,IAAK;AAAA,CAAL,CAAK,kBAAL;AAAA,EACL,wBAAO;AAAA,EACP,sBAAK;AAAA,EACL,wBAAO;AAAA,EACP,uBAAM;AAAA,EACN,uBAAM;AAAA,EACN,yBAAQ;AAAA,EACR,yBAAQ;AAAA,EACR,yBAAQ;AAAA,EACR,yBAAQ;AAAA,GATE;",
|
|
8
8
|
"debugId": "5EC6531CF2E47C8764756E2164756E21",
|
package/dist/cjs/package.json
CHANGED
|
@@ -8,9 +8,11 @@ import { intersectRanges } from "./utils/range-utils.mjs";
|
|
|
8
8
|
class AutoFill {
|
|
9
9
|
workbookManager;
|
|
10
10
|
styleManager;
|
|
11
|
-
|
|
11
|
+
rangeMetadataManager;
|
|
12
|
+
constructor(workbookManager, styleManager, rangeMetadataManager) {
|
|
12
13
|
this.workbookManager = workbookManager;
|
|
13
14
|
this.styleManager = styleManager;
|
|
15
|
+
this.rangeMetadataManager = rangeMetadataManager;
|
|
14
16
|
}
|
|
15
17
|
toFiniteRange(range) {
|
|
16
18
|
if (range.end.col.type === "infinity" || range.end.row.type === "infinity") {
|
|
@@ -62,6 +64,7 @@ class AutoFill {
|
|
|
62
64
|
this.workbookManager.setSheetContent(opts, newContent);
|
|
63
65
|
this.fillStyles(opts, finiteSeedRange, finiteFillRange, direction);
|
|
64
66
|
this.fillMetadata(opts, finiteSeedRange, finiteFillRange, direction);
|
|
67
|
+
this.fillRangeMetadata(opts, finiteSeedRange, finiteFillRange, direction);
|
|
65
68
|
}
|
|
66
69
|
getSeedCells(opts, seedRange) {
|
|
67
70
|
const cells = [];
|
|
@@ -406,9 +409,72 @@ class AutoFill {
|
|
|
406
409
|
}
|
|
407
410
|
}
|
|
408
411
|
}
|
|
412
|
+
fillRangeMetadata(opts, seedRange, fillRange, direction) {
|
|
413
|
+
const fillRangeAddress = {
|
|
414
|
+
workbookName: opts.workbookName,
|
|
415
|
+
sheetName: opts.sheetName,
|
|
416
|
+
range: {
|
|
417
|
+
start: { col: fillRange.start.col, row: fillRange.start.row },
|
|
418
|
+
end: {
|
|
419
|
+
col: { type: "number", value: fillRange.end.col },
|
|
420
|
+
row: { type: "number", value: fillRange.end.row }
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
};
|
|
424
|
+
this.rangeMetadataManager.clearRangeMetadataInRange(fillRangeAddress);
|
|
425
|
+
const seedWidth = seedRange.end.col - seedRange.start.col + 1;
|
|
426
|
+
const seedHeight = seedRange.end.row - seedRange.start.row + 1;
|
|
427
|
+
const allRangeMetadata = this.rangeMetadataManager.getAllRangeMetadata();
|
|
428
|
+
for (let row = fillRange.start.row;row <= fillRange.end.row; row++) {
|
|
429
|
+
for (let col = fillRange.start.col;col <= fillRange.end.col; col++) {
|
|
430
|
+
let seedCol;
|
|
431
|
+
let seedRow;
|
|
432
|
+
if (direction === "down" || direction === "up") {
|
|
433
|
+
seedCol = seedRange.start.col + (col - fillRange.start.col) % seedWidth;
|
|
434
|
+
seedRow = seedRange.start.row + (row - fillRange.start.row) % seedHeight;
|
|
435
|
+
} else {
|
|
436
|
+
seedRow = seedRange.start.row + (row - fillRange.start.row) % seedHeight;
|
|
437
|
+
seedCol = seedRange.start.col + (col - fillRange.start.col) % seedWidth;
|
|
438
|
+
}
|
|
439
|
+
const sourceCellRange = {
|
|
440
|
+
start: { col: seedCol, row: seedRow },
|
|
441
|
+
end: {
|
|
442
|
+
col: { type: "number", value: seedCol },
|
|
443
|
+
row: { type: "number", value: seedRow }
|
|
444
|
+
}
|
|
445
|
+
};
|
|
446
|
+
const targetCellRange = {
|
|
447
|
+
workbookName: opts.workbookName,
|
|
448
|
+
sheetName: opts.sheetName,
|
|
449
|
+
range: {
|
|
450
|
+
start: { col, row },
|
|
451
|
+
end: {
|
|
452
|
+
col: { type: "number", value: col },
|
|
453
|
+
row: { type: "number", value: row }
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
};
|
|
457
|
+
for (const entry of allRangeMetadata) {
|
|
458
|
+
for (const area of entry.areas) {
|
|
459
|
+
if (area.workbookName !== opts.workbookName || area.sheetName !== opts.sheetName) {
|
|
460
|
+
continue;
|
|
461
|
+
}
|
|
462
|
+
const intersection = intersectRanges(area.range, sourceCellRange);
|
|
463
|
+
if (!intersection) {
|
|
464
|
+
continue;
|
|
465
|
+
}
|
|
466
|
+
this.rangeMetadataManager.addRangeMetadata({
|
|
467
|
+
areas: [targetCellRange],
|
|
468
|
+
metadata: entry.metadata
|
|
469
|
+
});
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
}
|
|
409
475
|
}
|
|
410
476
|
export {
|
|
411
477
|
AutoFill
|
|
412
478
|
};
|
|
413
479
|
|
|
414
|
-
//# debugId=
|
|
480
|
+
//# debugId=8E208D0BC4A4FCCD64756E2164756E21
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/core/autofill-utils.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"/**\n * AutoFill class for handling spreadsheet autofill functionality\n */\n\nimport type {\n CellAddress,\n SerializedCellValue,\n SpreadsheetRange,\n FiniteSpreadsheetRange,\n LocalCellAddress,\n ConditionalStyle,\n DirectCellStyle,\n RangeAddress,\n} from \"./types.mjs\";\nimport type { FillDirection } from \"@ricsam/selection-manager\";\nimport { parseFormula } from \"../parser/parser.mjs\";\nimport { astToString } from \"../parser/formatter.mjs\";\nimport { transformAST } from \"./ast-traverser.mjs\";\nimport type { ReferenceNode, RangeNode } from \"../parser/ast.mjs\";\nimport { getCellReference } from \"./utils.mjs\";\nimport type { WorkbookManager } from \"./managers/workbook-manager.mjs\";\nimport type { StyleManager } from \"./managers/style-manager.mjs\";\nimport { intersectRanges } from \"./utils/range-utils.mjs\";\n\nexport class AutoFill {\n constructor(\n private workbookManager: WorkbookManager,\n private styleManager: StyleManager\n ) {}\n\n /**\n * Converts a SpreadsheetRange to FiniteSpreadsheetRange, throwing an error if infinite\n */\n private toFiniteRange(range: SpreadsheetRange): FiniteSpreadsheetRange {\n if (\n range.end.col.type === \"infinity\" ||\n range.end.row.type === \"infinity\"\n ) {\n throw new Error(\"AutoFill with infinite ranges is not supported\");\n }\n\n return {\n start: range.start,\n end: {\n col: range.end.col.value,\n row: range.end.row.value,\n },\n };\n }\n\n private getCellContent(address: CellAddress): SerializedCellValue {\n const sheet = this.workbookManager.getSheet(address);\n if (!sheet) {\n throw new Error(\"Sheet not found\");\n }\n return sheet.content.get(getCellReference(address));\n }\n\n fill(\n opts: { sheetName: string; workbookName: string },\n seedRange: SpreadsheetRange,\n fillRanges: SpreadsheetRange[],\n direction: FillDirection\n ) {\n // Process each fill range\n for (const fillRange of fillRanges) {\n this.fillSingleRange(opts, seedRange, fillRange, direction);\n }\n }\n\n /**\n * Fill a single range with seed data and styles\n */\n private fillSingleRange(\n opts: { sheetName: string; workbookName: string },\n seedRange: SpreadsheetRange,\n fillRange: SpreadsheetRange,\n direction: FillDirection\n ) {\n // Convert to finite ranges (throws error if infinite)\n const finiteSeedRange = this.toFiniteRange(seedRange);\n const finiteFillRange = this.toFiniteRange(fillRange);\n\n // Get seed cells data\n const seedCells = this.getSeedCells(opts, finiteSeedRange);\n\n // Collect all changes to apply in a single batch\n const changes = new Map<string, SerializedCellValue>();\n\n // Determine if we have a single cell or multi-cell seed\n const isSingleCell = seedCells.length === 1;\n\n if (isSingleCell) {\n const seedCell = seedCells[0];\n if (seedCell) {\n this.collectSingleCellPattern(\n seedCell,\n finiteFillRange,\n direction,\n changes\n );\n }\n } else {\n this.collectMultiCellPattern(\n seedCells,\n finiteSeedRange,\n finiteFillRange,\n direction,\n changes\n );\n }\n\n // Get current sheet content and merge with changes\n const currentContent = this.workbookManager.getSheetSerialized(opts);\n const newContent = new Map(currentContent);\n\n // Apply all changes\n changes.forEach((value, key) => {\n if (value === undefined) {\n newContent.delete(key);\n } else {\n newContent.set(key, value);\n }\n });\n\n // Update sheet content in a single operation (direct manager call, not through engine)\n this.workbookManager.setSheetContent(opts, newContent);\n\n // Copy styles from seed to fill range\n this.fillStyles(opts, finiteSeedRange, finiteFillRange, direction);\n\n // Copy metadata from seed to fill range\n this.fillMetadata(opts, finiteSeedRange, finiteFillRange, direction);\n }\n\n private getSeedCells(\n opts: { sheetName: string; workbookName: string },\n seedRange: FiniteSpreadsheetRange\n ) {\n const cells: Array<{\n address: CellAddress;\n content: SerializedCellValue;\n rowOffset: number;\n colOffset: number;\n }> = [];\n\n const startCol = seedRange.start.col;\n const startRow = seedRange.start.row;\n const endCol = seedRange.end.col;\n const endRow = seedRange.end.row;\n\n for (let row = startRow; row <= endRow; row++) {\n for (let col = startCol; col <= endCol; col++) {\n const address: CellAddress = {\n sheetName: opts.sheetName,\n workbookName: opts.workbookName,\n colIndex: col,\n rowIndex: row,\n };\n const content = this.getCellContent(address);\n cells.push({\n address,\n content,\n rowOffset: row - startRow,\n colOffset: col - startCol,\n });\n }\n }\n\n return cells;\n }\n\n private collectSingleCellPattern(\n seedCell: { address: CellAddress; content: SerializedCellValue },\n fillRange: FiniteSpreadsheetRange,\n direction: FillDirection,\n changes: Map<string, SerializedCellValue>\n ) {\n const { content } = seedCell;\n\n const startCol = fillRange.start.col;\n const startRow = fillRange.start.row;\n const endCol = fillRange.end.col;\n const endRow = fillRange.end.row;\n\n for (let row = startRow; row <= endRow; row++) {\n for (let col = startCol; col <= endCol; col++) {\n const targetAddress: CellAddress = {\n sheetName: seedCell.address.sheetName,\n workbookName: seedCell.address.workbookName,\n colIndex: col,\n rowIndex: row,\n };\n\n let newContent: SerializedCellValue;\n\n if (content === undefined || content === \"\") {\n // Blank cell - fills blanks (effectively clears targets)\n newContent = undefined;\n } else if (typeof content === \"string\" && content.startsWith(\"=\")) {\n // Formula - adjust relative references\n newContent = this.adjustFormulaReferences(\n content,\n seedCell.address,\n targetAddress\n );\n } else {\n // Number or text - copy by default\n newContent = content;\n }\n\n changes.set(getCellReference(targetAddress), newContent);\n }\n }\n }\n\n private collectMultiCellPattern(\n seedCells: Array<{\n address: CellAddress;\n content: SerializedCellValue;\n rowOffset: number;\n colOffset: number;\n }>,\n seedRange: FiniteSpreadsheetRange,\n fillRange: FiniteSpreadsheetRange,\n direction: FillDirection,\n changes: Map<string, SerializedCellValue>\n ) {\n // Try to infer linear step from numbers\n const step = this.inferLinearStep(seedCells, direction);\n\n const startCol = fillRange.start.col;\n const startRow = fillRange.start.row;\n const endCol = fillRange.end.col;\n const endRow = fillRange.end.row;\n\n const seedWidth = seedRange.end.col - seedRange.start.col + 1;\n const seedHeight = seedRange.end.row - seedRange.start.row + 1;\n\n for (let row = startRow; row <= endRow; row++) {\n for (let col = startCol; col <= endCol; col++) {\n const targetAddress: LocalCellAddress = {\n colIndex: col,\n rowIndex: row,\n };\n\n let newContent: SerializedCellValue;\n\n if (step !== null) {\n // Use linear progression\n newContent = this.applyLinearStep(\n seedCells,\n targetAddress,\n seedRange,\n step,\n direction\n );\n } else {\n // Repeat pattern (cycle through seed block)\n const seedColOffset = (col - startCol) % seedWidth;\n const seedRowOffset = (row - startRow) % seedHeight;\n\n const seedCell = seedCells.find(\n (cell) =>\n cell.colOffset === seedColOffset &&\n cell.rowOffset === seedRowOffset\n );\n\n if (seedCell) {\n if (\n typeof seedCell.content === \"string\" &&\n seedCell.content.startsWith(\"=\")\n ) {\n // Formula - adjust relative references\n newContent = this.adjustFormulaReferences(\n seedCell.content,\n seedCell.address,\n targetAddress\n );\n } else {\n newContent = seedCell.content;\n }\n } else {\n newContent = undefined;\n }\n }\n\n changes.set(getCellReference(targetAddress), newContent);\n }\n }\n }\n\n private inferLinearStep(\n seedCells: Array<{\n content: SerializedCellValue;\n rowOffset: number;\n colOffset: number;\n }>,\n direction: FillDirection\n ): number | null {\n // Extract numeric values in the direction of fill\n const values: number[] = [];\n\n if (direction === \"down\" || direction === \"up\") {\n // Look at first column, different rows\n const firstColCells = seedCells\n .filter((cell) => cell.colOffset === 0)\n .sort((a, b) => a.rowOffset - b.rowOffset);\n\n for (const cell of firstColCells) {\n if (typeof cell.content === \"number\") {\n values.push(cell.content);\n } else if (typeof cell.content === \"string\") {\n const num = parseFloat(cell.content);\n if (!isNaN(num)) {\n values.push(num);\n } else {\n return null; // Non-numeric content, can't infer step\n }\n } else {\n return null;\n }\n }\n } else {\n // Look at first row, different columns\n const firstRowCells = seedCells\n .filter((cell) => cell.rowOffset === 0)\n .sort((a, b) => a.colOffset - b.colOffset);\n\n for (const cell of firstRowCells) {\n if (typeof cell.content === \"number\") {\n values.push(cell.content);\n } else if (typeof cell.content === \"string\") {\n const num = parseFloat(cell.content);\n if (!isNaN(num)) {\n values.push(num);\n } else {\n return null; // Non-numeric content, can't infer step\n }\n } else {\n return null;\n }\n }\n }\n\n if (values.length < 2) {\n return null;\n }\n\n // Check if there's a consistent step\n const step = values[1]! - values[0]!;\n for (let i = 2; i < values.length; i++) {\n if (Math.abs(values[i]! - values[i - 1]! - step) > 1e-10) {\n return null; // Inconsistent step\n }\n }\n\n return step;\n }\n\n private applyLinearStep(\n seedCells: Array<{\n content: SerializedCellValue;\n rowOffset: number;\n colOffset: number;\n }>,\n targetAddress: LocalCellAddress,\n seedRange: FiniteSpreadsheetRange,\n step: number,\n direction: FillDirection\n ): SerializedCellValue {\n // Calculate the position in the overall sequence\n let positionInSequence: number;\n let baseValue: number;\n\n if (direction === \"down\") {\n positionInSequence = targetAddress.rowIndex - seedRange.start.row;\n\n // Find the base value from the first row of the seed\n const baseCell = seedCells.find(\n (cell) =>\n cell.colOffset === targetAddress.colIndex - seedRange.start.col &&\n cell.rowOffset === 0\n );\n\n if (!baseCell) return undefined;\n baseValue =\n typeof baseCell.content === \"number\"\n ? baseCell.content\n : parseFloat(String(baseCell.content || \"0\"));\n } else if (direction === \"up\") {\n positionInSequence = targetAddress.rowIndex - seedRange.start.row;\n\n // Find the base value from the first row of the seed (same as down direction)\n const baseCell = seedCells.find(\n (cell) =>\n cell.colOffset === targetAddress.colIndex - seedRange.start.col &&\n cell.rowOffset === 0\n );\n\n if (!baseCell) return undefined;\n baseValue =\n typeof baseCell.content === \"number\"\n ? baseCell.content\n : parseFloat(String(baseCell.content || \"0\"));\n } else if (direction === \"right\") {\n positionInSequence = targetAddress.colIndex - seedRange.start.col;\n\n // Find the base value from the first column of the seed\n const baseCell = seedCells.find(\n (cell) =>\n cell.rowOffset === targetAddress.rowIndex - seedRange.start.row &&\n cell.colOffset === 0\n );\n\n if (!baseCell) return undefined;\n baseValue =\n typeof baseCell.content === \"number\"\n ? baseCell.content\n : parseFloat(String(baseCell.content || \"0\"));\n } else {\n // left\n positionInSequence = targetAddress.colIndex - seedRange.start.col;\n\n // Find the base value from the first column of the seed (same as right direction)\n const baseCell = seedCells.find(\n (cell) =>\n cell.rowOffset === targetAddress.rowIndex - seedRange.start.row &&\n cell.colOffset === 0\n );\n\n if (!baseCell) return undefined;\n baseValue =\n typeof baseCell.content === \"number\"\n ? baseCell.content\n : parseFloat(String(baseCell.content || \"0\"));\n }\n\n if (isNaN(baseValue)) {\n return undefined;\n }\n\n const result = baseValue + step * positionInSequence;\n return typeof seedCells[0]?.content === \"string\"\n ? result.toString()\n : result;\n }\n\n private adjustFormulaReferences(\n formula: string,\n sourceAddress: LocalCellAddress,\n targetAddress: LocalCellAddress\n ): string {\n try {\n const ast = parseFormula(formula.slice(1)); // Remove the \"=\" sign\n\n const rowDelta = targetAddress.rowIndex - sourceAddress.rowIndex;\n const colDelta = targetAddress.colIndex - sourceAddress.colIndex;\n\n const adjustedAst = transformAST(ast, (node) => {\n if (node.type === \"reference\") {\n const refNode = node as ReferenceNode;\n return {\n ...refNode,\n address: {\n colIndex: refNode.isAbsolute.col\n ? refNode.address.colIndex\n : refNode.address.colIndex + colDelta,\n rowIndex: refNode.isAbsolute.row\n ? refNode.address.rowIndex\n : refNode.address.rowIndex + rowDelta,\n },\n };\n } else if (node.type === \"range\") {\n const rangeNode = node as RangeNode;\n return {\n ...rangeNode,\n range: {\n start: {\n col: rangeNode.isAbsolute.start.col\n ? rangeNode.range.start.col\n : rangeNode.range.start.col + colDelta,\n row: rangeNode.isAbsolute.start.row\n ? rangeNode.range.start.row\n : rangeNode.range.start.row + rowDelta,\n },\n end: {\n col:\n rangeNode.range.end.col.type === \"number\"\n ? rangeNode.isAbsolute.end.col\n ? rangeNode.range.end.col\n : {\n type: \"number\" as const,\n value: rangeNode.range.end.col.value + colDelta,\n }\n : rangeNode.range.end.col,\n row:\n rangeNode.range.end.row.type === \"number\"\n ? rangeNode.isAbsolute.end.row\n ? rangeNode.range.end.row\n : {\n type: \"number\" as const,\n value: rangeNode.range.end.row.value + rowDelta,\n }\n : rangeNode.range.end.row,\n },\n },\n };\n }\n return node;\n });\n\n return `=${astToString(adjustedAst)}`;\n } catch (error) {\n // If parsing fails, return the original formula\n console.warn(\"Failed to adjust formula references:\", error);\n return formula;\n }\n }\n\n /**\n * Fill styles from seed range to fill range based on direction\n * Clears existing cell styles in fill range first (Excel behavior)\n */\n private fillStyles(\n opts: { sheetName: string; workbookName: string },\n seedRange: FiniteSpreadsheetRange,\n fillRange: FiniteSpreadsheetRange,\n direction: FillDirection\n ): void {\n // STEP 1: Clear existing cell styles in fill range (Excel-like replacement)\n const fillRangeAddress: RangeAddress = {\n workbookName: opts.workbookName,\n sheetName: opts.sheetName,\n range: {\n start: { col: fillRange.start.col, row: fillRange.start.row },\n end: {\n col: { type: \"number\", value: fillRange.end.col },\n row: { type: \"number\", value: fillRange.end.row },\n },\n },\n };\n \n this.styleManager.clearCellStylesInRange(fillRangeAddress);\n\n const seedWidth = seedRange.end.col - seedRange.start.col + 1;\n const seedHeight = seedRange.end.row - seedRange.start.row + 1;\n\n // STEP 2: Get all styles intersecting with seed range\n const seedSpreadsheetRange: SpreadsheetRange = {\n start: { col: seedRange.start.col, row: seedRange.start.row },\n end: {\n col: { type: \"number\", value: seedRange.end.col },\n row: { type: \"number\", value: seedRange.end.row },\n },\n };\n\n const allConditionalStyles = this.styleManager.getAllConditionalStyles();\n const allCellStyles = this.styleManager.getAllCellStyles();\n\n // STEP 3: For each cell in fill range, determine corresponding seed cell and copy styles\n for (let row = fillRange.start.row; row <= fillRange.end.row; row++) {\n for (let col = fillRange.start.col; col <= fillRange.end.col; col++) {\n // Determine which seed cell corresponds to this fill cell\n let seedCol: number;\n let seedRow: number;\n\n if (direction === \"down\" || direction === \"up\") {\n // Vertical fill: keep column aligned, pattern repeat on rows\n seedCol = seedRange.start.col + (col - fillRange.start.col) % seedWidth;\n seedRow = seedRange.start.row + (row - fillRange.start.row) % seedHeight;\n } else {\n // Horizontal fill: keep row aligned, pattern repeat on columns\n seedRow = seedRange.start.row + (row - fillRange.start.row) % seedHeight;\n seedCol = seedRange.start.col + (col - fillRange.start.col) % seedWidth;\n }\n\n const sourceCellRange: SpreadsheetRange = {\n start: { col: seedCol, row: seedRow },\n end: {\n col: { type: \"number\", value: seedCol },\n row: { type: \"number\", value: seedRow },\n },\n };\n\n const targetCell: CellAddress = {\n workbookName: opts.workbookName,\n sheetName: opts.sheetName,\n colIndex: col,\n rowIndex: row,\n };\n\n // Copy conditional styles\n for (const style of allConditionalStyles) {\n for (const area of style.areas) {\n if (\n area.workbookName === opts.workbookName &&\n area.sheetName === opts.sheetName\n ) {\n const intersection = intersectRanges(area.range, sourceCellRange);\n if (intersection) {\n const newStyle: ConditionalStyle = {\n areas: [{\n workbookName: opts.workbookName,\n sheetName: opts.sheetName,\n range: {\n start: { col: targetCell.colIndex, row: targetCell.rowIndex },\n end: {\n col: { type: \"number\", value: targetCell.colIndex },\n row: { type: \"number\", value: targetCell.rowIndex },\n },\n },\n }],\n condition: style.condition,\n };\n this.styleManager.addConditionalStyle(newStyle);\n }\n }\n }\n }\n\n // Copy cell styles\n for (const style of allCellStyles) {\n for (const area of style.areas) {\n if (\n area.workbookName === opts.workbookName &&\n area.sheetName === opts.sheetName\n ) {\n const intersection = intersectRanges(area.range, sourceCellRange);\n if (intersection) {\n const newStyle: DirectCellStyle = {\n areas: [{\n workbookName: opts.workbookName,\n sheetName: opts.sheetName,\n range: {\n start: { col: targetCell.colIndex, row: targetCell.rowIndex },\n end: {\n col: { type: \"number\", value: targetCell.colIndex },\n row: { type: \"number\", value: targetCell.rowIndex },\n },\n },\n }],\n style: style.style,\n };\n this.styleManager.addCellStyle(newStyle);\n }\n }\n }\n }\n }\n }\n }\n\n /**\n * Copy metadata from seed range to fill range with pattern repetition\n */\n private fillMetadata(\n opts: { sheetName: string; workbookName: string },\n seedRange: FiniteSpreadsheetRange,\n fillRange: FiniteSpreadsheetRange,\n direction: FillDirection\n ): void {\n const seedWidth = seedRange.end.col - seedRange.start.col + 1;\n const seedHeight = seedRange.end.row - seedRange.start.row + 1;\n\n // For each cell in fill range, copy metadata from corresponding seed cell\n for (let row = fillRange.start.row; row <= fillRange.end.row; row++) {\n for (let col = fillRange.start.col; col <= fillRange.end.col; col++) {\n // Determine which seed cell corresponds to this fill cell\n let seedCol: number;\n let seedRow: number;\n\n if (direction === \"down\" || direction === \"up\") {\n // Vertical fill: keep column aligned, pattern repeat on rows\n seedCol = seedRange.start.col + (col - fillRange.start.col) % seedWidth;\n seedRow = seedRange.start.row + (row - fillRange.start.row) % seedHeight;\n } else {\n // Horizontal fill: keep row aligned, pattern repeat on columns\n seedRow = seedRange.start.row + (row - fillRange.start.row) % seedHeight;\n seedCol = seedRange.start.col + (col - fillRange.start.col) % seedWidth;\n }\n\n const sourceCellAddress: CellAddress = {\n workbookName: opts.workbookName,\n sheetName: opts.sheetName,\n colIndex: seedCol,\n rowIndex: seedRow,\n };\n\n const targetCellAddress: CellAddress = {\n workbookName: opts.workbookName,\n sheetName: opts.sheetName,\n colIndex: col,\n rowIndex: row,\n };\n\n // Copy metadata from source to target\n const sourceMetadata = this.workbookManager.getCellMetadata(sourceCellAddress);\n if (sourceMetadata) {\n this.workbookManager.setCellMetadata(targetCellAddress, { ...sourceMetadata });\n }\n }\n }\n }\n}\n"
|
|
5
|
+
"/**\n * AutoFill class for handling spreadsheet autofill functionality\n */\n\nimport type {\n CellAddress,\n SerializedCellValue,\n SpreadsheetRange,\n FiniteSpreadsheetRange,\n LocalCellAddress,\n ConditionalStyle,\n DirectCellStyle,\n RangeAddress,\n} from \"./types.mjs\";\nimport type { FillDirection } from \"@ricsam/selection-manager\";\nimport { parseFormula } from \"../parser/parser.mjs\";\nimport { astToString } from \"../parser/formatter.mjs\";\nimport { transformAST } from \"./ast-traverser.mjs\";\nimport type { ReferenceNode, RangeNode } from \"../parser/ast.mjs\";\nimport { getCellReference } from \"./utils.mjs\";\nimport type { WorkbookManager } from \"./managers/workbook-manager.mjs\";\nimport type { StyleManager } from \"./managers/style-manager.mjs\";\nimport type { RangeMetadataManager } from \"./managers/range-metadata-manager.mjs\";\nimport { intersectRanges } from \"./utils/range-utils.mjs\";\n\nexport class AutoFill {\n constructor(\n private workbookManager: WorkbookManager,\n private styleManager: StyleManager,\n private rangeMetadataManager: RangeMetadataManager\n ) {}\n\n /**\n * Converts a SpreadsheetRange to FiniteSpreadsheetRange, throwing an error if infinite\n */\n private toFiniteRange(range: SpreadsheetRange): FiniteSpreadsheetRange {\n if (\n range.end.col.type === \"infinity\" ||\n range.end.row.type === \"infinity\"\n ) {\n throw new Error(\"AutoFill with infinite ranges is not supported\");\n }\n\n return {\n start: range.start,\n end: {\n col: range.end.col.value,\n row: range.end.row.value,\n },\n };\n }\n\n private getCellContent(address: CellAddress): SerializedCellValue {\n const sheet = this.workbookManager.getSheet(address);\n if (!sheet) {\n throw new Error(\"Sheet not found\");\n }\n return sheet.content.get(getCellReference(address));\n }\n\n fill(\n opts: { sheetName: string; workbookName: string },\n seedRange: SpreadsheetRange,\n fillRanges: SpreadsheetRange[],\n direction: FillDirection\n ) {\n // Process each fill range\n for (const fillRange of fillRanges) {\n this.fillSingleRange(opts, seedRange, fillRange, direction);\n }\n }\n\n /**\n * Fill a single range with seed data and styles\n */\n private fillSingleRange(\n opts: { sheetName: string; workbookName: string },\n seedRange: SpreadsheetRange,\n fillRange: SpreadsheetRange,\n direction: FillDirection\n ) {\n // Convert to finite ranges (throws error if infinite)\n const finiteSeedRange = this.toFiniteRange(seedRange);\n const finiteFillRange = this.toFiniteRange(fillRange);\n\n // Get seed cells data\n const seedCells = this.getSeedCells(opts, finiteSeedRange);\n\n // Collect all changes to apply in a single batch\n const changes = new Map<string, SerializedCellValue>();\n\n // Determine if we have a single cell or multi-cell seed\n const isSingleCell = seedCells.length === 1;\n\n if (isSingleCell) {\n const seedCell = seedCells[0];\n if (seedCell) {\n this.collectSingleCellPattern(\n seedCell,\n finiteFillRange,\n direction,\n changes\n );\n }\n } else {\n this.collectMultiCellPattern(\n seedCells,\n finiteSeedRange,\n finiteFillRange,\n direction,\n changes\n );\n }\n\n // Get current sheet content and merge with changes\n const currentContent = this.workbookManager.getSheetSerialized(opts);\n const newContent = new Map(currentContent);\n\n // Apply all changes\n changes.forEach((value, key) => {\n if (value === undefined) {\n newContent.delete(key);\n } else {\n newContent.set(key, value);\n }\n });\n\n // Update sheet content in a single operation (direct manager call, not through engine)\n this.workbookManager.setSheetContent(opts, newContent);\n\n // Copy styles from seed to fill range\n this.fillStyles(opts, finiteSeedRange, finiteFillRange, direction);\n\n // Copy metadata from seed to fill range\n this.fillMetadata(opts, finiteSeedRange, finiteFillRange, direction);\n\n // Copy range metadata from seed to fill range\n this.fillRangeMetadata(opts, finiteSeedRange, finiteFillRange, direction);\n }\n\n private getSeedCells(\n opts: { sheetName: string; workbookName: string },\n seedRange: FiniteSpreadsheetRange\n ) {\n const cells: Array<{\n address: CellAddress;\n content: SerializedCellValue;\n rowOffset: number;\n colOffset: number;\n }> = [];\n\n const startCol = seedRange.start.col;\n const startRow = seedRange.start.row;\n const endCol = seedRange.end.col;\n const endRow = seedRange.end.row;\n\n for (let row = startRow; row <= endRow; row++) {\n for (let col = startCol; col <= endCol; col++) {\n const address: CellAddress = {\n sheetName: opts.sheetName,\n workbookName: opts.workbookName,\n colIndex: col,\n rowIndex: row,\n };\n const content = this.getCellContent(address);\n cells.push({\n address,\n content,\n rowOffset: row - startRow,\n colOffset: col - startCol,\n });\n }\n }\n\n return cells;\n }\n\n private collectSingleCellPattern(\n seedCell: { address: CellAddress; content: SerializedCellValue },\n fillRange: FiniteSpreadsheetRange,\n direction: FillDirection,\n changes: Map<string, SerializedCellValue>\n ) {\n const { content } = seedCell;\n\n const startCol = fillRange.start.col;\n const startRow = fillRange.start.row;\n const endCol = fillRange.end.col;\n const endRow = fillRange.end.row;\n\n for (let row = startRow; row <= endRow; row++) {\n for (let col = startCol; col <= endCol; col++) {\n const targetAddress: CellAddress = {\n sheetName: seedCell.address.sheetName,\n workbookName: seedCell.address.workbookName,\n colIndex: col,\n rowIndex: row,\n };\n\n let newContent: SerializedCellValue;\n\n if (content === undefined || content === \"\") {\n // Blank cell - fills blanks (effectively clears targets)\n newContent = undefined;\n } else if (typeof content === \"string\" && content.startsWith(\"=\")) {\n // Formula - adjust relative references\n newContent = this.adjustFormulaReferences(\n content,\n seedCell.address,\n targetAddress\n );\n } else {\n // Number or text - copy by default\n newContent = content;\n }\n\n changes.set(getCellReference(targetAddress), newContent);\n }\n }\n }\n\n private collectMultiCellPattern(\n seedCells: Array<{\n address: CellAddress;\n content: SerializedCellValue;\n rowOffset: number;\n colOffset: number;\n }>,\n seedRange: FiniteSpreadsheetRange,\n fillRange: FiniteSpreadsheetRange,\n direction: FillDirection,\n changes: Map<string, SerializedCellValue>\n ) {\n // Try to infer linear step from numbers\n const step = this.inferLinearStep(seedCells, direction);\n\n const startCol = fillRange.start.col;\n const startRow = fillRange.start.row;\n const endCol = fillRange.end.col;\n const endRow = fillRange.end.row;\n\n const seedWidth = seedRange.end.col - seedRange.start.col + 1;\n const seedHeight = seedRange.end.row - seedRange.start.row + 1;\n\n for (let row = startRow; row <= endRow; row++) {\n for (let col = startCol; col <= endCol; col++) {\n const targetAddress: LocalCellAddress = {\n colIndex: col,\n rowIndex: row,\n };\n\n let newContent: SerializedCellValue;\n\n if (step !== null) {\n // Use linear progression\n newContent = this.applyLinearStep(\n seedCells,\n targetAddress,\n seedRange,\n step,\n direction\n );\n } else {\n // Repeat pattern (cycle through seed block)\n const seedColOffset = (col - startCol) % seedWidth;\n const seedRowOffset = (row - startRow) % seedHeight;\n\n const seedCell = seedCells.find(\n (cell) =>\n cell.colOffset === seedColOffset &&\n cell.rowOffset === seedRowOffset\n );\n\n if (seedCell) {\n if (\n typeof seedCell.content === \"string\" &&\n seedCell.content.startsWith(\"=\")\n ) {\n // Formula - adjust relative references\n newContent = this.adjustFormulaReferences(\n seedCell.content,\n seedCell.address,\n targetAddress\n );\n } else {\n newContent = seedCell.content;\n }\n } else {\n newContent = undefined;\n }\n }\n\n changes.set(getCellReference(targetAddress), newContent);\n }\n }\n }\n\n private inferLinearStep(\n seedCells: Array<{\n content: SerializedCellValue;\n rowOffset: number;\n colOffset: number;\n }>,\n direction: FillDirection\n ): number | null {\n // Extract numeric values in the direction of fill\n const values: number[] = [];\n\n if (direction === \"down\" || direction === \"up\") {\n // Look at first column, different rows\n const firstColCells = seedCells\n .filter((cell) => cell.colOffset === 0)\n .sort((a, b) => a.rowOffset - b.rowOffset);\n\n for (const cell of firstColCells) {\n if (typeof cell.content === \"number\") {\n values.push(cell.content);\n } else if (typeof cell.content === \"string\") {\n const num = parseFloat(cell.content);\n if (!isNaN(num)) {\n values.push(num);\n } else {\n return null; // Non-numeric content, can't infer step\n }\n } else {\n return null;\n }\n }\n } else {\n // Look at first row, different columns\n const firstRowCells = seedCells\n .filter((cell) => cell.rowOffset === 0)\n .sort((a, b) => a.colOffset - b.colOffset);\n\n for (const cell of firstRowCells) {\n if (typeof cell.content === \"number\") {\n values.push(cell.content);\n } else if (typeof cell.content === \"string\") {\n const num = parseFloat(cell.content);\n if (!isNaN(num)) {\n values.push(num);\n } else {\n return null; // Non-numeric content, can't infer step\n }\n } else {\n return null;\n }\n }\n }\n\n if (values.length < 2) {\n return null;\n }\n\n // Check if there's a consistent step\n const step = values[1]! - values[0]!;\n for (let i = 2; i < values.length; i++) {\n if (Math.abs(values[i]! - values[i - 1]! - step) > 1e-10) {\n return null; // Inconsistent step\n }\n }\n\n return step;\n }\n\n private applyLinearStep(\n seedCells: Array<{\n content: SerializedCellValue;\n rowOffset: number;\n colOffset: number;\n }>,\n targetAddress: LocalCellAddress,\n seedRange: FiniteSpreadsheetRange,\n step: number,\n direction: FillDirection\n ): SerializedCellValue {\n // Calculate the position in the overall sequence\n let positionInSequence: number;\n let baseValue: number;\n\n if (direction === \"down\") {\n positionInSequence = targetAddress.rowIndex - seedRange.start.row;\n\n // Find the base value from the first row of the seed\n const baseCell = seedCells.find(\n (cell) =>\n cell.colOffset === targetAddress.colIndex - seedRange.start.col &&\n cell.rowOffset === 0\n );\n\n if (!baseCell) return undefined;\n baseValue =\n typeof baseCell.content === \"number\"\n ? baseCell.content\n : parseFloat(String(baseCell.content || \"0\"));\n } else if (direction === \"up\") {\n positionInSequence = targetAddress.rowIndex - seedRange.start.row;\n\n // Find the base value from the first row of the seed (same as down direction)\n const baseCell = seedCells.find(\n (cell) =>\n cell.colOffset === targetAddress.colIndex - seedRange.start.col &&\n cell.rowOffset === 0\n );\n\n if (!baseCell) return undefined;\n baseValue =\n typeof baseCell.content === \"number\"\n ? baseCell.content\n : parseFloat(String(baseCell.content || \"0\"));\n } else if (direction === \"right\") {\n positionInSequence = targetAddress.colIndex - seedRange.start.col;\n\n // Find the base value from the first column of the seed\n const baseCell = seedCells.find(\n (cell) =>\n cell.rowOffset === targetAddress.rowIndex - seedRange.start.row &&\n cell.colOffset === 0\n );\n\n if (!baseCell) return undefined;\n baseValue =\n typeof baseCell.content === \"number\"\n ? baseCell.content\n : parseFloat(String(baseCell.content || \"0\"));\n } else {\n // left\n positionInSequence = targetAddress.colIndex - seedRange.start.col;\n\n // Find the base value from the first column of the seed (same as right direction)\n const baseCell = seedCells.find(\n (cell) =>\n cell.rowOffset === targetAddress.rowIndex - seedRange.start.row &&\n cell.colOffset === 0\n );\n\n if (!baseCell) return undefined;\n baseValue =\n typeof baseCell.content === \"number\"\n ? baseCell.content\n : parseFloat(String(baseCell.content || \"0\"));\n }\n\n if (isNaN(baseValue)) {\n return undefined;\n }\n\n const result = baseValue + step * positionInSequence;\n return typeof seedCells[0]?.content === \"string\"\n ? result.toString()\n : result;\n }\n\n private adjustFormulaReferences(\n formula: string,\n sourceAddress: LocalCellAddress,\n targetAddress: LocalCellAddress\n ): string {\n try {\n const ast = parseFormula(formula.slice(1)); // Remove the \"=\" sign\n\n const rowDelta = targetAddress.rowIndex - sourceAddress.rowIndex;\n const colDelta = targetAddress.colIndex - sourceAddress.colIndex;\n\n const adjustedAst = transformAST(ast, (node) => {\n if (node.type === \"reference\") {\n const refNode = node as ReferenceNode;\n return {\n ...refNode,\n address: {\n colIndex: refNode.isAbsolute.col\n ? refNode.address.colIndex\n : refNode.address.colIndex + colDelta,\n rowIndex: refNode.isAbsolute.row\n ? refNode.address.rowIndex\n : refNode.address.rowIndex + rowDelta,\n },\n };\n } else if (node.type === \"range\") {\n const rangeNode = node as RangeNode;\n return {\n ...rangeNode,\n range: {\n start: {\n col: rangeNode.isAbsolute.start.col\n ? rangeNode.range.start.col\n : rangeNode.range.start.col + colDelta,\n row: rangeNode.isAbsolute.start.row\n ? rangeNode.range.start.row\n : rangeNode.range.start.row + rowDelta,\n },\n end: {\n col:\n rangeNode.range.end.col.type === \"number\"\n ? rangeNode.isAbsolute.end.col\n ? rangeNode.range.end.col\n : {\n type: \"number\" as const,\n value: rangeNode.range.end.col.value + colDelta,\n }\n : rangeNode.range.end.col,\n row:\n rangeNode.range.end.row.type === \"number\"\n ? rangeNode.isAbsolute.end.row\n ? rangeNode.range.end.row\n : {\n type: \"number\" as const,\n value: rangeNode.range.end.row.value + rowDelta,\n }\n : rangeNode.range.end.row,\n },\n },\n };\n }\n return node;\n });\n\n return `=${astToString(adjustedAst)}`;\n } catch (error) {\n // If parsing fails, return the original formula\n console.warn(\"Failed to adjust formula references:\", error);\n return formula;\n }\n }\n\n /**\n * Fill styles from seed range to fill range based on direction\n * Clears existing cell styles in fill range first (Excel behavior)\n */\n private fillStyles(\n opts: { sheetName: string; workbookName: string },\n seedRange: FiniteSpreadsheetRange,\n fillRange: FiniteSpreadsheetRange,\n direction: FillDirection\n ): void {\n // STEP 1: Clear existing cell styles in fill range (Excel-like replacement)\n const fillRangeAddress: RangeAddress = {\n workbookName: opts.workbookName,\n sheetName: opts.sheetName,\n range: {\n start: { col: fillRange.start.col, row: fillRange.start.row },\n end: {\n col: { type: \"number\", value: fillRange.end.col },\n row: { type: \"number\", value: fillRange.end.row },\n },\n },\n };\n \n this.styleManager.clearCellStylesInRange(fillRangeAddress);\n\n const seedWidth = seedRange.end.col - seedRange.start.col + 1;\n const seedHeight = seedRange.end.row - seedRange.start.row + 1;\n\n // STEP 2: Get all styles intersecting with seed range\n const seedSpreadsheetRange: SpreadsheetRange = {\n start: { col: seedRange.start.col, row: seedRange.start.row },\n end: {\n col: { type: \"number\", value: seedRange.end.col },\n row: { type: \"number\", value: seedRange.end.row },\n },\n };\n\n const allConditionalStyles = this.styleManager.getAllConditionalStyles();\n const allCellStyles = this.styleManager.getAllCellStyles();\n\n // STEP 3: For each cell in fill range, determine corresponding seed cell and copy styles\n for (let row = fillRange.start.row; row <= fillRange.end.row; row++) {\n for (let col = fillRange.start.col; col <= fillRange.end.col; col++) {\n // Determine which seed cell corresponds to this fill cell\n let seedCol: number;\n let seedRow: number;\n\n if (direction === \"down\" || direction === \"up\") {\n // Vertical fill: keep column aligned, pattern repeat on rows\n seedCol = seedRange.start.col + (col - fillRange.start.col) % seedWidth;\n seedRow = seedRange.start.row + (row - fillRange.start.row) % seedHeight;\n } else {\n // Horizontal fill: keep row aligned, pattern repeat on columns\n seedRow = seedRange.start.row + (row - fillRange.start.row) % seedHeight;\n seedCol = seedRange.start.col + (col - fillRange.start.col) % seedWidth;\n }\n\n const sourceCellRange: SpreadsheetRange = {\n start: { col: seedCol, row: seedRow },\n end: {\n col: { type: \"number\", value: seedCol },\n row: { type: \"number\", value: seedRow },\n },\n };\n\n const targetCell: CellAddress = {\n workbookName: opts.workbookName,\n sheetName: opts.sheetName,\n colIndex: col,\n rowIndex: row,\n };\n\n // Copy conditional styles\n for (const style of allConditionalStyles) {\n for (const area of style.areas) {\n if (\n area.workbookName === opts.workbookName &&\n area.sheetName === opts.sheetName\n ) {\n const intersection = intersectRanges(area.range, sourceCellRange);\n if (intersection) {\n const newStyle: ConditionalStyle = {\n areas: [{\n workbookName: opts.workbookName,\n sheetName: opts.sheetName,\n range: {\n start: { col: targetCell.colIndex, row: targetCell.rowIndex },\n end: {\n col: { type: \"number\", value: targetCell.colIndex },\n row: { type: \"number\", value: targetCell.rowIndex },\n },\n },\n }],\n condition: style.condition,\n };\n this.styleManager.addConditionalStyle(newStyle);\n }\n }\n }\n }\n\n // Copy cell styles\n for (const style of allCellStyles) {\n for (const area of style.areas) {\n if (\n area.workbookName === opts.workbookName &&\n area.sheetName === opts.sheetName\n ) {\n const intersection = intersectRanges(area.range, sourceCellRange);\n if (intersection) {\n const newStyle: DirectCellStyle = {\n areas: [{\n workbookName: opts.workbookName,\n sheetName: opts.sheetName,\n range: {\n start: { col: targetCell.colIndex, row: targetCell.rowIndex },\n end: {\n col: { type: \"number\", value: targetCell.colIndex },\n row: { type: \"number\", value: targetCell.rowIndex },\n },\n },\n }],\n style: style.style,\n };\n this.styleManager.addCellStyle(newStyle);\n }\n }\n }\n }\n }\n }\n }\n\n /**\n * Copy metadata from seed range to fill range with pattern repetition\n */\n private fillMetadata(\n opts: { sheetName: string; workbookName: string },\n seedRange: FiniteSpreadsheetRange,\n fillRange: FiniteSpreadsheetRange,\n direction: FillDirection\n ): void {\n const seedWidth = seedRange.end.col - seedRange.start.col + 1;\n const seedHeight = seedRange.end.row - seedRange.start.row + 1;\n\n // For each cell in fill range, copy metadata from corresponding seed cell\n for (let row = fillRange.start.row; row <= fillRange.end.row; row++) {\n for (let col = fillRange.start.col; col <= fillRange.end.col; col++) {\n // Determine which seed cell corresponds to this fill cell\n let seedCol: number;\n let seedRow: number;\n\n if (direction === \"down\" || direction === \"up\") {\n // Vertical fill: keep column aligned, pattern repeat on rows\n seedCol = seedRange.start.col + (col - fillRange.start.col) % seedWidth;\n seedRow = seedRange.start.row + (row - fillRange.start.row) % seedHeight;\n } else {\n // Horizontal fill: keep row aligned, pattern repeat on columns\n seedRow = seedRange.start.row + (row - fillRange.start.row) % seedHeight;\n seedCol = seedRange.start.col + (col - fillRange.start.col) % seedWidth;\n }\n\n const sourceCellAddress: CellAddress = {\n workbookName: opts.workbookName,\n sheetName: opts.sheetName,\n colIndex: seedCol,\n rowIndex: seedRow,\n };\n\n const targetCellAddress: CellAddress = {\n workbookName: opts.workbookName,\n sheetName: opts.sheetName,\n colIndex: col,\n rowIndex: row,\n };\n\n // Copy metadata from source to target\n const sourceMetadata = this.workbookManager.getCellMetadata(sourceCellAddress);\n if (sourceMetadata) {\n this.workbookManager.setCellMetadata(targetCellAddress, { ...sourceMetadata });\n }\n }\n }\n }\n\n /**\n * Copy range metadata from seed range to fill range with pattern repetition.\n */\n private fillRangeMetadata(\n opts: { sheetName: string; workbookName: string },\n seedRange: FiniteSpreadsheetRange,\n fillRange: FiniteSpreadsheetRange,\n direction: FillDirection\n ): void {\n const fillRangeAddress: RangeAddress = {\n workbookName: opts.workbookName,\n sheetName: opts.sheetName,\n range: {\n start: { col: fillRange.start.col, row: fillRange.start.row },\n end: {\n col: { type: \"number\", value: fillRange.end.col },\n row: { type: \"number\", value: fillRange.end.row },\n },\n },\n };\n\n this.rangeMetadataManager.clearRangeMetadataInRange(fillRangeAddress);\n\n const seedWidth = seedRange.end.col - seedRange.start.col + 1;\n const seedHeight = seedRange.end.row - seedRange.start.row + 1;\n const allRangeMetadata = this.rangeMetadataManager.getAllRangeMetadata();\n\n for (let row = fillRange.start.row; row <= fillRange.end.row; row++) {\n for (let col = fillRange.start.col; col <= fillRange.end.col; col++) {\n let seedCol: number;\n let seedRow: number;\n\n if (direction === \"down\" || direction === \"up\") {\n seedCol = seedRange.start.col + (col - fillRange.start.col) % seedWidth;\n seedRow = seedRange.start.row + (row - fillRange.start.row) % seedHeight;\n } else {\n seedRow = seedRange.start.row + (row - fillRange.start.row) % seedHeight;\n seedCol = seedRange.start.col + (col - fillRange.start.col) % seedWidth;\n }\n\n const sourceCellRange: SpreadsheetRange = {\n start: { col: seedCol, row: seedRow },\n end: {\n col: { type: \"number\", value: seedCol },\n row: { type: \"number\", value: seedRow },\n },\n };\n\n const targetCellRange: RangeAddress = {\n workbookName: opts.workbookName,\n sheetName: opts.sheetName,\n range: {\n start: { col, row },\n end: {\n col: { type: \"number\", value: col },\n row: { type: \"number\", value: row },\n },\n },\n };\n\n for (const entry of allRangeMetadata) {\n for (const area of entry.areas) {\n if (\n area.workbookName !== opts.workbookName ||\n area.sheetName !== opts.sheetName\n ) {\n continue;\n }\n\n const intersection = intersectRanges(area.range, sourceCellRange);\n if (!intersection) {\n continue;\n }\n\n this.rangeMetadataManager.addRangeMetadata({\n areas: [targetCellRange],\n metadata: entry.metadata,\n });\n }\n }\n }\n }\n }\n}\n"
|
|
6
6
|
],
|
|
7
|
-
"mappings": "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",
|
|
8
|
-
"debugId": "
|
|
7
|
+
"mappings": "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",
|
|
8
|
+
"debugId": "8E208D0BC4A4FCCD64756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/core/engine-snapshot.ts
|
|
2
|
-
var ENGINE_SNAPSHOT_VERSION =
|
|
2
|
+
var ENGINE_SNAPSHOT_VERSION = 5;
|
|
3
3
|
function getAstNodeSnapshotId(node) {
|
|
4
4
|
return `${node.key}::${JSON.stringify(node.getContextDependency())}`;
|
|
5
5
|
}
|
|
@@ -8,4 +8,4 @@ export {
|
|
|
8
8
|
ENGINE_SNAPSHOT_VERSION
|
|
9
9
|
};
|
|
10
10
|
|
|
11
|
-
//# debugId=
|
|
11
|
+
//# debugId=024E0D4A5B98A79764756E2164756E21
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/core/engine-snapshot.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"import type { ContextDependency } from \"../evaluator/evaluation-context.mjs\";\nimport type { DependencyNode } from \"./managers/dependency-node.mjs\";\nimport type {\n CellAddress,\n CellInRangeResult,\n CellValue,\n ConditionalStyle,\n DirectCellStyle,\n FormulaError,\n NamedExpression,\n RangeAddress,\n RelativeRange,\n SpreadsheetRange,\n TableDefinition,\n TrackedReference,\n Workbook,\n} from \"./types.mjs\";\n\nexport const ENGINE_SNAPSHOT_VERSION =
|
|
5
|
+
"import type { ContextDependency } from \"../evaluator/evaluation-context.mjs\";\nimport type { DependencyNode } from \"./managers/dependency-node.mjs\";\nimport type {\n CellAddress,\n CellInRangeResult,\n CellValue,\n ConditionalStyle,\n DirectCellStyle,\n FormulaError,\n NamedExpression,\n RangeAddress,\n RangeMetadata,\n RelativeRange,\n SpreadsheetRange,\n TableDefinition,\n TrackedReference,\n Workbook,\n} from \"./types.mjs\";\n\nexport const ENGINE_SNAPSHOT_VERSION = 5 as const;\n\nexport type NodeSnapshotId = string;\n\nexport type NamedExpressionManagerSnapshot = {\n sheetExpressions: Map<string, Map<string, Map<string, NamedExpression>>>;\n workbookExpressions: Map<string, Map<string, NamedExpression>>;\n globalExpressions: Map<string, NamedExpression>;\n};\n\nexport type WorkbookManagerSnapshot = Map<string, Workbook>;\n\nexport type TableManagerSnapshot = Map<string, Map<string, TableDefinition>>;\n\nexport type StyleManagerSnapshot = {\n conditionalStyles: ConditionalStyle[];\n cellStyles: DirectCellStyle[];\n};\n\nexport type RangeMetadataManagerSnapshot = RangeMetadata[];\n\nexport type ReferenceManagerSnapshot = Map<string, TrackedReference>;\n\nexport type SerializedValueEvaluationResultSnapshot = {\n type: \"value\";\n result: CellValue;\n sourceCell?: CellAddress;\n};\n\nexport type SerializedErrorEvaluationResultSnapshot = {\n type: \"error\";\n err: FormulaError;\n message: string;\n errAddressId: NodeSnapshotId;\n sourceCell?: CellAddress;\n};\n\nexport type SerializedSingleEvaluationResultSnapshot =\n | SerializedValueEvaluationResultSnapshot\n | SerializedErrorEvaluationResultSnapshot;\n\nexport type SerializedCellInRangeResultSnapshot = {\n relativePos: CellInRangeResult[\"relativePos\"];\n result: SerializedSingleEvaluationResultSnapshot;\n};\n\nexport type SerializedEvaluateAllCellsResultSnapshot =\n | SerializedErrorEvaluationResultSnapshot\n | {\n type: \"values\";\n values: SerializedCellInRangeResultSnapshot[];\n };\n\nexport type SerializedMaterializedSpillSnapshot = {\n kind: \"materialized\";\n relativeSpillArea: RelativeRange;\n source: string;\n sourceCell?: CellAddress;\n sourceRange?: RangeAddress;\n values: SerializedCellInRangeResultSnapshot[];\n};\n\nexport type SerializedSourceRangeSpillSnapshot = {\n kind: \"source-range\";\n relativeSpillArea: RelativeRange;\n source: string;\n sourceCell?: CellAddress;\n sourceRange: RangeAddress;\n};\n\nexport type SerializedSpillResultSnapshot =\n | SerializedMaterializedSpillSnapshot\n | SerializedSourceRangeSpillSnapshot;\n\nexport type SerializedSpilledValuesEvaluationResultSnapshot = {\n type: \"spilled-values\";\n spill: SerializedSpillResultSnapshot;\n};\n\nexport type SerializedFunctionEvaluationResultSnapshot =\n | SerializedSingleEvaluationResultSnapshot\n | SerializedSpilledValuesEvaluationResultSnapshot;\n\nexport type SerializedSpillMetaEvaluationResultSnapshot =\n | SerializedErrorEvaluationResultSnapshot\n | SerializedSpilledValuesEvaluationResultSnapshot\n | {\n type: \"does-not-spill\";\n };\n\ntype SerializedBaseNodeSnapshot = {\n snapshotId: NodeSnapshotId;\n key: string;\n dependencies: NodeSnapshotId[];\n};\n\nexport type SerializedCellValueNodeSnapshot = SerializedBaseNodeSnapshot & {\n kind: \"cell-value\";\n evaluationResult: SerializedSingleEvaluationResultSnapshot;\n spillMetaSnapshotId?: NodeSnapshotId;\n};\n\nexport type SerializedSpillMetaNodeSnapshot = SerializedBaseNodeSnapshot & {\n kind: \"spill-meta\";\n evaluationResult: SerializedSpillMetaEvaluationResultSnapshot;\n};\n\nexport type SerializedEmptyCellNodeSnapshot = SerializedBaseNodeSnapshot & {\n kind: \"empty\";\n evaluationResult: SerializedSingleEvaluationResultSnapshot;\n};\n\nexport type SerializedRangeNodeSnapshot = SerializedBaseNodeSnapshot & {\n kind: \"range\";\n result: SerializedEvaluateAllCellsResultSnapshot;\n};\n\nexport type SerializedAstNodeSnapshot = SerializedBaseNodeSnapshot & {\n kind: \"ast\";\n contextDependency: ContextDependency;\n evaluationResult: SerializedFunctionEvaluationResultSnapshot;\n};\n\nexport type SerializedResourceNodeSnapshot = SerializedBaseNodeSnapshot & {\n kind: \"resource\";\n};\n\nexport type SerializedDependencyNodeSnapshot =\n | SerializedCellValueNodeSnapshot\n | SerializedSpillMetaNodeSnapshot\n | SerializedEmptyCellNodeSnapshot\n | SerializedRangeNodeSnapshot\n | SerializedAstNodeSnapshot\n | SerializedResourceNodeSnapshot;\n\nexport type DependencyManagerSnapshot = {\n nodes: SerializedDependencyNodeSnapshot[];\n spilledValues: Array<[string, { origin: CellAddress; spillOnto: SpreadsheetRange }]>;\n};\n\nexport type SerializedSCCSnapshot = {\n id: number;\n nodes: NodeSnapshotId[];\n evaluationOrder: NodeSnapshotId[];\n resolved: boolean;\n hardEdgeSCCs: NodeSnapshotId[][];\n};\n\nexport type SerializedEvaluationOrderSnapshot = {\n nodeKey: string;\n evaluationOrder: NodeSnapshotId[];\n hasCycle: boolean;\n cycleNodes?: NodeSnapshotId[];\n hash: string;\n};\n\nexport type CacheManagerSnapshot = {\n evaluationOrders: SerializedEvaluationOrderSnapshot[];\n sccs: Array<{\n hash: string;\n scc: SerializedSCCSnapshot;\n }>;\n};\n\ntype EngineSnapshotManagers = {\n workbook: WorkbookManagerSnapshot;\n namedExpression: NamedExpressionManagerSnapshot;\n table: TableManagerSnapshot;\n style: StyleManagerSnapshot;\n rangeMetadata: RangeMetadataManagerSnapshot;\n reference: ReferenceManagerSnapshot;\n dependency: DependencyManagerSnapshot;\n cache: CacheManagerSnapshot;\n};\n\nexport type EngineSnapshot = {\n version: typeof ENGINE_SNAPSHOT_VERSION;\n managers: EngineSnapshotManagers;\n};\n\nexport function getAstNodeSnapshotId(\n node: DependencyNode & { getContextDependency(): ContextDependency }\n): NodeSnapshotId {\n return `${node.key}::${JSON.stringify(node.getContextDependency())}`;\n}\n"
|
|
6
6
|
],
|
|
7
|
-
"mappings": ";
|
|
8
|
-
"debugId": "
|
|
7
|
+
"mappings": ";AAmBO,IAAM,0BAA0B;AAoLhC,SAAS,oBAAoB,CAClC,MACgB;AAAA,EAChB,OAAO,GAAG,KAAK,QAAQ,KAAK,UAAU,KAAK,qBAAqB,CAAC;AAAA;",
|
|
8
|
+
"debugId": "024E0D4A5B98A79764756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|