react-native-inapp-inspector 1.1.35 → 2.0.0

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 (82) hide show
  1. package/README.md +123 -101
  2. package/android/build.gradle +13 -1
  3. package/android/src/main/java/com/inappinspector/NetworkInspectorModule.kt +904 -0
  4. package/android/src/main/java/com/inappinspector/NetworkInspectorPackage.kt +17 -0
  5. package/dist/commonjs/components/CopyButton.js +3 -0
  6. package/dist/commonjs/components/ErrorBoundary.js +3 -0
  7. package/dist/commonjs/components/Inspector/AnalyticsTab.js +7 -3
  8. package/dist/commonjs/components/Inspector/BundleTab.js +1 -1
  9. package/dist/commonjs/components/Inspector/ConsoleTab.js +1 -1
  10. package/dist/commonjs/components/Inspector/CrashTab.js +97 -90
  11. package/dist/commonjs/components/Inspector/InspectorHeader.js +12 -8
  12. package/dist/commonjs/components/Inspector/MainScreen.js +14 -101
  13. package/dist/commonjs/components/Inspector/NetworkTab.js +47 -10
  14. package/dist/commonjs/components/Inspector/PerformanceTab.js +96 -3
  15. package/dist/commonjs/components/Inspector/ReduxTab.js +18 -10
  16. package/dist/commonjs/components/Inspector/SettingsPanel.js +342 -88
  17. package/dist/commonjs/components/Inspector/TabBar.js +6 -3
  18. package/dist/commonjs/components/NetworkIcons.d.ts +1 -0
  19. package/dist/commonjs/components/NetworkIcons.js +6 -1
  20. package/dist/commonjs/components/TouchableScale.d.ts +1 -0
  21. package/dist/commonjs/components/TouchableScale.js +30 -32
  22. package/dist/commonjs/constants/index.d.ts +1 -2
  23. package/dist/commonjs/constants/index.js +4 -0
  24. package/dist/commonjs/constants/version.d.ts +1 -1
  25. package/dist/commonjs/constants/version.js +1 -1
  26. package/dist/commonjs/customHooks/analyticsLogger.d.ts +4 -0
  27. package/dist/commonjs/customHooks/analyticsLogger.js +7 -5
  28. package/dist/commonjs/customHooks/crashHandler.js +7 -0
  29. package/dist/commonjs/helpers/index.js +10 -1
  30. package/dist/commonjs/helpers/settingsStore.d.ts +9 -0
  31. package/dist/commonjs/helpers/settingsStore.js +59 -3
  32. package/dist/commonjs/index.d.ts +1 -0
  33. package/dist/commonjs/index.js +229 -39
  34. package/dist/commonjs/native/NativeInspector.d.ts +125 -0
  35. package/dist/commonjs/native/NativeInspector.js +313 -0
  36. package/dist/commonjs/native/NativeNetworkInspector.d.ts +22 -0
  37. package/dist/commonjs/native/NativeNetworkInspector.js +4 -0
  38. package/dist/commonjs/styles/index.js +6 -6
  39. package/dist/commonjs/types/enums.d.ts +1 -1
  40. package/dist/commonjs/types/interfaces.d.ts +9 -0
  41. package/dist/esm/components/CopyButton.js +3 -0
  42. package/dist/esm/components/ErrorBoundary.js +3 -0
  43. package/dist/esm/components/Inspector/AnalyticsTab.js +7 -3
  44. package/dist/esm/components/Inspector/BundleTab.js +1 -1
  45. package/dist/esm/components/Inspector/ConsoleTab.js +1 -1
  46. package/dist/esm/components/Inspector/CrashTab.js +97 -90
  47. package/dist/esm/components/Inspector/InspectorHeader.js +13 -9
  48. package/dist/esm/components/Inspector/MainScreen.js +15 -69
  49. package/dist/esm/components/Inspector/NetworkTab.js +47 -10
  50. package/dist/esm/components/Inspector/PerformanceTab.js +96 -3
  51. package/dist/esm/components/Inspector/ReduxTab.js +18 -10
  52. package/dist/esm/components/Inspector/SettingsPanel.js +344 -90
  53. package/dist/esm/components/Inspector/TabBar.js +7 -4
  54. package/dist/esm/components/NetworkIcons.d.ts +1 -0
  55. package/dist/esm/components/NetworkIcons.js +4 -0
  56. package/dist/esm/components/TouchableScale.d.ts +1 -0
  57. package/dist/esm/components/TouchableScale.js +31 -33
  58. package/dist/esm/constants/index.d.ts +1 -2
  59. package/dist/esm/constants/index.js +4 -0
  60. package/dist/esm/constants/version.d.ts +1 -1
  61. package/dist/esm/constants/version.js +1 -1
  62. package/dist/esm/customHooks/analyticsLogger.d.ts +4 -0
  63. package/dist/esm/customHooks/analyticsLogger.js +5 -4
  64. package/dist/esm/customHooks/crashHandler.js +7 -0
  65. package/dist/esm/helpers/index.js +10 -1
  66. package/dist/esm/helpers/settingsStore.d.ts +9 -0
  67. package/dist/esm/helpers/settingsStore.js +58 -3
  68. package/dist/esm/index.d.ts +1 -0
  69. package/dist/esm/index.js +215 -39
  70. package/dist/esm/native/NativeInspector.d.ts +125 -0
  71. package/dist/esm/native/NativeInspector.js +289 -0
  72. package/dist/esm/native/NativeNetworkInspector.d.ts +22 -0
  73. package/dist/esm/native/NativeNetworkInspector.js +2 -0
  74. package/dist/esm/styles/index.js +6 -6
  75. package/dist/esm/types/enums.d.ts +1 -1
  76. package/dist/esm/types/interfaces.d.ts +9 -0
  77. package/ios/NetworkInspectorModule.h +6 -0
  78. package/ios/NetworkInspectorModule.m +720 -5
  79. package/package.json +13 -2
  80. package/react-native-inapp-inspector.podspec +7 -2
  81. package/android/src/main/java/com/inappinspector/NetworkInspectorModule.java +0 -97
  82. package/android/src/main/java/com/inappinspector/NetworkInspectorPackage.java +0 -28
