code-playpad 0.3.0 → 0.4.0
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/JAVA-COMPATIBILITY.md +272 -0
- package/README.md +315 -45
- package/dist/cdn.js +2 -0
- package/dist/{element-BYcX5Z6z.js → element-Bh4TdnGA.js} +12 -11
- package/dist/element.d.ts +10 -1
- package/dist/element.js +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/java-CDMXnFT7.js +6 -0
- package/dist/java-DrWI9a5Q.js +1 -0
- package/dist/java-library.generated-Bg_JSWb_.js +6 -0
- package/dist/{javascript-hfFD1Fg2.js → javascript-C1_thu8i.js} +1 -1
- package/dist/{javascript-BhISU47e.js → javascript-EtrNZmfD.js} +1 -1
- package/dist/{pyodide-j1wg1W9_.js → pyodide-BeJ9RqWJ.js} +1 -1
- package/dist/{pyodide-BTGQ_X_F.js → pyodide-CqcU3YGb.js} +1 -1
- package/dist/react.d.ts +4 -2
- package/dist/react.js +1 -1
- package/dist/runtime/java-library.generated.d.ts +8 -0
- package/dist/runtime/java-worker.generated.d.ts +3 -3
- package/dist/runtime/worker-runtime.d.ts +17 -1
- package/dist/standalone.d.ts +6 -2
- package/dist/standalone.js +12 -11
- package/dist/types.d.ts +76 -0
- package/dist/worker-runtime-CNPpMRo1.js +9 -0
- package/dist/worker-runtime-Kjkt5ChF.js +4 -0
- package/package.json +4 -3
- package/dist/java-1ISFU8hm.js +0 -1
- package/dist/java-DSEX5tzl.js +0 -6
- package/dist/worker-runtime-CmbgEzLA.js +0 -9
- package/dist/worker-runtime-mfgjcG5l.js +0 -4
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{a as e}from"./config-DZqcFPEP.js";import{t}from"./worker-runtime-
|
|
1
|
+
import{a as e}from"./config-DZqcFPEP.js";import{t}from"./worker-runtime-Kjkt5ChF.js";var n=`let currentId=null,stdinLines=[],stdinExhausted=!1,nextRequest=1,inputWaitMs=0;const pendingLines=new Map;let sucrasePromise=null,sucraseURL="https://esm.sh/sucrase@3.35.1?bundle";function post(t){self.postMessage(t)}let functionLineOffset=0;try{new Function('throw new Error("probe")')()}catch(t){const n=/<anonymous>:(\\d+):/.exec(t.stack||"");n&&(functionLineOffset=Number(n[1])-1)}let currentFiles=[];const FLUSH_BYTES=8192,FLUSH_MS=16,EAGER_POSTS=32;let outputQueue=[],queuedChars=0,windowStart=-1/0,windowPosts=0;function writeOutput(t,n){const s=outputQueue[outputQueue.length-1];s&&s.type===t?s.text+=n:outputQueue.push({type:t,text:n}),queuedChars+=n.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 t=outputQueue;outputQueue=[],queuedChars=0;for(const n of t)post({type:n.type,id:currentId,text:n.text})}function format(t,n,s){if(n=n||new Set,typeof t=="string")return s?t:JSON.stringify(t);if(typeof t=="bigint")return String(t)+"n";if(typeof t=="function")return"[Function"+(t.name?": "+t.name:"")+"]";if(typeof t=="symbol"||t==null||typeof t!="object")return String(t);if(n.has(t))return"[Circular]";n.add(t);try{if(t instanceof Error)return t.stack||t.name+": "+t.message;if(Array.isArray(t))return"[ "+t.map(e=>format(e,n)).join(", ")+" ]";if(t instanceof Map)return"Map("+t.size+") { "+[...t].map(([e,o])=>format(e,n)+" => "+format(o,n)).join(", ")+" }";if(t instanceof Set)return"Set("+t.size+") { "+[...t].map(e=>format(e,n)).join(", ")+" }";if(t instanceof Date)return t.toISOString();if(t instanceof Promise)return"Promise { \\u2026 }";const i=Object.entries(t).map(([e,o])=>e+": "+format(o,n)),f=t.constructor&&t.constructor.name;return(f&&f!=="Object"?f+" ":"")+"{ "+i.join(", ")+" }"}finally{n.delete(t)}}function formatArgs(t){return t.map(n=>format(n,null,!0)).join(" ")+\`
|
|
2
2
|
\`}const nativeConsole=self.console;self.console=Object.assign(Object.create(nativeConsole),{log:(...t)=>writeOutput("stdout",formatArgs(t)),info:(...t)=>writeOutput("stdout",formatArgs(t)),debug:(...t)=>writeOutput("stdout",formatArgs(t)),warn:(...t)=>writeOutput("stderr",formatArgs(t)),error:(...t)=>writeOutput("stderr",formatArgs(t))}),self._ppReadLine=async()=>{if(stdinLines.length){const i=stdinLines.shift();return writeOutput("echo",i+\`
|
|
3
3
|
\`),i}const t=nextRequest++;flushOutput();const n=performance.now(),s=await new Promise(i=>{pendingLines.set(t,i),post({type:"stdin-request",id:currentId,request:t})});return inputWaitMs+=performance.now()-n,typeof s!="string"&&(stdinExhausted=!0),typeof s=="string"?s:null};async function input(t){t!==void 0&&writeOutput("stdout",String(t));const n=await self._ppReadLine();if(n===null)throw new Error("EOF: no more input");return n}self.input=input;async function loadSucrase(){return sucrasePromise||(sucrasePromise=import(sucraseURL)),sucrasePromise}function isModule(t,n){return Object.keys(t).length>1?!0:/^\\s*(import|export)\\s/m.test(t[n]||"")}function needsTypeScript(t){return/\\.(ts|tsx|jsx|mts|cts)$/.test(t)}function transformsFor(t){const n=["imports"];return/\\.tsx?$|\\.mts$|\\.cts$/.test(t)&&n.push("typescript"),/\\.[jt]sx$/.test(t)&&n.push("jsx"),n}async function runAsModules(t,n){const{transform:s}=await loadSucrase(),i=new Map,f=(e,o)=>{if(!o.startsWith("."))return null;const a=((e.includes("/")?e.slice(0,e.lastIndexOf("/")+1):"")+o).split("/"),d=[];for(const p of a)p==="."||p===""||(p===".."?d.pop():d.push(p));const c=d.join("/");return[c,c+".js",c+".ts",c+".tsx",c+".jsx",c+".json",c+"/index.js",c+"/index.ts"].find(p=>p in t)||null};function r(e){if(i.has(e))return i.get(e).exports;const o={exports:{}};if(i.set(e,o),e.endsWith(".json")){try{o.exports=JSON.parse(t[e])}catch(c){throw new SyntaxError("Invalid JSON in "+e+": "+c.message)}return o.exports}const{code:u}=s(t[e],{transforms:transformsFor(e),filePath:e,preserveDynamicImport:!0}),a=c=>{const l=f(e,c);if(!l)throw new Error('Cannot find module "'+c+'" from "'+e+'"');return r(l)};return new Function("exports","require","module","__filename","input","console",u+\`
|
|
4
4
|
//# sourceURL=\`+e)(o.exports,a,o,e,input,self.console),o.exports}r(n)}async function run(t){currentId=t.id,stdinLines=t.stdin?String(t.stdin).replace(/\\n$/,"").split(\`
|
|
@@ -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{a as e}from"./config-DZqcFPEP.js";import{t}from"./worker-runtime-
|
|
6
|
+
import{a as e}from"./config-DZqcFPEP.js";import{t}from"./worker-runtime-CNPpMRo1.js";var n=`let currentId=null,stdinLines=[],stdinExhausted=!1,nextRequest=1,inputWaitMs=0;const pendingLines=new Map;let sucrasePromise=null,sucraseURL="https://esm.sh/sucrase@3.35.1?bundle";function post(t){self.postMessage(t)}let functionLineOffset=0;try{new Function('throw new Error("probe")')()}catch(t){const n=/<anonymous>:(\\d+):/.exec(t.stack||"");n&&(functionLineOffset=Number(n[1])-1)}let currentFiles=[];const FLUSH_BYTES=8192,FLUSH_MS=16,EAGER_POSTS=32;let outputQueue=[],queuedChars=0,windowStart=-1/0,windowPosts=0;function writeOutput(t,n){const s=outputQueue[outputQueue.length-1];s&&s.type===t?s.text+=n:outputQueue.push({type:t,text:n}),queuedChars+=n.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 t=outputQueue;outputQueue=[],queuedChars=0;for(const n of t)post({type:n.type,id:currentId,text:n.text})}function format(t,n,s){if(n=n||new Set,typeof t=="string")return s?t:JSON.stringify(t);if(typeof t=="bigint")return String(t)+"n";if(typeof t=="function")return"[Function"+(t.name?": "+t.name:"")+"]";if(typeof t=="symbol"||t==null||typeof t!="object")return String(t);if(n.has(t))return"[Circular]";n.add(t);try{if(t instanceof Error)return t.stack||t.name+": "+t.message;if(Array.isArray(t))return"[ "+t.map(e=>format(e,n)).join(", ")+" ]";if(t instanceof Map)return"Map("+t.size+") { "+[...t].map(([e,o])=>format(e,n)+" => "+format(o,n)).join(", ")+" }";if(t instanceof Set)return"Set("+t.size+") { "+[...t].map(e=>format(e,n)).join(", ")+" }";if(t instanceof Date)return t.toISOString();if(t instanceof Promise)return"Promise { \\u2026 }";const i=Object.entries(t).map(([e,o])=>e+": "+format(o,n)),f=t.constructor&&t.constructor.name;return(f&&f!=="Object"?f+" ":"")+"{ "+i.join(", ")+" }"}finally{n.delete(t)}}function formatArgs(t){return t.map(n=>format(n,null,!0)).join(" ")+\`
|
|
7
7
|
\`}const nativeConsole=self.console;self.console=Object.assign(Object.create(nativeConsole),{log:(...t)=>writeOutput("stdout",formatArgs(t)),info:(...t)=>writeOutput("stdout",formatArgs(t)),debug:(...t)=>writeOutput("stdout",formatArgs(t)),warn:(...t)=>writeOutput("stderr",formatArgs(t)),error:(...t)=>writeOutput("stderr",formatArgs(t))}),self._ppReadLine=async()=>{if(stdinLines.length){const i=stdinLines.shift();return writeOutput("echo",i+\`
|
|
8
8
|
\`),i}const t=nextRequest++;flushOutput();const n=performance.now(),s=await new Promise(i=>{pendingLines.set(t,i),post({type:"stdin-request",id:currentId,request:t})});return inputWaitMs+=performance.now()-n,typeof s!="string"&&(stdinExhausted=!0),typeof s=="string"?s:null};async function input(t){t!==void 0&&writeOutput("stdout",String(t));const n=await self._ppReadLine();if(n===null)throw new Error("EOF: no more input");return n}self.input=input;async function loadSucrase(){return sucrasePromise||(sucrasePromise=import(sucraseURL)),sucrasePromise}function isModule(t,n){return Object.keys(t).length>1?!0:/^\\s*(import|export)\\s/m.test(t[n]||"")}function needsTypeScript(t){return/\\.(ts|tsx|jsx|mts|cts)$/.test(t)}function transformsFor(t){const n=["imports"];return/\\.tsx?$|\\.mts$|\\.cts$/.test(t)&&n.push("typescript"),/\\.[jt]sx$/.test(t)&&n.push("jsx"),n}async function runAsModules(t,n){const{transform:s}=await loadSucrase(),i=new Map,f=(e,o)=>{if(!o.startsWith("."))return null;const a=((e.includes("/")?e.slice(0,e.lastIndexOf("/")+1):"")+o).split("/"),d=[];for(const p of a)p==="."||p===""||(p===".."?d.pop():d.push(p));const c=d.join("/");return[c,c+".js",c+".ts",c+".tsx",c+".jsx",c+".json",c+"/index.js",c+"/index.ts"].find(p=>p in t)||null};function r(e){if(i.has(e))return i.get(e).exports;const o={exports:{}};if(i.set(e,o),e.endsWith(".json")){try{o.exports=JSON.parse(t[e])}catch(c){throw new SyntaxError("Invalid JSON in "+e+": "+c.message)}return o.exports}const{code:u}=s(t[e],{transforms:transformsFor(e),filePath:e,preserveDynamicImport:!0}),a=c=>{const l=f(e,c);if(!l)throw new Error('Cannot find module "'+c+'" from "'+e+'"');return r(l)};return new Function("exports","require","module","__filename","input","console",u+\`
|
|
9
9
|
//# sourceURL=\`+e)(o.exports,a,o,e,input,self.console),o.exports}r(n)}async function run(t){currentId=t.id,stdinLines=t.stdin?String(t.stdin).replace(/\\n$/,"").split(\`
|
|
@@ -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{i as e}from"./config-DZqcFPEP.js";import{t}from"./worker-runtime-
|
|
6
|
+
import{i as e}from"./config-DZqcFPEP.js";import{t}from"./worker-runtime-CNPpMRo1.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(\`
|
|
@@ -1,4 +1,4 @@
|
|
|
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-Kjkt5ChF.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(\`
|
package/dist/react.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { CSSProperties } from 'react';
|
|
2
2
|
import { CodePlayPadElement } from './element.js';
|
|
3
3
|
import type { ErrorEventDetail, OutputEventDetail, RunEventDetail } from './element.js';
|
|
4
|
-
import type { Files } from './types.js';
|
|
4
|
+
import type { Files, PracticeSpec } from './types.js';
|
|
5
5
|
export interface CodePlayPadProps {
|
|
6
6
|
/** Single-file shorthand. Ignored when `files` is given. */
|
|
7
7
|
code?: string;
|
|
@@ -21,6 +21,8 @@ export interface CodePlayPadProps {
|
|
|
21
21
|
autoRun?: boolean;
|
|
22
22
|
/** IndexedDB key: edits are restored on the student's next visit */
|
|
23
23
|
persist?: string;
|
|
24
|
+
/** Practice mode (Java): call a method with test cases instead of running main. */
|
|
25
|
+
practice?: PracticeSpec;
|
|
24
26
|
className?: string;
|
|
25
27
|
style?: CSSProperties;
|
|
26
28
|
onReady?: (detail: {
|
|
@@ -36,7 +38,7 @@ export interface CodePlayPadProps {
|
|
|
36
38
|
* which keeps React 18 (no non-string prop support on custom elements) working
|
|
37
39
|
* the same as React 19.
|
|
38
40
|
*/
|
|
39
|
-
export declare function CodePlayPad({ code, files, entry, stdin, language, height, minHeight, maxHeight, theme, readOnly, autoRun, persist, className, style, onReady, onRun, onOutput, onError }: CodePlayPadProps): import("react").JSX.Element;
|
|
41
|
+
export declare function CodePlayPad({ code, files, entry, stdin, language, height, minHeight, maxHeight, theme, readOnly, autoRun, persist, practice, className, style, onReady, onRun, onOutput, onError }: CodePlayPadProps): import("react").JSX.Element;
|
|
40
42
|
declare module 'react' {
|
|
41
43
|
namespace JSX {
|
|
42
44
|
interface IntrinsicElements {
|
package/dist/react.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{n as e}from"./element-
|
|
1
|
+
import{n as e}from"./element-Bh4TdnGA.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,practice:h,className:g,style:_,onReady:v,onRun:y,onOutput:b,onError:x}){let S=n(null),C=n({onReady:v,onRun:y,onOutput:b,onError:x});C.current={onReady:v,onRun:y,onOutput:b,onError:x},t(()=>{let e=S.current;if(!e)return;let t=(t,n)=>{let r=e=>n(C.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 w=i?JSON.stringify(i):null;t(()=>{let t=S.current;t&&(w?t.files=JSON.parse(w):e!==t.code&&(t.code=e))},[e,w]),t(()=>{S.current&&o!==void 0&&(S.current.stdin=o)},[o]);let T=h?JSON.stringify(h):null;return t(()=>{S.current&&(S.current.practice=T?JSON.parse(T):null)},[T]),r(`code-playpad`,{ref:S,language:s,theme:d,class:g,style:_,...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,8 @@
|
|
|
1
|
+
export declare const JAVA_LIBRARY: {
|
|
2
|
+
readonly name: "java-online-compiler";
|
|
3
|
+
readonly version: "0.26.0";
|
|
4
|
+
readonly commit: "5fe0606077ec6c58e155ad0513a97c00f466bd46";
|
|
5
|
+
readonly dirty: false;
|
|
6
|
+
readonly sha256: "ac7567b66338a86c7c15887460f5f1831cfa281358db7e14646efcc4eb18b005";
|
|
7
|
+
};
|
|
8
|
+
export declare const JAVA_LIBRARY_SOURCE: string;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
export declare const JAVA_ENGINE: {
|
|
2
2
|
readonly name: "java-online-compiler";
|
|
3
|
-
readonly version: "0.
|
|
4
|
-
readonly commit: "
|
|
3
|
+
readonly version: "0.26.0";
|
|
4
|
+
readonly commit: "5fe0606077ec6c58e155ad0513a97c00f466bd46";
|
|
5
5
|
readonly dirty: false;
|
|
6
|
-
readonly sha256: "
|
|
6
|
+
readonly sha256: "a10b902a50404b84de53b315beeb449238bcfebbce7ebe6a2d1291b49a863493";
|
|
7
7
|
};
|
|
8
8
|
export declare const JAVA_WORKER_SOURCE: string;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { LoadProgress, Result, RunOptions } from '../types.js';
|
|
1
|
+
import type { CaseResult, LoadProgress, Result, RunOptions } from '../types.js';
|
|
2
2
|
/**
|
|
3
3
|
* Everything a Worker-backed runtime needs that has nothing to do with the
|
|
4
4
|
* language: boot, reboot, a single-file queue, streamed output, interactive
|
|
@@ -39,6 +39,9 @@ export type WorkerMessage = {
|
|
|
39
39
|
id: number;
|
|
40
40
|
value?: string;
|
|
41
41
|
durationMs: number;
|
|
42
|
+
cases?: CaseResult[];
|
|
43
|
+
passed?: number;
|
|
44
|
+
total?: number;
|
|
42
45
|
} | {
|
|
43
46
|
type: 'error';
|
|
44
47
|
id: number;
|
|
@@ -46,10 +49,17 @@ export type WorkerMessage = {
|
|
|
46
49
|
hint?: string;
|
|
47
50
|
hintAbout?: 'stdin';
|
|
48
51
|
durationMs: number;
|
|
52
|
+
cases?: CaseResult[];
|
|
49
53
|
} | {
|
|
50
54
|
type: 'fatal';
|
|
51
55
|
id?: number;
|
|
52
56
|
message: string;
|
|
57
|
+
}
|
|
58
|
+
/** The running program needs a module the worker does not bundle (Java's library chunk). */
|
|
59
|
+
| {
|
|
60
|
+
type: 'module-request';
|
|
61
|
+
id: number;
|
|
62
|
+
name: string;
|
|
53
63
|
};
|
|
54
64
|
export declare abstract class WorkerRuntime {
|
|
55
65
|
#private;
|
|
@@ -57,6 +67,12 @@ export declare abstract class WorkerRuntime {
|
|
|
57
67
|
protected abstract get source(): string;
|
|
58
68
|
/** Extra fields for the init message (e.g. where to fetch a runtime from). */
|
|
59
69
|
protected initPayload(): Record<string, unknown>;
|
|
70
|
+
/**
|
|
71
|
+
* The source of a module the worker asked for mid-run (`module-request`).
|
|
72
|
+
* Only languages that split their worker override it; the default refuses,
|
|
73
|
+
* and the worker reports that as an engine error.
|
|
74
|
+
*/
|
|
75
|
+
protected loadModule(name: string): Promise<string>;
|
|
60
76
|
get ready(): boolean;
|
|
61
77
|
get interactiveStdin(): boolean;
|
|
62
78
|
protected get version(): string;
|
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{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-
|
|
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-BeJ9RqWJ.js`).then(e=>e.pythonRuntime)),f(`javascript`,()=>import(`./javascript-EtrNZmfD.js`).then(e=>e.javascriptRuntime)),f(`typescript`,()=>import(`./javascript-EtrNZmfD.js`).then(e=>e.typescriptRuntime)),f(`java`,()=>import(`./java-CDMXnFT7.js`).then(e=>e.javaRuntime));var h=String.raw`
|
|
7
7
|
:host {
|
|
8
8
|
--cp-bg: #ffffff;
|
|
9
9
|
--cp-fg: #1f2328;
|
|
@@ -301,10 +301,11 @@ table.cp-table th { background: var(--cp-bg); }
|
|
|
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 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.#
|
|
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`,`practice`]}#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.#q();#D=null;#O=!0;#k=[];#A=null;#j=null;#M=null;#N=0;#P=!1;#F=null;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.#V()}get practice(){if(this.#F)return this.#F;let e=this.getAttribute(`practice`);if(!e)return null;try{return JSON.parse(e)}catch{return null}}set practice(e){this.#F=e}get files(){return this.#U()}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.#H()),this.#u?.forgetFiles([]),this.#V(),this.#W(),this.#B()}get entry(){return this.#H()}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.#W(),this.#B())}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.#U()}reset(){this.#m={...this.#h},this.#g=this.#H(),this.#u?.forgetFiles([]),this.#V(),this.#W(),this.#X(),this.#s.hidden=!0,this.#Y(this.#f?.ready?`${this.#f.label} ready`:``,`idle`)}async run(){if(this.#y)return;await this.#d;let t=this.#U(),r=this.#H(),i=t[r]??``;this.#y=!0,this.#x=!1,this.#n.disabled=!0,this.#r.hidden=!1,this.#X(),this.#s.hidden=!1;let a=this.practice;this.hasAttribute(`practice`)&&!a&&this.#Z(`The practice attribute is not valid JSON.
|
|
305
|
+
`,`cp-err`),this.#re(`py-run`,{code:i,entry:r,files:t,language:this.language,...a?{practice:a}:{}});try{let o=await this.#z();if(this.#x)throw new e;if(a&&!o.supportsPractice)throw Error(`Practice mode is not available for ${o.label}.`);this.#Y(`Queued…`,`busy`),this.#o.hidden=!1;let s=o.run(i,{stdin:this.#l.value,files:t,entry:r,onStart:()=>this.#Y(`Running…`,`busy`),onStdout:e=>this.#Z(e),onStderr:e=>this.#Z(e,`cp-err`),onEcho:e=>this.#Z(e,`cp-in`),onStdinRequest:()=>this.#$(),...a?{practice:a}:{}});this.#b={runtime:o,run:s};let c=await s;if(c.table&&this.#ne(c.table),c.value!==void 0&&this.#Z(`${c.value}\n`,`cp-value`),c.hint&&this.#te(c.hint,n.has(c)),c.failed=o.statusDecidesFailure?c.failed===!0:!!c.stderr,c.failed)this.#Y(`Error · ${c.durationMs} ms`,`error`),this.#re(`py-error`,{message:c.stderr??``,hint:c.hint,language:this.language});else if(c.cases){let e=c.cases.filter(e=>e.expected!==void 0).length,t=c.passed===e;this.#Y(e?`${c.passed} of ${e} passed · ${c.durationMs} ms`:`Done in ${c.durationMs} ms`,t?`ok`:`error`)}else this.#Y(`Done in ${c.durationMs} ms`,`ok`);return this.#re(`py-output`,{...c,language:this.language}),c}catch(t){if(t instanceof e)this.#Z(`
|
|
305
306
|
[stopped]
|
|
306
|
-
`,`cp-err`),this.#
|
|
307
|
-
`,`cp-err`),this.#
|
|
307
|
+
`,`cp-err`),this.#Y(`Stopped`,`error`);else{let e=t instanceof Error?t.message:String(t);this.#Z(e+`
|
|
308
|
+
`,`cp-err`),this.#Y(`Failed to start`,`error`),this.#re(`py-error`,{message:e,language:this.language})}return}finally{this.#b=null,this.#ee(null),this.#Q(),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.#z()}connectedCallback(){if(this.#P){this.#R();return}if(!this.textContent?.trim()&&document.readyState===`loading`){document.addEventListener(`DOMContentLoaded`,()=>this.isConnected&&this.#I(),{once:!0});return}this.#I()}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.#ee(null),setTimeout(()=>{this.isConnected||!this.#u||(this.#_=this.#U(),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.#q();break;case`height`:case`min-height`:case`max-height`:this.#J();break;case`readonly`:this.#u?.setReadOnly(n!==null);break;case`stdin`:this.#c.hidden=n===null&&!this.#l.value;break;case`entry`:this.#W();break;case`language`:this.#f=null,this.#p=null,this.#S=!1,this.#z().catch(()=>{})}}#I(){this.#P=!0,this.#h=R(this,L(this.language)),this.#m=this.#_??{...this.#h},this.#g=this.#H(),this.#L(),this.#q(),this.#J();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.#H()}}this.#W();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.#K(),readOnly:this.hasAttribute(`readonly`),language:n,onRun:()=>void this.run(),onChange:e=>this.#G(e)}),this.#_=null,this.#B()})(),this.#R()}#L(){let e=document.createElement(`style`);e.textContent=h;let t=document.createElement(`div`);t.className=`cp-root`,t.innerHTML=`
|
|
308
309
|
<div class="cp-toolbar">
|
|
309
310
|
<button class="cp-primary" part="run-button" data-action="run">Run</button>
|
|
310
311
|
<button class="cp-danger" part="stop-button" data-action="stop" hidden>Stop</button>
|
|
@@ -319,10 +320,10 @@ table.cp-table th { background: var(--cp-bg); }
|
|
|
319
320
|
<label>Standard input — one value per line</label>
|
|
320
321
|
<textarea rows="2" spellcheck="false"></textarea>
|
|
321
322
|
</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.#k.push({text:n,className:t}),this.#M??=setTimeout(()=>this.#
|
|
325
|
-
… output truncated for display — the full text is in the
|
|
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}
|
|
327
|
-
`,`cp-in`):this.#
|
|
328
|
-
`,`cp-in`),this.#
|
|
323
|
+
<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.#z().catch(()=>{});this.#t.addEventListener(`pointerdown`,n,{once:!0}),this.#t.addEventListener(`focusin`,n,{once:!0})}#R(){this.#C||typeof IntersectionObserver>`u`||(this.#C=new IntersectionObserver(e=>{e.some(e=>e.isIntersecting)&&(this.#C?.disconnect(),this.#C=null,this.#z().then(()=>{this.hasAttribute(`autorun`)&&this.run()}).catch(()=>{}))},{rootMargin:`300px`}),this.#C.observe(this))}#z(){return this.#p||=(async()=>{let e=await m(this.language);this.#f=e,e.ready||(this.#o.hidden=!1,this.#Y(`Loading ${e.label}…`,`busy`));try{await e.load(e=>{this.#y||this.#Y(e.message,e.phase===`ready`?`ok`:`busy`)})}catch(e){this.#p=null,this.#Y(`Runtime unavailable`,`error`);let t=e instanceof Error?e.message:String(e);throw this.#Z(t+`
|
|
324
|
+
`,`cp-err`),this.#s.hidden=!1,e}finally{this.#o.hidden=!0}return this.#B(),this.#S||(this.#S=!0,this.#Y(`${e.label} ready`,`ok`),this.#re(`py-ready`,{language:e.id,label:e.label})),e})(),this.#p}async#B(){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??[])}#V(){if(this.#u){this.#u.setCode(this.#m[this.#g]??``);return}this.#d?.then(()=>{this.#u?.setCode(this.#m[this.#g]??``),this.#W()})}#H(){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}#U(){let e={...this.#m};if(this.#u)for(let t of Object.keys(e))e[t]=this.#u.fileCode(t,e[t]);return e}#W(){let e=Object.keys(this.#m);if(this.#v.hidden=e.length<2,this.#v.hidden){this.#v.replaceChildren();return}let t=this.#H();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}))}#G(e){this.#m[this.#g]=e;let t=this.getAttribute(`persist`);if(!t)return;this.#D&&clearTimeout(this.#D);let n=JSON.stringify(this.#U());this.#D=setTimeout(()=>void E(t,n).catch(()=>{}),400)}#K(){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}#q(){!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.#K();this.setAttribute(`data-resolved-theme`,e?`dark`:`light`),this.#u?.setTheme(e)}#J(){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)}}#Y(e,t){this.#a.textContent=e,this.#a.dataset.state=t}#X(){this.#M&&clearTimeout(this.#M),this.#M=null,this.#k=[],this.#N=0,this.#s.replaceChildren(),this.#O=!0}#Z(e,t){if(!e)return;let n=t===`cp-err`&&!this.#O?`\n${e}`:e;this.#O=n.endsWith(`
|
|
325
|
+
`),this.#k.push({text:n,className:t}),this.#M??=setTimeout(()=>this.#Q(),16)}#Q(){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)+`
|
|
326
|
+
… output truncated for display — the full text is in the playpad-output event
|
|
327
|
+
`),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}#$(){return this.#Q(),this.#ee(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.#Z(`
|
|
328
|
+
`,`cp-in`):this.#Z(n+`
|
|
329
|
+
`,`cp-in`),this.#Q(),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})})}#ee(e){this.#j?.(e),this.#j=null,this.#A=null}#te(e,t){this.#Q();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`))}#ne(e){this.#Q();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)}#re(e,t){this.dispatchEvent(new CustomEvent(e,{detail:t,bubbles:!0,composed:!0})),this.dispatchEvent(new CustomEvent(`playpad-${e.slice(3)}`,{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
|
@@ -14,6 +14,76 @@ export interface Result {
|
|
|
14
14
|
/** Runtime guidance about a failure, in plain language — not program output. */
|
|
15
15
|
hint?: string;
|
|
16
16
|
durationMs: number;
|
|
17
|
+
/** Practice mode: one result per case, in order. */
|
|
18
|
+
cases?: CaseResult[];
|
|
19
|
+
/** Practice mode: cases that passed, and cases run. */
|
|
20
|
+
passed?: number;
|
|
21
|
+
total?: number;
|
|
22
|
+
/**
|
|
23
|
+
* Whether the run failed. Python and JavaScript: any stderr output counts.
|
|
24
|
+
* Java: the run's own status decides (an exception, a compile error, a
|
|
25
|
+
* non-zero System.exit), so javac's warnings and System.err output on a
|
|
26
|
+
* run that finished normally do not, as in a terminal.
|
|
27
|
+
*/
|
|
28
|
+
failed?: boolean;
|
|
29
|
+
}
|
|
30
|
+
/** A value in practice mode, in its JSON encoding (see the README's "Practice mode"). */
|
|
31
|
+
export type PracticeValue = null | boolean | number | string | PracticeValue[] | {
|
|
32
|
+
[key: string]: PracticeValue;
|
|
33
|
+
};
|
|
34
|
+
export interface PracticeCase {
|
|
35
|
+
/** Shown in results; defaults to "1", "2", ... */
|
|
36
|
+
id?: string;
|
|
37
|
+
args: PracticeValue[];
|
|
38
|
+
/** Omitted: the case runs and reports what it returned. */
|
|
39
|
+
expected?: PracticeValue;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Practice mode (Java): call one method of the program with test cases,
|
|
43
|
+
* instead of running main, and report each case.
|
|
44
|
+
*/
|
|
45
|
+
export interface PracticeSpec {
|
|
46
|
+
/** The class declaring the method; by default, the one class with a method of that name. */
|
|
47
|
+
className?: string;
|
|
48
|
+
method: string;
|
|
49
|
+
/** Parameter types as Java writes them (`["int[]", "int"]`), to pick an overload. */
|
|
50
|
+
params?: string[];
|
|
51
|
+
cases: PracticeCase[];
|
|
52
|
+
/** Compare the return value (default), or an argument after the call (for a void method that fills one in). */
|
|
53
|
+
compare?: {
|
|
54
|
+
kind: 'return';
|
|
55
|
+
tolerance?: number;
|
|
56
|
+
} | {
|
|
57
|
+
kind: 'argument';
|
|
58
|
+
index: number;
|
|
59
|
+
tolerance?: number;
|
|
60
|
+
};
|
|
61
|
+
/** Linked-list or tree node classes whose shape is not obvious from their fields. */
|
|
62
|
+
nodes?: Record<string, {
|
|
63
|
+
kind: 'list' | 'tree';
|
|
64
|
+
value?: string;
|
|
65
|
+
next?: string;
|
|
66
|
+
left?: string;
|
|
67
|
+
right?: string;
|
|
68
|
+
}>;
|
|
69
|
+
}
|
|
70
|
+
export type CaseStatus = 'passed' | 'failed' | 'completed' | 'runtime-error' | 'resource-limit' | 'engine-limitation' | 'invalid-case' | 'not-run';
|
|
71
|
+
export interface CaseResult {
|
|
72
|
+
id: string;
|
|
73
|
+
status: CaseStatus;
|
|
74
|
+
args: PracticeValue[];
|
|
75
|
+
expected?: PracticeValue;
|
|
76
|
+
actual?: PracticeValue;
|
|
77
|
+
/** What the case printed. */
|
|
78
|
+
stdout: string;
|
|
79
|
+
stderr: string;
|
|
80
|
+
/** The stack trace or limit message, as for a whole program; or why the case is invalid. */
|
|
81
|
+
error?: string;
|
|
82
|
+
hint?: string;
|
|
83
|
+
/** For not-run: `compile-error`, `invalid-practice` or `engine-failure`. */
|
|
84
|
+
reason?: string;
|
|
85
|
+
instructions: number;
|
|
86
|
+
durationMs: number;
|
|
17
87
|
}
|
|
18
88
|
export interface LoadProgress {
|
|
19
89
|
phase: 'booting' | 'packages' | 'ready';
|
|
@@ -39,6 +109,8 @@ export interface RunOptions {
|
|
|
39
109
|
/** Streamed as the program writes; the full text is also in Result.stdout. */
|
|
40
110
|
onStdout?: (chunk: string) => void;
|
|
41
111
|
onStderr?: (chunk: string) => void;
|
|
112
|
+
/** Practice mode, for runtimes that support it (`supportsPractice`). */
|
|
113
|
+
practice?: PracticeSpec;
|
|
42
114
|
}
|
|
43
115
|
export interface Runtime {
|
|
44
116
|
/** stable id used by the registry, e.g. "python" */
|
|
@@ -57,6 +129,10 @@ export interface Runtime {
|
|
|
57
129
|
stop?(run?: Promise<Result>): void;
|
|
58
130
|
/** true once load() has resolved and the runtime is usable */
|
|
59
131
|
readonly ready: boolean;
|
|
132
|
+
/** Whether run() honors RunOptions.practice (Java). */
|
|
133
|
+
readonly supportsPractice?: boolean;
|
|
134
|
+
/** Whether a run's own status, not stderr output, says whether it failed (Java). */
|
|
135
|
+
readonly statusDecidesFailure?: boolean;
|
|
60
136
|
/** Whether this runtime can block on input() and wait for the page to answer.
|
|
61
137
|
* False falls back to consuming pre-filled lines and raising EOFError. */
|
|
62
138
|
readonly interactiveStdin: boolean;
|
|
@@ -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{}}loadModule(e){return Promise.reject(Error(`no module named ${e}`))}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.#y(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.#b(),a}stop(t){if(t){let n=this.#l.findIndex(e=>e.promise===t);if(n!==-1){this.#y(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.#y(r,new e);return}}this.#f()}#f(){let t=this.#e!==null,n=this.#i;if(this.#m(),this.#u&&this.#y(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.#v(t,e.request);break;case`module-request`:this.#_(t,e.name);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),failed:!1,...e.cases?{cases:e.cases,passed:e.passed,total:e.total}:{}}),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),failed:!0,...`cases`in e&&e.cases?{cases:e.cases,passed:0,total:e.cases.length}:{}};`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:`module`,name:t,...r})};this.loadModule(t).then(e=>r({code:e}),e=>r({error:e instanceof Error?e.message:String(e)}))}#v(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))}#y(e,t){e.reject(t),e.markDone()}async#b(){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,...e.options.practice?{practice:e.options.practice}:{}}),await e.done}catch(t){this.#y(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-Bh4TdnGA.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{}}loadModule(e){return Promise.reject(Error(`no module named ${e}`))}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.#y(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.#b(),a}stop(e){if(e){let t=this.#l.findIndex(t=>t.promise===e);if(t!==-1){this.#y(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.#y(r,new n);return}}this.#f()}#f(){let e=this.#e!==null,t=this.#i;if(this.#m(),this.#u&&this.#y(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.#v(n,e.request);break;case`module-request`:this.#_(n,e.name);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),failed:!1,...e.cases?{cases:e.cases,passed:e.passed,total:e.total}:{}}),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),failed:!0,...`cases`in e&&e.cases?{cases:e.cases,passed:0,total:e.cases.length}:{}};`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:`module`,name:t,...r})};this.loadModule(t).then(e=>r({code:e}),e=>r({error:e instanceof Error?e.message:String(e)}))}#v(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))}#y(e,t){e.reject(t),e.markDone()}async#b(){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,...e.options.practice?{practice:e.options.practice}:{}}),await e.done}catch(t){this.#y(e,t)}finally{this.#u=null}}}finally{this.#d=!1}}}};export{i as t};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "code-playpad",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
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",
|
|
@@ -10,7 +10,8 @@
|
|
|
10
10
|
"files": [
|
|
11
11
|
"dist",
|
|
12
12
|
"README.md",
|
|
13
|
-
"LICENSE"
|
|
13
|
+
"LICENSE",
|
|
14
|
+
"JAVA-COMPATIBILITY.md"
|
|
14
15
|
],
|
|
15
16
|
"exports": {
|
|
16
17
|
".": {
|
|
@@ -110,7 +111,7 @@
|
|
|
110
111
|
"homepage": "https://code-playpad.swengr.com",
|
|
111
112
|
"author": "Seung Hun Lee",
|
|
112
113
|
"unpkg": "./dist/standalone.js",
|
|
113
|
-
"jsdelivr": "./dist/
|
|
114
|
+
"jsdelivr": "./dist/cdn.js",
|
|
114
115
|
"engines": {
|
|
115
116
|
"node": ">=18"
|
|
116
117
|
}
|