@rejourneyco/react-native 1.0.0 → 1.0.1
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 +29 -0
- package/android/src/main/java/com/rejourney/RejourneyModuleImpl.kt +12 -1
- package/android/src/main/java/com/rejourney/capture/CaptureEngine.kt +25 -1
- package/android/src/main/java/com/rejourney/capture/CaptureHeuristics.kt +70 -32
- package/android/src/main/java/com/rejourney/core/Constants.kt +4 -4
- package/android/src/newarch/java/com/rejourney/RejourneyModule.kt +7 -0
- package/ios/Capture/RJCaptureEngine.m +74 -5
- package/ios/Capture/RJCaptureHeuristics.h +7 -5
- package/ios/Capture/RJCaptureHeuristics.m +138 -112
- package/ios/Core/Rejourney.mm +35 -10
- package/lib/commonjs/index.js +8 -14
- package/lib/commonjs/sdk/autoTracking.js +21 -48
- package/lib/module/index.js +8 -14
- package/lib/module/sdk/autoTracking.js +21 -48
- package/lib/typescript/NativeRejourney.d.ts +1 -0
- package/lib/typescript/sdk/autoTracking.d.ts +1 -2
- package/package.json +17 -3
- package/src/NativeRejourney.ts +2 -0
- package/src/index.ts +8 -15
- package/src/sdk/autoTracking.ts +26 -54
|
@@ -162,16 +162,16 @@ function initAutoTracking(trackingConfig, callbacks = {}) {
|
|
|
162
162
|
onErrorCaptured = callbacks.onError || null;
|
|
163
163
|
onScreenChange = callbacks.onScreen || null;
|
|
164
164
|
|
|
165
|
-
// Initialize metrics
|
|
166
|
-
metrics = createEmptyMetrics();
|
|
167
|
-
sessionStartTime = Date.now();
|
|
168
|
-
anonymousId = generateAnonymousId();
|
|
169
|
-
|
|
170
165
|
// Setup error tracking
|
|
171
166
|
setupErrorTracking();
|
|
172
167
|
|
|
173
168
|
// Setup React Navigation tracking (if available)
|
|
174
169
|
setupNavigationTracking();
|
|
170
|
+
|
|
171
|
+
// Load anonymous ID from native storage (or generate new one)
|
|
172
|
+
loadAnonymousId().then(id => {
|
|
173
|
+
anonymousId = id;
|
|
174
|
+
});
|
|
175
175
|
isInitialized = true;
|
|
176
176
|
}
|
|
177
177
|
|
|
@@ -1148,7 +1148,7 @@ function collectDeviceInfo() {
|
|
|
1148
1148
|
// =============================================================================
|
|
1149
1149
|
|
|
1150
1150
|
// Storage key for anonymous ID
|
|
1151
|
-
const ANONYMOUS_ID_KEY = '@rejourney_anonymous_id';
|
|
1151
|
+
// const ANONYMOUS_ID_KEY = '@rejourney_anonymous_id';
|
|
1152
1152
|
|
|
1153
1153
|
/**
|
|
1154
1154
|
* Generate a persistent anonymous ID
|
|
@@ -1159,39 +1159,12 @@ function generateAnonymousId() {
|
|
|
1159
1159
|
return `anon_${timestamp}_${random}`;
|
|
1160
1160
|
}
|
|
1161
1161
|
|
|
1162
|
-
/**
|
|
1163
|
-
* Initialize anonymous ID - tries to load from storage, generates new if not found
|
|
1164
|
-
* This is called internally and runs asynchronously
|
|
1165
|
-
*/
|
|
1166
|
-
async function initAnonymousId() {
|
|
1167
|
-
try {
|
|
1168
|
-
// Try to load from AsyncStorage
|
|
1169
|
-
const AsyncStorage = require('@react-native-async-storage/async-storage').default;
|
|
1170
|
-
const storedId = await AsyncStorage.getItem(ANONYMOUS_ID_KEY);
|
|
1171
|
-
if (storedId) {
|
|
1172
|
-
anonymousId = storedId;
|
|
1173
|
-
} else {
|
|
1174
|
-
// Generate new ID and persist
|
|
1175
|
-
anonymousId = generateAnonymousId();
|
|
1176
|
-
await AsyncStorage.setItem(ANONYMOUS_ID_KEY, anonymousId);
|
|
1177
|
-
}
|
|
1178
|
-
} catch {
|
|
1179
|
-
// AsyncStorage not available or error - just generate without persistence
|
|
1180
|
-
if (!anonymousId) {
|
|
1181
|
-
anonymousId = generateAnonymousId();
|
|
1182
|
-
}
|
|
1183
|
-
}
|
|
1184
|
-
}
|
|
1185
|
-
|
|
1186
1162
|
/**
|
|
1187
1163
|
* Get the anonymous ID (synchronous - returns generated ID immediately)
|
|
1188
|
-
* For persistent ID, call initAnonymousId() first
|
|
1189
1164
|
*/
|
|
1190
1165
|
function getAnonymousId() {
|
|
1191
1166
|
if (!anonymousId) {
|
|
1192
1167
|
anonymousId = generateAnonymousId();
|
|
1193
|
-
// Try to persist asynchronously (fire and forget)
|
|
1194
|
-
initAnonymousId().catch(() => {});
|
|
1195
1168
|
}
|
|
1196
1169
|
return anonymousId;
|
|
1197
1170
|
}
|
|
@@ -1204,11 +1177,10 @@ async function ensurePersistentAnonymousId() {
|
|
|
1204
1177
|
if (anonymousId) return anonymousId;
|
|
1205
1178
|
if (!anonymousIdPromise) {
|
|
1206
1179
|
anonymousIdPromise = (async () => {
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
return anonymousId;
|
|
1180
|
+
// Just use the load logic which now delegates to native or memory
|
|
1181
|
+
const id = await loadAnonymousId();
|
|
1182
|
+
anonymousId = id;
|
|
1183
|
+
return id;
|
|
1212
1184
|
})();
|
|
1213
1185
|
}
|
|
1214
1186
|
return anonymousIdPromise;
|
|
@@ -1219,22 +1191,23 @@ async function ensurePersistentAnonymousId() {
|
|
|
1219
1191
|
* Call this at app startup for best results
|
|
1220
1192
|
*/
|
|
1221
1193
|
async function loadAnonymousId() {
|
|
1222
|
-
|
|
1223
|
-
|
|
1194
|
+
const nativeModule = getRejourneyNativeModule();
|
|
1195
|
+
if (nativeModule && nativeModule.getUserIdentity) {
|
|
1196
|
+
try {
|
|
1197
|
+
return (await nativeModule.getUserIdentity()) || generateAnonymousId();
|
|
1198
|
+
} catch {
|
|
1199
|
+
return generateAnonymousId();
|
|
1200
|
+
}
|
|
1201
|
+
}
|
|
1202
|
+
return generateAnonymousId();
|
|
1224
1203
|
}
|
|
1225
1204
|
|
|
1226
1205
|
/**
|
|
1227
|
-
* Set a custom anonymous ID
|
|
1206
|
+
* Set a custom anonymous ID
|
|
1228
1207
|
*/
|
|
1229
1208
|
function setAnonymousId(id) {
|
|
1230
1209
|
anonymousId = id;
|
|
1231
|
-
//
|
|
1232
|
-
try {
|
|
1233
|
-
const AsyncStorage = require('@react-native-async-storage/async-storage').default;
|
|
1234
|
-
AsyncStorage.setItem(ANONYMOUS_ID_KEY, id).catch(() => {});
|
|
1235
|
-
} catch {
|
|
1236
|
-
// Ignore if AsyncStorage not available
|
|
1237
|
-
}
|
|
1210
|
+
// No-op for async persistence as we moved to native-only or memory-only
|
|
1238
1211
|
}
|
|
1239
1212
|
|
|
1240
1213
|
// =============================================================================
|
package/lib/module/index.js
CHANGED
|
@@ -168,7 +168,6 @@ function getAutoTracking() {
|
|
|
168
168
|
}
|
|
169
169
|
|
|
170
170
|
// State
|
|
171
|
-
const USER_IDENTITY_KEY = '@rejourney_user_identity';
|
|
172
171
|
let _isInitialized = false;
|
|
173
172
|
let _isRecording = false;
|
|
174
173
|
let _initializationFailed = false;
|
|
@@ -183,22 +182,17 @@ let _lastScrollOffset = 0;
|
|
|
183
182
|
const SCROLL_THROTTLE_MS = 100;
|
|
184
183
|
|
|
185
184
|
// Helper to save/load user identity
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
if (identity) {
|
|
190
|
-
await AsyncStorage.setItem(USER_IDENTITY_KEY, identity);
|
|
191
|
-
} else {
|
|
192
|
-
await AsyncStorage.removeItem(USER_IDENTITY_KEY);
|
|
193
|
-
}
|
|
194
|
-
} catch (e) {
|
|
195
|
-
// Ignore storage errors
|
|
196
|
-
}
|
|
185
|
+
// NOW HANDLED NATIVELY - No-op on JS side to avoid unnecessary bridge calls
|
|
186
|
+
async function persistUserIdentity(_identity) {
|
|
187
|
+
// Native module handles persistence automatically in setUserIdentity
|
|
197
188
|
}
|
|
198
189
|
async function loadPersistedUserIdentity() {
|
|
199
190
|
try {
|
|
200
|
-
const
|
|
201
|
-
|
|
191
|
+
const nativeModule = getRejourneyNative();
|
|
192
|
+
if (!nativeModule) return null;
|
|
193
|
+
|
|
194
|
+
// NATIVE STORAGE: Read directly from SharedPreferences/NSUserDefaults
|
|
195
|
+
return await nativeModule.getUserIdentity();
|
|
202
196
|
} catch (e) {
|
|
203
197
|
return null;
|
|
204
198
|
}
|
|
@@ -135,16 +135,16 @@ export function initAutoTracking(trackingConfig, callbacks = {}) {
|
|
|
135
135
|
onErrorCaptured = callbacks.onError || null;
|
|
136
136
|
onScreenChange = callbacks.onScreen || null;
|
|
137
137
|
|
|
138
|
-
// Initialize metrics
|
|
139
|
-
metrics = createEmptyMetrics();
|
|
140
|
-
sessionStartTime = Date.now();
|
|
141
|
-
anonymousId = generateAnonymousId();
|
|
142
|
-
|
|
143
138
|
// Setup error tracking
|
|
144
139
|
setupErrorTracking();
|
|
145
140
|
|
|
146
141
|
// Setup React Navigation tracking (if available)
|
|
147
142
|
setupNavigationTracking();
|
|
143
|
+
|
|
144
|
+
// Load anonymous ID from native storage (or generate new one)
|
|
145
|
+
loadAnonymousId().then(id => {
|
|
146
|
+
anonymousId = id;
|
|
147
|
+
});
|
|
148
148
|
isInitialized = true;
|
|
149
149
|
}
|
|
150
150
|
|
|
@@ -1121,7 +1121,7 @@ export function collectDeviceInfo() {
|
|
|
1121
1121
|
// =============================================================================
|
|
1122
1122
|
|
|
1123
1123
|
// Storage key for anonymous ID
|
|
1124
|
-
const ANONYMOUS_ID_KEY = '@rejourney_anonymous_id';
|
|
1124
|
+
// const ANONYMOUS_ID_KEY = '@rejourney_anonymous_id';
|
|
1125
1125
|
|
|
1126
1126
|
/**
|
|
1127
1127
|
* Generate a persistent anonymous ID
|
|
@@ -1132,39 +1132,12 @@ function generateAnonymousId() {
|
|
|
1132
1132
|
return `anon_${timestamp}_${random}`;
|
|
1133
1133
|
}
|
|
1134
1134
|
|
|
1135
|
-
/**
|
|
1136
|
-
* Initialize anonymous ID - tries to load from storage, generates new if not found
|
|
1137
|
-
* This is called internally and runs asynchronously
|
|
1138
|
-
*/
|
|
1139
|
-
async function initAnonymousId() {
|
|
1140
|
-
try {
|
|
1141
|
-
// Try to load from AsyncStorage
|
|
1142
|
-
const AsyncStorage = require('@react-native-async-storage/async-storage').default;
|
|
1143
|
-
const storedId = await AsyncStorage.getItem(ANONYMOUS_ID_KEY);
|
|
1144
|
-
if (storedId) {
|
|
1145
|
-
anonymousId = storedId;
|
|
1146
|
-
} else {
|
|
1147
|
-
// Generate new ID and persist
|
|
1148
|
-
anonymousId = generateAnonymousId();
|
|
1149
|
-
await AsyncStorage.setItem(ANONYMOUS_ID_KEY, anonymousId);
|
|
1150
|
-
}
|
|
1151
|
-
} catch {
|
|
1152
|
-
// AsyncStorage not available or error - just generate without persistence
|
|
1153
|
-
if (!anonymousId) {
|
|
1154
|
-
anonymousId = generateAnonymousId();
|
|
1155
|
-
}
|
|
1156
|
-
}
|
|
1157
|
-
}
|
|
1158
|
-
|
|
1159
1135
|
/**
|
|
1160
1136
|
* Get the anonymous ID (synchronous - returns generated ID immediately)
|
|
1161
|
-
* For persistent ID, call initAnonymousId() first
|
|
1162
1137
|
*/
|
|
1163
1138
|
export function getAnonymousId() {
|
|
1164
1139
|
if (!anonymousId) {
|
|
1165
1140
|
anonymousId = generateAnonymousId();
|
|
1166
|
-
// Try to persist asynchronously (fire and forget)
|
|
1167
|
-
initAnonymousId().catch(() => {});
|
|
1168
1141
|
}
|
|
1169
1142
|
return anonymousId;
|
|
1170
1143
|
}
|
|
@@ -1177,11 +1150,10 @@ export async function ensurePersistentAnonymousId() {
|
|
|
1177
1150
|
if (anonymousId) return anonymousId;
|
|
1178
1151
|
if (!anonymousIdPromise) {
|
|
1179
1152
|
anonymousIdPromise = (async () => {
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
return anonymousId;
|
|
1153
|
+
// Just use the load logic which now delegates to native or memory
|
|
1154
|
+
const id = await loadAnonymousId();
|
|
1155
|
+
anonymousId = id;
|
|
1156
|
+
return id;
|
|
1185
1157
|
})();
|
|
1186
1158
|
}
|
|
1187
1159
|
return anonymousIdPromise;
|
|
@@ -1192,22 +1164,23 @@ export async function ensurePersistentAnonymousId() {
|
|
|
1192
1164
|
* Call this at app startup for best results
|
|
1193
1165
|
*/
|
|
1194
1166
|
export async function loadAnonymousId() {
|
|
1195
|
-
|
|
1196
|
-
|
|
1167
|
+
const nativeModule = getRejourneyNativeModule();
|
|
1168
|
+
if (nativeModule && nativeModule.getUserIdentity) {
|
|
1169
|
+
try {
|
|
1170
|
+
return (await nativeModule.getUserIdentity()) || generateAnonymousId();
|
|
1171
|
+
} catch {
|
|
1172
|
+
return generateAnonymousId();
|
|
1173
|
+
}
|
|
1174
|
+
}
|
|
1175
|
+
return generateAnonymousId();
|
|
1197
1176
|
}
|
|
1198
1177
|
|
|
1199
1178
|
/**
|
|
1200
|
-
* Set a custom anonymous ID
|
|
1179
|
+
* Set a custom anonymous ID
|
|
1201
1180
|
*/
|
|
1202
1181
|
export function setAnonymousId(id) {
|
|
1203
1182
|
anonymousId = id;
|
|
1204
|
-
//
|
|
1205
|
-
try {
|
|
1206
|
-
const AsyncStorage = require('@react-native-async-storage/async-storage').default;
|
|
1207
|
-
AsyncStorage.setItem(ANONYMOUS_ID_KEY, id).catch(() => {});
|
|
1208
|
-
} catch {
|
|
1209
|
-
// Ignore if AsyncStorage not available
|
|
1210
|
-
}
|
|
1183
|
+
// No-op for async persistence as we moved to native-only or memory-only
|
|
1211
1184
|
}
|
|
1212
1185
|
|
|
1213
1186
|
// =============================================================================
|
|
@@ -167,7 +167,6 @@ export declare function getRemainingSessionDurationMs(): number;
|
|
|
167
167
|
export declare function collectDeviceInfo(): DeviceInfo;
|
|
168
168
|
/**
|
|
169
169
|
* Get the anonymous ID (synchronous - returns generated ID immediately)
|
|
170
|
-
* For persistent ID, call initAnonymousId() first
|
|
171
170
|
*/
|
|
172
171
|
export declare function getAnonymousId(): string;
|
|
173
172
|
/**
|
|
@@ -181,7 +180,7 @@ export declare function ensurePersistentAnonymousId(): Promise<string>;
|
|
|
181
180
|
*/
|
|
182
181
|
export declare function loadAnonymousId(): Promise<string>;
|
|
183
182
|
/**
|
|
184
|
-
* Set a custom anonymous ID
|
|
183
|
+
* Set a custom anonymous ID
|
|
185
184
|
*/
|
|
186
185
|
export declare function setAnonymousId(id: string): void;
|
|
187
186
|
declare const _default: {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rejourneyco/react-native",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "Rejourney Session Recording SDK for React Native",
|
|
5
5
|
"main": "lib/commonjs/index.js",
|
|
6
6
|
"module": "lib/module/index.js",
|
|
@@ -40,7 +40,10 @@
|
|
|
40
40
|
"test:coverage": "vitest run --coverage",
|
|
41
41
|
"release": "release-it",
|
|
42
42
|
"verify:ios": "./scripts/verify-ios-structure.sh",
|
|
43
|
-
"
|
|
43
|
+
"verify:package": "./scripts/verify-package-content.sh",
|
|
44
|
+
"test:ios-install": "./scripts/test-ios-install.sh",
|
|
45
|
+
"test:android-install": "./scripts/test-android-install.sh",
|
|
46
|
+
"audit:deps": "depcruise src --config .dependency-cruiser.js"
|
|
44
47
|
},
|
|
45
48
|
"keywords": [
|
|
46
49
|
"react-native",
|
|
@@ -61,6 +64,12 @@
|
|
|
61
64
|
"@typescript-eslint/eslint-plugin": "^8.15.0",
|
|
62
65
|
"@typescript-eslint/parser": "^8.15.0",
|
|
63
66
|
"@vitest/coverage-v8": "^2.1.0",
|
|
67
|
+
"dependency-cruiser": "^16.10.4",
|
|
68
|
+
"@react-navigation/native": "*",
|
|
69
|
+
"expo-router": "*",
|
|
70
|
+
"expo-constants": "*",
|
|
71
|
+
"expo-application": "*",
|
|
72
|
+
"react-native-device-info": "*",
|
|
64
73
|
"eslint": "^9.39.2",
|
|
65
74
|
"react": "*",
|
|
66
75
|
"react-native": "*",
|
|
@@ -70,7 +79,12 @@
|
|
|
70
79
|
},
|
|
71
80
|
"peerDependencies": {
|
|
72
81
|
"react": "*",
|
|
73
|
-
"react-native": "*"
|
|
82
|
+
"react-native": "*",
|
|
83
|
+
"@react-navigation/native": ">=6.0.0",
|
|
84
|
+
"expo-router": ">=3.0.0",
|
|
85
|
+
"expo-constants": ">=15.0.0",
|
|
86
|
+
"expo-application": ">=5.0.0",
|
|
87
|
+
"react-native-device-info": ">=10.0.0"
|
|
74
88
|
},
|
|
75
89
|
"codegenConfig": {
|
|
76
90
|
"name": "RejourneySpec",
|
package/src/NativeRejourney.ts
CHANGED
package/src/index.ts
CHANGED
|
@@ -193,8 +193,6 @@ function getAutoTracking() {
|
|
|
193
193
|
}
|
|
194
194
|
|
|
195
195
|
// State
|
|
196
|
-
const USER_IDENTITY_KEY = '@rejourney_user_identity';
|
|
197
|
-
|
|
198
196
|
let _isInitialized = false;
|
|
199
197
|
let _isRecording = false;
|
|
200
198
|
let _initializationFailed = false;
|
|
@@ -209,23 +207,18 @@ let _lastScrollOffset: number = 0;
|
|
|
209
207
|
const SCROLL_THROTTLE_MS = 100;
|
|
210
208
|
|
|
211
209
|
// Helper to save/load user identity
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
if (identity) {
|
|
216
|
-
await AsyncStorage.setItem(USER_IDENTITY_KEY, identity);
|
|
217
|
-
} else {
|
|
218
|
-
await AsyncStorage.removeItem(USER_IDENTITY_KEY);
|
|
219
|
-
}
|
|
220
|
-
} catch (e) {
|
|
221
|
-
// Ignore storage errors
|
|
222
|
-
}
|
|
210
|
+
// NOW HANDLED NATIVELY - No-op on JS side to avoid unnecessary bridge calls
|
|
211
|
+
async function persistUserIdentity(_identity: string | null): Promise<void> {
|
|
212
|
+
// Native module handles persistence automatically in setUserIdentity
|
|
223
213
|
}
|
|
224
214
|
|
|
225
215
|
async function loadPersistedUserIdentity(): Promise<string | null> {
|
|
226
216
|
try {
|
|
227
|
-
const
|
|
228
|
-
|
|
217
|
+
const nativeModule = getRejourneyNative();
|
|
218
|
+
if (!nativeModule) return null;
|
|
219
|
+
|
|
220
|
+
// NATIVE STORAGE: Read directly from SharedPreferences/NSUserDefaults
|
|
221
|
+
return await nativeModule.getUserIdentity();
|
|
229
222
|
} catch (e) {
|
|
230
223
|
return null;
|
|
231
224
|
}
|
package/src/sdk/autoTracking.ts
CHANGED
|
@@ -232,17 +232,17 @@ export function initAutoTracking(
|
|
|
232
232
|
onErrorCaptured = callbacks.onError || null;
|
|
233
233
|
onScreenChange = callbacks.onScreen || null;
|
|
234
234
|
|
|
235
|
-
// Initialize metrics
|
|
236
|
-
metrics = createEmptyMetrics();
|
|
237
|
-
sessionStartTime = Date.now();
|
|
238
|
-
anonymousId = generateAnonymousId();
|
|
239
|
-
|
|
240
235
|
// Setup error tracking
|
|
241
236
|
setupErrorTracking();
|
|
242
237
|
|
|
243
238
|
// Setup React Navigation tracking (if available)
|
|
244
239
|
setupNavigationTracking();
|
|
245
240
|
|
|
241
|
+
// Load anonymous ID from native storage (or generate new one)
|
|
242
|
+
loadAnonymousId().then(id => {
|
|
243
|
+
anonymousId = id;
|
|
244
|
+
});
|
|
245
|
+
|
|
246
246
|
isInitialized = true;
|
|
247
247
|
}
|
|
248
248
|
|
|
@@ -674,15 +674,15 @@ function setupNavigationTracking(): void {
|
|
|
674
674
|
// We retry a few times with increasing delays
|
|
675
675
|
let attempts = 0;
|
|
676
676
|
const maxAttempts = 5;
|
|
677
|
-
|
|
677
|
+
|
|
678
678
|
const trySetup = () => {
|
|
679
679
|
attempts++;
|
|
680
680
|
if (__DEV__) {
|
|
681
681
|
logger.debug('Navigation setup attempt', attempts, 'of', maxAttempts);
|
|
682
682
|
}
|
|
683
|
-
|
|
683
|
+
|
|
684
684
|
const success = trySetupExpoRouter();
|
|
685
|
-
|
|
685
|
+
|
|
686
686
|
if (success) {
|
|
687
687
|
if (__DEV__) {
|
|
688
688
|
logger.debug('Expo Router setup: SUCCESS on attempt', attempts);
|
|
@@ -1152,10 +1152,10 @@ export function collectDeviceInfo(): DeviceInfo {
|
|
|
1152
1152
|
const Dimensions = getDimensions();
|
|
1153
1153
|
const Platform = getPlatform();
|
|
1154
1154
|
const NativeModules = getNativeModules();
|
|
1155
|
-
|
|
1155
|
+
|
|
1156
1156
|
// Default values if react-native isn't available
|
|
1157
1157
|
let width = 0, height = 0, scale = 1;
|
|
1158
|
-
|
|
1158
|
+
|
|
1159
1159
|
if (Dimensions) {
|
|
1160
1160
|
const windowDims = Dimensions.get('window');
|
|
1161
1161
|
const screenDims = Dimensions.get('screen');
|
|
@@ -1261,7 +1261,7 @@ export function collectDeviceInfo(): DeviceInfo {
|
|
|
1261
1261
|
// =============================================================================
|
|
1262
1262
|
|
|
1263
1263
|
// Storage key for anonymous ID
|
|
1264
|
-
const ANONYMOUS_ID_KEY = '@rejourney_anonymous_id';
|
|
1264
|
+
// const ANONYMOUS_ID_KEY = '@rejourney_anonymous_id';
|
|
1265
1265
|
|
|
1266
1266
|
/**
|
|
1267
1267
|
* Generate a persistent anonymous ID
|
|
@@ -1272,40 +1272,12 @@ function generateAnonymousId(): string {
|
|
|
1272
1272
|
return `anon_${timestamp}_${random}`;
|
|
1273
1273
|
}
|
|
1274
1274
|
|
|
1275
|
-
/**
|
|
1276
|
-
* Initialize anonymous ID - tries to load from storage, generates new if not found
|
|
1277
|
-
* This is called internally and runs asynchronously
|
|
1278
|
-
*/
|
|
1279
|
-
async function initAnonymousId(): Promise<void> {
|
|
1280
|
-
try {
|
|
1281
|
-
// Try to load from AsyncStorage
|
|
1282
|
-
const AsyncStorage = require('@react-native-async-storage/async-storage').default;
|
|
1283
|
-
const storedId = await AsyncStorage.getItem(ANONYMOUS_ID_KEY);
|
|
1284
|
-
|
|
1285
|
-
if (storedId) {
|
|
1286
|
-
anonymousId = storedId;
|
|
1287
|
-
} else {
|
|
1288
|
-
// Generate new ID and persist
|
|
1289
|
-
anonymousId = generateAnonymousId();
|
|
1290
|
-
await AsyncStorage.setItem(ANONYMOUS_ID_KEY, anonymousId);
|
|
1291
|
-
}
|
|
1292
|
-
} catch {
|
|
1293
|
-
// AsyncStorage not available or error - just generate without persistence
|
|
1294
|
-
if (!anonymousId) {
|
|
1295
|
-
anonymousId = generateAnonymousId();
|
|
1296
|
-
}
|
|
1297
|
-
}
|
|
1298
|
-
}
|
|
1299
|
-
|
|
1300
1275
|
/**
|
|
1301
1276
|
* Get the anonymous ID (synchronous - returns generated ID immediately)
|
|
1302
|
-
* For persistent ID, call initAnonymousId() first
|
|
1303
1277
|
*/
|
|
1304
1278
|
export function getAnonymousId(): string {
|
|
1305
1279
|
if (!anonymousId) {
|
|
1306
1280
|
anonymousId = generateAnonymousId();
|
|
1307
|
-
// Try to persist asynchronously (fire and forget)
|
|
1308
|
-
initAnonymousId().catch(() => { });
|
|
1309
1281
|
}
|
|
1310
1282
|
return anonymousId;
|
|
1311
1283
|
}
|
|
@@ -1318,11 +1290,10 @@ export async function ensurePersistentAnonymousId(): Promise<string> {
|
|
|
1318
1290
|
if (anonymousId) return anonymousId;
|
|
1319
1291
|
if (!anonymousIdPromise) {
|
|
1320
1292
|
anonymousIdPromise = (async () => {
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
return anonymousId;
|
|
1293
|
+
// Just use the load logic which now delegates to native or memory
|
|
1294
|
+
const id = await loadAnonymousId();
|
|
1295
|
+
anonymousId = id;
|
|
1296
|
+
return id;
|
|
1326
1297
|
})();
|
|
1327
1298
|
}
|
|
1328
1299
|
return anonymousIdPromise;
|
|
@@ -1333,22 +1304,23 @@ export async function ensurePersistentAnonymousId(): Promise<string> {
|
|
|
1333
1304
|
* Call this at app startup for best results
|
|
1334
1305
|
*/
|
|
1335
1306
|
export async function loadAnonymousId(): Promise<string> {
|
|
1336
|
-
|
|
1337
|
-
|
|
1307
|
+
const nativeModule = getRejourneyNativeModule();
|
|
1308
|
+
if (nativeModule && nativeModule.getUserIdentity) {
|
|
1309
|
+
try {
|
|
1310
|
+
return await nativeModule.getUserIdentity() || generateAnonymousId();
|
|
1311
|
+
} catch {
|
|
1312
|
+
return generateAnonymousId();
|
|
1313
|
+
}
|
|
1314
|
+
}
|
|
1315
|
+
return generateAnonymousId();
|
|
1338
1316
|
}
|
|
1339
1317
|
|
|
1340
1318
|
/**
|
|
1341
|
-
* Set a custom anonymous ID
|
|
1319
|
+
* Set a custom anonymous ID
|
|
1342
1320
|
*/
|
|
1343
1321
|
export function setAnonymousId(id: string): void {
|
|
1344
1322
|
anonymousId = id;
|
|
1345
|
-
//
|
|
1346
|
-
try {
|
|
1347
|
-
const AsyncStorage = require('@react-native-async-storage/async-storage').default;
|
|
1348
|
-
AsyncStorage.setItem(ANONYMOUS_ID_KEY, id).catch(() => { });
|
|
1349
|
-
} catch {
|
|
1350
|
-
// Ignore if AsyncStorage not available
|
|
1351
|
-
}
|
|
1323
|
+
// No-op for async persistence as we moved to native-only or memory-only
|
|
1352
1324
|
}
|
|
1353
1325
|
|
|
1354
1326
|
// =============================================================================
|