@@ -37,7 +37,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
37
37
  };
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
39
  exports.registerComponentProfile = exports.getHermesMemoryStats = exports.measureAsync = exports.trackHeavyTask = exports.trackNavigationTransition = exports.trackComponentRender = exports.useNavigationProfiler = exports.useComponentProfiler = exports.usePerformanceTracker = exports.registerGAPlugin = exports.getEventCategory = exports.getLastActionForReducer = exports.clearActionHistory = exports.getActionHistory = exports.subscribeReduxState = exports.getReduxState = exports.inspectorReduxMiddleware = exports.connectReduxStore = exports.ErrorBoundary = exports.CrashTab = exports.computeCrashFingerprint = exports.recordUserActionBreadcrumb = exports.recordReduxBreadcrumb = exports.recordNetworkBreadcrumb = exports.recordNavigationBreadcrumb = exports.addCrashBreadcrumb = exports.recordCustomCrash = exports.parseCrashStackTrace = exports.exportCrashReport = exports.simulateTestCrash = exports.clearCrashRecords = exports.getCrashRecords = exports.emitCrashEvent = exports.subscribeCrashEvents = exports.setupGlobalCrashHandler = exports.getCollectionEnabled = exports.getDefaultEventParameters = exports.getCurrentUserId = exports.getCurrentUserProperties = exports.clearAnalyticsEvents = exports.subscribeAnalyticsEvents = exports.logAnalyticsEvent = exports.setupAnalyticsLogger = exports.subscribeConsoleLogs = exports.clearConsoleLogs = exports.setupConsoleLogger = exports.addAxiosInterceptors = exports.subscribeNetworkLogs = exports.clearNetworkLogs = exports.setupNetworkLogger = void 0;
40
- exports.BreadcrumbType = exports.CrashFilterType = exports.CrashDetailSubTab = exports.CrashExportFormat = exports.CrashType = exports.PerformanceSubTab = exports.BundleSubTab = exports.DiffResultType = exports.StackFrameType = exports.GAEventCategory = exports.AnalyticsEventSource = exports.ConsoleLogType = exports.LogFilter = exports.SettingsSubTab = exports.SettingsPage = exports.ModalAnimationType = exports.LocalFilter = exports.SortOrder = exports.StatusFilter = exports.Method = exports.ActiveTab = exports.InspectCatch = exports.InspectTrackTime = exports.InspectLog = exports.generateFixSnippet = exports.getInitialPerformanceEvents = exports.getInitialRenderProfiles = exports.getPerformanceEvents = exports.subscribePerformanceEvents = exports.clearPerformanceEvents = exports.logPerformanceEvent = exports.getRenderProfiles = exports.subscribeRenderProfiles = void 0;
40
+ exports.BreadcrumbType = exports.CrashFilterType = exports.CrashDetailSubTab = exports.CrashExportFormat = exports.CrashType = exports.PerformanceSubTab = exports.BundleSubTab = exports.DiffResultType = exports.StackFrameType = exports.GAEventCategory = exports.AnalyticsEventSource = exports.ConsoleLogType = exports.LogFilter = exports.SettingsSubTab = exports.SettingsPage = exports.ModalAnimationType = exports.LocalFilter = exports.SortOrder = exports.StatusFilter = exports.Method = exports.ActiveTab = exports.isNativeModuleAvailable = exports.setNativeStorageItem = exports.getNativeStorageItem = exports.getNativeFpsMetrics = exports.stopNativeFpsMonitoring = exports.startNativeFpsMonitoring = exports.subscribeNativeDeviceShake = exports.subscribeNativeFloatingButtonPress = exports.setNativeFloatingButtonBadge = exports.hideNativeFloatingButton = exports.showNativeFloatingButton = exports.subscribeNativeCrashes = exports.enableNativeCrashProtection = exports.getNativeDeviceMetrics = exports.InspectCatch = exports.InspectTrackTime = exports.InspectLog = exports.generateFixSnippet = exports.getInitialPerformanceEvents = exports.getInitialRenderProfiles = exports.getPerformanceEvents = exports.subscribePerformanceEvents = exports.clearPerformanceEvents = exports.logPerformanceEvent = exports.getRenderProfiles = exports.subscribeRenderProfiles = void 0;
41
41
  const react_1 = __importStar(require("react"));
42
42
  const react_native_1 = require("react-native");
43
43
  const native_1 = require("@react-navigation/native");
