webpack-bundle-analyzer 5.1.1 → 5.3.0

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/lib/template.js CHANGED
@@ -1,39 +1,79 @@
1
1
  "use strict";
2
2
 
3
- /* eslint-disable max-len */
4
- const path = require('path');
5
- const fs = require('fs');
3
+ const fs = require("node:fs");
4
+ const path = require("node:path");
6
5
  const {
7
6
  escape
8
- } = require('html-escaper');
9
- const projectRoot = path.resolve(__dirname, '..');
10
- const assetsRoot = path.join(projectRoot, 'public');
11
- exports.renderViewer = renderViewer;
7
+ } = require("html-escaper");
8
+ const projectRoot = path.resolve(__dirname, "..");
9
+ const assetsRoot = path.join(projectRoot, "public");
10
+
11
+ /** @typedef {import("./BundleAnalyzerPlugin").EXPECTED_ANY} EXPECTED_ANY */
12
+ /** @typedef {import("./BundleAnalyzerPlugin").Mode} Mode */
13
+ /** @typedef {import("./BundleAnalyzerPlugin").Sizes} Sizes */
14
+ /** @typedef {import("./BundleAnalyzerPlugin").CompressionAlgorithm} CompressionAlgorithm */
15
+ /** @typedef {import("./analyzer").ChartData} ChartData */
16
+ /** @typedef {import("./viewer").Entrypoints} Entrypoints */
12
17
 
13
18
  /**
14
19
  * Escapes `<` characters in JSON to safely use it in `<script>` tag.
20
+ * @param {EXPECTED_ANY} json json
21
+ * @returns {string} escaped json
15
22
  */
16
23
  function escapeJson(json) {
17
- return JSON.stringify(json).replace(/</gu, '\\u003c');
24
+ return JSON.stringify(json).replaceAll("<", "\\u003c");
18
25
  }
26
+
27
+ /**
28
+ * @param {string} filename filename
29
+ * @returns {string} content the text content of the specified file.
30
+ */
19
31
  function getAssetContent(filename) {
20
32
  const assetPath = path.join(assetsRoot, filename);
21
33
  if (!assetPath.startsWith(assetsRoot)) {
22
34
  throw new Error(`"${filename}" is outside of the assets root`);
23
35
  }
24
- return fs.readFileSync(assetPath, 'utf8');
36
+ return fs.readFileSync(assetPath, "utf8");
25
37
  }
38
+
39
+ /**
40
+ * @template {EXPECTED_ANY} T
41
+ * @param {TemplateStringsArray} strings strings
42
+ * @param {...T} values values
43
+ * @returns {string} HTML
44
+ */
26
45
  function html(strings, ...values) {
27
- return strings.map((string, index) => `${string}${values[index] || ''}`).join('');
46
+ return strings.map((string, index) => `${string}${values[index] || ""}`).join("");
28
47
  }
