react-native-inapp-inspector 2.2.2 → 2.2.3

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 (97) hide show
  1. package/dist/commonjs/constants/version.d.ts +1 -1
  2. package/dist/commonjs/constants/version.js +1 -1
  3. package/dist/esm/constants/version.d.ts +1 -1
  4. package/dist/esm/constants/version.js +1 -1
  5. package/package.json +2 -1
  6. package/src/analytics.ts +35 -0
  7. package/src/bundle.ts +25 -0
  8. package/src/components/AnalyticsDetail.tsx +865 -0
  9. package/src/components/AnalyticsEventCard.tsx +441 -0
  10. package/src/components/AnalyticsGraph.tsx +583 -0
  11. package/src/components/AnimatedEntrance.tsx +64 -0
  12. package/src/components/AppHeaderLogo.tsx +109 -0
  13. package/src/components/BrandCircleIcon.tsx +144 -0
  14. package/src/components/BrandSquareIcon.tsx +144 -0
  15. package/src/components/CodeSnippet.tsx +725 -0
  16. package/src/components/ConsoleLogCard.tsx +628 -0
  17. package/src/components/CopyButton.tsx +87 -0
  18. package/src/components/DiffViewer.tsx +82 -0
  19. package/src/components/DomainHeader.tsx +237 -0
  20. package/src/components/EmptyState.tsx +73 -0
  21. package/src/components/EndOfListFooter.tsx +100 -0
  22. package/src/components/ErrorBoundary.tsx +688 -0
  23. package/src/components/HeadersSection.tsx +192 -0
  24. package/src/components/HighlightText.tsx +100 -0
  25. package/src/components/Inspector/AnalyticsFilterModal.tsx +1250 -0
  26. package/src/components/Inspector/AnalyticsTab.tsx +1336 -0
  27. package/src/components/Inspector/BundleTab.tsx +4731 -0
  28. package/src/components/Inspector/ConsoleTab.tsx +702 -0
  29. package/src/components/Inspector/CrashDetail.tsx +941 -0
  30. package/src/components/Inspector/CrashFilterModal.tsx +721 -0
  31. package/src/components/Inspector/CrashTab.tsx +871 -0
  32. package/src/components/Inspector/FabLauncher.tsx +80 -0
  33. package/src/components/Inspector/InspectorContext.tsx +28 -0
  34. package/src/components/Inspector/InspectorHeader.tsx +973 -0
  35. package/src/components/Inspector/LogDetail.tsx +1427 -0
  36. package/src/components/Inspector/MainScreen.tsx +258 -0
  37. package/src/components/Inspector/NavigationTracker.tsx +13 -0
  38. package/src/components/Inspector/NetworkDetail.tsx +794 -0
  39. package/src/components/Inspector/NetworkTab.tsx +1095 -0
  40. package/src/components/Inspector/NpmUpdateToast.tsx +392 -0
  41. package/src/components/Inspector/PerformanceTab.tsx +1894 -0
  42. package/src/components/Inspector/ReduxDetail.tsx +1651 -0
  43. package/src/components/Inspector/ReduxTab.tsx +954 -0
  44. package/src/components/Inspector/SettingsPanel.tsx +3181 -0
  45. package/src/components/Inspector/TabBar.tsx +187 -0
  46. package/src/components/Inspector/TelemetryConsentModal.tsx +392 -0
  47. package/src/components/Inspector/UpdateAvailableModal.tsx +545 -0
  48. package/src/components/JsonViewer.tsx +486 -0
  49. package/src/components/LogCard.tsx +491 -0
  50. package/src/components/LogSyntaxHighlighter.tsx +178 -0
  51. package/src/components/MetaAccordion.tsx +340 -0
  52. package/src/components/MiniBarChart.tsx +42 -0
  53. package/src/components/MiniLineChart.tsx +33 -0
  54. package/src/components/NetworkIcons.tsx +2118 -0
  55. package/src/components/SectionHeader.tsx +113 -0
  56. package/src/components/SegmentedTabs.tsx +83 -0
  57. package/src/components/Slider.tsx +300 -0
  58. package/src/components/SourcePageCard.tsx +148 -0
  59. package/src/components/Toast.tsx +131 -0
  60. package/src/components/TouchableScale.tsx +91 -0
  61. package/src/components/TreeNode.tsx +186 -0
  62. package/src/console.ts +24 -0
  63. package/src/constants/index.ts +38 -0
  64. package/src/constants/version.ts +3 -0
  65. package/src/crash.ts +32 -0
  66. package/src/customHooks/analyticsLogger.ts +336 -0
  67. package/src/customHooks/bundleAnalyzer.ts +1231 -0
  68. package/src/customHooks/consoleLogger.ts +497 -0
  69. package/src/customHooks/crashHandler.ts +944 -0
  70. package/src/customHooks/logFilters.ts +32 -0
  71. package/src/customHooks/networkLogger.ts +419 -0
  72. package/src/customHooks/performanceTracker.ts +1014 -0
  73. package/src/customHooks/reduxLogger.ts +406 -0
  74. package/src/customHooks/useAccordion.tsx +60 -0
  75. package/src/decorators/index.ts +184 -0
  76. package/src/helpers/gaAnalyticsRegistry.ts +204 -0
  77. package/src/helpers/index.ts +860 -0
  78. package/src/helpers/memoryManager.ts +138 -0
  79. package/src/helpers/searchQueryParser.ts +283 -0
  80. package/src/helpers/settingsStore.ts +171 -0
  81. package/src/helpers/telemetry.ts +505 -0
  82. package/src/helpers/toast.ts +17 -0
  83. package/src/i18n/index.ts +69 -0
  84. package/src/i18n/locales/en.json +1052 -0
  85. package/src/index.tsx +2336 -0
  86. package/src/native/NativeInspector.ts +397 -0
  87. package/src/native/NativeNetworkInspector.ts +24 -0
  88. package/src/network.ts +22 -0
  89. package/src/performance.ts +38 -0
  90. package/src/redux.ts +23 -0
  91. package/src/styles/AppColors.ts +408 -0
  92. package/src/styles/AppFonts.ts +8 -0
  93. package/src/styles/common.ts +209 -0
  94. package/src/styles/index.ts +1570 -0
  95. package/src/types/enums.ts +194 -0
  96. package/src/types/index.ts +34 -0
  97. package/src/types/interfaces.ts +515 -0
