react-native-inapp-inspector 2.2.2 → 2.2.3

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 (97) hide show
  1. package/dist/commonjs/constants/version.d.ts +1 -1
  2. package/dist/commonjs/constants/version.js +1 -1
  3. package/dist/esm/constants/version.d.ts +1 -1
  4. package/dist/esm/constants/version.js +1 -1
  5. package/package.json +2 -1
  6. package/src/analytics.ts +35 -0
  7. package/src/bundle.ts +25 -0
  8. package/src/components/AnalyticsDetail.tsx +865 -0
  9. package/src/components/AnalyticsEventCard.tsx +441 -0
  10. package/src/components/AnalyticsGraph.tsx +583 -0
  11. package/src/components/AnimatedEntrance.tsx +64 -0
  12. package/src/components/AppHeaderLogo.tsx +109 -0
  13. package/src/components/BrandCircleIcon.tsx +144 -0
  14. package/src/components/BrandSquareIcon.tsx +144 -0
  15. package/src/components/CodeSnippet.tsx +725 -0
  16. package/src/components/ConsoleLogCard.tsx +628 -0
  17. package/src/components/CopyButton.tsx +87 -0
  18. package/src/components/DiffViewer.tsx +82 -0
  19. package/src/components/DomainHeader.tsx +237 -0
  20. package/src/components/EmptyState.tsx +73 -0
  21. package/src/components/EndOfListFooter.tsx +100 -0
  22. package/src/components/ErrorBoundary.tsx +688 -0
  23. package/src/components/HeadersSection.tsx +192 -0
  24. package/src/components/HighlightText.tsx +100 -0
  25. package/src/components/Inspector/AnalyticsFilterModal.tsx +1250 -0
  26. package/src/components/Inspector/AnalyticsTab.tsx +1336 -0
  27. package/src/components/Inspector/BundleTab.tsx +4731 -0
  28. package/src/components/Inspector/ConsoleTab.tsx +702 -0
  29. package/src/components/Inspector/CrashDetail.tsx +941 -0
  30. package/src/components/Inspector/CrashFilterModal.tsx +721 -0
  31. package/src/components/Inspector/CrashTab.tsx +871 -0
  32. package/src/components/Inspector/FabLauncher.tsx +80 -0
  33. package/src/components/Inspector/InspectorContext.tsx +28 -0
  34. package/src/components/Inspector/InspectorHeader.tsx +973 -0
  35. package/src/components/Inspector/LogDetail.tsx +1427 -0
  36. package/src/components/Inspector/MainScreen.tsx +258 -0
  37. package/src/components/Inspector/NavigationTracker.tsx +13 -0
  38. package/src/components/Inspector/NetworkDetail.tsx +794 -0
  39. package/src/components/Inspector/NetworkTab.tsx +1095 -0
  40. package/src/components/Inspector/NpmUpdateToast.tsx +392 -0
  41. package/src/components/Inspector/PerformanceTab.tsx +1894 -0
  42. package/src/components/Inspector/ReduxDetail.tsx +1651 -0
  43. package/src/components/Inspector/ReduxTab.tsx +954 -0
  44. package/src/components/Inspector/SettingsPanel.tsx +3181 -0
  45. package/src/components/Inspector/TabBar.tsx +187 -0
  46. package/src/components/Inspector/TelemetryConsentModal.tsx +392 -0
  47. package/src/components/Inspector/UpdateAvailableModal.tsx +545 -0
  48. package/src/components/JsonViewer.tsx +486 -0
  49. package/src/components/LogCard.tsx +491 -0
  50. package/src/components/LogSyntaxHighlighter.tsx +178 -0
  51. package/src/components/MetaAccordion.tsx +340 -0
  52. package/src/components/MiniBarChart.tsx +42 -0
  53. package/src/components/MiniLineChart.tsx +33 -0
  54. package/src/components/NetworkIcons.tsx +2118 -0
  55. package/src/components/SectionHeader.tsx +113 -0
  56. package/src/components/SegmentedTabs.tsx +83 -0
  57. package/src/components/Slider.tsx +300 -0
  58. package/src/components/SourcePageCard.tsx +148 -0
  59. package/src/components/Toast.tsx +131 -0
  60. package/src/components/TouchableScale.tsx +91 -0
  61. package/src/components/TreeNode.tsx +186 -0
  62. package/src/console.ts +24 -0
  63. package/src/constants/index.ts +38 -0
  64. package/src/constants/version.ts +3 -0
  65. package/src/crash.ts +32 -0
  66. package/src/customHooks/analyticsLogger.ts +336 -0
  67. package/src/customHooks/bundleAnalyzer.ts +1231 -0
  68. package/src/customHooks/consoleLogger.ts +497 -0
  69. package/src/customHooks/crashHandler.ts +944 -0
  70. package/src/customHooks/logFilters.ts +32 -0
  71. package/src/customHooks/networkLogger.ts +419 -0
  72. package/src/customHooks/performanceTracker.ts +1014 -0
  73. package/src/customHooks/reduxLogger.ts +406 -0
  74. package/src/customHooks/useAccordion.tsx +60 -0
  75. package/src/decorators/index.ts +184 -0
  76. package/src/helpers/gaAnalyticsRegistry.ts +204 -0
  77. package/src/helpers/index.ts +860 -0
  78. package/src/helpers/memoryManager.ts +138 -0
  79. package/src/helpers/searchQueryParser.ts +283 -0
  80. package/src/helpers/settingsStore.ts +171 -0
  81. package/src/helpers/telemetry.ts +505 -0
  82. package/src/helpers/toast.ts +17 -0
  83. package/src/i18n/index.ts +69 -0
  84. package/src/i18n/locales/en.json +1052 -0
  85. package/src/index.tsx +2336 -0
  86. package/src/native/NativeInspector.ts +397 -0
  87. package/src/native/NativeNetworkInspector.ts +24 -0
  88. package/src/network.ts +22 -0
  89. package/src/performance.ts +38 -0
  90. package/src/redux.ts +23 -0
  91. package/src/styles/AppColors.ts +408 -0
  92. package/src/styles/AppFonts.ts +8 -0
  93. package/src/styles/common.ts +209 -0
  94. package/src/styles/index.ts +1570 -0
  95. package/src/types/enums.ts +194 -0
  96. package/src/types/index.ts +34 -0
  97. package/src/types/interfaces.ts +515 -0
