react-native-inapp-inspector 2.0.4 → 2.0.6

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 (108) hide show
  1. package/android/.gradle/8.9/checksums/checksums.lock +0 -0
  2. package/android/.gradle/8.9/checksums/md5-checksums.bin +0 -0
  3. package/android/.gradle/8.9/checksums/sha1-checksums.bin +0 -0
  4. package/android/.gradle/8.9/dependencies-accessors/gc.properties +0 -0
  5. package/android/.gradle/8.9/executionHistory/executionHistory.lock +0 -0
  6. package/android/.gradle/8.9/fileChanges/last-build.bin +0 -0
  7. package/android/.gradle/8.9/fileHashes/fileHashes.lock +0 -0
  8. package/android/.gradle/8.9/gc.properties +0 -0
  9. package/android/.gradle/9.2.0/checksums/checksums.lock +0 -0
  10. package/android/.gradle/9.2.0/fileChanges/last-build.bin +0 -0
  11. package/android/.gradle/9.2.0/fileHashes/fileHashes.bin +0 -0
  12. package/android/.gradle/9.2.0/fileHashes/fileHashes.lock +0 -0
  13. package/android/.gradle/9.2.0/gc.properties +0 -0
  14. package/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
  15. package/android/.gradle/buildOutputCleanup/cache.properties +2 -0
  16. package/android/.gradle/vcs-1/gc.properties +0 -0
  17. package/android/build/reports/problems/problems-report.html +659 -0
  18. package/android/src/main/java/com/inappinspector/NetworkInspectorModule.kt +11 -0
  19. package/dist/commonjs/components/Inspector/AuditTab.d.ts +3 -0
  20. package/dist/commonjs/components/Inspector/AuditTab.js +741 -0
  21. package/dist/commonjs/components/Inspector/DeviceTab.d.ts +3 -0
  22. package/dist/commonjs/components/Inspector/DeviceTab.js +717 -0
  23. package/dist/commonjs/components/Inspector/InspectorHeader.js +115 -75
  24. package/dist/commonjs/components/Inspector/MainScreen.js +16 -2
  25. package/dist/commonjs/components/Inspector/NetworkDetail.js +15 -0
  26. package/dist/commonjs/components/Inspector/NetworkTab.js +317 -12
  27. package/dist/commonjs/components/Inspector/NpmUpdateToast.js +88 -39
  28. package/dist/commonjs/components/Inspector/PerformanceHud.d.ts +7 -0
  29. package/dist/commonjs/components/Inspector/PerformanceHud.js +210 -0
  30. package/dist/commonjs/components/Inspector/PerformanceTab.js +30 -18
  31. package/dist/commonjs/components/Inspector/RequestReplayModal.d.ts +9 -0
  32. package/dist/commonjs/components/Inspector/RequestReplayModal.js +792 -0
  33. package/dist/commonjs/components/Inspector/RequestReplayView.d.ts +8 -0
  34. package/dist/commonjs/components/Inspector/RequestReplayView.js +871 -0
  35. package/dist/commonjs/components/Inspector/SettingsPanel.js +847 -370
  36. package/dist/commonjs/components/Inspector/StorageTab.d.ts +3 -0
  37. package/dist/commonjs/components/Inspector/StorageTab.js +610 -0
  38. package/dist/commonjs/components/Inspector/TabBar.js +23 -2
  39. package/dist/commonjs/components/Inspector/UpdateAvailableModal.d.ts +8 -0
  40. package/dist/commonjs/components/Inspector/UpdateAvailableModal.js +469 -0
  41. package/dist/commonjs/components/NetworkIcons.d.ts +12 -0
  42. package/dist/commonjs/components/NetworkIcons.js +72 -3
  43. package/dist/commonjs/constants/version.d.ts +1 -1
  44. package/dist/commonjs/constants/version.js +1 -1
  45. package/dist/commonjs/customHooks/storageInspector.d.ts +13 -0
  46. package/dist/commonjs/customHooks/storageInspector.js +179 -0
  47. package/dist/commonjs/helpers/deviceInfo.d.ts +4 -0
  48. package/dist/commonjs/helpers/deviceInfo.js +94 -0
  49. package/dist/commonjs/helpers/index.d.ts +2 -0
  50. package/dist/commonjs/helpers/index.js +12 -1
  51. package/dist/commonjs/helpers/packageAuditor.d.ts +5 -0
  52. package/dist/commonjs/helpers/packageAuditor.js +182 -0
  53. package/dist/commonjs/helpers/searchQueryParser.d.ts +8 -3
  54. package/dist/commonjs/helpers/searchQueryParser.js +85 -31
  55. package/dist/commonjs/helpers/telemetry.js +4 -4
  56. package/dist/commonjs/i18n/locales/en.json +3 -2
  57. package/dist/commonjs/index.d.ts +1 -0
  58. package/dist/commonjs/index.js +171 -16
  59. package/dist/commonjs/native/NativeInspector.d.ts +1 -0
  60. package/dist/commonjs/types/enums.d.ts +7 -0
  61. package/dist/commonjs/types/enums.js +7 -0
  62. package/dist/commonjs/types/interfaces.d.ts +82 -0
  63. package/dist/esm/components/Inspector/AuditTab.d.ts +3 -0
  64. package/dist/esm/components/Inspector/AuditTab.js +702 -0
  65. package/dist/esm/components/Inspector/DeviceTab.d.ts +3 -0
  66. package/dist/esm/components/Inspector/DeviceTab.js +678 -0
  67. package/dist/esm/components/Inspector/InspectorHeader.js +115 -75
  68. package/dist/esm/components/Inspector/MainScreen.js +16 -2
  69. package/dist/esm/components/Inspector/NetworkDetail.js +16 -1
  70. package/dist/esm/components/Inspector/NetworkTab.js +317 -12
  71. package/dist/esm/components/Inspector/NpmUpdateToast.js +88 -39
  72. package/dist/esm/components/Inspector/PerformanceHud.d.ts +7 -0
  73. package/dist/esm/components/Inspector/PerformanceHud.js +170 -0
  74. package/dist/esm/components/Inspector/PerformanceTab.js +31 -19
  75. package/dist/esm/components/Inspector/RequestReplayModal.d.ts +9 -0
  76. package/dist/esm/components/Inspector/RequestReplayModal.js +752 -0
  77. package/dist/esm/components/Inspector/RequestReplayView.d.ts +8 -0
  78. package/dist/esm/components/Inspector/RequestReplayView.js +831 -0
  79. package/dist/esm/components/Inspector/SettingsPanel.js +848 -371
  80. package/dist/esm/components/Inspector/StorageTab.d.ts +3 -0
  81. package/dist/esm/components/Inspector/StorageTab.js +571 -0
  82. package/dist/esm/components/Inspector/TabBar.js +24 -3
  83. package/dist/esm/components/Inspector/UpdateAvailableModal.d.ts +8 -0
  84. package/dist/esm/components/Inspector/UpdateAvailableModal.js +432 -0
  85. package/dist/esm/components/NetworkIcons.d.ts +12 -0
  86. package/dist/esm/components/NetworkIcons.js +57 -0
  87. package/dist/esm/constants/version.d.ts +1 -1
  88. package/dist/esm/constants/version.js +1 -1
  89. package/dist/esm/customHooks/storageInspector.d.ts +13 -0
  90. package/dist/esm/customHooks/storageInspector.js +170 -0
  91. package/dist/esm/helpers/deviceInfo.d.ts +4 -0
  92. package/dist/esm/helpers/deviceInfo.js +89 -0
  93. package/dist/esm/helpers/index.d.ts +2 -0
  94. package/dist/esm/helpers/index.js +10 -0
  95. package/dist/esm/helpers/packageAuditor.d.ts +5 -0
  96. package/dist/esm/helpers/packageAuditor.js +173 -0
  97. package/dist/esm/helpers/searchQueryParser.d.ts +8 -3
  98. package/dist/esm/helpers/searchQueryParser.js +85 -31
  99. package/dist/esm/helpers/telemetry.js +4 -4
  100. package/dist/esm/i18n/locales/en.json +3 -2
  101. package/dist/esm/index.d.ts +1 -0
  102. package/dist/esm/index.js +167 -15
  103. package/dist/esm/native/NativeInspector.d.ts +1 -0
  104. package/dist/esm/types/enums.d.ts +7 -0
  105. package/dist/esm/types/enums.js +7 -0
  106. package/dist/esm/types/interfaces.d.ts +82 -0
  107. package/ios/NetworkInspectorModule.mm +12 -5
  108. package/package.json +4 -1
