Skip to content

Commit ef821bb

Browse files
committed
Keep the FormulaParser around
1 parent db23c4d commit ef821bb

1 file changed

Lines changed: 30 additions & 24 deletions

File tree

src/columns/fast-formula-parser.ts

Lines changed: 30 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ import * as glide from "../glide";
22

33
import FormulaParser, { FormulaHelpers, Types } from "fast-formula-parser";
44

5+
let data: any[][] = [];
6+
57
function convertCell(cell: any): any {
68
try {
79
if (typeof cell === "string") {
@@ -16,35 +18,39 @@ function convertCell(cell: any): any {
1618
}
1719
}
1820

19-
const run: glide.Column = (formula, ...params) => {
20-
const data: any[][] = params.map(p => [p.value]);
21-
22-
const parser = new FormulaParser({
23-
functions: {
24-
UPPER: text => {
25-
text = FormulaHelpers.accept(text, Types.STRING);
26-
return text.toUpperCase();
27-
},
28-
},
29-
onCell: ({ _, row, col }) => {
30-
return convertCell(data[row - 1][col - 1]);
21+
// We keep a single instance of this because it caches parsed formulas. Making
22+
// a new one for each invocation makes running lots of these about 2 order of
23+
// magnitude slower.
24+
const parser = new FormulaParser({
25+
functions: {
26+
UPPER: text => {
27+
text = FormulaHelpers.accept(text, Types.STRING);
28+
return text.toUpperCase();
3129
},
32-
onRange: (ref: { from: { row: number; col: number }; to: { row: number; col: number } }) => {
33-
const arr: any[][] = [];
34-
for (let row = ref.from.row; row <= ref.to.row; row++) {
35-
const innerArr: any[] = [];
36-
if (data[row - 1]) {
37-
for (let col = ref.from.col; col <= ref.to.col; col++) {
38-
innerArr.push(convertCell(data[row - 1][col - 1]));
39-
}
30+
},
31+
onCell: ({ _, row, col }) => {
32+
return convertCell(data[row - 1][col - 1]);
33+
},
34+
onRange: (ref: { from: { row: number; col: number }; to: { row: number; col: number } }) => {
35+
const arr: any[][] = [];
36+
for (let row = ref.from.row; row <= ref.to.row; row++) {
37+
const innerArr: any[] = [];
38+
if (data[row - 1]) {
39+
for (let col = ref.from.col; col <= ref.to.col; col++) {
40+
innerArr.push(convertCell(data[row - 1][col - 1]));
4041
}
41-
arr.push(innerArr);
4242
}
43-
return arr;
44-
},
45-
});
43+
arr.push(innerArr);
44+
}
45+
return arr;
46+
},
47+
});
4648

49+
const run: glide.Column = (formula, ...params) => {
4750
if (formula?.value === undefined) return undefined;
51+
52+
data = params.map(p => [p.value]);
53+
4854
const position = { row: 1, col: 1, sheet: 0 };
4955
try {
5056
const v = parser.parse(formula.value, position);

0 commit comments

Comments
 (0)