/** * Build the ES module source that runs inside the dynamic Worker. * * The module exports a `WorkerEntrypoint` subclass with an `evaluate` * method that: * 1. Captures console output into `__logs`. * 2. Creates a recursive `tools` Proxy that dispatches calls via RPC. * 3. Executes the normalised user code with a `Promise.race` timeout. * 4. Returns `{ result, error?, logs }`. */export const buildExecutorModule = (normalizedCode: string, timeoutMs: number): string => [ 'import { WorkerEntrypoint } from "cloudflare:workers";', "", "export default class CodeExecutor extends WorkerEntrypoint {", " async evaluate(__dispatcher) {", " const __logs = [];", ' console.log = (...a) => { __logs.push(a.map(String).join(" ")); };', ' console.warn = (...a) => { __logs.push("[warn] " + a.map(String).join(" ")); };', ' console.error = (...a) => { __logs.push("[error] " + a.map(String).join(" ")); };', "", " const __makeToolsProxy = (path = []) => new Proxy(() => undefined, {", " get(_target, prop) {", " if (prop === 'then' || typeof prop === 'symbol') return undefined;", " return __makeToolsProxy([...path, String(prop)]);", " },", " apply(_target, _thisArg, args) {", " const toolPath = path.join('.');", " if (!toolPath) throw new Error('Tool path missing in invocation');", " return __dispatcher.call(toolPath, JSON.stringify(args[0] ?? {})).then((raw) => {", " const data = JSON.parse(raw);", " if (data.error) throw new Error(data.error);", " return data.result;", " });", " },", " });", " const tools = __makeToolsProxy();", "", " try {", " const result = await Promise.race([", ` (${normalizedCode})(),`, " new Promise((_, reject) =>", ` setTimeout(() => reject(new Error("Execution timed out after ${timeoutMs}ms")), ${timeoutMs})`, " ),", " ]);", " return { result, logs: __logs };", " } catch (err) {", " return { result: undefined, error: err.message ?? String(err), logs: __logs };", " }", " }", "}", ].join("\n");
/**
* Build the ES module source that runs inside the dynamic Worker.
*
* The module exports a `WorkerEntrypoint` subclass with an `evaluate`
* method that:
* 1. Captures console output into `__logs`.
* 2. Creates a recursive `tools` Proxy that dispatches calls via RPC.
* 3. Executes the normalised user code with a `Promise.race` timeout.
* 4. Returns `{ result, error?, logs }`.
*/
export const buildExecutorModule = (normalizedCode: string, timeoutMs: number): string =>
[
'import { WorkerEntrypoint } from "cloudflare:workers";',
"",
"export default class CodeExecutor extends WorkerEntrypoint {",
" async evaluate(__dispatcher) {",
" const __logs = [];",
' console.log = (...a) => { __logs.push(a.map(String).join(" ")); };',
' console.warn = (...a) => { __logs.push("[warn] " + a.map(String).join(" ")); };',
' console.error = (...a) => { __logs.push("[error] " + a.map(String).join(" ")); };',
"",
" const __makeToolsProxy = (path = []) => new Proxy(() => undefined, {",
" get(_target, prop) {",
" if (prop === 'then' || typeof prop === 'symbol') return undefined;",
" return __makeToolsProxy([...path, String(prop)]);",
" },",
" apply(_target, _thisArg, args) {",
" const toolPath = path.join('.');",
" if (!toolPath) throw new Error('Tool path missing in invocation');",
" return __dispatcher.call(toolPath, JSON.stringify(args[0] ?? {})).then((raw) => {",
" const data = JSON.parse(raw);",
" if (data.error) throw new Error(data.error);",
" return data.result;",
" });",
" },",
" });",
" const tools = __makeToolsProxy();",
"",
" try {",
" const result = await Promise.race([",
` (${normalizedCode})(),`,
" new Promise((_, reject) =>",
` setTimeout(() => reject(new Error("Execution timed out after ${timeoutMs}ms")), ${timeoutMs})`,
" ),",
" ]);",
" return { result, logs: __logs };",
" } catch (err) {",
" return { result: undefined, error: err.message ?? String(err), logs: __logs };",
" }",
" }",
"}",
].join("\n");