fix function body extracter

This commit is contained in:
Han Tuerker
2022-12-10 11:42:08 +08:00
parent 30a563015a
commit 11d2635463
4 changed files with 31 additions and 17 deletions

View File

@@ -13,7 +13,7 @@ export default function Formula(props: IDisplayCellProps) {
const DisplayCell = getDisplayCell(type);
if (error) {
return <>Error</>;
return <>Error ${error}</>;
}
return <DisplayCell {...props} value={result} disabled={true} />;

View File

@@ -3,7 +3,11 @@ import { TableRow } from "@src/types/table";
import { useAtom } from "jotai";
import { pick, zipObject } from "lodash-es";
import { useEffect, useMemo, useState } from "react";
import { listenerFieldTypes, useDeepCompareMemoize } from "./util";
import {
getFunctionBody,
listenerFieldTypes,
useDeepCompareMemoize,
} from "./util";
export const useFormula = ({
row,
@@ -40,17 +44,17 @@ export const useFormula = ({
);
useEffect(() => {
setError(null);
setLoading(true);
const worker = new Worker(new URL("./worker.ts", import.meta.url), {
type: "module",
});
const timeout = setTimeout(() => {
setError(new Error("Timeout"));
setLoading(false);
worker.terminate();
}, 10000);
// const timeout = setTimeout(() => {
// setError(new Error("timeout"));
// setLoading(false);
// worker.terminate();
// }, 1000);
worker.onmessage = ({ data: { result, error } }: any) => {
worker.terminate();
if (error) {
@@ -59,18 +63,17 @@ export const useFormula = ({
setResult(result);
}
setLoading(false);
clearInterval(timeout);
// clearInterval(timeout);
};
const functionBody = formulaFn.replace(/^.*=>\s*{/, "").replace(/}$/, "");
worker.postMessage({
formulaFn: functionBody,
formulaFn: getFunctionBody(formulaFn),
row: availableFields,
});
return () => {
worker.terminate();
clearInterval(timeout);
// clearInterval(timeout);
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [useDeepCompareMemoize(listeners), formulaFn]);

View File

@@ -124,3 +124,19 @@ export const getDisplayCell = (type: FieldType) => {
return ShortTextDisplayCell;
}
};
export const getFunctionBody = (fn: string) => {
const sanitizedFn = fn.replace(/\/\*[\s\S]*?\*\/|\/\/.*/g, "");
const matches = sanitizedFn.match(/=>\s*({?[\s\S]*}?)$/);
if (!matches) {
return null;
}
const body = matches[1].trim();
const isOneLiner = body[0] !== "{" && body[body.length - 1] !== "}";
if (isOneLiner) return `return ${body}`;
return body.slice(1, body.length - 1);
};

View File

@@ -1,14 +1,9 @@
onmessage = async ({ data }) => {
try {
const { formulaFn, row } = data;
const AsyncFunction = async function () {}.constructor as any;
const fn = new AsyncFunction("row", formulaFn);
const result = await fn(row);
await new Promise((resolve) => setTimeout(() => resolve(50), 3000)).then(
(res) => console.log(res)
);
console.log(result);
postMessage({ result });
} catch (error: any) {
console.error("error: ", error);