react-native-bundle-discovery-ui 2.6.0 → 2.7.0-rc.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/dist/bin.js ADDED
@@ -0,0 +1,202 @@
1
+ #!/usr/bin/env node
2
+ const require_rolldown_runtime = require("./rolldown-runtime-VH7oDXx4.js");
3
+ const require_src = require("./src-BSLX-He2.js");
4
+ const require_discoveryrc = require("./discoveryrc.js");
5
+ let minimist = require("minimist");
6
+ minimist = require_rolldown_runtime.__toESM(minimist);
7
+ let node_fs = require("node:fs");
8
+ node_fs = require_rolldown_runtime.__toESM(node_fs);
9
+ let node_path = require("node:path");
10
+ node_path = require_rolldown_runtime.__toESM(node_path);
11
+ let _discoveryjs_cli = require("@discoveryjs/cli");
12
+ let chalk = require("chalk");
13
+ chalk = require_rolldown_runtime.__toESM(chalk);
14
+ let _discoveryjs_cli_lib_shared_utils_js = require("@discoveryjs/cli/lib/shared/utils.js");
15
+ //#region src/build.ts
16
+ function buildHtmlPage(filePath, output, clean, singleFile, verbose) {
17
+ if (verbose) console.info(`Building HTML page from file: ${chalk.default.green(filePath)} options: ${JSON.stringify({
18
+ output,
19
+ clean,
20
+ singleFile
21
+ }, null, 2)}`);
22
+ if (!filePath) {
23
+ console.error(`Usage: '${chalk.default.green("npx react-native-bundle-discovery build <path-to-file>")}', Please provide a path to a JSON file.`);
24
+ process.exit(1);
25
+ }
26
+ const jsonFilePath = node_path.default.resolve(process.cwd(), filePath);
27
+ if (verbose) console.info(`Loading JSON file from: ${chalk.default.green(jsonFilePath)}, base directory: ${chalk.default.green(process.cwd())}`);
28
+ let fullJsonPath;
29
+ try {
30
+ fullJsonPath = require.resolve(jsonFilePath);
31
+ } catch (err) {
32
+ console.error(`❌Error loading file: ${chalk.default.red(jsonFilePath)}\n\n`);
33
+ console.error(err.message);
34
+ process.exit(1);
35
+ }
36
+ const configFile = node_path.default.resolve(__dirname, "./.tmp.js");
37
+ if (verbose) console.info(`Creating temporary config file at: ${chalk.default.green(configFile)}, for discovery.js`);
38
+ const transformRcdoctor = node_path.default.join(__dirname, "rsdoctor.js");
39
+ node_fs.default.writeFileSync(configFile, `const {transformRSDoctorData} = require("${transformRcdoctor}");
40
+ module.exports = ${JSON.stringify({
41
+ ...require_discoveryrc,
42
+ data: "<tmp>"
43
+ }, null, 1).replace(`"<tmp>"`, require_src.isRsdoctorReportPath(fullJsonPath) ? `() => transformRSDoctorData(require("${fullJsonPath}"))` : `() => require("${fullJsonPath}")`)};`);
44
+ if (verbose) console.info(`Building HTML page with options:`, {
45
+ output,
46
+ clean,
47
+ singleFile
48
+ });
49
+ const _config = {
50
+ name: "Bundle Discovery",
51
+ mode: "single",
52
+ colorScheme: "auto",
53
+ download: true,
54
+ upload: false,
55
+ embed: false,
56
+ encodings: false
57
+ };
58
+ const _options = {
59
+ singleFile,
60
+ clean,
61
+ output,
62
+ cache: true,
63
+ cachedir: node_path.default.resolve(__dirname, "./.discoveryjs-cache"),
64
+ checkCacheTtl: false,
65
+ minify: true,
66
+ dataCompression: true,
67
+ sourcemap: false,
68
+ embed: "by-config",
69
+ experimentalJsonxl: false,
70
+ scriptFormat: "esm",
71
+ scriptExternal: [],
72
+ data: true,
73
+ excludeModelOnDataFail: false,
74
+ prettyData: false,
75
+ modelDownload: false,
76
+ modelDataUpload: true,
77
+ modelResetCache: false,
78
+ serveOnlyAssets: true,
79
+ dev: true,
80
+ config: configFile,
81
+ configFile
82
+ };
83
+ return (0, _discoveryjs_cli.build)(_options, _config, configFile).then(() => {
84
+ console.log(`========================================`);
85
+ console.log(`✅ HTML page built successfully at: ${chalk.default.green(node_path.default.resolve(output, "index.html").replace(`${process.cwd()}/`, ""))}`);
86
+ console.log(`========================================`);
87
+ });
88
+ }
89
+ //#endregion
90
+ //#region src/server.ts
91
+ function serve(filePath, port, verbose) {
92
+ const PORT = process.env.PORT || port;
93
+ if (verbose) console.info(`start server with file: ${filePath} on port: ${port} ${process.env.PORT ? `(${chalk.default.yellow("PORT")} env)` : ""}`);
94
+ if (!filePath) {
95
+ console.error(`Usage: '${chalk.default.green("npx react-native-bundle-discovery server <path-to-file>")}', Please provide a path to a JSON file.`);
96
+ process.exit(1);
97
+ }
98
+ const jsonFilePath = node_path.default.resolve(process.cwd(), filePath);
99
+ if (verbose) console.info(`Loading JSON file from: ${chalk.default.green(jsonFilePath)}, base directory: ${chalk.default.green(process.cwd())}`);
100
+ let fullJsonPath;
101
+ try {
102
+ fullJsonPath = require.resolve(jsonFilePath);
103
+ } catch (err) {
104
+ console.error(`❌Error loading file: ${chalk.default.red(jsonFilePath)}\n\n`);
105
+ console.error(err.message);
106
+ process.exit(1);
107
+ }
108
+ const configFile = node_path.default.resolve(__dirname, "./.tmp.js");
109
+ if (verbose) console.info(`Creating temporary config file at: ${chalk.default.green(configFile)}, for discovery.js`);
110
+ const transformRcdoctor = node_path.default.join(__dirname, "rsdoctor.js");
111
+ node_fs.default.writeFileSync(configFile, `const {transformRSDoctorData} = require("${transformRcdoctor}");
112
+ module.exports = ${JSON.stringify({
113
+ ...require_discoveryrc,
114
+ data: "<tmp>"
115
+ }, null, 1).replace(`"<tmp>"`, require_src.isRsdoctorReportPath(fullJsonPath) ? `() => transformRSDoctorData(require("${fullJsonPath}"))` : `() => require("${fullJsonPath}")`)};`);
116
+ if (verbose) console.info(`Running server with config: ${chalk.default.green(configFile)}`);
117
+ return (0, _discoveryjs_cli_lib_shared_utils_js.silent)(() => (0, _discoveryjs_cli.createServer)({
118
+ cache: false,
119
+ minify: true,
120
+ dev: false,
121
+ config: configFile,
122
+ configFile
123
+ }).then((server) => server.listen(PORT, () => {
124
+ console.log(`[react-native-bundle-discovery]: 🚀 Server listen on ${chalk.default.green.underline(chalk.default.green(`http://localhost:${PORT}`))}`);
125
+ })));
126
+ }
127
+ //#endregion
128
+ //#region src/bin.ts
129
+ function printHelp() {
130
+ console.log(`react-native-bundle-discovery-ui
131
+
132
+ Usage:
133
+ react-native-bundle-discovery-ui <file> [port] [--verbose] # <- server can be omitted
134
+ react-native-bundle-discovery-ui server <file> [port] [--verbose]
135
+
136
+ react-native-bundle-discovery-ui build <file> [--output <path>] [--clean] [--single-file] [--verbose]
137
+
138
+ Commands:
139
+ server <file> [port] Run a web server to show a Metro bundler stat report
140
+ build <file> Build a HTML report from the Metro bundler stat file
141
+
142
+ Options:
143
+ -v, --verbose Run with verbose logging
144
+ -o, --output <path> Path for a build result (default: .bundle-discovery)
145
+ -c, --clean Clean output directory before writing build files (default: true)
146
+ -s, --single-file Output report build as a single HTML file (default: true)
147
+ -p, --port <port> Port for server command (same as [port], default: 8079)
148
+ -h, --help Show help
149
+ `);
150
+ }
151
+ function fail(message) {
152
+ console.error(message);
153
+ console.error("Use --help to see usage.");
154
+ process.exit(1);
155
+ }
156
+ function main() {
157
+ const argv = (0, minimist.default)(process.argv.slice(2), {
158
+ alias: {
159
+ v: "verbose",
160
+ h: "help",
161
+ o: "output",
162
+ c: "clean",
163
+ s: "single-file",
164
+ p: "port"
165
+ },
166
+ boolean: [
167
+ "verbose",
168
+ "help",
169
+ "clean",
170
+ "single-file"
171
+ ],
172
+ string: ["output"],
173
+ default: {
174
+ clean: true,
175
+ "single-file": true
176
+ }
177
+ });
178
+ const command = argv._[0];
179
+ const isServerCommand = command === "server";
180
+ const isBuildCommand = command === "build";
181
+ const isImplicitServerCommand = Boolean(command) && !isServerCommand && !isBuildCommand;
182
+ if (argv.help || !command) {
183
+ printHelp();
184
+ process.exit(0);
185
+ }
186
+ if (isServerCommand || isImplicitServerCommand) {
187
+ const file = isImplicitServerCommand ? argv._[0] : argv._[1];
188
+ if (!file) fail("Missing required argument: <file>");
189
+ const rawPort = argv.port ?? (isImplicitServerCommand ? argv._[1] : argv._[2]) ?? 8079;
190
+ const port = Number(rawPort);
191
+ if (!Number.isFinite(port)) fail(`Invalid port: ${rawPort}`);
192
+ return serve(file, port, Boolean(argv.verbose));
193
+ }
194
+ if (isBuildCommand) {
195
+ const file = argv._[1];
196
+ if (!file) fail("Missing required argument: <file>");
197
+ return buildHtmlPage(file, argv.output, argv.clean, argv["single-file"], Boolean(argv.verbose));
198
+ }
199
+ fail(`Unknown command: ${command}`);
200
+ }
201
+ main();
202
+ //#endregion
@@ -0,0 +1,23 @@
1
+ //#region \0rolldown/runtime.js
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __copyProps = (to, from, except, desc) => {
9
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
10
+ key = keys[i];
11
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
12
+ get: ((k) => from[k]).bind(null, key),
13
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
14
+ });
15
+ }
16
+ return to;
17
+ };
18
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule || !__hasOwnProp.call(mod, "default") ? __defProp(target, "default", {
19
+ value: mod,
20
+ enumerable: true
21
+ }) : target, mod));
22
+ //#endregion
23
+ exports.__toESM = __toESM;
@@ -0,0 +1,282 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ //#region src/client/pages/_common.ts
3
+ const platformColor = `transformOptions.platform = 'android' ? 'rgba(194, 239, 116, .4)' : 'rgba(119, 31, 218, .4)'`;
4
+ function getPackage(entry) {
5
+ return `
6
+ $packages: $.packages;
7
+ $totalSize: $.modules.sum(=>output.sizeInBytes);
8
+ $toModule: => {
9
+ ext: $.path.getFileExtension(),
10
+ name: $.path,
11
+ size: $.output.sizeInBytes.formatBytes(),
12
+ percent: ($.output.sizeInBytes / $totalSize).percent(3),
13
+ };
14
+
15
+ ${entry}.group(=> path.getModulesName())
16
+ .map(=> ({
17
+ $pkgName: $.key;
18
+ pkgName: $pkgName, // example: lodash
19
+ size: $.value.sum(=>output.sizeInBytes),
20
+ pkgInstances: $.value
21
+ .group(=> path.split('node_modules/' + $pkgName).pick(0) + 'node_modules/' + $pkgName)
22
+ .map(=> {
23
+ $pkgNameWithPath: $.key;
24
+ $pkgInfo: $packages.[path = $pkgNameWithPath][0];
25
+ pkgName: $pkgNameWithPath, // example: node_modules/lodash
26
+ version: $pkgInfo.version,
27
+ metadata: $pkgInfo.metadata,
28
+ size: $.value.sum(=> output.sizeInBytes),
29
+ modules: $.value.map(=> $.$toModule()),
30
+ }),
31
+ }))`;
32
+ }
33
+ const metadataTooltip = {
34
+ view: "text",
35
+ when: "metadata.createdAt",
36
+ data: "'Published ' + metadata.createdAt.formatDate() + ' (' + metadata.createdAt.timeAgo() + ')'"
37
+ };
38
+ const outdatedColor = "rgba(255, 165, 0, 0.35)";
39
+ function getMetadataBadges({ deprecated, outdated, latestVersion, renderLatestVersion }) {
40
+ return [{
41
+ view: "pill-badge",
42
+ when: deprecated,
43
+ data: `{ text: '⚠️ deprecated', message: ${deprecated} }`,
44
+ color: "#cf222e",
45
+ textColor: "white",
46
+ darkColor: "#f85149",
47
+ darkTextColor: "white",
48
+ tooltip: "text: message"
49
+ }, renderLatestVersion ? {
50
+ view: "pill-badge",
51
+ when: outdated,
52
+ data: `{ text: '↑ v' + ${latestVersion} }`,
53
+ color: outdatedColor,
54
+ tooltip: "text: 'Latest version on npm'"
55
+ } : null].filter(Boolean);
56
+ }
57
+ function getPackageList({ data, itemPkgName, showCopiesBadge, expanded, limit, subLimit }) {
58
+ return {
59
+ view: "list",
60
+ data,
61
+ emptyText: "⚠️ No packages found",
62
+ limit,
63
+ item: {
64
+ view: "tree",
65
+ expanded,
66
+ itemConfig: {
67
+ content: [
68
+ itemPkgName,
69
+ "text: ' '",
70
+ "pill-badge:{ text: size.formatBytes(), color: 'rgba(120, 177, 9, 0.35)' }",
71
+ ...getMetadataBadges({
72
+ deprecated: "pkgInstances.metadata.deprecated[0]",
73
+ outdated: "pkgInstances.[metadata and not metadata.isLatest]",
74
+ latestVersion: "pkgInstances.metadata.latestVersion[0]",
75
+ renderLatestVersion: false
76
+ }),
77
+ showCopiesBadge ? {
78
+ view: "pill-badge",
79
+ when: "pkgInstances.size() > 1",
80
+ data: "(pkgInstances.size() - 1).pluralBadge(['copy','copies'], '+')",
81
+ color: "rgba(255, 0, 0, 0.35)"
82
+ } : null,
83
+ {
84
+ view: "pill-badge",
85
+ data: "pkgInstances.modules.size().pluralBadge(['file','files'])"
86
+ }
87
+ ].filter(Boolean),
88
+ children: `$.pkgInstances`,
89
+ itemConfig: {
90
+ view: "tree-leaf",
91
+ limit: subLimit,
92
+ content: [
93
+ "text:pkgName",
94
+ "text:' '",
95
+ {
96
+ view: "pill-badge",
97
+ data: "{ text: 'v' + version, metadata }",
98
+ color: "#0af",
99
+ tooltip: metadataTooltip
100
+ },
101
+ "pill-badge:{ text: size.formatBytes(), color: 'rgba(120, 177, 9, 0.35)' }",
102
+ {
103
+ view: "pill-badge",
104
+ data: "modules.size().pluralBadge(['file','files'])"
105
+ },
106
+ ...getMetadataBadges({
107
+ deprecated: "metadata.deprecated",
108
+ outdated: "metadata and not metadata.isLatest",
109
+ latestVersion: "metadata.latestVersion",
110
+ renderLatestVersion: true
111
+ })
112
+ ],
113
+ children: `$.modules`,
114
+ itemConfig: {
115
+ view: "tree-leaf",
116
+ content: getTreeModule({ hasPercent: true })
117
+ }
118
+ }
119
+ }
120
+ }
121
+ };
122
+ }
123
+ function getTreeModule({ hasTextMatch = false, hasPercent = false } = {}) {
124
+ return [
125
+ "pill-badge:{ text: ext, color: ext.getExtColor() }",
126
+ hasTextMatch ? {
127
+ view: "link",
128
+ content: hasTextMatch ? "text-match" : "text",
129
+ data: `{
130
+ href: name.pageLink("module", {}),
131
+ text: name,
132
+ match: #.filterByPathStr
133
+ }`
134
+ } : {
135
+ view: "link",
136
+ data: `{ href: $.name.pageLink("module", {}), text: $.name }`
137
+ },
138
+ "text:' '",
139
+ {
140
+ view: "badge",
141
+ when: "isEntry",
142
+ text: "Entrypoint",
143
+ color: "gold",
144
+ textColor: "black"
145
+ },
146
+ "pill-badge:{ text: size, color: 'rgba(120, 177, 9, 0.35)' }",
147
+ hasPercent ? "pill-badge:{ text: percent, color: 'rgba(120, 177, 9, 0.35)' }" : null
148
+ ].filter(Boolean);
149
+ }
150
+ function getModulesTree({ data, limit }) {
151
+ if (!data) throw new Error("[getModulesTree]: data is required");
152
+ return {
153
+ view: "content-filter",
154
+ data,
155
+ name: "filterByPathStr",
156
+ content: {
157
+ view: "list",
158
+ limit,
159
+ data: ".[name ~= #.filterByPathStr]",
160
+ emptyText: "⚠️ No modules found",
161
+ item: {
162
+ view: "tree",
163
+ expanded: false,
164
+ itemConfig: {
165
+ content: getTreeModule({ hasTextMatch: true }),
166
+ children: `
167
+ [
168
+ {
169
+ title:'Imported by modules',
170
+ data: $.reasons,
171
+ type: 'reasons',
172
+ },
173
+ {
174
+ title:'Similar copies',
175
+ data: $.duplicates,
176
+ type: 'duplicates',
177
+ }
178
+ ].filter(=> $.data.size() > 0)
179
+ `,
180
+ itemConfig: {
181
+ view: "switch",
182
+ content: [{
183
+ when: "type=\"reasons\"",
184
+ content: {
185
+ view: "tree-leaf",
186
+ content: [
187
+ "text:title",
188
+ "text:' '",
189
+ "badge:{ text: $.data.size() }"
190
+ ],
191
+ children: `$.data`,
192
+ itemConfig: {
193
+ view: "tree-leaf",
194
+ content: getTreeModule()
195
+ }
196
+ }
197
+ }, {
198
+ when: "type=\"duplicates\"",
199
+ content: {
200
+ view: "tree-leaf",
201
+ content: [
202
+ "text:title",
203
+ "text:' '",
204
+ "badge:{ text: $.data.size() }"
205
+ ],
206
+ children: `$.data`,
207
+ itemConfig: {
208
+ view: "tree-leaf",
209
+ content: getTreeModule()
210
+ }
211
+ }
212
+ }]
213
+ }
214
+ }
215
+ }
216
+ }
217
+ };
218
+ }
219
+ const metadata = {
220
+ platform: {
221
+ when: "transformOptions.platform",
222
+ view: "badge",
223
+ data: `{ prefix: 'Platform: ', text: transformOptions.platform, color: ${platformColor} }`
224
+ },
225
+ size: {
226
+ when: "modules.filter(=> $.path has 'node_modules').size()",
227
+ view: "badge",
228
+ data: `{ prefix: 'Size: ', text: modules.sum(=>output.sizeInBytes).formatBytes(), color: ${platformColor} }`
229
+ },
230
+ node_modules_size: {
231
+ when: "modules.filter(=> $.path has 'node_modules').size()",
232
+ view: "badge",
233
+ data: "{ prefix: 'node_modules: ', text: modules.filter(=> $.path has 'node_modules').sum(=>output.sizeInBytes).formatBytes(), color: 'rgba(255, 0, 0, 0.35)' }"
234
+ },
235
+ source_code_size: {
236
+ when: "modules.filter(=> $.path has 'node_modules').size()",
237
+ view: "badge",
238
+ data: `
239
+ // vars
240
+ $totalSize: modules.sum(=>output.sizeInBytes);
241
+ $thirdPartySize: modules.filter(=> $.path has 'node_modules').sum(=>output.sizeInBytes);
242
+ // return data
243
+ { prefix: 'Source code: ', text: ($totalSize - $thirdPartySize).formatBytes(), color: 'rgba(148, 111, 234, 0.5)' }`
244
+ },
245
+ is_dev: {
246
+ when: "transformOptions.dev != null",
247
+ view: "badge",
248
+ data: "{ prefix: '__DEV__: ', text: transformOptions.dev }"
249
+ },
250
+ is_minified: {
251
+ when: "transformOptions.minify != null",
252
+ view: "badge",
253
+ data: "{ prefix: 'Minify: ', text: transformOptions.minify }"
254
+ }
255
+ };
256
+ const externalLinkHtml = `<svg class="my-icon my-icon-link" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" ><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6M15 3h6v6M10 14 21 3"></path></svg>`;
257
+ function getCopyToClipboardButton({ textToCopy, className, text }) {
258
+ return {
259
+ view: "button",
260
+ className: `${className ?? ""} copy-to-clipboard`,
261
+ text,
262
+ data: `{ textToCopy: ${textToCopy} }`,
263
+ onClick(elm, data) {
264
+ clearTimeout(elm.__timer);
265
+ navigator.clipboard.writeText(data.textToCopy).then(() => {
266
+ elm.classList.add("done");
267
+ elm.__timer = setTimeout(() => elm.classList.remove("done"), 2e3);
268
+ }).catch(() => {
269
+ elm.classList.add("err");
270
+ elm.__timer = setTimeout(() => elm.classList.remove("err"), 2e3);
271
+ });
272
+ }
273
+ };
274
+ }
275
+ //#endregion
276
+ exports.externalLinkHtml = externalLinkHtml;
277
+ exports.getCopyToClipboardButton = getCopyToClipboardButton;
278
+ exports.getModulesTree = getModulesTree;
279
+ exports.getPackage = getPackage;
280
+ exports.getPackageList = getPackageList;
281
+ exports.getTreeModule = getTreeModule;
282
+ exports.metadata = metadata;
@@ -0,0 +1,184 @@
1
+ const require_pages__common = require("./_common.js");
2
+ //#region src/client/pages/default.ts
3
+ const topMetaData = [
4
+ require_pages__common.metadata.platform,
5
+ require_pages__common.metadata.size,
6
+ require_pages__common.metadata.source_code_size,
7
+ require_pages__common.metadata.node_modules_size,
8
+ require_pages__common.metadata.is_dev,
9
+ require_pages__common.metadata.is_minified
10
+ ];
11
+ const TABS = {
12
+ TREEMAP_FOAMTREE: "treemap-foamtree",
13
+ MODULES: "modules",
14
+ PACKAGES: "packages",
15
+ DUPLICATES: "duplicates"
16
+ };
17
+ function parseHashRef(url = window.location.href) {
18
+ return new URL(url).hash.split(":")?.[1];
19
+ }
20
+ discovery.page.define("default", [...topMetaData, {
21
+ view: "tabs",
22
+ name: "mainTabs",
23
+ className: "main-tabs",
24
+ value: parseHashRef() ?? TABS.TREEMAP_FOAMTREE,
25
+ tabs: [
26
+ {
27
+ value: TABS.TREEMAP_FOAMTREE,
28
+ text: "Treemap chart",
29
+ className: `main-tabs-${TABS.TREEMAP_FOAMTREE}`
30
+ },
31
+ {
32
+ value: TABS.PACKAGES,
33
+ className: `main-tabs-${TABS.PACKAGES}`,
34
+ content: ["text:'Packages '", `pill-badge: modules.filter(=> path has "node_modules").group(=> path.getModulesName(), => 0).size()`]
35
+ },
36
+ {
37
+ value: TABS.MODULES,
38
+ className: `main-tabs-${TABS.MODULES}`,
39
+ content: ["text:'Modules '", "pill-badge: modules.size()"]
40
+ },
41
+ {
42
+ value: TABS.DUPLICATES,
43
+ className: `main-tabs-${TABS.DUPLICATES}`,
44
+ content: ["text:'Duplicate modules '", "pill-badge: modules.filter(=> duplicates).size()"]
45
+ }
46
+ ],
47
+ content: {
48
+ view: "switch",
49
+ context(_data, context) {
50
+ const isHashChangeEvent = (/* @__PURE__ */ new Error("")).stack.includes("Promise.all");
51
+ discovery.overridePageHashStateWithAnchor({
52
+ id: "default",
53
+ ref: isHashChangeEvent ? discovery.pageRef : context.mainTabs
54
+ });
55
+ discovery.cancelScheduledRender();
56
+ const id = discovery.pageRef ?? TABS.TREEMAP_FOAMTREE;
57
+ setTimeout(() => {
58
+ discovery.dom.root.querySelectorAll(".main-tabs>div>.onclick").forEach((e) => {
59
+ e.classList.remove("active");
60
+ });
61
+ discovery.dom.root.querySelectorAll(`.main-tabs .main-tabs-${id}`).forEach((e) => {
62
+ e.classList.add("active");
63
+ });
64
+ }, 50);
65
+ return {
66
+ ...context,
67
+ id
68
+ };
69
+ },
70
+ content: [
71
+ {
72
+ when: `#.id="${TABS.TREEMAP_FOAMTREE}"`,
73
+ content: {
74
+ view: "content-filter",
75
+ name: "filterByPathStr",
76
+ debounce: 300,
77
+ className: "foamtree-filter",
78
+ content: {
79
+ view: "foamtree",
80
+ data: `
81
+ $root: $.rootFolder;
82
+ $applyFilter: => #.filterByPathStr ? $.modules.filter(=> $.path ~= #.filterByPathStr) : $.modules;
83
+ $dataObject: $.$applyFilter()
84
+ .map(=> {path, size: $.output.sizeInBytes})
85
+ .transformFilesList($root, "foamtree");
86
+
87
+ {
88
+ options: {
89
+ dataObject: $dataObject,
90
+ descriptionGroupSize: 0.05,
91
+ descriptionGroupMinHeight: 30,
92
+ }
93
+ }
94
+ `
95
+ }
96
+ }
97
+ },
98
+ {
99
+ when: `#.id="${TABS.MODULES}"`,
100
+ content: require_pages__common.getModulesTree({
101
+ limit: 200,
102
+ data: `
103
+ $entryPoint: $.entryPointPath;
104
+ $totalSize: modules.sum(=>output.sizeInBytes);
105
+ $toModule: => {
106
+ ext: $.path.getFileExtension(),
107
+ name: $.path,
108
+ size: $.output.sizeInBytes.formatBytes(),
109
+ percent: ($.output.sizeInBytes / $totalSize).percent(3),
110
+ };
111
+ modules.map(=> {
112
+ ...$.$toModule(),
113
+ isEntry: $.isEntry,
114
+ reasons: $.dependents.map(=> $.$toModule()),
115
+ duplicates: $.duplicates.map(=> $.$toModule()),
116
+ })
117
+ `
118
+ })
119
+ },
120
+ {
121
+ when: `#.id="${TABS.PACKAGES}"`,
122
+ content: [
123
+ require_pages__common.getCopyToClipboardButton({
124
+ text: "Copy list",
125
+ className: "copy-before-ask-chatgpt",
126
+ textToCopy: `"- " + modules.filter(=> path has "node_modules").group(=> path.getModulesName()).map(=> $.key).join("\\n- ")`
127
+ }),
128
+ {
129
+ view: "link",
130
+ className: "ask-chatgpt view-button",
131
+ text: "and Ask ChatGPT",
132
+ external: true,
133
+ data: `{
134
+ href: $.askChatGPTAboutPackages()
135
+ }`
136
+ },
137
+ {
138
+ view: "content-filter",
139
+ data: `${require_pages__common.getPackage(`modules.filter(=> path has "node_modules")`)}.sort(pkgInstances desc, size desc)`,
140
+ className: "packages-content",
141
+ name: "filterByPathStr",
142
+ content: require_pages__common.getPackageList({
143
+ showCopiesBadge: true,
144
+ expanded: false,
145
+ limit: 200,
146
+ subLimit: 50,
147
+ data: ".[pkgName ~= #.filterByPathStr]",
148
+ itemPkgName: {
149
+ view: "link",
150
+ content: "text-match",
151
+ data: `{
152
+ href: pkgName.pageLink("package", {}),
153
+ text: pkgName,
154
+ match: #.filterByPathStr
155
+ }`
156
+ }
157
+ })
158
+ }
159
+ ]
160
+ },
161
+ {
162
+ when: `#.id="${TABS.DUPLICATES}"`,
163
+ content: require_pages__common.getModulesTree({ data: `
164
+ // values
165
+ $duplicatesOnly: modules.filter(=> duplicates);
166
+ $totalSize: $duplicatesOnly.sum(=>output.sizeInBytes);
167
+ $toModule: => {
168
+ ext: $.path.getFileExtension(),
169
+ name: $.path,
170
+ size: $.output.sizeInBytes.formatBytes(),
171
+ percent: ($.output.sizeInBytes / $totalSize).percent(3),
172
+ };
173
+ // return
174
+ $duplicatesOnly.map(=> {
175
+ ...$.$toModule(),
176
+ reasons: $.dependents.map(=> $.$toModule()),
177
+ duplicates: $.duplicates.map(=> $.$toModule()),
178
+ })
179
+ ` })
180
+ }
181
+ ]
182
+ }
183
+ }]);
184
+ //#endregion