@divriots/jampack 0.2.2 → 0.2.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.
package/dist/index.js CHANGED
@@ -45,14 +45,17 @@ program.command('pack', { isDefault: true })
45
45
  await optimize(options.exclude);
46
46
  console.timeEnd('Done');
47
47
  }
48
- if (!options.onlyoptim) {
48
+ if (!options.onlyoptim && !options.fast) {
49
49
  printTitle('PASS 2 - Compressing the rest');
50
50
  console.time('Done');
51
51
  await compress(options.exclude);
52
52
  console.timeEnd('Done');
53
53
  }
54
54
  printSummary();
55
- printWarningsAndErrors(options);
55
+ printIssues();
56
+ if (options.failOnIssues && $state.issues.size > 0) {
57
+ exit(1);
58
+ }
56
59
  });
57
60
  program.parse();
58
61
  function printSummary() {
@@ -82,7 +85,7 @@ function printSummary() {
82
85
  console.log(table(dataTable, config));
83
86
  }
84
87
  }
85
- function printWarningsAndErrors(options) {
88
+ function printIssues() {
86
89
  let issueCount = 0;
87
90
  if ($state.issues.size === 0) {
88
91
  printTitle('✔ No issues');
@@ -91,15 +94,13 @@ function printWarningsAndErrors(options) {
91
94
  printTitle('Issues', kleur.bgRed);
92
95
  console.log('');
93
96
  for (let [file, list] of $state.issues) {
94
- console.log(kleur.red('▶ ' + file + '\n'));
97
+ console.log('▶ ' + file + '\n');
95
98
  list.forEach(issue => {
96
99
  issueCount++;
97
- console.log(`${issueCount}) ${issue.msg}\n`);
100
+ console.log(`${kleur.bgYellow(` ${issue.type} `)} ${issue.msg}\n`);
98
101
  });
99
102
  }
100
- printTitle(`${issueCount} issue(s) over ${$state.issues.size} files`, kleur.bgRed);
101
- if (options.failOnIssues) {
102
- exit(1);
103
- }
103
+ printTitle(`${issueCount} issue(s) over ${$state.issues.size} files`, kleur.bgYellow);
104
+ console.log('');
104
105
  }
105
106
  }
package/dist/logger.js CHANGED
@@ -21,5 +21,5 @@ export class Logger {
21
21
  }
22
22
  export function printTitle(msg, bgColor = kleur.bgGreen) {
23
23
  console.log('');
24
- console.log(bgColor(kleur.black(` ${msg} `)));
24
+ console.log(kleur.black(bgColor(` ${msg} `)));
25
25
  }
package/dist/optimize.js CHANGED
@@ -2,14 +2,14 @@ import { globby } from 'globby';
2
2
  import * as path from 'path';
3
3
  import * as fs from 'fs/promises';
4
4
  import cheerio from 'cheerio';
5
- import { isLocal, isNumeric, translateSrc } from './utils.js';
6
- import sharp from "sharp";
5
+ import { isNumeric } from './utils.js';
7
6
  import config from './config.js';
8
7
  import { compressImage } from './compress.js';
9
8
  import svgToMiniDataURI from 'mini-svg-data-uri';
10
9
  import $state from './state.js';
11
10
  import kleur from 'kleur';
12
11
  import ora from 'ora';
12
+ import { isLocal, Resource, translateSrc } from './utils/resource.js';
13
13
  async function analyse(file) {
14
14
  console.log('▶ ' + file);
15
15
  const html = (await fs.readFile(path.join($state.dir, file))).toString();
@@ -49,7 +49,7 @@ async function processImage(htmlfile, $, imgElement) {
49
49
  */
50
50
  const attrib_src = img.attr('src');
51
51
  if (!attrib_src) {
52
- $state.reportIssue(htmlfile, { msg: `Missing [src] on img - processing skipped.` });
52
+ $state.reportIssue(htmlfile, { type: 'warn', msg: `Missing [src] on img - processing skipped.` });
53
53
  return;
54
54
  }
55
55
  /*
@@ -57,7 +57,7 @@ async function processImage(htmlfile, $, imgElement) {
57
57
  */
58
58
  const attrib_alt = img.attr('alt');
59
59
  if (attrib_alt === undefined) {
60
- $state.reportIssue(htmlfile, { msg: `Missing [alt] on img src="${attrib_src}" - Added alt="" meanwhile.` });
60
+ $state.reportIssue(htmlfile, { type: 'a11y', msg: `Missing [alt] on img src="${attrib_src}" - Adding alt="" meanwhile.` });
61
61
  img.attr('alt', "");
62
62
  }
63
63
  if (attrib_src.startsWith('data:')) {
@@ -65,10 +65,6 @@ async function processImage(htmlfile, $, imgElement) {
65
65
  // TODO: try to compress it
66
66
  return;
67
67
  }
68
- if (!isLocal(attrib_src)) {
69
- // Image not local, don't touch it
70
- return;
71
- }
72
68
  /*
73
69
  * Attribute 'loading'
74
70
  */
@@ -85,48 +81,46 @@ async function processImage(htmlfile, $, imgElement) {
85
81
  // Don't touch it
86
82
  break;
87
83
  default:
88
- $state.reportIssue(htmlfile, { msg: `Invalid [loading]="${attr_loading}" on img src="${attrib_src}"` });
84
+ $state.reportIssue(htmlfile, { type: 'invalid', msg: `Invalid [loading]="${attr_loading}" on img src="${attrib_src}"` });
89
85
  }
90
86
  /*
91
87
  * Attribute 'decoding'
92
88
  */
93
89
  img.attr('decoding', 'async');
90
+ if (!isLocal(attrib_src)) {
91
+ // Image not local, don't touch it
92
+ return;
93
+ }
94
94
  /*
95
95
  * Loading image
96
96
  */
97
- const absoluteImgPath = translateSrc($state.dir, path.dirname(htmlfile), attrib_src);
98
- // file exists?
99
- try {
100
- await fs.stat(absoluteImgPath);
101
- }
102
- catch (e) {
103
- $state.reportIssue(htmlfile, { msg: `Can't find img src="${attrib_src}" in ${absoluteImgPath}` });
97
+ const originalImage = await Resource.loadResource($state.dir, htmlfile, attrib_src);
98
+ // No file -> give up
99
+ if (!originalImage) {
100
+ $state.reportIssue(htmlfile, { type: 'erro', msg: `Can't find img on disk src="${attrib_src}"` });
104
101
  return;
105
102
  }
106
- const sharpFile = sharp(absoluteImgPath);
107
- const meta = await sharpFile.metadata();
108
- const originalData = await fs.readFile(absoluteImgPath);
109
103
  /*
110
104
  * Compress image to WebP
111
105
  */
112
106
  let newImage;
113
- if (!$state.optimizedFiles.has(absoluteImgPath)) {
107
+ if (!$state.optimizedFiles.has(originalImage.filePathAbsolute)) {
114
108
  // Let's avoid to optimize same images twice
115
- $state.optimizedFiles.add(absoluteImgPath);
116
- newImage = await compressImage(originalData, {}, true);
117
- if ((newImage === null || newImage === void 0 ? void 0 : newImage.data) && newImage.data.length < originalData.length) {
109
+ $state.optimizedFiles.add(originalImage.filePathAbsolute);
110
+ newImage = await compressImage(await originalImage.getData(), {}, true);
111
+ if ((newImage === null || newImage === void 0 ? void 0 : newImage.data) && newImage.data.length < await originalImage.getLen()) {
118
112
  // Do we need to add an new extension?
119
113
  const newExtension = `.${newImage.format}`;
120
- const additionalExtension = path.extname(absoluteImgPath) === newExtension ? '' : newExtension;
121
- const newFilename = absoluteImgPath + additionalExtension;
114
+ const additionalExtension = path.extname(originalImage.filePathAbsolute) === newExtension ? '' : newExtension;
115
+ const newFilename = originalImage.filePathAbsolute + additionalExtension;
122
116
  if (!$state.args.nowrite) {
123
117
  fs.writeFile(newFilename, newImage.data);
124
118
  }
125
119
  $state.compressedFiles.add(newFilename);
126
120
  // Report compression result
127
121
  $state.reportSummary({
128
- action: (newFilename !== absoluteImgPath) ? `${meta.format}->${newImage.format}` : path.extname(absoluteImgPath),
129
- originalSize: originalData.length,
122
+ action: (newFilename !== originalImage.filePathAbsolute) ? `${await originalImage.getExt()}->${newImage.format}` : path.extname(originalImage.filePathAbsolute),
123
+ originalSize: await originalImage.getLen(),
130
124
  compressedSize: newImage.data.length
131
125
  });
132
126
  img.attr('src', attrib_src + additionalExtension);
@@ -159,9 +153,13 @@ async function processImage(htmlfile, $, imgElement) {
159
153
  img.attr('src', datauri);
160
154
  img.removeAttr('loading');
161
155
  img.removeAttr('decoding');
162
- $state.reportSummary({ action: `${newImage.format}->embed`, originalSize: originalData.length, compressedSize: newImage.data.length });
156
+ $state.reportSummary({ action: `${newImage.format}->embed`, originalSize: await originalImage.getLen(), compressedSize: newImage.data.length });
163
157
  }
164
158
  }
159
+ /*
160
+ * Attribute 'width' & 'height'
161
+ */
162
+ const [w, h] = await setImageSize(img, originalImage);
165
163
  if (isEmbed) {
166
164
  // Image is embed, no need for more processing
167
165
  return;
@@ -169,14 +167,7 @@ async function processImage(htmlfile, $, imgElement) {
169
167
  //
170
168
  // Stop here if svg
171
169
  //
172
- if (meta.format === 'svg')
173
- return;
174
- /*
175
- * Attribute 'width' & 'height'
176
- */
177
- const [w, h] = setImageSize(img, meta);
178
- if (w < 0 || h < 0) {
179
- $state.reportIssue(htmlfile, { msg: `Unexpected error in image size calculation src="${attrib_src}" - can't performance some optmizations.` });
170
+ if (await originalImage.getExt() === 'svg') {
180
171
  return;
181
172
  }
182
173
  /*
@@ -207,7 +198,7 @@ async function processImage(htmlfile, $, imgElement) {
207
198
  if (!$state.compressedFiles.has(absoluteFilename)) {
208
199
  // Add file to list avoid recompression
209
200
  $state.compressedFiles.add(absoluteFilename);
210
- const compressedImage = await compressImage(originalData, { width: valueW, height: valueH }, true);
201
+ const compressedImage = await compressImage(await originalImage.getData(), { width: valueW, height: valueH }, true);
211
202
  if ((compressedImage === null || compressedImage === void 0 ? void 0 : compressedImage.data) && !$state.args.nowrite) {
212
203
  fs.writeFile(absoluteFilename, compressedImage.data);
213
204
  }
@@ -223,10 +214,10 @@ async function processImage(htmlfile, $, imgElement) {
223
214
  }
224
215
  }
225
216
  catch (e) {
226
- $state.reportIssue(htmlfile, { msg: `Unexpected error while processing image: ${JSON.stringify(e)}` });
217
+ $state.reportIssue(htmlfile, { type: 'erro', msg: e.message || `Unexpected error while processing image: ${JSON.stringify(e)}` });
227
218
  }
228
219
  }
229
- function setImageSize(img, meta) {
220
+ async function setImageSize(img, image) {
230
221
  let width = img.attr('width');
231
222
  let height = img.attr('height');
232
223
  let width_new = undefined;
@@ -245,8 +236,12 @@ function setImageSize(img, meta) {
245
236
  }
246
237
  }
247
238
  // If we don't have the metadata, we can't do much more
248
- if (meta.width === undefined || meta.height === undefined) {
249
- return [-1, -1];
239
+ const meta = await image.getImageMeta();
240
+ if (!meta) {
241
+ throw new Error(`Can't get image meta information of "${image.src}" - some optimizations are not possible without this information.`);
242
+ }
243
+ if (meta.width === undefined && meta.height === undefined) {
244
+ throw new Error(`Can't get image width and height of "${image.src}" - some optimizations are not possible without this information.`);
250
245
  }
251
246
  const originalRatio = meta.width / meta.height;
252
247
  if (width !== undefined && height !== undefined) {
@@ -273,17 +268,68 @@ function setImageSize(img, meta) {
273
268
  }
274
269
  else {
275
270
  // No width or height provided - set both to image size
276
- width_new = meta.width;
277
- height_new = meta.height;
271
+ if (await image.getExt() === 'svg') {
272
+ // svg with no height and width has special sizing by browsers
273
+ // They size it inside 300x150 unless they have width and height
274
+ // attributes
275
+ // Load svg
276
+ const c = cheerio.load(await image.getData(), {});
277
+ const svg = c('svg').first();
278
+ const svg_viewbox = svg.attr('viewbox'); // bug in cheerio here, should be "viewBox"
279
+ const svg_width = svg.attr('width');
280
+ const svg_height = svg.attr('height');
281
+ // Calculate aspect ratio from viewbox
282
+ let svg_aspectratio_from_viewbox = undefined;
283
+ if (svg_viewbox) {
284
+ const box = svg_viewbox.split(' ');
285
+ const w = parseInt(box[2], 10);
286
+ const h = parseInt(box[3], 10);
287
+ svg_aspectratio_from_viewbox = w / h;
288
+ }
289
+ // Set size
290
+ //
291
+ if (svg_width && isNumeric(svg_width) && svg_height && isNumeric(svg_height)) {
292
+ // height and width are present
293
+ // use them
294
+ width_new = parseInt(svg_width, 10);
295
+ height_new = parseInt(svg_height, 10);
296
+ }
297
+ else if (svg_width === undefined && svg_height === undefined && svg_aspectratio_from_viewbox) {
298
+ // no height and no width but viewbox is present
299
+ // fit it in default browser box 300x150
300
+ if (svg_aspectratio_from_viewbox >= 2) {
301
+ // fit width
302
+ width_new = 300;
303
+ height_new = width_new / svg_aspectratio_from_viewbox;
304
+ }
305
+ else {
306
+ // fit height
307
+ height_new = 150;
308
+ width_new = height_new * svg_aspectratio_from_viewbox;
309
+ }
310
+ }
311
+ else {
312
+ // no width and no height and no viewbox
313
+ // default browser values
314
+ width_new = 300;
315
+ height_new = 150;
316
+ }
317
+ }
318
+ else {
319
+ width_new = meta.width;
320
+ height_new = meta.height;
321
+ }
278
322
  }
279
323
  // New sizes
280
324
  if (width_new !== undefined && height_new !== undefined) {
281
- img.attr('width', width_new.toFixed(0));
282
- img.attr('height', height_new.toFixed(0));
283
- return [Math.round(width_new), Math.round(height_new)];
325
+ const result_w = Math.round(width_new);
326
+ const result_h = Math.round(height_new);
327
+ img.attr('width', result_w.toFixed(0));
328
+ img.attr('height', result_h.toFixed(0));
329
+ return [result_w, result_h];
284
330
  }
285
331
  // Something when wrong
286
- throw new Error('Unexpected issue when resolving image sizes');
332
+ throw new Error(`Unexpected issue when resolving image size "${image.src}"`);
287
333
  }
288
334
  export async function optimize(exclude) {
289
335
  const glob = ['**/*.{htm,html}'];
package/dist/state.d.ts CHANGED
@@ -13,6 +13,7 @@ declare type Summary = {
13
13
  dataLenCompressed: number;
14
14
  };
15
15
  declare type Issue = {
16
+ type: 'invalid' | 'a11y' | 'perf' | 'erro' | 'warn';
16
17
  msg: string;
17
18
  };
18
19
  export declare class GlobalState {
@@ -0,0 +1,31 @@
1
+ /// <reference types="node" resolution-mode="require"/>
2
+ import { FileExtension, MimeType } from 'file-type';
3
+ declare type ImageMeta = {
4
+ width: number | undefined;
5
+ height: number | undefined;
6
+ isProgressive: boolean;
7
+ hasAlpha: boolean;
8
+ };
9
+ /**
10
+ * File extension, mime and data are loaded only on demand, then cached.
11
+ */
12
+ export declare class Resource {
13
+ readonly src: string;
14
+ readonly filePathAbsolute: string;
15
+ private ext;
16
+ private mime;
17
+ private data;
18
+ private image_meta;
19
+ constructor(src: string, filePathAbsolute: string);
20
+ getData(): Promise<Buffer>;
21
+ getImageMeta(): Promise<ImageMeta | null | undefined>;
22
+ getLen(): Promise<number>;
23
+ getExt(): Promise<FileExtension | 'svg'>;
24
+ getMime(): Promise<MimeType | 'image/svg+xml'>;
25
+ private loadFileType;
26
+ static loadResource(projectRoot: string, relativeFile: string, src: string): Promise<Resource | undefined>;
27
+ }
28
+ export declare function isLocal(src: string): boolean;
29
+ export declare function fileExists(path: string): Promise<boolean>;
30
+ export declare function translateSrc(projectRoot: string, htmlRelativePath: string, src: string): string;
31
+ export {};
@@ -0,0 +1,106 @@
1
+ import * as url from 'url';
2
+ import * as path from 'path';
3
+ import * as fs from 'fs/promises';
4
+ import { fileTypeFromBuffer } from 'file-type';
5
+ import sharp from 'sharp';
6
+ /**
7
+ * File extension, mime and data are loaded only on demand, then cached.
8
+ */
9
+ export class Resource {
10
+ constructor(src, filePathAbsolute) {
11
+ this.src = src;
12
+ this.filePathAbsolute = filePathAbsolute;
13
+ }
14
+ async getData() {
15
+ if (this.data === undefined) {
16
+ this.data = await fs.readFile(this.filePathAbsolute);
17
+ }
18
+ return this.data;
19
+ }
20
+ async getImageMeta() {
21
+ if (this.image_meta === undefined) {
22
+ const ext = await this.getExt();
23
+ switch (ext) {
24
+ case 'svg':
25
+ case 'gif':
26
+ case 'jpg':
27
+ case 'png':
28
+ case 'webp':
29
+ case 'tif':
30
+ let sharpFile = await sharp(await this.getData(), { animated: true });
31
+ const meta = await sharpFile.metadata();
32
+ this.image_meta = {
33
+ width: meta.width,
34
+ height: meta.height,
35
+ isProgressive: meta.isProgressive || false,
36
+ hasAlpha: meta.hasAlpha || false
37
+ };
38
+ break;
39
+ }
40
+ }
41
+ if (!this.image_meta) {
42
+ console.log(await this.getExt());
43
+ }
44
+ return this.image_meta;
45
+ }
46
+ async getLen() {
47
+ return (await this.getData()).length;
48
+ }
49
+ async getExt() {
50
+ if (this.ext === undefined) {
51
+ await this.loadFileType();
52
+ }
53
+ return this.ext;
54
+ }
55
+ async getMime() {
56
+ if (this.mime === undefined) {
57
+ await this.loadFileType();
58
+ }
59
+ return this.mime;
60
+ }
61
+ async loadFileType() {
62
+ const fileType = await fileTypeFromBuffer(await this.getData());
63
+ if (this.filePathAbsolute.endsWith('.svg')) {
64
+ this.ext = 'svg';
65
+ this.mime = 'image/svg+xml';
66
+ }
67
+ else if (fileType) {
68
+ this.ext = fileType.ext;
69
+ this.mime = fileType.mime;
70
+ }
71
+ else {
72
+ throw new Error(`Unknown file type "${this.src}"`);
73
+ }
74
+ }
75
+ static async loadResource(projectRoot, relativeFile, src) {
76
+ if (!isLocal(src)) {
77
+ throw new Error('Source should be local');
78
+ }
79
+ const relativePath = path.join(projectRoot, src.startsWith('/') ? '' : path.dirname(relativeFile), src);
80
+ const absolutePath = path.resolve(relativePath);
81
+ if (await fileExists(absolutePath)) {
82
+ return new Resource(src, absolutePath);
83
+ }
84
+ return undefined;
85
+ }
86
+ }
87
+ export function isLocal(src) {
88
+ const u = url.parse(src);
89
+ return !u.host;
90
+ }
91
+ export async function fileExists(path) {
92
+ try {
93
+ await fs.stat(path);
94
+ }
95
+ catch (e) {
96
+ return false;
97
+ }
98
+ return true;
99
+ }
100
+ export function translateSrc(projectRoot, htmlRelativePath, src) {
101
+ if (!isLocal(src)) {
102
+ throw new Error('Source should be local');
103
+ }
104
+ const srcAbsolutePath = path.join(projectRoot, src.startsWith('/') ? '' : htmlRelativePath, src);
105
+ return path.resolve(srcAbsolutePath);
106
+ }
package/dist/utils.d.ts CHANGED
@@ -1,4 +1,2 @@
1
1
  export declare function formatBytes(bytes: number, decimals?: number): string;
2
- export declare function isLocal(src: string): boolean;
3
- export declare function translateSrc(projectRoot: string, htmlRelativePath: string, src: string): string;
4
2
  export declare function isNumeric(value: string): boolean;
package/dist/utils.js CHANGED
@@ -1,5 +1,3 @@
1
- import * as url from 'url';
2
- import * as path from 'path';
3
1
  export function formatBytes(bytes, decimals = 2) {
4
2
  if (!+bytes)
5
3
  return '0 Bytes';
@@ -9,17 +7,6 @@ export function formatBytes(bytes, decimals = 2) {
9
7
  const i = Math.floor(Math.log(bytes) / Math.log(k));
10
8
  return `${(bytes / Math.pow(k, i)).toFixed(dm)} ${sizes[i]}`;
11
9
  }
12
- export function isLocal(src) {
13
- const u = url.parse(src);
14
- return !u.host;
15
- }
16
- export function translateSrc(projectRoot, htmlRelativePath, src) {
17
- if (!isLocal(src)) {
18
- throw new Error('Source should be local');
19
- }
20
- const srcAbsolutePath = path.join(projectRoot, src.startsWith('/') ? '' : htmlRelativePath, src);
21
- return path.resolve(srcAbsolutePath);
22
- }
23
10
  export function isNumeric(value) {
24
11
  return /^\d+$/.test(value);
25
12
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@divriots/jampack",
3
- "version": "0.2.2",
3
+ "version": "0.2.4",
4
4
  "description": "Packer for static websites",
5
5
  "author": "Georges Gomes @georges-gomes",
6
6
  "bin": {
@@ -29,6 +29,7 @@
29
29
  "cheerio": "0.22.0",
30
30
  "commander": "^9.4.1",
31
31
  "csso": "^5.0.5",
32
+ "file-type": "^18.0.0",
32
33
  "globby": "^13.1.2",
33
34
  "html-minifier-terser": "^7.0.0",
34
35
  "kleur": "^4.1.5",
package/dist/options.d.ts DELETED
@@ -1,30 +0,0 @@
1
- export declare type WebpOptions = {
2
- effort: number;
3
- mode: 'lossless' | 'lossly';
4
- quality: number;
5
- };
6
- export declare type Options = {
7
- image: {
8
- embed_size: number;
9
- srcset_min_width: number;
10
- srcset_max_width: number;
11
- jpeg: {
12
- options: {
13
- quality: number;
14
- mozjpeg: boolean;
15
- };
16
- };
17
- png: {
18
- options: {
19
- compressionLevel: number;
20
- };
21
- };
22
- webp: {
23
- options_lossless: WebpOptions;
24
- options_lossly: WebpOptions;
25
- };
26
- };
27
- };
28
- declare const default_options: Options;
29
- export declare function fast(): void;
30
- export default default_options;
package/dist/options.js DELETED
@@ -1,59 +0,0 @@
1
- const default_options = {
2
- image: {
3
- embed_size: 400,
4
- srcset_min_width: 400,
5
- srcset_max_width: 5120,
6
- jpeg: {
7
- options: {
8
- quality: 80,
9
- mozjpeg: true
10
- }
11
- },
12
- png: {
13
- options: {
14
- compressionLevel: 9,
15
- }
16
- },
17
- webp: {
18
- options_lossless: {
19
- effort: 4,
20
- quality: 80,
21
- mode: 'lossless'
22
- },
23
- options_lossly: {
24
- effort: 4,
25
- quality: 80,
26
- mode: 'lossly'
27
- }
28
- }
29
- }
30
- };
31
- const fast_options_override = {
32
- image: {
33
- embed_size: 0,
34
- srcset_min_width: 1024,
35
- srcset_max_width: 1024,
36
- jpeg: {
37
- options: {
38
- mozjpeg: false
39
- }
40
- },
41
- png: {
42
- options: {
43
- compressionLevel: 0,
44
- }
45
- },
46
- webp: {
47
- options_lossless: {
48
- effort: 0,
49
- },
50
- options_lossly: {
51
- effort: 0,
52
- }
53
- }
54
- }
55
- };
56
- export function fast() {
57
- Object.assign(default_options, fast_options_override);
58
- }
59
- export default default_options;
@@ -1,25 +0,0 @@
1
- export declare type Args = {
2
- nowrite?: boolean;
3
- };
4
- export declare type Result = {
5
- file: string;
6
- originalSize: number;
7
- compressedSize: number;
8
- };
9
- export declare type Summary = {
10
- nbFiles: number;
11
- nbFilesCompressed: number;
12
- dataLenUncompressed: number;
13
- dataLenCompressed: number;
14
- };
15
- export declare class GlobalState {
16
- dir: string;
17
- args: Args;
18
- compressedFiles: Set<string>;
19
- compressedFilesResult: Result[];
20
- summary: Summary;
21
- summaryByExtension: Record<string, Summary>;
22
- addFile(r: Result): void;
23
- }
24
- declare const state: GlobalState;
25
- export default state;
@@ -1,45 +0,0 @@
1
- import path from "path";
2
- export class GlobalState {
3
- constructor() {
4
- this.dir = 'dist';
5
- this.args = {};
6
- this.compressedFiles = new Set();
7
- this.compressedFilesResult = [];
8
- this.summary = {
9
- nbFiles: 0,
10
- nbFilesCompressed: 0,
11
- dataLenCompressed: 0,
12
- dataLenUncompressed: 0
13
- };
14
- this.summaryByExtension = {};
15
- }
16
- addFile(r) {
17
- const isCompressed = r.compressedSize < r.originalSize ? 1 : 0;
18
- this.compressedFiles.add(r.file);
19
- this.compressedFilesResult.push(r);
20
- this.summary.nbFiles++;
21
- state.summary.nbFilesCompressed += isCompressed;
22
- state.summary.dataLenUncompressed += r.originalSize;
23
- state.summary.dataLenCompressed += r.compressedSize;
24
- const ext = path.extname(r.file);
25
- if (ext) {
26
- let summary = this.summaryByExtension[ext];
27
- if (!summary) {
28
- summary = {
29
- nbFiles: 0,
30
- nbFilesCompressed: 0,
31
- dataLenUncompressed: 0,
32
- dataLenCompressed: 0
33
- };
34
- this.summaryByExtension[ext] = summary;
35
- }
36
- summary.nbFiles++;
37
- summary.nbFilesCompressed += isCompressed;
38
- summary.dataLenUncompressed += r.originalSize;
39
- summary.dataLenCompressed += r.compressedSize;
40
- }
41
- }
42
- ;
43
- }
44
- const state = new GlobalState();
45
- export default state;