wasm-idle 0.6.0 → 0.7.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 (33) hide show
  1. package/README.md +85 -11
  2. package/dist/playground/assets.d.ts +43 -0
  3. package/dist/playground/assets.js +164 -0
  4. package/dist/playground/elixir.d.ts +32 -0
  5. package/dist/playground/elixir.js +173 -0
  6. package/dist/playground/go.d.ts +31 -0
  7. package/dist/playground/go.js +166 -0
  8. package/dist/playground/index.js +36 -1
  9. package/dist/playground/ocaml.d.ts +32 -0
  10. package/dist/playground/ocaml.js +341 -0
  11. package/dist/playground/options.d.ts +4 -0
  12. package/dist/playground/tinygo.d.ts +75 -0
  13. package/dist/playground/tinygo.js +510 -0
  14. package/dist/playground/wasmElixirVersion.d.ts +1 -0
  15. package/dist/playground/wasmElixirVersion.js +1 -0
  16. package/dist/playground/wasmGoVersion.d.ts +1 -0
  17. package/dist/playground/wasmGoVersion.js +1 -0
  18. package/dist/playground/wasmOcamlVersion.d.ts +1 -0
  19. package/dist/playground/wasmOcamlVersion.js +1 -0
  20. package/dist/playground/wasmRustVersion.d.ts +1 -1
  21. package/dist/playground/wasmRustVersion.js +1 -1
  22. package/dist/playground/wasmTinyGoVersion.d.ts +1 -0
  23. package/dist/playground/wasmTinyGoVersion.js +1 -0
  24. package/dist/playground/worker/elixir.d.ts +1 -0
  25. package/dist/playground/worker/elixir.js +317 -0
  26. package/dist/playground/worker/go.d.ts +1 -0
  27. package/dist/playground/worker/go.js +163 -0
  28. package/dist/playground/worker/ocaml.d.ts +1 -0
  29. package/dist/playground/worker/ocaml.js +449 -0
  30. package/dist/playground/worker/tinygo.d.ts +1 -0
  31. package/dist/playground/worker/tinygo.js +137 -0
  32. package/dist/terminal/Terminal.svelte +69 -29
  33. package/package.json +35 -22
