wasm-idle 1.0.8 → 1.0.9

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 (56) hide show
  1. package/README.md +48 -11
  2. package/dist/playground/applicationAssets.js +18 -0
  3. package/dist/playground/assets.d.ts +70 -0
  4. package/dist/playground/assets.js +120 -0
  5. package/dist/playground/cachedClang.js +43 -5
  6. package/dist/playground/clang.d.ts +5 -0
  7. package/dist/playground/clang.js +96 -0
  8. package/dist/playground/clangWorkerProtocol.d.ts +12 -1
  9. package/dist/playground/fennel.d.ts +9 -0
  10. package/dist/playground/fennel.js +30 -0
  11. package/dist/playground/fennelBootstrap.d.ts +31 -0
  12. package/dist/playground/fennelBootstrap.js +118 -0
  13. package/dist/playground/grain.d.ts +9 -0
  14. package/dist/playground/grain.js +127 -0
  15. package/dist/playground/hy.d.ts +21 -0
  16. package/dist/playground/hy.js +24 -0
  17. package/dist/playground/index.d.ts +1 -1
  18. package/dist/playground/index.js +49 -0
  19. package/dist/playground/lua.d.ts +19 -0
  20. package/dist/playground/lua.js +64 -39
  21. package/dist/playground/objectivec.d.ts +3 -1
  22. package/dist/playground/objectivec.js +6 -2
  23. package/dist/playground/options.js +1 -1
  24. package/dist/playground/postgresql.d.ts +36 -0
  25. package/dist/playground/postgresql.js +543 -0
  26. package/dist/playground/python.d.ts +5 -0
  27. package/dist/playground/python.js +13 -0
  28. package/dist/playground/rescript.d.ts +5 -0
  29. package/dist/playground/rescript.js +58 -0
  30. package/dist/playground/rescriptPreflight.d.ts +26 -0
  31. package/dist/playground/rescriptPreflight.js +381 -0
  32. package/dist/playground/staticRuntimeModuleVersion.d.ts +1 -1
  33. package/dist/playground/staticRuntimeModuleVersion.js +1 -1
  34. package/dist/playground/staticRuntimePreflightExecute.d.ts +2 -1
  35. package/dist/playground/staticRuntimePreflightExecute.js +9 -0
  36. package/dist/playground/staticRuntimePreflightProtocol.d.ts +1 -1
  37. package/dist/playground/v.d.ts +46 -0
  38. package/dist/playground/v.js +703 -0
  39. package/dist/playground/wasmFennelVersion.d.ts +23 -0
  40. package/dist/playground/wasmFennelVersion.js +16 -0
  41. package/dist/playground/wasmGrainVersion.d.ts +24 -0
  42. package/dist/playground/wasmGrainVersion.js +25 -0
  43. package/dist/playground/wasmHyVersion.d.ts +7 -0
  44. package/dist/playground/wasmHyVersion.js +15 -0
  45. package/dist/playground/wasmReScriptVersion.d.ts +20 -0
  46. package/dist/playground/wasmReScriptVersion.js +20 -0
  47. package/dist/playground/worker/cachedClangCompile.js +37 -4
  48. package/dist/playground/worker/clang.js +35 -7
  49. package/dist/playground/worker/lua.js +48 -11
  50. package/dist/playground/worker/postgresql.d.ts +1 -0
  51. package/dist/playground/worker/postgresql.js +205 -0
  52. package/dist/playground/worker/python.js +106 -9
  53. package/dist/playground/worker/staticRuntimePreflight.js +2 -1
  54. package/dist/playground/worker/v.d.ts +1 -0
  55. package/dist/playground/worker/v.js +106 -0
  56. package/package.json +18 -7
@@ -2,6 +2,7 @@ import { flushQueuedStdin, readBufferedStdin, waitForBufferedStdin } from '../st
2
2
  import { isSharedBufferBackedView } from '../sharedBuffer';