@@ -50,8 +50,9 @@
50
50
  "activeBadge": "ACTIVE",
51
51
  "dormantBadge": "DORMANT",
52
52
  "protectedBadge": "PROTECTED",
53
- "modulesAndTools": "Modules & Tools",
54
- "uiPreferences": "UI Preferences",
53
+ "modulesAndTools": "Modules & Tabs",
54
+ "ramLimits": "RAM & Limits",
55
+ "uiPreferences": "UI & Appearance",
55
56
  "zeroOverheadTitle": "Zero Background Overhead",
56
57
  "zeroOverheadDesc": "Check the modules you wish to activate. Disabled modules consume 0% CPU & memory until saved.",
57
58
  "unsavedPending": "● Unsaved selections pending",
@@ -14,5 +14,6 @@ export { usePerformanceTracker, useComponentProfiler, useNavigationProfiler, tra
14
14
  export { InspectLog, InspectTrackTime, InspectCatch, type InspectLogOptions, } from './decorators';
15
15
  export { getNativeDeviceMetrics, enableNativeCrashProtection, subscribeNativeCrashes, showNativeFloatingButton, hideNativeFloatingButton, setNativeFloatingButtonBadge, subscribeNativeFloatingButtonPress, subscribeNativeDeviceShake, startNativeFpsMonitoring, stopNativeFpsMonitoring, getNativeFpsMetrics, getNativeStorageItem, setNativeStorageItem, isNativeModuleAvailable, type NativeDeviceMetrics, type NativeCrashEvent, type FloatingButtonOptions, type NativeFpsMetrics, } from './native/NativeInspector';
16
16
  export { sendSessionTelemetryPing, trackTelemetryEvent, trackInspectorOpen, trackTabSwitch, trackLogExport, GA4_MEASUREMENT_ID, GA4_API_SECRET, } from './helpers';
17
+ export { runLivePackageAudit, logCodeQualityIssue, clearCustomAuditIssues, } from './helpers/packageAuditor';
17
18
  export { BrandSquareIcon, BrandCircleIcon, } from './components/NetworkIcons';
18
19
  export { ActiveTab, Method, StatusFilter, SortOrder, LocalFilter, ModalAnimationType, SettingsPage, SettingsSubTab, LogFilter, ConsoleLogType, AnalyticsEventSource, GAEventCategory, StackFrameType, DiffResultType, BundleSubTab, PerformanceSubTab, CrashType, CrashExportFormat, CrashDetailSubTab, CrashFilterType, BreadcrumbType, } from './types';
package/dist/esm/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import React, { useEffect, useMemo, useRef, useState, useCallback } from 'react';
2
- import { Alert, Animated, PanResponder, Platform, UIManager, LogBox, InteractionManager, } from 'react-native';
2
+ import { Alert, Animated, PanResponder, Platform, UIManager, LogBox, InteractionManager, View, StyleSheet, } from 'react-native';
3
3
  import { NavigationContext } from '@react-navigation/native';
4
4
  // i18n
5
5
  import { I18nextProvider, i18n } from './i18n';
@@ -23,14 +23,22 @@ import { subscribeAnalyticsEvents, clearAnalyticsEvents, autoSetupAnalyticsLogge
23
23
  import { getReduxState, subscribeReduxState, setReduxAutoRefresh, getLastActionForReducer, clearActionHistory, isReduxConnected, setReduxModuleEnabled, } from './customHooks/reduxLogger';
24
24
  import { setPerformanceModuleEnabled } from './customHooks/performanceTracker';
25
25
  import { setBundleModuleEnabled } from './customHooks/bundleAnalyzer';
26
+ import { fetchAllStorageEntries, setStorageItem, removeStorageItem, clearAllStorage, subscribeStorageChanges, } from './customHooks/storageInspector';
27
+ import { getSystemDiagnostics } from './helpers/deviceInfo';
28
+ import { runLivePackageAudit, subscribeAuditChanges, logCodeQualityIssue, } from './helpers/packageAuditor';
26
29
  import { showNativeFloatingButton, hideNativeFloatingButton, setNativeFloatingButtonBadge, subscribeNativeFloatingButtonPress, subscribeNativeDeviceShake, isNativeModuleAvailable, } from './native/NativeInspector';
27
30
  import { LIB_VERSION } from './constants';
28
31
  // Stylesheet
29
32
  import { toggleGlobalTheme } from './styles';
30
- const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigationRef, appIcon, environment, initialVisible, visible: controlledVisible, }) => {
33
+ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigationRef, appIcon, environment, initialVisible, visible: controlledVisible, initialTab, enablePerformanceHud = false, }) => {
34
+ // Zero-overhead production stub: if disabled, return null immediately
35
+ if (!enabled || !isEnabled) {
36
+ return null;
37
+ }
31
38
  // Set custom storage synchronously during render phase
32
39
  setCustomStorage(storage || null);
33
40
  const [isDark, setIsDark] = useState(false);
41
+ const [isPerformanceHudEnabled, setIsPerformanceHudEnabled] = useState(enablePerformanceHud);
34
42
  const [reduxState, setReduxState] = useState(null);
35
43
  // Per-reducer last action is kept in component state so the
36
44
  // Redux tab re-renders live on every dispatch, independent of the state tree ref.
@@ -45,10 +53,19 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
45
53
  setVisible(controlledVisible);
46
54
  }
