@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.
- package/dist/mparticle.common.js +18 -9
- package/dist/mparticle.esm.js +18 -9
- package/dist/mparticle.js +93 -29
- package/dist/types/src/batchUploader.d.ts +2 -0
- package/dist/types/src/vault.d.ts +7 -2
- package/package.json +1 -1
- package/src/batchUploader.ts +56 -8
- package/src/persistence.js +10 -4
- package/src/vault.ts +47 -14
package/dist/mparticle.common.js
CHANGED
|
@@ -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.
|
|
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
|
-
|
|
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;
|
|
464
|
-
//
|
|
465
|
-
|
|
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
|
|
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
|
|
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
|
|
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.esm.js
CHANGED
|
@@ -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.
|
|
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
|
-
|
|
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;
|
|
464
|
-
//
|
|
465
|
-
|
|
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
|
|
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
|
|
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
|
|
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.
|
|
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
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
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
|
-
|
|
2391
|
-
|
|
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
|
-
|
|
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
|
-
(
|
|
2631
|
-
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
|
|
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
|
|
2894
|
-
return __generator(this, function (
|
|
2895
|
-
switch (
|
|
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
|
-
(
|
|
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
|
-
(
|
|
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 =
|
|
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
|
-
(
|
|
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.
|
|
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
|
-
|
|
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):
|
|
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):
|
|
43
|
+
store(_item: StorableItem): StorageResult;
|
|
39
44
|
retrieve(): StorableItem | null;
|
|
40
45
|
purge(): void;
|
|
41
46
|
}
|
package/package.json
CHANGED
package/src/batchUploader.ts
CHANGED
|
@@ -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
|
-
|
|
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.
|
|
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
|
+
}
|
package/src/persistence.js
CHANGED
|
@@ -853,10 +853,16 @@ export default function _Persistence(mpInstance) {
|
|
|
853
853
|
encodedCookiesWithExpirationAndPath;
|
|
854
854
|
} else {
|
|
855
855
|
if (mpInstance._Store.isLocalStorageAvailable) {
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
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):
|
|
45
|
+
public store(item: StorableItem): StorageResult {
|
|
29
46
|
let stringifiedItem: string;
|
|
30
|
-
this.contents = item;
|
|
31
47
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
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
|
-
|
|
72
|
+
try {
|
|
73
|
+
const item: string = this.storageObject.getItem(this._storageKey);
|
|
50
74
|
|
|
51
|
-
|
|
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
|
-
|
|
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):
|
|
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
|
+
}
|