react-native-inapp-inspector 1.1.15 β 1.1.16
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.
- package/README.md +137 -130
- package/dist/commonjs/components/CopyButton.d.ts +1 -1
- package/dist/commonjs/components/CopyButton.js +4 -4
- package/dist/commonjs/components/EndOfListFooter.js +2 -3
- package/dist/commonjs/components/Inspector/AnalyticsTab.d.ts +1 -1
- package/dist/commonjs/components/Inspector/AnalyticsTab.js +7 -8
- package/dist/commonjs/components/Inspector/ConsoleTab.d.ts +1 -1
- package/dist/commonjs/components/Inspector/ConsoleTab.js +9 -9
- package/dist/commonjs/components/Inspector/InspectorHeader.d.ts +1 -1
- package/dist/commonjs/components/Inspector/InspectorHeader.js +2 -2
- package/dist/commonjs/components/Inspector/LogDetail.d.ts +1 -1
- package/dist/commonjs/components/Inspector/LogDetail.js +2 -2
- package/dist/commonjs/components/Inspector/NetworkDetail.d.ts +1 -1
- package/dist/commonjs/components/Inspector/NetworkDetail.js +2 -2
- package/dist/commonjs/components/Inspector/NetworkTab.d.ts +1 -1
- package/dist/commonjs/components/Inspector/NetworkTab.js +10 -9
- package/dist/commonjs/components/Inspector/ReduxTab.d.ts +1 -1
- package/dist/commonjs/components/Inspector/ReduxTab.js +2 -2
- package/dist/commonjs/components/Inspector/TabBar.d.ts +1 -1
- package/dist/commonjs/components/Inspector/TabBar.js +2 -2
- package/dist/commonjs/components/JsonViewer.d.ts +2 -2
- package/dist/commonjs/components/JsonViewer.js +2 -2
- package/dist/commonjs/components/ReduxTreeView.d.ts +2 -2
- package/dist/commonjs/components/ReduxTreeView.js +2 -3
- package/dist/commonjs/components/SegmentedTabs.d.ts +1 -1
- package/dist/commonjs/components/SegmentedTabs.js +2 -2
- package/dist/commonjs/constants/version.d.ts +1 -1
- package/dist/commonjs/constants/version.js +1 -1
- package/dist/esm/components/CopyButton.d.ts +1 -1
- package/dist/esm/components/CopyButton.js +5 -5
- package/dist/esm/components/EndOfListFooter.js +2 -2
- package/dist/esm/components/Inspector/AnalyticsTab.d.ts +1 -1
- package/dist/esm/components/Inspector/AnalyticsTab.js +7 -8
- package/dist/esm/components/Inspector/ConsoleTab.d.ts +1 -1
- package/dist/esm/components/Inspector/ConsoleTab.js +9 -9
- package/dist/esm/components/Inspector/InspectorHeader.d.ts +1 -1
- package/dist/esm/components/Inspector/InspectorHeader.js +2 -2
- package/dist/esm/components/Inspector/LogDetail.d.ts +1 -1
- package/dist/esm/components/Inspector/LogDetail.js +2 -2
- package/dist/esm/components/Inspector/NetworkDetail.d.ts +1 -1
- package/dist/esm/components/Inspector/NetworkDetail.js +2 -2
- package/dist/esm/components/Inspector/NetworkTab.d.ts +1 -1
- package/dist/esm/components/Inspector/NetworkTab.js +10 -9
- package/dist/esm/components/Inspector/ReduxTab.d.ts +1 -1
- package/dist/esm/components/Inspector/ReduxTab.js +2 -2
- package/dist/esm/components/Inspector/TabBar.d.ts +1 -1
- package/dist/esm/components/Inspector/TabBar.js +2 -2
- package/dist/esm/components/JsonViewer.d.ts +2 -2
- package/dist/esm/components/JsonViewer.js +2 -2
- package/dist/esm/components/ReduxTreeView.d.ts +2 -2
- package/dist/esm/components/ReduxTreeView.js +2 -2
- package/dist/esm/components/SegmentedTabs.d.ts +1 -1
- package/dist/esm/components/SegmentedTabs.js +2 -2
- package/dist/esm/constants/version.d.ts +1 -1
- package/dist/esm/constants/version.js +1 -1
- package/example/App.tsx +57 -1
- package/example/README.md +33 -77
- package/package.json +1 -1
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
|
|
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,27 @@ 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
|
|
28
|
-
|
|
|
29
|
-
| Network
|
|
30
|
-
| Console
|
|
31
|
-
|
|
|
32
|
-
|
|
|
33
|
-
|
|
|
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
|
+
| πͺ **Rich JSON Viewer** | Explore data in **Pretty**, **Raw**, and **Table** modes with full-text search highlighting and uniform typography. |
|
|
35
|
+
| π‘οΈ **Error Boundary** | Built-in `ErrorBoundary` to gracefully catch and inspect React render crashes. |
|
|
34
36
|
|
|
35
37
|
---
|
|
36
38
|
|
|
37
|
-
## Video Walkthrough
|
|
39
|
+
## π¬ Video Walkthrough
|
|
38
40
|
|
|
39
41
|
[Download or watch the Video Walkthrough](https://raw.githubusercontent.com/vengatmacuser/react-native-inapp-inspector/main/example/guidance/Video-WalkThrough.mp4)
|
|
40
42
|
|
|
41
43
|
---
|
|
42
44
|
|
|
43
|
-
## Installation
|
|
45
|
+
## π¦ Installation
|
|
44
46
|
|
|
45
47
|
```bash
|
|
46
48
|
npm install --save-dev react-native-inapp-inspector axios
|
|
@@ -50,25 +52,22 @@ npm install --save-dev react-native-inapp-inspector axios
|
|
|
50
52
|
yarn add -D react-native-inapp-inspector axios
|
|
51
53
|
```
|
|
52
54
|
|
|
53
|
-
|
|
55
|
+
### Peer & Native Dependencies
|
|
54
56
|
|
|
55
|
-
|
|
57
|
+
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
58
|
|
|
57
|
-
|
|
58
|
-
npm install @react-native-firebase/analytics
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
For iOS, install pods after adding native dependencies:
|
|
59
|
+
*(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
60
|
|
|
63
61
|
```bash
|
|
62
|
+
# iOS Pods installation
|
|
64
63
|
cd ios && pod install
|
|
65
64
|
```
|
|
66
65
|
|
|
67
66
|
---
|
|
68
67
|
|
|
69
|
-
## Basic Setup
|
|
68
|
+
## π Basic Setup
|
|
70
69
|
|
|
71
|
-
Mount
|
|
70
|
+
Mount `<NetworkInspector />` near the root of your application:
|
|
72
71
|
|
|
73
72
|
```tsx
|
|
74
73
|
import React from 'react';
|
|
@@ -78,7 +77,7 @@ import NetworkInspector from 'react-native-inapp-inspector';
|
|
|
78
77
|
const App = () => {
|
|
79
78
|
return (
|
|
80
79
|
<SafeAreaView style={{flex: 1}}>
|
|
81
|
-
{/* Your
|
|
80
|
+
{/* Your application components */}
|
|
82
81
|
<NetworkInspector />
|
|
83
82
|
</SafeAreaView>
|
|
84
83
|
);
|
|
@@ -87,77 +86,59 @@ const App = () => {
|
|
|
87
86
|
export default App;
|
|
88
87
|
```
|
|
89
88
|
|
|
90
|
-
When mounted, the inspector sets up network logging,
|
|
89
|
+
When mounted, the inspector automatically sets up network logging, intercepts console methods, and attaches Firebase Analytics if available.
|
|
91
90
|
|
|
92
|
-
|
|
91
|
+
### Early Startup Network Logging
|
|
92
|
+
|
|
93
|
+
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
94
|
|
|
94
95
|
```tsx
|
|
95
96
|
import NetworkInspector, {
|
|
96
97
|
setupNetworkLogger,
|
|
98
|
+
setupConsoleLogger,
|
|
97
99
|
} from 'react-native-inapp-inspector';
|
|
98
100
|
|
|
99
101
|
setupNetworkLogger();
|
|
102
|
+
setupConsoleLogger();
|
|
100
103
|
```
|
|
101
104
|
|
|
102
|
-
|
|
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
|
|
105
|
+
### Toggling Visibility
|
|
117
106
|
|
|
118
|
-
|
|
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:
|
|
107
|
+
You can disable or hide the floating launcher overlay conditionally:
|
|
121
108
|
|
|
122
109
|
```tsx
|
|
123
|
-
|
|
110
|
+
// Fully disable the overlay and interception
|
|
111
|
+
<NetworkInspector enabled={__DEV__} />
|
|
124
112
|
|
|
125
|
-
|
|
113
|
+
// Hide the floating trigger button while keeping background interception active
|
|
114
|
+
<NetworkInspector isEnabled={false} />
|
|
126
115
|
```
|
|
127
116
|
|
|
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
117
|
---
|
|
131
118
|
|
|
132
|
-
##
|
|
119
|
+
## πͺ΅ Console Logger & Stack Trace
|
|
133
120
|
|
|
134
|
-
|
|
121
|
+
The console logger provides deep insight into every `console.log`, `info`, `warn`, and `error` call:
|
|
135
122
|
|
|
136
|
-
|
|
123
|
+
- **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`).
|
|
124
|
+
- **File Type Badges**: Distinct visual chips identifying `.tsx`, `.jsx`, `.ts`, and `.js` callers.
|
|
125
|
+
- **Detailed Sub-Tabs**:
|
|
126
|
+
- **Output / Message**: Full message with JSON Viewer (Pretty, Raw, Table modes) and link detection.
|
|
127
|
+
- **Args (N)**: Inspect each passed argument individually with type detection (`Array[5]`, `Object{4}`).
|
|
128
|
+
- **Call Stack Trace**: Structured frame cards (with Frame `#`, Function, File, and `L:C` pills) and Raw Trace view.
|
|
129
|
+
- **Error Stack**: Automatically captures the thrown Error stack trace when logging Error objects.
|
|
130
|
+
- **Metadata**: Structured table of log properties, timestamp, character count, and duplicate counter.
|
|
137
131
|
|
|
138
132
|
```tsx
|
|
139
|
-
|
|
140
|
-
|
|
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
|
-
};
|
|
133
|
+
console.log('[API] User authenticated successfully', {userId: 42, role: 'admin'});
|
|
134
|
+
console.error(new Error('Payment gateway timeout'));
|
|
154
135
|
```
|
|
155
136
|
|
|
156
137
|
---
|
|
157
138
|
|
|
158
|
-
## Network Logging
|
|
139
|
+
## π Network Logging
|
|
159
140
|
|
|
160
|
-
`setupNetworkLogger()`
|
|
141
|
+
`setupNetworkLogger()` intercepts global `fetch`, the default Axios instance, and instances created with `axios.create()`.
|
|
161
142
|
|
|
162
143
|
```tsx
|
|
163
144
|
import axios from 'axios';
|
|
@@ -171,7 +152,7 @@ await fetch('https://api.example.com/users');
|
|
|
171
152
|
await api.post('/login', {email, password});
|
|
172
153
|
```
|
|
173
154
|
|
|
174
|
-
If an
|
|
155
|
+
If an Axios instance was instantiated before `setupNetworkLogger()` ran, attach interceptors manually:
|
|
175
156
|
|
|
176
157
|
```tsx
|
|
177
158
|
import {addAxiosInterceptors} from 'react-native-inapp-inspector';
|
|
@@ -179,27 +160,46 @@ import {addAxiosInterceptors} from 'react-native-inapp-inspector';
|
|
|
179
160
|
addAxiosInterceptors(api);
|
|
180
161
|
```
|
|
181
162
|
|
|
182
|
-
Network logs are capped at 100 entries and ignore React Native symbolication requests.
|
|
183
|
-
|
|
184
163
|
---
|
|
185
164
|
|
|
186
|
-
##
|
|
165
|
+
## π Redux State & Action Inspection
|
|
187
166
|
|
|
188
|
-
|
|
167
|
+
Connect your Redux store once during application startup:
|
|
189
168
|
|
|
190
169
|
```tsx
|
|
191
|
-
import {
|
|
170
|
+
import {connectReduxStore} from 'react-native-inapp-inspector';
|
|
171
|
+
import store from './store';
|
|
192
172
|
|
|
193
|
-
|
|
173
|
+
connectReduxStore(store);
|
|
194
174
|
```
|
|
195
175
|
|
|
196
|
-
|
|
176
|
+
### RTK Query, Thunks & Sagas (Recommended)
|
|
177
|
+
|
|
178
|
+
To capture actions dispatched from inside async thunks, sagas, or RTK Query, add `inspectorReduxMiddleware`:
|
|
179
|
+
|
|
180
|
+
```tsx
|
|
181
|
+
import {configureStore} from '@reduxjs/toolkit';
|
|
182
|
+
import {inspectorReduxMiddleware, connectReduxStore} from 'react-native-inapp-inspector';
|
|
183
|
+
import rootReducer from './slices';
|
|
184
|
+
|
|
185
|
+
const store = configureStore({
|
|
186
|
+
reducer: rootReducer,
|
|
187
|
+
middleware: getDefaultMiddleware =>
|
|
188
|
+
getDefaultMiddleware().concat(inspectorReduxMiddleware),
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
connectReduxStore(store);
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
The Redux tab provides:
|
|
195
|
+
- **Action History**: Action type badge, timestamp, payload size, affected slices, deep state diffs, and snapshot viewer.
|
|
196
|
+
- **Slice Tree**: Live state tree per slice, persisted slice detection (`_persist`), search filtering, and JSON table exploration.
|
|
197
197
|
|
|
198
198
|
---
|
|
199
199
|
|
|
200
|
-
## Analytics Logging
|
|
200
|
+
## π Analytics Logging
|
|
201
201
|
|
|
202
|
-
|
|
202
|
+
Log manual analytics events or connect Firebase Analytics:
|
|
203
203
|
|
|
204
204
|
```tsx
|
|
205
205
|
import {logAnalyticsEvent} from 'react-native-inapp-inspector';
|
|
@@ -211,7 +211,7 @@ logAnalyticsEvent('purchase_completed', {
|
|
|
211
211
|
});
|
|
212
212
|
```
|
|
213
213
|
|
|
214
|
-
|
|
214
|
+
### Firebase Analytics Integration
|
|
215
215
|
|
|
216
216
|
```tsx
|
|
217
217
|
import analytics from '@react-native-firebase/analytics';
|
|
@@ -220,80 +220,89 @@ import {setupAnalyticsLogger} from 'react-native-inapp-inspector';
|
|
|
220
220
|
setupAnalyticsLogger(analytics());
|
|
221
221
|
```
|
|
222
222
|
|
|
223
|
-
The logger patches `logEvent`, `logScreenView`, `setUserProperty`, `setUserProperties`, and `setUserId`. Analytics events are capped at 200 entries.
|
|
224
|
-
|
|
225
223
|
---
|
|
226
224
|
|
|
227
|
-
##
|
|
225
|
+
## π§ Navigation & Screen Tracking
|
|
228
226
|
|
|
229
|
-
|
|
227
|
+
To group network requests, logs, and analytics by the active screen, pass your navigation container ref:
|
|
230
228
|
|
|
231
229
|
```tsx
|
|
232
|
-
import {
|
|
233
|
-
import
|
|
230
|
+
import {NavigationContainer, createNavigationContainerRef} from '@react-navigation/native';
|
|
231
|
+
import NetworkInspector from 'react-native-inapp-inspector';
|
|
234
232
|
|
|
235
|
-
|
|
233
|
+
const navigationRef = createNavigationContainerRef();
|
|
234
|
+
|
|
235
|
+
const App = () => {
|
|
236
|
+
return (
|
|
237
|
+
<>
|
|
238
|
+
<NavigationContainer ref={navigationRef}>
|
|
239
|
+
{/* Your screens */}
|
|
240
|
+
</NavigationContainer>
|
|
241
|
+
<NetworkInspector navigationRef={navigationRef} />
|
|
242
|
+
</>
|
|
243
|
+
);
|
|
244
|
+
};
|
|
236
245
|
```
|
|
237
246
|
|
|
238
|
-
|
|
247
|
+
---
|
|
239
248
|
|
|
240
|
-
|
|
241
|
-
import {inspectorReduxMiddleware} from 'react-native-inapp-inspector';
|
|
249
|
+
## βοΈ Settings Persistence
|
|
242
250
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
getDefaultMiddleware().concat(inspectorReduxMiddleware),
|
|
247
|
-
});
|
|
248
|
-
```
|
|
251
|
+
Inspector preferences (dark mode, active modules, default landing tab) persist across app launches:
|
|
252
|
+
- **iOS**: Uses React Native's built-in `Settings` module (`NSUserDefaults`) with zero extra configuration.
|
|
253
|
+
- **Android / Custom Storage**: Pass `@react-native-async-storage/async-storage` or `react-native-mmkv` to the `storage` prop:
|
|
249
254
|
|
|
250
|
-
|
|
255
|
+
```tsx
|
|
256
|
+
import AsyncStorage from '@react-native-async-storage/async-storage';
|
|
251
257
|
|
|
252
|
-
|
|
258
|
+
<NetworkInspector storage={AsyncStorage} />
|
|
259
|
+
```
|
|
253
260
|
|
|
254
261
|
---
|
|
255
262
|
|
|
256
|
-
## Error Boundary
|
|
263
|
+
## π‘οΈ Error Boundary
|
|
264
|
+
|
|
265
|
+
Catch and inspect unhandled React component render crashes:
|
|
257
266
|
|
|
258
267
|
```tsx
|
|
259
268
|
import {ErrorBoundary} from 'react-native-inapp-inspector';
|
|
260
269
|
|
|
261
270
|
<ErrorBoundary>
|
|
262
|
-
<
|
|
263
|
-
</ErrorBoundary
|
|
271
|
+
<YourApp />
|
|
272
|
+
</ErrorBoundary>
|
|
264
273
|
```
|
|
265
274
|
|
|
266
275
|
---
|
|
267
276
|
|
|
268
|
-
## Public API
|
|
269
|
-
|
|
270
|
-
| Export
|
|
271
|
-
|
|
|
272
|
-
| `NetworkInspector`
|
|
273
|
-
| `setupNetworkLogger()`
|
|
274
|
-
| `addAxiosInterceptors(instance)`
|
|
275
|
-
| `clearNetworkLogs()`
|
|
276
|
-
| `subscribeNetworkLogs(
|
|
277
|
-
| `setupConsoleLogger()`
|
|
278
|
-
| `clearConsoleLogs()`
|
|
279
|
-
| `subscribeConsoleLogs(
|
|
280
|
-
| `
|
|
281
|
-
| `
|
|
282
|
-
| `
|
|
283
|
-
| `
|
|
284
|
-
| `
|
|
285
|
-
| `
|
|
286
|
-
| `
|
|
287
|
-
| `
|
|
288
|
-
| `
|
|
289
|
-
| `
|
|
290
|
-
| `ErrorBoundary`
|
|
277
|
+
## π Public API Reference
|
|
278
|
+
|
|
279
|
+
| Export | Type | Description |
|
|
280
|
+
| --- | --- | --- |
|
|
281
|
+
| `NetworkInspector` | Component | Floating inspector overlay. Mount near app root. |
|
|
282
|
+
| `setupNetworkLogger()` | Function | Patches `fetch`, default Axios, and future `axios.create()` instances. |
|
|
283
|
+
| `addAxiosInterceptors(instance)` | Function | Manually attaches Axios interceptors to an existing instance. |
|
|
284
|
+
| `clearNetworkLogs()` | Function | Clears captured network requests. |
|
|
285
|
+
| `subscribeNetworkLogs(cb)` | Function | Subscribes to network log updates. |
|
|
286
|
+
| `setupConsoleLogger()` | Function | Intercepts `console.log`, `info`, `warn`, and `error`. |
|
|
287
|
+
| `clearConsoleLogs()` | Function | Clears captured console logs. |
|
|
288
|
+
| `subscribeConsoleLogs(cb)` | Function | Subscribes to console log updates. |
|
|
289
|
+
| `connectReduxStore(store)` | Function | Connects a Redux store for state and action inspection. |
|
|
290
|
+
| `inspectorReduxMiddleware` | Middleware | Redux middleware for capturing thunks, sagas, and RTK Query actions. |
|
|
291
|
+
| `getReduxState()` | Function | Returns the current captured Redux state snapshot. |
|
|
292
|
+
| `subscribeReduxState(cb)` | Function | Subscribes to Redux state changes. |
|
|
293
|
+
| `getActionHistory()` | Function | Returns the history of dispatched Redux actions. |
|
|
294
|
+
| `clearActionHistory()` | Function | Clears Redux action history. |
|
|
295
|
+
| `setupAnalyticsLogger(instance)` | Function | Patches a Firebase Analytics instance. |
|
|
296
|
+
| `logAnalyticsEvent(name, params?, userProps?)` | Function | Logs a manual analytics event. |
|
|
297
|
+
| `clearAnalyticsEvents()` | Function | Clears captured analytics events. |
|
|
298
|
+
| `subscribeAnalyticsEvents(cb)` | Function | Subscribes to analytics event updates. |
|
|
299
|
+
| `ErrorBoundary` | Component | React error boundary component. |
|
|
291
300
|
|
|
292
301
|
---
|
|
293
302
|
|
|
294
|
-
## Example App
|
|
303
|
+
## π± Example App
|
|
295
304
|
|
|
296
|
-
|
|
305
|
+
Check out the `example` directory for a complete demo application:
|
|
297
306
|
|
|
298
307
|
```bash
|
|
299
308
|
cd example
|
|
@@ -304,17 +313,15 @@ npm run ios
|
|
|
304
313
|
|
|
305
314
|
---
|
|
306
315
|
|
|
307
|
-
## Contributing
|
|
316
|
+
## π€ Contributing
|
|
308
317
|
|
|
309
|
-
Contributions are welcome! Please check out our [Contributing Guidelines](CONTRIBUTING.md) to
|
|
318
|
+
Contributions are welcome! Please check out our [Contributing Guidelines](CONTRIBUTING.md) to get started.
|
|
310
319
|
|
|
311
320
|
---
|
|
312
321
|
|
|
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.
|
|
322
|
+
## π Support & Sponsoring
|
|
316
323
|
|
|
317
|
-
|
|
324
|
+
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
325
|
|
|
319
326
|
π **[Sponsor @vengatmacuser on GitHub Sponsors](https://github.com/sponsors/vengatmacuser)**
|
|
320
327
|
|
|
@@ -322,6 +329,6 @@ Sponsoring helps prioritize your bug fixes, maintain compatibility with new Reac
|
|
|
322
329
|
|
|
323
330
|
---
|
|
324
331
|
|
|
325
|
-
## License
|
|
332
|
+
## π License
|
|
326
333
|
|
|
327
|
-
MIT
|
|
334
|
+
MIT Β© [vengatmacuser](LICENSE)
|
|
@@ -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
|
-
|
|
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',
|
|
@@ -46,9 +46,8 @@ const styles_1 = __importDefault(require("../../styles"));
|
|
|
46
46
|
const AppColors_1 = require("../../styles/AppColors");
|
|
47
47
|
const analyticsLogger_1 = require("../../customHooks/analyticsLogger");
|
|
48
48
|
const NetworkIcons_1 = require("../NetworkIcons");
|
|
49
|
-
const AnalyticsHeader = () => {
|
|
49
|
+
const AnalyticsHeader = react_1.default.memo(() => {
|
|
50
50
|
const { filteredAnalyticsEvents, analyticsHeaderExpanded, setAnalyticsHeaderExpanded, } = (0, InspectorContext_1.useInspector)();
|
|
51
|
-
const keyExtractor = (0, react_1.useCallback)((item, index) => item?.id?.toString() ?? index.toString(), []);
|
|
52
51
|
const userId = (0, analyticsLogger_1.getCurrentUserId)();
|
|
53
52
|
const userProperties = (0, analyticsLogger_1.getCurrentUserProperties)();
|
|
54
53
|
const defaultParams = (0, analyticsLogger_1.getDefaultEventParameters)();
|
|
@@ -125,9 +124,10 @@ const AnalyticsHeader = () => {
|
|
|
125
124
|
</react_native_1.View>)}
|
|
126
125
|
</>)}
|
|
127
126
|
</react_native_1.View>);
|
|
128
|
-
};
|
|
129
|
-
const AnalyticsTab = () => {
|
|
130
|
-
const { analyticsSearch, setAnalyticsSearch, handleDelete,
|
|
127
|
+
});
|
|
128
|
+
const AnalyticsTab = react_1.default.memo(() => {
|
|
129
|
+
const { filteredAnalyticsEvents, analyticsSearch, setAnalyticsSearch, handleDelete, selectedEvent, setSelectedEvent, newEventIds, logRouteMapRef, isAnalyticsLayoutReady, setIsAnalyticsLayoutReady, isAnalyticsPaused, setIsAnalyticsPaused, } = (0, InspectorContext_1.useInspector)();
|
|
130
|
+
const keyExtractor = (0, react_1.useCallback)((item, index) => item?.id?.toString() ?? index.toString(), []);
|
|
131
131
|
const renderItem = (0, react_1.useCallback)(({ item, index }) => {
|
|
132
132
|
const prev = filteredAnalyticsEvents[index + 1];
|
|
133
133
|
const next = filteredAnalyticsEvents[index - 1];
|
|
@@ -166,8 +166,7 @@ const AnalyticsTab = () => {
|
|
|
166
166
|
}
|
|
167
167
|
return screenName;
|
|
168
168
|
})()}/>);
|
|
169
|
-
}, [filteredAnalyticsEvents, analyticsSearch, newEventIds, setSelectedEvent]);
|
|
170
|
-
const keyExtractor = (0, react_1.useCallback)((item, index) => item?.id?.toString() ?? index.toString(), []);
|
|
169
|
+
}, [filteredAnalyticsEvents, analyticsSearch, newEventIds, setSelectedEvent, logRouteMapRef]);
|
|
171
170
|
return (<>
|
|
172
171
|
{/* βββ Search + Shared Toolbar for Analytics ββββββββββββββββββββββββ */}
|
|
173
172
|
{selectedEvent == null && (<react_native_1.View style={[
|
|
@@ -228,5 +227,5 @@ const AnalyticsTab = () => {
|
|
|
228
227
|
]} keyboardShouldPersistTaps="handled"/>) : null}
|
|
229
228
|
</react_native_1.View>
|
|
230
229
|
</>);
|
|
231
|
-
};
|
|
230
|
+
});
|
|
232
231
|
exports.default = AnalyticsTab;
|
|
@@ -49,14 +49,14 @@ const styles_1 = __importDefault(require("../../styles"));
|
|
|
49
49
|
const AppColors_1 = require("../../styles/AppColors");
|
|
50
50
|
const AppFonts_1 = require("../../styles/AppFonts");
|
|
51
51
|
const NetworkIcons_1 = require("../NetworkIcons");
|
|
52
|
-
const ConsoleTab = () => {
|
|
52
|
+
const ConsoleTab = react_1.default.memo(() => {
|
|
53
53
|
const { t } = (0, react_i18next_1.useTranslation)();
|
|
54
54
|
const { logSearch, setLogSearch, logSortOrder, setLogSortOrder, handleDelete, logFilters, setLogFilters, logCounts, filteredConsoleLogs, visibleConsoleLogs, isConsolePaused, setIsConsolePaused, } = (0, InspectorContext_1.useInspector)();
|
|
55
55
|
const renderItem = (0, react_1.useCallback)(({ item, index }) => (<AnimatedEntrance_1.default index={index} distance={8}>
|
|
56
56
|
<ConsoleLogCard_1.ConsoleLogCard item={item} searchStr={logSearch}/>
|
|
57
57
|
</AnimatedEntrance_1.default>), [logSearch]);
|
|
58
58
|
const keyExtractor = (0, react_1.useCallback)((item, index) => item?.id?.toString() ?? index.toString(), []);
|
|
59
|
-
const listHeader = (0, react_1.useMemo)(() =>
|
|
59
|
+
const listHeader = (0, react_1.useMemo)(() => {
|
|
60
60
|
const total = visibleConsoleLogs.length;
|
|
61
61
|
const filtered = filteredConsoleLogs.length;
|
|
62
62
|
const isAllSelected = logFilters.has('all') ||
|
|
@@ -66,8 +66,8 @@ const ConsoleTab = () => {
|
|
|
66
66
|
styles_1.default.resultCount,
|
|
67
67
|
{ marginBottom: 4, marginTop: 12 },
|
|
68
68
|
]}>
|
|
69
|
-
|
|
70
|
-
|
|
69
|
+
Showing ({filtered}/{total}) logs showing
|
|
70
|
+
</react_native_1.Text>);
|
|
71
71
|
}
|
|
72
72
|
else {
|
|
73
73
|
const activeFilterNames = Array.from(logFilters)
|
|
@@ -84,11 +84,11 @@ const ConsoleTab = () => {
|
|
|
84
84
|
styles_1.default.resultCount,
|
|
85
85
|
{ marginBottom: 4, marginTop: 12 },
|
|
86
86
|
]}>
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
87
|
+
Filtering with {activeFilterNames.join(', ')} (
|
|
88
|
+
{filtered}/{total}) logs is showing
|
|
89
|
+
</react_native_1.Text>);
|
|
90
90
|
}
|
|
91
|
-
}
|
|
91
|
+
}, [visibleConsoleLogs.length, filteredConsoleLogs.length, logFilters]);
|
|
92
92
|
return (<react_native_1.View style={{ flex: 1 }}>
|
|
93
93
|
<react_native_1.View style={{
|
|
94
94
|
backgroundColor: AppColors_1.AppColors.white,
|
|
@@ -406,5 +406,5 @@ const ConsoleTab = () => {
|
|
|
406
406
|
filteredConsoleLogs.length === 0 && { flexGrow: 1 },
|
|
407
407
|
]} keyboardShouldPersistTaps="handled"/>
|
|
408
408
|
</react_native_1.View>);
|
|
409
|
-
};
|
|
409
|
+
});
|
|
410
410
|
exports.default = ConsoleTab;
|
|
@@ -19,7 +19,7 @@ const helpers_2 = require("../../helpers");
|
|
|
19
19
|
const helpers_3 = require("../../helpers");
|
|
20
20
|
const helpers_4 = require("../../helpers");
|
|
21
21
|
const NetworkIcons_1 = require("../NetworkIcons");
|
|
22
|
-
const InspectorHeader = () => {
|
|
22
|
+
const InspectorHeader = react_1.default.memo(() => {
|
|
23
23
|
const { modalHeightPercent, selected, setSelected, selectedEvent, setSelectedEvent, selectedLog, setSelectedLog, showHeaderInfo, setShowHeaderInfo, updateAvailable, latestNpmVersion, clearAnim, activePulseAnim, unreadPulseAnim, runClearAllWithAnimation, setSettingsPage, closeModal, detailTitle, } = (0, InspectorContext_1.useInspector)();
|
|
24
24
|
const headerTopPadding = react_native_1.Platform.OS === 'ios' && modalHeightPercent >= 95 ? 44 : 0;
|
|
25
25
|
return (<react_native_linear_gradient_1.default colors={[AppColors_1.AppColors.purple, AppColors_1.AppColors.brandPurple]} style={styles_1.default.headerGradient}>
|
|
@@ -448,5 +448,5 @@ const InspectorHeader = () => {
|
|
|
448
448
|
</react_native_1.View>
|
|
449
449
|
</react_native_1.View>
|
|
450
450
|
</react_native_linear_gradient_1.default>);
|
|
451
|
-
};
|
|
451
|
+
});
|
|
452
452
|
exports.default = InspectorHeader;
|