SpriteDX - Implementing Computed Properties

Here we go. 99 days til Alpha. Today, w will be implementing aforementioned computed properties.
Quick Recap
We will use following format to allow for arbitrary javascript to run inside a safe quick-js sandbox.
"inputs": {
"fullName": {
"type": "string",
"computed": {
"sandbox": "quickjs", // default, but required to be specified
"with": {
"firstName": "..userInfo.firstName",
"lastName": "..userInfo.lastName"
},
"script": "`${firstName} ${lastName}`"
}
}
}
The main use-case again will be transforming inputs before feeding into the comfy workflow.
/**
* Run compute in a safe sandbox (QuickJS)
*
* "computed": {
* "sandbox": "quickjs",
* "with": { "scene": "sceneDescription", "shots": "shots" },
* "script": "`[SCENE DESCRIPTION] ${scene}\\n\\n${shots.map((shot, i) => `[SHOT ${i + 1}] ${shot.prompt}`).join('\\n\\n')}`"
* }
*/
function runSafeCompute<T = unknown>(
computed: Computed,
idPath: string,
fromPath: string,
pipeline: Pipeline,
values: Record<string, unknown>
): T {
const { sandbox, with: withMap, script } = computed;
if (sandbox !== "quickjs") {
throw new Error(`Unsupported compute sandbox: ${sandbox}`);
}
const withValues: Record<string, unknown> = {};
for (const [varName, varSource] of Object.entries(withMap)) {
withValues[varName] = getValueFromPipeline(varSource, fromPath, pipeline, values);
}
const QuickJS = globalThis.QuickJS;
if (!QuickJS) {
throw new Error("QuickJS is not loaded yet.");
}
const vm = QuickJS.newContext();
try {
Object.entries(withValues).forEach(([k, v]) => {
const prepResult = vm.evalCode(`var ${k} = ${JSON.stringify(v)};`);
if (prepResult.error) {
const dumped = vm.dump(prepResult.error);
prepResult.error.dispose();
throw new Error(
`Error when setting props for computed script for ${idPath}: ${JSON.stringify(dumped)}`
);
}
prepResult.value.dispose();
});
const result = vm.evalCode(script);
if (result.error) {
const dumped = vm.dump(result.error);
result.error.dispose();
throw new Error(`Error in computed script for ${idPath}: ${JSON.stringify(dumped)}`);
}
const value = vm.dump(result.value);
result.value.dispose();
return value as T;
} finally {
vm.dispose();
}
}
Here is the implementation.
It basically produces following script, and runs it inside QuickJS container.
var ${k} = ${JSON.stringify(v)};
{script}
Looks good so far.
—Sprited Dev 🌱




