From 832f3cdfe3eb29f8b233649d5721164cd1b1860c Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sun, 7 Dec 2025 13:38:38 +0000
Subject: [PATCH 01/10] Initial plan
From 010bce0073ade1d84d350c7a55a9687240c30d49 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sun, 7 Dec 2025 13:46:54 +0000
Subject: [PATCH 02/10] Refactor message processing to use Comlink library
- Install comlink dependency
- Refactor jsEval.worker.ts to expose API via Comlink
- Refactor pyodide.worker.ts to expose API via Comlink
- Refactor ruby.worker.ts to expose API via Comlink
- Refactor runtime.tsx to use Comlink wrap() instead of manual message handling
- Remove manual ID tracking and callback management
- Simplify worker communication using Comlink's RPC pattern
Co-authored-by: na-trium-144 <100704180+na-trium-144@users.noreply.github.com>
---
app/terminal/worker/jsEval.worker.ts | 96 ++++++------------
app/terminal/worker/pyodide.worker.ts | 111 +++++++--------------
app/terminal/worker/ruby.worker.ts | 136 +++++++------------------
app/terminal/worker/runtime.tsx | 138 ++++++++------------------
package-lock.json | 7 ++
package.json | 1 +
6 files changed, 157 insertions(+), 332 deletions(-)
diff --git a/app/terminal/worker/jsEval.worker.ts b/app/terminal/worker/jsEval.worker.ts
index d266282..08b1b2e 100644
--- a/app/terminal/worker/jsEval.worker.ts
+++ b/app/terminal/worker/jsEval.worker.ts
@@ -1,7 +1,8 @@
///
+import { expose } from "comlink";
import type { ReplOutput } from "../repl";
-import type { MessageType, WorkerRequest, WorkerResponse } from "./runtime";
+import type { WorkerCapabilities } from "./runtime";
import inspect from "object-inspect";
function format(...args: unknown[]): string {
@@ -29,12 +30,9 @@ self.console = {
},
};
-async function init({ id }: WorkerRequest["init"]) {
+async function init(): Promise<{ capabilities: WorkerCapabilities }> {
// Initialize the worker and report capabilities
- self.postMessage({
- id,
- payload: { capabilities: { interrupt: "restart" } },
- } satisfies WorkerResponse["init"]);
+ return { capabilities: { interrupt: "restart" } };
}
async function replLikeEval(code: string): Promise {
@@ -72,8 +70,10 @@ async function replLikeEval(code: string): Promise {
}
}
-async function runCode({ id, payload }: WorkerRequest["runCode"]) {
- const { code } = payload;
+async function runCode(code: string): Promise<{
+ output: ReplOutput[];
+ updatedFiles: Record;
+}> {
try {
const result = await replLikeEval(code);
jsOutput.push({
@@ -99,14 +99,13 @@ async function runCode({ id, payload }: WorkerRequest["runCode"]) {
const output = [...jsOutput];
jsOutput = []; // Clear output
- self.postMessage({
- id,
- payload: { output, updatedFiles: [] },
- } satisfies WorkerResponse["runCode"]);
+ return { output, updatedFiles: {} };
}
-function runFile({ id, payload }: WorkerRequest["runFile"]) {
- const { name, files } = payload;
+function runFile(
+ name: string,
+ files: Record
+): { output: ReplOutput[]; updatedFiles: Record } {
// pyodide worker などと異なり、複数ファイルを読み込んでimportのようなことをするのには対応していません。
try {
self.eval(files[name]);
@@ -129,23 +128,17 @@ function runFile({ id, payload }: WorkerRequest["runFile"]) {
const output = [...jsOutput];
jsOutput = []; // Clear output
- self.postMessage({
- id,
- payload: { output, updatedFiles: [] },
- } satisfies WorkerResponse["runFile"]);
+ return { output, updatedFiles: {} };
}
-async function checkSyntax({ id, payload }: WorkerRequest["checkSyntax"]) {
- const { code } = payload;
-
+async function checkSyntax(
+ code: string
+): Promise<{ status: "complete" | "incomplete" | "invalid" }> {
try {
// Try to create a Function to check syntax
// new Function(code); // <- not working
self.eval(`() => {${code}}`);
- self.postMessage({
- id,
- payload: { status: "complete" },
- } satisfies WorkerResponse["checkSyntax"]);
+ return { status: "complete" };
} catch (e) {
// Check if it's a syntax error or if more input is expected
if (e instanceof SyntaxError) {
@@ -154,28 +147,18 @@ async function checkSyntax({ id, payload }: WorkerRequest["checkSyntax"]) {
e.message.includes("Unexpected token '}'") ||
e.message.includes("Unexpected end of input")
) {
- self.postMessage({
- id,
- payload: { status: "incomplete" },
- } satisfies WorkerResponse["checkSyntax"]);
+ return { status: "incomplete" };
} else {
- self.postMessage({
- id,
- payload: { status: "invalid" },
- } satisfies WorkerResponse["checkSyntax"]);
+ return { status: "invalid" };
}
} else {
- self.postMessage({
- id,
- payload: { status: "invalid" },
- } satisfies WorkerResponse["checkSyntax"]);
+ return { status: "invalid" };
}
}
}
-async function restoreState({ id, payload }: WorkerRequest["restoreState"]) {
+async function restoreState(commands: string[]): Promise