From d403fdc945d5fc0dd7e008fb8fa475ff790dafcc Mon Sep 17 00:00:00 2001 From: "pullfrog[bot]" <226033991+pullfrog[bot]@users.noreply.github.com> Date: Tue, 9 Jun 2026 12:11:55 +0000 Subject: [PATCH 01/13] feat(languages): add Rune WASM language support --- functions/vendors/templates.js | 6 +-- scripts/build.js | 1 + src/livecodes/UI/command-menu-actions.ts | 1 + src/livecodes/html/language-info.html | 33 ++++++++++++ src/livecodes/languages/languages.ts | 2 + src/livecodes/languages/rune-wasm/index.ts | 1 + .../rune-wasm/lang-rune-wasm-script.ts | 53 +++++++++++++++++++ .../languages/rune-wasm/lang-rune-wasm.ts | 18 +++++++ src/livecodes/models.ts | 1 + src/livecodes/vendors.ts | 8 +++ src/sdk/models.ts | 5 ++ 11 files changed, 126 insertions(+), 3 deletions(-) create mode 100644 src/livecodes/languages/rune-wasm/index.ts create mode 100644 src/livecodes/languages/rune-wasm/lang-rune-wasm-script.ts create mode 100644 src/livecodes/languages/rune-wasm/lang-rune-wasm.ts diff --git a/functions/vendors/templates.js b/functions/vendors/templates.js index 46868446e..ace9a3ab5 100644 --- a/functions/vendors/templates.js +++ b/functions/vendors/templates.js @@ -1351,7 +1351,7 @@ func main() { fmt.Println("Hello from Go WebAssembly!") } } -`.trimStart()}};var I={name:"imba",title:getTemplateName("templates.starter.imba","Imba Starter"),thumbnail:"assets/templates/imba.svg",activeEditor:"script",markup:{language:"html",content:""},style:{language:"css",content:""},script:{language:"imba",content:` +`.trimStart()}};var W={name:"imba",title:getTemplateName("templates.starter.imba","Imba Starter"),thumbnail:"assets/templates/imba.svg",activeEditor:"script",markup:{language:"html",content:""},style:{language:"css",content:""},script:{language:"imba",content:` tag app-counter prop name = "Imba" prop count = 0 @@ -1369,7 +1369,7 @@ tag app-counter "Click me" imba.mount -`.trimStart()},stylesheets:[],scripts:[],cssPreset:"",imports:{},types:{}};var W={name:"java",title:getTemplateName("templates.starter.java","Java Starter"),thumbnail:"assets/templates/java.svg",activeEditor:"script",markup:{language:"html",content:` +`.trimStart()},stylesheets:[],scripts:[],cssPreset:"",imports:{},types:{}};var I={name:"java",title:getTemplateName("templates.starter.java","Java Starter"),thumbnail:"assets/templates/java.svg",activeEditor:"script",markup:{language:"html",content:`

Hello, World!