3
3
  import { parsePythonPackageLock } from '../pythonPackageLock';
4
4
  import { withCachedPyodideModule } from './runtimeModule';
5
+ import { fetchRuntimeAssetBytes } from './runtimeAssetFetch';
5
6
  import { configureWorkerRuntimeAssetAllowlist, configureWorkerRuntimeAssets, handleWorkerAssetMessage, loadWorkerRuntimeAsset } from './assets';
6
7
  self.document = {
7
8
  querySelector() {
@@ -14,6 +15,64 @@ self.document = {
14
15
  let stdinBufferPyodide, debugBufferPyodide, watchBufferPyodide, watchResultBufferPyodide, interruptBufferPyodide, pyodide, baseUrl = '', useAssetBridge = false;
15
16
  // Only the next matching run may reuse a successful package preparation.
16
17
  let preparedPackagesKey;
18
+ let maxRuntimeAssetBytes;
19
+ let installedHyVersion;
20
+ const HY_WHEEL_NAME_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._+-]*\.whl$/u;
21
+ const HY_VERSION_PATTERN = /^[0-9]{1,6}\.[0-9]{1,6}\.[0-9]{1,6}$/u;
22
+ const MAX_HY_WHEELS = 8;
23
+ function parseHyExtension(extension) {
24
+ const candidate = extension;
25
+ if (!candidate ||
26
+ candidate.language !== 'hy' ||
27
+ typeof candidate.version !== 'string' ||
28
+ !HY_VERSION_PATTERN.test(candidate.version) ||
29
+ !Array.isArray(candidate.wheels) ||
30
+ candidate.wheels.length === 0 ||
31
+ candidate.wheels.length > MAX_HY_WHEELS) {
32
+ throw new Error('Hy runtime configuration is invalid');
33
+ }
34
+ const wheels = candidate.wheels.map((wheel) => {
35
+ if (!wheel ||
36
+ typeof wheel.url !== 'string' ||
37
+ typeof wheel.fileName !== 'string' ||
38
+ !HY_WHEEL_NAME_PATTERN.test(wheel.fileName) ||
39
+ !Number.isSafeInteger(wheel.bytes) ||
40
+ wheel.bytes <= 0 ||
41
+ typeof wheel.sha256 !== 'string' ||
42
+ !/^[a-f0-9]{64}$/u.test(wheel.sha256)) {
43
+ throw new Error('Hy runtime wheel receipt is invalid');
44
+ }
45
+ return wheel;
46
+ });
47
+ return { version: candidate.version, wheels };
48
+ }
49
+ /** Install the receipt-verified Hy wheels into the running Pyodide site-packages once per worker. */
50
+ async function installHy(extension) {
51
+ const { version, wheels } = parseHyExtension(extension);
52
+ if (installedHyVersion === version)
53
+ return;
54
+ if (installedHyVersion !== undefined)
55
+ throw new Error('Hy runtime version changed');
56
+ const sitePackages = String(pyodide.runPython('import sysconfig\nsysconfig.get_path("purelib")'));
57
+ for (const [index, wheel] of wheels.entries()) {
58
+ postProgress(60 + Math.floor((index * 30) / wheels.length), `Loading ${wheel.fileName}`);
59
+ const bytes = await fetchRuntimeAssetBytes({
60
+ url: new URL(wheel.url, globalThis.location?.href).href,
61
+ label: `Hy wheel ${wheel.fileName}`,
62
+ cache: 'force-cache',
63
+ expected: { bytes: wheel.bytes, sha256: wheel.sha256 },
64
+ maxAssetBytes: Math.min(maxRuntimeAssetBytes ?? wheel.bytes, wheel.bytes),
65
+ integrityContext: { asset: wheel.fileName, runtimeId: 'HY' }
66
+ });
67
+ pyodide.unpackArchive(bytes, 'whl', { extractDir: sitePackages });
68
+ }
69
+ postProgress(92, 'Compiling Hy core');
70
+ const loadedVersion = String(pyodide.runPython('import importlib\nimportlib.invalidate_caches()\nimport hy\nimport hy.compiler\nhy.__version__'));
71
+ if (loadedVersion !== version) {
72
+ throw new Error(`Hy runtime version mismatch: expected ${version}, loaded ${loadedVersion}`);
73
+ }
74
+ installedHyVersion = version;
75
+ }
17
76
  const imageHook = `
18
77
  if not globals().get("__wasm_idle_img_inited__", False):
19
78
  globals()["__wasm_idle_img_inited__"] = True
@@ -257,16 +316,20 @@ function writeWorkspaceFiles(files = []) {
257
316
  self.onmessage = async (event) => {
258
317
  if (handleWorkerAssetMessage(event.data))
259
318
  return;
260
- const { code, buffer, debugBuffer, watchBuffer, watchResultBuffer, load, interrupt, assets, prepare, stdin, debug = false, breakpoints = [], pauseOnEntry = false, activePath, debugPath, workspaceFiles } = event.data;
319
+ const { code, buffer, debugBuffer, watchBuffer, watchResultBuffer, load, interrupt, assets, prepare, stdin, debug = false, breakpoints = [], pauseOnEntry = false, activePath, debugPath, workspaceFiles, language = 'python', extension } = event.data;
320
+ const isHy = language === 'hy';
261
321
  if (load) {
262
322
  preparedPackagesKey = undefined;
263
323
  try {
264
324
  const runtimeAssets = assets;
265
325
  baseUrl = runtimeAssets?.baseUrl || baseUrl;
266
326
  useAssetBridge = runtimeAssets?.useAssetBridge === true;
327
+ maxRuntimeAssetBytes = runtimeAssets?.maxAssetBytes;
267
328
  configureWorkerRuntimeAssets(runtimeAssets || null);
268
329
  postProgress(2, 'Loading Pyodide module');
269
330
  await loadPyodide(baseUrl);
331
+ if (extension !== undefined)
332
+ await installHy(extension);
270
333
  postProgress(100, 'Pyodide runtime ready');
271
334
  postMessage({ load: true });
272
335
  }
@@ -282,10 +345,12 @@ self.onmessage = async (event) => {
282
345
  await loadPyodide(baseUrl);
283
346
  writeWorkspaceFiles(workspaceFiles);
284
347
  postProgress(15, 'Resolving Python imports');
285
- await loadPackages([
286
- code,
287
- ...(workspaceFiles || []).map((file) => file.content)
288
- ].join('\n'));
348
+ // Hy sources are not Python; imports resolve against the bundled runtime only.
349
+ if (!isHy)
350
+ await loadPackages([
351
+ code,
352
+ ...(workspaceFiles || []).map((file) => file.content)
353
+ ].join('\n'));
289
354
  preparedPackagesKey = preparationKey;
290
355
  postProgress(100, 'Python packages ready');
291
356
  self.postMessage({ results: true });
@@ -303,7 +368,12 @@ self.onmessage = async (event) => {
303
368
  try {
304
369
  await loadPyodide(baseUrl);
305
370
  writeWorkspaceFiles(workspaceFiles);
306
- if (preparedKey !== packagePreparationKey(code, activePath, workspaceFiles)) {
371
+ if (isHy && installedHyVersion === undefined) {
372
+ throw new Error('Hy runtime is not installed');
373
+ }
374
+ if (isHy && debug)
375
+ throw new Error('Hy debugging is not supported');
376
+ if (!isHy && preparedKey !== packagePreparationKey(code, activePath, workspaceFiles)) {
307
377
  await loadPackages([
308
378
  code,
309
379
  ...(workspaceFiles || []).map((file) => file.content)
@@ -445,7 +515,8 @@ self.onmessage = async (event) => {
445
515
  }
446
516
  return JSON.stringify({ version, lines });
447
517
  };
448
- const executionFilename = normalizeWorkspacePath(activePath || '') || '__wasm_idle_user__.py';
518
+ const executionFilename = normalizeWorkspacePath(activePath || '') ||
519
+ (isHy ? '__wasm_idle_user__.hy' : '__wasm_idle_user__.py');
449
520
  const debugFilename = normalizeWorkspacePath(debugPath || '') || executionFilename;
450
521
  const executionFilenameLiteral = JSON.stringify(executionFilename);
451
522
  const debugFilenameLiteral = JSON.stringify(debugFilename);
@@ -645,6 +716,31 @@ sys.settrace(__wasm_idle_debug_trace)
645
716
  `
646
717
  : ''}
647
718
 
719
+ ${isHy
720
+ ? `
721
+ try:
722
+ import types
723
+ import hy
724
+ import hy.compiler
725
+ __wasm_idle_module = types.ModuleType("__main__")
726
+ __wasm_idle_module.__file__ = ${executionFilenameLiteral}
727
+ __wasm_idle_source = ${JSON.stringify(code)}
728
+ __wasm_idle_compiled = compile(
729
+ hy.compiler.hy_compile(
730
+ hy.read_many(__wasm_idle_source, filename = ${executionFilenameLiteral}),
731
+ __wasm_idle_module,
732
+ filename = ${executionFilenameLiteral},
733
+ source = __wasm_idle_source,
734
+ ),
735
+ ${executionFilenameLiteral},
736
+ "exec",
737
+ )
738
+ __wasm_idle_execution_ready()
739
+ exec(__wasm_idle_compiled, __wasm_idle_module.__dict__)
740
+ finally:
741
+ del __wasm_idle_execution_ready
742
+ `
743
+ : `
648
744
  try:
649
745
  __wasm_idle_globals = {
650
746
  "__name__": "__main__",
@@ -669,14 +765,15 @@ finally:
669
765
  del __wasm_idle_execution_ready
670
766
  sys.settrace(None)
671
767
  ${debug
672
- ? `
768
+ ? `
673
769
  __wasm_idle_debug_step_mode = None
674
770
  __wasm_idle_debug_resume_skip = None
675
771
  __wasm_idle_debug_next_depth = None
676
772
  __wasm_idle_debug_next_line = None
677
773
  __wasm_idle_debug_step_out_depth = None
678
774
  `
679
- : ''}
775
+ : ''}
776
+ `}
680
777
  `);
