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.
- package/README.md +123 -101
- package/android/build.gradle +13 -1
- package/android/src/main/java/com/inappinspector/NetworkInspectorModule.kt +904 -0
- package/android/src/main/java/com/inappinspector/NetworkInspectorPackage.kt +17 -0
- package/dist/commonjs/components/CopyButton.js +3 -0
- package/dist/commonjs/components/ErrorBoundary.js +3 -0
- package/dist/commonjs/components/Inspector/AnalyticsTab.js +7 -3
- package/dist/commonjs/components/Inspector/BundleTab.js +1 -1
- package/dist/commonjs/components/Inspector/ConsoleTab.js +1 -1
- package/dist/commonjs/components/Inspector/CrashTab.js +97 -90
- package/dist/commonjs/components/Inspector/InspectorHeader.js +12 -8
- package/dist/commonjs/components/Inspector/MainScreen.js +14 -101
- package/dist/commonjs/components/Inspector/NetworkTab.js +47 -10
- 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 +342 -88
- package/dist/commonjs/components/Inspector/TabBar.js +6 -3
- package/dist/commonjs/components/NetworkIcons.d.ts +1 -0
- package/dist/commonjs/components/NetworkIcons.js +6 -1
- 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 +7 -5
- package/dist/commonjs/customHooks/crashHandler.js +7 -0
- package/dist/commonjs/helpers/index.js +10 -1
- 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 +229 -39
- 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 +6 -6
- package/dist/commonjs/types/enums.d.ts +1 -1
- package/dist/commonjs/types/interfaces.d.ts +9 -0
- package/dist/esm/components/CopyButton.js +3 -0
- package/dist/esm/components/ErrorBoundary.js +3 -0
- package/dist/esm/components/Inspector/AnalyticsTab.js +7 -3
- package/dist/esm/components/Inspector/BundleTab.js +1 -1
- package/dist/esm/components/Inspector/ConsoleTab.js +1 -1
- package/dist/esm/components/Inspector/CrashTab.js +97 -90
- package/dist/esm/components/Inspector/InspectorHeader.js +13 -9
- package/dist/esm/components/Inspector/MainScreen.js +15 -69
- package/dist/esm/components/Inspector/NetworkTab.js +47 -10
- 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 +344 -90
- package/dist/esm/components/Inspector/TabBar.js +7 -4
- package/dist/esm/components/NetworkIcons.d.ts +1 -0
- package/dist/esm/components/NetworkIcons.js +4 -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 +5 -4
- package/dist/esm/customHooks/crashHandler.js +7 -0
- package/dist/esm/helpers/index.js +10 -1
- 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 +215 -39
- 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 +6 -6
- 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 +720 -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
|
@@ -10,7 +10,8 @@ import { InspectorContext, animateNextLayout, } from './components/Inspector/Ins
|
|
|
10
10
|
// Helpers
|
|
11
11
|
import { formatDisplayUrl, getNavigationInfo, deduplicateLogs, getDomainColor, getEventCategory, } 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';
|
|
@@ -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(250);
|
|
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,26 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
|
|
|
873
1006
|
if (!matchedMethod)
|
|
874
1007
|
return false;
|
|
875
1008
|
}
|
|
876
|
-
// Search Bar Check
|
|
877
|
-
if (search &&
|
|
878
|
-
|
|
1009
|
+
// Comprehensive Search Bar Check
|
|
1010
|
+
if (search && search.trim().length > 0) {
|
|
1011
|
+
const queryTokens = search.trim().toLowerCase().split(/\s+/).filter(Boolean);
|
|
1012
|
+
const routePath = logRouteMapRef.current.get(log.id)?.path || '';
|
|
1013
|
+
const reqStr = typeof log.request === 'string' ? log.request : JSON.stringify(log.request || '');
|
|
1014
|
+
const resStr = typeof log.response === 'string' ? log.response : JSON.stringify(log.response || '');
|
|
1015
|
+
const searchTarget = [
|
|
1016
|
+
log.method || '',
|
|
1017
|
+
log.url || '',
|
|
1018
|
+
String(log.status ?? ''),
|
|
1019
|
+
routePath,
|
|
1020
|
+
reqStr,
|
|
1021
|
+
resStr,
|
|
1022
|
+
JSON.stringify(log.requestHeaders || ''),
|
|
1023
|
+
JSON.stringify(log.responseHeaders || ''),
|
|
1024
|
+
].join(' ').toLowerCase();
|
|
1025
|
+
const isMatch = queryTokens.every(token => searchTarget.includes(token));
|
|
1026
|
+
if (!isMatch)
|
|
1027
|
+
return false;
|
|
1028
|
+
}
|
|
879
1029
|
return true;
|
|
880
1030
|
});
|
|
881
1031
|
if (sortOrder === 'oldest') {
|
|
@@ -1030,12 +1180,20 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
|
|
|
1030
1180
|
const filteredAnalyticsEvents = useMemo(() => {
|
|
1031
1181
|
let events = analyticsEvents;
|
|
1032
1182
|
// Search query filter
|
|
1033
|
-
if (analyticsSearch) {
|
|
1034
|
-
const
|
|
1035
|
-
events = events.filter(e =>
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1183
|
+
if (analyticsSearch && analyticsSearch.trim().length > 0) {
|
|
1184
|
+
const queryTokens = analyticsSearch.trim().toLowerCase().split(/\s+/).filter(Boolean);
|
|
1185
|
+
events = events.filter(e => {
|
|
1186
|
+
const searchTarget = [
|
|
1187
|
+
e.name || '',
|
|
1188
|
+
JSON.stringify(e.params || ''),
|
|
1189
|
+
JSON.stringify(e.userProperties || ''),
|
|
1190
|
+
e.screenName || '',
|
|
1191
|
+
e.pageTitle || '',
|
|
1192
|
+
e.userId || '',
|
|
1193
|
+
e.source || '',
|
|
1194
|
+
].join(' ').toLowerCase();
|
|
1195
|
+
return queryTokens.every(token => searchTarget.includes(token));
|
|
1196
|
+
});
|
|
1039
1197
|
}
|
|
1040
1198
|
// Category filter
|
|
1041
1199
|
if (analyticsFilters.categories.size > 0 && !analyticsFilters.categories.has('all')) {
|
|
@@ -1073,16 +1231,15 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
|
|
|
1073
1231
|
}
|
|
1074
1232
|
// Payload complexity filter
|
|
1075
1233
|
if (analyticsFilters.payloadComplexity !== 'all') {
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
});
|
|
1234
|
+
if (analyticsFilters.payloadComplexity === 'none') {
|
|
1235
|
+
events = events.filter(e => !e.params || Object.keys(e.params).length === 0);
|
|
1236
|
+
}
|
|
1237
|
+
else if (analyticsFilters.payloadComplexity === 'simple') {
|
|
1238
|
+
events = events.filter(e => e.params && Object.keys(e.params).length <= 3);
|
|
1239
|
+
}
|
|
1240
|
+
else if (analyticsFilters.payloadComplexity === 'heavy') {
|
|
1241
|
+
events = events.filter(e => e.params && Object.keys(e.params).length > 3);
|
|
1242
|
+
}
|
|
1086
1243
|
}
|
|
1087
1244
|
// Conversion / Goal events filter
|
|
1088
1245
|
if (analyticsFilters.onlyConversions) {
|
|
@@ -1115,10 +1272,8 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
|
|
|
1115
1272
|
}
|
|
1116
1273
|
// Has Revenue filter
|
|
1117
1274
|
if (analyticsFilters.hasRevenue) {
|
|
1118
|
-
events = events.filter(e =>
|
|
1119
|
-
|
|
1120
|
-
return val !== undefined && val !== null && Number(val) > 0;
|
|
1121
|
-
});
|
|
1275
|
+
events = events.filter(e => (e.params?.value != null && !isNaN(Number(e.params.value))) ||
|
|
1276
|
+
(e.params?.price != null && !isNaN(Number(e.params.price))));
|
|
1122
1277
|
}
|
|
1123
1278
|
// Has Items filter
|
|
1124
1279
|
if (analyticsFilters.hasItems) {
|
|
@@ -1183,16 +1338,23 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
|
|
|
1183
1338
|
if (logFilters.has('user-log') && log.sourceMethod === 'log')
|
|
1184
1339
|
return true;
|
|
1185
1340
|
if (logFilters.has('analytics') &&
|
|
1186
|
-
log.message
|
|
1341
|
+
log.message?.toLowerCase().includes('[analytics error]'))
|
|
1187
1342
|
return true;
|
|
1188
1343
|
return false;
|
|
1189
1344
|
});
|
|
1190
1345
|
}
|
|
1191
|
-
// Search bar check
|
|
1192
|
-
if (logSearch) {
|
|
1193
|
-
const
|
|
1194
|
-
result = result.filter(log =>
|
|
1195
|
-
|
|
1346
|
+
// Comprehensive Search bar check
|
|
1347
|
+
if (logSearch && logSearch.trim().length > 0) {
|
|
1348
|
+
const queryTokens = logSearch.trim().toLowerCase().split(/\s+/).filter(Boolean);
|
|
1349
|
+
result = result.filter(log => {
|
|
1350
|
+
const searchTarget = [
|
|
1351
|
+
log.message || '',
|
|
1352
|
+
log.caller || '',
|
|
1353
|
+
log.type || '',
|
|
1354
|
+
log.sourceMethod || '',
|
|
1355
|
+
].join(' ').toLowerCase();
|
|
1356
|
+
return queryTokens.every(token => searchTarget.includes(token));
|
|
1357
|
+
});
|
|
1196
1358
|
}
|
|
1197
1359
|
// #7 — apply sort order (newest/oldest first)
|
|
1198
1360
|
result = [...result].sort((a, b) => logSortOrder === 'newest'
|
|
@@ -1229,10 +1391,17 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
|
|
|
1229
1391
|
]);
|
|
1230
1392
|
const logCounts = useMemo(() => {
|
|
1231
1393
|
let searchedLogs = visibleConsoleLogs;
|
|
1232
|
-
if (logSearch) {
|
|
1233
|
-
const
|
|
1234
|
-
searchedLogs = visibleConsoleLogs.filter(log =>
|
|
1235
|
-
|
|
1394
|
+
if (logSearch && logSearch.trim().length > 0) {
|
|
1395
|
+
const queryTokens = logSearch.trim().toLowerCase().split(/\s+/).filter(Boolean);
|
|
1396
|
+
searchedLogs = visibleConsoleLogs.filter(log => {
|
|
1397
|
+
const searchTarget = [
|
|
1398
|
+
log.message || '',
|
|
1399
|
+
log.caller || '',
|
|
1400
|
+
log.type || '',
|
|
1401
|
+
log.sourceMethod || '',
|
|
1402
|
+
].join(' ').toLowerCase();
|
|
1403
|
+
return queryTokens.every(token => searchTarget.includes(token));
|
|
1404
|
+
});
|
|
1236
1405
|
}
|
|
1237
1406
|
const total = visibleConsoleLogs.length;
|
|
1238
1407
|
return {
|
|
@@ -1426,6 +1595,7 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
|
|
|
1426
1595
|
unreadPulseAnim,
|
|
1427
1596
|
runClearAllWithAnimation,
|
|
1428
1597
|
// ─── FAB / launcher ─────────────────────────────────────────────────
|
|
1598
|
+
useNativeFab,
|
|
1429
1599
|
fabPan,
|
|
1430
1600
|
fabPanResponder,
|
|
1431
1601
|
fabDraggedRef,
|
|
@@ -1543,6 +1713,11 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
|
|
|
1543
1713
|
setMaxNetworkLogs,
|
|
1544
1714
|
maxConsoleLogs,
|
|
1545
1715
|
setMaxConsoleLogs,
|
|
1716
|
+
maxAnalyticsEventsLimit,
|
|
1717
|
+
setMaxAnalyticsEventsLimit,
|
|
1718
|
+
isAutoRamLimitEnabled,
|
|
1719
|
+
setIsAutoRamLimitEnabled,
|
|
1720
|
+
deviceFreeRamMb,
|
|
1546
1721
|
reduxAutoRefresh,
|
|
1547
1722
|
setReduxAutoRefreshState,
|
|
1548
1723
|
reduxExpandDepth,
|
|
@@ -1576,4 +1751,5 @@ export { connectReduxStore, inspectorReduxMiddleware, getReduxState, subscribeRe
|
|
|
1576
1751
|
export { getEventCategory, registerGAPlugin, } from './helpers/gaAnalyticsRegistry';
|
|
1577
1752
|
export { usePerformanceTracker, useComponentProfiler, useNavigationProfiler, trackComponentRender, trackNavigationTransition, trackHeavyTask, measureAsync, getHermesMemoryStats, registerComponentProfile, subscribeRenderProfiles, getRenderProfiles, logPerformanceEvent, clearPerformanceEvents, subscribePerformanceEvents, getPerformanceEvents, getInitialRenderProfiles, getInitialPerformanceEvents, generateFixSnippet, } from './customHooks/performanceTracker';
|
|
1578
1753
|
export { InspectLog, InspectTrackTime, InspectCatch, } from './decorators';
|
|
1754
|
+
export { getNativeDeviceMetrics, enableNativeCrashProtection, subscribeNativeCrashes, showNativeFloatingButton, hideNativeFloatingButton, setNativeFloatingButtonBadge, subscribeNativeFloatingButtonPress, subscribeNativeDeviceShake, startNativeFpsMonitoring, stopNativeFpsMonitoring, getNativeFpsMetrics, getNativeStorageItem, setNativeStorageItem, isNativeModuleAvailable, } from './native/NativeInspector';
|
|
1579
1755
|
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>;
|