code-playpad 0.1.3

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.
Files changed (43) hide show
  1. package/LICENSE +27 -0
  2. package/README.md +166 -0
  3. package/dist/THIRD-PARTY-NOTICES.txt +473 -0
  4. package/dist/config-B2qK2rdk.js +6 -0
  5. package/dist/config-DZqcFPEP.js +1 -0
  6. package/dist/dist-B5vq9x6M.js +6 -0
  7. package/dist/dist-BThnYaQ5.js +12 -0
  8. package/dist/dist-CnC1nMtN.js +6 -0
  9. package/dist/dist-CqpVTRAq.js +28 -0
  10. package/dist/dist-D0FPZcUi.js +8 -0
  11. package/dist/dist-DOsLUKSb.js +10 -0
  12. package/dist/dist-D_qJovVA.js +14 -0
  13. package/dist/dist-DlIO0dzi.js +6 -0
  14. package/dist/dist-DmrP6yta.js +6 -0
  15. package/dist/dist-XlpaG2JF.js +6 -0
  16. package/dist/editor.d.ts +33 -0
  17. package/dist/element-CJuhuMOP.js +288 -0
  18. package/dist/element.d.ts +63 -0
  19. package/dist/element.js +1 -0
  20. package/dist/index.d.ts +10 -0
  21. package/dist/index.js +1 -0
  22. package/dist/javascript-CLly2mXM.js +318 -0
  23. package/dist/javascript-DGFKR69i.js +323 -0
  24. package/dist/languages.d.ts +9 -0
  25. package/dist/progress.d.ts +17 -0
  26. package/dist/pyodide-IYKXKyDw.js +13 -0
  27. package/dist/pyodide-yv6x2HCQ.js +18 -0
  28. package/dist/react.d.ts +44 -0
  29. package/dist/react.js +1 -0
  30. package/dist/runtime/config.d.ts +29 -0
  31. package/dist/runtime/javascript.d.ts +3 -0
  32. package/dist/runtime/js-worker.d.ts +9 -0
  33. package/dist/runtime/pyodide.d.ts +3 -0
  34. package/dist/runtime/registry.d.ts +9 -0
  35. package/dist/runtime/worker-runtime.d.ts +71 -0
  36. package/dist/runtime/worker.d.ts +14 -0
  37. package/dist/standalone.d.ts +14 -0
  38. package/dist/standalone.js +293 -0
  39. package/dist/styles.d.ts +3 -0
  40. package/dist/types.d.ts +67 -0
  41. package/dist/worker-runtime-8Mnw4vAD.js +9 -0
  42. package/dist/worker-runtime-BZHszOA3.js +4 -0
  43. package/package.json +110 -0
