Skip to content
This repository was archived by the owner on Jul 26, 2025. It is now read-only.

refactor: migrate to ESM-only #485

Merged
merged 2 commits into from
Jun 16, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/nodejs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ on:

jobs:
nodejs:
# Documentation: https://github.com/zakodium/workflows#nodejs-ci
uses: zakodium/workflows/.github/workflows/nodejs.yml@nodejs-v1
with:
lint-check-types: true
2 changes: 1 addition & 1 deletion .ncurc.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
reject:
# Package is now ESM-only
# Package is now asynchronous
- 'image-type'
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
CHANGELOG.md
36 changes: 21 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,32 @@
<h3 align="center">
<a href="https://www.zakodium.com">
<img src="https://www.zakodium.com/brand/zakodium-logo-white.svg" width="50" alt="Zakodium logo" />
</a>
<p>
Maintained by <a href="https://www.zakodium.com">Zakodium</a>
</p>
</h3>

# image-js

[![NPM version][npm-image]][npm-url]
[![build status][ci-image]][ci-url]
[![Test coverage][codecov-image]][codecov-url]
[![npm download][download-image]][download-url]
[![NPM version](https://img.shields.io/npm/v/image-js.svg)](https://www.npmjs.com/package/image-js)
[![npm download](https://img.shields.io/npm/dm/image-js.svg)](https://www.npmjs.com/package/image-js)
[![test coverage](https://img.shields.io/codecov/c/github/image-js-typescript/image-js-typescript.svg)](https://codecov.io/gh/image-js/image-js-typescript)
[![license](https://img.shields.io/npm/l/image-js.svg)](https://github.com/image-js/image-js-typescript/blob/main/LICENSE)

Image processing and manipulation in JavaScript.

## Installation

`$ npm i image-js`
```console
npm install image-js
```

## API

## [API](https://image-js.github.io/image-js-typescript/)
### [Complete API documentation](https://image-js.github.io/image-js-typescript/)

### [Usage docs and guides](https://image-js-docs.pages.dev/docs/Getting%20started)

## Development

Expand All @@ -20,12 +35,3 @@ See [Development documentation](./Development.md).
## License

[MIT](./LICENSE)

[npm-image]: https://img.shields.io/npm/v/image-js.svg
[npm-url]: https://www.npmjs.com/package/image-js
[ci-image]: https://github.com/image-js/image-js-typescript/actions/workflows/nodejs.yml/badge.svg
[ci-url]: https://github.com/image-js/image-js-typescript/actions/workflows/nodejs.yml
[codecov-image]: https://img.shields.io/codecov/c/github/image-js/image-js-typescript.svg
[codecov-url]: https://codecov.io/gh/image-js/image-js-typescript
[download-image]: https://img.shields.io/npm/dm/image-js.svg
[download-url]: https://www.npmjs.com/package/image-js
2 changes: 1 addition & 1 deletion api-extractor.json
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@
* SUPPORTED TOKENS: <projectFolder>, <packageName>, <unscopedPackageName>
* DEFAULT VALUE: "<projectFolder>/tsconfig.json"
*/
"tsconfigFilePath": "<projectFolder>/tsconfig.esm.json"
"tsconfigFilePath": "<projectFolder>/tsconfig.build.json"
/**
* Provides a compiler configuration that will be used instead of reading the tsconfig.json file from disk.
* The object must conform to the TypeScript tsconfig schema:
Expand Down
Empty file removed demo/.eslintrc.yml
Empty file.
2 changes: 1 addition & 1 deletion demo/components/CameraSelector.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useCameraContext } from '../contexts/cameraContext.js';

export default function CameraSelector() {

Check warning on line 3 in demo/components/CameraSelector.tsx

View workflow job for this annotation

GitHub Actions / nodejs / lint-eslint

Missing JSDoc comment
const [{ cameras, selectedCamera }, dispatch] = useCameraContext();
if (cameras.length === 0) return null;
return (
Expand All @@ -14,7 +14,7 @@
<select
id="camera"
name="camera"
className="block w-full py-2 pl-3 pr-10 mt-1 text-base border-gray-300 rounded-md focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"
className="block w-full py-2 pl-3 pr-10 mt-1 text-base border border-gray-300 rounded-md focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"
value={selectedCamera?.device.label}
onChange={(event) => {
const device = cameras.find(
Expand Down
1 change: 1 addition & 0 deletions demo/components/CameraSnapshotButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,14 @@
canvasInputRef: RefObject<HTMLCanvasElement | null>;
}

export default function CameraSnapshotButton(props: CameraSnapshotButtonProps) {

Check warning on line 12 in demo/components/CameraSnapshotButton.tsx

View workflow job for this annotation

GitHub Actions / nodejs / lint-eslint

Missing JSDoc comment
const { setSnapshotUrl, snapshotImageRef, canvasInputRef } = props;
function handleClick() {
if (canvasInputRef.current) {
const url = canvasInputRef.current.toDataURL();
const image = readCanvas(canvasInputRef.current);
setSnapshotUrl(url);
// eslint-disable-next-line react-hooks/react-compiler
snapshotImageRef.current = image;
}
}
Expand Down
3 changes: 2 additions & 1 deletion demo/components/CameraTransform.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
snapshotImageRef: RefObject<Image | null>;
}

export default function CameraTransform(props: CameraTransformProps) {

Check warning on line 24 in demo/components/CameraTransform.tsx

View workflow job for this annotation

GitHub Actions / nodejs / lint-eslint

Missing JSDoc comment
const { canvasInputRef, transform, snapshotUrl, snapshotImageRef } = props;
const [{ selectedCamera }] = useCameraContext();
const videoRef = useRef<HTMLVideoElement>(null);
Expand All @@ -31,7 +31,7 @@
transformRef.current = transform;
useEffect(() => {
// Reset error if transform is changed.
setError('');

Check warning on line 34 in demo/components/CameraTransform.tsx

View workflow job for this annotation

GitHub Actions / nodejs / lint-eslint

Avoid chaining state changes. When possible, update all relevant state simultaneously
}, [transform]);
useEffect(() => {
if (!selectedCamera || error) return;
Expand All @@ -45,6 +45,7 @@
const canvasInput = canvasInputRef.current as HTMLCanvasElement;
const canvasOutput = canvasOutputRef.current as HTMLCanvasElement;
if (!canvasInput || !canvasOutput) return;
// eslint-disable-next-line react-hooks/react-compiler
canvasInput.height = video.videoHeight;
canvasInput.width = video.videoWidth;
const inputContext = canvasInput.getContext(
Expand All @@ -63,7 +64,7 @@
}
writeCanvas(result, canvasOutput);
} catch (error_) {
setError(error_.stack);
setError((error_ as Error).stack as string);
console.error(error_);
}
nextFrameRequest = requestAnimationFrame(nextFrame);
Expand Down
4 changes: 2 additions & 2 deletions demo/components/Home.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@
import type { TransformFunction } from './CameraTransform.js';
import CameraTransform from './CameraTransform.js';
import Container from './Container.js';
import { testGetFastKeypoints } from './testFunctions/testGetFastKeypoints.js';
import { testCannyEdge } from './testFunctions/testCannyEdge.js';

const testTransform: TransformFunction = testGetFastKeypoints;
const testTransform: TransformFunction = testCannyEdge;

export default function Home() {

Check warning on line 14 in demo/components/Home.tsx

View workflow job for this annotation

GitHub Actions / nodejs / lint-eslint

Missing JSDoc comment
const snapshotImageRef = useRef<Image>(null);
const canvasInputRef = useRef<HTMLCanvasElement>(null);
const [snapshotUrl, setSnapshotUrl] = useState('');
Expand Down
6 changes: 3 additions & 3 deletions demo/index.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
@import 'tailwindcss';

@plugin '@tailwindcss/forms';
2 changes: 0 additions & 2 deletions demo/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import { createRoot } from 'react-dom/client';

import './index.css';

import App from './components/App.js';

const root = createRoot(document.querySelector('#root') as HTMLElement);
Expand Down
14 changes: 10 additions & 4 deletions eslint.config.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,22 @@
import { defineConfig, globalIgnores } from 'eslint/config';
import react from 'eslint-config-cheminfo-react/base';
import typescript from 'eslint-config-cheminfo-typescript';

export default [
...typescript,
...react,
export default defineConfig(
globalIgnores(['coverage', 'dist-types', 'lib']),
typescript,
{
rules: {
'@typescript-eslint/restrict-template-expressions': 'off',
},
},
{
files: ['demo/**'],
extends: [react],
rules: { 'no-console': 'off' },
},
];
{
files: ['scripts/**'],
rules: { 'no-console': 'off' },
},
);
3 changes: 2 additions & 1 deletion index.html
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
<!DOCTYPE html>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>image-js demo app</title>
<link rel="stylesheet" href="/demo/index.css" />
</head>
<body>
<div id="root"></div>
Expand Down
109 changes: 52 additions & 57 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,100 +1,95 @@
{
"name": "image-js",
"version": "0.0.0",
"license": "MIT",
"description": "Image processing and manipulation in JavaScript",
"author": "Michaël Zasso",
"keywords": [],
"type": "module",
"author": "Michaël Zasso",
"license": "MIT",
"files": [
"src",
"dist-types",
"lib",
"lib-cjs",
"dist-types"
"src"
],
"main": "./lib-cjs/index.js",
"module": "./lib/index.js",
"browser": {
"lib/save/write.js": "./lib/save/write.browser.js",
"lib/load/read.js": "./lib/load/read.browser.js"
},
"exports": "./lib/index.js",
"scripts": {
"api-extractor": "rimraf dist-types && api-extractor run --local",
"check-types": "tsc --noEmit",
"clean": "rimraf lib lib-cjs",
"clean": "rimraf coverage lib",
"demo": "vite --open",
"eslint": "eslint src demo --cache",
"eslint-fix": "npm run eslint -- --fix",
"eslint": "eslint . --cache",
"eslint-fix": "eslint . --cache --fix",
"prepack": "npm run tsc && npm run api-extractor",
"prettier": "prettier --check src demo",
"prettier-write": "prettier --write src demo",
"test": "npm run check-types && npm run test-only && npm run eslint && npm run prettier",
"prettier": "prettier --check .",
"prettier-write": "prettier --write .",
"test": "npm run test-only && npm run check-types && npm run eslint && npm run prettier",
"test-only": "cross-env JEST_IMAGE_SNAPSHOT_TRACK_OBSOLETE=1 vitest run --coverage",
"tsc": "npm run clean && npm run tsc-cjs && npm run tsc-esm",
"tsc-cjs": "tsc --project tsconfig.cjs.json && echo '{\"type\":\"commonjs\"}' > lib-cjs/package.json",
"tsc-esm": "tsc --project tsconfig.esm.json"
},
"repository": {
"type": "git",
"url": "git+https://github.com/image-js/image-js.git"
},
"bugs": {
"url": "https://github.com/image-js/image-js/issues"
"tsc": "npm run clean && npm run tsc-build",
"tsc-build": "tsc --project tsconfig.build.json"
},
"homepage": "https://github.com/image-js/image-js#readme",
"dependencies": {
"bresenham-zingl": "^0.2.0",
"colord": "^2.9.3",
"fast-bmp": "^2.0.1",
"fast-jpeg": "^2.0.1",
"fast-png": "^6.2.0",
"fast-bmp": "^4.0.0",
"fast-jpeg": "^3.0.0",
"fast-png": "^7.0.0",
"image-type": "^4.1.0",
"jpeg-js": "^0.4.4",
"js-priority-queue": "^0.1.5",
"median-quickselect": "^1.0.1",
"ml-affine-transform": "^1.0.3",
"ml-convolution": "^2.0.0",
"ml-matrix": "^6.12.0",
"ml-matrix": "^6.12.1",
"ml-ransac": "^1.0.0",
"ml-regression-multivariate-linear": "^2.0.4",
"ml-regression-polynomial-2d": "^1.0.0",
"ml-spectra-processing": "^14.9.1",
"ml-spectra-processing": "^14.12.0",
"robust-point-in-polygon": "^1.0.3",
"ssim.js": "^3.5.0",
"tiff": "^6.1.1",
"ts-pattern": "^5.6.1"
"tiff": "^7.0.0",
"ts-pattern": "^5.7.1"
},
"devDependencies": {
"@microsoft/api-extractor": "^7.49.1",
"@microsoft/api-extractor": "^7.52.8",
"@tailwindcss/forms": "^0.5.10",
"@tailwindcss/vite": "^4.1.10",
"@types/jest-image-snapshot": "^6.4.0",
"@types/js-priority-queue": "^0.0.9",
"@types/node": "^22.10.7",
"@types/react": "^19.0.7",
"@types/react-dom": "^19.0.3",
"@types/node": "^24.0.1",
"@types/react": "^19.1.8",
"@types/react-dom": "^19.1.6",
"@types/robust-point-in-polygon": "^1.0.4",
"@vitejs/plugin-react": "^4.3.4",
"@vitest/coverage-v8": "^2.1.8",
"@vitest/expect": "^2.1.8",
"autoprefixer": "^10.4.20",
"@vitejs/plugin-react": "^4.5.2",
"@vitest/coverage-v8": "^3.2.3",
"@vitest/expect": "^3.2.3",
"@zakodium/tsconfig": "^1.0.1",
"autoprefixer": "^10.4.21",
"clsx": "^2.1.1",
"cross-env": "^7.0.3",
"eslint": "^9.18.0",
"eslint-config-cheminfo-react": "^15.0.0",
"eslint-config-cheminfo-typescript": "^17.0.0",
"eslint": "^9.29.0",
"eslint-config-cheminfo-react": "^16.1.0",
"eslint-config-cheminfo-typescript": "^18.0.1",
"immer": "^10.1.1",
"jest-image-snapshot": "^6.4.0",
"jest-image-snapshot": "^6.5.1",
"jest-matcher-deep-close-to": "^3.0.2",
"postcss": "^8.5.1",
"prettier": "^3.4.2",
"react": "^19.0.0",
"react-dom": "^19.0.0",
"react-router-dom": "^7.1.3",
"postcss": "^8.5.5",
"prettier": "^3.5.3",
"react": "^19.1.0",
"react-dom": "^19.1.0",
"react-router-dom": "^7.6.2",
"rimraf": "^6.0.1",
"tailwindcss": "^3.4.17",
"typescript": "~5.7.3",
"tailwindcss": "^4.1.10",
"typescript": "~5.8.3",
"uint8-base64": "^1.0.0",
"vite": "^6.0.8",
"vitest": "^2.1.8"
}
"vite": "^6.3.5",
"vitest": "^3.2.3"
},
"repository": {
"type": "git",
"url": "git+https://github.com/image-js/image-js.git"
},
"bugs": {
"url": "https://github.com/image-js/image-js/issues"
},
"homepage": "https://github.com/image-js/image-js#readme"
}
6 changes: 0 additions & 6 deletions postcss.config.js

This file was deleted.

Loading
Loading