-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
/
evalInContext.ts
30 lines (28 loc) · 1.16 KB
/
evalInContext.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
/**
* Eval example code in a custom context:
* - `require()` that allows you to require modules from Markdown examples
* (won’t work dinamically becasue we need to know all required modules in
* advance to be able to bundle them with the code).
* - `state` variable, `setState` function that will be binded to a React
* component that manages example’s state on the frontend.
*
* Also prepends a given `code` with a `header` (maps required context modules
* to local variables: React, current component and modules defined via the
* `context` config option).
*/
export default function evalInContext(
header: string,
require: (module: string) => any,
code: string
): (state: Record<string, unknown>, setState: any) => any {
// 1. Prepend code with the header
// 2. Wrap code in a block (`{}`) to create a new scope, so you could
// explicitly import context modules in your examples)
const body = `${header}
{${code}}`;
// eslint-disable-next-line no-new-func
const func = new Function('require', 'state', 'setState', body);
// Bind the `require` function, other context arguments will be passed from
// the frontend
return func.bind(null, require);
}