@mparticle/web-sdk 2.19.0 → 2.19.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/mparticle.js CHANGED
@@ -725,7 +725,7 @@ var mParticle = (function () {
725
725
  Environment: Environment
726
726
  };
727
727
 
728
- var version = "2.19.0";
728
+ var version = "2.19.2";
729
729
 
730
730
  var Constants = {
731
731
  sdkVersion: version,
@@ -2111,27 +2111,12 @@ var mParticle = (function () {
2111
2111
  }
2112
2112
  }
2113
2113
 
2114
- /**
2115
- * BatchUploader contains all the logic to upload batches to mParticle.
2116
- * It queues events as they come in and at set intervals turns them into batches.
2117
- * It then attempts to upload them to mParticle.
2118
- *
2119
- * These uploads happen on an interval basis using window.fetch or XHR
2120
- * requests, depending on what is available in the browser.
2121
- *
2122
- * Uploads can also be triggered on browser visibility/focus changes via an
2123
- * event listener, which then uploads to mPartice via the browser's Beacon API.
2124
- */
2125
-
2126
2114
  var BatchUploader =
2127
2115
  /** @class */
2128
2116
  function () {
2129
- /**
2130
- * Creates an instance of a BatchUploader
2131
- * @param {MParticleWebSDK} mpInstance - the mParticle SDK instance
2132
- * @param {number} uploadInterval - the desired upload interval in milliseconds
2133
- */
2134
2117
  function BatchUploader(mpInstance, uploadInterval) {
2118
+ var _this_1 = this;
2119
+
2135
2120
  this.mpInstance = mpInstance;
2136
2121
  this.uploadIntervalMillis = uploadInterval;
2137
2122
  this.batchingEnabled = uploadInterval >= BatchUploader.MINIMUM_INTERVAL_MILLIS;
@@ -2140,8 +2125,8 @@ var mParticle = (function () {
2140
2125
  this.uploadIntervalMillis = BatchUploader.MINIMUM_INTERVAL_MILLIS;
2141
2126
  }
2142
2127
 
2143
- this.eventsQueuedForProcessing = [];
2144
- this.batchesQueuedForProcessing = [];
2128
+ this.pendingEvents = [];
2129
+ this.pendingUploads = [];
2145
2130
  var _a = this.mpInstance._Store,
2146
2131
  SDKConfig = _a.SDKConfig,
2147
2132
  devToken = _a.devToken;
@@ -2149,16 +2134,14 @@ var mParticle = (function () {
2149
2134
  var baseUrl = this.mpInstance._Helpers.createServiceUrl(SDKConfig.v3SecureServiceUrl, devToken);
2150
2135
 
2151
2136
  this.uploadUrl = "".concat(baseUrl, "/events");
2152
- this.uploader = window.fetch ? new FetchUploader(this.uploadUrl) : new XHRUploader(this.uploadUrl);
2153
- this.triggerUploadInterval(true, false);
2137
+ setTimeout(function () {
2138
+ _this_1.prepareAndUpload(true, false);
2139
+ }, this.uploadIntervalMillis);
2154
2140
  this.addEventListeners();
2155
- } // Adds listeners to be used trigger Navigator.sendBeacon if the browser
2156
- // loses focus for any reason, such as closing browser tab or minimizing window
2157
-
2141
+ }
2158
2142
 
2159
2143
  BatchUploader.prototype.addEventListeners = function () {
2160
- var _this = this; // visibility change is a document property, not window
2161
-
2144
+ var _this = this;
2162
2145
 
2163
2146
  document.addEventListener('visibilitychange', function () {
2164
2147
  _this.prepareAndUpload(false, _this.isBeaconAvailable());
@@ -2177,36 +2160,13 @@ var mParticle = (function () {
2177
2160
  }
2178
2161
 
2179
2162
  return false;
2180
- }; // Triggers a setTimeout for prepareAndUpload
2181
-
2182
-
2183
- BatchUploader.prototype.triggerUploadInterval = function (triggerFuture, useBeacon) {
2184
- var _this_1 = this;
2185
-
2186
- if (triggerFuture === void 0) {
2187
- triggerFuture = false;
2188
- }
2189
-
2190
- if (useBeacon === void 0) {
2191
- useBeacon = false;
2192
- }
2193
-
2194
- setTimeout(function () {
2195
- _this_1.prepareAndUpload(triggerFuture, useBeacon);
2196
- }, this.uploadIntervalMillis);
2197
2163
  };
2198
- /**
2199
- * This method will queue a single Event which will eventually be processed into a Batch
2200
- * @param event event that should be queued
2201
- */
2202
-
2203
2164
 
2204
2165
  BatchUploader.prototype.queueEvent = function (event) {
2205
2166
  if (!isEmpty(event)) {
2206
- this.eventsQueuedForProcessing.push(event);
2167
+ this.pendingEvents.push(event);
2207
2168
  this.mpInstance.Logger.verbose("Queuing event: ".concat(JSON.stringify(event)));
2208
- this.mpInstance.Logger.verbose("Queued event count: ".concat(this.eventsQueuedForProcessing.length)); // TODO: Remove this check once the v2 code path is removed
2209
- // https://go.mparticle.com/work/SQDSDKS-3720
2169
+ this.mpInstance.Logger.verbose("Queued event count: ".concat(this.pendingEvents.length));
2210
2170
 
2211
2171
  if (!this.batchingEnabled || Types.TriggerUploadType[event.EventDataType]) {
2212
2172
  this.prepareAndUpload(false, false);
@@ -2224,7 +2184,7 @@ var mParticle = (function () {
2224
2184
  */
2225
2185
 
2226
2186
 
2227
- BatchUploader.createNewBatches = function (sdkEvents, defaultUser, mpInstance) {
2187
+ BatchUploader.createNewUploads = function (sdkEvents, defaultUser, mpInstance) {
2228
2188
  if (!defaultUser || !sdkEvents || !sdkEvents.length) {
2229
2189
  return null;
2230
2190
  } //bucket by MPID, and then by session, ordered by timestamp
@@ -2304,139 +2264,157 @@ var mParticle = (function () {
2304
2264
 
2305
2265
  BatchUploader.prototype.prepareAndUpload = function (triggerFuture, useBeacon) {
2306
2266
  return __awaiter(this, void 0, void 0, function () {
2307
- var currentUser, currentEvents, newBatches, batchesToUpload, batchesThatDidNotUpload, promises;
2267
+ var currentUser, currentEvents, newUploads, currentUploads, remainingUploads;
2308
2268
 
2309
- var _a;
2269
+ var _a, _b;
2310
2270
 
2311
2271
  var _this_1 = this;
2312
2272
 
2313
- return __generator(this, function (_b) {
2314
- currentUser = this.mpInstance.Identity.getCurrentUser();
2315
- currentEvents = this.eventsQueuedForProcessing;
2316
- this.eventsQueuedForProcessing = [];
2317
- newBatches = BatchUploader.createNewBatches(currentEvents, currentUser, this.mpInstance);
2273
+ return __generator(this, function (_c) {
2274
+ switch (_c.label) {
2275
+ case 0:
2276
+ currentUser = this.mpInstance.Identity.getCurrentUser();
2277
+ currentEvents = this.pendingEvents;
2278
+ this.pendingEvents = [];
2279
+ newUploads = BatchUploader.createNewUploads(currentEvents, currentUser, this.mpInstance);
2318
2280
 
2319
- if (!isEmpty(newBatches)) {
2320
- (_a = this.batchesQueuedForProcessing).push.apply(_a, newBatches);
2321
- }
2281
+ if (newUploads && newUploads.length) {
2282
+ (_a = this.pendingUploads).push.apply(_a, newUploads);
2283
+ }
2322
2284
 
2323
- batchesToUpload = this.batchesQueuedForProcessing;
2324
- batchesThatDidNotUpload = [];
2325
- this.batchesQueuedForProcessing = [];
2326
- promises = batchesToUpload.map(function (upload) {
2327
- return _this_1.upload(_this_1.mpInstance.Logger, upload, useBeacon);
2328
- }); // Iterate through fulfilled promises and store any remaining batches
2329
- // for future re-transmission attempts
2285
+ currentUploads = this.pendingUploads;
2286
+ this.pendingUploads = [];
2287
+ return [4
2288
+ /*yield*/
2289
+ , this.upload(this.mpInstance.Logger, currentUploads, useBeacon)];
2330
2290
 
2331
- if (!isEmpty(promises)) {
2332
- Promise.all(promises).then(function (batchResponses) {
2333
- batchResponses.forEach(function (batch) {
2334
- return !isEmpty(batch) ? batchesThatDidNotUpload.push(batch) : null;
2335
- });
2336
- })["catch"](function (error) {
2337
- _this_1.mpInstance.Logger.error("Error processing batches during upload attempt: ".concat(error));
2338
- })["finally"](function () {
2339
- var _a; // Any batches that did not upload should be put back into the queue for processing
2291
+ case 1:
2292
+ remainingUploads = _c.sent();
2340
2293
 
2294
+ if (remainingUploads && remainingUploads.length) {
2295
+ (_b = this.pendingUploads).unshift.apply(_b, remainingUploads);
2296
+ }
2341
2297
 
2342
- if (!isEmpty(batchesThatDidNotUpload)) {
2343
- (_a = _this_1.batchesQueuedForProcessing).unshift.apply(_a, batchesThatDidNotUpload);
2298
+ if (triggerFuture) {
2299
+ setTimeout(function () {
2300
+ _this_1.prepareAndUpload(true, false);
2301
+ }, this.uploadIntervalMillis);
2344
2302
  }
2345
- });
2346
- }
2347
2303
 
2348
- if (triggerFuture) {
2349
- this.triggerUploadInterval(triggerFuture, false);
2304
+ return [2
2305
+ /*return*/
2306
+ ];
2350
2307
  }
2351
-
2352
- return [2
2353
- /*return*/
2354
- ];
2355
2308
  });
2356
2309
  });
2357
2310
  };
2358
2311
 
2359
- BatchUploader.prototype.upload = function (logger, batch, useBeacon) {
2312
+ BatchUploader.prototype.upload = function (logger, _uploads, useBeacon) {
2360
2313
  return __awaiter(this, void 0, void 0, function () {
2361
- var fetchPayload, blob, response, error_1;
2314
+ var uploader, uploads, i, fetchPayload, blob, response, e_1;
2362
2315
  return __generator(this, function (_a) {
2363
2316
  switch (_a.label) {
2364
2317
  case 0:
2365
- if (isEmpty(batch) || isEmpty(batch.events)) {
2318
+ uploads = _uploads.filter(function (upload) {
2319
+ return !isEmpty(upload.events);
2320
+ });
2321
+
2322
+ if (isEmpty(uploads)) {
2366
2323
  return [2
2367
2324
  /*return*/
2368
2325
  , null];
2369
2326
  }
2370
2327
 
2371
- logger.verbose("Uploading batches: ".concat(JSON.stringify(batch)));
2328
+ logger.verbose("Uploading batches: ".concat(JSON.stringify(uploads)));
2329
+ logger.verbose("Batch count: ".concat(uploads.length));
2330
+ i = 0;
2331
+ _a.label = 1;
2332
+
2333
+ case 1:
2334
+ if (!(i < uploads.length)) return [3
2335
+ /*break*/
2336
+ , 7];
2372
2337
  fetchPayload = {
2373
2338
  method: 'POST',
2374
2339
  headers: {
2375
2340
  Accept: BatchUploader.CONTENT_TYPE,
2376
2341
  'Content-Type': 'text/plain;charset=UTF-8'
2377
2342
  },
2378
- body: JSON.stringify(batch)
2343
+ body: JSON.stringify(uploads[i])
2379
2344
  };
2380
2345
  if (!(useBeacon && this.isBeaconAvailable())) return [3
2381
2346
  /*break*/
2382
- , 1];
2347
+ , 2];
2383
2348
  blob = new Blob([fetchPayload.body], {
2384
2349
  type: 'text/plain;charset=UTF-8'
2385
2350
  });
2386
2351
  navigator.sendBeacon(this.uploadUrl, blob);
2387
2352
  return [3
2388
2353
  /*break*/
2389
- , 4];
2354
+ , 6];
2390
2355
 
2391
- case 1:
2392
- _a.trys.push([1, 3,, 4]);
2356
+ case 2:
2357
+ if (!uploader) {
2358
+ if (window.fetch) {
2359
+ uploader = new FetchUploader(this.uploadUrl, logger);
2360
+ } else {
2361
+ uploader = new XHRUploader(this.uploadUrl, logger);
2362
+ }
2363
+ }
2364
+
2365
+ _a.label = 3;
2366
+
2367
+ case 3:
2368
+ _a.trys.push([3, 5,, 6]);
2393
2369
 
2394
2370
  return [4
2395
2371
  /*yield*/
2396
- , this.uploader.upload(fetchPayload)];
2372
+ , uploader.upload(fetchPayload, uploads, i)];
2397
2373
 
2398
- case 2:
2399
- response = _a.sent(); // TODO: Should we make this a switch statement instead?
2374
+ case 4:
2375
+ response = _a.sent();
2400
2376
 
2401
2377
  if (response.status >= 200 && response.status < 300) {
2402
- logger.verbose("Upload success for request ID: ".concat(batch.source_request_id));
2403
- return [2
2404
- /*return*/
2405
- , null];
2378
+ logger.verbose("Upload success for request ID: ".concat(uploads[i].source_request_id));
2406
2379
  } else if (response.status >= 500 || response.status === 429) {
2407
- logger.error("HTTP error status ".concat(response.status, " received")); // Server error, return current batch and try again later
2380
+ logger.error("HTTP error status ".concat(response.status, " received")); //server error, add back current events and try again later
2408
2381
 
2409
2382
  return [2
2410
2383
  /*return*/
2411
- , batch];
2384
+ , uploads.slice(i, uploads.length)];
2412
2385
  } else if (response.status >= 401) {
2413
- logger.error("HTTP error status ".concat(response.status, " while uploading - please verify your API key.")); // if we're getting a 401, assume we'll keep getting a 401
2414
- // so return the upload so it can be stored for later use
2386
+ logger.error("HTTP error status ".concat(response.status, " while uploading - please verify your API key.")); //if we're getting a 401, assume we'll keep getting a 401 and clear the uploads.
2415
2387
 
2416
2388
  return [2
2417
2389
  /*return*/
2418
- , batch];
2390
+ , null];
2419
2391
  }
2420
2392
 
2421
2393
  return [3
2422
2394
  /*break*/
2423
- , 4];
2395
+ , 6];
2424
2396
 
2425
- case 3:
2426
- error_1 = _a.sent();
2427
- logger.error("Error sending event to mParticle servers. ".concat(error_1));
2397
+ case 5:
2398
+ e_1 = _a.sent();
2399
+ logger.error("Error sending event to mParticle servers. ".concat(e_1));
2428
2400
  return [2
2429
2401
  /*return*/
2430
- , batch];
2402
+ , uploads.slice(i, uploads.length)];
2431
2403
 
2432
- case 4:
2404
+ case 6:
2405
+ i++;
2406
+ return [3
2407
+ /*break*/
2408
+ , 1];
2409
+
2410
+ case 7:
2433
2411
  return [2
2434
2412
  /*return*/
2435
2413
  , null];
2436
2414
  }
2437
2415
  });
2438
2416
  });
2439
- }; // We upload JSON, but this content type is required to avoid a CORS preflight request
2417
+ }; //we upload JSON, but this content type is required to avoid a CORS preflight request
2440
2418
 
2441
2419
 
2442
2420
  BatchUploader.CONTENT_TYPE = 'text/plain;charset=UTF-8';
@@ -2447,8 +2425,9 @@ var mParticle = (function () {
2447
2425
  var AsyncUploader =
2448
2426
  /** @class */
2449
2427
  function () {
2450
- function AsyncUploader(url) {
2428
+ function AsyncUploader(url, logger) {
2451
2429
  this.url = url;
2430
+ this.logger = logger;
2452
2431
  }
2453
2432
 
2454
2433
  return AsyncUploader;
@@ -2463,7 +2442,7 @@ var mParticle = (function () {
2463
2442
  return _super !== null && _super.apply(this, arguments) || this;
2464
2443
  }
2465
2444
 
2466
- FetchUploader.prototype.upload = function (fetchPayload) {
2445
+ FetchUploader.prototype.upload = function (fetchPayload, uploads, i) {
2467
2446
  return __awaiter(this, void 0, void 0, function () {
2468
2447
  var response;
2469
2448
  return __generator(this, function (_a) {
@@ -2495,7 +2474,7 @@ var mParticle = (function () {
2495
2474
  return _super !== null && _super.apply(this, arguments) || this;
2496
2475
  }
2497
2476
 
2498
- XHRUploader.prototype.upload = function (fetchPayload) {
2477
+ XHRUploader.prototype.upload = function (fetchPayload, uploads, i) {
2499
2478
  return __awaiter(this, void 0, void 0, function () {
2500
2479
  var response;
2501
2480
  return __generator(this, function (_a) {
@@ -2503,7 +2482,7 @@ var mParticle = (function () {
2503
2482
  case 0:
2504
2483
  return [4
2505
2484
  /*yield*/
2506
- , this.makeRequest(this.url, fetchPayload.body)];
2485
+ , this.makeRequest(this.url, this.logger, fetchPayload.body)];
2507
2486
 
2508
2487
  case 1:
2509
2488
  response = _a.sent();
@@ -2515,7 +2494,7 @@ var mParticle = (function () {
2515
2494
  });
2516
2495
  };
2517
2496
 
2518
- XHRUploader.prototype.makeRequest = function (url, data) {
2497
+ XHRUploader.prototype.makeRequest = function (url, logger, data) {
2519
2498
  return __awaiter(this, void 0, void 0, function () {
2520
2499
  var xhr;
2521
2500
  return __generator(this, function (_a) {
@@ -2679,7 +2658,7 @@ var mParticle = (function () {
2679
2658
  if (xhr) {
2680
2659
  try {
2681
2660
  xhr.open('post', mpInstance._Helpers.createServiceUrl(mpInstance._Store.SDKConfig.v2SecureServiceUrl, mpInstance._Store.devToken) + '/Events');
2682
- xhr.send(JSON.stringify(mpInstance._ServerModel.convertEventToDTO(event)));
2661
+ xhr.send(JSON.stringify(mpInstance._ServerModel.convertEventToV2DTO(event)));
2683
2662
  } catch (e) {
2684
2663
  mpInstance.Logger.error('Error sending event to mParticle servers. ' + e);
2685
2664
  }
@@ -3435,33 +3414,43 @@ var mParticle = (function () {
3435
3414
 
3436
3415
  var Messages$7 = Constants.Messages;
3437
3416
  function cookieSyncManager(mpInstance) {
3438
- var self = this;
3417
+ var self = this; // Public
3439
3418
 
3440
3419
  this.attemptCookieSync = function (previousMPID, mpid, mpidIsNotInCookies) {
3441
- var pixelConfig, lastSyncDateForModule, url, redirect, urlWithRedirect, requiresConsent;
3420
+ // TODO: These should move inside the for loop
3421
+ var pixelConfig, lastSyncDateForModule, url, redirect, urlWithRedirect, requiresConsent; // TODO: Make this exit quicker instead of nested
3442
3422
 
3443
3423
  if (mpid && !mpInstance._Store.webviewBridgeEnabled) {
3444
3424
  mpInstance._Store.pixelConfigurations.forEach(function (pixelSettings) {
3445
3425
  // set requiresConsent to false to start each additional pixel configuration
3446
3426
  // set to true only if filteringConsenRuleValues.values.length exists
3447
- requiresConsent = false;
3427
+ requiresConsent = false; // TODO: Replace with isEmpty
3448
3428
 
3449
3429
  if (pixelSettings.filteringConsentRuleValues && pixelSettings.filteringConsentRuleValues.values && pixelSettings.filteringConsentRuleValues.values.length) {
3450
3430
  requiresConsent = true;
3451
3431
  }
3452
3432
 
3453
3433
  pixelConfig = {
3434
+ // Kit Module ID
3454
3435
  moduleId: pixelSettings.moduleId,
3436
+ // Tells you how often we should do a cookie sync (in days)
3455
3437
  frequencyCap: pixelSettings.frequencyCap,
3438
+ // Url for cookie sync pixel
3456
3439
  pixelUrl: self.replaceAmp(pixelSettings.pixelUrl),
3440
+ // TODO: Document requirements for redirectUrl
3457
3441
  redirectUrl: pixelSettings.redirectUrl ? self.replaceAmp(pixelSettings.redirectUrl) : null,
3442
+ // Filtering rules as defined in UI
3458
3443
  filteringConsentRuleValues: pixelSettings.filteringConsentRuleValues
3459
- };
3444
+ }; // TODO: combine replaceMPID and replaceAmp into sanitizeUrl function
3445
+
3460
3446
  url = self.replaceMPID(pixelConfig.pixelUrl, mpid);
3461
3447
  redirect = pixelConfig.redirectUrl ? self.replaceMPID(pixelConfig.redirectUrl, mpid) : '';
3462
- urlWithRedirect = url + encodeURIComponent(redirect);
3448
+ urlWithRedirect = url + encodeURIComponent(redirect); // TODO: Refactor so that Persistence is only called once
3449
+ // outside of the loop
3450
+
3451
+ var persistence = mpInstance._Persistence.getPersistence(); // TODO: Is there a historic reason for checking for previousMPID?
3452
+ // it does not appear to be passed in anywhere
3463
3453
 
3464
- var persistence = mpInstance._Persistence.getPersistence();
3465
3454
 
3466
3455
  if (previousMPID && previousMPID !== mpid) {
3467
3456
  if (persistence && persistence[mpid]) {
@@ -3474,6 +3463,8 @@ var mParticle = (function () {
3474
3463
 
3475
3464
  return;
3476
3465
  } else {
3466
+ // TODO: Refactor to check for the inverse and exit early
3467
+ // rather than nesting
3477
3468
  if (persistence[mpid]) {
3478
3469
  if (!persistence[mpid].csd) {
3479
3470
  persistence[mpid].csd = {};
@@ -3483,7 +3474,12 @@ var mParticle = (function () {
3483
3474
 
3484
3475
  if (lastSyncDateForModule) {
3485
3476
  // Check to see if we need to refresh cookieSync
3486
- if (new Date().getTime() > new Date(lastSyncDateForModule).getTime() + pixelConfig.frequencyCap * 60 * 1000 * 60 * 24) {
3477
+ if ( // TODO: Turn this into a convenience method for readability?
3478
+ // We use similar comparisons elsewhere in the SDK,
3479
+ // so perhaps we can make a time comparison convenience method
3480
+ new Date().getTime() > new Date(lastSyncDateForModule).getTime() + pixelConfig.frequencyCap * // TODO: Turn these numbers into a constant so
3481
+ // we can remember what this number is for
3482
+ 60 * 1000 * 60 * 24) {
3487
3483
  self.performCookieSync(urlWithRedirect, pixelConfig.moduleId, mpid, persistence[mpid].csd, pixelConfig.filteringConsentRuleValues, mpidIsNotInCookies, requiresConsent);
3488
3484
  }
3489
3485
  } else {
@@ -3493,29 +3489,40 @@ var mParticle = (function () {
3493
3489
  }
3494
3490
  });
3495
3491
  }
3496
- };
3492
+ }; // Private
3493
+
3497
3494
 
3498
3495
  this.replaceMPID = function (string, mpid) {
3499
3496
  return string.replace('%%mpid%%', mpid);
3500
- };
3497
+ }; // Private
3498
+ // TODO: Rename function to replaceAmpWithAmpersand
3499
+
3501
3500
 
3502
3501
  this.replaceAmp = function (string) {
3503
3502
  return string.replace(/&amp;/g, '&');
3504
- };
3503
+ }; // Private
3504
+
3505
3505
 
3506
3506
  this.performCookieSync = function (url, moduleId, mpid, cookieSyncDates, filteringConsentRuleValues, mpidIsNotInCookies, requiresConsent) {
3507
3507
  // if MPID is new to cookies, we should not try to perform the cookie sync
3508
3508
  // because a cookie sync can only occur once a user either consents or doesn't
3509
3509
  // we should not check if its enabled if the user has a blank consent
3510
+ // TODO: We should do this check outside of this function
3510
3511
  if (requiresConsent && mpidIsNotInCookies) {
3511
3512
  return;
3512
- }
3513
+ } // TODO: Refactor so that check is made outside of the function.
3514
+ // Cache or store the boolean so that it only gets called once per
3515
+ // cookie sync attempt per module.
3516
+ // Currently, attemptCookieSync is called as a loop and therefore this
3517
+ // function polls the user object and consent multiple times.
3518
+
3513
3519
 
3514
3520
  if (mpInstance._Consent.isEnabledForUserConsent(filteringConsentRuleValues, mpInstance.Identity.getCurrentUser())) {
3515
3521
  var img = document.createElement('img');
3516
3522
  mpInstance.Logger.verbose(Messages$7.InformationMessages.CookieSync);
3517
3523
 
3518
3524
  img.onload = function () {
3525
+ // TODO: Break this out into a convenience method so we can unit test
3519
3526
  cookieSyncDates[moduleId.toString()] = new Date().getTime();
3520
3527
 
3521
3528
  mpInstance._Persistence.saveUserCookieSyncDatesToPersistence(mpid, cookieSyncDates);
@@ -6585,7 +6592,7 @@ var mParticle = (function () {
6585
6592
  }
6586
6593
  }
6587
6594
 
6588
- function convertProductToDTO(product) {
6595
+ function convertProductToV2DTO(product) {
6589
6596
  return {
6590
6597
  id: parseStringOrNumber(product.Sku),
6591
6598
  nm: parseStringOrNumber(product.Name),
@@ -6601,13 +6608,13 @@ var mParticle = (function () {
6601
6608
  };
6602
6609
  }
6603
6610
 
6604
- function convertProductListToDTO(productList) {
6611
+ function convertProductListToV2DTO(productList) {
6605
6612
  if (!productList) {
6606
6613
  return [];
6607
6614
  }
6608
6615
 
6609
6616
  return productList.map(function (product) {
6610
- return convertProductToDTO(product);
6617
+ return convertProductToV2DTO(product);
6611
6618
  });
6612
6619
  }
6613
6620
 
@@ -6661,7 +6668,7 @@ var mParticle = (function () {
6661
6668
  event.UserIdentities = validUserIdentities;
6662
6669
  };
6663
6670
 
6664
- this.convertToConsentStateDTO = function (state) {
6671
+ this.convertToConsentStateV2DTO = function (state) {
6665
6672
  if (!state) {
6666
6673
  return null;
6667
6674
  }
@@ -6801,7 +6808,7 @@ var mParticle = (function () {
6801
6808
  return null;
6802
6809
  };
6803
6810
 
6804
- this.convertEventToDTO = function (event) {
6811
+ this.convertEventToV2DTO = function (event) {
6805
6812
  var dto = {
6806
6813
  n: event.EventName,
6807
6814
  et: event.EventCategory,
@@ -6835,7 +6842,7 @@ var mParticle = (function () {
6835
6842
  }
6836
6843
  }
6837
6844
 
6838
- var consent = self.convertToConsentStateDTO(event.ConsentState);
6845
+ var consent = self.convertToConsentStateV2DTO(event.ConsentState);
6839
6846
 
6840
6847
  if (consent) {
6841
6848
  dto.con = consent;
@@ -6860,7 +6867,7 @@ var mParticle = (function () {
6860
6867
 
6861
6868
  if (event.ShoppingCart) {
6862
6869
  dto.sc = {
6863
- pl: convertProductListToDTO(event.ShoppingCart.ProductList)
6870
+ pl: convertProductListToV2DTO(event.ShoppingCart.ProductList)
6864
6871
  };
6865
6872
  }
6866
6873
 
@@ -6869,7 +6876,7 @@ var mParticle = (function () {
6869
6876
  an: event.ProductAction.ProductActionType,
6870
6877
  cs: mpInstance._Helpers.parseNumber(event.ProductAction.CheckoutStep),
6871
6878
  co: event.ProductAction.CheckoutOptions,
6872
- pl: convertProductListToDTO(event.ProductAction.ProductList),
6879
+ pl: convertProductListToV2DTO(event.ProductAction.ProductList),
6873
6880
  ti: event.ProductAction.TransactionId,
6874
6881
  ta: event.ProductAction.Affiliation,
6875
6882
  tcc: event.ProductAction.CouponCode,
@@ -6893,7 +6900,7 @@ var mParticle = (function () {
6893
6900
  dto.pi = event.ProductImpressions.map(function (impression) {
6894
6901
  return {
6895
6902
  pil: impression.ProductImpressionList,
6896
- pl: convertProductListToDTO(impression.ProductList)
6903
+ pl: convertProductListToV2DTO(impression.ProductList)
6897
6904
  };
6898
6905
  });
6899
6906
  }
@@ -8241,9 +8248,11 @@ var mParticle = (function () {
8241
8248
  };
8242
8249
  }
8243
8250
 
8251
+ var CCPAPurpose = 'data_sale_opt_out';
8244
8252
  function Consent(mpInstance) {
8245
- var self = this;
8246
- var CCPAPurpose = 'data_sale_opt_out'; // this function is called when consent is required to determine if a cookie sync should happen, or a forwarder should be initialized
8253
+ var self = this; // this function is called when consent is required to
8254
+ // determine if a cookie sync should happen, or a
8255
+ // forwarder should be initialized
8247
8256
 
8248
8257
  this.isEnabledForUserConsent = function (consentRules, user) {
8249
8258
  if (!consentRules || !consentRules.values || !consentRules.values.length) {
@@ -8254,16 +8263,15 @@ var mParticle = (function () {
8254
8263
  return false;
8255
8264
  }
8256
8265
 
8257
- var purposeHashes = {},
8258
- consentState = user.getConsentState(),
8259
- purposeHash;
8266
+ var purposeHashes = {};
8267
+ var consentState = user.getConsentState();
8268
+ var purposeHash;
8260
8269
 
8261
8270
  if (consentState) {
8262
8271
  // the server hashes consent purposes in the following way:
8263
8272
  // GDPR - '1' + purpose name
8264
8273
  // CCPA - '2data_sale_opt_out' (there is only 1 purpose of data_sale_opt_out for CCPA)
8265
8274
  var GDPRConsentHashPrefix = '1';
8266
- var CCPAPurpose = 'data_sale_opt_out';
8267
8275
  var CCPAHashString = '2' + CCPAPurpose;
8268
8276
  var gdprConsentState = consentState.getGDPRConsentState();
8269
8277
 
@@ -8291,6 +8299,8 @@ var mParticle = (function () {
8291
8299
  if (purposeHashes.hasOwnProperty(consentPurposeHash)) {
8292
8300
  return purposeHashes[consentPurposeHash] === hasConsented;
8293
8301
  }
8302
+
8303
+ return false;
8294
8304
  });
8295
8305
  return consentRules.includeOnMatch === isMatch;
8296
8306
  };
@@ -8332,6 +8342,8 @@ var mParticle = (function () {
8332
8342
 
8333
8343
  this.ConsentSerialization = {
8334
8344
  toMinifiedJsonObject: function toMinifiedJsonObject(state) {
8345
+ var _a;
8346
+
8335
8347
  var jsonObject = {};
8336
8348
 
8337
8349
  if (state) {
@@ -8371,8 +8383,7 @@ var mParticle = (function () {
8371
8383
  var ccpaConsentState = state.getCCPAConsentState();
8372
8384
 
8373
8385
  if (ccpaConsentState) {
8374
- jsonObject.ccpa = {};
8375
- jsonObject.ccpa[CCPAPurpose] = {};
8386
+ jsonObject.ccpa = (_a = {}, _a[CCPAPurpose] = {}, _a);
8376
8387
 
8377
8388
  if (typeof ccpaConsentState.Consented === 'boolean') {
8378
8389
  jsonObject.ccpa[CCPAPurpose].c = ccpaConsentState.Consented;
@@ -8419,15 +8430,18 @@ var mParticle = (function () {
8419
8430
 
8420
8431
  return state;
8421
8432
  }
8422
- };
8433
+ }; // TODO: Refactor this method into a constructor
8423
8434
 
8424
8435
  this.createConsentState = function (consentState) {
8425
8436
  var gdpr = {};
8426
8437
  var ccpa = {};
8427
8438
 
8428
8439
  if (consentState) {
8429
- setGDPRConsentState(consentState.getGDPRConsentState());
8430
- setCCPAConsentState(consentState.getCCPAConsentState());
8440
+ var consentStateCopy = self.createConsentState();
8441
+ consentStateCopy.setGDPRConsentState(consentState.getGDPRConsentState());
8442
+ consentStateCopy.setCCPAConsentState(consentState.getCCPAConsentState()); // TODO: Remove casting once `removeCCPAState` is removed;
8443
+
8444
+ return consentStateCopy;
8431
8445
  }
8432
8446
 
8433
8447
  function canonicalizeForDeduplication(purpose) {
@@ -8446,7 +8460,7 @@ var mParticle = (function () {
8446
8460
  /**
8447
8461
  * Invoke these methods on a consent state object.
8448
8462
  * <p>
8449
- * Usage: var consent = mParticle.Consent.createConsentState()
8463
+ * Usage: const consent = mParticle.Consent.createConsentState()
8450
8464
  * <br>
8451
8465
  * consent.setGDPRCoonsentState()
8452
8466
  *
@@ -8470,7 +8484,7 @@ var mParticle = (function () {
8470
8484
  return this;
8471
8485
  }
8472
8486
 
8473
- if (!mpInstance._Helpers.isObject(gdprConsent)) {
8487
+ if (!isObject(gdprConsent)) {
8474
8488
  mpInstance.Logger.error('Invoked with a bad or empty consent object.');
8475
8489
  return this;
8476
8490
  }
@@ -8487,12 +8501,12 @@ var mParticle = (function () {
8487
8501
  function setGDPRConsentState(gdprConsentState) {
8488
8502
  if (!gdprConsentState) {
8489
8503
  gdpr = {};
8490
- } else if (mpInstance._Helpers.isObject(gdprConsentState)) {
8504
+ } else if (isObject(gdprConsentState)) {
8491
8505
  gdpr = {};
8492
8506
 
8493
8507
  for (var purpose in gdprConsentState) {
8494
8508
  if (gdprConsentState.hasOwnProperty(purpose)) {
8495
- addGDPRConsentState(purpose, gdprConsentState[purpose]);
8509
+ this.addGDPRConsentState(purpose, gdprConsentState[purpose]);
8496
8510
  }
8497
8511
  }
8498
8512
  }
@@ -8526,7 +8540,7 @@ var mParticle = (function () {
8526
8540
 
8527
8541
 
8528
8542
  function getGDPRConsentState() {
8529
- return mpInstance._Helpers.extend({}, gdpr);
8543
+ return Object.assign({}, gdpr);
8530
8544
  }
8531
8545
  /**
8532
8546
  * Sets a CCPA Consent state (has a single purpose of 'data_sale_opt_out')
@@ -8537,7 +8551,7 @@ var mParticle = (function () {
8537
8551
 
8538
8552
 
8539
8553
  function setCCPAConsentState(ccpaConsent) {
8540
- if (!mpInstance._Helpers.isObject(ccpaConsent)) {
8554
+ if (!isObject(ccpaConsent)) {
8541
8555
  mpInstance.Logger.error('Invoked with a bad or empty CCPA consent object.');
8542
8556
  return this;
8543
8557
  }
@@ -8571,10 +8585,12 @@ var mParticle = (function () {
8571
8585
  function removeCCPAConsentState() {
8572
8586
  delete ccpa[CCPAPurpose];
8573
8587
  return this;
8574
- }
8588
+ } // TODO: Can we remove this? It is deprecated.
8589
+
8575
8590
 
8576
8591
  function removeCCPAState() {
8577
- mpInstance.Logger.warning('removeCCPAState is deprecated and will be removed in a future release; use removeCCPAConsentState instead');
8592
+ mpInstance.Logger.warning('removeCCPAState is deprecated and will be removed in a future release; use removeCCPAConsentState instead'); // @ts-ignore
8593
+
8578
8594
  return removeCCPAConsentState();
8579
8595
  }
8580
8596
 
@@ -10666,6 +10682,9 @@ var mParticle = (function () {
10666
10682
  // Certain Helper, Store, and Identity properties need to be mocked to be used in the `returnBatch` method
10667
10683
  _Helpers: {
10668
10684
  sanitizeAttributes: window.mParticle.getInstance()._Helpers.sanitizeAttributes,
10685
+ generateHash: function generateHash() {
10686
+ return 'mockHash';
10687
+ },
10669
10688
  generateUniqueId: function generateUniqueId() {
10670
10689
  return 'mockId';
10671
10690
  },