react-native-inapp-inspector 1.1.13 → 1.1.15

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.
Files changed (250) hide show
  1. package/README.md +9 -34
  2. package/dist/commonjs/assets/svgAssets.d.ts +3 -0
  3. package/dist/commonjs/assets/svgAssets.js +17 -0
  4. package/dist/commonjs/components/AnalyticsEventCard.d.ts +1 -14
  5. package/dist/commonjs/components/AnalyticsEventCard.js +120 -50
  6. package/dist/commonjs/components/AnalyticsGraph.d.ts +2 -6
  7. package/dist/commonjs/components/AnalyticsGraph.js +8 -8
  8. package/dist/commonjs/components/AnalyticsTabView.d.ts +15 -0
  9. package/dist/commonjs/components/AnalyticsTabView.js +157 -0
  10. package/dist/commonjs/components/AnimatedEntrance.d.ts +1 -1
  11. package/dist/commonjs/components/AnimatedEntrance.js +2 -2
  12. package/dist/commonjs/components/ApiDetailView.d.ts +22 -0
  13. package/dist/commonjs/components/ApiDetailView.js +304 -0
  14. package/dist/commonjs/components/ApisTabView.d.ts +33 -0
  15. package/dist/commonjs/components/ApisTabView.js +235 -0
  16. package/dist/commonjs/components/CodeSnippet.d.ts +1 -5
  17. package/dist/commonjs/components/CodeSnippet.js +34 -34
  18. package/dist/commonjs/components/ConsoleLogCard.d.ts +1 -8
  19. package/dist/commonjs/components/ConsoleLogCard.js +262 -442
  20. package/dist/commonjs/components/ConsoleLogDetailView.d.ts +9 -0
  21. package/dist/commonjs/components/ConsoleLogDetailView.js +278 -0
  22. package/dist/commonjs/components/ConsoleLogsTabView.d.ts +24 -0
  23. package/dist/commonjs/components/ConsoleLogsTabView.js +354 -0
  24. package/dist/commonjs/components/DiffViewer.js +4 -2
  25. package/dist/commonjs/components/DomainHeader.js +66 -41
  26. package/dist/commonjs/components/EmptyState.d.ts +2 -2
  27. package/dist/commonjs/components/EmptyState.js +2 -2
  28. package/dist/commonjs/components/EndOfListFooter.d.ts +8 -0
  29. package/dist/commonjs/components/EndOfListFooter.js +90 -0
  30. package/dist/commonjs/components/ErrorBoundary.d.ts +5 -14
  31. package/dist/commonjs/components/ErrorBoundary.js +28 -28
  32. package/dist/commonjs/components/FloatingBubble.d.ts +14 -0
  33. package/dist/commonjs/components/FloatingBubble.js +75 -0
  34. package/dist/commonjs/components/HeadersSection.js +5 -3
  35. package/dist/commonjs/components/HighlightText.d.ts +1 -1
  36. package/dist/commonjs/components/HighlightText.js +5 -7
  37. package/dist/commonjs/components/Inspector/AnalyticsTab.d.ts +3 -0
  38. package/dist/commonjs/components/Inspector/AnalyticsTab.js +232 -0
  39. package/dist/commonjs/components/Inspector/ConsoleTab.d.ts +3 -0
  40. package/dist/commonjs/components/Inspector/ConsoleTab.js +410 -0
  41. package/dist/commonjs/components/Inspector/FabLauncher.d.ts +3 -0
  42. package/dist/commonjs/components/Inspector/FabLauncher.js +54 -0
  43. package/dist/commonjs/components/Inspector/InsightsDashboard.d.ts +3 -0
  44. package/dist/commonjs/components/Inspector/InsightsDashboard.js +619 -0
  45. package/dist/commonjs/components/Inspector/InspectorContext.d.ts +5 -0
  46. package/dist/commonjs/components/Inspector/InspectorContext.js +18 -0
  47. package/dist/commonjs/components/Inspector/InspectorHeader.d.ts +3 -0
  48. package/dist/commonjs/components/Inspector/InspectorHeader.js +452 -0
  49. package/dist/commonjs/components/Inspector/LogDetail.d.ts +3 -0
  50. package/dist/commonjs/components/Inspector/LogDetail.js +963 -0
  51. package/dist/commonjs/components/Inspector/MainScreen.d.ts +3 -0
  52. package/dist/commonjs/components/Inspector/MainScreen.js +68 -0
  53. package/dist/commonjs/components/Inspector/NavigationTracker.d.ts +3 -0
  54. package/dist/commonjs/components/Inspector/NavigationTracker.js +12 -0
  55. package/dist/commonjs/components/Inspector/NetworkDetail.d.ts +3 -0
  56. package/dist/commonjs/components/Inspector/NetworkDetail.js +405 -0
  57. package/dist/commonjs/components/Inspector/NetworkTab.d.ts +3 -0
  58. package/dist/commonjs/components/Inspector/NetworkTab.js +281 -0
  59. package/dist/commonjs/components/Inspector/ReduxTab.d.ts +3 -0
  60. package/dist/commonjs/components/Inspector/ReduxTab.js +75 -0
  61. package/dist/commonjs/components/Inspector/SettingsPanel.d.ts +3 -0
  62. package/dist/commonjs/components/Inspector/SettingsPanel.js +1476 -0
  63. package/dist/commonjs/components/Inspector/TabBar.d.ts +3 -0
  64. package/dist/commonjs/components/Inspector/TabBar.js +95 -0
  65. package/dist/commonjs/components/Inspector/WebViewTab.d.ts +3 -0
  66. package/dist/commonjs/components/Inspector/WebViewTab.js +757 -0
  67. package/dist/commonjs/components/InspectorHeader.d.ts +19 -0
  68. package/dist/commonjs/components/InspectorHeader.js +329 -0
  69. package/dist/commonjs/components/InspectorTabBar.d.ts +16 -0
  70. package/dist/commonjs/components/InspectorTabBar.js +90 -0
  71. package/dist/commonjs/components/JsonViewer.d.ts +4 -1
  72. package/dist/commonjs/components/JsonViewer.js +110 -171
  73. package/dist/commonjs/components/LogCard.js +109 -86
  74. package/dist/commonjs/components/MetaAccordion.d.ts +1 -10
  75. package/dist/commonjs/components/MetaAccordion.js +23 -21
  76. package/dist/commonjs/components/NavigationTracker.d.ts +7 -0
  77. package/dist/commonjs/components/NavigationTracker.js +76 -0
  78. package/dist/commonjs/components/NetworkIcons.d.ts +6 -0
  79. package/dist/commonjs/components/NetworkIcons.js +54 -8
  80. package/dist/commonjs/components/ReduxTabView.d.ts +9 -0
  81. package/dist/commonjs/components/ReduxTabView.js +56 -0
  82. package/dist/commonjs/components/ReduxTreeView.js +241 -200
  83. package/dist/commonjs/components/SegmentedTabs.d.ts +15 -0
  84. package/dist/commonjs/components/SegmentedTabs.js +52 -0
  85. package/dist/commonjs/components/SettingsView.d.ts +13 -0
  86. package/dist/commonjs/components/SettingsView.js +328 -0
  87. package/dist/commonjs/components/TouchableScale.d.ts +2 -2
  88. package/dist/commonjs/components/TouchableScale.js +2 -2
  89. package/dist/commonjs/components/TreeNode.js +2 -2
  90. package/dist/commonjs/constants/index.js +1 -12
  91. package/dist/commonjs/constants/version.d.ts +1 -1
  92. package/dist/commonjs/constants/version.js +1 -1
  93. package/dist/commonjs/customHooks/analyticsLogger.d.ts +8 -0
  94. package/dist/commonjs/customHooks/analyticsLogger.js +42 -1
  95. package/dist/commonjs/customHooks/consoleLogger.js +137 -13
  96. package/dist/commonjs/customHooks/networkLogger.d.ts +0 -1
  97. package/dist/commonjs/customHooks/networkLogger.js +0 -1
  98. package/dist/commonjs/customHooks/reduxLogger.d.ts +2 -9
  99. package/dist/commonjs/enums/index.d.ts +39 -0
  100. package/dist/commonjs/enums/index.js +50 -0
  101. package/dist/commonjs/helpers/index.d.ts +27 -1
  102. package/dist/commonjs/helpers/index.js +187 -12
  103. package/dist/commonjs/helpers/settingsStore.d.ts +2 -24
  104. package/dist/commonjs/i18n/en.json +144 -0
  105. package/dist/commonjs/i18n/index.d.ts +2 -0
  106. package/dist/commonjs/i18n/index.js +27 -0
  107. package/dist/commonjs/i18n/locales/en.json +314 -0
  108. package/dist/commonjs/index.d.ts +2 -3
  109. package/dist/commonjs/index.js +207 -4927
  110. package/dist/commonjs/styles/AppColors.d.ts +148 -0
  111. package/dist/commonjs/styles/AppColors.js +176 -0
  112. package/dist/commonjs/styles/common.d.ts +3 -0
  113. package/dist/commonjs/styles/common.js +201 -0
  114. package/dist/commonjs/styles/index.d.ts +219 -435
  115. package/dist/commonjs/styles/index.js +312 -488
  116. package/dist/commonjs/types/enums.d.ts +9 -0
  117. package/dist/commonjs/types/enums.js +4 -0
  118. package/dist/commonjs/types/index.d.ts +4 -111
  119. package/dist/commonjs/types/index.js +16 -0
  120. package/dist/commonjs/types/interfaces.d.ts +337 -0
  121. package/dist/commonjs/types/interfaces.js +2 -0
  122. package/dist/esm/assets/svgAssets.d.ts +3 -0
  123. package/dist/esm/assets/svgAssets.js +14 -0
  124. package/dist/esm/components/AnalyticsEventCard.d.ts +1 -14
  125. package/dist/esm/components/AnalyticsEventCard.js +118 -48
  126. package/dist/esm/components/AnalyticsGraph.d.ts +2 -6
  127. package/dist/esm/components/AnalyticsGraph.js +8 -8
  128. package/dist/esm/components/AnalyticsTabView.d.ts +15 -0
  129. package/dist/esm/components/AnalyticsTabView.js +151 -0
  130. package/dist/esm/components/AnimatedEntrance.d.ts +1 -1
  131. package/dist/esm/components/AnimatedEntrance.js +2 -2
  132. package/dist/esm/components/ApiDetailView.d.ts +22 -0
  133. package/dist/esm/components/ApiDetailView.js +264 -0
  134. package/dist/esm/components/ApisTabView.d.ts +33 -0
  135. package/dist/esm/components/ApisTabView.js +196 -0
  136. package/dist/esm/components/CodeSnippet.d.ts +1 -5
  137. package/dist/esm/components/CodeSnippet.js +34 -34
  138. package/dist/esm/components/ConsoleLogCard.d.ts +1 -8
  139. package/dist/esm/components/ConsoleLogCard.js +262 -409
  140. package/dist/esm/components/ConsoleLogDetailView.d.ts +9 -0
  141. package/dist/esm/components/ConsoleLogDetailView.js +271 -0
  142. package/dist/esm/components/ConsoleLogsTabView.d.ts +24 -0
  143. package/dist/esm/components/ConsoleLogsTabView.js +348 -0
  144. package/dist/esm/components/DiffViewer.js +4 -2
  145. package/dist/esm/components/DomainHeader.js +66 -41
  146. package/dist/esm/components/EmptyState.d.ts +2 -2
  147. package/dist/esm/components/EmptyState.js +2 -2
  148. package/dist/esm/components/EndOfListFooter.d.ts +8 -0
  149. package/dist/esm/components/EndOfListFooter.js +83 -0
  150. package/dist/esm/components/ErrorBoundary.d.ts +5 -14
  151. package/dist/esm/components/ErrorBoundary.js +29 -29
  152. package/dist/esm/components/FloatingBubble.d.ts +14 -0
  153. package/dist/esm/components/FloatingBubble.js +68 -0
  154. package/dist/esm/components/HeadersSection.js +5 -3
  155. package/dist/esm/components/HighlightText.d.ts +1 -1
  156. package/dist/esm/components/HighlightText.js +5 -7
  157. package/dist/esm/components/Inspector/AnalyticsTab.d.ts +3 -0
  158. package/dist/esm/components/Inspector/AnalyticsTab.js +194 -0
  159. package/dist/esm/components/Inspector/ConsoleTab.d.ts +3 -0
  160. package/dist/esm/components/Inspector/ConsoleTab.js +372 -0
  161. package/dist/esm/components/Inspector/FabLauncher.d.ts +3 -0
  162. package/dist/esm/components/Inspector/FabLauncher.js +49 -0
  163. package/dist/esm/components/Inspector/InsightsDashboard.d.ts +3 -0
  164. package/dist/esm/components/Inspector/InsightsDashboard.js +614 -0
  165. package/dist/esm/components/Inspector/InspectorContext.d.ts +5 -0
  166. package/dist/esm/components/Inspector/InspectorContext.js +13 -0
  167. package/dist/esm/components/Inspector/InspectorHeader.d.ts +3 -0
  168. package/dist/esm/components/Inspector/InspectorHeader.js +447 -0
  169. package/dist/esm/components/Inspector/LogDetail.d.ts +3 -0
  170. package/dist/esm/components/Inspector/LogDetail.js +925 -0
  171. package/dist/esm/components/Inspector/MainScreen.d.ts +3 -0
  172. package/dist/esm/components/Inspector/MainScreen.js +63 -0
  173. package/dist/esm/components/Inspector/NavigationTracker.d.ts +3 -0
  174. package/dist/esm/components/Inspector/NavigationTracker.js +10 -0
  175. package/dist/esm/components/Inspector/NetworkDetail.d.ts +3 -0
  176. package/dist/esm/components/Inspector/NetworkDetail.js +367 -0
  177. package/dist/esm/components/Inspector/NetworkTab.d.ts +3 -0
  178. package/dist/esm/components/Inspector/NetworkTab.js +243 -0
  179. package/dist/esm/components/Inspector/ReduxTab.d.ts +3 -0
  180. package/dist/esm/components/Inspector/ReduxTab.js +70 -0
  181. package/dist/esm/components/Inspector/SettingsPanel.d.ts +3 -0
  182. package/dist/esm/components/Inspector/SettingsPanel.js +1438 -0
  183. package/dist/esm/components/Inspector/TabBar.d.ts +3 -0
  184. package/dist/esm/components/Inspector/TabBar.js +90 -0
  185. package/dist/esm/components/Inspector/WebViewTab.d.ts +3 -0
  186. package/dist/esm/components/Inspector/WebViewTab.js +752 -0
  187. package/dist/esm/components/InspectorHeader.d.ts +19 -0
  188. package/dist/esm/components/InspectorHeader.js +323 -0
  189. package/dist/esm/components/InspectorTabBar.d.ts +16 -0
  190. package/dist/esm/components/InspectorTabBar.js +84 -0
  191. package/dist/esm/components/JsonViewer.d.ts +4 -1
  192. package/dist/esm/components/JsonViewer.js +111 -172
  193. package/dist/esm/components/LogCard.js +111 -88
  194. package/dist/esm/components/MetaAccordion.d.ts +1 -10
  195. package/dist/esm/components/MetaAccordion.js +23 -21
  196. package/dist/esm/components/NavigationTracker.d.ts +7 -0
  197. package/dist/esm/components/NavigationTracker.js +39 -0
  198. package/dist/esm/components/NetworkIcons.d.ts +6 -0
  199. package/dist/esm/components/NetworkIcons.js +46 -6
  200. package/dist/esm/components/ReduxTabView.d.ts +9 -0
  201. package/dist/esm/components/ReduxTabView.js +50 -0
  202. package/dist/esm/components/ReduxTreeView.js +243 -202
  203. package/dist/esm/components/SegmentedTabs.d.ts +15 -0
  204. package/dist/esm/components/SegmentedTabs.js +47 -0
  205. package/dist/esm/components/SettingsView.d.ts +13 -0
  206. package/dist/esm/components/SettingsView.js +321 -0
  207. package/dist/esm/components/TouchableScale.d.ts +2 -2
  208. package/dist/esm/components/TouchableScale.js +2 -2
  209. package/dist/esm/components/TreeNode.js +2 -2
  210. package/dist/esm/constants/index.js +1 -12
  211. package/dist/esm/constants/version.d.ts +1 -1
  212. package/dist/esm/constants/version.js +1 -1
  213. package/dist/esm/customHooks/analyticsLogger.d.ts +8 -0
  214. package/dist/esm/customHooks/analyticsLogger.js +37 -0
  215. package/dist/esm/customHooks/consoleLogger.js +137 -13
  216. package/dist/esm/customHooks/networkLogger.d.ts +0 -1
  217. package/dist/esm/customHooks/networkLogger.js +0 -1
  218. package/dist/esm/customHooks/reduxLogger.d.ts +2 -9
  219. package/dist/esm/enums/index.d.ts +39 -0
  220. package/dist/esm/enums/index.js +47 -0
  221. package/dist/esm/helpers/index.d.ts +27 -1
  222. package/dist/esm/helpers/index.js +180 -11
  223. package/dist/esm/helpers/settingsStore.d.ts +2 -24
  224. package/dist/esm/i18n/en.json +144 -0
  225. package/dist/esm/i18n/index.d.ts +2 -0
  226. package/dist/esm/i18n/index.js +22 -0
  227. package/dist/esm/i18n/locales/en.json +314 -0
  228. package/dist/esm/index.d.ts +2 -3
  229. package/dist/esm/index.js +207 -4923
  230. package/dist/esm/styles/AppColors.d.ts +148 -0
  231. package/dist/esm/styles/AppColors.js +176 -0
  232. package/dist/esm/styles/common.d.ts +3 -0
  233. package/dist/esm/styles/common.js +197 -0
  234. package/dist/esm/styles/index.d.ts +219 -435
  235. package/dist/esm/styles/index.js +312 -488
  236. package/dist/esm/types/enums.d.ts +9 -0
  237. package/dist/esm/types/enums.js +3 -0
  238. package/dist/esm/types/index.d.ts +4 -111
  239. package/dist/esm/types/index.js +2 -1
  240. package/dist/esm/types/interfaces.d.ts +337 -0
  241. package/dist/esm/types/interfaces.js +1 -0
  242. package/example/App.tsx +88 -1
  243. package/example/android/app/build.gradle +29 -1
  244. package/example/android/app/src/main/java/com/example/MainApplication.kt +25 -0
  245. package/example/android/build.gradle +31 -4
  246. package/example/android/gradle/wrapper/gradle-wrapper.properties +1 -1
  247. package/example/android/gradle.properties +1 -0
  248. package/example/android/settings.gradle +20 -1
  249. package/example/package-lock.json +1 -1
  250. package/package.json +3 -1
