diff --git a/packages/server/src/jsRunner.ts b/packages/server/src/jsRunner.ts index abb4091835..179e736fb2 100644 --- a/packages/server/src/jsRunner.ts +++ b/packages/server/src/jsRunner.ts @@ -14,18 +14,20 @@ export function init() { setJSRunner((js: string, ctx: Record) => { return tracer.trace("runJS", {}, span => { const bbCtx = context.getCurrentContext()! - if (!bbCtx.jsIsolate) { - bbCtx.jsIsolate = new ivm.Isolate({ memoryLimit: 64 }) - bbCtx.jsContext = bbCtx.jsIsolate.createContextSync() - const helpersModule = bbCtx.jsIsolate.compileModuleSync(helpersSource) - helpersModule.instantiateSync(bbCtx.jsContext, specifier => { - throw new Error(`No imports allowed. Required: ${specifier}`) - }) - } + let { jsContext, jsIsolate } = bbCtx + // if (!jsIsolate) { + jsIsolate = new ivm.Isolate({ memoryLimit: 64 }) + jsContext = jsIsolate.createContextSync() + const helpersModule = jsIsolate.compileModuleSync(helpersSource) + + helpersModule.instantiateSync(jsContext, specifier => { + throw new Error(`No imports allowed. Required: ${specifier}`) + }) + // } const perRequestLimit = env.JS_PER_REQUEST_TIME_LIMIT_MS if (perRequestLimit) { - const cpuMs = Number(bbCtx.jsIsolate.cpuTime) / 1e6 + const cpuMs = Number(jsIsolate.cpuTime) / 1e6 if (cpuMs > perRequestLimit) { throw new Error( `CPU time limit exceeded (${cpuMs}ms > ${perRequestLimit}ms)` @@ -33,19 +35,42 @@ export function init() { } } - const global = bbCtx.jsContext!.global + const global = jsContext!.global + for (const [key, value] of Object.entries(ctx)) { - if (typeof value === "function") { - // Can't copy functions into the isolate, so we just ignore them + if (key === "helpers") { + // Can't copy the native helpers into the isolate. We just ignore them as they are handled properly from the helpersSource continue } - global.setSync(key, new ivm.ExternalCopy(value).copyInto()) + global.setSync(key, value) } - const script = bbCtx.jsIsolate.compileScriptSync(js) - return script.runSync(bbCtx.jsContext!, { + const script = jsIsolate.compileModuleSync( + `import helpers from "compiled_module";${js};cb(run());`, + {} + ) + + script.instantiateSync(jsContext!, specifier => { + if (specifier === "compiled_module") { + return helpersModule + } + + throw new Error(`"${specifier}" import not allowed`) + }) + + let result + global.setSync( + "cb", + new ivm.Callback((value: any) => { + result = value + }) + ) + + script.evaluateSync({ timeout: env.JS_PER_EXECUTION_TIME_LIMIT_MS, }) + + return result }) }) }