wasm-idle 0.4.1 → 0.5.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.
Files changed (39) hide show
  1. package/README.md +94 -3
  2. package/dist/clang/app.d.ts +4 -0
  3. package/dist/clang/app.js +315 -12
  4. package/dist/clang/index.d.ts +4 -0
  5. package/dist/clang/index.js +151 -8
  6. package/dist/debug/controller.svelte.d.ts +43 -0
  7. package/dist/debug/controller.svelte.js +268 -0
  8. package/dist/debug/editor/index.d.ts +2 -1
  9. package/dist/debug/editor/index.js +1 -1
  10. package/dist/debug/editor/monaco.d.ts +8 -0
  11. package/dist/debug/editor/monaco.js +23 -0
  12. package/dist/debug/expression.d.ts +24 -0
  13. package/dist/debug/expression.js +307 -138
  14. package/dist/debug/index.d.ts +4 -1
  15. package/dist/debug/index.js +2 -1
  16. package/dist/index.d.ts +5 -3
  17. package/dist/index.js +3 -3
  18. package/dist/playground/assets.d.ts +5 -0
  19. package/dist/playground/assets.js +8 -0
  20. package/dist/playground/clang.d.ts +5 -0
  21. package/dist/playground/clang.js +45 -2
  22. package/dist/playground/index.d.ts +5 -5
  23. package/dist/playground/index.js +45 -5
  24. package/dist/playground/options.d.ts +9 -0
  25. package/dist/playground/python.d.ts +1 -0
  26. package/dist/playground/python.js +12 -0
  27. package/dist/playground/rust.d.ts +32 -0
  28. package/dist/playground/rust.js +175 -0
  29. package/dist/playground/sandbox.d.ts +18 -4
  30. package/dist/playground/wasmRustVersion.d.ts +1 -0
  31. package/dist/playground/wasmRustVersion.js +1 -0
  32. package/dist/playground/worker/clang.js +12 -4
  33. package/dist/playground/worker/rust.d.ts +1 -0
  34. package/dist/playground/worker/rust.js +159 -0
  35. package/dist/terminal/Terminal.svelte +78 -25
  36. package/dist/terminal/Terminal.svelte.d.ts +2 -0
  37. package/dist/terminal/theme.js +2 -2
  38. package/dist/terminal/types.d.ts +3 -0
  39. package/package.json +15 -9
@@ -1,5 +1,6 @@
1
1
  import { resolveSandboxExecutionArgs } from './options';
2
- import { flushBufferedEof, flushQueuedStdin, resetBufferedStdin } from './stdinBuffer';
2
+ import { bufferedSequence, flushBufferedEof, flushQueuedStdin, resetBufferedStdin, waitForBufferedSequenceChange } from './stdinBuffer';
3
+ const debugBreakpointBufferInts = 1028;
3
4
  class Clang {
4
5
  language;
5
6
  ts = Date.now();
@@ -7,7 +8,9 @@ class Clang {
7
8
  ondebug;
8
9
  worker = null;
9
10
  buffer = new SharedArrayBuffer(1024);
10
- debugBuffer = new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4);
11
+ debugBuffer = new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * debugBreakpointBufferInts);
12
+ watchBuffer = new SharedArrayBuffer(1024);
13
+ watchResultBuffer = new SharedArrayBuffer(1024);
11
14
  interruptBuffer = new SharedArrayBuffer(1);
12
15
  pendingInput = [];
13
16
  begin = 0;
