@rejourneyco/react-native 1.0.9 → 1.0.11
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.
- package/README.md +77 -3
- package/android/src/main/AndroidManifest.xml +6 -0
- package/android/src/main/java/com/rejourney/RejourneyModuleImpl.kt +54 -0
- package/android/src/main/java/com/rejourney/RejourneyOkHttpInitProvider.kt +68 -0
- package/android/src/main/java/com/rejourney/engine/DeviceRegistrar.kt +3 -0
- package/android/src/main/java/com/rejourney/recording/RejourneyNetworkInterceptor.kt +0 -7
- package/android/src/main/java/com/rejourney/recording/ReplayOrchestrator.kt +4 -1
- package/android/src/main/java/com/rejourney/recording/SegmentDispatcher.kt +3 -0
- package/android/src/main/java/com/rejourney/recording/TelemetryPipeline.kt +26 -0
- package/android/src/main/java/com/rejourney/utility/DataCompression.kt +14 -2
- package/ios/Engine/RejourneyImpl.swift +5 -0
- package/ios/Recording/RejourneyURLProtocol.swift +58 -10
- package/ios/Recording/ReplayOrchestrator.swift +3 -1
- package/ios/Recording/TelemetryPipeline.swift +28 -2
- package/ios/Recording/VisualCapture.swift +25 -21
- package/ios/Rejourney.h +4 -0
- package/ios/Rejourney.mm +3 -15
- package/ios/Utility/DataCompression.swift +2 -2
- package/lib/commonjs/expoRouterTracking.js +137 -0
- package/lib/commonjs/index.js +176 -19
- package/lib/commonjs/sdk/autoTracking.js +100 -89
- package/lib/module/expoRouterTracking.js +135 -0
- package/lib/module/index.js +175 -13
- package/lib/module/sdk/autoTracking.js +98 -89
- package/lib/typescript/expoRouterTracking.d.ts +14 -0
- package/lib/typescript/index.d.ts +2 -2
- package/lib/typescript/sdk/autoTracking.d.ts +11 -0
- package/lib/typescript/types/index.d.ts +42 -3
- package/package.json +22 -2
- package/rejourney.podspec +11 -2
- package/src/expoRouterTracking.ts +167 -0
- package/src/index.ts +184 -16
- package/src/sdk/autoTracking.ts +110 -103
- package/src/types/index.ts +43 -3
|
@@ -13,11 +13,13 @@ exports.getRemainingSessionDurationMs = getRemainingSessionDurationMs;
|
|
|
13
13
|
exports.getSessionMetrics = getSessionMetrics;
|
|
14
14
|
exports.hasExceededMaxSessionDuration = hasExceededMaxSessionDuration;
|
|
15
15
|
exports.initAutoTracking = initAutoTracking;
|
|
16
|
+
exports.isExpoRouterTrackingEnabled = isExpoRouterTrackingEnabled;
|
|
16
17
|
exports.loadAnonymousId = loadAnonymousId;
|
|
17
18
|
exports.markTapHandled = markTapHandled;
|
|
18
19
|
exports.notifyStateChange = notifyStateChange;
|
|
19
20
|
exports.resetMetrics = resetMetrics;
|
|
20
21
|
exports.setAnonymousId = setAnonymousId;
|
|
22
|
+
exports.setExpoRouterPollingInterval = setExpoRouterPollingInterval;
|
|
21
23
|
exports.setMaxSessionDurationMinutes = setMaxSessionDurationMinutes;
|
|
22
24
|
exports.trackAPIRequest = trackAPIRequest;
|
|
23
25
|
exports.trackGesture = trackGesture;
|
|
@@ -147,6 +149,7 @@ function initAutoTracking(trackingConfig, callbacks = {}) {
|
|
|
147
149
|
trackReactNativeErrors: true,
|
|
148
150
|
trackConsoleLogs: true,
|
|
149
151
|
collectDeviceInfo: true,
|
|
152
|
+
autoTrackExpoRouter: true,
|
|
150
153
|
maxSessionDurationMs: trackingConfig.maxSessionDurationMs,
|
|
151
154
|
...trackingConfig
|
|
152
155
|
};
|
|
@@ -596,10 +599,26 @@ function restoreConsoleHandlers() {
|
|
|
596
599
|
// Note: console.error is restored in restoreErrorHandlers via originalConsoleError
|
|
597
600
|
}
|
|
598
601
|
let navigationPollingInterval = null;
|
|
602
|
+
/** Interval ID from optional expo-router entry; cleared in cleanupNavigationTracking */
|
|
603
|
+
let expoRouterPollingIntervalId = null;
|
|
599
604
|
let lastDetectedScreen = '';
|
|
600
605
|
let navigationSetupDone = false;
|
|
601
|
-
|
|
602
|
-
|
|
606
|
+
|
|
607
|
+
/**
|
|
608
|
+
* Register the polling interval from the optional expo-router entry so we can clear it on cleanup.
|
|
609
|
+
* Used by src/expoRouterTracking.ts (only loaded when app imports '@rejourneyco/react-native/expo-router').
|
|
610
|
+
*/
|
|
611
|
+
function setExpoRouterPollingInterval(id) {
|
|
612
|
+
expoRouterPollingIntervalId = id;
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
/**
|
|
616
|
+
* Check if Expo Router auto-tracking is enabled in the current configuration.
|
|
617
|
+
* Used by src/expoRouterTracking.ts.
|
|
618
|
+
*/
|
|
619
|
+
function isExpoRouterTrackingEnabled() {
|
|
620
|
+
return config.autoTrackExpoRouter !== false;
|
|
621
|
+
}
|
|
603
622
|
|
|
604
623
|
/**
|
|
605
624
|
* Track a navigation state change from React Navigation.
|
|
@@ -696,91 +715,94 @@ function useNavigationTracking() {
|
|
|
696
715
|
}
|
|
697
716
|
|
|
698
717
|
/**
|
|
699
|
-
* Setup automatic
|
|
700
|
-
*
|
|
701
|
-
*
|
|
702
|
-
*
|
|
718
|
+
* Setup automatic navigation tracking.
|
|
719
|
+
*
|
|
720
|
+
* Expo Router: not set up here to avoid pulling expo-router into the main bundle
|
|
721
|
+
* (Metro resolves require() at build time, which causes "Requiring unknown module"
|
|
722
|
+
* in apps that use Expo + react-navigation without expo-router). If you use
|
|
723
|
+
* expo-router, add: import '@rejourneyco/react-native/expo-router';
|
|
724
|
+
*
|
|
725
|
+
* For React Navigation (non–expo-router), use trackNavigationState() on your
|
|
726
|
+
* NavigationContainer's onStateChange.
|
|
703
727
|
*/
|
|
704
728
|
function setupNavigationTracking() {
|
|
705
729
|
if (navigationSetupDone) return;
|
|
706
730
|
navigationSetupDone = true;
|
|
707
|
-
|
|
708
|
-
|
|
731
|
+
|
|
732
|
+
// Auto-detect expo-router and set up screen tracking if available.
|
|
733
|
+
// This is safe: if expo-router isn't installed, the require fails silently.
|
|
734
|
+
// We defer slightly so the router has time to initialize after JS bundle load.
|
|
735
|
+
if (config.autoTrackExpoRouter !== false) {
|
|
736
|
+
tryAutoSetupExpoRouter();
|
|
709
737
|
}
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
const
|
|
724
|
-
|
|
725
|
-
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
/**
|
|
741
|
+
* Attempt to auto-detect and set up expo-router screen tracking.
|
|
742
|
+
* Uses a retry mechanism because the router may not be ready immediately
|
|
743
|
+
* after JS bundle load.
|
|
744
|
+
*/
|
|
745
|
+
function tryAutoSetupExpoRouter(attempt = 0, maxAttempts = 5) {
|
|
746
|
+
const delay = 200 * (attempt + 1); // 200, 400, 600, 800, 1000ms
|
|
747
|
+
|
|
748
|
+
setTimeout(() => {
|
|
749
|
+
try {
|
|
750
|
+
// Dynamic require wrapped in a variable to prevent Metro from statically resolving it
|
|
751
|
+
const EXPO_ROUTER = 'expo-router';
|
|
752
|
+
const expoRouter = require(EXPO_ROUTER);
|
|
753
|
+
if (!expoRouter?.router) {
|
|
754
|
+
// expo-router exists but router not ready yet — retry
|
|
755
|
+
if (attempt < maxAttempts - 1) {
|
|
756
|
+
tryAutoSetupExpoRouter(attempt + 1, maxAttempts);
|
|
757
|
+
}
|
|
758
|
+
return;
|
|
726
759
|
}
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
760
|
+
|
|
761
|
+
// Router is ready — set up the polling-based screen tracker
|
|
762
|
+
setupExpoRouterPolling(expoRouter.router);
|
|
763
|
+
} catch {
|
|
764
|
+
// expo-router not installed — this is fine, just means the app
|
|
765
|
+
// uses bare React Navigation or no navigation at all.
|
|
766
|
+
if (__DEV__ && attempt === 0) {
|
|
767
|
+
_utils.logger.debug('Expo Router not detected, skipping auto screen tracking. Use trackNavigationState() for React Navigation.');
|
|
732
768
|
}
|
|
733
769
|
}
|
|
734
|
-
};
|
|
735
|
-
setTimeout(trySetup, 200);
|
|
770
|
+
}, delay);
|
|
736
771
|
}
|
|
737
772
|
|
|
738
773
|
/**
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
774
|
+
* Poll expo-router state for screen changes.
|
|
775
|
+
* Inlined from expoRouterTracking.ts so no separate import is needed.
|
|
776
|
+
*/
|
|
777
|
+
function setupExpoRouterPolling(router) {
|
|
778
|
+
// Guard against double-setup (core auto-detection + legacy expoRouterTracking.ts import)
|
|
779
|
+
if (expoRouterPollingIntervalId != null) return;
|
|
780
|
+
const MAX_POLLING_ERRORS = 10;
|
|
781
|
+
let pollingErrors = 0;
|
|
744
782
|
try {
|
|
745
|
-
const expoRouter = require('expo-router');
|
|
746
|
-
const router = expoRouter.router;
|
|
747
|
-
if (!router) {
|
|
748
|
-
if (__DEV__) {
|
|
749
|
-
_utils.logger.debug('Expo Router: router object not found');
|
|
750
|
-
}
|
|
751
|
-
return false;
|
|
752
|
-
}
|
|
753
|
-
if (__DEV__) {
|
|
754
|
-
_utils.logger.debug('Expo Router: Setting up navigation tracking');
|
|
755
|
-
}
|
|
756
783
|
const {
|
|
757
784
|
normalizeScreenName,
|
|
758
785
|
getScreenNameFromPath
|
|
759
786
|
} = require('./navigation');
|
|
760
|
-
|
|
787
|
+
const intervalId = setInterval(() => {
|
|
761
788
|
try {
|
|
762
789
|
let state = null;
|
|
763
|
-
let stateSource = '';
|
|
764
790
|
if (typeof router.getState === 'function') {
|
|
765
791
|
state = router.getState();
|
|
766
|
-
stateSource = 'router.getState()';
|
|
767
792
|
} else if (router.rootState) {
|
|
768
793
|
state = router.rootState;
|
|
769
|
-
stateSource = 'router.rootState';
|
|
770
794
|
}
|
|
771
795
|
if (!state) {
|
|
772
796
|
try {
|
|
773
|
-
const
|
|
797
|
+
const STORE_PATH = 'expo-router/build/global-state/router-store';
|
|
798
|
+
const storeModule = require(STORE_PATH);
|
|
774
799
|
if (storeModule?.store) {
|
|
775
800
|
state = storeModule.store.state;
|
|
776
|
-
if (state) stateSource = 'store.state';
|
|
777
801
|
if (!state && storeModule.store.navigationRef?.current) {
|
|
778
802
|
state = storeModule.store.navigationRef.current.getRootState?.();
|
|
779
|
-
if (state) stateSource = 'navigationRef.getRootState()';
|
|
780
803
|
}
|
|
781
804
|
if (!state) {
|
|
782
805
|
state = storeModule.store.rootState || storeModule.store.initialState;
|
|
783
|
-
if (state) stateSource = 'store.rootState/initialState';
|
|
784
806
|
}
|
|
785
807
|
}
|
|
786
808
|
} catch {
|
|
@@ -789,67 +811,53 @@ function trySetupExpoRouter() {
|
|
|
789
811
|
}
|
|
790
812
|
if (!state) {
|
|
791
813
|
try {
|
|
792
|
-
const
|
|
814
|
+
const IMPERATIVE_PATH = 'expo-router/build/imperative-api';
|
|
815
|
+
const imperative = require(IMPERATIVE_PATH);
|
|
793
816
|
if (imperative?.router) {
|
|
794
817
|
state = imperative.router.getState?.();
|
|
795
|
-
if (state) stateSource = 'imperative-api';
|
|
796
818
|
}
|
|
797
819
|
} catch {
|
|
798
820
|
// Ignore
|
|
799
821
|
}
|
|
800
822
|
}
|
|
801
823
|
if (state) {
|
|
802
|
-
|
|
803
|
-
navigationPollingErrors = 0;
|
|
824
|
+
pollingErrors = 0;
|
|
804
825
|
const screenName = extractScreenNameFromRouterState(state, getScreenNameFromPath, normalizeScreenName);
|
|
805
826
|
if (screenName && screenName !== lastDetectedScreen) {
|
|
806
|
-
if (__DEV__) {
|
|
807
|
-
_utils.logger.debug('Screen changed:', lastDetectedScreen, '->', screenName, `(source: ${stateSource})`);
|
|
808
|
-
}
|
|
809
827
|
lastDetectedScreen = screenName;
|
|
810
828
|
trackScreen(screenName);
|
|
811
829
|
}
|
|
812
830
|
} else {
|
|
813
|
-
|
|
814
|
-
if (
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
if (navigationPollingErrors >= MAX_POLLING_ERRORS) {
|
|
818
|
-
cleanupNavigationTracking();
|
|
831
|
+
pollingErrors++;
|
|
832
|
+
if (pollingErrors >= MAX_POLLING_ERRORS) {
|
|
833
|
+
clearInterval(intervalId);
|
|
834
|
+
expoRouterPollingIntervalId = null;
|
|
819
835
|
}
|
|
820
836
|
}
|
|
821
|
-
} catch
|
|
822
|
-
|
|
823
|
-
if (
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
if (navigationPollingErrors >= MAX_POLLING_ERRORS) {
|
|
827
|
-
cleanupNavigationTracking();
|
|
837
|
+
} catch {
|
|
838
|
+
pollingErrors++;
|
|
839
|
+
if (pollingErrors >= MAX_POLLING_ERRORS) {
|
|
840
|
+
clearInterval(intervalId);
|
|
841
|
+
expoRouterPollingIntervalId = null;
|
|
828
842
|
}
|
|
829
843
|
}
|
|
830
844
|
}, 500);
|
|
831
|
-
|
|
832
|
-
} catch
|
|
833
|
-
|
|
834
|
-
_utils.logger.debug('Expo Router not available:', e);
|
|
835
|
-
}
|
|
836
|
-
return false;
|
|
845
|
+
expoRouterPollingIntervalId = intervalId;
|
|
846
|
+
} catch {
|
|
847
|
+
// navigation module not available — ignore
|
|
837
848
|
}
|
|
838
849
|
}
|
|
839
850
|
|
|
840
851
|
/**
|
|
841
|
-
* Extract screen name from
|
|
842
|
-
*
|
|
843
|
-
* Handles complex nested structures like Drawer → Tabs → Stack
|
|
844
|
-
* by recursively accumulating segments from each navigation level.
|
|
852
|
+
* Extract the active screen name from expo-router navigation state.
|
|
845
853
|
*/
|
|
846
|
-
function extractScreenNameFromRouterState(state,
|
|
854
|
+
function extractScreenNameFromRouterState(state, getScreenNameFromPathFn, normalizeScreenNameFn, accumulatedSegments = []) {
|
|
847
855
|
if (!state?.routes) return null;
|
|
848
856
|
const route = state.routes[state.index ?? state.routes.length - 1];
|
|
849
857
|
if (!route) return null;
|
|
850
858
|
const newSegments = [...accumulatedSegments, route.name];
|
|
851
859
|
if (route.state) {
|
|
852
|
-
return extractScreenNameFromRouterState(route.state,
|
|
860
|
+
return extractScreenNameFromRouterState(route.state, getScreenNameFromPathFn, normalizeScreenNameFn, newSegments);
|
|
853
861
|
}
|
|
854
862
|
const cleanSegments = newSegments.filter(s => !s.startsWith('(') && !s.endsWith(')'));
|
|
855
863
|
if (cleanSegments.length === 0) {
|
|
@@ -862,7 +870,7 @@ function extractScreenNameFromRouterState(state, getScreenNameFromPath, normaliz
|
|
|
862
870
|
}
|
|
863
871
|
}
|
|
864
872
|
const pathname = '/' + cleanSegments.join('/');
|
|
865
|
-
return
|
|
873
|
+
return getScreenNameFromPathFn(pathname, newSegments);
|
|
866
874
|
}
|
|
867
875
|
|
|
868
876
|
/**
|
|
@@ -873,9 +881,12 @@ function cleanupNavigationTracking() {
|
|
|
873
881
|
clearInterval(navigationPollingInterval);
|
|
874
882
|
navigationPollingInterval = null;
|
|
875
883
|
}
|
|
884
|
+
if (expoRouterPollingIntervalId != null) {
|
|
885
|
+
clearInterval(expoRouterPollingIntervalId);
|
|
886
|
+
expoRouterPollingIntervalId = null;
|
|
887
|
+
}
|
|
876
888
|
navigationSetupDone = false;
|
|
877
889
|
lastDetectedScreen = '';
|
|
878
|
-
navigationPollingErrors = 0;
|
|
879
890
|
}
|
|
880
891
|
|
|
881
892
|
/**
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Optional Expo Router integration for @rejourneyco/react-native
|
|
3
|
+
*
|
|
4
|
+
* This file is only loaded when you import '@rejourneyco/react-native/expo-router'.
|
|
5
|
+
* It contains require('expo-router') and related subpaths. Metro bundles require()
|
|
6
|
+
* at build time, so keeping this in a separate entry ensures apps that use
|
|
7
|
+
* Expo with react-navigation (without expo-router) never pull in expo-router
|
|
8
|
+
* and avoid "Requiring unknown module" crashes.
|
|
9
|
+
*
|
|
10
|
+
* If you use expo-router, add this once (e.g. in your root _layout.tsx):
|
|
11
|
+
* import '@rejourneyco/react-native/expo-router';
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import { trackScreen, setExpoRouterPollingInterval, isExpoRouterTrackingEnabled } from './sdk/autoTracking';
|
|
15
|
+
import { normalizeScreenName, getScreenNameFromPath } from './sdk/navigation';
|
|
16
|
+
const MAX_POLLING_ERRORS = 10;
|
|
17
|
+
function extractScreenNameFromRouterState(state, getScreenNameFromPathFn, normalizeScreenNameFn, accumulatedSegments = []) {
|
|
18
|
+
if (!state?.routes) return null;
|
|
19
|
+
const route = state.routes[state.index ?? state.routes.length - 1];
|
|
20
|
+
if (!route) return null;
|
|
21
|
+
const newSegments = [...accumulatedSegments, route.name];
|
|
22
|
+
if (route.state) {
|
|
23
|
+
return extractScreenNameFromRouterState(route.state, getScreenNameFromPathFn, normalizeScreenNameFn, newSegments);
|
|
24
|
+
}
|
|
25
|
+
const cleanSegments = newSegments.filter(s => !s.startsWith('(') && !s.endsWith(')'));
|
|
26
|
+
if (cleanSegments.length === 0) {
|
|
27
|
+
for (let i = newSegments.length - 1; i >= 0; i--) {
|
|
28
|
+
const seg = newSegments[i];
|
|
29
|
+
if (seg && !seg.startsWith('(') && !seg.endsWith(')')) {
|
|
30
|
+
cleanSegments.push(seg);
|
|
31
|
+
break;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
const pathname = '/' + cleanSegments.join('/');
|
|
36
|
+
return getScreenNameFromPathFn(pathname, newSegments);
|
|
37
|
+
}
|
|
38
|
+
function setupExpoRouterPolling() {
|
|
39
|
+
let lastDetectedScreen = '';
|
|
40
|
+
let pollingErrors = 0;
|
|
41
|
+
try {
|
|
42
|
+
const EXPO_ROUTER = 'expo-router';
|
|
43
|
+
const expoRouter = require(EXPO_ROUTER);
|
|
44
|
+
const router = expoRouter.router;
|
|
45
|
+
if (!router) {
|
|
46
|
+
if (typeof __DEV__ !== 'undefined' && __DEV__) {
|
|
47
|
+
console.debug('[Rejourney] Expo Router: router object not found');
|
|
48
|
+
}
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
const intervalId = setInterval(() => {
|
|
52
|
+
try {
|
|
53
|
+
let state = null;
|
|
54
|
+
if (typeof router.getState === 'function') {
|
|
55
|
+
state = router.getState();
|
|
56
|
+
} else if (router.rootState) {
|
|
57
|
+
state = router.rootState;
|
|
58
|
+
}
|
|
59
|
+
if (!state) {
|
|
60
|
+
try {
|
|
61
|
+
const STORE_PATH = 'expo-router/build/global-state/router-store';
|
|
62
|
+
const storeModule = require(STORE_PATH);
|
|
63
|
+
if (storeModule?.store) {
|
|
64
|
+
state = storeModule.store.state;
|
|
65
|
+
if (!state && storeModule.store.navigationRef?.current) {
|
|
66
|
+
state = storeModule.store.navigationRef.current.getRootState?.();
|
|
67
|
+
}
|
|
68
|
+
if (!state) {
|
|
69
|
+
state = storeModule.store.rootState || storeModule.store.initialState;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
} catch {
|
|
73
|
+
// Ignore
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
if (!state) {
|
|
77
|
+
try {
|
|
78
|
+
const IMPERATIVE_PATH = 'expo-router/build/imperative-api';
|
|
79
|
+
const imperative = require(IMPERATIVE_PATH);
|
|
80
|
+
if (imperative?.router) {
|
|
81
|
+
state = imperative.router.getState?.();
|
|
82
|
+
}
|
|
83
|
+
} catch {
|
|
84
|
+
// Ignore
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
if (state) {
|
|
88
|
+
pollingErrors = 0;
|
|
89
|
+
const screenName = extractScreenNameFromRouterState(state, getScreenNameFromPath, normalizeScreenName);
|
|
90
|
+
if (screenName && screenName !== lastDetectedScreen) {
|
|
91
|
+
lastDetectedScreen = screenName;
|
|
92
|
+
trackScreen(screenName);
|
|
93
|
+
}
|
|
94
|
+
} else {
|
|
95
|
+
pollingErrors++;
|
|
96
|
+
if (pollingErrors >= MAX_POLLING_ERRORS) {
|
|
97
|
+
clearInterval(intervalId);
|
|
98
|
+
setExpoRouterPollingInterval(null);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
} catch {
|
|
102
|
+
pollingErrors++;
|
|
103
|
+
if (pollingErrors >= MAX_POLLING_ERRORS) {
|
|
104
|
+
clearInterval(intervalId);
|
|
105
|
+
setExpoRouterPollingInterval(null);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}, 500);
|
|
109
|
+
setExpoRouterPollingInterval(intervalId);
|
|
110
|
+
} catch (e) {
|
|
111
|
+
if (typeof __DEV__ !== 'undefined' && __DEV__) {
|
|
112
|
+
console.debug('[Rejourney] Expo Router not available:', e);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
let attempts = 0;
|
|
117
|
+
const maxAttempts = 5;
|
|
118
|
+
function trySetup() {
|
|
119
|
+
attempts++;
|
|
120
|
+
try {
|
|
121
|
+
const EXPO_ROUTER = 'expo-router';
|
|
122
|
+
const expoRouter = require(EXPO_ROUTER);
|
|
123
|
+
if (expoRouter?.router && isExpoRouterTrackingEnabled()) {
|
|
124
|
+
setupExpoRouterPolling();
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
} catch {
|
|
128
|
+
// Not ready or not installed
|
|
129
|
+
}
|
|
130
|
+
if (attempts < maxAttempts) {
|
|
131
|
+
setTimeout(trySetup, 200 * attempts);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
setTimeout(trySetup, 200);
|
|
135
|
+
//# sourceMappingURL=expoRouterTracking.js.map
|