@datalyr/react-native 1.5.0 → 1.6.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.
Files changed (38) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/README.md +82 -121
  3. package/android/build.gradle +0 -7
  4. package/android/src/main/java/com/datalyr/reactnative/DatalyrNativeModule.java +2 -380
  5. package/android/src/main/java/com/datalyr/reactnative/DatalyrPackage.java +1 -1
  6. package/datalyr-react-native.podspec +3 -7
  7. package/expo-module.config.json +4 -1
  8. package/ios/DatalyrNativeModule.swift +0 -266
  9. package/lib/datalyr-sdk.d.ts +14 -5
  10. package/lib/datalyr-sdk.js +90 -144
  11. package/lib/http-client.js +2 -2
  12. package/lib/index.d.ts +1 -1
  13. package/lib/index.js +1 -1
  14. package/lib/integrations/index.d.ts +3 -4
  15. package/lib/integrations/index.js +3 -4
  16. package/lib/native/DatalyrNativeBridge.d.ts +6 -22
  17. package/lib/native/DatalyrNativeBridge.js +6 -147
  18. package/lib/native/index.d.ts +1 -1
  19. package/lib/native/index.js +1 -1
  20. package/lib/types.d.ts +5 -19
  21. package/package.json +3 -5
  22. package/src/datalyr-sdk-expo.ts +96 -140
  23. package/src/datalyr-sdk.ts +102 -174
  24. package/src/http-client.ts +2 -2
  25. package/src/index.ts +1 -1
  26. package/src/integrations/index.ts +3 -4
  27. package/src/native/DatalyrNativeBridge.ts +6 -241
  28. package/src/native/index.ts +0 -2
  29. package/src/types.ts +11 -26
  30. package/src/utils-expo.ts +2 -2
  31. package/ios/DatalyrObjCExceptionCatcher.h +0 -14
  32. package/ios/DatalyrObjCExceptionCatcher.m +0 -30
  33. package/lib/integrations/meta-integration.d.ts +0 -77
  34. package/lib/integrations/meta-integration.js +0 -219
  35. package/lib/integrations/tiktok-integration.d.ts +0 -83
  36. package/lib/integrations/tiktok-integration.js +0 -360
  37. package/src/integrations/meta-integration.ts +0 -239
  38. package/src/integrations/tiktok-integration.ts +0 -363
@@ -31,7 +31,7 @@ import { journeyManager } from './journey';
31
31
  import { createAutoEventsManager, AutoEventsManager, SessionData } from './auto-events';
32
32
  import { ConversionValueEncoder, ConversionTemplates } from './ConversionValueEncoder';
33
33
  import { SKAdNetworkBridge } from './native/SKAdNetworkBridge';
34
- import { metaIntegration, tiktokIntegration, appleSearchAdsIntegration, playInstallReferrerIntegration } from './integrations';
34
+ import { appleSearchAdsIntegration, playInstallReferrerIntegration } from './integrations';
35
35
  import { AppleSearchAdsAttribution, AdvertiserInfoBridge } from './native/DatalyrNativeBridge';
36
36
  import { networkStatusManager } from './network-status';
37
37
 
@@ -199,28 +199,6 @@ export class DatalyrSDK {
199
199
  playInstallReferrerIntegration.initialize(),
200
200
  ];
201
201
 
202
- // Add Meta initialization if configured
203
- if (config.meta?.appId) {
204
- platformInitPromises.push(
205
- metaIntegration.initialize(config.meta, config.debug).then(async () => {
206
- // After Meta initializes, fetch deferred deep link
207
- if (config.enableAttribution !== false) {
208
- const deferredLink = await metaIntegration.fetchDeferredDeepLink();
209
- if (deferredLink) {
210
- await this.handleDeferredDeepLink(deferredLink);
211
- }
212
- }
213
- })
214
- );
215
- }
216
-
217
- // Add TikTok initialization if configured
218
- if (config.tiktok?.appId && config.tiktok?.tiktokAppId) {
219
- platformInitPromises.push(
220
- tiktokIntegration.initialize(config.tiktok, config.debug)
221
- );
222
- }
223
-
224
202
  // Wait for all platform integrations to complete