@@ -17,6 +20,7 @@ class Clang {
17
20
  waitingForInput = false;
18
21
  pendingEof = false;
19
22
  exit = true;
23
+ activeReject = null;
20
24
  constructor(language) {
21
25
  this.language = language;
22
26
  }
@@ -65,7 +69,9 @@ class Clang {
65
69
  return new Promise(async (resolve, reject) => {
66
70
  if (!this.worker)
67
71
  return reject('Worker not loaded');
72
+ this.activeReject = reject;
68
73
  const { compileArgs, programArgs } = resolveSandboxExecutionArgs(this.language, args, options);
74
+ this.setBreakpoints(options.debug ? [...(options.breakpoints || [])] : []);
69
75
  const interrupt = new Uint8Array(this.interruptBuffer), _uid = ++this.uid;
70
76
  const handler = (event) => {
71
77
  if (!this.worker)
@@ -86,6 +92,7 @@ class Clang {
86
92
  this.exit = true;
87
93
  this.waitingForInput = false;
88
94
  this.pendingEof = false;
95
+ this.activeReject = null;
89
96
  this.ondebug?.({ type: 'stop' });
90
97
  resolve(results);
91
98
  }
@@ -95,6 +102,7 @@ class Clang {
95
102
  this.elapse = Date.now() - this.begin;
96
103
  this.waitingForInput = false;
97
104
  this.pendingEof = false;
105
+ this.activeReject = null;
98
106
  this.exit = true;
99
107
  this.ondebug?.({ type: 'stop' });
100
108
  reject(error);
@@ -110,6 +118,8 @@ class Clang {
110
118
  prepare,
111
119
  buffer: this.buffer,
112
120
  debugBuffer: this.debugBuffer,
121
+ watchBuffer: this.watchBuffer,
122
+ watchResultBuffer: this.watchResultBuffer,
113
123
  interrupt: this.interruptBuffer,
114
124
  context: {},
115
125
  log,
@@ -131,15 +141,46 @@ class Clang {
131
141
  Atomics.notify(control, 0);
132
142
  this.ondebug?.({ type: 'resume', command });
133
143
  }
144
+ setBreakpoints(lines) {
145
+ const control = new Int32Array(this.debugBuffer);
146
+ const next = [...new Set(lines.filter((line) => Number.isInteger(line) && line > 0))]
147
+ .sort((left, right) => left - right)
148
+ .slice(0, Math.max(0, control.length - 4));
149
+ for (let index = 4; index < control.length; index += 1) {
150
+ Atomics.store(control, index, next[index - 4] || 0);
151
+ }
152
+ Atomics.store(control, 3, next.length);
153
+ Atomics.add(control, 2, 1);
154
+ }
155
+ async debugEvaluate(expression) {
156
+ if (!this.worker)
157
+ throw new Error('Worker not loaded');
158
+ resetBufferedStdin(this.watchResultBuffer);
159
+ const previousSequence = bufferedSequence(this.watchResultBuffer);
160
+ flushQueuedStdin([expression], this.watchBuffer);
161
+ const control = new Int32Array(this.debugBuffer);
162
+ Atomics.store(control, 1, 5);
163
+ Atomics.add(control, 0, 1);
164
+ Atomics.notify(control, 0);
165
+ return ((await waitForBufferedSequenceChange(this.watchResultBuffer, previousSequence, 5000)) ??
166
+ '?');
167
+ }
134
168
  kill() {
135
169
  this.terminate();
136
170
  }
137
171
  terminate() {
172
+ this.activeReject?.('Process terminated');
173
+ this.activeReject = null;
174
+ this.waitingForInput = false;
138
175
  this.pendingEof = false;
176
+ this.uid += 1;
139
177
  new Uint8Array(this.interruptBuffer)[0] = 2;
140
178
  const control = new Int32Array(this.debugBuffer);
141
179
  Atomics.add(control, 0, 1);
142
180
  Atomics.notify(control, 0);
181
+ this.worker?.terminate?.();
182
+ delete this.worker;
183
+ this.exit = true;
143
184
  }
144
185
  async clear() {
145
186
  this.terminate();
@@ -149,6 +190,8 @@ class Clang {
149
190
  if (this.worker)
150
191
  this.worker.onmessage = null;
151
192
  resetBufferedStdin(this.buffer);
193
+ resetBufferedStdin(this.watchBuffer);
194
+ resetBufferedStdin(this.watchResultBuffer);
152
195
  const debugBuffer = new Int32Array(this.debugBuffer);
153
196
  debugBuffer.fill(0);
154
197
  await new Promise((resolve) => setTimeout(resolve, 200));
@@ -1,6 +1,6 @@
1
- import Clang from './clang';
2
- import Java from './java';
3
- import Python from './python';
4
- import type { Sandbox } from './sandbox';
1
+ import type { BoundSandbox, PlaygroundBinding, Sandbox, SandboxRuntimeAssets } from './sandbox';
5
2
  export declare const supportedLanguages: string[];
6
- export default function load(language: string): Promise<Sandbox | Clang | Java | Python>;
3
+ export declare function createPlaygroundBinding(runtimeAssets: SandboxRuntimeAssets): PlaygroundBinding;
4
+ declare function playground(language: string): Promise<Sandbox>;
5
+ declare function playground(language: string, runtimeAssets: SandboxRuntimeAssets): Promise<BoundSandbox>;
6
+ export default playground;
@@ -1,11 +1,45 @@
1
1
  import Clang from './clang';
2
2
  import Java from './java';
3
3
  import Python from './python';
4
+ import Rust from './rust';
4
5
  const sandboxCache = {};
5
- export const supportedLanguages = ['PYTHON3', 'PYPY3', 'C', 'CPP', 'JAVA'];
6
- export default async function load(language) {
7
- if (sandboxCache[language])
8
- return sandboxCache[language];
6
+ export const supportedLanguages = ['PYTHON3', 'PYPY3', 'C', 'CPP', 'JAVA', 'RUST'];
7
+ function bindRuntimeAssets(sandbox, runtimeAssets) {
8
+ return new Proxy(sandbox, {
9
+ get(target, prop, receiver) {
10
+ if (prop === 'runtimeAssets')
11
+ return runtimeAssets;
12
+ if (prop === 'load') {
13
+ return (code = '', log = true, args = [], options = {}, progress) => target.load(runtimeAssets, code, log, args, options, progress);
14
+ }
15
+ const value = Reflect.get(target, prop, receiver);
16
+ return typeof value === 'function' ? value.bind(target) : value;
17
+ },
18
+ set(target, prop, value, receiver) {
19
+ return Reflect.set(target, prop, value, receiver);
20
+ }
21
+ });
22
+ }
23
+ export function createPlaygroundBinding(runtimeAssets) {
24
+ const binding = {
25
+ runtimeAssets,
26
+ terminalProps: {},
27
+ async load(language) {
28
+ return bindRuntimeAssets(await playground(language), runtimeAssets);
29
+ }
30
+ };
31
+ binding.terminalProps = {
32
+ playground: binding,
33
+ runtimeAssets
34
+ };
35
+ return binding;
36
+ }
37
+ async function playground(language, runtimeAssets) {
38
+ if (sandboxCache[language]) {
39
+ return runtimeAssets
40
+ ? bindRuntimeAssets(sandboxCache[language], runtimeAssets)
41
+ : sandboxCache[language];
42
+ }
9
43
  let sandbox;
10
44
  switch (language) {
11
45
  case 'PYTHON3':
@@ -22,6 +56,9 @@ export default async function load(language) {
22
56
  case 'JAVA':
23
57
  sandbox = new Java();
24
58
  break;
59
+ case 'RUST':
60
+ sandbox = new Rust();
61
+ break;
25
62
  default:
26
63
  throw new Error(`Unsupported language: ${language}`);
27
64
  }
@@ -39,6 +76,9 @@ export default async function load(language) {
39
76
  sandboxCache['CPP'] = sandbox;
40
77
  if (language === 'JAVA')
41
78
  sandboxCache['JAVA'] = sandbox;
79
+ if (language === 'RUST')
80
+ sandboxCache['RUST'] = sandbox;
42
81
  }
43
- return sandbox;
82
+ return runtimeAssets ? bindRuntimeAssets(sandbox, runtimeAssets) : sandbox;
44
83
  }
84
+ export default playground;
@@ -13,8 +13,14 @@ export interface CompilerDiagnostic {
13
13
  severity: CompilerDiagnosticSeverity;
14
14
  message: string;
15
15
  }
16
+ export type RustTargetTriple = 'wasm32-wasip1' | 'wasm32-wasip2' | 'wasm32-wasip3';
16
17
  export type DebugVariableKind = 'number' | 'bool' | 'array' | 'text';
17
18
  export type DebugArrayElementKind = 'int' | 'float' | 'double' | 'bool' | 'char';
19
+ export interface DebugStructFieldMetadata {
20
+ name: string;
21
+ kind: DebugArrayElementKind;
22
+ offset: number;
23
+ }
18
24
  export interface DebugVariableMetadata {
19
25
  slot: number;
20
26
  name: string;
@@ -24,6 +30,8 @@ export interface DebugVariableMetadata {
24
30
  elementKind?: DebugArrayElementKind;
25
31
  length?: number;
26
32
  dimensions?: number[];
33
+ structFields?: DebugStructFieldMetadata[];
34
+ structSize?: number;
27
35
  }
28
36
  export interface DebugFrame {
29
37
  functionName: string;
@@ -50,6 +58,7 @@ export interface SandboxExecutionOptions {
50
58
  programArgs?: string[];
51
59
  cppVersion?: string;
52
60
  cVersion?: string;
61
+ rustTargetTriple?: RustTargetTriple;
53
62
  }
54
63
  export interface ResolvedSandboxExecutionArgs {
55
64
  compileArgs: string[];
@@ -25,6 +25,7 @@ declare class Python implements Sandbox {
25
25
  pendingEof: boolean;
26
26
  exit: boolean;
27
27
  assetBridge: WorkerAssetBridge | null;
28
+ activeReject: ((reason?: string) => void) | null;
28
29
  load(runtimeAssets?: string | PlaygroundRuntimeAssets, code?: string, log?: boolean, _args?: string[], _options?: SandboxExecutionOptions, progress?: {
29
30
  set?: (value: number) => void;
30
31
  } | import('svelte/store').Writable<number>): Promise<void>;
@@ -20,6 +20,7 @@ class Python {
20
20
  pendingEof = false;
21
21
  exit = true;
22
22
  assetBridge = null;
23
+ activeReject = null;
23
24
  load(runtimeAssets = '', code = '', log = true, _args = [], _options = {}, progress) {
24
25
  return new Promise(async (resolve, reject) => {
25
26
  this.pendingInput = [];
@@ -89,6 +90,7 @@ class Python {
89
90
  return new Promise(async (resolve, reject) => {
90
91
  if (!this.worker)
91
92
  return reject('Worker not loaded');
93
+ this.activeReject = reject;
92
94
  const interrupt = new Uint8Array(this.interruptBuffer), _uid = ++this.uid;
93
95
  const handler = (event) => {
94
96
  if (this.assetBridge?.handleMessage(event))
@@ -113,6 +115,7 @@ class Python {
113
115
  this.exit = true;
114
116
  this.waitingForInput = false;
115
117
  this.pendingEof = false;
118
+ this.activeReject = null;
116
119
  this.ondebug?.({ type: 'stop' });
117
120
  resolve(results);
118
121
  }
@@ -123,6 +126,7 @@ class Python {
123
126
  this.exit = true;
124
127
  this.waitingForInput = false;
125
128
  this.pendingEof = false;
129
+ this.activeReject = null;
126
130
  this.ondebug?.({ type: 'stop' });
127
131
  reject(error);
128
132
  }
@@ -169,11 +173,19 @@ class Python {
169
173
  this.terminate();
170
174
  }
171
175
  terminate() {
176
+ this.activeReject?.('Process terminated');
177
+ this.activeReject = null;
178
+ this.waitingForInput = false;
172
179
  this.pendingEof = false;
180
+ this.uid += 1;
173
181
  new Uint8Array(this.interruptBuffer)[0] = 2;
174
182
  const control = new Int32Array(this.debugBuffer);
175
183
  Atomics.add(control, 0, 1);
176
184
  Atomics.notify(control, 0);
185
+ this.worker?.terminate?.();
186
+ delete this.worker;
187
+ this.assetBridge = null;
188
+ this.exit = true;
177
189
  }
178
190
  async clear() {
179
191
  this.terminate();
@@ -0,0 +1,32 @@
1
+ import { type PlaygroundRuntimeAssets } from './assets';
2
+ import { type CompilerDiagnostic, type SandboxExecutionOptions } from './options';
3
+ import type { Sandbox } from './sandbox';
4
+ declare class Rust implements Sandbox {
5
+ output: any;
6
+ worker?: Worker;
7
+ buffer: SharedArrayBuffer;
8
+ pendingInput: string[];
9
+ begin: number;
10
+ elapse: number;
11
+ uid: number;
12
+ exit: boolean;
13
+ compilerUrl: string;
14
+ assetPath: string;
15
+ activeReject: ((reason: string) => void) | null;
16
+ oncompilerdiagnostic?: (diagnostic: CompilerDiagnostic) => void;
17
+ waitingForInput: boolean;
18
+ pendingEof: boolean;
19
+ load(runtimeAssets?: string | PlaygroundRuntimeAssets, _code?: string, _log?: boolean, _args?: string[], _options?: SandboxExecutionOptions, progress?: {
20
+ set?: (value: number) => void;
21
+ } | import('svelte/store').Writable<number>): Promise<void>;
22
+ write(input: string): void;
23
+ eof(): void;
24
+ private flushPendingInput;
25
+ run(code: string, prepare: boolean, _log?: boolean, _prog?: {
26
+ set?: (value: number) => void;
27
+ } | import('svelte/store').Writable<number>, args?: string[], options?: SandboxExecutionOptions): Promise<boolean | string>;
28
+ kill(): void;
29
+ terminate(): void;
30
+ clear(): Promise<void>;
31
+ }
32
+ export default Rust;
@@ -0,0 +1,175 @@
1
+ import { resolveRustCompilerUrl } from './assets';
2
+ import { resolveSandboxExecutionArgs } from './options';
3
+ import { flushBufferedEof, flushQueuedStdin, resetBufferedStdin } from './stdinBuffer';
4
+ class Rust {
5
+ output = null;
6
+ worker = null;
7
+ buffer = new SharedArrayBuffer(1024);
8
+ pendingInput = [];
9
+ begin = 0;
10
+ elapse = 0;
11
+ uid = 0;
12
+ exit = true;
13
+ compilerUrl = '';
14
+ assetPath = '';
15
+ activeReject = null;
16
+ oncompilerdiagnostic;
17
+ waitingForInput = false;
18
+ pendingEof = false;
19
+ load(runtimeAssets = '', _code = '', _log = true, _args = [], _options = {}, progress) {
20
+ return new Promise(async (resolve, reject) => {
21
+ this.pendingInput = [];
22
+ this.waitingForInput = false;
23
+ this.pendingEof = false;
24
+ const currentUrl = typeof window !== 'undefined' ? window.location.href : '';
25
+ const nextCompilerUrl = resolveRustCompilerUrl(runtimeAssets, currentUrl);
26
+ const nextAssetPath = typeof runtimeAssets === 'string'
27
+ ? runtimeAssets
28
+ : runtimeAssets?.rootUrl ||
29
+ (typeof window !== 'undefined'
30
+ ? window.location.pathname.replace(/\/$/, '')
31
+ : '');
32
+ if (!nextCompilerUrl) {
33
+ return reject('Rust runtime is not configured. Set PUBLIC_WASM_RUST_COMPILER_URL or runtimeAssets.rust.compilerUrl.');
34
+ }
35
+ const needsWorkerReset = !this.worker || this.compilerUrl !== nextCompilerUrl || this.assetPath !== nextAssetPath;
36
+ this.compilerUrl = nextCompilerUrl;
37
+ this.assetPath = nextAssetPath;
38
+ if (needsWorkerReset && this.worker) {
39
+ this.worker.terminate();
40
+ delete this.worker;
41
+ }
42
+ if (!this.worker) {
43
+ this.worker = new (await import('./worker/rust?worker')).default();
44
+ this.worker.onerror = (event) => {
45
+ const location = event.filename && event.lineno
46
+ ? ` (${event.filename}:${event.lineno}:${event.colno})`
47
+ : '';
48
+ reject(`Rust worker script error: ${event.message || 'unknown error'}${location}`);
49
+ };
50
+ this.worker.onmessageerror = () => {
51
+ reject('Rust worker message deserialization failed');
52
+ };
53
+ this.worker.onmessage = (event) => {
54
+ if (event.data?.load) {
55
+ progress?.set?.(1);
56
+ resolve();
57
+ }
58
+ if (event.data?.error)
59
+ reject(event.data.error);
60
+ };
61
+ this.worker.postMessage({
62
+ load: true,
63
+ compilerUrl: this.compilerUrl,
64
+ path: this.assetPath
65
+ });
66
+ }
67
+ else {
68
+ progress?.set?.(1);
69
+ resolve();
70
+ }
71
+ });
72
+ }
73
+ write(input) {
74
+ this.pendingInput.push(input);
75
+ this.pendingEof = false;
76
+ this.flushPendingInput();
77
+ }
78
+ eof() {
79
+ this.pendingEof = true;
80
+ this.flushPendingInput();
81
+ }
82
+ flushPendingInput() {
83
+ if (!this.waitingForInput)
84
+ return;
85
+ if (flushQueuedStdin(this.pendingInput, this.buffer)) {
86
+ this.waitingForInput = false;
87
+ return;
88
+ }
89
+ if (this.pendingEof) {
90
+ flushBufferedEof(this.buffer);
91
+ this.pendingEof = false;
92
+ this.waitingForInput = false;
93
+ }
94
+ }
95
+ run(code, prepare, _log = true, _prog, args = [], options = {}) {
96
+ this.exit = false;
97
+ return new Promise((resolve, reject) => {
98
+ if (!this.worker)
99
+ return reject('Worker not loaded');
100
+ const { programArgs } = resolveSandboxExecutionArgs('RUST', args, options);
101
+ const targetTriple = options.rustTargetTriple || 'wasm32-wasip1';
102
+ const _uid = ++this.uid;
103
+ this.activeReject = reject;
104
+ const handler = (event) => {
105
+ if (!this.worker)
106
+ return reject('Worker not loaded');
107
+ if (_uid !== this.uid)
108
+ return (this.worker.onmessage = null);
109
+ const { output, results, error, buffer, diagnostic, progress } = event.data;
110
+ if (buffer) {
111
+ this.waitingForInput = true;
112
+ this.flushPendingInput();
113
+ }
114
+ if (progress && typeof progress.percent === 'number') {
115
+ _prog?.set?.(Math.max(0, Math.min(progress.percent / 100, 1)));
116
+ }
117
+ if (output)
118
+ this.output(output);
119
+ if (diagnostic)
120
+ this.oncompilerdiagnostic?.(diagnostic);
121
+ if (results) {
122
+ this.elapse = Date.now() - this.begin;
123
+ this.exit = true;
124
+ this.waitingForInput = false;
125
+ this.pendingEof = false;
126
+ this.activeReject = null;
127
+ resolve(results);
128
+ }
129
+ if (error) {
130
+ this.elapse = Date.now() - this.begin;
131
+ this.exit = true;
132
+ this.waitingForInput = false;
133
+ this.pendingEof = false;
134
+ this.activeReject = null;
135
+ reject(error);
136
+ }
137
+ };
138
+ this.worker.onmessage = handler;
139
+ this.begin = Date.now();
140
+ this.worker.postMessage({
141
+ code,
142
+ prepare,
143
+ buffer: this.buffer,
144
+ args: programArgs,
145
+ targetTriple,
146
+ log: _log
147
+ });
148
+ });
149
+ }
150
+ kill() {
151
+ this.terminate();
152
+ }
153
+ terminate() {
154
+ this.activeReject?.('Process terminated');
155
+ this.activeReject = null;
156
+ this.waitingForInput = false;
157
+ this.pendingEof = false;
158
+ this.uid += 1;
159
+ this.worker?.terminate?.();
160
+ delete this.worker;
161
+ this.exit = true;
162
+ }
163
+ async clear() {
164
+ this.pendingInput = [];
165
+ this.waitingForInput = false;
166
+ this.pendingEof = false;
167
+ if (this.worker)
168
+ this.worker.onmessage = null;
169
+ resetBufferedStdin(this.buffer);
170
+ if (!this.exit) {
171
+ this.terminate();
172
+ }
173
+ }
174
+ }
175
+ export default Rust;
@@ -1,14 +1,15 @@
1
1
  import type { CompilerDiagnostic, DebugCommand, DebugSessionEvent, SandboxExecutionOptions } from './options';
2
2
  import type { PlaygroundRuntimeAssets } from './assets';
3
3
  import type { Writable } from 'svelte/store';
4
- type ProgressLike = Writable<number> | {
4
+ export type SandboxRuntimeAssets = string | PlaygroundRuntimeAssets;
5
+ export type SandboxProgress = Writable<number> | {
5
6
  set?: (value: number) => void;
6
7
  };
7
8
  export interface Sandbox {
8
9
  constructor: any;
9
10
  eof: () => void;
10
- load: (runtimeAssets?: string | PlaygroundRuntimeAssets, code?: string, log?: boolean, args?: string[], options?: SandboxExecutionOptions, progress?: ProgressLike) => Promise<void>;
11
- run: (code: string, prepare: boolean, log?: boolean, prog?: ProgressLike, args?: string[], options?: SandboxExecutionOptions) => Promise<boolean | string>;
11
+ load: (runtimeAssets?: SandboxRuntimeAssets, code?: string, log?: boolean, args?: string[], options?: SandboxExecutionOptions, progress?: SandboxProgress) => Promise<void>;
12
+ run: (code: string, prepare: boolean, log?: boolean, prog?: SandboxProgress, args?: string[], options?: SandboxExecutionOptions) => Promise<boolean | string>;
12
13
  terminate: () => void;
13
14
  clear: () => Promise<void>;
14
15
  kill?: () => void;
@@ -17,6 +18,7 @@ export interface Sandbox {
17
18
  ondebug?: (event: DebugSessionEvent) => void;
18
19
  oncompilerdiagnostic?: (diagnostic: CompilerDiagnostic) => void;
19
20
  debugCommand?: (command: DebugCommand) => void;
21
+ setBreakpoints?: (lines: number[]) => void;
20
22
  debugEvaluate?: (expression: string) => Promise<string>;
21
23
  image?: (data: {
22
24
  mime: string;
@@ -25,4 +27,16 @@ export interface Sandbox {
25
27
  }) => void;
26
28
  elapse?: number;
27
29
  }
28
- export {};
30
+ export interface BoundSandbox extends Omit<Sandbox, 'load'> {
31
+ load: (code?: string, log?: boolean, args?: string[], options?: SandboxExecutionOptions, progress?: SandboxProgress) => Promise<void>;
32
+ runtimeAssets: SandboxRuntimeAssets;
33
+ }
34
+ export interface PlaygroundTerminalProps {
35
+ playground: PlaygroundBinding;
36
+ runtimeAssets: SandboxRuntimeAssets;
37
+ }
38
+ export interface PlaygroundBinding {
39
+ runtimeAssets: SandboxRuntimeAssets;
40
+ terminalProps: PlaygroundTerminalProps;
41
+ load: (language: string) => Promise<BoundSandbox>;
42
+ }
@@ -0,0 +1 @@
1
+ export declare const WASM_RUST_ASSET_VERSION = "2d36c8a3cd2cbbfd";
@@ -0,0 +1 @@
1
+ export const WASM_RUST_ASSET_VERSION = "2d36c8a3cd2cbbfd";
@@ -4,7 +4,7 @@ self.document = {
4
4
  return [];
5
5
  }
6
6
  };
7
- let stdinBufferClang, debugBufferClang, interruptBufferClang, clang;
7
+ let stdinBufferClang, debugBufferClang, watchBufferClang, watchResultBufferClang, interruptBufferClang, clang;
8
8
  async function loadClang(path, log) {
9
9
  const { default: Clang } = await import('../../clang');
10
10
  clang = new Clang({
@@ -17,7 +17,7 @@ async function loadClang(path, log) {
17
17
  });
18
18
  }
19
19
  self.onmessage = async (event) => {
20
- const { code, buffer, debugBuffer, load, interrupt, log, path, prepare, language, compileArgs, programArgs, cppVersion, cVersion, debug, breakpoints, pauseOnEntry } = event.data;
20
+ const { code, buffer, debugBuffer, watchBuffer, watchResultBuffer, load, interrupt, log, path, prepare, language, compileArgs, programArgs, cppVersion, cVersion, debug, breakpoints, pauseOnEntry } = event.data;
21
21
  if (load) {
22
22
  await loadClang(path, log);
23
23
  postMessage({ load: true });
@@ -25,6 +25,8 @@ self.onmessage = async (event) => {
25
25
  else if (prepare) {
26
26
  stdinBufferClang = new Int32Array(buffer);
27
27
  debugBufferClang = new Int32Array(debugBuffer);
28
+ watchBufferClang = new Int32Array(watchBuffer);
29
+ watchResultBufferClang = new Int32Array(watchResultBuffer);
28
30
  interruptBufferClang = new Uint8Array(interrupt);
29
31
  try {
30
32
  await clang.compileLink(code, {
@@ -37,7 +39,9 @@ self.onmessage = async (event) => {
37
39
  breakpoints,
38
40
  pauseOnEntry,
39
41
  debugBuffer: debugBufferClang,
40
- interruptBuffer: interruptBufferClang
42
+ interruptBuffer: interruptBufferClang,
43
+ watchBuffer: watchBufferClang,
44
+ watchResultBuffer: watchResultBufferClang
41
45
  });
42
46
  self.postMessage({ results: true });
43
47
  }
@@ -49,6 +53,8 @@ self.onmessage = async (event) => {
49
53
  clang.log = log;
50
54
  stdinBufferClang = new Int32Array(buffer);
51
55
  debugBufferClang = new Int32Array(debugBuffer);
56
+ watchBufferClang = new Int32Array(watchBuffer);
57
+ watchResultBufferClang = new Int32Array(watchResultBuffer);
52
58
  interruptBufferClang = new Uint8Array(interrupt);
53
59
  try {
54
60
  await clang.compileLinkRun(code, {
@@ -61,7 +67,9 @@ self.onmessage = async (event) => {
61
67
  breakpoints,
62
68
  pauseOnEntry,
63
69
  debugBuffer: debugBufferClang,
64
- interruptBuffer: interruptBufferClang
70
+ interruptBuffer: interruptBufferClang,
71
+ watchBuffer: watchBufferClang,
72
+ watchResultBuffer: watchResultBufferClang
65
73
  });
66
74
  self.postMessage({ results: true });
67
75
  }
@@ -0,0 +1 @@
1
+ export {};