@rejourneyco/react-native 1.0.0

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 (152) hide show
  1. package/android/build.gradle.kts +135 -0
  2. package/android/consumer-rules.pro +10 -0
  3. package/android/proguard-rules.pro +1 -0
  4. package/android/src/main/AndroidManifest.xml +15 -0
  5. package/android/src/main/java/com/rejourney/RejourneyModuleImpl.kt +2981 -0
  6. package/android/src/main/java/com/rejourney/capture/ANRHandler.kt +206 -0
  7. package/android/src/main/java/com/rejourney/capture/ActivityTracker.kt +98 -0
  8. package/android/src/main/java/com/rejourney/capture/CaptureEngine.kt +1553 -0
  9. package/android/src/main/java/com/rejourney/capture/CaptureHeuristics.kt +375 -0
  10. package/android/src/main/java/com/rejourney/capture/CrashHandler.kt +153 -0
  11. package/android/src/main/java/com/rejourney/capture/MotionEvent.kt +215 -0
  12. package/android/src/main/java/com/rejourney/capture/SegmentUploader.kt +512 -0
  13. package/android/src/main/java/com/rejourney/capture/VideoEncoder.kt +773 -0
  14. package/android/src/main/java/com/rejourney/capture/ViewHierarchyScanner.kt +633 -0
  15. package/android/src/main/java/com/rejourney/capture/ViewSerializer.kt +286 -0
  16. package/android/src/main/java/com/rejourney/core/Constants.kt +117 -0
  17. package/android/src/main/java/com/rejourney/core/Logger.kt +93 -0
  18. package/android/src/main/java/com/rejourney/core/Types.kt +124 -0
  19. package/android/src/main/java/com/rejourney/lifecycle/SessionLifecycleService.kt +162 -0
  20. package/android/src/main/java/com/rejourney/network/DeviceAuthManager.kt +747 -0
  21. package/android/src/main/java/com/rejourney/network/HttpClientProvider.kt +16 -0
  22. package/android/src/main/java/com/rejourney/network/NetworkMonitor.kt +272 -0
  23. package/android/src/main/java/com/rejourney/network/UploadManager.kt +1363 -0
  24. package/android/src/main/java/com/rejourney/network/UploadWorker.kt +492 -0
  25. package/android/src/main/java/com/rejourney/privacy/PrivacyMask.kt +645 -0
  26. package/android/src/main/java/com/rejourney/touch/GestureClassifier.kt +233 -0
  27. package/android/src/main/java/com/rejourney/touch/KeyboardTracker.kt +158 -0
  28. package/android/src/main/java/com/rejourney/touch/TextInputTracker.kt +181 -0
  29. package/android/src/main/java/com/rejourney/touch/TouchInterceptor.kt +591 -0
  30. package/android/src/main/java/com/rejourney/utils/EventBuffer.kt +284 -0
  31. package/android/src/main/java/com/rejourney/utils/OEMDetector.kt +154 -0
  32. package/android/src/main/java/com/rejourney/utils/PerfTiming.kt +235 -0
  33. package/android/src/main/java/com/rejourney/utils/Telemetry.kt +297 -0
  34. package/android/src/main/java/com/rejourney/utils/WindowUtils.kt +84 -0
  35. package/android/src/newarch/java/com/rejourney/RejourneyModule.kt +187 -0
  36. package/android/src/newarch/java/com/rejourney/RejourneyPackage.kt +40 -0
  37. package/android/src/oldarch/java/com/rejourney/RejourneyModule.kt +218 -0
  38. package/android/src/oldarch/java/com/rejourney/RejourneyPackage.kt +23 -0
  39. package/ios/Capture/RJANRHandler.h +42 -0
  40. package/ios/Capture/RJANRHandler.m +328 -0
  41. package/ios/Capture/RJCaptureEngine.h +275 -0
  42. package/ios/Capture/RJCaptureEngine.m +2062 -0
  43. package/ios/Capture/RJCaptureHeuristics.h +80 -0
  44. package/ios/Capture/RJCaptureHeuristics.m +903 -0
  45. package/ios/Capture/RJCrashHandler.h +46 -0
  46. package/ios/Capture/RJCrashHandler.m +313 -0
  47. package/ios/Capture/RJMotionEvent.h +183 -0
  48. package/ios/Capture/RJMotionEvent.m +183 -0
  49. package/ios/Capture/RJPerformanceManager.h +100 -0
  50. package/ios/Capture/RJPerformanceManager.m +373 -0
  51. package/ios/Capture/RJPixelBufferDownscaler.h +42 -0
  52. package/ios/Capture/RJPixelBufferDownscaler.m +85 -0
  53. package/ios/Capture/RJSegmentUploader.h +146 -0
  54. package/ios/Capture/RJSegmentUploader.m +778 -0
  55. package/ios/Capture/RJVideoEncoder.h +247 -0
  56. package/ios/Capture/RJVideoEncoder.m +1036 -0
  57. package/ios/Capture/RJViewControllerTracker.h +73 -0
  58. package/ios/Capture/RJViewControllerTracker.m +508 -0
  59. package/ios/Capture/RJViewHierarchyScanner.h +215 -0
  60. package/ios/Capture/RJViewHierarchyScanner.m +1464 -0
  61. package/ios/Capture/RJViewSerializer.h +119 -0
  62. package/ios/Capture/RJViewSerializer.m +498 -0
  63. package/ios/Core/RJConstants.h +124 -0
  64. package/ios/Core/RJConstants.m +88 -0
  65. package/ios/Core/RJLifecycleManager.h +85 -0
  66. package/ios/Core/RJLifecycleManager.m +308 -0
  67. package/ios/Core/RJLogger.h +61 -0
  68. package/ios/Core/RJLogger.m +211 -0
  69. package/ios/Core/RJTypes.h +176 -0
  70. package/ios/Core/RJTypes.m +66 -0
  71. package/ios/Core/Rejourney.h +64 -0
  72. package/ios/Core/Rejourney.mm +2495 -0
  73. package/ios/Network/RJDeviceAuthManager.h +94 -0
  74. package/ios/Network/RJDeviceAuthManager.m +967 -0
  75. package/ios/Network/RJNetworkMonitor.h +68 -0
  76. package/ios/Network/RJNetworkMonitor.m +267 -0
  77. package/ios/Network/RJRetryManager.h +73 -0
  78. package/ios/Network/RJRetryManager.m +325 -0
  79. package/ios/Network/RJUploadManager.h +267 -0
  80. package/ios/Network/RJUploadManager.m +2296 -0
  81. package/ios/Privacy/RJPrivacyMask.h +163 -0
  82. package/ios/Privacy/RJPrivacyMask.m +922 -0
  83. package/ios/Rejourney.h +63 -0
  84. package/ios/Touch/RJGestureClassifier.h +130 -0
  85. package/ios/Touch/RJGestureClassifier.m +333 -0
  86. package/ios/Touch/RJTouchInterceptor.h +169 -0
  87. package/ios/Touch/RJTouchInterceptor.m +772 -0
  88. package/ios/Utils/RJEventBuffer.h +112 -0
  89. package/ios/Utils/RJEventBuffer.m +358 -0
  90. package/ios/Utils/RJGzipUtils.h +33 -0
  91. package/ios/Utils/RJGzipUtils.m +89 -0
  92. package/ios/Utils/RJKeychainManager.h +48 -0
  93. package/ios/Utils/RJKeychainManager.m +111 -0
  94. package/ios/Utils/RJPerfTiming.h +209 -0
  95. package/ios/Utils/RJPerfTiming.m +264 -0
  96. package/ios/Utils/RJTelemetry.h +92 -0
  97. package/ios/Utils/RJTelemetry.m +320 -0
  98. package/ios/Utils/RJWindowUtils.h +66 -0
  99. package/ios/Utils/RJWindowUtils.m +133 -0
  100. package/lib/commonjs/NativeRejourney.js +40 -0
  101. package/lib/commonjs/components/Mask.js +79 -0
  102. package/lib/commonjs/index.js +1381 -0
  103. package/lib/commonjs/sdk/autoTracking.js +1259 -0
  104. package/lib/commonjs/sdk/constants.js +151 -0
  105. package/lib/commonjs/sdk/errorTracking.js +199 -0
  106. package/lib/commonjs/sdk/index.js +50 -0
  107. package/lib/commonjs/sdk/metricsTracking.js +204 -0
  108. package/lib/commonjs/sdk/navigation.js +151 -0
  109. package/lib/commonjs/sdk/networkInterceptor.js +412 -0
  110. package/lib/commonjs/sdk/utils.js +363 -0
  111. package/lib/commonjs/types/expo-router.d.js +2 -0
  112. package/lib/commonjs/types/index.js +2 -0
  113. package/lib/module/NativeRejourney.js +38 -0
  114. package/lib/module/components/Mask.js +72 -0
  115. package/lib/module/index.js +1284 -0
  116. package/lib/module/sdk/autoTracking.js +1233 -0
  117. package/lib/module/sdk/constants.js +145 -0
  118. package/lib/module/sdk/errorTracking.js +189 -0
  119. package/lib/module/sdk/index.js +12 -0
  120. package/lib/module/sdk/metricsTracking.js +187 -0
  121. package/lib/module/sdk/navigation.js +143 -0
  122. package/lib/module/sdk/networkInterceptor.js +401 -0
  123. package/lib/module/sdk/utils.js +342 -0
  124. package/lib/module/types/expo-router.d.js +2 -0
  125. package/lib/module/types/index.js +2 -0
  126. package/lib/typescript/NativeRejourney.d.ts +147 -0
  127. package/lib/typescript/components/Mask.d.ts +39 -0
  128. package/lib/typescript/index.d.ts +117 -0
  129. package/lib/typescript/sdk/autoTracking.d.ts +204 -0
  130. package/lib/typescript/sdk/constants.d.ts +120 -0
  131. package/lib/typescript/sdk/errorTracking.d.ts +32 -0
  132. package/lib/typescript/sdk/index.d.ts +9 -0
  133. package/lib/typescript/sdk/metricsTracking.d.ts +58 -0
  134. package/lib/typescript/sdk/navigation.d.ts +33 -0
  135. package/lib/typescript/sdk/networkInterceptor.d.ts +47 -0
  136. package/lib/typescript/sdk/utils.d.ts +148 -0
  137. package/lib/typescript/types/index.d.ts +624 -0
  138. package/package.json +102 -0
  139. package/rejourney.podspec +21 -0
  140. package/src/NativeRejourney.ts +165 -0
  141. package/src/components/Mask.tsx +80 -0
  142. package/src/index.ts +1459 -0
  143. package/src/sdk/autoTracking.ts +1373 -0
  144. package/src/sdk/constants.ts +134 -0
  145. package/src/sdk/errorTracking.ts +231 -0
  146. package/src/sdk/index.ts +11 -0
  147. package/src/sdk/metricsTracking.ts +232 -0
  148. package/src/sdk/navigation.ts +157 -0
  149. package/src/sdk/networkInterceptor.ts +440 -0
  150. package/src/sdk/utils.ts +369 -0
  151. package/src/types/expo-router.d.ts +7 -0
  152. package/src/types/index.ts +739 -0
