wasm-idle 0.2.5 → 0.3.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/dist/clang/app.d.ts +44 -0
- package/dist/clang/app.js +229 -2
- package/dist/clang/index.d.ts +40 -9
- package/dist/clang/index.js +591 -15
- package/dist/clang/memory/memFs.d.ts +3 -1
- package/dist/clang/memory/memFs.js +12 -1
- package/dist/clang/memory/memory.d.ts +8 -4
- package/dist/clang/memory/memory.js +14 -0
- package/dist/clang/memory/tar.d.ts +1 -1
- package/dist/clang/memory/tar.js +1 -1
- package/dist/clang/wasm.d.ts +1 -1
- package/dist/clang/wasm.js +13 -4
- package/dist/clangd/config.d.ts +18 -0
- package/dist/clangd/config.js +14 -0
- package/dist/clangd/jsonStream.d.ts +9 -0
- package/dist/clangd/jsonStream.js +48 -0
- package/dist/clangd/session.d.ts +14 -0
- package/dist/clangd/session.js +94 -0
- package/dist/clangd/worker.d.ts +1 -0
- package/dist/clangd/worker.js +130 -0
- package/dist/debug/editor/index.d.ts +1 -0
- package/dist/debug/editor/index.js +1 -0
- package/dist/debug/editor/monaco.d.ts +18 -0
- package/dist/debug/editor/monaco.js +105 -0
- package/dist/debug/expression.d.ts +2 -0
- package/dist/debug/expression.js +182 -0
- package/dist/debug/index.d.ts +5 -0
- package/dist/debug/index.js +4 -0
- package/dist/debug/language/cpp.d.ts +2 -0
- package/dist/debug/language/cpp.js +7 -0
- package/dist/debug/language/index.d.ts +2 -0
- package/dist/debug/language/index.js +1 -0
- package/dist/debug/language/types.d.ts +6 -0
- package/dist/debug/language/types.js +1 -0
- package/dist/debug/locals.d.ts +2 -0
- package/dist/debug/locals.js +8 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +1 -0
- package/dist/playground/clang.d.ts +8 -2
- package/dist/playground/clang.js +25 -4
- package/dist/playground/options.d.ts +38 -0
- package/dist/playground/options.js +1 -0
- package/dist/playground/python.d.ts +10 -2
- package/dist/playground/python.js +6 -3
- package/dist/playground/sandbox.d.ts +15 -2
- package/dist/playground/worker/clang.js +21 -4
- package/dist/playground/worker/python.js +196 -3
- package/dist/terminal/Terminal.svelte +35 -11
- package/dist/terminal/Terminal.svelte.d.ts +12 -9
- package/dist/terminal/index.d.ts +2 -0
- package/dist/terminal/theme.js +2 -2
- package/dist/terminal/types.d.ts +13 -0
- package/dist/terminal/types.js +1 -0
- package/package.json +42 -33
|
@@ -3,11 +3,12 @@ self.document = {
|
|
|
3
3
|
return [];
|
|
4
4
|
}
|
|
5
5
|
};
|
|
6
|
-
let stdinBufferClang, interruptBufferClang, clang;
|
|
6
|
+
let stdinBufferClang, debugBufferClang, interruptBufferClang, clang;
|
|
7
7
|
async function loadClang(path, log) {
|
|
8
8
|
const { default: Clang } = await import('../../clang');
|
|
9
9
|
clang = new Clang({
|
|
10
10
|
stdout: (output) => postMessage({ output }),
|
|
11
|
+
onDebugEvent: (debugEvent) => postMessage({ debugEvent }),
|
|
11
12
|
stdin: () => {
|
|
12
13
|
while (true) {
|
|
13
14
|
postMessage({ buffer: true });
|
|
@@ -33,16 +34,24 @@ async function loadClang(path, log) {
|
|
|
33
34
|
});
|
|
34
35
|
}
|
|
35
36
|
self.onmessage = async (event) => {
|
|
36
|
-
const { code, buffer, load, interrupt, log, path, prepare, args } = event.data;
|
|
37
|
+
const { code, buffer, debugBuffer, load, interrupt, log, path, prepare, args, debug, breakpoints, pauseOnEntry } = event.data;
|
|
37
38
|
if (load) {
|
|
38
39
|
await loadClang(path, log);
|
|
39
40
|
postMessage({ load: true });
|
|
40
41
|
}
|
|
41
42
|
else if (prepare) {
|
|
42
43
|
stdinBufferClang = new Int32Array(buffer);
|
|
44
|
+
debugBufferClang = new Int32Array(debugBuffer);
|
|
43
45
|
interruptBufferClang = new Uint8Array(interrupt);
|
|
44
46
|
try {
|
|
45
|
-
await clang.compileLink(code, {
|
|
47
|
+
await clang.compileLink(code, {
|
|
48
|
+
args,
|
|
49
|
+
debug,
|
|
50
|
+
breakpoints,
|
|
51
|
+
pauseOnEntry,
|
|
52
|
+
debugBuffer: debugBufferClang,
|
|
53
|
+
interruptBuffer: interruptBufferClang
|
|
54
|
+
});
|
|
46
55
|
self.postMessage({ results: true });
|
|
47
56
|
}
|
|
48
57
|
catch (error) {
|
|
@@ -52,9 +61,17 @@ self.onmessage = async (event) => {
|
|
|
52
61
|
else if (code) {
|
|
53
62
|
clang.log = log;
|
|
54
63
|
stdinBufferClang = new Int32Array(buffer);
|
|
64
|
+
debugBufferClang = new Int32Array(debugBuffer);
|
|
55
65
|
interruptBufferClang = new Uint8Array(interrupt);
|
|
56
66
|
try {
|
|
57
|
-
await clang.compileLinkRun(code, {
|
|
67
|
+
await clang.compileLinkRun(code, {
|
|
68
|
+
args,
|
|
69
|
+
debug,
|
|
70
|
+
breakpoints,
|
|
71
|
+
pauseOnEntry,
|
|
72
|
+
debugBuffer: debugBufferClang,
|
|
73
|
+
interruptBuffer: interruptBufferClang
|
|
74
|
+
});
|
|
58
75
|
self.postMessage({ results: true });
|
|
59
76
|
}
|
|
60
77
|
catch (error) {
|
|
@@ -6,12 +6,200 @@ self.document = {
|
|
|
6
6
|
return [];
|
|
7
7
|
}
|
|
8
8
|
};
|
|
9
|
-
let stdinBufferPyodide, interruptBufferPyodide, pyodide, path = '';
|
|
9
|
+
let stdinBufferPyodide, interruptBufferPyodide, pyodide, path = '', packageBaseUrl = '';
|
|
10
|
+
let jungolRobotReady = false;
|
|
11
|
+
const imageHook = `
|
|
12
|
+
if not globals().get("__wasm_idle_img_inited__", False):
|
|
13
|
+
globals()["__wasm_idle_img_inited__"] = True
|
|
14
|
+
import base64, io, time
|
|
15
|
+
try:
|
|
16
|
+
from js import postMessage
|
|
17
|
+
except Exception:
|
|
18
|
+
postMessage = None
|
|
19
|
+
_MAX_WIDTH = 1280
|
|
20
|
+
_MAX_HEIGHT = 720
|
|
21
|
+
_WEBP_QUALITY = 85
|
|
22
|
+
try:
|
|
23
|
+
from PIL import Image
|
|
24
|
+
_RESAMPLE = Image.Resampling.LANCZOS if hasattr(Image, "Resampling") else Image.LANCZOS
|
|
25
|
+
except Exception:
|
|
26
|
+
Image = None
|
|
27
|
+
_RESAMPLE = None
|
|
28
|
+
|
|
29
|
+
def __wasm_idle_rasterize_svg(raw):
|
|
30
|
+
try:
|
|
31
|
+
import cairosvg
|
|
32
|
+
return cairosvg.svg2png(bytestring=raw)
|
|
33
|
+
except Exception:
|
|
34
|
+
return None
|
|
35
|
+
|
|
36
|
+
def __wasm_idle_to_webp(raw):
|
|
37
|
+
if Image is None or _RESAMPLE is None:
|
|
38
|
+
return None
|
|
39
|
+
try:
|
|
40
|
+
img = Image.open(io.BytesIO(raw))
|
|
41
|
+
img.load()
|
|
42
|
+
if _MAX_WIDTH > 0 and _MAX_HEIGHT > 0:
|
|
43
|
+
img.thumbnail((_MAX_WIDTH, _MAX_HEIGHT), _RESAMPLE)
|
|
44
|
+
if img.mode not in ("RGB", "RGBA"):
|
|
45
|
+
img = img.convert("RGBA" if "A" in img.mode else "RGB")
|
|
46
|
+
buf = io.BytesIO()
|
|
47
|
+
img.save(buf, format="WEBP", quality=_WEBP_QUALITY, method=6)
|
|
48
|
+
return buf.getvalue()
|
|
49
|
+
except Exception:
|
|
50
|
+
return None
|
|
51
|
+
|
|
52
|
+
def __wasm_idle_send_img(mime, raw):
|
|
53
|
+
try:
|
|
54
|
+
if postMessage is None:
|
|
55
|
+
return
|
|
56
|
+
if raw is None:
|
|
57
|
+
return
|
|
58
|
+
if isinstance(raw, str):
|
|
59
|
+
raw_bytes = raw.encode("utf-8")
|
|
60
|
+
else:
|
|
61
|
+
raw_bytes = raw
|
|
62
|
+
if mime == "image/svg+xml":
|
|
63
|
+
raster = __wasm_idle_rasterize_svg(raw_bytes)
|
|
64
|
+
if raster:
|
|
65
|
+
raw_bytes = raster
|
|
66
|
+
mime = "image/png"
|
|
67
|
+
webp = __wasm_idle_to_webp(raw_bytes)
|
|
68
|
+
if webp:
|
|
69
|
+
raw_bytes = webp
|
|
70
|
+
mime = "image/webp"
|
|
71
|
+
b64 = base64.b64encode(raw_bytes).decode("ascii")
|
|
72
|
+
ts = int(time.time() * 1000)
|
|
73
|
+
postMessage({"type": "img", "data": {"mime": mime, "b64": b64, "ts": ts}})
|
|
74
|
+
except Exception:
|
|
75
|
+
pass
|
|
76
|
+
|
|
77
|
+
def __wasm_idle_capture_fig(fig):
|
|
78
|
+
try:
|
|
79
|
+
buf = io.BytesIO()
|
|
80
|
+
fig.savefig(buf, format="png", bbox_inches="tight")
|
|
81
|
+
__wasm_idle_send_img("image/png", buf.getvalue())
|
|
82
|
+
buf.close()
|
|
83
|
+
except Exception:
|
|
84
|
+
pass
|
|
85
|
+
|
|
86
|
+
try:
|
|
87
|
+
import matplotlib
|
|
88
|
+
matplotlib.use("Agg")
|
|
89
|
+
import matplotlib.pyplot as plt
|
|
90
|
+
from matplotlib.figure import Figure
|
|
91
|
+
_orig_show = plt.show
|
|
92
|
+
|
|
93
|
+
def _show(*args, **kwargs):
|
|
94
|
+
try:
|
|
95
|
+
figs = [plt.figure(num) for num in plt.get_fignums()]
|
|
96
|
+
if not figs:
|
|
97
|
+
figs = [plt.gcf()]
|
|
98
|
+
for fig in figs:
|
|
99
|
+
__wasm_idle_capture_fig(fig)
|
|
100
|
+
plt.close("all")
|
|
101
|
+
except Exception:
|
|
102
|
+
pass
|
|
103
|
+
try:
|
|
104
|
+
return _orig_show(*args, **kwargs)
|
|
105
|
+
except Exception:
|
|
106
|
+
return None
|
|
107
|
+
|
|
108
|
+
plt.show = _show
|
|
109
|
+
|
|
110
|
+
_orig_fig_show = Figure.show
|
|
111
|
+
|
|
112
|
+
def _fig_show(self, *args, **kwargs):
|
|
113
|
+
try:
|
|
114
|
+
__wasm_idle_capture_fig(self)
|
|
115
|
+
except Exception:
|
|
116
|
+
pass
|
|
117
|
+
try:
|
|
118
|
+
return _orig_fig_show(self, *args, **kwargs)
|
|
119
|
+
except Exception:
|
|
120
|
+
return None
|
|
121
|
+
|
|
122
|
+
Figure.show = _fig_show
|
|
123
|
+
except Exception:
|
|
124
|
+
pass
|
|
125
|
+
|
|
126
|
+
try:
|
|
127
|
+
from IPython import display as _ip_display
|
|
128
|
+
_orig_display = _ip_display.display
|
|
129
|
+
|
|
130
|
+
def _display(*objs, **kwargs):
|
|
131
|
+
for obj in objs:
|
|
132
|
+
try:
|
|
133
|
+
if hasattr(obj, "_repr_png_"):
|
|
134
|
+
data = obj._repr_png_()
|
|
135
|
+
if data:
|
|
136
|
+
__wasm_idle_send_img("image/png", data)
|
|
137
|
+
continue
|
|
138
|
+
if hasattr(obj, "_repr_svg_"):
|
|
139
|
+
data = obj._repr_svg_()
|
|
140
|
+
if data:
|
|
141
|
+
__wasm_idle_send_img("image/svg+xml", data)
|
|
142
|
+
continue
|
|
143
|
+
except Exception:
|
|
144
|
+
pass
|
|
145
|
+
try:
|
|
146
|
+
return _orig_display(*objs, **kwargs)
|
|
147
|
+
except Exception:
|
|
148
|
+
return None
|
|
149
|
+
|
|
150
|
+
_ip_display.display = _display
|
|
151
|
+
except Exception:
|
|
152
|
+
pass
|
|
153
|
+
`;
|
|
154
|
+
const cdnFallbackUrl = (version) => version ? `https://cdn.jsdelivr.net/pyodide/v${version}/full/` : '';
|
|
10
155
|
async function loadPyodide(path) {
|
|
11
156
|
if (pyodide)
|
|
12
157
|
return;
|
|
13
158
|
const { loadPyodide } = await import('pyodide');
|
|
14
159
|
pyodide = await loadPyodide({ indexURL: path + '/pyodide' });
|
|
160
|
+
packageBaseUrl = path + '/pyodide';
|
|
161
|
+
const setCdnUrl = pyodide?.setCdnUrl;
|
|
162
|
+
if (typeof setCdnUrl === 'function')
|
|
163
|
+
setCdnUrl(packageBaseUrl);
|
|
164
|
+
}
|
|
165
|
+
async function ensureRobotJungol() {
|
|
166
|
+
if (jungolRobotReady || !pyodide)
|
|
167
|
+
return;
|
|
168
|
+
try {
|
|
169
|
+
const res = await fetch(path + '/jungol-robot/jungol_robot.zip');
|
|
170
|
+
if (!res.ok)
|
|
171
|
+
throw new Error('jungol-robot zip not found');
|
|
172
|
+
const data = await res.arrayBuffer();
|
|
173
|
+
const siteRaw = pyodide.runPython('import site; site.getsitepackages()[0]');
|
|
174
|
+
const sitePath = typeof siteRaw === 'string' ? siteRaw : siteRaw.toString();
|
|
175
|
+
const unpackArchive = pyodide?.unpackArchive;
|
|
176
|
+
if (typeof unpackArchive !== 'function')
|
|
177
|
+
throw new Error('pyodide.unpackArchive unavailable');
|
|
178
|
+
unpackArchive(data, 'zip', sitePath);
|
|
179
|
+
pyodide.runPython('import importlib; importlib.invalidate_caches()');
|
|
180
|
+
jungolRobotReady = true;
|
|
181
|
+
}
|
|
182
|
+
catch (e) {
|
|
183
|
+
console.warn('jungol-robot preload failed', e);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
async function loadPackages(code) {
|
|
187
|
+
if (!code)
|
|
188
|
+
return;
|
|
189
|
+
try {
|
|
190
|
+
await pyodide.loadPackagesFromImports(code);
|
|
191
|
+
}
|
|
192
|
+
catch (e) {
|
|
193
|
+
const fallback = cdnFallbackUrl(pyodide?.version || '');
|
|
194
|
+
const setCdnUrl = pyodide?.setCdnUrl;
|
|
195
|
+
if (fallback && fallback !== packageBaseUrl && typeof setCdnUrl === 'function') {
|
|
196
|
+
setCdnUrl(fallback);
|
|
197
|
+
packageBaseUrl = fallback;
|
|
198
|
+
await pyodide.loadPackagesFromImports(code);
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
throw e;
|
|
202
|
+
}
|
|
15
203
|
}
|
|
16
204
|
self.onmessage = async (event) => {
|
|
17
205
|
const { code, buffer, load, interrupt, path: _p, prepare } = event.data;
|
|
@@ -19,6 +207,7 @@ self.onmessage = async (event) => {
|
|
|
19
207
|
path = _p;
|
|
20
208
|
postMessage({ output: 'Loading Pyodide...' });
|
|
21
209
|
await loadPyodide(path);
|
|
210
|
+
await ensureRobotJungol();
|
|
22
211
|
postMessage({ output: ' Done.\n\r' });
|
|
23
212
|
postMessage({ load: true });
|
|
24
213
|
}
|
|
@@ -26,7 +215,8 @@ self.onmessage = async (event) => {
|
|
|
26
215
|
postMessage({ output: 'Loading packages...' });
|
|
27
216
|
try {
|
|
28
217
|
await loadPyodide(path);
|
|
29
|
-
await
|
|
218
|
+
await ensureRobotJungol();
|
|
219
|
+
await loadPackages(code);
|
|
30
220
|
postMessage({ output: ' Done.\n\r' });
|
|
31
221
|
self.postMessage({ results: true });
|
|
32
222
|
}
|
|
@@ -36,7 +226,8 @@ self.onmessage = async (event) => {
|
|
|
36
226
|
}
|
|
37
227
|
else if (code) {
|
|
38
228
|
await loadPyodide(path);
|
|
39
|
-
await
|
|
229
|
+
await ensureRobotJungol();
|
|
230
|
+
await loadPackages(code);
|
|
40
231
|
const ts = Date.now();
|
|
41
232
|
stdinBufferPyodide = new Int32Array(buffer);
|
|
42
233
|
interruptBufferPyodide = new Uint8Array(interrupt);
|
|
@@ -103,6 +294,8 @@ print = __pyodide__output_${ts}
|
|
|
103
294
|
__builtins__.input = __pyodide__input_${ts}
|
|
104
295
|
__builtins__.print = __pyodide__output_${ts}
|
|
105
296
|
|
|
297
|
+
${imageHook}
|
|
298
|
+
|
|
106
299
|
${code}`);
|
|
107
300
|
self.postMessage({ results: true });
|
|
108
301
|
}
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
+
import type { DebugCommand, DebugSessionEvent, SandboxExecutionOptions } from '../playground/options';
|
|
2
3
|
import type { Sandbox } from '../playground/sandbox';
|
|
4
|
+
import type { TerminalControl } from './types';
|
|
3
5
|
import { Theme, registerAllPlugins } from './';
|
|
4
6
|
import load from '../playground';
|
|
5
7
|
import { onMount } from 'svelte';
|
|
6
8
|
import '@xterm/xterm/css/xterm.css';
|
|
7
9
|
import type { Terminal as TerminalType } from '@xterm/xterm';
|
|
8
10
|
|
|
9
|
-
type TerminalControl = typeof terminalControl;
|
|
10
11
|
interface Props {
|
|
11
12
|
dark?: boolean;
|
|
12
13
|
path?: string;
|
|
@@ -15,6 +16,8 @@
|
|
|
15
16
|
onload?: () => void;
|
|
16
17
|
onfinish?: () => void;
|
|
17
18
|
onkey?: (e: KeyboardEvent) => void;
|
|
19
|
+
ondebug?: (event: DebugSessionEvent) => void;
|
|
20
|
+
onimage?: (payload: { mime: string; b64: string; ts?: number }) => void;
|
|
18
21
|
terminal?: TerminalControl;
|
|
19
22
|
}
|
|
20
23
|
|
|
@@ -25,6 +28,8 @@
|
|
|
25
28
|
onload,
|
|
26
29
|
onfinish,
|
|
27
30
|
onkey,
|
|
31
|
+
ondebug,
|
|
32
|
+
onimage,
|
|
28
33
|
terminal = $bindable()
|
|
29
34
|
}: Props = $props();
|
|
30
35
|
|
|
@@ -62,11 +67,13 @@
|
|
|
62
67
|
await sandbox.clear();
|
|
63
68
|
ll = language;
|
|
64
69
|
}
|
|
70
|
+
sandbox.image = onimage;
|
|
71
|
+
sandbox.ondebug = ondebug;
|
|
65
72
|
sandbox.output = (output: string) =>
|
|
66
73
|
_tc === tc && term && term.write(output.replaceAll('\n', '\r\n'));
|
|
67
74
|
}
|
|
68
75
|
|
|
69
|
-
function runSandbox(pr: Promise<
|
|
76
|
+
function runSandbox<T>(pr: Promise<T>) {
|
|
70
77
|
return pr
|
|
71
78
|
.then((x) => {
|
|
72
79
|
term?.write(`\r\nProcess finished after ${sandbox.elapse}ms\u001B[?25l`);
|
|
@@ -76,11 +83,10 @@
|
|
|
76
83
|
term?.write(`\r\n\x1B[1;3;31m${msg}\u001B[?25l`);
|
|
77
84
|
return false;
|
|
78
85
|
})
|
|
79
|
-
.finally((
|
|
86
|
+
.finally(() => {
|
|
80
87
|
onfinish?.();
|
|
81
88
|
finish = true;
|
|
82
89
|
if (term) term.options.cursorBlink = false;
|
|
83
|
-
return ret;
|
|
84
90
|
});
|
|
85
91
|
}
|
|
86
92
|
|
|
@@ -94,7 +100,7 @@
|
|
|
94
100
|
first = false;
|
|
95
101
|
}
|
|
96
102
|
|
|
97
|
-
const terminalControl = {
|
|
103
|
+
const terminalControl: TerminalControl = {
|
|
98
104
|
async clear() {
|
|
99
105
|
await wait();
|
|
100
106
|
term?.reset();
|
|
@@ -103,25 +109,43 @@
|
|
|
103
109
|
first = true;
|
|
104
110
|
await new Promise((r) => setTimeout(r, 100));
|
|
105
111
|
},
|
|
106
|
-
async prepare(
|
|
112
|
+
async prepare(
|
|
113
|
+
language: string,
|
|
114
|
+
code: string,
|
|
115
|
+
log = true,
|
|
116
|
+
prog?: { set?: (value: number) => void },
|
|
117
|
+
args: string[] = [],
|
|
118
|
+
options: SandboxExecutionOptions = {}
|
|
119
|
+
) {
|
|
107
120
|
await Promise.all([
|
|
108
|
-
initSandbox(language).then(() => sandbox.load(path, code, log)),
|
|
121
|
+
initSandbox(language).then(() => sandbox.load(path, code, log, args, options)),
|
|
109
122
|
initTerm(false)
|
|
110
123
|
]);
|
|
111
|
-
return await runSandbox(sandbox.run(code, true, log, prog, args));
|
|
124
|
+
return !!(await runSandbox(sandbox.run(code, true, log, prog, args, options)));
|
|
112
125
|
},
|
|
113
|
-
async run(
|
|
126
|
+
async run(
|
|
127
|
+
language: string,
|
|
128
|
+
code: string,
|
|
129
|
+
log = true,
|
|
130
|
+
prog?: { set?: (value: number) => void },
|
|
131
|
+
args: string[] = [],
|
|
132
|
+
options: SandboxExecutionOptions = {}
|
|
133
|
+
) {
|
|
114
134
|
await Promise.all([
|
|
115
|
-
initSandbox(language).then(() => sandbox.load(path, code, log)),
|
|
135
|
+
initSandbox(language).then(() => sandbox.load(path, code, log, args, options)),
|
|
116
136
|
initTerm()
|
|
117
137
|
]);
|
|
118
|
-
return await runSandbox(sandbox.run(code, false, log, prog, args));
|
|
138
|
+
return await runSandbox(sandbox.run(code, false, log, prog, args, options));
|
|
119
139
|
},
|
|
120
140
|
async destroy() {
|
|
121
141
|
await wait();
|
|
122
142
|
term?.dispose();
|
|
123
143
|
if (sandbox) await sandbox.clear();
|
|
124
144
|
},
|
|
145
|
+
async debugCommand(command: DebugCommand) {
|
|
146
|
+
await wait();
|
|
147
|
+
sandbox.debugCommand?.(command);
|
|
148
|
+
},
|
|
125
149
|
async write(input: string) {
|
|
126
150
|
await wait();
|
|
127
151
|
term?.write(input + '\r\n');
|
|
@@ -1,18 +1,21 @@
|
|
|
1
|
+
import type { DebugSessionEvent } from '../playground/options';
|
|
2
|
+
import type { TerminalControl } from './types';
|
|
1
3
|
import '@xterm/xterm/css/xterm.css';
|
|
2
|
-
|
|
4
|
+
interface Props {
|
|
3
5
|
dark?: boolean;
|
|
4
6
|
path?: string;
|
|
5
7
|
font?: string;
|
|
6
8
|
onload?: () => void;
|
|
7
9
|
onfinish?: () => void;
|
|
8
10
|
onkey?: (e: KeyboardEvent) => void;
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
}
|
|
11
|
+
ondebug?: (event: DebugSessionEvent) => void;
|
|
12
|
+
onimage?: (payload: {
|
|
13
|
+
mime: string;
|
|
14
|
+
b64: string;
|
|
15
|
+
ts?: number;
|
|
16
|
+
}) => void;
|
|
17
|
+
terminal?: TerminalControl;
|
|
18
|
+
}
|
|
19
|
+
declare const Terminal: import("svelte").Component<Props, {}, "terminal">;
|
|
17
20
|
type Terminal = ReturnType<typeof Terminal>;
|
|
18
21
|
export default Terminal;
|
package/dist/terminal/index.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import Theme from './theme';
|
|
2
2
|
import registerAllPlugins from './plugin';
|
|
3
3
|
import Terminal from './Terminal.svelte';
|
|
4
|
+
import type { DebugCommand, DebugFrame, DebugSessionEvent, DebugVariable, SandboxExecutionOptions, TerminalControl } from './types';
|
|
4
5
|
export { Theme, registerAllPlugins };
|
|
6
|
+
export type { DebugCommand, DebugFrame, DebugSessionEvent, DebugVariable, SandboxExecutionOptions, TerminalControl };
|
|
5
7
|
export default Terminal;
|
package/dist/terminal/theme.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const theme = {
|
|
2
2
|
Tango_Dark: {
|
|
3
3
|
foreground: '#eee',
|
|
4
|
-
background: '#
|
|
4
|
+
background: '#111827',
|
|
5
5
|
cursor: '#FFFFFF',
|
|
6
6
|
cursorAccent: '#ffffff',
|
|
7
7
|
selection: '#ffffff44',
|
|
@@ -24,7 +24,7 @@ const theme = {
|
|
|
24
24
|
},
|
|
25
25
|
Tango_Light: {
|
|
26
26
|
foreground: '#111',
|
|
27
|
-
background: '#
|
|
27
|
+
background: '#FFFFFF',
|
|
28
28
|
cursor: '#000000',
|
|
29
29
|
cursorAccent: '#000000',
|
|
30
30
|
selection: '#00000044',
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { DebugCommand, DebugFrame, DebugSessionEvent, DebugVariable, SandboxExecutionOptions } from '../playground/options';
|
|
2
|
+
export interface ProgressLike {
|
|
3
|
+
set?: (value: number) => void;
|
|
4
|
+
}
|
|
5
|
+
export interface TerminalControl {
|
|
6
|
+
clear: () => Promise<void>;
|
|
7
|
+
prepare: (language: string, code: string, log?: boolean, prog?: ProgressLike, args?: string[], options?: SandboxExecutionOptions) => Promise<boolean>;
|
|
8
|
+
run: (language: string, code: string, log?: boolean, prog?: ProgressLike, args?: string[], options?: SandboxExecutionOptions) => Promise<boolean | string>;
|
|
9
|
+
destroy: () => Promise<void>;
|
|
10
|
+
debugCommand: (command: DebugCommand) => Promise<void>;
|
|
11
|
+
write: (input: string) => Promise<void>;
|
|
12
|
+
}
|
|
13
|
+
export type { DebugCommand, DebugFrame, DebugSessionEvent, DebugVariable, SandboxExecutionOptions };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wasm-idle",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "A simple web app to run C++/Python code in the browser",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -10,49 +10,58 @@
|
|
|
10
10
|
"preview": "vite preview",
|
|
11
11
|
"package": "svelte-kit sync && svelte-package && publint",
|
|
12
12
|
"prepublishOnly": "npm run package",
|
|
13
|
+
"test": "vitest run",
|
|
14
|
+
"test:watch": "vitest",
|
|
13
15
|
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
|
14
16
|
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
|
|
15
17
|
"lint": "prettier --check . && eslint .",
|
|
16
|
-
"format": "prettier --write ."
|
|
18
|
+
"format": "prettier --write .",
|
|
19
|
+
"page": "npm run build && node gh-pages.js"
|
|
17
20
|
},
|
|
18
21
|
"devDependencies": {
|
|
19
|
-
"@eslint/js": "^
|
|
20
|
-
"@sveltejs/adapter-auto": "^
|
|
21
|
-
"@sveltejs/adapter-static": "^3.0.
|
|
22
|
-
"@sveltejs/kit": "^2.
|
|
23
|
-
"@sveltejs/package": "^2.
|
|
24
|
-
"@sveltejs/vite-plugin-svelte": "^
|
|
25
|
-
"@
|
|
26
|
-
"@
|
|
27
|
-
"eslint": "^
|
|
28
|
-
"eslint
|
|
29
|
-
"eslint
|
|
22
|
+
"@eslint/js": "^10.0.1",
|
|
23
|
+
"@sveltejs/adapter-auto": "^7.0.1",
|
|
24
|
+
"@sveltejs/adapter-static": "^3.0.10",
|
|
25
|
+
"@sveltejs/kit": "^2.53.4",
|
|
26
|
+
"@sveltejs/package": "^2.5.7",
|
|
27
|
+
"@sveltejs/vite-plugin-svelte": "^6.2.4",
|
|
28
|
+
"@testing-library/svelte": "^5.3.1",
|
|
29
|
+
"@testing-library/user-event": "^14.6.1",
|
|
30
|
+
"@typescript-eslint/eslint-plugin": "^8.57.0",
|
|
31
|
+
"@typescript-eslint/parser": "^8.57.0",
|
|
32
|
+
"eslint": "^10.0.3",
|
|
33
|
+
"eslint-config-prettier": "^10.1.8",
|
|
34
|
+
"eslint-plugin-svelte": "^3.15.2",
|
|
30
35
|
"eslint-plugin-svelte3": "^4.0.0",
|
|
31
36
|
"gh-pages": "^6.3.0",
|
|
32
|
-
"globals": "^
|
|
33
|
-
"
|
|
34
|
-
"
|
|
35
|
-
"prettier
|
|
36
|
-
"svelte": "^5.
|
|
37
|
-
"svelte
|
|
37
|
+
"globals": "^17.4.0",
|
|
38
|
+
"jsdom": "^28.1.0",
|
|
39
|
+
"monaco-editor": "^0.55.1",
|
|
40
|
+
"prettier": "^3.8.1",
|
|
41
|
+
"prettier-plugin-svelte": "^3.5.1",
|
|
42
|
+
"svelte": "^5.53.10",
|
|
43
|
+
"svelte-check": "^4.4.5",
|
|
38
44
|
"tslib": "^2.8.1",
|
|
39
|
-
"typescript": "^5.
|
|
40
|
-
"typescript-eslint": "^8.
|
|
41
|
-
"vite": "^
|
|
45
|
+
"typescript": "^5.9.3",
|
|
46
|
+
"typescript-eslint": "^8.57.0",
|
|
47
|
+
"vite": "^7.3.1",
|
|
48
|
+
"vitest": "^4.0.18"
|
|
42
49
|
},
|
|
43
50
|
"dependencies": {
|
|
51
|
+
"@hancomac/monaco-languageclient": "^1.1.0",
|
|
44
52
|
"@xterm/addon-canvas": "^0.7.0",
|
|
45
|
-
"@xterm/addon-fit": "^0.
|
|
46
|
-
"@xterm/addon-ligatures": "^0.
|
|
47
|
-
"@xterm/addon-search": "^0.
|
|
48
|
-
"@xterm/addon-serialize": "^0.
|
|
49
|
-
"@xterm/addon-unicode11": "^0.
|
|
50
|
-
"@xterm/addon-web-links": "^0.
|
|
51
|
-
"@xterm/addon-webgl": "^0.
|
|
52
|
-
"@xterm/xterm": "^
|
|
53
|
-
"@zip.js/zip.js": "^2.
|
|
54
|
-
"publint": "^0.3.
|
|
55
|
-
"pyodide": "0.26.2"
|
|
53
|
+
"@xterm/addon-fit": "^0.11.0",
|
|
54
|
+
"@xterm/addon-ligatures": "^0.10.0",
|
|
55
|
+
"@xterm/addon-search": "^0.16.0",
|
|
56
|
+
"@xterm/addon-serialize": "^0.14.0",
|
|
57
|
+
"@xterm/addon-unicode11": "^0.9.0",
|
|
58
|
+
"@xterm/addon-web-links": "^0.12.0",
|
|
59
|
+
"@xterm/addon-webgl": "^0.19.0",
|
|
60
|
+
"@xterm/xterm": "^6.0.0",
|
|
61
|
+
"@zip.js/zip.js": "^2.8.23",
|
|
62
|
+
"publint": "^0.3.18",
|
|
63
|
+
"pyodide": "0.26.2",
|
|
64
|
+
"vscode-jsonrpc": "^8.2.1"
|
|
56
65
|
},
|
|
57
66
|
"files": [
|
|
58
67
|
"dist",
|