wasm-image-optimization 1.0.2 → 1.0.4

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.
Files changed (2) hide show
  1. package/README.md +86 -49
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,5 +1,8 @@
1
1
  # wasm-image-optimization
2
2
 
3
+ - The 'avif' version is available here
4
+ https://www.npmjs.com/package/wasm-image-optimization-avif
5
+
3
6
  - Cloudflare workers
4
7
  `import { optimizeImage } from 'wasm-image-optimization';`
5
8
  - Next.js(Webpack)
@@ -31,8 +34,23 @@ optimizeImage({image: ArrayBuffer, width?: number, height?:number,quality?: numb
31
34
 
32
35
  ## Next.js image optimization with Cloudflare
33
36
 
37
+ ### Parameters
38
+
39
+ | Name | Type | Description |
40
+ | ---- | ------ | -------------------------- |
41
+ | url | string | Image URL |
42
+ | q | number | Quality |
43
+ | w | number | Width |
44
+ | type | string | Output type(webp/png/jpeg) |
45
+
46
+ https://xxx.yyy.workers.dev/?url=https://xxx.png&q=80&w=200
47
+
48
+ ### Source code
49
+
50
+ https://github.com/SoraKumo001/cloudflare-workers-image-optimization
51
+
34
52
  ```ts
35
- import { optimizeImage } from 'wasm-image-optimization';
53
+ import { optimizeImage } from "wasm-image-optimization";
36
54
 
37
55
  const isValidUrl = (url: string) => {
38
56
  try {
@@ -48,54 +66,64 @@ const handleRequest = async (
48
66
  _env: {},
49
67
  ctx: ExecutionContext
50
68
  ): Promise<Response> => {
51
- const accept = request.headers.get('accept');
69
+ const url = new URL(request.url);
70
+ const params = url.searchParams;
71
+ const type = ["webp", "png", "jpeg"].find((v) => v === params.get("type")) as
72
+ | "webp"
73
+ | "png"
74
+ | "jpeg"
75
+ | undefined;
76
+ const accept = request.headers.get("accept");
52
77
  const isWebp =
53
78
  accept
54
- ?.split(',')
79
+ ?.split(",")
55
80
  .map((format) => format.trim())
56
- .some((format) => ['image/webp', '*/*', 'image/*'].includes(format)) ?? true;
57
-
58
- const url = new URL(request.url);
81
+ .some((format) => ["image/webp", "*/*", "image/*"].includes(format)) ??
82
+ true;
59
83
 
60
- const params = url.searchParams;
61
- const imageUrl = params.get('url');
84
+ const imageUrl = params.get("url");
62
85
  if (!imageUrl || !isValidUrl(imageUrl)) {
63
- return new Response('url is required', { status: 400 });
86
+ return new Response("url is required", { status: 400 });
64
87
  }
65
88
 
66
89
  const cache = caches.default;
67
- url.searchParams.append('webp', isWebp.toString());
90
+ url.searchParams.append("webp", isWebp.toString());
68
91
  const cacheKey = new Request(url.toString());
69
92
  const cachedResponse = await cache.match(cacheKey);
70
93
  if (cachedResponse) {
71
94
  return cachedResponse;
72
95
  }
73
96
 
74
- const width = params.get('w');
75
- const quality = params.get('q');
97
+ const width = params.get("w");
98
+ const quality = params.get("q");
76
99
 
77
- const [srcImage, contentType] = await fetch(imageUrl, { cf: { cacheKey: imageUrl } })
100
+ const [srcImage, contentType] = await fetch(imageUrl, {
101
+ cf: { cacheKey: imageUrl },
102
+ })
78
103
  .then(async (res) =>
79
- res.ok ? ([await res.arrayBuffer(), res.headers.get('content-type')] as const) : []
104
+ res.ok
105
+ ? ([await res.arrayBuffer(), res.headers.get("content-type")] as const)
106
+ : []
80
107
  )
81
108
  .catch(() => []);
82
109
 
83
110
  if (!srcImage) {
84
- return new Response('image not found', { status: 404 });
111
+ return new Response("image not found", { status: 404 });
85
112
  }
86
113
 
87
- if (contentType && ['image/svg+xml', 'image/gif'].includes(contentType)) {
114
+ if (contentType && ["image/svg+xml", "image/gif"].includes(contentType)) {
88
115
  const response = new Response(srcImage, {
89
116
  headers: {
90
- 'Content-Type': contentType,
91
- 'Cache-Control': 'public, max-age=31536000, immutable',
117
+ "Content-Type": contentType,
118
+ "Cache-Control": "public, max-age=31536000, immutable",
92
119
  },
93
120
  });
94
121
  ctx.waitUntil(cache.put(cacheKey, response.clone()));
95
122
  return response;
96
123
  }
97
124
 
98
- const format = isWebp ? 'webp' : contentType === 'image/jpeg' ? 'jpeg' : 'png';
125
+ const format =
126
+ type ?? (isWebp ? "webp" : contentType === "image/jpeg" ? "jpeg" : "png");
99
127
  const image = await optimizeImage({
100
128
  image: srcImage,
101
129
  width: width ? parseInt(width) : undefined,
@@ -104,8 +132,8 @@ const handleRequest = async (
104
132
  });
105
133
  const response = new Response(image, {
106
134
  headers: {
107
- 'Content-Type': `image/${format}`,
108
- 'Cache-Control': 'public, max-age=31536000, immutable',
135
+ "Content-Type": `image/${format}`,
136
+ "Cache-Control": "public, max-age=31536000, immutable",
109
137
  date: new Date().toUTCString(),
110
138
  },
111
139
  });
@@ -126,7 +154,7 @@ export default {
126
154
  */
127
155
  const config = {
128
156
  images: {
129
- path: 'https://xxx.yyy.workers.dev/',
157
+ path: "https://xxx.yyy.workers.dev/",
130
158
  },
131
159
  };
132
160
  export default config;
@@ -136,16 +164,21 @@ export default config;
136
164
 
137
165
  ### Parameters
138
166
 
139
- | Name | Type | Description |
140
- | ---- | ------ | ----------- |
141
- | url | string | Image URL |
142
- | q | number | Quality |
143
- | w | number | Width |
167
+ | Name | Type | Description |
168
+ | ---- | ------ | -------------------------- |
169
+ | url | string | Image URL |
170
+ | q | number | Quality |
171
+ | w | number | Width |
172
+ | type | string | Output type(webp/png/jpeg) |
144
173
 
145
174
  https://xxxx.deno.dev/?url=https://xxx.png&q=80&w=200
146
175
 
176
+ ### Source code
177
+
178
+ https://github.com/SoraKumo001/deno-wasm-image-optimization
179
+
147
180
  ```ts
148
- import { optimizeImage } from 'npm:wasm-image-optimization/esm';
181
+ import { optimizeImage } from "npm:wasm-image-optimization/esm";
149
182
 
150
183
  const isValidUrl = (url: string) => {
151
184
  try {
@@ -156,7 +189,7 @@ const isValidUrl = (url: string) => {
156
189
  }
157
190
  };
158
191
 
159
- const cache = await caches.open('image-cache');
192
+ const cache = await caches.open("image-cache");
160
193
 
161
194
  Deno.serve(async (request) => {
162
195
  const cached = await cache.match(request);
@@ -166,55 +199,59 @@ Deno.serve(async (request) => {
166
199
 
167
200
  const url = new URL(request.url);
168
201
  const params = url.searchParams;
169
- const type = ['webp', 'png', 'jpeg'].find((v) => v === params.get('type')) as
170
- | 'webp'
171
- | 'png'
172
- | 'jpeg'
202
+ const type = ["webp", "png", "jpeg"].find((v) => v === params.get("type")) as
203
+ | "webp"
204
+ | "png"
205
+ | "jpeg"
173
206
  | undefined;
174
- const accept = request.headers.get('accept');
207
+ const accept = request.headers.get("accept");
175
208
  const isWebp =
176
209
  accept
177
- ?.split(',')
210
+ ?.split(",")
178
211
  .map((format) => format.trim())
179
- .some((format) => ['image/webp', '*/*', 'image/*'].includes(format)) ?? true;
212
+ .some((format) => ["image/webp", "*/*", "image/*"].includes(format)) ??
213
+ true;
180
214
 
181
- const imageUrl = params.get('url');
215
+ const imageUrl = params.get("url");
182
216
  if (!imageUrl || !isValidUrl(imageUrl)) {
183
- return new Response('url is required', { status: 400 });
217
+ return new Response("url is required", { status: 400 });
184
218
  }
185
219
 
186
- url.searchParams.append('webp', isWebp.toString());
220
+ url.searchParams.append("webp", isWebp.toString());
187
221
  const cacheKey = new Request(url.toString());
188
222
  const cachedResponse = await cache.match(cacheKey);
189
223
  if (cachedResponse) {
190
224
  return cachedResponse;
191
225
  }
192
226
 
193
- const width = params.get('w');
194
- const quality = params.get('q');
227
+ const width = params.get("w");
228
+ const quality = params.get("q");
195
229
 
196
230
  const [srcImage, contentType] = await fetch(imageUrl)
197
231
  .then(async (res) =>
198
- res.ok ? ([await res.arrayBuffer(), res.headers.get('content-type')] as const) : []
232
+ res.ok
233
+ ? ([await res.arrayBuffer(), res.headers.get("content-type")] as const)
234
+ : []
199
235
  )
200
236
  .catch(() => []);
201
237
 
202
238
  if (!srcImage) {
203
- return new Response('image not found', { status: 404 });
239
+ return new Response("image not found", { status: 404 });
204
240
  }
205
241
 
206
- if (contentType && ['image/svg+xml', 'image/gif'].includes(contentType)) {
242
+ if (contentType && ["image/svg+xml", "image/gif"].includes(contentType)) {
207
243
  const response = new Response(srcImage, {
208
244
  headers: {
209
- 'Content-Type': contentType,
210
- 'Cache-Control': 'public, max-age=31536000, immutable',
245
+ "Content-Type": contentType,
246
+ "Cache-Control": "public, max-age=31536000, immutable",
211
247
  },
212
248
  });
213
249
  cache.put(request, response.clone());
214
250
  return response;
215
251
  }
216
252
 
217
- const format = type ?? (isWebp ? 'webp' : contentType === 'image/jpeg' ? 'jpeg' : 'png');
253
+ const format =
254
+ type ?? (isWebp ? "webp" : contentType === "image/jpeg" ? "jpeg" : "png");
218
255
  const image = await optimizeImage({
219
256
  image: srcImage,
220
257
  width: width ? parseInt(width) : undefined,
@@ -223,8 +260,8 @@ Deno.serve(async (request) => {
223
260
  });
224
261
  const response = new Response(image, {
225
262
  headers: {
226
- 'Content-Type': `image/${format}`,
227
- 'Cache-Control': 'public, max-age=31536000, immutable',
263
+ "Content-Type": `image/${format}`,
264
+ "Cache-Control": "public, max-age=31536000, immutable",
228
265
  date: new Date().toUTCString(),
229
266
  },
230
267
  });
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "wasm-image-optimization",
3
3
  "description": "Optimize images with wasm on edge runtime",
4
- "version": "1.0.2",
4
+ "version": "1.0.4",
5
5
  "exports": {
6
6
  "./esm": {
7
7
  "default": {