react-native-inapp-inspector 1.1.23 → 1.1.25

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/dist/commonjs/components/AnalyticsEventCard.js +94 -88
  2. package/dist/commonjs/components/ConsoleLogCard.js +49 -25
  3. package/dist/commonjs/components/Inspector/AnalyticsFilterModal.d.ts +7 -0
  4. package/dist/commonjs/components/Inspector/AnalyticsFilterModal.js +1002 -0
  5. package/dist/commonjs/components/Inspector/AnalyticsTab.js +637 -10
  6. package/dist/commonjs/components/Inspector/BundleTab.d.ts +1 -1
  7. package/dist/commonjs/components/Inspector/BundleTab.js +859 -402
  8. package/dist/commonjs/components/Inspector/InspectorContext.js +6 -1
  9. package/dist/commonjs/components/Inspector/InspectorHeader.js +13 -5
  10. package/dist/commonjs/components/Inspector/LogDetail.js +223 -111
  11. package/dist/commonjs/components/Inspector/MainScreen.js +1 -1
  12. package/dist/commonjs/components/Inspector/NetworkDetail.js +131 -81
  13. package/dist/commonjs/components/Inspector/PerformanceTab.js +20 -10
  14. package/dist/commonjs/components/NetworkIcons.d.ts +14 -0
  15. package/dist/commonjs/components/NetworkIcons.js +93 -1
  16. package/dist/commonjs/components/SegmentedTabs.js +31 -22
  17. package/dist/commonjs/components/TreeNode.js +13 -12
  18. package/dist/commonjs/constants/version.d.ts +1 -1
  19. package/dist/commonjs/constants/version.js +1 -1
  20. package/dist/commonjs/customHooks/bundleAnalyzer.d.ts +6 -2
  21. package/dist/commonjs/customHooks/bundleAnalyzer.js +552 -114
  22. package/dist/commonjs/customHooks/consoleLogger.js +83 -45
  23. package/dist/commonjs/customHooks/networkLogger.js +10 -1
  24. package/dist/commonjs/customHooks/performanceTracker.d.ts +8 -0
  25. package/dist/commonjs/customHooks/performanceTracker.js +44 -3
  26. package/dist/commonjs/decorators/index.d.ts +49 -0
  27. package/dist/commonjs/decorators/index.js +142 -0
  28. package/dist/commonjs/helpers/gaAnalyticsRegistry.d.ts +18 -0
  29. package/dist/commonjs/helpers/gaAnalyticsRegistry.js +174 -0
  30. package/dist/commonjs/helpers/index.d.ts +7 -4
  31. package/dist/commonjs/helpers/index.js +102 -64
  32. package/dist/commonjs/i18n/locales/en.json +53 -4
  33. package/dist/commonjs/index.d.ts +4 -0
  34. package/dist/commonjs/index.js +216 -8
  35. package/dist/commonjs/styles/index.d.ts +4 -1
  36. package/dist/commonjs/styles/index.js +22 -19
  37. package/dist/commonjs/types/enums.d.ts +115 -9
  38. package/dist/commonjs/types/enums.js +103 -2
  39. package/dist/commonjs/types/interfaces.d.ts +19 -0
  40. package/dist/esm/components/AnalyticsEventCard.js +95 -89
  41. package/dist/esm/components/ConsoleLogCard.js +49 -25
  42. package/dist/esm/components/Inspector/AnalyticsFilterModal.d.ts +7 -0
  43. package/dist/esm/components/Inspector/AnalyticsFilterModal.js +964 -0
  44. package/dist/esm/components/Inspector/AnalyticsTab.js +639 -12
  45. package/dist/esm/components/Inspector/BundleTab.d.ts +1 -1
  46. package/dist/esm/components/Inspector/BundleTab.js +860 -403
  47. package/dist/esm/components/Inspector/InspectorContext.js +1 -0
  48. package/dist/esm/components/Inspector/InspectorHeader.js +14 -6
  49. package/dist/esm/components/Inspector/LogDetail.js +223 -111
  50. package/dist/esm/components/Inspector/MainScreen.js +2 -2
  51. package/dist/esm/components/Inspector/NetworkDetail.js +132 -49
  52. package/dist/esm/components/Inspector/PerformanceTab.js +20 -10
  53. package/dist/esm/components/NetworkIcons.d.ts +14 -0
  54. package/dist/esm/components/NetworkIcons.js +78 -0
  55. package/dist/esm/components/SegmentedTabs.js +31 -22
  56. package/dist/esm/components/TreeNode.js +13 -12
  57. package/dist/esm/constants/version.d.ts +1 -1
  58. package/dist/esm/constants/version.js +1 -1
  59. package/dist/esm/customHooks/bundleAnalyzer.d.ts +6 -2
  60. package/dist/esm/customHooks/bundleAnalyzer.js +549 -114
  61. package/dist/esm/customHooks/consoleLogger.js +83 -45
  62. package/dist/esm/customHooks/networkLogger.js +10 -1
  63. package/dist/esm/customHooks/performanceTracker.d.ts +8 -0
  64. package/dist/esm/customHooks/performanceTracker.js +38 -1
  65. package/dist/esm/decorators/index.d.ts +49 -0
  66. package/dist/esm/decorators/index.js +137 -0
  67. package/dist/esm/helpers/gaAnalyticsRegistry.d.ts +18 -0
  68. package/dist/esm/helpers/gaAnalyticsRegistry.js +169 -0
  69. package/dist/esm/helpers/index.d.ts +7 -4
  70. package/dist/esm/helpers/index.js +100 -63
  71. package/dist/esm/i18n/locales/en.json +53 -4
  72. package/dist/esm/index.d.ts +4 -0
  73. package/dist/esm/index.js +190 -8
  74. package/dist/esm/styles/index.d.ts +4 -1
  75. package/dist/esm/styles/index.js +22 -19
  76. package/dist/esm/types/enums.d.ts +115 -9
  77. package/dist/esm/types/enums.js +102 -3
  78. package/dist/esm/types/interfaces.d.ts +19 -0
  79. package/package.json +1 -1
