From 430122c49d1627dd8fe16352ddeee58559365671 Mon Sep 17 00:00:00 2001 From: Raunak Raj <71929976+bajrangCoder@users.noreply.github.com> Date: Thu, 27 Aug 2026 22:47:20 +0530 Subject: [PATCH 1/2] fix(console): run JavaScript files in isolated worker --- src/lib/console.js | 20 ++++++++ src/lib/consoleRuntime.js | 31 ++++++++++++ src/lib/run.js | 2 +- src/views/console.hbs | 8 +-- tests/unit/consoleExecutionContext.test.js | 59 ++++++++++++++++++++++ 5 files changed, 116 insertions(+), 4 deletions(-) diff --git a/src/lib/console.js b/src/lib/console.js index 05ca41fa6a..35a32cb2b9 100644 --- a/src/lib/console.js +++ b/src/lib/console.js @@ -7,6 +7,7 @@ import loadPolyFill from "utils/polyfill"; import ConsoleExecutor, { applyConsoleViewport, executeConsoleCommand, + executeConsoleScript, resolveConsoleExecutionContext, } from "./consoleRuntime"; @@ -25,6 +26,9 @@ import ConsoleExecutor, { const themeEndpoint = document.querySelector( 'meta[name="acode-console-theme-endpoint"]', )?.content; + const startupScriptUrl = document.querySelector( + 'meta[name="acode-console-executing-script"]', + )?.content; const originalConsole = console; const $input = tag("textarea", { id: "__c-input", @@ -184,6 +188,7 @@ import ConsoleExecutor, { if (isStandaloneConsole) { showConsole(); + void runStartupScript(); return; } @@ -205,6 +210,21 @@ import ConsoleExecutor, { themeSyncTimer = null; } + async function runStartupScript() { + if (!startupScriptUrl) return; + + setExecutionState(true); + const result = await executeConsoleScript({ + scriptUrl: startupScriptUrl, + workerExecutor: executor, + }); + setExecutionState(false); + + if (result?.type === "error") { + log("error", getStack(new Error()), result.value); + } + } + async function syncTheme() { if (themeSyncPending) return; themeSyncPending = true; diff --git a/src/lib/consoleRuntime.js b/src/lib/consoleRuntime.js index 383ddd0946..5e45e25236 100644 --- a/src/lib/consoleRuntime.js +++ b/src/lib/consoleRuntime.js @@ -184,3 +184,34 @@ export function executeConsoleCommand({ if (context === "page") return Promise.resolve(pageExecutor(code)); return workerExecutor.execute(code); } + +/** + * Loads a standalone JavaScript file and executes it in the isolated console + * worker. The file is fetched first so it is never inserted as a page script. + */ +export async function executeConsoleScript({ + scriptUrl, + workerExecutor, + fetchScript = globalThis.fetch, +}) { + if (!scriptUrl) return null; + + try { + if (typeof fetchScript !== "function") { + throw new Error("This WebView cannot load the JavaScript file."); + } + + const response = await fetchScript(scriptUrl, { cache: "no-store" }); + if (!response.ok) { + const status = response.status ? ` (${response.status})` : ""; + throw new Error(`Failed to load JavaScript file${status}.`); + } + + return workerExecutor.execute(await response.text()); + } catch (error) { + return { + type: "error", + value: error instanceof Error ? error : new Error(String(error)), + }; + } +} diff --git a/src/lib/run.js b/src/lib/run.js index d130c11bae..3f40a098aa 100644 --- a/src/lib/run.js +++ b/src/lib/run.js @@ -72,7 +72,7 @@ async function run( let isLoading = false; let filename, pathName, extension; let port = appSettings.value.serverPort; - let EXECUTING_SCRIPT = uuid + "_script.js"; + let EXECUTING_SCRIPT = null; const MIMETYPE_HTML = mimeType.lookup("html"); const CONSOLE_SCRIPT = uuid + "_console.js"; const CONSOLE_WORKER_SCRIPT = uuid + "_console_worker.js"; diff --git a/src/views/console.hbs b/src/views/console.hbs index 40068d74c8..69ba1eca4e 100644 --- a/src/views/console.hbs +++ b/src/views/console.hbs @@ -6,15 +6,17 @@ + {{#EXECUTING_SCRIPT}} + + {{/EXECUTING_SCRIPT}}