@datalyr/react-native 1.1.1 → 1.2.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.
Files changed (42) hide show
  1. package/CHANGELOG.md +24 -141
  2. package/LICENSE +21 -0
  3. package/README.md +405 -217
  4. package/datalyr-react-native.podspec +31 -0
  5. package/ios/DatalyrNative.m +70 -0
  6. package/ios/DatalyrNative.swift +275 -0
  7. package/ios/DatalyrSKAdNetwork.m +26 -0
  8. package/lib/datalyr-sdk.d.ts +64 -3
  9. package/lib/datalyr-sdk.js +322 -3
  10. package/lib/index.d.ts +1 -0
  11. package/lib/index.js +4 -2
  12. package/lib/integrations/index.d.ts +6 -0
  13. package/lib/integrations/index.js +6 -0
  14. package/lib/integrations/meta-integration.d.ts +76 -0
  15. package/lib/integrations/meta-integration.js +218 -0
  16. package/lib/integrations/tiktok-integration.d.ts +82 -0
  17. package/lib/integrations/tiktok-integration.js +356 -0
  18. package/lib/native/DatalyrNativeBridge.d.ts +31 -0
  19. package/lib/native/DatalyrNativeBridge.js +168 -0
  20. package/lib/native/index.d.ts +5 -0
  21. package/lib/native/index.js +5 -0
  22. package/lib/types.d.ts +29 -0
  23. package/package.json +10 -5
  24. package/src/datalyr-sdk-expo.ts +957 -0
  25. package/src/datalyr-sdk.ts +419 -19
  26. package/src/expo.ts +38 -18
  27. package/src/index.ts +5 -2
  28. package/src/integrations/index.ts +7 -0
  29. package/src/integrations/meta-integration.ts +238 -0
  30. package/src/integrations/tiktok-integration.ts +360 -0
  31. package/src/native/DatalyrNativeBridge.ts +271 -0
  32. package/src/native/index.ts +11 -0
  33. package/src/types.ts +39 -0
  34. package/src/utils-expo.ts +25 -3
  35. package/src/utils-interface.ts +38 -0
  36. package/EXPO_INSTALL.md +0 -297
  37. package/INSTALL.md +0 -402
  38. package/examples/attribution-example.tsx +0 -377
  39. package/examples/auto-events-example.tsx +0 -403
  40. package/examples/example.tsx +0 -250
  41. package/examples/skadnetwork-example.tsx +0 -380
  42. package/examples/test-implementation.tsx +0 -163
@@ -1,19 +1,20 @@
1
1
  import { Platform, AppState } from 'react-native';