@@ -1,4 +1,4 @@
1
- import { NetworkLog, RouteInfo, DiffResult, JsonContent } from '../types';
1
+ import { NetworkLog, RouteInfo, DiffResult, JsonContent, StackFrameType } from '../types';
2
2
  export declare const getDomainColor: (domain: string) => string;
3
3
  export declare const formatDateTime: (timestamp: number) => string;
4
4
  export declare const getStatusColor: (status: number | null) => string;
@@ -40,17 +40,20 @@ export interface ParsedStackFrame {
40
40
  functionName: string;
41
41
  fileName: string;
42
42
  fullPath: string;
43
- fileExt?: 'tsx' | 'jsx' | 'ts' | 'js' | 'other';
44
- isUserCode?: boolean;
43
+ fileExt: string;
44
+ frameType: StackFrameType | 'app' | 'dependency' | 'runtime' | 'native';
45
+ isUserCode: boolean;
46
+ isRuntimeNoise: boolean;
45
47
  lineNumber?: string;
46
48
  columnNumber?: string;
47
49
  isOrigin?: boolean;
50
+ copyableLocation: string;
48
51
  }
49
52
  /** Parses a stack trace line to extract function name, file name, extension (.tsx/.jsx/.ts), line, and column numbers */
50
53
  export declare const parseStackLine: (rawLine: string, isOrigin?: boolean) => ParsedStackFrame;
51
54
  export declare const ANALYTICS_EVENT_PALETTE: string[];
52
55
  export declare const getEventColor: (name: string) => string;
53
- export declare const getEventCategory: (name: string) => "page_view" | "ecommerce" | "system" | "custom";
56
+ export { getEventCategory, registerGAPlugin, type GAEventCategory, type GAPlugin, } from './gaAnalyticsRegistry';
54
57
  export declare const getCategoryColors: (category: string) => {
55
58
  bg: string;
56
59
  border: string;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getRuntimeDiagnostics = exports.getCategoryColors = exports.getEventCategory = exports.getEventColor = exports.ANALYTICS_EVENT_PALETTE = exports.parseStackLine = exports.getJsonPreviewText = exports.getJsonContent = exports.formatGap = exports.formatTime = exports.formatTimeShort = exports.handleOpenExternalLink = exports.getAppName = exports.getBundleIdentifier = exports.formatDateTimeToAnalytics = exports.isAllValuesEmpty = exports.getLocalizedFilePathWithSlash = exports.getLocalizedFilePath = exports.formatDisplayUrl = exports.getDiff = exports.flattenObject = exports.getNavigationInfo = exports.escapeRegex = exports.deduplicateLogs = exports.getFetchCommand = exports.getCurlCommand = exports.getBaseUrl = exports.getPath = exports.copyToClipboard = exports.getSize = exports.getDurationColor = exports.getStatusColor = exports.formatDateTime = exports.getDomainColor = void 0;
3
+ exports.getRuntimeDiagnostics = exports.getCategoryColors = exports.registerGAPlugin = exports.getEventCategory = exports.getEventColor = exports.ANALYTICS_EVENT_PALETTE = exports.parseStackLine = exports.getJsonPreviewText = exports.getJsonContent = exports.formatGap = exports.formatTime = exports.formatTimeShort = exports.handleOpenExternalLink = exports.getAppName = exports.getBundleIdentifier = exports.formatDateTimeToAnalytics = exports.isAllValuesEmpty = exports.getLocalizedFilePathWithSlash = exports.getLocalizedFilePath = exports.formatDisplayUrl = exports.getDiff = exports.flattenObject = exports.getNavigationInfo = exports.escapeRegex = exports.deduplicateLogs = exports.getFetchCommand = exports.getCurlCommand = exports.getBaseUrl = exports.getPath = exports.copyToClipboard = exports.getSize = exports.getDurationColor = exports.getStatusColor = exports.formatDateTime = exports.getDomainColor = void 0;
4
4
  const react_native_1 = require("react-native");
5
5
  // Stylesheet
6
6
  const AppColors_1 = require("../styles/AppColors");
@@ -60,58 +60,83 @@ const getSize = (data) => {
60
60
  }
61
61
  };
62
62
  exports.getSize = getSize;
63
- // Try loading community clipboard or native clipboard modules with graceful fallbacks
63
+ // Safely detect and load clipboard natively without static require() calls that Metro fails on
64
64
  const getClipboardModule = () => {
65
+ // 1. Check TurboModuleRegistry (TurboModules / New Architecture)
65
66
  try {
66
- // @ts-ignore
67
- const community = require('@react-native-clipboard/clipboard');
68
- if (community?.default?.setString)
69
- return community.default;
70
- if (community?.setString)
71
- return community;
67
+ const tmReg = react_native_1.TurboModuleRegistry || globalThis.__turboModuleProxy;
68
+ if (tmReg?.get) {
69
+ const tm = tmReg.get('RNCClipboard') ||
70
+ tmReg.get('NativeClipboard') ||
71
+ tmReg.get('ExpoClipboard');
72
+ if (tm &&
73
+ (typeof tm.setString === 'function' ||
74
+ typeof tm.setStringAsync === 'function')) {
75
+ return tm;
76
+ }
77
+ }
72
78
  }
73
79
  catch { }
80
+ // 2. Check legacy NativeModules table (Bridge / Old Architecture)
74
81
  try {
75
- // @ts-ignore
76
- const oldCommunity = require('@react-native-community/clipboard');
77
- if (oldCommunity?.default?.setString)
78
- return oldCommunity.default;
79
- if (oldCommunity?.setString)
80
- return oldCommunity;
82
+ if (react_native_1.NativeModules?.RNCClipboard &&
83
+ typeof react_native_1.NativeModules.RNCClipboard.setString === 'function') {
84
+ return react_native_1.NativeModules.RNCClipboard;
85
+ }
86
+ if (react_native_1.NativeModules?.ExpoClipboard &&
87
+ typeof react_native_1.NativeModules.ExpoClipboard.setStringAsync === 'function') {
88
+ return react_native_1.NativeModules.ExpoClipboard;
89
+ }
90
+ if (react_native_1.NativeModules?.Clipboard &&
91
+ typeof react_native_1.NativeModules.Clipboard.setString === 'function') {
92
+ return react_native_1.NativeModules.Clipboard;
93
+ }
81
94
  }
82
95
  catch { }
96
+ // 3. Check legacy React Native core Clipboard
83
97
  try {
84
- if (react_native_1.NativeModules?.RNCClipboard?.setString)
85
- return react_native_1.NativeModules.RNCClipboard;
98
+ if (react_native_1.Clipboard && typeof react_native_1.Clipboard.setString === 'function') {
99
+ return react_native_1.Clipboard;
100
+ }
86
101
  }
87
102
  catch { }
88
- return react_native_1.Clipboard;
103
+ return null;
89
104
  };
