@rudderstack/analytics-js 3.0.0-beta.1 → 3.0.0-beta.3
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 +24 -2
- package/README.md +48 -6
- package/index.d.ts +54 -25
- package/legacy/cjs/index.js +372 -363
- package/legacy/esm/index.js +372 -363
- package/legacy/umd/index.js +372 -363
- package/modern/cjs/index.js +263 -219
- package/modern/esm/index.js +263 -219
- package/modern/umd/index.js +263 -219
- package/package.json +7 -5
package/modern/esm/index.js
CHANGED
@@ -511,11 +511,15 @@ mergeDeepRight(mergedArray[index],value):value;});return mergedArray;};const mer
|
|
511
511
|
* A utility to recursively remove undefined values from an object
|
512
512
|
* @param obj input object
|
513
513
|
* @returns a new object
|
514
|
-
*/const removeUndefinedValues=obj=>{const result=pickBy$1(isDefined,obj);Object.
|
514
|
+
*/const removeUndefinedValues=obj=>{const result=pickBy$1(isDefined,obj);Object.keys(result).forEach(key=>{const value=result[key];if(isObjectLiteralAndNotNull(value)){result[key]=removeUndefinedValues(value);}});return result;};/**
|
515
515
|
* A utility to recursively remove undefined and null values from an object
|
516
516
|
* @param obj input object
|
517
517
|
* @returns a new object
|
518
|
-
*/const removeUndefinedAndNullValues=obj=>{const result=pickBy$1(isDefinedAndNotNull,obj);Object.
|
518
|
+
*/const removeUndefinedAndNullValues=obj=>{const result=pickBy$1(isDefinedAndNotNull,obj);Object.keys(result).forEach(key=>{const value=result[key];if(isObjectLiteralAndNotNull(value)){result[key]=removeUndefinedAndNullValues(value);}});return result;};/**
|
519
|
+
* A utility to get all the values from an object
|
520
|
+
* @param obj Input object
|
521
|
+
* @returns an array of values from the input object
|
522
|
+
*/const getObjectValues=obj=>{const result=[];Object.keys(obj).forEach(key=>{result.push(obj[key]);});return result;};
|
519
523
|
|
520
524
|
const trim=value=>value.replace(/^\s+|\s+$/gm,'');const removeDoubleSpaces=value=>value.replace(/ {2,}/g,' ');/**
|
521
525
|
* A function to convert values to string
|
@@ -535,17 +539,43 @@ const trim=value=>value.replace(/^\s+|\s+$/gm,'');const removeDoubleSpaces=value
|
|
535
539
|
// if yes make them null instead of omitting in overloaded cases
|
536
540
|
/*
|
537
541
|
* Normalise the overloaded arguments of the page call facade
|
538
|
-
*/const pageArgumentsToCallOptions=(category,name,properties,options,callback)=>{const payload={};if(isFunction(callback)){payload.
|
542
|
+
*/const pageArgumentsToCallOptions=(category,name,properties,options,callback)=>{const payload={category:category,name:name,properties:properties,options:options};if(isFunction(callback)){payload.callback=callback;}if(isFunction(options)){payload.category=category;payload.name=name;payload.properties=properties;delete payload.options;payload.callback=options;}if(isFunction(properties)){payload.category=category;payload.name=name;delete payload.properties;delete payload.options;payload.callback=properties;}if(isFunction(name)){payload.category=category;delete payload.name;delete payload.properties;delete payload.options;payload.callback=name;}if(isFunction(category)){delete payload.category;delete payload.name;delete payload.properties;delete payload.options;payload.callback=category;}if(isObjectLiteralAndNotNull(category)){delete payload.name;delete payload.category;payload.properties=category;payload.options=name;}else if(isObjectLiteralAndNotNull(name)){delete payload.name;payload.properties=name;payload.options=!isFunction(properties)?properties:null;}// if the category argument alone is provided b/w category and name,
|
543
|
+
// use it as name and set category to undefined
|
544
|
+
if(isString(category)&&!isString(name)){delete payload.category;payload.name=category;}// Rest of the code is just to clean up undefined values
|
545
|
+
// and set some proper defaults
|
546
|
+
// Also, to clone the incoming object type arguments
|
547
|
+
if(!isDefined(payload.category)){delete payload.category;}if(!isDefined(payload.name)){delete payload.name;}payload.properties=payload.properties?clone$1(payload.properties):{};if(isDefined(payload.options)){payload.options=clone$1(payload.options);}else {delete payload.options;}// add name and category to properties
|
548
|
+
payload.properties=mergeDeepRight(isObjectLiteralAndNotNull(payload.properties)?payload.properties:{},{name:isString(payload.name)?payload.name:null,category:isString(payload.category)?payload.category:null});return payload;};/*
|
539
549
|
* Normalise the overloaded arguments of the track call facade
|
540
|
-
*/const trackArgumentsToCallOptions=(event,properties,options,callback)=>{const payload={name:event};if(isFunction(callback)){payload.
|
541
|
-
|
550
|
+
*/const trackArgumentsToCallOptions=(event,properties,options,callback)=>{const payload={name:event,properties:properties,options:options};if(isFunction(callback)){payload.callback=callback;}if(isFunction(options)){payload.properties=properties;delete payload.options;payload.callback=options;}if(isFunction(properties)){delete payload.properties;delete payload.options;payload.callback=properties;}// Rest of the code is just to clean up undefined values
|
551
|
+
// and set some proper defaults
|
552
|
+
// Also, to clone the incoming object type arguments
|
553
|
+
payload.properties=isDefinedAndNotNull(payload.properties)?clone$1(payload.properties):{};if(isDefined(payload.options)){payload.options=clone$1(payload.options);}else {delete payload.options;}return payload;};/*
|
542
554
|
* Normalise the overloaded arguments of the identify call facade
|
543
|
-
*/const identifyArgumentsToCallOptions=(userId,traits,options,callback)=>{const payload={};if(isFunction(callback)){payload.
|
555
|
+
*/const identifyArgumentsToCallOptions=(userId,traits,options,callback)=>{const payload={userId:userId,traits:traits,options:options};if(isFunction(callback)){payload.callback=callback;}if(isFunction(options)){payload.userId=userId;payload.traits=traits;delete payload.options;payload.callback=options;}if(isFunction(traits)){payload.userId=userId;delete payload.traits;delete payload.options;payload.callback=traits;}if(isObjectLiteralAndNotNull(userId)||isNull(userId)){// Explicitly set null to prevent resetting the existing value
|
556
|
+
// in the Analytics class
|
557
|
+
payload.userId=null;payload.traits=userId;payload.options=traits;}// Rest of the code is just to clean up undefined values
|
558
|
+
// and set some proper defaults
|
559
|
+
// Also, to clone the incoming object type arguments
|
560
|
+
if(isDefined(payload.userId)){payload.userId=tryStringify(payload.userId);}else {delete payload.userId;}if(isObjectLiteralAndNotNull(payload.traits)){payload.traits=clone$1(payload.traits);}else {delete payload.traits;}if(isDefined(payload.options)){payload.options=clone$1(payload.options);}else {delete payload.options;}return payload;};/*
|
544
561
|
* Normalise the overloaded arguments of the alias call facade
|
545
|
-
*/const aliasArgumentsToCallOptions=(to,from,options,callback)=>{const payload={};if(isFunction(callback)){payload.
|
562
|
+
*/const aliasArgumentsToCallOptions=(to,from,options,callback)=>{const payload={to:to,from:from,options:options};if(isFunction(callback)){payload.callback=callback;}if(isFunction(options)){payload.to=to;payload.from=from;delete payload.options;payload.callback=options;}if(isFunction(from)){payload.to=to;delete payload.from;delete payload.options;payload.callback=from;}else if(isObjectLiteralAndNotNull(from)||isNull(from)){payload.to=to;delete payload.from;payload.options=from;}if(isFunction(to)){delete payload.to;delete payload.from;delete payload.options;payload.callback=to;}else if(isObjectLiteralAndNotNull(to)||isNull(to)){delete payload.to;delete payload.from;payload.options=to;}// Rest of the code is just to clean up undefined values
|
563
|
+
// and set some proper defaults
|
564
|
+
// Also, to clone the incoming object type arguments
|
565
|
+
if(isDefined(payload.to)){payload.to=tryStringify(payload.to);}else {delete payload.to;}if(isDefined(payload.from)){payload.from=tryStringify(payload.from);}else {delete payload.from;}if(isDefined(payload.options)){payload.options=clone$1(payload.options);}else {delete payload.options;}return payload;};/*
|
546
566
|
* Normalise the overloaded arguments of the group call facade
|
547
|
-
*/const groupArgumentsToCallOptions=(groupId,traits,options,callback)=>{const payload={};if(isFunction(callback)){payload.
|
548
|
-
if(isFunction(groupId)){
|
567
|
+
*/const groupArgumentsToCallOptions=(groupId,traits,options,callback)=>{const payload={groupId:groupId,traits:traits,options:options};if(isFunction(callback)){payload.callback=callback;}if(isFunction(options)){payload.groupId=groupId;payload.traits=traits;delete payload.options;payload.callback=options;}if(isFunction(traits)){payload.groupId=groupId;delete payload.traits;delete payload.options;payload.callback=traits;}// TODO: why do we enable overload for group that only passes callback? is there any use case?
|
568
|
+
if(isFunction(groupId)){// Explicitly set null to prevent resetting the existing value
|
569
|
+
payload.groupId=null;delete payload.traits;delete payload.options;payload.callback=groupId;}else if(isObjectLiteralAndNotNull(groupId)||isNull(groupId)){// Explicitly set null to prevent resetting the existing value
|
570
|
+
// in the Analytics class
|
571
|
+
payload.groupId=null;payload.traits=groupId;payload.options=!isFunction(traits)?traits:null;}// Rest of the code is just to clean up undefined values
|
572
|
+
// and set some proper defaults
|
573
|
+
// Also, to clone the incoming object type arguments
|
574
|
+
if(isDefined(payload.groupId)){payload.groupId=tryStringify(payload.groupId);}else {delete payload.groupId;}payload.traits=isObjectLiteralAndNotNull(payload.traits)?clone$1(payload.traits):{};if(isDefined(payload.options)){payload.options=clone$1(payload.options);}else {delete payload.options;}return payload;};
|
575
|
+
|
576
|
+
const CAPABILITIES_MANAGER='CapabilitiesManager';const CONFIG_MANAGER='ConfigManager';const EVENT_MANAGER='EventManager';const PLUGINS_MANAGER='PluginsManager';const USER_SESSION_MANAGER='UserSessionManager';const ERROR_HANDLER='ErrorHandler';const PLUGIN_ENGINE='PluginEngine';const STORE_MANAGER='StoreManager';const READY_API='readyApi';const LOAD_CONFIGURATION='LoadConfiguration';const EVENT_REPOSITORY='EventRepository';const EXTERNAL_SRC_LOADER='ExternalSrcLoader';const HTTP_CLIENT='HttpClient';const RS_APP='RudderStackApplication';const ANALYTICS_CORE='AnalyticsCore';
|
577
|
+
|
578
|
+
const APP_NAME='RudderLabs JavaScript SDK';const APP_VERSION='3.0.0-beta.3';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';
|
549
579
|
|
550
580
|
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';
|
551
581
|
|
@@ -557,8 +587,6 @@ const QUERY_PARAM_TRAIT_PREFIX='ajs_trait_';const QUERY_PARAM_PROPERTY_PREFIX='a
|
|
557
587
|
* Get values from globally accessible RudderStackGlobals object by analytics instance
|
558
588
|
*/const getExposedGlobal=(keyName,analyticsInstanceId='app')=>{createExposedGlobals(analyticsInstanceId);return globalThis.RudderStackGlobals[analyticsInstanceId][keyName];};
|
559
589
|
|
560
|
-
const APP_NAME='RudderLabs JavaScript SDK';const APP_VERSION='3.0.0-beta.1';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';
|
561
|
-
|
562
590
|
/**
|
563
591
|
* Parse query string params into object values for keys that start with a defined prefix
|
564
592
|
*/const getEventDataFromQueryString=(params,dataTypeNamePrefix)=>{const data={};params.forEach((value,key)=>{if(key.startsWith(dataTypeNamePrefix)){// remove prefix from key name
|
@@ -579,6 +607,85 @@ if(queryObject.get(QUERY_PARAM_ANONYMOUS_ID_KEY)){argumentsArray.unshift(['setAn
|
|
579
607
|
retrieveEventsFromQueryString(preloadedEventsArray);const sanitizedPreloadedEventsArray=preloadedEventsArray.filter(bufferedEvent=>bufferedEvent[0]!=='load');// Enqueue the non load events in the buffer of the global rudder analytics singleton
|
580
608
|
if(sanitizedPreloadedEventsArray.length>0){instance.enqueuePreloadBufferEvents(sanitizedPreloadedEventsArray);setExposedGlobal(GLOBAL_PRELOAD_BUFFER,[]);}};const consumePreloadBufferedEvent=(event,analyticsInstance)=>{const methodName=event.shift();let callOptions;if(isFunction(analyticsInstance[methodName])){switch(methodName){case'page':callOptions=pageArgumentsToCallOptions(...event);break;case'track':callOptions=trackArgumentsToCallOptions(...event);break;case'identify':callOptions=identifyArgumentsToCallOptions(...event);break;case'alias':callOptions=aliasArgumentsToCallOptions(...event);break;case'group':callOptions=groupArgumentsToCallOptions(...event);break;default:analyticsInstance[methodName](...event);break;}if(callOptions){analyticsInstance[methodName](callOptions);}}};
|
581
609
|
|
610
|
+
const DEFAULT_EXT_SRC_LOAD_TIMEOUT_MS=10*1000;// 10 seconds
|
611
|
+
|
612
|
+
const LOG_CONTEXT_SEPARATOR=':: ';const SCRIPT_ALREADY_EXISTS_ERROR=id=>`A script with the id "${id}" is already loaded. Skipping the loading of this script to prevent conflicts.`;const SCRIPT_LOAD_ERROR=(id,url)=>`Failed to load the script with the id "${id}" from URL "${url}".`;const SCRIPT_LOAD_TIMEOUT_ERROR=(id,url,timeout)=>`A timeout of ${timeout} ms occurred while trying to load the script with id "${id}" from URL "${url}".`;const CIRCULAR_REFERENCE_WARNING=(context,key)=>`${context}${LOG_CONTEXT_SEPARATOR}A circular reference has been detected in the object and the property "${key}" has been dropped from the output.`;const JSON_STRINGIFY_WARNING=`Failed to convert the value to a JSON string.`;
|
613
|
+
|
614
|
+
const JSON_STRINGIFY='JSONStringify';const getCircularReplacer=(excludeNull,excludeKeys,logger)=>{const ancestors=[];// Here we do not want to use arrow function to use "this" in function context
|
615
|
+
// eslint-disable-next-line func-names
|
616
|
+
return function(key,value){if(excludeKeys?.includes(key)){return undefined;}if(excludeNull&&isNullOrUndefined(value)){return undefined;}if(typeof value!=='object'||isNull(value)){return value;}// `this` is the object that value is contained in, i.e., its direct parent.
|
617
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
618
|
+
// @ts-ignore-next-line
|
619
|
+
while(ancestors.length>0&&ancestors[ancestors.length-1]!==this){ancestors.pop();}if(ancestors.includes(value)){logger?.warn(CIRCULAR_REFERENCE_WARNING(JSON_STRINGIFY,key));return '[Circular Reference]';}ancestors.push(value);return value;};};/**
|
620
|
+
* Utility method for JSON stringify object excluding null values & circular references
|
621
|
+
*
|
622
|
+
* @param {*} value input
|
623
|
+
* @param {boolean} excludeNull if it should exclude nul or not
|
624
|
+
* @param {function} logger optional logger methods for warning
|
625
|
+
* @returns string
|
626
|
+
*/const stringifyWithoutCircular=(value,excludeNull,excludeKeys,logger)=>{try{return JSON.stringify(value,getCircularReplacer(excludeNull,excludeKeys,logger));}catch(err){logger?.warn(JSON_STRINGIFY_WARNING,err);return null;}};
|
627
|
+
|
628
|
+
/**
|
629
|
+
* Get mutated error with issue prepended to error message
|
630
|
+
* @param err Original error
|
631
|
+
* @param issue Issue to prepend to error message
|
632
|
+
* @returns Instance of Error with message prepended with issue
|
633
|
+
*/const getMutatedError=(err,issue)=>{let finalError=err;if(!isTypeOfError(err)){finalError=new Error(`${issue}: ${stringifyWithoutCircular(err)}`);}else {finalError.message=`${issue}: ${err.message}`;}return finalError;};
|
634
|
+
|
635
|
+
const EXTERNAL_SOURCE_LOAD_ORIGIN='RS_JS_SDK';
|
636
|
+
|
637
|
+
/**
|
638
|
+
* Create the DOM element to load a script marked as RS SDK originated
|
639
|
+
*
|
640
|
+
* @param {*} url The URL of the script to be loaded
|
641
|
+
* @param {*} id ID for the script tag
|
642
|
+
* @param {*} async Whether to load the script in async mode. Defaults to `true` [optional]
|
643
|
+
* @param {*} onload callback to invoke onload [optional]
|
644
|
+
* @param {*} onerror callback to invoke onerror [optional]
|
645
|
+
* @param {*} extraAttributes key/value pair with html attributes to add in html tag [optional]
|
646
|
+
*
|
647
|
+
* @returns HTMLScriptElement
|
648
|
+
*/const createScriptElement=(url,id,async=true,onload=null,onerror=null,extraAttributes={})=>{const scriptElement=document.createElement('script');scriptElement.type='text/javascript';scriptElement.onload=onload;scriptElement.onerror=onerror;scriptElement.src=url;scriptElement.id=id;scriptElement.async=async;scriptElement.setAttribute('data-append-origin',EXTERNAL_SOURCE_LOAD_ORIGIN);Object.keys(extraAttributes).forEach(attributeName=>{scriptElement.setAttribute(attributeName,extraAttributes[attributeName]);});return scriptElement;};/**
|
649
|
+
* Add script DOM element to DOM
|
650
|
+
*
|
651
|
+
* @param {*} newScriptElement the script element to add
|
652
|
+
*
|
653
|
+
* @returns
|
654
|
+
*/const insertScript=newScriptElement=>{// First try to add it to the head
|
655
|
+
const headElements=document.getElementsByTagName('head');if(headElements.length>0){headElements[0].insertBefore(newScriptElement,headElements[0].firstChild);return;}// Else wise add it before the first script tag
|
656
|
+
const scriptElements=document.getElementsByTagName('script');if(scriptElements.length>0&&scriptElements[0].parentNode){scriptElements[0].parentNode.insertBefore(newScriptElement,scriptElements[0]);return;}// Create a new head element and add the script as fallback
|
657
|
+
const headElement=document.createElement('head');headElement.appendChild(newScriptElement);const htmlElement=document.getElementsByTagName('html')[0];htmlElement.insertBefore(headElement,htmlElement.firstChild);};/**
|
658
|
+
* Loads external js file as a script html tag
|
659
|
+
*
|
660
|
+
* @param {*} url The URL of the script to be loaded
|
661
|
+
* @param {*} id ID for the script tag
|
662
|
+
* @param {*} timeout loading timeout
|
663
|
+
* @param {*} async Whether to load the script in async mode. Defaults to `true` [optional]
|
664
|
+
* @param {*} extraAttributes key/value pair with html attributes to add in html tag [optional]
|
665
|
+
*
|
666
|
+
* @returns
|
667
|
+
*/const jsFileLoader=(url,id,timeout,async=true,extraAttributes)=>new Promise((resolve,reject)=>{const scriptExists=document.getElementById(id);if(scriptExists){reject(new Error(SCRIPT_ALREADY_EXISTS_ERROR(id)));}try{let timeoutID;const onload=()=>{globalThis.clearTimeout(timeoutID);resolve(id);};const onerror=()=>{globalThis.clearTimeout(timeoutID);reject(new Error(SCRIPT_LOAD_ERROR(id,url)));};// Create the DOM element to load the script and add it to the DOM
|
668
|
+
insertScript(createScriptElement(url,id,async,onload,onerror,extraAttributes));// Reject on timeout
|
669
|
+
timeoutID=globalThis.setTimeout(()=>{reject(new Error(SCRIPT_LOAD_TIMEOUT_ERROR(id,url,timeout)));},timeout);}catch(err){reject(getMutatedError(err,SCRIPT_LOAD_ERROR(id,url)));}});
|
670
|
+
|
671
|
+
/**
|
672
|
+
* Service to load external resources/files
|
673
|
+
*/class ExternalSrcLoader{hasErrorHandler=false;constructor(errorHandler,logger,timeout=DEFAULT_EXT_SRC_LOAD_TIMEOUT_MS){this.errorHandler=errorHandler;this.logger=logger;this.timeout=timeout;this.hasErrorHandler=Boolean(this.errorHandler);this.onError=this.onError.bind(this);}/**
|
674
|
+
* Load external resource of type javascript
|
675
|
+
*/loadJSFile(config){const{url,id,timeout,async,callback,extraAttributes}=config;const isFireAndForget=!(callback&&isFunction(callback));jsFileLoader(url,id,timeout||this.timeout,async,extraAttributes).then(id=>{if(!isFireAndForget){callback(id);}}).catch(err=>{this.onError(err);if(!isFireAndForget){callback();}});}/**
|
676
|
+
* Handle errors
|
677
|
+
*/onError(error){if(this.hasErrorHandler){this.errorHandler?.onError(error,EXTERNAL_SRC_LOADER);}else {throw error;}}}
|
678
|
+
|
679
|
+
function i(){throw new Error("Cycle detected");}function t(){if(!(h>1)){var i,t=!1;while(void 0!==n){var o=n;n=void 0;s++;while(void 0!==o){var r=o.o;o.o=void 0;o.f&=-3;if(!(8&o.f)&&c(o))try{o.c();}catch(o){if(!t){i=o;t=!0;}}o=r;}}s=0;h--;if(t)throw i;}else h--;}function o(i){if(h>0)return i();h++;try{return i();}finally{t();}}var r=void 0,n=void 0,h=0,s=0,f=0;function v(i){if(void 0!==r){var t=i.n;if(void 0===t||t.t!==r){t={i:0,S:i,p:r.s,n:void 0,t:r,e:void 0,x:void 0,r:t};if(void 0!==r.s)r.s.n=t;r.s=t;i.n=t;if(32&r.f)i.S(t);return t;}else if(-1===t.i){t.i=0;if(void 0!==t.n){t.n.p=t.p;if(void 0!==t.p)t.p.n=t.n;t.p=r.s;t.n=void 0;r.s.n=t;r.s=t;}return t;}}}function e(i){this.v=i;this.i=0;this.n=void 0;this.t=void 0;}e.prototype.h=function(){return !0;};e.prototype.S=function(i){if(this.t!==i&&void 0===i.e){i.x=this.t;if(void 0!==this.t)this.t.e=i;this.t=i;}};e.prototype.U=function(i){if(void 0!==this.t){var t=i.e,o=i.x;if(void 0!==t){t.x=o;i.e=void 0;}if(void 0!==o){o.e=t;i.x=void 0;}if(i===this.t)this.t=o;}};e.prototype.subscribe=function(i){var t=this;return b(function(){var o=t.value,r=32&this.f;this.f&=-33;try{i(o);}finally{this.f|=r;}});};e.prototype.valueOf=function(){return this.value;};e.prototype.toString=function(){return this.value+"";};e.prototype.toJSON=function(){return this.value;};e.prototype.peek=function(){return this.v;};Object.defineProperty(e.prototype,"value",{get:function(){var i=v(this);if(void 0!==i)i.i=this.i;return this.v;},set:function(o){if(r instanceof l)!function(){throw new Error("Computed cannot have side-effects");}();if(o!==this.v){if(s>100)i();this.v=o;this.i++;f++;h++;try{for(var n=this.t;void 0!==n;n=n.x)n.t.N();}finally{t();}}}});function u(i){return new e(i);}function c(i){for(var t=i.s;void 0!==t;t=t.n)if(t.S.i!==t.i||!t.S.h()||t.S.i!==t.i)return !0;return !1;}function d(i){for(var t=i.s;void 0!==t;t=t.n){var o=t.S.n;if(void 0!==o)t.r=o;t.S.n=t;t.i=-1;if(void 0===t.n){i.s=t;break;}}}function a(i){var t=i.s,o=void 0;while(void 0!==t){var r=t.p;if(-1===t.i){t.S.U(t);if(void 0!==r)r.n=t.n;if(void 0!==t.n)t.n.p=r;}else o=t;t.S.n=t.r;if(void 0!==t.r)t.r=void 0;t=r;}i.s=o;}function l(i){e.call(this,void 0);this.x=i;this.s=void 0;this.g=f-1;this.f=4;}(l.prototype=new e()).h=function(){this.f&=-3;if(1&this.f)return !1;if(32==(36&this.f))return !0;this.f&=-5;if(this.g===f)return !0;this.g=f;this.f|=1;if(this.i>0&&!c(this)){this.f&=-2;return !0;}var i=r;try{d(this);r=this;var t=this.x();if(16&this.f||this.v!==t||0===this.i){this.v=t;this.f&=-17;this.i++;}}catch(i){this.v=i;this.f|=16;this.i++;}r=i;a(this);this.f&=-2;return !0;};l.prototype.S=function(i){if(void 0===this.t){this.f|=36;for(var t=this.s;void 0!==t;t=t.n)t.S.S(t);}e.prototype.S.call(this,i);};l.prototype.U=function(i){if(void 0!==this.t){e.prototype.U.call(this,i);if(void 0===this.t){this.f&=-33;for(var t=this.s;void 0!==t;t=t.n)t.S.U(t);}}};l.prototype.N=function(){if(!(2&this.f)){this.f|=6;for(var i=this.t;void 0!==i;i=i.x)i.t.N();}};l.prototype.peek=function(){if(!this.h())i();if(16&this.f)throw this.v;return this.v;};Object.defineProperty(l.prototype,"value",{get:function(){if(1&this.f)i();var t=v(this);this.h();if(void 0!==t)t.i=this.i;if(16&this.f)throw this.v;return this.v;}});function y(i){var o=i.u;i.u=void 0;if("function"==typeof o){h++;var n=r;r=void 0;try{o();}catch(t){i.f&=-2;i.f|=8;_(i);throw t;}finally{r=n;t();}}}function _(i){for(var t=i.s;void 0!==t;t=t.n)t.S.U(t);i.x=void 0;i.s=void 0;y(i);}function p(i){if(r!==this)throw new Error("Out-of-order effect");a(this);r=i;this.f&=-2;if(8&this.f)_(this);t();}function g(i){this.x=i;this.u=void 0;this.s=void 0;this.o=void 0;this.f=32;}g.prototype.c=function(){var i=this.S();try{if(8&this.f)return;if(void 0===this.x)return;var t=this.x();if("function"==typeof t)this.u=t;}finally{i();}};g.prototype.S=function(){if(1&this.f)i();this.f|=1;this.f&=-9;y(this);d(this);h++;var t=r;r=this;return p.bind(this,t);};g.prototype.N=function(){if(!(2&this.f)){this.f|=2;this.o=n;n=this;}};g.prototype.d=function(){this.f|=8;if(!(1&this.f))_(this);};function b(i){var t=new g(i);try{t.c();}catch(i){t.d();throw i;}return t.d.bind(t);}
|
680
|
+
|
681
|
+
let LifecycleStatus=/*#__PURE__*/function(LifecycleStatus){LifecycleStatus["Mounted"]="mounted";LifecycleStatus["BrowserCapabilitiesReady"]="browserCapabilitiesReady";LifecycleStatus["Configured"]="configured";LifecycleStatus["PluginsLoading"]="pluginsLoading";LifecycleStatus["PluginsReady"]="pluginsReady";LifecycleStatus["Initialized"]="initialized";LifecycleStatus["Loaded"]="loaded";LifecycleStatus["DestinationsLoading"]="destinationsLoading";LifecycleStatus["DestinationsReady"]="destinationsReady";LifecycleStatus["Ready"]="ready";return LifecycleStatus;}({});
|
682
|
+
|
683
|
+
// TODO: should we take the types from IdentifyTrait instead of any string key?
|
684
|
+
// https://www.rudderstack.com/docs/event-spec/standard-events/identify/#identify-traits
|
685
|
+
/**
|
686
|
+
* Represents the options parameter in the APIs
|
687
|
+
*/let RudderEventType=/*#__PURE__*/function(RudderEventType){RudderEventType["Page"]="page";RudderEventType["Track"]="track";RudderEventType["Identify"]="identify";RudderEventType["Alias"]="alias";RudderEventType["Group"]="group";return RudderEventType;}({});
|
688
|
+
|
582
689
|
const LOG_LEVEL_MAP={[LogLevel.Log]:0,[LogLevel.Info]:1,[LogLevel.Debug]:2,[LogLevel.Warn]:3,[LogLevel.Error]:4,[LogLevel.None]:5};const DEFAULT_LOG_LEVEL=LogLevel.Error;const LOG_MSG_PREFIX='RS SDK';const LOG_MSG_PREFIX_STYLE='font-weight: bold; background: black; color: white;';const LOG_MSG_STYLE='font-weight: normal;';/**
|
583
690
|
* Service to log messages/data to output provider, default is console
|
584
691
|
*/class Logger{constructor(minLogLevel=DEFAULT_LOG_LEVEL,scope='',logProvider=console){this.minLogLevel=LOG_LEVEL_MAP[minLogLevel];this.scope=scope;this.logProvider=logProvider;}log(...data){this.outputLog(LogLevel.Log,data);}info(...data){this.outputLog(LogLevel.Info,data);}debug(...data){this.outputLog(LogLevel.Debug,data);}warn(...data){this.outputLog(LogLevel.Warn,data);}error(...data){this.outputLog(LogLevel.Error,data);}outputLog(logMethod,data){if(this.minLogLevel<=LOG_LEVEL_MAP[logMethod]){this.logProvider[logMethod.toLowerCase()](...this.formatLogData(data));}}setScope(scopeVal){this.scope=scopeVal||this.scope;}// TODO: should we allow to change the level via global variable on run time
|
@@ -595,40 +702,29 @@ LOG_MSG_STYLE// reset the style for the actual message
|
|
595
702
|
if(!isString(data[0])){styledLogArgs.push(data[0]);}// append rest of the original arguments
|
596
703
|
styledLogArgs.push(...data.slice(1));return styledLogArgs;}return data;}}const defaultLogger=new Logger();
|
597
704
|
|
598
|
-
|
599
|
-
|
600
|
-
const LOG_CONTEXT_SEPARATOR=':: ';const SCRIPT_ALREADY_EXISTS_ERROR=id=>`A script with the id "${id}" is already loaded. Skipping the loading of this script to prevent conflicts.`;const SCRIPT_LOAD_ERROR=(id,url)=>`Failed to load the script with the id "${id}" from URL "${url}".`;const SCRIPT_LOAD_TIMEOUT_ERROR=(id,url,timeout)=>`A timeout of ${timeout} ms occurred while trying to load the script with id "${id}" from URL "${url}".`;const CIRCULAR_REFERENCE_WARNING=(context,key)=>`${context}${LOG_CONTEXT_SEPARATOR}A circular reference has been detected in the object and the property "${key}" has been dropped from the output.`;const JSON_STRINGIFY_WARNING=`Failed to convert the value to a JSON string.`;
|
705
|
+
let StorageEncryptionVersion=/*#__PURE__*/function(StorageEncryptionVersion){StorageEncryptionVersion["Legacy"]="legacy";StorageEncryptionVersion["V3"]="v3";return StorageEncryptionVersion;}({});// default
|
706
|
+
const SUPPORTED_STORAGE_TYPES=['localStorage','memoryStorage','cookieStorage','sessionStorage','none'];const DEFAULT_STORAGE_TYPE='cookieStorage';
|
601
707
|
|
602
708
|
const SOURCE_CONFIG_OPTION_ERROR=`"getSourceConfig" must be a function. Please make sure that it is defined and returns a valid source configuration object.`;const INTG_CDN_BASE_URL_ERROR=`Failed to load the SDK as the CDN base URL for integrations is not valid.`;const PLUGINS_CDN_BASE_URL_ERROR=`Failed to load the SDK as the CDN base URL for plugins is not valid.`;const DATA_PLANE_URL_ERROR=`Failed to load the SDK as the data plane URL could not be determined. Please check that the data plane URL is set correctly and try again.`;const XHR_PAYLOAD_PREP_ERROR=`Failed to prepare data for the request.`;const EVENT_OBJECT_GENERATION_ERROR=`Failed to generate the event object.`;const PLUGIN_EXT_POINT_MISSING_ERROR=`Failed to invoke plugin because the extension point name is missing.`;const PLUGIN_EXT_POINT_INVALID_ERROR=`Failed to invoke plugin because the extension point name is invalid.`;// ERROR
|
603
709
|
const UNSUPPORTED_CONSENT_MANAGER_ERROR=(context,selectedConsentManager,consentManagersToPluginNameMap)=>`${context}${LOG_CONTEXT_SEPARATOR}The consent manager "${selectedConsentManager}" is not supported. Please choose one of the following supported consent managers: "${Object.keys(consentManagersToPluginNameMap)}".`;const REPORTING_PLUGIN_INIT_FAILURE_ERROR=context=>`${context}${LOG_CONTEXT_SEPARATOR}Failed to initialize the error reporting plugin.`;const NOTIFY_FAILURE_ERROR=context=>`${context}${LOG_CONTEXT_SEPARATOR}Failed to notify the error.`;const PLUGIN_NAME_MISSING_ERROR=context=>`${context}${LOG_CONTEXT_SEPARATOR}Plugin name is missing.`;const PLUGIN_ALREADY_EXISTS_ERROR=(context,pluginName)=>`${context}${LOG_CONTEXT_SEPARATOR}Plugin "${pluginName}" already exists.`;const PLUGIN_NOT_FOUND_ERROR=(context,pluginName)=>`${context}${LOG_CONTEXT_SEPARATOR}Plugin "${pluginName}" not found.`;const PLUGIN_ENGINE_BUG_ERROR=(context,pluginName)=>`${context}${LOG_CONTEXT_SEPARATOR}Plugin "${pluginName}" not found in plugins but found in byName. This indicates a bug in the plugin engine. Please report this issue to the development team.`;const PLUGIN_DEPS_ERROR=(context,pluginName,notExistDeps)=>`${context}${LOG_CONTEXT_SEPARATOR}Plugin "${pluginName}" could not be loaded because some of its dependencies "${notExistDeps}" do not exist.`;const PLUGIN_INVOCATION_ERROR=(context,extPoint,pluginName)=>`${context}${LOG_CONTEXT_SEPARATOR}Failed to invoke the "${extPoint}" extension point of plugin "${pluginName}".`;const STORAGE_UNAVAILABILITY_ERROR_PREFIX=(context,storageType)=>`${context}${LOG_CONTEXT_SEPARATOR}The "${storageType}" storage type is `;const SOURCE_CONFIG_FETCH_ERROR=reason=>`Failed to fetch the source config. Reason: ${reason}`;const WRITE_KEY_VALIDATION_ERROR=writeKey=>`The write key "${writeKey}" is invalid. It must be a non-empty string. Please check that the write key is correct and try again.`;const DATA_PLANE_URL_VALIDATION_ERROR=dataPlaneUrl=>`The data plane URL "${dataPlaneUrl}" is invalid. It must be a valid URL string. Please check that the data plane URL is correct and try again.`;const READY_API_CALLBACK_ERROR=context=>`${context}${LOG_CONTEXT_SEPARATOR}The callback is not a function.`;const XHR_DELIVERY_ERROR=(prefix,status,statusText,url)=>`${prefix} with status: ${status}, ${statusText} for URL: ${url}.`;const XHR_REQUEST_ERROR=(prefix,e,url)=>`${prefix} due to timeout or no connection (${e?e.type:''}) for URL: ${url}.`;const XHR_SEND_ERROR=(prefix,url)=>`${prefix} for URL: ${url}`;const STORE_DATA_SAVE_ERROR=key=>`Failed to save the value for "${key}" to storage`;const STORE_DATA_FETCH_ERROR=key=>`Failed to retrieve or parse data for "${key}" from storage`;// WARNING
|
604
|
-
const UNSUPPORTED_ERROR_REPORTING_PROVIDER_WARNING=(context,selectedErrorReportingProvider,errorReportingProvidersToPluginNameMap,defaultProvider)=>`${context}${LOG_CONTEXT_SEPARATOR}The error reporting provider "${selectedErrorReportingProvider}" is not supported. Please choose one of the following supported providers: "${Object.keys(errorReportingProvidersToPluginNameMap)}". The default provider "${defaultProvider}" will be used instead.`;const UNSUPPORTED_STORAGE_ENCRYPTION_VERSION_WARNING=(context,selectedStorageEncryptionVersion,storageEncryptionVersionsToPluginNameMap,defaultVersion)=>`${context}${LOG_CONTEXT_SEPARATOR}The storage encryption version "${selectedStorageEncryptionVersion}" is not supported. Please choose one of the following supported versions: "${Object.keys(storageEncryptionVersionsToPluginNameMap)}". The default version "${defaultVersion}" will be used instead.`;const STORAGE_DATA_MIGRATION_OVERRIDE_WARNING=(context,storageEncryptionVersion,defaultVersion)=>`${context}${LOG_CONTEXT_SEPARATOR}The storage data migration has been disabled because the configured storage encryption version (${storageEncryptionVersion}) is not the latest (${defaultVersion}). To enable storage data migration, please update the storage encryption version to the latest version.`;const UNSUPPORTED_RESIDENCY_SERVER_REGION_WARNING=(context,selectedResidencyServerRegion,defaultRegion)=>`${context}${LOG_CONTEXT_SEPARATOR}The residency server region "${selectedResidencyServerRegion}" is not supported. Please choose one of the following supported regions: "${Object.values(ResidencyServerRegion)}". The default region "${defaultRegion}" will be used instead.`;const RESERVED_KEYWORD_WARNING=(context,property,parentKeyPath,reservedElements)=>`${context}${LOG_CONTEXT_SEPARATOR}The "${property}" property defined under "${parentKeyPath}" is a reserved keyword. Please choose a different property name to avoid conflicts with reserved keywords (${reservedElements}).`;const INVALID_CONTEXT_OBJECT_WARNING=logContext=>`${logContext}${LOG_CONTEXT_SEPARATOR}Please make sure that the "context" property in the event API's "options" argument is a valid object literal with key-value pairs.`;const UNSUPPORTED_BEACON_API_WARNING=context=>`${context}${LOG_CONTEXT_SEPARATOR}The Beacon API is not supported by your browser. The events will be sent using XHR instead.`;const TIMEOUT_NOT_NUMBER_WARNING=(context,timeout,defaultValue)=>`${context}${LOG_CONTEXT_SEPARATOR}The session timeout value "${timeout}" is not a number. The default timeout of ${defaultValue} ms will be used instead.`;const TIMEOUT_ZERO_WARNING=context=>`${context}${LOG_CONTEXT_SEPARATOR}The session timeout value is 0, which disables the automatic session tracking feature. If you want to enable session tracking, please provide a positive integer value for the timeout.`;const TIMEOUT_NOT_RECOMMENDED_WARNING=(context,timeout,minTimeout)=>`${context}${LOG_CONTEXT_SEPARATOR}The session timeout value ${timeout} ms is less than the recommended minimum of ${minTimeout} ms. Please consider increasing the timeout value to ensure optimal performance and reliability.`;const INVALID_SESSION_ID_WARNING=(context,sessionId,minSessionIdLength)=>`${context}${LOG_CONTEXT_SEPARATOR}The provided session ID (${sessionId}) is either invalid, not a positive integer, or not at least "${minSessionIdLength}" digits long. A new session ID will be auto-generated instead.`;const STORAGE_QUOTA_EXCEEDED_WARNING=context=>`${context}${LOG_CONTEXT_SEPARATOR}The storage is either full or unavailable, so the data will not be persisted. Switching to in-memory storage.`;const
|
710
|
+
const STORAGE_TYPE_VALIDATION_WARNING=(context,storageType,defaultStorageType)=>`${context}${LOG_CONTEXT_SEPARATOR}The storage type "${storageType}" is not supported. Please choose one of the following supported storage types: "${SUPPORTED_STORAGE_TYPES}". The default storage "${defaultStorageType}" will be used instead.`;const UNSUPPORTED_ERROR_REPORTING_PROVIDER_WARNING=(context,selectedErrorReportingProvider,errorReportingProvidersToPluginNameMap,defaultProvider)=>`${context}${LOG_CONTEXT_SEPARATOR}The error reporting provider "${selectedErrorReportingProvider}" is not supported. Please choose one of the following supported providers: "${Object.keys(errorReportingProvidersToPluginNameMap)}". The default provider "${defaultProvider}" will be used instead.`;const UNSUPPORTED_STORAGE_ENCRYPTION_VERSION_WARNING=(context,selectedStorageEncryptionVersion,storageEncryptionVersionsToPluginNameMap,defaultVersion)=>`${context}${LOG_CONTEXT_SEPARATOR}The storage encryption version "${selectedStorageEncryptionVersion}" is not supported. Please choose one of the following supported versions: "${Object.keys(storageEncryptionVersionsToPluginNameMap)}". The default version "${defaultVersion}" will be used instead.`;const STORAGE_DATA_MIGRATION_OVERRIDE_WARNING=(context,storageEncryptionVersion,defaultVersion)=>`${context}${LOG_CONTEXT_SEPARATOR}The storage data migration has been disabled because the configured storage encryption version (${storageEncryptionVersion}) is not the latest (${defaultVersion}). To enable storage data migration, please update the storage encryption version to the latest version.`;const UNSUPPORTED_RESIDENCY_SERVER_REGION_WARNING=(context,selectedResidencyServerRegion,defaultRegion)=>`${context}${LOG_CONTEXT_SEPARATOR}The residency server region "${selectedResidencyServerRegion}" is not supported. Please choose one of the following supported regions: "${Object.values(ResidencyServerRegion)}". The default region "${defaultRegion}" will be used instead.`;const RESERVED_KEYWORD_WARNING=(context,property,parentKeyPath,reservedElements)=>`${context}${LOG_CONTEXT_SEPARATOR}The "${property}" property defined under "${parentKeyPath}" is a reserved keyword. Please choose a different property name to avoid conflicts with reserved keywords (${reservedElements}).`;const INVALID_CONTEXT_OBJECT_WARNING=logContext=>`${logContext}${LOG_CONTEXT_SEPARATOR}Please make sure that the "context" property in the event API's "options" argument is a valid object literal with key-value pairs.`;const UNSUPPORTED_BEACON_API_WARNING=context=>`${context}${LOG_CONTEXT_SEPARATOR}The Beacon API is not supported by your browser. The events will be sent using XHR instead.`;const TIMEOUT_NOT_NUMBER_WARNING=(context,timeout,defaultValue)=>`${context}${LOG_CONTEXT_SEPARATOR}The session timeout value "${timeout}" is not a number. The default timeout of ${defaultValue} ms will be used instead.`;const TIMEOUT_ZERO_WARNING=context=>`${context}${LOG_CONTEXT_SEPARATOR}The session timeout value is 0, which disables the automatic session tracking feature. If you want to enable session tracking, please provide a positive integer value for the timeout.`;const TIMEOUT_NOT_RECOMMENDED_WARNING=(context,timeout,minTimeout)=>`${context}${LOG_CONTEXT_SEPARATOR}The session timeout value ${timeout} ms is less than the recommended minimum of ${minTimeout} ms. Please consider increasing the timeout value to ensure optimal performance and reliability.`;const INVALID_SESSION_ID_WARNING=(context,sessionId,minSessionIdLength)=>`${context}${LOG_CONTEXT_SEPARATOR}The provided session ID (${sessionId}) is either invalid, not a positive integer, or not at least "${minSessionIdLength}" digits long. A new session ID will be auto-generated instead.`;const STORAGE_QUOTA_EXCEEDED_WARNING=context=>`${context}${LOG_CONTEXT_SEPARATOR}The storage is either full or unavailable, so the data will not be persisted. Switching to in-memory storage.`;const STORAGE_UNAVAILABLE_WARNING=(context,selectedStorageType,finalStorageType)=>`${context}${LOG_CONTEXT_SEPARATOR}The storage type "${selectedStorageType}" is not available. The SDK will be initialized with "${finalStorageType}" instead.`;const WRITE_KEY_NOT_A_STRING_ERROR=(context,writeKey)=>`${context}${LOG_CONTEXT_SEPARATOR}The write key "${writeKey}" is not a string. Please check that the write key is correct and try again.`;const EMPTY_GROUP_CALL_ERROR=context=>`${context}${LOG_CONTEXT_SEPARATOR}The group() method must be called with at least one argument.`;const READY_CALLBACK_INVOKE_ERROR=`Failed to invoke the ready callback`;const API_CALLBACK_INVOKE_ERROR=`API Callback Invocation Failed`;const INVALID_CONFIG_URL_WARNING=(context,configUrl)=>`${context}${LOG_CONTEXT_SEPARATOR}The provided config URL "${configUrl}" is invalid. Using the default value instead.`;// DEBUG
|
605
711
|
|
606
|
-
|
607
|
-
|
608
|
-
|
609
|
-
|
610
|
-
const
|
611
|
-
// do some unified pre-process before application starts.
|
612
|
-
processRawPlugins(callback){callback(this.plugins);this.cache={};}invoke(extPoint,allowMultiple=true,...args){let extensionPointName=extPoint;if(!extensionPointName){throw new Error(PLUGIN_EXT_POINT_MISSING_ERROR);}const noCall=extensionPointName.startsWith('!');const throws=this.config.throws??extensionPointName.endsWith('!');// eslint-disable-next-line unicorn/better-regex
|
613
|
-
extensionPointName=extensionPointName.replace(/(^!|!$)/g,'');if(!extensionPointName){throw new Error(PLUGIN_EXT_POINT_INVALID_ERROR);}const extensionPointNameParts=extensionPointName.split('.');extensionPointNameParts.pop();const pluginMethodPath=extensionPointNameParts.join('.');const pluginsToInvoke=allowMultiple?this.getPlugins(extensionPointName):[this.getPlugins(extensionPointName)[0]];return pluginsToInvoke.map(plugin=>{const method=getValueByPath(plugin,extensionPointName);if(!isFunction(method)||noCall){return method;}try{return method.apply(getValueByPath(plugin,pluginMethodPath),args);}catch(err){// When a plugin failed, doesn't break the app
|
614
|
-
if(throws){throw err;}else {this.logger?.error(PLUGIN_INVOCATION_ERROR(PLUGIN_ENGINE,extensionPointName,plugin.name),err);}}return null;});}invokeSingle(extPoint,...args){return this.invoke(extPoint,false,...args)[0];}invokeMultiple(extPoint,...args){return this.invoke(extPoint,true,...args);}}const defaultPluginEngine=new PluginEngine({throws:true},defaultLogger);
|
615
|
-
|
616
|
-
function i(){throw new Error("Cycle detected");}function t(){if(!(h>1)){var i,t=!1;while(void 0!==n){var o=n;n=void 0;s++;while(void 0!==o){var r=o.o;o.o=void 0;o.f&=-3;if(!(8&o.f)&&c(o))try{o.c();}catch(o){if(!t){i=o;t=!0;}}o=r;}}s=0;h--;if(t)throw i;}else h--;}function o(i){if(h>0)return i();h++;try{return i();}finally{t();}}var r=void 0,n=void 0,h=0,s=0,f=0;function v(i){if(void 0!==r){var t=i.n;if(void 0===t||t.t!==r){t={i:0,S:i,p:r.s,n:void 0,t:r,e:void 0,x:void 0,r:t};if(void 0!==r.s)r.s.n=t;r.s=t;i.n=t;if(32&r.f)i.S(t);return t;}else if(-1===t.i){t.i=0;if(void 0!==t.n){t.n.p=t.p;if(void 0!==t.p)t.p.n=t.n;t.p=r.s;t.n=void 0;r.s.n=t;r.s=t;}return t;}}}function e(i){this.v=i;this.i=0;this.n=void 0;this.t=void 0;}e.prototype.h=function(){return !0;};e.prototype.S=function(i){if(this.t!==i&&void 0===i.e){i.x=this.t;if(void 0!==this.t)this.t.e=i;this.t=i;}};e.prototype.U=function(i){if(void 0!==this.t){var t=i.e,o=i.x;if(void 0!==t){t.x=o;i.e=void 0;}if(void 0!==o){o.e=t;i.x=void 0;}if(i===this.t)this.t=o;}};e.prototype.subscribe=function(i){var t=this;return b(function(){var o=t.value,r=32&this.f;this.f&=-33;try{i(o);}finally{this.f|=r;}});};e.prototype.valueOf=function(){return this.value;};e.prototype.toString=function(){return this.value+"";};e.prototype.toJSON=function(){return this.value;};e.prototype.peek=function(){return this.v;};Object.defineProperty(e.prototype,"value",{get:function(){var i=v(this);if(void 0!==i)i.i=this.i;return this.v;},set:function(o){if(r instanceof l)!function(){throw new Error("Computed cannot have side-effects");}();if(o!==this.v){if(s>100)i();this.v=o;this.i++;f++;h++;try{for(var n=this.t;void 0!==n;n=n.x)n.t.N();}finally{t();}}}});function u(i){return new e(i);}function c(i){for(var t=i.s;void 0!==t;t=t.n)if(t.S.i!==t.i||!t.S.h()||t.S.i!==t.i)return !0;return !1;}function d(i){for(var t=i.s;void 0!==t;t=t.n){var o=t.S.n;if(void 0!==o)t.r=o;t.S.n=t;t.i=-1;if(void 0===t.n){i.s=t;break;}}}function a(i){var t=i.s,o=void 0;while(void 0!==t){var r=t.p;if(-1===t.i){t.S.U(t);if(void 0!==r)r.n=t.n;if(void 0!==t.n)t.n.p=r;}else o=t;t.S.n=t.r;if(void 0!==t.r)t.r=void 0;t=r;}i.s=o;}function l(i){e.call(this,void 0);this.x=i;this.s=void 0;this.g=f-1;this.f=4;}(l.prototype=new e()).h=function(){this.f&=-3;if(1&this.f)return !1;if(32==(36&this.f))return !0;this.f&=-5;if(this.g===f)return !0;this.g=f;this.f|=1;if(this.i>0&&!c(this)){this.f&=-2;return !0;}var i=r;try{d(this);r=this;var t=this.x();if(16&this.f||this.v!==t||0===this.i){this.v=t;this.f&=-17;this.i++;}}catch(i){this.v=i;this.f|=16;this.i++;}r=i;a(this);this.f&=-2;return !0;};l.prototype.S=function(i){if(void 0===this.t){this.f|=36;for(var t=this.s;void 0!==t;t=t.n)t.S.S(t);}e.prototype.S.call(this,i);};l.prototype.U=function(i){if(void 0!==this.t){e.prototype.U.call(this,i);if(void 0===this.t){this.f&=-33;for(var t=this.s;void 0!==t;t=t.n)t.S.U(t);}}};l.prototype.N=function(){if(!(2&this.f)){this.f|=6;for(var i=this.t;void 0!==i;i=i.x)i.t.N();}};l.prototype.peek=function(){if(!this.h())i();if(16&this.f)throw this.v;return this.v;};Object.defineProperty(l.prototype,"value",{get:function(){if(1&this.f)i();var t=v(this);this.h();if(void 0!==t)t.i=this.i;if(16&this.f)throw this.v;return this.v;}});function y(i){var o=i.u;i.u=void 0;if("function"==typeof o){h++;var n=r;r=void 0;try{o();}catch(t){i.f&=-2;i.f|=8;_(i);throw t;}finally{r=n;t();}}}function _(i){for(var t=i.s;void 0!==t;t=t.n)t.S.U(t);i.x=void 0;i.s=void 0;y(i);}function p(i){if(r!==this)throw new Error("Out-of-order effect");a(this);r=i;this.f&=-2;if(8&this.f)_(this);t();}function g(i){this.x=i;this.u=void 0;this.s=void 0;this.o=void 0;this.f=32;}g.prototype.c=function(){var i=this.S();try{if(8&this.f)return;if(void 0===this.x)return;var t=this.x();if("function"==typeof t)this.u=t;}finally{i();}};g.prototype.S=function(){if(1&this.f)i();this.f|=1;this.f&=-9;y(this);d(this);h++;var t=r;r=this;return p.bind(this,t);};g.prototype.N=function(){if(!(2&this.f)){this.f|=2;this.o=n;n=this;}};g.prototype.d=function(){this.f|=8;if(!(1&this.f))_(this);};function b(i){var t=new g(i);try{t.c();}catch(i){t.d();throw i;}return t.d.bind(t);}
|
617
|
-
|
618
|
-
const BUILD_TYPE='modern';const SDK_CDN_BASE_URL='https://cdn.rudderlabs.com';const CDN_ARCH_VERSION_DIR='v3';const CDN_INT_DIR='js-integrations';const CDN_PLUGINS_DIR='plugins';const DEST_SDK_BASE_URL=`${SDK_CDN_BASE_URL}/${CDN_ARCH_VERSION_DIR}/latest/${BUILD_TYPE}/${CDN_INT_DIR}`;const PLUGINS_BASE_URL=`${SDK_CDN_BASE_URL}/${CDN_ARCH_VERSION_DIR}/latest/${BUILD_TYPE}/${CDN_PLUGINS_DIR}`;const DEFAULT_CONFIG_BE_URL='https://api.rudderstack.com';
|
712
|
+
const DEFAULT_XHR_TIMEOUT_MS=10*1000;// 10 seconds
|
713
|
+
const DEFAULT_COOKIE_MAX_AGE_MS=31536000*1000;// 1 year
|
714
|
+
const DEFAULT_SESSION_TIMEOUT_MS=30*60*1000;// 30 minutes
|
715
|
+
const MIN_SESSION_TIMEOUT_MS=10*1000;// 10 seconds
|
716
|
+
const DEFAULT_DATA_PLANE_EVENTS_BUFFER_TIMEOUT_MS=10*1000;// 10 seconds
|
619
717
|
|
620
|
-
const
|
621
|
-
const
|
622
|
-
const
|
623
|
-
const
|
624
|
-
|
625
|
-
let StorageEncryptionVersion=/*#__PURE__*/function(StorageEncryptionVersion){StorageEncryptionVersion["Legacy"]="legacy";StorageEncryptionVersion["V3"]="v3";return StorageEncryptionVersion;}({});// default
|
718
|
+
const BUILD_TYPE='modern';const SDK_CDN_BASE_URL='https://cdn.rudderlabs.com';const CDN_ARCH_VERSION_DIR='v3';const CDN_INT_DIR='js-integrations';const CDN_PLUGINS_DIR='plugins';const DEST_SDK_BASE_URL=`${SDK_CDN_BASE_URL}/beta/3.0.0-beta/${BUILD_TYPE}/${CDN_INT_DIR}`;const PLUGINS_BASE_URL=`${SDK_CDN_BASE_URL}/beta/3.0.0-beta/${BUILD_TYPE}/${CDN_PLUGINS_DIR}`;// TODO: change the above to production URLs when beta phase is done
|
719
|
+
// const DEST_SDK_BASE_URL = `${SDK_CDN_BASE_URL}/latest/${CDN_ARCH_VERSION_DIR}/${BUILD_TYPE}/${CDN_INT_DIR}`;
|
720
|
+
// const PLUGINS_BASE_URL = `${SDK_CDN_BASE_URL}/latest/${CDN_ARCH_VERSION_DIR}/${BUILD_TYPE}/${CDN_PLUGINS_DIR}`;
|
721
|
+
const DEFAULT_CONFIG_BE_URL='https://api.rudderstack.com';
|
626
722
|
|
627
723
|
const DEFAULT_ERROR_REPORTING_PROVIDER='bugsnag';const DEFAULT_STORAGE_ENCRYPTION_VERSION=StorageEncryptionVersion.V3;const ConsentManagersToPluginNameMap={oneTrust:PluginName.OneTrustConsentManager,ketch:PluginName.KetchConsentManager};const ErrorReportingProvidersToPluginNameMap={[DEFAULT_ERROR_REPORTING_PROVIDER]:PluginName.Bugsnag};const StorageEncryptionVersionsToPluginNameMap={[DEFAULT_STORAGE_ENCRYPTION_VERSION]:PluginName.StorageEncryption,[StorageEncryptionVersion.Legacy]:PluginName.StorageEncryptionLegacy};
|
628
724
|
|
629
|
-
const defaultLoadOptions={logLevel:LogLevel.Error,configUrl:DEFAULT_CONFIG_BE_URL,loadIntegration:true,sessions:{autoTrack:true,timeout:
|
725
|
+
const defaultLoadOptions={logLevel:LogLevel.Error,configUrl:DEFAULT_CONFIG_BE_URL,loadIntegration:true,sessions:{autoTrack:true,timeout:DEFAULT_SESSION_TIMEOUT_MS},sameSiteCookie:CookieSameSite.Lax,polyfillIfRequired:true,integrations:{All:true},useBeacon:false,beaconQueueOptions:{},destinationsQueueOptions:{},queueOptions:{},lockIntegrationsVersion:false,uaChTrackLevel:UaChTrackLevel.None,plugins:[],useGlobalIntegrationsConfigInEvents:false,bufferDataPlaneEventsUntilReady:false,dataPlaneEventsBufferTimeout:DEFAULT_DATA_PLANE_EVENTS_BUFFER_TIMEOUT_MS,storage:{encryption:{version:DEFAULT_STORAGE_ENCRYPTION_VERSION},migrate:false},sendAdblockPageOptions:{}};const loadOptionsState=u(clone$1(defaultLoadOptions));
|
630
726
|
|
631
|
-
const defaultSessionInfo={autoTrack:true,timeout:
|
727
|
+
const defaultSessionInfo={autoTrack:true,timeout:DEFAULT_SESSION_TIMEOUT_MS};const sessionState={userId:u(undefined),userTraits:u(undefined),anonymousUserId:u(undefined),groupId:u(undefined),groupTraits:u(undefined),initialReferrer:u(undefined),initialReferringDomain:u(undefined),sessionInfo:u({...defaultSessionInfo})};
|
632
728
|
|
633
729
|
const capabilitiesState={isOnline:u(true),storage:{isLocalStorageAvailable:u(false),isCookieStorageAvailable:u(false),isSessionStorageAvailable:u(false)},isBeaconAvailable:u(false),isLegacyDOM:u(false),isUaCHAvailable:u(false),isCryptoAvailable:u(false),isIE11:u(false),isAdBlocked:u(false)};
|
634
730
|
|
@@ -652,23 +748,19 @@ const pluginsState={ready:u(false),loadedPlugins:u([]),failedPlugins:u([]),plugi
|
|
652
748
|
|
653
749
|
const pagePropertiesState={path:u(''),referrer:u(''),referring_domain:u(''),search:u(''),title:u(''),url:u(''),tab_url:u('')};
|
654
750
|
|
655
|
-
const storageState={encryptionPluginName:u(undefined),migrate:u(false)};
|
751
|
+
const storageState={encryptionPluginName:u(undefined),migrate:u(false),type:u(undefined)};
|
656
752
|
|
657
753
|
const defaultStateValues={capabilities:capabilitiesState,consents:consentsState,context:contextState,eventBuffer:eventBufferState,lifecycle:lifecycleState,loadOptions:loadOptionsState,metrics:metricsState,nativeDestinations:nativeDestinationsState,plugins:pluginsState,reporting:reportingState,session:sessionState,source:sourceConfigState,page:pagePropertiesState,storage:storageState};const state={...clone$1(defaultStateValues)};
|
658
754
|
|
659
|
-
|
660
|
-
//
|
661
|
-
|
662
|
-
//
|
663
|
-
//
|
664
|
-
|
665
|
-
|
666
|
-
|
667
|
-
|
668
|
-
* @param {boolean} excludeNull if it should exclude nul or not
|
669
|
-
* @param {function} logger optional logger methods for warning
|
670
|
-
* @returns string
|
671
|
-
*/const stringifyWithoutCircular=(value,excludeNull,excludeKeys,logger)=>{try{return JSON.stringify(value,getCircularReplacer(excludeNull,excludeKeys,logger));}catch(err){logger?.warn(JSON_STRINGIFY_WARNING,err);return null;}};
|
755
|
+
// to next or return the value if it is the last one instead of an array per
|
756
|
+
// plugin that is the normal invoke
|
757
|
+
// TODO: add invoke method for extension point that we know only one plugin can be used. add invokeMultiple and invokeSingle methods
|
758
|
+
class PluginEngine{plugins=[];byName={};cache={};config={throws:true};constructor(options={},logger){this.config={throws:true,...options};this.logger=logger;}register(plugin,state){if(!plugin.name){const errorMessage=PLUGIN_NAME_MISSING_ERROR(PLUGIN_ENGINE);if(this.config.throws){throw new Error(errorMessage);}else {this.logger?.error(errorMessage,plugin);}}if(this.byName[plugin.name]){const errorMessage=PLUGIN_ALREADY_EXISTS_ERROR(PLUGIN_ENGINE,plugin.name);if(this.config.throws){throw new Error(errorMessage);}else {this.logger?.error(errorMessage);}}this.cache={};this.plugins=this.plugins.slice();let pos=this.plugins.length;this.plugins.forEach((pluginItem,index)=>{if(pluginItem.deps?.includes(plugin.name)){pos=Math.min(pos,index);}});this.plugins.splice(pos,0,plugin);this.byName[plugin.name]=plugin;if(plugin.initialize&&isFunction(plugin.initialize)){plugin.initialize(state);}}unregister(name){const plugin=this.byName[name];if(!plugin){const errorMessage=PLUGIN_NOT_FOUND_ERROR(PLUGIN_ENGINE,name);if(this.config.throws){throw new Error(errorMessage);}else {this.logger?.error(errorMessage);}}const index=this.plugins.indexOf(plugin);if(index===-1){const errorMessage=PLUGIN_ENGINE_BUG_ERROR(PLUGIN_ENGINE,name);if(this.config.throws){throw new Error(errorMessage);}else {this.logger?.error(errorMessage);}}this.cache={};delete this.byName[name];this.plugins=this.plugins.slice();this.plugins.splice(index,1);}getPlugin(name){return this.byName[name];}getPlugins(extPoint){const lifeCycleName=extPoint??'.';if(!this.cache[lifeCycleName]){this.cache[lifeCycleName]=this.plugins.filter(plugin=>{if(plugin.deps?.some(dependency=>!this.byName[dependency])){// If deps not exist, then not load it.
|
759
|
+
const notExistDeps=plugin.deps.filter(dependency=>!this.byName[dependency]);this.logger?.error(PLUGIN_DEPS_ERROR(PLUGIN_ENGINE,plugin.name,notExistDeps));return false;}return lifeCycleName==='.'?true:hasValueByPath(plugin,lifeCycleName);});}return this.cache[lifeCycleName];}// This method allows to process this.plugins so that it could
|
760
|
+
// do some unified pre-process before application starts.
|
761
|
+
processRawPlugins(callback){callback(this.plugins);this.cache={};}invoke(extPoint,allowMultiple=true,...args){let extensionPointName=extPoint;if(!extensionPointName){throw new Error(PLUGIN_EXT_POINT_MISSING_ERROR);}const noCall=extensionPointName.startsWith('!');const throws=this.config.throws??extensionPointName.endsWith('!');// eslint-disable-next-line unicorn/better-regex
|
762
|
+
extensionPointName=extensionPointName.replace(/(^!|!$)/g,'');if(!extensionPointName){throw new Error(PLUGIN_EXT_POINT_INVALID_ERROR);}const extensionPointNameParts=extensionPointName.split('.');extensionPointNameParts.pop();const pluginMethodPath=extensionPointNameParts.join('.');const pluginsToInvoke=allowMultiple?this.getPlugins(extensionPointName):[this.getPlugins(extensionPointName)[0]];return pluginsToInvoke.map(plugin=>{const method=getValueByPath(plugin,extensionPointName);if(!isFunction(method)||noCall){return method;}try{return method.apply(getValueByPath(plugin,pluginMethodPath),args);}catch(err){// When a plugin failed, doesn't break the app
|
763
|
+
if(throws){throw err;}else {this.logger?.error(PLUGIN_INVOCATION_ERROR(PLUGIN_ENGINE,extensionPointName,plugin.name),err);}}return null;});}invokeSingle(extPoint,...args){return this.invoke(extPoint,false,...args)[0];}invokeMultiple(extPoint,...args){return this.invoke(extPoint,true,...args);}}const defaultPluginEngine=new PluginEngine({throws:true},defaultLogger);
|
672
764
|
|
673
765
|
const FAILED_REQUEST_ERR_MSG_PREFIX='The request failed';const ERROR_MESSAGES_TO_BE_FILTERED=[FAILED_REQUEST_ERR_MSG_PREFIX];
|
674
766
|
|
@@ -691,7 +783,7 @@ if(isTypeOfError(error)){normalizedError.message=errorMessage;}else {normalizedE
|
|
691
783
|
* occurred and send to external error monitoring service via a plugin
|
692
784
|
*
|
693
785
|
* @param {string} breadcrumb breadcrumbs message
|
694
|
-
*/leaveBreadcrumb(breadcrumb){if(this.pluginEngine){try{this.pluginEngine.invokeSingle('errorReporting.breadcrumb',this.pluginEngine,this.errReportingClient,breadcrumb,this.logger);}catch(err){this.onError(err,'errorReporting.breadcrumb');}}}/**
|
786
|
+
*/leaveBreadcrumb(breadcrumb){if(this.pluginEngine){try{this.pluginEngine.invokeSingle('errorReporting.breadcrumb',this.pluginEngine,this.errReportingClient,breadcrumb,this.logger);}catch(err){this.onError(err,ERROR_HANDLER,'errorReporting.breadcrumb');}}}/**
|
695
787
|
* Send handled errors to external error monitoring service via a plugin
|
696
788
|
*
|
697
789
|
* @param {Error} error Error instance from handled error
|
@@ -713,14 +805,12 @@ destination.config.useNativeSDK===true);const isHybridModeDestination=destinatio
|
|
713
805
|
* @returns destinations
|
714
806
|
*/const getNonCloudDestinations=destinations=>destinations.filter(isNonCloudDestination);
|
715
807
|
|
716
|
-
let LifecycleStatus=/*#__PURE__*/function(LifecycleStatus){LifecycleStatus["Mounted"]="mounted";LifecycleStatus["BrowserCapabilitiesReady"]="browserCapabilitiesReady";LifecycleStatus["Configured"]="configured";LifecycleStatus["PluginsLoading"]="pluginsLoading";LifecycleStatus["PluginsReady"]="pluginsReady";LifecycleStatus["Initialized"]="initialized";LifecycleStatus["Loaded"]="loaded";LifecycleStatus["DestinationsLoading"]="destinationsLoading";LifecycleStatus["DestinationsReady"]="destinationsReady";LifecycleStatus["Ready"]="ready";return LifecycleStatus;}({});
|
717
|
-
|
718
808
|
/**
|
719
809
|
* List of plugin names that are loaded as dynamic imports in modern builds
|
720
810
|
*/const remotePluginNames=[PluginName.BeaconQueue,PluginName.DeviceModeTransformation,PluginName.DeviceModeDestinations,PluginName.ErrorReporting,PluginName.ExternalAnonymousId,PluginName.GoogleLinker,PluginName.NativeDestinationQueue,PluginName.StorageEncryption,PluginName.StorageEncryptionLegacy,PluginName.StorageMigrator,PluginName.XhrQueue,PluginName.OneTrustConsentManager,PluginName.KetchConsentManager,PluginName.Bugsnag];
|
721
811
|
|
722
812
|
const remotesMap = {
|
723
|
-
'rudderAnalyticsRemotePlugins':{url:()=>Promise.resolve(window.RudderStackGlobals && window.RudderStackGlobals.app && window.RudderStackGlobals.app.pluginsCDNPath ? "" + window.RudderStackGlobals.app.pluginsCDNPath + "/rsa-plugins.js" : "
|
813
|
+
'rudderAnalyticsRemotePlugins':{url:()=>Promise.resolve(window.RudderStackGlobals && window.RudderStackGlobals.app && window.RudderStackGlobals.app.pluginsCDNPath ? "" + window.RudderStackGlobals.app.pluginsCDNPath + "/rsa-plugins.js" : "https://cdn.rudderlabs.com/3.0.0-beta.3/modern/plugins/rsa-plugins.js"),format:'esm',from:'vite'}
|
724
814
|
};
|
725
815
|
const loadJS = async (url, fn) => {
|
726
816
|
const resolvedUrl = typeof url === 'function' ? await url() : url;
|
@@ -844,13 +934,6 @@ unregisterLocalPlugins(){Object.values(pluginsInventory).forEach(localPlugin=>{t
|
|
844
934
|
* Handle errors
|
845
935
|
*/onError(error,customMessage){if(this.errorHandler){this.errorHandler.onError(error,PLUGINS_MANAGER,customMessage);}else {throw error;}}}
|
846
936
|
|
847
|
-
/**
|
848
|
-
* Get mutated error with issue prepended to error message
|
849
|
-
* @param err Original error
|
850
|
-
* @param issue Issue to prepend to error message
|
851
|
-
* @returns Instance of Error with message prepended with issue
|
852
|
-
*/const getMutatedError=(err,issue)=>{let finalError=err;if(!isTypeOfError(err)){finalError=new Error(`${issue}: ${stringifyWithoutCircular(err)}`);}else {finalError.message=`${issue}: ${err.message}`;}return finalError;};
|
853
|
-
|
854
937
|
/**
|
855
938
|
* Utility to parse XHR JSON response
|
856
939
|
*/const responseTextToJson=(responseText,onError)=>{try{return JSON.parse(responseText||'');}catch(err){const error=getMutatedError(err,'Failed to parse response data');if(onError&&isFunction(onError)){onError(error);}else {throw error;}}return undefined;};
|
@@ -861,7 +944,7 @@ const DEFAULT_XHR_REQUEST_OPTIONS={headers:{Accept:'application/json','Content-T
|
|
861
944
|
* Utility implementation of XHR, fetch cannot be used as it requires explicit
|
862
945
|
* origin allowed values and not wildcard for CORS requests with credentials and
|
863
946
|
* this is not supported by our sourceConfig API
|
864
|
-
*/const xhrRequest=(options,timeout=
|
947
|
+
*/const xhrRequest=(options,timeout=DEFAULT_XHR_TIMEOUT_MS,logger)=>new Promise((resolve,reject)=>{let payload;if(options.sendRawData===true){payload=options.data;}else {payload=stringifyWithoutCircular(options.data,false,[],logger);if(isNull(payload)){reject({error:new Error(XHR_PAYLOAD_PREP_ERROR),undefined,options});// return and don't process further if the payload could not be stringified
|
865
948
|
return;}}const xhr=new XMLHttpRequest();// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
866
949
|
const xhrReject=e=>{reject({error:new Error(XHR_DELIVERY_ERROR(FAILED_REQUEST_ERR_MSG_PREFIX,xhr.status,xhr.statusText,options.url)),xhr,options});};const xhrError=e=>{reject({error:new Error(XHR_REQUEST_ERROR(FAILED_REQUEST_ERR_MSG_PREFIX,e,options.url)),xhr,options});};xhr.ontimeout=xhrError;xhr.onerror=xhrError;xhr.onload=()=>{if(xhr.status>=200&&xhr.status<400){resolve({response:xhr.responseText,xhr,options});}else {xhrReject();}};xhr.open(options.method,options.url);// The timeout property may be set only in the time interval between a call to the open method
|
867
950
|
// and the first call to the send method in legacy browsers
|
@@ -881,55 +964,24 @@ xhr.timeout=timeout;Object.keys(options.headers).forEach(headerName=>{if(options
|
|
881
964
|
* Clear basic authentication header
|
882
965
|
*/resetAuthHeader(){this.basicAuthHeader=undefined;}}const defaultHttpClient=new HttpClient(defaultErrorHandler,defaultLogger);
|
883
966
|
|
884
|
-
const
|
967
|
+
const COOKIE_STORAGE='cookieStorage';const LOCAL_STORAGE='localStorage';const SESSION_STORAGE='sessionStorage';const MEMORY_STORAGE='memoryStorage';const NO_STORAGE='none';
|
885
968
|
|
886
|
-
const
|
969
|
+
const STORAGE_TEST_COOKIE='test_rudder_cookie';const STORAGE_TEST_LOCAL_STORAGE='test_rudder_ls';const STORAGE_TEST_SESSION_STORAGE='test_rudder_ss';const STORAGE_TEST_TOP_LEVEL_DOMAIN='__tld__';const CLIENT_DATA_STORE_NAME='clientData';
|
887
970
|
|
888
971
|
/**
|
889
|
-
*
|
890
|
-
*
|
891
|
-
|
892
|
-
* @param {*} id ID for the script tag
|
893
|
-
* @param {*} async Whether to load the script in async mode. Defaults to `true` [optional]
|
894
|
-
* @param {*} onload callback to invoke onload [optional]
|
895
|
-
* @param {*} onerror callback to invoke onerror [optional]
|
896
|
-
* @param {*} extraAttributes key/value pair with html attributes to add in html tag [optional]
|
897
|
-
*
|
898
|
-
* @returns HTMLScriptElement
|
899
|
-
*/const createScriptElement=(url,id,async=true,onload=null,onerror=null,extraAttributes={})=>{const scriptElement=document.createElement('script');scriptElement.type='text/javascript';scriptElement.onload=onload;scriptElement.onerror=onerror;scriptElement.src=url;scriptElement.id=id;scriptElement.async=async;scriptElement.setAttribute('data-append-origin',EXTERNAL_SOURCE_LOAD_ORIGIN);Object.keys(extraAttributes).forEach(attributeName=>{scriptElement.setAttribute(attributeName,extraAttributes[attributeName]);});return scriptElement;};/**
|
900
|
-
* Add script DOM element to DOM
|
901
|
-
*
|
902
|
-
* @param {*} newScriptElement the script element to add
|
903
|
-
*
|
904
|
-
* @returns
|
905
|
-
*/const insertScript=newScriptElement=>{// First try to add it to the head
|
906
|
-
const headElements=document.getElementsByTagName('head');if(headElements.length>0){headElements[0].insertBefore(newScriptElement,headElements[0].firstChild);return;}// Else wise add it before the first script tag
|
907
|
-
const scriptElements=document.getElementsByTagName('script');if(scriptElements.length>0&&scriptElements[0].parentNode){scriptElements[0].parentNode.insertBefore(newScriptElement,scriptElements[0]);return;}// Create a new head element and add the script as fallback
|
908
|
-
const headElement=document.createElement('head');headElement.appendChild(newScriptElement);const htmlElement=document.getElementsByTagName('html')[0];htmlElement.insertBefore(headElement,htmlElement.firstChild);};/**
|
909
|
-
* Loads external js file as a script html tag
|
910
|
-
*
|
911
|
-
* @param {*} url The URL of the script to be loaded
|
912
|
-
* @param {*} id ID for the script tag
|
913
|
-
* @param {*} timeout loading timeout
|
914
|
-
* @param {*} async Whether to load the script in async mode. Defaults to `true` [optional]
|
915
|
-
* @param {*} extraAttributes key/value pair with html attributes to add in html tag [optional]
|
916
|
-
*
|
917
|
-
* @returns
|
918
|
-
*/const jsFileLoader=(url,id,timeout,async=true,extraAttributes)=>new Promise((resolve,reject)=>{const scriptExists=document.getElementById(id);if(scriptExists){reject(new Error(SCRIPT_ALREADY_EXISTS_ERROR(id)));}try{let timeoutID;const onload=()=>{globalThis.clearTimeout(timeoutID);resolve(id);};const onerror=()=>{globalThis.clearTimeout(timeoutID);reject(new Error(SCRIPT_LOAD_ERROR(id,url)));};// Create the DOM element to load the script and add it to the DOM
|
919
|
-
insertScript(createScriptElement(url,id,async,onload,onerror,extraAttributes));// Reject on timeout
|
920
|
-
timeoutID=globalThis.setTimeout(()=>{reject(new Error(SCRIPT_LOAD_TIMEOUT_ERROR(id,url,timeout)));},timeout);}catch(err){reject(getMutatedError(err,SCRIPT_LOAD_ERROR(id,url)));}});
|
972
|
+
* To get the current timestamp in ISO string format
|
973
|
+
* @returns ISO formatted timestamp string
|
974
|
+
*/const getCurrentTimeFormatted=()=>{const curDateTime=new Date().toISOString();return curDateTime;};
|
921
975
|
|
922
|
-
|
923
|
-
* Service to load external resources/files
|
924
|
-
*/class ExternalSrcLoader{hasErrorHandler=false;constructor(errorHandler,logger,timeout=DEFAULT_EXT_SRC_LOAD_TIMEOUT){this.errorHandler=errorHandler;this.logger=logger;this.timeout=timeout;this.hasErrorHandler=Boolean(this.errorHandler);this.onError=this.onError.bind(this);}/**
|
925
|
-
* Load external resource of type javascript
|
926
|
-
*/loadJSFile(config){const{url,id,timeout,async,callback,extraAttributes}=config;const isFireAndForget=!(callback&&isFunction(callback));jsFileLoader(url,id,timeout||this.timeout,async,extraAttributes).then(id=>{if(!isFireAndForget){callback(id);}}).catch(err=>{this.onError(err);if(!isFireAndForget){callback();}});}/**
|
927
|
-
* Handle errors
|
928
|
-
*/onError(error){if(this.hasErrorHandler){this.errorHandler?.onError(error,EXTERNAL_SRC_LOADER);}else {throw error;}}}
|
976
|
+
function random(len){return crypto.getRandomValues(new Uint8Array(len));}
|
929
977
|
|
930
|
-
|
978
|
+
var SIZE=4096,HEX$1=[],IDX$1=0,BUFFER$1;for(;IDX$1<256;IDX$1++){HEX$1[IDX$1]=(IDX$1+256).toString(16).substring(1);}function v4$1(){if(!BUFFER$1||IDX$1+16>SIZE){BUFFER$1=random(SIZE);IDX$1=0;}var i=0,tmp,out='';for(;i<16;i++){tmp=BUFFER$1[IDX$1+i];if(i==6)out+=HEX$1[tmp&15|64];else if(i==8)out+=HEX$1[tmp&63|128];else out+=HEX$1[tmp];if(i&1&&i>1&&i<11)out+='-';}IDX$1+=16;return out;}
|
931
979
|
|
932
|
-
|
980
|
+
var IDX=256,HEX=[],BUFFER;while(IDX--)HEX[IDX]=(IDX+256).toString(16).substring(1);function v4(){var i=0,num,out='';if(!BUFFER||IDX+16>256){BUFFER=Array(i=256);while(i--)BUFFER[i]=256*Math.random()|0;i=IDX=0;}for(;i<16;i++){num=BUFFER[IDX+i];if(i==6)out+=HEX[num&15|64];else if(i==8)out+=HEX[num&63|128];else out+=HEX[num];if(i&1&&i>1&&i<11)out+='-';}IDX++;return out;}
|
981
|
+
|
982
|
+
const hasCrypto$1=()=>!isNullOrUndefined(globalThis.crypto)&&isFunction(globalThis.crypto.getRandomValues);
|
983
|
+
|
984
|
+
const generateUUID=()=>{if(hasCrypto$1()){return v4$1();}return v4();};
|
933
985
|
|
934
986
|
const detectAdBlockers=(errorHandler,logger)=>{// Apparently, '?view=ad' is a query param that is blocked by majority of adblockers
|
935
987
|
// Use source config URL here as it is very unlikely to be blocked by adblockers
|
@@ -941,11 +993,11 @@ method:'HEAD',headers:{'Content-Type':undefined}},isRawResponse:true,callback:(r
|
|
941
993
|
// Often adblockers instead of blocking the request, they redirect it to an internal URL
|
942
994
|
state.capabilities.isAdBlocked.value=details?.error!==undefined||details?.xhr?.responseURL!==url;}});};
|
943
995
|
|
944
|
-
const hasCrypto
|
996
|
+
const hasCrypto=()=>!isNullOrUndefined(globalThis.crypto)&&isFunction(globalThis.crypto.getRandomValues);const hasUAClientHints=()=>!isNullOrUndefined(globalThis.navigator.userAgentData);const hasBeacon=()=>!isNullOrUndefined(globalThis.navigator.sendBeacon)&&isFunction(globalThis.navigator.sendBeacon);const isIE11=()=>Boolean(globalThis.navigator.userAgent.match(/Trident.*rv:11\./));
|
945
997
|
|
946
998
|
const getUserAgentClientHint=(callback,level='none')=>{if(level==='none'){callback(undefined);}if(level==='default'){callback(navigator.userAgentData);}if(level==='full'){navigator.userAgentData?.getHighEntropyValues(['architecture','bitness','brands','mobile','model','platform','platformVersion','uaFullVersion','fullVersionList','wow64']).then(ua=>{callback(ua);}).catch(()=>{callback();});}};
|
947
999
|
|
948
|
-
const isDatasetAvailable=()=>{const testElement=document.createElement('div');testElement.setAttribute('data-a-b','c');return testElement.dataset?testElement.dataset.aB==='c':false;};const legacyJSEngineRequiredPolyfills={URLSearchParams:()=>!globalThis.URLSearchParams,URL:()=>!isFunction(globalThis.URL),MutationObserver:()=>isUndefined(MutationObserver),Promise:()=>isUndefined(Promise),'Number.isNaN':()=>!Number.isNaN,'Number.isInteger':()=>!Number.isInteger,'Array.from':()=>!Array.from,'Array.prototype.find':()=>!Array.prototype.find,'Array.prototype.includes':()=>!Array.prototype.includes,'String.prototype.endsWith':()=>!String.prototype.endsWith,'String.prototype.startsWith':()=>!String.prototype.startsWith,'String.prototype.includes':()=>!String.prototype.includes,'Object.entries':()=>!Object.entries,'Object.values':()=>!Object.values,'Element.prototype.dataset':()=>!isDatasetAvailable(),'String.prototype.replaceAll':()=>!String.prototype.replaceAll,TextEncoder:()=>isUndefined(TextEncoder),TextDecoder:()=>isUndefined(TextDecoder),'String.fromCodePoint':()=>!String.fromCodePoint};const isLegacyJSEngine=()=>{const requiredCapabilitiesList=Object.keys(legacyJSEngineRequiredPolyfills);let needsPolyfill=false;/* eslint-disable-next-line unicorn/no-for-loop */for(let i=0;i<requiredCapabilitiesList.length;i++){const isCapabilityMissing=legacyJSEngineRequiredPolyfills[requiredCapabilitiesList[i]];if(isCapabilityMissing()){needsPolyfill=true;}}return needsPolyfill;};
|
1000
|
+
const isDatasetAvailable=()=>{const testElement=document.createElement('div');testElement.setAttribute('data-a-b','c');return testElement.dataset?testElement.dataset.aB==='c':false;};const legacyJSEngineRequiredPolyfills={URLSearchParams:()=>!globalThis.URLSearchParams,URL:()=>!isFunction(globalThis.URL),MutationObserver:()=>isUndefined(MutationObserver),Promise:()=>isUndefined(Promise),'Number.isNaN':()=>!Number.isNaN,'Number.isInteger':()=>!Number.isInteger,'Array.from':()=>!Array.from,'Array.prototype.find':()=>!Array.prototype.find,'Array.prototype.includes':()=>!Array.prototype.includes,'String.prototype.endsWith':()=>!String.prototype.endsWith,'String.prototype.startsWith':()=>!String.prototype.startsWith,'String.prototype.includes':()=>!String.prototype.includes,'Object.entries':()=>!Object.entries,'Object.values':()=>!Object.values,'Element.prototype.dataset':()=>!isDatasetAvailable(),'String.prototype.replaceAll':()=>!String.prototype.replaceAll,TextEncoder:()=>isUndefined(TextEncoder),TextDecoder:()=>isUndefined(TextDecoder),'String.fromCodePoint':()=>!String.fromCodePoint,requestAnimationFrame:()=>!isFunction(globalThis.requestAnimationFrame),cancelAnimationFrame:()=>!isFunction(globalThis.cancelAnimationFrame),CustomEvent:()=>!isFunction(globalThis.CustomEvent)};const isLegacyJSEngine=()=>{const requiredCapabilitiesList=Object.keys(legacyJSEngineRequiredPolyfills);let needsPolyfill=false;/* eslint-disable-next-line unicorn/no-for-loop */for(let i=0;i<requiredCapabilitiesList.length;i++){const isCapabilityMissing=legacyJSEngineRequiredPolyfills[requiredCapabilitiesList[i]];if(isCapabilityMissing()){needsPolyfill=true;break;}}return needsPolyfill;};
|
949
1001
|
|
950
1002
|
const getScreenDetails=()=>{let screenDetails={density:0,width:0,height:0,innerWidth:0,innerHeight:0};screenDetails={width:globalThis.screen.width,height:globalThis.screen.height,density:globalThis.devicePixelRatio,innerWidth:globalThis.innerWidth,innerHeight:globalThis.innerHeight};return screenDetails;};
|
951
1003
|
|
@@ -956,21 +1008,6 @@ const isQuotaExceededError=matchingNames.includes(e.name)||matchingCodes.include
|
|
956
1008
|
const isStorageAvailable=(type=LOCAL_STORAGE,storageInstance,logger)=>{let storage;let testData;try{switch(type){case MEMORY_STORAGE:return true;case COOKIE_STORAGE:storage=storageInstance;testData=STORAGE_TEST_COOKIE;break;case LOCAL_STORAGE:storage=storageInstance??globalThis.localStorage;testData=STORAGE_TEST_LOCAL_STORAGE;// was STORAGE_TEST_LOCAL_STORAGE in ours and generateUUID() in segment retry one
|
957
1009
|
break;case SESSION_STORAGE:storage=storageInstance??globalThis.sessionStorage;testData=STORAGE_TEST_SESSION_STORAGE;break;default:return false;}if(!storage){return false;}storage.setItem(testData,'true');if(storage.getItem(testData)){storage.removeItem(testData);return true;}return false;}catch(err){const msgPrefix=STORAGE_UNAVAILABILITY_ERROR_PREFIX(CAPABILITIES_MANAGER,type);let reason='unavailable';if(isStorageQuotaExceeded(err)){reason='full';}logger?.error(`${msgPrefix}${reason}.`,err);return false;}};
|
958
1010
|
|
959
|
-
/**
|
960
|
-
* To get the current timestamp in ISO string format
|
961
|
-
* @returns ISO formatted timestamp string
|
962
|
-
*/const getCurrentTimeFormatted=()=>{const curDateTime=new Date().toISOString();return curDateTime;};
|
963
|
-
|
964
|
-
function random(len){return crypto.getRandomValues(new Uint8Array(len));}
|
965
|
-
|
966
|
-
var SIZE=4096,HEX$1=[],IDX$1=0,BUFFER$1;for(;IDX$1<256;IDX$1++){HEX$1[IDX$1]=(IDX$1+256).toString(16).substring(1);}function v4$1(){if(!BUFFER$1||IDX$1+16>SIZE){BUFFER$1=random(SIZE);IDX$1=0;}var i=0,tmp,out='';for(;i<16;i++){tmp=BUFFER$1[IDX$1+i];if(i==6)out+=HEX$1[tmp&15|64];else if(i==8)out+=HEX$1[tmp&63|128];else out+=HEX$1[tmp];if(i&1&&i>1&&i<11)out+='-';}IDX$1+=16;return out;}
|
967
|
-
|
968
|
-
var IDX=256,HEX=[],BUFFER;while(IDX--)HEX[IDX]=(IDX+256).toString(16).substring(1);function v4(){var i=0,num,out='';if(!BUFFER||IDX+16>256){BUFFER=Array(i=256);while(i--)BUFFER[i]=256*Math.random()|0;i=IDX=0;}for(;i<16;i++){num=BUFFER[IDX+i];if(i==6)out+=HEX[num&15|64];else if(i==8)out+=HEX[num&63|128];else out+=HEX[num];if(i&1&&i>1&&i<11)out+='-';}IDX++;return out;}
|
969
|
-
|
970
|
-
const hasCrypto=()=>!isNullOrUndefined(globalThis.crypto)&&isFunction(globalThis.crypto.getRandomValues);
|
971
|
-
|
972
|
-
const generateUUID=()=>{if(hasCrypto()){return v4$1();}return v4();};
|
973
|
-
|
974
1011
|
/**
|
975
1012
|
* Encode.
|
976
1013
|
*/const encode=value=>encodeURIComponent(value);/**
|
@@ -1011,7 +1048,7 @@ cookie(cname,1,opts);// If successful
|
|
1011
1048
|
if(cookie(cname)){// Remove cookie from domain
|
1012
1049
|
cookie(cname,null,opts);return domain;}}return '';};
|
1013
1050
|
|
1014
|
-
const getDefaultCookieOptions=()=>{const topDomain=domain(globalThis.location.href);return {maxage:
|
1051
|
+
const getDefaultCookieOptions=()=>{const topDomain=domain(globalThis.location.href);return {maxage:DEFAULT_COOKIE_MAX_AGE_MS,path:'/',domain:!topDomain||topDomain==='.'?undefined:topDomain,samesite:CookieSameSite.Lax,enabled:true};};const getDefaultLocalStorageOptions=()=>({enabled:true});const getDefaultInMemoryStorageOptions=()=>({enabled:true});
|
1015
1052
|
|
1016
1053
|
/**
|
1017
1054
|
* A storage utility to persist values in cookies via Storage interface
|
@@ -1080,7 +1117,7 @@ Object.keys(validKeys).forEach(key=>{const value=this.get(validKeys[key]);const
|
|
1080
1117
|
this.remove(key);});this.engine=inMemoryStorage;}/**
|
1081
1118
|
* Set value by key.
|
1082
1119
|
*/set(key,value){const validKey=this.createValidKey(key);if(!validKey){return;}try{// storejs that is used in localstorage engine already stringifies json
|
1083
|
-
this.engine.setItem(validKey,this.encrypt(stringifyWithoutCircular(value,false,[],this.logger)));}catch(err){if(isStorageQuotaExceeded(err)){this.logger?.warn(STORAGE_QUOTA_EXCEEDED_WARNING(
|
1120
|
+
this.engine.setItem(validKey,this.encrypt(stringifyWithoutCircular(value,false,[],this.logger)));}catch(err){if(isStorageQuotaExceeded(err)){this.logger?.warn(STORAGE_QUOTA_EXCEEDED_WARNING(`Store ${this.id}`));// switch to inMemory engine
|
1084
1121
|
this.swapQueueStoreToInMemoryEngine();// and save it there
|
1085
1122
|
this.set(key,value);}else {this.onError(getMutatedError(err,STORE_DATA_SAVE_ERROR(key)));}}}/**
|
1086
1123
|
* Get by Key.
|
@@ -1105,12 +1142,10 @@ return JSON.parse(str);}catch(err){this.onError(new Error(`${STORE_DATA_FETCH_ER
|
|
1105
1142
|
* Configure available storage client instances
|
1106
1143
|
*/init(){if(this.isInitialized){return;}const config={cookieOptions:{samesite:state.loadOptions.value.sameSiteCookie,secure:state.loadOptions.value.secureCookie,domain:state.loadOptions.value.setCookieDomain,enabled:true},localStorageOptions:{enabled:true},inMemoryStorageOptions:{enabled:true}};configureStorageEngines(removeUndefinedValues(config.cookieOptions),removeUndefinedValues(config.localStorageOptions),removeUndefinedValues(config.inMemoryStorageOptions));this.initClientDataStore();this.isInitialized=true;}/**
|
1107
1144
|
* Create store to persist data used by the SDK like session, used details etc
|
1108
|
-
*/initClientDataStore(){let storageType=
|
1109
|
-
if(getStorageEngine(COOKIE_STORAGE)?.isEnabled){
|
1110
|
-
// TODO: should we fallback to session storage instead so we retain values on page refresh, navigation etc?
|
1111
|
-
if(!storageType){this.logger?.error(STORAGE_UNAVAILABLE_ERROR(STORE_MANAGER));return;}// TODO: fill in extra config values and bring them in from StoreManagerOptions if needed
|
1145
|
+
*/initClientDataStore(){const storageType=state.storage.type.value||COOKIE_STORAGE;let finalStorageType=storageType;switch(storageType){case LOCAL_STORAGE:if(!getStorageEngine(LOCAL_STORAGE)?.isEnabled){finalStorageType=MEMORY_STORAGE;}break;case MEMORY_STORAGE:finalStorageType=MEMORY_STORAGE;break;case NO_STORAGE:finalStorageType=NO_STORAGE;break;case COOKIE_STORAGE:default:// First try setting the storage to cookie else to local storage
|
1146
|
+
if(getStorageEngine(COOKIE_STORAGE)?.isEnabled){finalStorageType=COOKIE_STORAGE;}else if(getStorageEngine(LOCAL_STORAGE)?.isEnabled){finalStorageType=LOCAL_STORAGE;}else {finalStorageType=MEMORY_STORAGE;}break;}if(finalStorageType!==storageType){this.logger?.warn(STORAGE_UNAVAILABLE_WARNING(STORE_MANAGER,storageType,finalStorageType));}// TODO: fill in extra config values and bring them in from StoreManagerOptions if needed
|
1112
1147
|
// TODO: should we pass the keys for all in order to validate or leave free as v1.1?
|
1113
|
-
this.setStore({id:CLIENT_DATA_STORE_NAME,name:CLIENT_DATA_STORE_NAME,isEncrypted:true,noCompoundKey:true,type:
|
1148
|
+
if(finalStorageType!==NO_STORAGE){this.setStore({id:CLIENT_DATA_STORE_NAME,name:CLIENT_DATA_STORE_NAME,isEncrypted:true,noCompoundKey:true,type:finalStorageType});}}/**
|
1114
1149
|
* Create a new store
|
1115
1150
|
*/setStore(storeConfig){const storageEngine=getStorageEngine(storeConfig.type);this.stores[storeConfig.id]=new Store(storeConfig,storageEngine,this.pluginsManager);return this.stores[storeConfig.id];}/**
|
1116
1151
|
* Retrieve a store
|
@@ -1144,7 +1179,29 @@ if(utmParam==='campaign'){utmParam='name';}result[utmParam]=value;}});}catch(err
|
|
1144
1179
|
*/const getUrlWithoutHash=url=>{let urlWithoutHash=url;try{const urlObj=new URL(url);urlWithoutHash=urlObj.origin+urlObj.pathname+urlObj.search;}catch(error){// Do nothing
|
1145
1180
|
}return urlWithoutHash;};
|
1146
1181
|
|
1147
|
-
const validateWriteKey=writeKey=>{if(!writeKey||writeKey.trim().length===0){throw new Error(WRITE_KEY_VALIDATION_ERROR(writeKey));}};const validateDataPlaneUrl=dataPlaneUrl=>{if(dataPlaneUrl&&!isValidUrl(dataPlaneUrl)){throw new Error(DATA_PLANE_URL_VALIDATION_ERROR(dataPlaneUrl));}};const validateLoadArgs=(writeKey,dataPlaneUrl)=>{validateWriteKey(writeKey);validateDataPlaneUrl(dataPlaneUrl);};const isValidSourceConfig=res=>isObjectLiteralAndNotNull(res)&&isObjectLiteralAndNotNull(res.source)&&!isNullOrUndefined(res.source.id)&&isObjectLiteralAndNotNull(res.source.config)&&Array.isArray(res.source.destinations);
|
1182
|
+
const validateWriteKey=writeKey=>{if(!isString(writeKey)||writeKey.trim().length===0){throw new Error(WRITE_KEY_VALIDATION_ERROR(writeKey));}};const validateDataPlaneUrl=dataPlaneUrl=>{if(dataPlaneUrl&&!isValidUrl(dataPlaneUrl)){throw new Error(DATA_PLANE_URL_VALIDATION_ERROR(dataPlaneUrl));}};const validateLoadArgs=(writeKey,dataPlaneUrl)=>{validateWriteKey(writeKey);validateDataPlaneUrl(dataPlaneUrl);};const isValidSourceConfig=res=>isObjectLiteralAndNotNull(res)&&isObjectLiteralAndNotNull(res.source)&&!isNullOrUndefined(res.source.id)&&isObjectLiteralAndNotNull(res.source.config)&&Array.isArray(res.source.destinations);const isValidStorageType=storageType=>typeof storageType==='string'&&SUPPORTED_STORAGE_TYPES.includes(storageType);
|
1183
|
+
|
1184
|
+
const removeDuplicateSlashes=str=>str.replace(/\/{2,}/g,'/');
|
1185
|
+
|
1186
|
+
const defaultOptionalPluginsList=[PluginName.Bugsnag,PluginName.DeviceModeDestinations,PluginName.ErrorReporting,PluginName.ExternalAnonymousId,PluginName.GoogleLinker,PluginName.NativeDestinationQueue,PluginName.StorageEncryption,PluginName.StorageEncryptionLegacy,PluginName.StorageMigrator,PluginName.XhrQueue,PluginName.OneTrustConsentManager,PluginName.KetchConsentManager,PluginName.BeaconQueue];
|
1187
|
+
|
1188
|
+
/**
|
1189
|
+
* A function to check given value is a number or not
|
1190
|
+
* @param num input value
|
1191
|
+
* @returns boolean
|
1192
|
+
*/const isNumber=num=>typeof num==='number'&&!Number.isNaN(num);/**
|
1193
|
+
* A function to check given number has minimum length or not
|
1194
|
+
* @param minimumLength minimum length
|
1195
|
+
* @param num input number
|
1196
|
+
* @returns boolean
|
1197
|
+
*/const hasMinLength=(minimumLength,num)=>num.toString().length>=minimumLength;/**
|
1198
|
+
* A function to check given value is a positive integer or not
|
1199
|
+
* @param num input value
|
1200
|
+
* @returns boolean
|
1201
|
+
*/const isPositiveInteger=num=>isNumber(num)&&num>=0&&Number.isInteger(num);
|
1202
|
+
|
1203
|
+
const normalizeLoadOptions=(loadOptionsFromState,loadOptions)=>{// TODO: Maybe add warnings for invalid values
|
1204
|
+
const normalizedLoadOpts=clone$1(loadOptions);if(!isString(normalizedLoadOpts.setCookieDomain)){delete normalizedLoadOpts.setCookieDomain;}if(!getObjectValues(CookieSameSite).includes(normalizedLoadOpts.sameSiteCookie)){delete normalizedLoadOpts.sameSiteCookie;}normalizedLoadOpts.secureCookie=normalizedLoadOpts.secureCookie===true;if(!getObjectValues(UaChTrackLevel).includes(normalizedLoadOpts.uaChTrackLevel)){delete normalizedLoadOpts.uaChTrackLevel;}if(!isObjectLiteralAndNotNull(normalizedLoadOpts.integrations)){delete normalizedLoadOpts.integrations;}normalizedLoadOpts.plugins=normalizedLoadOpts.plugins??defaultOptionalPluginsList;normalizedLoadOpts.useGlobalIntegrationsConfigInEvents=normalizedLoadOpts.useGlobalIntegrationsConfigInEvents===true;normalizedLoadOpts.bufferDataPlaneEventsUntilReady=normalizedLoadOpts.bufferDataPlaneEventsUntilReady===true;normalizedLoadOpts.sendAdblockPage=normalizedLoadOpts.sendAdblockPage===true;if(!isObjectLiteralAndNotNull(normalizedLoadOpts.sendAdblockPageOptions)){delete normalizedLoadOpts.sendAdblockPageOptions;}if(!isDefined(normalizedLoadOpts.loadIntegration)){delete normalizedLoadOpts.loadIntegration;}else {normalizedLoadOpts.loadIntegration=normalizedLoadOpts.loadIntegration===true;}if(!isObjectLiteralAndNotNull(normalizedLoadOpts.storage)){delete normalizedLoadOpts.storage;}else {normalizedLoadOpts.storage=removeUndefinedAndNullValues(normalizedLoadOpts.storage);normalizedLoadOpts.storage.migrate=normalizedLoadOpts.storage?.migrate===true;}if(!isObjectLiteralAndNotNull(normalizedLoadOpts.beaconQueueOptions)){delete normalizedLoadOpts.beaconQueueOptions;}else {normalizedLoadOpts.beaconQueueOptions=removeUndefinedAndNullValues(normalizedLoadOpts.beaconQueueOptions);}if(!isObjectLiteralAndNotNull(normalizedLoadOpts.destinationsQueueOptions)){delete normalizedLoadOpts.destinationsQueueOptions;}else {normalizedLoadOpts.destinationsQueueOptions=removeUndefinedAndNullValues(normalizedLoadOpts.destinationsQueueOptions);}if(!isObjectLiteralAndNotNull(normalizedLoadOpts.queueOptions)){delete normalizedLoadOpts.queueOptions;}else {normalizedLoadOpts.queueOptions=removeUndefinedAndNullValues(normalizedLoadOpts.queueOptions);}normalizedLoadOpts.lockIntegrationsVersion=normalizedLoadOpts.lockIntegrationsVersion===true;if(!isNumber(normalizedLoadOpts.dataPlaneEventsBufferTimeout)){delete normalizedLoadOpts.dataPlaneEventsBufferTimeout;}const mergedLoadOptions=mergeDeepRight(loadOptionsFromState,normalizedLoadOpts);return mergedLoadOptions;};const getSourceConfigURL=(configUrl,writeKey,lockIntegrationsVersion,logger)=>{const defSearchParams=new URLSearchParams({p:MODULE_TYPE,v:APP_VERSION,build:BUILD_TYPE,writeKey,lockIntegrationsVersion:lockIntegrationsVersion.toString()});let origin=DEFAULT_CONFIG_BE_URL;let searchParams=defSearchParams;let pathname='/sourceConfig/';let hash='';try{const configUrlInstance=new URL(configUrl);if(!removeTrailingSlashes(configUrlInstance.pathname).endsWith('/sourceConfig')){configUrlInstance.pathname=`${removeTrailingSlashes(configUrlInstance.pathname)}/sourceConfig/`;}configUrlInstance.pathname=removeDuplicateSlashes(configUrlInstance.pathname);defSearchParams.forEach((value,key)=>{if(configUrlInstance.searchParams.get(key)===null){configUrlInstance.searchParams.set(key,value);}});origin=configUrlInstance.origin;pathname=configUrlInstance.pathname;searchParams=configUrlInstance.searchParams;hash=configUrlInstance.hash;}catch(err){logger?.warn(INVALID_CONFIG_URL_WARNING(CONFIG_MANAGER,configUrl));}return `${origin}${pathname}?${searchParams}${hash}`;};
|
1148
1205
|
|
1149
1206
|
/**
|
1150
1207
|
* A function to filter enabled destinations and map to required properties only
|
@@ -1153,13 +1210,6 @@ const validateWriteKey=writeKey=>{if(!writeKey||writeKey.trim().length===0){thro
|
|
1153
1210
|
* @returns Destination[]
|
1154
1211
|
*/const filterEnabledDestination=destinations=>{const nativeDestinations=[];destinations.forEach(destination=>{if(destination.enabled&&!destination.deleted){nativeDestinations.push({id:destination.id,displayName:destination.destinationDefinition.displayName,config:destination.config,shouldApplyDeviceModeTransformation:destination.shouldApplyDeviceModeTransformation||false,propagateEventsUntransformedOnError:destination.propagateEventsUntransformedOnError||false,userFriendlyId:`${destination.destinationDefinition.displayName.replaceAll(' ','-')}___${destination.id}`});}});return nativeDestinations;};
|
1155
1212
|
|
1156
|
-
const defaultOptionalPluginsList=[PluginName.Bugsnag,PluginName.DeviceModeDestinations,PluginName.ErrorReporting,PluginName.ExternalAnonymousId,PluginName.GoogleLinker,PluginName.NativeDestinationQueue,PluginName.StorageEncryption,PluginName.StorageEncryptionLegacy,PluginName.StorageMigrator,PluginName.XhrQueue,PluginName.OneTrustConsentManager,PluginName.KetchConsentManager,PluginName.BeaconQueue];
|
1157
|
-
|
1158
|
-
const normalizeLoadOptions=(loadOptionsFromState,loadOptions)=>{// TODO: add all the validations as per
|
1159
|
-
// https://github.com/rudderlabs/rudder-sdk-js/blob/a620e11f98e1438be34114ad40b325201b1d7a6e/src/core/analytics.js#L1156
|
1160
|
-
// TODO: Maybe add warnings for invalid values
|
1161
|
-
const normalizedLoadOpts=clone$1(loadOptions);normalizedLoadOpts.setCookieDomain=isDefined(normalizedLoadOpts.setCookieDomain)&&isString(normalizedLoadOpts.setCookieDomain)?normalizedLoadOpts.setCookieDomain:undefined;normalizedLoadOpts.secureCookie=normalizedLoadOpts.secureCookie===true;normalizedLoadOpts.sameSiteCookie=isDefined(normalizedLoadOpts.sameSiteCookie)&&Object.values(CookieSameSite).includes(normalizedLoadOpts.sameSiteCookie)?normalizedLoadOpts.sameSiteCookie:undefined;normalizedLoadOpts.plugins=normalizedLoadOpts.plugins??defaultOptionalPluginsList;normalizedLoadOpts.useGlobalIntegrationsConfigInEvents=normalizedLoadOpts.useGlobalIntegrationsConfigInEvents===true;normalizedLoadOpts.bufferDataPlaneEventsUntilReady=normalizedLoadOpts.bufferDataPlaneEventsUntilReady===true;normalizedLoadOpts.sendAdblockPage=normalizedLoadOpts.sendAdblockPage===true;normalizedLoadOpts.sendAdblockPageOptions=isObjectLiteralAndNotNull(normalizedLoadOpts.sendAdblockPageOptions)?normalizedLoadOpts.sendAdblockPageOptions:{};normalizedLoadOpts.storage=isObjectLiteralAndNotNull(normalizedLoadOpts.storage)?removeUndefinedAndNullValues(normalizedLoadOpts.storage):{};normalizedLoadOpts.storage.migrate=normalizedLoadOpts.storage?.migrate===true;normalizedLoadOpts.beaconQueueOptions=isObjectLiteralAndNotNull(normalizedLoadOpts.beaconQueueOptions)?removeUndefinedAndNullValues(normalizedLoadOpts.beaconQueueOptions):{};normalizedLoadOpts.destinationsQueueOptions=isObjectLiteralAndNotNull(normalizedLoadOpts.destinationsQueueOptions)?removeUndefinedAndNullValues(normalizedLoadOpts.destinationsQueueOptions):{};normalizedLoadOpts.queueOptions=isObjectLiteralAndNotNull(normalizedLoadOpts.queueOptions)?removeUndefinedAndNullValues(normalizedLoadOpts.queueOptions):{};const mergedLoadOptions=mergeDeepRight(loadOptionsFromState,normalizedLoadOpts);return mergedLoadOptions;};const getSourceConfigURL=(configUrlHost=DEFAULT_CONFIG_BE_URL)=>`${configUrlHost}/sourceConfig/?p=${MODULE_TYPE}&v=${APP_VERSION}&build=${BUILD_TYPE}`;
|
1162
|
-
|
1163
1213
|
const DEFAULT_REGION='US';/**
|
1164
1214
|
* A function to get url from source config response
|
1165
1215
|
* @param {array} urls An array of objects containing urls
|
@@ -1226,13 +1276,14 @@ const sdkURL=getSDKUrl();pluginsCDNPath=sdkURL&&isString(sdkURL)?sdkURL.split('/
|
|
1226
1276
|
class ConfigManager{hasErrorHandler=false;constructor(httpClient,errorHandler,logger){this.errorHandler=errorHandler;this.logger=logger;this.httpClient=httpClient;this.hasErrorHandler=Boolean(this.errorHandler);this.onError=this.onError.bind(this);this.processConfig=this.processConfig.bind(this);}attachEffects(){b(()=>{this.logger?.setMinLogLevel(state.lifecycle.logLevel.value);});}/**
|
1227
1277
|
* A function to validate, construct and store loadOption, lifecycle, source and destination
|
1228
1278
|
* config related information in global state
|
1229
|
-
*/init(){let consentManagerPluginName;this.attachEffects();validateLoadArgs(state.lifecycle.writeKey.value,state.lifecycle.dataPlaneUrl.value)
|
1279
|
+
*/init(){let consentManagerPluginName;this.attachEffects();const lockIntegrationsVersion=state.loadOptions.value.lockIntegrationsVersion;validateLoadArgs(state.lifecycle.writeKey.value,state.lifecycle.dataPlaneUrl.value);// determine the path to fetch integration SDK from
|
1230
1280
|
const intgCdnUrl=getIntegrationsCDNPath(APP_VERSION,lockIntegrationsVersion,state.loadOptions.value.destSDKBaseURL);// determine the path to fetch remote plugins from
|
1231
1281
|
const pluginsCDNPath=getPluginsCDNPath(state.loadOptions.value.pluginsSDKBaseURL);// Get the consent manager if provided as load option
|
1232
1282
|
const selectedConsentManager=getUserSelectedConsentManager(state.loadOptions.value.cookieConsentManager);if(selectedConsentManager){// Get the corresponding plugin name of the selected consent manager from the supported consent managers
|
1233
1283
|
consentManagerPluginName=ConsentManagersToPluginNameMap[selectedConsentManager];if(!consentManagerPluginName){this.logger?.error(UNSUPPORTED_CONSENT_MANAGER_ERROR(CONFIG_MANAGER,selectedConsentManager,ConsentManagersToPluginNameMap));}}updateStorageState(this.logger);// set application lifecycle state in global state
|
1234
|
-
o(()=>{state.lifecycle.integrationsCDNPath.value=intgCdnUrl;state.lifecycle.pluginsCDNPath.value=pluginsCDNPath;if(state.loadOptions.value.logLevel){state.lifecycle.logLevel.value=state.loadOptions.value.logLevel;}if(state.loadOptions.value.configUrl){state.lifecycle.sourceConfigUrl.value=
|
1235
|
-
state.consents.activeConsentManagerPluginName.value=consentManagerPluginName
|
1284
|
+
o(()=>{state.lifecycle.integrationsCDNPath.value=intgCdnUrl;state.lifecycle.pluginsCDNPath.value=pluginsCDNPath;if(state.loadOptions.value.logLevel){state.lifecycle.logLevel.value=state.loadOptions.value.logLevel;}if(state.loadOptions.value.configUrl){state.lifecycle.sourceConfigUrl.value=getSourceConfigURL(state.loadOptions.value.configUrl,state.lifecycle.writeKey.value,lockIntegrationsVersion,this.logger);}// Set consent manager plugin name in state
|
1285
|
+
state.consents.activeConsentManagerPluginName.value=consentManagerPluginName;// set storage type in state
|
1286
|
+
const storageType=state.loadOptions.value.storage?.type;if(!isValidStorageType(storageType)){this.logger?.warn(STORAGE_TYPE_VALIDATION_WARNING(CONFIG_MANAGER,storageType,DEFAULT_STORAGE_TYPE));state.storage.type.value=DEFAULT_STORAGE_TYPE;}else {state.storage.type.value=storageType;}});this.getConfig();}/**
|
1236
1287
|
* Handle errors
|
1237
1288
|
*/onError(error,customMessage,shouldAlwaysThrow){if(this.hasErrorHandler){this.errorHandler?.onError(error,CONFIG_MANAGER,customMessage,shouldAlwaysThrow);}else {throw error;}}/**
|
1238
1289
|
* A callback function that is executed once we fetch the source config response.
|
@@ -1243,18 +1294,17 @@ if(!response){this.onError(SOURCE_CONFIG_FETCH_ERROR(details?.error));return;}le
|
|
1243
1294
|
const dataPlaneUrl=resolveDataPlaneUrl(res.source.dataplanes,state.lifecycle.dataPlaneUrl.value,state.loadOptions.value.residencyServer,this.logger);if(!dataPlaneUrl){this.onError(new Error(DATA_PLANE_URL_ERROR),undefined,true);return;}const nativeDestinations=res.source.destinations.length>0?filterEnabledDestination(res.source.destinations):[];// set in the state --> source, destination, lifecycle, reporting
|
1244
1295
|
o(()=>{// set source related information in state
|
1245
1296
|
state.source.value={config:res.source.config,id:res.source.id};// set device mode destination related information in state
|
1246
|
-
state.nativeDestinations.configuredDestinations.value=nativeDestinations;// set
|
1247
|
-
// Cast to string as we are sure that the value is not undefined
|
1248
|
-
state.lifecycle.activeDataplaneUrl.value=removeTrailingSlashes(dataPlaneUrl);state.lifecycle.status.value=LifecycleStatus.Configured;// set the values in state for reporting slice
|
1297
|
+
state.nativeDestinations.configuredDestinations.value=nativeDestinations;// set the values in state for reporting slice
|
1249
1298
|
updateReportingState(res,this.logger);// set the desired optional plugins
|
1250
1299
|
state.plugins.pluginsToLoadFromConfig.value=state.loadOptions.value.plugins??[];// set application lifecycle state
|
1251
|
-
|
1300
|
+
// Cast to string as we are sure that the value is not undefined
|
1301
|
+
state.lifecycle.activeDataplaneUrl.value=removeTrailingSlashes(dataPlaneUrl);state.lifecycle.status.value=LifecycleStatus.Configured;});}/**
|
1252
1302
|
* A function to fetch source config either from /sourceConfig endpoint
|
1253
1303
|
* or from getSourceConfig load option
|
1254
1304
|
* @returns
|
1255
1305
|
*/getConfig(){const sourceConfigFunc=state.loadOptions.value.getSourceConfig;if(sourceConfigFunc){if(!isFunction(sourceConfigFunc)){throw new Error(SOURCE_CONFIG_OPTION_ERROR);}// fetch source config from the function
|
1256
|
-
const res=sourceConfigFunc();if(res instanceof Promise){res.then(pRes=>this.processConfig(pRes)).catch(err=>{this.onError(err,'SourceConfig');});}else {this.processConfig(res);}
|
1257
|
-
this.httpClient.getAsyncData({url:state.lifecycle.sourceConfigUrl.value,options:{headers:{'Content-Type':undefined}},callback:this.processConfig});}}
|
1306
|
+
const res=sourceConfigFunc();if(res instanceof Promise){res.then(pRes=>this.processConfig(pRes)).catch(err=>{this.onError(err,'SourceConfig');});}else {this.processConfig(res);}}else {// fetch source config from config url API
|
1307
|
+
this.httpClient.getAsyncData({url:state.lifecycle.sourceConfigUrl.value,options:{headers:{'Content-Type':undefined}},callback:this.processConfig});}}}
|
1258
1308
|
|
1259
1309
|
/**
|
1260
1310
|
* Get the referrer URL
|
@@ -1277,12 +1327,12 @@ if(urlObj.search===''){pageUrl=canonicalUrl+search;}else {pageUrl=canonicalUrl;}
|
|
1277
1327
|
const POLYFILL_URL=`https://polyfill.io/v3/polyfill.min.js?features=${Object.keys(legacyJSEngineRequiredPolyfills).join('%2C')}`;const POLYFILL_LOAD_TIMEOUT=10*1000;// 10 seconds
|
1278
1328
|
const POLYFILL_SCRIPT_ID='rudderstackPolyfill';
|
1279
1329
|
|
1280
|
-
class CapabilitiesManager{constructor(errorHandler,logger){this.logger=logger;this.errorHandler=errorHandler;this.externalSrcLoader=new ExternalSrcLoader(this.errorHandler,this.logger);this.onError=this.onError.bind(this);this.onReady=this.onReady.bind(this);}init(){try{this.prepareBrowserCapabilities();this.attachWindowListeners();}catch(
|
1330
|
+
class CapabilitiesManager{constructor(errorHandler,logger){this.logger=logger;this.errorHandler=errorHandler;this.externalSrcLoader=new ExternalSrcLoader(this.errorHandler,this.logger);this.onError=this.onError.bind(this);this.onReady=this.onReady.bind(this);}init(){try{this.prepareBrowserCapabilities();this.attachWindowListeners();}catch(err){this.onError(err);}}/**
|
1281
1331
|
* Detect supported capabilities and set values in state
|
1282
1332
|
*/ // eslint-disable-next-line class-methods-use-this
|
1283
1333
|
detectBrowserCapabilities(){o(()=>{// Storage related details
|
1284
1334
|
state.capabilities.storage.isCookieStorageAvailable.value=isStorageAvailable(COOKIE_STORAGE,getStorageEngine(COOKIE_STORAGE),this.logger);state.capabilities.storage.isLocalStorageAvailable.value=isStorageAvailable(LOCAL_STORAGE,undefined,this.logger);state.capabilities.storage.isSessionStorageAvailable.value=isStorageAvailable(SESSION_STORAGE,undefined,this.logger);// Browser feature detection details
|
1285
|
-
state.capabilities.isBeaconAvailable.value=hasBeacon();state.capabilities.isUaCHAvailable.value=hasUAClientHints();state.capabilities.isCryptoAvailable.value=hasCrypto
|
1335
|
+
state.capabilities.isBeaconAvailable.value=hasBeacon();state.capabilities.isUaCHAvailable.value=hasUAClientHints();state.capabilities.isCryptoAvailable.value=hasCrypto();state.capabilities.isIE11.value=isIE11();state.capabilities.isOnline.value=globalThis.navigator.onLine;// Get page context details
|
1286
1336
|
state.context.userAgent.value=getUserAgent();state.context.locale.value=getLanguage();state.context.screen.value=getScreenDetails();state.context.campaign.value=extractUTMParameters(globalThis.location.href);if(hasUAClientHints()){getUserAgentClientHint(uach=>{state.context['ua-ch'].value=uach;},state.loadOptions.value.uaChTrackLevel);}// Get page properties details
|
1287
1337
|
const pageProperties=getDefaultPageProperties();state.page.path.value=pageProperties.path;state.page.referrer.value=pageProperties.referrer;state.page.referring_domain.value=pageProperties.referring_domain;state.page.search.value=pageProperties.search;state.page.title.value=pageProperties.title;state.page.url.value=pageProperties.url;state.page.tab_url.value=pageProperties.tab_url;});// Ad blocker detection
|
1288
1338
|
b(()=>{if(state.loadOptions.value.sendAdblockPage===true&&state.lifecycle.sourceConfigUrl.value!==undefined){detectAdBlockers(this.errorHandler,this.logger);}});}/**
|
@@ -1292,7 +1342,7 @@ b(()=>{if(state.loadOptions.value.sendAdblockPage===true&&state.lifecycle.source
|
|
1292
1342
|
const onPolyfillLoad=scriptId=>Boolean(scriptId)&&this.onReady();this.externalSrcLoader?.loadJSFile({url:state.loadOptions.value.polyfillURL??POLYFILL_URL,id:POLYFILL_SCRIPT_ID,async:true,timeout:POLYFILL_LOAD_TIMEOUT,callback:onPolyfillLoad});}else {this.onReady();}}/**
|
1293
1343
|
* Attach listeners to window to observe event that update capabilities state values
|
1294
1344
|
*/ // eslint-disable-next-line class-methods-use-this
|
1295
|
-
attachWindowListeners(){globalThis.addEventListener('offline',()=>{state.capabilities.isOnline.value=false;});globalThis.addEventListener('online',()=>{state.capabilities.isOnline.value=true;});// TODO: add
|
1345
|
+
attachWindowListeners(){globalThis.addEventListener('offline',()=>{state.capabilities.isOnline.value=false;});globalThis.addEventListener('online',()=>{state.capabilities.isOnline.value=true;});// TODO: add debounced listener for globalThis.onResize event and update state.context.screen.value
|
1296
1346
|
}/**
|
1297
1347
|
* Set the lifecycle status to next phase
|
1298
1348
|
*/ // eslint-disable-next-line class-methods-use-this
|
@@ -1301,12 +1351,6 @@ onReady(){this.detectBrowserCapabilities();state.lifecycle.status.value=Lifecycl
|
|
1301
1351
|
* @param error The error object
|
1302
1352
|
*/onError(error){if(this.errorHandler){this.errorHandler.onError(error,CAPABILITIES_MANAGER);}else {throw error;}}}
|
1303
1353
|
|
1304
|
-
// TODO: should we take the types from IdentifyTrait instead of any string key?
|
1305
|
-
// https://www.rudderstack.com/docs/event-spec/standard-events/identify/#identify-traits
|
1306
|
-
/**
|
1307
|
-
* Represents the options parameter in the APIs
|
1308
|
-
*/let RudderEventType=/*#__PURE__*/function(RudderEventType){RudderEventType["Page"]="page";RudderEventType["Track"]="track";RudderEventType["Identify"]="identify";RudderEventType["Alias"]="alias";RudderEventType["Group"]="group";return RudderEventType;}({});
|
1309
|
-
|
1310
1354
|
const CHANNEL='web';// These are the top-level elements in the standard RudderStack event spec
|
1311
1355
|
const TOP_LEVEL_ELEMENTS=['integrations','anonymousId','originalTimestamp'];// Reserved elements in the context of standard RudderStack event spec
|
1312
1356
|
// Typically, these elements are not allowed to be overridden by the user
|
@@ -1364,8 +1408,9 @@ rudderEvent.context=getMergedContext(rudderEvent.context,options);}};/**
|
|
1364
1408
|
* @param pageProps Page properties
|
1365
1409
|
* @param logger logger
|
1366
1410
|
* @returns Enriched RudderEvent object
|
1367
|
-
*/const getEnrichedEvent=(rudderEvent,options,pageProps,logger)=>{const commonEventData={//
|
1368
|
-
anonymousId
|
1411
|
+
*/const getEnrichedEvent=(rudderEvent,options,pageProps,logger)=>{const commonEventData={channel:CHANNEL,context:{traits:clone$1(state.session.userTraits.value),sessionId:state.session.sessionInfo.value.id||undefined,sessionStart:state.session.sessionInfo.value.sessionStart||undefined,consentManagement:{deniedConsentIds:clone$1(state.consents.data.value.deniedConsentIds)},'ua-ch':state.context['ua-ch'].value,app:state.context.app.value,library:state.context.library.value,userAgent:state.context.userAgent.value,os:state.context.os.value,locale:state.context.locale.value,screen:state.context.screen.value,campaign:clone$1(state.context.campaign.value),page:getContextPageProperties(pageProps)},originalTimestamp:getCurrentTimeFormatted(),integrations:DEFAULT_INTEGRATIONS_CONFIG,messageId:generateUUID(),userId:rudderEvent.userId||state.session.userId.value};if(state.storage.type.value===NO_STORAGE){// Generate new anonymous id for each request
|
1412
|
+
commonEventData.anonymousId=generateUUID();commonEventData.context.anonymousTracking=true;}else {// Type casting to string as the user session manager will take care of initializing the value
|
1413
|
+
commonEventData.anonymousId=state.session.anonymousUserId.value;}if(rudderEvent.type===RudderEventType.Identify){commonEventData.context.traits=state.storage.type.value!==NO_STORAGE?clone$1(state.session.userTraits.value):rudderEvent.context.traits;}if(rudderEvent.type===RudderEventType.Group){if(rudderEvent.groupId||state.session.groupId.value){commonEventData.groupId=rudderEvent.groupId||state.session.groupId.value;}if(rudderEvent.traits||state.session.groupTraits.value){commonEventData.traits=state.storage.type.value!==NO_STORAGE?clone$1(state.session.groupTraits.value):rudderEvent.traits;}}const processedEvent=mergeDeepRight(rudderEvent,commonEventData);// Set the default values for the event properties
|
1369
1414
|
// matching with v1.1 payload
|
1370
1415
|
if(processedEvent.event===undefined){processedEvent.event=null;}if(processedEvent.properties===undefined){processedEvent.properties=null;}processOptions(processedEvent,options);// TODO: We might not need this check altogether
|
1371
1416
|
checkForReservedElements(processedEvent,logger);// Update the integrations config for the event
|
@@ -1385,7 +1430,7 @@ class RudderEventFactory{constructor(logger){this.logger=logger;}/**
|
|
1385
1430
|
*/generateTrackEvent(event,properties,options){const trackEvent={properties,event,type:RudderEventType.Track};return getEnrichedEvent(trackEvent,options,undefined,this.logger);}/**
|
1386
1431
|
* Generate an 'identify' event based on the user-input fields
|
1387
1432
|
* @param options API options
|
1388
|
-
*/generateIdentifyEvent(options){const identifyEvent={type:RudderEventType.Identify};return getEnrichedEvent(identifyEvent,options,undefined,this.logger);}/**
|
1433
|
+
*/generateIdentifyEvent(userId,traits,options){const identifyEvent={userId,type:RudderEventType.Identify,context:{traits}};return getEnrichedEvent(identifyEvent,options,undefined,this.logger);}/**
|
1389
1434
|
* Generate an 'alias' event based on the user-input fields
|
1390
1435
|
* @param to New user ID
|
1391
1436
|
* @param from Old user ID
|
@@ -1394,11 +1439,11 @@ class RudderEventFactory{constructor(logger){this.logger=logger;}/**
|
|
1394
1439
|
enrichedEvent.userId=to??enrichedEvent.userId;return enrichedEvent;}/**
|
1395
1440
|
* Generate a 'group' event based on the user-input fields
|
1396
1441
|
* @param options API options
|
1397
|
-
*/generateGroupEvent(options){const groupEvent={type:RudderEventType.Group};return getEnrichedEvent(groupEvent,options,undefined,this.logger);}/**
|
1442
|
+
*/generateGroupEvent(groupId,traits,options){const groupEvent={type:RudderEventType.Group};if(groupId){groupEvent.groupId=groupId;}if(traits){groupEvent.traits=traits;}return getEnrichedEvent(groupEvent,options,undefined,this.logger);}/**
|
1398
1443
|
* Generates a new RudderEvent object based on the user-input fields
|
1399
1444
|
* @param event API event parameters object
|
1400
1445
|
* @returns A RudderEvent object
|
1401
|
-
*/create(event){let eventObj;switch(event.type){case RudderEventType.Page:eventObj=this.generatePageEvent(event.category,event.name,event.properties,event.options);break;case RudderEventType.Track:eventObj=this.generateTrackEvent(event.name,event.properties,event.options);break;case RudderEventType.Identify:eventObj=this.generateIdentifyEvent(event.options);break;case RudderEventType.Alias:eventObj=this.generateAliasEvent(event.to,event.from,event.options);break;case RudderEventType.Group:eventObj=this.generateGroupEvent(event.options);break;}return eventObj;}}
|
1446
|
+
*/create(event){let eventObj;switch(event.type){case RudderEventType.Page:eventObj=this.generatePageEvent(event.category,event.name,event.properties,event.options);break;case RudderEventType.Track:eventObj=this.generateTrackEvent(event.name,event.properties,event.options);break;case RudderEventType.Identify:eventObj=this.generateIdentifyEvent(event.userId,event.traits,event.options);break;case RudderEventType.Alias:eventObj=this.generateAliasEvent(event.to,event.from,event.options);break;case RudderEventType.Group:eventObj=this.generateGroupEvent(event.groupId,event.traits,event.options);break;}return eventObj;}}
|
1402
1447
|
|
1403
1448
|
/**
|
1404
1449
|
* A service to generate valid event payloads and queue them for processing
|
@@ -1410,7 +1455,7 @@ enrichedEvent.userId=to??enrichedEvent.userId;return enrichedEvent;}/**
|
|
1410
1455
|
* @param logger Logger object
|
1411
1456
|
*/constructor(eventRepository,userSessionManager,errorHandler,logger){this.eventRepository=eventRepository;this.userSessionManager=userSessionManager;this.errorHandler=errorHandler;this.logger=logger;this.eventFactory=new RudderEventFactory(this.logger);this.onError=this.onError.bind(this);}/**
|
1412
1457
|
* Initializes the event manager
|
1413
|
-
*/init(){this.eventRepository.init();
|
1458
|
+
*/init(){this.eventRepository.init();}/**
|
1414
1459
|
* Consumes a new incoming event
|
1415
1460
|
* @param event Incoming event data
|
1416
1461
|
*/addEvent(event){this.userSessionManager.refreshSession();const rudderEvent=this.eventFactory.create(event);if(rudderEvent){this.eventRepository.enqueue(rudderEvent,event.callback);}else {this.onError(new Error(EVENT_OBJECT_GENERATION_ERROR));}}/**
|
@@ -1418,21 +1463,6 @@ enrichedEvent.userId=to??enrichedEvent.userId;return enrichedEvent;}/**
|
|
1418
1463
|
* @param error The error object
|
1419
1464
|
*/onError(error,customMessage,shouldAlwaysThrow){if(this.errorHandler){this.errorHandler.onError(error,EVENT_MANAGER,customMessage,shouldAlwaysThrow);}else {throw error;}}}
|
1420
1465
|
|
1421
|
-
/**
|
1422
|
-
* A function to check given value is a number or not
|
1423
|
-
* @param num input value
|
1424
|
-
* @returns boolean
|
1425
|
-
*/const isNumber=num=>typeof num==='number'&&!Number.isNaN(num);/**
|
1426
|
-
* A function to check given number has minimum length or not
|
1427
|
-
* @param minimumLength minimum length
|
1428
|
-
* @param num input number
|
1429
|
-
* @returns boolean
|
1430
|
-
*/const hasMinLength=(minimumLength,num)=>num.toString().length>=minimumLength;/**
|
1431
|
-
* A function to check given value is a positive integer or not
|
1432
|
-
* @param num input value
|
1433
|
-
* @returns boolean
|
1434
|
-
*/const isPositiveInteger=num=>isNumber(num)&&num>=0&&Number.isInteger(num);
|
1435
|
-
|
1436
1466
|
const MIN_SESSION_ID_LENGTH=10;/**
|
1437
1467
|
* A function to validate current session and return true/false depending on that
|
1438
1468
|
* @returns boolean
|
@@ -1447,7 +1477,7 @@ const MIN_SESSION_ID_LENGTH=10;/**
|
|
1447
1477
|
* A function to generate new auto tracking session
|
1448
1478
|
* @param sessionTimeout current timestamp
|
1449
1479
|
* @returns SessionInfo
|
1450
|
-
*/const generateAutoTrackingSession=sessionTimeout=>{const timestamp=Date.now();const timeout=sessionTimeout||
|
1480
|
+
*/const generateAutoTrackingSession=sessionTimeout=>{const timestamp=Date.now();const timeout=sessionTimeout||DEFAULT_SESSION_TIMEOUT_MS;return {id:timestamp,// set the current timestamp
|
1451
1481
|
expiresAt:timestamp+timeout,// set the expiry time of the session
|
1452
1482
|
timeout,sessionStart:undefined,autoTrack:true};};/**
|
1453
1483
|
* A function to generate new manual tracking session
|
@@ -1456,19 +1486,19 @@ timeout,sessionStart:undefined,autoTrack:true};};/**
|
|
1456
1486
|
* @returns SessionInfo
|
1457
1487
|
*/const generateManualTrackingSession=(id,logger)=>{const sessionId=isManualSessionIdValid(id,logger)?id:generateSessionId();return {id:sessionId,sessionStart:undefined,manualTrack:true};};
|
1458
1488
|
|
1459
|
-
const userSessionStorageKeys={userId:'rl_user_id',userTraits:'rl_trait',anonymousUserId:'rl_anonymous_id',groupId:'rl_group_id',groupTraits:'rl_group_trait',initialReferrer:'rl_page_init_referrer',initialReferringDomain:'rl_page_init_referring_domain',sessionInfo:'rl_session'};
|
1489
|
+
const userSessionStorageKeys={userId:'rl_user_id',userTraits:'rl_trait',anonymousUserId:'rl_anonymous_id',groupId:'rl_group_id',groupTraits:'rl_group_trait',initialReferrer:'rl_page_init_referrer',initialReferringDomain:'rl_page_init_referring_domain',sessionInfo:'rl_session'};const defaultUserSessionValues={userId:'',userTraits:{},anonymousUserId:'',groupId:'',groupTraits:{},initialReferrer:'',initialReferringDomain:'',sessionInfo:{}};
|
1460
1490
|
|
1461
1491
|
class UserSessionManager{constructor(errorHandler,logger,pluginsManager,store){this.store=store;this.pluginsManager=pluginsManager;this.logger=logger;this.errorHandler=errorHandler;this.onError=this.onError.bind(this);}/**
|
1462
1492
|
* Initialize User session with values from storage
|
1463
1493
|
* @param store Selected store
|
1464
|
-
*/init(store){this.store=store;this.migrateStorageIfNeeded();// get the values from storage and set it again
|
1465
|
-
this.setUserId(this.getUserId()??
|
1494
|
+
*/init(store){if(!store){this.setDefaultValues();}else {this.store=store;this.migrateStorageIfNeeded();// get the values from storage and set it again
|
1495
|
+
this.setUserId(this.getUserId()??defaultUserSessionValues.userId);this.setUserTraits(this.getUserTraits()??defaultUserSessionValues.userTraits);this.setGroupId(this.getGroupId()??defaultUserSessionValues.groupId);this.setGroupTraits(this.getGroupTraits()??defaultUserSessionValues.groupTraits);this.setAnonymousId(this.getAnonymousId(state.loadOptions.value.anonymousIdOptions));const initialReferrer=this.getInitialReferrer();const initialReferringDomain=this.getInitialReferringDomain();if(initialReferrer&&initialReferringDomain){this.setInitialReferrer(initialReferrer);this.setInitialReferringDomain(initialReferringDomain);}else if(initialReferrer){this.setInitialReferrer(initialReferrer);this.setInitialReferringDomain(getReferringDomain(initialReferrer));}else {const referrer=getReferrer();this.setInitialReferrer(referrer);this.setInitialReferringDomain(getReferringDomain(referrer));}// Initialize session tracking
|
1466
1496
|
this.initializeSessionTracking();// Register the effect to sync with storage
|
1467
|
-
this.registerEffects();}migrateStorageIfNeeded(){if(!state.storage.migrate.value){return;}Object.values(userSessionStorageKeys).forEach(storageEntry=>{const migratedVal=this.pluginsManager?.invokeSingle('storage.migrate',storageEntry,this.store?.engine,this.logger);this.syncValueToStorage(storageEntry,migratedVal);});}/**
|
1497
|
+
this.registerEffects();}}setDefaultValues(){o(()=>{state.session.userId.value=defaultUserSessionValues.userId;state.session.userTraits.value=defaultUserSessionValues.userTraits;state.session.groupId.value=defaultUserSessionValues.groupId;state.session.groupTraits.value=defaultUserSessionValues.groupTraits;state.session.anonymousUserId.value=defaultUserSessionValues.anonymousUserId;state.session.initialReferrer.value=defaultUserSessionValues.initialReferrer;state.session.initialReferringDomain.value=defaultUserSessionValues.initialReferringDomain;state.session.sessionInfo.value=defaultUserSessionValues.sessionInfo;});}migrateStorageIfNeeded(){if(!state.storage.migrate.value){return;}Object.values(userSessionStorageKeys).forEach(storageEntry=>{const migratedVal=this.pluginsManager?.invokeSingle('storage.migrate',storageEntry,this.store?.engine,this.errorHandler,this.logger);this.syncValueToStorage(storageEntry,migratedVal);});}/**
|
1468
1498
|
* A function to initialize sessionTracking
|
1469
|
-
*/initializeSessionTracking(){const sessionInfo=this.getSessionFromStorage()??defaultSessionInfo;let finalAutoTrackingStatus=!(state.loadOptions.value.sessions.autoTrack===false||sessionInfo.manualTrack===true);let sessionTimeout;const configuredSessionTimeout=state.loadOptions.value.sessions.timeout;if(!isPositiveInteger(configuredSessionTimeout)){this.logger?.warn(TIMEOUT_NOT_NUMBER_WARNING(USER_SESSION_MANAGER,configuredSessionTimeout,
|
1499
|
+
*/initializeSessionTracking(){const sessionInfo=this.getSessionFromStorage()??defaultSessionInfo;let finalAutoTrackingStatus=!(state.loadOptions.value.sessions.autoTrack===false||sessionInfo.manualTrack===true);let sessionTimeout;const configuredSessionTimeout=state.loadOptions.value.sessions.timeout;if(!isPositiveInteger(configuredSessionTimeout)){this.logger?.warn(TIMEOUT_NOT_NUMBER_WARNING(USER_SESSION_MANAGER,configuredSessionTimeout,DEFAULT_SESSION_TIMEOUT_MS));sessionTimeout=DEFAULT_SESSION_TIMEOUT_MS;}else {sessionTimeout=configuredSessionTimeout;}if(sessionTimeout===0){this.logger?.warn(TIMEOUT_ZERO_WARNING(USER_SESSION_MANAGER));finalAutoTrackingStatus=false;}// In case user provides a timeout value greater than 0 but less than 10 seconds SDK will show a warning
|
1470
1500
|
// and will proceed with it
|
1471
|
-
if(sessionTimeout>0&&sessionTimeout<
|
1501
|
+
if(sessionTimeout>0&&sessionTimeout<MIN_SESSION_TIMEOUT_MS){this.logger?.warn(TIMEOUT_NOT_RECOMMENDED_WARNING(USER_SESSION_MANAGER,sessionTimeout,MIN_SESSION_TIMEOUT_MS));}state.session.sessionInfo.value={...sessionInfo,timeout:sessionTimeout,autoTrack:finalAutoTrackingStatus};// If auto session tracking is enabled start the session tracking
|
1472
1502
|
if(state.session.sessionInfo.value.autoTrack){this.startOrRenewAutoTracking();}}/**
|
1473
1503
|
* Handles error
|
1474
1504
|
* @param error The error object
|
@@ -1501,7 +1531,7 @@ if(state.session.sessionInfo.value.autoTrack){this.startOrRenewAutoTracking();}}
|
|
1501
1531
|
* 2. rudderAmpLinkerParam: value generated from linker query parm (rudderstack)
|
1502
1532
|
* using parseLinker util.
|
1503
1533
|
* 3. generateUUID: A new unique id is generated and assigned.
|
1504
|
-
*/setAnonymousId(anonymousId,rudderAmpLinkerParam){let finalAnonymousId=anonymousId;if(!finalAnonymousId&&rudderAmpLinkerParam){const linkerPluginsResult=this.pluginsManager?.invokeMultiple('userSession.anonymousIdGoogleLinker',rudderAmpLinkerParam);finalAnonymousId=linkerPluginsResult?.[0];}state.session.anonymousUserId.value=finalAnonymousId||this.generateAnonymousId();}/**
|
1534
|
+
*/setAnonymousId(anonymousId,rudderAmpLinkerParam){if(this.store){let finalAnonymousId=anonymousId;if(!finalAnonymousId&&rudderAmpLinkerParam){const linkerPluginsResult=this.pluginsManager?.invokeMultiple('userSession.anonymousIdGoogleLinker',rudderAmpLinkerParam);finalAnonymousId=linkerPluginsResult?.[0];}state.session.anonymousUserId.value=finalAnonymousId||this.generateAnonymousId();}}/**
|
1505
1535
|
* Generate a new anonymousId
|
1506
1536
|
* @returns string anonymousID
|
1507
1537
|
*/generateAnonymousId(){return generateUUID();}/**
|
@@ -1541,22 +1571,22 @@ const autoCapturedAnonymousId=this.pluginsManager?.invokeSingle('storage.getAnon
|
|
1541
1571
|
*/reset(resetAnonymousId,noNewSessionStart){const{manualTrack,autoTrack}=state.session.sessionInfo.value;o(()=>{state.session.userId.value='';state.session.userTraits.value={};state.session.groupId.value='';state.session.groupTraits.value={};if(resetAnonymousId){state.session.anonymousUserId.value='';}if(noNewSessionStart){return;}if(autoTrack){state.session.sessionInfo.value={};this.startOrRenewAutoTracking();}else if(manualTrack){this.startManualTrackingInternal();}});}/**
|
1542
1572
|
* Set user Id
|
1543
1573
|
* @param userId
|
1544
|
-
*/setUserId(userId){state.session.userId.value=userId;}/**
|
1574
|
+
*/setUserId(userId){if(this.store){state.session.userId.value=userId;}}/**
|
1545
1575
|
* Set user traits
|
1546
1576
|
* @param traits
|
1547
|
-
*/setUserTraits(traits){if(traits){state.session.userTraits.value=mergeDeepRight(state.session.userTraits.value??{},traits);}}/**
|
1577
|
+
*/setUserTraits(traits){if(traits&&this.store){state.session.userTraits.value=mergeDeepRight(state.session.userTraits.value??{},traits);}}/**
|
1548
1578
|
* Set group Id
|
1549
1579
|
* @param groupId
|
1550
|
-
*/setGroupId(groupId){state.session.groupId.value=groupId;}/**
|
1580
|
+
*/setGroupId(groupId){if(this.store){state.session.groupId.value=groupId;}}/**
|
1551
1581
|
* Set group traits
|
1552
1582
|
* @param traits
|
1553
|
-
*/setGroupTraits(traits){if(traits){state.session.groupTraits.value=mergeDeepRight(state.session.groupTraits.value??{},traits);}}/**
|
1583
|
+
*/setGroupTraits(traits){if(traits&&this.store){state.session.groupTraits.value=mergeDeepRight(state.session.groupTraits.value??{},traits);}}/**
|
1554
1584
|
* Set initial referrer
|
1555
1585
|
* @param referrer
|
1556
|
-
*/setInitialReferrer(referrer){state.session.initialReferrer.value=referrer;}/**
|
1586
|
+
*/setInitialReferrer(referrer){if(this.store){state.session.initialReferrer.value=referrer;}}/**
|
1557
1587
|
* Set initial referring domain
|
1558
1588
|
* @param referrer
|
1559
|
-
*/setInitialReferringDomain(referrer){state.session.initialReferringDomain.value=referrer;}/**
|
1589
|
+
*/setInitialReferringDomain(referrer){if(this.store){state.session.initialReferringDomain.value=referrer;}}/**
|
1560
1590
|
* A function to check for existing session details and depending on that create a new session.
|
1561
1591
|
*/startOrRenewAutoTracking(){if(hasSessionExpired(state.session.sessionInfo.value.expiresAt)){state.session.sessionInfo.value=generateAutoTrackingSession(state.session.sessionInfo.value.timeout);}else {const timestamp=Date.now();const timeout=state.session.sessionInfo.value.timeout;state.session.sessionInfo.value=mergeDeepRight(state.session.sessionInfo.value,{expiresAt:timestamp+timeout// set the expiry time of the session
|
1562
1592
|
});}}/**
|
@@ -1597,10 +1627,11 @@ b(()=>{if(state.nativeDestinations.clientDestinationsReady.value===true){this.de
|
|
1597
1627
|
// However, events will be enqueued for now.
|
1598
1628
|
// At the time of processing the events, the integrations config data from destinations
|
1599
1629
|
// is merged into the event object
|
1600
|
-
b(()=>{const shouldBufferDpEvents=state.loadOptions.value.bufferDataPlaneEventsUntilReady===true&&state.nativeDestinations.clientDestinationsReady.value===false;const hybridDestExist=state.nativeDestinations.activeDestinations.value.some(dest=>isHybridModeDestination(dest));if(hybridDestExist===false||shouldBufferDpEvents===false&&this.dataplaneEventsQueue?.
|
1630
|
+
b(()=>{const shouldBufferDpEvents=state.loadOptions.value.bufferDataPlaneEventsUntilReady===true&&state.nativeDestinations.clientDestinationsReady.value===false;const hybridDestExist=state.nativeDestinations.activeDestinations.value.some(dest=>isHybridModeDestination(dest));if(hybridDestExist===false||shouldBufferDpEvents===false&&this.dataplaneEventsQueue?.scheduleTimeoutActive!==true){this.dataplaneEventsQueue?.start();}});// Force start the data plane events queue processing after a timeout
|
1631
|
+
if(state.loadOptions.value.bufferDataPlaneEventsUntilReady===true){globalThis.setTimeout(()=>{if(this.dataplaneEventsQueue?.scheduleTimeoutActive!==true){this.dataplaneEventsQueue?.start();}},state.loadOptions.value.dataPlaneEventsBufferTimeout);}const dpQEvent=clone$1(event);this.pluginsManager.invokeSingle(`${DATA_PLANE_QUEUE_EXT_POINT_PREFIX}.enqueue`,state,this.dataplaneEventsQueue,dpQEvent,this.errorHandler,this.logger);const dQEvent=clone$1(event);this.pluginsManager.invokeSingle(`${DESTINATIONS_QUEUE_EXT_POINT_PREFIX}.enqueue`,state,this.destinationsEventsQueue,dQEvent,this.errorHandler,this.logger);// Invoke the callback if it exists
|
1601
1632
|
try{// Using the event sent to the data plane queue here
|
1602
1633
|
// to ensure the mutated (if any) event is sent to the callback
|
1603
|
-
callback?.(dpQEvent);}catch(error){this.onError(error,
|
1634
|
+
callback?.(dpQEvent);}catch(error){this.onError(error,API_CALLBACK_INVOKE_ERROR);}}/**
|
1604
1635
|
* Handles error
|
1605
1636
|
* @param error The error object
|
1606
1637
|
* @param customMessage a message
|
@@ -1611,7 +1642,7 @@ callback?.(dpQEvent);}catch(error){this.onError(error,'API Callback Invocation F
|
|
1611
1642
|
* Analytics class with lifecycle based on state ad user triggered events
|
1612
1643
|
*/class Analytics{preloadBuffer=new BufferQueue();/**
|
1613
1644
|
* Initialize services and components or use default ones if singletons
|
1614
|
-
*/constructor(){this.initialized=false;this.errorHandler=defaultErrorHandler;this.logger=defaultLogger;this.externalSrcLoader=new ExternalSrcLoader(this.errorHandler,this.logger);this.capabilitiesManager=new CapabilitiesManager(this.errorHandler,this.logger);this.httpClient=defaultHttpClient;this.load=this.load.bind(this);this.startLifecycle=this.startLifecycle.bind(this);this.prepareBrowserCapabilities=this.prepareBrowserCapabilities.bind(this);this.enqueuePreloadBufferEvents=this.enqueuePreloadBufferEvents.bind(this);this.processDataInPreloadBuffer=this.processDataInPreloadBuffer.bind(this);this.prepareInternalServices=this.prepareInternalServices.bind(this);this.loadConfig=this.loadConfig.bind(this);this.init=this.init.bind(this);this.loadPlugins=this.loadPlugins.bind(this);this.
|
1645
|
+
*/constructor(){this.initialized=false;this.errorHandler=defaultErrorHandler;this.logger=defaultLogger;this.externalSrcLoader=new ExternalSrcLoader(this.errorHandler,this.logger);this.capabilitiesManager=new CapabilitiesManager(this.errorHandler,this.logger);this.httpClient=defaultHttpClient;this.load=this.load.bind(this);this.startLifecycle=this.startLifecycle.bind(this);this.prepareBrowserCapabilities=this.prepareBrowserCapabilities.bind(this);this.enqueuePreloadBufferEvents=this.enqueuePreloadBufferEvents.bind(this);this.processDataInPreloadBuffer=this.processDataInPreloadBuffer.bind(this);this.prepareInternalServices=this.prepareInternalServices.bind(this);this.loadConfig=this.loadConfig.bind(this);this.init=this.init.bind(this);this.loadPlugins=this.loadPlugins.bind(this);this.onInitialized=this.onInitialized.bind(this);this.processBufferedEvents=this.processBufferedEvents.bind(this);this.loadDestinations=this.loadDestinations.bind(this);this.onDestinationsReady=this.onDestinationsReady.bind(this);this.onReady=this.onReady.bind(this);this.ready=this.ready.bind(this);this.page=this.page.bind(this);this.track=this.track.bind(this);this.identify=this.identify.bind(this);this.alias=this.alias.bind(this);this.group=this.group.bind(this);this.reset=this.reset.bind(this);this.getAnonymousId=this.getAnonymousId.bind(this);this.setAnonymousId=this.setAnonymousId.bind(this);this.getUserId=this.getUserId.bind(this);this.getUserTraits=this.getUserTraits.bind(this);this.getGroupId=this.getGroupId.bind(this);this.getGroupTraits=this.getGroupTraits.bind(this);this.startSession=this.startSession.bind(this);this.endSession=this.endSession.bind(this);this.getSessionId=this.getSessionId.bind(this);}/**
|
1615
1646
|
* Start application lifecycle if not already started
|
1616
1647
|
*/load(writeKey,dataPlaneUrl,loadOptions={}){if(state.lifecycle.status.value){return;}let clonedDataPlaneUrl=clone$1(dataPlaneUrl);let clonedLoadOptions=clone$1(loadOptions);// dataPlaneUrl is not provided
|
1617
1648
|
if(isObjectAndNotNull(dataPlaneUrl)){clonedLoadOptions=dataPlaneUrl;clonedDataPlaneUrl=undefined;}// Set initial state values
|
@@ -1621,8 +1652,8 @@ setExposedGlobal('state',state,writeKey);// Configure initial config of any serv
|
|
1621
1652
|
this.startLifecycle();}// Start lifecycle methods
|
1622
1653
|
/**
|
1623
1654
|
* Orchestrate the lifecycle of the application phases/status
|
1624
|
-
*/startLifecycle(){b(()=>{switch(state.lifecycle.status.value){case LifecycleStatus.Mounted:this.prepareBrowserCapabilities();break;case LifecycleStatus.BrowserCapabilitiesReady:// initialize the preloaded events enqueuing
|
1625
|
-
retrievePreloadBufferEvents(this);this.prepareInternalServices();this.loadConfig();break;case LifecycleStatus.Configured:this.loadPlugins();break;case LifecycleStatus.PluginsLoading:break;case LifecycleStatus.PluginsReady:this.init();break;case LifecycleStatus.Initialized:this.
|
1655
|
+
*/startLifecycle(){b(()=>{try{switch(state.lifecycle.status.value){case LifecycleStatus.Mounted:this.prepareBrowserCapabilities();break;case LifecycleStatus.BrowserCapabilitiesReady:// initialize the preloaded events enqueuing
|
1656
|
+
retrievePreloadBufferEvents(this);this.prepareInternalServices();this.loadConfig();break;case LifecycleStatus.Configured:this.loadPlugins();break;case LifecycleStatus.PluginsLoading:break;case LifecycleStatus.PluginsReady:this.init();break;case LifecycleStatus.Initialized:this.onInitialized();break;case LifecycleStatus.Loaded:this.loadDestinations();this.processBufferedEvents();break;case LifecycleStatus.DestinationsLoading:break;case LifecycleStatus.DestinationsReady:this.onDestinationsReady();break;case LifecycleStatus.Ready:this.onReady();break;default:break;}}catch(err){const issue='Failed to load the SDK';this.errorHandler.onError(getMutatedError(err,issue),ANALYTICS_CORE);}});}/**
|
1626
1657
|
* Load browser polyfill if required
|
1627
1658
|
*/prepareBrowserCapabilities(){this.capabilitiesManager.init();}/**
|
1628
1659
|
* Enqueue in SDK preload buffer events, used from preloadBuffer component
|
@@ -1635,41 +1666,53 @@ retrievePreloadBufferEvents(this);this.prepareInternalServices();this.loadConfig
|
|
1635
1666
|
*/init(){this.errorHandler.init(this.externalSrcLoader);// Initialize storage
|
1636
1667
|
this.storeManager?.init();this.clientDataStore=this.storeManager?.getStore(CLIENT_DATA_STORE_NAME);this.userSessionManager?.init(this.clientDataStore);// Initialize consent manager
|
1637
1668
|
if(state.consents.activeConsentManagerPluginName.value){this.pluginsManager?.invokeSingle(`consentManager.init`,state,this.storeManager,this.logger);}// Initialize event manager
|
1638
|
-
this.eventManager?.init()
|
1669
|
+
this.eventManager?.init();// Mark the SDK as initialized
|
1670
|
+
state.lifecycle.status.value=LifecycleStatus.Initialized;}/**
|
1639
1671
|
* Load plugins
|
1640
1672
|
*/loadPlugins(){this.pluginsManager?.init();// TODO: are we going to enable custom plugins to be passed as load options?
|
1641
1673
|
// registerCustomPlugins(state.loadOptions.value.customPlugins);
|
1642
1674
|
}/**
|
1643
|
-
* Trigger onLoaded callback if any is provided in config
|
1644
|
-
*/
|
1645
|
-
this.processDataInPreloadBuffer();//
|
1646
|
-
|
1647
|
-
if
|
1675
|
+
* Trigger onLoaded callback if any is provided in config & emit initialised event
|
1676
|
+
*/onInitialized(){// Process any preloaded events
|
1677
|
+
this.processDataInPreloadBuffer();// TODO: we need to avoid passing the window object to the callback function
|
1678
|
+
// as this will prevent us from supporting multiple SDK instances in the same page
|
1679
|
+
// Execute onLoaded callback if provided in load options
|
1680
|
+
if(isFunction(state.loadOptions.value.onLoaded)){state.loadOptions.value.onLoaded(globalThis.rudderanalytics);}// Set lifecycle state
|
1681
|
+
o(()=>{state.lifecycle.loaded.value=true;state.lifecycle.status.value=LifecycleStatus.Loaded;});this.initialized=true;// Emit an event to use as substitute to the onLoaded callback
|
1682
|
+
const initializedEvent=new CustomEvent('RSA_Initialised',{detail:{analyticsInstance:globalThis.rudderanalytics},bubbles:true,cancelable:true,composed:true});globalThis.document.dispatchEvent(initializedEvent);}/**
|
1683
|
+
* Emit ready event
|
1684
|
+
*/ // eslint-disable-next-line class-methods-use-this
|
1685
|
+
onReady(){// Emit an event to use as substitute to the ready callback
|
1686
|
+
const readyEvent=new CustomEvent('RSA_Ready',{detail:{analyticsInstance:globalThis.rudderanalytics},bubbles:true,cancelable:true,composed:true});globalThis.document.dispatchEvent(readyEvent);}/**
|
1648
1687
|
* Consume preloaded events buffer
|
1649
1688
|
*/processBufferedEvents(){// Process buffered events
|
1650
1689
|
state.eventBuffer.toBeProcessedArray.value.forEach(bufferedItem=>{const methodName=bufferedItem[0];if(isFunction(this[methodName])){this[methodName](...bufferedItem.slice(1));}});state.eventBuffer.toBeProcessedArray.value=[];}/**
|
1651
|
-
* Load device mode
|
1652
|
-
*/
|
1653
|
-
this.pluginsManager?.invokeSingle('nativeDestinations.setActiveDestinations',state,this.pluginsManager,this.logger);const totalDestinationsToLoad=state.nativeDestinations.activeDestinations.value.length;if(totalDestinationsToLoad===0){state.lifecycle.status.value=LifecycleStatus.DestinationsReady;return;}// Start loading native integration scripts and create instances
|
1654
|
-
state.lifecycle.status.value=LifecycleStatus.DestinationsLoading;this.pluginsManager?.invokeSingle('nativeDestinations.load',state,this.externalSrcLoader,this.logger);// Progress to next lifecycle phase if all native
|
1690
|
+
* Load device mode destinations
|
1691
|
+
*/loadDestinations(){// Set in state the desired activeDestinations to inject in DOM
|
1692
|
+
this.pluginsManager?.invokeSingle('nativeDestinations.setActiveDestinations',state,this.pluginsManager,this.errorHandler,this.logger);const totalDestinationsToLoad=state.nativeDestinations.activeDestinations.value.length;if(totalDestinationsToLoad===0){state.lifecycle.status.value=LifecycleStatus.DestinationsReady;return;}// Start loading native integration scripts and create instances
|
1693
|
+
state.lifecycle.status.value=LifecycleStatus.DestinationsLoading;this.pluginsManager?.invokeSingle('nativeDestinations.load',state,this.externalSrcLoader,this.errorHandler,this.logger);// Progress to next lifecycle phase if all native destinations are initialized or failed
|
1655
1694
|
b(()=>{const areAllDestinationsReady=totalDestinationsToLoad===0||state.nativeDestinations.initializedDestinations.value.length+state.nativeDestinations.failedDestinations.value.length===totalDestinationsToLoad;if(areAllDestinationsReady){o(()=>{state.lifecycle.status.value=LifecycleStatus.DestinationsReady;state.nativeDestinations.clientDestinationsReady.value=true;});}});}/**
|
1656
1695
|
* Invoke the ready callbacks if any exist
|
1657
1696
|
*/ // eslint-disable-next-line class-methods-use-this
|
1658
|
-
|
1697
|
+
onDestinationsReady(){state.eventBuffer.readyCallbacksArray.value.forEach(callback=>{try{callback();}catch(err){this.errorHandler.onError(err,ANALYTICS_CORE,READY_CALLBACK_INVOKE_ERROR);}});state.lifecycle.status.value=LifecycleStatus.Ready;}// End lifecycle methods
|
1659
1698
|
// Start consumer exposed methods
|
1660
|
-
ready(callback){const type='ready';this.errorHandler.leaveBreadcrumb(`New ${type} invocation`);if(!
|
1661
|
-
* If
|
1699
|
+
ready(callback){const type='ready';this.errorHandler.leaveBreadcrumb(`New ${type} invocation`);if(!state.lifecycle.loaded.value){state.eventBuffer.toBeProcessedArray.value.push([type,callback]);return;}if(!isFunction(callback)){this.logger.error(READY_API_CALLBACK_ERROR(READY_API));return;}/**
|
1700
|
+
* If destinations are loaded or no integration is available for loading
|
1662
1701
|
* execute the callback immediately else push the callbacks to a queue that
|
1663
1702
|
* will be executed after loading completes
|
1664
|
-
*/if(state.lifecycle.status.value===LifecycleStatus.Ready){callback();}else {state.eventBuffer.readyCallbacksArray.value.push(callback);}}page(payload){const type='page';this.errorHandler.leaveBreadcrumb(`New ${type} event`);state.metrics.triggered.value+=1;if(!state.lifecycle.loaded.value){state.eventBuffer.toBeProcessedArray.value.push([type,payload]);return;}this.eventManager?.addEvent({type:RudderEventType.Page,category:payload.category,name:payload.name,properties:payload.properties,options:payload.options,callback:payload.callback});// TODO: Maybe we should alter the behavior to send the ad-block page event even if the SDK is still loaded. It'll be pushed into the to be processed queue.
|
1703
|
+
*/if(state.lifecycle.status.value===LifecycleStatus.Ready){try{callback();}catch(err){this.errorHandler.onError(err,ANALYTICS_CORE,READY_CALLBACK_INVOKE_ERROR);}}else {state.eventBuffer.readyCallbacksArray.value.push(callback);}}page(payload){const type='page';this.errorHandler.leaveBreadcrumb(`New ${type} event`);state.metrics.triggered.value+=1;if(!state.lifecycle.loaded.value){state.eventBuffer.toBeProcessedArray.value.push([type,payload]);return;}this.eventManager?.addEvent({type:RudderEventType.Page,category:payload.category,name:payload.name,properties:payload.properties,options:payload.options,callback:payload.callback});// TODO: Maybe we should alter the behavior to send the ad-block page event even if the SDK is still loaded. It'll be pushed into the to be processed queue.
|
1665
1704
|
// Send automatic ad blocked page event if adblockers are detected on the page
|
1705
|
+
// Check page category to avoid infinite loop
|
1666
1706
|
if(state.capabilities.isAdBlocked.value===true&&payload.category!==ADBLOCK_PAGE_CATEGORY){const pageCallArgs={category:ADBLOCK_PAGE_CATEGORY,name:ADBLOCK_PAGE_NAME,properties:{// 'title' is intentionally omitted as it does not make sense
|
1667
1707
|
// in v3 implementation
|
1668
|
-
path:ADBLOCK_PAGE_PATH},options:state.loadOptions.value.sendAdblockPageOptions};this.page(pageCallArgs);}}track(payload){const type='track';this.errorHandler.leaveBreadcrumb(`New ${type} event`);state.metrics.triggered.value+=1;if(!state.lifecycle.loaded.value){state.eventBuffer.toBeProcessedArray.value.push([type,payload]);return;}this.eventManager?.addEvent({type:RudderEventType.Track,name:payload.name,properties:payload.properties,options:payload.options,callback:payload.callback});}identify(payload){const type='identify';this.errorHandler.leaveBreadcrumb(`New ${type} event`);state.metrics.triggered.value+=1;if(!state.lifecycle.loaded.value){state.eventBuffer.toBeProcessedArray.value.push([type,payload]);return;}const shouldResetSession=Boolean(payload.userId&&state.session.userId.value&&payload.userId!==state.session.userId.value);if(shouldResetSession){this.reset();}
|
1708
|
+
path:ADBLOCK_PAGE_PATH},options:state.loadOptions.value.sendAdblockPageOptions};this.page(pageCallArgs);}}track(payload){const type='track';this.errorHandler.leaveBreadcrumb(`New ${type} event`);state.metrics.triggered.value+=1;if(!state.lifecycle.loaded.value){state.eventBuffer.toBeProcessedArray.value.push([type,payload]);return;}this.eventManager?.addEvent({type:RudderEventType.Track,name:payload.name||undefined,properties:payload.properties,options:payload.options,callback:payload.callback});}identify(payload){const type='identify';this.errorHandler.leaveBreadcrumb(`New ${type} event`);state.metrics.triggered.value+=1;if(!state.lifecycle.loaded.value){state.eventBuffer.toBeProcessedArray.value.push([type,payload]);return;}const shouldResetSession=Boolean(payload.userId&&state.session.userId.value&&payload.userId!==state.session.userId.value);if(shouldResetSession){this.reset();}// `null` value indicates that previous user ID needs to be retained
|
1709
|
+
if(!isNull(payload.userId)){this.userSessionManager?.setUserId(payload.userId);}this.userSessionManager?.setUserTraits(payload.traits);this.eventManager?.addEvent({type:RudderEventType.Identify,userId:payload.userId,traits:payload.traits,options:payload.options,callback:payload.callback});}alias(payload){const type='alias';this.errorHandler.leaveBreadcrumb(`New ${type} event`);state.metrics.triggered.value+=1;if(!state.lifecycle.loaded.value){state.eventBuffer.toBeProcessedArray.value.push([type,payload]);return;}const previousId=payload.from??this.userSessionManager?.getUserId()??this.userSessionManager?.getAnonymousId();this.eventManager?.addEvent({type:RudderEventType.Alias,to:payload.to,from:previousId,options:payload.options,callback:payload.callback});}group(payload){const type='group';this.errorHandler.leaveBreadcrumb(`New ${type} event`);state.metrics.triggered.value+=1;if(!state.lifecycle.loaded.value){state.eventBuffer.toBeProcessedArray.value.push([type,payload]);return;}// `null` value indicates that previous group ID needs to be retained
|
1710
|
+
if(!isNull(payload.groupId)){this.userSessionManager?.setGroupId(payload.groupId);}this.userSessionManager?.setGroupTraits(payload.traits);this.eventManager?.addEvent({type:RudderEventType.Group,groupId:payload.groupId,traits:payload.traits,options:payload.options,callback:payload.callback});}reset(resetAnonymousId){const type='reset';this.errorHandler.leaveBreadcrumb(`New ${type} invocation, resetAnonymousId: ${resetAnonymousId}`);if(!state.lifecycle.loaded.value){state.eventBuffer.toBeProcessedArray.value.push([type,resetAnonymousId]);return;}this.userSessionManager?.reset(resetAnonymousId);}getAnonymousId(options){return this.userSessionManager?.getAnonymousId(options);}setAnonymousId(anonymousId,rudderAmpLinkerParam){const type='setAnonymousId';// Buffering is needed as setting the anonymous ID may require invoking the GoogleLinker plugin
|
1711
|
+
if(!state.lifecycle.loaded.value){state.eventBuffer.toBeProcessedArray.value.push([type,anonymousId,rudderAmpLinkerParam]);return;}this.userSessionManager?.setAnonymousId(anonymousId,rudderAmpLinkerParam);}// eslint-disable-next-line class-methods-use-this
|
1669
1712
|
getUserId(){return state.session.userId.value;}// eslint-disable-next-line class-methods-use-this
|
1670
1713
|
getUserTraits(){return state.session.userTraits.value;}// eslint-disable-next-line class-methods-use-this
|
1671
1714
|
getGroupId(){return state.session.groupId.value;}// eslint-disable-next-line class-methods-use-this
|
1672
|
-
getGroupTraits(){return state.session.groupTraits.value;}startSession(sessionId){this.userSessionManager?.start(sessionId);}endSession(){this.userSessionManager?.end();}// eslint-disable-next-line class-methods-use-this
|
1715
|
+
getGroupTraits(){return state.session.groupTraits.value;}startSession(sessionId){const type='startSession';this.errorHandler.leaveBreadcrumb(`New ${type} invocation`);if(!state.lifecycle.loaded.value){state.eventBuffer.toBeProcessedArray.value.push([type,sessionId]);return;}this.userSessionManager?.start(sessionId);}endSession(){const type='endSession';this.errorHandler.leaveBreadcrumb(`New ${type} invocation`);if(!state.lifecycle.loaded.value){state.eventBuffer.toBeProcessedArray.value.push([type]);return;}this.userSessionManager?.end();}// eslint-disable-next-line class-methods-use-this
|
1673
1716
|
getSessionId(){this.userSessionManager?.refreshSession();return state.session.sessionInfo.value?.id??null;}// End consumer exposed methods
|
1674
1717
|
}
|
1675
1718
|
|
@@ -1678,20 +1721,21 @@ getSessionId(){this.userSessionManager?.refreshSession();return state.session.se
|
|
1678
1721
|
* expose overloaded methods
|
1679
1722
|
* handle multiple Analytics instances
|
1680
1723
|
* consume SDK preload event buffer
|
1681
|
-
*/class RudderAnalytics{static globalSingleton=null;analyticsInstances={};defaultAnalyticsKey='';// Singleton with constructor bind methods
|
1682
|
-
constructor(){if(RudderAnalytics.globalSingleton){//
|
1683
|
-
|
1724
|
+
*/class RudderAnalytics{static globalSingleton=null;analyticsInstances={};defaultAnalyticsKey='';logger=defaultLogger;// Singleton with constructor bind methods
|
1725
|
+
constructor(){if(RudderAnalytics.globalSingleton){// START-NO-SONAR-SCAN
|
1726
|
+
// eslint-disable-next-line no-constructor-return
|
1727
|
+
return RudderAnalytics.globalSingleton;// END-NO-SONAR-SCAN
|
1728
|
+
}this.setDefaultInstanceKey=this.setDefaultInstanceKey.bind(this);this.getAnalyticsInstance=this.getAnalyticsInstance.bind(this);this.load=this.load.bind(this);this.ready=this.ready.bind(this);this.getPreloadBuffer=this.getPreloadBuffer.bind(this);this.triggerBufferedLoadEvent=this.triggerBufferedLoadEvent.bind(this);this.page=this.page.bind(this);this.track=this.track.bind(this);this.identify=this.identify.bind(this);this.alias=this.alias.bind(this);this.group=this.group.bind(this);this.reset=this.reset.bind(this);this.getAnonymousId=this.getAnonymousId.bind(this);this.setAnonymousId=this.setAnonymousId.bind(this);this.getUserId=this.getUserId.bind(this);this.getUserTraits=this.getUserTraits.bind(this);this.getGroupId=this.getGroupId.bind(this);this.getGroupTraits=this.getGroupTraits.bind(this);this.startSession=this.startSession.bind(this);this.endSession=this.endSession.bind(this);this.getSessionId=this.getSessionId.bind(this);RudderAnalytics.globalSingleton=this;// get the preloaded events before replacing global object
|
1684
1729
|
this.getPreloadBuffer();// start loading if a load event was buffered or wait for explicit load call
|
1685
|
-
this.triggerBufferedLoadEvent()
|
1686
|
-
return this;}/**
|
1730
|
+
this.triggerBufferedLoadEvent();}/**
|
1687
1731
|
* Set instance to use if no specific writeKey is provided in methods
|
1688
1732
|
* automatically for the first created instance
|
1689
1733
|
* TODO: to support multiple analytics instances in the near future
|
1690
1734
|
*/setDefaultInstanceKey(writeKey){if(isEmpty$1(this.analyticsInstances)){this.defaultAnalyticsKey=writeKey;}}/**
|
1691
1735
|
* Retrieve an existing analytics instance
|
1692
|
-
*/getAnalyticsInstance(writeKey){const instanceId=writeKey
|
1736
|
+
*/getAnalyticsInstance(writeKey){const instanceId=writeKey??this.defaultAnalyticsKey;const analyticsInstanceExists=Boolean(this.analyticsInstances[instanceId]);if(!analyticsInstanceExists){this.analyticsInstances[instanceId]=new Analytics();}return this.analyticsInstances[instanceId];}/**
|
1693
1737
|
* Create new analytics instance and trigger application lifecycle start
|
1694
|
-
*/load(writeKey,dataPlaneUrl,loadOptions){
|
1738
|
+
*/load(writeKey,dataPlaneUrl,loadOptions){if(!isString(writeKey)){this.logger.error(WRITE_KEY_NOT_A_STRING_ERROR(RS_APP,writeKey));return;}if(this.analyticsInstances[writeKey]){return;}this.setDefaultInstanceKey(writeKey);this.analyticsInstances[writeKey]=new Analytics();this.getAnalyticsInstance(writeKey).load(writeKey,dataPlaneUrl,loadOptions);}/**
|
1695
1739
|
* Get preloaded events in buffer queue if exists
|
1696
1740
|
*/ // eslint-disable-next-line class-methods-use-this
|
1697
1741
|
getPreloadBuffer(){const preloadedEventsArray=Array.isArray(globalThis.rudderanalytics)?globalThis.rudderanalytics:[];// Expose buffer to global objects
|
@@ -1714,6 +1758,6 @@ this.load.apply(null,loadEvent);}}/**
|
|
1714
1758
|
* Process alias arguments and forward to page call
|
1715
1759
|
*/alias(to,from,options,callback){this.getAnalyticsInstance().alias(aliasArgumentsToCallOptions(to,from,options,callback));}/**
|
1716
1760
|
* Process group arguments and forward to page call
|
1717
|
-
*/group(groupId,traits,options,callback){this.getAnalyticsInstance().group(groupArgumentsToCallOptions(groupId,traits,options,callback));}reset(resetAnonymousId){this.getAnalyticsInstance().reset(resetAnonymousId);}getAnonymousId(options){return this.getAnalyticsInstance().getAnonymousId(options);}setAnonymousId(anonymousId,rudderAmpLinkerParam){this.getAnalyticsInstance().setAnonymousId(anonymousId,rudderAmpLinkerParam);}getUserId(){return this.getAnalyticsInstance().getUserId();}getUserTraits(){return this.getAnalyticsInstance().getUserTraits();}getGroupId(){return this.getAnalyticsInstance().getGroupId();}getGroupTraits(){return this.getAnalyticsInstance().getGroupTraits();}startSession(sessionId){return this.getAnalyticsInstance().startSession(sessionId);}endSession(){return this.getAnalyticsInstance().endSession();}getSessionId(){return this.getAnalyticsInstance().getSessionId();}}
|
1761
|
+
*/group(groupId,traits,options,callback){if(arguments.length===0){this.logger.error(EMPTY_GROUP_CALL_ERROR(RS_APP));return;}this.getAnalyticsInstance().group(groupArgumentsToCallOptions(groupId,traits,options,callback));}reset(resetAnonymousId){this.getAnalyticsInstance().reset(resetAnonymousId);}getAnonymousId(options){return this.getAnalyticsInstance().getAnonymousId(options);}setAnonymousId(anonymousId,rudderAmpLinkerParam){this.getAnalyticsInstance().setAnonymousId(anonymousId,rudderAmpLinkerParam);}getUserId(){return this.getAnalyticsInstance().getUserId();}getUserTraits(){return this.getAnalyticsInstance().getUserTraits();}getGroupId(){return this.getAnalyticsInstance().getGroupId();}getGroupTraits(){return this.getAnalyticsInstance().getGroupTraits();}startSession(sessionId){return this.getAnalyticsInstance().startSession(sessionId);}endSession(){return this.getAnalyticsInstance().endSession();}getSessionId(){return this.getAnalyticsInstance().getSessionId();}}
|
1718
1762
|
|
1719
1763
|
export { CookieSameSite, LogLevel, PluginName, ResidencyServerRegion, RudderAnalytics, UaChTrackLevel };
|