@@ -4177,4 +4177,4 @@ new Vue({ (i32.add (local.get $0) (i32.const 1)) ) ) -`.trimStart()},stylesheets:[],scripts:[],cssPreset:"",imports:{},types:{}};var vo=[b,D,Ut,ut,dt,Et,d,it,_t,wt,V,kt,Q,jt,xt,U,v,g,bt,Z,Y,h,G,O,A,C,ot,Lt,S,X,y,x,I,ht,gt,et,ct,pt,mt,ft,vt,N,H,nt,rt,_,j,W,T,st,F,J,Ct,L,z,yt,k,w,R,Tt,K,u,qt,St,at,lt,tt,f,E];export{vo as starterTemplates}; +`.trimStart()},stylesheets:[],scripts:[],cssPreset:"",imports:{},types:{}};var vo=[b,D,Ut,ut,dt,Et,d,it,_t,wt,V,kt,Q,jt,xt,U,v,g,bt,Z,Y,h,G,O,A,C,ot,Lt,S,X,y,x,W,ht,gt,et,ct,pt,mt,ft,vt,N,H,nt,rt,_,j,I,T,st,F,J,Ct,L,z,yt,k,w,R,Tt,K,u,qt,St,at,lt,tt,f,E];export{vo as starterTemplates}; diff --git a/scripts/build.js b/scripts/build.js index 6c7588987..adc1f1af8 100644 --- a/scripts/build.js +++ b/scripts/build.js @@ -253,6 +253,7 @@ const iifeBuild = () => 'languages/rescript/lang-rescript-formatter.ts', 'languages/riot/lang-riot-compiler.ts', 'languages/ruby-wasm/lang-ruby-wasm-script.ts', + 'languages/rune-wasm/lang-rune-wasm-script.ts', 'languages/scss/lang-scss-compiler.ts', 'languages/solid/lang-solid-compiler.ts', 'languages/sql/lang-sql-compiler.ts', diff --git a/src/livecodes/UI/command-menu-actions.ts b/src/livecodes/UI/command-menu-actions.ts index 8d7816e64..e6ed2f721 100644 --- a/src/livecodes/UI/command-menu-actions.ts +++ b/src/livecodes/UI/command-menu-actions.ts @@ -296,6 +296,7 @@ export const getCommandMenuActions = ({ 'r', 'ruby', 'ruby-wasm', + 'rune-wasm', 'go', 'go-wasm', 'php', diff --git a/src/livecodes/html/language-info.html b/src/livecodes/html/language-info.html index b14fad6a4..fb118951b 100644 --- a/src/livecodes/html/language-info.html +++ b/src/livecodes/html/language-info.html @@ -1693,6 +1693,39 @@

Ruby (WASM)

+
+

Rune

+
+ Rune is a dynamic, Rust-like programming language that compiles to WebAssembly and runs in the + browser. +
+ +

Sass

Syntactically Awesome Style Sheets.
diff --git a/src/livecodes/languages/languages.ts b/src/livecodes/languages/languages.ts index d642d7300..09e8d5429 100644 --- a/src/livecodes/languages/languages.ts +++ b/src/livecodes/languages/languages.ts @@ -63,6 +63,7 @@ import { richtext } from './richtext'; import { riot } from './riot'; import { ruby } from './ruby'; import { rubyWasm } from './ruby-wasm'; +import { runeWasm } from './rune-wasm'; import { scheme } from './scheme'; import { sass, scss } from './scss'; import { solid, solidTsx } from './solid'; @@ -143,6 +144,7 @@ export const languages: LanguageSpecs[] = [ r, ruby, rubyWasm, + runeWasm, go, goWasm, php, diff --git a/src/livecodes/languages/rune-wasm/index.ts b/src/livecodes/languages/rune-wasm/index.ts new file mode 100644 index 000000000..58f7c6c45 --- /dev/null +++ b/src/livecodes/languages/rune-wasm/index.ts @@ -0,0 +1 @@ +export * from './lang-rune-wasm'; diff --git a/src/livecodes/languages/rune-wasm/lang-rune-wasm-script.ts b/src/livecodes/languages/rune-wasm/lang-rune-wasm-script.ts new file mode 100644 index 000000000..bb2b3dcdb --- /dev/null +++ b/src/livecodes/languages/rune-wasm/lang-rune-wasm-script.ts @@ -0,0 +1,53 @@ +import { runeWasmWasmUrl } from '../../vendors'; + +const originalFetch = window.fetch; + +window.fetch = ((resource: string | Request | URL, init: RequestInit | undefined) => { + if (typeof resource === 'string' && resource.includes('/js/assets/rune_wasm-')) { + return originalFetch(runeWasmWasmUrl, { ...init, credentials: 'omit' as RequestCredentials }); + } + return originalFetch(resource, init); +}) as typeof window.fetch; + +declare const rune: { + init: () => Promise; + module: + | ({ + compile: (input: string, config: Record) => Promise; + } & Record) + | null; +}; + +livecodes.runeWasm ??= {}; + +livecodes.runeWasm.run ??= async () => { + parent.postMessage({ type: 'loading', payload: true }, '*'); + + let code = ''; + const scripts = document.querySelectorAll('script[type="text/rune"]'); + scripts.forEach((script) => (code += script.innerHTML + '\n')); + + if (!code.trim()) { + parent.postMessage({ type: 'loading', payload: false }, '*'); + return; + } + + try { + if (!rune.module) { + // eslint-disable-next-line no-console + console.log('Initializing Rune WASM environment...'); + await rune.init(); + } + + // eslint-disable-next-line no-console + console.log('Running Rune code...'); + await rune.module!.compile(code, {}); + } catch (err) { + // eslint-disable-next-line no-console + console.error(err); + } finally { + parent.postMessage({ type: 'loading', payload: false }, '*'); + } +}; + +window.addEventListener('load', () => livecodes.runeWasm.run?.()); diff --git a/src/livecodes/languages/rune-wasm/lang-rune-wasm.ts b/src/livecodes/languages/rune-wasm/lang-rune-wasm.ts new file mode 100644 index 000000000..84688f901 --- /dev/null +++ b/src/livecodes/languages/rune-wasm/lang-rune-wasm.ts @@ -0,0 +1,18 @@ +import type { LanguageSpecs } from '../../models'; +import { runeWasmUrl } from '../../vendors'; + +export const runeWasm: LanguageSpecs = { + name: 'rune-wasm', + title: 'Rune', + compiler: { + factory: () => async (code) => code, + scripts: ({ baseUrl }) => [runeWasmUrl, baseUrl + '{{hash:lang-rune-wasm-script.js}}'], + liveReload: true, + scriptType: 'text/rune', + compiledCodeLanguage: 'rune-wasm', + }, + extensions: ['rune', 'rn'], + editor: 'script', + editorLanguage: 'rust', + largeDownload: true, +}; diff --git a/src/livecodes/models.ts b/src/livecodes/models.ts index 4663bc8ad..77ca01e75 100644 --- a/src/livecodes/models.ts +++ b/src/livecodes/models.ts @@ -202,6 +202,7 @@ export interface Compiler { | 'text/prolog' | 'text/minizinc' | 'text/go-wasm' + | 'text/rune' | 'application/json' | 'application/lua' | 'text/fennel' diff --git a/src/livecodes/vendors.ts b/src/livecodes/vendors.ts index 500deb324..22e5ac95c 100644 --- a/src/livecodes/vendors.ts +++ b/src/livecodes/vendors.ts @@ -488,6 +488,14 @@ export const wabtjsUrl = /* @__PURE__ */ getUrl('wabt@1.0.35/index.js'); export const wasmoonUrl = /* @__PURE__ */ getUrl('wasmoon@1.16.0/dist/index.js'); +export const runeWasmUrl = /* @__PURE__ */ getUrl( + 'gh:rune-rs/rune-rs.github.io@797a2695/js/rune.js', +); + +export const runeWasmWasmUrl = /* @__PURE__ */ getUrl( + 'gh:rune-rs/rune-rs.github.io@797a2695/js/assets/rune_wasm-80f04f7b.wasm', +); + export const waveDromBaseUrl = /* @__PURE__ */ getUrl('wavedrom@3.2.0/'); export const webRBaseUrl = /* @__PURE__ */ getUrl('webr@0.4.0/dist/'); diff --git a/src/sdk/models.ts b/src/sdk/models.ts index 92b450275..b23215faf 100644 --- a/src/sdk/models.ts +++ b/src/sdk/models.ts @@ -145,9 +145,13 @@ export type Language = | 'r-wasm' | 'ruby' | 'rb' + | 'rust' | 'ruby-wasm' | 'wasm.rb' | 'rubywasm' + | 'rune-wasm' + | 'rune' + | 'rn' | 'go' | 'golang' | 'go-wasm' @@ -386,6 +390,7 @@ export type TemplateName = | 'r' | 'ruby' | 'ruby-wasm' + | 'rune-wasm' | 'go' | 'go-wasm' | 'php' From d03f86eb36c024112902f201ca774cc7fb05c8de Mon Sep 17 00:00:00 2001 From: "pullfrog[bot]" <226033991+pullfrog[bot]@users.noreply.github.com> Date: Tue, 9 Jun 2026 12:12:46 +0000 Subject: [PATCH 02/13] chore(i18n): add Rune WASM i18n keys --- .../i18n/locales/en/language-info.lokalise.json | 12 ++++++++++++ src/livecodes/i18n/locales/en/language-info.ts | 5 +++++ 2 files changed, 17 insertions(+) diff --git a/src/livecodes/i18n/locales/en/language-info.lokalise.json b/src/livecodes/i18n/locales/en/language-info.lokalise.json index 71bcdf6d6..f299e4848 100644 --- a/src/livecodes/i18n/locales/en/language-info.lokalise.json +++ b/src/livecodes/i18n/locales/en/language-info.lokalise.json @@ -808,6 +808,18 @@ "notes": "", "translation": "Ruby (WASM)" }, + "runeWasm.desc": { + "notes": "", + "translation": "Rune is a dynamic, Rust-like programming language that compiles to WebAssembly and runs in the browser." + }, + "runeWasm.link": { + "notes": "### ###\n
  • \n\n### ###\n\n\n### ###\n
  • \n\n### ###\n\n\n### ###\n
  • \n\n### ###\n\n\n### ###\n
  • \n\n### ###\n\n\n### ###\n
  • \n\n### ###\n\n\n### ###\n
  • \n\n### ###\n\n\n", + "translation": " Rune official website Rune documentation Rune playground GitHub repository LiveCodes Documentations Load starter template " + }, + "runeWasm.name": { + "notes": "", + "translation": "Rune" + }, "sass.desc": { "notes": "", "translation": "Syntactically Awesome Style Sheets." diff --git a/src/livecodes/i18n/locales/en/language-info.ts b/src/livecodes/i18n/locales/en/language-info.ts index 43eda14e0..4033c9421 100644 --- a/src/livecodes/i18n/locales/en/language-info.ts +++ b/src/livecodes/i18n/locales/en/language-info.ts @@ -348,6 +348,11 @@ const languageInfo = { link: '<1> <2>Ruby official website <3> <4>Ruby documentation <5> <6>ruby.wasm website <7><8>CRuby <9> <10>Learn X in Y minutes, where X=ruby <11> <12>LiveCodes Documentations <13> <14>Load starter template ', name: 'Ruby (WASM)', }, + runeWasm: { + desc: 'Rune is a dynamic, Rust-like programming language that compiles to WebAssembly and runs in the browser.', + link: '<1> <2>Rune official website <3> <4>Rune documentation <5> <6>Rune playground <7> <8>GitHub repository <9> <10>LiveCodes Documentations <11> <12>Load starter template ', + name: 'Rune', + }, sass: { desc: 'Syntactically Awesome Style Sheets.', link: '<1> <2>Sass official website <3> <4>Sass documentation <5> <6>Sass (the indented) syntax <7> <8>Learn X in Y minutes, where X=sass ', From baa413e545efadf47bdb2459f8700f71deb31df6 Mon Sep 17 00:00:00 2001 From: "pullfrog[bot]" <226033991+pullfrog[bot]@users.noreply.github.com> Date: Tue, 9 Jun 2026 12:24:25 +0000 Subject: [PATCH 03/13] fix(i18n): add missing runeWasm keys to all locale files --- src/livecodes/i18n/locales/ar/language-info.ts | 5 +++++ src/livecodes/i18n/locales/bn/language-info.ts | 5 +++++ src/livecodes/i18n/locales/de/language-info.ts | 5 +++++ src/livecodes/i18n/locales/es/language-info.ts | 5 +++++ src/livecodes/i18n/locales/fa/language-info.ts | 5 +++++ src/livecodes/i18n/locales/fr/language-info.ts | 5 +++++ src/livecodes/i18n/locales/hi/language-info.ts | 5 +++++ src/livecodes/i18n/locales/hu/language-info.ts | 5 +++++ src/livecodes/i18n/locales/id/language-info.ts | 5 +++++ src/livecodes/i18n/locales/it/language-info.ts | 5 +++++ src/livecodes/i18n/locales/ja/language-info.ts | 5 +++++ src/livecodes/i18n/locales/nl/language-info.ts | 5 +++++ src/livecodes/i18n/locales/pt/language-info.ts | 5 +++++ src/livecodes/i18n/locales/ru/language-info.ts | 5 +++++ src/livecodes/i18n/locales/tr/language-info.ts | 5 +++++ src/livecodes/i18n/locales/ur/language-info.ts | 5 +++++ src/livecodes/i18n/locales/zh-CN/language-info.ts | 5 +++++ 17 files changed, 85 insertions(+) diff --git a/src/livecodes/i18n/locales/ar/language-info.ts b/src/livecodes/i18n/locales/ar/language-info.ts index 1d04eb152..e984fadc1 100644 --- a/src/livecodes/i18n/locales/ar/language-info.ts +++ b/src/livecodes/i18n/locales/ar/language-info.ts @@ -338,6 +338,11 @@ const languageInfo: I18nLangInfoTranslation = { link: '<1> <2>الموقع الرسمي لروبي <3> <4>وثائق روبي <5> <6>موقع ruby.wasm <7><8>CRuby <9> <10>تعلم X في Y دقيقة، حيث X=ruby <11> <12>وثائق LiveCodes <13> <14>تحميل قالب البداية ', name: 'Ruby (WASM)', }, + runeWasm: { + desc: 'Rune is a dynamic, Rust-like programming language that compiles to WebAssembly and runs in the browser.', + link: '<1> <2>Rune official website <3> <4>Rune documentation <5> <6>Rune playground <7> <8>GitHub repository <9> <10>LiveCodes Documentations <11> <12>Load starter template ', + name: 'Rune', + }, sass: { desc: 'أوراق الأنماط الرائعة نحويًا.', link: '<1> <2>الموقع الرسمي لـ Sass <3> <4>وثائق Sass <5> <6>بناء جملة Sass (المسافة البادئة) <7> <8>تعلم X في Y دقيقة، حيث X=sass ', diff --git a/src/livecodes/i18n/locales/bn/language-info.ts b/src/livecodes/i18n/locales/bn/language-info.ts index 8b3ffd9cd..925c9280b 100644 --- a/src/livecodes/i18n/locales/bn/language-info.ts +++ b/src/livecodes/i18n/locales/bn/language-info.ts @@ -340,6 +340,11 @@ const languageInfo: I18nLangInfoTranslation = { link: '<1> <2>Ruby অফিসিয়াল ওয়েবসাইট <3> <4>Ruby ডকুমেন্টেশন <5> <6>ruby.wasm ওয়েবসাইট <7><8>CRuby <9> <10>Y মিনিটে X শিখুন, যেখানে X=ruby <11> <12>LiveCodes ডকুমেন্টেশন <13> <14>স্টার্টার টেমপ্লেট লোড করুন ', name: 'Ruby (WASM)', }, + runeWasm: { + desc: 'Rune is a dynamic, Rust-like programming language that compiles to WebAssembly and runs in the browser.', + link: '<1> <2>Rune official website <3> <4>Rune documentation <5> <6>Rune playground <7> <8>GitHub repository <9> <10>LiveCodes Documentations <11> <12>Load starter template ', + name: 'Rune', + }, sass: { desc: 'সিনট্যাক্টিক্যালি অসাধারণ স্টাইল শীট।', link: '<1> <2>Sass অফিসিয়াল ওয়েবসাইট <3> <4>Sass ডকুমেন্টেশন <5> <6>Sass (ইন্ডেন্টেড) সিনট্যাক্স <7> <8>Y মিনিটে X শিখুন, যেখানে X=sass ', diff --git a/src/livecodes/i18n/locales/de/language-info.ts b/src/livecodes/i18n/locales/de/language-info.ts index 758274f00..4f82f35bb 100644 --- a/src/livecodes/i18n/locales/de/language-info.ts +++ b/src/livecodes/i18n/locales/de/language-info.ts @@ -342,6 +342,11 @@ const languageInfo: I18nLangInfoTranslation = { link: '<1> <2>Ruby offizielle Website <3> <4>Ruby Dokumentation <5> <6>ruby.wasm Website <7><8>CRuby <9> <10>Lerne X in Y Minuten, wobei X=Ruby <11> <12>LiveCodes Dokumentation <13> <14>Starter-Vorlage laden ', name: 'Ruby (WASM)', }, + runeWasm: { + desc: 'Rune is a dynamic, Rust-like programming language that compiles to WebAssembly and runs in the browser.', + link: '<1> <2>Rune official website <3> <4>Rune documentation <5> <6>Rune playground <7> <8>GitHub repository <9> <10>LiveCodes Documentations <11> <12>Load starter template ', + name: 'Rune', + }, sass: { desc: 'Syntaktisch Awesome Style Sheets.', link: '<1> <2>Sass offizielle Website <3> <4>Sass Dokumentation <5> <6>Sass (die eingerückte) Syntax <7> <8>Lerne X in Y Minuten, wobei X=Sass ', diff --git a/src/livecodes/i18n/locales/es/language-info.ts b/src/livecodes/i18n/locales/es/language-info.ts index c63b0be78..fbb0bc34d 100644 --- a/src/livecodes/i18n/locales/es/language-info.ts +++ b/src/livecodes/i18n/locales/es/language-info.ts @@ -342,6 +342,11 @@ const languageInfo: I18nLangInfoTranslation = { link: '<1> <2>Sitio web oficial de Ruby <3> <4>Documentación de Ruby <5> <6>Sitio web de ruby.wasm <7><8>CRuby <9> <10>Aprende X en Y minutos, donde X=ruby <11> <12>Documentación de LiveCodes <13> <14>Cargar plantilla inicial ', name: 'Ruby (WASM)', }, + runeWasm: { + desc: 'Rune is a dynamic, Rust-like programming language that compiles to WebAssembly and runs in the browser.', + link: '<1> <2>Rune official website <3> <4>Rune documentation <5> <6>Rune playground <7> <8>GitHub repository <9> <10>LiveCodes Documentations <11> <12>Load starter template ', + name: 'Rune', + }, sass: { desc: 'Hojas de Estilo Sintácticamente Impresionantes.', link: '<1> <2>Sitio web oficial de Sass <3> <4>Documentación de Sass <5> <6>Sintaxis de Sass (con indentación) <7> <8>Aprende X en Y minutos, donde X=sass ', diff --git a/src/livecodes/i18n/locales/fa/language-info.ts b/src/livecodes/i18n/locales/fa/language-info.ts index 9341fe6a1..bc6b9a3e7 100644 --- a/src/livecodes/i18n/locales/fa/language-info.ts +++ b/src/livecodes/i18n/locales/fa/language-info.ts @@ -341,6 +341,11 @@ const languageInfo: I18nLangInfoTranslation = { link: '<1> <2>وب‌سایت رسمی Ruby <3> <4>مستندات Ruby <5> <6>وب‌سایت ruby.wasm <7><8>CRuby <9> <10>یادگیری X در Y دقیقه، جایی که X=ruby <11> <12>مستندات LiveCodes <13> <14>بارگذاری قالب شروع کننده ', name: 'Ruby (WASM)', }, + runeWasm: { + desc: 'Rune is a dynamic, Rust-like programming language that compiles to WebAssembly and runs in the browser.', + link: '<1> <2>Rune official website <3> <4>Rune documentation <5> <6>Rune playground <7> <8>GitHub repository <9> <10>LiveCodes Documentations <11> <12>Load starter template ', + name: 'Rune', + }, sass: { desc: 'شیوه‌نامه‌های شگفت انگیز از نظر نحوی.', link: '<1> <2>وب‌سایت رسمی Sass <3> <4>مستندات Sass <5> <6>نحو Sass (نحو تو رفته) <7> <8>یادگیری X در Y دقیقه، جایی که X=sass ', diff --git a/src/livecodes/i18n/locales/fr/language-info.ts b/src/livecodes/i18n/locales/fr/language-info.ts index da7650f6b..1bd7ca95c 100644 --- a/src/livecodes/i18n/locales/fr/language-info.ts +++ b/src/livecodes/i18n/locales/fr/language-info.ts @@ -342,6 +342,11 @@ const languageInfo: I18nLangInfoTranslation = { link: '<1> <2>Site officiel de Ruby <3> <4>Documentation Ruby <5> <6>Site web de ruby.wasm <7><8>CRuby <9> <10>Apprenez X en Y minutes, où X=ruby <11> <12>Documentation LiveCodes <13> <14>Charger le modèle de démarrage ', name: 'Ruby (WASM)', }, + runeWasm: { + desc: 'Rune is a dynamic, Rust-like programming language that compiles to WebAssembly and runs in the browser.', + link: '<1> <2>Rune official website <3> <4>Rune documentation <5> <6>Rune playground <7> <8>GitHub repository <9> <10>LiveCodes Documentations <11> <12>Load starter template ', + name: 'Rune', + }, sass: { desc: 'Feuilles de style syntaxiquement impressionnantes.', link: '<1> <2>Site officiel de Sass <3> <4>Documentation Sass <5> <6>Syntaxe Sass (indentée) <7> <8>Apprenez X en Y minutes, où X=sass ', diff --git a/src/livecodes/i18n/locales/hi/language-info.ts b/src/livecodes/i18n/locales/hi/language-info.ts index 8c19c1929..a148342bc 100644 --- a/src/livecodes/i18n/locales/hi/language-info.ts +++ b/src/livecodes/i18n/locales/hi/language-info.ts @@ -343,6 +343,11 @@ const languageInfo: I18nLangInfoTranslation = { link: '<1> <2>Ruby की आधिकारिक वेबसाइट <3> <4>Ruby दस्तावेज़ीकरण <5> <6>ruby.wasm वेबसाइट <7><8>CRuby <9> <10>X को Y मिनट में सीखें, जहां X=ruby <11> <12>LiveCodes दस्तावेज़ीकरण <13> <14>स्टार्टर टेम्पलेट लोड करें ', name: 'Ruby (WASM)', }, + runeWasm: { + desc: 'Rune is a dynamic, Rust-like programming language that compiles to WebAssembly and runs in the browser.', + link: '<1> <2>Rune official website <3> <4>Rune documentation <5> <6>Rune playground <7> <8>GitHub repository <9> <10>LiveCodes Documentations <11> <12>Load starter template ', + name: 'Rune', + }, sass: { desc: 'वाक्यरचनात्मक रूप से अद्भुत स्टाइल शीट्स।', link: '<1> <2>Sass की आधिकारिक वेबसाइट <3> <4>Sass दस्तावेज़ीकरण <5> <6>Sass (इंडेंटेड) वाक्यरचना <7> <8>X को Y मिनट में सीखें, जहां X=sass ', diff --git a/src/livecodes/i18n/locales/hu/language-info.ts b/src/livecodes/i18n/locales/hu/language-info.ts index d4e750dc1..29a7e4127 100644 --- a/src/livecodes/i18n/locales/hu/language-info.ts +++ b/src/livecodes/i18n/locales/hu/language-info.ts @@ -342,6 +342,11 @@ const languageInfo: I18nLangInfoTranslation = { link: '<1> <2>Ruby hivatalos weboldal <3> <4>Ruby dokumentáció <5> <6>ruby.wasm weboldal <7><8>CRuby <9> <10>Tanulj X-et Y perc alatt, ahol X=ruby <11> <12>LiveCodes dokumentáció <13> <14>Kezdő sablon betöltése ', name: 'Ruby (WASM)', }, + runeWasm: { + desc: 'Rune is a dynamic, Rust-like programming language that compiles to WebAssembly and runs in the browser.', + link: '<1> <2>Rune official website <3> <4>Rune documentation <5> <6>Rune playground <7> <8>GitHub repository <9> <10>LiveCodes Documentations <11> <12>Load starter template ', + name: 'Rune', + }, sass: { desc: 'Szintaktikusan Fantasztikus Stíluslapok.', link: '<1> <2>Sass hivatalos weboldal <3> <4>Sass dokumentáció <5> <6>Sass (a behúzott) szintaxis <7> <8>Tanulj X-et Y perc alatt, ahol X=sass ', diff --git a/src/livecodes/i18n/locales/id/language-info.ts b/src/livecodes/i18n/locales/id/language-info.ts index 08e0fccb9..c5a701b4f 100644 --- a/src/livecodes/i18n/locales/id/language-info.ts +++ b/src/livecodes/i18n/locales/id/language-info.ts @@ -342,6 +342,11 @@ const languageInfo: I18nLangInfoTranslation = { link: '<1> <2>Situs web resmi Ruby <3> <4>Dokumentasi Ruby <5> <6>Situs web ruby.wasm <7><8>CRuby <9> <10>Pelajari X dalam Y menit, dengan X=ruby <11> <12>Dokumentasi LiveCodes <13> <14>Muat template pemula ', name: 'Ruby (WASM)', }, + runeWasm: { + desc: 'Rune is a dynamic, Rust-like programming language that compiles to WebAssembly and runs in the browser.', + link: '<1> <2>Rune official website <3> <4>Rune documentation <5> <6>Rune playground <7> <8>GitHub repository <9> <10>LiveCodes Documentations <11> <12>Load starter template ', + name: 'Rune', + }, sass: { desc: 'Syntactically Awesome Style Sheets.', link: '<1> <2>Situs web resmi Sass <3> <4>Dokumentasi Sass <5> <6>Sintaks Sass (yang berindentasi) <7> <8>Pelajari X dalam Y menit, dengan X=sass ', diff --git a/src/livecodes/i18n/locales/it/language-info.ts b/src/livecodes/i18n/locales/it/language-info.ts index c54b618bc..473c5bc35 100644 --- a/src/livecodes/i18n/locales/it/language-info.ts +++ b/src/livecodes/i18n/locales/it/language-info.ts @@ -341,6 +341,11 @@ const languageInfo: I18nLangInfoTranslation = { link: '<1> <2>Sito ufficiale di Ruby <3> <4>Documentazione di Ruby <5> <6>Sito web di ruby.wasm <7><8>CRuby <9> <10>Impara X in Y minuti, dove X=ruby <11> <12>Documentazione LiveCodes <13> <14>Carica modello di partenza ', name: 'Ruby (WASM)', }, + runeWasm: { + desc: 'Rune is a dynamic, Rust-like programming language that compiles to WebAssembly and runs in the browser.', + link: '<1> <2>Rune official website <3> <4>Rune documentation <5> <6>Rune playground <7> <8>GitHub repository <9> <10>LiveCodes Documentations <11> <12>Load starter template ', + name: 'Rune', + }, sass: { desc: 'Fogli di stile sintatticamente fantastici.', link: '<1> <2>Sito ufficiale di Sass <3> <4>Documentazione di Sass <5> <6>Sintassi Sass (indentata) <7> <8>Impara X in Y minuti, dove X=sass ', diff --git a/src/livecodes/i18n/locales/ja/language-info.ts b/src/livecodes/i18n/locales/ja/language-info.ts index 7f6bb3743..f1fd6c4f0 100644 --- a/src/livecodes/i18n/locales/ja/language-info.ts +++ b/src/livecodes/i18n/locales/ja/language-info.ts @@ -342,6 +342,11 @@ const languageInfo: I18nLangInfoTranslation = { link: '<1> <2>Ruby公式ウェブサイト <3> <4>Rubyドキュメント <5> <6>ruby.wasmウェブサイト <7><8>CRuby <9> <10>X分でわかるRuby(X in Y minutes) <11> <12>LiveCodesドキュメント <13> <14>スターターテンプレートを読み込む ', name: 'Ruby(WASM)', }, + runeWasm: { + desc: 'Rune is a dynamic, Rust-like programming language that compiles to WebAssembly and runs in the browser.', + link: '<1> <2>Rune official website <3> <4>Rune documentation <5> <6>Rune playground <7> <8>GitHub repository <9> <10>LiveCodes Documentations <11> <12>Load starter template ', + name: 'Rune', + }, sass: { desc: '構文的にすばらしいスタイルシート。', link: '<1> <2>Sass公式ウェブサイト <3> <4>Sassドキュメント <5> <6>Sass(インデント)構文 <7> <8>X分でわかるSass(X in Y minutes) ', diff --git a/src/livecodes/i18n/locales/nl/language-info.ts b/src/livecodes/i18n/locales/nl/language-info.ts index fa2f2eecb..dbb2acd5d 100644 --- a/src/livecodes/i18n/locales/nl/language-info.ts +++ b/src/livecodes/i18n/locales/nl/language-info.ts @@ -341,6 +341,11 @@ const languageInfo: I18nLangInfoTranslation = { link: '<1> <2>Ruby officiële website <3> <4>Ruby documentatie <5> <6>ruby.wasm website <7><8>CRuby <9> <10>Leer X in Y minuten, waarbij X=ruby <11> <12>LiveCodes Documentatie <13> <14>Startsjabloon laden ', name: 'Ruby (WASM)', }, + runeWasm: { + desc: 'Rune is a dynamic, Rust-like programming language that compiles to WebAssembly and runs in the browser.', + link: '<1> <2>Rune official website <3> <4>Rune documentation <5> <6>Rune playground <7> <8>GitHub repository <9> <10>LiveCodes Documentations <11> <12>Load starter template ', + name: 'Rune', + }, sass: { desc: 'Syntactisch geweldige stylesheets.', link: '<1> <2>Sass officiële website <3> <4>Sass documentatie <5> <6>Sass (de ingesprongen) syntaxis <7> <8>Leer X in Y minuten, waarbij X=sass ', diff --git a/src/livecodes/i18n/locales/pt/language-info.ts b/src/livecodes/i18n/locales/pt/language-info.ts index ceedba9d8..66d3af29d 100644 --- a/src/livecodes/i18n/locales/pt/language-info.ts +++ b/src/livecodes/i18n/locales/pt/language-info.ts @@ -341,6 +341,11 @@ const languageInfo: I18nLangInfoTranslation = { link: '<1> <2>Site oficial do Ruby <3> <4>Documentação do Ruby <5> <6>Site do ruby.wasm <7><8>CRuby <9> <10>Aprenda X em Y minutos, onde X=ruby <11> <12>Documentação do LiveCodes <13> <14>Carregar modelo inicial ', name: 'Ruby (WASM)', }, + runeWasm: { + desc: 'Rune is a dynamic, Rust-like programming language that compiles to WebAssembly and runs in the browser.', + link: '<1> <2>Rune official website <3> <4>Rune documentation <5> <6>Rune playground <7> <8>GitHub repository <9> <10>LiveCodes Documentations <11> <12>Load starter template ', + name: 'Rune', + }, sass: { desc: 'Folhas de Estilo Sintaticamente Incríveis.', link: '<1> <2>Site oficial do Sass <3> <4>Documentação do Sass <5> <6>Sintaxe indentada do Sass <7> <8>Aprenda X em Y minutos, onde X=sass ', diff --git a/src/livecodes/i18n/locales/ru/language-info.ts b/src/livecodes/i18n/locales/ru/language-info.ts index 6dfe25079..09271794c 100644 --- a/src/livecodes/i18n/locales/ru/language-info.ts +++ b/src/livecodes/i18n/locales/ru/language-info.ts @@ -343,6 +343,11 @@ const languageInfo: I18nLangInfoTranslation = { link: '<1> <2>Официальный сайт Ruby <3> <4>Документация Ruby <5> <6>Сайт ruby.wasm <7><8>CRuby <9> <10>Изучите X за Y минут, где X=ruby <11> <12>Документация LiveCodes <13> <14>Загрузить стартовый шаблон ', name: 'Ruby (WASM)', }, + runeWasm: { + desc: 'Rune is a dynamic, Rust-like programming language that compiles to WebAssembly and runs in the browser.', + link: '<1> <2>Rune official website <3> <4>Rune documentation <5> <6>Rune playground <7> <8>GitHub repository <9> <10>LiveCodes Documentations <11> <12>Load starter template ', + name: 'Rune', + }, sass: { desc: 'Синтаксически удивительные таблицы стилей.', link: '<1> <2>Официальный сайт Sass <3> <4>Документация Sass <5> <6>Синтаксис Sass (с отступами) <7> <8>Изучите X за Y минут, где X=sass ', diff --git a/src/livecodes/i18n/locales/tr/language-info.ts b/src/livecodes/i18n/locales/tr/language-info.ts index 21b5ee04e..d65fee450 100644 --- a/src/livecodes/i18n/locales/tr/language-info.ts +++ b/src/livecodes/i18n/locales/tr/language-info.ts @@ -342,6 +342,11 @@ const languageInfo: I18nLangInfoTranslation = { link: '<1> <2>Ruby resmi web sitesi <3> <4>Ruby dokümantasyonu <5> <6>ruby.wasm web sitesi <7><8>CRuby <9> <10>Y Dakikada X Öğrenin, X=ruby <11> <12>LiveCodes Dokümantasyonu <13> <14>Başlangıç şablonunu yükle ', name: 'Ruby (WASM)', }, + runeWasm: { + desc: 'Rune is a dynamic, Rust-like programming language that compiles to WebAssembly and runs in the browser.', + link: '<1> <2>Rune official website <3> <4>Rune documentation <5> <6>Rune playground <7> <8>GitHub repository <9> <10>LiveCodes Documentations <11> <12>Load starter template ', + name: 'Rune', + }, sass: { desc: 'Sözdizimsel Olarak Harika Stil Sayfaları.', link: '<1> <2>Sass resmi web sitesi <3> <4>Sass dokümantasyonu <5> <6>Sass (girintili) sözdizimi <7> <8>Y Dakikada X Öğrenin, X=sass ', diff --git a/src/livecodes/i18n/locales/ur/language-info.ts b/src/livecodes/i18n/locales/ur/language-info.ts index 58d0352ca..b34d3cebb 100644 --- a/src/livecodes/i18n/locales/ur/language-info.ts +++ b/src/livecodes/i18n/locales/ur/language-info.ts @@ -344,6 +344,11 @@ const languageInfo: I18nLangInfoTranslation = { link: '<1> <2>روبی کی سرکاری ویب سائٹ <3> <4>روبی دستاویزات <5> <6>روبی.ڈبلیو اے ایس ایم ویب سائٹ <7><8>سی روبی <9> <10>X کو Y منٹ میں سیکھیں، جہاں X=روبی <11> <12>لائیو کوڈز دستاویزات <13> <14>ابتدائی سانچہ لوڈ کریں ', name: 'روبی (ڈبلیو اے ایس ایم)', }, + runeWasm: { + desc: 'Rune is a dynamic, Rust-like programming language that compiles to WebAssembly and runs in the browser.', + link: '<1> <2>Rune official website <3> <4>Rune documentation <5> <6>Rune playground <7> <8>GitHub repository <9> <10>LiveCodes Documentations <11> <12>Load starter template ', + name: 'Rune', + }, sass: { desc: 'نحوی طور پر شاندار اسٹائل شیٹس۔', link: '<1> <2>ساس کی سرکاری ویب سائٹ <3> <4>ساس دستاویزات <5> <6>ساس (انڈینٹڈ) نحو <7> <8>X کو Y منٹ میں سیکھیں، جہاں X=ساس ', diff --git a/src/livecodes/i18n/locales/zh-CN/language-info.ts b/src/livecodes/i18n/locales/zh-CN/language-info.ts index 2964f4e86..7b64665ad 100644 --- a/src/livecodes/i18n/locales/zh-CN/language-info.ts +++ b/src/livecodes/i18n/locales/zh-CN/language-info.ts @@ -336,6 +336,11 @@ const languageInfo: I18nLangInfoTranslation = { link: '<1> <2>Ruby 官方网站 <3> <4>Ruby 文档 <5> <6>ruby.wasm 网站 <7><8>CRuby <9> <10>在 Y 分钟内学习 X,其中 X=ruby <11> <12>LiveCodes 文档 <13> <14>加载启动模板 ', name: 'Ruby(WASM)', }, + runeWasm: { + desc: 'Rune is a dynamic, Rust-like programming language that compiles to WebAssembly and runs in the browser.', + link: '<1> <2>Rune official website <3> <4>Rune documentation <5> <6>Rune playground <7> <8>GitHub repository <9> <10>LiveCodes Documentations <11> <12>Load starter template ', + name: 'Rune', + }, sass: { desc: '语法超赞的样式表。', link: '<1> <2>Sass 官方网站 <3> <4>Sass 文档 <5> <6>Sass(缩进)语法 <7> <8>在 Y 分钟内学习 X,其中 X=sass ', From b2fd1b38cd0eab9a24ed9ae5ffe85bf09350d2c4 Mon Sep 17 00:00:00 2001 From: "pullfrog[bot]" <226033991+pullfrog[bot]@users.noreply.github.com> Date: Tue, 9 Jun 2026 18:55:57 +0000 Subject: [PATCH 04/13] fix(rune-wasm): add loading guard to prevent concurrent init race With liveReload: true, multiple calls to run() can trigger concurrent rune.init() calls, causing rune.module to remain null and the compile call to fail with "Cannot read properties of null (reading 'compile')". Add a shared initPromise to serialize initialization, and use a stricter check (typeof rune.module?.compile !== 'function') instead of !rune.module to properly verify the module is ready. --- .../languages/rune-wasm/lang-rune-wasm-script.ts | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/livecodes/languages/rune-wasm/lang-rune-wasm-script.ts b/src/livecodes/languages/rune-wasm/lang-rune-wasm-script.ts index bb2b3dcdb..22ff2fd50 100644 --- a/src/livecodes/languages/rune-wasm/lang-rune-wasm-script.ts +++ b/src/livecodes/languages/rune-wasm/lang-rune-wasm-script.ts @@ -19,6 +19,7 @@ declare const rune: { }; livecodes.runeWasm ??= {}; +let initPromise: Promise | null = null; livecodes.runeWasm.run ??= async () => { parent.postMessage({ type: 'loading', payload: true }, '*'); @@ -33,10 +34,16 @@ livecodes.runeWasm.run ??= async () => { } try { - if (!rune.module) { - // eslint-disable-next-line no-console - console.log('Initializing Rune WASM environment...'); - await rune.init(); + if (typeof rune.module?.compile !== 'function') { + if (!initPromise) { + // eslint-disable-next-line no-console + console.log('Initializing Rune WASM environment...'); + initPromise = rune.init(); + } + await initPromise; + if (typeof rune.module?.compile !== 'function') { + throw new Error('Failed to initialize Rune WASM environment'); + } } // eslint-disable-next-line no-console From e6253d9b446a7103eb951eb9c0782f4f5f7148b3 Mon Sep 17 00:00:00 2001 From: "pullfrog[bot]" <226033991+pullfrog[bot]@users.noreply.github.com> Date: Tue, 9 Jun 2026 20:31:14 +0000 Subject: [PATCH 05/13] feat(rune-wasm): capture output, exit code, and errors --- .../rune-wasm/lang-rune-wasm-script.ts | 88 +++++++++++++------ 1 file changed, 63 insertions(+), 25 deletions(-) diff --git a/src/livecodes/languages/rune-wasm/lang-rune-wasm-script.ts b/src/livecodes/languages/rune-wasm/lang-rune-wasm-script.ts index 22ff2fd50..f90d47187 100644 --- a/src/livecodes/languages/rune-wasm/lang-rune-wasm-script.ts +++ b/src/livecodes/languages/rune-wasm/lang-rune-wasm-script.ts @@ -1,3 +1,4 @@ +/* eslint-disable no-console */ import { runeWasmWasmUrl } from '../../vendors'; const originalFetch = window.fetch; @@ -21,40 +22,77 @@ declare const rune: { livecodes.runeWasm ??= {}; let initPromise: Promise | null = null; -livecodes.runeWasm.run ??= async () => { +const init = async () => { + if (typeof rune.module?.compile === 'function') return; + if (!initPromise) { + console.log('Initializing Rune WASM environment...'); + initPromise = rune.init(); + } + await initPromise; + if (typeof rune.module?.compile !== 'function') { + throw new Error('Failed to initialize Rune WASM environment'); + } + console.log('Rune WASM environment initialized successfully'); +}; + +const runCode = async ( + code: string, +): Promise<{ output: string | null; error: string | null; exitCode: number }> => { + try { + console.log('Running Rune code...'); + const result = await rune.module!.compile(code, {}); + const output = result != null ? String(result) : ''; + return { output, error: null, exitCode: 0 }; + } catch (err) { + const error = (err as Error).message ?? String(err); + return { output: null, error, exitCode: (err as any).code ?? 1 }; + } +}; + +livecodes.runeWasm.run ??= async (input?: string) => { parent.postMessage({ type: 'loading', payload: true }, '*'); let code = ''; + livecodes.runeWasm.input = input; + livecodes.runeWasm.output = null; + livecodes.runeWasm.ready = false; const scripts = document.querySelectorAll('script[type="text/rune"]'); scripts.forEach((script) => (code += script.innerHTML + '\n')); - if (!code.trim()) { - parent.postMessage({ type: 'loading', payload: false }, '*'); - return; + const { output, error, exitCode } = !code.trim() + ? { output: null, error: null, exitCode: 0 } + : await (async () => { + try { + await init(); + return await runCode(code); + } catch (err) { + const error = (err as Error).message ?? String(err); + return { output: null, error, exitCode: 1 }; + } + })(); + + if (error != null) { + console.error(error); + } else if (output != null) { + console.log(output); } - try { - if (typeof rune.module?.compile !== 'function') { - if (!initPromise) { - // eslint-disable-next-line no-console - console.log('Initializing Rune WASM environment...'); - initPromise = rune.init(); - } - await initPromise; - if (typeof rune.module?.compile !== 'function') { - throw new Error('Failed to initialize Rune WASM environment'); - } - } + livecodes.runeWasm.input = input; + livecodes.runeWasm.output = output; + livecodes.runeWasm.error = error; + livecodes.runeWasm.exitCode = exitCode; + livecodes.runeWasm.ready = true; - // eslint-disable-next-line no-console - console.log('Running Rune code...'); - await rune.module!.compile(code, {}); - } catch (err) { - // eslint-disable-next-line no-console - console.error(err); - } finally { - parent.postMessage({ type: 'loading', payload: false }, '*'); - } + parent.postMessage({ type: 'loading', payload: false }, '*'); }; +livecodes.runeWasm.loaded = new Promise((resolve) => { + const interval = setInterval(() => { + if (livecodes.runeWasm.ready) { + clearInterval(interval); + resolve(); + } + }, 50); +}); + window.addEventListener('load', () => livecodes.runeWasm.run?.()); From b85a6731707905cf25bff8d303bc1bc8a4c1e421 Mon Sep 17 00:00:00 2001 From: "pullfrog[bot]" <226033991+pullfrog[bot]@users.noreply.github.com> Date: Tue, 9 Jun 2026 20:53:23 +0000 Subject: [PATCH 06/13] feat(templates): add Rune WASM starter template --- src/livecodes/assets/templates/rune.svg | 10 +++ src/livecodes/i18n/locales/ar/translation.ts | 1 + src/livecodes/i18n/locales/bn/translation.ts | 1 + src/livecodes/i18n/locales/de/translation.ts | 1 + .../i18n/locales/en/translation.lokalise.json | 4 ++ src/livecodes/i18n/locales/en/translation.ts | 1 + src/livecodes/i18n/locales/es/translation.ts | 1 + src/livecodes/i18n/locales/fa/translation.ts | 1 + src/livecodes/i18n/locales/fr/translation.ts | 1 + src/livecodes/i18n/locales/hi/translation.ts | 1 + src/livecodes/i18n/locales/hu/translation.ts | 1 + src/livecodes/i18n/locales/id/translation.ts | 1 + src/livecodes/i18n/locales/it/translation.ts | 1 + src/livecodes/i18n/locales/ja/translation.ts | 1 + src/livecodes/i18n/locales/nl/translation.ts | 1 + src/livecodes/i18n/locales/pt/translation.ts | 1 + src/livecodes/i18n/locales/ru/translation.ts | 1 + src/livecodes/i18n/locales/tr/translation.ts | 1 + src/livecodes/i18n/locales/ur/translation.ts | 1 + .../i18n/locales/zh-CN/translation.ts | 1 + src/livecodes/models.ts | 2 + src/livecodes/templates/starter/index.ts | 2 + .../templates/starter/rune-wasm-starter.ts | 70 +++++++++++++++++++ storybook/solid/src/solid.ts | 2 +- 24 files changed, 107 insertions(+), 1 deletion(-) create mode 100644 src/livecodes/assets/templates/rune.svg create mode 100644 src/livecodes/templates/starter/rune-wasm-starter.ts diff --git a/src/livecodes/assets/templates/rune.svg b/src/livecodes/assets/templates/rune.svg new file mode 100644 index 000000000..08c2fdb13 --- /dev/null +++ b/src/livecodes/assets/templates/rune.svg @@ -0,0 +1,10 @@ + + + + + + + + + R + diff --git a/src/livecodes/i18n/locales/ar/translation.ts b/src/livecodes/i18n/locales/ar/translation.ts index c6073f210..7da223682 100644 --- a/src/livecodes/i18n/locales/ar/translation.ts +++ b/src/livecodes/i18n/locales/ar/translation.ts @@ -1033,6 +1033,7 @@ const translation: I18nTranslation = { riot: 'قالب Riot.js', ruby: 'قالب Ruby', 'ruby-wasm': 'قالب Ruby-Wasm', + 'rune-wasm': 'Rune Starter', scheme: 'قالب Scheme', shadcnui: 'قالب shadcn/ui', solid: 'قالب Solid', diff --git a/src/livecodes/i18n/locales/bn/translation.ts b/src/livecodes/i18n/locales/bn/translation.ts index c3b822b7e..fce7b4094 100644 --- a/src/livecodes/i18n/locales/bn/translation.ts +++ b/src/livecodes/i18n/locales/bn/translation.ts @@ -1033,6 +1033,7 @@ const translation: I18nTranslation = { riot: 'Riot.js স্টার্টার', ruby: 'Ruby স্টার্টার', 'ruby-wasm': 'Ruby (Wasm) স্টার্টার', + 'rune-wasm': 'Rune Starter', scheme: 'Scheme স্টার্টার', shadcnui: 'shadcn/ui স্টার্টার', solid: 'Solid স্টার্টার', diff --git a/src/livecodes/i18n/locales/de/translation.ts b/src/livecodes/i18n/locales/de/translation.ts index c2737a760..89b363f8f 100644 --- a/src/livecodes/i18n/locales/de/translation.ts +++ b/src/livecodes/i18n/locales/de/translation.ts @@ -1035,6 +1035,7 @@ const translation: I18nTranslation = { riot: 'Riot.js-Starter', ruby: 'Ruby-Starter', 'ruby-wasm': 'Ruby (Wasm)-Starter', + 'rune-wasm': 'Rune Starter', scheme: 'Scheme-Starter', shadcnui: 'shadcn/ui-Starter', solid: 'Solid-Starter', diff --git a/src/livecodes/i18n/locales/en/translation.lokalise.json b/src/livecodes/i18n/locales/en/translation.lokalise.json index d5859dc1d..da5583bd3 100644 --- a/src/livecodes/i18n/locales/en/translation.lokalise.json +++ b/src/livecodes/i18n/locales/en/translation.lokalise.json @@ -2776,6 +2776,10 @@ "notes": "", "translation": "Ruby (Wasm) Starter" }, + "templates.starter.rune-wasm": { + "notes": "", + "translation": "Rune Starter" + }, "templates.starter.scheme": { "notes": "", "translation": "Scheme Starter" diff --git a/src/livecodes/i18n/locales/en/translation.ts b/src/livecodes/i18n/locales/en/translation.ts index 25144530b..68b2deb65 100644 --- a/src/livecodes/i18n/locales/en/translation.ts +++ b/src/livecodes/i18n/locales/en/translation.ts @@ -1040,6 +1040,7 @@ const translation = { riot: 'Riot.js Starter', ruby: 'Ruby Starter', 'ruby-wasm': 'Ruby (Wasm) Starter', + 'rune-wasm': 'Rune Starter', scheme: 'Scheme Starter', shadcnui: 'shadcn/ui Starter', solid: 'Solid Starter', diff --git a/src/livecodes/i18n/locales/es/translation.ts b/src/livecodes/i18n/locales/es/translation.ts index 534697911..47daff8c1 100644 --- a/src/livecodes/i18n/locales/es/translation.ts +++ b/src/livecodes/i18n/locales/es/translation.ts @@ -1033,6 +1033,7 @@ const translation: I18nTranslation = { riot: 'Inicio Riot.js', ruby: 'Inicio Ruby', 'ruby-wasm': 'Inicio Ruby (Wasm)', + 'rune-wasm': 'Rune Starter', scheme: 'Inicio Scheme', shadcnui: 'Inicio shadcn/ui', solid: 'Inicio Solid', diff --git a/src/livecodes/i18n/locales/fa/translation.ts b/src/livecodes/i18n/locales/fa/translation.ts index f5934a2aa..60cb6b460 100644 --- a/src/livecodes/i18n/locales/fa/translation.ts +++ b/src/livecodes/i18n/locales/fa/translation.ts @@ -1034,6 +1034,7 @@ const translation: I18nTranslation = { riot: 'شروع کننده Riot.js', ruby: 'شروع کننده Ruby', 'ruby-wasm': 'شروع کننده Ruby (Wasm)', + 'rune-wasm': 'Rune Starter', scheme: 'شروع کننده Scheme', shadcnui: 'شروع کننده shadcn/ui', solid: 'شروع کننده Solid', diff --git a/src/livecodes/i18n/locales/fr/translation.ts b/src/livecodes/i18n/locales/fr/translation.ts index 16ea491f5..4dd91474d 100644 --- a/src/livecodes/i18n/locales/fr/translation.ts +++ b/src/livecodes/i18n/locales/fr/translation.ts @@ -1035,6 +1035,7 @@ const translation: I18nTranslation = { riot: 'Démarrage Riot.js', ruby: 'Démarrage Ruby', 'ruby-wasm': 'Démarrage Ruby (Wasm)', + 'rune-wasm': 'Rune Starter', scheme: 'Démarrage Scheme', shadcnui: 'Démarrage shadcn/ui', solid: 'Démarrage Solid', diff --git a/src/livecodes/i18n/locales/hi/translation.ts b/src/livecodes/i18n/locales/hi/translation.ts index bb1bd1401..eb08cfedf 100644 --- a/src/livecodes/i18n/locales/hi/translation.ts +++ b/src/livecodes/i18n/locales/hi/translation.ts @@ -1033,6 +1033,7 @@ const translation: I18nTranslation = { riot: 'Riot.js स्टार्टर', ruby: 'Ruby स्टार्टर', 'ruby-wasm': 'Ruby (Wasm) स्टार्टर', + 'rune-wasm': 'Rune Starter', scheme: 'Scheme स्टार्टर', shadcnui: 'shadcn/ui स्टार्टर', solid: 'Solid स्टार्टर', diff --git a/src/livecodes/i18n/locales/hu/translation.ts b/src/livecodes/i18n/locales/hu/translation.ts index 5ee504dba..e60c03e82 100644 --- a/src/livecodes/i18n/locales/hu/translation.ts +++ b/src/livecodes/i18n/locales/hu/translation.ts @@ -1034,6 +1034,7 @@ const translation: I18nTranslation = { riot: 'Riot.js kezdő', ruby: 'Ruby kezdő', 'ruby-wasm': 'Ruby (Wasm) kezdő', + 'rune-wasm': 'Rune Starter', scheme: 'Scheme kezdő', shadcnui: 'shadcn/ui kezdő', solid: 'Solid kezdő', diff --git a/src/livecodes/i18n/locales/id/translation.ts b/src/livecodes/i18n/locales/id/translation.ts index 9569bd6a7..5e57e37c0 100644 --- a/src/livecodes/i18n/locales/id/translation.ts +++ b/src/livecodes/i18n/locales/id/translation.ts @@ -1033,6 +1033,7 @@ const translation: I18nTranslation = { riot: 'Pemula Riot.js', ruby: 'Pemula Ruby', 'ruby-wasm': 'Pemula Ruby (Wasm)', + 'rune-wasm': 'Rune Starter', scheme: 'Pemula Scheme', shadcnui: 'Pemula shadcn/ui', solid: 'Pemula Solid', diff --git a/src/livecodes/i18n/locales/it/translation.ts b/src/livecodes/i18n/locales/it/translation.ts index 2af811bf4..547f77a58 100644 --- a/src/livecodes/i18n/locales/it/translation.ts +++ b/src/livecodes/i18n/locales/it/translation.ts @@ -1034,6 +1034,7 @@ const translation: I18nTranslation = { riot: 'Starter Riot.js', ruby: 'Starter Ruby', 'ruby-wasm': 'Starter Ruby (Wasm)', + 'rune-wasm': 'Rune Starter', scheme: 'Starter Scheme', shadcnui: 'Starter shadcn/ui', solid: 'Starter Solid', diff --git a/src/livecodes/i18n/locales/ja/translation.ts b/src/livecodes/i18n/locales/ja/translation.ts index 184b15fc3..256f81b11 100644 --- a/src/livecodes/i18n/locales/ja/translation.ts +++ b/src/livecodes/i18n/locales/ja/translation.ts @@ -1034,6 +1034,7 @@ const translation: I18nTranslation = { riot: 'Riot.jsスターター', ruby: 'Rubyスターター', 'ruby-wasm': 'Ruby(Wasm)スターター', + 'rune-wasm': 'Rune Starter', scheme: 'Schemeスターター', shadcnui: 'shadcn/uiスターター', solid: 'Solidスターター', diff --git a/src/livecodes/i18n/locales/nl/translation.ts b/src/livecodes/i18n/locales/nl/translation.ts index 9e84ded3b..473050987 100644 --- a/src/livecodes/i18n/locales/nl/translation.ts +++ b/src/livecodes/i18n/locales/nl/translation.ts @@ -1034,6 +1034,7 @@ const translation: I18nTranslation = { riot: 'Riot.js-starter', ruby: 'Ruby-starter', 'ruby-wasm': 'Ruby (Wasm)-starter', + 'rune-wasm': 'Rune Starter', scheme: 'Scheme-starter', shadcnui: 'shadcn/ui-starter', solid: 'Solid-starter', diff --git a/src/livecodes/i18n/locales/pt/translation.ts b/src/livecodes/i18n/locales/pt/translation.ts index 9319a5991..0e9390629 100644 --- a/src/livecodes/i18n/locales/pt/translation.ts +++ b/src/livecodes/i18n/locales/pt/translation.ts @@ -1034,6 +1034,7 @@ const translation: I18nTranslation = { riot: 'Iniciante Riot.js', ruby: 'Iniciante Ruby', 'ruby-wasm': 'Iniciante Ruby (Wasm)', + 'rune-wasm': 'Rune Starter', scheme: 'Iniciante Scheme', shadcnui: 'Modelo inicial shadcn/ui', solid: 'Iniciante Solid', diff --git a/src/livecodes/i18n/locales/ru/translation.ts b/src/livecodes/i18n/locales/ru/translation.ts index 439cc3fab..a1f6f100c 100644 --- a/src/livecodes/i18n/locales/ru/translation.ts +++ b/src/livecodes/i18n/locales/ru/translation.ts @@ -1033,6 +1033,7 @@ const translation: I18nTranslation = { riot: 'Стартер Riot.js', ruby: 'Стартер Ruby', 'ruby-wasm': 'Стартер Ruby (Wasm)', + 'rune-wasm': 'Rune Starter', scheme: 'Стартер Scheme', shadcnui: 'Стартер shadcn/ui', solid: 'Стартер Solid', diff --git a/src/livecodes/i18n/locales/tr/translation.ts b/src/livecodes/i18n/locales/tr/translation.ts index 4cbf6519a..85d153290 100644 --- a/src/livecodes/i18n/locales/tr/translation.ts +++ b/src/livecodes/i18n/locales/tr/translation.ts @@ -1034,6 +1034,7 @@ const translation: I18nTranslation = { riot: 'Riot.js Başlangıç', ruby: 'Ruby Başlangıç', 'ruby-wasm': 'Ruby (Wasm) Başlangıç', + 'rune-wasm': 'Rune Starter', scheme: 'Scheme Başlangıç', shadcnui: 'shadcn/ui Başlangıç', solid: 'Solid Başlangıç', diff --git a/src/livecodes/i18n/locales/ur/translation.ts b/src/livecodes/i18n/locales/ur/translation.ts index e5ce1de1a..a6c7c8dbc 100644 --- a/src/livecodes/i18n/locales/ur/translation.ts +++ b/src/livecodes/i18n/locales/ur/translation.ts @@ -1033,6 +1033,7 @@ const translation: I18nTranslation = { riot: 'رائٹ.جے ایس شروعاتی', ruby: 'روبی شروعاتی', 'ruby-wasm': 'روبی (واسم) شروعاتی', + 'rune-wasm': 'Rune Starter', scheme: 'اسکیم شروعاتی', shadcnui: 'shadcn/ui شروعاتی', solid: 'سالڈ شروعاتی', diff --git a/src/livecodes/i18n/locales/zh-CN/translation.ts b/src/livecodes/i18n/locales/zh-CN/translation.ts index eaca469dd..6b57e7b26 100644 --- a/src/livecodes/i18n/locales/zh-CN/translation.ts +++ b/src/livecodes/i18n/locales/zh-CN/translation.ts @@ -1031,6 +1031,7 @@ const translation: I18nTranslation = { riot: 'Riot.js 启动模板', ruby: 'Ruby 启动模板', 'ruby-wasm': 'Ruby(Wasm)启动模板', + 'rune-wasm': 'Rune Starter', scheme: 'Scheme 启动模板', shadcnui: 'shadcn/ui 启动模板', solid: 'Solid 启动模板', diff --git a/src/livecodes/models.ts b/src/livecodes/models.ts index 77ca01e75..2e5f5baba 100644 --- a/src/livecodes/models.ts +++ b/src/livecodes/models.ts @@ -234,6 +234,8 @@ export type TemplateAlias = | 'rlang' | 'rb' | 'rb-wasm' + | 'rune' + | 'rn' | 'golang' | 'golang-wasm' | 'c++' diff --git a/src/livecodes/templates/starter/index.ts b/src/livecodes/templates/starter/index.ts index 4bc1caaf2..5ecc906bf 100644 --- a/src/livecodes/templates/starter/index.ts +++ b/src/livecodes/templates/starter/index.ts @@ -56,6 +56,7 @@ import { rescriptStarter } from './rescript-starter'; import { riotStarter } from './riot-starter'; import { rubyStarter } from './ruby-starter'; import { rubyWasmStarter } from './ruby-wasm-starter'; +import { runeWasmStarter } from './rune-wasm-starter'; import { schemeStarter } from './scheme-starter'; import { shadcnuiStarter } from './shadcn-ui-starter'; import { solidStarter } from './solid-starter'; @@ -112,6 +113,7 @@ export const starterTemplates = [ rStarter, rubyStarter, rubyWasmStarter, + runeWasmStarter, goStarter, goWasmStarter, phpStarter, diff --git a/src/livecodes/templates/starter/rune-wasm-starter.ts b/src/livecodes/templates/starter/rune-wasm-starter.ts new file mode 100644 index 000000000..b0c1e311f --- /dev/null +++ b/src/livecodes/templates/starter/rune-wasm-starter.ts @@ -0,0 +1,70 @@ +import type { Template } from '../../models'; + +export const runeWasmStarter: Template = { + name: 'rune-wasm', + aliases: ['rune', 'rn'], + title: window.deps.translateString('templates.starter.rune-wasm', 'Rune Starter'), + thumbnail: 'assets/templates/rune.svg', + activeEditor: 'script', + markup: { + language: 'html', + content: ` +
    +

    Hello, World!

    + +

    You clicked 0 times.

    + +
    + + +`.trimStart(), + }, + style: { + language: 'css', + content: ` +.container, +.container button { + text-align: center; + font: 1em sans-serif; +} +.logo { + width: 150px; +} +`.trimStart(), + }, + script: { + language: 'rune-wasm', + content: ` +pub fn main() { + println("Hello, Rune!"); + + let a = 10; + let b = 32; + let sum = a + b; + println(\`\${a} + \${b} = \${sum}\`); +} +`.trimStart(), + }, +}; diff --git a/storybook/solid/src/solid.ts b/storybook/solid/src/solid.ts index e5263fe35..b196750b3 100644 --- a/storybook/solid/src/solid.ts +++ b/storybook/solid/src/solid.ts @@ -10,7 +10,7 @@ import { createComponent } from '@live-codes/solid-sdk'; import type { Component, JSX } from 'solid-js'; import { createPlayground } from 'livecodes'; -// eslint-disable-next-line import/order + import type { EmbedOptions, Playground } from 'livecodes'; export type { Code, Config, EmbedOptions, Language, Playground } from 'livecodes'; From 37c7a545fe8298f26584c2a2f7c7b360f3d785bf Mon Sep 17 00:00:00 2001 From: "pullfrog[bot]" <226033991+pullfrog[bot]@users.noreply.github.com> Date: Tue, 9 Jun 2026 21:13:36 +0000 Subject: [PATCH 07/13] fix(rune-wasm): pass input to rune for counter in starter template --- .../rune-wasm/lang-rune-wasm-script.ts | 6 ++- .../templates/starter/rune-wasm-starter.ts | 40 +++++++++++-------- 2 files changed, 28 insertions(+), 18 deletions(-) diff --git a/src/livecodes/languages/rune-wasm/lang-rune-wasm-script.ts b/src/livecodes/languages/rune-wasm/lang-rune-wasm-script.ts index f90d47187..23e5a842b 100644 --- a/src/livecodes/languages/rune-wasm/lang-rune-wasm-script.ts +++ b/src/livecodes/languages/rune-wasm/lang-rune-wasm-script.ts @@ -37,10 +37,12 @@ const init = async () => { const runCode = async ( code: string, + input?: string, ): Promise<{ output: string | null; error: string | null; exitCode: number }> => { try { console.log('Running Rune code...'); - const result = await rune.module!.compile(code, {}); + const fullCode = `let input = ${input ?? '-1'};\n` + code; + const result = await rune.module!.compile(fullCode, {}); const output = result != null ? String(result) : ''; return { output, error: null, exitCode: 0 }; } catch (err) { @@ -64,7 +66,7 @@ livecodes.runeWasm.run ??= async (input?: string) => { : await (async () => { try { await init(); - return await runCode(code); + return await runCode(code, input); } catch (err) { const error = (err as Error).message ?? String(err); return { output: null, error, exitCode: 1 }; diff --git a/src/livecodes/templates/starter/rune-wasm-starter.ts b/src/livecodes/templates/starter/rune-wasm-starter.ts index b0c1e311f..e3c6bdbd9 100644 --- a/src/livecodes/templates/starter/rune-wasm-starter.ts +++ b/src/livecodes/templates/starter/rune-wasm-starter.ts @@ -19,23 +19,33 @@ export const runeWasmStarter: Template = { @@ -59,11 +69,9 @@ export const runeWasmStarter: Template = { content: ` pub fn main() { println("Hello, Rune!"); - - let a = 10; - let b = 32; - let sum = a + b; - println(\`\${a} + \${b} = \${sum}\`); + let count = input; + count = count + 1; + println(\`{count}\`); } `.trimStart(), }, From 5f3f41b4219e225baa14ca38efc5fbfa668916ad Mon Sep 17 00:00:00 2001 From: "pullfrog[bot]" <226033991+pullfrog[bot]@users.noreply.github.com> Date: Tue, 9 Jun 2026 21:14:41 +0000 Subject: [PATCH 08/13] feat(rune-wasm): pass input to rune code, increment counter in rune - Pass input from run() to runCode() as injected __input variable - Update starter template to use rune for counter increment (matching csharp-wasm pattern) --- .../rune-wasm/lang-rune-wasm-script.ts | 7 ++- .../templates/starter/rune-wasm-starter.ts | 47 ++++++++++++------- 2 files changed, 35 insertions(+), 19 deletions(-) diff --git a/src/livecodes/languages/rune-wasm/lang-rune-wasm-script.ts b/src/livecodes/languages/rune-wasm/lang-rune-wasm-script.ts index f90d47187..42b39a88c 100644 --- a/src/livecodes/languages/rune-wasm/lang-rune-wasm-script.ts +++ b/src/livecodes/languages/rune-wasm/lang-rune-wasm-script.ts @@ -37,10 +37,13 @@ const init = async () => { const runCode = async ( code: string, + input?: string, ): Promise<{ output: string | null; error: string | null; exitCode: number }> => { try { console.log('Running Rune code...'); - const result = await rune.module!.compile(code, {}); + const compiledCode = + input != null && input !== '' ? `let __input = ${Number(input)};\n${code}` : code; + const result = await rune.module!.compile(compiledCode, {}); const output = result != null ? String(result) : ''; return { output, error: null, exitCode: 0 }; } catch (err) { @@ -64,7 +67,7 @@ livecodes.runeWasm.run ??= async (input?: string) => { : await (async () => { try { await init(); - return await runCode(code); + return await runCode(code, input); } catch (err) { const error = (err as Error).message ?? String(err); return { output: null, error, exitCode: 1 }; diff --git a/src/livecodes/templates/starter/rune-wasm-starter.ts b/src/livecodes/templates/starter/rune-wasm-starter.ts index b0c1e311f..1ba517221 100644 --- a/src/livecodes/templates/starter/rune-wasm-starter.ts +++ b/src/livecodes/templates/starter/rune-wasm-starter.ts @@ -17,26 +17,43 @@ export const runeWasmStarter: Template = {
  • `.trimStart(), @@ -59,11 +76,7 @@ export const runeWasmStarter: Template = { content: ` pub fn main() { println("Hello, Rune!"); - - let a = 10; - let b = 32; - let sum = a + b; - println(\`\${a} + \${b} = \${sum}\`); + println(\`\${__input + 1}\`); } `.trimStart(), }, From a9bb3353c08dfebc46361bd9bbc9e13d5f837ec8 Mon Sep 17 00:00:00 2001 From: "pullfrog[bot]" <226033991+pullfrog[bot]@users.noreply.github.com> Date: Tue, 9 Jun 2026 21:28:30 +0000 Subject: [PATCH 09/13] fix: prettier formatting in rune-wasm runtime script --- src/livecodes/languages/rune-wasm/lang-rune-wasm-script.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/livecodes/languages/rune-wasm/lang-rune-wasm-script.ts b/src/livecodes/languages/rune-wasm/lang-rune-wasm-script.ts index 42093c651..3bffba66f 100644 --- a/src/livecodes/languages/rune-wasm/lang-rune-wasm-script.ts +++ b/src/livecodes/languages/rune-wasm/lang-rune-wasm-script.ts @@ -41,8 +41,7 @@ const runCode = async ( ): Promise<{ output: string | null; error: string | null; exitCode: number }> => { try { console.log('Running Rune code...'); - const compiledCode = - input != null && input !== '' ? `let input = ${input};\n${code}` : code; + const compiledCode = input != null && input !== '' ? `let input = ${input};\n${code}` : code; const result = await rune.module!.compile(compiledCode, {}); const output = result != null ? String(result) : ''; return { output, error: null, exitCode: 0 }; From a3ada2abdfedb79ced25df86d25e213869fb7d8f Mon Sep 17 00:00:00 2001 From: "pullfrog[bot]" <226033991+pullfrog[bot]@users.noreply.github.com> Date: Wed, 10 Jun 2026 02:33:09 +0000 Subject: [PATCH 10/13] fix(rune-wasm): fix starter template output displaying [object Object] and undefined --- src/livecodes/languages/rune-wasm/lang-rune-wasm-script.ts | 2 ++ src/livecodes/templates/starter/rune-wasm-starter.ts | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/livecodes/languages/rune-wasm/lang-rune-wasm-script.ts b/src/livecodes/languages/rune-wasm/lang-rune-wasm-script.ts index 3bffba66f..5df034690 100644 --- a/src/livecodes/languages/rune-wasm/lang-rune-wasm-script.ts +++ b/src/livecodes/languages/rune-wasm/lang-rune-wasm-script.ts @@ -87,6 +87,8 @@ livecodes.runeWasm.run ??= async (input?: string) => { livecodes.runeWasm.ready = true; parent.postMessage({ type: 'loading', payload: false }, '*'); + + return { output, error, exitCode }; }; livecodes.runeWasm.loaded = new Promise((resolve) => { diff --git a/src/livecodes/templates/starter/rune-wasm-starter.ts b/src/livecodes/templates/starter/rune-wasm-starter.ts index 353b3af09..a288db768 100644 --- a/src/livecodes/templates/starter/rune-wasm-starter.ts +++ b/src/livecodes/templates/starter/rune-wasm-starter.ts @@ -42,9 +42,9 @@ export const runeWasmStarter: Template = { const counter = document.querySelector("#counter"); const button = document.querySelector("#counter-button"); - const [title, count] = output.split('\\n'); + const [title, count] = output.split('\n'); - if (parseInt(count) !== NaN) { + if (!isNaN(parseInt(count))) { window.count = count; counter.innerText = window.count; } From 7f039758f2d9f29dc9bbc4532dcd792248b1132d Mon Sep 17 00:00:00 2001 From: "pullfrog[bot]" <226033991+pullfrog[bot]@users.noreply.github.com> Date: Wed, 10 Jun 2026 03:19:16 +0000 Subject: [PATCH 11/13] fix(rune-wasm): extract .output/.error from WasmCompileResult object instead of stringifying The Rune WASM compile() returns a WasmCompileResult object with .output, .result, and .error fields, not a plain string. Calling String(result) on the object produced [object Object]. Extract the correct fields instead. --- .../languages/rune-wasm/lang-rune-wasm-script.ts | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/livecodes/languages/rune-wasm/lang-rune-wasm-script.ts b/src/livecodes/languages/rune-wasm/lang-rune-wasm-script.ts index 5df034690..562e1d0ff 100644 --- a/src/livecodes/languages/rune-wasm/lang-rune-wasm-script.ts +++ b/src/livecodes/languages/rune-wasm/lang-rune-wasm-script.ts @@ -14,7 +14,14 @@ declare const rune: { init: () => Promise; module: | ({ - compile: (input: string, config: Record) => Promise; + compile: ( + input: string, + config: Record, + ) => Promise<{ + output: string | null; + result: string | null; + error: string | null; + }>; } & Record) | null; }; @@ -43,8 +50,10 @@ const runCode = async ( console.log('Running Rune code...'); const compiledCode = input != null && input !== '' ? `let input = ${input};\n${code}` : code; const result = await rune.module!.compile(compiledCode, {}); - const output = result != null ? String(result) : ''; - return { output, error: null, exitCode: 0 }; + if (result.error != null) { + return { output: result.output ?? null, error: result.error, exitCode: 1 }; + } + return { output: result.output ?? '', error: null, exitCode: 0 }; } catch (err) { const error = (err as Error).message ?? String(err); return { output: null, error, exitCode: (err as any).code ?? 1 }; From 1ffd78571d6b8dd4a381cb47b4aca6b6ce4b7619 Mon Sep 17 00:00:00 2001 From: "pullfrog[bot]" <226033991+pullfrog[bot]@users.noreply.github.com> Date: Wed, 10 Jun 2026 04:08:06 +0000 Subject: [PATCH 12/13] fix: commit generated templates.js with rune-wasm starter and lint fix --- functions/vendors/templates.js | 97 ++++++++++++++++++++++++++++------ storybook/solid/src/solid.ts | 2 +- 2 files changed, 81 insertions(+), 18 deletions(-) diff --git a/functions/vendors/templates.js b/functions/vendors/templates.js index ace9a3ab5..c81cebc4c 100644 --- a/functions/vendors/templates.js +++ b/functions/vendors/templates.js @@ -1029,7 +1029,7 @@ svg .container h3:not(:nth-child(1)) { margin-top: 3em; } -`.trimStart()},script:{language:"javascript",content:""},stylesheets:[],scripts:[],cssPreset:"",imports:{},types:{}};var L={name:"fennel",title:getTemplateName("templates.starter.fennel","Fennel Starter"),thumbnail:"assets/templates/fennel.svg",activeEditor:"script",markup:{language:"html",content:` +`.trimStart()},script:{language:"javascript",content:""},stylesheets:[],scripts:[],cssPreset:"",imports:{},types:{}};var q={name:"fennel",title:getTemplateName("templates.starter.fennel","Fennel Starter"),thumbnail:"assets/templates/fennel.svg",activeEditor:"script",markup:{language:"html",content:`

    Hello, World!

    @@ -1063,7 +1063,7 @@ svg (global counter (Counter:new nil)) (global button (document:querySelector "#counter-button")) (button:addEventListener :click (fn [] (counter:increment) (counter:show))) -`.trimStart()}};var $=["esm.sh","skypack","esm.run","jsdelivr.esm","fastly.jsdelivr.esm","gcore.jsdelivr.esm","testingcf.jsdelivr.esm","jsdelivr.b-cdn.esm","jspm"],B=["jsdelivr","fastly.jsdelivr","unpkg","gcore.jsdelivr","testingcf.jsdelivr","jsdelivr.b-cdn","npmcdn"],M=["jsdelivr.gh","fastly.jsdelivr.gh","statically","gcore.jsdelivr.gh","testingcf.jsdelivr.gh","jsdelivr.b-cdn.gh"],r={getModuleUrl:(e,{isModule:s=!0,defaultCDN:i="esm.sh",external:o}={})=>{e=e.replace(/#nobundle/g,"");let a=n=>!o||!n.includes("https://esm.sh")?n:n.includes("?")?`${n}&external=${o}`:`${n}?external=${o}`,l=q(e,s,i);return l?a(l):s?a("https://esm.sh/"+e):"https://cdn.jsdelivr.net/npm/"+e},getUrl:(e,s)=>e.startsWith("http")||e.startsWith("data:")?e:q(e,!1,s||$t())||e,cdnLists:{npm:B,module:$,gh:M},checkCDNs:async(e,s)=>{let i=[s,...r.cdnLists.npm].filter(Boolean);for(let o of i)try{if((await fetch(r.getUrl(e,o),{method:"HEAD"})).ok)return o}catch{}return r.cdnLists.npm[0]}},$t=()=>{if(globalThis.appCDN)return globalThis.appCDN;try{return new URL(location.href).searchParams.get("appCDN")||r.cdnLists.npm[0]}catch{return r.cdnLists.npm[0]}},q=(e,s,i)=>{let o=s&&e.startsWith("unpkg:")?"?module":"";e.startsWith("gh:")?e=e.replace("gh",M[0]):e.includes(":")||(e=(i||(s?$[0]:B[0]))+":"+e);for(let a of Bt){let[l,n]=a;if(l.test(e))return e.replace(l,n)+o}return null},Bt=[[/^(esm\.sh:)(.+)/i,"https://esm.sh/$2"],[/^(npm:)(.+)/i,"https://esm.sh/$2"],[/^(node:)(.+)/i,"https://esm.sh/$2"],[/^(jsr:)(.+)/i,"https://esm.sh/jsr/$2"],[/^(pr:)(.+)/i,"https://esm.sh/pr/$2"],[/^(pkg\.pr\.new:)(.+)/i,"https://esm.sh/pkg.pr.new/$2"],[/^(skypack:)(.+)/i,"https://cdn.skypack.dev/$2"],[/^(jsdelivr:)(.+)/i,"https://cdn.jsdelivr.net/npm/$2"],[/^(fastly\.jsdelivr:)(.+)/i,"https://fastly.jsdelivr.net/npm/$2"],[/^(gcore\.jsdelivr:)(.+)/i,"https://gcore.jsdelivr.net/npm/$2"],[/^(testingcf\.jsdelivr:)(.+)/i,"https://testingcf.jsdelivr.net/npm/$2"],[/^(jsdelivr\.b-cdn:)(.+)/i,"https://jsdelivr.b-cdn.net/npm/$2"],[/^(jsdelivr\.gh:)(.+)/i,"https://cdn.jsdelivr.net/gh/$2"],[/^(fastly\.jsdelivr\.gh:)(.+)/i,"https://fastly.jsdelivr.net/gh/$2"],[/^(gcore\.jsdelivr\.gh:)(.+)/i,"https://gcore.jsdelivr.net/gh/$2"],[/^(testingcf\.jsdelivr\.gh:)(.+)/i,"https://testingcf.jsdelivr.net/gh/$2"],[/^(jsdelivr\.b-cdn\.gh:)(.+)/i,"https://jsdelivr.b-cdn.net/gh/$2"],[/^(statically:)(.+)/i,"https://cdn.statically.io/gh/$2"],[/^(esm\.run:)(.+)/i,"https://esm.run/$2"],[/^(jsdelivr\.esm:)(.+)/i,"https://cdn.jsdelivr.net/npm/$2/+esm"],[/^(fastly\.jsdelivr\.esm:)(.+)/i,"https://fastly.jsdelivr.net/npm/$2/+esm"],[/^(gcore\.jsdelivr\.esm:)(.+)/i,"https://gcore.jsdelivr.net/npm/$2/+esm"],[/^(testingcf\.jsdelivr\.esm:)(.+)/i,"https://testingcf.jsdelivr.net/npm/$2/+esm"],[/^(jsdelivr\.b-cdn\.esm:)(.+)/i,"https://jsdelivr.b-cdn.net/npm/$2/+esm"],[/^(jspm:)(.+)/i,"https://jspm.dev/$2"],[/^(esbuild:)(.+)/i,"https://esbuild.vercel.app/$2"],[/^(bundle\.run:)(.+)/i,"https://bundle.run/$2"],[/^(unpkg:)(.+)/i,"https://unpkg.com/$2"],[/^(npmcdn:)(.+)/i,"https://npmcdn.com/$2"],[/^(bundlejs:)(.+)/i,"https://deno.bundlejs.com/?file&q=$2"],[/^(bundle:)(.+)/i,"https://deno.bundlejs.com/?file&q=$2"],[/^(deno:)(.+)/i,"https://deno.bundlejs.com/?file&q=https://deno.land/x/$2/mod.ts"],[/^(https:\/\/deno\.land\/.+)/i,"https://deno.bundlejs.com/?file&q=$1"],[/^(github:|https:\/\/github\.com\/)(.[^\/]+?)\/(.[^\/]+?)\/(?!releases\/)(?:(?:blob|raw)\/)?(.+?\/.+)/i,"https://deno.bundlejs.com/?file&q=https://cdn.jsdelivr.net/gh/$2/$3@$4"],[/^(gist\.github:)(.+?\/[0-9a-f]+\/raw\/(?:[0-9a-f]+\/)?.+)$/i,"https://gist.githack.com/$2"],[/^(gitlab:|https:\/\/gitlab\.com\/)([^\/]+.*\/[^\/]+)\/(?:raw|blob)\/(.+?)(?:\?.*)?$/i,"https://deno.bundlejs.com/?file&q=https://gl.githack.com/$2/raw/$3"],[/^(bitbucket:|https:\/\/bitbucket\.org\/)([^\/]+\/[^\/]+)\/(?:raw|src)\/(.+?)(?:\?.*)?$/i,"https://deno.bundlejs.com/?file&q=https://bb.githack.com/$2/raw/$3"],[/^(bitbucket:)snippets\/([^\/]+\/[^\/]+)\/revisions\/([^\/\#\?]+)(?:\?[^#]*)?(?:\#file-(.+?))$/i,"https://bb.githack.com/!api/2.0/snippets/$2/$3/files/$4"],[/^(bitbucket:)snippets\/([^\/]+\/[^\/\#\?]+)(?:\?[^#]*)?(?:\#file-(.+?))$/i,"https://bb.githack.com/!api/2.0/snippets/$2/HEAD/files/$3"],[/^(bitbucket:)\!api\/2.0\/snippets\/([^\/]+\/[^\/]+\/[^\/]+)\/files\/(.+?)(?:\?.*)?$/i,"https://bb.githack.com/!api/2.0/snippets/$2/files/$3"],[/^(api\.bitbucket:)2.0\/snippets\/([^\/]+\/[^\/]+\/[^\/]+)\/files\/(.+?)(?:\?.*)?$/i,"https://bb.githack.com/!api/2.0/snippets/$2/files/$3"],[/^(rawgit:)(.+?\/[0-9a-f]+\/raw\/(?:[0-9a-f]+\/)?.+)$/i,"https://gist.githack.com/$2"],[/^(rawgit:|https:\/\/raw\.githubusercontent\.com)(\/[^\/]+\/[^\/]+|[0-9A-Za-z-]+\/[0-9a-f]+\/raw)\/(.+)/i,"https://deno.bundlejs.com/?file&q=https://raw.githack.com/$2/$3"]];var{getUrl:P,getModuleUrl:se}=r;var c=P("gh:live-codes/gleam-precompiled@v0.5.0/");var Mt="5.9.3",oe=P(`typescript@${Mt}/lib/typescript.js`);var p=c+"build/packages/plinth/src/plinth/",m=c+"build/dev/javascript/plinth/plinth/",R={name:"gleam",title:getTemplateName("templates.starter.gleam","Gleam Starter"),thumbnail:"assets/templates/gleam.svg",activeEditor:"script",markup:{language:"html",content:` +`.trimStart()}};var $=["esm.sh","skypack","esm.run","jsdelivr.esm","fastly.jsdelivr.esm","gcore.jsdelivr.esm","testingcf.jsdelivr.esm","jsdelivr.b-cdn.esm","jspm"],B=["jsdelivr","fastly.jsdelivr","unpkg","gcore.jsdelivr","testingcf.jsdelivr","jsdelivr.b-cdn","npmcdn"],M=["jsdelivr.gh","fastly.jsdelivr.gh","statically","gcore.jsdelivr.gh","testingcf.jsdelivr.gh","jsdelivr.b-cdn.gh"],r={getModuleUrl:(e,{isModule:s=!0,defaultCDN:i="esm.sh",external:o}={})=>{e=e.replace(/#nobundle/g,"");let a=n=>!o||!n.includes("https://esm.sh")?n:n.includes("?")?`${n}&external=${o}`:`${n}?external=${o}`,l=L(e,s,i);return l?a(l):s?a("https://esm.sh/"+e):"https://cdn.jsdelivr.net/npm/"+e},getUrl:(e,s)=>e.startsWith("http")||e.startsWith("data:")?e:L(e,!1,s||Bt())||e,cdnLists:{npm:B,module:$,gh:M},checkCDNs:async(e,s)=>{let i=[s,...r.cdnLists.npm].filter(Boolean);for(let o of i)try{if((await fetch(r.getUrl(e,o),{method:"HEAD"})).ok)return o}catch{}return r.cdnLists.npm[0]}},Bt=()=>{if(globalThis.appCDN)return globalThis.appCDN;try{return new URL(location.href).searchParams.get("appCDN")||r.cdnLists.npm[0]}catch{return r.cdnLists.npm[0]}},L=(e,s,i)=>{let o=s&&e.startsWith("unpkg:")?"?module":"";e.startsWith("gh:")?e=e.replace("gh",M[0]):e.includes(":")||(e=(i||(s?$[0]:B[0]))+":"+e);for(let a of Mt){let[l,n]=a;if(l.test(e))return e.replace(l,n)+o}return null},Mt=[[/^(esm\.sh:)(.+)/i,"https://esm.sh/$2"],[/^(npm:)(.+)/i,"https://esm.sh/$2"],[/^(node:)(.+)/i,"https://esm.sh/$2"],[/^(jsr:)(.+)/i,"https://esm.sh/jsr/$2"],[/^(pr:)(.+)/i,"https://esm.sh/pr/$2"],[/^(pkg\.pr\.new:)(.+)/i,"https://esm.sh/pkg.pr.new/$2"],[/^(skypack:)(.+)/i,"https://cdn.skypack.dev/$2"],[/^(jsdelivr:)(.+)/i,"https://cdn.jsdelivr.net/npm/$2"],[/^(fastly\.jsdelivr:)(.+)/i,"https://fastly.jsdelivr.net/npm/$2"],[/^(gcore\.jsdelivr:)(.+)/i,"https://gcore.jsdelivr.net/npm/$2"],[/^(testingcf\.jsdelivr:)(.+)/i,"https://testingcf.jsdelivr.net/npm/$2"],[/^(jsdelivr\.b-cdn:)(.+)/i,"https://jsdelivr.b-cdn.net/npm/$2"],[/^(jsdelivr\.gh:)(.+)/i,"https://cdn.jsdelivr.net/gh/$2"],[/^(fastly\.jsdelivr\.gh:)(.+)/i,"https://fastly.jsdelivr.net/gh/$2"],[/^(gcore\.jsdelivr\.gh:)(.+)/i,"https://gcore.jsdelivr.net/gh/$2"],[/^(testingcf\.jsdelivr\.gh:)(.+)/i,"https://testingcf.jsdelivr.net/gh/$2"],[/^(jsdelivr\.b-cdn\.gh:)(.+)/i,"https://jsdelivr.b-cdn.net/gh/$2"],[/^(statically:)(.+)/i,"https://cdn.statically.io/gh/$2"],[/^(esm\.run:)(.+)/i,"https://esm.run/$2"],[/^(jsdelivr\.esm:)(.+)/i,"https://cdn.jsdelivr.net/npm/$2/+esm"],[/^(fastly\.jsdelivr\.esm:)(.+)/i,"https://fastly.jsdelivr.net/npm/$2/+esm"],[/^(gcore\.jsdelivr\.esm:)(.+)/i,"https://gcore.jsdelivr.net/npm/$2/+esm"],[/^(testingcf\.jsdelivr\.esm:)(.+)/i,"https://testingcf.jsdelivr.net/npm/$2/+esm"],[/^(jsdelivr\.b-cdn\.esm:)(.+)/i,"https://jsdelivr.b-cdn.net/npm/$2/+esm"],[/^(jspm:)(.+)/i,"https://jspm.dev/$2"],[/^(esbuild:)(.+)/i,"https://esbuild.vercel.app/$2"],[/^(bundle\.run:)(.+)/i,"https://bundle.run/$2"],[/^(unpkg:)(.+)/i,"https://unpkg.com/$2"],[/^(npmcdn:)(.+)/i,"https://npmcdn.com/$2"],[/^(bundlejs:)(.+)/i,"https://deno.bundlejs.com/?file&q=$2"],[/^(bundle:)(.+)/i,"https://deno.bundlejs.com/?file&q=$2"],[/^(deno:)(.+)/i,"https://deno.bundlejs.com/?file&q=https://deno.land/x/$2/mod.ts"],[/^(https:\/\/deno\.land\/.+)/i,"https://deno.bundlejs.com/?file&q=$1"],[/^(github:|https:\/\/github\.com\/)(.[^\/]+?)\/(.[^\/]+?)\/(?!releases\/)(?:(?:blob|raw)\/)?(.+?\/.+)/i,"https://deno.bundlejs.com/?file&q=https://cdn.jsdelivr.net/gh/$2/$3@$4"],[/^(gist\.github:)(.+?\/[0-9a-f]+\/raw\/(?:[0-9a-f]+\/)?.+)$/i,"https://gist.githack.com/$2"],[/^(gitlab:|https:\/\/gitlab\.com\/)([^\/]+.*\/[^\/]+)\/(?:raw|blob)\/(.+?)(?:\?.*)?$/i,"https://deno.bundlejs.com/?file&q=https://gl.githack.com/$2/raw/$3"],[/^(bitbucket:|https:\/\/bitbucket\.org\/)([^\/]+\/[^\/]+)\/(?:raw|src)\/(.+?)(?:\?.*)?$/i,"https://deno.bundlejs.com/?file&q=https://bb.githack.com/$2/raw/$3"],[/^(bitbucket:)snippets\/([^\/]+\/[^\/]+)\/revisions\/([^\/\#\?]+)(?:\?[^#]*)?(?:\#file-(.+?))$/i,"https://bb.githack.com/!api/2.0/snippets/$2/$3/files/$4"],[/^(bitbucket:)snippets\/([^\/]+\/[^\/\#\?]+)(?:\?[^#]*)?(?:\#file-(.+?))$/i,"https://bb.githack.com/!api/2.0/snippets/$2/HEAD/files/$3"],[/^(bitbucket:)\!api\/2.0\/snippets\/([^\/]+\/[^\/]+\/[^\/]+)\/files\/(.+?)(?:\?.*)?$/i,"https://bb.githack.com/!api/2.0/snippets/$2/files/$3"],[/^(api\.bitbucket:)2.0\/snippets\/([^\/]+\/[^\/]+\/[^\/]+)\/files\/(.+?)(?:\?.*)?$/i,"https://bb.githack.com/!api/2.0/snippets/$2/files/$3"],[/^(rawgit:)(.+?\/[0-9a-f]+\/raw\/(?:[0-9a-f]+\/)?.+)$/i,"https://gist.githack.com/$2"],[/^(rawgit:|https:\/\/raw\.githubusercontent\.com)(\/[^\/]+\/[^\/]+|[0-9A-Za-z-]+\/[0-9a-f]+\/raw)\/(.+)/i,"https://deno.bundlejs.com/?file&q=https://raw.githack.com/$2/$3"]];var{getUrl:P,getModuleUrl:oe}=r;var c=P("gh:live-codes/gleam-precompiled@v0.5.0/");var Pt="5.9.3",ne=P(`typescript@${Pt}/lib/typescript.js`);var p=c+"build/packages/plinth/src/plinth/",m=c+"build/dev/javascript/plinth/plinth/",R={name:"gleam",title:getTemplateName("templates.starter.gleam","Gleam Starter"),thumbnail:"assets/templates/gleam.svg",activeEditor:"script",markup:{language:"html",content:`

    Hello, World!

    @@ -1471,7 +1471,7 @@ button.addEventListener("click", () => { count++; counter.innerText = count; }); -`.trimStart()},stylesheets:[],scripts:[],cssPreset:"",imports:{},types:{}};var A={name:"jest-react",title:getTemplateName("templates.starter.jest-react","Jest/React Starter"),thumbnail:"assets/templates/jest.svg",activeEditor:"script",autotest:!0,markup:{language:"html",content:""},style:{language:"css",content:` +`.trimStart()},stylesheets:[],scripts:[],cssPreset:"",imports:{},types:{}};var O={name:"jest-react",title:getTemplateName("templates.starter.jest-react","Jest/React Starter"),thumbnail:"assets/templates/jest.svg",activeEditor:"script",autotest:!0,markup:{language:"html",content:""},style:{language:"css",content:` .container, .container button { text-align: center; @@ -1553,7 +1553,7 @@ describe("Page", () => { ); }); }); -`.trimStart()},tools:{enabled:"all",active:"tests",status:"open"}};var O={name:"jest",title:getTemplateName("templates.starter.jest","Jest Starter"),thumbnail:"assets/templates/jest.svg",autotest:!0,activeEditor:"script",markup:{language:"html",content:` +`.trimStart()},tools:{enabled:"all",active:"tests",status:"open"}};var A={name:"jest",title:getTemplateName("templates.starter.jest","Jest Starter"),thumbnail:"assets/templates/jest.svg",autotest:!0,activeEditor:"script",markup:{language:"html",content:`

    Hello, World!

    @@ -3461,7 +3461,70 @@ elsif current_time < 18 else puts "Good evening, " + msg end -`.trimStart()}};var yt={name:"scheme",title:getTemplateName("templates.starter.scheme","Scheme Starter"),thumbnail:"assets/templates/scheme.svg",activeEditor:"script",markup:{language:"html",content:` +`.trimStart()}};var yt={name:"rune-wasm",aliases:["rune","rn"],title:getTemplateName("templates.starter.rune-wasm","Rune Starter"),thumbnail:"assets/templates/rune.svg",activeEditor:"script",markup:{language:"html",content:` +
    +

    Hello, World!

    + +

    You clicked 0 times.

    + +
    + +