sane-wasm 0.5.0 → 0.6.1

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.
package/README.md CHANGED
@@ -6,31 +6,31 @@ It supports USB scanners on browser environments through the [WebUSB API](https:
6
6
 
7
7
  This works by compiling all SANE backends (and required dependencies) to WebAssembly using Emscripten. The other key piece is @RReverser's bridge from libusb to WebUSB ([article](https://web.dev/articles/porting-libusb-to-webusb)/[article](https://web.dev/articles/porting-gphoto2-to-the-web)/[code](https://github.com/libusb/libusb/pull/1057)/[code](https://github.com/libusb/libusb/pull/1339)) for direct USB access.
8
8
 
9
- Right now, it includes [all backends](http://www.sane-project.org/lists/sane-backends-cvs.html) that have support for at least one USB device ([genesys is not included due to issues](https://github.com/goncalomb/sane-wasm/issues/3)). No [external backends](http://www.sane-project.org/lists/sane-backends-external.html) are included at the moment.
9
+ Right now, it includes [all backends](http://www.sane-project.org/lists/sane-backends-cvs.html) that have support for at least one USB device. No [external backends](http://www.sane-project.org/lists/sane-backends-external.html) are included at the moment.
10
10
 
11
11
  ## WebScan
12
12
 
13
- **Check [webscan.goncalomb.com](https://webscan.goncalomb.com/) for a demo of sane-wasm.** This is a React application that uses sane-wasm for document/image scanning directly in the browser. It exposes all scanning options to the user for full control.
13
+ **Check [webscan.goncalomb.com](https://webscan.goncalomb.com/) ([source](https://github.com/goncalomb/webscan)) for a demo of sane-wasm.** This is a React application that uses sane-wasm for document/image scanning directly in the browser. It exposes all scanning options for full control.
14
14
 
15
15
  ## Usage
16
16
 
17
17
  The pre-compiled WebAssembly package for sane-wasm is published on NPM:
18
18
 
19
- https://www.npmjs.com/package/sane-wasm?activeTab=code
19
+ <https://www.npmjs.com/package/sane-wasm>
20
20
 
21
- ### For Web Environments (e.g. Webpack)
21
+ ### For Web environments (e.g. Webpack, Vite, etc.)
22
22
 
23
- ```
24
- npm install -D sane-wasm
23
+ ```bash
24
+ npm install sane-wasm
25
25
  ```
26
26
 
27
- The main .js will not be bundled with your application. A loader ([lib/loader.js](https://github.com/goncalomb/sane-wasm/blob/master/lib/loader.js)) is provided to automatically load the .js/.wasm files from a CDN ([jsdelivr.com](https://www.jsdelivr.com/)). You can configure the loader to serve the files from your server if you want.
27
+ Cross-origin isolation ([COOP+COEP](https://web.dev/articles/coop-coep)) is required for [multithreading](https://emscripten.org/docs/porting/pthreads.html) which uses Web Workers and SharedArrayBuffer. This is not optional.
28
28
 
29
29
  See [examples/webpack/](https://github.com/goncalomb/sane-wasm/tree/master/examples/webpack) for a working example.
30
30
 
31
31
  ### For Node.js
32
32
 
33
- ```
33
+ ```bash
34
34
  npm install sane-wasm usb
35
35
  ```
36
36
 
@@ -38,58 +38,37 @@ The usb package ([node-usb](https://github.com/node-usb/node-usb)) is required t
38
38
 
39
39
  See [examples/node/](https://github.com/goncalomb/sane-wasm/tree/master/examples/node) for a working example.
40
40
 
41
- ### As Git Submodule (not recommended) / Custom Build
42
-
43
- As an alternative, you can add sane-wasm as a [submodule](https://git-scm.com/book/en/v2/Git-Tools-Submodules) to your application and integrate `./build.sh` with your build process. This is not recommended as it relies on some magical/dubious code on `./build.sh` to make the build work.
44
-
45
- You can also just build sane-wasm independently and use the build artifacts...
46
-
47
- ```
48
- <script src="build/libsane.js"></script>
49
- <script>
50
- window.LibSANE().then(lib => {
51
- // your code
52
- console.log(lib.sane_init());
53
- });
54
- </script>
55
- ```
56
-
57
- ```
58
- const { libsane } = require('./sane-wasm');
59
- libsane().then(lib => {
60
- console.log(lib.sane_init());
61
- });
62
- ```
63
-
64
- ```
65
- import { libsane } from './sane-wasm';
66
- const lib = await libsane();
67
- console.log(lib.sane_init());
68
- ```
69
-
70
41
  ## Building
71
42
 
72
- ### SANE Only
43
+ A pre-configured Docker image is used for building and debugging. Most `npm run ...` commands use Docker.
73
44
 
74
- Building requires [emscripten](https://github.com/emscripten-core/emscripten) and all the required tools to build the dependencies.
45
+ ### Build SANE and test page
75
46
 
76
- The preferred way is just to use the pre-configured Docker image:
47
+ ```bash
48
+ git clone https://github.com/goncalomb/sane-wasm.git
49
+ cd sane-wasm
50
+ npm run debug
51
+ ```
77
52
 
78
- git clone --recurse-submodules https://github.com/goncalomb/sane-wasm.git
79
- cd sane-wasm
80
- ./build.sh --with-docker --clean
53
+ Check the test page at: <http://localhost:6931/libsane.html>.
81
54
 
82
- Start the test server with:
55
+ ### Other commands
83
56
 
84
- ./build.sh --with-docker --no-build --emrun
57
+ ```bash
58
+ npm run clean # clean build artifacts and dependencies
59
+ npm run build # run full clean build (SANE + TypeScript)
60
+ npm run debug # run debug build (SANE only) and start the test server
61
+ npm run emrun # start the test server
62
+ npm run test # run the tests
63
+ ```
85
64
 
86
- Check the test page at: http://localhost:6931/libsane.html.
65
+ ### Non-Docker builds and `build.sh`
87
66
 
88
- #### build.sh
67
+ Building without Docker is possible but untested. It requires [Emscripten](https://emscripten.org/) and all the tools to build the dependencies, see [Dockerfile](https://github.com/goncalomb/sane-wasm/blob/master/Dockerfile).
89
68
 
90
- The `./build.sh` script has other options for debugging:
69
+ The `./build.sh` script controls the build and has other options for debugging:
91
70
 
92
- ```
71
+ ```text
93
72
  usage: build.sh [options]
94
73
  --with-docker run with docker (preferred)
95
74
  --clean clean 'deps' and 'build' directories
@@ -99,13 +78,11 @@ usage: build.sh [options]
99
78
  --shell run debug shell (depends on --with-docker)
100
79
  ```
101
80
 
102
- ### Full Build (SANE + TypeScript)
103
-
104
- To do a full build use `npm run build`.
105
-
106
81
  ## API
107
82
 
108
- Most of the SANE API is exposed as-is. Check the [SANE Standard](https://sane-project.gitlab.io/standard/index.html).
83
+ API documentation is available at: [https://goncalomb.github.io/sane-wasm/](https://goncalomb.github.io/sane-wasm/modules.html).
84
+
85
+ Most of the SANE API is exposed as-is, check the [SANE Standard](https://sane-project.gitlab.io/standard/index.html).
109
86
 
110
87
  Some safeguards are in place to avoid API misuse and prevent memory leaks. It's important to understand the SANE API and follow the [Code Flow](https://sane-project.gitlab.io/standard/api.html#code-flow) to avoid issues.
111
88
 
@@ -113,11 +90,23 @@ Some safeguards are in place to avoid API misuse and prevent memory leaks. It's
113
90
 
114
91
  The most important difference with the underlying SANE API is that **device handles are not exposed**. This means that `sane_open()` does not return a device handle. A single handle is managed by the internal code. This effectively means that **only one device can be accessed at a time**. This was a design decision made to simplify the API and prevent other issues.
115
92
 
116
- > Personally, I believe that this is an acceptable change, especially for WebAssembly where it may be easier to lose track of opened resources and crash the application. The SANE API is also somewhat unforgiving and building more safeguards around it (especially with multiple handles) is not worth the effort. Ultimately I don't see a use that requires more than one device open at a time. -goncalomb
93
+ Other differences include:
94
+
95
+ - function arguments and return values are adapted for javascript (see docs)
96
+ - extra sane-wasm constants: `SANE_WASM_COMMIT`, `SANE_WASM_VERSION`, and `SANE_WASM_BACKENDS`
97
+ - values of type `SANE_Fixed` are automatically converted to/from `Number`
98
+ - extra `sane_get_state()` function exclusive to sane-wasm
99
+ - `sane_control_option()` is split into 3 separate functions:
100
+ - `sane_control_option_get_value()`
101
+ - `sane_control_option_set_value()`
102
+ - `sane_control_option_set_auto()`
103
+ - `sane_set_io_mode()` is not available on sane-wasm
104
+ - `sane_get_select_fd()` is no available on sane-wasm
117
105
 
118
- ### Documentation
106
+ ### Extra TypeScript classes (utilities)
119
107
 
120
- Check API documentation at: [goncalomb.github.io/sane-wasm/modules.html](https://goncalomb.github.io/sane-wasm/modules.html).
108
+ - [src/options.ts](https://github.com/goncalomb/sane-wasm/blob/master/src/options.ts) to manage scanner options
109
+ - [src/readers.ts](https://github.com/goncalomb/sane-wasm/blob/master/src/readers.ts) for image acquisition and decoding
121
110
 
122
111
  ## License
123
112
 
@@ -60,8 +60,35 @@
60
60
  <h2>Scan Result</h2>
61
61
  <canvas></canvas>
62
62
  </main>
63
- <script async type="text/javascript" src="libsane.js"></script>
64
63
  <script>
64
+ function reloadWithDebug(on = true) {
65
+ location.hash = on ? JSON.stringify({
66
+ debugSANE: true,
67
+ debugUSB: true,
68
+ debugFunctionCalls: true,
69
+ debugTestDevices: 5,
70
+ }) : "";
71
+ location.reload();
72
+ }
73
+ const Module = LibSANE = {
74
+ sane: JSON.parse(decodeURIComponent(location.hash.substring(1)) || null) || {
75
+ debugFunctionCalls: true,
76
+ debugTestDevices: 3,
77
+ },
78
+ };
79
+ console.log("sane = ", Module.sane);
80
+ Module._promiseOnRuntimeInitialized = new Promise((resolve) => {
81
+ Module.onRuntimeInitialized = () => resolve(Module);
82
+ });
83
+ // the SCRIPT placeholder initializes the Module object
84
+ </script>
85
+
86
+ <script type="module">
87
+ import initModule from "./libsane.js";
88
+ initModule(Module);
89
+ </script>
90
+
91
+ <script type="module">
65
92
  (function() {
66
93
  // util function to build the dom
67
94
  const tree = (data, parent = document.createDocumentFragment()) => {
@@ -301,29 +328,9 @@
301
328
  }
302
329
  }
303
330
 
304
- // reload with debug
305
- function reloadWithDebug() {
306
- const sane = {
307
- debugSANE: true,
308
- debugUSB: true,
309
- debugFunctionCalls: true,
310
- debugTestDevices: 5,
311
- };
312
- location.hash = JSON.stringify(sane);
313
- location.reload();
314
- }
315
-
316
331
  // initialization
317
332
  window.addEventListener("load", () => {
318
- const sane = JSON.parse(decodeURIComponent(location.hash.substring(1)) || null) || {
319
- debugFunctionCalls: true,
320
- debugTestDevices: 3,
321
- };
322
- console.log("sane = ", sane);
323
- window.LibSANE({ sane }).then(LibSANE => {
324
- // publish module to window
325
- window.LibSANE = LibSANE;
326
- // initialize
333
+ Module._promiseOnRuntimeInitialized.then(LibSANE => {
327
334
  const saneControls = document.querySelector("#sane-controls");
328
335
  saneControls.innerHTML = "";
329
336
  saneControls.append(tree([