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.
- package/LICENSE +27 -0
- package/README.md +166 -0
- package/dist/THIRD-PARTY-NOTICES.txt +473 -0
- package/dist/config-B2qK2rdk.js +6 -0
- package/dist/config-DZqcFPEP.js +1 -0
- package/dist/dist-B5vq9x6M.js +6 -0
- package/dist/dist-BThnYaQ5.js +12 -0
- package/dist/dist-CnC1nMtN.js +6 -0
- package/dist/dist-CqpVTRAq.js +28 -0
- package/dist/dist-D0FPZcUi.js +8 -0
- package/dist/dist-DOsLUKSb.js +10 -0
- package/dist/dist-D_qJovVA.js +14 -0
- package/dist/dist-DlIO0dzi.js +6 -0
- package/dist/dist-DmrP6yta.js +6 -0
- package/dist/dist-XlpaG2JF.js +6 -0
- package/dist/editor.d.ts +33 -0
- package/dist/element-CJuhuMOP.js +288 -0
- package/dist/element.d.ts +63 -0
- package/dist/element.js +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +1 -0
- package/dist/javascript-CLly2mXM.js +318 -0
- package/dist/javascript-DGFKR69i.js +323 -0
- package/dist/languages.d.ts +9 -0
- package/dist/progress.d.ts +17 -0
- package/dist/pyodide-IYKXKyDw.js +13 -0
- package/dist/pyodide-yv6x2HCQ.js +18 -0
- package/dist/react.d.ts +44 -0
- package/dist/react.js +1 -0
- package/dist/runtime/config.d.ts +29 -0
- package/dist/runtime/javascript.d.ts +3 -0
- package/dist/runtime/js-worker.d.ts +9 -0
- package/dist/runtime/pyodide.d.ts +3 -0
- package/dist/runtime/registry.d.ts +9 -0
- package/dist/runtime/worker-runtime.d.ts +71 -0
- package/dist/runtime/worker.d.ts +14 -0
- package/dist/standalone.d.ts +14 -0
- package/dist/standalone.js +293 -0
- package/dist/styles.d.ts +3 -0
- package/dist/types.d.ts +67 -0
- package/dist/worker-runtime-8Mnw4vAD.js +9 -0
- package/dist/worker-runtime-BZHszOA3.js +4 -0
- package/package.json +110 -0
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
async function e(e){try{return await t(e)}catch(t){return console.warn(`[code-playpad] CodeMirror unavailable, using plain textarea:`,t),n(e)}}async function t(e){let[t,n,r,i,a,o]=await Promise.all([import(`@codemirror/view`),import(`@codemirror/state`),import(`@codemirror/commands`),import(`@codemirror/language`),import(`@codemirror/autocomplete`),import(`@codemirror/theme-one-dark`)]),{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 n(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 r=new Map,i=new Map;function a(e,t){r.set(e,t)}function o(){return[...r.keys()]}function s(e){let t=i.get(e);if(t)return t;let n=r.get(e);if(!n)return Promise.reject(Error(`Unknown runtime "${e}". Registered: ${o().join(`, `)||`none`}`));let a=n().catch(t=>{throw i.delete(e),t});return i.set(e,a),a}a(`python`,()=>import(`./pyodide-IYKXKyDw.js`).then(e=>e.pythonRuntime)),a(`javascript`,()=>import(`./javascript-CLly2mXM.js`).then(e=>e.javascriptRuntime)),a(`typescript`,()=>import(`./javascript-CLly2mXM.js`).then(e=>e.typescriptRuntime));var c=class extends Error{constructor(e=`Execution stopped`){super(e),this.name=`RunStopped`}},l=class extends Error{constructor(e=`Web Workers are unavailable in this page`){super(e),this.name=`WorkerUnavailable`}},u=String.raw`
|
|
2
|
+
:host {
|
|
3
|
+
--cp-bg: #ffffff;
|
|
4
|
+
--cp-fg: #1f2328;
|
|
5
|
+
--cp-muted: #656d76;
|
|
6
|
+
--cp-border: #d0d7de;
|
|
7
|
+
--cp-surface: #f6f8fa;
|
|
8
|
+
--cp-accent: #1f6feb;
|
|
9
|
+
--cp-accent-fg: #ffffff;
|
|
10
|
+
--cp-danger: #cf222e;
|
|
11
|
+
--cp-ok: #1a7f37;
|
|
12
|
+
--cp-radius: 8px;
|
|
13
|
+
--cp-font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
|
|
14
|
+
--cp-font-ui: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
|
|
15
|
+
|
|
16
|
+
display: block;
|
|
17
|
+
margin: 1rem 0;
|
|
18
|
+
color-scheme: light;
|
|
19
|
+
contain: content;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
:host([hidden]) { display: none; }
|
|
23
|
+
|
|
24
|
+
:host([data-resolved-theme="dark"]) {
|
|
25
|
+
--cp-bg: #0d1117;
|
|
26
|
+
--cp-fg: #e6edf3;
|
|
27
|
+
--cp-muted: #8b949e;
|
|
28
|
+
--cp-border: #30363d;
|
|
29
|
+
--cp-surface: #161b22;
|
|
30
|
+
--cp-accent: #388bfd;
|
|
31
|
+
--cp-danger: #ff7b72;
|
|
32
|
+
--cp-ok: #3fb950;
|
|
33
|
+
color-scheme: dark;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
* { box-sizing: border-box; }
|
|
37
|
+
|
|
38
|
+
.cp-root {
|
|
39
|
+
border: 1px solid var(--cp-border);
|
|
40
|
+
border-radius: var(--cp-radius);
|
|
41
|
+
background: var(--cp-bg);
|
|
42
|
+
color: var(--cp-fg);
|
|
43
|
+
font-family: var(--cp-font-ui);
|
|
44
|
+
font-size: 14px;
|
|
45
|
+
overflow: hidden;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.cp-toolbar {
|
|
49
|
+
display: flex;
|
|
50
|
+
align-items: center;
|
|
51
|
+
gap: 8px;
|
|
52
|
+
padding: 6px 8px;
|
|
53
|
+
background: var(--cp-surface);
|
|
54
|
+
border-bottom: 1px solid var(--cp-border);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.cp-spacer { flex: 1 1 auto; }
|
|
58
|
+
|
|
59
|
+
.cp-status {
|
|
60
|
+
font-size: 12px;
|
|
61
|
+
color: var(--cp-muted);
|
|
62
|
+
white-space: nowrap;
|
|
63
|
+
overflow: hidden;
|
|
64
|
+
text-overflow: ellipsis;
|
|
65
|
+
max-width: 55%;
|
|
66
|
+
}
|
|
67
|
+
.cp-status[data-state="error"] { color: var(--cp-danger); }
|
|
68
|
+
.cp-status[data-state="ok"] { color: var(--cp-ok); }
|
|
69
|
+
|
|
70
|
+
button {
|
|
71
|
+
font: inherit;
|
|
72
|
+
font-size: 13px;
|
|
73
|
+
line-height: 1;
|
|
74
|
+
padding: 6px 12px;
|
|
75
|
+
border-radius: 6px;
|
|
76
|
+
border: 1px solid var(--cp-border);
|
|
77
|
+
background: var(--cp-bg);
|
|
78
|
+
color: var(--cp-fg);
|
|
79
|
+
cursor: pointer;
|
|
80
|
+
}
|
|
81
|
+
button:hover:not(:disabled) { border-color: var(--cp-accent); }
|
|
82
|
+
button:disabled { opacity: 0.5; cursor: default; }
|
|
83
|
+
button:focus-visible { outline: 2px solid var(--cp-accent); outline-offset: 1px; }
|
|
84
|
+
|
|
85
|
+
button.cp-primary {
|
|
86
|
+
background: var(--cp-accent);
|
|
87
|
+
border-color: var(--cp-accent);
|
|
88
|
+
color: var(--cp-accent-fg);
|
|
89
|
+
font-weight: 600;
|
|
90
|
+
}
|
|
91
|
+
button.cp-danger { color: var(--cp-danger); border-color: var(--cp-danger); }
|
|
92
|
+
|
|
93
|
+
.cp-tabs {
|
|
94
|
+
display: flex;
|
|
95
|
+
gap: 2px;
|
|
96
|
+
overflow-x: auto;
|
|
97
|
+
padding: 0 6px;
|
|
98
|
+
background: var(--cp-surface);
|
|
99
|
+
border-bottom: 1px solid var(--cp-border);
|
|
100
|
+
scrollbar-width: thin;
|
|
101
|
+
}
|
|
102
|
+
.cp-tabs[hidden] { display: none; }
|
|
103
|
+
.cp-tabs button {
|
|
104
|
+
border: 0;
|
|
105
|
+
border-bottom: 2px solid transparent;
|
|
106
|
+
border-radius: 0;
|
|
107
|
+
background: transparent;
|
|
108
|
+
color: var(--cp-muted);
|
|
109
|
+
font-family: var(--cp-font-mono);
|
|
110
|
+
font-size: 12px;
|
|
111
|
+
padding: 7px 10px;
|
|
112
|
+
white-space: nowrap;
|
|
113
|
+
}
|
|
114
|
+
.cp-tabs button:hover:not(:disabled) { color: var(--cp-fg); }
|
|
115
|
+
.cp-tabs button[aria-pressed='true'] {
|
|
116
|
+
color: var(--cp-fg);
|
|
117
|
+
border-bottom-color: var(--cp-accent);
|
|
118
|
+
background: var(--cp-bg);
|
|
119
|
+
}
|
|
120
|
+
.cp-tabs button.cp-entry::before {
|
|
121
|
+
content: '▸';
|
|
122
|
+
margin-right: 4px;
|
|
123
|
+
color: var(--cp-accent);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
.cp-editor {
|
|
127
|
+
height: var(--cp-height, 220px);
|
|
128
|
+
overflow: hidden;
|
|
129
|
+
}
|
|
130
|
+
.cp-editor .cm-editor { height: 100%; }
|
|
131
|
+
.cp-editor .cm-scroller {
|
|
132
|
+
font-family: var(--cp-font-mono);
|
|
133
|
+
font-size: 13px;
|
|
134
|
+
line-height: 1.5;
|
|
135
|
+
}
|
|
136
|
+
.cp-editor .cm-editor.cm-focused { outline: none; }
|
|
137
|
+
|
|
138
|
+
.cp-fallback-editor {
|
|
139
|
+
width: 100%;
|
|
140
|
+
height: 100%;
|
|
141
|
+
border: 0;
|
|
142
|
+
padding: 8px;
|
|
143
|
+
resize: none;
|
|
144
|
+
background: var(--cp-bg);
|
|
145
|
+
color: var(--cp-fg);
|
|
146
|
+
font-family: var(--cp-font-mono);
|
|
147
|
+
font-size: 13px;
|
|
148
|
+
line-height: 1.5;
|
|
149
|
+
}
|
|
150
|
+
.cp-fallback-editor:focus { outline: none; }
|
|
151
|
+
|
|
152
|
+
.cp-stdin { border-top: 1px solid var(--cp-border); background: var(--cp-surface); }
|
|
153
|
+
.cp-stdin[hidden] { display: none; }
|
|
154
|
+
.cp-stdin.cp-attention {
|
|
155
|
+
box-shadow: inset 0 0 0 2px var(--cp-accent);
|
|
156
|
+
}
|
|
157
|
+
.cp-stdin label {
|
|
158
|
+
display: block;
|
|
159
|
+
padding: 6px 8px 0;
|
|
160
|
+
font-size: 11px;
|
|
161
|
+
text-transform: uppercase;
|
|
162
|
+
letter-spacing: 0.04em;
|
|
163
|
+
color: var(--cp-muted);
|
|
164
|
+
}
|
|
165
|
+
.cp-stdin textarea {
|
|
166
|
+
display: block;
|
|
167
|
+
width: 100%;
|
|
168
|
+
min-height: 52px;
|
|
169
|
+
border: 0;
|
|
170
|
+
padding: 4px 8px 8px;
|
|
171
|
+
background: transparent;
|
|
172
|
+
color: var(--cp-fg);
|
|
173
|
+
font-family: var(--cp-font-mono);
|
|
174
|
+
font-size: 13px;
|
|
175
|
+
resize: vertical;
|
|
176
|
+
}
|
|
177
|
+
.cp-stdin textarea:focus { outline: none; }
|
|
178
|
+
|
|
179
|
+
.cp-output {
|
|
180
|
+
border-top: 1px solid var(--cp-border);
|
|
181
|
+
padding: 8px 10px;
|
|
182
|
+
margin: 0;
|
|
183
|
+
max-height: 260px;
|
|
184
|
+
overflow: auto;
|
|
185
|
+
background: var(--cp-surface);
|
|
186
|
+
font-family: var(--cp-font-mono);
|
|
187
|
+
font-size: 13px;
|
|
188
|
+
line-height: 1.5;
|
|
189
|
+
white-space: pre-wrap;
|
|
190
|
+
word-break: break-word;
|
|
191
|
+
}
|
|
192
|
+
.cp-output[hidden] { display: none; }
|
|
193
|
+
.cp-output .cp-err { color: var(--cp-danger); }
|
|
194
|
+
.cp-output .cp-hint {
|
|
195
|
+
margin-top: 6px;
|
|
196
|
+
padding: 6px 8px;
|
|
197
|
+
border-left: 3px solid var(--cp-accent);
|
|
198
|
+
background: var(--cp-bg);
|
|
199
|
+
color: var(--cp-fg);
|
|
200
|
+
font-family: var(--cp-font-ui);
|
|
201
|
+
font-size: 12.5px;
|
|
202
|
+
white-space: normal;
|
|
203
|
+
}
|
|
204
|
+
.cp-output .cp-value { color: var(--cp-muted); }
|
|
205
|
+
.cp-output .cp-in { color: var(--cp-accent); }
|
|
206
|
+
|
|
207
|
+
.cp-prompt {
|
|
208
|
+
display: inline-flex;
|
|
209
|
+
align-items: center;
|
|
210
|
+
gap: 4px;
|
|
211
|
+
}
|
|
212
|
+
.cp-prompt input {
|
|
213
|
+
font: inherit;
|
|
214
|
+
color: var(--cp-accent);
|
|
215
|
+
background: transparent;
|
|
216
|
+
border: 0;
|
|
217
|
+
border-bottom: 1px solid var(--cp-accent);
|
|
218
|
+
padding: 0 2px;
|
|
219
|
+
min-width: 12ch;
|
|
220
|
+
caret-color: var(--cp-accent);
|
|
221
|
+
}
|
|
222
|
+
.cp-prompt input:focus { outline: none; }
|
|
223
|
+
.cp-prompt button {
|
|
224
|
+
padding: 1px 6px;
|
|
225
|
+
font-size: 11px;
|
|
226
|
+
line-height: 1.4;
|
|
227
|
+
border-radius: 4px;
|
|
228
|
+
color: var(--cp-muted);
|
|
229
|
+
font-family: var(--cp-font-mono);
|
|
230
|
+
}
|
|
231
|
+
.cp-prompt button.cp-send { color: var(--cp-accent); border-color: var(--cp-accent); }
|
|
232
|
+
|
|
233
|
+
table.cp-table {
|
|
234
|
+
border-collapse: collapse;
|
|
235
|
+
margin: 6px 0;
|
|
236
|
+
font-size: 12px;
|
|
237
|
+
}
|
|
238
|
+
table.cp-table th, table.cp-table td {
|
|
239
|
+
border: 1px solid var(--cp-border);
|
|
240
|
+
padding: 3px 8px;
|
|
241
|
+
text-align: left;
|
|
242
|
+
}
|
|
243
|
+
table.cp-table th { background: var(--cp-bg); }
|
|
244
|
+
|
|
245
|
+
.cp-progress {
|
|
246
|
+
height: 2px;
|
|
247
|
+
background: linear-gradient(90deg, transparent, var(--cp-accent), transparent);
|
|
248
|
+
background-size: 40% 100%;
|
|
249
|
+
background-repeat: no-repeat;
|
|
250
|
+
animation: cp-slide 1.1s ease-in-out infinite;
|
|
251
|
+
}
|
|
252
|
+
.cp-progress[hidden] { display: none; }
|
|
253
|
+
|
|
254
|
+
@keyframes cp-slide {
|
|
255
|
+
0% { background-position: -40% 0; }
|
|
256
|
+
100% { background-position: 140% 0; }
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
@media (prefers-reduced-motion: reduce) {
|
|
260
|
+
.cp-progress { animation: none; background-position: 0 0; background-size: 100% 100%; opacity: 0.4; }
|
|
261
|
+
}
|
|
262
|
+
`,d=e=>()=>import(`@codemirror/lang-javascript`).then(t=>t.javascript(e)),f={py:()=>import(`@codemirror/lang-python`).then(e=>e.python()),pyi:()=>import(`@codemirror/lang-python`).then(e=>e.python()),js:d({}),mjs:d({}),cjs:d({}),jsx:d({jsx:!0}),ts:d({typescript:!0}),mts:d({typescript:!0}),cts:d({typescript:!0}),tsx:d({typescript:!0,jsx:!0}),json:()=>import(`@codemirror/lang-json`).then(e=>e.json())};async function p(e){let t=f[e.includes(`.`)?e.slice(e.lastIndexOf(`.`)+1).toLowerCase():``];return t?t().catch(()=>null):null}var m=`code-playpad`,h=1,g=`snippets`,_=`progress`,v=null;function y(){return typeof indexedDB>`u`?Promise.reject(Error(`IndexedDB unavailable`)):(v||=new Promise((e,t)=>{let n=indexedDB.open(m,h);n.onupgradeneeded=()=>{let e=n.result;e.objectStoreNames.contains(g)||e.createObjectStore(g),e.objectStoreNames.contains(_)||e.createObjectStore(_,{keyPath:`id`})},n.onsuccess=()=>e(n.result),n.onerror=()=>t(n.error)}).catch(e=>{throw v=null,e}),v)}function b(e,t,n){return y().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 x(e,t){return b(g,`readwrite`,n=>n.put(t,e)).then(()=>void 0)}function S(e){return b(g,`readonly`,t=>t.get(e)).then(e=>e??null)}function C(e){return b(g,`readwrite`,t=>t.delete(e)).then(()=>void 0)}function w(e,t={}){let n={completed:!0,...t,id:e,updatedAt:Date.now()};return b(_,`readwrite`,e=>e.put(n)).then(()=>n)}function T(e){return b(_,`readonly`,t=>t.get(e)).then(e=>e??null)}function E(){return b(_,`readonly`,e=>e.getAll())}var D=`code-playpad`;function O(e){let t=e.replace(/\t/g,` `).split(`
|
|
263
|
+
`);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(`
|
|
264
|
+
`)}var k=2e5,A=`playpad-file`,j={python:`main.py`,javascript:`main.js`,typescript:`main.ts`};function M(e){return j[e]??`main.txt`}function N(e,t){let n={};for(let t of e.children){if(t.tagName.toLowerCase()!==A)continue;let e=t.getAttribute(`name`);e&&(n[e]=O(t.textContent??``))}if(Object.keys(n).length)return n;let r=O([...e.childNodes].filter(e=>e.nodeType!==Node.ELEMENT_NODE||e.tagName.toLowerCase()!==A).map(e=>e.textContent??``).join(``));return{[t]:r}}function P(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 F=typeof HTMLElement>`u`?class{}:HTMLElement,I=class extends F{static get observedAttributes(){return[`language`,`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=!1;#x=null;#S=null;#C=()=>this.#U();#w=null;#T=!0;#E=[];#D=null;#O=null;#k=null;#A=0;#j=!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.#L()}get files(){return this.#z()}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.#R()),this.#u?.forgetFiles([]),this.#L(),this.#B(),this.#I()}get entry(){return this.#R()}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.#B(),this.#I())}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.#z()}reset(){this.#m={...this.#h},this.#g=this.#R(),this.#u?.forgetFiles([]),this.#L(),this.#B(),this.#K(),this.#s.hidden=!0,this.#G(this.#f?.ready?`${this.#f.label} ready`:``,`idle`)}async run(){if(this.#y)return;await this.#d;let e=this.#z(),t=this.#R(),n=e[t]??``;this.#y=!0,this.#n.disabled=!0,this.#r.hidden=!1,this.#K(),this.#s.hidden=!1,this.#$(`py-run`,{code:n,entry:t,files:e,language:this.language});try{let r=await this.#F();this.#G(`Queued…`,`busy`),this.#o.hidden=!1;let i=await r.run(n,{stdin:this.#l.value,files:e,entry:t,onStart:()=>this.#G(`Running…`,`busy`),onStdout:e=>this.#q(e),onStderr:e=>this.#q(e,`cp-err`),onEcho:e=>this.#q(e,`cp-in`),onStdinRequest:()=>this.#Y()});return i.table&&this.#Q(i.table),i.value!==void 0&&this.#q(`${i.value}\n`,`cp-value`),i.hint&&this.#Z(i.hint),i.stderr?(this.#G(`Error · ${i.durationMs} ms`,`error`),this.#$(`py-error`,{message:i.stderr,hint:i.hint,language:this.language})):this.#G(`Done in ${i.durationMs} ms`,`ok`),this.#$(`py-output`,{...i,language:this.language}),i}catch(e){if(e instanceof c)this.#q(`
|
|
265
|
+
[stopped]
|
|
266
|
+
`,`cp-err`),this.#G(`Stopped`,`error`);else{let t=e instanceof Error?e.message:String(e);this.#q(t+`
|
|
267
|
+
`,`cp-err`),this.#G(`Failed to start`,`error`),this.#$(`py-error`,{message:t,language:this.language})}return}finally{this.#X(null),this.#J(),this.#y=!1,this.#n.disabled=!1,this.#r.hidden=!0,this.#o.hidden=!0}}stop(){this.#f?.stop?.()}prewarm(){return this.#F()}connectedCallback(){if(this.#j){this.#P();return}if(!this.textContent?.trim()&&document.readyState===`loading`){document.addEventListener(`DOMContentLoaded`,()=>this.isConnected&&this.#M(),{once:!0});return}this.#M()}disconnectedCallback(){this.#x?.disconnect(),this.#x=null,this.#S?.removeEventListener(`change`,this.#C),this.#S=null,this.#w&&clearTimeout(this.#w),this.#X(null),setTimeout(()=>{this.isConnected||!this.#u||(this.#_=this.#z(),this.#u.destroy(),this.#u=null,this.#d=null,this.#j=!1)},0)}attributeChangedCallback(e,t,n){if(this.#j)switch(e){case`theme`:this.#U();break;case`height`:this.#W();break;case`readonly`:this.#u?.setReadOnly(n!==null);break;case`stdin`:this.#c.hidden=n===null&&!this.#l.value;break;case`entry`:this.#B();break;case`language`:this.#f=null,this.#p=null,this.#b=!1,this.#F().catch(()=>{})}}#M(){this.#j=!0,this.#h=N(this,M(this.language)),this.#m=this.#_??{...this.#h},this.#g=this.#R(),this.#N(),this.#U(),this.#W();let t=this.getAttribute(`persist`);this.#d=(async()=>{if(t&&this.#_==null){let e=await S(t).catch(()=>null),n=e==null?null:P(e,M(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.#R()}}this.#B();let n=await s(this.language).catch(()=>null),r=n?await n.editorLanguage().catch(()=>null):null;this.#u=await e({parent:this.#t,doc:this.#m[this.#g]??``,name:this.#g,dark:this.#H(),readOnly:this.hasAttribute(`readonly`),language:r,onRun:()=>void this.run(),onChange:e=>this.#V(e)}),this.#_=null,this.#I()})(),this.#P()}#N(){let e=document.createElement(`style`);e.textContent=u;let t=document.createElement(`div`);t.className=`cp-root`,t.innerHTML=`
|
|
268
|
+
<div class="cp-toolbar">
|
|
269
|
+
<button class="cp-primary" part="run-button" data-action="run">Run</button>
|
|
270
|
+
<button class="cp-danger" part="stop-button" data-action="stop" hidden>Stop</button>
|
|
271
|
+
<button data-action="reset">Reset</button>
|
|
272
|
+
<span class="cp-spacer"></span>
|
|
273
|
+
<span class="cp-status" data-state="idle"></span>
|
|
274
|
+
</div>
|
|
275
|
+
<div class="cp-progress" hidden></div>
|
|
276
|
+
<div class="cp-tabs" part="tabs" hidden></div>
|
|
277
|
+
<div class="cp-editor"></div>
|
|
278
|
+
<div class="cp-stdin" hidden>
|
|
279
|
+
<label>Standard input — one value per line</label>
|
|
280
|
+
<textarea rows="2" spellcheck="false"></textarea>
|
|
281
|
+
</div>
|
|
282
|
+
<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.#F().catch(()=>{});this.#t.addEventListener(`pointerdown`,n,{once:!0}),this.#t.addEventListener(`focusin`,n,{once:!0})}#P(){this.#x||typeof IntersectionObserver>`u`||(this.#x=new IntersectionObserver(e=>{e.some(e=>e.isIntersecting)&&(this.#x?.disconnect(),this.#x=null,this.#F().then(()=>{this.hasAttribute(`autorun`)&&this.run()}).catch(()=>{}))},{rootMargin:`300px`}),this.#x.observe(this))}#F(){return this.#p||=(async()=>{let e=await s(this.language);this.#f=e,e.ready||(this.#o.hidden=!1,this.#G(`Loading ${e.label}…`,`busy`));try{await e.load(e=>{this.#y||this.#G(e.message,e.phase===`ready`?`ok`:`busy`)})}catch(e){this.#p=null,this.#G(`Runtime unavailable`,`error`);let t=e instanceof Error?e.message:String(e);throw this.#q(t+`
|
|
283
|
+
`,`cp-err`),this.#s.hidden=!1,e}finally{this.#o.hidden=!0}return this.#I(),this.#b||(this.#b=!0,this.#G(`${e.label} ready`,`ok`),this.#$(`py-ready`,{language:e.id,label:e.label})),e})(),this.#p}async#I(){if(!this.#u)return;let e=this.#g,t=await p(e);if(t){this.#g===e&&this.#u?.setLanguage(t);return}let n=e.includes(`.`)?null:await(this.#f??await s(this.language).catch(()=>null))?.editorLanguage().catch(()=>null);this.#g===e&&this.#u?.setLanguage(n??[])}#L(){if(this.#u){this.#u.setCode(this.#m[this.#g]??``);return}this.#d?.then(()=>{this.#u?.setCode(this.#m[this.#g]??``),this.#B()})}#R(){let e=Object.keys(this.#m),t=this.getAttribute(`entry`);if(t&&e.includes(t))return t;let n=M(this.language);return e.includes(n)?n:e[0]??n}#z(){let e={...this.#m};if(this.#u)for(let t of Object.keys(e))e[t]=this.#u.fileCode(t,e[t]);return e}#B(){let e=Object.keys(this.#m);if(this.#v.hidden=e.length<2,this.#v.hidden){this.#v.replaceChildren();return}let t=this.#R();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}))}#V(e){this.#m[this.#g]=e;let t=this.getAttribute(`persist`);if(!t)return;this.#w&&clearTimeout(this.#w);let n=JSON.stringify(this.#z());this.#w=setTimeout(()=>void x(t,n).catch(()=>{}),400)}#H(){let e=this.getAttribute(`theme`)??`auto`;return e===`dark`||e!==`light`&&!!this.#S?.matches}#U(){!this.#S&&typeof matchMedia==`function`&&(this.#S=matchMedia(`(prefers-color-scheme: dark)`),this.#S.addEventListener(`change`,this.#C));let e=this.#H();this.setAttribute(`data-resolved-theme`,e?`dark`:`light`),this.#u?.setTheme(e)}#W(){let e=this.getAttribute(`height`);e&&this.style.setProperty(`--cp-height`,/^\d+$/.test(e)?`${e}px`:e)}#G(e,t){this.#a.textContent=e,this.#a.dataset.state=t}#K(){this.#k&&clearTimeout(this.#k),this.#k=null,this.#E=[],this.#A=0,this.#s.replaceChildren(),this.#T=!0}#q(e,t){if(!e)return;let n=t===`cp-err`&&!this.#T?`\n${e}`:e;this.#T=n.endsWith(`
|
|
284
|
+
`),this.#E.push({text:n,className:t}),this.#k??=setTimeout(()=>this.#J(),16)}#J(){if(this.#k&&clearTimeout(this.#k),this.#k=null,!this.#E.length)return;let e=this.#E;this.#E=[];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.#A>=k)break;let e=t.text;this.#A+e.length>k&&(e=e.slice(0,k-this.#A)+`
|
|
285
|
+
… output truncated for display — the full text is in the py-output event
|
|
286
|
+
`),this.#A+=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}#Y(){return this.#J(),this.#X(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.#D===e&&(this.#D=null,this.#O=null,t.remove(),n===null?this.#q(`
|
|
287
|
+
`,`cp-in`):this.#q(n+`
|
|
288
|
+
`,`cp-in`),this.#J(),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.#D=e,this.#O=a,n.focus({preventScroll:!0})})}#X(e){this.#O?.(e),this.#O=null,this.#D=null}#Z(e){this.#J();let t=document.createElement(`div`);t.className=`cp-hint`,t.textContent=e,this.#s.hidden=!1,this.#s.appendChild(t),this.#s.scrollTop=this.#s.scrollHeight,this.#c.hidden=!1,this.#c.classList.add(`cp-attention`)}#Q(e){this.#J();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)}#$(e,t){this.dispatchEvent(new CustomEvent(e,{detail:t,bubbles:!0,composed:!0}))}};function L(e=D){typeof window>`u`||typeof customElements>`u`||customElements.get(e)||customElements.define(e,I)}L();export{T as a,w as c,s as d,o as f,C as i,c as l,e as m,L as n,S as o,a as p,E as r,x as s,I as t,l as u};
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { Files, Result, Runtime } from './types.js';
|
|
2
|
+
export interface RunEventDetail {
|
|
3
|
+
code: string;
|
|
4
|
+
language: string;
|
|
5
|
+
/** Path of the file being run, e.g. "main.py". */
|
|
6
|
+
entry: string;
|
|
7
|
+
files: Files;
|
|
8
|
+
}
|
|
9
|
+
export interface OutputEventDetail extends Result {
|
|
10
|
+
language: string;
|
|
11
|
+
}
|
|
12
|
+
export interface ErrorEventDetail {
|
|
13
|
+
message: string;
|
|
14
|
+
/** Plain-language guidance, when the runtime could work out the cause. */
|
|
15
|
+
hint?: string;
|
|
16
|
+
language: string;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* `class X extends HTMLElement` is evaluated when the module loads, so importing
|
|
20
|
+
* this package during server rendering (Next.js, Astro, SvelteKit) would throw
|
|
21
|
+
* before defineCodePlayPad() ever got the chance to decline. The stand-in is
|
|
22
|
+
* never instantiated — there is nothing to construct without a DOM.
|
|
23
|
+
*/
|
|
24
|
+
declare const ElementBase: typeof HTMLElement;
|
|
25
|
+
export declare class CodePlayPadElement extends ElementBase {
|
|
26
|
+
#private;
|
|
27
|
+
static get observedAttributes(): string[];
|
|
28
|
+
constructor();
|
|
29
|
+
/** Contents of the file currently on screen. */
|
|
30
|
+
get code(): string;
|
|
31
|
+
set code(value: string);
|
|
32
|
+
/** Every file in this widget, entry point included. */
|
|
33
|
+
get files(): Files;
|
|
34
|
+
set files(value: Files);
|
|
35
|
+
/** Path of the file that gets executed. */
|
|
36
|
+
get entry(): string;
|
|
37
|
+
set entry(value: string);
|
|
38
|
+
/** Bring a file on screen. */
|
|
39
|
+
openFile(name: string): void;
|
|
40
|
+
get stdin(): string;
|
|
41
|
+
set stdin(value: string);
|
|
42
|
+
/** Which runtime executes the code: "python", "javascript" or "typescript".
|
|
43
|
+
* Deliberately not `lang`, which is a standard global HTML attribute for the
|
|
44
|
+
* *human* language of an element's text — putting "python" there would feed
|
|
45
|
+
* a bogus BCP-47 tag to screen readers and `:lang()` selectors. */
|
|
46
|
+
get language(): string;
|
|
47
|
+
set language(value: string);
|
|
48
|
+
getCode(): string;
|
|
49
|
+
getFiles(): Files;
|
|
50
|
+
/** Restore the files the page shipped with. */
|
|
51
|
+
reset(): void;
|
|
52
|
+
/** Runs the entry file, with every other file placed alongside it first. */
|
|
53
|
+
run(): Promise<Result | undefined>;
|
|
54
|
+
stop(): void;
|
|
55
|
+
/** Boot the runtime without running anything. Safe to call repeatedly. */
|
|
56
|
+
prewarm(): Promise<Runtime>;
|
|
57
|
+
connectedCallback(): void;
|
|
58
|
+
disconnectedCallback(): void;
|
|
59
|
+
attributeChangedCallback(name: string, _old: string | null, value: string | null): void;
|
|
60
|
+
}
|
|
61
|
+
/** Register the element. Idempotent, and a no-op during SSR. */
|
|
62
|
+
export declare function defineCodePlayPad(tag?: string): void;
|
|
63
|
+
export {};
|
package/dist/element.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{n as e,t}from"./element-CJuhuMOP.js";export{t as CodePlayPadElement,e as defineCodePlayPad};
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export { CodePlayPadElement, defineCodePlayPad } from './element.js';
|
|
2
|
+
export type { ErrorEventDetail, OutputEventDetail, RunEventDetail } from './element.js';
|
|
3
|
+
export { createEditor } from './editor.js';
|
|
4
|
+
export type { EditorHandle, EditorOptions } from './editor.js';
|
|
5
|
+
export { getRuntime, listRuntimes, registerRuntime } from './runtime/registry.js';
|
|
6
|
+
export { configurePython, configureTypeScript, pyodideAssetUrls, PYODIDE_VERSION } from './runtime/config.js';
|
|
7
|
+
export { RunStopped, WorkerUnavailable } from './types.js';
|
|
8
|
+
export type { Files, LoadProgress, Result, Runtime, RunOptions, Table } from './types.js';
|
|
9
|
+
export { allProgress, clearSnippet, getProgress, loadSnippet, saveSnippet, setProgress } from './progress.js';
|
|
10
|
+
export type { ProgressRecord } from './progress.js';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{a as e,c as t,d as n,f as r,i,l as a,m as o,n as s,o as c,p as l,r as u,s as d,t as f,u as p}from"./element-CJuhuMOP.js";import{n as m,o as h,r as g,t as _}from"./config-DZqcFPEP.js";export{f as CodePlayPadElement,_ as PYODIDE_VERSION,a as RunStopped,p as WorkerUnavailable,u as allProgress,i as clearSnippet,m as configurePython,g as configureTypeScript,o as createEditor,s as defineCodePlayPad,e as getProgress,n as getRuntime,r as listRuntimes,c as loadSnippet,h as pyodideAssetUrls,l as registerRuntime,d as saveSnippet,t as setProgress};
|