@@ -0,0 +1,166 @@
1
+ import { resolveGoCompilerUrl } from './assets';
2
+ import { resolveSandboxExecutionArgs } from './options';
3
+ import { flushBufferedEof, flushQueuedStdin, resetBufferedStdin } from './stdinBuffer';
4
+ class Go {
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
+ activeReject = null;
15
+ oncompilerdiagnostic;
16
+ waitingForInput = false;
17
+ pendingEof = false;
18
+ load(runtimeAssets = '', _code = '', _log = true, _args = [], _options = {}, progress) {
19
+ return new Promise(async (resolve, reject) => {
20
+ this.pendingInput = [];
21
+ this.waitingForInput = false;
22
+ this.pendingEof = false;
23
+ const currentUrl = typeof window !== 'undefined' ? window.location.href : '';
24
+ const nextCompilerUrl = resolveGoCompilerUrl(runtimeAssets, currentUrl);
25
+ if (!nextCompilerUrl) {
26
+ return reject('Go runtime is not configured. Set PUBLIC_WASM_GO_COMPILER_URL or runtimeAssets.go.compilerUrl.');
27
+ }
28
+ const needsWorkerReset = !this.worker || this.compilerUrl !== nextCompilerUrl;
29
+ this.compilerUrl = nextCompilerUrl;
30
+ if (needsWorkerReset && this.worker) {
31
+ this.worker.terminate();
32
+ delete this.worker;
33
+ }
34
+ if (!this.worker) {
35
+ this.worker = new (await import('./worker/go?worker')).default();
36
+ this.worker.onerror = (event) => {
37
+ const location = event.filename && event.lineno
38
+ ? ` (${event.filename}:${event.lineno}:${event.colno})`
39
+ : '';
40
+ reject(`Go worker script error: ${event.message || 'unknown error'}${location}`);
41
+ };
42
+ this.worker.onmessageerror = () => {
43
+ reject('Go worker message deserialization failed');
44
+ };
45
+ this.worker.onmessage = (event) => {
46
+ if (event.data?.load) {
47
+ progress?.set?.(1);
48
+ resolve();
49
+ }
50
+ if (event.data?.error)
51
+ reject(event.data.error);
52
+ };
53
+ this.worker.postMessage({
54
+ load: true,
55
+ compilerUrl: this.compilerUrl
56
+ });
57
+ }
58
+ else {
59
+ progress?.set?.(1);
60
+ resolve();
61
+ }
62
+ });
63
+ }
64
+ write(input) {
65
+ this.pendingInput.push(input);
66
+ this.pendingEof = false;
67
+ this.flushPendingInput();
68
+ }
69
+ eof() {
70
+ this.pendingEof = true;
71
+ this.flushPendingInput();
72
+ }
73
+ flushPendingInput() {
74
+ if (!this.waitingForInput)
75
+ return;
76
+ if (flushQueuedStdin(this.pendingInput, this.buffer)) {
77
+ this.waitingForInput = false;
78
+ return;
79
+ }
80
+ if (this.pendingEof) {
81
+ flushBufferedEof(this.buffer);
82
+ this.pendingEof = false;
83
+ this.waitingForInput = false;
84
+ }
85
+ }
86
+ run(code, prepare, _log = true, _prog, args = [], options = {}) {
87
+ this.exit = false;
88
+ return new Promise((resolve, reject) => {
89
+ if (!this.worker)
90
+ return reject('Worker not loaded');
91
+ const { programArgs } = resolveSandboxExecutionArgs('GO', args, options);
92
+ const target = options.goTarget || 'wasip1/wasm';
93
+ const _uid = ++this.uid;
94
+ this.activeReject = reject;
95
+ const handler = (event) => {
96
+ if (!this.worker)
97
+ return reject('Worker not loaded');
98
+ if (_uid !== this.uid)
99
+ return (this.worker.onmessage = null);
100
+ const { output, results, error, buffer, diagnostic, progress } = event.data;
101
+ if (buffer) {
102
+ this.waitingForInput = true;
103
+ this.flushPendingInput();
104
+ }
105
+ if (progress && typeof progress.percent === 'number') {
106
+ _prog?.set?.(Math.max(0, Math.min(progress.percent / 100, 1)));
107
+ }
108
+ if (output)
109
+ this.output(output);
110
+ if (diagnostic)
111
+ this.oncompilerdiagnostic?.(diagnostic);
112
+ if (results) {
113
+ this.elapse = Date.now() - this.begin;
114
+ this.exit = true;
115
+ this.waitingForInput = false;
116
+ this.pendingEof = false;
117
+ this.activeReject = null;
118
+ resolve(results);
119
+ }
120
+ if (error) {
121
+ this.elapse = Date.now() - this.begin;
122
+ this.exit = true;
123
+ this.waitingForInput = false;
124
+ this.pendingEof = false;
125
+ this.activeReject = null;
126
+ reject(error);
127
+ }
128
+ };
129
+ this.worker.onmessage = handler;
130
+ this.begin = Date.now();
131
+ this.worker.postMessage({
132
+ code,
133
+ prepare,
134
+ buffer: this.buffer,
135
+ args: programArgs,
136
+ target,
137
+ log: _log
138
+ });
139
+ });
140
+ }
141
+ kill() {
142
+ this.terminate();
143
+ }
144
+ terminate() {
145
+ this.activeReject?.('Process terminated');
146
+ this.activeReject = null;
147
+ this.waitingForInput = false;
148
+ this.pendingEof = false;
149
+ this.uid += 1;
150
+ this.worker?.terminate?.();
151
+ delete this.worker;
152
+ this.exit = true;
153
+ }
154
+ async clear() {
155
+ this.pendingInput = [];
156
+ this.waitingForInput = false;
157
+ this.pendingEof = false;
158
+ if (this.worker)
159
+ this.worker.onmessage = null;
160
+ resetBufferedStdin(this.buffer);
161
+ if (!this.exit) {
162
+ this.terminate();
163
+ }
164
+ }
165
+ }
166
+ export default Go;
@@ -1,9 +1,24 @@
1
1
  import Clang from './clang';
2
+ import Elixir from './elixir';
3
+ import Go from './go';
2
4
  import Java from './java';
5
+ import Ocaml from './ocaml';
3
6
  import Python from './python';
4
7
  import Rust from './rust';
8
+ import TinyGo from './tinygo';
5
9
  const sandboxCache = {};
