@mparticle/web-sdk 2.64.1 → 2.65.0
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 +32 -18
- package/dist/mparticle.esm.js +32 -18
- package/dist/mparticle.js +68 -9
- package/dist/types/src/batchUploader.d.ts +9 -0
- package/dist/types/src/constants.d.ts +1 -0
- package/dist/types/src/cookieConsentManager.d.ts +7 -0
- package/package.json +1 -1
- package/src/batchUploader.ts +39 -5
- package/src/constants.ts +5 -0
- package/src/cookieConsentManager.ts +23 -0
- package/src/identity.js +9 -0
- package/src/mp-instance.ts +11 -0
- package/src/store.ts +7 -0
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.
|
|
18
|
+
var version = "2.65.0";
|
|
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
|
|
@@ -27,7 +27,10 @@ CaptureIntegrationSpecificIds:"captureIntegrationSpecificIds",// CaptureIntegrat
|
|
|
27
27
|
// - 'all' → capture all IDs
|
|
28
28
|
// - 'none' → capture none
|
|
29
29
|
// - 'roktonly' → capture only Rokt-related IDs
|
|
30
|
-
CaptureIntegrationSpecificIdsV2:"captureIntegrationSpecificIds.V2",AstBackgroundEvents:"astBackgroundEvents"},DefaultInstance:"default_instance",CCPAPurpose:"data_sale_opt_out",IdentityMethods:{Modify:"modify",Logout:"logout",Login:"login",Identify:"identify"},Environment:{Development:"development",Production:"production"},CaptureIntegrationSpecificIdsV2Modes:{All:"all",None:"none",RoktOnly:"roktonly"},Rokt:{LauncherInstanceGuidKey:"__rokt_li_guid__"}};var ONE_DAY_IN_SECONDS=86400;var MILLIS_IN_ONE_SEC=1e3;//
|
|
30
|
+
CaptureIntegrationSpecificIdsV2:"captureIntegrationSpecificIds.V2",AstBackgroundEvents:"astBackgroundEvents"},DefaultInstance:"default_instance",CCPAPurpose:"data_sale_opt_out",IdentityMethods:{Modify:"modify",Logout:"logout",Login:"login",Identify:"identify"},Environment:{Development:"development",Production:"production"},CaptureIntegrationSpecificIdsV2Modes:{All:"all",None:"none",RoktOnly:"roktonly"},Rokt:{LauncherInstanceGuidKey:"__rokt_li_guid__"}};var ONE_DAY_IN_SECONDS=86400;var MILLIS_IN_ONE_SEC=1e3;// User attribute set when the end user opts out of ad targeting via
|
|
31
|
+
// launcherOptions.noTargeting. Server-side systems use this attribute
|
|
32
|
+
// to exclude the user from retargeting audiences.
|
|
33
|
+
var NO_TARGETING_ATTRIBUTE="$NoTargeting";// https://developer.mozilla.org/en-US/docs/Web/HTTP/Status
|
|
31
34
|
var HTTP_OK=200;var HTTP_ACCEPTED=202;var HTTP_BAD_REQUEST=400;var HTTP_SERVER_ERROR=500;
|
|
32
35
|
|
|
33
36
|
function _typeof$1(o) {
|
|
@@ -487,8 +490,11 @@ function appendUserInfo(a,b){if(b){if(!a)return b.MPID=null,b.ConsentState=null,
|
|
|
487
490
|
* Creates an instance of a BatchUploader
|
|
488
491
|
* @param {IMParticleWebSDKInstance} mpInstance - the mParticle SDK instance
|
|
489
492
|
* @param {number} uploadInterval - the desired upload interval in milliseconds
|
|
490
|
-
*/function a(b,c){var d,e;this.offlineStorageEnabled=!1,this.lastASTEventTime=0,this.AST_DEBOUNCE_MS=1e3,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
|
|
491
|
-
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();}
|
|
493
|
+
*/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
|
|
494
|
+
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();}/**
|
|
495
|
+
* Cleans up timers and event listeners to prevent leaks when the SDK
|
|
496
|
+
* is re-initialized (e.g. between tests or on repeated init calls).
|
|
497
|
+
*/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
|
|
492
498
|
// TODO: Handle cases where Local Storage is unavailable
|
|
493
499
|
// Potentially shared between Vault and Persistence as well
|
|
494
500
|
// https://go.mparticle.com/work/SQDSDKS-5022
|
|
@@ -496,9 +502,9 @@ return e>=f},a.prototype.shouldDebounceAndUpdateLastASTTime=function(){var a=Dat
|
|
|
496
502
|
if(s){this.mpInstance._IntegrationCapture.capture();var t=this.mpInstance._IntegrationCapture.getClickIdsAsCustomFlags();o=__assign(__assign({},t),o);var u=this.mpInstance._IntegrationCapture.getClickIdsAsIntegrationAttributes();p=__assign(__assign({},u),p);}return n.CustomFlags=o,n.IntegrationAttributes=p,appendUserInfo(m(),n),n},a.prototype.addEventListeners=function(){var a=this,b=this,c=function(){// Check for debounce before creating and queueing event
|
|
497
503
|
var c=a.mpInstance._Helpers.getFeatureFlag,d=Constants.FeatureFlags.AstBackgroundEvents;if(c(d)){if(b.shouldDebounceAndUpdateLastASTTime())return;// Add application state transition event to queue
|
|
498
504
|
var e=b.createBackgroundASTEvent();b.queueEvent(e);}// Then trigger the upload with beacon
|
|
499
|
-
b.prepareAndUpload(!1,b.isBeaconAvailable());};
|
|
505
|
+
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
|
|
500
506
|
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.
|
|
501
|
-
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);if(u)try{c._Forwarders.sendBatchToForwarders(u);}catch(a){c.Logger.error("Error forwarding batch to kits. ".concat(a));}var 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.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
|
|
507
|
+
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);if(u)try{c._Forwarders.sendBatchToForwarders(u);}catch(a){c.Logger.error("Error forwarding batch to kits. ".concat(a));}var 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
|
|
502
508
|
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.
|
|
503
509
|
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)}();
|
|
504
510
|
|
|
@@ -632,9 +638,12 @@ function processFlags(a){var b={},c=Constants.FeatureFlags,d=c.ReportBatching,e=
|
|
|
632
638
|
// Passed in config flags take priority over defaults
|
|
633
639
|
}function processBaseUrls(a,b,c){// an API key is not present in a webview only mode. In this case, no baseUrls are needed
|
|
634
640
|
if(!c)return {};// Set default baseUrls
|
|
635
|
-
//
|
|
641
|
+
// A CNAME (config.domain, e.g. set by the snippet v2.6+) takes precedence
|
|
642
|
+
// over direct URL routing so that customer-configured first-party domains
|
|
643
|
+
// and the snippet's fallback domain are always honored.
|
|
644
|
+
return isEmpty(a.domain)?b.directURLRouting?processDirectBaseUrls(a,c):processCustomBaseUrls(a):processCustomBaseUrls(a);// When direct URL routing is false, update baseUrls based custom urls
|
|
636
645
|
// passed to the config
|
|
637
|
-
|
|
646
|
+
}function processCustomBaseUrls(a){var b=Constants.DefaultBaseUrls,c=Constants.CNAMEUrlPaths,d={};// newBaseUrls are default if the customer is not using a CNAME
|
|
638
647
|
// If a customer passes either config.domain or config.v3SecureServiceUrl,
|
|
639
648
|
// config.identityUrl, etc, the customer is using a CNAME.
|
|
640
649
|
// config.domain will take priority if a customer passes both.
|
|
@@ -1334,8 +1343,12 @@ return a._Helpers.getFeatureFlag(FeatureFlags$1.AudienceAPI)?void(null===d.audie
|
|
|
1334
1343
|
* @method getCartProducts
|
|
1335
1344
|
* @return {Array} array of cart products
|
|
1336
1345
|
* @deprecated
|
|
1337
|
-
*/getCartProducts:function getCartProducts(){return a.Logger.warning(generateDeprecationMessage("Identity.getCurrentUser().getCart().getCartProducts()",!0,"eCommerce.logProductAction()","https://docs.mparticle.com/developers/sdk/web/commerce-tracking")),[]}}},this.parseIdentityResponse=function(b,d,f,g,h,i,j){var k,l,m,n=a.Identity.getUser(d),o=n?n.getMPID():null,p=n?n.getUserIdentities().userIdentities:{},q={};a._Store.identityCallInFlight=!1;try{var r,s,t;if(a.Logger.verbose("Parsing \""+h+"\" identity response from server"),l=null!==(r=b.responseText)&&void 0!==r?r:null,a._Store.isLoggedIn=(null===(s=l)||void 0===s?void 0:s.is_logged_in)||!1,hasMPIDChanged(n,l)&&(a._Store.mpid=l.mpid,n&&a._Persistence.setLastSeenTime(d),k=!a._Persistence.getFirstSeenTime(l.mpid),a._Persistence.setFirstSeenTime(l.mpid)),b.status===HTTP_OK){c(CacheIdentity)&&cacheOrClearIdCache(h,i,e.idCache,b,j);var
|
|
1338
|
-
|
|
1346
|
+
*/getCartProducts:function getCartProducts(){return a.Logger.warning(generateDeprecationMessage("Identity.getCurrentUser().getCart().getCartProducts()",!0,"eCommerce.logProductAction()","https://docs.mparticle.com/developers/sdk/web/commerce-tracking")),[]}}},this.parseIdentityResponse=function(b,d,f,g,h,i,j){var k,l,m,n=a.Identity.getUser(d),o=n?n.getMPID():null,p=n?n.getUserIdentities().userIdentities:{},q={};a._Store.identityCallInFlight=!1;try{var r,s,t;if(a.Logger.verbose("Parsing \""+h+"\" identity response from server"),l=null!==(r=b.responseText)&&void 0!==r?r:null,a._Store.isLoggedIn=(null===(s=l)||void 0===s?void 0:s.is_logged_in)||!1,hasMPIDChanged(n,l)&&(a._Store.mpid=l.mpid,n&&a._Persistence.setLastSeenTime(d),k=!a._Persistence.getFirstSeenTime(l.mpid),a._Persistence.setFirstSeenTime(l.mpid)),b.status===HTTP_OK){var u;c(CacheIdentity)&&cacheOrClearIdCache(h,i,e.idCache,b,j);var v=e.IdentityAPI.getUser(l.mpid),w=v?v.getUserIdentities().userIdentities:{};h===Modify$1?(q=a._Identity.IdentityRequest.combineUserIdentities(p,g.userIdentities),a._Store.setUserIdentities(d,q)):(h===Identify&&n&&l.mpid===o&&a._Persistence.setFirstSeenTime(l.mpid),a._Store.addMpidToSessionHistory(l.mpid,d),a._CookieSyncManager.attemptCookieSync(l.mpid,k),a._Persistence.swapCurrentUser(d,l.mpid,a._Store.currentSessionMPIDs),g&&!isEmpty(g.userIdentities)&&(q=e.IdentityRequest.combineUserIdentities(w,g.userIdentities)),a._Store.setUserIdentities(l.mpid,q),a._Persistence.update(),a._Store.syncPersistenceData(),a._Persistence.findPrevCookiesBasedOnUI(g),a._Store.context=l.context||a._Store.context),m=a.Identity.getCurrentUser(),tryOnUserAlias(n,m,g,a.Logger);var x=a._Persistence.getPersistence();m&&(a._Persistence.storeDataInMemory(x,m.getMPID()),e.reinitForwardersOnUserChange(n,m),e.setForwarderCallbacks(m,h));var y=IdentityType.getNewIdentitiesByName(q),z=h===Modify$1?p:w;// Sync $NoTargeting before sendUserIdentityChangeEvent
|
|
1347
|
+
// because UIC events call sendEventToServer which triggers
|
|
1348
|
+
// processQueuedEvents, draining the event queue. The
|
|
1349
|
+
// attribute must be in the store before that happens so
|
|
1350
|
+
// appendUserInfo picks it up.
|
|
1351
|
+
null===(u=a._CookieConsentManager)||void 0===u||u.syncNoTargetingAttribute(m),e.sendUserIdentityChangeEvent(y,h,l.mpid,z);}if(f){var A=0===b.status?HTTPCodes$2.noHttpCoverage:b.status;a._Helpers.invokeCallback(f,A,l||null,m);}else l&&!isEmpty(l.errors)&&// https://go.mparticle.com/work/SQDSDKS-6500
|
|
1339
1352
|
a.Logger.error("Received HTTP response code of "+b.status+" - "+l.errors[0].message);a.Logger.verbose("Successfully parsed Identity Response"),null===(t=a._APIClient)||void 0===t||t.processQueuedEvents();}catch(c){f&&a._Helpers.invokeCallback(f,b.status,l||null),a.Logger.error("Error parsing JSON response from Identity server: "+c);}a._Store.isInitialized=!0,a._RoktManager.onIdentityComplete(),a._preInit.readyQueue=processReadyQueue(a._preInit.readyQueue);},this.sendUserIdentityChangeEvent=function(b,c,d,f){if(d||c===Modify$1)// https://go.mparticle.com/work/SQDSDKS-6501
|
|
1340
1353
|
{// https://go.mparticle.com/work/SQDSDKS-6354
|
|
1341
1354
|
var g=this.IdentityAPI.getUser(d);for(var h in b)// Verifies a change actually happened
|
|
@@ -1520,7 +1533,7 @@ Promise.resolve(k).then(function(a){h&&h(a);})["catch"](j);}catch(a){j(a);}});}}
|
|
|
1520
1533
|
*/var CookieConsentManager=/** @class */function(){function a(a){this.flags=a,this.flags={noFunctional:!0===a.noFunctional,noTargeting:!0===a.noTargeting};}/**
|
|
1521
1534
|
* Returns true if third-party targeting is disabled.
|
|
1522
1535
|
* Targeting is allowed when noTargeting is false (default).
|
|
1523
|
-
*/return a.prototype.getNoTargeting=function(){return this.flags.noTargeting},a.prototype.getNoFunctional=function(){return this.flags.noFunctional},a}();
|
|
1536
|
+
*/return a.prototype.getNoTargeting=function(){return this.flags.noTargeting},a.prototype.getNoFunctional=function(){return this.flags.noFunctional},a.prototype.syncNoTargetingAttribute=function(a){a&&(this.flags.noTargeting?a.setUserAttribute(NO_TARGETING_ATTRIBUTE,!0):a.getAllUserAttributes().hasOwnProperty(NO_TARGETING_ATTRIBUTE)&&a.removeUserAttribute(NO_TARGETING_ATTRIBUTE));},a}();
|
|
1524
1537
|
|
|
1525
1538
|
var ErrorReportingDispatcher=/** @class */function(){function a(){this.services=[];}return a.prototype.register=function(a){this.services.push(a);},a.prototype.report=function(a){var b=this;this.services.forEach(function(c){var d;try{c.report(a);}catch(a){null===(d=b.logger)||void 0===d?void 0:d.error("Error in ErrorReportingService: "+a);}});},a}();
|
|
1526
1539
|
|
|
@@ -1694,17 +1707,18 @@ if(b._Helpers.canLog()){if(!b._Helpers.Validators.isValidAttributeValue(c))retur
|
|
|
1694
1707
|
if(b._preInit.integrationDelays[a]=c,!0!==c){// If the integration delay is set to false, check to see if there are any
|
|
1695
1708
|
// other integration delays set to true. It not, process the queued events/.
|
|
1696
1709
|
var d=Object.keys(b._preInit.integrationDelays);if(0!==d.length){var e=d.some(function(a){return !0===b._preInit.integrationDelays[a]});e||b._APIClient.processQueuedEvents();}}},this._setWrapperSDKInfo=function(a,c){var d=queueIfNotInitialized(function(){b._setWrapperSDKInfo(a,c);},b);d||(b._Store.wrapperSDKInfo===void 0||!b._Store.wrapperSDKInfo.isInfoSet)&&(b._Store.wrapperSDKInfo={name:a,version:c,isInfoSet:!0});},this._registerErrorReportingService=function(a){b._ErrorReportingDispatcher.register(a);},this._registerLoggingService=function(a){b._LoggingDispatcher.register(a);};var c=Constants.Rokt.LauncherInstanceGuidKey;this.setLauncherInstanceGuid=function(){window[c]&&"string"==typeof window[c]||(window[c]=b._Helpers.generateUniqueId());},this.getLauncherInstanceGuid=function(){return window[c]},this.captureTiming=function(a){var b;"undefined"!=typeof window&&(null===(b=window.performance)||void 0===b?void 0:b.mark)&&window.performance.mark(a);};}// Some (server) config settings need to be returned before they are set on SDKConfig in a self hosted environment
|
|
1697
|
-
function completeSDKInitialization(a,b,c){var d,e,f=createKitBlocker(b,c),
|
|
1710
|
+
function completeSDKInitialization(a,b,c){var d,e,f,g,h=createKitBlocker(b,c),i=c._Helpers.getFeatureFlag;// Destroy previous batch uploader to prevent leaked timers and event listeners
|
|
1711
|
+
// Web View Bridge is used for cases where the Web SDK is loaded within an iOS or Android device's
|
|
1698
1712
|
// Web View. The Web SDK simply acts as a passthrough to the mParticle Native SDK. It is not
|
|
1699
1713
|
// responsible for sending events directly to mParticle's servers. The Web SDK will not initialize
|
|
1700
1714
|
// persistence or Identity directly.
|
|
1701
|
-
if(c._APIClient=new APIClient(c,
|
|
1702
|
-
var
|
|
1703
|
-
var
|
|
1704
|
-
var
|
|
1705
|
-
c._RoktManager.init(
|
|
1715
|
+
if((null===(d=c._APIClient)||void 0===d?void 0:d.uploader)&&c._APIClient.uploader.destroy(),c._APIClient=new APIClient(c,h),c._Forwarders=new Forwarders(c,h),c._Store.processConfig(b),c._Identity.idCache=createIdentityCache(c),removeExpiredIdentityCacheDates(c._Identity.idCache),c._Store.webviewBridgeEnabled)c._NativeSdkHelpers.initializeSessionAttributes(a);else {c._Persistence.initializeStorage(),c._Store.syncPersistenceData();// Set up user identitiy variables for later use
|
|
1716
|
+
var j=c.Identity.getCurrentUser(),k=j?j.getMPID():null,l=j?j.getUserIdentities().userIdentities:{};c._Store.SDKConfig.identifyRequest=c._Store.hasInvalidIdentifyRequest()?{userIdentities:l}:c._Store.SDKConfig.identifyRequest,i(ReportBatching)&&c._ForwardingStatsUploader.startForwardingStatsTimer();// https://go.mparticle.com/work/SQDSDKS-7639
|
|
1717
|
+
var m=i(CaptureIntegrationSpecificIds),n=i(CaptureIntegrationSpecificIdsV2),o=n&&n!==CaptureIntegrationSpecificIdsV2Modes.None||!0===m;if(o){var p;m||n===CaptureIntegrationSpecificIdsV2Modes.All?p="all":n===CaptureIntegrationSpecificIdsV2Modes.RoktOnly&&(p="roktonly"),c._IntegrationCapture=new IntegrationCapture(p),c._IntegrationCapture.capture();}// Configure Rokt Manager with user and filtered user
|
|
1718
|
+
var q=parseConfig(b,"Rokt",181);if(q){var r=null===(e=q.settings)||void 0===e?void 0:e.accountId;c._Store.setRoktAccountId(r);var s=q.userAttributeFilters,t=filteredMparticleUser(k,{userAttributeFilters:s},c),u={sandbox:null===b||void 0===b?void 0:b.isDevelopmentMode,launcherOptions:null===b||void 0===b?void 0:b.launcherOptions,domain:null===b||void 0===b?void 0:b.domain};// https://go.mparticle.com/work/SQDSDKS-7339
|
|
1719
|
+
c._RoktManager.init(q,t,c.Identity,c._Store,c.Logger,u,c.captureTiming,c._ErrorReportingDispatcher,c._LoggingDispatcher);}c._Forwarders.processForwarders(b,c._APIClient.prepareForwardingStats),c._Forwarders.processPixelConfigs(b),c._SessionManager.initialize(),c._Events.logAST(),processIdentityCallback(c,j,k,l);}// We will continue to clear out the ready queue as part of the initial init flow
|
|
1706
1720
|
// if an identify request is unnecessary, such as if there is an existing session
|
|
1707
|
-
(c._Store.mpid&&!c._Store.identifyCalled||c._Store.webviewBridgeEnabled)&&(c._Store.isInitialized=!0,c._preInit.readyQueue=processReadyQueue(c._preInit.readyQueue)),null===(
|
|
1721
|
+
(c._Store.mpid&&!c._Store.identifyCalled||c._Store.webviewBridgeEnabled)&&(c._Store.isInitialized=!0,null===(f=c._CookieConsentManager)||void 0===f?void 0:f.syncNoTargetingAttribute(c.Identity.getCurrentUser()),c._preInit.readyQueue=processReadyQueue(c._preInit.readyQueue)),null===(g=c.processQueueOnNoFunctional)||void 0===g?void 0:g.call(c),c._Store.isFirstRun&&(c._Store.isFirstRun=!1);}// https://go.mparticle.com/work/SQDSDKS-7061
|
|
1708
1722
|
function createKitBlocker(a,b){var c,d,e,f;/* There are three ways a data plan object for blocking can be passed to the SDK:
|
|
1709
1723
|
1. Manually via config.dataPlanOptions (this takes priority)
|
|
1710
1724
|
If not passed in manually, we user the server provided via either
|
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.
|
|
18
|
+
var version = "2.65.0";
|
|
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
|
|
@@ -27,7 +27,10 @@ CaptureIntegrationSpecificIds:"captureIntegrationSpecificIds",// CaptureIntegrat
|
|
|
27
27
|
// - 'all' → capture all IDs
|
|
28
28
|
// - 'none' → capture none
|
|
29
29
|
// - 'roktonly' → capture only Rokt-related IDs
|
|
30
|
-
CaptureIntegrationSpecificIdsV2:"captureIntegrationSpecificIds.V2",AstBackgroundEvents:"astBackgroundEvents"},DefaultInstance:"default_instance",CCPAPurpose:"data_sale_opt_out",IdentityMethods:{Modify:"modify",Logout:"logout",Login:"login",Identify:"identify"},Environment:{Development:"development",Production:"production"},CaptureIntegrationSpecificIdsV2Modes:{All:"all",None:"none",RoktOnly:"roktonly"},Rokt:{LauncherInstanceGuidKey:"__rokt_li_guid__"}};var ONE_DAY_IN_SECONDS=86400;var MILLIS_IN_ONE_SEC=1e3;//
|
|
30
|
+
CaptureIntegrationSpecificIdsV2:"captureIntegrationSpecificIds.V2",AstBackgroundEvents:"astBackgroundEvents"},DefaultInstance:"default_instance",CCPAPurpose:"data_sale_opt_out",IdentityMethods:{Modify:"modify",Logout:"logout",Login:"login",Identify:"identify"},Environment:{Development:"development",Production:"production"},CaptureIntegrationSpecificIdsV2Modes:{All:"all",None:"none",RoktOnly:"roktonly"},Rokt:{LauncherInstanceGuidKey:"__rokt_li_guid__"}};var ONE_DAY_IN_SECONDS=86400;var MILLIS_IN_ONE_SEC=1e3;// User attribute set when the end user opts out of ad targeting via
|
|
31
|
+
// launcherOptions.noTargeting. Server-side systems use this attribute
|
|
32
|
+
// to exclude the user from retargeting audiences.
|
|
33
|
+
var NO_TARGETING_ATTRIBUTE="$NoTargeting";// https://developer.mozilla.org/en-US/docs/Web/HTTP/Status
|
|
31
34
|
var HTTP_OK=200;var HTTP_ACCEPTED=202;var HTTP_BAD_REQUEST=400;var HTTP_SERVER_ERROR=500;
|
|
32
35
|
|
|
33
36
|
function _typeof$1(o) {
|
|
@@ -487,8 +490,11 @@ function appendUserInfo(a,b){if(b){if(!a)return b.MPID=null,b.ConsentState=null,
|
|
|
487
490
|
* Creates an instance of a BatchUploader
|
|
488
491
|
* @param {IMParticleWebSDKInstance} mpInstance - the mParticle SDK instance
|
|
489
492
|
* @param {number} uploadInterval - the desired upload interval in milliseconds
|
|
490
|
-
*/function a(b,c){var d,e;this.offlineStorageEnabled=!1,this.lastASTEventTime=0,this.AST_DEBOUNCE_MS=1e3,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
|
|
491
|
-
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();}
|
|
493
|
+
*/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
|
|
494
|
+
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();}/**
|
|
495
|
+
* Cleans up timers and event listeners to prevent leaks when the SDK
|
|
496
|
+
* is re-initialized (e.g. between tests or on repeated init calls).
|
|
497
|
+
*/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
|
|
492
498
|
// TODO: Handle cases where Local Storage is unavailable
|
|
493
499
|
// Potentially shared between Vault and Persistence as well
|
|
494
500
|
// https://go.mparticle.com/work/SQDSDKS-5022
|
|
@@ -496,9 +502,9 @@ return e>=f},a.prototype.shouldDebounceAndUpdateLastASTTime=function(){var a=Dat
|
|
|
496
502
|
if(s){this.mpInstance._IntegrationCapture.capture();var t=this.mpInstance._IntegrationCapture.getClickIdsAsCustomFlags();o=__assign(__assign({},t),o);var u=this.mpInstance._IntegrationCapture.getClickIdsAsIntegrationAttributes();p=__assign(__assign({},u),p);}return n.CustomFlags=o,n.IntegrationAttributes=p,appendUserInfo(m(),n),n},a.prototype.addEventListeners=function(){var a=this,b=this,c=function(){// Check for debounce before creating and queueing event
|
|
497
503
|
var c=a.mpInstance._Helpers.getFeatureFlag,d=Constants.FeatureFlags.AstBackgroundEvents;if(c(d)){if(b.shouldDebounceAndUpdateLastASTTime())return;// Add application state transition event to queue
|
|
498
504
|
var e=b.createBackgroundASTEvent();b.queueEvent(e);}// Then trigger the upload with beacon
|
|
499
|
-
b.prepareAndUpload(!1,b.isBeaconAvailable());};
|
|
505
|
+
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
|
|
500
506
|
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.
|
|
501
|
-
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);if(u)try{c._Forwarders.sendBatchToForwarders(u);}catch(a){c.Logger.error("Error forwarding batch to kits. ".concat(a));}var 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.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
|
|
507
|
+
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);if(u)try{c._Forwarders.sendBatchToForwarders(u);}catch(a){c.Logger.error("Error forwarding batch to kits. ".concat(a));}var 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
|
|
502
508
|
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.
|
|
503
509
|
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)}();
|
|
504
510
|
|
|
@@ -632,9 +638,12 @@ function processFlags(a){var b={},c=Constants.FeatureFlags,d=c.ReportBatching,e=
|
|
|
632
638
|
// Passed in config flags take priority over defaults
|
|
633
639
|
}function processBaseUrls(a,b,c){// an API key is not present in a webview only mode. In this case, no baseUrls are needed
|
|
634
640
|
if(!c)return {};// Set default baseUrls
|
|
635
|
-
//
|
|
641
|
+
// A CNAME (config.domain, e.g. set by the snippet v2.6+) takes precedence
|
|
642
|
+
// over direct URL routing so that customer-configured first-party domains
|
|
643
|
+
// and the snippet's fallback domain are always honored.
|
|
644
|
+
return isEmpty(a.domain)?b.directURLRouting?processDirectBaseUrls(a,c):processCustomBaseUrls(a):processCustomBaseUrls(a);// When direct URL routing is false, update baseUrls based custom urls
|
|
636
645
|
// passed to the config
|
|
637
|
-
|
|
646
|
+
}function processCustomBaseUrls(a){var b=Constants.DefaultBaseUrls,c=Constants.CNAMEUrlPaths,d={};// newBaseUrls are default if the customer is not using a CNAME
|
|
638
647
|
// If a customer passes either config.domain or config.v3SecureServiceUrl,
|
|
639
648
|
// config.identityUrl, etc, the customer is using a CNAME.
|
|
640
649
|
// config.domain will take priority if a customer passes both.
|
|
@@ -1334,8 +1343,12 @@ return a._Helpers.getFeatureFlag(FeatureFlags$1.AudienceAPI)?void(null===d.audie
|
|
|
1334
1343
|
* @method getCartProducts
|
|
1335
1344
|
* @return {Array} array of cart products
|
|
1336
1345
|
* @deprecated
|
|
1337
|
-
*/getCartProducts:function getCartProducts(){return a.Logger.warning(generateDeprecationMessage("Identity.getCurrentUser().getCart().getCartProducts()",!0,"eCommerce.logProductAction()","https://docs.mparticle.com/developers/sdk/web/commerce-tracking")),[]}}},this.parseIdentityResponse=function(b,d,f,g,h,i,j){var k,l,m,n=a.Identity.getUser(d),o=n?n.getMPID():null,p=n?n.getUserIdentities().userIdentities:{},q={};a._Store.identityCallInFlight=!1;try{var r,s,t;if(a.Logger.verbose("Parsing \""+h+"\" identity response from server"),l=null!==(r=b.responseText)&&void 0!==r?r:null,a._Store.isLoggedIn=(null===(s=l)||void 0===s?void 0:s.is_logged_in)||!1,hasMPIDChanged(n,l)&&(a._Store.mpid=l.mpid,n&&a._Persistence.setLastSeenTime(d),k=!a._Persistence.getFirstSeenTime(l.mpid),a._Persistence.setFirstSeenTime(l.mpid)),b.status===HTTP_OK){c(CacheIdentity)&&cacheOrClearIdCache(h,i,e.idCache,b,j);var
|
|
1338
|
-
|
|
1346
|
+
*/getCartProducts:function getCartProducts(){return a.Logger.warning(generateDeprecationMessage("Identity.getCurrentUser().getCart().getCartProducts()",!0,"eCommerce.logProductAction()","https://docs.mparticle.com/developers/sdk/web/commerce-tracking")),[]}}},this.parseIdentityResponse=function(b,d,f,g,h,i,j){var k,l,m,n=a.Identity.getUser(d),o=n?n.getMPID():null,p=n?n.getUserIdentities().userIdentities:{},q={};a._Store.identityCallInFlight=!1;try{var r,s,t;if(a.Logger.verbose("Parsing \""+h+"\" identity response from server"),l=null!==(r=b.responseText)&&void 0!==r?r:null,a._Store.isLoggedIn=(null===(s=l)||void 0===s?void 0:s.is_logged_in)||!1,hasMPIDChanged(n,l)&&(a._Store.mpid=l.mpid,n&&a._Persistence.setLastSeenTime(d),k=!a._Persistence.getFirstSeenTime(l.mpid),a._Persistence.setFirstSeenTime(l.mpid)),b.status===HTTP_OK){var u;c(CacheIdentity)&&cacheOrClearIdCache(h,i,e.idCache,b,j);var v=e.IdentityAPI.getUser(l.mpid),w=v?v.getUserIdentities().userIdentities:{};h===Modify$1?(q=a._Identity.IdentityRequest.combineUserIdentities(p,g.userIdentities),a._Store.setUserIdentities(d,q)):(h===Identify&&n&&l.mpid===o&&a._Persistence.setFirstSeenTime(l.mpid),a._Store.addMpidToSessionHistory(l.mpid,d),a._CookieSyncManager.attemptCookieSync(l.mpid,k),a._Persistence.swapCurrentUser(d,l.mpid,a._Store.currentSessionMPIDs),g&&!isEmpty(g.userIdentities)&&(q=e.IdentityRequest.combineUserIdentities(w,g.userIdentities)),a._Store.setUserIdentities(l.mpid,q),a._Persistence.update(),a._Store.syncPersistenceData(),a._Persistence.findPrevCookiesBasedOnUI(g),a._Store.context=l.context||a._Store.context),m=a.Identity.getCurrentUser(),tryOnUserAlias(n,m,g,a.Logger);var x=a._Persistence.getPersistence();m&&(a._Persistence.storeDataInMemory(x,m.getMPID()),e.reinitForwardersOnUserChange(n,m),e.setForwarderCallbacks(m,h));var y=IdentityType.getNewIdentitiesByName(q),z=h===Modify$1?p:w;// Sync $NoTargeting before sendUserIdentityChangeEvent
|
|
1347
|
+
// because UIC events call sendEventToServer which triggers
|
|
1348
|
+
// processQueuedEvents, draining the event queue. The
|
|
1349
|
+
// attribute must be in the store before that happens so
|
|
1350
|
+
// appendUserInfo picks it up.
|
|
1351
|
+
null===(u=a._CookieConsentManager)||void 0===u||u.syncNoTargetingAttribute(m),e.sendUserIdentityChangeEvent(y,h,l.mpid,z);}if(f){var A=0===b.status?HTTPCodes$2.noHttpCoverage:b.status;a._Helpers.invokeCallback(f,A,l||null,m);}else l&&!isEmpty(l.errors)&&// https://go.mparticle.com/work/SQDSDKS-6500
|
|
1339
1352
|
a.Logger.error("Received HTTP response code of "+b.status+" - "+l.errors[0].message);a.Logger.verbose("Successfully parsed Identity Response"),null===(t=a._APIClient)||void 0===t||t.processQueuedEvents();}catch(c){f&&a._Helpers.invokeCallback(f,b.status,l||null),a.Logger.error("Error parsing JSON response from Identity server: "+c);}a._Store.isInitialized=!0,a._RoktManager.onIdentityComplete(),a._preInit.readyQueue=processReadyQueue(a._preInit.readyQueue);},this.sendUserIdentityChangeEvent=function(b,c,d,f){if(d||c===Modify$1)// https://go.mparticle.com/work/SQDSDKS-6501
|
|
1340
1353
|
{// https://go.mparticle.com/work/SQDSDKS-6354
|
|
1341
1354
|
var g=this.IdentityAPI.getUser(d);for(var h in b)// Verifies a change actually happened
|
|
@@ -1520,7 +1533,7 @@ Promise.resolve(k).then(function(a){h&&h(a);})["catch"](j);}catch(a){j(a);}});}}
|
|
|
1520
1533
|
*/var CookieConsentManager=/** @class */function(){function a(a){this.flags=a,this.flags={noFunctional:!0===a.noFunctional,noTargeting:!0===a.noTargeting};}/**
|
|
1521
1534
|
* Returns true if third-party targeting is disabled.
|
|
1522
1535
|
* Targeting is allowed when noTargeting is false (default).
|
|
1523
|
-
*/return a.prototype.getNoTargeting=function(){return this.flags.noTargeting},a.prototype.getNoFunctional=function(){return this.flags.noFunctional},a}();
|
|
1536
|
+
*/return a.prototype.getNoTargeting=function(){return this.flags.noTargeting},a.prototype.getNoFunctional=function(){return this.flags.noFunctional},a.prototype.syncNoTargetingAttribute=function(a){a&&(this.flags.noTargeting?a.setUserAttribute(NO_TARGETING_ATTRIBUTE,!0):a.getAllUserAttributes().hasOwnProperty(NO_TARGETING_ATTRIBUTE)&&a.removeUserAttribute(NO_TARGETING_ATTRIBUTE));},a}();
|
|
1524
1537
|
|
|
1525
1538
|
var ErrorReportingDispatcher=/** @class */function(){function a(){this.services=[];}return a.prototype.register=function(a){this.services.push(a);},a.prototype.report=function(a){var b=this;this.services.forEach(function(c){var d;try{c.report(a);}catch(a){null===(d=b.logger)||void 0===d?void 0:d.error("Error in ErrorReportingService: "+a);}});},a}();
|
|
1526
1539
|
|
|
@@ -1694,17 +1707,18 @@ if(b._Helpers.canLog()){if(!b._Helpers.Validators.isValidAttributeValue(c))retur
|
|
|
1694
1707
|
if(b._preInit.integrationDelays[a]=c,!0!==c){// If the integration delay is set to false, check to see if there are any
|
|
1695
1708
|
// other integration delays set to true. It not, process the queued events/.
|
|
1696
1709
|
var d=Object.keys(b._preInit.integrationDelays);if(0!==d.length){var e=d.some(function(a){return !0===b._preInit.integrationDelays[a]});e||b._APIClient.processQueuedEvents();}}},this._setWrapperSDKInfo=function(a,c){var d=queueIfNotInitialized(function(){b._setWrapperSDKInfo(a,c);},b);d||(b._Store.wrapperSDKInfo===void 0||!b._Store.wrapperSDKInfo.isInfoSet)&&(b._Store.wrapperSDKInfo={name:a,version:c,isInfoSet:!0});},this._registerErrorReportingService=function(a){b._ErrorReportingDispatcher.register(a);},this._registerLoggingService=function(a){b._LoggingDispatcher.register(a);};var c=Constants.Rokt.LauncherInstanceGuidKey;this.setLauncherInstanceGuid=function(){window[c]&&"string"==typeof window[c]||(window[c]=b._Helpers.generateUniqueId());},this.getLauncherInstanceGuid=function(){return window[c]},this.captureTiming=function(a){var b;"undefined"!=typeof window&&(null===(b=window.performance)||void 0===b?void 0:b.mark)&&window.performance.mark(a);};}// Some (server) config settings need to be returned before they are set on SDKConfig in a self hosted environment
|
|
1697
|
-
function completeSDKInitialization(a,b,c){var d,e,f=createKitBlocker(b,c),
|
|
1710
|
+
function completeSDKInitialization(a,b,c){var d,e,f,g,h=createKitBlocker(b,c),i=c._Helpers.getFeatureFlag;// Destroy previous batch uploader to prevent leaked timers and event listeners
|
|
1711
|
+
// Web View Bridge is used for cases where the Web SDK is loaded within an iOS or Android device's
|
|
1698
1712
|
// Web View. The Web SDK simply acts as a passthrough to the mParticle Native SDK. It is not
|
|
1699
1713
|
// responsible for sending events directly to mParticle's servers. The Web SDK will not initialize
|
|
1700
1714
|
// persistence or Identity directly.
|
|
1701
|
-
if(c._APIClient=new APIClient(c,
|
|
1702
|
-
var
|
|
1703
|
-
var
|
|
1704
|
-
var
|
|
1705
|
-
c._RoktManager.init(
|
|
1715
|
+
if((null===(d=c._APIClient)||void 0===d?void 0:d.uploader)&&c._APIClient.uploader.destroy(),c._APIClient=new APIClient(c,h),c._Forwarders=new Forwarders(c,h),c._Store.processConfig(b),c._Identity.idCache=createIdentityCache(c),removeExpiredIdentityCacheDates(c._Identity.idCache),c._Store.webviewBridgeEnabled)c._NativeSdkHelpers.initializeSessionAttributes(a);else {c._Persistence.initializeStorage(),c._Store.syncPersistenceData();// Set up user identitiy variables for later use
|
|
1716
|
+
var j=c.Identity.getCurrentUser(),k=j?j.getMPID():null,l=j?j.getUserIdentities().userIdentities:{};c._Store.SDKConfig.identifyRequest=c._Store.hasInvalidIdentifyRequest()?{userIdentities:l}:c._Store.SDKConfig.identifyRequest,i(ReportBatching)&&c._ForwardingStatsUploader.startForwardingStatsTimer();// https://go.mparticle.com/work/SQDSDKS-7639
|
|
1717
|
+
var m=i(CaptureIntegrationSpecificIds),n=i(CaptureIntegrationSpecificIdsV2),o=n&&n!==CaptureIntegrationSpecificIdsV2Modes.None||!0===m;if(o){var p;m||n===CaptureIntegrationSpecificIdsV2Modes.All?p="all":n===CaptureIntegrationSpecificIdsV2Modes.RoktOnly&&(p="roktonly"),c._IntegrationCapture=new IntegrationCapture(p),c._IntegrationCapture.capture();}// Configure Rokt Manager with user and filtered user
|
|
1718
|
+
var q=parseConfig(b,"Rokt",181);if(q){var r=null===(e=q.settings)||void 0===e?void 0:e.accountId;c._Store.setRoktAccountId(r);var s=q.userAttributeFilters,t=filteredMparticleUser(k,{userAttributeFilters:s},c),u={sandbox:null===b||void 0===b?void 0:b.isDevelopmentMode,launcherOptions:null===b||void 0===b?void 0:b.launcherOptions,domain:null===b||void 0===b?void 0:b.domain};// https://go.mparticle.com/work/SQDSDKS-7339
|
|
1719
|
+
c._RoktManager.init(q,t,c.Identity,c._Store,c.Logger,u,c.captureTiming,c._ErrorReportingDispatcher,c._LoggingDispatcher);}c._Forwarders.processForwarders(b,c._APIClient.prepareForwardingStats),c._Forwarders.processPixelConfigs(b),c._SessionManager.initialize(),c._Events.logAST(),processIdentityCallback(c,j,k,l);}// We will continue to clear out the ready queue as part of the initial init flow
|
|
1706
1720
|
// if an identify request is unnecessary, such as if there is an existing session
|
|
1707
|
-
(c._Store.mpid&&!c._Store.identifyCalled||c._Store.webviewBridgeEnabled)&&(c._Store.isInitialized=!0,c._preInit.readyQueue=processReadyQueue(c._preInit.readyQueue)),null===(
|
|
1721
|
+
(c._Store.mpid&&!c._Store.identifyCalled||c._Store.webviewBridgeEnabled)&&(c._Store.isInitialized=!0,null===(f=c._CookieConsentManager)||void 0===f?void 0:f.syncNoTargetingAttribute(c.Identity.getCurrentUser()),c._preInit.readyQueue=processReadyQueue(c._preInit.readyQueue)),null===(g=c.processQueueOnNoFunctional)||void 0===g?void 0:g.call(c),c._Store.isFirstRun&&(c._Store.isFirstRun=!1);}// https://go.mparticle.com/work/SQDSDKS-7061
|
|
1708
1722
|
function createKitBlocker(a,b){var c,d,e,f;/* There are three ways a data plan object for blocking can be passed to the SDK:
|
|
1709
1723
|
1. Manually via config.dataPlanOptions (this takes priority)
|
|
1710
1724
|
If not passed in manually, we user the server provided via either
|
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.
|
|
206
|
+
var version = "2.65.0";
|
|
207
207
|
|
|
208
208
|
var Constants = {
|
|
209
209
|
sdkVersion: version,
|
|
@@ -409,6 +409,10 @@ var mParticle = (function () {
|
|
|
409
409
|
// https://go.mparticle.com/work/SQDSDKS-6080
|
|
410
410
|
var ONE_DAY_IN_SECONDS = 60 * 60 * 24;
|
|
411
411
|
var MILLIS_IN_ONE_SEC = 1000;
|
|
412
|
+
// User attribute set when the end user opts out of ad targeting via
|
|
413
|
+
// launcherOptions.noTargeting. Server-side systems use this attribute
|
|
414
|
+
// to exclude the user from retargeting audiences.
|
|
415
|
+
var NO_TARGETING_ATTRIBUTE = '$NoTargeting';
|
|
412
416
|
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Status
|
|
413
417
|
var HTTP_OK = 200;
|
|
414
418
|
var HTTP_ACCEPTED = 202;
|
|
@@ -2689,6 +2693,10 @@ var mParticle = (function () {
|
|
|
2689
2693
|
this.offlineStorageEnabled = false;
|
|
2690
2694
|
this.lastASTEventTime = 0;
|
|
2691
2695
|
this.AST_DEBOUNCE_MS = 1000; // 1 second debounce
|
|
2696
|
+
this.uploadIntervalTimerId = null;
|
|
2697
|
+
this.exitHandler = null;
|
|
2698
|
+
this.visibilityChangeHandler = null;
|
|
2699
|
+
this.destroyed = false;
|
|
2692
2700
|
this.mpInstance = mpInstance;
|
|
2693
2701
|
this.uploadIntervalMillis = uploadInterval;
|
|
2694
2702
|
this.batchingEnabled = uploadInterval >= BatchUploader.MINIMUM_INTERVAL_MILLIS;
|
|
@@ -2721,6 +2729,26 @@ var mParticle = (function () {
|
|
|
2721
2729
|
this.triggerUploadInterval(true, false);
|
|
2722
2730
|
this.addEventListeners();
|
|
2723
2731
|
}
|
|
2732
|
+
/**
|
|
2733
|
+
* Cleans up timers and event listeners to prevent leaks when the SDK
|
|
2734
|
+
* is re-initialized (e.g. between tests or on repeated init calls).
|
|
2735
|
+
*/
|
|
2736
|
+
BatchUploader.prototype.destroy = function () {
|
|
2737
|
+
this.destroyed = true;
|
|
2738
|
+
if (this.uploadIntervalTimerId !== null) {
|
|
2739
|
+
clearTimeout(this.uploadIntervalTimerId);
|
|
2740
|
+
this.uploadIntervalTimerId = null;
|
|
2741
|
+
}
|
|
2742
|
+
if (this.visibilityChangeHandler) {
|
|
2743
|
+
document.removeEventListener('visibilitychange', this.visibilityChangeHandler);
|
|
2744
|
+
}
|
|
2745
|
+
if (this.exitHandler) {
|
|
2746
|
+
window.removeEventListener('beforeunload', this.exitHandler);
|
|
2747
|
+
window.removeEventListener('pagehide', this.exitHandler);
|
|
2748
|
+
}
|
|
2749
|
+
this.exitHandler = null;
|
|
2750
|
+
this.visibilityChangeHandler = null;
|
|
2751
|
+
};
|
|
2724
2752
|
BatchUploader.prototype.isOfflineStorageAvailable = function () {
|
|
2725
2753
|
var _a = this.mpInstance,
|
|
2726
2754
|
getFeatureFlag = _a._Helpers.getFeatureFlag,
|
|
@@ -2816,12 +2844,14 @@ var mParticle = (function () {
|
|
|
2816
2844
|
// Then trigger the upload with beacon
|
|
2817
2845
|
_this.prepareAndUpload(false, _this.isBeaconAvailable());
|
|
2818
2846
|
};
|
|
2819
|
-
|
|
2820
|
-
|
|
2847
|
+
this.exitHandler = handleExit;
|
|
2848
|
+
this.visibilityChangeHandler = function () {
|
|
2821
2849
|
if (document.visibilityState === 'hidden') {
|
|
2822
2850
|
handleExit();
|
|
2823
2851
|
}
|
|
2824
|
-
}
|
|
2852
|
+
};
|
|
2853
|
+
// visibility change is a document property, not window
|
|
2854
|
+
document.addEventListener('visibilitychange', this.visibilityChangeHandler);
|
|
2825
2855
|
window.addEventListener('beforeunload', handleExit);
|
|
2826
2856
|
window.addEventListener('pagehide', handleExit);
|
|
2827
2857
|
};
|
|
@@ -2840,7 +2870,7 @@ var mParticle = (function () {
|
|
|
2840
2870
|
if (useBeacon === void 0) {
|
|
2841
2871
|
useBeacon = false;
|
|
2842
2872
|
}
|
|
2843
|
-
setTimeout(function () {
|
|
2873
|
+
this.uploadIntervalTimerId = setTimeout(function () {
|
|
2844
2874
|
_this_1.prepareAndUpload(triggerFuture, useBeacon);
|
|
2845
2875
|
}, this.uploadIntervalMillis);
|
|
2846
2876
|
};
|
|
@@ -3004,7 +3034,7 @@ var mParticle = (function () {
|
|
|
3004
3034
|
// Clear batch queue since everything should be in Offline Storage
|
|
3005
3035
|
this.batchesQueuedForProcessing = [];
|
|
3006
3036
|
}
|
|
3007
|
-
if (triggerFuture) {
|
|
3037
|
+
if (triggerFuture && !this.destroyed) {
|
|
3008
3038
|
this.triggerUploadInterval(triggerFuture, false);
|
|
3009
3039
|
}
|
|
3010
3040
|
return [2 /*return*/];
|
|
@@ -5108,6 +5138,12 @@ var mParticle = (function () {
|
|
|
5108
5138
|
if (!apiKey) {
|
|
5109
5139
|
return {};
|
|
5110
5140
|
}
|
|
5141
|
+
// A CNAME (config.domain, e.g. set by the snippet v2.6+) takes precedence
|
|
5142
|
+
// over direct URL routing so that customer-configured first-party domains
|
|
5143
|
+
// and the snippet's fallback domain are always honored.
|
|
5144
|
+
if (!isEmpty(config.domain)) {
|
|
5145
|
+
return processCustomBaseUrls(config);
|
|
5146
|
+
}
|
|
5111
5147
|
// When direct URL routing is false, update baseUrls based custom urls
|
|
5112
5148
|
// passed to the config
|
|
5113
5149
|
if (flags.directURLRouting) {
|
|
@@ -8555,6 +8591,7 @@ var mParticle = (function () {
|
|
|
8555
8591
|
mpInstance._Persistence.setFirstSeenTime(identityApiResult.mpid);
|
|
8556
8592
|
}
|
|
8557
8593
|
if (identityResponse.status === HTTP_OK) {
|
|
8594
|
+
var _mpInstance$_CookieCo;
|
|
8558
8595
|
if (getFeatureFlag(CacheIdentity)) {
|
|
8559
8596
|
cacheOrClearIdCache(method, knownIdentities, self.idCache, identityResponse, parsingCachedResponse);
|
|
8560
8597
|
}
|
|
@@ -8601,6 +8638,13 @@ var mParticle = (function () {
|
|
|
8601
8638
|
var newIdentitiesByName = IdentityType.getNewIdentitiesByName(newIdentitiesByType);
|
|
8602
8639
|
var uiByName = method === Modify$1 ? previousUIByName : incomingUIByName;
|
|
8603
8640
|
|
|
8641
|
+
// Sync $NoTargeting before sendUserIdentityChangeEvent
|
|
8642
|
+
// because UIC events call sendEventToServer which triggers
|
|
8643
|
+
// processQueuedEvents, draining the event queue. The
|
|
8644
|
+
// attribute must be in the store before that happens so
|
|
8645
|
+
// appendUserInfo picks it up.
|
|
8646
|
+
(_mpInstance$_CookieCo = mpInstance._CookieConsentManager) === null || _mpInstance$_CookieCo === void 0 || _mpInstance$_CookieCo.syncNoTargetingAttribute(newUser);
|
|
8647
|
+
|
|
8604
8648
|
// https://go.mparticle.com/work/SQDSDKS-6501
|
|
8605
8649
|
self.sendUserIdentityChangeEvent(newIdentitiesByName, method, identityApiResult.mpid, uiByName);
|
|
8606
8650
|
}
|
|
@@ -10683,6 +10727,14 @@ var mParticle = (function () {
|
|
|
10683
10727
|
CookieConsentManager.prototype.getNoFunctional = function () {
|
|
10684
10728
|
return this.flags.noFunctional;
|
|
10685
10729
|
};
|
|
10730
|
+
CookieConsentManager.prototype.syncNoTargetingAttribute = function (user) {
|
|
10731
|
+
if (!user) return;
|
|
10732
|
+
if (this.flags.noTargeting) {
|
|
10733
|
+
user.setUserAttribute(NO_TARGETING_ATTRIBUTE, true);
|
|
10734
|
+
} else if (user.getAllUserAttributes().hasOwnProperty(NO_TARGETING_ATTRIBUTE)) {
|
|
10735
|
+
user.removeUserAttribute(NO_TARGETING_ATTRIBUTE);
|
|
10736
|
+
}
|
|
10737
|
+
};
|
|
10686
10738
|
return CookieConsentManager;
|
|
10687
10739
|
}();
|
|
10688
10740
|
|
|
@@ -11716,9 +11768,13 @@ var mParticle = (function () {
|
|
|
11716
11768
|
}
|
|
11717
11769
|
// Some (server) config settings need to be returned before they are set on SDKConfig in a self hosted environment
|
|
11718
11770
|
function completeSDKInitialization(apiKey, config, mpInstance) {
|
|
11719
|
-
var _a, _b;
|
|
11771
|
+
var _a, _b, _c, _d;
|
|
11720
11772
|
var kitBlocker = createKitBlocker(config, mpInstance);
|
|
11721
11773
|
var getFeatureFlag = mpInstance._Helpers.getFeatureFlag;
|
|
11774
|
+
// Destroy previous batch uploader to prevent leaked timers and event listeners
|
|
11775
|
+
if ((_a = mpInstance._APIClient) === null || _a === void 0 ? void 0 : _a.uploader) {
|
|
11776
|
+
mpInstance._APIClient.uploader.destroy();
|
|
11777
|
+
}
|
|
11722
11778
|
mpInstance._APIClient = new APIClient(mpInstance, kitBlocker);
|
|
11723
11779
|
mpInstance._Forwarders = new Forwarders(mpInstance, kitBlocker);
|
|
11724
11780
|
mpInstance._Store.processConfig(config);
|
|
@@ -11762,7 +11818,7 @@ var mParticle = (function () {
|
|
|
11762
11818
|
// Configure Rokt Manager with user and filtered user
|
|
11763
11819
|
var roktConfig = parseConfig(config, 'Rokt', 181);
|
|
11764
11820
|
if (roktConfig) {
|
|
11765
|
-
var accountId = (
|
|
11821
|
+
var accountId = (_b = roktConfig.settings) === null || _b === void 0 ? void 0 : _b.accountId;
|
|
11766
11822
|
mpInstance._Store.setRoktAccountId(accountId);
|
|
11767
11823
|
var userAttributeFilters = roktConfig.userAttributeFilters;
|
|
11768
11824
|
var roktFilteredUser = filteredMparticleUser(currentUserMPID, {
|
|
@@ -11788,11 +11844,14 @@ var mParticle = (function () {
|
|
|
11788
11844
|
// if an identify request is unnecessary, such as if there is an existing session
|
|
11789
11845
|
if (mpInstance._Store.mpid && !mpInstance._Store.identifyCalled || mpInstance._Store.webviewBridgeEnabled) {
|
|
11790
11846
|
mpInstance._Store.isInitialized = true;
|
|
11847
|
+
// Sync $NoTargeting user attribute on re-init when no identity call is made
|
|
11848
|
+
// if for some reason there was a change in boolean between init calls
|
|
11849
|
+
(_c = mpInstance._CookieConsentManager) === null || _c === void 0 ? void 0 : _c.syncNoTargetingAttribute(mpInstance.Identity.getCurrentUser());
|
|
11791
11850
|
mpInstance._preInit.readyQueue = processReadyQueue(mpInstance._preInit.readyQueue);
|
|
11792
11851
|
}
|
|
11793
11852
|
// For noFunctional sessions with no identity, drain any pre-init ready callbacks
|
|
11794
11853
|
// that were queued before _CookieConsentManager was available to evaluate the condition.
|
|
11795
|
-
(
|
|
11854
|
+
(_d = mpInstance.processQueueOnNoFunctional) === null || _d === void 0 ? void 0 : _d.call(mpInstance);
|
|
11796
11855
|
// https://go.mparticle.com/work/SQDSDKS-6040
|
|
11797
11856
|
if (mpInstance._Store.isFirstRun) {
|
|
11798
11857
|
mpInstance._Store.isFirstRun = false;
|
|
@@ -31,12 +31,21 @@ export declare class BatchUploader {
|
|
|
31
31
|
private uploader;
|
|
32
32
|
private lastASTEventTime;
|
|
33
33
|
private readonly AST_DEBOUNCE_MS;
|
|
34
|
+
private uploadIntervalTimerId;
|
|
35
|
+
private exitHandler;
|
|
36
|
+
private visibilityChangeHandler;
|
|
37
|
+
private destroyed;
|
|
34
38
|
/**
|
|
35
39
|
* Creates an instance of a BatchUploader
|
|
36
40
|
* @param {IMParticleWebSDKInstance} mpInstance - the mParticle SDK instance
|
|
37
41
|
* @param {number} uploadInterval - the desired upload interval in milliseconds
|
|
38
42
|
*/
|
|
39
43
|
constructor(mpInstance: IMParticleWebSDKInstance, uploadInterval: number);
|
|
44
|
+
/**
|
|
45
|
+
* Cleans up timers and event listeners to prevent leaks when the SDK
|
|
46
|
+
* is re-initialized (e.g. between tests or on repeated init calls).
|
|
47
|
+
*/
|
|
48
|
+
destroy(): void;
|
|
40
49
|
private isOfflineStorageAvailable;
|
|
41
50
|
private shouldDebounceAndUpdateLastASTTime;
|
|
42
51
|
private createBackgroundASTEvent;
|
|
@@ -192,6 +192,7 @@ declare const Constants: {
|
|
|
192
192
|
export default Constants;
|
|
193
193
|
export declare const ONE_DAY_IN_SECONDS: number;
|
|
194
194
|
export declare const MILLIS_IN_ONE_SEC = 1000;
|
|
195
|
+
export declare const NO_TARGETING_ATTRIBUTE = "$NoTargeting";
|
|
195
196
|
export declare const HTTP_OK: 200;
|
|
196
197
|
export declare const HTTP_ACCEPTED: 202;
|
|
197
198
|
export declare const HTTP_BAD_REQUEST: 400;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { IMParticleUser } from './identity-user-interfaces';
|
|
1
2
|
/**
|
|
2
3
|
* Cookie consent flags control SDK behavior based on user consent preferences for Rokt integration.
|
|
3
4
|
* @see https://docs.rokt.com/developers/integration-guides/web/cookie-consent-flags/
|
|
@@ -24,6 +25,11 @@ export interface ICookieConsentManager {
|
|
|
24
25
|
* Functional tracking is allowed when noFunctional is false (default)
|
|
25
26
|
*/
|
|
26
27
|
getNoFunctional: () => boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Syncs the $NoTargeting user attribute based on the current noTargeting flag.
|
|
30
|
+
* Sets the attribute when noTargeting is true, removes it when false.
|
|
31
|
+
*/
|
|
32
|
+
syncNoTargetingAttribute: (user: IMParticleUser | null) => void;
|
|
27
33
|
}
|
|
28
34
|
/**
|
|
29
35
|
* CookieConsentManager handles storage and access of consent flags (noFunctional, noTargeting)
|
|
@@ -47,4 +53,5 @@ export default class CookieConsentManager implements ICookieConsentManager {
|
|
|
47
53
|
* Functional tracking is allowed when noFunctional is false (default).
|
|
48
54
|
*/
|
|
49
55
|
getNoFunctional(): boolean;
|
|
56
|
+
syncNoTargetingAttribute(user: IMParticleUser | null): void;
|
|
50
57
|
}
|
package/package.json
CHANGED
package/src/batchUploader.ts
CHANGED
|
@@ -47,6 +47,10 @@ export class BatchUploader {
|
|
|
47
47
|
private uploader: AsyncUploader;
|
|
48
48
|
private lastASTEventTime: number = 0;
|
|
49
49
|
private readonly AST_DEBOUNCE_MS: number = 1000; // 1 second debounce
|
|
50
|
+
private uploadIntervalTimerId: ReturnType<typeof setTimeout> | null = null;
|
|
51
|
+
private exitHandler: (() => void) | null = null;
|
|
52
|
+
private visibilityChangeHandler: (() => void) | null = null;
|
|
53
|
+
private destroyed = false;
|
|
50
54
|
|
|
51
55
|
/**
|
|
52
56
|
* Creates an instance of a BatchUploader
|
|
@@ -105,6 +109,31 @@ export class BatchUploader {
|
|
|
105
109
|
this.addEventListeners();
|
|
106
110
|
}
|
|
107
111
|
|
|
112
|
+
/**
|
|
113
|
+
* Cleans up timers and event listeners to prevent leaks when the SDK
|
|
114
|
+
* is re-initialized (e.g. between tests or on repeated init calls).
|
|
115
|
+
*/
|
|
116
|
+
public destroy(): void {
|
|
117
|
+
this.destroyed = true;
|
|
118
|
+
|
|
119
|
+
if (this.uploadIntervalTimerId !== null) {
|
|
120
|
+
clearTimeout(this.uploadIntervalTimerId);
|
|
121
|
+
this.uploadIntervalTimerId = null;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
if (this.visibilityChangeHandler) {
|
|
125
|
+
document.removeEventListener('visibilitychange', this.visibilityChangeHandler);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
if (this.exitHandler) {
|
|
129
|
+
window.removeEventListener('beforeunload', this.exitHandler);
|
|
130
|
+
window.removeEventListener('pagehide', this.exitHandler);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
this.exitHandler = null;
|
|
134
|
+
this.visibilityChangeHandler = null;
|
|
135
|
+
}
|
|
136
|
+
|
|
108
137
|
private isOfflineStorageAvailable(): boolean {
|
|
109
138
|
const {
|
|
110
139
|
_Helpers: { getFeatureFlag },
|
|
@@ -218,12 +247,17 @@ export class BatchUploader {
|
|
|
218
247
|
// Then trigger the upload with beacon
|
|
219
248
|
_this.prepareAndUpload(false, _this.isBeaconAvailable());
|
|
220
249
|
};
|
|
221
|
-
|
|
222
|
-
|
|
250
|
+
|
|
251
|
+
this.exitHandler = handleExit;
|
|
252
|
+
|
|
253
|
+
this.visibilityChangeHandler = () => {
|
|
223
254
|
if (document.visibilityState === 'hidden') {
|
|
224
255
|
handleExit();
|
|
225
256
|
}
|
|
226
|
-
}
|
|
257
|
+
};
|
|
258
|
+
|
|
259
|
+
// visibility change is a document property, not window
|
|
260
|
+
document.addEventListener('visibilitychange', this.visibilityChangeHandler);
|
|
227
261
|
window.addEventListener('beforeunload', handleExit);
|
|
228
262
|
window.addEventListener('pagehide', handleExit);
|
|
229
263
|
}
|
|
@@ -240,7 +274,7 @@ export class BatchUploader {
|
|
|
240
274
|
triggerFuture: boolean = false,
|
|
241
275
|
useBeacon: boolean = false
|
|
242
276
|
): void {
|
|
243
|
-
setTimeout(() => {
|
|
277
|
+
this.uploadIntervalTimerId = setTimeout(() => {
|
|
244
278
|
this.prepareAndUpload(triggerFuture, useBeacon);
|
|
245
279
|
}, this.uploadIntervalMillis);
|
|
246
280
|
}
|
|
@@ -445,7 +479,7 @@ export class BatchUploader {
|
|
|
445
479
|
this.batchesQueuedForProcessing = [];
|
|
446
480
|
}
|
|
447
481
|
|
|
448
|
-
if (triggerFuture) {
|
|
482
|
+
if (triggerFuture && !this.destroyed) {
|
|
449
483
|
this.triggerUploadInterval(triggerFuture, false);
|
|
450
484
|
}
|
|
451
485
|
}
|
package/src/constants.ts
CHANGED
|
@@ -225,6 +225,11 @@ export default Constants;
|
|
|
225
225
|
export const ONE_DAY_IN_SECONDS = 60 * 60 * 24;
|
|
226
226
|
export const MILLIS_IN_ONE_SEC = 1000;
|
|
227
227
|
|
|
228
|
+
// User attribute set when the end user opts out of ad targeting via
|
|
229
|
+
// launcherOptions.noTargeting. Server-side systems use this attribute
|
|
230
|
+
// to exclude the user from retargeting audiences.
|
|
231
|
+
export const NO_TARGETING_ATTRIBUTE = '$NoTargeting';
|
|
232
|
+
|
|
228
233
|
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Status
|
|
229
234
|
export const HTTP_OK = 200 as const;
|
|
230
235
|
export const HTTP_ACCEPTED = 202 as const;
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { NO_TARGETING_ATTRIBUTE } from './constants';
|
|
2
|
+
import { IMParticleUser } from './identity-user-interfaces';
|
|
3
|
+
|
|
1
4
|
/**
|
|
2
5
|
* Cookie consent flags control SDK behavior based on user consent preferences for Rokt integration.
|
|
3
6
|
* @see https://docs.rokt.com/developers/integration-guides/web/cookie-consent-flags/
|
|
@@ -27,6 +30,12 @@ export interface ICookieConsentManager {
|
|
|
27
30
|
* Functional tracking is allowed when noFunctional is false (default)
|
|
28
31
|
*/
|
|
29
32
|
getNoFunctional: () => boolean;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Syncs the $NoTargeting user attribute based on the current noTargeting flag.
|
|
36
|
+
* Sets the attribute when noTargeting is true, removes it when false.
|
|
37
|
+
*/
|
|
38
|
+
syncNoTargetingAttribute: (user: IMParticleUser | null) => void;
|
|
30
39
|
}
|
|
31
40
|
|
|
32
41
|
/**
|
|
@@ -61,4 +70,18 @@ export default class CookieConsentManager implements ICookieConsentManager {
|
|
|
61
70
|
getNoFunctional(): boolean {
|
|
62
71
|
return this.flags.noFunctional;
|
|
63
72
|
}
|
|
73
|
+
|
|
74
|
+
syncNoTargetingAttribute(user: IMParticleUser | null): void {
|
|
75
|
+
if (!user) return;
|
|
76
|
+
|
|
77
|
+
if (this.flags.noTargeting) {
|
|
78
|
+
user.setUserAttribute(NO_TARGETING_ATTRIBUTE, true);
|
|
79
|
+
} else if (
|
|
80
|
+
user
|
|
81
|
+
.getAllUserAttributes()
|
|
82
|
+
.hasOwnProperty(NO_TARGETING_ATTRIBUTE)
|
|
83
|
+
) {
|
|
84
|
+
user.removeUserAttribute(NO_TARGETING_ATTRIBUTE);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
64
87
|
}
|
package/src/identity.js
CHANGED
|
@@ -1524,6 +1524,15 @@ export default function Identity(mpInstance) {
|
|
|
1524
1524
|
const uiByName =
|
|
1525
1525
|
method === Modify ? previousUIByName : incomingUIByName;
|
|
1526
1526
|
|
|
1527
|
+
// Sync $NoTargeting before sendUserIdentityChangeEvent
|
|
1528
|
+
// because UIC events call sendEventToServer which triggers
|
|
1529
|
+
// processQueuedEvents, draining the event queue. The
|
|
1530
|
+
// attribute must be in the store before that happens so
|
|
1531
|
+
// appendUserInfo picks it up.
|
|
1532
|
+
mpInstance._CookieConsentManager?.syncNoTargetingAttribute(
|
|
1533
|
+
newUser
|
|
1534
|
+
);
|
|
1535
|
+
|
|
1527
1536
|
// https://go.mparticle.com/work/SQDSDKS-6501
|
|
1528
1537
|
self.sendUserIdentityChangeEvent(
|
|
1529
1538
|
newIdentitiesByName,
|
package/src/mp-instance.ts
CHANGED
|
@@ -1446,6 +1446,11 @@ function completeSDKInitialization(apiKey, config, mpInstance) {
|
|
|
1446
1446
|
const kitBlocker = createKitBlocker(config, mpInstance);
|
|
1447
1447
|
const { getFeatureFlag } = mpInstance._Helpers;
|
|
1448
1448
|
|
|
1449
|
+
// Destroy previous batch uploader to prevent leaked timers and event listeners
|
|
1450
|
+
if (mpInstance._APIClient?.uploader) {
|
|
1451
|
+
mpInstance._APIClient.uploader.destroy();
|
|
1452
|
+
}
|
|
1453
|
+
|
|
1449
1454
|
mpInstance._APIClient = new APIClient(mpInstance, kitBlocker);
|
|
1450
1455
|
mpInstance._Forwarders = new Forwarders(mpInstance, kitBlocker);
|
|
1451
1456
|
mpInstance._Store.processConfig(config);
|
|
@@ -1553,6 +1558,12 @@ function completeSDKInitialization(apiKey, config, mpInstance) {
|
|
|
1553
1558
|
) {
|
|
1554
1559
|
mpInstance._Store.isInitialized = true;
|
|
1555
1560
|
|
|
1561
|
+
// Sync $NoTargeting user attribute on re-init when no identity call is made
|
|
1562
|
+
// if for some reason there was a change in boolean between init calls
|
|
1563
|
+
mpInstance._CookieConsentManager?.syncNoTargetingAttribute(
|
|
1564
|
+
mpInstance.Identity.getCurrentUser()
|
|
1565
|
+
);
|
|
1566
|
+
|
|
1556
1567
|
mpInstance._preInit.readyQueue = processReadyQueue(
|
|
1557
1568
|
mpInstance._preInit.readyQueue
|
|
1558
1569
|
);
|
package/src/store.ts
CHANGED
|
@@ -800,6 +800,13 @@ export function processBaseUrls(
|
|
|
800
800
|
// Set default baseUrls
|
|
801
801
|
let baseUrls: Dictionary<string>;
|
|
802
802
|
|
|
803
|
+
// A CNAME (config.domain, e.g. set by the snippet v2.6+) takes precedence
|
|
804
|
+
// over direct URL routing so that customer-configured first-party domains
|
|
805
|
+
// and the snippet's fallback domain are always honored.
|
|
806
|
+
if (!isEmpty(config.domain)) {
|
|
807
|
+
return processCustomBaseUrls(config);
|
|
808
|
+
}
|
|
809
|
+
|
|
803
810
|
// When direct URL routing is false, update baseUrls based custom urls
|
|
804
811
|
// passed to the config
|
|
805
812
|
if (flags.directURLRouting) {
|