riuve-rn 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.
- package/LICENSE +21 -0
- package/README.md +848 -0
- package/dist/Riuve.d.ts +91 -0
- package/dist/Riuve.d.ts.map +1 -0
- package/dist/Riuve.js +402 -0
- package/dist/Rive.d.ts +91 -0
- package/dist/Rive.d.ts.map +1 -0
- package/dist/Rive.js +402 -0
- package/dist/adapters/deviceInfo/ExpoDeviceInfo.d.ts +13 -0
- package/dist/adapters/deviceInfo/ExpoDeviceInfo.d.ts.map +1 -0
- package/dist/adapters/deviceInfo/ExpoDeviceInfo.js +91 -0
- package/dist/adapters/deviceInfo/FallbackDeviceInfo.d.ts +13 -0
- package/dist/adapters/deviceInfo/FallbackDeviceInfo.d.ts.map +1 -0
- package/dist/adapters/deviceInfo/FallbackDeviceInfo.js +36 -0
- package/dist/adapters/deviceInfo/NativeDeviceInfo.d.ts +17 -0
- package/dist/adapters/deviceInfo/NativeDeviceInfo.d.ts.map +1 -0
- package/dist/adapters/deviceInfo/NativeDeviceInfo.js +83 -0
- package/dist/adapters/deviceInfo/index.d.ts +14 -0
- package/dist/adapters/deviceInfo/index.d.ts.map +1 -0
- package/dist/adapters/deviceInfo/index.js +38 -0
- package/dist/adapters/deviceInfo/types.d.ts +25 -0
- package/dist/adapters/deviceInfo/types.d.ts.map +1 -0
- package/dist/adapters/deviceInfo/types.js +7 -0
- package/dist/adapters/network/ExpoNetworkManager.d.ts +20 -0
- package/dist/adapters/network/ExpoNetworkManager.d.ts.map +1 -0
- package/dist/adapters/network/ExpoNetworkManager.js +114 -0
- package/dist/adapters/network/FallbackNetworkManager.d.ts +15 -0
- package/dist/adapters/network/FallbackNetworkManager.d.ts.map +1 -0
- package/dist/adapters/network/FallbackNetworkManager.js +27 -0
- package/dist/adapters/network/NativeNetworkManager.d.ts +20 -0
- package/dist/adapters/network/NativeNetworkManager.d.ts.map +1 -0
- package/dist/adapters/network/NativeNetworkManager.js +68 -0
- package/dist/adapters/network/index.d.ts +14 -0
- package/dist/adapters/network/index.d.ts.map +1 -0
- package/dist/adapters/network/index.js +38 -0
- package/dist/adapters/network/types.d.ts +28 -0
- package/dist/adapters/network/types.d.ts.map +1 -0
- package/dist/adapters/network/types.js +7 -0
- package/dist/adapters/utils/moduleDetector.d.ts +17 -0
- package/dist/adapters/utils/moduleDetector.d.ts.map +1 -0
- package/dist/adapters/utils/moduleDetector.js +32 -0
- package/dist/constants.d.ts +41 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +43 -0
- package/dist/core/ApiClient.d.ts +49 -0
- package/dist/core/ApiClient.d.ts.map +1 -0
- package/dist/core/ApiClient.js +184 -0
- package/dist/core/DeviceInfo.d.ts +27 -0
- package/dist/core/DeviceInfo.d.ts.map +1 -0
- package/dist/core/DeviceInfo.js +69 -0
- package/dist/core/EventQueue.d.ts +71 -0
- package/dist/core/EventQueue.d.ts.map +1 -0
- package/dist/core/EventQueue.js +216 -0
- package/dist/core/Storage.d.ts +29 -0
- package/dist/core/Storage.d.ts.map +1 -0
- package/dist/core/Storage.js +88 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +17 -0
- package/dist/managers/BatchManager.d.ts +50 -0
- package/dist/managers/BatchManager.d.ts.map +1 -0
- package/dist/managers/BatchManager.js +277 -0
- package/dist/managers/IdentityManager.d.ts +47 -0
- package/dist/managers/IdentityManager.d.ts.map +1 -0
- package/dist/managers/IdentityManager.js +135 -0
- package/dist/managers/NetworkManager.d.ts +32 -0
- package/dist/managers/NetworkManager.d.ts.map +1 -0
- package/dist/managers/NetworkManager.js +67 -0
- package/dist/types/api.d.ts +65 -0
- package/dist/types/api.d.ts.map +1 -0
- package/dist/types/api.js +15 -0
- package/dist/types/config.d.ts +32 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/config.js +5 -0
- package/dist/types/events.d.ts +63 -0
- package/dist/types/events.d.ts.map +1 -0
- package/dist/types/events.js +5 -0
- package/dist/types/index.d.ts +8 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +23 -0
- package/dist/types/storage.d.ts +26 -0
- package/dist/types/storage.d.ts.map +1 -0
- package/dist/types/storage.js +5 -0
- package/dist/utils/fetchWithTimeout.d.ts +6 -0
- package/dist/utils/fetchWithTimeout.d.ts.map +1 -0
- package/dist/utils/fetchWithTimeout.js +28 -0
- package/dist/utils/logger.d.ts +21 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +39 -0
- package/dist/utils/retry.d.ts +29 -0
- package/dist/utils/retry.d.ts.map +1 -0
- package/dist/utils/retry.js +78 -0
- package/dist/utils/uuid.d.ts +12 -0
- package/dist/utils/uuid.d.ts.map +1 -0
- package/dist/utils/uuid.js +27 -0
- package/dist/utils/validators.d.ts +32 -0
- package/dist/utils/validators.d.ts.map +1 -0
- package/dist/utils/validators.js +68 -0
- package/package.json +65 -0
package/dist/Rive.js
ADDED
|
@@ -0,0 +1,402 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Rive SDK - Main SDK Class (Singleton)
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const uuid_1 = require("./utils/uuid");
|
|
7
|
+
const react_native_1 = require("react-native");
|
|
8
|
+
const EventQueue_1 = require("./core/EventQueue");
|
|
9
|
+
const ApiClient_1 = require("./core/ApiClient");
|
|
10
|
+
const DeviceInfo_1 = require("./core/DeviceInfo");
|
|
11
|
+
const Storage_1 = require("./core/Storage");
|
|
12
|
+
const IdentityManager_1 = require("./managers/IdentityManager");
|
|
13
|
+
const NetworkManager_1 = require("./managers/NetworkManager");
|
|
14
|
+
const BatchManager_1 = require("./managers/BatchManager");
|
|
15
|
+
const constants_1 = require("./constants");
|
|
16
|
+
const logger_1 = require("./utils/logger");
|
|
17
|
+
const validators_1 = require("./utils/validators");
|
|
18
|
+
class RiveSDK {
|
|
19
|
+
/**
|
|
20
|
+
* Private constructor for singleton pattern
|
|
21
|
+
*/
|
|
22
|
+
constructor() {
|
|
23
|
+
this.config = null;
|
|
24
|
+
this.isInitialized = false;
|
|
25
|
+
this.eventQueue = null;
|
|
26
|
+
this.apiClient = null;
|
|
27
|
+
this.identityManager = null;
|
|
28
|
+
this.networkManager = null;
|
|
29
|
+
this.batchManager = null;
|
|
30
|
+
this.appStateSubscription = null;
|
|
31
|
+
this.pendingEvents = [];
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Gets the singleton instance
|
|
35
|
+
*/
|
|
36
|
+
static getInstance() {
|
|
37
|
+
if (!RiveSDK.instance) {
|
|
38
|
+
RiveSDK.instance = new RiveSDK();
|
|
39
|
+
}
|
|
40
|
+
return RiveSDK.instance;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Initializes the SDK
|
|
44
|
+
*/
|
|
45
|
+
async initialize(apiKey, config) {
|
|
46
|
+
// Validate API key
|
|
47
|
+
(0, validators_1.validateApiKey)(apiKey);
|
|
48
|
+
// Build full config
|
|
49
|
+
this.config = {
|
|
50
|
+
...constants_1.DEFAULT_CONFIG,
|
|
51
|
+
...config,
|
|
52
|
+
apiKey,
|
|
53
|
+
};
|
|
54
|
+
// Enable debug mode if configured
|
|
55
|
+
logger_1.logger.setDebugMode(this.config.debugMode);
|
|
56
|
+
logger_1.logger.info('Initializing Rive SDK...');
|
|
57
|
+
logger_1.logger.debug('Config:', this.config);
|
|
58
|
+
try {
|
|
59
|
+
// Initialize managers
|
|
60
|
+
this.identityManager = new IdentityManager_1.IdentityManager();
|
|
61
|
+
const anonymousId = await this.identityManager.initialize();
|
|
62
|
+
this.networkManager = new NetworkManager_1.NetworkManager();
|
|
63
|
+
await this.networkManager.initialize();
|
|
64
|
+
// Initialize API client with hardcoded base URL
|
|
65
|
+
this.apiClient = new ApiClient_1.ApiClient(constants_1.API_BASE_URL, this.config.apiKey, this.config.maxRetries, this.config.retryDelay, this.config.requestTimeout);
|
|
66
|
+
// Initialize event queue
|
|
67
|
+
this.eventQueue = new EventQueue_1.EventQueue(this.config.batchSize, this.config.batchTimeout, this.config.maxQueueSize);
|
|
68
|
+
// Load persisted events from storage
|
|
69
|
+
await this.eventQueue.loadFromStorage();
|
|
70
|
+
// Initialize batch manager
|
|
71
|
+
this.batchManager = new BatchManager_1.BatchManager(this.eventQueue, this.apiClient, this.networkManager, this.identityManager, this.config.eventRetentionDays);
|
|
72
|
+
// Collect device info
|
|
73
|
+
const deviceInfo = await DeviceInfo_1.deviceInfoCollector.collect();
|
|
74
|
+
// Call initialize endpoint
|
|
75
|
+
if (this.networkManager.isConnected()) {
|
|
76
|
+
try {
|
|
77
|
+
await this.apiClient.initialize({
|
|
78
|
+
anonymous_id: anonymousId,
|
|
79
|
+
device_info: deviceInfo,
|
|
80
|
+
});
|
|
81
|
+
logger_1.logger.info('SDK initialized successfully on backend');
|
|
82
|
+
}
|
|
83
|
+
catch (error) {
|
|
84
|
+
logger_1.logger.warn('Failed to initialize on backend (will retry):', error);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
logger_1.logger.warn('Offline - backend initialization will occur when online');
|
|
89
|
+
}
|
|
90
|
+
// Setup app state listener for background flush
|
|
91
|
+
if (this.config.autoFlushOnBackground) {
|
|
92
|
+
this.setupAppStateListener();
|
|
93
|
+
}
|
|
94
|
+
// Process pending events (events that were tracked before initialization)
|
|
95
|
+
if (this.pendingEvents.length > 0) {
|
|
96
|
+
logger_1.logger.info(`Processing ${this.pendingEvents.length} pending events...`);
|
|
97
|
+
const anonymousId = this.identityManager.getAnonymousId();
|
|
98
|
+
const externalUserId = this.identityManager.getExternalUserId();
|
|
99
|
+
let processedCount = 0;
|
|
100
|
+
for (const pendingEvent of this.pendingEvents) {
|
|
101
|
+
try {
|
|
102
|
+
const event = {
|
|
103
|
+
id: (0, uuid_1.generateUUID)(),
|
|
104
|
+
name: pendingEvent.eventName,
|
|
105
|
+
properties: pendingEvent.eventProperties,
|
|
106
|
+
timestamp: pendingEvent.timestamp, // Use original timestamp
|
|
107
|
+
anonymousId,
|
|
108
|
+
externalUserId: externalUserId || undefined,
|
|
109
|
+
};
|
|
110
|
+
await this.eventQueue.enqueue(event);
|
|
111
|
+
processedCount++;
|
|
112
|
+
logger_1.logger.info(` Processed pending event: ${pendingEvent.eventName} (id: ${event.id})`);
|
|
113
|
+
}
|
|
114
|
+
catch (error) {
|
|
115
|
+
logger_1.logger.error(`Failed to process pending event '${pendingEvent.eventName}':`, error);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
logger_1.logger.info(`Successfully processed ${processedCount}/${this.pendingEvents.length} pending events`);
|
|
119
|
+
this.pendingEvents = []; // Clear pending events
|
|
120
|
+
}
|
|
121
|
+
this.isInitialized = true;
|
|
122
|
+
logger_1.logger.info('Rive SDK initialized successfully');
|
|
123
|
+
// Flush any offline queue
|
|
124
|
+
await this.batchManager.flushOfflineQueue();
|
|
125
|
+
}
|
|
126
|
+
catch (error) {
|
|
127
|
+
logger_1.logger.error('Failed to initialize SDK:', error);
|
|
128
|
+
throw error;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Identifies a user
|
|
133
|
+
*/
|
|
134
|
+
async identify(externalUserId, userProperties) {
|
|
135
|
+
this.ensureInitialized();
|
|
136
|
+
// Validate inputs
|
|
137
|
+
(0, validators_1.validateUserId)(externalUserId);
|
|
138
|
+
if (userProperties) {
|
|
139
|
+
(0, validators_1.validateUserProperties)(userProperties);
|
|
140
|
+
}
|
|
141
|
+
logger_1.logger.info(`Identifying user: ${externalUserId}`);
|
|
142
|
+
try {
|
|
143
|
+
// Update identity manager
|
|
144
|
+
await this.identityManager.identify(externalUserId, userProperties);
|
|
145
|
+
// Call identify endpoint if online
|
|
146
|
+
if (this.networkManager.isConnected()) {
|
|
147
|
+
try {
|
|
148
|
+
const anonymousId = this.identityManager.getAnonymousId();
|
|
149
|
+
await this.apiClient.identify({
|
|
150
|
+
anonymous_id: anonymousId,
|
|
151
|
+
external_user_id: externalUserId,
|
|
152
|
+
user_properties: userProperties,
|
|
153
|
+
});
|
|
154
|
+
logger_1.logger.info('User identified on backend successfully');
|
|
155
|
+
}
|
|
156
|
+
catch (error) {
|
|
157
|
+
logger_1.logger.warn('Failed to identify user on backend:', error);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
else {
|
|
161
|
+
logger_1.logger.warn('Offline - user will be identified when online');
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
catch (error) {
|
|
165
|
+
logger_1.logger.error('Failed to identify user:', error);
|
|
166
|
+
throw error;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Tracks an event
|
|
171
|
+
*/
|
|
172
|
+
async track(eventName, eventProperties) {
|
|
173
|
+
// Validate inputs
|
|
174
|
+
(0, validators_1.validateEventName)(eventName);
|
|
175
|
+
if (eventProperties) {
|
|
176
|
+
(0, validators_1.validateEventProperties)(eventProperties);
|
|
177
|
+
}
|
|
178
|
+
// If SDK is not initialized yet, add to pending events queue
|
|
179
|
+
if (!this.isInitialized) {
|
|
180
|
+
const timestamp = Date.now();
|
|
181
|
+
this.pendingEvents.push({
|
|
182
|
+
eventName,
|
|
183
|
+
eventProperties,
|
|
184
|
+
timestamp,
|
|
185
|
+
});
|
|
186
|
+
const propsStr = eventProperties ? this.truncateJson(JSON.stringify(eventProperties), 150) : 'none';
|
|
187
|
+
logger_1.logger.info(`Event tracked: ${eventName}`);
|
|
188
|
+
logger_1.logger.info(` Properties: ${propsStr}`);
|
|
189
|
+
logger_1.logger.info(` Timestamp: ${new Date(timestamp).toISOString()}`);
|
|
190
|
+
logger_1.logger.info(` Status: Added to pending queue (SDK not initialized yet)`);
|
|
191
|
+
logger_1.logger.info(` Pending queue size: ${this.pendingEvents.length}`);
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
// SDK is initialized, proceed with normal flow
|
|
195
|
+
try {
|
|
196
|
+
const event = {
|
|
197
|
+
id: (0, uuid_1.generateUUID)(),
|
|
198
|
+
name: eventName,
|
|
199
|
+
properties: eventProperties,
|
|
200
|
+
timestamp: Date.now(),
|
|
201
|
+
anonymousId: this.identityManager.getAnonymousId(),
|
|
202
|
+
externalUserId: this.identityManager.getExternalUserId() || undefined,
|
|
203
|
+
};
|
|
204
|
+
const queueSizeBefore = this.eventQueue.size();
|
|
205
|
+
// Add to queue
|
|
206
|
+
await this.eventQueue.enqueue(event);
|
|
207
|
+
const queueSizeAfter = this.eventQueue.size();
|
|
208
|
+
const propsStr = eventProperties ? this.truncateJson(JSON.stringify(eventProperties), 150) : 'none';
|
|
209
|
+
logger_1.logger.info(`Event tracked: ${eventName}`);
|
|
210
|
+
logger_1.logger.info(` Properties: ${propsStr}`);
|
|
211
|
+
logger_1.logger.info(` Event ID: ${event.id.substring(0, 8)}...`);
|
|
212
|
+
logger_1.logger.info(` Timestamp: ${new Date(event.timestamp).toISOString()}`);
|
|
213
|
+
logger_1.logger.info(` Queue size: ${queueSizeBefore} -> ${queueSizeAfter}/${this.config.maxQueueSize}`);
|
|
214
|
+
logger_1.logger.info(` Status: Added to queue`);
|
|
215
|
+
}
|
|
216
|
+
catch (error) {
|
|
217
|
+
logger_1.logger.error(`Failed to track event '${eventName}':`, error);
|
|
218
|
+
throw error;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Sets the FCM token for push notifications
|
|
223
|
+
*/
|
|
224
|
+
async setFcmToken(token) {
|
|
225
|
+
this.ensureInitialized();
|
|
226
|
+
if (typeof token !== 'string' || token.trim().length === 0) {
|
|
227
|
+
throw new Error('FCM token must be a non-empty string');
|
|
228
|
+
}
|
|
229
|
+
logger_1.logger.info('Setting FCM token...');
|
|
230
|
+
try {
|
|
231
|
+
// Store token
|
|
232
|
+
await Storage_1.storage.set('FCM_TOKEN', token);
|
|
233
|
+
// Send to backend if online
|
|
234
|
+
if (this.networkManager.isConnected()) {
|
|
235
|
+
try {
|
|
236
|
+
const anonymousId = this.identityManager.getAnonymousId();
|
|
237
|
+
const externalUserId = this.identityManager.getExternalUserId();
|
|
238
|
+
await this.apiClient.setFcmToken({
|
|
239
|
+
anonymous_id: anonymousId,
|
|
240
|
+
external_user_id: externalUserId || undefined,
|
|
241
|
+
fcm_token: token,
|
|
242
|
+
});
|
|
243
|
+
logger_1.logger.info('FCM token set successfully');
|
|
244
|
+
}
|
|
245
|
+
catch (error) {
|
|
246
|
+
logger_1.logger.warn('Failed to set FCM token on backend:', error);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
else {
|
|
250
|
+
logger_1.logger.warn('Offline - FCM token will be sent when online');
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
catch (error) {
|
|
254
|
+
logger_1.logger.error('Failed to set FCM token:', error);
|
|
255
|
+
throw error;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Manually flushes all pending events
|
|
260
|
+
*/
|
|
261
|
+
async flush() {
|
|
262
|
+
this.ensureInitialized();
|
|
263
|
+
logger_1.logger.info('Manually flushing events...');
|
|
264
|
+
try {
|
|
265
|
+
await this.eventQueue.flush();
|
|
266
|
+
logger_1.logger.info('Flush completed');
|
|
267
|
+
}
|
|
268
|
+
catch (error) {
|
|
269
|
+
logger_1.logger.error('Flush failed:', error);
|
|
270
|
+
throw error;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Resets the SDK (new anonymous user)
|
|
275
|
+
*/
|
|
276
|
+
async reset() {
|
|
277
|
+
this.ensureInitialized();
|
|
278
|
+
logger_1.logger.info('Resetting SDK...');
|
|
279
|
+
try {
|
|
280
|
+
// Flush pending events
|
|
281
|
+
await this.flush();
|
|
282
|
+
// Reset identity
|
|
283
|
+
await this.identityManager.reset();
|
|
284
|
+
// Clear FCM token
|
|
285
|
+
await Storage_1.storage.remove('FCM_TOKEN');
|
|
286
|
+
logger_1.logger.info('SDK reset successfully');
|
|
287
|
+
}
|
|
288
|
+
catch (error) {
|
|
289
|
+
logger_1.logger.error('Failed to reset SDK:', error);
|
|
290
|
+
throw error;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* Gets the anonymous ID
|
|
295
|
+
*/
|
|
296
|
+
getAnonymousId() {
|
|
297
|
+
if (!this.isInitialized || !this.identityManager) {
|
|
298
|
+
return null;
|
|
299
|
+
}
|
|
300
|
+
return this.identityManager.getAnonymousId();
|
|
301
|
+
}
|
|
302
|
+
/**
|
|
303
|
+
* Gets the external user ID
|
|
304
|
+
*/
|
|
305
|
+
getExternalUserId() {
|
|
306
|
+
if (!this.isInitialized || !this.identityManager) {
|
|
307
|
+
return null;
|
|
308
|
+
}
|
|
309
|
+
return this.identityManager.getExternalUserId();
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* Gets the current configuration
|
|
313
|
+
*/
|
|
314
|
+
getConfig() {
|
|
315
|
+
return this.config ? { ...this.config } : null;
|
|
316
|
+
}
|
|
317
|
+
/**
|
|
318
|
+
* Gets the event queue size
|
|
319
|
+
*/
|
|
320
|
+
getQueueSize() {
|
|
321
|
+
if (!this.isInitialized || !this.eventQueue) {
|
|
322
|
+
return 0;
|
|
323
|
+
}
|
|
324
|
+
return this.eventQueue.size();
|
|
325
|
+
}
|
|
326
|
+
/**
|
|
327
|
+
* Gets the failed batch count
|
|
328
|
+
*/
|
|
329
|
+
async getFailedBatchCount() {
|
|
330
|
+
if (!this.isInitialized || !this.batchManager) {
|
|
331
|
+
return 0;
|
|
332
|
+
}
|
|
333
|
+
return this.batchManager.getFailedBatchCount();
|
|
334
|
+
}
|
|
335
|
+
/**
|
|
336
|
+
* Checks if the SDK is initialized
|
|
337
|
+
*/
|
|
338
|
+
isReady() {
|
|
339
|
+
return this.isInitialized;
|
|
340
|
+
}
|
|
341
|
+
/**
|
|
342
|
+
* Sets up app state listener for background flush
|
|
343
|
+
*/
|
|
344
|
+
setupAppStateListener() {
|
|
345
|
+
this.appStateSubscription = react_native_1.AppState.addEventListener('change', (nextAppState) => {
|
|
346
|
+
if (nextAppState === 'background' || nextAppState === 'inactive') {
|
|
347
|
+
logger_1.logger.info('App going to background, flushing events...');
|
|
348
|
+
this.flush().catch((error) => {
|
|
349
|
+
logger_1.logger.error('Background flush failed:', error);
|
|
350
|
+
});
|
|
351
|
+
}
|
|
352
|
+
});
|
|
353
|
+
}
|
|
354
|
+
/**
|
|
355
|
+
* Ensures the SDK is initialized before operations
|
|
356
|
+
*/
|
|
357
|
+
ensureInitialized() {
|
|
358
|
+
if (!this.isInitialized) {
|
|
359
|
+
throw new Error(constants_1.ERROR_MESSAGES.NOT_INITIALIZED);
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
/**
|
|
363
|
+
* Truncates JSON string if too long
|
|
364
|
+
*/
|
|
365
|
+
truncateJson(json, maxLength) {
|
|
366
|
+
if (json.length <= maxLength) {
|
|
367
|
+
return json;
|
|
368
|
+
}
|
|
369
|
+
return json.substring(0, maxLength) + '...';
|
|
370
|
+
}
|
|
371
|
+
/**
|
|
372
|
+
* Cleanup method (for testing or app shutdown)
|
|
373
|
+
*/
|
|
374
|
+
async cleanup() {
|
|
375
|
+
logger_1.logger.info('Cleaning up SDK...');
|
|
376
|
+
// Flush pending events
|
|
377
|
+
if (this.eventQueue) {
|
|
378
|
+
try {
|
|
379
|
+
await this.eventQueue.flush();
|
|
380
|
+
}
|
|
381
|
+
catch (error) {
|
|
382
|
+
logger_1.logger.warn('Failed to flush during cleanup:', error);
|
|
383
|
+
}
|
|
384
|
+
this.eventQueue.destroy();
|
|
385
|
+
}
|
|
386
|
+
// Cleanup network manager
|
|
387
|
+
if (this.networkManager) {
|
|
388
|
+
this.networkManager.cleanup();
|
|
389
|
+
}
|
|
390
|
+
// Remove app state listener
|
|
391
|
+
if (this.appStateSubscription) {
|
|
392
|
+
this.appStateSubscription.remove();
|
|
393
|
+
this.appStateSubscription = null;
|
|
394
|
+
}
|
|
395
|
+
this.isInitialized = false;
|
|
396
|
+
logger_1.logger.info('SDK cleanup completed');
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
RiveSDK.instance = null;
|
|
400
|
+
// Export singleton instance methods
|
|
401
|
+
const Rive = RiveSDK.getInstance();
|
|
402
|
+
exports.default = Rive;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Expo DeviceInfo Adapter
|
|
3
|
+
*
|
|
4
|
+
* Uses Expo SDK modules for device information.
|
|
5
|
+
* This adapter works in Expo Go without requiring a development build.
|
|
6
|
+
*/
|
|
7
|
+
import type { DeviceInfoAdapter, DeviceInfoType } from './types';
|
|
8
|
+
export declare class ExpoDeviceInfo implements DeviceInfoAdapter {
|
|
9
|
+
private cachedInfo;
|
|
10
|
+
collect(): Promise<DeviceInfoType>;
|
|
11
|
+
getCached(): DeviceInfoType | null;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=ExpoDeviceInfo.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ExpoDeviceInfo.d.ts","sourceRoot":"","sources":["../../../src/adapters/deviceInfo/ExpoDeviceInfo.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAEjE,qBAAa,cAAe,YAAW,iBAAiB;IACtD,OAAO,CAAC,UAAU,CAA+B;IAE3C,OAAO,IAAI,OAAO,CAAC,cAAc,CAAC;IA4CxC,SAAS,IAAI,cAAc,GAAG,IAAI;CAGnC"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Expo DeviceInfo Adapter
|
|
4
|
+
*
|
|
5
|
+
* Uses Expo SDK modules for device information.
|
|
6
|
+
* This adapter works in Expo Go without requiring a development build.
|
|
7
|
+
*/
|
|
8
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
9
|
+
if (k2 === undefined) k2 = k;
|
|
10
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
11
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
12
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
13
|
+
}
|
|
14
|
+
Object.defineProperty(o, k2, desc);
|
|
15
|
+
}) : (function(o, m, k, k2) {
|
|
16
|
+
if (k2 === undefined) k2 = k;
|
|
17
|
+
o[k2] = m[k];
|
|
18
|
+
}));
|
|
19
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
20
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
21
|
+
}) : function(o, v) {
|
|
22
|
+
o["default"] = v;
|
|
23
|
+
});
|
|
24
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
25
|
+
var ownKeys = function(o) {
|
|
26
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
27
|
+
var ar = [];
|
|
28
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
29
|
+
return ar;
|
|
30
|
+
};
|
|
31
|
+
return ownKeys(o);
|
|
32
|
+
};
|
|
33
|
+
return function (mod) {
|
|
34
|
+
if (mod && mod.__esModule) return mod;
|
|
35
|
+
var result = {};
|
|
36
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
37
|
+
__setModuleDefault(result, mod);
|
|
38
|
+
return result;
|
|
39
|
+
};
|
|
40
|
+
})();
|
|
41
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
42
|
+
exports.ExpoDeviceInfo = void 0;
|
|
43
|
+
const react_native_1 = require("react-native");
|
|
44
|
+
class ExpoDeviceInfo {
|
|
45
|
+
constructor() {
|
|
46
|
+
this.cachedInfo = null;
|
|
47
|
+
}
|
|
48
|
+
async collect() {
|
|
49
|
+
if (this.cachedInfo) {
|
|
50
|
+
return this.cachedInfo;
|
|
51
|
+
}
|
|
52
|
+
try {
|
|
53
|
+
// Lazy import - only import when this adapter is actually used
|
|
54
|
+
// @ts-ignore - expo modules are optional peer dependencies
|
|
55
|
+
const Device = await Promise.resolve().then(() => __importStar(require('expo-device')));
|
|
56
|
+
// @ts-ignore - expo modules are optional peer dependencies
|
|
57
|
+
const Application = await Promise.resolve().then(() => __importStar(require('expo-application')));
|
|
58
|
+
// @ts-ignore - expo modules are optional peer dependencies
|
|
59
|
+
const Localization = await Promise.resolve().then(() => __importStar(require('expo-localization')));
|
|
60
|
+
const platform = react_native_1.Platform.OS;
|
|
61
|
+
const systemVersion = Device.osVersion || react_native_1.Platform.Version.toString();
|
|
62
|
+
const osVersion = `${react_native_1.Platform.OS === 'ios' ? 'iOS' : 'Android'} ${systemVersion}`;
|
|
63
|
+
const deviceInfo = {
|
|
64
|
+
os_version: osVersion,
|
|
65
|
+
device_model: Device.modelName || 'Unknown',
|
|
66
|
+
app_version: Application.nativeApplicationVersion || '1.0.0',
|
|
67
|
+
locale: Localization.locale || 'en-US',
|
|
68
|
+
platform,
|
|
69
|
+
manufacturer: Device.manufacturer || undefined,
|
|
70
|
+
brand: Device.brand || undefined,
|
|
71
|
+
};
|
|
72
|
+
this.cachedInfo = deviceInfo;
|
|
73
|
+
return deviceInfo;
|
|
74
|
+
}
|
|
75
|
+
catch (error) {
|
|
76
|
+
// Fallback if expo modules fail
|
|
77
|
+
const fallbackInfo = {
|
|
78
|
+
os_version: react_native_1.Platform.Version.toString(),
|
|
79
|
+
device_model: 'Unknown',
|
|
80
|
+
app_version: '1.0.0',
|
|
81
|
+
locale: 'en-US',
|
|
82
|
+
platform: react_native_1.Platform.OS,
|
|
83
|
+
};
|
|
84
|
+
return fallbackInfo;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
getCached() {
|
|
88
|
+
return this.cachedInfo;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
exports.ExpoDeviceInfo = ExpoDeviceInfo;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fallback DeviceInfo Adapter
|
|
3
|
+
*
|
|
4
|
+
* Uses only React Native's Platform API for minimal device information.
|
|
5
|
+
* This adapter works in any React Native environment without any dependencies.
|
|
6
|
+
*/
|
|
7
|
+
import type { DeviceInfoAdapter, DeviceInfoType } from './types';
|
|
8
|
+
export declare class FallbackDeviceInfo implements DeviceInfoAdapter {
|
|
9
|
+
private cachedInfo;
|
|
10
|
+
collect(): Promise<DeviceInfoType>;
|
|
11
|
+
getCached(): DeviceInfoType | null;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=FallbackDeviceInfo.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FallbackDeviceInfo.d.ts","sourceRoot":"","sources":["../../../src/adapters/deviceInfo/FallbackDeviceInfo.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAEjE,qBAAa,kBAAmB,YAAW,iBAAiB;IAC1D,OAAO,CAAC,UAAU,CAA+B;IAE3C,OAAO,IAAI,OAAO,CAAC,cAAc,CAAC;IAqBxC,SAAS,IAAI,cAAc,GAAG,IAAI;CAGnC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Fallback DeviceInfo Adapter
|
|
4
|
+
*
|
|
5
|
+
* Uses only React Native's Platform API for minimal device information.
|
|
6
|
+
* This adapter works in any React Native environment without any dependencies.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.FallbackDeviceInfo = void 0;
|
|
10
|
+
const react_native_1 = require("react-native");
|
|
11
|
+
class FallbackDeviceInfo {
|
|
12
|
+
constructor() {
|
|
13
|
+
this.cachedInfo = null;
|
|
14
|
+
}
|
|
15
|
+
async collect() {
|
|
16
|
+
if (this.cachedInfo) {
|
|
17
|
+
return this.cachedInfo;
|
|
18
|
+
}
|
|
19
|
+
const platform = react_native_1.Platform.OS;
|
|
20
|
+
const version = react_native_1.Platform.Version.toString();
|
|
21
|
+
const osVersion = `${react_native_1.Platform.OS === 'ios' ? 'iOS' : 'Android'} ${version}`;
|
|
22
|
+
const deviceInfo = {
|
|
23
|
+
os_version: osVersion,
|
|
24
|
+
device_model: 'Unknown',
|
|
25
|
+
app_version: '1.0.0',
|
|
26
|
+
locale: 'en-US',
|
|
27
|
+
platform,
|
|
28
|
+
};
|
|
29
|
+
this.cachedInfo = deviceInfo;
|
|
30
|
+
return deviceInfo;
|
|
31
|
+
}
|
|
32
|
+
getCached() {
|
|
33
|
+
return this.cachedInfo;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
exports.FallbackDeviceInfo = FallbackDeviceInfo;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Native DeviceInfo Adapter
|
|
3
|
+
*
|
|
4
|
+
* Uses react-native-device-info for maximum device information.
|
|
5
|
+
* This adapter provides the most comprehensive data but requires native modules.
|
|
6
|
+
*/
|
|
7
|
+
import type { DeviceInfoAdapter, DeviceInfoType } from './types';
|
|
8
|
+
export declare class NativeDeviceInfo implements DeviceInfoAdapter {
|
|
9
|
+
private cachedInfo;
|
|
10
|
+
collect(): Promise<DeviceInfoType>;
|
|
11
|
+
getCached(): DeviceInfoType | null;
|
|
12
|
+
/**
|
|
13
|
+
* Gets the device locale using NativeModules
|
|
14
|
+
*/
|
|
15
|
+
private getLocale;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=NativeDeviceInfo.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NativeDeviceInfo.d.ts","sourceRoot":"","sources":["../../../src/adapters/deviceInfo/NativeDeviceInfo.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAEjE,qBAAa,gBAAiB,YAAW,iBAAiB;IACxD,OAAO,CAAC,UAAU,CAA+B;IAE3C,OAAO,IAAI,OAAO,CAAC,cAAc,CAAC;IAoDxC,SAAS,IAAI,cAAc,GAAG,IAAI;IAIlC;;OAEG;IACH,OAAO,CAAC,SAAS;CAiBlB"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Native DeviceInfo Adapter
|
|
4
|
+
*
|
|
5
|
+
* Uses react-native-device-info for maximum device information.
|
|
6
|
+
* This adapter provides the most comprehensive data but requires native modules.
|
|
7
|
+
*/
|
|
8
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
9
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.NativeDeviceInfo = void 0;
|
|
13
|
+
const react_native_device_info_1 = __importDefault(require("react-native-device-info"));
|
|
14
|
+
const react_native_1 = require("react-native");
|
|
15
|
+
class NativeDeviceInfo {
|
|
16
|
+
constructor() {
|
|
17
|
+
this.cachedInfo = null;
|
|
18
|
+
}
|
|
19
|
+
async collect() {
|
|
20
|
+
if (this.cachedInfo) {
|
|
21
|
+
return this.cachedInfo;
|
|
22
|
+
}
|
|
23
|
+
try {
|
|
24
|
+
const [systemVersion, model, version, manufacturer, brand,] = await Promise.all([
|
|
25
|
+
react_native_device_info_1.default.getSystemVersion(),
|
|
26
|
+
react_native_device_info_1.default.getModel(),
|
|
27
|
+
react_native_device_info_1.default.getVersion(),
|
|
28
|
+
react_native_device_info_1.default.getManufacturer(),
|
|
29
|
+
react_native_device_info_1.default.getBrand(),
|
|
30
|
+
]);
|
|
31
|
+
// Get locale
|
|
32
|
+
const locale = this.getLocale();
|
|
33
|
+
const platform = react_native_1.Platform.OS === 'ios' ? 'ios' : 'android';
|
|
34
|
+
const osVersion = `${react_native_1.Platform.OS === 'ios' ? 'iOS' : 'Android'} ${systemVersion}`;
|
|
35
|
+
const deviceInfo = {
|
|
36
|
+
os_version: osVersion,
|
|
37
|
+
device_model: model,
|
|
38
|
+
app_version: version,
|
|
39
|
+
locale,
|
|
40
|
+
platform,
|
|
41
|
+
manufacturer,
|
|
42
|
+
brand,
|
|
43
|
+
};
|
|
44
|
+
this.cachedInfo = deviceInfo;
|
|
45
|
+
return deviceInfo;
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
// Fallback if native module fails
|
|
49
|
+
const fallbackInfo = {
|
|
50
|
+
os_version: `${react_native_1.Platform.OS} unknown`,
|
|
51
|
+
device_model: 'unknown',
|
|
52
|
+
app_version: '1.0.0',
|
|
53
|
+
locale: this.getLocale(),
|
|
54
|
+
platform: react_native_1.Platform.OS === 'ios' ? 'ios' : 'android',
|
|
55
|
+
};
|
|
56
|
+
return fallbackInfo;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
getCached() {
|
|
60
|
+
return this.cachedInfo;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Gets the device locale using NativeModules
|
|
64
|
+
*/
|
|
65
|
+
getLocale() {
|
|
66
|
+
try {
|
|
67
|
+
if (react_native_1.Platform.OS === 'ios') {
|
|
68
|
+
const locale = react_native_1.NativeModules.SettingsManager?.settings?.AppleLocale ||
|
|
69
|
+
react_native_1.NativeModules.SettingsManager?.settings?.AppleLanguages?.[0] ||
|
|
70
|
+
'en-US';
|
|
71
|
+
return locale;
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
const locale = react_native_1.NativeModules.I18nManager?.localeIdentifier || 'en-US';
|
|
75
|
+
return locale;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
return 'en-US';
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
exports.NativeDeviceInfo = NativeDeviceInfo;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DeviceInfo Adapter Selector
|
|
3
|
+
*
|
|
4
|
+
* Automatically detects available modules and selects the best adapter:
|
|
5
|
+
* 1. NativeDeviceInfo (react-native-device-info) - Best performance & data
|
|
6
|
+
* 2. ExpoDeviceInfo (expo-device, expo-application) - Expo Go compatible
|
|
7
|
+
* 3. FallbackDeviceInfo (Platform API only) - Always works
|
|
8
|
+
*/
|
|
9
|
+
import type { DeviceInfoAdapter } from './types';
|
|
10
|
+
/**
|
|
11
|
+
* Gets the appropriate DeviceInfo adapter for the current environment
|
|
12
|
+
*/
|
|
13
|
+
export declare function getDeviceInfoAdapter(): DeviceInfoAdapter;
|
|
14
|
+
//# sourceMappingURL=index.d.ts.map
|