6
- export const supportedLanguages = ['PYTHON3', 'PYPY3', 'C', 'CPP', 'JAVA', 'RUST'];
10
+ export const supportedLanguages = [
11
+ 'PYTHON3',
12
+ 'PYPY3',
13
+ 'C',
14
+ 'CPP',
15
+ 'JAVA',
16
+ 'RUST',
17
+ 'GO',
18
+ 'ELIXIR',
19
+ 'TINYGO',
20
+ 'OCAML'
21
+ ];
7
22
  function bindRuntimeAssets(sandbox, runtimeAssets) {
8
23
  return new Proxy(sandbox, {
9
24
  get(target, prop, receiver) {
@@ -59,6 +74,18 @@ async function playground(language, runtimeAssets) {
59
74
  case 'RUST':
60
75
  sandbox = new Rust();
61
76
  break;
77
+ case 'GO':
78
+ sandbox = new Go();
79
+ break;
80
+ case 'ELIXIR':
81
+ sandbox = new Elixir();
82
+ break;
83
+ case 'TINYGO':
84
+ sandbox = new TinyGo();
85
+ break;
86
+ case 'OCAML':
87
+ sandbox = new Ocaml();
88
+ break;
62
89
  default:
63
90
  throw new Error(`Unsupported language: ${language}`);
64
91
  }
@@ -78,6 +105,14 @@ async function playground(language, runtimeAssets) {
78
105
  sandboxCache['JAVA'] = sandbox;
79
106
  if (language === 'RUST')
80
107
  sandboxCache['RUST'] = sandbox;
108
+ if (language === 'GO')
109
+ sandboxCache['GO'] = sandbox;
110
+ if (language === 'ELIXIR')
111
+ sandboxCache['ELIXIR'] = sandbox;
112
+ if (language === 'TINYGO')
113
+ sandboxCache['TINYGO'] = sandbox;
114
+ if (language === 'OCAML')
115
+ sandboxCache['OCAML'] = sandbox;
81
116
  }
82
117
  return runtimeAssets ? bindRuntimeAssets(sandbox, runtimeAssets) : sandbox;
83
118
  }
@@ -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 Ocaml 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
+ moduleUrl: string;
14
+ manifestUrl: 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 Ocaml;
@@ -0,0 +1,341 @@
1
+ import { resolveOcamlManifestUrl, resolveOcamlModuleUrl } from './assets';
2
+ import {} from './options';
3
+ import { flushBufferedEof, flushQueuedStdin, resetBufferedStdin } from './stdinBuffer';
4
+ class Ocaml {
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
+ moduleUrl = '';
14
+ manifestUrl = '';
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
+ resetBufferedStdin(this.buffer);
25
+ const currentUrl = typeof window !== 'undefined' ? window.location.href : '';
26
+ const nextModuleUrl = resolveOcamlModuleUrl(runtimeAssets, currentUrl);
27
+ const nextManifestUrl = resolveOcamlManifestUrl(runtimeAssets, currentUrl);
28
+ if (!nextModuleUrl || !nextManifestUrl) {
29
+ return reject('OCaml runtime is not configured. Set runtimeAssets.ocaml.moduleUrl and runtimeAssets.ocaml.manifestUrl or sync the bundled wasm-of-js-of-ocaml assets.');
30
+ }
31
+ const needsWorkerReset = !this.worker ||
32
+ this.moduleUrl !== nextModuleUrl ||
33
+ this.manifestUrl !== nextManifestUrl;
34
+ this.moduleUrl = nextModuleUrl;
35
+ this.manifestUrl = nextManifestUrl;
36
+ if (needsWorkerReset && this.worker) {
37
+ this.worker.terminate();
38
+ delete this.worker;
39
+ }
40
+ if (!this.worker) {
41
+ this.worker = new (await import('./worker/ocaml?worker')).default();
42
+ this.worker.onerror = (event) => {
43
+ const location = event.filename && event.lineno
44
+ ? ` (${event.filename}:${event.lineno}:${event.colno})`
45
+ : '';
46
+ reject(`OCaml worker script error: ${event.message || 'unknown error'}${location}`);
47
+ };
48
+ this.worker.onmessageerror = () => {
49
+ reject('OCaml worker message deserialization failed');
50
+ };
51
+ this.worker.onmessage = (event) => {
52
+ if (event.data?.load) {
53
+ progress?.set?.(1);
54
+ resolve();
55
+ }
56
+ if (event.data?.error)
57
+ reject(event.data.error);
58
+ };
59
+ this.worker.postMessage({
60
+ load: true,
61
+ moduleUrl: this.moduleUrl,
62
+ manifestUrl: this.manifestUrl
63
+ });
64
+ }
65
+ else {
66
+ progress?.set?.(1);
67
+ resolve();
68
+ }
69
+ });
70
+ }
71
+ write(input) {
72
+ this.pendingInput.push(input);
73
+ this.pendingEof = false;
74
+ this.flushPendingInput();
75
+ }
76
+ eof() {
77
+ this.pendingEof = true;
78
+ this.flushPendingInput();
79
+ }
80
+ flushPendingInput() {
81
+ if (!this.waitingForInput)
82
+ return;
83
+ if (flushQueuedStdin(this.pendingInput, this.buffer)) {
84
+ this.waitingForInput = false;
85
+ return;
86
+ }
87
+ if (this.pendingEof) {
88
+ flushBufferedEof(this.buffer);
89
+ this.pendingEof = false;
90
+ this.waitingForInput = false;
91
+ }
92
+ }
93
+ run(code, prepare, _log = true, _prog, _args = [], options = {}) {
94
+ this.exit = false;
95
+ return new Promise((resolve, reject) => {
96
+ if (!this.worker)
97
+ return reject('Worker not loaded');
98
+ const target = options.ocamlBackend || 'wasm';
99
+ const _uid = ++this.uid;
100
+ this.activeReject = reject;
101
+ const handler = async (event) => {
102
+ if (!this.worker)
103
+ return reject('Worker not loaded');
104
+ if (_uid !== this.uid)
105
+ return (this.worker.onmessage = null);
106
+ const { output, results, error, diagnostic, progress, runtime } = event.data;
107
+ if (progress && typeof progress.percent === 'number') {
108
+ _prog?.set?.(Math.max(0, Math.min(progress.percent / 100, 1)));
109
+ }
110
+ if (event.data?.buffer) {
111
+ this.waitingForInput = true;
112
+ this.flushPendingInput();
113
+ }
114
+ if (output)
115
+ this.output(output);
116
+ if (diagnostic)
117
+ this.oncompilerdiagnostic?.(diagnostic);
118
+ if (runtime) {
119
+ const createdObjectUrls = [];
120
+ const originalConsole = window.console;
121
+ const originalFetch = window.fetch.bind(window);
122
+ const originalInstantiate = WebAssembly.instantiate.bind(WebAssembly);
123
+ const originalInstantiateStreaming = WebAssembly.instantiateStreaming
124
+ ? WebAssembly.instantiateStreaming.bind(WebAssembly)
125
+ : undefined;
126
+ const runtimePromiseKey = '__wasm_of_js_of_ocaml_runtime_promise';
127
+ const assetResolverKey = '__wasm_of_js_of_ocaml_resolve_asset';
128
+ const runtimeGlobal = window;
129
+ const hadProcess = Object.prototype.hasOwnProperty.call(runtimeGlobal, 'process');
130
+ const hadRequire = Object.prototype.hasOwnProperty.call(runtimeGlobal, 'require');
131
+ const hadModule = Object.prototype.hasOwnProperty.call(runtimeGlobal, 'module');
132
+ const hadExports = Object.prototype.hasOwnProperty.call(runtimeGlobal, 'exports');
133
+ const originalProcess = runtimeGlobal.process;
134
+ const originalRequire = runtimeGlobal.require;
135
+ const originalModule = runtimeGlobal.module;
136
+ const originalExports = runtimeGlobal.exports;
137
+ originalConsole.log(`[wasm-idle:ocaml-runtime] start source=${String(runtime.sourcePath || '')} chars=${String(String(runtime.programSource || '').length)} assets=${String(Array.isArray(runtime.assetFiles) ? runtime.assetFiles.length : 0)}`);
138
+ const sourceDir = String(runtime.sourcePath || '').replace(/\/[^/]+$/, '');
139
+ const assetEntries = Array.isArray(runtime.assetFiles)
140
+ ? runtime.assetFiles.map((assetFile) => {
141
+ const copiedAssetData = new Uint8Array(assetFile.data.byteLength);
142
+ copiedAssetData.set(assetFile.data);
143
+ const objectUrl = URL.createObjectURL(new Blob([copiedAssetData], {
144
+ type: assetFile.path.endsWith('.wasm')
145
+ ? 'application/wasm'
146
+ : 'application/octet-stream'
147
+ }));
148
+ createdObjectUrls.push(objectUrl);
149
+ return {
150
+ path: assetFile.path,
151
+ basename: assetFile.path.split('/').at(-1) || assetFile.path,
152
+ relativeFromSourceDir: assetFile.path.startsWith(`${sourceDir}/`)
153
+ ? assetFile.path.slice(sourceDir.length + 1)
154
+ : assetFile.path.replace(/^\/+/, ''),
155
+ objectUrl
156
+ };
157
+ })
158
+ : [];
159
+ const emitOutput = (...args) => {
160
+ const text = args.map((value) => String(value)).join(' ');
161
+ this.output(text.endsWith('\n') ? text : `${text}\n`);
162
+ };
163
+ const resolveAssetUrl = (requestedAsset) => assetEntries
164
+ .map((assetEntry) => {
165
+ const candidates = [String(requestedAsset)];
166
+ try {
167
+ candidates.push(new URL(String(requestedAsset), window.location.href).pathname);
168
+ }
169
+ catch {
170
+ // ignore URL parse errors
171
+ }
172
+ return candidates.some((candidate) => candidate === assetEntry.path ||
173
+ candidate === assetEntry.relativeFromSourceDir ||
174
+ candidate.endsWith(`/${assetEntry.relativeFromSourceDir}`) ||
175
+ candidate.endsWith(`/${assetEntry.basename}`))
176
+ ? assetEntry.objectUrl
177
+ : null;
178
+ })
179
+ .find((candidate) => !!candidate) || null;
180
+ window.console = {
181
+ ...originalConsole,
182
+ log: (...args) => {
183
+ emitOutput(...args);
184
+ originalConsole.log(...args);
185
+ },
186
+ info: (...args) => {
187
+ emitOutput(...args);
188
+ originalConsole.info(...args);
189
+ },
190
+ warn: (...args) => {
191
+ emitOutput(...args);
192
+ originalConsole.warn(...args);
193
+ },
194
+ error: (...args) => {
195
+ emitOutput(...args);
196
+ originalConsole.error(...args);
197
+ }
198
+ };
199
+ window.fetch = (async (input, init) => {
200
+ const requestUrl = typeof input === 'string'
201
+ ? input
202
+ : input instanceof URL
203
+ ? input.toString()
204
+ : input.url;
205
+ const resolvedAssetUrl = resolveAssetUrl(requestUrl);
206
+ if (resolvedAssetUrl) {
207
+ return await originalFetch(resolvedAssetUrl, init);
208
+ }
209
+ return await originalFetch(input, init);
210
+ });
211
+ WebAssembly.instantiate = (async (source, importObject) => {
212
+ return await originalInstantiate(source, importObject);
213
+ });
214
+ if (originalInstantiateStreaming) {
215
+ WebAssembly.instantiateStreaming = (async (source, importObject) => {
216
+ return await originalInstantiateStreaming(source, importObject);
217
+ });
218
+ }
219
+ runtimeGlobal.process = undefined;
220
+ runtimeGlobal.require = undefined;
221
+ runtimeGlobal.module = undefined;
222
+ runtimeGlobal.exports = undefined;
223
+ runtimeGlobal[assetResolverKey] = resolveAssetUrl;
224
+ try {
225
+ const normalizedSource = String(runtime.programSource || '').includes('($=>async a=>{')
226
+ ? String(runtime.programSource).replace('($=>async a=>{', `globalThis.${runtimePromiseKey}=($=>async a=>{`)
227
+ : String(runtime.programSource || '');
228
+ const sourceWithAssetResolver = normalizedSource.replace(/function ([A-Za-z$_][\w$]*)\(([A-Za-z$_][\w$]*)\)\{const ([A-Za-z$_][\w$]*)=([A-Za-z$_][\w$]*)\?new URL\(\2,\4\):\2;return fetch\(\3\)\}/, `function $1($2){if(globalThis.${assetResolverKey}){const resolvedAsset=globalThis.${assetResolverKey}($2);if(resolvedAsset)return fetch(resolvedAsset)}const $3=$4?new URL($2,$4):$2;return fetch($3)}`);
229
+ new Function(`${sourceWithAssetResolver}\n//# sourceURL=${String(runtime.sourcePath || 'ocaml-runtime.js')}`)();
230
+ originalConsole.log('[wasm-idle:ocaml-runtime] script invoked');
231
+ const runtimePromise = runtimeGlobal[runtimePromiseKey];
232
+ originalConsole.log(`[wasm-idle:ocaml-runtime] runtime promise=${String(runtimePromise instanceof Promise)}`);
233
+ if (runtimePromise instanceof Promise) {
234
+ await runtimePromise;
235
+ }
236
+ this.elapse = Date.now() - this.begin;
237
+ this.exit = true;
238
+ this.activeReject = null;
239
+ resolve(true);
240
+ }
241
+ catch (runtimeError) {
242
+ this.elapse = Date.now() - this.begin;
243
+ this.exit = true;
244
+ this.activeReject = null;
245
+ reject(runtimeError?.message || String(runtimeError));
246
+ }
247
+ finally {
248
+ window.console = originalConsole;
249
+ window.fetch = originalFetch;
250
+ WebAssembly.instantiate = originalInstantiate;
251
+ if (originalInstantiateStreaming) {
252
+ WebAssembly.instantiateStreaming = originalInstantiateStreaming;
253
+ }
254
+ delete runtimeGlobal[runtimePromiseKey];
255
+ delete runtimeGlobal[assetResolverKey];
256
+ if (!hadProcess) {
257
+ delete runtimeGlobal.process;
258
+ }
259
+ else {
260
+ runtimeGlobal.process = originalProcess;
261
+ }
262
+ if (!hadRequire) {
263
+ delete runtimeGlobal.require;
264
+ }
265
+ else {
266
+ runtimeGlobal.require = originalRequire;
267
+ }
268
+ if (!hadModule) {
269
+ delete runtimeGlobal.module;
270
+ }
271
+ else {
272
+ runtimeGlobal.module = originalModule;
273
+ }
274
+ if (!hadExports) {
275
+ delete runtimeGlobal.exports;
276
+ }
277
+ else {
278
+ runtimeGlobal.exports = originalExports;
279
+ }
280
+ for (const objectUrl of createdObjectUrls) {
281
+ URL.revokeObjectURL(objectUrl);
282
+ }
283
+ }
284
+ return;
285
+ }
286
+ if (results) {
287
+ this.elapse = Date.now() - this.begin;
288
+ this.exit = true;
289
+ this.waitingForInput = false;
290
+ this.pendingEof = false;
291
+ this.activeReject = null;
292
+ resolve(results);
293
+ }
294
+ if (error) {
295
+ this.elapse = Date.now() - this.begin;
296
+ this.exit = true;
297
+ this.waitingForInput = false;
298
+ this.pendingEof = false;
299
+ this.activeReject = null;
300
+ reject(error);
301
+ }
302
+ };
303
+ this.worker.onmessage = (event) => {
304
+ void handler(event);
305
+ };
306
+ this.begin = Date.now();
307
+ this.worker.postMessage({
308
+ code,
309
+ prepare,
310
+ target,
311
+ log: _log,
312
+ buffer: this.buffer
313
+ });
314
+ });
315
+ }
316
+ kill() {
317
+ this.terminate();
318
+ }
319
+ terminate() {
320
+ this.activeReject?.('Process terminated');
321
+ this.activeReject = null;
322
+ this.waitingForInput = false;
323
+ this.pendingEof = false;
324
+ this.uid += 1;
325
+ this.worker?.terminate?.();
326
+ delete this.worker;
327
+ this.exit = true;
328
+ }
329
+ async clear() {
330
+ this.pendingInput = [];
331
+ this.waitingForInput = false;
332
+ this.pendingEof = false;
333
+ if (this.worker)
334
+ this.worker.onmessage = null;
335
+ resetBufferedStdin(this.buffer);
336
+ if (!this.exit) {
337
+ this.terminate();
338
+ }
339
+ }
340
+ }
341
+ export default Ocaml;
@@ -14,6 +14,8 @@ export interface CompilerDiagnostic {
14
14
  message: string;
15
15
  }
16
16
  export type RustTargetTriple = 'wasm32-wasip1' | 'wasm32-wasip2' | 'wasm32-wasip3';
17
+ export type GoTarget = 'wasip1/wasm' | 'wasip2/wasm' | 'wasip3/wasm' | 'js/wasm';
18
+ export type OcamlBackend = 'js' | 'wasm';
17
19
  export type DebugVariableKind = 'number' | 'bool' | 'array' | 'text';
18
20
  export type DebugArrayElementKind = 'int' | 'float' | 'double' | 'bool' | 'char';
19
21
  export interface DebugStructFieldMetadata {
@@ -59,6 +61,8 @@ export interface SandboxExecutionOptions {
59
61
  cppVersion?: string;
60
62
  cVersion?: string;
61
63
  rustTargetTriple?: RustTargetTriple;
64
+ goTarget?: GoTarget;
65
+ ocamlBackend?: OcamlBackend;
62
66
  }
63
67
  export interface ResolvedSandboxExecutionArgs {
64
68
  compileArgs: string[];