@@ -51,6 +51,7 @@ const InspectorContext_1 = require("./components/Inspector/InspectorContext");
51
51
  const helpers_1 = require("./helpers");
52
52
  // #5 — settings persistence
53
53
  const settingsStore_1 = require("./helpers/settingsStore");
54
+ const NativeInspector_1 = require("./native/NativeInspector");
54
55
  // Network
55
56
  const networkLogger_1 = require("./customHooks/networkLogger");
56
57
  // Console
@@ -62,6 +63,7 @@ const analyticsLogger_1 = require("./customHooks/analyticsLogger");
62
63
  const reduxLogger_1 = require("./customHooks/reduxLogger");
63
64
  const performanceTracker_1 = require("./customHooks/performanceTracker");
64
65
  const bundleAnalyzer_1 = require("./customHooks/bundleAnalyzer");
66
+ const NativeInspector_2 = require("./native/NativeInspector");
65
67
  const constants_1 = require("./constants");
66
68
  // Stylesheet
67
69
  const styles_1 = require("./styles");
@@ -214,6 +216,9 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
214
216
  crash: false,
215
217
  });
216
218
  const [maxNetworkLogs, setMaxNetworkLogs] = (0, react_1.useState)(100);
219
+ const [maxAnalyticsEventsLimit, setMaxAnalyticsEventsLimit] = (0, react_1.useState)(250);
220
+ const [isAutoRamLimitEnabled, setIsAutoRamLimitEnabled] = (0, react_1.useState)(true);
221
+ const [deviceFreeRamMb, setDeviceFreeRamMb] = (0, react_1.useState)(1800);
217
222
  const [reduxAutoRefresh, setReduxAutoRefreshState] = (0, react_1.useState)(true);
218
223
  const [reduxExpandDepth, setReduxExpandDepth] = (0, react_1.useState)(1);
219
224
  // #6 — tab the inspector opens on. Shown with a DEFAULT badge in Settings.
@@ -229,6 +234,25 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
229
234
  (0, crashHandler_1.setCrashModuleEnabled)(!!tabVisibility.crash);
230
235
  (0, bundleAnalyzer_1.setBundleModuleEnabled)(!!tabVisibility.bundle);
231
236
  }, [tabVisibility]);
237
+ // Query native hardware RAM and auto-tune limits if auto-RAM is active
238
+ (0, react_1.useEffect)(() => {
239
+ (0, NativeInspector_1.getNativeSystemMetrics)()
240
+ .then(metrics => {
241
+ if (metrics) {
242
+ const freeRam = metrics.totalPhysicalRamMb - metrics.residentRamMb;
243
+ const freeMb = Math.max(200, Math.round(freeRam > 0 ? freeRam : 1500));
244
+ setDeviceFreeRamMb(freeMb);
245
+ if (isAutoRamLimitEnabled) {
246
+ const profile = (0, settingsStore_1.calculateRamBasedLimits)(freeMb);
247
+ setMaxNetworkLogs(profile.maxNetworkLogs);
248
+ setMaxConsoleLogs(profile.maxConsoleLogs);
249
+ setMaxAnalyticsEventsLimit(profile.maxAnalyticsEvents);
250
+ setMaxCrashLogs(profile.maxCrashRecords);
251
+ }
252
+ }
253
+ })
254
+ .catch(() => { });
255
+ }, [isAutoRamLimitEnabled]);
232
256
  const resetToDefaults = async () => {
233
257
  await (0, settingsStore_1.clearPersistedSettings)();
234
258
  setIsDark(false);
@@ -245,9 +269,12 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
245
269
  crash: false,
246
270
  });
247
271
  setDefaultTab('apis');
248
- setMaxCrashLogs(100);
249
- setMaxNetworkLogs(100);
250
- setMaxConsoleLogs(200);
272
+ setIsAutoRamLimitEnabled(true);
273
+ const profile = (0, settingsStore_1.calculateRamBasedLimits)(deviceFreeRamMb);
274
+ setMaxCrashLogs(profile.maxCrashRecords);
275
+ setMaxNetworkLogs(profile.maxNetworkLogs);
276
+ setMaxConsoleLogs(profile.maxConsoleLogs);
277
+ setMaxAnalyticsEventsLimit(profile.maxAnalyticsEvents);
251
278
  setShowConsoleLevels({
252
279
  info: true,
253
280
  warn: true,
@@ -281,10 +308,16 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
281
308
  }));
282
309
  if (saved.defaultTab)
283
310
  setDefaultTab(saved.defaultTab);
311
+ if (saved.isAutoRamLimitEnabled != null)
312
+ setIsAutoRamLimitEnabled(saved.isAutoRamLimitEnabled);
284
313
  if (saved.maxNetworkLogs != null)
285
314
  setMaxNetworkLogs(saved.maxNetworkLogs);
286
315
  if (saved.maxConsoleLogs != null)
287
316
  setMaxConsoleLogs(saved.maxConsoleLogs);
317
+ if (saved.maxAnalyticsEventsLimit != null)
318
+ setMaxAnalyticsEventsLimit(saved.maxAnalyticsEventsLimit);
319
+ if (saved.maxCrashLogs != null)
320
+ setMaxCrashLogs(saved.maxCrashLogs);
288
321
  if (saved.showConsoleLevels)
289
322
  setShowConsoleLevels(saved.showConsoleLevels);
