2024-02-09 04:00:45 +08:00
|
|
|
import { System } from "../lib/plugos/system.ts";
|
2024-02-06 23:51:04 +08:00
|
|
|
import { ScriptObject } from "../plugs/index/script.ts";
|
2024-02-07 21:50:01 +08:00
|
|
|
import { AppCommand, CommandDef } from "./hooks/command.ts";
|
2024-02-06 23:51:04 +08:00
|
|
|
|
|
|
|
export class ScriptEnvironment {
|
2024-02-07 21:50:01 +08:00
|
|
|
functions: Record<string, (...args: any[]) => any> = {};
|
|
|
|
commands: Record<string, AppCommand> = {};
|
2024-02-06 23:51:04 +08:00
|
|
|
|
|
|
|
// Public API
|
2024-02-07 21:50:01 +08:00
|
|
|
registerFunction(name: string, fn: (...args: any[]) => any) {
|
2024-02-06 23:51:04 +08:00
|
|
|
this.functions[name] = fn;
|
|
|
|
}
|
|
|
|
|
2024-02-07 21:50:01 +08:00
|
|
|
registerCommand(command: CommandDef, fn: (...args: any[]) => any) {
|
|
|
|
this.commands[command.name] = {
|
|
|
|
command,
|
|
|
|
run: (...args: any[]) => {
|
|
|
|
return new Promise((resolve) => {
|
|
|
|
// Next tick
|
|
|
|
setTimeout(() => {
|
|
|
|
resolve(fn(...args));
|
|
|
|
});
|
|
|
|
});
|
|
|
|
},
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2024-02-06 23:51:04 +08:00
|
|
|
// Internal API
|
|
|
|
evalScript(script: string, system: System<any>) {
|
|
|
|
try {
|
2024-02-07 21:50:01 +08:00
|
|
|
const fn = Function(
|
|
|
|
"silverbullet",
|
|
|
|
"syscall",
|
|
|
|
"Deno",
|
|
|
|
"window",
|
|
|
|
"globalThis",
|
|
|
|
"self",
|
|
|
|
script,
|
|
|
|
);
|
|
|
|
fn.call(
|
|
|
|
{},
|
2024-02-06 23:51:04 +08:00
|
|
|
this,
|
|
|
|
(name: string, ...args: any[]) => system.syscall({}, name, args),
|
2024-02-07 21:50:01 +08:00
|
|
|
// The rest is explicitly left to be undefined to prevent access to the global scope
|
2024-02-06 23:51:04 +08:00
|
|
|
);
|
|
|
|
} catch (e: any) {
|
|
|
|
throw new Error(
|
|
|
|
`Error evaluating script: ${e.message} for script: ${script}`,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
async loadFromSystem(system: System<any>) {
|
|
|
|
if (!system.loadedPlugs.has("index")) {
|
|
|
|
console.warn("Index plug not found, skipping loading space scripts");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
const allScripts: ScriptObject[] = await system.invokeFunction(
|
|
|
|
"index.queryObjects",
|
|
|
|
["space-script", {}],
|
|
|
|
);
|
|
|
|
for (const script of allScripts) {
|
|
|
|
this.evalScript(script.script, system);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|