code-playpad 0.2.1 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +134 -13
- package/dist/THIRD-PARTY-NOTICES.txt +50 -0
- package/dist/cdn.js +2 -0
- package/dist/config-DZqcFPEP.js +5 -0
- package/dist/dist-BKRQwpg6.js +6 -0
- package/dist/{element-VP5lhHx6.js → element-BYcX5Z6z.js} +11 -11
- package/dist/element.d.ts +3 -0
- package/dist/element.js +1 -1
- package/dist/hints-v5iHTd1l.js +6 -0
- package/dist/index.js +1 -1
- package/dist/java-1ISFU8hm.js +1 -0
- package/dist/java-DSEX5tzl.js +6 -0
- package/dist/javascript-BhISU47e.js +14 -0
- package/dist/javascript-hfFD1Fg2.js +9 -0
- package/dist/{pyodide-5ByQYqgo.js → pyodide-BTGQ_X_F.js} +8 -8
- package/dist/{pyodide-yv6x2HCQ.js → pyodide-j1wg1W9_.js} +8 -8
- package/dist/react.js +1 -1
- package/dist/runtime/hints.d.ts +11 -0
- package/dist/runtime/java-worker.generated.d.ts +8 -0
- package/dist/runtime/java.d.ts +3 -0
- package/dist/runtime/worker-runtime.d.ts +14 -4
- package/dist/standalone.d.ts +6 -2
- package/dist/standalone.js +11 -11
- package/dist/types.d.ts +6 -2
- package/dist/worker-runtime-CmbgEzLA.js +9 -0
- package/dist/worker-runtime-mfgjcG5l.js +4 -0
- package/package.json +12 -4
- package/dist/config-B2qK2rdk.js +0 -6
- package/dist/javascript-DGFKR69i.js +0 -323
- package/dist/javascript-RVtPk08Z.js +0 -318
- package/dist/worker-runtime-8Mnw4vAD.js +0 -9
- package/dist/worker-runtime-CJ3Zww5E.js +0 -4
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import{i as e}from"./config-DZqcFPEP.js";import{t}from"./worker-runtime-
|
|
1
|
+
import{i as e}from"./config-DZqcFPEP.js";import{t}from"./worker-runtime-mfgjcG5l.js";var n=`let pyodide=null,stdinLines=[],stdinExhausted=!1,currentId=null,interactive=!1,inputWaitMs=0,nextRequest=1;const pendingLines=new Map,MOUNT="/home/pyodide/playground";let written=new Set,internals=null;const REFRESH=["import importlib, os, sys","MOUNT = "+JSON.stringify(MOUNT),"os.makedirs(MOUNT, exist_ok=True)","sys.path.insert(0, MOUNT) if MOUNT not in sys.path else None","os.chdir(MOUNT)","for _name, _mod in list(sys.modules.items()):",' _file = getattr(_mod, "__file__", None) or ""',' _paths = list(getattr(_mod, "__path__", None) or [])'," if _file.startswith(MOUNT) or any(str(p).startswith(MOUNT) for p in _paths):"," del sys.modules[_name]","importlib.invalidate_caches()"].join(\`
|
|
2
2
|
\`);function flushStreams(){try{pyodide.runPython(\`import sys
|
|
3
3
|
sys.stdout.flush()
|
|
4
4
|
sys.stderr.flush()\`,{globals:internals})}catch{}flushOutput()}const INPUT_OVERRIDE=["import builtins, sys, js","from pyodide.ffi import run_sync","",'def _pg_input(prompt=""):',' if prompt != "":'," sys.stdout.write(str(prompt))"," sys.stdout.flush()"," line = run_sync(js._pgReadLine())"," # Pyodide maps JS null to its own JsNull singleton, not None, so test"," # for what we want rather than for the several ways EOF can arrive."," if not isinstance(line, str):",' raise EOFError("EOF when reading a line")'," return line","",'_pg_input.__name__ = "input"','_pg_input.__qualname__ = "input"',"_pg_input.__doc__ = builtins.input.__doc__","builtins.input = _pg_input"].join(\`
|
|
5
|
-
\`);self._pgReadLine=async()=>{if(stdinLines.length){const
|
|
6
|
-
\`),
|
|
7
|
-
\`);if(/^Traceback/.test(n[0])){let
|
|
8
|
-
\`)}return t.split(MOUNT+"/").join("").replace(/\\s+$/,"")}async function importLoadPyodide(e){try{const t=await import(e+"pyodide.mjs");if(t&&t.loadPyodide)return t.loadPyodide}catch(t){if(typeof importScripts!="function")throw t}return importScripts(e+"pyodide.js"),self.loadPyodide}async function boot(e){post({type:"progress",phase:"booting",message:"Loading Python runtime"}),pyodide=await(await importLoadPyodide(e))({indexURL:e});const n=new TextDecoder,
|
|
5
|
+
\`);self._pgReadLine=async()=>{if(stdinLines.length){const i=stdinLines.shift();return writeOutput("echo",i+\`
|
|
6
|
+
\`),i}if(!interactive)return stdinExhausted=!0,null;const e=nextRequest++;flushOutput();const t=performance.now(),n=await new Promise(i=>{pendingLines.set(e,i),post({type:"stdin-request",id:currentId,request:e})});return inputWaitMs+=performance.now()-t,n===void 0?null:n};function syncFiles(e){const t=Object.keys(e);for(const n of written)if(t.indexOf(n)===-1)try{pyodide.FS.unlink(MOUNT+"/"+n)}catch{}written=new Set(t);for(const n of t){const i=MOUNT+"/"+n,s=i.slice(0,i.lastIndexOf("/"));pyodide.FS.mkdirTree(s),pyodide.FS.writeFile(i,e[n],{encoding:"utf8"})}pyodide.runPython(REFRESH,{globals:internals})}function post(e){self.postMessage(e)}const FLUSH_BYTES=8192,FLUSH_MS=16,EAGER_POSTS=32;let outputQueue=[],queuedChars=0,windowStart=-1/0,windowPosts=0;function writeOutput(e,t){const n=outputQueue[outputQueue.length-1];n&&n.type===e?n.text+=t:outputQueue.push({type:e,text:t}),queuedChars+=t.length;const i=performance.now();i-windowStart>=FLUSH_MS&&(windowStart=i,windowPosts=0),(windowPosts<EAGER_POSTS||queuedChars>=FLUSH_BYTES)&&flushOutput()}function flushOutput(){if(!outputQueue.length)return;windowPosts++;const e=outputQueue;outputQueue=[],queuedChars=0;for(const t of e)post({type:t.type,id:currentId,text:t.text})}function formatError(e){let t=e&&e.message?e.message:String(e);const n=t.split(\`
|
|
7
|
+
\`);if(/^Traceback/.test(n[0])){let i=-1;for(let r=1;r<n.length;r++){const a=n[r].match(/^\\s*File "([^"]+)"/);if(a&&a[1].indexOf("/_pyodide/")===-1){i=r;break}}const s=i>1?[n[0]].concat(n.slice(i)):n,o=[];for(let r=0;r<s.length;r++){const a=s[r].match(/^\\s*File "[^"]*", line \\d+, in (.+)$/);if(a&&a[1]==="_pg_input"){for(;r+1<s.length&&/^ {4,}/.test(s[r+1]);)r++;continue}o.push(s[r])}t=o.join(\`
|
|
8
|
+
\`)}return t.split(MOUNT+"/").join("").replace(/\\s+$/,"")}async function importLoadPyodide(e){try{const t=await import(e+"pyodide.mjs");if(t&&t.loadPyodide)return t.loadPyodide}catch(t){if(typeof importScripts!="function")throw t}return importScripts(e+"pyodide.js"),self.loadPyodide}async function boot(e){post({type:"progress",phase:"booting",message:"Loading Python runtime"}),pyodide=await(await importLoadPyodide(e))({indexURL:e});const n=new TextDecoder,i=new TextDecoder;pyodide.setStdout({isatty:!0,write:o=>(writeOutput("stdout",n.decode(o,{stream:!0})),o.length)}),pyodide.setStderr({isatty:!0,write:o=>(writeOutput("stderr",i.decode(o,{stream:!0})),o.length)}),pyodide.setStdin({stdin:()=>{if(flushOutput(),stdinLines.length){const o=stdinLines.shift();return writeOutput("echo",o+\`
|
|
9
9
|
\`),o+\`
|
|
10
|
-
\`}return stdinExhausted=!0,null},autoEOF:!1});let
|
|
11
|
-
\`):[],stdinExhausted=!1,inputWaitMs=0;for(const
|
|
12
|
-
\`})}t=pyodide.runPython('dict(__name__="__main__")'),e.entry&&t.set("__file__",e.entry);const
|
|
10
|
+
\`}return stdinExhausted=!0,null},autoEOF:!1});let s=pyodide.version;try{s=pyodide.runPython("import sys; '.'.join(str(p) for p in sys.version_info[:3])")}catch{}if(internals=pyodide.runPython("dict()"),typeof WebAssembly.Suspending=="function")try{pyodide.runPython(INPUT_OVERRIDE,{globals:internals}),interactive=!0}catch{interactive=!1}post({type:"ready",version:s,interactiveStdin:interactive})}async function run(e){let t=null;currentId=e.id,stdinLines=e.stdin?String(e.stdin).replace(/\\n$/,"").split(\`
|
|
11
|
+
\`):[],stdinExhausted=!1,inputWaitMs=0,windowStart=-1/0;for(const i of pendingLines.values())i(null);pendingLines.clear();const n=performance.now();try{e.files&&syncFiles(e.files);try{await pyodide.loadPackagesFromImports(e.code,{messageCallback:r=>post({type:"progress",id:e.id,phase:"packages",message:r}),errorCallback:()=>{}})}catch(r){post({type:"stderr",id:e.id,text:"Could not auto-install packages: "+formatError(r)+\`
|
|
12
|
+
\`})}t=pyodide.runPython('dict(__name__="__main__")'),e.entry&&t.set("__file__",e.entry);const i={globals:t};e.entry&&(i.filename=MOUNT+"/"+e.entry);const s=await pyodide.runPythonAsync(e.code,i);flushStreams();let o;if(s!=null)try{t.set("_pg_last",s),o=pyodide.runPython("repr(_pg_last)",{globals:t})}catch{o=String(s)}s&&typeof s.destroy=="function"&&s.destroy(),post({type:"result",id:e.id,value:o,durationMs:performance.now()-n-inputWaitMs})}catch(i){flushStreams();const s=formatError(i);post({type:"error",id:e.id,message:s,hint:stdinExhausted&&s.indexOf("EOFError")!==-1?"input() asked for a line that standard input did not have. Add one line per input() call in the box above, then run again.":void 0,hintAbout:stdinExhausted&&s.indexOf("EOFError")!==-1?"stdin":void 0,durationMs:performance.now()-n-inputWaitMs})}finally{if(currentId=null,t){try{t.destroy()}catch{}t=null}}}self.onmessage=async e=>{const t=e.data;try{if(t.type==="init")await boot(t.indexURL);else if(t.type==="run")await run(t);else if(t.type==="stdin-response"){const n=pendingLines.get(t.request);n&&(pendingLines.delete(t.request),n(t.text===void 0?null:t.text))}}catch(n){post({type:"fatal",id:t&&t.id,message:formatError(n)})}};
|
|
13
13
|
`,r=new class extends t{id=`python`;get source(){return n}initPayload(){return{indexURL:e()}}get label(){return this.version?`Python ${this.version.split(`.`).slice(0,2).join(`.`)}`:`Python`}async editorLanguage(){let{python:e}=await import(`@codemirror/lang-python`);return e()}};export{r as pythonRuntime};
|
|
@@ -3,16 +3,16 @@
|
|
|
3
3
|
* Bundles CodeMirror 6 and Lezer (MIT) © Marijn Haverbeke and others.
|
|
4
4
|
* Full third-party licences: THIRD-PARTY-NOTICES.txt in this package.
|
|
5
5
|
*/
|
|
6
|
-
import{i as e}from"./config-
|
|
6
|
+
import{i as e}from"./config-DZqcFPEP.js";import{t}from"./worker-runtime-CmbgEzLA.js";var n=`let pyodide=null,stdinLines=[],stdinExhausted=!1,currentId=null,interactive=!1,inputWaitMs=0,nextRequest=1;const pendingLines=new Map,MOUNT="/home/pyodide/playground";let written=new Set,internals=null;const REFRESH=["import importlib, os, sys","MOUNT = "+JSON.stringify(MOUNT),"os.makedirs(MOUNT, exist_ok=True)","sys.path.insert(0, MOUNT) if MOUNT not in sys.path else None","os.chdir(MOUNT)","for _name, _mod in list(sys.modules.items()):",' _file = getattr(_mod, "__file__", None) or ""',' _paths = list(getattr(_mod, "__path__", None) or [])'," if _file.startswith(MOUNT) or any(str(p).startswith(MOUNT) for p in _paths):"," del sys.modules[_name]","importlib.invalidate_caches()"].join(\`
|
|
7
7
|
\`);function flushStreams(){try{pyodide.runPython(\`import sys
|
|
8
8
|
sys.stdout.flush()
|
|
9
9
|
sys.stderr.flush()\`,{globals:internals})}catch{}flushOutput()}const INPUT_OVERRIDE=["import builtins, sys, js","from pyodide.ffi import run_sync","",'def _pg_input(prompt=""):',' if prompt != "":'," sys.stdout.write(str(prompt))"," sys.stdout.flush()"," line = run_sync(js._pgReadLine())"," # Pyodide maps JS null to its own JsNull singleton, not None, so test"," # for what we want rather than for the several ways EOF can arrive."," if not isinstance(line, str):",' raise EOFError("EOF when reading a line")'," return line","",'_pg_input.__name__ = "input"','_pg_input.__qualname__ = "input"',"_pg_input.__doc__ = builtins.input.__doc__","builtins.input = _pg_input"].join(\`
|
|
10
|
-
\`);self._pgReadLine=async()=>{if(stdinLines.length){const
|
|
11
|
-
\`),
|
|
12
|
-
\`);if(/^Traceback/.test(n[0])){let
|
|
13
|
-
\`)}return t.split(MOUNT+"/").join("").replace(/\\s+$/,"")}async function importLoadPyodide(e){try{const t=await import(e+"pyodide.mjs");if(t&&t.loadPyodide)return t.loadPyodide}catch(t){if(typeof importScripts!="function")throw t}return importScripts(e+"pyodide.js"),self.loadPyodide}async function boot(e){post({type:"progress",phase:"booting",message:"Loading Python runtime"}),pyodide=await(await importLoadPyodide(e))({indexURL:e});const n=new TextDecoder,
|
|
10
|
+
\`);self._pgReadLine=async()=>{if(stdinLines.length){const i=stdinLines.shift();return writeOutput("echo",i+\`
|
|
11
|
+
\`),i}if(!interactive)return stdinExhausted=!0,null;const e=nextRequest++;flushOutput();const t=performance.now(),n=await new Promise(i=>{pendingLines.set(e,i),post({type:"stdin-request",id:currentId,request:e})});return inputWaitMs+=performance.now()-t,n===void 0?null:n};function syncFiles(e){const t=Object.keys(e);for(const n of written)if(t.indexOf(n)===-1)try{pyodide.FS.unlink(MOUNT+"/"+n)}catch{}written=new Set(t);for(const n of t){const i=MOUNT+"/"+n,s=i.slice(0,i.lastIndexOf("/"));pyodide.FS.mkdirTree(s),pyodide.FS.writeFile(i,e[n],{encoding:"utf8"})}pyodide.runPython(REFRESH,{globals:internals})}function post(e){self.postMessage(e)}const FLUSH_BYTES=8192,FLUSH_MS=16,EAGER_POSTS=32;let outputQueue=[],queuedChars=0,windowStart=-1/0,windowPosts=0;function writeOutput(e,t){const n=outputQueue[outputQueue.length-1];n&&n.type===e?n.text+=t:outputQueue.push({type:e,text:t}),queuedChars+=t.length;const i=performance.now();i-windowStart>=FLUSH_MS&&(windowStart=i,windowPosts=0),(windowPosts<EAGER_POSTS||queuedChars>=FLUSH_BYTES)&&flushOutput()}function flushOutput(){if(!outputQueue.length)return;windowPosts++;const e=outputQueue;outputQueue=[],queuedChars=0;for(const t of e)post({type:t.type,id:currentId,text:t.text})}function formatError(e){let t=e&&e.message?e.message:String(e);const n=t.split(\`
|
|
12
|
+
\`);if(/^Traceback/.test(n[0])){let i=-1;for(let r=1;r<n.length;r++){const a=n[r].match(/^\\s*File "([^"]+)"/);if(a&&a[1].indexOf("/_pyodide/")===-1){i=r;break}}const s=i>1?[n[0]].concat(n.slice(i)):n,o=[];for(let r=0;r<s.length;r++){const a=s[r].match(/^\\s*File "[^"]*", line \\d+, in (.+)$/);if(a&&a[1]==="_pg_input"){for(;r+1<s.length&&/^ {4,}/.test(s[r+1]);)r++;continue}o.push(s[r])}t=o.join(\`
|
|
13
|
+
\`)}return t.split(MOUNT+"/").join("").replace(/\\s+$/,"")}async function importLoadPyodide(e){try{const t=await import(e+"pyodide.mjs");if(t&&t.loadPyodide)return t.loadPyodide}catch(t){if(typeof importScripts!="function")throw t}return importScripts(e+"pyodide.js"),self.loadPyodide}async function boot(e){post({type:"progress",phase:"booting",message:"Loading Python runtime"}),pyodide=await(await importLoadPyodide(e))({indexURL:e});const n=new TextDecoder,i=new TextDecoder;pyodide.setStdout({isatty:!0,write:o=>(writeOutput("stdout",n.decode(o,{stream:!0})),o.length)}),pyodide.setStderr({isatty:!0,write:o=>(writeOutput("stderr",i.decode(o,{stream:!0})),o.length)}),pyodide.setStdin({stdin:()=>{if(flushOutput(),stdinLines.length){const o=stdinLines.shift();return writeOutput("echo",o+\`
|
|
14
14
|
\`),o+\`
|
|
15
|
-
\`}return stdinExhausted=!0,null},autoEOF:!1});let
|
|
16
|
-
\`):[],stdinExhausted=!1,inputWaitMs=0;for(const
|
|
17
|
-
\`})}t=pyodide.runPython('dict(__name__="__main__")'),e.entry&&t.set("__file__",e.entry);const
|
|
15
|
+
\`}return stdinExhausted=!0,null},autoEOF:!1});let s=pyodide.version;try{s=pyodide.runPython("import sys; '.'.join(str(p) for p in sys.version_info[:3])")}catch{}if(internals=pyodide.runPython("dict()"),typeof WebAssembly.Suspending=="function")try{pyodide.runPython(INPUT_OVERRIDE,{globals:internals}),interactive=!0}catch{interactive=!1}post({type:"ready",version:s,interactiveStdin:interactive})}async function run(e){let t=null;currentId=e.id,stdinLines=e.stdin?String(e.stdin).replace(/\\n$/,"").split(\`
|
|
16
|
+
\`):[],stdinExhausted=!1,inputWaitMs=0,windowStart=-1/0;for(const i of pendingLines.values())i(null);pendingLines.clear();const n=performance.now();try{e.files&&syncFiles(e.files);try{await pyodide.loadPackagesFromImports(e.code,{messageCallback:r=>post({type:"progress",id:e.id,phase:"packages",message:r}),errorCallback:()=>{}})}catch(r){post({type:"stderr",id:e.id,text:"Could not auto-install packages: "+formatError(r)+\`
|
|
17
|
+
\`})}t=pyodide.runPython('dict(__name__="__main__")'),e.entry&&t.set("__file__",e.entry);const i={globals:t};e.entry&&(i.filename=MOUNT+"/"+e.entry);const s=await pyodide.runPythonAsync(e.code,i);flushStreams();let o;if(s!=null)try{t.set("_pg_last",s),o=pyodide.runPython("repr(_pg_last)",{globals:t})}catch{o=String(s)}s&&typeof s.destroy=="function"&&s.destroy(),post({type:"result",id:e.id,value:o,durationMs:performance.now()-n-inputWaitMs})}catch(i){flushStreams();const s=formatError(i);post({type:"error",id:e.id,message:s,hint:stdinExhausted&&s.indexOf("EOFError")!==-1?"input() asked for a line that standard input did not have. Add one line per input() call in the box above, then run again.":void 0,hintAbout:stdinExhausted&&s.indexOf("EOFError")!==-1?"stdin":void 0,durationMs:performance.now()-n-inputWaitMs})}finally{if(currentId=null,t){try{t.destroy()}catch{}t=null}}}self.onmessage=async e=>{const t=e.data;try{if(t.type==="init")await boot(t.indexURL);else if(t.type==="run")await run(t);else if(t.type==="stdin-response"){const n=pendingLines.get(t.request);n&&(pendingLines.delete(t.request),n(t.text===void 0?null:t.text))}}catch(n){post({type:"fatal",id:t&&t.id,message:formatError(n)})}};
|
|
18
18
|
`,r=new class extends t{id=`python`;get source(){return n}initPayload(){return{indexURL:e()}}get label(){return this.version?`Python ${this.version.split(`.`).slice(0,2).join(`.`)}`:`Python`}async editorLanguage(){let{python:e}=await import(`./dist-D_qJovVA.js`);return e()}};export{r as pythonRuntime};
|
package/dist/react.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{n as e}from"./element-
|
|
1
|
+
import{n as e}from"./element-BYcX5Z6z.js";import{useEffect as t,useRef as n}from"react";import{jsx as r}from"react/jsx-runtime";e();function i({code:e=``,files:i,entry:a,stdin:o,language:s=`python`,height:c,minHeight:l,maxHeight:u,theme:d=`auto`,readOnly:f,autoRun:p,persist:m,className:h,style:g,onReady:_,onRun:v,onOutput:y,onError:b}){let x=n(null),S=n({onReady:_,onRun:v,onOutput:y,onError:b});S.current={onReady:_,onRun:v,onOutput:y,onError:b},t(()=>{let e=x.current;if(!e)return;let t=(t,n)=>{let r=e=>n(S.current)?.(e.detail);return e.addEventListener(t,r),()=>e.removeEventListener(t,r)},n=[t(`py-ready`,e=>e.onReady),t(`py-run`,e=>e.onRun),t(`py-output`,e=>e.onOutput),t(`py-error`,e=>e.onError)];return()=>n.forEach(e=>e())},[]);let C=i?JSON.stringify(i):null;return t(()=>{let t=x.current;t&&(C?t.files=JSON.parse(C):e!==t.code&&(t.code=e))},[e,C]),t(()=>{x.current&&o!==void 0&&(x.current.stdin=o)},[o]),r(`code-playpad`,{ref:x,language:s,theme:d,class:h,style:g,...c===void 0?{}:{height:String(c)},...l===void 0?{}:{"min-height":String(l)},...u===void 0?{}:{"max-height":String(u)},...f?{readonly:``}:{},...p?{autorun:``}:{},...m?{persist:m}:{},...a?{entry:a}:{},children:i?null:e})}export{i as CodePlayPad,i as default};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Result } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Results whose `hint` is about standard input ("input() asked for a line
|
|
4
|
+
* that standard input did not have"). The widget opens the stdin box for
|
|
5
|
+
* those, and only those: a hint about a runaway loop or a memory limit has
|
|
6
|
+
* nothing to do with input.
|
|
7
|
+
*
|
|
8
|
+
* A module of its own, so the widget can read it without statically pulling
|
|
9
|
+
* the worker runtime into its bundle. Not part of the public API.
|
|
10
|
+
*/
|
|
11
|
+
export declare const inputHints: WeakSet<Result>;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare const JAVA_ENGINE: {
|
|
2
|
+
readonly name: "java-online-compiler";
|
|
3
|
+
readonly version: "0.3.0";
|
|
4
|
+
readonly commit: "c9ef6de64c7ff079d89bc7251713d0f5b934b6c0";
|
|
5
|
+
readonly dirty: false;
|
|
6
|
+
readonly sha256: "7d02f896fcb6b58128f8be4104284404e4910630a850bfd36004433bef36b770";
|
|
7
|
+
};
|
|
8
|
+
export declare const JAVA_WORKER_SOURCE: string;
|
|
@@ -44,6 +44,7 @@ export type WorkerMessage = {
|
|
|
44
44
|
id: number;
|
|
45
45
|
message: string;
|
|
46
46
|
hint?: string;
|
|
47
|
+
hintAbout?: 'stdin';
|
|
47
48
|
durationMs: number;
|
|
48
49
|
} | {
|
|
49
50
|
type: 'fatal';
|
|
@@ -62,10 +63,19 @@ export declare abstract class WorkerRuntime {
|
|
|
62
63
|
load(onProgress?: (p: LoadProgress) => void): Promise<void>;
|
|
63
64
|
run(code: string, options?: RunOptions): Promise<Result>;
|
|
64
65
|
/**
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
66
|
+
* Stop one run, or — with no argument — whatever is running.
|
|
67
|
+
*
|
|
68
|
+
* Pass the promise run() returned to cancel only that run. If it is still
|
|
69
|
+
* queued, or waiting for the worker to boot, it is dropped and rejects with
|
|
70
|
+
* RunStopped; nothing else is touched. Only if its code is already in the
|
|
71
|
+
* worker is the worker killed and rebooted: user code that never yields
|
|
72
|
+
* cannot be interrupted cooperatively without SharedArrayBuffer (which needs
|
|
73
|
+
* site-wide COOP/COEP). A run that has already finished is a no-op.
|
|
74
|
+
*
|
|
75
|
+
* With no argument (the original behaviour), the worker is killed and the
|
|
76
|
+
* active run fails, whoever owns it. Either way, queued runs survive and
|
|
77
|
+
* execute on the fresh worker.
|
|
68
78
|
*/
|
|
69
|
-
stop(): void;
|
|
79
|
+
stop(run?: Promise<Result>): void;
|
|
70
80
|
abstract get label(): string;
|
|
71
81
|
}
|
package/dist/standalone.d.ts
CHANGED
|
@@ -3,9 +3,13 @@
|
|
|
3
3
|
* page needs one script tag and no import map.
|
|
4
4
|
*
|
|
5
5
|
* Pyodide is still fetched at runtime and never bundled — that is the whole
|
|
6
|
-
* reason this file is ~100KB gzipped instead of
|
|
6
|
+
* reason this file is ~100KB gzipped instead of ~6MB.
|
|
7
7
|
*
|
|
8
|
-
* <script type="module" src="https://cdn.jsdelivr.net/npm/code-playpad"></script>
|
|
8
|
+
* <script type="module" src="https://cdn.jsdelivr.net/npm/code-playpad@0.3.1/dist/standalone.js"></script>
|
|
9
|
+
*
|
|
10
|
+
* The bare package URL works too from 0.3.1: jsDelivr serves dist/cdn.js
|
|
11
|
+
* there, which re-exports this file by absolute URL (see
|
|
12
|
+
* vite.standalone.config.ts).
|
|
9
13
|
* <code-playpad>print("hi")</code-playpad>
|
|
10
14
|
*
|
|
11
15
|
* Prefer the "." entry (with CodeMirror as peer dependencies) if you already
|
package/dist/standalone.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Bundles CodeMirror 6 and Lezer (MIT) © Marijn Haverbeke and others.
|
|
4
4
|
* Full third-party licences: THIRD-PARTY-NOTICES.txt in this package.
|
|
5
5
|
*/
|
|
6
|
-
import{
|
|
6
|
+
import{n as e,r as t,t as n}from"./hints-v5iHTd1l.js";import{n as r,o as i,r as a,t as o}from"./config-DZqcFPEP.js";async function s(e){try{return await c(e)}catch(t){return console.warn(`[code-playpad] CodeMirror unavailable, using plain textarea:`,t),l(e)}}async function c(e){let[t,n,r,i,a,o]=await Promise.all([import(`./dist-BThnYaQ5.js`).then(e=>e.s),import(`./dist-DOsLUKSb.js`).then(e=>e.x),import(`./dist-CnC1nMtN.js`),import(`./dist-D0FPZcUi.js`),import(`./dist-DmrP6yta.js`),import(`./dist-DlIO0dzi.js`)]),{EditorView:s,keymap:c,lineNumbers:l,highlightActiveLine:u,highlightActiveLineGutter:d,highlightSpecialChars:f,drawSelection:p,rectangularSelection:m,crosshairCursor:h}=t,{EditorState:g,Compartment:_}=n,{defaultKeymap:v,history:y,historyKeymap:b,indentWithTab:x}=r,{syntaxHighlighting:S,defaultHighlightStyle:C,indentOnInput:w,bracketMatching:T,foldGutter:E,foldKeymap:D}=i,{autocompletion:O,closeBrackets:k,closeBracketsKeymap:A,completionKeymap:j}=a,M=new _,N=new _,P=new _,F=[s.theme({"&":{color:`#1f2328`,backgroundColor:`#ffffff`},".cm-gutters":{backgroundColor:`#f6f8fa`,color:`#8b949e`,border:`none`},".cm-activeLine":{backgroundColor:`#f6f8fa88`},".cm-activeLineGutter":{backgroundColor:`#eaeef2`},".cm-cursor":{borderLeftColor:`#1f2328`},"&.cm-focused .cm-selectionBackground, .cm-selectionBackground, ::selection":{backgroundColor:`#cfe3ff`}}),S(C,{fallback:!0})],I=e=>e?o.oneDark:F,L=c.of([{key:`Mod-Enter`,preventDefault:!0,run:()=>(e.onRun?.(),!0)},{key:`Shift-Enter`,preventDefault:!0,run:()=>(e.onRun?.(),!0)}]),R=e.dark,z=e.readOnly,B=e.language??[],V=t=>g.create({doc:t,extensions:[l(),d(),f(),y(),E(),p(),g.allowMultipleSelections.of(!0),w(),T(),k(),O(),m(),h(),u(),L,c.of([...A,...v,...b,...D,...j,x]),s.lineWrapping,P.of(B),M.of(I(R)),N.of(g.readOnly.of(z)),s.updateListener.of(t=>{t.docChanged&&e.onChange?.(t.state.doc.toString())})]}),H=new s({parent:e.parent,state:V(e.doc)}),U=new Map,W=e.name??``;return{fallback:!1,getCode:()=>H.state.doc.toString(),setCode(e){H.dispatch({changes:{from:0,to:H.state.doc.length,insert:e}})},openFile(e,t){if(e===W)return;U.set(W,H.state);let n=U.get(e);H.setState(n??V(t)),W=e,n&&H.dispatch({effects:[M.reconfigure(I(R)),N.reconfigure(g.readOnly.of(z)),P.reconfigure(B)]})},fileCode(e,t){if(e===W)return H.state.doc.toString();let n=U.get(e);return n?n.doc.toString():t},forgetFiles(e){for(let t of[...U.keys()])e.includes(t)||U.delete(t)},setTheme(e){R=e,H.dispatch({effects:M.reconfigure(I(R))})},setReadOnly(e){z=e,H.dispatch({effects:N.reconfigure(g.readOnly.of(z))})},setLanguage(e){B=e,H.dispatch({effects:P.reconfigure(B)})},focus:()=>H.focus(),destroy:()=>H.destroy()}}function l(e){let t=document.createElement(`textarea`);t.className=`cp-fallback-editor`,t.spellcheck=!1,t.value=e.doc,t.readOnly=e.readOnly,t.addEventListener(`input`,()=>e.onChange?.(t.value)),t.addEventListener(`keydown`,t=>{(t.metaKey||t.ctrlKey)&&t.key===`Enter`&&(t.preventDefault(),e.onRun?.())}),e.parent.appendChild(t);let n=new Map,r=e.name??``;return{fallback:!0,getCode:()=>t.value,setCode:e=>{t.value=e},openFile(e,i){e!==r&&(n.set(r,t.value),t.value=n.get(e)??i,r=e)},fileCode(e,i){return e===r?t.value:n.get(e)??i},forgetFiles(e){for(let t of[...n.keys()])e.includes(t)||n.delete(t)},setTheme:()=>{},setReadOnly:e=>{t.readOnly=e},setLanguage:()=>{},focus:()=>t.focus(),destroy:()=>t.remove()}}var u=new Map,d=new Map;function f(e,t){u.set(e,t)}function p(){return[...u.keys()]}function m(e){let t=d.get(e);if(t)return t;let n=u.get(e);if(!n)return Promise.reject(Error(`Unknown runtime "${e}". Registered: ${p().join(`, `)||`none`}`));let r=n().catch(t=>{throw d.delete(e),t});return d.set(e,r),r}f(`python`,()=>import(`./pyodide-j1wg1W9_.js`).then(e=>e.pythonRuntime)),f(`javascript`,()=>import(`./javascript-BhISU47e.js`).then(e=>e.javascriptRuntime)),f(`typescript`,()=>import(`./javascript-BhISU47e.js`).then(e=>e.typescriptRuntime)),f(`java`,()=>import(`./java-DSEX5tzl.js`).then(e=>e.javaRuntime));var h=String.raw`
|
|
7
7
|
:host {
|
|
8
8
|
--cp-bg: #ffffff;
|
|
9
9
|
--cp-fg: #1f2328;
|
|
@@ -299,12 +299,12 @@ table.cp-table th { background: var(--cp-bg); }
|
|
|
299
299
|
@media (prefers-reduced-motion: reduce) {
|
|
300
300
|
.cp-progress { animation: none; background-position: 0 0; background-size: 100% 100%; opacity: 0.4; }
|
|
301
301
|
}
|
|
302
|
-
`,
|
|
302
|
+
`,g=e=>()=>import(`./dist-CqpVTRAq.js`).then(t=>t.javascript(e)),_={py:()=>import(`./dist-D_qJovVA.js`).then(e=>e.python()),pyi:()=>import(`./dist-D_qJovVA.js`).then(e=>e.python()),js:g({}),mjs:g({}),cjs:g({}),jsx:g({jsx:!0}),ts:g({typescript:!0}),mts:g({typescript:!0}),cts:g({typescript:!0}),tsx:g({typescript:!0,jsx:!0}),json:()=>import(`./dist-XlpaG2JF.js`).then(e=>e.json()),java:()=>import(`./dist-BKRQwpg6.js`).then(e=>e.java())};async function v(e){let t=_[e.includes(`.`)?e.slice(e.lastIndexOf(`.`)+1).toLowerCase():``];return t?t().catch(()=>null):null}var y=`code-playpad`,b=1,x=`snippets`,S=`progress`,C=null;function w(){return typeof indexedDB>`u`?Promise.reject(Error(`IndexedDB unavailable`)):(C||=new Promise((e,t)=>{let n=indexedDB.open(y,b);n.onupgradeneeded=()=>{let e=n.result;e.objectStoreNames.contains(x)||e.createObjectStore(x),e.objectStoreNames.contains(S)||e.createObjectStore(S,{keyPath:`id`})},n.onsuccess=()=>e(n.result),n.onerror=()=>t(n.error)}).catch(e=>{throw C=null,e}),C)}function T(e,t,n){return w().then(r=>new Promise((i,a)=>{let o=n(r.transaction(e,t).objectStore(e));o.onsuccess=()=>i(o.result),o.onerror=()=>a(o.error)}))}function E(e,t){return T(x,`readwrite`,n=>n.put(t,e)).then(()=>void 0)}function D(e){return T(x,`readonly`,t=>t.get(e)).then(e=>e??null)}function O(e){return T(x,`readwrite`,t=>t.delete(e)).then(()=>void 0)}function k(e,t={}){let n={completed:!0,...t,id:e,updatedAt:Date.now()};return T(S,`readwrite`,e=>e.put(n)).then(()=>n)}function A(e){return T(S,`readonly`,t=>t.get(e)).then(e=>e??null)}function j(){return T(S,`readonly`,e=>e.getAll())}var M=`code-playpad`;function N(e){let t=e.replace(/\t/g,` `).split(`
|
|
303
303
|
`);for(;t.length&&t[0].trim()===``;)t.shift();for(;t.length&&t[t.length-1].trim()===``;)t.pop();let n=t.filter(e=>e.trim()!==``).reduce((e,t)=>Math.min(e,t.match(/^ */)[0].length),1/0);return(n===1/0?t:t.map(e=>e.slice(n))).join(`
|
|
304
|
-
`)}var
|
|
304
|
+
`)}var P=2e5,F=`playpad-file`,I={python:`main.py`,javascript:`main.js`,typescript:`main.ts`,java:`Main.java`};function L(e){return I[e]??`main.txt`}function R(e,t){let n={};for(let t of e.children){if(t.tagName.toLowerCase()!==F)continue;let e=t.getAttribute(`name`);e&&(n[e]=N(t.textContent??``))}if(Object.keys(n).length)return n;let r=[...e.childNodes].filter(e=>e.nodeType!==Node.ELEMENT_NODE||e.tagName.toLowerCase()!==F),i=r.some(e=>e.nodeType===Node.ELEMENT_NODE),a=N(r.filter(e=>!(i&&e.nodeType===Node.TEXT_NODE&&!(e.textContent??``).trim())).map(e=>e.textContent??``).join(``));return{[t]:a}}function z(e,t){try{let t=JSON.parse(e);if(t&&typeof t==`object`&&!Array.isArray(t)){let e=t;return Object.keys(e).length?e:null}}catch{}return e?{[t]:e}:null}var B=typeof HTMLElement>`u`?class{}:HTMLElement,V=class extends B{static get observedAttributes(){return[`language`,`height`,`min-height`,`max-height`,`theme`,`readonly`,`autorun`,`stdin`,`persist`,`entry`]}#e;#t;#n;#r;#i;#a;#o;#s;#c;#l;#u=null;#d=null;#f=null;#p=null;#m={};#h={};#g=`main.py`;#_=null;#v;#y=!1;#b=null;#x=!1;#S=!1;#C=null;#w=null;#T=null;#E=()=>this.#K();#D=null;#O=!0;#k=[];#A=null;#j=null;#M=null;#N=0;#P=!1;constructor(){super(),this.#e=this.attachShadow({mode:`open`})}get code(){return this.#u?this.#u.getCode():this.#m[this.#g]??``}set code(e){this.#m[this.#g]=e,this.#B()}get files(){return this.#H()}set files(e){let t=Object.keys(e);if(!t.length)return;let n=Object.keys(this.#h);n.length===1&&!this.#h[n[0]]&&(this.#h={...e}),this.#m={...e},t.includes(this.#g)||(this.#g=this.#V()),this.#u?.forgetFiles([]),this.#B(),this.#U(),this.#z()}get entry(){return this.#V()}set entry(e){this.setAttribute(`entry`,e)}openFile(e){e in this.#m&&(this.#u&&(this.#m[this.#g]=this.#u.getCode(),this.#u.openFile(e,this.#m[e]??``)),this.#g=e,this.#U(),this.#z())}get stdin(){return this.#l?this.#l.value:``}set stdin(e){this.#l&&(this.#l.value=e,this.#c.hidden=!1)}get language(){return this.getAttribute(`language`)||`python`}set language(e){this.setAttribute(`language`,e)}getCode(){return this.code}getFiles(){return this.#H()}reset(){this.#m={...this.#h},this.#g=this.#V(),this.#u?.forgetFiles([]),this.#B(),this.#U(),this.#Y(),this.#s.hidden=!0,this.#J(this.#f?.ready?`${this.#f.label} ready`:``,`idle`)}async run(){if(this.#y)return;await this.#d;let t=this.#H(),r=this.#V(),i=t[r]??``;this.#y=!0,this.#x=!1,this.#n.disabled=!0,this.#r.hidden=!1,this.#Y(),this.#s.hidden=!1,this.#ne(`py-run`,{code:i,entry:r,files:t,language:this.language});try{let a=await this.#R();if(this.#x)throw new e;this.#J(`Queued…`,`busy`),this.#o.hidden=!1;let o=a.run(i,{stdin:this.#l.value,files:t,entry:r,onStart:()=>this.#J(`Running…`,`busy`),onStdout:e=>this.#X(e),onStderr:e=>this.#X(e,`cp-err`),onEcho:e=>this.#X(e,`cp-in`),onStdinRequest:()=>this.#Q()});this.#b={runtime:a,run:o};let s=await o;return s.table&&this.#te(s.table),s.value!==void 0&&this.#X(`${s.value}\n`,`cp-value`),s.hint&&this.#ee(s.hint,n.has(s)),s.stderr?(this.#J(`Error · ${s.durationMs} ms`,`error`),this.#ne(`py-error`,{message:s.stderr,hint:s.hint,language:this.language})):this.#J(`Done in ${s.durationMs} ms`,`ok`),this.#ne(`py-output`,{...s,language:this.language}),s}catch(t){if(t instanceof e)this.#X(`
|
|
305
305
|
[stopped]
|
|
306
|
-
`,`cp-err`),this.#
|
|
307
|
-
`,`cp-err`),this.#
|
|
306
|
+
`,`cp-err`),this.#J(`Stopped`,`error`);else{let e=t instanceof Error?t.message:String(t);this.#X(e+`
|
|
307
|
+
`,`cp-err`),this.#J(`Failed to start`,`error`),this.#ne(`py-error`,{message:e,language:this.language})}return}finally{this.#b=null,this.#$(null),this.#Z(),this.#y=!1,this.#n.disabled=!1,this.#r.hidden=!0,this.#o.hidden=!0}}stop(){this.#b?this.#b.runtime.stop?.(this.#b.run):this.#y&&(this.#x=!0)}prewarm(){return this.#R()}connectedCallback(){if(this.#P){this.#L();return}if(!this.textContent?.trim()&&document.readyState===`loading`){document.addEventListener(`DOMContentLoaded`,()=>this.isConnected&&this.#F(),{once:!0});return}this.#F()}disconnectedCallback(){this.#C?.disconnect(),this.#C=null,this.#w?.removeEventListener(`change`,this.#E),this.#w=null,this.#T?.disconnect(),this.#T=null,this.#D&&clearTimeout(this.#D),this.#$(null),setTimeout(()=>{this.isConnected||!this.#u||(this.#_=this.#H(),this.#u.destroy(),this.#u=null,this.#d=null,this.#P=!1)},0)}attributeChangedCallback(e,t,n){if(this.#P)switch(e){case`theme`:this.#K();break;case`height`:case`min-height`:case`max-height`:this.#q();break;case`readonly`:this.#u?.setReadOnly(n!==null);break;case`stdin`:this.#c.hidden=n===null&&!this.#l.value;break;case`entry`:this.#U();break;case`language`:this.#f=null,this.#p=null,this.#S=!1,this.#R().catch(()=>{})}}#F(){this.#P=!0,this.#h=R(this,L(this.language)),this.#m=this.#_??{...this.#h},this.#g=this.#V(),this.#I(),this.#K(),this.#q();let e=this.getAttribute(`persist`);this.#d=(async()=>{if(e&&this.#_==null){let t=await D(e).catch(()=>null),n=t==null?null:z(t,L(this.language));if(n){let e={};for(let t of Object.keys(this.#h))e[t]=n[t]??this.#h[t];this.#m=e,this.#g=this.#V()}}this.#U();let t=await m(this.language).catch(()=>null),n=t?await t.editorLanguage().catch(()=>null):null;this.#u=await s({parent:this.#t,doc:this.#m[this.#g]??``,name:this.#g,dark:this.#G(),readOnly:this.hasAttribute(`readonly`),language:n,onRun:()=>void this.run(),onChange:e=>this.#W(e)}),this.#_=null,this.#z()})(),this.#L()}#I(){let e=document.createElement(`style`);e.textContent=h;let t=document.createElement(`div`);t.className=`cp-root`,t.innerHTML=`
|
|
308
308
|
<div class="cp-toolbar">
|
|
309
309
|
<button class="cp-primary" part="run-button" data-action="run">Run</button>
|
|
310
310
|
<button class="cp-danger" part="stop-button" data-action="stop" hidden>Stop</button>
|
|
@@ -319,10 +319,10 @@ table.cp-table th { background: var(--cp-bg); }
|
|
|
319
319
|
<label>Standard input — one value per line</label>
|
|
320
320
|
<textarea rows="2" spellcheck="false"></textarea>
|
|
321
321
|
</div>
|
|
322
|
-
<pre class="cp-output" part="output" hidden></pre>`,this.#e.replaceChildren(e,t),this.#n=t.querySelector(`[data-action="run"]`),this.#r=t.querySelector(`[data-action="stop"]`),this.#i=t.querySelector(`[data-action="reset"]`),this.#a=t.querySelector(`.cp-status`),this.#o=t.querySelector(`.cp-progress`),this.#v=t.querySelector(`.cp-tabs`),this.#t=t.querySelector(`.cp-editor`),this.#c=t.querySelector(`.cp-stdin`),this.#l=t.querySelector(`.cp-stdin textarea`),this.#s=t.querySelector(`.cp-output`),this.#c.hidden=!this.hasAttribute(`stdin`),this.#l.addEventListener(`input`,()=>this.#c.classList.remove(`cp-attention`)),this.#v.addEventListener(`click`,e=>{let t=e.target.closest(`button[data-file]`);t&&this.openFile(t.getAttribute(`data-file`))}),this.#n.addEventListener(`click`,()=>void this.run()),this.#r.addEventListener(`click`,()=>this.stop()),this.#i.addEventListener(`click`,()=>this.reset());let n=()=>void this.#
|
|
323
|
-
`,`cp-err`),this.#s.hidden=!1,e}finally{this.#o.hidden=!0}return this.#
|
|
324
|
-
`),this.#
|
|
322
|
+
<pre class="cp-output" part="output" hidden></pre>`,this.#e.replaceChildren(e,t),this.#n=t.querySelector(`[data-action="run"]`),this.#r=t.querySelector(`[data-action="stop"]`),this.#i=t.querySelector(`[data-action="reset"]`),this.#a=t.querySelector(`.cp-status`),this.#o=t.querySelector(`.cp-progress`),this.#v=t.querySelector(`.cp-tabs`),this.#t=t.querySelector(`.cp-editor`),this.#c=t.querySelector(`.cp-stdin`),this.#l=t.querySelector(`.cp-stdin textarea`),this.#s=t.querySelector(`.cp-output`),this.#c.hidden=!this.hasAttribute(`stdin`),this.#l.addEventListener(`input`,()=>this.#c.classList.remove(`cp-attention`)),this.#v.addEventListener(`click`,e=>{let t=e.target.closest(`button[data-file]`);t&&this.openFile(t.getAttribute(`data-file`))}),this.#n.addEventListener(`click`,()=>void this.run()),this.#r.addEventListener(`click`,()=>this.stop()),this.#i.addEventListener(`click`,()=>this.reset());let n=()=>void this.#R().catch(()=>{});this.#t.addEventListener(`pointerdown`,n,{once:!0}),this.#t.addEventListener(`focusin`,n,{once:!0})}#L(){this.#C||typeof IntersectionObserver>`u`||(this.#C=new IntersectionObserver(e=>{e.some(e=>e.isIntersecting)&&(this.#C?.disconnect(),this.#C=null,this.#R().then(()=>{this.hasAttribute(`autorun`)&&this.run()}).catch(()=>{}))},{rootMargin:`300px`}),this.#C.observe(this))}#R(){return this.#p||=(async()=>{let e=await m(this.language);this.#f=e,e.ready||(this.#o.hidden=!1,this.#J(`Loading ${e.label}…`,`busy`));try{await e.load(e=>{this.#y||this.#J(e.message,e.phase===`ready`?`ok`:`busy`)})}catch(e){this.#p=null,this.#J(`Runtime unavailable`,`error`);let t=e instanceof Error?e.message:String(e);throw this.#X(t+`
|
|
323
|
+
`,`cp-err`),this.#s.hidden=!1,e}finally{this.#o.hidden=!0}return this.#z(),this.#S||(this.#S=!0,this.#J(`${e.label} ready`,`ok`),this.#ne(`py-ready`,{language:e.id,label:e.label})),e})(),this.#p}async#z(){if(!this.#u)return;let e=this.#g,t=await v(e);if(t){this.#g===e&&this.#u?.setLanguage(t);return}let n=e.includes(`.`)?null:await(this.#f??await m(this.language).catch(()=>null))?.editorLanguage().catch(()=>null);this.#g===e&&this.#u?.setLanguage(n??[])}#B(){if(this.#u){this.#u.setCode(this.#m[this.#g]??``);return}this.#d?.then(()=>{this.#u?.setCode(this.#m[this.#g]??``),this.#U()})}#V(){let e=Object.keys(this.#m),t=this.getAttribute(`entry`);if(t&&e.includes(t))return t;let n=L(this.language);return e.includes(n)?n:e[0]??n}#H(){let e={...this.#m};if(this.#u)for(let t of Object.keys(e))e[t]=this.#u.fileCode(t,e[t]);return e}#U(){let e=Object.keys(this.#m);if(this.#v.hidden=e.length<2,this.#v.hidden){this.#v.replaceChildren();return}let t=this.#V();this.#v.replaceChildren(...e.map(e=>{let n=document.createElement(`button`);return n.dataset.file=e,n.textContent=e,n.setAttribute(`aria-pressed`,String(e===this.#g)),e===t&&(n.classList.add(`cp-entry`),n.title=`entry point — this is the file Run executes`),n}))}#W(e){this.#m[this.#g]=e;let t=this.getAttribute(`persist`);if(!t)return;this.#D&&clearTimeout(this.#D);let n=JSON.stringify(this.#H());this.#D=setTimeout(()=>void E(t,n).catch(()=>{}),400)}#G(){let e=this.getAttribute(`theme`)??`auto`;if(e===`dark`)return!0;if(e===`light`)return!1;let t=typeof document>`u`?``:getComputedStyle(document.documentElement).colorScheme,n=t.includes(`dark`);return n===t.includes(`light`)?!!this.#w?.matches:n}#K(){!this.#w&&typeof matchMedia==`function`&&(this.#w=matchMedia(`(prefers-color-scheme: dark)`),this.#w.addEventListener(`change`,this.#E)),!this.#T&&typeof MutationObserver==`function`&&typeof document<`u`&&(this.#T=new MutationObserver(this.#E),this.#T.observe(document.documentElement,{attributes:!0,attributeFilter:[`class`,`style`,`data-theme`,`data-color-scheme`,`color-scheme`]}));let e=this.#G();this.setAttribute(`data-resolved-theme`,e?`dark`:`light`),this.#u?.setTheme(e)}#q(){for(let[e,t]of[[`height`,`--cp-height`],[`min-height`,`--cp-min-height`],[`max-height`,`--cp-max-height`]]){let n=this.getAttribute(e);n===null||n===``?this.style.removeProperty(t):this.style.setProperty(t,/^\d+$/.test(n)?`${n}px`:n)}}#J(e,t){this.#a.textContent=e,this.#a.dataset.state=t}#Y(){this.#M&&clearTimeout(this.#M),this.#M=null,this.#k=[],this.#N=0,this.#s.replaceChildren(),this.#O=!0}#X(e,t){if(!e)return;let n=t===`cp-err`&&!this.#O?`\n${e}`:e;this.#O=n.endsWith(`
|
|
324
|
+
`),this.#k.push({text:n,className:t}),this.#M??=setTimeout(()=>this.#Z(),16)}#Z(){if(this.#M&&clearTimeout(this.#M),this.#M=null,!this.#k.length)return;let e=this.#k;this.#k=[];let t=document.createDocumentFragment(),n=``,r,i=()=>{if(!n)return;let e=document.createElement(`span`);r&&(e.className=r),e.textContent=n,t.appendChild(e),n=``};for(let t of e){if(this.#N>=P)break;let e=t.text;this.#N+e.length>P&&(e=e.slice(0,P-this.#N)+`
|
|
325
325
|
… output truncated for display — the full text is in the py-output event
|
|
326
|
-
`),this.#
|
|
327
|
-
`,`cp-in`):this.#
|
|
328
|
-
`,`cp-in`),this.#
|
|
326
|
+
`),this.#N+=t.text.length,r!==t.className&&(i(),r=t.className),n+=e}i(),this.#s.hidden=!1;let a=this.#s.querySelector(`.cp-prompt`);a?this.#s.insertBefore(t,a):this.#s.appendChild(t),this.#s.scrollTop=this.#s.scrollHeight}#Q(){return this.#Z(),this.#$(null),new Promise(e=>{let t=document.createElement(`form`);t.className=`cp-prompt`;let n=document.createElement(`input`);n.type=`text`,n.setAttribute(`aria-label`,`Program input — press Enter to send`),n.autocapitalize=`off`,n.autocomplete=`off`,n.spellcheck=!1;let r=document.createElement(`button`);r.type=`submit`,r.className=`cp-send`,r.textContent=`⏎`,r.title=`Send this line (Enter)`;let i=document.createElement(`button`);i.type=`button`,i.className=`cp-eof`,i.textContent=`EOF`,i.title=`End of input (Ctrl-D) — makes input() raise EOFError`;let a=n=>{this.#A===e&&(this.#A=null,this.#j=null,t.remove(),n===null?this.#X(`
|
|
327
|
+
`,`cp-in`):this.#X(n+`
|
|
328
|
+
`,`cp-in`),this.#Z(),e(n))};t.addEventListener(`submit`,e=>{e.preventDefault(),a(n.value)}),i.addEventListener(`click`,()=>a(null)),n.addEventListener(`keydown`,e=>{(e.key===`Escape`||e.key===`d`&&e.ctrlKey)&&(e.preventDefault(),a(null))}),t.append(n,r,i),this.#s.hidden=!1,this.#s.appendChild(t),this.#s.scrollTop=this.#s.scrollHeight,this.#A=e,this.#j=a,n.focus({preventScroll:!0})})}#$(e){this.#j?.(e),this.#j=null,this.#A=null}#ee(e,t){this.#Z();let n=document.createElement(`div`);n.className=`cp-hint`,n.textContent=e,this.#s.hidden=!1,this.#s.appendChild(n),this.#s.scrollTop=this.#s.scrollHeight,t&&(this.#c.hidden=!1,this.#c.classList.add(`cp-attention`))}#te(e){this.#Z();let t=document.createElement(`table`);t.className=`cp-table`;let n=t.createTHead().insertRow();for(let t of e.columns){let e=document.createElement(`th`);e.textContent=t,n.appendChild(e)}let r=t.createTBody();for(let t of e.rows){let e=r.insertRow();for(let n of t)e.insertCell().textContent=n==null?``:String(n)}this.#s.hidden=!1,this.#s.appendChild(t)}#ne(e,t){this.dispatchEvent(new CustomEvent(e,{detail:t,bubbles:!0,composed:!0}))}};function H(e=M){typeof window>`u`||typeof customElements>`u`||customElements.get(e)||customElements.define(e,V)}H();export{V as CodePlayPadElement,o as PYODIDE_VERSION,e as RunStopped,t as WorkerUnavailable,j as allProgress,O as clearSnippet,r as configurePython,a as configureTypeScript,s as createEditor,H as defineCodePlayPad,A as getProgress,m as getRuntime,p as listRuntimes,D as loadSnippet,i as pyodideAssetUrls,f as registerRuntime,E as saveSnippet,k as setProgress};
|
package/dist/types.d.ts
CHANGED
|
@@ -49,8 +49,12 @@ export interface Runtime {
|
|
|
49
49
|
editorLanguage(): Promise<Extension>;
|
|
50
50
|
load(onProgress?: (p: LoadProgress) => void): Promise<void>;
|
|
51
51
|
run(code: string, options?: RunOptions): Promise<Result>;
|
|
52
|
-
/**
|
|
53
|
-
|
|
52
|
+
/** Hard stop. Optional per the interface.
|
|
53
|
+
* Given the promise run() returned, stops only that run: a queued run is
|
|
54
|
+
* dropped (it rejects with RunStopped) and nothing else is touched; a run
|
|
55
|
+
* already executing kills the worker, which reboots. With no argument, kills
|
|
56
|
+
* the worker and fails whichever run is active. */
|
|
57
|
+
stop?(run?: Promise<Result>): void;
|
|
54
58
|
/** true once load() has resolved and the runtime is usable */
|
|
55
59
|
readonly ready: boolean;
|
|
56
60
|
/** Whether this runtime can block on input() and wait for the page to answer.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* code-playpad — MIT © 2026 Seung Hun Lee
|
|
3
|
+
* Bundles CodeMirror 6 and Lezer (MIT) © Marijn Haverbeke and others.
|
|
4
|
+
* Full third-party licences: THIRD-PARTY-NOTICES.txt in this package.
|
|
5
|
+
*/
|
|
6
|
+
import{n as e,r as t,t as n}from"./hints-v5iHTd1l.js";var r=1,i=class{#e=null;#t=null;#n=`module`;#r=null;#i=null;#a=!1;#o=!1;#s=``;#c=new Set;#l=[];#u=null;#d=!1;initPayload(){return{}}get ready(){return this.#a}get interactiveStdin(){return this.#o}get version(){return this.#s}load(e){e&&this.#c.add(e);let n=()=>{e&&this.#c.delete(e)};if(!this.#r){let e=new Promise((e,n)=>{this.#i={resolve:e,reject:n};let r;try{if(typeof Worker>`u`)throw Error(`Worker constructor missing`);let e=new Blob([this.source],{type:`text/javascript`});this.#t=URL.createObjectURL(e),r=new Worker(this.#t,{type:this.#n})}catch(e){this.#i=null,n(new t(`Could not start a Web Worker: ${e.message}`));return}this.#e=r,r.onmessage=t=>{let r=t.data;if(r.type===`ready`){this.#s=r.version,this.#o=r.interactiveStdin===!0,this.#a=!0,this.#i=null,this.#h({phase:`ready`,message:`${this.label} ready`}),e();return}if(r.type===`fatal`&&!this.#a){this.#p(r.message,e,n);return}this.#g(r)},r.onerror=t=>{let r=t.message||`Worker failed to start`;this.#a?this.#u&&this.#v(this.#u,Error(r)):this.#p(r,e,n)},r.postMessage({type:`init`,...this.initPayload()})});this.#r=e,e.catch(()=>{this.#r===e&&(this.#r=null)})}return this.#r.then(n,e=>{throw n(),e})}run(e,t={}){let n,i,a=new Promise((e,t)=>{n=e,i=t}),o,s=new Promise(e=>{o=e}),c={id:r++,code:e,options:t,stdout:``,stderr:``,resolve:n,reject:i,promise:a,started:!1,settled:!1,done:s,markDone:()=>{c.settled=!0,o()}};return this.#l.push(c),this.#y(),a}stop(t){if(t){let n=this.#l.findIndex(e=>e.promise===t);if(n!==-1){this.#v(this.#l.splice(n,1)[0],new e);return}let r=this.#u;if(!r||r.promise!==t||r.settled)return;if(!r.started){this.#v(r,new e);return}}this.#f()}#f(){let t=this.#e!==null,n=this.#i;if(this.#m(),this.#u&&this.#v(this.#u,new e),t){let e=this.load();n&&e.then(n.resolve,n.reject),e.catch(()=>{})}}#p(e,t,n){if(this.#m(),this.#n===`module`){this.#n=`classic`,this.load().then(t,n);return}n(Error(e))}#m(){this.#e?.terminate(),this.#e=null,this.#t&&=(URL.revokeObjectURL(this.#t),null),this.#r=null,this.#i=null,this.#a=!1}#h(e){for(let t of this.#c)t(e)}#g(e){if(e.type===`progress`){this.#h({phase:e.phase,message:e.message});return}let t=this.#u;if(!(!t||!(`id`in e)||e.id!==t.id))switch(e.type){case`stdout`:t.stdout+=e.text,t.options.onStdout?.(e.text);break;case`echo`:t.options.onEcho?.(e.text);break;case`stdin-request`:this.#_(t,e.request);break;case`stderr`:t.stderr+=e.text,t.options.onStderr?.(e.text);break;case`result`:t.resolve({stdout:t.stdout,stderr:t.stderr||void 0,value:e.value,durationMs:Math.round(e.durationMs)}),t.markDone();break;case`error`:case`fatal`:{let r=(t.stderr&&!t.stderr.endsWith(`
|
|
7
|
+
`)?`
|
|
8
|
+
`:``)+e.message+`
|
|
9
|
+
`;t.stderr+=r,t.options.onStderr?.(r);let i={stdout:t.stdout,stderr:t.stderr,hint:`hint`in e?e.hint:void 0,durationMs:Math.round(`durationMs`in e?e.durationMs:0)};`hintAbout`in e&&e.hintAbout===`stdin`&&n.add(i),t.resolve(i),t.markDone();break}}}#_(e,t){let n=this.#e,r=r=>{this.#e===n&&this.#u===e&&n?.postMessage({type:`stdin-response`,request:t,text:r})},i=e.options.onStdinRequest;if(!i){r(null);return}i().then(r,()=>r(null))}#v(e,t){e.reject(t),e.markDone()}async#y(){if(!this.#d){this.#d=!0;try{for(;this.#l.length;){let e=this.#l.shift();this.#u=e;try{if(await this.load(),e.settled)continue;e.started=!0,e.options.onStart?.(),this.#e.postMessage({type:`run`,id:e.id,code:e.code,stdin:e.options.stdin,files:e.options.files,entry:e.options.entry}),await e.done}catch(t){this.#v(e,t)}finally{this.#u=null}}}finally{this.#d=!1}}}};export{i as t};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import{d as e,l as t,u as n}from"./element-BYcX5Z6z.js";var r=1,i=class{#e=null;#t=null;#n=`module`;#r=null;#i=null;#a=!1;#o=!1;#s=``;#c=new Set;#l=[];#u=null;#d=!1;initPayload(){return{}}get ready(){return this.#a}get interactiveStdin(){return this.#o}get version(){return this.#s}load(t){t&&this.#c.add(t);let n=()=>{t&&this.#c.delete(t)};if(!this.#r){let t=new Promise((t,n)=>{this.#i={resolve:t,reject:n};let r;try{if(typeof Worker>`u`)throw Error(`Worker constructor missing`);let e=new Blob([this.source],{type:`text/javascript`});this.#t=URL.createObjectURL(e),r=new Worker(this.#t,{type:this.#n})}catch(t){this.#i=null,n(new e(`Could not start a Web Worker: ${t.message}`));return}this.#e=r,r.onmessage=e=>{let r=e.data;if(r.type===`ready`){this.#s=r.version,this.#o=r.interactiveStdin===!0,this.#a=!0,this.#i=null,this.#h({phase:`ready`,message:`${this.label} ready`}),t();return}if(r.type===`fatal`&&!this.#a){this.#p(r.message,t,n);return}this.#g(r)},r.onerror=e=>{let r=e.message||`Worker failed to start`;this.#a?this.#u&&this.#v(this.#u,Error(r)):this.#p(r,t,n)},r.postMessage({type:`init`,...this.initPayload()})});this.#r=t,t.catch(()=>{this.#r===t&&(this.#r=null)})}return this.#r.then(n,e=>{throw n(),e})}run(e,t={}){let n,i,a=new Promise((e,t)=>{n=e,i=t}),o,s=new Promise(e=>{o=e}),c={id:r++,code:e,options:t,stdout:``,stderr:``,resolve:n,reject:i,promise:a,started:!1,settled:!1,done:s,markDone:()=>{c.settled=!0,o()}};return this.#l.push(c),this.#y(),a}stop(e){if(e){let t=this.#l.findIndex(t=>t.promise===e);if(t!==-1){this.#v(this.#l.splice(t,1)[0],new n);return}let r=this.#u;if(!r||r.promise!==e||r.settled)return;if(!r.started){this.#v(r,new n);return}}this.#f()}#f(){let e=this.#e!==null,t=this.#i;if(this.#m(),this.#u&&this.#v(this.#u,new n),e){let e=this.load();t&&e.then(t.resolve,t.reject),e.catch(()=>{})}}#p(e,t,n){if(this.#m(),this.#n===`module`){this.#n=`classic`,this.load().then(t,n);return}n(Error(e))}#m(){this.#e?.terminate(),this.#e=null,this.#t&&=(URL.revokeObjectURL(this.#t),null),this.#r=null,this.#i=null,this.#a=!1}#h(e){for(let t of this.#c)t(e)}#g(e){if(e.type===`progress`){this.#h({phase:e.phase,message:e.message});return}let n=this.#u;if(!(!n||!(`id`in e)||e.id!==n.id))switch(e.type){case`stdout`:n.stdout+=e.text,n.options.onStdout?.(e.text);break;case`echo`:n.options.onEcho?.(e.text);break;case`stdin-request`:this.#_(n,e.request);break;case`stderr`:n.stderr+=e.text,n.options.onStderr?.(e.text);break;case`result`:n.resolve({stdout:n.stdout,stderr:n.stderr||void 0,value:e.value,durationMs:Math.round(e.durationMs)}),n.markDone();break;case`error`:case`fatal`:{let r=(n.stderr&&!n.stderr.endsWith(`
|
|
2
|
+
`)?`
|
|
3
|
+
`:``)+e.message+`
|
|
4
|
+
`;n.stderr+=r,n.options.onStderr?.(r);let i={stdout:n.stdout,stderr:n.stderr,hint:`hint`in e?e.hint:void 0,durationMs:Math.round(`durationMs`in e?e.durationMs:0)};`hintAbout`in e&&e.hintAbout===`stdin`&&t.add(i),n.resolve(i),n.markDone();break}}}#_(e,t){let n=this.#e,r=r=>{this.#e===n&&this.#u===e&&n?.postMessage({type:`stdin-response`,request:t,text:r})},i=e.options.onStdinRequest;if(!i){r(null);return}i().then(r,()=>r(null))}#v(e,t){e.reject(t),e.markDone()}async#y(){if(!this.#d){this.#d=!0;try{for(;this.#l.length;){let e=this.#l.shift();this.#u=e;try{if(await this.load(),e.settled)continue;e.started=!0,e.options.onStart?.(),this.#e.postMessage({type:`run`,id:e.id,code:e.code,stdin:e.options.stdin,files:e.options.files,entry:e.options.entry}),await e.done}catch(t){this.#v(e,t)}finally{this.#u=null}}}finally{this.#d=!1}}}};export{i as t};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "code-playpad",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Embeddable browser code playground: a CodeMirror editor that runs Python, JavaScript and
|
|
3
|
+
"version": "0.3.1",
|
|
4
|
+
"description": "Embeddable browser code playground: a CodeMirror editor that runs Python, JavaScript, TypeScript and a subset of Java in the browser. No backend. One shared worker per page, blocking input(), multi-file projects, lazy per-language loading.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"sideEffects": [
|
|
@@ -36,11 +36,14 @@
|
|
|
36
36
|
"build:demo": "npm run build && vite build --config vite.demo.config.ts",
|
|
37
37
|
"preview:demo": "vite preview --config vite.demo.config.ts",
|
|
38
38
|
"typecheck": "tsc --noEmit",
|
|
39
|
-
"prepublishOnly": "npm run build && node scripts/check-dist.mjs --publish"
|
|
39
|
+
"prepublishOnly": "npm run build && node scripts/check-dist.mjs --publish",
|
|
40
|
+
"sync:java": "node scripts/sync-java.mjs",
|
|
41
|
+
"test": "node --test --test-reporter=spec \"tests/*.test.mjs\""
|
|
40
42
|
},
|
|
41
43
|
"peerDependencies": {
|
|
42
44
|
"@codemirror/autocomplete": "^6",
|
|
43
45
|
"@codemirror/commands": "^6",
|
|
46
|
+
"@codemirror/lang-java": "^6",
|
|
44
47
|
"@codemirror/lang-javascript": "^6",
|
|
45
48
|
"@codemirror/lang-json": "^6",
|
|
46
49
|
"@codemirror/lang-python": "^6",
|
|
@@ -62,11 +65,15 @@
|
|
|
62
65
|
},
|
|
63
66
|
"@codemirror/lang-python": {
|
|
64
67
|
"optional": true
|
|
68
|
+
},
|
|
69
|
+
"@codemirror/lang-java": {
|
|
70
|
+
"optional": true
|
|
65
71
|
}
|
|
66
72
|
},
|
|
67
73
|
"devDependencies": {
|
|
68
74
|
"@codemirror/autocomplete": "^6.20.3",
|
|
69
75
|
"@codemirror/commands": "^6.11.0",
|
|
76
|
+
"@codemirror/lang-java": "^6.0.2",
|
|
70
77
|
"@codemirror/lang-javascript": "^6.2.5",
|
|
71
78
|
"@codemirror/lang-json": "^6.0.2",
|
|
72
79
|
"@codemirror/lang-python": "^6.2.1",
|
|
@@ -94,6 +101,7 @@
|
|
|
94
101
|
"pyodide",
|
|
95
102
|
"javascript",
|
|
96
103
|
"typescript",
|
|
104
|
+
"java",
|
|
97
105
|
"wasm",
|
|
98
106
|
"run-code-in-browser",
|
|
99
107
|
"education",
|
|
@@ -102,7 +110,7 @@
|
|
|
102
110
|
"homepage": "https://code-playpad.swengr.com",
|
|
103
111
|
"author": "Seung Hun Lee",
|
|
104
112
|
"unpkg": "./dist/standalone.js",
|
|
105
|
-
"jsdelivr": "./dist/
|
|
113
|
+
"jsdelivr": "./dist/cdn.js",
|
|
106
114
|
"engines": {
|
|
107
115
|
"node": ">=18"
|
|
108
116
|
}
|
package/dist/config-B2qK2rdk.js
DELETED
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
/*!
|
|
2
|
-
* code-playpad — MIT © 2026 Seung Hun Lee
|
|
3
|
-
* Bundles CodeMirror 6 and Lezer (MIT) © Marijn Haverbeke and others.
|
|
4
|
-
* Full third-party licences: THIRD-PARTY-NOTICES.txt in this package.
|
|
5
|
-
*/
|
|
6
|
-
var e=class extends Error{constructor(e=`Execution stopped`){super(e),this.name=`RunStopped`}},t=class extends Error{constructor(e=`Web Workers are unavailable in this page`){super(e),this.name=`WorkerUnavailable`}},n=`314.0.5`,r=`https://cdn.jsdelivr.net/pyodide/v${n}/full/`,i=`https://esm.sh/sucrase@3.35.1?bundle`;function a(e){r=e.indexURL.endsWith(`/`)?e.indexURL:e.indexURL+`/`}function o(e){i=e.sucraseURL}function s(){return r}function c(){return i}function l(){return[{url:r+`pyodide.js`,as:`script`},{url:r+`pyodide.asm.wasm`,as:`fetch`},{url:r+`python_stdlib.zip`,as:`fetch`}]}export{c as a,t as c,s as i,a as n,l as o,o as r,e as s,n as t};
|