react-native-inapp-inspector 2.3.14 → 2.3.16

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 (125) hide show
  1. package/README.md +1 -0
  2. package/dist/commonjs/components/AnimatedEntrance.js +3 -3
  3. package/dist/commonjs/components/ConsoleLogCard.js +174 -100
  4. package/dist/commonjs/components/Inspector/AnalyticsTab.js +0 -22
  5. package/dist/commonjs/components/Inspector/ConsoleTab.js +25 -38
  6. package/dist/commonjs/components/Inspector/CrashTab.js +19 -28
  7. package/dist/commonjs/components/Inspector/DeviceInfoTab.js +198 -98
  8. package/dist/commonjs/components/Inspector/FeedbackModal.d.ts +7 -0
  9. package/dist/commonjs/components/Inspector/FeedbackModal.js +552 -0
  10. package/dist/commonjs/components/Inspector/InspectorHeader.js +58 -6
  11. package/dist/commonjs/components/Inspector/MainScreen.js +100 -58
  12. package/dist/commonjs/components/Inspector/NetworkTab.js +26 -371
  13. package/dist/commonjs/components/Inspector/NpmStarPrompt.d.ts +3 -0
  14. package/dist/commonjs/components/Inspector/NpmStarPrompt.js +494 -0
  15. package/dist/commonjs/components/Inspector/PerformanceTab.js +40 -7
  16. package/dist/commonjs/components/Inspector/ReduxTab.js +3 -23
  17. package/dist/commonjs/components/Inspector/SettingsPanel.js +1035 -173
  18. package/dist/commonjs/components/Inspector/StorageTab.js +23 -28
  19. package/dist/commonjs/components/Inspector/TabBar.js +50 -15
  20. package/dist/commonjs/components/JsonViewer.js +14 -2
  21. package/dist/commonjs/components/LogCard.js +428 -227
  22. package/dist/commonjs/components/NetworkIcons.d.ts +5 -0
  23. package/dist/commonjs/components/NetworkIcons.js +33 -2
  24. package/dist/commonjs/constants/version.d.ts +1 -1
  25. package/dist/commonjs/constants/version.js +1 -1
  26. package/dist/commonjs/customHooks/analyticsLogger.js +1 -1
  27. package/dist/commonjs/customHooks/consoleLogger.js +34 -2
  28. package/dist/commonjs/customHooks/crashHandler.js +1 -1
  29. package/dist/commonjs/customHooks/networkLogger.js +184 -26
  30. package/dist/commonjs/helpers/index.d.ts +1 -0
  31. package/dist/commonjs/helpers/index.js +1 -0
  32. package/dist/commonjs/helpers/remoteConfig.d.ts +4 -0
  33. package/dist/commonjs/helpers/remoteConfig.js +165 -0
  34. package/dist/commonjs/helpers/searchQueryParser.d.ts +1 -1
  35. package/dist/commonjs/helpers/searchQueryParser.js +39 -291
  36. package/dist/commonjs/helpers/telemetry.d.ts +5 -0
  37. package/dist/commonjs/helpers/telemetry.js +339 -8
  38. package/dist/commonjs/index.d.ts +1 -0
  39. package/dist/commonjs/index.js +173 -29
  40. package/dist/commonjs/styles/AppFonts.d.ts +2 -0
  41. package/dist/commonjs/styles/AppFonts.js +1 -0
  42. package/dist/commonjs/styles/index.d.ts +22 -0
  43. package/dist/commonjs/styles/index.js +19 -0
  44. package/dist/commonjs/types/enums.d.ts +1 -0
  45. package/dist/commonjs/types/enums.js +1 -0
  46. package/dist/commonjs/types/interfaces.d.ts +12 -0
  47. package/dist/esm/components/AnimatedEntrance.js +3 -3
  48. package/dist/esm/components/ConsoleLogCard.js +141 -100
  49. package/dist/esm/components/Inspector/AnalyticsTab.js +1 -23
  50. package/dist/esm/components/Inspector/ConsoleTab.js +26 -39
  51. package/dist/esm/components/Inspector/CrashTab.js +20 -29
  52. package/dist/esm/components/Inspector/DeviceInfoTab.js +198 -98
  53. package/dist/esm/components/Inspector/FeedbackModal.d.ts +7 -0
  54. package/dist/esm/components/Inspector/FeedbackModal.js +515 -0
  55. package/dist/esm/components/Inspector/InspectorHeader.js +60 -8
  56. package/dist/esm/components/Inspector/MainScreen.js +101 -59
  57. package/dist/esm/components/Inspector/NetworkTab.js +27 -372
  58. package/dist/esm/components/Inspector/NpmStarPrompt.d.ts +3 -0
  59. package/dist/esm/components/Inspector/NpmStarPrompt.js +454 -0
  60. package/dist/esm/components/Inspector/PerformanceTab.js +40 -7
  61. package/dist/esm/components/Inspector/ReduxTab.js +4 -24
  62. package/dist/esm/components/Inspector/SettingsPanel.js +1038 -176
  63. package/dist/esm/components/Inspector/StorageTab.js +23 -28
  64. package/dist/esm/components/Inspector/TabBar.js +50 -15
  65. package/dist/esm/components/JsonViewer.js +14 -2
  66. package/dist/esm/components/LogCard.js +422 -221
  67. package/dist/esm/components/NetworkIcons.d.ts +5 -0
  68. package/dist/esm/components/NetworkIcons.js +26 -0
  69. package/dist/esm/constants/version.d.ts +1 -1
  70. package/dist/esm/constants/version.js +1 -1
  71. package/dist/esm/customHooks/analyticsLogger.js +1 -1
  72. package/dist/esm/customHooks/consoleLogger.js +34 -2
  73. package/dist/esm/customHooks/crashHandler.js +1 -1
  74. package/dist/esm/customHooks/networkLogger.js +184 -26
  75. package/dist/esm/helpers/index.d.ts +1 -0
  76. package/dist/esm/helpers/index.js +1 -0
  77. package/dist/esm/helpers/remoteConfig.d.ts +4 -0
  78. package/dist/esm/helpers/remoteConfig.js +160 -0
  79. package/dist/esm/helpers/searchQueryParser.d.ts +1 -1
  80. package/dist/esm/helpers/searchQueryParser.js +39 -291
  81. package/dist/esm/helpers/telemetry.d.ts +5 -0
  82. package/dist/esm/helpers/telemetry.js +332 -9
  83. package/dist/esm/index.d.ts +1 -0
  84. package/dist/esm/index.js +171 -29
  85. package/dist/esm/styles/AppFonts.d.ts +2 -0
  86. package/dist/esm/styles/AppFonts.js +1 -0
  87. package/dist/esm/styles/index.d.ts +22 -0
  88. package/dist/esm/styles/index.js +19 -0
  89. package/dist/esm/types/enums.d.ts +1 -0
  90. package/dist/esm/types/enums.js +1 -0
  91. package/dist/esm/types/interfaces.d.ts +12 -0
  92. package/package.json +1 -1
  93. package/src/components/AnimatedEntrance.tsx +3 -3
  94. package/src/components/ConsoleLogCard.tsx +154 -103
  95. package/src/components/Inspector/AnalyticsTab.tsx +0 -23
  96. package/src/components/Inspector/ConsoleTab.tsx +27 -41
  97. package/src/components/Inspector/CrashTab.tsx +19 -28
  98. package/src/components/Inspector/DeviceInfoTab.tsx +224 -102
  99. package/src/components/Inspector/FeedbackModal.tsx +626 -0
  100. package/src/components/Inspector/InspectorHeader.tsx +83 -5
  101. package/src/components/Inspector/MainScreen.tsx +61 -6
  102. package/src/components/Inspector/NetworkTab.tsx +70 -480
  103. package/src/components/Inspector/NpmStarPrompt.tsx +532 -0
  104. package/src/components/Inspector/PerformanceTab.tsx +44 -8
  105. package/src/components/Inspector/ReduxTab.tsx +9 -24
  106. package/src/components/Inspector/SettingsPanel.tsx +1162 -197
  107. package/src/components/Inspector/StorageTab.tsx +27 -30
  108. package/src/components/Inspector/TabBar.tsx +57 -20
  109. package/src/components/JsonViewer.tsx +15 -2
  110. package/src/components/LogCard.tsx +528 -339
  111. package/src/components/NetworkIcons.tsx +92 -0
  112. package/src/constants/version.ts +1 -1
  113. package/src/customHooks/analyticsLogger.ts +1 -1
  114. package/src/customHooks/consoleLogger.ts +36 -3
  115. package/src/customHooks/crashHandler.ts +1 -1
  116. package/src/customHooks/networkLogger.ts +214 -26
  117. package/src/helpers/index.ts +1 -0
  118. package/src/helpers/remoteConfig.ts +212 -0
  119. package/src/helpers/searchQueryParser.ts +42 -284
  120. package/src/helpers/telemetry.ts +381 -10
  121. package/src/index.tsx +374 -211
  122. package/src/styles/AppFonts.ts +2 -0
  123. package/src/styles/index.ts +20 -1
  124. package/src/types/enums.ts +1 -0
  125. package/src/types/interfaces.ts +12 -0
