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 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
- - webp
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: 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
- const cachedResponse = await cache.match(new Request(url.toString(), request));
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) => (res.ok ? res.arrayBuffer() : null))
65
- .catch((e) => null);
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': 'image/webp',
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(request, response.clone()));
110
+ ctx.waitUntil(cache.put(cacheKey, response.clone()));
82
111
  return response;
83
112
  };
84
113
 
@@ -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
@@ -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,GAMd,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,QAAQ,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AAVlE,QAAA,aAAa,iBAUqD","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}: {\n image: BufferSource;\n width?: number;\n height?: number;\n quality?: number;\n}) => libImage.then(({ optimize }) => optimize(image, width, height, quality));\n"]}
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"]}