@rejourneyco/react-native 1.0.7

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 (105) hide show
  1. package/README.md +29 -0
  2. package/android/build.gradle.kts +135 -0
  3. package/android/consumer-rules.pro +10 -0
  4. package/android/proguard-rules.pro +1 -0
  5. package/android/src/main/AndroidManifest.xml +15 -0
  6. package/android/src/main/java/com/rejourney/RejourneyModuleImpl.kt +860 -0
  7. package/android/src/main/java/com/rejourney/engine/DeviceRegistrar.kt +290 -0
  8. package/android/src/main/java/com/rejourney/engine/DiagnosticLog.kt +385 -0
  9. package/android/src/main/java/com/rejourney/engine/RejourneyImpl.kt +512 -0
  10. package/android/src/main/java/com/rejourney/platform/OEMDetector.kt +173 -0
  11. package/android/src/main/java/com/rejourney/platform/PerfTiming.kt +384 -0
  12. package/android/src/main/java/com/rejourney/platform/SessionLifecycleService.kt +160 -0
  13. package/android/src/main/java/com/rejourney/platform/Telemetry.kt +301 -0
  14. package/android/src/main/java/com/rejourney/platform/WindowUtils.kt +100 -0
  15. package/android/src/main/java/com/rejourney/recording/AnrSentinel.kt +129 -0
  16. package/android/src/main/java/com/rejourney/recording/EventBuffer.kt +330 -0
  17. package/android/src/main/java/com/rejourney/recording/InteractionRecorder.kt +519 -0
  18. package/android/src/main/java/com/rejourney/recording/ReplayOrchestrator.kt +740 -0
  19. package/android/src/main/java/com/rejourney/recording/SegmentDispatcher.kt +559 -0
  20. package/android/src/main/java/com/rejourney/recording/StabilityMonitor.kt +238 -0
  21. package/android/src/main/java/com/rejourney/recording/TelemetryPipeline.kt +633 -0
  22. package/android/src/main/java/com/rejourney/recording/ViewHierarchyScanner.kt +232 -0
  23. package/android/src/main/java/com/rejourney/recording/VisualCapture.kt +474 -0
  24. package/android/src/main/java/com/rejourney/utility/DataCompression.kt +63 -0
  25. package/android/src/main/java/com/rejourney/utility/ImageBlur.kt +412 -0
  26. package/android/src/main/java/com/rejourney/utility/ViewIdentifier.kt +169 -0
  27. package/android/src/newarch/java/com/rejourney/RejourneyModule.kt +232 -0
  28. package/android/src/newarch/java/com/rejourney/RejourneyPackage.kt +40 -0
  29. package/android/src/oldarch/java/com/rejourney/RejourneyModule.kt +268 -0
  30. package/android/src/oldarch/java/com/rejourney/RejourneyPackage.kt +23 -0
  31. package/ios/Engine/DeviceRegistrar.swift +288 -0
  32. package/ios/Engine/DiagnosticLog.swift +387 -0
  33. package/ios/Engine/RejourneyImpl.swift +719 -0
  34. package/ios/Recording/AnrSentinel.swift +142 -0
  35. package/ios/Recording/EventBuffer.swift +326 -0
  36. package/ios/Recording/InteractionRecorder.swift +428 -0
  37. package/ios/Recording/ReplayOrchestrator.swift +624 -0
  38. package/ios/Recording/SegmentDispatcher.swift +492 -0
  39. package/ios/Recording/StabilityMonitor.swift +223 -0
  40. package/ios/Recording/TelemetryPipeline.swift +547 -0
  41. package/ios/Recording/ViewHierarchyScanner.swift +156 -0
  42. package/ios/Recording/VisualCapture.swift +675 -0
  43. package/ios/Rejourney.h +38 -0
  44. package/ios/Rejourney.mm +375 -0
  45. package/ios/Utility/DataCompression.swift +55 -0
  46. package/ios/Utility/ImageBlur.swift +89 -0
  47. package/ios/Utility/RuntimeMethodSwap.swift +41 -0
  48. package/ios/Utility/ViewIdentifier.swift +37 -0
  49. package/lib/commonjs/NativeRejourney.js +40 -0
  50. package/lib/commonjs/components/Mask.js +88 -0
  51. package/lib/commonjs/index.js +1443 -0
  52. package/lib/commonjs/sdk/autoTracking.js +1087 -0
  53. package/lib/commonjs/sdk/constants.js +166 -0
  54. package/lib/commonjs/sdk/errorTracking.js +187 -0
  55. package/lib/commonjs/sdk/index.js +50 -0
  56. package/lib/commonjs/sdk/metricsTracking.js +205 -0
  57. package/lib/commonjs/sdk/navigation.js +128 -0
  58. package/lib/commonjs/sdk/networkInterceptor.js +375 -0
  59. package/lib/commonjs/sdk/utils.js +433 -0
  60. package/lib/commonjs/sdk/version.js +13 -0
  61. package/lib/commonjs/types/expo-router.d.js +2 -0
  62. package/lib/commonjs/types/index.js +2 -0
  63. package/lib/module/NativeRejourney.js +38 -0
  64. package/lib/module/components/Mask.js +83 -0
  65. package/lib/module/index.js +1341 -0
  66. package/lib/module/sdk/autoTracking.js +1059 -0
  67. package/lib/module/sdk/constants.js +154 -0
  68. package/lib/module/sdk/errorTracking.js +177 -0
  69. package/lib/module/sdk/index.js +26 -0
  70. package/lib/module/sdk/metricsTracking.js +187 -0
  71. package/lib/module/sdk/navigation.js +120 -0
  72. package/lib/module/sdk/networkInterceptor.js +364 -0
  73. package/lib/module/sdk/utils.js +412 -0
  74. package/lib/module/sdk/version.js +7 -0
  75. package/lib/module/types/expo-router.d.js +2 -0
  76. package/lib/module/types/index.js +2 -0
  77. package/lib/typescript/NativeRejourney.d.ts +160 -0
  78. package/lib/typescript/components/Mask.d.ts +54 -0
  79. package/lib/typescript/index.d.ts +117 -0
  80. package/lib/typescript/sdk/autoTracking.d.ts +226 -0
  81. package/lib/typescript/sdk/constants.d.ts +138 -0
  82. package/lib/typescript/sdk/errorTracking.d.ts +47 -0
  83. package/lib/typescript/sdk/index.d.ts +24 -0
  84. package/lib/typescript/sdk/metricsTracking.d.ts +75 -0
  85. package/lib/typescript/sdk/navigation.d.ts +48 -0
  86. package/lib/typescript/sdk/networkInterceptor.d.ts +62 -0
  87. package/lib/typescript/sdk/utils.d.ts +193 -0
  88. package/lib/typescript/sdk/version.d.ts +6 -0
  89. package/lib/typescript/types/index.d.ts +618 -0
  90. package/package.json +122 -0
  91. package/rejourney.podspec +23 -0
  92. package/src/NativeRejourney.ts +185 -0
  93. package/src/components/Mask.tsx +93 -0
  94. package/src/index.ts +1555 -0
  95. package/src/sdk/autoTracking.ts +1245 -0
  96. package/src/sdk/constants.ts +155 -0
  97. package/src/sdk/errorTracking.ts +231 -0
  98. package/src/sdk/index.ts +25 -0
  99. package/src/sdk/metricsTracking.ts +227 -0
  100. package/src/sdk/navigation.ts +152 -0
  101. package/src/sdk/networkInterceptor.ts +423 -0
  102. package/src/sdk/utils.ts +442 -0
  103. package/src/sdk/version.ts +6 -0
  104. package/src/types/expo-router.d.ts +7 -0
  105. package/src/types/index.ts +709 -0
