react-native-inapp-inspector 1.0.2 → 1.0.4

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.
@@ -2,7 +2,7 @@ import React from 'react';
2
2
  declare const TouchableScale: ({ onPress, style, children, hitSlop, disabled, }: {
3
3
  onPress?: () => void;
4
4
  style?: any;
5
- children: React.ReactNode;
5
+ children?: React.ReactNode;
6
6
  hitSlop?: any;
7
7
  disabled?: boolean;
8
8
  }) => React.JSX.Element;
@@ -108,7 +108,7 @@ exports.clearConsoleLogs = clearConsoleLogs;
108
108
  const getConsoleLogs = () => [...logs];
109
109
  exports.getConsoleLogs = getConsoleLogs;
110
110
  const setupConsoleLogger = () => {
111
- if (global.__CONSOLE_LOGGER_INITIALIZED__)
111
+ if (globalThis.__CONSOLE_LOGGER_INITIALIZED__)
112
112
  return;
113
113
  const originalConsole = {
114
114
  log: console.log,
@@ -136,6 +136,6 @@ const setupConsoleLogger = () => {
136
136
  addLog('error', args, 'error');
137
137
  originalConsole.error(...args);
138
138
  };
139
- global.__CONSOLE_LOGGER_INITIALIZED__ = true;
139
+ globalThis.__CONSOLE_LOGGER_INITIALIZED__ = true;
140
140
  };
141
141
  exports.setupConsoleLogger = setupConsoleLogger;
@@ -117,12 +117,12 @@ const addOrUpdateLog = (log) => {
117
117
  };
118
118
  // ─── Setup ────────────────────────────────────────────────────────────────────
119
119
  const setupNetworkLogger = () => {
120
- if (global.__NETWORK_LOGGER_INITIALIZED__)
120
+ if (globalThis.__NETWORK_LOGGER_INITIALIZED__)
121
121
  return;
122
- global.__NETWORK_LOGGER__ = addOrUpdateLog;
123
- const originalFetch = global.fetch;
122
+ globalThis.__NETWORK_LOGGER__ = addOrUpdateLog;
123
+ const originalFetch = globalThis.fetch;
124
124
  if (originalFetch) {
125
- global.fetch = async (url, options = {}) => {
125
+ globalThis.fetch = async (url, options = {}) => {
126
126
  const method = (options?.method || 'GET').toUpperCase();
127
127
  if (!ALLOWED_METHODS.includes(method))
128
128
  return originalFetch(url, options);
@@ -192,7 +192,7 @@ const setupNetworkLogger = () => {
192
192
  }
193
193
  };
194
194
  }
195
- global.__NETWORK_LOGGER_INITIALIZED__ = true;
195
+ globalThis.__NETWORK_LOGGER_INITIALIZED__ = true;
196
196
  };
197
197
  exports.setupNetworkLogger = setupNetworkLogger;
198
198
  // ─── Axios interceptor helper ─────────────────────────────────────────────────
@@ -79,6 +79,13 @@ const AnalyticsDetail_1 = __importDefault(require("./components/AnalyticsDetail"
79
79
  // WebView
80
80
  const webViewLogger_1 = require("./customHooks/webViewLogger");
81
81
  const constants_1 = require("./constants");
82
+ const NavigationTracker = ({ onStateChange }) => {
83
+ const navState = (0, native_1.useNavigationState)(state => state);
84
+ (0, react_1.useEffect)(() => {
85
+ onStateChange(navState);
86
+ }, [navState, onStateChange]);
87
+ return null;
88
+ };
82
89
  const NetworkInspector = () => {
83
90
  const [logs, setLogs] = (0, react_1.useState)([]);
84
91
  const [visible, setVisible] = (0, react_1.useState)(false);
@@ -145,13 +152,17 @@ const NetworkInspector = () => {
145
152
  const [topEventsExpanded, setTopEventsExpanded] = (0, react_1.useState)(true);
146
153
  const [newEventIds, setNewEventIds] = (0, react_1.useState)(new Set());
147
154
  const prevEventIdsRef = (0, react_1.useRef)(new Set());
148
- const navState = (0, native_1.useNavigationState)(state => state);
155
+ const [navState, setNavState] = (0, react_1.useState)(null);
156
+ const navigationContext = react_1.default.useContext(native_1.NavigationContext);
157
+ const hasNavigationContext = navigationContext !== undefined;
149
158
  const currentRouteRef = (0, react_1.useRef)({
150
159
  path: 'Navigators',
151
160
  params: null,
152
161
  });
153
162
  (0, react_1.useEffect)(() => {
154
- currentRouteRef.current = (0, helpers_1.getNavigationInfo)(navState);
163
+ if (navState) {
164
+ currentRouteRef.current = (0, helpers_1.getNavigationInfo)(navState);
165
+ }
155
166
  }, [navState]);
156
167
  const logRouteMapRef = (0, react_1.useRef)(new Map());
157
168
  const prevLogIdsRef = (0, react_1.useRef)(new Set());
@@ -804,6 +815,7 @@ const NetworkInspector = () => {
804
815
  toggleSectionCollapse,
805
816
  ]);
806
817
  return (<>
818
+ {hasNavigationContext && (<NavigationTracker onStateChange={setNavState}/>)}
807
819
  <TouchableScale_1.default style={styles_1.default.fabWrapper} onPress={() => setVisible(true)} hitSlop={10}>
808
820
  <react_native_1.Animated.View style={[styles_1.default.fabPulseRing, { transform: [{ scale: pulseAnim }] }]}/>
809
821
  <react_native_linear_gradient_1.default colors={[AppColors_1.AppColors.purple, '#8F6EFF']} style={styles_1.default.fab}>
@@ -2,7 +2,7 @@ import React from 'react';
2
2
  declare const TouchableScale: ({ onPress, style, children, hitSlop, disabled, }: {
3
3
  onPress?: () => void;
4
4
  style?: any;
5
- children: React.ReactNode;
5
+ children?: React.ReactNode;
6
6
  hitSlop?: any;
7
7
  disabled?: boolean;
8
8
  }) => React.JSX.Element;
@@ -102,7 +102,7 @@ export const clearConsoleLogs = () => {
102
102
  };
103
103
  export const getConsoleLogs = () => [...logs];
104
104
  export const setupConsoleLogger = () => {
105
- if (global.__CONSOLE_LOGGER_INITIALIZED__)
105
+ if (globalThis.__CONSOLE_LOGGER_INITIALIZED__)
106
106
  return;
107
107
  const originalConsole = {
108
108
  log: console.log,
@@ -130,5 +130,5 @@ export const setupConsoleLogger = () => {
130
130
  addLog('error', args, 'error');
131
131
  originalConsole.error(...args);
132
132
  };
133
- global.__CONSOLE_LOGGER_INITIALIZED__ = true;
133
+ globalThis.__CONSOLE_LOGGER_INITIALIZED__ = true;
134
134
  };
@@ -111,12 +111,12 @@ const addOrUpdateLog = (log) => {
111
111
  };
112
112
  // ─── Setup ────────────────────────────────────────────────────────────────────
113
113
  export const setupNetworkLogger = () => {
114
- if (global.__NETWORK_LOGGER_INITIALIZED__)
114
+ if (globalThis.__NETWORK_LOGGER_INITIALIZED__)
115
115
  return;
116
- global.__NETWORK_LOGGER__ = addOrUpdateLog;
117
- const originalFetch = global.fetch;
116
+ globalThis.__NETWORK_LOGGER__ = addOrUpdateLog;
117
+ const originalFetch = globalThis.fetch;
118
118
  if (originalFetch) {
119
- global.fetch = async (url, options = {}) => {
119
+ globalThis.fetch = async (url, options = {}) => {
120
120
  const method = (options?.method || 'GET').toUpperCase();
121
121
  if (!ALLOWED_METHODS.includes(method))
122
122
  return originalFetch(url, options);
@@ -186,7 +186,7 @@ export const setupNetworkLogger = () => {
186
186
  }
187
187
  };
188
188
  }
189
- global.__NETWORK_LOGGER_INITIALIZED__ = true;
189
+ globalThis.__NETWORK_LOGGER_INITIALIZED__ = true;
190
190
  };
191
191
  // ─── Axios interceptor helper ─────────────────────────────────────────────────
192
192
  export const addAxiosInterceptors = (axiosInstance) => {
package/dist/esm/index.js CHANGED
@@ -2,7 +2,7 @@ import React, { useEffect, useMemo, useRef, useState, useCallback } from 'react'
2
2
  import { Alert, Animated, StyleSheet, FlatList, SectionList, Modal, Platform, Pressable, ScrollView, Text, TextInput, View, Linking, Image, InteractionManager, ActivityIndicator, StatusBar, } from 'react-native';
3
3
  import Svg, { Circle, Path } from 'react-native-svg';
4
4
  import LinearGradient from 'react-native-linear-gradient';
5
- import { useNavigationState } from '@react-navigation/native';
5
+ import { useNavigationState, NavigationContext } from '@react-navigation/native';
6
6
  // Components
7
7
  import TouchableScale from './components/TouchableScale';
8
8
  import useAccordion from './customHooks/useAccordion';
@@ -40,6 +40,13 @@ import AnalyticsDetail from './components/AnalyticsDetail';
40
40
  // WebView
41
41
  import { getWebViewLogs, getWebViewNavHistory, getWebViewHtml, getWebViewCss, getWebViewJs, getWebViewHtmlUrl, clearWebViewData, subscribeWebView, } from './customHooks/webViewLogger';
42
42
  import { METHOD_COLORS, STATUS_FILTERS } from './constants';
43
+ const NavigationTracker = ({ onStateChange }) => {
44
+ const navState = useNavigationState(state => state);
45
+ useEffect(() => {
46
+ onStateChange(navState);
47
+ }, [navState, onStateChange]);
48
+ return null;
49
+ };
43
50
  const NetworkInspector = () => {
44
51
  const [logs, setLogs] = useState([]);
45
52
  const [visible, setVisible] = useState(false);
@@ -106,13 +113,17 @@ const NetworkInspector = () => {
106
113
  const [topEventsExpanded, setTopEventsExpanded] = useState(true);
107
114
  const [newEventIds, setNewEventIds] = useState(new Set());
108
115
  const prevEventIdsRef = useRef(new Set());
109
- const navState = useNavigationState(state => state);
116
+ const [navState, setNavState] = useState(null);
117
+ const navigationContext = React.useContext(NavigationContext);
118
+ const hasNavigationContext = navigationContext !== undefined;
110
119
  const currentRouteRef = useRef({
111
120
  path: 'Navigators',
112
121
  params: null,
113
122
  });
114
123
  useEffect(() => {
115
- currentRouteRef.current = getNavigationInfo(navState);
124
+ if (navState) {
125
+ currentRouteRef.current = getNavigationInfo(navState);
126
+ }
116
127
  }, [navState]);
117
128
  const logRouteMapRef = useRef(new Map());
118
129
  const prevLogIdsRef = useRef(new Set());
@@ -765,6 +776,7 @@ const NetworkInspector = () => {
765
776
  toggleSectionCollapse,
766
777
  ]);
767
778
  return (<>
779
+ {hasNavigationContext && (<NavigationTracker onStateChange={setNavState}/>)}
768
780
  <TouchableScale style={styles.fabWrapper} onPress={() => setVisible(true)} hitSlop={10}>
769
781
  <Animated.View style={[styles.fabPulseRing, { transform: [{ scale: pulseAnim }] }]}/>
770
782
  <LinearGradient colors={[AppColors.purple, '#8F6EFF']} style={styles.fab}>
package/example/App.tsx CHANGED
@@ -8,12 +8,12 @@ import {
8
8
  ScrollView,
9
9
  useColorScheme,
10
10
  } from 'react-native';
11
- import { SafeAreaProvider, SafeAreaView } from 'react-native-safe-area-context';
11
+ import { SafeAreaProvider } from 'react-native-safe-area-context';
12
+ import { NavigationContainer } from '@react-navigation/native';
13
+ import { createNativeStackNavigator } from '@react-navigation/native-stack';
12
14
  import NetworkInspector from 'react-native-inapp-inspector';
13
15
 
14
- function App() {
15
- const isDarkMode = useColorScheme() === 'dark';
16
-
16
+ function HomeScreen({ navigation }: any) {
17
17
  const triggerNetworkRequest = async () => {
18
18
  try {
19
19
  console.log('[API] Triggering network request...');
@@ -40,37 +40,116 @@ function App() {
40
40
  console.error('[App] Error log triggered! Simulated critical error.');
41
41
  };
42
42
 
43
+ React.useEffect(() => {
44
+ console.log('[Test] HomeScreen mounted, triggering automated tests...');
45
+ triggerNetworkRequest();
46
+ triggerConsoleLogs();
47
+
48
+ const timer = setTimeout(() => {
49
+ console.log('[Test] Navigating to Details screen...');
50
+ navigation.navigate('Details');
51
+ }, 2500);
52
+
53
+ return () => clearTimeout(timer);
54
+ }, []);
55
+
56
+ return (
57
+ <View style={styles.container}>
58
+ <ScrollView contentContainerStyle={styles.content}>
59
+ <Text style={styles.title}>RN In-App Inspector</Text>
60
+ <Text style={styles.subtitle}>Reference Implementation</Text>
61
+
62
+ <View style={styles.card}>
63
+ <Text style={styles.cardTitle}>Inspect Network & Console Logs</Text>
64
+ <Text style={styles.cardDesc}>
65
+ Tap the buttons below to trigger simulated background events, then click the floating inspector badge to open the inspector overlay.
66
+ </Text>
67
+
68
+ <TouchableOpacity style={styles.button} onPress={triggerNetworkRequest}>
69
+ <Text style={styles.buttonText}>Trigger Fetch (200 OK)</Text>
70
+ </TouchableOpacity>
71
+
72
+ <TouchableOpacity style={[styles.button, styles.dangerButton]} onPress={triggerFailedNetworkRequest}>
73
+ <Text style={styles.buttonText}>Trigger Fetch (404 Error)</Text>
74
+ </TouchableOpacity>
75
+
76
+ <TouchableOpacity style={[styles.button, styles.infoButton]} onPress={triggerConsoleLogs}>
77
+ <Text style={styles.buttonText}>Trigger Console Logs</Text>
78
+ </TouchableOpacity>
79
+
80
+ <TouchableOpacity style={[styles.button, styles.successButton]} onPress={() => navigation.navigate('Details')}>
81
+ <Text style={styles.buttonText}>Go to Details Screen</Text>
82
+ </TouchableOpacity>
83
+ </View>
84
+ </ScrollView>
85
+ <NetworkInspector />
86
+ </View>
87
+ );
88
+ }
89
+
90
+ function DetailsScreen({ navigation }: any) {
91
+ const triggerDetailLogs = () => {
92
+ console.log('[Details] User navigated to details screen and triggered a log.');
93
+ };
94
+
95
+ React.useEffect(() => {
96
+ console.log('[Test] DetailsScreen mounted!');
97
+ triggerDetailLogs();
98
+ }, []);
99
+
100
+ return (
101
+ <View style={styles.container}>
102
+ <ScrollView contentContainerStyle={styles.content}>
103
+ <Text style={styles.title}>Details Screen</Text>
104
+ <Text style={styles.subtitle}>Navigation State Verification</Text>
105
+
106
+ <View style={styles.card}>
107
+ <Text style={styles.cardTitle}>Verify Navigation Routing</Text>
108
+ <Text style={styles.cardDesc}>
109
+ The inspector tracks your current navigation route. Open the inspector overlay and check the 'route' metadata on new network/console logs.
110
+ </Text>
111
+
112
+ <TouchableOpacity style={styles.button} onPress={triggerDetailLogs}>
113
+ <Text style={styles.buttonText}>Trigger Log from Details</Text>
114
+ </TouchableOpacity>
115
+
116
+ <TouchableOpacity style={[styles.button, styles.secondaryButton]} onPress={() => navigation.goBack()}>
117
+ <Text style={styles.buttonText}>Go Back Home</Text>
118
+ </TouchableOpacity>
119
+ </View>
120
+ </ScrollView>
121
+ <NetworkInspector />
122
+ </View>
123
+ );
124
+ }
125
+
126
+ const Stack = createNativeStackNavigator();
127
+
128
+ function App() {
129
+ const isDarkMode = useColorScheme() === 'dark';
130
+
43
131
  return (
44
132
  <SafeAreaProvider>
45
133
  <StatusBar barStyle={isDarkMode ? 'light-content' : 'dark-content'} />
46
- <SafeAreaView style={styles.container}>
47
- <ScrollView contentContainerStyle={styles.content}>
48
- <Text style={styles.title}>RN In-App Inspector</Text>
49
- <Text style={styles.subtitle}>Reference Implementation</Text>
50
-
51
- <View style={styles.card}>
52
- <Text style={styles.cardTitle}>Inspect Network & Console Logs</Text>
53
- <Text style={styles.cardDesc}>
54
- Tap the buttons below to trigger simulated background events, then click the floating inspector badge to open the inspector overlay.
55
- </Text>
56
-
57
- <TouchableOpacity style={styles.button} onPress={triggerNetworkRequest}>
58
- <Text style={styles.buttonText}>Trigger Fetch (200 OK)</Text>
59
- </TouchableOpacity>
60
-
61
- <TouchableOpacity style={[styles.button, styles.dangerButton]} onPress={triggerFailedNetworkRequest}>
62
- <Text style={styles.buttonText}>Trigger Fetch (404 Error)</Text>
63
- </TouchableOpacity>
64
-
65
- <TouchableOpacity style={[styles.button, styles.infoButton]} onPress={triggerConsoleLogs}>
66
- <Text style={styles.buttonText}>Trigger Console Logs</Text>
67
- </TouchableOpacity>
68
- </View>
69
- </ScrollView>
70
-
71
- {/* Floating In-App Debug Inspector */}
72
- <NetworkInspector />
73
- </SafeAreaView>
134
+ <NavigationContainer>
135
+ <Stack.Navigator
136
+ screenOptions={{
137
+ headerStyle: {
138
+ backgroundColor: '#1E1E24',
139
+ },
140
+ headerTintColor: '#FFFFFF',
141
+ headerTitleStyle: {
142
+ fontWeight: 'bold',
143
+ },
144
+ contentStyle: {
145
+ backgroundColor: '#121214',
146
+ },
147
+ }}
148
+ >
149
+ <Stack.Screen name="Home" component={HomeScreen} options={{ title: 'Dashboard' }} />
150
+ <Stack.Screen name="Details" component={DetailsScreen} options={{ title: 'Details' }} />
151
+ </Stack.Navigator>
152
+ </NavigationContainer>
74
153
  </SafeAreaProvider>
75
154
  );
76
155
  }
@@ -133,6 +212,12 @@ const styles = StyleSheet.create({
133
212
  infoButton: {
134
213
  backgroundColor: '#5856D6',
135
214
  },
215
+ successButton: {
216
+ backgroundColor: '#34C759',
217
+ },
218
+ secondaryButton: {
219
+ backgroundColor: '#8E8E93',
220
+ },
136
221
  buttonText: {
137
222
  fontSize: 15,
138
223
  fontWeight: '600',