react-native-inapp-inspector 1.1.0 → 1.1.2
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 +42 -40
- package/dist/commonjs/components/JsonViewer.d.ts +2 -1
- package/dist/commonjs/components/JsonViewer.js +6 -4
- package/dist/commonjs/components/MetaAccordion.js +26 -6
- package/dist/commonjs/components/ReduxTreeView.d.ts +4 -0
- package/dist/commonjs/components/ReduxTreeView.js +115 -10
- package/dist/commonjs/constants/index.d.ts +1 -0
- package/dist/commonjs/constants/index.js +5 -1
- package/dist/commonjs/constants/version.d.ts +1 -0
- package/dist/commonjs/constants/version.js +6 -0
- package/dist/commonjs/customHooks/reduxLogger.js +9 -1
- package/dist/commonjs/index.js +830 -181
- package/dist/commonjs/styles/index.d.ts +24 -0
- package/dist/commonjs/styles/index.js +22 -1
- package/dist/esm/components/JsonViewer.d.ts +2 -1
- package/dist/esm/components/JsonViewer.js +6 -4
- package/dist/esm/components/MetaAccordion.js +27 -7
- package/dist/esm/components/ReduxTreeView.d.ts +4 -0
- package/dist/esm/components/ReduxTreeView.js +111 -10
- package/dist/esm/constants/index.d.ts +1 -0
- package/dist/esm/constants/index.js +3 -0
- package/dist/esm/constants/version.d.ts +1 -0
- package/dist/esm/constants/version.js +3 -0
- package/dist/esm/customHooks/reduxLogger.js +9 -1
- package/dist/esm/index.js +834 -185
- package/dist/esm/styles/index.d.ts +24 -0
- package/dist/esm/styles/index.js +22 -1
- package/example/App.tsx +199 -61
- package/example/ios/example.xcodeproj/project.pbxproj +10 -0
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
<p align="center">
|
|
4
4
|
<picture>
|
|
5
|
-
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/vengatmacuser/react-native-inapp-inspector/main/assets/banner_dark.svg">
|
|
6
5
|
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/vengatmacuser/react-native-inapp-inspector/main/assets/banner_light.svg">
|
|
7
|
-
<
|
|
6
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/vengatmacuser/react-native-inapp-inspector/main/assets/banner_dark.svg">
|
|
7
|
+
<img alt="React Native In-App Inspector Banner" src="https://raw.githubusercontent.com/vengatmacuser/react-native-inapp-inspector/main/assets/banner_dark.svg" width="100%">
|
|
8
8
|
</picture>
|
|
9
9
|
</p>
|
|
10
10
|
|
|
@@ -20,15 +20,15 @@ A self-contained in-app debugging overlay for React Native. Inspect network traf
|
|
|
20
20
|
|
|
21
21
|
## Features
|
|
22
22
|
|
|
23
|
-
| Feature
|
|
24
|
-
|
|
25
|
-
| Network inspector
|
|
26
|
-
| Insights dashboard | Shows request totals, status breakdowns, latency, payload size, slow requests, and recent activity charts.
|
|
27
|
-
| Console logger
|
|
28
|
-
| Analytics tracker
|
|
29
|
-
| Redux inspector
|
|
30
|
-
| WebView inspector
|
|
31
|
-
| Error boundary
|
|
23
|
+
| Feature | Description |
|
|
24
|
+
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
25
|
+
| 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. |
|
|
26
|
+
| Insights dashboard | Shows request totals, status breakdowns, latency, payload size, slow requests, and recent activity charts. |
|
|
27
|
+
| Console logger | Captures `console.log`, `console.info`, `console.warn`, and `console.error` with source method and caller details. |
|
|
28
|
+
| Analytics tracker | Captures manual analytics events and patched `@react-native-firebase/analytics` calls including `logEvent`, `logScreenView`, user properties, and user id. |
|
|
29
|
+
| Redux inspector | Connects to a Redux store, displays the live state tree, tracks dispatched actions, affected slices, and action history. |
|
|
30
|
+
| WebView inspector | Provides an instrumented `WebView` with console capture, navigation history, HTML/CSS/JS snapshots, and optional loading overlay. |
|
|
31
|
+
| Error boundary | Exports an `ErrorBoundary` for catching React errors and wrapping the inspector safely. |
|
|
32
32
|
|
|
33
33
|
---
|
|
34
34
|
|
|
@@ -90,7 +90,9 @@ When mounted, the inspector sets up network logging, clears previous network log
|
|
|
90
90
|
If you need to capture requests that happen before the component mounts, call `setupNetworkLogger()` at module level in your app entry file.
|
|
91
91
|
|
|
92
92
|
```tsx
|
|
93
|
-
import NetworkInspector, {
|
|
93
|
+
import NetworkInspector, {
|
|
94
|
+
setupNetworkLogger,
|
|
95
|
+
} from 'react-native-inapp-inspector';
|
|
94
96
|
|
|
95
97
|
setupNetworkLogger();
|
|
96
98
|
```
|
|
@@ -214,40 +216,40 @@ import {ErrorBoundary} from 'react-native-inapp-inspector';
|
|
|
214
216
|
|
|
215
217
|
<ErrorBoundary>
|
|
216
218
|
<YourComponent />
|
|
217
|
-
</ErrorBoundary
|
|
219
|
+
</ErrorBoundary>;
|
|
218
220
|
```
|
|
219
221
|
|
|
220
222
|
---
|
|
221
223
|
|
|
222
224
|
## Public API
|
|
223
225
|
|
|
224
|
-
| Export
|
|
225
|
-
|
|
226
|
-
| `NetworkInspector`
|
|
227
|
-
| `setupNetworkLogger()`
|
|
228
|
-
| `addAxiosInterceptors(instance)`
|
|
229
|
-
| `clearNetworkLogs()`
|
|
230
|
-
| `subscribeNetworkLogs(callback)`
|
|
231
|
-
| `setupConsoleLogger()`
|
|
232
|
-
| `clearConsoleLogs()`
|
|
233
|
-
| `subscribeConsoleLogs(callback)`
|
|
234
|
-
| `setupAnalyticsLogger(instance)`
|
|
235
|
-
| `logAnalyticsEvent(name, params?, userProperties?)` | function
|
|
236
|
-
| `clearAnalyticsEvents()`
|
|
237
|
-
| `subscribeAnalyticsEvents(callback)`
|
|
238
|
-
| `connectReduxStore(store)`
|
|
239
|
-
| `getReduxState()`
|
|
240
|
-
| `subscribeReduxState(callback)`
|
|
241
|
-
| `WebView`
|
|
242
|
-
| `getWebViewLogs()`
|
|
243
|
-
| `getWebViewNavHistory()`
|
|
244
|
-
| `getWebViewHtml()`
|
|
245
|
-
| `getWebViewCss()`
|
|
246
|
-
| `getWebViewJs()`
|
|
247
|
-
| `getWebViewHtmlUrl()`
|
|
248
|
-
| `clearWebViewData()`
|
|
249
|
-
| `subscribeWebView(callback)`
|
|
250
|
-
| `ErrorBoundary`
|
|
226
|
+
| Export | Type | Description |
|
|
227
|
+
| --------------------------------------------------- | ----------------- | -------------------------------------------------------------------------- |
|
|
228
|
+
| `NetworkInspector` | default component | Floating inspector overlay. Mount once near the root of the app. |
|
|
229
|
+
| `setupNetworkLogger()` | function | Patches `fetch`, default axios, and future `axios.create()` instances. |
|
|
230
|
+
| `addAxiosInterceptors(instance)` | function | Manually attaches axios interceptors to an existing instance. |
|
|
231
|
+
| `clearNetworkLogs()` | function | Clears captured network logs. |
|
|
232
|
+
| `subscribeNetworkLogs(callback)` | function | Subscribes to network log updates and returns an unsubscribe function. |
|
|
233
|
+
| `setupConsoleLogger()` | function | Patches console methods. |
|
|
234
|
+
| `clearConsoleLogs()` | function | Clears captured console logs. |
|
|
235
|
+
| `subscribeConsoleLogs(callback)` | function | Subscribes to console log updates and returns an unsubscribe function. |
|
|
236
|
+
| `setupAnalyticsLogger(instance)` | function | Patches a Firebase Analytics instance. |
|
|
237
|
+
| `logAnalyticsEvent(name, params?, userProperties?)` | function | Adds a manual analytics event to the inspector. |
|
|
238
|
+
| `clearAnalyticsEvents()` | function | Clears captured analytics events. |
|
|
239
|
+
| `subscribeAnalyticsEvents(callback)` | function | Subscribes to analytics event updates and returns an unsubscribe function. |
|
|
240
|
+
| `connectReduxStore(store)` | function | Connects a Redux store for live state and action inspection. |
|
|
241
|
+
| `getReduxState()` | function | Returns the latest captured Redux state. |
|
|
242
|
+
| `subscribeReduxState(callback)` | function | Subscribes to Redux state updates and returns an unsubscribe function. |
|
|
243
|
+
| `WebView` | component | Instrumented WebView wrapper. |
|
|
244
|
+
| `getWebViewLogs()` | function | Returns captured WebView console logs. |
|
|
245
|
+
| `getWebViewNavHistory()` | function | Returns captured WebView navigation history. |
|
|
246
|
+
| `getWebViewHtml()` | function | Returns the latest captured WebView HTML. |
|
|
247
|
+
| `getWebViewCss()` | function | Returns the latest captured WebView CSS. |
|
|
248
|
+
| `getWebViewJs()` | function | Returns the latest captured WebView JavaScript. |
|
|
249
|
+
| `getWebViewHtmlUrl()` | function | Returns the URL for the latest captured WebView source snapshot. |
|
|
250
|
+
| `clearWebViewData()` | function | Clears captured WebView logs, navigation, and source data. |
|
|
251
|
+
| `subscribeWebView(callback)` | function | Subscribes to WebView data changes and returns an unsubscribe function. |
|
|
252
|
+
| `ErrorBoundary` | component | React error boundary component. |
|
|
251
253
|
|
|
252
254
|
---
|
|
253
255
|
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
declare const JsonViewer: ({ data, search, forceOpen, defaultExpandDepth, }: {
|
|
2
|
+
declare const JsonViewer: ({ data, search, forceOpen, defaultExpandDepth, wrap, }: {
|
|
3
3
|
data: unknown;
|
|
4
4
|
search?: string;
|
|
5
5
|
forceOpen?: boolean;
|
|
6
6
|
defaultExpandDepth?: number;
|
|
7
|
+
wrap?: boolean;
|
|
7
8
|
}) => React.JSX.Element;
|
|
8
9
|
export default JsonViewer;
|
|
@@ -9,11 +9,13 @@ const react_native_1 = require("react-native");
|
|
|
9
9
|
const TreeNode_1 = __importDefault(require("./TreeNode"));
|
|
10
10
|
// Stylesheet
|
|
11
11
|
const styles_1 = __importDefault(require("../styles"));
|
|
12
|
-
const JsonViewer = ({ data, search, forceOpen, defaultExpandDepth, }) => {
|
|
12
|
+
const JsonViewer = ({ data, search, forceOpen, defaultExpandDepth, wrap, }) => {
|
|
13
|
+
const tree = (<TreeNode_1.default data={data} search={search} forceOpen={forceOpen} defaultExpandDepth={defaultExpandDepth}/>);
|
|
14
|
+
if (wrap) {
|
|
15
|
+
return <react_native_1.View style={[styles_1.default.codeBlock, { width: '100%' }]}>{tree}</react_native_1.View>;
|
|
16
|
+
}
|
|
13
17
|
return (<react_native_1.ScrollView horizontal showsHorizontalScrollIndicator={true} style={styles_1.default.codeBlockScroll}>
|
|
14
|
-
<react_native_1.View style={styles_1.default.codeBlock}>
|
|
15
|
-
<TreeNode_1.default data={data} search={search} forceOpen={forceOpen} defaultExpandDepth={defaultExpandDepth}/>
|
|
16
|
-
</react_native_1.View>
|
|
18
|
+
<react_native_1.View style={styles_1.default.codeBlock}>{tree}</react_native_1.View>
|
|
17
19
|
</react_native_1.ScrollView>);
|
|
18
20
|
};
|
|
19
21
|
exports.default = JsonViewer;
|
|
@@ -45,7 +45,7 @@ const MetaAccordion = ({ status, statusColor, duration, size, triggeredAt, metho
|
|
|
45
45
|
</react_native_1.Text>
|
|
46
46
|
</react_native_1.View>
|
|
47
47
|
<react_native_1.View style={styles_1.default.metaDivider}/>
|
|
48
|
-
|
|
48
|
+
|
|
49
49
|
<react_native_1.View style={styles_1.default.metaRow}>
|
|
50
50
|
<react_native_1.View style={styles_1.default.metaLabelRow}>
|
|
51
51
|
<NetworkIcons_1.TerminalIcon color={AppColors_1.AppColors.grayTextWeak} size={14}/>
|
|
@@ -56,9 +56,12 @@ const MetaAccordion = ({ status, statusColor, duration, size, triggeredAt, metho
|
|
|
56
56
|
{
|
|
57
57
|
borderColor: 'rgba(107, 78, 255, 0.25)',
|
|
58
58
|
backgroundColor: 'rgba(107, 78, 255, 0.08)',
|
|
59
|
-
}
|
|
59
|
+
},
|
|
60
|
+
]}>
|
|
61
|
+
<react_native_1.Text style={[
|
|
62
|
+
styles_1.default.statusText,
|
|
63
|
+
{ color: AppColors_1.AppColors.purple, fontFamily: AppFonts_1.AppFonts.interBold },
|
|
60
64
|
]}>
|
|
61
|
-
<react_native_1.Text style={[styles_1.default.statusText, { color: AppColors_1.AppColors.purple, fontFamily: AppFonts_1.AppFonts.interBold }]}>
|
|
62
65
|
{method || 'GET'}
|
|
63
66
|
</react_native_1.Text>
|
|
64
67
|
</react_native_1.View>
|
|
@@ -96,7 +99,9 @@ const MetaAccordion = ({ status, statusColor, duration, size, triggeredAt, metho
|
|
|
96
99
|
<NetworkIcons_1.GlobeIcon color={AppColors_1.AppColors.grayTextWeak} size={14}/>
|
|
97
100
|
<react_native_1.Text style={styles_1.default.metaLabel}>Content Type</react_native_1.Text>
|
|
98
101
|
</react_native_1.View>
|
|
99
|
-
<react_native_1.Text style={styles_1.default.metaValue}>
|
|
102
|
+
<react_native_1.Text style={styles_1.default.metaValue}>
|
|
103
|
+
{contentType || 'application/json'}
|
|
104
|
+
</react_native_1.Text>
|
|
100
105
|
</react_native_1.View>
|
|
101
106
|
<react_native_1.View style={styles_1.default.metaDivider}/>
|
|
102
107
|
|
|
@@ -130,7 +135,7 @@ const MetaAccordion = ({ status, statusColor, duration, size, triggeredAt, metho
|
|
|
130
135
|
</react_native_1.View>
|
|
131
136
|
</react_native_1.View>
|
|
132
137
|
<react_native_1.View style={styles_1.default.metaDivider}/>
|
|
133
|
-
|
|
138
|
+
|
|
134
139
|
<react_native_1.View style={styles_1.default.metaRow}>
|
|
135
140
|
<react_native_1.View style={styles_1.default.metaLabelRow}>
|
|
136
141
|
<NetworkIcons_1.SizeIcon color={AppColors_1.AppColors.grayTextWeak}/>
|
|
@@ -145,7 +150,22 @@ const MetaAccordion = ({ status, statusColor, duration, size, triggeredAt, metho
|
|
|
145
150
|
<NetworkIcons_1.GlobeIcon color={AppColors_1.AppColors.grayTextWeak} size={14}/>
|
|
146
151
|
<react_native_1.Text style={styles_1.default.metaLabel}>Full URL</react_native_1.Text>
|
|
147
152
|
</react_native_1.View>
|
|
148
|
-
<react_native_1.Text selectable={true} numberOfLines={3} ellipsizeMode="tail"
|
|
153
|
+
<react_native_1.Text selectable={true} numberOfLines={3} ellipsizeMode="tail" onPress={() => {
|
|
154
|
+
if (url) {
|
|
155
|
+
react_native_1.Linking.openURL(url).catch(() => { });
|
|
156
|
+
}
|
|
157
|
+
}} style={[
|
|
158
|
+
styles_1.default.metaValue,
|
|
159
|
+
{
|
|
160
|
+
fontSize: 11.5,
|
|
161
|
+
color: url ? AppColors_1.AppColors.purple : AppColors_1.AppColors.grayTextWeak,
|
|
162
|
+
textDecorationLine: url ? 'underline' : 'none',
|
|
163
|
+
fontFamily: AppFonts_1.AppFonts.interMedium,
|
|
164
|
+
flex: 1,
|
|
165
|
+
textAlign: 'right',
|
|
166
|
+
lineHeight: 16,
|
|
167
|
+
},
|
|
168
|
+
]}>
|
|
149
169
|
{url || '—'}
|
|
150
170
|
</react_native_1.Text>
|
|
151
171
|
</react_native_1.View>
|
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
export declare const ReduxStoreIcon: ({ color, size, }: any) => React.JSX.Element;
|
|
3
|
+
export declare const ReduxBoltIcon: ({ color, size, }: any) => React.JSX.Element;
|
|
4
|
+
export declare const ReduxTimelineIcon: ({ color, size, }: any) => React.JSX.Element;
|
|
5
|
+
export declare const ReduxTreeIcon: ({ color, size, }: any) => React.JSX.Element;
|
|
2
6
|
export declare const ReduxTreeView: ({ state, lastActionMap, search, }: {
|
|
3
7
|
state: any;
|
|
4
8
|
lastActionMap: Record<string, any>;
|
|
@@ -36,7 +36,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
36
36
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
37
|
};
|
|
38
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
-
exports.ReduxActionTimeline = exports.ReduxTreeView = void 0;
|
|
39
|
+
exports.ReduxActionTimeline = exports.ReduxTreeView = exports.ReduxTreeIcon = exports.ReduxTimelineIcon = exports.ReduxBoltIcon = exports.ReduxStoreIcon = void 0;
|
|
40
40
|
const react_1 = __importStar(require("react"));
|
|
41
41
|
const react_native_1 = require("react-native");
|
|
42
42
|
const AppColors_1 = require("../styles/AppColors");
|
|
@@ -44,6 +44,44 @@ const AppFonts_1 = require("../styles/AppFonts");
|
|
|
44
44
|
const NetworkIcons_1 = require("./NetworkIcons");
|
|
45
45
|
const react_native_svg_1 = __importStar(require("react-native-svg"));
|
|
46
46
|
const AnimatedEntrance_1 = __importDefault(require("./AnimatedEntrance"));
|
|
47
|
+
const helpers_1 = require("../helpers");
|
|
48
|
+
// #15 — copy-to-clipboard control for a single dispatched action
|
|
49
|
+
const ActionCopyButton = ({ value }) => {
|
|
50
|
+
const [copied, setCopied] = (0, react_1.useState)(false);
|
|
51
|
+
return (<react_native_1.Pressable hitSlop={10} onPress={() => {
|
|
52
|
+
(0, helpers_1.copyToClipboard)(value(), 'Action');
|
|
53
|
+
setCopied(true);
|
|
54
|
+
setTimeout(() => setCopied(false), 1200);
|
|
55
|
+
}} style={{
|
|
56
|
+
width: 26,
|
|
57
|
+
height: 26,
|
|
58
|
+
borderRadius: 7,
|
|
59
|
+
alignItems: 'center',
|
|
60
|
+
justifyContent: 'center',
|
|
61
|
+
backgroundColor: copied
|
|
62
|
+
? `${AppColors_1.AppColors.greenColor}1A`
|
|
63
|
+
: AppColors_1.AppColors.grayBackground,
|
|
64
|
+
borderWidth: 1,
|
|
65
|
+
borderColor: AppColors_1.AppColors.dividerColor,
|
|
66
|
+
}}>
|
|
67
|
+
{copied ? (<NetworkIcons_1.CheckIcon color={AppColors_1.AppColors.greenColor} size={13}/>) : (<NetworkIcons_1.CopyIcon color={AppColors_1.AppColors.grayTextWeak} size={13}/>)}
|
|
68
|
+
</react_native_1.Pressable>);
|
|
69
|
+
};
|
|
70
|
+
// #15 — derive the redux module / folder name from an action type.
|
|
71
|
+
// Supports RTK slice convention ("booking/setDate" -> "Booking") and
|
|
72
|
+
// falls back to the first affected slice.
|
|
73
|
+
const getActionModule = (type, affectedSlices) => {
|
|
74
|
+
if (type && type.includes('/')) {
|
|
75
|
+
const prefix = type.split('/')[0];
|
|
76
|
+
if (prefix)
|
|
77
|
+
return prefix.charAt(0).toUpperCase() + prefix.slice(1);
|
|
78
|
+
}
|
|
79
|
+
if (affectedSlices && affectedSlices.length > 0) {
|
|
80
|
+
const s = affectedSlices[0];
|
|
81
|
+
return s.charAt(0).toUpperCase() + s.slice(1);
|
|
82
|
+
}
|
|
83
|
+
return null;
|
|
84
|
+
};
|
|
47
85
|
// Custom icons
|
|
48
86
|
const DatabaseIcon = ({ color = AppColors_1.AppColors.grayTextWeak, size = 12 }) => (<react_native_svg_1.default width={size} height={size} viewBox="0 0 24 24" fill="none">
|
|
49
87
|
<react_native_svg_1.Path d="M12 2C6.5 2 2 4.2 2 7v10c0 2.8 4.5 5 10 5s10-2.2 10-5V7c0-2.8-4.5-5-10-5z" stroke={color} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
|
|
@@ -56,6 +94,30 @@ const BoltIcon = ({ color = AppColors_1.AppColors.grayTextWeak, size = 12 }) =>
|
|
|
56
94
|
const FolderIcon = ({ color = AppColors_1.AppColors.grayTextWeak, size = 12 }) => (<react_native_svg_1.default width={size} height={size} viewBox="0 0 24 24" fill="none">
|
|
57
95
|
<react_native_svg_1.Path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z" stroke={color} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
|
|
58
96
|
</react_native_svg_1.default>);
|
|
97
|
+
// Exported icons so the Redux tab's section headers and sub-tab buttons can
|
|
98
|
+
// render real vector icons instead of emoji (which fail to render on some
|
|
99
|
+
// Android/font setups).
|
|
100
|
+
const ReduxStoreIcon = ({ color = AppColors_1.AppColors.grayTextWeak, size = 12, }) => (<react_native_svg_1.default width={size} height={size} viewBox="0 0 24 24" fill="none">
|
|
101
|
+
<react_native_svg_1.Path d="M3 9l1.5-5h15L21 9M3 9v10a1 1 0 0 0 1 1h16a1 1 0 0 0 1-1V9M3 9h18M7 9v3a2 2 0 0 0 4 0V9m2 0v3a2 2 0 0 0 4 0V9" stroke={color} strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"/>
|
|
102
|
+
</react_native_svg_1.default>);
|
|
103
|
+
exports.ReduxStoreIcon = ReduxStoreIcon;
|
|
104
|
+
const ReduxBoltIcon = ({ color = AppColors_1.AppColors.grayTextWeak, size = 12, }) => (<react_native_svg_1.default width={size} height={size} viewBox="0 0 24 24" fill="none">
|
|
105
|
+
<react_native_svg_1.Path d="M13 2L3 14h9l-1 8 10-12h-9l1-8z" fill={color} stroke={color} strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/>
|
|
106
|
+
</react_native_svg_1.default>);
|
|
107
|
+
exports.ReduxBoltIcon = ReduxBoltIcon;
|
|
108
|
+
// Action Timeline — a history/clock icon reads as "sequence over time".
|
|
109
|
+
const ReduxTimelineIcon = ({ color = AppColors_1.AppColors.grayTextWeak, size = 12, }) => (<react_native_svg_1.default width={size} height={size} viewBox="0 0 24 24" fill="none">
|
|
110
|
+
<react_native_svg_1.Path d="M3 3v5h5" stroke={color} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
|
|
111
|
+
<react_native_svg_1.Path d="M3.05 13A9 9 0 1 0 6 5.3L3 8" stroke={color} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
|
|
112
|
+
<react_native_svg_1.Path d="M12 7v5l3 2" stroke={color} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
|
|
113
|
+
</react_native_svg_1.default>);
|
|
114
|
+
exports.ReduxTimelineIcon = ReduxTimelineIcon;
|
|
115
|
+
// Store Tree — a node hierarchy icon reads as "nested tree structure".
|
|
116
|
+
const ReduxTreeIcon = ({ color = AppColors_1.AppColors.grayTextWeak, size = 12, }) => (<react_native_svg_1.default width={size} height={size} viewBox="0 0 24 24" fill="none">
|
|
117
|
+
<react_native_svg_1.Path d="M9 4h6v4H9zM3 16h6v4H3zm12 0h6v4h-6z" stroke={color} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
|
|
118
|
+
<react_native_svg_1.Path d="M12 8v4M6 16v-2h12v2" stroke={color} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
|
|
119
|
+
</react_native_svg_1.default>);
|
|
120
|
+
exports.ReduxTreeIcon = ReduxTreeIcon;
|
|
59
121
|
const animateTreeLayout = () => {
|
|
60
122
|
react_native_1.LayoutAnimation.configureNext(react_native_1.LayoutAnimation.Presets.easeInEaseOut);
|
|
61
123
|
};
|
|
@@ -181,7 +243,10 @@ const ReduxTreeView = ({ state, lastActionMap, search, }) => {
|
|
|
181
243
|
setStoreExpanded(!storeExpanded);
|
|
182
244
|
}} style={styles.storeHeader}>
|
|
183
245
|
<AnimatedChevron color="#FFFFFF" expanded={storeExpanded} size={12} style={styles.chevronWrap}/>
|
|
184
|
-
<react_native_1.
|
|
246
|
+
<react_native_1.View style={{ flexDirection: 'row', alignItems: 'center', gap: 6 }}>
|
|
247
|
+
<exports.ReduxStoreIcon color="#FFFFFF" size={14}/>
|
|
248
|
+
<react_native_1.Text style={styles.storeTitle}>Redux Store</react_native_1.Text>
|
|
249
|
+
</react_native_1.View>
|
|
185
250
|
<react_native_1.View style={styles.badge}>
|
|
186
251
|
<react_native_1.Text style={styles.badgeText}>{reducers.length} Reducers</react_native_1.Text>
|
|
187
252
|
</react_native_1.View>
|
|
@@ -286,9 +351,12 @@ const ReduxActionTimeline = ({ history, onClear, search, }) => {
|
|
|
286
351
|
});
|
|
287
352
|
return (<react_native_1.View style={timelineStyles.container}>
|
|
288
353
|
<react_native_1.View style={timelineStyles.headerRow}>
|
|
289
|
-
<react_native_1.
|
|
290
|
-
|
|
291
|
-
|
|
354
|
+
<react_native_1.View style={{ flexDirection: 'row', alignItems: 'center', gap: 6 }}>
|
|
355
|
+
<exports.ReduxBoltIcon color={AppColors_1.AppColors.purple} size={15}/>
|
|
356
|
+
<react_native_1.Text style={timelineStyles.headerTitle}>
|
|
357
|
+
Dispatched Actions ({filteredHistory.length})
|
|
358
|
+
</react_native_1.Text>
|
|
359
|
+
</react_native_1.View>
|
|
292
360
|
{history.length > 0 && (<react_native_1.Pressable onPress={onClear} style={timelineStyles.clearBtn}>
|
|
293
361
|
<react_native_1.Text style={timelineStyles.clearBtnText}>Clear Log</react_native_1.Text>
|
|
294
362
|
</react_native_1.Pressable>)}
|
|
@@ -323,12 +391,49 @@ const ReduxActionTimeline = ({ history, onClear, search, }) => {
|
|
|
323
391
|
},
|
|
324
392
|
]}>
|
|
325
393
|
<react_native_1.View style={timelineStyles.cardHeader}>
|
|
326
|
-
<react_native_1.View style={
|
|
327
|
-
|
|
394
|
+
<react_native_1.View style={{
|
|
395
|
+
flexDirection: 'row',
|
|
396
|
+
alignItems: 'center',
|
|
397
|
+
gap: 6,
|
|
398
|
+
flex: 1,
|
|
399
|
+
}}>
|
|
400
|
+
{(() => {
|
|
401
|
+
const moduleName = getActionModule(item.type, item.affectedSlices);
|
|
402
|
+
return moduleName ? (<react_native_1.View style={{
|
|
403
|
+
paddingHorizontal: 7,
|
|
404
|
+
paddingVertical: 2,
|
|
405
|
+
borderRadius: 6,
|
|
406
|
+
backgroundColor: `${AppColors_1.AppColors.purple}14`,
|
|
407
|
+
borderWidth: 1,
|
|
408
|
+
borderColor: `${AppColors_1.AppColors.purple}33`,
|
|
409
|
+
}}>
|
|
410
|
+
<react_native_1.Text style={{
|
|
411
|
+
fontFamily: AppFonts_1.AppFonts.interBold,
|
|
412
|
+
fontSize: 9.5,
|
|
413
|
+
color: AppColors_1.AppColors.purple,
|
|
414
|
+
letterSpacing: 0.2,
|
|
415
|
+
}}>
|
|
416
|
+
{moduleName}
|
|
417
|
+
</react_native_1.Text>
|
|
418
|
+
</react_native_1.View>) : null;
|
|
419
|
+
})()}
|
|
420
|
+
<react_native_1.View style={timelineStyles.typeBadge}>
|
|
421
|
+
<react_native_1.Text style={timelineStyles.typeText}>{item.type}</react_native_1.Text>
|
|
422
|
+
</react_native_1.View>
|
|
423
|
+
</react_native_1.View>
|
|
424
|
+
<react_native_1.View style={{
|
|
425
|
+
flexDirection: 'row',
|
|
426
|
+
alignItems: 'center',
|
|
427
|
+
gap: 8,
|
|
428
|
+
}}>
|
|
429
|
+
<react_native_1.Text style={timelineStyles.timestamp}>
|
|
430
|
+
{item.timestamp}
|
|
431
|
+
</react_native_1.Text>
|
|
432
|
+
<ActionCopyButton value={() => ({
|
|
433
|
+
type: item.type,
|
|
434
|
+
payload: item.payload,
|
|
435
|
+
})}/>
|
|
328
436
|
</react_native_1.View>
|
|
329
|
-
<react_native_1.Text style={timelineStyles.timestamp}>
|
|
330
|
-
{item.timestamp}
|
|
331
|
-
</react_native_1.Text>
|
|
332
437
|
</react_native_1.View>
|
|
333
438
|
|
|
334
439
|
{item.affectedSlices.length > 0 && (<react_native_1.View style={timelineStyles.slicesRow}>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.DURATION_SLOW_MS = exports.DURATION_FAST_MS = exports.DOMAIN_COLORS = exports.METHOD_COLORS = exports.STATUS_FILTERS = void 0;
|
|
3
|
+
exports.LIB_VERSION = exports.DURATION_SLOW_MS = exports.DURATION_FAST_MS = exports.DOMAIN_COLORS = exports.METHOD_COLORS = exports.STATUS_FILTERS = void 0;
|
|
4
4
|
// Styles
|
|
5
5
|
const AppColors_1 = require("../styles/AppColors");
|
|
6
6
|
exports.STATUS_FILTERS = [
|
|
@@ -33,3 +33,7 @@ exports.DOMAIN_COLORS = [
|
|
|
33
33
|
];
|
|
34
34
|
exports.DURATION_FAST_MS = 200;
|
|
35
35
|
exports.DURATION_SLOW_MS = 800;
|
|
36
|
+
// Package version — auto-generated from package.json at build time.
|
|
37
|
+
// See scripts/gen-version.js (wired to the "prebuild" npm script).
|
|
38
|
+
var version_1 = require("./version");
|
|
39
|
+
Object.defineProperty(exports, "LIB_VERSION", { enumerable: true, get: function () { return version_1.LIB_VERSION; } });
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const LIB_VERSION = "1.1.2";
|
|
@@ -41,7 +41,9 @@ const subscribeReduxState = (cb) => {
|
|
|
41
41
|
};
|
|
42
42
|
exports.subscribeReduxState = subscribeReduxState;
|
|
43
43
|
const connectReduxStore = (store) => {
|
|
44
|
-
if (!store ||
|
|
44
|
+
if (!store ||
|
|
45
|
+
typeof store.getState !== 'function' ||
|
|
46
|
+
typeof store.subscribe !== 'function') {
|
|
45
47
|
console.warn('[NetworkInspector] Invalid Redux store passed to connectReduxStore.');
|
|
46
48
|
return;
|
|
47
49
|
}
|
|
@@ -84,8 +86,14 @@ const connectReduxStore = (store) => {
|
|
|
84
86
|
}
|
|
85
87
|
}
|
|
86
88
|
if (globalReduxAutoRefresh) {
|
|
89
|
+
// Refresh the displayed state tree snapshot.
|
|
87
90
|
(0, exports.setReduxState)(nextState);
|
|
88
91
|
}
|
|
92
|
+
else {
|
|
93
|
+
// Tree is paused, but the action timeline / last-action map still changed,
|
|
94
|
+
// so notify subscribers to re-render those without moving the tree snapshot.
|
|
95
|
+
listeners.forEach(cb => cb());
|
|
96
|
+
}
|
|
89
97
|
return result;
|
|
90
98
|
};
|
|
91
99
|
(0, exports.setReduxState)(store.getState());
|