From e29711a4e250f15799da2284c66cf565782b6310 Mon Sep 17 00:00:00 2001 From: Owen Buckley Date: Mon, 1 Jun 2026 21:28:56 -0400 Subject: [PATCH 1/2] feat: #11 support multiple language formats --- src/index.html | 6 ++++++ src/scripts/repl-init.ts | 27 +++++++++++++++++++++++++-- src/scripts/repl.ts | 5 ++++- 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/src/index.html b/src/index.html index 01b8da1..3c1c1d8 100644 --- a/src/index.html +++ b/src/index.html @@ -62,6 +62,12 @@

Input

+
diff --git a/src/scripts/repl-init.ts b/src/scripts/repl-init.ts index 4e14a28..3ff4aff 100644 --- a/src/scripts/repl-init.ts +++ b/src/scripts/repl-init.ts @@ -72,12 +72,22 @@ const commonSettings = { theme: "custom-theme", }; +const extensionLanguageMapper = { + js: "javascript", + ts: "typescript", + jsx: "javascript", + tsx: "typescript", +}; + document.addEventListener("DOMContentLoaded", () => { console.log("Initializing Editor..."); + const languageSelector = document.getElementById("input-language") as HTMLSelectElement; const inputEditor = monaco.editor.create(inputContainer, { value: inputContents.trim(), - language: "javascript", + language: + extensionLanguageMapper[languageSelector.value as keyof typeof extensionLanguageMapper] ?? + "javascript", ...commonSettings, }); const outputEditor = monaco.editor.create(outputContainer, { @@ -86,13 +96,26 @@ document.addEventListener("DOMContentLoaded", () => { readOnly: true, }); + languageSelector.addEventListener("change", () => { + const language = + extensionLanguageMapper[languageSelector.value as keyof typeof extensionLanguageMapper] ?? + "javascript"; + monaco.editor.setModelLanguage(inputEditor.getModel()!, language); + }); + // listen for changes in the input editor and send the updated code to the worker for compilation inputEditor.onDidChangeModelContent(() => { - worker.postMessage([inputEditor.getValue()]); + worker.postMessage([inputEditor.getValue(), languageSelector.value ?? "javascript"]); }); // once the worker sends back the compiled HTML, update the output editor with the result worker.onmessage = (result) => { + if (result.data.err) { + console.error("Error in worker:", result.data.err); + outputEditor.setValue(`Error: ${result.data.err.message || result.data.err}`); + return; + } + outputEditor.setValue(prettify(result.data.output)); }; diff --git a/src/scripts/repl.ts b/src/scripts/repl.ts index bc61558..d38eddc 100644 --- a/src/scripts/repl.ts +++ b/src/scripts/repl.ts @@ -3,9 +3,12 @@ import { renderToString } from "wc-compiler"; onmessage = async (e) => { console.log("Worker: Message received from main script", { e }); const input = e.data[0]; - const props = e.data[1] ?? null; + const language = e.data[1] ?? "javascript"; + const props = e.data[2] ?? null; const wrappingEntryTag = true; + console.log({ input, language, props }); + let err; let output; From bb2b5e57fb583b988693ff5281accfc1c43424b1 Mon Sep 17 00:00:00 2001 From: Owen Buckley Date: Mon, 8 Jun 2026 20:57:47 -0400 Subject: [PATCH 2/2] feat: #11 tsx editor support --- src/index.html | 6 ------ src/scripts/repl-init.ts | 44 +++++++++++++++++++++++++--------------- 2 files changed, 28 insertions(+), 22 deletions(-) diff --git a/src/index.html b/src/index.html index 3c1c1d8..01b8da1 100644 --- a/src/index.html +++ b/src/index.html @@ -62,12 +62,6 @@

Input

-
diff --git a/src/scripts/repl-init.ts b/src/scripts/repl-init.ts index 3ff4aff..268ac75 100644 --- a/src/scripts/repl-init.ts +++ b/src/scripts/repl-init.ts @@ -54,7 +54,7 @@ class Footer extends HTMLElement { export default Footer; -customElements.define('wcc-footer', Footer); +customElements.define('x-footer', Footer); `; monaco.editor.defineTheme("custom-theme", { @@ -72,12 +72,30 @@ const commonSettings = { theme: "custom-theme", }; -const extensionLanguageMapper = { - js: "javascript", - ts: "typescript", - jsx: "javascript", - tsx: "typescript", -}; +// https://gist.github.com/RoboPhred/f767bea5cbc972e04155a625dc11da11 +// Important Bit #1: Typescript must see the 'file' it is editing as having a .tsx extension +const modelUri = monaco.Uri.file("file.tsx"); + +// Important Bit #2 +// By default, monaco use the "value" property to create its own model without any extensions, so typescript assumes ".ts" +// We need to create a custom model using the desired file name (uri). See the last arg. +const codeModel = monaco.editor.createModel( + inputContents.trim(), + "typescript", + modelUri, // Pass the file name to the model here. +); + +// Important Bit #3: Tell typescript to use 'react' for jsx files. +// TODO: support wc-compiler jsxImportSource +monaco.typescript.typescriptDefaults.setCompilerOptions({ + jsx: monaco.typescript.JsxEmit.Preserve, +}); + +// TODO: additional diagnostics +monaco.typescript.typescriptDefaults.setDiagnosticsOptions({ + noSemanticValidation: false, + noSyntaxValidation: false, +}); document.addEventListener("DOMContentLoaded", () => { console.log("Initializing Editor..."); @@ -85,9 +103,7 @@ document.addEventListener("DOMContentLoaded", () => { const inputEditor = monaco.editor.create(inputContainer, { value: inputContents.trim(), - language: - extensionLanguageMapper[languageSelector.value as keyof typeof extensionLanguageMapper] ?? - "javascript", + language: "typescript", ...commonSettings, }); const outputEditor = monaco.editor.create(outputContainer, { @@ -96,12 +112,8 @@ document.addEventListener("DOMContentLoaded", () => { readOnly: true, }); - languageSelector.addEventListener("change", () => { - const language = - extensionLanguageMapper[languageSelector.value as keyof typeof extensionLanguageMapper] ?? - "javascript"; - monaco.editor.setModelLanguage(inputEditor.getModel()!, language); - }); + inputEditor.setModel(codeModel); + monaco.editor.setModelLanguage(inputEditor.getModel()!, "typescript"); // listen for changes in the input editor and send the updated code to the worker for compilation inputEditor.onDidChangeModelContent(() => {