Skip to content

Commit 2a7a0e6

Browse files
committed
Make the URL/path of the WASM file configurable (fixes #23)
1 parent a13c7af commit 2a7a0e6

17 files changed

+117
-39
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ EM_VERSION = 3.1.44
1414
EM_OPTS = --rm -w /$(SRC) -v $$PWD:/$(SRC) emscripten/emsdk:$(EM_VERSION)
1515
EM_DOCKER = docker run -u $(shell id -u):$(shell id -g) $(EM_OPTS)
1616
EM_PODMAN = podman run $(EM_OPTS)
17-
EM_ENGINE = $(EM_DOCKER)
17+
EM_ENGINE = $(EM_PODMAN)
1818

1919
# See https://emscripten.org/docs/tools_reference/emcc.html
2020
EMCC = $(EM_ENGINE) emcc

README.md

Lines changed: 41 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ of the [ZBar Bar Code Reader](https://github.com/mchehab/zbar) written in C/C++.
2323
RGB/grayscale [`ArrayBuffer`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer) objects
2424
+ Outperforms pure JavaScript barcode scanners
2525

26-
:warning: zbar-wasm version 0.10 contains breaking changes with respect to version 0.9, please refer to section [Bundling/deploying zbar-wasm](#bundlingdeploying-zbar-wasm).
26+
:warning: zbar-wasm versions 0.10 and above contain breaking changes with respect to version 0.9, please refer to section [Bundling/deploying zbar-wasm](#bundlingdeploying-zbar-wasm).
2727

2828

2929
## Examples based on zbar-wasm
@@ -54,7 +54,7 @@ An example that scans a static image file:
5454
<pre id="result"></pre>
5555

5656
<script type="module">
57-
import * as zbarWasm from 'https://cdn.jsdelivr.net/npm/@undecaf/zbar-wasm@0.10.1/dist/index.js'
57+
import * as zbarWasm from 'https://cdn.jsdelivr.net/npm/@undecaf/zbar-wasm@0.11.0/dist/index.js'
5858
5959
(async () => {
6060
const
@@ -88,15 +88,15 @@ Almost identical to the snippet above, just replace the lines
8888
```html
8989
9090
<script type="module">
91-
import * as zbarWasm from 'https://cdn.jsdelivr.net/npm/@undecaf/zbar-wasm@0.10.1/dist/index.js'
91+
import * as zbarWasm from 'https://cdn.jsdelivr.net/npm/@undecaf/zbar-wasm@0.11.0/dist/index.js'
9292
9393
```
9494
9595
with
9696
9797
```html
9898
99-
<script src="https://cdn.jsdelivr.net/npm/@undecaf/zbar-wasm@0.10.1/dist/index.js"></script>
99+
<script src="https://cdn.jsdelivr.net/npm/@undecaf/zbar-wasm@0.11.0/dist/index.js"></script>
100100
<script>
101101
102102
```
@@ -107,9 +107,9 @@ with
107107
Installing:
108108
109109
```shell script
110-
$ npm install @undecaf/zbar-wasm@0.10.1
110+
$ npm install @undecaf/zbar-wasm@0.11.0
111111
or
112-
$ yarn add @undecaf/zbar-wasm@0.10.1
112+
$ yarn add @undecaf/zbar-wasm@0.11.0
113113
```
114114
115115
Using:
@@ -151,17 +151,16 @@ const { scanImageData } = require('@undecaf/zbar-wasm');
151151
152152
### Bundling/deploying zbar-wasm
153153
154-
zbar-wasm provides ESM and CommonJS modules for Node.js and browsers. One of them needs to be
155-
bundled in your application. In any case, barcode scanning is delegated to the WebAssembly code
156-
in file `zbar.wasm`. At runtime, this file can be provided in different ways depending on the
157-
bundling configuration and on which zbar-wasm module was emitted by the bundler:
154+
Barcode scanning is always delegated to the WebAssembly code in file `zbar.wasm`.
155+
zbar-wasm provides various functionally equivalent ESM and CommonJS modules for Node.js and for browsers
156+
that differ in how `zbar.wasm` is to be provided at runtime:
158157
159-
+ It can be loaded from a CDN by browsers.
160-
+ It can be bundled as an asset. That asset should be served to browsers as `application/wasm`
158+
+ `zbar.wasm` can be loaded from a CDN by browsers.
159+
+ `zbar.wasm` can be bundled as an asset. That asset should be served to browsers as `application/wasm`
161160
so that it can be compiled in parallel with being received.
162161
+ Several zbar-wasm modules contain `zbar.wasm` as inline data.
163162
164-
This overview shows which modules are available in zbar-wasm:
163+
The following overview shows the modules that are available in zbar-wasm. One of them needs to be bundled in your application.
165164
166165
| Path in package | Module type | Node core modules polyfilled<br>(suitable for browsers) | `zbar.wasm` inlined |
167166
|:--------------------------|:-----------:|:-------------------------------------------------------:|:-------------------:|
@@ -179,8 +178,8 @@ appropriate module by default in most cases. However, `zbar.wasm` as inline data
179178
[export condition](https://nodejs.org/docs/latest-v16.x/api/packages.html#conditional-exports) in the bundler configuration, typically `'zbar-inlined'`.
180179
Please refer to the `exports` section of `package.json` for details.
181180
182-
[Building zbar-wasm](#building-zbar-wasm-from-source) runs bundling tests with [Webpack](https://webpack.js.org/), [Rollup](https://rollupjs.org/) and
183-
[esbuild](https://esbuild.github.io/) and also tests the resulting bundles. The bundler configuration files
181+
[Building zbar-wasm](#building-zbar-wasm-from-source) includes testing the bundling process with [Webpack](https://webpack.js.org/), [Rollup](https://rollupjs.org/) and
182+
[esbuild](https://esbuild.github.io/) and also testing the resulting bundles. The bundler configuration files
184183
[`tests/{webpack,rollup,esbuild}.config.js`](https://github.com/undecaf/zbar-wasm/tree/master/tests)
185184
may be used as a reference of how to achieve a particular bundling result. Each of them covers
186185
the following combinations of platforms, module types and `zbar.wasm` provisioning for the
@@ -193,6 +192,33 @@ respective bundler:
193192
| inlined in module | ESM, CommonJS | ESM, plain `<script>` |
194193
195194
195+
### Loading `zbar.wasm` from a custom location
196+
197+
As a last resort, if you cannot make your bundler place `zbar.wasm` where it can be located by the script,
198+
you can specify an URL or path for that WASM file at runtime:
199+
200+
```javascript
201+
import { scanImageData, setModuleArgs } from '@undecaf/zbar-wasm';
202+
203+
// Call this function once at the beginning
204+
setModuleArgs({
205+
/**
206+
* This function must return the URL or path of the WASM file.
207+
*
208+
* @param filename default WASM filename ('zbar.wasm')
209+
* @param directory default WASM directory (URL or directory of the current script)
210+
* @returns {string} URL or path of the WASM file
211+
*/
212+
locateFile: (filename, directory) => {
213+
return 'file:///your/wasm/directory/zbar.wasm'
214+
}
215+
});
216+
217+
// Then use the scanner
218+
const symbols = await scanImageData(...);
219+
```
220+
221+
196222
## API documentation
197223
198224
Owing to the predecessor of this project, [samsam2310/zbar.wasm](https://github.com/samsam2310/zbar.wasm),

docs/example/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ <h5>Result</h5>
6363
</div>
6464
</div>
6565

66-
<script src="https://cdn.jsdelivr.net/npm/@undecaf/zbar-wasm@0.10.1/dist/index.js"></script>
66+
<script src="https://cdn.jsdelivr.net/npm/@undecaf/zbar-wasm@0.11.0/dist/index.js"></script>
6767
<script src="js/main.js"></script>
6868

6969
</body>

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@undecaf/zbar-wasm",
3-
"version": "0.10.1",
3+
"version": "0.11.0",
44
"description": "A WebAssembly build of the C/C++ ZBar barcode reader",
55
"type": "module",
66
"main": "./dist/main.mjs",

src/instance.ts

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,46 @@
11
import zbarJs from 'zbarJs'
22
import type ZBarInstance from './ZBarInstance'
33

4-
let zbarInstance: ZBarInstance
54

6-
const zbarInstancePromise = (async () => {
7-
zbarInstance = await zbarJs()
8-
if (!zbarInstance) {
9-
throw Error('WASM was not loaded')
5+
let zbarInstancePromise: Promise<ZBarInstance>
6+
7+
8+
/**
9+
* Arguments used for building a `ZBarInstance`
10+
*/
11+
export type ZBarModuleArgs = {
12+
locateFile?: (filename: string, directory: string) => string,
13+
}
14+
15+
16+
/**
17+
* Causes a new `ZBarInstance` built with the specified arguments
18+
* to be returned by subsequent `getInstance()` calls.
19+
*/
20+
export function setModuleArgs(args: ZBarModuleArgs = {}): void {
21+
zbarInstancePromise = (async function(): Promise<ZBarInstance> {
22+
const zbarInstance = await zbarJs(args)
23+
24+
if (zbarInstance) {
25+
return zbarInstance
26+
27+
} else {
28+
throw Error('WASM was not loaded')
29+
}
30+
})()
31+
}
32+
33+
34+
/**
35+
* Returns a `ZBarInstance` built with the arguments set by `setModuleArgs()`,
36+
* or built without any arguments.
37+
* Successive calls return the same instance until `setModuleArgs()` is called.
38+
*/
39+
export async function getInstance(): Promise<ZBarInstance> {
40+
// Instantiate the module without arguments if no args have been set explicitly
41+
if (!zbarInstancePromise) {
42+
setModuleArgs()
1043
}
11-
return zbarInstance
12-
})()
1344

14-
export const getInstance = async (): Promise<ZBarInstance> => {
1545
return await zbarInstancePromise
1646
}

tests/10-instance.test.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import { getInstance } from '../dist/main.cjs'
1+
import { getInstance, setModuleArgs } from '../dist/main.cjs'
2+
import type { ZBarModuleArgs} from '../dist/main.cjs';
23

34
export function testZBarInstance(inst) {
45
expect(inst).toBeDefined()
@@ -34,3 +35,13 @@ test('ZBarInstance created', async () => {
3435
const inst = await getInstance()
3536
testZBarInstance(inst)
3637
})
38+
39+
40+
test('ZBarInstance created from a custom WASM file', async () => {
41+
setModuleArgs({
42+
locateFile: () => './dist/zbar.wasm'
43+
})
44+
45+
const inst = await getInstance()
46+
testZBarInstance(inst)
47+
})

tests/20-instance-browser.test.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,13 @@ test('ZBarInstance created', async () => {
2929
const inst = await zbarWasm.getInstance()
3030
testZBarInstance(inst);
3131
});
32+
33+
34+
test('ZBarInstance created from a custom WASM file', async () => {
35+
zbarWasm.setModuleArgs({
36+
locateFile: () => '../dist/zbar.wasm'
37+
})
38+
39+
const inst = await zbarWasm.getInstance()
40+
testZBarInstance(inst)
41+
})

tests/esbuild.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ const
1919
} = namedBuildConfigs,
2020
ZBAR_WASM_PKG_NAME = '@undecaf/zbar-wasm',
2121
// For production, set
22-
// ZBAR_WASM_REPOSITORY = `https://cdn.jsdelivr.net/npm/${ZBAR_WASM_PKG_NAME}@0.10.1`,
22+
// ZBAR_WASM_REPOSITORY = `https://cdn.jsdelivr.net/npm/${ZBAR_WASM_PKG_NAME}@0.11.0`,
2323
ZBAR_WASM_REPOSITORY = `http://localhost:${repositoryPort}`,
2424
ZBAR_WASM = `node_modules/${ZBAR_WASM_PKG_NAME}/dist/zbar.wasm`;
2525

tests/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "zbar-wasm-test",
3-
"version": "0.10.1",
3+
"version": "0.11.0",
44
"type": "module",
55
"scripts": {
66
"prebuild:webpack": "rimraf build/*/webpack",
@@ -11,7 +11,7 @@
1111
"build:esbuild": "node esbuild.config.js"
1212
},
1313
"dependencies": {
14-
"@undecaf/zbar-wasm": "../undecaf-zbar-wasm-0.10.1.tgz",
14+
"@undecaf/zbar-wasm": "../undecaf-zbar-wasm-0.11.0.tgz",
1515
"canvas": "^2.11.2"
1616
},
1717
"devDependencies": {

0 commit comments

Comments
 (0)