Skip to content

Commit 912bfa4

Browse files
authored
Make state values available in eval context SSR (#4135)
## Description In client side evaluations state values are available without needing the `state.` prefix. Now this should work in SSR as well. I also prevented shadowing of some special globals that we set ourselves and don't want to override.
1 parent c042d67 commit 912bfa4

File tree

2 files changed

+44
-0
lines changed

2 files changed

+44
-0
lines changed

.changeset/sharp-pandas-joke.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@builder.io/react": patch
3+
---
4+
5+
Fixed state variable context availability in SSR rendering

packages/react/src/functions/try-eval.tsx

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,29 @@ export const tryEval = (str?: string, data: any = {}, errors?: Error[]): any =>
5656
// for the server build
5757
const ivm = safeDynamicRequire('isolated-vm');
5858
const context = getIsolateContext();
59+
60+
Object.keys(data).forEach(key => {
61+
switch (key) {
62+
case 'state':
63+
case 'global':
64+
case 'log':
65+
console.warn(`Not setting state.${key} as global ${key} in isolated vm`);
66+
break;
67+
default:
68+
if (data[key] === undefined) {
69+
return;
70+
}
71+
try {
72+
if (typeof data[key] === 'object' && data[key] !== null) {
73+
context.global.setSync(key, new ivm.ExternalCopy(data[key]).copyInto());
74+
} else {
75+
context.global.setSync(key, data[key]);
76+
}
77+
} catch (error) {
78+
console.warn(`Could not set ${key} for isolated-vm:`, error);
79+
}
80+
}
81+
});
5982
const fnString = makeFn(str!, useReturn, ['state']);
6083
const resultStr = context.evalClosureSync(fnString, [new ivm.Reference(data || {})]);
6184
try {
@@ -78,6 +101,22 @@ export const tryEval = (str?: string, data: any = {}, errors?: Error[]): any =>
78101
}
79102
// Add to req.options.errors to return to client
80103
}
104+
} finally {
105+
if (!(Builder.isBrowser || shouldForceBrowserRuntimeInNode())) {
106+
const context = getIsolateContext();
107+
108+
// Clean up the global context
109+
Object.keys(data).forEach(key => {
110+
switch (key) {
111+
case 'state':
112+
case 'global':
113+
case 'log':
114+
break;
115+
default:
116+
context.global.deleteSync(key);
117+
}
118+
});
119+
}
81120
}
82121

83122
return;

0 commit comments

Comments
 (0)