react-native-inapp-inspector 1.1.16 → 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.
- package/README.md +13 -0
- package/dist/commonjs/components/AnimatedEntrance.js +3 -0
- package/dist/commonjs/components/AppHeaderLogo.d.ts +8 -0
- package/dist/commonjs/components/AppHeaderLogo.js +85 -0
- package/dist/commonjs/components/Inspector/BundleTab.d.ts +41 -0
- package/dist/commonjs/components/Inspector/BundleTab.js +2309 -0
- package/dist/commonjs/components/Inspector/InspectorHeader.js +185 -52
- package/dist/commonjs/components/Inspector/MainScreen.js +86 -7
- package/dist/commonjs/components/Inspector/ReduxDetail.d.ts +3 -0
- package/dist/commonjs/components/Inspector/ReduxDetail.js +576 -0
- package/dist/commonjs/components/Inspector/ReduxTab.js +433 -49
- package/dist/commonjs/components/Inspector/SettingsPanel.js +8 -2
- package/dist/commonjs/components/Inspector/TabBar.js +9 -6
- package/dist/commonjs/components/JsonViewer.js +91 -30
- package/dist/commonjs/components/LogCard.js +3 -4
- package/dist/commonjs/components/NetworkIcons.d.ts +8 -0
- package/dist/commonjs/components/NetworkIcons.js +54 -1
- package/dist/commonjs/constants/version.d.ts +1 -1
- package/dist/commonjs/constants/version.js +1 -1
- package/dist/commonjs/customHooks/consoleLogger.js +37 -9
- package/dist/commonjs/customHooks/reduxLogger.js +4 -2
- package/dist/commonjs/helpers/index.js +6 -2
- package/dist/commonjs/index.js +15 -1
- package/dist/commonjs/styles/AppColors.js +163 -163
- package/dist/commonjs/styles/index.d.ts +14 -0
- package/dist/commonjs/styles/index.js +14 -0
- package/dist/commonjs/types/enums.d.ts +2 -2
- package/dist/commonjs/types/interfaces.d.ts +11 -0
- package/dist/esm/components/AnimatedEntrance.js +4 -1
- package/dist/esm/components/AppHeaderLogo.d.ts +8 -0
- package/dist/esm/components/AppHeaderLogo.js +45 -0
- package/dist/esm/components/Inspector/BundleTab.d.ts +41 -0
- package/dist/esm/components/Inspector/BundleTab.js +2271 -0
- package/dist/esm/components/Inspector/InspectorHeader.js +151 -51
- package/dist/esm/components/Inspector/MainScreen.js +53 -7
- package/dist/esm/components/Inspector/ReduxDetail.d.ts +3 -0
- package/dist/esm/components/Inspector/ReduxDetail.js +538 -0
- package/dist/esm/components/Inspector/ReduxTab.js +402 -51
- package/dist/esm/components/Inspector/SettingsPanel.js +9 -3
- package/dist/esm/components/Inspector/TabBar.js +10 -7
- package/dist/esm/components/JsonViewer.js +92 -31
- package/dist/esm/components/LogCard.js +3 -4
- package/dist/esm/components/NetworkIcons.d.ts +8 -0
- package/dist/esm/components/NetworkIcons.js +47 -1
- package/dist/esm/constants/version.d.ts +1 -1
- package/dist/esm/constants/version.js +1 -1
- package/dist/esm/customHooks/consoleLogger.js +37 -9
- package/dist/esm/customHooks/reduxLogger.js +4 -2
- package/dist/esm/helpers/index.js +6 -2
- package/dist/esm/index.js +15 -1
- package/dist/esm/styles/AppColors.js +163 -163
- package/dist/esm/styles/index.d.ts +14 -0
- package/dist/esm/styles/index.js +14 -0
- package/dist/esm/types/enums.d.ts +2 -2
- package/dist/esm/types/interfaces.d.ts +11 -0
- package/example/App.tsx +5 -1
- package/example/assets/app_icon.png +0 -0
- package/example/ios/Podfile.lock +3 -3
- package/example/ios/example/Images.xcassets/AppIcon.appiconset/Contents.json +18 -9
- package/example/ios/example/Images.xcassets/AppIcon.appiconset/app_icon_1024.png +0 -0
- package/example/package-lock.json +824 -10
- package/example/package.json +6 -2
- package/package.json +4 -2
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { useState, useEffect } from 'react';
|
|
2
|
-
import { ScrollView, View, Text, StyleSheet } from 'react-native';
|
|
2
|
+
import { ScrollView, View, Text, StyleSheet, TouchableOpacity } from 'react-native';
|
|
3
3
|
import { useTranslation } from 'react-i18next';
|
|
4
4
|
// Components
|
|
5
5
|
import TreeNode from './TreeNode';
|
|
@@ -10,10 +10,63 @@ import { PrettyIcon, RawIcon, TableIcon } from './NetworkIcons';
|
|
|
10
10
|
import { AppColors } from '../styles/AppColors';
|
|
11
11
|
import { AppFonts } from '../styles/AppFonts';
|
|
12
12
|
import styles from '../styles';
|
|
13
|
+
// ── Table Row Component with 3-Line Clamp & Show More/Less ───────────────────
|
|
14
|
+
const JsonTableRow = React.memo(({ itemKey, val, search, }) => {
|
|
15
|
+
const [expanded, setExpanded] = useState(false);
|
|
16
|
+
const isObject = val !== null && typeof val === 'object';
|
|
17
|
+
let rawStr = '';
|
|
18
|
+
if (val === null) {
|
|
19
|
+
rawStr = 'null';
|
|
20
|
+
}
|
|
21
|
+
else if (val === undefined) {
|
|
22
|
+
rawStr = 'undefined';
|
|
23
|
+
}
|
|
24
|
+
else if (isObject) {
|
|
25
|
+
try {
|
|
26
|
+
rawStr = JSON.stringify(val, null, 2);
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
rawStr = String(val);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
rawStr = String(val);
|
|
34
|
+
}
|
|
35
|
+
const isMultiline = rawStr.includes('\n') || rawStr.length > 90;
|
|
36
|
+
return (<View style={localStyles.tableRow}>
|
|
37
|
+
<View style={{ flex: 2, paddingRight: 8 }}>
|
|
38
|
+
<HighlightText text={itemKey} search={search} style={localStyles.tableCellKey} highlightStyle={localStyles.highlight}/>
|
|
39
|
+
{isObject && (<Text style={localStyles.tableTypeBadge}>
|
|
40
|
+
{Array.isArray(val) ? `Array(${val.length})` : 'Object'}
|
|
41
|
+
</Text>)}
|
|
42
|
+
</View>
|
|
43
|
+
|
|
44
|
+
<View style={{ flex: 3 }}>
|
|
45
|
+
<HighlightText text={rawStr} search={search} style={[
|
|
46
|
+
localStyles.tableCellValue,
|
|
47
|
+
isObject && localStyles.tableCellRawCode,
|
|
48
|
+
]} highlightStyle={localStyles.highlight} numberOfLines={expanded ? undefined : 3} selectable={true}/>
|
|
49
|
+
{isMultiline && (<TouchableOpacity onPress={() => setExpanded(prev => !prev)} hitSlop={6} style={localStyles.showMoreBtn}>
|
|
50
|
+
<Text style={localStyles.showMoreText}>
|
|
51
|
+
{expanded ? 'Show less ▲' : 'Show more ▼'}
|
|
52
|
+
</Text>
|
|
53
|
+
</TouchableOpacity>)}
|
|
54
|
+
</View>
|
|
55
|
+
</View>);
|
|
56
|
+
});
|
|
13
57
|
// ── JsonViewer Component ─────────────────────────────────────────────────────
|
|
14
58
|
const JsonViewer = React.memo(({ data, search, forceOpen, defaultExpandDepth, wrap, fullHeight = false, maxHeight, mode: externalMode, onModeChange, hideTabs = false, }) => {
|
|
15
59
|
const { t } = useTranslation();
|
|
16
|
-
const [
|
|
60
|
+
const [internalMode, setInternalMode] = useState('pretty');
|
|
61
|
+
const mode = externalMode ?? internalMode;
|
|
62
|
+
const setMode = (newMode) => {
|
|
63
|
+
if (onModeChange) {
|
|
64
|
+
onModeChange(newMode);
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
setInternalMode(newMode);
|
|
68
|
+
}
|
|
69
|
+
};
|
|
17
70
|
const rawText = React.useMemo(() => {
|
|
18
71
|
if (typeof data === 'string') {
|
|
19
72
|
return data;
|
|
@@ -27,12 +80,9 @@ const JsonViewer = React.memo(({ data, search, forceOpen, defaultExpandDepth, wr
|
|
|
27
80
|
}, [data]);
|
|
28
81
|
useEffect(() => {
|
|
29
82
|
if (externalMode) {
|
|
30
|
-
|
|
83
|
+
setInternalMode(externalMode);
|
|
31
84
|
}
|
|
32
85
|
}, [externalMode]);
|
|
33
|
-
useEffect(() => {
|
|
34
|
-
onModeChange?.(mode);
|
|
35
|
-
}, [mode, onModeChange]);
|
|
36
86
|
const contentWrapperStyle = [
|
|
37
87
|
localStyles.contentWrapper,
|
|
38
88
|
{ backgroundColor: AppColors.contentBg },
|
|
@@ -45,7 +95,9 @@ const JsonViewer = React.memo(({ data, search, forceOpen, defaultExpandDepth, wr
|
|
|
45
95
|
];
|
|
46
96
|
// Determine type and size details
|
|
47
97
|
const isObject = typeof data === 'object' && data !== null;
|
|
48
|
-
const isEmpty =
|
|
98
|
+
const isEmpty = data === null ||
|
|
99
|
+
data === undefined ||
|
|
100
|
+
(isObject && Object.keys(data).length === 0);
|
|
49
101
|
// Render Table view (Key-Value flat table for root keys)
|
|
50
102
|
const renderTableMode = () => {
|
|
51
103
|
if (!isObject) {
|
|
@@ -65,28 +117,7 @@ const JsonViewer = React.memo(({ data, search, forceOpen, defaultExpandDepth, wr
|
|
|
65
117
|
<Text style={[localStyles.tableHeaderCell, { flex: 2 }]}>{t('network.jsonViewer.key')}</Text>
|
|
66
118
|
<Text style={[localStyles.tableHeaderCell, { flex: 3 }]}>{t('network.jsonViewer.value')}</Text>
|
|
67
119
|
</View>
|
|
68
|
-
{keys.map((key) => {
|
|
69
|
-
const val = data[key];
|
|
70
|
-
let displayVal = '';
|
|
71
|
-
if (val === null) {
|
|
72
|
-
displayVal = 'null';
|
|
73
|
-
}
|
|
74
|
-
else if (val === undefined) {
|
|
75
|
-
displayVal = 'undefined';
|
|
76
|
-
}
|
|
77
|
-
else if (typeof val === 'object') {
|
|
78
|
-
displayVal = Array.isArray(val) ? `[Array(${val.length})]` : '{Object}';
|
|
79
|
-
}
|
|
80
|
-
else {
|
|
81
|
-
displayVal = String(val);
|
|
82
|
-
}
|
|
83
|
-
return (<View key={key} style={localStyles.tableRow}>
|
|
84
|
-
<Text style={[localStyles.tableCellKey, { flex: 2 }]}>{key}</Text>
|
|
85
|
-
<Text style={[localStyles.tableCellValue, { flex: 3 }]} numberOfLines={2}>
|
|
86
|
-
{displayVal}
|
|
87
|
-
</Text>
|
|
88
|
-
</View>);
|
|
89
|
-
})}
|
|
120
|
+
{keys.map((key) => (<JsonTableRow key={key} itemKey={key} val={data[key]} search={search}/>))}
|
|
90
121
|
</View>);
|
|
91
122
|
};
|
|
92
123
|
// Tree View Content
|
|
@@ -220,11 +251,36 @@ const localStyles = StyleSheet.create({
|
|
|
220
251
|
fontSize: 12.5,
|
|
221
252
|
color: AppColors.purple,
|
|
222
253
|
},
|
|
254
|
+
tableTypeBadge: {
|
|
255
|
+
fontFamily: AppFonts.interMedium,
|
|
256
|
+
fontSize: 9.5,
|
|
257
|
+
color: AppColors.slate400,
|
|
258
|
+
marginTop: 2,
|
|
259
|
+
},
|
|
223
260
|
tableCellValue: {
|
|
224
261
|
fontFamily: AppFonts.interRegular,
|
|
225
|
-
fontSize: 12
|
|
262
|
+
fontSize: 12,
|
|
226
263
|
color: AppColors.primaryBlack,
|
|
227
|
-
lineHeight:
|
|
264
|
+
lineHeight: 17,
|
|
265
|
+
},
|
|
266
|
+
tableCellRawCode: {
|
|
267
|
+
fontFamily: AppFonts.interRegular,
|
|
268
|
+
fontSize: 11.5,
|
|
269
|
+
color: AppColors.slate700,
|
|
270
|
+
backgroundColor: `${AppColors.slate100}80`,
|
|
271
|
+
padding: 6,
|
|
272
|
+
borderRadius: 6,
|
|
273
|
+
},
|
|
274
|
+
showMoreBtn: {
|
|
275
|
+
alignSelf: 'flex-start',
|
|
276
|
+
marginTop: 4,
|
|
277
|
+
paddingVertical: 2,
|
|
278
|
+
paddingHorizontal: 4,
|
|
279
|
+
},
|
|
280
|
+
showMoreText: {
|
|
281
|
+
fontFamily: AppFonts.interBold,
|
|
282
|
+
fontSize: 11,
|
|
283
|
+
color: AppColors.purple,
|
|
228
284
|
},
|
|
229
285
|
emptyTable: {
|
|
230
286
|
padding: 24,
|
|
@@ -236,5 +292,10 @@ const localStyles = StyleSheet.create({
|
|
|
236
292
|
fontSize: 12.5,
|
|
237
293
|
color: AppColors.slate400,
|
|
238
294
|
},
|
|
295
|
+
highlight: {
|
|
296
|
+
backgroundColor: '#FEF08A',
|
|
297
|
+
color: '#854D0E',
|
|
298
|
+
fontFamily: AppFonts.interBold,
|
|
299
|
+
},
|
|
239
300
|
});
|
|
240
301
|
export default JsonViewer;
|
|
@@ -39,9 +39,8 @@ const LogCard = React.memo(function LogCard({ item, onPress, timelineMinStart, t
|
|
|
39
39
|
}, [isNew]);
|
|
40
40
|
const path = getPath(item.url);
|
|
41
41
|
const baseUrl = getBaseUrl(item.url) || item.url;
|
|
42
|
-
const cleanHost = baseUrl.replace(/^https?:\/\//, '');
|
|
43
42
|
const slug = path && path !== '/' ? path : item.url;
|
|
44
|
-
const showSlug = slug !==
|
|
43
|
+
const showSlug = slug !== baseUrl && slug !== item.url;
|
|
45
44
|
const triggeredAt = formatDateTime(item.startTime);
|
|
46
45
|
const isJson = item.url.split('?')[0].toLowerCase().endsWith('.json');
|
|
47
46
|
return (<TouchableScale onPress={onPress} style={[
|
|
@@ -52,7 +51,7 @@ const LogCard = React.memo(function LogCard({ item, onPress, timelineMinStart, t
|
|
|
52
51
|
},
|
|
53
52
|
]}>
|
|
54
53
|
<View style={styles.cardBody}>
|
|
55
|
-
{/* Row 1: Header (Checkbox, Serial, Method Badge, Base URL / Host, Status Pill) */}
|
|
54
|
+
{/* Row 1: Header (Checkbox, Serial, Method Badge, Base URL / Host with HTTPS, Status Pill) */}
|
|
56
55
|
<View style={styles.cardHeaderRow}>
|
|
57
56
|
<View style={styles.cardHeaderLeft}>
|
|
58
57
|
<Pressable onPress={() => onToggleSelect(item.id)} hitSlop={12} style={[
|
|
@@ -72,7 +71,7 @@ const LogCard = React.memo(function LogCard({ item, onPress, timelineMinStart, t
|
|
|
72
71
|
</Text>
|
|
73
72
|
</View>
|
|
74
73
|
|
|
75
|
-
<HighlightText text={
|
|
74
|
+
<HighlightText text={baseUrl || item.url} search={searchStr} style={styles.cardHostText} highlightStyle={styles.highlight} numberOfLines={1} ellipsizeMode="tail"/>
|
|
76
75
|
</View>
|
|
77
76
|
|
|
78
77
|
<View style={[
|
|
@@ -57,3 +57,11 @@ export declare const SortIcon: ({ ascending, color, size, }: any) => React.JSX.E
|
|
|
57
57
|
export declare const PrettyIcon: ({ color, size, }: any) => React.JSX.Element;
|
|
58
58
|
export declare const RawIcon: ({ color, size, }: any) => React.JSX.Element;
|
|
59
59
|
export declare const TableIcon: ({ color, size, }: any) => React.JSX.Element;
|
|
60
|
+
export declare const PackageIcon: ({ color, size, }: any) => React.JSX.Element;
|
|
61
|
+
export declare const ForwardChevronIcon: ({ color, size, }: any) => React.JSX.Element;
|
|
62
|
+
export declare const BundleIcon: ({ color, size, }: any) => React.JSX.Element;
|
|
63
|
+
export declare const LiveStateIcon: ({ color, size, }: any) => React.JSX.Element;
|
|
64
|
+
export declare const TimelineIcon: ({ color, size, }: any) => React.JSX.Element;
|
|
65
|
+
export declare const StorageIcon: ({ color, size, }: any) => React.JSX.Element;
|
|
66
|
+
export declare const MetadataIcon: ({ color, size, }: any) => React.JSX.Element;
|
|
67
|
+
export declare const ReduxIcon: ({ color, size, }: any) => React.JSX.Element;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import Svg, { Circle, Line, Path, Rect } from 'react-native-svg';
|
|
2
|
+
import Svg, { Circle, Ellipse, Line, Path, Rect } from 'react-native-svg';
|
|
3
3
|
// Stylesheet
|
|
4
4
|
import { AppColors } from '../styles/AppColors';
|
|
5
5
|
export const EmptyRadarIcon = ({ color = AppColors.purple, size = 32 }) => {
|
|
@@ -348,3 +348,49 @@ export const TableIcon = ({ color = AppColors.grayTextWeak, size = 14, }) => {
|
|
|
348
348
|
<Rect x="3" y="14" width="7" height="7" rx="1.5" stroke={color} strokeWidth="2"/>
|
|
349
349
|
</Svg>);
|
|
350
350
|
};
|
|
351
|
+
export const PackageIcon = ({ color = AppColors.grayTextWeak, size = 14, }) => {
|
|
352
|
+
return (<Svg width={size} height={size} viewBox="0 0 24 24" fill="none">
|
|
353
|
+
<Path d="M16.5 9.4 7.55 4.24a1.78 1.78 0 0 0-2.5 1.55v12.42a1.78 1.78 0 0 0 .86 1.52l8.95 5.16a1.78 1.78 0 0 0 1.78 0l8.95-5.16a1.78 1.78 0 0 0 .86-1.52V5.79a1.78 1.78 0 0 0-2.5-1.55L16.5 9.4z" stroke={color} strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"/>
|
|
354
|
+
<Path d="M3.29 7 12 12.01 20.71 7M12 22.08V12" stroke={color} strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"/>
|
|
355
|
+
</Svg>);
|
|
356
|
+
};
|
|
357
|
+
export const ForwardChevronIcon = ({ color = AppColors.grayTextWeak, size = 14, }) => {
|
|
358
|
+
return (<Svg width={size} height={size} viewBox="0 0 24 24" fill="none">
|
|
359
|
+
<Path d="M9 18l6-6-6-6" stroke={color} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
|
|
360
|
+
</Svg>);
|
|
361
|
+
};
|
|
362
|
+
export const BundleIcon = PackageIcon;
|
|
363
|
+
export const LiveStateIcon = ({ color = AppColors.purple, size = 14, }) => {
|
|
364
|
+
return (<Svg width={size} height={size} viewBox="0 0 24 24" fill="none">
|
|
365
|
+
<Path d="M12 3v3M12 18v3M3 12h3M18 12h3" stroke={color} strokeWidth="2" strokeLinecap="round"/>
|
|
366
|
+
<Circle cx="12" cy="12" r="3.5" stroke={color} strokeWidth="1.8" fill={`${color}22`}/>
|
|
367
|
+
<Circle cx="12" cy="12" r="1.5" fill={color}/>
|
|
368
|
+
</Svg>);
|
|
369
|
+
};
|
|
370
|
+
export const TimelineIcon = ({ color = AppColors.purple, size = 14, }) => {
|
|
371
|
+
return (<Svg width={size} height={size} viewBox="0 0 24 24" fill="none">
|
|
372
|
+
<Circle cx="12" cy="12" r="8.5" stroke={color} strokeWidth="1.8"/>
|
|
373
|
+
<Path d="M12 7.5v4.5l3 2" stroke={color} strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"/>
|
|
374
|
+
</Svg>);
|
|
375
|
+
};
|
|
376
|
+
export const StorageIcon = ({ color = AppColors.purple, size = 14, }) => {
|
|
377
|
+
return (<Svg width={size} height={size} viewBox="0 0 24 24" fill="none">
|
|
378
|
+
<Ellipse cx="12" cy="6" rx="8" ry="2.8" stroke={color} strokeWidth="1.8"/>
|
|
379
|
+
<Path d="M20 12c0 1.55-3.58 2.8-8 2.8s-8-1.25-8-2.8" stroke={color} strokeWidth="1.8" strokeLinecap="round"/>
|
|
380
|
+
<Path d="M4 6v12c0 1.55 3.58 2.8 8 2.8s8-1.25 8-2.8V6" stroke={color} strokeWidth="1.8" strokeLinecap="round"/>
|
|
381
|
+
</Svg>);
|
|
382
|
+
};
|
|
383
|
+
export const MetadataIcon = ({ color = AppColors.purple, size = 14, }) => {
|
|
384
|
+
return (<Svg width={size} height={size} viewBox="0 0 24 24" fill="none">
|
|
385
|
+
<Circle cx="12" cy="12" r="8.5" stroke={color} strokeWidth="1.8"/>
|
|
386
|
+
<Path d="M12 16v-4M12 8.2h.01" stroke={color} strokeWidth="2" strokeLinecap="round"/>
|
|
387
|
+
</Svg>);
|
|
388
|
+
};
|
|
389
|
+
export const ReduxIcon = ({ color = AppColors.purple, size = 14, }) => {
|
|
390
|
+
return (<Svg width={size} height={size} viewBox="0 0 24 24" fill="none">
|
|
391
|
+
<Circle cx="12" cy="12" r="4" stroke={color} strokeWidth="1.8"/>
|
|
392
|
+
<Path d="M12 3a9 9 0 0 1 9 9M12 21a9 9 0 0 1-9-9" stroke={color} strokeWidth="1.8" strokeLinecap="round"/>
|
|
393
|
+
<Circle cx="21" cy="12" r="1.5" fill={color}/>
|
|
394
|
+
<Circle cx="3" cy="12" r="1.5" fill={color}/>
|
|
395
|
+
</Svg>);
|
|
396
|
+
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const LIB_VERSION = "1.1.
|
|
1
|
+
export declare const LIB_VERSION = "1.1.17";
|
|
@@ -63,6 +63,16 @@ const symbolicateStack = async (stackString) => {
|
|
|
63
63
|
catch { }
|
|
64
64
|
return null;
|
|
65
65
|
};
|
|
66
|
+
const isLoggerInternal = (line) => {
|
|
67
|
+
const l = line.toLowerCase();
|
|
68
|
+
return (l.includes('getstackdetails') ||
|
|
69
|
+
l.includes('addlog') ||
|
|
70
|
+
l.includes('consolelogger') ||
|
|
71
|
+
l.includes('setupconsolelogger') ||
|
|
72
|
+
l.includes('formatargs') ||
|
|
73
|
+
l.includes('react-native-inapp-inspector') ||
|
|
74
|
+
l.trim() === 'error');
|
|
75
|
+
};
|
|
66
76
|
const getStackDetails = (args) => {
|
|
67
77
|
try {
|
|
68
78
|
let errorStack;
|
|
@@ -89,11 +99,7 @@ const getStackDetails = (args) => {
|
|
|
89
99
|
let fallbackCaller;
|
|
90
100
|
for (let i = 0; i < lines.length; i++) {
|
|
91
101
|
const line = lines[i];
|
|
92
|
-
if (!line ||
|
|
93
|
-
line.includes('consoleLogger') ||
|
|
94
|
-
line.includes('setupConsoleLogger') ||
|
|
95
|
-
line.includes('react-native-inapp-inspector') ||
|
|
96
|
-
line.trim() === 'Error') {
|
|
102
|
+
if (!line || isLoggerInternal(line)) {
|
|
97
103
|
continue;
|
|
98
104
|
}
|
|
99
105
|
const isInternal = line.includes('react-native/Libraries') ||
|
|
@@ -110,10 +116,7 @@ const getStackDetails = (args) => {
|
|
|
110
116
|
break;
|
|
111
117
|
}
|
|
112
118
|
}
|
|
113
|
-
const cleanedStack = lines
|
|
114
|
-
.filter(l => !l.includes('consoleLogger') &&
|
|
115
|
-
!l.includes('setupConsoleLogger'))
|
|
116
|
-
.join('\n');
|
|
119
|
+
const cleanedStack = lines.filter(l => !isLoggerInternal(l)).join('\n');
|
|
117
120
|
const caller = userCaller || fallbackCaller || 'Unknown';
|
|
118
121
|
return { caller, stack: cleanedStack || stackToUse, errorStack, stackToUse };
|
|
119
122
|
}
|
|
@@ -159,6 +162,31 @@ const addLog = (type, args, sourceMethod) => {
|
|
|
159
162
|
logs.unshift(newLog);
|
|
160
163
|
logs = logs.slice(0, MAX_LOGS);
|
|
161
164
|
notify();
|
|
165
|
+
// Asynchronously symbolicate stack trace via Metro in development
|
|
166
|
+
if (newLog.stack && typeof __DEV__ !== 'undefined' && __DEV__) {
|
|
167
|
+
symbolicateStack(newLog.stack)
|
|
168
|
+
.then(symbolicatedFrames => {
|
|
169
|
+
if (symbolicatedFrames && symbolicatedFrames.length > 0) {
|
|
170
|
+
const validFrames = symbolicatedFrames.filter(f => f.file &&
|
|
171
|
+
!f.file.includes('react-native/Libraries') &&
|
|
172
|
+
!f.file.includes('node_modules') &&
|
|
173
|
+
!isLoggerInternal(f.file) &&
|
|
174
|
+
!isLoggerInternal(f.methodName || ''));
|
|
175
|
+
const topFrame = validFrames[0] || symbolicatedFrames[0];
|
|
176
|
+
if (topFrame) {
|
|
177
|
+
const cleanMethod = topFrame.methodName || 'anonymous';
|
|
178
|
+
const cleanFile = topFrame.file.split('/').pop() || topFrame.file;
|
|
179
|
+
newLog.caller = `${cleanMethod} (${cleanFile}:${topFrame.lineNumber || 1}:${topFrame.column || 1})`;
|
|
180
|
+
}
|
|
181
|
+
newLog.stack = symbolicatedFrames
|
|
182
|
+
.filter(f => !isLoggerInternal(f.file || '') && !isLoggerInternal(f.methodName || ''))
|
|
183
|
+
.map(f => ` at ${f.methodName || 'anonymous'} (${f.file}:${f.lineNumber || 1}:${f.column || 1})`)
|
|
184
|
+
.join('\n');
|
|
185
|
+
notify();
|
|
186
|
+
}
|
|
187
|
+
})
|
|
188
|
+
.catch(() => { });
|
|
189
|
+
}
|
|
162
190
|
// Asynchronously symbolicate stack trace using Metro in DEV mode
|
|
163
191
|
if (stackToUse && typeof __DEV__ !== 'undefined' && __DEV__) {
|
|
164
192
|
const currentLogId = newLog.id;
|
|
@@ -67,7 +67,8 @@ function recordAction(action, prevState, nextState) {
|
|
|
67
67
|
const payload = action && typeof action === 'object' && action.payload !== undefined
|
|
68
68
|
? action.payload
|
|
69
69
|
: null;
|
|
70
|
-
const
|
|
70
|
+
const now = Date.now();
|
|
71
|
+
const timestamp = new Date(now).toLocaleTimeString();
|
|
71
72
|
const affectedSlices = [];
|
|
72
73
|
if (prevState &&
|
|
73
74
|
nextState &&
|
|
@@ -75,7 +76,7 @@ function recordAction(action, prevState, nextState) {
|
|
|
75
76
|
typeof nextState === 'object') {
|
|
76
77
|
Object.keys(nextState).forEach(key => {
|
|
77
78
|
if (prevState[key] !== nextState[key]) {
|
|
78
|
-
lastActionForReducer[key] = { type, payload, timestamp };
|
|
79
|
+
lastActionForReducer[key] = { type, payload, timestamp, updatedAt: now };
|
|
79
80
|
affectedSlices.push(key);
|
|
80
81
|
}
|
|
81
82
|
});
|
|
@@ -85,6 +86,7 @@ function recordAction(action, prevState, nextState) {
|
|
|
85
86
|
type,
|
|
86
87
|
payload,
|
|
87
88
|
timestamp,
|
|
89
|
+
updatedAt: now,
|
|
88
90
|
affectedSlices,
|
|
89
91
|
prevState,
|
|
90
92
|
nextState,
|
|
@@ -458,10 +458,14 @@ export const parseStackLine = (rawLine, isOrigin = false) => {
|
|
|
458
458
|
columnNumber = locMatch[3];
|
|
459
459
|
}
|
|
460
460
|
// Clean file name (remove query strings, packager urls, and parent paths)
|
|
461
|
-
let cleanPath = fullPath
|
|
461
|
+
let cleanPath = fullPath
|
|
462
|
+
.split('?')[0]
|
|
463
|
+
.split('&')[0]
|
|
464
|
+
.replace(/[)]+$/, '')
|
|
465
|
+
.replace(/\/\/+$/, '');
|
|
462
466
|
// Remove protocol prefixes
|
|
463
467
|
cleanPath = cleanPath.replace(/^(?:https?:\/\/[^\/]+\/|file:\/\/\/|webpack:\/\/\/?)/, '');
|
|
464
|
-
const fileName = cleanPath.split('/').pop() || cleanPath;
|
|
468
|
+
const fileName = cleanPath.split('/').filter(Boolean).pop() || cleanPath;
|
|
465
469
|
// Determine file extension (.tsx, .jsx, .ts, .js)
|
|
466
470
|
const extMatch = fileName.match(/\.([a-z0-9]+)$/i);
|
|
467
471
|
const ext = extMatch ? extMatch[1].toLowerCase() : '';
|
package/dist/esm/index.js
CHANGED
|
@@ -22,7 +22,7 @@ import { getReduxState, subscribeReduxState, setReduxAutoRefresh, getLastActionF
|
|
|
22
22
|
import { LIB_VERSION } from './constants';
|
|
23
23
|
// Stylesheet
|
|
24
24
|
import { toggleGlobalTheme } from './styles';
|
|
25
|
-
const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigationRef, }) => {
|
|
25
|
+
const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigationRef, appIcon, environment, }) => {
|
|
26
26
|
// Set custom storage synchronously during render phase
|
|
27
27
|
setCustomStorage(storage || null);
|
|
28
28
|
const [isDark, setIsDark] = useState(false);
|
|
@@ -41,6 +41,9 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
|
|
|
41
41
|
const [search, setSearch] = useState('');
|
|
42
42
|
const [detailSearch, setDetailSearch] = useState('');
|
|
43
43
|
const [reduxSearch, setReduxSearch] = useState('');
|
|
44
|
+
const [selectedReduxSlice, setSelectedReduxSlice] = useState(null);
|
|
45
|
+
const [selectedReduxAction, setSelectedReduxAction] = useState(null);
|
|
46
|
+
const [reduxActiveSubTab, setReduxActiveSubTab] = useState('state');
|
|
44
47
|
const [apiDetailActiveTab, setApiDetailActiveTab] = useState('response');
|
|
45
48
|
useEffect(() => {
|
|
46
49
|
LogBox.ignoreAllLogs(enabled);
|
|
@@ -147,6 +150,7 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
|
|
|
147
150
|
logs: true,
|
|
148
151
|
analytics: true,
|
|
149
152
|
redux: false,
|
|
153
|
+
bundle: true,
|
|
150
154
|
});
|
|
151
155
|
const [maxNetworkLogs, setMaxNetworkLogs] = useState(100);
|
|
152
156
|
const [reduxAutoRefresh, setReduxAutoRefreshState] = useState(true);
|
|
@@ -165,6 +169,7 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
|
|
|
165
169
|
logs: true,
|
|
166
170
|
analytics: true,
|
|
167
171
|
redux: false,
|
|
172
|
+
bundle: true,
|
|
168
173
|
});
|
|
169
174
|
setDefaultTab('apis');
|
|
170
175
|
setMaxNetworkLogs(100);
|
|
@@ -222,6 +227,7 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
|
|
|
222
227
|
logs: true,
|
|
223
228
|
analytics: true,
|
|
224
229
|
redux: false,
|
|
230
|
+
bundle: true,
|
|
225
231
|
},
|
|
226
232
|
...(saved.tabVisibility || {}),
|
|
227
233
|
apis: true,
|
|
@@ -1089,6 +1095,8 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
|
|
|
1089
1095
|
closeModal,
|
|
1090
1096
|
isReady,
|
|
1091
1097
|
isEnabled,
|
|
1098
|
+
appIcon,
|
|
1099
|
+
environment,
|
|
1092
1100
|
modalHeightPercent,
|
|
1093
1101
|
setModalHeightPercent,
|
|
1094
1102
|
modalAnimationType,
|
|
@@ -1197,6 +1205,12 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
|
|
|
1197
1205
|
reduxLastActionMap,
|
|
1198
1206
|
reduxSearch,
|
|
1199
1207
|
setReduxSearch,
|
|
1208
|
+
selectedReduxSlice,
|
|
1209
|
+
setSelectedReduxSlice,
|
|
1210
|
+
selectedReduxAction,
|
|
1211
|
+
setSelectedReduxAction,
|
|
1212
|
+
reduxActiveSubTab,
|
|
1213
|
+
setReduxActiveSubTab,
|
|
1200
1214
|
// ─── Settings ───────────────────────────────────────────────────────
|
|
1201
1215
|
settingsActiveSubTab,
|
|
1202
1216
|
setSettingsActiveSubTab,
|