react-native-inapp-inspector 1.1.15 → 1.1.17

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 (106) hide show
  1. package/README.md +150 -130
  2. package/dist/commonjs/components/AnimatedEntrance.js +3 -0
  3. package/dist/commonjs/components/AppHeaderLogo.d.ts +8 -0
  4. package/dist/commonjs/components/AppHeaderLogo.js +85 -0
  5. package/dist/commonjs/components/CopyButton.d.ts +1 -1
  6. package/dist/commonjs/components/CopyButton.js +4 -4
  7. package/dist/commonjs/components/EndOfListFooter.js +2 -3
  8. package/dist/commonjs/components/Inspector/AnalyticsTab.d.ts +1 -1
  9. package/dist/commonjs/components/Inspector/AnalyticsTab.js +7 -8
  10. package/dist/commonjs/components/Inspector/BundleTab.d.ts +41 -0
  11. package/dist/commonjs/components/Inspector/BundleTab.js +2309 -0
  12. package/dist/commonjs/components/Inspector/ConsoleTab.d.ts +1 -1
  13. package/dist/commonjs/components/Inspector/ConsoleTab.js +9 -9
  14. package/dist/commonjs/components/Inspector/InspectorHeader.d.ts +1 -1
  15. package/dist/commonjs/components/Inspector/InspectorHeader.js +187 -54
  16. package/dist/commonjs/components/Inspector/LogDetail.d.ts +1 -1
  17. package/dist/commonjs/components/Inspector/LogDetail.js +2 -2
  18. package/dist/commonjs/components/Inspector/MainScreen.js +86 -7
  19. package/dist/commonjs/components/Inspector/NetworkDetail.d.ts +1 -1
  20. package/dist/commonjs/components/Inspector/NetworkDetail.js +2 -2
  21. package/dist/commonjs/components/Inspector/NetworkTab.d.ts +1 -1
  22. package/dist/commonjs/components/Inspector/NetworkTab.js +10 -9
  23. package/dist/commonjs/components/Inspector/ReduxDetail.d.ts +3 -0
  24. package/dist/commonjs/components/Inspector/ReduxDetail.js +576 -0
  25. package/dist/commonjs/components/Inspector/ReduxTab.d.ts +1 -1
  26. package/dist/commonjs/components/Inspector/ReduxTab.js +435 -51
  27. package/dist/commonjs/components/Inspector/SettingsPanel.js +8 -2
  28. package/dist/commonjs/components/Inspector/TabBar.d.ts +1 -1
  29. package/dist/commonjs/components/Inspector/TabBar.js +11 -8
  30. package/dist/commonjs/components/JsonViewer.d.ts +2 -2
  31. package/dist/commonjs/components/JsonViewer.js +93 -32
  32. package/dist/commonjs/components/LogCard.js +3 -4
  33. package/dist/commonjs/components/NetworkIcons.d.ts +8 -0
  34. package/dist/commonjs/components/NetworkIcons.js +54 -1
  35. package/dist/commonjs/components/ReduxTreeView.d.ts +2 -2
  36. package/dist/commonjs/components/ReduxTreeView.js +2 -3
  37. package/dist/commonjs/components/SegmentedTabs.d.ts +1 -1
  38. package/dist/commonjs/components/SegmentedTabs.js +2 -2
  39. package/dist/commonjs/constants/version.d.ts +1 -1
  40. package/dist/commonjs/constants/version.js +1 -1
  41. package/dist/commonjs/customHooks/consoleLogger.js +37 -9
  42. package/dist/commonjs/customHooks/reduxLogger.js +4 -2
  43. package/dist/commonjs/helpers/index.js +6 -2
  44. package/dist/commonjs/index.js +15 -1
  45. package/dist/commonjs/styles/AppColors.js +163 -163
  46. package/dist/commonjs/styles/index.d.ts +14 -0
  47. package/dist/commonjs/styles/index.js +14 -0
  48. package/dist/commonjs/types/enums.d.ts +2 -2
  49. package/dist/commonjs/types/interfaces.d.ts +11 -0
  50. package/dist/esm/components/AnimatedEntrance.js +4 -1
  51. package/dist/esm/components/AppHeaderLogo.d.ts +8 -0
  52. package/dist/esm/components/AppHeaderLogo.js +45 -0
  53. package/dist/esm/components/CopyButton.d.ts +1 -1
  54. package/dist/esm/components/CopyButton.js +5 -5
  55. package/dist/esm/components/EndOfListFooter.js +2 -2
  56. package/dist/esm/components/Inspector/AnalyticsTab.d.ts +1 -1
  57. package/dist/esm/components/Inspector/AnalyticsTab.js +7 -8
  58. package/dist/esm/components/Inspector/BundleTab.d.ts +41 -0
  59. package/dist/esm/components/Inspector/BundleTab.js +2271 -0
  60. package/dist/esm/components/Inspector/ConsoleTab.d.ts +1 -1
  61. package/dist/esm/components/Inspector/ConsoleTab.js +9 -9
  62. package/dist/esm/components/Inspector/InspectorHeader.d.ts +1 -1
  63. package/dist/esm/components/Inspector/InspectorHeader.js +153 -53
  64. package/dist/esm/components/Inspector/LogDetail.d.ts +1 -1
  65. package/dist/esm/components/Inspector/LogDetail.js +2 -2
  66. package/dist/esm/components/Inspector/MainScreen.js +53 -7
  67. package/dist/esm/components/Inspector/NetworkDetail.d.ts +1 -1
  68. package/dist/esm/components/Inspector/NetworkDetail.js +2 -2
  69. package/dist/esm/components/Inspector/NetworkTab.d.ts +1 -1
  70. package/dist/esm/components/Inspector/NetworkTab.js +10 -9
  71. package/dist/esm/components/Inspector/ReduxDetail.d.ts +3 -0
  72. package/dist/esm/components/Inspector/ReduxDetail.js +538 -0
  73. package/dist/esm/components/Inspector/ReduxTab.d.ts +1 -1
  74. package/dist/esm/components/Inspector/ReduxTab.js +404 -53
  75. package/dist/esm/components/Inspector/SettingsPanel.js +9 -3
  76. package/dist/esm/components/Inspector/TabBar.d.ts +1 -1
  77. package/dist/esm/components/Inspector/TabBar.js +12 -9
  78. package/dist/esm/components/JsonViewer.d.ts +2 -2
  79. package/dist/esm/components/JsonViewer.js +94 -33
  80. package/dist/esm/components/LogCard.js +3 -4
  81. package/dist/esm/components/NetworkIcons.d.ts +8 -0
  82. package/dist/esm/components/NetworkIcons.js +47 -1
  83. package/dist/esm/components/ReduxTreeView.d.ts +2 -2
  84. package/dist/esm/components/ReduxTreeView.js +2 -2
  85. package/dist/esm/components/SegmentedTabs.d.ts +1 -1
  86. package/dist/esm/components/SegmentedTabs.js +2 -2
  87. package/dist/esm/constants/version.d.ts +1 -1
  88. package/dist/esm/constants/version.js +1 -1
  89. package/dist/esm/customHooks/consoleLogger.js +37 -9
  90. package/dist/esm/customHooks/reduxLogger.js +4 -2
  91. package/dist/esm/helpers/index.js +6 -2
  92. package/dist/esm/index.js +15 -1
  93. package/dist/esm/styles/AppColors.js +163 -163
  94. package/dist/esm/styles/index.d.ts +14 -0
  95. package/dist/esm/styles/index.js +14 -0
  96. package/dist/esm/types/enums.d.ts +2 -2
  97. package/dist/esm/types/interfaces.d.ts +11 -0
  98. package/example/App.tsx +62 -2
  99. package/example/README.md +33 -77
  100. package/example/assets/app_icon.png +0 -0
  101. package/example/ios/Podfile.lock +3 -3
  102. package/example/ios/example/Images.xcassets/AppIcon.appiconset/Contents.json +18 -9
  103. package/example/ios/example/Images.xcassets/AppIcon.appiconset/app_icon_1024.png +0 -0
  104. package/example/package-lock.json +824 -10
  105. package/example/package.json +6 -2
  106. package/package.json +4 -2
