@ecopages/image-processor 0.2.0-beta.9 → 0.2.0-rc.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 +22 -3
- package/package.json +20 -13
- package/src/bun-plugins.js +48 -29
- package/src/component/html.js +12 -6
- package/src/component/jsx.d.ts +12 -0
- package/src/component/jsx.js +18 -0
- package/src/component/react.js +17 -10
- package/src/constants.js +5 -4
- package/src/image-plugins.js +48 -29
- package/src/image-processor.js +147 -135
- package/src/image-renderer.js +222 -220
- package/src/image-runtime-state.d.ts +20 -0
- package/src/image-runtime-state.js +59 -0
- package/src/image-types.d.ts +3 -0
- package/src/image-utils.js +109 -98
- package/src/index.js +3 -3
- package/src/plugin.d.ts +30 -10
- package/src/plugin.js +315 -271
- package/src/types.js +1 -0
- package/src/utils.js +24 -25
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@ It provides automatic image processing (e.g. converting and compressing to WebP)
|
|
|
9
9
|
- **Automatic Image Optimization**: Converts and compresses images to modern formats at build time.
|
|
10
10
|
- **Responsive Image Generation**: Creates multiple variants for different screen sizes.
|
|
11
11
|
- **Virtual Module Integration**: Type-safe imports through `ecopages:images`.
|
|
12
|
-
- **Ecopages Components**: Ready-to-use HTML
|
|
12
|
+
- **Ecopages Components**: Ready-to-use HTML, Ecopages JSX, and React (`EcoImage`) components.
|
|
13
13
|
- **Multiple Layout Options**: Fixed, constrained, and full-width layouts built-in.
|
|
14
14
|
|
|
15
15
|
## Installation
|
|
@@ -68,11 +68,22 @@ import { heroImage, profilePicture } from 'ecopages:images';
|
|
|
68
68
|
> **No manual dependencies required.**
|
|
69
69
|
> Ecopages automatically detects these virtual module imports and processes them during the build, enabling effective tree-shaking for only the required images.
|
|
70
70
|
|
|
71
|
+
## TypeScript Setup
|
|
72
|
+
|
|
73
|
+
Add one import to the app `modules.d.ts`:
|
|
74
|
+
|
|
75
|
+
```typescript
|
|
76
|
+
import '@ecopages/image-processor/types';
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
That declares `ecopages:images`. Named exports are generated at dev/build time into
|
|
80
|
+
`node_modules/@types/ecopages-image-processor`, which TypeScript loads automatically.
|
|
81
|
+
|
|
71
82
|
### Components
|
|
72
83
|
|
|
73
|
-
The plugin provides ready-to-use components for HTML (
|
|
84
|
+
The plugin provides ready-to-use components for string HTML (KitaJS), Ecopages JSX, and React.
|
|
74
85
|
|
|
75
|
-
**HTML Component
|
|
86
|
+
**HTML Component** (returns a markup string; use as a function, or in string-based JSX runtimes like KitaJS):
|
|
76
87
|
|
|
77
88
|
```typescript
|
|
78
89
|
import { EcoImage } from '@ecopages/image-processor/component/html';
|
|
@@ -85,6 +96,14 @@ EcoImage({
|
|
|
85
96
|
});
|
|
86
97
|
```
|
|
87
98
|
|
|
99
|
+
**Ecopages JSX Component:**
|
|
100
|
+
|
|
101
|
+
```jsx
|
|
102
|
+
import { EcoImage } from '@ecopages/image-processor/component/jsx';
|
|
103
|
+
|
|
104
|
+
<EcoImage {...heroImage} alt="Hero banner" layout="constrained" priority />;
|
|
105
|
+
```
|
|
106
|
+
|
|
88
107
|
**React Component:**
|
|
89
108
|
|
|
90
109
|
```jsx
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ecopages/image-processor",
|
|
3
|
-
"version": "0.2.0-
|
|
3
|
+
"version": "0.2.0-rc.1",
|
|
4
4
|
"description": "Image processor, transform and optimize images for web",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"image",
|
|
@@ -15,14 +15,20 @@
|
|
|
15
15
|
"directory": "packages/processors/image-processor"
|
|
16
16
|
},
|
|
17
17
|
"peerDependencies": {
|
|
18
|
-
"@ecopages/core": "0.2.0-
|
|
18
|
+
"@ecopages/core": "0.2.0-rc.1",
|
|
19
|
+
"@ecopages/jsx": "^0.3.0-rc.2"
|
|
20
|
+
},
|
|
21
|
+
"peerDependenciesMeta": {
|
|
22
|
+
"@ecopages/jsx": {
|
|
23
|
+
"optional": true
|
|
24
|
+
}
|
|
19
25
|
},
|
|
20
26
|
"dependencies": {
|
|
21
|
-
"@ecopages/file-system": "0.2.0-
|
|
27
|
+
"@ecopages/file-system": "0.2.0-rc.1",
|
|
22
28
|
"@ecopages/logger": "^0.2.3",
|
|
23
29
|
"react": "^19.2.6",
|
|
24
30
|
"react-dom": "^19.2.6",
|
|
25
|
-
"sharp": "^0.
|
|
31
|
+
"sharp": "^0.35.3"
|
|
26
32
|
},
|
|
27
33
|
"exports": {
|
|
28
34
|
".": {
|
|
@@ -30,34 +36,35 @@
|
|
|
30
36
|
"types": "./src/index.d.ts"
|
|
31
37
|
},
|
|
32
38
|
"./types": {
|
|
33
|
-
"types": "./src/types.d.ts"
|
|
39
|
+
"types": "./src/image-types.d.ts"
|
|
34
40
|
},
|
|
35
41
|
"./component/html": {
|
|
36
42
|
"default": "./src/component/html.js",
|
|
37
43
|
"types": "./src/component/html.d.ts"
|
|
38
44
|
},
|
|
45
|
+
"./component/jsx": {
|
|
46
|
+
"default": "./src/component/jsx.js",
|
|
47
|
+
"types": "./src/component/jsx.d.ts"
|
|
48
|
+
},
|
|
39
49
|
"./component/react": {
|
|
40
50
|
"default": "./src/component/react.js",
|
|
41
51
|
"types": "./src/component/react.d.ts"
|
|
42
52
|
},
|
|
43
53
|
"./types.ts": {
|
|
44
|
-
"types": "./src/types.d.ts"
|
|
54
|
+
"types": "./src/image-types.d.ts"
|
|
45
55
|
},
|
|
46
56
|
"./component/html.ts": {
|
|
47
57
|
"default": "./src/component/html.js",
|
|
48
58
|
"types": "./src/component/html.d.ts"
|
|
49
59
|
},
|
|
60
|
+
"./component/jsx.ts": {
|
|
61
|
+
"default": "./src/component/jsx.js",
|
|
62
|
+
"types": "./src/component/jsx.d.ts"
|
|
63
|
+
},
|
|
50
64
|
"./component/react.ts": {
|
|
51
65
|
"default": "./src/component/react.js",
|
|
52
66
|
"types": "./src/component/react.d.ts"
|
|
53
67
|
}
|
|
54
68
|
},
|
|
55
|
-
"typesVersions": {
|
|
56
|
-
"*": {
|
|
57
|
-
"ecopages:images": [
|
|
58
|
-
"./virtual-module.d.ts"
|
|
59
|
-
]
|
|
60
|
-
}
|
|
61
|
-
},
|
|
62
69
|
"types": "./src/index.d.ts"
|
|
63
70
|
}
|
package/src/bun-plugins.js
CHANGED
|
@@ -1,33 +1,52 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* This file contains the plugins for bundling the image specifications.
|
|
3
|
+
* @module @ecopages/image-processor/bun-plugins
|
|
4
|
+
*/
|
|
5
|
+
import { anyCaseToCamelCase } from './utils.js';
|
|
6
|
+
/**
|
|
7
|
+
* This function creates the plugin result for the image specifications.
|
|
8
|
+
*/
|
|
2
9
|
function createPluginResult(exports) {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
10
|
+
return {
|
|
11
|
+
contents: `${Object.entries(exports)
|
|
12
|
+
.map(([key, value]) => `export const ${anyCaseToCamelCase(key)} = ${JSON.stringify(value)};`)
|
|
13
|
+
.join('\n')}`,
|
|
14
|
+
loader: 'ts',
|
|
15
|
+
};
|
|
7
16
|
}
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
17
|
+
/**
|
|
18
|
+
* This function creates a plugin for bundling the image specifications.
|
|
19
|
+
* https://bun.sh/docs/runtime/plugins#virtual-modules
|
|
20
|
+
* @param exports
|
|
21
|
+
* @returns
|
|
22
|
+
*/
|
|
23
|
+
export function createImagePlugin(exports) {
|
|
24
|
+
return {
|
|
25
|
+
name: 'ecopages:images',
|
|
26
|
+
setup(build) {
|
|
27
|
+
build.module('ecopages:images', () => createPluginResult(exports));
|
|
28
|
+
},
|
|
29
|
+
};
|
|
15
30
|
}
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
31
|
+
/**
|
|
32
|
+
* This function creates a plugin for bundling the image specifications.
|
|
33
|
+
* Due to some limitations in the bundler, we need to use a different approach.
|
|
34
|
+
* https://bun.sh/docs/runtime/plugins#virtual-modules > bun-v1.2.5
|
|
35
|
+
* (This feature is currently only available at runtime with Bun.plugin and not yet supported in the bundler, but you can mimic the behavior using onResolve and onLoad.)
|
|
36
|
+
* @param exports
|
|
37
|
+
* @returns
|
|
38
|
+
*/
|
|
39
|
+
export function createImagePluginBundler(exports) {
|
|
40
|
+
return {
|
|
41
|
+
name: 'ecopages:images',
|
|
42
|
+
setup(build) {
|
|
43
|
+
build.onResolve({ filter: /^ecopages:images$/ }, () => {
|
|
44
|
+
return {
|
|
45
|
+
namespace: 'ecopages-images',
|
|
46
|
+
path: 'ecopages:images',
|
|
47
|
+
};
|
|
48
|
+
});
|
|
49
|
+
build.onLoad({ filter: /.*/, namespace: 'ecopages-images' }, () => createPluginResult(exports));
|
|
50
|
+
},
|
|
51
|
+
};
|
|
29
52
|
}
|
|
30
|
-
export {
|
|
31
|
-
createImagePlugin,
|
|
32
|
-
createImagePluginBundler
|
|
33
|
-
};
|
package/src/component/html.js
CHANGED
|
@@ -1,7 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Image component that renders the image as a string.
|
|
3
|
+
* @module @ecopages/image-processor/component/html
|
|
4
|
+
*/
|
|
5
|
+
import { renderer } from '../image-renderer.js';
|
|
6
|
+
/**
|
|
7
|
+
* EcoImage
|
|
8
|
+
* This component generates the image element based on the provided props as a string
|
|
9
|
+
* @param props {@link EcoImageProps}
|
|
10
|
+
*/
|
|
11
|
+
export const EcoImage = (props) => {
|
|
12
|
+
return renderer.renderToString(props);
|
|
7
13
|
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Image component that renders as an Ecopages JSX element.
|
|
3
|
+
* @module @ecopages/image-processor/component/jsx
|
|
4
|
+
*/
|
|
5
|
+
import { type JsxRenderable } from '@ecopages/jsx';
|
|
6
|
+
import { type EcoImageProps } from '../image-renderer.js';
|
|
7
|
+
/**
|
|
8
|
+
* EcoImage
|
|
9
|
+
* This component generates the image element based on the provided props as JSX
|
|
10
|
+
* @param props {@link EcoImageProps}
|
|
11
|
+
*/
|
|
12
|
+
export declare const EcoImage: (props: EcoImageProps) => JsxRenderable;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Image component that renders as an Ecopages JSX element.
|
|
3
|
+
* @module @ecopages/image-processor/component/jsx
|
|
4
|
+
*/
|
|
5
|
+
import { jsx } from '@ecopages/jsx';
|
|
6
|
+
import { renderer } from '../image-renderer.js';
|
|
7
|
+
/**
|
|
8
|
+
* EcoImage
|
|
9
|
+
* This component generates the image element based on the provided props as JSX
|
|
10
|
+
* @param props {@link EcoImageProps}
|
|
11
|
+
*/
|
|
12
|
+
export const EcoImage = (props) => {
|
|
13
|
+
const attributes = renderer.generateAttributes(props);
|
|
14
|
+
if (!attributes) {
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
return jsx('img', attributes);
|
|
18
|
+
};
|
package/src/component/react.js
CHANGED
|
@@ -1,11 +1,18 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Image component that renders the image as a string.
|
|
3
|
+
* @module @ecopages/image-processor/component/react
|
|
4
|
+
*/
|
|
5
|
+
import { createElement } from 'react';
|
|
6
|
+
import { renderer } from '../image-renderer.js';
|
|
7
|
+
/**
|
|
8
|
+
* EcoImage
|
|
9
|
+
* This component generates the image element based on the provided props as JSX
|
|
10
|
+
* @param props {@link EcoImageProps}
|
|
11
|
+
* @returns
|
|
12
|
+
*/
|
|
13
|
+
export const EcoImage = (props) => {
|
|
14
|
+
return createElement('img', {
|
|
15
|
+
...renderer.generateAttributesJsx(props),
|
|
16
|
+
suppressHydrationWarning: true,
|
|
17
|
+
});
|
|
11
18
|
};
|
package/src/constants.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Default image layout
|
|
3
|
+
* @constant "constrained"
|
|
4
|
+
*/
|
|
5
|
+
export const DEFAULT_LAYOUT = 'constrained';
|
package/src/image-plugins.js
CHANGED
|
@@ -1,33 +1,52 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* This file contains the plugins for bundling the image specifications.
|
|
3
|
+
* @module @ecopages/image-processor/image-plugins
|
|
4
|
+
*/
|
|
5
|
+
import { anyCaseToCamelCase } from './utils.js';
|
|
6
|
+
/**
|
|
7
|
+
* This function creates the plugin result for the image specifications.
|
|
8
|
+
*/
|
|
2
9
|
function createPluginResult(exports) {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
10
|
+
return {
|
|
11
|
+
contents: `${Object.entries(exports)
|
|
12
|
+
.map(([key, value]) => `export const ${anyCaseToCamelCase(key)} = ${JSON.stringify(value)};`)
|
|
13
|
+
.join('\n')}`,
|
|
14
|
+
loader: 'ts',
|
|
15
|
+
};
|
|
7
16
|
}
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
17
|
+
/**
|
|
18
|
+
* This function creates a plugin for bundling the image specifications.
|
|
19
|
+
* https://bun.sh/docs/runtime/plugins#virtual-modules
|
|
20
|
+
* @param exports
|
|
21
|
+
* @returns
|
|
22
|
+
*/
|
|
23
|
+
export function createImagePlugin(exports) {
|
|
24
|
+
return {
|
|
25
|
+
name: 'ecopages:images',
|
|
26
|
+
setup(build) {
|
|
27
|
+
build.module('ecopages:images', () => createPluginResult(exports));
|
|
28
|
+
},
|
|
29
|
+
};
|
|
15
30
|
}
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
31
|
+
/**
|
|
32
|
+
* This function creates a plugin for bundling the image specifications.
|
|
33
|
+
* Due to some limitations in the bundler, we need to use a different approach.
|
|
34
|
+
* https://bun.sh/docs/runtime/plugins#virtual-modules > bun-v1.2.5
|
|
35
|
+
* (This feature is currently only available at runtime with Bun.plugin and not yet supported in the bundler, but you can mimic the behavior using onResolve and onLoad.)
|
|
36
|
+
* @param exports
|
|
37
|
+
* @returns
|
|
38
|
+
*/
|
|
39
|
+
export function createImagePluginBundler(exports) {
|
|
40
|
+
return {
|
|
41
|
+
name: 'ecopages:images',
|
|
42
|
+
setup(build) {
|
|
43
|
+
build.onResolve({ filter: /^ecopages:images$/ }, () => {
|
|
44
|
+
return {
|
|
45
|
+
namespace: 'ecopages-images',
|
|
46
|
+
path: 'ecopages:images',
|
|
47
|
+
};
|
|
48
|
+
});
|
|
49
|
+
build.onLoad({ filter: /.*/, namespace: 'ecopages-images' }, () => createPluginResult(exports));
|
|
50
|
+
},
|
|
51
|
+
};
|
|
29
52
|
}
|
|
30
|
-
export {
|
|
31
|
-
createImagePlugin,
|
|
32
|
-
createImagePluginBundler
|
|
33
|
-
};
|