47
55
  }, [controlledVisible]);
56
+ useEffect(() => {
57
+ if (enablePerformanceHud !== undefined) {
58
+ setIsPerformanceHudEnabled(enablePerformanceHud);
59
+ }
60
+ }, [enablePerformanceHud]);
48
61
  const [isReady, setIsReady] = useState(false);
49
62
  const [selected, setSelected] = useState(null);
50
63
  const [selectedLogs, setSelectedLogs] = useState(new Set());
51
64
  const [search, setSearch] = useState('');
65
+ const [searchScope, setSearchScope] = useState('all');
66
+ const [isRegexSearch, setIsRegexSearch] = useState(false);
67
+ const [isCaseSensitive, setIsCaseSensitive] = useState(false);
68
+ const [quickFilter, setQuickFilter] = useState('all');
52
69
  const [detailSearch, setDetailSearch] = useState('');
53
70
  const [reduxSearch, setReduxSearch] = useState('');
54
71
  const [selectedReduxSlice, setSelectedReduxSlice] = useState(null);
@@ -80,7 +97,7 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
80
97
  const [showReqDiff, setShowReqDiff] = useState(false);
81
98
  const [showResDiff, setShowResDiff] = useState(false);
82
99
  // ─── Analytics state ───────────────────────────────────────────────────────
83
- const [activeTab, setActiveTab] = useState('apis');
100
+ const [activeTab, setActiveTab] = useState(initialTab || 'apis');
84
101
  const [analyticsEvents, setAnalyticsEvents] = useState([]);
85
102
  // ─── Logs state ────────────────────────────────────────────────────────────
86
103
  const [consoleLogs, setConsoleLogs] = useState([]);
@@ -136,6 +153,47 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
136
153
  setLastReadCrashesCount(crashRecords.length);
137
154
  }