2
- import {
3
- DatalyrConfig,
4
- EventData,
5
- UserProperties,
6
- EventPayload,
2
+ import {
3
+ DatalyrConfig,
4
+ EventData,
5
+ UserProperties,
6
+ EventPayload,
7
7
  SDKState,
8
8
  AppState as AppStateType,
9
9
  AutoEventConfig,
10
+ DeferredDeepLinkResult,
10
11
  } from './types';
11
- import {
12
- getOrCreateVisitorId,
12
+ import {
13
+ getOrCreateVisitorId,
13
14
  getOrCreateAnonymousId,
14
- getOrCreateSessionId,
15
- createFingerprintData,
16
- generateUUID,
15
+ getOrCreateSessionId,
16
+ createFingerprintData,
17
+ generateUUID,
17
18
  getDeviceInfo,
18
19
  getNetworkType,
19
20
  validateEventName,
@@ -29,6 +30,7 @@ import { attributionManager, AttributionData } from './attribution';
29
30
  import { createAutoEventsManager, AutoEventsManager, SessionData } from './auto-events';
30
31
  import { ConversionValueEncoder, ConversionTemplates } from './ConversionValueEncoder';
31
32
  import { SKAdNetworkBridge } from './native/SKAdNetworkBridge';
33
+ import { metaIntegration, tiktokIntegration } from './integrations';
32
34
 
33
35
  export class DatalyrSDK {
34
36
  private state: SDKState;
@@ -153,7 +155,7 @@ export class DatalyrSDK {
153
155
  if (template) {
154
156
  DatalyrSDK.conversionEncoder = new ConversionValueEncoder(template);
155
157
  DatalyrSDK.debugEnabled = config.debug || false;
156
-
158
+
157
159
  if (DatalyrSDK.debugEnabled) {
158
160
  debugLog(`SKAdNetwork encoder initialized with template: ${config.skadTemplate}`);
159
161
  debugLog(`SKAdNetwork bridge available: ${SKAdNetworkBridge.isAvailable()}`);
@@ -161,6 +163,29 @@ export class DatalyrSDK {
161
163
  }
162
164
  }
163
165
 
166
+ // Initialize Meta SDK if configured
167
+ if (config.meta?.appId) {
168
+ await metaIntegration.initialize(config.meta, config.debug);
169
+
170
+ // Fetch deferred deep link and merge with attribution
171
+ if (config.enableAttribution !== false) {
172
+ const deferredLink = await metaIntegration.fetchDeferredDeepLink();
173
+ if (deferredLink) {
174
+ await this.handleDeferredDeepLink(deferredLink);
175
+ }
176
+ }
177
+ }
178
+
179
+ // Initialize TikTok SDK if configured
180
+ if (config.tiktok?.appId && config.tiktok?.tiktokAppId) {
181
+ await tiktokIntegration.initialize(config.tiktok, config.debug);
182
+ }
183
+
184
+ debugLog('Platform integrations initialized', {
185
+ meta: metaIntegration.isAvailable(),
186
+ tiktok: tiktokIntegration.isAvailable(),
187
+ });
188
+
164
189
  // SDK initialized successfully - set state before tracking install event
165
190
  this.state.initialized = true;
166
191
 
@@ -270,6 +295,39 @@ export class DatalyrSDK {
270
295
  }
271
296
  }
272
297
 
298
+ // Forward user data to platform SDKs for Advanced Matching
299
+ const email = properties?.email as string | undefined;
300
+ const phone = properties?.phone as string | undefined;
301
+ const firstName = (properties?.first_name || properties?.firstName) as string | undefined;
302
+ const lastName = (properties?.last_name || properties?.lastName) as string | undefined;
303
+ const dateOfBirth = (properties?.date_of_birth || properties?.dob || properties?.birthday) as string | undefined;
304
+ const gender = properties?.gender as string | undefined;
305
+ const city = properties?.city as string | undefined;
306
+ const state = properties?.state as string | undefined;
307
+ const zip = (properties?.zip || properties?.postal_code || properties?.zipcode) as string | undefined;
308
+ const country = properties?.country as string | undefined;
309
+
310
+ // Meta Advanced Matching
311
+ if (metaIntegration.isAvailable()) {
312
+ metaIntegration.setUserData({
313
+ email,
314
+ firstName,
315
+ lastName,
316
+ phone,
317
+ dateOfBirth,
318
+ gender,
319
+ city,
320
+ state,
321
+ zip,
322
+ country,
323
+ });
324
+ }
325
+
326
+ // TikTok identification
327
+ if (tiktokIntegration.isAvailable()) {
328
+ tiktokIntegration.identify(email, phone, userId);
329
+ }
330
+
273
331
  } catch (error) {
274
332
  errorLog('Error identifying user:', error as Error);
275
333
  }
@@ -391,6 +449,11 @@ export class DatalyrSDK {
391
449
  // Generate new session
392
450
  this.state.sessionId = await getOrCreateSessionId();
393
451
 
452
+ // Clear user data from platform SDKs
453
+ if (metaIntegration.isAvailable()) {
454
+ metaIntegration.clearUserData();
455
+ }
456
+
394
457
  debugLog('User data reset completed');
395
458
 
396
459
  } catch (error) {
@@ -533,31 +596,310 @@ export class DatalyrSDK {
533
596
  }
534
597
 
535
598
  /**
536
- * Track purchase with automatic revenue encoding
599
+ * Track purchase with automatic revenue encoding and platform forwarding
537
600
  */
538
601
  async trackPurchase(
539
- value: number,
540
- currency = 'USD',
602
+ value: number,
603
+ currency = 'USD',
541
604
  productId?: string
542
605
  ): Promise<void> {
543
606
  const properties: Record<string, any> = { revenue: value, currency };
544
607
  if (productId) properties.product_id = productId;
545
-
608
+
546
609
  await this.trackWithSKAdNetwork('purchase', properties);
610
+
611
+ // Forward to Meta if available
612
+ if (metaIntegration.isAvailable()) {
613
+ metaIntegration.logPurchase(value, currency, { fb_content_id: productId });
614
+ }
615
+
616
+ // Forward to TikTok if available
617
+ if (tiktokIntegration.isAvailable()) {
618
+ tiktokIntegration.logPurchase(value, currency, productId, 'product');
619
+ }
547
620
  }
548
621
 
549
622
  /**
550
- * Track subscription with automatic revenue encoding
623
+ * Track subscription with automatic revenue encoding and platform forwarding
551
624
  */
552
625
  async trackSubscription(
553
- value: number,
554
- currency = 'USD',
626
+ value: number,
627
+ currency = 'USD',
555
628
  plan?: string
556
629
  ): Promise<void> {
557
630
  const properties: Record<string, any> = { revenue: value, currency };
558
631
  if (plan) properties.plan = plan;
559
-
632
+
560
633
  await this.trackWithSKAdNetwork('subscribe', properties);
634
+
635
+ // Forward to Meta if available
636
+ if (metaIntegration.isAvailable()) {
637
+ metaIntegration.logEvent('Subscribe', value, { subscription_plan: plan });
638
+ }
639
+
640
+ // Forward to TikTok if available
641
+ if (tiktokIntegration.isAvailable()) {
642
+ tiktokIntegration.logSubscription(value, currency, plan);
643
+ }
644
+ }
645
+
646
+ // MARK: - Standard E-commerce Events
647
+
648
+ /**
649
+ * Track add to cart event
650
+ */
651
+ async trackAddToCart(
652
+ value: number,
653
+ currency = 'USD',
654
+ productId?: string,
655
+ productName?: string
656
+ ): Promise<void> {
657
+ const properties: Record<string, any> = { value, currency };
658
+ if (productId) properties.product_id = productId;
659
+ if (productName) properties.product_name = productName;
660
+
661
+ await this.trackWithSKAdNetwork('add_to_cart', properties);
662
+
663
+ // Forward to Meta
664
+ if (metaIntegration.isAvailable()) {
665
+ metaIntegration.logEvent('AddToCart', value, {
666
+ currency,
667
+ content_ids: productId ? [productId] : undefined,
668
+ content_name: productName,
669
+ });
670
+ }
671
+
672
+ // Forward to TikTok
673
+ if (tiktokIntegration.isAvailable()) {
674
+ tiktokIntegration.logAddToCart(value, currency, productId, 'product');
675
+ }
676
+ }
677
+
678
+ /**
679
+ * Track view content/product event
680
+ */
681
+ async trackViewContent(
682
+ contentId?: string,
683
+ contentName?: string,
684
+ contentType = 'product',
685
+ value?: number,
686
+ currency?: string
687
+ ): Promise<void> {
688
+ const properties: Record<string, any> = { content_type: contentType };
689
+ if (contentId) properties.content_id = contentId;
690
+ if (contentName) properties.content_name = contentName;
691
+ if (value !== undefined) properties.value = value;
692
+ if (currency) properties.currency = currency;
693
+
694
+ await this.track('view_content', properties);
695
+
696
+ // Forward to Meta
697
+ if (metaIntegration.isAvailable()) {
698
+ metaIntegration.logEvent('ViewContent', value, {
699
+ content_ids: contentId ? [contentId] : undefined,
700
+ content_name: contentName,
701
+ content_type: contentType,
702
+ currency,
703
+ });
704
+ }
705
+
706
+ // Forward to TikTok
707
+ if (tiktokIntegration.isAvailable()) {
708
+ tiktokIntegration.logViewContent(contentId, contentName, contentType);
709
+ }
710
+ }
711
+
712
+ /**
713
+ * Track initiate checkout event
714
+ */
715
+ async trackInitiateCheckout(
716
+ value: number,
717
+ currency = 'USD',
718
+ numItems?: number,
719
+ productIds?: string[]
720
+ ): Promise<void> {
721
+ const properties: Record<string, any> = { value, currency };
722
+ if (numItems !== undefined) properties.num_items = numItems;
723
+ if (productIds) properties.product_ids = productIds;
724
+
725
+ await this.trackWithSKAdNetwork('initiate_checkout', properties);
726
+
727
+ // Forward to Meta
728
+ if (metaIntegration.isAvailable()) {
729
+ metaIntegration.logEvent('InitiateCheckout', value, {
730
+ currency,
731
+ num_items: numItems,
732
+ content_ids: productIds,
733
+ });
734
+ }
735
+
736
+ // Forward to TikTok
737
+ if (tiktokIntegration.isAvailable()) {
738
+ tiktokIntegration.logInitiateCheckout(value, currency, numItems);
739
+ }
740
+ }
741
+
742
+ /**
743
+ * Track complete registration event
744
+ */
745
+ async trackCompleteRegistration(method?: string): Promise<void> {
746
+ const properties: Record<string, any> = {};
747
+ if (method) properties.method = method;
748
+
749
+ await this.trackWithSKAdNetwork('complete_registration', properties);
750
+
751
+ // Forward to Meta
752
+ if (metaIntegration.isAvailable()) {
753
+ metaIntegration.logEvent('CompleteRegistration', undefined, { registration_method: method });
754
+ }
755
+
756
+ // Forward to TikTok
757
+ if (tiktokIntegration.isAvailable()) {
758
+ tiktokIntegration.logCompleteRegistration(method);
759
+ }
760
+ }
761
+
762
+ /**
763
+ * Track search event
764
+ */
765
+ async trackSearch(query: string, resultIds?: string[]): Promise<void> {
766
+ const properties: Record<string, any> = { query };
767
+ if (resultIds) properties.result_ids = resultIds;
768
+
769
+ await this.track('search', properties);
770
+
771
+ // Forward to Meta
772
+ if (metaIntegration.isAvailable()) {
773
+ metaIntegration.logEvent('Search', undefined, {
774
+ search_string: query,
775
+ content_ids: resultIds,
776
+ });
777
+ }
778
+
779
+ // Forward to TikTok
780
+ if (tiktokIntegration.isAvailable()) {
781
+ tiktokIntegration.logSearch(query);
782
+ }
783
+ }
784
+
785
+ /**
786
+ * Track lead/contact form submission
787
+ */
788
+ async trackLead(value?: number, currency?: string): Promise<void> {
789
+ const properties: Record<string, any> = {};
790
+ if (value !== undefined) properties.value = value;
791
+ if (currency) properties.currency = currency;
792
+
793
+ await this.trackWithSKAdNetwork('lead', properties);
794
+
795
+ // Forward to Meta
796
+ if (metaIntegration.isAvailable()) {
797
+ metaIntegration.logEvent('Lead', value, { currency });
798
+ }
799
+
800
+ // Forward to TikTok
801
+ if (tiktokIntegration.isAvailable()) {
802
+ tiktokIntegration.logLead(value, currency);
803
+ }
804
+ }
805
+
806
+ /**
807
+ * Track add payment info event
808
+ */
809
+ async trackAddPaymentInfo(success = true): Promise<void> {
810
+ await this.track('add_payment_info', { success });
811
+
812
+ // Forward to Meta
813
+ if (metaIntegration.isAvailable()) {
814
+ metaIntegration.logEvent('AddPaymentInfo', undefined, { success: success ? 1 : 0 });
815
+ }
816
+
817
+ // Forward to TikTok
818
+ if (tiktokIntegration.isAvailable()) {
819
+ tiktokIntegration.logAddPaymentInfo(success);
820
+ }
821
+ }
822
+
823
+ // MARK: - Platform Integration Methods
824
+
825
+ /**
826
+ * Get deferred attribution data from platform SDKs
827
+ */
828
+ getDeferredAttributionData(): DeferredDeepLinkResult | null {
829
+ return metaIntegration.getDeferredDeepLinkData();
830
+ }
831
+
832
+ /**
833
+ * Get platform integration status
834
+ */
835
+ getPlatformIntegrationStatus(): { meta: boolean; tiktok: boolean } {
836
+ return {
837
+ meta: metaIntegration.isAvailable(),
838
+ tiktok: tiktokIntegration.isAvailable(),
839
+ };
840
+ }
841
+
842
+ /**
843
+ * Update tracking authorization status on all platform SDKs
844
+ * Call this AFTER the user responds to the ATT permission dialog
845
+ */
846
+ async updateTrackingAuthorization(enabled: boolean): Promise<void> {
847
+ if (!this.state.initialized) {
848
+ errorLog('SDK not initialized. Call initialize() first.');
849
+ return;
850
+ }
851
+
852
+ metaIntegration.updateTrackingAuthorization(enabled);
853
+ tiktokIntegration.updateTrackingAuthorization(enabled);
854
+
855
+ // Track ATT status event
856
+ await this.track('$att_status', {
857
+ authorized: enabled,
858
+ status: enabled ? 3 : 2,
859
+ status_name: enabled ? 'authorized' : 'denied',
860
+ });
861
+
862
+ debugLog(`ATT status updated: ${enabled ? 'authorized' : 'denied'}`);
863
+ }
864
+
865
+ /**
866
+ * Handle deferred deep link data from platform SDKs
867
+ */
868
+ private async handleDeferredDeepLink(data: DeferredDeepLinkResult): Promise<void> {
869
+ try {
870
+ debugLog('Processing deferred deep link:', data);
871
+
872
+ // Track deferred attribution event
873
+ await this.track('$deferred_deep_link', {
874
+ url: data.url,
875
+ source: data.source,
876
+ fbclid: data.fbclid,
877
+ ttclid: data.ttclid,
878
+ utm_source: data.utmSource,
879
+ utm_medium: data.utmMedium,
880
+ utm_campaign: data.utmCampaign,
881
+ utm_content: data.utmContent,
882
+ utm_term: data.utmTerm,
883
+ campaign_id: data.campaignId,
884
+ adset_id: data.adsetId,
885
+ ad_id: data.adId,
886
+ });
887
+
888
+ // Merge into attribution manager
889
+ attributionManager.mergeWebAttribution({
890
+ fbclid: data.fbclid,
891
+ ttclid: data.ttclid,
892
+ utm_source: data.utmSource,
893
+ utm_medium: data.utmMedium,
894
+ utm_campaign: data.utmCampaign,
895
+ utm_content: data.utmContent,
896
+ utm_term: data.utmTerm,
897
+ });
898
+
899
+ debugLog('Deferred deep link processed successfully');
900
+ } catch (error) {
901
+ errorLog('Error processing deferred deep link:', error as Error);
902
+ }
561
903
  }
562
904
 
563
905
  /**
@@ -846,6 +1188,64 @@ export class Datalyr {
846
1188
  static updateAutoEventsConfig(config: Partial<AutoEventConfig>): void {
847
1189
  datalyr.updateAutoEventsConfig(config);
848
1190
  }
1191
+
1192
+ // Standard e-commerce events (all forward to Meta and TikTok)
1193
+ static async trackAddToCart(
1194
+ value: number,
1195
+ currency = 'USD',
1196
+ productId?: string,
1197
+ productName?: string
1198
+ ): Promise<void> {
1199
+ await datalyr.trackAddToCart(value, currency, productId, productName);
1200
+ }
1201
+
1202
+ static async trackViewContent(
1203
+ contentId?: string,
1204
+ contentName?: string,
1205
+ contentType = 'product',
1206
+ value?: number,
1207
+ currency?: string
1208
+ ): Promise<void> {
1209
+ await datalyr.trackViewContent(contentId, contentName, contentType, value, currency);
1210
+ }
1211
+
1212
+ static async trackInitiateCheckout(
1213
+ value: number,
1214
+ currency = 'USD',
1215
+ numItems?: number,
1216
+ productIds?: string[]
1217
+ ): Promise<void> {
1218
+ await datalyr.trackInitiateCheckout(value, currency, numItems, productIds);
1219
+ }
1220
+
1221
+ static async trackCompleteRegistration(method?: string): Promise<void> {
1222
+ await datalyr.trackCompleteRegistration(method);
1223
+ }
1224
+
1225
+ static async trackSearch(query: string, resultIds?: string[]): Promise<void> {
1226
+ await datalyr.trackSearch(query, resultIds);
1227
+ }
1228
+
1229
+ static async trackLead(value?: number, currency?: string): Promise<void> {
1230
+ await datalyr.trackLead(value, currency);
1231
+ }
1232
+
1233
+ static async trackAddPaymentInfo(success = true): Promise<void> {
1234
+ await datalyr.trackAddPaymentInfo(success);
1235
+ }
1236
+
1237
+ // Platform integration methods
1238
+ static getDeferredAttributionData(): DeferredDeepLinkResult | null {
1239
+ return datalyr.getDeferredAttributionData();
1240
+ }
1241
+
1242
+ static getPlatformIntegrationStatus(): { meta: boolean; tiktok: boolean } {
1243
+ return datalyr.getPlatformIntegrationStatus();
1244
+ }
1245
+
1246
+ static async updateTrackingAuthorization(enabled: boolean): Promise<void> {
1247
+ await datalyr.updateTrackingAuthorization(enabled);
1248
+ }
849
1249
  }
850
1250
 
851
1251
  // Export default instance for backward compatibility
package/src/expo.ts CHANGED
@@ -1,36 +1,56 @@
1
- // Expo entry point - uses Expo-compatible utilities
2
- // Import this with: import { datalyr } from '@datalyr/react-native-sdk/expo';
1
+ /**
2
+ * Expo entry point - uses Expo-compatible utilities
3
+ * Import with: import { Datalyr } from '@datalyr/react-native/expo';
4
+ *
5
+ * Uses Expo-specific packages:
6
+ * - expo-application (app version, bundle ID)
7
+ * - expo-device (device model, manufacturer)
8
+ * - expo-network (network type detection)
9
+ *
10
+ * For React Native CLI, use:
11
+ * import { Datalyr } from '@datalyr/react-native';
12
+ */
3
13
 
4
- // Note: This is a placeholder - you'd need to create a version of DatalyrSDK
5
- // that imports from utils-expo.ts instead of utils.ts
14
+ // Export Expo-specific SDK (uses utils-expo.ts)
15
+ export { DatalyrSDKExpo as DatalyrSDK, DatalyrExpo as Datalyr } from './datalyr-sdk-expo';
16
+ import datalyrExpo from './datalyr-sdk-expo';
17
+ export { datalyrExpo as datalyr };
6
18
 
7
- export { DatalyrSDK as datalyr } from './datalyr-sdk';
19
+ // Export types
8
20
  export * from './types';
21
+
22
+ // Export attribution manager
9
23
  export { attributionManager } from './attribution';
24
+
25
+ // Export auto-events
10
26
  export { createAutoEventsManager, AutoEventsManager } from './auto-events';
11
27
 
12
- // Re-export Expo-specific utilities
13
- export {
14
- debugLog,
15
- errorLog,
16
- generateUUID,
17
- Storage,
18
- getOrCreateVisitorId,
28
+ // Re-export Expo-specific utilities for advanced usage
29
+ export {
30
+ debugLog,
31
+ errorLog,
32
+ generateUUID,
33
+ Storage,
34
+ getOrCreateVisitorId,
35
+ getOrCreateAnonymousId,
19
36
  getOrCreateSessionId,
20
37
  createFingerprintData,
21
38
  getNetworkType,
22
39
  validateEventName,
23
40
  validateEventData,
24
41
  isFirstLaunch,
25
- checkAppVersion
42
+ checkAppVersion,
43
+ getDeviceInfo,
44
+ STORAGE_KEYS,
26
45
  } from './utils-expo';
27
46
 
47
+ // Export HTTP client and event queue
28
48
  export * from './http-client';
29
49
  export * from './event-queue';
30
50
 
31
- // Default export for compatibility
32
- import { DatalyrSDK } from './datalyr-sdk';
33
- export default DatalyrSDK;
51
+ // Export SKAdNetwork components
52
+ export { ConversionValueEncoder, ConversionTemplates } from './ConversionValueEncoder';
53
+ export { SKAdNetworkBridge } from './native/SKAdNetworkBridge';
34
54
 
35
- // TODO: Create expo-specific version that uses utils-expo.ts
36
- // This would require creating datalyr-sdk-expo.ts that imports utils-expo instead of utils
55
+ // Default export
56
+ export default datalyrExpo;
package/src/index.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  // Main entry point for React Native CLI
2
- // Import this with: import { datalyr } from '@datalyr/react-native-sdk';
2
+ // Import with: import { Datalyr } from '@datalyr/react-native';
3
3
 
4
4
  import { DatalyrSDK, Datalyr } from './datalyr-sdk';
5
5
 
@@ -26,5 +26,8 @@ export { DatalyrSDK };
26
26
  export { ConversionValueEncoder, ConversionTemplates } from './ConversionValueEncoder';
27
27
  export { SKAdNetworkBridge } from './native/SKAdNetworkBridge';
28
28
 
29
- // Default export for compatibility
29
+ // Export platform integrations
30
+ export { metaIntegration, tiktokIntegration } from './integrations';
31
+
32
+ // Default export for compatibility
30
33
  export default DatalyrSDK;
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Platform SDK Integrations
3
+ * Meta (Facebook) and TikTok SDK wrappers for deferred deep linking and event forwarding
4
+ */
5
+
6
+ export { MetaIntegration, metaIntegration } from './meta-integration';
7
+ export { TikTokIntegration, tiktokIntegration } from './tiktok-integration';