quickjs-worker
Run QuickJS as a worker from NodeJS
Run untrusted ES6 code in a secure QuickJS sandbox. Includes worker like API and eval API. Every instance runs in it's own thread and memory space. Also supports loading and exporting bytecode.
Example:
import { QJSWorker } from "quickjs-worker";
const runtime = QJSWorker({
console: {
log: (...args) => {
}
},
maxEvalMs: 1500,
maxMemoryBytes: 256 * 1000 * 1000,
maxStackSizeBytes: 10 * 1000 * 1000,
maxInterrupt: 10000,
staticGlobals: {
a_boolean: true,
addTwo: (a, b) => a + b,
json_value: {
state: "Texas"
}
}
});
runtime.on("message", (msg) => {
})
runtime.postMessage({key: "value"})
(async () => {
const [evalResult, evalStats] = await runtime.eval("2 + 2");
console.assert(evalResult == 4);
const [addTwoResult] = await runtime.eval("addTwo(2, 3)");
console.assert(addTwoResult == 5);
const [jsonValue] = await runtime.eval("json_value.state");
console.assert(jsonValue == "Texas");
const [promise] = await runtime.eval("Promise.resolve({hello: 'world'})");
console.assert(promise.hello == "world");
const [nestedPromise] = await runtime.eval("Promise.resolve(Promise.resolve({hello: 'world'}))");
console.assert(nestedPromise.hello == "world");
await runtime.eval(`on('message', (msg) => { /* handle message */ })`);
await runtime.eval(`postMessage(["never", "gonna", "give"])`);
const memStatus = await runtime.memory();
await runtime.gc();
const byteCode = await runtime.getByteCode(`const test = (a, b) => Promise.resolve(a+b)`);
const runtime2 = QJSWorker();
await runtime2.loadByteCode(byteCode);
const [byteCodeFnResult] = await runtime2.eval(`test(1, 2)`);
console.assert(byteCodeFnResult == 3);
await runtime.close();
await runtime2.close();
})()
Current major limitations:
- Alpha software, don't have any tests in place yet.
- Would like to support async functions in staticGlobals at some point.
- Does not support es6 modules
import
or export
syntax in the runtime.