@@ -0,0 +1,67 @@
1
+ import type { Extension } from '@codemirror/state';
2
+ /** Tabular result — used by SQL-style runtimes. Present from day one so
3
+ * adding one later is not a breaking change. */
4
+ export interface Table {
5
+ columns: string[];
6
+ rows: unknown[][];
7
+ }
8
+ export interface Result {
9
+ stdout: string;
10
+ stderr?: string;
11
+ /** repr of the last expression, if the snippet ended in one */
12
+ value?: string;
13
+ table?: Table;
14
+ /** Runtime guidance about a failure, in plain language — not program output. */
15
+ hint?: string;
16
+ durationMs: number;
17
+ }
18
+ export interface LoadProgress {
19
+ phase: 'booting' | 'packages' | 'ready';
20
+ message: string;
21
+ }
22
+ /** name -> contents. Names are relative paths: "utils.py", "pkg/__init__.py",
23
+ * "data.csv". Written into the runtime's filesystem before the run. */
24
+ export type Files = Record<string, string>;
25
+ export interface RunOptions {
26
+ stdin?: string;
27
+ /** Extra files to place next to the entry point before running. */
28
+ files?: Files;
29
+ /** Path the entry code is written to, so tracebacks name a real file. */
30
+ entry?: string;
31
+ /** Fires when the job leaves the queue and actually reaches the runtime. */
32
+ onStart?: () => void;
33
+ /** Input echoed back as it is consumed, the way a terminal echoes typing.
34
+ * Display only — it is not part of the program's stdout. */
35
+ onEcho?: (text: string) => void;
36
+ /** Called when the program blocks on input() and the pre-filled lines have
37
+ * run out. Resolve with a line, or null for EOF. */
38
+ onStdinRequest?: () => Promise<string | null>;
39
+ /** Streamed as the program writes; the full text is also in Result.stdout. */
40
+ onStdout?: (chunk: string) => void;
41
+ onStderr?: (chunk: string) => void;
42
+ }
43
+ export interface Runtime {
44
+ /** stable id used by the registry, e.g. "python" */
45
+ id: string;
46
+ /** human label, e.g. "Python 3.14" */
47
+ label: string;
48
+ /** CodeMirror language support, loaded on demand */
49
+ editorLanguage(): Promise<Extension>;
50
+ load(onProgress?: (p: LoadProgress) => void): Promise<void>;
51
+ run(code: string, options?: RunOptions): Promise<Result>;
52
+ /** hard stop: kill the worker and reboot. Optional per the interface. */
53
+ stop?(): void;
54
+ /** true once load() has resolved and the runtime is usable */
55
+ readonly ready: boolean;
56
+ /** Whether this runtime can block on input() and wait for the page to answer.
57
+ * False falls back to consuming pre-filled lines and raising EOFError. */
58
+ readonly interactiveStdin: boolean;
59
+ }
60
+ /** Thrown when a run is cancelled by stop(). */
61
+ export declare class RunStopped extends Error {
62
+ constructor(message?: string);
63
+ }
64
+ /** Thrown when the environment refuses to give us a Worker (CSP, etc.). */
65
+ export declare class WorkerUnavailable extends Error {
66
+ constructor(message?: string);
67
+ }
@@ -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{c as e,s as t}from"./config-B2qK2rdk.js";var n=1,r=class{#e=null;#t=null;#n=`module`;#r=null;#i=!1;#a=!1;#o=``;#s=new Set;#c=[];#l=null;#u=!1;initPayload(){return{}}get ready(){return this.#i}get interactiveStdin(){return this.#a}get version(){return this.#o}load(t){t&&this.#s.add(t);let n=()=>{t&&this.#s.delete(t)};if(!this.#r){let t=new Promise((t,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){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.#o=r.version,this.#a=r.interactiveStdin===!0,this.#i=!0,this.#p({phase:`ready`,message:`${this.label} ready`}),t();return}if(r.type===`fatal`&&!this.#i){this.#d(r.message,t,n);return}this.#m(r)},r.onerror=e=>{let r=e.message||`Worker failed to start`;this.#i?this.#l&&this.#g(this.#l,Error(r)):this.#d(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 r,i=new Promise(e=>{r=e});return new Promise((a,o)=>{this.#c.push({id:n++,code:e,options:t,stdout:``,stderr:``,resolve:a,reject:o,done:i,markDone:r}),this.#_()})}stop(){let e=this.#e!==null;this.#f(),this.#l&&this.#g(this.#l,new t),e&&this.load().catch(()=>{})}#d(e,t,n){if(this.#f(),this.#n===`module`){this.#n=`classic`,this.load().then(t,n);return}n(Error(e))}#f(){this.#e?.terminate(),this.#e=null,this.#t&&=(URL.revokeObjectURL(this.#t),null),this.#r=null,this.#i=!1}#p(e){for(let t of this.#s)t(e)}#m(e){if(e.type===`progress`){this.#p({phase:e.phase,message:e.message});return}let t=this.#l;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.#h(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 n=(t.stderr&&!t.stderr.endsWith(`
7
+ `)?`
8
+ `:``)+e.message+`
9
+ `;t.stderr+=n,t.options.onStderr?.(n),t.resolve({stdout:t.stdout,stderr:t.stderr,hint:`hint`in e?e.hint:void 0,durationMs:Math.round(`durationMs`in e?e.durationMs:0)}),t.markDone();break}}}#h(e,t){let n=this.#e,r=r=>{this.#e===n&&this.#l===e&&n?.postMessage({type:`stdin-response`,request:t,text:r})},i=e.options.onStdinRequest;if(!i){r(null);return}i().then(r,()=>r(null))}#g(e,t){e.reject(t),e.markDone()}async#_(){if(!this.#u){this.#u=!0;try{for(;this.#c.length;){let e=this.#c.shift();this.#l=e;try{await this.load(),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.#g(e,t)}finally{this.#l=null}}}finally{this.#u=!1}}}};export{r as t};
@@ -0,0 +1,4 @@
1
+ import{l as e,u as t}from"./element-CJuhuMOP.js";var n=1,r=class{#e=null;#t=null;#n=`module`;#r=null;#i=!1;#a=!1;#o=``;#s=new Set;#c=[];#l=null;#u=!1;initPayload(){return{}}get ready(){return this.#i}get interactiveStdin(){return this.#a}get version(){return this.#o}load(e){e&&this.#s.add(e);let n=()=>{e&&this.#s.delete(e)};if(!this.#r){let e=new Promise((e,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){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.#o=r.version,this.#a=r.interactiveStdin===!0,this.#i=!0,this.#p({phase:`ready`,message:`${this.label} ready`}),e();return}if(r.type===`fatal`&&!this.#i){this.#d(r.message,e,n);return}this.#m(r)},r.onerror=t=>{let r=t.message||`Worker failed to start`;this.#i?this.#l&&this.#g(this.#l,Error(r)):this.#d(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 r,i=new Promise(e=>{r=e});return new Promise((a,o)=>{this.#c.push({id:n++,code:e,options:t,stdout:``,stderr:``,resolve:a,reject:o,done:i,markDone:r}),this.#_()})}stop(){let t=this.#e!==null;this.#f(),this.#l&&this.#g(this.#l,new e),t&&this.load().catch(()=>{})}#d(e,t,n){if(this.#f(),this.#n===`module`){this.#n=`classic`,this.load().then(t,n);return}n(Error(e))}#f(){this.#e?.terminate(),this.#e=null,this.#t&&=(URL.revokeObjectURL(this.#t),null),this.#r=null,this.#i=!1}#p(e){for(let t of this.#s)t(e)}#m(e){if(e.type===`progress`){this.#p({phase:e.phase,message:e.message});return}let t=this.#l;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.#h(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 n=(t.stderr&&!t.stderr.endsWith(`
2
+ `)?`
3
+ `:``)+e.message+`
4
+ `;t.stderr+=n,t.options.onStderr?.(n),t.resolve({stdout:t.stdout,stderr:t.stderr,hint:`hint`in e?e.hint:void 0,durationMs:Math.round(`durationMs`in e?e.durationMs:0)}),t.markDone();break}}}#h(e,t){let n=this.#e,r=r=>{this.#e===n&&this.#l===e&&n?.postMessage({type:`stdin-response`,request:t,text:r})},i=e.options.onStdinRequest;if(!i){r(null);return}i().then(r,()=>r(null))}#g(e,t){e.reject(t),e.markDone()}async#_(){if(!this.#u){this.#u=!0;try{for(;this.#c.length;){let e=this.#c.shift();this.#l=e;try{await this.load(),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.#g(e,t)}finally{this.#l=null}}}finally{this.#u=!1}}}};export{r as t};
package/package.json ADDED
@@ -0,0 +1,110 @@
1
+ {
2
+ "name": "code-playpad",
3
+ "version": "0.1.3",
4
+ "description": "Embeddable browser code playground: a CodeMirror editor that runs Python, JavaScript and TypeScript in the browser. No backend. One shared worker per page, blocking input(), multi-file projects, lazy per-language loading.",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "sideEffects": [
8
+ "./dist/element.js",
9
+ "./dist/index.js",
10
+ "./dist/standalone.js"
11
+ ],
12
+ "files": [
13
+ "dist",
14
+ "README.md",
15
+ "LICENSE"
16
+ ],
17
+ "exports": {
18
+ ".": {
19
+ "types": "./dist/index.d.ts",
20
+ "default": "./dist/index.js"
21
+ },
22
+ "./react": {
23
+ "types": "./dist/react.d.ts",
24
+ "default": "./dist/react.js"
25
+ },
26
+ "./element": {
27
+ "types": "./dist/element.d.ts",
28
+ "default": "./dist/element.js"
29
+ },
30
+ "./standalone": {
31
+ "types": "./dist/standalone.d.ts",
32
+ "default": "./dist/standalone.js"
33
+ }
34
+ },
35
+ "scripts": {
36
+ "dev": "vite --config vite.demo.config.ts",
37
+ "build": "vite build && vite build --config vite.standalone.config.ts && tsc -p tsconfig.build.json && node scripts/check-dist.mjs",
38
+ "build:demo": "npm run build && vite build --config vite.demo.config.ts",
39
+ "preview:demo": "vite preview --config vite.demo.config.ts",
40
+ "typecheck": "tsc --noEmit",
41
+ "prepublishOnly": "npm run build && node scripts/check-dist.mjs --publish"
42
+ },
43
+ "peerDependencies": {
44
+ "@codemirror/autocomplete": "^6",
45
+ "@codemirror/commands": "^6",
46
+ "@codemirror/lang-javascript": "^6",
47
+ "@codemirror/lang-json": "^6",
48
+ "@codemirror/lang-python": "^6",
49
+ "@codemirror/language": "^6",
50
+ "@codemirror/state": "^6",
51
+ "@codemirror/theme-one-dark": "^6",
52
+ "@codemirror/view": "^6",
53
+ "react": ">=18"
54
+ },
55
+ "peerDependenciesMeta": {
56
+ "react": {
57
+ "optional": true
58
+ },
59
+ "@codemirror/lang-javascript": {
60
+ "optional": true
61
+ },
62
+ "@codemirror/lang-json": {
63
+ "optional": true
64
+ },
65
+ "@codemirror/lang-python": {
66
+ "optional": true
67
+ }
68
+ },
69
+ "devDependencies": {
70
+ "@codemirror/autocomplete": "^6.20.3",
71
+ "@codemirror/commands": "^6.11.0",
72
+ "@codemirror/lang-javascript": "^6.2.5",
73
+ "@codemirror/lang-json": "^6.0.2",
74
+ "@codemirror/lang-python": "^6.2.1",
75
+ "@codemirror/language": "^6.12.4",
76
+ "@codemirror/state": "^6.7.1",
77
+ "@codemirror/theme-one-dark": "^6.1.3",
78
+ "@codemirror/view": "^6.43.9",
79
+ "@types/react": "^19.2.18",
80
+ "@types/react-dom": "^19.2.4",
81
+ "esbuild": "^0.28.2",
82
+ "react": "^19.2.8",
83
+ "react-dom": "^19.2.8",
84
+ "typescript": "^5.9.3",
85
+ "vite": "^8.2.2"
86
+ },
87
+ "keywords": [
88
+ "playground",
89
+ "code-editor",
90
+ "codemirror",
91
+ "repl",
92
+ "web-component",
93
+ "custom-element",
94
+ "python",
95
+ "pyodide",
96
+ "javascript",
97
+ "typescript",
98
+ "wasm",
99
+ "run-code-in-browser",
100
+ "education",
101
+ "sandbox"
102
+ ],
103
+ "homepage": "https://code-playpad.swengr.com",
104
+ "author": "Seung Hun Lee",
105
+ "unpkg": "./dist/standalone.js",
106
+ "jsdelivr": "./dist/standalone.js",
107
+ "engines": {
108
+ "node": ">=18"
109
+ }
110
+ }