48
+
49
+ /**
50
+ * @param {string} filename filename
51
+ * @param {Mode} mode mode
52
+ * @returns {string} script tag
53
+ */
29
54
  function getScript(filename, mode) {
30
- if (mode === 'static') {
55
+ if (mode === "static") {
31
56
  return `<!-- ${escape(filename)} -->
32
57
  <script>${getAssetContent(filename)}</script>`;
33
- } else {
34
- return `<script src="${escape(filename)}"></script>`;
35
58
  }
59
+ return `<script src="${escape(filename)}"></script>`;
36
60
  }
61
+
62
+ /**
63
+ * @typedef {object} ViewerOptions
64
+ * @property {string} title title
65
+ * @property {boolean} enableWebSocket true when need to enable, otherwise false
66
+ * @property {ChartData} chartData chart data
67
+ * @property {Entrypoints} entrypoints entrypoints
68
+ * @property {Sizes} defaultSizes default sizes
69
+ * @property {CompressionAlgorithm} compressionAlgorithm compression algorithm
70
+ * @property {Mode} mode mode
71
+ */
72
+
73
+ /**
74
+ * @param {ViewerOptions} options viewer Options
75
+ * @returns {string} content for viewer
76
+ */
37
77
  function renderViewer({
38
78
  title,
39
79
  enableWebSocket,
@@ -42,29 +82,36 @@ function renderViewer({
42
82
  defaultSizes,
43
83
  compressionAlgorithm,
44
84
  mode
45
- } = {}) {
85
+ }) {
46
86
  return html`<!DOCTYPE html>
47
- <html>
48
- <head>
49
- <meta charset="UTF-8"/>
50
- <meta name="viewport" content="width=device-width, initial-scale=1"/>
51
- <title>${escape(title)}</title>
52
- <link rel="shortcut icon" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAMAAACdt4HsAAABrVBMVEUAAAD///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////+O1foceMD///+J0/qK1Pr7/v8Xdr/9///W8P4UdL7L7P0Scr2r4Pyj3vwad8D5/f/2/f+55f3E6f34+/2H0/ojfMKpzOd0rNgQcb3F3O/j9f7c8v6g3Pz0/P/w+v/q+P7n9v6T1/uQ1vuE0vqLut/y+v+Z2fvt+f+15Pzv9fuc2/vR7v2V2Pvd6/bg9P7I6/285/2y4/yp3/zp8vk8i8kqgMT7/P31+fyv4vxGkcz6/P6/6P3j7vfS5PNnpNUxhcbO7f7F6v3O4vHK3/DA2u631Ouy0eqXweKJud5wqthfoNMMbLvY8f73+v2dxeR8sNtTmdDx9/zX6PSjyeaCtd1YnNGX2PuQveCGt95Nls42h8dLlM3F4vBtAAAAM3RSTlMAAyOx0/sKBvik8opWGBMOAe3l1snDm2E9LSb06eHcu5JpHbarfHZCN9CBb08zzkdNS0kYaptYAAAFV0lEQVRYw92X51/aYBDHHS2O2qqttVbrqNq9m+TJIAYIShBkWwqIiCgoWvfeq7Z2/s29hyQNyUcR7LveGwVyXy6XH8/9rqxglLfUPLxVduUor3h0rfp2TYvpivk37929TkG037hffoX0+peVtZQc1589rigVUdXS/ABSAyEmGIO/1XfvldSK8vs3OqB6u3m0nxmIrvgB0dj7rr7Y9IbuF68hnfFaiHA/sxqm0wciIG43P60qKv9WXWc1RXGh/mFESFABTSBi0sNAKzqet17eCtOb3kZIDwxEEU0oAIJGYxNBDhBND29e0rtXXbcpuPmED9IhEAAQ/AXEaF8EPmnrrKsv0LvWR3fg5sWDNAFZOgAgaKvZDogHNU9MFwnnYROkc56RD5CjAbQX9Ow4g7upCsvYu55aSI/Nj0H1akgKQEUM94dwK65hYRmFU9MIcH/fqJYOZYcnuJSU/waKDgTOEVaVKhwrTRP5XzgSpAITYzom7UvkhFX5VutmxeNnWDjjswTKTyfgluNDGbUpWissXhF3s7mlSml+czWkg3D0l1nNjGNjz3myOQOa1KM/jOS6ebdbAVTCi4gljHSFrviza7tOgRWcS0MOUX9zdNgag5w7rRqA44Lzw0hr1WqES36dFliSJFlh2rXIae3FFcDDgKdxrUIDePr8jGcSClV1u7A9xeN0ModY/pHMxmR1EzRh8TJiwqsHmKW0l4FCEZI+jHio+JdPPE9qwQtTRxku2D8sIeRL2LnxWSllANCQGOIiqVHAz2ye2JR0DcH+HoxDkaADLjgxjKQ+AwCX/g0+DNgdG0ukYCONAe+dbc2IAc6fwt1ARoDSezNHxV2Cmzwv3O6lDMV55edBGwGK9n1+x2F8EDfAGCxug8MhpsMEcTEAWf3rx2vZhe/LAmtIn/6apE6PN0ULKgywD9mmdxbmFl3OvD5AS5fW5zLbv/YHmcsBTjf/afDz3MaZTVCfAP9z6/Bw6ycv8EUBWJIn9zYcoAWWlW9+OzO3vkTy8H+RANLmdrpOuYWdZYEXpo+TlCJrW5EARb7fF+bWdqf3hhyZI1nWJQHgznErZhbjoEsWqi8dQNoE294aldzFurwSABL2XXMf9+H1VQGke9exw5P/AnA5Pv5ngMul7LOvO922iwACu8WkCwLCafvM4CeWPxfA8lNHcWZSoi8EwMAIciKX2Z4SWCMAa3snCZ/G4EA8D6CMLNFsGQhkkz/gQNEBbPCbWsxGUpYVu3z8IyNAknwJkfPMEhLyrdi5RTyUVACkw4GSFRNWJNEW+fgPGwHD8/JxnRuLabN4CGNRkAE23na2+VmEAUmrYymSGjMAYqH84YUIyzgzs3XC7gNgH36Vcc4zKY9o9fgPBXUAiHHwVboBHGLiX6Zcjp1f2wu4tvzZKo0ecPnDtQYDQvJXaBeNzce45Fp28ZQLrEZVuFqgBwOalArKXnW1UzlnSusQKJqKYNuz4tOnI6sZG4zanpemv+7ySU2jbA9h6uhcgpfy6G2PahirDZ6zvq6zDduMVFTKvzw8wgyEdelwY9in3XkEPs3osJuwRQ4qTkfzifndg9Gfc4pdsu82+tTnHZTBa2EAMrqr2t43pguc8tNm7JQVQ2S0ukj2d22dhXYP0/veWtwKrCkNoNimAN5+Xr/oLrxswKbVJjteWrX7eR63o4j9q0GxnaBdWgGA5VStpanIjQmEhV0/nVt5VOFUvix6awJhPcAaTEShgrG+iGyvb5a0Ndb1YGHFPEwoqAinoaykaID1o1pdPNu7XsnCKQ3R+hwWIIhGvORcJUBYXe3Xa3vq/mF/N9V13ugufMkfXn+KHsRD0B8AAAAASUVORK5CYII=" type="image/x-icon" />
87
+ <html>
88
+ <head>
89
+ <meta charset="UTF-8" />
90
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
91
+ <title>${escape(title)}</title>
92
+ <link
93
+ rel="shortcut icon"
94
+ href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAMAAACdt4HsAAABrVBMVEUAAAD///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////+O1foceMD///+J0/qK1Pr7/v8Xdr/9///W8P4UdL7L7P0Scr2r4Pyj3vwad8D5/f/2/f+55f3E6f34+/2H0/ojfMKpzOd0rNgQcb3F3O/j9f7c8v6g3Pz0/P/w+v/q+P7n9v6T1/uQ1vuE0vqLut/y+v+Z2fvt+f+15Pzv9fuc2/vR7v2V2Pvd6/bg9P7I6/285/2y4/yp3/zp8vk8i8kqgMT7/P31+fyv4vxGkcz6/P6/6P3j7vfS5PNnpNUxhcbO7f7F6v3O4vHK3/DA2u631Ouy0eqXweKJud5wqthfoNMMbLvY8f73+v2dxeR8sNtTmdDx9/zX6PSjyeaCtd1YnNGX2PuQveCGt95Nls42h8dLlM3F4vBtAAAAM3RSTlMAAyOx0/sKBvik8opWGBMOAe3l1snDm2E9LSb06eHcu5JpHbarfHZCN9CBb08zzkdNS0kYaptYAAAFV0lEQVRYw92X51/aYBDHHS2O2qqttVbrqNq9m+TJIAYIShBkWwqIiCgoWvfeq7Z2/s29hyQNyUcR7LveGwVyXy6XH8/9rqxglLfUPLxVduUor3h0rfp2TYvpivk37929TkG037hffoX0+peVtZQc1589rigVUdXS/ABSAyEmGIO/1XfvldSK8vs3OqB6u3m0nxmIrvgB0dj7rr7Y9IbuF68hnfFaiHA/sxqm0wciIG43P60qKv9WXWc1RXGh/mFESFABTSBi0sNAKzqet17eCtOb3kZIDwxEEU0oAIJGYxNBDhBND29e0rtXXbcpuPmED9IhEAAQ/AXEaF8EPmnrrKsv0LvWR3fg5sWDNAFZOgAgaKvZDogHNU9MFwnnYROkc56RD5CjAbQX9Ow4g7upCsvYu55aSI/Nj0H1akgKQEUM94dwK65hYRmFU9MIcH/fqJYOZYcnuJSU/waKDgTOEVaVKhwrTRP5XzgSpAITYzom7UvkhFX5VutmxeNnWDjjswTKTyfgluNDGbUpWissXhF3s7mlSml+czWkg3D0l1nNjGNjz3myOQOa1KM/jOS6ebdbAVTCi4gljHSFrviza7tOgRWcS0MOUX9zdNgag5w7rRqA44Lzw0hr1WqES36dFliSJFlh2rXIae3FFcDDgKdxrUIDePr8jGcSClV1u7A9xeN0ModY/pHMxmR1EzRh8TJiwqsHmKW0l4FCEZI+jHio+JdPPE9qwQtTRxku2D8sIeRL2LnxWSllANCQGOIiqVHAz2ye2JR0DcH+HoxDkaADLjgxjKQ+AwCX/g0+DNgdG0ukYCONAe+dbc2IAc6fwt1ARoDSezNHxV2Cmzwv3O6lDMV55edBGwGK9n1+x2F8EDfAGCxug8MhpsMEcTEAWf3rx2vZhe/LAmtIn/6apE6PN0ULKgywD9mmdxbmFl3OvD5AS5fW5zLbv/YHmcsBTjf/afDz3MaZTVCfAP9z6/Bw6ycv8EUBWJIn9zYcoAWWlW9+OzO3vkTy8H+RANLmdrpOuYWdZYEXpo+TlCJrW5EARb7fF+bWdqf3hhyZI1nWJQHgznErZhbjoEsWqi8dQNoE294aldzFurwSABL2XXMf9+H1VQGke9exw5P/AnA5Pv5ngMul7LOvO922iwACu8WkCwLCafvM4CeWPxfA8lNHcWZSoi8EwMAIciKX2Z4SWCMAa3snCZ/G4EA8D6CMLNFsGQhkkz/gQNEBbPCbWsxGUpYVu3z8IyNAknwJkfPMEhLyrdi5RTyUVACkw4GSFRNWJNEW+fgPGwHD8/JxnRuLabN4CGNRkAE23na2+VmEAUmrYymSGjMAYqH84YUIyzgzs3XC7gNgH36Vcc4zKY9o9fgPBXUAiHHwVboBHGLiX6Zcjp1f2wu4tvzZKo0ecPnDtQYDQvJXaBeNzce45Fp28ZQLrEZVuFqgBwOalArKXnW1UzlnSusQKJqKYNuz4tOnI6sZG4zanpemv+7ySU2jbA9h6uhcgpfy6G2PahirDZ6zvq6zDduMVFTKvzw8wgyEdelwY9in3XkEPs3osJuwRQ4qTkfzifndg9Gfc4pdsu82+tTnHZTBa2EAMrqr2t43pguc8tNm7JQVQ2S0ukj2d22dhXYP0/veWtwKrCkNoNimAN5+Xr/oLrxswKbVJjteWrX7eR63o4j9q0GxnaBdWgGA5VStpanIjQmEhV0/nVt5VOFUvix6awJhPcAaTEShgrG+iGyvb5a0Ndb1YGHFPEwoqAinoaykaID1o1pdPNu7XsnCKQ3R+hwWIIhGvORcJUBYXe3Xa3vq/mF/N9V13ugufMkfXn+KHsRD0B8AAAAASUVORK5CYII="
95
+ type="image/x-icon"
96
+ />
53
97
 
54
- <script>
55
- window.enableWebSocket = ${escapeJson(enableWebSocket)};
56
- </script>
57
- ${getScript('viewer.js', mode)}
58
- </head>
98
+ <script>
99
+ window.enableWebSocket = ${escapeJson(enableWebSocket)};
100
+ </script>
101
+ ${getScript("viewer.js", mode)}
102
+ </head>
59
103
 
60
- <body>
61
- <div id="app"></div>
62
- <script>
63
- window.chartData = ${escapeJson(chartData)};
64
- window.entrypoints = ${escapeJson(entrypoints)};
65
- window.defaultSizes = ${escapeJson(defaultSizes)};
66
- window.compressionAlgorithm = ${escapeJson(compressionAlgorithm)};
67
- </script>
68
- </body>
69
- </html>`;
70
- }
104
+ <body>
105
+ <div id="app"></div>
106
+ <script>
107
+ window.chartData = ${escapeJson(chartData)};
108
+ window.entrypoints = ${escapeJson(entrypoints)};
109
+ window.defaultSizes = ${escapeJson(defaultSizes)};
110
+ window.compressionAlgorithm = ${escapeJson(compressionAlgorithm)};
111
+ </script>
112
+ </body>
113
+ </html>`;
114
+ }
115
+ module.exports = {
116
+ renderViewer
117
+ };
@@ -4,28 +4,69 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.default = void 0;
7
- var _Node = _interopRequireDefault(require("./Node"));
7
+ var _Node = _interopRequireDefault(require("./Node.js"));
8
8
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
9
+ /** @typedef {import("./Folder").default} Folder */
10
+ /** @typedef {import("./Module").default} Module */
11
+ /** @typedef {import("./Module").ModuleChartData} ModuleChartData */
12
+ /** @typedef {import("./ConcatenatedModule").default} ConcatenatedModule */
13
+ /** @typedef {import("./ContentModule").default} ContentModule */
14
+ /** @typedef {import("./ContentFolder").default} ContentFolder */
15
+ /** @typedef {import("./ContentFolder").ContentFolderChartData} ContentFolderChartData */
16
+ /** @typedef {import("./Folder").FolderChartData} FolderChartData */
17
+
18
+ /**
19
+ * @typedef {object} BaseFolderChartData
20
+ * @property {string} label label
21
+ * @property {string} path path
22
+ * @property {number} statSize stat size
23
+ * @property {(FolderChartData | ModuleChartData | ContentFolderChartData)[]} groups groups
24
+ */
25
+
26
+ /** @typedef {Module | ContentModule | ConcatenatedModule | ContentFolder | Folder} Children */
27
+
9
28
  class BaseFolder extends _Node.default {
29
+ /**
30
+ * @param {string} name name
31
+ * @param {Node=} parent parent
32
+ */
10
33
  constructor(name, parent) {
11
34
  super(name, parent);
35
+ /** @type {Record<string, Children>} */
12
36
  this.children = Object.create(null);
13
37
  }
38
+
39
+ /**
40
+ * @returns {string} src
41
+ */
14
42
  get src() {
15
- if (!Object.prototype.hasOwnProperty.call(this, '_src')) {
16
- this._src = this.walk((node, src) => src += node.src || '', '', false);
43
+ if (!Object.hasOwn(this, "_src")) {
44
+ this._src = this.walk((node, src) => src += node.src || "", /** @type {string} */"", false);
17
45
  }
18
- return this._src;
46
+ return /** @type {string} */this._src;
19
47
  }
48
+
49
+ /**
50
+ * @returns {number} size
51
+ */
20
52
  get size() {
21
- if (!Object.prototype.hasOwnProperty.call(this, '_size')) {
22
- this._size = this.walk((node, size) => size + node.size, 0, false);
53
+ if (!Object.hasOwn(this, "_size")) {
54
+ this._size = this.walk((node, size) => size + node.size, /** @type {number} */0, false);
23
55
  }
24
- return this._size;
56
+ return /** @type {number} */this._size;
25
57
  }
58
+
59
+ /**
60
+ * @param {string} name name
61
+ * @returns {Children} child
62
+ */
26
63
  getChild(name) {
27
64
  return this.children[name];
28
65
  }
66
+
67
+ /**
68
+ * @param {Module | ContentModule | ConcatenatedModule} module module
69
+ */
29
70
  addChildModule(module) {
30
71
  const {
31
72
  name
@@ -46,6 +87,11 @@ class BaseFolder extends _Node.default {
46
87
  delete this._size;
47
88
  delete this._src;
48
89
  }
90
+
91
+ /**
92
+ * @param {ContentFolder | Folder} folder folder
93
+ * @returns {ContentFolder | Folder} folder
94
+ */
49
95
  addChildFolder(folder) {
50
96
  folder.parent = this;
51
97
  this.children[folder.name] = folder;
@@ -53,43 +99,59 @@ class BaseFolder extends _Node.default {
53
99
  delete this._src;
54
100
  return folder;
55
101
  }
56
- walk(walker, state = {}, deep = true) {
102
+
103
+ /**
104
+ * @template T
105
+ * @param {(node: Children, state: T, stop: (state: T) => void) => T} walker walker function
106
+ * @param {T} state state state
107
+ * @param {boolean | ((state: T) => T)=} deep true when need to deep walk, otherwise false
108
+ * @returns {T} state
109
+ */
110
+ walk(walker, state = (/** @type T */{}), deep = true) {
57
111
  let stopped = false;
58
- Object.values(this.children).forEach(child => {
59
- if (deep && child.walk) {
60
- state = child.walk(walker, state, stop);
61
- } else {
62
- state = walker(child, state, stop);
63
- }
64
- if (stopped) return false;
65
- });
66
- return state;
112
+
113
+ /**
114
+ * @param {T} finalState final state
115
+ * @returns {T} final state
116
+ */
67
117
  function stop(finalState) {
68
118
  stopped = true;
69
119
  return finalState;
70
120
  }
121
+ for (const child of Object.values(this.children)) {
122
+ state = deep && /** @type {BaseFolder} */child.walk ? /** @type {BaseFolder} */child.walk(walker, state, stop) : walker(child, state, stop);
123
+ if (stopped) return /** @type {T} */false;
124
+ }
125
+ return state;
71
126
  }
72
127
  mergeNestedFolders() {
73
128
  if (!this.isRoot) {
74
129
  let childNames;
75
130
  while ((childNames = Object.keys(this.children)).length === 1) {
76
- const childName = childNames[0];
131
+ const [childName] = childNames;
77
132
  const onlyChild = this.children[childName];
78
133
  if (onlyChild instanceof this.constructor) {
79
134
  this.name += `/${onlyChild.name}`;
80
- this.children = onlyChild.children;
135
+ this.children = /** @type {BaseFolder} */onlyChild.children;
81
136
  } else {
82
137
  break;
83
138
  }
84
139
  }
85
140
  }
86
- this.walk(child => {
141
+ this.walk((child, state) => {
87
142
  child.parent = this;
88
- if (child.mergeNestedFolders) {
143
+ if (/** @type {Folder | ContentFolder | ConcatenatedModule} */
144
+ child.mergeNestedFolders) {
145
+ /** @type {Folder | ContentFolder | ConcatenatedModule} */
89
146
  child.mergeNestedFolders();
90
147
  }
148
+ return state;
91
149
  }, null, false);
92
150
  }
151
+
152
+ /**
153
+ * @returns {BaseFolderChartData} base folder chart data
154
+ */
93
155
  toChartData() {
94
156
  return {
95
157
  label: this.name,
@@ -99,5 +161,4 @@ class BaseFolder extends _Node.default {
99
161
  };
100
162
  }
101
163
  }
102
- exports.default = BaseFolder;
103
- ;
164
+ exports.default = BaseFolder;
@@ -4,73 +4,135 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.default = void 0;
7
- var _Module = _interopRequireDefault(require("./Module"));
8
- var _ContentModule = _interopRequireDefault(require("./ContentModule"));
9
- var _ContentFolder = _interopRequireDefault(require("./ContentFolder"));
10
- var _utils = require("./utils");
7
+ var _ContentFolder = _interopRequireDefault(require("./ContentFolder.js"));
8
+ var _ContentModule = _interopRequireDefault(require("./ContentModule.js"));
9
+ var _Module = _interopRequireDefault(require("./Module.js"));
10
+ var _utils = require("./utils.js");
11
11
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
12
+ /** @typedef {import("webpack").StatsModule} StatsModule */
13
+ /** @typedef {import("./Node").default} NodeType */
14
+ /** @typedef {import("./Module").ModuleChartData} ModuleChartData */
15
+ /** @typedef {import("./Module").SizeType} SizeType */
16
+ /** @typedef {import("./Folder").default} Folder */
17
+ /** @typedef {import("./BaseFolder").Children} Children */
18
+ /** @typedef {import("./ContentFolder").ContentFolderChartData} ContentFolderChartData */
19
+ /** @typedef {import("./ContentModule").ContentModuleChartData} ContentModuleChartData */
20
+ /** @typedef {import("../sizeUtils").Algorithm} CompressionAlgorithm */
21
+
22
+ /**
23
+ * @typedef {object} OwnConcatenatedModuleChartData
24
+ * @property {boolean} concatenated true when concatenated, otherwise false
25
+ * @property {(ConcatenatedModuleChartData | ContentFolderChartData | ContentModuleChartData)[]} groups groups
26
+ */
27
+
28
+ /** @typedef {ModuleChartData & OwnConcatenatedModuleChartData} ConcatenatedModuleChartData */
29
+
12
30
  class ConcatenatedModule extends _Module.default {
31
+ /**
32
+ * @param {string} name name
33
+ * @param {StatsModule} data data
34
+ * @param {NodeType} parent parent
35
+ * @param {{ compressionAlgorithm: CompressionAlgorithm }} opts options
36
+ */
13
37
  constructor(name, data, parent, opts) {
14
38
  super(name, data, parent, opts);
15
- this.name += ' (concatenated)';
39
+ this.name += " (concatenated)";
40
+ /** @type {Record<string, ConcatenatedModule | ContentModule | ContentFolder>} */
16
41
  this.children = Object.create(null);
17
42
  this.fillContentModules();
18
43
  }
19
44
  get parsedSize() {
20
- return this.getParsedSize() ?? this.getEstimatedSize('parsedSize');
45
+ return this.getParsedSize() ?? this.getEstimatedSize("parsedSize");
21
46
  }
22
47
  get gzipSize() {
23
- return this.getGzipSize() ?? this.getEstimatedSize('gzipSize');
48
+ return this.getGzipSize() ?? this.getEstimatedSize("gzipSize");
24
49
  }
25
50
  get brotliSize() {
26
- return this.getBrotliSize() ?? this.getEstimatedSize('brotliSize');
51
+ return this.getBrotliSize() ?? this.getEstimatedSize("brotliSize");
52
+ }
53
+ get zstdSize() {
54
+ return this.getZstdSize() ?? this.getEstimatedSize("zstdSize");
27
55
  }
56
+
57
+ /**
58
+ * @param {SizeType} sizeType size type
59
+ * @returns {number | undefined} size
60
+ */
28
61
  getEstimatedSize(sizeType) {
29
- const parentModuleSize = this.parent[sizeType];
62
+ const parentModuleSize = /** @type {Folder} */this.parent[sizeType];
30
63
  if (parentModuleSize !== undefined) {
31
- return Math.floor(this.size / this.parent.size * parentModuleSize);
64
+ return Math.floor(this.size / /** @type {Folder} */this.parent.size * parentModuleSize);
32
65
  }
33
66
  }
34
67
  fillContentModules() {
35
- this.data.modules.forEach(moduleData => this.addContentModule(moduleData));
68
+ for (const moduleData of this.data.modules || []) {
69
+ this.addContentModule(moduleData);
70
+ }
36
71
  }
72
+
73
+ /**
74
+ * @param {StatsModule} moduleData module data
75
+ */
37
76
  addContentModule(moduleData) {
38
77
  const pathParts = (0, _utils.getModulePathParts)(moduleData);
39
78
  if (!pathParts) {
40
79
  return;
41
80
  }
42
81
  const [folders, fileName] = [pathParts.slice(0, -1), pathParts[pathParts.length - 1]];
82
+ /** @type {ConcatenatedModule | ContentFolder} */
43
83
  let currentFolder = this;
44
- folders.forEach(folderName => {
84
+ for (const folderName of folders) {
85
+ /** @type {Children} */
45
86
  let childFolder = currentFolder.getChild(folderName);
46
87
  if (!childFolder) {
47
88
  childFolder = currentFolder.addChildFolder(new _ContentFolder.default(folderName, this));
48
89
  }
49
- currentFolder = childFolder;
50
- });
90
+ currentFolder = /** @type {ConcatenatedModule | ContentFolder} */
91
+ childFolder;
92
+ }
51
93
  const ModuleConstructor = moduleData.modules ? ConcatenatedModule : _ContentModule.default;
52
94
  const module = new ModuleConstructor(fileName, moduleData, this, this.opts);
53
95
  currentFolder.addChildModule(module);
54
96
  }
97
+
98
+ /**
99
+ * @param {string} name name
100
+ * @returns {ConcatenatedModule | ContentModule | ContentFolder} child folder
101
+ */
55
102
  getChild(name) {
56
103
  return this.children[name];
57
104
  }
105
+
106
+ /**
107
+ * @param {ConcatenatedModule | ContentModule} module child module
108
+ */
58
109
  addChildModule(module) {
59
110
  module.parent = this;
60
111
  this.children[module.name] = module;
61
112
  }
113
+
114
+ /**
115
+ * @param {ContentFolder} folder child folder
116
+ * @returns {ContentFolder} child folder
117
+ */
62
118
  addChildFolder(folder) {
63
119
  folder.parent = this;
64
120
  this.children[folder.name] = folder;
65
121
  return folder;
66
122
  }
67
123
  mergeNestedFolders() {
68
- Object.values(this.children).forEach(child => {
69
- if (child.mergeNestedFolders) {
124
+ for (const child of Object.values(this.children)) {
125
+ if (/** @type {Folder | ContentFolder | ConcatenatedModule} */
126
+ child.mergeNestedFolders) {
127
+ /** @type {Folder | ContentFolder | ConcatenatedModule} */
70
128
  child.mergeNestedFolders();
71
129
  }
72
- });
130
+ }
73
131
  }
132
+
133
+ /**
134
+ * @returns {ConcatenatedModuleChartData} chart data
135
+ */
74
136
  toChartData() {
75
137
  return {
76
138
  ...super.toChartData(),
@@ -79,5 +141,4 @@ class ConcatenatedModule extends _Module.default {
79
141
  };
80
142
  }
81
143
  }
82
- exports.default = ConcatenatedModule;
83
- ;
144
+ exports.default = ConcatenatedModule;
@@ -4,37 +4,70 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.default = void 0;
7
- var _BaseFolder = _interopRequireDefault(require("./BaseFolder"));
7
+ var _BaseFolder = _interopRequireDefault(require("./BaseFolder.js"));
8
8
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
9
+ /** @typedef {import("./Node").default} Node */
10
+ /** @typedef {import("./ConcatenatedModule").default} ConcatenatedModule */
11
+ /** @typedef {import("./BaseFolder").BaseFolderChartData} BaseFolderChartData */
12
+ /** @typedef {import("./Module").SizeType} SizeType */
13
+
14
+ /**
15
+ * @typedef {object} OwnContentFolderChartData
16
+ * @property {number | undefined} parsedSize parsed size
17
+ * @property {number | undefined} gzipSize gzip size
18
+ * @property {number | undefined} brotliSize brotli size
19
+ * @property {number | undefined} zstdSize zstd size
20
+ * @property {boolean} inaccurateSizes true when inaccurate sizes, otherwise false
21
+ */
22
+
23
+ /** @typedef {BaseFolderChartData & OwnContentFolderChartData} ContentFolderChartData */
24
+
9
25
  class ContentFolder extends _BaseFolder.default {
26
+ /**
27
+ * @param {string} name name
28
+ * @param {ConcatenatedModule} ownerModule owner module
29
+ * @param {Node=} parent v
30
+ */
10
31
  constructor(name, ownerModule, parent) {
11
32
  super(name, parent);
12
33
  this.ownerModule = ownerModule;
13
34
  }
14
35
  get parsedSize() {
15
- return this.getSize('parsedSize');
36
+ return this.getSize("parsedSize");
16
37
  }
17
38
  get gzipSize() {
18
- return this.getSize('gzipSize');
39
+ return this.getSize("gzipSize");
19
40
  }
20
41
  get brotliSize() {
21
- return this.getSize('brotliSize');
42
+ return this.getSize("brotliSize");
22
43
  }
44
+ get zstdSize() {
45
+ return this.getSize("zstdSize");
46
+ }
47
+
48
+ /**
49
+ * @param {SizeType} sizeType size type
50
+ * @returns {number | undefined} size
51
+ */
23
52
  getSize(sizeType) {
24
53
  const ownerModuleSize = this.ownerModule[sizeType];
25
54
  if (ownerModuleSize !== undefined) {
26
55
  return Math.floor(this.size / this.ownerModule.size * ownerModuleSize);
27
56
  }
28
57
  }
58
+
59
+ /**
60
+ * @returns {ContentFolderChartData} chart data
61
+ */
29
62
  toChartData() {
30
63
  return {
31
64
  ...super.toChartData(),
32
65
  parsedSize: this.parsedSize,
33
66
  gzipSize: this.gzipSize,
34
67
  brotliSize: this.brotliSize,
68
+ zstdSize: this.zstdSize,
35
69
  inaccurateSizes: true
36
70
  };
37
71
  }
38
72
  }
39
- exports.default = ContentFolder;
40
- ;
73
+ exports.default = ContentFolder;
@@ -4,28 +4,61 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.default = void 0;
7
- var _Module = _interopRequireDefault(require("./Module"));
7
+ var _Module = _interopRequireDefault(require("./Module.js"));
8
8
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
9
+ /** @typedef {import("webpack").StatsModule} StatsModule */
10
+ /** @typedef {import("./Node").default} NodeType */
11
+ /** @typedef {import("./Module").ModuleChartData} ModuleChartData */
12
+ /** @typedef {import("./Module").ModuleOptions} ModuleOptions */
13
+ /** @typedef {import("./Module").SizeType} SizeType */
14
+ /** @typedef {import("./ConcatenatedModule").default} ConcatenatedModule */
15
+
16
+ /**
17
+ * @typedef {object} OwnContentModuleChartData
18
+ * @property {boolean} inaccurateSizes true when inaccurate sizes, otherwise false
19
+ */
20
+
21
+ /** @typedef {ModuleChartData & OwnContentModuleChartData} ContentModuleChartData */
22
+
9
23
  class ContentModule extends _Module.default {
10
- constructor(name, data, ownerModule, parent) {
11
- super(name, data, parent);
24
+ /**
25
+ * @param {string} name name
26
+ * @param {StatsModule} data data
27
+ * @param {ConcatenatedModule} ownerModule owner module
28
+ * @param {ModuleOptions} opts options
29
+ */
30
+ constructor(name, data, ownerModule, opts) {
31
+ super(name, data, undefined, opts);
32
+ /** @type {ConcatenatedModule} */
12
33
  this.ownerModule = ownerModule;
13
34
  }
14
35
  get parsedSize() {
15
- return this.getSize('parsedSize');
36
+ return this.getSize("parsedSize");
16
37
  }
17
38
  get gzipSize() {
18
- return this.getSize('gzipSize');
39
+ return this.getSize("gzipSize");
19
40
  }
20
41
  get brotliSize() {
21
- return this.getSize('brotliSize');
42
+ return this.getSize("brotliSize");
22
43
  }
44
+ get zstdSize() {
45
+ return this.getSize("zstdSize");
46
+ }
47
+
48
+ /**
49
+ * @param {SizeType} sizeType size type
50
+ * @returns {number | undefined} size
51
+ */
23
52
  getSize(sizeType) {
24
53
  const ownerModuleSize = this.ownerModule[sizeType];
25
54
  if (ownerModuleSize !== undefined) {
26
55
  return Math.floor(this.size / this.ownerModule.size * ownerModuleSize);
27
56
  }
28
57
  }
58
+
59
+ /**
60
+ * @returns {ContentModuleChartData} chart data
61
+ */
29
62
  toChartData() {
30
63
  return {
31
64
  ...super.toChartData(),
@@ -33,5 +66,4 @@ class ContentModule extends _Module.default {
33
66
  };
34
67
  }
35
68
  }
36
- exports.default = ContentModule;
37
- ;
69
+ exports.default = ContentModule;