Refactor
This commit is contained in:
parent
1ee20b0464
commit
e2a1d8c880
1 changed files with 26 additions and 27 deletions
|
@ -13,25 +13,24 @@ class ScriptRunner {
|
||||||
this.vm = new IsolatedVM({
|
this.vm = new IsolatedVM({
|
||||||
memoryLimit: env.JS_RUNNER_MEMORY_LIMIT,
|
memoryLimit: env.JS_RUNNER_MEMORY_LIMIT,
|
||||||
parseBson,
|
parseBson,
|
||||||
|
context: {
|
||||||
|
...context,
|
||||||
|
data: parseBson
|
||||||
|
? bson.BSON.serialize({ data: context.data })
|
||||||
|
: context.data,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
this.vm.context = {
|
|
||||||
...context,
|
|
||||||
data: parseBson
|
|
||||||
? bson.BSON.serialize({ data: context.data })
|
|
||||||
: context.data,
|
|
||||||
results: { out: "" },
|
|
||||||
}
|
|
||||||
|
|
||||||
if (parseBson) {
|
if (parseBson) {
|
||||||
script = `return JSON.parse(JSON.stringify((function(){data=deserialize(data).data;${script}})()));`
|
script = `return JSON.parse(JSON.stringify((function(){data=deserialize(data).data;${script}})()));`
|
||||||
}
|
}
|
||||||
|
|
||||||
const code = `const fn=function(){${script}};cb(fn());`
|
this.vm.code = script
|
||||||
this.vm.code = code
|
|
||||||
}
|
}
|
||||||
|
|
||||||
execute() {
|
execute() {
|
||||||
const result = this.vm.runScript()
|
this.vm.runScript()
|
||||||
|
const result = this.vm.getResult()
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -43,18 +42,27 @@ class IsolatedVM {
|
||||||
#script: ivm.Module = undefined!
|
#script: ivm.Module = undefined!
|
||||||
#bsonModule?: ivm.Module
|
#bsonModule?: ivm.Module
|
||||||
|
|
||||||
|
readonly #resultKey = "results"
|
||||||
|
|
||||||
constructor({
|
constructor({
|
||||||
memoryLimit,
|
memoryLimit,
|
||||||
parseBson,
|
parseBson,
|
||||||
|
context,
|
||||||
}: {
|
}: {
|
||||||
memoryLimit: number
|
memoryLimit: number
|
||||||
parseBson: boolean
|
parseBson: boolean
|
||||||
|
context: Record<string, any>
|
||||||
}) {
|
}) {
|
||||||
this.#isolate = new ivm.Isolate({ memoryLimit })
|
this.#isolate = new ivm.Isolate({ memoryLimit })
|
||||||
this.#vm = this.#isolate.createContextSync()
|
this.#vm = this.#isolate.createContextSync()
|
||||||
this.#jail = this.#vm.global
|
this.#jail = this.#vm.global
|
||||||
this.#jail.setSync("global", this.#jail.derefInto())
|
this.#jail.setSync("global", this.#jail.derefInto())
|
||||||
|
|
||||||
|
this.#addToContext(context)
|
||||||
|
this.#addToContext({
|
||||||
|
[this.#resultKey]: { out: "" },
|
||||||
|
})
|
||||||
|
|
||||||
if (parseBson) {
|
if (parseBson) {
|
||||||
const bsonSource = loadBundle(BundleType.BSON)
|
const bsonSource = loadBundle(BundleType.BSON)
|
||||||
this.#bsonModule = this.#isolate.compileModuleSync(bsonSource)
|
this.#bsonModule = this.#isolate.compileModuleSync(bsonSource)
|
||||||
|
@ -64,27 +72,28 @@ class IsolatedVM {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getValue(key: string) {
|
getResult() {
|
||||||
const ref = this.#vm.global.getSync(key, { reference: true })
|
const ref = this.#vm.global.getSync(this.#resultKey, { reference: true })
|
||||||
const result = ref.copySync()
|
const result = ref.copySync()
|
||||||
ref.release()
|
ref.release()
|
||||||
return result
|
return result.out
|
||||||
}
|
}
|
||||||
|
|
||||||
set context(context: Record<string, any>) {
|
#addToContext(context: Record<string, any>) {
|
||||||
for (let key in context) {
|
for (let key in context) {
|
||||||
this.#jail.setSync(key, this.copyRefToVm(context[key]))
|
this.#jail.setSync(key, this.#copyRefToVm(context[key]))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
set code(code: string) {
|
set code(code: string) {
|
||||||
|
code = `const fn=function(){${code}};results.out=fn();`
|
||||||
if (this.#bsonModule) {
|
if (this.#bsonModule) {
|
||||||
code = `import {deserialize} from "compiled_module";${code}`
|
code = `import {deserialize} from "compiled_module";${code}`
|
||||||
}
|
}
|
||||||
this.#script = this.#isolate.compileModuleSync(code)
|
this.#script = this.#isolate.compileModuleSync(code)
|
||||||
}
|
}
|
||||||
|
|
||||||
runScript() {
|
runScript(): void {
|
||||||
if (this.#bsonModule) {
|
if (this.#bsonModule) {
|
||||||
this.#script.instantiateSync(this.#vm, specifier => {
|
this.#script.instantiateSync(this.#vm, specifier => {
|
||||||
if (specifier === "compiled_module") {
|
if (specifier === "compiled_module") {
|
||||||
|
@ -95,20 +104,10 @@ class IsolatedVM {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
let result
|
|
||||||
this.#vm.global.setSync(
|
|
||||||
"cb",
|
|
||||||
new ivm.Callback((value: any) => {
|
|
||||||
result = value
|
|
||||||
})
|
|
||||||
)
|
|
||||||
|
|
||||||
this.#script.evaluateSync({ timeout: JS_TIMEOUT_MS })
|
this.#script.evaluateSync({ timeout: JS_TIMEOUT_MS })
|
||||||
|
|
||||||
return result
|
|
||||||
}
|
}
|
||||||
|
|
||||||
copyRefToVm(value: Object): ivm.Copy<Object> {
|
#copyRefToVm(value: Object): ivm.Copy<Object> {
|
||||||
return new ivm.ExternalCopy(value).copyInto({ release: true })
|
return new ivm.ExternalCopy(value).copyInto({ release: true })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue