react-native-inapp-inspector 1.1.35 → 2.0.1
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.
- package/README.md +123 -101
- package/android/build.gradle +13 -1
- package/android/src/main/java/com/inappinspector/NetworkInspectorModule.kt +890 -0
- package/android/src/main/java/com/inappinspector/NetworkInspectorPackage.kt +17 -0
- package/dist/commonjs/components/ConsoleLogCard.js +5 -5
- package/dist/commonjs/components/CopyButton.js +3 -0
- package/dist/commonjs/components/EndOfListFooter.js +1 -1
- package/dist/commonjs/components/ErrorBoundary.js +3 -0
- package/dist/commonjs/components/Inspector/AnalyticsTab.js +25 -73
- package/dist/commonjs/components/Inspector/BundleTab.js +671 -189
- package/dist/commonjs/components/Inspector/ConsoleTab.js +110 -99
- package/dist/commonjs/components/Inspector/CrashTab.js +99 -91
- package/dist/commonjs/components/Inspector/InspectorHeader.js +107 -20
- package/dist/commonjs/components/Inspector/MainScreen.js +111 -68
- package/dist/commonjs/components/Inspector/NetworkTab.js +151 -30
- package/dist/commonjs/components/Inspector/PerformanceTab.js +96 -3
- package/dist/commonjs/components/Inspector/ReduxTab.js +18 -10
- package/dist/commonjs/components/Inspector/SettingsPanel.js +1218 -1238
- package/dist/commonjs/components/Inspector/TabBar.js +4 -2
- package/dist/commonjs/components/JsonViewer.js +9 -4
- package/dist/commonjs/components/LogCard.js +31 -1
- package/dist/commonjs/components/LogSyntaxHighlighter.d.ts +16 -0
- package/dist/commonjs/components/LogSyntaxHighlighter.js +130 -0
- package/dist/commonjs/components/NetworkIcons.d.ts +3 -0
- package/dist/commonjs/components/NetworkIcons.js +15 -1
- package/dist/commonjs/components/Slider.d.ts +13 -0
- package/dist/commonjs/components/Slider.js +261 -0
- package/dist/commonjs/components/TouchableScale.d.ts +1 -0
- package/dist/commonjs/components/TouchableScale.js +30 -32
- package/dist/commonjs/constants/index.d.ts +1 -2
- package/dist/commonjs/constants/index.js +4 -0
- package/dist/commonjs/constants/version.d.ts +1 -1
- package/dist/commonjs/constants/version.js +1 -1
- package/dist/commonjs/customHooks/analyticsLogger.d.ts +4 -0
- package/dist/commonjs/customHooks/analyticsLogger.js +8 -6
- package/dist/commonjs/customHooks/crashHandler.js +8 -1
- package/dist/commonjs/helpers/index.d.ts +1 -0
- package/dist/commonjs/helpers/index.js +25 -1
- package/dist/commonjs/helpers/searchQueryParser.d.ts +6 -0
- package/dist/commonjs/helpers/searchQueryParser.js +236 -0
- package/dist/commonjs/helpers/settingsStore.d.ts +9 -0
- package/dist/commonjs/helpers/settingsStore.js +59 -3
- package/dist/commonjs/index.d.ts +1 -0
- package/dist/commonjs/index.js +220 -43
- package/dist/commonjs/native/NativeInspector.d.ts +125 -0
- package/dist/commonjs/native/NativeInspector.js +313 -0
- package/dist/commonjs/native/NativeNetworkInspector.d.ts +22 -0
- package/dist/commonjs/native/NativeNetworkInspector.js +4 -0
- package/dist/commonjs/styles/index.js +41 -41
- package/dist/commonjs/types/enums.d.ts +1 -1
- package/dist/commonjs/types/interfaces.d.ts +9 -0
- package/dist/esm/components/ConsoleLogCard.js +5 -5
- package/dist/esm/components/CopyButton.js +3 -0
- package/dist/esm/components/EndOfListFooter.js +2 -2
- package/dist/esm/components/ErrorBoundary.js +3 -0
- package/dist/esm/components/Inspector/AnalyticsTab.js +27 -75
- package/dist/esm/components/Inspector/BundleTab.js +671 -189
- package/dist/esm/components/Inspector/ConsoleTab.js +111 -100
- package/dist/esm/components/Inspector/CrashTab.js +99 -91
- package/dist/esm/components/Inspector/InspectorHeader.js +108 -21
- package/dist/esm/components/Inspector/MainScreen.js +113 -70
- package/dist/esm/components/Inspector/NetworkTab.js +152 -31
- package/dist/esm/components/Inspector/PerformanceTab.js +96 -3
- package/dist/esm/components/Inspector/ReduxTab.js +18 -10
- package/dist/esm/components/Inspector/SettingsPanel.js +1222 -1242
- package/dist/esm/components/Inspector/TabBar.js +4 -2
- package/dist/esm/components/JsonViewer.js +9 -4
- package/dist/esm/components/LogCard.js +32 -2
- package/dist/esm/components/LogSyntaxHighlighter.d.ts +16 -0
- package/dist/esm/components/LogSyntaxHighlighter.js +123 -0
- package/dist/esm/components/NetworkIcons.d.ts +3 -0
- package/dist/esm/components/NetworkIcons.js +11 -0
- package/dist/esm/components/Slider.d.ts +13 -0
- package/dist/esm/components/Slider.js +222 -0
- package/dist/esm/components/TouchableScale.d.ts +1 -0
- package/dist/esm/components/TouchableScale.js +31 -33
- package/dist/esm/constants/index.d.ts +1 -2
- package/dist/esm/constants/index.js +4 -0
- package/dist/esm/constants/version.d.ts +1 -1
- package/dist/esm/constants/version.js +1 -1
- package/dist/esm/customHooks/analyticsLogger.d.ts +4 -0
- package/dist/esm/customHooks/analyticsLogger.js +6 -5
- package/dist/esm/customHooks/crashHandler.js +8 -1
- package/dist/esm/helpers/index.d.ts +1 -0
- package/dist/esm/helpers/index.js +11 -1
- package/dist/esm/helpers/searchQueryParser.d.ts +6 -0
- package/dist/esm/helpers/searchQueryParser.js +233 -0
- package/dist/esm/helpers/settingsStore.d.ts +9 -0
- package/dist/esm/helpers/settingsStore.js +58 -3
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.js +207 -44
- package/dist/esm/native/NativeInspector.d.ts +125 -0
- package/dist/esm/native/NativeInspector.js +289 -0
- package/dist/esm/native/NativeNetworkInspector.d.ts +22 -0
- package/dist/esm/native/NativeNetworkInspector.js +2 -0
- package/dist/esm/styles/index.js +41 -41
- package/dist/esm/types/enums.d.ts +1 -1
- package/dist/esm/types/interfaces.d.ts +9 -0
- package/ios/NetworkInspectorModule.h +6 -0
- package/ios/NetworkInspectorModule.m +760 -5
- package/package.json +13 -2
- package/react-native-inapp-inspector.podspec +7 -2
- package/android/src/main/java/com/inappinspector/NetworkInspectorModule.java +0 -97
- package/android/src/main/java/com/inappinspector/NetworkInspectorPackage.java +0 -28
package/dist/esm/index.js
CHANGED
|
@@ -8,9 +8,10 @@ import ErrorBoundary from './components/ErrorBoundary';
|
|
|
8
8
|
import MainScreen from './components/Inspector/MainScreen';
|
|
9
9
|
import { InspectorContext, animateNextLayout, } from './components/Inspector/InspectorContext';
|
|
10
10
|
// Helpers
|
|
11
|
-
import { formatDisplayUrl, getNavigationInfo, deduplicateLogs, getDomainColor, getEventCategory, } from './helpers';
|
|
11
|
+
import { formatDisplayUrl, getNavigationInfo, deduplicateLogs, getDomainColor, getEventCategory, matchNetworkLogQuery, } from './helpers';
|
|
12
12
|
// #5 — settings persistence
|
|
13
|
-
import { loadSettings, saveSettings, setCustomStorage, clearPersistedSettings, } from './helpers/settingsStore';
|
|
13
|
+
import { loadSettings, saveSettings, setCustomStorage, clearPersistedSettings, calculateRamBasedLimits, } from './helpers/settingsStore';
|
|
14
|
+
import { getNativeSystemMetrics, pushNativeLogRecord, fetchNativeCachedPage, } from './native/NativeInspector';
|
|
14
15
|
// Network
|
|
15
16
|
import { setupNetworkLogger, clearNetworkLogs, subscribeNetworkLogs, setNetworkModuleEnabled, } from './customHooks/networkLogger';
|
|
16
17
|
// Console
|
|
@@ -22,6 +23,7 @@ import { subscribeAnalyticsEvents, clearAnalyticsEvents, autoSetupAnalyticsLogge
|
|
|
22
23
|
import { getReduxState, subscribeReduxState, setReduxAutoRefresh, getLastActionForReducer, clearActionHistory, isReduxConnected, setReduxModuleEnabled, } from './customHooks/reduxLogger';
|
|
23
24
|
import { setPerformanceModuleEnabled } from './customHooks/performanceTracker';
|
|
24
25
|
import { setBundleModuleEnabled } from './customHooks/bundleAnalyzer';
|
|
26
|
+
import { showNativeFloatingButton, hideNativeFloatingButton, setNativeFloatingButtonBadge, subscribeNativeFloatingButtonPress, subscribeNativeDeviceShake, isNativeModuleAvailable, } from './native/NativeInspector';
|
|
25
27
|
import { LIB_VERSION } from './constants';
|
|
26
28
|
// Stylesheet
|
|
27
29
|
import { toggleGlobalTheme } from './styles';
|
|
@@ -97,7 +99,7 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
|
|
|
97
99
|
// ─── Crash state ───────────────────────────────────────────────────────────
|
|
98
100
|
const [crashRecords, setCrashRecords] = useState(() => getCrashRecords());
|
|
99
101
|
const [selectedCrash, setSelectedCrash] = useState(null);
|
|
100
|
-
const [maxCrashLogs, setMaxCrashLogs] = useState(
|
|
102
|
+
const [maxCrashLogs, setMaxCrashLogs] = useState(50);
|
|
101
103
|
useEffect(() => {
|
|
102
104
|
setMaxCrashLogsLimit(maxCrashLogs);
|
|
103
105
|
}, [maxCrashLogs]);
|
|
@@ -129,7 +131,7 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
|
|
|
129
131
|
setLastReadCrashesCount(crashRecords.length);
|
|
130
132
|
}
|
|
131
133
|
}, [activeTab, crashRecords.length]);
|
|
132
|
-
const [maxConsoleLogs, setMaxConsoleLogs] = useState(
|
|
134
|
+
const [maxConsoleLogs, setMaxConsoleLogs] = useState(100);
|
|
133
135
|
const [showConsoleLevels, setShowConsoleLevels] = useState({
|
|
134
136
|
info: true,
|
|
135
137
|
warn: false,
|
|
@@ -174,6 +176,9 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
|
|
|
174
176
|
crash: false,
|
|
175
177
|
});
|
|
176
178
|
const [maxNetworkLogs, setMaxNetworkLogs] = useState(100);
|
|
179
|
+
const [maxAnalyticsEventsLimit, setMaxAnalyticsEventsLimit] = useState(75);
|
|
180
|
+
const [isAutoRamLimitEnabled, setIsAutoRamLimitEnabled] = useState(true);
|
|
181
|
+
const [deviceFreeRamMb, setDeviceFreeRamMb] = useState(1800);
|
|
177
182
|
const [reduxAutoRefresh, setReduxAutoRefreshState] = useState(true);
|
|
178
183
|
const [reduxExpandDepth, setReduxExpandDepth] = useState(1);
|
|
179
184
|
// #6 — tab the inspector opens on. Shown with a DEFAULT badge in Settings.
|
|
@@ -189,6 +194,25 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
|
|
|
189
194
|
setCrashModuleEnabled(!!tabVisibility.crash);
|
|
190
195
|
setBundleModuleEnabled(!!tabVisibility.bundle);
|
|
191
196
|
}, [tabVisibility]);
|
|
197
|
+
// Query native hardware RAM and auto-tune limits if auto-RAM is active
|
|
198
|
+
useEffect(() => {
|
|
199
|
+
getNativeSystemMetrics()
|
|
200
|
+
.then(metrics => {
|
|
201
|
+
if (metrics) {
|
|
202
|
+
const freeRam = metrics.totalPhysicalRamMb - metrics.residentRamMb;
|
|
203
|
+
const freeMb = Math.max(200, Math.round(freeRam > 0 ? freeRam : 1500));
|
|
204
|
+
setDeviceFreeRamMb(freeMb);
|
|
205
|
+
if (isAutoRamLimitEnabled) {
|
|
206
|
+
const profile = calculateRamBasedLimits(freeMb);
|
|
207
|
+
setMaxNetworkLogs(profile.maxNetworkLogs);
|
|
208
|
+
setMaxConsoleLogs(profile.maxConsoleLogs);
|
|
209
|
+
setMaxAnalyticsEventsLimit(profile.maxAnalyticsEvents);
|
|
210
|
+
setMaxCrashLogs(profile.maxCrashRecords);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
})
|
|
214
|
+
.catch(() => { });
|
|
215
|
+
}, [isAutoRamLimitEnabled]);
|
|
192
216
|
const resetToDefaults = async () => {
|
|
193
217
|
await clearPersistedSettings();
|
|
194
218
|
setIsDark(false);
|
|
@@ -205,9 +229,12 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
|
|
|
205
229
|
crash: false,
|
|
206
230
|
});
|
|
207
231
|
setDefaultTab('apis');
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
232
|
+
setIsAutoRamLimitEnabled(true);
|
|
233
|
+
const profile = calculateRamBasedLimits(deviceFreeRamMb);
|
|
234
|
+
setMaxCrashLogs(profile.maxCrashRecords);
|
|
235
|
+
setMaxNetworkLogs(profile.maxNetworkLogs);
|
|
236
|
+
setMaxConsoleLogs(profile.maxConsoleLogs);
|
|
237
|
+
setMaxAnalyticsEventsLimit(profile.maxAnalyticsEvents);
|
|
211
238
|
setShowConsoleLevels({
|
|
212
239
|
info: true,
|
|
213
240
|
warn: true,
|
|
@@ -241,10 +268,16 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
|
|
|
241
268
|
}));
|
|
242
269
|
if (saved.defaultTab)
|
|
243
270
|
setDefaultTab(saved.defaultTab);
|
|
271
|
+
if (saved.isAutoRamLimitEnabled != null)
|
|
272
|
+
setIsAutoRamLimitEnabled(saved.isAutoRamLimitEnabled);
|
|
244
273
|
if (saved.maxNetworkLogs != null)
|
|
245
274
|
setMaxNetworkLogs(saved.maxNetworkLogs);
|
|
246
275
|
if (saved.maxConsoleLogs != null)
|
|
247
276
|
setMaxConsoleLogs(saved.maxConsoleLogs);
|
|
277
|
+
if (saved.maxAnalyticsEventsLimit != null)
|
|
278
|
+
setMaxAnalyticsEventsLimit(saved.maxAnalyticsEventsLimit);
|
|
279
|
+
if (saved.maxCrashLogs != null)
|
|
280
|
+
setMaxCrashLogs(saved.maxCrashLogs);
|
|
248
281
|
if (saved.showConsoleLevels)
|
|
249
282
|
setShowConsoleLevels(saved.showConsoleLevels);
|
|
250
283
|
if (saved.reduxAutoRefresh != null)
|
|
@@ -287,6 +320,9 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
|
|
|
287
320
|
defaultTab,
|
|
288
321
|
maxNetworkLogs,
|
|
289
322
|
maxConsoleLogs,
|
|
323
|
+
maxAnalyticsEventsLimit,
|
|
324
|
+
maxCrashLogs,
|
|
325
|
+
isAutoRamLimitEnabled,
|
|
290
326
|
showConsoleLevels,
|
|
291
327
|
reduxAutoRefresh,
|
|
292
328
|
reduxExpandDepth,
|
|
@@ -300,6 +336,9 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
|
|
|
300
336
|
defaultTab,
|
|
301
337
|
maxNetworkLogs,
|
|
302
338
|
maxConsoleLogs,
|
|
339
|
+
maxAnalyticsEventsLimit,
|
|
340
|
+
maxCrashLogs,
|
|
341
|
+
isAutoRamLimitEnabled,
|
|
303
342
|
showConsoleLevels,
|
|
304
343
|
reduxAutoRefresh,
|
|
305
344
|
reduxExpandDepth,
|
|
@@ -374,13 +413,43 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
|
|
|
374
413
|
return newVisibility;
|
|
375
414
|
});
|
|
376
415
|
};
|
|
416
|
+
const loadNativePage = useCallback(async (tabKey, query = '') => {
|
|
417
|
+
if (tabKey === 'apis' || tabKey === 'logs' || tabKey === 'analytics' || tabKey === 'crash') {
|
|
418
|
+
const pageData = await fetchNativeCachedPage(tabKey, 0, 100, query);
|
|
419
|
+
if (pageData && pageData.items && pageData.items.length > 0) {
|
|
420
|
+
if (tabKey === 'apis')
|
|
421
|
+
setLogs(pageData.items);
|
|
422
|
+
else if (tabKey === 'logs')
|
|
423
|
+
setConsoleLogs(pageData.items);
|
|
424
|
+
else if (tabKey === 'analytics')
|
|
425
|
+
setAnalyticsEvents(pageData.items);
|
|
426
|
+
else if (tabKey === 'crash')
|
|
427
|
+
setCrashRecords(pageData.items);
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
}, []);
|
|
377
431
|
const switchActiveTab = useCallback((key) => {
|
|
378
432
|
if (key === 'redux' && !isReduxConnected())
|
|
379
433
|
return;
|
|
380
434
|
if (key === 'analytics' && !isAnalyticsConnected())
|
|
381
435
|
return;
|
|
382
|
-
|
|
383
|
-
|
|
436
|
+
setSelected(null);
|
|
437
|
+
setSelectedEvent(null);
|
|
438
|
+
setSelectedLog(null);
|
|
439
|
+
setSelectedReduxSlice(null);
|
|
440
|
+
setSelectedReduxAction(null);
|
|
441
|
+
setSelectedCrash(null);
|
|
442
|
+
if (typeof React.startTransition === 'function') {
|
|
443
|
+
React.startTransition(() => {
|
|
444
|
+
setActiveTab(key);
|
|
445
|
+
loadNativePage(key);
|
|
446
|
+
});
|
|
447
|
+
}
|
|
448
|
+
else {
|
|
449
|
+
setActiveTab(key);
|
|
450
|
+
loadNativePage(key);
|
|
451
|
+
}
|
|
452
|
+
}, [loadNativePage]);
|
|
384
453
|
const [selectedEvent, setSelectedEvent] = useState(null);
|
|
385
454
|
const [analyticsSearch, setAnalyticsSearch] = useState('');
|
|
386
455
|
const [analyticsFilters, setAnalyticsFilters] = useState({
|
|
@@ -628,6 +697,53 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
|
|
|
628
697
|
loop.start();
|
|
629
698
|
return () => loop.stop();
|
|
630
699
|
}, [unreadPulseAnim]);
|
|
700
|
+
const isNativeModule = useMemo(() => isNativeModuleAvailable(), []);
|
|
701
|
+
const useNativeFab = (Platform.OS === 'ios' || Platform.OS === 'android') && isNativeModule;
|
|
702
|
+
// 100% Native Main-Thread Floating Button Lifecycle
|
|
703
|
+
useEffect(() => {
|
|
704
|
+
if (!useNativeFab || !isEnabled || !enabled) {
|
|
705
|
+
if (useNativeFab) {
|
|
706
|
+
hideNativeFloatingButton();
|
|
707
|
+
}
|
|
708
|
+
return;
|
|
709
|
+
}
|
|
710
|
+
if (visible) {
|
|
711
|
+
hideNativeFloatingButton();
|
|
712
|
+
}
|
|
713
|
+
else {
|
|
714
|
+
showNativeFloatingButton();
|
|
715
|
+
setNativeFloatingButtonBadge(logs.length > 0 || analyticsEvents.length > 0);
|
|
716
|
+
}
|
|
717
|
+
}, [
|
|
718
|
+
useNativeFab,
|
|
719
|
+
isEnabled,
|
|
720
|
+
enabled,
|
|
721
|
+
visible,
|
|
722
|
+
logs.length,
|
|
723
|
+
analyticsEvents.length,
|
|
724
|
+
]);
|
|
725
|
+
// Subscribe to native UI-thread floating button tap events
|
|
726
|
+
useEffect(() => {
|
|
727
|
+
if (!useNativeFab)
|
|
728
|
+
return;
|
|
729
|
+
const unsubscribe = subscribeNativeFloatingButtonPress(() => {
|
|
730
|
+
setVisible(true);
|
|
731
|
+
});
|
|
732
|
+
return () => {
|
|
733
|
+
unsubscribe();
|
|
734
|
+
};
|
|
735
|
+
}, [useNativeFab]);
|
|
736
|
+
// Subscribe to physical hardware shake events (or Cmd+Ctrl+Z on iOS simulator)
|
|
737
|
+
useEffect(() => {
|
|
738
|
+
if (!useNativeFab)
|
|
739
|
+
return;
|
|
740
|
+
const unsubscribe = subscribeNativeDeviceShake(() => {
|
|
741
|
+
setVisible(prev => !prev);
|
|
742
|
+
});
|
|
743
|
+
return () => {
|
|
744
|
+
unsubscribe();
|
|
745
|
+
};
|
|
746
|
+
}, [useNativeFab]);
|
|
631
747
|
const isVisibleRefObj = useRef(visible);
|
|
632
748
|
// #6 — every time the inspector is opened, land on chosen default tab & sync latest logs
|
|
633
749
|
useEffect(() => {
|
|
@@ -694,6 +810,9 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
|
|
|
694
810
|
return;
|
|
695
811
|
}
|
|
696
812
|
const updated = getCrashRecords();
|
|
813
|
+
if (updated.length > 0) {
|
|
814
|
+
pushNativeLogRecord('crash', JSON.stringify(updated[0]));
|
|
815
|
+
}
|
|
697
816
|
if (isVisibleRef.current) {
|
|
698
817
|
setCrashRecords(updated);
|
|
699
818
|
}
|
|
@@ -702,12 +821,16 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
|
|
|
702
821
|
// during the very first commit, which fires before effects are mounted).
|
|
703
822
|
const pendingCrashes = getCrashRecords();
|
|
704
823
|
if (pendingCrashes.length > 0) {
|
|
824
|
+
pendingCrashes.forEach(c => pushNativeLogRecord('crash', JSON.stringify(c)));
|
|
705
825
|
setCrashRecords(pendingCrashes);
|
|
706
826
|
}
|
|
707
827
|
let timeoutId;
|
|
708
828
|
let isFirstNetworkCall = true;
|
|
709
829
|
const unsubscribe = subscribeNetworkLogs((raw) => {
|
|
710
830
|
latestNetworkLogsRef.current = raw;
|
|
831
|
+
if (raw.length > 0) {
|
|
832
|
+
pushNativeLogRecord('apis', JSON.stringify(raw[0]));
|
|
833
|
+
}
|
|
711
834
|
if (isNetworkPausedRef.current)
|
|
712
835
|
return;
|
|
713
836
|
if (!isVisibleRef.current)
|
|
@@ -749,6 +872,9 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
|
|
|
749
872
|
let isFirstAnalyticsCall = true;
|
|
750
873
|
const unsubscribeAnalytics = subscribeAnalyticsEvents((raw) => {
|
|
751
874
|
latestAnalyticsEventsRef.current = raw;
|
|
875
|
+
if (raw.length > 0) {
|
|
876
|
+
pushNativeLogRecord('analytics', JSON.stringify(raw[0]));
|
|
877
|
+
}
|
|
752
878
|
if (isAnalyticsPausedRef.current)
|
|
753
879
|
return;
|
|
754
880
|
if (!isVisibleRef.current)
|
|
@@ -788,6 +914,9 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
|
|
|
788
914
|
let isFirstConsoleCall = true;
|
|
789
915
|
const unsubscribeConsole = subscribeConsoleLogs((raw) => {
|
|
790
916
|
latestConsoleLogsRef.current = raw;
|
|
917
|
+
if (raw.length > 0) {
|
|
918
|
+
pushNativeLogRecord('logs', JSON.stringify(raw[0]));
|
|
919
|
+
}
|
|
791
920
|
if (isConsolePausedRef.current)
|
|
792
921
|
return;
|
|
793
922
|
if (!isVisibleRef.current)
|
|
@@ -858,6 +987,10 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
|
|
|
858
987
|
return true;
|
|
859
988
|
if (f === 'Failed')
|
|
860
989
|
return log.status === 0 || log.status == null;
|
|
990
|
+
const codeNum = parseInt(f, 10);
|
|
991
|
+
if (!isNaN(codeNum)) {
|
|
992
|
+
return Number(log.status) === codeNum;
|
|
993
|
+
}
|
|
861
994
|
return String(log.status)[0] === f[0];
|
|
862
995
|
});
|
|
863
996
|
if (!matched)
|
|
@@ -873,9 +1006,13 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
|
|
|
873
1006
|
if (!matchedMethod)
|
|
874
1007
|
return false;
|
|
875
1008
|
}
|
|
876
|
-
// Search
|
|
877
|
-
if (search &&
|
|
878
|
-
|
|
1009
|
+
// Advanced Search Query Engine Check (Supports method:POST, is:error, slow:>1s, status:200, headers, body, etc.)
|
|
1010
|
+
if (search && search.trim().length > 0) {
|
|
1011
|
+
const routePath = logRouteMapRef.current.get(log.id)?.path || '';
|
|
1012
|
+
const isMatch = matchNetworkLogQuery(log, search, routePath);
|
|
1013
|
+
if (!isMatch)
|
|
1014
|
+
return false;
|
|
1015
|
+
}
|
|
879
1016
|
return true;
|
|
880
1017
|
});
|
|
881
1018
|
if (sortOrder === 'oldest') {
|
|
@@ -1030,12 +1167,20 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
|
|
|
1030
1167
|
const filteredAnalyticsEvents = useMemo(() => {
|
|
1031
1168
|
let events = analyticsEvents;
|
|
1032
1169
|
// Search query filter
|
|
1033
|
-
if (analyticsSearch) {
|
|
1034
|
-
const
|
|
1035
|
-
events = events.filter(e =>
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1170
|
+
if (analyticsSearch && analyticsSearch.trim().length > 0) {
|
|
1171
|
+
const queryTokens = analyticsSearch.trim().toLowerCase().split(/\s+/).filter(Boolean);
|
|
1172
|
+
events = events.filter(e => {
|
|
1173
|
+
const searchTarget = [
|
|
1174
|
+
e.name || '',
|
|
1175
|
+
JSON.stringify(e.params || ''),
|
|
1176
|
+
JSON.stringify(e.userProperties || ''),
|
|
1177
|
+
e.screenName || '',
|
|
1178
|
+
e.pageTitle || '',
|
|
1179
|
+
e.userId || '',
|
|
1180
|
+
e.source || '',
|
|
1181
|
+
].join(' ').toLowerCase();
|
|
1182
|
+
return queryTokens.every(token => searchTarget.includes(token));
|
|
1183
|
+
});
|
|
1039
1184
|
}
|
|
1040
1185
|
// Category filter
|
|
1041
1186
|
if (analyticsFilters.categories.size > 0 && !analyticsFilters.categories.has('all')) {
|
|
@@ -1073,16 +1218,15 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
|
|
|
1073
1218
|
}
|
|
1074
1219
|
// Payload complexity filter
|
|
1075
1220
|
if (analyticsFilters.payloadComplexity !== 'all') {
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
});
|
|
1221
|
+
if (analyticsFilters.payloadComplexity === 'none') {
|
|
1222
|
+
events = events.filter(e => !e.params || Object.keys(e.params).length === 0);
|
|
1223
|
+
}
|
|
1224
|
+
else if (analyticsFilters.payloadComplexity === 'simple') {
|
|
1225
|
+
events = events.filter(e => e.params && Object.keys(e.params).length <= 3);
|
|
1226
|
+
}
|
|
1227
|
+
else if (analyticsFilters.payloadComplexity === 'heavy') {
|
|
1228
|
+
events = events.filter(e => e.params && Object.keys(e.params).length > 3);
|
|
1229
|
+
}
|
|
1086
1230
|
}
|
|
1087
1231
|
// Conversion / Goal events filter
|
|
1088
1232
|
if (analyticsFilters.onlyConversions) {
|
|
@@ -1115,10 +1259,8 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
|
|
|
1115
1259
|
}
|
|
1116
1260
|
// Has Revenue filter
|
|
1117
1261
|
if (analyticsFilters.hasRevenue) {
|
|
1118
|
-
events = events.filter(e =>
|
|
1119
|
-
|
|
1120
|
-
return val !== undefined && val !== null && Number(val) > 0;
|
|
1121
|
-
});
|
|
1262
|
+
events = events.filter(e => (e.params?.value != null && !isNaN(Number(e.params.value))) ||
|
|
1263
|
+
(e.params?.price != null && !isNaN(Number(e.params.price))));
|
|
1122
1264
|
}
|
|
1123
1265
|
// Has Items filter
|
|
1124
1266
|
if (analyticsFilters.hasItems) {
|
|
@@ -1171,8 +1313,8 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
|
|
|
1171
1313
|
else if (analyticsFilters.sortBy === 'count_desc') {
|
|
1172
1314
|
result = [...result].sort((a, b) => (b.count || 1) - (a.count || 1));
|
|
1173
1315
|
}
|
|
1174
|
-
return result;
|
|
1175
|
-
}, [analyticsEvents, analyticsSearch, analyticsFilters]);
|
|
1316
|
+
return result.slice(0, maxAnalyticsEventsLimit);
|
|
1317
|
+
}, [analyticsEvents, analyticsSearch, analyticsFilters, maxAnalyticsEventsLimit]);
|
|
1176
1318
|
const filteredConsoleLogs = useMemo(() => {
|
|
1177
1319
|
let result = visibleConsoleLogs;
|
|
1178
1320
|
// Filters check
|
|
@@ -1183,16 +1325,23 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
|
|
|
1183
1325
|
if (logFilters.has('user-log') && log.sourceMethod === 'log')
|
|
1184
1326
|
return true;
|
|
1185
1327
|
if (logFilters.has('analytics') &&
|
|
1186
|
-
log.message
|
|
1328
|
+
log.message?.toLowerCase().includes('[analytics error]'))
|
|
1187
1329
|
return true;
|
|
1188
1330
|
return false;
|
|
1189
1331
|
});
|
|
1190
1332
|
}
|
|
1191
|
-
// Search bar check
|
|
1192
|
-
if (logSearch) {
|
|
1193
|
-
const
|
|
1194
|
-
result = result.filter(log =>
|
|
1195
|
-
|
|
1333
|
+
// Comprehensive Search bar check
|
|
1334
|
+
if (logSearch && logSearch.trim().length > 0) {
|
|
1335
|
+
const queryTokens = logSearch.trim().toLowerCase().split(/\s+/).filter(Boolean);
|
|
1336
|
+
result = result.filter(log => {
|
|
1337
|
+
const searchTarget = [
|
|
1338
|
+
log.message || '',
|
|
1339
|
+
log.caller || '',
|
|
1340
|
+
log.type || '',
|
|
1341
|
+
log.sourceMethod || '',
|
|
1342
|
+
].join(' ').toLowerCase();
|
|
1343
|
+
return queryTokens.every(token => searchTarget.includes(token));
|
|
1344
|
+
});
|
|
1196
1345
|
}
|
|
1197
1346
|
// #7 — apply sort order (newest/oldest first)
|
|
1198
1347
|
result = [...result].sort((a, b) => logSortOrder === 'newest'
|
|
@@ -1229,10 +1378,17 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
|
|
|
1229
1378
|
]);
|
|
1230
1379
|
const logCounts = useMemo(() => {
|
|
1231
1380
|
let searchedLogs = visibleConsoleLogs;
|
|
1232
|
-
if (logSearch) {
|
|
1233
|
-
const
|
|
1234
|
-
searchedLogs = visibleConsoleLogs.filter(log =>
|
|
1235
|
-
|
|
1381
|
+
if (logSearch && logSearch.trim().length > 0) {
|
|
1382
|
+
const queryTokens = logSearch.trim().toLowerCase().split(/\s+/).filter(Boolean);
|
|
1383
|
+
searchedLogs = visibleConsoleLogs.filter(log => {
|
|
1384
|
+
const searchTarget = [
|
|
1385
|
+
log.message || '',
|
|
1386
|
+
log.caller || '',
|
|
1387
|
+
log.type || '',
|
|
1388
|
+
log.sourceMethod || '',
|
|
1389
|
+
].join(' ').toLowerCase();
|
|
1390
|
+
return queryTokens.every(token => searchTarget.includes(token));
|
|
1391
|
+
});
|
|
1236
1392
|
}
|
|
1237
1393
|
const total = visibleConsoleLogs.length;
|
|
1238
1394
|
return {
|
|
@@ -1426,6 +1582,7 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
|
|
|
1426
1582
|
unreadPulseAnim,
|
|
1427
1583
|
runClearAllWithAnimation,
|
|
1428
1584
|
// ─── FAB / launcher ─────────────────────────────────────────────────
|
|
1585
|
+
useNativeFab,
|
|
1429
1586
|
fabPan,
|
|
1430
1587
|
fabPanResponder,
|
|
1431
1588
|
fabDraggedRef,
|
|
@@ -1543,6 +1700,11 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
|
|
|
1543
1700
|
setMaxNetworkLogs,
|
|
1544
1701
|
maxConsoleLogs,
|
|
1545
1702
|
setMaxConsoleLogs,
|
|
1703
|
+
maxAnalyticsEventsLimit,
|
|
1704
|
+
setMaxAnalyticsEventsLimit,
|
|
1705
|
+
isAutoRamLimitEnabled,
|
|
1706
|
+
setIsAutoRamLimitEnabled,
|
|
1707
|
+
deviceFreeRamMb,
|
|
1546
1708
|
reduxAutoRefresh,
|
|
1547
1709
|
setReduxAutoRefreshState,
|
|
1548
1710
|
reduxExpandDepth,
|
|
@@ -1576,4 +1738,5 @@ export { connectReduxStore, inspectorReduxMiddleware, getReduxState, subscribeRe
|
|
|
1576
1738
|
export { getEventCategory, registerGAPlugin, } from './helpers/gaAnalyticsRegistry';
|
|
1577
1739
|
export { usePerformanceTracker, useComponentProfiler, useNavigationProfiler, trackComponentRender, trackNavigationTransition, trackHeavyTask, measureAsync, getHermesMemoryStats, registerComponentProfile, subscribeRenderProfiles, getRenderProfiles, logPerformanceEvent, clearPerformanceEvents, subscribePerformanceEvents, getPerformanceEvents, getInitialRenderProfiles, getInitialPerformanceEvents, generateFixSnippet, } from './customHooks/performanceTracker';
|
|
1578
1740
|
export { InspectLog, InspectTrackTime, InspectCatch, } from './decorators';
|
|
1741
|
+
export { getNativeDeviceMetrics, enableNativeCrashProtection, subscribeNativeCrashes, showNativeFloatingButton, hideNativeFloatingButton, setNativeFloatingButtonBadge, subscribeNativeFloatingButtonPress, subscribeNativeDeviceShake, startNativeFpsMonitoring, stopNativeFpsMonitoring, getNativeFpsMetrics, getNativeStorageItem, setNativeStorageItem, isNativeModuleAvailable, } from './native/NativeInspector';
|
|
1579
1742
|
export { ActiveTab, Method, StatusFilter, SortOrder, LocalFilter, ModalAnimationType, SettingsPage, SettingsSubTab, LogFilter, ConsoleLogType, AnalyticsEventSource, GAEventCategory, StackFrameType, DiffResultType, BundleSubTab, PerformanceSubTab, CrashType, CrashExportFormat, CrashDetailSubTab, CrashFilterType, BreadcrumbType, } from './types';
|
|
@@ -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>;
|