diff --git a/src/scripts/repl-init.ts b/src/scripts/repl-init.ts index 4e14a28..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,38 @@ const commonSettings = { theme: "custom-theme", }; +// 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..."); + const languageSelector = document.getElementById("input-language") as HTMLSelectElement; const inputEditor = monaco.editor.create(inputContainer, { value: inputContents.trim(), - language: "javascript", + language: "typescript", ...commonSettings, }); const outputEditor = monaco.editor.create(outputContainer, { @@ -86,13 +112,22 @@ document.addEventListener("DOMContentLoaded", () => { readOnly: true, }); + 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(() => { - 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;