react-native-inapp-inspector 1.1.24 → 1.1.26

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 (114) hide show
  1. package/android/build.gradle +36 -0
  2. package/android/src/main/AndroidManifest.xml +3 -0
  3. package/android/src/main/java/com/inappinspector/NetworkInspectorModule.java +114 -0
  4. package/android/src/main/java/com/inappinspector/NetworkInspectorPackage.java +28 -0
  5. package/dist/commonjs/components/AnalyticsEventCard.js +94 -88
  6. package/dist/commonjs/components/ConsoleLogCard.js +49 -25
  7. package/dist/commonjs/components/ErrorBoundary.d.ts +1 -1
  8. package/dist/commonjs/components/ErrorBoundary.js +9 -145
  9. package/dist/commonjs/components/Inspector/AnalyticsFilterModal.d.ts +7 -0
  10. package/dist/commonjs/components/Inspector/AnalyticsFilterModal.js +1002 -0
  11. package/dist/commonjs/components/Inspector/AnalyticsTab.js +637 -10
  12. package/dist/commonjs/components/Inspector/BundleTab.d.ts +1 -1
  13. package/dist/commonjs/components/Inspector/BundleTab.js +826 -406
  14. package/dist/commonjs/components/Inspector/CrashDetail.d.ts +3 -0
  15. package/dist/commonjs/components/Inspector/CrashDetail.js +796 -0
  16. package/dist/commonjs/components/Inspector/CrashFilterModal.d.ts +20 -0
  17. package/dist/commonjs/components/Inspector/CrashFilterModal.js +597 -0
  18. package/dist/commonjs/components/Inspector/CrashTab.d.ts +3 -0
  19. package/dist/commonjs/components/Inspector/CrashTab.js +727 -0
  20. package/dist/commonjs/components/Inspector/InspectorContext.js +6 -1
  21. package/dist/commonjs/components/Inspector/InspectorHeader.js +65 -28
  22. package/dist/commonjs/components/Inspector/LogDetail.js +227 -114
  23. package/dist/commonjs/components/Inspector/MainScreen.js +13 -4
  24. package/dist/commonjs/components/Inspector/NetworkDetail.js +131 -81
  25. package/dist/commonjs/components/Inspector/PerformanceTab.js +20 -10
  26. package/dist/commonjs/components/Inspector/SettingsPanel.js +90 -1
  27. package/dist/commonjs/components/Inspector/TabBar.js +15 -3
  28. package/dist/commonjs/components/NetworkIcons.d.ts +25 -0
  29. package/dist/commonjs/components/NetworkIcons.js +188 -1
  30. package/dist/commonjs/components/SegmentedTabs.js +33 -23
  31. package/dist/commonjs/components/TreeNode.js +13 -12
  32. package/dist/commonjs/constants/version.d.ts +1 -1
  33. package/dist/commonjs/constants/version.js +1 -1
  34. package/dist/commonjs/customHooks/analyticsLogger.js +70 -44
  35. package/dist/commonjs/customHooks/bundleAnalyzer.d.ts +5 -1
  36. package/dist/commonjs/customHooks/bundleAnalyzer.js +497 -126
  37. package/dist/commonjs/customHooks/consoleLogger.d.ts +1 -0
  38. package/dist/commonjs/customHooks/consoleLogger.js +153 -51
  39. package/dist/commonjs/customHooks/crashHandler.d.ts +64 -0
  40. package/dist/commonjs/customHooks/crashHandler.js +681 -0
  41. package/dist/commonjs/customHooks/networkLogger.js +74 -49
  42. package/dist/commonjs/customHooks/performanceTracker.d.ts +8 -0
  43. package/dist/commonjs/customHooks/performanceTracker.js +44 -3
  44. package/dist/commonjs/decorators/index.d.ts +49 -0
  45. package/dist/commonjs/decorators/index.js +142 -0
  46. package/dist/commonjs/helpers/gaAnalyticsRegistry.d.ts +18 -0
  47. package/dist/commonjs/helpers/gaAnalyticsRegistry.js +174 -0
  48. package/dist/commonjs/helpers/index.d.ts +7 -4
  49. package/dist/commonjs/helpers/index.js +102 -64
  50. package/dist/commonjs/i18n/locales/en.json +182 -4
  51. package/dist/commonjs/index.d.ts +6 -0
  52. package/dist/commonjs/index.js +310 -8
  53. package/dist/commonjs/styles/index.d.ts +4 -1
  54. package/dist/commonjs/styles/index.js +22 -19
  55. package/dist/commonjs/types/enums.d.ts +156 -9
  56. package/dist/commonjs/types/enums.js +139 -2
  57. package/dist/commonjs/types/interfaces.d.ts +70 -1
  58. package/dist/esm/components/AnalyticsEventCard.js +95 -89
  59. package/dist/esm/components/ConsoleLogCard.js +49 -25
  60. package/dist/esm/components/ErrorBoundary.d.ts +1 -1
  61. package/dist/esm/components/ErrorBoundary.js +10 -113
  62. package/dist/esm/components/Inspector/AnalyticsFilterModal.d.ts +7 -0
  63. package/dist/esm/components/Inspector/AnalyticsFilterModal.js +964 -0
  64. package/dist/esm/components/Inspector/AnalyticsTab.js +639 -12
  65. package/dist/esm/components/Inspector/BundleTab.d.ts +1 -1
  66. package/dist/esm/components/Inspector/BundleTab.js +827 -407
  67. package/dist/esm/components/Inspector/CrashDetail.d.ts +3 -0
  68. package/dist/esm/components/Inspector/CrashDetail.js +758 -0
  69. package/dist/esm/components/Inspector/CrashFilterModal.d.ts +20 -0
  70. package/dist/esm/components/Inspector/CrashFilterModal.js +557 -0
  71. package/dist/esm/components/Inspector/CrashTab.d.ts +3 -0
  72. package/dist/esm/components/Inspector/CrashTab.js +689 -0
  73. package/dist/esm/components/Inspector/InspectorContext.js +1 -0
  74. package/dist/esm/components/Inspector/InspectorHeader.js +66 -29
  75. package/dist/esm/components/Inspector/LogDetail.js +227 -114
  76. package/dist/esm/components/Inspector/MainScreen.js +14 -5
  77. package/dist/esm/components/Inspector/NetworkDetail.js +132 -49
  78. package/dist/esm/components/Inspector/PerformanceTab.js +20 -10
  79. package/dist/esm/components/Inspector/SettingsPanel.js +91 -2
  80. package/dist/esm/components/Inspector/TabBar.js +16 -4
  81. package/dist/esm/components/NetworkIcons.d.ts +25 -0
  82. package/dist/esm/components/NetworkIcons.js +161 -0
  83. package/dist/esm/components/SegmentedTabs.js +33 -23
  84. package/dist/esm/components/TreeNode.js +13 -12
  85. package/dist/esm/constants/version.d.ts +1 -1
  86. package/dist/esm/constants/version.js +1 -1
  87. package/dist/esm/customHooks/analyticsLogger.js +70 -44
  88. package/dist/esm/customHooks/bundleAnalyzer.d.ts +5 -1
  89. package/dist/esm/customHooks/bundleAnalyzer.js +493 -125
  90. package/dist/esm/customHooks/consoleLogger.d.ts +1 -0
  91. package/dist/esm/customHooks/consoleLogger.js +151 -50
  92. package/dist/esm/customHooks/crashHandler.d.ts +64 -0
  93. package/dist/esm/customHooks/crashHandler.js +659 -0
  94. package/dist/esm/customHooks/networkLogger.js +74 -49
  95. package/dist/esm/customHooks/performanceTracker.d.ts +8 -0
  96. package/dist/esm/customHooks/performanceTracker.js +38 -1
  97. package/dist/esm/decorators/index.d.ts +49 -0
  98. package/dist/esm/decorators/index.js +137 -0
  99. package/dist/esm/helpers/gaAnalyticsRegistry.d.ts +18 -0
  100. package/dist/esm/helpers/gaAnalyticsRegistry.js +169 -0
  101. package/dist/esm/helpers/index.d.ts +7 -4
  102. package/dist/esm/helpers/index.js +100 -63
  103. package/dist/esm/i18n/locales/en.json +182 -4
  104. package/dist/esm/index.d.ts +6 -0
  105. package/dist/esm/index.js +262 -8
  106. package/dist/esm/styles/index.d.ts +4 -1
  107. package/dist/esm/styles/index.js +22 -19
  108. package/dist/esm/types/enums.d.ts +156 -9
  109. package/dist/esm/types/enums.js +138 -3
  110. package/dist/esm/types/interfaces.d.ts +70 -1
  111. package/ios/NetworkInspectorModule.h +6 -0
  112. package/ios/NetworkInspectorModule.m +125 -0
  113. package/package.json +5 -2
  114. package/react-native-inapp-inspector.podspec +18 -0