225
203
  await Promise.all(platformInitPromises);
226
204
 
@@ -232,8 +210,6 @@ export class DatalyrSDK {
232
210
  }
233
211
 
234
212
  debugLog('Platform integrations initialized', {
235
- meta: metaIntegration.isAvailable(),
236
- tiktok: tiktokIntegration.isAvailable(),
237
213
  appleSearchAds: appleSearchAdsIntegration.isAvailable(),
238
214
  playInstallReferrer: playInstallReferrerIntegration.isAvailable(),
239
215
  });
@@ -252,7 +228,7 @@ export class DatalyrSDK {
252
228
  const installData = await attributionManager.trackInstall();
253
229
  await this.track('app_install', {
254
230
  platform: Platform.OS === 'ios' || Platform.OS === 'android' ? Platform.OS : 'android',
255
- sdk_version: '1.4.9',
231
+ sdk_version: '1.6.1',
256
232
  ...installData,
257
233
  });
258
234
  }
@@ -361,31 +337,6 @@ export class DatalyrSDK {
361
337
  const dateOfBirth = (properties?.date_of_birth || properties?.dob || properties?.birthday) as string | undefined;
362
338
  const gender = properties?.gender as string | undefined;
363
339
  const city = properties?.city as string | undefined;
364
- const state = properties?.state as string | undefined;
365
- const zip = (properties?.zip || properties?.postal_code || properties?.zipcode) as string | undefined;
366
- const country = properties?.country as string | undefined;
367
-
368
- // Meta Advanced Matching
369
- if (metaIntegration.isAvailable()) {
370
- metaIntegration.setUserData({
371
- email,
372
- firstName,
373
- lastName,
374
- phone,
375
- dateOfBirth,
376
- gender,
377
- city,
378
- state,
379
- zip,
380
- country,
381
- });
382
- }
383
-
384
- // TikTok identification
385
- if (tiktokIntegration.isAvailable()) {
386
- tiktokIntegration.identify(email, phone, userId);
387
- }
388
-
389
340
  } catch (error) {
390
341
  errorLog('Error identifying user:', error as Error);
391
342
  }
