react-native-bundle-discovery-ui 2.5.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.
@@ -0,0 +1,282 @@
1
+ //#region src/client/queryHelpers.ts
2
+ const helpers = {
3
+ prettifyMap: /* @__PURE__ */ new Map(),
4
+ prettifyJS(sourceStr) {
5
+ if (helpers.prettifyMap.has(sourceStr)) return helpers.prettifyMap.get(sourceStr);
6
+ const prettier = require("prettier/standalone");
7
+ const prettierPluginBabel = require("prettier/plugins/babel");
8
+ const prettierPluginEstree = require("prettier/plugins/estree");
9
+ return prettier.format(sourceStr, {
10
+ parser: "babel",
11
+ plugins: [prettierPluginBabel, prettierPluginEstree]
12
+ }).then((formatted) => {
13
+ helpers.prettifyMap.set(sourceStr, formatted);
14
+ return formatted;
15
+ }).catch(() => {
16
+ return sourceStr;
17
+ });
18
+ },
19
+ askChatGPTAboutPackages() {
20
+ return `https://chat.openai.com/?prompt=${encodeURIComponent(`I have a list of JavaScript packages from my React Native bundle (see below). I want to optimize bundle size by identifying similar or redundant packages — such as multiple versions of similar libraries (e.g., lodash, lodash-es, underscore, etc.), duplicate utilities, or overlapping functionality (e.g., date libraries like moment, dayjs, date-fns).
21
+
22
+ Please do the following:
23
+
24
+ 1. Group similar or overlapping packages together.
25
+ 2. For each group, suggest which one to keep and which ones to consider removing.
26
+ 3. For each group, provide a regex string that can be used to filter those packages from the list (e.g., in grep, find, or search tools).
27
+ 4. Keep the output concise and copy-paste friendly.`)}`;
28
+ },
29
+ plural(count, [singular, plural]) {
30
+ return count === 1 ? singular : plural;
31
+ },
32
+ pluralWithCount(count, [singular, plural]) {
33
+ return `${count} ${helpers.plural(count, [singular, plural])}`;
34
+ },
35
+ pluralBadge(count, [singular, plural], prefix = "") {
36
+ return {
37
+ text: prefix + count,
38
+ postfix: helpers.plural(count, [singular, plural])
39
+ };
40
+ },
41
+ getModulesName(path) {
42
+ const modules = path.split("node_modules/");
43
+ const [folder, subFolder] = modules[modules.length - 1].split("/");
44
+ if (folder.startsWith("@")) return `${folder}/${subFolder}`;
45
+ return folder;
46
+ },
47
+ getBestNetworkGraphSize(module, params) {
48
+ let maxParentDepth = 0;
49
+ let itemsCount = 0;
50
+ do {
51
+ maxParentDepth++;
52
+ itemsCount = helpers.getNetworkGraph(module, {
53
+ ...params,
54
+ maxParentDepth
55
+ }).data.length;
56
+ if (itemsCount < 10) {
57
+ const limit = itemsCount - 1;
58
+ return limit > 2 ? limit : 2;
59
+ }
60
+ } while (maxParentDepth < 6);
61
+ return maxParentDepth;
62
+ },
63
+ getNetworkGraph(module, { maxParentDepth = 2, omitVisitedModules = true } = {}) {
64
+ const queue = [{
65
+ module,
66
+ parentId: "",
67
+ level: 0
68
+ }];
69
+ const visited = /* @__PURE__ */ new Set();
70
+ const result = [];
71
+ let entryPointPath = null;
72
+ const data = [];
73
+ while (queue.length > 0) {
74
+ const { module: currentModule, parentId, level } = queue.shift();
75
+ if (level >= Number(maxParentDepth)) break;
76
+ const id = currentModule.path;
77
+ if (omitVisitedModules) {
78
+ if (visited.has(id)) continue;
79
+ visited.add(id);
80
+ }
81
+ if (parentId) {
82
+ const isEntryPoint = currentModule.dependents.length === 0;
83
+ result.push({
84
+ isEntryPoint,
85
+ id,
86
+ parentId
87
+ });
88
+ data.push([parentId, id]);
89
+ if (isEntryPoint) entryPointPath = id;
90
+ }
91
+ if (Array.isArray(currentModule.dependents)) for (const dependentModule of currentModule.dependents) queue.push({
92
+ module: dependentModule,
93
+ parentId: id,
94
+ level: level + 1
95
+ });
96
+ }
97
+ if (!entryPointPath) {
98
+ for (const item of result) if (item.isEntryPoint) {
99
+ entryPointPath = item.id;
100
+ break;
101
+ }
102
+ }
103
+ return {
104
+ entryPointPath,
105
+ data
106
+ };
107
+ },
108
+ getExtColor(extName) {
109
+ const colors = {
110
+ js: "#f1e05a50",
111
+ ts: "#2b748950",
112
+ tsx: "#2b748950",
113
+ json: "#e34c2650",
114
+ svg: "#e69f0d50",
115
+ css: "#563d7c50",
116
+ png: "#e44b2350"
117
+ };
118
+ return colors[extName] ?? colors.js;
119
+ },
120
+ getFileExtension(filename) {
121
+ const idx = filename.lastIndexOf(".");
122
+ return idx === -1 ? "js" : filename.slice(idx + 1);
123
+ },
124
+ formatDate(isoDate) {
125
+ return isoDate ? new Date(isoDate).toISOString().slice(0, 10) : "";
126
+ },
127
+ timeAgo(isoDate) {
128
+ if (!isoDate) return "";
129
+ const days = Math.floor((Date.now() - new Date(isoDate).getTime()) / 864e5);
130
+ const [count, unit] = days >= 365 ? [Math.floor(days / 365), ["year", "years"]] : days >= 30 ? [Math.floor(days / 30), ["month", "months"]] : [days, ["day", "days"]];
131
+ return count === 0 ? "today" : `${helpers.pluralWithCount(count, unit)} ago`;
132
+ },
133
+ toFixed(value, fractionDigits = 2) {
134
+ return Number(value).toFixed(fractionDigits);
135
+ },
136
+ percent(value, fractionDigits = 2) {
137
+ return `${(100 * value).toFixed(fractionDigits)}%`;
138
+ },
139
+ formatBytes(bytes, decimals) {
140
+ if (bytes == 0) return "0 Bytes";
141
+ const k = 1024, dm = decimals || 2, sizes = [
142
+ "Bytes",
143
+ "KB",
144
+ "MB",
145
+ "GB",
146
+ "TB",
147
+ "PB",
148
+ "EB",
149
+ "ZB",
150
+ "YB"
151
+ ], i = Math.floor(Math.log(bytes) / Math.log(k));
152
+ return `${parseFloat((bytes / k ** i).toFixed(dm))} ${sizes[i]}`;
153
+ },
154
+ isPackageImport(moduleName) {
155
+ return moduleName?.[0] !== ".";
156
+ },
157
+ transformFilesList(files, rootFolder, type) {
158
+ const nodeModulesMap = {
159
+ children: {},
160
+ size: 0
161
+ };
162
+ const sourceCodeMap = {
163
+ children: {},
164
+ size: 0
165
+ };
166
+ files.forEach(({ path, size }) => {
167
+ if (path === "__prelude__") path = "node_modules/__prelude__";
168
+ if (path === "__runtime__") path = "node_modules/__runtime__";
169
+ const shortPath = path.replace(`${rootFolder}/`, "");
170
+ const isNodeModule = shortPath.includes("node_modules/");
171
+ const parts = shortenPath(shortPath, nodeModulesMap).split("/");
172
+ let current = (isNodeModule ? nodeModulesMap : sourceCodeMap).children;
173
+ parts.forEach((part, index) => {
174
+ if (!current[part]) current[part] = {
175
+ size: 0,
176
+ children: {}
177
+ };
178
+ if (index === parts.length - 1) {
179
+ current[part].size = size;
180
+ current[part].path = shortPath;
181
+ current[part].fullPath = path;
182
+ }
183
+ current = current[part].children;
184
+ });
185
+ });
186
+ if (type === "foamtree") {
187
+ sumSizes(nodeModulesMap);
188
+ sumSizes(sourceCodeMap);
189
+ const sourceCodeGroup = toGroups(sourceCodeMap, "Source Code");
190
+ const nodeModulesGroup = nodeModulesMap?.children?.node_modules ? toGroups(nodeModulesMap.children.node_modules, "node_modules") : {};
191
+ if (!sourceCodeGroup.groups) return nodeModulesGroup;
192
+ if (!nodeModulesGroup.groups) return sourceCodeGroup;
193
+ const topLevelNode = { groups: [sourceCodeGroup, nodeModulesGroup] };
194
+ topLevelNode.weight = topLevelNode.groups.reduce((acc, group) => acc + group.weight, 0);
195
+ return topLevelNode;
196
+ }
197
+ if (type === "highcharts-treemap") {
198
+ const ROOT_ID_1 = "~";
199
+ const ROOT_ID_2 = ".";
200
+ return [{
201
+ id: ROOT_ID_1,
202
+ name: "node_modules"
203
+ }, {
204
+ id: ROOT_ID_2,
205
+ name: "Source Code"
206
+ }].concat(flattenTree(nodeModulesMap.children.node_modules, ROOT_ID_1)).concat(flattenTree(sourceCodeMap, ROOT_ID_2));
207
+ }
208
+ throw new Error(`Unsupported type: ${type}`);
209
+ }
210
+ };
211
+ function flattenTree(node, parentId, prevWasSkipped = false, lvl = 0, result = [], overrideParentId) {
212
+ const nodeChildrenCount = Object.keys(node.children);
213
+ for (const key of nodeChildrenCount) {
214
+ const childNode = node.children[key];
215
+ const childId = `${parentId}/${key}`;
216
+ const childrenCount = Object.keys(childNode.children).length;
217
+ const hasChildren = childrenCount > 0;
218
+ const item = {
219
+ id: childId,
220
+ name: prevWasSkipped ? parentId : key,
221
+ parent: overrideParentId ?? parentId
222
+ };
223
+ if (!hasChildren) item.value = childNode.size;
224
+ if (lvl === 0) item.color = Highcharts.getOptions().colors[randomInt(0, 9)];
225
+ const skipThisNode = nodeChildrenCount.length === 1 && childrenCount === 1;
226
+ if (!skipThisNode) result.push(item);
227
+ flattenTree(childNode, childId, skipThisNode, lvl + 1, result, skipThisNode ? overrideParentId ?? parentId : void 0);
228
+ }
229
+ return result;
230
+ }
231
+ function sumSizes(node) {
232
+ const isFile = Object.keys(node.children).length === 0;
233
+ let totalFiles = isFile ? 1 : 0;
234
+ let totalSize = node.size || 0;
235
+ for (const key in node.children) {
236
+ const result = sumSizes(node.children[key]);
237
+ totalSize += result.totalSize;
238
+ totalFiles += result.totalFiles;
239
+ }
240
+ node.type = isFile ? "file" : "folder";
241
+ node.size = totalSize;
242
+ node.files = totalFiles;
243
+ return {
244
+ totalSize,
245
+ totalFiles
246
+ };
247
+ }
248
+ function toGroups(node, label) {
249
+ const keys = Object.keys(node.children);
250
+ const common = {
251
+ label,
252
+ weight: node.size,
253
+ fullPath: node.fullPath,
254
+ files: node.files,
255
+ type: node.type,
256
+ size: helpers.formatBytes(node.size)
257
+ };
258
+ if (keys.length === 0) return common;
259
+ return Object.assign(common, { groups: keys.map((key) => toGroups(node.children[key], key)) });
260
+ }
261
+ function randomInt(min, max) {
262
+ return Math.floor(Math.random() * (max - min + 1)) + min;
263
+ }
264
+ const nm = "node_modules/";
265
+ function shortenPath(path, nodeModulesMap) {
266
+ if (path.startsWith(`${nm}.pnpm/`)) path = path.replaceAll(`${nm}.pnpm/`, "");
267
+ const index = path.lastIndexOf(nm);
268
+ if (index > 0) {
269
+ const pathWithoutNestedNM = path.slice(index);
270
+ const firstSlash = pathWithoutNestedNM.indexOf("/");
271
+ const secondSlash = pathWithoutNestedNM.indexOf("/", firstSlash + 1);
272
+ const pkgName = secondSlash === -1 ? pathWithoutNestedNM.slice(firstSlash + 1) : pathWithoutNestedNM.slice(firstSlash + 1, secondSlash);
273
+ if (nodeModulesMap?.children?.node_modules?.children?.[pkgName]) {
274
+ const parentPackage = helpers.getModulesName(path.slice(0, index));
275
+ return `${nm + parentPackage} ~ ${pathWithoutNestedNM.slice(13)}`;
276
+ }
277
+ return pathWithoutNestedNM;
278
+ }
279
+ return path;
280
+ }
281
+ //#endregion
282
+ module.exports = helpers;
@@ -0,0 +1,9 @@
1
+ const require_prepare = require("./prepare.js");
2
+ const require_queryHelpers = require("./queryHelpers.js");
3
+ //#region src/client/setup.ts
4
+ function setup({ addQueryHelpers, setPrepare }) {
5
+ addQueryHelpers(require_queryHelpers);
6
+ setPrepare(require_prepare);
7
+ }
8
+ //#endregion
9
+ module.exports = setup;
@@ -0,0 +1,16 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ //#region src/client/views/_theme.ts
3
+ function isDark() {
4
+ const isSystemDarkMode = window?.matchMedia?.("(prefers-color-scheme: dark)")?.matches;
5
+ const userMode = localStorage.getItem("discoveryjs:color-scheme");
6
+ return userMode === "auto" ? isSystemDarkMode : userMode === "dark";
7
+ }
8
+ function doTheming(el) {
9
+ const dark = isDark();
10
+ el.classList.add("highcharts-light");
11
+ el.classList[!dark ? "add" : "remove"]("my-light");
12
+ el.classList[dark ? "add" : "remove"]("highcharts-dark");
13
+ }
14
+ if (isDark()) require("../../../vendors/high-contrast-dark.js");
15
+ //#endregion
16
+ exports.doTheming = doTheming;
@@ -0,0 +1,88 @@
1
+ let vendors_foamtree_js = require("../../../vendors/foamtree.js");
2
+ //#region src/client/views/foamtree.ts
3
+ function injectTooltip(root) {
4
+ const t = root.querySelector(".tooltip");
5
+ if (t) return t;
6
+ const tooltip = document.createElement("div");
7
+ tooltip.className = "tooltip";
8
+ tooltip.id = "foamtree-tooltip";
9
+ root.appendChild(tooltip);
10
+ return tooltip;
11
+ }
12
+ function prependDuplicateTo(label) {
13
+ if (label.includes(" ~ ")) return `<b class='i-duplicate'>Duplicate</b> ${label.split(" ~ ")[1]}`;
14
+ return label;
15
+ }
16
+ discovery.view.define("foamtree", (el, _config, rawData, context) => {
17
+ if (Array.isArray(rawData?.options?.series)) rawData.options.series.forEach((e) => {
18
+ if (e.data?.[0]?.value !== void 0) e.data = e.data.map((d) => d.value ?? null);
19
+ });
20
+ setTimeout(() => {
21
+ try {
22
+ window.__el = el;
23
+ const root = el.closest(".discovery-root");
24
+ const tooltip = injectTooltip(root);
25
+ window.addEventListener("resize", () => ft.resize(), { passive: true });
26
+ root.addEventListener("mousemove", (event) => {
27
+ if (tooltip.style.display === "none") return;
28
+ tooltip.style.left = `${event.pageX + 10}px`;
29
+ tooltip.style.top = `${event.pageY + 10}px`;
30
+ }, { passive: true });
31
+ el.addEventListener("mouseover", () => {
32
+ tooltip.style.display = "block";
33
+ });
34
+ el.addEventListener("mouseout", () => {
35
+ tooltip.style.display = "none";
36
+ });
37
+ const ft = new vendors_foamtree_js.FoamTree({
38
+ element: el,
39
+ layout: "squarified",
40
+ stacking: "flattened",
41
+ pixelRatio: window.devicePixelRatio || 1,
42
+ maxGroups: Infinity,
43
+ maxGroupLevelsDrawn: Infinity,
44
+ maxGroupLabelLevelsDrawn: Infinity,
45
+ maxGroupLevelsAttached: Infinity,
46
+ wireframeLabelDrawing: "always",
47
+ groupMinDiameter: 0,
48
+ groupLabelVerticalPadding: .2,
49
+ rolloutDuration: 0,
50
+ pullbackDuration: 0,
51
+ fadeDuration: 0,
52
+ groupExposureZoomMargin: .2,
53
+ zoomMouseWheelDuration: 300,
54
+ openCloseDuration: 200,
55
+ onGroupClick(event) {
56
+ event.preventDefault();
57
+ ft.zoom(event.group);
58
+ },
59
+ onGroupDoubleClick: (e) => e.preventDefault(),
60
+ onGroupHover(event) {
61
+ if (event.group && event.group === rawData.options.dataObject) return event.preventDefault();
62
+ const { group } = event;
63
+ if (group?.type) {
64
+ const htmlContent = [
65
+ `<b class="tooltip-name">${group.type}</b>: ${prependDuplicateTo(group.label)}`,
66
+ `<b>Size</b>: ${group.size}`,
67
+ group.type === "folder" ? null : `<b>Path</b>: ${group.fullPath}`,
68
+ group.type === "folder" ? `<b>Files</b>: ${group.files}` : null
69
+ ].filter((e) => !!e).join("<br/>");
70
+ tooltip.style.display = "block";
71
+ tooltip.innerHTML = htmlContent;
72
+ } else {
73
+ tooltip.style.display = "none";
74
+ tooltip.innerHTML = "";
75
+ }
76
+ },
77
+ ...rawData.options
78
+ });
79
+ } catch (e) {
80
+ console.error(e, rawData);
81
+ discovery.view.render(el, {
82
+ view: "alert-danger",
83
+ data: "\"Error rendering chart, please check the console for more information.\""
84
+ }, rawData, context);
85
+ }
86
+ }, 0);
87
+ });
88
+ //#endregion
@@ -0,0 +1,23 @@
1
+ const require_runtime = require("../_virtual/_rolldown/runtime.js");
2
+ const require_views__theme = require("./_theme.js");
3
+ let vendors_highcharts_js = require("../../../vendors/highcharts.js");
4
+ vendors_highcharts_js = require_runtime.__toESM(vendors_highcharts_js);
5
+ require("../../../vendors/highcharts-networkgraph.js");
6
+ require("../../../vendors/highcharts-exporting.js");
7
+ //#region src/client/views/highcharts.ts
8
+ discovery.view.define("highcharts", (el, _config, rawData, context) => {
9
+ require_views__theme.doTheming(el);
10
+ if (Array.isArray(rawData?.options?.series)) rawData.options.series.forEach((e) => {
11
+ if (e.data?.[0]?.value !== void 0) e.data = e.data.map((d) => d.value ?? null);
12
+ });
13
+ try {
14
+ vendors_highcharts_js.default.chart(el, vendors_highcharts_js.default.merge({}, rawData.options));
15
+ } catch (e) {
16
+ console.error(e, rawData);
17
+ discovery.view.render(el, {
18
+ view: "alert-danger",
19
+ data: "\"Error rendering chart, please check the console for more information.\""
20
+ }, rawData, context);
21
+ }
22
+ });
23
+ //#endregion
@@ -0,0 +1,9 @@
1
+ //#region src/client/views/prettify.ts
2
+ discovery.view.define("source-prettify", async function renderPrettify(el, config, data, context) {
3
+ await this.render(el, this.composeConfig([{
4
+ ...config,
5
+ source: await config.source,
6
+ view: "source"
7
+ }]), data, context);
8
+ });
9
+ //#endregion
@@ -0,0 +1,21 @@
1
+ const require_rolldown_runtime = require("./rolldown-runtime-VH7oDXx4.js");
2
+ let node_path = require("node:path");
3
+ node_path = require_rolldown_runtime.__toESM(node_path);
4
+ //#region src/discoveryrc.ts
5
+ const config = {
6
+ name: "react-native-bundle-discovery",
7
+ data: () => require(node_path.default.resolve(__dirname, "../../../tmp/metro-stats.json")),
8
+ setup: node_path.default.resolve(__dirname, "client/setup.js"),
9
+ view: { assets: [
10
+ node_path.default.resolve(__dirname, "../assets/global.css"),
11
+ node_path.default.resolve(__dirname, "client/pages/default.js"),
12
+ node_path.default.resolve(__dirname, "client/pages/module.js"),
13
+ node_path.default.resolve(__dirname, "client/pages/package.js"),
14
+ node_path.default.resolve(__dirname, "../assets/highcharts.css"),
15
+ node_path.default.resolve(__dirname, "client/views/prettify.js"),
16
+ node_path.default.resolve(__dirname, "client/views/highcharts.js"),
17
+ node_path.default.resolve(__dirname, "client/views/foamtree.js")
18
+ ] }
19
+ };
20
+ //#endregion
21
+ module.exports = config;
@@ -0,0 +1,28 @@
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
+ Object.defineProperty(exports, "__toESM", {
24
+ enumerable: true,
25
+ get: function() {
26
+ return __toESM;
27
+ }
28
+ });
@@ -0,0 +1,75 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ require("./src-BSLX-He2.js");
3
+ let node_path = require("node:path");
4
+ //#region ../shared/src/rsdoctor.ts
5
+ const possibleEntryFiles = [
6
+ "index.js",
7
+ "index.jsx",
8
+ "index.ts",
9
+ "index.tsx",
10
+ "index.mjs",
11
+ "index.cjs"
12
+ ];
13
+ const doStructureCheck = (rsdoctorData) => {
14
+ if (!(Array.isArray(rsdoctorData?.data?.configs) && rsdoctorData.data.configs.length === 1)) throw new Error(`Unexpected number of "data.configs[]" in rsdoctor-data.json. Work only with single config. Found: ${rsdoctorData?.data?.configs?.length}`);
15
+ if (!Array.isArray(rsdoctorData?.data?.packageGraph?.packages)) throw new Error(`Unexpected "data.packageGraph.packages[]" in rsdoctor-data.json. Expected array. Found: ${typeof rsdoctorData?.data?.packageGraph?.packages}`);
16
+ const firstConfig = rsdoctorData.data.configs[0];
17
+ if (!(firstConfig.name === "rspack" || firstConfig.name === "webpack")) throw new Error(`Unsupported bundler: ${firstConfig.name}@${firstConfig.version}. Only 'rspack' and 'webpack' are supported.`);
18
+ };
19
+ const getDependenciesMap = (rsdoctorData) => {
20
+ return new Map(rsdoctorData.data.moduleGraph.dependencies.map((dep) => [dep.id, dep]));
21
+ };
22
+ const getEntryFile = (rsdoctorData) => {
23
+ const firstConfig = rsdoctorData.data.configs[0];
24
+ const main = firstConfig.config.entry?.main;
25
+ const entryFile = typeof main === "string" ? main : typeof main?.import === "string" ? main.import : main?.import[0];
26
+ if (entryFile) return (0, node_path.resolve)(firstConfig.root, entryFile);
27
+ const pathsToCheck = possibleEntryFiles.map((f) => (0, node_path.resolve)(firstConfig.root, f));
28
+ const indexFile = rsdoctorData.data.moduleGraph.modules.find((mdl) => pathsToCheck.some((entry) => mdl.path === entry));
29
+ if (indexFile && indexFile.imported?.length === 0) return indexFile.path;
30
+ return `${firstConfig.root}/index.js`;
31
+ };
32
+ const transformRSDoctorData = (rsdoctorData) => {
33
+ doStructureCheck(rsdoctorData);
34
+ const tmpDependenciesMap = getDependenciesMap(rsdoctorData);
35
+ const firstConfig = rsdoctorData.data.configs[0];
36
+ return {
37
+ date: Date.now(),
38
+ entryPoint: getEntryFile(rsdoctorData),
39
+ rootFolder: firstConfig.root,
40
+ transformOptions: {
41
+ dev: firstConfig.config.mode !== "production",
42
+ minify: firstConfig.config.optimization?.minimize ?? false,
43
+ platform: firstConfig.config.name ?? "ios"
44
+ },
45
+ packages: rsdoctorData.data.packageGraph.packages.map((pkg) => ({
46
+ name: pkg.name,
47
+ absolutePath: pkg.root,
48
+ version: pkg.version,
49
+ source: { sizeInBytes: pkg.size?.sourceSize ?? 1 },
50
+ output: { sizeInBytes: pkg.size?.parsedSize ?? 1 }
51
+ })),
52
+ modules: rsdoctorData.data.moduleGraph.modules.map((mdl) => ({
53
+ path: mdl.path,
54
+ source: {
55
+ code: "",
56
+ lineCount: 0,
57
+ sizeInBytes: mdl.size?.sourceSize ?? 0
58
+ },
59
+ output: {
60
+ code: "",
61
+ lineCount: 0,
62
+ sizeInBytes: mdl.size?.parsedSize ?? 0
63
+ },
64
+ dependencies: mdl.dependencies.map((depNumId) => {
65
+ const dep = tmpDependenciesMap.get(depNumId);
66
+ return dep ? {
67
+ absolutePath: dep.resolvedRequest,
68
+ name: dep.request
69
+ } : null;
70
+ }).filter((e) => e !== null)
71
+ }))
72
+ };
73
+ };
74
+ //#endregion
75
+ exports.transformRSDoctorData = transformRSDoctorData;
@@ -0,0 +1,30 @@
1
+ const require_rolldown_runtime = require("./rolldown-runtime-VH7oDXx4.js");
2
+ let chalk = require("chalk");
3
+ chalk = require_rolldown_runtime.__toESM(chalk);
4
+ //#region ../shared/src/isRsdoctorReport.ts
5
+ const isRsdoctorReport = (reportJson, reportPath, noLogs) => {
6
+ try {
7
+ if (Array.isArray(reportJson?.data?.moduleGraph?.modules) || Array.isArray(reportJson?.data?.packageGraph?.packages)) {
8
+ !noLogs && console.info(`Detected ${chalk.default.red("rsdoctor")} format in the input file: ${chalk.default.green(reportPath)}`);
9
+ return true;
10
+ }
11
+ return false;
12
+ } catch {
13
+ return false;
14
+ }
15
+ };
16
+ const isRsdoctorReportPath = (reportPath) => {
17
+ try {
18
+ const reportJson = require(reportPath);
19
+ return isRsdoctorReport(reportJson, reportPath);
20
+ } catch {
21
+ return false;
22
+ }
23
+ };
24
+ //#endregion
25
+ Object.defineProperty(exports, "isRsdoctorReportPath", {
26
+ enumerable: true,
27
+ get: function() {
28
+ return isRsdoctorReportPath;
29
+ }
30
+ });
package/package.json CHANGED
@@ -1,18 +1,27 @@
1
1
  {
2
2
  "name": "react-native-bundle-discovery-ui",
3
- "version": "2.5.0",
4
- "main": "lib/bin.js",
5
- "bin": "lib/bin.js",
6
- "repository": "git@github.com:retyui/react-native-bundle-discovery.git",
3
+ "version": "2.7.0-rc.0",
4
+ "description": "Browser UI for React Native bundle reports",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "git+https://github.com/retyui/react-native-bundle-discovery.git",
8
+ "directory": "packages/ui"
9
+ },
7
10
  "author": "David <4661784+retyui@users.noreply.github.com>",