package/README.md CHANGED
@@ -14,7 +14,7 @@
14
14
  <a href="https://github.com/vengatmacuser/react-native-inapp-inspector"><img src="https://img.shields.io/badge/platform-iOS%20%7C%20Android-blue" alt="platform" /></a>
15
15
  </p>
16
16
 
17
- A self-contained in-app debugging overlay for React Native. Inspect network traffic, console output, analytics events, and Redux state directly inside your app.
17
+ A self-contained, developer-first in-app debugging overlay for React Native. Inspect network traffic, console logs, stack traces, analytics events, and Redux state directly on your device or simulator with zero external dependencies.
18
18
 
19
19
  <p align="center">
20
20
  <img src="https://raw.githubusercontent.com/vengatmacuser/react-native-inapp-inspector/main/assets/walkthrough.gif" alt="React Native In-App Inspector Walkthrough" width="360" style="border-radius: 20px;" />
@@ -22,25 +22,28 @@ A self-contained in-app debugging overlay for React Native. Inspect network traf
22
22
 
23
23
  ---
24
24
 
25
- ## Features
25
+ ## Features
26
26
 
27
- | Feature | Description |
28
- | ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
29
- | Network inspector | Captures `fetch` and axios `GET`, `POST`, `PUT`, `PATCH`, and `DELETE` calls with URL, method, status, headers, body, response, duration, caller, cURL, and fetch snippets. |
30
- | Console logger | Captures `console.log`, `console.info`, `console.warn`, and `console.error` with source method and caller details. |
31
- | Analytics tracker | Captures manual analytics events and patched `@react-native-firebase/analytics` calls including `logEvent`, `logScreenView`, user properties, and user id. |
32
- | Redux inspector | Connects to a Redux store, displays the live state tree, tracks dispatched actions, affected slices, and action history. |
33
- | Error boundary | Exports an `ErrorBoundary` for catching React errors and wrapping the inspector safely. |
27
+ | Feature | Description |
28
+ | --- | --- |
29
+ | 🌐 **Network Inspector** | Intercepts `fetch` and Axios (`GET`, `POST`, `PUT`, `PATCH`, `DELETE`). Inspect status codes, request/response headers, body JSON, duration, caller origin, and instant cURL / fetch export snippets. |
30
+ | 🪵 **Console Logger & Stack Trace** | Captures `console.log`, `info`, `warn`, and `error`. Displays trigger file (`TSX`, `JSX`, `TS`, `JS`) & line numbers via **Metro Symbolication**, call stack frames, individual arguments inspection, and duplicate collapsing (`×N`). |
31
+ | ⏸️ **Live Stream Pause / Resume** | Freeze incoming network requests, console logs, and analytics streams on the fly to inspect active traffic without list jumping. |
32
+ | 📊 **Analytics Tracker** | Tracks manual events and auto-patches `@react-native-firebase/analytics` calls (`logEvent`, `logScreenView`, `setUserProperties`, and `setUserId`). |
33
+ | 🔄 **Redux State & Actions** | Connects to Redux / Redux Toolkit. Inspect dispatched actions with deep state diffs, payload breakdown, slice state trees, and `redux-persist` metadata. |
34
+ | 📦 **Bundle Visualizer** | In-app JavaScript bundle size breakdown, Hermes engine bytecode metrics, visual package treemap, and integrated `react-native-bundle-visualizer` CLI. |
35
+ | 🪟 **Rich JSON Viewer** | Explore data in **Pretty**, **Raw**, and **Table** modes with full-text search highlighting and uniform typography. |
36
+ | 🛡️ **Error Boundary** | Built-in `ErrorBoundary` to gracefully catch and inspect React render crashes. |
34
37
 