@@ -1,37 +1,4 @@
1
1
  "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
2
  var __importDefault = (this && this.__importDefault) || function (mod) {
36
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
37
4
  };
@@ -39,7 +6,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
39
6
  const react_1 = __importDefault(require("react"));
40
7
  const i18n_1 = require("../../i18n");
41
8
  const react_native_1 = require("react-native");
42
- const react_native_svg_1 = __importStar(require("react-native-svg"));
43
9
  const InspectorContext_1 = require("./InspectorContext");
44
10
  const TouchableScale_1 = __importDefault(require("../TouchableScale"));
45
11
  const SegmentedTabs_1 = __importDefault(require("../SegmentedTabs"));
@@ -111,70 +77,122 @@ const NetworkDetail = react_1.default.memo(() => {
111
77
  <react_native_1.View style={{
112
78
  flexDirection: 'row',
113
79
  alignItems: 'center',
114
- gap: 8,
80
+ gap: 6,
81
+ flexWrap: 'wrap',
82
+ flex: 1,
115
83
  }}>
84
+ {/* Method Chip */}
116
85
  <react_native_1.View style={[
117
86
  styles_1.default.methodBadge,
118
87
  {
119
88
  backgroundColor: constants_1.METHOD_COLORS[selected.method] ?? constants_1.METHOD_COLORS.ALL,
89
+ paddingHorizontal: 8,
90
+ paddingVertical: 4,
91
+ borderRadius: 7,
120
92
  },
121
93
  ]}>
122
94
  <react_native_1.Text style={[
123
95
  styles_1.default.methodBadgeText,
124
96
  {
125
97
  color: AppColors_1.AppColors.white,
98
+ fontSize: 10.5,
126
99
  },
127
100
  ]}>
128
101
  {selected.method}
129
102
  </react_native_1.Text>
130
103
  </react_native_1.View>
131
104
 
105
+ {/* Status Pill */}
132
106
  {selected.status != null && (<react_native_1.View style={[
133
107
  styles_1.default.chip,
134
108
  {
135
109
  backgroundColor: selected.status === 0
136
- ? `${AppColors_1.AppColors.errorColor}15`
137
- : `${(0, helpers_1.getStatusColor)(selected.status)}15`,
110
+ ? `${AppColors_1.AppColors.errorColor}18`
111
+ : `${(0, helpers_1.getStatusColor)(selected.status)}18`,
138
112
  borderColor: selected.status === 0
139
113
  ? `${AppColors_1.AppColors.errorColor}40`
140
114
  : `${(0, helpers_1.getStatusColor)(selected.status)}40`,
115
+ paddingHorizontal: 7,
116
+ paddingVertical: 3.5,
117
+ borderRadius: 7,
141
118
  },
142
119
  ]}>
143
- {selected.status === 0 ? (<NetworkIcons_1.FailIcon size={8} color={AppColors_1.AppColors.errorColor}/>) : (<react_native_svg_1.default width={6} height={6} viewBox="0 0 10 10" fill="none">
144
- <react_native_svg_1.Circle cx="5" cy="5" r="5" fill={(0, helpers_1.getStatusColor)(selected.status)}/>
145
- </react_native_svg_1.default>)}
120
+ {selected.status === 0 ? (<NetworkIcons_1.FailIcon size={8} color={AppColors_1.AppColors.errorColor}/>) : (<react_native_1.View style={{
121
+ width: 6,
122
+ height: 6,
123
+ borderRadius: 3,
124
+ backgroundColor: (0, helpers_1.getStatusColor)(selected.status),
125
+ }}/>)}
146
126
  <react_native_1.Text style={[
147
127
  styles_1.default.chipText,
148
128
  {
149
129
  color: selected.status === 0
150
130
  ? AppColors_1.AppColors.errorColor
151
131
  : (0, helpers_1.getStatusColor)(selected.status),
132
+ fontFamily: AppFonts_1.AppFonts.interBold,
133
+ fontSize: 10.5,
152
134
  },
153
135
  ]}>
154
136
  {selected.status === 0
155
137
  ? 'Failed'
156
- : String(selected.status)}
138
+ : `${selected.status} ${selected.status === 200 ? 'OK' : ''}`}
157
139
  </react_native_1.Text>
158
140
  </react_native_1.View>)}
159
141
 
142
+ {/* Duration Pill */}
160
143
  {selected.duration != null && (<react_native_1.View style={[
161
144
  styles_1.default.chip,
162
145
  {
163
- backgroundColor: `${AppColors_1.AppColors.purple}14`,
164
- borderColor: `${AppColors_1.AppColors.purple}2E`,
146
+ backgroundColor: `${AppColors_1.AppColors.brandPurple}14`,
147
+ borderColor: `${AppColors_1.AppColors.brandPurple}30`,
148
+ paddingHorizontal: 7,
149
+ paddingVertical: 3.5,
150
+ borderRadius: 7,
151
+ gap: 4,
165
152
  },
166
153
  ]}>
154
+ <NetworkIcons_1.ClockIcon color={AppColors_1.AppColors.brandPurple} size={10}/>
167
155
  <react_native_1.Text style={[
168
156
  styles_1.default.chipText,
169
- { color: AppColors_1.AppColors.purple },
157
+ {
158
+ color: AppColors_1.AppColors.brandPurple,
159
+ fontFamily: AppFonts_1.AppFonts.interBold,
160
+ fontSize: 10.5,
161
+ },
170
162
  ]}>
171
163
  {selected.duration}ms
172
164
  </react_native_1.Text>
173
165
  </react_native_1.View>)}
166
+
167
+ {/* Size Pill */}
168
+ {selected.response != null && (<react_native_1.View style={[
169
+ styles_1.default.chip,
170
+ {
171
+ backgroundColor: `${AppColors_1.AppColors.sky600}14`,
172
+ borderColor: `${AppColors_1.AppColors.sky600}30`,
173
+ paddingHorizontal: 7,
174
+ paddingVertical: 3.5,
175
+ borderRadius: 7,
176
+ gap: 4,
177
+ },
178
+ ]}>
179
+ <NetworkIcons_1.SizeIcon color={AppColors_1.AppColors.sky600} size={10}/>
180
+ <react_native_1.Text style={[
181
+ styles_1.default.chipText,
182
+ {
183
+ color: AppColors_1.AppColors.sky600,
184
+ fontFamily: AppFonts_1.AppFonts.interBold,
185
+ fontSize: 10.5,
186
+ },
187
+ ]}>
188
+ {(0, helpers_1.getSize)(selected.response)}
189
+ </react_native_1.Text>
190
+ </react_native_1.View>)}
174
191
  </react_native_1.View>
192
+
175
193
  <react_native_1.View style={styles_1.default.detailInfoRight}>
176
- <TouchableScale_1.default style={styles_1.default.iconSquareBtn} onPress={() => react_native_1.Linking.openURL(detailDisplayUrl)} hitSlop={12}>
177
- <NetworkIcons_1.GlobeIcon color={AppColors_1.AppColors.grayTextWeak} size={14}/>
194
+ <TouchableScale_1.default style={[styles_1.default.iconSquareBtn, { backgroundColor: `${AppColors_1.AppColors.sky600}15` }]} onPress={() => react_native_1.Linking.openURL(detailDisplayUrl)} hitSlop={12}>
195
+ <NetworkIcons_1.ExternalLinkIcon color={AppColors_1.AppColors.sky600} size={14}/>
178
196
  </TouchableScale_1.default>
179
197
  <CopyButton_1.default value={(0, helpers_1.getFetchCommand)(selected)} label="fetch()" iconType="fetch"/>
180
198
  <CopyButton_1.default value={(0, helpers_1.getCurlCommand)(selected)} label="cURL" iconType="terminal"/>
@@ -182,67 +200,99 @@ const NetworkDetail = react_1.default.memo(() => {
182
200
  </react_native_1.View>
183
201
  </react_native_1.View>
184
202
 
203
+ {/* Full Live URL Analysis Card */}
185
204
  <react_native_1.Pressable style={{
186
205
  backgroundColor: AppColors_1.AppColors.grayBackground,
187
206
  borderRadius: 10,
188
207
  borderWidth: 1,
189
208
  borderColor: AppColors_1.AppColors.dividerColor,
190
209
  padding: 10,
191
- marginTop: 6,
210
+ marginTop: 8,
211
+ gap: 6,
192
212
  }} onPress={() => react_native_1.Linking.openURL(detailDisplayUrl)}>
193
213
  <react_native_1.View style={{
194
214
  flexDirection: 'row',
195
215
  alignItems: 'center',
196
216
  justifyContent: 'space-between',
197
- marginBottom: 2,
198
217
  }}>
199
- <react_native_1.Text style={{
200
- fontFamily: AppFonts_1.AppFonts.interMedium,
201
- fontSize: 10,
202
- color: AppColors_1.AppColors.grayTextWeak,
203
- flex: 1,
204
- }} numberOfLines={1}>
205
- {schemeStr ? (<>
218
+ <react_native_1.View style={{ flexDirection: 'row', alignItems: 'center', gap: 6 }}>
219
+ {schemeStr ? (<react_native_1.View style={{
220
+ backgroundColor: schemeStr.startsWith('https')
221
+ ? `${AppColors_1.AppColors.green600}18`
222
+ : `${AppColors_1.AppColors.amber500}18`,
223
+ paddingHorizontal: 6,
224
+ paddingVertical: 2,
225
+ borderRadius: 4,
226
+ }}>
206
227
  <react_native_1.Text style={{
207
- color: AppColors_1.AppColors.slate400,
208
- fontFamily: AppFonts_1.AppFonts.interRegular,
228
+ fontFamily: AppFonts_1.AppFonts.interBold,
229
+ fontSize: 9,
230
+ color: schemeStr.startsWith('https')
231
+ ? AppColors_1.AppColors.green600
232
+ : AppColors_1.AppColors.amber500,
209
233
  }}>
210
- {schemeStr}
234
+ {schemeStr.replace('://', '').toUpperCase()}
211
235
  </react_native_1.Text>
212
- {hostStr}
213
- </>) : (hostStr || 'API Endpoint')}
214
- </react_native_1.Text>
215
- {queryStr ? (<react_native_1.View style={{
236
+ </react_native_1.View>) : null}
237
+
238
+ <react_native_1.Text style={{
239
+ fontFamily: AppFonts_1.AppFonts.interBold,
240
+ fontSize: 10,
241
+ color: AppColors_1.AppColors.grayTextWeak,
242
+ letterSpacing: 0.4,
243
+ textTransform: 'uppercase',
244
+ }}>
245
+ ENDPOINT URL ↗
246
+ </react_native_1.Text>
247
+ </react_native_1.View>
248
+
249
+ <react_native_1.View style={{ flexDirection: 'row', alignItems: 'center', gap: 4 }}>
250
+ {queryStr ? (<react_native_1.View style={{
216
251
  backgroundColor: `${AppColors_1.AppColors.purple}14`,
217
- paddingHorizontal: 5,
218
- paddingVertical: 1,
252
+ paddingHorizontal: 6,
253
+ paddingVertical: 2,
219
254
  borderRadius: 4,
220
255
  }}>
221
- <react_native_1.Text style={{
256
+ <react_native_1.Text style={{
222
257
  fontFamily: AppFonts_1.AppFonts.interBold,
223
258
  fontSize: 8.5,
224
259
  color: AppColors_1.AppColors.purple,
225
260
  }}>
226
- {t('network.queryParams')}
261
+ {t('network.queryParams')}
262
+ </react_native_1.Text>
263
+ </react_native_1.View>) : null}
264
+
265
+ <react_native_1.View style={{
266
+ flexDirection: 'row',
267
+ alignItems: 'center',
268
+ gap: 3,
269
+ backgroundColor: `${AppColors_1.AppColors.sky600}14`,
270
+ paddingHorizontal: 6,
271
+ paddingVertical: 2,
272
+ borderRadius: 4,
273
+ }}>
274
+ <NetworkIcons_1.ExternalLinkIcon color={AppColors_1.AppColors.sky600} size={10}/>
275
+ <react_native_1.Text style={{
276
+ fontFamily: AppFonts_1.AppFonts.interBold,
277
+ fontSize: 9,
278
+ color: AppColors_1.AppColors.sky600,
279
+ }}>
280
+ Open ↗
227
281
  </react_native_1.Text>
228
- </react_native_1.View>) : null}
282
+ </react_native_1.View>
283
+ </react_native_1.View>
229
284
  </react_native_1.View>
285
+
286
+ {/* Full Clickable Hyperlink */}
230
287
  <react_native_1.Text selectable={true} style={{
231
- fontFamily: AppFonts_1.AppFonts.interBold,
232
- fontSize: 12,
233
- color: AppColors_1.AppColors.primaryBlack,
234
- marginTop: 2,
235
- }} numberOfLines={2}>
236
- {pathStr}
288
+ fontFamily: AppFonts_1.AppFonts.interMedium,
289
+ fontSize: 12.5,
290
+ color: AppColors_1.AppColors.skyBlue,
291
+ textDecorationLine: 'underline',
292
+ lineHeight: 18,
293
+ }}>
294
+ {detailDisplayUrl}
237
295
  </react_native_1.Text>
238
- {queryStr ? (<react_native_1.Text selectable={true} style={{
239
- fontFamily: AppFonts_1.AppFonts.interRegular,
240
- fontSize: 10,
241
- color: AppColors_1.AppColors.grayTextWeak,
242
- marginTop: 4,
243
- }} numberOfLines={1}>
244
- {queryStr}
245
- </react_native_1.Text>) : null}
246
296
  </react_native_1.Pressable>
247
297
  </>);
248
298
  })()}
@@ -47,6 +47,7 @@ const AppFonts_1 = require("../../styles/AppFonts");
47
47
  const i18n_1 = require("../../i18n");
48
48
  const helpers_1 = require("../../helpers");
49
49
  const NetworkIcons_1 = require("../NetworkIcons");
50
+ const performanceTracker_1 = require("../../customHooks/performanceTracker");
50
51
  const PerformanceTab = react_1.default.memo(() => {
51
52
  const { t } = (0, i18n_1.useTranslation)();
52
53
  // ─── Real-Time FPS Tracking ────────────────────────────────────────────────
@@ -72,10 +73,16 @@ const PerformanceTab = react_1.default.memo(() => {
72
73
  const [fpsHistory, setFpsHistory] = (0, react_1.useState)([
73
74
  60, 59, 60, 60, 58, 60, 59, 60, 60, 60, 57, 60, 59, 60, 60, 58, 60, 60, 59, 60,
74
75
  ]);
75
- // Performance Log Events
76
- const [events, setEvents] = (0, react_1.useState)([]);
76
+ // Performance Log Events (Initialized with benchmark & diagnostics events)
77
+ const [events, setEvents] = (0, react_1.useState)(performanceTracker_1.INITIAL_EVENTS);
77
78
  const [filterCategory, setFilterCategory] = (0, react_1.useState)('ALL');
78
79
  const [search, setSearch] = (0, react_1.useState)('');
80
+ (0, react_1.useEffect)(() => {
81
+ const unsub = (0, performanceTracker_1.subscribePerformanceEvents)(liveEvents => {
82
+ setEvents(liveEvents);
83
+ });
84
+ return unsub;
85
+ }, []);
79
86
  // ─── Live Frame Measurement Loop (1-Second Batch Interval) ────────────────
80
87
  const lastFrameTimeRef = (0, react_1.useRef)(Date.now());
81
88
  const rafIdRef = (0, react_1.useRef)(null);
@@ -119,9 +126,7 @@ const PerformanceTab = react_1.default.memo(() => {
119
126
  // Trigger log if noticeable frame drop
120
127
  if (measuredFps < 50) {
121
128
  const durationStr = (1000 / measuredFps).toFixed(1);
122
- const newEvent = {
123
- id: `drop-${Date.now()}`,
124
- timestamp: Date.now(),
129
+ (0, performanceTracker_1.logPerformanceEvent)({
125
130
  type: 'fps_drop',
126
131
  category: 'render',
127
132
  fps: measuredFps,
@@ -135,8 +140,7 @@ const PerformanceTab = react_1.default.memo(() => {
135
140
  },
136
141
  advice: t('performance.liveFpsDipAdvice'),
137
142
  severity: measuredFps < 30 ? 'critical' : 'warning',
138
- };
139
- setEvents(prev => [newEvent, ...prev.slice(0, 49)]);
143
+ });
140
144
  }
141
145
  frameCount = 0;
142
146
  maxLagInSecond = 0;
@@ -246,7 +250,7 @@ const PerformanceTab = react_1.default.memo(() => {
246
250
  };
247
251
  }, [avgFps, jsLagMs]);
248
252
  const clearEvents = () => {
249
- setEvents([]);
253
+ (0, performanceTracker_1.clearPerformanceEvents)();
250
254
  };
251
255
  return (<react_native_1.View style={perfStyles.container}>
252
256
  {/* Search & Live Control Header */}
@@ -291,9 +295,9 @@ const PerformanceTab = react_1.default.memo(() => {
291
295
  </react_native_1.View>
292
296
  </react_native_1.View>
293
297
 
294
- {/* Filter Tabs */}
298
+ {/* ─── Frozen Interactive Filter Tabs Under Search Component ─── */}
295
299
  <react_native_1.View style={perfStyles.filterRow}>
296
- <react_native_1.ScrollView horizontal showsHorizontalScrollIndicator={false} contentContainerStyle={{ gap: 6, paddingHorizontal: 12, paddingVertical: 4 }}>
300
+ <react_native_1.ScrollView horizontal showsHorizontalScrollIndicator={false} contentContainerStyle={perfStyles.filterScrollContent}>
297
301
  {[
298
302
  { key: 'ALL', label: t('performance.allLogs'), Icon: NetworkIcons_1.BoltIcon, count: events.length },
299
303
  {
@@ -690,6 +694,12 @@ const perfStyles = react_native_1.StyleSheet.create({
690
694
  backgroundColor: AppColors_1.AppColors.white,
691
695
  borderBottomWidth: 1,
692
696
  borderBottomColor: AppColors_1.AppColors.dividerColor,
697
+ paddingVertical: 5,
698
+ },
699
+ filterScrollContent: {
700
+ gap: 6,
701
+ paddingHorizontal: 12,
702
+ paddingVertical: 2,
693
703
  },
694
704
  filterPill: {
695
705
  flexDirection: 'row',
@@ -50,9 +50,10 @@ const settingsStore_1 = require("../../helpers/settingsStore");
50
50
  const networkLogger_1 = require("../../customHooks/networkLogger");
51
51
  const consoleLogger_1 = require("../../customHooks/consoleLogger");
52
52
  const analyticsLogger_1 = require("../../customHooks/analyticsLogger");
53
+ const crashHandler_1 = require("../../customHooks/crashHandler");
53
54
  const NetworkIcons_1 = require("../NetworkIcons");
54
55
  const SettingsPanel = () => {
55
- const { settingsPage, setSettingsPage, settingsActiveSubTab, setSettingsActiveSubTab, tabVisibility, toggleTabVisibility, defaultTab, setDefaultTab, isDark, setIsDark, modalHeightPercent, setModalHeightPercent, modalAnimationType, setModalAnimationType, showDuplicateLogs, setShowDuplicateLogs, showConsoleLevels, setShowConsoleLevels, resetToDefaults, storage, logs, consoleLogs, analyticsEvents, reduxState, maxNetworkLogs, setMaxNetworkLogs, maxConsoleLogs, setMaxConsoleLogs, reduxAutoRefresh, setReduxAutoRefreshState, reduxExpandDepth, setReduxExpandDepth, switchActiveTab, setSelected, setSelectedEvent, setReduxState, } = (0, InspectorContext_1.useInspector)();
56
+ const { settingsPage, setSettingsPage, settingsActiveSubTab, setSettingsActiveSubTab, tabVisibility, toggleTabVisibility, defaultTab, setDefaultTab, isDark, setIsDark, modalHeightPercent, setModalHeightPercent, modalAnimationType, setModalAnimationType, showDuplicateLogs, setShowDuplicateLogs, showConsoleLevels, setShowConsoleLevels, resetToDefaults, storage, logs, consoleLogs, analyticsEvents, reduxState, maxNetworkLogs, setMaxNetworkLogs, maxConsoleLogs, setMaxConsoleLogs, reduxAutoRefresh, setReduxAutoRefreshState, reduxExpandDepth, setReduxExpandDepth, switchActiveTab, setSelected, setSelectedEvent, setReduxState, crashRecords, maxCrashLogs, setMaxCrashLogs, } = (0, InspectorContext_1.useInspector)();
56
57
  const isPersistent = (0, settingsStore_1.isPersistentStorageAvailable)();
57
58
  const headerTopPadding = react_native_1.Platform.OS === 'ios' && modalHeightPercent >= 95 ? 44 : 0;
58
59
  if (settingsPage === 'main') {
@@ -63,6 +64,7 @@ const SettingsPanel = () => {
63
64
  { key: 'redux', label: 'Redux', icon: 'redux' },
64
65
  { key: 'bundle', label: 'Bundle', icon: 'bundle' },
65
66
  { key: 'performance', label: 'Performance', icon: 'performance' },
67
+ { key: 'crash', label: 'Crash', icon: 'crash' },
66
68
  ];
67
69
  return (<react_native_1.View style={{ flex: 1, backgroundColor: AppColors_1.AppColors.grayBackground }}>
68
70
  {/* Settings Header with back button */}
@@ -273,6 +275,9 @@ const SettingsPanel = () => {
273
275
  {tab.icon === 'performance' && (<NetworkIcons_1.PerformanceIcon color={isLocked
274
276
  ? AppColors_1.AppColors.grayTextWeak
275
277
  : AppColors_1.AppColors.purple} size={11}/>)}
278
+ {tab.icon === 'crash' && (<NetworkIcons_1.CrashIcon color={isLocked
279
+ ? AppColors_1.AppColors.grayTextWeak
280
+ : AppColors_1.AppColors.purple} size={11}/>)}
276
281
  </react_native_1.View>
277
282
  {/* Label + Required badge */}
278
283
  <react_native_1.Text style={{
@@ -712,6 +717,7 @@ const SettingsPanel = () => {
712
717
  {tab.icon === 'redux' && (<NetworkIcons_1.ReduxIcon color={isActive ? AppColors_1.AppColors.white : AppColors_1.AppColors.purple} size={11}/>)}
713
718
  {tab.icon === 'bundle' && (<NetworkIcons_1.PackageIcon color={isActive ? AppColors_1.AppColors.white : AppColors_1.AppColors.purple} size={11}/>)}
714
719
  {tab.icon === 'performance' && (<NetworkIcons_1.PerformanceIcon color={isActive ? AppColors_1.AppColors.white : AppColors_1.AppColors.purple} size={11}/>)}
720
+ {tab.icon === 'crash' && (<NetworkIcons_1.CrashIcon color={isActive ? AppColors_1.AppColors.white : AppColors_1.AppColors.purple} size={11}/>)}
715
721
  </react_native_1.View>
716
722
  <react_native_1.Text style={{
717
723
  fontFamily: AppFonts_1.AppFonts.interBold,
@@ -1430,6 +1436,89 @@ const SettingsPanel = () => {
1430
1436
  </react_native_1.View>
1431
1437
  </react_native_1.ScrollView>);
1432
1438
  }
1439
+ else if (settingsPage === 'crash') {
1440
+ title = 'Crash Settings';
1441
+ icon = <NetworkIcons_1.CrashIcon color={AppColors_1.AppColors.white} size={16}/>;
1442
+ rightInfo = `Total: ${crashRecords?.length || 0}`;
1443
+ content = (<react_native_1.ScrollView style={{ flex: 1 }} contentContainerStyle={{ padding: 16 }}>
1444
+ <react_native_1.View style={{
1445
+ backgroundColor: AppColors_1.AppColors.primaryLight,
1446
+ padding: 16,
1447
+ borderRadius: 12,
1448
+ borderWidth: 1,
1449
+ borderColor: AppColors_1.AppColors.grayBorderSecondary,
1450
+ gap: 4,
1451
+ }}>
1452
+ {renderSettingRow({
1453
+ icon: <NetworkIcons_1.LayersIcon color={AppColors_1.AppColors.purple} size={16}/>,
1454
+ label: 'Max Crash Logs',
1455
+ description: 'How many crash records to preserve in history',
1456
+ picker: {
1457
+ options: [25, 50, 100, 200],
1458
+ selectedValue: maxCrashLogs || 100,
1459
+ onSelect: val => setMaxCrashLogs(val),
1460
+ },
1461
+ })}
1462
+ <react_native_1.View style={{ height: 1, backgroundColor: AppColors_1.AppColors.dividerColor }}/>
1463
+ {renderSettingRow({
1464
+ icon: <NetworkIcons_1.ShieldAlertIcon color={AppColors_1.AppColors.greenColor} size={16}/>,
1465
+ label: 'Global Crash Guard',
1466
+ description: 'Intercepts native, JS, and render errors directly',
1467
+ isLast: true,
1468
+ right: (<react_native_1.View style={{
1469
+ paddingHorizontal: 8,
1470
+ paddingVertical: 4,
1471
+ borderRadius: 6,
1472
+ backgroundColor: `${AppColors_1.AppColors.greenColor}1F`,
1473
+ }}>
1474
+ <react_native_1.Text style={{
1475
+ fontFamily: AppFonts_1.AppFonts.interBold,
1476
+ fontSize: 10,
1477
+ color: AppColors_1.AppColors.greenColor,
1478
+ }}>
1479
+ PROTECTED
1480
+ </react_native_1.Text>
1481
+ </react_native_1.View>),
1482
+ })}
1483
+ </react_native_1.View>
1484
+
1485
+ <react_native_1.View style={{
1486
+ backgroundColor: AppColors_1.AppColors.primaryLight,
1487
+ borderRadius: 12,
1488
+ borderWidth: 1,
1489
+ borderColor: AppColors_1.AppColors.grayBorderSecondary,
1490
+ padding: 16,
1491
+ marginTop: 12,
1492
+ }}>
1493
+ {renderSettingRow({
1494
+ icon: <NetworkIcons_1.TrashIcon color={AppColors_1.AppColors.errorColor} size={16}/>,
1495
+ label: 'Clear Crash History',
1496
+ description: `${crashRecords?.length || 0} crash logs stored`,
1497
+ isLast: true,
1498
+ onPress: () => {
1499
+ (0, crashHandler_1.clearCrashRecords)();
1500
+ react_native_1.Alert.alert('Success', 'Crash logs cleared.');
1501
+ },
1502
+ right: (<react_native_1.View style={{
1503
+ paddingHorizontal: 10,
1504
+ paddingVertical: 5,
1505
+ borderRadius: 7,
1506
+ backgroundColor: `${AppColors_1.AppColors.errorColor}14`,
1507
+ borderWidth: 1,
1508
+ borderColor: `${AppColors_1.AppColors.errorColor}33`,
1509
+ }}>
1510
+ <react_native_1.Text style={{
1511
+ fontFamily: AppFonts_1.AppFonts.interBold,
1512
+ fontSize: 11,
1513
+ color: AppColors_1.AppColors.errorColor,
1514
+ }}>
1515
+ Clear
1516
+ </react_native_1.Text>
1517
+ </react_native_1.View>),
1518
+ })}
1519
+ </react_native_1.View>
1520
+ </react_native_1.ScrollView>);
1521
+ }
1433
1522
  return (<react_native_1.View style={{ flex: 1, backgroundColor: AppColors_1.AppColors.grayBackground }}>
1434
1523
  <react_native_linear_gradient_1.default colors={[AppColors_1.AppColors.purple, AppColors_1.AppColors.brandPurple]} start={{ x: 0, y: 0 }} end={{ x: 1, y: 0 }} style={styles_1.default.headerGradient}>
1435
1524
  <react_native_1.View style={{ paddingTop: headerTopPadding, width: '100%' }}>
@@ -11,7 +11,7 @@ const styles_1 = __importDefault(require("../../styles"));
11
11
  const AppColors_1 = require("../../styles/AppColors");
12
12
  const NetworkIcons_1 = require("../NetworkIcons");
13
13
  const TabBar = react_1.default.memo(() => {
14
- const { activeTab, switchActiveTab, tabVisibility, logs, consoleLogs, analyticsEvents, lastReadApisCount, lastReadLogsCount, unreadPulseAnim, } = (0, InspectorContext_1.useInspector)();
14
+ const { activeTab, switchActiveTab, tabVisibility, logs, consoleLogs, analyticsEvents, crashRecords, lastReadApisCount, lastReadLogsCount, lastReadCrashesCount, unreadPulseAnim, } = (0, InspectorContext_1.useInspector)();
15
15
  return (<react_native_1.View style={styles_1.default.tabBarContainer}>
16
16
  <react_native_1.ScrollView horizontal showsHorizontalScrollIndicator={false} contentContainerStyle={{ paddingRight: 16 }}>
17
17
  {[
@@ -51,18 +51,28 @@ const TabBar = react_1.default.memo(() => {
51
51
  count: 0,
52
52
  icon: 'performance',
53
53
  },
54
+ {
55
+ key: 'crash',
56
+ label: 'Crash',
57
+ count: crashRecords?.length || 0,
58
+ icon: 'crash',
59
+ },
54
60
  ]
55
61
  .filter(tab => tabVisibility?.[tab.key])
56
62
  .map(tab => {
57
63
  const isActive = activeTab === tab.key;
58
64
  const iconColor = isActive
59
65
  ? AppColors_1.AppColors.white
60
- : AppColors_1.AppColors.grayText;
66
+ : tab.key === 'crash' && tab.count > 0
67
+ ? AppColors_1.AppColors.errorColor
68
+ : AppColors_1.AppColors.grayText;
61
69
  const countLabel = tab.count > 9 ? '9+' : String(tab.count);
62
70
  const hasUnreadApis = activeTab !== 'apis' &&
63
71
  logs.length > lastReadApisCount;
64
72
  const hasUnreadLogs = activeTab !== 'logs' &&
65
73
  consoleLogs.length > lastReadLogsCount;
74
+ const hasUnreadCrashes = activeTab !== 'crash' &&
75
+ (crashRecords?.length || 0) > (lastReadCrashesCount || 0);
66
76
  return (<TouchableScale_1.default key={tab.key} onPress={() => switchActiveTab(tab.key)} style={[
67
77
  styles_1.default.contentTabButton,
68
78
  isActive && styles_1.default.contentTabButtonActive,
@@ -78,6 +88,7 @@ const TabBar = react_1.default.memo(() => {
78
88
  {tab.icon === 'redux' && (<NetworkIcons_1.ReduxIcon color={iconColor} size={14}/>)}
79
89
  {tab.icon === 'bundle' && (<NetworkIcons_1.PackageIcon color={iconColor} size={14}/>)}
80
90
  {tab.icon === 'performance' && (<NetworkIcons_1.PerformanceIcon color={iconColor} size={14}/>)}
91
+ {tab.icon === 'crash' && (<NetworkIcons_1.CrashIcon color={iconColor} size={14}/>)}
81
92
  <react_native_1.Text numberOfLines={1} ellipsizeMode="tail" style={[
82
93
  styles_1.default.contentTabButtonText,
83
94
  isActive &&
@@ -87,7 +98,8 @@ const TabBar = react_1.default.memo(() => {
87
98
  {tab.count > 0 ? `(${countLabel})` : ''}
88
99
  </react_native_1.Text>
89
100
  {((tab.key === 'apis' && hasUnreadApis) ||
90
- (tab.key === 'logs' && hasUnreadLogs)) && (<react_native_1.Animated.View style={{
101
+ (tab.key === 'logs' && hasUnreadLogs) ||
102
+ (tab.key === 'crash' && hasUnreadCrashes)) && (<react_native_1.Animated.View style={{
91
103
  width: 6,
92
104
  height: 6,
93
105
  borderRadius: 3,
@@ -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,27 @@ 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;
95
+ export declare const CrashIcon: ({ color, size, }: any) => React.JSX.Element;
96
+ export declare const ShieldAlertIcon: ({ color, size, }: any) => React.JSX.Element;
97
+ export declare const SkullIcon: ({ color, size, }: any) => React.JSX.Element;
98
+ export declare const ChipIcon: ({ color, size, }: any) => React.JSX.Element;
99
+ export declare const LayoutIcon: ({ color, size, }: any) => React.JSX.Element;
100
+ export declare const StackTraceIcon: ({ color, size, }: any) => React.JSX.Element;
101
+ export declare const DiagnosticsIcon: ({ color, size, }: any) => React.JSX.Element;
102
+ export declare const TrailIcon: ({ color, size, }: any) => React.JSX.Element;
103
+ export declare const RawJsonIcon: ({ color, size, }: any) => React.JSX.Element;
104
+ export declare const AppFramesIcon: ({ color, size, }: any) => React.JSX.Element;
105
+ export declare const AllFramesIcon: ({ color, size, }: any) => React.JSX.Element;