react-native-inapp-inspector 2.3.4 → 2.3.6
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 +168 -9
- 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 +7 -0
- package/dist/commonjs/constants/telemetryConfig.js +10 -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 +302 -0
- package/dist/commonjs/i18n/index.d.ts +0 -9
- package/dist/commonjs/i18n/index.js +0 -15
- package/dist/commonjs/index.d.ts +0 -1
- package/dist/commonjs/index.js +18 -102
- 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 +168 -9
- 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 +7 -0
- package/dist/esm/constants/telemetryConfig.js +7 -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 +298 -0
- package/dist/esm/i18n/index.d.ts +0 -9
- package/dist/esm/i18n/index.js +0 -15
- package/dist/esm/index.d.ts +0 -1
- package/dist/esm/index.js +15 -98
- 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/components/Inspector/MainScreen.tsx +188 -2
- package/src/constants/telemetryConfig.ts +16 -0
- package/src/constants/version.ts +1 -1
- package/src/helpers/telemetry.ts +341 -0
- package/src/index.tsx +15 -2
- package/src/types/interfaces.ts +3 -0
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
// Styles
|
|
2
1
|
import { AppColors } from '../styles/AppColors';
|
|
3
2
|
export const STATUS_FILTERS = [
|
|
4
3
|
'ALL',
|
|
@@ -13,16 +12,14 @@ export const STATUS_FILTERS = [
|
|
|
13
12
|
'Failed',
|
|
14
13
|
];
|
|
15
14
|
export const METHOD_COLORS = {
|
|
16
|
-
ALL: '#64748B',
|
|
17
|
-
GET: '#059669',
|
|
18
|
-
POST: '#2563EB',
|
|
19
|
-
PUT: '#D97706',
|
|
20
|
-
PATCH: '#7C3AED',
|
|
21
|
-
DELETE: '#DC2626',
|
|
15
|
+
ALL: '#64748B',
|
|
16
|
+
GET: '#059669',
|
|
17
|
+
POST: '#2563EB',
|
|
18
|
+
PUT: '#D97706',
|
|
19
|
+
PATCH: '#7C3AED',
|
|
20
|
+
DELETE: '#DC2626',
|
|
22
21
|
};
|
|
23
22
|
export const DOMAIN_COLORS = AppColors.domainColors;
|
|
24
23
|
export const DURATION_FAST_MS = 200;
|
|
25
24
|
export const DURATION_SLOW_MS = 800;
|
|
26
|
-
// Package version — auto-generated from package.json at build time.
|
|
27
|
-
// See scripts/gen-version.js (wired to the "prebuild" npm script).
|
|
28
25
|
export { LIB_VERSION } from './version';
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare const ENC_MID = "029e338afbbf509e97b2ea5b";
|
|
2
|
+
export declare const ENC_MID_IV = "9a6d6b4d732f07bedbe40229";
|
|
3
|
+
export declare const ENC_MID_TAG = "e545372ce1ad53c593394a2c0281c75d";
|
|
4
|
+
export declare const ENC_SEC = "7e95ab688f1b37f9b72d3ab70c9d92105e5bd7046e84";
|
|
5
|
+
export declare const ENC_SEC_IV = "64a3aa1ee24005449e885c08";
|
|
6
|
+
export declare const ENC_SEC_TAG = "007ce86e096dfb0ed902678902754f71";
|
|
7
|
+
export declare const TELEMETRY_SALT = "rn-inapp-inspector-telemetry-v1";
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export const ENC_MID = '029e338afbbf509e97b2ea5b';
|
|
2
|
+
export const ENC_MID_IV = '9a6d6b4d732f07bedbe40229';
|
|
3
|
+
export const ENC_MID_TAG = 'e545372ce1ad53c593394a2c0281c75d';
|
|
4
|
+
export const ENC_SEC = '7e95ab688f1b37f9b72d3ab70c9d92105e5bd7046e84';
|
|
5
|
+
export const ENC_SEC_IV = '64a3aa1ee24005449e885c08';
|
|
6
|
+
export const ENC_SEC_TAG = '007ce86e096dfb0ed902678902754f71';
|
|
7
|
+
export const TELEMETRY_SALT = 'rn-inapp-inspector-telemetry-v1';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const LIB_VERSION = "2.3.
|
|
1
|
+
export declare const LIB_VERSION = "2.3.6";
|
package/dist/esm/crash.d.ts
CHANGED
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Sub-module entry point: react-native-inapp-inspector/crash
|
|
3
|
-
* Clean tree-shaking & isolated global crash handler and reporting.
|
|
4
|
-
*/
|
|
5
1
|
export { setupGlobalCrashHandler, subscribeCrashEvents, emitCrashEvent, getCrashRecords, clearCrashRecords, simulateTestCrash, exportCrashReport, parseCrashStackTrace, setMaxCrashLogsLimit, getMaxCrashLogsLimit, pruneCrashRecords, setCrashModuleEnabled, getCrashModuleEnabled, } from './customHooks/crashHandler';
|
|
6
2
|
export type { CrashRecord, CrashBreadcrumb, } from './types';
|
|
7
3
|
export { CrashType, CrashExportFormat, CrashDetailSubTab, CrashFilterType, BreadcrumbType, } from './types';
|
package/dist/esm/crash.js
CHANGED
|
@@ -1,6 +1,2 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Sub-module entry point: react-native-inapp-inspector/crash
|
|
3
|
-
* Clean tree-shaking & isolated global crash handler and reporting.
|
|
4
|
-
*/
|
|
5
1
|
export { setupGlobalCrashHandler, subscribeCrashEvents, emitCrashEvent, getCrashRecords, clearCrashRecords, simulateTestCrash, exportCrashReport, parseCrashStackTrace, setMaxCrashLogsLimit, getMaxCrashLogsLimit, pruneCrashRecords, setCrashModuleEnabled, getCrashModuleEnabled, } from './customHooks/crashHandler';
|
|
6
2
|
export { CrashType, CrashExportFormat, CrashDetailSubTab, CrashFilterType, BreadcrumbType, } from './types';
|
|
@@ -15,14 +15,7 @@ export declare const getDefaultEventParameters: () => {
|
|
|
15
15
|
[x: string]: any;
|
|
16
16
|
};
|
|
17
17
|
export declare const getCollectionEnabled: () => boolean;
|
|
18
|
-
/**
|
|
19
|
-
* Directly push an event into the inspector without going through Firebase.
|
|
20
|
-
* Useful for custom analytics wrappers or testing.
|
|
21
|
-
*/
|
|
22
18
|
export declare const logAnalyticsEvent: (name: string, params?: Record<string, any>, userProperties?: Record<string, any>) => void;
|
|
23
|
-
/**
|
|
24
|
-
* Returns true if analytics logging is active (always ready for custom and Firebase events).
|
|
25
|
-
*/
|
|
26
19
|
export declare const isAnalyticsConnected: () => boolean;
|
|
27
20
|
export declare const isFirebaseAnalyticsPatched: () => boolean;
|
|
28
21
|
export declare const setupAnalyticsLogger: (analyticsInstance: any) => void;
|
|
@@ -1,26 +1,3 @@
|
|
|
1
|
-
// ─── Analytics Logger ─────────────────────────────────────────────────────────
|
|
2
|
-
//
|
|
3
|
-
// Captures @react-native-firebase/analytics events by monkey-patching the
|
|
4
|
-
// analytics instance returned by `analytics()`.
|
|
5
|
-
//
|
|
6
|
-
// Setup (call once at app startup, before any analytics calls):
|
|
7
|
-
//
|
|
8
|
-
// import analytics from '@react-native-firebase/analytics';
|
|
9
|
-
// import { setupAnalyticsLogger } from './network/analyticsLogger';
|
|
10
|
-
//
|
|
11
|
-
// setupAnalyticsLogger(analytics());
|
|
12
|
-
//
|
|
13
|
-
// That's it — every subsequent logEvent / logScreenView / setUserProperty call
|
|
14
|
-
// will be intercepted and shown in the Analytics tab of NetworkInspector.
|
|
15
|
-
//
|
|
16
|
-
// Patched methods:
|
|
17
|
-
// logEvent(name, params)
|
|
18
|
-
// logScreenView({ screen_name, screen_class })
|
|
19
|
-
// setUserProperty(name, value)
|
|
20
|
-
// setUserProperties(properties)
|
|
21
|
-
// setUserId(id)
|
|
22
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
23
|
-
// ─── Internal state ───────────────────────────────────────────────────────────
|
|
24
1
|
let events = [];
|
|
25
2
|
let listeners = [];
|
|
26
3
|
let counter = 0;
|
|
@@ -29,7 +6,6 @@ export const setAnalyticsModuleEnabled = (enabled) => {
|
|
|
29
6
|
isAnalyticsModuleEnabled = enabled;
|
|
30
7
|
};
|
|
31
8
|
export const getAnalyticsModuleEnabled = () => isAnalyticsModuleEnabled;
|
|
32
|
-
// Running snapshot of user properties set so far — attached to every event
|
|
33
9
|
let currentUserProperties = {};
|
|
34
10
|
let currentUserId;
|
|
35
11
|
let currentDefaultEventParameters = {};
|
|
@@ -52,7 +28,6 @@ export const pruneAnalyticsLogs = (targetCount) => {
|
|
|
52
28
|
}
|
|
53
29
|
return Math.max(0, pruned);
|
|
54
30
|
};
|
|
55
|
-
// ─── Core helpers ─────────────────────────────────────────────────────────────
|
|
56
31
|
const notify = () => {
|
|
57
32
|
const snapshot = [...events];
|
|
58
33
|
listeners.forEach(cb => cb(snapshot));
|
|
@@ -64,7 +39,6 @@ const addEvent = (event) => {
|
|
|
64
39
|
events = events.slice(0, maxAnalyticsLogsLimit);
|
|
65
40
|
notify();
|
|
66
41
|
};
|
|
67
|
-
// ─── Public subscribe / query API ────────────────────────────────────────────
|
|
68
42
|
export const subscribeAnalyticsEvents = (callback) => {
|
|
69
43
|
listeners.push(callback);
|
|
70
44
|
callback([...events]);
|
|
@@ -81,11 +55,6 @@ export const getCurrentUserProperties = () => ({ ...currentUserProperties });
|
|
|
81
55
|
export const getCurrentUserId = () => currentUserId;
|
|
82
56
|
export const getDefaultEventParameters = () => ({ ...currentDefaultEventParameters });
|
|
83
57
|
export const getCollectionEnabled = () => isCollectionEnabled;
|
|
84
|
-
// ─── Manual logging (escape hatch, rarely needed) ────────────────────────────
|
|
85
|
-
/**
|
|
86
|
-
* Directly push an event into the inspector without going through Firebase.
|
|
87
|
-
* Useful for custom analytics wrappers or testing.
|
|
88
|
-
*/
|
|
89
58
|
export const logAnalyticsEvent = (name, params = {}, userProperties = {}) => {
|
|
90
59
|
addEvent({
|
|
91
60
|
id: counter++,
|
|
@@ -99,22 +68,7 @@ export const logAnalyticsEvent = (name, params = {}, userProperties = {}) => {
|
|
|
99
68
|
screenClass: '',
|
|
100
69
|
});
|
|
101
70
|
};
|
|
102
|
-
// ─── Firebase Analytics instance patcher ─────────────────────────────────────
|
|
103
|
-
/**
|
|
104
|
-
* Monkey-patches a @react-native-firebase/analytics instance so all calls
|
|
105
|
-
* are intercepted and forwarded to the NetworkInspector analytics tab.
|
|
106
|
-
*
|
|
107
|
-
* Pass the result of `analytics()` (the default app instance or any named one).
|
|
108
|
-
* Safe to call multiple times with the same instance — won't double-patch.
|
|
109
|
-
*
|
|
110
|
-
* @example
|
|
111
|
-
* import analytics from '@react-native-firebase/analytics';
|
|
112
|
-
* setupAnalyticsLogger(analytics());
|
|
113
|
-
*/
|
|
114
71
|
let isAnalyticsPatched = false;
|
|
115
|
-
/**
|
|
116
|
-
* Returns true if analytics logging is active (always ready for custom and Firebase events).
|
|
117
|
-
*/
|
|
118
72
|
export const isAnalyticsConnected = () => true;
|
|
119
73
|
export const isFirebaseAnalyticsPatched = () => isAnalyticsPatched;
|
|
120
74
|
export const setupAnalyticsLogger = (analyticsInstance) => {
|
|
@@ -123,11 +77,9 @@ export const setupAnalyticsLogger = (analyticsInstance) => {
|
|
|
123
77
|
return;
|
|
124
78
|
}
|
|
125
79
|
isAnalyticsPatched = true;
|
|
126
|
-
// Guard against double-patching the same instance
|
|
127
80
|
if (analyticsInstance.__INSPECTOR_PATCHED__)
|
|
128
81
|
return;
|
|
129
82
|
analyticsInstance.__INSPECTOR_PATCHED__ = true;
|
|
130
|
-
// ── logEvent ──────────────────────────────────────────────────────────────
|
|
131
83
|
const originalLogEvent = analyticsInstance.logEvent.bind(analyticsInstance);
|
|
132
84
|
analyticsInstance.logEvent = async (name, params) => {
|
|
133
85
|
try {
|
|
@@ -146,7 +98,6 @@ export const setupAnalyticsLogger = (analyticsInstance) => {
|
|
|
146
98
|
catch { }
|
|
147
99
|
return originalLogEvent(name, params);
|
|
148
100
|
};
|
|
149
|
-
// ── logScreenView ─────────────────────────────────────────────────────────
|
|
150
101
|
const originalLogScreenView = analyticsInstance.logScreenView.bind(analyticsInstance);
|
|
151
102
|
analyticsInstance.logScreenView = async (params) => {
|
|
152
103
|
try {
|
|
@@ -165,7 +116,6 @@ export const setupAnalyticsLogger = (analyticsInstance) => {
|
|
|
165
116
|
catch { }
|
|
166
117
|
return originalLogScreenView(params);
|
|
167
118
|
};
|
|
168
|
-
// ── setUserProperty ───────────────────────────────────────────────────────
|
|
169
119
|
const originalSetUserProperty = analyticsInstance.setUserProperty.bind(analyticsInstance);
|
|
170
120
|
analyticsInstance.setUserProperty = async (name, value) => {
|
|
171
121
|
try {
|
|
@@ -179,7 +129,6 @@ export const setupAnalyticsLogger = (analyticsInstance) => {
|
|
|
179
129
|
catch { }
|
|
180
130
|
return originalSetUserProperty(name, value);
|
|
181
131
|
};
|
|
182
|
-
// ── setUserProperties ─────────────────────────────────────────────────────
|
|
183
132
|
const originalSetUserProperties = analyticsInstance.setUserProperties.bind(analyticsInstance);
|
|
184
133
|
analyticsInstance.setUserProperties = async (properties) => {
|
|
185
134
|
try {
|
|
@@ -195,7 +144,6 @@ export const setupAnalyticsLogger = (analyticsInstance) => {
|
|
|
195
144
|
catch { }
|
|
196
145
|
return originalSetUserProperties(properties);
|
|
197
146
|
};
|
|
198
|
-
// ── setUserId ─────────────────────────────────────────────────────────────
|
|
199
147
|
const originalSetUserId = analyticsInstance.setUserId.bind(analyticsInstance);
|
|
200
148
|
analyticsInstance.setUserId = async (id) => {
|
|
201
149
|
try {
|
|
@@ -205,7 +153,6 @@ export const setupAnalyticsLogger = (analyticsInstance) => {
|
|
|
205
153
|
catch { }
|
|
206
154
|
return originalSetUserId(id);
|
|
207
155
|
};
|
|
208
|
-
// ── setDefaultEventParameters ──────────────────────────────────────────────
|
|
209
156
|
if (typeof analyticsInstance.setDefaultEventParameters === 'function') {
|
|
210
157
|
const originalSetDefaultEventParameters = analyticsInstance.setDefaultEventParameters.bind(analyticsInstance);
|
|
211
158
|
analyticsInstance.setDefaultEventParameters = async (params) => {
|
|
@@ -217,7 +164,6 @@ export const setupAnalyticsLogger = (analyticsInstance) => {
|
|
|
217
164
|
return originalSetDefaultEventParameters(params);
|
|
218
165
|
};
|
|
219
166
|
}
|
|
220
|
-
// ── setAnalyticsCollectionEnabled ───────────────────────────────────────────
|
|
221
167
|
if (typeof analyticsInstance.setAnalyticsCollectionEnabled === 'function') {
|
|
222
168
|
const originalSetAnalyticsCollectionEnabled = analyticsInstance.setAnalyticsCollectionEnabled.bind(analyticsInstance);
|
|
223
169
|
analyticsInstance.setAnalyticsCollectionEnabled = async (enabled) => {
|
|
@@ -229,7 +175,6 @@ export const setupAnalyticsLogger = (analyticsInstance) => {
|
|
|
229
175
|
return originalSetAnalyticsCollectionEnabled(enabled);
|
|
230
176
|
};
|
|
231
177
|
}
|
|
232
|
-
// ── resetAnalyticsData ──────────────────────────────────────────────────────
|
|
233
178
|
if (typeof analyticsInstance.resetAnalyticsData === 'function') {
|
|
234
179
|
const originalResetAnalyticsData = analyticsInstance.resetAnalyticsData.bind(analyticsInstance);
|
|
235
180
|
analyticsInstance.resetAnalyticsData = async () => {
|
|
@@ -250,10 +195,10 @@ export const autoSetupAnalyticsLogger = () => {
|
|
|
250
195
|
return true;
|
|
251
196
|
let mod;
|
|
252
197
|
try {
|
|
253
|
-
mod = require('@react-native-firebase/analytics');
|
|
198
|
+
mod = require('@react-native-firebase/analytics');
|
|
254
199
|
}
|
|
255
200
|
catch {
|
|
256
|
-
return false;
|
|
201
|
+
return false;
|
|
257
202
|
}
|
|
258
203
|
const accessor = mod?.default ?? mod;
|
|
259
204
|
if (typeof accessor !== 'function')
|
|
@@ -261,9 +206,8 @@ export const autoSetupAnalyticsLogger = () => {
|
|
|
261
206
|
try {
|
|
262
207
|
setupAnalyticsLogger(accessor());
|
|
263
208
|
}
|
|
264
|
-
catch { }
|
|
209
|
+
catch { }
|
|
265
210
|
if (!accessor.__INSPECTOR_WRAPPED__) {
|
|
266
|
-
// patch future/named instances
|
|
267
211
|
const wrapped = function (...args) {
|
|
268
212
|
const instance = accessor.apply(this, args);
|
|
269
213
|
try {
|
|
@@ -108,17 +108,8 @@ export declare const getBundleModuleEnabled: () => boolean;
|
|
|
108
108
|
export declare const getHostScriptURL: () => string;
|
|
109
109
|
export declare const trackRuntimeModuleExecution: () => void;
|
|
110
110
|
export declare const trackRuntimeDefine: () => void;
|
|
111
|
-
/**
|
|
112
|
-
* Parses raw Metro bundle source code to discover real modules and packages in the host app.
|
|
113
|
-
*/
|
|
114
111
|
export declare const parseBundleSource: (bundleText: string, totalBytes: number, scriptURL: string, isLive?: boolean) => HostBundleAnalysisResult;
|
|
115
|
-
/**
|
|
116
|
-
* Returns an instant baseline bundle analysis synchronously (never blocks UI).
|
|
117
|
-
*/
|
|
118
112
|
export declare const getInitialBundleAnalysis: () => HostBundleAnalysisResult;
|
|
119
|
-
/**
|
|
120
|
-
* Asynchronously fetch and analyze the running Metro bundle in the background.
|
|
121
|
-
*/
|
|
122
113
|
export declare const analyzeHostAppBundle: (forceRefresh?: boolean) => Promise<HostBundleAnalysisResult>;
|
|
123
114
|
export declare const clearCachedBundleAnalysis: () => void;
|
|
124
115
|
export declare const getCachedBundleAnalysis: () => HostBundleAnalysisResult | null;
|
|
@@ -1,14 +1,5 @@
|
|
|
1
1
|
import { AppColors } from '../styles/AppColors';
|
|
2
2
|
import { t } from '../i18n';
|
|
3
|
-
// ─── Real Host App Bundle Analyzer ──────────────────────────────────────────
|
|
4
|
-
//
|
|
5
|
-
// Dynamically measures and analyzes the real JavaScript bundle and packages
|
|
6
|
-
// for the hosted application at runtime by:
|
|
7
|
-
// 1. Inspecting `NativeModules.SourceCode.scriptURL` for the active Metro bundle.
|
|
8
|
-
// 2. Fetching and measuring the exact byte size of the running JS bundle.
|
|
9
|
-
// 3. Extracting real module paths (project files vs node_modules dependencies).
|
|
10
|
-
// 4. Computing real Development and Production Binary (.ipa / .aab / .apk) sizes.
|
|
11
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
12
3
|
import { NativeModules, Platform, TurboModuleRegistry } from 'react-native';
|
|
13
4
|
let cachedAnalysis = null;
|
|
14
5
|
let isAnalyzing = false;
|
|
@@ -39,7 +30,6 @@ const getSourceCodeModule = () => {
|
|
|
39
30
|
return null;
|
|
40
31
|
};
|
|
41
32
|
export const getHostScriptURL = () => {
|
|
42
|
-
// 1. NativeModules.SourceCode (bridged) or SourceCode TurboModule (bridgeless / new arch)
|
|
43
33
|
try {
|
|
44
34
|
const scriptURL = getSourceCodeModule()?.scriptURL;
|
|
45
35
|
if (typeof scriptURL === 'string' && scriptURL.length > 0) {
|
|
@@ -47,7 +37,6 @@ export const getHostScriptURL = () => {
|
|
|
47
37
|
}
|
|
48
38
|
}
|
|
49
39
|
catch { }
|
|
50
|
-
// 2. Android legacy & new arch: PlatformConstants.serverHost, DevSettings, or AndroidConstants
|
|
51
40
|
try {
|
|
52
41
|
const serverHost = NativeModules?.PlatformConstants?.serverHost ||
|
|
53
42
|
NativeModules?.AndroidConstants?.serverHost ||
|
|
@@ -59,7 +48,6 @@ export const getHostScriptURL = () => {
|
|
|
59
48
|
}
|
|
60
49
|
}
|
|
61
50
|
catch { }
|
|
62
|
-
// 3. Fallback to global dev configs if defined
|
|
63
51
|
try {
|
|
64
52
|
const globalHost = globalThis?.__DEV_SERVER_URL__ ||
|
|
65
53
|
globalThis?.__METRO_SERVER_HOST__ ||
|
|
@@ -82,7 +70,6 @@ export const getHostScriptURL = () => {
|
|
|
82
70
|
catch { }
|
|
83
71
|
return '';
|
|
84
72
|
};
|
|
85
|
-
// Dynamic Metro dev server ports to probe
|
|
86
73
|
const DYNAMIC_DEV_PORTS = [8081, 8082, 8083, 8084, 8085, 8086, 8087, 8088, 8089, 8090, 19000, 19001, 3000];
|
|
87
74
|
const extractHostAndPort = (scriptURL) => {
|
|
88
75
|
if (!scriptURL || typeof scriptURL !== 'string') {
|
|
@@ -99,7 +86,6 @@ const extractHostAndPort = (scriptURL) => {
|
|
|
99
86
|
};
|
|
100
87
|
const probeCandidateUrlsInParallel = async (scriptURL, timeoutMs = 3000) => {
|
|
101
88
|
const { host: extractedHost, port: extractedPort } = extractHostAndPort(scriptURL);
|
|
102
|
-
// 1. If we have a direct HTTP scriptURL, try fetching directly
|
|
103
89
|
if (scriptURL && scriptURL.startsWith('http')) {
|
|
104
90
|
try {
|
|
105
91
|
const controller = new AbortController();
|
|
@@ -116,10 +102,8 @@ const probeCandidateUrlsInParallel = async (scriptURL, timeoutMs = 3000) => {
|
|
|
116
102
|
}
|
|
117
103
|
}
|
|
118
104
|
catch {
|
|
119
|
-
// Continue to dynamic port discovery
|
|
120
105
|
}
|
|
121
106
|
}
|
|
122
|
-
// 2. Dynamic Port Discovery via parallel lightweight Metro /status probes
|
|
123
107
|
const candidateHosts = extractedHost
|
|
124
108
|
? [extractedHost, 'localhost', '127.0.0.1', ...(Platform.OS === 'android' ? ['10.0.2.2', '10.0.3.2'] : [])]
|
|
125
109
|
: ['localhost', '127.0.0.1', ...(Platform.OS === 'android' ? ['10.0.2.2', '10.0.3.2'] : [])];
|
|
@@ -172,7 +156,6 @@ const probeCandidateUrlsInParallel = async (scriptURL, timeoutMs = 3000) => {
|
|
|
172
156
|
catch {
|
|
173
157
|
activeServer = null;
|
|
174
158
|
}
|
|
175
|
-
// 3. If a live Metro port was detected dynamically, fetch the bundle from it
|
|
176
159
|
if (activeServer) {
|
|
177
160
|
const dynamicBundleUrl = `http://${activeServer.host}:${activeServer.port}/index.bundle?platform=${Platform.OS}&dev=true`;
|
|
178
161
|
try {
|
|
@@ -190,13 +173,10 @@ const probeCandidateUrlsInParallel = async (scriptURL, timeoutMs = 3000) => {
|
|
|
190
173
|
}
|
|
191
174
|
}
|
|
192
175
|
catch {
|
|
193
|
-
// Fallback
|
|
194
176
|
}
|
|
195
177
|
}
|
|
196
178
|
return null;
|
|
197
179
|
};
|
|
198
|
-
// ─── Runtime Module & Define Tracking ────────────────────────────────────────
|
|
199
|
-
// Captures modules registered via Metro's global __d and executed via __r.
|
|
200
180
|
const executedModuleIds = new Set();
|
|
201
181
|
const runtimeModules = new Map();
|
|
202
182
|
export const trackRuntimeModuleExecution = () => {
|
|
@@ -257,7 +237,6 @@ const extractBundleModules = (bundleText) => {
|
|
|
257
237
|
const modules = [];
|
|
258
238
|
const seenIds = new Set();
|
|
259
239
|
if (bundleText && bundleText.length > 0) {
|
|
260
|
-
// 1. Fast linear regex on sourceURL (100% linear, zero backtracking, super fast)
|
|
261
240
|
const sourceUrlRegex = /\/\/[#@]\s*sourceURL=(?:https?:\/\/[^\s\r\n/]+\/|file:\/\/)?([^\s\r\n?#]+)/g;
|
|
262
241
|
let srcMatch;
|
|
263
242
|
let autoId = 900000;
|
|
@@ -271,7 +250,6 @@ const extractBundleModules = (bundleText) => {
|
|
|
271
250
|
}
|
|
272
251
|
}
|
|
273
252
|
}
|
|
274
|
-
// 2. Linear bounded regex for __d definitions: __d(..., <id>, [...], "<path>")
|
|
275
253
|
const linearDefineRegex = /,\s*(\d+)\s*,\s*(?:\[[^\]\r\n]{0,500}\]|\{[^}\r\n]{0,500}\})\s*,\s*["']([^"'\r\n]+)["']\s*\)/g;
|
|
276
254
|
let defMatch;
|
|
277
255
|
while ((defMatch = linearDefineRegex.exec(bundleText)) !== null) {
|
|
@@ -283,7 +261,6 @@ const extractBundleModules = (bundleText) => {
|
|
|
283
261
|
}
|
|
284
262
|
}
|
|
285
263
|
}
|
|
286
|
-
// 3. Merge runtime modules registered through global.__d
|
|
287
264
|
runtimeModules.forEach((item, id) => {
|
|
288
265
|
if (!seenIds.has(id)) {
|
|
289
266
|
seenIds.add(id);
|
|
@@ -306,27 +283,20 @@ const getStaticStartupModuleIds = (bundleText) => {
|
|
|
306
283
|
}
|
|
307
284
|
return ids;
|
|
308
285
|
};
|
|
309
|
-
/**
|
|
310
|
-
* Dynamically computes the host app's project root directory without hardcoding any folder names.
|
|
311
|
-
* Uses node_modules boundary, root entry points (index/App/package.json), and common directory analysis.
|
|
312
|
-
*/
|
|
313
286
|
const detectProjectRoot = (allRawPaths) => {
|
|
314
287
|
const normPaths = allRawPaths.map(p => p.replace(/\\/g, '/'));
|
|
315
|
-
// 1. Extract from node_modules path (most definitive in Metro dev bundles)
|
|
316
288
|
for (const norm of normPaths) {
|
|
317
289
|
const nmIdx = norm.indexOf('/node_modules/');
|
|
318
290
|
if (nmIdx !== -1) {
|
|
319
|
-
return norm.slice(0, nmIdx + 1);
|
|
291
|
+
return norm.slice(0, nmIdx + 1);
|
|
320
292
|
}
|
|
321
293
|
}
|
|
322
|
-
// 2. Extract from root entrypoint files (e.g. /path/to/project/index.js or App.tsx)
|
|
323
294
|
for (const norm of normPaths) {
|
|
324
295
|
const match = norm.match(/^(.*\/)(?:index\.[jt]sx?|app\.[jt]sx?|package\.json)(?:[?#].*)?$/i);
|
|
325
296
|
if (match && match[1]) {
|
|
326
297
|
return match[1];
|
|
327
298
|
}
|
|
328
299
|
}
|
|
329
|
-
// 3. Fallback: lowest common directory ancestor among all absolute project paths
|
|
330
300
|
const absPaths = normPaths.filter(p => p.startsWith('/') && !p.includes('/node_modules/'));
|
|
331
301
|
if (absPaths.length === 0)
|
|
332
302
|
return '';
|
|
@@ -349,31 +319,22 @@ const detectProjectRoot = (allRawPaths) => {
|
|
|
349
319
|
}
|
|
350
320
|
return commonLen > 0 ? first.slice(0, commonLen).join('/') + '/' : '';
|
|
351
321
|
};
|
|
352
|
-
/**
|
|
353
|
-
* Normalizes absolute or relative module paths so they retain their full
|
|
354
|
-
* folder hierarchy from the host project root dynamically.
|
|
355
|
-
*/
|
|
356
322
|
const normalizeProjectRelativePath = (rawPath, projectRoot) => {
|
|
357
323
|
let clean = rawPath.replace(/\\/g, '/');
|
|
358
|
-
// Strip query parameters e.g. ?platform=ios or hashes
|
|
359
324
|
const qIdx = clean.search(/[?#]/);
|
|
360
325
|
if (qIdx !== -1) {
|
|
361
326
|
clean = clean.slice(0, qIdx);
|
|
362
327
|
}
|
|
363
|
-
// Strip file:// or http://.../ dev server URL prefixes
|
|
364
328
|
clean = clean.replace(/^(?:https?:\/\/[^/]+\/|file:\/\/)/, '');
|
|
365
|
-
// Strip dynamically detected project root prefix
|
|
366
329
|
if (projectRoot && clean.startsWith(projectRoot)) {
|
|
367
330
|
clean = clean.slice(projectRoot.length);
|
|
368
331
|
}
|
|
369
|
-
// Clean leading ../ sequences, ./, and leading /
|
|
370
332
|
clean = clean.replace(/^(\.\.\/)+/, '').replace(/^\.\//, '').replace(/^\/+/, '');
|
|
371
333
|
if (!clean)
|
|
372
334
|
clean = rawPath.split('/').pop() || rawPath;
|
|
373
335
|
return clean;
|
|
374
336
|
};
|
|
375
337
|
const isExternalPackage = (rawPath) => {
|
|
376
|
-
// 1. Standard node_modules
|
|
377
338
|
if (rawPath.includes('node_modules/')) {
|
|
378
339
|
const pkgMatch = rawPath.match(/node_modules\/(?:@([^/]+)\/([^/]+)|([^/]+))/);
|
|
379
340
|
if (pkgMatch) {
|
|
@@ -382,15 +343,12 @@ const isExternalPackage = (rawPath) => {
|
|
|
382
343
|
}
|
|
383
344
|
return { isPkg: true };
|
|
384
345
|
}
|
|
385
|
-
// 2. React Native In-App Inspector (when linked or embedded)
|
|
386
346
|
if (rawPath.includes('react-native-inapp-inspector')) {
|
|
387
347
|
return { isPkg: true, pkgName: 'react-native-inapp-inspector' };
|
|
388
348
|
}
|
|
389
|
-
// 3. Yarn berry / pnpm virtual stores
|
|
390
349
|
if (rawPath.includes('.yarn/') || rawPath.includes('.pnpm/')) {
|
|
391
350
|
return { isPkg: true };
|
|
392
351
|
}
|
|
393
|
-
// 4. Compiled package dist / build folders outside project source
|
|
394
352
|
if (rawPath.includes('/dist/esm/') ||
|
|
395
353
|
rawPath.includes('/dist/commonjs/') ||
|
|
396
354
|
rawPath.includes('/dist/cjs/') ||
|
|
@@ -411,22 +369,16 @@ const isInternalModule = (rawPath) => {
|
|
|
411
369
|
rawPath.includes('Libraries/Core/InitializeCore.js') ||
|
|
412
370
|
rawPath.includes('@babel/runtime'));
|
|
413
371
|
};
|
|
414
|
-
/**
|
|
415
|
-
* Parses raw Metro bundle source code to discover real modules and packages in the host app.
|
|
416
|
-
*/
|
|
417
372
|
export const parseBundleSource = (bundleText, totalBytes, scriptURL, isLive = true) => {
|
|
418
373
|
const isHermes = Boolean(globalThis.HermesInternal);
|
|
419
374
|
const totalDevMb = Number((totalBytes / (1024 * 1024)).toFixed(2));
|
|
420
375
|
const totalDevKb = Math.round(totalBytes / 1024);
|
|
421
376
|
const modules = extractBundleModules(bundleText);
|
|
422
377
|
const startupIds = getStaticStartupModuleIds(bundleText);
|
|
423
|
-
// Build module map for dependency graph traversal
|
|
424
378
|
const modMap = new Map();
|
|
425
379
|
for (const mod of modules) {
|
|
426
380
|
modMap.set(mod.id, mod);
|
|
427
381
|
}
|
|
428
|
-
// Transitive Reachability: traverse the dependency graph starting from
|
|
429
|
-
// entrypoints (index.js, App.tsx, app.json, startupIds, executedModuleIds)
|
|
430
382
|
const consumedIds = new Set();
|
|
431
383
|
const queue = [];
|
|
432
384
|
const markConsumed = (id) => {
|
|
@@ -435,7 +387,6 @@ export const parseBundleSource = (bundleText, totalBytes, scriptURL, isLive = tr
|
|
|
435
387
|
queue.push(id);
|
|
436
388
|
}
|
|
437
389
|
};
|
|
438
|
-
// Seed with root entrypoints and runtime executions
|
|
439
390
|
markConsumed(0);
|
|
440
391
|
startupIds.forEach(id => markConsumed(id));
|
|
441
392
|
executedModuleIds.forEach(id => markConsumed(id));
|
|
@@ -454,7 +405,6 @@ export const parseBundleSource = (bundleText, totalBytes, scriptURL, isLive = tr
|
|
|
454
405
|
markConsumed(mod.id);
|
|
455
406
|
}
|
|
456
407
|
}
|
|
457
|
-
// Transitive BFS dependency traversal
|
|
458
408
|
while (queue.length > 0) {
|
|
459
409
|
const currId = queue.shift();
|
|
460
410
|
const currMod = modMap.get(currId);
|
|
@@ -467,7 +417,7 @@ export const parseBundleSource = (bundleText, totalBytes, scriptURL, isLive = tr
|
|
|
467
417
|
const discoveredPackagesMap = new Map();
|
|
468
418
|
const rawProjectItems = [];
|
|
469
419
|
for (const mod of modules) {
|
|
470
|
-
const rawPath = mod.path.replace(/\\/g, '/');
|
|
420
|
+
const rawPath = mod.path.replace(/\\/g, '/');
|
|
471
421
|
const { isPkg, pkgName } = isExternalPackage(rawPath);
|
|
472
422
|
if (isPkg) {
|
|
473
423
|
if (pkgName && !pkgName.startsWith('.')) {
|
|
@@ -475,13 +425,11 @@ export const parseBundleSource = (bundleText, totalBytes, scriptURL, isLive = tr
|
|
|
475
425
|
}
|
|
476
426
|
continue;
|
|
477
427
|
}
|
|
478
|
-
// Filter out internal Metro polyfills / virtual modules
|
|
479
428
|
if (isInternalModule(rawPath)) {
|
|
480
429
|
continue;
|
|
481
430
|
}
|
|
482
431
|
rawProjectItems.push({ mod, rawPath });
|
|
483
432
|
}
|
|
484
|
-
// Dynamically calculate project root prefix to cleanly extract all host app folders & files
|
|
485
433
|
const projectRoot = detectProjectRoot(modules.map(item => item.path));
|
|
486
434
|
const discoveredFiles = [];
|
|
487
435
|
let fileIdx = 0;
|
|
@@ -541,11 +489,7 @@ export const parseBundleSource = (bundleText, totalBytes, scriptURL, isLive = tr
|
|
|
541
489
|
category = 'json';
|
|
542
490
|
color = AppColors.emerald500;
|
|
543
491
|
}
|
|
544
|
-
// Approximate module size from total dev size and module count
|
|
545
492
|
const approxKb = Math.max(2, Math.round((totalDevKb * 0.15) / Math.max(modules.length, 20)));
|
|
546
|
-
// In React Native Metro bundler, modules included in the bundle are transitively
|
|
547
|
-
// imported from the entrypoint (index.js / App.tsx) and active in the dependency tree.
|
|
548
|
-
// A module is marked as 'Not Consumed' only if it is an orphaned test file, mock fixture, or dead spec.
|
|
549
493
|
const isTestOrFixture = cleanPath.includes('.test.') ||
|
|
550
494
|
cleanPath.includes('.spec.') ||
|
|
551
495
|
cleanPath.includes('__tests__') ||
|
|
@@ -569,7 +513,6 @@ export const parseBundleSource = (bundleText, totalBytes, scriptURL, isLive = tr
|
|
|
569
513
|
isConsumed,
|
|
570
514
|
});
|
|
571
515
|
}
|
|
572
|
-
// Dynamic color palette generator based on package name hash
|
|
573
516
|
const getPackageColor = (name) => {
|
|
574
517
|
const colors = [
|
|
575
518
|
AppColors.indigo500, AppColors.sky500, AppColors.pink500, AppColors.purple500, AppColors.emerald500,
|
|
@@ -652,7 +595,6 @@ export const parseBundleSource = (bundleText, totalBytes, scriptURL, isLive = tr
|
|
|
652
595
|
}
|
|
653
596
|
return null;
|
|
654
597
|
};
|
|
655
|
-
// Convert discovered packages into dynamic package items
|
|
656
598
|
const packageEntries = Array.from(discoveredPackagesMap.entries());
|
|
657
599
|
const totalPkgHits = packageEntries.reduce((sum, [, hits]) => sum + hits, 0) || 1;
|
|
658
600
|
const packagesList = [];
|
|
@@ -682,7 +624,6 @@ export const parseBundleSource = (bundleText, totalBytes, scriptURL, isLive = tr
|
|
|
682
624
|
lastActive: `${hits} modules`,
|
|
683
625
|
});
|
|
684
626
|
});
|
|
685
|
-
// Attach subpackages to their direct parents
|
|
686
627
|
const directPackagesMap = new Map();
|
|
687
628
|
packagesList.forEach(pkg => {
|
|
688
629
|
if (pkg.isDirectDefined) {
|
|
@@ -697,9 +638,7 @@ export const parseBundleSource = (bundleText, totalBytes, scriptURL, isLive = tr
|
|
|
697
638
|
parent.subpackages.push(pkg);
|
|
698
639
|
}
|
|
699
640
|
});
|
|
700
|
-
// Sort packages by size descending
|
|
701
641
|
packagesList.sort((a, b) => b.sizeKb - a.sizeKb);
|
|
702
|
-
// Compute Development Split-Up dynamically from real discovered files and packages
|
|
703
642
|
let realNodeModulesKb = 0;
|
|
704
643
|
for (const pkg of packagesList) {
|
|
705
644
|
realNodeModulesKb += pkg.sizeKb || 0;
|
|
@@ -718,35 +657,21 @@ export const parseBundleSource = (bundleText, totalBytes, scriptURL, isLive = tr
|
|
|
718
657
|
const nodeModulesKb = realNodeModulesKb > 0 ? realNodeModulesKb : Math.round(totalDevKb * 0.58);
|
|
719
658
|
const assetsMediaKb = realAssetsMediaKb > 0 ? realAssetsMediaKb : Math.round(totalDevKb * 0.08);
|
|
720
659
|
const metroOverheadKb = Math.max(0, totalDevKb - appSourceKb - nodeModulesKb - assetsMediaKb);
|
|
721
|
-
// ─── Production Binary (.ipa / .aab / .apk) Dynamically Scaled ────────────
|
|
722
|
-
// Fully dynamic across any React Native project based on:
|
|
723
|
-
// 1. Exact Hermes bytecode size (releaseJsMb derived from totalDevKb)
|
|
724
|
-
// 2. Exact third-party package count and dependency weight
|
|
725
|
-
// 3. Exact media assets, fonts, and images size (assetsMediaKb)
|
|
726
660
|
const releaseJsMb = Number(((totalDevKb * 0.38) / 1024).toFixed(2));
|
|
727
661
|
const nodeModulesMb = Number((nodeModulesKb / 1024).toFixed(2));
|
|
728
662
|
const assetsMediaMb = Number((assetsMediaKb / 1024).toFixed(2));
|
|
729
|
-
// In node_modules, only ~15-20% of packages contain compiled native code (C++ .so, Swift/Obj-C)
|
|
730
|
-
// Clamp effective native packages so large JS dependency trees (150+ packages) scale realistically
|
|
731
663
|
const effectiveNativePkgCount = Math.min(packagesList.length, 55);
|
|
732
|
-
// ─── 1. iOS Binary Calculations (.ipa / App Store) ────────────────────────
|
|
733
|
-
// Base React Native iOS engine Mach-O + third-party dynamic Frameworks + Assets + Hermes
|
|
734
664
|
const nativeFrameworksMb = Number((48.0 + effectiveNativePkgCount * 0.35 + nodeModulesMb * 0.9).toFixed(1));
|
|
735
665
|
const nativeMachoMb = Number((38.0 + effectiveNativePkgCount * 0.22 + nodeModulesMb * 0.6).toFixed(1));
|
|
736
666
|
const assetsCatalogMb = Number((30.0 + assetsMediaMb * 2.2).toFixed(1));
|
|
737
667
|
const metadataMb = 6.4;
|
|
738
668
|
const iosInstallMb = Number((releaseJsMb + nativeFrameworksMb + nativeMachoMb + assetsCatalogMb + metadataMb).toFixed(1));
|
|
739
|
-
// iOS .ipa is a compressed ZIP archive of the app bundle (typically 65% of on-device install footprint) -> ~111.9 MB
|
|
740
669
|
const iosDownloadMb = Number((iosInstallMb * 0.655).toFixed(1));
|
|
741
|
-
// ─── 2. Android Google Play App Bundle (.aab / dynamic split delivery) ───
|
|
742
670
|
const androidCppMb = Number((20.0 + effectiveNativePkgCount * 0.12 + nodeModulesMb * 0.4).toFixed(1));
|
|
743
671
|
const androidDexMb = Number((14.0 + effectiveNativePkgCount * 0.08 + nodeModulesMb * 0.25).toFixed(1));
|
|
744
672
|
const androidResMb = Number((16.0 + assetsMediaMb * 1.5).toFixed(1));
|
|
745
673
|
const androidInstallMb = Number((releaseJsMb + androidCppMb + androidDexMb + androidResMb + 3.8).toFixed(1));
|
|
746
674
|
const androidDownloadMb = Number((androidInstallMb * 0.54).toFixed(1));
|
|
747
|
-
// ─── 3. Universal Standalone FAT APK (.apk) ───────────────────────────────
|
|
748
|
-
// Multi-ABI FAT APK bundling 4 distinct native architectures (arm64-v8a + armeabi-v7a + x86_64 + x86)
|
|
749
|
-
// Base multi-ABI engine C++ libraries (libhermes.so, libreactnativejni.so, libfbjni.so, libc++_shared.so) ~195 MB
|
|
750
675
|
const androidMultiAbiCppMb = Number((195.0 + effectiveNativePkgCount * 0.55 + nodeModulesMb * 1.6).toFixed(1));
|
|
751
676
|
const androidApkDexMb = Number((54.0 + effectiveNativePkgCount * 0.2 + nodeModulesMb * 0.6).toFixed(1));
|
|
752
677
|
const androidApkResMb = Number((58.0 + assetsMediaMb * 2.8).toFixed(1));
|
|
@@ -971,20 +896,14 @@ export const parseBundleSource = (bundleText, totalBytes, scriptURL, isLive = tr
|
|
|
971
896
|
},
|
|
972
897
|
};
|
|
973
898
|
};
|
|
974
|
-
/**
|
|
975
|
-
* Returns an instant baseline bundle analysis synchronously (never blocks UI).
|
|
976
|
-
*/
|
|
977
899
|
export const getInitialBundleAnalysis = () => {
|
|
978
900
|
if (cachedAnalysis)
|
|
979
901
|
return cachedAnalysis;
|
|
980
902
|
const scriptURL = getHostScriptURL();
|
|
981
|
-
const fallbackBytes = 6840000;
|
|
903
|
+
const fallbackBytes = 6840000;
|
|
982
904
|
const result = parseBundleSource('', fallbackBytes, scriptURL || 'unknown', false);
|
|
983
905
|
return result;
|
|
984
906
|
};
|
|
985
|
-
/**
|
|
986
|
-
* Asynchronously fetch and analyze the running Metro bundle in the background.
|
|
987
|
-
*/
|
|
988
907
|
export const analyzeHostAppBundle = async (forceRefresh = false) => {
|
|
989
908
|
if (forceRefresh) {
|
|
990
909
|
cachedAnalysis = null;
|
|
@@ -1010,9 +929,7 @@ export const analyzeHostAppBundle = async (forceRefresh = false) => {
|
|
|
1010
929
|
}
|
|
1011
930
|
}
|
|
1012
931
|
catch {
|
|
1013
|
-
// Silent catch
|
|
1014
932
|
}
|
|
1015
|
-
// Fallback: could not reach a Metro dev server (offline, device on different network, or release build).
|
|
1016
933
|
const fallbackBytes = 6840000;
|
|
1017
934
|
const result = parseBundleSource('', fallbackBytes, scriptURL || 'unknown', false);
|
|
1018
935
|
cachedAnalysis = result;
|