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
|
@@ -35,6 +35,7 @@ export declare const getRawStyles: (colors: typeof AppColors) => {
|
|
|
35
35
|
color: string;
|
|
36
36
|
fontSize: number;
|
|
37
37
|
letterSpacing: number;
|
|
38
|
+
paddingBottom: number;
|
|
38
39
|
};
|
|
39
40
|
headerButtonGroup: {
|
|
40
41
|
flexDirection: string;
|
|
@@ -174,6 +175,26 @@ export declare const getRawStyles: (colors: typeof AppColors) => {
|
|
|
174
175
|
listContent: {
|
|
175
176
|
paddingBottom: number;
|
|
176
177
|
};
|
|
178
|
+
scrollTopBtn: {
|
|
179
|
+
position: string;
|
|
180
|
+
top: number;
|
|
181
|
+
right: number;
|
|
182
|
+
width: number;
|
|
183
|
+
height: number;
|
|
184
|
+
borderRadius: number;
|
|
185
|
+
backgroundColor: string;
|
|
186
|
+
alignItems: string;
|
|
187
|
+
justifyContent: string;
|
|
188
|
+
shadowColor: string;
|
|
189
|
+
shadowOffset: {
|
|
190
|
+
width: number;
|
|
191
|
+
height: number;
|
|
192
|
+
};
|
|
193
|
+
shadowOpacity: number;
|
|
194
|
+
shadowRadius: number;
|
|
195
|
+
elevation: number;
|
|
196
|
+
zIndex: number;
|
|
197
|
+
};
|
|
177
198
|
detailScroll: {
|
|
178
199
|
flex: number;
|
|
179
200
|
};
|
|
@@ -1420,6 +1441,9 @@ export declare const getRawStyles: (colors: typeof AppColors) => {
|
|
|
1420
1441
|
};
|
|
1421
1442
|
headerGradient: {
|
|
1422
1443
|
width: string;
|
|
1444
|
+
borderTopLeftRadius: number;
|
|
1445
|
+
borderTopRightRadius: number;
|
|
1446
|
+
overflow: string;
|
|
1423
1447
|
};
|
|
1424
1448
|
statusChip: {
|
|
1425
1449
|
paddingHorizontal: number;
|
|
@@ -62,8 +62,9 @@ const getRawStyles = (colors) => ({
|
|
|
62
62
|
headerTitle: {
|
|
63
63
|
fontFamily: AppFonts_1.AppFonts.interBold,
|
|
64
64
|
color: colors.primaryLight,
|
|
65
|
-
fontSize:
|
|
65
|
+
fontSize: 15,
|
|
66
66
|
letterSpacing: 0.3,
|
|
67
|
+
paddingBottom: 4,
|
|
67
68
|
},
|
|
68
69
|
headerButtonGroup: {
|
|
69
70
|
flexDirection: 'row',
|
|
@@ -187,6 +188,23 @@ const getRawStyles = (colors) => ({
|
|
|
187
188
|
borderColor: 'rgba(255, 255, 255, 0.08)',
|
|
188
189
|
},
|
|
189
190
|
listContent: { paddingBottom: 12 },
|
|
191
|
+
scrollTopBtn: {
|
|
192
|
+
position: 'absolute',
|
|
193
|
+
top: 12,
|
|
194
|
+
right: 16,
|
|
195
|
+
width: 38,
|
|
196
|
+
height: 38,
|
|
197
|
+
borderRadius: 19,
|
|
198
|
+
backgroundColor: colors.purple,
|
|
199
|
+
alignItems: 'center',
|
|
200
|
+
justifyContent: 'center',
|
|
201
|
+
shadowColor: '#000000',
|
|
202
|
+
shadowOffset: { width: 0, height: 3 },
|
|
203
|
+
shadowOpacity: 0.25,
|
|
204
|
+
shadowRadius: 5,
|
|
205
|
+
elevation: 6,
|
|
206
|
+
zIndex: 50,
|
|
207
|
+
},
|
|
190
208
|
detailScroll: { flex: 1 },
|
|
191
209
|
detailContent: { paddingHorizontal: 6, paddingTop: 8, paddingBottom: 20 },
|
|
192
210
|
fabWrapper: {
|
|
@@ -1321,6 +1339,9 @@ const getRawStyles = (colors) => ({
|
|
|
1321
1339
|
},
|
|
1322
1340
|
headerGradient: {
|
|
1323
1341
|
width: '100%',
|
|
1342
|
+
borderTopLeftRadius: 20,
|
|
1343
|
+
borderTopRightRadius: 20,
|
|
1344
|
+
overflow: 'hidden',
|
|
1324
1345
|
},
|
|
1325
1346
|
// Status chip used in MetaAccordion
|
|
1326
1347
|
statusChip: {
|
|
@@ -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;
|
|
@@ -4,11 +4,13 @@ import { ScrollView, View } from 'react-native';
|
|
|
4
4
|
import TreeNode from './TreeNode';
|
|
5
5
|
// Stylesheet
|
|
6
6
|
import styles from '../styles';
|
|
7
|
-
const JsonViewer = ({ data, search, forceOpen, defaultExpandDepth, }) => {
|
|
7
|
+
const JsonViewer = ({ data, search, forceOpen, defaultExpandDepth, wrap, }) => {
|
|
8
|
+
const tree = (<TreeNode data={data} search={search} forceOpen={forceOpen} defaultExpandDepth={defaultExpandDepth}/>);
|
|
9
|
+
if (wrap) {
|
|
10
|
+
return <View style={[styles.codeBlock, { width: '100%' }]}>{tree}</View>;
|
|
11
|
+
}
|
|
8
12
|
return (<ScrollView horizontal showsHorizontalScrollIndicator={true} style={styles.codeBlockScroll}>
|
|
9
|
-
<View style={styles.codeBlock}>
|
|
10
|
-
<TreeNode data={data} search={search} forceOpen={forceOpen} defaultExpandDepth={defaultExpandDepth}/>
|
|
11
|
-
</View>
|
|
13
|
+
<View style={styles.codeBlock}>{tree}</View>
|
|
12
14
|
</ScrollView>);
|
|
13
15
|
};
|
|
14
16
|
export default JsonViewer;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { View, Pressable, Text, Animated } from 'react-native';
|
|
2
|
+
import { View, Pressable, Text, Animated, Linking } from 'react-native';
|
|
3
3
|
// Constants
|
|
4
4
|
import { DURATION_FAST_MS, DURATION_SLOW_MS } from '../constants';
|
|
5
5
|
// Custom Hooks
|
|
@@ -40,7 +40,7 @@ const MetaAccordion = ({ status, statusColor, duration, size, triggeredAt, metho
|
|
|
40
40
|
</Text>
|
|
41
41
|
</View>
|
|
42
42
|
<View style={styles.metaDivider}/>
|
|
43
|
-
|
|
43
|
+
|
|
44
44
|
<View style={styles.metaRow}>
|
|
45
45
|
<View style={styles.metaLabelRow}>
|
|
46
46
|
<TerminalIcon color={AppColors.grayTextWeak} size={14}/>
|
|
@@ -51,9 +51,12 @@ const MetaAccordion = ({ status, statusColor, duration, size, triggeredAt, metho
|
|
|
51
51
|
{
|
|
52
52
|
borderColor: 'rgba(107, 78, 255, 0.25)',
|
|
53
53
|
backgroundColor: 'rgba(107, 78, 255, 0.08)',
|
|
54
|
-
}
|
|
54
|
+
},
|
|
55
|
+
]}>
|
|
56
|
+
<Text style={[
|
|
57
|
+
styles.statusText,
|
|
58
|
+
{ color: AppColors.purple, fontFamily: AppFonts.interBold },
|
|
55
59
|
]}>
|
|
56
|
-
<Text style={[styles.statusText, { color: AppColors.purple, fontFamily: AppFonts.interBold }]}>
|
|
57
60
|
{method || 'GET'}
|
|
58
61
|
</Text>
|
|
59
62
|
</View>
|
|
@@ -91,7 +94,9 @@ const MetaAccordion = ({ status, statusColor, duration, size, triggeredAt, metho
|
|
|
91
94
|
<GlobeIcon color={AppColors.grayTextWeak} size={14}/>
|
|
92
95
|
<Text style={styles.metaLabel}>Content Type</Text>
|
|
93
96
|
</View>
|
|
94
|
-
<Text style={styles.metaValue}>
|
|
97
|
+
<Text style={styles.metaValue}>
|
|
98
|
+
{contentType || 'application/json'}
|
|
99
|
+
</Text>
|
|
95
100
|
</View>
|
|
96
101
|
<View style={styles.metaDivider}/>
|
|
97
102
|
|
|
@@ -125,7 +130,7 @@ const MetaAccordion = ({ status, statusColor, duration, size, triggeredAt, metho
|
|
|
125
130
|
</View>
|
|
126
131
|
</View>
|
|
127
132
|
<View style={styles.metaDivider}/>
|
|
128
|
-
|
|
133
|
+
|
|
129
134
|
<View style={styles.metaRow}>
|
|
130
135
|
<View style={styles.metaLabelRow}>
|
|
131
136
|
<SizeIcon color={AppColors.grayTextWeak}/>
|
|
@@ -140,7 +145,22 @@ const MetaAccordion = ({ status, statusColor, duration, size, triggeredAt, metho
|
|
|
140
145
|
<GlobeIcon color={AppColors.grayTextWeak} size={14}/>
|
|
141
146
|
<Text style={styles.metaLabel}>Full URL</Text>
|
|
142
147
|
</View>
|
|
143
|
-
<Text selectable={true} numberOfLines={3} ellipsizeMode="tail"
|
|
148
|
+
<Text selectable={true} numberOfLines={3} ellipsizeMode="tail" onPress={() => {
|
|
149
|
+
if (url) {
|
|
150
|
+
Linking.openURL(url).catch(() => { });
|
|
151
|
+
}
|
|
152
|
+
}} style={[
|
|
153
|
+
styles.metaValue,
|
|
154
|
+
{
|
|
155
|
+
fontSize: 11.5,
|
|
156
|
+
color: url ? AppColors.purple : AppColors.grayTextWeak,
|
|
157
|
+
textDecorationLine: url ? 'underline' : 'none',
|
|
158
|
+
fontFamily: AppFonts.interMedium,
|
|
159
|
+
flex: 1,
|
|
160
|
+
textAlign: 'right',
|
|
161
|
+
lineHeight: 16,
|
|
162
|
+
},
|
|
163
|
+
]}>
|
|
144
164
|
{url || '—'}
|
|
145
165
|
</Text>
|
|
146
166
|
</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>;
|
|
@@ -2,9 +2,47 @@ import React, { useEffect, useRef, useState } from 'react';
|
|
|
2
2
|
import { Animated, LayoutAnimation, Platform, Pressable, StyleSheet, Text, UIManager, View, } from 'react-native';
|
|
3
3
|
import { AppColors } from '../styles/AppColors';
|
|
4
4
|
import { AppFonts } from '../styles/AppFonts';
|
|
5
|
-
import { ChevronIcon } from './NetworkIcons';
|
|
5
|
+
import { ChevronIcon, CopyIcon, CheckIcon } from './NetworkIcons';
|
|
6
6
|
import Svg, { Path } from 'react-native-svg';
|
|
7
7
|
import AnimatedEntrance from './AnimatedEntrance';
|
|
8
|
+
import { copyToClipboard } from '../helpers';
|
|
9
|
+
// #15 — copy-to-clipboard control for a single dispatched action
|
|
10
|
+
const ActionCopyButton = ({ value }) => {
|
|
11
|
+
const [copied, setCopied] = useState(false);
|
|
12
|
+
return (<Pressable hitSlop={10} onPress={() => {
|
|
13
|
+
copyToClipboard(value(), 'Action');
|
|
14
|
+
setCopied(true);
|
|
15
|
+
setTimeout(() => setCopied(false), 1200);
|
|
16
|
+
}} style={{
|
|
17
|
+
width: 26,
|
|
18
|
+
height: 26,
|
|
19
|
+
borderRadius: 7,
|
|
20
|
+
alignItems: 'center',
|
|
21
|
+
justifyContent: 'center',
|
|
22
|
+
backgroundColor: copied
|
|
23
|
+
? `${AppColors.greenColor}1A`
|
|
24
|
+
: AppColors.grayBackground,
|
|
25
|
+
borderWidth: 1,
|
|
26
|
+
borderColor: AppColors.dividerColor,
|
|
27
|
+
}}>
|
|
28
|
+
{copied ? (<CheckIcon color={AppColors.greenColor} size={13}/>) : (<CopyIcon color={AppColors.grayTextWeak} size={13}/>)}
|
|
29
|
+
</Pressable>);
|
|
30
|
+
};
|
|
31
|
+
// #15 — derive the redux module / folder name from an action type.
|
|
32
|
+
// Supports RTK slice convention ("booking/setDate" -> "Booking") and
|
|
33
|
+
// falls back to the first affected slice.
|
|
34
|
+
const getActionModule = (type, affectedSlices) => {
|
|
35
|
+
if (type && type.includes('/')) {
|
|
36
|
+
const prefix = type.split('/')[0];
|
|
37
|
+
if (prefix)
|
|
38
|
+
return prefix.charAt(0).toUpperCase() + prefix.slice(1);
|
|
39
|
+
}
|
|
40
|
+
if (affectedSlices && affectedSlices.length > 0) {
|
|
41
|
+
const s = affectedSlices[0];
|
|
42
|
+
return s.charAt(0).toUpperCase() + s.slice(1);
|
|
43
|
+
}
|
|
44
|
+
return null;
|
|
45
|
+
};
|
|
8
46
|
// Custom icons
|
|
9
47
|
const DatabaseIcon = ({ color = AppColors.grayTextWeak, size = 12 }) => (<Svg width={size} height={size} viewBox="0 0 24 24" fill="none">
|
|
10
48
|
<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"/>
|
|
@@ -17,6 +55,26 @@ const BoltIcon = ({ color = AppColors.grayTextWeak, size = 12 }) => (<Svg width=
|
|
|
17
55
|
const FolderIcon = ({ color = AppColors.grayTextWeak, size = 12 }) => (<Svg width={size} height={size} viewBox="0 0 24 24" fill="none">
|
|
18
56
|
<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"/>
|
|
19
57
|
</Svg>);
|
|
58
|
+
// Exported icons so the Redux tab's section headers and sub-tab buttons can
|
|
59
|
+
// render real vector icons instead of emoji (which fail to render on some
|
|
60
|
+
// Android/font setups).
|
|
61
|
+
export const ReduxStoreIcon = ({ color = AppColors.grayTextWeak, size = 12, }) => (<Svg width={size} height={size} viewBox="0 0 24 24" fill="none">
|
|
62
|
+
<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"/>
|
|
63
|
+
</Svg>);
|
|
64
|
+
export const ReduxBoltIcon = ({ color = AppColors.grayTextWeak, size = 12, }) => (<Svg width={size} height={size} viewBox="0 0 24 24" fill="none">
|
|
65
|
+
<Path d="M13 2L3 14h9l-1 8 10-12h-9l1-8z" fill={color} stroke={color} strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/>
|
|
66
|
+
</Svg>);
|
|
67
|
+
// Action Timeline — a history/clock icon reads as "sequence over time".
|
|
68
|
+
export const ReduxTimelineIcon = ({ color = AppColors.grayTextWeak, size = 12, }) => (<Svg width={size} height={size} viewBox="0 0 24 24" fill="none">
|
|
69
|
+
<Path d="M3 3v5h5" stroke={color} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
|
|
70
|
+
<Path d="M3.05 13A9 9 0 1 0 6 5.3L3 8" stroke={color} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
|
|
71
|
+
<Path d="M12 7v5l3 2" stroke={color} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
|
|
72
|
+
</Svg>);
|
|
73
|
+
// Store Tree — a node hierarchy icon reads as "nested tree structure".
|
|
74
|
+
export const ReduxTreeIcon = ({ color = AppColors.grayTextWeak, size = 12, }) => (<Svg width={size} height={size} viewBox="0 0 24 24" fill="none">
|
|
75
|
+
<Path d="M9 4h6v4H9zM3 16h6v4H3zm12 0h6v4h-6z" stroke={color} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
|
|
76
|
+
<Path d="M12 8v4M6 16v-2h12v2" stroke={color} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
|
|
77
|
+
</Svg>);
|
|
20
78
|
const animateTreeLayout = () => {
|
|
21
79
|
LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
|
|
22
80
|
};
|
|
@@ -142,7 +200,10 @@ export const ReduxTreeView = ({ state, lastActionMap, search, }) => {
|
|
|
142
200
|
setStoreExpanded(!storeExpanded);
|
|
143
201
|
}} style={styles.storeHeader}>
|
|
144
202
|
<AnimatedChevron color="#FFFFFF" expanded={storeExpanded} size={12} style={styles.chevronWrap}/>
|
|
145
|
-
<
|
|
203
|
+
<View style={{ flexDirection: 'row', alignItems: 'center', gap: 6 }}>
|
|
204
|
+
<ReduxStoreIcon color="#FFFFFF" size={14}/>
|
|
205
|
+
<Text style={styles.storeTitle}>Redux Store</Text>
|
|
206
|
+
</View>
|
|
146
207
|
<View style={styles.badge}>
|
|
147
208
|
<Text style={styles.badgeText}>{reducers.length} Reducers</Text>
|
|
148
209
|
</View>
|
|
@@ -246,9 +307,12 @@ export const ReduxActionTimeline = ({ history, onClear, search, }) => {
|
|
|
246
307
|
});
|
|
247
308
|
return (<View style={timelineStyles.container}>
|
|
248
309
|
<View style={timelineStyles.headerRow}>
|
|
249
|
-
<
|
|
250
|
-
|
|
251
|
-
|
|
310
|
+
<View style={{ flexDirection: 'row', alignItems: 'center', gap: 6 }}>
|
|
311
|
+
<ReduxBoltIcon color={AppColors.purple} size={15}/>
|
|
312
|
+
<Text style={timelineStyles.headerTitle}>
|
|
313
|
+
Dispatched Actions ({filteredHistory.length})
|
|
314
|
+
</Text>
|
|
315
|
+
</View>
|
|
252
316
|
{history.length > 0 && (<Pressable onPress={onClear} style={timelineStyles.clearBtn}>
|
|
253
317
|
<Text style={timelineStyles.clearBtnText}>Clear Log</Text>
|
|
254
318
|
</Pressable>)}
|
|
@@ -283,12 +347,49 @@ export const ReduxActionTimeline = ({ history, onClear, search, }) => {
|
|
|
283
347
|
},
|
|
284
348
|
]}>
|
|
285
349
|
<View style={timelineStyles.cardHeader}>
|
|
286
|
-
<View style={
|
|
287
|
-
|
|
350
|
+
<View style={{
|
|
351
|
+
flexDirection: 'row',
|
|
352
|
+
alignItems: 'center',
|
|
353
|
+
gap: 6,
|
|
354
|
+
flex: 1,
|
|
355
|
+
}}>
|
|
356
|
+
{(() => {
|
|
357
|
+
const moduleName = getActionModule(item.type, item.affectedSlices);
|
|
358
|
+
return moduleName ? (<View style={{
|
|
359
|
+
paddingHorizontal: 7,
|
|
360
|
+
paddingVertical: 2,
|
|
361
|
+
borderRadius: 6,
|
|
362
|
+
backgroundColor: `${AppColors.purple}14`,
|
|
363
|
+
borderWidth: 1,
|
|
364
|
+
borderColor: `${AppColors.purple}33`,
|
|
365
|
+
}}>
|
|
366
|
+
<Text style={{
|
|
367
|
+
fontFamily: AppFonts.interBold,
|
|
368
|
+
fontSize: 9.5,
|
|
369
|
+
color: AppColors.purple,
|
|
370
|
+
letterSpacing: 0.2,
|
|
371
|
+
}}>
|
|
372
|
+
{moduleName}
|
|
373
|
+
</Text>
|
|
374
|
+
</View>) : null;
|
|
375
|
+
})()}
|
|
376
|
+
<View style={timelineStyles.typeBadge}>
|
|
377
|
+
<Text style={timelineStyles.typeText}>{item.type}</Text>
|
|
378
|
+
</View>
|
|
379
|
+
</View>
|
|
380
|
+
<View style={{
|
|
381
|
+
flexDirection: 'row',
|
|
382
|
+
alignItems: 'center',
|
|
383
|
+
gap: 8,
|
|
384
|
+
}}>
|
|
385
|
+
<Text style={timelineStyles.timestamp}>
|
|
386
|
+
{item.timestamp}
|
|
387
|
+
</Text>
|
|
388
|
+
<ActionCopyButton value={() => ({
|
|
389
|
+
type: item.type,
|
|
390
|
+
payload: item.payload,
|
|
391
|
+
})}/>
|
|
288
392
|
</View>
|
|
289
|
-
<Text style={timelineStyles.timestamp}>
|
|
290
|
-
{item.timestamp}
|
|
291
|
-
</Text>
|
|
292
393
|
</View>
|
|
293
394
|
|
|
294
395
|
{item.affectedSlices.length > 0 && (<View style={timelineStyles.slicesRow}>
|
|
@@ -30,3 +30,6 @@ export const DOMAIN_COLORS = [
|
|
|
30
30
|
];
|
|
31
31
|
export const DURATION_FAST_MS = 200;
|
|
32
32
|
export const DURATION_SLOW_MS = 800;
|
|
33
|
+
// Package version — auto-generated from package.json at build time.
|
|
34
|
+
// See scripts/gen-version.js (wired to the "prebuild" npm script).
|
|
35
|
+
export { LIB_VERSION } from './version';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const LIB_VERSION = "1.1.2";
|
|
@@ -29,7 +29,9 @@ export const subscribeReduxState = (cb) => {
|
|
|
29
29
|
};
|
|
30
30
|
};
|
|
31
31
|
export const connectReduxStore = (store) => {
|
|
32
|
-
if (!store ||
|
|
32
|
+
if (!store ||
|
|
33
|
+
typeof store.getState !== 'function' ||
|
|
34
|
+
typeof store.subscribe !== 'function') {
|
|
33
35
|
console.warn('[NetworkInspector] Invalid Redux store passed to connectReduxStore.');
|
|
34
36
|
return;
|
|
35
37
|
}
|
|
@@ -72,8 +74,14 @@ export const connectReduxStore = (store) => {
|
|
|
72
74
|
}
|
|
73
75
|
}
|
|
74
76
|
if (globalReduxAutoRefresh) {
|
|
77
|
+
// Refresh the displayed state tree snapshot.
|
|
75
78
|
setReduxState(nextState);
|
|
76
79
|
}
|
|
80
|
+
else {
|
|
81
|
+
// Tree is paused, but the action timeline / last-action map still changed,
|
|
82
|
+
// so notify subscribers to re-render those without moving the tree snapshot.
|
|
83
|
+
listeners.forEach(cb => cb());
|
|
84
|
+
}
|
|
77
85
|
return result;
|
|
78
86
|
};
|
|
79
87
|
setReduxState(store.getState());
|