@@ -589,11 +540,6 @@ export class DatalyrSDK {
589
540
  // Generate new session
590
541
  this.state.sessionId = await getOrCreateSessionId();
591
542
 
592
- // Clear user data from platform SDKs
593
- if (metaIntegration.isAvailable()) {
594
- metaIntegration.clearUserData();
595
- }
596
-
597
543
  debugLog('User data reset completed');
598
544
 
599
545
  } catch (error) {
@@ -773,16 +719,6 @@ export class DatalyrSDK {
773
719
  if (productId) properties.product_id = productId;
774
720
 
775
721
  await this.trackWithSKAdNetwork('purchase', properties);
776
-
777
- // Forward to Meta if available
778
- if (metaIntegration.isAvailable()) {
779
- metaIntegration.logPurchase(value, currency, { fb_content_id: productId });
780
- }
781
-
782
- // Forward to TikTok if available
783
- if (tiktokIntegration.isAvailable()) {
784
- tiktokIntegration.logPurchase(value, currency, productId, 'product');
785
- }
786
722
  }
787
723
 
788
724
  /**
@@ -797,16 +733,6 @@ export class DatalyrSDK {
797
733
  if (plan) properties.plan = plan;
798
734
 
799
735
  await this.trackWithSKAdNetwork('subscribe', properties);
800
-
801
- // Forward to Meta if available
802
- if (metaIntegration.isAvailable()) {
803
- metaIntegration.logEvent('Subscribe', value, { subscription_plan: plan });
804
- }
805
-
806
- // Forward to TikTok if available
807
- if (tiktokIntegration.isAvailable()) {
808
- tiktokIntegration.logSubscription(value, currency, plan);
809
- }
810
736
  }
811
737
 
812
738
  // MARK: - Standard E-commerce Events
@@ -825,20 +751,6 @@ export class DatalyrSDK {
825
751
  if (productName) properties.product_name = productName;
826
752
 
827
753
  await this.trackWithSKAdNetwork('add_to_cart', properties);
828
-
829
- // Forward to Meta
830
- if (metaIntegration.isAvailable()) {
831
- metaIntegration.logEvent('AddToCart', value, {
832
- currency,
833
- content_ids: productId ? [productId] : undefined,
834
- content_name: productName,
835
- });
836
- }
837
-
838
- // Forward to TikTok
839
- if (tiktokIntegration.isAvailable()) {
840
- tiktokIntegration.logAddToCart(value, currency, productId, 'product');
841
- }
842
754
  }
843
755
 
844
756
  /**
@@ -858,21 +770,6 @@ export class DatalyrSDK {
858
770
  if (currency) properties.currency = currency;
859
771
 
860
772
  await this.track('view_content', properties);
861
-
862
- // Forward to Meta
863
- if (metaIntegration.isAvailable()) {
864
- metaIntegration.logEvent('ViewContent', value, {
865
- content_ids: contentId ? [contentId] : undefined,
866
- content_name: contentName,
867
- content_type: contentType,
868
- currency,
869
- });
870
- }
871
-
872
- // Forward to TikTok
873
- if (tiktokIntegration.isAvailable()) {
874
- tiktokIntegration.logViewContent(contentId, contentName, contentType);
875
- }
876
773
  }
877
774
 
878
775
  /**
@@ -889,20 +786,6 @@ export class DatalyrSDK {
889
786
  if (productIds) properties.product_ids = productIds;
890
787
 
891
788
  await this.trackWithSKAdNetwork('initiate_checkout', properties);
892
-
893
- // Forward to Meta
894
- if (metaIntegration.isAvailable()) {
895
- metaIntegration.logEvent('InitiateCheckout', value, {
896
- currency,
897
- num_items: numItems,
898
- content_ids: productIds,
899
- });
900
- }
901
-
902
- // Forward to TikTok
903
- if (tiktokIntegration.isAvailable()) {
904
- tiktokIntegration.logInitiateCheckout(value, currency, numItems);
905
- }
906
789
  }
907
790
 
908
791
  /**
@@ -913,16 +796,6 @@ export class DatalyrSDK {
913
796
  if (method) properties.method = method;
914
797
 
915
798
  await this.trackWithSKAdNetwork('complete_registration', properties);
916
-
917
- // Forward to Meta
918
- if (metaIntegration.isAvailable()) {
919
- metaIntegration.logEvent('CompleteRegistration', undefined, { registration_method: method });
920
- }
921
-
922
- // Forward to TikTok
923
- if (tiktokIntegration.isAvailable()) {
924
- tiktokIntegration.logCompleteRegistration(method);
925
- }
926
799
  }
927
800
 
928
801
  /**
@@ -933,19 +806,6 @@ export class DatalyrSDK {
933
806
  if (resultIds) properties.result_ids = resultIds;
934
807
 
935
808
  await this.track('search', properties);
936
-
937
- // Forward to Meta
938
- if (metaIntegration.isAvailable()) {
939
- metaIntegration.logEvent('Search', undefined, {
940
- search_string: query,
941
- content_ids: resultIds,
942
- });
943
- }
944
-
945
- // Forward to TikTok
946
- if (tiktokIntegration.isAvailable()) {
947
- tiktokIntegration.logSearch(query);
948
- }
949
809
  }
950
810
 
951
811
  /**
@@ -957,16 +817,6 @@ export class DatalyrSDK {
957
817
  if (currency) properties.currency = currency;
958
818
 
959
819
  await this.trackWithSKAdNetwork('lead', properties);
960
-
961
- // Forward to Meta
962
- if (metaIntegration.isAvailable()) {
963
- metaIntegration.logEvent('Lead', value, { currency });
964
- }
965
-
966
- // Forward to TikTok
967
- if (tiktokIntegration.isAvailable()) {
968
- tiktokIntegration.logLead(value, currency);
969
- }
970
820
  }
971
821
 
972
822
  /**
@@ -974,16 +824,6 @@ export class DatalyrSDK {
974
824
  */
975
825
  async trackAddPaymentInfo(success = true): Promise<void> {
976
826
  await this.track('add_payment_info', { success });
977
-
978
- // Forward to Meta
979
- if (metaIntegration.isAvailable()) {
980
- metaIntegration.logEvent('AddPaymentInfo', undefined, { success: success ? 1 : 0 });
981
- }
982
-
983
- // Forward to TikTok
984
- if (tiktokIntegration.isAvailable()) {
985
- tiktokIntegration.logAddPaymentInfo(success);
986
- }
987
827
  }
988
828
 
989
829
  // MARK: - Platform Integration Methods
@@ -992,16 +832,14 @@ export class DatalyrSDK {
992
832
  * Get deferred attribution data from platform SDKs
993
833
  */
994
834
  getDeferredAttributionData(): DeferredDeepLinkResult | null {
995
- return metaIntegration.getDeferredDeepLinkData();
835
+ return null;
996
836
  }
997
837
 
998
838
  /**
999
839
  * Get platform integration status
1000
840
  */
1001
- getPlatformIntegrationStatus(): { meta: boolean; tiktok: boolean; appleSearchAds: boolean; playInstallReferrer: boolean } {
841
+ getPlatformIntegrationStatus(): { appleSearchAds: boolean; playInstallReferrer: boolean } {
1002
842
  return {
1003
- meta: metaIntegration.isAvailable(),
1004
- tiktok: tiktokIntegration.isAvailable(),
1005
843
  appleSearchAds: appleSearchAdsIntegration.isAvailable(),
1006
844
  playInstallReferrer: playInstallReferrerIntegration.isAvailable(),
1007
845
  };
@@ -1024,8 +862,91 @@ export class DatalyrSDK {
1024
862
  return data ? playInstallReferrerIntegration.getAttributionData() : null;
1025
863
  }
1026
864
 
865
+ // MARK: - Third-Party Integration Methods
866
+
1027
867
  /**
1028
- * Update tracking authorization status on all platform SDKs
868
+ * Get attribution data formatted for Superwall's setUserAttributes()
869
+ * Returns a flat Record<string, string> with only non-empty values
870
+ */
871
+ getSuperwallAttributes(): Record<string, string> {
872
+ const attribution = attributionManager.getAttributionData();
873
+ const advertiser = this.cachedAdvertiserInfo;
874
+ const attrs: Record<string, string> = {};
875
+
876
+ const set = (key: string, value: any) => {
877
+ if (value != null && String(value) !== '') attrs[key] = String(value);
878
+ };
879
+
880
+ set('datalyr_id', this.state.visitorId);
881
+ set('media_source', attribution.utm_source);
882
+ set('campaign', attribution.utm_campaign);
883
+ set('adgroup', attribution.adset_id || attribution.utm_content);
884
+ set('ad', attribution.ad_id);
885
+ set('keyword', attribution.keyword);
886
+ set('network', attribution.network);
887
+ set('utm_source', attribution.utm_source);
888
+ set('utm_medium', attribution.utm_medium);
889
+ set('utm_campaign', attribution.utm_campaign);
890
+ set('utm_term', attribution.utm_term);
891
+ set('utm_content', attribution.utm_content);
892
+ set('lyr', attribution.lyr);
893
+ set('fbclid', attribution.fbclid);
894
+ set('gclid', attribution.gclid);
895
+ set('ttclid', attribution.ttclid);
896
+ set('idfa', advertiser?.idfa);
897
+ set('gaid', advertiser?.gaid);
898
+ set('att_status', advertiser?.att_status);
899
+
900
+ return attrs;
901
+ }
902
+
903
+ /**
904
+ * Get attribution data formatted for RevenueCat's Purchases.setAttributes()
905
+ * Returns a flat Record<string, string> with $-prefixed reserved keys
906
+ */
907
+ getRevenueCatAttributes(): Record<string, string> {
908
+ const attribution = attributionManager.getAttributionData();
909
+ const advertiser = this.cachedAdvertiserInfo;
910
+ const attrs: Record<string, string> = {};
911
+
912
+ const set = (key: string, value: any) => {
913
+ if (value != null && String(value) !== '') attrs[key] = String(value);
914
+ };
915
+
916
+ // Reserved attributes ($ prefix)
917
+ set('$datalyrId', this.state.visitorId);
918
+ set('$mediaSource', attribution.utm_source);
919
+ set('$campaign', attribution.utm_campaign);
920
+ set('$adGroup', attribution.adset_id);
921
+ set('$ad', attribution.ad_id);
922
+ set('$keyword', attribution.keyword);
923
+ set('$idfa', advertiser?.idfa);
924
+ set('$gpsAdId', advertiser?.gaid);
925
+ if (advertiser?.att_status != null) {
926
+ const statusMap: Record<number, string> = { 0: 'notDetermined', 1: 'restricted', 2: 'denied', 3: 'authorized' };
927
+ set('$attConsentStatus', statusMap[advertiser.att_status] || String(advertiser.att_status));
928
+ }
929
+
930
+ // Custom attributes
931
+ set('utm_source', attribution.utm_source);
932
+ set('utm_medium', attribution.utm_medium);
933
+ set('utm_campaign', attribution.utm_campaign);
934
+ set('utm_term', attribution.utm_term);
935
+ set('utm_content', attribution.utm_content);
936
+ set('lyr', attribution.lyr);
937
+ set('fbclid', attribution.fbclid);
938
+ set('gclid', attribution.gclid);
939
+ set('ttclid', attribution.ttclid);
940
+ set('wbraid', attribution.wbraid);
941
+ set('gbraid', attribution.gbraid);
942
+ set('network', attribution.network);
943
+ set('creative_id', attribution.creative_id);
944
+
945
+ return attrs;
946
+ }
947
+
948
+ /**
949
+ * Update tracking authorization status
1029
950
  * Call this AFTER the user responds to the ATT permission dialog
1030
951
  */
1031
952
  async updateTrackingAuthorization(enabled: boolean): Promise<void> {
@@ -1034,9 +955,6 @@ export class DatalyrSDK {
1034
955
  return;
1035
956
  }
1036
957
 
1037
- metaIntegration.updateTrackingAuthorization(enabled);
1038
- tiktokIntegration.updateTrackingAuthorization(enabled);
1039
-
1040
958
  // Refresh cached advertiser info after ATT status change
1041
959
  try {
1042
960
  this.cachedAdvertiserInfo = await AdvertiserInfoBridge.getAdvertiserInfo();
@@ -1156,8 +1074,8 @@ export class DatalyrSDK {
1156
1074
  carrier: deviceInfo.carrier,
1157
1075
  network_type: getNetworkType(),
1158
1076
  timestamp: Date.now(),
1159
- sdk_version: '1.4.9',
1160
- // Advertiser data (IDFA/GAID, ATT status) for Meta CAPI / TikTok Events API
1077
+ sdk_version: '1.6.1',
1078
+ // Advertiser data (IDFA/GAID, ATT status) for server-side postback
1161
1079
  ...(advertiserInfo ? {
1162
1080
  idfa: advertiserInfo.idfa,
1163
1081
  idfv: advertiserInfo.idfv,
@@ -1468,7 +1386,7 @@ export class Datalyr {
1468
1386
  datalyr.updateAutoEventsConfig(config);
1469
1387
  }
1470
1388
 
1471
- // Standard e-commerce events (all forward to Meta and TikTok)
1389
+ // Standard e-commerce events
1472
1390
  static async trackAddToCart(
1473
1391
  value: number,
1474
1392
  currency = 'USD',
@@ -1518,7 +1436,7 @@ export class Datalyr {
1518
1436
  return datalyr.getDeferredAttributionData();
1519
1437
  }
1520
1438
 
1521
- static getPlatformIntegrationStatus(): { meta: boolean; tiktok: boolean; appleSearchAds: boolean } {
1439
+ static getPlatformIntegrationStatus(): { appleSearchAds: boolean; playInstallReferrer: boolean } {
1522
1440
  return datalyr.getPlatformIntegrationStatus();
1523
1441
  }
1524
1442
 
@@ -1529,6 +1447,16 @@ export class Datalyr {
1529
1447
  static async updateTrackingAuthorization(enabled: boolean): Promise<void> {
1530
1448
  await datalyr.updateTrackingAuthorization(enabled);
1531
1449
  }
1450
+
1451
+ // Third-party integration methods
1452
+
1453
+ static getSuperwallAttributes(): Record<string, string> {
1454
+ return datalyr.getSuperwallAttributes();
1455
+ }
1456
+
1457
+ static getRevenueCatAttributes(): Record<string, string> {
1458
+ return datalyr.getRevenueCatAttributes();
1459
+ }
1532
1460
  }
1533
1461
 
1534
1462
  // Export default instance for backward compatibility
@@ -72,7 +72,7 @@ export class HttpClient {
72
72
 
73
73
  const headers: Record<string, string> = {
74
74
  'Content-Type': 'application/json',
75
- 'User-Agent': `@datalyr/react-native/1.4.8`,
75
+ 'User-Agent': `@datalyr/react-native/1.5.0`,
76
76
  };
77
77
 
78
78
  // Server-side tracking uses X-API-Key header
@@ -197,7 +197,7 @@ export class HttpClient {
197
197
  },
198
198
  context: {
199
199
  library: '@datalyr/react-native',
200
- version: '1.4.8',
200
+ version: '1.5.0',
201
201
  source: 'mobile_app', // Explicitly set source for mobile
202
202
  userProperties: payload.userProperties,
203
203
  },
package/src/index.ts CHANGED
@@ -29,7 +29,7 @@ export { ConversionValueEncoder, ConversionTemplates } from './ConversionValueEn
29
29
  export { SKAdNetworkBridge } from './native/SKAdNetworkBridge';
30
30
 
31
31
  // Export platform integrations
32
- export { metaIntegration, tiktokIntegration, appleSearchAdsIntegration, playInstallReferrerIntegration } from './integrations';
32
+ export { appleSearchAdsIntegration, playInstallReferrerIntegration } from './integrations';
33
33
 
34
34
  // Export network status manager
35
35
  export { networkStatusManager } from './network-status';
@@ -1,10 +1,9 @@
1
1
  /**
2
- * Platform SDK Integrations
3
- * Meta (Facebook), TikTok, Apple Search Ads, and Google Play Install Referrer SDK wrappers
2
+ * Platform Integrations
3
+ * Apple Search Ads and Google Play Install Referrer
4
+ * Conversion routing to Meta/TikTok/Google is handled server-side via postback.
4
5
  */
5
6
 
6
- export { MetaIntegration, metaIntegration } from './meta-integration';
7
- export { TikTokIntegration, tiktokIntegration } from './tiktok-integration';
8
7
  export { AppleSearchAdsIntegration, appleSearchAdsIntegration } from './apple-search-ads-integration';
9
8
  export { playInstallReferrerIntegration } from './play-install-referrer';
10
9
  export type { PlayInstallReferrer } from './play-install-referrer';