@rudderstack/analytics-js 3.0.0-beta.13 → 3.0.0-beta.14
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 +18 -0
- package/dist/npm/index.d.ts +52 -16
- package/dist/npm/legacy/cjs/index.js +163 -121
- package/dist/npm/legacy/esm/index.js +163 -121
- package/dist/npm/legacy/umd/index.js +163 -121
- package/dist/npm/modern/bundled/cjs/index.js +157 -115
- package/dist/npm/modern/bundled/esm/index.js +157 -115
- package/dist/npm/modern/bundled/umd/index.js +157 -115
- package/dist/npm/modern/cjs/index.js +115 -84
- package/dist/npm/modern/esm/index.js +115 -84
- package/dist/npm/modern/umd/index.js +115 -84
- package/package.json +2 -2
@@ -56,8 +56,9 @@ function _has(prop,obj){return Object.prototype.hasOwnProperty.call(obj,prop);}
|
|
56
56
|
* R.type([]); //=> "Array"
|
57
57
|
* R.type(/[A-z]/); //=> "RegExp"
|
58
58
|
* R.type(() => {}); //=> "Function"
|
59
|
+
* R.type(async () => {}); //=> "AsyncFunction"
|
59
60
|
* R.type(undefined); //=> "Undefined"
|
60
|
-
*/var type=/*#__PURE__*/_curry1(function type(val){return val===null?'Null':val===undefined?'Undefined':Object.prototype.toString.call(val).slice(8,-1);});
|
61
|
+
*/var type=/*#__PURE__*/_curry1(function type(val){return val===null?'Null':val===undefined?'Undefined':Object.prototype.toString.call(val).slice(8,-1);});const type$1 = type;
|
61
62
|
|
62
63
|
function _isObject(x){return Object.prototype.toString.call(x)==='[object Object]';}
|
63
64
|
|
@@ -97,7 +98,7 @@ function _isString(x){return Object.prototype.toString.call(x)==='[object String
|
|
97
98
|
* @symb R.nth(-1, [a, b, c]) = c
|
98
99
|
* @symb R.nth(0, [a, b, c]) = a
|
99
100
|
* @symb R.nth(1, [a, b, c]) = b
|
100
|
-
*/var nth=/*#__PURE__*/_curry2(function nth(offset,list){var idx=offset<0?list.length+offset:offset;return _isString(list)?list.charAt(idx):list[idx];});
|
101
|
+
*/var nth=/*#__PURE__*/_curry2(function nth(offset,list){var idx=offset<0?list.length+offset:offset;return _isString(list)?list.charAt(idx):list[idx];});const nth$1 = nth;
|
101
102
|
|
102
103
|
function _cloneRegExp(pattern){return new RegExp(pattern.source,pattern.flags?pattern.flags:(pattern.global?'g':'')+(pattern.ignoreCase?'i':'')+(pattern.multiline?'m':'')+(pattern.sticky?'y':'')+(pattern.unicode?'u':'')+(pattern.dotAll?'s':''));}
|
103
104
|
|
@@ -110,7 +111,7 @@ function _cloneRegExp(pattern){return new RegExp(pattern.source,pattern.flags?pa
|
|
110
111
|
* @return {*} The copied value.
|
111
112
|
*/function _clone(value,deep,map){map||(map=new _ObjectMap());// this avoids the slower switch with a quick if decision removing some milliseconds in each run.
|
112
113
|
if(_isPrimitive(value)){return value;}var copy=function copy(copiedValue){// Check for circular and same references on the object graph and return its corresponding clone.
|
113
|
-
var cachedCopy=map.get(value);if(cachedCopy){return cachedCopy;}map.set(value,copiedValue);for(var key in value){if(Object.prototype.hasOwnProperty.call(value,key)){copiedValue[key]=deep?_clone(value[key],true,map):value[key];}}return copiedValue;};switch(type(value)){case'Object':return copy(Object.create(Object.getPrototypeOf(value)));case'Array':return copy([]);case'Date':return new Date(value.valueOf());case'RegExp':return _cloneRegExp(value);case'Int8Array':case'Uint8Array':case'Uint8ClampedArray':case'Int16Array':case'Uint16Array':case'Int32Array':case'Uint32Array':case'Float32Array':case'Float64Array':case'BigInt64Array':case'BigUint64Array':return value.slice();default:return value;}}function _isPrimitive(param){var type=typeof param;return param==null||type!='object'&&type!='function';}var _ObjectMap=/*#__PURE__*/function(){function _ObjectMap(){this.map={};this.length=0;}_ObjectMap.prototype.set=function(key,value){const hashedKey=this.hash(key);let bucket=this.map[hashedKey];if(!bucket){this.map[hashedKey]=bucket=[];}bucket.push([key,value]);this.length+=1;};_ObjectMap.prototype.hash=function(key){let hashedKey=[];for(var value in key){hashedKey.push(Object.prototype.toString.call(key[value]));}return hashedKey.join();};_ObjectMap.prototype.get=function(key){/**
|
114
|
+
var cachedCopy=map.get(value);if(cachedCopy){return cachedCopy;}map.set(value,copiedValue);for(var key in value){if(Object.prototype.hasOwnProperty.call(value,key)){copiedValue[key]=deep?_clone(value[key],true,map):value[key];}}return copiedValue;};switch(type$1(value)){case'Object':return copy(Object.create(Object.getPrototypeOf(value)));case'Array':return copy([]);case'Date':return new Date(value.valueOf());case'RegExp':return _cloneRegExp(value);case'Int8Array':case'Uint8Array':case'Uint8ClampedArray':case'Int16Array':case'Uint16Array':case'Int32Array':case'Uint32Array':case'Float32Array':case'Float64Array':case'BigInt64Array':case'BigUint64Array':return value.slice();default:return value;}}function _isPrimitive(param){var type=typeof param;return param==null||type!='object'&&type!='function';}var _ObjectMap=/*#__PURE__*/function(){function _ObjectMap(){this.map={};this.length=0;}_ObjectMap.prototype.set=function(key,value){const hashedKey=this.hash(key);let bucket=this.map[hashedKey];if(!bucket){this.map[hashedKey]=bucket=[];}bucket.push([key,value]);this.length+=1;};_ObjectMap.prototype.hash=function(key){let hashedKey=[];for(var value in key){hashedKey.push(Object.prototype.toString.call(key[value]));}return hashedKey.join();};_ObjectMap.prototype.get=function(key){/**
|
114
115
|
* depending on the number of objects to be cloned is faster to just iterate over the items in the map just because the hash function is so costly,
|
115
116
|
* on my tests this number is 180, anything above that using the hash function is faster.
|
116
117
|
*/if(this.length<=180){for(const p in this.map){const bucket=this.map[p];for(let i=0;i<bucket.length;i+=1){const element=bucket[i];if(element[0]===key){return element[1];}}}return;}const hashedKey=this.hash(key);const bucket=this.map[hashedKey];if(!bucket){return;}for(let i=0;i<bucket.length;i+=1){const element=bucket[i];if(element[0]===key){return element[1];}}};return _ObjectMap;}();
|
@@ -160,7 +161,7 @@ var cachedCopy=map.get(value);if(cachedCopy){return cachedCopy;}map.set(value,co
|
|
160
161
|
*
|
161
162
|
* R.paths([['a', 'b'], ['p', 0, 'q']], {a: {b: 2}, p: [{q: 3}]}); //=> [2, 3]
|
162
163
|
* R.paths([['a', 'b'], ['p', 'r']], {a: {b: 2}, p: [{q: 3}]}); //=> [2, undefined]
|
163
|
-
*/var paths=/*#__PURE__*/_curry2(function paths(pathsArray,obj){return pathsArray.map(function(paths){var val=obj;var idx=0;var p;while(idx<paths.length){if(val==null){return;}p=paths[idx];val=_isInteger(p)?nth(p,val):val[p];idx+=1;}return val;});});
|
164
|
+
*/var paths=/*#__PURE__*/_curry2(function paths(pathsArray,obj){return pathsArray.map(function(paths){var val=obj;var idx=0;var p;while(idx<paths.length){if(val==null){return;}p=paths[idx];val=_isInteger(p)?nth$1(p,val):val[p];idx+=1;}return val;});});const paths$1 = paths;
|
164
165
|
|
165
166
|
/**
|
166
167
|
* Retrieves the value at a given path. The nodes of the path can be arbitrary strings or non-negative integers.
|
@@ -185,7 +186,7 @@ var cachedCopy=map.get(value);if(cachedCopy){return cachedCopy;}map.set(value,co
|
|
185
186
|
* R.path(['a', 'b', -2], {a: {b: [1, 2, 3]}}); //=> 2
|
186
187
|
* R.path([2], {'2': 2}); //=> 2
|
187
188
|
* R.path([-2], {'-2': 'a'}); //=> undefined
|
188
|
-
*/var path=/*#__PURE__*/_curry2(function path(pathAr,obj){return paths([pathAr],obj)[0];});const path$1 = path;
|
189
|
+
*/var path=/*#__PURE__*/_curry2(function path(pathAr,obj){return paths$1([pathAr],obj)[0];});const path$1 = path;
|
189
190
|
|
190
191
|
/**
|
191
192
|
* Creates a new object with the own properties of the two provided objects. If
|
@@ -211,7 +212,7 @@ var cachedCopy=map.get(value);if(cachedCopy){return cachedCopy;}map.set(value,co
|
|
211
212
|
* { b: true, thing: 'bar', values: [15, 35] });
|
212
213
|
* //=> { a: true, b: true, thing: 'bar', values: [10, 20, 15, 35] }
|
213
214
|
* @symb R.mergeWithKey(f, { x: 1, y: 2 }, { y: 5, z: 3 }) = { x: 1, y: f('y', 2, 5), z: 3 }
|
214
|
-
*/var mergeWithKey=/*#__PURE__*/_curry3(function mergeWithKey(fn,l,r){var result={};var k;l=l||{};r=r||{};for(k in l){if(_has(k,l)){result[k]=_has(k,r)?fn(k,l[k],r[k]):l[k];}}for(k in r){if(_has(k,r)&&!_has(k,result)){result[k]=r[k];}}return result;});
|
215
|
+
*/var mergeWithKey=/*#__PURE__*/_curry3(function mergeWithKey(fn,l,r){var result={};var k;l=l||{};r=r||{};for(k in l){if(_has(k,l)){result[k]=_has(k,r)?fn(k,l[k],r[k]):l[k];}}for(k in r){if(_has(k,r)&&!_has(k,result)){result[k]=r[k];}}return result;});const mergeWithKey$1 = mergeWithKey;
|
215
216
|
|
216
217
|
/**
|
217
218
|
* Creates a new object with the own properties of the two provided objects.
|
@@ -240,7 +241,7 @@ var cachedCopy=map.get(value);if(cachedCopy){return cachedCopy;}map.set(value,co
|
|
240
241
|
* { a: true, c: { thing: 'foo', values: [10, 20] }},
|
241
242
|
* { b: true, c: { thing: 'bar', values: [15, 35] }});
|
242
243
|
* //=> { a: true, b: true, c: { thing: 'bar', values: [10, 20, 15, 35] }}
|
243
|
-
*/var mergeDeepWithKey=/*#__PURE__*/_curry3(function mergeDeepWithKey(fn,lObj,rObj){return mergeWithKey(function(k,lVal,rVal){if(_isObject(lVal)&&_isObject(rVal)){return mergeDeepWithKey(fn,lVal,rVal);}else {return fn(k,lVal,rVal);}},lObj,rObj);});
|
244
|
+
*/var mergeDeepWithKey=/*#__PURE__*/_curry3(function mergeDeepWithKey(fn,lObj,rObj){return mergeWithKey$1(function(k,lVal,rVal){if(_isObject(lVal)&&_isObject(rVal)){return mergeDeepWithKey(fn,lVal,rVal);}else {return fn(k,lVal,rVal);}},lObj,rObj);});const mergeDeepWithKey$1 = mergeDeepWithKey;
|
244
245
|
|
245
246
|
/**
|
246
247
|
* Creates a new object with the own properties of the two provided objects.
|
@@ -268,7 +269,7 @@ var cachedCopy=map.get(value);if(cachedCopy){return cachedCopy;}map.set(value,co
|
|
268
269
|
* { a: true, c: { values: [10, 20] }},
|
269
270
|
* { b: true, c: { values: [15, 35] }});
|
270
271
|
* //=> { a: true, b: true, c: { values: [10, 20, 15, 35] }}
|
271
|
-
*/var mergeDeepWith=/*#__PURE__*/_curry3(function mergeDeepWith(fn,lObj,rObj){return mergeDeepWithKey(function(k,lVal,rVal){return fn(lVal,rVal);},lObj,rObj);});const mergeDeepWith$1 = mergeDeepWith;
|
272
|
+
*/var mergeDeepWith=/*#__PURE__*/_curry3(function mergeDeepWith(fn,lObj,rObj){return mergeDeepWithKey$1(function(k,lVal,rVal){return fn(lVal,rVal);},lObj,rObj);});const mergeDeepWith$1 = mergeDeepWith;
|
272
273
|
|
273
274
|
/**
|
274
275
|
* Returns a partial copy of an object containing only the keys that satisfy
|
@@ -295,7 +296,8 @@ var cachedCopy=map.get(value);if(cachedCopy){return cachedCopy;}map.set(value,co
|
|
295
296
|
* A function to check given value is a function
|
296
297
|
* @param value input value
|
297
298
|
* @returns boolean
|
298
|
-
*/
|
299
|
+
*/ // eslint-disable-next-line @typescript-eslint/ban-types
|
300
|
+
const isFunction=value=>typeof value==='function'&&Boolean(value.constructor&&value.call&&value.apply);/**
|
299
301
|
* A function to check given value is a string
|
300
302
|
* @param value input value
|
301
303
|
* @returns boolean
|
@@ -413,9 +415,9 @@ payload.groupId=null;payload.traits=groupId;payload.options=!isFunction(traits)?
|
|
413
415
|
// Also, to clone the incoming object type arguments
|
414
416
|
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;};
|
415
417
|
|
416
|
-
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
|
418
|
+
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 EVENT_REPOSITORY='EventRepository';const EXTERNAL_SRC_LOADER='ExternalSrcLoader';const HTTP_CLIENT='HttpClient';const RS_APP='RudderStackApplication';const ANALYTICS_CORE='AnalyticsCore';
|
417
419
|
|
418
|
-
const APP_NAME='RudderLabs JavaScript SDK';const APP_VERSION='3.0.0-beta.
|
420
|
+
const APP_NAME='RudderLabs JavaScript SDK';const APP_VERSION='3.0.0-beta.14';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';
|
419
421
|
|
420
422
|
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';
|
421
423
|
|
@@ -499,9 +501,9 @@ const EXTERNAL_SOURCE_LOAD_ORIGIN='RS_JS_SDK';
|
|
499
501
|
*
|
500
502
|
* @returns
|
501
503
|
*/const insertScript=newScriptElement=>{// First try to add it to the head
|
502
|
-
const headElements=document.getElementsByTagName('head');if(headElements.length>0){headElements[0]
|
503
|
-
const scriptElements=document.getElementsByTagName('script');if(scriptElements.length>0&&scriptElements[0]
|
504
|
-
const headElement=document.createElement('head');headElement.appendChild(newScriptElement);const htmlElement=document.getElementsByTagName('html')[0];htmlElement
|
504
|
+
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
|
505
|
+
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
|
506
|
+
const headElement=document.createElement('head');headElement.appendChild(newScriptElement);const htmlElement=document.getElementsByTagName('html')[0];htmlElement?.insertBefore(headElement,htmlElement.firstChild);};/**
|
505
507
|
* Loads external js file as a script html tag
|
506
508
|
*
|
507
509
|
* @param {*} url The URL of the script to be loaded
|
@@ -519,7 +521,7 @@ timeoutID=globalThis.setTimeout(()=>{reject(new Error(SCRIPT_LOAD_TIMEOUT_ERROR(
|
|
519
521
|
* Service to load external resources/files
|
520
522
|
*/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);}/**
|
521
523
|
* Load external resource of type javascript
|
522
|
-
*/loadJSFile(config){const{url,id,timeout,async,callback,extraAttributes}=config;const isFireAndForget=!
|
524
|
+
*/loadJSFile(config){const{url,id,timeout,async,callback,extraAttributes}=config;const isFireAndForget=!isFunction(callback);jsFileLoader(url,id,timeout||this.timeout,async,extraAttributes).then(id=>{if(!isFireAndForget){callback(id);}}).catch(err=>{this.onError(err);if(!isFireAndForget){callback();}});}/**
|
523
525
|
* Handle errors
|
524
526
|
*/onError(error){if(this.hasErrorHandler){this.errorHandler?.onError(error,EXTERNAL_SRC_LOADER);}else {throw error;}}}
|
525
527
|
|
@@ -555,7 +557,7 @@ const BUILD_TYPE='modern';const SDK_CDN_BASE_URL='https://cdn.rudderlabs.com';co
|
|
555
557
|
// const PLUGINS_BASE_URL = `${SDK_CDN_BASE_URL}/latest/${CDN_ARCH_VERSION_DIR}/${BUILD_TYPE}/${CDN_PLUGINS_DIR}`;
|
556
558
|
const DEFAULT_CONFIG_BE_URL='https://api.rudderstack.com';
|
557
559
|
|
558
|
-
const DEFAULT_ERROR_REPORTING_PROVIDER='bugsnag';const DEFAULT_STORAGE_ENCRYPTION_VERSION='v3';const ConsentManagersToPluginNameMap={oneTrust:'OneTrustConsentManager',ketch:'KetchConsentManager'};const ErrorReportingProvidersToPluginNameMap={[DEFAULT_ERROR_REPORTING_PROVIDER]:'Bugsnag'};const StorageEncryptionVersionsToPluginNameMap={[DEFAULT_STORAGE_ENCRYPTION_VERSION]:'StorageEncryption',legacy:'StorageEncryptionLegacy'};
|
560
|
+
const DEFAULT_ERROR_REPORTING_PROVIDER='bugsnag';const DEFAULT_STORAGE_ENCRYPTION_VERSION='v3';const ConsentManagersToPluginNameMap={oneTrust:'OneTrustConsentManager',ketch:'KetchConsentManager',custom:'CustomConsentManager'};const ErrorReportingProvidersToPluginNameMap={[DEFAULT_ERROR_REPORTING_PROVIDER]:'Bugsnag'};const StorageEncryptionVersionsToPluginNameMap={[DEFAULT_STORAGE_ENCRYPTION_VERSION]:'StorageEncryption',legacy:'StorageEncryptionLegacy'};
|
559
561
|
|
560
562
|
const defaultLoadOptions={logLevel:'ERROR',configUrl:DEFAULT_CONFIG_BE_URL,loadIntegration:true,sessions:{autoTrack:true,timeout:DEFAULT_SESSION_TIMEOUT_MS},sameSiteCookie:'Lax',polyfillIfRequired:true,integrations:{All:true},useBeacon:false,beaconQueueOptions:{},destinationsQueueOptions:{},queueOptions:{},lockIntegrationsVersion:false,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=a(clone$1(defaultLoadOptions));
|
561
563
|
|
@@ -571,11 +573,11 @@ const sourceConfigState=a(undefined);
|
|
571
573
|
|
572
574
|
const lifecycleState={activeDataplaneUrl:a(undefined),integrationsCDNPath:a(DEST_SDK_BASE_URL),pluginsCDNPath:a(PLUGINS_BASE_URL),sourceConfigUrl:a(undefined),status:a(undefined),initialized:a(false),logLevel:a('ERROR'),loaded:a(false),readyCallbacks:a([]),writeKey:a(undefined),dataPlaneUrl:a(undefined)};
|
573
575
|
|
574
|
-
const consentsState={
|
576
|
+
const consentsState={enabled:a(false),initialized:a(false),data:a({}),activeConsentManagerPluginName:a(undefined),preConsent:a({enabled:false}),postConsent:a({})};
|
575
577
|
|
576
578
|
const metricsState={retries:a(0),dropped:a(0),sent:a(0),queued:a(0),triggered:a(0)};
|
577
579
|
|
578
|
-
const contextState={app:a({name:APP_NAME,namespace:APP_NAMESPACE,version:APP_VERSION}),traits:a(null),library:a({name:APP_NAME,version:APP_VERSION}),userAgent:a(''),device:a(null),network:a(null),os:a({name:'',version:''}),locale:a(null),screen:a({density:0,width:0,height:0,innerWidth:0,innerHeight:0}),'ua-ch':a(undefined)};
|
580
|
+
const contextState={app:a({name:APP_NAME,namespace:APP_NAMESPACE,version:APP_VERSION}),traits:a(null),library:a({name:APP_NAME,version:APP_VERSION}),userAgent:a(''),device:a(null),network:a(null),os:a({name:'',version:''}),locale:a(null),screen:a({density:0,width:0,height:0,innerWidth:0,innerHeight:0}),'ua-ch':a(undefined),timezone:a(undefined)};
|
579
581
|
|
580
582
|
const nativeDestinationsState={configuredDestinations:a([]),activeDestinations:a([]),loadOnlyIntegrations:a({}),failedDestinations:a([]),loadIntegration:a(true),initializedDestinations:a([]),clientDestinationsReady:a(false),integrationsConfig:a({})};
|
581
583
|
|
@@ -590,7 +592,7 @@ const defaultStateValues={capabilities:capabilitiesState,consents:consentsState,
|
|
590
592
|
// to next or return the value if it is the last one instead of an array per
|
591
593
|
// plugin that is the normal invoke
|
592
594
|
// TODO: add invoke method for extension point that we know only one plugin can be used. add invokeMultiple and invokeSingle methods
|
593
|
-
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(
|
595
|
+
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(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.
|
594
596
|
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
|
595
597
|
// do some unified pre-process before application starts.
|
596
598
|
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
|
@@ -640,7 +642,7 @@ destination.config.useNativeSDK===true);const isHybridModeDestination=destinatio
|
|
640
642
|
|
641
643
|
/**
|
642
644
|
* List of plugin names that are loaded as dynamic imports in modern builds
|
643
|
-
*/const pluginNamesList=['BeaconQueue','Bugsnag','DeviceModeDestinations','DeviceModeTransformation','ErrorReporting','ExternalAnonymousId','GoogleLinker','KetchConsentManager','NativeDestinationQueue','OneTrustConsentManager','StorageEncryption','StorageEncryptionLegacy','StorageMigrator','XhrQueue'];
|
645
|
+
*/const pluginNamesList=['BeaconQueue','Bugsnag','CustomConsentManager','DeviceModeDestinations','DeviceModeTransformation','ErrorReporting','ExternalAnonymousId','GoogleLinker','KetchConsentManager','NativeDestinationQueue','OneTrustConsentManager','StorageEncryption','StorageEncryptionLegacy','StorageMigrator','XhrQueue'];
|
644
646
|
|
645
647
|
const COOKIE_STORAGE='cookieStorage';const LOCAL_STORAGE='localStorage';const SESSION_STORAGE='sessionStorage';const MEMORY_STORAGE='memoryStorage';const NO_STORAGE='none';
|
646
648
|
|
@@ -719,11 +721,11 @@ const sortByTime=(a,b)=>a.time-b.time;const RETRY_QUEUE='RetryQueue';/**
|
|
719
721
|
* @param {QueueProcessCallback} fn The function to call in order to process an item added to the queue
|
720
722
|
*/class RetryQueue{constructor(name,options,queueProcessCb,storeManager,storageType=LOCAL_STORAGE,logger,queueBatchItemsSizeCalculatorCb){this.storeManager=storeManager;this.logger=logger;this.name=name;this.id=generateUUID();this.processQueueCb=queueProcessCb;this.batchSizeCalcCb=queueBatchItemsSizeCalculatorCb;this.maxItems=options.maxItems||DEFAULT_MAX_ITEMS;this.maxAttempts=options.maxAttempts||DEFAULT_MAX_RETRY_ATTEMPTS;this.batch={enabled:false};this.configureBatchMode(options);this.backoff={minRetryDelay:options.minRetryDelay||DEFAULT_MIN_RETRY_DELAY_MS,maxRetryDelay:options.maxRetryDelay||DEFAULT_MAX_RETRY_DELAY_MS,factor:options.backoffFactor||DEFAULT_BACKOFF_FACTOR,jitter:options.backoffJitter||DEFAULT_BACKOFF_JITTER};// painstakingly tuned. that's why they're not "easily" configurable
|
721
723
|
this.timeouts={ackTimer:DEFAULT_ACK_TIMER_MS,reclaimTimer:DEFAULT_RECLAIM_TIMER_MS,reclaimTimeout:DEFAULT_RECLAIM_TIMEOUT_MS,reclaimWait:DEFAULT_RECLAIM_WAIT_MS};this.schedule=new Schedule();this.processId='0';// Set up our empty queues
|
722
|
-
this.store=this.storeManager.setStore({id:this.id,name:this.name,validKeys:QueueStatuses,type:storageType});this.
|
724
|
+
this.store=this.storeManager.setStore({id:this.id,name:this.name,validKeys:QueueStatuses,type:storageType});this.setDefaultQueueEntries();// bind recurring tasks for ease of use
|
723
725
|
this.ack=this.ack.bind(this);this.checkReclaim=this.checkReclaim.bind(this);this.processHead=this.processHead.bind(this);this.flushBatch=this.flushBatch.bind(this);// Attach visibility change listener to flush the queue
|
724
|
-
this.attachListeners();this.scheduleTimeoutActive=false;}configureBatchMode(options){this.batchingInProgress=false;if(!isObjectLiteralAndNotNull(options.batch)){return;}const batchOptions=options.batch;this.batch.enabled=batchOptions.enabled===true;if(this.batch.enabled){// Set upper cap on the batch payload size
|
725
|
-
this.batch.maxSize=Math.min(batchOptions.maxSize??DEFAULT_MAX_BATCH_SIZE_BYTES,DEFAULT_MAX_BATCH_SIZE_BYTES);this.batch.maxItems=batchOptions.maxItems??DEFAULT_MAX_BATCH_ITEMS;this.batch.flushInterval=batchOptions.flushInterval??DEFAULT_BATCH_FLUSH_INTERVAL_MS;}}attachListeners(){if(this.batch.enabled){globalThis.addEventListener('visibilitychange',()=>{if(document.visibilityState==='hidden'){this.flushBatch();}});}}
|
726
|
-
|
726
|
+
this.attachListeners();this.scheduleTimeoutActive=false;}setDefaultQueueEntries(){this.setStorageEntry(QueueStatuses.IN_PROGRESS,{});this.setStorageEntry(QueueStatuses.QUEUE,[]);this.setStorageEntry(QueueStatuses.BATCH_QUEUE,[]);}configureBatchMode(options){this.batchingInProgress=false;if(!isObjectLiteralAndNotNull(options.batch)){return;}const batchOptions=options.batch;this.batch.enabled=batchOptions.enabled===true;if(this.batch.enabled){// Set upper cap on the batch payload size
|
727
|
+
this.batch.maxSize=Math.min(batchOptions.maxSize??DEFAULT_MAX_BATCH_SIZE_BYTES,DEFAULT_MAX_BATCH_SIZE_BYTES);this.batch.maxItems=batchOptions.maxItems??DEFAULT_MAX_BATCH_ITEMS;this.batch.flushInterval=batchOptions.flushInterval??DEFAULT_BATCH_FLUSH_INTERVAL_MS;}}attachListeners(){if(this.batch.enabled){globalThis.addEventListener('visibilitychange',()=>{if(document.visibilityState==='hidden'){this.flushBatch();}});}}getStorageEntry(name){return this.store.get(name??this.name);}// TODO: fix the type of different queues to be the same if possible
|
728
|
+
setStorageEntry(name,value){this.store.set(name??this.name,value??[]);}/**
|
727
729
|
* Stops processing the queue
|
728
730
|
*/stop(){this.schedule.cancelAll();this.scheduleTimeoutActive=false;}/**
|
729
731
|
* Starts processing the queue
|
@@ -731,7 +733,7 @@ setQueue(name,value){this.store.set(name??this.name,value??[]);}/**
|
|
731
733
|
* Configures the timeout handler for flushing the batch queue
|
732
734
|
*/scheduleFlushBatch(){if(this.batch.enabled&&this.batch?.flushInterval){if(this.flushBatchTaskId){this.schedule.cancel(this.flushBatchTaskId);}this.flushBatchTaskId=this.schedule.run(this.flushBatch,this.batch.flushInterval,ScheduleModes.ASAP);}}/**
|
733
735
|
* Flushes the batch queue
|
734
|
-
*/flushBatch(){if(!this.batchingInProgress){this.batchingInProgress=true;let batchQueue=this.
|
736
|
+
*/flushBatch(){if(!this.batchingInProgress){this.batchingInProgress=true;let batchQueue=this.getStorageEntry(QueueStatuses.BATCH_QUEUE)??[];if(batchQueue.length>0){batchQueue=batchQueue.slice(-batchQueue.length);const batchEntry=this.genQueueItem(batchQueue.map(queueItem=>queueItem.item));this.setStorageEntry(QueueStatuses.BATCH_QUEUE,[]);this.pushToMainQueue(batchEntry);}this.batchingInProgress=false;// Re-schedule the flush task
|
735
737
|
this.scheduleFlushBatch();}}/**
|
736
738
|
* Decides whether to retry. Overridable.
|
737
739
|
*
|
@@ -748,10 +750,10 @@ if(curEntry){this.pushToMainQueue(curEntry);}}/**
|
|
748
750
|
* Handles a new item added to the retry queue when batching is enabled
|
749
751
|
* @param entry New item added to the retry queue
|
750
752
|
* @returns Undefined or batch entry object
|
751
|
-
*/handleNewItemForBatch(entry){let curEntry;let batchQueue=this.
|
753
|
+
*/handleNewItemForBatch(entry){let curEntry;let batchQueue=this.getStorageEntry(QueueStatuses.BATCH_QUEUE)??[];if(!this.batchingInProgress){this.batchingInProgress=true;batchQueue=batchQueue.slice(-batchQueue.length);batchQueue.push(entry);const batchDispatchInfo=this.getBatchDispInfo(batchQueue);// if batch criteria is met, queue the batch events to the main queue and clear batch queue
|
752
754
|
if(batchDispatchInfo.criteriaMet||batchDispatchInfo.criteriaExceeded){let batchItems;if(batchDispatchInfo.criteriaExceeded){batchItems=batchQueue.slice(0,batchQueue.length-1).map(queueItem=>queueItem.item);batchQueue=[entry];}else {batchItems=batchQueue.map(queueItem=>queueItem.item);batchQueue=[];}curEntry=this.genQueueItem(batchItems);// re-attach the timeout handler
|
753
755
|
this.scheduleFlushBatch();}this.batchingInProgress=false;}else {batchQueue.push(entry);}// update the batch queue
|
754
|
-
this.
|
756
|
+
this.setStorageEntry(QueueStatuses.BATCH_QUEUE,batchQueue);return curEntry;}pushToMainQueue(curEntry){let queue=this.getStorageEntry(QueueStatuses.QUEUE)??[];queue=queue.slice(-(this.maxItems-1));queue.push(curEntry);queue=queue.sort(sortByTime);this.setStorageEntry(QueueStatuses.QUEUE,queue);if(this.scheduleTimeoutActive){this.processHead();}}/**
|
755
757
|
* Adds an item to the queue
|
756
758
|
*
|
757
759
|
* @param {Object} itemData The item to process
|
@@ -772,28 +774,28 @@ this.setQueue(QueueStatuses.BATCH_QUEUE,batchQueue);return curEntry;}pushToMainQ
|
|
772
774
|
* @returns Batch dispatch info
|
773
775
|
*/getBatchDispInfo(batchItems){let lengthCriteriaMet=false;let lengthCriteriaExceeded=false;const configuredBatchMaxItems=this.batch?.maxItems;if(isDefined(configuredBatchMaxItems)){lengthCriteriaMet=batchItems.length===configuredBatchMaxItems;lengthCriteriaExceeded=batchItems.length>configuredBatchMaxItems;}if(lengthCriteriaMet||lengthCriteriaExceeded){return {criteriaMet:lengthCriteriaMet,criteriaExceeded:lengthCriteriaExceeded};}let sizeCriteriaMet=false;let sizeCriteriaExceeded=false;const configuredBatchMaxSize=this.batch?.maxSize;if(isDefined(configuredBatchMaxSize)&&isDefined(this.batchSizeCalcCb)){const curBatchSize=this.batchSizeCalcCb(batchItems.map(queueItem=>queueItem.item));sizeCriteriaMet=curBatchSize===configuredBatchMaxSize;sizeCriteriaExceeded=curBatchSize>configuredBatchMaxSize;}return {criteriaMet:sizeCriteriaMet,criteriaExceeded:sizeCriteriaExceeded};}processHead(){// cancel the scheduled task if it exists
|
774
776
|
this.schedule.cancel(this.processId);// Pop the head off the queue
|
775
|
-
let queue=this.
|
776
|
-
const processItemCallback=(el,id)=>(err,res)=>{const inProgress=this.
|
777
|
+
let queue=this.getStorageEntry(QueueStatuses.QUEUE)??[];const inProgress=this.getStorageEntry(QueueStatuses.IN_PROGRESS)??{};const now=this.schedule.now();const toRun=[];// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
778
|
+
const processItemCallback=(el,id)=>(err,res)=>{const inProgress=this.getStorageEntry(QueueStatuses.IN_PROGRESS)??{};delete inProgress[id];this.setStorageEntry(QueueStatuses.IN_PROGRESS,inProgress);if(err){this.requeue(el.item,el.attemptNumber+1,err,el.id);}};const enqueueItem=(el,id)=>{toRun.push({item:el.item,done:processItemCallback(el,id),attemptNumber:el.attemptNumber});};let inProgressSize=Object.keys(inProgress).length;// eslint-disable-next-line no-plusplus
|
777
779
|
while(queue.length>0&&queue[0].time<=now&&inProgressSize++<this.maxItems){const el=queue.shift();if(el){const id=generateUUID();// Save this to the in progress map
|
778
|
-
inProgress[id]={item:el.item,attemptNumber:el.attemptNumber,time:this.schedule.now()};enqueueItem(el,id);}}this.
|
780
|
+
inProgress[id]={item:el.item,attemptNumber:el.attemptNumber,time:this.schedule.now()};enqueueItem(el,id);}}this.setStorageEntry(QueueStatuses.QUEUE,queue);this.setStorageEntry(QueueStatuses.IN_PROGRESS,inProgress);toRun.forEach(el=>{// TODO: handle processQueueCb timeout
|
779
781
|
try{const willBeRetried=this.shouldRetry(el.item,el.attemptNumber+1);this.processQueueCb(el.item,el.done,el.attemptNumber,this.maxAttempts,willBeRetried);}catch(err){this.logger?.error(RETRY_QUEUE_PROCESS_ERROR(RETRY_QUEUE),err);}});// re-read the queue in case the process function finished immediately or added another item
|
780
|
-
queue=this.
|
781
|
-
ack(){this.
|
782
|
+
queue=this.getStorageEntry(QueueStatuses.QUEUE)??[];this.schedule.cancel(this.processId);if(queue.length>0){const nextProcessExecutionTime=queue[0].time-now;this.processId=this.schedule.run(this.processHead,nextProcessExecutionTime,ScheduleModes.ASAP);}}// Ack continuously to prevent other tabs from claiming our queue
|
783
|
+
ack(){this.setStorageEntry(QueueStatuses.ACK,this.schedule.now());this.setStorageEntry(QueueStatuses.RECLAIM_START,null);this.setStorageEntry(QueueStatuses.RECLAIM_END,null);this.schedule.run(this.ack,this.timeouts.ackTimer,ScheduleModes.ASAP);}reclaim(id){const other=this.storeManager.setStore({id,name:this.name,validKeys:QueueStatuses,type:LOCAL_STORAGE});const our={queue:this.getStorageEntry(QueueStatuses.QUEUE)??[]};const their={inProgress:other.get(QueueStatuses.IN_PROGRESS)??{},batchQueue:other.get(QueueStatuses.BATCH_QUEUE)??[],queue:other.get(QueueStatuses.QUEUE)??[]};const trackMessageIds=[];const addConcatQueue=(queue,incrementAttemptNumberBy)=>{const concatIterator=el=>{const id=el.id??generateUUID();if(trackMessageIds.includes(id));else {our.queue.push({item:el.item,attemptNumber:el.attemptNumber+incrementAttemptNumberBy,time:this.schedule.now(),id});trackMessageIds.push(id);}};if(Array.isArray(queue)){queue.forEach(concatIterator);}else if(queue){Object.values(queue).forEach(concatIterator);}};// add their queue to ours, resetting run-time to immediate and copying the attempt#
|
782
784
|
addConcatQueue(their.queue,0);// Process batch queue items
|
783
785
|
if(this.batch.enabled){their.batchQueue.forEach(el=>{const id=el.id??generateUUID();if(trackMessageIds.includes(id));else {this.enqueue(el);trackMessageIds.push(id);}});}else {// if batching is not enabled in the current instance, add those items to the main queue directly
|
784
786
|
addConcatQueue(their.batchQueue,0);}// if the queue is abandoned, all the in-progress are failed. retry them immediately and increment the attempt#
|
785
|
-
addConcatQueue(their.inProgress,1);our.queue=our.queue.sort(sortByTime);this.
|
786
|
-
this.
|
787
|
+
addConcatQueue(their.inProgress,1);our.queue=our.queue.sort(sortByTime);this.setStorageEntry(QueueStatuses.QUEUE,our.queue);// remove all keys one by on next tick to avoid NS_ERROR_STORAGE_BUSY error
|
788
|
+
this.clearQueueEntries(other,1);// process the new items we claimed
|
787
789
|
this.processHead();}// eslint-disable-next-line class-methods-use-this
|
788
|
-
|
790
|
+
clearQueueEntries(other,localStorageBackoff){this.removeStorageEntry(other,0,localStorageBackoff);}removeStorageEntry(store,entryIdx,backoff,attempt=1){const maxAttempts=2;globalThis.setTimeout(()=>{const queueEntryKeys=Object.keys(QueueStatuses);const entry=QueueStatuses[queueEntryKeys[entryIdx]];try{store.remove(entry);// clear the next entry
|
789
791
|
if(entryIdx+1<queueEntryKeys.length){this.removeStorageEntry(store,entryIdx+1,backoff);}}catch(err){const storageBusyErr='NS_ERROR_STORAGE_BUSY';const isLocalStorageBusy=err.name===storageBusyErr||err.code===storageBusyErr||err.code===0x80630001;if(isLocalStorageBusy&&attempt<maxAttempts){// Try clearing the same entry again with some extra delay
|
790
792
|
this.removeStorageEntry(store,entryIdx,backoff+40,attempt+1);}else {this.logger?.error(RETRY_QUEUE_ENTRY_REMOVE_ERROR(RETRY_QUEUE,entry,attempt),err);}// clear the next entry
|
791
793
|
if(attempt===maxAttempts&&entryIdx+1<queueEntryKeys.length){this.removeStorageEntry(store,entryIdx+1,backoff);}}},backoff);}checkReclaim(){const createReclaimStartTask=store=>()=>{if(store.get(QueueStatuses.RECLAIM_END)!==this.id){return;}if(store.get(QueueStatuses.RECLAIM_START)!==this.id){return;}this.reclaim(store.id);};const createReclaimEndTask=store=>()=>{if(store.get(QueueStatuses.RECLAIM_START)!==this.id){return;}store.set(QueueStatuses.RECLAIM_END,this.id);this.schedule.run(createReclaimStartTask(store),this.timeouts.reclaimWait,ScheduleModes.ABANDON);};const tryReclaim=store=>{store.set(QueueStatuses.RECLAIM_START,this.id);store.set(QueueStatuses.ACK,this.schedule.now());this.schedule.run(createReclaimEndTask(store),this.timeouts.reclaimWait,ScheduleModes.ABANDON);};const findOtherQueues=name=>{const res=[];const storage=this.store.getOriginalEngine();for(let i=0;i<storage.length;i++){const k=storage.key(i);const parts=k?k.split('.'):[];if(parts.length!==3){// eslint-disable-next-line no-continue
|
792
794
|
continue;}if(parts[0]!==name){// eslint-disable-next-line no-continue
|
793
795
|
continue;}if(parts[2]!==QueueStatuses.ACK){// eslint-disable-next-line no-continue
|
794
|
-
continue;}res.push(this.storeManager.setStore({id:parts[1],name,validKeys:QueueStatuses,type:LOCAL_STORAGE}));}return res;};findOtherQueues(this.name).forEach(store=>{if(store.id===this.id){return;}if(this.schedule.now()-store.get(QueueStatuses.ACK)<this.timeouts.reclaimTimeout){return;}tryReclaim(store);});this.schedule.run(this.checkReclaim,this.timeouts.reclaimTimer,ScheduleModes.RESCHEDULE);}}
|
796
|
+
continue;}res.push(this.storeManager.setStore({id:parts[1],name,validKeys:QueueStatuses,type:LOCAL_STORAGE}));}return res;};findOtherQueues(this.name).forEach(store=>{if(store.id===this.id){return;}if(this.schedule.now()-store.get(QueueStatuses.ACK)<this.timeouts.reclaimTimeout){return;}tryReclaim(store);});this.schedule.run(this.checkReclaim,this.timeouts.reclaimTimer,ScheduleModes.RESCHEDULE);}clear(){this.schedule.cancelAll();this.setDefaultQueueEntries();}}
|
795
797
|
|
796
|
-
const pluginName$
|
798
|
+
const pluginName$e='BeaconQueue';const BeaconQueue=()=>({name:pluginName$e,deps:[],initialize:state=>{state.plugins.loadedPlugins.value=[...state.plugins.loadedPlugins.value,pluginName$e];},dataplaneEventsQueue:{/**
|
797
799
|
* Initialize the queue for delivery
|
798
800
|
* @param state Application state
|
799
801
|
* @param httpClient http client instance
|
@@ -844,16 +846,24 @@ event.context='Script load failures';}// eslint-disable-next-line no-param-reass
|
|
844
846
|
event.severity='error';};const onError=state=>{const metadataSource=state.source.value?.id;return event=>{try{// Discard the event if it's not originated at the SDK
|
845
847
|
if(!isRudderSDKError(event)){return false;}enhanceErrorEventMutator(event,metadataSource);return true;}catch{// Drop the error event if it couldn't be filtered as
|
846
848
|
// it is most likely a non-SDK error
|
847
|
-
return false;}};};const getReleaseStage=()=>{const host=globalThis.location.hostname;return host&&DEV_HOSTS.includes(host)?'development':'production';};const getGlobalBugsnagLibInstance=()=>globalThis[BUGSNAG_LIB_INSTANCE_GLOBAL_KEY_NAME];const getNewClient=(state,logger)=>{const globalBugsnagLibInstance=getGlobalBugsnagLibInstance();const clientConfig={apiKey:API_KEY,appVersion:'3.0.0-beta.
|
849
|
+
return false;}};};const getReleaseStage=()=>{const host=globalThis.location.hostname;return host&&DEV_HOSTS.includes(host)?'development':'production';};const getGlobalBugsnagLibInstance=()=>globalThis[BUGSNAG_LIB_INSTANCE_GLOBAL_KEY_NAME];const getNewClient=(state,logger)=>{const globalBugsnagLibInstance=getGlobalBugsnagLibInstance();const clientConfig={apiKey:API_KEY,appVersion:'3.0.0-beta.14',// Set SDK version as the app version from build config
|
848
850
|
metaData:{SDK:{name:'JS',installType:'npm'}},beforeSend:onError(state),autoCaptureSessions:false,// auto capture sessions is disabled
|
849
851
|
collectUserIp:false,// collecting user's IP is disabled
|
850
852
|
// enabledBreadcrumbTypes: ['error', 'log', 'user'], // for v7 and above
|
851
853
|
maxEvents:100,maxBreadcrumbs:40,releaseStage:getReleaseStage(),user:{id:state.lifecycle.writeKey.value},logger,networkBreadcrumbsEnabled:false};const client=globalBugsnagLibInstance(clientConfig);return client;};const isApiKeyValid=apiKey=>{const isAPIKeyValid=!(apiKey.startsWith('{{')||apiKey.endsWith('}}')||apiKey.length===0);return isAPIKeyValid;};const loadBugsnagSDK=(externalSrcLoader,logger)=>{const isNotLoaded=GLOBAL_LIBRARY_OBJECT_NAMES.every(globalKeyName=>!globalThis[globalKeyName]);if(!isNotLoaded){return;}externalSrcLoader.loadJSFile({url:BUGSNAG_CDN_URL,id:ERROR_REPORT_PROVIDER_NAME_BUGSNAG,callback:id=>{if(!id){logger?.error(BUGSNAG_SDK_LOAD_ERROR(BUGSNAG_PLUGIN));}}});};const initBugsnagClient=(state,promiseResolve,promiseReject,logger,time=0)=>{const globalBugsnagLibInstance=getGlobalBugsnagLibInstance();if(typeof globalBugsnagLibInstance==='function'){if(isValidVersion(globalBugsnagLibInstance)){const client=getNewClient(state,logger);promiseResolve(client);}}else if(time>=MAX_WAIT_FOR_SDK_LOAD_MS){promiseReject(new Error(BUGSNAG_SDK_LOAD_TIMEOUT_ERROR(MAX_WAIT_FOR_SDK_LOAD_MS)));}else {// Try to initialize the client after a delay
|
852
854
|
globalThis.setTimeout(initBugsnagClient,SDK_LOAD_POLL_INTERVAL_MS,state,promiseResolve,promiseReject,logger,time+SDK_LOAD_POLL_INTERVAL_MS);}};const getAppStateForMetadata=state=>{const stateStr=stringifyWithoutCircular(state,false,APP_STATE_EXCLUDE_KEYS);return stateStr!==null?JSON.parse(stateStr):undefined;};
|
853
855
|
|
854
|
-
const pluginName$
|
856
|
+
const pluginName$d='Bugsnag';const Bugsnag=()=>({name:pluginName$d,deps:[],initialize:state=>{state.plugins.loadedPlugins.value=[...state.plugins.loadedPlugins.value,pluginName$d];},errorReportingProvider:{init:(state,externalSrcLoader,logger)=>new Promise((resolve,reject)=>{// If API key token is not parsed or invalid, don't proceed to initialize the client
|
855
857
|
if(!isApiKeyValid(API_KEY)){reject(new Error(BUGSNAG_API_KEY_VALIDATION_ERROR(API_KEY)));return;}loadBugsnagSDK(externalSrcLoader,logger);initBugsnagClient(state,resolve,reject,logger);}),notify:(client,error,state,logger)=>{client?.notify(error,{metaData:{state:getAppStateForMetadata(state)}});},breadcrumb:(client,message,logger)=>{client?.leaveBreadcrumb(message);}}});
|
856
858
|
|
859
|
+
/* eslint-disable @typescript-eslint/no-unused-vars */ /* eslint-disable no-param-reassign */const pluginName$c='CustomConsentManager';const CustomConsentManager=()=>({name:pluginName$c,deps:[],initialize:state=>{state.plugins.loadedPlugins.value=[...state.plugins.loadedPlugins.value,pluginName$c];},consentManager:{init(state,logger){// Nothing to initialize
|
860
|
+
},updateConsentsInfo(state,storeManager,logger){// Nothing to update. Already provided by the user
|
861
|
+
},isDestinationConsented(state,destConfig,errorHandler,logger){// if (!state.consents.initialized.value) {
|
862
|
+
// return true;
|
863
|
+
// }
|
864
|
+
// TODO: Implement this
|
865
|
+
return true;}}});
|
866
|
+
|
857
867
|
const DIR_NAME$19='AdobeAnalytics';const DISPLAY_NAME$19='Adobe Analytics';
|
858
868
|
|
859
869
|
const DIR_NAME$18='Amplitude';const DISPLAY_NAME$18='Amplitude';
|
@@ -1042,7 +1052,7 @@ state.nativeDestinations.loadOnlyIntegrations.value=clone$1(state.loadOptions.va
|
|
1042
1052
|
const configSupportedDestinations=state.nativeDestinations.configuredDestinations.value.filter(configDest=>{if(destDisplayNamesToFileNamesMap[configDest.displayName]){return true;}errorHandler?.onError(new Error(DESTINATION_NOT_SUPPORTED_ERROR(configDest.userFriendlyId)),DEVICE_MODE_DESTINATIONS_PLUGIN);return false;});// Filter destinations that are disabled through load options
|
1043
1053
|
const destinationsToLoad=filterDestinations(state.nativeDestinations.loadOnlyIntegrations.value,configSupportedDestinations);const consentedDestinations=destinationsToLoad.filter(dest=>// if consent manager is not configured, then default to load the destination
|
1044
1054
|
pluginsManager.invokeSingle(`consentManager.isDestinationConsented`,state,dest.config,errorHandler,logger)??true);state.nativeDestinations.activeDestinations.value=consentedDestinations;},load(state,externalSrcLoader,errorHandler,logger,externalScriptOnLoad){const integrationsCDNPath=state.lifecycle.integrationsCDNPath.value;const activeDestinations=state.nativeDestinations.activeDestinations.value;activeDestinations.forEach(dest=>{const sdkName=destDisplayNamesToFileNamesMap[dest.displayName];const destSDKIdentifier=`${sdkName}_RS`;// this is the name of the object loaded on the window
|
1045
|
-
const sdkTypeName=sdkName;if(
|
1055
|
+
const sdkTypeName=sdkName;if(sdkTypeName&&!isDestinationSDKMounted(destSDKIdentifier,sdkTypeName)){const destSdkURL=`${integrationsCDNPath}/${sdkName}.min.js`;externalSrcLoader.loadJSFile({url:destSdkURL,id:dest.userFriendlyId,callback:externalScriptOnLoad??(id=>{if(!id){logger?.error(DESTINATION_SDK_LOAD_ERROR(DEVICE_MODE_DESTINATIONS_PLUGIN,dest.userFriendlyId));state.nativeDestinations.failedDestinations.value=[...state.nativeDestinations.failedDestinations.value,dest];}else {initializeDestination(dest,state,destSDKIdentifier,sdkTypeName,errorHandler,logger);}}),timeout:SCRIPT_LOAD_TIMEOUT_MS});}else if(sdkTypeName){initializeDestination(dest,state,destSDKIdentifier,sdkTypeName,errorHandler,logger);}else {logger?.error(DESTINATION_SDK_LOAD_ERROR(DEVICE_MODE_DESTINATIONS_PLUGIN,dest.displayName));}});}}});
|
1046
1056
|
|
1047
1057
|
const DEFAULT_TRANSFORMATION_QUEUE_OPTIONS={minRetryDelay:500,backoffFactor:2,maxAttempts:3};const REQUEST_TIMEOUT_MS$1=10*1000;// 10 seconds
|
1048
1058
|
const QUEUE_NAME$2='rudder';const DMT_PLUGIN='DeviceModeTransformationPlugin';
|
@@ -1087,7 +1097,9 @@ const AMP_LINKER_ANONYMOUS_ID_KEY='rs_amp_id';
|
|
1087
1097
|
*
|
1088
1098
|
* @param {string} str
|
1089
1099
|
* @returns {number} crc32
|
1090
|
-
*/const crc32=str=>{const crcTable=makeCRCTable();let crc=0^-1;for(let i=0;i<str.length;i++){
|
1100
|
+
*/const crc32=str=>{const crcTable=makeCRCTable();let crc=0^-1;for(let i=0;i<str.length;i++){// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
1101
|
+
// @ts-ignore
|
1102
|
+
crc=crc>>>8^crcTable[(crc^str.charCodeAt(i))&0xff];}return (crc^-1)>>>0;};
|
1091
1103
|
|
1092
1104
|
/**
|
1093
1105
|
* An interface to fetch user device details.
|
@@ -1127,7 +1139,7 @@ return null;}const version=Number(parts.shift());if(version!==VALID_VERSION){ret
|
|
1127
1139
|
* @param {string} serializedIds
|
1128
1140
|
*
|
1129
1141
|
* @return {!Object<string, string>}
|
1130
|
-
*/const deserialize=serializedIds=>{const keyValuePairs={};const params=serializedIds.split(DELIMITER);for(let i=0;i<params.length;i+=2){const key=params[i];const valid=KEY_VALIDATOR.test(key);if(valid){keyValuePairs[key]=decode$1(params[i+1]);}}return keyValuePairs;};/**
|
1142
|
+
*/const deserialize=serializedIds=>{if(!serializedIds){return {};}const keyValuePairs={};const params=serializedIds.split(DELIMITER);for(let i=0;i<params.length;i+=2){const key=params[i];const valid=KEY_VALIDATOR.test(key);if(valid){keyValuePairs[key]=decode$1(params[i+1]);}}return keyValuePairs;};/**
|
1131
1143
|
* Generates a semi-unique value for page visitor.
|
1132
1144
|
*
|
1133
1145
|
* @return {string}
|
@@ -1159,7 +1171,7 @@ return crc.toString(36);};/**
|
|
1159
1171
|
* @param {string} value
|
1160
1172
|
*
|
1161
1173
|
* @return {?Object<string, string>}
|
1162
|
-
*/const parseLinker=value=>{const linkerObj=parseLinkerParamValue(value);if(!linkerObj){return null;}const{checksum,serializedIds}=linkerObj;if(!isCheckSumValid(serializedIds,checksum)){return null;}return deserialize(serializedIds);};
|
1174
|
+
*/const parseLinker=value=>{const linkerObj=parseLinkerParamValue(value);if(!linkerObj){return null;}const{checksum,serializedIds}=linkerObj;if(!serializedIds||!checksum||!isCheckSumValid(serializedIds,checksum)){return null;}return deserialize(serializedIds);};
|
1163
1175
|
|
1164
1176
|
const pluginName$7='GoogleLinker';const GoogleLinker=()=>({name:pluginName$7,initialize:state=>{state.plugins.loadedPlugins.value=[...state.plugins.loadedPlugins.value,pluginName$7];},userSession:{anonymousIdGoogleLinker(rudderAmpLinkerParam){if(!rudderAmpLinkerParam){return null;}const parsedAnonymousIdObj=rudderAmpLinkerParam?parseLinker(rudderAmpLinkerParam):null;return parsedAnonymousIdObj?parsedAnonymousIdObj[AMP_LINKER_ANONYMOUS_ID_KEY]:null;}}});
|
1165
1177
|
|
@@ -1179,18 +1191,18 @@ const consentPurposes={};Object.entries(consentCookieData).forEach(pEntry=>{cons
|
|
1179
1191
|
* Gets the consent data in the format expected by the application state
|
1180
1192
|
* @param ketchConsentData Consent data derived from the consent cookie
|
1181
1193
|
* @returns Consent data
|
1182
|
-
*/const getConsentData=ketchConsentData=>{const
|
1194
|
+
*/const getConsentData=ketchConsentData=>{const allowedConsentIds=[];const deniedConsentIds=[];if(ketchConsentData){Object.entries(ketchConsentData).forEach(e=>{const purposeCode=e[0];const isConsented=e[1];if(isConsented){allowedConsentIds.push(purposeCode);}else {deniedConsentIds.push(purposeCode);}});}return {allowedConsentIds,deniedConsentIds};};const updateConsentStateFromData=(state,ketchConsentData)=>{const consentData=getConsentData(ketchConsentData);state.consents.initialized.value=isDefined(ketchConsentData);state.consents.data.value=consentData;};
|
1183
1195
|
|
1184
|
-
const pluginName$6='KetchConsentManager';const KetchConsentManager=()=>({name:pluginName$6,deps:[],initialize:state=>{state.plugins.loadedPlugins.value=[...state.plugins.loadedPlugins.value,pluginName$6];},consentManager:{init(state,
|
1196
|
+
const pluginName$6='KetchConsentManager';const KetchConsentManager=()=>({name:pluginName$6,deps:[],initialize:state=>{state.plugins.loadedPlugins.value=[...state.plugins.loadedPlugins.value,pluginName$6];},consentManager:{init(state,logger){// getKetchUserConsentedPurposes returns current ketch opted-in purposes
|
1185
1197
|
// This will be helpful for debugging
|
1186
|
-
globalThis.getKetchUserConsentedPurposes=()=>state.consents.data.value.
|
1198
|
+
globalThis.getKetchUserConsentedPurposes=()=>state.consents.data.value.allowedConsentIds?.slice();// getKetchUserDeniedPurposes returns current ketch opted-out purposes
|
1187
1199
|
// This will be helpful for debugging
|
1188
1200
|
globalThis.getKetchUserDeniedPurposes=()=>state.consents.data.value.deniedConsentIds?.slice();// updateKetchConsent callback function to update current consent purpose state
|
1189
1201
|
// this will be called from ketch rudderstack plugin
|
1190
|
-
globalThis.updateKetchConsent=ketchConsentData=>{updateConsentStateFromData(state,ketchConsentData);}
|
1191
|
-
let ketchConsentData;if(!isUndefined(globalThis.ketchConsent)){ketchConsentData=globalThis.ketchConsent;}else {ketchConsentData=getKetchConsentData(storeManager,logger);}updateConsentStateFromData(state,ketchConsentData);},isDestinationConsented(state,destConfig,errorHandler,logger){
|
1202
|
+
globalThis.updateKetchConsent=ketchConsentData=>{updateConsentStateFromData(state,ketchConsentData);};},updateConsentsInfo(state,storeManager,logger){// retrieve consent data and update the state
|
1203
|
+
let ketchConsentData;if(!isUndefined(globalThis.ketchConsent)){ketchConsentData=globalThis.ketchConsent;}else {ketchConsentData=getKetchConsentData(storeManager,logger);}updateConsentStateFromData(state,ketchConsentData);},isDestinationConsented(state,destConfig,errorHandler,logger){if(!state.consents.initialized.value){return true;}const allowedConsentIds=state.consents.data.value.allowedConsentIds;try{const{ketchConsentPurposes}=destConfig;// If the destination do not have this mapping events will be sent.
|
1192
1204
|
if(!ketchConsentPurposes||ketchConsentPurposes.length===0){return true;}const purposes=ketchConsentPurposes.map(p=>p.purpose).filter(n=>n);// Check if any of the destination's mapped ketch purposes are consented by the user in the browser.
|
1193
|
-
const containsAnyOfConsent=purposes.some(element=>
|
1205
|
+
const containsAnyOfConsent=purposes.some(element=>allowedConsentIds.includes(element.trim()));return containsAnyOfConsent;}catch(err){errorHandler?.onError(err,KETCH_CONSENT_MANAGER_PLUGIN,DESTINATION_CONSENT_STATUS_ERROR$1);return true;}}}});
|
1194
1206
|
|
1195
1207
|
const DEFAULT_QUEUE_OPTIONS={maxItems:100};const QUEUE_NAME$1='rudder_destinations_events';const NATIVE_DESTINATION_QUEUE_PLUGIN='NativeDestinationQueuePlugin';
|
1196
1208
|
|
@@ -1240,18 +1252,19 @@ const ONETRUST_ACCESS_ERROR=context=>`${context}${LOG_CONTEXT_SEPARATOR}Failed t
|
|
1240
1252
|
|
1241
1253
|
const ONETRUST_CONSENT_MANAGER_PLUGIN='OneTrustConsentManagerPlugin';
|
1242
1254
|
|
1243
|
-
const pluginName$4='OneTrustConsentManager';const OneTrustConsentManager=()=>({name:pluginName$4,deps:[],initialize:state=>{state.plugins.loadedPlugins.value=[...state.plugins.loadedPlugins.value,pluginName$4];},consentManager:{init(state,
|
1255
|
+
const pluginName$4='OneTrustConsentManager';const OneTrustConsentManager=()=>({name:pluginName$4,deps:[],initialize:state=>{state.plugins.loadedPlugins.value=[...state.plugins.loadedPlugins.value,pluginName$4];},consentManager:{init(state,logger){// Nothing to initialize
|
1256
|
+
},updateConsentsInfo(state,storeManager,logger){if(!globalThis.OneTrust||!globalThis.OnetrustActiveGroups){logger?.error(ONETRUST_ACCESS_ERROR(ONETRUST_CONSENT_MANAGER_PLUGIN));state.consents.initialized.value=false;return;}// OneTrustConsentManager SDK populates a data layer object OnetrustActiveGroups with
|
1244
1257
|
// the cookie categories Ids that the user has consented to.
|
1245
1258
|
// Eg: ',C0001,C0003,'
|
1246
1259
|
// We split it and save it as an array.
|
1247
1260
|
const allowedConsentIds=globalThis.OnetrustActiveGroups.split(',').filter(n=>n);const allowedConsents={};const deniedConsentIds=[];// Get the groups(cookie categorization), user has created in one trust account.
|
1248
|
-
const oneTrustAllGroupsInfo=globalThis.OneTrust.GetDomainData().Groups;oneTrustAllGroupsInfo.forEach(group=>{const{CustomGroupId,GroupName}=group;if(allowedConsentIds.includes(CustomGroupId)){allowedConsents[CustomGroupId]=GroupName;}else {deniedConsentIds.push(CustomGroupId);}});state.consents.data.value={
|
1261
|
+
const oneTrustAllGroupsInfo=globalThis.OneTrust.GetDomainData().Groups;oneTrustAllGroupsInfo.forEach(group=>{const{CustomGroupId,GroupName}=group;if(allowedConsentIds.includes(CustomGroupId)){allowedConsents[CustomGroupId]=GroupName;}else {deniedConsentIds.push(CustomGroupId);}});state.consents.initialized.value=true;state.consents.data.value={allowedConsentIds:allowedConsents,deniedConsentIds};},isDestinationConsented(state,destConfig,errorHandler,logger){if(!state.consents.initialized.value){return true;}const allowedConsentIds=state.consents.data.value.allowedConsentIds;try{// mapping of the destination with the consent group name
|
1249
1262
|
const{oneTrustCookieCategories}=destConfig;// If the destination do not have this mapping events will be sent.
|
1250
1263
|
if(!oneTrustCookieCategories){return true;}// Change the structure of oneTrustConsentGroup as an array and filter values if empty string
|
1251
1264
|
// Eg:
|
1252
1265
|
// ["Performance Cookies", "Functional Cookies"]
|
1253
1266
|
const validOneTrustCookieCategories=oneTrustCookieCategories.map(c=>c.oneTrustCookieCategory).filter(n=>n);let containsAllConsent=true;// Check if all the destination's mapped cookie categories are consented by the user in the browser.
|
1254
|
-
containsAllConsent=validOneTrustCookieCategories.every(element=>Object.keys(
|
1267
|
+
containsAllConsent=validOneTrustCookieCategories.every(element=>Object.keys(allowedConsentIds).includes(element.trim())||Object.values(allowedConsentIds).includes(element.trim()));return containsAllConsent;}catch(err){errorHandler?.onError(err,ONETRUST_CONSENT_MANAGER_PLUGIN,DESTINATION_CONSENT_STATUS_ERROR);return true;}}}});
|
1255
1268
|
|
1256
1269
|
const pluginName$3='StorageEncryption';const StorageEncryption=()=>({name:pluginName$3,initialize:state=>{state.plugins.loadedPlugins.value=[...state.plugins.loadedPlugins.value,pluginName$3];},storage:{encrypt(value){return encrypt$1(value);},decrypt(value){return decrypt$1(value);}}});
|
1257
1270
|
|
@@ -2240,7 +2253,7 @@ const DATA_PLANE_API_VERSION='v1';const QUEUE_NAME='rudder';const XHR_QUEUE_PLUG
|
|
2240
2253
|
|
2241
2254
|
const EVENT_DELIVERY_FAILURE_ERROR_PREFIX=(context,url)=>`${context}${LOG_CONTEXT_SEPARATOR}Failed to deliver event(s) to ${url}.`;
|
2242
2255
|
|
2243
|
-
const getBatchDeliveryPayload=(events,logger)=>{const batchPayload={batch:events};return stringifyWithoutCircular(batchPayload,true,undefined,logger);};const getNormalizedQueueOptions=queueOpts=>mergeDeepRight(DEFAULT_RETRY_QUEUE_OPTIONS,queueOpts);const getDeliveryUrl=(dataplaneUrl,endpoint)=>{const dpUrl=new URL(dataplaneUrl);return new URL(removeDuplicateSlashes([dpUrl.pathname,'/',DATA_PLANE_API_VERSION,'/',endpoint].join('')),dpUrl).href;};const getBatchDeliveryUrl=dataplaneUrl=>getDeliveryUrl(dataplaneUrl,'batch');const logErrorOnFailure=(details,url,willBeRetried,attemptNumber,maxRetryAttempts,logger)=>{if(isUndefined(details?.error)||isUndefined(logger)){return;}const isRetryableFailure=isErrRetryable(details);let errMsg=EVENT_DELIVERY_FAILURE_ERROR_PREFIX(XHR_QUEUE_PLUGIN,url);const dropMsg=`The event(s) will be dropped.`;if(isRetryableFailure){if(willBeRetried){errMsg=`${errMsg} It/they will be retried.`;if(attemptNumber>0){errMsg=`${errMsg} Retry attempt ${attemptNumber} of ${maxRetryAttempts}.`;}}else {errMsg=`${errMsg} Retries exhausted (${maxRetryAttempts}). ${dropMsg}`;}}else {errMsg=`${errMsg} ${dropMsg}`;}logger?.error(errMsg);};const getRequestInfo=(itemData,state,logger)=>{let data;let headers;let url;if(Array.isArray(itemData)){const finalEvents=itemData.map(queueItemData=>getFinalEventForDeliveryMutator(queueItemData.event));data=getBatchDeliveryPayload(finalEvents,logger);headers=clone$1(itemData[0].headers);url=getBatchDeliveryUrl(state.lifecycle.activeDataplaneUrl.value);}else {const{url:eventUrl,event,headers:eventHeaders}=itemData;const finalEvent=getFinalEventForDeliveryMutator(event);data=getDeliveryPayload(finalEvent,logger);headers=clone$1(eventHeaders);url=eventUrl;}return {data,headers,url};};
|
2256
|
+
const getBatchDeliveryPayload=(events,logger)=>{const batchPayload={batch:events};return stringifyWithoutCircular(batchPayload,true,undefined,logger);};const getNormalizedQueueOptions=queueOpts=>mergeDeepRight(DEFAULT_RETRY_QUEUE_OPTIONS,queueOpts);const getDeliveryUrl=(dataplaneUrl,endpoint)=>{const dpUrl=new URL(dataplaneUrl);return new URL(removeDuplicateSlashes([dpUrl.pathname,'/',DATA_PLANE_API_VERSION,'/',endpoint].join('')),dpUrl).href;};const getBatchDeliveryUrl=dataplaneUrl=>getDeliveryUrl(dataplaneUrl,'batch');const logErrorOnFailure=(details,url,willBeRetried,attemptNumber,maxRetryAttempts,logger)=>{if(isUndefined(details?.error)||isUndefined(logger)){return;}const isRetryableFailure=isErrRetryable(details);let errMsg=EVENT_DELIVERY_FAILURE_ERROR_PREFIX(XHR_QUEUE_PLUGIN,url);const dropMsg=`The event(s) will be dropped.`;if(isRetryableFailure){if(willBeRetried){errMsg=`${errMsg} It/they will be retried.`;if(attemptNumber>0){errMsg=`${errMsg} Retry attempt ${attemptNumber} of ${maxRetryAttempts}.`;}}else {errMsg=`${errMsg} Retries exhausted (${maxRetryAttempts}). ${dropMsg}`;}}else {errMsg=`${errMsg} ${dropMsg}`;}logger?.error(errMsg);};const getRequestInfo=(itemData,state,logger)=>{let data;let headers;let url;if(Array.isArray(itemData)){const finalEvents=itemData.map(queueItemData=>getFinalEventForDeliveryMutator(queueItemData.event));data=getBatchDeliveryPayload(finalEvents,logger);headers=itemData[0]?clone$1(itemData[0].headers):{};url=getBatchDeliveryUrl(state.lifecycle.activeDataplaneUrl.value);}else {const{url:eventUrl,event,headers:eventHeaders}=itemData;const finalEvent=getFinalEventForDeliveryMutator(event);data=getDeliveryPayload(finalEvent,logger);headers=clone$1(eventHeaders);url=eventUrl;}return {data,headers,url};};
|
2244
2257
|
|
2245
2258
|
const pluginName='XhrQueue';const XhrQueue=()=>({name:pluginName,deps:[],initialize:state=>{state.plugins.loadedPlugins.value=[...state.plugins.loadedPlugins.value,pluginName];},dataplaneEventsQueue:{/**
|
2246
2259
|
* Initialize the queue for delivery
|
@@ -2271,7 +2284,7 @@ AnonymousId:toBase64(event.anonymousId)};eventsQueue.addItem({url,headers,event}
|
|
2271
2284
|
|
2272
2285
|
/**
|
2273
2286
|
* Map plugin names to direct code imports from plugins package
|
2274
|
-
*/const getBundledBuildPluginImports=()=>({BeaconQueue,Bugsnag,DeviceModeDestinations,DeviceModeTransformation,ErrorReporting,ExternalAnonymousId,GoogleLinker,KetchConsentManager,NativeDestinationQueue,OneTrustConsentManager,StorageEncryption,StorageEncryptionLegacy,StorageMigrator,XhrQueue});
|
2287
|
+
*/const getBundledBuildPluginImports=()=>({BeaconQueue,Bugsnag,CustomConsentManager,DeviceModeDestinations,DeviceModeTransformation,ErrorReporting,ExternalAnonymousId,GoogleLinker,KetchConsentManager,NativeDestinationQueue,OneTrustConsentManager,StorageEncryption,StorageEncryptionLegacy,StorageMigrator,XhrQueue});
|
2275
2288
|
|
2276
2289
|
/**
|
2277
2290
|
* Map of mandatory plugin names and direct imports
|
@@ -2300,7 +2313,7 @@ const supportedErrReportingProviderPluginNames=Object.values(ErrorReportingProvi
|
|
2300
2313
|
if(state.loadOptions.value.useBeacon===true&&state.capabilities.isBeaconAvailable.value){pluginsToLoadFromConfig=pluginsToLoadFromConfig.filter(pluginName=>pluginName!=='XhrQueue');}else {if(state.loadOptions.value.useBeacon===true){this.logger?.warn(UNSUPPORTED_BEACON_API_WARNING(PLUGINS_MANAGER));}pluginsToLoadFromConfig=pluginsToLoadFromConfig.filter(pluginName=>pluginName!=='BeaconQueue');}// Enforce default cloud mode event delivery queue plugin is none exists
|
2301
2314
|
if(!pluginsToLoadFromConfig.includes('XhrQueue')&&!pluginsToLoadFromConfig.includes('BeaconQueue')){pluginsToLoadFromConfig.push('XhrQueue');}// Device mode destinations related plugins
|
2302
2315
|
if(getNonCloudDestinations(state.nativeDestinations.configuredDestinations.value??[]).length===0){pluginsToLoadFromConfig=pluginsToLoadFromConfig.filter(pluginName=>!['DeviceModeDestinations','DeviceModeTransformation','NativeDestinationQueue'].includes(pluginName));}// Consent Management related plugins
|
2303
|
-
const supportedConsentManagerPlugins=Object.values(ConsentManagersToPluginNameMap);
|
2316
|
+
const supportedConsentManagerPlugins=Object.values(ConsentManagersToPluginNameMap);let filterCondition=pluginName=>!(pluginName!==state.consents.activeConsentManagerPluginName.value&&supportedConsentManagerPlugins.includes(pluginName));if(!state.consents.enabled.value){filterCondition=pluginName=>!supportedConsentManagerPlugins.includes(pluginName);}pluginsToLoadFromConfig=pluginsToLoadFromConfig.filter(filterCondition);// Storage encryption related plugins
|
2304
2317
|
const supportedStorageEncryptionPlugins=Object.values(StorageEncryptionVersionsToPluginNameMap);pluginsToLoadFromConfig=pluginsToLoadFromConfig.filter(pluginName=>!(pluginName!==state.storage.encryptionPluginName.value&&supportedStorageEncryptionPlugins.includes(pluginName)));// Storage migrator related plugins
|
2305
2318
|
if(!state.storage.migrate.value){pluginsToLoadFromConfig=pluginsToLoadFromConfig.filter(pluginName=>pluginName!=='StorageMigrator');}return [...Object.keys(getMandatoryPluginsMap()),...pluginsToLoadFromConfig];}/**
|
2306
2319
|
* Determine the list of plugins that should be activated
|
@@ -2323,7 +2336,7 @@ unregisterLocalPlugins(){Object.values(pluginsInventory).forEach(localPlugin=>{t
|
|
2323
2336
|
|
2324
2337
|
/**
|
2325
2338
|
* Utility to parse XHR JSON response
|
2326
|
-
*/const responseTextToJson=(responseText,onError)=>{try{return JSON.parse(responseText||'');}catch(err){const error=getMutatedError(err,'Failed to parse response data');if(
|
2339
|
+
*/const responseTextToJson=(responseText,onError)=>{try{return JSON.parse(responseText||'');}catch(err){const error=getMutatedError(err,'Failed to parse response data');if(isFunction(onError)){onError(error);}else {throw error;}}return undefined;};
|
2327
2340
|
|
2328
2341
|
const DEFAULT_XHR_REQUEST_OPTIONS={headers:{Accept:'application/json','Content-Type':'application/json;charset=UTF-8'},method:'GET'};/**
|
2329
2342
|
* Utility to create request configuration based on default options
|
@@ -2343,7 +2356,7 @@ xhr.timeout=timeout;Object.keys(options.headers).forEach(headerName=>{if(options
|
|
2343
2356
|
* Implement requests in a blocking way
|
2344
2357
|
*/async getData(config){const{url,options,timeout,isRawResponse}=config;try{const data=await xhrRequest(createXhrRequestOptions(url,options,this.basicAuthHeader),timeout,this.logger);return {data:isRawResponse?data.response:responseTextToJson(data.response,this.onError),details:data};}catch(reason){this.onError(reason.error??reason);return {data:undefined,details:reason};}}/**
|
2345
2358
|
* Implement requests in a non-blocking way
|
2346
|
-
*/getAsyncData(config){const{callback,url,options,timeout,isRawResponse}=config;const isFireAndForget=!
|
2359
|
+
*/getAsyncData(config){const{callback,url,options,timeout,isRawResponse}=config;const isFireAndForget=!isFunction(callback);xhrRequest(createXhrRequestOptions(url,options,this.basicAuthHeader),timeout,this.logger).then(data=>{if(!isFireAndForget){callback(isRawResponse?data.response:responseTextToJson(data.response,this.onError),data);}}).catch(data=>{this.onError(data.error??data);if(!isFireAndForget){callback(undefined,data);}});}/**
|
2347
2360
|
* Handle errors
|
2348
2361
|
*/onError(error){if(this.hasErrorHandler){this.errorHandler?.onError(error,HTTP_CLIENT);}else {throw error;}}/**
|
2349
2362
|
* Set basic authentication header (eg writekey)
|
@@ -2369,7 +2382,7 @@ const hasCrypto=()=>!isNullOrUndefined(globalThis.crypto)&&isFunction(globalThis
|
|
2369
2382
|
|
2370
2383
|
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();});}};
|
2371
2384
|
|
2372
|
-
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,'Object.assign':()=>typeof Object.assign!=='function','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;};
|
2385
|
+
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,'Object.assign':()=>typeof Object.assign!=='function','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(isFunction(isCapabilityMissing)&&isCapabilityMissing()){needsPolyfill=true;break;}}return needsPolyfill;};
|
2373
2386
|
|
2374
2387
|
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;};
|
2375
2388
|
|
@@ -2388,7 +2401,7 @@ break;case SESSION_STORAGE:storage=storageInstance??globalThis.sessionStorage;te
|
|
2388
2401
|
return undefined;}};/**
|
2389
2402
|
* Parse cookie `str`
|
2390
2403
|
*/const parse=str=>{const obj={};const pairs=str.split(/\s*;\s*/);let pair;if(!pairs[0]){return obj;}// TODO: Decode only the cookies that are needed by the SDK
|
2391
|
-
pairs.forEach(pairItem=>{pair=pairItem.split('=');const keyName=decode(pair[0]);if(keyName){obj[keyName]=decode(pair[1]);}});return obj;};/**
|
2404
|
+
pairs.forEach(pairItem=>{pair=pairItem.split('=');const keyName=pair[0]?decode(pair[0]):undefined;if(keyName){obj[keyName]=pair[1]?decode(pair[1]):undefined;}});return obj;};/**
|
2392
2405
|
* Set cookie `name` to `value`
|
2393
2406
|
*/const set=(name,value,optionsConfig,logger)=>{const options={...optionsConfig}||{};let cookieString=`${encode(name,logger)}=${encode(value,logger)}`;if(isNull(value)){options.maxage=-1;}if(options.maxage){options.expires=new Date(+new Date()+options.maxage);}if(options.path){cookieString+=`; path=${options.path}`;}if(options.domain){cookieString+=`; domain=${options.domain}`;}if(options.expires){cookieString+=`; expires=${options.expires.toUTCString()}`;}if(options.samesite){cookieString+=`; samesite=${options.samesite}`;}if(options.secure){cookieString+=`; secure`;}globalThis.document.cookie=cookieString;};/**
|
2394
2407
|
* Return all cookies
|
@@ -2405,9 +2418,9 @@ const legacyGetHostname=href=>{const l=document.createElement('a');l.href=href;r
|
|
2405
2418
|
* The method returns an empty array when the hostname is an ip.
|
2406
2419
|
*/const levelsFunc=url=>{// This is called before the polyfills load thus new URL cannot be used
|
2407
2420
|
const host=typeof globalThis.URL!=='function'?legacyGetHostname(url):new URL(url).hostname;const parts=host?.split('.')??[];const last=parts[parts.length-1];const levels=[];// Ip address.
|
2408
|
-
if(parts.length===4&&last===parseInt(last,10).toString()){return levels;}// Localhost.
|
2421
|
+
if(parts.length===4&&last&&last===parseInt(last,10).toString()){return levels;}// Localhost.
|
2409
2422
|
if(parts.length<=1){// Fix to support localhost
|
2410
|
-
if(parts[0].indexOf('localhost')!==-1){return ['localhost'];}return levels;}// Create levels.
|
2423
|
+
if(parts[0]&&parts[0].indexOf('localhost')!==-1){return ['localhost'];}return levels;}// Create levels.
|
2411
2424
|
for(let i=parts.length-2;i>=0;i-=1){levels.push(parts.slice(i).join('.'));}return levels;};/**
|
2412
2425
|
* Get the top domain.
|
2413
2426
|
*
|
@@ -2427,7 +2440,7 @@ const getDefaultCookieOptions=()=>{const topDomain=domain(globalThis.location.hr
|
|
2427
2440
|
/**
|
2428
2441
|
* A storage utility to persist values in cookies via Storage interface
|
2429
2442
|
*/class CookieStorage{static globalSingleton=null;isSupportAvailable=true;isEnabled=true;length=0;constructor(options={},logger){if(CookieStorage.globalSingleton){// eslint-disable-next-line no-constructor-return
|
2430
|
-
return CookieStorage.globalSingleton;}this.options=getDefaultCookieOptions();this.logger=logger;this.configure(options);CookieStorage.globalSingleton=this;}configure(options){this.options=mergeDeepRight(this.options??{},options);this.isSupportAvailable=isStorageAvailable(COOKIE_STORAGE,this,this.logger);this.isEnabled=Boolean(this.options.enabled&&this.isSupportAvailable);return this.options;}setItem(key,value){cookie(key,value,this.options,this.logger);this.length=Object.keys(cookie()).length;return true;}// eslint-disable-next-line class-methods-use-this
|
2443
|
+
return CookieStorage.globalSingleton;}this.options=getDefaultCookieOptions();this.logger=logger;this.configure(options);CookieStorage.globalSingleton=this;}configure(options){this.options=mergeDeepRight(this.options??{},options);if(options.sameDomainCookiesOnly){delete this.options.domain;}this.isSupportAvailable=isStorageAvailable(COOKIE_STORAGE,this,this.logger);this.isEnabled=Boolean(this.options.enabled&&this.isSupportAvailable);return this.options;}setItem(key,value){cookie(key,value,this.options,this.logger);this.length=Object.keys(cookie()).length;return true;}// eslint-disable-next-line class-methods-use-this
|
2431
2444
|
getItem(key){const value=cookie(key);return isUndefined(value)?null:value;}removeItem(key){const result=this.setItem(key,null);this.length=Object.keys(cookie()).length;return result;}// eslint-disable-next-line class-methods-use-this
|
2432
2445
|
clear(){// Not implemented
|
2433
2446
|
// getting a list of all cookie storage keys and remove all values
|
@@ -2439,7 +2452,7 @@ key(index){const cookies=cookie();const cookieNames=Object.keys(cookies);return
|
|
2439
2452
|
|
2440
2453
|
/**
|
2441
2454
|
* A storage utility to retain values in memory via Storage interface
|
2442
|
-
*/class InMemoryStorage{isEnabled=true;length=0;data={};constructor(options,logger){this.options=getDefaultInMemoryStorageOptions();this.logger=logger;this.configure(options??{});}configure(options){this.options=mergeDeepRight(this.options,options);this.isEnabled=Boolean(this.options.enabled);return this.options;}setItem(key,value){this.data[key]=value;this.length=Object.keys(this.data).length;return value;}getItem(key){if(key in this.data){return this.data[key];}return null;}removeItem(key){if(key in this.data){delete this.data[key];}this.length=Object.keys(this.data).length;return null;}clear(){this.data={};this.length=0;}key(index){return Object.keys(this.data)[index];}}const defaultInMemoryStorage=new InMemoryStorage({},defaultLogger);
|
2455
|
+
*/class InMemoryStorage{isEnabled=true;length=0;data={};constructor(options,logger){this.options=getDefaultInMemoryStorageOptions();this.logger=logger;this.configure(options??{});}configure(options){this.options=mergeDeepRight(this.options,options);this.isEnabled=Boolean(this.options.enabled);return this.options;}setItem(key,value){this.data[key]=value;this.length=Object.keys(this.data).length;return value;}getItem(key){if(key in this.data){return this.data[key];}return null;}removeItem(key){if(key in this.data){delete this.data[key];}this.length=Object.keys(this.data).length;return null;}clear(){this.data={};this.length=0;}key(index){return Object.keys(this.data)[index]?Object.keys(this.data)[index]:null;}}const defaultInMemoryStorage=new InMemoryStorage({},defaultLogger);
|
2443
2456
|
|
2444
2457
|
var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
|
2445
2458
|
|
@@ -2463,7 +2476,7 @@ if(key===undefined){var ret={};this.forEach(function(key,val){return ret[key]=va
|
|
2463
2476
|
* A storage utility to persist values in localstorage via Storage interface
|
2464
2477
|
*/class LocalStorage{isSupportAvailable=true;isEnabled=true;length=0;constructor(options={},logger){this.options=getDefaultLocalStorageOptions();this.logger=logger;this.configure(options);}configure(options){this.options=mergeDeepRight(this.options,options);this.isSupportAvailable=isStorageAvailable(LOCAL_STORAGE,this,this.logger);this.isEnabled=Boolean(this.options.enabled&&this.isSupportAvailable);return this.options;}setItem(key,value){store.set(key,value);this.length=store.keys().length;}// eslint-disable-next-line class-methods-use-this
|
2465
2478
|
getItem(key){const value=store.get(key);return isUndefined(value)?null:value;}removeItem(key){store.remove(key);this.length=store.keys().length;}clear(){store.clear();this.length=0;}// eslint-disable-next-line class-methods-use-this
|
2466
|
-
key(index){return store.keys()[index];}}const defaultLocalStorage=new LocalStorage({},defaultLogger);
|
2479
|
+
key(index){return store.keys()[index]?store.keys()[index]:null;}}const defaultLocalStorage=new LocalStorage({},defaultLogger);
|
2467
2480
|
|
2468
2481
|
/**
|
2469
2482
|
* A storage utility to persist values in SessionStorage via Storage interface
|
@@ -2481,7 +2494,7 @@ key(index){return store.keys()[index];}}const defaultLocalStorage=new LocalStora
|
|
2481
2494
|
* Configure session storage singleton
|
2482
2495
|
*/const configureSessionStorageEngine=options=>{defaultSessionStorage.configure(options);};/**
|
2483
2496
|
* Configure all storage singleton instances
|
2484
|
-
*/const configureStorageEngines=(
|
2497
|
+
*/const configureStorageEngines=(cookieStorageOptions={},localStorageOptions={},inMemoryStorageOptions={},sessionStorageOptions={})=>{configureCookieStorageEngine(cookieStorageOptions);configureLocalStorageEngine(localStorageOptions);configureInMemoryStorageEngine(inMemoryStorageOptions);configureSessionStorageEngine(sessionStorageOptions);};
|
2485
2498
|
|
2486
2499
|
/**
|
2487
2500
|
* Store Implementation with dedicated storage
|
@@ -2517,18 +2530,21 @@ return JSON.parse(str);}catch(err){this.onError(new Error(`${STORE_DATA_FETCH_ER
|
|
2517
2530
|
* Handle errors
|
2518
2531
|
*/onError(error){if(this.hasErrorHandler){this.errorHandler?.onError(error,`Store ${this.id}`);}else {throw error;}}}
|
2519
2532
|
|
2533
|
+
const getStorageTypeFromPreConsent=(state,sessionKey)=>{let overriddenStorageType;if(state.consents.preConsent.value.enabled){switch(state.consents.preConsent.value.storage?.strategy){case'none':overriddenStorageType=NO_STORAGE;break;case'session':if(sessionKey!=='sessionInfo'){overriddenStorageType=NO_STORAGE;}else {overriddenStorageType=DEFAULT_STORAGE_TYPE;}break;case'anonymousId':if(sessionKey!=='anonymousId'){overriddenStorageType=NO_STORAGE;}else {overriddenStorageType=DEFAULT_STORAGE_TYPE;}break;}}return overriddenStorageType;};
|
2534
|
+
|
2520
2535
|
/**
|
2521
2536
|
* A service to manage stores & available storage client configurations
|
2522
2537
|
*/class StoreManager{stores={};isInitialized=false;hasErrorHandler=false;constructor(pluginsManager,errorHandler,logger){this.errorHandler=errorHandler;this.logger=logger;this.hasErrorHandler=Boolean(this.errorHandler);this.pluginsManager=pluginsManager;this.onError=this.onError.bind(this);}/**
|
2523
2538
|
* Configure available storage client instances
|
2524
|
-
*/init(){if(this.isInitialized){return;}const config={
|
2539
|
+
*/init(){if(this.isInitialized){return;}const config={cookieStorageOptions:{samesite:state.loadOptions.value.sameSiteCookie,secure:state.loadOptions.value.secureCookie,domain:state.loadOptions.value.setCookieDomain,sameDomainCookiesOnly:state.loadOptions.value.sameDomainCookiesOnly,enabled:true},localStorageOptions:{enabled:true},inMemoryStorageOptions:{enabled:true},sessionStorageOptions:{enabled:true}};configureStorageEngines(removeUndefinedValues(mergeDeepRight(config.cookieStorageOptions??{},state.storage.cookie?.value??{})),removeUndefinedValues(config.localStorageOptions),removeUndefinedValues(config.inMemoryStorageOptions),removeUndefinedValues(config.sessionStorageOptions));this.initClientDataStores();this.isInitialized=true;}/**
|
2525
2540
|
* Create store to persist data used by the SDK like session, used details etc
|
2526
|
-
*/
|
2527
|
-
if(getStorageEngine(COOKIE_STORAGE)?.isEnabled){finalStorageType=COOKIE_STORAGE;}else if(getStorageEngine(LOCAL_STORAGE)?.isEnabled){finalStorageType=LOCAL_STORAGE;}else if(getStorageEngine(SESSION_STORAGE)?.isEnabled){finalStorageType=SESSION_STORAGE;}else {finalStorageType=MEMORY_STORAGE;}break;}if(finalStorageType!==storageType){this.logger?.warn(STORAGE_UNAVAILABLE_WARNING(STORE_MANAGER,storageType,finalStorageType));}if(finalStorageType!==NO_STORAGE){trulyAnonymousTracking=false;}const storageState=state.storage.entries.value;state.storage.entries.value={...storageState,[sessionKey]:{type:finalStorageType,key:userSessionStorageKeys[storageKey]}};});state.storage.trulyAnonymousTracking.value=trulyAnonymousTracking;// TODO: fill in extra config values and bring them in from StoreManagerOptions if needed
|
2541
|
+
*/initClientDataStores(){this.initializeStorageState();// TODO: fill in extra config values and bring them in from StoreManagerOptions if needed
|
2528
2542
|
// TODO: should we pass the keys for all in order to validate or leave free as v1.1?
|
2529
2543
|
// Initializing all the enabled store because previous user data might be in different storage
|
2530
2544
|
// that needs auto migration
|
2531
|
-
const storageTypesRequiringInitialization=[MEMORY_STORAGE];if(getStorageEngine(LOCAL_STORAGE)?.isEnabled){storageTypesRequiringInitialization.push(LOCAL_STORAGE);}if(getStorageEngine(COOKIE_STORAGE)?.isEnabled){storageTypesRequiringInitialization.push(COOKIE_STORAGE);}if(getStorageEngine(SESSION_STORAGE)?.isEnabled){storageTypesRequiringInitialization.push(SESSION_STORAGE);}storageTypesRequiringInitialization.forEach(storageType=>{this.setStore({id:storageClientDataStoreNameMap[storageType],name:storageClientDataStoreNameMap[storageType],isEncrypted:true,noCompoundKey:true,type:storageType});});}
|
2545
|
+
const storageTypesRequiringInitialization=[MEMORY_STORAGE];if(getStorageEngine(LOCAL_STORAGE)?.isEnabled){storageTypesRequiringInitialization.push(LOCAL_STORAGE);}if(getStorageEngine(COOKIE_STORAGE)?.isEnabled){storageTypesRequiringInitialization.push(COOKIE_STORAGE);}if(getStorageEngine(SESSION_STORAGE)?.isEnabled){storageTypesRequiringInitialization.push(SESSION_STORAGE);}storageTypesRequiringInitialization.forEach(storageType=>{this.setStore({id:storageClientDataStoreNameMap[storageType],name:storageClientDataStoreNameMap[storageType],isEncrypted:true,noCompoundKey:true,type:storageType});});}initializeStorageState(){const globalStorageType=state.storage.type.value;let trulyAnonymousTracking=true;const entries=state.loadOptions.value.storage?.entries;const userSessionKeyValues=['userId','userTraits','anonymousId','groupId','groupTraits','initialReferrer','initialReferringDomain','sessionInfo'];userSessionKeyValues.forEach(sessionKey=>{const key=sessionKey;const storageKey=sessionKey;const providedStorageType=entries?.[key]?.type;const preConsentStorageType=getStorageTypeFromPreConsent(state,sessionKey);// Storage type precedence order: pre-consent strategy > entry type > global type > default
|
2546
|
+
const storageType=preConsentStorageType??providedStorageType??globalStorageType??DEFAULT_STORAGE_TYPE;let finalStorageType=storageType;switch(storageType){case LOCAL_STORAGE:if(!getStorageEngine(LOCAL_STORAGE)?.isEnabled){finalStorageType=MEMORY_STORAGE;}break;case SESSION_STORAGE:if(!getStorageEngine(SESSION_STORAGE)?.isEnabled){finalStorageType=MEMORY_STORAGE;}break;case MEMORY_STORAGE:case NO_STORAGE:break;case COOKIE_STORAGE:default:// First try setting the storage to cookie else to local storage
|
2547
|
+
if(getStorageEngine(COOKIE_STORAGE)?.isEnabled){finalStorageType=COOKIE_STORAGE;}else if(getStorageEngine(LOCAL_STORAGE)?.isEnabled){finalStorageType=LOCAL_STORAGE;}else if(getStorageEngine(SESSION_STORAGE)?.isEnabled){finalStorageType=SESSION_STORAGE;}else {finalStorageType=MEMORY_STORAGE;}break;}if(finalStorageType!==storageType){this.logger?.warn(STORAGE_UNAVAILABLE_WARNING(STORE_MANAGER,storageType,finalStorageType));}if(finalStorageType!==NO_STORAGE){trulyAnonymousTracking=false;}const storageState=state.storage.entries.value;state.storage.entries.value={...storageState,[sessionKey]:{type:finalStorageType,key:userSessionStorageKeys[storageKey]}};});state.storage.trulyAnonymousTracking.value=trulyAnonymousTracking;}/**
|
2532
2548
|
* Create a new store
|
2533
2549
|
*/setStore(storeConfig){const storageEngine=getStorageEngine(storeConfig.type);this.stores[storeConfig.id]=new Store(storeConfig,storageEngine,this.pluginsManager);return this.stores[storeConfig.id];}/**
|
2534
2550
|
* Retrieve a store
|
@@ -2566,7 +2582,7 @@ const validateWriteKey=writeKey=>{if(!isString(writeKey)||writeKey.trim().length
|
|
2566
2582
|
|
2567
2583
|
/**
|
2568
2584
|
* Plugins to be loaded in the plugins loadOption is not defined
|
2569
|
-
*/const defaultOptionalPluginsList=['BeaconQueue','Bugsnag','DeviceModeDestinations','DeviceModeTransformation','ErrorReporting','ExternalAnonymousId','GoogleLinker','KetchConsentManager','NativeDestinationQueue','OneTrustConsentManager','StorageEncryption','StorageEncryptionLegacy','StorageMigrator','XhrQueue'];
|
2585
|
+
*/const defaultOptionalPluginsList=['BeaconQueue','Bugsnag','CustomConsentManager','DeviceModeDestinations','DeviceModeTransformation','ErrorReporting','ExternalAnonymousId','GoogleLinker','KetchConsentManager','NativeDestinationQueue','OneTrustConsentManager','StorageEncryption','StorageEncryptionLegacy','StorageMigrator','XhrQueue'];
|
2570
2586
|
|
2571
2587
|
/**
|
2572
2588
|
* A function to check given value is a number or not
|
@@ -2617,18 +2633,27 @@ const DEFAULT_PRE_CONSENT_STORAGE_STRATEGY='none';const DEFAULT_PRE_CONSENT_EVEN
|
|
2617
2633
|
const isErrorReportingEnabled=sourceConfig=>sourceConfig?.statsCollection?.errors?.enabled===true;const getErrorReportingProviderNameFromConfig=sourceConfig=>sourceConfig?.statsCollection?.errors?.provider;const isMetricsReportingEnabled=sourceConfig=>sourceConfig?.statsCollection?.metrics?.enabled===true;
|
2618
2634
|
|
2619
2635
|
/**
|
2620
|
-
*
|
2621
|
-
* @param
|
2622
|
-
* @returns
|
2623
|
-
|
2624
|
-
|
2625
|
-
*
|
2626
|
-
*
|
2627
|
-
*
|
2628
|
-
|
2629
|
-
*
|
2630
|
-
*
|
2631
|
-
|
2636
|
+
* Validates and normalizes the consent options provided by the user
|
2637
|
+
* @param options Consent options provided by the user
|
2638
|
+
* @returns Validated and normalized consent options
|
2639
|
+
*/const getValidPostConsentOptions=options=>{const validOptions={sendPageEvent:false,trackConsent:false,discardPreConsentEvents:false};if(isObjectLiteralAndNotNull(options)){const clonedOptions=clone$1(options);validOptions.storage=clonedOptions.storage;validOptions.integrations=clonedOptions.integrations;validOptions.discardPreConsentEvents=clonedOptions.discardPreConsentEvents===true;validOptions.sendPageEvent=clonedOptions.sendPageEvent===true;validOptions.trackConsent=clonedOptions.trackConsent===true;if(isNonEmptyObject(clonedOptions.consentManagement)){// Override enabled value with the current state value
|
2640
|
+
validOptions.consentManagement=mergeDeepRight(clonedOptions.consentManagement,{enabled:state.consents.enabled.value});}}return validOptions;};/**
|
2641
|
+
* Validates if the input is a valid consents data
|
2642
|
+
* @param value Input consents data
|
2643
|
+
* @returns true if the input is a valid consents data else false
|
2644
|
+
*/const isValidConsentsData=value=>isNonEmptyObject(value)||Array.isArray(value);/**
|
2645
|
+
* Retrieves the corresponding plugin name of the selected consent manager from the supported consent managers
|
2646
|
+
* @param consentProvider consent management provider name
|
2647
|
+
* @param logger logger instance
|
2648
|
+
* @returns Corresponding plugin name of the selected consent manager from the supported consent managers
|
2649
|
+
*/const getConsentManagerPluginName=(consentProvider,logger)=>{const consentManagerPluginName=ConsentManagersToPluginNameMap[consentProvider];if(consentProvider&&!consentManagerPluginName){logger?.error(UNSUPPORTED_CONSENT_MANAGER_ERROR(CONFIG_MANAGER,consentProvider,ConsentManagersToPluginNameMap));}return consentManagerPluginName;};/**
|
2650
|
+
* Validates and converts the consent management options into a normalized format
|
2651
|
+
* @param consentManagementOpts Consent management options provided by the user
|
2652
|
+
* @param logger logger instance
|
2653
|
+
* @returns An object containing the consent manager plugin name, initialized, enabled and consents data
|
2654
|
+
*/const getConsentManagementData=(consentManagementOpts,logger)=>{let consentManagerPluginName;let allowedConsentIds=[];let deniedConsentIds=[];let initialized=false;let enabled=consentManagementOpts?.enabled===true;if(isNonEmptyObject(consentManagementOpts)&&enabled){const consentProvider=consentManagementOpts.provider;// Get the corresponding plugin name of the selected consent manager from the supported consent managers
|
2655
|
+
consentManagerPluginName=getConsentManagerPluginName(consentProvider,logger);if(isValidConsentsData(consentManagementOpts.allowedConsentIds)){allowedConsentIds=consentManagementOpts.allowedConsentIds;initialized=true;}if(isValidConsentsData(consentManagementOpts.deniedConsentIds)){deniedConsentIds=consentManagementOpts.deniedConsentIds;initialized=true;}}const consentsData={allowedConsentIds,deniedConsentIds};// Enable consent management only if consent manager is supported
|
2656
|
+
enabled=enabled&&Boolean(consentManagerPluginName);return {consentManagerPluginName,initialized,enabled,consentsData};};
|
2632
2657
|
|
2633
2658
|
/**
|
2634
2659
|
* Determines the SDK url
|
@@ -2641,10 +2666,11 @@ const isErrorReportingEnabled=sourceConfig=>sourceConfig?.statsCollection?.error
|
|
2641
2666
|
const errReportingProviderPlugin=errReportingProvider?ErrorReportingProvidersToPluginNameMap[errReportingProvider]:undefined;if(!isUndefined(errReportingProvider)&&!errReportingProviderPlugin){// set the default error reporting provider
|
2642
2667
|
logger?.warn(UNSUPPORTED_ERROR_REPORTING_PROVIDER_WARNING(CONFIG_MANAGER,errReportingProvider,ErrorReportingProvidersToPluginNameMap,DEFAULT_ERROR_REPORTING_PROVIDER));}state.reporting.errorReportingProviderPluginName.value=errReportingProviderPlugin??ErrorReportingProvidersToPluginNameMap[DEFAULT_ERROR_REPORTING_PROVIDER];}};const updateStorageState=logger=>{const storageOptsFromLoad=state.loadOptions.value.storage;let storageType=storageOptsFromLoad?.type;if(isDefined(storageType)&&!isValidStorageType(storageType)){logger?.warn(STORAGE_TYPE_VALIDATION_WARNING(CONFIG_MANAGER,storageType,DEFAULT_STORAGE_TYPE));storageType=DEFAULT_STORAGE_TYPE;}let storageEncryptionVersion=storageOptsFromLoad?.encryption?.version;const encryptionPluginName=storageEncryptionVersion&&StorageEncryptionVersionsToPluginNameMap[storageEncryptionVersion];if(!isUndefined(storageEncryptionVersion)&&isUndefined(encryptionPluginName)){// set the default encryption plugin
|
2643
2668
|
logger?.warn(UNSUPPORTED_STORAGE_ENCRYPTION_VERSION_WARNING(CONFIG_MANAGER,storageEncryptionVersion,StorageEncryptionVersionsToPluginNameMap,DEFAULT_STORAGE_ENCRYPTION_VERSION));storageEncryptionVersion=DEFAULT_STORAGE_ENCRYPTION_VERSION;}else if(isUndefined(storageEncryptionVersion)){storageEncryptionVersion=DEFAULT_STORAGE_ENCRYPTION_VERSION;}// Allow migration only if the configured encryption version is the default encryption version
|
2644
|
-
const configuredMigrationValue=storageOptsFromLoad?.migrate;const finalMigrationVal=configuredMigrationValue&&storageEncryptionVersion===DEFAULT_STORAGE_ENCRYPTION_VERSION;if(configuredMigrationValue===true&&finalMigrationVal!==configuredMigrationValue){logger?.warn(STORAGE_DATA_MIGRATION_OVERRIDE_WARNING(CONFIG_MANAGER,storageEncryptionVersion,DEFAULT_STORAGE_ENCRYPTION_VERSION));}n(()=>{state.storage.type.value=storageType;state.storage.cookie.value=storageOptsFromLoad?.cookie;state.storage.encryptionPluginName.value=StorageEncryptionVersionsToPluginNameMap[storageEncryptionVersion];state.storage.migrate.value=finalMigrationVal;});};const updateConsentsState=logger=>{
|
2645
|
-
const
|
2646
|
-
|
2647
|
-
|
2669
|
+
const configuredMigrationValue=storageOptsFromLoad?.migrate;const finalMigrationVal=configuredMigrationValue&&storageEncryptionVersion===DEFAULT_STORAGE_ENCRYPTION_VERSION;if(configuredMigrationValue===true&&finalMigrationVal!==configuredMigrationValue){logger?.warn(STORAGE_DATA_MIGRATION_OVERRIDE_WARNING(CONFIG_MANAGER,storageEncryptionVersion,DEFAULT_STORAGE_ENCRYPTION_VERSION));}n(()=>{state.storage.type.value=storageType;state.storage.cookie.value=storageOptsFromLoad?.cookie;state.storage.encryptionPluginName.value=StorageEncryptionVersionsToPluginNameMap[storageEncryptionVersion];state.storage.migrate.value=finalMigrationVal;});};const updateConsentsState=logger=>{const{consentManagerPluginName,initialized,enabled,consentsData}=getConsentManagementData(state.loadOptions.value.consentManagement,logger);// Pre-consent
|
2670
|
+
const preConsentOpts=state.loadOptions.value.preConsent;let storageStrategy=preConsentOpts?.storage?.strategy??DEFAULT_PRE_CONSENT_STORAGE_STRATEGY;const StorageStrategies=['none','session','anonymousId'];if(isDefined(storageStrategy)&&!StorageStrategies.includes(storageStrategy)){storageStrategy=DEFAULT_PRE_CONSENT_STORAGE_STRATEGY;logger?.warn(UNSUPPORTED_PRE_CONSENT_STORAGE_STRATEGY(CONFIG_MANAGER,preConsentOpts?.storage?.strategy,DEFAULT_PRE_CONSENT_STORAGE_STRATEGY));}let eventsDeliveryType=preConsentOpts?.events?.delivery??DEFAULT_PRE_CONSENT_EVENTS_DELIVERY_TYPE;const deliveryTypes=['immediate','buffer'];if(isDefined(eventsDeliveryType)&&!deliveryTypes.includes(eventsDeliveryType)){eventsDeliveryType=DEFAULT_PRE_CONSENT_EVENTS_DELIVERY_TYPE;logger?.warn(UNSUPPORTED_PRE_CONSENT_EVENTS_DELIVERY_TYPE(CONFIG_MANAGER,preConsentOpts?.events?.delivery,DEFAULT_PRE_CONSENT_EVENTS_DELIVERY_TYPE));}n(()=>{state.consents.activeConsentManagerPluginName.value=consentManagerPluginName;state.consents.initialized.value=initialized;state.consents.enabled.value=enabled;state.consents.data.value=consentsData;state.consents.preConsent.value={// Only enable pre-consent if it is explicitly enabled and
|
2671
|
+
// if it is not already initialized and
|
2672
|
+
// if consent management is enabled
|
2673
|
+
enabled:state.loadOptions.value.preConsent?.enabled===true&&initialized===false&&enabled===true,storage:{strategy:storageStrategy},events:{delivery:eventsDeliveryType}};});};
|
2648
2674
|
|
2649
2675
|
/**
|
2650
2676
|
* A function that determines integration SDK loading path
|
@@ -2666,7 +2692,7 @@ const sdkURL=getSDKUrl();pluginsCDNPath=sdkURL&&isString(sdkURL)?sdkURL.split('/
|
|
2666
2692
|
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(){O(()=>{this.logger?.setMinLogLevel(state.lifecycle.logLevel.value);});}/**
|
2667
2693
|
* A function to validate, construct and store loadOption, lifecycle, source and destination
|
2668
2694
|
* config related information in global state
|
2669
|
-
*/init(){this.attachEffects();
|
2695
|
+
*/init(){this.attachEffects();validateLoadArgs(state.lifecycle.writeKey.value,state.lifecycle.dataPlaneUrl.value);const lockIntegrationsVersion=state.loadOptions.value.lockIntegrationsVersion;// determine the path to fetch integration SDK from
|
2670
2696
|
const intgCdnUrl=getIntegrationsCDNPath(APP_VERSION,lockIntegrationsVersion,state.loadOptions.value.destSDKBaseURL);// determine the path to fetch remote plugins from
|
2671
2697
|
const pluginsCDNPath=getPluginsCDNPath(state.loadOptions.value.pluginsSDKBaseURL);updateStorageState(this.logger);updateConsentsState(this.logger);// set application lifecycle state in global state
|
2672
2698
|
n(()=>{state.lifecycle.integrationsCDNPath.value=intgCdnUrl;state.lifecycle.pluginsCDNPath.value=pluginsCDNPath;if(state.loadOptions.value.logLevel){state.lifecycle.logLevel.value=state.loadOptions.value.logLevel;}state.lifecycle.sourceConfigUrl.value=getSourceConfigURL(state.loadOptions.value.configUrl,state.lifecycle.writeKey.value,lockIntegrationsVersion,this.logger);});this.getConfig();}/**
|
@@ -2692,6 +2718,12 @@ state.lifecycle.activeDataplaneUrl.value=removeTrailingSlashes(dataPlaneUrl);sta
|
|
2692
2718
|
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
|
2693
2719
|
this.httpClient.getAsyncData({url:state.lifecycle.sourceConfigUrl.value,options:{headers:{'Content-Type':undefined}},callback:this.processConfig});}}}
|
2694
2720
|
|
2721
|
+
/**
|
2722
|
+
* To get the timezone of the user
|
2723
|
+
*
|
2724
|
+
* @returns string
|
2725
|
+
*/const getTimezone=()=>{const timezone=new Date().toString().match(/([A-Z]+[+-]\d+)/);return timezone&&timezone[1]?timezone[1]:'NA';};
|
2726
|
+
|
2695
2727
|
/**
|
2696
2728
|
* Get the referrer URL
|
2697
2729
|
* @returns The referrer URL
|
@@ -2719,15 +2751,15 @@ class CapabilitiesManager{constructor(errorHandler,logger){this.logger=logger;th
|
|
2719
2751
|
detectBrowserCapabilities(){n(()=>{// Storage related details
|
2720
2752
|
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
|
2721
2753
|
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
|
2722
|
-
state.context.userAgent.value=getUserAgent();state.context.locale.value=getLanguage();state.context.screen.value=getScreenDetails();if(hasUAClientHints()){getUserAgentClientHint(uach=>{state.context['ua-ch'].value=uach;},state.loadOptions.value.uaChTrackLevel);}});// Ad blocker detection
|
2754
|
+
state.context.userAgent.value=getUserAgent();state.context.locale.value=getLanguage();state.context.screen.value=getScreenDetails();state.context.timezone.value=getTimezone();if(hasUAClientHints()){getUserAgentClientHint(uach=>{state.context['ua-ch'].value=uach;},state.loadOptions.value.uaChTrackLevel);}});// Ad blocker detection
|
2723
2755
|
O(()=>{if(state.loadOptions.value.sendAdblockPage===true&&state.lifecycle.sourceConfigUrl.value!==undefined){detectAdBlockers(this.errorHandler,this.logger);}});}/**
|
2724
2756
|
* Detect if polyfills are required and then load script from polyfill URL
|
2725
|
-
*/prepareBrowserCapabilities(){state.capabilities.isLegacyDOM.value=isLegacyJSEngine();let polyfillUrl=state.loadOptions.value.polyfillURL??POLYFILL_URL;const shouldLoadPolyfill=state.loadOptions.value.polyfillIfRequired&&state.capabilities.isLegacyDOM.value&&Boolean(polyfillUrl);if(shouldLoadPolyfill){const isDefaultPolyfillService=polyfillUrl!==state.loadOptions.value.polyfillURL;if(isDefaultPolyfillService){
|
2757
|
+
*/prepareBrowserCapabilities(){state.capabilities.isLegacyDOM.value=isLegacyJSEngine();let polyfillUrl=state.loadOptions.value.polyfillURL??POLYFILL_URL;const shouldLoadPolyfill=state.loadOptions.value.polyfillIfRequired&&state.capabilities.isLegacyDOM.value&&Boolean(polyfillUrl);if(shouldLoadPolyfill){const isDefaultPolyfillService=polyfillUrl!==state.loadOptions.value.polyfillURL;if(isDefaultPolyfillService){// write key specific callback
|
2726
2758
|
// NOTE: we're not putting this into RudderStackGlobals as providing the property path to the callback function in the polyfill URL is not possible
|
2727
|
-
const polyfillCallbackName=`RS_polyfillCallback_${state.lifecycle.writeKey.value}`;
|
2759
|
+
const polyfillCallbackName=`RS_polyfillCallback_${state.lifecycle.writeKey.value}`;const polyfillCallback=()=>{this.onReady();// Remove the entry from window so we don't leave room for calling it again
|
2760
|
+
delete globalThis[polyfillCallbackName];};globalThis[polyfillCallbackName]=polyfillCallback;polyfillUrl=`${polyfillUrl}&callback=${polyfillCallbackName}`;}this.externalSrcLoader?.loadJSFile({url:polyfillUrl,id:POLYFILL_SCRIPT_ID,async:true,timeout:POLYFILL_LOAD_TIMEOUT,callback:scriptId=>{if(!scriptId){this.onError(new Error(POLYFILL_SCRIPT_LOAD_ERROR(POLYFILL_SCRIPT_ID,polyfillUrl)));}else if(!isDefaultPolyfillService){this.onReady();}}});}else {this.onReady();}}/**
|
2728
2761
|
* Attach listeners to window to observe event that update capabilities state values
|
2729
|
-
*/
|
2730
|
-
attachWindowListeners(){globalThis.addEventListener('offline',()=>{state.capabilities.isOnline.value=false;});globalThis.addEventListener('online',()=>{state.capabilities.isOnline.value=true;});globalThis.addEventListener('resize',debounce(()=>{state.context.screen.value=getScreenDetails();},this));}/**
|
2762
|
+
*/attachWindowListeners(){globalThis.addEventListener('offline',()=>{state.capabilities.isOnline.value=false;});globalThis.addEventListener('online',()=>{state.capabilities.isOnline.value=true;});globalThis.addEventListener('resize',debounce(()=>{state.context.screen.value=getScreenDetails();},this));}/**
|
2731
2763
|
* Set the lifecycle status to next phase
|
2732
2764
|
*/ // eslint-disable-next-line class-methods-use-this
|
2733
2765
|
onReady(){this.detectBrowserCapabilities();state.lifecycle.status.value='browserCapabilitiesReady';}/**
|
@@ -2766,7 +2798,7 @@ const{properties,traits,context}=rudderEvent;const{traits:contextualTraits}=cont
|
|
2766
2798
|
* @param rudderEvent Generated rudder event
|
2767
2799
|
* @param options API options
|
2768
2800
|
*/const updateTopLevelEventElements=(rudderEvent,options)=>{if(options.anonymousId&&isString(options.anonymousId)){// eslint-disable-next-line no-param-reassign
|
2769
|
-
rudderEvent.anonymousId=options.anonymousId;}if(
|
2801
|
+
rudderEvent.anonymousId=options.anonymousId;}if(isObjectLiteralAndNotNull(options.integrations)){// eslint-disable-next-line no-param-reassign
|
2770
2802
|
rudderEvent.integrations=options.integrations;}if(options.originalTimestamp&&isString(options.originalTimestamp)){// eslint-disable-next-line no-param-reassign
|
2771
2803
|
rudderEvent.originalTimestamp=options.originalTimestamp;}};/**
|
2772
2804
|
* To merge the contextual information in API options with existing data
|
@@ -2781,7 +2813,7 @@ rudderEvent.originalTimestamp=options.originalTimestamp;}};/**
|
|
2781
2813
|
* @param rudderEvent Generated rudder event
|
2782
2814
|
* @param options API options
|
2783
2815
|
*/const processOptions=(rudderEvent,options)=>{// Only allow object type for options
|
2784
|
-
if(
|
2816
|
+
if(isObjectLiteralAndNotNull(options)){updateTopLevelEventElements(rudderEvent,options);// eslint-disable-next-line no-param-reassign
|
2785
2817
|
rudderEvent.context=getMergedContext(rudderEvent.context,options);}};/**
|
2786
2818
|
* Returns the final integrations config for the event based on the global config and event's config
|
2787
2819
|
* @param integrationsConfig Event's integrations config
|
@@ -2793,7 +2825,7 @@ rudderEvent.context=getMergedContext(rudderEvent.context,options);}};/**
|
|
2793
2825
|
* @param pageProps Page properties
|
2794
2826
|
* @param logger logger
|
2795
2827
|
* @returns Enriched RudderEvent object
|
2796
|
-
*/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:extractUTMParameters(globalThis.location.href),page:getContextPageProperties(pageProps)},originalTimestamp:getCurrentTimeFormatted(),integrations:DEFAULT_INTEGRATIONS_CONFIG,messageId:generateUUID(),userId:rudderEvent.userId||state.session.userId.value};if(state.storage.entries.value.anonymousId?.type===NO_STORAGE){// Generate new anonymous id for each request
|
2828
|
+
*/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:extractUTMParameters(globalThis.location.href),page:getContextPageProperties(pageProps),timezone:state.context.timezone.value},originalTimestamp:getCurrentTimeFormatted(),integrations:DEFAULT_INTEGRATIONS_CONFIG,messageId:generateUUID(),userId:rudderEvent.userId||state.session.userId.value};if(state.storage.entries.value.anonymousId?.type===NO_STORAGE){// Generate new anonymous id for each request
|
2797
2829
|
commonEventData.anonymousId=generateUUID();}else {// Type casting to string as the user session manager will take care of initializing the value
|
2798
2830
|
commonEventData.anonymousId=state.session.anonymousId.value;}// set truly anonymous tracking flag
|
2799
2831
|
if(state.storage.trulyAnonymousTracking.value){commonEventData.context.trulyAnonymousTracking=true;}if(rudderEvent.type==='identify'){commonEventData.context.traits=state.storage.entries.value.userTraits?.type!==NO_STORAGE?clone$1(state.session.userTraits.value):rudderEvent.context.traits;}if(rudderEvent.type==='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.entries.value.groupTraits?.type!==NO_STORAGE?clone$1(state.session.groupTraits.value):rudderEvent.traits;}}const processedEvent=mergeDeepRight(rudderEvent,commonEventData);// Set the default values for the event properties
|
@@ -2844,7 +2876,7 @@ enrichedEvent.userId=to??enrichedEvent.userId;return enrichedEvent;}/**
|
|
2844
2876
|
* @param logger Logger object
|
2845
2877
|
*/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);}/**
|
2846
2878
|
* Initializes the event manager
|
2847
|
-
*/init(){this.eventRepository.init();}/**
|
2879
|
+
*/init(){this.eventRepository.init();}resume(){this.eventRepository.resume();}/**
|
2848
2880
|
* Consumes a new incoming event
|
2849
2881
|
* @param event Incoming event data
|
2850
2882
|
*/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));}}/**
|
@@ -2878,10 +2910,10 @@ timeout,sessionStart:undefined,autoTrack:true};};/**
|
|
2878
2910
|
|
2879
2911
|
class UserSessionManager{constructor(errorHandler,logger,pluginsManager,storeManager){this.storeManager=storeManager;this.pluginsManager=pluginsManager;this.logger=logger;this.errorHandler=errorHandler;this.onError=this.onError.bind(this);}/**
|
2880
2912
|
* Initialize User session with values from storage
|
2881
|
-
*/init(){this.
|
2882
|
-
|
2883
|
-
if(this.
|
2884
|
-
this.
|
2913
|
+
*/init(){this.syncStorageDataToState();// Register the effect to sync with storage
|
2914
|
+
this.registerEffects();}syncStorageDataToState(){this.migrateStorageIfNeeded();this.migrateDataFromPreviousStorage();// get the values from storage and set it again
|
2915
|
+
const userId=this.getUserId();const userTraits=this.getUserTraits();const groupId=this.getGroupId();const groupTraits=this.getGroupTraits();const anonymousId=this.getAnonymousId(state.loadOptions.value.anonymousIdOptions);if(userId){this.setUserId(userId);}if(userTraits){this.setUserTraits(userTraits);}if(groupId){this.setGroupId(groupId);}if(groupTraits){this.setGroupTraits(groupTraits);}if(anonymousId){this.setAnonymousId(anonymousId);}const authToken=this.getAuthToken();if(authToken){this.setAuthToken(authToken);}const persistedInitialReferrer=this.getInitialReferrer();const persistedInitialReferringDomain=this.getInitialReferringDomain();if(persistedInitialReferrer&&persistedInitialReferringDomain){this.setInitialReferrer(persistedInitialReferrer);this.setInitialReferringDomain(persistedInitialReferringDomain);}else {const initialReferrer=persistedInitialReferrer||getReferrer();this.setInitialReferrer(initialReferrer);this.setInitialReferringDomain(getReferringDomain(initialReferrer));}// Initialize session tracking
|
2916
|
+
if(this.isPersistenceEnabledForStorageEntry('sessionInfo')){this.initializeSessionTracking();}}isPersistenceEnabledForStorageEntry(entryName){const entries=state.storage.entries.value;return isStorageTypeValidForStoringData(entries[entryName]?.type);}migrateDataFromPreviousStorage(){const entries=state.storage.entries.value;const storagesForMigration=[COOKIE_STORAGE,LOCAL_STORAGE,SESSION_STORAGE];Object.keys(entries).forEach(entry=>{const key=entry;const currentStorage=entries[key]?.type;const curStore=this.storeManager?.getStore(storageClientDataStoreNameMap[currentStorage]);if(curStore){storagesForMigration.forEach(storage=>{const store=this.storeManager?.getStore(storageClientDataStoreNameMap[storage]);if(store&&storage!==currentStorage){const value=store.get(userSessionStorageKeys[key]);if(isDefinedNotNullAndNotEmptyString(value)){curStore.set(userSessionStorageKeys[key],value);}store.remove(userSessionStorageKeys[key]);}});}});}migrateStorageIfNeeded(){if(!state.storage.migrate.value){return;}const cookieStorage=this.storeManager?.getStore(CLIENT_DATA_STORE_COOKIE);const localStorage=this.storeManager?.getStore(CLIENT_DATA_STORE_LS);const sessionStorage=this.storeManager?.getStore(CLIENT_DATA_STORE_SESSION);const stores=[];if(cookieStorage){stores.push(cookieStorage);}if(localStorage){stores.push(localStorage);}if(sessionStorage){stores.push(sessionStorage);}Object.keys(userSessionStorageKeys).forEach(storageEntryKey=>{const key=storageEntryKey;const storageEntry=userSessionStorageKeys[key];stores.forEach(store=>{const migratedVal=this.pluginsManager?.invokeSingle('storage.migrate',storageEntry,store.engine,this.errorHandler,this.logger);if(migratedVal){store.set(storageEntry,migratedVal);}});});}/**
|
2885
2917
|
* A function to initialize sessionTracking
|
2886
2918
|
*/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
|
2887
2919
|
// and will proceed with it
|
@@ -3016,7 +3048,7 @@ const DATA_PLANE_QUEUE_EXT_POINT_PREFIX='dataplaneEventsQueue';const DESTINATION
|
|
3016
3048
|
* @returns Mutated event with final integrations config
|
3017
3049
|
*/const getFinalEvent=(event,state)=>{const finalEvent=clone$1(event);// Merge the destination specific integrations config with the event's integrations config
|
3018
3050
|
// In general, the preference is given to the event's integrations config
|
3019
|
-
const eventIntgConfig=event.integrations??DEFAULT_INTEGRATIONS_CONFIG;const destinationsIntgConfig=state.nativeDestinations.integrationsConfig.value;const overriddenIntgOpts=getOverriddenIntegrationOptions(eventIntgConfig,destinationsIntgConfig);finalEvent.integrations=mergeDeepRight(destinationsIntgConfig,overriddenIntgOpts);return finalEvent;};
|
3051
|
+
const eventIntgConfig=event.integrations??DEFAULT_INTEGRATIONS_CONFIG;const destinationsIntgConfig=state.nativeDestinations.integrationsConfig.value;const overriddenIntgOpts=getOverriddenIntegrationOptions(eventIntgConfig,destinationsIntgConfig);finalEvent.integrations=mergeDeepRight(destinationsIntgConfig,overriddenIntgOpts);return finalEvent;};const shouldBufferEventsForPreConsent=state=>state.consents.preConsent.value.enabled&&state.consents.preConsent.value.events?.delivery==='buffer'&&(state.consents.preConsent.value.storage?.strategy==='session'||state.consents.preConsent.value.storage?.strategy==='none');
|
3020
3052
|
|
3021
3053
|
/**
|
3022
3054
|
* Event repository class responsible for queuing events for further processing and delivery
|
@@ -3033,8 +3065,8 @@ O(()=>{if(state.nativeDestinations.clientDestinationsReady.value===true){this.de
|
|
3033
3065
|
// However, events will be enqueued for now.
|
3034
3066
|
// At the time of processing the events, the integrations config data from destinations
|
3035
3067
|
// is merged into the event object
|
3036
|
-
let timeoutId;O(()=>{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){globalThis.clearTimeout(timeoutId);this.dataplaneEventsQueue?.start();}});// Force start the data plane events queue processing after a timeout
|
3037
|
-
if(state.loadOptions.value.bufferDataPlaneEventsUntilReady===true){timeoutId=globalThis.setTimeout(()=>{if(this.dataplaneEventsQueue?.scheduleTimeoutActive!==true){this.dataplaneEventsQueue?.start();}},state.loadOptions.value.dataPlaneEventsBufferTimeout);}}/**
|
3068
|
+
let timeoutId;O(()=>{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)&&!shouldBufferEventsForPreConsent(state)&&this.dataplaneEventsQueue?.scheduleTimeoutActive!==true){globalThis.clearTimeout(timeoutId);this.dataplaneEventsQueue?.start();}});// Force start the data plane events queue processing after a timeout
|
3069
|
+
if(state.loadOptions.value.bufferDataPlaneEventsUntilReady===true){timeoutId=globalThis.setTimeout(()=>{if(this.dataplaneEventsQueue?.scheduleTimeoutActive!==true){this.dataplaneEventsQueue?.start();}},state.loadOptions.value.dataPlaneEventsBufferTimeout);}}resume(){if(this.dataplaneEventsQueue?.scheduleTimeoutActive!==true){if(state.consents.postConsent.value.discardPreConsentEvents){this.dataplaneEventsQueue?.clear();this.destinationsEventsQueue?.clear();}this.dataplaneEventsQueue?.start();}}/**
|
3038
3070
|
* Enqueues the event for processing
|
3039
3071
|
* @param event RudderEvent object
|
3040
3072
|
* @param callback API callback function
|
@@ -3056,14 +3088,16 @@ callback?.(dpQEvent);}catch(error){this.onError(error,API_CALLBACK_INVOKE_ERROR)
|
|
3056
3088
|
* Start application lifecycle if not already started
|
3057
3089
|
*/load(writeKey,dataPlaneUrl,loadOptions={}){if(state.lifecycle.status.value){return;}let clonedDataPlaneUrl=clone$1(dataPlaneUrl);let clonedLoadOptions=clone$1(loadOptions);// dataPlaneUrl is not provided
|
3058
3090
|
if(isObjectAndNotNull(dataPlaneUrl)){clonedLoadOptions=dataPlaneUrl;clonedDataPlaneUrl=undefined;}// Set initial state values
|
3059
|
-
n(()=>{state.lifecycle.writeKey.value=writeKey;state.lifecycle.dataPlaneUrl.value=clonedDataPlaneUrl;state.loadOptions.value=normalizeLoadOptions(state.loadOptions.value,clonedLoadOptions);state.lifecycle.status.value='mounted';});//
|
3091
|
+
n(()=>{state.lifecycle.writeKey.value=writeKey;state.lifecycle.dataPlaneUrl.value=clonedDataPlaneUrl;state.loadOptions.value=normalizeLoadOptions(state.loadOptions.value,clonedLoadOptions);state.lifecycle.status.value='mounted';});// set log level as early as possible
|
3092
|
+
if(state.loadOptions.value.logLevel){this.logger?.setMinLogLevel(state.loadOptions.value.logLevel);}// Expose state to global objects
|
3060
3093
|
setExposedGlobal('state',state,writeKey);// Configure initial config of any services or components here
|
3061
3094
|
// State application lifecycle
|
3062
3095
|
this.startLifecycle();}// Start lifecycle methods
|
3063
3096
|
/**
|
3064
3097
|
* Orchestrate the lifecycle of the application phases/status
|
3065
3098
|
*/startLifecycle(){O(()=>{try{switch(state.lifecycle.status.value){case'mounted':this.prepareBrowserCapabilities();break;case'browserCapabilitiesReady':// initialize the preloaded events enqueuing
|
3066
|
-
retrievePreloadBufferEvents(this);this.prepareInternalServices();this.loadConfig();break;case'configured':this.loadPlugins();break;case'pluginsLoading':break;case'pluginsReady':this.init();break;case'initialized':this.onInitialized();break;case'loaded':this.
|
3099
|
+
retrievePreloadBufferEvents(this);this.prepareInternalServices();this.loadConfig();break;case'configured':this.loadPlugins();break;case'pluginsLoading':break;case'pluginsReady':this.init();break;case'initialized':this.onInitialized();break;case'loaded':this.onLoaded();break;case'destinationsLoading':break;case'destinationsReady':this.onDestinationsReady();break;case'ready':this.onReady();break;default:break;}}catch(err){const issue='Failed to load the SDK';this.errorHandler.onError(getMutatedError(err,issue),ANALYTICS_CORE);}});}onLoaded(){this.processBufferedEvents();// Short-circuit the life cycle and move to the ready state if pre-consent behavior is enabled
|
3100
|
+
if(state.consents.preConsent.value.enabled===true){state.lifecycle.status.value='ready';}else {this.loadDestinations();}}/**
|
3067
3101
|
* Load browser polyfill if required
|
3068
3102
|
*/prepareBrowserCapabilities(){this.capabilitiesManager.init();}/**
|
3069
3103
|
* Enqueue in SDK preload buffer events, used from preloadBuffer component
|
@@ -3071,11 +3105,11 @@ retrievePreloadBufferEvents(this);this.prepareInternalServices();this.loadConfig
|
|
3071
3105
|
* Process the buffer preloaded events by passing their arguments to the respective facade methods
|
3072
3106
|
*/processDataInPreloadBuffer(){while(this.preloadBuffer.size()>0){const eventToProcess=this.preloadBuffer.dequeue();if(eventToProcess){consumePreloadBufferedEvent([...eventToProcess],this);}}}prepareInternalServices(){this.pluginsManager=new PluginsManager(defaultPluginEngine,this.errorHandler,this.logger);this.storeManager=new StoreManager(this.pluginsManager,this.errorHandler,this.logger);this.configManager=new ConfigManager(this.httpClient,this.errorHandler,this.logger);this.userSessionManager=new UserSessionManager(this.errorHandler,this.logger,this.pluginsManager,this.storeManager);this.eventRepository=new EventRepository(this.pluginsManager,this.storeManager,this.errorHandler,this.logger);this.eventManager=new EventManager(this.eventRepository,this.userSessionManager,this.errorHandler,this.logger);}/**
|
3073
3107
|
* Load configuration
|
3074
|
-
*/loadConfig(){if(
|
3108
|
+
*/loadConfig(){if(state.lifecycle.writeKey.value){this.httpClient.setAuthHeader(state.lifecycle.writeKey.value);}this.configManager?.init();}/**
|
3075
3109
|
* Initialize the storage and event queue
|
3076
3110
|
*/init(){this.errorHandler.init(this.externalSrcLoader);// Initialize storage
|
3077
|
-
this.storeManager?.init();this.userSessionManager?.init();// Initialize consent manager
|
3078
|
-
if(state.consents.
|
3111
|
+
this.storeManager?.init();this.userSessionManager?.init();// Initialize the appropriate consent manager plugin
|
3112
|
+
if(state.consents.enabled.value&&!state.consents.initialized.value){this.pluginsManager?.invokeSingle(`consentManager.init`,state,this.logger);if(state.consents.preConsent.value.enabled===false){this.pluginsManager?.invokeSingle(`consentManager.updateConsentsInfo`,state,this.storeManager,this.logger);}}// Initialize event manager
|
3079
3113
|
this.eventManager?.init();// Mark the SDK as initialized
|
3080
3114
|
state.lifecycle.status.value='initialized';}/**
|
3081
3115
|
* Load plugins
|
@@ -3092,19 +3126,21 @@ n(()=>{state.lifecycle.loaded.value=true;state.lifecycle.status.value='loaded';}
|
|
3092
3126
|
const initializedEvent=new CustomEvent('RSA_Initialised',{detail:{analyticsInstance:globalThis.rudderanalytics},bubbles:true,cancelable:true,composed:true});globalThis.document.dispatchEvent(initializedEvent);}/**
|
3093
3127
|
* Emit ready event
|
3094
3128
|
*/ // eslint-disable-next-line class-methods-use-this
|
3095
|
-
onReady(){
|
3129
|
+
onReady(){state.eventBuffer.readyCallbacksArray.value.forEach(callback=>{try{callback();}catch(err){this.errorHandler.onError(err,ANALYTICS_CORE,READY_CALLBACK_INVOKE_ERROR);}});// Emit an event to use as substitute to the ready callback
|
3096
3130
|
const readyEvent=new CustomEvent('RSA_Ready',{detail:{analyticsInstance:globalThis.rudderanalytics},bubbles:true,cancelable:true,composed:true});globalThis.document.dispatchEvent(readyEvent);}/**
|
3097
3131
|
* Consume preloaded events buffer
|
3098
3132
|
*/processBufferedEvents(){// Process buffered events
|
3099
3133
|
state.eventBuffer.toBeProcessedArray.value.forEach(bufferedItem=>{const methodName=bufferedItem[0];if(isFunction(this[methodName])){this[methodName](...bufferedItem.slice(1));}});state.eventBuffer.toBeProcessedArray.value=[];}/**
|
3100
3134
|
* Load device mode destinations
|
3101
|
-
*/loadDestinations(){// Set in state the desired activeDestinations to inject in DOM
|
3135
|
+
*/loadDestinations(){if(state.nativeDestinations.clientDestinationsReady.value){return;}// Set in state the desired activeDestinations to inject in DOM
|
3102
3136
|
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='destinationsReady';return;}// Start loading native integration scripts and create instances
|
3103
3137
|
state.lifecycle.status.value='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
|
3104
3138
|
O(()=>{const areAllDestinationsReady=totalDestinationsToLoad===0||state.nativeDestinations.initializedDestinations.value.length+state.nativeDestinations.failedDestinations.value.length===totalDestinationsToLoad;if(areAllDestinationsReady){n(()=>{state.lifecycle.status.value='destinationsReady';state.nativeDestinations.clientDestinationsReady.value=true;});}});}/**
|
3105
|
-
*
|
3139
|
+
* Move to the ready state
|
3106
3140
|
*/ // eslint-disable-next-line class-methods-use-this
|
3107
|
-
onDestinationsReady(){
|
3141
|
+
onDestinationsReady(){// May be do any destination specific actions here
|
3142
|
+
// Mark the ready status if not already done
|
3143
|
+
if(state.lifecycle.status.value!=='ready'){state.lifecycle.status.value='ready';}}// End lifecycle methods
|
3108
3144
|
// Start consumer exposed methods
|
3109
3145
|
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;}/**
|
3110
3146
|
* If destinations are loaded or no integration is available for loading
|
@@ -3123,7 +3159,13 @@ getUserId(){return state.session.userId.value;}// eslint-disable-next-line class
|
|
3123
3159
|
getUserTraits(){return state.session.userTraits.value;}// eslint-disable-next-line class-methods-use-this
|
3124
3160
|
getGroupId(){return state.session.groupId.value;}// eslint-disable-next-line class-methods-use-this
|
3125
3161
|
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
|
3126
|
-
getSessionId(){const sessionId=this.userSessionManager?.getSessionId();return sessionId??null;}
|
3162
|
+
getSessionId(){const sessionId=this.userSessionManager?.getSessionId();return sessionId??null;}consent(options){this.errorHandler.leaveBreadcrumb(`New consent invocation`);n(()=>{state.consents.preConsent.value={...state.consents.preConsent.value,enabled:false};state.consents.postConsent.value=getValidPostConsentOptions(options);const{initialized,consentsData}=getConsentManagementData(state.consents.postConsent.value.consentManagement,this.logger);state.consents.initialized.value=initialized||state.consents.initialized.value;state.consents.data.value=consentsData;});// Update consents data in state
|
3163
|
+
if(state.consents.enabled.value&&!state.consents.initialized.value){this.pluginsManager?.invokeSingle(`consentManager.updateConsentsInfo`,state,this.storeManager,this.logger);}// TODO: Re-init store manager
|
3164
|
+
// this.storeManager?.initClientDataStores();
|
3165
|
+
// TODO: Re-init user session manager
|
3166
|
+
// this.userSessionManager?.syncStorageDataToState();
|
3167
|
+
// Resume event manager to process the events to destinations
|
3168
|
+
this.eventManager?.resume();this.loadDestinations();}setAuthToken(token){this.userSessionManager?.setAuthToken(token);}// End consumer exposed methods
|
3127
3169
|
}
|
3128
3170
|
|
3129
3171
|
/*
|
@@ -3135,7 +3177,7 @@ getSessionId(){const sessionId=this.userSessionManager?.getSessionId();return se
|
|
3135
3177
|
constructor(){if(RudderAnalytics.globalSingleton){// START-NO-SONAR-SCAN
|
3136
3178
|
// eslint-disable-next-line no-constructor-return
|
3137
3179
|
return RudderAnalytics.globalSingleton;// END-NO-SONAR-SCAN
|
3138
|
-
}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);this.setAuthToken=this.setAuthToken.bind(this);RudderAnalytics.globalSingleton=this;// get the preloaded events before replacing global object
|
3180
|
+
}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);this.setAuthToken=this.setAuthToken.bind(this);this.consent=this.consent.bind(this);RudderAnalytics.globalSingleton=this;// get the preloaded events before replacing global object
|
3139
3181
|
this.getPreloadBuffer();// start loading if a load event was buffered or wait for explicit load call
|
3140
3182
|
this.triggerBufferedLoadEvent();}/**
|
3141
3183
|
* Set instance to use if no specific writeKey is provided in methods
|
@@ -3168,6 +3210,6 @@ this.load.apply(null,loadEvent);}}/**
|
|
3168
3210
|
* Process alias arguments and forward to page call
|
3169
3211
|
*/alias(to,from,options,callback){this.getAnalyticsInstance().alias(aliasArgumentsToCallOptions(to,from,options,callback));}/**
|
3170
3212
|
* Process group arguments and forward to page call
|
3171
|
-
*/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();}setAuthToken(token){return this.getAnalyticsInstance().setAuthToken(token);}}
|
3213
|
+
*/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();}setAuthToken(token){return this.getAnalyticsInstance().setAuthToken(token);}consent(options){return this.getAnalyticsInstance().consent(options);}}
|
3172
3214
|
|
3173
3215
|
exports.RudderAnalytics = RudderAnalytics;
|