138
155
  }, [activeTab, crashRecords.length]);
156
+ // ─── Storage state ─────────────────────────────────────────────────────────
157
+ const [storageEntries, setStorageEntries] = useState([]);
158
+ const [selectedStorageKey, setSelectedStorageKey] = useState(null);
159
+ const refreshStorageEntries = useCallback(async () => {
160
+ try {
161
+ const entries = await fetchAllStorageEntries();
162
+ setStorageEntries(entries);
163
+ }
164
+ catch { }
165
+ }, []);
166
+ const updateStorageEntry = useCallback(async (key, value) => {
167
+ await setStorageItem(key, value);
168
+ await refreshStorageEntries();
169
+ }, [refreshStorageEntries]);
170
+ const deleteStorageEntry = useCallback(async (key) => {
171
+ await removeStorageItem(key);
172
+ await refreshStorageEntries();
173
+ }, [refreshStorageEntries]);
174
+ const clearAllStorageEntries = useCallback(async () => {
175
+ await clearAllStorage();
176
+ await refreshStorageEntries();
177
+ }, [refreshStorageEntries]);
178
+ useEffect(() => {
179
+ refreshStorageEntries();
180
+ const unsub = subscribeStorageChanges(refreshStorageEntries);
181
+ return () => unsub();
182
+ }, [refreshStorageEntries]);
183
+ // ─── Device info state ──────────────────────────────────────────────────────
184
+ const [deviceInfo] = useState(() => getSystemDiagnostics());
185
+ // ─── Code Quality & Package Audit state ─────────────────────────────────────
186
+ const [auditReport, setAuditReport] = useState(() => runLivePackageAudit());
187
+ useEffect(() => {
188
+ const unsub = subscribeAuditChanges(setAuditReport);
189
+ return () => unsub();
190
+ }, []);
191
+ const refreshAuditReport = useCallback(() => {
192
+ setAuditReport(runLivePackageAudit());
193
+ }, []);
194
+ const logCustomAuditIssue = useCallback((issue) => {
195
+ logCodeQualityIssue(issue);
196
+ }, []);
139
197
  const [maxConsoleLogs, setMaxConsoleLogs] = useState(100);
