@mparticle/web-sdk 2.79.1 → 2.79.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -15,7 +15,7 @@ map:function map(a,b){var c,d,e;if(null===this)throw new TypeError(" this is nul
15
15
  filter:function filter(a/*, thisArg*/){if(void 0===this||null===this)throw new TypeError;var b=Object(this),c=b.length>>>0;if("function"!=typeof a)throw new TypeError;for(var d=[],e=2<=arguments.length?arguments[1]:void 0,f=0;f<c;f++)if(f in b){var g=b[f];a.call(e,g,f,b)&&d.push(g);}return d},// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray
16
16
  isArray:function isArray(a){return "[object Array]"===Object.prototype.toString.call(a)},Base64:Base64$1};
17
17
 
18
- var version = "2.79.1";
18
+ var version = "2.79.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
@@ -1658,12 +1658,23 @@ var ErrorReportingDispatcher=/** @class */function(){function a(){this.services=
1658
1658
 
1659
1659
  var LoggingDispatcher=/** @class */function(){function a(){this.services=[];}return a.prototype.register=function(a){this.services.push(a);},a.prototype.log=function(a){var b=this;this.services.forEach(function(c){var d;try{c.log(a);}catch(a){null===(d=b.logger)||void 0===d?void 0:d.error("Error in LoggingService: "+a);}});},a}();
1660
1660
 
1661
- var WRAPPED_MARKER="__mpApvWrapped__",PageViewTracker=/** @class */function(){function a(a){this.lastPath=null,this.isActive=!1,this.originalPushState=null,this.originalReplaceState=null,this.pushStateWrapper=null,this.replaceStateWrapper=null,this.popStateListener=null,this.mpInstance=a;}return a.prototype.isSupportedEnvironment=function(){return "undefined"!=typeof window&&"undefined"!=typeof window.history&&"function"==typeof window.history.pushState&&"function"==typeof window.addEventListener},a.prototype.init=function(){return this.mpInstance.Logger.verbose("mParticle APV: [init] PageViewTracker Init"),this.isSupportedEnvironment()?void(this.isActive&&(this.mpInstance.Logger.verbose("mParticle APV: [init] starting (teardown-first for idempotency)"),this.teardown()),this.isActive=!0,this.lastPath=this.getCurrentKey(),this.mpInstance.Logger.verbose("mParticle APV: [init] seeded lastPath: ".concat(this.lastPath)),this.patchHistoryMethods(),this.addNavigationListeners(),this.mpInstance.Logger.verbose("mParticle APV: [init] patched pushState/replaceState + listening for popstate")):void this.mpInstance.Logger.verbose("mParticle APV: [init] unsupported environment (no History API), not starting")},a.prototype.patchHistoryMethods=function(){var a=this,b=window.history.pushState;if(b[WRAPPED_MARKER])return void this.mpInstance.Logger.verbose("mParticle APV: [patch] history already wrapped, skipping to avoid double-wrap");var c=window.history.pushState,d=window.history.replaceState;this.originalPushState=c,this.originalReplaceState=d;var e=function(){for(var b=[],d=0;d<arguments.length;d++)b[d]=arguments[d];var e=c.apply(this,b);return a.safeHandleNavigation("pushState"),e},f=function(){for(var b=[],c=0;c<arguments.length;c++)b[c]=arguments[c];var e=d.apply(this,b);return a.safeHandleNavigation("replaceState"),e};Object.defineProperty(e,WRAPPED_MARKER,{value:!0,enumerable:!1}),Object.defineProperty(f,WRAPPED_MARKER,{value:!0,enumerable:!1}),this.pushStateWrapper=e,this.replaceStateWrapper=f;try{window.history.pushState=e,window.history.replaceState=f;}catch(a){this.mpInstance.Logger.verbose("mParticle APV: [error] failed to patch history methods (frozen/sealed), rolling back: ".concat(a));try{window.history.pushState===e&&(window.history.pushState=c),window.history.replaceState===f&&(window.history.replaceState=d);}catch(a){this.mpInstance.Logger.verbose("mParticle APV: [error] failed to restore history methods after patch failure: ".concat(a));}this.pushStateWrapper=null,this.replaceStateWrapper=null,this.originalPushState=null,this.originalReplaceState=null;}},a.prototype.addNavigationListeners=function(){var a=this;this.popStateListener=function(){return a.safeHandleNavigation("popstate")},window.addEventListener("popstate",this.popStateListener);},a.prototype.safeHandleNavigation=function(a){try{this.handleNavigation(a);}catch(b){this.mpInstance.Logger.verbose("mParticle APV: [error] navigation handler threw (".concat(a,"), page view skipped: ").concat(b));}},a.prototype.getCurrentKey=function(){return window.location.pathname},a.prototype.handleNavigation=function(a){var b=this,c=this.getCurrentKey();if(this.mpInstance.Logger.verbose("mParticle APV: [detect] navigation signal (source: ".concat(a,", candidatePath: ").concat(c,", lastPath: ").concat(this.lastPath,")")),c===this.lastPath)return void this.mpInstance.Logger.verbose("mParticle APV: [dedupe] pathname unchanged, skipping (source: ".concat(a,", path: ").concat(c,")"));this.mpInstance.Logger.verbose("mParticle APV: [accept] pathname changed, scheduling fire (source: ".concat(a,", from: ").concat(this.lastPath,", to: ").concat(c,")")),this.lastPath=c;// Snapshot the path now: it is already settled at this point, and a
1661
+ var WRAPPED_MARKER="__mpApvWrapped__";// window key under which the single active tracker is stored.
1662
+ // Survives module re-evaluation (Next.js re-executes the bundle on every SPA
1663
+ // navigation, resetting all module-level state, but window persists for the
1664
+ // lifetime of the tab).
1665
+ var WIN_TRACKER_KEY="__mpApvTracker__";// Guards the initial page view so repeated mParticle.init() calls from SPA
1666
+ // re-renders don't fire duplicate logPageView() events for the same page.
1667
+ var WIN_INIT_PV_KEY="__mpApvInitPVLogged__";var PageViewTracker=/** @class */function(){function a(a){this.lastPath=null,this._isActive=!1,this.pendingNavigations=[],this.originalPushState=null,this.originalReplaceState=null,this.pushStateWrapper=null,this.replaceStateWrapper=null,this.popStateListener=null,this.mpInstance=a;}return a.hasInitialPageViewFired=function(){return !!window[WIN_INIT_PV_KEY]},a.markInitialPageViewFired=function(){window[WIN_INIT_PV_KEY]=!0;},a.resetWindowState=function(a){var b=getWindowTracker();b&&b!==a&&b.teardown(),"undefined"!=typeof window&&delete window[WIN_INIT_PV_KEY],setWindowTracker(void 0);},Object.defineProperty(a.prototype,"isActive",{get:function get(){return this._isActive},enumerable:!1,configurable:!0}),a.prototype.isSupportedEnvironment=function(){return "undefined"!=typeof window&&"undefined"!=typeof window.history&&"function"==typeof window.history.pushState&&"function"==typeof window.addEventListener},a.prototype.init=function(){var a=this;if(this.mpInstance.Logger.verbose("mParticle APV: [init] PageViewTracker Init"),!this.isSupportedEnvironment())return void this.mpInstance.Logger.verbose("mParticle APV: [init] unsupported environment (no History API), not starting");// Tear down any tracker left over from a previous module load.
1668
+ // window[WIN_TRACKER_KEY] outlives module re-evaluation; this is the
1669
+ // only way to reach a tracker instance in a dead module scope.
1670
+ // Transfer any pending navigations first so a route change that queued a
1671
+ // deferred fire before module re-evaluation occurs is not silently dropped.
1672
+ var b=getWindowTracker(),c=[];b&&b!==this&&(this.mpInstance.Logger.verbose("mParticle APV: [init] found stale tracker from previous module load \u2014 transferring pending navigations and tearing down"),c=b.takePendingNavigations(),b.teardown()),this._isActive&&(this.mpInstance.Logger.verbose("mParticle APV: [init] starting (teardown-first for idempotency)"),c=__spreadArray(__spreadArray([],c,!0),this.takePendingNavigations(),!0),this.teardown()),this._isActive=!0,this.lastPath=this.getCurrentKey(),this.mpInstance.Logger.verbose("mParticle APV: [init] seeded lastPath: ".concat(this.lastPath)),this.patchHistoryMethods(),this.addNavigationListeners(),setWindowTracker(this),this.mpInstance.Logger.verbose("mParticle APV: [init] patched pushState/replaceState + listening for popstate"),c.forEach(function(b){var c=setTimeout(function(){a.pendingNavigations=a.pendingNavigations.filter(function(a){return a.timeoutId!==c}),a._isActive&&(a.mpInstance._SessionManager.resetSessionTimer(),a.firePageView(b));},0);a.pendingNavigations.push({path:b,timeoutId:c});});},a.prototype.patchHistoryMethods=function(){var a=this,b=window.history.pushState;if(b[WRAPPED_MARKER])return void this.mpInstance.Logger.verbose("mParticle APV: [patch] history already wrapped, skipping to avoid double-wrap \u2014 STACKED WRAPPER DETECTED");var c=window.history.pushState,d=window.history.replaceState;this.originalPushState=c,this.originalReplaceState=d;var e=function(){for(var b=[],d=0;d<arguments.length;d++)b[d]=arguments[d];var e=c.apply(this,b);return a._isActive&&a.safeHandleNavigation("pushState"),e},f=function(){for(var b=[],c=0;c<arguments.length;c++)b[c]=arguments[c];var e=d.apply(this,b);return a._isActive&&a.safeHandleNavigation("replaceState"),e};Object.defineProperty(e,WRAPPED_MARKER,{value:!0,enumerable:!1}),Object.defineProperty(f,WRAPPED_MARKER,{value:!0,enumerable:!1}),this.pushStateWrapper=e,this.replaceStateWrapper=f;try{window.history.pushState=e,window.history.replaceState=f;}catch(a){this.mpInstance.Logger.verbose("mParticle APV: [error] failed to patch history methods (frozen/sealed), rolling back: ".concat(a));try{window.history.pushState===e&&(window.history.pushState=c),window.history.replaceState===f&&(window.history.replaceState=d);}catch(a){this.mpInstance.Logger.verbose("mParticle APV: [error] failed to restore history methods after patch failure: ".concat(a));}this.pushStateWrapper=null,this.replaceStateWrapper=null,this.originalPushState=null,this.originalReplaceState=null;}},a.prototype.addNavigationListeners=function(){var a=this;this.popStateListener=function(){return a.safeHandleNavigation("popstate")},window.addEventListener("popstate",this.popStateListener);},a.prototype.safeHandleNavigation=function(a){try{this.handleNavigation(a);}catch(b){this.mpInstance.Logger.verbose("mParticle APV: [error] navigation handler threw (".concat(a,"), page view skipped: ").concat(b));}},a.prototype.getCurrentKey=function(){return window.location.pathname},a.prototype.handleNavigation=function(a){var b=this,c=this.getCurrentKey();if(this.mpInstance.Logger.verbose("mParticle APV: [detect] navigation signal (source: ".concat(a,", candidatePath: ").concat(c,", lastPath: ").concat(this.lastPath,")")),c===this.lastPath)return void this.mpInstance.Logger.verbose("mParticle APV: [dedupe] pathname unchanged, skipping (source: ".concat(a,", path: ").concat(c,")"));this.mpInstance.Logger.verbose("mParticle APV: [accept] pathname changed, scheduling fire (source: ".concat(a,", from: ").concat(this.lastPath,", to: ").concat(c,")")),this.lastPath=c;// Snapshot the path now: it is already settled at this point, and a
1662
1673
  // same-tick navigation would otherwise overwrite window.location
1663
1674
  // before the deferred flush reads it. The title is intentionally read
1664
1675
  // later (in the deferred flush) so the router's post-navigation render
1665
1676
  // commit has a chance to update document.title first.
1666
- setTimeout(function(){return b.isActive?void(b.mpInstance._SessionManager.resetSessionTimer(),b.firePageView(c)):void b.mpInstance.Logger.verbose("mParticle APV: [defer] fire aborted, tracker inactive (torn down before flush)")},0);},a.prototype.firePageView=function(a){var b=window.document.title;this.mpInstance.Logger.verbose("mParticle APV: [fire] deferred flush -> _Events.logEvent(PageView) (path: ".concat(a,", title: ").concat(b,")")),this.mpInstance._Events.logEvent({messageType:MessageType$1.PageView,name:"PageView",data:{hostname:window.location.hostname,title:b,path:a},eventType:EventType.Unknown});},a.prototype.teardown=function(){this.popStateListener&&(window.removeEventListener("popstate",this.popStateListener),this.popStateListener=null);var a=null!==this.pushStateWrapper&&window.history.pushState===this.pushStateWrapper;this.originalPushState&&(a?(window.history.pushState=this.originalPushState,this.mpInstance.Logger.verbose("mParticle APV: [teardown] restored original pushState")):this.mpInstance.Logger.verbose("mParticle APV: [teardown] pushState no longer ours; leaving in place, gating callback to no-op"),this.originalPushState=null,this.pushStateWrapper=null);var b=null!==this.replaceStateWrapper&&window.history.replaceState===this.replaceStateWrapper;this.originalReplaceState&&(b?(window.history.replaceState=this.originalReplaceState,this.mpInstance.Logger.verbose("mParticle APV: [teardown] restored original replaceState")):this.mpInstance.Logger.verbose("mParticle APV: [teardown] replaceState no longer ours; leaving in place, gating callback to no-op"),this.originalReplaceState=null,this.replaceStateWrapper=null),this.isActive=!1;},a}();
1677
+ var d=c,e=setTimeout(function(){return b.pendingNavigations=b.pendingNavigations.filter(function(a){return a.timeoutId!==e}),b._isActive?void(b.mpInstance._SessionManager.resetSessionTimer(),b.firePageView(d)):void b.mpInstance.Logger.verbose("mParticle APV: [defer] fire aborted, tracker inactive (torn down before flush)")},0);this.pendingNavigations.push({path:d,timeoutId:e});},a.prototype.firePageView=function(a){var b=window.document.title;this.mpInstance.Logger.verbose("mParticle APV: [fire] deferred flush -> _Events.logEvent(PageView) (path: ".concat(a,", title: ").concat(b,")")),this.mpInstance._Events.logEvent({messageType:MessageType$1.PageView,name:"PageView",data:{hostname:window.location.hostname,title:b,path:a},eventType:EventType.Unknown});},a.prototype.takePendingNavigations=function(){var a=this.pendingNavigations.map(function(a){return a.path});return this.pendingNavigations.forEach(function(a){return clearTimeout(a.timeoutId)}),this.pendingNavigations=[],a},a.prototype.restoreHistoryMethod=function(a,b,c){if(b){var d=null!==c&&window.history[a]===c;d?(window.history[a]=b,this.mpInstance.Logger.verbose("mParticle APV: [teardown] restored original ".concat(a))):this.mpInstance.Logger.verbose("mParticle APV: [teardown] ".concat(a," no longer ours; leaving in place, gating callback to no-op"));}},a.prototype.teardown=function(){this.pendingNavigations.forEach(function(a){return clearTimeout(a.timeoutId)}),this.pendingNavigations=[],this.popStateListener&&(window.removeEventListener("popstate",this.popStateListener),this.popStateListener=null),this.restoreHistoryMethod("pushState",this.originalPushState,this.pushStateWrapper),this.originalPushState=null,this.pushStateWrapper=null,this.restoreHistoryMethod("replaceState",this.originalReplaceState,this.replaceStateWrapper),this.originalReplaceState=null,this.replaceStateWrapper=null,this._isActive=!1,getWindowTracker()===this&&setWindowTracker(void 0);},a}();function getWindowTracker(){return "undefined"==typeof window?void 0:window[WIN_TRACKER_KEY]}function setWindowTracker(a){if("undefined"!=typeof window){var b=window;a?b[WIN_TRACKER_KEY]=a:delete b[WIN_TRACKER_KEY];}}
1667
1678
 
1668
1679
  var Messages=Constants.Messages,HTTPCodes=Constants.HTTPCodes,FeatureFlags=Constants.FeatureFlags,CaptureIntegrationSpecificIdsV2Modes=Constants.CaptureIntegrationSpecificIdsV2Modes,ReportBatching=FeatureFlags.ReportBatching,CaptureIntegrationSpecificIds=FeatureFlags.CaptureIntegrationSpecificIds,CaptureIntegrationSpecificIdsV2=FeatureFlags.CaptureIntegrationSpecificIdsV2,StartingInitialization=Messages.InformationMessages.StartingInitialization;/**
1669
1680
  * <p>All of the following methods can be called on the primary mParticle class. In version 2.10.0, we introduced <a href="https://docs.mparticle.com/developers/sdk/web/multiple-instances/">multiple instances</a>. If you are using multiple instances (self hosted environments only), you should call these methods on each instance.</p>
@@ -1680,7 +1691,7 @@ var Messages=Constants.Messages,HTTPCodes=Constants.HTTPCodes,FeatureFlags=Const
1680
1691
  this._instanceName=a,this._NativeSdkHelpers=new NativeSdkHelpers(this),this._SessionManager=new SessionManager(this),this._Persistence=new _Persistence(this),this._Helpers=new Helpers(this),this._Events=new Events(this),this._CookieSyncManager=new CookieSyncManager(this),this._ServerModel=new ServerModel(this),this._Ecommerce=new Ecommerce(this),this._ForwardingStatsUploader=new forwardingStatsUploader(this),this._Consent=new Consent(this),this._IdentityAPIClient=new IdentityAPIClient(this),this._preInit={readyQueue:[],integrationDelays:{},forwarderConstructors:[]},this._ErrorReportingDispatcher=new ErrorReportingDispatcher,this._LoggingDispatcher=new LoggingDispatcher,this._RoktManager=new RoktManager,this._RoktManager.setOnReadyCallback(function(){b.processQueueOnIdentityFailure();}),this.processQueueOnIdentityFailure=function(){var a,c,d;(null===(a=b._Store)||void 0===a?void 0:a.isInitialized)||(null===(c=b._Store)||void 0===c?void 0:c.identityCallFailed)&&(null===(d=b._RoktManager)||void 0===d?void 0:d.isReady())&&(b._RoktManager.processMessageQueue(),b._preInit.readyQueue=processReadyQueue(b._preInit.readyQueue,b.Logger));},this.processQueueOnNoFunctional=function(){var a,c;if(!(null!==(a=b._Store)&&void 0!==a)||!a.isInitialized){var d=(null===(c=b._CookieConsentManager)||void 0===c?void 0:c.getNoFunctional())&&!hasExplicitIdentifier(b._Store);d&&(b._preInit.readyQueue=processReadyQueue(b._preInit.readyQueue,b.Logger));}},this.IdentityType=IdentityType,this.EventType=EventType,this.CommerceEventType=CommerceEventType,this.PromotionType=PromotionActionType,this.ProductActionType=ProductActionType,this.RoktEvents=RoktEvents,this._Identity=new Identity(this),this.Identity=this._Identity.IdentityAPI,this.generateHash=this._Helpers.generateHash,this.getDeviceId=this._Persistence.getDeviceId,"undefined"!=typeof window&&window.mParticle&&window.mParticle.config&&window.mParticle.config.hasOwnProperty("rq")&&(this._preInit.readyQueue=window.mParticle.config.rq),this.init=function(a,b){var c=this;// config code - Fetch config when requestConfig = true, otherwise, proceed with SDKInitialization
1681
1692
  // Since fetching the configuration is asynchronous, we must pass completeSDKInitialization
1682
1693
  // to it for it to be run after fetched
1683
- if(b||console.warn("You did not pass a config object to init(). mParticle will not initialize properly"),runPreConfigFetchInitialization(this,a,b),!b)return void console.error("No config available on the window, please pass a config object to mParticle.init()");if(!b.hasOwnProperty("requestConfig")||b.requestConfig){var d=new ConfigAPIClient(a,b,this);d.getSDKConfiguration().then(function(d){var e=extend({},b,d);completeSDKInitialization(a,e,c);});}else completeSDKInitialization(a,b,this);},this.setLogLevel=function(a){b.Logger.setLogLevel(a);},this.reset=function(a){try{a._Persistence.resetPersistence(),a._Store&&delete a._Store;}catch(a){console.error("Cannot reset mParticle",a);}},this._resetForTests=function(a,b,c){c._Store&&delete c._Store,c._ErrorReportingDispatcher=new ErrorReportingDispatcher,c._LoggingDispatcher=new LoggingDispatcher,c.Logger=new Logger(a),c._ErrorReportingDispatcher.logger=c.Logger,c._LoggingDispatcher.logger=c.Logger,c._Store=new Store(a,c),c._Store.isLocalStorageAvailable=c._Persistence.determineLocalStorageAvailability(window.localStorage),c._Events.stopTracking(),b||c._Persistence.resetPersistence(),c._Persistence.forwardingStatsBatches.uploadsTable={},c._Persistence.forwardingStatsBatches.forwardingStatsEventQueue=[],c._preInit={readyQueue:[],pixelConfigurations:[],integrationDelays:{},forwarderConstructors:[],isDevelopmentMode:!1};},this.ready=function(a){var c,d,e,f=(null===(c=b._CookieConsentManager)||void 0===c?void 0:c.getNoFunctional())&&!hasExplicitIdentifier(b._Store),g=isFunction(a)&&((null===(d=b._Store)||void 0===d?void 0:d.isInitialized)||(null===(e=b._Store)||void 0===e?void 0:e.identityCallFailed)&&b._RoktManager.isReady()||f);g?a():b._preInit.readyQueue.push(a);},this.getEnvironment=function(){return b._Store.SDKConfig.isDevelopmentMode?Constants.Environment.Development:Constants.Environment.Production},this.getVersion=function(){return Constants.sdkVersion},this.setAppVersion=function(a){var c=queueIfNotInitialized(function(){b.setAppVersion(a);},b);c||(b._Store.SDKConfig.appVersion=a,b._Persistence.update());},this.setDeviceId=function(a){var c=queueIfNotInitialized(function(){b.setDeviceId(a);},b);c||this._Store.setDeviceId(a);},this.isInitialized=function(){return !!b._Store&&b._Store.isInitialized},this.getAppName=function(){return b._Store.SDKConfig.appName},this.setAppName=function(a){var c=queueIfNotInitialized(function(){b.setAppName(a);},b);c||(b._Store.SDKConfig.appName=a);},this.getAppVersion=function(){return b._Store.SDKConfig.appVersion},this.stopTrackingLocation=function(){b._SessionManager.resetSessionTimer(),b._Events.stopTracking();},this.startTrackingLocation=function(a){isFunction(a)||b.Logger.warning("Warning: Location tracking is triggered, but not including a callback into the `startTrackingLocation` may result in events logged too quickly and not being associated with a location."),b._SessionManager.resetSessionTimer(),b._Events.startTracking(a);},this.setPosition=function(a,c){var d=queueIfNotInitialized(function(){b.setPosition(a,c);},b);d||(b._SessionManager.resetSessionTimer(),"number"==typeof a&&"number"==typeof c?b._Store.currentPosition={lat:a,lng:c}:b.Logger.error("Position latitude and/or longitude must both be of type number"));},this.startNewSession=function(){b._SessionManager.startNewSession();},this.endSession=function(){// Sends true as an over ride vs when endSession is called from the setInterval
1694
+ if(b||console.warn("You did not pass a config object to init(). mParticle will not initialize properly"),runPreConfigFetchInitialization(this,a,b),!b)return void console.error("No config available on the window, please pass a config object to mParticle.init()");if(!b.hasOwnProperty("requestConfig")||b.requestConfig){var d=new ConfigAPIClient(a,b,this);d.getSDKConfiguration().then(function(d){var e=extend({},b,d);completeSDKInitialization(a,e,c);});}else completeSDKInitialization(a,b,this);},this.setLogLevel=function(a){b.Logger.setLogLevel(a);},this.reset=function(a){try{a._Persistence.resetPersistence(),a._Store&&delete a._Store;}catch(a){console.error("Cannot reset mParticle",a);}},this._resetForTests=function(a,b,c){c._Store&&delete c._Store,c._ErrorReportingDispatcher=new ErrorReportingDispatcher,c._LoggingDispatcher=new LoggingDispatcher,c.Logger=new Logger(a),c._ErrorReportingDispatcher.logger=c.Logger,c._LoggingDispatcher.logger=c.Logger,c._Store=new Store(a,c),c._Store.isLocalStorageAvailable=c._Persistence.determineLocalStorageAvailability(window.localStorage),c._Events.stopTracking();var d=c._PageViewTracker;d&&(d.teardown(),c._PageViewTracker=void 0),PageViewTracker.resetWindowState(d),b||c._Persistence.resetPersistence(),c._Persistence.forwardingStatsBatches.uploadsTable={},c._Persistence.forwardingStatsBatches.forwardingStatsEventQueue=[],c._preInit={readyQueue:[],pixelConfigurations:[],integrationDelays:{},forwarderConstructors:[],isDevelopmentMode:!1};},this.ready=function(a){var c,d,e,f=(null===(c=b._CookieConsentManager)||void 0===c?void 0:c.getNoFunctional())&&!hasExplicitIdentifier(b._Store),g=isFunction(a)&&((null===(d=b._Store)||void 0===d?void 0:d.isInitialized)||(null===(e=b._Store)||void 0===e?void 0:e.identityCallFailed)&&b._RoktManager.isReady()||f);g?a():b._preInit.readyQueue.push(a);},this.getEnvironment=function(){return b._Store.SDKConfig.isDevelopmentMode?Constants.Environment.Development:Constants.Environment.Production},this.getVersion=function(){return Constants.sdkVersion},this.setAppVersion=function(a){var c=queueIfNotInitialized(function(){b.setAppVersion(a);},b);c||(b._Store.SDKConfig.appVersion=a,b._Persistence.update());},this.setDeviceId=function(a){var c=queueIfNotInitialized(function(){b.setDeviceId(a);},b);c||this._Store.setDeviceId(a);},this.isInitialized=function(){return !!b._Store&&b._Store.isInitialized},this.getAppName=function(){return b._Store.SDKConfig.appName},this.setAppName=function(a){var c=queueIfNotInitialized(function(){b.setAppName(a);},b);c||(b._Store.SDKConfig.appName=a);},this.getAppVersion=function(){return b._Store.SDKConfig.appVersion},this.stopTrackingLocation=function(){b._SessionManager.resetSessionTimer(),b._Events.stopTracking();},this.startTrackingLocation=function(a){isFunction(a)||b.Logger.warning("Warning: Location tracking is triggered, but not including a callback into the `startTrackingLocation` may result in events logged too quickly and not being associated with a location."),b._SessionManager.resetSessionTimer(),b._Events.startTracking(a);},this.setPosition=function(a,c){var d=queueIfNotInitialized(function(){b.setPosition(a,c);},b);d||(b._SessionManager.resetSessionTimer(),"number"==typeof a&&"number"==typeof c?b._Store.currentPosition={lat:a,lng:c}:b.Logger.error("Position latitude and/or longitude must both be of type number"));},this.startNewSession=function(){b._SessionManager.startNewSession();},this.endSession=function(){// Sends true as an over ride vs when endSession is called from the setInterval
1684
1695
  b._SessionManager.endSession(!0);},this.logBaseEvent=function(a,c){var d=queueIfNotInitialized(function(){b.logBaseEvent(a,c);},b);if(!d)return (b._SessionManager.resetSessionTimer(),"string"!=typeof a.name)?void b.Logger.error(Messages.ErrorMessages.EventNameInvalidType):(a.eventType||(a.eventType=EventType.Unknown),b._Helpers.canLog()?void b._Events.logEvent(a,c):void b.Logger.error(Messages.ErrorMessages.LoggingDisabled))},this.logEvent=function(a,c,d,e,f){var g=queueIfNotInitialized(function(){b.logEvent(a,c,d,e,f);},b);if(!g)return (b._SessionManager.resetSessionTimer(),"string"!=typeof a)?void b.Logger.error(Messages.ErrorMessages.EventNameInvalidType):(c||(c=EventType.Unknown),b._Helpers.isEventType(c)?b._Helpers.canLog()?void b._Events.logEvent({messageType:MessageType$1.PageEvent,name:a,data:d,eventType:c,customFlags:e},f):void b.Logger.error(Messages.ErrorMessages.LoggingDisabled):void b.Logger.error("Invalid event type: "+c+", must be one of: \n"+JSON.stringify(EventType)))},this.logError=function(a,c){var d=queueIfNotInitialized(function(){b.logError(a,c);},b);if(!d&&(b._SessionManager.resetSessionTimer(),!!a)){"string"==typeof a&&(a={message:a});var e={m:a.message?a.message:a,s:"Error",t:a.stack||null};if(c){var f=b._Helpers.sanitizeAttributes(c,e.m);for(var g in f)e[g]=f[g];}b._Events.logEvent({messageType:MessageType$1.CrashReport,name:a.name?a.name:"Error",eventType:EventType.Other,data:e});}},this.logLink=function(a,c,d,e){b._Events.addEventHandler("click",a,c,e,d);},this.logForm=function(a,c,d,e){b._Events.addEventHandler("submit",a,c,e,d);},this.logPageView=function(a,c,d,e){var f=queueIfNotInitialized(function(){b.logPageView(a,c,d,e);},b);if(!f){if(b._SessionManager.resetSessionTimer(),b._Helpers.canLog()){if(b._Helpers.Validators.isStringOrNumber(a)||(a="PageView"),!c)c={hostname:window.location.hostname,title:window.document.title};else if(!b._Helpers.isObject(c))return void b.Logger.error("The attributes argument must be an object. A "+_typeof$1(c)+" was entered. Please correct and retry.");if(d&&!b._Helpers.isObject(d))return void b.Logger.error("The customFlags argument must be an object. A "+_typeof$1(d)+" was entered. Please correct and retry.")}b._Events.logEvent({messageType:MessageType$1.PageView,name:a,data:c,eventType:EventType.Unknown,customFlags:d},e);}},this.upload=function(){var a,c;b._Helpers.canLog()&&(b._Store.webviewBridgeEnabled?b._NativeSdkHelpers.sendToNative(Constants.NativeSdkPaths.Upload):null===(c=null===(a=b._APIClient)||void 0===a?void 0:a.uploader)||void 0===c?void 0:c.prepareAndUpload(!1,!1));},this.Consent={/**
1685
1696
  * Creates a CCPA Opt Out Consent State.
1686
1697
  *
@@ -1842,7 +1853,7 @@ if((null===(d=c._APIClient)||void 0===d?void 0:d.uploader)&&c._APIClient.uploade
1842
1853
  var k=c.Identity.getCurrentUser(),l=k?k.getMPID():null,m=k?k.getUserIdentities().userIdentities:{};c._Store.SDKConfig.identifyRequest=c._Store.hasInvalidIdentifyRequest()?{userIdentities:m}:c._Store.SDKConfig.identifyRequest,i(ReportBatching)&&c._ForwardingStatsUploader.startForwardingStatsTimer();// https://go.mparticle.com/work/SQDSDKS-7639
1843
1854
  var n=i(CaptureIntegrationSpecificIds),o=i(CaptureIntegrationSpecificIdsV2),p=o&&o!==CaptureIntegrationSpecificIdsV2Modes.None||!0===n;if(p){var q;n||o===CaptureIntegrationSpecificIdsV2Modes.All?q="all":o===CaptureIntegrationSpecificIdsV2Modes.RoktOnly&&(q="roktonly"),c._IntegrationCapture=new IntegrationCapture(q),c._IntegrationCapture.capture();}// Configure Rokt Manager with user and filtered user
1844
1855
  var r=parseConfig(b,"Rokt",181);if(r){var s=null===(e=r.settings)||void 0===e?void 0:e.accountId;c._Store.setRoktAccountId(s);var t=r.userAttributeFilters,u=filteredMparticleUser(l,{userAttributeFilters:t},c),v={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
1845
- c._RoktManager.init(r,u,c.Identity,c._Store,c.Logger,v,c.captureTiming,c._ErrorReportingDispatcher,c._LoggingDispatcher,c._IntegrationCapture);}c._Forwarders.processForwarders(b,c._APIClient.prepareForwardingStats),c._Forwarders.processPixelConfigs(b),c._SessionManager.initialize(),c._Events.logAST(),i(j)?(c._Events.logPageView(),!c._PageViewTracker&&(c._PageViewTracker=new PageViewTracker(c)),c._PageViewTracker.init()):c._PageViewTracker&&c._PageViewTracker.teardown(),processIdentityCallback(c,k,l,m);}// We will continue to clear out the ready queue as part of the initial init flow
1856
+ c._RoktManager.init(r,u,c.Identity,c._Store,c.Logger,v,c.captureTiming,c._ErrorReportingDispatcher,c._LoggingDispatcher,c._IntegrationCapture);}c._Forwarders.processForwarders(b,c._APIClient.prepareForwardingStats),c._Forwarders.processPixelConfigs(b),c._SessionManager.initialize(),c._Events.logAST(),i(j)?(c._PageViewTracker?c.Logger.verbose("mParticle APV: [sdk-init] tracker already on this instance, skipping logPageView"):(c.Logger.verbose("mParticle APV: [sdk-init] creating new PageViewTracker for this instance"),c._PageViewTracker=new PageViewTracker(c),PageViewTracker.hasInitialPageViewFired()?c.Logger.verbose("mParticle APV: [sdk-init] initial page view already logged this page load, skipping"):(PageViewTracker.markInitialPageViewFired(),c._Events.logPageView())),c._PageViewTracker.init()):c._PageViewTracker&&c._PageViewTracker.teardown(),processIdentityCallback(c,k,l,m);}// We will continue to clear out the ready queue as part of the initial init flow
1846
1857
  // if an identify request is unnecessary, such as if there is an existing session
1847
1858
  (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,c.Logger)),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
1848
1859
  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:
@@ -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.79.1";
18
+ var version = "2.79.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
@@ -1658,12 +1658,23 @@ var ErrorReportingDispatcher=/** @class */function(){function a(){this.services=
1658
1658
 
1659
1659
  var LoggingDispatcher=/** @class */function(){function a(){this.services=[];}return a.prototype.register=function(a){this.services.push(a);},a.prototype.log=function(a){var b=this;this.services.forEach(function(c){var d;try{c.log(a);}catch(a){null===(d=b.logger)||void 0===d?void 0:d.error("Error in LoggingService: "+a);}});},a}();
1660
1660
 
1661
- var WRAPPED_MARKER="__mpApvWrapped__",PageViewTracker=/** @class */function(){function a(a){this.lastPath=null,this.isActive=!1,this.originalPushState=null,this.originalReplaceState=null,this.pushStateWrapper=null,this.replaceStateWrapper=null,this.popStateListener=null,this.mpInstance=a;}return a.prototype.isSupportedEnvironment=function(){return "undefined"!=typeof window&&"undefined"!=typeof window.history&&"function"==typeof window.history.pushState&&"function"==typeof window.addEventListener},a.prototype.init=function(){return this.mpInstance.Logger.verbose("mParticle APV: [init] PageViewTracker Init"),this.isSupportedEnvironment()?void(this.isActive&&(this.mpInstance.Logger.verbose("mParticle APV: [init] starting (teardown-first for idempotency)"),this.teardown()),this.isActive=!0,this.lastPath=this.getCurrentKey(),this.mpInstance.Logger.verbose("mParticle APV: [init] seeded lastPath: ".concat(this.lastPath)),this.patchHistoryMethods(),this.addNavigationListeners(),this.mpInstance.Logger.verbose("mParticle APV: [init] patched pushState/replaceState + listening for popstate")):void this.mpInstance.Logger.verbose("mParticle APV: [init] unsupported environment (no History API), not starting")},a.prototype.patchHistoryMethods=function(){var a=this,b=window.history.pushState;if(b[WRAPPED_MARKER])return void this.mpInstance.Logger.verbose("mParticle APV: [patch] history already wrapped, skipping to avoid double-wrap");var c=window.history.pushState,d=window.history.replaceState;this.originalPushState=c,this.originalReplaceState=d;var e=function(){for(var b=[],d=0;d<arguments.length;d++)b[d]=arguments[d];var e=c.apply(this,b);return a.safeHandleNavigation("pushState"),e},f=function(){for(var b=[],c=0;c<arguments.length;c++)b[c]=arguments[c];var e=d.apply(this,b);return a.safeHandleNavigation("replaceState"),e};Object.defineProperty(e,WRAPPED_MARKER,{value:!0,enumerable:!1}),Object.defineProperty(f,WRAPPED_MARKER,{value:!0,enumerable:!1}),this.pushStateWrapper=e,this.replaceStateWrapper=f;try{window.history.pushState=e,window.history.replaceState=f;}catch(a){this.mpInstance.Logger.verbose("mParticle APV: [error] failed to patch history methods (frozen/sealed), rolling back: ".concat(a));try{window.history.pushState===e&&(window.history.pushState=c),window.history.replaceState===f&&(window.history.replaceState=d);}catch(a){this.mpInstance.Logger.verbose("mParticle APV: [error] failed to restore history methods after patch failure: ".concat(a));}this.pushStateWrapper=null,this.replaceStateWrapper=null,this.originalPushState=null,this.originalReplaceState=null;}},a.prototype.addNavigationListeners=function(){var a=this;this.popStateListener=function(){return a.safeHandleNavigation("popstate")},window.addEventListener("popstate",this.popStateListener);},a.prototype.safeHandleNavigation=function(a){try{this.handleNavigation(a);}catch(b){this.mpInstance.Logger.verbose("mParticle APV: [error] navigation handler threw (".concat(a,"), page view skipped: ").concat(b));}},a.prototype.getCurrentKey=function(){return window.location.pathname},a.prototype.handleNavigation=function(a){var b=this,c=this.getCurrentKey();if(this.mpInstance.Logger.verbose("mParticle APV: [detect] navigation signal (source: ".concat(a,", candidatePath: ").concat(c,", lastPath: ").concat(this.lastPath,")")),c===this.lastPath)return void this.mpInstance.Logger.verbose("mParticle APV: [dedupe] pathname unchanged, skipping (source: ".concat(a,", path: ").concat(c,")"));this.mpInstance.Logger.verbose("mParticle APV: [accept] pathname changed, scheduling fire (source: ".concat(a,", from: ").concat(this.lastPath,", to: ").concat(c,")")),this.lastPath=c;// Snapshot the path now: it is already settled at this point, and a
1661
+ var WRAPPED_MARKER="__mpApvWrapped__";// window key under which the single active tracker is stored.
1662
+ // Survives module re-evaluation (Next.js re-executes the bundle on every SPA
1663
+ // navigation, resetting all module-level state, but window persists for the
1664
+ // lifetime of the tab).
1665
+ var WIN_TRACKER_KEY="__mpApvTracker__";// Guards the initial page view so repeated mParticle.init() calls from SPA
1666
+ // re-renders don't fire duplicate logPageView() events for the same page.
1667
+ var WIN_INIT_PV_KEY="__mpApvInitPVLogged__";var PageViewTracker=/** @class */function(){function a(a){this.lastPath=null,this._isActive=!1,this.pendingNavigations=[],this.originalPushState=null,this.originalReplaceState=null,this.pushStateWrapper=null,this.replaceStateWrapper=null,this.popStateListener=null,this.mpInstance=a;}return a.hasInitialPageViewFired=function(){return !!window[WIN_INIT_PV_KEY]},a.markInitialPageViewFired=function(){window[WIN_INIT_PV_KEY]=!0;},a.resetWindowState=function(a){var b=getWindowTracker();b&&b!==a&&b.teardown(),"undefined"!=typeof window&&delete window[WIN_INIT_PV_KEY],setWindowTracker(void 0);},Object.defineProperty(a.prototype,"isActive",{get:function get(){return this._isActive},enumerable:!1,configurable:!0}),a.prototype.isSupportedEnvironment=function(){return "undefined"!=typeof window&&"undefined"!=typeof window.history&&"function"==typeof window.history.pushState&&"function"==typeof window.addEventListener},a.prototype.init=function(){var a=this;if(this.mpInstance.Logger.verbose("mParticle APV: [init] PageViewTracker Init"),!this.isSupportedEnvironment())return void this.mpInstance.Logger.verbose("mParticle APV: [init] unsupported environment (no History API), not starting");// Tear down any tracker left over from a previous module load.
1668
+ // window[WIN_TRACKER_KEY] outlives module re-evaluation; this is the
1669
+ // only way to reach a tracker instance in a dead module scope.
1670
+ // Transfer any pending navigations first so a route change that queued a
1671
+ // deferred fire before module re-evaluation occurs is not silently dropped.
1672
+ var b=getWindowTracker(),c=[];b&&b!==this&&(this.mpInstance.Logger.verbose("mParticle APV: [init] found stale tracker from previous module load \u2014 transferring pending navigations and tearing down"),c=b.takePendingNavigations(),b.teardown()),this._isActive&&(this.mpInstance.Logger.verbose("mParticle APV: [init] starting (teardown-first for idempotency)"),c=__spreadArray(__spreadArray([],c,!0),this.takePendingNavigations(),!0),this.teardown()),this._isActive=!0,this.lastPath=this.getCurrentKey(),this.mpInstance.Logger.verbose("mParticle APV: [init] seeded lastPath: ".concat(this.lastPath)),this.patchHistoryMethods(),this.addNavigationListeners(),setWindowTracker(this),this.mpInstance.Logger.verbose("mParticle APV: [init] patched pushState/replaceState + listening for popstate"),c.forEach(function(b){var c=setTimeout(function(){a.pendingNavigations=a.pendingNavigations.filter(function(a){return a.timeoutId!==c}),a._isActive&&(a.mpInstance._SessionManager.resetSessionTimer(),a.firePageView(b));},0);a.pendingNavigations.push({path:b,timeoutId:c});});},a.prototype.patchHistoryMethods=function(){var a=this,b=window.history.pushState;if(b[WRAPPED_MARKER])return void this.mpInstance.Logger.verbose("mParticle APV: [patch] history already wrapped, skipping to avoid double-wrap \u2014 STACKED WRAPPER DETECTED");var c=window.history.pushState,d=window.history.replaceState;this.originalPushState=c,this.originalReplaceState=d;var e=function(){for(var b=[],d=0;d<arguments.length;d++)b[d]=arguments[d];var e=c.apply(this,b);return a._isActive&&a.safeHandleNavigation("pushState"),e},f=function(){for(var b=[],c=0;c<arguments.length;c++)b[c]=arguments[c];var e=d.apply(this,b);return a._isActive&&a.safeHandleNavigation("replaceState"),e};Object.defineProperty(e,WRAPPED_MARKER,{value:!0,enumerable:!1}),Object.defineProperty(f,WRAPPED_MARKER,{value:!0,enumerable:!1}),this.pushStateWrapper=e,this.replaceStateWrapper=f;try{window.history.pushState=e,window.history.replaceState=f;}catch(a){this.mpInstance.Logger.verbose("mParticle APV: [error] failed to patch history methods (frozen/sealed), rolling back: ".concat(a));try{window.history.pushState===e&&(window.history.pushState=c),window.history.replaceState===f&&(window.history.replaceState=d);}catch(a){this.mpInstance.Logger.verbose("mParticle APV: [error] failed to restore history methods after patch failure: ".concat(a));}this.pushStateWrapper=null,this.replaceStateWrapper=null,this.originalPushState=null,this.originalReplaceState=null;}},a.prototype.addNavigationListeners=function(){var a=this;this.popStateListener=function(){return a.safeHandleNavigation("popstate")},window.addEventListener("popstate",this.popStateListener);},a.prototype.safeHandleNavigation=function(a){try{this.handleNavigation(a);}catch(b){this.mpInstance.Logger.verbose("mParticle APV: [error] navigation handler threw (".concat(a,"), page view skipped: ").concat(b));}},a.prototype.getCurrentKey=function(){return window.location.pathname},a.prototype.handleNavigation=function(a){var b=this,c=this.getCurrentKey();if(this.mpInstance.Logger.verbose("mParticle APV: [detect] navigation signal (source: ".concat(a,", candidatePath: ").concat(c,", lastPath: ").concat(this.lastPath,")")),c===this.lastPath)return void this.mpInstance.Logger.verbose("mParticle APV: [dedupe] pathname unchanged, skipping (source: ".concat(a,", path: ").concat(c,")"));this.mpInstance.Logger.verbose("mParticle APV: [accept] pathname changed, scheduling fire (source: ".concat(a,", from: ").concat(this.lastPath,", to: ").concat(c,")")),this.lastPath=c;// Snapshot the path now: it is already settled at this point, and a
1662
1673
  // same-tick navigation would otherwise overwrite window.location
1663
1674
  // before the deferred flush reads it. The title is intentionally read
1664
1675
  // later (in the deferred flush) so the router's post-navigation render
1665
1676
  // commit has a chance to update document.title first.
1666
- setTimeout(function(){return b.isActive?void(b.mpInstance._SessionManager.resetSessionTimer(),b.firePageView(c)):void b.mpInstance.Logger.verbose("mParticle APV: [defer] fire aborted, tracker inactive (torn down before flush)")},0);},a.prototype.firePageView=function(a){var b=window.document.title;this.mpInstance.Logger.verbose("mParticle APV: [fire] deferred flush -> _Events.logEvent(PageView) (path: ".concat(a,", title: ").concat(b,")")),this.mpInstance._Events.logEvent({messageType:MessageType$1.PageView,name:"PageView",data:{hostname:window.location.hostname,title:b,path:a},eventType:EventType.Unknown});},a.prototype.teardown=function(){this.popStateListener&&(window.removeEventListener("popstate",this.popStateListener),this.popStateListener=null);var a=null!==this.pushStateWrapper&&window.history.pushState===this.pushStateWrapper;this.originalPushState&&(a?(window.history.pushState=this.originalPushState,this.mpInstance.Logger.verbose("mParticle APV: [teardown] restored original pushState")):this.mpInstance.Logger.verbose("mParticle APV: [teardown] pushState no longer ours; leaving in place, gating callback to no-op"),this.originalPushState=null,this.pushStateWrapper=null);var b=null!==this.replaceStateWrapper&&window.history.replaceState===this.replaceStateWrapper;this.originalReplaceState&&(b?(window.history.replaceState=this.originalReplaceState,this.mpInstance.Logger.verbose("mParticle APV: [teardown] restored original replaceState")):this.mpInstance.Logger.verbose("mParticle APV: [teardown] replaceState no longer ours; leaving in place, gating callback to no-op"),this.originalReplaceState=null,this.replaceStateWrapper=null),this.isActive=!1;},a}();
1677
+ var d=c,e=setTimeout(function(){return b.pendingNavigations=b.pendingNavigations.filter(function(a){return a.timeoutId!==e}),b._isActive?void(b.mpInstance._SessionManager.resetSessionTimer(),b.firePageView(d)):void b.mpInstance.Logger.verbose("mParticle APV: [defer] fire aborted, tracker inactive (torn down before flush)")},0);this.pendingNavigations.push({path:d,timeoutId:e});},a.prototype.firePageView=function(a){var b=window.document.title;this.mpInstance.Logger.verbose("mParticle APV: [fire] deferred flush -> _Events.logEvent(PageView) (path: ".concat(a,", title: ").concat(b,")")),this.mpInstance._Events.logEvent({messageType:MessageType$1.PageView,name:"PageView",data:{hostname:window.location.hostname,title:b,path:a},eventType:EventType.Unknown});},a.prototype.takePendingNavigations=function(){var a=this.pendingNavigations.map(function(a){return a.path});return this.pendingNavigations.forEach(function(a){return clearTimeout(a.timeoutId)}),this.pendingNavigations=[],a},a.prototype.restoreHistoryMethod=function(a,b,c){if(b){var d=null!==c&&window.history[a]===c;d?(window.history[a]=b,this.mpInstance.Logger.verbose("mParticle APV: [teardown] restored original ".concat(a))):this.mpInstance.Logger.verbose("mParticle APV: [teardown] ".concat(a," no longer ours; leaving in place, gating callback to no-op"));}},a.prototype.teardown=function(){this.pendingNavigations.forEach(function(a){return clearTimeout(a.timeoutId)}),this.pendingNavigations=[],this.popStateListener&&(window.removeEventListener("popstate",this.popStateListener),this.popStateListener=null),this.restoreHistoryMethod("pushState",this.originalPushState,this.pushStateWrapper),this.originalPushState=null,this.pushStateWrapper=null,this.restoreHistoryMethod("replaceState",this.originalReplaceState,this.replaceStateWrapper),this.originalReplaceState=null,this.replaceStateWrapper=null,this._isActive=!1,getWindowTracker()===this&&setWindowTracker(void 0);},a}();function getWindowTracker(){return "undefined"==typeof window?void 0:window[WIN_TRACKER_KEY]}function setWindowTracker(a){if("undefined"!=typeof window){var b=window;a?b[WIN_TRACKER_KEY]=a:delete b[WIN_TRACKER_KEY];}}
1667
1678
 
1668
1679
  var Messages=Constants.Messages,HTTPCodes=Constants.HTTPCodes,FeatureFlags=Constants.FeatureFlags,CaptureIntegrationSpecificIdsV2Modes=Constants.CaptureIntegrationSpecificIdsV2Modes,ReportBatching=FeatureFlags.ReportBatching,CaptureIntegrationSpecificIds=FeatureFlags.CaptureIntegrationSpecificIds,CaptureIntegrationSpecificIdsV2=FeatureFlags.CaptureIntegrationSpecificIdsV2,StartingInitialization=Messages.InformationMessages.StartingInitialization;/**
1669
1680
  * <p>All of the following methods can be called on the primary mParticle class. In version 2.10.0, we introduced <a href="https://docs.mparticle.com/developers/sdk/web/multiple-instances/">multiple instances</a>. If you are using multiple instances (self hosted environments only), you should call these methods on each instance.</p>
@@ -1680,7 +1691,7 @@ var Messages=Constants.Messages,HTTPCodes=Constants.HTTPCodes,FeatureFlags=Const
1680
1691
  this._instanceName=a,this._NativeSdkHelpers=new NativeSdkHelpers(this),this._SessionManager=new SessionManager(this),this._Persistence=new _Persistence(this),this._Helpers=new Helpers(this),this._Events=new Events(this),this._CookieSyncManager=new CookieSyncManager(this),this._ServerModel=new ServerModel(this),this._Ecommerce=new Ecommerce(this),this._ForwardingStatsUploader=new forwardingStatsUploader(this),this._Consent=new Consent(this),this._IdentityAPIClient=new IdentityAPIClient(this),this._preInit={readyQueue:[],integrationDelays:{},forwarderConstructors:[]},this._ErrorReportingDispatcher=new ErrorReportingDispatcher,this._LoggingDispatcher=new LoggingDispatcher,this._RoktManager=new RoktManager,this._RoktManager.setOnReadyCallback(function(){b.processQueueOnIdentityFailure();}),this.processQueueOnIdentityFailure=function(){var a,c,d;(null===(a=b._Store)||void 0===a?void 0:a.isInitialized)||(null===(c=b._Store)||void 0===c?void 0:c.identityCallFailed)&&(null===(d=b._RoktManager)||void 0===d?void 0:d.isReady())&&(b._RoktManager.processMessageQueue(),b._preInit.readyQueue=processReadyQueue(b._preInit.readyQueue,b.Logger));},this.processQueueOnNoFunctional=function(){var a,c;if(!(null!==(a=b._Store)&&void 0!==a)||!a.isInitialized){var d=(null===(c=b._CookieConsentManager)||void 0===c?void 0:c.getNoFunctional())&&!hasExplicitIdentifier(b._Store);d&&(b._preInit.readyQueue=processReadyQueue(b._preInit.readyQueue,b.Logger));}},this.IdentityType=IdentityType,this.EventType=EventType,this.CommerceEventType=CommerceEventType,this.PromotionType=PromotionActionType,this.ProductActionType=ProductActionType,this.RoktEvents=RoktEvents,this._Identity=new Identity(this),this.Identity=this._Identity.IdentityAPI,this.generateHash=this._Helpers.generateHash,this.getDeviceId=this._Persistence.getDeviceId,"undefined"!=typeof window&&window.mParticle&&window.mParticle.config&&window.mParticle.config.hasOwnProperty("rq")&&(this._preInit.readyQueue=window.mParticle.config.rq),this.init=function(a,b){var c=this;// config code - Fetch config when requestConfig = true, otherwise, proceed with SDKInitialization
1681
1692
  // Since fetching the configuration is asynchronous, we must pass completeSDKInitialization
1682
1693
  // to it for it to be run after fetched
1683
- if(b||console.warn("You did not pass a config object to init(). mParticle will not initialize properly"),runPreConfigFetchInitialization(this,a,b),!b)return void console.error("No config available on the window, please pass a config object to mParticle.init()");if(!b.hasOwnProperty("requestConfig")||b.requestConfig){var d=new ConfigAPIClient(a,b,this);d.getSDKConfiguration().then(function(d){var e=extend({},b,d);completeSDKInitialization(a,e,c);});}else completeSDKInitialization(a,b,this);},this.setLogLevel=function(a){b.Logger.setLogLevel(a);},this.reset=function(a){try{a._Persistence.resetPersistence(),a._Store&&delete a._Store;}catch(a){console.error("Cannot reset mParticle",a);}},this._resetForTests=function(a,b,c){c._Store&&delete c._Store,c._ErrorReportingDispatcher=new ErrorReportingDispatcher,c._LoggingDispatcher=new LoggingDispatcher,c.Logger=new Logger(a),c._ErrorReportingDispatcher.logger=c.Logger,c._LoggingDispatcher.logger=c.Logger,c._Store=new Store(a,c),c._Store.isLocalStorageAvailable=c._Persistence.determineLocalStorageAvailability(window.localStorage),c._Events.stopTracking(),b||c._Persistence.resetPersistence(),c._Persistence.forwardingStatsBatches.uploadsTable={},c._Persistence.forwardingStatsBatches.forwardingStatsEventQueue=[],c._preInit={readyQueue:[],pixelConfigurations:[],integrationDelays:{},forwarderConstructors:[],isDevelopmentMode:!1};},this.ready=function(a){var c,d,e,f=(null===(c=b._CookieConsentManager)||void 0===c?void 0:c.getNoFunctional())&&!hasExplicitIdentifier(b._Store),g=isFunction(a)&&((null===(d=b._Store)||void 0===d?void 0:d.isInitialized)||(null===(e=b._Store)||void 0===e?void 0:e.identityCallFailed)&&b._RoktManager.isReady()||f);g?a():b._preInit.readyQueue.push(a);},this.getEnvironment=function(){return b._Store.SDKConfig.isDevelopmentMode?Constants.Environment.Development:Constants.Environment.Production},this.getVersion=function(){return Constants.sdkVersion},this.setAppVersion=function(a){var c=queueIfNotInitialized(function(){b.setAppVersion(a);},b);c||(b._Store.SDKConfig.appVersion=a,b._Persistence.update());},this.setDeviceId=function(a){var c=queueIfNotInitialized(function(){b.setDeviceId(a);},b);c||this._Store.setDeviceId(a);},this.isInitialized=function(){return !!b._Store&&b._Store.isInitialized},this.getAppName=function(){return b._Store.SDKConfig.appName},this.setAppName=function(a){var c=queueIfNotInitialized(function(){b.setAppName(a);},b);c||(b._Store.SDKConfig.appName=a);},this.getAppVersion=function(){return b._Store.SDKConfig.appVersion},this.stopTrackingLocation=function(){b._SessionManager.resetSessionTimer(),b._Events.stopTracking();},this.startTrackingLocation=function(a){isFunction(a)||b.Logger.warning("Warning: Location tracking is triggered, but not including a callback into the `startTrackingLocation` may result in events logged too quickly and not being associated with a location."),b._SessionManager.resetSessionTimer(),b._Events.startTracking(a);},this.setPosition=function(a,c){var d=queueIfNotInitialized(function(){b.setPosition(a,c);},b);d||(b._SessionManager.resetSessionTimer(),"number"==typeof a&&"number"==typeof c?b._Store.currentPosition={lat:a,lng:c}:b.Logger.error("Position latitude and/or longitude must both be of type number"));},this.startNewSession=function(){b._SessionManager.startNewSession();},this.endSession=function(){// Sends true as an over ride vs when endSession is called from the setInterval
1694
+ if(b||console.warn("You did not pass a config object to init(). mParticle will not initialize properly"),runPreConfigFetchInitialization(this,a,b),!b)return void console.error("No config available on the window, please pass a config object to mParticle.init()");if(!b.hasOwnProperty("requestConfig")||b.requestConfig){var d=new ConfigAPIClient(a,b,this);d.getSDKConfiguration().then(function(d){var e=extend({},b,d);completeSDKInitialization(a,e,c);});}else completeSDKInitialization(a,b,this);},this.setLogLevel=function(a){b.Logger.setLogLevel(a);},this.reset=function(a){try{a._Persistence.resetPersistence(),a._Store&&delete a._Store;}catch(a){console.error("Cannot reset mParticle",a);}},this._resetForTests=function(a,b,c){c._Store&&delete c._Store,c._ErrorReportingDispatcher=new ErrorReportingDispatcher,c._LoggingDispatcher=new LoggingDispatcher,c.Logger=new Logger(a),c._ErrorReportingDispatcher.logger=c.Logger,c._LoggingDispatcher.logger=c.Logger,c._Store=new Store(a,c),c._Store.isLocalStorageAvailable=c._Persistence.determineLocalStorageAvailability(window.localStorage),c._Events.stopTracking();var d=c._PageViewTracker;d&&(d.teardown(),c._PageViewTracker=void 0),PageViewTracker.resetWindowState(d),b||c._Persistence.resetPersistence(),c._Persistence.forwardingStatsBatches.uploadsTable={},c._Persistence.forwardingStatsBatches.forwardingStatsEventQueue=[],c._preInit={readyQueue:[],pixelConfigurations:[],integrationDelays:{},forwarderConstructors:[],isDevelopmentMode:!1};},this.ready=function(a){var c,d,e,f=(null===(c=b._CookieConsentManager)||void 0===c?void 0:c.getNoFunctional())&&!hasExplicitIdentifier(b._Store),g=isFunction(a)&&((null===(d=b._Store)||void 0===d?void 0:d.isInitialized)||(null===(e=b._Store)||void 0===e?void 0:e.identityCallFailed)&&b._RoktManager.isReady()||f);g?a():b._preInit.readyQueue.push(a);},this.getEnvironment=function(){return b._Store.SDKConfig.isDevelopmentMode?Constants.Environment.Development:Constants.Environment.Production},this.getVersion=function(){return Constants.sdkVersion},this.setAppVersion=function(a){var c=queueIfNotInitialized(function(){b.setAppVersion(a);},b);c||(b._Store.SDKConfig.appVersion=a,b._Persistence.update());},this.setDeviceId=function(a){var c=queueIfNotInitialized(function(){b.setDeviceId(a);},b);c||this._Store.setDeviceId(a);},this.isInitialized=function(){return !!b._Store&&b._Store.isInitialized},this.getAppName=function(){return b._Store.SDKConfig.appName},this.setAppName=function(a){var c=queueIfNotInitialized(function(){b.setAppName(a);},b);c||(b._Store.SDKConfig.appName=a);},this.getAppVersion=function(){return b._Store.SDKConfig.appVersion},this.stopTrackingLocation=function(){b._SessionManager.resetSessionTimer(),b._Events.stopTracking();},this.startTrackingLocation=function(a){isFunction(a)||b.Logger.warning("Warning: Location tracking is triggered, but not including a callback into the `startTrackingLocation` may result in events logged too quickly and not being associated with a location."),b._SessionManager.resetSessionTimer(),b._Events.startTracking(a);},this.setPosition=function(a,c){var d=queueIfNotInitialized(function(){b.setPosition(a,c);},b);d||(b._SessionManager.resetSessionTimer(),"number"==typeof a&&"number"==typeof c?b._Store.currentPosition={lat:a,lng:c}:b.Logger.error("Position latitude and/or longitude must both be of type number"));},this.startNewSession=function(){b._SessionManager.startNewSession();},this.endSession=function(){// Sends true as an over ride vs when endSession is called from the setInterval
1684
1695
  b._SessionManager.endSession(!0);},this.logBaseEvent=function(a,c){var d=queueIfNotInitialized(function(){b.logBaseEvent(a,c);},b);if(!d)return (b._SessionManager.resetSessionTimer(),"string"!=typeof a.name)?void b.Logger.error(Messages.ErrorMessages.EventNameInvalidType):(a.eventType||(a.eventType=EventType.Unknown),b._Helpers.canLog()?void b._Events.logEvent(a,c):void b.Logger.error(Messages.ErrorMessages.LoggingDisabled))},this.logEvent=function(a,c,d,e,f){var g=queueIfNotInitialized(function(){b.logEvent(a,c,d,e,f);},b);if(!g)return (b._SessionManager.resetSessionTimer(),"string"!=typeof a)?void b.Logger.error(Messages.ErrorMessages.EventNameInvalidType):(c||(c=EventType.Unknown),b._Helpers.isEventType(c)?b._Helpers.canLog()?void b._Events.logEvent({messageType:MessageType$1.PageEvent,name:a,data:d,eventType:c,customFlags:e},f):void b.Logger.error(Messages.ErrorMessages.LoggingDisabled):void b.Logger.error("Invalid event type: "+c+", must be one of: \n"+JSON.stringify(EventType)))},this.logError=function(a,c){var d=queueIfNotInitialized(function(){b.logError(a,c);},b);if(!d&&(b._SessionManager.resetSessionTimer(),!!a)){"string"==typeof a&&(a={message:a});var e={m:a.message?a.message:a,s:"Error",t:a.stack||null};if(c){var f=b._Helpers.sanitizeAttributes(c,e.m);for(var g in f)e[g]=f[g];}b._Events.logEvent({messageType:MessageType$1.CrashReport,name:a.name?a.name:"Error",eventType:EventType.Other,data:e});}},this.logLink=function(a,c,d,e){b._Events.addEventHandler("click",a,c,e,d);},this.logForm=function(a,c,d,e){b._Events.addEventHandler("submit",a,c,e,d);},this.logPageView=function(a,c,d,e){var f=queueIfNotInitialized(function(){b.logPageView(a,c,d,e);},b);if(!f){if(b._SessionManager.resetSessionTimer(),b._Helpers.canLog()){if(b._Helpers.Validators.isStringOrNumber(a)||(a="PageView"),!c)c={hostname:window.location.hostname,title:window.document.title};else if(!b._Helpers.isObject(c))return void b.Logger.error("The attributes argument must be an object. A "+_typeof$1(c)+" was entered. Please correct and retry.");if(d&&!b._Helpers.isObject(d))return void b.Logger.error("The customFlags argument must be an object. A "+_typeof$1(d)+" was entered. Please correct and retry.")}b._Events.logEvent({messageType:MessageType$1.PageView,name:a,data:c,eventType:EventType.Unknown,customFlags:d},e);}},this.upload=function(){var a,c;b._Helpers.canLog()&&(b._Store.webviewBridgeEnabled?b._NativeSdkHelpers.sendToNative(Constants.NativeSdkPaths.Upload):null===(c=null===(a=b._APIClient)||void 0===a?void 0:a.uploader)||void 0===c?void 0:c.prepareAndUpload(!1,!1));},this.Consent={/**
1685
1696
  * Creates a CCPA Opt Out Consent State.
1686
1697
  *
@@ -1842,7 +1853,7 @@ if((null===(d=c._APIClient)||void 0===d?void 0:d.uploader)&&c._APIClient.uploade
1842
1853
  var k=c.Identity.getCurrentUser(),l=k?k.getMPID():null,m=k?k.getUserIdentities().userIdentities:{};c._Store.SDKConfig.identifyRequest=c._Store.hasInvalidIdentifyRequest()?{userIdentities:m}:c._Store.SDKConfig.identifyRequest,i(ReportBatching)&&c._ForwardingStatsUploader.startForwardingStatsTimer();// https://go.mparticle.com/work/SQDSDKS-7639
1843
1854
  var n=i(CaptureIntegrationSpecificIds),o=i(CaptureIntegrationSpecificIdsV2),p=o&&o!==CaptureIntegrationSpecificIdsV2Modes.None||!0===n;if(p){var q;n||o===CaptureIntegrationSpecificIdsV2Modes.All?q="all":o===CaptureIntegrationSpecificIdsV2Modes.RoktOnly&&(q="roktonly"),c._IntegrationCapture=new IntegrationCapture(q),c._IntegrationCapture.capture();}// Configure Rokt Manager with user and filtered user
1844
1855
  var r=parseConfig(b,"Rokt",181);if(r){var s=null===(e=r.settings)||void 0===e?void 0:e.accountId;c._Store.setRoktAccountId(s);var t=r.userAttributeFilters,u=filteredMparticleUser(l,{userAttributeFilters:t},c),v={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
1845
- c._RoktManager.init(r,u,c.Identity,c._Store,c.Logger,v,c.captureTiming,c._ErrorReportingDispatcher,c._LoggingDispatcher,c._IntegrationCapture);}c._Forwarders.processForwarders(b,c._APIClient.prepareForwardingStats),c._Forwarders.processPixelConfigs(b),c._SessionManager.initialize(),c._Events.logAST(),i(j)?(c._Events.logPageView(),!c._PageViewTracker&&(c._PageViewTracker=new PageViewTracker(c)),c._PageViewTracker.init()):c._PageViewTracker&&c._PageViewTracker.teardown(),processIdentityCallback(c,k,l,m);}// We will continue to clear out the ready queue as part of the initial init flow
1856
+ c._RoktManager.init(r,u,c.Identity,c._Store,c.Logger,v,c.captureTiming,c._ErrorReportingDispatcher,c._LoggingDispatcher,c._IntegrationCapture);}c._Forwarders.processForwarders(b,c._APIClient.prepareForwardingStats),c._Forwarders.processPixelConfigs(b),c._SessionManager.initialize(),c._Events.logAST(),i(j)?(c._PageViewTracker?c.Logger.verbose("mParticle APV: [sdk-init] tracker already on this instance, skipping logPageView"):(c.Logger.verbose("mParticle APV: [sdk-init] creating new PageViewTracker for this instance"),c._PageViewTracker=new PageViewTracker(c),PageViewTracker.hasInitialPageViewFired()?c.Logger.verbose("mParticle APV: [sdk-init] initial page view already logged this page load, skipping"):(PageViewTracker.markInitialPageViewFired(),c._Events.logPageView())),c._PageViewTracker.init()):c._PageViewTracker&&c._PageViewTracker.teardown(),processIdentityCallback(c,k,l,m);}// We will continue to clear out the ready queue as part of the initial init flow
1846
1857
  // if an identify request is unnecessary, such as if there is an existing session
1847
1858
  (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,c.Logger)),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
1848
1859
  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:
package/dist/mparticle.js CHANGED
@@ -204,7 +204,7 @@ var mParticle = (function () {
204
204
  Base64: Base64$1
205
205
  };
206
206
 
207
- var version = "2.79.1";
207
+ var version = "2.79.2";
208
208
 
209
209
  var Constants = {
210
210
  sdkVersion: version,
@@ -11173,10 +11173,19 @@ var mParticle = (function () {
11173
11173
  }();
11174
11174
 
11175
11175
  var WRAPPED_MARKER = '__mpApvWrapped__';
11176
+ // window key under which the single active tracker is stored.
11177
+ // Survives module re-evaluation (Next.js re-executes the bundle on every SPA
11178
+ // navigation, resetting all module-level state, but window persists for the
11179
+ // lifetime of the tab).
11180
+ var WIN_TRACKER_KEY = '__mpApvTracker__';
11181
+ // Guards the initial page view so repeated mParticle.init() calls from SPA
11182
+ // re-renders don't fire duplicate logPageView() events for the same page.
11183
+ var WIN_INIT_PV_KEY = '__mpApvInitPVLogged__';
11176
11184
  var PageViewTracker = /** @class */function () {
11177
11185
  function PageViewTracker(mpInstance) {
11178
11186
  this.lastPath = null;
11179
- this.isActive = false;
11187
+ this._isActive = false;
11188
+ this.pendingNavigations = [];
11180
11189
  this.originalPushState = null;
11181
11190
  this.originalReplaceState = null;
11182
11191
  this.pushStateWrapper = null;
@@ -11184,31 +11193,91 @@ var mParticle = (function () {
11184
11193
  this.popStateListener = null;
11185
11194
  this.mpInstance = mpInstance;
11186
11195
  }
11196
+ PageViewTracker.hasInitialPageViewFired = function () {
11197
+ return !!window[WIN_INIT_PV_KEY];
11198
+ };
11199
+ PageViewTracker.markInitialPageViewFired = function () {
11200
+ window[WIN_INIT_PV_KEY] = true;
11201
+ };
11202
+ // Tears down any window-registered tracker that differs from instanceTracker
11203
+ // (e.g. left by a previous module load), then clears both APV window flags.
11204
+ // Call from _resetForTests after tearing down the instance-level tracker.
11205
+ PageViewTracker.resetWindowState = function (instanceTracker) {
11206
+ var windowTracker = getWindowTracker();
11207
+ if (windowTracker && windowTracker !== instanceTracker) {
11208
+ windowTracker.teardown();
11209
+ }
11210
+ if (typeof window !== 'undefined') {
11211
+ delete window[WIN_INIT_PV_KEY];
11212
+ }
11213
+ setWindowTracker(undefined);
11214
+ };
11215
+ Object.defineProperty(PageViewTracker.prototype, "isActive", {
11216
+ get: function get() {
11217
+ return this._isActive;
11218
+ },
11219
+ enumerable: false,
11220
+ configurable: true
11221
+ });
11187
11222
  PageViewTracker.prototype.isSupportedEnvironment = function () {
11188
11223
  return typeof window !== 'undefined' && typeof window.history !== 'undefined' && typeof window.history.pushState === 'function' && typeof window.addEventListener === 'function';
11189
11224
  };
11190
11225
  PageViewTracker.prototype.init = function () {
11226
+ var _this = this;
11191
11227
  this.mpInstance.Logger.verbose('mParticle APV: [init] PageViewTracker Init');
11192
11228
  if (!this.isSupportedEnvironment()) {
11193
11229
  this.mpInstance.Logger.verbose('mParticle APV: [init] unsupported environment (no History API), not starting');
11194
11230
  return;
11195
11231
  }
11196
- if (this.isActive) {
11232
+ // Tear down any tracker left over from a previous module load.
11233
+ // window[WIN_TRACKER_KEY] outlives module re-evaluation; this is the
11234
+ // only way to reach a tracker instance in a dead module scope.
11235
+ // Transfer any pending navigations first so a route change that queued a
11236
+ // deferred fire before module re-evaluation occurs is not silently dropped.
11237
+ var prev = getWindowTracker();
11238
+ var inheritedPaths = [];
11239
+ if (prev && prev !== this) {
11240
+ this.mpInstance.Logger.verbose('mParticle APV: [init] found stale tracker from previous module load — transferring pending navigations and tearing down');
11241
+ inheritedPaths = prev.takePendingNavigations();
11242
+ prev.teardown();
11243
+ }
11244
+ if (this._isActive) {
11197
11245
  this.mpInstance.Logger.verbose('mParticle APV: [init] starting (teardown-first for idempotency)');
11246
+ // Preserve pending navigations through the self-teardown so a route
11247
+ // change queued before mParticle.init() was called again is not lost.
11248
+ inheritedPaths = __spreadArray(__spreadArray([], inheritedPaths, true), this.takePendingNavigations(), true);
11198
11249
  this.teardown();
11199
11250
  }
11200
- this.isActive = true;
11251
+ this._isActive = true;
11201
11252
  this.lastPath = this.getCurrentKey();
11202
11253
  this.mpInstance.Logger.verbose("mParticle APV: [init] seeded lastPath: ".concat(this.lastPath));
11203
11254
  this.patchHistoryMethods();
11204
11255
  this.addNavigationListeners();
11256
+ setWindowTracker(this);
11205
11257
  this.mpInstance.Logger.verbose('mParticle APV: [init] patched pushState/replaceState + listening for popstate');
11258
+ // Re-fire navigations that the stale tracker had queued but not yet flushed
11259
+ // when module re-evaluation occurred. Title is read at flush time so the
11260
+ // router's post-navigation render commit still has a chance to update it.
11261
+ inheritedPaths.forEach(function (path) {
11262
+ var timeoutId = setTimeout(function () {
11263
+ _this.pendingNavigations = _this.pendingNavigations.filter(function (p) {
11264
+ return p.timeoutId !== timeoutId;
11265
+ });
11266
+ if (!_this._isActive) return;
11267
+ _this.mpInstance._SessionManager.resetSessionTimer();
11268
+ _this.firePageView(path);
11269
+ }, 0);
11270
+ _this.pendingNavigations.push({
11271
+ path: path,
11272
+ timeoutId: timeoutId
11273
+ });
11274
+ });
11206
11275
  };
11207
11276
  PageViewTracker.prototype.patchHistoryMethods = function () {
11208
11277
  var self = this;
11209
11278
  var installed = window.history.pushState;
11210
11279
  if (installed[WRAPPED_MARKER]) {
11211
- this.mpInstance.Logger.verbose('mParticle APV: [patch] history already wrapped, skipping to avoid double-wrap');
11280
+ this.mpInstance.Logger.verbose('mParticle APV: [patch] history already wrapped, skipping to avoid double-wrap — STACKED WRAPPER DETECTED');
11212
11281
  return;
11213
11282
  }
11214
11283
  var originalPushState = window.history.pushState;
@@ -11221,7 +11290,9 @@ var mParticle = (function () {
11221
11290
  args[_i] = arguments[_i];
11222
11291
  }
11223
11292
  var result = originalPushState.apply(this, args);
11224
- self.safeHandleNavigation('pushState');
11293
+ if (self._isActive) {
11294
+ self.safeHandleNavigation('pushState');
11295
+ }
11225
11296
  return result;
11226
11297
  };
11227
11298
  var replaceStateWrapper = function replaceStateWrapper() {
@@ -11230,7 +11301,9 @@ var mParticle = (function () {
11230
11301
  args[_i] = arguments[_i];
11231
11302
  }
11232
11303
  var result = originalReplaceState.apply(this, args);
11233
- self.safeHandleNavigation('replaceState');
11304
+ if (self._isActive) {
11305
+ self.safeHandleNavigation('replaceState');
11306
+ }
11234
11307
  return result;
11235
11308
  };
11236
11309
  Object.defineProperty(pushStateWrapper, WRAPPED_MARKER, {
@@ -11297,14 +11370,21 @@ var mParticle = (function () {
11297
11370
  // later (in the deferred flush) so the router's post-navigation render
11298
11371
  // commit has a chance to update document.title first.
11299
11372
  var capturedPath = candidatePath;
11300
- setTimeout(function () {
11301
- if (!_this.isActive) {
11373
+ var timeoutId = setTimeout(function () {
11374
+ _this.pendingNavigations = _this.pendingNavigations.filter(function (p) {
11375
+ return p.timeoutId !== timeoutId;
11376
+ });
11377
+ if (!_this._isActive) {
11302
11378
  _this.mpInstance.Logger.verbose('mParticle APV: [defer] fire aborted, tracker inactive (torn down before flush)');
11303
11379
  return;
11304
11380
  }
11305
11381
  _this.mpInstance._SessionManager.resetSessionTimer();
11306
11382
  _this.firePageView(capturedPath);
11307
11383
  }, 0);
11384
+ this.pendingNavigations.push({
11385
+ path: capturedPath,
11386
+ timeoutId: timeoutId
11387
+ });
11308
11388
  };
11309
11389
  // Mirrors the event shape of the public mParticle.logPageView(), but carries
11310
11390
  // the captured SPA path rather than reading the live location.
@@ -11322,37 +11402,67 @@ var mParticle = (function () {
11322
11402
  eventType: EventType.Unknown
11323
11403
  });
11324
11404
  };
11405
+ // Cancels pending deferred fires and returns their captured paths so a
11406
+ // successor tracker can re-schedule them. Call before teardown() during
11407
+ // module-replacement handoff.
11408
+ PageViewTracker.prototype.takePendingNavigations = function () {
11409
+ var paths = this.pendingNavigations.map(function (p) {
11410
+ return p.path;
11411
+ });
11412
+ this.pendingNavigations.forEach(function (p) {
11413
+ return clearTimeout(p.timeoutId);
11414
+ });
11415
+ this.pendingNavigations = [];
11416
+ return paths;
11417
+ };
11418
+ PageViewTracker.prototype.restoreHistoryMethod = function (methodName, original, wrapper) {
11419
+ if (!original) return;
11420
+ var stillOurs = wrapper !== null && window.history[methodName] === wrapper;
11421
+ if (stillOurs) {
11422
+ window.history[methodName] = original;
11423
+ this.mpInstance.Logger.verbose("mParticle APV: [teardown] restored original ".concat(methodName));
11424
+ } else {
11425
+ this.mpInstance.Logger.verbose("mParticle APV: [teardown] ".concat(methodName, " no longer ours; leaving in place, gating callback to no-op"));
11426
+ }
11427
+ };
11325
11428
  PageViewTracker.prototype.teardown = function () {
11429
+ // Cancel any pending deferred fires (e.g. when the feature flag is
11430
+ // disabled on re-init). For module-replacement, call takePendingNavigations()
11431
+ // before teardown() instead so paths are transferred, not discarded.
11432
+ this.pendingNavigations.forEach(function (p) {
11433
+ return clearTimeout(p.timeoutId);
11434
+ });
11435
+ this.pendingNavigations = [];
11326
11436
  if (this.popStateListener) {
11327
11437
  window.removeEventListener('popstate', this.popStateListener);
11328
11438
  this.popStateListener = null;
11329
11439
  }
11330
- var pushStateStillOurs = this.pushStateWrapper !== null && window.history.pushState === this.pushStateWrapper;
11331
- if (this.originalPushState) {
11332
- if (pushStateStillOurs) {
11333
- window.history.pushState = this.originalPushState;
11334
- this.mpInstance.Logger.verbose('mParticle APV: [teardown] restored original pushState');
11335
- } else {
11336
- this.mpInstance.Logger.verbose('mParticle APV: [teardown] pushState no longer ours; leaving in place, gating callback to no-op');
11337
- }
11338
- this.originalPushState = null;
11339
- this.pushStateWrapper = null;
11340
- }
11341
- var replaceStateStillOurs = this.replaceStateWrapper !== null && window.history.replaceState === this.replaceStateWrapper;
11342
- if (this.originalReplaceState) {
11343
- if (replaceStateStillOurs) {
11344
- window.history.replaceState = this.originalReplaceState;
11345
- this.mpInstance.Logger.verbose('mParticle APV: [teardown] restored original replaceState');
11346
- } else {
11347
- this.mpInstance.Logger.verbose('mParticle APV: [teardown] replaceState no longer ours; leaving in place, gating callback to no-op');
11348
- }
11349
- this.originalReplaceState = null;
11350
- this.replaceStateWrapper = null;
11440
+ this.restoreHistoryMethod('pushState', this.originalPushState, this.pushStateWrapper);
11441
+ this.originalPushState = null;
11442
+ this.pushStateWrapper = null;
11443
+ this.restoreHistoryMethod('replaceState', this.originalReplaceState, this.replaceStateWrapper);
11444
+ this.originalReplaceState = null;
11445
+ this.replaceStateWrapper = null;
11446
+ this._isActive = false;
11447
+ if (getWindowTracker() === this) {
11448
+ setWindowTracker(undefined);
11351
11449
  }
11352
- this.isActive = false;
11353
11450
  };
11354
11451
  return PageViewTracker;
11355
11452
  }();
11453
+ function getWindowTracker() {
11454
+ if (typeof window === 'undefined') return undefined;
11455
+ return window[WIN_TRACKER_KEY];
11456
+ }
11457
+ function setWindowTracker(tracker) {
11458
+ if (typeof window === 'undefined') return;
11459
+ var win = window;
11460
+ if (tracker) {
11461
+ win[WIN_TRACKER_KEY] = tracker;
11462
+ } else {
11463
+ delete win[WIN_TRACKER_KEY];
11464
+ }
11465
+ }
11356
11466
 
11357
11467
  var Messages = Constants.Messages,
11358
11468
  HTTPCodes = Constants.HTTPCodes,
@@ -11506,6 +11616,12 @@ var mParticle = (function () {
11506
11616
  instance._Store = new Store(config, instance);
11507
11617
  instance._Store.isLocalStorageAvailable = instance._Persistence.determineLocalStorageAvailability(window.localStorage);
11508
11618
  instance._Events.stopTracking();
11619
+ var instanceTracker = instance._PageViewTracker;
11620
+ if (instanceTracker) {
11621
+ instanceTracker.teardown();
11622
+ instance._PageViewTracker = undefined;
11623
+ }
11624
+ PageViewTracker.resetWindowState(instanceTracker);
11509
11625
  if (!keepPersistence) {
11510
11626
  instance._Persistence.resetPersistence();
11511
11627
  }
@@ -12432,13 +12548,29 @@ var mParticle = (function () {
12432
12548
  // Logs a session start or session end event accordingly
12433
12549
  mpInstance._SessionManager.initialize();
12434
12550
  mpInstance._Events.logAST();
12551
+ // Note: APV uses window-level singletons (WIN_TRACKER_KEY, WIN_INIT_PV_KEY)
12552
+ // that assume a single active SDK instance. Multiple-instance support is
12553
+ // out of scope
12435
12554
  if (getFeatureFlag(AutoLogPageView)) {
12436
- mpInstance._Events.logPageView();
12437
12555
  if (!mpInstance._PageViewTracker) {
12556
+ mpInstance.Logger.verbose('mParticle APV: [sdk-init] creating new PageViewTracker for this instance');
12438
12557
  mpInstance._PageViewTracker = new PageViewTracker(mpInstance);
12558
+ // Fire the initial page view once per page load (hard navigation).
12559
+ // The flag survives module re-evaluation so repeated init() calls
12560
+ // from SPA re-renders don't fire duplicate logPageView() events.
12561
+ if (PageViewTracker.hasInitialPageViewFired()) {
12562
+ mpInstance.Logger.verbose('mParticle APV: [sdk-init] initial page view already logged this page load, skipping');
12563
+ } else {
12564
+ PageViewTracker.markInitialPageViewFired();
12565
+ mpInstance._Events.logPageView();
12566
+ }
12567
+ } else {
12568
+ mpInstance.Logger.verbose('mParticle APV: [sdk-init] tracker already on this instance, skipping logPageView');
12439
12569
  }
12440
12570
  mpInstance._PageViewTracker.init();
12441
12571
  } else if (mpInstance._PageViewTracker) {
12572
+ // AutoLogPageView was disabled on re-init: tear down the active tracker
12573
+ // so it stops listening. Re-created if the flag is re-enabled later.
12442
12574
  mpInstance._PageViewTracker.teardown();
12443
12575
  }
12444
12576
  processIdentityCallback(mpInstance, currentUser, currentUserMPID, currentUserIdentities);
@@ -1,8 +1,19 @@
1
1
  import { IMParticleWebSDKInstance } from './mp-instance';
2
+ export declare const WIN_TRACKER_KEY = "__mpApvTracker__";
3
+ export declare const WIN_INIT_PV_KEY: "__mpApvInitPVLogged__";
4
+ export type WindowWithApvFlags = Window & {
5
+ [WIN_TRACKER_KEY]?: PageViewTracker;
6
+ [WIN_INIT_PV_KEY]?: boolean;
7
+ };
2
8
  export declare class PageViewTracker {
9
+ static hasInitialPageViewFired(): boolean;
10
+ static markInitialPageViewFired(): void;
11
+ static resetWindowState(instanceTracker?: PageViewTracker): void;
3
12
  mpInstance: IMParticleWebSDKInstance;
4
13
  private lastPath;
5
- private isActive;
14
+ private _isActive;
15
+ get isActive(): boolean;
16
+ private pendingNavigations;
6
17
  private originalPushState;
7
18
  private originalReplaceState;
8
19
  private pushStateWrapper;
@@ -17,5 +28,7 @@ export declare class PageViewTracker {
17
28
  private getCurrentKey;
18
29
  private handleNavigation;
19
30
  private firePageView;
31
+ takePendingNavigations(): string[];
32
+ private restoreHistoryMethod;
20
33
  teardown(): void;
21
34
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mparticle/web-sdk",
3
- "version": "2.79.1",
3
+ "version": "2.79.2",
4
4
  "description": "mParticle core SDK for web applications",
5
5
  "license": "Apache-2.0",
6
6
  "keywords": [
@@ -297,6 +297,14 @@ export default function mParticleInstance(this: IMParticleWebSDKInstance, instan
297
297
  window.localStorage
298
298
  );
299
299
  instance._Events.stopTracking();
300
+
301
+ const instanceTracker = instance._PageViewTracker;
302
+ if (instanceTracker) {
303
+ instanceTracker.teardown();
304
+ instance._PageViewTracker = undefined;
305
+ }
306
+ PageViewTracker.resetWindowState(instanceTracker);
307
+
300
308
  if (!keepPersistence) {
301
309
  instance._Persistence.resetPersistence();
302
310
  }
@@ -1585,14 +1593,36 @@ function completeSDKInitialization(apiKey, config, mpInstance) {
1585
1593
  mpInstance._SessionManager.initialize();
1586
1594
  mpInstance._Events.logAST();
1587
1595
 
1596
+ // Note: APV uses window-level singletons (WIN_TRACKER_KEY, WIN_INIT_PV_KEY)
1597
+ // that assume a single active SDK instance. Multiple-instance support is
1598
+ // out of scope
1588
1599
  if (getFeatureFlag(AutoLogPageView)) {
1589
- mpInstance._Events.logPageView();
1590
-
1591
1600
  if (!mpInstance._PageViewTracker) {
1601
+ mpInstance.Logger.verbose(
1602
+ 'mParticle APV: [sdk-init] creating new PageViewTracker for this instance'
1603
+ );
1592
1604
  mpInstance._PageViewTracker = new PageViewTracker(mpInstance);
1605
+
1606
+ // Fire the initial page view once per page load (hard navigation).
1607
+ // The flag survives module re-evaluation so repeated init() calls
1608
+ // from SPA re-renders don't fire duplicate logPageView() events.
1609
+ if (PageViewTracker.hasInitialPageViewFired()) {
1610
+ mpInstance.Logger.verbose(
1611
+ 'mParticle APV: [sdk-init] initial page view already logged this page load, skipping'
1612
+ );
1613
+ } else {
1614
+ PageViewTracker.markInitialPageViewFired();
1615
+ mpInstance._Events.logPageView();
1616
+ }
1617
+ } else {
1618
+ mpInstance.Logger.verbose(
1619
+ 'mParticle APV: [sdk-init] tracker already on this instance, skipping logPageView'
1620
+ );
1593
1621
  }
1594
1622
  mpInstance._PageViewTracker.init();
1595
1623
  } else if (mpInstance._PageViewTracker) {
1624
+ // AutoLogPageView was disabled on re-init: tear down the active tracker
1625
+ // so it stops listening. Re-created if the flag is re-enabled later.
1596
1626
  mpInstance._PageViewTracker.teardown();
1597
1627
  }
1598
1628
 
@@ -9,11 +9,59 @@ type MarkedHistoryMethod = HistoryStateMethod & {
9
9
  [WRAPPED_MARKER]?: boolean;
10
10
  };
11
11
 
12
+ // window key under which the single active tracker is stored.
13
+ // Survives module re-evaluation (Next.js re-executes the bundle on every SPA
14
+ // navigation, resetting all module-level state, but window persists for the
15
+ // lifetime of the tab).
16
+ export const WIN_TRACKER_KEY = '__mpApvTracker__';
17
+
18
+ // Guards the initial page view so repeated mParticle.init() calls from SPA
19
+ // re-renders don't fire duplicate logPageView() events for the same page.
20
+ export const WIN_INIT_PV_KEY = '__mpApvInitPVLogged__' as const;
21
+
22
+ export type WindowWithApvFlags = Window & {
23
+ [WIN_TRACKER_KEY]?: PageViewTracker;
24
+ [WIN_INIT_PV_KEY]?: boolean;
25
+ };
26
+
27
+ type NavigationSource = 'pushState' | 'replaceState' | 'popstate';
28
+
12
29
  export class PageViewTracker {
30
+ static hasInitialPageViewFired(): boolean {
31
+ return !!(window as WindowWithApvFlags)[WIN_INIT_PV_KEY];
32
+ }
33
+
34
+ static markInitialPageViewFired(): void {
35
+ (window as WindowWithApvFlags)[WIN_INIT_PV_KEY] = true;
36
+ }
37
+
38
+ // Tears down any window-registered tracker that differs from instanceTracker
39
+ // (e.g. left by a previous module load), then clears both APV window flags.
40
+ // Call from _resetForTests after tearing down the instance-level tracker.
41
+ static resetWindowState(instanceTracker?: PageViewTracker): void {
42
+ const windowTracker = getWindowTracker();
43
+ if (windowTracker && windowTracker !== instanceTracker) {
44
+ windowTracker.teardown();
45
+ }
46
+ if (typeof window !== 'undefined') {
47
+ delete (window as WindowWithApvFlags)[WIN_INIT_PV_KEY];
48
+ }
49
+ setWindowTracker(undefined);
50
+ }
51
+
13
52
  mpInstance: IMParticleWebSDKInstance;
14
53
 
15
54
  private lastPath: string | null = null;
16
- private isActive = false;
55
+ private _isActive = false;
56
+
57
+ get isActive(): boolean {
58
+ return this._isActive;
59
+ }
60
+
61
+ private pendingNavigations: Array<{
62
+ path: string;
63
+ timeoutId: ReturnType<typeof setTimeout>;
64
+ }> = [];
17
65
 
18
66
  private originalPushState: HistoryStateMethod | null = null;
19
67
  private originalReplaceState: HistoryStateMethod | null = null;
@@ -37,9 +85,7 @@ export class PageViewTracker {
37
85
  }
38
86
 
39
87
  public init(): void {
40
- this.mpInstance.Logger.verbose(
41
- 'mParticle APV: [init] PageViewTracker Init'
42
- );
88
+ this.mpInstance.Logger.verbose('mParticle APV: [init] PageViewTracker Init');
43
89
  if (!this.isSupportedEnvironment()) {
44
90
  this.mpInstance.Logger.verbose(
45
91
  'mParticle APV: [init] unsupported environment (no History API), not starting'
@@ -47,14 +93,32 @@ export class PageViewTracker {
47
93
  return;
48
94
  }
49
95
 
50
- if (this.isActive) {
96
+ // Tear down any tracker left over from a previous module load.
97
+ // window[WIN_TRACKER_KEY] outlives module re-evaluation; this is the
98
+ // only way to reach a tracker instance in a dead module scope.
99
+ // Transfer any pending navigations first so a route change that queued a
100
+ // deferred fire before module re-evaluation occurs is not silently dropped.
101
+ const prev = getWindowTracker();
102
+ let inheritedPaths: string[] = [];
103
+ if (prev && prev !== this) {
104
+ this.mpInstance.Logger.verbose(
105
+ 'mParticle APV: [init] found stale tracker from previous module load — transferring pending navigations and tearing down'
106
+ );
107
+ inheritedPaths = prev.takePendingNavigations();
108
+ prev.teardown();
109
+ }
110
+
111
+ if (this._isActive) {
51
112
  this.mpInstance.Logger.verbose(
52
113
  'mParticle APV: [init] starting (teardown-first for idempotency)'
53
114
  );
115
+ // Preserve pending navigations through the self-teardown so a route
116
+ // change queued before mParticle.init() was called again is not lost.
117
+ inheritedPaths = [...inheritedPaths, ...this.takePendingNavigations()];
54
118
  this.teardown();
55
119
  }
56
120
 
57
- this.isActive = true;
121
+ this._isActive = true;
58
122
 
59
123
  this.lastPath = this.getCurrentKey();
60
124
 
@@ -65,9 +129,26 @@ export class PageViewTracker {
65
129
  this.patchHistoryMethods();
66
130
  this.addNavigationListeners();
67
131
 
132
+ setWindowTracker(this);
133
+
68
134
  this.mpInstance.Logger.verbose(
69
135
  'mParticle APV: [init] patched pushState/replaceState + listening for popstate'
70
136
  );
137
+
138
+ // Re-fire navigations that the stale tracker had queued but not yet flushed
139
+ // when module re-evaluation occurred. Title is read at flush time so the
140
+ // router's post-navigation render commit still has a chance to update it.
141
+ inheritedPaths.forEach(path => {
142
+ const timeoutId = setTimeout(() => {
143
+ this.pendingNavigations = this.pendingNavigations.filter(
144
+ p => p.timeoutId !== timeoutId
145
+ );
146
+ if (!this._isActive) return;
147
+ this.mpInstance._SessionManager.resetSessionTimer();
148
+ this.firePageView(path);
149
+ }, 0);
150
+ this.pendingNavigations.push({ path, timeoutId });
151
+ });
71
152
  }
72
153
 
73
154
  private patchHistoryMethods(): void {
@@ -76,7 +157,7 @@ export class PageViewTracker {
76
157
  const installed = window.history.pushState as MarkedHistoryMethod;
77
158
  if (installed[WRAPPED_MARKER]) {
78
159
  this.mpInstance.Logger.verbose(
79
- 'mParticle APV: [patch] history already wrapped, skipping to avoid double-wrap'
160
+ 'mParticle APV: [patch] history already wrapped, skipping to avoid double-wrap — STACKED WRAPPER DETECTED'
80
161
  );
81
162
  return;
82
163
  }
@@ -91,7 +172,9 @@ export class PageViewTracker {
91
172
  ...args: Parameters<HistoryStateMethod>
92
173
  ): void {
93
174
  const result = originalPushState.apply(this, args);
94
- self.safeHandleNavigation('pushState');
175
+ if (self._isActive) {
176
+ self.safeHandleNavigation('pushState');
177
+ }
95
178
  return result;
96
179
  };
97
180
 
@@ -100,7 +183,9 @@ export class PageViewTracker {
100
183
  ...args: Parameters<HistoryStateMethod>
101
184
  ): void {
102
185
  const result = originalReplaceState.apply(this, args);
103
- self.safeHandleNavigation('replaceState');
186
+ if (self._isActive) {
187
+ self.safeHandleNavigation('replaceState');
188
+ }
104
189
  return result;
105
190
  };
106
191
 
@@ -147,7 +232,7 @@ export class PageViewTracker {
147
232
  window.addEventListener('popstate', this.popStateListener);
148
233
  }
149
234
 
150
- private safeHandleNavigation(source: string): void {
235
+ private safeHandleNavigation(source: NavigationSource): void {
151
236
  try {
152
237
  this.handleNavigation(source);
153
238
  } catch (e) {
@@ -161,7 +246,7 @@ export class PageViewTracker {
161
246
  return window.location.pathname;
162
247
  }
163
248
 
164
- private handleNavigation(source: string): void {
249
+ private handleNavigation(source: NavigationSource): void {
165
250
  const candidatePath = this.getCurrentKey();
166
251
 
167
252
  this.mpInstance.Logger.verbose(
@@ -187,8 +272,11 @@ export class PageViewTracker {
187
272
  // commit has a chance to update document.title first.
188
273
  const capturedPath = candidatePath;
189
274
 
190
- setTimeout(() => {
191
- if (!this.isActive) {
275
+ const timeoutId = setTimeout(() => {
276
+ this.pendingNavigations = this.pendingNavigations.filter(
277
+ p => p.timeoutId !== timeoutId
278
+ );
279
+ if (!this._isActive) {
192
280
  this.mpInstance.Logger.verbose(
193
281
  'mParticle APV: [defer] fire aborted, tracker inactive (torn down before flush)'
194
282
  );
@@ -198,6 +286,7 @@ export class PageViewTracker {
198
286
  this.mpInstance._SessionManager.resetSessionTimer();
199
287
  this.firePageView(capturedPath);
200
288
  }, 0);
289
+ this.pendingNavigations.push({ path: capturedPath, timeoutId });
201
290
  }
202
291
 
203
292
  // Mirrors the event shape of the public mParticle.logPageView(), but carries
@@ -221,47 +310,73 @@ export class PageViewTracker {
221
310
  });
222
311
  }
223
312
 
313
+ // Cancels pending deferred fires and returns their captured paths so a
314
+ // successor tracker can re-schedule them. Call before teardown() during
315
+ // module-replacement handoff.
316
+ public takePendingNavigations(): string[] {
317
+ const paths = this.pendingNavigations.map(p => p.path);
318
+ this.pendingNavigations.forEach(p => clearTimeout(p.timeoutId));
319
+ this.pendingNavigations = [];
320
+ return paths;
321
+ }
322
+
323
+ private restoreHistoryMethod(
324
+ methodName: 'pushState' | 'replaceState',
325
+ original: HistoryStateMethod | null,
326
+ wrapper: HistoryStateMethod | null
327
+ ): void {
328
+ if (!original) return;
329
+ const stillOurs = wrapper !== null && window.history[methodName] === wrapper;
330
+ if (stillOurs) {
331
+ window.history[methodName] = original;
332
+ this.mpInstance.Logger.verbose(
333
+ `mParticle APV: [teardown] restored original ${methodName}`
334
+ );
335
+ } else {
336
+ this.mpInstance.Logger.verbose(
337
+ `mParticle APV: [teardown] ${methodName} no longer ours; leaving in place, gating callback to no-op`
338
+ );
339
+ }
340
+ }
341
+
224
342
  public teardown(): void {
343
+ // Cancel any pending deferred fires (e.g. when the feature flag is
344
+ // disabled on re-init). For module-replacement, call takePendingNavigations()
345
+ // before teardown() instead so paths are transferred, not discarded.
346
+ this.pendingNavigations.forEach(p => clearTimeout(p.timeoutId));
347
+ this.pendingNavigations = [];
348
+
225
349
  if (this.popStateListener) {
226
350
  window.removeEventListener('popstate', this.popStateListener);
227
351
  this.popStateListener = null;
228
352
  }
229
- const pushStateStillOurs =
230
- this.pushStateWrapper !== null &&
231
- window.history.pushState === this.pushStateWrapper;
232
- if (this.originalPushState) {
233
- if (pushStateStillOurs) {
234
- window.history.pushState = this.originalPushState;
235
- this.mpInstance.Logger.verbose(
236
- 'mParticle APV: [teardown] restored original pushState'
237
- );
238
- } else {
239
- this.mpInstance.Logger.verbose(
240
- 'mParticle APV: [teardown] pushState no longer ours; leaving in place, gating callback to no-op'
241
- );
242
- }
243
- this.originalPushState = null;
244
- this.pushStateWrapper = null;
245
- }
246
353
 
247
- const replaceStateStillOurs =
248
- this.replaceStateWrapper !== null &&
249
- window.history.replaceState === this.replaceStateWrapper;
250
- if (this.originalReplaceState) {
251
- if (replaceStateStillOurs) {
252
- window.history.replaceState = this.originalReplaceState;
253
- this.mpInstance.Logger.verbose(
254
- 'mParticle APV: [teardown] restored original replaceState'
255
- );
256
- } else {
257
- this.mpInstance.Logger.verbose(
258
- 'mParticle APV: [teardown] replaceState no longer ours; leaving in place, gating callback to no-op'
259
- );
260
- }
261
- this.originalReplaceState = null;
262
- this.replaceStateWrapper = null;
354
+ this.restoreHistoryMethod('pushState', this.originalPushState, this.pushStateWrapper);
355
+ this.originalPushState = null;
356
+ this.pushStateWrapper = null;
357
+
358
+ this.restoreHistoryMethod('replaceState', this.originalReplaceState, this.replaceStateWrapper);
359
+ this.originalReplaceState = null;
360
+ this.replaceStateWrapper = null;
361
+
362
+ this._isActive = false;
363
+ if (getWindowTracker() === this) {
364
+ setWindowTracker(undefined);
263
365
  }
366
+ }
367
+ }
368
+
369
+ function getWindowTracker(): PageViewTracker | undefined {
370
+ if (typeof window === 'undefined') return undefined;
371
+ return (window as WindowWithApvFlags)[WIN_TRACKER_KEY];
372
+ }
264
373
 
265
- this.isActive = false;
374
+ function setWindowTracker(tracker: PageViewTracker | undefined): void {
375
+ if (typeof window === 'undefined') return;
376
+ const win = window as WindowWithApvFlags;
377
+ if (tracker) {
378
+ win[WIN_TRACKER_KEY] = tracker;
379
+ } else {
380
+ delete win[WIN_TRACKER_KEY];
266
381
  }
267
382
  }