@@ -0,0 +1,82 @@
1
+ import {useTranslation} from '../i18n';
2
+ import React, {useMemo} from 'react';
3
+ import {View, Text, ScrollView} from 'react-native';
4
+
5
+ // Helpers
6
+ import {getDiff} from '../helpers';
7
+
8
+ // Stylesheet
9
+ import {AppColors} from '../styles/AppColors';
10
+ import styles from '../styles';
11
+
12
+ const DiffViewer = React.memo(
13
+ ({
14
+ oldData,
15
+ newData,
16
+ forceOpen,
17
+ }: {
18
+ oldData: any;
19
+ newData: any;
20
+ forceOpen?: boolean;
21
+ }) => {
22
+ const {t} = useTranslation();
23
+ const diffs = useMemo(() => getDiff(oldData, newData), [oldData, newData]);
24
+
25
+ if (forceOpen === false) {
26
+ return (
27
+ <View style={styles.codeBlock}>
28
+ <Text style={[styles.codeText, {color: AppColors.grayTextWeak}]}>
29
+ {t('network.diffHidden')}
30
+ </Text>
31
+ </View>
32
+ );
33
+ }
34
+
35
+ if (diffs.length === 0) {
36
+ return (
37
+ <View style={styles.codeBlock}>
38
+ <Text style={styles.codeText}>{t('network.noDiff')}</Text>
39
+ </View>
40
+ );
41
+ }
42
+
43
+ return (
44
+ <ScrollView
45
+ horizontal
46
+ showsHorizontalScrollIndicator={true}
47
+ style={styles.codeBlockScroll}>
48
+ <View style={styles.diffBlock}>
49
+ {diffs.map((d, i) => {
50
+ const key = d.path === 'root' ? '' : `"${d.path}": `;
51
+ if (d.type === 'added') {
52
+ return (
53
+ <Text key={i} selectable={true} style={styles.diffAdded}>
54
+ + <Text style={styles.codeKey}>{key}</Text>
55
+ {JSON.stringify(d.newVal)}
56
+ </Text>
57
+ );
58
+ }
59
+ if (d.type === 'removed') {
60
+ return (
61
+ <Text key={i} selectable={true} style={styles.diffRemoved}>
62
+ - <Text style={styles.codeKey}>{key}</Text>
63
+ {JSON.stringify(d.oldVal)}
64
+ </Text>
65
+ );
66
+ }
67
+ return (
68
+ <Text key={i} selectable={true} style={styles.diffChanged}>
69
+ ~ <Text style={styles.codeKey}>{key}</Text>
70
+ {JSON.stringify(d.oldVal)}{' '}
71
+ <Text style={{color: AppColors.grayTextWeak}}>➔</Text>{' '}
72
+ {JSON.stringify(d.newVal)}
73
+ </Text>
74
+ );
75
+ })}
76
+ </View>
77
+ </ScrollView>
78
+ );
79
+ },
80
+ );
81
+
82
+ export default DiffViewer;
@@ -0,0 +1,237 @@
1
+ import React, {useEffect, useRef} from 'react';
2
+ import {Animated, Pressable, View, Text} from 'react-native';
3
+
4
+ // Stylesheet
5
+ import {AppColors} from '../styles/AppColors';
6
+ import {AppFonts} from '../styles/AppFonts';
7
+
8
+ // Helpers
9
+ import {formatDateTime} from '../helpers';
10
+
11
+ // Assets
12
+ import {
13
+ ChevronIcon,
14
+ ScreenIcon,
15
+ CheckIcon,
16
+ FailIcon,
17
+ ClockIcon,
18
+ } from './NetworkIcons';
19
+
20
+ // Stylesheet
21
+ import styles from '../styles';
22
+
23
+ // Type Definition
24
+ import {LocalFilter} from '../types';
25
+
26
+ const DomainHeader = ({
27
+ pageName,
28
+ color,
29
+ stats,
30
+ activeFilters,
31
+ onToggleFilter,
32
+ isCollapsed,
33
+ onToggleCollapse,
34
+ isFirst,
35
+ timestamp,
36
+ }: {
37
+ pageName: string;
38
+ color: string;
39
+ stats: {success: number; failed: number; loading: number};
40
+ activeFilters: Set<LocalFilter>;
41
+ onToggleFilter: (pageName: string, filter: LocalFilter) => void;
42
+ isCollapsed: boolean;
43
+ onToggleCollapse: (pageName: string) => void;
44
+ isFirst: boolean;
45
+ timestamp: number;
46
+ }) => {
47
+ const chevronAnim = useRef(new Animated.Value(isCollapsed ? 0 : 1)).current;
48
+ useEffect(() => {
49
+ Animated.timing(chevronAnim, {
50
+ toValue: isCollapsed ? 0 : 1,
51
+ duration: 220,
52
+ useNativeDriver: true,
53
+ }).start();
54
+ }, [isCollapsed]);
55
+
56
+ const chevronRotate = chevronAnim.interpolate({
57
+ inputRange: [0, 1],
58
+ outputRange: ['-90deg', '0deg'],
59
+ });
60
+
61
+ const visibleStats = ['success', 'failed', 'loading'];
62
+
63
+ const total = stats.success + stats.failed + stats.loading;
64
+ const pctSuccess =
65
+ total > 0 ? Math.round((stats.success / total) * 100) : 0;
66
+ const pctFailed =
67
+ total > 0 ? Math.round((stats.failed / total) * 100) : 0;
68
+ const pctLoading =
69
+ total > 0 ? Math.round((stats.loading / total) * 100) : 0;
70
+
71
+ return (
72
+ <Pressable
73
+ style={[
74
+ styles.domainHeaderCard,
75
+ !isCollapsed && styles.domainHeaderCardExpanded,
76
+ ]}
77
+ onPress={() => onToggleCollapse(pageName)}>
78
+ <View style={styles.domainHeaderTopRow}>
79
+ <View style={styles.domainHeaderLeft}>
80
+ <Animated.View style={{transform: [{rotate: chevronRotate}], flexShrink: 0}}>
81
+ <ChevronIcon color={AppColors.grayTextWeak} size={13} />
82
+ </Animated.View>
83
+ <View style={[styles.domainIconWrap, {backgroundColor: `${color}18`, flexShrink: 0}]}>
84
+ <ScreenIcon color={color} size={14} />
85
+ </View>
86
+ <View style={{flex: 1, justifyContent: 'center', minWidth: 0}}>
87
+ <View style={{flexDirection: 'row', alignItems: 'center', gap: 6, minWidth: 0}}>
88
+ <Text
89
+ style={[styles.domainTitleText, {flexShrink: 1}]}
90
+ numberOfLines={1}
91
+ ellipsizeMode="tail">
92
+ {pageName}
93
+ </Text>
94
+ {total > 0 && (
95
+ <View
96
+ style={{
97
+ flexDirection: 'row',
98
+ alignItems: 'center',
99
+ gap: 4,
100
+ backgroundColor:
101
+ stats.failed > 0
102
+ ? AppColors.red100
103
+ : stats.loading > 0
104
+ ? AppColors.amber100
105
+ : AppColors.emerald100,
106
+ paddingHorizontal: 5,
107
+ paddingVertical: 1.5,
108
+ borderRadius: 4,
109
+ flexShrink: 0,
110
+ }}>
111
+ <View
112
+ style={{
113
+ width: 22,
114
+ height: 3.5,
115
+ borderRadius: 2,
116
+ backgroundColor: AppColors.gray200,
117
+ flexDirection: 'row',
118
+ overflow: 'hidden',
119
+ }}>
120
+ {pctSuccess > 0 && (
121
+ <View
122
+ style={{
123
+ width: `${pctSuccess}%`,
124
+ height: '100%',
125
+ backgroundColor: AppColors.emerald500,
126
+ }}
127
+ />
128
+ )}
129
+ {pctFailed > 0 && (
130
+ <View
131
+ style={{
132
+ width: `${pctFailed}%`,
133
+ height: '100%',
134
+ backgroundColor: AppColors.red500,
135
+ }}
136
+ />
137
+ )}
138
+ {pctLoading > 0 && (
139
+ <View
140
+ style={{
141
+ width: `${pctLoading}%`,
142
+ height: '100%',
143
+ backgroundColor: AppColors.amber500,
144
+ }}
145
+ />
146
+ )}
147
+ </View>
148
+ <Text
149
+ style={{
150
+ fontFamily: AppFonts.interBold,
151
+ fontSize: 8.5,
152
+ color:
153
+ stats.failed > 0
154
+ ? AppColors.redErrorText
155
+ : stats.loading > 0
156
+ ? AppColors.amber800Warm
157
+ : AppColors.emerald700,
158
+ }}>
159
+ {pctSuccess}%
160
+ </Text>
161
+ </View>
162
+ )}
163
+ </View>
164
+ <Text style={styles.domainSummaryText} numberOfLines={1} ellipsizeMode="tail">
165
+ {formatDateTime(timestamp)}
166
+ </Text>
167
+ </View>
168
+ </View>
169
+
170
+ <View style={styles.domainStatsGroup}>
171
+ {visibleStats.map(type => {
172
+ const isActive = activeFilters.has(type as LocalFilter);
173
+
174
+ let IconComponent;
175
+ let activeColor = '';
176
+ let count = 0;
177
+
178
+ if (type === 'success') {
179
+ IconComponent = CheckIcon;
180
+ activeColor = AppColors.greenColor;
181
+ count = stats.success;
182
+ } else if (type === 'failed') {
183
+ IconComponent = FailIcon;
184
+ activeColor = AppColors.errorColor;
185
+ count = stats.failed;
186
+ } else {
187
+ IconComponent = ClockIcon;
188
+ activeColor = AppColors.darkOrange;
189
+ count = stats.loading;
190
+ }
191
+
192
+ return (
193
+ <Pressable
194
+ key={type}
195
+ onPress={() => onToggleFilter(pageName, type as LocalFilter)}
196
+ hitSlop={6}
197
+ style={[
198
+ styles.domainStatPill,
199
+ isActive && {
200
+ borderColor: `${activeColor}40`,
201
+ backgroundColor: `${activeColor}12`,
202
+ },
203
+ ]}>
204
+ <View
205
+ style={[
206
+ styles.filterCheckbox,
207
+ {marginRight: 0, width: 11, height: 11, borderRadius: 2.5},
208
+ isActive && [
209
+ styles.filterCheckboxActive,
210
+ {backgroundColor: activeColor},
211
+ ],
212
+ ]}>
213
+ {isActive && (
214
+ <CheckIcon color={AppColors.white} size={7} />
215
+ )}
216
+ </View>
217
+ <IconComponent
218
+ color={isActive ? activeColor : AppColors.grayTextWeak}
219
+ size={type === 'failed' ? 8 : 10}
220
+ />
221
+ <Text
222
+ style={[
223
+ styles.domainStatText,
224
+ {color: isActive ? activeColor : AppColors.grayTextWeak},
225
+ ]}>
226
+ {count}
227
+ </Text>
228
+ </Pressable>
229
+ );
230
+ })}
231
+ </View>
232
+ </View>
233
+ </Pressable>
234
+ );
235
+ };
236
+
237
+ export default DomainHeader;
@@ -0,0 +1,73 @@
1
+ import React, {useEffect, useRef} from 'react';
2
+ import {Animated, DevSettings, Alert, View, Text} from 'react-native';
3
+
4
+ // Components
5
+ import TouchableScale from './TouchableScale';
6
+ import AnimatedEntrance from './AnimatedEntrance';
7
+
8
+ // Assets
9
+ import {EmptyRadarIcon} from './NetworkIcons';
10
+
11
+ // Stylesheet
12
+ import {AppColors} from '../styles/AppColors';
13
+ import styles from '../styles';
14
+
15
+ const EmptyState = React.memo(function EmptyState({isSearch}: {isSearch?: boolean}) {
16
+ const iconPulse = useRef(new Animated.Value(1)).current;
17
+
18
+ useEffect(() => {
19
+ const loop = Animated.loop(
20
+ Animated.sequence([
21
+ Animated.timing(iconPulse, {
22
+ toValue: 1.06,
23
+ duration: 900,
24
+ useNativeDriver: true,
25
+ }),
26
+ Animated.timing(iconPulse, {
27
+ toValue: 1,
28
+ duration: 900,
29
+ useNativeDriver: true,
30
+ }),
31
+ ]),
32
+ );
33
+
34
+ loop.start();
35
+ return () => loop.stop();
36
+ }, [iconPulse]);
37
+
38
+ const handleReload = () => {
39
+ if (__DEV__ && DevSettings && DevSettings.reload) {
40
+ DevSettings.reload();
41
+ return;
42
+ }
43
+
44
+ Alert.alert(
45
+ 'Reload',
46
+ 'App reload is typically only available in development mode.',
47
+ );
48
+ };
49
+
50
+ return (
51
+ <AnimatedEntrance style={styles.emptyContainer} distance={14}>
52
+ <Animated.View
53
+ style={[styles.emptyIconWrap, {transform: [{scale: iconPulse}]}]}>
54
+ <EmptyRadarIcon color={AppColors.purple} size={32} />
55
+ </Animated.View>
56
+ <Text style={styles.emptyTitle}>
57
+ {isSearch ? 'No matching APIs' : 'No network activity'}
58
+ </Text>
59
+ <Text style={styles.emptySub}>
60
+ {isSearch
61
+ ? 'Try adjusting your filters or search.'
62
+ : 'Listening for incoming API calls...'}
63
+ </Text>
64
+ {!isSearch && (
65
+ <TouchableScale style={styles.reloadBtn} onPress={handleReload}>
66
+ <Text style={styles.reloadBtnText}>Reload App</Text>
67
+ </TouchableScale>
68
+ )}
69
+ </AnimatedEntrance>
70
+ );
71
+ });
72
+
73
+ export default EmptyState;
@@ -0,0 +1,100 @@
1
+ import React from 'react';
2
+ import {Platform, StyleSheet, Text, View} from 'react-native';
3
+ import {AppColors} from '../styles/AppColors';
4
+ import {AppFonts} from '../styles/AppFonts';
5
+ import {CheckIcon} from './NetworkIcons';
6
+
7
+ interface EndOfListFooterProps {
8
+ count?: number;
9
+ label?: string;
10
+ message?: string;
11
+ }
12
+
13
+ export const EndOfListFooter: React.FC<EndOfListFooterProps> = React.memo(({
14
+ count,
15
+ label,
16
+ message = "You've reached the end of the list",
17
+ }) => {
18
+ return (
19
+ <View style={styles.container}>
20
+ <View style={styles.dividerLine} />
21
+ <View style={styles.badgePill}>
22
+ <View style={styles.iconCircle}>
23
+ <CheckIcon color={AppColors.purple} size={8} />
24
+ </View>
25
+ <Text style={styles.messageText}>{message}</Text>
26
+ {count != null && count > 0 && (
27
+ <View style={styles.countBadge}>
28
+ <Text style={styles.countText}>
29
+ {count} {label ? (count === 1 ? label.replace(/s$/, '') : label) : ''}
30
+ </Text>
31
+ </View>
32
+ )}
33
+ </View>
34
+ <View style={styles.dividerLine} />
35
+ </View>
36
+ );
37
+ });
38
+
39
+ const styles = StyleSheet.create({
40
+ container: {
41
+ flexDirection: 'row',
42
+ alignItems: 'center',
43
+ justifyContent: 'center',
44
+ paddingHorizontal: 16,
45
+ paddingTop: 16,
46
+ paddingBottom: Platform.OS === 'ios' ? 44 : 32,
47
+ gap: 8,
48
+ },
49
+ dividerLine: {
50
+ flex: 1,
51
+ height: 1,
52
+ backgroundColor: AppColors.dividerColor,
53
+ opacity: 0.7,
54
+ },
55
+ badgePill: {
56
+ flexDirection: 'row',
57
+ alignItems: 'center',
58
+ gap: 6,
59
+ paddingHorizontal: 10,
60
+ paddingVertical: 5,
61
+ borderRadius: 999,
62
+ backgroundColor: AppColors.primaryLight,
63
+ borderWidth: 1,
64
+ borderColor: AppColors.grayBorderSecondary,
65
+ shadowColor: AppColors.black,
66
+ shadowOffset: {width: 0, height: 1},
67
+ shadowOpacity: 0.04,
68
+ shadowRadius: 2,
69
+ elevation: 1,
70
+ },
71
+ iconCircle: {
72
+ width: 14,
73
+ height: 14,
74
+ borderRadius: 7,
75
+ backgroundColor: `${AppColors.purple}18`,
76
+ alignItems: 'center',
77
+ justifyContent: 'center',
78
+ },
79
+ messageText: {
80
+ fontFamily: AppFonts.interMedium,
81
+ fontSize: 11,
82
+ color: AppColors.grayTextWeak,
83
+ letterSpacing: 0.1,
84
+ },
85
+ countBadge: {
86
+ paddingHorizontal: 5,
87
+ paddingVertical: 1,
88
+ borderRadius: 6,
89
+ backgroundColor: AppColors.grayBackground,
90
+ borderWidth: 1,
91
+ borderColor: AppColors.grayBorderSecondary,
92
+ },
93
+ countText: {
94
+ fontFamily: AppFonts.interBold,
95
+ fontSize: 9.5,
96
+ color: AppColors.grayTextStrong,
97
+ },
98
+ });
99
+
100
+ export default EndOfListFooter;