react-native-inapp-inspector 1.1.23 → 1.1.25
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/dist/commonjs/components/AnalyticsEventCard.js +94 -88
- package/dist/commonjs/components/ConsoleLogCard.js +49 -25
- package/dist/commonjs/components/Inspector/AnalyticsFilterModal.d.ts +7 -0
- package/dist/commonjs/components/Inspector/AnalyticsFilterModal.js +1002 -0
- package/dist/commonjs/components/Inspector/AnalyticsTab.js +637 -10
- package/dist/commonjs/components/Inspector/BundleTab.d.ts +1 -1
- package/dist/commonjs/components/Inspector/BundleTab.js +859 -402
- package/dist/commonjs/components/Inspector/InspectorContext.js +6 -1
- package/dist/commonjs/components/Inspector/InspectorHeader.js +13 -5
- package/dist/commonjs/components/Inspector/LogDetail.js +223 -111
- package/dist/commonjs/components/Inspector/MainScreen.js +1 -1
- package/dist/commonjs/components/Inspector/NetworkDetail.js +131 -81
- package/dist/commonjs/components/Inspector/PerformanceTab.js +20 -10
- package/dist/commonjs/components/NetworkIcons.d.ts +14 -0
- package/dist/commonjs/components/NetworkIcons.js +93 -1
- package/dist/commonjs/components/SegmentedTabs.js +31 -22
- package/dist/commonjs/components/TreeNode.js +13 -12
- package/dist/commonjs/constants/version.d.ts +1 -1
- package/dist/commonjs/constants/version.js +1 -1
- package/dist/commonjs/customHooks/bundleAnalyzer.d.ts +6 -2
- package/dist/commonjs/customHooks/bundleAnalyzer.js +552 -114
- package/dist/commonjs/customHooks/consoleLogger.js +83 -45
- package/dist/commonjs/customHooks/networkLogger.js +10 -1
- package/dist/commonjs/customHooks/performanceTracker.d.ts +8 -0
- package/dist/commonjs/customHooks/performanceTracker.js +44 -3
- package/dist/commonjs/decorators/index.d.ts +49 -0
- package/dist/commonjs/decorators/index.js +142 -0
- package/dist/commonjs/helpers/gaAnalyticsRegistry.d.ts +18 -0
- package/dist/commonjs/helpers/gaAnalyticsRegistry.js +174 -0
- package/dist/commonjs/helpers/index.d.ts +7 -4
- package/dist/commonjs/helpers/index.js +102 -64
- package/dist/commonjs/i18n/locales/en.json +53 -4
- package/dist/commonjs/index.d.ts +4 -0
- package/dist/commonjs/index.js +216 -8
- package/dist/commonjs/styles/index.d.ts +4 -1
- package/dist/commonjs/styles/index.js +22 -19
- package/dist/commonjs/types/enums.d.ts +115 -9
- package/dist/commonjs/types/enums.js +103 -2
- package/dist/commonjs/types/interfaces.d.ts +19 -0
- package/dist/esm/components/AnalyticsEventCard.js +95 -89
- package/dist/esm/components/ConsoleLogCard.js +49 -25
- package/dist/esm/components/Inspector/AnalyticsFilterModal.d.ts +7 -0
- package/dist/esm/components/Inspector/AnalyticsFilterModal.js +964 -0
- package/dist/esm/components/Inspector/AnalyticsTab.js +639 -12
- package/dist/esm/components/Inspector/BundleTab.d.ts +1 -1
- package/dist/esm/components/Inspector/BundleTab.js +860 -403
- package/dist/esm/components/Inspector/InspectorContext.js +1 -0
- package/dist/esm/components/Inspector/InspectorHeader.js +14 -6
- package/dist/esm/components/Inspector/LogDetail.js +223 -111
- package/dist/esm/components/Inspector/MainScreen.js +2 -2
- package/dist/esm/components/Inspector/NetworkDetail.js +132 -49
- package/dist/esm/components/Inspector/PerformanceTab.js +20 -10
- package/dist/esm/components/NetworkIcons.d.ts +14 -0
- package/dist/esm/components/NetworkIcons.js +78 -0
- package/dist/esm/components/SegmentedTabs.js +31 -22
- package/dist/esm/components/TreeNode.js +13 -12
- package/dist/esm/constants/version.d.ts +1 -1
- package/dist/esm/constants/version.js +1 -1
- package/dist/esm/customHooks/bundleAnalyzer.d.ts +6 -2
- package/dist/esm/customHooks/bundleAnalyzer.js +549 -114
- package/dist/esm/customHooks/consoleLogger.js +83 -45
- package/dist/esm/customHooks/networkLogger.js +10 -1
- package/dist/esm/customHooks/performanceTracker.d.ts +8 -0
- package/dist/esm/customHooks/performanceTracker.js +38 -1
- package/dist/esm/decorators/index.d.ts +49 -0
- package/dist/esm/decorators/index.js +137 -0
- package/dist/esm/helpers/gaAnalyticsRegistry.d.ts +18 -0
- package/dist/esm/helpers/gaAnalyticsRegistry.js +169 -0
- package/dist/esm/helpers/index.d.ts +7 -4
- package/dist/esm/helpers/index.js +100 -63
- package/dist/esm/i18n/locales/en.json +53 -4
- package/dist/esm/index.d.ts +4 -0
- package/dist/esm/index.js +190 -8
- package/dist/esm/styles/index.d.ts +4 -1
- package/dist/esm/styles/index.js +22 -19
- package/dist/esm/types/enums.d.ts +115 -9
- package/dist/esm/types/enums.js +102 -3
- package/dist/esm/types/interfaces.d.ts +19 -0
- package/package.json +1 -1
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { useTranslation } from '../../i18n';
|
|
3
3
|
import { Image, Linking, Pressable, ScrollView, Text, TextInput, View, } from 'react-native';
|
|
4
|
-
import Svg, { Circle } from 'react-native-svg';
|
|
5
4
|
import { animateNextLayout, useInspector } from './InspectorContext';
|
|
6
5
|
import TouchableScale from '../TouchableScale';
|
|
7
6
|
import SegmentedTabs from '../SegmentedTabs';
|
|
@@ -17,7 +16,7 @@ import { AppColors } from '../../styles/AppColors';
|
|
|
17
16
|
import { AppFonts } from '../../styles/AppFonts';
|
|
18
17
|
import { METHOD_COLORS } from '../../constants';
|
|
19
18
|
import { getStatusColor, getSize, formatDateTime, getFetchCommand, getCurlCommand, } from '../../helpers';
|
|
20
|
-
import { FailIcon,
|
|
19
|
+
import { FailIcon, StatusIcon, HeadersIcon, RequestIcon, ResponseIcon, DownloadIcon, ClearIcon, SizeIcon, ExternalLinkIcon, ClockIcon, } from '../NetworkIcons';
|
|
21
20
|
const NetworkDetail = React.memo(() => {
|
|
22
21
|
const { t } = useTranslation();
|
|
23
22
|
const { selected, detailDisplayUrl, apiDetailActiveTab, setApiDetailActiveTab, detailSearch, setDetailSearch, reqExpanded, setReqExpanded, resExpanded, setResExpanded, showReqDiff, setShowReqDiff, showResDiff, setShowResDiff, prevRequestData, prevResponseData, logRouteMapRef, } = useInspector();
|
|
@@ -73,70 +72,122 @@ const NetworkDetail = React.memo(() => {
|
|
|
73
72
|
<View style={{
|
|
74
73
|
flexDirection: 'row',
|
|
75
74
|
alignItems: 'center',
|
|
76
|
-
gap:
|
|
75
|
+
gap: 6,
|
|
76
|
+
flexWrap: 'wrap',
|
|
77
|
+
flex: 1,
|
|
77
78
|
}}>
|
|
79
|
+
{/* Method Chip */}
|
|
78
80
|
<View style={[
|
|
79
81
|
styles.methodBadge,
|
|
80
82
|
{
|
|
81
83
|
backgroundColor: METHOD_COLORS[selected.method] ?? METHOD_COLORS.ALL,
|
|
84
|
+
paddingHorizontal: 8,
|
|
85
|
+
paddingVertical: 4,
|
|
86
|
+
borderRadius: 7,
|
|
82
87
|
},
|
|
83
88
|
]}>
|
|
84
89
|
<Text style={[
|
|
85
90
|
styles.methodBadgeText,
|
|
86
91
|
{
|
|
87
92
|
color: AppColors.white,
|
|
93
|
+
fontSize: 10.5,
|
|
88
94
|
},
|
|
89
95
|
]}>
|
|
90
96
|
{selected.method}
|
|
91
97
|
</Text>
|
|
92
98
|
</View>
|
|
93
99
|
|
|
100
|
+
{/* Status Pill */}
|
|
94
101
|
{selected.status != null && (<View style={[
|
|
95
102
|
styles.chip,
|
|
96
103
|
{
|
|
97
104
|
backgroundColor: selected.status === 0
|
|
98
|
-
? `${AppColors.errorColor}
|
|
99
|
-
: `${getStatusColor(selected.status)}
|
|
105
|
+
? `${AppColors.errorColor}18`
|
|
106
|
+
: `${getStatusColor(selected.status)}18`,
|
|
100
107
|
borderColor: selected.status === 0
|
|
101
108
|
? `${AppColors.errorColor}40`
|
|
102
109
|
: `${getStatusColor(selected.status)}40`,
|
|
110
|
+
paddingHorizontal: 7,
|
|
111
|
+
paddingVertical: 3.5,
|
|
112
|
+
borderRadius: 7,
|
|
103
113
|
},
|
|
104
114
|
]}>
|
|
105
|
-
{selected.status === 0 ? (<FailIcon size={8} color={AppColors.errorColor}/>) : (<
|
|
106
|
-
|
|
107
|
-
|
|
115
|
+
{selected.status === 0 ? (<FailIcon size={8} color={AppColors.errorColor}/>) : (<View style={{
|
|
116
|
+
width: 6,
|
|
117
|
+
height: 6,
|
|
118
|
+
borderRadius: 3,
|
|
119
|
+
backgroundColor: getStatusColor(selected.status),
|
|
120
|
+
}}/>)}
|
|
108
121
|
<Text style={[
|
|
109
122
|
styles.chipText,
|
|
110
123
|
{
|
|
111
124
|
color: selected.status === 0
|
|
112
125
|
? AppColors.errorColor
|
|
113
126
|
: getStatusColor(selected.status),
|
|
127
|
+
fontFamily: AppFonts.interBold,
|
|
128
|
+
fontSize: 10.5,
|
|
114
129
|
},
|
|
115
130
|
]}>
|
|
116
131
|
{selected.status === 0
|
|
117
132
|
? 'Failed'
|
|
118
|
-
:
|
|
133
|
+
: `${selected.status} ${selected.status === 200 ? 'OK' : ''}`}
|
|
119
134
|
</Text>
|
|
120
135
|
</View>)}
|
|
121
136
|
|
|
137
|
+
{/* Duration Pill */}
|
|
122
138
|
{selected.duration != null && (<View style={[
|
|
123
139
|
styles.chip,
|
|
124
140
|
{
|
|
125
|
-
backgroundColor: `${AppColors.
|
|
126
|
-
borderColor: `${AppColors.
|
|
141
|
+
backgroundColor: `${AppColors.brandPurple}14`,
|
|
142
|
+
borderColor: `${AppColors.brandPurple}30`,
|
|
143
|
+
paddingHorizontal: 7,
|
|
144
|
+
paddingVertical: 3.5,
|
|
145
|
+
borderRadius: 7,
|
|
146
|
+
gap: 4,
|
|
127
147
|
},
|
|
128
148
|
]}>
|
|
149
|
+
<ClockIcon color={AppColors.brandPurple} size={10}/>
|
|
129
150
|
<Text style={[
|
|
130
151
|
styles.chipText,
|
|
131
|
-
{
|
|
152
|
+
{
|
|
153
|
+
color: AppColors.brandPurple,
|
|
154
|
+
fontFamily: AppFonts.interBold,
|
|
155
|
+
fontSize: 10.5,
|
|
156
|
+
},
|
|
132
157
|
]}>
|
|
133
158
|
{selected.duration}ms
|
|
134
159
|
</Text>
|
|
135
160
|
</View>)}
|
|
161
|
+
|
|
162
|
+
{/* Size Pill */}
|
|
163
|
+
{selected.response != null && (<View style={[
|
|
164
|
+
styles.chip,
|
|
165
|
+
{
|
|
166
|
+
backgroundColor: `${AppColors.sky600}14`,
|
|
167
|
+
borderColor: `${AppColors.sky600}30`,
|
|
168
|
+
paddingHorizontal: 7,
|
|
169
|
+
paddingVertical: 3.5,
|
|
170
|
+
borderRadius: 7,
|
|
171
|
+
gap: 4,
|
|
172
|
+
},
|
|
173
|
+
]}>
|
|
174
|
+
<SizeIcon color={AppColors.sky600} size={10}/>
|
|
175
|
+
<Text style={[
|
|
176
|
+
styles.chipText,
|
|
177
|
+
{
|
|
178
|
+
color: AppColors.sky600,
|
|
179
|
+
fontFamily: AppFonts.interBold,
|
|
180
|
+
fontSize: 10.5,
|
|
181
|
+
},
|
|
182
|
+
]}>
|
|
183
|
+
{getSize(selected.response)}
|
|
184
|
+
</Text>
|
|
185
|
+
</View>)}
|
|
136
186
|
</View>
|
|
187
|
+
|
|
137
188
|
<View style={styles.detailInfoRight}>
|
|
138
|
-
<TouchableScale style={styles.iconSquareBtn} onPress={() => Linking.openURL(detailDisplayUrl)} hitSlop={12}>
|
|
139
|
-
<
|
|
189
|
+
<TouchableScale style={[styles.iconSquareBtn, { backgroundColor: `${AppColors.sky600}15` }]} onPress={() => Linking.openURL(detailDisplayUrl)} hitSlop={12}>
|
|
190
|
+
<ExternalLinkIcon color={AppColors.sky600} size={14}/>
|
|
140
191
|
</TouchableScale>
|
|
141
192
|
<CopyButton value={getFetchCommand(selected)} label="fetch()" iconType="fetch"/>
|
|
142
193
|
<CopyButton value={getCurlCommand(selected)} label="cURL" iconType="terminal"/>
|
|
@@ -144,67 +195,99 @@ const NetworkDetail = React.memo(() => {
|
|
|
144
195
|
</View>
|
|
145
196
|
</View>
|
|
146
197
|
|
|
198
|
+
{/* Full Live URL Analysis Card */}
|
|
147
199
|
<Pressable style={{
|
|
148
200
|
backgroundColor: AppColors.grayBackground,
|
|
149
201
|
borderRadius: 10,
|
|
150
202
|
borderWidth: 1,
|
|
151
203
|
borderColor: AppColors.dividerColor,
|
|
152
204
|
padding: 10,
|
|
153
|
-
marginTop:
|
|
205
|
+
marginTop: 8,
|
|
206
|
+
gap: 6,
|
|
154
207
|
}} onPress={() => Linking.openURL(detailDisplayUrl)}>
|
|
155
208
|
<View style={{
|
|
156
209
|
flexDirection: 'row',
|
|
157
210
|
alignItems: 'center',
|
|
158
211
|
justifyContent: 'space-between',
|
|
159
|
-
marginBottom: 2,
|
|
160
212
|
}}>
|
|
161
|
-
<
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
213
|
+
<View style={{ flexDirection: 'row', alignItems: 'center', gap: 6 }}>
|
|
214
|
+
{schemeStr ? (<View style={{
|
|
215
|
+
backgroundColor: schemeStr.startsWith('https')
|
|
216
|
+
? `${AppColors.green600}18`
|
|
217
|
+
: `${AppColors.amber500}18`,
|
|
218
|
+
paddingHorizontal: 6,
|
|
219
|
+
paddingVertical: 2,
|
|
220
|
+
borderRadius: 4,
|
|
221
|
+
}}>
|
|
168
222
|
<Text style={{
|
|
169
|
-
|
|
170
|
-
|
|
223
|
+
fontFamily: AppFonts.interBold,
|
|
224
|
+
fontSize: 9,
|
|
225
|
+
color: schemeStr.startsWith('https')
|
|
226
|
+
? AppColors.green600
|
|
227
|
+
: AppColors.amber500,
|
|
171
228
|
}}>
|
|
172
|
-
{schemeStr}
|
|
229
|
+
{schemeStr.replace('://', '').toUpperCase()}
|
|
173
230
|
</Text>
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
231
|
+
</View>) : null}
|
|
232
|
+
|
|
233
|
+
<Text style={{
|
|
234
|
+
fontFamily: AppFonts.interBold,
|
|
235
|
+
fontSize: 10,
|
|
236
|
+
color: AppColors.grayTextWeak,
|
|
237
|
+
letterSpacing: 0.4,
|
|
238
|
+
textTransform: 'uppercase',
|
|
239
|
+
}}>
|
|
240
|
+
ENDPOINT URL ↗
|
|
241
|
+
</Text>
|
|
242
|
+
</View>
|
|
243
|
+
|
|
244
|
+
<View style={{ flexDirection: 'row', alignItems: 'center', gap: 4 }}>
|
|
245
|
+
{queryStr ? (<View style={{
|
|
178
246
|
backgroundColor: `${AppColors.purple}14`,
|
|
179
|
-
paddingHorizontal:
|
|
180
|
-
paddingVertical:
|
|
247
|
+
paddingHorizontal: 6,
|
|
248
|
+
paddingVertical: 2,
|
|
181
249
|
borderRadius: 4,
|
|
182
250
|
}}>
|
|
183
|
-
|
|
251
|
+
<Text style={{
|
|
184
252
|
fontFamily: AppFonts.interBold,
|
|
185
253
|
fontSize: 8.5,
|
|
186
254
|
color: AppColors.purple,
|
|
187
255
|
}}>
|
|
188
|
-
|
|
256
|
+
{t('network.queryParams')}
|
|
257
|
+
</Text>
|
|
258
|
+
</View>) : null}
|
|
259
|
+
|
|
260
|
+
<View style={{
|
|
261
|
+
flexDirection: 'row',
|
|
262
|
+
alignItems: 'center',
|
|
263
|
+
gap: 3,
|
|
264
|
+
backgroundColor: `${AppColors.sky600}14`,
|
|
265
|
+
paddingHorizontal: 6,
|
|
266
|
+
paddingVertical: 2,
|
|
267
|
+
borderRadius: 4,
|
|
268
|
+
}}>
|
|
269
|
+
<ExternalLinkIcon color={AppColors.sky600} size={10}/>
|
|
270
|
+
<Text style={{
|
|
271
|
+
fontFamily: AppFonts.interBold,
|
|
272
|
+
fontSize: 9,
|
|
273
|
+
color: AppColors.sky600,
|
|
274
|
+
}}>
|
|
275
|
+
Open ↗
|
|
189
276
|
</Text>
|
|
190
|
-
</View>
|
|
277
|
+
</View>
|
|
278
|
+
</View>
|
|
191
279
|
</View>
|
|
280
|
+
|
|
281
|
+
{/* Full Clickable Hyperlink */}
|
|
192
282
|
<Text selectable={true} style={{
|
|
193
|
-
fontFamily: AppFonts.
|
|
194
|
-
fontSize: 12,
|
|
195
|
-
color: AppColors.
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
283
|
+
fontFamily: AppFonts.interMedium,
|
|
284
|
+
fontSize: 12.5,
|
|
285
|
+
color: AppColors.skyBlue,
|
|
286
|
+
textDecorationLine: 'underline',
|
|
287
|
+
lineHeight: 18,
|
|
288
|
+
}}>
|
|
289
|
+
{detailDisplayUrl}
|
|
199
290
|
</Text>
|
|
200
|
-
{queryStr ? (<Text selectable={true} style={{
|
|
201
|
-
fontFamily: AppFonts.interRegular,
|
|
202
|
-
fontSize: 10,
|
|
203
|
-
color: AppColors.grayTextWeak,
|
|
204
|
-
marginTop: 4,
|
|
205
|
-
}} numberOfLines={1}>
|
|
206
|
-
{queryStr}
|
|
207
|
-
</Text>) : null}
|
|
208
291
|
</Pressable>
|
|
209
292
|
</>);
|
|
210
293
|
})()}
|
|
@@ -9,6 +9,7 @@ import { AppFonts } from '../../styles/AppFonts';
|
|
|
9
9
|
import { useTranslation } from '../../i18n';
|
|
10
10
|
import { getRuntimeDiagnostics } from '../../helpers';
|
|
11
11
|
import { SearchIcon, CircleXIcon, PerformanceIcon, BoltIcon, LightbulbIcon, WarningTriangleIcon, MapIcon, AtomIcon, BrainIcon, GlobeIcon, } from '../NetworkIcons';
|
|
12
|
+
import { INITIAL_EVENTS, subscribePerformanceEvents, logPerformanceEvent, clearPerformanceEvents, } from '../../customHooks/performanceTracker';
|
|
12
13
|
const PerformanceTab = React.memo(() => {
|
|
13
14
|
const { t } = useTranslation();
|
|
14
15
|
// ─── Real-Time FPS Tracking ────────────────────────────────────────────────
|
|
@@ -34,10 +35,16 @@ const PerformanceTab = React.memo(() => {
|
|
|
34
35
|
const [fpsHistory, setFpsHistory] = useState([
|
|
35
36
|
60, 59, 60, 60, 58, 60, 59, 60, 60, 60, 57, 60, 59, 60, 60, 58, 60, 60, 59, 60,
|
|
36
37
|
]);
|
|
37
|
-
// Performance Log Events
|
|
38
|
-
const [events, setEvents] = useState(
|
|
38
|
+
// Performance Log Events (Initialized with benchmark & diagnostics events)
|
|
39
|
+
const [events, setEvents] = useState(INITIAL_EVENTS);
|
|
39
40
|
const [filterCategory, setFilterCategory] = useState('ALL');
|
|
40
41
|
const [search, setSearch] = useState('');
|
|
42
|
+
useEffect(() => {
|
|
43
|
+
const unsub = subscribePerformanceEvents(liveEvents => {
|
|
44
|
+
setEvents(liveEvents);
|
|
45
|
+
});
|
|
46
|
+
return unsub;
|
|
47
|
+
}, []);
|
|
41
48
|
// ─── Live Frame Measurement Loop (1-Second Batch Interval) ────────────────
|
|
42
49
|
const lastFrameTimeRef = useRef(Date.now());
|
|
43
50
|
const rafIdRef = useRef(null);
|
|
@@ -81,9 +88,7 @@ const PerformanceTab = React.memo(() => {
|
|
|
81
88
|
// Trigger log if noticeable frame drop
|
|
82
89
|
if (measuredFps < 50) {
|
|
83
90
|
const durationStr = (1000 / measuredFps).toFixed(1);
|
|
84
|
-
|
|
85
|
-
id: `drop-${Date.now()}`,
|
|
86
|
-
timestamp: Date.now(),
|
|
91
|
+
logPerformanceEvent({
|
|
87
92
|
type: 'fps_drop',
|
|
88
93
|
category: 'render',
|
|
89
94
|
fps: measuredFps,
|
|
@@ -97,8 +102,7 @@ const PerformanceTab = React.memo(() => {
|
|
|
97
102
|
},
|
|
98
103
|
advice: t('performance.liveFpsDipAdvice'),
|
|
99
104
|
severity: measuredFps < 30 ? 'critical' : 'warning',
|
|
100
|
-
};
|
|
101
|
-
setEvents(prev => [newEvent, ...prev.slice(0, 49)]);
|
|
105
|
+
});
|
|
102
106
|
}
|
|
103
107
|
frameCount = 0;
|
|
104
108
|
maxLagInSecond = 0;
|
|
@@ -208,7 +212,7 @@ const PerformanceTab = React.memo(() => {
|
|
|
208
212
|
};
|
|
209
213
|
}, [avgFps, jsLagMs]);
|
|
210
214
|
const clearEvents = () => {
|
|
211
|
-
|
|
215
|
+
clearPerformanceEvents();
|
|
212
216
|
};
|
|
213
217
|
return (<View style={perfStyles.container}>
|
|
214
218
|
{/* Search & Live Control Header */}
|
|
@@ -253,9 +257,9 @@ const PerformanceTab = React.memo(() => {
|
|
|
253
257
|
</View>
|
|
254
258
|
</View>
|
|
255
259
|
|
|
256
|
-
{/* Filter Tabs */}
|
|
260
|
+
{/* ─── Frozen Interactive Filter Tabs Under Search Component ─── */}
|
|
257
261
|
<View style={perfStyles.filterRow}>
|
|
258
|
-
<ScrollView horizontal showsHorizontalScrollIndicator={false} contentContainerStyle={
|
|
262
|
+
<ScrollView horizontal showsHorizontalScrollIndicator={false} contentContainerStyle={perfStyles.filterScrollContent}>
|
|
259
263
|
{[
|
|
260
264
|
{ key: 'ALL', label: t('performance.allLogs'), Icon: BoltIcon, count: events.length },
|
|
261
265
|
{
|
|
@@ -652,6 +656,12 @@ const perfStyles = StyleSheet.create({
|
|
|
652
656
|
backgroundColor: AppColors.white,
|
|
653
657
|
borderBottomWidth: 1,
|
|
654
658
|
borderBottomColor: AppColors.dividerColor,
|
|
659
|
+
paddingVertical: 5,
|
|
660
|
+
},
|
|
661
|
+
filterScrollContent: {
|
|
662
|
+
gap: 6,
|
|
663
|
+
paddingHorizontal: 12,
|
|
664
|
+
paddingVertical: 2,
|
|
655
665
|
},
|
|
656
666
|
filterPill: {
|
|
657
667
|
flexDirection: 'row',
|
|
@@ -62,6 +62,7 @@ export declare const ForwardChevronIcon: ({ color, size, }: any) => React.JSX.El
|
|
|
62
62
|
export declare const BundleIcon: ({ color, size, }: any) => React.JSX.Element;
|
|
63
63
|
export declare const LiveStateIcon: ({ color, size, }: any) => React.JSX.Element;
|
|
64
64
|
export declare const TimelineIcon: ({ color, size, }: any) => React.JSX.Element;
|
|
65
|
+
export declare const RefreshCcwIcon: ({ color, size, }: any) => React.JSX.Element;
|
|
65
66
|
export declare const StorageIcon: ({ color, size, }: any) => React.JSX.Element;
|
|
66
67
|
export declare const MetadataIcon: ({ color, size, }: any) => React.JSX.Element;
|
|
67
68
|
export declare const ReduxIcon: ({ color, size, }: any) => React.JSX.Element;
|
|
@@ -78,3 +79,16 @@ export declare const BrainIcon: ({ color, size }: any) => React.JSX.Element;
|
|
|
78
79
|
export declare const TextAaIcon: ({ color, size }: any) => React.JSX.Element;
|
|
79
80
|
export declare const CartIcon: ({ color, size }: any) => React.JSX.Element;
|
|
80
81
|
export declare const MoneyIcon: ({ color, size }: any) => React.JSX.Element;
|
|
82
|
+
export declare const ExternalLinkIcon: ({ color, size, }: any) => React.JSX.Element;
|
|
83
|
+
export declare const PackageBoxIcon: ({ color, size, }: any) => React.JSX.Element;
|
|
84
|
+
export declare const GitHubIcon: ({ color, size, }: any) => React.JSX.Element;
|
|
85
|
+
export declare const LinkChainIcon: ({ color, size, }: any) => React.JSX.Element;
|
|
86
|
+
export declare const AppleIcon: ({ color, size, }: any) => React.JSX.Element;
|
|
87
|
+
export declare const AndroidIcon: ({ color, size, }: any) => React.JSX.Element;
|
|
88
|
+
export declare const CodeBracketsIcon: ({ color, size, }: any) => React.JSX.Element;
|
|
89
|
+
export declare const FlameIcon: ({ color, size, }: any) => React.JSX.Element;
|
|
90
|
+
export declare const HourglassIcon: ({ color, size, }: any) => React.JSX.Element;
|
|
91
|
+
export declare const PinIcon: ({ color, size, }: any) => React.JSX.Element;
|
|
92
|
+
export declare const RepeatIcon: ({ color, size, }: any) => React.JSX.Element;
|
|
93
|
+
export declare const TargetGoalIcon: ({ color, size, }: any) => React.JSX.Element;
|
|
94
|
+
export declare const UserCheckIcon: ({ color, size, }: any) => React.JSX.Element;
|
|
@@ -373,6 +373,11 @@ export const TimelineIcon = ({ color = AppColors.purple, size = 14, }) => {
|
|
|
373
373
|
<Path d="M12 7.5v4.5l3 2" stroke={color} strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"/>
|
|
374
374
|
</Svg>);
|
|
375
375
|
};
|
|
376
|
+
export const RefreshCcwIcon = ({ color = AppColors.grayTextWeak, size = 14, }) => {
|
|
377
|
+
return (<Svg width={size} height={size} viewBox="0 0 24 24" fill="none">
|
|
378
|
+
<Path d="M3 12a9 9 0 0 1 15-6.7L21 8M21 3v5h-5M21 12a9 9 0 0 1-15 6.7L3 16M3 21v-5h5" stroke={color} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
|
|
379
|
+
</Svg>);
|
|
380
|
+
};
|
|
376
381
|
export const StorageIcon = ({ color = AppColors.purple, size = 14, }) => {
|
|
377
382
|
return (<Svg width={size} height={size} viewBox="0 0 24 24" fill="none">
|
|
378
383
|
<Ellipse cx="12" cy="6" rx="8" ry="2.8" stroke={color} strokeWidth="1.8"/>
|
|
@@ -481,3 +486,76 @@ export const MoneyIcon = ({ color = AppColors.emerald500, size = 14 }) => {
|
|
|
481
486
|
<Path d="M12 7v10M14.5 9.5c-.6-1-1.5-1.5-2.5-1.5-1.5 0-2.5.9-2.5 2s1 1.8 2.5 2 2.5.8 2.5 2-1 2-2.5 2c-1 0-1.9-.5-2.5-1.5" stroke={color} strokeWidth="1.8" strokeLinecap="round"/>
|
|
482
487
|
</Svg>);
|
|
483
488
|
};
|
|
489
|
+
export const ExternalLinkIcon = ({ color = AppColors.grayTextWeak, size = 14, }) => {
|
|
490
|
+
return (<Svg width={size} height={size} viewBox="0 0 24 24" fill="none">
|
|
491
|
+
<Path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" stroke={color} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
|
|
492
|
+
<Path d="M15 3h6v6M10 14L21 3" stroke={color} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
|
|
493
|
+
</Svg>);
|
|
494
|
+
};
|
|
495
|
+
export const PackageBoxIcon = ({ color = AppColors.grayTextWeak, size = 14, }) => {
|
|
496
|
+
return (<Svg width={size} height={size} viewBox="0 0 24 24" fill="none">
|
|
497
|
+
<Path d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z" stroke={color} strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"/>
|
|
498
|
+
<Path d="M3.27 6.96L12 12.01l8.73-5.05M12 22.08V12" stroke={color} strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"/>
|
|
499
|
+
</Svg>);
|
|
500
|
+
};
|
|
501
|
+
export const GitHubIcon = ({ color = AppColors.grayTextWeak, size = 14, }) => {
|
|
502
|
+
return (<Svg width={size} height={size} viewBox="0 0 24 24" fill="none">
|
|
503
|
+
<Path d="M9 19c-5 1.5-5-2.5-7-3m14 6v-3.87a3.37 3.37 0 0 0-.94-2.61c3.14-.35 6.44-1.54 6.44-7A5.44 5.44 0 0 0 20 4.77 5.07 5.07 0 0 0 19.91 1S18.73.65 16 2.48a13.38 13.38 0 0 0-7 0C6.27.65 5.09 1 5.09 1A5.07 5.07 0 0 0 5 4.77a5.44 5.44 0 0 0-1.5 3.78c0 5.42 3.3 6.61 6.44 7A3.37 3.37 0 0 0 9 18.13V22" stroke={color} strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"/>
|
|
504
|
+
</Svg>);
|
|
505
|
+
};
|
|
506
|
+
export const LinkChainIcon = ({ color = AppColors.grayTextWeak, size = 14, }) => {
|
|
507
|
+
return (<Svg width={size} height={size} viewBox="0 0 24 24" fill="none">
|
|
508
|
+
<Path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71" stroke={color} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
|
|
509
|
+
<Path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71" stroke={color} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
|
|
510
|
+
</Svg>);
|
|
511
|
+
};
|
|
512
|
+
export const AppleIcon = ({ color = AppColors.white, size = 12, }) => {
|
|
513
|
+
return (<Svg width={size} height={size} viewBox="0 0 24 24" fill={color}>
|
|
514
|
+
<Path d="M18.71 19.5c-.83 1.24-1.71 2.45-3.05 2.47-1.34.03-1.77-.79-3.29-.79-1.53 0-2 .77-3.27.82-1.31.05-2.3-1.32-3.14-2.53C4.25 17 2.94 12.45 4.7 9.39c.87-1.52 2.43-2.48 4.12-2.51 1.28-.02 2.5.87 3.29.87.78 0 2.26-1.07 3.81-.91.65.03 2.47.26 3.64 1.98-.09.06-2.17 1.28-2.15 3.81.03 3.02 2.65 4.03 2.68 4.04-.03.07-.42 1.44-1.38 2.83M15.97 6.37c.61-.75 1.04-1.8 0.92-2.87-.9.04-1.99.6-2.63 1.35-.56.65-1.06 1.71-.93 2.74 1.01.08 2.03-.47 2.64-1.22z"/>
|
|
515
|
+
</Svg>);
|
|
516
|
+
};
|
|
517
|
+
export const AndroidIcon = ({ color = AppColors.white, size = 12, }) => {
|
|
518
|
+
return (<Svg width={size} height={size} viewBox="0 0 24 24" fill={color}>
|
|
519
|
+
<Path d="M6 18c0 .55.45 1 1 1h1v3.5c0 .83.67 1.5 1.5 1.5s1.5-.67 1.5-1.5V19h2v3.5c0 .83.67 1.5 1.5 1.5s1.5-.67 1.5-1.5V19h1c.55 0 1-.45 1-1V8H6v10zM3.5 8C2.67 8 2 8.67 2 9.5v6c0 .83.67 1.5 1.5 1.5S5 16.33 5 15.5v-6C5 8.67 4.33 8 3.5 8zm17 0c-.83 0-1.5.67-1.5 1.5v6c0 .83.67 1.5 1.5 1.5s1.5-.67 1.5-1.5v-6c0-.83-.67-1.5-1.5-1.5zm-4.97-4.84l1.3-1.3c.2-.2.2-.51 0-.71-.2-.2-.51-.2-.71 0l-1.48 1.48C13.85 2.23 12.95 2 12 2c-.96 0-1.86.23-2.66.63L7.85 1.15c-.2-.2-.51-.2-.71 0-.2.2-.2.51 0 .71l1.31 1.31C6.73 4.26 5.54 6 5.16 8h13.68c-.38-2-1.57-3.74-3.31-4.84zM9 6c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1zm6 0c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1z"/>
|
|
520
|
+
</Svg>);
|
|
521
|
+
};
|
|
522
|
+
export const CodeBracketsIcon = ({ color = AppColors.grayTextWeak, size = 14, }) => {
|
|
523
|
+
return (<Svg width={size} height={size} viewBox="0 0 24 24" fill="none">
|
|
524
|
+
<Path d="M16 18l6-6-6-6M8 6l-6 6 6 6" stroke={color} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
|
|
525
|
+
</Svg>);
|
|
526
|
+
};
|
|
527
|
+
export const FlameIcon = ({ color = AppColors.darkOrange, size = 14, }) => {
|
|
528
|
+
return (<Svg width={size} height={size} viewBox="0 0 24 24" fill="none">
|
|
529
|
+
<Path d="M8.5 14.5A2.5 2.5 0 0 0 11 12c0-1.38-.5-2-1-3-1.072-2.143-.224-4.054 2-6 .5 2.5 2 4.9 4 6.5 2 1.6 3 3.5 3 5.5a7 7 0 1 1-14 0c0-1.153.433-2.294 1-3a2.5 2.5 0 0 0 2.5 3z" stroke={color} strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"/>
|
|
530
|
+
</Svg>);
|
|
531
|
+
};
|
|
532
|
+
export const HourglassIcon = ({ color = AppColors.grayTextWeak, size = 14, }) => {
|
|
533
|
+
return (<Svg width={size} height={size} viewBox="0 0 24 24" fill="none">
|
|
534
|
+
<Path d="M5 22h14M5 2h14M17 22v-4.172a2 2 0 0 0-.586-1.414L12 12l-4.414 4.414A2 2 0 0 0 7 17.828V22M7 2v4.172a2 2 0 0 0 .586 1.414L12 12l4.414-4.414A2 2 0 0 0 17 6.172V2" stroke={color} strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"/>
|
|
535
|
+
</Svg>);
|
|
536
|
+
};
|
|
537
|
+
export const PinIcon = ({ color = AppColors.grayTextWeak, size = 14, }) => {
|
|
538
|
+
return (<Svg width={size} height={size} viewBox="0 0 24 24" fill="none">
|
|
539
|
+
<Path d="M12 21s-6-5.333-6-10a6 6 0 0 1 12 0c0 4.667-6 10-6 10z" stroke={color} strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"/>
|
|
540
|
+
<Circle cx="12" cy="11" r="2" fill={color}/>
|
|
541
|
+
</Svg>);
|
|
542
|
+
};
|
|
543
|
+
export const RepeatIcon = ({ color = AppColors.grayTextWeak, size = 14, }) => {
|
|
544
|
+
return (<Svg width={size} height={size} viewBox="0 0 24 24" fill="none">
|
|
545
|
+
<Path d="M17 2l4 4-4 4M3 11v-1a4 4 0 0 1 4-4h14M7 22l-4-4 4-4M21 13v1a4 4 0 0 1-4 4H3" stroke={color} strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"/>
|
|
546
|
+
</Svg>);
|
|
547
|
+
};
|
|
548
|
+
export const TargetGoalIcon = ({ color = AppColors.brandPurple, size = 14, }) => {
|
|
549
|
+
return (<Svg width={size} height={size} viewBox="0 0 24 24" fill="none">
|
|
550
|
+
<Circle cx="12" cy="12" r="10" stroke={color} strokeWidth="1.8"/>
|
|
551
|
+
<Circle cx="12" cy="12" r="6" stroke={color} strokeWidth="1.8"/>
|
|
552
|
+
<Circle cx="12" cy="12" r="2" fill={color}/>
|
|
553
|
+
</Svg>);
|
|
554
|
+
};
|
|
555
|
+
export const UserCheckIcon = ({ color = AppColors.grayTextWeak, size = 14, }) => {
|
|
556
|
+
return (<Svg width={size} height={size} viewBox="0 0 24 24" fill="none">
|
|
557
|
+
<Path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2" stroke={color} strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"/>
|
|
558
|
+
<Circle cx="9" cy="7" r="4" stroke={color} strokeWidth="1.8"/>
|
|
559
|
+
<Path d="M16 11l2 2 4-4" stroke={color} strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"/>
|
|
560
|
+
</Svg>);
|
|
561
|
+
};
|
|
@@ -5,39 +5,48 @@ import { AppFonts } from '../styles/AppFonts';
|
|
|
5
5
|
const SegmentedTabs = React.memo(({ tabs, activeKey, onChange, style }) => (<View style={[
|
|
6
6
|
{
|
|
7
7
|
flexDirection: 'row',
|
|
8
|
-
borderRadius:
|
|
9
|
-
|
|
8
|
+
borderRadius: 10,
|
|
9
|
+
backgroundColor: `${AppColors.slate200}80`,
|
|
10
|
+
padding: 3,
|
|
10
11
|
borderWidth: 1,
|
|
11
12
|
borderColor: AppColors.dividerColor,
|
|
12
|
-
|
|
13
|
+
gap: 3,
|
|
13
14
|
},
|
|
14
15
|
style,
|
|
15
16
|
]}>
|
|
16
|
-
{tabs.map((tab
|
|
17
|
+
{tabs.map((tab) => {
|
|
17
18
|
const isActive = activeKey === tab.key;
|
|
18
|
-
return (<Pressable key={tab.key} onPress={() => onChange(tab.key)} style={{
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
:
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
19
|
+
return (<Pressable key={tab.key} onPress={() => onChange(tab.key)} style={({ pressed }) => [
|
|
20
|
+
{
|
|
21
|
+
flex: 1,
|
|
22
|
+
paddingVertical: 7,
|
|
23
|
+
paddingHorizontal: 6,
|
|
24
|
+
borderRadius: 7,
|
|
25
|
+
backgroundColor: isActive
|
|
26
|
+
? AppColors.brandPurple
|
|
27
|
+
: 'transparent',
|
|
28
|
+
alignItems: 'center',
|
|
29
|
+
justifyContent: 'center',
|
|
30
|
+
gap: 4.5,
|
|
31
|
+
flexDirection: 'row',
|
|
32
|
+
opacity: pressed ? 0.8 : 1,
|
|
33
|
+
},
|
|
34
|
+
isActive && {
|
|
35
|
+
shadowColor: AppColors.brandPurple,
|
|
36
|
+
shadowOffset: { width: 0, height: 1 },
|
|
37
|
+
shadowOpacity: 0.25,
|
|
38
|
+
shadowRadius: 3,
|
|
39
|
+
elevation: 2,
|
|
40
|
+
},
|
|
41
|
+
]}>
|
|
32
42
|
{tab.icon ? tab.icon(isActive) : null}
|
|
33
43
|
<Text style={{
|
|
34
44
|
fontFamily: AppFonts.interBold,
|
|
35
|
-
fontSize: 10,
|
|
45
|
+
fontSize: 10.5,
|
|
36
46
|
color: isActive
|
|
37
47
|
? AppColors.white
|
|
38
|
-
: AppColors.
|
|
39
|
-
|
|
40
|
-
letterSpacing: 0.3,
|
|
48
|
+
: AppColors.grayText,
|
|
49
|
+
letterSpacing: 0.2,
|
|
41
50
|
}}>
|
|
42
51
|
{tab.label}
|
|
43
52
|
</Text>
|
|
@@ -12,6 +12,19 @@ const TreeNode = React.memo(function TreeNode({ data, name, level = 0, search, f
|
|
|
12
12
|
const open = localOpen;
|
|
13
13
|
const isObject = typeof data === 'object' && data !== null;
|
|
14
14
|
const isArray = Array.isArray(data);
|
|
15
|
+
// Declare all hooks at the top unconditionally (prevents "Rendered fewer hooks than expected" error)
|
|
16
|
+
const treeChevronAnim = useRef(new Animated.Value(open ? 1 : 0)).current;
|
|
17
|
+
useEffect(() => {
|
|
18
|
+
Animated.timing(treeChevronAnim, {
|
|
19
|
+
toValue: open ? 1 : 0,
|
|
20
|
+
duration: 160,
|
|
21
|
+
useNativeDriver: true,
|
|
22
|
+
}).start();
|
|
23
|
+
}, [open]);
|
|
24
|
+
const treeChevronRotate = treeChevronAnim.interpolate({
|
|
25
|
+
inputRange: [0, 1],
|
|
26
|
+
outputRange: ['0deg', '180deg'],
|
|
27
|
+
});
|
|
15
28
|
function renderHighlighted(text) {
|
|
16
29
|
if (text === 'null' || text === 'undefined') {
|
|
17
30
|
return [
|
|
@@ -68,18 +81,6 @@ const TreeNode = React.memo(function TreeNode({ data, name, level = 0, search, f
|
|
|
68
81
|
? data.map((v, i) => [i, v])
|
|
69
82
|
: Object.entries(data);
|
|
70
83
|
const countLabel = isArray ? `[${entries.length}]` : `{${entries.length}}`;
|
|
71
|
-
const treeChevronAnim = useRef(new Animated.Value(open ? 1 : 0)).current;
|
|
72
|
-
useEffect(() => {
|
|
73
|
-
Animated.timing(treeChevronAnim, {
|
|
74
|
-
toValue: open ? 1 : 0,
|
|
75
|
-
duration: 160,
|
|
76
|
-
useNativeDriver: true,
|
|
77
|
-
}).start();
|
|
78
|
-
}, [open]);
|
|
79
|
-
const treeChevronRotate = treeChevronAnim.interpolate({
|
|
80
|
-
inputRange: [0, 1],
|
|
81
|
-
outputRange: ['0deg', '180deg'],
|
|
82
|
-
});
|
|
83
84
|
return (<View style={indentStyle}>
|
|
84
85
|
<Pressable style={styles.treeRow} onPress={() => setLocalOpen(v => !v)} hitSlop={{ top: 10, bottom: 10, left: 10, right: 10 }}>
|
|
85
86
|
<Animated.View style={{ transform: [{ rotate: treeChevronRotate }], marginRight: 6 }}>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const LIB_VERSION = "1.1.
|
|
1
|
+
export declare const LIB_VERSION = "1.1.25";
|
|
@@ -104,12 +104,16 @@ export interface HostBundleAnalysisResult {
|
|
|
104
104
|
};
|
|
105
105
|
}
|
|
106
106
|
export declare const getHostScriptURL: () => string;
|
|
107
|
+
export declare const trackRuntimeModuleExecution: () => void;
|
|
108
|
+
export declare const trackRuntimeDefine: () => void;
|
|
107
109
|
/**
|
|
108
110
|
* Parses raw Metro bundle source code to discover real modules and packages in the host app.
|
|
109
111
|
*/
|
|
110
|
-
export declare const parseBundleSource: (bundleText: string, totalBytes: number, scriptURL: string) => HostBundleAnalysisResult;
|
|
112
|
+
export declare const parseBundleSource: (bundleText: string, totalBytes: number, scriptURL: string, isLive?: boolean) => HostBundleAnalysisResult;
|
|
111
113
|
/**
|
|
112
114
|
* Automatically fetch and analyze the real running bundle for the host app.
|
|
115
|
+
* Supports dynamic port detection (8081, 8082, 8083, etc.) and parallel dev server probing.
|
|
113
116
|
*/
|
|
114
|
-
export declare const analyzeHostAppBundle: () => Promise<HostBundleAnalysisResult>;
|
|
117
|
+
export declare const analyzeHostAppBundle: (forceRefresh?: boolean) => Promise<HostBundleAnalysisResult>;
|
|
118
|
+
export declare const clearCachedBundleAnalysis: () => void;
|
|
115
119
|
export declare const getCachedBundleAnalysis: () => HostBundleAnalysisResult | null;
|