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
@@ -1,47 +1,45 @@
1
1
  import React, { useRef } from 'react';
2
- import { Animated, Pressable, StyleSheet, Platform } from 'react-native';
3
- const TouchableScale = React.memo(function TouchableScale({ onPress, onLongPress, style, children, hitSlop, disabled, accessible, accessibilityRole, accessibilityLabel, accessibilityHint, accessibilityState, accessibilityValue, ...rest }) {
4
- if (Platform.OS === 'android') {
5
- return (<Pressable accessible={accessible} accessibilityRole={accessibilityRole} accessibilityLabel={accessibilityLabel} accessibilityHint={accessibilityHint} accessibilityState={accessibilityState} accessibilityValue={accessibilityValue} disabled={disabled} onPress={onPress} onLongPress={onLongPress} hitSlop={hitSlop} style={({ pressed }) => [
6
- style,
7
- { opacity: pressed ? 0.75 : 1 },
8
- ]} {...rest}>
9
- {children}
10
- </Pressable>);
11
- }
2
+ import { Animated, Pressable } from 'react-native';
3
+ import { triggerNativeHaptic } from '../native/NativeInspector';
4
+ const AnimatedPressable = Animated.createAnimatedComponent(Pressable);
5
+ const TouchableScale = React.memo(function TouchableScale({ onPress, onLongPress, style, children, hitSlop, disabled, enableHaptics = true, accessible, accessibilityRole, accessibilityLabel, accessibilityHint, accessibilityState, accessibilityValue, ...rest }) {
12
6
  const scale = useRef(new Animated.Value(1)).current;
13
7
  const opacity = useRef(new Animated.Value(1)).current;
14
- const animatePress = (pressed) => {
8
+ const handlePressIn = () => {
9
+ if (disabled)
10
+ return;
11
+ if (enableHaptics) {
12
+ triggerNativeHaptic('light');
13
+ }
15
14
  Animated.parallel([
16
- Animated.spring(scale, {
17
- toValue: pressed ? 0.94 : 1,
18
- friction: 6,
19
- tension: 120,
15
+ Animated.timing(scale, {
16
+ toValue: 0.94,
17
+ duration: 50,
20
18
  useNativeDriver: true,
21
19
  }),
22
20
  Animated.timing(opacity, {
23
- toValue: pressed ? 0.86 : 1,
24
- duration: pressed ? 90 : 140,
21
+ toValue: 0.85,
22
+ duration: 50,
25
23
  useNativeDriver: true,
26
24
  }),
27
25
  ]).start();
28
26
  };
29
- const flattenedStyle = StyleSheet.flatten(style) || {};
30
- const layoutStyle = {
31
- flex: flattenedStyle.flex,
32
- flexDirection: flattenedStyle.flexDirection,
33
- alignItems: flattenedStyle.alignItems,
34
- justifyContent: flattenedStyle.justifyContent,
35
- flexWrap: flattenedStyle.flexWrap,
36
- alignSelf: flattenedStyle.alignSelf,
37
- flexGrow: flattenedStyle.flexGrow,
38
- flexShrink: flattenedStyle.flexShrink,
39
- gap: flattenedStyle.gap,
27
+ const handlePressOut = () => {
28
+ Animated.parallel([
29
+ Animated.timing(scale, {
30
+ toValue: 1,
31
+ duration: 100,
32
+ useNativeDriver: true,
33
+ }),
34
+ Animated.timing(opacity, {
35
+ toValue: 1,
36
+ duration: 100,
37
+ useNativeDriver: true,
38
+ }),
39
+ ]).start();
40
40
  };
41
- return (<Pressable accessible={accessible} accessibilityRole={accessibilityRole} accessibilityLabel={accessibilityLabel} accessibilityHint={accessibilityHint} accessibilityState={accessibilityState} accessibilityValue={accessibilityValue} disabled={disabled} style={style} onPressIn={() => animatePress(true)} onPressOut={() => animatePress(false)} onPress={onPress} onLongPress={onLongPress} hitSlop={hitSlop} {...rest}>
42
- <Animated.View style={[{ opacity, transform: [{ scale }] }, layoutStyle]}>
43
- {children}
44
- </Animated.View>
45
- </Pressable>);
41
+ return (<AnimatedPressable accessible={accessible} accessibilityRole={accessibilityRole} accessibilityLabel={accessibilityLabel} accessibilityHint={accessibilityHint} accessibilityState={accessibilityState} accessibilityValue={accessibilityValue} disabled={disabled} style={[style, { opacity, transform: [{ scale }] }]} onPressIn={handlePressIn} onPressOut={handlePressOut} onPress={onPress} onLongPress={onLongPress} hitSlop={hitSlop} {...rest}>
42
+ {children}
43
+ </AnimatedPressable>);
46
44
  });
47
45
  export default TouchableScale;
@@ -1,6 +1,5 @@
1
1
  import { Method } from '../types';
2
- import { StatusFilter } from '../types';
3
- export declare const STATUS_FILTERS: StatusFilter[];
2
+ export declare const STATUS_FILTERS: string[];
4
3
  export declare const METHOD_COLORS: Record<Method, string>;
5
4
  export declare const DOMAIN_COLORS: string[];
6
5
  export declare const DURATION_FAST_MS = 200;
@@ -3,9 +3,13 @@ import { AppColors } from '../styles/AppColors';
3
3
  export const STATUS_FILTERS = [
4
4
  'ALL',
5
5
  '2xx',
6
+ '200',
6
7
  '3xx',
7
8
  '4xx',
9
+ '400',
10
+ '404',
8
11
  '5xx',
12
+ '500',
9
13
  'Failed',
10
14
  ];
11
15
  export const METHOD_COLORS = {
@@ -1 +1 @@
1
- export declare const LIB_VERSION = "1.1.35";
1
+ export declare const LIB_VERSION = "2.0.0";
@@ -1,3 +1,3 @@
1
1
  // AUTO-GENERATED FILE — do not edit by hand.
2
2
  // Regenerated from package.json on every build by scripts/gen-version.js.
3
- export const LIB_VERSION = '1.1.35';
3
+ export const LIB_VERSION = '2.0.0';
@@ -17,6 +17,10 @@ export declare const getCollectionEnabled: () => boolean;
17
17
  * Useful for custom analytics wrappers or testing.
18
18
  */
19
19
  export declare const logAnalyticsEvent: (name: string, params?: Record<string, any>, userProperties?: Record<string, any>) => void;
20
+ /**
21
+ * Returns true if analytics logging is active (always ready for custom and Firebase events).
22
+ */
20
23
  export declare const isAnalyticsConnected: () => boolean;
24
+ export declare const isFirebaseAnalyticsPatched: () => boolean;
21
25
  export declare const setupAnalyticsLogger: (analyticsInstance: any) => void;
22
26
  export declare const autoSetupAnalyticsLogger: () => boolean;
@@ -94,10 +94,11 @@ export const logAnalyticsEvent = (name, params = {}, userProperties = {}) => {
94
94
  * setupAnalyticsLogger(analytics());
95
95
  */
96
96
  let isAnalyticsPatched = false;
97
- export const isAnalyticsConnected = () => isAnalyticsPatched ||
98
- events.length > 0 ||
99
- Object.keys(currentUserProperties).length > 0 ||
100
- currentUserId != null;
97
+ /**
98
+ * Returns true if analytics logging is active (always ready for custom and Firebase events).
99
+ */
100
+ export const isAnalyticsConnected = () => true;
101
+ export const isFirebaseAnalyticsPatched = () => isAnalyticsPatched;
101
102
  export const setupAnalyticsLogger = (analyticsInstance) => {
102
103
  if (!analyticsInstance) {
103
104
  console.warn('[AnalyticsLogger] No analytics instance provided — skipping setup.');
@@ -1,6 +1,7 @@
1
1
  import { LogBox, NativeModules, TurboModuleRegistry, NativeEventEmitter, Platform, AppState, Dimensions, } from 'react-native';
2
2
  import { CrashExportFormat, CrashType } from '../types/enums';
3
3
  import { addLogFromCrash } from './consoleLogger';
4
+ import { showNativeFloatingButton, setNativeFloatingButtonBadge, } from '../native/NativeInspector';
4
5
  import { t } from '../i18n';
5
6
  export { CrashExportFormat };
6
7
  let crashListeners = [];
@@ -365,6 +366,12 @@ export const handleInterceptedCrash = (errorOrTitle, rawStack, isFatal = false,
365
366
  logId: log?.id,
366
367
  crashRecord,
367
368
  });
369
+ // Ensure native floating icon is visible & badged even if React UI is broken
370
+ try {
371
+ showNativeFloatingButton();
372
+ setNativeFloatingButtonBadge(true);
373
+ }
374
+ catch { }
368
375
  return crashRecord;
369
376
  }
370
377
  catch (err) {
@@ -156,9 +156,18 @@ export const getFetchCommand = (log) => {
156
156
  export const deduplicateLogs = (raw) => {
157
157
  const map = new Map();
158
158
  raw.forEach(entry => {
159
- if (!map.has(entry.id) || entry.status != null) {
159
+ if (!map.has(entry.id)) {
160
160
  map.set(entry.id, entry);
161
161
  }
162
+ else {
163
+ const existing = map.get(entry.id);
164
+ if (existing.status == null && entry.status != null) {
165
+ map.set(entry.id, entry);
166
+ }
167
+ else if ((entry.startTime ?? 0) >= (existing.startTime ?? 0)) {
168
+ map.set(entry.id, entry);
169
+ }
170
+ }
162
171
  });
163
172
  return Array.from(map.values()).sort((a, b) => b.id - a.id);
164
173
  };
@@ -6,3 +6,12 @@ export declare function saveSettings(settings: PersistedSettings): void;
6
6
  export declare function clearPersistedSettings(): Promise<void>;
7
7
  export declare const isPersistentStorageAvailable: () => boolean;
8
8
  export declare function getCustomStorage(): InspectorStorage | null;
9
+ export interface RamLimitsProfile {
10
+ maxNetworkLogs: number;
11
+ maxConsoleLogs: number;
12
+ maxAnalyticsEvents: number;
13
+ maxCrashRecords: number;
14
+ profileName: 'High-End' | 'Standard' | 'Compact' | 'Ultra-Light';
15
+ freeRamMb: number;
16
+ }
17
+ export declare function calculateRamBasedLimits(freeRamMb: number): RamLimitsProfile;
@@ -3,6 +3,7 @@
3
3
  // Backed by iOS Settings (NSUserDefaults) for iOS, or custom storage if passed (e.g. AsyncStorage/MMKV).
4
4
  // Contains an in-memory fallback for Android or Jest test environments.
5
5
  import { Platform, Settings } from 'react-native';
6
+ import { getNativeStorageItem, setNativeStorageItem, isNativeModuleAvailable, } from '../native/NativeInspector';
6
7
  // In-memory fallback (settings survive for the app session only).
7
8
  const memory = new Map();
8
9
  let customStorage = null;
@@ -19,6 +20,13 @@ export async function loadSettings() {
19
20
  const parsed = JSON.parse(raw);
20
21
  return parsed && typeof parsed === 'object' ? parsed : {};
21
22
  }
23
+ if (isNativeModuleAvailable()) {
24
+ const raw = await getNativeStorageItem(SETTINGS_KEY);
25
+ if (raw) {
26
+ const parsed = JSON.parse(raw);
27
+ return parsed && typeof parsed === 'object' ? parsed : {};
28
+ }
29
+ }
22
30
  if (Platform.OS === 'ios') {
23
31
  const raw = Settings.get(SETTINGS_KEY);
24
32
  if (!raw)
@@ -29,7 +37,7 @@ export async function loadSettings() {
29
37
  }
30
38
  return raw && typeof raw === 'object' ? raw : {};
31
39
  }
32
- // Android/fallback: memory
40
+ // In-memory fallback
33
41
  const raw = memory.get(SETTINGS_KEY);
34
42
  if (!raw)
35
43
  return {};
@@ -47,11 +55,13 @@ export function saveSettings(settings) {
47
55
  customStorage.setItem(SETTINGS_KEY, raw);
48
56
  return;
49
57
  }
58
+ if (isNativeModuleAvailable()) {
59
+ setNativeStorageItem(SETTINGS_KEY, raw);
60
+ }
50
61
  if (Platform.OS === 'ios') {
51
62
  Settings.set({ [SETTINGS_KEY]: raw });
52
63
  return;
53
64
  }
54
- // Android/fallback: memory
55
65
  memory.set(SETTINGS_KEY, raw);
56
66
  }
57
67
  catch {
@@ -69,6 +79,9 @@ export async function clearPersistedSettings() {
69
79
  }
70
80
  return;
71
81
  }
82
+ if (isNativeModuleAvailable()) {
83
+ await setNativeStorageItem(SETTINGS_KEY, null);
84
+ }
72
85
  if (Platform.OS === 'ios') {
73
86
  Settings.set({ [SETTINGS_KEY]: null });
74
87
  return;
@@ -80,8 +93,50 @@ export async function clearPersistedSettings() {
80
93
  }
81
94
  }
82
95
  export const isPersistentStorageAvailable = () => {
83
- return customStorage !== null || Platform.OS === 'ios';
96
+ return customStorage !== null || isNativeModuleAvailable() || Platform.OS === 'ios';
84
97
  };
85
98
  export function getCustomStorage() {
86
99
  return customStorage;
87
100
  }
101
+ export function calculateRamBasedLimits(freeRamMb) {
102
+ if (freeRamMb >= 3000) {
103
+ return {
104
+ maxNetworkLogs: 1000,
105
+ maxConsoleLogs: 1500,
106
+ maxAnalyticsEvents: 500,
107
+ maxCrashRecords: 100,
108
+ profileName: 'High-End',
109
+ freeRamMb,
110
+ };
111
+ }
112
+ else if (freeRamMb >= 1500) {
113
+ return {
114
+ maxNetworkLogs: 500,
115
+ maxConsoleLogs: 750,
116
+ maxAnalyticsEvents: 250,
117
+ maxCrashRecords: 50,
118
+ profileName: 'Standard',
119
+ freeRamMb,
120
+ };
121
+ }
122
+ else if (freeRamMb >= 600) {
123
+ return {
124
+ maxNetworkLogs: 200,
125
+ maxConsoleLogs: 300,
126
+ maxAnalyticsEvents: 100,
127
+ maxCrashRecords: 25,
128
+ profileName: 'Compact',
129
+ freeRamMb,
130
+ };
131
+ }
132
+ else {
133
+ return {
134
+ maxNetworkLogs: 100,
135
+ maxConsoleLogs: 150,
136
+ maxAnalyticsEvents: 50,
137
+ maxCrashRecords: 15,
138
+ profileName: 'Ultra-Light',
139
+ freeRamMb,
140
+ };
141
+ }
142
+ }
@@ -12,4 +12,5 @@ export { connectReduxStore, inspectorReduxMiddleware, getReduxState, subscribeRe
12
12
  export { getEventCategory, registerGAPlugin, type GAPlugin, } from './helpers/gaAnalyticsRegistry';
13
13
  export { usePerformanceTracker, useComponentProfiler, useNavigationProfiler, trackComponentRender, trackNavigationTransition, trackHeavyTask, measureAsync, getHermesMemoryStats, registerComponentProfile, subscribeRenderProfiles, getRenderProfiles, logPerformanceEvent, clearPerformanceEvents, subscribePerformanceEvents, getPerformanceEvents, getInitialRenderProfiles, getInitialPerformanceEvents, generateFixSnippet, } from './customHooks/performanceTracker';
14
14
  export { InspectLog, InspectTrackTime, InspectCatch, type InspectLogOptions, } from './decorators';
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';
15
16
  export { ActiveTab, Method, StatusFilter, SortOrder, LocalFilter, ModalAnimationType, SettingsPage, SettingsSubTab, LogFilter, ConsoleLogType, AnalyticsEventSource, GAEventCategory, StackFrameType, DiffResultType, BundleSubTab, PerformanceSubTab, CrashType, CrashExportFormat, CrashDetailSubTab, CrashFilterType, BreadcrumbType, } from './types';