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