140
198
  const [showConsoleLevels, setShowConsoleLevels] = useState({
141
199
  info: true,
@@ -176,6 +234,9 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
176
234
  logs: true,
177
235
  analytics: false,
178
236
  redux: false,
237
+ storage: false,
238
+ device: false,
239
+ audit: false,
179
240
  bundle: false,
180
241
  performance: false,
181
242
  crash: false,
@@ -230,6 +291,9 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
230
291
  logs: true,
231
292
  analytics: false,
232
293
  redux: false,
294
+ storage: false,
295
+ device: false,
296
+ audit: false,
233
297
  bundle: false,
234
298
  performance: false,
235
299
  crash: false,
@@ -267,14 +331,24 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
267
331
  setModalHeightPercent(saved.modalHeightPercent);
268
332
  if (saved.modalAnimationType)
269
333
  setModalAnimationType(saved.modalAnimationType);
270
- if (saved.tabVisibility)
334
+ if (saved.tabVisibility) {
335
+ const savedVis = saved.tabVisibility;
271
336
  setTabVisibility(prev => ({
272
337
  ...prev,
273
- ...saved.tabVisibility,
338
+ ...savedVis,
339
+ storage: savedVis.storage ?? false,
340
+ device: savedVis.device ?? false,
341
+ audit: savedVis.audit ?? false,
274
342
  apis: true, // APIs is always required
275
343
  }));
276
- if (saved.defaultTab)
344
+ }
345
+ if (initialTab) {
346
+ setActiveTab(initialTab);
347
+ }
348
+ else if (saved.defaultTab) {
277
349
  setDefaultTab(saved.defaultTab);
350
+ setActiveTab(saved.defaultTab);
351
+ }
278
352
  if (saved.isAutoRamLimitEnabled != null)
279
353
  setIsAutoRamLimitEnabled(saved.isAutoRamLimitEnabled);
280
354
  if (saved.maxNetworkLogs != null)
@@ -295,7 +369,10 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
295
369
  setShowDuplicateLogs(saved.showDuplicateLogs);
296
370
  if (saved.showUpdateToast != null)
297
371
  setShowUpdateToast(saved.showUpdateToast);
298
- if (saved.defaultTab) {
372
+ if (initialTab) {
373
+ setActiveTab(initialTab);
374
+ }
375
+ else if (saved.defaultTab) {
299
376
  const dt = saved.defaultTab;
300
377
  const vis = {
301
378
  ...{
@@ -303,6 +380,9 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
303
380
  logs: true,
304
381
  analytics: false,
305
382
  redux: false,
383
+ storage: false,
384
+ device: false,
385
+ audit: false,
306
386
  bundle: false,
307
387
  performance: false,
308
388
  crash: false,
@@ -771,6 +851,12 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
771
851
  ? defaultTab
772
852
  : 'apis';
773
853
  setActiveTab(target);
854
+ setSelected(null);
855
+ setSelectedEvent(null);
856
+ setSelectedLog(null);
857
+ setSelectedReduxSlice(null);
858
+ setSelectedReduxAction(null);
859
+ setSelectedCrash(null);
774
860
  // Track inspector opened event in GA4
775
861
  trackInspectorOpen({ activeTab: target });
776
862
  // Instant synchronization of data collected while modal was closed
@@ -1000,7 +1086,40 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
1000
1086
  }, [selected]);
1001
1087
  const filteredLogs = useMemo(() => {
1002
1088
  let result = logs.filter(log => {
1003
- // Status Filter Check
1089
+ // 1. Quick Filter Check (All, Errors, Success, Slow, GET, POST, GraphQL)
1090
+ if (quickFilter && quickFilter !== 'all') {
1091
+ if (quickFilter === 'errors') {
1092
+ const isErr = log.status === 0 ||
1093
+ log.status == null ||
1094
+ (typeof log.status === 'number' && log.status >= 400);
1095
+ if (!isErr)
1096
+ return false;
1097
+ }
1098
+ else if (quickFilter === 'success') {
1099
+ const isSuccess = typeof log.status === 'number' &&
1100
+ log.status >= 200 &&
1101
+ log.status < 400;
1102
+ if (!isSuccess)
1103
+ return false;
1104
+ }
1105
+ else if (quickFilter === 'slow') {
1106
+ if ((log.duration || 0) < 500)
1107
+ return false;
1108
+ }
1109
+ else if (quickFilter === 'graphql') {
1110
+ const isGql = (log.url || '').toLowerCase().includes('graphql') ||
1111
+ (log.client || '').toLowerCase().includes('graphql') ||
1112
+ (log.client || '').toLowerCase().includes('apollo');
1113
+ if (!isGql)
1114
+ return false;
1115
+ }
1116
+ else {
1117
+ if (log.method?.toUpperCase() !== quickFilter.toUpperCase()) {
1118
+ return false;
1119
+ }
1120
+ }
1121
+ }
1122
+ // 2. Status Filter Check (from filters accordion dropdown)
1004
1123
  if (statusFilters.size > 0) {
1005
1124
  const matched = [...statusFilters].some(f => {
1006
1125
  if (f === 'ALL')
@@ -1016,7 +1135,7 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
1016
1135
  if (!matched)
1017
1136
  return false;
1018
1137
  }
1019
- // Method Filter Check
1138
+ // 3. Method Filter Check (from filters accordion dropdown)
1020
1139
  if (methodFilters.size > 0) {
1021
1140
  const matchedMethod = [...methodFilters].some(m => {
1022
1141
  if (m === 'ALL')
@@ -1026,10 +1145,14 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
1026
1145
  if (!matchedMethod)
1027
1146
  return false;
1028
1147
  }
1029
- // Advanced Search Query Engine Check (Supports method:POST, is:error, slow:>1s, status:200, headers, body, etc.)
1148
+ // 4. Advanced Search Query Engine Check with Scope, Regex and Case-Sensitivity
1030
1149
  if (search && search.trim().length > 0) {
1031
1150
  const routePath = logRouteMapRef.current.get(log.id)?.path || '';
1032
- const isMatch = matchNetworkLogQuery(log, search, routePath);
1151
+ const isMatch = matchNetworkLogQuery(log, search, routePath, {
1152
+ scope: searchScope,
1153
+ isRegex: isRegexSearch,
1154
+ isCaseSensitive: isCaseSensitive,
1155
+ });
1033
1156
  if (!isMatch)
1034
1157
  return false;
1035
1158
  }
@@ -1038,9 +1161,7 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
1038
1161
  if (sortOrder === 'oldest') {
1039
1162
  result = [...result].reverse();
1040
1163
  }
1041
- // #9 — collapse consecutive identical requests (same method + url +
1042
- // status) into one row carrying a ×N counter, unless the user opted in
1043
- // to seeing every duplicate via Settings → "Show Duplicate Logs".
1164
+ // #9 — collapse consecutive identical requests
1044
1165
  if (!showDuplicateLogs) {
1045
1166
  const collapsed = [];
1046
1167
  for (const log of result) {
@@ -1064,6 +1185,10 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
1064
1185
  }, [
1065
1186
  logs,
1066
1187
  search,
1188
+ searchScope,
1189
+ isRegexSearch,
1190
+ isCaseSensitive,
1191
+ quickFilter,
1067
1192
  statusFilters,
1068
1193
  methodFilters,
1069
1194
  sortOrder,
@@ -1614,6 +1739,14 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
1614
1739
  groupedData,
1615
1740
  search,
1616
1741
  setSearch,
1742
+ searchScope,
1743
+ setSearchScope,
1744
+ isRegexSearch,
1745
+ setIsRegexSearch,
1746
+ isCaseSensitive,
1747
+ setIsCaseSensitive,
1748
+ quickFilter,
1749
+ setQuickFilter,
1617
1750
  statusFilters,
1618
1751
  setStatusFilters,
1619
1752
  methodFilters,
@@ -1703,6 +1836,20 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
1703
1836
  setCrashRecords([]);
1704
1837
  setSelectedCrash(null);
1705
1838
  },
1839
+ // ─── Storage ─────────────────────────────────────────────────────────
1840
+ storageEntries,
1841
+ refreshStorageEntries,
1842
+ updateStorageEntry,
1843
+ deleteStorageEntry,
1844
+ clearAllStorageEntries,
1845
+ selectedStorageKey,
1846
+ setSelectedStorageKey,
1847
+ // ─── Device ──────────────────────────────────────────────────────────
1848
+ deviceInfo,
1849
+ // ─── Audit / Code Quality ─────────────────────────────────────────────
1850
+ auditReport,
1851
+ refreshAuditReport,
1852
+ logCustomAuditIssue,
1706
1853
  // ─── Settings ───────────────────────────────────────────────────────
1707
1854
  settingsActiveSubTab,
1708
1855
  setSettingsActiveSubTab,
@@ -1727,13 +1874,17 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
1727
1874
  isAutoRamLimitEnabled,
1728
1875
  setIsAutoRamLimitEnabled,
1729
1876
  deviceFreeRamMb,
1877
+ isPerformanceHudEnabled,
1878
+ setIsPerformanceHudEnabled,
1730
1879
  reduxAutoRefresh,
1731
1880
  setReduxAutoRefreshState,
1732
1881
  reduxExpandDepth,
1733
1882
  setReduxExpandDepth,
1734
1883
  };
1735
1884
  return (<InspectorContext.Provider value={contextValue}>
1736
- <MainScreen />
1885
+ <View style={StyleSheet.absoluteFill} pointerEvents="box-none">
1886
+ <MainScreen />
1887
+ </View>
1737
1888
  </InspectorContext.Provider>);
1738
1889
  };
1739
1890
  const NetworkInspectorWrapper = (props) => {
@@ -1762,5 +1913,6 @@ export { usePerformanceTracker, useComponentProfiler, useNavigationProfiler, tra
1762
1913
  export { InspectLog, InspectTrackTime, InspectCatch, } from './decorators';
1763
1914
  export { getNativeDeviceMetrics, enableNativeCrashProtection, subscribeNativeCrashes, showNativeFloatingButton, hideNativeFloatingButton, setNativeFloatingButtonBadge, subscribeNativeFloatingButtonPress, subscribeNativeDeviceShake, startNativeFpsMonitoring, stopNativeFpsMonitoring, getNativeFpsMetrics, getNativeStorageItem, setNativeStorageItem, isNativeModuleAvailable, } from './native/NativeInspector';
1764
1915
  export { sendSessionTelemetryPing, trackTelemetryEvent, trackInspectorOpen, trackTabSwitch, trackLogExport, GA4_MEASUREMENT_ID, GA4_API_SECRET, } from './helpers';
1916
+ export { runLivePackageAudit, logCodeQualityIssue, clearCustomAuditIssues, } from './helpers/packageAuditor';
1765
1917
  export { BrandSquareIcon, BrandCircleIcon, } from './components/NetworkIcons';
1766
1918
  export { ActiveTab, Method, StatusFilter, SortOrder, LocalFilter, ModalAnimationType, SettingsPage, SettingsSubTab, LogFilter, ConsoleLogType, AnalyticsEventSource, GAEventCategory, StackFrameType, DiffResultType, BundleSubTab, PerformanceSubTab, CrashType, CrashExportFormat, CrashDetailSubTab, CrashFilterType, BreadcrumbType, } from './types';
@@ -14,6 +14,7 @@ export interface NativeDeviceMetrics {
14
14
  isCharging?: boolean;
15
15
  deviceModel?: string;
16
16
  deviceBrand?: string;
17
+ deviceId?: string;
17
18
  osVersion?: string;
18
19
  apiLevel?: number;
19
20
  cpuAbi?: string;
@@ -3,6 +3,9 @@ export declare const ActiveTab: {
3
3
  readonly Analytics: "analytics";
4
4
  readonly Logs: "logs";
5
5
  readonly Redux: "redux";
6
+ readonly Storage: "storage";
7
+ readonly Device: "device";
8
+ readonly Audit: "audit";
6
9
  readonly Bundle: "bundle";
7
10
  readonly Performance: "performance";
8
11
  readonly Crash: "crash";
@@ -49,6 +52,9 @@ export declare const SettingsPage: {
49
52
  readonly Logs: "logs";
50
53
  readonly Analytics: "analytics";
51
54
  readonly Redux: "redux";
55
+ readonly Storage: "storage";
56
+ readonly Device: "device";
57
+ readonly Audit: "audit";
52
58
  readonly Bundle: "bundle";
53
59
  readonly Performance: "performance";
54
60
  readonly Crash: "crash";
@@ -56,6 +62,7 @@ export declare const SettingsPage: {
56
62
  export type SettingsPage = (typeof SettingsPage)[keyof typeof SettingsPage] | null;
57
63
  export declare const SettingsSubTab: {
58
64
  readonly Module: "module";
65
+ readonly Limits: "limits";
59
66
  readonly Ui: "ui";
60
67
  };
61
68
  export type SettingsSubTab = (typeof SettingsSubTab)[keyof typeof SettingsSubTab];
@@ -6,6 +6,9 @@ export const ActiveTab = {
6
6
  Analytics: 'analytics',
7
7
  Logs: 'logs',
8
8
  Redux: 'redux',
9
+ Storage: 'storage',
10
+ Device: 'device',
11
+ Audit: 'audit',
9
12
  Bundle: 'bundle',
10
13
  Performance: 'performance',
11
14
  Crash: 'crash',
@@ -46,12 +49,16 @@ export const SettingsPage = {
46
49
  Logs: 'logs',
47
50
  Analytics: 'analytics',
48
51
  Redux: 'redux',
52
+ Storage: 'storage',
53
+ Device: 'device',
54
+ Audit: 'audit',
49
55
  Bundle: 'bundle',
50
56
  Performance: 'performance',
51
57
  Crash: 'crash',
52
58
  };
53
59
  export const SettingsSubTab = {
54
60
  Module: 'module',
61
+ Limits: 'limits',
55
62
  Ui: 'ui',
56
63
  };
57
64
  export const LogFilter = {
@@ -2,6 +2,65 @@ import React from 'react';
2
2
  import { ViewStyle } from 'react-native';
3
3
  import { Animated, PanResponderInstance } from 'react-native';
4
4
  import type { ActiveTab, BreadcrumbType, CrashType, GroupedListItem, LocalFilter, LogFilter, Method, SettingsPage, SettingsSubTab, SortOrder, StatusFilter } from './index';
5
+ export type SearchScope = 'all' | 'url' | 'reqBody' | 'resBody' | 'headers';
6
+ export interface StorageEntry {
7
+ key: string;
8
+ value: string;
9
+ sizeBytes: number;
10
+ isJson: boolean;
11
+ parsedJson?: any;
12
+ updatedAt: number;
13
+ }
14
+ export interface DeviceInfoData {
15
+ appName: string;
16
+ bundleId: string;
17
+ appVersion: string;
18
+ buildNumber: string;
19
+ reactNativeVersion: string;
20
+ jsEngine: string;
21
+ isHermes: boolean;
22
+ isFabric: boolean;
23
+ isTurboModule: boolean;
24
+ platform: 'ios' | 'android' | 'windows' | 'macos' | 'web';
25
+ osVersion: string;
26
+ deviceModel: string;
27
+ deviceId?: string;
28
+ isDevice: boolean;
29
+ screenWidth: number;
30
+ screenHeight: number;
31
+ screenScale: number;
32
+ screenFontScale: number;
33
+ statusBarHeight: number;
34
+ memoryMb?: number;
35
+ arch?: string;
36
+ locale?: string;
37
+ timeZone?: string;
38
+ }
39
+ export type AuditSeverity = 'critical' | 'warning' | 'info' | 'optimal';
40
+ export type AuditCategory = 'dependency' | 'typescript' | 'peer' | 'performance' | 'security';
41
+ export interface AuditIssue {
42
+ id: string;
43
+ title: string;
44
+ message: string;
45
+ severity: AuditSeverity;
46
+ category: AuditCategory;
47
+ packageName?: string;
48
+ currentVersion?: string;
49
+ requiredVersion?: string;
50
+ fixCommand?: string;
51
+ fixSnippet?: string;
52
+ timestamp: number;
53
+ }
54
+ export interface PackageHealthReport {
55
+ score: number;
56
+ grade: 'A+' | 'A' | 'B' | 'C' | 'D';
57
+ totalIssues: number;
58
+ criticalCount: number;
59
+ warningCount: number;
60
+ infoCount: number;
61
+ issues: AuditIssue[];
62
+ scannedAt: number;
63
+ }
5
64
  export interface ParsedStackFrame {
6
65
  method: string;
7
66
  file: string;
@@ -163,6 +222,8 @@ export interface NetworkInspectorProps {
163
222
  environment?: 'DEV' | 'UAT' | 'PrePROD' | 'PROD' | 'QA' | 'Staging' | string;
164
223
  initialVisible?: boolean;
165
224
  visible?: boolean;
225
+ initialTab?: ActiveTab;
226
+ enablePerformanceHud?: boolean;
166
227
  }
167
228
  export interface NavigationTrackerProps {
168
229
  onStateChange: (state: any) => void;
@@ -175,6 +236,8 @@ export interface InspectorContextValue {
175
236
  isEnabled: boolean;
176
237
  appIcon?: any;
177
238
  environment?: string;
239
+ isPerformanceHudEnabled: boolean;
240
+ setIsPerformanceHudEnabled: React.Dispatch<React.SetStateAction<boolean>>;
178
241
  modalHeightPercent: number;
179
242
  setModalHeightPercent: React.Dispatch<React.SetStateAction<number>>;
180
243
  modalAnimationType: 'slide' | 'fade' | 'none';
@@ -214,6 +277,14 @@ export interface InspectorContextValue {
214
277
  groupedData: GroupedListItem[];
215
278
  search: string;
216
279
  setSearch: React.Dispatch<React.SetStateAction<string>>;
280
+ searchScope: SearchScope;
281
+ setSearchScope: React.Dispatch<React.SetStateAction<SearchScope>>;
282
+ isRegexSearch: boolean;
283
+ setIsRegexSearch: React.Dispatch<React.SetStateAction<boolean>>;
284
+ isCaseSensitive: boolean;
285
+ setIsCaseSensitive: React.Dispatch<React.SetStateAction<boolean>>;
286
+ quickFilter: string;
287
+ setQuickFilter: React.Dispatch<React.SetStateAction<string>>;
217
288
  statusFilters: Set<StatusFilter>;
218
289
  setStatusFilters: React.Dispatch<React.SetStateAction<Set<StatusFilter>>>;
219
290
  methodFilters: Set<Method>;
@@ -296,6 +367,17 @@ export interface InspectorContextValue {
296
367
  maxCrashLogs: number;
297
368
  setMaxCrashLogs: React.Dispatch<React.SetStateAction<number>>;
298
369
  clearAllCrashes: () => void;
370
+ storageEntries: StorageEntry[];
371
+ refreshStorageEntries: () => Promise<void>;
372
+ updateStorageEntry: (key: string, value: string) => Promise<void>;
373
+ deleteStorageEntry: (key: string) => Promise<void>;
374
+ clearAllStorageEntries: () => Promise<void>;
375
+ selectedStorageKey: string | null;
376
+ setSelectedStorageKey: React.Dispatch<React.SetStateAction<string | null>>;
377
+ deviceInfo: DeviceInfoData;
378
+ auditReport: PackageHealthReport;
379
+ refreshAuditReport: () => void;
380
+ logCustomAuditIssue: (issue: Omit<AuditIssue, 'id' | 'timestamp'>) => void;
299
381
  settingsActiveSubTab: SettingsSubTab;
300
382
  setSettingsActiveSubTab: React.Dispatch<React.SetStateAction<SettingsSubTab>>;
301
383
  defaultTab: ActiveTab;
@@ -515,6 +515,10 @@ RCT_EXPORT_METHOD(getDeviceMetrics:(RCTPromiseResolveBlock)resolve
515
515
  [metrics setObject:[UIDevice currentDevice].systemName forKey:@"deviceBrand"];
516
516
  [metrics setObject:[UIDevice currentDevice].systemVersion forKey:@"osVersion"];
517
517
  [metrics setObject:@"arm64" forKey:@"cpuAbi"];
518
+ NSString *deviceId = [[UIDevice currentDevice].identifierForVendor UUIDString];
519
+ if (deviceId) {
520
+ [metrics setObject:deviceId forKey:@"deviceId"];
521
+ }
518
522
 
519
523
  // 5. Application Identifiers (Legal & Non-PII)
520
524
  NSBundle *mainBundle = [NSBundle mainBundle];
@@ -557,10 +561,13 @@ static UIWindow *GetAppActiveWindow(void) {
557
561
  return [UIApplication sharedApplication].windows.firstObject;
558
562
  }
559
563
 
564
+ static BOOL isFloatingButtonRequestedVisible = NO;
565
+
560
566
  RCT_EXPORT_METHOD(showFloatingButton:(NSDictionary *)options
561
567
  resolve:(RCTPromiseResolveBlock)resolve
562
568
  reject:(RCTPromiseRejectBlock)reject) {
563
569
  dispatch_async(dispatch_get_main_queue(), ^{
570
+ isFloatingButtonRequestedVisible = YES;
564
571
  UIWindow *targetWindow = GetAppActiveWindow();
565
572
  CGRect screenBounds = targetWindow ? targetWindow.bounds : [UIScreen mainScreen].bounds;
566
573
 
@@ -599,6 +606,7 @@ RCT_EXPORT_METHOD(showFloatingButton:(NSDictionary *)options
599
606
  }
600
607
 
601
608
  void (^attachToWindow)(void) = ^{
609
+ if (!isFloatingButtonRequestedVisible) return;
602
610
  UIWindow *activeWin = GetAppActiveWindow();
603
611
  if (!activeWin || !floatingButtonView) return;
604
612
 
@@ -635,12 +643,11 @@ RCT_EXPORT_METHOD(showFloatingButton:(NSDictionary *)options
635
643
  RCT_EXPORT_METHOD(hideFloatingButton:(RCTPromiseResolveBlock)resolve
636
644
  reject:(RCTPromiseRejectBlock)reject) {
637
645
  dispatch_async(dispatch_get_main_queue(), ^{
646
+ isFloatingButtonRequestedVisible = NO;
638
647
  if (floatingButtonView != nil) {
639
- [UIView animateWithDuration:0.15 animations:^{
640
- floatingButtonView.alpha = 0.0;
641
- } completion:^(BOOL finished) {
642
- floatingButtonView.hidden = YES;
643
- }];
648
+ floatingButtonView.alpha = 0.0;
649
+ floatingButtonView.hidden = YES;
650
+ [floatingButtonView removeFromSuperview];
644
651
  }
645
652
  resolve(@(YES));
646
653
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-inapp-inspector",
3
- "version": "2.0.4",
3
+ "version": "2.0.6",
4
4
  "description": "The zero-config, all-in-one in-app debugger for React Native & Expo. Inspect Network (fetch/axios), Console logs, Stack Traces, Redux State, Firebase Analytics, and JS Bundle size directly on device.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -44,6 +44,9 @@
44
44
  "clean": "rm -rf dist",
45
45
  "prebuild": "node scripts/gen-version.js",
46
46
  "build": "npm run clean && tsc && tsc -p tsconfig.esm.json && node scripts/inject-telemetry.js",
47
+ "typecheck": "tsc --noEmit",
48
+ "format": "prettier --write \"src/**/*.{ts,tsx}\"",
49
+ "format:check": "prettier --check \"src/**/*.{ts,tsx}\"",
47
50
  "watch": "tsc -w",
48
51
  "prepack": "npm run build",
49
52
  "publish": "node release.cjs",