@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.
- package/dist/mparticle.common.js +16 -5
- package/dist/mparticle.esm.js +16 -5
- package/dist/mparticle.js +164 -32
- package/dist/types/src/pageViewTracker.d.ts +14 -1
- package/package.json +1 -1
- package/src/mp-instance.ts +32 -2
- package/src/pageViewTracker.ts +162 -47
package/dist/mparticle.common.js
CHANGED
|
@@ -15,7 +15,7 @@ map:function map(a,b){var c,d,e;if(null===this)throw new TypeError(" this is nul
|
|
|
15
15
|
filter:function filter(a/*, thisArg*/){if(void 0===this||null===this)throw new TypeError;var b=Object(this),c=b.length>>>0;if("function"!=typeof a)throw new TypeError;for(var d=[],e=2<=arguments.length?arguments[1]:void 0,f=0;f<c;f++)if(f in b){var g=b[f];a.call(e,g,f,b)&&d.push(g);}return d},// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray
|
|
16
16
|
isArray:function isArray(a){return "[object Array]"===Object.prototype.toString.call(a)},Base64:Base64$1};
|
|
17
17
|
|
|
18
|
-
var version = "2.79.
|
|
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__"
|
|
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.
|
|
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.
|
|
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.esm.js
CHANGED
|
@@ -15,7 +15,7 @@ map:function map(a,b){var c,d,e;if(null===this)throw new TypeError(" this is nul
|
|
|
15
15
|
filter:function filter(a/*, thisArg*/){if(void 0===this||null===this)throw new TypeError;var b=Object(this),c=b.length>>>0;if("function"!=typeof a)throw new TypeError;for(var d=[],e=2<=arguments.length?arguments[1]:void 0,f=0;f<c;f++)if(f in b){var g=b[f];a.call(e,g,f,b)&&d.push(g);}return d},// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray
|
|
16
16
|
isArray:function isArray(a){return "[object Array]"===Object.prototype.toString.call(a)},Base64:Base64$1};
|
|
17
17
|
|
|
18
|
-
var version = "2.79.
|
|
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__"
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
11331
|
-
|
|
11332
|
-
|
|
11333
|
-
|
|
11334
|
-
|
|
11335
|
-
|
|
11336
|
-
|
|
11337
|
-
|
|
11338
|
-
|
|
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
|
|
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
package/src/mp-instance.ts
CHANGED
|
@@ -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
|
|
package/src/pageViewTracker.ts
CHANGED
|
@@ -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
|
|
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
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
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:
|
|
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:
|
|
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
|
-
|
|
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
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
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
|
-
|
|
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
|
}
|