@mparticle/web-sdk 2.71.1 → 2.71.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.
@@ -15,7 +15,7 @@ map:function map(a,b){var c,d,e;if(null===this)throw new TypeError(" this is nul
15
15
  filter:function filter(a/*, thisArg*/){if(void 0===this||null===this)throw new TypeError;var b=Object(this),c=b.length>>>0;if("function"!=typeof a)throw new TypeError;for(var d=[],e=2<=arguments.length?arguments[1]:void 0,f=0;f<c;f++)if(f in b){var g=b[f];a.call(e,g,f,b)&&d.push(g);}return d},// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray
16
16
  isArray:function isArray(a){return "[object Array]"===Object.prototype.toString.call(a)},Base64:Base64$1};
17
17
 
18
- var version = "2.71.1";
18
+ var version = "2.71.2";
19
19
 
20
20
  var Constants={sdkVersion:version,sdkVendor:"mparticle",platform:"web",Messages:{DeprecationMessages:{MethodHasBeenDeprecated:"has been deprecated.",MethodMarkedForDeprecationPostfix:"is a deprecated method and will be removed in future releases.",AlternativeMethodPrefix:"Please use the alternate method:"},ErrorMessages:{NoToken:"A token must be specified.",EventNameInvalidType:"Event name must be a valid string value.",EventDataInvalidType:"Event data must be a valid object hash.",LoggingDisabled:"Event logging is currently disabled.",CookieParseError:"Could not parse cookie",EventEmpty:"Event object is null or undefined, cancelling send",APIRequestEmpty:"APIRequest is null or undefined, cancelling send",NoEventType:"Event type must be specified.",TransactionIdRequired:"Transaction ID is required",TransactionRequired:"A transaction attributes object is required",PromotionIdRequired:"Promotion ID is required",BadAttribute:"Attribute value cannot be object or array",BadKey:"Key value cannot be object or array",BadLogPurchase:"Transaction attributes and a product are both required to log a purchase, https://docs.mparticle.com/?javascript#measuring-transactions",AudienceAPINotEnabled:"Your workspace is not enabled to retrieve user audiences."},InformationMessages:{CookieSearch:"Searching for cookie",CookieFound:"Cookie found, parsing values",CookieNotFound:"Cookies not found",CookieSet:"Setting cookie",CookieSync:"Performing cookie sync",SendBegin:"Starting to send event",SendIdentityBegin:"Starting to send event to identity server",SendWindowsPhone:"Sending event to Windows Phone container",SendIOS:"Calling iOS path: ",SendAndroid:"Calling Android JS interface method: ",SendHttp:"Sending event to mParticle HTTP service",SendAliasHttp:"Sending alias request to mParticle HTTP service",SendIdentityHttp:"Sending event to mParticle HTTP service",StartingNewSession:"Starting new Session",StartingLogEvent:"Starting to log event",StartingLogOptOut:"Starting to log user opt in/out",StartingEndSession:"Starting to end session",StartingInitialization:"Starting to initialize",StartingLogCommerceEvent:"Starting to log commerce event",StartingAliasRequest:"Starting to Alias MPIDs",LoadingConfig:"Loading configuration options",AbandonLogEvent:"Cannot log event, logging disabled or developer token not set",AbandonAliasUsers:"Cannot Alias Users, logging disabled or developer token not set",AbandonStartSession:"Cannot start session, logging disabled or developer token not set",AbandonEndSession:"Cannot end session, logging disabled or developer token not set",NoSessionToEnd:"Cannot end session, no active session found"},ValidationMessages:{ModifyIdentityRequestUserIdentitiesPresent:"identityRequests to modify require userIdentities to be present. Request not sent to server. Please fix and try again",IdentityRequesetInvalidKey:"There is an invalid key on your identityRequest object. It can only contain a `userIdentities` object and a `onUserAlias` function. Request not sent to server. Please fix and try again.",OnUserAliasType:"The onUserAlias value must be a function.",UserIdentities:"The userIdentities key must be an object with keys of identityTypes and values of strings. Request not sent to server. Please fix and try again.",UserIdentitiesInvalidKey:"There is an invalid identity key on your `userIdentities` object within the identityRequest. Request not sent to server. Please fix and try again.",UserIdentitiesInvalidValues:"All user identity values must be strings or null. Request not sent to server. Please fix and try again.",AliasMissingMpid:"Alias Request must contain both a destinationMpid and a sourceMpid",AliasNonUniqueMpid:"Alias Request's destinationMpid and sourceMpid must be unique",AliasMissingTime:"Alias Request must have both a startTime and an endTime",AliasStartBeforeEndTime:"Alias Request's endTime must be later than its startTime"}},NativeSdkPaths:{LogEvent:"logEvent",SetUserTag:"setUserTag",RemoveUserTag:"removeUserTag",SetUserAttribute:"setUserAttribute",RemoveUserAttribute:"removeUserAttribute",SetSessionAttribute:"setSessionAttribute",AddToCart:"addToCart",RemoveFromCart:"removeFromCart",ClearCart:"clearCart",LogOut:"logOut",SetUserAttributeList:"setUserAttributeList",RemoveAllUserAttributes:"removeAllUserAttributes",GetUserAttributesLists:"getUserAttributesLists",GetAllUserAttributes:"getAllUserAttributes",Identify:"identify",Logout:"logout",Login:"login",Modify:"modify",Alias:"aliasUsers",Upload:"upload"},StorageNames:{localStorageName:"mprtcl-api",localStorageNameV3:"mprtcl-v3",cookieName:"mprtcl-api",cookieNameV2:"mprtcl-v2",cookieNameV3:"mprtcl-v3",localStorageNameV4:"mprtcl-v4",localStorageProductsV4:"mprtcl-prodv4",cookieNameV4:"mprtcl-v4",currentStorageName:"mprtcl-v4",currentStorageProductsName:"mprtcl-prodv4"},DefaultConfig:{cookieDomain:null,cookieExpiration:365,logLevel:null,timeout:300,sessionTimeout:30,maxProducts:20,forwarderStatsTimeout:5e3,integrationDelayTimeout:5e3,maxCookieSize:3e3,aliasMaxWindow:90,uploadInterval:0// Maximum milliseconds in between batch uploads, below 500 will mean immediate upload. The server returns this as a string, but we are using it as a number internally
21
21
  },DefaultBaseUrls:{v1SecureServiceUrl:"jssdks.mparticle.com/v1/JS/",v2SecureServiceUrl:"jssdks.mparticle.com/v2/JS/",v3SecureServiceUrl:"jssdks.mparticle.com/v3/JS/",configUrl:"jssdkcdns.mparticle.com/JS/v2/",identityUrl:"identity.mparticle.com/v1/",aliasUrl:"jssdks.mparticle.com/v1/identity/",userAudienceUrl:"nativesdks.mparticle.com/v1/"},// These are the paths that are used to construct the CNAME urls
@@ -452,7 +452,10 @@ return g=Object.assign(g,b),{event_type:dist.EventTypeEnum.applicationStateTrans
452
452
  //spanning_mpids: sdkEvent.SessionMpids
453
453
  };return c=Object.assign(c,b),{event_type:dist.EventTypeEnum.sessionEnd,data:c}}function convertSessionStartEvent(a){var b=convertBaseEventData(a),c={};return c=Object.assign(c,b),{event_type:dist.EventTypeEnum.sessionStart,data:c}}function convertPageViewEvent(a){var b=convertBaseEventData(a),c={custom_flags:a.CustomFlags,screen_name:a.EventName};return c=Object.assign(c,b),{event_type:dist.EventTypeEnum.screenView,data:c}}function convertOptOutEvent(a){var b=convertBaseEventData(a),c={is_opted_out:a.OptOut};return c=Object.assign(c,b),{event_type:dist.EventTypeEnum.optOut,data:c}}function convertCustomEvent(a){var b=convertBaseEventData(a),c={custom_event_type:convertSdkEventType(a.EventCategory),custom_flags:a.CustomFlags,event_name:a.EventName};return c=Object.assign(c,b),{event_type:dist.EventTypeEnum.customEvent,data:c}}function convertSdkEventType(a){return a===Types.EventType.Other?dist.CustomEventDataCustomEventTypeEnum.other:a===Types.EventType.Location?dist.CustomEventDataCustomEventTypeEnum.location:a===Types.EventType.Navigation?dist.CustomEventDataCustomEventTypeEnum.navigation:a===Types.EventType.Search?dist.CustomEventDataCustomEventTypeEnum.search:a===Types.EventType.Social?dist.CustomEventDataCustomEventTypeEnum.social:a===Types.EventType.Transaction?dist.CustomEventDataCustomEventTypeEnum.transaction:a===Types.EventType.UserContent?dist.CustomEventDataCustomEventTypeEnum.userContent:a===Types.EventType.UserPreference?dist.CustomEventDataCustomEventTypeEnum.userPreference:a===Types.EventType.Media?dist.CustomEventDataCustomEventTypeEnum.media:a===Types.CommerceEventType.ProductAddToCart?dist.CommerceEventDataCustomEventTypeEnum.addToCart:a===Types.CommerceEventType.ProductAddToWishlist?dist.CommerceEventDataCustomEventTypeEnum.addToWishlist:a===Types.CommerceEventType.ProductCheckout?dist.CommerceEventDataCustomEventTypeEnum.checkout:a===Types.CommerceEventType.ProductCheckoutOption?dist.CommerceEventDataCustomEventTypeEnum.checkoutOption:a===Types.CommerceEventType.ProductClick?dist.CommerceEventDataCustomEventTypeEnum.click:a===Types.CommerceEventType.ProductImpression?dist.CommerceEventDataCustomEventTypeEnum.impression:a===Types.CommerceEventType.ProductPurchase?dist.CommerceEventDataCustomEventTypeEnum.purchase:a===Types.CommerceEventType.ProductRefund?dist.CommerceEventDataCustomEventTypeEnum.refund:a===Types.CommerceEventType.ProductRemoveFromCart?dist.CommerceEventDataCustomEventTypeEnum.removeFromCart:a===Types.CommerceEventType.ProductRemoveFromWishlist?dist.CommerceEventDataCustomEventTypeEnum.removeFromWishlist:a===Types.CommerceEventType.ProductViewDetail?dist.CommerceEventDataCustomEventTypeEnum.viewDetail:a===Types.CommerceEventType.PromotionClick?dist.CommerceEventDataCustomEventTypeEnum.promotionClick:a===Types.CommerceEventType.PromotionView?dist.CommerceEventDataCustomEventTypeEnum.promotionView:dist.CustomEventDataCustomEventTypeEnum.unknown}function convertBaseEventData(a){var b={timestamp_unixtime_ms:a.Timestamp,session_uuid:a.SessionId,session_start_unixtime_ms:a.SessionStartDate,custom_attributes:a.EventAttributes,location:convertSDKLocation(a.Location),source_message_id:a.SourceMessageId,active_time_on_site_ms:a.ActiveTimeOnSite,page_url:a.PageUrl};return b}function convertSDKLocation(a){return a&&Object.keys(a).length?{latitude:a.lat,longitude:a.lng}:null}function convertUserAttributeChangeEvent(a){var b=convertBaseEventData(a),c={user_attribute_name:a.UserAttributeChanges.UserAttributeName,new:a.UserAttributeChanges.New,old:a.UserAttributeChanges.Old,deleted:a.UserAttributeChanges.Deleted,is_new_attribute:a.UserAttributeChanges.IsNewAttribute};return c=__assign(__assign({},c),b),{event_type:dist.EventTypeEnum.userAttributeChange,data:c}}function convertUserIdentityChangeEvent(a){var b=convertBaseEventData(a),c={new:{identity_type:convertUserIdentityTypeToServerIdentityType(a.UserIdentityChanges.New.IdentityType),identity:a.UserIdentityChanges.New.Identity||null,timestamp_unixtime_ms:a.Timestamp,created_this_batch:a.UserIdentityChanges.New.CreatedThisBatch},old:{identity_type:convertUserIdentityTypeToServerIdentityType(a.UserIdentityChanges.Old.IdentityType),identity:a.UserIdentityChanges.Old.Identity||null,timestamp_unixtime_ms:a.Timestamp,created_this_batch:a.UserIdentityChanges.Old.CreatedThisBatch}};return c=Object.assign(c,b),{event_type:dist.EventTypeEnum.userIdentityChange,data:c}}function convertUserIdentityTypeToServerIdentityType(a){return a===SDKIdentityTypeEnum.other?dist.IdentityTypeEnum.other:a===SDKIdentityTypeEnum.customerId?dist.IdentityTypeEnum.customerId:a===SDKIdentityTypeEnum.facebook?dist.IdentityTypeEnum.facebook:a===SDKIdentityTypeEnum.twitter?dist.IdentityTypeEnum.twitter:a===SDKIdentityTypeEnum.google?dist.IdentityTypeEnum.google:a===SDKIdentityTypeEnum.microsoft?dist.IdentityTypeEnum.microsoft:a===SDKIdentityTypeEnum.yahoo?dist.IdentityTypeEnum.yahoo:a===SDKIdentityTypeEnum.email?dist.IdentityTypeEnum.email:a===SDKIdentityTypeEnum.alias?dist.IdentityTypeEnum.alias:a===SDKIdentityTypeEnum.facebookCustomAudienceId?dist.IdentityTypeEnum.facebookCustomAudienceId:a===SDKIdentityTypeEnum.otherId2?dist.IdentityTypeEnum.otherId2:a===SDKIdentityTypeEnum.otherId3?dist.IdentityTypeEnum.otherId3:a===SDKIdentityTypeEnum.otherId4?dist.IdentityTypeEnum.otherId4:a===SDKIdentityTypeEnum.otherId5?dist.IdentityTypeEnum.otherId5:a===SDKIdentityTypeEnum.otherId6?dist.IdentityTypeEnum.otherId6:a===SDKIdentityTypeEnum.otherId7?dist.IdentityTypeEnum.otherId7:a===SDKIdentityTypeEnum.otherId8?dist.IdentityTypeEnum.otherId8:a===SDKIdentityTypeEnum.otherId9?dist.IdentityTypeEnum.otherId9:a===SDKIdentityTypeEnum.otherId10?dist.IdentityTypeEnum.otherId10:a===SDKIdentityTypeEnum.mobileNumber?dist.IdentityTypeEnum.mobileNumber:a===SDKIdentityTypeEnum.phoneNumber2?dist.IdentityTypeEnum.phoneNumber2:a===SDKIdentityTypeEnum.phoneNumber3?dist.IdentityTypeEnum.phoneNumber3:void 0}
454
454
 
455
- var BaseVault=/** @class */function(){/**
455
+ // `Unavailable` covers storage being blocked/disabled (e.g. SecurityError),
456
+ // where retrying with a smaller payload cannot succeed.
457
+ var StorageResult;(function(a){a.Success="Success",a.QuotaExceeded="QuotaExceeded",a.Unavailable="Unavailable";})(StorageResult||(StorageResult={}));var isQuotaExceededError=function(a){return a instanceof DOMException&&(// Standard quota errors, plus Firefox's legacy name/code.
458
+ 22===a.code||1014===a.code||"QuotaExceededError"===a.name||"NS_ERROR_DOM_QUOTA_REACHED"===a.name)},BaseVault=/** @class */function(){/**
456
459
  *
457
460
  * @param {string} storageKey the local storage key string
458
461
  * @param {Storage} storageObject Web API Storage object that is being used
@@ -460,9 +463,9 @@ var BaseVault=/** @class */function(){/**
460
463
  * Stores a StorableItem to Storage
461
464
  * @method store
462
465
  * @param item {StorableItem}
463
- */return a.prototype.store=function(a){var b;this.contents=a,b=isNumber(a)||!isEmpty(a)?JSON.stringify(a):"",this.storageObject.setItem(this._storageKey,b);},a.prototype.retrieve=function(){// TODO: Handle cases where Local Storage is unavailable
464
- // https://go.mparticle.com/work/SQDSDKS-5022
465
- var a=this.storageObject.getItem(this._storageKey);return this.contents=a?JSON.parse(a):null,this.contents},a.prototype.purge=function(){this.contents=null,this.storageObject.removeItem(this._storageKey);},a}();var LocalStorageVault=/** @class */function(a){function b(b){return a.call(this,b,window.localStorage)||this}return __extends(b,a),b}(BaseVault);var SessionStorageVault=/** @class */function(a){function b(b){return a.call(this,b,window.sessionStorage)||this}return __extends(b,a),b}(BaseVault);var DisabledVault=/** @class */function(a){function b(b){var c=a.call(this,b,window.localStorage)||this;return c.contents=null,c.storageObject.removeItem(c._storageKey),c}return __extends(b,a),b.prototype.store=function(){this.contents=null;},b.prototype.retrieve=function(){return this.contents},b.prototype.purge=function(){this.contents=null;},b}(BaseVault);
466
+ */return a.prototype.store=function(a){var b;try{return b=isNumber(a)||!isEmpty(a)?JSON.stringify(a):"",this.storageObject.setItem(this._storageKey,b),this.contents=a,StorageResult.Success}catch(a){return isQuotaExceededError(a)?StorageResult.QuotaExceeded:StorageResult.Unavailable}},a.prototype.retrieve=function(){// https://go.mparticle.com/work/SQDSDKS-5022
467
+ try{var a=this.storageObject.getItem(this._storageKey);this.contents=a?JSON.parse(a):null;}catch(a){this.contents=null;}return this.contents},a.prototype.purge=function(){this.contents=null;try{this.storageObject.removeItem(this._storageKey);}catch(a){// Storage persistence is best effort.
468
+ }},a}();var LocalStorageVault=/** @class */function(a){function b(b){return a.call(this,b,window.localStorage)||this}return __extends(b,a),b}(BaseVault);var SessionStorageVault=/** @class */function(a){function b(b){return a.call(this,b,window.sessionStorage)||this}return __extends(b,a),b}(BaseVault);var DisabledVault=/** @class */function(a){function b(b){var c=a.call(this,b,window.localStorage)||this;return c.contents=null,c.storageObject.removeItem(c._storageKey),c}return __extends(b,a),b.prototype.store=function(){return this.contents=null,StorageResult.Success},b.prototype.retrieve=function(){return this.contents},b.prototype.purge=function(){this.contents=null;},b}(BaseVault);
466
469
 
467
470
  var AsyncUploader=/** @class */function(){function a(a){this.url=a;}return a}();var FetchUploader=/** @class */function(a){function b(){return null!==a&&a.apply(this,arguments)||this}return __extends(b,a),b.prototype.upload=function(a,b){return __awaiter(this,void 0,void 0,function(){var c;return __generator(this,function(d){switch(d.label){case 0:return c=b||this.url,[4/*yield*/,fetch(c,a)];case 1:return [2/*return*/,d.sent()]}})})},b}(AsyncUploader);var XHRUploader=/** @class */function(a){function b(){return null!==a&&a.apply(this,arguments)||this}return __extends(b,a),b.prototype.upload=function(a){return __awaiter(this,void 0,void 0,function(){var b;return __generator(this,function(c){switch(c.label){case 0:return [4/*yield*/,this.makeRequest(this.url,a.body,a.method,a.headers)];case 1:return b=c.sent(),[2/*return*/,b]}})})},b.prototype.makeRequest=function(a,b,c,d){return void 0===c&&(c="post"),void 0===d&&(d={}),__awaiter(this,void 0,void 0,function(){var e;return __generator(this,function(){return e=new XMLHttpRequest,[2/*return*/,new Promise(function(f,g){for(var h in e.onreadystatechange=function(){4!==e.readyState||// Process the response
468
471
  // We resolve all xhr responses whose ready state is 4 regardless of HTTP codes that may be errors (400+)
@@ -491,8 +494,8 @@ function appendUserInfo(a,b){if(b){if(!a)return b.MPID=null,b.ConsentState=null,
491
494
  * Creates an instance of a BatchUploader
492
495
  * @param {IMParticleWebSDKInstance} mpInstance - the mParticle SDK instance
493
496
  * @param {number} uploadInterval - the desired upload interval in milliseconds
494
- */function a(b,c){var d,e;this.offlineStorageEnabled=!1,this.lastASTEventTime=0,this.AST_DEBOUNCE_MS=1e3,this.uploadIntervalTimerId=null,this.exitHandler=null,this.visibilityChangeHandler=null,this.destroyed=!1,this.mpInstance=b,this.uploadIntervalMillis=c,this.batchingEnabled=c>=a.MINIMUM_INTERVAL_MILLIS,this.uploadIntervalMillis<a.MINIMUM_INTERVAL_MILLIS&&(this.uploadIntervalMillis=a.MINIMUM_INTERVAL_MILLIS),this.eventsQueuedForProcessing=[],this.batchesQueuedForProcessing=[],this.offlineStorageEnabled=this.isOfflineStorageAvailable();// When noFunctional is true, prevent events/batches storage
495
- var f=null===(e=b._CookieConsentManager)||void 0===e?void 0:e.getNoFunctional();this.offlineStorageEnabled&&!f&&(this.eventVault=new SessionStorageVault("".concat(b._Store.storageName,"-events")),this.batchVault=new LocalStorageVault("".concat(b._Store.storageName,"-batches")),(d=this.eventsQueuedForProcessing).push.apply(d,this.eventVault.retrieve()));var g=this.mpInstance._Store,h=g.SDKConfig,i=g.devToken,j=this.mpInstance._Helpers.createServiceUrl(h.v3SecureServiceUrl,i);this.uploadUrl="".concat(j,"/events"),this.uploader=window.fetch?new FetchUploader(this.uploadUrl):new XHRUploader(this.uploadUrl),this.triggerUploadInterval(!0,!1),this.addEventListeners();}/**
497
+ */function a(b,c){var d,e,f;this.offlineStorageEnabled=!1,this.lastASTEventTime=0,this.AST_DEBOUNCE_MS=1e3,this.uploadIntervalTimerId=null,this.exitHandler=null,this.visibilityChangeHandler=null,this.destroyed=!1,this.mpInstance=b,this.uploadIntervalMillis=c,this.batchingEnabled=c>=a.MINIMUM_INTERVAL_MILLIS,this.uploadIntervalMillis<a.MINIMUM_INTERVAL_MILLIS&&(this.uploadIntervalMillis=a.MINIMUM_INTERVAL_MILLIS),this.eventsQueuedForProcessing=[],this.batchesQueuedForProcessing=[],this.offlineStorageEnabled=this.isOfflineStorageAvailable();// When noFunctional is true, prevent events/batches storage
498
+ var g=null===(e=b._CookieConsentManager)||void 0===e?void 0:e.getNoFunctional();this.offlineStorageEnabled&&!g&&(this.eventVault=new SessionStorageVault("".concat(b._Store.storageName,"-events")),this.batchVault=new LocalStorageVault("".concat(b._Store.storageName,"-batches")),(d=this.eventsQueuedForProcessing).push.apply(d,null!==(f=this.eventVault.retrieve())&&void 0!==f?f:[]));var h=this.mpInstance._Store,i=h.SDKConfig,j=h.devToken,k=this.mpInstance._Helpers.createServiceUrl(i.v3SecureServiceUrl,j);this.uploadUrl="".concat(k,"/events"),this.uploader=window.fetch?new FetchUploader(this.uploadUrl):new XHRUploader(this.uploadUrl),this.triggerUploadInterval(!0,!1),this.addEventListeners();}/**
496
499
  * Cleans up timers and event listeners to prevent leaks when the SDK
497
500
  * is re-initialized (e.g. between tests or on repeated init calls).
498
501
  */return a.prototype.destroy=function(){this.destroyed=!0,null!==this.uploadIntervalTimerId&&(clearTimeout(this.uploadIntervalTimerId),this.uploadIntervalTimerId=null),this.visibilityChangeHandler&&document.removeEventListener("visibilitychange",this.visibilityChangeHandler),this.exitHandler&&(window.removeEventListener("beforeunload",this.exitHandler),window.removeEventListener("pagehide",this.exitHandler)),this.exitHandler=null,this.visibilityChangeHandler=null;},a.prototype.isOfflineStorageAvailable=function(){var a=this.mpInstance,b=a._Helpers.getFeatureFlag,c=a._Store.deviceId,d=b(Constants.FeatureFlags.OfflineStorage),e=parseInt(d,10),f=getRampNumber(c);// https://go.mparticle.com/work/SQDSDKS-6317
@@ -505,7 +508,13 @@ var c=a.mpInstance._Helpers.getFeatureFlag,d=Constants.FeatureFlags.AstBackgroun
505
508
  var e=b.createBackgroundASTEvent();b.queueEvent(e);}// Then trigger the upload with beacon
506
509
  b.prepareAndUpload(!1,b.isBeaconAvailable());};this.exitHandler=c,this.visibilityChangeHandler=function(){"hidden"===document.visibilityState&&c();},document.addEventListener("visibilitychange",this.visibilityChangeHandler),window.addEventListener("beforeunload",c),window.addEventListener("pagehide",c);},a.prototype.isBeaconAvailable=function(){return !!navigator.sendBeacon},a.prototype.triggerUploadInterval=function(a,b){var c=this;void 0===a&&(a=!1),void 0===b&&(b=!1),this.uploadIntervalTimerId=setTimeout(function(){c.prepareAndUpload(a,b);},this.uploadIntervalMillis);},a.prototype.queueEvent=function(a){if(!isEmpty(a)){if(this.eventsQueuedForProcessing.push(a),this.offlineStorageEnabled&&this.eventVault&&this.eventVault.store(this.eventsQueuedForProcessing),this.mpInstance.Logger.isVerbose()){var b=obfuscateDevData(a,this.mpInstance._Store.SDKConfig.isDevelopmentMode);this.mpInstance.Logger.verbose("Queuing event: ".concat(JSON.stringify(b))),this.mpInstance.Logger.verbose("Queued event count: ".concat(this.eventsQueuedForProcessing.length));}this.shouldTriggerImmediateUpload(a.EventDataType)&&this.prepareAndUpload(!1,!1);}},a.prototype.shouldTriggerImmediateUpload=function(a){var b=[MessageType$1.Commerce,MessageType$1.UserIdentityChange];return !this.batchingEnabled||b.includes(a)},(a.createNewBatches=function(a,b,c){if(!b||!a||!a.length)return null;//bucket by MPID, and then by session, ordered by timestamp
507
510
  for(var d,e=[],f=new Map,g=0,h=a;g<h.length;g++){//on initial startup, there may be events logged without an mpid.
508
- if(d=h[g],!d.MPID){var i=b.getMPID();d.MPID=i;}var j=f.get(d.MPID);j||(j=[]),j.push(d),f.set(d.MPID,j);}for(var k=0,l=Array.from(f.entries());k<l.length;k++){for(var m=l[k],i=m[0],n=m[1],o=new Map,p=0,q=n;p<q.length;p++){var d=q[p],j=o.get(d.SessionId);j||(j=[]),j.push(d),o.set(d.SessionId,j);}for(var r=0,s=Array.from(o.entries());r<s.length;r++){var t=s[r],u=convertEvents(i,t[1],c),v=c._Store.SDKConfig.onCreateBatch;v&&(u=v(u),u?u.modified=!0:c.Logger.warning("Skiping batch upload because no batch was returned from onCreateBatch callback")),u&&e.push(u);}}return e},a.prototype.prepareAndUpload=function(b,c){return void 0===b&&(b=!1),void 0===c&&(c=!1),__awaiter(this,void 0,void 0,function(){var d,e,f,g,h,i,j,k;return __generator(this,function(l){switch(l.label){case 0:return d=this.mpInstance.Identity.getCurrentUser(),e=this.eventsQueuedForProcessing,this.eventsQueuedForProcessing=[],this.offlineStorageEnabled&&this.eventVault&&this.eventVault.store([]),f=[],isEmpty(e)||(f=a.createNewBatches(e,d,this.mpInstance)),this.offlineStorageEnabled&&this.batchVault&&((i=this.batchesQueuedForProcessing).unshift.apply(i,this.batchVault.retrieve()),this.batchVault.purge()),isEmpty(f)||(j=this.batchesQueuedForProcessing).push.apply(j,f),g=this.batchesQueuedForProcessing,this.batchesQueuedForProcessing=[],[4/*yield*/,this.uploadBatches(g,c)];case 1:return h=l.sent(),isEmpty(h)||(k=this.batchesQueuedForProcessing).unshift.apply(k,h),!c&&this.offlineStorageEnabled&&this.batchVault&&(this.batchVault.store(this.batchesQueuedForProcessing),this.batchesQueuedForProcessing=[]),b&&!this.destroyed&&this.triggerUploadInterval(b,!1),[2/*return*/]}})})},a.prototype.uploadBatches=function(b,c){return __awaiter(this,void 0,void 0,function(){var d,e,f,g,h,j,k;return __generator(this,function(i){switch(i.label){case 0:if(d=b.filter(function(a){return !isEmpty(a.events)}),isEmpty(d))return [2/*return*/,null];this.mpInstance.Logger.isVerbose()&&(e=obfuscateDevData(d,this.mpInstance._Store.SDKConfig.isDevelopmentMode),this.mpInstance.Logger.verbose("Uploading batches: ".concat(JSON.stringify(e))),this.mpInstance.Logger.verbose("Batch count: ".concat(d.length))),f=0,i.label=1;case 1:return f<d.length?(g={method:"POST",headers:{Accept:a.CONTENT_TYPE,"Content-Type":"text/plain;charset=UTF-8"},body:JSON.stringify(d[f])},!(c&&this.isBeaconAvailable()))?[3/*break*/,2]:(h=new Blob([g.body],{type:"text/plain;charset=UTF-8"}),navigator.sendBeacon(this.uploadUrl,h),[3/*break*/,5]):[3/*break*/,6];case 2:return i.trys.push([2,4,,5]),[4/*yield*/,this.uploader.upload(g)];case 3:if(j=i.sent(),200<=j.status&&300>j.status)this.mpInstance.Logger.verbose("Upload success for request ID: ".concat(d[f].source_request_id));else {if(500<=j.status||429===j.status)// Server error, add back current batches and try again later
511
+ if(d=h[g],!d.MPID){var i=b.getMPID();d.MPID=i;}var j=f.get(d.MPID);j||(j=[]),j.push(d),f.set(d.MPID,j);}for(var k=0,l=Array.from(f.entries());k<l.length;k++){for(var m=l[k],i=m[0],n=m[1],o=new Map,p=0,q=n;p<q.length;p++){var d=q[p],j=o.get(d.SessionId);j||(j=[]),j.push(d),o.set(d.SessionId,j);}for(var r=0,s=Array.from(o.entries());r<s.length;r++){var t=s[r],u=convertEvents(i,t[1],c),v=c._Store.SDKConfig.onCreateBatch;v&&(u=v(u),u?u.modified=!0:c.Logger.warning("Skiping batch upload because no batch was returned from onCreateBatch callback")),u&&e.push(u);}}return e},a.prototype.prepareAndUpload=function(b,c){var d;return void 0===b&&(b=!1),void 0===c&&(c=!1),__awaiter(this,void 0,void 0,function(){var e,f,g,h,i,j,k,l;return __generator(this,function(m){switch(m.label){case 0:return e=this.mpInstance.Identity.getCurrentUser(),f=this.eventsQueuedForProcessing,this.eventsQueuedForProcessing=[],this.offlineStorageEnabled&&this.eventVault&&this.eventVault.store([]),g=[],isEmpty(f)||(g=a.createNewBatches(f,e,this.mpInstance)),this.offlineStorageEnabled&&this.batchVault&&((j=this.batchesQueuedForProcessing).unshift.apply(j,null!==(d=this.batchVault.retrieve())&&void 0!==d?d:[]),this.batchVault.purge()),isEmpty(g)||(k=this.batchesQueuedForProcessing).push.apply(k,g),h=this.batchesQueuedForProcessing,this.batchesQueuedForProcessing=[],[4/*yield*/,this.uploadBatches(h,c)];case 1:return i=m.sent(),isEmpty(i)||(l=this.batchesQueuedForProcessing).unshift.apply(l,i),!c&&this.offlineStorageEnabled&&this.batchVault&&this.storeBatchesQueuedForProcessing(),b&&!this.destroyed&&this.triggerUploadInterval(b,!1),[2/*return*/]}})})},a.prototype.storeBatchesQueuedForProcessing=function(){var a=this.batchesQueuedForProcessing;// Nothing to persist: reset offline storage to an empty state.
512
+ if(isEmpty(a))return this.batchVault.store([]),void(this.batchesQueuedForProcessing=[]);// Drop oldest batches until storage accepts the payload. Only quota
513
+ // failures are recoverable by trimming; if storage is unavailable,
514
+ // dropping batches won't help, so retain them in memory.
515
+ for(var b,c=0;c<a.length;c++){if(b=this.batchVault.store(a.slice(c)),b===StorageResult.Success)return this.logDroppedOfflineBatches(c),void(this.batchesQueuedForProcessing=[]);if(b===StorageResult.Unavailable)return void this.mpInstance.Logger.warning("Offline batch storage is unavailable. Retaining batches in memory.")}// Every attempt stayed over quota, even down to the newest batch.
516
+ // Retain them in memory rather than dropping everything.
517
+ this.mpInstance.Logger.warning("Offline batch storage is over quota. Retaining batches in memory.");},a.prototype.logDroppedOfflineBatches=function(a){0<a&&this.mpInstance.Logger.warning("Offline batch storage is over quota. Dropped "+"".concat(a," oldest batch(es)."));},a.prototype.uploadBatches=function(b,c){return __awaiter(this,void 0,void 0,function(){var d,e,f,g,h,j,k;return __generator(this,function(i){switch(i.label){case 0:if(d=b.filter(function(a){return !isEmpty(a.events)}),isEmpty(d))return [2/*return*/,null];this.mpInstance.Logger.isVerbose()&&(e=obfuscateDevData(d,this.mpInstance._Store.SDKConfig.isDevelopmentMode),this.mpInstance.Logger.verbose("Uploading batches: ".concat(JSON.stringify(e))),this.mpInstance.Logger.verbose("Batch count: ".concat(d.length))),f=0,i.label=1;case 1:return f<d.length?(g={method:"POST",headers:{Accept:a.CONTENT_TYPE,"Content-Type":"text/plain;charset=UTF-8"},body:JSON.stringify(d[f])},!(c&&this.isBeaconAvailable()))?[3/*break*/,2]:(h=new Blob([g.body],{type:"text/plain;charset=UTF-8"}),navigator.sendBeacon(this.uploadUrl,h),[3/*break*/,5]):[3/*break*/,6];case 2:return i.trys.push([2,4,,5]),[4/*yield*/,this.uploader.upload(g)];case 3:if(j=i.sent(),200<=j.status&&300>j.status)this.mpInstance.Logger.verbose("Upload success for request ID: ".concat(d[f].source_request_id));else {if(500<=j.status||429===j.status)// Server error, add back current batches and try again later
509
518
  return this.mpInstance.Logger.error("HTTP error status ".concat(j.status," received")),[2/*return*/,d.slice(f,d.length)];if(401<=j.status)//if we're getting a 401, assume we'll keep getting a 401 and clear the uploads.
510
519
  return this.mpInstance.Logger.error("HTTP error status ".concat(j.status," while uploading - please verify your API key.")),[2/*return*/,null];throw console.error("HTTP error status ".concat(j.status," while uploading events."),j),new Error("Uncaught HTTP Error ".concat(j.status,". Batch upload will be re-attempted."))}return [3/*break*/,5];case 4:return k=i.sent(),this.mpInstance.Logger.error("Error sending event to mParticle servers. ".concat(k)),[2/*return*/,d.slice(f,d.length)];case 5:return f++,[3/*break*/,1];case 6:return [2/*return*/,null]}})})},a.CONTENT_TYPE="text/plain;charset=UTF-8",a.MINIMUM_INTERVAL_MILLIS=500,a)}();
511
520
 
@@ -759,7 +768,7 @@ if(Object.keys(k).length)for(var m in k)g=d(b,c,e),g.length>f&&k.hasOwnProperty(
759
768
  for(var n,o=0;o<h.length&&(g=d(b,c,e),g.length>f);o++)n=h[o],b[n]?(a.Logger.verbose("Size of new encoded cookie is larger than maxCookieSize setting of "+f+". Removing from cookie the earliest logged in MPID containing: "+JSON.stringify(b[n],0,2)),delete b[n]):a.Logger.error("Unable to save MPID data to cookies because the resulting encoded cookie is larger than the maxCookieSize setting of "+f+". We recommend using a maxCookieSize of 1500.");}return g},this.findPrevCookiesBasedOnUI=function(b){var c,d=a._Persistence.getPersistence();if(b)for(var e in b.userIdentities)if(d&&Object.keys(d).length)for(var g in d)// any value in persistence that has an MPID key will be an MPID to search through
760
769
  // other keys on the cookie are currentSessionMPIDs and currentMPID which should not be searched
761
770
  if(d[g].mpid){var h=d[g].ui;for(var i in h)if(e===i&&b.userIdentities[e]===h[i]){c=g;break}}c&&f.storeDataInMemory(d,c);},this.encodePersistence=function(b){for(var c in b=JSON.parse(b),b.gs)b.gs.hasOwnProperty(c)&&(Base64CookieKeys[c]?b.gs[c]?Array.isArray(b.gs[c])&&b.gs[c].length||a._Helpers.isObject(b.gs[c])&&Object.keys(b.gs[c]).length?b.gs[c]=Base64.encode(JSON.stringify(b.gs[c])):delete b.gs[c]:delete b.gs[c]:"ie"===c?b.gs[c]=b.gs[c]?1:0:!b.gs[c]&&delete b.gs[c]);for(var d in b)if(b.hasOwnProperty(d)&&!SDKv2NonMPIDCookieKeys[d])for(c in b[d])b[d].hasOwnProperty(c)&&Base64CookieKeys[c]&&(a._Helpers.isObject(b[d][c])&&Object.keys(b[d][c]).length?b[d][c]=Base64.encode(JSON.stringify(b[d][c])):delete b[d][c]);return createCookieString(JSON.stringify(b))},this.decodePersistence=function(b){try{if(b){if(b=JSON.parse(revertCookieString(b)),a._Helpers.isObject(b)&&Object.keys(b).length){for(var c in b.gs)b.gs.hasOwnProperty(c)&&(Base64CookieKeys[c]?b.gs[c]=JSON.parse(Base64.decode(b.gs[c])):"ie"===c&&(b.gs[c]=!!b.gs[c]));for(var d in b)if(b.hasOwnProperty(d))if(!SDKv2NonMPIDCookieKeys[d])for(c in b[d])b[d].hasOwnProperty(c)&&Base64CookieKeys[c]&&b[d][c].length&&(b[d][c]=JSON.parse(Base64.decode(b[d][c])));else "l"===d&&(b[d]=!!b[d]);}return JSON.stringify(b)}}catch(b){a.Logger.error("Problem with decoding cookie",b);}},this.getCookieDomain=function(){if(a._Store.SDKConfig.cookieDomain)return a._Store.SDKConfig.cookieDomain;var b=f.getDomain(document,location.hostname);return ""===b?"":"."+b},this.getDomain=function(a,b){var c,d,e=b.split(".");for(c=e.length-1;0<=c;c--)if(d=e.slice(c).join("."),a.cookie="mptest=cookie;domain=."+d+";",-1<a.cookie.indexOf("mptest=cookie"))return a.cookie="mptest=;domain=."+d+";expires=Thu, 01 Jan 1970 00:00:01 GMT;",d;return ""},this.saveUserCookieSyncDatesToPersistence=function(a,b){if(b){var c=f.getPersistence();c&&(c[a]?c[a].csd=b:c[a]={csd:b}),f.savePersistence(c);}},this.swapCurrentUser=function(a,b,c){if(a&&b&&a!==b){var d=f.getPersistence();d&&(d.cu=b,d.gs.csm=c,f.savePersistence(d));}},this.savePersistence=function(b){var c;// Block mprtcl-v4 persistence when noFunctional is true
762
- if(!(null!==(c=a._CookieConsentManager)&&void 0!==c&&c.getNoFunctional())){var d,e=f.encodePersistence(JSON.stringify(b)),g=new Date,h=a._Store.storageName,i=new Date(g.getTime()+1e3*(60*(60*(24*a._Store.SDKConfig.cookieExpiration)))).toGMTString(),j=f.getCookieDomain();if(d=""===j?"":";domain="+j,a._Store.SDKConfig.useCookieStorage){var k=f.reduceAndEncodePersistence(b,i,d,a._Store.SDKConfig.maxCookieSize);window.document.cookie=encodeURIComponent(h)+"="+k;}else a._Store.isLocalStorageAvailable&&localStorage.setItem(a._Store.storageName,e);}},this.getPersistence=function(){var a=this.useLocalStorage()?this.getLocalStorage():this.getCookie();return a},this.getFirstSeenTime=function(a){if(!a)return null;var b=f.getPersistence();return b&&b[a]&&b[a].fst?b[a].fst:null},this.setFirstSeenTime=function(a,b){if(a){b||(b=new Date().getTime());var c=f.getPersistence();c&&(!c[a]&&(c[a]={}),!c[a].fst&&(c[a].fst=b,f.savePersistence(c)));}// https://go.mparticle.com/work/SQDSDKS-6329
771
+ if(!(null!==(c=a._CookieConsentManager)&&void 0!==c&&c.getNoFunctional())){var d,e=f.encodePersistence(JSON.stringify(b)),g=new Date,h=a._Store.storageName,i=new Date(g.getTime()+1e3*(60*(60*(24*a._Store.SDKConfig.cookieExpiration)))).toGMTString(),j=f.getCookieDomain();if(d=""===j?"":";domain="+j,a._Store.SDKConfig.useCookieStorage){var k=f.reduceAndEncodePersistence(b,i,d,a._Store.SDKConfig.maxCookieSize);window.document.cookie=encodeURIComponent(h)+"="+k;}else if(a._Store.isLocalStorageAvailable)try{localStorage.setItem(a._Store.storageName,e);}catch(b){a.Logger.error("Error saving persistence to localStorage.");}}},this.getPersistence=function(){var a=this.useLocalStorage()?this.getLocalStorage():this.getCookie();return a},this.getFirstSeenTime=function(a){if(!a)return null;var b=f.getPersistence();return b&&b[a]&&b[a].fst?b[a].fst:null},this.setFirstSeenTime=function(a,b){if(a){b||(b=new Date().getTime());var c=f.getPersistence();c&&(!c[a]&&(c[a]={}),!c[a].fst&&(c[a].fst=b,f.savePersistence(c)));}// https://go.mparticle.com/work/SQDSDKS-6329
763
772
  },this.getLastSeenTime=function(b){if(!b)return null;if(b===a.Identity.getCurrentUser().getMPID())//if the mpid is the current user, its last seen time is the current time
764
773
  return new Date().getTime();var c=f.getPersistence();return c&&c[b]&&c[b].lst?c[b].lst:null},this.setLastSeenTime=function(a,b){if(a){b||(b=new Date().getTime());var c=f.getPersistence();c&&c[a]&&(c[a].lst=b,f.savePersistence(c));}// https://go.mparticle.com/work/SQDSDKS-6329
765
774
  },this.getDeviceId=function(){return a._Store.deviceId},this.setDeviceId=function(b){a._Store.deviceId=b,f.update();},this.resetPersistence=function(){if(localStorage.clear(),f.expireCookies(StorageNames.cookieName),f.expireCookies(StorageNames.cookieNameV2),f.expireCookies(StorageNames.cookieNameV3),f.expireCookies(StorageNames.cookieNameV4),f.expireCookies(a._Store.storageName),mParticle._isTestEnv){c(a._Helpers.createMainStorageName("abcdef")),f.expireCookies(a._Helpers.createMainStorageName("abcdef"));}},this.forwardingStatsBatches={uploadsTable:{},forwardingStatsEventQueue:[]};}
@@ -15,7 +15,7 @@ map:function map(a,b){var c,d,e;if(null===this)throw new TypeError(" this is nul
15
15
  filter:function filter(a/*, thisArg*/){if(void 0===this||null===this)throw new TypeError;var b=Object(this),c=b.length>>>0;if("function"!=typeof a)throw new TypeError;for(var d=[],e=2<=arguments.length?arguments[1]:void 0,f=0;f<c;f++)if(f in b){var g=b[f];a.call(e,g,f,b)&&d.push(g);}return d},// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray
16
16
  isArray:function isArray(a){return "[object Array]"===Object.prototype.toString.call(a)},Base64:Base64$1};
17
17
 
18
- var version = "2.71.1";
18
+ var version = "2.71.2";
19
19
 
20
20
  var Constants={sdkVersion:version,sdkVendor:"mparticle",platform:"web",Messages:{DeprecationMessages:{MethodHasBeenDeprecated:"has been deprecated.",MethodMarkedForDeprecationPostfix:"is a deprecated method and will be removed in future releases.",AlternativeMethodPrefix:"Please use the alternate method:"},ErrorMessages:{NoToken:"A token must be specified.",EventNameInvalidType:"Event name must be a valid string value.",EventDataInvalidType:"Event data must be a valid object hash.",LoggingDisabled:"Event logging is currently disabled.",CookieParseError:"Could not parse cookie",EventEmpty:"Event object is null or undefined, cancelling send",APIRequestEmpty:"APIRequest is null or undefined, cancelling send",NoEventType:"Event type must be specified.",TransactionIdRequired:"Transaction ID is required",TransactionRequired:"A transaction attributes object is required",PromotionIdRequired:"Promotion ID is required",BadAttribute:"Attribute value cannot be object or array",BadKey:"Key value cannot be object or array",BadLogPurchase:"Transaction attributes and a product are both required to log a purchase, https://docs.mparticle.com/?javascript#measuring-transactions",AudienceAPINotEnabled:"Your workspace is not enabled to retrieve user audiences."},InformationMessages:{CookieSearch:"Searching for cookie",CookieFound:"Cookie found, parsing values",CookieNotFound:"Cookies not found",CookieSet:"Setting cookie",CookieSync:"Performing cookie sync",SendBegin:"Starting to send event",SendIdentityBegin:"Starting to send event to identity server",SendWindowsPhone:"Sending event to Windows Phone container",SendIOS:"Calling iOS path: ",SendAndroid:"Calling Android JS interface method: ",SendHttp:"Sending event to mParticle HTTP service",SendAliasHttp:"Sending alias request to mParticle HTTP service",SendIdentityHttp:"Sending event to mParticle HTTP service",StartingNewSession:"Starting new Session",StartingLogEvent:"Starting to log event",StartingLogOptOut:"Starting to log user opt in/out",StartingEndSession:"Starting to end session",StartingInitialization:"Starting to initialize",StartingLogCommerceEvent:"Starting to log commerce event",StartingAliasRequest:"Starting to Alias MPIDs",LoadingConfig:"Loading configuration options",AbandonLogEvent:"Cannot log event, logging disabled or developer token not set",AbandonAliasUsers:"Cannot Alias Users, logging disabled or developer token not set",AbandonStartSession:"Cannot start session, logging disabled or developer token not set",AbandonEndSession:"Cannot end session, logging disabled or developer token not set",NoSessionToEnd:"Cannot end session, no active session found"},ValidationMessages:{ModifyIdentityRequestUserIdentitiesPresent:"identityRequests to modify require userIdentities to be present. Request not sent to server. Please fix and try again",IdentityRequesetInvalidKey:"There is an invalid key on your identityRequest object. It can only contain a `userIdentities` object and a `onUserAlias` function. Request not sent to server. Please fix and try again.",OnUserAliasType:"The onUserAlias value must be a function.",UserIdentities:"The userIdentities key must be an object with keys of identityTypes and values of strings. Request not sent to server. Please fix and try again.",UserIdentitiesInvalidKey:"There is an invalid identity key on your `userIdentities` object within the identityRequest. Request not sent to server. Please fix and try again.",UserIdentitiesInvalidValues:"All user identity values must be strings or null. Request not sent to server. Please fix and try again.",AliasMissingMpid:"Alias Request must contain both a destinationMpid and a sourceMpid",AliasNonUniqueMpid:"Alias Request's destinationMpid and sourceMpid must be unique",AliasMissingTime:"Alias Request must have both a startTime and an endTime",AliasStartBeforeEndTime:"Alias Request's endTime must be later than its startTime"}},NativeSdkPaths:{LogEvent:"logEvent",SetUserTag:"setUserTag",RemoveUserTag:"removeUserTag",SetUserAttribute:"setUserAttribute",RemoveUserAttribute:"removeUserAttribute",SetSessionAttribute:"setSessionAttribute",AddToCart:"addToCart",RemoveFromCart:"removeFromCart",ClearCart:"clearCart",LogOut:"logOut",SetUserAttributeList:"setUserAttributeList",RemoveAllUserAttributes:"removeAllUserAttributes",GetUserAttributesLists:"getUserAttributesLists",GetAllUserAttributes:"getAllUserAttributes",Identify:"identify",Logout:"logout",Login:"login",Modify:"modify",Alias:"aliasUsers",Upload:"upload"},StorageNames:{localStorageName:"mprtcl-api",localStorageNameV3:"mprtcl-v3",cookieName:"mprtcl-api",cookieNameV2:"mprtcl-v2",cookieNameV3:"mprtcl-v3",localStorageNameV4:"mprtcl-v4",localStorageProductsV4:"mprtcl-prodv4",cookieNameV4:"mprtcl-v4",currentStorageName:"mprtcl-v4",currentStorageProductsName:"mprtcl-prodv4"},DefaultConfig:{cookieDomain:null,cookieExpiration:365,logLevel:null,timeout:300,sessionTimeout:30,maxProducts:20,forwarderStatsTimeout:5e3,integrationDelayTimeout:5e3,maxCookieSize:3e3,aliasMaxWindow:90,uploadInterval:0// Maximum milliseconds in between batch uploads, below 500 will mean immediate upload. The server returns this as a string, but we are using it as a number internally
21
21
  },DefaultBaseUrls:{v1SecureServiceUrl:"jssdks.mparticle.com/v1/JS/",v2SecureServiceUrl:"jssdks.mparticle.com/v2/JS/",v3SecureServiceUrl:"jssdks.mparticle.com/v3/JS/",configUrl:"jssdkcdns.mparticle.com/JS/v2/",identityUrl:"identity.mparticle.com/v1/",aliasUrl:"jssdks.mparticle.com/v1/identity/",userAudienceUrl:"nativesdks.mparticle.com/v1/"},// These are the paths that are used to construct the CNAME urls
@@ -452,7 +452,10 @@ return g=Object.assign(g,b),{event_type:dist.EventTypeEnum.applicationStateTrans
452
452
  //spanning_mpids: sdkEvent.SessionMpids
453
453
  };return c=Object.assign(c,b),{event_type:dist.EventTypeEnum.sessionEnd,data:c}}function convertSessionStartEvent(a){var b=convertBaseEventData(a),c={};return c=Object.assign(c,b),{event_type:dist.EventTypeEnum.sessionStart,data:c}}function convertPageViewEvent(a){var b=convertBaseEventData(a),c={custom_flags:a.CustomFlags,screen_name:a.EventName};return c=Object.assign(c,b),{event_type:dist.EventTypeEnum.screenView,data:c}}function convertOptOutEvent(a){var b=convertBaseEventData(a),c={is_opted_out:a.OptOut};return c=Object.assign(c,b),{event_type:dist.EventTypeEnum.optOut,data:c}}function convertCustomEvent(a){var b=convertBaseEventData(a),c={custom_event_type:convertSdkEventType(a.EventCategory),custom_flags:a.CustomFlags,event_name:a.EventName};return c=Object.assign(c,b),{event_type:dist.EventTypeEnum.customEvent,data:c}}function convertSdkEventType(a){return a===Types.EventType.Other?dist.CustomEventDataCustomEventTypeEnum.other:a===Types.EventType.Location?dist.CustomEventDataCustomEventTypeEnum.location:a===Types.EventType.Navigation?dist.CustomEventDataCustomEventTypeEnum.navigation:a===Types.EventType.Search?dist.CustomEventDataCustomEventTypeEnum.search:a===Types.EventType.Social?dist.CustomEventDataCustomEventTypeEnum.social:a===Types.EventType.Transaction?dist.CustomEventDataCustomEventTypeEnum.transaction:a===Types.EventType.UserContent?dist.CustomEventDataCustomEventTypeEnum.userContent:a===Types.EventType.UserPreference?dist.CustomEventDataCustomEventTypeEnum.userPreference:a===Types.EventType.Media?dist.CustomEventDataCustomEventTypeEnum.media:a===Types.CommerceEventType.ProductAddToCart?dist.CommerceEventDataCustomEventTypeEnum.addToCart:a===Types.CommerceEventType.ProductAddToWishlist?dist.CommerceEventDataCustomEventTypeEnum.addToWishlist:a===Types.CommerceEventType.ProductCheckout?dist.CommerceEventDataCustomEventTypeEnum.checkout:a===Types.CommerceEventType.ProductCheckoutOption?dist.CommerceEventDataCustomEventTypeEnum.checkoutOption:a===Types.CommerceEventType.ProductClick?dist.CommerceEventDataCustomEventTypeEnum.click:a===Types.CommerceEventType.ProductImpression?dist.CommerceEventDataCustomEventTypeEnum.impression:a===Types.CommerceEventType.ProductPurchase?dist.CommerceEventDataCustomEventTypeEnum.purchase:a===Types.CommerceEventType.ProductRefund?dist.CommerceEventDataCustomEventTypeEnum.refund:a===Types.CommerceEventType.ProductRemoveFromCart?dist.CommerceEventDataCustomEventTypeEnum.removeFromCart:a===Types.CommerceEventType.ProductRemoveFromWishlist?dist.CommerceEventDataCustomEventTypeEnum.removeFromWishlist:a===Types.CommerceEventType.ProductViewDetail?dist.CommerceEventDataCustomEventTypeEnum.viewDetail:a===Types.CommerceEventType.PromotionClick?dist.CommerceEventDataCustomEventTypeEnum.promotionClick:a===Types.CommerceEventType.PromotionView?dist.CommerceEventDataCustomEventTypeEnum.promotionView:dist.CustomEventDataCustomEventTypeEnum.unknown}function convertBaseEventData(a){var b={timestamp_unixtime_ms:a.Timestamp,session_uuid:a.SessionId,session_start_unixtime_ms:a.SessionStartDate,custom_attributes:a.EventAttributes,location:convertSDKLocation(a.Location),source_message_id:a.SourceMessageId,active_time_on_site_ms:a.ActiveTimeOnSite,page_url:a.PageUrl};return b}function convertSDKLocation(a){return a&&Object.keys(a).length?{latitude:a.lat,longitude:a.lng}:null}function convertUserAttributeChangeEvent(a){var b=convertBaseEventData(a),c={user_attribute_name:a.UserAttributeChanges.UserAttributeName,new:a.UserAttributeChanges.New,old:a.UserAttributeChanges.Old,deleted:a.UserAttributeChanges.Deleted,is_new_attribute:a.UserAttributeChanges.IsNewAttribute};return c=__assign(__assign({},c),b),{event_type:dist.EventTypeEnum.userAttributeChange,data:c}}function convertUserIdentityChangeEvent(a){var b=convertBaseEventData(a),c={new:{identity_type:convertUserIdentityTypeToServerIdentityType(a.UserIdentityChanges.New.IdentityType),identity:a.UserIdentityChanges.New.Identity||null,timestamp_unixtime_ms:a.Timestamp,created_this_batch:a.UserIdentityChanges.New.CreatedThisBatch},old:{identity_type:convertUserIdentityTypeToServerIdentityType(a.UserIdentityChanges.Old.IdentityType),identity:a.UserIdentityChanges.Old.Identity||null,timestamp_unixtime_ms:a.Timestamp,created_this_batch:a.UserIdentityChanges.Old.CreatedThisBatch}};return c=Object.assign(c,b),{event_type:dist.EventTypeEnum.userIdentityChange,data:c}}function convertUserIdentityTypeToServerIdentityType(a){return a===SDKIdentityTypeEnum.other?dist.IdentityTypeEnum.other:a===SDKIdentityTypeEnum.customerId?dist.IdentityTypeEnum.customerId:a===SDKIdentityTypeEnum.facebook?dist.IdentityTypeEnum.facebook:a===SDKIdentityTypeEnum.twitter?dist.IdentityTypeEnum.twitter:a===SDKIdentityTypeEnum.google?dist.IdentityTypeEnum.google:a===SDKIdentityTypeEnum.microsoft?dist.IdentityTypeEnum.microsoft:a===SDKIdentityTypeEnum.yahoo?dist.IdentityTypeEnum.yahoo:a===SDKIdentityTypeEnum.email?dist.IdentityTypeEnum.email:a===SDKIdentityTypeEnum.alias?dist.IdentityTypeEnum.alias:a===SDKIdentityTypeEnum.facebookCustomAudienceId?dist.IdentityTypeEnum.facebookCustomAudienceId:a===SDKIdentityTypeEnum.otherId2?dist.IdentityTypeEnum.otherId2:a===SDKIdentityTypeEnum.otherId3?dist.IdentityTypeEnum.otherId3:a===SDKIdentityTypeEnum.otherId4?dist.IdentityTypeEnum.otherId4:a===SDKIdentityTypeEnum.otherId5?dist.IdentityTypeEnum.otherId5:a===SDKIdentityTypeEnum.otherId6?dist.IdentityTypeEnum.otherId6:a===SDKIdentityTypeEnum.otherId7?dist.IdentityTypeEnum.otherId7:a===SDKIdentityTypeEnum.otherId8?dist.IdentityTypeEnum.otherId8:a===SDKIdentityTypeEnum.otherId9?dist.IdentityTypeEnum.otherId9:a===SDKIdentityTypeEnum.otherId10?dist.IdentityTypeEnum.otherId10:a===SDKIdentityTypeEnum.mobileNumber?dist.IdentityTypeEnum.mobileNumber:a===SDKIdentityTypeEnum.phoneNumber2?dist.IdentityTypeEnum.phoneNumber2:a===SDKIdentityTypeEnum.phoneNumber3?dist.IdentityTypeEnum.phoneNumber3:void 0}
454
454
 
455
- var BaseVault=/** @class */function(){/**
455
+ // `Unavailable` covers storage being blocked/disabled (e.g. SecurityError),
456
+ // where retrying with a smaller payload cannot succeed.
457
+ var StorageResult;(function(a){a.Success="Success",a.QuotaExceeded="QuotaExceeded",a.Unavailable="Unavailable";})(StorageResult||(StorageResult={}));var isQuotaExceededError=function(a){return a instanceof DOMException&&(// Standard quota errors, plus Firefox's legacy name/code.
458
+ 22===a.code||1014===a.code||"QuotaExceededError"===a.name||"NS_ERROR_DOM_QUOTA_REACHED"===a.name)},BaseVault=/** @class */function(){/**
456
459
  *
457
460
  * @param {string} storageKey the local storage key string
458
461
  * @param {Storage} storageObject Web API Storage object that is being used
@@ -460,9 +463,9 @@ var BaseVault=/** @class */function(){/**
460
463
  * Stores a StorableItem to Storage
461
464
  * @method store
462
465
  * @param item {StorableItem}
463
- */return a.prototype.store=function(a){var b;this.contents=a,b=isNumber(a)||!isEmpty(a)?JSON.stringify(a):"",this.storageObject.setItem(this._storageKey,b);},a.prototype.retrieve=function(){// TODO: Handle cases where Local Storage is unavailable
464
- // https://go.mparticle.com/work/SQDSDKS-5022
465
- var a=this.storageObject.getItem(this._storageKey);return this.contents=a?JSON.parse(a):null,this.contents},a.prototype.purge=function(){this.contents=null,this.storageObject.removeItem(this._storageKey);},a}();var LocalStorageVault=/** @class */function(a){function b(b){return a.call(this,b,window.localStorage)||this}return __extends(b,a),b}(BaseVault);var SessionStorageVault=/** @class */function(a){function b(b){return a.call(this,b,window.sessionStorage)||this}return __extends(b,a),b}(BaseVault);var DisabledVault=/** @class */function(a){function b(b){var c=a.call(this,b,window.localStorage)||this;return c.contents=null,c.storageObject.removeItem(c._storageKey),c}return __extends(b,a),b.prototype.store=function(){this.contents=null;},b.prototype.retrieve=function(){return this.contents},b.prototype.purge=function(){this.contents=null;},b}(BaseVault);
466
+ */return a.prototype.store=function(a){var b;try{return b=isNumber(a)||!isEmpty(a)?JSON.stringify(a):"",this.storageObject.setItem(this._storageKey,b),this.contents=a,StorageResult.Success}catch(a){return isQuotaExceededError(a)?StorageResult.QuotaExceeded:StorageResult.Unavailable}},a.prototype.retrieve=function(){// https://go.mparticle.com/work/SQDSDKS-5022
467
+ try{var a=this.storageObject.getItem(this._storageKey);this.contents=a?JSON.parse(a):null;}catch(a){this.contents=null;}return this.contents},a.prototype.purge=function(){this.contents=null;try{this.storageObject.removeItem(this._storageKey);}catch(a){// Storage persistence is best effort.
468
+ }},a}();var LocalStorageVault=/** @class */function(a){function b(b){return a.call(this,b,window.localStorage)||this}return __extends(b,a),b}(BaseVault);var SessionStorageVault=/** @class */function(a){function b(b){return a.call(this,b,window.sessionStorage)||this}return __extends(b,a),b}(BaseVault);var DisabledVault=/** @class */function(a){function b(b){var c=a.call(this,b,window.localStorage)||this;return c.contents=null,c.storageObject.removeItem(c._storageKey),c}return __extends(b,a),b.prototype.store=function(){return this.contents=null,StorageResult.Success},b.prototype.retrieve=function(){return this.contents},b.prototype.purge=function(){this.contents=null;},b}(BaseVault);
466
469
 
467
470
  var AsyncUploader=/** @class */function(){function a(a){this.url=a;}return a}();var FetchUploader=/** @class */function(a){function b(){return null!==a&&a.apply(this,arguments)||this}return __extends(b,a),b.prototype.upload=function(a,b){return __awaiter(this,void 0,void 0,function(){var c;return __generator(this,function(d){switch(d.label){case 0:return c=b||this.url,[4/*yield*/,fetch(c,a)];case 1:return [2/*return*/,d.sent()]}})})},b}(AsyncUploader);var XHRUploader=/** @class */function(a){function b(){return null!==a&&a.apply(this,arguments)||this}return __extends(b,a),b.prototype.upload=function(a){return __awaiter(this,void 0,void 0,function(){var b;return __generator(this,function(c){switch(c.label){case 0:return [4/*yield*/,this.makeRequest(this.url,a.body,a.method,a.headers)];case 1:return b=c.sent(),[2/*return*/,b]}})})},b.prototype.makeRequest=function(a,b,c,d){return void 0===c&&(c="post"),void 0===d&&(d={}),__awaiter(this,void 0,void 0,function(){var e;return __generator(this,function(){return e=new XMLHttpRequest,[2/*return*/,new Promise(function(f,g){for(var h in e.onreadystatechange=function(){4!==e.readyState||// Process the response
468
471
  // We resolve all xhr responses whose ready state is 4 regardless of HTTP codes that may be errors (400+)
@@ -491,8 +494,8 @@ function appendUserInfo(a,b){if(b){if(!a)return b.MPID=null,b.ConsentState=null,
491
494
  * Creates an instance of a BatchUploader
492
495
  * @param {IMParticleWebSDKInstance} mpInstance - the mParticle SDK instance
493
496
  * @param {number} uploadInterval - the desired upload interval in milliseconds
494
- */function a(b,c){var d,e;this.offlineStorageEnabled=!1,this.lastASTEventTime=0,this.AST_DEBOUNCE_MS=1e3,this.uploadIntervalTimerId=null,this.exitHandler=null,this.visibilityChangeHandler=null,this.destroyed=!1,this.mpInstance=b,this.uploadIntervalMillis=c,this.batchingEnabled=c>=a.MINIMUM_INTERVAL_MILLIS,this.uploadIntervalMillis<a.MINIMUM_INTERVAL_MILLIS&&(this.uploadIntervalMillis=a.MINIMUM_INTERVAL_MILLIS),this.eventsQueuedForProcessing=[],this.batchesQueuedForProcessing=[],this.offlineStorageEnabled=this.isOfflineStorageAvailable();// When noFunctional is true, prevent events/batches storage
495
- var f=null===(e=b._CookieConsentManager)||void 0===e?void 0:e.getNoFunctional();this.offlineStorageEnabled&&!f&&(this.eventVault=new SessionStorageVault("".concat(b._Store.storageName,"-events")),this.batchVault=new LocalStorageVault("".concat(b._Store.storageName,"-batches")),(d=this.eventsQueuedForProcessing).push.apply(d,this.eventVault.retrieve()));var g=this.mpInstance._Store,h=g.SDKConfig,i=g.devToken,j=this.mpInstance._Helpers.createServiceUrl(h.v3SecureServiceUrl,i);this.uploadUrl="".concat(j,"/events"),this.uploader=window.fetch?new FetchUploader(this.uploadUrl):new XHRUploader(this.uploadUrl),this.triggerUploadInterval(!0,!1),this.addEventListeners();}/**
497
+ */function a(b,c){var d,e,f;this.offlineStorageEnabled=!1,this.lastASTEventTime=0,this.AST_DEBOUNCE_MS=1e3,this.uploadIntervalTimerId=null,this.exitHandler=null,this.visibilityChangeHandler=null,this.destroyed=!1,this.mpInstance=b,this.uploadIntervalMillis=c,this.batchingEnabled=c>=a.MINIMUM_INTERVAL_MILLIS,this.uploadIntervalMillis<a.MINIMUM_INTERVAL_MILLIS&&(this.uploadIntervalMillis=a.MINIMUM_INTERVAL_MILLIS),this.eventsQueuedForProcessing=[],this.batchesQueuedForProcessing=[],this.offlineStorageEnabled=this.isOfflineStorageAvailable();// When noFunctional is true, prevent events/batches storage
498
+ var g=null===(e=b._CookieConsentManager)||void 0===e?void 0:e.getNoFunctional();this.offlineStorageEnabled&&!g&&(this.eventVault=new SessionStorageVault("".concat(b._Store.storageName,"-events")),this.batchVault=new LocalStorageVault("".concat(b._Store.storageName,"-batches")),(d=this.eventsQueuedForProcessing).push.apply(d,null!==(f=this.eventVault.retrieve())&&void 0!==f?f:[]));var h=this.mpInstance._Store,i=h.SDKConfig,j=h.devToken,k=this.mpInstance._Helpers.createServiceUrl(i.v3SecureServiceUrl,j);this.uploadUrl="".concat(k,"/events"),this.uploader=window.fetch?new FetchUploader(this.uploadUrl):new XHRUploader(this.uploadUrl),this.triggerUploadInterval(!0,!1),this.addEventListeners();}/**
496
499
  * Cleans up timers and event listeners to prevent leaks when the SDK
497
500
  * is re-initialized (e.g. between tests or on repeated init calls).
498
501
  */return a.prototype.destroy=function(){this.destroyed=!0,null!==this.uploadIntervalTimerId&&(clearTimeout(this.uploadIntervalTimerId),this.uploadIntervalTimerId=null),this.visibilityChangeHandler&&document.removeEventListener("visibilitychange",this.visibilityChangeHandler),this.exitHandler&&(window.removeEventListener("beforeunload",this.exitHandler),window.removeEventListener("pagehide",this.exitHandler)),this.exitHandler=null,this.visibilityChangeHandler=null;},a.prototype.isOfflineStorageAvailable=function(){var a=this.mpInstance,b=a._Helpers.getFeatureFlag,c=a._Store.deviceId,d=b(Constants.FeatureFlags.OfflineStorage),e=parseInt(d,10),f=getRampNumber(c);// https://go.mparticle.com/work/SQDSDKS-6317
@@ -505,7 +508,13 @@ var c=a.mpInstance._Helpers.getFeatureFlag,d=Constants.FeatureFlags.AstBackgroun
505
508
  var e=b.createBackgroundASTEvent();b.queueEvent(e);}// Then trigger the upload with beacon
506
509
  b.prepareAndUpload(!1,b.isBeaconAvailable());};this.exitHandler=c,this.visibilityChangeHandler=function(){"hidden"===document.visibilityState&&c();},document.addEventListener("visibilitychange",this.visibilityChangeHandler),window.addEventListener("beforeunload",c),window.addEventListener("pagehide",c);},a.prototype.isBeaconAvailable=function(){return !!navigator.sendBeacon},a.prototype.triggerUploadInterval=function(a,b){var c=this;void 0===a&&(a=!1),void 0===b&&(b=!1),this.uploadIntervalTimerId=setTimeout(function(){c.prepareAndUpload(a,b);},this.uploadIntervalMillis);},a.prototype.queueEvent=function(a){if(!isEmpty(a)){if(this.eventsQueuedForProcessing.push(a),this.offlineStorageEnabled&&this.eventVault&&this.eventVault.store(this.eventsQueuedForProcessing),this.mpInstance.Logger.isVerbose()){var b=obfuscateDevData(a,this.mpInstance._Store.SDKConfig.isDevelopmentMode);this.mpInstance.Logger.verbose("Queuing event: ".concat(JSON.stringify(b))),this.mpInstance.Logger.verbose("Queued event count: ".concat(this.eventsQueuedForProcessing.length));}this.shouldTriggerImmediateUpload(a.EventDataType)&&this.prepareAndUpload(!1,!1);}},a.prototype.shouldTriggerImmediateUpload=function(a){var b=[MessageType$1.Commerce,MessageType$1.UserIdentityChange];return !this.batchingEnabled||b.includes(a)},(a.createNewBatches=function(a,b,c){if(!b||!a||!a.length)return null;//bucket by MPID, and then by session, ordered by timestamp
507
510
  for(var d,e=[],f=new Map,g=0,h=a;g<h.length;g++){//on initial startup, there may be events logged without an mpid.
508
- if(d=h[g],!d.MPID){var i=b.getMPID();d.MPID=i;}var j=f.get(d.MPID);j||(j=[]),j.push(d),f.set(d.MPID,j);}for(var k=0,l=Array.from(f.entries());k<l.length;k++){for(var m=l[k],i=m[0],n=m[1],o=new Map,p=0,q=n;p<q.length;p++){var d=q[p],j=o.get(d.SessionId);j||(j=[]),j.push(d),o.set(d.SessionId,j);}for(var r=0,s=Array.from(o.entries());r<s.length;r++){var t=s[r],u=convertEvents(i,t[1],c),v=c._Store.SDKConfig.onCreateBatch;v&&(u=v(u),u?u.modified=!0:c.Logger.warning("Skiping batch upload because no batch was returned from onCreateBatch callback")),u&&e.push(u);}}return e},a.prototype.prepareAndUpload=function(b,c){return void 0===b&&(b=!1),void 0===c&&(c=!1),__awaiter(this,void 0,void 0,function(){var d,e,f,g,h,i,j,k;return __generator(this,function(l){switch(l.label){case 0:return d=this.mpInstance.Identity.getCurrentUser(),e=this.eventsQueuedForProcessing,this.eventsQueuedForProcessing=[],this.offlineStorageEnabled&&this.eventVault&&this.eventVault.store([]),f=[],isEmpty(e)||(f=a.createNewBatches(e,d,this.mpInstance)),this.offlineStorageEnabled&&this.batchVault&&((i=this.batchesQueuedForProcessing).unshift.apply(i,this.batchVault.retrieve()),this.batchVault.purge()),isEmpty(f)||(j=this.batchesQueuedForProcessing).push.apply(j,f),g=this.batchesQueuedForProcessing,this.batchesQueuedForProcessing=[],[4/*yield*/,this.uploadBatches(g,c)];case 1:return h=l.sent(),isEmpty(h)||(k=this.batchesQueuedForProcessing).unshift.apply(k,h),!c&&this.offlineStorageEnabled&&this.batchVault&&(this.batchVault.store(this.batchesQueuedForProcessing),this.batchesQueuedForProcessing=[]),b&&!this.destroyed&&this.triggerUploadInterval(b,!1),[2/*return*/]}})})},a.prototype.uploadBatches=function(b,c){return __awaiter(this,void 0,void 0,function(){var d,e,f,g,h,j,k;return __generator(this,function(i){switch(i.label){case 0:if(d=b.filter(function(a){return !isEmpty(a.events)}),isEmpty(d))return [2/*return*/,null];this.mpInstance.Logger.isVerbose()&&(e=obfuscateDevData(d,this.mpInstance._Store.SDKConfig.isDevelopmentMode),this.mpInstance.Logger.verbose("Uploading batches: ".concat(JSON.stringify(e))),this.mpInstance.Logger.verbose("Batch count: ".concat(d.length))),f=0,i.label=1;case 1:return f<d.length?(g={method:"POST",headers:{Accept:a.CONTENT_TYPE,"Content-Type":"text/plain;charset=UTF-8"},body:JSON.stringify(d[f])},!(c&&this.isBeaconAvailable()))?[3/*break*/,2]:(h=new Blob([g.body],{type:"text/plain;charset=UTF-8"}),navigator.sendBeacon(this.uploadUrl,h),[3/*break*/,5]):[3/*break*/,6];case 2:return i.trys.push([2,4,,5]),[4/*yield*/,this.uploader.upload(g)];case 3:if(j=i.sent(),200<=j.status&&300>j.status)this.mpInstance.Logger.verbose("Upload success for request ID: ".concat(d[f].source_request_id));else {if(500<=j.status||429===j.status)// Server error, add back current batches and try again later
511
+ if(d=h[g],!d.MPID){var i=b.getMPID();d.MPID=i;}var j=f.get(d.MPID);j||(j=[]),j.push(d),f.set(d.MPID,j);}for(var k=0,l=Array.from(f.entries());k<l.length;k++){for(var m=l[k],i=m[0],n=m[1],o=new Map,p=0,q=n;p<q.length;p++){var d=q[p],j=o.get(d.SessionId);j||(j=[]),j.push(d),o.set(d.SessionId,j);}for(var r=0,s=Array.from(o.entries());r<s.length;r++){var t=s[r],u=convertEvents(i,t[1],c),v=c._Store.SDKConfig.onCreateBatch;v&&(u=v(u),u?u.modified=!0:c.Logger.warning("Skiping batch upload because no batch was returned from onCreateBatch callback")),u&&e.push(u);}}return e},a.prototype.prepareAndUpload=function(b,c){var d;return void 0===b&&(b=!1),void 0===c&&(c=!1),__awaiter(this,void 0,void 0,function(){var e,f,g,h,i,j,k,l;return __generator(this,function(m){switch(m.label){case 0:return e=this.mpInstance.Identity.getCurrentUser(),f=this.eventsQueuedForProcessing,this.eventsQueuedForProcessing=[],this.offlineStorageEnabled&&this.eventVault&&this.eventVault.store([]),g=[],isEmpty(f)||(g=a.createNewBatches(f,e,this.mpInstance)),this.offlineStorageEnabled&&this.batchVault&&((j=this.batchesQueuedForProcessing).unshift.apply(j,null!==(d=this.batchVault.retrieve())&&void 0!==d?d:[]),this.batchVault.purge()),isEmpty(g)||(k=this.batchesQueuedForProcessing).push.apply(k,g),h=this.batchesQueuedForProcessing,this.batchesQueuedForProcessing=[],[4/*yield*/,this.uploadBatches(h,c)];case 1:return i=m.sent(),isEmpty(i)||(l=this.batchesQueuedForProcessing).unshift.apply(l,i),!c&&this.offlineStorageEnabled&&this.batchVault&&this.storeBatchesQueuedForProcessing(),b&&!this.destroyed&&this.triggerUploadInterval(b,!1),[2/*return*/]}})})},a.prototype.storeBatchesQueuedForProcessing=function(){var a=this.batchesQueuedForProcessing;// Nothing to persist: reset offline storage to an empty state.
512
+ if(isEmpty(a))return this.batchVault.store([]),void(this.batchesQueuedForProcessing=[]);// Drop oldest batches until storage accepts the payload. Only quota
513
+ // failures are recoverable by trimming; if storage is unavailable,
514
+ // dropping batches won't help, so retain them in memory.
515
+ for(var b,c=0;c<a.length;c++){if(b=this.batchVault.store(a.slice(c)),b===StorageResult.Success)return this.logDroppedOfflineBatches(c),void(this.batchesQueuedForProcessing=[]);if(b===StorageResult.Unavailable)return void this.mpInstance.Logger.warning("Offline batch storage is unavailable. Retaining batches in memory.")}// Every attempt stayed over quota, even down to the newest batch.
516
+ // Retain them in memory rather than dropping everything.
517
+ this.mpInstance.Logger.warning("Offline batch storage is over quota. Retaining batches in memory.");},a.prototype.logDroppedOfflineBatches=function(a){0<a&&this.mpInstance.Logger.warning("Offline batch storage is over quota. Dropped "+"".concat(a," oldest batch(es)."));},a.prototype.uploadBatches=function(b,c){return __awaiter(this,void 0,void 0,function(){var d,e,f,g,h,j,k;return __generator(this,function(i){switch(i.label){case 0:if(d=b.filter(function(a){return !isEmpty(a.events)}),isEmpty(d))return [2/*return*/,null];this.mpInstance.Logger.isVerbose()&&(e=obfuscateDevData(d,this.mpInstance._Store.SDKConfig.isDevelopmentMode),this.mpInstance.Logger.verbose("Uploading batches: ".concat(JSON.stringify(e))),this.mpInstance.Logger.verbose("Batch count: ".concat(d.length))),f=0,i.label=1;case 1:return f<d.length?(g={method:"POST",headers:{Accept:a.CONTENT_TYPE,"Content-Type":"text/plain;charset=UTF-8"},body:JSON.stringify(d[f])},!(c&&this.isBeaconAvailable()))?[3/*break*/,2]:(h=new Blob([g.body],{type:"text/plain;charset=UTF-8"}),navigator.sendBeacon(this.uploadUrl,h),[3/*break*/,5]):[3/*break*/,6];case 2:return i.trys.push([2,4,,5]),[4/*yield*/,this.uploader.upload(g)];case 3:if(j=i.sent(),200<=j.status&&300>j.status)this.mpInstance.Logger.verbose("Upload success for request ID: ".concat(d[f].source_request_id));else {if(500<=j.status||429===j.status)// Server error, add back current batches and try again later
509
518
  return this.mpInstance.Logger.error("HTTP error status ".concat(j.status," received")),[2/*return*/,d.slice(f,d.length)];if(401<=j.status)//if we're getting a 401, assume we'll keep getting a 401 and clear the uploads.
510
519
  return this.mpInstance.Logger.error("HTTP error status ".concat(j.status," while uploading - please verify your API key.")),[2/*return*/,null];throw console.error("HTTP error status ".concat(j.status," while uploading events."),j),new Error("Uncaught HTTP Error ".concat(j.status,". Batch upload will be re-attempted."))}return [3/*break*/,5];case 4:return k=i.sent(),this.mpInstance.Logger.error("Error sending event to mParticle servers. ".concat(k)),[2/*return*/,d.slice(f,d.length)];case 5:return f++,[3/*break*/,1];case 6:return [2/*return*/,null]}})})},a.CONTENT_TYPE="text/plain;charset=UTF-8",a.MINIMUM_INTERVAL_MILLIS=500,a)}();
511
520
 
@@ -759,7 +768,7 @@ if(Object.keys(k).length)for(var m in k)g=d(b,c,e),g.length>f&&k.hasOwnProperty(
759
768
  for(var n,o=0;o<h.length&&(g=d(b,c,e),g.length>f);o++)n=h[o],b[n]?(a.Logger.verbose("Size of new encoded cookie is larger than maxCookieSize setting of "+f+". Removing from cookie the earliest logged in MPID containing: "+JSON.stringify(b[n],0,2)),delete b[n]):a.Logger.error("Unable to save MPID data to cookies because the resulting encoded cookie is larger than the maxCookieSize setting of "+f+". We recommend using a maxCookieSize of 1500.");}return g},this.findPrevCookiesBasedOnUI=function(b){var c,d=a._Persistence.getPersistence();if(b)for(var e in b.userIdentities)if(d&&Object.keys(d).length)for(var g in d)// any value in persistence that has an MPID key will be an MPID to search through
760
769
  // other keys on the cookie are currentSessionMPIDs and currentMPID which should not be searched
761
770
  if(d[g].mpid){var h=d[g].ui;for(var i in h)if(e===i&&b.userIdentities[e]===h[i]){c=g;break}}c&&f.storeDataInMemory(d,c);},this.encodePersistence=function(b){for(var c in b=JSON.parse(b),b.gs)b.gs.hasOwnProperty(c)&&(Base64CookieKeys[c]?b.gs[c]?Array.isArray(b.gs[c])&&b.gs[c].length||a._Helpers.isObject(b.gs[c])&&Object.keys(b.gs[c]).length?b.gs[c]=Base64.encode(JSON.stringify(b.gs[c])):delete b.gs[c]:delete b.gs[c]:"ie"===c?b.gs[c]=b.gs[c]?1:0:!b.gs[c]&&delete b.gs[c]);for(var d in b)if(b.hasOwnProperty(d)&&!SDKv2NonMPIDCookieKeys[d])for(c in b[d])b[d].hasOwnProperty(c)&&Base64CookieKeys[c]&&(a._Helpers.isObject(b[d][c])&&Object.keys(b[d][c]).length?b[d][c]=Base64.encode(JSON.stringify(b[d][c])):delete b[d][c]);return createCookieString(JSON.stringify(b))},this.decodePersistence=function(b){try{if(b){if(b=JSON.parse(revertCookieString(b)),a._Helpers.isObject(b)&&Object.keys(b).length){for(var c in b.gs)b.gs.hasOwnProperty(c)&&(Base64CookieKeys[c]?b.gs[c]=JSON.parse(Base64.decode(b.gs[c])):"ie"===c&&(b.gs[c]=!!b.gs[c]));for(var d in b)if(b.hasOwnProperty(d))if(!SDKv2NonMPIDCookieKeys[d])for(c in b[d])b[d].hasOwnProperty(c)&&Base64CookieKeys[c]&&b[d][c].length&&(b[d][c]=JSON.parse(Base64.decode(b[d][c])));else "l"===d&&(b[d]=!!b[d]);}return JSON.stringify(b)}}catch(b){a.Logger.error("Problem with decoding cookie",b);}},this.getCookieDomain=function(){if(a._Store.SDKConfig.cookieDomain)return a._Store.SDKConfig.cookieDomain;var b=f.getDomain(document,location.hostname);return ""===b?"":"."+b},this.getDomain=function(a,b){var c,d,e=b.split(".");for(c=e.length-1;0<=c;c--)if(d=e.slice(c).join("."),a.cookie="mptest=cookie;domain=."+d+";",-1<a.cookie.indexOf("mptest=cookie"))return a.cookie="mptest=;domain=."+d+";expires=Thu, 01 Jan 1970 00:00:01 GMT;",d;return ""},this.saveUserCookieSyncDatesToPersistence=function(a,b){if(b){var c=f.getPersistence();c&&(c[a]?c[a].csd=b:c[a]={csd:b}),f.savePersistence(c);}},this.swapCurrentUser=function(a,b,c){if(a&&b&&a!==b){var d=f.getPersistence();d&&(d.cu=b,d.gs.csm=c,f.savePersistence(d));}},this.savePersistence=function(b){var c;// Block mprtcl-v4 persistence when noFunctional is true
762
- if(!(null!==(c=a._CookieConsentManager)&&void 0!==c&&c.getNoFunctional())){var d,e=f.encodePersistence(JSON.stringify(b)),g=new Date,h=a._Store.storageName,i=new Date(g.getTime()+1e3*(60*(60*(24*a._Store.SDKConfig.cookieExpiration)))).toGMTString(),j=f.getCookieDomain();if(d=""===j?"":";domain="+j,a._Store.SDKConfig.useCookieStorage){var k=f.reduceAndEncodePersistence(b,i,d,a._Store.SDKConfig.maxCookieSize);window.document.cookie=encodeURIComponent(h)+"="+k;}else a._Store.isLocalStorageAvailable&&localStorage.setItem(a._Store.storageName,e);}},this.getPersistence=function(){var a=this.useLocalStorage()?this.getLocalStorage():this.getCookie();return a},this.getFirstSeenTime=function(a){if(!a)return null;var b=f.getPersistence();return b&&b[a]&&b[a].fst?b[a].fst:null},this.setFirstSeenTime=function(a,b){if(a){b||(b=new Date().getTime());var c=f.getPersistence();c&&(!c[a]&&(c[a]={}),!c[a].fst&&(c[a].fst=b,f.savePersistence(c)));}// https://go.mparticle.com/work/SQDSDKS-6329
771
+ if(!(null!==(c=a._CookieConsentManager)&&void 0!==c&&c.getNoFunctional())){var d,e=f.encodePersistence(JSON.stringify(b)),g=new Date,h=a._Store.storageName,i=new Date(g.getTime()+1e3*(60*(60*(24*a._Store.SDKConfig.cookieExpiration)))).toGMTString(),j=f.getCookieDomain();if(d=""===j?"":";domain="+j,a._Store.SDKConfig.useCookieStorage){var k=f.reduceAndEncodePersistence(b,i,d,a._Store.SDKConfig.maxCookieSize);window.document.cookie=encodeURIComponent(h)+"="+k;}else if(a._Store.isLocalStorageAvailable)try{localStorage.setItem(a._Store.storageName,e);}catch(b){a.Logger.error("Error saving persistence to localStorage.");}}},this.getPersistence=function(){var a=this.useLocalStorage()?this.getLocalStorage():this.getCookie();return a},this.getFirstSeenTime=function(a){if(!a)return null;var b=f.getPersistence();return b&&b[a]&&b[a].fst?b[a].fst:null},this.setFirstSeenTime=function(a,b){if(a){b||(b=new Date().getTime());var c=f.getPersistence();c&&(!c[a]&&(c[a]={}),!c[a].fst&&(c[a].fst=b,f.savePersistence(c)));}// https://go.mparticle.com/work/SQDSDKS-6329
763
772
  },this.getLastSeenTime=function(b){if(!b)return null;if(b===a.Identity.getCurrentUser().getMPID())//if the mpid is the current user, its last seen time is the current time
764
773
  return new Date().getTime();var c=f.getPersistence();return c&&c[b]&&c[b].lst?c[b].lst:null},this.setLastSeenTime=function(a,b){if(a){b||(b=new Date().getTime());var c=f.getPersistence();c&&c[a]&&(c[a].lst=b,f.savePersistence(c));}// https://go.mparticle.com/work/SQDSDKS-6329
765
774
  },this.getDeviceId=function(){return a._Store.deviceId},this.setDeviceId=function(b){a._Store.deviceId=b,f.update();},this.resetPersistence=function(){if(localStorage.clear(),f.expireCookies(StorageNames.cookieName),f.expireCookies(StorageNames.cookieNameV2),f.expireCookies(StorageNames.cookieNameV3),f.expireCookies(StorageNames.cookieNameV4),f.expireCookies(a._Store.storageName),mParticle._isTestEnv){c(a._Helpers.createMainStorageName("abcdef")),f.expireCookies(a._Helpers.createMainStorageName("abcdef"));}},this.forwardingStatsBatches={uploadsTable:{},forwardingStatsEventQueue:[]};}
package/dist/mparticle.js CHANGED
@@ -203,7 +203,7 @@ var mParticle = (function () {
203
203
  Base64: Base64$1
204
204
  };
205
205
 
206
- var version = "2.71.1";
206
+ var version = "2.71.2";
207
207
 
208
208
  var Constants = {
209
209
  sdkVersion: version,
@@ -2353,6 +2353,20 @@ var mParticle = (function () {
2353
2353
  }
2354
2354
  }
2355
2355
 
2356
+ // Outcome of a vault write so callers can react to the cause of a failure.
2357
+ // `Unavailable` covers storage being blocked/disabled (e.g. SecurityError),
2358
+ // where retrying with a smaller payload cannot succeed.
2359
+ var StorageResult;
2360
+ (function (StorageResult) {
2361
+ StorageResult["Success"] = "Success";
2362
+ StorageResult["QuotaExceeded"] = "QuotaExceeded";
2363
+ StorageResult["Unavailable"] = "Unavailable";
2364
+ })(StorageResult || (StorageResult = {}));
2365
+ var isQuotaExceededError = function isQuotaExceededError(e) {
2366
+ return e instanceof DOMException && (
2367
+ // Standard quota errors, plus Firefox's legacy name/code.
2368
+ e.code === 22 || e.code === 1014 || e.name === 'QuotaExceededError' || e.name === 'NS_ERROR_DOM_QUOTA_REACHED');
2369
+ };
2356
2370
  var BaseVault = /** @class */function () {
2357
2371
  /**
2358
2372
  *
@@ -2371,13 +2385,18 @@ var mParticle = (function () {
2371
2385
  */
2372
2386
  BaseVault.prototype.store = function (item) {
2373
2387
  var stringifiedItem;
2374
- this.contents = item;
2375
- if (isNumber(item) || !isEmpty(item)) {
2376
- stringifiedItem = JSON.stringify(item);
2377
- } else {
2378
- stringifiedItem = '';
2388
+ try {
2389
+ if (isNumber(item) || !isEmpty(item)) {
2390
+ stringifiedItem = JSON.stringify(item);
2391
+ } else {
2392
+ stringifiedItem = '';
2393
+ }
2394
+ this.storageObject.setItem(this._storageKey, stringifiedItem);
2395
+ this.contents = item;
2396
+ return StorageResult.Success;
2397
+ } catch (e) {
2398
+ return isQuotaExceededError(e) ? StorageResult.QuotaExceeded : StorageResult.Unavailable;
2379
2399
  }
2380
- this.storageObject.setItem(this._storageKey, stringifiedItem);
2381
2400
  };
2382
2401
  /**
2383
2402
  * Retrieve StorableItem from Storage
@@ -2385,10 +2404,13 @@ var mParticle = (function () {
2385
2404
  * @returns {StorableItem}
2386
2405
  */
2387
2406
  BaseVault.prototype.retrieve = function () {
2388
- // TODO: Handle cases where Local Storage is unavailable
2389
2407
  // https://go.mparticle.com/work/SQDSDKS-5022
2390
- var item = this.storageObject.getItem(this._storageKey);
2391
- this.contents = item ? JSON.parse(item) : null;
2408
+ try {
2409
+ var item = this.storageObject.getItem(this._storageKey);
2410
+ this.contents = item ? JSON.parse(item) : null;
2411
+ } catch (e) {
2412
+ this.contents = null;
2413
+ }
2392
2414
  return this.contents;
2393
2415
  };
2394
2416
  /**
@@ -2398,7 +2420,11 @@ var mParticle = (function () {
2398
2420
  */
2399
2421
  BaseVault.prototype.purge = function () {
2400
2422
  this.contents = null;
2401
- this.storageObject.removeItem(this._storageKey);
2423
+ try {
2424
+ this.storageObject.removeItem(this._storageKey);
2425
+ } catch (e) {
2426
+ // Storage persistence is best effort.
2427
+ }
2402
2428
  };
2403
2429
  return BaseVault;
2404
2430
  }();
@@ -2427,6 +2453,7 @@ var mParticle = (function () {
2427
2453
  }
2428
2454
  DisabledVault.prototype.store = function (_item) {
2429
2455
  this.contents = null;
2456
+ return StorageResult.Success;
2430
2457
  };
2431
2458
  DisabledVault.prototype.retrieve = function () {
2432
2459
  return this.contents;
@@ -2598,7 +2625,7 @@ var mParticle = (function () {
2598
2625
  */
2599
2626
  function BatchUploader(mpInstance, uploadInterval) {
2600
2627
  var _a;
2601
- var _b;
2628
+ var _b, _c;
2602
2629
  this.offlineStorageEnabled = false;
2603
2630
  this.lastASTEventTime = 0;
2604
2631
  this.AST_DEBOUNCE_MS = 1000; // 1 second debounce
@@ -2626,12 +2653,14 @@ var mParticle = (function () {
2626
2653
  if (this.offlineStorageEnabled && !noFunctional) {
2627
2654
  this.eventVault = new SessionStorageVault("".concat(mpInstance._Store.storageName, "-events"));
2628
2655
  this.batchVault = new LocalStorageVault("".concat(mpInstance._Store.storageName, "-batches"));
2629
- // Load Events from Session Storage in case we have any in storage
2630
- (_a = this.eventsQueuedForProcessing).push.apply(_a, this.eventVault.retrieve());
2631
- }
2632
- var _c = this.mpInstance._Store,
2633
- SDKConfig = _c.SDKConfig,
2634
- devToken = _c.devToken;
2656
+ // Load Events from Session Storage in case we have any in storage.
2657
+ // retrieve() returns null for empty/corrupt storage, so default to
2658
+ // an empty array to keep the spread safe.
2659
+ (_a = this.eventsQueuedForProcessing).push.apply(_a, (_c = this.eventVault.retrieve()) !== null && _c !== void 0 ? _c : []);
2660
+ }
2661
+ var _d = this.mpInstance._Store,
2662
+ SDKConfig = _d.SDKConfig,
2663
+ devToken = _d.devToken;
2635
2664
  var baseUrl = this.mpInstance._Helpers.createServiceUrl(SDKConfig.v3SecureServiceUrl, devToken);
2636
2665
  this.uploadUrl = "".concat(baseUrl, "/events");
2637
2666
  this.uploader = window.fetch ? new FetchUploader(this.uploadUrl) : new XHRUploader(this.uploadUrl);
@@ -2882,6 +2911,7 @@ var mParticle = (function () {
2882
2911
  * @param useBeacon whether to use the beacon API - used when the page is being unloaded
2883
2912
  */
2884
2913
  BatchUploader.prototype.prepareAndUpload = function (triggerFuture, useBeacon) {
2914
+ var _a;
2885
2915
  if (triggerFuture === void 0) {
2886
2916
  triggerFuture = false;
2887
2917
  }
@@ -2890,9 +2920,9 @@ var mParticle = (function () {
2890
2920
  }
2891
2921
  return __awaiter(this, void 0, void 0, function () {
2892
2922
  var currentUser, currentEvents, newBatches, batchesToUpload, batchesThatDidNotUpload;
2893
- var _a, _b, _c;
2894
- return __generator(this, function (_d) {
2895
- switch (_d.label) {
2923
+ var _b, _c, _d;
2924
+ return __generator(this, function (_e) {
2925
+ switch (_e.label) {
2896
2926
  case 0:
2897
2927
  currentUser = this.mpInstance.Identity.getCurrentUser();
2898
2928
  currentEvents = this.eventsQueuedForProcessing;
@@ -2906,25 +2936,25 @@ var mParticle = (function () {
2906
2936
  }
2907
2937
  // Top Load any older Batches from Offline Storage so they go out first
2908
2938
  if (this.offlineStorageEnabled && this.batchVault) {
2909
- (_a = this.batchesQueuedForProcessing).unshift.apply(_a, this.batchVault.retrieve());
2939
+ (_b = this.batchesQueuedForProcessing).unshift.apply(_b, (_a = this.batchVault.retrieve()) !== null && _a !== void 0 ? _a : []);
2910
2940
  // Remove batches from local storage before transmit to
2911
2941
  // prevent duplication
2912
2942
  this.batchVault.purge();
2913
2943
  }
2914
2944
  if (!isEmpty(newBatches)) {
2915
- (_b = this.batchesQueuedForProcessing).push.apply(_b, newBatches);
2945
+ (_c = this.batchesQueuedForProcessing).push.apply(_c, newBatches);
2916
2946
  }
2917
2947
  batchesToUpload = this.batchesQueuedForProcessing;
2918
2948
  this.batchesQueuedForProcessing = [];
2919
2949
  return [4 /*yield*/, this.uploadBatches(batchesToUpload, useBeacon)];
2920
2950
  case 1:
2921
- batchesThatDidNotUpload = _d.sent();
2951
+ batchesThatDidNotUpload = _e.sent();
2922
2952
  // Batches that do not successfully upload are added back to the process queue
2923
2953
  // in the order they were created so that we can attempt re-transmission in
2924
2954
  // the same sequence. This is to prevent any potential data corruption.
2925
2955
  if (!isEmpty(batchesThatDidNotUpload)) {
2926
2956
  // TODO: https://go.mparticle.com/work/SQDSDKS-5165
2927
- (_c = this.batchesQueuedForProcessing).unshift.apply(_c, batchesThatDidNotUpload);
2957
+ (_d = this.batchesQueuedForProcessing).unshift.apply(_d, batchesThatDidNotUpload);
2928
2958
  }
2929
2959
  // Update Offline Storage with current state of batch queue
2930
2960
  if (!useBeacon && this.offlineStorageEnabled && this.batchVault) {
@@ -2933,9 +2963,7 @@ var mParticle = (function () {
2933
2963
  // therefore NOT overwrite Offline Storage when beacon returns, so that we can retry
2934
2964
  // uploading saved batches at a later time. Batches should only be removed from
2935
2965
  // Local Storage once we can confirm they are successfully uploaded.
2936
- this.batchVault.store(this.batchesQueuedForProcessing);
2937
- // Clear batch queue since everything should be in Offline Storage
2938
- this.batchesQueuedForProcessing = [];
2966
+ this.storeBatchesQueuedForProcessing();
2939
2967
  }
2940
2968
  if (triggerFuture && !this.destroyed) {
2941
2969
  this.triggerUploadInterval(triggerFuture, false);
@@ -2946,6 +2974,38 @@ var mParticle = (function () {
2946
2974
  });
2947
2975
  };
2948
2976
 
2977
+ BatchUploader.prototype.storeBatchesQueuedForProcessing = function () {
2978
+ var batches = this.batchesQueuedForProcessing;
2979
+ // Nothing to persist: reset offline storage to an empty state.
2980
+ if (isEmpty(batches)) {
2981
+ this.batchVault.store([]);
2982
+ this.batchesQueuedForProcessing = [];
2983
+ return;
2984
+ }
2985
+ // Drop oldest batches until storage accepts the payload. Only quota
2986
+ // failures are recoverable by trimming; if storage is unavailable,
2987
+ // dropping batches won't help, so retain them in memory.
2988
+ for (var dropped = 0; dropped < batches.length; dropped++) {
2989
+ var result = this.batchVault.store(batches.slice(dropped));
2990
+ if (result === StorageResult.Success) {
2991
+ this.logDroppedOfflineBatches(dropped);
2992
+ this.batchesQueuedForProcessing = [];
2993
+ return;
2994
+ }
2995
+ if (result === StorageResult.Unavailable) {
2996
+ this.mpInstance.Logger.warning('Offline batch storage is unavailable. Retaining batches in memory.');
2997
+ return;
2998
+ }
2999
+ }
3000
+ // Every attempt stayed over quota, even down to the newest batch.
3001
+ // Retain them in memory rather than dropping everything.
3002
+ this.mpInstance.Logger.warning('Offline batch storage is over quota. Retaining batches in memory.');
3003
+ };
3004
+ BatchUploader.prototype.logDroppedOfflineBatches = function (droppedBatchCount) {
3005
+ if (droppedBatchCount > 0) {
3006
+ this.mpInstance.Logger.warning('Offline batch storage is over quota. Dropped ' + "".concat(droppedBatchCount, " oldest batch(es)."));
3007
+ }
3008
+ };
2949
3009
  BatchUploader.prototype.uploadBatches = function (batches, useBeacon) {
2950
3010
  return __awaiter(this, void 0, void 0, function () {
2951
3011
  var uploads, uploadsToLog, i, fetchPayload, blob, response, e_1;
@@ -6059,7 +6119,11 @@ var mParticle = (function () {
6059
6119
  window.document.cookie = encodeURIComponent(key) + '=' + encodedCookiesWithExpirationAndPath;
6060
6120
  } else {
6061
6121
  if (mpInstance._Store.isLocalStorageAvailable) {
6062
- localStorage.setItem(mpInstance._Store.storageName, encodedPersistence);
6122
+ try {
6123
+ localStorage.setItem(mpInstance._Store.storageName, encodedPersistence);
6124
+ } catch (e) {
6125
+ mpInstance.Logger.error('Error saving persistence to localStorage.');
6126
+ }
6063
6127
  }
6064
6128
  }
6065
6129
  };
@@ -77,5 +77,7 @@ export declare class BatchUploader {
77
77
  * @param useBeacon whether to use the beacon API - used when the page is being unloaded
78
78
  */
79
79
  prepareAndUpload(triggerFuture?: boolean, useBeacon?: boolean): Promise<void>;
80
+ private storeBatchesQueuedForProcessing;
81
+ private logDroppedOfflineBatches;
80
82
  private uploadBatches;
81
83
  }
@@ -1,3 +1,8 @@
1
+ export declare enum StorageResult {
2
+ Success = "Success",
3
+ QuotaExceeded = "QuotaExceeded",
4
+ Unavailable = "Unavailable"
5
+ }
1
6
  export declare abstract class BaseVault<StorableItem> {
2
7
  contents: StorableItem;
3
8
  protected readonly _storageKey: string;
@@ -13,7 +18,7 @@ export declare abstract class BaseVault<StorableItem> {
13
18
  * @method store
14
19
  * @param item {StorableItem}
15
20
  */
16
- store(item: StorableItem): void;
21
+ store(item: StorableItem): StorageResult;
17
22
  /**
18
23
  * Retrieve StorableItem from Storage
19
24
  * @method retrieve
@@ -35,7 +40,7 @@ export declare class SessionStorageVault<StorableItem> extends BaseVault<Storabl
35
40
  }
36
41
  export declare class DisabledVault<StorableItem> extends BaseVault<StorableItem> {
37
42
  constructor(storageKey: string);
38
- store(_item: StorableItem): void;
43
+ store(_item: StorableItem): StorageResult;
39
44
  retrieve(): StorableItem | null;
40
45
  purge(): void;
41
46
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mparticle/web-sdk",
3
- "version": "2.71.1",
3
+ "version": "2.71.2",
4
4
  "description": "mParticle core SDK for web applications",
5
5
  "license": "Apache-2.0",
6
6
  "keywords": [
@@ -4,7 +4,7 @@ import { SDKEvent, SDKEventCustomFlags } from './sdkRuntimeModels';
4
4
  import { convertEvents } from './sdkToEventsApiConverter';
5
5
  import { MessageType, EventType } from './types';
6
6
  import { getRampNumber, getHref, isEmpty, obfuscateDevData } from './utils';
7
- import { SessionStorageVault, LocalStorageVault } from './vault';
7
+ import { SessionStorageVault, LocalStorageVault, StorageResult } from './vault';
8
8
  import {
9
9
  AsyncUploader,
10
10
  FetchUploader,
@@ -90,8 +90,12 @@ export class BatchUploader {
90
90
  `${mpInstance._Store.storageName}-batches`
91
91
  );
92
92
 
93
- // Load Events from Session Storage in case we have any in storage
94
- this.eventsQueuedForProcessing.push(...this.eventVault.retrieve());
93
+ // Load Events from Session Storage in case we have any in storage.
94
+ // retrieve() returns null for empty/corrupt storage, so default to
95
+ // an empty array to keep the spread safe.
96
+ this.eventsQueuedForProcessing.push(
97
+ ...(this.eventVault.retrieve() ?? [])
98
+ );
95
99
  }
96
100
 
97
101
  const { SDKConfig, devToken } = this.mpInstance._Store;
@@ -426,7 +430,7 @@ export class BatchUploader {
426
430
  // Top Load any older Batches from Offline Storage so they go out first
427
431
  if (this.offlineStorageEnabled && this.batchVault) {
428
432
  this.batchesQueuedForProcessing.unshift(
429
- ...this.batchVault.retrieve()
433
+ ...(this.batchVault.retrieve() ?? [])
430
434
  );
431
435
 
432
436
  // Remove batches from local storage before transmit to
@@ -463,9 +467,7 @@ export class BatchUploader {
463
467
  // uploading saved batches at a later time. Batches should only be removed from
464
468
  // Local Storage once we can confirm they are successfully uploaded.
465
469
 
466
- this.batchVault.store(this.batchesQueuedForProcessing);
467
- // Clear batch queue since everything should be in Offline Storage
468
- this.batchesQueuedForProcessing = [];
470
+ this.storeBatchesQueuedForProcessing();
469
471
  }
470
472
 
471
473
  if (triggerFuture && !this.destroyed) {
@@ -473,6 +475,52 @@ export class BatchUploader {
473
475
  }
474
476
  }
475
477
 
478
+ private storeBatchesQueuedForProcessing(): void {
479
+ const batches = this.batchesQueuedForProcessing;
480
+
481
+ // Nothing to persist: reset offline storage to an empty state.
482
+ if (isEmpty(batches)) {
483
+ this.batchVault.store([]);
484
+ this.batchesQueuedForProcessing = [];
485
+ return;
486
+ }
487
+
488
+ // Drop oldest batches until storage accepts the payload. Only quota
489
+ // failures are recoverable by trimming; if storage is unavailable,
490
+ // dropping batches won't help, so retain them in memory.
491
+ for (let dropped = 0; dropped < batches.length; dropped++) {
492
+ const result = this.batchVault.store(batches.slice(dropped));
493
+
494
+ if (result === StorageResult.Success) {
495
+ this.logDroppedOfflineBatches(dropped);
496
+ this.batchesQueuedForProcessing = [];
497
+ return;
498
+ }
499
+
500
+ if (result === StorageResult.Unavailable) {
501
+ this.mpInstance.Logger.warning(
502
+ 'Offline batch storage is unavailable. Retaining batches in memory.'
503
+ );
504
+ return;
505
+ }
506
+ }
507
+
508
+ // Every attempt stayed over quota, even down to the newest batch.
509
+ // Retain them in memory rather than dropping everything.
510
+ this.mpInstance.Logger.warning(
511
+ 'Offline batch storage is over quota. Retaining batches in memory.'
512
+ );
513
+ }
514
+
515
+ private logDroppedOfflineBatches(droppedBatchCount: number): void {
516
+ if (droppedBatchCount > 0) {
517
+ this.mpInstance.Logger.warning(
518
+ 'Offline batch storage is over quota. Dropped ' +
519
+ `${droppedBatchCount} oldest batch(es).`
520
+ );
521
+ }
522
+ }
523
+
476
524
  private async uploadBatches(
477
525
  batches: Batch[],
478
526
  useBeacon: boolean
@@ -551,4 +599,4 @@ export class BatchUploader {
551
599
  }
552
600
  return null;
553
601
  }
554
- }
602
+ }
@@ -853,10 +853,16 @@ export default function _Persistence(mpInstance) {
853
853
  encodedCookiesWithExpirationAndPath;
854
854
  } else {
855
855
  if (mpInstance._Store.isLocalStorageAvailable) {
856
- localStorage.setItem(
857
- mpInstance._Store.storageName,
858
- encodedPersistence
859
- );
856
+ try {
857
+ localStorage.setItem(
858
+ mpInstance._Store.storageName,
859
+ encodedPersistence
860
+ );
861
+ } catch (e) {
862
+ mpInstance.Logger.error(
863
+ 'Error saving persistence to localStorage.'
864
+ );
865
+ }
860
866
  }
861
867
  }
862
868
  };
package/src/vault.ts CHANGED
@@ -1,5 +1,22 @@
1
1
  import { isEmpty, isNumber } from './utils';
2
2
 
3
+ // Outcome of a vault write so callers can react to the cause of a failure.
4
+ // `Unavailable` covers storage being blocked/disabled (e.g. SecurityError),
5
+ // where retrying with a smaller payload cannot succeed.
6
+ export enum StorageResult {
7
+ Success = 'Success',
8
+ QuotaExceeded = 'QuotaExceeded',
9
+ Unavailable = 'Unavailable',
10
+ }
11
+
12
+ const isQuotaExceededError = (e: unknown): boolean =>
13
+ e instanceof DOMException &&
14
+ // Standard quota errors, plus Firefox's legacy name/code.
15
+ (e.code === 22 ||
16
+ e.code === 1014 ||
17
+ e.name === 'QuotaExceededError' ||
18
+ e.name === 'NS_ERROR_DOM_QUOTA_REACHED');
19
+
3
20
  export abstract class BaseVault<StorableItem> {
4
21
  public contents: StorableItem;
5
22
  protected readonly _storageKey: string;
@@ -25,17 +42,24 @@ export abstract class BaseVault<StorableItem> {
25
42
  * @method store
26
43
  * @param item {StorableItem}
27
44
  */
28
- public store(item: StorableItem): void {
45
+ public store(item: StorableItem): StorageResult {
29
46
  let stringifiedItem: string;
30
- this.contents = item;
31
47
 
32
- if (isNumber(item) || !isEmpty(item)) {
33
- stringifiedItem = JSON.stringify(item);
34
- } else {
35
- stringifiedItem = '';
48
+ try {
49
+ if (isNumber(item) || !isEmpty(item)) {
50
+ stringifiedItem = JSON.stringify(item);
51
+ } else {
52
+ stringifiedItem = '';
53
+ }
54
+
55
+ this.storageObject.setItem(this._storageKey, stringifiedItem);
56
+ this.contents = item;
57
+ return StorageResult.Success;
58
+ } catch (e) {
59
+ return isQuotaExceededError(e)
60
+ ? StorageResult.QuotaExceeded
61
+ : StorageResult.Unavailable;
36
62
  }
37
-
38
- this.storageObject.setItem(this._storageKey, stringifiedItem);
39
63
  }
40
64
 
41
65
  /**
@@ -44,11 +68,14 @@ export abstract class BaseVault<StorableItem> {
44
68
  * @returns {StorableItem}
45
69
  */
46
70
  public retrieve(): StorableItem | null {
47
- // TODO: Handle cases where Local Storage is unavailable
48
71
  // https://go.mparticle.com/work/SQDSDKS-5022
49
- const item: string = this.storageObject.getItem(this._storageKey);
72
+ try {
73
+ const item: string = this.storageObject.getItem(this._storageKey);
50
74
 
51
- this.contents = item ? JSON.parse(item) : null;
75
+ this.contents = item ? JSON.parse(item) : null;
76
+ } catch (e) {
77
+ this.contents = null;
78
+ }
52
79
 
53
80
  return this.contents;
54
81
  }
@@ -60,7 +87,12 @@ export abstract class BaseVault<StorableItem> {
60
87
  */
61
88
  public purge(): void {
62
89
  this.contents = null;
63
- this.storageObject.removeItem(this._storageKey);
90
+
91
+ try {
92
+ this.storageObject.removeItem(this._storageKey);
93
+ } catch (e) {
94
+ // Storage persistence is best effort.
95
+ }
64
96
  }
65
97
  }
66
98
 
@@ -84,8 +116,9 @@ export class DisabledVault<StorableItem> extends BaseVault<StorableItem> {
84
116
  this.storageObject.removeItem(this._storageKey);
85
117
  }
86
118
 
87
- public store(_item: StorableItem): void {
119
+ public store(_item: StorableItem): StorageResult {
88
120
  this.contents = null;
121
+ return StorageResult.Success;
89
122
  }
90
123
 
91
124
  public retrieve(): StorableItem | null {
@@ -95,4 +128,4 @@ export class DisabledVault<StorableItem> extends BaseVault<StorableItem> {
95
128
  public purge(): void {
96
129
  this.contents = null;
97
130
  }
98
- }
131
+ }