@magicpixel/rn-mp-client-sdk 1.13.0 → 1.13.21

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 (104) hide show
  1. package/README.md +163 -14
  2. package/lib/commonjs/common/app-types.js.map +1 -1
  3. package/lib/commonjs/common/constants.js +11 -2
  4. package/lib/commonjs/common/constants.js.map +1 -1
  5. package/lib/commonjs/common/data-store.js +13 -30
  6. package/lib/commonjs/common/data-store.js.map +1 -1
  7. package/lib/commonjs/common/deeplink-helper.js +174 -0
  8. package/lib/commonjs/common/deeplink-helper.js.map +1 -0
  9. package/lib/commonjs/common/device-info-helper.js +168 -0
  10. package/lib/commonjs/common/device-info-helper.js.map +1 -0
  11. package/lib/commonjs/common/event-bus.js +39 -0
  12. package/lib/commonjs/common/event-bus.js.map +1 -1
  13. package/lib/commonjs/common/network-service.js +119 -15
  14. package/lib/commonjs/common/network-service.js.map +1 -1
  15. package/lib/commonjs/common/reporter.js +75 -14
  16. package/lib/commonjs/common/reporter.js.map +1 -1
  17. package/lib/commonjs/common/storage-helper.js +227 -0
  18. package/lib/commonjs/common/storage-helper.js.map +1 -0
  19. package/lib/commonjs/common/utils.js +62 -2
  20. package/lib/commonjs/common/utils.js.map +1 -1
  21. package/lib/commonjs/eedl/eedl.js +198 -44
  22. package/lib/commonjs/eedl/eedl.js.map +1 -1
  23. package/lib/commonjs/index.js +301 -54
  24. package/lib/commonjs/index.js.map +1 -1
  25. package/lib/commonjs/models/mp-client-sdk.js +17 -10
  26. package/lib/commonjs/models/mp-client-sdk.js.map +1 -1
  27. package/lib/commonjs/processors/data-element.processor.js +51 -7
  28. package/lib/commonjs/processors/data-element.processor.js.map +1 -1
  29. package/lib/commonjs/processors/visit-id.processor.js +78 -15
  30. package/lib/commonjs/processors/visit-id.processor.js.map +1 -1
  31. package/lib/module/common/app-types.js.map +1 -1
  32. package/lib/module/common/constants.js +11 -2
  33. package/lib/module/common/constants.js.map +1 -1
  34. package/lib/module/common/data-store.js +13 -30
  35. package/lib/module/common/data-store.js.map +1 -1
  36. package/lib/module/common/deeplink-helper.js +168 -0
  37. package/lib/module/common/deeplink-helper.js.map +1 -0
  38. package/lib/module/common/device-info-helper.js +161 -0
  39. package/lib/module/common/device-info-helper.js.map +1 -0
  40. package/lib/module/common/event-bus.js +39 -0
  41. package/lib/module/common/event-bus.js.map +1 -1
  42. package/lib/module/common/network-service.js +119 -15
  43. package/lib/module/common/network-service.js.map +1 -1
  44. package/lib/module/common/reporter.js +76 -14
  45. package/lib/module/common/reporter.js.map +1 -1
  46. package/lib/module/common/storage-helper.js +221 -0
  47. package/lib/module/common/storage-helper.js.map +1 -0
  48. package/lib/module/common/utils.js +63 -2
  49. package/lib/module/common/utils.js.map +1 -1
  50. package/lib/module/eedl/eedl.js +198 -44
  51. package/lib/module/eedl/eedl.js.map +1 -1
  52. package/lib/module/index.js +290 -53
  53. package/lib/module/index.js.map +1 -1
  54. package/lib/module/models/mp-client-sdk.js +16 -9
  55. package/lib/module/models/mp-client-sdk.js.map +1 -1
  56. package/lib/module/processors/data-element.processor.js +51 -7
  57. package/lib/module/processors/data-element.processor.js.map +1 -1
  58. package/lib/module/processors/visit-id.processor.js +78 -15
  59. package/lib/module/processors/visit-id.processor.js.map +1 -1
  60. package/lib/typescript/{common → src/common}/app-types.d.ts +30 -9
  61. package/lib/typescript/{common → src/common}/constants.d.ts +0 -1
  62. package/lib/typescript/{common → src/common}/data-store.d.ts +3 -8
  63. package/lib/typescript/src/common/deeplink-helper.d.ts +60 -0
  64. package/lib/typescript/src/common/device-info-helper.d.ts +54 -0
  65. package/lib/typescript/src/common/event-bus.d.ts +21 -0
  66. package/lib/typescript/src/common/network-service.d.ts +32 -0
  67. package/lib/typescript/{common → src/common}/reporter.d.ts +2 -1
  68. package/lib/typescript/src/common/storage-helper.d.ts +47 -0
  69. package/lib/typescript/{common → src/common}/utils.d.ts +25 -0
  70. package/lib/typescript/{eedl → src/eedl}/eedl.d.ts +43 -1
  71. package/lib/typescript/{index.d.ts → src/index.d.ts} +39 -5
  72. package/lib/typescript/{models → src/models}/mp-client-sdk.d.ts +7 -0
  73. package/lib/typescript/src/processors/visit-id.processor.d.ts +23 -0
  74. package/package.json +25 -36
  75. package/src/common/app-types.ts +33 -10
  76. package/src/common/constants.ts +0 -6
  77. package/src/common/data-store.ts +8 -30
  78. package/src/common/deeplink-helper.ts +181 -0
  79. package/src/common/device-info-helper.ts +190 -0
  80. package/src/common/event-bus.ts +39 -0
  81. package/src/common/network-service.ts +154 -21
  82. package/src/common/reporter.ts +97 -16
  83. package/src/common/storage-helper.ts +260 -0
  84. package/src/common/utils.ts +63 -2
  85. package/src/eedl/eedl.ts +225 -51
  86. package/src/index.tsx +346 -73
  87. package/src/models/mp-client-sdk.ts +8 -0
  88. package/src/processors/data-element.processor.ts +85 -7
  89. package/src/processors/visit-id.processor.ts +92 -22
  90. package/lib/commonjs/processors/trans-function.processor.js +0 -73
  91. package/lib/commonjs/processors/trans-function.processor.js.map +0 -1
  92. package/lib/module/processors/trans-function.processor.js +0 -66
  93. package/lib/module/processors/trans-function.processor.js.map +0 -1
  94. package/lib/typescript/common/event-bus.d.ts +0 -6
  95. package/lib/typescript/common/network-service.d.ts +0 -8
  96. package/lib/typescript/processors/trans-function.processor.d.ts +0 -12
  97. package/lib/typescript/processors/visit-id.processor.d.ts +0 -9
  98. package/src/processors/trans-function.processor.ts +0 -85
  99. /package/lib/typescript/{common → src/common}/logger.d.ts +0 -0
  100. /package/lib/typescript/{models → src/models}/geo-api-response.d.ts +0 -0
  101. /package/lib/typescript/{processors → src/processors}/data-element.processor.d.ts +0 -0
  102. /package/lib/typescript/{processors → src/processors}/geo-location.processor.d.ts +0 -0
  103. /package/lib/typescript/{processors → src/processors}/qc.processor.d.ts +0 -0
  104. /package/lib/typescript/{processors → src/processors}/tag.processor.d.ts +0 -0
