@componentor/quickjs-emscripten 0.31.22 → 0.31.24

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 (2) hide show
  1. package/README.md +131 -0
  2. package/package.json +22 -22
package/README.md CHANGED
@@ -63,6 +63,10 @@ main()
63
63
  - [Asyncify](#asyncify)
64
64
  - [Async module loader](#async-module-loader)
65
65
  - [Async on host, sync in QuickJS](#async-on-host-sync-in-quickjs)
66
+ - [Worker Pool (Parallel Execution)](#worker-pool-parallel-execution)
67
+ - [Browser Setup for Multi-Threading](#browser-setup-for-multi-threading)
68
+ - [WasmFS with OPFS (Native Filesystem)](#wasmfs-with-opfs-native-filesystem)
69
+ - [File Watching for HMR](#file-watching-for-hmr)
66
70
  - [Testing your code](#testing-your-code)
67
71
  - [Packaging](#packaging)
68
72
  - [Reducing package size](#reducing-package-size)
@@ -555,6 +559,133 @@ const upperCaseData = context.unwrapResult(result).consume(context.getString)
555
559
  console.log(upperCaseData) // 'VERY USEFUL DATA'
556
560
  ```
557
561
 
562
+ ### Worker Pool (Parallel Execution)
563
+
564
+ For applications that need to run many QuickJS evaluations, the `@componentor/quickjs-emscripten-worker-pool` package provides a worker pool that can run tasks in parallel across multiple Web Workers.
565
+
566
+ **Key features:**
567
+
568
+ - **Parallel execution** across multiple workers for CPU-bound tasks
569
+ - **Graceful degradation** to single-threaded mode when SharedArrayBuffer is unavailable
570
+ - **Same API** regardless of threading mode
571
+ - **Verbose logging** to verify multi-threading is working
572
+
573
+ ```bash
574
+ npm install @componentor/quickjs-emscripten-worker-pool @componentor/quickjs-singlefile-cjs-release-sync
575
+ ```
576
+
577
+ ```typescript
578
+ import {
579
+ newWorkerPool,
580
+ isMultiThreadingSupported,
581
+ } from "@componentor/quickjs-emscripten-worker-pool"
582
+
583
+ // Check if multi-threading is available
584
+ console.log("Multi-threading:", isMultiThreadingSupported())
585
+
586
+ // Create pool with verbose logging to verify workers
587
+ const pool = await newWorkerPool({
588
+ poolSize: 4,
589
+ verbose: true, // Logs worker creation and task dispatch
590
+ })
591
+
592
+ console.log("Using real workers:", pool.isMultiThreaded)
593
+
594
+ // Execute tasks in parallel (or sequentially if SharedArrayBuffer unavailable)
595
+ const results = await Promise.all([
596
+ pool.evalCode("1 + 1"),
597
+ pool.evalCode("2 * 2"),
598
+ pool.evalCode("Math.sqrt(16)"),
599
+ ])
600
+
601
+ pool.dispose()
602
+ ```
603
+
604
+ #### Browser Setup for Multi-Threading
605
+
606
+ Multi-threaded mode requires **Cross-Origin Isolation** via HTTP headers:
607
+
608
+ ```
609
+ Cross-Origin-Opener-Policy: same-origin
610
+ Cross-Origin-Embedder-Policy: require-corp
611
+ ```
612
+
613
+ **Vite example:**
614
+
615
+ ```typescript
616
+ // vite.config.ts
617
+ export default defineConfig({
618
+ server: {
619
+ headers: {
620
+ "Cross-Origin-Opener-Policy": "same-origin",
621
+ "Cross-Origin-Embedder-Policy": "require-corp",
622
+ },
623
+ },
624
+ })
625
+ ```
626
+
627
+ Without these headers, the pool automatically falls back to single-threaded mode (sequential execution on the main thread).
628
+
629
+ See the [worker-pool package documentation](./packages/quickjs-emscripten-worker-pool/README.md) for full API reference.
630
+
631
+ ### WasmFS with OPFS (Native Filesystem)
632
+
633
+ For applications that need high-performance filesystem access, the `@componentor/quickjs-wasmfs-release-sync` variant provides native filesystem operations via [WasmFS](https://emscripten.org/docs/api_reference/Filesystem-API.html#wasmfs) with [OPFS](https://developer.mozilla.org/en-US/docs/Web/API/File_System_API/Origin_private_file_system) (Origin Private File System) backend.
634
+
635
+ **Key benefits:**
636
+
637
+ - **No JS boundary crossing** - filesystem operations run entirely inside Wasm
638
+ - **Persistent storage** - files persist across sessions via OPFS
639
+ - **Faster I/O** - eliminates ~1-5ms overhead per filesystem call
640
+
641
+ ```bash
642
+ npm install @componentor/quickjs-wasmfs-release-sync quickjs-emscripten-core
643
+ ```
644
+
645
+ ```typescript
646
+ import variant from "@componentor/quickjs-wasmfs-release-sync"
647
+ import { newQuickJSWASMModuleFromVariant } from "quickjs-emscripten-core"
648
+
649
+ const QuickJS = await newQuickJSWASMModuleFromVariant(variant)
650
+
651
+ // Mount OPFS at /opfs
652
+ await QuickJS.getWasmModule().mountOPFS("/opfs")
653
+
654
+ // Filesystem operations inside QuickJS now access /opfs/* directly
655
+ // without crossing the JS↔Wasm boundary
656
+ const vm = QuickJS.newContext()
657
+ vm.evalCode(`
658
+ const fs = require('fs')
659
+ fs.writeFileSync('/opfs/hello.txt', 'Hello from Wasm!')
660
+ const content = fs.readFileSync('/opfs/hello.txt', 'utf-8')
661
+ console.log(content)
662
+ `)
663
+ ```
664
+
665
+ #### File Watching for HMR
666
+
667
+ WasmFS includes a polling-based directory watcher for Hot Module Replacement:
668
+
669
+ ```typescript
670
+ const wasm = QuickJS.getWasmModule()
671
+
672
+ // Watch directory for changes
673
+ const stopWatching = wasm.watchDirectory(
674
+ "/opfs/src",
675
+ (changes) => {
676
+ for (const { path, type } of changes) {
677
+ console.log(`${type}: ${path}`)
678
+ }
679
+ },
680
+ 100, // poll every 100ms
681
+ )
682
+
683
+ // Stop watching when done
684
+ stopWatching()
685
+ ```
686
+
687
+ **Note:** WasmFS with OPFS is browser-only (OPFS is a browser API). For more details, see the [WasmFS variant documentation](./packages/variant-quickjs-wasmfs-release-sync/README.md) and [WasmFS Integration Guide](./WASMFS_INTEGRATION.md).
688
+
558
689
  ### Testing your code
559
690
 
560
691
  This library is complicated to use, so please consider automated testing your
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@componentor/quickjs-emscripten",
3
- "version": "0.31.22",
3
+ "version": "0.31.24",
4
4
  "sideEffects": false,
5
5
  "license": "MIT",
6
6
  "type": "commonjs",
@@ -44,29 +44,29 @@
44
44
  "./package.json": "./package.json"
45
45
  },
46
46
  "dependencies": {
47
- "@componentor/quickjs-wasmfs-release-sync": "0.31.22",
48
- "@componentor/quickjs-wasmfile-debug-asyncify": "0.31.22",
49
- "@componentor/quickjs-wasmfile-debug-sync": "0.31.22",
50
- "@componentor/quickjs-wasmfile-release-sync": "0.31.22",
51
- "@componentor/quickjs-wasmfile-release-asyncify": "0.31.22",
52
- "@componentor/quickjs-emscripten-core": "0.31.22"
47
+ "@componentor/quickjs-wasmfs-release-sync": "0.31.24",
48
+ "@componentor/quickjs-wasmfile-debug-sync": "0.31.24",
49
+ "@componentor/quickjs-wasmfile-debug-asyncify": "0.31.24",
50
+ "@componentor/quickjs-emscripten-core": "0.31.24",
51
+ "@componentor/quickjs-wasmfile-release-sync": "0.31.24",
52
+ "@componentor/quickjs-wasmfile-release-asyncify": "0.31.24"
53
53
  },
54
54
  "devDependencies": {
55
- "@componentor/quickjs-ng-wasmfile-debug-sync": "0.31.22",
56
- "@componentor/quickjs-asmjs-mjs-release-sync": "0.31.22",
57
- "@componentor/quickjs-ng-wasmfile-debug-asyncify": "0.31.22",
58
- "@componentor/quickjs-ng-wasmfile-release-sync": "0.31.22",
59
- "@componentor/quickjs-ng-wasmfile-release-asyncify": "0.31.22",
60
- "@componentor/quickjs-singlefile-cjs-debug-asyncify": "0.31.22",
61
- "@componentor/quickjs-singlefile-cjs-debug-sync": "0.31.22",
62
- "@componentor/quickjs-singlefile-cjs-release-sync": "0.31.22",
63
- "@componentor/quickjs-singlefile-cjs-release-asyncify": "0.31.22",
64
- "@componentor/quickjs-ffi-types": "0.31.22",
65
- "@componentor/quickjs-singlefile-mjs-debug-sync": "0.31.22",
66
- "@componentor/quickjs-singlefile-mjs-debug-asyncify": "0.31.22",
67
- "@jitl/tsconfig": "0.31.22",
68
- "@componentor/quickjs-singlefile-mjs-release-asyncify": "0.31.22",
69
- "@componentor/quickjs-singlefile-mjs-release-sync": "0.31.22"
55
+ "@componentor/quickjs-ffi-types": "0.31.24",
56
+ "@componentor/quickjs-ng-wasmfile-debug-asyncify": "0.31.24",
57
+ "@componentor/quickjs-ng-wasmfile-release-sync": "0.31.24",
58
+ "@componentor/quickjs-singlefile-cjs-debug-asyncify": "0.31.24",
59
+ "@componentor/quickjs-singlefile-cjs-debug-sync": "0.31.24",
60
+ "@componentor/quickjs-singlefile-cjs-release-asyncify": "0.31.24",
61
+ "@componentor/quickjs-ng-wasmfile-release-asyncify": "0.31.24",
62
+ "@componentor/quickjs-singlefile-cjs-release-sync": "0.31.24",
63
+ "@componentor/quickjs-asmjs-mjs-release-sync": "0.31.24",
64
+ "@componentor/quickjs-singlefile-mjs-release-asyncify": "0.31.24",
65
+ "@componentor/quickjs-singlefile-mjs-debug-asyncify": "0.31.24",
66
+ "@componentor/quickjs-ng-wasmfile-debug-sync": "0.31.24",
67
+ "@jitl/tsconfig": "0.31.24",
68
+ "@componentor/quickjs-singlefile-mjs-debug-sync": "0.31.24",
69
+ "@componentor/quickjs-singlefile-mjs-release-sync": "0.31.24"
70
70
  },
71
71
  "engines": {
72
72
  "node": ">=16.0.0"