react-native-inapp-inspector 2.2.2 → 2.2.3

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.
Files changed (97) hide show
  1. package/dist/commonjs/constants/version.d.ts +1 -1
  2. package/dist/commonjs/constants/version.js +1 -1
  3. package/dist/esm/constants/version.d.ts +1 -1
  4. package/dist/esm/constants/version.js +1 -1
  5. package/package.json +2 -1
  6. package/src/analytics.ts +35 -0
  7. package/src/bundle.ts +25 -0
  8. package/src/components/AnalyticsDetail.tsx +865 -0
  9. package/src/components/AnalyticsEventCard.tsx +441 -0
  10. package/src/components/AnalyticsGraph.tsx +583 -0
  11. package/src/components/AnimatedEntrance.tsx +64 -0
  12. package/src/components/AppHeaderLogo.tsx +109 -0
  13. package/src/components/BrandCircleIcon.tsx +144 -0
  14. package/src/components/BrandSquareIcon.tsx +144 -0
  15. package/src/components/CodeSnippet.tsx +725 -0
  16. package/src/components/ConsoleLogCard.tsx +628 -0
  17. package/src/components/CopyButton.tsx +87 -0
  18. package/src/components/DiffViewer.tsx +82 -0
  19. package/src/components/DomainHeader.tsx +237 -0
  20. package/src/components/EmptyState.tsx +73 -0
  21. package/src/components/EndOfListFooter.tsx +100 -0
  22. package/src/components/ErrorBoundary.tsx +688 -0
  23. package/src/components/HeadersSection.tsx +192 -0
  24. package/src/components/HighlightText.tsx +100 -0
  25. package/src/components/Inspector/AnalyticsFilterModal.tsx +1250 -0
  26. package/src/components/Inspector/AnalyticsTab.tsx +1336 -0
  27. package/src/components/Inspector/BundleTab.tsx +4731 -0
  28. package/src/components/Inspector/ConsoleTab.tsx +702 -0
  29. package/src/components/Inspector/CrashDetail.tsx +941 -0
  30. package/src/components/Inspector/CrashFilterModal.tsx +721 -0
  31. package/src/components/Inspector/CrashTab.tsx +871 -0
  32. package/src/components/Inspector/FabLauncher.tsx +80 -0
  33. package/src/components/Inspector/InspectorContext.tsx +28 -0
  34. package/src/components/Inspector/InspectorHeader.tsx +973 -0
  35. package/src/components/Inspector/LogDetail.tsx +1427 -0
  36. package/src/components/Inspector/MainScreen.tsx +258 -0
  37. package/src/components/Inspector/NavigationTracker.tsx +13 -0
  38. package/src/components/Inspector/NetworkDetail.tsx +794 -0
  39. package/src/components/Inspector/NetworkTab.tsx +1095 -0
  40. package/src/components/Inspector/NpmUpdateToast.tsx +392 -0
  41. package/src/components/Inspector/PerformanceTab.tsx +1894 -0
  42. package/src/components/Inspector/ReduxDetail.tsx +1651 -0
  43. package/src/components/Inspector/ReduxTab.tsx +954 -0
  44. package/src/components/Inspector/SettingsPanel.tsx +3181 -0
  45. package/src/components/Inspector/TabBar.tsx +187 -0
  46. package/src/components/Inspector/TelemetryConsentModal.tsx +392 -0
  47. package/src/components/Inspector/UpdateAvailableModal.tsx +545 -0
  48. package/src/components/JsonViewer.tsx +486 -0
  49. package/src/components/LogCard.tsx +491 -0
  50. package/src/components/LogSyntaxHighlighter.tsx +178 -0
  51. package/src/components/MetaAccordion.tsx +340 -0
  52. package/src/components/MiniBarChart.tsx +42 -0
  53. package/src/components/MiniLineChart.tsx +33 -0
  54. package/src/components/NetworkIcons.tsx +2118 -0
  55. package/src/components/SectionHeader.tsx +113 -0
  56. package/src/components/SegmentedTabs.tsx +83 -0
  57. package/src/components/Slider.tsx +300 -0
  58. package/src/components/SourcePageCard.tsx +148 -0
  59. package/src/components/Toast.tsx +131 -0
  60. package/src/components/TouchableScale.tsx +91 -0
  61. package/src/components/TreeNode.tsx +186 -0
  62. package/src/console.ts +24 -0
  63. package/src/constants/index.ts +38 -0
  64. package/src/constants/version.ts +3 -0
  65. package/src/crash.ts +32 -0
  66. package/src/customHooks/analyticsLogger.ts +336 -0
  67. package/src/customHooks/bundleAnalyzer.ts +1231 -0
  68. package/src/customHooks/consoleLogger.ts +497 -0
  69. package/src/customHooks/crashHandler.ts +944 -0
  70. package/src/customHooks/logFilters.ts +32 -0
  71. package/src/customHooks/networkLogger.ts +419 -0
  72. package/src/customHooks/performanceTracker.ts +1014 -0
  73. package/src/customHooks/reduxLogger.ts +406 -0
  74. package/src/customHooks/useAccordion.tsx +60 -0
  75. package/src/decorators/index.ts +184 -0
  76. package/src/helpers/gaAnalyticsRegistry.ts +204 -0
  77. package/src/helpers/index.ts +860 -0
  78. package/src/helpers/memoryManager.ts +138 -0
  79. package/src/helpers/searchQueryParser.ts +283 -0
  80. package/src/helpers/settingsStore.ts +171 -0
  81. package/src/helpers/telemetry.ts +505 -0
  82. package/src/helpers/toast.ts +17 -0
  83. package/src/i18n/index.ts +69 -0
  84. package/src/i18n/locales/en.json +1052 -0
  85. package/src/index.tsx +2336 -0
  86. package/src/native/NativeInspector.ts +397 -0
  87. package/src/native/NativeNetworkInspector.ts +24 -0
  88. package/src/network.ts +22 -0
  89. package/src/performance.ts +38 -0
  90. package/src/redux.ts +23 -0
  91. package/src/styles/AppColors.ts +408 -0
  92. package/src/styles/AppFonts.ts +8 -0
  93. package/src/styles/common.ts +209 -0
  94. package/src/styles/index.ts +1570 -0
  95. package/src/types/enums.ts +194 -0
  96. package/src/types/index.ts +34 -0
  97. package/src/types/interfaces.ts +515 -0
