import { renderToString } from "npm:react-dom/server";
import { blob } from "https://esm.town/v/std/blob?v=12";
import { createHash } from "node:crypto";
import base32Encode from "npm:base32-encode";
const oneSecond = 1000;
const TIMEOUT = 5 * oneSecond;
blob.setJSON;
const fetch = async (req: Request): Promise<Response> => {
let repp = new Repp([{
code: "",
}, {
code: ``,
}]);
if (req.method === "GET") {
return new Response(
renderToString(
<div>
<form method="POST">
<textarea name="code">hi</textarea>
<button type="submit">Submit</button>
</form>
</div>,
),
{ headers: { "content-type": "text/html" } },
);
}
};
interface Segment {
code: string;
result?: { args: unknown[]; level: string; index: number }[];
}
const hashSegments = (segments: Segment[]): string => {
return base32Encode(
createHash("sha256").update(JSON.stringify(segments.map(s => s.code))).digest().slice(0, 20),
"RFC4648",
{ padding: false },
).toLowerCase();
};
type Log = {
level: string;
args: unknown[];
stack: string;
};
const workerScript = () => {
type Log = {
level: string;
args: unknown[];
stack: string;
};
const logs: Log[] = [];
globalThis.console = new Proxy(console, {
get(target, key) {
const real = target[key];
if (typeof real === "function" && typeof key === "string") {
const fn = function(...args: any[]) {
logs.push({
level: key,
stack: new Error().stack.replace("Error\n", "")
.split("\n").filter((s) => !s.includes("Proxy.fn"))
.join("\n"),
args,
});
return real.call(this, ...args);
};
return fn;
}
},
});
async function evaluate(url) {
try {
const _ = await import(url);
return;
} catch (err) {
return { error: { message: err.message, stack: err.stack.replaceAll(url, "./script.ts") } };
}
}
self.onmessage = async (e) => {
const blob = new Blob([e.data], { type: "text/tsx" });
const url = URL.createObjectURL(blob);
let resp = await evaluate(url);
logs.forEach((l) => {
l.stack = l.stack.replaceAll(url, "./script.ts");
});
self.postMessage(JSON.stringify({ resp, logs }));
};
};
type EvalResponse = { segments?: Segment[]; error?: { message: string; stack: string } };