react-native-inapp-inspector 2.3.5 → 2.3.7
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/dist/commonjs/analytics.d.ts +0 -4
- package/dist/commonjs/analytics.js +0 -4
- package/dist/commonjs/bundle.d.ts +0 -4
- package/dist/commonjs/bundle.js +0 -4
- package/dist/commonjs/components/AnalyticsDetail.js +18 -27
- package/dist/commonjs/components/AnalyticsEventCard.js +9 -12
- package/dist/commonjs/components/AnalyticsGraph.js +10 -15
- package/dist/commonjs/components/AppHeaderLogo.js +0 -3
- package/dist/commonjs/components/BrandCircleIcon.js +15 -15
- package/dist/commonjs/components/BrandSquareIcon.js +20 -20
- package/dist/commonjs/components/CodeSnippet.js +6 -19
- package/dist/commonjs/components/ConsoleLogCard.js +0 -1
- package/dist/commonjs/components/CopyButton.js +0 -4
- package/dist/commonjs/components/DiffViewer.js +0 -2
- package/dist/commonjs/components/DomainHeader.js +0 -4
- package/dist/commonjs/components/EmptyState.js +0 -3
- package/dist/commonjs/components/ErrorBoundary.js +5 -10
- package/dist/commonjs/components/HeadersSection.js +0 -5
- package/dist/commonjs/components/HighlightText.js +1 -4
- package/dist/commonjs/components/Inspector/AnalyticsFilterModal.js +11 -26
- package/dist/commonjs/components/Inspector/AnalyticsTab.js +34 -40
- package/dist/commonjs/components/Inspector/BundleTab.js +56 -84
- package/dist/commonjs/components/Inspector/ConsoleTab.js +7 -7
- package/dist/commonjs/components/Inspector/CrashDetail.js +18 -20
- package/dist/commonjs/components/Inspector/CrashFilterModal.js +0 -1
- package/dist/commonjs/components/Inspector/CrashTab.js +11 -20
- package/dist/commonjs/components/Inspector/DeviceInfoTab.js +12 -24
- package/dist/commonjs/components/Inspector/FabLauncher.js +1 -1
- package/dist/commonjs/components/Inspector/InspectorContext.js +0 -2
- package/dist/commonjs/components/Inspector/InspectorHeader.js +7 -8
- package/dist/commonjs/components/Inspector/LogDetail.js +27 -29
- package/dist/commonjs/components/Inspector/MainScreen.js +9 -10
- package/dist/commonjs/components/Inspector/NetworkDetail.js +10 -11
- package/dist/commonjs/components/Inspector/NetworkTab.js +14 -14
- package/dist/commonjs/components/Inspector/NpmUpdateToast.js +6 -9
- package/dist/commonjs/components/Inspector/PerformanceTab.js +30 -43
- package/dist/commonjs/components/Inspector/ReduxDetail.js +18 -34
- package/dist/commonjs/components/Inspector/ReduxTab.js +11 -20
- package/dist/commonjs/components/Inspector/SettingsPanel.js +32 -36
- package/dist/commonjs/components/Inspector/SkeletonPlaceholder.js +6 -6
- package/dist/commonjs/components/Inspector/StorageTab.js +14 -26
- package/dist/commonjs/components/Inspector/UpdateAvailableModal.js +5 -6
- package/dist/commonjs/components/JsonViewer.js +3 -10
- package/dist/commonjs/components/LogCard.js +7 -7
- package/dist/commonjs/components/MetaAccordion.js +1 -7
- package/dist/commonjs/components/NetworkIcons.js +12 -16
- package/dist/commonjs/components/SectionHeader.js +0 -4
- package/dist/commonjs/components/SkeletonPlaceholder.js +6 -6
- package/dist/commonjs/components/Slider.js +6 -6
- package/dist/commonjs/components/SourcePageCard.js +0 -4
- package/dist/commonjs/components/TreeNode.js +0 -4
- package/dist/commonjs/console.d.ts +0 -4
- package/dist/commonjs/console.js +0 -4
- package/dist/commonjs/constants/index.js +6 -9
- package/dist/commonjs/constants/telemetryConfig.d.ts +3 -0
- package/dist/commonjs/constants/telemetryConfig.js +6 -0
- package/dist/commonjs/constants/version.d.ts +1 -1
- package/dist/commonjs/constants/version.js +1 -3
- package/dist/commonjs/crash.d.ts +0 -4
- package/dist/commonjs/crash.js +0 -4
- package/dist/commonjs/customHooks/analyticsLogger.d.ts +0 -7
- package/dist/commonjs/customHooks/analyticsLogger.js +3 -59
- package/dist/commonjs/customHooks/bundleAnalyzer.d.ts +0 -9
- package/dist/commonjs/customHooks/bundleAnalyzer.js +3 -86
- package/dist/commonjs/customHooks/consoleLogger.js +0 -16
- package/dist/commonjs/customHooks/crashHandler.d.ts +0 -28
- package/dist/commonjs/customHooks/crashHandler.js +0 -55
- package/dist/commonjs/customHooks/logFilters.d.ts +0 -4
- package/dist/commonjs/customHooks/logFilters.js +0 -11
- package/dist/commonjs/customHooks/networkLogger.js +2 -13
- package/dist/commonjs/customHooks/performanceTracker.d.ts +0 -27
- package/dist/commonjs/customHooks/performanceTracker.js +0 -31
- package/dist/commonjs/customHooks/reduxLogger.d.ts +0 -12
- package/dist/commonjs/customHooks/reduxLogger.js +0 -51
- package/dist/commonjs/customHooks/storageInspector.d.ts +0 -40
- package/dist/commonjs/customHooks/storageInspector.js +1 -56
- package/dist/commonjs/decorators/index.d.ts +0 -37
- package/dist/commonjs/decorators/index.js +0 -42
- package/dist/commonjs/helpers/gaAnalyticsRegistry.d.ts +0 -10
- package/dist/commonjs/helpers/gaAnalyticsRegistry.js +0 -26
- package/dist/commonjs/helpers/index.d.ts +0 -7
- package/dist/commonjs/helpers/index.js +1 -42
- package/dist/commonjs/helpers/memoryManager.d.ts +0 -11
- package/dist/commonjs/helpers/memoryManager.js +0 -13
- package/dist/commonjs/helpers/searchQueryParser.d.ts +0 -4
- package/dist/commonjs/helpers/searchQueryParser.js +0 -18
- package/dist/commonjs/helpers/settingsStore.js +0 -8
- package/dist/commonjs/helpers/telemetry.d.ts +2 -0
- package/dist/commonjs/helpers/telemetry.js +136 -0
- package/dist/commonjs/i18n/index.d.ts +0 -9
- package/dist/commonjs/i18n/index.js +0 -15
- package/dist/commonjs/index.js +15 -97
- package/dist/commonjs/native/NativeInspector.d.ts +0 -54
- package/dist/commonjs/native/NativeInspector.js +0 -56
- package/dist/commonjs/network.d.ts +0 -4
- package/dist/commonjs/network.js +0 -4
- package/dist/commonjs/performance.d.ts +0 -4
- package/dist/commonjs/performance.js +0 -4
- package/dist/commonjs/redux.d.ts +0 -4
- package/dist/commonjs/redux.js +0 -4
- package/dist/commonjs/storage.d.ts +0 -4
- package/dist/commonjs/storage.js +0 -4
- package/dist/commonjs/styles/AppColors.d.ts +0 -3
- package/dist/commonjs/styles/AppColors.js +15 -30
- package/dist/commonjs/styles/AppFonts.d.ts +0 -4
- package/dist/commonjs/styles/AppFonts.js +0 -4
- package/dist/commonjs/styles/common.js +0 -11
- package/dist/commonjs/styles/index.js +0 -8
- package/dist/commonjs/types/enums.js +0 -3
- package/dist/commonjs/types/interfaces.d.ts +3 -3
- package/dist/esm/analytics.d.ts +0 -4
- package/dist/esm/analytics.js +0 -4
- package/dist/esm/bundle.d.ts +0 -4
- package/dist/esm/bundle.js +0 -4
- package/dist/esm/components/AnalyticsDetail.js +18 -27
- package/dist/esm/components/AnalyticsEventCard.js +9 -12
- package/dist/esm/components/AnalyticsGraph.js +10 -15
- package/dist/esm/components/AppHeaderLogo.js +0 -3
- package/dist/esm/components/BrandCircleIcon.js +15 -15
- package/dist/esm/components/BrandSquareIcon.js +20 -20
- package/dist/esm/components/CodeSnippet.js +6 -19
- package/dist/esm/components/ConsoleLogCard.js +0 -1
- package/dist/esm/components/CopyButton.js +0 -4
- package/dist/esm/components/DiffViewer.js +0 -2
- package/dist/esm/components/DomainHeader.js +0 -4
- package/dist/esm/components/EmptyState.js +0 -3
- package/dist/esm/components/ErrorBoundary.js +5 -10
- package/dist/esm/components/HeadersSection.js +0 -5
- package/dist/esm/components/HighlightText.js +1 -4
- package/dist/esm/components/Inspector/AnalyticsFilterModal.js +11 -26
- package/dist/esm/components/Inspector/AnalyticsTab.js +34 -40
- package/dist/esm/components/Inspector/BundleTab.js +56 -84
- package/dist/esm/components/Inspector/ConsoleTab.js +7 -7
- package/dist/esm/components/Inspector/CrashDetail.js +18 -20
- package/dist/esm/components/Inspector/CrashFilterModal.js +0 -1
- package/dist/esm/components/Inspector/CrashTab.js +11 -20
- package/dist/esm/components/Inspector/DeviceInfoTab.js +12 -24
- package/dist/esm/components/Inspector/FabLauncher.js +1 -1
- package/dist/esm/components/Inspector/InspectorContext.js +0 -2
- package/dist/esm/components/Inspector/InspectorHeader.js +7 -8
- package/dist/esm/components/Inspector/LogDetail.js +27 -29
- package/dist/esm/components/Inspector/MainScreen.js +9 -10
- package/dist/esm/components/Inspector/NetworkDetail.js +10 -11
- package/dist/esm/components/Inspector/NetworkTab.js +14 -14
- package/dist/esm/components/Inspector/NpmUpdateToast.js +6 -9
- package/dist/esm/components/Inspector/PerformanceTab.js +30 -43
- package/dist/esm/components/Inspector/ReduxDetail.js +18 -34
- package/dist/esm/components/Inspector/ReduxTab.js +11 -20
- package/dist/esm/components/Inspector/SettingsPanel.js +32 -36
- package/dist/esm/components/Inspector/SkeletonPlaceholder.js +6 -6
- package/dist/esm/components/Inspector/StorageTab.js +14 -26
- package/dist/esm/components/Inspector/UpdateAvailableModal.js +5 -6
- package/dist/esm/components/JsonViewer.js +3 -10
- package/dist/esm/components/LogCard.js +7 -7
- package/dist/esm/components/MetaAccordion.js +1 -7
- package/dist/esm/components/NetworkIcons.js +12 -16
- package/dist/esm/components/SectionHeader.js +0 -4
- package/dist/esm/components/SkeletonPlaceholder.js +6 -6
- package/dist/esm/components/Slider.js +6 -6
- package/dist/esm/components/SourcePageCard.js +0 -4
- package/dist/esm/components/TreeNode.js +0 -4
- package/dist/esm/console.d.ts +0 -4
- package/dist/esm/console.js +0 -4
- package/dist/esm/constants/index.js +6 -9
- package/dist/esm/constants/telemetryConfig.d.ts +3 -0
- package/dist/esm/constants/telemetryConfig.js +3 -0
- package/dist/esm/constants/version.d.ts +1 -1
- package/dist/esm/constants/version.js +1 -3
- package/dist/esm/crash.d.ts +0 -4
- package/dist/esm/crash.js +0 -4
- package/dist/esm/customHooks/analyticsLogger.d.ts +0 -7
- package/dist/esm/customHooks/analyticsLogger.js +3 -59
- package/dist/esm/customHooks/bundleAnalyzer.d.ts +0 -9
- package/dist/esm/customHooks/bundleAnalyzer.js +3 -86
- package/dist/esm/customHooks/consoleLogger.js +0 -16
- package/dist/esm/customHooks/crashHandler.d.ts +0 -28
- package/dist/esm/customHooks/crashHandler.js +0 -55
- package/dist/esm/customHooks/logFilters.d.ts +0 -4
- package/dist/esm/customHooks/logFilters.js +0 -11
- package/dist/esm/customHooks/networkLogger.js +2 -13
- package/dist/esm/customHooks/performanceTracker.d.ts +0 -27
- package/dist/esm/customHooks/performanceTracker.js +0 -31
- package/dist/esm/customHooks/reduxLogger.d.ts +0 -12
- package/dist/esm/customHooks/reduxLogger.js +0 -51
- package/dist/esm/customHooks/storageInspector.d.ts +0 -40
- package/dist/esm/customHooks/storageInspector.js +1 -56
- package/dist/esm/decorators/index.d.ts +0 -37
- package/dist/esm/decorators/index.js +0 -42
- package/dist/esm/helpers/gaAnalyticsRegistry.d.ts +0 -10
- package/dist/esm/helpers/gaAnalyticsRegistry.js +0 -26
- package/dist/esm/helpers/index.d.ts +0 -7
- package/dist/esm/helpers/index.js +1 -42
- package/dist/esm/helpers/memoryManager.d.ts +0 -11
- package/dist/esm/helpers/memoryManager.js +0 -13
- package/dist/esm/helpers/searchQueryParser.d.ts +0 -4
- package/dist/esm/helpers/searchQueryParser.js +0 -18
- package/dist/esm/helpers/settingsStore.js +0 -8
- package/dist/esm/helpers/telemetry.d.ts +2 -0
- package/dist/esm/helpers/telemetry.js +132 -0
- package/dist/esm/i18n/index.d.ts +0 -9
- package/dist/esm/i18n/index.js +0 -15
- package/dist/esm/index.js +15 -97
- package/dist/esm/native/NativeInspector.d.ts +0 -54
- package/dist/esm/native/NativeInspector.js +0 -56
- package/dist/esm/network.d.ts +0 -4
- package/dist/esm/network.js +0 -4
- package/dist/esm/performance.d.ts +0 -4
- package/dist/esm/performance.js +0 -4
- package/dist/esm/redux.d.ts +0 -4
- package/dist/esm/redux.js +0 -4
- package/dist/esm/storage.d.ts +0 -4
- package/dist/esm/storage.js +0 -4
- package/dist/esm/styles/AppColors.d.ts +0 -3
- package/dist/esm/styles/AppColors.js +15 -30
- package/dist/esm/styles/AppFonts.d.ts +0 -4
- package/dist/esm/styles/AppFonts.js +0 -4
- package/dist/esm/styles/common.js +0 -11
- package/dist/esm/styles/index.js +0 -8
- package/dist/esm/types/enums.js +0 -3
- package/dist/esm/types/interfaces.d.ts +3 -3
- package/package.json +2 -2
- package/src/constants/telemetryConfig.ts +6 -0
- package/src/constants/version.ts +1 -1
- package/src/helpers/telemetry.ts +161 -0
- package/src/index.tsx +15 -1
- package/src/types/interfaces.ts +3 -0
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import { Platform, ToastAndroid, Alert, NativeModules, Linking, } from 'react-native';
|
|
2
2
|
import Clipboard from '@react-native-clipboard/clipboard';
|
|
3
3
|
import { showToast } from './toast';
|
|
4
|
-
// Stylesheet
|
|
5
4
|
import { AppColors } from '../styles/AppColors';
|
|
6
|
-
// Constants
|
|
7
5
|
import { DOMAIN_COLORS, DURATION_FAST_MS, DURATION_SLOW_MS } from '../constants';
|
|
8
6
|
export * from './searchQueryParser';
|
|
9
7
|
export * from './memoryManager';
|
|
@@ -83,7 +81,6 @@ export const copyToClipboard = (value, label) => {
|
|
|
83
81
|
textToCopy = String(resolved);
|
|
84
82
|
}
|
|
85
83
|
}
|
|
86
|
-
// Use @react-native-clipboard/clipboard npm package
|
|
87
84
|
try {
|
|
88
85
|
if (typeof Clipboard?.setString === 'function') {
|
|
89
86
|
Clipboard.setString(textToCopy);
|
|
@@ -97,12 +94,10 @@ export const copyToClipboard = (value, label) => {
|
|
|
97
94
|
console.warn('[NetworkInspector] Clipboard.setString failed:', err);
|
|
98
95
|
}
|
|
99
96
|
}
|
|
100
|
-
// Trigger floating in-app bottom toast notification
|
|
101
97
|
try {
|
|
102
98
|
showToast(label ? `${label} copied to clipboard` : 'Copied to clipboard');
|
|
103
99
|
}
|
|
104
100
|
catch { }
|
|
105
|
-
// Native Android Toast fallback
|
|
106
101
|
try {
|
|
107
102
|
if (Platform.OS === 'android' && ToastAndroid?.show) {
|
|
108
103
|
ToastAndroid.show(label ? `${label} copied to clipboard` : 'Copied to clipboard', ToastAndroid.SHORT);
|
|
@@ -215,7 +210,6 @@ export const getNavigationInfo = (state, path = []) => {
|
|
|
215
210
|
return { path: resolved, params: route.params || null };
|
|
216
211
|
};
|
|
217
212
|
export const getLogPageName = (log, routeInfo) => {
|
|
218
|
-
// 1. If routeInfo has a valid path, resolve the leaf screen name
|
|
219
213
|
const effectiveRoute = routeInfo || log?.routeInfo;
|
|
220
214
|
if (effectiveRoute &&
|
|
221
215
|
effectiveRoute.path &&
|
|
@@ -225,11 +219,10 @@ export const getLogPageName = (log, routeInfo) => {
|
|
|
225
219
|
.map((s) => s.trim())
|
|
226
220
|
.filter(Boolean);
|
|
227
221
|
if (parts.length > 0) {
|
|
228
|
-
return parts[parts.length - 1];
|
|
222
|
+
return parts[parts.length - 1];
|
|
229
223
|
}
|
|
230
224
|
return effectiveRoute.path;
|
|
231
225
|
}
|
|
232
|
-
// 2. Extract screen / component name from log.caller stack trace
|
|
233
226
|
if (log.caller && log.caller !== 'Unknown') {
|
|
234
227
|
try {
|
|
235
228
|
const match = log.caller.match(/([^/\\]+)\.(tsx|jsx|ts|js)/i);
|
|
@@ -254,7 +247,6 @@ export const getLogPageName = (log, routeInfo) => {
|
|
|
254
247
|
}
|
|
255
248
|
catch (e) { }
|
|
256
249
|
}
|
|
257
|
-
// 3. Fallback to API resource / endpoint category from URL
|
|
258
250
|
if (log.url) {
|
|
259
251
|
try {
|
|
260
252
|
const cleanUrl = log.url.split('?')[0].split('#')[0];
|
|
@@ -410,17 +402,13 @@ export const getBundleIdentifier = () => {
|
|
|
410
402
|
return 'org.reactjs.native.example';
|
|
411
403
|
};
|
|
412
404
|
export const getAppName = () => {
|
|
413
|
-
// Try iOS via PlatformConstants
|
|
414
405
|
const constants = NativeModules.PlatformConstants;
|
|
415
406
|
if (constants && typeof constants.interfaceIdiom === 'string') {
|
|
416
|
-
// Fallback: try to parse from SourceCode
|
|
417
407
|
}
|
|
418
|
-
// Try react-native-device-info
|
|
419
408
|
const RNDeviceInfo = NativeModules.RNDeviceInfo;
|
|
420
409
|
if (RNDeviceInfo && typeof RNDeviceInfo.appName === 'string') {
|
|
421
410
|
return RNDeviceInfo.appName;
|
|
422
411
|
}
|
|
423
|
-
// Try Expo
|
|
424
412
|
const ExpoApplication = NativeModules.ExpoApplication;
|
|
425
413
|
if (ExpoApplication && typeof ExpoApplication.applicationName === 'string') {
|
|
426
414
|
return ExpoApplication.applicationName;
|
|
@@ -431,17 +419,14 @@ export const getAppName = () => {
|
|
|
431
419
|
if (manifest.name)
|
|
432
420
|
return manifest.name;
|
|
433
421
|
}
|
|
434
|
-
// Android: try to get from AndroidInfoModule
|
|
435
422
|
const AppInfo = NativeModules.AppInfo;
|
|
436
423
|
if (AppInfo && typeof AppInfo.appName === 'string') {
|
|
437
424
|
return AppInfo.appName;
|
|
438
425
|
}
|
|
439
|
-
// Fallback: derive from bundle ID (last segment, cleaned up)
|
|
440
426
|
const bundleId = getBundleIdentifier();
|
|
441
427
|
if (bundleId && bundleId !== 'org.reactjs.native.example') {
|
|
442
428
|
const parts = bundleId.split('.');
|
|
443
429
|
const last = parts[parts.length - 1];
|
|
444
|
-
// Capitalize first letter
|
|
445
430
|
return last ? last.charAt(0).toUpperCase() + last.slice(1) : 'App';
|
|
446
431
|
}
|
|
447
432
|
return 'App';
|
|
@@ -449,7 +434,6 @@ export const getAppName = () => {
|
|
|
449
434
|
export const getAppVersionAndBuild = () => {
|
|
450
435
|
let version = '';
|
|
451
436
|
let build = '';
|
|
452
|
-
// 1. Try ExpoApplication / ExponentConstants
|
|
453
437
|
const ExpoApplication = NativeModules.ExpoApplication;
|
|
454
438
|
if (ExpoApplication) {
|
|
455
439
|
if (typeof ExpoApplication.nativeAppVersion === 'string') {
|
|
@@ -476,7 +460,6 @@ export const getAppVersionAndBuild = () => {
|
|
|
476
460
|
}
|
|
477
461
|
}
|
|
478
462
|
}
|
|
479
|
-
// 2. Try react-native-device-info
|
|
480
463
|
const RNDeviceInfo = NativeModules.RNDeviceInfo;
|
|
481
464
|
if (RNDeviceInfo) {
|
|
482
465
|
if (!version) {
|
|
@@ -502,7 +485,6 @@ export const getAppVersionAndBuild = () => {
|
|
|
502
485
|
}
|
|
503
486
|
}
|
|
504
487
|
}
|
|
505
|
-
// 3. Try PlatformConstants / Platform.constants
|
|
506
488
|
const constants = Platform.constants || NativeModules.PlatformConstants;
|
|
507
489
|
if (constants) {
|
|
508
490
|
if (!version &&
|
|
@@ -518,7 +500,6 @@ export const getAppVersionAndBuild = () => {
|
|
|
518
500
|
}
|
|
519
501
|
}
|
|
520
502
|
}
|
|
521
|
-
// 4. Try Android AppInfo
|
|
522
503
|
const AppInfo = NativeModules.AppInfo;
|
|
523
504
|
if (AppInfo) {
|
|
524
505
|
if (!version && typeof AppInfo.versionName === 'string') {
|
|
@@ -528,7 +509,6 @@ export const getAppVersionAndBuild = () => {
|
|
|
528
509
|
build = AppInfo.versionCode;
|
|
529
510
|
}
|
|
530
511
|
}
|
|
531
|
-
// Fallbacks
|
|
532
512
|
if (!version)
|
|
533
513
|
version = '1.0.0';
|
|
534
514
|
if (!build)
|
|
@@ -553,7 +533,6 @@ export const handleOpenExternalLink = (url) => {
|
|
|
553
533
|
},
|
|
554
534
|
]);
|
|
555
535
|
};
|
|
556
|
-
/** Formats a timestamp as HH:MM:SS (no milliseconds). */
|
|
557
536
|
export const formatTimeShort = (ts) => {
|
|
558
537
|
const d = new Date(ts);
|
|
559
538
|
const hh = String(d.getHours()).padStart(2, '0');
|
|
@@ -561,7 +540,6 @@ export const formatTimeShort = (ts) => {
|
|
|
561
540
|
const ss = String(d.getSeconds()).padStart(2, '0');
|
|
562
541
|
return `${hh}:${mm}:${ss}`;
|
|
563
542
|
};
|
|
564
|
-
/** Formats a timestamp as HH:MM:SS.mmm (with milliseconds). */
|
|
565
543
|
export const formatTime = (ts) => {
|
|
566
544
|
const d = new Date(ts);
|
|
567
545
|
const hh = String(d.getHours()).padStart(2, '0');
|
|
@@ -570,7 +548,6 @@ export const formatTime = (ts) => {
|
|
|
570
548
|
const ms = String(d.getMilliseconds()).padStart(3, '0');
|
|
571
549
|
return `${hh}:${mm}:${ss}.${ms}`;
|
|
572
550
|
};
|
|
573
|
-
/** Formats a relative gap like "+2s" / "+1m 5s" / "+350ms". */
|
|
574
551
|
export const formatGap = (ms) => {
|
|
575
552
|
if (ms < 1000)
|
|
576
553
|
return `+${ms}ms`;
|
|
@@ -581,7 +558,6 @@ export const formatGap = (ms) => {
|
|
|
581
558
|
const rem = s % 60;
|
|
582
559
|
return rem > 0 ? `+${m}m ${rem}s` : `+${m}m`;
|
|
583
560
|
};
|
|
584
|
-
/** Finds the first JSON object/array embedded anywhere in a log message. */
|
|
585
561
|
export const getJsonContent = (message) => {
|
|
586
562
|
if (!message)
|
|
587
563
|
return null;
|
|
@@ -601,12 +577,10 @@ export const getJsonContent = (message) => {
|
|
|
601
577
|
}
|
|
602
578
|
}
|
|
603
579
|
catch (e) {
|
|
604
|
-
// Ignore
|
|
605
580
|
}
|
|
606
581
|
}
|
|
607
582
|
return null;
|
|
608
583
|
};
|
|
609
|
-
/** Pretty-prints JSON data showing 3-4 lines with trailing "..." */
|
|
610
584
|
export const getJsonPreviewText = (data, maxLines = 4) => {
|
|
611
585
|
try {
|
|
612
586
|
const formatted = JSON.stringify(data, null, 2);
|
|
@@ -629,17 +603,14 @@ export const getJsonPreviewText = (data, maxLines = 4) => {
|
|
|
629
603
|
};
|
|
630
604
|
}
|
|
631
605
|
};
|
|
632
|
-
/** Parses a stack trace line to extract function name, file name, extension (.tsx/.jsx/.ts), line, and column numbers */
|
|
633
606
|
export const parseStackLine = (rawLine, isOrigin = false) => {
|
|
634
607
|
let line = rawLine.trim().replace(/^at /, '');
|
|
635
|
-
// Format: func@file:line:col (JSC / Hermes format)
|
|
636
608
|
if (line.includes('@')) {
|
|
637
609
|
const atIndex = line.indexOf('@');
|
|
638
610
|
const funcPart = line.substring(0, atIndex).trim();
|
|
639
611
|
const pathPart = line.substring(atIndex + 1).trim();
|
|
640
612
|
line = funcPart ? `${funcPart} (${pathPart})` : pathPart;
|
|
641
613
|
}
|
|
642
|
-
// Check for "func (path:line:col)" or "path:line:col"
|
|
643
614
|
const parenMatch = line.match(/^(.*?)\s*\((.*?)\)$/);
|
|
644
615
|
let functionName = '<anonymous>';
|
|
645
616
|
let locationPart = line;
|
|
@@ -647,13 +618,10 @@ export const parseStackLine = (rawLine, isOrigin = false) => {
|
|
|
647
618
|
functionName = parenMatch[1].trim() || '<anonymous>';
|
|
648
619
|
locationPart = parenMatch[2].trim();
|
|
649
620
|
}
|
|
650
|
-
// Clean Babel/Hermes artifacts in function names like ?anon_0_, _callee$, etc.
|
|
651
621
|
if (functionName.startsWith('?anon_') || functionName === '?') {
|
|
652
622
|
functionName = 'anonymous';
|
|
653
623
|
}
|
|
654
|
-
// Remove "address at " prefix if present in Hermes
|
|
655
624
|
locationPart = locationPart.replace(/^address at /, '');
|
|
656
|
-
// Extract file, line, and col from locationPart (e.g. "path/to/file.tsx:42:15" or "http://...:42:15")
|
|
657
625
|
const locMatch = locationPart.match(/^(.*?):(\d+):(\d+)$/);
|
|
658
626
|
let fullPath = locationPart;
|
|
659
627
|
let lineNumber;
|
|
@@ -663,16 +631,13 @@ export const parseStackLine = (rawLine, isOrigin = false) => {
|
|
|
663
631
|
lineNumber = locMatch[2];
|
|
664
632
|
columnNumber = locMatch[3];
|
|
665
633
|
}
|
|
666
|
-
// Clean file name (remove query strings, packager urls, and parent paths)
|
|
667
634
|
let cleanPath = fullPath
|
|
668
635
|
.split('?')[0]
|
|
669
636
|
.split('&')[0]
|
|
670
637
|
.replace(/[)]+$/, '')
|
|
671
638
|
.replace(/\/\/+$/, '');
|
|
672
|
-
// Remove protocol prefixes
|
|
673
639
|
cleanPath = cleanPath.replace(/^(?:https?:\/\/[^\/]+\/|file:\/\/\/|webpack:\/\/\/?)/, '');
|
|
674
640
|
const fileName = cleanPath.split('/').filter(Boolean).pop() || cleanPath;
|
|
675
|
-
// Determine file extension (.tsx, .jsx, .ts, .js)
|
|
676
641
|
const extMatch = fileName.match(/\.([a-z0-9]+)$/i);
|
|
677
642
|
const ext = extMatch ? extMatch[1].toLowerCase() : '';
|
|
678
643
|
const fileExt = ext === 'tsx' || ext === 'jsx' || ext === 'ts' || ext === 'js'
|
|
@@ -709,7 +674,6 @@ export const parseStackLine = (rawLine, isOrigin = false) => {
|
|
|
709
674
|
isNative ||
|
|
710
675
|
functionName === 'asyncGeneratorStep' ||
|
|
711
676
|
functionName === '_next';
|
|
712
|
-
// Format clean relative project path
|
|
713
677
|
let relativePath = cleanPath;
|
|
714
678
|
if (relativePath.includes('/example/')) {
|
|
715
679
|
relativePath = relativePath.substring(relativePath.indexOf('/example/') + 9);
|
|
@@ -739,14 +703,12 @@ export const parseStackLine = (rawLine, isOrigin = false) => {
|
|
|
739
703
|
copyableLocation,
|
|
740
704
|
};
|
|
741
705
|
};
|
|
742
|
-
/** Opens a file and line number directly in VS Code / system editor */
|
|
743
706
|
export const openInVSCode = (filePath, lineNumber, columnNumber) => {
|
|
744
707
|
const numLine = lineNumber ? Number(lineNumber) : 1;
|
|
745
708
|
const numCol = columnNumber ? Number(columnNumber) : 1;
|
|
746
709
|
const line = lineNumber ? `:${lineNumber}` : '';
|
|
747
710
|
const col = columnNumber ? `:${columnNumber}` : '';
|
|
748
711
|
const cleanPath = filePath.replace(/^file:\/\//, '');
|
|
749
|
-
// 1. Notify Metro dev server on host to launch editor directly on local system
|
|
750
712
|
let extractedOrigin = null;
|
|
751
713
|
try {
|
|
752
714
|
const scriptURL = NativeModules?.SourceCode?.scriptURL ||
|
|
@@ -783,20 +745,17 @@ export const openInVSCode = (filePath, lineNumber, columnNumber) => {
|
|
|
783
745
|
}
|
|
784
746
|
catch { }
|
|
785
747
|
});
|
|
786
|
-
// 2. Also invoke native URL scheme handlers
|
|
787
748
|
const vscodeUrl = `vscode://file/${cleanPath.replace(/^\/+/, '')}${line}${col}`;
|
|
788
749
|
const cursorUrl = `cursor://file/${cleanPath.replace(/^\/+/, '')}${line}${col}`;
|
|
789
750
|
const vscodeInsidersUrl = `vscode-insiders://file/${cleanPath.replace(/^\/+/, '')}${line}${col}`;
|
|
790
751
|
Linking.openURL(vscodeUrl).catch(() => {
|
|
791
752
|
Linking.openURL(cursorUrl).catch(() => {
|
|
792
753
|
Linking.openURL(vscodeInsidersUrl).catch(() => {
|
|
793
|
-
// Fallback: Copy to clipboard so user can jump immediately
|
|
794
754
|
copyToClipboard(`${cleanPath}${line}${col}`, 'Location');
|
|
795
755
|
});
|
|
796
756
|
});
|
|
797
757
|
});
|
|
798
758
|
};
|
|
799
|
-
// ─── Analytics Helpers ────────────────────────────────────────────────────────
|
|
800
759
|
export const ANALYTICS_EVENT_PALETTE = [
|
|
801
760
|
AppColors.googleBlue,
|
|
802
761
|
AppColors.googleGreen,
|
|
@@ -10,19 +10,8 @@ export interface MemoryPruneSummary {
|
|
|
10
10
|
triggeredBy: 'memory-warning' | 'manual' | 'ram-threshold';
|
|
11
11
|
}
|
|
12
12
|
type MemoryWarningListener = (summary: MemoryPruneSummary) => void;
|
|
13
|
-
/**
|
|
14
|
-
* Prunes all in-memory log stores to prevent OOM / memory pressure.
|
|
15
|
-
* Keeps targetRetentionPct (default: 50%) of existing logs.
|
|
16
|
-
*/
|
|
17
13
|
export declare const pruneAllLogs: (triggeredBy?: MemoryPruneSummary["triggeredBy"], targetRetentionPct?: number) => MemoryPruneSummary;
|
|
18
|
-
/**
|
|
19
|
-
* Starts listening to OS memory pressure warnings via AppState 'memoryWarning'.
|
|
20
|
-
* Automatically prunes logs and notifies subscribers when memory is constrained.
|
|
21
|
-
*/
|
|
22
14
|
export declare const setupMemoryWarningHandler: () => (() => void);
|
|
23
|
-
/**
|
|
24
|
-
* Subscribes to memory prune events.
|
|
25
|
-
*/
|
|
26
15
|
export declare const subscribeMemoryWarning: (listener: MemoryWarningListener) => (() => void);
|
|
27
16
|
export declare const getLastPruneTimestamp: () => number;
|
|
28
17
|
export declare const isMemoryHandlerActive: () => boolean;
|
|
@@ -10,10 +10,6 @@ const memoryListeners = new Set();
|
|
|
10
10
|
let appStateSubscription = null;
|
|
11
11
|
let isMemoryWarningHandlerActive = false;
|
|
12
12
|
let lastPruneTimestamp = 0;
|
|
13
|
-
/**
|
|
14
|
-
* Prunes all in-memory log stores to prevent OOM / memory pressure.
|
|
15
|
-
* Keeps targetRetentionPct (default: 50%) of existing logs.
|
|
16
|
-
*/
|
|
17
13
|
export const pruneAllLogs = (triggeredBy = 'manual', targetRetentionPct = 0.5) => {
|
|
18
14
|
const targetPct = Math.max(0.1, Math.min(1.0, targetRetentionPct));
|
|
19
15
|
const prunedNetwork = pruneNetworkLogs(undefined);
|
|
@@ -29,7 +25,6 @@ export const pruneAllLogs = (triggeredBy = 'manual', targetRetentionPct = 0.5) =
|
|
|
29
25
|
prunedCrashes +
|
|
30
26
|
prunedPerformance;
|
|
31
27
|
lastPruneTimestamp = Date.now();
|
|
32
|
-
// Trigger Hermes/V8 Garbage Collection if exposed
|
|
33
28
|
if (typeof globalThis.gc === 'function') {
|
|
34
29
|
try {
|
|
35
30
|
globalThis.gc();
|
|
@@ -59,10 +54,6 @@ export const pruneAllLogs = (triggeredBy = 'manual', targetRetentionPct = 0.5) =
|
|
|
59
54
|
});
|
|
60
55
|
return summary;
|
|
61
56
|
};
|
|
62
|
-
/**
|
|
63
|
-
* Starts listening to OS memory pressure warnings via AppState 'memoryWarning'.
|
|
64
|
-
* Automatically prunes logs and notifies subscribers when memory is constrained.
|
|
65
|
-
*/
|
|
66
57
|
export const setupMemoryWarningHandler = () => {
|
|
67
58
|
if (isMemoryWarningHandlerActive) {
|
|
68
59
|
return () => { };
|
|
@@ -78,7 +69,6 @@ export const setupMemoryWarningHandler = () => {
|
|
|
78
69
|
});
|
|
79
70
|
}
|
|
80
71
|
catch (e) {
|
|
81
|
-
// AppState memoryWarning might not be supported on all mock/test platforms
|
|
82
72
|
}
|
|
83
73
|
return () => {
|
|
84
74
|
if (appStateSubscription) {
|
|
@@ -91,9 +81,6 @@ export const setupMemoryWarningHandler = () => {
|
|
|
91
81
|
isMemoryWarningHandlerActive = false;
|
|
92
82
|
};
|
|
93
83
|
};
|
|
94
|
-
/**
|
|
95
|
-
* Subscribes to memory prune events.
|
|
96
|
-
*/
|
|
97
84
|
export const subscribeMemoryWarning = (listener) => {
|
|
98
85
|
memoryListeners.add(listener);
|
|
99
86
|
return () => {
|
|
@@ -4,8 +4,4 @@ export interface SearchQueryOptions {
|
|
|
4
4
|
isRegex?: boolean;
|
|
5
5
|
isCaseSensitive?: boolean;
|
|
6
6
|
}
|
|
7
|
-
/**
|
|
8
|
-
* Parses query strings like `method:POST is:error slow:>1s status:200 auth`
|
|
9
|
-
* and checks whether a given NetworkLog matches all tokens against the specified scope.
|
|
10
|
-
*/
|
|
11
7
|
export declare function matchNetworkLogQuery(log: NetworkLog, searchQuery: string, routePath?: string, options?: SearchQueryOptions): boolean;
|
|
@@ -1,11 +1,6 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Parses query strings like `method:POST is:error slow:>1s status:200 auth`
|
|
3
|
-
* and checks whether a given NetworkLog matches all tokens against the specified scope.
|
|
4
|
-
*/
|
|
5
1
|
export function matchNetworkLogQuery(log, searchQuery, routePath, options) {
|
|
6
2
|
if (!searchQuery || searchQuery.trim().length === 0)
|
|
7
3
|
return true;
|
|
8
|
-
// Split tokens by spaces or commas while respecting quotes
|
|
9
4
|
const rawTokens = searchQuery.trim().match(/(?:[^\s,"']+|"[^"]*"|'[^']*')+/g) || [];
|
|
10
5
|
if (rawTokens.length === 0)
|
|
11
6
|
return true;
|
|
@@ -40,7 +35,6 @@ export function matchNetworkLogQuery(log, searchQuery, routePath, options) {
|
|
|
40
35
|
? JSON.stringify(log.responseHeaders)
|
|
41
36
|
: '';
|
|
42
37
|
const pathRaw = routePath || log?.routeInfo?.path || '';
|
|
43
|
-
// Construct search corpus based on active scope
|
|
44
38
|
const getScopedCorpus = (caseSens) => {
|
|
45
39
|
let parts = [];
|
|
46
40
|
if (scope === 'url') {
|
|
@@ -87,7 +81,6 @@ export function matchNetworkLogQuery(log, searchQuery, routePath, options) {
|
|
|
87
81
|
if (!token)
|
|
88
82
|
continue;
|
|
89
83
|
const lowerToken = token.toLowerCase();
|
|
90
|
-
// 1. method:<VAL> or m:<VAL>
|
|
91
84
|
if (lowerToken.startsWith('method:') || lowerToken.startsWith('m:')) {
|
|
92
85
|
const targetMethod = lowerToken.replace(/^(method:|m:)/, '').trim();
|
|
93
86
|
if (targetMethod.startsWith('!')) {
|
|
@@ -100,7 +93,6 @@ export function matchNetworkLogQuery(log, searchQuery, routePath, options) {
|
|
|
100
93
|
}
|
|
101
94
|
continue;
|
|
102
95
|
}
|
|
103
|
-
// 2. status:<VAL> or s:<VAL>
|
|
104
96
|
if (lowerToken.startsWith('status:') || lowerToken.startsWith('s:')) {
|
|
105
97
|
const val = lowerToken.replace(/^(status:|s:)/, '').trim();
|
|
106
98
|
if (val === 'pending' || val === 'loading') {
|
|
@@ -144,7 +136,6 @@ export function matchNetworkLogQuery(log, searchQuery, routePath, options) {
|
|
|
144
136
|
}
|
|
145
137
|
continue;
|
|
146
138
|
}
|
|
147
|
-
// 3. is:<FLAG>
|
|
148
139
|
if (lowerToken.startsWith('is:')) {
|
|
149
140
|
const flag = lowerToken.slice(3).trim();
|
|
150
141
|
if (flag === 'error' ||
|
|
@@ -202,7 +193,6 @@ export function matchNetworkLogQuery(log, searchQuery, routePath, options) {
|
|
|
202
193
|
}
|
|
203
194
|
continue;
|
|
204
195
|
}
|
|
205
|
-
// 4. slow:<DURATION> or dur:<DURATION> or duration:<DURATION>
|
|
206
196
|
if (lowerToken.startsWith('slow:') ||
|
|
207
197
|
lowerToken.startsWith('dur:') ||
|
|
208
198
|
lowerToken.startsWith('duration:')) {
|
|
@@ -247,21 +237,18 @@ export function matchNetworkLogQuery(log, searchQuery, routePath, options) {
|
|
|
247
237
|
}
|
|
248
238
|
continue;
|
|
249
239
|
}
|
|
250
|
-
// 5. client:<CLIENT> or c:<CLIENT>
|
|
251
240
|
if (lowerToken.startsWith('client:') || lowerToken.startsWith('c:')) {
|
|
252
241
|
const targetClient = lowerToken.replace(/^(client:|c:)/, '').trim();
|
|
253
242
|
if (!clientStr.includes(targetClient))
|
|
254
243
|
return false;
|
|
255
244
|
continue;
|
|
256
245
|
}
|
|
257
|
-
// 6. domain:<DOMAIN> or d:<DOMAIN>
|
|
258
246
|
if (lowerToken.startsWith('domain:') || lowerToken.startsWith('d:')) {
|
|
259
247
|
const targetDomain = lowerToken.replace(/^(domain:|d:)/, '').trim();
|
|
260
248
|
if (!urlStr.includes(targetDomain))
|
|
261
249
|
return false;
|
|
262
250
|
continue;
|
|
263
251
|
}
|
|
264
|
-
// 7. path:<PATH> or p:<PATH> or page:<PAGE>
|
|
265
252
|
if (lowerToken.startsWith('path:') ||
|
|
266
253
|
lowerToken.startsWith('p:') ||
|
|
267
254
|
lowerToken.startsWith('page:')) {
|
|
@@ -275,21 +262,18 @@ export function matchNetworkLogQuery(log, searchQuery, routePath, options) {
|
|
|
275
262
|
}
|
|
276
263
|
continue;
|
|
277
264
|
}
|
|
278
|
-
// 8. req:<TERM> or body:<TERM>
|
|
279
265
|
if (lowerToken.startsWith('req:') || lowerToken.startsWith('body:')) {
|
|
280
266
|
const target = lowerToken.replace(/^(req:|body:)/, '').trim();
|
|
281
267
|
if (!reqStr.includes(target))
|
|
282
268
|
return false;
|
|
283
269
|
continue;
|
|
284
270
|
}
|
|
285
|
-
// 9. res:<TERM>
|
|
286
271
|
if (lowerToken.startsWith('res:')) {
|
|
287
272
|
const target = lowerToken.slice(4).trim();
|
|
288
273
|
if (!resStr.includes(target))
|
|
289
274
|
return false;
|
|
290
275
|
continue;
|
|
291
276
|
}
|
|
292
|
-
// 10. header:<TERM> or h:<TERM>
|
|
293
277
|
if (lowerToken.startsWith('header:') || lowerToken.startsWith('h:')) {
|
|
294
278
|
const target = lowerToken.replace(/^(header:|h:)/, '').trim();
|
|
295
279
|
if (!reqHeadersStr.includes(target) && !resHeadersStr.includes(target)) {
|
|
@@ -297,7 +281,6 @@ export function matchNetworkLogQuery(log, searchQuery, routePath, options) {
|
|
|
297
281
|
}
|
|
298
282
|
continue;
|
|
299
283
|
}
|
|
300
|
-
// 11. Generic Match (handles Regex, Case-sensitivity, and Scoped corpus)
|
|
301
284
|
if (isRegex) {
|
|
302
285
|
try {
|
|
303
286
|
const re = new RegExp(token, isCaseSensitive ? '' : 'i');
|
|
@@ -313,7 +296,6 @@ export function matchNetworkLogQuery(log, searchQuery, routePath, options) {
|
|
|
313
296
|
else {
|
|
314
297
|
const queryTerm = isCaseSensitive ? token : lowerToken;
|
|
315
298
|
if (!targetCorpus.includes(queryTerm)) {
|
|
316
|
-
// Special case: if user typed "error" / "failed", check error status
|
|
317
299
|
if (queryTerm === 'error' ||
|
|
318
300
|
queryTerm === 'failed' ||
|
|
319
301
|
queryTerm === 'fail') {
|
|
@@ -1,10 +1,5 @@
|
|
|
1
|
-
// #5 — Persistence layer for the inspector's settings selections.
|
|
2
|
-
//
|
|
3
|
-
// Backed by iOS Settings (NSUserDefaults) for iOS, or custom storage if passed (e.g. AsyncStorage/MMKV).
|
|
4
|
-
// Contains an in-memory fallback for Android or Jest test environments.
|
|
5
1
|
import { Platform, Settings } from 'react-native';
|
|
6
2
|
import { getNativeStorageItem, setNativeStorageItem, isNativeModuleAvailable, } from '../native/NativeInspector';
|
|
7
|
-
// In-memory fallback (settings survive for the app session only).
|
|
8
3
|
const memory = new Map();
|
|
9
4
|
let customStorage = null;
|
|
10
5
|
export function setCustomStorage(storage) {
|
|
@@ -37,7 +32,6 @@ export async function loadSettings() {
|
|
|
37
32
|
}
|
|
38
33
|
return raw && typeof raw === 'object' ? raw : {};
|
|
39
34
|
}
|
|
40
|
-
// In-memory fallback
|
|
41
35
|
const raw = memory.get(SETTINGS_KEY);
|
|
42
36
|
if (!raw)
|
|
43
37
|
return {};
|
|
@@ -65,7 +59,6 @@ export function saveSettings(settings) {
|
|
|
65
59
|
memory.set(SETTINGS_KEY, raw);
|
|
66
60
|
}
|
|
67
61
|
catch {
|
|
68
|
-
// ignore
|
|
69
62
|
}
|
|
70
63
|
}
|
|
71
64
|
export async function clearPersistedSettings() {
|
|
@@ -89,7 +82,6 @@ export async function clearPersistedSettings() {
|
|
|
89
82
|
memory.delete(SETTINGS_KEY);
|
|
90
83
|
}
|
|
91
84
|
catch {
|
|
92
|
-
// ignore
|
|
93
85
|
}
|
|
94
86
|
}
|
|
95
87
|
export const isPersistentStorageAvailable = () => {
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { Platform } from 'react-native';
|
|
2
|
+
import { LIB_VERSION } from '../constants/version';
|
|
3
|
+
import { loadSettings, saveSettings } from './settingsStore';
|
|
4
|
+
import { ENC_MID, ENC_SEC, TELEMETRY_SALT, } from '../constants/telemetryConfig';
|
|
5
|
+
const PKG_NAME = 'react-native-inapp-inspector';
|
|
6
|
+
const KEY_MATERIAL = `${PKG_NAME}::${TELEMETRY_SALT}`;
|
|
7
|
+
function getKeystream(material, length) {
|
|
8
|
+
const stream = [];
|
|
9
|
+
let acc = 0x5a827999;
|
|
10
|
+
for (let i = 0; i < length; i++) {
|
|
11
|
+
const charCode = material.charCodeAt(i % material.length);
|
|
12
|
+
acc = ((acc * 31 + charCode * 17 + i * 13) ^ (acc >>> 7)) & 0xffffffff;
|
|
13
|
+
stream.push((acc >>> (i % 24)) & 0xff);
|
|
14
|
+
}
|
|
15
|
+
return stream;
|
|
16
|
+
}
|
|
17
|
+
function deobfuscate(hexStr) {
|
|
18
|
+
if (!hexStr)
|
|
19
|
+
return '';
|
|
20
|
+
const bytes = [];
|
|
21
|
+
for (let i = 0; i < hexStr.length; i += 2) {
|
|
22
|
+
bytes.push(parseInt(hexStr.substring(i, i + 2), 16));
|
|
23
|
+
}
|
|
24
|
+
const keystream = getKeystream(KEY_MATERIAL, bytes.length);
|
|
25
|
+
const out = [];
|
|
26
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
27
|
+
const k = keystream[i];
|
|
28
|
+
const s = TELEMETRY_SALT.charCodeAt(i % TELEMETRY_SALT.length);
|
|
29
|
+
const dec = (bytes[i] ^ k ^ s) & 0xff;
|
|
30
|
+
out.push(String.fromCharCode(dec));
|
|
31
|
+
}
|
|
32
|
+
return out.join('');
|
|
33
|
+
}
|
|
34
|
+
let _cachedMid = null;
|
|
35
|
+
let _cachedSec = null;
|
|
36
|
+
function getCredentials() {
|
|
37
|
+
if (_cachedMid !== null && _cachedSec !== null) {
|
|
38
|
+
return { measurementId: _cachedMid, apiSecret: _cachedSec };
|
|
39
|
+
}
|
|
40
|
+
if (!ENC_MID || !ENC_SEC || !TELEMETRY_SALT) {
|
|
41
|
+
_cachedMid = '';
|
|
42
|
+
_cachedSec = '';
|
|
43
|
+
return { measurementId: '', apiSecret: '' };
|
|
44
|
+
}
|
|
45
|
+
try {
|
|
46
|
+
_cachedMid = deobfuscate(ENC_MID);
|
|
47
|
+
_cachedSec = deobfuscate(ENC_SEC);
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
_cachedMid = '';
|
|
51
|
+
_cachedSec = '';
|
|
52
|
+
}
|
|
53
|
+
return { measurementId: _cachedMid, apiSecret: _cachedSec };
|
|
54
|
+
}
|
|
55
|
+
function getCollectUrl() {
|
|
56
|
+
const { measurementId, apiSecret } = getCredentials();
|
|
57
|
+
if (!measurementId || !apiSecret)
|
|
58
|
+
return '';
|
|
59
|
+
return `https://www.google-analytics.com/mp/collect?measurement_id=${measurementId}&api_secret=${apiSecret}`;
|
|
60
|
+
}
|
|
61
|
+
const PING_INTERVAL_MS = 24 * 60 * 60 * 1000;
|
|
62
|
+
let isTelemetryEnabled = true;
|
|
63
|
+
export function setTelemetryEnabled(enabled) {
|
|
64
|
+
isTelemetryEnabled = enabled;
|
|
65
|
+
}
|
|
66
|
+
async function getOrCreateClientId() {
|
|
67
|
+
try {
|
|
68
|
+
const settings = await loadSettings();
|
|
69
|
+
if (settings.telemetryClientId) {
|
|
70
|
+
return settings.telemetryClientId;
|
|
71
|
+
}
|
|
72
|
+
const part1 = Math.floor(100000000 + Math.random() * 900000000);
|
|
73
|
+
const part2 = Math.floor(1000000000 + Math.random() * 9000000000);
|
|
74
|
+
const newId = `${part1}.${part2}`;
|
|
75
|
+
saveSettings({ ...settings, telemetryClientId: newId });
|
|
76
|
+
return newId;
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
return `${Math.floor(100000000 + Math.random() * 900000000)}.${Math.floor(1000000000 + Math.random() * 9000000000)}`;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
function getSystemMetadata(environment) {
|
|
83
|
+
const rnConstants = Platform.constants;
|
|
84
|
+
const rnVersion = rnConstants?.reactNativeVersion
|
|
85
|
+
? `${rnConstants.reactNativeVersion.major}.${rnConstants.reactNativeVersion.minor}.${rnConstants.reactNativeVersion.patch}`
|
|
86
|
+
: 'unknown';
|
|
87
|
+
const isHermes = Boolean(typeof global.HermesInternal === 'object' && global.HermesInternal !== null);
|
|
88
|
+
const isFabric = Boolean(global?.nativeFabricUIManager !== undefined);
|
|
89
|
+
const isDev = Boolean(typeof __DEV__ !== 'undefined' && __DEV__);
|
|
90
|
+
return {
|
|
91
|
+
lib_version: LIB_VERSION,
|
|
92
|
+
platform: Platform.OS,
|
|
93
|
+
os_version: String(Platform.Version || 'unknown'),
|
|
94
|
+
rn_version: rnVersion,
|
|
95
|
+
is_hermes: isHermes,
|
|
96
|
+
is_fabric: isFabric,
|
|
97
|
+
is_dev: isDev,
|
|
98
|
+
environment: environment || (isDev ? 'DEV' : 'PROD'),
|
|
99
|
+
engagement_time_msec: 1000,
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
export async function trackActiveTelemetryHeartbeat(telemetryEnabled = true, environment) {
|
|
103
|
+
if (telemetryEnabled === false) {
|
|
104
|
+
isTelemetryEnabled = false;
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
isTelemetryEnabled = true;
|
|
108
|
+
const url = getCollectUrl();
|
|
109
|
+
if (!url)
|
|
110
|
+
return;
|
|
111
|
+
try {
|
|
112
|
+
const settings = await loadSettings();
|
|
113
|
+
const lastPing = settings.telemetryLastPing || 0;
|
|
114
|
+
const now = Date.now();
|
|
115
|
+
if (now - lastPing < PING_INTERVAL_MS)
|
|
116
|
+
return;
|
|
117
|
+
const clientId = await getOrCreateClientId();
|
|
118
|
+
const params = getSystemMetadata(environment);
|
|
119
|
+
await fetch(url, {
|
|
120
|
+
method: 'POST',
|
|
121
|
+
headers: { 'Content-Type': 'application/json' },
|
|
122
|
+
body: JSON.stringify({
|
|
123
|
+
client_id: clientId,
|
|
124
|
+
non_personalized_ads: true,
|
|
125
|
+
events: [{ name: 'inspector_active_heartbeat', params }],
|
|
126
|
+
}),
|
|
127
|
+
});
|
|
128
|
+
saveSettings({ ...settings, telemetryLastPing: now });
|
|
129
|
+
}
|
|
130
|
+
catch {
|
|
131
|
+
}
|
|
132
|
+
}
|
package/dist/esm/i18n/index.d.ts
CHANGED
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
type TranslationParams = Record<string, any>;
|
|
3
|
-
/**
|
|
4
|
-
* Standalone zero-dependency translation function
|
|
5
|
-
*/
|
|
6
3
|
export declare function t(key: string, optionsOrFallback?: TranslationParams | string): string;
|
|
7
4
|
export declare function setLanguage(lang: string): void;
|
|
8
5
|
export declare function addTranslations(lang: string, translations: Record<string, any>): void;
|
|
@@ -16,9 +13,6 @@ export declare const i18n: {
|
|
|
16
13
|
addTranslations: typeof addTranslations;
|
|
17
14
|
setTranslations: typeof setTranslations;
|
|
18
15
|
};
|
|
19
|
-
/**
|
|
20
|
-
* React hook compatible with react-i18next useTranslation()
|
|
21
|
-
*/
|
|
22
16
|
export declare function useTranslation(): {
|
|
23
17
|
t: typeof t;
|
|
24
18
|
i18n: {
|
|
@@ -31,9 +25,6 @@ export declare function useTranslation(): {
|
|
|
31
25
|
setTranslations: typeof setTranslations;
|
|
32
26
|
};
|
|
33
27
|
};
|
|
34
|
-
/**
|
|
35
|
-
* Backward-compatible I18nextProvider component
|
|
36
|
-
*/
|
|
37
28
|
export declare const I18nextProvider: ({ children }: {
|
|
38
29
|
children?: React.ReactNode;
|
|
39
30
|
i18n?: any;
|