@@ -0,0 +1,336 @@
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
+
24
+ import {AnalyticsEvent} from '../types';
25
+
26
+ // ─── Internal state ───────────────────────────────────────────────────────────
27
+
28
+ let events: AnalyticsEvent[] = [];
29
+ let listeners: ((events: AnalyticsEvent[]) => void)[] = [];
30
+ let counter = 0;
31
+ let isAnalyticsModuleEnabled = false;
32
+
33
+ export const setAnalyticsModuleEnabled = (enabled: boolean) => {
34
+ isAnalyticsModuleEnabled = enabled;
35
+ };
36
+
37
+ export const getAnalyticsModuleEnabled = () => isAnalyticsModuleEnabled;
38
+
39
+ // Running snapshot of user properties set so far — attached to every event
40
+ let currentUserProperties: Record<string, any> = {};
41
+ let currentUserId: string | undefined;
42
+ let currentDefaultEventParameters: Record<string, any> = {};
43
+ let isCollectionEnabled = true;
44
+
45
+ let maxAnalyticsLogsLimit = 75;
46
+
47
+ export const setMaxAnalyticsLogsLimit = (limit: number): void => {
48
+ maxAnalyticsLogsLimit = Math.max(10, limit);
49
+ if (events.length > maxAnalyticsLogsLimit) {
50
+ events = events.slice(0, maxAnalyticsLogsLimit);
51
+ notify();
52
+ }
53
+ };
54
+
55
+ export const getMaxAnalyticsLogsLimit = (): number => maxAnalyticsLogsLimit;
56
+
57
+ export const pruneAnalyticsLogs = (targetCount?: number): number => {
58
+ const countToKeep = targetCount !== undefined ? Math.max(0, targetCount) : Math.floor(events.length / 2);
59
+ const pruned = events.length - countToKeep;
60
+ if (pruned > 0) {
61
+ events = events.slice(0, countToKeep);
62
+ notify();
63
+ }
64
+ return Math.max(0, pruned);
65
+ };
66
+
67
+ // ─── Core helpers ─────────────────────────────────────────────────────────────
68
+
69
+ const notify = () => {
70
+ const snapshot = [...events];
71
+ listeners.forEach(cb => cb(snapshot));
72
+ };
73
+
74
+ const addEvent = (event: AnalyticsEvent) => {
75
+ if (!isAnalyticsModuleEnabled) return;
76
+ events.unshift(event);
77
+ events = events.slice(0, maxAnalyticsLogsLimit);
78
+ notify();
79
+ };
80
+
81
+ // ─── Public subscribe / query API ────────────────────────────────────────────
82
+
83
+ export const subscribeAnalyticsEvents = (
84
+ callback: (events: AnalyticsEvent[]) => void,
85
+ ) => {
86
+ listeners.push(callback);
87
+ callback([...events]);
88
+ return () => {
89
+ listeners = listeners.filter(l => l !== callback);
90
+ };
91
+ };
92
+
93
+ export const clearAnalyticsEvents = () => {
94
+ events = [];
95
+ notify();
96
+ };
97
+
98
+ export const getAnalyticsEvents = () => [...events];
99
+
100
+ export const getCurrentUserProperties = () => ({...currentUserProperties});
101
+ export const getCurrentUserId = () => currentUserId;
102
+ export const getDefaultEventParameters = () => ({...currentDefaultEventParameters});
103
+ export const getCollectionEnabled = () => isCollectionEnabled;
104
+
105
+ // ─── Manual logging (escape hatch, rarely needed) ────────────────────────────
106
+
107
+ /**
108
+ * Directly push an event into the inspector without going through Firebase.
109
+ * Useful for custom analytics wrappers or testing.
110
+ */
111
+ export const logAnalyticsEvent = (
112
+ name: string,
113
+ params: Record<string, any> = {},
114
+ userProperties: Record<string, any> = {},
115
+ ) => {
116
+ addEvent({
117
+ id: counter++,
118
+ name,
119
+ params,
120
+ userProperties: {...currentUserProperties, ...userProperties},
121
+ timestamp: Date.now(),
122
+ source: 'manual',
123
+ userId: currentUserId ?? '',
124
+ screenName: '',
125
+ screenClass: '',
126
+ });
127
+ };
128
+
129
+ // ─── Firebase Analytics instance patcher ─────────────────────────────────────
130
+
131
+ /**
132
+ * Monkey-patches a @react-native-firebase/analytics instance so all calls
133
+ * are intercepted and forwarded to the NetworkInspector analytics tab.
134
+ *
135
+ * Pass the result of `analytics()` (the default app instance or any named one).
136
+ * Safe to call multiple times with the same instance — won't double-patch.
137
+ *
138
+ * @example
139
+ * import analytics from '@react-native-firebase/analytics';
140
+ * setupAnalyticsLogger(analytics());
141
+ */
142
+ let isAnalyticsPatched = false;
143
+
144
+ /**
145
+ * Returns true if analytics logging is active (always ready for custom and Firebase events).
146
+ */
147
+ export const isAnalyticsConnected = () => true;
148
+
149
+ export const isFirebaseAnalyticsPatched = () => isAnalyticsPatched;
150
+
151
+ export const setupAnalyticsLogger = (analyticsInstance: any): void => {
152
+ if (!analyticsInstance) {
153
+ console.warn(
154
+ '[AnalyticsLogger] No analytics instance provided — skipping setup.',
155
+ );
156
+ return;
157
+ }
158
+
159
+ isAnalyticsPatched = true;
160
+
161
+ // Guard against double-patching the same instance
162
+ if (analyticsInstance.__INSPECTOR_PATCHED__) return;
163
+ analyticsInstance.__INSPECTOR_PATCHED__ = true;
164
+
165
+ // ── logEvent ──────────────────────────────────────────────────────────────
166
+ const originalLogEvent = analyticsInstance.logEvent.bind(analyticsInstance);
167
+ analyticsInstance.logEvent = async (
168
+ name: string,
169
+ params?: Record<string, any>,
170
+ ) => {
171
+ try {
172
+ addEvent({
173
+ id: counter++,
174
+ name,
175
+ params: params ?? {},
176
+ userProperties: {...currentUserProperties},
177
+ timestamp: Date.now(),
178
+ source: 'firebase',
179
+ userId: currentUserId ?? '',
180
+ screenName: '',
181
+ screenClass: '',
182
+ });
183
+ } catch {}
184
+ return originalLogEvent(name, params);
185
+ };
186
+
187
+ // ── logScreenView ─────────────────────────────────────────────────────────
188
+ const originalLogScreenView =
189
+ analyticsInstance.logScreenView.bind(analyticsInstance);
190
+ analyticsInstance.logScreenView = async (params?: {
191
+ screen_name?: string;
192
+ screen_class?: string;
193
+ [key: string]: any;
194
+ }) => {
195
+ try {
196
+ addEvent({
197
+ id: counter++,
198
+ name: 'screen_view',
199
+ params: params ?? {},
200
+ userProperties: {...currentUserProperties},
201
+ timestamp: Date.now(),
202
+ source: 'firebase',
203
+ screenName: params?.screen_name ?? '',
204
+ screenClass: params?.screen_class ?? '',
205
+ userId: currentUserId ?? '',
206
+ });
207
+ } catch {}
208
+ return originalLogScreenView(params);
209
+ };
210
+
211
+ // ── setUserProperty ───────────────────────────────────────────────────────
212
+ const originalSetUserProperty =
213
+ analyticsInstance.setUserProperty.bind(analyticsInstance);
214
+ analyticsInstance.setUserProperty = async (
215
+ name: string,
216
+ value: string | null,
217
+ ) => {
218
+ try {
219
+ if (value === null) {
220
+ delete currentUserProperties[name];
221
+ } else {
222
+ currentUserProperties[name] = value;
223
+ }
224
+ } catch {}
225
+ return originalSetUserProperty(name, value);
226
+ };
227
+
228
+ // ── setUserProperties ─────────────────────────────────────────────────────
229
+ const originalSetUserProperties =
230
+ analyticsInstance.setUserProperties.bind(analyticsInstance);
231
+ analyticsInstance.setUserProperties = async (
232
+ properties: Record<string, string | null>,
233
+ ) => {
234
+ try {
235
+ if (properties && typeof properties === 'object') {
236
+ Object.entries(properties).forEach(([k, v]) => {
237
+ if (v === null) delete currentUserProperties[k];
238
+ else currentUserProperties[k] = v;
239
+ });
240
+ }
241
+ } catch {}
242
+ return originalSetUserProperties(properties);
243
+ };
244
+
245
+ // ── setUserId ─────────────────────────────────────────────────────────────
246
+ const originalSetUserId = analyticsInstance.setUserId.bind(analyticsInstance);
247
+ analyticsInstance.setUserId = async (id: string | null) => {
248
+ try {
249
+ currentUserId = id ?? undefined;
250
+ notify();
251
+ } catch {}
252
+ return originalSetUserId(id);
253
+ };
254
+
255
+ // ── setDefaultEventParameters ──────────────────────────────────────────────
256
+ if (typeof analyticsInstance.setDefaultEventParameters === 'function') {
257
+ const originalSetDefaultEventParameters =
258
+ analyticsInstance.setDefaultEventParameters.bind(analyticsInstance);
259
+ analyticsInstance.setDefaultEventParameters = async (
260
+ params: Record<string, any> | null,
261
+ ) => {
262
+ try {
263
+ currentDefaultEventParameters = params ?? {};
264
+ notify();
265
+ } catch {}
266
+ return originalSetDefaultEventParameters(params);
267
+ };
268
+ }
269
+
270
+ // ── setAnalyticsCollectionEnabled ───────────────────────────────────────────
271
+ if (typeof analyticsInstance.setAnalyticsCollectionEnabled === 'function') {
272
+ const originalSetAnalyticsCollectionEnabled =
273
+ analyticsInstance.setAnalyticsCollectionEnabled.bind(analyticsInstance);
274
+ analyticsInstance.setAnalyticsCollectionEnabled = async (enabled: boolean) => {
275
+ try {
276
+ isCollectionEnabled = enabled;
277
+ notify();
278
+ } catch {}
279
+ return originalSetAnalyticsCollectionEnabled(enabled);
280
+ };
281
+ }
282
+
283
+ // ── resetAnalyticsData ──────────────────────────────────────────────────────
284
+ if (typeof analyticsInstance.resetAnalyticsData === 'function') {
285
+ const originalResetAnalyticsData =
286
+ analyticsInstance.resetAnalyticsData.bind(analyticsInstance);
287
+ analyticsInstance.resetAnalyticsData = async () => {
288
+ try {
289
+ clearAnalyticsEvents();
290
+ currentUserProperties = {};
291
+ currentUserId = undefined;
292
+ currentDefaultEventParameters = {};
293
+ notify();
294
+ } catch {}
295
+ return originalResetAnalyticsData();
296
+ };
297
+ }
298
+ };
299
+
300
+ export const autoSetupAnalyticsLogger = (): boolean => {
301
+ if ((globalThis as any).__INSPECTOR_ANALYTICS_AUTOSETUP__) return true;
302
+
303
+ let mod: any;
304
+ try {
305
+ mod = require('@react-native-firebase/analytics'); // optional dep
306
+ } catch {
307
+ return false; // GA not installed — silent no-op
308
+ }
309
+
310
+ const accessor = mod?.default ?? mod;
311
+ if (typeof accessor !== 'function') return false;
312
+
313
+ try {
314
+ setupAnalyticsLogger(accessor());
315
+ } catch {} // patch default-app instance
316
+
317
+ if (!accessor.__INSPECTOR_WRAPPED__) {
318
+ // patch future/named instances
319
+ const wrapped: any = function (this: any, ...args: any[]) {
320
+ const instance = accessor.apply(this, args);
321
+ try {
322
+ setupAnalyticsLogger(instance);
323
+ } catch {}
324
+ return instance;
325
+ };
326
+ Object.setPrototypeOf(wrapped, accessor);
327
+ Object.assign(wrapped, accessor);
328
+ wrapped.__INSPECTOR_WRAPPED__ = true;
329
+ try {
330
+ if (mod.default !== undefined) mod.default = wrapped;
331
+ } catch {}
332
+ }
333
+
334
+ (globalThis as any).__INSPECTOR_ANALYTICS_AUTOSETUP__ = true;
335
+ return true;
336
+ };