Add a "donkey" worker that execs or evaluates all the things (#2210)

* WIP

* Add a "donkey" worker that execs or evaluates all the things

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
Andrea Giammarchi
2024-10-04 17:06:07 +02:00
committed by GitHub
parent 8c6bfecbff
commit f827efe2fc
10 changed files with 137 additions and 10 deletions

View File

@@ -0,0 +1,64 @@
import { assign, dedent } from "polyscript/exports";
const invoke = (name, args) => `${name}(code, ${args.join(", ")})`;
export default (options = {}) => {
const type = options.type || "py";
const args = options.persistent
? ["globals()", "__locals__"]
: ["{}", "{}"];
const src = URL.createObjectURL(
new Blob([
dedent(`
from pyscript import sync, config
__message__ = lambda e,v: f"\x1b[31m\x1b[1m{e.__name__}\x1b[0m: {v}"
__locals__ = {}
if config["type"] == "py":
import sys
def __error__(_):
info = sys.exc_info()
return __message__(info[0], info[1])
else:
__error__ = lambda e: __message__(e.__class__, e.value)
def execute(code):
try: return ${invoke("exec", args)};
except Exception as e: print(__error__(e));
def evaluate(code):
try: return ${invoke("eval", args)};
except Exception as e: print(__error__(e));
sync.execute = execute
sync.evaluate = evaluate
`),
]),
);
const script = assign(document.createElement("script"), { type, src });
script.toggleAttribute("worker", true);
script.toggleAttribute("terminal", true);
if (options.terminal) script.setAttribute("target", options.terminal);
if (options.config)
script.setAttribute("config", JSON.stringify(options.config));
return new Promise((resolve) => {
script.addEventListener(`${type}:done`, (event) => {
event.stopPropagation();
URL.revokeObjectURL(src);
const { xworker, process, terminal } = script;
const { execute, evaluate } = xworker.sync;
script.remove();
resolve({
process,
execute: (code) => execute(dedent(code)),
evaluate: (code) => evaluate(dedent(code)),
clear: () => terminal.clear(),
reset: () => terminal.reset(),
kill: () => {
xworker.terminate();
terminal.dispose();
},
});
});
document.body.append(script);
});
};