wasm-idle 0.7.1 → 0.7.2

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.
@@ -1,3 +1,5 @@
1
+ import { WorkerAssetBridge } from './assetBridge';
2
+ import { resolveRuntimeAssetConfig } from './assets';
1
3
  import { resolveSandboxExecutionArgs } from './options';
2
4
  import { bufferedSequence, flushBufferedEof, flushQueuedStdin, resetBufferedStdin, waitForBufferedSequenceChange } from './stdinBuffer';
3
5
  const debugBreakpointBufferInts = 1028;
@@ -20,23 +22,48 @@ class Clang {
20
22
  waitingForInput = false;
21
23
  pendingEof = false;
22
24
  exit = true;
25
+ assetBridge = null;
23
26
  activeReject = null;
24
27
  constructor(language) {
25
28
  this.language = language;
26
29
  }
27
- load(runtimeAssets = '', code = '', log = true, args = [], _options = {}, _progress) {
30
+ load(runtimeAssets = '', code = '', log = true, args = [], _options = {}, progress) {
28
31
  return new Promise(async (resolve) => {
29
32
  this.log = log;
30
33
  this.pendingInput = [];
31
34
  this.waitingForInput = false;
32
35
  this.pendingEof = false;
33
- const path = typeof runtimeAssets === 'string' ? runtimeAssets : runtimeAssets?.rootUrl || '';
36
+ const assetConfig = resolveRuntimeAssetConfig('clang', runtimeAssets, typeof window !== 'undefined' ? window.location.href : '');
37
+ const needsWorkerReset = !this.worker || !this.assetBridge || !this.assetBridge.matches(assetConfig);
38
+ if (needsWorkerReset && this.worker) {
39
+ this.worker.terminate();
40
+ delete this.worker;
41
+ this.assetBridge = null;
42
+ }
34
43
  if (!this.worker) {
35
44
  this.worker = new (await import('./worker/clang?worker')).default();
36
- this.worker.onmessage = () => resolve();
37
- this.worker.postMessage({ load: true, path, log, code, args });
45
+ this.assetBridge = new WorkerAssetBridge(this.worker, 'clang', assetConfig, progress);
46
+ this.worker.onmessage = (event) => {
47
+ if (this.assetBridge?.handleMessage(event))
48
+ return;
49
+ if (event.data?.progress != null)
50
+ progress?.set?.(event.data.progress);
51
+ if (event.data?.load)
52
+ resolve();
53
+ };
54
+ this.worker.postMessage({
55
+ load: true,
56
+ log,
57
+ code,
58
+ args,
59
+ assets: {
60
+ baseUrl: assetConfig.baseUrl,
61
+ useAssetBridge: assetConfig.useAssetBridge
62
+ }
63
+ });
38
64
  }
39
65
  else {
66
+ this.assetBridge?.rebind(this.worker, assetConfig, progress);
40
67
  this.worker.postMessage({ log });
41
68
  resolve();
42
69
  }
@@ -74,6 +101,8 @@ class Clang {
74
101
  this.setBreakpoints(options.debug ? [...(options.breakpoints || [])] : []);
75
102
  const interrupt = new Uint8Array(this.interruptBuffer), _uid = ++this.uid;
76
103
  const handler = (event) => {
104
+ if (this.assetBridge?.handleMessage(event))
105
+ return;
77
106
  if (!this.worker)
78
107
  return reject('Worker not loaded');
79
108
  if (_uid !== this.uid)
@@ -180,6 +209,7 @@ class Clang {
180
209
  Atomics.notify(control, 0);
181
210
  this.worker?.terminate?.();
182
211
  delete this.worker;
212
+ this.assetBridge = null;
183
213
  this.exit = true;
184
214
  }
185
215
  async clear() {
@@ -198,6 +228,7 @@ class Clang {
198
228
  if (!this.exit) {
199
229
  this.worker?.terminate?.();
200
230
  delete this.worker;
231
+ this.assetBridge = null;
201
232
  this.exit = true;
202
233
  }
203
234
  }
@@ -96,6 +96,7 @@ class Ocaml {
96
96
  if (!this.worker)
97
97
  return reject('Worker not loaded');
98
98
  const target = options.ocamlBackend || 'wasm';
99
+ const wasmBinaryenMode = options.ocamlWasmBinaryenMode || 'fast';
99
100
  const _uid = ++this.uid;
100
101
  this.activeReject = reject;
101
102
  const handler = async (event) => {
@@ -308,6 +309,7 @@ class Ocaml {
308
309
  code,
309
310
  prepare,
310
311
  target,
312
+ wasmBinaryenMode,
311
313
  log: _log,
312
314
  buffer: this.buffer
313
315
  });
@@ -15,7 +15,9 @@ export interface CompilerDiagnostic {
15
15
  }
16
16
  export type RustTargetTriple = 'wasm32-wasip1' | 'wasm32-wasip2' | 'wasm32-wasip3';
17
17
  export type GoTarget = 'wasip1/wasm' | 'wasip2/wasm' | 'wasip3/wasm' | 'js/wasm';
18
+ export type TinyGoTarget = 'wasm' | 'wasip1' | 'wasip2' | 'wasip3';
18
19
  export type OcamlBackend = 'js' | 'wasm';
20
+ export type OcamlWasmBinaryenMode = 'fast' | 'full';
19
21
  export type DebugVariableKind = 'number' | 'bool' | 'array' | 'text';
20
22
  export type DebugArrayElementKind = 'int' | 'float' | 'double' | 'bool' | 'char';
21
23
  export interface DebugStructFieldMetadata {
@@ -62,7 +64,9 @@ export interface SandboxExecutionOptions {
62
64
  cVersion?: string;
63
65
  rustTargetTriple?: RustTargetTriple;
64
66
  goTarget?: GoTarget;
67
+ tinygoTarget?: TinyGoTarget;
65
68
  ocamlBackend?: OcamlBackend;
69
+ ocamlWasmBinaryenMode?: OcamlWasmBinaryenMode;
66
70
  }
67
71
  export interface ResolvedSandboxExecutionArgs {
68
72
  compileArgs: string[];
@@ -1,5 +1,5 @@
1
1
  import { type PlaygroundRuntimeAssets, type TinyGoRuntimeAssetLoader, type TinyGoRuntimeAssetPackReference } from './assets';
2
- import { type SandboxExecutionOptions } from './options';
2
+ import { type SandboxExecutionOptions, type TinyGoTarget } from './options';
3
3
  import type { Sandbox } from './sandbox';
4
4
  type TinyGoRuntimeHooks = {
5
5
  boot(): Promise<void>;
@@ -15,6 +15,9 @@ type TinyGoRuntimeHooks = {
15
15
  entrypoint?: '_start' | '_initialize' | 'main' | null;
16
16
  reason?: 'bootstrap-artifact' | 'missing-wasi-entrypoint';
17
17
  } | null;
18
+ setBuildRequestOverrides?(overrides: {
19
+ target?: TinyGoTarget;
20
+ } | null): void;
18
21
  setWorkspaceFiles(files: Record<string, string> | null): void;
19
22
  dispose?(): void;
20
23
  };
@@ -146,7 +146,8 @@ class TinyGo {
146
146
  }
147
147
  const moduleUrl = this.moduleUrl;
148
148
  this.runtimePromise = (async () => {
149
- const runtimeModule = (await import(/* @vite-ignore */ moduleUrl));
149
+ const runtimeModule = (await import(
150
+ /* @vite-ignore */ moduleUrl));
150
151
  if (typeof runtimeModule.createBundledTinyGoRuntime === 'function') {
151
152
  this.runtime = runtimeModule.createBundledTinyGoRuntime({
152
153
  assetLoader: this.assetLoader,
@@ -212,7 +213,6 @@ class TinyGo {
212
213
  });
213
214
  return this.runtime;
214
215
  }
215
- ;
216
216
  throw new Error('TinyGo runtime module must export createBundledTinyGoRuntime or createTinyGoRuntime');
217
217
  })().catch((error) => {
218
218
  this.disposeRuntime();
@@ -245,11 +245,13 @@ class TinyGo {
245
245
  }
246
246
  return 'TinyGo compilation failed';
247
247
  }
248
- async compileArtifact(code, log = true, prog) {
248
+ async compileArtifact(code, target = 'wasm', log = true, prog) {
249
+ const hostCompileTarget = target === 'wasm' ? 'wasip1' : target;
249
250
  const compileCacheKey = JSON.stringify({
250
251
  code,
251
252
  hostCompileUrls: this.hostCompileUrls,
252
- moduleUrl: this.moduleUrl
253
+ moduleUrl: this.moduleUrl,
254
+ target
253
255
  });
254
256
  if (this.compiledArtifact && this.compiledCacheKey === compileCacheKey) {
255
257
  return;
@@ -266,7 +268,8 @@ class TinyGo {
266
268
  'content-type': 'application/json'
267
269
  },
268
270
  body: JSON.stringify({
269
- source: code
271
+ source: code,
272
+ target: hostCompileTarget
270
273
  })
271
274
  });
272
275
  }
@@ -337,6 +340,7 @@ class TinyGo {
337
340
  runtime.reset();
338
341
  this.lastActivityLog = runtime.readActivityLog();
339
342
  runtime.setWorkspaceFiles({ 'main.go': code });
343
+ runtime.setBuildRequestOverrides?.({ target });
340
344
  this.runtimeProgress = prog;
341
345
  this.runtimeProgressAssets.clear();
342
346
  this.runtimeProgressStart = 0.05;
@@ -420,7 +424,8 @@ class TinyGo {
420
424
  try {
421
425
  this.begin = Date.now();
422
426
  await this.ensureWorker();
423
- await this.compileArtifact(code, _log, prepare ? _prog : undefined);
427
+ const target = options.tinygoTarget || 'wasm';
428
+ await this.compileArtifact(code, target, _log, prepare ? _prog : undefined);
424
429
  if (prepare) {
425
430
  this.elapse = Date.now() - this.begin;
426
431
  this.exit = true;
@@ -1 +1 @@
1
- export declare const WASM_OCAML_ASSET_VERSION = "bd4c85620ead3426";
1
+ export declare const WASM_OCAML_ASSET_VERSION = "5215e843db69fc28";
@@ -1 +1 @@
1
- export const WASM_OCAML_ASSET_VERSION = "bd4c85620ead3426";
1
+ export const WASM_OCAML_ASSET_VERSION = "5215e843db69fc28";
@@ -1 +1 @@
1
- export declare const WASM_TINYGO_ASSET_VERSION = "c45e1d6b3e297250";
1
+ export declare const WASM_TINYGO_ASSET_VERSION = "be561e38c81e2e23";
@@ -1 +1 @@
1
- export const WASM_TINYGO_ASSET_VERSION = "c45e1d6b3e297250";
1
+ export const WASM_TINYGO_ASSET_VERSION = 'be561e38c81e2e23';
@@ -1,4 +1,5 @@
1
1
  import { waitForBufferedStdin } from '../stdinBuffer';
2
+ import { configureWorkerRuntimeAssets, handleWorkerAssetMessage } from './assets';
2
3
  self.document = {
3
4
  querySelectorAll() {
4
5
  return [];
@@ -17,9 +18,13 @@ async function loadClang(path, log) {
17
18
  });
18
19
  }
19
20
  self.onmessage = async (event) => {
20
- const { code, buffer, debugBuffer, watchBuffer, watchResultBuffer, load, interrupt, log, path, prepare, language, compileArgs, programArgs, cppVersion, cVersion, debug, breakpoints, pauseOnEntry } = event.data;
21
+ if (handleWorkerAssetMessage(event.data))
22
+ return;
23
+ const { code, buffer, debugBuffer, watchBuffer, watchResultBuffer, load, interrupt, log, path, assets, prepare, language, compileArgs, programArgs, cppVersion, cVersion, debug, breakpoints, pauseOnEntry } = event.data;
21
24
  if (load) {
22
- await loadClang(path, log);
25
+ const runtimeAssets = assets;
26
+ configureWorkerRuntimeAssets(runtimeAssets || null);
27
+ await loadClang(runtimeAssets?.baseUrl || path || '', log);
23
28
  postMessage({ load: true });
24
29
  }
25
30
  else if (prepare) {
@@ -363,7 +363,7 @@ async function executeCompileResult(result, log = false) {
363
363
  }
364
364
  }
365
365
  self.onmessage = async (event) => {
366
- const { load, moduleUrl: nextModuleUrl, manifestUrl: nextManifestUrl, code, prepare, target = 'wasm', log = true, buffer } = event.data;
366
+ const { load, moduleUrl: nextModuleUrl, manifestUrl: nextManifestUrl, code, prepare, target = 'wasm', wasmBinaryenMode = 'fast', log = true, buffer } = event.data;
367
367
  try {
368
368
  if (load) {
369
369
  moduleUrl = nextModuleUrl;
@@ -374,7 +374,7 @@ self.onmessage = async (event) => {
374
374
  }
375
375
  stdinBufferOcaml = buffer ? new Int32Array(buffer) : null;
376
376
  if (log) {
377
- console.log(`[wasm-idle:ocaml-worker] compile start prepare=${prepare} target=${target}`);
377
+ console.log(`[wasm-idle:ocaml-worker] compile start prepare=${prepare} target=${target} binaryen=${wasmBinaryenMode}`);
378
378
  }
379
379
  postMessage({ progress: { stage: 'compile-bootstrap', percent: 10 } });
380
380
  const [compilerModule, manifest] = await Promise.all([
@@ -382,7 +382,7 @@ self.onmessage = async (event) => {
382
382
  loadManifest(manifestUrl)
383
383
  ]);
384
384
  postMessage({ progress: { stage: 'compile-ready', percent: 25 } });
385
- const compileKey = `${target}\n${code}`;
385
+ const compileKey = `${target}\n${wasmBinaryenMode}\n${code}`;
386
386
  let compiledFresh = false;
387
387
  if (!compiledResult || compiledCacheKey !== compileKey) {
388
388
  const result = await compilerModule.compile({
@@ -391,7 +391,8 @@ self.onmessage = async (event) => {
391
391
  },
392
392
  entry: 'main.ml',
393
393
  target,
394
- effectsMode: 'cps'
394
+ effectsMode: 'cps',
395
+ wasmBinaryenMode
395
396
  }, {
396
397
  system: compilerModule.createBrowserWorkerSystemDispatcher({
397
398
  manifest
@@ -107,6 +107,10 @@
107
107
  hasPythonLoader: !!currentRuntimeAssets?.python?.loader,
108
108
  javaBaseUrl: currentRuntimeAssets?.java?.baseUrl || '',
109
109
  hasJavaLoader: !!currentRuntimeAssets?.java?.loader,
110
+ clangBaseUrl: currentRuntimeAssets?.clang?.baseUrl || '',
111
+ hasClangLoader: !!currentRuntimeAssets?.clang?.loader,
112
+ clangdBaseUrl: currentRuntimeAssets?.clangd?.baseUrl || '',
113
+ hasClangdLoader: !!currentRuntimeAssets?.clangd?.loader,
110
114
  rustCompilerUrl: currentRuntimeAssets?.rust?.compilerUrl || '',
111
115
  goCompilerUrl: currentRuntimeAssets?.go?.compilerUrl || '',
112
116
  elixirBundleUrl: currentRuntimeAssets?.elixir?.bundleUrl || '',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wasm-idle",
3
- "version": "0.7.1",
3
+ "version": "0.7.2",
4
4
  "description": "A simple web app to run code in the browser",
5
5
  "license": "MIT",
6
6
  "type": "module",