@rudderstack/analytics-js 3.25.0 → 3.25.1-beta.pr.2607.91e7d4a
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/CHANGELOG.md +12 -0
- package/dist/npm/legacy/bundled/cjs/index.cjs +40 -15
- package/dist/npm/legacy/bundled/esm/index.mjs +40 -15
- package/dist/npm/legacy/bundled/umd/index.js +40 -15
- package/dist/npm/legacy/cjs/index.cjs +40 -15
- package/dist/npm/legacy/content-script/cjs/index.cjs +40 -15
- package/dist/npm/legacy/content-script/esm/index.mjs +40 -15
- package/dist/npm/legacy/content-script/umd/index.js +40 -15
- package/dist/npm/legacy/esm/index.mjs +40 -15
- package/dist/npm/legacy/umd/index.js +40 -15
- package/dist/npm/modern/bundled/cjs/index.cjs +40 -15
- package/dist/npm/modern/bundled/esm/index.mjs +40 -15
- package/dist/npm/modern/bundled/umd/index.js +40 -15
- package/dist/npm/modern/cjs/index.cjs +40 -15
- package/dist/npm/modern/content-script/cjs/index.cjs +40 -15
- package/dist/npm/modern/content-script/esm/index.mjs +40 -15
- package/dist/npm/modern/content-script/umd/index.js +40 -15
- package/dist/npm/modern/esm/index.mjs +40 -15
- package/dist/npm/modern/umd/index.js +40 -15
- package/package.json +55 -2
|
@@ -431,7 +431,11 @@ const generateUUID=()=>{if(hasCrypto$1()){return v4$1();}return v4();};
|
|
|
431
431
|
* @returns boolean
|
|
432
432
|
*/const isSDKRunningInChromeExtension=()=>!!window.chrome?.runtime?.id;const isIE11=()=>isString(globalThis.navigator.userAgent)&&/Trident.*rv:11\./.test(globalThis.navigator.userAgent);
|
|
433
433
|
|
|
434
|
-
|
|
434
|
+
/**
|
|
435
|
+
* Registers events to detect page leave scenarios
|
|
436
|
+
* @param callback Callback function
|
|
437
|
+
* @param avoidBfCacheOptimization When `true`, forcefully subscribes to beforeunload event, compromising on the bfcache optimization
|
|
438
|
+
*/const onPageLeave=(callback,avoidBfCacheOptimization=false)=>{// To ensure the callback is only called once even if more than one events
|
|
435
439
|
// are fired at once.
|
|
436
440
|
let pageLeft=false;let isAccessible=false;function handleOnLeave(){if(pageLeft){return;}pageLeft=true;callback(isAccessible);// Reset pageLeft on the next tick
|
|
437
441
|
// to ensure callback executes for other listeners
|
|
@@ -442,7 +446,8 @@ setTimeout(()=>{pageLeft=false;},0);}// Catches the unloading of the page (e.g.,
|
|
|
442
446
|
// Note that 'pagehide' is not supported in IE.
|
|
443
447
|
// Registering this event conditionally for IE11 also because
|
|
444
448
|
// it affects bfcache optimization on modern browsers otherwise.
|
|
445
|
-
|
|
449
|
+
// However, if optimization is disabled, force subscribe the event
|
|
450
|
+
if(avoidBfCacheOptimization||isIE11()){globalThis.addEventListener('beforeunload',()=>{isAccessible=false;handleOnLeave();});}// This is important for iOS Safari browser as it does not
|
|
446
451
|
// fire the regular pagehide and visibilitychange events
|
|
447
452
|
// when user goes to tablist view and closes the tab.
|
|
448
453
|
globalThis.addEventListener('blur',()=>{isAccessible=true;handleOnLeave();});globalThis.addEventListener('focus',()=>{pageLeft=false;});// Catches the page being hidden, including scenarios like closing the tab.
|
|
@@ -505,7 +510,7 @@ error.stack=`${stack}\n${MANUAL_ERROR_IDENTIFIER}`;break;case stacktrace:// esli
|
|
|
505
510
|
error.stacktrace=`${stacktrace}\n${MANUAL_ERROR_IDENTIFIER}`;break;case operaSourceloc:default:// eslint-disable-next-line no-param-reassign
|
|
506
511
|
error['opera#sourceloc']=`${operaSourceloc}\n${MANUAL_ERROR_IDENTIFIER}`;break;}}}globalThis.dispatchEvent(new ErrorEvent('error',{error,bubbles:true,cancelable:true,composed:true}));};
|
|
507
512
|
|
|
508
|
-
const APP_NAME='RudderLabs JavaScript SDK';const APP_VERSION='3.25.
|
|
513
|
+
const APP_NAME='RudderLabs JavaScript SDK';const APP_VERSION='3.25.1-beta.pr.2607.91e7d4a';const APP_NAMESPACE='com.rudderlabs.javascript';const MODULE_TYPE='npm';const ADBLOCK_PAGE_CATEGORY='RudderJS-Initiated';const ADBLOCK_PAGE_NAME='ad-block page request';const ADBLOCK_PAGE_PATH='/ad-blocked';const GLOBAL_PRELOAD_BUFFER='preloadedEventsBuffer';const CONSENT_TRACK_EVENT_NAME='Consent Management Interaction';
|
|
509
514
|
|
|
510
515
|
const QUERY_PARAM_TRAIT_PREFIX='ajs_trait_';const QUERY_PARAM_PROPERTY_PREFIX='ajs_prop_';const QUERY_PARAM_ANONYMOUS_ID_KEY='ajs_aid';const QUERY_PARAM_USER_ID_KEY='ajs_uid';const QUERY_PARAM_TRACK_EVENT_NAME_KEY='ajs_event';
|
|
511
516
|
|
|
@@ -689,9 +694,9 @@ var errorStackParser$1 = {exports: {}};
|
|
|
689
694
|
|
|
690
695
|
var stackframe$1 = {exports: {}};
|
|
691
696
|
|
|
692
|
-
var stackframe=stackframe$1.exports;var hasRequiredStackframe;function requireStackframe(){if(hasRequiredStackframe)return stackframe$1.exports;hasRequiredStackframe=1;(function(module,exports){(function(root,factory){/* istanbul ignore next */{module.exports=factory();}})(stackframe,function(){function _isNumber(n){return !isNaN(parseFloat(n))&&isFinite(n);}function _capitalize(str){return str.charAt(0).toUpperCase()+str.substring(1);}function _getter(p){return function(){return this[p];};}var booleanProps=['isConstructor','isEval','isNative','isToplevel'];var numericProps=['columnNumber','lineNumber'];var stringProps=['fileName','functionName','source'];var arrayProps=['args'];var objectProps=['evalOrigin'];var props=booleanProps.concat(numericProps,stringProps,arrayProps,objectProps);function StackFrame(obj){if(!obj)return;for(var i=0;i<props.length;i++){if(obj[props[i]]!==undefined){this['set'+_capitalize(props[i])](obj[props[i]]);}}}StackFrame.prototype={getArgs:function(){return this.args;},setArgs:function(v){if(Object.prototype.toString.call(v)!=='[object Array]'){throw new TypeError('Args must be an Array');}this.args=v;},getEvalOrigin:function(){return this.evalOrigin;},setEvalOrigin:function(v){if(v instanceof StackFrame){this.evalOrigin=v;}else if(v instanceof Object){this.evalOrigin=new StackFrame(v);}else {throw new TypeError('Eval Origin must be an Object or StackFrame');}},toString:function(){var fileName=this.getFileName()||'';var lineNumber=this.getLineNumber()||'';var columnNumber=this.getColumnNumber()||'';var functionName=this.getFunctionName()||'';if(this.getIsEval()){if(fileName){return '[eval] ('+fileName+':'+lineNumber+':'+columnNumber+')';}return '[eval]:'+lineNumber+':'+columnNumber;}if(functionName){return functionName+' ('+fileName+':'+lineNumber+':'+columnNumber+')';}return fileName+':'+lineNumber+':'+columnNumber;}};StackFrame.fromString=function StackFrame$$fromString(str){var argsStartIndex=str.indexOf('(');var argsEndIndex=str.lastIndexOf(')');var functionName=str.substring(0,argsStartIndex);var args=str.substring(argsStartIndex+1,argsEndIndex).split(',');var locationString=str.substring(argsEndIndex+1);if(locationString.indexOf('@')===0){var parts=/@(.+?)(?::(\d+))?(?::(\d+))?$/.exec(locationString,'');var fileName=parts[1];var lineNumber=parts[2];var columnNumber=parts[3];}return new StackFrame({functionName:functionName,args:args||undefined,fileName:fileName,lineNumber:lineNumber||undefined,columnNumber:columnNumber||undefined});};for(var i=0;i<booleanProps.length;i++){StackFrame.prototype['get'+_capitalize(booleanProps[i])]=_getter(booleanProps[i]);StackFrame.prototype['set'+_capitalize(booleanProps[i])]=function(p){return function(v){this[p]=Boolean(v);};}(booleanProps[i]);}for(var j=0;j<numericProps.length;j++){StackFrame.prototype['get'+_capitalize(numericProps[j])]=_getter(numericProps[j]);StackFrame.prototype['set'+_capitalize(numericProps[j])]=function(p){return function(v){if(!_isNumber(v)){throw new TypeError(p+' must be a Number');}this[p]=Number(v);};}(numericProps[j]);}for(var k=0;k<stringProps.length;k++){StackFrame.prototype['get'+_capitalize(stringProps[k])]=_getter(stringProps[k]);StackFrame.prototype['set'+_capitalize(stringProps[k])]=function(p){return function(v){this[p]=String(v);};}(stringProps[k]);}return StackFrame;});})(stackframe$1);return stackframe$1.exports;}
|
|
697
|
+
var stackframe=stackframe$1.exports;var hasRequiredStackframe;function requireStackframe(){if(hasRequiredStackframe)return stackframe$1.exports;hasRequiredStackframe=1;(function(module,exports$1){(function(root,factory){/* istanbul ignore next */{module.exports=factory();}})(stackframe,function(){function _isNumber(n){return !isNaN(parseFloat(n))&&isFinite(n);}function _capitalize(str){return str.charAt(0).toUpperCase()+str.substring(1);}function _getter(p){return function(){return this[p];};}var booleanProps=['isConstructor','isEval','isNative','isToplevel'];var numericProps=['columnNumber','lineNumber'];var stringProps=['fileName','functionName','source'];var arrayProps=['args'];var objectProps=['evalOrigin'];var props=booleanProps.concat(numericProps,stringProps,arrayProps,objectProps);function StackFrame(obj){if(!obj)return;for(var i=0;i<props.length;i++){if(obj[props[i]]!==undefined){this['set'+_capitalize(props[i])](obj[props[i]]);}}}StackFrame.prototype={getArgs:function(){return this.args;},setArgs:function(v){if(Object.prototype.toString.call(v)!=='[object Array]'){throw new TypeError('Args must be an Array');}this.args=v;},getEvalOrigin:function(){return this.evalOrigin;},setEvalOrigin:function(v){if(v instanceof StackFrame){this.evalOrigin=v;}else if(v instanceof Object){this.evalOrigin=new StackFrame(v);}else {throw new TypeError('Eval Origin must be an Object or StackFrame');}},toString:function(){var fileName=this.getFileName()||'';var lineNumber=this.getLineNumber()||'';var columnNumber=this.getColumnNumber()||'';var functionName=this.getFunctionName()||'';if(this.getIsEval()){if(fileName){return '[eval] ('+fileName+':'+lineNumber+':'+columnNumber+')';}return '[eval]:'+lineNumber+':'+columnNumber;}if(functionName){return functionName+' ('+fileName+':'+lineNumber+':'+columnNumber+')';}return fileName+':'+lineNumber+':'+columnNumber;}};StackFrame.fromString=function StackFrame$$fromString(str){var argsStartIndex=str.indexOf('(');var argsEndIndex=str.lastIndexOf(')');var functionName=str.substring(0,argsStartIndex);var args=str.substring(argsStartIndex+1,argsEndIndex).split(',');var locationString=str.substring(argsEndIndex+1);if(locationString.indexOf('@')===0){var parts=/@(.+?)(?::(\d+))?(?::(\d+))?$/.exec(locationString,'');var fileName=parts[1];var lineNumber=parts[2];var columnNumber=parts[3];}return new StackFrame({functionName:functionName,args:args||undefined,fileName:fileName,lineNumber:lineNumber||undefined,columnNumber:columnNumber||undefined});};for(var i=0;i<booleanProps.length;i++){StackFrame.prototype['get'+_capitalize(booleanProps[i])]=_getter(booleanProps[i]);StackFrame.prototype['set'+_capitalize(booleanProps[i])]=function(p){return function(v){this[p]=Boolean(v);};}(booleanProps[i]);}for(var j=0;j<numericProps.length;j++){StackFrame.prototype['get'+_capitalize(numericProps[j])]=_getter(numericProps[j]);StackFrame.prototype['set'+_capitalize(numericProps[j])]=function(p){return function(v){if(!_isNumber(v)){throw new TypeError(p+' must be a Number');}this[p]=Number(v);};}(numericProps[j]);}for(var k=0;k<stringProps.length;k++){StackFrame.prototype['get'+_capitalize(stringProps[k])]=_getter(stringProps[k]);StackFrame.prototype['set'+_capitalize(stringProps[k])]=function(p){return function(v){this[p]=String(v);};}(stringProps[k]);}return StackFrame;});})(stackframe$1);return stackframe$1.exports;}
|
|
693
698
|
|
|
694
|
-
var errorStackParser=errorStackParser$1.exports;var hasRequiredErrorStackParser;function requireErrorStackParser(){if(hasRequiredErrorStackParser)return errorStackParser$1.exports;hasRequiredErrorStackParser=1;(function(module,exports){(function(root,factory){/* istanbul ignore next */{module.exports=factory(requireStackframe());}})(errorStackParser,function ErrorStackParser(StackFrame){var FIREFOX_SAFARI_STACK_REGEXP=/(^|@)\S+:\d+/;var CHROME_IE_STACK_REGEXP=/^\s*at .*(\S+:\d+|\(native\))/m;var SAFARI_NATIVE_CODE_REGEXP=/^(eval@)?(\[native code])?$/;return {/**
|
|
699
|
+
var errorStackParser=errorStackParser$1.exports;var hasRequiredErrorStackParser;function requireErrorStackParser(){if(hasRequiredErrorStackParser)return errorStackParser$1.exports;hasRequiredErrorStackParser=1;(function(module,exports$1){(function(root,factory){/* istanbul ignore next */{module.exports=factory(requireStackframe());}})(errorStackParser,function ErrorStackParser(StackFrame){var FIREFOX_SAFARI_STACK_REGEXP=/(^|@)\S+:\d+/;var CHROME_IE_STACK_REGEXP=/^\s*at .*(\S+:\d+|\(native\))/m;var SAFARI_NATIVE_CODE_REGEXP=/^(eval@)?(\[native code])?$/;return {/**
|
|
695
700
|
* Given an Error object, extract the most information from it.
|
|
696
701
|
*
|
|
697
702
|
* @param {Error} error object
|
|
@@ -1073,7 +1078,7 @@ const getDefaultCookieOptions=()=>{const topDomain=`.${domain(globalThis.locatio
|
|
|
1073
1078
|
|
|
1074
1079
|
var store$2 = {exports: {}};
|
|
1075
1080
|
|
|
1076
|
-
var store$1=store$2.exports;var hasRequiredStore;function requireStore(){if(hasRequiredStore)return store$2.exports;hasRequiredStore=1;(function(module,exports){(function(global,factory){module.exports=factory();})(store$1,function(){function isJSON(obj){obj=JSON.stringify(obj);if(!/^\{[\s\S]*\}$/.test(obj)){return false;}return true;}function stringify(val){return val===undefined||typeof val==="function"?val+'':JSON.stringify(val);}function deserialize(value){if(typeof value!=='string'){return undefined;}try{return JSON.parse(value);}catch(e){return value;}}function isFunction(value){return {}.toString.call(value)==="[object Function]";}function isArray(value){return Object.prototype.toString.call(value)==="[object Array]";}// https://github.com/jaywcjlove/store.js/pull/8
|
|
1081
|
+
var store$1=store$2.exports;var hasRequiredStore;function requireStore(){if(hasRequiredStore)return store$2.exports;hasRequiredStore=1;(function(module,exports$1){(function(global,factory){module.exports=factory();})(store$1,function(){function isJSON(obj){obj=JSON.stringify(obj);if(!/^\{[\s\S]*\}$/.test(obj)){return false;}return true;}function stringify(val){return val===undefined||typeof val==="function"?val+'':JSON.stringify(val);}function deserialize(value){if(typeof value!=='string'){return undefined;}try{return JSON.parse(value);}catch(e){return value;}}function isFunction(value){return {}.toString.call(value)==="[object Function]";}function isArray(value){return Object.prototype.toString.call(value)==="[object Array]";}// https://github.com/jaywcjlove/store.js/pull/8
|
|
1077
1082
|
// Error: QuotaExceededError
|
|
1078
1083
|
function dealIncognito(storage){var _KEY='_Is_Incognit',_VALUE='yes';try{// NOTE: set default storage when not passed in
|
|
1079
1084
|
if(!storage){storage=window.localStorage;}storage.setItem(_KEY,_VALUE);storage.removeItem(_KEY);}catch(e){var inMemoryStorage={};inMemoryStorage._data={};inMemoryStorage.setItem=function(id,val){return inMemoryStorage._data[id]=String(val);};inMemoryStorage.getItem=function(id){return inMemoryStorage._data.hasOwnProperty(id)?inMemoryStorage._data[id]:undefined;};inMemoryStorage.removeItem=function(id){return delete inMemoryStorage._data[id];};inMemoryStorage.clear=function(){return inMemoryStorage._data={};};storage=inMemoryStorage;}finally{if(storage.getItem(_KEY)===_VALUE)storage.removeItem(_KEY);}return storage;}// deal QuotaExceededError if user use incognito mode in browser
|
|
@@ -1580,7 +1585,11 @@ enrichedEvent.userId=to??enrichedEvent.userId;return enrichedEvent;}/**
|
|
|
1580
1585
|
* @param event Incoming event data
|
|
1581
1586
|
*/addEvent(event){this.userSessionManager.refreshSession();const rudderEvent=this.eventFactory.create(event);this.eventRepository.enqueue(rudderEvent,event.callback);}}
|
|
1582
1587
|
|
|
1583
|
-
class UserSessionManager{
|
|
1588
|
+
class UserSessionManager{/**
|
|
1589
|
+
* Tracks whether the setting the cookies action has been queued or not
|
|
1590
|
+
*//**
|
|
1591
|
+
* Tracks the number of queued cookie set requests
|
|
1592
|
+
*/constructor(pluginsManager,storeManager,httpClient,errorHandler,logger){this.storeManager=storeManager;this.pluginsManager=pluginsManager;this.logger=logger;this.errorHandler=errorHandler;this.httpClient=httpClient;this.onError=this.onError.bind(this);this.serverSideCookieDebounceFuncs={};this.serverSideCookiesRequestInProgress={};this.serverSideCookieSetRequests={};}/**
|
|
1584
1593
|
* Initialize User session with values from storage
|
|
1585
1594
|
*/init(){this.syncStorageDataToState();// Register the effect to sync with storage
|
|
1586
1595
|
this.registerEffects();}syncStorageDataToState(){this.migrateStorageIfNeeded();this.migrateDataFromPreviousStorage();// get the values from storage and set it again
|
|
@@ -1612,18 +1621,33 @@ cutOffDuration=DEFAULT_SESSION_CUT_OFF_DURATION_MS;}else if(cutOffDuration<sessi
|
|
|
1612
1621
|
* A function to make an external request to set the cookie from server side
|
|
1613
1622
|
* @param key cookie name
|
|
1614
1623
|
* @param value encrypted cookie value
|
|
1615
|
-
*/setServerSideCookies(
|
|
1624
|
+
*/setServerSideCookies(sessionEntries,cb,store){// Retrieve the cookie value from the state
|
|
1625
|
+
const sessionKeys=Object.keys(sessionEntries);const cookiesData=sessionKeys.map(sessionKey=>{return {name:sessionEntries[sessionKey].name,value:state.session[sessionKey].value};});const clearInProgressFlags=()=>{sessionKeys.forEach(sessionKey=>{this.serverSideCookiesRequestInProgress[sessionKey]=false;});};try{// encrypt cookies values
|
|
1616
1626
|
const encryptedCookieData=this.getEncryptedCookieData(cookiesData,store);if(encryptedCookieData.length>0){// make request to data service to set the cookie from server side
|
|
1617
|
-
this.makeRequestToSetCookie(encryptedCookieData,(res,details)=>{
|
|
1627
|
+
this.makeRequestToSetCookie(encryptedCookieData,(res,details)=>{// Mark the cookie req status as done
|
|
1628
|
+
clearInProgressFlags();if(details?.xhr?.status===200){cookiesData.forEach(cData=>{const cookieValue=store?.get(cData.name);const before=stringifyWithoutCircular(cData.value,false,[]);const after=stringifyWithoutCircular(cookieValue,false,[]);if(after!==before){this.logger.error(FAILED_SETTING_COOKIE_FROM_SERVER_ERROR(cData.name));if(cb){cb(cData.name,cData.value);}}});}else {this.logger.error(DATA_SERVER_REQUEST_FAIL_ERROR(details?.xhr?.status));cookiesData.forEach(each=>{if(cb){cb(each.name,each.value);}});}});}else {// Mark the cookie req status as done
|
|
1629
|
+
clearInProgressFlags();}}catch(e){// Mark the cookie req status as done
|
|
1630
|
+
clearInProgressFlags();this.onError(e,FAILED_SETTING_COOKIE_FROM_SERVER_GLOBAL_ERROR,FAILED_SETTING_COOKIE_FROM_SERVER_GLOBAL_ERROR);cookiesData.forEach(each=>{if(cb){cb(each.name,each.value);}});}}/**
|
|
1618
1631
|
* A function to sync values in storage
|
|
1619
1632
|
* @param sessionKey
|
|
1620
|
-
* @param value
|
|
1621
|
-
*/syncValueToStorage(sessionKey,
|
|
1633
|
+
* @param stateValue optional state value to sync. By default, we directly read from the state
|
|
1634
|
+
*/syncValueToStorage(sessionKey,stateValue){const entries=state.storage.entries.value;const storageType=entries[sessionKey]?.type;if(isStorageTypeValidForStoringData(storageType)){const curStore=this.storeManager?.getStore(storageClientDataStoreNameMap[storageType]);const key=entries[sessionKey]?.key;// Determine the final user session entry value
|
|
1635
|
+
const value=stateValue??state.session[sessionKey].value;if(value&&(isString(value)||isNonEmptyObject(value))){// if useServerSideCookies load option is set to true
|
|
1622
1636
|
// set the cookie from server side
|
|
1623
|
-
if(state.serverCookies.isEnabledServerSideCookies.value&&storageType===COOKIE_STORAGE){
|
|
1637
|
+
if(state.serverCookies.isEnabledServerSideCookies.value&&storageType===COOKIE_STORAGE){// Mark the requests as in progress.
|
|
1638
|
+
this.serverSideCookiesRequestInProgress[sessionKey]=true;const setCookieFunc=()=>{const sessionEntries={[sessionKey]:{name:key}};this.setServerSideCookies(sessionEntries,(cookieName,cookieValue)=>{curStore?.set(cookieName,cookieValue);},curStore);};// When debounce is not active, set it up.
|
|
1639
|
+
// Debounce behavior: Only the first and last values are sent during the debounce window.
|
|
1640
|
+
// The first request is sent immediately to prevent events from missing session info.
|
|
1641
|
+
// Subsequent changes within the debounce window are consolidated into a single request
|
|
1642
|
+
// that sends the latest value after the debounce delay. Intermediate values are not persisted.
|
|
1643
|
+
if(!this.serverSideCookieDebounceFuncs[sessionKey]){this.serverSideCookieSetRequests[sessionKey]=0;// For the first time, make the cookie request anyway.
|
|
1644
|
+
setCookieFunc();this.serverSideCookieDebounceFuncs[sessionKey]=globalThis.setTimeout(()=>{delete this.serverSideCookieDebounceFuncs[sessionKey];// In the debounce function, make the cookie request only when cookie requests are waiting
|
|
1645
|
+
// in the queue. The first request would have been sent already.
|
|
1646
|
+
if(this.serverSideCookieSetRequests[sessionKey]>0){setCookieFunc();this.serverSideCookieSetRequests[sessionKey]=0;}},SERVER_SIDE_COOKIES_DEBOUNCE_TIME);}else {// Increment the queued cookie set actions
|
|
1647
|
+
this.serverSideCookieSetRequests[sessionKey]+=1;}}else {curStore?.set(key,value);}}else {curStore?.remove(key);}}}/**
|
|
1624
1648
|
* Function to update storage whenever state value changes
|
|
1625
1649
|
*/registerEffects(){// This will work as long as the user session entry key names are same as the state keys
|
|
1626
|
-
USER_SESSION_KEYS.forEach(sessionKey=>{E(()=>{this.syncValueToStorage(sessionKey
|
|
1650
|
+
USER_SESSION_KEYS.forEach(sessionKey=>{E(()=>{this.syncValueToStorage(sessionKey);});});}/**
|
|
1627
1651
|
* Sets anonymous id in the following precedence:
|
|
1628
1652
|
*
|
|
1629
1653
|
* 1. anonymousId: Id directly provided to the function.
|
|
@@ -1669,7 +1693,8 @@ this.migrateStorageIfNeeded([store],[sessionKey]);const storageKey=entries[sessi
|
|
|
1669
1693
|
*/getSessionId(){const sessionInfo=this.getSessionInfo()??DEFAULT_USER_SESSION_VALUES.sessionInfo;if(sessionInfo.autoTrack&&!hasSessionExpired(sessionInfo)||sessionInfo.manualTrack){return sessionInfo.id??null;}return null;}/**
|
|
1670
1694
|
* A function to keep the session information up to date in the state
|
|
1671
1695
|
* before using it for building event payloads.
|
|
1672
|
-
*/refreshSession(){let
|
|
1696
|
+
*/refreshSession(){let initialSessionInfo=this.getSessionInfo();// If cookie set request is in progress, use the state value. That should be sufficient.
|
|
1697
|
+
if(initialSessionInfo===null&&this.serverSideCookiesRequestInProgress['sessionInfo']){initialSessionInfo=state.session.sessionInfo.value;}let sessionInfo=initialSessionInfo??DEFAULT_USER_SESSION_VALUES.sessionInfo;if(sessionInfo.autoTrack||sessionInfo.manualTrack){if(sessionInfo.autoTrack){this.startOrRenewAutoTracking(sessionInfo);sessionInfo=state.session.sessionInfo.value;}// Note that if sessionStart is false, then it's an active session.
|
|
1673
1698
|
// So, we needn't update the session info.
|
|
1674
1699
|
//
|
|
1675
1700
|
// For other scenarios,
|
|
@@ -1919,7 +1944,7 @@ state.autoTrack.enabled.value=autoTrackEnabled||pageLifecycleEnabled;if(!pageLif
|
|
|
1919
1944
|
* @param events
|
|
1920
1945
|
* @param useBeacon
|
|
1921
1946
|
* @param options
|
|
1922
|
-
*/setupPageUnloadTracking(events,useBeacon,options){if(events.length===0||events.includes(PageLifecycleEvents.UNLOADED)){if(useBeacon===true){onPageLeave(isAccessible=>{if(isAccessible===false&&state.lifecycle.loaded.value){const pageUnloadedTimestamp=Date.now();const timeOnPage=pageUnloadedTimestamp-state.autoTrack.pageLifecycle.pageLoadedTimestamp.value;this.track(PageLifecycleEvents.UNLOADED,{timeOnPage},{...options,originalTimestamp:getFormattedTimestamp(new Date(pageUnloadedTimestamp))});}});}else {// log warning if beacon is disabled
|
|
1947
|
+
*/setupPageUnloadTracking(events,useBeacon,options){if(events.length===0||events.includes(PageLifecycleEvents.UNLOADED)){if(useBeacon===true){onPageLeave(isAccessible=>{if(isAccessible===false&&state.lifecycle.loaded.value){const pageUnloadedTimestamp=Date.now();const timeOnPage=pageUnloadedTimestamp-state.autoTrack.pageLifecycle.pageLoadedTimestamp.value;this.track(PageLifecycleEvents.UNLOADED,{timeOnPage},{...options,originalTimestamp:getFormattedTimestamp(new Date(pageUnloadedTimestamp))});}},true);}else {// log warning if beacon is disabled
|
|
1923
1948
|
this.logger.warn(PAGE_UNLOAD_ON_BEACON_DISABLED_WARNING(RSA));}}}/**
|
|
1924
1949
|
* Trigger load event in buffer queue if exists and stores the
|
|
1925
1950
|
* remaining preloaded events array in global object
|
|
@@ -440,7 +440,11 @@ const generateUUID=()=>{if(hasCrypto$1()){return v4$1();}return v4();};
|
|
|
440
440
|
* @returns boolean
|
|
441
441
|
*/const isSDKRunningInChromeExtension=()=>!!window.chrome?.runtime?.id;const isIE11=()=>isString(globalThis.navigator.userAgent)&&/Trident.*rv:11\./.test(globalThis.navigator.userAgent);
|
|
442
442
|
|
|
443
|
-
|
|
443
|
+
/**
|
|
444
|
+
* Registers events to detect page leave scenarios
|
|
445
|
+
* @param callback Callback function
|
|
446
|
+
* @param avoidBfCacheOptimization When `true`, forcefully subscribes to beforeunload event, compromising on the bfcache optimization
|
|
447
|
+
*/const onPageLeave=(callback,avoidBfCacheOptimization=false)=>{// To ensure the callback is only called once even if more than one events
|
|
444
448
|
// are fired at once.
|
|
445
449
|
let pageLeft=false;let isAccessible=false;function handleOnLeave(){if(pageLeft){return;}pageLeft=true;callback(isAccessible);// Reset pageLeft on the next tick
|
|
446
450
|
// to ensure callback executes for other listeners
|
|
@@ -451,7 +455,8 @@ setTimeout(()=>{pageLeft=false;},0);}// Catches the unloading of the page (e.g.,
|
|
|
451
455
|
// Note that 'pagehide' is not supported in IE.
|
|
452
456
|
// Registering this event conditionally for IE11 also because
|
|
453
457
|
// it affects bfcache optimization on modern browsers otherwise.
|
|
454
|
-
|
|
458
|
+
// However, if optimization is disabled, force subscribe the event
|
|
459
|
+
if(avoidBfCacheOptimization||isIE11()){globalThis.addEventListener('beforeunload',()=>{isAccessible=false;handleOnLeave();});}// This is important for iOS Safari browser as it does not
|
|
455
460
|
// fire the regular pagehide and visibilitychange events
|
|
456
461
|
// when user goes to tablist view and closes the tab.
|
|
457
462
|
globalThis.addEventListener('blur',()=>{isAccessible=true;handleOnLeave();});globalThis.addEventListener('focus',()=>{pageLeft=false;});// Catches the page being hidden, including scenarios like closing the tab.
|
|
@@ -514,7 +519,7 @@ error.stack=`${stack}\n${MANUAL_ERROR_IDENTIFIER}`;break;case stacktrace:// esli
|
|
|
514
519
|
error.stacktrace=`${stacktrace}\n${MANUAL_ERROR_IDENTIFIER}`;break;case operaSourceloc:default:// eslint-disable-next-line no-param-reassign
|
|
515
520
|
error['opera#sourceloc']=`${operaSourceloc}\n${MANUAL_ERROR_IDENTIFIER}`;break;}}}globalThis.dispatchEvent(new ErrorEvent('error',{error,bubbles:true,cancelable:true,composed:true}));};
|
|
516
521
|
|
|
517
|
-
const APP_NAME='RudderLabs JavaScript SDK';const APP_VERSION='3.25.
|
|
522
|
+
const APP_NAME='RudderLabs JavaScript SDK';const APP_VERSION='3.25.1-beta.pr.2607.91e7d4a';const APP_NAMESPACE='com.rudderlabs.javascript';const MODULE_TYPE='npm';const ADBLOCK_PAGE_CATEGORY='RudderJS-Initiated';const ADBLOCK_PAGE_NAME='ad-block page request';const ADBLOCK_PAGE_PATH='/ad-blocked';const GLOBAL_PRELOAD_BUFFER='preloadedEventsBuffer';const CONSENT_TRACK_EVENT_NAME='Consent Management Interaction';
|
|
518
523
|
|
|
519
524
|
const QUERY_PARAM_TRAIT_PREFIX='ajs_trait_';const QUERY_PARAM_PROPERTY_PREFIX='ajs_prop_';const QUERY_PARAM_ANONYMOUS_ID_KEY='ajs_aid';const QUERY_PARAM_USER_ID_KEY='ajs_uid';const QUERY_PARAM_TRACK_EVENT_NAME_KEY='ajs_event';
|
|
520
525
|
|
|
@@ -698,9 +703,9 @@ var errorStackParser$1 = {exports: {}};
|
|
|
698
703
|
|
|
699
704
|
var stackframe$1 = {exports: {}};
|
|
700
705
|
|
|
701
|
-
var stackframe=stackframe$1.exports;var hasRequiredStackframe;function requireStackframe(){if(hasRequiredStackframe)return stackframe$1.exports;hasRequiredStackframe=1;(function(module,exports){(function(root,factory){/* istanbul ignore next */{module.exports=factory();}})(stackframe,function(){function _isNumber(n){return !isNaN(parseFloat(n))&&isFinite(n);}function _capitalize(str){return str.charAt(0).toUpperCase()+str.substring(1);}function _getter(p){return function(){return this[p];};}var booleanProps=['isConstructor','isEval','isNative','isToplevel'];var numericProps=['columnNumber','lineNumber'];var stringProps=['fileName','functionName','source'];var arrayProps=['args'];var objectProps=['evalOrigin'];var props=booleanProps.concat(numericProps,stringProps,arrayProps,objectProps);function StackFrame(obj){if(!obj)return;for(var i=0;i<props.length;i++){if(obj[props[i]]!==undefined){this['set'+_capitalize(props[i])](obj[props[i]]);}}}StackFrame.prototype={getArgs:function(){return this.args;},setArgs:function(v){if(Object.prototype.toString.call(v)!=='[object Array]'){throw new TypeError('Args must be an Array');}this.args=v;},getEvalOrigin:function(){return this.evalOrigin;},setEvalOrigin:function(v){if(v instanceof StackFrame){this.evalOrigin=v;}else if(v instanceof Object){this.evalOrigin=new StackFrame(v);}else {throw new TypeError('Eval Origin must be an Object or StackFrame');}},toString:function(){var fileName=this.getFileName()||'';var lineNumber=this.getLineNumber()||'';var columnNumber=this.getColumnNumber()||'';var functionName=this.getFunctionName()||'';if(this.getIsEval()){if(fileName){return '[eval] ('+fileName+':'+lineNumber+':'+columnNumber+')';}return '[eval]:'+lineNumber+':'+columnNumber;}if(functionName){return functionName+' ('+fileName+':'+lineNumber+':'+columnNumber+')';}return fileName+':'+lineNumber+':'+columnNumber;}};StackFrame.fromString=function StackFrame$$fromString(str){var argsStartIndex=str.indexOf('(');var argsEndIndex=str.lastIndexOf(')');var functionName=str.substring(0,argsStartIndex);var args=str.substring(argsStartIndex+1,argsEndIndex).split(',');var locationString=str.substring(argsEndIndex+1);if(locationString.indexOf('@')===0){var parts=/@(.+?)(?::(\d+))?(?::(\d+))?$/.exec(locationString,'');var fileName=parts[1];var lineNumber=parts[2];var columnNumber=parts[3];}return new StackFrame({functionName:functionName,args:args||undefined,fileName:fileName,lineNumber:lineNumber||undefined,columnNumber:columnNumber||undefined});};for(var i=0;i<booleanProps.length;i++){StackFrame.prototype['get'+_capitalize(booleanProps[i])]=_getter(booleanProps[i]);StackFrame.prototype['set'+_capitalize(booleanProps[i])]=function(p){return function(v){this[p]=Boolean(v);};}(booleanProps[i]);}for(var j=0;j<numericProps.length;j++){StackFrame.prototype['get'+_capitalize(numericProps[j])]=_getter(numericProps[j]);StackFrame.prototype['set'+_capitalize(numericProps[j])]=function(p){return function(v){if(!_isNumber(v)){throw new TypeError(p+' must be a Number');}this[p]=Number(v);};}(numericProps[j]);}for(var k=0;k<stringProps.length;k++){StackFrame.prototype['get'+_capitalize(stringProps[k])]=_getter(stringProps[k]);StackFrame.prototype['set'+_capitalize(stringProps[k])]=function(p){return function(v){this[p]=String(v);};}(stringProps[k]);}return StackFrame;});})(stackframe$1);return stackframe$1.exports;}
|
|
706
|
+
var stackframe=stackframe$1.exports;var hasRequiredStackframe;function requireStackframe(){if(hasRequiredStackframe)return stackframe$1.exports;hasRequiredStackframe=1;(function(module,exports$1){(function(root,factory){/* istanbul ignore next */{module.exports=factory();}})(stackframe,function(){function _isNumber(n){return !isNaN(parseFloat(n))&&isFinite(n);}function _capitalize(str){return str.charAt(0).toUpperCase()+str.substring(1);}function _getter(p){return function(){return this[p];};}var booleanProps=['isConstructor','isEval','isNative','isToplevel'];var numericProps=['columnNumber','lineNumber'];var stringProps=['fileName','functionName','source'];var arrayProps=['args'];var objectProps=['evalOrigin'];var props=booleanProps.concat(numericProps,stringProps,arrayProps,objectProps);function StackFrame(obj){if(!obj)return;for(var i=0;i<props.length;i++){if(obj[props[i]]!==undefined){this['set'+_capitalize(props[i])](obj[props[i]]);}}}StackFrame.prototype={getArgs:function(){return this.args;},setArgs:function(v){if(Object.prototype.toString.call(v)!=='[object Array]'){throw new TypeError('Args must be an Array');}this.args=v;},getEvalOrigin:function(){return this.evalOrigin;},setEvalOrigin:function(v){if(v instanceof StackFrame){this.evalOrigin=v;}else if(v instanceof Object){this.evalOrigin=new StackFrame(v);}else {throw new TypeError('Eval Origin must be an Object or StackFrame');}},toString:function(){var fileName=this.getFileName()||'';var lineNumber=this.getLineNumber()||'';var columnNumber=this.getColumnNumber()||'';var functionName=this.getFunctionName()||'';if(this.getIsEval()){if(fileName){return '[eval] ('+fileName+':'+lineNumber+':'+columnNumber+')';}return '[eval]:'+lineNumber+':'+columnNumber;}if(functionName){return functionName+' ('+fileName+':'+lineNumber+':'+columnNumber+')';}return fileName+':'+lineNumber+':'+columnNumber;}};StackFrame.fromString=function StackFrame$$fromString(str){var argsStartIndex=str.indexOf('(');var argsEndIndex=str.lastIndexOf(')');var functionName=str.substring(0,argsStartIndex);var args=str.substring(argsStartIndex+1,argsEndIndex).split(',');var locationString=str.substring(argsEndIndex+1);if(locationString.indexOf('@')===0){var parts=/@(.+?)(?::(\d+))?(?::(\d+))?$/.exec(locationString,'');var fileName=parts[1];var lineNumber=parts[2];var columnNumber=parts[3];}return new StackFrame({functionName:functionName,args:args||undefined,fileName:fileName,lineNumber:lineNumber||undefined,columnNumber:columnNumber||undefined});};for(var i=0;i<booleanProps.length;i++){StackFrame.prototype['get'+_capitalize(booleanProps[i])]=_getter(booleanProps[i]);StackFrame.prototype['set'+_capitalize(booleanProps[i])]=function(p){return function(v){this[p]=Boolean(v);};}(booleanProps[i]);}for(var j=0;j<numericProps.length;j++){StackFrame.prototype['get'+_capitalize(numericProps[j])]=_getter(numericProps[j]);StackFrame.prototype['set'+_capitalize(numericProps[j])]=function(p){return function(v){if(!_isNumber(v)){throw new TypeError(p+' must be a Number');}this[p]=Number(v);};}(numericProps[j]);}for(var k=0;k<stringProps.length;k++){StackFrame.prototype['get'+_capitalize(stringProps[k])]=_getter(stringProps[k]);StackFrame.prototype['set'+_capitalize(stringProps[k])]=function(p){return function(v){this[p]=String(v);};}(stringProps[k]);}return StackFrame;});})(stackframe$1);return stackframe$1.exports;}
|
|
702
707
|
|
|
703
|
-
var errorStackParser=errorStackParser$1.exports;var hasRequiredErrorStackParser;function requireErrorStackParser(){if(hasRequiredErrorStackParser)return errorStackParser$1.exports;hasRequiredErrorStackParser=1;(function(module,exports){(function(root,factory){/* istanbul ignore next */{module.exports=factory(requireStackframe());}})(errorStackParser,function ErrorStackParser(StackFrame){var FIREFOX_SAFARI_STACK_REGEXP=/(^|@)\S+:\d+/;var CHROME_IE_STACK_REGEXP=/^\s*at .*(\S+:\d+|\(native\))/m;var SAFARI_NATIVE_CODE_REGEXP=/^(eval@)?(\[native code])?$/;return {/**
|
|
708
|
+
var errorStackParser=errorStackParser$1.exports;var hasRequiredErrorStackParser;function requireErrorStackParser(){if(hasRequiredErrorStackParser)return errorStackParser$1.exports;hasRequiredErrorStackParser=1;(function(module,exports$1){(function(root,factory){/* istanbul ignore next */{module.exports=factory(requireStackframe());}})(errorStackParser,function ErrorStackParser(StackFrame){var FIREFOX_SAFARI_STACK_REGEXP=/(^|@)\S+:\d+/;var CHROME_IE_STACK_REGEXP=/^\s*at .*(\S+:\d+|\(native\))/m;var SAFARI_NATIVE_CODE_REGEXP=/^(eval@)?(\[native code])?$/;return {/**
|
|
704
709
|
* Given an Error object, extract the most information from it.
|
|
705
710
|
*
|
|
706
711
|
* @param {Error} error object
|
|
@@ -2805,7 +2810,7 @@ const getDefaultCookieOptions=()=>{const topDomain=`.${domain(globalThis.locatio
|
|
|
2805
2810
|
|
|
2806
2811
|
var store$2 = {exports: {}};
|
|
2807
2812
|
|
|
2808
|
-
var store$1=store$2.exports;var hasRequiredStore;function requireStore(){if(hasRequiredStore)return store$2.exports;hasRequiredStore=1;(function(module,exports){(function(global,factory){module.exports=factory();})(store$1,function(){function isJSON(obj){obj=JSON.stringify(obj);if(!/^\{[\s\S]*\}$/.test(obj)){return false;}return true;}function stringify(val){return val===undefined||typeof val==="function"?val+'':JSON.stringify(val);}function deserialize(value){if(typeof value!=='string'){return undefined;}try{return JSON.parse(value);}catch(e){return value;}}function isFunction(value){return {}.toString.call(value)==="[object Function]";}function isArray(value){return Object.prototype.toString.call(value)==="[object Array]";}// https://github.com/jaywcjlove/store.js/pull/8
|
|
2813
|
+
var store$1=store$2.exports;var hasRequiredStore;function requireStore(){if(hasRequiredStore)return store$2.exports;hasRequiredStore=1;(function(module,exports$1){(function(global,factory){module.exports=factory();})(store$1,function(){function isJSON(obj){obj=JSON.stringify(obj);if(!/^\{[\s\S]*\}$/.test(obj)){return false;}return true;}function stringify(val){return val===undefined||typeof val==="function"?val+'':JSON.stringify(val);}function deserialize(value){if(typeof value!=='string'){return undefined;}try{return JSON.parse(value);}catch(e){return value;}}function isFunction(value){return {}.toString.call(value)==="[object Function]";}function isArray(value){return Object.prototype.toString.call(value)==="[object Array]";}// https://github.com/jaywcjlove/store.js/pull/8
|
|
2809
2814
|
// Error: QuotaExceededError
|
|
2810
2815
|
function dealIncognito(storage){var _KEY='_Is_Incognit',_VALUE='yes';try{// NOTE: set default storage when not passed in
|
|
2811
2816
|
if(!storage){storage=window.localStorage;}storage.setItem(_KEY,_VALUE);storage.removeItem(_KEY);}catch(e){var inMemoryStorage={};inMemoryStorage._data={};inMemoryStorage.setItem=function(id,val){return inMemoryStorage._data[id]=String(val);};inMemoryStorage.getItem=function(id){return inMemoryStorage._data.hasOwnProperty(id)?inMemoryStorage._data[id]:undefined;};inMemoryStorage.removeItem=function(id){return delete inMemoryStorage._data[id];};inMemoryStorage.clear=function(){return inMemoryStorage._data={};};storage=inMemoryStorage;}finally{if(storage.getItem(_KEY)===_VALUE)storage.removeItem(_KEY);}return storage;}// deal QuotaExceededError if user use incognito mode in browser
|
|
@@ -3288,7 +3293,11 @@ enrichedEvent.userId=to??enrichedEvent.userId;return enrichedEvent;}/**
|
|
|
3288
3293
|
* @param event Incoming event data
|
|
3289
3294
|
*/addEvent(event){this.userSessionManager.refreshSession();const rudderEvent=this.eventFactory.create(event);this.eventRepository.enqueue(rudderEvent,event.callback);}}
|
|
3290
3295
|
|
|
3291
|
-
class UserSessionManager{
|
|
3296
|
+
class UserSessionManager{/**
|
|
3297
|
+
* Tracks whether the setting the cookies action has been queued or not
|
|
3298
|
+
*//**
|
|
3299
|
+
* Tracks the number of queued cookie set requests
|
|
3300
|
+
*/constructor(pluginsManager,storeManager,httpClient,errorHandler,logger){this.storeManager=storeManager;this.pluginsManager=pluginsManager;this.logger=logger;this.errorHandler=errorHandler;this.httpClient=httpClient;this.onError=this.onError.bind(this);this.serverSideCookieDebounceFuncs={};this.serverSideCookiesRequestInProgress={};this.serverSideCookieSetRequests={};}/**
|
|
3292
3301
|
* Initialize User session with values from storage
|
|
3293
3302
|
*/init(){this.syncStorageDataToState();// Register the effect to sync with storage
|
|
3294
3303
|
this.registerEffects();}syncStorageDataToState(){this.migrateStorageIfNeeded();this.migrateDataFromPreviousStorage();// get the values from storage and set it again
|
|
@@ -3320,18 +3329,33 @@ cutOffDuration=DEFAULT_SESSION_CUT_OFF_DURATION_MS;}else if(cutOffDuration<sessi
|
|
|
3320
3329
|
* A function to make an external request to set the cookie from server side
|
|
3321
3330
|
* @param key cookie name
|
|
3322
3331
|
* @param value encrypted cookie value
|
|
3323
|
-
*/setServerSideCookies(
|
|
3332
|
+
*/setServerSideCookies(sessionEntries,cb,store){// Retrieve the cookie value from the state
|
|
3333
|
+
const sessionKeys=Object.keys(sessionEntries);const cookiesData=sessionKeys.map(sessionKey=>{return {name:sessionEntries[sessionKey].name,value:state.session[sessionKey].value};});const clearInProgressFlags=()=>{sessionKeys.forEach(sessionKey=>{this.serverSideCookiesRequestInProgress[sessionKey]=false;});};try{// encrypt cookies values
|
|
3324
3334
|
const encryptedCookieData=this.getEncryptedCookieData(cookiesData,store);if(encryptedCookieData.length>0){// make request to data service to set the cookie from server side
|
|
3325
|
-
this.makeRequestToSetCookie(encryptedCookieData,(res,details)=>{
|
|
3335
|
+
this.makeRequestToSetCookie(encryptedCookieData,(res,details)=>{// Mark the cookie req status as done
|
|
3336
|
+
clearInProgressFlags();if(details?.xhr?.status===200){cookiesData.forEach(cData=>{const cookieValue=store?.get(cData.name);const before=stringifyWithoutCircular(cData.value,false,[]);const after=stringifyWithoutCircular(cookieValue,false,[]);if(after!==before){this.logger.error(FAILED_SETTING_COOKIE_FROM_SERVER_ERROR(cData.name));if(cb){cb(cData.name,cData.value);}}});}else {this.logger.error(DATA_SERVER_REQUEST_FAIL_ERROR(details?.xhr?.status));cookiesData.forEach(each=>{if(cb){cb(each.name,each.value);}});}});}else {// Mark the cookie req status as done
|
|
3337
|
+
clearInProgressFlags();}}catch(e){// Mark the cookie req status as done
|
|
3338
|
+
clearInProgressFlags();this.onError(e,FAILED_SETTING_COOKIE_FROM_SERVER_GLOBAL_ERROR,FAILED_SETTING_COOKIE_FROM_SERVER_GLOBAL_ERROR);cookiesData.forEach(each=>{if(cb){cb(each.name,each.value);}});}}/**
|
|
3326
3339
|
* A function to sync values in storage
|
|
3327
3340
|
* @param sessionKey
|
|
3328
|
-
* @param value
|
|
3329
|
-
*/syncValueToStorage(sessionKey,
|
|
3341
|
+
* @param stateValue optional state value to sync. By default, we directly read from the state
|
|
3342
|
+
*/syncValueToStorage(sessionKey,stateValue){const entries=state.storage.entries.value;const storageType=entries[sessionKey]?.type;if(isStorageTypeValidForStoringData(storageType)){const curStore=this.storeManager?.getStore(storageClientDataStoreNameMap[storageType]);const key=entries[sessionKey]?.key;// Determine the final user session entry value
|
|
3343
|
+
const value=stateValue??state.session[sessionKey].value;if(value&&(isString(value)||isNonEmptyObject(value))){// if useServerSideCookies load option is set to true
|
|
3330
3344
|
// set the cookie from server side
|
|
3331
|
-
if(state.serverCookies.isEnabledServerSideCookies.value&&storageType===COOKIE_STORAGE){
|
|
3345
|
+
if(state.serverCookies.isEnabledServerSideCookies.value&&storageType===COOKIE_STORAGE){// Mark the requests as in progress.
|
|
3346
|
+
this.serverSideCookiesRequestInProgress[sessionKey]=true;const setCookieFunc=()=>{const sessionEntries={[sessionKey]:{name:key}};this.setServerSideCookies(sessionEntries,(cookieName,cookieValue)=>{curStore?.set(cookieName,cookieValue);},curStore);};// When debounce is not active, set it up.
|
|
3347
|
+
// Debounce behavior: Only the first and last values are sent during the debounce window.
|
|
3348
|
+
// The first request is sent immediately to prevent events from missing session info.
|
|
3349
|
+
// Subsequent changes within the debounce window are consolidated into a single request
|
|
3350
|
+
// that sends the latest value after the debounce delay. Intermediate values are not persisted.
|
|
3351
|
+
if(!this.serverSideCookieDebounceFuncs[sessionKey]){this.serverSideCookieSetRequests[sessionKey]=0;// For the first time, make the cookie request anyway.
|
|
3352
|
+
setCookieFunc();this.serverSideCookieDebounceFuncs[sessionKey]=globalThis.setTimeout(()=>{delete this.serverSideCookieDebounceFuncs[sessionKey];// In the debounce function, make the cookie request only when cookie requests are waiting
|
|
3353
|
+
// in the queue. The first request would have been sent already.
|
|
3354
|
+
if(this.serverSideCookieSetRequests[sessionKey]>0){setCookieFunc();this.serverSideCookieSetRequests[sessionKey]=0;}},SERVER_SIDE_COOKIES_DEBOUNCE_TIME);}else {// Increment the queued cookie set actions
|
|
3355
|
+
this.serverSideCookieSetRequests[sessionKey]+=1;}}else {curStore?.set(key,value);}}else {curStore?.remove(key);}}}/**
|
|
3332
3356
|
* Function to update storage whenever state value changes
|
|
3333
3357
|
*/registerEffects(){// This will work as long as the user session entry key names are same as the state keys
|
|
3334
|
-
USER_SESSION_KEYS.forEach(sessionKey=>{E(()=>{this.syncValueToStorage(sessionKey
|
|
3358
|
+
USER_SESSION_KEYS.forEach(sessionKey=>{E(()=>{this.syncValueToStorage(sessionKey);});});}/**
|
|
3335
3359
|
* Sets anonymous id in the following precedence:
|
|
3336
3360
|
*
|
|
3337
3361
|
* 1. anonymousId: Id directly provided to the function.
|
|
@@ -3377,7 +3401,8 @@ this.migrateStorageIfNeeded([store],[sessionKey]);const storageKey=entries[sessi
|
|
|
3377
3401
|
*/getSessionId(){const sessionInfo=this.getSessionInfo()??DEFAULT_USER_SESSION_VALUES.sessionInfo;if(sessionInfo.autoTrack&&!hasSessionExpired(sessionInfo)||sessionInfo.manualTrack){return sessionInfo.id??null;}return null;}/**
|
|
3378
3402
|
* A function to keep the session information up to date in the state
|
|
3379
3403
|
* before using it for building event payloads.
|
|
3380
|
-
*/refreshSession(){let
|
|
3404
|
+
*/refreshSession(){let initialSessionInfo=this.getSessionInfo();// If cookie set request is in progress, use the state value. That should be sufficient.
|
|
3405
|
+
if(initialSessionInfo===null&&this.serverSideCookiesRequestInProgress['sessionInfo']){initialSessionInfo=state.session.sessionInfo.value;}let sessionInfo=initialSessionInfo??DEFAULT_USER_SESSION_VALUES.sessionInfo;if(sessionInfo.autoTrack||sessionInfo.manualTrack){if(sessionInfo.autoTrack){this.startOrRenewAutoTracking(sessionInfo);sessionInfo=state.session.sessionInfo.value;}// Note that if sessionStart is false, then it's an active session.
|
|
3381
3406
|
// So, we needn't update the session info.
|
|
3382
3407
|
//
|
|
3383
3408
|
// For other scenarios,
|
|
@@ -3627,7 +3652,7 @@ state.autoTrack.enabled.value=autoTrackEnabled||pageLifecycleEnabled;if(!pageLif
|
|
|
3627
3652
|
* @param events
|
|
3628
3653
|
* @param useBeacon
|
|
3629
3654
|
* @param options
|
|
3630
|
-
*/setupPageUnloadTracking(events,useBeacon,options){if(events.length===0||events.includes(PageLifecycleEvents.UNLOADED)){if(useBeacon===true){onPageLeave(isAccessible=>{if(isAccessible===false&&state.lifecycle.loaded.value){const pageUnloadedTimestamp=Date.now();const timeOnPage=pageUnloadedTimestamp-state.autoTrack.pageLifecycle.pageLoadedTimestamp.value;this.track(PageLifecycleEvents.UNLOADED,{timeOnPage},{...options,originalTimestamp:getFormattedTimestamp(new Date(pageUnloadedTimestamp))});}});}else {// log warning if beacon is disabled
|
|
3655
|
+
*/setupPageUnloadTracking(events,useBeacon,options){if(events.length===0||events.includes(PageLifecycleEvents.UNLOADED)){if(useBeacon===true){onPageLeave(isAccessible=>{if(isAccessible===false&&state.lifecycle.loaded.value){const pageUnloadedTimestamp=Date.now();const timeOnPage=pageUnloadedTimestamp-state.autoTrack.pageLifecycle.pageLoadedTimestamp.value;this.track(PageLifecycleEvents.UNLOADED,{timeOnPage},{...options,originalTimestamp:getFormattedTimestamp(new Date(pageUnloadedTimestamp))});}},true);}else {// log warning if beacon is disabled
|
|
3631
3656
|
this.logger.warn(PAGE_UNLOAD_ON_BEACON_DISABLED_WARNING(RSA));}}}/**
|
|
3632
3657
|
* Trigger load event in buffer queue if exists and stores the
|
|
3633
3658
|
* remaining preloaded events array in global object
|
|
@@ -436,7 +436,11 @@ const generateUUID=()=>{if(hasCrypto$1()){return v4$1();}return v4();};
|
|
|
436
436
|
* @returns boolean
|
|
437
437
|
*/const isSDKRunningInChromeExtension=()=>!!window.chrome?.runtime?.id;const isIE11=()=>isString(globalThis.navigator.userAgent)&&/Trident.*rv:11\./.test(globalThis.navigator.userAgent);
|
|
438
438
|
|
|
439
|
-
|
|
439
|
+
/**
|
|
440
|
+
* Registers events to detect page leave scenarios
|
|
441
|
+
* @param callback Callback function
|
|
442
|
+
* @param avoidBfCacheOptimization When `true`, forcefully subscribes to beforeunload event, compromising on the bfcache optimization
|
|
443
|
+
*/const onPageLeave=(callback,avoidBfCacheOptimization=false)=>{// To ensure the callback is only called once even if more than one events
|
|
440
444
|
// are fired at once.
|
|
441
445
|
let pageLeft=false;let isAccessible=false;function handleOnLeave(){if(pageLeft){return;}pageLeft=true;callback(isAccessible);// Reset pageLeft on the next tick
|
|
442
446
|
// to ensure callback executes for other listeners
|
|
@@ -447,7 +451,8 @@ setTimeout(()=>{pageLeft=false;},0);}// Catches the unloading of the page (e.g.,
|
|
|
447
451
|
// Note that 'pagehide' is not supported in IE.
|
|
448
452
|
// Registering this event conditionally for IE11 also because
|
|
449
453
|
// it affects bfcache optimization on modern browsers otherwise.
|
|
450
|
-
|
|
454
|
+
// However, if optimization is disabled, force subscribe the event
|
|
455
|
+
if(avoidBfCacheOptimization||isIE11()){globalThis.addEventListener('beforeunload',()=>{isAccessible=false;handleOnLeave();});}// This is important for iOS Safari browser as it does not
|
|
451
456
|
// fire the regular pagehide and visibilitychange events
|
|
452
457
|
// when user goes to tablist view and closes the tab.
|
|
453
458
|
globalThis.addEventListener('blur',()=>{isAccessible=true;handleOnLeave();});globalThis.addEventListener('focus',()=>{pageLeft=false;});// Catches the page being hidden, including scenarios like closing the tab.
|
|
@@ -510,7 +515,7 @@ error.stack=`${stack}\n${MANUAL_ERROR_IDENTIFIER}`;break;case stacktrace:// esli
|
|
|
510
515
|
error.stacktrace=`${stacktrace}\n${MANUAL_ERROR_IDENTIFIER}`;break;case operaSourceloc:default:// eslint-disable-next-line no-param-reassign
|
|
511
516
|
error['opera#sourceloc']=`${operaSourceloc}\n${MANUAL_ERROR_IDENTIFIER}`;break;}}}globalThis.dispatchEvent(new ErrorEvent('error',{error,bubbles:true,cancelable:true,composed:true}));};
|
|
512
517
|
|
|
513
|
-
const APP_NAME='RudderLabs JavaScript SDK';const APP_VERSION='3.25.
|
|
518
|
+
const APP_NAME='RudderLabs JavaScript SDK';const APP_VERSION='3.25.1-beta.pr.2607.91e7d4a';const APP_NAMESPACE='com.rudderlabs.javascript';const MODULE_TYPE='npm';const ADBLOCK_PAGE_CATEGORY='RudderJS-Initiated';const ADBLOCK_PAGE_NAME='ad-block page request';const ADBLOCK_PAGE_PATH='/ad-blocked';const GLOBAL_PRELOAD_BUFFER='preloadedEventsBuffer';const CONSENT_TRACK_EVENT_NAME='Consent Management Interaction';
|
|
514
519
|
|
|
515
520
|
const QUERY_PARAM_TRAIT_PREFIX='ajs_trait_';const QUERY_PARAM_PROPERTY_PREFIX='ajs_prop_';const QUERY_PARAM_ANONYMOUS_ID_KEY='ajs_aid';const QUERY_PARAM_USER_ID_KEY='ajs_uid';const QUERY_PARAM_TRACK_EVENT_NAME_KEY='ajs_event';
|
|
516
521
|
|
|
@@ -694,9 +699,9 @@ var errorStackParser$1 = {exports: {}};
|
|
|
694
699
|
|
|
695
700
|
var stackframe$1 = {exports: {}};
|
|
696
701
|
|
|
697
|
-
var stackframe=stackframe$1.exports;var hasRequiredStackframe;function requireStackframe(){if(hasRequiredStackframe)return stackframe$1.exports;hasRequiredStackframe=1;(function(module,exports){(function(root,factory){/* istanbul ignore next */{module.exports=factory();}})(stackframe,function(){function _isNumber(n){return !isNaN(parseFloat(n))&&isFinite(n);}function _capitalize(str){return str.charAt(0).toUpperCase()+str.substring(1);}function _getter(p){return function(){return this[p];};}var booleanProps=['isConstructor','isEval','isNative','isToplevel'];var numericProps=['columnNumber','lineNumber'];var stringProps=['fileName','functionName','source'];var arrayProps=['args'];var objectProps=['evalOrigin'];var props=booleanProps.concat(numericProps,stringProps,arrayProps,objectProps);function StackFrame(obj){if(!obj)return;for(var i=0;i<props.length;i++){if(obj[props[i]]!==undefined){this['set'+_capitalize(props[i])](obj[props[i]]);}}}StackFrame.prototype={getArgs:function(){return this.args;},setArgs:function(v){if(Object.prototype.toString.call(v)!=='[object Array]'){throw new TypeError('Args must be an Array');}this.args=v;},getEvalOrigin:function(){return this.evalOrigin;},setEvalOrigin:function(v){if(v instanceof StackFrame){this.evalOrigin=v;}else if(v instanceof Object){this.evalOrigin=new StackFrame(v);}else {throw new TypeError('Eval Origin must be an Object or StackFrame');}},toString:function(){var fileName=this.getFileName()||'';var lineNumber=this.getLineNumber()||'';var columnNumber=this.getColumnNumber()||'';var functionName=this.getFunctionName()||'';if(this.getIsEval()){if(fileName){return '[eval] ('+fileName+':'+lineNumber+':'+columnNumber+')';}return '[eval]:'+lineNumber+':'+columnNumber;}if(functionName){return functionName+' ('+fileName+':'+lineNumber+':'+columnNumber+')';}return fileName+':'+lineNumber+':'+columnNumber;}};StackFrame.fromString=function StackFrame$$fromString(str){var argsStartIndex=str.indexOf('(');var argsEndIndex=str.lastIndexOf(')');var functionName=str.substring(0,argsStartIndex);var args=str.substring(argsStartIndex+1,argsEndIndex).split(',');var locationString=str.substring(argsEndIndex+1);if(locationString.indexOf('@')===0){var parts=/@(.+?)(?::(\d+))?(?::(\d+))?$/.exec(locationString,'');var fileName=parts[1];var lineNumber=parts[2];var columnNumber=parts[3];}return new StackFrame({functionName:functionName,args:args||undefined,fileName:fileName,lineNumber:lineNumber||undefined,columnNumber:columnNumber||undefined});};for(var i=0;i<booleanProps.length;i++){StackFrame.prototype['get'+_capitalize(booleanProps[i])]=_getter(booleanProps[i]);StackFrame.prototype['set'+_capitalize(booleanProps[i])]=function(p){return function(v){this[p]=Boolean(v);};}(booleanProps[i]);}for(var j=0;j<numericProps.length;j++){StackFrame.prototype['get'+_capitalize(numericProps[j])]=_getter(numericProps[j]);StackFrame.prototype['set'+_capitalize(numericProps[j])]=function(p){return function(v){if(!_isNumber(v)){throw new TypeError(p+' must be a Number');}this[p]=Number(v);};}(numericProps[j]);}for(var k=0;k<stringProps.length;k++){StackFrame.prototype['get'+_capitalize(stringProps[k])]=_getter(stringProps[k]);StackFrame.prototype['set'+_capitalize(stringProps[k])]=function(p){return function(v){this[p]=String(v);};}(stringProps[k]);}return StackFrame;});})(stackframe$1);return stackframe$1.exports;}
|
|
702
|
+
var stackframe=stackframe$1.exports;var hasRequiredStackframe;function requireStackframe(){if(hasRequiredStackframe)return stackframe$1.exports;hasRequiredStackframe=1;(function(module,exports$1){(function(root,factory){/* istanbul ignore next */{module.exports=factory();}})(stackframe,function(){function _isNumber(n){return !isNaN(parseFloat(n))&&isFinite(n);}function _capitalize(str){return str.charAt(0).toUpperCase()+str.substring(1);}function _getter(p){return function(){return this[p];};}var booleanProps=['isConstructor','isEval','isNative','isToplevel'];var numericProps=['columnNumber','lineNumber'];var stringProps=['fileName','functionName','source'];var arrayProps=['args'];var objectProps=['evalOrigin'];var props=booleanProps.concat(numericProps,stringProps,arrayProps,objectProps);function StackFrame(obj){if(!obj)return;for(var i=0;i<props.length;i++){if(obj[props[i]]!==undefined){this['set'+_capitalize(props[i])](obj[props[i]]);}}}StackFrame.prototype={getArgs:function(){return this.args;},setArgs:function(v){if(Object.prototype.toString.call(v)!=='[object Array]'){throw new TypeError('Args must be an Array');}this.args=v;},getEvalOrigin:function(){return this.evalOrigin;},setEvalOrigin:function(v){if(v instanceof StackFrame){this.evalOrigin=v;}else if(v instanceof Object){this.evalOrigin=new StackFrame(v);}else {throw new TypeError('Eval Origin must be an Object or StackFrame');}},toString:function(){var fileName=this.getFileName()||'';var lineNumber=this.getLineNumber()||'';var columnNumber=this.getColumnNumber()||'';var functionName=this.getFunctionName()||'';if(this.getIsEval()){if(fileName){return '[eval] ('+fileName+':'+lineNumber+':'+columnNumber+')';}return '[eval]:'+lineNumber+':'+columnNumber;}if(functionName){return functionName+' ('+fileName+':'+lineNumber+':'+columnNumber+')';}return fileName+':'+lineNumber+':'+columnNumber;}};StackFrame.fromString=function StackFrame$$fromString(str){var argsStartIndex=str.indexOf('(');var argsEndIndex=str.lastIndexOf(')');var functionName=str.substring(0,argsStartIndex);var args=str.substring(argsStartIndex+1,argsEndIndex).split(',');var locationString=str.substring(argsEndIndex+1);if(locationString.indexOf('@')===0){var parts=/@(.+?)(?::(\d+))?(?::(\d+))?$/.exec(locationString,'');var fileName=parts[1];var lineNumber=parts[2];var columnNumber=parts[3];}return new StackFrame({functionName:functionName,args:args||undefined,fileName:fileName,lineNumber:lineNumber||undefined,columnNumber:columnNumber||undefined});};for(var i=0;i<booleanProps.length;i++){StackFrame.prototype['get'+_capitalize(booleanProps[i])]=_getter(booleanProps[i]);StackFrame.prototype['set'+_capitalize(booleanProps[i])]=function(p){return function(v){this[p]=Boolean(v);};}(booleanProps[i]);}for(var j=0;j<numericProps.length;j++){StackFrame.prototype['get'+_capitalize(numericProps[j])]=_getter(numericProps[j]);StackFrame.prototype['set'+_capitalize(numericProps[j])]=function(p){return function(v){if(!_isNumber(v)){throw new TypeError(p+' must be a Number');}this[p]=Number(v);};}(numericProps[j]);}for(var k=0;k<stringProps.length;k++){StackFrame.prototype['get'+_capitalize(stringProps[k])]=_getter(stringProps[k]);StackFrame.prototype['set'+_capitalize(stringProps[k])]=function(p){return function(v){this[p]=String(v);};}(stringProps[k]);}return StackFrame;});})(stackframe$1);return stackframe$1.exports;}
|
|
698
703
|
|
|
699
|
-
var errorStackParser=errorStackParser$1.exports;var hasRequiredErrorStackParser;function requireErrorStackParser(){if(hasRequiredErrorStackParser)return errorStackParser$1.exports;hasRequiredErrorStackParser=1;(function(module,exports){(function(root,factory){/* istanbul ignore next */{module.exports=factory(requireStackframe());}})(errorStackParser,function ErrorStackParser(StackFrame){var FIREFOX_SAFARI_STACK_REGEXP=/(^|@)\S+:\d+/;var CHROME_IE_STACK_REGEXP=/^\s*at .*(\S+:\d+|\(native\))/m;var SAFARI_NATIVE_CODE_REGEXP=/^(eval@)?(\[native code])?$/;return {/**
|
|
704
|
+
var errorStackParser=errorStackParser$1.exports;var hasRequiredErrorStackParser;function requireErrorStackParser(){if(hasRequiredErrorStackParser)return errorStackParser$1.exports;hasRequiredErrorStackParser=1;(function(module,exports$1){(function(root,factory){/* istanbul ignore next */{module.exports=factory(requireStackframe());}})(errorStackParser,function ErrorStackParser(StackFrame){var FIREFOX_SAFARI_STACK_REGEXP=/(^|@)\S+:\d+/;var CHROME_IE_STACK_REGEXP=/^\s*at .*(\S+:\d+|\(native\))/m;var SAFARI_NATIVE_CODE_REGEXP=/^(eval@)?(\[native code])?$/;return {/**
|
|
700
705
|
* Given an Error object, extract the most information from it.
|
|
701
706
|
*
|
|
702
707
|
* @param {Error} error object
|
|
@@ -2801,7 +2806,7 @@ const getDefaultCookieOptions=()=>{const topDomain=`.${domain(globalThis.locatio
|
|
|
2801
2806
|
|
|
2802
2807
|
var store$2 = {exports: {}};
|
|
2803
2808
|
|
|
2804
|
-
var store$1=store$2.exports;var hasRequiredStore;function requireStore(){if(hasRequiredStore)return store$2.exports;hasRequiredStore=1;(function(module,exports){(function(global,factory){module.exports=factory();})(store$1,function(){function isJSON(obj){obj=JSON.stringify(obj);if(!/^\{[\s\S]*\}$/.test(obj)){return false;}return true;}function stringify(val){return val===undefined||typeof val==="function"?val+'':JSON.stringify(val);}function deserialize(value){if(typeof value!=='string'){return undefined;}try{return JSON.parse(value);}catch(e){return value;}}function isFunction(value){return {}.toString.call(value)==="[object Function]";}function isArray(value){return Object.prototype.toString.call(value)==="[object Array]";}// https://github.com/jaywcjlove/store.js/pull/8
|
|
2809
|
+
var store$1=store$2.exports;var hasRequiredStore;function requireStore(){if(hasRequiredStore)return store$2.exports;hasRequiredStore=1;(function(module,exports$1){(function(global,factory){module.exports=factory();})(store$1,function(){function isJSON(obj){obj=JSON.stringify(obj);if(!/^\{[\s\S]*\}$/.test(obj)){return false;}return true;}function stringify(val){return val===undefined||typeof val==="function"?val+'':JSON.stringify(val);}function deserialize(value){if(typeof value!=='string'){return undefined;}try{return JSON.parse(value);}catch(e){return value;}}function isFunction(value){return {}.toString.call(value)==="[object Function]";}function isArray(value){return Object.prototype.toString.call(value)==="[object Array]";}// https://github.com/jaywcjlove/store.js/pull/8
|
|
2805
2810
|
// Error: QuotaExceededError
|
|
2806
2811
|
function dealIncognito(storage){var _KEY='_Is_Incognit',_VALUE='yes';try{// NOTE: set default storage when not passed in
|
|
2807
2812
|
if(!storage){storage=window.localStorage;}storage.setItem(_KEY,_VALUE);storage.removeItem(_KEY);}catch(e){var inMemoryStorage={};inMemoryStorage._data={};inMemoryStorage.setItem=function(id,val){return inMemoryStorage._data[id]=String(val);};inMemoryStorage.getItem=function(id){return inMemoryStorage._data.hasOwnProperty(id)?inMemoryStorage._data[id]:undefined;};inMemoryStorage.removeItem=function(id){return delete inMemoryStorage._data[id];};inMemoryStorage.clear=function(){return inMemoryStorage._data={};};storage=inMemoryStorage;}finally{if(storage.getItem(_KEY)===_VALUE)storage.removeItem(_KEY);}return storage;}// deal QuotaExceededError if user use incognito mode in browser
|
|
@@ -3284,7 +3289,11 @@ enrichedEvent.userId=to??enrichedEvent.userId;return enrichedEvent;}/**
|
|
|
3284
3289
|
* @param event Incoming event data
|
|
3285
3290
|
*/addEvent(event){this.userSessionManager.refreshSession();const rudderEvent=this.eventFactory.create(event);this.eventRepository.enqueue(rudderEvent,event.callback);}}
|
|
3286
3291
|
|
|
3287
|
-
class UserSessionManager{
|
|
3292
|
+
class UserSessionManager{/**
|
|
3293
|
+
* Tracks whether the setting the cookies action has been queued or not
|
|
3294
|
+
*//**
|
|
3295
|
+
* Tracks the number of queued cookie set requests
|
|
3296
|
+
*/constructor(pluginsManager,storeManager,httpClient,errorHandler,logger){this.storeManager=storeManager;this.pluginsManager=pluginsManager;this.logger=logger;this.errorHandler=errorHandler;this.httpClient=httpClient;this.onError=this.onError.bind(this);this.serverSideCookieDebounceFuncs={};this.serverSideCookiesRequestInProgress={};this.serverSideCookieSetRequests={};}/**
|
|
3288
3297
|
* Initialize User session with values from storage
|
|
3289
3298
|
*/init(){this.syncStorageDataToState();// Register the effect to sync with storage
|
|
3290
3299
|
this.registerEffects();}syncStorageDataToState(){this.migrateStorageIfNeeded();this.migrateDataFromPreviousStorage();// get the values from storage and set it again
|
|
@@ -3316,18 +3325,33 @@ cutOffDuration=DEFAULT_SESSION_CUT_OFF_DURATION_MS;}else if(cutOffDuration<sessi
|
|
|
3316
3325
|
* A function to make an external request to set the cookie from server side
|
|
3317
3326
|
* @param key cookie name
|
|
3318
3327
|
* @param value encrypted cookie value
|
|
3319
|
-
*/setServerSideCookies(
|
|
3328
|
+
*/setServerSideCookies(sessionEntries,cb,store){// Retrieve the cookie value from the state
|
|
3329
|
+
const sessionKeys=Object.keys(sessionEntries);const cookiesData=sessionKeys.map(sessionKey=>{return {name:sessionEntries[sessionKey].name,value:state.session[sessionKey].value};});const clearInProgressFlags=()=>{sessionKeys.forEach(sessionKey=>{this.serverSideCookiesRequestInProgress[sessionKey]=false;});};try{// encrypt cookies values
|
|
3320
3330
|
const encryptedCookieData=this.getEncryptedCookieData(cookiesData,store);if(encryptedCookieData.length>0){// make request to data service to set the cookie from server side
|
|
3321
|
-
this.makeRequestToSetCookie(encryptedCookieData,(res,details)=>{
|
|
3331
|
+
this.makeRequestToSetCookie(encryptedCookieData,(res,details)=>{// Mark the cookie req status as done
|
|
3332
|
+
clearInProgressFlags();if(details?.xhr?.status===200){cookiesData.forEach(cData=>{const cookieValue=store?.get(cData.name);const before=stringifyWithoutCircular(cData.value,false,[]);const after=stringifyWithoutCircular(cookieValue,false,[]);if(after!==before){this.logger.error(FAILED_SETTING_COOKIE_FROM_SERVER_ERROR(cData.name));if(cb){cb(cData.name,cData.value);}}});}else {this.logger.error(DATA_SERVER_REQUEST_FAIL_ERROR(details?.xhr?.status));cookiesData.forEach(each=>{if(cb){cb(each.name,each.value);}});}});}else {// Mark the cookie req status as done
|
|
3333
|
+
clearInProgressFlags();}}catch(e){// Mark the cookie req status as done
|
|
3334
|
+
clearInProgressFlags();this.onError(e,FAILED_SETTING_COOKIE_FROM_SERVER_GLOBAL_ERROR,FAILED_SETTING_COOKIE_FROM_SERVER_GLOBAL_ERROR);cookiesData.forEach(each=>{if(cb){cb(each.name,each.value);}});}}/**
|
|
3322
3335
|
* A function to sync values in storage
|
|
3323
3336
|
* @param sessionKey
|
|
3324
|
-
* @param value
|
|
3325
|
-
*/syncValueToStorage(sessionKey,
|
|
3337
|
+
* @param stateValue optional state value to sync. By default, we directly read from the state
|
|
3338
|
+
*/syncValueToStorage(sessionKey,stateValue){const entries=state.storage.entries.value;const storageType=entries[sessionKey]?.type;if(isStorageTypeValidForStoringData(storageType)){const curStore=this.storeManager?.getStore(storageClientDataStoreNameMap[storageType]);const key=entries[sessionKey]?.key;// Determine the final user session entry value
|
|
3339
|
+
const value=stateValue??state.session[sessionKey].value;if(value&&(isString(value)||isNonEmptyObject(value))){// if useServerSideCookies load option is set to true
|
|
3326
3340
|
// set the cookie from server side
|
|
3327
|
-
if(state.serverCookies.isEnabledServerSideCookies.value&&storageType===COOKIE_STORAGE){
|
|
3341
|
+
if(state.serverCookies.isEnabledServerSideCookies.value&&storageType===COOKIE_STORAGE){// Mark the requests as in progress.
|
|
3342
|
+
this.serverSideCookiesRequestInProgress[sessionKey]=true;const setCookieFunc=()=>{const sessionEntries={[sessionKey]:{name:key}};this.setServerSideCookies(sessionEntries,(cookieName,cookieValue)=>{curStore?.set(cookieName,cookieValue);},curStore);};// When debounce is not active, set it up.
|
|
3343
|
+
// Debounce behavior: Only the first and last values are sent during the debounce window.
|
|
3344
|
+
// The first request is sent immediately to prevent events from missing session info.
|
|
3345
|
+
// Subsequent changes within the debounce window are consolidated into a single request
|
|
3346
|
+
// that sends the latest value after the debounce delay. Intermediate values are not persisted.
|
|
3347
|
+
if(!this.serverSideCookieDebounceFuncs[sessionKey]){this.serverSideCookieSetRequests[sessionKey]=0;// For the first time, make the cookie request anyway.
|
|
3348
|
+
setCookieFunc();this.serverSideCookieDebounceFuncs[sessionKey]=globalThis.setTimeout(()=>{delete this.serverSideCookieDebounceFuncs[sessionKey];// In the debounce function, make the cookie request only when cookie requests are waiting
|
|
3349
|
+
// in the queue. The first request would have been sent already.
|
|
3350
|
+
if(this.serverSideCookieSetRequests[sessionKey]>0){setCookieFunc();this.serverSideCookieSetRequests[sessionKey]=0;}},SERVER_SIDE_COOKIES_DEBOUNCE_TIME);}else {// Increment the queued cookie set actions
|
|
3351
|
+
this.serverSideCookieSetRequests[sessionKey]+=1;}}else {curStore?.set(key,value);}}else {curStore?.remove(key);}}}/**
|
|
3328
3352
|
* Function to update storage whenever state value changes
|
|
3329
3353
|
*/registerEffects(){// This will work as long as the user session entry key names are same as the state keys
|
|
3330
|
-
USER_SESSION_KEYS.forEach(sessionKey=>{E(()=>{this.syncValueToStorage(sessionKey
|
|
3354
|
+
USER_SESSION_KEYS.forEach(sessionKey=>{E(()=>{this.syncValueToStorage(sessionKey);});});}/**
|
|
3331
3355
|
* Sets anonymous id in the following precedence:
|
|
3332
3356
|
*
|
|
3333
3357
|
* 1. anonymousId: Id directly provided to the function.
|
|
@@ -3373,7 +3397,8 @@ this.migrateStorageIfNeeded([store],[sessionKey]);const storageKey=entries[sessi
|
|
|
3373
3397
|
*/getSessionId(){const sessionInfo=this.getSessionInfo()??DEFAULT_USER_SESSION_VALUES.sessionInfo;if(sessionInfo.autoTrack&&!hasSessionExpired(sessionInfo)||sessionInfo.manualTrack){return sessionInfo.id??null;}return null;}/**
|
|
3374
3398
|
* A function to keep the session information up to date in the state
|
|
3375
3399
|
* before using it for building event payloads.
|
|
3376
|
-
*/refreshSession(){let
|
|
3400
|
+
*/refreshSession(){let initialSessionInfo=this.getSessionInfo();// If cookie set request is in progress, use the state value. That should be sufficient.
|
|
3401
|
+
if(initialSessionInfo===null&&this.serverSideCookiesRequestInProgress['sessionInfo']){initialSessionInfo=state.session.sessionInfo.value;}let sessionInfo=initialSessionInfo??DEFAULT_USER_SESSION_VALUES.sessionInfo;if(sessionInfo.autoTrack||sessionInfo.manualTrack){if(sessionInfo.autoTrack){this.startOrRenewAutoTracking(sessionInfo);sessionInfo=state.session.sessionInfo.value;}// Note that if sessionStart is false, then it's an active session.
|
|
3377
3402
|
// So, we needn't update the session info.
|
|
3378
3403
|
//
|
|
3379
3404
|
// For other scenarios,
|
|
@@ -3623,7 +3648,7 @@ state.autoTrack.enabled.value=autoTrackEnabled||pageLifecycleEnabled;if(!pageLif
|
|
|
3623
3648
|
* @param events
|
|
3624
3649
|
* @param useBeacon
|
|
3625
3650
|
* @param options
|
|
3626
|
-
*/setupPageUnloadTracking(events,useBeacon,options){if(events.length===0||events.includes(PageLifecycleEvents.UNLOADED)){if(useBeacon===true){onPageLeave(isAccessible=>{if(isAccessible===false&&state.lifecycle.loaded.value){const pageUnloadedTimestamp=Date.now();const timeOnPage=pageUnloadedTimestamp-state.autoTrack.pageLifecycle.pageLoadedTimestamp.value;this.track(PageLifecycleEvents.UNLOADED,{timeOnPage},{...options,originalTimestamp:getFormattedTimestamp(new Date(pageUnloadedTimestamp))});}});}else {// log warning if beacon is disabled
|
|
3651
|
+
*/setupPageUnloadTracking(events,useBeacon,options){if(events.length===0||events.includes(PageLifecycleEvents.UNLOADED)){if(useBeacon===true){onPageLeave(isAccessible=>{if(isAccessible===false&&state.lifecycle.loaded.value){const pageUnloadedTimestamp=Date.now();const timeOnPage=pageUnloadedTimestamp-state.autoTrack.pageLifecycle.pageLoadedTimestamp.value;this.track(PageLifecycleEvents.UNLOADED,{timeOnPage},{...options,originalTimestamp:getFormattedTimestamp(new Date(pageUnloadedTimestamp))});}},true);}else {// log warning if beacon is disabled
|
|
3627
3652
|
this.logger.warn(PAGE_UNLOAD_ON_BEACON_DISABLED_WARNING(RSA));}}}/**
|
|
3628
3653
|
* Trigger load event in buffer queue if exists and stores the
|
|
3629
3654
|
* remaining preloaded events array in global object
|