681
778
  self.postMessage({ results: true });
682
779
  }
@@ -16,7 +16,8 @@ function isRequest(value) {
16
16
  request.runtimeId === 'FORTH' ||
17
17
  request.runtimeId === 'J' ||
18
18
  request.runtimeId === 'JANET' ||
19
- request.runtimeId === 'PROLOG') &&
19
+ request.runtimeId === 'PROLOG' ||
20
+ request.runtimeId === 'RESCRIPT') &&
20
21
  typeof request.baseUrl === 'string' &&
21
22
  typeof request.manifestUrl === 'string' &&
22
23
  request.profile !== null &&
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,106 @@
1
+ import { waitForBufferedStdin } from '../stdinBuffer';
2
+ import { configureWorkerRuntimeAssets, handleWorkerAssetMessage } from './assets';
3
+ import { createVCompiler, executeBrowserVArtifact } from '@wasm-idle/llvm-core/v';
4
+ self.document = {
5
+ querySelectorAll() {
6
+ return [];
7
+ }
8
+ };
9
+ let compiler = null;
10
+ let stdinBufferV = null;
11
+ let hasInitialStdinV = false;
12
+ let initialStdinV = null;
13
+ let initialStdinConsumedV = false;
14
+ const normalizeWorkspacePath = (value) => value
15
+ .replaceAll('\\', '/')
16
+ .split('/')
17
+ .filter((part) => part && part !== '.' && part !== '..')
18
+ .join('/');
19
+ const ensureTrailingNewline = (source) => (source.endsWith('\n') ? source : `${source}\n`);
20
+ function resolveInputPath(activePath) {
21
+ const normalized = normalizeWorkspacePath(activePath || '');
22
+ if (!normalized)
23
+ return 'main.v';
24
+ return /\.[A-Za-z0-9_-]+$/.test(normalized) ? normalized : `${normalized}.v`;
25
+ }
26
+ function readProgramStdin() {
27
+ if (hasInitialStdinV) {
28
+ if (initialStdinConsumedV)
29
+ return null;
30
+ initialStdinConsumedV = true;
31
+ return initialStdinV ?? '';
32
+ }
33
+ return waitForBufferedStdin(stdinBufferV, () => postMessage({ buffer: true }));
34
+ }
35
+ async function loadVRuntime(clangAssets, vBaseUrl, maxAssetBytes, log) {
36
+ configureWorkerRuntimeAssets(clangAssets || null);
37
+ compiler = await createVCompiler({
38
+ runtimeBaseUrl: vBaseUrl,
39
+ clangRuntimeBaseUrl: clangAssets?.baseUrl || '',
40
+ maxAssetBytes,
41
+ log
42
+ });
43
+ }
44
+ self.onmessage = async (event) => {
45
+ if (handleWorkerAssetMessage(event.data))
46
+ return;
47
+ const { code, buffer, load, log, prepare, compileArgs, programArgs, activePath, workspaceFiles, stdin, clangAssets, vBaseUrl, maxAssetBytes } = event.data;
48
+ if (load) {
49
+ try {
50
+ await loadVRuntime(clangAssets, vBaseUrl, maxAssetBytes, log);
51
+ postMessage({ load: true });
52
+ }
53
+ catch (error) {
54
+ postMessage({ error: error.message });
55
+ }
56
+ }
57
+ else if (typeof log === 'boolean' && !code) {
58
+ // The compiler receives the current logging preference for every compilation.
59
+ if (typeof code === 'string')
60
+ postMessage({ results: true });
61
+ }
62
+ else if (code) {
63
+ if (!compiler) {
64
+ postMessage({ error: 'V runtime is not loaded.' });
65
+ return;
66
+ }
67
+ stdinBufferV = new Int32Array(buffer);
68
+ hasInitialStdinV = typeof stdin === 'string';
69
+ initialStdinV = hasInitialStdinV ? stdin : null;
70
+ initialStdinConsumedV = false;
71
+ try {
72
+ const files = (workspaceFiles || []);
73
+ const result = await compiler.compile({
74
+ code: ensureTrailingNewline(code),
75
+ fileName: resolveInputPath(activePath),
76
+ compileArgs: compileArgs || [],
77
+ workspaceFiles: files,
78
+ log,
79
+ onProgress: ({ percent, message }) => {
80
+ postMessage({ progress: percent / 100 });
81
+ if (log)
82
+ postMessage({ log: message });
83
+ }
84
+ });
85
+ if (!result.success || !result.artifact) {
86
+ throw new Error(result.stderr || 'V did not produce a WebAssembly program.');
87
+ }
88
+ if (!prepare) {
89
+ const execution = await executeBrowserVArtifact(result.artifact, {
90
+ args: programArgs || [],
91
+ stdin: readProgramStdin,
92
+ stdout: (output) => postMessage({ output }),
93
+ stderr: (output) => postMessage({ output }),
94
+ files: files.map(({ path, content }) => ({ path, contents: content }))
95
+ });
96
+ if (execution.exitCode) {
97
+ throw new Error(`V program exited with ${execution.exitCode}`);
98
+ }
99
+ }
100
+ postMessage({ results: true });
101
+ }
102
+ catch (error) {
103
+ postMessage({ error: error.message });
104
+ }
105
+ }
106
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wasm-idle",
3
- "version": "1.0.8",
3
+ "version": "1.0.9",
4
4
  "description": "A simple web app to run code in the browser",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -25,6 +25,7 @@
25
25
  "@testing-library/user-event": "^14.6.1",
26
26
  "@assemblyscript/loader": "0.28.17",
27
27
  "@duckdb/duckdb-wasm": "1.33.1-dev45.0",
28
+ "@electric-sql/pglite": "0.5.8",
28
29
  "@live-codes/gleam-precompiled": "0.5.0",
29
30
  "@ruby/3.4-wasm-wasi": "2.9.3-2.9.4",
30
31
  "@ruby/wasm-wasi": "2.9.3-2.9.4",
@@ -61,15 +62,15 @@
61
62
  "vitest": "^4.1.4",
62
63
  "waforth": "0.20.1",
63
64
  "webr": "0.6.0",
64
- "@wasm-idle/debug": "1.0.8",
65
- "@wasm-idle/lsp": "1.0.8",
66
- "@wasm-idle/terminal": "1.0.8"
65
+ "@wasm-idle/debug": "1.0.9",
66
+ "@wasm-idle/lsp": "1.0.9",
67
+ "@wasm-idle/terminal": "1.0.9"
67
68
  },