@@ -0,0 +1,486 @@
1
+ import React, {useState, useEffect} from 'react';
2
+ import {ScrollView, View, Text, StyleSheet, TouchableOpacity} from 'react-native';
3
+ import {useTranslation} from '../i18n';
4
+
5
+ // Components
6
+ import TreeNode from './TreeNode';
7
+ import SegmentedTabs from './SegmentedTabs';
8
+ import HighlightText from './HighlightText';
9
+ import {PrettyIcon, RawIcon, TableIcon} from './NetworkIcons';
10
+
11
+ // Styles
12
+ import {AppColors} from '../styles/AppColors';
13
+ import {AppFonts} from '../styles/AppFonts';
14
+ import styles from '../styles';
15
+
16
+ // ── Table Row Component with 3-Line Clamp & Show More/Less ───────────────────
17
+
18
+ const JsonTableRow = React.memo(({
19
+ itemKey,
20
+ val,
21
+ search,
22
+ }: {
23
+ itemKey: string;
24
+ val: any;
25
+ search?: string;
26
+ }) => {
27
+ const [expanded, setExpanded] = useState(false);
28
+ const isObject = val !== null && typeof val === 'object';
29
+
30
+ let rawStr = '';
31
+ if (val === null) {
32
+ rawStr = 'null';
33
+ } else if (val === undefined) {
34
+ rawStr = 'undefined';
35
+ } else if (isObject) {
36
+ try {
37
+ rawStr = JSON.stringify(val, null, 2);
38
+ } catch {
39
+ rawStr = String(val);
40
+ }
41
+ } else {
42
+ rawStr = String(val);
43
+ }
44
+
45
+ const isMultiline = rawStr.includes('\n') || rawStr.length > 90;
46
+
47
+ return (
48
+ <View style={localStyles.tableRow}>
49
+ <View style={{flex: 2, paddingRight: 8}}>
50
+ <HighlightText
51
+ text={itemKey}
52
+ search={search}
53
+ style={localStyles.tableCellKey}
54
+ highlightStyle={localStyles.highlight}
55
+ />
56
+ {isObject && (
57
+ <Text style={localStyles.tableTypeBadge}>
58
+ {Array.isArray(val) ? `Array(${val.length})` : 'Object'}
59
+ </Text>
60
+ )}
61
+ </View>
62
+
63
+ <View style={{flex: 3}}>
64
+ <HighlightText
65
+ text={rawStr}
66
+ search={search}
67
+ style={[
68
+ localStyles.tableCellValue,
69
+ isObject && localStyles.tableCellRawCode,
70
+ ]}
71
+ highlightStyle={localStyles.highlight}
72
+ numberOfLines={expanded ? undefined : 3}
73
+ selectable={true}
74
+ />
75
+ {isMultiline && (
76
+ <TouchableOpacity
77
+ onPress={() => setExpanded(prev => !prev)}
78
+ hitSlop={6}
79
+ style={localStyles.showMoreBtn}>
80
+ <Text style={localStyles.showMoreText}>
81
+ {expanded ? 'Show less ▲' : 'Show more ▼'}
82
+ </Text>
83
+ </TouchableOpacity>
84
+ )}
85
+ </View>
86
+ </View>
87
+ );
88
+ });
89
+
90
+ // ── JsonViewer Component ─────────────────────────────────────────────────────
91
+
92
+ const JsonViewer = React.memo(({
93
+ data,
94
+ search,
95
+ forceOpen,
96
+ defaultExpandDepth = 1,
97
+ wrap,
98
+ fullHeight = false,
99
+ maxHeight,
100
+ mode: externalMode,
101
+ onModeChange,
102
+ hideTabs = false,
103
+ }: {
104
+ data: unknown;
105
+ search?: string;
106
+ forceOpen?: boolean;
107
+ defaultExpandDepth?: number;
108
+ wrap?: boolean;
109
+ fullHeight?: boolean;
110
+ maxHeight?: number;
111
+ mode?: 'pretty' | 'raw' | 'table';
112
+ onModeChange?: (mode: 'pretty' | 'raw' | 'table') => void;
113
+ hideTabs?: boolean;
114
+ }) => {
115
+ const {t} = useTranslation();
116
+ const [internalMode, setInternalMode] = useState<'pretty' | 'raw' | 'table'>('raw');
117
+ const mode = externalMode ?? internalMode;
118
+
119
+ const setMode = (newMode: 'pretty' | 'raw' | 'table') => {
120
+ if (onModeChange) {
121
+ onModeChange(newMode);
122
+ } else {
123
+ setInternalMode(newMode);
124
+ }
125
+ };
126
+
127
+ const rawText = React.useMemo(() => {
128
+ if (data === undefined || data === null) {
129
+ return '';
130
+ }
131
+ if (typeof data === 'string') {
132
+ return data;
133
+ }
134
+ try {
135
+ const stringified = JSON.stringify(data);
136
+ return stringified ?? '';
137
+ } catch {
138
+ return String(data) || '';
139
+ }
140
+ }, [data]);
141
+
142
+ const [showFullRaw, setShowFullRaw] = useState(false);
143
+ const RAW_LIMIT = 50000;
144
+ const safeRawText = typeof rawText === 'string' ? rawText : '';
145
+ const isTruncated = safeRawText.length > RAW_LIMIT && !showFullRaw;
146
+ const displayRawText = isTruncated ? safeRawText.slice(0, RAW_LIMIT) : safeRawText;
147
+
148
+ useEffect(() => {
149
+ if (externalMode) {
150
+ setInternalMode(externalMode);
151
+ }
152
+ }, [externalMode]);
153
+
154
+ const contentWrapperStyle = [
155
+ localStyles.contentWrapper,
156
+ {backgroundColor: AppColors.contentBg},
157
+ fullHeight && {flex: 1, maxHeight: undefined},
158
+ !fullHeight && maxHeight != null && {maxHeight},
159
+ ];
160
+ const scrollStyle = [
161
+ localStyles.rawScroll,
162
+ !fullHeight && maxHeight != null && {maxHeight},
163
+ ];
164
+
165
+ // Determine type and size details
166
+ const isObject = typeof data === 'object' && data !== null;
167
+ const isEmpty =
168
+ data === null ||
169
+ data === undefined ||
170
+ (isObject && Object.keys(data as object).length === 0);
171
+
172
+ // Render Table view (Key-Value flat table for root keys)
173
+ const renderTableMode = () => {
174
+ if (!isObject) {
175
+ return (
176
+ <View style={localStyles.tableRow}>
177
+ <Text style={localStyles.tableCellKey}>{t('network.jsonViewer.value')}</Text>
178
+ <Text style={localStyles.tableCellValue}>{String(data)}</Text>
179
+ </View>
180
+ );
181
+ }
182
+
183
+ const keys = Object.keys(data as object);
184
+ if (keys.length === 0) {
185
+ return (
186
+ <View style={localStyles.emptyTable}>
187
+ <Text style={localStyles.emptyTableText}>{t('network.jsonViewer.emptyTable')}</Text>
188
+ </View>
189
+ );
190
+ }
191
+
192
+ return (
193
+ <View style={localStyles.tableView}>
194
+ <View style={localStyles.tableHeaderRow}>
195
+ <Text style={[localStyles.tableHeaderCell, {flex: 2}]}>{t('network.jsonViewer.key')}</Text>
196
+ <Text style={[localStyles.tableHeaderCell, {flex: 3}]}>{t('network.jsonViewer.value')}</Text>
197
+ </View>
198
+ {keys.map((key) => (
199
+ <JsonTableRow
200
+ key={key}
201
+ itemKey={key}
202
+ val={(data as any)[key]}
203
+ search={search}
204
+ />
205
+ ))}
206
+ </View>
207
+ );
208
+ };
209
+
210
+ // Tree View Content
211
+ const tree = (
212
+ <TreeNode
213
+ data={data}
214
+ search={search}
215
+ forceOpen={forceOpen}
216
+ defaultExpandDepth={defaultExpandDepth}
217
+ />
218
+ );
219
+
220
+ return (
221
+ <View style={[localStyles.container, fullHeight && {flex: 1}]}>
222
+ {/* ── Top Toolbar (Postman-style) ── */}
223
+ {!hideTabs && (
224
+ <View style={localStyles.toolbar}>
225
+ <SegmentedTabs
226
+ tabs={[
227
+ {
228
+ key: 'pretty',
229
+ label: t('network.jsonViewer.pretty'),
230
+ icon: (isActive: boolean) => (
231
+ <PrettyIcon
232
+ color={isActive ? AppColors.white : AppColors.slate400}
233
+ size={12}
234
+ />
235
+ ),
236
+ },
237
+ {
238
+ key: 'raw',
239
+ label: t('network.jsonViewer.raw'),
240
+ icon: (isActive: boolean) => (
241
+ <RawIcon
242
+ color={isActive ? AppColors.white : AppColors.slate400}
243
+ size={12}
244
+ />
245
+ ),
246
+ },
247
+ {
248
+ key: 'table',
249
+ label: t('network.jsonViewer.table'),
250
+ icon: (isActive: boolean) => (
251
+ <TableIcon
252
+ color={isActive ? AppColors.white : AppColors.slate400}
253
+ size={12}
254
+ />
255
+ ),
256
+ },
257
+ ]}
258
+ activeKey={mode}
259
+ onChange={key =>
260
+ setMode(key as 'pretty' | 'raw' | 'table')
261
+ }
262
+ />
263
+ </View>
264
+ )}
265
+
266
+ {/* ── Main View Content Area (Royal Monospace Theme) ── */}
267
+ <View style={contentWrapperStyle}>
268
+ {mode === 'pretty' && (
269
+ isEmpty ? (
270
+ <View style={localStyles.emptyTable}>
271
+ <Text style={localStyles.emptyTableText}>
272
+ {t('network.jsonViewer.emptyPayload')}
273
+ </Text>
274
+ </View>
275
+ ) : (
276
+ wrap ? (
277
+ fullHeight ? (
278
+ <ScrollView style={{flex: 1}} contentContainerStyle={{flexGrow: 1}}>
279
+ <View style={[styles.codeBlock, {width: '100%'}]}>{tree}</View>
280
+ </ScrollView>
281
+ ) : (
282
+ <ScrollView style={scrollStyle} contentContainerStyle={{flexGrow: 1}}>
283
+ <View style={[styles.codeBlock, {width: '100%'}]}>{tree}</View>
284
+ </ScrollView>
285
+ )
286
+ ) : (
287
+ fullHeight ? (
288
+ <ScrollView style={{flex: 1}} contentContainerStyle={{flexGrow: 1}}>
289
+ <View style={styles.codeBlock}>{tree}</View>
290
+ </ScrollView>
291
+ ) : (
292
+ <ScrollView style={scrollStyle}>
293
+ <ScrollView
294
+ horizontal
295
+ showsHorizontalScrollIndicator={true}
296
+ style={styles.codeBlockScroll}>
297
+ <View style={styles.codeBlock}>{tree}</View>
298
+ </ScrollView>
299
+ </ScrollView>
300
+ )
301
+ )
302
+ )
303
+ )}
304
+
305
+ {mode === 'raw' && (
306
+ <ScrollView
307
+ style={scrollStyle}
308
+ contentContainerStyle={localStyles.rawContainer}
309
+ showsVerticalScrollIndicator={true}
310
+ nestedScrollEnabled={true}>
311
+ <HighlightText
312
+ text={displayRawText}
313
+ search={search}
314
+ detectLinks={rawText.length < 20000}
315
+ style={localStyles.rawPlainText}
316
+ selectable={true}
317
+ highlightStyle={{
318
+ backgroundColor: AppColors.yellowHighlight,
319
+ color: AppColors.primaryBlack,
320
+ borderRadius: 3,
321
+ paddingHorizontal: 2,
322
+ }}
323
+ />
324
+ {isTruncated && (
325
+ <TouchableOpacity
326
+ onPress={() => setShowFullRaw(true)}
327
+ style={{
328
+ marginTop: 10,
329
+ backgroundColor: `${AppColors.brandPurple}15`,
330
+ paddingVertical: 8,
331
+ paddingHorizontal: 12,
332
+ borderRadius: 6,
333
+ alignItems: 'center',
334
+ borderWidth: 1,
335
+ borderColor: `${AppColors.brandPurple}30`,
336
+ }}>
337
+ <Text
338
+ style={{
339
+ fontFamily: AppFonts.interBold,
340
+ fontSize: 11,
341
+ color: AppColors.brandPurple,
342
+ }}>
343
+ Showing first 50 KB ({Math.round(rawText.length / 1024)} KB total) · Tap to load full
344
+ </Text>
345
+ </TouchableOpacity>
346
+ )}
347
+ </ScrollView>
348
+ )}
349
+
350
+ {mode === 'table' && (
351
+ fullHeight ? (
352
+ <ScrollView style={scrollStyle}>
353
+ {renderTableMode()}
354
+ </ScrollView>
355
+ ) : (
356
+ <ScrollView style={scrollStyle}>
357
+ {renderTableMode()}
358
+ </ScrollView>
359
+ )
360
+ )}
361
+ </View>
362
+ </View>
363
+ );
364
+ });
365
+
366
+ const localStyles = StyleSheet.create({
367
+ container: {
368
+ backgroundColor: AppColors.white,
369
+ borderRadius: 12,
370
+ borderWidth: 1.5,
371
+ borderColor: AppColors.slate200,
372
+ overflow: 'hidden',
373
+ shadowColor: AppColors.black,
374
+ shadowOpacity: 0.04,
375
+ shadowRadius: 5,
376
+ shadowOffset: {width: 0, height: 2},
377
+ elevation: 2,
378
+ width: '100%',
379
+ },
380
+ toolbar: {
381
+ flexDirection: 'row',
382
+ alignItems: 'center',
383
+ justifyContent: 'space-between',
384
+ backgroundColor: AppColors.slate50,
385
+ borderBottomWidth: 1,
386
+ borderBottomColor: AppColors.slate200,
387
+ paddingHorizontal: 12,
388
+ paddingVertical: 8,
389
+ },
390
+ contentWrapper: {
391
+ backgroundColor: AppColors.white,
392
+ minHeight: 120,
393
+ },
394
+ rawScroll: {
395
+ flex: 1,
396
+ backgroundColor: AppColors.paperBg, // Royal off-white paper tone
397
+ },
398
+ rawContainer: {
399
+ padding: 12,
400
+ },
401
+ rawPlainText: {
402
+ fontFamily: AppFonts.interRegular,
403
+ fontSize: 12.5,
404
+ color: AppColors.primaryBlack,
405
+ lineHeight: 18,
406
+ },
407
+ tableView: {
408
+ flex: 1,
409
+ },
410
+ tableHeaderRow: {
411
+ flexDirection: 'row',
412
+ backgroundColor: AppColors.slate100,
413
+ borderBottomWidth: 1,
414
+ borderBottomColor: AppColors.slate200,
415
+ paddingVertical: 8,
416
+ paddingHorizontal: 12,
417
+ },
418
+ tableHeaderCell: {
419
+ fontFamily: AppFonts.interBold,
420
+ fontSize: 11,
421
+ color: AppColors.slate600,
422
+ letterSpacing: 0.5,
423
+ textTransform: 'uppercase',
424
+ },
425
+ tableRow: {
426
+ flexDirection: 'row',
427
+ borderBottomWidth: 1,
428
+ borderBottomColor: AppColors.slate100,
429
+ paddingVertical: 10,
430
+ paddingHorizontal: 12,
431
+ alignItems: 'center',
432
+ },
433
+ tableCellKey: {
434
+ fontFamily: AppFonts.interBold,
435
+ fontSize: 12.5,
436
+ color: AppColors.purple,
437
+ },
438
+ tableTypeBadge: {
439
+ fontFamily: AppFonts.interMedium,
440
+ fontSize: 9.5,
441
+ color: AppColors.slate400,
442
+ marginTop: 2,
443
+ },
444
+ tableCellValue: {
445
+ fontFamily: AppFonts.interRegular,
446
+ fontSize: 12,
447
+ color: AppColors.primaryBlack,
448
+ lineHeight: 17,
449
+ },
450
+ tableCellRawCode: {
451
+ fontFamily: AppFonts.interRegular,
452
+ fontSize: 11.5,
453
+ color: AppColors.slate700,
454
+ backgroundColor: `${AppColors.slate100}80`,
455
+ padding: 6,
456
+ borderRadius: 6,
457
+ },
458
+ showMoreBtn: {
459
+ alignSelf: 'flex-start',
460
+ marginTop: 4,
461
+ paddingVertical: 2,
462
+ paddingHorizontal: 4,
463
+ },
464
+ showMoreText: {
465
+ fontFamily: AppFonts.interBold,
466
+ fontSize: 11,
467
+ color: AppColors.purple,
468
+ },
469
+ emptyTable: {
470
+ padding: 24,
471
+ alignItems: 'center',
472
+ justifyContent: 'center',
473
+ },
474
+ emptyTableText: {
475
+ fontFamily: AppFonts.interMedium,
476
+ fontSize: 12.5,
477
+ color: AppColors.slate400,
478
+ },
479
+ highlight: {
480
+ backgroundColor: '#FEF08A',
481
+ color: '#854D0E',
482
+ fontFamily: AppFonts.interBold,
483
+ },
484
+ });
485
+
486
+ export default JsonViewer;