@divriots/jampack 0.5.1 → 0.5.2

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/LICENSE CHANGED
File without changes
package/README.md CHANGED
@@ -68,6 +68,8 @@ See [the list of features](https://jampack.divriots.com).
68
68
  - [WebComponents.dev](https://WebComponents.dev)
69
69
  - [LWC.studio](https://lwc.studio)
70
70
  - [Components.studio](https://components.studio)
71
+ - [keycloak.ch](https://keycloak.ch)
72
+
71
73
  > Add yours here
72
74
 
73
75
  ## Why is it called `jampack`?
@@ -1,7 +1,8 @@
1
+ /// <reference types="node" resolution-mode="require"/>
1
2
  import sharp from 'sharp';
2
3
  import type { Image } from './types.js';
3
4
  export declare const compressImage: (data: Buffer, options: {
4
5
  resize?: sharp.ResizeOptions;
5
- toFormat?: 'webp' | 'pjpg' | 'unchanged';
6
+ toFormat?: 'webp' | 'pjpg' | 'avif' | 'unchanged';
6
7
  }) => Promise<Image | undefined>;
7
8
  export declare function compress(exclude: string): Promise<void>;
package/dist/compress.js CHANGED
@@ -108,87 +108,92 @@ export const compressImage = async (data, options) => {
108
108
  // Skip animated images for the moment.
109
109
  return undefined;
110
110
  }
111
- let doSharp = false;
112
111
  let outputFormat;
113
- switch (meta.format) {
114
- case 'svg':
115
- const newData = svgo(data, {
116
- multipass: true,
117
- plugins: [
118
- {
119
- name: 'preset-default',
120
- params: {
121
- overrides: {
122
- removeViewBox: false,
123
- },
112
+ // Special case for svg
113
+ if (meta.format === 'svg') {
114
+ const newData = svgo(data, {
115
+ multipass: true,
116
+ plugins: [
117
+ {
118
+ name: 'preset-default',
119
+ params: {
120
+ overrides: {
121
+ removeViewBox: false,
124
122
  },
125
123
  },
126
- ],
127
- });
128
- if (newData.error || newData.modernError) {
129
- console.log(`Error processing svg ${data}`);
130
- return undefined;
131
- }
132
- return { format: 'svg', data: Buffer.from(newData.data, 'utf8') };
133
- case 'png':
134
- outputFormat = 'png';
135
- if (toFormat === 'unchanged') {
124
+ },
125
+ ],
126
+ });
127
+ if (newData.error || newData.modernError) {
128
+ console.log(`Error processing svg ${data}`);
129
+ return undefined;
130
+ }
131
+ return { format: 'svg', data: Buffer.from(newData.data, 'utf8') };
132
+ }
133
+ // The bitmap images
134
+ if (toFormat === 'unchanged') {
135
+ switch (meta.format) {
136
+ case 'png':
136
137
  sharpFile = sharpFile.png(config.image.png.options || {});
137
- }
138
- doSharp = true;
139
- break;
140
- case 'jpeg':
141
- case 'jpg':
142
- outputFormat = 'jpg';
143
- if (toFormat === 'unchanged') {
138
+ outputFormat = 'png';
139
+ break;
140
+ case 'jpeg':
141
+ case 'jpg':
144
142
  sharpFile = sharpFile.jpeg(config.image.jpeg.options || {});
145
- }
146
- doSharp = true;
147
- break;
148
- case 'webp':
149
- outputFormat = 'webp';
150
- sharpFile = sharpFile.webp(createWebpOptions(config.image.webp.options_lossly) || {});
151
- doSharp = true;
152
- toFormat = 'unchanged'; // Don't need to convert to webP again
153
- break;
154
- case 'avif':
155
- outputFormat = 'avif';
156
- // TODO but avif is already pretty optimized
157
- toFormat = 'unchanged';
158
- break;
159
- }
160
- if (doSharp) {
161
- if (toFormat === 'webp') {
162
- sharpFile = sharpFile.webp(createWebpOptions(meta.format === 'png'
163
- ? config.image.webp.options_lossless
164
- : config.image.webp.options_lossly));
165
- outputFormat = 'webp';
166
- }
167
- else if (toFormat === 'pjpg') {
168
- sharpFile = sharpFile.jpeg({ ...config.image.jpeg.options, progressive: true } || {});
169
- outputFormat = 'jpg';
143
+ outputFormat = 'jpg';
144
+ break;
145
+ case 'webp':
146
+ sharpFile = sharpFile.webp(createWebpOptions(config.image.webp.options_lossly) || {});
147
+ outputFormat = 'webp';
148
+ break;
149
+ case 'avif':
150
+ sharpFile = sharpFile.avif();
151
+ outputFormat = 'avif';
152
+ break;
170
153
  }
171
- if (((_a = options.resize) === null || _a === void 0 ? void 0 : _a.width) && ((_b = options.resize) === null || _b === void 0 ? void 0 : _b.height)) {
172
- sharpFile = sharpFile.resize({
173
- ...options.resize,
174
- fit: 'fill',
175
- withoutEnlargement: true,
176
- });
154
+ }
155
+ else {
156
+ // To format
157
+ switch (toFormat) {
158
+ case 'pjpg':
159
+ sharpFile = sharpFile.jpeg({ ...config.image.jpeg.options, progressive: true } || {});
160
+ outputFormat = 'jpg';
161
+ break;
162
+ case 'webp':
163
+ sharpFile = sharpFile.webp(createWebpOptions(meta.format === 'png'
164
+ ? config.image.webp.options_lossless
165
+ : config.image.webp.options_lossly));
166
+ outputFormat = 'webp';
167
+ break;
168
+ case 'avif':
169
+ sharpFile = sharpFile.avif({ effort: 6 });
170
+ outputFormat = 'avif';
171
+ break;
177
172
  }
178
- //
179
- // Output image processed
180
- //
181
- // Add to cache
182
- const outputImage = {
183
- format: outputFormat,
184
- data: await sharpFile.toBuffer(),
185
- };
186
- await addToCacheCompressImage(cacheHash, outputImage);
187
- // Go
188
- return outputImage;
189
173
  }
190
- // Unknown input format or error while processing
191
- return undefined;
174
+ // Unknow input format or output format
175
+ // Can't do
176
+ if (!outputFormat)
177
+ return undefined;
178
+ // If resize is requested
179
+ if (((_a = options.resize) === null || _a === void 0 ? void 0 : _a.width) && ((_b = options.resize) === null || _b === void 0 ? void 0 : _b.height)) {
180
+ sharpFile = sharpFile.resize({
181
+ ...options.resize,
182
+ fit: 'fill',
183
+ withoutEnlargement: true,
184
+ });
185
+ }
186
+ //
187
+ // Output image processed
188
+ //
189
+ // Add to cache
190
+ const outputImage = {
191
+ format: outputFormat,
192
+ data: await sharpFile.toBuffer(),
193
+ };
194
+ await addToCacheCompressImage(cacheHash, outputImage);
195
+ // Go
196
+ return outputImage;
192
197
  };
193
198
  const compressImageFile = async (file) => {
194
199
  const buffer = await fs.readFile(file);
package/dist/index.js CHANGED
File without changes
package/dist/optimize.js CHANGED
@@ -240,9 +240,12 @@ async function processImage(htmlfile, $, imgElement, isAboveTheFold) {
240
240
  }
241
241
  else {
242
242
  // Generate image set
243
+ // Avif => Avif
244
+ // png, jpg, ... => WebP
245
+ const targetFormat = (await originalImage.getMime()) === 'image/avif' ? 'avif' : 'webp';
243
246
  const ext = path.extname(attrib_src);
244
247
  const fullbasename = attrib_src.slice(0, -ext.length);
245
- const imageSrc = (addition) => `${fullbasename}${addition}.${canBeProgressiveJpeg ? 'jpg' : 'webp'}`;
248
+ const imageSrc = (addition) => `${fullbasename}${addition}.${canBeProgressiveJpeg ? 'jpg' : targetFormat}`;
246
249
  // Start from original image
247
250
  let new_srcset = '';
248
251
  // Start reduction
@@ -250,6 +253,9 @@ async function processImage(htmlfile, $, imgElement, isAboveTheFold) {
250
253
  const ratio = w / h;
251
254
  let valueW = w - step;
252
255
  let valueH = Math.trunc(valueW / ratio);
256
+ let previousImageSize = (newImage === null || newImage === void 0 ? void 0 : newImage.data)
257
+ ? Math.min(newImage.data.length, await originalImage.getLen())
258
+ : await originalImage.getLen();
253
259
  while (valueW > config.image.srcset_min_width) {
254
260
  const src = imageSrc(`@${valueW}w`);
255
261
  const absoluteFilename = translateSrc($state.dir, path.dirname(htmlfile), src);
@@ -259,11 +265,19 @@ async function processImage(htmlfile, $, imgElement, isAboveTheFold) {
259
265
  $state.compressedFiles.add(absoluteFilename);
260
266
  const compressedImage = await compressImage(await originalImage.getData(), {
261
267
  resize: { width: valueW, height: valueH },
262
- toFormat: canBeProgressiveJpeg ? 'pjpg' : 'webp',
268
+ toFormat: canBeProgressiveJpeg ? 'pjpg' : targetFormat,
263
269
  });
264
- if ((compressedImage === null || compressedImage === void 0 ? void 0 : compressedImage.data) && !$state.args.nowrite) {
270
+ if (!(compressedImage === null || compressedImage === void 0 ? void 0 : compressedImage.data) ||
271
+ compressedImage.data.length >= previousImageSize) {
272
+ // jampack was not able to compress below the original image
273
+ // Let's move on
274
+ continue;
275
+ }
276
+ if (!$state.args.nowrite) {
265
277
  fs.writeFile(absoluteFilename, compressedImage.data);
266
278
  }
279
+ // Add previous smaller file size
280
+ previousImageSize = compressedImage.data.length;
267
281
  }
268
282
  new_srcset += `, ${src} ${valueW}w`;
269
283
  // reduce size
package/dist/state.js CHANGED
@@ -27,7 +27,6 @@ export class GlobalState {
27
27
  state.summary.nbFilesCompressed += isCompressed;
28
28
  state.summary.dataLenUncompressed += r.originalSize;
29
29
  state.summary.dataLenCompressed += r.compressedSize;
30
- console.log(r.action);
31
30
  if (r.action) {
32
31
  let summary = this.summaryByExtension[r.action];
33
32
  if (!summary) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@divriots/jampack",
3
- "version": "0.5.1",
3
+ "version": "0.5.2",
4
4
  "description": "Packer for static websites",
5
5
  "author": "Georges Gomes @georges-gomes",
6
6
  "bin": {
@@ -47,16 +47,16 @@
47
47
  "tslib": "^2.4.1",
48
48
  "typescript": "^4.9.3"
49
49
  },
50
- "scripts": {
51
- "watch": "pnpm build --watch",
52
- "try": "shx rm -fr demo && cp -R demo_avif demo && node ./dist/index.js ./demo",
53
- "build": "shx rm -rf dist && tsc -b",
54
- "lint": "eslint . --ext .ts --config .eslintrc"
55
- },
56
50
  "engines": {
57
51
  "node": ">=14.0.0"
58
52
  },
59
53
  "bugs": "https://github.com/divriots/jampack/issues",
60
54
  "keywords": [],
61
- "types": "dist/index.d.ts"
62
- }
55
+ "types": "dist/index.d.ts",
56
+ "scripts": {
57
+ "watch": "pnpm build --watch",
58
+ "try": "shx rm -fr demo && cp -R demo_avif demo && node ./dist/index.js ./demo --nocache",
59
+ "build": "shx rm -rf dist && tsc -b",
60
+ "lint": "eslint . --ext .ts --config .eslintrc"
61
+ }
62
+ }