90
105
  const copyToClipboard = (value, label) => {
91
106
  const resolved = typeof value === 'function' ? value() : value;
92
107
  const text = typeof resolved === 'string' ? resolved : JSON.stringify(resolved, null, 2);
93
108
  const textToCopy = text ?? '';
109
+ let copied = false;
94
110
  try {
95
111
  const cb = getClipboardModule();
96
- if (cb && typeof cb.setString === 'function') {
97
- cb.setString(textToCopy);
98
- }
99
- else {
100
- react_native_1.Clipboard.setString(textToCopy);
112
+ if (cb) {
113
+ if (typeof cb.setStringAsync === 'function') {
114
+ cb.setStringAsync(textToCopy);
115
+ copied = true;
116
+ }
117
+ else if (typeof cb.setString === 'function') {
118
+ cb.setString(textToCopy);
119
+ copied = true;
120
+ }
101
121
  }
102
122
  }
103
- catch {
123
+ catch { }
124
+ if (!copied) {
104
125
  try {
105
- react_native_1.Clipboard.setString(textToCopy);
126
+ if (typeof navigator !== 'undefined' && navigator?.clipboard?.writeText) {
127
+ navigator.clipboard.writeText(textToCopy);
128
+ copied = true;
129
+ }
106
130
  }
107
131
  catch { }
108
132
  }
109
- if (react_native_1.Platform.OS === 'android') {
110
- react_native_1.ToastAndroid.show(`${label} copied`, react_native_1.ToastAndroid.SHORT);
111
- }
112
- else {
113
- react_native_1.Alert.alert('Copied', `${label} copied to clipboard`, [{ text: 'OK' }]);
133
+ // Visual toast feedback on Android if ToastAndroid exists
134
+ try {
135
+ if (react_native_1.Platform.OS === 'android' && react_native_1.ToastAndroid?.show) {
136
+ react_native_1.ToastAndroid.show(`${label} copied`, react_native_1.ToastAndroid.SHORT);
137
+ }
114
138
  }
139
+ catch { }
115
140
  };
116
141
  exports.copyToClipboard = copyToClipboard;
117
142
  const getPath = (url) => {
@@ -476,6 +501,10 @@ const parseStackLine = (rawLine, isOrigin = false) => {
476
501
  functionName = parenMatch[1].trim() || '<anonymous>';
477
502
  locationPart = parenMatch[2].trim();
478
503
  }
504
+ // Clean Babel/Hermes artifacts in function names like ?anon_0_, _callee$, etc.
505
+ if (functionName.startsWith('?anon_') || functionName === '?') {
506
+ functionName = 'anonymous';
507
+ }
479
508
  // Remove "address at " prefix if present in Hermes
480
509
  locationPart = locationPart.replace(/^address at /, '');
481
510
  // Extract file, line, and col from locationPart (e.g. "path/to/file.tsx:42:15" or "http://...:42:15")
@@ -503,20 +532,56 @@ const parseStackLine = (rawLine, isOrigin = false) => {
503
532
  const fileExt = ext === 'tsx' || ext === 'jsx' || ext === 'ts' || ext === 'js'
504
533
  ? ext
505
534
  : 'other';
506
- const isUserCode = !cleanPath.includes('node_modules') &&
507
- !cleanPath.includes('react-native/') &&
508
- !cleanPath.includes('react-native-inapp-inspector') &&
509
- (fileExt === 'tsx' || fileExt === 'jsx' || fileExt === 'ts' || fileExt === 'js');
535
+ const isNative = locationPart === 'native' || cleanPath === 'native';
536
+ const isInternalBytecode = cleanPath.includes('InternalBytecode') ||
537
+ cleanPath.includes('metro-runtime') ||
538
+ cleanPath.includes('regenerator-runtime') ||
539
+ functionName === 'tryCallOne' ||
540
+ functionName === 'asyncGeneratorStep' ||
541
+ functionName === '_next' ||
542
+ (functionName === 'next' && isNative);
543
+ const isDependency = cleanPath.includes('node_modules') ||
544
+ cleanPath.includes('react-native/Libraries') ||
545
+ (cleanPath.includes('react-native-inapp-inspector') && !cleanPath.includes('/example/'));
546
+ const isUserCode = !isNative &&
547
+ !isInternalBytecode &&
548
+ !isDependency &&
549
+ (fileExt === 'tsx' || fileExt === 'jsx' || fileExt === 'ts' || fileExt === 'js' || !fileName.includes('.bundle'));
550
+ const frameType = isUserCode
551
+ ? 'app'
552
+ : isDependency
553
+ ? 'dependency'
554
+ : isNative
555
+ ? 'native'
556
+ : 'runtime';
557
+ const isRuntimeNoise = isInternalBytecode || isNative || functionName === 'asyncGeneratorStep' || functionName === '_next';
558
+ // Format clean relative project path
559
+ let relativePath = cleanPath;
560
+ if (relativePath.includes('/example/')) {
561
+ relativePath = relativePath.substring(relativePath.indexOf('/example/') + 9);
562
+ }
563
+ else if (relativePath.includes('/src/')) {
564
+ relativePath = relativePath.substring(relativePath.indexOf('/src/') + 1);
565
+ }
566
+ else if (relativePath.includes('/node_modules/')) {
567
+ relativePath = relativePath.substring(relativePath.indexOf('/node_modules/') + 14);
568
+ }
569
+ const copyableLocation = lineNumber
570
+ ? `${fileName}:${lineNumber}${columnNumber ? `:${columnNumber}` : ''}`
571
+ : fileName;
510
572
  return {
511
573
  raw: rawLine,
512
574
  functionName,
513
575
  fileName,
514
- fullPath: cleanPath,
576
+ fullPath: relativePath,
515
577
  fileExt,
578
+ frameType,
516
579
  isUserCode,
580
+ isRuntimeNoise,
517
581
  lineNumber,
518
582
  columnNumber,
519
583
  isOrigin,
584
+ copyableLocation,
520
585
  };
521
586
  };
522
587
  exports.parseStackLine = parseStackLine;
@@ -540,36 +605,9 @@ const getEventColor = (name) => {
540
605
  return exports.ANALYTICS_EVENT_PALETTE[Math.abs(hash) % exports.ANALYTICS_EVENT_PALETTE.length];
541
606
  };
542
607
  exports.getEventColor = getEventColor;
543
- const getEventCategory = (name) => {
544
- if (!name)
545
- return 'custom';
546
- const lowercaseName = name.toLowerCase();
547
- if (lowercaseName === 'screen_view' || lowercaseName === 'page_view') {
548
- return 'page_view';
549
- }
550
- // Ecommerce events
551
- const ecommerceEvents = [
552
- 'purchase', 'add_to_cart', 'begin_checkout', 'view_item',
553
- 'select_item', 'remove_from_cart', 'view_cart',
554
- 'add_shipping_info', 'add_payment_info', 'refund',
555
- 'view_item_list', 'select_promotion', 'view_promotion'
556
- ];
557
- if (ecommerceEvents.includes(lowercaseName)) {
558
- return 'ecommerce';
559
- }
560
- // Firebase System Auto-events
561
- const systemEvents = [
562
- 'first_open', 'session_start', 'user_engagement',
563
- 'app_clear_data', 'app_exception', 'app_update', 'os_update',
564
- 'notification_receive', 'notification_open', 'notification_dismiss',
565
- 'screen_active', 'screen_inactive'
566
- ];
567
- if (systemEvents.includes(lowercaseName) || lowercaseName.startsWith('firebase_') || lowercaseName.startsWith('_')) {
568
- return 'system';
569
- }
570
- return 'custom';
571
- };
572
- exports.getEventCategory = getEventCategory;
608
+ var gaAnalyticsRegistry_1 = require("./gaAnalyticsRegistry");
609
+ Object.defineProperty(exports, "getEventCategory", { enumerable: true, get: function () { return gaAnalyticsRegistry_1.getEventCategory; } });
610
+ Object.defineProperty(exports, "registerGAPlugin", { enumerable: true, get: function () { return gaAnalyticsRegistry_1.registerGAPlugin; } });
573
611
  const getCategoryColors = (category) => {
574
612
  switch (category) {
575
613
  case 'page_view':
@@ -211,7 +211,29 @@
211
211
  "filterWarn": "Warn",
212
212
  "filterError": "Error",
213
213
  "filterUserLog": "User Log",
214
- "filterAnalytics": "Analytics"
214
+ "filterAnalytics": "Analytics",
215
+ "tabOutput": "Output",
216
+ "tabArgs": "Args ({{count}})",
217
+ "tabStack": "Stack Trace",
218
+ "tabMetadata": "Metadata",
219
+ "callStack": "Call Stack ({{count}} frames)",
220
+ "errorStack": "Error Exception Stack ({{count}} frames)",
221
+ "callOriginStack": "Call Origin Stack",
222
+ "errorThrownStack": "Error Thrown Stack",
223
+ "appCodeScope": "🎯 App Code ({{count}})",
224
+ "allFramesScope": "📜 All Frames ({{count}})",
225
+ "cardsView": "Cards",
226
+ "rawTraceView": "Raw",
227
+ "noStackAvailable": "No call stack frames found matching the active filter.",
228
+ "originBadge": "#1 ORIGIN",
229
+ "appCodeBadge": "App Code",
230
+ "dependencyBadge": "Dependency",
231
+ "nativeBadge": "Native",
232
+ "hermesVmBadge": "Hermes VM",
233
+ "fullStackTrace": "Full Stack Trace",
234
+ "lineCol": "Line {{line}}, Col {{col}}",
235
+ "lineColShort": "L{{line}}:C{{col}}",
236
+ "searchInLogDetails": "Search in log details..."
215
237
  },
216
238
  "analytics": {
217
239
  "title": "Analytics",
@@ -355,6 +377,8 @@
355
377
  "heroTitle": "Bundle & Asset Architecture",
356
378
  "heroSubtitle": "Real-time size breakdown across all assets, code, and dependencies",
357
379
  "heroSubtitleLive": "Live analysis of {{scriptUrl}}",
380
+ "liveAnalysisUnavailable": "Live bundle analysis unavailable",
381
+ "liveAnalysisUnavailableSub": "Could not reach the Metro dev server, so values are estimates. Make sure the app runs in development via `npx react-native start` and the Inspector can reach your Metro port (8081, 8082, ...).",
358
382
  "bundleOverviewJson": "Bundle Overview JSON",
359
383
  "devBundleSize": "DEV BUNDLE SIZE",
360
384
  "devBundleHint": "{{kb}} KB • {{modules}} modules",
@@ -396,11 +420,36 @@
396
420
  "catTsDesc": "App screen components, hooks, and business logic",
397
421
  "catJsonTitle": "JSON Data & Localizations",
398
422
  "catJsonDesc": "i18n translation dictionaries and static configs",
399
- "catRowSub": "{{count}} items • {{desc}}",
400
- "totalBundleAssets": "TOTAL BUNDLE ASSETS",
423
+ "totalBundleAssets": "TOTAL HOST PROJECT FILES",
401
424
  "totalBundleValue": "{{kb}} KB (~{{mb}} MB)",
402
- "totalFormula": "Sum: {{images}} KB + {{js}} KB + {{fonts}} KB + {{ts}} KB + {{json}} KB = {{total}} KB ({{count}} items • 100%)",
425
+ "totalFormula": "Sum of host source files: {{images}} KB + {{js}} KB + {{fonts}} KB + {{ts}} KB + {{json}} KB = {{total}} KB ({{count}} items)",
426
+ "prodIosApp": "iOS App (.ipa)",
427
+ "prodAndroidAab": "Android AAB (.aab)",
428
+ "prodAndroidApk": "Universal APK (.apk)",
429
+ "prodHeroTitleIos": "iOS Production Binary Footprint",
430
+ "prodHeroTitleAab": "Google Play App Bundle (.aab)",
431
+ "prodHeroTitleApk": "Universal Standalone APK (.apk)",
432
+ "prodHeroSubIos": "App Store install & over-the-air cellular download estimates",
433
+ "prodHeroSubAab": "Optimized per-device dynamic delivery split APK architecture",
434
+ "prodHeroSubApk": "Multi-ABI universal install archive for sideloading & direct distribution",
435
+ "prodInstallSize": "INSTALL SIZE",
436
+ "prodInstallHint": "On-device uncompressed footprint",
437
+ "prodDownloadSize": "DOWNLOAD SIZE",
438
+ "prodDownloadHint": "Store network transfer payload",
439
+ "prodCompression": "COMPRESSION",
440
+ "prodCompressionHint": "Bytecode & asset ratio",
441
+ "prodFormatArch": "FORMAT ARCHITECTURE",
442
+ "prodFormatHintIos": "Apple ARM64 runtime",
443
+ "prodFormatHintAab": "Dynamic Google Play delivery",
444
+ "prodFormatHintApk": "Sideload universal package",
445
+ "prodArchTitle": "Binary Component Architecture",
446
+ "prodArchSub": "Compiled native libraries, runtime bytecodes, assets, and signature blocks",
447
+ "prodTotalIos": "TOTAL IOS APP BINARY",
448
+ "prodTotalAab": "TOTAL ANDROID AAB BUNDLE",
449
+ "prodTotalApk": "TOTAL UNIVERSAL APK",
450
+ "prodTotalFormula": "From {{devKb}} KB (~{{devMb}} MB • {{count}} total assets) dev source bundle → {{installMb}} MB optimized native binary ({{pct}}% bytecode/asset compression).",
403
451
  "tabOverview": "Overview",
452
+ "tabProduction": "Production ({{count}})",
404
453
  "tabFiles": "Files ({{count}})",
405
454
  "tabPackages": "Packages ({{count}})",
406
455
  "tabMedia": "Media ({{count}})",
@@ -7,3 +7,7 @@ export { setupConsoleLogger, clearConsoleLogs, subscribeConsoleLogs, } from './c
7
7
  export { setupAnalyticsLogger, logAnalyticsEvent, subscribeAnalyticsEvents, clearAnalyticsEvents, getCurrentUserProperties, getCurrentUserId, getDefaultEventParameters, getCollectionEnabled, } from './customHooks/analyticsLogger';
8
8
  export { default as ErrorBoundary } from './components/ErrorBoundary';
9
9
  export { connectReduxStore, inspectorReduxMiddleware, getReduxState, subscribeReduxState, getActionHistory, clearActionHistory, getLastActionForReducer, } from './customHooks/reduxLogger';
10
+ export { getEventCategory, registerGAPlugin, type GAPlugin, } from './helpers/gaAnalyticsRegistry';
11
+ export { usePerformanceTracker, logPerformanceEvent, clearPerformanceEvents, subscribePerformanceEvents, getPerformanceEvents, } from './customHooks/performanceTracker';
12
+ export { InspectLog, InspectTrackTime, InspectCatch, type InspectLogOptions, } from './decorators';
13
+ export { ActiveTab, Method, StatusFilter, SortOrder, LocalFilter, ModalAnimationType, SettingsPage, SettingsSubTab, LogFilter, ConsoleLogType, AnalyticsEventSource, GAEventCategory, StackFrameType, DiffResultType, BundleSubTab, PerformanceSubTab, } from './types';
@@ -36,7 +36,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
36
36
  return (mod && mod.__esModule) ? mod : { "default": mod };
37
37
  };
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
- exports.getLastActionForReducer = exports.clearActionHistory = exports.getActionHistory = exports.subscribeReduxState = exports.getReduxState = exports.inspectorReduxMiddleware = exports.connectReduxStore = exports.ErrorBoundary = exports.getCollectionEnabled = exports.getDefaultEventParameters = exports.getCurrentUserId = exports.getCurrentUserProperties = exports.clearAnalyticsEvents = exports.subscribeAnalyticsEvents = exports.logAnalyticsEvent = exports.setupAnalyticsLogger = exports.subscribeConsoleLogs = exports.clearConsoleLogs = exports.setupConsoleLogger = exports.addAxiosInterceptors = exports.subscribeNetworkLogs = exports.clearNetworkLogs = exports.setupNetworkLogger = void 0;
39
+ exports.PerformanceSubTab = exports.BundleSubTab = exports.DiffResultType = exports.StackFrameType = exports.GAEventCategory = exports.AnalyticsEventSource = exports.ConsoleLogType = exports.LogFilter = exports.SettingsSubTab = exports.SettingsPage = exports.ModalAnimationType = exports.LocalFilter = exports.SortOrder = exports.StatusFilter = exports.Method = exports.ActiveTab = exports.InspectCatch = exports.InspectTrackTime = exports.InspectLog = exports.getPerformanceEvents = exports.subscribePerformanceEvents = exports.clearPerformanceEvents = exports.logPerformanceEvent = exports.usePerformanceTracker = exports.registerGAPlugin = exports.getEventCategory = exports.getLastActionForReducer = exports.clearActionHistory = exports.getActionHistory = exports.subscribeReduxState = exports.getReduxState = exports.inspectorReduxMiddleware = exports.connectReduxStore = exports.ErrorBoundary = exports.getCollectionEnabled = exports.getDefaultEventParameters = exports.getCurrentUserId = exports.getCurrentUserProperties = exports.clearAnalyticsEvents = exports.subscribeAnalyticsEvents = exports.logAnalyticsEvent = exports.setupAnalyticsLogger = exports.subscribeConsoleLogs = exports.clearConsoleLogs = exports.setupConsoleLogger = exports.addAxiosInterceptors = exports.subscribeNetworkLogs = exports.clearNetworkLogs = exports.setupNetworkLogger = void 0;
40
40
  const react_1 = __importStar(require("react"));
41
41
  const react_native_1 = require("react-native");
42
42
  const native_1 = require("@react-navigation/native");
@@ -371,7 +371,67 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
371
371
  }, []);
372
372
  const [selectedEvent, setSelectedEvent] = (0, react_1.useState)(null);
373
373
  const [analyticsSearch, setAnalyticsSearch] = (0, react_1.useState)('');
374
- const [hideScreenView] = (0, react_1.useState)(true);
374
+ const [analyticsFilters, setAnalyticsFilters] = (0, react_1.useState)({
375
+ categories: new Set(['all']),
376
+ screens: new Set(),
377
+ sources: new Set(['all']),
378
+ userTypes: new Set(['all']),
379
+ timeWindow: 'all',
380
+ payloadComplexity: 'all',
381
+ hasRevenue: false,
382
+ hasItems: false,
383
+ hasUserProps: false,
384
+ hasParams: false,
385
+ onlyDuplicates: false,
386
+ onlyConversions: false,
387
+ sortBy: 'time_desc',
388
+ });
389
+ const isAnalyticsFilterApplied = (0, react_1.useMemo)(() => {
390
+ if (analyticsFilters.categories.size > 0 && !analyticsFilters.categories.has('all'))
391
+ return true;
392
+ if (analyticsFilters.screens.size > 0)
393
+ return true;
394
+ if (analyticsFilters.sources.size > 0 && !analyticsFilters.sources.has('all'))
395
+ return true;
396
+ if (analyticsFilters.userTypes.size > 0 && !analyticsFilters.userTypes.has('all'))
397
+ return true;
398
+ if (analyticsFilters.timeWindow !== 'all')
399
+ return true;
400
+ if (analyticsFilters.payloadComplexity !== 'all')
401
+ return true;
402
+ if (analyticsFilters.hasRevenue)
403
+ return true;
404
+ if (analyticsFilters.hasItems)
405
+ return true;
406
+ if (analyticsFilters.hasUserProps)
407
+ return true;
408
+ if (analyticsFilters.hasParams)
409
+ return true;
410
+ if (analyticsFilters.onlyDuplicates)
411
+ return true;
412
+ if (analyticsFilters.onlyConversions)
413
+ return true;
414
+ if (analyticsFilters.sortBy !== 'time_desc')
415
+ return true;
416
+ return false;
417
+ }, [analyticsFilters]);
418
+ const resetAnalyticsFilters = (0, react_1.useCallback)(() => {
419
+ setAnalyticsFilters({
420
+ categories: new Set(['all']),
421
+ screens: new Set(),
422
+ sources: new Set(['all']),
423
+ userTypes: new Set(['all']),
424
+ timeWindow: 'all',
425
+ payloadComplexity: 'all',
426
+ hasRevenue: false,
427
+ hasItems: false,
428
+ hasUserProps: false,
429
+ hasParams: false,
430
+ onlyDuplicates: false,
431
+ onlyConversions: false,
432
+ sortBy: 'time_desc',
433
+ });
434
+ }, []);
375
435
  const [isAnalyticsLayoutReady, setIsAnalyticsLayoutReady] = (0, react_1.useState)(false);
376
436
  const [analyticsHeaderExpanded, setAnalyticsHeaderExpanded] = (0, react_1.useState)(false);
377
437
  const [newEventIds, setNewEventIds] = (0, react_1.useState)(new Set());
@@ -905,15 +965,110 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
905
965
  const prevResponseData = prevSameRequest ? prevSameRequest.response : null;
906
966
  const filteredAnalyticsEvents = (0, react_1.useMemo)(() => {
907
967
  let events = analyticsEvents;
908
- if (hideScreenView) {
909
- events = events.filter(e => e.name !== 'screen_view');
910
- }
968
+ // Search query filter
911
969
  if (analyticsSearch) {
912
970
  const s = analyticsSearch.toLowerCase();
913
971
  events = events.filter(e => e.name.toLowerCase().includes(s) ||
914
- JSON.stringify(e.params).toLowerCase().includes(s) ||
972
+ JSON.stringify(e.params || {}).toLowerCase().includes(s) ||
973
+ (e.screenName ?? '').toLowerCase().includes(s) ||
915
974
  (e.pageTitle ?? '').toLowerCase().includes(s));
916
975
  }
976
+ // Category filter
977
+ if (analyticsFilters.categories.size > 0 && !analyticsFilters.categories.has('all')) {
978
+ events = events.filter(e => {
979
+ const cat = (0, helpers_1.getEventCategory)(e.name);
980
+ return analyticsFilters.categories.has(cat);
981
+ });
982
+ }
983
+ // Time window filter
984
+ if (analyticsFilters.timeWindow !== 'all') {
985
+ const now = Date.now();
986
+ const cutoff = analyticsFilters.timeWindow === '1m'
987
+ ? now - 60 * 1000
988
+ : analyticsFilters.timeWindow === '5m'
989
+ ? now - 5 * 60 * 1000
990
+ : analyticsFilters.timeWindow === '15m'
991
+ ? now - 15 * 60 * 1000
992
+ : now - 60 * 60 * 1000;
993
+ events = events.filter(e => e.timestamp >= cutoff);
994
+ }
995
+ // Source filter
996
+ if (analyticsFilters.sources.size > 0 && !analyticsFilters.sources.has('all')) {
997
+ events = events.filter(e => analyticsFilters.sources.has(e.source || 'manual'));
998
+ }
999
+ // User identification filter
1000
+ if (analyticsFilters.userTypes.size > 0 && !analyticsFilters.userTypes.has('all')) {
1001
+ events = events.filter(e => {
1002
+ const isIdentified = Boolean(e.userId && e.userId.trim() !== '');
1003
+ if (analyticsFilters.userTypes.has('identified') && isIdentified)
1004
+ return true;
1005
+ if (analyticsFilters.userTypes.has('anonymous') && !isIdentified)
1006
+ return true;
1007
+ return false;
1008
+ });
1009
+ }
1010
+ // Payload complexity filter
1011
+ if (analyticsFilters.payloadComplexity !== 'all') {
1012
+ events = events.filter(e => {
1013
+ const count = e.params ? Object.keys(e.params).length : 0;
1014
+ if (analyticsFilters.payloadComplexity === 'none')
1015
+ return count === 0;
1016
+ if (analyticsFilters.payloadComplexity === 'simple')
1017
+ return count >= 1 && count <= 5;
1018
+ if (analyticsFilters.payloadComplexity === 'heavy')
1019
+ return count > 5;
1020
+ return true;
1021
+ });
1022
+ }
1023
+ // Conversion / Goal events filter
1024
+ if (analyticsFilters.onlyConversions) {
1025
+ const CONVERSION_PATTERNS = [
1026
+ 'purchase',
1027
+ 'item_purchase',
1028
+ 'ecommerce_purchase',
1029
+ 'sign_up',
1030
+ 'login',
1031
+ 'lead',
1032
+ 'generate_lead',
1033
+ 'tutorial_complete',
1034
+ 'add_payment_info',
1035
+ 'begin_checkout',
1036
+ 'spend_virtual_currency',
1037
+ ];
1038
+ events = events.filter(e => CONVERSION_PATTERNS.some(pat => e.name.toLowerCase().includes(pat)));
1039
+ }
1040
+ // Screen filter
1041
+ if (analyticsFilters.screens.size > 0) {
1042
+ events = events.filter(e => {
1043
+ const scr = e.screenName ||
1044
+ e.params?.firebase_screen ||
1045
+ e.params?.screen_name ||
1046
+ e.params?.firebase_screen_class ||
1047
+ e.screenClass ||
1048
+ '';
1049
+ return analyticsFilters.screens.has(scr);
1050
+ });
1051
+ }
1052
+ // Has Revenue filter
1053
+ if (analyticsFilters.hasRevenue) {
1054
+ events = events.filter(e => {
1055
+ const val = e.params?.value ?? e.params?.price;
1056
+ return val !== undefined && val !== null && Number(val) > 0;
1057
+ });
1058
+ }
1059
+ // Has Items filter
1060
+ if (analyticsFilters.hasItems) {
1061
+ events = events.filter(e => Array.isArray(e.params?.items) && e.params.items.length > 0);
1062
+ }
1063
+ // Has User Props filter
1064
+ if (analyticsFilters.hasUserProps) {
1065
+ events = events.filter(e => e.userProperties && Object.keys(e.userProperties).length > 0);
1066
+ }
1067
+ // Has Params filter
1068
+ if (analyticsFilters.hasParams) {
1069
+ events = events.filter(e => e.params && Object.keys(e.params).length > 0);
1070
+ }
1071
+ // Deduplication
917
1072
  const deduplicatedEvents = [];
918
1073
  for (const e of events) {
919
1074
  if (deduplicatedEvents.length === 0) {
@@ -933,8 +1088,27 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
933
1088
  deduplicatedEvents.push({ ...e, count: 1 });
934
1089
  }
935
1090
  }
936
- return deduplicatedEvents;
937
- }, [analyticsEvents, analyticsSearch, hideScreenView]);
1091
+ let result = deduplicatedEvents;
1092
+ // Only duplicates filter
1093
+ if (analyticsFilters.onlyDuplicates) {
1094
+ result = result.filter(e => (e.count || 1) > 1);
1095
+ }
1096
+ // Sorting
1097
+ if (analyticsFilters.sortBy === 'time_asc') {
1098
+ result = [...result].sort((a, b) => a.timestamp - b.timestamp);
1099
+ }
1100
+ else if (analyticsFilters.sortBy === 'revenue_desc') {
1101
+ result = [...result].sort((a, b) => {
1102
+ const valA = Number(a.params?.value ?? a.params?.price ?? 0);
1103
+ const valB = Number(b.params?.value ?? b.params?.price ?? 0);
1104
+ return valB - valA;
1105
+ });
1106
+ }
1107
+ else if (analyticsFilters.sortBy === 'count_desc') {
1108
+ result = [...result].sort((a, b) => (b.count || 1) - (a.count || 1));
1109
+ }
1110
+ return result;
1111
+ }, [analyticsEvents, analyticsSearch, analyticsFilters]);
938
1112
  const filteredConsoleLogs = (0, react_1.useMemo)(() => {
939
1113
  let result = visibleConsoleLogs;
940
1114
  // Filters check
@@ -1233,6 +1407,10 @@ const NetworkInspector = ({ enabled = true, isEnabled = true, storage, navigatio
1233
1407
  filteredAnalyticsEvents,
1234
1408
  analyticsSearch,
1235
1409
  setAnalyticsSearch,
1410
+ analyticsFilters,
1411
+ setAnalyticsFilters,
1412
+ isAnalyticsFilterApplied,
1413
+ resetAnalyticsFilters,
1236
1414
  newEventIds,
1237
1415
  isAnalyticsLayoutReady,
1238
1416
  setIsAnalyticsLayoutReady,
@@ -1320,3 +1498,33 @@ Object.defineProperty(exports, "subscribeReduxState", { enumerable: true, get: f
1320
1498
  Object.defineProperty(exports, "getActionHistory", { enumerable: true, get: function () { return reduxLogger_2.getActionHistory; } });
1321
1499
  Object.defineProperty(exports, "clearActionHistory", { enumerable: true, get: function () { return reduxLogger_2.clearActionHistory; } });
1322
1500
  Object.defineProperty(exports, "getLastActionForReducer", { enumerable: true, get: function () { return reduxLogger_2.getLastActionForReducer; } });
1501
+ var gaAnalyticsRegistry_1 = require("./helpers/gaAnalyticsRegistry");
1502
+ Object.defineProperty(exports, "getEventCategory", { enumerable: true, get: function () { return gaAnalyticsRegistry_1.getEventCategory; } });
1503
+ Object.defineProperty(exports, "registerGAPlugin", { enumerable: true, get: function () { return gaAnalyticsRegistry_1.registerGAPlugin; } });
1504
+ var performanceTracker_1 = require("./customHooks/performanceTracker");
1505
+ Object.defineProperty(exports, "usePerformanceTracker", { enumerable: true, get: function () { return performanceTracker_1.usePerformanceTracker; } });
1506
+ Object.defineProperty(exports, "logPerformanceEvent", { enumerable: true, get: function () { return performanceTracker_1.logPerformanceEvent; } });
1507
+ Object.defineProperty(exports, "clearPerformanceEvents", { enumerable: true, get: function () { return performanceTracker_1.clearPerformanceEvents; } });
1508
+ Object.defineProperty(exports, "subscribePerformanceEvents", { enumerable: true, get: function () { return performanceTracker_1.subscribePerformanceEvents; } });
1509
+ Object.defineProperty(exports, "getPerformanceEvents", { enumerable: true, get: function () { return performanceTracker_1.getPerformanceEvents; } });
1510
+ var decorators_1 = require("./decorators");
1511
+ Object.defineProperty(exports, "InspectLog", { enumerable: true, get: function () { return decorators_1.InspectLog; } });
1512
+ Object.defineProperty(exports, "InspectTrackTime", { enumerable: true, get: function () { return decorators_1.InspectTrackTime; } });
1513
+ Object.defineProperty(exports, "InspectCatch", { enumerable: true, get: function () { return decorators_1.InspectCatch; } });
1514
+ var types_1 = require("./types");
1515
+ Object.defineProperty(exports, "ActiveTab", { enumerable: true, get: function () { return types_1.ActiveTab; } });
1516
+ Object.defineProperty(exports, "Method", { enumerable: true, get: function () { return types_1.Method; } });
1517
+ Object.defineProperty(exports, "StatusFilter", { enumerable: true, get: function () { return types_1.StatusFilter; } });
1518
+ Object.defineProperty(exports, "SortOrder", { enumerable: true, get: function () { return types_1.SortOrder; } });
1519
+ Object.defineProperty(exports, "LocalFilter", { enumerable: true, get: function () { return types_1.LocalFilter; } });
1520
+ Object.defineProperty(exports, "ModalAnimationType", { enumerable: true, get: function () { return types_1.ModalAnimationType; } });
1521
+ Object.defineProperty(exports, "SettingsPage", { enumerable: true, get: function () { return types_1.SettingsPage; } });
1522
+ Object.defineProperty(exports, "SettingsSubTab", { enumerable: true, get: function () { return types_1.SettingsSubTab; } });
1523
+ Object.defineProperty(exports, "LogFilter", { enumerable: true, get: function () { return types_1.LogFilter; } });
1524
+ Object.defineProperty(exports, "ConsoleLogType", { enumerable: true, get: function () { return types_1.ConsoleLogType; } });
1525
+ Object.defineProperty(exports, "AnalyticsEventSource", { enumerable: true, get: function () { return types_1.AnalyticsEventSource; } });
1526
+ Object.defineProperty(exports, "GAEventCategory", { enumerable: true, get: function () { return types_1.GAEventCategory; } });
1527
+ Object.defineProperty(exports, "StackFrameType", { enumerable: true, get: function () { return types_1.StackFrameType; } });
1528
+ Object.defineProperty(exports, "DiffResultType", { enumerable: true, get: function () { return types_1.DiffResultType; } });
1529
+ Object.defineProperty(exports, "BundleSubTab", { enumerable: true, get: function () { return types_1.BundleSubTab; } });
1530
+ Object.defineProperty(exports, "PerformanceSubTab", { enumerable: true, get: function () { return types_1.PerformanceSubTab; } });
@@ -641,6 +641,10 @@ export declare const getRawStyles: (colors: typeof AppColors) => {
641
641
  fontSize: number;
642
642
  color: string;
643
643
  letterSpacing: number;
644
+ backgroundColor: string;
645
+ paddingHorizontal: number;
646
+ paddingVertical: number;
647
+ borderRadius: number;
644
648
  };
645
649
  slugText: {
646
650
  fontFamily: string;
@@ -1457,7 +1461,6 @@ export declare const getRawStyles: (colors: typeof AppColors) => {
1457
1461
  flexDirection: string;
1458
1462
  justifyContent: string;
1459
1463
  alignItems: string;
1460
- marginBottom: number;
1461
1464
  };
1462
1465
  analyticsHeaderTitle: {
1463
1466
  fontFamily: string;