35
38
  ---
36
39
 
37
- ## Video Walkthrough
40
+ ## 🎬 Video Walkthrough
38
41
 
39
42
  [Download or watch the Video Walkthrough](https://raw.githubusercontent.com/vengatmacuser/react-native-inapp-inspector/main/example/guidance/Video-WalkThrough.mp4)
40
43
 
41
44
  ---
42
45
 
43
- ## Installation
46
+ ## 📦 Installation
44
47
 
45
48
  ```bash
46
49
  npm install --save-dev react-native-inapp-inspector axios
@@ -50,25 +53,22 @@ npm install --save-dev react-native-inapp-inspector axios
50
53
  yarn add -D react-native-inapp-inspector axios
51
54
  ```
52
55
 
53
- The package has React and React Native as peer dependencies. It depends on `@react-navigation/native`, `react-native-linear-gradient`, and `react-native-svg`. The current network logger imports `axios` for axios interception, so install `axios` even if most of your requests use `fetch`.
56
+ ### Peer & Native Dependencies
54
57
 
55
- Install optional integrations when you use Firebase Analytics capture:
58
+ The package has React and React Native as peer dependencies. It depends on `@react-navigation/native`, `react-native-linear-gradient`, and `react-native-svg`.
56
59
 
57
- ```bash
58
- npm install @react-native-firebase/analytics
59
- ```
60
-
61
- For iOS, install pods after adding native dependencies:
60
+ *(Optional)* If you use `@react-native-clipboard/clipboard` in your project, the inspector automatically detects and utilizes native clipboard bridges for seamless emulator-to-host copying.
62
61
 
63
62
  ```bash
63
+ # iOS Pods installation
64
64
  cd ios && pod install
65
65
  ```
66
66
 
67
67
  ---
68
68
 
69
- ## Basic Setup
69
+ ## 🚀 Basic Setup
70
70
 
71
- Mount the inspector once near the root of your app.
71
+ Mount `<NetworkInspector />` near the root of your application:
72
72
 
73
73
  ```tsx
74
74
  import React from 'react';
@@ -78,7 +78,7 @@ import NetworkInspector from 'react-native-inapp-inspector';
78
78
  const App = () => {
79
79
  return (
80
80
  <SafeAreaView style={{flex: 1}}>
81
- {/* Your app */}
81
+ {/* Your application components */}
82
82
  <NetworkInspector />
83
83
  </SafeAreaView>
84
84
  );
@@ -87,77 +87,59 @@ const App = () => {
87
87
  export default App;
88
88
  ```
89
89
 
90
- When mounted, the inspector sets up network logging, clears previous network logs, patches console logging, and attempts Firebase Analytics auto-setup if `@react-native-firebase/analytics` is installed.
90
+ When mounted, the inspector automatically sets up network logging, intercepts console methods, and attaches Firebase Analytics if available.
91
91
 
92
- If you need to capture requests that happen before the component mounts, call `setupNetworkLogger()` at module level in your app entry file.
92
+ ### Early Startup Network Logging
93
+
94
+ If your application makes API calls before the root component finishes mounting, initialize the logger at the module level in your entry file (`index.js` or `App.tsx`):
93
95
 
94
96
  ```tsx
95
97
  import NetworkInspector, {
96
98
  setupNetworkLogger,
99
+ setupConsoleLogger,
97
100
  } from 'react-native-inapp-inspector';
98
101
 
99
102
  setupNetworkLogger();
103
+ setupConsoleLogger();
100
104
  ```
101
105
 
102
- You can disable the overlay without removing it from your tree:
103
-
104
- ```tsx
105
- <NetworkInspector enabled={false} />
106
- ```
107
-
108
- Use `isEnabled` (defaults to `true`) to fully hide the floating launcher button:
109
-
110
- ```tsx
111
- <NetworkInspector isEnabled={false} />
112
- ```
113
-
114
- ---
115
-
116
- ## Settings Persistence
106
+ ### Toggling Visibility
117
107
 
118
- By default, the inspector preserves configuration preferences (such as dark mode, default landing tab, and module visibilities):
119
- - **iOS:** Settings are persisted automatically using React Native's built-in `Settings` module (`NSUserDefaults`) with zero configuration or additional packages required.
120
- - **Android / Custom:** To persist settings on Android (or to use a custom storage mechanism on both platforms), pass a storage instance such as `@react-native-async-storage/async-storage` or `react-native-mmkv` to the `storage` prop:
108
+ You can disable or hide the floating launcher overlay conditionally:
121
109
 
122
110
  ```tsx
123
- import AsyncStorage from '@react-native-async-storage/async-storage';
111
+ // Fully disable the overlay and interception
112
+ <NetworkInspector enabled={__DEV__} />
124
113
 
125
- <NetworkInspector storage={AsyncStorage} />
114
+ // Hide the floating trigger button while keeping background interception active
115
+ <NetworkInspector isEnabled={false} />
126
116
  ```
127
117
 
128
- If no `storage` prop is passed, Android will fall back to an in-memory store (settings reset when the app is restarted).
129
-
130
118
  ---
131
119
 
132
- ## Navigation & Screen Tracking
120
+ ## 🪵 Console Logger & Stack Trace
133
121
 
134
- To group network requests, console logs, and analytics events by the specific navigation screen where they occurred, the inspector automatically hooks into React Navigation context.
122
+ The console logger provides deep insight into every `console.log`, `info`, `warn`, and `error` call:
135
123
 
136
- If you mount `<NetworkInspector />` globally at the root of your application (outside of the `<NavigationContainer>`), it won't have access to React Navigation's context. To enable accurate screen tracking in this setup, create a navigation ref and pass it to the `navigationRef` prop:
124
+ - **Metro Source Map Symbolication**: In development mode, stack traces are automatically symbolicated against Metro to point directly to your exact project source files (`HomeScreen.tsx:42:15`, `App.tsx:20`).
125
+ - **File Type Badges**: Distinct visual chips identifying `.tsx`, `.jsx`, `.ts`, and `.js` callers.
126
+ - **Detailed Sub-Tabs**:
127
+ - **Output / Message**: Full message with JSON Viewer (Pretty, Raw, Table modes) and link detection.
128
+ - **Args (N)**: Inspect each passed argument individually with type detection (`Array[5]`, `Object{4}`).
129
+ - **Call Stack Trace**: Structured frame cards (with Frame `#`, Function, File, and `L:C` pills) and Raw Trace view.
130
+ - **Error Stack**: Automatically captures the thrown Error stack trace when logging Error objects.
131
+ - **Metadata**: Structured table of log properties, timestamp, character count, and duplicate counter.
137
132
 
138
133
  ```tsx
139
- import { NavigationContainer, createNavigationContainerRef } from '@react-navigation/native';
140
- import NetworkInspector from 'react-native-inapp-inspector';
141
-
142
- const navigationRef = createNavigationContainerRef();
143
-
144
- const App = () => {
145
- return (
146
- <>
147
- <NavigationContainer ref={navigationRef}>
148
- {/* Navigators / Screens */}
149
- </NavigationContainer>
150
- <NetworkInspector navigationRef={navigationRef} />
151
- </>
152
- );
153
- };
134
+ console.log('[API] User authenticated successfully', {userId: 42, role: 'admin'});
135
+ console.error(new Error('Payment gateway timeout'));
154
136
  ```
155
137
 
156
138
  ---
157
139
 
158
- ## Network Logging
140
+ ## 🌐 Network Logging
159
141
 
160
- `setupNetworkLogger()` patches global `fetch`, the default axios instance, and future axios instances created with `axios.create()`.
142
+ `setupNetworkLogger()` intercepts global `fetch`, the default Axios instance, and instances created with `axios.create()`.
161
143
 
162
144
  ```tsx
163
145
  import axios from 'axios';
@@ -171,7 +153,7 @@ await fetch('https://api.example.com/users');
171
153
  await api.post('/login', {email, password});
172
154
  ```
173
155
 
174
- If an axios instance was created before `setupNetworkLogger()` ran, attach interceptors manually:
156
+ If an Axios instance was instantiated before `setupNetworkLogger()` ran, attach interceptors manually:
175
157
 
176
158
  ```tsx
177
159
  import {addAxiosInterceptors} from 'react-native-inapp-inspector';
@@ -179,27 +161,46 @@ import {addAxiosInterceptors} from 'react-native-inapp-inspector';
179
161
  addAxiosInterceptors(api);
180
162
  ```
181
163
 
182
- Network logs are capped at 100 entries and ignore React Native symbolication requests.
183
-
184
164
  ---
185
165
 
186
- ## Console Logging
166
+ ## 🔄 Redux State & Action Inspection
187
167
 
188
- The inspector captures console output automatically when mounted. You can also set it up manually:
168
+ Connect your Redux store once during application startup:
189
169
 
190
170
  ```tsx
191
- import {setupConsoleLogger} from 'react-native-inapp-inspector';
171
+ import {connectReduxStore} from 'react-native-inapp-inspector';
172
+ import store from './store';
192
173
 
193
- setupConsoleLogger();
174
+ connectReduxStore(store);
175
+ ```
176
+
177
+ ### RTK Query, Thunks & Sagas (Recommended)
178
+
179
+ To capture actions dispatched from inside async thunks, sagas, or RTK Query, add `inspectorReduxMiddleware`:
180
+
181
+ ```tsx
182
+ import {configureStore} from '@reduxjs/toolkit';
183
+ import {inspectorReduxMiddleware, connectReduxStore} from 'react-native-inapp-inspector';
184
+ import rootReducer from './slices';
185
+
186
+ const store = configureStore({
187
+ reducer: rootReducer,
188
+ middleware: getDefaultMiddleware =>
189
+ getDefaultMiddleware().concat(inspectorReduxMiddleware),
190
+ });
191
+
192
+ connectReduxStore(store);
194
193
  ```
195
194
 
196
- Captured levels are `log`, `info`, `warn`, and `error`.
195
+ The Redux tab provides:
196
+ - **Action History**: Action type badge, timestamp, payload size, affected slices, deep state diffs, and snapshot viewer.
197
+ - **Slice Tree**: Live state tree per slice, persisted slice detection (`_persist`), search filtering, and JSON table exploration.
197
198
 
198
199
  ---
199
200
 
200
- ## Analytics Logging
201
+ ## 📊 Analytics Logging
201
202
 
202
- Manual events can be pushed into the Analytics tab:
203
+ Log manual analytics events or connect Firebase Analytics:
203
204
 
204
205
  ```tsx
205
206
  import {logAnalyticsEvent} from 'react-native-inapp-inspector';
@@ -211,7 +212,7 @@ logAnalyticsEvent('purchase_completed', {
211
212
  });
212
213
  ```
213
214
 
214
- For Firebase Analytics, pass the result of `analytics()` to `setupAnalyticsLogger()` before analytics calls begin:
215
+ ### Firebase Analytics Integration
215
216
 
216
217
  ```tsx
217
218
  import analytics from '@react-native-firebase/analytics';
@@ -220,80 +221,101 @@ import {setupAnalyticsLogger} from 'react-native-inapp-inspector';
220
221
  setupAnalyticsLogger(analytics());
221
222
  ```
222
223
 
223
- The logger patches `logEvent`, `logScreenView`, `setUserProperty`, `setUserProperties`, and `setUserId`. Analytics events are capped at 200 entries.
224
-
225
224
  ---
226
225
 
227
- ## Redux Inspection
226
+ ## 🧭 Navigation & Screen Tracking
228
227
 
229
- Connect your Redux store once during app startup.
228
+ To group network requests, logs, and analytics by the active screen, pass your navigation container ref:
230
229
 
231
230
  ```tsx
232
- import {connectReduxStore} from 'react-native-inapp-inspector';
233
- import store from './store';
231
+ import {NavigationContainer, createNavigationContainerRef} from '@react-navigation/native';
232
+ import NetworkInspector from 'react-native-inapp-inspector';
234
233
 
235
- connectReduxStore(store);
234
+ const navigationRef = createNavigationContainerRef();
235
+
236
+ const App = () => {
237
+ return (
238
+ <>
239
+ <NavigationContainer ref={navigationRef}>
240
+ {/* Your screens */}
241
+ </NavigationContainer>
242
+ <NetworkInspector navigationRef={navigationRef} />
243
+ </>
244
+ );
245
+ };
236
246
  ```
237
247
 
238
- **Recommended:** if you use thunks, sagas or RTK Query, also add the inspector middleware so actions dispatched from inside them are captured with full type/payload attribution (they bypass the wrapped outer dispatch otherwise):
248
+ ---
239
249
 
240
- ```tsx
241
- import {inspectorReduxMiddleware} from 'react-native-inapp-inspector';
250
+ ## 📦 Application Bundle Size & Asset Inspector
242
251
 
243
- const store = configureStore({
244
- reducer,
245
- middleware: getDefaultMiddleware =>
246
- getDefaultMiddleware().concat(inspectorReduxMiddleware),
247
- });
248
- ```
252
+ The inspector includes a dedicated **Bundle** tab (placed right after Redux) with **5 specialized sub-tabs** to inspect and optimize bundle assets:
249
253
 
250
- Using both together is safe they de-duplicate automatically.
254
+ 1. 📊 **Overview & Treemap**: Real-time stacked visual ratio bar, total bundle size (`MB`), Hermes Bytecode engine detection, and category weight cards.
255
+ 2. 📁 **Files Explorer**: Searchable file-by-file footprint breakdown (`PNG`, `TSX`, `JS`, `TTF`, `JSON`) with lines, resolution, and optimization status.
256
+ 3. 📦 **Packages**: Node modules footprint audit (`react-native`, `@react-navigation`, `axios`, `react-native-svg`), version tags, and direct vs. transitive dependency analysis.
257
+ 4. 🖼️ **Media Auditor**: Dedicated asset compression analysis for images and custom fonts with potential WebP savings calculators.
258
+ 5. ⚡ **Optimizer Checklist**: Actionable best-practice tips for Hermes engine, selective path imports (tree-shaking), font subsetting, and screen lazy-loading.
251
259
 
252
- The Redux tab shows the latest state tree, recent dispatches, payloads, and changed top-level state slices. Action history is capped at 50 entries.
260
+ ---
261
+
262
+ ## ⚙️ Settings Persistence
263
+
264
+ Inspector preferences (dark mode, active modules, default landing tab) persist across app launches:
265
+ - **iOS**: Uses React Native's built-in `Settings` module (`NSUserDefaults`) with zero extra configuration.
266
+ - **Android / Custom Storage**: Pass `@react-native-async-storage/async-storage` or `react-native-mmkv` to the `storage` prop:
267
+
268
+ ```tsx
269
+ import AsyncStorage from '@react-native-async-storage/async-storage';
270
+
271
+ <NetworkInspector storage={AsyncStorage} />
272
+ ```
253
273
 
254
274
  ---
255
275
 
256
- ## Error Boundary
276
+ ## 🛡️ Error Boundary
277
+
278
+ Catch and inspect unhandled React component render crashes:
257
279
 
258
280
  ```tsx
259
281
  import {ErrorBoundary} from 'react-native-inapp-inspector';
260
282
 
261
283
  <ErrorBoundary>
262
- <YourComponent />
263
- </ErrorBoundary>;
284
+ <YourApp />
285
+ </ErrorBoundary>
264
286
  ```
265
287
 
266
288
  ---
267
289
 
268
- ## Public API
269
-
270
- | Export | Type | Description |
271
- | --------------------------------------------------- | ----------------- | -------------------------------------------------------------------------- |
272
- | `NetworkInspector` | default component | Floating inspector overlay. Mount once near the root of the app. |
273
- | `setupNetworkLogger()` | function | Patches `fetch`, default axios, and future `axios.create()` instances. |
274
- | `addAxiosInterceptors(instance)` | function | Manually attaches axios interceptors to an existing instance. |
275
- | `clearNetworkLogs()` | function | Clears captured network logs. |
276
- | `subscribeNetworkLogs(callback)` | function | Subscribes to network log updates and returns an unsubscribe function. |
277
- | `setupConsoleLogger()` | function | Patches console methods. |
278
- | `clearConsoleLogs()` | function | Clears captured console logs. |
279
- | `subscribeConsoleLogs(callback)` | function | Subscribes to console log updates and returns an unsubscribe function. |
280
- | `setupAnalyticsLogger(instance)` | function | Patches a Firebase Analytics instance. |
281
- | `logAnalyticsEvent(name, params?, userProperties?)` | function | Adds a manual analytics event to the inspector. |
282
- | `clearAnalyticsEvents()` | function | Clears captured analytics events. |
283
- | `subscribeAnalyticsEvents(callback)` | function | Subscribes to analytics event updates and returns an unsubscribe function. |
284
- | `connectReduxStore(store)` | function | Connects a Redux store for live state and action inspection. |
285
- | `inspectorReduxMiddleware` | middleware | Redux middleware to capture actions dispatched from thunks/sagas. |
286
- | `getReduxState()` | function | Returns the latest captured Redux state. |
287
- | `subscribeReduxState(callback)` | function | Subscribes to Redux state updates and returns an unsubscribe function. |
288
- | `getActionHistory()` | function | Returns the recent dispatched Redux actions. |
289
- | `clearActionHistory()` | function | Clears the Redux action history. |
290
- | `ErrorBoundary` | component | React error boundary component. |
290
+ ## 📚 Public API Reference
291
+
292
+ | Export | Type | Description |
293
+ | --- | --- | --- |
294
+ | `NetworkInspector` | Component | Floating inspector overlay. Mount near app root. |
295
+ | `setupNetworkLogger()` | Function | Patches `fetch`, default Axios, and future `axios.create()` instances. |
296
+ | `addAxiosInterceptors(instance)` | Function | Manually attaches Axios interceptors to an existing instance. |
297
+ | `clearNetworkLogs()` | Function | Clears captured network requests. |
298
+ | `subscribeNetworkLogs(cb)` | Function | Subscribes to network log updates. |
299
+ | `setupConsoleLogger()` | Function | Intercepts `console.log`, `info`, `warn`, and `error`. |
300
+ | `clearConsoleLogs()` | Function | Clears captured console logs. |
301
+ | `subscribeConsoleLogs(cb)` | Function | Subscribes to console log updates. |
302
+ | `connectReduxStore(store)` | Function | Connects a Redux store for state and action inspection. |
303
+ | `inspectorReduxMiddleware` | Middleware | Redux middleware for capturing thunks, sagas, and RTK Query actions. |
304
+ | `getReduxState()` | Function | Returns the current captured Redux state snapshot. |
305
+ | `subscribeReduxState(cb)` | Function | Subscribes to Redux state changes. |
306
+ | `getActionHistory()` | Function | Returns the history of dispatched Redux actions. |
307
+ | `clearActionHistory()` | Function | Clears Redux action history. |
308
+ | `setupAnalyticsLogger(instance)` | Function | Patches a Firebase Analytics instance. |
309
+ | `logAnalyticsEvent(name, params?, userProps?)` | Function | Logs a manual analytics event. |
310
+ | `clearAnalyticsEvents()` | Function | Clears captured analytics events. |
311
+ | `subscribeAnalyticsEvents(cb)` | Function | Subscribes to analytics event updates. |
312
+ | `ErrorBoundary` | Component | React error boundary component. |
291
313
 
292
314
  ---
293
315
 
294
- ## Example App
316
+ ## 📱 Example App
295
317
 
296
- The `example` directory contains a React Native sample app and video walkthrough.
318
+ Check out the `example` directory for a complete demo application:
297
319
 
298
320
  ```bash
299
321
  cd example
@@ -304,17 +326,15 @@ npm run ios
304
326
 
305
327
  ---
306
328
 
307
- ## Contributing 🤝
329
+ ## 🤝 Contributing
308
330
 
309
- Contributions are welcome! Please check out our [Contributing Guidelines](CONTRIBUTING.md) to learn how to get started, set up the development environment, or request features.
331
+ Contributions are welcome! Please check out our [Contributing Guidelines](CONTRIBUTING.md) to get started.
310
332
 
311
333
  ---
312
334
 
313
- ## Support & Sponsoring 💖
314
-
315
- This library is a completely free, open-source utility maintained in the author's spare time. If this tool has saved you or your team hours of debugging, please consider supporting its continuous development.
335
+ ## 💖 Support & Sponsoring
316
336
 
317
- Sponsoring helps prioritize your bug fixes, maintain compatibility with new React Native versions, and support new features.
337
+ This library is a free, open-source utility maintained in spare time. If it saved you or your team time debugging, please consider supporting its continuous development.
318
338
 
319
339
  👉 **[Sponsor @vengatmacuser on GitHub Sponsors](https://github.com/sponsors/vengatmacuser)**
320
340
 
@@ -322,6 +342,6 @@ Sponsoring helps prioritize your bug fixes, maintain compatibility with new Reac
322
342
 
323
343
  ---
324
344
 
325
- ## License
345
+ ## 📄 License
326
346
 
327
- MIT - see the [LICENSE](LICENSE) file for details.
347
+ MIT © [vengatmacuser](LICENSE)
@@ -36,6 +36,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
36
36
  const react_1 = __importStar(require("react"));
37
37
  const react_native_1 = require("react-native");
38
38
  const AnimatedEntrance = react_1.default.memo(function AnimatedEntrance({ children, delay = 0, distance = 10, duration = 220, index = 0, style, }) {
39
+ if (react_native_1.Platform.OS === 'android') {
40
+ return <react_native_1.View style={style}>{children}</react_native_1.View>;
41
+ }
39
42
  const progress = (0, react_1.useRef)(new react_native_1.Animated.Value(0)).current;
40
43
  (0, react_1.useEffect)(() => {
41
44
  progress.setValue(0);
@@ -0,0 +1,8 @@
1
+ import React from 'react';
2
+ import { ImageSourcePropType } from 'react-native';
3
+ interface AppHeaderLogoProps {
4
+ size?: number;
5
+ customIcon?: ImageSourcePropType | null;
6
+ }
7
+ export declare const AppHeaderLogo: React.FC<AppHeaderLogoProps>;
8
+ export default AppHeaderLogo;
@@ -0,0 +1,85 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.AppHeaderLogo = void 0;
40
+ const react_1 = __importStar(require("react"));
41
+ const react_native_1 = require("react-native");
42
+ const BrandSquareIcon_1 = __importDefault(require("./BrandSquareIcon"));
43
+ const AppColors_1 = require("../styles/AppColors");
44
+ const AppHeaderLogo = ({ size = 46, customIcon, }) => {
45
+ const [loadError, setLoadError] = (0, react_1.useState)(false);
46
+ // 1. If customIcon is explicitly provided, render it directly
47
+ if (customIcon) {
48
+ return (<react_native_1.View style={[logoStyles.container, { width: size, height: size }]}>
49
+ <react_native_1.Image source={customIcon} style={{ width: size - 4, height: size - 4, borderRadius: 10 }} resizeMode="cover"/>
50
+ </react_native_1.View>);
51
+ }
52
+ // 2. Dynamically query installed native app icon (AppIcon on iOS, ic_launcher on Android)
53
+ if (!loadError && react_native_1.Platform.OS !== 'web') {
54
+ const nativeSource = react_native_1.Platform.select({
55
+ ios: { uri: 'AppIcon' },
56
+ android: { uri: 'ic_launcher' },
57
+ default: { uri: 'AppIcon' },
58
+ });
59
+ return (<react_native_1.View style={[logoStyles.container, { width: size, height: size }]}>
60
+ <react_native_1.Image source={nativeSource} style={{ width: size - 4, height: size - 4, borderRadius: 10 }} resizeMode="cover" onError={() => setLoadError(true)}/>
61
+ </react_native_1.View>);
62
+ }
63
+ // 3. Fallback: Inspector's Signature Owl Brand Logo
64
+ return (<react_native_1.View style={[logoStyles.container, { width: size, height: size }]}>
65
+ <BrandSquareIcon_1.default size={size - 4}/>
66
+ </react_native_1.View>);
67
+ };
68
+ exports.AppHeaderLogo = AppHeaderLogo;
69
+ const logoStyles = react_native_1.StyleSheet.create({
70
+ container: {
71
+ alignItems: 'center',
72
+ justifyContent: 'center',
73
+ borderRadius: 12,
74
+ backgroundColor: `${AppColors_1.AppColors.white}24`,
75
+ borderWidth: 1.5,
76
+ borderColor: `${AppColors_1.AppColors.white}4D`,
77
+ overflow: 'hidden',
78
+ shadowColor: AppColors_1.AppColors.primaryBlack,
79
+ shadowOffset: { width: 0, height: 2 },
80
+ shadowOpacity: 0.15,
81
+ shadowRadius: 4,
82
+ elevation: 3,
83
+ },
84
+ });
85
+ exports.default = exports.AppHeaderLogo;
@@ -1,4 +1,4 @@
1
1
  import React from 'react';
2
2
  import { CopyButtonProps } from '../types';
3
- declare const CopyButton: ({ value, label, iconType }: CopyButtonProps) => React.JSX.Element;
3
+ declare const CopyButton: React.MemoExoticComponent<({ value, label, iconType }: CopyButtonProps) => React.JSX.Element>;
4
4
  export default CopyButton;
@@ -46,14 +46,14 @@ const NetworkIcons_1 = require("./NetworkIcons");
46
46
  // Stylesheet
47
47
  const AppColors_1 = require("../styles/AppColors");
48
48
  const styles_1 = __importDefault(require("../styles"));
49
- const CopyButton = ({ value, label, iconType = 'copy' }) => {
49
+ const CopyButton = react_1.default.memo(({ value, label, iconType = 'copy' }) => {
50
50
  const [copied, setCopied] = (0, react_1.useState)(false);
51
- const handlePress = () => {
51
+ const handlePress = (0, react_1.useCallback)(() => {
52
52
  const resolvedValue = typeof value === 'function' ? value() : value;
53
53
  (0, helpers_1.copyToClipboard)(resolvedValue, label);
54
54
  setCopied(true);
55
55
  setTimeout(() => setCopied(false), 1200);
56
- };
56
+ }, [value, label]);
57
57
  const containerStyle = [
58
58
  styles_1.default.iconSquareBtn,
59
59
  copied && styles_1.default.iconSquareBtnSuccess,
@@ -66,5 +66,5 @@ const CopyButton = ({ value, label, iconType = 'copy' }) => {
66
66
  return (<TouchableScale_1.default onPress={handlePress} hitSlop={12} style={containerStyle}>
67
67
  {copied ? (<NetworkIcons_1.CheckIcon color={AppColors_1.AppColors.greenColor} size={14}/>) : (<IconComponent color={AppColors_1.AppColors.grayTextWeak} size={14}/>)}
68
68
  </TouchableScale_1.default>);
69
- };
69
+ });
70
70
  exports.default = CopyButton;
@@ -9,7 +9,7 @@ const react_native_1 = require("react-native");
9
9
  const AppColors_1 = require("../styles/AppColors");
10
10
  const AppFonts_1 = require("../styles/AppFonts");
11
11
  const NetworkIcons_1 = require("./NetworkIcons");
12
- const EndOfListFooter = ({ count, label, message = "You've reached the end of the list", }) => {
12
+ exports.EndOfListFooter = react_1.default.memo(({ count, label, message = "You've reached the end of the list", }) => {
13
13
  return (<react_native_1.View style={styles.container}>
14
14
  <react_native_1.View style={styles.dividerLine}/>
15
15
  <react_native_1.View style={styles.badgePill}>
@@ -25,8 +25,7 @@ const EndOfListFooter = ({ count, label, message = "You've reached the end of th
25
25
  </react_native_1.View>
26
26
  <react_native_1.View style={styles.dividerLine}/>
27
27
  </react_native_1.View>);
28
- };
29
- exports.EndOfListFooter = EndOfListFooter;
28
+ });
30
29
  const styles = react_native_1.StyleSheet.create({
31
30
  container: {
32
31
  flexDirection: 'row',
@@ -1,3 +1,3 @@
1
1
  import React from 'react';
2
- declare const AnalyticsTab: () => React.JSX.Element;
2
+ declare const AnalyticsTab: React.MemoExoticComponent<() => React.JSX.Element>;
3
3
  export default AnalyticsTab;