wasm-image-optimization 0.0.9 → 0.1.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 +39 -10
- package/dist/cjs/index.d.ts +2 -1
- package/dist/cjs/index.js +1 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/esm/libImage.js +1 -1
- package/dist/esm/libImage.wasm +0 -0
- package/dist/workers/index.d.ts +2 -1
- package/dist/workers/index.js +1 -1
- package/dist/workers/index.js.map +1 -1
- package/dist/workers/libImage.js +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
|
|
12
12
|
```ts
|
|
13
13
|
// quality: 1-100
|
|
14
|
-
optimizeImage({image: ArrayBuffer, width?: number, height?:number,quality?: number}): Promise<ArrayBuffer>
|
|
14
|
+
optimizeImage({image: ArrayBuffer, width?: number, height?:number,quality?: number,format?: "png" | "jpeg" | "webp"}): Promise<ArrayBuffer>
|
|
15
15
|
```
|
|
16
16
|
|
|
17
17
|
- source format
|
|
@@ -21,7 +21,9 @@ optimizeImage({image: ArrayBuffer, width?: number, height?:number,quality?: numb
|
|
|
21
21
|
- svg
|
|
22
22
|
- avif
|
|
23
23
|
- output format
|
|
24
|
-
-
|
|
24
|
+
- jpeg
|
|
25
|
+
- png
|
|
26
|
+
- webp(default)
|
|
25
27
|
|
|
26
28
|
# usage
|
|
27
29
|
|
|
@@ -29,7 +31,6 @@ Next.js image optimization with Cloudflare
|
|
|
29
31
|
|
|
30
32
|
```ts
|
|
31
33
|
import { optimizeImage } from 'wasm-image-optimization';
|
|
32
|
-
export interface Env {}
|
|
33
34
|
|
|
34
35
|
const isValidUrl = (url: string) => {
|
|
35
36
|
try {
|
|
@@ -42,17 +43,28 @@ const isValidUrl = (url: string) => {
|
|
|
42
43
|
|
|
43
44
|
const handleRequest = async (
|
|
44
45
|
request: Request,
|
|
45
|
-
_env:
|
|
46
|
+
_env: {},
|
|
46
47
|
ctx: ExecutionContext
|
|
47
48
|
): Promise<Response> => {
|
|
49
|
+
const accept = request.headers.get('accept');
|
|
50
|
+
const isWebp =
|
|
51
|
+
accept
|
|
52
|
+
?.split(',')
|
|
53
|
+
.map((format) => format.trim())
|
|
54
|
+
.some((format) => ['image/webp', '*/*', 'image/*'].includes(format)) ?? true;
|
|
55
|
+
|
|
48
56
|
const url = new URL(request.url);
|
|
57
|
+
|
|
49
58
|
const params = url.searchParams;
|
|
50
59
|
const imageUrl = params.get('url');
|
|
51
60
|
if (!imageUrl || !isValidUrl(imageUrl)) {
|
|
52
61
|
return new Response('url is required', { status: 400 });
|
|
53
62
|
}
|
|
63
|
+
|
|
54
64
|
const cache = caches.default;
|
|
55
|
-
|
|
65
|
+
url.searchParams.append('webp', isWebp.toString());
|
|
66
|
+
const cacheKey = new Request(url.toString());
|
|
67
|
+
const cachedResponse = await cache.match(cacheKey);
|
|
56
68
|
if (cachedResponse) {
|
|
57
69
|
return cachedResponse;
|
|
58
70
|
}
|
|
@@ -60,25 +72,42 @@ const handleRequest = async (
|
|
|
60
72
|
const width = params.get('w');
|
|
61
73
|
const quality = params.get('q');
|
|
62
74
|
|
|
63
|
-
const srcImage = await fetch(imageUrl, { cf: { cacheKey: imageUrl } })
|
|
64
|
-
.then((res) =>
|
|
65
|
-
|
|
75
|
+
const [srcImage, contentType] = await fetch(imageUrl, { cf: { cacheKey: imageUrl } })
|
|
76
|
+
.then(async (res) =>
|
|
77
|
+
res.ok ? ([await res.arrayBuffer(), res.headers.get('content-type')] as const) : []
|
|
78
|
+
)
|
|
79
|
+
.catch(() => []);
|
|
66
80
|
|
|
67
81
|
if (!srcImage) {
|
|
68
82
|
return new Response('image not found', { status: 404 });
|
|
69
83
|
}
|
|
84
|
+
|
|
85
|
+
if (contentType && ['image/svg+xml', 'image/gif'].includes(contentType)) {
|
|
86
|
+
const response = new Response(srcImage, {
|
|
87
|
+
headers: {
|
|
88
|
+
'Content-Type': contentType,
|
|
89
|
+
'Cache-Control': 'public, max-age=31536000, immutable',
|
|
90
|
+
},
|
|
91
|
+
});
|
|
92
|
+
ctx.waitUntil(cache.put(cacheKey, response.clone()));
|
|
93
|
+
return response;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const format = isWebp ? 'webp' : contentType === 'image/jpeg' ? 'jpeg' : 'png';
|
|
70
97
|
const image = await optimizeImage({
|
|
71
98
|
image: srcImage,
|
|
72
99
|
width: width ? parseInt(width) : undefined,
|
|
73
100
|
quality: quality ? parseInt(quality) : undefined,
|
|
101
|
+
format,
|
|
74
102
|
});
|
|
75
103
|
const response = new Response(image, {
|
|
76
104
|
headers: {
|
|
77
|
-
'Content-Type':
|
|
105
|
+
'Content-Type': `image/${format}`,
|
|
78
106
|
'Cache-Control': 'public, max-age=31536000, immutable',
|
|
107
|
+
date: new Date().toUTCString(),
|
|
79
108
|
},
|
|
80
109
|
});
|
|
81
|
-
ctx.waitUntil(cache.put(
|
|
110
|
+
ctx.waitUntil(cache.put(cacheKey, response.clone()));
|
|
82
111
|
return response;
|
|
83
112
|
};
|
|
84
113
|
|
package/dist/cjs/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
export declare const optimizeImage: ({ image, width, height, quality, }: {
|
|
1
|
+
export declare const optimizeImage: ({ image, width, height, quality, format, }: {
|
|
2
2
|
image: BufferSource;
|
|
3
3
|
width?: number | undefined;
|
|
4
4
|
height?: number | undefined;
|
|
5
5
|
quality?: number | undefined;
|
|
6
|
+
format?: "jpeg" | "png" | "webp" | undefined;
|
|
6
7
|
}) => Promise<Uint8Array | null>;
|
package/dist/cjs/index.js
CHANGED
|
@@ -10,6 +10,6 @@ const fs_1 = __importDefault(require("fs"));
|
|
|
10
10
|
const libImage = (0, libImage_1.default)({
|
|
11
11
|
wasmBinary: fs_1.default.readFileSync(path_1.default.resolve(__dirname, '../esm/libImage.wasm')),
|
|
12
12
|
});
|
|
13
|
-
const optimizeImage = async ({ image, width = 0, height = 0, quality = 100, }) => libImage.then(({ optimize }) => optimize(image, width, height, quality));
|
|
13
|
+
const optimizeImage = async ({ image, width = 0, height = 0, quality = 100, format = 'webp', }) => libImage.then(({ optimize }) => optimize(image, width, height, quality, format));
|
|
14
14
|
exports.optimizeImage = optimizeImage;
|
|
15
15
|
//# sourceMappingURL=index.js.map
|
package/dist/cjs/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cjs/index.ts"],"names":[],"mappings":";;;;;;AAAA,mEAA2C;AAC3C,gDAAwB;AACxB,4CAAoB;AAEpB,MAAM,QAAQ,GAAG,IAAA,kBAAQ,EAAC;IACxB,UAAU,EAAE,YAAE,CAAC,YAAY,CAAC,cAAI,CAAC,OAAO,CAAC,SAAS,EAAE,sBAAsB,CAAC,CAAC;CAC7E,CAAC,CAAC;AAEI,MAAM,aAAa,GAAG,KAAK,EAAE,EAClC,KAAK,EACL,KAAK,GAAG,CAAC,EACT,MAAM,GAAG,CAAC,EACV,OAAO,GAAG,GAAG,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cjs/index.ts"],"names":[],"mappings":";;;;;;AAAA,mEAA2C;AAC3C,gDAAwB;AACxB,4CAAoB;AAEpB,MAAM,QAAQ,GAAG,IAAA,kBAAQ,EAAC;IACxB,UAAU,EAAE,YAAE,CAAC,YAAY,CAAC,cAAI,CAAC,OAAO,CAAC,SAAS,EAAE,sBAAsB,CAAC,CAAC;CAC7E,CAAC,CAAC;AAEI,MAAM,aAAa,GAAG,KAAK,EAAE,EAClC,KAAK,EACL,KAAK,GAAG,CAAC,EACT,MAAM,GAAG,CAAC,EACV,OAAO,GAAG,GAAG,EACb,MAAM,GAAG,MAAM,GAOhB,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,QAAQ,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC;AAZ1E,QAAA,aAAa,iBAY6D","sourcesContent":["import LibImage from '../workers/libImage';\nimport path from 'path';\nimport fs from 'fs';\n\nconst libImage = LibImage({\n wasmBinary: fs.readFileSync(path.resolve(__dirname, '../esm/libImage.wasm')),\n});\n\nexport const optimizeImage = async ({\n image,\n width = 0,\n height = 0,\n quality = 100,\n format = 'webp',\n}: {\n image: BufferSource;\n width?: number;\n height?: number;\n quality?: number;\n format?: 'jpeg' | 'png' | 'webp';\n}) => libImage.then(({ optimize }) => optimize(image, width, height, quality, format));\n"]}
|