barcode-detector
Advanced tools
Comparing version 1.0.4 to 2.0.0
120
package.json
{ | ||
"name": "barcode-detector", | ||
"version": "1.0.4", | ||
"author": { | ||
"name": "Niklas Gruhn", | ||
"email": "niklas@gruhn.me" | ||
}, | ||
"license": "MIT", | ||
"repository": "github:gruhn/barcode-detector", | ||
"bugs": "https://github.com/gruhn/barcode-detector/issues", | ||
"description": "", | ||
"source": "src/BarcodeDetector.ts", | ||
"main": "dist/barcode-detector.js", | ||
"description": "A Barcode Detection API polyfill that uses ZXing webassembly under the hood", | ||
"private": false, | ||
"version": "2.0.0", | ||
"type": "module", | ||
"files": [ | ||
"./dist" | ||
], | ||
"main": "./dist/cjs/index.js", | ||
"module": "./dist/es/index.js", | ||
"exports": { | ||
".": { | ||
"types": "./dist/BarcodeDetector.d.ts", | ||
"import": "./dist/barcode-detector.mjs", | ||
"require": "./dist/barcode-detector.js" | ||
"import": "./dist/es/index.js", | ||
"require": "./dist/cjs/index.js", | ||
"default": "./dist/es/index.js" | ||
}, | ||
"./pure": { | ||
"import": "./dist/es/pure.js", | ||
"require": "./dist/cjs/pure.js", | ||
"default": "./dist/es/pure.js" | ||
}, | ||
"./side-effects": { | ||
"import": "./dist/es/side-effects.js", | ||
"require": "./dist/cjs/side-effects.js", | ||
"default": "./dist/es/side-effects.js" | ||
} | ||
}, | ||
"types": "dist/BarcodeDetector.d.ts", | ||
"module": "dist/barcode-detector.mjs", | ||
"unpkg": "dist/barcode-detector.umd.js", | ||
"amdName": "BarcodeDetectorPolyfill", | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/Sec-ant/barcode-detector" | ||
}, | ||
"homepage": "https://github.com/Sec-ant/barcode-detector", | ||
"bugs": { | ||
"url": "https://github.com/Sec-ant/barcode-detector/issues", | ||
"email": "zzwu@zju.edu.cn" | ||
}, | ||
"keywords": [ | ||
"es6", | ||
"qrcode", | ||
"barcode", | ||
"barcode-detector", | ||
"wasm", | ||
"polyfill", | ||
"zxing", | ||
"esmodule", | ||
"webassembly" | ||
], | ||
"author": { | ||
"name": "Ze-Zheng Wu" | ||
}, | ||
"license": "MIT", | ||
"config": { | ||
"port": "18080" | ||
}, | ||
"scripts": { | ||
"build": "microbundle", | ||
"dev": "microbundle watch" | ||
"lint": "eslint . --ext .ts", | ||
"type-check": "tsc --noEmit --emitDeclarationOnly false", | ||
"format": "prettier . --write", | ||
"prebuild": "npm run lint && npm run type-check && npm run format", | ||
"build:es": "vite build", | ||
"build:cjs": "node ./scripts/build-cjs.js", | ||
"build:iife": "node ./scripts/build-iife.js", | ||
"build": "npm run build:es && npm run build:cjs && npm run build:iife", | ||
"postbuild:es": "tsc --declarationDir ./dist/es", | ||
"postbuild:cjs": "tsc --declarationDir ./dist/cjs", | ||
"start": "vite preview --outDir ./tests --port $npm_package_config_port -l silent", | ||
"pretest": "node ./scripts/list-dir.js", | ||
"pretest:ui": "node ./scripts/list-dir.js", | ||
"precoverage": "node ./scripts/list-dir.js", | ||
"test": "start-server-and-test $npm_package_config_port 'vitest --coverage'", | ||
"test:ui": "start-server-and-test $npm_package_config_port 'vitest --ui --coverage'", | ||
"coverage": "start-server-and-test $npm_package_config_port 'vitest run --coverage'", | ||
"prepublishOnly": "npm run build", | ||
"ncu": "npx npm-check-updates -u", | ||
"postncu": "npm i" | ||
}, | ||
"dependencies": { | ||
"@zxing/library": "^0.18.4", | ||
"jsqr": "^1.3.1" | ||
}, | ||
"devDependencies": { | ||
"microbundle": "^0.13.3", | ||
"semantic-release": "^17.4.3" | ||
"@typescript-eslint/eslint-plugin": "^6.4.1", | ||
"@typescript-eslint/parser": "^6.4.1", | ||
"@vitest/browser": "^0.34.3", | ||
"@vitest/coverage-istanbul": "^0.34.3", | ||
"@vitest/ui": "^0.34.3", | ||
"eslint": "^8.48.0", | ||
"http-server": "^14.1.1", | ||
"npm-check-updates": "^16.13.1", | ||
"playwright": "^1.37.1", | ||
"prettier": "^3.0.2", | ||
"rimraf": "^5.0.1", | ||
"start-server-and-test": "^2.0.0", | ||
"typescript": "^5.2.2", | ||
"vite": "^4.4.9", | ||
"vitest": "^0.34.3" | ||
}, | ||
"files": [ | ||
"dist", | ||
"example_codes", | ||
"src", | ||
"!src/worker/node_modules" | ||
] | ||
"dependencies": { | ||
"@sec-ant/zxing-wasm": "^2.1.3", | ||
"@types/dom-webcodecs": "^0.1.8" | ||
} | ||
} |
308
README.md
@@ -1,77 +0,265 @@ | ||
# :construction: WIP: BarcodeDetector Polyfill :construction: | ||
Spec compliant polyfill of the [Barcode Detection API](https://wicg.github.io/shape-detection-api/#barcode-detection-api). | ||
It can be used for barcode/QR-code recognition in images from various kinds of | ||
sources including `<canvas>`, `<img>`, `<image>` (inside SVGs), `<video>`, `File`, `Blob`, `ImageData`, `ImageBitmap`, `OffscreenCanvas`. | ||
# barcode-detector | ||
[simple demo](https://gruhn.github.io/barcode-detector/index.html) | ||
[![npm](https://img.shields.io/npm/v/barcode-detector)](https://www.npmjs.com/package/barcode-detector/v/latest) [![npm bundle size (scoped)](https://img.shields.io/bundlephobia/minzip/%40sec-ant/barcode-detector)](https://www.npmjs.com/package/barcode-detector/v/latest) [![jsDelivr hits (npm scoped)](https://img.shields.io/jsdelivr/npm/hm/%40sec-ant%2Fbarcode-detector?color=%23ff5627)](https://cdn.jsdelivr.net/npm/barcode-detector@latest/) | ||
Design goals: | ||
* spec compliance | ||
* support as many barcode formats as possible | ||
* detect multiple codes in one image | ||
* provide position/coordinate information of detected codes | ||
* sufficient performance to process live video streams | ||
A [Barcode Detection API](https://wicg.github.io/shape-detection-api/#barcode-detection-api) polyfill that uses [ZXing webassembly](https://github.com/Sec-ant/zxing-wasm) under the hood. | ||
## Installation | ||
> This package was originally published as [`@sec-ant/barcode-detector`](https://www.npmjs.com/package/@sec-ant/barcode-detector) on the npm registry. With appreciation for the generous offer from [@gruhn](https://github.com/gruhn), the package is now released under the name `barcode-detector` starting from version 2.0.0. The original name `@sec-ant/barcode-detector` will continue to be used for versions prior to 2.0.0, and will be retained solely for maintenance purposes. Eventually, it will be deprecated at an appropriate juncture. | ||
```sh | ||
npm install barcode-detector | ||
## Install | ||
To install, run the following command: | ||
```bash | ||
npm i barcode-detector | ||
``` | ||
```js | ||
import BarcodeDetector from "barcode-detector" | ||
// polyfill unless already supported | ||
if (!("BarcodeDetector" in window)) { | ||
window.BarcodeDetector = BarcodeDetector | ||
} | ||
## Recommended Usage with Node + ESM | ||
This package can be imported in three different ways: | ||
### Pure Module | ||
```ts | ||
import { BarcodeDetector } from "barcode-detector/pure"; | ||
``` | ||
## Usage | ||
To avoid potential namespace collisions, you can also rename the export: | ||
```js | ||
// pick barcode formats. Other formats will be ignored | ||
const barcodeDetector = new BarcodeDetector({ formats: ["qr_code"] }) | ||
```ts | ||
import { BarcodeDetector as BarcodeDetectorPolyfill } from "barcode-detector/pure"; | ||
``` | ||
// directly pass an image element, video element, ... | ||
const barcodes = await barcodeDetector.detect(someImageSource) | ||
This approach is beneficial when you want to use a package to detect barcodes without polluting `globalThis`, or when your runtime already provides an implementation of the Barcode Detection API, but you still want this package to function. | ||
// can detect multiple barcodes in one image | ||
const [ barcode1, barcode2, ...evenMoreBarcodes ] = barcodes | ||
### Side Effects | ||
// access encoded string | ||
const { rawValue } = barcode1 | ||
```ts | ||
import "barcode-detector/side-effects"; | ||
``` | ||
For in-depth documentation checkout the [corresponding MDN page](https://developer.mozilla.org/en-US/docs/Web/API/Barcode_Detection_API). | ||
This approach is beneficial when you need a drop-in polyfill. If there's already an implementation of Barcode Detection API on `globalThis`, this won't take effect (type declarations will, as we cannot optionally declare types). In such cases, please use the [pure module](#pure-module) instead. | ||
### Supported Formats | ||
### Both | ||
`src/BarcodeDetectorJsqr.ts`: | ||
- :x: `aztec` | ||
- :x: `code_128` | ||
- :x: `code_39` | ||
- :x: `code_93` | ||
- :x: `codabar` | ||
- :x: `data_matrix` | ||
- :x: `ean_13` | ||
- :x: `ean_8` | ||
- :x: `itf` | ||
- :x: `pdf417` | ||
- :heavy_check_mark: `qr_code` | ||
- :x: `upc_a` | ||
- :x: `upc_e` | ||
```ts | ||
import { BarcodeDetector } from "barcode-detector"; | ||
``` | ||
`src/BarcodeDetectorZXing.ts` (not exposed at the moment. See [#1](https://github.com/gruhn/barcode-detector-polyfill/issues/1)): | ||
- :heavy_check_mark: `aztec` | ||
- :heavy_check_mark: `code_128` | ||
- :heavy_check_mark: `code_39` | ||
- :x: `code_93` | ||
- :x: `codabar` | ||
- :heavy_check_mark: `data_matrix` | ||
- :heavy_check_mark: `ean_13` | ||
- :heavy_check_mark: `ean_8` | ||
- :heavy_check_mark: `itf` | ||
- :heavy_check_mark: `pdf417` | ||
- :heavy_check_mark: `qr_code` | ||
- :x: `upc_a` | ||
- :x: `upc_e` | ||
This approach combines the [pure module](#pure-module) and [side effects](#side-effects). | ||
## Recommended Usage in Modern Browsers | ||
For [modern browsers that support ES modules](https://caniuse.com/es6-module), this package can be imported via the `<script type="module">` tags: | ||
1. Include side effects: | ||
```html | ||
<!-- register --> | ||
<script | ||
type="module" | ||
src="https://cdn.jsdelivr.net/npm/barcode-detector@2/dist/es/side-effects.min.js" | ||
></script> | ||
<!-- use --> | ||
<script type="module"> | ||
const barcodeDetector = new BarcodeDetector(); | ||
</script> | ||
``` | ||
2. Script scoped access: | ||
```html | ||
<script type="module"> | ||
import { BarcodeDetector } from "https://cdn.jsdelivr.net/npm/barcode-detector@2/dist/es/pure.min.js"; | ||
const barcodeDetector = new BarcodeDetector(); | ||
</script> | ||
``` | ||
3. With import maps: | ||
```html | ||
<!-- import map --> | ||
<script type="importmap"> | ||
{ | ||
"imports": { | ||
"barcode-detector/pure": "https://cdn.jsdelivr.net/npm/barcode-detector@2/dist/es/pure.min.js" | ||
} | ||
} | ||
</script> | ||
<!-- script scoped access --> | ||
<script type="module"> | ||
import { BarcodeDetector } from "barcode-detector/pure"; | ||
const barcodeDetector = new BarcodeDetector(); | ||
</script> | ||
``` | ||
## Usage with Legacy Compatibility | ||
Starting from v1.2, this package supports IIFE and CJS build outputs for use cases that require legacy compatibility. | ||
### IIFE | ||
For legacy browsers that lack support for module type `<script>` tags, or for userscripts, IIFE is the preferred choice. Upon executing the IIFE script, a variable named `BarcodeDetectionAPI` will be registered in the global. | ||
```html | ||
<!-- | ||
IIFE pure.js registers: | ||
window.BarcodeDetectionAPI.BarcodeDetector | ||
window.BarcodeDetectionAPI.setZXingModuleOverrides | ||
--> | ||
<script src="https://cdn.jsdelivr.net/npm/barcode-detector@2/dist/iife/pure.min.js"></script> | ||
<!-- | ||
IIFE side-effects.js registers: | ||
window.BarcodeDetector | ||
window.BarcodeDetectionAPI.setZXingModuleOverrides | ||
--> | ||
<script src="https://cdn.jsdelivr.net/npm/barcode-detector@2/dist/iife/side-effects.min.js"></script> | ||
<!-- | ||
IIFE index.js registers: | ||
window.BarcodeDetector | ||
window.BarcodeDetectionAPI.BarcodeDetector | ||
window.BarcodeDetectionAPI.setZXingModuleOverrides | ||
--> | ||
<script src="https://cdn.jsdelivr.net/npm/barcode-detector@2/dist/iife/index.min.js"></script> | ||
``` | ||
### CJS | ||
This package can also be consumed as a commonjs package: | ||
1. Vanilla Javascript: | ||
```js | ||
// src/index.js | ||
const { BarcodeDetector } = require("barcode-detector/pure"); | ||
``` | ||
2. With Typescript: | ||
```ts | ||
// src/index.ts | ||
import { BarcodeDetector } from "barcode-detector/pure"; | ||
``` | ||
`tsconfig.json`: | ||
```json | ||
{ | ||
"compilerOptions": { | ||
"module": "CommonJS", | ||
"moduleResolution": "Node", | ||
"skipLibCheck": true | ||
}, | ||
"include": ["src"] | ||
} | ||
``` | ||
## `setZXingModuleOverrides` | ||
In addition to `BarcodeDetector`, this package exports another function called `setZXingModuleOverrides`. | ||
This package employs [Sec-ant/zxing-wasm](https://github.com/Sec-ant/zxing-wasm) to enable the core barcode reading functionality. As a result, a `.wasm` binary file is fetched at runtime. The default fetch path for this binary file is: | ||
``` | ||
https://cdn.jsdelivr.net/npm/@sec-ant/zxing-wasm@<version>/dist/reader/zxing_reader.wasm | ||
``` | ||
The `setZXingModuleOverrides` function allows you to govern where the `.wasm` binary is served from, thereby enabling offline use of the package, use within a local network, or within a site having strict [CSP](https://developer.mozilla.org/docs/Web/HTTP/Headers/Content-Security-Policy/script-src#unsafe_webassembly_execution) rules. | ||
For instance, should you want to inline this `.wasm` file in your build output for offline usage, with the assistance of build tools, you could try: | ||
```ts | ||
// src/index.ts | ||
import wasmFile from "../node_modules/@sec-ant/zxing-wasm/dist/reader/zxing_reader.wasm?url"; | ||
import { | ||
setZXingModuleOverrides, | ||
BarcodeDetector, | ||
} from "barcode-detector/pure"; | ||
setZXingModuleOverrides({ | ||
locateFile: (path, prefix) => { | ||
if (path.endsWith(".wasm")) { | ||
return wasmFile; | ||
} | ||
return prefix + path; | ||
}, | ||
}); | ||
const barcodeDetector = new BarcodeDetector(); | ||
// detect barcodes | ||
// ... | ||
``` | ||
Alternatively, the `.wasm` file could be copied to your dist folder to be served from your local server, without incorporating it into the output as an extensive base64 data URL. | ||
It's noteworthy that you'll always want to choose the correct version of the `.wasm` file, so the APIs exported by it are exactly what the js code expects. | ||
For more information on how to use this function, you can check [the notes here](https://github.com/Sec-ant/zxing-wasm#notes) and [discussions here](https://github.com/gruhn/vue-qrcode-reader/issues/354). | ||
This function is exported from all the subpaths, including the [side effects](#side-effects). | ||
## API | ||
Please check the [spec](https://wicg.github.io/shape-detection-api/#barcode-detection-api), [MDN doc](https://developer.mozilla.org/docs/Web/API/Barcode_Detection_API) and [Chromium implementation](https://github.com/chromium/chromium/tree/main/third_party/blink/renderer/modules/shapedetection) for more information. | ||
## Lifecycle Events | ||
The `BarcodeDetector` provided by this package also extends class `EventTarget` and provides 2 lifecycle events: `load` and `error`. You can use `addEventListener` and `removeEventListener` to register and remove callback hooks on these events. | ||
### `load` Event | ||
The `load` event, which is a `CustomEvent`, will be dispatched on the successful instanciation of ZXing wasm module. For advanced usage, the instanciated module is passed as the `detail` parameter. | ||
```ts | ||
import { BarcodeDetector } from "barcode-detector/pure"; | ||
const barcodeDetector = new BarcodeDetector(); | ||
barcodeDetector.addEventListener("load", ({ detail }) => { | ||
console.log(detail); // zxing wasm module | ||
}); | ||
``` | ||
### `error` Event | ||
The `error` event, which is a `CustomEvent`, will be dispatched if the instanciation of ZXing wasm module is failed. An error is passed as the `detail` parameter. | ||
```ts | ||
import { BarcodeDetector } from "barcode-detector/pure"; | ||
const barcodeDetector = new BarcodeDetector(); | ||
barcodeDetector.addEventListener("error", ({ detail }) => { | ||
console.log(detail); // an error | ||
}); | ||
``` | ||
## Example | ||
```ts | ||
import { BarcodeDetector } from "barcode-detector/pure"; | ||
const barcodeDetector: BarcodeDetector = new BarcodeDetector({ | ||
formats: ["qr_code"], | ||
}); | ||
const imageFile = await fetch( | ||
"https://api.qrserver.com/v1/create-qr-code/?size=150x150&data=Hello%20world!", | ||
).then((resp) => resp.blob()); | ||
barcodeDetector.detect(imageFile).then(console.log); | ||
``` | ||
## License | ||
The source code in this repository, as well as the build output, except for the parts listed below, is licensed under the [MIT license](./LICENSE). | ||
Test samples and resources are collected from [zxing-cpp/zxing-cpp](https://github.com/zxing-cpp/zxing-cpp), which is licensed under the [Apache-2.0 license](https://raw.githubusercontent.com/zxing-cpp/zxing-cpp/master/LICENSE), and [web-platform-tests/wpt](https://github.com/web-platform-tests/wpt), which is licensed under the [3-Clause BSD license](https://raw.githubusercontent.com/web-platform-tests/wpt/master/LICENSE.md). | ||
This package has an indirect dependency on [Sec-ant/zxing-wasm-build](https://github.com/Sec-ant/zxing-wasm-build), which is licensed under the [Apache-2.0 license](https://raw.githubusercontent.com/Sec-ant/zxing-wasm-build/main/LICENSE). |
Sorry, the diff of this file is not supported yet
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 1 instance in 1 package
Deprecated
MaintenanceThe maintainer of the package marked it as deprecated. This could indicate that a single version should not be used, or that the package is no longer maintained and any new vulnerabilities will not be fixed.
Found 1 instance in 1 package
No bug tracker
MaintenancePackage does not have a linked bug tracker in package.json.
Found 1 instance in 1 package
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
No website
QualityPackage does not have a website.
Found 1 instance in 1 package
2920
0
0
266
0
Yes
270054
15
23
22
+ Added@sec-ant/zxing-wasm@^2.1.3
+ Added@types/dom-webcodecs@^0.1.8
+ Added@sec-ant/zxing-wasm@2.2.0(transitive)
+ Added@types/dom-webcodecs@0.1.11(transitive)
+ Added@types/emscripten@1.39.13(transitive)
+ Addedjs-tokens@4.0.0(transitive)
+ Addedloose-envify@1.4.0(transitive)
+ Addedreact@18.3.1(transitive)
+ Addeduse-sync-external-store@1.2.0(transitive)
+ Addedzustand@4.5.4(transitive)
- Removed@zxing/library@^0.18.4
- Removedjsqr@^1.3.1
- Removed@zxing/library@0.18.6(transitive)
- Removed@zxing/text-encoding@0.9.0(transitive)
- Removedjsqr@1.4.0(transitive)
- Removedts-custom-error@3.3.1(transitive)