290
323
  if (saved.reduxAutoRefresh != null)
@@ -327,6 +360,9 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
327
360
  defaultTab,
328
361
  maxNetworkLogs,
329
362
  maxConsoleLogs,
363
+ maxAnalyticsEventsLimit,
364
+ maxCrashLogs,
365
+ isAutoRamLimitEnabled,
330
366
  showConsoleLevels,
331
367
  reduxAutoRefresh,
332
368
  reduxExpandDepth,
@@ -340,6 +376,9 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
340
376
  defaultTab,
341
377
  maxNetworkLogs,
342
378
  maxConsoleLogs,
379
+ maxAnalyticsEventsLimit,
380
+ maxCrashLogs,
381
+ isAutoRamLimitEnabled,
343
382
  showConsoleLevels,
344
383
  reduxAutoRefresh,
345
384
  reduxExpandDepth,
@@ -414,13 +453,43 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
414
453
  return newVisibility;
415
454
  });
416
455
  };
456
+ const loadNativePage = (0, react_1.useCallback)(async (tabKey, query = '') => {
457
+ if (tabKey === 'apis' || tabKey === 'logs' || tabKey === 'analytics' || tabKey === 'crash') {
458
+ const pageData = await (0, NativeInspector_1.fetchNativeCachedPage)(tabKey, 0, 100, query);
459
+ if (pageData && pageData.items && pageData.items.length > 0) {
460
+ if (tabKey === 'apis')
461
+ setLogs(pageData.items);
462
+ else if (tabKey === 'logs')
463
+ setConsoleLogs(pageData.items);
464
+ else if (tabKey === 'analytics')
465
+ setAnalyticsEvents(pageData.items);
466
+ else if (tabKey === 'crash')
467
+ setCrashRecords(pageData.items);
468
+ }
469
+ }
470
+ }, []);
417
471
  const switchActiveTab = (0, react_1.useCallback)((key) => {
418
472
  if (key === 'redux' && !(0, reduxLogger_1.isReduxConnected)())
419
473
  return;
420
474
  if (key === 'analytics' && !(0, analyticsLogger_1.isAnalyticsConnected)())
421
475
  return;
422
- setActiveTab(key);
423
- }, []);
476
+ setSelected(null);
477
+ setSelectedEvent(null);
478
+ setSelectedLog(null);
479
+ setSelectedReduxSlice(null);
480
+ setSelectedReduxAction(null);
481
+ setSelectedCrash(null);
482
+ if (typeof react_1.default.startTransition === 'function') {
483
+ react_1.default.startTransition(() => {
484
+ setActiveTab(key);
485
+ loadNativePage(key);
486
+ });
487
+ }
488
+ else {
489
+ setActiveTab(key);
490
+ loadNativePage(key);
491
+ }
492
+ }, [loadNativePage]);
424
493
  const [selectedEvent, setSelectedEvent] = (0, react_1.useState)(null);
425
494
  const [analyticsSearch, setAnalyticsSearch] = (0, react_1.useState)('');
426
495
  const [analyticsFilters, setAnalyticsFilters] = (0, react_1.useState)({
@@ -668,6 +737,53 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
668
737
  loop.start();
669
738
  return () => loop.stop();
670
739
  }, [unreadPulseAnim]);
740
+ const isNativeModule = (0, react_1.useMemo)(() => (0, NativeInspector_2.isNativeModuleAvailable)(), []);
741
+ const useNativeFab = (react_native_1.Platform.OS === 'ios' || react_native_1.Platform.OS === 'android') && isNativeModule;
742
+ // 100% Native Main-Thread Floating Button Lifecycle
743
+ (0, react_1.useEffect)(() => {
744
+ if (!useNativeFab || !isEnabled || !enabled) {
745
+ if (useNativeFab) {
746
+ (0, NativeInspector_2.hideNativeFloatingButton)();
747
+ }
748
+ return;
749
+ }
750
+ if (visible) {
751
+ (0, NativeInspector_2.hideNativeFloatingButton)();
752
+ }
753
+ else {
754
+ (0, NativeInspector_2.showNativeFloatingButton)();
755
+ (0, NativeInspector_2.setNativeFloatingButtonBadge)(logs.length > 0 || analyticsEvents.length > 0);
756
+ }
757
+ }, [
758
+ useNativeFab,
759
+ isEnabled,
760
+ enabled,
761
+ visible,
762
+ logs.length,
763
+ analyticsEvents.length,
764
+ ]);
765
+ // Subscribe to native UI-thread floating button tap events
766
+ (0, react_1.useEffect)(() => {
767
+ if (!useNativeFab)
768
+ return;
769
+ const unsubscribe = (0, NativeInspector_2.subscribeNativeFloatingButtonPress)(() => {
770
+ setVisible(true);
771
+ });
772
+ return () => {
773
+ unsubscribe();
774
+ };
775
+ }, [useNativeFab]);
776
+ // Subscribe to physical hardware shake events (or Cmd+Ctrl+Z on iOS simulator)
777
+ (0, react_1.useEffect)(() => {
778
+ if (!useNativeFab)
779
+ return;
780
+ const unsubscribe = (0, NativeInspector_2.subscribeNativeDeviceShake)(() => {
781
+ setVisible(prev => !prev);
782
+ });
783
+ return () => {
784
+ unsubscribe();
785
+ };
786
+ }, [useNativeFab]);
671
787
  const isVisibleRefObj = (0, react_1.useRef)(visible);
