react-native-inapp-inspector 2.0.0 → 2.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -0
- package/android/.gradle/8.9/checksums/checksums.lock +0 -0
- package/android/.gradle/8.9/checksums/md5-checksums.bin +0 -0
- package/android/.gradle/8.9/checksums/sha1-checksums.bin +0 -0
- package/android/.gradle/8.9/dependencies-accessors/gc.properties +0 -0
- package/android/.gradle/8.9/executionHistory/executionHistory.lock +0 -0
- package/android/.gradle/8.9/fileChanges/last-build.bin +0 -0
- package/android/.gradle/8.9/fileHashes/fileHashes.lock +0 -0
- package/android/.gradle/8.9/gc.properties +0 -0
- package/android/.gradle/9.2.0/checksums/checksums.lock +0 -0
- package/android/.gradle/9.2.0/fileChanges/last-build.bin +0 -0
- package/android/.gradle/9.2.0/fileHashes/fileHashes.bin +0 -0
- package/android/.gradle/9.2.0/fileHashes/fileHashes.lock +0 -0
- package/android/.gradle/9.2.0/gc.properties +0 -0
- package/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
- package/android/.gradle/buildOutputCleanup/cache.properties +2 -0
- package/android/.gradle/vcs-1/gc.properties +0 -0
- package/android/build/reports/problems/problems-report.html +659 -0
- package/android/src/main/java/com/inappinspector/NetworkInspectorModule.kt +33 -24
- package/dist/commonjs/components/ConsoleLogCard.js +5 -5
- package/dist/commonjs/components/EndOfListFooter.js +1 -1
- package/dist/commonjs/components/Inspector/AnalyticsTab.js +19 -71
- package/dist/commonjs/components/Inspector/BundleTab.js +670 -188
- package/dist/commonjs/components/Inspector/ConsoleTab.js +109 -98
- package/dist/commonjs/components/Inspector/CrashTab.js +2 -1
- package/dist/commonjs/components/Inspector/InspectorHeader.js +102 -19
- package/dist/commonjs/components/Inspector/MainScreen.js +151 -17
- package/dist/commonjs/components/Inspector/NetworkTab.js +104 -20
- package/dist/commonjs/components/Inspector/SettingsPanel.js +1111 -1385
- package/dist/commonjs/components/Inspector/TabBar.js +3 -4
- package/dist/commonjs/components/Inspector/TelemetryConsentModal.d.ts +3 -0
- package/dist/commonjs/components/Inspector/TelemetryConsentModal.js +212 -0
- package/dist/commonjs/components/JsonViewer.js +9 -4
- package/dist/commonjs/components/LogCard.js +31 -1
- package/dist/commonjs/components/LogSyntaxHighlighter.d.ts +16 -0
- package/dist/commonjs/components/LogSyntaxHighlighter.js +130 -0
- package/dist/commonjs/components/NetworkIcons.d.ts +2 -0
- package/dist/commonjs/components/NetworkIcons.js +10 -1
- package/dist/commonjs/components/Slider.d.ts +13 -0
- package/dist/commonjs/components/Slider.js +261 -0
- package/dist/commonjs/constants/version.d.ts +1 -1
- package/dist/commonjs/constants/version.js +1 -1
- package/dist/commonjs/customHooks/analyticsLogger.js +1 -1
- package/dist/commonjs/customHooks/crashHandler.js +1 -1
- package/dist/commonjs/helpers/index.d.ts +2 -0
- package/dist/commonjs/helpers/index.js +16 -0
- package/dist/commonjs/helpers/searchQueryParser.d.ts +6 -0
- package/dist/commonjs/helpers/searchQueryParser.js +236 -0
- package/dist/commonjs/helpers/settingsStore.js +13 -13
- package/dist/commonjs/helpers/telemetry.d.ts +99 -0
- package/dist/commonjs/helpers/telemetry.js +398 -0
- package/dist/commonjs/index.d.ts +2 -0
- package/dist/commonjs/index.js +30 -21
- package/dist/commonjs/native/NativeInspector.d.ts +5 -0
- package/dist/commonjs/native/NativeInspector.js +3 -2
- package/dist/commonjs/styles/index.js +35 -35
- package/dist/esm/components/ConsoleLogCard.js +5 -5
- package/dist/esm/components/EndOfListFooter.js +2 -2
- package/dist/esm/components/Inspector/AnalyticsTab.js +21 -73
- package/dist/esm/components/Inspector/BundleTab.js +670 -188
- package/dist/esm/components/Inspector/ConsoleTab.js +110 -99
- package/dist/esm/components/Inspector/CrashTab.js +2 -1
- package/dist/esm/components/Inspector/InspectorHeader.js +103 -20
- package/dist/esm/components/Inspector/MainScreen.js +119 -18
- package/dist/esm/components/Inspector/NetworkTab.js +105 -21
- package/dist/esm/components/Inspector/SettingsPanel.js +1114 -1388
- package/dist/esm/components/Inspector/TabBar.js +4 -5
- package/dist/esm/components/Inspector/TelemetryConsentModal.d.ts +3 -0
- package/dist/esm/components/Inspector/TelemetryConsentModal.js +175 -0
- package/dist/esm/components/JsonViewer.js +9 -4
- package/dist/esm/components/LogCard.js +32 -2
- package/dist/esm/components/LogSyntaxHighlighter.d.ts +16 -0
- package/dist/esm/components/LogSyntaxHighlighter.js +123 -0
- package/dist/esm/components/NetworkIcons.d.ts +2 -0
- package/dist/esm/components/NetworkIcons.js +7 -0
- package/dist/esm/components/Slider.d.ts +13 -0
- package/dist/esm/components/Slider.js +222 -0
- package/dist/esm/constants/version.d.ts +1 -1
- package/dist/esm/constants/version.js +1 -1
- package/dist/esm/customHooks/analyticsLogger.js +1 -1
- package/dist/esm/customHooks/crashHandler.js +1 -1
- package/dist/esm/helpers/index.d.ts +2 -0
- package/dist/esm/helpers/index.js +2 -0
- package/dist/esm/helpers/searchQueryParser.d.ts +6 -0
- package/dist/esm/helpers/searchQueryParser.js +233 -0
- package/dist/esm/helpers/settingsStore.js +13 -13
- package/dist/esm/helpers/telemetry.d.ts +99 -0
- package/dist/esm/helpers/telemetry.js +380 -0
- package/dist/esm/index.d.ts +2 -0
- package/dist/esm/index.js +20 -21
- package/dist/esm/native/NativeInspector.d.ts +5 -0
- package/dist/esm/native/NativeInspector.js +3 -2
- package/dist/esm/styles/index.js +35 -35
- package/ios/{NetworkInspectorModule.m → NetworkInspectorModule.mm} +193 -97
- package/package.json +2 -2
|
@@ -113,7 +113,11 @@ const PackageLogoRenderer = ({ name, size = 28 }) => {
|
|
|
113
113
|
if (lowerName.includes('screens') || lowerName.includes('software-mansion')) {
|
|
114
114
|
return (<react_native_1.View style={[
|
|
115
115
|
bundleStyles.pkgLogoWrap,
|
|
116
|
-
{
|
|
116
|
+
{
|
|
117
|
+
width: size,
|
|
118
|
+
height: size,
|
|
119
|
+
backgroundColor: AppColors_1.AppColors.reanimatedNavy,
|
|
120
|
+
},
|
|
117
121
|
]}>
|
|
118
122
|
<react_native_svg_1.default width={size - 8} height={size - 8} viewBox="0 0 100 100" fill="none">
|
|
119
123
|
<react_native_svg_1.Path d="M50 15 L88 35 L50 55 L12 35 Z" fill={AppColors_1.AppColors.sky400}/>
|
|
@@ -165,7 +169,12 @@ const PackageLogoRenderer = ({ name, size = 28 }) => {
|
|
|
165
169
|
</react_native_1.View>);
|
|
166
170
|
};
|
|
167
171
|
const BundleCategoryIcon = ({ type, size = 16, color = AppColors_1.AppColors.purple }) => {
|
|
168
|
-
const stroke = {
|
|
172
|
+
const stroke = {
|
|
173
|
+
stroke: color,
|
|
174
|
+
strokeWidth: 1.7,
|
|
175
|
+
strokeLinecap: 'round',
|
|
176
|
+
strokeLinejoin: 'round',
|
|
177
|
+
};
|
|
169
178
|
const renderGlyph = () => {
|
|
170
179
|
switch (type) {
|
|
171
180
|
case 'folder':
|
|
@@ -376,7 +385,9 @@ const downloadBundleFile = async (file, scriptURL) => {
|
|
|
376
385
|
// Path: ${file.path}
|
|
377
386
|
// Category: ${file.category.toUpperCase()}
|
|
378
387
|
// Size: ${file.sizeKb} KB
|
|
379
|
-
// Status: ${file.status === 'optimal'
|
|
388
|
+
// Status: ${file.status === 'optimal'
|
|
389
|
+
? 'Active in Dependency Graph'
|
|
390
|
+
: 'Not consumed / Static'}
|
|
380
391
|
// Meta: ${file.meta}
|
|
381
392
|
// ─────────────────────────────────────────────────────────────
|
|
382
393
|
|
|
@@ -419,10 +430,9 @@ const BundleTreeNodeView = ({ node, level, search, totalBundleKb, expandedFolder
|
|
|
419
430
|
const indentLeft = level * 16 + 10;
|
|
420
431
|
if (node.isFolder) {
|
|
421
432
|
return (<react_native_1.View style={bundleStyles.treeFolderBlock}>
|
|
422
|
-
<TouchableScale_1.default accessible={true} accessibilityRole="button" accessibilityLabel={`Folder ${node.name}, ${node.fileCount} ${node.fileCount === 1 ? 'file' : 'files'}, ${node.sizeKb >= 1024
|
|
423
|
-
|
|
424
|
-
{ paddingLeft: indentLeft }
|
|
425
|
-
]}>
|
|
433
|
+
<TouchableScale_1.default accessible={true} accessibilityRole="button" accessibilityLabel={`Folder ${node.name}, ${node.fileCount} ${node.fileCount === 1 ? 'file' : 'files'}, ${node.sizeKb >= 1024
|
|
434
|
+
? `${(node.sizeKb / 1024).toFixed(2)} MB`
|
|
435
|
+
: `${node.sizeKb} KB`}`} accessibilityState={{ expanded: isExpanded }} accessibilityHint="Double tap to expand or collapse folder" onPress={() => toggleFolder(node.fullPath)} style={[bundleStyles.treeFolderRow, { paddingLeft: indentLeft }]}>
|
|
426
436
|
<react_native_1.View style={bundleStyles.treeRowLeft}>
|
|
427
437
|
<react_native_1.Text style={bundleStyles.treeChevron}>
|
|
428
438
|
{isCollapsed ? '▸' : '▾'}
|
|
@@ -431,7 +441,8 @@ const BundleTreeNodeView = ({ node, level, search, totalBundleKb, expandedFolder
|
|
|
431
441
|
<HighlightText_1.default text={node.name + '/'} search={search} style={bundleStyles.treeFolderName} highlightStyle={bundleStyles.searchHighlight}/>
|
|
432
442
|
<react_native_1.View style={bundleStyles.treeCountBadge}>
|
|
433
443
|
<react_native_1.Text style={bundleStyles.treeCountBadgeText}>
|
|
434
|
-
{node.fileCount}
|
|
444
|
+
{node.fileCount}{' '}
|
|
445
|
+
{node.fileCount === 1 ? (0, i18n_1.t)('bundle.file') : (0, i18n_1.t)('bundle.files')}
|
|
435
446
|
</react_native_1.Text>
|
|
436
447
|
</react_native_1.View>
|
|
437
448
|
</react_native_1.View>
|
|
@@ -439,7 +450,9 @@ const BundleTreeNodeView = ({ node, level, search, totalBundleKb, expandedFolder
|
|
|
439
450
|
<react_native_1.View style={bundleStyles.treeRowRight}>
|
|
440
451
|
<react_native_1.Text style={bundleStyles.treeFolderSize}>
|
|
441
452
|
{node.sizeKb >= 1024
|
|
442
|
-
? (0, i18n_1.t)('bundle.fileSizeMb', {
|
|
453
|
+
? (0, i18n_1.t)('bundle.fileSizeMb', {
|
|
454
|
+
size: (node.sizeKb / 1024).toFixed(2),
|
|
455
|
+
})
|
|
443
456
|
: (0, i18n_1.t)('bundle.fileSizeKb', { size: node.sizeKb })}
|
|
444
457
|
</react_native_1.Text>
|
|
445
458
|
<CopyButton_1.default value={() => ({
|
|
@@ -478,13 +491,18 @@ const BundleTreeNodeView = ({ node, level, search, totalBundleKb, expandedFolder
|
|
|
478
491
|
<HighlightText_1.default text={file.name} search={search} style={bundleStyles.treeFileName} highlightStyle={bundleStyles.searchHighlight}/>
|
|
479
492
|
|
|
480
493
|
{isUnused && (<react_native_1.View style={bundleStyles.treeUnusedPill}>
|
|
481
|
-
<react_native_1.Text style={bundleStyles.treeUnusedPillText}>
|
|
494
|
+
<react_native_1.Text style={bundleStyles.treeUnusedPillText}>
|
|
495
|
+
{(0, i18n_1.t)('bundle.notConsumed')}
|
|
496
|
+
</react_native_1.Text>
|
|
482
497
|
</react_native_1.View>)}
|
|
483
498
|
</react_native_1.View>
|
|
484
499
|
|
|
485
500
|
<react_native_1.View style={bundleStyles.treeRowRight}>
|
|
486
501
|
<react_native_1.View style={bundleStyles.treeFileSizeGroup}>
|
|
487
|
-
<react_native_1.Text style={[
|
|
502
|
+
<react_native_1.Text style={[
|
|
503
|
+
bundleStyles.treeFileSizeText,
|
|
504
|
+
isUnused && { color: AppColors_1.AppColors.red600 },
|
|
505
|
+
]}>
|
|
488
506
|
{file.sizeKb >= 1024
|
|
489
507
|
? (0, i18n_1.t)('bundle.fileSizeMb', { size: (file.sizeKb / 1024).toFixed(2) })
|
|
490
508
|
: (0, i18n_1.t)('bundle.fileSizeKb', { size: file.sizeKb })}
|
|
@@ -507,17 +525,41 @@ const CATEGORY_TABS = [
|
|
|
507
525
|
{ key: 'UNUSED', labelKey: 'bundle.catUnused', iconType: 'ban' },
|
|
508
526
|
{ key: 'CONSUMED', labelKey: 'bundle.catConsumed', iconType: 'bolt' },
|
|
509
527
|
{ key: 'image', labelKey: 'bundle.catImages', iconType: 'image' },
|
|
510
|
-
{
|
|
511
|
-
|
|
528
|
+
{
|
|
529
|
+
key: 'typescript',
|
|
530
|
+
labelKey: 'bundle.catTypescript',
|
|
531
|
+
iconType: 'typescript',
|
|
532
|
+
},
|
|
533
|
+
{
|
|
534
|
+
key: 'javascript',
|
|
535
|
+
labelKey: 'bundle.catJavascript',
|
|
536
|
+
iconType: 'javascript',
|
|
537
|
+
},
|
|
512
538
|
{ key: 'font', labelKey: 'bundle.catFonts', iconType: 'font' },
|
|
513
539
|
{ key: 'json', labelKey: 'bundle.catJson', iconType: 'json' },
|
|
514
540
|
];
|
|
515
541
|
const CATEGORY_COLORS = {
|
|
516
|
-
image: {
|
|
517
|
-
|
|
518
|
-
|
|
542
|
+
image: {
|
|
543
|
+
label: 'Images & Media',
|
|
544
|
+
color: AppColors_1.AppColors.pink500,
|
|
545
|
+
bg: AppColors_1.AppColors.pink100,
|
|
546
|
+
},
|
|
547
|
+
typescript: {
|
|
548
|
+
label: 'TypeScript',
|
|
549
|
+
color: AppColors_1.AppColors.sky500,
|
|
550
|
+
bg: AppColors_1.AppColors.sky100,
|
|
551
|
+
},
|
|
552
|
+
javascript: {
|
|
553
|
+
label: 'JavaScript',
|
|
554
|
+
color: AppColors_1.AppColors.indigo500,
|
|
555
|
+
bg: AppColors_1.AppColors.indigo50,
|
|
556
|
+
},
|
|
519
557
|
font: { label: 'Fonts', color: AppColors_1.AppColors.purple500, bg: AppColors_1.AppColors.purple100 },
|
|
520
|
-
json: {
|
|
558
|
+
json: {
|
|
559
|
+
label: 'JSON / Data',
|
|
560
|
+
color: AppColors_1.AppColors.emerald500,
|
|
561
|
+
bg: AppColors_1.AppColors.emerald100,
|
|
562
|
+
},
|
|
521
563
|
};
|
|
522
564
|
const BundleTab = react_1.default.memo(() => {
|
|
523
565
|
const { t } = (0, i18n_1.useTranslation)();
|
|
@@ -564,8 +606,13 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
564
606
|
const bundlePackages = (0, react_1.useMemo)(() => (analysis ? analysis.packages : []), [analysis]);
|
|
565
607
|
// Comprehensive bundle summary (full Metro bundle calculation e.g. 6.0 MB)
|
|
566
608
|
const summary = (0, react_1.useMemo)(() => {
|
|
567
|
-
const totalKb = analysis?.totalDevKb ||
|
|
568
|
-
|
|
609
|
+
const totalKb = analysis?.totalDevKb ||
|
|
610
|
+
(analysis?.totalDevBytes
|
|
611
|
+
? Math.round(analysis.totalDevBytes / 1024)
|
|
612
|
+
: 6144);
|
|
613
|
+
const totalMb = analysis?.totalDevMb
|
|
614
|
+
? analysis.totalDevMb.toFixed(2)
|
|
615
|
+
: (totalKb / 1024).toFixed(2);
|
|
569
616
|
const nodeModulesKb = analysis?.splitUp?.nodeModules?.kb || Math.round(totalKb * 0.52);
|
|
570
617
|
const nodeModulesPct = analysis?.splitUp?.nodeModules?.pct || 52.0;
|
|
571
618
|
const metroKb = analysis?.splitUp?.metroDevOverhead?.kb || Math.round(totalKb * 0.21);
|
|
@@ -616,7 +663,9 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
616
663
|
iconType: 'image',
|
|
617
664
|
title: 'Images & Static Media',
|
|
618
665
|
targetTab: 'media',
|
|
619
|
-
count: bundleFiles.filter(f => f.category === 'image' ||
|
|
666
|
+
count: bundleFiles.filter(f => f.category === 'image' ||
|
|
667
|
+
f.category === 'font' ||
|
|
668
|
+
f.category === 'json').length || 3,
|
|
620
669
|
sizeKb: assetsMediaKb,
|
|
621
670
|
sizeMb: (assetsMediaKb / 1024).toFixed(2),
|
|
622
671
|
pct: assetsMediaPct,
|
|
@@ -800,7 +849,7 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
800
849
|
</TouchableScale_1.default>);
|
|
801
850
|
})}
|
|
802
851
|
</react_native_1.ScrollView>
|
|
803
|
-
<TouchableScale_1.default accessible={true} accessibilityRole="button" accessibilityLabel={isAnalyzing ?
|
|
852
|
+
<TouchableScale_1.default accessible={true} accessibilityRole="button" accessibilityLabel={isAnalyzing ? 'Analyzing Metro bundle' : 'Reload bundle analysis'} accessibilityHint="Re-probes Metro dev server and refreshes bundle statistics" onPress={refreshAnalysis} style={bundleStyles.reloadButton} hitSlop={{ top: 8, bottom: 8, left: 8, right: 8 }}>
|
|
804
853
|
{isAnalyzing ? (<react_native_1.ActivityIndicator size="small" color={AppColors_1.AppColors.brandPurple}/>) : (<NetworkIcons_1.RefreshCcwIcon color={AppColors_1.AppColors.brandPurple} size={14}/>)}
|
|
805
854
|
</TouchableScale_1.default>
|
|
806
855
|
</react_native_1.View>
|
|
@@ -809,7 +858,6 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
809
858
|
{/* ── 1. TAB: OVERVIEW & TREEMAP ───────────────────────────────────────── */}
|
|
810
859
|
{/* ══════════════════════════════════════════════════════════════════════ */}
|
|
811
860
|
{activeSubTab === 'overview' && (<react_native_1.ScrollView style={{ flex: 1 }} contentContainerStyle={bundleStyles.contentContainer} keyboardShouldPersistTaps="handled">
|
|
812
|
-
|
|
813
861
|
{/* Hero Overview Card */}
|
|
814
862
|
<react_native_1.View style={bundleStyles.heroCard}>
|
|
815
863
|
<react_native_1.View style={bundleStyles.heroTopRow}>
|
|
@@ -817,7 +865,9 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
817
865
|
<NetworkIcons_1.PackageIcon color={AppColors_1.AppColors.brandPurple} size={24}/>
|
|
818
866
|
</react_native_1.View>
|
|
819
867
|
<react_native_1.View style={{ flex: 1 }}>
|
|
820
|
-
<react_native_1.Text style={bundleStyles.heroTitle}>
|
|
868
|
+
<react_native_1.Text style={bundleStyles.heroTitle}>
|
|
869
|
+
{t('bundle.heroTitle')}
|
|
870
|
+
</react_native_1.Text>
|
|
821
871
|
{analysis?.isLive && analysis.scriptURL ? (<react_native_1.View style={{ marginTop: 4, gap: 4 }}>
|
|
822
872
|
<react_native_1.Text style={bundleStyles.heroSubtitle}>
|
|
823
873
|
{t('bundle.heroSubtitle')}
|
|
@@ -836,7 +886,11 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
836
886
|
justifyContent: 'space-between',
|
|
837
887
|
marginBottom: 3,
|
|
838
888
|
}}>
|
|
839
|
-
<react_native_1.View style={{
|
|
889
|
+
<react_native_1.View style={{
|
|
890
|
+
flexDirection: 'row',
|
|
891
|
+
alignItems: 'center',
|
|
892
|
+
gap: 4,
|
|
893
|
+
}}>
|
|
840
894
|
<NetworkIcons_1.ExternalLinkIcon color={AppColors_1.AppColors.skyBlue} size={11}/>
|
|
841
895
|
<react_native_1.Text style={{
|
|
842
896
|
fontFamily: AppFonts_1.AppFonts.interBold,
|
|
@@ -876,7 +930,9 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
876
930
|
{/* 4-Stat Metric Grid */}
|
|
877
931
|
<react_native_1.View style={bundleStyles.metricsGrid}>
|
|
878
932
|
<react_native_1.View style={bundleStyles.metricBox}>
|
|
879
|
-
<react_native_1.Text style={bundleStyles.metricLabel}>
|
|
933
|
+
<react_native_1.Text style={bundleStyles.metricLabel}>
|
|
934
|
+
{t('bundle.devBundleSize')}
|
|
935
|
+
</react_native_1.Text>
|
|
880
936
|
<react_native_1.Text style={bundleStyles.metricValue}>
|
|
881
937
|
{t('bundle.mbValue', {
|
|
882
938
|
size: analysis ? analysis.totalDevMb : summary.totalMb,
|
|
@@ -893,8 +949,13 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
893
949
|
</react_native_1.View>
|
|
894
950
|
|
|
895
951
|
<react_native_1.View style={bundleStyles.metricBox}>
|
|
896
|
-
<react_native_1.Text style={bundleStyles.metricLabel}>
|
|
897
|
-
|
|
952
|
+
<react_native_1.Text style={bundleStyles.metricLabel}>
|
|
953
|
+
{t('bundle.imagesMedia')}
|
|
954
|
+
</react_native_1.Text>
|
|
955
|
+
<react_native_1.Text style={[
|
|
956
|
+
bundleStyles.metricValue,
|
|
957
|
+
{ color: AppColors_1.AppColors.pink500 },
|
|
958
|
+
]}>
|
|
898
959
|
{t('bundle.fileSizeKb', { size: summary.images.kb })}
|
|
899
960
|
</react_native_1.Text>
|
|
900
961
|
<react_native_1.Text style={bundleStyles.metricHint}>
|
|
@@ -903,9 +964,13 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
903
964
|
</react_native_1.View>
|
|
904
965
|
|
|
905
966
|
<react_native_1.View style={bundleStyles.metricBox}>
|
|
906
|
-
<react_native_1.Text style={bundleStyles.metricLabel}>
|
|
967
|
+
<react_native_1.Text style={bundleStyles.metricLabel}>
|
|
968
|
+
{t('bundle.tsJsSource')}
|
|
969
|
+
</react_native_1.Text>
|
|
907
970
|
<react_native_1.Text style={[bundleStyles.metricValue, { color: AppColors_1.AppColors.sky500 }]}>
|
|
908
|
-
{t('bundle.fileSizeKb', {
|
|
971
|
+
{t('bundle.fileSizeKb', {
|
|
972
|
+
size: summary.ts.kb + summary.js.kb,
|
|
973
|
+
})}
|
|
909
974
|
</react_native_1.Text>
|
|
910
975
|
<react_native_1.Text style={bundleStyles.metricHint}>
|
|
911
976
|
{t('bundle.pctOfTrackedAssets', {
|
|
@@ -915,11 +980,22 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
915
980
|
</react_native_1.View>
|
|
916
981
|
|
|
917
982
|
<react_native_1.View style={bundleStyles.metricBox}>
|
|
918
|
-
<react_native_1.Text style={bundleStyles.metricLabel}>
|
|
919
|
-
|
|
983
|
+
<react_native_1.Text style={bundleStyles.metricLabel}>
|
|
984
|
+
{t('bundle.jsEngine')}
|
|
985
|
+
</react_native_1.Text>
|
|
986
|
+
<react_native_1.View style={{
|
|
987
|
+
flexDirection: 'row',
|
|
988
|
+
alignItems: 'center',
|
|
989
|
+
gap: 5,
|
|
990
|
+
marginTop: 2,
|
|
991
|
+
}}>
|
|
920
992
|
<react_native_1.View style={[
|
|
921
993
|
bundleStyles.statusIndicator,
|
|
922
|
-
{
|
|
994
|
+
{
|
|
995
|
+
backgroundColor: isHermes
|
|
996
|
+
? AppColors_1.AppColors.greenColor
|
|
997
|
+
: AppColors_1.AppColors.darkOrange,
|
|
998
|
+
},
|
|
923
999
|
]}/>
|
|
924
1000
|
<react_native_1.Text style={bundleStyles.metricValue}>
|
|
925
1001
|
{isHermes ? 'Hermes' : 'JSC'}
|
|
@@ -934,7 +1010,12 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
934
1010
|
|
|
935
1011
|
{/* Live analysis unavailable warning */}
|
|
936
1012
|
{analysis && !analysis.isLive && (<react_native_1.View style={bundleStyles.liveWarningCard}>
|
|
937
|
-
<react_native_1.View style={{
|
|
1013
|
+
<react_native_1.View style={{
|
|
1014
|
+
flexDirection: 'row',
|
|
1015
|
+
alignItems: 'center',
|
|
1016
|
+
gap: 6,
|
|
1017
|
+
flex: 1,
|
|
1018
|
+
}}>
|
|
938
1019
|
<NetworkIcons_1.CircleAlertIcon color={AppColors_1.AppColors.amber700} size={16}/>
|
|
939
1020
|
<react_native_1.View style={{ flex: 1 }}>
|
|
940
1021
|
<react_native_1.Text style={bundleStyles.liveWarningTitle}>
|
|
@@ -947,13 +1028,13 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
947
1028
|
</react_native_1.View>
|
|
948
1029
|
</react_native_1.View>)}
|
|
949
1030
|
|
|
950
|
-
|
|
951
|
-
|
|
952
1031
|
{/* Visual Type Distribution Ratio Bar */}
|
|
953
1032
|
<react_native_1.View style={bundleStyles.sectionCard}>
|
|
954
1033
|
<react_native_1.View style={bundleStyles.sectionHeaderRow}>
|
|
955
|
-
<react_native_1.View>
|
|
956
|
-
<react_native_1.Text style={bundleStyles.sectionTitle}>
|
|
1034
|
+
<react_native_1.View style={{ flex: 1, paddingRight: 4 }}>
|
|
1035
|
+
<react_native_1.Text style={bundleStyles.sectionTitle}>
|
|
1036
|
+
{t('bundle.treemapTitle')}
|
|
1037
|
+
</react_native_1.Text>
|
|
957
1038
|
<react_native_1.Text style={bundleStyles.sectionSub}>
|
|
958
1039
|
{t('bundle.treemapSub', { mb: summary.totalMb })}
|
|
959
1040
|
</react_native_1.Text>
|
|
@@ -961,19 +1042,44 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
961
1042
|
<CopyButton_1.default value={() => ({
|
|
962
1043
|
totalMb: summary.totalMb,
|
|
963
1044
|
totalKb: summary.totalKb,
|
|
964
|
-
nodeModules: {
|
|
1045
|
+
nodeModules: {
|
|
1046
|
+
kb: summary.nodeModulesKb,
|
|
1047
|
+
pct: summary.nodeModulesPct,
|
|
1048
|
+
},
|
|
965
1049
|
metroRuntime: { kb: summary.metroKb, pct: summary.metroPct },
|
|
966
|
-
appSource: {
|
|
967
|
-
|
|
1050
|
+
appSource: {
|
|
1051
|
+
kb: summary.appSourceKb,
|
|
1052
|
+
pct: summary.appSourcePct,
|
|
1053
|
+
},
|
|
1054
|
+
assetsMedia: {
|
|
1055
|
+
kb: summary.assetsMediaKb,
|
|
1056
|
+
pct: summary.assetsMediaPct,
|
|
1057
|
+
},
|
|
968
1058
|
})} label={t('bundle.treemapJson')}/>
|
|
969
1059
|
</react_native_1.View>
|
|
970
1060
|
|
|
971
1061
|
{/* Stacked Colored Bar for Full 6.0 MB Bundle */}
|
|
972
1062
|
<react_native_1.View style={bundleStyles.treemapBar}>
|
|
973
|
-
<react_native_1.View style={{
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
1063
|
+
<react_native_1.View style={{
|
|
1064
|
+
flex: summary.nodeModulesPct,
|
|
1065
|
+
backgroundColor: AppColors_1.AppColors.indigo500,
|
|
1066
|
+
height: 16,
|
|
1067
|
+
}}/>
|
|
1068
|
+
<react_native_1.View style={{
|
|
1069
|
+
flex: summary.metroPct,
|
|
1070
|
+
backgroundColor: AppColors_1.AppColors.amber500,
|
|
1071
|
+
height: 16,
|
|
1072
|
+
}}/>
|
|
1073
|
+
<react_native_1.View style={{
|
|
1074
|
+
flex: summary.appSourcePct,
|
|
1075
|
+
backgroundColor: AppColors_1.AppColors.sky500,
|
|
1076
|
+
height: 16,
|
|
1077
|
+
}}/>
|
|
1078
|
+
<react_native_1.View style={{
|
|
1079
|
+
flex: summary.assetsMediaPct,
|
|
1080
|
+
backgroundColor: AppColors_1.AppColors.pink500,
|
|
1081
|
+
height: 16,
|
|
1082
|
+
}}/>
|
|
977
1083
|
</react_native_1.View>
|
|
978
1084
|
|
|
979
1085
|
{/* Legend Grid */}
|
|
@@ -985,7 +1091,8 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
985
1091
|
<react_native_1.Text style={bundleStyles.legendVal}>
|
|
986
1092
|
{summary.nodeModulesKb >= 1024
|
|
987
1093
|
? `${(summary.nodeModulesKb / 1024).toFixed(1)} MB`
|
|
988
|
-
: `${summary.nodeModulesKb} KB`}
|
|
1094
|
+
: `${summary.nodeModulesKb} KB`}{' '}
|
|
1095
|
+
({summary.nodeModulesPct}%)
|
|
989
1096
|
</react_native_1.Text>
|
|
990
1097
|
</react_native_1.Text>
|
|
991
1098
|
</react_native_1.View>
|
|
@@ -996,7 +1103,8 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
996
1103
|
<react_native_1.Text style={bundleStyles.legendVal}>
|
|
997
1104
|
{summary.metroKb >= 1024
|
|
998
1105
|
? `${(summary.metroKb / 1024).toFixed(1)} MB`
|
|
999
|
-
: `${summary.metroKb} KB`}
|
|
1106
|
+
: `${summary.metroKb} KB`}{' '}
|
|
1107
|
+
({summary.metroPct}%)
|
|
1000
1108
|
</react_native_1.Text>
|
|
1001
1109
|
</react_native_1.Text>
|
|
1002
1110
|
</react_native_1.View>
|
|
@@ -1007,7 +1115,8 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
1007
1115
|
<react_native_1.Text style={bundleStyles.legendVal}>
|
|
1008
1116
|
{summary.appSourceKb >= 1024
|
|
1009
1117
|
? `${(summary.appSourceKb / 1024).toFixed(1)} MB`
|
|
1010
|
-
: `${summary.appSourceKb} KB`}
|
|
1118
|
+
: `${summary.appSourceKb} KB`}{' '}
|
|
1119
|
+
({summary.appSourcePct}%)
|
|
1011
1120
|
</react_native_1.Text>
|
|
1012
1121
|
</react_native_1.Text>
|
|
1013
1122
|
</react_native_1.View>
|
|
@@ -1018,7 +1127,8 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
1018
1127
|
<react_native_1.Text style={bundleStyles.legendVal}>
|
|
1019
1128
|
{summary.assetsMediaKb >= 1024
|
|
1020
1129
|
? `${(summary.assetsMediaKb / 1024).toFixed(1)} MB`
|
|
1021
|
-
: `${summary.assetsMediaKb} KB`}
|
|
1130
|
+
: `${summary.assetsMediaKb} KB`}{' '}
|
|
1131
|
+
({summary.assetsMediaPct}%)
|
|
1022
1132
|
</react_native_1.Text>
|
|
1023
1133
|
</react_native_1.Text>
|
|
1024
1134
|
</react_native_1.View>
|
|
@@ -1028,10 +1138,12 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
1028
1138
|
{/* Detailed Category Footprint Cards */}
|
|
1029
1139
|
<react_native_1.View style={bundleStyles.sectionCard}>
|
|
1030
1140
|
<react_native_1.View style={bundleStyles.sectionHeaderRow}>
|
|
1031
|
-
<react_native_1.Text style={bundleStyles.sectionTitle}>
|
|
1141
|
+
<react_native_1.Text style={bundleStyles.sectionTitle}>
|
|
1142
|
+
{t('bundle.categoryBreakdown')}
|
|
1143
|
+
</react_native_1.Text>
|
|
1032
1144
|
<CopyButton_1.default value={() => summary} label={t('bundle.categoriesJson')}/>
|
|
1033
1145
|
</react_native_1.View>
|
|
1034
|
-
|
|
1146
|
+
|
|
1035
1147
|
{summary.categories.map((cat, cIdx) => (<react_native_1.Pressable key={cIdx} accessible={true} accessibilityRole="button" accessibilityLabel={`${cat.title}, ${cat.sizeKb >= 1024 ? `${cat.sizeMb} MB` : `${cat.sizeKb} KB`}, ${cat.pct}% of bundle`} accessibilityHint={`Double tap to view ${cat.title} details`} style={({ pressed }) => [
|
|
1036
1148
|
bundleStyles.catRowCard,
|
|
1037
1149
|
pressed && { opacity: 0.85, transform: [{ scale: 0.99 }] },
|
|
@@ -1039,25 +1151,42 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
1039
1151
|
<react_native_1.View style={bundleStyles.catRowTop}>
|
|
1040
1152
|
<react_native_1.View style={[
|
|
1041
1153
|
bundleStyles.catIconBox,
|
|
1042
|
-
{
|
|
1154
|
+
{
|
|
1155
|
+
backgroundColor: `${cat.color}15`,
|
|
1156
|
+
borderColor: `${cat.color}30`,
|
|
1157
|
+
},
|
|
1043
1158
|
]}>
|
|
1044
1159
|
<BundleCategoryIcon type={cat.iconType} size={18} color={cat.color}/>
|
|
1045
1160
|
</react_native_1.View>
|
|
1046
1161
|
|
|
1047
1162
|
<react_native_1.View style={bundleStyles.catRowTitleWrap}>
|
|
1048
|
-
<react_native_1.View style={{
|
|
1163
|
+
<react_native_1.View style={{
|
|
1164
|
+
flexDirection: 'row',
|
|
1165
|
+
alignItems: 'center',
|
|
1166
|
+
justifyContent: 'space-between',
|
|
1167
|
+
gap: 6,
|
|
1168
|
+
}}>
|
|
1049
1169
|
<react_native_1.Text style={bundleStyles.catRowTitle} numberOfLines={1}>
|
|
1050
1170
|
{cat.title}
|
|
1051
1171
|
</react_native_1.Text>
|
|
1052
|
-
<react_native_1.View style={{
|
|
1172
|
+
<react_native_1.View style={{
|
|
1173
|
+
flexDirection: 'row',
|
|
1174
|
+
alignItems: 'center',
|
|
1175
|
+
gap: 6,
|
|
1176
|
+
}}>
|
|
1053
1177
|
<react_native_1.Text style={bundleStyles.catRowSize}>
|
|
1054
|
-
{cat.sizeKb >= 1024
|
|
1178
|
+
{cat.sizeKb >= 1024
|
|
1179
|
+
? `${cat.sizeMb} MB`
|
|
1180
|
+
: `${cat.sizeKb} KB`}
|
|
1055
1181
|
</react_native_1.Text>
|
|
1056
1182
|
<react_native_1.View style={[
|
|
1057
1183
|
bundleStyles.catPctPill,
|
|
1058
1184
|
{ backgroundColor: `${cat.color}18` },
|
|
1059
1185
|
]}>
|
|
1060
|
-
<react_native_1.Text style={[
|
|
1186
|
+
<react_native_1.Text style={[
|
|
1187
|
+
bundleStyles.catPctText,
|
|
1188
|
+
{ color: cat.color },
|
|
1189
|
+
]}>
|
|
1061
1190
|
{cat.pct}%
|
|
1062
1191
|
</react_native_1.Text>
|
|
1063
1192
|
</react_native_1.View>
|
|
@@ -1108,20 +1237,43 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
1108
1237
|
{/* 4-Pill Chip Breakdown */}
|
|
1109
1238
|
<react_native_1.View style={bundleStyles.totalFormulaGrid}>
|
|
1110
1239
|
<react_native_1.View style={bundleStyles.totalChip}>
|
|
1111
|
-
<react_native_1.View style={[
|
|
1112
|
-
|
|
1240
|
+
<react_native_1.View style={[
|
|
1241
|
+
bundleStyles.totalDot,
|
|
1242
|
+
{ backgroundColor: AppColors_1.AppColors.indigo500 },
|
|
1243
|
+
]}/>
|
|
1244
|
+
<react_native_1.Text style={bundleStyles.totalChipText}>
|
|
1245
|
+
NPM: {(summary.nodeModulesKb / 1024).toFixed(1)}M (
|
|
1246
|
+
{summary.nodeModulesPct}%)
|
|
1247
|
+
</react_native_1.Text>
|
|
1113
1248
|
</react_native_1.View>
|
|
1114
1249
|
<react_native_1.View style={bundleStyles.totalChip}>
|
|
1115
|
-
<react_native_1.View style={[
|
|
1116
|
-
|
|
1250
|
+
<react_native_1.View style={[
|
|
1251
|
+
bundleStyles.totalDot,
|
|
1252
|
+
{ backgroundColor: AppColors_1.AppColors.amber500 },
|
|
1253
|
+
]}/>
|
|
1254
|
+
<react_native_1.Text style={bundleStyles.totalChipText}>
|
|
1255
|
+
Metro: {(summary.metroKb / 1024).toFixed(1)}M (
|
|
1256
|
+
{summary.metroPct}%)
|
|
1257
|
+
</react_native_1.Text>
|
|
1117
1258
|
</react_native_1.View>
|
|
1118
1259
|
<react_native_1.View style={bundleStyles.totalChip}>
|
|
1119
|
-
<react_native_1.View style={[
|
|
1120
|
-
|
|
1260
|
+
<react_native_1.View style={[
|
|
1261
|
+
bundleStyles.totalDot,
|
|
1262
|
+
{ backgroundColor: AppColors_1.AppColors.sky500 },
|
|
1263
|
+
]}/>
|
|
1264
|
+
<react_native_1.Text style={bundleStyles.totalChipText}>
|
|
1265
|
+
Source: {(summary.appSourceKb / 1024).toFixed(1)}M (
|
|
1266
|
+
{summary.appSourcePct}%)
|
|
1267
|
+
</react_native_1.Text>
|
|
1121
1268
|
</react_native_1.View>
|
|
1122
1269
|
<react_native_1.View style={bundleStyles.totalChip}>
|
|
1123
|
-
<react_native_1.View style={[
|
|
1124
|
-
|
|
1270
|
+
<react_native_1.View style={[
|
|
1271
|
+
bundleStyles.totalDot,
|
|
1272
|
+
{ backgroundColor: AppColors_1.AppColors.pink500 },
|
|
1273
|
+
]}/>
|
|
1274
|
+
<react_native_1.Text style={bundleStyles.totalChipText}>
|
|
1275
|
+
Media: {summary.assetsMediaKb}K ({summary.assetsMediaPct}%)
|
|
1276
|
+
</react_native_1.Text>
|
|
1125
1277
|
</react_native_1.View>
|
|
1126
1278
|
</react_native_1.View>
|
|
1127
1279
|
</react_native_1.View>
|
|
@@ -1130,10 +1282,13 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
1130
1282
|
{/* Detailed Subsystem Architecture Split-up */}
|
|
1131
1283
|
<react_native_1.View style={bundleStyles.sectionCard}>
|
|
1132
1284
|
<react_native_1.View style={bundleStyles.sectionHeaderRow}>
|
|
1133
|
-
<react_native_1.View>
|
|
1134
|
-
<react_native_1.Text style={bundleStyles.sectionTitle}>
|
|
1285
|
+
<react_native_1.View style={{ flex: 1, paddingRight: 4 }}>
|
|
1286
|
+
<react_native_1.Text style={bundleStyles.sectionTitle}>
|
|
1287
|
+
Bundle Subsystem Breakdown
|
|
1288
|
+
</react_native_1.Text>
|
|
1135
1289
|
<react_native_1.Text style={bundleStyles.sectionSub}>
|
|
1136
|
-
Granular analysis of packages, application source, engine
|
|
1290
|
+
Granular analysis of packages, application source, engine
|
|
1291
|
+
runtime & assets
|
|
1137
1292
|
</react_native_1.Text>
|
|
1138
1293
|
</react_native_1.View>
|
|
1139
1294
|
<CopyButton_1.default value={() => ({
|
|
@@ -1142,8 +1297,11 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
1142
1297
|
hermesEngine: isHermes ? 'Hermes (Bytecode)' : 'JSC (Source)',
|
|
1143
1298
|
jsDevKb: summary.totalKb,
|
|
1144
1299
|
jsHermesReleaseKb: Math.round(summary.totalKb * 0.38),
|
|
1145
|
-
appSourceFiles: bundleFiles.filter(f => f.category === 'typescript' ||
|
|
1146
|
-
|
|
1300
|
+
appSourceFiles: bundleFiles.filter(f => f.category === 'typescript' ||
|
|
1301
|
+
f.category === 'javascript').length,
|
|
1302
|
+
mediaAssets: bundleFiles.filter(f => f.category === 'image' ||
|
|
1303
|
+
f.category === 'font' ||
|
|
1304
|
+
f.category === 'json').length,
|
|
1147
1305
|
})} label="Subsystem Split JSON"/>
|
|
1148
1306
|
</react_native_1.View>
|
|
1149
1307
|
|
|
@@ -1152,28 +1310,51 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
1152
1310
|
<react_native_1.View style={bundleStyles.subsystemHeader}>
|
|
1153
1311
|
<react_native_1.View style={{ flexDirection: 'row', alignItems: 'center', gap: 6 }}>
|
|
1154
1312
|
<BundleCategoryIcon type="deps" size={16} color={AppColors_1.AppColors.indigo500}/>
|
|
1155
|
-
<react_native_1.Text style={bundleStyles.subsystemTitle}>
|
|
1313
|
+
<react_native_1.Text style={bundleStyles.subsystemTitle}>
|
|
1314
|
+
NPM & Third-Party Dependencies
|
|
1315
|
+
</react_native_1.Text>
|
|
1156
1316
|
</react_native_1.View>
|
|
1157
|
-
<react_native_1.View style={[
|
|
1158
|
-
|
|
1159
|
-
|
|
1317
|
+
<react_native_1.View style={[
|
|
1318
|
+
bundleStyles.subsystemBadge,
|
|
1319
|
+
{ backgroundColor: `${AppColors_1.AppColors.indigo500}18` },
|
|
1320
|
+
]}>
|
|
1321
|
+
<react_native_1.Text style={[
|
|
1322
|
+
bundleStyles.subsystemBadgeText,
|
|
1323
|
+
{ color: AppColors_1.AppColors.indigo500 },
|
|
1324
|
+
]}>
|
|
1325
|
+
{(summary.nodeModulesKb / 1024).toFixed(1)} MB •{' '}
|
|
1326
|
+
{summary.nodeModulesPct}%
|
|
1160
1327
|
</react_native_1.Text>
|
|
1161
1328
|
</react_native_1.View>
|
|
1162
1329
|
</react_native_1.View>
|
|
1163
1330
|
<react_native_1.View style={bundleStyles.subsystemGrid}>
|
|
1164
1331
|
<react_native_1.View style={bundleStyles.subsystemItem}>
|
|
1165
1332
|
<react_native_1.Text style={bundleStyles.subsystemItemText}>
|
|
1166
|
-
Direct:
|
|
1333
|
+
Direct:{' '}
|
|
1334
|
+
<react_native_1.Text style={bundleStyles.subsystemItemVal}>
|
|
1335
|
+
{bundlePackages.filter(p => p.type === 'direct').length ||
|
|
1336
|
+
12}{' '}
|
|
1337
|
+
pkgs
|
|
1338
|
+
</react_native_1.Text>
|
|
1167
1339
|
</react_native_1.Text>
|
|
1168
1340
|
</react_native_1.View>
|
|
1169
1341
|
<react_native_1.View style={bundleStyles.subsystemItem}>
|
|
1170
1342
|
<react_native_1.Text style={bundleStyles.subsystemItemText}>
|
|
1171
|
-
Transitive:
|
|
1343
|
+
Transitive:{' '}
|
|
1344
|
+
<react_native_1.Text style={bundleStyles.subsystemItemVal}>
|
|
1345
|
+
{bundlePackages.filter(p => p.type !== 'direct').length ||
|
|
1346
|
+
41}{' '}
|
|
1347
|
+
pkgs
|
|
1348
|
+
</react_native_1.Text>
|
|
1172
1349
|
</react_native_1.Text>
|
|
1173
1350
|
</react_native_1.View>
|
|
1174
1351
|
<react_native_1.View style={bundleStyles.subsystemItem}>
|
|
1175
1352
|
<react_native_1.Text style={bundleStyles.subsystemItemText}>
|
|
1176
|
-
Top Package:
|
|
1353
|
+
Top Package:{' '}
|
|
1354
|
+
<react_native_1.Text style={bundleStyles.subsystemItemVal}>
|
|
1355
|
+
{bundlePackages[0]?.name || 'react-native'} (
|
|
1356
|
+
{bundlePackages[0]?.sizeKb || 1240} KB)
|
|
1357
|
+
</react_native_1.Text>
|
|
1177
1358
|
</react_native_1.Text>
|
|
1178
1359
|
</react_native_1.View>
|
|
1179
1360
|
</react_native_1.View>
|
|
@@ -1184,28 +1365,50 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
1184
1365
|
<react_native_1.View style={bundleStyles.subsystemHeader}>
|
|
1185
1366
|
<react_native_1.View style={{ flexDirection: 'row', alignItems: 'center', gap: 6 }}>
|
|
1186
1367
|
<BundleCategoryIcon type="source" size={16} color={AppColors_1.AppColors.sky500}/>
|
|
1187
|
-
<react_native_1.Text style={bundleStyles.subsystemTitle}>
|
|
1368
|
+
<react_native_1.Text style={bundleStyles.subsystemTitle}>
|
|
1369
|
+
Application Source Code
|
|
1370
|
+
</react_native_1.Text>
|
|
1188
1371
|
</react_native_1.View>
|
|
1189
|
-
<react_native_1.View style={[
|
|
1190
|
-
|
|
1191
|
-
|
|
1372
|
+
<react_native_1.View style={[
|
|
1373
|
+
bundleStyles.subsystemBadge,
|
|
1374
|
+
{ backgroundColor: `${AppColors_1.AppColors.sky500}18` },
|
|
1375
|
+
]}>
|
|
1376
|
+
<react_native_1.Text style={[
|
|
1377
|
+
bundleStyles.subsystemBadgeText,
|
|
1378
|
+
{ color: AppColors_1.AppColors.sky500 },
|
|
1379
|
+
]}>
|
|
1380
|
+
{(summary.appSourceKb / 1024).toFixed(1)} MB •{' '}
|
|
1381
|
+
{summary.appSourcePct}%
|
|
1192
1382
|
</react_native_1.Text>
|
|
1193
1383
|
</react_native_1.View>
|
|
1194
1384
|
</react_native_1.View>
|
|
1195
1385
|
<react_native_1.View style={bundleStyles.subsystemGrid}>
|
|
1196
1386
|
<react_native_1.View style={bundleStyles.subsystemItem}>
|
|
1197
1387
|
<react_native_1.Text style={bundleStyles.subsystemItemText}>
|
|
1198
|
-
TypeScript/TSX:
|
|
1388
|
+
TypeScript/TSX:{' '}
|
|
1389
|
+
<react_native_1.Text style={bundleStyles.subsystemItemVal}>
|
|
1390
|
+
{bundleFiles.filter(f => f.category === 'typescript')
|
|
1391
|
+
.length || 14}{' '}
|
|
1392
|
+
files
|
|
1393
|
+
</react_native_1.Text>
|
|
1199
1394
|
</react_native_1.Text>
|
|
1200
1395
|
</react_native_1.View>
|
|
1201
1396
|
<react_native_1.View style={bundleStyles.subsystemItem}>
|
|
1202
1397
|
<react_native_1.Text style={bundleStyles.subsystemItemText}>
|
|
1203
|
-
JavaScript/JSX:
|
|
1398
|
+
JavaScript/JSX:{' '}
|
|
1399
|
+
<react_native_1.Text style={bundleStyles.subsystemItemVal}>
|
|
1400
|
+
{bundleFiles.filter(f => f.category === 'javascript')
|
|
1401
|
+
.length || 3}{' '}
|
|
1402
|
+
files
|
|
1403
|
+
</react_native_1.Text>
|
|
1204
1404
|
</react_native_1.Text>
|
|
1205
1405
|
</react_native_1.View>
|
|
1206
1406
|
<react_native_1.View style={bundleStyles.subsystemItem}>
|
|
1207
1407
|
<react_native_1.Text style={bundleStyles.subsystemItemText}>
|
|
1208
|
-
Tracked Modules:
|
|
1408
|
+
Tracked Modules:{' '}
|
|
1409
|
+
<react_native_1.Text style={bundleStyles.subsystemItemVal}>
|
|
1410
|
+
{bundleFiles.length || 18} files
|
|
1411
|
+
</react_native_1.Text>
|
|
1209
1412
|
</react_native_1.Text>
|
|
1210
1413
|
</react_native_1.View>
|
|
1211
1414
|
</react_native_1.View>
|
|
@@ -1216,10 +1419,18 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
1216
1419
|
<react_native_1.View style={bundleStyles.subsystemHeader}>
|
|
1217
1420
|
<react_native_1.View style={{ flexDirection: 'row', alignItems: 'center', gap: 6 }}>
|
|
1218
1421
|
<BundleCategoryIcon type="bolt" size={16} color={AppColors_1.AppColors.emerald600}/>
|
|
1219
|
-
<react_native_1.Text style={bundleStyles.subsystemTitle}>
|
|
1422
|
+
<react_native_1.Text style={bundleStyles.subsystemTitle}>
|
|
1423
|
+
Hermes Bytecode Engine
|
|
1424
|
+
</react_native_1.Text>
|
|
1220
1425
|
</react_native_1.View>
|
|
1221
|
-
<react_native_1.View style={[
|
|
1222
|
-
|
|
1426
|
+
<react_native_1.View style={[
|
|
1427
|
+
bundleStyles.subsystemBadge,
|
|
1428
|
+
{ backgroundColor: `${AppColors_1.AppColors.emerald500}18` },
|
|
1429
|
+
]}>
|
|
1430
|
+
<react_native_1.Text style={[
|
|
1431
|
+
bundleStyles.subsystemBadgeText,
|
|
1432
|
+
{ color: AppColors_1.AppColors.emerald700 },
|
|
1433
|
+
]}>
|
|
1223
1434
|
~62% AOT Compression
|
|
1224
1435
|
</react_native_1.Text>
|
|
1225
1436
|
</react_native_1.View>
|
|
@@ -1227,17 +1438,26 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
1227
1438
|
<react_native_1.View style={bundleStyles.subsystemGrid}>
|
|
1228
1439
|
<react_native_1.View style={bundleStyles.subsystemItem}>
|
|
1229
1440
|
<react_native_1.Text style={bundleStyles.subsystemItemText}>
|
|
1230
|
-
Dev JS Size:
|
|
1441
|
+
Dev JS Size:{' '}
|
|
1442
|
+
<react_native_1.Text style={bundleStyles.subsystemItemVal}>
|
|
1443
|
+
{summary.totalMb} MB
|
|
1444
|
+
</react_native_1.Text>
|
|
1231
1445
|
</react_native_1.Text>
|
|
1232
1446
|
</react_native_1.View>
|
|
1233
1447
|
<react_native_1.View style={bundleStyles.subsystemItem}>
|
|
1234
1448
|
<react_native_1.Text style={bundleStyles.subsystemItemText}>
|
|
1235
|
-
Hermes Bytecode:
|
|
1449
|
+
Hermes Bytecode:{' '}
|
|
1450
|
+
<react_native_1.Text style={bundleStyles.subsystemItemVal}>
|
|
1451
|
+
{((summary.totalKb * 0.38) / 1024).toFixed(2)} MB
|
|
1452
|
+
</react_native_1.Text>
|
|
1236
1453
|
</react_native_1.Text>
|
|
1237
1454
|
</react_native_1.View>
|
|
1238
1455
|
<react_native_1.View style={bundleStyles.subsystemItem}>
|
|
1239
1456
|
<react_native_1.Text style={bundleStyles.subsystemItemText}>
|
|
1240
|
-
Execution:
|
|
1457
|
+
Execution:{' '}
|
|
1458
|
+
<react_native_1.Text style={bundleStyles.subsystemItemVal}>
|
|
1459
|
+
{isHermes ? 'Hermes JSI Direct' : 'JSC Standard'}
|
|
1460
|
+
</react_native_1.Text>
|
|
1241
1461
|
</react_native_1.Text>
|
|
1242
1462
|
</react_native_1.View>
|
|
1243
1463
|
</react_native_1.View>
|
|
@@ -1248,10 +1468,18 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
1248
1468
|
<react_native_1.View style={bundleStyles.subsystemHeader}>
|
|
1249
1469
|
<react_native_1.View style={{ flexDirection: 'row', alignItems: 'center', gap: 6 }}>
|
|
1250
1470
|
<BundleCategoryIcon type="media" size={16} color={AppColors_1.AppColors.pink500}/>
|
|
1251
|
-
<react_native_1.Text style={bundleStyles.subsystemTitle}>
|
|
1471
|
+
<react_native_1.Text style={bundleStyles.subsystemTitle}>
|
|
1472
|
+
Images, Fonts & Static Assets
|
|
1473
|
+
</react_native_1.Text>
|
|
1252
1474
|
</react_native_1.View>
|
|
1253
|
-
<react_native_1.View style={[
|
|
1254
|
-
|
|
1475
|
+
<react_native_1.View style={[
|
|
1476
|
+
bundleStyles.subsystemBadge,
|
|
1477
|
+
{ backgroundColor: `${AppColors_1.AppColors.pink500}18` },
|
|
1478
|
+
]}>
|
|
1479
|
+
<react_native_1.Text style={[
|
|
1480
|
+
bundleStyles.subsystemBadgeText,
|
|
1481
|
+
{ color: AppColors_1.AppColors.pink500 },
|
|
1482
|
+
]}>
|
|
1255
1483
|
{summary.assetsMediaKb} KB • {summary.assetsMediaPct}%
|
|
1256
1484
|
</react_native_1.Text>
|
|
1257
1485
|
</react_native_1.View>
|
|
@@ -1259,17 +1487,32 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
1259
1487
|
<react_native_1.View style={bundleStyles.subsystemGrid}>
|
|
1260
1488
|
<react_native_1.View style={bundleStyles.subsystemItem}>
|
|
1261
1489
|
<react_native_1.Text style={bundleStyles.subsystemItemText}>
|
|
1262
|
-
Images & Icons:
|
|
1490
|
+
Images & Icons:{' '}
|
|
1491
|
+
<react_native_1.Text style={bundleStyles.subsystemItemVal}>
|
|
1492
|
+
{bundleFiles.filter(f => f.category === 'image').length ||
|
|
1493
|
+
2}{' '}
|
|
1494
|
+
assets
|
|
1495
|
+
</react_native_1.Text>
|
|
1263
1496
|
</react_native_1.Text>
|
|
1264
1497
|
</react_native_1.View>
|
|
1265
1498
|
<react_native_1.View style={bundleStyles.subsystemItem}>
|
|
1266
1499
|
<react_native_1.Text style={bundleStyles.subsystemItemText}>
|
|
1267
|
-
JSON Data:
|
|
1500
|
+
JSON Data:{' '}
|
|
1501
|
+
<react_native_1.Text style={bundleStyles.subsystemItemVal}>
|
|
1502
|
+
{bundleFiles.filter(f => f.category === 'json').length ||
|
|
1503
|
+
1}{' '}
|
|
1504
|
+
files
|
|
1505
|
+
</react_native_1.Text>
|
|
1268
1506
|
</react_native_1.Text>
|
|
1269
1507
|
</react_native_1.View>
|
|
1270
1508
|
<react_native_1.View style={bundleStyles.subsystemItem}>
|
|
1271
1509
|
<react_native_1.Text style={bundleStyles.subsystemItemText}>
|
|
1272
|
-
Custom Fonts:
|
|
1510
|
+
Custom Fonts:{' '}
|
|
1511
|
+
<react_native_1.Text style={bundleStyles.subsystemItemVal}>
|
|
1512
|
+
{bundleFiles.filter(f => f.category === 'font').length ||
|
|
1513
|
+
0}{' '}
|
|
1514
|
+
fonts
|
|
1515
|
+
</react_native_1.Text>
|
|
1273
1516
|
</react_native_1.Text>
|
|
1274
1517
|
</react_native_1.View>
|
|
1275
1518
|
</react_native_1.View>
|
|
@@ -1281,13 +1524,24 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
1281
1524
|
{/* ── 2. TAB: PRODUCTION BUILDS & PLATFORMS ───────────────────────────── */}
|
|
1282
1525
|
{/* ══════════════════════════════════════════════════════════════════════ */}
|
|
1283
1526
|
{activeSubTab === 'production' && (<react_native_1.ScrollView style={{ flex: 1 }} contentContainerStyle={bundleStyles.contentContainer} keyboardShouldPersistTaps="handled">
|
|
1284
|
-
|
|
1285
1527
|
{/* Platform Segmented Switcher (Horizontally Scrollable) */}
|
|
1286
1528
|
<react_native_1.ScrollView horizontal showsHorizontalScrollIndicator={false} contentContainerStyle={bundleStyles.prodPlatformScroll}>
|
|
1287
1529
|
{[
|
|
1288
|
-
{
|
|
1289
|
-
|
|
1290
|
-
|
|
1530
|
+
{
|
|
1531
|
+
key: 'ios',
|
|
1532
|
+
label: 'iOS App (.ipa)',
|
|
1533
|
+
badge: `${analysis?.production.ios.totalDownloadMb || 111.9} MB`,
|
|
1534
|
+
},
|
|
1535
|
+
{
|
|
1536
|
+
key: 'androidAab',
|
|
1537
|
+
label: 'Android AAB (.aab)',
|
|
1538
|
+
badge: `${analysis?.production.androidAab.totalDownloadMb || 38.5} MB`,
|
|
1539
|
+
},
|
|
1540
|
+
{
|
|
1541
|
+
key: 'androidApk',
|
|
1542
|
+
label: 'Universal APK (.apk)',
|
|
1543
|
+
badge: `${analysis?.production.androidApk.totalInstallMb || 364.0} MB`,
|
|
1544
|
+
},
|
|
1291
1545
|
].map(tab => {
|
|
1292
1546
|
const isSelected = prodPlatform === tab.key;
|
|
1293
1547
|
return (<TouchableScale_1.default key={tab.key} accessible={true} accessibilityRole="tab" accessibilityLabel={`${tab.label}, ${tab.badge}`} accessibilityState={{ selected: isSelected }} accessibilityHint={`Switches production estimate to ${tab.label}`} onPress={() => setProdPlatform(tab.key)} style={[
|
|
@@ -1344,31 +1598,51 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
1344
1598
|
<react_native_1.View style={bundleStyles.metricsGrid}>
|
|
1345
1599
|
<react_native_1.View style={bundleStyles.metricBox}>
|
|
1346
1600
|
<react_native_1.Text style={bundleStyles.metricLabel}>INSTALL SIZE</react_native_1.Text>
|
|
1347
|
-
<react_native_1.Text style={[
|
|
1601
|
+
<react_native_1.Text style={[
|
|
1602
|
+
bundleStyles.metricValue,
|
|
1603
|
+
{ color: AppColors_1.AppColors.purple },
|
|
1604
|
+
]}>
|
|
1348
1605
|
{analysis.production[prodPlatform].totalInstallMb} MB
|
|
1349
1606
|
</react_native_1.Text>
|
|
1350
|
-
<react_native_1.Text style={bundleStyles.metricHint}>
|
|
1607
|
+
<react_native_1.Text style={bundleStyles.metricHint}>
|
|
1608
|
+
On-device uncompressed footprint
|
|
1609
|
+
</react_native_1.Text>
|
|
1351
1610
|
</react_native_1.View>
|
|
1352
1611
|
|
|
1353
1612
|
<react_native_1.View style={bundleStyles.metricBox}>
|
|
1354
1613
|
<react_native_1.Text style={bundleStyles.metricLabel}>DOWNLOAD SIZE</react_native_1.Text>
|
|
1355
|
-
<react_native_1.Text style={[
|
|
1614
|
+
<react_native_1.Text style={[
|
|
1615
|
+
bundleStyles.metricValue,
|
|
1616
|
+
{ color: AppColors_1.AppColors.emerald600 },
|
|
1617
|
+
]}>
|
|
1356
1618
|
~{analysis.production[prodPlatform].totalDownloadMb} MB
|
|
1357
1619
|
</react_native_1.Text>
|
|
1358
|
-
<react_native_1.Text style={bundleStyles.metricHint}>
|
|
1620
|
+
<react_native_1.Text style={bundleStyles.metricHint}>
|
|
1621
|
+
Store network transfer payload
|
|
1622
|
+
</react_native_1.Text>
|
|
1359
1623
|
</react_native_1.View>
|
|
1360
1624
|
|
|
1361
1625
|
<react_native_1.View style={bundleStyles.metricBox}>
|
|
1362
1626
|
<react_native_1.Text style={bundleStyles.metricLabel}>COMPRESSION</react_native_1.Text>
|
|
1363
|
-
<react_native_1.Text style={[
|
|
1627
|
+
<react_native_1.Text style={[
|
|
1628
|
+
bundleStyles.metricValue,
|
|
1629
|
+
{ color: AppColors_1.AppColors.sky500 },
|
|
1630
|
+
]}>
|
|
1364
1631
|
{analysis.production[prodPlatform].compressionRatioPct}%
|
|
1365
1632
|
</react_native_1.Text>
|
|
1366
|
-
<react_native_1.Text style={bundleStyles.metricHint}>
|
|
1633
|
+
<react_native_1.Text style={bundleStyles.metricHint}>
|
|
1634
|
+
Bytecode & asset ratio
|
|
1635
|
+
</react_native_1.Text>
|
|
1367
1636
|
</react_native_1.View>
|
|
1368
1637
|
|
|
1369
1638
|
<react_native_1.View style={bundleStyles.metricBox}>
|
|
1370
|
-
<react_native_1.Text style={bundleStyles.metricLabel}>
|
|
1371
|
-
|
|
1639
|
+
<react_native_1.Text style={bundleStyles.metricLabel}>
|
|
1640
|
+
FORMAT ARCHITECTURE
|
|
1641
|
+
</react_native_1.Text>
|
|
1642
|
+
<react_native_1.Text style={[
|
|
1643
|
+
bundleStyles.metricValue,
|
|
1644
|
+
{ color: AppColors_1.AppColors.amber700 },
|
|
1645
|
+
]}>
|
|
1372
1646
|
{prodPlatform === 'ios'
|
|
1373
1647
|
? 'Mach-O 64-bit'
|
|
1374
1648
|
: prodPlatform === 'androidAab'
|
|
@@ -1389,10 +1663,13 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
1389
1663
|
{/* Component Breakdown Cards */}
|
|
1390
1664
|
{analysis && (<react_native_1.View style={bundleStyles.sectionCard}>
|
|
1391
1665
|
<react_native_1.View style={bundleStyles.sectionHeaderRow}>
|
|
1392
|
-
<react_native_1.View>
|
|
1393
|
-
<react_native_1.Text style={bundleStyles.sectionTitle}>
|
|
1666
|
+
<react_native_1.View style={{ flex: 1, paddingRight: 4 }}>
|
|
1667
|
+
<react_native_1.Text style={bundleStyles.sectionTitle}>
|
|
1668
|
+
Binary Component Architecture
|
|
1669
|
+
</react_native_1.Text>
|
|
1394
1670
|
<react_native_1.Text style={bundleStyles.sectionSub}>
|
|
1395
|
-
Compiled native libraries, runtime bytecodes, assets, and
|
|
1671
|
+
Compiled native libraries, runtime bytecodes, assets, and
|
|
1672
|
+
signature blocks
|
|
1396
1673
|
</react_native_1.Text>
|
|
1397
1674
|
</react_native_1.View>
|
|
1398
1675
|
<CopyButton_1.default value={() => analysis.production[prodPlatform].components} label="Components JSON"/>
|
|
@@ -1410,26 +1687,29 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
1410
1687
|
{/* Production Binary Legend */}
|
|
1411
1688
|
<react_native_1.View style={[bundleStyles.legendGrid, { marginBottom: 12 }]}>
|
|
1412
1689
|
{analysis.production[prodPlatform].components.map((comp, cIdx) => (<react_native_1.View key={cIdx} style={bundleStyles.legendItem}>
|
|
1413
|
-
|
|
1690
|
+
<react_native_1.View style={{
|
|
1414
1691
|
width: 8,
|
|
1415
1692
|
height: 8,
|
|
1416
1693
|
borderRadius: 4,
|
|
1417
1694
|
backgroundColor: comp.color,
|
|
1418
1695
|
}}/>
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1696
|
+
<react_native_1.Text style={bundleStyles.legendText} numberOfLines={1}>
|
|
1697
|
+
{comp.name}{' '}
|
|
1698
|
+
<react_native_1.Text style={bundleStyles.legendVal}>
|
|
1699
|
+
{comp.sizeMb} MB ({comp.pct}%)
|
|
1700
|
+
</react_native_1.Text>
|
|
1423
1701
|
</react_native_1.Text>
|
|
1424
|
-
</react_native_1.
|
|
1425
|
-
</react_native_1.View>))}
|
|
1702
|
+
</react_native_1.View>))}
|
|
1426
1703
|
</react_native_1.View>
|
|
1427
1704
|
|
|
1428
1705
|
{analysis.production[prodPlatform].components.map((comp, idx) => (<react_native_1.View key={idx} style={bundleStyles.catRowCard}>
|
|
1429
1706
|
<react_native_1.View style={bundleStyles.catRowTop}>
|
|
1430
1707
|
<react_native_1.View style={[
|
|
1431
1708
|
bundleStyles.catIconBox,
|
|
1432
|
-
{
|
|
1709
|
+
{
|
|
1710
|
+
backgroundColor: `${comp.color}15`,
|
|
1711
|
+
borderColor: `${comp.color}30`,
|
|
1712
|
+
},
|
|
1433
1713
|
]}>
|
|
1434
1714
|
<BundleCategoryIcon type={comp.category === 'native'
|
|
1435
1715
|
? 'source'
|
|
@@ -1443,17 +1723,31 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
1443
1723
|
</react_native_1.View>
|
|
1444
1724
|
|
|
1445
1725
|
<react_native_1.View style={bundleStyles.catRowTitleWrap}>
|
|
1446
|
-
<react_native_1.View style={{
|
|
1726
|
+
<react_native_1.View style={{
|
|
1727
|
+
flexDirection: 'row',
|
|
1728
|
+
alignItems: 'center',
|
|
1729
|
+
justifyContent: 'space-between',
|
|
1730
|
+
gap: 6,
|
|
1731
|
+
}}>
|
|
1447
1732
|
<react_native_1.Text style={bundleStyles.catRowTitle} numberOfLines={1}>
|
|
1448
1733
|
{comp.name}
|
|
1449
1734
|
</react_native_1.Text>
|
|
1450
|
-
<react_native_1.View style={{
|
|
1451
|
-
|
|
1735
|
+
<react_native_1.View style={{
|
|
1736
|
+
flexDirection: 'row',
|
|
1737
|
+
alignItems: 'center',
|
|
1738
|
+
gap: 6,
|
|
1739
|
+
}}>
|
|
1740
|
+
<react_native_1.Text style={bundleStyles.catRowSize}>
|
|
1741
|
+
{comp.sizeMb} MB
|
|
1742
|
+
</react_native_1.Text>
|
|
1452
1743
|
<react_native_1.View style={[
|
|
1453
1744
|
bundleStyles.catPctPill,
|
|
1454
1745
|
{ backgroundColor: `${comp.color}18` },
|
|
1455
1746
|
]}>
|
|
1456
|
-
<react_native_1.Text style={[
|
|
1747
|
+
<react_native_1.Text style={[
|
|
1748
|
+
bundleStyles.catPctText,
|
|
1749
|
+
{ color: comp.color },
|
|
1750
|
+
]}>
|
|
1457
1751
|
{comp.pct}%
|
|
1458
1752
|
</react_native_1.Text>
|
|
1459
1753
|
</react_native_1.View>
|
|
@@ -1473,9 +1767,16 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
1473
1767
|
]}/>
|
|
1474
1768
|
</react_native_1.View>
|
|
1475
1769
|
|
|
1476
|
-
{comp.advice ? (<react_native_1.View style={[
|
|
1770
|
+
{comp.advice ? (<react_native_1.View style={[
|
|
1771
|
+
bundleStyles.adviceBadge,
|
|
1772
|
+
bundleStyles.adviceOptimal,
|
|
1773
|
+
{ marginTop: 6 },
|
|
1774
|
+
]}>
|
|
1477
1775
|
<NetworkIcons_1.LightbulbIcon color={AppColors_1.AppColors.emerald700} size={13}/>
|
|
1478
|
-
<react_native_1.Text style={[
|
|
1776
|
+
<react_native_1.Text style={[
|
|
1777
|
+
bundleStyles.adviceText,
|
|
1778
|
+
{ color: AppColors_1.AppColors.emerald700, flex: 1, marginLeft: 4 },
|
|
1779
|
+
]}>
|
|
1479
1780
|
{comp.advice}
|
|
1480
1781
|
</react_native_1.Text>
|
|
1481
1782
|
</react_native_1.View>) : null}
|
|
@@ -1510,21 +1811,33 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
1510
1811
|
{/* Platform Metric Grid Chips */}
|
|
1511
1812
|
<react_native_1.View style={bundleStyles.totalFormulaGrid}>
|
|
1512
1813
|
<react_native_1.View style={bundleStyles.totalChip}>
|
|
1513
|
-
<react_native_1.View style={[
|
|
1814
|
+
<react_native_1.View style={[
|
|
1815
|
+
bundleStyles.totalDot,
|
|
1816
|
+
{ backgroundColor: AppColors_1.AppColors.purple },
|
|
1817
|
+
]}/>
|
|
1514
1818
|
<react_native_1.Text style={bundleStyles.totalChipText}>
|
|
1515
|
-
Install:
|
|
1819
|
+
Install:{' '}
|
|
1820
|
+
{analysis.production[prodPlatform].totalInstallMb} MB
|
|
1516
1821
|
</react_native_1.Text>
|
|
1517
1822
|
</react_native_1.View>
|
|
1518
1823
|
<react_native_1.View style={bundleStyles.totalChip}>
|
|
1519
|
-
<react_native_1.View style={[
|
|
1824
|
+
<react_native_1.View style={[
|
|
1825
|
+
bundleStyles.totalDot,
|
|
1826
|
+
{ backgroundColor: AppColors_1.AppColors.sky500 },
|
|
1827
|
+
]}/>
|
|
1520
1828
|
<react_native_1.Text style={bundleStyles.totalChipText}>
|
|
1521
|
-
Download: ~
|
|
1829
|
+
Download: ~
|
|
1830
|
+
{analysis.production[prodPlatform].totalDownloadMb} MB
|
|
1522
1831
|
</react_native_1.Text>
|
|
1523
1832
|
</react_native_1.View>
|
|
1524
1833
|
<react_native_1.View style={bundleStyles.totalChip}>
|
|
1525
|
-
<react_native_1.View style={[
|
|
1834
|
+
<react_native_1.View style={[
|
|
1835
|
+
bundleStyles.totalDot,
|
|
1836
|
+
{ backgroundColor: AppColors_1.AppColors.emerald500 },
|
|
1837
|
+
]}/>
|
|
1526
1838
|
<react_native_1.Text style={bundleStyles.totalChipText}>
|
|
1527
|
-
Compression:
|
|
1839
|
+
Compression:{' '}
|
|
1840
|
+
{analysis.production[prodPlatform].compressionRatioPct}%
|
|
1528
1841
|
</react_native_1.Text>
|
|
1529
1842
|
</react_native_1.View>
|
|
1530
1843
|
</react_native_1.View>
|
|
@@ -1561,8 +1874,16 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
1561
1874
|
return (<TouchableScale_1.default key={tab.key} accessible={true} accessibilityRole="button" accessibilityLabel={`Filter by ${t(tab.labelKey)}, ${count} items`} accessibilityState={{ selected: isActive }} accessibilityHint={`Filters files list to ${t(tab.labelKey)}`} onPress={() => setActiveCategory(tab.key)} style={[
|
|
1562
1875
|
bundleStyles.catPill,
|
|
1563
1876
|
isActive && bundleStyles.catPillActive,
|
|
1564
|
-
tab.key === 'UNUSED' &&
|
|
1565
|
-
|
|
1877
|
+
tab.key === 'UNUSED' &&
|
|
1878
|
+
isActive && {
|
|
1879
|
+
backgroundColor: AppColors_1.AppColors.red500,
|
|
1880
|
+
borderColor: AppColors_1.AppColors.red600,
|
|
1881
|
+
},
|
|
1882
|
+
tab.key === 'CONSUMED' &&
|
|
1883
|
+
isActive && {
|
|
1884
|
+
backgroundColor: AppColors_1.AppColors.emerald600,
|
|
1885
|
+
borderColor: AppColors_1.AppColors.emerald700,
|
|
1886
|
+
},
|
|
1566
1887
|
]}>
|
|
1567
1888
|
<BundleCategoryIcon type={tab.iconType} size={12} color={isActive ? AppColors_1.AppColors.white : AppColors_1.AppColors.grayTextStrong}/>
|
|
1568
1889
|
<react_native_1.Text style={[
|
|
@@ -1578,7 +1899,6 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
1578
1899
|
|
|
1579
1900
|
{/* Files List / Tree Content */}
|
|
1580
1901
|
<react_native_1.ScrollView style={{ flex: 1 }} contentContainerStyle={bundleStyles.contentContainer} keyboardShouldPersistTaps="handled">
|
|
1581
|
-
|
|
1582
1902
|
{/* View Mode Toggle Header Bar */}
|
|
1583
1903
|
<react_native_1.View style={bundleStyles.treeHeaderRow}>
|
|
1584
1904
|
<react_native_1.View style={bundleStyles.viewModeToggleGroup}>
|
|
@@ -1588,7 +1908,8 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
1588
1908
|
]}>
|
|
1589
1909
|
<react_native_1.Text style={[
|
|
1590
1910
|
bundleStyles.viewModeBtnText,
|
|
1591
|
-
filesViewMode === 'tree' &&
|
|
1911
|
+
filesViewMode === 'tree' &&
|
|
1912
|
+
bundleStyles.viewModeBtnTextActive,
|
|
1592
1913
|
]}>
|
|
1593
1914
|
{t('bundle.treeView')}
|
|
1594
1915
|
</react_native_1.Text>
|
|
@@ -1599,7 +1920,8 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
1599
1920
|
]}>
|
|
1600
1921
|
<react_native_1.Text style={[
|
|
1601
1922
|
bundleStyles.viewModeBtnText,
|
|
1602
|
-
filesViewMode === 'list' &&
|
|
1923
|
+
filesViewMode === 'list' &&
|
|
1924
|
+
bundleStyles.viewModeBtnTextActive,
|
|
1603
1925
|
]}>
|
|
1604
1926
|
{t('bundle.flatList')}
|
|
1605
1927
|
</react_native_1.Text>
|
|
@@ -1608,11 +1930,17 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
1608
1930
|
|
|
1609
1931
|
{filesViewMode === 'tree' ? (<react_native_1.View style={{ flexDirection: 'row', alignItems: 'center', gap: 8 }}>
|
|
1610
1932
|
<TouchableScale_1.default accessible={true} accessibilityRole="button" accessibilityLabel="Expand all folders" onPress={expandAllFolders}>
|
|
1611
|
-
<react_native_1.Text style={bundleStyles.treeActionLink}>
|
|
1933
|
+
<react_native_1.Text style={bundleStyles.treeActionLink}>
|
|
1934
|
+
{t('bundle.expand')}
|
|
1935
|
+
</react_native_1.Text>
|
|
1612
1936
|
</TouchableScale_1.default>
|
|
1613
|
-
<react_native_1.Text style={{ color: AppColors_1.AppColors.grayTextWeak, fontSize: 11 }}
|
|
1937
|
+
<react_native_1.Text style={{ color: AppColors_1.AppColors.grayTextWeak, fontSize: 11 }}>
|
|
1938
|
+
•
|
|
1939
|
+
</react_native_1.Text>
|
|
1614
1940
|
<TouchableScale_1.default accessible={true} accessibilityRole="button" accessibilityLabel="Collapse all folders" onPress={collapseAllFolders}>
|
|
1615
|
-
<react_native_1.Text style={bundleStyles.treeActionLink}>
|
|
1941
|
+
<react_native_1.Text style={bundleStyles.treeActionLink}>
|
|
1942
|
+
{t('bundle.collapse')}
|
|
1943
|
+
</react_native_1.Text>
|
|
1616
1944
|
</TouchableScale_1.default>
|
|
1617
1945
|
</react_native_1.View>) : (<react_native_1.Text style={bundleStyles.listHeaderCount}>
|
|
1618
1946
|
{t('bundle.showingFilesOf', {
|
|
@@ -1629,9 +1957,13 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
1629
1957
|
/* ── MODE 2: FLAT LIST VIEW ── */
|
|
1630
1958
|
filteredFiles.map((file, index) => {
|
|
1631
1959
|
const categoryMeta = CATEGORY_COLORS[file.category] || CATEGORY_COLORS.typescript;
|
|
1632
|
-
const pctOfTotal = ((file.sizeKb / summary.totalKb) *
|
|
1960
|
+
const pctOfTotal = ((file.sizeKb / summary.totalKb) *
|
|
1961
|
+
100).toFixed(1);
|
|
1633
1962
|
const isUnused = file.isConsumed === false;
|
|
1634
|
-
return (<react_native_1.View key={file.id} style={[
|
|
1963
|
+
return (<react_native_1.View key={file.id} style={[
|
|
1964
|
+
bundleStyles.fileCard,
|
|
1965
|
+
isUnused && bundleStyles.treeFileCardUnused,
|
|
1966
|
+
]}>
|
|
1635
1967
|
<react_native_1.View style={bundleStyles.fileCardTop}>
|
|
1636
1968
|
<react_native_1.View style={bundleStyles.sNoBadge}>
|
|
1637
1969
|
<react_native_1.Text style={bundleStyles.sNoText}>#{index + 1}</react_native_1.Text>
|
|
@@ -1640,25 +1972,45 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
1640
1972
|
<MediaPreviewThumbnail file={file}/>
|
|
1641
1973
|
|
|
1642
1974
|
<react_native_1.View style={{ flex: 1, paddingHorizontal: 4 }}>
|
|
1643
|
-
<react_native_1.View style={{
|
|
1975
|
+
<react_native_1.View style={{
|
|
1976
|
+
flexDirection: 'row',
|
|
1977
|
+
alignItems: 'center',
|
|
1978
|
+
gap: 6,
|
|
1979
|
+
flexWrap: 'wrap',
|
|
1980
|
+
}}>
|
|
1644
1981
|
<HighlightText_1.default text={file.name} search={search} style={bundleStyles.fileName} highlightStyle={bundleStyles.searchHighlight}/>
|
|
1645
1982
|
{isUnused ? (<react_native_1.View style={bundleStyles.unusedBadge}>
|
|
1646
|
-
<react_native_1.Text style={bundleStyles.unusedBadgeText}>
|
|
1983
|
+
<react_native_1.Text style={bundleStyles.unusedBadgeText}>
|
|
1984
|
+
{t('bundle.notConsumed')}
|
|
1985
|
+
</react_native_1.Text>
|
|
1647
1986
|
</react_native_1.View>) : (<react_native_1.View style={bundleStyles.consumedBadge}>
|
|
1648
|
-
<react_native_1.Text style={bundleStyles.consumedBadgeText}>
|
|
1987
|
+
<react_native_1.Text style={bundleStyles.consumedBadgeText}>
|
|
1988
|
+
{t('bundle.consumed')}
|
|
1989
|
+
</react_native_1.Text>
|
|
1649
1990
|
</react_native_1.View>)}
|
|
1650
1991
|
</react_native_1.View>
|
|
1651
1992
|
<HighlightText_1.default text={file.path} search={search} style={bundleStyles.filePath} highlightStyle={bundleStyles.searchHighlight} numberOfLines={1}/>
|
|
1652
1993
|
</react_native_1.View>
|
|
1653
1994
|
|
|
1654
|
-
<react_native_1.View style={{
|
|
1995
|
+
<react_native_1.View style={{
|
|
1996
|
+
flexDirection: 'row',
|
|
1997
|
+
alignItems: 'center',
|
|
1998
|
+
gap: 6,
|
|
1999
|
+
}}>
|
|
1655
2000
|
<react_native_1.View style={bundleStyles.fileSizeBox}>
|
|
1656
|
-
<react_native_1.Text style={[
|
|
2001
|
+
<react_native_1.Text style={[
|
|
2002
|
+
bundleStyles.fileSizeKb,
|
|
2003
|
+
isUnused && { color: AppColors_1.AppColors.amber800Warm },
|
|
2004
|
+
]}>
|
|
1657
2005
|
{file.sizeKb >= 1024
|
|
1658
|
-
? t('bundle.fileSizeMb', {
|
|
2006
|
+
? t('bundle.fileSizeMb', {
|
|
2007
|
+
size: (file.sizeKb / 1024).toFixed(2),
|
|
2008
|
+
})
|
|
1659
2009
|
: t('bundle.fileSizeKb', { size: file.sizeKb })}
|
|
1660
2010
|
</react_native_1.Text>
|
|
1661
|
-
<react_native_1.Text style={bundleStyles.filePercent}>
|
|
2011
|
+
<react_native_1.Text style={bundleStyles.filePercent}>
|
|
2012
|
+
{pctOfTotal}%
|
|
2013
|
+
</react_native_1.Text>
|
|
1662
2014
|
</react_native_1.View>
|
|
1663
2015
|
<TouchableScale_1.default onPress={() => (0, exports.downloadBundleFile)(file, analysis?.scriptURL)} style={bundleStyles.downloadFileBtn} hitSlop={8}>
|
|
1664
2016
|
<NetworkIcons_1.DownloadIcon size={14} color={AppColors_1.AppColors.sky500}/>
|
|
@@ -1672,7 +2024,9 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
1672
2024
|
bundleStyles.fileProgressBar,
|
|
1673
2025
|
{
|
|
1674
2026
|
width: `${Math.min(100, Math.max(4, Number(pctOfTotal) * 4))}%`,
|
|
1675
|
-
backgroundColor: isUnused
|
|
2027
|
+
backgroundColor: isUnused
|
|
2028
|
+
? AppColors_1.AppColors.red500
|
|
2029
|
+
: categoryMeta.color,
|
|
1676
2030
|
},
|
|
1677
2031
|
]}/>
|
|
1678
2032
|
</react_native_1.View>
|
|
@@ -1731,7 +2085,6 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
1731
2085
|
{/* ══════════════════════════════════════════════════════════════════════ */}
|
|
1732
2086
|
{activeSubTab === 'packages' && (<react_native_1.View style={{ flex: 1 }}>
|
|
1733
2087
|
<react_native_1.ScrollView style={{ flex: 1 }} contentContainerStyle={bundleStyles.contentContainer} keyboardShouldPersistTaps="handled">
|
|
1734
|
-
|
|
1735
2088
|
<react_native_1.View style={bundleStyles.filterContainer}>
|
|
1736
2089
|
<react_native_1.View style={bundleStyles.searchRow}>
|
|
1737
2090
|
<NetworkIcons_1.SearchIcon color={AppColors_1.AppColors.grayTextWeak} size={15}/>
|
|
@@ -1744,14 +2097,25 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
1744
2097
|
</react_native_1.View>
|
|
1745
2098
|
|
|
1746
2099
|
<react_native_1.Text style={bundleStyles.listHeaderCount}>
|
|
1747
|
-
{t('bundle.showingDependencies', {
|
|
2100
|
+
{t('bundle.showingDependencies', {
|
|
2101
|
+
count: filteredPackages.length,
|
|
2102
|
+
})}
|
|
1748
2103
|
</react_native_1.Text>
|
|
1749
2104
|
|
|
1750
2105
|
{filteredPackages.map((pkg, index) => {
|
|
1751
|
-
const cleanInstalledVersion = pkg.version
|
|
1752
|
-
|
|
2106
|
+
const cleanInstalledVersion = pkg.version
|
|
2107
|
+
? pkg.version.replace(/^\^/, '')
|
|
2108
|
+
: '';
|
|
2109
|
+
const hasUpdate = !!pkg.latestVersion &&
|
|
2110
|
+
!!cleanInstalledVersion &&
|
|
1753
2111
|
pkg.latestVersion !== cleanInstalledVersion;
|
|
1754
|
-
return (<react_native_1.View key={pkg.id} style={[
|
|
2112
|
+
return (<react_native_1.View key={pkg.id} style={[
|
|
2113
|
+
bundleStyles.fileCard,
|
|
2114
|
+
pkg.isDeprecated && {
|
|
2115
|
+
borderColor: AppColors_1.AppColors.errorBorder,
|
|
2116
|
+
backgroundColor: AppColors_1.AppColors.errorCardBg,
|
|
2117
|
+
},
|
|
2118
|
+
]}>
|
|
1755
2119
|
{/* Header Row: #s.no + Logo + Package Name + Version Pill + Update/Deprecated Badges + Size & Copy */}
|
|
1756
2120
|
<react_native_1.View style={bundleStyles.fileCardTop}>
|
|
1757
2121
|
<react_native_1.View style={bundleStyles.sNoBadge}>
|
|
@@ -1761,12 +2125,19 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
1761
2125
|
<PackageLogoRenderer name={pkg.name} color={pkg.color} size={28}/>
|
|
1762
2126
|
|
|
1763
2127
|
<react_native_1.View style={{ flex: 1, paddingHorizontal: 4 }}>
|
|
1764
|
-
<react_native_1.View style={{
|
|
2128
|
+
<react_native_1.View style={{
|
|
2129
|
+
flexDirection: 'row',
|
|
2130
|
+
alignItems: 'center',
|
|
2131
|
+
gap: 6,
|
|
2132
|
+
flexWrap: 'wrap',
|
|
2133
|
+
}}>
|
|
1765
2134
|
<HighlightText_1.default text={pkg.name} search={search} style={bundleStyles.fileName} highlightStyle={bundleStyles.searchHighlight}/>
|
|
1766
2135
|
<react_native_1.View style={bundleStyles.versionPill}>
|
|
1767
2136
|
<react_native_1.Text style={bundleStyles.versionPillText}>
|
|
1768
2137
|
{cleanInstalledVersion
|
|
1769
|
-
? t('bundle.versionPrefix', {
|
|
2138
|
+
? t('bundle.versionPrefix', {
|
|
2139
|
+
version: cleanInstalledVersion,
|
|
2140
|
+
})
|
|
1770
2141
|
: t('bundle.bundled')}
|
|
1771
2142
|
</react_native_1.Text>
|
|
1772
2143
|
</react_native_1.View>
|
|
@@ -1777,34 +2148,72 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
1777
2148
|
</react_native_1.Text>
|
|
1778
2149
|
</react_native_1.View>) : hasUpdate ? (<react_native_1.View style={bundleStyles.updateBadge}>
|
|
1779
2150
|
<react_native_1.Text style={bundleStyles.updateBadgeText}>
|
|
1780
|
-
{t('bundle.updateAvailable', {
|
|
2151
|
+
{t('bundle.updateAvailable', {
|
|
2152
|
+
version: pkg.latestVersion,
|
|
2153
|
+
})}
|
|
1781
2154
|
</react_native_1.Text>
|
|
1782
|
-
</react_native_1.View>) : cleanInstalledVersion ? (<react_native_1.View style={[
|
|
1783
|
-
|
|
2155
|
+
</react_native_1.View>) : cleanInstalledVersion ? (<react_native_1.View style={[
|
|
2156
|
+
bundleStyles.updateBadge,
|
|
2157
|
+
{
|
|
2158
|
+
backgroundColor: AppColors_1.AppColors.gray100,
|
|
2159
|
+
borderColor: AppColors_1.AppColors.gray200,
|
|
2160
|
+
},
|
|
2161
|
+
]}>
|
|
2162
|
+
<react_native_1.Text style={[
|
|
2163
|
+
bundleStyles.updateBadgeText,
|
|
2164
|
+
{ color: AppColors_1.AppColors.gray600 },
|
|
2165
|
+
]}>
|
|
1784
2166
|
{t('bundle.upToDate')}
|
|
1785
2167
|
</react_native_1.Text>
|
|
1786
|
-
</react_native_1.View>) : (<react_native_1.View style={[
|
|
1787
|
-
|
|
2168
|
+
</react_native_1.View>) : (<react_native_1.View style={[
|
|
2169
|
+
bundleStyles.updateBadge,
|
|
2170
|
+
{
|
|
2171
|
+
backgroundColor: AppColors_1.AppColors.gray100,
|
|
2172
|
+
borderColor: AppColors_1.AppColors.gray200,
|
|
2173
|
+
},
|
|
2174
|
+
]}>
|
|
2175
|
+
<react_native_1.Text style={[
|
|
2176
|
+
bundleStyles.updateBadgeText,
|
|
2177
|
+
{ color: AppColors_1.AppColors.gray600 },
|
|
2178
|
+
]}>
|
|
1788
2179
|
{t('bundle.bundledBadge')}
|
|
1789
2180
|
</react_native_1.Text>
|
|
1790
2181
|
</react_native_1.View>)}
|
|
1791
2182
|
</react_native_1.View>
|
|
1792
2183
|
</react_native_1.View>
|
|
1793
2184
|
|
|
1794
|
-
<react_native_1.View style={{
|
|
2185
|
+
<react_native_1.View style={{
|
|
2186
|
+
flexDirection: 'row',
|
|
2187
|
+
alignItems: 'center',
|
|
2188
|
+
gap: 6,
|
|
2189
|
+
}}>
|
|
1795
2190
|
<react_native_1.View style={bundleStyles.fileSizeBox}>
|
|
1796
2191
|
<react_native_1.Text style={bundleStyles.fileSizeKb}>
|
|
1797
2192
|
{t('bundle.fileSizeKb', { size: pkg.sizeKb })}
|
|
1798
2193
|
</react_native_1.Text>
|
|
1799
|
-
<react_native_1.Text style={bundleStyles.filePercent}>
|
|
2194
|
+
<react_native_1.Text style={bundleStyles.filePercent}>
|
|
2195
|
+
{pkg.percentage}%
|
|
2196
|
+
</react_native_1.Text>
|
|
1800
2197
|
</react_native_1.View>
|
|
1801
2198
|
<CopyButton_1.default value={() => pkg} label={t('bundle.packageDetailsJson')}/>
|
|
1802
2199
|
</react_native_1.View>
|
|
1803
2200
|
</react_native_1.View>
|
|
1804
2201
|
|
|
1805
2202
|
{/* Subtitle Row: Category Chip + Description */}
|
|
1806
|
-
<react_native_1.View style={{
|
|
1807
|
-
|
|
2203
|
+
<react_native_1.View style={{
|
|
2204
|
+
flexDirection: 'row',
|
|
2205
|
+
alignItems: 'center',
|
|
2206
|
+
gap: 6,
|
|
2207
|
+
marginTop: 4,
|
|
2208
|
+
marginBottom: 2,
|
|
2209
|
+
}}>
|
|
2210
|
+
<react_native_1.View style={[
|
|
2211
|
+
bundleStyles.pkgBadge,
|
|
2212
|
+
{
|
|
2213
|
+
backgroundColor: `${pkg.color}1F`,
|
|
2214
|
+
borderColor: `${pkg.color}4D`,
|
|
2215
|
+
},
|
|
2216
|
+
]}>
|
|
1808
2217
|
<react_native_1.Text style={[bundleStyles.pkgBadgeText, { color: pkg.color }]}>
|
|
1809
2218
|
{pkg.category.toUpperCase()}
|
|
1810
2219
|
</react_native_1.Text>
|
|
@@ -1816,7 +2225,11 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
1816
2225
|
|
|
1817
2226
|
{/* Deprecation Warning Banner if deprecated */}
|
|
1818
2227
|
{pkg.isDeprecated && pkg.deprecationReason && (<react_native_1.View style={bundleStyles.deprecationBox}>
|
|
1819
|
-
<react_native_1.View style={{
|
|
2228
|
+
<react_native_1.View style={{
|
|
2229
|
+
flexDirection: 'row',
|
|
2230
|
+
alignItems: 'center',
|
|
2231
|
+
gap: 5,
|
|
2232
|
+
}}>
|
|
1820
2233
|
<NetworkIcons_1.CircleAlertIcon color={AppColors_1.AppColors.errorColor} size={12}/>
|
|
1821
2234
|
<react_native_1.Text style={bundleStyles.deprecationText}>
|
|
1822
2235
|
{pkg.deprecationReason}
|
|
@@ -1827,19 +2240,39 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
1827
2240
|
<react_native_1.View style={bundleStyles.fileProgressTrack}>
|
|
1828
2241
|
<react_native_1.View style={[
|
|
1829
2242
|
bundleStyles.fileProgressBar,
|
|
1830
|
-
{
|
|
2243
|
+
{
|
|
2244
|
+
width: `${pkg.percentage * 2}%`,
|
|
2245
|
+
backgroundColor: pkg.isDeprecated
|
|
2246
|
+
? AppColors_1.AppColors.red500
|
|
2247
|
+
: pkg.color,
|
|
2248
|
+
},
|
|
1831
2249
|
]}/>
|
|
1832
2250
|
</react_native_1.View>
|
|
1833
2251
|
|
|
1834
2252
|
{/* Footer Row: Type Tag + Last Active + NPM Link Button */}
|
|
1835
|
-
<react_native_1.View style={{
|
|
1836
|
-
|
|
2253
|
+
<react_native_1.View style={{
|
|
2254
|
+
flexDirection: 'row',
|
|
2255
|
+
justifyContent: 'space-between',
|
|
2256
|
+
alignItems: 'center',
|
|
2257
|
+
marginTop: 3,
|
|
2258
|
+
}}>
|
|
2259
|
+
<react_native_1.View style={{
|
|
2260
|
+
flexDirection: 'row',
|
|
2261
|
+
alignItems: 'center',
|
|
2262
|
+
gap: 8,
|
|
2263
|
+
}}>
|
|
1837
2264
|
<react_native_1.View style={bundleStyles.typeTag}>
|
|
1838
2265
|
<react_native_1.Text style={bundleStyles.typeTagText}>
|
|
1839
|
-
{pkg.type === 'direct'
|
|
2266
|
+
{pkg.type === 'direct'
|
|
2267
|
+
? t('bundle.direct')
|
|
2268
|
+
: t('bundle.transitive')}
|
|
1840
2269
|
</react_native_1.Text>
|
|
1841
2270
|
</react_native_1.View>
|
|
1842
|
-
{pkg.lastActive && (<react_native_1.View style={{
|
|
2271
|
+
{pkg.lastActive && (<react_native_1.View style={{
|
|
2272
|
+
flexDirection: 'row',
|
|
2273
|
+
alignItems: 'center',
|
|
2274
|
+
gap: 4,
|
|
2275
|
+
}}>
|
|
1843
2276
|
<NetworkIcons_1.ClockIcon color={AppColors_1.AppColors.grayTextWeak} size={11}/>
|
|
1844
2277
|
<react_native_1.Text style={bundleStyles.lastActiveText}>
|
|
1845
2278
|
{pkg.lastActive}
|
|
@@ -1847,15 +2280,22 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
1847
2280
|
</react_native_1.View>)}
|
|
1848
2281
|
</react_native_1.View>
|
|
1849
2282
|
|
|
1850
|
-
<react_native_1.View style={{
|
|
2283
|
+
<react_native_1.View style={{
|
|
2284
|
+
flexDirection: 'row',
|
|
2285
|
+
alignItems: 'center',
|
|
2286
|
+
gap: 8,
|
|
2287
|
+
}}>
|
|
1851
2288
|
<react_native_1.Text style={bundleStyles.fileMetaText}>
|
|
1852
2289
|
{t('bundle.minified', { size: pkg.sizeKb })}
|
|
1853
2290
|
</react_native_1.Text>
|
|
1854
2291
|
<TouchableScale_1.default accessible={true} accessibilityRole="link" accessibilityLabel={`Open ${pkg.name} on NPM`} accessibilityHint="Opens NPM package page in browser" onPress={() => {
|
|
1855
|
-
const url = pkg.npmUrl ||
|
|
2292
|
+
const url = pkg.npmUrl ||
|
|
2293
|
+
`https://www.npmjs.com/package/${pkg.name}`;
|
|
1856
2294
|
react_native_1.Linking.openURL(url).catch(() => { });
|
|
1857
2295
|
}} style={bundleStyles.npmLinkBtn}>
|
|
1858
|
-
<react_native_1.Text style={bundleStyles.npmLinkText}>
|
|
2296
|
+
<react_native_1.Text style={bundleStyles.npmLinkText}>
|
|
2297
|
+
{t('bundle.npmLink')}
|
|
2298
|
+
</react_native_1.Text>
|
|
1859
2299
|
</TouchableScale_1.default>
|
|
1860
2300
|
</react_native_1.View>
|
|
1861
2301
|
</react_native_1.View>
|
|
@@ -1868,7 +2308,9 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
1868
2308
|
<react_native_1.View style={{ flexDirection: 'row', alignItems: 'center', gap: 6 }}>
|
|
1869
2309
|
<NetworkIcons_1.PackageIcon color={AppColors_1.AppColors.purple} size={14}/>
|
|
1870
2310
|
<react_native_1.Text style={bundleStyles.footerTitle}>
|
|
1871
|
-
{t('bundle.dependenciesCount', {
|
|
2311
|
+
{t('bundle.dependenciesCount', {
|
|
2312
|
+
count: filteredPackages.length,
|
|
2313
|
+
})}
|
|
1872
2314
|
</react_native_1.Text>
|
|
1873
2315
|
</react_native_1.View>
|
|
1874
2316
|
<react_native_1.Text style={bundleStyles.footerSizeVal}>
|
|
@@ -1885,22 +2327,36 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
1885
2327
|
{/* ══════════════════════════════════════════════════════════════════════ */}
|
|
1886
2328
|
{activeSubTab === 'media' && (<react_native_1.View style={{ flex: 1 }}>
|
|
1887
2329
|
<react_native_1.ScrollView style={{ flex: 1 }} contentContainerStyle={bundleStyles.contentContainer} keyboardShouldPersistTaps="handled">
|
|
1888
|
-
|
|
1889
2330
|
<react_native_1.View style={bundleStyles.tipsCard}>
|
|
1890
|
-
<react_native_1.View style={{
|
|
2331
|
+
<react_native_1.View style={{
|
|
2332
|
+
flexDirection: 'row',
|
|
2333
|
+
alignItems: 'center',
|
|
2334
|
+
justifyContent: 'space-between',
|
|
2335
|
+
marginBottom: 8,
|
|
2336
|
+
}}>
|
|
1891
2337
|
<react_native_1.View style={{ flexDirection: 'row', alignItems: 'center', gap: 6 }}>
|
|
1892
2338
|
<NetworkIcons_1.StorageIcon color={AppColors_1.AppColors.purple} size={18}/>
|
|
1893
|
-
<react_native_1.Text style={bundleStyles.tipsHeading}>
|
|
2339
|
+
<react_native_1.Text style={bundleStyles.tipsHeading}>
|
|
2340
|
+
{t('bundle.mediaAuditorTitle')}
|
|
2341
|
+
</react_native_1.Text>
|
|
1894
2342
|
</react_native_1.View>
|
|
1895
2343
|
<CopyButton_1.default value={() => mediaFiles} label={t('bundle.mediaAssetsJson')}/>
|
|
1896
2344
|
</react_native_1.View>
|
|
1897
2345
|
<react_native_1.Text style={bundleStyles.tipDesc}>
|
|
1898
2346
|
{t('bundle.mediaAuditorPrefix')}{' '}
|
|
1899
|
-
<react_native_1.Text style={{
|
|
2347
|
+
<react_native_1.Text style={{
|
|
2348
|
+
fontFamily: AppFonts_1.AppFonts.interBold,
|
|
2349
|
+
color: AppColors_1.AppColors.purple,
|
|
2350
|
+
}}>
|
|
1900
2351
|
{summary.images.pct + summary.fonts.pct}%
|
|
1901
2352
|
</react_native_1.Text>{' '}
|
|
1902
|
-
{t('bundle.mediaAuditorMid', {
|
|
1903
|
-
|
|
2353
|
+
{t('bundle.mediaAuditorMid', {
|
|
2354
|
+
kb: summary.images.kb + summary.fonts.kb,
|
|
2355
|
+
})}{' '}
|
|
2356
|
+
<react_native_1.Text style={{
|
|
2357
|
+
fontFamily: AppFonts_1.AppFonts.interBold,
|
|
2358
|
+
color: AppColors_1.AppColors.emerald700,
|
|
2359
|
+
}}>
|
|
1904
2360
|
{t('bundle.mediaSavings', { size: 540 })}
|
|
1905
2361
|
</react_native_1.Text>{' '}
|
|
1906
2362
|
{t('bundle.mediaAuditorSuffix')}
|
|
@@ -1924,7 +2380,11 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
1924
2380
|
<react_native_1.Text style={bundleStyles.filePath}>{file.path}</react_native_1.Text>
|
|
1925
2381
|
</react_native_1.View>
|
|
1926
2382
|
|
|
1927
|
-
<react_native_1.View style={{
|
|
2383
|
+
<react_native_1.View style={{
|
|
2384
|
+
flexDirection: 'row',
|
|
2385
|
+
alignItems: 'center',
|
|
2386
|
+
gap: 6,
|
|
2387
|
+
}}>
|
|
1928
2388
|
<react_native_1.View style={bundleStyles.fileSizeBox}>
|
|
1929
2389
|
<react_native_1.Text style={bundleStyles.fileSizeKb}>
|
|
1930
2390
|
{t('bundle.fileSizeKb', { size: file.sizeKb })}
|
|
@@ -1982,12 +2442,18 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
1982
2442
|
{/* ── 5. TAB: OPTIMIZER CHECKLIST ─────────────────────────────────────── */}
|
|
1983
2443
|
{/* ══════════════════════════════════════════════════════════════════════ */}
|
|
1984
2444
|
{activeSubTab === 'optimizer' && (<react_native_1.ScrollView style={{ flex: 1 }} contentContainerStyle={bundleStyles.contentContainer} keyboardShouldPersistTaps="handled">
|
|
1985
|
-
|
|
1986
2445
|
<react_native_1.View style={bundleStyles.tipsCard}>
|
|
1987
|
-
<react_native_1.View style={{
|
|
2446
|
+
<react_native_1.View style={{
|
|
2447
|
+
flexDirection: 'row',
|
|
2448
|
+
alignItems: 'center',
|
|
2449
|
+
justifyContent: 'space-between',
|
|
2450
|
+
marginBottom: 12,
|
|
2451
|
+
}}>
|
|
1988
2452
|
<react_native_1.View style={{ flexDirection: 'row', alignItems: 'center', gap: 6 }}>
|
|
1989
2453
|
<NetworkIcons_1.CircleAlertIcon color={AppColors_1.AppColors.purple} size={18}/>
|
|
1990
|
-
<react_native_1.Text style={bundleStyles.tipsHeading}>
|
|
2454
|
+
<react_native_1.Text style={bundleStyles.tipsHeading}>
|
|
2455
|
+
{t('bundle.optimizerTitle')}
|
|
2456
|
+
</react_native_1.Text>
|
|
1991
2457
|
</react_native_1.View>
|
|
1992
2458
|
<CopyButton_1.default value={() => [
|
|
1993
2459
|
t('bundle.optTip1Title'),
|
|
@@ -2014,8 +2480,12 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
2014
2480
|
desc: isHermes
|
|
2015
2481
|
? t('bundle.optTip2DescActive')
|
|
2016
2482
|
: t('bundle.optTip2DescInactive'),
|
|
2017
|
-
badge: isHermes
|
|
2018
|
-
|
|
2483
|
+
badge: isHermes
|
|
2484
|
+
? t('bundle.active')
|
|
2485
|
+
: t('bundle.actionRequired'),
|
|
2486
|
+
badgeColor: isHermes
|
|
2487
|
+
? AppColors_1.AppColors.emerald500
|
|
2488
|
+
: AppColors_1.AppColors.amber500,
|
|
2019
2489
|
},
|
|
2020
2490
|
{
|
|
2021
2491
|
iconType: 'font',
|
|
@@ -2051,8 +2521,17 @@ const BundleTab = react_1.default.memo(() => {
|
|
|
2051
2521
|
<react_native_1.Text style={bundleStyles.tipTitle}>{tip.title}</react_native_1.Text>
|
|
2052
2522
|
</react_native_1.View>
|
|
2053
2523
|
<react_native_1.View style={bundleStyles.tipActionWrap}>
|
|
2054
|
-
<react_native_1.View style={[
|
|
2055
|
-
|
|
2524
|
+
<react_native_1.View style={[
|
|
2525
|
+
bundleStyles.impactBadge,
|
|
2526
|
+
{
|
|
2527
|
+
backgroundColor: `${tip.badgeColor}18`,
|
|
2528
|
+
borderColor: `${tip.badgeColor}40`,
|
|
2529
|
+
},
|
|
2530
|
+
]}>
|
|
2531
|
+
<react_native_1.Text style={[
|
|
2532
|
+
bundleStyles.impactBadgeText,
|
|
2533
|
+
{ color: tip.badgeColor },
|
|
2534
|
+
]}>
|
|
2056
2535
|
{tip.badge}
|
|
2057
2536
|
</react_native_1.Text>
|
|
2058
2537
|
</react_native_1.View>
|
|
@@ -2275,12 +2754,14 @@ const bundleStyles = react_native_1.StyleSheet.create({
|
|
|
2275
2754
|
padding: 14,
|
|
2276
2755
|
borderWidth: 1,
|
|
2277
2756
|
borderColor: AppColors_1.AppColors.dividerColor,
|
|
2757
|
+
overflow: 'hidden',
|
|
2278
2758
|
},
|
|
2279
2759
|
sectionHeaderRow: {
|
|
2280
2760
|
flexDirection: 'row',
|
|
2281
2761
|
justifyContent: 'space-between',
|
|
2282
2762
|
alignItems: 'center',
|
|
2283
2763
|
marginBottom: 10,
|
|
2764
|
+
gap: 8,
|
|
2284
2765
|
},
|
|
2285
2766
|
sectionTitle: {
|
|
2286
2767
|
fontFamily: AppFonts_1.AppFonts.interBold,
|
|
@@ -3121,7 +3602,8 @@ const bundleStyles = react_native_1.StyleSheet.create({
|
|
|
3121
3602
|
alignItems: 'center',
|
|
3122
3603
|
backgroundColor: AppColors_1.AppColors.white,
|
|
3123
3604
|
paddingHorizontal: 16,
|
|
3124
|
-
|
|
3605
|
+
paddingTop: 10,
|
|
3606
|
+
paddingBottom: react_native_1.Platform.OS === 'ios' ? 24 : 12,
|
|
3125
3607
|
borderTopWidth: 1,
|
|
3126
3608
|
borderTopColor: AppColors_1.AppColors.dividerColor,
|
|
3127
3609
|
shadowColor: AppColors_1.AppColors.primaryBlack,
|