68
69
  "dependencies": {
69
70
  "@bjorn3/browser_wasi_shim": "^0.4.2",
70
71
  "fflate": "0.8.3",
71
- "@wasm-idle/core": "1.0.8",
72
- "@wasm-idle/llvm-core": "1.0.8"
72
+ "@wasm-idle/core": "1.0.9",
73
+ "@wasm-idle/llvm-core": "1.0.9"
73
74
  },
74
75
  "files": [
75
76
  "dist",
@@ -114,6 +115,8 @@
114
115
  "test:browser:clang-stdin": "WASM_IDLE_RUN_REAL_BROWSER_CLANG_STDIN=1 pnpm exec vitest run src/lib/playground/stdin.playwright.test.ts",
115
116
  "test:browser:fortran": "WASM_IDLE_RUN_REAL_BROWSER_FORTRAN=1 pnpm exec vitest run src/lib/playground/stdin.playwright.test.ts",
116
117
  "test:browser:cobol": "WASM_IDLE_RUN_REAL_BROWSER_COBOL=1 pnpm exec vitest run src/lib/playground/stdin.playwright.test.ts",
118
+ "test:browser:v": "WASM_IDLE_RUN_REAL_BROWSER_V=1 pnpm exec vitest run src/lib/playground/stdin.playwright.test.ts -t \"V \"",
119
+ "test:browser:postgresql": "WASM_IDLE_RUN_REAL_BROWSER_POSTGRESQL=1 pnpm exec vitest run src/lib/playground/stdin.playwright.test.ts",
117
120
  "test:browser:objectivec": "WASM_IDLE_RUN_REAL_BROWSER_OBJECTIVEC=1 pnpm exec vitest run src/lib/playground/stdin.playwright.test.ts",
118
121
  "test:browser:objectivecxx": "WASM_IDLE_RUN_REAL_BROWSER_OBJECTIVECXX=1 pnpm exec vitest run src/lib/playground/objectivecxx.playwright.test.ts",
119
122
  "test:browser:debug": "WASM_IDLE_RUN_REAL_BROWSER_DEBUG=1 pnpm exec vitest run src/lib/playground/debug.playwright.test.ts",
@@ -122,6 +125,7 @@
122
125
  "test:browser:d": "WASM_IDLE_RUN_REAL_BROWSER_D=1 pnpm exec vitest run src/lib/playground/d.playwright.test.ts",
123
126
  "test:browser:stdin": "WASM_IDLE_RUN_REAL_BROWSER_STDIN=1 pnpm exec vitest run src/lib/playground/stdin.playwright.test.ts",
124
127
  "test:browser:lisp": "WASM_IDLE_RUN_REAL_BROWSER_LISP=1 pnpm exec vitest run src/lib/playground/stdin.playwright.test.ts",
128
+ "test:browser:fennel": "WASM_IDLE_RUN_REAL_BROWSER_FENNEL=1 pnpm exec vitest run src/lib/playground/stdin.playwright.test.ts",
125
129
  "test:browser:ocaml": "WASM_IDLE_RUN_REAL_BROWSER_OCAML=1 pnpm exec vitest run src/lib/playground/ocaml.playwright.test.ts",
126
130
  "test:browser:octave": "WASM_IDLE_RUN_REAL_BROWSER_OCTAVE=1 pnpm exec vitest run src/lib/playground/octave.playwright.test.ts",
127
131
  "test:browser:prolog": "WASM_IDLE_RUN_REAL_BROWSER_PROLOG=1 pnpm exec vitest run src/lib/playground/static-worker-runtimes.playwright.test.ts",
@@ -139,6 +143,7 @@
139
143
  "test:browser:bash": "WASM_IDLE_RUN_REAL_BROWSER_BASH=1 pnpm exec vitest run src/lib/playground/bash.playwright.test.ts",
140
144
  "test:browser:ruby": "WASM_IDLE_RUN_REAL_BROWSER_RUBY=1 pnpm exec vitest run src/lib/playground/ruby.playwright.test.ts",
141
145
  "test:browser:clojurescript": "WASM_IDLE_RUN_REAL_BROWSER_CLOJURESCRIPT=1 pnpm exec vitest run src/lib/playground/static-worker-runtimes.playwright.test.ts",
146
+ "test:browser:rescript": "WASM_IDLE_RUN_REAL_BROWSER_RESCRIPT=1 pnpm exec vitest run src/lib/playground/rescript.playwright.test.ts",
142
147
  "test:unit:swift": "pnpm exec vitest run src/lib/playground/swift.test.ts",
143
148
  "test:browser:playwright": "WASM_IDLE_RUN_REAL_BROWSER_RUST=1 pnpm exec vitest run src/lib/playground/rust.playwright.test.ts",
144
149
  "test:browser:tinygo": "WASM_IDLE_RUN_REAL_BROWSER_TINYGO=1 pnpm exec vitest run src/lib/playground/tinygo.playwright.test.ts",
@@ -156,6 +161,7 @@
156
161
  "test:wasm-debug-release": "node --test scripts/prepare-wasm-debug-release.test.mjs scripts/sync-wasm-debug.test.mjs scripts/verify-page-wasm-debug.test.mjs",
157
162
  "sync:wasm-objectivec": "node scripts/sync-wasm-objectivec.mjs",
158
163
  "sync:wasm-cobol": "node scripts/sync-runtime.mjs wasm-cobol",
164
+ "sync:wasm-v": "node scripts/sync-runtime.mjs wasm-v",
159
165
  "sync:wasm-of-js-of-ocaml": "node scripts/sync-runtime.mjs wasm-of-js-of-ocaml",
160
166
  "sync:wasm-dotnet": "node scripts/sync-runtime.mjs wasm-dotnet",
161
167
  "sync:wasm-d": "node scripts/sync-runtime.mjs wasm-d",
@@ -187,6 +193,7 @@
187
193
  "sync:wasm-nim": "node scripts/sync-runtime.mjs wasm-nim",
188
194
  "sync:wasm-bash": "node scripts/sync-runtime.mjs wasm-bash",
189
195
  "sync:wasm-clojurescript": "node scripts/sync-runtime.mjs wasm-clojurescript",
196
+ "sync:wasm-rescript": "node scripts/sync-runtime.mjs wasm-rescript",
190
197
  "sync:webr": "node scripts/sync-runtime.mjs webr",
191
198
  "compress:static-runtimes": "node scripts/compress-static-runtime-assets.mjs static",
192
199
  "compress:build-runtimes": "node scripts/compress-static-runtime-assets.mjs build",
@@ -203,7 +210,7 @@
203
210
  "build:static-runtime-modules": "node scripts/build-static-runtime-modules.mjs",
204
211
  "support:matrix": "node scripts/support-matrix.mjs write",
205
212
  "check:support-matrix": "node scripts/support-matrix.mjs check",
206
- "sync:page-runtimes": "pnpm run sync:pyodide && pnpm run sync:webr && pnpm run sync:wasm-of-js-of-ocaml && pnpm run sync:wasm-typescript && pnpm run sync:wasm-octave && pnpm run sync:wasm-prolog && pnpm run sync:wasm-gleam && pnpm run sync:wasm-perl && pnpm run sync:wasm-tcl && pnpm run sync:wasm-awk && pnpm run sync:wasm-pascal && pnpm run sync:wasm-forth && pnpm run sync:wasm-j && pnpm run sync:wasm-bqn && pnpm run sync:wasm-janet && pnpm run sync:wasm-julia && pnpm run sync:wasm-nim && pnpm run sync:wasm-ruby && pnpm run sync:wasm-bash && pnpm run sync:wasm-clojurescript",
213
+ "sync:page-runtimes": "pnpm run sync:pyodide && pnpm run sync:webr && pnpm run sync:wasm-of-js-of-ocaml && pnpm run sync:wasm-typescript && pnpm run sync:wasm-octave && pnpm run sync:wasm-prolog && pnpm run sync:wasm-gleam && pnpm run sync:wasm-perl && pnpm run sync:wasm-tcl && pnpm run sync:wasm-awk && pnpm run sync:wasm-pascal && pnpm run sync:wasm-forth && pnpm run sync:wasm-j && pnpm run sync:wasm-bqn && pnpm run sync:wasm-janet && pnpm run sync:wasm-julia && pnpm run sync:wasm-nim && pnpm run sync:wasm-ruby && pnpm run sync:wasm-bash && pnpm run sync:wasm-clojurescript && pnpm run sync:wasm-rescript",
207
214
  "page:build": "pnpm run verify:page-c3 && pnpm run verify:page-lfortran && pnpm run prepare:test-assets -- clang && pnpm run build:page-runtimes && pnpm run sync:page-runtimes && pnpm run build:static-runtime-modules && pnpm run prepare:wasm-debug-release && pnpm run layer:static-runtimes && pnpm run compress:static-runtimes && pnpm run assets:lock && pnpm run check:assets-lock && pnpm run build && pnpm run compress:build-runtimes && pnpm run verify:page-c3 build && pnpm run verify:page-lfortran build",
208
215
  "package:root": "svelte-kit sync && node scripts/clean-package-output.mjs && svelte-package --tsconfig ./tsconfig.package.json && publint",
209
216
  "package": "pnpm run build:publish-deps && pnpm run package:root",
@@ -225,6 +232,10 @@
225
232
  "format": "prettier --write .",
226
233
  "page": "pnpm run page:build && pnpm run test:browser:audit:full --use-build && node gh-pages.js",
227
234
  "sync:wasm-c3": "node scripts/sync-wasm-c3.mjs",
235
+ "sync:wasm-grain": "node scripts/sync-wasm-grain.mjs",
236
+ "test:browser:grain": "WASM_IDLE_RUN_REAL_BROWSER_GRAIN=1 pnpm exec vitest run src/lib/playground/grain.playwright.test.ts",
237
+ "sync:wasm-hy": "node scripts/sync-wasm-hy.mjs",
238
+ "test:browser:hy": "WASM_IDLE_RUN_REAL_BROWSER_HY=1 pnpm exec vitest run src/lib/playground/hy.playwright.test.ts",
228
239
  "test:browser:c3": "WASM_IDLE_RUN_REAL_BROWSER_C3=1 pnpm exec vitest run src/lib/playground/c3.playwright.test.ts",
229
240
  "test:unit:c3": "node --test scripts/c3-memory.test.mjs scripts/c3-stdin.test.mjs scripts/sync-wasm-c3.test.mjs",
230
241
  "verify:page-c3": "node scripts/verify-page-c3-compiler.mjs",