@@ -1520,6 +1520,23 @@ export const PackageBoxIcon = ({
1520
1520
  );
1521
1521
  };
1522
1522
 
1523
+ export const StarIcon = ({
1524
+ color = '#F59E0B',
1525
+ size = 14,
1526
+ }: IconProps) => {
1527
+ return (
1528
+ <Svg width={size} height={size} viewBox="0 0 24 24" fill={color}>
1529
+ <Path
1530
+ d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"
1531
+ stroke={color}
1532
+ strokeWidth="1.5"
1533
+ strokeLinecap="round"
1534
+ strokeLinejoin="round"
1535
+ />
1536
+ </Svg>
1537
+ );
1538
+ };
1539
+
1523
1540
  export const GitHubIcon = ({
1524
1541
  color = AppColors.grayTextWeak,
1525
1542
  size = 14,
@@ -2355,3 +2372,78 @@ export const TurtleIcon = ({
2355
2372
  </Svg>
2356
2373
  );
2357
2374
 
2375
+ export const HeadphonesIcon = ({
2376
+ color = AppColors.white,
2377
+ size = 20,
2378
+ }: IconProps) => (
2379
+ <Svg width={size} height={size} viewBox="0 0 24 24" fill="none">
2380
+ <Path
2381
+ d="M3 18v-6a9 9 0 0 1 18 0v6"
2382
+ stroke={color}
2383
+ strokeWidth="2"
2384
+ strokeLinecap="round"
2385
+ strokeLinejoin="round"
2386
+ />
2387
+ <Path
2388
+ d="M21 19a2 2 0 0 1-2 2h-1a2 2 0 0 1-2-2v-3a2 2 0 0 1 2-2h3v5zM3 19a2 2 0 0 0 2 2h1a2 2 0 0 0 2-2v-3a2 2 0 0 0-2-2H3v5z"
2389
+ stroke={color}
2390
+ strokeWidth="2"
2391
+ strokeLinecap="round"
2392
+ strokeLinejoin="round"
2393
+ />
2394
+ </Svg>
2395
+ );
2396
+
2397
+ export const HelpCircleIcon = ({
2398
+ color = AppColors.white,
2399
+ size = 20,
2400
+ }: IconProps) => (
2401
+ <Svg width={size} height={size} viewBox="0 0 24 24" fill="none">
2402
+ <Circle cx="12" cy="12" r="10" stroke={color} strokeWidth="2" />
2403
+ <Path
2404
+ d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3"
2405
+ stroke={color}
2406
+ strokeWidth="2"
2407
+ strokeLinecap="round"
2408
+ strokeLinejoin="round"
2409
+ />
2410
+ <Line x1="12" y1="17" x2="12.01" y2="17" stroke={color} strokeWidth="2" strokeLinecap="round" />
2411
+ </Svg>
2412
+ );
2413
+
2414
+ export const SendIcon = ({
2415
+ color = AppColors.white,
2416
+ size = 18,
2417
+ }: IconProps) => (
2418
+ <Svg width={size} height={size} viewBox="0 0 24 24" fill="none">
2419
+ <Path
2420
+ d="M22 2L11 13"
2421
+ stroke={color}
2422
+ strokeWidth="2"
2423
+ strokeLinecap="round"
2424
+ strokeLinejoin="round"
2425
+ />
2426
+ <Path
2427
+ d="M22 2L15 22L11 13L2 9L22 2Z"
2428
+ stroke={color}
2429
+ strokeWidth="2"
2430
+ strokeLinecap="round"
2431
+ strokeLinejoin="round"
2432
+ />
2433
+ </Svg>
2434
+ );
2435
+
2436
+ export const LifeBuoyIcon = ({
2437
+ color = AppColors.white,
2438
+ size = 20,
2439
+ }: IconProps) => (
2440
+ <Svg width={size} height={size} viewBox="0 0 24 24" fill="none">
2441
+ <Circle cx="12" cy="12" r="10" stroke={color} strokeWidth="2" />
2442
+ <Circle cx="12" cy="12" r="4" stroke={color} strokeWidth="2" />
2443
+ <Line x1="4.93" y1="4.93" x2="9.17" y2="9.17" stroke={color} strokeWidth="2" strokeLinecap="round" />
2444
+ <Line x1="14.83" y1="9.17" x2="19.07" y2="4.93" stroke={color} strokeWidth="2" strokeLinecap="round" />
2445
+ <Line x1="14.83" y1="14.83" x2="19.07" y2="19.07" stroke={color} strokeWidth="2" strokeLinecap="round" />
2446
+ <Line x1="4.93" y1="19.07" x2="9.17" y2="14.83" stroke={color} strokeWidth="2" strokeLinecap="round" />
2447
+ </Svg>
2448
+ );
2449
+
@@ -1,3 +1,3 @@
1
1
  // AUTO-GENERATED FILE — do not edit by hand.
2
2
  // Regenerated from package.json on every build by scripts/gen-version.js.
3
- export const LIB_VERSION = '2.3.14';
3
+ export const LIB_VERSION = '2.3.16';
@@ -42,7 +42,7 @@ let currentUserId: string | undefined;
42
42
  let currentDefaultEventParameters: Record<string, any> = {};
43
43
  let isCollectionEnabled = true;
44
44
 
45
- let maxAnalyticsLogsLimit = 75;
45
+ let maxAnalyticsLogsLimit = 150;
46
46
 
47
47
  export const setMaxAnalyticsLogsLimit = (limit: number): void => {
48
48
  maxAnalyticsLogsLimit = Math.max(10, limit);
@@ -15,7 +15,7 @@ export const setConsoleModuleEnabled = (enabled: boolean) => {
15
15
 
16
16
  export const getConsoleModuleEnabled = () => isConsoleModuleEnabled;
17
17
 
18
- let maxConsoleLogsLimit = 100;
18
+ let maxConsoleLogsLimit = 250;
19
19
 
20
20
  export const setMaxConsoleLogsLimit = (limit: number): void => {
21
21
  maxConsoleLogsLimit = Math.max(10, limit);
@@ -293,9 +293,9 @@ const addLog = (
293
293
  logs = logs.slice(0, maxConsoleLogsLimit);
294
294
  notify();
295
295
 
296
- // Asynchronously symbolicate stack trace via Metro in development
296
+ // Asynchronously symbolicate stack trace via Metro in development (errors only)
297
297
  const stackToSymbolicate = errorStack || stackToUse || stack;
298
- if (stackToSymbolicate && typeof __DEV__ !== 'undefined' && __DEV__) {
298
+ if (type === 'error' && stackToSymbolicate && typeof __DEV__ !== 'undefined' && __DEV__) {
299
299
  const currentLogId = newLog.id;
300
300
  symbolicateStack(stackToSymbolicate)
301
301
  .then(symFrames => {
@@ -443,6 +443,8 @@ export const setupConsoleLogger = () => {
443
443
  info: console.info,
444
444
  warn: console.warn,
445
445
  error: console.error,
446
+ debug: console.debug,
447
+ trace: console.trace,
446
448
  };
447
449
 
448
450
  // Intercept console.log
@@ -461,6 +463,30 @@ export const setupConsoleLogger = () => {
461
463
  originalConsole.info(...args);
462
464
  };
463
465
 
466
+ // Intercept console.debug
467
+ console.debug = (...args: any[]) => {
468
+ try {
469
+ addLog('info', args, 'info');
470
+ } catch {}
471
+ if (typeof originalConsole.debug === 'function') {
472
+ originalConsole.debug(...args);
473
+ } else {
474
+ originalConsole.log(...args);
475
+ }
476
+ };
477
+
478
+ // Intercept console.trace
479
+ console.trace = (...args: any[]) => {
480
+ try {
481
+ addLog('info', args, 'info');
482
+ } catch {}
483
+ if (typeof originalConsole.trace === 'function') {
484
+ originalConsole.trace(...args);
485
+ } else {
486
+ originalConsole.log(...args);
487
+ }
488
+ };
489
+
464
490
  // Intercept console.warn
465
491
  console.warn = (...args: any[]) => {
466
492
  try {
@@ -495,3 +521,10 @@ export const setupConsoleLogger = () => {
495
521
 
496
522
  (globalThis as any).__CONSOLE_LOGGER_INITIALIZED__ = true;
497
523
  };
524
+
525
+ // Auto-initialize console logger on module load
526
+ if (typeof globalThis !== 'undefined') {
527
+ try {
528
+ setupConsoleLogger();
529
+ } catch {}
530
+ }
@@ -36,7 +36,7 @@ let lastHandledErrorTimestamp = 0;
36
36
  let crashRecordsStore: CrashRecord[] = [];
37
37
  let breadcrumbsStore: CrashBreadcrumb[] = [];
38
38
  const MAX_BREADCRUMBS = 50;
39
- let maxStoredCrashes = 50;
39
+ let maxStoredCrashes = 100;
40
40
  const appStartTime = Date.now();
41
41
  let isCrashModuleEnabled = false;
42
42
 
@@ -36,17 +36,23 @@ export const setNetworkModuleEnabled = (enabled: boolean) => {
36
36
 
37
37
  export const getNetworkModuleEnabled = () => isNetworkModuleEnabled;
38
38
 
39
- const ALLOWED_METHODS = ["GET", "POST", "PUT", "PATCH", "DELETE"];
39
+ const ALLOWED_METHODS = [
40
+ "GET",
41
+ "POST",
42
+ "PUT",
43
+ "PATCH",
44
+ "DELETE",
45
+ "HEAD",
46
+ "OPTIONS",
47
+ "CONNECT",
48
+ "TRACE",
49
+ ];
40
50
 
41
51
  const IGNORED_URL_PATTERNS: RegExp[] = [
42
- /\/symbolicate(?:[/?#]|$)/i,
52
+ /\/symbolicate(?:\?|$)/i,
43
53
  /\/index\.bundle(?:\?|$)/i,
44
- /\/hot(?:\?|$)/i,
45
- /\/message(?:\?|$)/i,
46
54
  /\/open-debugger(?:\?|$)/i,
47
- /\/status(?:\?|$)/i,
48
- /127\.0\.0\.1:(?:8081|8082|8083|19000|19001|19002|3000|8000)/i,
49
- /localhost:(?:8081|8082|8083|19000|19001|19002|3000|8000)\/index\.bundle/i,
55
+ /:(?:8081|8082|8083|19000|19001)\/(?:index\.bundle|symbolicate|hot|message|status)/i,
50
56
  /google-analytics\.com\/mp\/collect/i,
51
57
  /analytics\.google\.com/i,
52
58
  ];
@@ -58,6 +64,23 @@ function shouldIgnoreUrl(url: string | undefined | null): boolean {
58
64
 
59
65
  // ─── Helpers ──────────────────────────────────────────────────────────────────
60
66
 
67
+ function parseXHRResponseHeaders(
68
+ headerStr: string | null | undefined,
69
+ ): Record<string, string> | undefined {
70
+ if (!headerStr || typeof headerStr !== "string") return undefined;
71
+ const lines = headerStr.trim().split(/[\r\n]+/);
72
+ const result: Record<string, string> = {};
73
+ lines.forEach((line) => {
74
+ const idx = line.indexOf(":");
75
+ if (idx > 0) {
76
+ const key = line.substring(0, idx).trim().toLowerCase();
77
+ const val = line.substring(idx + 1).trim();
78
+ result[key] = val;
79
+ }
80
+ });
81
+ return Object.keys(result).length > 0 ? result : undefined;
82
+ }
83
+
61
84
  function normaliseHeaders(
62
85
  raw: Headers | undefined | null,
63
86
  ): Record<string, string> | undefined {
@@ -158,7 +181,7 @@ export const clearNetworkLogs = () => {
158
181
 
159
182
  export const getNetworkLogs = () => [...logs];
160
183
 
161
- let maxNetworkLogsLimit = 100;
184
+ let maxNetworkLogsLimit = 250;
162
185
 
163
186
  export const setMaxNetworkLogsLimit = (limit: number): void => {
164
187
  maxNetworkLogsLimit = Math.max(10, limit);
@@ -191,7 +214,7 @@ const addOrUpdateLog = (log: NetworkLog) => {
191
214
  if (!isNetworkModuleEnabled) return;
192
215
  const method = log.method?.toUpperCase();
193
216
 
194
- if (!ALLOWED_METHODS.includes(method)) return;
217
+ if (method && !ALLOWED_METHODS.includes(method)) return;
195
218
 
196
219
  if (shouldIgnoreUrl(log.url)) return;
197
220
 
@@ -207,19 +230,167 @@ const addOrUpdateLog = (log: NetworkLog) => {
207
230
  notify();
208
231
  };
209
232
 
233
+ let isInsideFetch = false;
234
+
210
235
  // ─── Setup ────────────────────────────────────────────────────────────────────
211
236
 
212
237
  export const setupNetworkLogger = () => {
213
238
  if ((globalThis as any).__NETWORK_LOGGER_INITIALIZED__) return;
214
239
  (globalThis as any).__NETWORK_LOGGER__ = addOrUpdateLog;
215
240
 
241
+ // 1. Hook XMLHttpRequest
242
+ const globalXHR = (globalThis as any).XMLHttpRequest;
243
+ if (globalXHR && globalXHR.prototype && !(globalThis as any).__XHR_LOGGER_INITIALIZED__) {
244
+ (globalThis as any).__XHR_LOGGER_INITIALIZED__ = true;
245
+ const originalOpen = globalXHR.prototype.open;
246
+ const originalSend = globalXHR.prototype.send;
247
+ const originalSetRequestHeader = globalXHR.prototype.setRequestHeader;
248
+
249
+ globalXHR.prototype.open = function (
250
+ method: string,
251
+ url: string | any,
252
+ async?: boolean,
253
+ user?: string | null,
254
+ password?: string | null,
255
+ ) {
256
+ this.__logMethod = (method || "GET").toUpperCase();
257
+ this.__logUrl = typeof url === "string" ? url : String(url);
258
+ this.__logRequestHeaders = {};
259
+ this.__logStartTime = Date.now();
260
+ this.__logCaller = getCallerFromStack();
261
+
262
+ return originalOpen.apply(this, [method, url, async !== false, user, password]);
263
+ };
264
+
265
+ globalXHR.prototype.setRequestHeader = function (header: string, value: string) {
266
+ if (header && value != null) {
267
+ if (!this.__logRequestHeaders) this.__logRequestHeaders = {};
268
+ this.__logRequestHeaders[header.toLowerCase()] = String(value);
269
+ }
270
+ return originalSetRequestHeader.apply(this, [header, value]);
271
+ };
272
+
273
+ globalXHR.prototype.send = function (body?: any) {
274
+ if (!isNetworkModuleEnabled || isInsideFetch || this.__inAppInspectorTracked) {
275
+ return originalSend.apply(this, [body]);
276
+ }
277
+
278
+ const url = this.__logUrl || "";
279
+ const method = this.__logMethod || "GET";
280
+
281
+ if (shouldIgnoreUrl(url)) {
282
+ return originalSend.apply(this, [body]);
283
+ }
284
+
285
+ const id = counter++;
286
+ this.__logId = id;
287
+ const start = this.__logStartTime || Date.now();
288
+ const caller = this.__logCaller || "Unknown";
289
+ const requestHeaders = this.__logRequestHeaders;
290
+
291
+ let client = "xhr";
292
+ if (
293
+ requestHeaders?.["apollographql-client-name"] ||
294
+ url.toLowerCase().includes("/graphql")
295
+ ) {
296
+ client = "apollo";
297
+ } else if (caller.toLowerCase().includes("axios")) {
298
+ client = "axios";
299
+ }
300
+
301
+ const currentRoute = currentRouteProvider ? currentRouteProvider() : null;
302
+
303
+ addOrUpdateLog({
304
+ id,
305
+ url,
306
+ method,
307
+ startTime: start,
308
+ caller,
309
+ client,
310
+ routeInfo: currentRoute || undefined,
311
+ request: method === "GET" ? undefined : parseRequestData(body),
312
+ requestHeaders:
313
+ Object.keys(requestHeaders || {}).length > 0 ? requestHeaders : undefined,
314
+ });
315
+
316
+ const onFinished = () => {
317
+ if (this.__logFinished) return;
318
+ this.__logFinished = true;
319
+ const duration = Date.now() - start;
320
+ let responseData: any = null;
321
+
322
+ try {
323
+ if (this.responseType === "" || this.responseType === "text") {
324
+ const raw = this.responseText;
325
+ try {
326
+ responseData = JSON.parse(raw);
327
+ } catch {
328
+ responseData = raw;
329
+ }
330
+ } else if (this.responseType === "json") {
331
+ responseData = this.response;
332
+ } else if (this.responseType === "blob") {
333
+ responseData = `[Blob: ${this.response?.size || 0} bytes]`;
334
+ } else {
335
+ responseData = `[${this.responseType || "Unknown"} Data]`;
336
+ }
337
+ } catch {
338
+ responseData = this.response || null;
339
+ }
340
+
341
+ const rawRespHeaders = this.getAllResponseHeaders
342
+ ? this.getAllResponseHeaders()
343
+ : "";
344
+ const responseHeaders = parseXHRResponseHeaders(rawRespHeaders);
345
+
346
+ addOrUpdateLog({
347
+ id,
348
+ url,
349
+ method,
350
+ status: this.status,
351
+ response: responseData,
352
+ duration,
353
+ startTime: start,
354
+ caller,
355
+ client,
356
+ responseHeaders,
357
+ });
358
+ };
359
+
360
+ const onErrorOrAbort = () => {
361
+ if (this.__logFinished) return;
362
+ this.__logFinished = true;
363
+ const duration = Date.now() - start;
364
+
365
+ addOrUpdateLog({
366
+ id,
367
+ url,
368
+ method,
369
+ status: this.status || 0,
370
+ response: "Network request failed",
371
+ duration,
372
+ startTime: start,
373
+ caller,
374
+ client,
375
+ });
376
+ };
377
+
378
+ this.addEventListener("load", onFinished);
379
+ this.addEventListener("error", onErrorOrAbort);
380
+ this.addEventListener("abort", onErrorOrAbort);
381
+ this.addEventListener("timeout", onErrorOrAbort);
382
+
383
+ return originalSend.apply(this, [body]);
384
+ };
385
+ }
386
+
387
+ // 2. Hook fetch
216
388
  const originalFetch = (globalThis as any).fetch;
217
389
 
218
390
  if (originalFetch) {
219
391
  (globalThis as any).fetch = async (url: any, options: any = {}) => {
220
392
  if (!isNetworkModuleEnabled) return originalFetch(url, options);
221
393
  const method = (options?.method || "GET").toUpperCase();
222
- if (!ALLOWED_METHODS.includes(method)) return originalFetch(url, options);
223
394
 
224
395
  const id = counter++;
225
396
  const start = Date.now();
@@ -229,18 +400,23 @@ export const setupNetworkLogger = () => {
229
400
 
230
401
  let caller = "Unknown";
231
402
  let requestHeaders: Record<string, string> | undefined;
232
- let client = 'fetch';
403
+ let client = "fetch";
233
404
 
234
405
  try {
235
406
  requestHeaders = normaliseHeaders(options?.headers);
236
407
  caller = getCallerFromStack(); // ✅ Capture call line
237
408
 
238
- if (requestHeaders?.['apollographql-client-name'] || finalUrl?.toLowerCase().includes('/graphql')) {
239
- client = 'apollo';
240
- } else if (requestHeaders?.['x-requested-with']?.toLowerCase().includes('xmlhttprequest')) {
241
- client = 'xhr';
242
- } else if (caller?.toLowerCase().includes('axios')) {
243
- client = 'axios';
409
+ if (
410
+ requestHeaders?.["apollographql-client-name"] ||
411
+ finalUrl?.toLowerCase().includes("/graphql")
412
+ ) {
413
+ client = "apollo";
414
+ } else if (
415
+ requestHeaders?.["x-requested-with"]?.toLowerCase().includes("xmlhttprequest")
416
+ ) {
417
+ client = "xhr";
418
+ } else if (caller?.toLowerCase().includes("axios")) {
419
+ client = "axios";
244
420
  }
245
421
 
246
422
  const currentRoute = currentRouteProvider ? currentRouteProvider() : null;
@@ -259,7 +435,13 @@ export const setupNetworkLogger = () => {
259
435
  } catch {}
260
436
 
261
437
  try {
262
- const response = await originalFetch(url, options);
438
+ isInsideFetch = true;
439
+ let response: any;
440
+ try {
441
+ response = await originalFetch(url, options);
442
+ } finally {
443
+ isInsideFetch = false;
444
+ }
263
445
  const duration = Date.now() - start;
264
446
 
265
447
  try {
@@ -317,7 +499,7 @@ export const setupNetworkLogger = () => {
317
499
  };
318
500
  }
319
501
 
320
- // Hook Axios — patches both the default instance and any future axios.create() instances
502
+ // 3. Hook Axios — patches default instance and future axios.create() instances
321
503
  try {
322
504
  if (axios) {
323
505
  addAxiosInterceptors(axios);
@@ -331,7 +513,7 @@ export const setupNetworkLogger = () => {
331
513
  }
332
514
  }
333
515
  } catch (_e) {
334
- // Axios not available — fetch-only mode
516
+ // Axios not available — fetch/XHR mode
335
517
  }
336
518
 
337
519
  try {
@@ -345,7 +527,6 @@ export const setupNetworkLogger = () => {
345
527
  export const addAxiosInterceptors = (axiosInstance: any) => {
346
528
  axiosInstance.interceptors.request.use(async (config: any) => {
347
529
  const method = (config.method || "GET").toUpperCase();
348
- if (!ALLOWED_METHODS.includes(method)) return config;
349
530
 
350
531
  const id = counter++;
351
532
  const start = Date.now();
@@ -369,7 +550,7 @@ export const addAxiosInterceptors = (axiosInstance: any) => {
369
550
  method,
370
551
  startTime: start,
371
552
  caller,
372
- client: 'axios',
553
+ client: "axios",
373
554
  routeInfo: currentRoute || undefined,
374
555
  request: method === "GET" ? undefined : parseRequestData(config.data),
375
556
  requestHeaders: normaliseHeaders(config.headers),
@@ -386,7 +567,7 @@ export const addAxiosInterceptors = (axiosInstance: any) => {
386
567
  const caller = config.__logCaller;
387
568
  const method = (config.method || "GET").toUpperCase();
388
569
 
389
- if (id == null || !ALLOWED_METHODS.includes(method)) return response;
570
+ if (id == null) return response;
390
571
 
391
572
  let url = config.url ?? "";
392
573
  if (!url.startsWith("http")) url = `${config.baseURL ?? ""}${url}`;
@@ -400,7 +581,7 @@ export const addAxiosInterceptors = (axiosInstance: any) => {
400
581
  startTime: start || Date.now(),
401
582
  duration: start != null ? Date.now() - start : undefined,
402
583
  caller,
403
- client: 'axios',
584
+ client: "axios",
404
585
  responseHeaders: normaliseHeaders(response.headers),
405
586
  });
406
587
 
@@ -413,7 +594,7 @@ export const addAxiosInterceptors = (axiosInstance: any) => {
413
594
  const caller = config.__logCaller;
414
595
  const method = (config.method || "GET").toUpperCase();
415
596
 
416
- if (id != null && ALLOWED_METHODS.includes(method)) {
597
+ if (id != null) {
417
598
  let url = config.url ?? "";
418
599
  if (!url.startsWith("http")) url = `${config.baseURL ?? ""}${url}`;
419
600
 
@@ -426,7 +607,7 @@ export const addAxiosInterceptors = (axiosInstance: any) => {
426
607
  startTime: start || Date.now(),
427
608
  duration: start != null ? Date.now() - start : undefined,
428
609
  caller,
429
- client: 'axios',
610
+ client: "axios",
430
611
  responseHeaders: normaliseHeaders(error.response?.headers),
431
612
  });
432
613
  }
@@ -434,3 +615,10 @@ export const addAxiosInterceptors = (axiosInstance: any) => {
434
615
  },
435
616
  );
436
617
  };
618
+
619
+ // Auto-initialize logger on module load so startup requests are never missed
620
+ if (typeof globalThis !== "undefined") {
621
+ try {
622
+ setupNetworkLogger();
623
+ } catch {}
624
+ }
@@ -24,6 +24,7 @@ import {
24
24
  } from '../types';
25
25
  export * from './searchQueryParser';
26
26
  export * from './memoryManager';
27
+ export * from './toast';
27
28
 
28
29
  /**
29
30
  * Returns true if running in local debug environment (connected to Metro/dev server, __DEV__ is true).