@@ -0,0 +1,614 @@
1
+ import React from 'react';
2
+ import { ScrollView, Text, TouchableOpacity, View } from 'react-native';
3
+ import { animateNextLayout, useInspector } from './InspectorContext';
4
+ import TouchableScale from '../TouchableScale';
5
+ import styles from '../../styles';
6
+ import { AppColors } from '../../styles/AppColors';
7
+ import { AppFonts } from '../../styles/AppFonts';
8
+ import { getSize } from '../../helpers';
9
+ import { SignalIcon, TerminalIcon, AnalyticsIcon, GlobeIcon, } from '../NetworkIcons';
10
+ const InsightsDashboard = () => {
11
+ const { logs, visibleConsoleLogs, analyticsEvents, webViewNavHistory, tabVisibility, slowRequestThreshold, insightsActiveSubTab, setInsightsActiveSubTab, switchActiveTab, reduxState, } = useInspector();
12
+ const apiTotal = logs.length;
13
+ const apiErrors = logs.filter(l => (l.status != null && l.status >= 400) ||
14
+ l.status === 0 ||
15
+ l.status == null).length;
16
+ const apiSuccess = apiTotal - apiErrors;
17
+ const apiSuccessRate = apiTotal > 0 ? Math.round((apiSuccess / apiTotal) * 100) : 100;
18
+ const durations = logs
19
+ .filter(l => l.duration != null)
20
+ .map(l => l.duration);
21
+ const avgTime = durations.length > 0
22
+ ? Math.round(durations.reduce((a, b) => a + b, 0) / durations.length)
23
+ : null;
24
+ const logTotal = visibleConsoleLogs.length;
25
+ const logErrors = visibleConsoleLogs.filter(l => l.type === 'error').length;
26
+ const logWarns = visibleConsoleLogs.filter(l => l.type === 'warn').length;
27
+ const logInfos = visibleConsoleLogs.filter(l => l.type === 'info').length;
28
+ const analyticsTotal = analyticsEvents.length;
29
+ const uniqueEvents = new Set(analyticsEvents.map(e => e.name)).size;
30
+ const screenViews = analyticsEvents.filter(e => e.name === 'screen_view' ||
31
+ e.name === 'page_view' ||
32
+ e.name === 'firebase_screen_class').length;
33
+ const webviewTotal = webViewNavHistory.length;
34
+ // --- Richer insights metrics ---
35
+ const slowestTime = durations.length > 0 ? Math.max(...durations) : null;
36
+ const fastestTime = durations.length > 0 ? Math.min(...durations) : null;
37
+ const slowCount = durations.filter(d => d >= slowRequestThreshold).length;
38
+ const status2xx = logs.filter(l => l.status != null && l.status >= 200 && l.status < 300).length;
39
+ const status3xx = logs.filter(l => l.status != null && l.status >= 300 && l.status < 400).length;
40
+ const status4xx = logs.filter(l => l.status != null && l.status >= 400 && l.status < 500).length;
41
+ const status5xx = logs.filter(l => l.status != null && l.status >= 500).length;
42
+ const totalSignals = apiTotal + logTotal + analyticsTotal + webviewTotal;
43
+ const totalIssues = apiErrors + logErrors;
44
+ const activeModules = [
45
+ tabVisibility?.apis,
46
+ tabVisibility?.logs,
47
+ tabVisibility?.analytics,
48
+ tabVisibility?.webview,
49
+ tabVisibility?.redux,
50
+ ].filter(Boolean).length;
51
+ // Composite health score: success rate penalised by error volume and slow requests.
52
+ const healthScore = totalSignals === 0
53
+ ? 100
54
+ : Math.max(0, Math.min(100, Math.round(apiSuccessRate -
55
+ (logErrors > 0 ? Math.min(15, logErrors * 3) : 0) -
56
+ (slowCount > 0 ? Math.min(10, slowCount * 2) : 0))));
57
+ const healthColor = healthScore >= 90
58
+ ? AppColors.greenColor
59
+ : healthScore >= 70
60
+ ? AppColors.warningIconGold
61
+ : AppColors.errorColor;
62
+ const healthLabel = healthScore >= 90
63
+ ? 'Healthy'
64
+ : healthScore >= 70
65
+ ? 'Needs attention'
66
+ : 'Degraded';
67
+ return (<View style={styles.dashboardContainer}>
68
+ {/* Overview hero card */}
69
+ <View style={{
70
+ backgroundColor: AppColors.primaryLight,
71
+ borderRadius: 14,
72
+ borderWidth: 1,
73
+ borderColor: AppColors.grayBorderSecondary,
74
+ padding: 16,
75
+ marginBottom: 12,
76
+ }}>
77
+ <View style={{
78
+ flexDirection: 'row',
79
+ alignItems: 'center',
80
+ gap: 14,
81
+ }}>
82
+ {/* Health ring stand-in */}
83
+ <View style={{
84
+ width: 64,
85
+ height: 64,
86
+ borderRadius: 32,
87
+ borderWidth: 4,
88
+ borderColor: healthColor,
89
+ alignItems: 'center',
90
+ justifyContent: 'center',
91
+ backgroundColor: AppColors.purpleShade50,
92
+ }}>
93
+ <Text style={{
94
+ fontFamily: AppFonts.interBold,
95
+ fontSize: 18,
96
+ color: healthColor,
97
+ }}>
98
+ {healthScore}
99
+ </Text>
100
+ <Text style={{
101
+ fontFamily: AppFonts.interMedium,
102
+ fontSize: 7.5,
103
+ color: AppColors.grayTextWeak,
104
+ letterSpacing: 0.4,
105
+ }}>
106
+ HEALTH
107
+ </Text>
108
+ </View>
109
+ <View style={{ flex: 1 }}>
110
+ <Text style={{
111
+ fontFamily: AppFonts.interBold,
112
+ fontSize: 15,
113
+ color: AppColors.primaryBlack,
114
+ }}>
115
+ Session Overview
116
+ </Text>
117
+ <View style={{
118
+ flexDirection: 'row',
119
+ alignItems: 'center',
120
+ gap: 6,
121
+ marginTop: 3,
122
+ }}>
123
+ <View style={{
124
+ width: 7,
125
+ height: 7,
126
+ borderRadius: 3.5,
127
+ backgroundColor: healthColor,
128
+ }}/>
129
+ <Text style={{
130
+ fontFamily: AppFonts.interMedium,
131
+ fontSize: 11.5,
132
+ color: healthColor,
133
+ }}>
134
+ {healthLabel}
135
+ </Text>
136
+ <Text style={{
137
+ fontFamily: AppFonts.interRegular,
138
+ fontSize: 11.5,
139
+ color: AppColors.grayTextWeak,
140
+ }}>
141
+ • {activeModules} modules active
142
+ </Text>
143
+ </View>
144
+ </View>
145
+ </View>
146
+
147
+ {/* Quick totals strip */}
148
+ <View style={{
149
+ flexDirection: 'row',
150
+ marginTop: 14,
151
+ borderTopWidth: 1,
152
+ borderTopColor: AppColors.dividerColor,
153
+ paddingTop: 12,
154
+ }}>
155
+ <View style={{ flex: 1, alignItems: 'center' }}>
156
+ <Text style={{
157
+ fontFamily: AppFonts.interBold,
158
+ fontSize: 16,
159
+ color: AppColors.primaryBlack,
160
+ }}>
161
+ {totalSignals}
162
+ </Text>
163
+ <Text style={{
164
+ fontFamily: AppFonts.interRegular,
165
+ fontSize: 10,
166
+ color: AppColors.grayTextWeak,
167
+ marginTop: 1,
168
+ }}>
169
+ Signals
170
+ </Text>
171
+ </View>
172
+ <View style={{ width: 1, backgroundColor: AppColors.dividerColor }}/>
173
+ <View style={{ flex: 1, alignItems: 'center' }}>
174
+ <Text style={{
175
+ fontFamily: AppFonts.interBold,
176
+ fontSize: 16,
177
+ color: totalIssues > 0
178
+ ? AppColors.errorColor
179
+ : AppColors.primaryBlack,
180
+ }}>
181
+ {totalIssues}
182
+ </Text>
183
+ <Text style={{
184
+ fontFamily: AppFonts.interRegular,
185
+ fontSize: 10,
186
+ color: AppColors.grayTextWeak,
187
+ marginTop: 1,
188
+ }}>
189
+ Issues
190
+ </Text>
191
+ </View>
192
+ <View style={{ width: 1, backgroundColor: AppColors.dividerColor }}/>
193
+ <View style={{ flex: 1, alignItems: 'center' }}>
194
+ <Text style={{
195
+ fontFamily: AppFonts.interBold,
196
+ fontSize: 16,
197
+ color: slowCount > 0
198
+ ? AppColors.warningIconGold
199
+ : AppColors.primaryBlack,
200
+ }}>
201
+ {slowCount}
202
+ </Text>
203
+ <Text style={{
204
+ fontFamily: AppFonts.interRegular,
205
+ fontSize: 10,
206
+ color: AppColors.grayTextWeak,
207
+ marginTop: 1,
208
+ }}>
209
+ Slow ({slowRequestThreshold}ms+)
210
+ </Text>
211
+ </View>
212
+ </View>
213
+ </View>
214
+
215
+ {/* ── Insights Sub-Tab Selector ── */}
216
+ {(() => {
217
+ const insightTabs = [
218
+ {
219
+ key: 'apis',
220
+ label: 'APIs',
221
+ icon: (c, s) => <SignalIcon color={c} size={s}/>,
222
+ color: AppColors.purple,
223
+ count: apiTotal,
224
+ visible: !!tabVisibility?.apis,
225
+ },
226
+ {
227
+ key: 'logs',
228
+ label: 'Logs',
229
+ icon: (c, s) => <TerminalIcon color={c} size={s}/>,
230
+ color: '#0D9488',
231
+ count: logTotal,
232
+ visible: !!tabVisibility?.logs,
233
+ },
234
+ {
235
+ key: 'analytics',
236
+ label: 'Analytics',
237
+ icon: (c, s) => <AnalyticsIcon color={c} size={s}/>,
238
+ color: '#EA580C',
239
+ count: analyticsTotal,
240
+ visible: !!tabVisibility?.analytics,
241
+ },
242
+ {
243
+ key: 'webview',
244
+ label: 'WebView',
245
+ icon: (c, s) => <GlobeIcon color={c} size={s}/>,
246
+ color: '#2563EB',
247
+ count: webviewTotal,
248
+ visible: !!tabVisibility?.webview,
249
+ },
250
+ {
251
+ key: 'redux',
252
+ label: 'Redux',
253
+ icon: (c, s) => <TerminalIcon color={c} size={s}/>,
254
+ color: AppColors.purple,
255
+ count: reduxState ? Object.keys(reduxState).length : 0,
256
+ visible: !!tabVisibility?.redux,
257
+ },
258
+ ];
259
+ const visibleTabs = insightTabs.filter(t => t.visible);
260
+ if (visibleTabs.length === 0)
261
+ return null;
262
+ return (<>
263
+ <ScrollView horizontal showsHorizontalScrollIndicator={false} contentContainerStyle={{
264
+ paddingHorizontal: 2,
265
+ paddingVertical: 2,
266
+ gap: 8,
267
+ }} style={{
268
+ marginBottom: 12,
269
+ flexGrow: 0,
270
+ }}>
271
+ {visibleTabs.map(tab => {
272
+ const isActive = insightsActiveSubTab === tab.key;
273
+ return (<TouchableOpacity key={tab.key} onPress={() => {
274
+ animateNextLayout();
275
+ setInsightsActiveSubTab(tab.key);
276
+ }} activeOpacity={0.7} style={{
277
+ flexDirection: 'row',
278
+ alignItems: 'center',
279
+ gap: 6,
280
+ paddingHorizontal: 14,
281
+ paddingVertical: 8,
282
+ borderRadius: 20,
283
+ backgroundColor: isActive
284
+ ? tab.color
285
+ : AppColors.primaryLight,
286
+ borderWidth: 1,
287
+ borderColor: isActive
288
+ ? tab.color
289
+ : AppColors.grayBorderSecondary,
290
+ }}>
291
+ {tab.icon(isActive ? '#FFFFFF' : tab.color, 14)}
292
+ <Text style={{
293
+ fontFamily: AppFonts.interBold,
294
+ fontSize: 11.5,
295
+ color: isActive ? '#FFFFFF' : AppColors.grayTextStrong,
296
+ }}>
297
+ {tab.label}
298
+ </Text>
299
+ <View style={{
300
+ minWidth: 20,
301
+ height: 18,
302
+ borderRadius: 9,
303
+ paddingHorizontal: 5,
304
+ alignItems: 'center',
305
+ justifyContent: 'center',
306
+ backgroundColor: isActive
307
+ ? 'rgba(255,255,255,0.25)'
308
+ : AppColors.grayBackground,
309
+ }}>
310
+ <Text style={{
311
+ fontFamily: AppFonts.interBold,
312
+ fontSize: 9.5,
313
+ color: isActive ? '#FFFFFF' : AppColors.grayTextWeak,
314
+ }}>
315
+ {tab.count}
316
+ </Text>
317
+ </View>
318
+ </TouchableOpacity>);
319
+ })}
320
+ </ScrollView>
321
+
322
+ {/* ── Active Module Card ── */}
323
+ {insightsActiveSubTab === 'apis' && tabVisibility?.apis && (<TouchableScale style={styles.dashboardModuleCard} onPress={() => switchActiveTab('apis')}>
324
+ <View style={styles.dashboardModuleHeader}>
325
+ <View style={{ flexDirection: 'row', alignItems: 'center', gap: 8 }}>
326
+ <SignalIcon color={AppColors.purple} size={18}/>
327
+ <Text style={styles.dashboardModuleTitle}>APIs & Network</Text>
328
+ </View>
329
+ <Text style={styles.dashboardModuleGoText}>View Details →</Text>
330
+ </View>
331
+ <View style={styles.dashboardModuleGrid}>
332
+ <View style={styles.dashboardGridItem}>
333
+ <Text style={styles.dashboardGridVal}>{apiTotal}</Text>
334
+ <Text style={styles.dashboardGridLbl}>Requests</Text>
335
+ </View>
336
+ <View style={styles.dashboardGridItem}>
337
+ <Text style={[
338
+ styles.dashboardGridVal,
339
+ apiSuccessRate < 90 && { color: AppColors.warningIconGold },
340
+ ]}>
341
+ {apiSuccessRate}%
342
+ </Text>
343
+ <Text style={styles.dashboardGridLbl}>Success Rate</Text>
344
+ </View>
345
+ <View style={styles.dashboardGridItem}>
346
+ <Text style={[
347
+ styles.dashboardGridVal,
348
+ apiErrors > 0 && { color: AppColors.errorColor },
349
+ ]}>
350
+ {apiErrors}
351
+ </Text>
352
+ <Text style={styles.dashboardGridLbl}>Errors</Text>
353
+ </View>
354
+ <View style={styles.dashboardGridItem}>
355
+ <Text style={styles.dashboardGridVal}>
356
+ {avgTime != null ? `${avgTime}ms` : '—'}
357
+ </Text>
358
+ <Text style={styles.dashboardGridLbl}>Avg Latency</Text>
359
+ </View>
360
+ </View>
361
+
362
+ {/* Status-class breakdown + latency range */}
363
+ <View style={{
364
+ marginTop: 10,
365
+ paddingTop: 10,
366
+ borderTopWidth: 1,
367
+ borderTopColor: AppColors.dividerColor,
368
+ flexDirection: 'row',
369
+ alignItems: 'center',
370
+ flexWrap: 'wrap',
371
+ gap: 6,
372
+ }}>
373
+ {[
374
+ { label: '2xx', value: status2xx, color: AppColors.greenColor },
375
+ { label: '3xx', value: status3xx, color: AppColors.skyBlue },
376
+ {
377
+ label: '4xx',
378
+ value: status4xx,
379
+ color: AppColors.warningIconGold,
380
+ },
381
+ { label: '5xx', value: status5xx, color: AppColors.errorColor },
382
+ ].map(s => (<View key={s.label} style={{
383
+ flexDirection: 'row',
384
+ alignItems: 'center',
385
+ gap: 4,
386
+ backgroundColor: AppColors.grayBackground,
387
+ borderRadius: 6,
388
+ borderWidth: 1,
389
+ borderColor: AppColors.dividerColor,
390
+ paddingHorizontal: 7,
391
+ paddingVertical: 3,
392
+ }}>
393
+ <View style={{
394
+ width: 6,
395
+ height: 6,
396
+ borderRadius: 3,
397
+ backgroundColor: s.color,
398
+ }}/>
399
+ <Text style={{
400
+ fontFamily: AppFonts.interBold,
401
+ fontSize: 10,
402
+ color: AppColors.grayTextStrong,
403
+ }}>
404
+ {s.label} {s.value}
405
+ </Text>
406
+ </View>))}
407
+ {slowestTime != null && (<View style={{
408
+ marginLeft: 'auto',
409
+ flexDirection: 'row',
410
+ alignItems: 'center',
411
+ gap: 4,
412
+ }}>
413
+ <Text style={{
414
+ fontFamily: AppFonts.interRegular,
415
+ fontSize: 10,
416
+ color: AppColors.grayTextWeak,
417
+ }}>
418
+ Range
419
+ </Text>
420
+ <Text style={{
421
+ fontFamily: AppFonts.interBold,
422
+ fontSize: 10,
423
+ color: AppColors.grayTextStrong,
424
+ }}>
425
+ {fastestTime}–{slowestTime}ms
426
+ </Text>
427
+ </View>)}
428
+ </View>
429
+ </TouchableScale>)}
430
+
431
+ {insightsActiveSubTab === 'logs' && tabVisibility?.logs && (<TouchableScale style={styles.dashboardModuleCard} onPress={() => switchActiveTab('logs')}>
432
+ <View style={styles.dashboardModuleHeader}>
433
+ <View style={{ flexDirection: 'row', alignItems: 'center', gap: 8 }}>
434
+ <TerminalIcon color="#0D9488" size={18}/>
435
+ <Text style={styles.dashboardModuleTitle}>Console Logs</Text>
436
+ </View>
437
+ <Text style={styles.dashboardModuleGoText}>View Details →</Text>
438
+ </View>
439
+ <View style={styles.dashboardModuleGrid}>
440
+ <View style={styles.dashboardGridItem}>
441
+ <Text style={styles.dashboardGridVal}>{logTotal}</Text>
442
+ <Text style={styles.dashboardGridLbl}>Total Logs</Text>
443
+ </View>
444
+ <View style={styles.dashboardGridItem}>
445
+ <Text style={[styles.dashboardGridVal, { color: '#0D9488' }]}>
446
+ {logInfos}
447
+ </Text>
448
+ <Text style={styles.dashboardGridLbl}>Info</Text>
449
+ </View>
450
+ <View style={styles.dashboardGridItem}>
451
+ <Text style={[
452
+ styles.dashboardGridVal,
453
+ logWarns > 0 && { color: AppColors.warningIconGold },
454
+ ]}>
455
+ {logWarns}
456
+ </Text>
457
+ <Text style={styles.dashboardGridLbl}>Warnings</Text>
458
+ </View>
459
+ <View style={styles.dashboardGridItem}>
460
+ <Text style={[
461
+ styles.dashboardGridVal,
462
+ logErrors > 0 && { color: AppColors.errorColor },
463
+ ]}>
464
+ {logErrors}
465
+ </Text>
466
+ <Text style={styles.dashboardGridLbl}>Errors</Text>
467
+ </View>
468
+ </View>
469
+ </TouchableScale>)}
470
+
471
+ {insightsActiveSubTab === 'analytics' && tabVisibility?.analytics && (<TouchableScale style={styles.dashboardModuleCard} onPress={() => switchActiveTab('analytics')}>
472
+ <View style={styles.dashboardModuleHeader}>
473
+ <View style={{ flexDirection: 'row', alignItems: 'center', gap: 8 }}>
474
+ <AnalyticsIcon color="#EA580C" size={18}/>
475
+ <Text style={styles.dashboardModuleTitle}>
476
+ Analytics Events
477
+ </Text>
478
+ </View>
479
+ <Text style={styles.dashboardModuleGoText}>View Details →</Text>
480
+ </View>
481
+ <View style={styles.dashboardModuleGrid}>
482
+ <View style={styles.dashboardGridItem}>
483
+ <Text style={styles.dashboardGridVal}>{analyticsTotal}</Text>
484
+ <Text style={styles.dashboardGridLbl}>Total Events</Text>
485
+ </View>
486
+ <View style={styles.dashboardGridItem}>
487
+ <Text style={[styles.dashboardGridVal, { color: '#EA580C' }]}>
488
+ {uniqueEvents}
489
+ </Text>
490
+ <Text style={styles.dashboardGridLbl}>Unique Names</Text>
491
+ </View>
492
+ <View style={styles.dashboardGridItem}>
493
+ <Text style={styles.dashboardGridVal}>{screenViews}</Text>
494
+ <Text style={styles.dashboardGridLbl}>Screen Views</Text>
495
+ </View>
496
+ <View style={styles.dashboardGridItem}>
497
+ <Text style={styles.dashboardGridVal}>
498
+ {analyticsTotal > 0
499
+ ? Math.round(analyticsTotal / Math.max(1, logs.length / 5))
500
+ : 0}
501
+ </Text>
502
+ <Text style={styles.dashboardGridLbl}>Events Ratio</Text>
503
+ </View>
504
+ </View>
505
+ </TouchableScale>)}
506
+
507
+ {insightsActiveSubTab === 'webview' && tabVisibility?.webview && (<TouchableScale style={styles.dashboardModuleCard} onPress={() => switchActiveTab('webview')}>
508
+ <View style={styles.dashboardModuleHeader}>
509
+ <View style={{ flexDirection: 'row', alignItems: 'center', gap: 8 }}>
510
+ <GlobeIcon color="#2563EB" size={18}/>
511
+ <Text style={styles.dashboardModuleTitle}>
512
+ WebView Captures
513
+ </Text>
514
+ </View>
515
+ <Text style={styles.dashboardModuleGoText}>View Details →</Text>
516
+ </View>
517
+ <View style={styles.dashboardModuleGrid}>
518
+ <View style={styles.dashboardGridItem}>
519
+ <Text style={styles.dashboardGridVal}>{webviewTotal}</Text>
520
+ <Text style={styles.dashboardGridLbl}>History Size</Text>
521
+ </View>
522
+ <View style={styles.dashboardGridItem}>
523
+ <Text style={[styles.dashboardGridVal, { color: '#16A34A' }]}>
524
+ Active
525
+ </Text>
526
+ <Text style={styles.dashboardGridLbl}>Status</Text>
527
+ </View>
528
+ <View style={styles.dashboardGridItem}>
529
+ <Text numberOfLines={1} style={styles.dashboardGridVal}>
530
+ {webviewTotal > 0
531
+ ? `${webViewNavHistory[0]?.title?.substring(0, 10) ?? ''}...`
532
+ : '—'}
533
+ </Text>
534
+ <Text style={styles.dashboardGridLbl}>Last URL</Text>
535
+ </View>
536
+ </View>
537
+ </TouchableScale>)}
538
+
539
+ {insightsActiveSubTab === 'redux' && tabVisibility?.redux && (<TouchableScale style={styles.dashboardModuleCard} onPress={() => switchActiveTab('redux')}>
540
+ <View style={styles.dashboardModuleHeader}>
541
+ <View style={{ flexDirection: 'row', alignItems: 'center', gap: 8 }}>
542
+ <TerminalIcon color={AppColors.purple} size={18}/>
543
+ <Text style={styles.dashboardModuleTitle}>
544
+ Redux Store State
545
+ </Text>
546
+ </View>
547
+ <Text style={styles.dashboardModuleGoText}>View Details →</Text>
548
+ </View>
549
+ {reduxState ? (<View style={{ paddingHorizontal: 12, paddingBottom: 12, gap: 6 }}>
550
+ <View style={{
551
+ flexDirection: 'row',
552
+ justifyContent: 'space-between',
553
+ marginBottom: 4,
554
+ }}>
555
+ <Text style={{
556
+ fontFamily: AppFonts.interBold,
557
+ fontSize: 10,
558
+ color: AppColors.grayTextWeak,
559
+ letterSpacing: 0.5,
560
+ }}>
561
+ REDUCER NAME
562
+ </Text>
563
+ <Text style={{
564
+ fontFamily: AppFonts.interBold,
565
+ fontSize: 10,
566
+ color: AppColors.grayTextWeak,
567
+ letterSpacing: 0.5,
568
+ }}>
569
+ SIZE / FIELDS
570
+ </Text>
571
+ </View>
572
+ {Object.keys(reduxState).map(key => {
573
+ const val = reduxState[key];
574
+ const fieldsCount = typeof val === 'object' && val !== null
575
+ ? Object.keys(val).length
576
+ : 0;
577
+ const sizeStr = getSize(val);
578
+ return (<View key={key} style={{
579
+ flexDirection: 'row',
580
+ justifyContent: 'space-between',
581
+ alignItems: 'center',
582
+ paddingVertical: 2,
583
+ }}>
584
+ <Text style={{
585
+ fontFamily: AppFonts.interMedium,
586
+ fontSize: 12,
587
+ color: AppColors.grayTextStrong,
588
+ }}>
589
+ {key}
590
+ </Text>
591
+ <Text style={{
592
+ fontFamily: AppFonts.interRegular,
593
+ fontSize: 11,
594
+ color: AppColors.grayTextWeak,
595
+ }}>
596
+ {sizeStr} ({fieldsCount} fields)
597
+ </Text>
598
+ </View>);
599
+ })}
600
+ </View>) : (<View style={{ padding: 12, alignItems: 'center' }}>
601
+ <Text style={{
602
+ fontFamily: AppFonts.interRegular,
603
+ fontSize: 12,
604
+ color: AppColors.grayTextWeak,
605
+ }}>
606
+ No connected Redux store.
607
+ </Text>
608
+ </View>)}
609
+ </TouchableScale>)}
610
+ </>);
611
+ })()}
612
+ </View>);
613
+ };
614
+ export default InsightsDashboard;
@@ -0,0 +1,5 @@
1
+ import { InspectorContextValue } from '../../types';
2
+ export { InspectorContextValue, InspectorStorage, ModalAnimationType, SettingsPage, SettingsSubTab, LogFilter, } from '../../types';
3
+ export declare const InspectorContext: import("react").Context<InspectorContextValue>;
4
+ export declare const useInspector: () => InspectorContextValue;
5
+ export declare const animateNextLayout: () => void;
@@ -0,0 +1,13 @@
1
+ import { createContext, useContext } from 'react';
2
+ export const InspectorContext = createContext(null);
3
+ export const useInspector = () => {
4
+ const ctx = useContext(InspectorContext);
5
+ if (!ctx) {
6
+ throw new Error('useInspector must be used within <InspectorContext.Provider>');
7
+ }
8
+ return ctx;
9
+ };
10
+ export const animateNextLayout = () => {
11
+ // Disabled LayoutAnimation to prevent iOS NSRangeException crashes under Fabric
12
+ // and Android rendering performance freezes.
13
+ };
@@ -0,0 +1,3 @@
1
+ import React from 'react';
2
+ declare const InspectorHeader: () => React.JSX.Element;
3
+ export default InspectorHeader;