@datalyr/react-native 1.7.1 → 1.7.3
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 +4 -2
- package/lib/auto-events.d.ts +1 -10
- package/lib/auto-events.js +3 -64
- package/lib/datalyr-sdk.d.ts +3 -5
- package/lib/datalyr-sdk.js +26 -17
- package/package.json +1 -1
- package/src/auto-events.ts +3 -72
- package/src/datalyr-sdk-expo.ts +25 -16
- package/src/datalyr-sdk.ts +26 -19
package/README.md
CHANGED
|
@@ -271,6 +271,8 @@ await Datalyr.trackAddPaymentInfo(true);
|
|
|
271
271
|
|
|
272
272
|
### Revenue Events
|
|
273
273
|
|
|
274
|
+
> **Important:** If you use **Superwall** or **RevenueCat**, do not use `trackPurchase()`, `trackSubscription()`, or `trackRevenue()` for revenue attribution. These fire client-side before payment is confirmed, so trials and failed payments get counted as revenue. Use the [Superwall](https://docs.datalyr.com/integrations/superwall) or [RevenueCat](https://docs.datalyr.com/integrations/revenuecat) webhook integration for revenue events instead — they only fire when real money changes hands. Use the SDK for behavioral events only (`track('paywall_view')`, `track('trial_start')`, `screen()`, `identify()`, etc.).
|
|
275
|
+
|
|
274
276
|
Track revenue with automatic SKAdNetwork encoding:
|
|
275
277
|
|
|
276
278
|
```typescript
|
|
@@ -845,7 +847,7 @@ A real landing page with a download button. Better ad platform compliance, highe
|
|
|
845
847
|
<meta charset="utf-8">
|
|
846
848
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
847
849
|
<title>Download Your App</title>
|
|
848
|
-
<script src="https://
|
|
850
|
+
<script src="https://track.datalyr.com/dl.js" data-workspace-id="YOUR_WORKSPACE_ID"></script>
|
|
849
851
|
</head>
|
|
850
852
|
<body>
|
|
851
853
|
<h1>Download Our App</h1>
|
|
@@ -880,7 +882,7 @@ Instant redirect -- no visible content, user goes straight to app store.
|
|
|
880
882
|
<!DOCTYPE html>
|
|
881
883
|
<html>
|
|
882
884
|
<head>
|
|
883
|
-
<script src="https://
|
|
885
|
+
<script src="https://track.datalyr.com/dl.js" data-workspace-id="YOUR_WORKSPACE_ID"></script>
|
|
884
886
|
<script>
|
|
885
887
|
window.addEventListener('DOMContentLoaded', function() {
|
|
886
888
|
var isAndroid = /android/i.test(navigator.userAgent);
|
package/lib/auto-events.d.ts
CHANGED
|
@@ -16,7 +16,6 @@ export declare class AutoEventsManager {
|
|
|
16
16
|
private config;
|
|
17
17
|
private currentSession;
|
|
18
18
|
private lastScreenName;
|
|
19
|
-
private performanceMarks;
|
|
20
19
|
private trackEvent;
|
|
21
20
|
constructor(trackEvent: (eventName: string, properties: Record<string, any>) => Promise<void>, config?: Partial<AutoEventConfig>);
|
|
22
21
|
/**
|
|
@@ -59,17 +58,9 @@ export declare class AutoEventsManager {
|
|
|
59
58
|
/**
|
|
60
59
|
* Track app launch performance
|
|
61
60
|
*/
|
|
62
|
-
private trackAppLaunchTime;
|
|
63
|
-
/**
|
|
64
|
-
* Track automatic app update
|
|
65
|
-
*/
|
|
66
|
-
trackAppUpdate(previousVersion: string, currentVersion: string): Promise<void>;
|
|
67
|
-
/**
|
|
68
|
-
* Track revenue event (purchases, subscriptions)
|
|
69
|
-
*/
|
|
70
|
-
trackRevenueEvent(eventName: string, properties?: Record<string, any>): Promise<void>;
|
|
71
61
|
/**
|
|
72
62
|
* Track custom automatic event (called by SDK)
|
|
63
|
+
* Updates session counters for activity tracking
|
|
73
64
|
*/
|
|
74
65
|
onEvent(eventName: string): Promise<void>;
|
|
75
66
|
/**
|
package/lib/auto-events.js
CHANGED
|
@@ -3,7 +3,6 @@ export class AutoEventsManager {
|
|
|
3
3
|
constructor(trackEvent, config = {}) {
|
|
4
4
|
this.currentSession = null;
|
|
5
5
|
this.lastScreenName = null;
|
|
6
|
-
this.performanceMarks = new Map();
|
|
7
6
|
this.trackEvent = trackEvent;
|
|
8
7
|
this.config = {
|
|
9
8
|
trackSessions: true,
|
|
@@ -25,10 +24,8 @@ export class AutoEventsManager {
|
|
|
25
24
|
await this.startSession();
|
|
26
25
|
this.setupSessionMonitoring();
|
|
27
26
|
}
|
|
28
|
-
//
|
|
29
|
-
|
|
30
|
-
this.trackAppLaunchTime();
|
|
31
|
-
}
|
|
27
|
+
// Auto events: session_start, session_end only
|
|
28
|
+
// app_install is tracked by the SDK directly, not via AutoEventsManager
|
|
32
29
|
debugLog('Automatic events manager initialized');
|
|
33
30
|
}
|
|
34
31
|
catch (error) {
|
|
@@ -195,63 +192,9 @@ export class AutoEventsManager {
|
|
|
195
192
|
/**
|
|
196
193
|
* Track app launch performance
|
|
197
194
|
*/
|
|
198
|
-
trackAppLaunchTime() {
|
|
199
|
-
try {
|
|
200
|
-
// Mark app launch start
|
|
201
|
-
this.performanceMarks.set('app_launch_start', Date.now());
|
|
202
|
-
// Track when app is fully loaded (after a short delay)
|
|
203
|
-
setTimeout(async () => {
|
|
204
|
-
const launchStart = this.performanceMarks.get('app_launch_start');
|
|
205
|
-
if (launchStart) {
|
|
206
|
-
const launchTime = Date.now() - launchStart;
|
|
207
|
-
await this.trackEvent('app_launch_performance', {
|
|
208
|
-
launch_time_ms: launchTime,
|
|
209
|
-
launch_time_seconds: launchTime / 1000,
|
|
210
|
-
});
|
|
211
|
-
debugLog('App launch time tracked:', launchTime);
|
|
212
|
-
}
|
|
213
|
-
}, 2000); // Wait 2 seconds for app to fully load
|
|
214
|
-
}
|
|
215
|
-
catch (error) {
|
|
216
|
-
errorLog('Error tracking app launch performance:', error);
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
/**
|
|
220
|
-
* Track automatic app update
|
|
221
|
-
*/
|
|
222
|
-
async trackAppUpdate(previousVersion, currentVersion) {
|
|
223
|
-
try {
|
|
224
|
-
await this.trackEvent('app_update', {
|
|
225
|
-
previous_version: previousVersion,
|
|
226
|
-
current_version: currentVersion,
|
|
227
|
-
timestamp: Date.now(),
|
|
228
|
-
});
|
|
229
|
-
debugLog('App update tracked:', { from: previousVersion, to: currentVersion });
|
|
230
|
-
}
|
|
231
|
-
catch (error) {
|
|
232
|
-
errorLog('Error tracking app update:', error);
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
/**
|
|
236
|
-
* Track revenue event (purchases, subscriptions)
|
|
237
|
-
*/
|
|
238
|
-
async trackRevenueEvent(eventName, properties) {
|
|
239
|
-
var _a;
|
|
240
|
-
try {
|
|
241
|
-
await this.trackEvent('revenue_event', {
|
|
242
|
-
event_name: eventName,
|
|
243
|
-
session_id: (_a = this.currentSession) === null || _a === void 0 ? void 0 : _a.sessionId,
|
|
244
|
-
timestamp: Date.now(),
|
|
245
|
-
...properties,
|
|
246
|
-
});
|
|
247
|
-
debugLog('Revenue event tracked:', eventName);
|
|
248
|
-
}
|
|
249
|
-
catch (error) {
|
|
250
|
-
errorLog('Error tracking revenue event:', error);
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
195
|
/**
|
|
254
196
|
* Track custom automatic event (called by SDK)
|
|
197
|
+
* Updates session counters for activity tracking
|
|
255
198
|
*/
|
|
256
199
|
async onEvent(eventName) {
|
|
257
200
|
try {
|
|
@@ -259,10 +202,6 @@ export class AutoEventsManager {
|
|
|
259
202
|
this.currentSession.events++;
|
|
260
203
|
this.currentSession.lastActivity = Date.now();
|
|
261
204
|
}
|
|
262
|
-
// Track specific automatic events based on event name
|
|
263
|
-
if (eventName === 'purchase' || eventName === 'subscription' || eventName.includes('purchase')) {
|
|
264
|
-
await this.trackRevenueEvent(eventName);
|
|
265
|
-
}
|
|
266
205
|
}
|
|
267
206
|
catch (error) {
|
|
268
207
|
errorLog('Error handling automatic event:', error);
|
package/lib/datalyr-sdk.d.ts
CHANGED
|
@@ -12,6 +12,9 @@ export declare class DatalyrSDK {
|
|
|
12
12
|
private cachedAdvertiserInfo;
|
|
13
13
|
private static conversionEncoder?;
|
|
14
14
|
private static debugEnabled;
|
|
15
|
+
/** Events that arrived before initialize() completed. Flushed once init finishes. */
|
|
16
|
+
private preInitQueue;
|
|
17
|
+
private static readonly PRE_INIT_QUEUE_MAX;
|
|
15
18
|
constructor();
|
|
16
19
|
/**
|
|
17
20
|
* Initialize the SDK with configuration
|
|
@@ -105,10 +108,6 @@ export declare class DatalyrSDK {
|
|
|
105
108
|
* Track app update manually
|
|
106
109
|
*/
|
|
107
110
|
trackAppUpdate(previousVersion: string, currentVersion: string): Promise<void>;
|
|
108
|
-
/**
|
|
109
|
-
* Track revenue event manually (purchases, subscriptions)
|
|
110
|
-
*/
|
|
111
|
-
trackRevenue(eventName: string, properties?: EventData): Promise<void>;
|
|
112
111
|
/**
|
|
113
112
|
* Update auto-events configuration
|
|
114
113
|
*/
|
|
@@ -273,7 +272,6 @@ export declare class Datalyr {
|
|
|
273
272
|
static getCurrentSession(): SessionData | null;
|
|
274
273
|
static endSession(): Promise<void>;
|
|
275
274
|
static trackAppUpdate(previousVersion: string, currentVersion: string): Promise<void>;
|
|
276
|
-
static trackRevenue(eventName: string, properties?: EventData): Promise<void>;
|
|
277
275
|
static updateAutoEventsConfig(config: Partial<AutoEventConfig>): void;
|
|
278
276
|
static trackAddToCart(value: number, currency?: string, productId?: string, productName?: string): Promise<void>;
|
|
279
277
|
static trackViewContent(contentId?: string, contentName?: string, contentType?: string, value?: number, currency?: string): Promise<void>;
|
package/lib/datalyr-sdk.js
CHANGED
|
@@ -16,6 +16,8 @@ export class DatalyrSDK {
|
|
|
16
16
|
this.appStateSubscription = null;
|
|
17
17
|
this.networkStatusUnsubscribe = null;
|
|
18
18
|
this.cachedAdvertiserInfo = null;
|
|
19
|
+
/** Events that arrived before initialize() completed. Flushed once init finishes. */
|
|
20
|
+
this.preInitQueue = [];
|
|
19
21
|
// Initialize state with defaults
|
|
20
22
|
this.state = {
|
|
21
23
|
initialized: false,
|
|
@@ -167,6 +169,15 @@ export class DatalyrSDK {
|
|
|
167
169
|
});
|
|
168
170
|
// SDK initialized successfully - set state before tracking install event
|
|
169
171
|
this.state.initialized = true;
|
|
172
|
+
// Flush any events that were queued before init completed (e.g. screen tracking)
|
|
173
|
+
if (this.preInitQueue.length > 0) {
|
|
174
|
+
debugLog(`Flushing ${this.preInitQueue.length} pre-init event(s)`);
|
|
175
|
+
const queued = [...this.preInitQueue];
|
|
176
|
+
this.preInitQueue = [];
|
|
177
|
+
for (const { eventName, eventData } of queued) {
|
|
178
|
+
await this.track(eventName, eventData);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
170
181
|
// Check for app install (after SDK is marked as initialized)
|
|
171
182
|
if (attributionManager.isInstall()) {
|
|
172
183
|
// iOS: Attempt deferred web-to-app attribution via IP matching before tracking install
|
|
@@ -177,7 +188,7 @@ export class DatalyrSDK {
|
|
|
177
188
|
const installData = await attributionManager.trackInstall();
|
|
178
189
|
await this.track('app_install', {
|
|
179
190
|
platform: Platform.OS === 'ios' || Platform.OS === 'android' ? Platform.OS : 'android',
|
|
180
|
-
sdk_version: '1.7.
|
|
191
|
+
sdk_version: '1.7.2',
|
|
181
192
|
...installData,
|
|
182
193
|
});
|
|
183
194
|
}
|
|
@@ -199,7 +210,14 @@ export class DatalyrSDK {
|
|
|
199
210
|
async track(eventName, eventData) {
|
|
200
211
|
try {
|
|
201
212
|
if (!this.state.initialized) {
|
|
202
|
-
|
|
213
|
+
// Queue events that arrive before init completes instead of dropping them
|
|
214
|
+
if (this.preInitQueue.length < DatalyrSDK.PRE_INIT_QUEUE_MAX) {
|
|
215
|
+
debugLog(`Queuing pre-init event: ${eventName}`);
|
|
216
|
+
this.preInitQueue.push({ eventName, eventData });
|
|
217
|
+
}
|
|
218
|
+
else {
|
|
219
|
+
errorLog('Pre-init event queue full, dropping event:', eventName);
|
|
220
|
+
}
|
|
203
221
|
return;
|
|
204
222
|
}
|
|
205
223
|
if (!validateEventName(eventName)) {
|
|
@@ -541,17 +559,10 @@ export class DatalyrSDK {
|
|
|
541
559
|
* Track app update manually
|
|
542
560
|
*/
|
|
543
561
|
async trackAppUpdate(previousVersion, currentVersion) {
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
/**
|
|
549
|
-
* Track revenue event manually (purchases, subscriptions)
|
|
550
|
-
*/
|
|
551
|
-
async trackRevenue(eventName, properties) {
|
|
552
|
-
if (this.autoEventsManager) {
|
|
553
|
-
await this.autoEventsManager.trackRevenueEvent(eventName, properties);
|
|
554
|
-
}
|
|
562
|
+
await this.track('app_update', {
|
|
563
|
+
previous_version: previousVersion,
|
|
564
|
+
current_version: currentVersion,
|
|
565
|
+
});
|
|
555
566
|
}
|
|
556
567
|
/**
|
|
557
568
|
* Update auto-events configuration
|
|
@@ -908,7 +919,7 @@ export class DatalyrSDK {
|
|
|
908
919
|
carrier: deviceInfo.carrier,
|
|
909
920
|
network_type: getNetworkType(),
|
|
910
921
|
timestamp: Date.now(),
|
|
911
|
-
sdk_version: '1.7.
|
|
922
|
+
sdk_version: '1.7.2',
|
|
912
923
|
// Advertiser data (IDFA/GAID, ATT status) for server-side postback
|
|
913
924
|
...(advertiserInfo ? {
|
|
914
925
|
idfa: advertiserInfo.idfa,
|
|
@@ -1089,6 +1100,7 @@ export class DatalyrSDK {
|
|
|
1089
1100
|
}
|
|
1090
1101
|
}
|
|
1091
1102
|
DatalyrSDK.debugEnabled = false;
|
|
1103
|
+
DatalyrSDK.PRE_INIT_QUEUE_MAX = 50;
|
|
1092
1104
|
// Create singleton instance
|
|
1093
1105
|
const datalyr = new DatalyrSDK();
|
|
1094
1106
|
// Export enhanced Datalyr class with static methods
|
|
@@ -1163,9 +1175,6 @@ export class Datalyr {
|
|
|
1163
1175
|
static async trackAppUpdate(previousVersion, currentVersion) {
|
|
1164
1176
|
await datalyr.trackAppUpdate(previousVersion, currentVersion);
|
|
1165
1177
|
}
|
|
1166
|
-
static async trackRevenue(eventName, properties) {
|
|
1167
|
-
await datalyr.trackRevenue(eventName, properties);
|
|
1168
|
-
}
|
|
1169
1178
|
static updateAutoEventsConfig(config) {
|
|
1170
1179
|
datalyr.updateAutoEventsConfig(config);
|
|
1171
1180
|
}
|
package/package.json
CHANGED
package/src/auto-events.ts
CHANGED
|
@@ -20,8 +20,6 @@ export class AutoEventsManager {
|
|
|
20
20
|
private config: AutoEventConfig;
|
|
21
21
|
private currentSession: SessionData | null = null;
|
|
22
22
|
private lastScreenName: string | null = null;
|
|
23
|
-
private performanceMarks: Map<string, number> = new Map();
|
|
24
|
-
|
|
25
23
|
// Event tracking callback
|
|
26
24
|
private trackEvent: (eventName: string, properties: Record<string, any>) => Promise<void>;
|
|
27
25
|
|
|
@@ -53,10 +51,8 @@ export class AutoEventsManager {
|
|
|
53
51
|
this.setupSessionMonitoring();
|
|
54
52
|
}
|
|
55
53
|
|
|
56
|
-
//
|
|
57
|
-
|
|
58
|
-
this.trackAppLaunchTime();
|
|
59
|
-
}
|
|
54
|
+
// Auto events: session_start, session_end only
|
|
55
|
+
// app_install is tracked by the SDK directly, not via AutoEventsManager
|
|
60
56
|
|
|
61
57
|
debugLog('Automatic events manager initialized');
|
|
62
58
|
|
|
@@ -237,68 +233,9 @@ export class AutoEventsManager {
|
|
|
237
233
|
/**
|
|
238
234
|
* Track app launch performance
|
|
239
235
|
*/
|
|
240
|
-
private trackAppLaunchTime(): void {
|
|
241
|
-
try {
|
|
242
|
-
// Mark app launch start
|
|
243
|
-
this.performanceMarks.set('app_launch_start', Date.now());
|
|
244
|
-
|
|
245
|
-
// Track when app is fully loaded (after a short delay)
|
|
246
|
-
setTimeout(async () => {
|
|
247
|
-
const launchStart = this.performanceMarks.get('app_launch_start');
|
|
248
|
-
if (launchStart) {
|
|
249
|
-
const launchTime = Date.now() - launchStart;
|
|
250
|
-
|
|
251
|
-
await this.trackEvent('app_launch_performance', {
|
|
252
|
-
launch_time_ms: launchTime,
|
|
253
|
-
launch_time_seconds: launchTime / 1000,
|
|
254
|
-
});
|
|
255
|
-
|
|
256
|
-
debugLog('App launch time tracked:', launchTime);
|
|
257
|
-
}
|
|
258
|
-
}, 2000); // Wait 2 seconds for app to fully load
|
|
259
|
-
|
|
260
|
-
} catch (error) {
|
|
261
|
-
errorLog('Error tracking app launch performance:', error as Error);
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
/**
|
|
266
|
-
* Track automatic app update
|
|
267
|
-
*/
|
|
268
|
-
async trackAppUpdate(previousVersion: string, currentVersion: string): Promise<void> {
|
|
269
|
-
try {
|
|
270
|
-
await this.trackEvent('app_update', {
|
|
271
|
-
previous_version: previousVersion,
|
|
272
|
-
current_version: currentVersion,
|
|
273
|
-
timestamp: Date.now(),
|
|
274
|
-
});
|
|
275
|
-
|
|
276
|
-
debugLog('App update tracked:', { from: previousVersion, to: currentVersion });
|
|
277
|
-
} catch (error) {
|
|
278
|
-
errorLog('Error tracking app update:', error as Error);
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
/**
|
|
283
|
-
* Track revenue event (purchases, subscriptions)
|
|
284
|
-
*/
|
|
285
|
-
async trackRevenueEvent(eventName: string, properties?: Record<string, any>): Promise<void> {
|
|
286
|
-
try {
|
|
287
|
-
await this.trackEvent('revenue_event', {
|
|
288
|
-
event_name: eventName,
|
|
289
|
-
session_id: this.currentSession?.sessionId,
|
|
290
|
-
timestamp: Date.now(),
|
|
291
|
-
...properties,
|
|
292
|
-
});
|
|
293
|
-
|
|
294
|
-
debugLog('Revenue event tracked:', eventName);
|
|
295
|
-
} catch (error) {
|
|
296
|
-
errorLog('Error tracking revenue event:', error as Error);
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
|
|
300
236
|
/**
|
|
301
237
|
* Track custom automatic event (called by SDK)
|
|
238
|
+
* Updates session counters for activity tracking
|
|
302
239
|
*/
|
|
303
240
|
async onEvent(eventName: string): Promise<void> {
|
|
304
241
|
try {
|
|
@@ -306,12 +243,6 @@ export class AutoEventsManager {
|
|
|
306
243
|
this.currentSession.events++;
|
|
307
244
|
this.currentSession.lastActivity = Date.now();
|
|
308
245
|
}
|
|
309
|
-
|
|
310
|
-
// Track specific automatic events based on event name
|
|
311
|
-
if (eventName === 'purchase' || eventName === 'subscription' || eventName.includes('purchase')) {
|
|
312
|
-
await this.trackRevenueEvent(eventName);
|
|
313
|
-
}
|
|
314
|
-
|
|
315
246
|
} catch (error) {
|
|
316
247
|
errorLog('Error handling automatic event:', error as Error);
|
|
317
248
|
}
|
package/src/datalyr-sdk-expo.ts
CHANGED
|
@@ -47,6 +47,9 @@ export class DatalyrSDKExpo {
|
|
|
47
47
|
private cachedAdvertiserInfo: any = null;
|
|
48
48
|
private static conversionEncoder?: ConversionValueEncoder;
|
|
49
49
|
private static debugEnabled = false;
|
|
50
|
+
/** Events that arrived before initialize() completed. Flushed once init finishes. */
|
|
51
|
+
private preInitQueue: Array<{ eventName: string; eventData?: EventData }> = [];
|
|
52
|
+
private static readonly PRE_INIT_QUEUE_MAX = 50;
|
|
50
53
|
|
|
51
54
|
constructor() {
|
|
52
55
|
this.state = {
|
|
@@ -192,11 +195,21 @@ export class DatalyrSDKExpo {
|
|
|
192
195
|
|
|
193
196
|
this.state.initialized = true;
|
|
194
197
|
|
|
198
|
+
// Flush any events that were queued before init completed (e.g. screen tracking)
|
|
199
|
+
if (this.preInitQueue.length > 0) {
|
|
200
|
+
debugLog(`Flushing ${this.preInitQueue.length} pre-init event(s)`);
|
|
201
|
+
const queued = [...this.preInitQueue];
|
|
202
|
+
this.preInitQueue = [];
|
|
203
|
+
for (const { eventName, eventData } of queued) {
|
|
204
|
+
await this.track(eventName, eventData);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
195
208
|
if (attributionManager.isInstall()) {
|
|
196
209
|
const installData = await attributionManager.trackInstall();
|
|
197
210
|
await this.track('app_install', {
|
|
198
211
|
platform: Platform.OS,
|
|
199
|
-
sdk_version: '1.7.
|
|
212
|
+
sdk_version: '1.7.2',
|
|
200
213
|
sdk_variant: 'expo',
|
|
201
214
|
...installData,
|
|
202
215
|
});
|
|
@@ -218,7 +231,12 @@ export class DatalyrSDKExpo {
|
|
|
218
231
|
async track(eventName: string, eventData?: EventData): Promise<void> {
|
|
219
232
|
try {
|
|
220
233
|
if (!this.state.initialized) {
|
|
221
|
-
|
|
234
|
+
if (this.preInitQueue.length < DatalyrSDKExpo.PRE_INIT_QUEUE_MAX) {
|
|
235
|
+
debugLog(`Queuing pre-init event: ${eventName}`);
|
|
236
|
+
this.preInitQueue.push({ eventName, eventData });
|
|
237
|
+
} else {
|
|
238
|
+
errorLog('Pre-init event queue full, dropping event:', eventName as unknown as Error);
|
|
239
|
+
}
|
|
222
240
|
return;
|
|
223
241
|
}
|
|
224
242
|
|
|
@@ -471,15 +489,10 @@ export class DatalyrSDKExpo {
|
|
|
471
489
|
}
|
|
472
490
|
|
|
473
491
|
async trackAppUpdate(previousVersion: string, currentVersion: string): Promise<void> {
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
async trackRevenue(eventName: string, properties?: EventData): Promise<void> {
|
|
480
|
-
if (this.autoEventsManager) {
|
|
481
|
-
await this.autoEventsManager.trackRevenueEvent(eventName, properties);
|
|
482
|
-
}
|
|
492
|
+
await this.track('app_update', {
|
|
493
|
+
previous_version: previousVersion,
|
|
494
|
+
current_version: currentVersion,
|
|
495
|
+
});
|
|
483
496
|
}
|
|
484
497
|
|
|
485
498
|
updateAutoEventsConfig(config: Partial<AutoEventConfig>): void {
|
|
@@ -792,7 +805,7 @@ export class DatalyrSDKExpo {
|
|
|
792
805
|
carrier: deviceInfo.carrier,
|
|
793
806
|
network_type: networkType,
|
|
794
807
|
timestamp: Date.now(),
|
|
795
|
-
sdk_version: '1.7.
|
|
808
|
+
sdk_version: '1.7.2',
|
|
796
809
|
sdk_variant: 'expo',
|
|
797
810
|
// Advertiser data (IDFA/GAID, ATT status) for server-side postback
|
|
798
811
|
...(advertiserInfo ? {
|
|
@@ -993,10 +1006,6 @@ export class DatalyrExpo {
|
|
|
993
1006
|
await datalyrExpo.trackAppUpdate(previousVersion, currentVersion);
|
|
994
1007
|
}
|
|
995
1008
|
|
|
996
|
-
static async trackRevenue(eventName: string, properties?: EventData): Promise<void> {
|
|
997
|
-
await datalyrExpo.trackRevenue(eventName, properties);
|
|
998
|
-
}
|
|
999
|
-
|
|
1000
1009
|
static updateAutoEventsConfig(config: Partial<AutoEventConfig>): void {
|
|
1001
1010
|
datalyrExpo.updateAutoEventsConfig(config);
|
|
1002
1011
|
}
|
package/src/datalyr-sdk.ts
CHANGED
|
@@ -45,6 +45,9 @@ export class DatalyrSDK {
|
|
|
45
45
|
private cachedAdvertiserInfo: any = null;
|
|
46
46
|
private static conversionEncoder?: ConversionValueEncoder;
|
|
47
47
|
private static debugEnabled = false;
|
|
48
|
+
/** Events that arrived before initialize() completed. Flushed once init finishes. */
|
|
49
|
+
private preInitQueue: Array<{ eventName: string; eventData?: EventData }> = [];
|
|
50
|
+
private static readonly PRE_INIT_QUEUE_MAX = 50;
|
|
48
51
|
|
|
49
52
|
constructor() {
|
|
50
53
|
// Initialize state with defaults
|
|
@@ -217,6 +220,16 @@ export class DatalyrSDK {
|
|
|
217
220
|
// SDK initialized successfully - set state before tracking install event
|
|
218
221
|
this.state.initialized = true;
|
|
219
222
|
|
|
223
|
+
// Flush any events that were queued before init completed (e.g. screen tracking)
|
|
224
|
+
if (this.preInitQueue.length > 0) {
|
|
225
|
+
debugLog(`Flushing ${this.preInitQueue.length} pre-init event(s)`);
|
|
226
|
+
const queued = [...this.preInitQueue];
|
|
227
|
+
this.preInitQueue = [];
|
|
228
|
+
for (const { eventName, eventData } of queued) {
|
|
229
|
+
await this.track(eventName, eventData);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
220
233
|
// Check for app install (after SDK is marked as initialized)
|
|
221
234
|
if (attributionManager.isInstall()) {
|
|
222
235
|
// iOS: Attempt deferred web-to-app attribution via IP matching before tracking install
|
|
@@ -228,7 +241,7 @@ export class DatalyrSDK {
|
|
|
228
241
|
const installData = await attributionManager.trackInstall();
|
|
229
242
|
await this.track('app_install', {
|
|
230
243
|
platform: Platform.OS === 'ios' || Platform.OS === 'android' ? Platform.OS : 'android',
|
|
231
|
-
sdk_version: '1.7.
|
|
244
|
+
sdk_version: '1.7.2',
|
|
232
245
|
...installData,
|
|
233
246
|
});
|
|
234
247
|
}
|
|
@@ -252,7 +265,13 @@ export class DatalyrSDK {
|
|
|
252
265
|
async track(eventName: string, eventData?: EventData): Promise<void> {
|
|
253
266
|
try {
|
|
254
267
|
if (!this.state.initialized) {
|
|
255
|
-
|
|
268
|
+
// Queue events that arrive before init completes instead of dropping them
|
|
269
|
+
if (this.preInitQueue.length < DatalyrSDK.PRE_INIT_QUEUE_MAX) {
|
|
270
|
+
debugLog(`Queuing pre-init event: ${eventName}`);
|
|
271
|
+
this.preInitQueue.push({ eventName, eventData });
|
|
272
|
+
} else {
|
|
273
|
+
errorLog('Pre-init event queue full, dropping event:', eventName as unknown as Error);
|
|
274
|
+
}
|
|
256
275
|
return;
|
|
257
276
|
}
|
|
258
277
|
|
|
@@ -657,18 +676,10 @@ export class DatalyrSDK {
|
|
|
657
676
|
* Track app update manually
|
|
658
677
|
*/
|
|
659
678
|
async trackAppUpdate(previousVersion: string, currentVersion: string): Promise<void> {
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
/**
|
|
666
|
-
* Track revenue event manually (purchases, subscriptions)
|
|
667
|
-
*/
|
|
668
|
-
async trackRevenue(eventName: string, properties?: EventData): Promise<void> {
|
|
669
|
-
if (this.autoEventsManager) {
|
|
670
|
-
await this.autoEventsManager.trackRevenueEvent(eventName, properties);
|
|
671
|
-
}
|
|
679
|
+
await this.track('app_update', {
|
|
680
|
+
previous_version: previousVersion,
|
|
681
|
+
current_version: currentVersion,
|
|
682
|
+
});
|
|
672
683
|
}
|
|
673
684
|
|
|
674
685
|
/**
|
|
@@ -1086,7 +1097,7 @@ export class DatalyrSDK {
|
|
|
1086
1097
|
carrier: deviceInfo.carrier,
|
|
1087
1098
|
network_type: getNetworkType(),
|
|
1088
1099
|
timestamp: Date.now(),
|
|
1089
|
-
sdk_version: '1.7.
|
|
1100
|
+
sdk_version: '1.7.2',
|
|
1090
1101
|
// Advertiser data (IDFA/GAID, ATT status) for server-side postback
|
|
1091
1102
|
...(advertiserInfo ? {
|
|
1092
1103
|
idfa: advertiserInfo.idfa,
|
|
@@ -1390,10 +1401,6 @@ export class Datalyr {
|
|
|
1390
1401
|
await datalyr.trackAppUpdate(previousVersion, currentVersion);
|
|
1391
1402
|
}
|
|
1392
1403
|
|
|
1393
|
-
static async trackRevenue(eventName: string, properties?: EventData): Promise<void> {
|
|
1394
|
-
await datalyr.trackRevenue(eventName, properties);
|
|
1395
|
-
}
|
|
1396
|
-
|
|
1397
1404
|
static updateAutoEventsConfig(config: Partial<AutoEventConfig>): void {
|
|
1398
1405
|
datalyr.updateAutoEventsConfig(config);
|
|
1399
1406
|
}
|