@@ -0,0 +1,166 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.PRIVACY = exports.PLAYBACK_SPEEDS = exports.MEMORY_SETTINGS = exports.GESTURE_TYPES = exports.EVENT_TYPES = exports.DEFAULT_CONFIG = exports.CPU_SETTINGS = exports.CAPTURE_SETTINGS = void 0;
7
+ Object.defineProperty(exports, "SDK_VERSION", {
8
+ enumerable: true,
9
+ get: function () {
10
+ return _version.SDK_VERSION;
11
+ }
12
+ });
13
+ exports.UPLOAD_SETTINGS = exports.STORAGE_SETTINGS = void 0;
14
+ var _version = require("./version");
15
+ /**
16
+ * Copyright 2026 Rejourney
17
+ *
18
+ * Licensed under the Apache License, Version 2.0 (the "License");
19
+ * you may not use this file except in compliance with the License.
20
+ * You may obtain a copy of the License at
21
+ *
22
+ * http://www.apache.org/licenses/LICENSE-2.0
23
+ *
24
+ * Unless required by applicable law or agreed to in writing, software
25
+ * distributed under the License is distributed on an "AS IS" BASIS,
26
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
27
+ * See the License for the specific language governing permissions and
28
+ * limitations under the License.
29
+ */
30
+
31
+ /**
32
+ * Rejourney SDK Constants
33
+ */
34
+
35
+ // Import version from auto-generated file (generated from package.json by scripts/generate-version.js)
36
+
37
+ /** Default configuration values */
38
+ const DEFAULT_CONFIG = exports.DEFAULT_CONFIG = {
39
+ enabled: true,
40
+ captureFPS: 0.5,
41
+ captureOnEvents: true,
42
+ maxSessionDuration: 10 * 60 * 1000,
43
+ maxStorageSize: 50 * 1024 * 1024,
44
+ autoScreenTracking: true,
45
+ autoGestureTracking: true,
46
+ privacyOcclusion: true,
47
+ enableCompression: true,
48
+ inactivityThreshold: 5000,
49
+ disableInDev: false,
50
+ detectRageTaps: true,
51
+ detectDeadTaps: true,
52
+ rageTapThreshold: 3,
53
+ rageTapTimeWindow: 1000,
54
+ debug: false,
55
+ autoStartRecording: true,
56
+ collectDeviceInfo: true,
57
+ collectGeoLocation: true,
58
+ postNavigationDelay: 300,
59
+ postGestureDelay: 200,
60
+ postModalDelay: 400
61
+ };
62
+
63
+ /** Event type constants */
64
+ const EVENT_TYPES = exports.EVENT_TYPES = {
65
+ GESTURE: 'gesture',
66
+ SCREEN_CHANGE: 'screen_change',
67
+ CUSTOM: 'custom',
68
+ APP_STATE: 'app_state',
69
+ FRUSTRATION: 'frustration',
70
+ ERROR: 'error'
71
+ };
72
+
73
+ /** Gesture type constants */
74
+ const GESTURE_TYPES = exports.GESTURE_TYPES = {
75
+ TAP: 'tap',
76
+ DOUBLE_TAP: 'double_tap',
77
+ LONG_PRESS: 'long_press',
78
+ SWIPE_LEFT: 'swipe_left',
79
+ SWIPE_RIGHT: 'swipe_right',
80
+ SWIPE_UP: 'swipe_up',
81
+ SWIPE_DOWN: 'swipe_down',
82
+ PINCH: 'pinch',
83
+ SCROLL: 'scroll',
84
+ RAGE_TAP: 'rage_tap',
85
+ DEAD_TAP: 'dead_tap'
86
+ };
87
+
88
+ /** Playback speeds */
89
+ const PLAYBACK_SPEEDS = exports.PLAYBACK_SPEEDS = [0.5, 1, 2, 4];
90
+
91
+ /** Capture settings */
92
+ const CAPTURE_SETTINGS = exports.CAPTURE_SETTINGS = {
93
+ DEFAULT_FPS: 0.5,
94
+ MIN_FPS: 0.1,
95
+ MAX_FPS: 2,
96
+ CAPTURE_SCALE: 0.25,
97
+ MIN_CAPTURE_DELTA_TIME: 0.5
98
+ };
99
+
100
+ /** Memory management settings */
101
+ const MEMORY_SETTINGS = exports.MEMORY_SETTINGS = {
102
+ /** Maximum events to keep in memory before flushing */
103
+ MAX_EVENTS_IN_MEMORY: 100,
104
+ /** Memory warning threshold in MB (flush when exceeded) */
105
+ MEMORY_WARNING_THRESHOLD_MB: 100,
106
+ /** Enable aggressive memory cleanup during low memory */
107
+ AGGRESSIVE_CLEANUP_ENABLED: true,
108
+ /** Bitmap pool size for reusing bitmaps (Android) */
109
+ BITMAP_POOL_SIZE: 3
110
+ };
111
+
112
+ /** CPU throttling settings */
113
+ const CPU_SETTINGS = exports.CPU_SETTINGS = {
114
+ /** Throttle captures when CPU usage exceeds this percentage */
115
+ CPU_THROTTLE_THRESHOLD: 80,
116
+ /** Minimum interval between captures when throttled (seconds) */
117
+ THROTTLED_MIN_INTERVAL: 2.0,
118
+ /** Skip captures when battery is below this level (0-100) */
119
+ LOW_BATTERY_THRESHOLD: 15,
120
+ /** Skip captures when device is thermally throttled */
121
+ THERMAL_THROTTLE_ENABLED: true,
122
+ /** Maximum consecutive captures before forced cooldown */
123
+ MAX_CONSECUTIVE_CAPTURES: 10,
124
+ /** Cooldown period after max consecutive captures (ms) */
125
+ CAPTURE_COOLDOWN_MS: 1000
126
+ };
127
+
128
+ /** Storage management settings */
129
+ const STORAGE_SETTINGS = exports.STORAGE_SETTINGS = {
130
+ /** Maximum total storage for session data (bytes) */
131
+ MAX_STORAGE_SIZE: 50 * 1024 * 1024,
132
+ // 50MB
133
+ /** Storage warning threshold - start cleanup at this level */
134
+ STORAGE_WARNING_THRESHOLD: 0.8,
135
+ // 80% of max
136
+ /** Number of old sessions to keep */
137
+ MAX_SESSIONS_TO_KEEP: 5,
138
+ /** Auto-delete sessions older than this (hours) */
139
+ SESSION_EXPIRY_HOURS: 24,
140
+ /** Use efficient binary storage format */
141
+ USE_BINARY_FORMAT: true
142
+ };
143
+
144
+ /** Network/Upload settings */
145
+ const UPLOAD_SETTINGS = exports.UPLOAD_SETTINGS = {
146
+ /** Batch upload interval (ms) */
147
+ BATCH_INTERVAL_MS: 30000,
148
+ // 30 seconds
149
+ /** Max retry attempts for failed uploads */
150
+ MAX_RETRY_ATTEMPTS: 3,
151
+ /** Retry delay multiplier (exponential backoff) */
152
+ RETRY_DELAY_MULTIPLIER: 2,
153
+ /** Initial retry delay (ms) */
154
+ INITIAL_RETRY_DELAY_MS: 1000,
155
+ /** Max events per upload batch */
156
+ MAX_EVENTS_PER_BATCH: 50,
157
+ /** Skip uploads when on cellular and battery is low */
158
+ CELLULAR_BATTERY_AWARE: true
159
+ };
160
+
161
+ /** Privacy constants */
162
+ const PRIVACY = exports.PRIVACY = {
163
+ OCCLUSION_COLOR: '#808080',
164
+ SENSITIVE_COMPONENT_TYPES: ['TextInput', 'SecureTextEntry', 'PasswordField']
165
+ };
166
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1,187 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.captureError = captureError;
7
+ exports.cleanupErrorTracking = cleanupErrorTracking;
8
+ exports.getErrorCount = getErrorCount;
9
+ exports.resetErrorCount = resetErrorCount;
10
+ exports.setupErrorTracking = setupErrorTracking;
11
+ /**
12
+ * Copyright 2026 Rejourney
13
+ *
14
+ * Licensed under the Apache License, Version 2.0 (the "License");
15
+ * you may not use this file except in compliance with the License.
16
+ * You may obtain a copy of the License at
17
+ *
18
+ * http://www.apache.org/licenses/LICENSE-2.0
19
+ *
20
+ * Unless required by applicable law or agreed to in writing, software
21
+ * distributed under the License is distributed on an "AS IS" BASIS,
22
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
23
+ * See the License for the specific language governing permissions and
24
+ * limitations under the License.
25
+ */
26
+
27
+ /**
28
+ * Error Tracking Module for Rejourney SDK
29
+ *
30
+ * Handles JS error capture, React Native ErrorUtils, and unhandled promise rejections.
31
+ * Split from autoTracking.ts for better code organization.
32
+ */
33
+
34
+ const _globalThis = globalThis;
35
+ let originalErrorHandler;
36
+ let originalOnError = null;
37
+ let originalOnUnhandledRejection = null;
38
+ let onErrorCallback = null;
39
+ let errorCount = 0;
40
+
41
+ /**
42
+ * Setup error tracking with the given callback
43
+ */
44
+ function setupErrorTracking(config, onError) {
45
+ onErrorCallback = onError;
46
+ errorCount = 0;
47
+ if (config.trackReactNativeErrors !== false) {
48
+ setupReactNativeErrorHandler();
49
+ }
50
+ if (config.trackJSErrors !== false && typeof _globalThis !== 'undefined') {
51
+ setupJSErrorHandler();
52
+ }
53
+ if (config.trackPromiseRejections !== false && typeof _globalThis !== 'undefined') {
54
+ setupPromiseRejectionHandler();
55
+ }
56
+ }
57
+
58
+ /**
59
+ * Cleanup error tracking and restore original handlers
60
+ */
61
+ function cleanupErrorTracking() {
62
+ if (originalErrorHandler) {
63
+ try {
64
+ const ErrorUtils = _globalThis.ErrorUtils;
65
+ if (ErrorUtils) {
66
+ ErrorUtils.setGlobalHandler(originalErrorHandler);
67
+ }
68
+ } catch {
69
+ // Ignore
70
+ }
71
+ originalErrorHandler = undefined;
72
+ }
73
+ if (originalOnError !== null) {
74
+ _globalThis.onerror = originalOnError;
75
+ originalOnError = null;
76
+ }
77
+ if (originalOnUnhandledRejection && typeof _globalThis.removeEventListener !== 'undefined') {
78
+ _globalThis.removeEventListener('unhandledrejection', originalOnUnhandledRejection);
79
+ originalOnUnhandledRejection = null;
80
+ }
81
+ onErrorCallback = null;
82
+ }
83
+
84
+ /**
85
+ * Get current error count
86
+ */
87
+ function getErrorCount() {
88
+ return errorCount;
89
+ }
90
+
91
+ /**
92
+ * Reset error count
93
+ */
94
+ function resetErrorCount() {
95
+ errorCount = 0;
96
+ }
97
+
98
+ /**
99
+ * Manually capture an error
100
+ */
101
+ function captureError(message, stack, name) {
102
+ trackError({
103
+ type: 'error',
104
+ timestamp: Date.now(),
105
+ message,
106
+ stack,
107
+ name: name || 'Error'
108
+ });
109
+ }
110
+
111
+ /**
112
+ * Track an error internally
113
+ */
114
+ function trackError(error) {
115
+ errorCount++;
116
+ if (onErrorCallback) {
117
+ onErrorCallback(error);
118
+ }
119
+ }
120
+
121
+ /**
122
+ * Setup React Native ErrorUtils handler
123
+ */
124
+ function setupReactNativeErrorHandler() {
125
+ try {
126
+ const ErrorUtils = _globalThis.ErrorUtils;
127
+ if (!ErrorUtils) return;
128
+ originalErrorHandler = ErrorUtils.getGlobalHandler();
129
+ ErrorUtils.setGlobalHandler((error, isFatal) => {
130
+ trackError({
131
+ type: 'error',
132
+ timestamp: Date.now(),
133
+ message: error.message || String(error),
134
+ stack: error.stack,
135
+ name: error.name || 'Error'
136
+ });
137
+ if (originalErrorHandler) {
138
+ originalErrorHandler(error, isFatal);
139
+ }
140
+ });
141
+ } catch {
142
+ // Ignore
143
+ }
144
+ }
145
+
146
+ /**
147
+ * Setup global JS error handler
148
+ */
149
+ function setupJSErrorHandler() {
150
+ if (typeof _globalThis.onerror !== 'undefined') {
151
+ originalOnError = _globalThis.onerror;
152
+ _globalThis.onerror = (message, source, lineno, colno, error) => {
153
+ trackError({
154
+ type: 'error',
155
+ timestamp: Date.now(),
156
+ message: typeof message === 'string' ? message : 'Unknown error',
157
+ stack: error?.stack || `${source}:${lineno}:${colno}`,
158
+ name: error?.name || 'Error'
159
+ });
160
+ if (originalOnError) {
161
+ return originalOnError(message, source, lineno, colno, error);
162
+ }
163
+ return false;
164
+ };
165
+ }
166
+ }
167
+
168
+ /**
169
+ * Setup unhandled promise rejection handler
170
+ */
171
+ function setupPromiseRejectionHandler() {
172
+ if (typeof _globalThis.addEventListener !== 'undefined') {
173
+ const handler = event => {
174
+ const reason = event.reason;
175
+ trackError({
176
+ type: 'error',
177
+ timestamp: Date.now(),
178
+ message: reason?.message || String(reason) || 'Unhandled Promise Rejection',
179
+ stack: reason?.stack,
180
+ name: reason?.name || 'UnhandledRejection'
181
+ });
182
+ };
183
+ originalOnUnhandledRejection = handler;
184
+ _globalThis.addEventListener('unhandledrejection', handler);
185
+ }
186
+ }
187
+ //# sourceMappingURL=errorTracking.js.map
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ var _constants = require("./constants");
7
+ Object.keys(_constants).forEach(function (key) {
8
+ if (key === "default" || key === "__esModule") return;
9
+ if (key in exports && exports[key] === _constants[key]) return;
10
+ Object.defineProperty(exports, key, {
11
+ enumerable: true,
12
+ get: function () {
13
+ return _constants[key];
14
+ }
15
+ });
16
+ });
17
+ var _utils = require("./utils");
18
+ Object.keys(_utils).forEach(function (key) {
19
+ if (key === "default" || key === "__esModule") return;
20
+ if (key in exports && exports[key] === _utils[key]) return;
21
+ Object.defineProperty(exports, key, {
22
+ enumerable: true,
23
+ get: function () {
24
+ return _utils[key];
25
+ }
26
+ });
27
+ });
28
+ var _autoTracking = require("./autoTracking");
29
+ Object.keys(_autoTracking).forEach(function (key) {
30
+ if (key === "default" || key === "__esModule") return;
31
+ if (key in exports && exports[key] === _autoTracking[key]) return;
32
+ Object.defineProperty(exports, key, {
33
+ enumerable: true,
34
+ get: function () {
35
+ return _autoTracking[key];
36
+ }
37
+ });
38
+ });
39
+ var _networkInterceptor = require("./networkInterceptor");
40
+ Object.keys(_networkInterceptor).forEach(function (key) {
41
+ if (key === "default" || key === "__esModule") return;
42
+ if (key in exports && exports[key] === _networkInterceptor[key]) return;
43
+ Object.defineProperty(exports, key, {
44
+ enumerable: true,
45
+ get: function () {
46
+ return _networkInterceptor[key];
47
+ }
48
+ });
49
+ });
50
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,205 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.addScreenVisited = addScreenVisited;
7
+ exports.createEmptyMetrics = createEmptyMetrics;
8
+ exports.getSessionMetrics = getSessionMetrics;
9
+ exports.incrementDeadTapCount = incrementDeadTapCount;
10
+ exports.incrementErrorCount = incrementErrorCount;
11
+ exports.incrementNavigationCount = incrementNavigationCount;
12
+ exports.incrementRageTapCount = incrementRageTapCount;
13
+ exports.incrementScrollCount = incrementScrollCount;
14
+ exports.incrementTouchCount = incrementTouchCount;
15
+ exports.initMetrics = initMetrics;
16
+ exports.resetMetrics = resetMetrics;
17
+ exports.setMaxSessionDurationMinutes = setMaxSessionDurationMinutes;
18
+ exports.trackAPIMetrics = trackAPIMetrics;
19
+ /**
20
+ * Copyright 2026 Rejourney
21
+ *
22
+ * Licensed under the Apache License, Version 2.0 (the "License");
23
+ * you may not use this file except in compliance with the License.
24
+ * You may obtain a copy of the License at
25
+ *
26
+ * http://www.apache.org/licenses/LICENSE-2.0
27
+ *
28
+ * Unless required by applicable law or agreed to in writing, software
29
+ * distributed under the License is distributed on an "AS IS" BASIS,
30
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
31
+ * See the License for the specific language governing permissions and
32
+ * limitations under the License.
33
+ */
34
+
35
+ /**
36
+ * Session Metrics Module for Rejourney SDK
37
+ *
38
+ * Tracks and calculates session metrics including interaction scores,
39
+ * API performance, and user engagement metrics.
40
+ * Split from autoTracking.ts for better code organization.
41
+ */
42
+
43
+ /**
44
+ * Session metrics structure
45
+ */
46
+
47
+ let metrics = createEmptyMetrics();
48
+ let sessionStartTime = 0;
49
+ let maxSessionDurationMs = 10 * 60 * 1000;
50
+
51
+ /**
52
+ * Create empty metrics object
53
+ */
54
+ function createEmptyMetrics() {
55
+ return {
56
+ totalEvents: 0,
57
+ touchCount: 0,
58
+ scrollCount: 0,
59
+ gestureCount: 0,
60
+ inputCount: 0,
61
+ navigationCount: 0,
62
+ errorCount: 0,
63
+ rageTapCount: 0,
64
+ deadTapCount: 0,
65
+ apiSuccessCount: 0,
66
+ apiErrorCount: 0,
67
+ apiTotalCount: 0,
68
+ netTotalDurationMs: 0,
69
+ netTotalBytes: 0,
70
+ screensVisited: [],
71
+ uniqueScreensCount: 0,
72
+ interactionScore: 100,
73
+ explorationScore: 100,
74
+ uxScore: 100
75
+ };
76
+ }
77
+
78
+ /**
79
+ * Reset all metrics
80
+ */
81
+ function resetMetrics() {
82
+ metrics = createEmptyMetrics();
83
+ sessionStartTime = 0;
84
+ }
85
+
86
+ /**
87
+ * Initialize metrics for new session
88
+ */
89
+ function initMetrics() {
90
+ metrics = createEmptyMetrics();
91
+ sessionStartTime = Date.now();
92
+ }
93
+
94
+ /**
95
+ * Get current session metrics with calculated scores
96
+ */
97
+ function getSessionMetrics() {
98
+ const rawDuration = Date.now() - sessionStartTime;
99
+ const durationMs = Math.min(rawDuration, maxSessionDurationMs);
100
+ const interactionScore = calculateInteractionScore(durationMs);
101
+ const explorationScore = calculateExplorationScore();
102
+ const uxScore = calculateUXScore();
103
+ return {
104
+ ...metrics,
105
+ interactionScore,
106
+ explorationScore,
107
+ uxScore
108
+ };
109
+ }
110
+
111
+ /**
112
+ * Set max session duration (in minutes)
113
+ */
114
+ function setMaxSessionDurationMinutes(minutes) {
115
+ if (minutes !== undefined && minutes > 0) {
116
+ // Clamp to 1-10 minutes
117
+ const clampedMinutes = Math.max(1, Math.min(10, minutes));
118
+ maxSessionDurationMs = clampedMinutes * 60 * 1000;
119
+ }
120
+ }
121
+ function incrementTouchCount() {
122
+ metrics.touchCount++;
123
+ metrics.totalEvents++;
124
+ }
125
+ function incrementScrollCount() {
126
+ metrics.scrollCount++;
127
+ metrics.totalEvents++;
128
+ }
129
+ function incrementNavigationCount() {
130
+ metrics.navigationCount++;
131
+ metrics.totalEvents++;
132
+ }
133
+ function incrementRageTapCount() {
134
+ metrics.rageTapCount++;
135
+ }
136
+ function incrementDeadTapCount() {
137
+ metrics.deadTapCount++;
138
+ }
139
+ function incrementErrorCount() {
140
+ metrics.errorCount++;
141
+ metrics.totalEvents++;
142
+ }
143
+ function addScreenVisited(screenName) {
144
+ metrics.screensVisited.push(screenName);
145
+ metrics.uniqueScreensCount = new Set(metrics.screensVisited).size;
146
+ }
147
+ function trackAPIMetrics(success, durationMs = 0, responseBytes = 0) {
148
+ metrics.apiTotalCount++;
149
+ if (durationMs > 0) {
150
+ metrics.netTotalDurationMs += durationMs;
151
+ }
152
+ if (responseBytes > 0) {
153
+ metrics.netTotalBytes += responseBytes;
154
+ }
155
+ if (success) {
156
+ metrics.apiSuccessCount++;
157
+ } else {
158
+ metrics.apiErrorCount++;
159
+ metrics.errorCount++;
160
+ }
161
+ }
162
+
163
+ /**
164
+ * Calculate interaction score based on engagement with app
165
+ * Higher = more engaged (more interactions per minute)
166
+ */
167
+ function calculateInteractionScore(durationMs) {
168
+ if (durationMs <= 0) return 100;
169
+ const durationMinutes = durationMs / 60000;
170
+ const interactionsPerMinute = metrics.touchCount / Math.max(0.5, durationMinutes);
171
+ if (interactionsPerMinute < 2) return 20;
172
+ if (interactionsPerMinute < 5) return 50;
173
+ if (interactionsPerMinute < 10) return 70;
174
+ if (interactionsPerMinute <= 30) return 100;
175
+ if (interactionsPerMinute <= 60) return 80;
176
+ return 50;
177
+ }
178
+
179
+ /**
180
+ * Calculate exploration score based on screens visited
181
+ * Higher = user explored more of the app
182
+ */
183
+ function calculateExplorationScore() {
184
+ const uniqueScreens = metrics.uniqueScreensCount;
185
+ if (uniqueScreens >= 10) return 100;
186
+ if (uniqueScreens >= 7) return 90;
187
+ if (uniqueScreens >= 5) return 80;
188
+ if (uniqueScreens >= 3) return 60;
189
+ if (uniqueScreens >= 2) return 40;
190
+ return 20;
191
+ }
192
+
193
+ /**
194
+ * Calculate UX score based on errors and frustration
195
+ * Higher = better experience (fewer issues)
196
+ */
197
+ function calculateUXScore() {
198
+ let score = 100;
199
+ score -= metrics.errorCount * 10;
200
+ score -= metrics.rageTapCount * 20;
201
+ score -= metrics.deadTapCount * 10;
202
+ score -= metrics.apiErrorCount * 5;
203
+ return Math.max(0, Math.min(100, score));
204
+ }
205
+ //# sourceMappingURL=metricsTracking.js.map