8
11
  "license": "MIT",
12
+ "main": "./dist/bin.js",
13
+ "bin": "./dist/bin.js",
14
+ "files": [
15
+ "dist",
16
+ "!dist/.tmp.js",
17
+ "assets",
18
+ "vendors"
19
+ ],
9
20
  "scripts": {
10
- "srv": "node ./lib/bin.js server",
11
- "analyze": "node ./_cli/bin.js analyze",
12
- "tmp": "yarn srv /Users/davyd.narbutovich/tmp/RNDiscovery/metro-stats.json",
13
- "format": "prettier --write .",
14
- "start": "NODE_ENV=development npx discovery --config .discoveryrc.js",
15
- "build": "npx discovery-build --config .discoveryrc.js --output build --serve-only-assets --single-file"
21
+ "build": "run -T tsdown",
22
+ "typecheck": "run -T tsc -p tsconfig.json && run -T tsc -p src/client/tsconfig.json",
23
+ "dev": "run -T tsdown && NODE_ENV=development discovery --config dist/discoveryrc.js",
24
+ "prepack": "cp ../../README.md README.md"
16
25
  },
17
26
  "dependencies": {
18
27
  "@discoveryjs/cli": "2.14.7",
@@ -21,29 +30,19 @@
21
30
  "minimist": "^1.2.8",
22
31
  "prettier": "^3.9.6"
23
32
  },
33
+ "devDependencies": {
34
+ "@react-native-bundle-discovery/shared": "workspace:*",
35
+ "@types/minimist": "^1.2.5"
36
+ },
24
37
  "peerDependencies": {
25
- "metro": "*"
38
+ "metro": ">=0.68.0"
26
39
  },
27
40
  "peerDependenciesMeta": {
28
41
  "metro": {
29
42
  "optional": true
30
43
  }
31
44
  },
32
- "files": [
33
- "vendors",
34
- "lib",
35
- "!lib/.tmp.js",
36
- "views",
37
- "pages",
38
- "index.js",
39
- "setup.js",
40
- "prepare.js",
41
- "queryHelpers.js",
42
- ".discoveryrc.js"
43
- ],
44
- "packageManager": "yarn@4.18.0",
45
- "devDependencies": {
46
- "acorn": "^8.18.0",
47
- "acorn-walk": "^8.3.5"
45
+ "publishConfig": {
46
+ "access": "public"
48
47
  }
49
48
  }