@mparticle/web-sdk 2.20.3 → 2.21.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/mparticle.js CHANGED
@@ -1,7 +1,7 @@
1
1
  var mParticle = (function () {
2
2
 
3
3
  // Base64 encoder/decoder - http://www.webtoolkit.info/javascript_base64.html
4
- var Base64$2 = {
4
+ var Base64$1 = {
5
5
  _keyStr: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=',
6
6
  // Input must be a string
7
7
  encode: function encode(input) {
@@ -32,7 +32,7 @@ var mParticle = (function () {
32
32
  } else if (isNaN(chr3)) {
33
33
  enc4 = 64;
34
34
  }
35
- output = output + Base64$2._keyStr.charAt(enc1) + Base64$2._keyStr.charAt(enc2) + Base64$2._keyStr.charAt(enc3) + Base64$2._keyStr.charAt(enc4);
35
+ output = output + Base64$1._keyStr.charAt(enc1) + Base64$1._keyStr.charAt(enc2) + Base64$1._keyStr.charAt(enc3) + Base64$1._keyStr.charAt(enc4);
36
36
  }
37
37
  return output;
38
38
  },
@@ -44,7 +44,7 @@ var mParticle = (function () {
44
44
  } catch (e) {
45
45
  //log(e);
46
46
  }
47
- return Base64$2._decode(input);
47
+ return Base64$1._decode(input);
48
48
  },
49
49
  _decode: function _decode(input) {
50
50
  var output = '';
@@ -53,10 +53,10 @@ var mParticle = (function () {
53
53
  var i = 0;
54
54
  input = input.replace(/[^A-Za-z0-9\+\/\=]/g, '');
55
55
  while (i < input.length) {
56
- enc1 = Base64$2._keyStr.indexOf(input.charAt(i++));
57
- enc2 = Base64$2._keyStr.indexOf(input.charAt(i++));
58
- enc3 = Base64$2._keyStr.indexOf(input.charAt(i++));
59
- enc4 = Base64$2._keyStr.indexOf(input.charAt(i++));
56
+ enc1 = Base64$1._keyStr.indexOf(input.charAt(i++));
57
+ enc2 = Base64$1._keyStr.indexOf(input.charAt(i++));
58
+ enc3 = Base64$1._keyStr.indexOf(input.charAt(i++));
59
+ enc4 = Base64$1._keyStr.indexOf(input.charAt(i++));
60
60
  chr1 = enc1 << 2 | enc2 >> 4;
61
61
  chr2 = (enc2 & 15) << 4 | enc3 >> 2;
62
62
  chr3 = (enc3 & 3) << 6 | enc4;
@@ -200,7 +200,7 @@ var mParticle = (function () {
200
200
  isArray: function isArray(arg) {
201
201
  return Object.prototype.toString.call(arg) === '[object Array]';
202
202
  },
203
- Base64: Base64$2
203
+ Base64: Base64$1
204
204
  };
205
205
 
206
206
  function _defineProperty(obj, key, value) {
@@ -582,7 +582,7 @@ var mParticle = (function () {
582
582
  Environment: Environment
583
583
  };
584
584
 
585
- var version = "2.20.3";
585
+ var version = "2.21.1";
586
586
 
587
587
  var Constants = {
588
588
  sdkVersion: version,
@@ -731,7 +731,8 @@ var mParticle = (function () {
731
731
  FeatureFlags: {
732
732
  ReportBatching: 'reportBatching',
733
733
  EventsV3: 'eventsV3',
734
- EventBatchingIntervalMillis: 'eventBatchingIntervalMillis'
734
+ EventBatchingIntervalMillis: 'eventBatchingIntervalMillis',
735
+ OfflineStorage: 'offlineStorage'
735
736
  },
736
737
  DefaultInstance: 'default_instance'
737
738
  };
@@ -1166,6 +1167,12 @@ var mParticle = (function () {
1166
1167
 
1167
1168
  var slugify = slugify$1.exports;
1168
1169
 
1170
+ var createCookieString = function createCookieString(value) {
1171
+ return replaceCommasWithPipes(replaceQuotesWithApostrophes(value));
1172
+ };
1173
+ var revertCookieString = function revertCookieString(value) {
1174
+ return replacePipesWithCommas(replaceApostrophesWithQuotes(value));
1175
+ };
1169
1176
  var inArray = function inArray(items, name) {
1170
1177
  var i = 0;
1171
1178
  if (Array.prototype.indexOf) {
@@ -1273,6 +1280,18 @@ var mParticle = (function () {
1273
1280
  return null;
1274
1281
  }
1275
1282
  };
1283
+ var replaceCommasWithPipes = function replaceCommasWithPipes(value) {
1284
+ return value.replace(/,/g, '|');
1285
+ };
1286
+ var replacePipesWithCommas = function replacePipesWithCommas(value) {
1287
+ return value.replace(/\|/g, ',');
1288
+ };
1289
+ var replaceApostrophesWithQuotes = function replaceApostrophesWithQuotes(value) {
1290
+ return value.replace(/\'/g, '"');
1291
+ };
1292
+ var replaceQuotesWithApostrophes = function replaceQuotesWithApostrophes(value) {
1293
+ return value.replace(/\"/g, "'");
1294
+ };
1276
1295
  // FIXME: REFACTOR for V3
1277
1296
  // only used in store.js to sanitize server-side formatting of
1278
1297
  // booleans when checking for `isDevelopmentMode`
@@ -1898,10 +1917,88 @@ var mParticle = (function () {
1898
1917
  }
1899
1918
  }
1900
1919
 
1920
+ var BaseVault = /** @class */function () {
1921
+ /**
1922
+ *
1923
+ * @param {string} storageKey the local storage key string
1924
+ * @param {Storage} Web API Storage object that is being used
1925
+ * @param {IVaultOptions} options A Dictionary of IVaultOptions
1926
+ */
1927
+ function BaseVault(storageKey, storageObject, options) {
1928
+ this._storageKey = storageKey;
1929
+ this.storageObject = storageObject;
1930
+ // Add a fake logger in case one is not provided or needed
1931
+ this.logger = (options === null || options === void 0 ? void 0 : options.logger) || {
1932
+ verbose: function verbose() {},
1933
+ warning: function warning() {},
1934
+ error: function error() {}
1935
+ };
1936
+ this.contents = this.retrieve();
1937
+ }
1938
+ /**
1939
+ * Stores a StorableItem to Storage
1940
+ * @method store
1941
+ * @param item {StorableItem}
1942
+ */
1943
+ BaseVault.prototype.store = function (item) {
1944
+ this.contents = item;
1945
+ var stringifiedItem = !isEmpty(item) ? JSON.stringify(item) : '';
1946
+ try {
1947
+ this.storageObject.setItem(this._storageKey, stringifiedItem);
1948
+ this.logger.verbose("Saving item to Storage: ".concat(stringifiedItem));
1949
+ } catch (error) {
1950
+ this.logger.error("Cannot Save items to Storage: ".concat(stringifiedItem));
1951
+ this.logger.error(error);
1952
+ }
1953
+ };
1954
+ /**
1955
+ * Retrieve StorableItem from Storage
1956
+ * @method retrieve
1957
+ * @returns {StorableItem}
1958
+ */
1959
+ BaseVault.prototype.retrieve = function () {
1960
+ // TODO: Handle cases where Local Storage is unavailable
1961
+ // https://go.mparticle.com/work/SQDSDKS-5022
1962
+ var item = this.storageObject.getItem(this._storageKey);
1963
+ this.contents = item ? JSON.parse(item) : null;
1964
+ this.logger.verbose("Retrieving item from Storage: ".concat(item));
1965
+ return this.contents;
1966
+ };
1967
+ /**
1968
+ * Removes all persisted data from Storage based on this vault's `key`
1969
+ * Will remove storage key from Storage as well
1970
+ * @method purge
1971
+ */
1972
+ BaseVault.prototype.purge = function () {
1973
+ this.logger.verbose('Purging Storage');
1974
+ this.contents = null;
1975
+ this.storageObject.removeItem(this._storageKey);
1976
+ };
1977
+ return BaseVault;
1978
+ }();
1979
+ var LocalStorageVault = /** @class */function (_super) {
1980
+ __extends(LocalStorageVault, _super);
1981
+ function LocalStorageVault(storageKey, options) {
1982
+ return _super.call(this, storageKey, window.localStorage, options) || this;
1983
+ }
1984
+ return LocalStorageVault;
1985
+ }(BaseVault);
1986
+ var SessionStorageVault = /** @class */function (_super) {
1987
+ __extends(SessionStorageVault, _super);
1988
+ function SessionStorageVault(storageKey, options) {
1989
+ return _super.call(this, storageKey, window.sessionStorage, options) || this;
1990
+ }
1991
+ return SessionStorageVault;
1992
+ }(BaseVault);
1993
+
1901
1994
  /**
1902
- * BatchUploader contains all the logic to upload batches to mParticle.
1903
- * It queues events as they come in and at set intervals turns them into batches.
1904
- * It then attempts to upload them to mParticle.
1995
+ * BatchUploader contains all the logic to store/retrieve events and batches
1996
+ * to/from persistence, and upload batches to mParticle.
1997
+ * It queues events as they come in, storing them in persistence, then at set
1998
+ * intervals turns them into batches and transfers between event and batch
1999
+ * persistence.
2000
+ * It then attempts to upload them to mParticle, purging batch persistence if
2001
+ * the upload is successful
1905
2002
  *
1906
2003
  * These uploads happen on an interval basis using window.fetch or XHR
1907
2004
  * requests, depending on what is available in the browser.
@@ -1916,23 +2013,53 @@ var mParticle = (function () {
1916
2013
  * @param {number} uploadInterval - the desired upload interval in milliseconds
1917
2014
  */
1918
2015
  function BatchUploader(mpInstance, uploadInterval) {
1919
- var _a;
2016
+ var _a, _b;
2017
+ this.offlineStorageEnabled = false;
1920
2018
  this.mpInstance = mpInstance;
1921
2019
  this.uploadIntervalMillis = uploadInterval;
1922
2020
  this.batchingEnabled = uploadInterval >= BatchUploader.MINIMUM_INTERVAL_MILLIS;
1923
2021
  if (this.uploadIntervalMillis < BatchUploader.MINIMUM_INTERVAL_MILLIS) {
1924
2022
  this.uploadIntervalMillis = BatchUploader.MINIMUM_INTERVAL_MILLIS;
1925
2023
  }
2024
+ // Events will be queued during `queueEvents` method
1926
2025
  this.eventsQueuedForProcessing = [];
2026
+ // Batch queue should start empty and will be populated during
2027
+ // `prepareAndUpload` method, either via Local Storage or after
2028
+ // new batches are created.
1927
2029
  this.batchesQueuedForProcessing = [];
1928
- var SDKConfig = (_a = this.mpInstance._Store, _a.SDKConfig),
1929
- devToken = _a.devToken;
2030
+ // Cache Offline Storage Availability boolean
2031
+ // so that we don't have to check it every time
2032
+ this.offlineStorageEnabled = this.isOfflineStorageAvailable();
2033
+ if (this.offlineStorageEnabled) {
2034
+ this.eventVault = new SessionStorageVault("".concat(mpInstance._Store.storageName, "-events"), {
2035
+ logger: mpInstance.Logger
2036
+ });
2037
+ this.batchVault = new LocalStorageVault("".concat(mpInstance._Store.storageName, "-batches"), {
2038
+ logger: mpInstance.Logger
2039
+ });
2040
+ // Load Events from Session Storage in case we have any in storage
2041
+ (_a = this.eventsQueuedForProcessing).push.apply(_a, this.eventVault.retrieve());
2042
+ }
2043
+ var SDKConfig = (_b = this.mpInstance._Store, _b.SDKConfig),
2044
+ devToken = _b.devToken;
1930
2045
  var baseUrl = this.mpInstance._Helpers.createServiceUrl(SDKConfig.v3SecureServiceUrl, devToken);
1931
2046
  this.uploadUrl = "".concat(baseUrl, "/events");
1932
2047
  this.uploader = window.fetch ? new FetchUploader(this.uploadUrl) : new XHRUploader(this.uploadUrl);
1933
2048
  this.triggerUploadInterval(true, false);
1934
2049
  this.addEventListeners();
1935
2050
  }
2051
+ BatchUploader.prototype.isOfflineStorageAvailable = function () {
2052
+ var _a;
2053
+ var getFeatureFlag = (_a = this.mpInstance, _a._Helpers.getFeatureFlag),
2054
+ deviceId = _a._Store.deviceId;
2055
+ var offlineStorageFeatureFlagValue = getFeatureFlag(Constants.FeatureFlags.OfflineStorage);
2056
+ var offlineStoragePercentage = parseInt(offlineStorageFeatureFlagValue, 10);
2057
+ var rampNumber = getRampNumber(deviceId);
2058
+ // TODO: Handle cases where Local Storage is unavailable
2059
+ // Potentially shared between Vault and Persistence as well
2060
+ // https://go.mparticle.com/work/SQDSDKS-5022
2061
+ return offlineStoragePercentage >= rampNumber;
2062
+ };
1936
2063
  // Adds listeners to be used trigger Navigator.sendBeacon if the browser
1937
2064
  // loses focus for any reason, such as closing browser tab or minimizing window
1938
2065
  BatchUploader.prototype.addEventListeners = function () {
@@ -1974,6 +2101,9 @@ var mParticle = (function () {
1974
2101
  BatchUploader.prototype.queueEvent = function (event) {
1975
2102
  if (!isEmpty(event)) {
1976
2103
  this.eventsQueuedForProcessing.push(event);
2104
+ if (this.offlineStorageEnabled && this.eventVault) {
2105
+ this.eventVault.store(this.eventsQueuedForProcessing);
2106
+ }
1977
2107
  this.mpInstance.Logger.verbose("Queuing event: ".concat(JSON.stringify(event)));
1978
2108
  this.mpInstance.Logger.verbose("Queued event count: ".concat(this.eventsQueuedForProcessing.length));
1979
2109
  // TODO: Remove this check once the v2 code path is removed
@@ -2057,28 +2187,58 @@ var mParticle = (function () {
2057
2187
  BatchUploader.prototype.prepareAndUpload = function (triggerFuture, useBeacon) {
2058
2188
  return __awaiter(this, void 0, void 0, function () {
2059
2189
  var currentUser, currentEvents, newBatches, batchesToUpload, batchesThatDidNotUpload;
2060
- var _a, _b;
2061
- return __generator(this, function (_c) {
2062
- switch (_c.label) {
2190
+ var _a, _b, _c;
2191
+ return __generator(this, function (_d) {
2192
+ switch (_d.label) {
2063
2193
  case 0:
2064
2194
  currentUser = this.mpInstance.Identity.getCurrentUser();
2065
2195
  currentEvents = this.eventsQueuedForProcessing;
2066
2196
  this.eventsQueuedForProcessing = [];
2067
- newBatches = BatchUploader.createNewBatches(currentEvents, currentUser, this.mpInstance);
2197
+ if (this.offlineStorageEnabled && this.eventVault) {
2198
+ this.eventVault.store([]);
2199
+ }
2200
+ newBatches = [];
2201
+ if (!isEmpty(currentEvents)) {
2202
+ newBatches = BatchUploader.createNewBatches(currentEvents, currentUser, this.mpInstance);
2203
+ }
2204
+ // Top Load any older Batches from Offline Storage so they go out first
2205
+ if (this.offlineStorageEnabled && this.batchVault) {
2206
+ (_a = this.batchesQueuedForProcessing).unshift.apply(_a, this.batchVault.retrieve());
2207
+ // Remove batches from local storage before transmit to
2208
+ // prevent duplication
2209
+ this.batchVault.purge();
2210
+ }
2068
2211
  if (!isEmpty(newBatches)) {
2069
- (_a = this.batchesQueuedForProcessing).push.apply(_a, newBatches);
2212
+ (_b = this.batchesQueuedForProcessing).push.apply(_b, newBatches);
2070
2213
  }
2071
2214
  batchesToUpload = this.batchesQueuedForProcessing;
2072
2215
  this.batchesQueuedForProcessing = [];
2216
+ // If `useBeacon` is true, the browser has been closed suddently
2217
+ // so we should save `batchesToUpload` to Offline Storage before
2218
+ // an upload is attempted.
2219
+ if (useBeacon && this.offlineStorageEnabled && this.batchVault) {
2220
+ this.batchVault.store(batchesToUpload);
2221
+ }
2073
2222
  return [4 /*yield*/, this.uploadBatches(this.mpInstance.Logger, batchesToUpload, useBeacon)];
2074
2223
  case 1:
2075
- batchesThatDidNotUpload = _c.sent();
2224
+ batchesThatDidNotUpload = _d.sent();
2076
2225
  // Batches that do not successfully upload are added back to the process queue
2077
2226
  // in the order they were created so that we can attempt re-transmission in
2078
2227
  // the same sequence. This is to prevent any potential data corruption.
2079
2228
  if (!isEmpty(batchesThatDidNotUpload)) {
2080
2229
  // TODO: https://go.mparticle.com/work/SQDSDKS-5165
2081
- (_b = this.batchesQueuedForProcessing).unshift.apply(_b, batchesThatDidNotUpload);
2230
+ (_c = this.batchesQueuedForProcessing).unshift.apply(_c, batchesThatDidNotUpload);
2231
+ }
2232
+ // Update Offline Storage with current state of batch queue
2233
+ if (!useBeacon && this.offlineStorageEnabled && this.batchVault) {
2234
+ // Note: since beacon is "Fire and forget" it will empty `batchesThatDidNotUplod`
2235
+ // regardless of whether the batches were successfully uploaded or not. We should
2236
+ // therefore NOT overwrite Offline Storage when beacon returns, so that we can retry
2237
+ // uploading saved batches at a later time. Batches should only be removed from
2238
+ // Local Storage once we can confirm they are successfully uploaded.
2239
+ this.batchVault.store(this.batchesQueuedForProcessing);
2240
+ // Clear batch queue since everything should be in Offline Storage
2241
+ this.batchesQueuedForProcessing = [];
2082
2242
  }
2083
2243
  if (triggerFuture) {
2084
2244
  this.triggerUploadInterval(triggerFuture, false);
@@ -2498,7 +2658,7 @@ var mParticle = (function () {
2498
2658
  }
2499
2659
  };
2500
2660
 
2501
- var StorageNames$2 = Constants.StorageNames;
2661
+ var StorageNames$1 = Constants.StorageNames;
2502
2662
  function Helpers(mpInstance) {
2503
2663
  var self = this;
2504
2664
  this.canLog = function () {
@@ -2794,16 +2954,16 @@ var mParticle = (function () {
2794
2954
  };
2795
2955
  this.createMainStorageName = function (workspaceToken) {
2796
2956
  if (workspaceToken) {
2797
- return StorageNames$2.currentStorageName + '_' + workspaceToken;
2957
+ return StorageNames$1.currentStorageName + '_' + workspaceToken;
2798
2958
  } else {
2799
- return StorageNames$2.currentStorageName;
2959
+ return StorageNames$1.currentStorageName;
2800
2960
  }
2801
2961
  };
2802
2962
  this.createProductStorageName = function (workspaceToken) {
2803
2963
  if (workspaceToken) {
2804
- return StorageNames$2.currentStorageProductsName + '_' + workspaceToken;
2964
+ return StorageNames$1.currentStorageProductsName + '_' + workspaceToken;
2805
2965
  } else {
2806
- return StorageNames$2.currentStorageProductsName;
2966
+ return StorageNames$1.currentStorageProductsName;
2807
2967
  }
2808
2968
  };
2809
2969
 
@@ -3621,7 +3781,6 @@ var mParticle = (function () {
3621
3781
  clientId: null,
3622
3782
  deviceId: null,
3623
3783
  devToken: null,
3624
- migrationData: {},
3625
3784
  serverSettings: {},
3626
3785
  dateLastEventSent: null,
3627
3786
  sessionStartDate: null,
@@ -3636,7 +3795,6 @@ var mParticle = (function () {
3636
3795
  configurationLoaded: false,
3637
3796
  identityCallInFlight: false,
3638
3797
  SDKConfig: {},
3639
- migratingToIDSyncCookies: false,
3640
3798
  nonCurrentUserMPIDs: {},
3641
3799
  identifyCalled: false,
3642
3800
  isLoggedIn: false,
@@ -3814,6 +3972,9 @@ var mParticle = (function () {
3814
3972
  if (!this.SDKConfig.flags.hasOwnProperty(Constants.FeatureFlags.ReportBatching)) {
3815
3973
  this.SDKConfig.flags[Constants.FeatureFlags.ReportBatching] = false;
3816
3974
  }
3975
+ if (!this.SDKConfig.flags.hasOwnProperty(Constants.FeatureFlags.OfflineStorage)) {
3976
+ this.SDKConfig.flags[Constants.FeatureFlags.OfflineStorage] = 0;
3977
+ }
3817
3978
  }
3818
3979
  }
3819
3980
 
@@ -3868,11 +4029,11 @@ var mParticle = (function () {
3868
4029
  };
3869
4030
  }
3870
4031
 
3871
- var Base64$1 = Polyfill.Base64,
4032
+ var Base64 = Polyfill.Base64,
3872
4033
  Messages$4 = Constants.Messages,
3873
4034
  Base64CookieKeys = Constants.Base64CookieKeys,
3874
4035
  SDKv2NonMPIDCookieKeys = Constants.SDKv2NonMPIDCookieKeys,
3875
- StorageNames$1 = Constants.StorageNames;
4036
+ StorageNames = Constants.StorageNames;
3876
4037
  function _Persistence(mpInstance) {
3877
4038
  var self = this;
3878
4039
  this.useLocalStorage = function () {
@@ -3933,7 +4094,7 @@ var mParticle = (function () {
3933
4094
  if (mpInstance._Store.isLocalStorageAvailable) {
3934
4095
  var encodedProducts = localStorage.getItem(mpInstance._Store.prodStorageName);
3935
4096
  if (encodedProducts) {
3936
- var decodedProducts = JSON.parse(Base64$1.decode(encodedProducts));
4097
+ var decodedProducts = JSON.parse(Base64.decode(encodedProducts));
3937
4098
  }
3938
4099
  if (mpInstance._Store.mpid) {
3939
4100
  self.storeProductsInMemory(decodedProducts, mpInstance._Store.mpid);
@@ -4047,7 +4208,7 @@ var mParticle = (function () {
4047
4208
  parsedProducts,
4048
4209
  encodedProducts = localStorage.getItem(mpInstance._Store.prodStorageName);
4049
4210
  if (encodedProducts) {
4050
- decodedProducts = Base64$1.decode(encodedProducts);
4211
+ decodedProducts = Base64.decode(encodedProducts);
4051
4212
  }
4052
4213
  // if there is an MPID, we are retrieving the user's products, which is an array
4053
4214
  if (mpid) {
@@ -4073,7 +4234,7 @@ var mParticle = (function () {
4073
4234
  encodedProducts = localStorage.getItem(mpInstance._Store.prodStorageName),
4074
4235
  parsedDecodedProducts;
4075
4236
  if (encodedProducts) {
4076
- decodedProducts = Base64$1.decode(encodedProducts);
4237
+ decodedProducts = Base64.decode(encodedProducts);
4077
4238
  }
4078
4239
  // returns an object with keys of MPID and values of array of products
4079
4240
  try {
@@ -4099,7 +4260,7 @@ var mParticle = (function () {
4099
4260
  allLocalStorageProducts = allLocalStorageProducts || {};
4100
4261
  allLocalStorageProducts[mpid] = currentUserProducts;
4101
4262
  try {
4102
- window.localStorage.setItem(encodeURIComponent(mpInstance._Store.prodStorageName), Base64$1.encode(JSON.stringify(allLocalStorageProducts)));
4263
+ window.localStorage.setItem(encodeURIComponent(mpInstance._Store.prodStorageName), Base64.encode(JSON.stringify(allLocalStorageProducts)));
4103
4264
  } catch (e) {
4104
4265
  mpInstance.Logger.error('Error with setting products on localStorage.');
4105
4266
  }
@@ -4357,7 +4518,7 @@ var mParticle = (function () {
4357
4518
  if (persistence.gs[key]) {
4358
4519
  // base64 encode any value that is an object or Array in globalSettings
4359
4520
  if (Array.isArray(persistence.gs[key]) && persistence.gs[key].length || mpInstance._Helpers.isObject(persistence.gs[key]) && Object.keys(persistence.gs[key]).length) {
4360
- persistence.gs[key] = Base64$1.encode(JSON.stringify(persistence.gs[key]));
4521
+ persistence.gs[key] = Base64.encode(JSON.stringify(persistence.gs[key]));
4361
4522
  } else {
4362
4523
  delete persistence.gs[key];
4363
4524
  }
@@ -4378,7 +4539,7 @@ var mParticle = (function () {
4378
4539
  if (persistence[mpid].hasOwnProperty(key)) {
4379
4540
  if (Base64CookieKeys[key]) {
4380
4541
  if (mpInstance._Helpers.isObject(persistence[mpid][key]) && Object.keys(persistence[mpid][key]).length) {
4381
- persistence[mpid][key] = Base64$1.encode(JSON.stringify(persistence[mpid][key]));
4542
+ persistence[mpid][key] = Base64.encode(JSON.stringify(persistence[mpid][key]));
4382
4543
  } else {
4383
4544
  delete persistence[mpid][key];
4384
4545
  }
@@ -4388,17 +4549,20 @@ var mParticle = (function () {
4388
4549
  }
4389
4550
  }
4390
4551
  }
4391
- return self.createCookieString(JSON.stringify(persistence));
4552
+ return createCookieString(JSON.stringify(persistence));
4392
4553
  };
4554
+
4555
+ // TODO: This should actually be decodePersistenceString or
4556
+ // we should refactor this to take a string and return an object
4393
4557
  this.decodePersistence = function (persistence) {
4394
4558
  try {
4395
4559
  if (persistence) {
4396
- persistence = JSON.parse(self.revertCookieString(persistence));
4560
+ persistence = JSON.parse(revertCookieString(persistence));
4397
4561
  if (mpInstance._Helpers.isObject(persistence) && Object.keys(persistence).length) {
4398
4562
  for (var key in persistence.gs) {
4399
4563
  if (persistence.gs.hasOwnProperty(key)) {
4400
4564
  if (Base64CookieKeys[key]) {
4401
- persistence.gs[key] = JSON.parse(Base64$1.decode(persistence.gs[key]));
4565
+ persistence.gs[key] = JSON.parse(Base64.decode(persistence.gs[key]));
4402
4566
  } else if (key === 'ie') {
4403
4567
  persistence.gs[key] = Boolean(persistence.gs[key]);
4404
4568
  }
@@ -4411,7 +4575,7 @@ var mParticle = (function () {
4411
4575
  if (persistence[mpid].hasOwnProperty(key)) {
4412
4576
  if (Base64CookieKeys[key]) {
4413
4577
  if (persistence[mpid][key].length) {
4414
- persistence[mpid][key] = JSON.parse(Base64$1.decode(persistence[mpid][key]));
4578
+ persistence[mpid][key] = JSON.parse(Base64.decode(persistence[mpid][key]));
4415
4579
  }
4416
4580
  }
4417
4581
  }
@@ -4428,24 +4592,6 @@ var mParticle = (function () {
4428
4592
  mpInstance.Logger.error('Problem with decoding cookie', e);
4429
4593
  }
4430
4594
  };
4431
- this.replaceCommasWithPipes = function (string) {
4432
- return string.replace(/,/g, '|');
4433
- };
4434
- this.replacePipesWithCommas = function (string) {
4435
- return string.replace(/\|/g, ',');
4436
- };
4437
- this.replaceApostrophesWithQuotes = function (string) {
4438
- return string.replace(/\'/g, '"');
4439
- };
4440
- this.replaceQuotesWithApostrophes = function (string) {
4441
- return string.replace(/\"/g, "'");
4442
- };
4443
- this.createCookieString = function (string) {
4444
- return self.replaceCommasWithPipes(self.replaceQuotesWithApostrophes(string));
4445
- };
4446
- this.revertCookieString = function (string) {
4447
- return self.replacePipesWithCommas(self.replaceApostrophesWithQuotes(string));
4448
- };
4449
4595
  this.getCookieDomain = function () {
4450
4596
  if (mpInstance._Store.SDKConfig.cookieDomain) {
4451
4597
  return mpInstance._Store.SDKConfig.cookieDomain;
@@ -4499,7 +4645,7 @@ var mParticle = (function () {
4499
4645
  var allCartProducts,
4500
4646
  cartProductsString = localStorage.getItem(mpInstance._Store.prodStorageName);
4501
4647
  if (cartProductsString) {
4502
- allCartProducts = JSON.parse(Base64$1.decode(cartProductsString));
4648
+ allCartProducts = JSON.parse(Base64.decode(cartProductsString));
4503
4649
  if (allCartProducts && allCartProducts[mpid] && allCartProducts[mpid].cp) {
4504
4650
  return allCartProducts[mpid].cp;
4505
4651
  }
@@ -4511,7 +4657,7 @@ var mParticle = (function () {
4511
4657
  return;
4512
4658
  }
4513
4659
  try {
4514
- window.localStorage.setItem(encodeURIComponent(mpInstance._Store.prodStorageName), Base64$1.encode(JSON.stringify(allProducts)));
4660
+ window.localStorage.setItem(encodeURIComponent(mpInstance._Store.prodStorageName), Base64.encode(JSON.stringify(allProducts)));
4515
4661
  } catch (e) {
4516
4662
  mpInstance.Logger.error('Error with setting products on localStorage.');
4517
4663
  }
@@ -4690,16 +4836,16 @@ var mParticle = (function () {
4690
4836
  self.update();
4691
4837
  };
4692
4838
  this.resetPersistence = function () {
4693
- removeLocalStorage(StorageNames$1.localStorageName);
4694
- removeLocalStorage(StorageNames$1.localStorageNameV3);
4695
- removeLocalStorage(StorageNames$1.localStorageNameV4);
4839
+ removeLocalStorage(StorageNames.localStorageName);
4840
+ removeLocalStorage(StorageNames.localStorageNameV3);
4841
+ removeLocalStorage(StorageNames.localStorageNameV4);
4696
4842
  removeLocalStorage(mpInstance._Store.prodStorageName);
4697
4843
  removeLocalStorage(mpInstance._Store.storageName);
4698
- removeLocalStorage(StorageNames$1.localStorageProductsV4);
4699
- self.expireCookies(StorageNames$1.cookieName);
4700
- self.expireCookies(StorageNames$1.cookieNameV2);
4701
- self.expireCookies(StorageNames$1.cookieNameV3);
4702
- self.expireCookies(StorageNames$1.cookieNameV4);
4844
+ removeLocalStorage(StorageNames.localStorageProductsV4);
4845
+ self.expireCookies(StorageNames.cookieName);
4846
+ self.expireCookies(StorageNames.cookieNameV2);
4847
+ self.expireCookies(StorageNames.cookieNameV3);
4848
+ self.expireCookies(StorageNames.cookieNameV4);
4703
4849
  self.expireCookies(mpInstance._Store.prodStorageName);
4704
4850
  self.expireCookies(mpInstance._Store.storageName);
4705
4851
  if (mParticle._isTestEnv) {
@@ -4985,208 +5131,6 @@ var mParticle = (function () {
4985
5131
  };
4986
5132
  }
4987
5133
 
4988
- var StorageNames = Constants.StorageNames,
4989
- Base64 = Polyfill.Base64,
4990
- CookiesGlobalSettingsKeys = {
4991
- das: 1
4992
- },
4993
- MPIDKeys = {
4994
- ui: 1
4995
- };
4996
- function Migrations(mpInstance) {
4997
- var self = this;
4998
- // if there is a cookie or localStorage:
4999
- // 1. determine which version it is ('mprtcl-api', 'mprtcl-v2', 'mprtcl-v3', 'mprtcl-v4')
5000
- // 2. return if 'mprtcl-v4', otherwise migrate to mprtclv4 schema
5001
- // 3. if 'mprtcl-api', could be JSSDKv2 or JSSDKv1. JSSDKv2 cookie has a 'globalSettings' key on it
5002
- this.migrate = function () {
5003
- try {
5004
- migrateCookies();
5005
- } catch (e) {
5006
- mpInstance._Persistence.expireCookies(StorageNames.cookieNameV3);
5007
- mpInstance._Persistence.expireCookies(StorageNames.cookieNameV4);
5008
- mpInstance.Logger.error('Error migrating cookie: ' + e);
5009
- }
5010
- if (mpInstance._Store.isLocalStorageAvailable) {
5011
- try {
5012
- migrateLocalStorage();
5013
- } catch (e) {
5014
- localStorage.removeItem(StorageNames.localStorageNameV3);
5015
- localStorage.removeItem(StorageNames.localStorageNameV4);
5016
- mpInstance.Logger.error('Error migrating localStorage: ' + e);
5017
- }
5018
- }
5019
- };
5020
- function migrateCookies() {
5021
- var cookies = window.document.cookie.split('; '),
5022
- foundCookie,
5023
- i,
5024
- l,
5025
- parts,
5026
- name,
5027
- cookie;
5028
- mpInstance.Logger.verbose(Constants.Messages.InformationMessages.CookieSearch);
5029
- for (i = 0, l = cookies.length; i < l; i++) {
5030
- try {
5031
- parts = cookies[i].split('=');
5032
- name = mpInstance._Helpers.decoded(parts.shift());
5033
- cookie = mpInstance._Helpers.decoded(parts.join('='));
5034
- } catch (e) {
5035
- mpInstance.Logger.verbose('Unable to parse cookie: ' + name + '. Skipping.');
5036
- }
5037
-
5038
- //most recent version needs no migration
5039
- if (name === mpInstance._Store.storageName) {
5040
- return;
5041
- }
5042
- if (name === StorageNames.cookieNameV4) {
5043
- // adds cookies to new namespace, removes previous cookie
5044
- finishCookieMigration(cookie, StorageNames.cookieNameV4);
5045
- if (mpInstance._Store.isLocalStorageAvailable) {
5046
- migrateProductsToNameSpace();
5047
- }
5048
- return;
5049
- // migration path for SDKv1CookiesV3, doesn't need to be encoded
5050
- }
5051
-
5052
- if (name === StorageNames.cookieNameV3) {
5053
- foundCookie = self.convertSDKv1CookiesV3ToSDKv2CookiesV4(cookie);
5054
- finishCookieMigration(foundCookie, StorageNames.cookieNameV3);
5055
- break;
5056
- }
5057
- }
5058
- }
5059
- function finishCookieMigration(cookie, cookieName) {
5060
- var date = new Date(),
5061
- cookieDomain = mpInstance._Persistence.getCookieDomain(),
5062
- expires,
5063
- domain;
5064
- expires = new Date(date.getTime() + StorageNames.CookieExpiration * 24 * 60 * 60 * 1000).toGMTString();
5065
- if (cookieDomain === '') {
5066
- domain = '';
5067
- } else {
5068
- domain = ';domain=' + cookieDomain;
5069
- }
5070
- mpInstance.Logger.verbose(Constants.Messages.InformationMessages.CookieSet);
5071
- window.document.cookie = encodeURIComponent(mpInstance._Store.storageName) + '=' + cookie + ';expires=' + expires + ';path=/' + domain;
5072
- mpInstance._Persistence.expireCookies(cookieName);
5073
- mpInstance._Store.migratingToIDSyncCookies = true;
5074
- }
5075
- this.convertSDKv1CookiesV3ToSDKv2CookiesV4 = function (SDKv1CookiesV3) {
5076
- SDKv1CookiesV3 = mpInstance._Persistence.replacePipesWithCommas(mpInstance._Persistence.replaceApostrophesWithQuotes(SDKv1CookiesV3));
5077
- var parsedSDKv1CookiesV3 = JSON.parse(SDKv1CookiesV3);
5078
- var parsedCookiesV4 = JSON.parse(restructureToV4Cookie(SDKv1CookiesV3));
5079
- if (parsedSDKv1CookiesV3.mpid) {
5080
- parsedCookiesV4.gs.csm.push(parsedSDKv1CookiesV3.mpid);
5081
- // all other values are already encoded, so we have to encode any new values
5082
- parsedCookiesV4.gs.csm = Base64.encode(JSON.stringify(parsedCookiesV4.gs.csm));
5083
- migrateProductsFromSDKv1ToSDKv2CookiesV4(parsedSDKv1CookiesV3, parsedSDKv1CookiesV3.mpid);
5084
- }
5085
- return JSON.stringify(parsedCookiesV4);
5086
- };
5087
- function restructureToV4Cookie(cookies) {
5088
- try {
5089
- var cookiesV4Schema = {
5090
- gs: {
5091
- csm: []
5092
- }
5093
- };
5094
- cookies = JSON.parse(cookies);
5095
- for (var key in cookies) {
5096
- if (cookies.hasOwnProperty(key)) {
5097
- if (CookiesGlobalSettingsKeys[key]) {
5098
- cookiesV4Schema.gs[key] = cookies[key];
5099
- } else if (key === 'mpid') {
5100
- cookiesV4Schema.cu = cookies[key];
5101
- } else if (cookies.mpid) {
5102
- cookiesV4Schema[cookies.mpid] = cookiesV4Schema[cookies.mpid] || {};
5103
- if (MPIDKeys[key]) {
5104
- cookiesV4Schema[cookies.mpid][key] = cookies[key];
5105
- }
5106
- }
5107
- }
5108
- }
5109
- return JSON.stringify(cookiesV4Schema);
5110
- } catch (e) {
5111
- mpInstance.Logger.error('Failed to restructure previous cookie into most current cookie schema');
5112
- }
5113
- }
5114
- function migrateProductsToNameSpace() {
5115
- var lsProdV4Name = StorageNames.localStorageProductsV4;
5116
- var products = localStorage.getItem(StorageNames.localStorageProductsV4);
5117
- localStorage.setItem(mpInstance._Store.prodStorageName, products);
5118
- localStorage.removeItem(lsProdV4Name);
5119
- }
5120
- function migrateProductsFromSDKv1ToSDKv2CookiesV4(cookies, mpid) {
5121
- if (!mpInstance._Store.isLocalStorageAvailable) {
5122
- return;
5123
- }
5124
- var localStorageProducts = {};
5125
- localStorageProducts[mpid] = {};
5126
- if (cookies.cp) {
5127
- try {
5128
- localStorageProducts[mpid].cp = JSON.parse(Base64.decode(cookies.cp));
5129
- } catch (e) {
5130
- localStorageProducts[mpid].cp = cookies.cp;
5131
- }
5132
- if (!Array.isArray(localStorageProducts[mpid].cp)) {
5133
- localStorageProducts[mpid].cp = [];
5134
- }
5135
- }
5136
- localStorage.setItem(mpInstance._Store.prodStorageName, Base64.encode(JSON.stringify(localStorageProducts)));
5137
- }
5138
- function migrateLocalStorage() {
5139
- var cookies,
5140
- v3LSName = StorageNames.localStorageNameV3,
5141
- v4LSName = StorageNames.localStorageNameV4,
5142
- currentVersionLSData = window.localStorage.getItem(mpInstance._Store.storageName),
5143
- v4LSData,
5144
- v3LSData,
5145
- v3LSDataStringCopy;
5146
- if (currentVersionLSData) {
5147
- return;
5148
- }
5149
- v4LSData = window.localStorage.getItem(v4LSName);
5150
- if (v4LSData) {
5151
- finishLSMigration(v4LSData, v4LSName);
5152
- migrateProductsToNameSpace();
5153
- return;
5154
- }
5155
- v3LSData = window.localStorage.getItem(v3LSName);
5156
- if (v3LSData) {
5157
- mpInstance._Store.migratingToIDSyncCookies = true;
5158
- v3LSDataStringCopy = v3LSData.slice();
5159
- v3LSData = JSON.parse(mpInstance._Persistence.replacePipesWithCommas(mpInstance._Persistence.replaceApostrophesWithQuotes(v3LSData)));
5160
- // localStorage may contain only products, or the full persistence
5161
- // when there is an MPID on the cookie, it is the full persistence
5162
- if (v3LSData.mpid) {
5163
- v3LSData = JSON.parse(self.convertSDKv1CookiesV3ToSDKv2CookiesV4(v3LSDataStringCopy));
5164
- finishLSMigration(JSON.stringify(v3LSData), v3LSName);
5165
- return;
5166
- // if no MPID, it is only the products
5167
- } else if ((v3LSData.cp || v3LSData.pb) && !v3LSData.mpid) {
5168
- cookies = mpInstance._Persistence.getCookie();
5169
- if (cookies) {
5170
- migrateProductsFromSDKv1ToSDKv2CookiesV4(v3LSData, cookies.cu);
5171
- localStorage.removeItem(StorageNames.localStorageNameV3);
5172
- return;
5173
- } else {
5174
- localStorage.removeItem(StorageNames.localStorageNameV3);
5175
- return;
5176
- }
5177
- }
5178
- }
5179
- function finishLSMigration(data, lsName) {
5180
- try {
5181
- window.localStorage.setItem(encodeURIComponent(mpInstance._Store.storageName), data);
5182
- } catch (e) {
5183
- mpInstance.Logger.error('Error with setting localStorage item.');
5184
- }
5185
- window.localStorage.removeItem(encodeURIComponent(lsName));
5186
- }
5187
- }
5188
- }
5189
-
5190
5134
  function filteredMparticleUser(mpid, forwarder, mpInstance, kitBlocker) {
5191
5135
  var self = this;
5192
5136
  return {
@@ -6966,16 +6910,8 @@ var mParticle = (function () {
6966
6910
  }
6967
6911
  mpInstance._CookieSyncManager.attemptCookieSync(previousMPID, identityApiResult.mpid, mpidIsNotInCookies);
6968
6912
  self.checkIdentitySwap(previousMPID, identityApiResult.mpid, mpInstance._Store.currentSessionMPIDs);
6969
-
6970
- //if there is any previous migration data
6971
- if (Object.keys(mpInstance._Store.migrationData).length) {
6972
- newIdentitiesByType = mpInstance._Store.migrationData.userIdentities || {};
6973
- var userAttributes = mpInstance._Store.migrationData.userAttributes || {};
6974
- mpInstance._Persistence.saveUserAttributesToPersistence(identityApiResult.mpid, userAttributes);
6975
- } else {
6976
- if (identityApiData && identityApiData.userIdentities && Object.keys(identityApiData.userIdentities).length) {
6977
- newIdentitiesByType = self.IdentityRequest.combineUserIdentities(incomingMpidUIByName, identityApiData.userIdentities);
6978
- }
6913
+ if (identityApiData && identityApiData.userIdentities && Object.keys(identityApiData.userIdentities).length) {
6914
+ newIdentitiesByType = self.IdentityRequest.combineUserIdentities(incomingMpidUIByName, identityApiData.userIdentities);
6979
6915
  }
6980
6916
  mpInstance._Persistence.saveUserIdentitiesToPersistence(identityApiResult.mpid, newIdentitiesByType);
6981
6917
  mpInstance._Persistence.update();
@@ -7993,7 +7929,6 @@ var mParticle = (function () {
7993
7929
  // These classes are for internal use only. Not documented for public consumption
7994
7930
  this._instanceName = instanceName;
7995
7931
  this._NativeSdkHelpers = new NativeSdkHelpers(this);
7996
- this._Migrations = new Migrations(this);
7997
7932
  this._SessionManager = new SessionManager(this);
7998
7933
  this._Persistence = new _Persistence(this);
7999
7934
  this._Helpers = new Helpers(this);
@@ -8942,9 +8877,6 @@ var mParticle = (function () {
8942
8877
  mpInstance._Store.webviewBridgeEnabled = mpInstance._NativeSdkHelpers.isWebviewEnabled(mpInstance._Store.SDKConfig.requiredWebviewBridgeName, mpInstance._Store.SDKConfig.minWebviewBridgeVersion);
8943
8878
  mpInstance._Store.configurationLoaded = true;
8944
8879
  if (!mpInstance._Store.webviewBridgeEnabled) {
8945
- // Migrate any cookies from previous versions to current cookie version
8946
- mpInstance._Migrations.migrate();
8947
-
8948
8880
  // Load any settings/identities/attributes from cookie or localStorage
8949
8881
  mpInstance._Persistence.initializeStorage();
8950
8882
  }
@@ -8978,12 +8910,6 @@ var mParticle = (function () {
8978
8910
  userIdentities: modifiedUIforIdentityRequest
8979
8911
  };
8980
8912
  }
8981
-
8982
- // If migrating from pre-IDSync to IDSync, a sessionID will exist and an identify request will not have been fired, so we need this check
8983
- if (mpInstance._Store.migratingToIDSyncCookies) {
8984
- mpInstance.Identity.identify(mpInstance._Store.SDKConfig.identifyRequest, mpInstance._Store.SDKConfig.identityCallback);
8985
- mpInstance._Store.migratingToIDSyncCookies = false;
8986
- }
8987
8913
  currentUser = mpInstance.Identity.getCurrentUser();
8988
8914
  if (mpInstance._Helpers.getFeatureFlag(Constants.FeatureFlags.ReportBatching)) {
8989
8915
  mpInstance._ForwardingStatsUploader.startForwardingStatsTimer();
@@ -9098,7 +9024,9 @@ var mParticle = (function () {
9098
9024
  mpInstance._Store.devToken = apiKey || null;
9099
9025
  mpInstance.Logger.verbose(Messages.InformationMessages.StartingInitialization);
9100
9026
 
9101
- //check to see if localStorage is available for migrating purposes
9027
+ // Check to see if localStorage is available before main configuration runs
9028
+ // since we will need this for the current implementation of user persistence
9029
+ // TODO: Refactor this when we refactor User Identity Persistence
9102
9030
  try {
9103
9031
  mpInstance._Store.isLocalStorageAvailable = mpInstance._Persistence.determineLocalStorageAvailability(window.localStorage);
9104
9032
  } catch (e) {
@@ -9182,7 +9110,6 @@ var mParticle = (function () {
9182
9110
  consentState: null,
9183
9111
  clientId: null,
9184
9112
  deviceId: null,
9185
- migrationData: {},
9186
9113
  serverSettings: {},
9187
9114
  dateLastEventSent: null,
9188
9115
  sessionStartDate: null,
@@ -9196,7 +9123,6 @@ var mParticle = (function () {
9196
9123
  context: null,
9197
9124
  configurationLoaded: false,
9198
9125
  identityCallInFlight: false,
9199
- migratingToIDSyncCookies: false,
9200
9126
  nonCurrentUserMPIDs: {},
9201
9127
  identifyCalled: false,
9202
9128
  isLoggedIn: false,
@@ -9251,10 +9177,16 @@ var mParticle = (function () {
9251
9177
  upload: mockFunction
9252
9178
  };
9253
9179
  };
9254
- _BatchValidator.prototype.returnBatch = function (event) {
9180
+ _BatchValidator.prototype.createSDKEventFunction = function (event) {
9181
+ return new ServerModel(this.getMPInstance()).createEventObject(event);
9182
+ };
9183
+ _BatchValidator.prototype.returnBatch = function (events) {
9184
+ var _this = this;
9255
9185
  var mpInstance = this.getMPInstance();
9256
- var sdkEvent = new ServerModel(mpInstance).createEventObject(event);
9257
- var batch = convertEvents('0', [sdkEvent], mpInstance);
9186
+ var sdkEvents = Array.isArray(events) ? events.map(function (event) {
9187
+ return _this.createSDKEventFunction(event);
9188
+ }) : [this.createSDKEventFunction(events)];
9189
+ var batch = convertEvents('0', sdkEvents, mpInstance);
9258
9190
  return batch;
9259
9191
  };
9260
9192
  return _BatchValidator;