react-native-inapp-inspector 1.1.17 → 1.1.18

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.
@@ -62,6 +62,7 @@ const SettingsPanel = () => {
62
62
  { key: 'analytics', label: 'Analytics', icon: 'analytics' },
63
63
  { key: 'redux', label: 'Redux', icon: 'redux' },
64
64
  { key: 'bundle', label: 'Bundle', icon: 'bundle' },
65
+ { key: 'performance', label: 'Performance', icon: 'performance' },
65
66
  ];
66
67
  return (<react_native_1.View style={{ flex: 1, backgroundColor: AppColors_1.AppColors.grayBackground }}>
67
68
  {/* Settings Header with back button */}
@@ -269,6 +270,9 @@ const SettingsPanel = () => {
269
270
  {tab.icon === 'bundle' && (<NetworkIcons_1.PackageIcon color={isLocked
270
271
  ? AppColors_1.AppColors.grayTextWeak
271
272
  : AppColors_1.AppColors.purple} size={11}/>)}
273
+ {tab.icon === 'performance' && (<NetworkIcons_1.PerformanceIcon color={isLocked
274
+ ? AppColors_1.AppColors.grayTextWeak
275
+ : AppColors_1.AppColors.purple} size={11}/>)}
272
276
  </react_native_1.View>
273
277
  {/* Label + Required badge */}
274
278
  <react_native_1.Text style={{
@@ -707,6 +711,7 @@ const SettingsPanel = () => {
707
711
  {tab.icon === 'analytics' && (<NetworkIcons_1.AnalyticsIcon color={isActive ? AppColors_1.AppColors.white : AppColors_1.AppColors.purple} size={11}/>)}
708
712
  {tab.icon === 'redux' && (<NetworkIcons_1.ReduxIcon color={isActive ? AppColors_1.AppColors.white : AppColors_1.AppColors.purple} size={11}/>)}
709
713
  {tab.icon === 'bundle' && (<NetworkIcons_1.PackageIcon color={isActive ? AppColors_1.AppColors.white : AppColors_1.AppColors.purple} size={11}/>)}
714
+ {tab.icon === 'performance' && (<NetworkIcons_1.PerformanceIcon color={isActive ? AppColors_1.AppColors.white : AppColors_1.AppColors.purple} size={11}/>)}
710
715
  </react_native_1.View>
711
716
  <react_native_1.Text style={{
712
717
  fontFamily: AppFonts_1.AppFonts.interBold,
@@ -45,6 +45,12 @@ const TabBar = react_1.default.memo(() => {
45
45
  count: 0,
46
46
  icon: 'bundle',
47
47
  },
48
+ {
49
+ key: 'performance',
50
+ label: 'Performance',
51
+ count: 0,
52
+ icon: 'performance',
53
+ },
48
54
  ]
49
55
  .filter(tab => tabVisibility?.[tab.key])
50
56
  .map(tab => {
@@ -71,6 +77,7 @@ const TabBar = react_1.default.memo(() => {
71
77
  {tab.icon === 'analytics' && (<NetworkIcons_1.AnalyticsIcon color={iconColor} size={14}/>)}
72
78
  {tab.icon === 'redux' && (<NetworkIcons_1.ReduxIcon color={iconColor} size={14}/>)}
73
79
  {tab.icon === 'bundle' && (<NetworkIcons_1.PackageIcon color={iconColor} size={14}/>)}
80
+ {tab.icon === 'performance' && (<NetworkIcons_1.PerformanceIcon color={iconColor} size={14}/>)}
74
81
  <react_native_1.Text numberOfLines={1} ellipsizeMode="tail" style={[
75
82
  styles_1.default.contentTabButtonText,
76
83
  isActive &&
@@ -65,3 +65,4 @@ export declare const TimelineIcon: ({ color, size, }: any) => React.JSX.Element;
65
65
  export declare const StorageIcon: ({ color, size, }: any) => React.JSX.Element;
66
66
  export declare const MetadataIcon: ({ color, size, }: any) => React.JSX.Element;
67
67
  export declare const ReduxIcon: ({ color, size, }: any) => React.JSX.Element;
68
+ export declare const PerformanceIcon: ({ color, size, }: any) => React.JSX.Element;
@@ -37,7 +37,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
37
37
  };
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
39
  exports.InfoCircleIcon = exports.UserIcon = exports.LayersIcon = exports.WipeIcon = exports.FolderIcon = exports.SettingsIcon = exports.EyeIcon = exports.JsIcon = exports.CssIcon = exports.HtmlIcon = exports.BrandSquareIcon = exports.BrandCircleIcon = exports.MoonIcon = exports.SunIcon = exports.DebugIcon = exports.InsightsIcon = exports.AnalyticsIcon = exports.WhiteBackNavigation = exports.CloseWhite = exports.DownloadIcon = exports.FilterIcon = exports.ChevronIcon = exports.SortArrowIcon = exports.GlobeIcon = exports.DiffIcon = exports.SignalIcon = exports.ExportIcon = exports.HeaderPauseIcon = exports.TrashIcon = exports.FailIcon = exports.CircleAlertIcon = exports.CircleXIcon = exports.CircleCheckIcon = exports.CheckIcon = exports.TerminalIcon = exports.FetchIcon = exports.CopyIcon = exports.HeadersIcon = exports.ResponseIcon = exports.RequestIcon = exports.SizeIcon = exports.StatusIcon = exports.CalendarIcon = exports.ClockIcon = exports.ClearIcon = exports.SearchIcon = exports.ExpandCollapseIcon = exports.ScreenIcon = exports.MapPinIcon = exports.EmptyRadarIcon = void 0;
40
- exports.ReduxIcon = exports.MetadataIcon = exports.StorageIcon = exports.TimelineIcon = exports.LiveStateIcon = exports.BundleIcon = exports.ForwardChevronIcon = exports.PackageIcon = exports.TableIcon = exports.RawIcon = exports.PrettyIcon = exports.SortIcon = exports.MotionIcon = exports.TrendingUpIcon = exports.ErrorCircleIcon = exports.WarningTriangleIcon = void 0;
40
+ exports.PerformanceIcon = exports.ReduxIcon = exports.MetadataIcon = exports.StorageIcon = exports.TimelineIcon = exports.LiveStateIcon = exports.BundleIcon = exports.ForwardChevronIcon = exports.PackageIcon = exports.TableIcon = exports.RawIcon = exports.PrettyIcon = exports.SortIcon = exports.MotionIcon = exports.TrendingUpIcon = exports.ErrorCircleIcon = exports.WarningTriangleIcon = void 0;
41
41
  const react_1 = __importDefault(require("react"));
42
42
  const react_native_svg_1 = __importStar(require("react-native-svg"));
43
43
  // Stylesheet
@@ -499,3 +499,12 @@ const ReduxIcon = ({ color = AppColors_1.AppColors.purple, size = 14, }) => {
499
499
  </react_native_svg_1.default>);
500
500
  };
501
501
  exports.ReduxIcon = ReduxIcon;
502
+ const PerformanceIcon = ({ color = AppColors_1.AppColors.purple, size = 14, }) => {
503
+ return (<react_native_svg_1.default width={size} height={size} viewBox="0 0 24 24" fill="none">
504
+ <react_native_svg_1.Path d="M12 3v2M5.636 5.636l1.414 1.414M18.364 5.636l-1.414 1.414M3 12h2M19 12h2" stroke={color} strokeWidth="1.8" strokeLinecap="round"/>
505
+ <react_native_svg_1.Path d="M12 19a7 7 0 1 0-7-7c0 1.93.784 3.68 2.05 4.95" stroke={color} strokeWidth="1.8" strokeLinecap="round"/>
506
+ <react_native_svg_1.Path d="M12 12l3.5-3.5" stroke={color} strokeWidth="2" strokeLinecap="round"/>
507
+ <react_native_svg_1.Circle cx="12" cy="12" r="1.5" fill={color}/>
508
+ </react_native_svg_1.default>);
509
+ };
510
+ exports.PerformanceIcon = PerformanceIcon;
@@ -1 +1 @@
1
- export declare const LIB_VERSION = "1.1.17";
1
+ export declare const LIB_VERSION = "1.1.18";
@@ -3,4 +3,4 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.LIB_VERSION = void 0;
4
4
  // AUTO-GENERATED FILE — do not edit by hand.
5
5
  // Regenerated from package.json on every build by scripts/gen-version.js.
6
- exports.LIB_VERSION = '1.1.17';
6
+ exports.LIB_VERSION = '1.1.18';
@@ -189,7 +189,8 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
189
189
  logs: true,
190
190
  analytics: true,
191
191
  redux: false,
192
- bundle: true,
192
+ bundle: false,
193
+ performance: false,
193
194
  });
194
195
  const [maxNetworkLogs, setMaxNetworkLogs] = (0, react_1.useState)(100);
195
196
  const [reduxAutoRefresh, setReduxAutoRefreshState] = (0, react_1.useState)(true);
@@ -208,7 +209,8 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
208
209
  logs: true,
209
210
  analytics: true,
210
211
  redux: false,
211
- bundle: true,
212
+ bundle: false,
213
+ performance: false,
212
214
  });
213
215
  setDefaultTab('apis');
214
216
  setMaxNetworkLogs(100);
@@ -266,7 +268,8 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
266
268
  logs: true,
267
269
  analytics: true,
268
270
  redux: false,
269
- bundle: true,
271
+ bundle: false,
272
+ performance: false,
270
273
  },
271
274
  ...(saved.tabVisibility || {}),
272
275
  apis: true,
@@ -1,9 +1,9 @@
1
- export type ActiveTab = 'apis' | 'analytics' | 'logs' | 'redux' | 'bundle';
1
+ export type ActiveTab = 'apis' | 'analytics' | 'logs' | 'redux' | 'bundle' | 'performance';
2
2
  export type Method = 'ALL' | 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
3
3
  export type StatusFilter = 'ALL' | '2xx' | '3xx' | '4xx' | '5xx' | 'Failed';
4
4
  export type SortOrder = 'newest' | 'oldest';
5
5
  export type LocalFilter = 'success' | 'failed' | 'loading';
6
6
  export type ModalAnimationType = 'slide' | 'fade' | 'none';
7
- export type SettingsPage = 'main' | 'apis' | 'logs' | 'analytics' | 'redux' | 'bundle' | null;
7
+ export type SettingsPage = 'main' | 'apis' | 'logs' | 'analytics' | 'redux' | 'bundle' | 'performance' | null;
8
8
  export type SettingsSubTab = 'module' | 'ui';
9
9
  export type LogFilter = 'all' | 'info' | 'warn' | 'error' | 'user-log' | 'analytics';
@@ -26,6 +26,11 @@ export interface BundlePackageItem {
26
26
  color: string;
27
27
  description: string;
28
28
  logoUri?: string;
29
+ latestVersion?: string;
30
+ isDeprecated?: boolean;
31
+ deprecationReason?: string;
32
+ lastActive?: string;
33
+ npmUrl?: string;
29
34
  }
30
35
  export interface TreeNode {
31
36
  id: string;
@@ -1,5 +1,5 @@
1
1
  import React, { useState, useMemo, useCallback } from 'react';
2
- import { Image, Pressable, ScrollView, StyleSheet, Text, TextInput, View, } from 'react-native';
2
+ import { Image, Linking, Pressable, ScrollView, StyleSheet, Text, TextInput, View, } from 'react-native';
3
3
  import { useTranslation } from 'react-i18next';
4
4
  import TouchableScale from '../TouchableScale';
5
5
  import CopyButton from '../CopyButton';
@@ -594,6 +594,7 @@ const BUNDLE_PACKAGES_DATA = [
594
594
  id: 'pkg-1',
595
595
  name: 'react-native',
596
596
  version: '0.85.3',
597
+ latestVersion: '0.85.3',
597
598
  sizeKb: 680,
598
599
  percentage: 38.5,
599
600
  type: 'direct',
@@ -601,11 +602,15 @@ const BUNDLE_PACKAGES_DATA = [
601
602
  color: '#38BDF8',
602
603
  description: 'React Native runtime, Fabric UI engine, Native Bridge, and Turbomodules.',
603
604
  logoUri: 'https://upload.wikimedia.org/wikipedia/commons/thumb/a/a7/React-icon.svg/512px-React-icon.svg.png',
605
+ lastActive: '3 days ago',
606
+ npmUrl: 'https://www.npmjs.com/package/react-native',
607
+ isDeprecated: false,
604
608
  },
605
609
  {
606
610
  id: 'pkg-2',
607
611
  name: '@react-navigation/native-stack',
608
612
  version: '^7.16.0',
613
+ latestVersion: '7.16.0',
609
614
  sizeKb: 245,
610
615
  percentage: 13.9,
611
616
  type: 'direct',
@@ -613,11 +618,15 @@ const BUNDLE_PACKAGES_DATA = [
613
618
  color: '#818CF8',
614
619
  description: 'Native screen router, UIViewController / Fragment animations and transitions.',
615
620
  logoUri: 'https://reactnavigation.org/img/spiro.svg',
621
+ lastActive: '1 week ago',
622
+ npmUrl: 'https://www.npmjs.com/package/@react-navigation/native-stack',
623
+ isDeprecated: false,
616
624
  },
617
625
  {
618
626
  id: 'pkg-3',
619
627
  name: 'react',
620
628
  version: '19.2.3',
629
+ latestVersion: '19.2.3',
621
630
  sizeKb: 185,
622
631
  percentage: 10.5,
623
632
  type: 'direct',
@@ -625,11 +634,15 @@ const BUNDLE_PACKAGES_DATA = [
625
634
  color: '#06B6D4',
626
635
  description: 'React core virtual DOM reconciler, hooks engine, and JSX runtime.',
627
636
  logoUri: 'https://upload.wikimedia.org/wikipedia/commons/thumb/a/a7/React-icon.svg/512px-React-icon.svg.png',
637
+ lastActive: '5 days ago',
638
+ npmUrl: 'https://www.npmjs.com/package/react',
639
+ isDeprecated: false,
628
640
  },
629
641
  {
630
642
  id: 'pkg-4',
631
643
  name: 'react-native-svg',
632
644
  version: '^15.15.5',
645
+ latestVersion: '15.16.0',
633
646
  sizeKb: 140,
634
647
  percentage: 7.9,
635
648
  type: 'direct',
@@ -637,11 +650,15 @@ const BUNDLE_PACKAGES_DATA = [
637
650
  color: '#F472B6',
638
651
  description: 'Scalable Vector Graphics XML parser and native canvas path rasterizer.',
639
652
  logoUri: 'https://upload.wikimedia.org/wikipedia/commons/thumb/0/02/SVG_logo.svg/512px-SVG_logo.svg.png',
653
+ lastActive: '2 days ago',
654
+ npmUrl: 'https://www.npmjs.com/package/react-native-svg',
655
+ isDeprecated: false,
640
656
  },
641
657
  {
642
658
  id: 'pkg-5',
643
659
  name: 'react-native-screens',
644
660
  version: '^4.25.2',
661
+ latestVersion: '4.25.2',
645
662
  sizeKb: 110,
646
663
  percentage: 6.2,
647
664
  type: 'transitive',
@@ -649,11 +666,15 @@ const BUNDLE_PACKAGES_DATA = [
649
666
  color: '#A78BFA',
650
667
  description: 'Native navigation container primitives for iOS and Android memory management.',
651
668
  logoUri: 'https://reactnavigation.org/img/spiro.svg',
669
+ lastActive: '2 weeks ago',
670
+ npmUrl: 'https://www.npmjs.com/package/react-native-screens',
671
+ isDeprecated: false,
652
672
  },
653
673
  {
654
674
  id: 'pkg-6',
655
675
  name: 'axios',
656
676
  version: '^1.17.0',
677
+ latestVersion: '1.18.0',
657
678
  sizeKb: 88,
658
679
  percentage: 5.0,
659
680
  type: 'direct',
@@ -661,11 +682,15 @@ const BUNDLE_PACKAGES_DATA = [
661
682
  color: '#F59E0B',
662
683
  description: 'HTTP client, request/response interceptors, and adapter pipelines.',
663
684
  logoUri: 'https://axios-http.com/assets/logo.svg',
685
+ lastActive: '4 days ago',
686
+ npmUrl: 'https://www.npmjs.com/package/axios',
687
+ isDeprecated: false,
664
688
  },
665
689
  {
666
690
  id: 'pkg-7',
667
691
  name: 'react-native-linear-gradient',
668
692
  version: '^2.8.3',
693
+ latestVersion: '2.8.3',
669
694
  sizeKb: 45,
670
695
  percentage: 2.5,
671
696
  type: 'direct',
@@ -673,11 +698,16 @@ const BUNDLE_PACKAGES_DATA = [
673
698
  color: '#FB7185',
674
699
  description: 'Hardware accelerated native gradient drawing shaders.',
675
700
  logoUri: 'https://upload.wikimedia.org/wikipedia/commons/thumb/a/a7/React-icon.svg/512px-React-icon.svg.png',
701
+ lastActive: '2 years ago',
702
+ npmUrl: 'https://www.npmjs.com/package/react-native-linear-gradient',
703
+ isDeprecated: true,
704
+ deprecationReason: 'Package maintenance is in transition. Consider expo-linear-gradient or @react-native-community/linear-gradient for Fabric support.',
676
705
  },
677
706
  {
678
707
  id: 'pkg-8',
679
708
  name: 'i18next & react-i18next',
680
709
  version: '^26.3.6',
710
+ latestVersion: '26.3.6',
681
711
  sizeKb: 62,
682
712
  percentage: 3.5,
683
713
  type: 'direct',
@@ -685,6 +715,9 @@ const BUNDLE_PACKAGES_DATA = [
685
715
  color: '#10B981',
686
716
  description: 'Internationalization framework, language interpolator, and locale switcher.',
687
717
  logoUri: 'https://raw.githubusercontent.com/i18next/i18next/master/assets/i18next-logo.png',
718
+ lastActive: '6 days ago',
719
+ npmUrl: 'https://www.npmjs.com/package/i18next',
720
+ isDeprecated: false,
688
721
  },
689
722
  ];
690
723
  const CATEGORY_TABS = [
@@ -1316,65 +1349,99 @@ const BundleTab = React.memo(() => {
1316
1349
  Showing {filteredPackages.length} dependencies
1317
1350
  </Text>
1318
1351
 
1319
- {filteredPackages.map((pkg, index) => (<View key={pkg.id} style={bundleStyles.fileCard}>
1320
- {/* Header Row: #s.no + Logo + Package Name + Version Pill + Size & Copy */}
1321
- <View style={bundleStyles.fileCardTop}>
1322
- <View style={bundleStyles.sNoBadge}>
1323
- <Text style={bundleStyles.sNoText}>#{index + 1}</Text>
1324
- </View>
1352
+ {filteredPackages.map((pkg, index) => {
1353
+ const cleanInstalledVersion = pkg.version.replace(/^\^/, '');
1354
+ const hasUpdate = pkg.latestVersion && pkg.latestVersion !== cleanInstalledVersion;
1355
+ return (<View key={pkg.id} style={[bundleStyles.fileCard, pkg.isDeprecated && { borderColor: '#FECDD3', backgroundColor: '#FFFDFD' }]}>
1356
+ {/* Header Row: #s.no + Logo + Package Name + Version Pill + Update/Deprecated Badges + Size & Copy */}
1357
+ <View style={bundleStyles.fileCardTop}>
1358
+ <View style={bundleStyles.sNoBadge}>
1359
+ <Text style={bundleStyles.sNoText}>#{index + 1}</Text>
1360
+ </View>
1325
1361
 
1326
- <PackageLogoRenderer name={pkg.name} color={pkg.color} size={28}/>
1362
+ <PackageLogoRenderer name={pkg.name} color={pkg.color} size={28}/>
1327
1363
 
1328
- <View style={{ flex: 1, paddingHorizontal: 4 }}>
1329
- <View style={{ flexDirection: 'row', alignItems: 'center', gap: 6, flexWrap: 'wrap' }}>
1330
- <HighlightText text={pkg.name} search={search} style={bundleStyles.fileName} highlightStyle={bundleStyles.searchHighlight}/>
1331
- <View style={bundleStyles.versionPill}>
1332
- <Text style={bundleStyles.versionPillText}>
1333
- v{pkg.version.replace(/^\^/, '')}
1334
- </Text>
1364
+ <View style={{ flex: 1, paddingHorizontal: 4 }}>
1365
+ <View style={{ flexDirection: 'row', alignItems: 'center', gap: 6, flexWrap: 'wrap' }}>
1366
+ <HighlightText text={pkg.name} search={search} style={bundleStyles.fileName} highlightStyle={bundleStyles.searchHighlight}/>
1367
+ <View style={bundleStyles.versionPill}>
1368
+ <Text style={bundleStyles.versionPillText}>
1369
+ v{cleanInstalledVersion}
1370
+ </Text>
1371
+ </View>
1372
+
1373
+ {pkg.isDeprecated ? (<View style={bundleStyles.deprecatedBadge}>
1374
+ <Text style={bundleStyles.deprecatedBadgeText}>⚠️ DEPRECATED</Text>
1375
+ </View>) : hasUpdate ? (<View style={bundleStyles.updateBadge}>
1376
+ <Text style={bundleStyles.updateBadgeText}>⚡ Update: v{pkg.latestVersion}</Text>
1377
+ </View>) : (<View style={[bundleStyles.updateBadge, { backgroundColor: '#F3F4F6', borderColor: '#E5E7EB' }]}>
1378
+ <Text style={[bundleStyles.updateBadgeText, { color: '#4B5563' }]}>✨ Up to date</Text>
1379
+ </View>)}
1335
1380
  </View>
1336
1381
  </View>
1337
- </View>
1338
1382
 
1339
- <View style={{ flexDirection: 'row', alignItems: 'center', gap: 6 }}>
1340
- <View style={bundleStyles.fileSizeBox}>
1341
- <Text style={bundleStyles.fileSizeKb}>{pkg.sizeKb} KB</Text>
1342
- <Text style={bundleStyles.filePercent}>{pkg.percentage}%</Text>
1383
+ <View style={{ flexDirection: 'row', alignItems: 'center', gap: 6 }}>
1384
+ <View style={bundleStyles.fileSizeBox}>
1385
+ <Text style={bundleStyles.fileSizeKb}>{pkg.sizeKb} KB</Text>
1386
+ <Text style={bundleStyles.filePercent}>{pkg.percentage}%</Text>
1387
+ </View>
1388
+ <CopyButton value={() => pkg} label="Package Details JSON"/>
1343
1389
  </View>
1344
- <CopyButton value={() => pkg} label="Package Details JSON"/>
1345
1390
  </View>
1346
- </View>
1347
1391
 
1348
- {/* Subtitle Row: Category Chip + Description */}
1349
- <View style={{ flexDirection: 'row', alignItems: 'center', gap: 6, marginTop: 4, marginBottom: 2 }}>
1350
- <View style={[bundleStyles.pkgBadge, { backgroundColor: `${pkg.color}1F`, borderColor: `${pkg.color}4D` }]}>
1351
- <Text style={[bundleStyles.pkgBadgeText, { color: pkg.color }]}>
1352
- {pkg.category.toUpperCase()}
1392
+ {/* Subtitle Row: Category Chip + Description */}
1393
+ <View style={{ flexDirection: 'row', alignItems: 'center', gap: 6, marginTop: 4, marginBottom: 2 }}>
1394
+ <View style={[bundleStyles.pkgBadge, { backgroundColor: `${pkg.color}1F`, borderColor: `${pkg.color}4D` }]}>
1395
+ <Text style={[bundleStyles.pkgBadgeText, { color: pkg.color }]}>
1396
+ {pkg.category.toUpperCase()}
1397
+ </Text>
1398
+ </View>
1399
+ <Text style={[bundleStyles.filePath, { flex: 1, marginTop: 0 }]} numberOfLines={1}>
1400
+ {pkg.description}
1353
1401
  </Text>
1354
1402
  </View>
1355
- <Text style={[bundleStyles.filePath, { flex: 1, marginTop: 0 }]} numberOfLines={1}>
1356
- {pkg.description}
1357
- </Text>
1358
- </View>
1359
1403
 
1360
- <View style={bundleStyles.fileProgressTrack}>
1361
- <View style={[
1362
- bundleStyles.fileProgressBar,
1363
- { width: `${pkg.percentage * 2}%`, backgroundColor: pkg.color },
1364
- ]}/>
1365
- </View>
1404
+ {/* Deprecation Warning Banner if deprecated */}
1405
+ {pkg.isDeprecated && pkg.deprecationReason && (<View style={bundleStyles.deprecationBox}>
1406
+ <Text style={bundleStyles.deprecationText}>
1407
+ ⚠️ {pkg.deprecationReason}
1408
+ </Text>
1409
+ </View>)}
1366
1410
 
1367
- <View style={{ flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', marginTop: 2 }}>
1368
- <View style={bundleStyles.typeTag}>
1369
- <Text style={bundleStyles.typeTagText}>
1370
- {pkg.type === 'direct' ? '📦 Direct Dependency' : '🔗 Transitive Peer'}
1371
- </Text>
1411
+ <View style={bundleStyles.fileProgressTrack}>
1412
+ <View style={[
1413
+ bundleStyles.fileProgressBar,
1414
+ { width: `${pkg.percentage * 2}%`, backgroundColor: pkg.isDeprecated ? '#EF4444' : pkg.color },
1415
+ ]}/>
1372
1416
  </View>
1373
- <Text style={bundleStyles.fileMetaText}>
1374
- ~{pkg.sizeKb} KB minified
1375
- </Text>
1376
- </View>
1377
- </View>))}
1417
+
1418
+ {/* Footer Row: Type Tag + Last Active + NPM Link Button */}
1419
+ <View style={{ flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', marginTop: 3 }}>
1420
+ <View style={{ flexDirection: 'row', alignItems: 'center', gap: 8 }}>
1421
+ <View style={bundleStyles.typeTag}>
1422
+ <Text style={bundleStyles.typeTagText}>
1423
+ {pkg.type === 'direct' ? '📦 Direct' : '🔗 Transitive'}
1424
+ </Text>
1425
+ </View>
1426
+ {pkg.lastActive && (<Text style={bundleStyles.lastActiveText}>
1427
+ 🕒 {pkg.lastActive}
1428
+ </Text>)}
1429
+ </View>
1430
+
1431
+ <View style={{ flexDirection: 'row', alignItems: 'center', gap: 8 }}>
1432
+ <Text style={bundleStyles.fileMetaText}>
1433
+ ~{pkg.sizeKb} KB minified
1434
+ </Text>
1435
+ <TouchableScale onPress={() => {
1436
+ const url = pkg.npmUrl || `https://www.npmjs.com/package/${pkg.name}`;
1437
+ Linking.openURL(url).catch(() => { });
1438
+ }} style={bundleStyles.npmLinkBtn}>
1439
+ <Text style={bundleStyles.npmLinkText}>npm ↗</Text>
1440
+ </TouchableScale>
1441
+ </View>
1442
+ </View>
1443
+ </View>);
1444
+ })}
1378
1445
  </ScrollView>
1379
1446
 
1380
1447
  {/* Sticky Total Package Size Footer */}
@@ -2100,6 +2167,69 @@ const bundleStyles = StyleSheet.create({
2100
2167
  fontSize: 9.5,
2101
2168
  color: AppColors.grayText,
2102
2169
  },
2170
+ npmLinkBtn: {
2171
+ flexDirection: 'row',
2172
+ alignItems: 'center',
2173
+ gap: 3,
2174
+ paddingHorizontal: 7,
2175
+ paddingVertical: 2,
2176
+ borderRadius: 5,
2177
+ backgroundColor: '#CB383714',
2178
+ borderWidth: 1,
2179
+ borderColor: '#CB383733',
2180
+ },
2181
+ npmLinkText: {
2182
+ fontFamily: AppFonts.interBold,
2183
+ fontSize: 9.5,
2184
+ color: '#CB3837',
2185
+ },
2186
+ deprecatedBadge: {
2187
+ paddingHorizontal: 6,
2188
+ paddingVertical: 1.5,
2189
+ borderRadius: 4,
2190
+ backgroundColor: '#FEE2E2',
2191
+ borderWidth: 1,
2192
+ borderColor: '#FECACA',
2193
+ },
2194
+ deprecatedBadgeText: {
2195
+ fontFamily: AppFonts.interBold,
2196
+ fontSize: 9,
2197
+ color: '#DC2626',
2198
+ letterSpacing: 0.3,
2199
+ },
2200
+ updateBadge: {
2201
+ paddingHorizontal: 6,
2202
+ paddingVertical: 1.5,
2203
+ borderRadius: 4,
2204
+ backgroundColor: '#DCFCE7',
2205
+ borderWidth: 1,
2206
+ borderColor: '#BBF7D0',
2207
+ },
2208
+ updateBadgeText: {
2209
+ fontFamily: AppFonts.interBold,
2210
+ fontSize: 9,
2211
+ color: '#047857',
2212
+ },
2213
+ lastActiveText: {
2214
+ fontFamily: AppFonts.interRegular,
2215
+ fontSize: 10,
2216
+ color: AppColors.grayTextWeak,
2217
+ },
2218
+ deprecationBox: {
2219
+ backgroundColor: '#FFF1F2',
2220
+ borderRadius: 6,
2221
+ paddingHorizontal: 8,
2222
+ paddingVertical: 5,
2223
+ borderWidth: 1,
2224
+ borderColor: '#FECDD3',
2225
+ marginTop: 3,
2226
+ },
2227
+ deprecationText: {
2228
+ fontFamily: AppFonts.interMedium,
2229
+ fontSize: 10.5,
2230
+ color: '#BE123C',
2231
+ lineHeight: 14,
2232
+ },
2103
2233
  unusedBadge: {
2104
2234
  paddingHorizontal: 6,
2105
2235
  paddingVertical: 1.5,
@@ -14,6 +14,7 @@ import AnalyticsDetail from '../AnalyticsDetail';
14
14
  import ReduxTab from './ReduxTab';
15
15
  import ReduxDetail from './ReduxDetail';
16
16
  import BundleTab from './BundleTab';
17
+ import PerformanceTab from './PerformanceTab';
17
18
  import SettingsPanel from './SettingsPanel';
18
19
  import styles from '../../styles';
19
20
  import { AppColors } from '../../styles/AppColors';
@@ -83,6 +84,12 @@ const MainScreen = () => {
83
84
  }}>
84
85
  {mountedTabs.bundle && <BundleTab />}
85
86
  </View>
87
+ <View style={{
88
+ flex: 1,
89
+ display: activeTab === 'performance' ? 'flex' : 'none',
90
+ }}>
91
+ {mountedTabs.performance && <PerformanceTab />}
92
+ </View>
86
93
  </>)) : (<View style={styles.empty}>
87
94
  <ActivityIndicator size="large" color={AppColors.purple}/>
88
95
  <Text style={[styles.emptySub, { marginTop: 12 }]}>
@@ -0,0 +1,22 @@
1
+ import React from 'react';
2
+ export interface PerformanceEvent {
3
+ id: string;
4
+ timestamp: number;
5
+ type: 'fps_drop' | 'slow_render' | 'transition' | 'memory' | 'network' | 'bridge' | 'touch';
6
+ category: 'render' | 'navigation' | 'memory' | 'io' | 'bridge';
7
+ fps: number;
8
+ durationMs: number;
9
+ label: string;
10
+ detail: string;
11
+ source?: string;
12
+ breakdown?: {
13
+ jsTimeMs: number;
14
+ uiTimeMs: number;
15
+ bridgeLatencyMs?: number;
16
+ };
17
+ heapDeltaKb?: number;
18
+ advice?: string;
19
+ severity: 'optimal' | 'warning' | 'critical';
20
+ }
21
+ declare const PerformanceTab: React.MemoExoticComponent<() => React.JSX.Element>;
22
+ export default PerformanceTab;