@@ -0,0 +1,401 @@
1
+ /**
2
+ * Network Interceptor for Rejourney - Optimized Version
3
+ *
4
+ * Automatically intercepts fetch() and XMLHttpRequest to log API calls.
5
+ *
6
+ * PERFORMANCE OPTIMIZATIONS:
7
+ * - Minimal synchronous overhead (just captures timing, no processing)
8
+ * - Batched async logging (doesn't block requests)
9
+ * - Circular buffer with max size limit
10
+ * - Sampling for high-frequency endpoints
11
+ * - No string allocations in hot path
12
+ * - Lazy URL parsing
13
+ * - PII Scrubbing for query parameters
14
+ */
15
+
16
+ // Store original implementations
17
+ let originalFetch = null;
18
+ let originalXHROpen = null;
19
+ let originalXHRSend = null;
20
+
21
+ // Callback to log network requests (called asynchronously)
22
+ let logCallback = null;
23
+
24
+ // Pending requests buffer (circular buffer for memory efficiency)
25
+ const MAX_PENDING_REQUESTS = 100;
26
+ const pendingRequests = new Array(MAX_PENDING_REQUESTS).fill(null);
27
+ let pendingHead = 0;
28
+ let pendingTail = 0;
29
+ let pendingCount = 0;
30
+
31
+ // Flush timer
32
+ let flushTimer = null;
33
+ const FLUSH_INTERVAL = 500; // Flush every 500ms
34
+
35
+ // Sampling for high-frequency endpoints
36
+ const endpointCounts = new Map();
37
+ const SAMPLE_WINDOW = 10000; // 10 second window
38
+ const MAX_PER_ENDPOINT = 20; // Max 20 requests per endpoint per window
39
+
40
+ // Configuration
41
+ const config = {
42
+ enabled: true,
43
+ ignorePatterns: [],
44
+ // Simple string patterns for fast matching
45
+ maxUrlLength: 300,
46
+ // Shorter for efficiency
47
+ captureSizes: false // Disabled by default for performance
48
+ };
49
+
50
+ // PII Scrubbing - Sensitive keys to look for in query params
51
+ const SENSITIVE_KEYS = ['token', 'key', 'secret', 'password', 'auth', 'access_token', 'api_key'];
52
+
53
+ /**
54
+ * Scrub sensitive data from URL
55
+ */
56
+ function scrubUrl(url) {
57
+ try {
58
+ // Fast check if URL might contain params
59
+ if (url.indexOf('?') === -1) return url;
60
+ const urlObj = new URL(url);
61
+ let modified = false;
62
+ SENSITIVE_KEYS.forEach(key => {
63
+ if (urlObj.searchParams.has(key)) {
64
+ urlObj.searchParams.set(key, '[REDACTED]');
65
+ modified = true;
66
+ }
67
+ });
68
+
69
+ // Also scan for partial matches (case-insensitive) if strict scrubbing needed
70
+ // But for performance, we stick to exact keys or common variations
71
+
72
+ return modified ? urlObj.toString() : url;
73
+ } catch {
74
+ // If URL parsing fails (relative URL?), try primitive replacement
75
+ let scrubbed = url;
76
+ SENSITIVE_KEYS.forEach(key => {
77
+ const regex = new RegExp(`([?&])${key}=[^&]*`, 'gi');
78
+ scrubbed = scrubbed.replace(regex, `$1${key}=[REDACTED]`);
79
+ });
80
+ return scrubbed;
81
+ }
82
+ }
83
+
84
+ /**
85
+ * Fast check if URL should be ignored (no regex for speed)
86
+ */
87
+ function shouldIgnoreUrl(url) {
88
+ const patterns = config.ignorePatterns;
89
+ for (let i = 0; i < patterns.length; i++) {
90
+ const pattern = patterns[i];
91
+ if (pattern && url.indexOf(pattern) !== -1) return true;
92
+ }
93
+ return false;
94
+ }
95
+
96
+ /**
97
+ * Check if we should sample this request (rate limiting per endpoint)
98
+ */
99
+ function shouldSampleRequest(urlPath) {
100
+ const now = Date.now();
101
+ let entry = endpointCounts.get(urlPath);
102
+ if (!entry || now - entry.lastReset > SAMPLE_WINDOW) {
103
+ entry = {
104
+ count: 0,
105
+ lastReset: now
106
+ };
107
+ endpointCounts.set(urlPath, entry);
108
+ }
109
+ entry.count++;
110
+ return entry.count <= MAX_PER_ENDPOINT;
111
+ }
112
+
113
+ /**
114
+ * Add request to pending buffer (non-blocking)
115
+ */
116
+ function queueRequest(request) {
117
+ if (pendingCount >= MAX_PENDING_REQUESTS) {
118
+ // Buffer full, drop oldest
119
+ pendingHead = (pendingHead + 1) % MAX_PENDING_REQUESTS;
120
+ pendingCount--;
121
+ }
122
+
123
+ // Scrub URL before queuing
124
+ request.url = scrubUrl(request.url);
125
+ pendingRequests[pendingTail] = request;
126
+ pendingTail = (pendingTail + 1) % MAX_PENDING_REQUESTS;
127
+ pendingCount++;
128
+
129
+ // Schedule flush if not already scheduled
130
+ if (!flushTimer) {
131
+ flushTimer = setTimeout(flushPendingRequests, FLUSH_INTERVAL);
132
+ }
133
+ }
134
+
135
+ /**
136
+ * Flush pending requests to callback
137
+ */
138
+ function flushPendingRequests() {
139
+ flushTimer = null;
140
+ if (!logCallback || pendingCount === 0) return;
141
+
142
+ // Process all pending requests
143
+ while (pendingCount > 0) {
144
+ const request = pendingRequests[pendingHead];
145
+ pendingRequests[pendingHead] = null; // Allow GC
146
+ pendingHead = (pendingHead + 1) % MAX_PENDING_REQUESTS;
147
+ pendingCount--;
148
+ if (request) {
149
+ try {
150
+ logCallback(request);
151
+ } catch {
152
+ // Ignore logging errors
153
+ }
154
+ }
155
+ }
156
+ }
157
+
158
+ /**
159
+ * Parse URL efficiently (only extract what we need)
160
+ */
161
+ function parseUrlFast(url) {
162
+ // Fast path for common patterns
163
+ let hostEnd = -1;
164
+ let pathStart = -1;
165
+
166
+ // Find ://
167
+ const protoEnd = url.indexOf('://');
168
+ if (protoEnd !== -1) {
169
+ const afterProto = protoEnd + 3;
170
+ // Find end of host (first / after ://)
171
+ const slashPos = url.indexOf('/', afterProto);
172
+ if (slashPos !== -1) {
173
+ hostEnd = slashPos;
174
+ pathStart = slashPos;
175
+ } else {
176
+ hostEnd = url.length;
177
+ pathStart = url.length;
178
+ }
179
+ return {
180
+ host: url.substring(afterProto, hostEnd),
181
+ path: pathStart < url.length ? url.substring(pathStart) : '/'
182
+ };
183
+ }
184
+
185
+ // Relative URL
186
+ return {
187
+ host: '',
188
+ path: url
189
+ };
190
+ }
191
+
192
+ /**
193
+ * Intercept fetch - minimal overhead version
194
+ */
195
+ function interceptFetch() {
196
+ if (typeof globalThis.fetch === 'undefined') return;
197
+ if (originalFetch) return;
198
+ originalFetch = globalThis.fetch;
199
+ globalThis.fetch = function optimizedFetch(input, init) {
200
+ // Fast path: if disabled or no callback, skip entirely
201
+ if (!config.enabled || !logCallback) {
202
+ return originalFetch(input, init);
203
+ }
204
+
205
+ // Extract URL string (minimal work)
206
+ const url = typeof input === 'string' ? input : input instanceof URL ? input.href : input.url;
207
+
208
+ // Fast ignore check
209
+ if (shouldIgnoreUrl(url)) {
210
+ return originalFetch(input, init);
211
+ }
212
+
213
+ // Parse URL and check sampling
214
+ const {
215
+ path
216
+ } = parseUrlFast(url);
217
+ if (!shouldSampleRequest(path)) {
218
+ return originalFetch(input, init);
219
+ }
220
+
221
+ // Capture start time (only synchronous work)
222
+ const startTime = Date.now();
223
+ const method = (init?.method || 'GET').toUpperCase();
224
+
225
+ // Call original fetch
226
+ return originalFetch(input, init).then(response => {
227
+ // Success - queue the log asynchronously
228
+ queueRequest({
229
+ requestId: `f${startTime}`,
230
+ method,
231
+ url: url.length > config.maxUrlLength ? url.substring(0, config.maxUrlLength) : url,
232
+ statusCode: response.status,
233
+ duration: Date.now() - startTime,
234
+ startTimestamp: startTime,
235
+ endTimestamp: Date.now(),
236
+ success: response.ok
237
+ });
238
+ return response;
239
+ }, error => {
240
+ // Error - queue the log asynchronously
241
+ queueRequest({
242
+ requestId: `f${startTime}`,
243
+ method,
244
+ url: url.length > config.maxUrlLength ? url.substring(0, config.maxUrlLength) : url,
245
+ statusCode: 0,
246
+ duration: Date.now() - startTime,
247
+ startTimestamp: startTime,
248
+ endTimestamp: Date.now(),
249
+ success: false,
250
+ errorMessage: error?.message || 'Network error'
251
+ });
252
+ throw error;
253
+ });
254
+ };
255
+ }
256
+
257
+ /**
258
+ * Intercept XMLHttpRequest - minimal overhead version
259
+ */
260
+ function interceptXHR() {
261
+ if (typeof XMLHttpRequest === 'undefined') return;
262
+ if (originalXHROpen) return;
263
+ originalXHROpen = XMLHttpRequest.prototype.open;
264
+ originalXHRSend = XMLHttpRequest.prototype.send;
265
+ XMLHttpRequest.prototype.open = function (method, url, async = true, username, password) {
266
+ const urlString = typeof url === 'string' ? url : url.toString();
267
+
268
+ // Store minimal info
269
+ this.__rj = {
270
+ m: method.toUpperCase(),
271
+ u: urlString,
272
+ t: 0
273
+ };
274
+ return originalXHROpen.call(this, method, urlString, async, username, password);
275
+ };
276
+ XMLHttpRequest.prototype.send = function (body) {
277
+ const data = this.__rj;
278
+ if (!config.enabled || !logCallback || !data || shouldIgnoreUrl(data.u)) {
279
+ return originalXHRSend.call(this, body);
280
+ }
281
+
282
+ // Check sampling
283
+ const {
284
+ path
285
+ } = parseUrlFast(data.u);
286
+ if (!shouldSampleRequest(path)) {
287
+ return originalXHRSend.call(this, body);
288
+ }
289
+ data.t = Date.now();
290
+ const onComplete = () => {
291
+ const endTime = Date.now();
292
+ queueRequest({
293
+ requestId: `x${data.t}`,
294
+ method: data.m,
295
+ url: data.u.length > config.maxUrlLength ? data.u.substring(0, config.maxUrlLength) : data.u,
296
+ statusCode: this.status,
297
+ duration: endTime - data.t,
298
+ startTimestamp: data.t,
299
+ endTimestamp: endTime,
300
+ success: this.status >= 200 && this.status < 400,
301
+ errorMessage: this.status === 0 ? 'Network error' : undefined
302
+ });
303
+ };
304
+
305
+ // Use load/error events (more efficient than readystatechange)
306
+ // Note: We use basic addEventListener without options for RN compatibility
307
+ this.addEventListener('load', onComplete);
308
+ this.addEventListener('error', onComplete);
309
+ this.addEventListener('abort', onComplete);
310
+ return originalXHRSend.call(this, body);
311
+ };
312
+ }
313
+
314
+ /**
315
+ * Initialize network interception
316
+ */
317
+ export function initNetworkInterceptor(callback, options) {
318
+ logCallback = callback;
319
+
320
+ // Convert patterns to simple strings for fast matching
321
+ if (options?.ignoreUrls) {
322
+ config.ignorePatterns = options.ignoreUrls.filter(p => typeof p === 'string');
323
+ // Note: RegExp patterns are not supported in optimized version for performance
324
+ }
325
+ if (options?.captureSizes !== undefined) {
326
+ config.captureSizes = options.captureSizes;
327
+ }
328
+ interceptFetch();
329
+ interceptXHR();
330
+ }
331
+
332
+ /**
333
+ * Disable network interception
334
+ */
335
+ export function disableNetworkInterceptor() {
336
+ config.enabled = false;
337
+
338
+ // Flush any pending requests
339
+ if (flushTimer) {
340
+ clearTimeout(flushTimer);
341
+ flushTimer = null;
342
+ }
343
+ flushPendingRequests();
344
+ }
345
+
346
+ /**
347
+ * Re-enable network interception
348
+ */
349
+ export function enableNetworkInterceptor() {
350
+ config.enabled = true;
351
+ }
352
+
353
+ /**
354
+ * Force flush pending requests (call before app termination)
355
+ */
356
+ export function flushNetworkRequests() {
357
+ if (flushTimer) {
358
+ clearTimeout(flushTimer);
359
+ flushTimer = null;
360
+ }
361
+ flushPendingRequests();
362
+ }
363
+
364
+ /**
365
+ * Restore original fetch and XHR
366
+ */
367
+ export function restoreNetworkInterceptor() {
368
+ if (originalFetch) {
369
+ globalThis.fetch = originalFetch;
370
+ originalFetch = null;
371
+ }
372
+ if (originalXHROpen && originalXHRSend) {
373
+ XMLHttpRequest.prototype.open = originalXHROpen;
374
+ XMLHttpRequest.prototype.send = originalXHRSend;
375
+ originalXHROpen = null;
376
+ originalXHRSend = null;
377
+ }
378
+ logCallback = null;
379
+
380
+ // Clear state
381
+ pendingHead = 0;
382
+ pendingTail = 0;
383
+ pendingCount = 0;
384
+ endpointCounts.clear();
385
+ if (flushTimer) {
386
+ clearTimeout(flushTimer);
387
+ flushTimer = null;
388
+ }
389
+ }
390
+
391
+ /**
392
+ * Get stats for debugging
393
+ */
394
+ export function getNetworkInterceptorStats() {
395
+ return {
396
+ pendingCount,
397
+ endpointCount: endpointCounts.size,
398
+ enabled: config.enabled
399
+ };
400
+ }
401
+ //# sourceMappingURL=networkInterceptor.js.map