@@ -1,6 +1,8 @@
1
1
  function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
2
2
  function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
3
3
  function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
4
+ // Polyfill for crypto.getRandomValues() required by ULID
5
+ import 'react-native-get-random-values';
4
6
  import { MpDataLayerHelper } from './eedl/eedl';
5
7
  import { DataStore } from './common/data-store';
6
8
  import { Logger } from './common/logger';
@@ -13,19 +15,121 @@ import { NetworkService } from './common/network-service';
13
15
  import { EventBus } from './common/event-bus';
14
16
  import { VisitIdProcessor } from './processors/visit-id.processor';
15
17
  import { GeoLocationProcessor } from './processors/geo-location.processor';
18
+ import { DeviceInfoHelper } from './common/device-info-helper';
19
+ import { DeepLinkHelper } from './common/deeplink-helper';
20
+ import { StorageHelper } from './common/storage-helper';
16
21
  const DL_INIT_EVENT = 'page_load';
22
+
23
+ // Maximum number of events to buffer before SDK is ready
24
+ const MAX_BUFFERED_EVENTS = 500;
25
+
26
+ // Type for buffered events
27
+
17
28
  class MagicPixelImpl {
18
- static async init(options) {
19
- var _options$device_type;
29
+ /**
30
+ * Initialize the MagicPixel SDK
31
+ * This method is synchronous - it stores config immediately and runs async setup in background
32
+ * Events called before async setup completes are buffered and processed once ready
33
+ * @param options SDK initialization options
34
+ */
35
+ static init(options) {
36
+ // Guard against multiple init() calls
37
+ if (this.isReady) {
38
+ Logger.logDbg('MagicPixel SDK already initialized. Ignoring duplicate init() call.');
39
+ return;
40
+ }
41
+ if (this.isInitializing) {
42
+ Logger.logDbg('MagicPixel SDK initialization in progress. Ignoring duplicate init() call.');
43
+ return;
44
+ }
45
+ this.isInitializing = true;
46
+
47
+ // Sync setup - happens immediately
20
48
  Logger.setLogLevel(options.logLevel ?? 'none');
49
+ this.orgId = options.orgId;
50
+ this.onInitFailureCallback = options.onInitFailure;
51
+ Logger.logDbg('MagicPixel SDK init started');
52
+
53
+ // Async setup - runs in background, events are buffered until complete
54
+ this.initAsync(options).catch(err => {
55
+ Logger.logError('MagicPixel SDK initialization failed:', err);
56
+ Reporter.reportError('sdk_init', err);
57
+
58
+ // Reset initializing flag so developer can retry if needed
59
+ this.isInitializing = false;
60
+
61
+ // Call failure callback if provided
62
+ if (this.onInitFailureCallback) {
63
+ const error = err instanceof Error ? err : new Error(String(err));
64
+ this.onInitFailureCallback(error);
65
+ }
66
+ });
67
+ }
68
+
69
+ /**
70
+ * Shutdown the SDK and release all resources
71
+ * Call this when the app is closing or when you need to reinitialize the SDK
72
+ * After shutdown, you must call init() again to use the SDK
73
+ */
74
+ static shutdown() {
75
+ Logger.logDbg('MagicPixel SDK shutting down...');
76
+
77
+ // Clean up deeplink listener and callback
78
+ DeepLinkHelper.cleanup();
79
+
80
+ // Clear all EventBus listeners to prevent duplicates on reinit
81
+ EventBus.clearAll();
82
+
83
+ // Clear session-scoped data element values (in-memory store)
84
+ StorageHelper.clearSessionStore();
85
+
86
+ // Clear event buffer
87
+ this.eventBuffer = [];
88
+
89
+ // Reset state flags
90
+ this.isReady = false;
91
+ this.isInitializing = false;
92
+ this.onInitFailureCallback = undefined;
93
+
94
+ // Reset customer data
95
+ this.customerInfo = undefined;
96
+ this.customerIdentifiers = {};
97
+ this.deepLinkUrl = undefined;
98
+ this.firstAppLaunch = true;
99
+
100
+ // Shutdown EEDL
101
+ this.dl.shutdown();
102
+ Logger.logDbg('MagicPixel SDK shutdown complete');
103
+ }
104
+
105
+ /**
106
+ * Async initialization - runs in background
107
+ */
108
+ static async initAsync(options) {
21
109
  await NetworkService.refreshClientSdkJson(options);
22
110
  if (!DataStore.isDataStoreReady()) {
23
- throw new Error('MagicPixel SDK is not ready. No tags will be processed');
111
+ throw new Error('MagicPixel SDK: DataStore not ready after config fetch. Initialization failed.');
24
112
  }
25
- if (options && options.device_type && ((_options$device_type = options.device_type) === null || _options$device_type === void 0 ? void 0 : _options$device_type.trim().length) > 0) {
26
- DataStore.overrideDeviceType(options.device_type);
27
- }
28
- this.setAppVersion(options.app_version);
113
+
114
+ // Initialize StorageHelper for data element storage duration
115
+ // This loads visitor-scoped values from AsyncStorage and clears expired ones (>30 days)
116
+ await StorageHelper.initialize();
117
+
118
+ // Auto-detect device info - always use detected values to prevent hardcoded values
119
+ const autoDetectedInfo = await DeviceInfoHelper.getAppInfo();
120
+ Logger.logDbg('Auto-detected device info:', autoDetectedInfo);
121
+
122
+ // Set device type from auto-detection (Expo/react-native-device-info)
123
+ // This is more reliable than dimension-based detection which fails on high-res phones
124
+ const detectedDeviceType = autoDetectedInfo.is_tablet ? 'tablet' : 'mobile';
125
+ DataStore.overrideDeviceType(detectedDeviceType);
126
+ Logger.logDbg('Device type set from auto-detection:', detectedDeviceType);
127
+
128
+ // Always use auto-detected app_version (ignore options.app_version)
129
+ this.setAppVersion(autoDetectedInfo.app_version);
130
+
131
+ // Set device info with auto-detected values (cannot be overridden)
132
+ await this.setDeviceInfo();
29
133
  await VisitIdProcessor.init(options === null || options === void 0 ? void 0 : options.orgId);
30
134
  const fbp = await VisitIdProcessor.getFacebookFBP();
31
135
  if (fbp) {
@@ -35,9 +139,38 @@ class MagicPixelImpl {
35
139
  Logger.logDbg('No facebook client id found. not setting');
36
140
  }
37
141
 
142
+ // Auto-detect deeplink if app was opened via deeplink (e.g., ad click)
143
+ // Supports: custom schemes (myapp://), universal links (https://), app links, HTTP links
144
+ const initialDeepLink = await DeepLinkHelper.initialize((url, linkType) => {
145
+ try {
146
+ Logger.logDbg(`Deeplink detected (${linkType}):`, url);
147
+
148
+ // Store deeplink URL - will be attached to next page_load event
149
+ this.setDeepLinkUrl(url);
150
+
151
+ // Fire deeplink opened event
152
+ // URL params will be parsed and attached to page_load event automatically
153
+ this.recordEvent('deeplink_opened', {
154
+ deep_link_url: url,
155
+ link_type: linkType
156
+ });
157
+ } catch (err) {
158
+ Logger.logError('Error processing deeplink:', err);
159
+ Reporter.reportError('deeplink_callback', err);
160
+ }
161
+ });
162
+ if (initialDeepLink) {
163
+ Logger.logDbg('App opened with initial deeplink:', initialDeepLink);
164
+ }
165
+
38
166
  // Initialize EEDL with any global event listeners
39
167
  await this.dl.init({});
40
168
 
169
+ // Set event deduplication window if specified (default is 5000ms)
170
+ if (typeof options.eventDeduplicationWindowMs !== 'undefined') {
171
+ this.dl.setDeduplicationWindow(options.eventDeduplicationWindowMs);
172
+ }
173
+
41
174
  // Make geo location API call after initialization
42
175
  try {
43
176
  await GeoLocationProcessor.makeGeoLocationApiCall();
@@ -51,9 +184,8 @@ class MagicPixelImpl {
51
184
  const eventId = eventDataModel['ev._id'];
52
185
  Logger.logDbg('Tracking Event:: ', eventName, 'with id:: ', eventId);
53
186
  if (DataStore.shouldExecuteTMForEvent(eventName)) {
54
- // if this is something the tag manager is interested in - fire tag manager
55
- DataStore.enQueueTMFire(false, `custom_event_${eventName}`, eventName, eventId, eventDataModel);
56
- await this.checkAndFireTM();
187
+ // Call runTM directly - no queuing, EEDL manages sequential processing
188
+ await this.runTM(false, `custom_event_${eventName}`, eventName, eventId, eventDataModel);
57
189
  }
58
190
  });
59
191
  const isFirstOpen = await VisitIdProcessor.isFirstOpenAfterInstall();
@@ -62,8 +194,32 @@ class MagicPixelImpl {
62
194
  this.recordEvent('app_first_open', {});
63
195
  }
64
196
  this.ready();
197
+
198
+ // Mark SDK as ready and flush any buffered events
199
+ this.isReady = true;
200
+ this.isInitializing = false;
201
+ Logger.logDbg('SDK is ready, flushing event buffer');
202
+ this.flushEventBuffer();
65
203
  }
66
204
  static recordEvent(eventName, payload) {
205
+ // Buffer event if SDK is not ready yet
206
+ if (!this.isReady) {
207
+ Logger.logDbg(`SDK not ready, buffering event: ${eventName}`);
208
+ // Evict oldest event if buffer at capacity
209
+ if (this.eventBuffer.length >= MAX_BUFFERED_EVENTS) {
210
+ const evicted = this.eventBuffer.shift();
211
+ Logger.logDbg(`Event buffer at capacity (${MAX_BUFFERED_EVENTS}), evicted oldest:`, (evicted === null || evicted === void 0 ? void 0 : evicted.type) === 'event' ? evicted.name : 'pageLoad');
212
+ }
213
+ this.eventBuffer.push({
214
+ type: 'event',
215
+ name: eventName,
216
+ data: payload
217
+ });
218
+ return;
219
+ }
220
+ this.processRecordEvent(eventName, payload);
221
+ }
222
+ static processRecordEvent(eventName, payload) {
67
223
  if (this.customerInfo) {
68
224
  const newPayload = {
69
225
  ...payload,
@@ -82,32 +238,38 @@ class MagicPixelImpl {
82
238
  static ready() {
83
239
  this.dl.ready();
84
240
  }
85
- static getDebugId() {
86
- return DataStore.getDebugId();
87
- }
88
- static async checkAndFireTM() {
89
- try {
90
- if (!DataStore.isTagManagerProcessing()) {
91
- const item = DataStore.deQueueTMFire();
92
- if (item) {
93
- Logger.logDbg('Executing TM For: ', item.name, ', Event:: ', item.dcrName, ', Event id:: ', item.eventId, 'Payload:: ', item.dcrPayload);
94
- await this.runTM(item.sseOnly, item.name, item.dcrName, item.eventId, item.dcrPayload);
95
- }
96
- } else {
97
- Logger.logDbg('Tag Manager is processing or is not ready. This event will start after that');
241
+
242
+ /**
243
+ * Flush buffered events after SDK is ready
244
+ * Events are processed in the order they were received
245
+ */
246
+ static flushEventBuffer() {
247
+ if (this.eventBuffer.length === 0) {
248
+ Logger.logDbg('No buffered events to flush');
249
+ return;
250
+ }
251
+ Logger.logDbg(`Flushing ${this.eventBuffer.length} buffered event(s)`);
252
+
253
+ // Process all buffered events in order
254
+ while (this.eventBuffer.length > 0) {
255
+ const event = this.eventBuffer.shift();
256
+ if (event.type === 'pageLoad') {
257
+ Logger.logDbg(`Processing buffered page load: ${event.data.page_name}`);
258
+ this.processRecordPageLoad(event.data);
259
+ } else if (event.type === 'event') {
260
+ Logger.logDbg(`Processing buffered event: ${event.name}`);
261
+ this.processRecordEvent(event.name, event.data);
98
262
  }
99
- } catch (err) {
100
- Logger.logError('Error check and process tm', err);
101
- Reporter.reportError('m:checkAndFireTM', err);
102
263
  }
264
+ Logger.logDbg('Event buffer flushed');
265
+ }
266
+ static getDebugId() {
267
+ return DataStore.getDebugId();
103
268
  }
104
269
  static async runTM(sseOnly, triggerName, evtName, evtId, eventData) {
105
270
  try {
106
271
  Logger.logDbg('Running:: ', sseOnly, triggerName, evtName, evtId, eventData);
107
272
 
108
- // set tag manager in process status
109
- DataStore.setTagManagerProcessing(true);
110
-
111
273
  // process all the data elements and cache them for this run
112
274
  await DataElementProcessor.processDataElements(DataStore.getSdkDataElements(), eventData);
113
275
  const sdk = DataStore.getClientSdk();
@@ -122,7 +284,8 @@ class MagicPixelImpl {
122
284
  DataStore.setPrivacyCompliance(false);
123
285
  }
124
286
  } else {
125
- Logger.logDbg('Set: PR Comp: ', false);
287
+ // No privacy manager configured - default to true (tracking allowed)
288
+ Logger.logDbg('Set: PR Comp: ', true, '(no privacy manager configured)');
126
289
  DataStore.setPrivacyCompliance(true);
127
290
  }
128
291
  if (DataStore.getSdkPageLangKey()) {
@@ -135,48 +298,47 @@ class MagicPixelImpl {
135
298
  //set page_browser default data element with page_os because backend expects this
136
299
  DataStore.setDataElement('page_browser', DataStore.getOperatingSystem().toLowerCase());
137
300
  Reporter.initReporter(sdk.s.ev, sdk.s.ev_id, DataStore.getDeviceType(), DataStore.getPageLang(), DataStore.getDeviceOs(), DataStore.getPageName(), evtName, evtId, DataStore.getClientDownStream(), DataStore.getCoreVersion(), []);
301
+
302
+ // Store developer payload (base64 encoded) for report
303
+ if (eventData) {
304
+ Reporter.reportDevPayload(eventData, evtId);
305
+ }
138
306
  const validQCList = QcProcessor.processQc(DataStore.getSdkQC(), evtName, evtId);
139
307
  if ((validQCList === null || validQCList === void 0 ? void 0 : validQCList.length) > 0) {
140
308
  Logger.logDbg('Found Valid QCs to process', DataStore.getValidQcInfo());
141
309
  TagProcessor.processTags(evtName, evtId).then(() => {
142
- this._fireTM(sdk.s.ev, sdk.s.ev_id, evtName, evtId);
310
+ this._fireTM(sdk.s.ev, sdk.s.ev_id, evtName, evtId, eventData);
143
311
  }).catch(err => {
144
312
  Logger.logError('Error processing tag lists.', err);
145
313
  Reporter.reportError('i::processTags', err);
146
- this._fireTM(sdk.s.ev, sdk.s.ev_id, evtName, evtId);
314
+ this._fireTM(sdk.s.ev, sdk.s.ev_id, evtName, evtId, eventData);
147
315
  });
148
316
  } else {
149
- this._fireTM(sdk.s.ev, sdk.s.ev_id, evtName, evtId);
317
+ this._fireTM(sdk.s.ev, sdk.s.ev_id, evtName, evtId, eventData);
150
318
  }
151
319
  } catch (runTMErr) {
152
320
  Logger.logError('Error in runTM', runTMErr);
153
321
  Reporter.reportError('m::runTM', runTMErr);
154
322
  }
155
323
  }
156
- static _fireTM(envName, envId, evtName, evtId) {
324
+ static _fireTM(envName, envId, evtName, evtId, eventData) {
157
325
  // increment visit_depth if event name is page_load because that's the only way we can track page views in an app for now
158
326
  if (evtName === DL_INIT_EVENT) {
159
- VisitIdProcessor.incrementVisitDepth().finally(() => {
160
- this._fireTMPrivate(envName, envId, evtName, evtId);
161
- });
162
- } else {
163
- this._fireTMPrivate(envName, envId, evtName, evtId);
327
+ // Synchronous increment - no race condition possible
328
+ VisitIdProcessor.incrementVisitDepth();
164
329
  }
330
+
331
+ // Continue immediately after sync increment
332
+ this._fireTMPrivate(envName, envId, evtName, evtId, eventData);
165
333
  }
166
- static _fireTMPrivate(envName, envId, evtName, evtId) {
334
+ static _fireTMPrivate(envName, envId, evtName, evtId, eventData) {
167
335
  if (DataStore.hasOneSSTTag() && DataStore.shouldFireSstForEvent(evtName)) {
168
- Reporter.postSST(DataStore.getDataElements(), envName, envId, DataStore.getSSTDownStream(), evtName, evtId).catch(err => {
336
+ Reporter.postSST(DataStore.getDataElements(), envName, envId, DataStore.getSSTDownStream(), evtName, evtId, eventData).catch(err => {
169
337
  Reporter.reportError('l::postSST', err);
170
338
  });
171
339
  }
172
- DataStore.setTagManagerProcessing(false);
173
- Utils.sleep(250).then(async () => {
174
- try {
175
- await this.checkAndFireTM();
176
- } catch (err) {
177
- Reporter.reportError('i::runTM', err);
178
- }
179
- });
340
+ // Note: EEDL handles queue progression via its own .finally() block
341
+ // No need to call processNext() here - it would be redundant
180
342
  }
181
343
  static setCustomerInfo(customerInfo) {
182
344
  this.customerInfo = customerInfo;
@@ -188,7 +350,39 @@ class MagicPixelImpl {
188
350
  static setDeepLinkUrl(deepLinkUrl) {
189
351
  this.deepLinkUrl = deepLinkUrl;
190
352
  }
191
- static setDeviceInfo(deviceInfo) {
353
+
354
+ /**
355
+ * Set device info with auto-detected values
356
+ * Standard fields (os_version, device_model_name, package_name) are always auto-detected
357
+ * Optional customFields parameter allows adding custom tracking fields only
358
+ * @param customFields Optional custom fields to add (cannot override standard fields)
359
+ */
360
+ static async setDeviceInfo(customFields) {
361
+ // Always auto-detect standard device info (cannot be overridden)
362
+ const autoDetectedInfo = await DeviceInfoHelper.getAppInfo();
363
+
364
+ // Standard fields are always auto-detected to prevent hardcoded values
365
+ const deviceInfo = {
366
+ os_version: autoDetectedInfo.os_version,
367
+ device_model_name: autoDetectedInfo.device_model_name,
368
+ package_name: autoDetectedInfo.package_name
369
+ };
370
+
371
+ // Add any custom fields (if provided)
372
+ if (customFields) {
373
+ // Filter out attempts to override standard fields
374
+ const allowedCustomFields = {
375
+ ...customFields
376
+ };
377
+ delete allowedCustomFields.os_version;
378
+ delete allowedCustomFields.device_model_name;
379
+ delete allowedCustomFields.package_name;
380
+ Object.assign(deviceInfo, allowedCustomFields);
381
+ if (Object.keys(allowedCustomFields).length !== Object.keys(customFields).length) {
382
+ Logger.logDbg('Warning: Attempted to override standard device fields. Using auto-detected values instead.');
383
+ }
384
+ }
385
+ Logger.logDbg('Setting device info:', deviceInfo);
192
386
  DataStore.setDeviceInfo(deviceInfo);
193
387
  }
194
388
  static setFacebookClientId(fbp) {
@@ -196,11 +390,34 @@ class MagicPixelImpl {
196
390
  }
197
391
  static setAppVersion(appVersion) {
198
392
  var _appVersion$trim;
199
- if (appVersion && (appVersion === null || appVersion === void 0 ? void 0 : (_appVersion$trim = appVersion.trim()) === null || _appVersion$trim === void 0 ? void 0 : _appVersion$trim.length) > 0) {
393
+ if (appVersion && (appVersion === null || appVersion === void 0 || (_appVersion$trim = appVersion.trim()) === null || _appVersion$trim === void 0 ? void 0 : _appVersion$trim.length) > 0) {
200
394
  this.customerIdentifiers.app_version = appVersion;
201
395
  }
202
396
  }
203
397
  static recordPageLoad(pageLoadInfo) {
398
+ // Buffer page load if SDK is not ready yet
399
+ if (!this.isReady) {
400
+ Logger.logDbg(`SDK not ready, buffering page load: ${pageLoadInfo.page_name}`);
401
+ // Evict oldest event if buffer at capacity
402
+ if (this.eventBuffer.length >= MAX_BUFFERED_EVENTS) {
403
+ const evicted = this.eventBuffer.shift();
404
+ Logger.logDbg(`Event buffer at capacity (${MAX_BUFFERED_EVENTS}), evicted oldest:`, (evicted === null || evicted === void 0 ? void 0 : evicted.type) === 'event' ? evicted.name : 'pageLoad');
405
+ }
406
+ this.eventBuffer.push({
407
+ type: 'pageLoad',
408
+ data: {
409
+ ...pageLoadInfo
410
+ } // Clone to preserve original data
411
+ });
412
+ return;
413
+ }
414
+ this.processRecordPageLoad(pageLoadInfo);
415
+ }
416
+ static processRecordPageLoad(pageLoadInfo) {
417
+ // Retry visitor ID fetch if it failed during init (fire and forget)
418
+ VisitIdProcessor.retryVisitorIdIfNeeded().catch(err => {
419
+ Logger.logError('Error retrying visitor ID fetch:', err);
420
+ });
204
421
  pageLoadInfo.is_entry = this.firstAppLaunch ? 1 : 0;
205
422
 
206
423
  // Use stored deepLinkUrl if it exists AND either:
@@ -209,13 +426,26 @@ class MagicPixelImpl {
209
426
  if (this.deepLinkUrl && !pageLoadInfo.deep_link_url) {
210
427
  pageLoadInfo.deep_link_url = this.deepLinkUrl;
211
428
  }
429
+
430
+ // Set page_url for attribution framework
431
+ // Priority: deep_link_url (if present) > constructed URL (v_<orgId>://<screen_name>)
432
+ // Using deep_link_url allows urlp data elements to extract attribution params (gclid, fbclid, etc.)
433
+ if (pageLoadInfo.deep_link_url) {
434
+ pageLoadInfo.page_url = pageLoadInfo.deep_link_url;
435
+ Logger.logDbg('Setting page_url from deep_link_url:', pageLoadInfo.page_url);
436
+ } else if (this.orgId && pageLoadInfo.page_name) {
437
+ pageLoadInfo.page_url = `v_${this.orgId}://${pageLoadInfo.page_name}`;
438
+ Logger.logDbg('Setting page_url from orgId/page_name:', pageLoadInfo.page_url);
439
+ } else {
440
+ Logger.logDbg('Not setting page_url. No deep_link_url and orgId or page_name is missing. Org Id is: ', this.orgId, 'page_name is: ', pageLoadInfo.page_name);
441
+ }
212
442
  const deviceInfo = DataStore.getDeviceInfo();
213
443
  if (this.customerInfo) {
214
444
  const newPayload = {
215
445
  ...pageLoadInfo,
216
446
  ...this.customerInfo,
217
447
  ...(this.customerIdentifiers ?? {}),
218
- ...Utils.parseQueryParamsToObject(pageLoadInfo === null || pageLoadInfo === void 0 ? void 0 : pageLoadInfo.deep_link_url)
448
+ page_params: Utils.parseQueryParamsToObject(pageLoadInfo === null || pageLoadInfo === void 0 ? void 0 : pageLoadInfo.deep_link_url)
219
449
  };
220
450
  if (deviceInfo) {
221
451
  newPayload.device_info = deviceInfo;
@@ -225,7 +455,7 @@ class MagicPixelImpl {
225
455
  const newPayload = {
226
456
  ...pageLoadInfo,
227
457
  ...(this.customerIdentifiers ?? {}),
228
- ...Utils.parseQueryParamsToObject(pageLoadInfo === null || pageLoadInfo === void 0 ? void 0 : pageLoadInfo.deep_link_url)
458
+ page_params: Utils.parseQueryParamsToObject(pageLoadInfo === null || pageLoadInfo === void 0 ? void 0 : pageLoadInfo.deep_link_url)
229
459
  };
230
460
  if (deviceInfo) {
231
461
  newPayload.device_info = deviceInfo;
@@ -311,7 +541,14 @@ _defineProperty(MagicPixelImpl, "dl", new MpDataLayerHelper('mpDlEvent', 'manual
311
541
  _defineProperty(MagicPixelImpl, "customerInfo", void 0);
312
542
  _defineProperty(MagicPixelImpl, "customerIdentifiers", {});
313
543
  _defineProperty(MagicPixelImpl, "deepLinkUrl", undefined);
544
+ _defineProperty(MagicPixelImpl, "orgId", undefined);
314
545
  _defineProperty(MagicPixelImpl, "firstAppLaunch", true);
546
+ // SDK readiness state and event buffer
547
+ _defineProperty(MagicPixelImpl, "isReady", false);
548
+ _defineProperty(MagicPixelImpl, "isInitializing", false);
549
+ _defineProperty(MagicPixelImpl, "eventBuffer", []);
550
+ _defineProperty(MagicPixelImpl, "onInitFailureCallback", void 0);
315
551
  export const MagicPixelEventBus = EventBus;
316
552
  export const MagicPixel = MagicPixelImpl;
553
+ export { DeepLinkHelper, DeepLinkType } from './common/deeplink-helper';
317
554
  //# sourceMappingURL=index.js.map