672
788
  // #6 — every time the inspector is opened, land on chosen default tab & sync latest logs
673
789
  (0, react_1.useEffect)(() => {
@@ -734,6 +850,9 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
734
850
  return;
735
851
  }
736
852
  const updated = (0, crashHandler_1.getCrashRecords)();
853
+ if (updated.length > 0) {
854
+ (0, NativeInspector_1.pushNativeLogRecord)('crash', JSON.stringify(updated[0]));
855
+ }
737
856
  if (isVisibleRef.current) {
738
857
  setCrashRecords(updated);
739
858
  }
@@ -742,12 +861,16 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
742
861
  // during the very first commit, which fires before effects are mounted).
743
862
  const pendingCrashes = (0, crashHandler_1.getCrashRecords)();
744
863
  if (pendingCrashes.length > 0) {
864
+ pendingCrashes.forEach(c => (0, NativeInspector_1.pushNativeLogRecord)('crash', JSON.stringify(c)));
745
865
  setCrashRecords(pendingCrashes);
746
866
  }
747
867
  let timeoutId;
748
868
  let isFirstNetworkCall = true;
749
869
  const unsubscribe = (0, networkLogger_1.subscribeNetworkLogs)((raw) => {
750
870
  latestNetworkLogsRef.current = raw;
871
+ if (raw.length > 0) {
872
+ (0, NativeInspector_1.pushNativeLogRecord)('apis', JSON.stringify(raw[0]));
873
+ }
751
874
  if (isNetworkPausedRef.current)
752
875
  return;
753
876
  if (!isVisibleRef.current)
@@ -789,6 +912,9 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
789
912
  let isFirstAnalyticsCall = true;
790
913
  const unsubscribeAnalytics = (0, analyticsLogger_1.subscribeAnalyticsEvents)((raw) => {
791
914
  latestAnalyticsEventsRef.current = raw;
915
+ if (raw.length > 0) {
916
+ (0, NativeInspector_1.pushNativeLogRecord)('analytics', JSON.stringify(raw[0]));
917
+ }
792
918
  if (isAnalyticsPausedRef.current)
793
919
  return;
794
920
  if (!isVisibleRef.current)
@@ -828,6 +954,9 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
828
954
  let isFirstConsoleCall = true;
829
955
  const unsubscribeConsole = (0, consoleLogger_1.subscribeConsoleLogs)((raw) => {
830
956
  latestConsoleLogsRef.current = raw;
957
+ if (raw.length > 0) {
958
+ (0, NativeInspector_1.pushNativeLogRecord)('logs', JSON.stringify(raw[0]));
959
+ }
831
960
  if (isConsolePausedRef.current)
832
961
  return;
833
962
  if (!isVisibleRef.current)
@@ -898,6 +1027,10 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
898
1027
  return true;
899
1028
  if (f === 'Failed')
900
1029
  return log.status === 0 || log.status == null;
1030
+ const codeNum = parseInt(f, 10);
1031
+ if (!isNaN(codeNum)) {
1032
+ return Number(log.status) === codeNum;
1033
+ }
901
1034
  return String(log.status)[0] === f[0];
902
1035
  });
903
1036
  if (!matched)
@@ -913,9 +1046,26 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
913
1046
  if (!matchedMethod)
914
1047
  return false;
915
1048
  }
916
- // Search Bar Check
917
- if (search && !log.url?.toLowerCase().includes(search.toLowerCase()))
918
- return false;
1049
+ // Comprehensive Search Bar Check
1050
+ if (search && search.trim().length > 0) {
1051
+ const queryTokens = search.trim().toLowerCase().split(/\s+/).filter(Boolean);
1052
+ const routePath = logRouteMapRef.current.get(log.id)?.path || '';
1053
+ const reqStr = typeof log.request === 'string' ? log.request : JSON.stringify(log.request || '');
1054
+ const resStr = typeof log.response === 'string' ? log.response : JSON.stringify(log.response || '');
1055
+ const searchTarget = [
1056
+ log.method || '',
1057
+ log.url || '',
1058
+ String(log.status ?? ''),
1059
+ routePath,
1060
+ reqStr,
1061
+ resStr,
1062
+ JSON.stringify(log.requestHeaders || ''),
1063
+ JSON.stringify(log.responseHeaders || ''),
1064
+ ].join(' ').toLowerCase();
1065
+ const isMatch = queryTokens.every(token => searchTarget.includes(token));
1066
+ if (!isMatch)
1067
+ return false;
1068
+ }
919
1069
  return true;
920
1070
  });
921
1071
  if (sortOrder === 'oldest') {
@@ -1070,12 +1220,20 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
1070
1220
  const filteredAnalyticsEvents = (0, react_1.useMemo)(() => {
1071
1221
  let events = analyticsEvents;
1072
1222
  // Search query filter
1073
- if (analyticsSearch) {
1074
- const s = analyticsSearch.toLowerCase();
1075
- events = events.filter(e => e.name.toLowerCase().includes(s) ||
1076
- JSON.stringify(e.params || {}).toLowerCase().includes(s) ||
1077
- (e.screenName ?? '').toLowerCase().includes(s) ||
1078
- (e.pageTitle ?? '').toLowerCase().includes(s));
1223
+ if (analyticsSearch && analyticsSearch.trim().length > 0) {
1224
+ const queryTokens = analyticsSearch.trim().toLowerCase().split(/\s+/).filter(Boolean);
1225
+ events = events.filter(e => {
1226
+ const searchTarget = [
1227
+ e.name || '',
1228
+ JSON.stringify(e.params || ''),
1229
+ JSON.stringify(e.userProperties || ''),
1230
+ e.screenName || '',
1231
+ e.pageTitle || '',
1232
+ e.userId || '',
1233
+ e.source || '',
1234
+ ].join(' ').toLowerCase();
1235
+ return queryTokens.every(token => searchTarget.includes(token));
1236
+ });
1079
1237
  }
1080
1238
  // Category filter
1081
1239
  if (analyticsFilters.categories.size > 0 && !analyticsFilters.categories.has('all')) {
@@ -1113,16 +1271,15 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
1113
1271
  }
1114
1272
  // Payload complexity filter
1115
1273
  if (analyticsFilters.payloadComplexity !== 'all') {
1116
- events = events.filter(e => {
1117
- const count = e.params ? Object.keys(e.params).length : 0;
1118
- if (analyticsFilters.payloadComplexity === 'none')
1119
- return count === 0;
1120
- if (analyticsFilters.payloadComplexity === 'simple')
1121
- return count >= 1 && count <= 5;
1122
- if (analyticsFilters.payloadComplexity === 'heavy')
1123
- return count > 5;
1124
- return true;
1125
- });
1274
+ if (analyticsFilters.payloadComplexity === 'none') {
1275
+ events = events.filter(e => !e.params || Object.keys(e.params).length === 0);
1276
+ }
1277
+ else if (analyticsFilters.payloadComplexity === 'simple') {
1278
+ events = events.filter(e => e.params && Object.keys(e.params).length <= 3);
1279
+ }
1280
+ else if (analyticsFilters.payloadComplexity === 'heavy') {
1281
+ events = events.filter(e => e.params && Object.keys(e.params).length > 3);
1282
+ }
1126
1283
  }
1127
1284
  // Conversion / Goal events filter
1128
1285
  if (analyticsFilters.onlyConversions) {
@@ -1155,10 +1312,8 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
1155
1312
  }
1156
1313
  // Has Revenue filter
1157
1314
  if (analyticsFilters.hasRevenue) {
1158
- events = events.filter(e => {
1159
- const val = e.params?.value ?? e.params?.price;
1160
- return val !== undefined && val !== null && Number(val) > 0;
1161
- });
1315
+ events = events.filter(e => (e.params?.value != null && !isNaN(Number(e.params.value))) ||
1316
+ (e.params?.price != null && !isNaN(Number(e.params.price))));
1162
1317
  }
1163
1318
  // Has Items filter
1164
1319
  if (analyticsFilters.hasItems) {
@@ -1223,16 +1378,23 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
1223
1378
  if (logFilters.has('user-log') && log.sourceMethod === 'log')
1224
1379
  return true;
1225
1380
  if (logFilters.has('analytics') &&
1226
- log.message.toLowerCase().includes('[analytics error]'))
1381
+ log.message?.toLowerCase().includes('[analytics error]'))
1227
1382
  return true;
1228
1383
  return false;
1229
1384
  });
1230
1385
  }
1231
- // Search bar check
1232
- if (logSearch) {
1233
- const s = logSearch.toLowerCase();
1234
- result = result.filter(log => log.message.toLowerCase().includes(s) ||
1235
- (log.caller ?? '').toLowerCase().includes(s));
1386
+ // Comprehensive Search bar check
1387
+ if (logSearch && logSearch.trim().length > 0) {
1388
+ const queryTokens = logSearch.trim().toLowerCase().split(/\s+/).filter(Boolean);
1389
+ result = result.filter(log => {
1390
+ const searchTarget = [
1391
+ log.message || '',
1392
+ log.caller || '',
1393
+ log.type || '',
1394
+ log.sourceMethod || '',
1395
+ ].join(' ').toLowerCase();
1396
+ return queryTokens.every(token => searchTarget.includes(token));
1397
+ });
1236
1398
  }
1237
1399
  // #7 — apply sort order (newest/oldest first)
1238
1400
  result = [...result].sort((a, b) => logSortOrder === 'newest'
@@ -1269,10 +1431,17 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
1269
1431
  ]);
1270
1432
  const logCounts = (0, react_1.useMemo)(() => {
1271
1433
  let searchedLogs = visibleConsoleLogs;
1272
- if (logSearch) {
1273
- const s = logSearch.toLowerCase();
1274
- searchedLogs = visibleConsoleLogs.filter(log => log.message.toLowerCase().includes(s) ||
1275
- (log.caller ?? '').toLowerCase().includes(s));
1434
+ if (logSearch && logSearch.trim().length > 0) {
1435
+ const queryTokens = logSearch.trim().toLowerCase().split(/\s+/).filter(Boolean);
1436
+ searchedLogs = visibleConsoleLogs.filter(log => {
1437
+ const searchTarget = [
1438
+ log.message || '',
1439
+ log.caller || '',
1440
+ log.type || '',
1441
+ log.sourceMethod || '',
1442
+ ].join(' ').toLowerCase();
1443
+ return queryTokens.every(token => searchTarget.includes(token));
1444
+ });
1276
1445
  }
1277
1446
  const total = visibleConsoleLogs.length;
1278
1447
  return {
@@ -1466,6 +1635,7 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
1466
1635
  unreadPulseAnim,
1467
1636
  runClearAllWithAnimation,
1468
1637
  // ─── FAB / launcher ─────────────────────────────────────────────────
1638
+ useNativeFab,
1469
1639
  fabPan,
1470
1640
  fabPanResponder,
1471
1641
  fabDraggedRef,
@@ -1583,6 +1753,11 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
1583
1753
  setMaxNetworkLogs,
1584
1754
  maxConsoleLogs,
1585
1755
  setMaxConsoleLogs,
1756
+ maxAnalyticsEventsLimit,
1757
+ setMaxAnalyticsEventsLimit,
1758
+ isAutoRamLimitEnabled,
1759
+ setIsAutoRamLimitEnabled,
1760
+ deviceFreeRamMb,
1586
1761
  reduxAutoRefresh,
1587
1762
  setReduxAutoRefreshState,
1588
1763
  reduxExpandDepth,
@@ -1678,6 +1853,21 @@ var decorators_1 = require("./decorators");
1678
1853
  Object.defineProperty(exports, "InspectLog", { enumerable: true, get: function () { return decorators_1.InspectLog; } });
1679
1854
  Object.defineProperty(exports, "InspectTrackTime", { enumerable: true, get: function () { return decorators_1.InspectTrackTime; } });
1680
1855
  Object.defineProperty(exports, "InspectCatch", { enumerable: true, get: function () { return decorators_1.InspectCatch; } });
1856
+ var NativeInspector_3 = require("./native/NativeInspector");
1857
+ Object.defineProperty(exports, "getNativeDeviceMetrics", { enumerable: true, get: function () { return NativeInspector_3.getNativeDeviceMetrics; } });
1858
+ Object.defineProperty(exports, "enableNativeCrashProtection", { enumerable: true, get: function () { return NativeInspector_3.enableNativeCrashProtection; } });
1859
+ Object.defineProperty(exports, "subscribeNativeCrashes", { enumerable: true, get: function () { return NativeInspector_3.subscribeNativeCrashes; } });
1860
+ Object.defineProperty(exports, "showNativeFloatingButton", { enumerable: true, get: function () { return NativeInspector_3.showNativeFloatingButton; } });
1861
+ Object.defineProperty(exports, "hideNativeFloatingButton", { enumerable: true, get: function () { return NativeInspector_3.hideNativeFloatingButton; } });
1862
+ Object.defineProperty(exports, "setNativeFloatingButtonBadge", { enumerable: true, get: function () { return NativeInspector_3.setNativeFloatingButtonBadge; } });
1863
+ Object.defineProperty(exports, "subscribeNativeFloatingButtonPress", { enumerable: true, get: function () { return NativeInspector_3.subscribeNativeFloatingButtonPress; } });
1864
+ Object.defineProperty(exports, "subscribeNativeDeviceShake", { enumerable: true, get: function () { return NativeInspector_3.subscribeNativeDeviceShake; } });
1865
+ Object.defineProperty(exports, "startNativeFpsMonitoring", { enumerable: true, get: function () { return NativeInspector_3.startNativeFpsMonitoring; } });
1866
+ Object.defineProperty(exports, "stopNativeFpsMonitoring", { enumerable: true, get: function () { return NativeInspector_3.stopNativeFpsMonitoring; } });
1867
+ Object.defineProperty(exports, "getNativeFpsMetrics", { enumerable: true, get: function () { return NativeInspector_3.getNativeFpsMetrics; } });
1868
+ Object.defineProperty(exports, "getNativeStorageItem", { enumerable: true, get: function () { return NativeInspector_3.getNativeStorageItem; } });
1869
+ Object.defineProperty(exports, "setNativeStorageItem", { enumerable: true, get: function () { return NativeInspector_3.setNativeStorageItem; } });
1870
+ Object.defineProperty(exports, "isNativeModuleAvailable", { enumerable: true, get: function () { return NativeInspector_3.isNativeModuleAvailable; } });
1681
1871
  var types_1 = require("./types");
1682
1872
  Object.defineProperty(exports, "ActiveTab", { enumerable: true, get: function () { return types_1.ActiveTab; } });
1683
1873
  Object.defineProperty(exports, "Method", { enumerable: true, get: function () { return types_1.Method; } });
@@ -0,0 +1,125 @@
1
+ export interface NativeDeviceMetrics {
2
+ totalRAM?: number;
3
+ freeRAM?: number;
4
+ usedRAM?: number;
5
+ residentMemory?: number;
6
+ virtualMemory?: number;
7
+ isLowMemory?: boolean;
8
+ nativeHeapAllocated?: number;
9
+ nativeHeapSize?: number;
10
+ nativeHeapFree?: number;
11
+ freeStorage?: number;
12
+ totalStorage?: number;
13
+ batteryPercent?: number;
14
+ isCharging?: boolean;
15
+ deviceModel?: string;
16
+ deviceBrand?: string;
17
+ osVersion?: string;
18
+ apiLevel?: number;
19
+ cpuAbi?: string;
20
+ }
21
+ export interface NativeCrashEvent {
22
+ platform: 'android' | 'ios';
23
+ error: string;
24
+ name?: string;
25
+ stack?: string;
26
+ threadName?: string;
27
+ timestamp: number;
28
+ }
29
+ export declare const isNativeModuleAvailable: () => boolean;
30
+ /**
31
+ * Retrieves low-level native hardware and system metrics (RAM, Heap, Disk, Battery, CPU).
32
+ */
33
+ export declare const getNativeDeviceMetrics: () => Promise<NativeDeviceMetrics | null>;
34
+ /**
35
+ * Enables native signal and uncaught exception protection in the iOS / Android runtime.
36
+ * Automatically ensures the native floating icon is shown and available before UI renders.
37
+ */
38
+ export declare const enableNativeCrashProtection: (options?: {
39
+ showFloatingButton?: boolean;
40
+ }) => Promise<boolean>;
41
+ /**
42
+ * Subscribes to fatal native crash events caught by the iOS / Kotlin exception handlers.
43
+ */
44
+ export declare const subscribeNativeCrashes: (callback: (event: NativeCrashEvent) => void) => (() => void);
45
+ export interface FloatingButtonOptions {
46
+ size?: number;
47
+ x?: number;
48
+ y?: number;
49
+ }
50
+ /**
51
+ * Displays the 100% native main-thread floating overlay button.
52
+ * Dragging & touches run on the native UI thread, completely isolated from JS thread stalls.
53
+ */
54
+ export declare const showNativeFloatingButton: (options?: FloatingButtonOptions) => Promise<boolean>;
55
+ /**
56
+ * Hides the native floating overlay button.
57
+ */
58
+ export declare const hideNativeFloatingButton: () => Promise<boolean>;
59
+ /**
60
+ * Updates the badge/status dot on the native floating overlay button.
61
+ */
62
+ export declare const setNativeFloatingButtonBadge: (hasBadge: boolean) => Promise<boolean>;
63
+ /**
64
+ * Subscribes to tap events on the native floating button.
65
+ */
66
+ export declare const subscribeNativeFloatingButtonPress: (callback: () => void) => (() => void);
67
+ /**
68
+ * Starts hardware-accurate native UI thread FPS tracking (CADisplayLink / Choreographer).
69
+ */
70
+ export declare const startNativeFpsMonitoring: () => Promise<boolean>;
71
+ /**
72
+ * Stops native FPS tracking.
73
+ */
74
+ export declare const stopNativeFpsMonitoring: () => Promise<boolean>;
75
+ export interface NativeFpsMetrics {
76
+ fps: number;
77
+ targetFps: number;
78
+ }
79
+ /**
80
+ * Reads the latest live hardware FPS from CADisplayLink (iOS) or Choreographer (Android).
81
+ */
82
+ export declare const getNativeFpsMetrics: () => Promise<NativeFpsMetrics>;
83
+ /**
84
+ * Subscribes to physical hardware shake events (or Cmd+Ctrl+Z on iOS simulator).
85
+ */
86
+ export declare const subscribeNativeDeviceShake: (callback: () => void) => (() => void);
87
+ /**
88
+ * Reads a persisted value synchronously from native NSUserDefaults / SharedPreferences.
89
+ */
90
+ export declare const getNativeStorageItem: (key: string) => Promise<string | null>;
91
+ /**
92
+ * Persists a key-value pair to native NSUserDefaults / SharedPreferences with 0ms latency.
93
+ */
94
+ export declare const setNativeStorageItem: (key: string, value: string | null) => Promise<boolean>;
95
+ export type HapticStyle = 'light' | 'medium' | 'heavy' | 'success' | 'warning' | 'error';
96
+ /**
97
+ * Triggers hardware native haptic feedback (iOS UIFeedbackGenerator / Android VibrationEffect).
98
+ */
99
+ export declare const triggerNativeHaptic: (style?: HapticStyle) => Promise<boolean>;
100
+ export interface NativeSystemMetrics {
101
+ thermalState: 'nominal' | 'fair' | 'serious' | 'critical';
102
+ residentRamMb: number;
103
+ totalPhysicalRamMb: number;
104
+ fps: number;
105
+ activeCpuCores: number;
106
+ }
107
+ /**
108
+ * Retrieves live system thermal state and RAM telemetry directly from native layer.
109
+ */
110
+ export declare const getNativeSystemMetrics: () => Promise<NativeSystemMetrics | null>;
111
+ /**
112
+ * Pushes a log payload to native background worker queues for instant native page caching.
113
+ */
114
+ export declare const pushNativeLogRecord: (pageKey: "apis" | "logs" | "analytics" | "crash", jsonPayload: string) => Promise<boolean>;
115
+ export interface NativeCachedPageResult<T = any> {
116
+ pageKey: string;
117
+ total: number;
118
+ offset: number;
119
+ items: T[];
120
+ }
121
+ /**
122
+ * Fetches pre-indexed, pre-sliced page data directly from native background memory queues.
123
+ * Delivers instantaneous 0ms page loading without blocking JS render thread.
124
+ */
125
+ export declare const fetchNativeCachedPage: <T = any>(pageKey: "apis" | "logs" | "analytics" | "crash", offset?: number, limit?: number, query?: string) => Promise<NativeCachedPageResult<T> | null>;