Skip to content

Commit 3a2259f

Browse files
committed
wip
1 parent 2bdbc10 commit 3a2259f

File tree

3 files changed

+46
-44
lines changed

3 files changed

+46
-44
lines changed

package-lock.json

Lines changed: 12 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/form-js-viewer/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
},
4646
"dependencies": {
4747
"@carbon/grid": "^11.11.0",
48+
"@jetbrains/websandbox": "^1.0.10",
4849
"big.js": "^6.2.1",
4950
"classnames": "^2.3.1",
5051
"didi": "^10.0.1",

packages/form-js-viewer/src/render/components/form-fields/JSFunctionField.js

Lines changed: 33 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,72 +1,61 @@
1+
import Sandbox from 'websandbox';
12
import { useCallback, useEffect, useState } from 'preact/hooks';
2-
import { useExpressionEvaluation, useDeepCompareMemoize, usePrevious } from '../../hooks';
3+
import { useExpressionEvaluation, useDeepCompareMemoize } from '../../hooks';
34
import { isObject } from 'min-dash';
45

5-
const type = 'script';
66

77
export function JSFunctionField(props) {
88
const { field, onChange } = props;
9-
const { jsFunction, functionParameters, onLoadOnly } = field;
9+
const { jsFunction, functionParameters } = field;
1010

11-
const [ loadLatch, setLoadLatch ] = useState(false);
11+
const [ sandbox, setSandbox ] = useState(null);
1212

1313
const paramsEval = useExpressionEvaluation(functionParameters);
1414
const params = useDeepCompareMemoize(isObject(paramsEval) ? paramsEval : {});
1515

16-
const functionMemo = useCallback((params) => {
17-
18-
const cleanupCallbacks = [];
19-
20-
try {
21-
22-
setLoadLatch(true);
23-
const func = new Function('data', 'setValue', 'onCleanup', jsFunction);
24-
func(params, value => onChange({ field, value }), callback => cleanupCallbacks.push(callback));
25-
26-
} catch (error) {
27-
28-
// invalid expression definition, may happen during editing
29-
if (error instanceof SyntaxError) {
30-
return;
16+
const rebuildSandbox = useCallback(() => {
17+
const localApi = {
18+
setValue: function(value) {
19+
onChange({ field, value });
3120
}
32-
33-
console.error('Error evaluating expression:', error);
34-
onChange({ field, value: null });
35-
}
36-
37-
return () => {
38-
cleanupCallbacks.forEach(fn => fn());
3921
};
4022

41-
}, [ jsFunction, field, onChange ]);
42-
43-
const previousFunctionMemo = usePrevious(functionMemo);
44-
const previousParams = usePrevious(params);
23+
const newSandbox = Sandbox.create(localApi, {
24+
frameContainer: '.iframe__container',
25+
frameClassName: 'simple__iframe'
26+
});
4527

46-
useEffect(() => {
28+
newSandbox.promise.then((sandboxInstance) => {
29+
setSandbox(sandboxInstance);
30+
sandboxInstance.run(`
31+
Websandbox.connection.setLocalApi({
32+
onInit: () => Websandbox.connection.remote.onInit(),
33+
onData: (data) => Websandbox.connection.remote.onData(data),
34+
});
4735
48-
// reset load latch
49-
if (!onLoadOnly && loadLatch) {
50-
setLoadLatch(false);
51-
}
36+
// Custom user code
37+
${jsFunction}
38+
`);
5239

53-
const functionChanged = previousFunctionMemo !== functionMemo;
54-
const paramsChanged = previousParams !== params;
55-
const alreadyLoaded = onLoadOnly && loadLatch;
40+
sandboxInstance.connection.remote.onInit();
41+
});
42+
}, [ jsFunction, onChange, field ]);
5643

57-
const shouldExecute = functionChanged || paramsChanged && !alreadyLoaded;
44+
useEffect(() => {
45+
rebuildSandbox();
46+
}, [ rebuildSandbox ]);
5847

59-
if (shouldExecute) {
60-
return functionMemo(params);
48+
useEffect(() => {
49+
if (sandbox && sandbox.connection && sandbox.connection.remote.onData) {
50+
sandbox.connection.remote.onData(params);
6151
}
62-
63-
}, [ previousFunctionMemo, functionMemo, previousParams, params, loadLatch, onLoadOnly ]);
52+
}, [ params, sandbox ]);
6453

6554
return null;
6655
}
6756

6857
JSFunctionField.config = {
69-
type,
58+
type: 'script',
7059
label: 'JS Function',
7160
group: 'basic-input',
7261
keyed: true,

0 commit comments

Comments
 (0)