@rudderstack/analytics-js 3.0.0-beta.14 → 3.0.0-beta.15
Sign up to get free protection for your applications and to get access to all the features.
- package/CHANGELOG.md +17 -0
- package/dist/npm/index.d.ts +55 -35
- package/dist/npm/legacy/cjs/index.js +276 -247
- package/dist/npm/legacy/esm/index.js +276 -247
- package/dist/npm/legacy/umd/index.js +276 -247
- package/dist/npm/modern/bundled/cjs/index.js +275 -245
- package/dist/npm/modern/bundled/esm/index.js +275 -245
- package/dist/npm/modern/bundled/umd/index.js +275 -245
- package/dist/npm/modern/cjs/index.js +157 -152
- package/dist/npm/modern/esm/index.js +157 -152
- package/dist/npm/modern/umd/index.js +157 -152
- package/package.json +3 -2
@@ -417,7 +417,7 @@ if(isDefined(payload.groupId)){payload.groupId=tryStringify(payload.groupId);}el
|
|
417
417
|
|
418
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';
|
419
419
|
|
420
|
-
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.15';const APP_NAMESPACE='com.rudderlabs.javascript';const MODULE_TYPE='npm';const ADBLOCK_PAGE_CATEGORY='RudderJS-Initiated';const ADBLOCK_PAGE_NAME='ad-block page request';const ADBLOCK_PAGE_PATH='/ad-blocked';const GLOBAL_PRELOAD_BUFFER='preloadedEventsBuffer';const CONSENT_TRACK_EVENT_NAME='Consent Management Interaction';
|
421
421
|
|
422
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';
|
423
423
|
|
@@ -450,11 +450,17 @@ if(queryObject.get(QUERY_PARAM_ANONYMOUS_ID_KEY)){argumentsArray.unshift(['setAn
|
|
450
450
|
* Retrieve an existing buffered load method call and remove from the existing array
|
451
451
|
*/const getPreloadedLoadEvent=preloadedEventsArray=>{const loadMethodName='load';let loadEvent=[];/**
|
452
452
|
* Iterate the buffered API calls until we find load call and process it separately
|
453
|
-
*/let i=0;while(i<preloadedEventsArray.length){if(preloadedEventsArray[i]&&preloadedEventsArray[i][0]===loadMethodName){loadEvent=preloadedEventsArray[i];preloadedEventsArray.splice(i,1);break;}i+=1;}return loadEvent;};/**
|
453
|
+
*/let i=0;while(i<preloadedEventsArray.length){if(preloadedEventsArray[i]&&preloadedEventsArray[i][0]===loadMethodName){loadEvent=clone$1(preloadedEventsArray[i]);preloadedEventsArray.splice(i,1);break;}i+=1;}return loadEvent;};/**
|
454
|
+
* Promote consent events to the top of the preloaded events array
|
455
|
+
* @param preloadedEventsArray Preloaded events array
|
456
|
+
* @returns None
|
457
|
+
*/const promotePreloadedConsentEventsToTop=preloadedEventsArray=>{const consentMethodName='consent';const consentEvents=preloadedEventsArray.filter(bufferedEvent=>bufferedEvent[0]===consentMethodName);const nonConsentEvents=preloadedEventsArray.filter(bufferedEvent=>bufferedEvent[0]!==consentMethodName);// Remove all elements and add consent events first followed by non consent events
|
458
|
+
// eslint-disable-next-line unicorn/no-useless-spread
|
459
|
+
preloadedEventsArray.splice(0,preloadedEventsArray.length,...consentEvents,...nonConsentEvents);};/**
|
454
460
|
* Retrieve any existing events that were triggered before SDK load and enqueue in buffer
|
455
461
|
*/const retrievePreloadBufferEvents=instance=>{const preloadedEventsArray=getExposedGlobal(GLOBAL_PRELOAD_BUFFER)||[];// Get events that are pre-populated via query string params
|
456
|
-
retrieveEventsFromQueryString(preloadedEventsArray)
|
457
|
-
if(
|
462
|
+
retrieveEventsFromQueryString(preloadedEventsArray);// Enqueue the non load events in the buffer of the global rudder analytics singleton
|
463
|
+
if(preloadedEventsArray.length>0){instance.enqueuePreloadBufferEvents(preloadedEventsArray);setExposedGlobal(GLOBAL_PRELOAD_BUFFER,[]);}};const consumePreloadBufferedEvent=(event,analyticsInstance)=>{const methodName=event.shift();let callOptions;if(isFunction(analyticsInstance[methodName])){switch(methodName){case'page':callOptions=pageArgumentsToCallOptions(...event);break;case'track':callOptions=trackArgumentsToCallOptions(...event);break;case'identify':callOptions=identifyArgumentsToCallOptions(...event);break;case'alias':callOptions=aliasArgumentsToCallOptions(...event);break;case'group':callOptions=groupArgumentsToCallOptions(...event);break;default:analyticsInstance[methodName](...event);break;}if(callOptions){analyticsInstance[methodName](callOptions);}}};
|
458
464
|
|
459
465
|
const DEFAULT_EXT_SRC_LOAD_TIMEOUT_MS=10*1000;// 10 seconds
|
460
466
|
|
@@ -546,9 +552,9 @@ styledLogArgs.push(...data.slice(1));return styledLogArgs;}return data;}}const d
|
|
546
552
|
// default is v3
|
547
553
|
const SUPPORTED_STORAGE_TYPES=['localStorage','memoryStorage','cookieStorage','sessionStorage','none'];const DEFAULT_STORAGE_TYPE='cookieStorage';
|
548
554
|
|
549
|
-
const SOURCE_CONFIG_OPTION_ERROR=`"getSourceConfig" must be a function. Please make sure that it is defined and returns a valid source configuration object.`;const INTG_CDN_BASE_URL_ERROR=`Failed to load the SDK as the CDN base URL for integrations is not valid.`;const PLUGINS_CDN_BASE_URL_ERROR=`Failed to load the SDK as the CDN base URL for plugins is not valid.`;const DATA_PLANE_URL_ERROR=`Failed to load the SDK as the data plane URL could not be determined. Please check that the data plane URL is set correctly and try again.`;const XHR_PAYLOAD_PREP_ERROR=`Failed to prepare data for the request.`;const EVENT_OBJECT_GENERATION_ERROR=`Failed to generate the event object.`;const PLUGIN_EXT_POINT_MISSING_ERROR=`Failed to invoke plugin because the extension point name is missing.`;const PLUGIN_EXT_POINT_INVALID_ERROR=`Failed to invoke plugin because the extension point name is invalid.`;// ERROR
|
555
|
+
const SOURCE_CONFIG_OPTION_ERROR=`"getSourceConfig" must be a function. Please make sure that it is defined and returns a valid source configuration object.`;const INTG_CDN_BASE_URL_ERROR=`Failed to load the SDK as the CDN base URL for integrations is not valid.`;const PLUGINS_CDN_BASE_URL_ERROR=`Failed to load the SDK as the CDN base URL for plugins is not valid.`;const DATA_PLANE_URL_ERROR=`Failed to load the SDK as the data plane URL could not be determined. Please check that the data plane URL is set correctly and try again.`;const SOURCE_CONFIG_RESOLUTION_ERROR=`Unable to process/parse source configuration response.`;const XHR_PAYLOAD_PREP_ERROR=`Failed to prepare data for the request.`;const EVENT_OBJECT_GENERATION_ERROR=`Failed to generate the event object.`;const PLUGIN_EXT_POINT_MISSING_ERROR=`Failed to invoke plugin because the extension point name is missing.`;const PLUGIN_EXT_POINT_INVALID_ERROR=`Failed to invoke plugin because the extension point name is invalid.`;// ERROR
|
550
556
|
const UNSUPPORTED_CONSENT_MANAGER_ERROR=(context,selectedConsentManager,consentManagersToPluginNameMap)=>`${context}${LOG_CONTEXT_SEPARATOR}The consent manager "${selectedConsentManager}" is not supported. Please choose one of the following supported consent managers: "${Object.keys(consentManagersToPluginNameMap)}".`;const REPORTING_PLUGIN_INIT_FAILURE_ERROR=context=>`${context}${LOG_CONTEXT_SEPARATOR}Failed to initialize the error reporting plugin.`;const NOTIFY_FAILURE_ERROR=context=>`${context}${LOG_CONTEXT_SEPARATOR}Failed to notify the error.`;const PLUGIN_NAME_MISSING_ERROR=context=>`${context}${LOG_CONTEXT_SEPARATOR}Plugin name is missing.`;const PLUGIN_ALREADY_EXISTS_ERROR=(context,pluginName)=>`${context}${LOG_CONTEXT_SEPARATOR}Plugin "${pluginName}" already exists.`;const PLUGIN_NOT_FOUND_ERROR=(context,pluginName)=>`${context}${LOG_CONTEXT_SEPARATOR}Plugin "${pluginName}" not found.`;const PLUGIN_ENGINE_BUG_ERROR=(context,pluginName)=>`${context}${LOG_CONTEXT_SEPARATOR}Plugin "${pluginName}" not found in plugins but found in byName. This indicates a bug in the plugin engine. Please report this issue to the development team.`;const PLUGIN_DEPS_ERROR=(context,pluginName,notExistDeps)=>`${context}${LOG_CONTEXT_SEPARATOR}Plugin "${pluginName}" could not be loaded because some of its dependencies "${notExistDeps}" do not exist.`;const PLUGIN_INVOCATION_ERROR=(context,extPoint,pluginName)=>`${context}${LOG_CONTEXT_SEPARATOR}Failed to invoke the "${extPoint}" extension point of plugin "${pluginName}".`;const STORAGE_UNAVAILABILITY_ERROR_PREFIX=(context,storageType)=>`${context}${LOG_CONTEXT_SEPARATOR}The "${storageType}" storage type is `;const SOURCE_CONFIG_FETCH_ERROR=reason=>`Failed to fetch the source config. Reason: ${reason}`;const WRITE_KEY_VALIDATION_ERROR=writeKey=>`The write key "${writeKey}" is invalid. It must be a non-empty string. Please check that the write key is correct and try again.`;const DATA_PLANE_URL_VALIDATION_ERROR=dataPlaneUrl=>`The data plane URL "${dataPlaneUrl}" is invalid. It must be a valid URL string. Please check that the data plane URL is correct and try again.`;const READY_API_CALLBACK_ERROR=context=>`${context}${LOG_CONTEXT_SEPARATOR}The callback is not a function.`;const XHR_DELIVERY_ERROR=(prefix,status,statusText,url)=>`${prefix} with status: ${status}, ${statusText} for URL: ${url}.`;const XHR_REQUEST_ERROR=(prefix,e,url)=>`${prefix} due to timeout or no connection (${e?e.type:''}) for URL: ${url}.`;const XHR_SEND_ERROR=(prefix,url)=>`${prefix} for URL: ${url}`;const STORE_DATA_SAVE_ERROR=key=>`Failed to save the value for "${key}" to storage`;const STORE_DATA_FETCH_ERROR=key=>`Failed to retrieve or parse data for "${key}" from storage`;// WARNING
|
551
|
-
const STORAGE_TYPE_VALIDATION_WARNING=(context,storageType,defaultStorageType)=>`${context}${LOG_CONTEXT_SEPARATOR}The storage type "${storageType}" is not supported. Please choose one of the following supported types: "${SUPPORTED_STORAGE_TYPES}". The default type "${defaultStorageType}" will be used instead.`;const UNSUPPORTED_ERROR_REPORTING_PROVIDER_WARNING=(context,selectedErrorReportingProvider,errorReportingProvidersToPluginNameMap,defaultProvider)=>`${context}${LOG_CONTEXT_SEPARATOR}The error reporting provider "${selectedErrorReportingProvider}" is not supported. Please choose one of the following supported providers: "${Object.keys(errorReportingProvidersToPluginNameMap)}". The default provider "${defaultProvider}" will be used instead.`;const UNSUPPORTED_STORAGE_ENCRYPTION_VERSION_WARNING=(context,selectedStorageEncryptionVersion,storageEncryptionVersionsToPluginNameMap,defaultVersion)=>`${context}${LOG_CONTEXT_SEPARATOR}The storage encryption version "${selectedStorageEncryptionVersion}" is not supported. Please choose one of the following supported versions: "${Object.keys(storageEncryptionVersionsToPluginNameMap)}". The default version "${defaultVersion}" will be used instead.`;const STORAGE_DATA_MIGRATION_OVERRIDE_WARNING=(context,storageEncryptionVersion,defaultVersion)=>`${context}${LOG_CONTEXT_SEPARATOR}The storage data migration has been disabled because the configured storage encryption version (${storageEncryptionVersion}) is not the latest (${defaultVersion}). To enable storage data migration, please update the storage encryption version to the latest version.`;const UNSUPPORTED_RESIDENCY_SERVER_REGION_WARNING=(context,selectedResidencyServerRegion,defaultRegion)=>`${context}${LOG_CONTEXT_SEPARATOR}The residency server region "${selectedResidencyServerRegion}" is not supported. Please choose one of the following supported regions: "US, EU". The default region "${defaultRegion}" will be used instead.`;const RESERVED_KEYWORD_WARNING=(context,property,parentKeyPath,reservedElements)=>`${context}${LOG_CONTEXT_SEPARATOR}The "${property}" property defined under "${parentKeyPath}" is a reserved keyword. Please choose a different property name to avoid conflicts with reserved keywords (${reservedElements}).`;const INVALID_CONTEXT_OBJECT_WARNING=logContext=>`${logContext}${LOG_CONTEXT_SEPARATOR}Please make sure that the "context" property in the event API's "options" argument is a valid object literal with key-value pairs.`;const UNSUPPORTED_BEACON_API_WARNING=context=>`${context}${LOG_CONTEXT_SEPARATOR}The Beacon API is not supported by your browser. The events will be sent using XHR instead.`;const TIMEOUT_NOT_NUMBER_WARNING=(context,timeout,defaultValue)=>`${context}${LOG_CONTEXT_SEPARATOR}The session timeout value "${timeout}" is not a number. The default timeout of ${defaultValue} ms will be used instead.`;const TIMEOUT_ZERO_WARNING=context=>`${context}${LOG_CONTEXT_SEPARATOR}The session timeout value is 0, which disables the automatic session tracking feature. If you want to enable session tracking, please provide a positive integer value for the timeout.`;const TIMEOUT_NOT_RECOMMENDED_WARNING=(context,timeout,minTimeout)=>`${context}${LOG_CONTEXT_SEPARATOR}The session timeout value ${timeout} ms is less than the recommended minimum of ${minTimeout} ms. Please consider increasing the timeout value to ensure optimal performance and reliability.`;const INVALID_SESSION_ID_WARNING=(context,sessionId,minSessionIdLength)=>`${context}${LOG_CONTEXT_SEPARATOR}The provided session ID (${sessionId}) is either invalid, not a positive integer, or not at least "${minSessionIdLength}" digits long. A new session ID will be auto-generated instead.`;const STORAGE_QUOTA_EXCEEDED_WARNING=context=>`${context}${LOG_CONTEXT_SEPARATOR}The storage is either full or unavailable, so the data will not be persisted. Switching to in-memory storage.`;const STORAGE_UNAVAILABLE_WARNING=(context,selectedStorageType,finalStorageType)=>`${context}${LOG_CONTEXT_SEPARATOR}The storage type "${selectedStorageType}" is not available. The SDK will
|
557
|
+
const STORAGE_TYPE_VALIDATION_WARNING=(context,storageType,defaultStorageType)=>`${context}${LOG_CONTEXT_SEPARATOR}The storage type "${storageType}" is not supported. Please choose one of the following supported types: "${SUPPORTED_STORAGE_TYPES}". The default type "${defaultStorageType}" will be used instead.`;const UNSUPPORTED_ERROR_REPORTING_PROVIDER_WARNING=(context,selectedErrorReportingProvider,errorReportingProvidersToPluginNameMap,defaultProvider)=>`${context}${LOG_CONTEXT_SEPARATOR}The error reporting provider "${selectedErrorReportingProvider}" is not supported. Please choose one of the following supported providers: "${Object.keys(errorReportingProvidersToPluginNameMap)}". The default provider "${defaultProvider}" will be used instead.`;const UNSUPPORTED_STORAGE_ENCRYPTION_VERSION_WARNING=(context,selectedStorageEncryptionVersion,storageEncryptionVersionsToPluginNameMap,defaultVersion)=>`${context}${LOG_CONTEXT_SEPARATOR}The storage encryption version "${selectedStorageEncryptionVersion}" is not supported. Please choose one of the following supported versions: "${Object.keys(storageEncryptionVersionsToPluginNameMap)}". The default version "${defaultVersion}" will be used instead.`;const STORAGE_DATA_MIGRATION_OVERRIDE_WARNING=(context,storageEncryptionVersion,defaultVersion)=>`${context}${LOG_CONTEXT_SEPARATOR}The storage data migration has been disabled because the configured storage encryption version (${storageEncryptionVersion}) is not the latest (${defaultVersion}). To enable storage data migration, please update the storage encryption version to the latest version.`;const UNSUPPORTED_RESIDENCY_SERVER_REGION_WARNING=(context,selectedResidencyServerRegion,defaultRegion)=>`${context}${LOG_CONTEXT_SEPARATOR}The residency server region "${selectedResidencyServerRegion}" is not supported. Please choose one of the following supported regions: "US, EU". The default region "${defaultRegion}" will be used instead.`;const RESERVED_KEYWORD_WARNING=(context,property,parentKeyPath,reservedElements)=>`${context}${LOG_CONTEXT_SEPARATOR}The "${property}" property defined under "${parentKeyPath}" is a reserved keyword. Please choose a different property name to avoid conflicts with reserved keywords (${reservedElements}).`;const INVALID_CONTEXT_OBJECT_WARNING=logContext=>`${logContext}${LOG_CONTEXT_SEPARATOR}Please make sure that the "context" property in the event API's "options" argument is a valid object literal with key-value pairs.`;const UNSUPPORTED_BEACON_API_WARNING=context=>`${context}${LOG_CONTEXT_SEPARATOR}The Beacon API is not supported by your browser. The events will be sent using XHR instead.`;const TIMEOUT_NOT_NUMBER_WARNING=(context,timeout,defaultValue)=>`${context}${LOG_CONTEXT_SEPARATOR}The session timeout value "${timeout}" is not a number. The default timeout of ${defaultValue} ms will be used instead.`;const TIMEOUT_ZERO_WARNING=context=>`${context}${LOG_CONTEXT_SEPARATOR}The session timeout value is 0, which disables the automatic session tracking feature. If you want to enable session tracking, please provide a positive integer value for the timeout.`;const TIMEOUT_NOT_RECOMMENDED_WARNING=(context,timeout,minTimeout)=>`${context}${LOG_CONTEXT_SEPARATOR}The session timeout value ${timeout} ms is less than the recommended minimum of ${minTimeout} ms. Please consider increasing the timeout value to ensure optimal performance and reliability.`;const INVALID_SESSION_ID_WARNING=(context,sessionId,minSessionIdLength)=>`${context}${LOG_CONTEXT_SEPARATOR}The provided session ID (${sessionId}) is either invalid, not a positive integer, or not at least "${minSessionIdLength}" digits long. A new session ID will be auto-generated instead.`;const STORAGE_QUOTA_EXCEEDED_WARNING=context=>`${context}${LOG_CONTEXT_SEPARATOR}The storage is either full or unavailable, so the data will not be persisted. Switching to in-memory storage.`;const STORAGE_UNAVAILABLE_WARNING=(context,entry,selectedStorageType,finalStorageType)=>`${context}${LOG_CONTEXT_SEPARATOR}The storage type "${selectedStorageType}" is not available for entry "${entry}". The SDK will initialize the entry with "${finalStorageType}" storage type instead.`;const WRITE_KEY_NOT_A_STRING_ERROR=(context,writeKey)=>`${context}${LOG_CONTEXT_SEPARATOR}The write key "${writeKey}" is not a string. Please check that the write key is correct and try again.`;const EMPTY_GROUP_CALL_ERROR=context=>`${context}${LOG_CONTEXT_SEPARATOR}The group() method must be called with at least one argument.`;const READY_CALLBACK_INVOKE_ERROR=`Failed to invoke the ready callback`;const API_CALLBACK_INVOKE_ERROR=`API Callback Invocation Failed`;const INVALID_CONFIG_URL_WARNING=(context,configUrl)=>`${context}${LOG_CONTEXT_SEPARATOR}The provided config URL "${configUrl}" is invalid. Using the default value instead.`;const POLYFILL_SCRIPT_LOAD_ERROR=(scriptId,url)=>`Failed to load the polyfill script with ID "${scriptId}" from URL ${url}.`;const COOKIE_DATA_ENCODING_ERROR=`Failed to encode the cookie data.`;const UNSUPPORTED_PRE_CONSENT_STORAGE_STRATEGY=(context,selectedStrategy,defaultStrategy)=>`${context}${LOG_CONTEXT_SEPARATOR}The pre-consent storage strategy "${selectedStrategy}" is not supported. Please choose one of the following supported strategies: "none, session, anonymousId". The default strategy "${defaultStrategy}" will be used instead.`;const UNSUPPORTED_PRE_CONSENT_EVENTS_DELIVERY_TYPE=(context,selectedDeliveryType,defaultDeliveryType)=>`${context}${LOG_CONTEXT_SEPARATOR}The pre-consent events delivery type "${selectedDeliveryType}" is not supported. Please choose one of the following supported types: "immediate, buffer". The default type "${defaultDeliveryType}" will be used instead.`;// DEBUG
|
552
558
|
|
553
559
|
const CDN_INT_DIR='js-integrations';const CDN_PLUGINS_DIR='plugins';
|
554
560
|
|
@@ -561,9 +567,9 @@ const DEFAULT_ERROR_REPORTING_PROVIDER='bugsnag';const DEFAULT_STORAGE_ENCRYPTIO
|
|
561
567
|
|
562
568
|
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));
|
563
569
|
|
564
|
-
const
|
570
|
+
const USER_SESSION_STORAGE_KEYS={userId:'rl_user_id',userTraits:'rl_trait',anonymousId:'rl_anonymous_id',groupId:'rl_group_id',groupTraits:'rl_group_trait',initialReferrer:'rl_page_init_referrer',initialReferringDomain:'rl_page_init_referring_domain',sessionInfo:'rl_session',authToken:'rl_auth_token'};const DEFAULT_USER_SESSION_VALUES={userId:'',userTraits:{},anonymousId:'',groupId:'',groupTraits:{},initialReferrer:'',initialReferringDomain:'',sessionInfo:{},authToken:null};
|
565
571
|
|
566
|
-
const defaultSessionInfo={autoTrack:true,timeout:DEFAULT_SESSION_TIMEOUT_MS};const sessionState={userId:a(
|
572
|
+
const defaultSessionInfo={autoTrack:true,timeout:DEFAULT_SESSION_TIMEOUT_MS};const sessionState={userId:a(DEFAULT_USER_SESSION_VALUES.userId),userTraits:a(DEFAULT_USER_SESSION_VALUES.userTraits),anonymousId:a(DEFAULT_USER_SESSION_VALUES.anonymousId),groupId:a(DEFAULT_USER_SESSION_VALUES.groupId),groupTraits:a(DEFAULT_USER_SESSION_VALUES.groupTraits),initialReferrer:a(DEFAULT_USER_SESSION_VALUES.initialReferrer),initialReferringDomain:a(DEFAULT_USER_SESSION_VALUES.initialReferringDomain),sessionInfo:a(DEFAULT_USER_SESSION_VALUES.sessionInfo),authToken:a(DEFAULT_USER_SESSION_VALUES.authToken)};
|
567
573
|
|
568
574
|
const capabilitiesState={isOnline:a(true),storage:{isLocalStorageAvailable:a(false),isCookieStorageAvailable:a(false),isSessionStorageAvailable:a(false)},isBeaconAvailable:a(false),isLegacyDOM:a(false),isUaCHAvailable:a(false),isCryptoAvailable:a(false),isIE11:a(false),isAdBlocked:a(false)};
|
569
575
|
|
@@ -573,7 +579,7 @@ const sourceConfigState=a(undefined);
|
|
573
579
|
|
574
580
|
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)};
|
575
581
|
|
576
|
-
const consentsState={enabled:a(false),initialized:a(false),data:a({}),activeConsentManagerPluginName:a(undefined),preConsent:a({enabled:false}),postConsent:a({})};
|
582
|
+
const consentsState={enabled:a(false),initialized:a(false),data:a({}),activeConsentManagerPluginName:a(undefined),preConsent:a({enabled:false}),postConsent:a({}),resolutionStrategy:a('and'),provider:a(undefined),metadata:a(undefined)};
|
577
583
|
|
578
584
|
const metricsState={retries:a(0),dropped:a(0),sent:a(0),queued:a(0),triggered:a(0)};
|
579
585
|
|
@@ -751,7 +757,8 @@ if(curEntry){this.pushToMainQueue(curEntry);}}/**
|
|
751
757
|
* @param entry New item added to the retry queue
|
752
758
|
* @returns Undefined or batch entry object
|
753
759
|
*/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
|
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=[];}
|
760
|
+
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=[];}// Don't make any batch request if there are no items
|
761
|
+
if(batchItems.length>0){curEntry=this.genQueueItem(batchItems);}// re-attach the timeout handler
|
755
762
|
this.scheduleFlushBatch();}this.batchingInProgress=false;}else {batchQueue.push(entry);}// update the batch queue
|
756
763
|
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();}}/**
|
757
764
|
* Adds an item to the queue
|
@@ -846,7 +853,7 @@ event.context='Script load failures';}// eslint-disable-next-line no-param-reass
|
|
846
853
|
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
|
847
854
|
if(!isRudderSDKError(event)){return false;}enhanceErrorEventMutator(event,metadataSource);return true;}catch{// Drop the error event if it couldn't be filtered as
|
848
855
|
// it is most likely a non-SDK error
|
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.
|
856
|
+
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.15',// Set SDK version as the app version from build config
|
850
857
|
metaData:{SDK:{name:'JS',installType:'npm'}},beforeSend:onError(state),autoCaptureSessions:false,// auto capture sessions is disabled
|
851
858
|
collectUserIp:false,// collecting user's IP is disabled
|
852
859
|
// enabledBreadcrumbTypes: ['error', 'log', 'user'], // for v7 and above
|
@@ -856,164 +863,171 @@ globalThis.setTimeout(initBugsnagClient,SDK_LOAD_POLL_INTERVAL_MS,state,promiseR
|
|
856
863
|
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
|
857
864
|
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);}}});
|
858
865
|
|
859
|
-
|
866
|
+
const CUSTOM_CONSENT_MANAGER_PLUGIN='CustomConsentManagerPlugin';
|
867
|
+
|
868
|
+
const DESTINATION_CONSENT_STATUS_ERROR$2=`Failed to determine the consent status for the destination. Please check the destination configuration and try again.`;
|
869
|
+
|
870
|
+
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
871
|
},updateConsentsInfo(state,storeManager,logger){// Nothing to update. Already provided by the user
|
861
|
-
},isDestinationConsented(state,destConfig,errorHandler,logger){
|
862
|
-
|
863
|
-
|
864
|
-
|
865
|
-
|
872
|
+
},isDestinationConsented(state,destConfig,errorHandler,logger){if(!state.consents.initialized.value){return true;}const allowedConsentIds=state.consents.data.value.allowedConsentIds;try{const{consentManagement}=destConfig;// If the destination does not have consent management config, events should be sent.
|
873
|
+
if(!consentManagement){return true;}// Get the corresponding consents for the destination
|
874
|
+
const cmpConfig=consentManagement.find(c=>c.provider===state.consents.provider.value);// If there are no consents configured for the destination for the current provider, events should be sent.
|
875
|
+
if(!cmpConfig?.consents){return true;}const configuredConsents=cmpConfig.consents.map(c=>c.consent.trim()).filter(n=>n);const resolutionStrategy=cmpConfig.resolutionStrategy??state.consents.resolutionStrategy.value;// match the configured consents with user provided consents as per
|
876
|
+
// the configured resolution strategy
|
877
|
+
const matchPredicate=consent=>allowedConsentIds.includes(consent);switch(resolutionStrategy){case'or':return configuredConsents.some(matchPredicate)||configuredConsents.length===0;case'and':default:return configuredConsents.every(matchPredicate);}}catch(err){errorHandler?.onError(err,CUSTOM_CONSENT_MANAGER_PLUGIN,DESTINATION_CONSENT_STATUS_ERROR$2);return true;}}}});
|
866
878
|
|
867
|
-
const DIR_NAME$
|
879
|
+
const DIR_NAME$1a='AdobeAnalytics';const DISPLAY_NAME$1a='Adobe Analytics';
|
868
880
|
|
869
|
-
const DIR_NAME$
|
881
|
+
const DIR_NAME$19='Amplitude';const DISPLAY_NAME$19='Amplitude';
|
870
882
|
|
871
|
-
const DIR_NAME$
|
883
|
+
const DIR_NAME$18='Appcues';const DISPLAY_NAME$18='Appcues';
|
872
884
|
|
873
|
-
const DIR_NAME$
|
885
|
+
const DIR_NAME$17='BingAds';const DISPLAY_NAME$17='Bing Ads';
|
874
886
|
|
875
|
-
const DIR_NAME$
|
887
|
+
const DIR_NAME$16='Braze';const DISPLAY_NAME$16='Braze';
|
876
888
|
|
877
|
-
const DIR_NAME$
|
889
|
+
const DIR_NAME$15='Bugsnag';const DISPLAY_NAME$15='Bugsnag';
|
878
890
|
|
879
|
-
const DIR_NAME$
|
891
|
+
const DIR_NAME$14='Chartbeat';const DISPLAY_NAME$14='Chartbeat';
|
880
892
|
|
881
|
-
const DIR_NAME$
|
893
|
+
const DIR_NAME$13='Clevertap';const DISPLAY_NAME$13='CleverTap';
|
882
894
|
|
883
|
-
const DIR_NAME$
|
895
|
+
const DIR_NAME$12='Comscore';const DISPLAY_NAME$12='Comscore';
|
884
896
|
|
885
|
-
const DIR_NAME$
|
897
|
+
const DIR_NAME$11='Criteo';const DISPLAY_NAME$11='Criteo';
|
886
898
|
|
887
|
-
const DIR_NAME
|
899
|
+
const DIR_NAME$10='CustomerIO';const DISPLAY_NAME$10='Customer IO';
|
888
900
|
|
889
|
-
const DIR_NAME
|
901
|
+
const DIR_NAME$$='Drip';const DISPLAY_NAME$$='Drip';
|
890
902
|
|
891
|
-
const DIR_NAME$
|
903
|
+
const DIR_NAME$_='FacebookPixel';const DISPLAY_NAME$_='Facebook Pixel';
|
892
904
|
|
893
|
-
const DIR_NAME$
|
905
|
+
const DIR_NAME$Z='Fullstory';const DISPLAY_NAME$Z='Fullstory';
|
894
906
|
|
895
|
-
const DIR_NAME$
|
907
|
+
const DIR_NAME$Y='GA';const DISPLAY_NAME$Y='Google Analytics';
|
896
908
|
|
897
|
-
const DIR_NAME$
|
909
|
+
const DIR_NAME$X='GA4';const DISPLAY_NAME$X='Google Analytics 4 (GA4)';
|
898
910
|
|
899
|
-
const DIR_NAME$
|
911
|
+
const DIR_NAME$W='GoogleAds';const DISPLAY_NAME$W='Google Ads';
|
900
912
|
|
901
|
-
const DIR_NAME$
|
913
|
+
const DIR_NAME$V='GoogleOptimize';const DISPLAY_NAME$V='Google Optimize';
|
902
914
|
|
903
|
-
const DIR_NAME$
|
915
|
+
const DIR_NAME$U='GoogleTagManager';const DISPLAY_NAME$U='Google Tag Manager';
|
904
916
|
|
905
|
-
const DIR_NAME$
|
917
|
+
const DIR_NAME$T='Heap';const DISPLAY_NAME$T='Heap.io';
|
906
918
|
|
907
|
-
const DIR_NAME$
|
919
|
+
const DIR_NAME$S='Hotjar';const DISPLAY_NAME$S='Hotjar';
|
908
920
|
|
909
|
-
const DIR_NAME$
|
921
|
+
const DIR_NAME$R='HubSpot';const DISPLAY_NAME$R='HubSpot';
|
910
922
|
|
911
|
-
const DIR_NAME$
|
923
|
+
const DIR_NAME$Q='INTERCOM';const DISPLAY_NAME$Q='Intercom';
|
912
924
|
|
913
|
-
const DIR_NAME$
|
925
|
+
const DIR_NAME$P='Keen';const DISPLAY_NAME$P='Keen';
|
914
926
|
|
915
|
-
const DIR_NAME$
|
927
|
+
const DIR_NAME$O='Kissmetrics';const DISPLAY_NAME$O='Kiss Metrics';
|
916
928
|
|
917
|
-
const DIR_NAME$
|
929
|
+
const DIR_NAME$N='Klaviyo';const DISPLAY_NAME$N='Klaviyo';
|
918
930
|
|
919
|
-
const DIR_NAME$
|
931
|
+
const DIR_NAME$M='LaunchDarkly';const DISPLAY_NAME$M='LaunchDarkly';
|
920
932
|
|
921
|
-
const DIR_NAME$
|
933
|
+
const DIR_NAME$L='LinkedInInsightTag';const DISPLAY_NAME$L='Linkedin Insight Tag';
|
922
934
|
|
923
|
-
const DIR_NAME$
|
935
|
+
const DIR_NAME$K='Lotame';const DISPLAY_NAME$K='Lotame';
|
924
936
|
|
925
|
-
const DIR_NAME$
|
937
|
+
const DIR_NAME$J='Lytics';const DISPLAY_NAME$J='Lytics';
|
926
938
|
|
927
|
-
const DIR_NAME$
|
939
|
+
const DIR_NAME$I='Mixpanel';const DISPLAY_NAME$I='Mixpanel';
|
928
940
|
|
929
|
-
const DIR_NAME$
|
941
|
+
const DIR_NAME$H='MoEngage';const DISPLAY_NAME$H='MoEngage';
|
930
942
|
|
931
|
-
const DIR_NAME$
|
943
|
+
const DIR_NAME$G='Optimizely';const DISPLAY_NAME$G='Optimizely Web';
|
932
944
|
|
933
|
-
const DIR_NAME$
|
945
|
+
const DIR_NAME$F='Pendo';const DISPLAY_NAME$F='Pendo';
|
934
946
|
|
935
|
-
const DIR_NAME$
|
947
|
+
const DIR_NAME$E='PinterestTag';const DISPLAY_NAME$E='Pinterest Tag';
|
936
948
|
|
937
|
-
const DIR_NAME$
|
949
|
+
const DIR_NAME$D='PostAffiliatePro';const DISPLAY_NAME$D='Post Affiliate Pro';
|
938
950
|
|
939
|
-
const DIR_NAME$
|
951
|
+
const DIR_NAME$C='Posthog';const DISPLAY_NAME$C='PostHog';
|
940
952
|
|
941
|
-
const DIR_NAME$
|
953
|
+
const DIR_NAME$B='ProfitWell';const DISPLAY_NAME$B='ProfitWell';
|
942
954
|
|
943
|
-
const DIR_NAME$
|
955
|
+
const DIR_NAME$A='Qualtrics';const DISPLAY_NAME$A='Qualtrics';
|
944
956
|
|
945
|
-
const DIR_NAME$
|
957
|
+
const DIR_NAME$z='QuantumMetric';const DISPLAY_NAME$z='Quantum Metric';
|
946
958
|
|
947
|
-
const DIR_NAME$
|
959
|
+
const DIR_NAME$y='RedditPixel';const DISPLAY_NAME$y='Reddit Pixel';
|
948
960
|
|
949
|
-
const DIR_NAME$
|
961
|
+
const DIR_NAME$x='Sentry';const DISPLAY_NAME$x='Sentry';
|
950
962
|
|
951
|
-
const DIR_NAME$
|
963
|
+
const DIR_NAME$w='SnapPixel';const DISPLAY_NAME$w='Snap Pixel';
|
952
964
|
|
953
|
-
const DIR_NAME$
|
965
|
+
const DIR_NAME$v='TVSquared';const DISPLAY_NAME$v='TVSquared';
|
954
966
|
|
955
|
-
const DIR_NAME$
|
967
|
+
const DIR_NAME$u='VWO';const DISPLAY_NAME$u='VWO';
|
956
968
|
|
957
|
-
const DIR_NAME$
|
969
|
+
const DIR_NAME$t='GA360';const DISPLAY_NAME$t='Google Analytics 360';
|
958
970
|
|
959
|
-
const DIR_NAME$
|
971
|
+
const DIR_NAME$s='Adroll';const DISPLAY_NAME$s='Adroll';
|
960
972
|
|
961
|
-
const DIR_NAME$
|
973
|
+
const DIR_NAME$r='DCMFloodlight';const DISPLAY_NAME$r='DCM Floodlight';
|
962
974
|
|
963
|
-
const DIR_NAME$
|
975
|
+
const DIR_NAME$q='Matomo';const DISPLAY_NAME$q='Matomo';
|
964
976
|
|
965
|
-
const DIR_NAME$
|
977
|
+
const DIR_NAME$p='Vero';const DISPLAY_NAME$p='Vero';
|
966
978
|
|
967
|
-
const DIR_NAME$
|
979
|
+
const DIR_NAME$o='Mouseflow';const DISPLAY_NAME$o='Mouseflow';
|
968
980
|
|
969
|
-
const DIR_NAME$
|
981
|
+
const DIR_NAME$n='Rockerbox';const DISPLAY_NAME$n='Rockerbox';
|
970
982
|
|
971
|
-
const DIR_NAME$
|
983
|
+
const DIR_NAME$m='ConvertFlow';const DISPLAY_NAME$m='ConvertFlow';
|
972
984
|
|
973
|
-
const DIR_NAME$
|
985
|
+
const DIR_NAME$l='SnapEngage';const DISPLAY_NAME$l='SnapEngage';
|
974
986
|
|
975
|
-
const DIR_NAME$
|
987
|
+
const DIR_NAME$k='LiveChat';const DISPLAY_NAME$k='LiveChat';
|
976
988
|
|
977
|
-
const DIR_NAME$
|
989
|
+
const DIR_NAME$j='Shynet';const DISPLAY_NAME$j='Shynet';
|
978
990
|
|
979
|
-
const DIR_NAME$
|
991
|
+
const DIR_NAME$i='Woopra';const DISPLAY_NAME$i='Woopra';
|
980
992
|
|
981
|
-
const DIR_NAME$
|
993
|
+
const DIR_NAME$h='RollBar';const DISPLAY_NAME$h='RollBar';
|
982
994
|
|
983
|
-
const DIR_NAME$
|
995
|
+
const DIR_NAME$g='QuoraPixel';const DISPLAY_NAME$g='Quora Pixel';
|
984
996
|
|
985
|
-
const DIR_NAME$
|
997
|
+
const DIR_NAME$f='June';const DISPLAY_NAME$f='June';
|
986
998
|
|
987
|
-
const DIR_NAME$
|
999
|
+
const DIR_NAME$e='Engage';const DISPLAY_NAME$e='Engage';
|
988
1000
|
|
989
|
-
const DIR_NAME$
|
1001
|
+
const DIR_NAME$d='Iterable';const DISPLAY_NAME$d='Iterable';
|
990
1002
|
|
991
|
-
const DIR_NAME$
|
1003
|
+
const DIR_NAME$c='YandexMetrica';const DISPLAY_NAME$c='Yandex.Metrica';
|
992
1004
|
|
993
|
-
const DIR_NAME$
|
1005
|
+
const DIR_NAME$b='Refiner';const DISPLAY_NAME$b='Refiner';
|
994
1006
|
|
995
|
-
const DIR_NAME$
|
1007
|
+
const DIR_NAME$a='Qualaroo';const DISPLAY_NAME$a='Qualaroo';
|
996
1008
|
|
997
|
-
const DIR_NAME$
|
1009
|
+
const DIR_NAME$9='Podsights';const DISPLAY_NAME$9='Podsights';
|
998
1010
|
|
999
|
-
const DIR_NAME$
|
1011
|
+
const DIR_NAME$8='Axeptio';const DISPLAY_NAME$8='Axeptio';
|
1000
1012
|
|
1001
|
-
const DIR_NAME$
|
1013
|
+
const DIR_NAME$7='Satismeter';const DISPLAY_NAME$7='Satismeter';
|
1002
1014
|
|
1003
|
-
const DIR_NAME$
|
1015
|
+
const DIR_NAME$6='MicrosoftClarity';const DISPLAY_NAME$6='Microsoft Clarity';
|
1004
1016
|
|
1005
|
-
const DIR_NAME$
|
1017
|
+
const DIR_NAME$5='Sendinblue';const DISPLAY_NAME$5='Sendinblue';
|
1006
1018
|
|
1007
|
-
const DIR_NAME$
|
1019
|
+
const DIR_NAME$4='Olark';const DISPLAY_NAME$4='Olark';
|
1008
1020
|
|
1009
|
-
const DIR_NAME$
|
1021
|
+
const DIR_NAME$3='Lemnisk';const DISPLAY_NAME$3='Lemnisk';
|
1010
1022
|
|
1011
|
-
const DIR_NAME$
|
1023
|
+
const DIR_NAME$2='TiktokAds';const DISPLAY_NAME$2='TikTok Ads';
|
1012
1024
|
|
1013
|
-
const DIR_NAME='ActiveCampaign';const DISPLAY_NAME='Active Campaign';
|
1025
|
+
const DIR_NAME$1='ActiveCampaign';const DISPLAY_NAME$1='Active Campaign';
|
1026
|
+
|
1027
|
+
const DIR_NAME='Sprig';const DISPLAY_NAME='Sprig';
|
1014
1028
|
|
1015
1029
|
// map of the destination display names to the destination directory names
|
1016
|
-
const destDisplayNamesToFileNamesMap={[DISPLAY_NAME$
|
1030
|
+
const destDisplayNamesToFileNamesMap={[DISPLAY_NAME$R]:DIR_NAME$R,[DISPLAY_NAME$Y]:DIR_NAME$Y,[DISPLAY_NAME$S]:DIR_NAME$S,[DISPLAY_NAME$W]:DIR_NAME$W,[DISPLAY_NAME$u]:DIR_NAME$u,[DISPLAY_NAME$U]:DIR_NAME$U,[DISPLAY_NAME$16]:DIR_NAME$16,[DISPLAY_NAME$Q]:DIR_NAME$Q,[DISPLAY_NAME$P]:DIR_NAME$P,[DISPLAY_NAME$O]:DIR_NAME$O,[DISPLAY_NAME$10]:DIR_NAME$10,[DISPLAY_NAME$14]:DIR_NAME$14,[DISPLAY_NAME$12]:DIR_NAME$12,[DISPLAY_NAME$_]:DIR_NAME$_,[DISPLAY_NAME$K]:DIR_NAME$K,[DISPLAY_NAME$G]:DIR_NAME$G,[DISPLAY_NAME$15]:DIR_NAME$15,[DISPLAY_NAME$Z]:DIR_NAME$Z,[DISPLAY_NAME$v]:DIR_NAME$v,[DISPLAY_NAME$X]:DIR_NAME$X,[DISPLAY_NAME$H]:DIR_NAME$H,[DISPLAY_NAME$19]:DIR_NAME$19,[DISPLAY_NAME$F]:DIR_NAME$F,[DISPLAY_NAME$J]:DIR_NAME$J,[DISPLAY_NAME$18]:DIR_NAME$18,[DISPLAY_NAME$C]:DIR_NAME$C,[DISPLAY_NAME$N]:DIR_NAME$N,[DISPLAY_NAME$13]:DIR_NAME$13,[DISPLAY_NAME$17]:DIR_NAME$17,[DISPLAY_NAME$E]:DIR_NAME$E,[DISPLAY_NAME$1a]:DIR_NAME$1a,[DISPLAY_NAME$L]:DIR_NAME$L,[DISPLAY_NAME$y]:DIR_NAME$y,[DISPLAY_NAME$$]:DIR_NAME$$,[DISPLAY_NAME$T]:DIR_NAME$T,[DISPLAY_NAME$11]:DIR_NAME$11,[DISPLAY_NAME$I]:DIR_NAME$I,[DISPLAY_NAME$A]:DIR_NAME$A,[DISPLAY_NAME$B]:DIR_NAME$B,[DISPLAY_NAME$x]:DIR_NAME$x,[DISPLAY_NAME$z]:DIR_NAME$z,[DISPLAY_NAME$w]:DIR_NAME$w,[DISPLAY_NAME$D]:DIR_NAME$D,[DISPLAY_NAME$V]:DIR_NAME$V,[DISPLAY_NAME$M]:DIR_NAME$M,[DISPLAY_NAME$t]:DIR_NAME$t,[DISPLAY_NAME$s]:DIR_NAME$s,[DISPLAY_NAME$r]:DIR_NAME$r,[DISPLAY_NAME$q]:DIR_NAME$q,[DISPLAY_NAME$p]:DIR_NAME$p,[DISPLAY_NAME$o]:DIR_NAME$o,[DISPLAY_NAME$n]:DIR_NAME$n,[DISPLAY_NAME$m]:DIR_NAME$m,[DISPLAY_NAME$l]:DIR_NAME$l,[DISPLAY_NAME$k]:DIR_NAME$k,[DISPLAY_NAME$j]:DIR_NAME$j,[DISPLAY_NAME$i]:DIR_NAME$i,[DISPLAY_NAME$h]:DIR_NAME$h,[DISPLAY_NAME$g]:DIR_NAME$g,[DISPLAY_NAME$f]:DIR_NAME$f,[DISPLAY_NAME$e]:DIR_NAME$e,[DISPLAY_NAME$d]:DIR_NAME$d,[DISPLAY_NAME$c]:DIR_NAME$c,[DISPLAY_NAME$b]:DIR_NAME$b,[DISPLAY_NAME$a]:DIR_NAME$a,[DISPLAY_NAME$9]:DIR_NAME$9,[DISPLAY_NAME$8]:DIR_NAME$8,[DISPLAY_NAME$7]:DIR_NAME$7,[DISPLAY_NAME$6]:DIR_NAME$6,[DISPLAY_NAME$5]:DIR_NAME$5,[DISPLAY_NAME$4]:DIR_NAME$4,[DISPLAY_NAME$3]:DIR_NAME$3,[DISPLAY_NAME$2]:DIR_NAME$2,[DISPLAY_NAME$1]:DIR_NAME$1,[DISPLAY_NAME]:DIR_NAME};
|
1017
1031
|
|
1018
1032
|
const DEFAULT_INTEGRATIONS_CONFIG={All:true};
|
1019
1033
|
|
@@ -1022,7 +1036,7 @@ const isDestIntgConfigTruthy=destIntgConfig=>!isUndefined(destIntgConfig)&&Boole
|
|
1022
1036
|
* @param intgOpts Integration options object
|
1023
1037
|
* @param destinations Destinations array
|
1024
1038
|
* @returns Destinations array filtered based on the integration options
|
1025
|
-
*/const filterDestinations=(intgOpts,destinations)=>{const allOptVal=intgOpts.All;return destinations.filter(dest=>{const destDisplayName=dest.displayName;let isDestEnabled;if(allOptVal){isDestEnabled=true;if(isDestIntgConfigFalsy(intgOpts[destDisplayName])){isDestEnabled=false;}}else {isDestEnabled=false;if(isDestIntgConfigTruthy(intgOpts[destDisplayName])){isDestEnabled=true;}}return isDestEnabled;});};
|
1039
|
+
*/const filterDestinations=(intgOpts,destinations)=>{const allOptVal=intgOpts.All??true;return destinations.filter(dest=>{const destDisplayName=dest.displayName;let isDestEnabled;if(allOptVal){isDestEnabled=true;if(isDestIntgConfigFalsy(intgOpts[destDisplayName])){isDestEnabled=false;}}else {isDestEnabled=false;if(isDestIntgConfigTruthy(intgOpts[destDisplayName])){isDestEnabled=true;}}return isDestEnabled;});};
|
1026
1040
|
|
1027
1041
|
const READY_CHECK_TIMEOUT_MS=11*1000;// 11 seconds
|
1028
1042
|
const SCRIPT_LOAD_TIMEOUT_MS=10*1000;// 10 seconds
|
@@ -1036,7 +1050,7 @@ const DESTINATION_NOT_SUPPORTED_ERROR=destUserFriendlyId=>`Destination ${destUse
|
|
1036
1050
|
* @param sdkTypeName The name of the destination SDK type
|
1037
1051
|
* @param logger Logger instance
|
1038
1052
|
* @returns true if the destination SDK code is evaluated, false otherwise
|
1039
|
-
*/const isDestinationSDKMounted=(destSDKIdentifier,sdkTypeName,logger)=>Boolean(globalThis[destSDKIdentifier]&&globalThis[destSDKIdentifier][sdkTypeName]&&globalThis[destSDKIdentifier][sdkTypeName].prototype&&typeof globalThis[destSDKIdentifier][sdkTypeName].prototype.constructor!=='undefined');const createDestinationInstance=(destSDKIdentifier,sdkTypeName,dest,state)=>{const rAnalytics=globalThis.rudderanalytics;const analytics=rAnalytics.getAnalyticsInstance(state.lifecycle.writeKey.value);return new globalThis[destSDKIdentifier][sdkTypeName](clone$1(dest.config),{loadIntegration:state.nativeDestinations.loadIntegration.value,logLevel:state.lifecycle.logLevel.value,loadOnlyIntegrations:state.nativeDestinations.loadOnlyIntegrations.value,page:(category,name,properties,options,callback)=>analytics.page(pageArgumentsToCallOptions(category,name,properties,options,callback)),track:(event,properties,options,callback)=>analytics.track(trackArgumentsToCallOptions(event,properties,options,callback)),identify:(userId,traits,options,callback)=>analytics.identify(identifyArgumentsToCallOptions(userId,traits,options,callback)),alias:(to,from,options,callback)=>analytics.alias(aliasArgumentsToCallOptions(to,from,options,callback)),group:(groupId,traits,options,callback)=>analytics.group(groupArgumentsToCallOptions(groupId,traits,options,callback)),getAnonymousId:()=>analytics.getAnonymousId(),getUserId:()=>analytics.getUserId(),getUserTraits:()=>analytics.getUserTraits(),getGroupId:()=>analytics.getGroupId(),getGroupTraits:()=>analytics.getGroupTraits(),getSessionId:()=>analytics.getSessionId()},{shouldApplyDeviceModeTransformation:dest.shouldApplyDeviceModeTransformation,propagateEventsUntransformedOnError:dest.propagateEventsUntransformedOnError,destinationId:dest.id});};const isDestinationReady=dest=>new Promise((resolve,reject)=>{const instance=dest.instance;let handleNumber;const checkReady=()=>{if(instance.isLoaded()&&(!instance.isReady||instance.isReady())){resolve(true);}else {handleNumber=globalThis.requestAnimationFrame(checkReady);}};checkReady();setTimeout(()=>{globalThis.cancelAnimationFrame(handleNumber);reject(new Error(DESTINATION_READY_TIMEOUT_ERROR(READY_CHECK_TIMEOUT_MS,dest.userFriendlyId)));},READY_CHECK_TIMEOUT_MS);});/**
|
1053
|
+
*/const isDestinationSDKMounted=(destSDKIdentifier,sdkTypeName,logger)=>Boolean(globalThis[destSDKIdentifier]&&globalThis[destSDKIdentifier][sdkTypeName]&&globalThis[destSDKIdentifier][sdkTypeName].prototype&&typeof globalThis[destSDKIdentifier][sdkTypeName].prototype.constructor!=='undefined');const createDestinationInstance=(destSDKIdentifier,sdkTypeName,dest,state)=>{const rAnalytics=globalThis.rudderanalytics;const analytics=rAnalytics.getAnalyticsInstance(state.lifecycle.writeKey.value);return new globalThis[destSDKIdentifier][sdkTypeName](clone$1(dest.config),{loadIntegration:state.nativeDestinations.loadIntegration.value,logLevel:state.lifecycle.logLevel.value,loadOnlyIntegrations:state.consents.postConsent.value?.integrations??state.nativeDestinations.loadOnlyIntegrations.value,page:(category,name,properties,options,callback)=>analytics.page(pageArgumentsToCallOptions(category,name,properties,options,callback)),track:(event,properties,options,callback)=>analytics.track(trackArgumentsToCallOptions(event,properties,options,callback)),identify:(userId,traits,options,callback)=>analytics.identify(identifyArgumentsToCallOptions(userId,traits,options,callback)),alias:(to,from,options,callback)=>analytics.alias(aliasArgumentsToCallOptions(to,from,options,callback)),group:(groupId,traits,options,callback)=>analytics.group(groupArgumentsToCallOptions(groupId,traits,options,callback)),getAnonymousId:()=>analytics.getAnonymousId(),getUserId:()=>analytics.getUserId(),getUserTraits:()=>analytics.getUserTraits(),getGroupId:()=>analytics.getGroupId(),getGroupTraits:()=>analytics.getGroupTraits(),getSessionId:()=>analytics.getSessionId()},{shouldApplyDeviceModeTransformation:dest.shouldApplyDeviceModeTransformation,propagateEventsUntransformedOnError:dest.propagateEventsUntransformedOnError,destinationId:dest.id});};const isDestinationReady=dest=>new Promise((resolve,reject)=>{const instance=dest.instance;let handleNumber;const checkReady=()=>{if(instance.isLoaded()&&(!instance.isReady||instance.isReady())){resolve(true);}else {handleNumber=globalThis.requestAnimationFrame(checkReady);}};checkReady();setTimeout(()=>{globalThis.cancelAnimationFrame(handleNumber);reject(new Error(DESTINATION_READY_TIMEOUT_ERROR(READY_CHECK_TIMEOUT_MS,dest.userFriendlyId)));},READY_CHECK_TIMEOUT_MS);});/**
|
1040
1054
|
* Extracts the integration config, if any, from the given destination
|
1041
1055
|
* and merges it with the current integrations config
|
1042
1056
|
* @param dest Destination object
|
@@ -1049,8 +1063,8 @@ logger?.error(err);});}catch(err){state.nativeDestinations.failedDestinations.va
|
|
1049
1063
|
|
1050
1064
|
const pluginName$b='DeviceModeDestinations';const DeviceModeDestinations=()=>({name:pluginName$b,initialize:state=>{state.plugins.loadedPlugins.value=[...state.plugins.loadedPlugins.value,pluginName$b];},nativeDestinations:{setActiveDestinations(state,pluginsManager,errorHandler,logger){// Normalize the integration options from the load API call
|
1051
1065
|
state.nativeDestinations.loadOnlyIntegrations.value=clone$1(state.loadOptions.value.integrations)??DEFAULT_INTEGRATIONS_CONFIG;state.nativeDestinations.loadIntegration.value=state.loadOptions.value.loadIntegration;// Filter destination that doesn't have mapping config-->Integration names
|
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
|
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
|
1066
|
+
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 or consent API options
|
1067
|
+
const destinationsToLoad=filterDestinations(state.consents.postConsent.value?.integrations??state.nativeDestinations.loadOnlyIntegrations.value,configSupportedDestinations);const consentedDestinations=destinationsToLoad.filter(dest=>// if consent manager is not configured, then default to load the destination
|
1054
1068
|
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
|
1055
1069
|
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));}});}}});
|
1056
1070
|
|
@@ -1200,9 +1214,16 @@ globalThis.getKetchUserConsentedPurposes=()=>state.consents.data.value.allowedCo
|
|
1200
1214
|
globalThis.getKetchUserDeniedPurposes=()=>state.consents.data.value.deniedConsentIds?.slice();// updateKetchConsent callback function to update current consent purpose state
|
1201
1215
|
// this will be called from ketch rudderstack plugin
|
1202
1216
|
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;//
|
1204
|
-
if(
|
1205
|
-
const
|
1217
|
+
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,consentManagement}=destConfig;const matchPredicate=consent=>allowedConsentIds.includes(consent);// Generic consent management
|
1218
|
+
if(consentManagement){// Get the corresponding consents for the destination
|
1219
|
+
const cmpConsents=consentManagement.find(c=>c.provider===state.consents.provider.value)?.consents;// If there are no consents configured for the destination for the current provider, events should be sent.
|
1220
|
+
if(!cmpConsents){return true;}const configuredConsents=cmpConsents.map(c=>c.consent.trim()).filter(n=>n);// match the configured consents with user provided consents as per
|
1221
|
+
// the configured resolution strategy
|
1222
|
+
switch(state.consents.resolutionStrategy.value){case'or':return configuredConsents.some(matchPredicate)||configuredConsents.length===0;case'and':default:return configuredConsents.every(matchPredicate);}// Legacy cookie consent management
|
1223
|
+
// TODO: To be removed once the source config API is updated to support generic consent management
|
1224
|
+
}else if(ketchConsentPurposes){const configuredConsents=ketchConsentPurposes.map(p=>p.purpose.trim()).filter(n=>n);// Check if any of the destination's mapped ketch purposes are consented by the user in the browser.
|
1225
|
+
return configuredConsents.some(matchPredicate)||configuredConsents.length===0;}// If there are no consents configured for the destination for the current provider, events should be sent.
|
1226
|
+
return true;}catch(err){errorHandler?.onError(err,KETCH_CONSENT_MANAGER_PLUGIN,DESTINATION_CONSENT_STATUS_ERROR$1);return true;}}}});
|
1206
1227
|
|
1207
1228
|
const DEFAULT_QUEUE_OPTIONS={maxItems:100};const QUEUE_NAME$1='rudder_destinations_events';const NATIVE_DESTINATION_QUEUE_PLUGIN='NativeDestinationQueuePlugin';
|
1208
1229
|
|
@@ -1257,14 +1278,24 @@ const pluginName$4='OneTrustConsentManager';const OneTrustConsentManager=()=>({n
|
|
1257
1278
|
// the cookie categories Ids that the user has consented to.
|
1258
1279
|
// Eg: ',C0001,C0003,'
|
1259
1280
|
// We split it and save it as an array.
|
1260
|
-
const allowedConsentIds=globalThis.OnetrustActiveGroups.split(',').filter(n=>n);const allowedConsents={};const deniedConsentIds=[];// Get the groups(cookie categorization), user has created in
|
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
|
1262
|
-
|
1263
|
-
if(!
|
1281
|
+
const allowedConsentIds=globalThis.OnetrustActiveGroups.split(',').filter(n=>n);const allowedConsents={};const deniedConsentIds=[];// Get the groups (cookie categorization), user has created in OneTrust account.
|
1282
|
+
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;// In case of OneTrust, as we still support both category names and IDs, the allowed consents
|
1283
|
+
// are stored as an object with key as the category ID and value as the category name.
|
1284
|
+
state.consents.data.value={allowedConsentIds:allowedConsents,deniedConsentIds};},isDestinationConsented(state,destConfig,errorHandler,logger){if(!state.consents.initialized.value){return true;}const allowedConsents=state.consents.data.value.allowedConsentIds;try{// mapping of the destination with the consent group name
|
1285
|
+
const{oneTrustCookieCategories,consentManagement}=destConfig;const allowedConsentIds=Object.keys(allowedConsents);const allowedConsentNames=Object.values(allowedConsents);// Match the consent in both IDs and names
|
1286
|
+
const matchPredicate=consent=>allowedConsentIds.includes(consent)||allowedConsentNames.includes(consent);// Generic consent management
|
1287
|
+
if(consentManagement){// Get the corresponding consents for the destination
|
1288
|
+
const cmpConsents=consentManagement.find(c=>c.provider===state.consents.provider.value)?.consents;// If there are no consents configured for the destination for the current provider, events should be sent.
|
1289
|
+
if(!cmpConsents){return true;}const configuredConsents=cmpConsents.map(c=>c.consent.trim()).filter(n=>n);// match the configured consents with user provided consents as per
|
1290
|
+
// the configured resolution strategy
|
1291
|
+
switch(state.consents.resolutionStrategy.value){case'or':return configuredConsents.some(matchPredicate)||configuredConsents.length===0;case'and':default:return configuredConsents.every(matchPredicate);}// Legacy cookie consent management
|
1292
|
+
// TODO: To be removed once the source config API is updated to support generic consent management
|
1293
|
+
}else if(oneTrustCookieCategories){// Change the structure of oneTrustConsentGroup as an array and filter values if empty string
|
1264
1294
|
// Eg:
|
1265
1295
|
// ["Performance Cookies", "Functional Cookies"]
|
1266
|
-
const
|
1267
|
-
|
1296
|
+
const configuredConsents=oneTrustCookieCategories.map(c=>c.oneTrustCookieCategory.trim()).filter(n=>n);// Check if all the destination's mapped cookie categories are consented by the user in the browser.
|
1297
|
+
return configuredConsents.every(matchPredicate);}// If there are no consents configured for the destination for the current provider, events should be sent.
|
1298
|
+
return true;}catch(err){errorHandler?.onError(err,ONETRUST_CONSENT_MANAGER_PLUGIN,DESTINATION_CONSENT_STATUS_ERROR);return true;}}}});
|
1268
1299
|
|
1269
1300
|
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);}}});
|
1270
1301
|
|
@@ -2364,7 +2395,7 @@ xhr.timeout=timeout;Object.keys(options.headers).forEach(headerName=>{if(options
|
|
2364
2395
|
* Clear basic authentication header
|
2365
2396
|
*/resetAuthHeader(){this.basicAuthHeader=undefined;}}const defaultHttpClient=new HttpClient(defaultErrorHandler,defaultLogger);
|
2366
2397
|
|
2367
|
-
const STORAGE_TEST_COOKIE='test_rudder_cookie';const STORAGE_TEST_LOCAL_STORAGE='test_rudder_ls';const STORAGE_TEST_SESSION_STORAGE='test_rudder_ss';const STORAGE_TEST_TOP_LEVEL_DOMAIN='__tld__';const CLIENT_DATA_STORE_COOKIE='clientDataInCookie';const CLIENT_DATA_STORE_LS='clientDataInLocalStorage';const CLIENT_DATA_STORE_MEMORY='clientDataInMemory';const CLIENT_DATA_STORE_SESSION='clientDataInSessionStorage';
|
2398
|
+
const STORAGE_TEST_COOKIE='test_rudder_cookie';const STORAGE_TEST_LOCAL_STORAGE='test_rudder_ls';const STORAGE_TEST_SESSION_STORAGE='test_rudder_ss';const STORAGE_TEST_TOP_LEVEL_DOMAIN='__tld__';const CLIENT_DATA_STORE_COOKIE='clientDataInCookie';const CLIENT_DATA_STORE_LS='clientDataInLocalStorage';const CLIENT_DATA_STORE_MEMORY='clientDataInMemory';const CLIENT_DATA_STORE_SESSION='clientDataInSessionStorage';const USER_SESSION_KEYS=['userId','userTraits','anonymousId','groupId','groupTraits','initialReferrer','initialReferringDomain','sessionInfo','authToken'];
|
2368
2399
|
|
2369
2400
|
const storageClientDataStoreNameMap={[COOKIE_STORAGE]:CLIENT_DATA_STORE_COOKIE,[LOCAL_STORAGE]:CLIENT_DATA_STORE_LS,[MEMORY_STORAGE]:CLIENT_DATA_STORE_MEMORY,[SESSION_STORAGE]:CLIENT_DATA_STORE_SESSION};
|
2370
2401
|
|
@@ -2382,7 +2413,7 @@ const hasCrypto=()=>!isNullOrUndefined(globalThis.crypto)&&isFunction(globalThis
|
|
2382
2413
|
|
2383
2414
|
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();});}};
|
2384
2415
|
|
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;};
|
2416
|
+
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),/* eslint-disable-next-line */'navigator.sendBeacon':()=>!isFunction(navigator.sendBeacon)};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;};
|
2386
2417
|
|
2387
2418
|
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;};
|
2388
2419
|
|
@@ -2530,21 +2561,22 @@ return JSON.parse(str);}catch(err){this.onError(new Error(`${STORE_DATA_FETCH_ER
|
|
2530
2561
|
* Handle errors
|
2531
2562
|
*/onError(error){if(this.hasErrorHandler){this.errorHandler?.onError(error,`Store ${this.id}`);}else {throw error;}}}
|
2532
2563
|
|
2533
|
-
const
|
2564
|
+
const getStorageTypeFromPreConsentIfApplicable=(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;}break;case'anonymousId':if(sessionKey!=='anonymousId'){overriddenStorageType=NO_STORAGE;}break;}}return overriddenStorageType;};
|
2534
2565
|
|
2535
2566
|
/**
|
2536
2567
|
* A service to manage stores & available storage client configurations
|
2537
2568
|
*/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);}/**
|
2538
2569
|
* Configure available storage client instances
|
2539
|
-
*/init(){if(this.isInitialized){return;}const config={cookieStorageOptions:{samesite:
|
2570
|
+
*/init(){if(this.isInitialized){return;}const loadOptions=state.loadOptions.value;const config={cookieStorageOptions:{samesite:loadOptions.sameSiteCookie,secure:loadOptions.secureCookie,domain:loadOptions.setCookieDomain,sameDomainCookiesOnly:loadOptions.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;}/**
|
2540
2571
|
* Create store to persist data used by the SDK like session, used details etc
|
2541
2572
|
*/initClientDataStores(){this.initializeStorageState();// TODO: fill in extra config values and bring them in from StoreManagerOptions if needed
|
2542
2573
|
// TODO: should we pass the keys for all in order to validate or leave free as v1.1?
|
2543
2574
|
// Initializing all the enabled store because previous user data might be in different storage
|
2544
2575
|
// that needs auto migration
|
2545
|
-
const
|
2546
|
-
const
|
2547
|
-
|
2576
|
+
const storageTypes=[MEMORY_STORAGE,LOCAL_STORAGE,COOKIE_STORAGE,SESSION_STORAGE];storageTypes.forEach(storageType=>{if(getStorageEngine(storageType)?.isEnabled){this.setStore({id:storageClientDataStoreNameMap[storageType],name:storageClientDataStoreNameMap[storageType],isEncrypted:true,noCompoundKey:true,type:storageType});}});}initializeStorageState(){let globalStorageType=state.storage.type.value;let entriesOptions=state.loadOptions.value.storage?.entries;// Use the storage options from post consent if anything is defined
|
2577
|
+
const postConsentStorageOpts=state.consents.postConsent.value.storage;if(isDefined(postConsentStorageOpts?.type)||isDefined(postConsentStorageOpts?.entries)){globalStorageType=postConsentStorageOpts?.type;entriesOptions=postConsentStorageOpts?.entries;}let trulyAnonymousTracking=true;let storageEntries={};USER_SESSION_KEYS.forEach(sessionKey=>{const key=sessionKey;const storageKey=sessionKey;const configuredStorageType=entriesOptions?.[key]?.type;const preConsentStorageType=getStorageTypeFromPreConsentIfApplicable(state,sessionKey);// Storage type precedence order: pre-consent strategy > entry type > global type > default
|
2578
|
+
const storageType=preConsentStorageType??configuredStorageType??globalStorageType??DEFAULT_STORAGE_TYPE;const finalStorageType=this.getResolvedStorageTypeForEntry(storageType,sessionKey);if(finalStorageType!==NO_STORAGE){trulyAnonymousTracking=false;}storageEntries={...storageEntries,[sessionKey]:{type:finalStorageType,key:USER_SESSION_STORAGE_KEYS[storageKey]}};});n(()=>{state.storage.type.value=globalStorageType;state.storage.entries.value=storageEntries;state.storage.trulyAnonymousTracking.value=trulyAnonymousTracking;});}getResolvedStorageTypeForEntry(storageType,sessionKey){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
|
2579
|
+
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,sessionKey,storageType,finalStorageType));}return finalStorageType;}/**
|
2548
2580
|
* Create a new store
|
2549
2581
|
*/setStore(storeConfig){const storageEngine=getStorageEngine(storeConfig.type);this.stores[storeConfig.id]=new Store(storeConfig,storageEngine,this.pluginsManager);return this.stores[storeConfig.id];}/**
|
2550
2582
|
* Retrieve a store
|
@@ -2636,24 +2668,25 @@ const isErrorReportingEnabled=sourceConfig=>sourceConfig?.statsCollection?.error
|
|
2636
2668
|
* Validates and normalizes the consent options provided by the user
|
2637
2669
|
* @param options Consent options provided by the user
|
2638
2670
|
* @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
|
2671
|
+
*/const getValidPostConsentOptions=options=>{const validOptions={sendPageEvent:false,trackConsent:false,discardPreConsentEvents:false};if(isObjectLiteralAndNotNull(options)){const clonedOptions=clone$1(options);validOptions.storage=clonedOptions.storage;if(isDefined(clonedOptions.integrations)){validOptions.integrations=isObjectLiteralAndNotNull(clonedOptions.integrations)?clonedOptions.integrations:DEFAULT_INTEGRATIONS_CONFIG;}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
2672
|
validOptions.consentManagement=mergeDeepRight(clonedOptions.consentManagement,{enabled:state.consents.enabled.value});}}return validOptions;};/**
|
2641
2673
|
* Validates if the input is a valid consents data
|
2642
2674
|
* @param value Input consents data
|
2643
2675
|
* @returns true if the input is a valid consents data else false
|
2644
2676
|
*/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
|
2677
|
+
* Retrieves the corresponding provider and plugin name of the selected consent manager from the supported consent managers
|
2678
|
+
* @param consentManagementOpts consent management options
|
2647
2679
|
* @param logger logger instance
|
2648
|
-
* @returns Corresponding plugin name of the selected consent manager from the supported consent managers
|
2649
|
-
*/const
|
2680
|
+
* @returns Corresponding provider and plugin name of the selected consent manager from the supported consent managers
|
2681
|
+
*/const getConsentManagerInfo=(consentManagementOpts,logger)=>{let{provider}=consentManagementOpts;const consentManagerPluginName=ConsentManagersToPluginNameMap[provider];if(provider&&!consentManagerPluginName){logger?.error(UNSUPPORTED_CONSENT_MANAGER_ERROR(CONFIG_MANAGER,provider,ConsentManagersToPluginNameMap));// Reset the provider value
|
2682
|
+
provider=undefined;}return {provider,consentManagerPluginName};};/**
|
2650
2683
|
* Validates and converts the consent management options into a normalized format
|
2651
2684
|
* @param consentManagementOpts Consent management options provided by the user
|
2652
2685
|
* @param logger logger instance
|
2653
2686
|
* @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){
|
2655
|
-
consentManagerPluginName=
|
2656
|
-
enabled=enabled&&Boolean(consentManagerPluginName);return {consentManagerPluginName,initialized,enabled,consentsData};};
|
2687
|
+
*/const getConsentManagementData=(consentManagementOpts,logger)=>{let consentManagerPluginName;let allowedConsentIds=[];let deniedConsentIds=[];let initialized=false;let provider;let enabled=consentManagementOpts?.enabled===true;if(isNonEmptyObject(consentManagementOpts)&&enabled){// Get the corresponding plugin name of the selected consent manager from the supported consent managers
|
2688
|
+
({provider,consentManagerPluginName}=getConsentManagerInfo(consentManagementOpts,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
|
2689
|
+
enabled=enabled&&Boolean(consentManagerPluginName);return {provider,consentManagerPluginName,initialized,enabled,consentsData};};
|
2657
2690
|
|
2658
2691
|
/**
|
2659
2692
|
* Determines the SDK url
|
@@ -2664,13 +2697,18 @@ enabled=enabled&&Boolean(consentManagerPluginName);return {consentManagerPluginN
|
|
2664
2697
|
* @param logger Logger instance
|
2665
2698
|
*/const updateReportingState=(res,logger)=>{state.reporting.isErrorReportingEnabled.value=isErrorReportingEnabled(res.source.config);state.reporting.isMetricsReportingEnabled.value=isMetricsReportingEnabled(res.source.config);if(state.reporting.isErrorReportingEnabled.value){const errReportingProvider=getErrorReportingProviderNameFromConfig(res.source.config);// Get the corresponding plugin name of the selected error reporting provider from the supported error reporting providers
|
2666
2699
|
const errReportingProviderPlugin=errReportingProvider?ErrorReportingProvidersToPluginNameMap[errReportingProvider]:undefined;if(!isUndefined(errReportingProvider)&&!errReportingProviderPlugin){// set the default error reporting provider
|
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
|
2700
|
+
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 updateStorageStateFromLoadOptions=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
|
2668
2701
|
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
|
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
|
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
|
2702
|
+
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 updateConsentsStateFromLoadOptions=logger=>{const{provider,consentManagerPluginName,initialized,enabled,consentsData}=getConsentManagementData(state.loadOptions.value.consentManagement,logger);// Pre-consent
|
2703
|
+
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.provider.value=provider;state.consents.preConsent.value={// Only enable pre-consent if it is explicitly enabled and
|
2671
2704
|
// if it is not already initialized and
|
2672
2705
|
// if consent management is enabled
|
2673
|
-
enabled:state.loadOptions.value.preConsent?.enabled===true&&initialized===false&&enabled===true,storage:{strategy:storageStrategy},events:{delivery:eventsDeliveryType}};});}
|
2706
|
+
enabled:state.loadOptions.value.preConsent?.enabled===true&&initialized===false&&enabled===true,storage:{strategy:storageStrategy},events:{delivery:eventsDeliveryType}};});};/**
|
2707
|
+
* Determines the consent management state variables from the source config data
|
2708
|
+
* @param resp Source config response
|
2709
|
+
* @param logger Logger instance
|
2710
|
+
*/const updateConsentsState=resp=>{let resolutionStrategy=state.consents.resolutionStrategy.value;let cmpMetadata;if(isObjectLiteralAndNotNull(resp.consentManagementMetadata)){if(state.consents.provider.value){resolutionStrategy=resp.consentManagementMetadata.providers.find(p=>p.provider===state.consents.provider.value)?.resolutionStrategy??state.consents.resolutionStrategy.value;}cmpMetadata=resp.consentManagementMetadata;}// If the provider is custom, then the resolution strategy is not applicable
|
2711
|
+
if(state.consents.provider.value==='custom'){resolutionStrategy=undefined;}n(()=>{state.consents.metadata.value=clone$1(cmpMetadata);state.consents.resolutionStrategy.value=resolutionStrategy;});};
|
2674
2712
|
|
2675
2713
|
/**
|
2676
2714
|
* A function that determines integration SDK loading path
|
@@ -2694,7 +2732,7 @@ class ConfigManager{hasErrorHandler=false;constructor(httpClient,errorHandler,lo
|
|
2694
2732
|
* config related information in global state
|
2695
2733
|
*/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
|
2696
2734
|
const intgCdnUrl=getIntegrationsCDNPath(APP_VERSION,lockIntegrationsVersion,state.loadOptions.value.destSDKBaseURL);// determine the path to fetch remote plugins from
|
2697
|
-
const pluginsCDNPath=getPluginsCDNPath(state.loadOptions.value.pluginsSDKBaseURL);
|
2735
|
+
const pluginsCDNPath=getPluginsCDNPath(state.loadOptions.value.pluginsSDKBaseURL);updateStorageStateFromLoadOptions(this.logger);updateConsentsStateFromLoadOptions(this.logger);// set application lifecycle state in global state
|
2698
2736
|
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();}/**
|
2699
2737
|
* Handle errors
|
2700
2738
|
*/onError(error,customMessage,shouldAlwaysThrow){if(this.hasErrorHandler){this.errorHandler?.onError(error,CONFIG_MANAGER,customMessage,shouldAlwaysThrow);}else {throw error;}}/**
|
@@ -2702,13 +2740,13 @@ n(()=>{state.lifecycle.integrationsCDNPath.value=intgCdnUrl;state.lifecycle.plug
|
|
2702
2740
|
* Use to construct and store information that are dependent on the sourceConfig.
|
2703
2741
|
*/processConfig(response,details){// TODO: add retry logic with backoff based on rejectionDetails.xhr.status
|
2704
2742
|
// We can use isErrRetryable utility method
|
2705
|
-
if(!response){this.onError(SOURCE_CONFIG_FETCH_ERROR(details?.error));return;}let res;
|
2743
|
+
if(!response){this.onError(SOURCE_CONFIG_FETCH_ERROR(details?.error));return;}let res;try{if(isString(response)){res=JSON.parse(response);}else {res=response;}}catch(err){this.onError(err,SOURCE_CONFIG_RESOLUTION_ERROR,true);return;}if(!isValidSourceConfig(res)){this.onError(new Error(SOURCE_CONFIG_RESOLUTION_ERROR),undefined,true);return;}// set the values in state for reporting slice
|
2706
2744
|
updateReportingState(res,this.logger);// determine the dataPlane url
|
2707
2745
|
const dataPlaneUrl=resolveDataPlaneUrl(res.source.dataplanes,state.lifecycle.dataPlaneUrl.value,state.loadOptions.value.residencyServer,this.logger);if(!dataPlaneUrl){this.onError(new Error(DATA_PLANE_URL_ERROR),undefined,true);return;}const nativeDestinations=res.source.destinations.length>0?filterEnabledDestination(res.source.destinations):[];// set in the state --> source, destination, lifecycle, reporting
|
2708
2746
|
n(()=>{// set source related information in state
|
2709
2747
|
state.source.value={config:res.source.config,id:res.source.id};// set device mode destination related information in state
|
2710
2748
|
state.nativeDestinations.configuredDestinations.value=nativeDestinations;// set the desired optional plugins
|
2711
|
-
state.plugins.pluginsToLoadFromConfig.value=state.loadOptions.value.plugins??[];// set application lifecycle state
|
2749
|
+
state.plugins.pluginsToLoadFromConfig.value=state.loadOptions.value.plugins??[];updateConsentsState(res);// set application lifecycle state
|
2712
2750
|
// Cast to string as we are sure that the value is not undefined
|
2713
2751
|
state.lifecycle.activeDataplaneUrl.value=removeTrailingSlashes(dataPlaneUrl);state.lifecycle.status.value='configured';});}/**
|
2714
2752
|
* A function to fetch source config either from /sourceConfig endpoint
|
@@ -2773,6 +2811,33 @@ const TOP_LEVEL_ELEMENTS=['integrations','anonymousId','originalTimestamp'];// R
|
|
2773
2811
|
const CONTEXT_RESERVED_ELEMENTS=['library','consentManagement','userAgent','ua-ch','screen'];// Reserved elements in the standard RudderStack event spec
|
2774
2812
|
const RESERVED_ELEMENTS=['anonymousId','sentAt','receivedAt','timestamp','originalTimestamp','event','messageId','channel'];
|
2775
2813
|
|
2814
|
+
const MIN_SESSION_ID_LENGTH=10;/**
|
2815
|
+
* A function to validate current session and return true/false depending on that
|
2816
|
+
* @returns boolean
|
2817
|
+
*/const hasSessionExpired=expiresAt=>{const timestamp=Date.now();return Boolean(!expiresAt||timestamp>expiresAt);};/**
|
2818
|
+
* A function to generate session id
|
2819
|
+
* @returns number
|
2820
|
+
*/const generateSessionId=()=>Date.now();/**
|
2821
|
+
* Function to validate user provided sessionId
|
2822
|
+
* @param {number} sessionId
|
2823
|
+
* @param logger logger
|
2824
|
+
* @returns
|
2825
|
+
*/const isManualSessionIdValid=(sessionId,logger)=>{if(!sessionId||!isPositiveInteger(sessionId)||!hasMinLength(MIN_SESSION_ID_LENGTH,sessionId)){logger?.warn(INVALID_SESSION_ID_WARNING(USER_SESSION_MANAGER,sessionId,MIN_SESSION_ID_LENGTH));return false;}return true;};/**
|
2826
|
+
* A function to generate new auto tracking session
|
2827
|
+
* @param sessionTimeout current timestamp
|
2828
|
+
* @returns SessionInfo
|
2829
|
+
*/const generateAutoTrackingSession=sessionTimeout=>{const timestamp=Date.now();const timeout=sessionTimeout||DEFAULT_SESSION_TIMEOUT_MS;return {id:timestamp,// set the current timestamp
|
2830
|
+
expiresAt:timestamp+timeout,// set the expiry time of the session
|
2831
|
+
timeout,sessionStart:undefined,autoTrack:true};};/**
|
2832
|
+
* A function to generate new manual tracking session
|
2833
|
+
* @param id Provided sessionId
|
2834
|
+
* @param logger Logger module
|
2835
|
+
* @returns SessionInfo
|
2836
|
+
*/const generateManualTrackingSession=(id,logger)=>{const sessionId=isManualSessionIdValid(id,logger)?id:generateSessionId();return {id:sessionId,sessionStart:undefined,manualTrack:true};};const isStorageTypeValidForStoringData=storageType=>Boolean(storageType===COOKIE_STORAGE||storageType===LOCAL_STORAGE||storageType===SESSION_STORAGE||storageType===MEMORY_STORAGE);/**
|
2837
|
+
* Generate a new anonymousId
|
2838
|
+
* @returns string anonymousID
|
2839
|
+
*/const generateAnonymousId=()=>generateUUID();
|
2840
|
+
|
2776
2841
|
/**
|
2777
2842
|
* To get the page properties for context object
|
2778
2843
|
* @param pageProps Page properties
|
@@ -2808,7 +2873,7 @@ rudderEvent.originalTimestamp=options.originalTimestamp;}};/**
|
|
2808
2873
|
*/const getMergedContext=(rudderContext,options,logger)=>{let context=rudderContext;Object.keys(options).forEach(key=>{if(!TOP_LEVEL_ELEMENTS.includes(key)&&!CONTEXT_RESERVED_ELEMENTS.includes(key)){if(key!=='context'){context=mergeDeepRight(context,{[key]:options[key]});}else if(!isUndefined(options[key])&&isObjectLiteralAndNotNull(options[key])){const tempContext={};Object.keys(options[key]).forEach(e=>{if(!CONTEXT_RESERVED_ELEMENTS.includes(e)){tempContext[e]=options[key][e];}});context=mergeDeepRight(context,{...tempContext});}else {logger?.warn(INVALID_CONTEXT_OBJECT_WARNING(EVENT_MANAGER));}}});return context;};/**
|
2809
2874
|
* A function to determine whether SDK should use the integration option provided in load call
|
2810
2875
|
* @returns boolean
|
2811
|
-
*/const shouldUseGlobalIntegrationsConfigInEvents=()=>state.loadOptions.value.useGlobalIntegrationsConfigInEvents&&isObjectLiteralAndNotNull(state.nativeDestinations.loadOnlyIntegrations.value);/**
|
2876
|
+
*/const shouldUseGlobalIntegrationsConfigInEvents=()=>state.loadOptions.value.useGlobalIntegrationsConfigInEvents&&(isObjectLiteralAndNotNull(state.consents.postConsent.value?.integrations)||isObjectLiteralAndNotNull(state.nativeDestinations.loadOnlyIntegrations.value));/**
|
2812
2877
|
* Updates rudder event object with data from the API options
|
2813
2878
|
* @param rudderEvent Generated rudder event
|
2814
2879
|
* @param options API options
|
@@ -2818,15 +2883,16 @@ rudderEvent.context=getMergedContext(rudderEvent.context,options);}};/**
|
|
2818
2883
|
* Returns the final integrations config for the event based on the global config and event's config
|
2819
2884
|
* @param integrationsConfig Event's integrations config
|
2820
2885
|
* @returns Final integrations config
|
2821
|
-
*/const getEventIntegrationsConfig=integrationsConfig=>{let finalIntgConfig;if(shouldUseGlobalIntegrationsConfigInEvents()){finalIntgConfig=state.nativeDestinations.loadOnlyIntegrations.value;}else if(isObjectLiteralAndNotNull(integrationsConfig)){finalIntgConfig=integrationsConfig;}else {finalIntgConfig=DEFAULT_INTEGRATIONS_CONFIG;}return finalIntgConfig;};/**
|
2886
|
+
*/const getEventIntegrationsConfig=integrationsConfig=>{let finalIntgConfig;if(shouldUseGlobalIntegrationsConfigInEvents()){finalIntgConfig=clone$1(state.consents.postConsent.value?.integrations??state.nativeDestinations.loadOnlyIntegrations.value);}else if(isObjectLiteralAndNotNull(integrationsConfig)){finalIntgConfig=integrationsConfig;}else {finalIntgConfig=DEFAULT_INTEGRATIONS_CONFIG;}return finalIntgConfig;};/**
|
2822
2887
|
* Enrich the base event object with data from state and the API options
|
2823
2888
|
* @param rudderEvent RudderEvent object
|
2824
2889
|
* @param options API options
|
2825
2890
|
* @param pageProps Page properties
|
2826
2891
|
* @param logger logger
|
2827
2892
|
* @returns Enriched RudderEvent object
|
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
|
2829
|
-
|
2893
|
+
*/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,// Add 'consentManagement' only if consent management is enabled
|
2894
|
+
...(state.consents.enabled.value&&{consentManagement:{deniedConsentIds:clone$1(state.consents.data.value.deniedConsentIds),allowedConsentIds:clone$1(state.consents.data.value.allowedConsentIds),provider:state.consents.provider.value,resolutionStrategy:state.consents.resolutionStrategy.value}}),'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(!isStorageTypeValidForStoringData(state.storage.entries.value.anonymousId?.type)){// Generate new anonymous id for each request
|
2895
|
+
commonEventData.anonymousId=generateAnonymousId();}else {// Type casting to string as the user session manager will take care of initializing the value
|
2830
2896
|
commonEventData.anonymousId=state.session.anonymousId.value;}// set truly anonymous tracking flag
|
2831
2897
|
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
|
2832
2898
|
// matching with v1.1 payload
|
@@ -2884,41 +2950,17 @@ enrichedEvent.userId=to??enrichedEvent.userId;return enrichedEvent;}/**
|
|
2884
2950
|
* @param error The error object
|
2885
2951
|
*/onError(error,customMessage,shouldAlwaysThrow){if(this.errorHandler){this.errorHandler.onError(error,EVENT_MANAGER,customMessage,shouldAlwaysThrow);}else {throw error;}}}
|
2886
2952
|
|
2887
|
-
const MIN_SESSION_ID_LENGTH=10;/**
|
2888
|
-
* A function to validate current session and return true/false depending on that
|
2889
|
-
* @returns boolean
|
2890
|
-
*/const hasSessionExpired=expiresAt=>{const timestamp=Date.now();return Boolean(!expiresAt||timestamp>expiresAt);};/**
|
2891
|
-
* A function to generate session id
|
2892
|
-
* @returns number
|
2893
|
-
*/const generateSessionId=()=>Date.now();/**
|
2894
|
-
* Function to validate user provided sessionId
|
2895
|
-
* @param {number} sessionId
|
2896
|
-
* @param logger logger
|
2897
|
-
* @returns
|
2898
|
-
*/const isManualSessionIdValid=(sessionId,logger)=>{if(!sessionId||!isPositiveInteger(sessionId)||!hasMinLength(MIN_SESSION_ID_LENGTH,sessionId)){logger?.warn(INVALID_SESSION_ID_WARNING(USER_SESSION_MANAGER,sessionId,MIN_SESSION_ID_LENGTH));return false;}return true;};/**
|
2899
|
-
* A function to generate new auto tracking session
|
2900
|
-
* @param sessionTimeout current timestamp
|
2901
|
-
* @returns SessionInfo
|
2902
|
-
*/const generateAutoTrackingSession=sessionTimeout=>{const timestamp=Date.now();const timeout=sessionTimeout||DEFAULT_SESSION_TIMEOUT_MS;return {id:timestamp,// set the current timestamp
|
2903
|
-
expiresAt:timestamp+timeout,// set the expiry time of the session
|
2904
|
-
timeout,sessionStart:undefined,autoTrack:true};};/**
|
2905
|
-
* A function to generate new manual tracking session
|
2906
|
-
* @param id Provided sessionId
|
2907
|
-
* @param logger Logger module
|
2908
|
-
* @returns SessionInfo
|
2909
|
-
*/const generateManualTrackingSession=(id,logger)=>{const sessionId=isManualSessionIdValid(id,logger)?id:generateSessionId();return {id:sessionId,sessionStart:undefined,manualTrack:true};};const isStorageTypeValidForStoringData=storageType=>Boolean(storageType===COOKIE_STORAGE||storageType===LOCAL_STORAGE||storageType===SESSION_STORAGE||storageType===MEMORY_STORAGE);
|
2910
|
-
|
2911
2953
|
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);}/**
|
2912
2954
|
* Initialize User session with values from storage
|
2913
2955
|
*/init(){this.syncStorageDataToState();// Register the effect to sync with storage
|
2914
2956
|
this.registerEffects();}syncStorageDataToState(){this.migrateStorageIfNeeded();this.migrateDataFromPreviousStorage();// get the values from storage and set it again
|
2915
|
-
|
2916
|
-
|
2917
|
-
|
2918
|
-
|
2957
|
+
this.setUserId(this.getUserId());this.setUserTraits(this.getUserTraits());this.setGroupId(this.getGroupId());this.setGroupTraits(this.getGroupTraits());this.setAnonymousId(this.getAnonymousId(state.loadOptions.value.anonymousIdOptions));this.setAuthToken(this.getAuthToken());this.setInitialReferrerInfo();this.configureSessionTracking();}configureSessionTracking(){let sessionInfo=this.getSessionInfo();if(this.isPersistenceEnabledForStorageEntry('sessionInfo')){const configuredSessionTrackingInfo=this.getConfiguredSessionTrackingInfo();const persistedSessionInfo=this.getSessionInfo()??defaultSessionInfo;sessionInfo={...persistedSessionInfo,...configuredSessionTrackingInfo,autoTrack:configuredSessionTrackingInfo.autoTrack&&persistedSessionInfo.manualTrack!==true};}this.setSessionInfo(sessionInfo);}setInitialReferrerInfo(){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));}}isPersistenceEnabledForStorageEntry(entryName){return isStorageTypeValidForStoringData(state.storage.entries.value[entryName]?.type);}migrateDataFromPreviousStorage(){const entries=state.storage.entries.value;const storageTypesForMigration=[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){storageTypesForMigration.forEach(storage=>{const store=this.storeManager?.getStore(storageClientDataStoreNameMap[storage]);if(store&&storage!==currentStorage){const value=store.get(USER_SESSION_STORAGE_KEYS[key]);if(isDefinedNotNullAndNotEmptyString(value)){curStore.set(USER_SESSION_STORAGE_KEYS[key],value);}store.remove(USER_SESSION_STORAGE_KEYS[key]);}});}});}migrateStorageIfNeeded(){if(!state.storage.migrate.value){return;}const persistentStoreNames=[CLIENT_DATA_STORE_COOKIE,CLIENT_DATA_STORE_LS,CLIENT_DATA_STORE_SESSION];const stores=[];persistentStoreNames.forEach(storeName=>{const store=this.storeManager?.getStore(storeName);if(store){stores.push(store);}});Object.keys(USER_SESSION_STORAGE_KEYS).forEach(storageKey=>{const storageEntry=USER_SESSION_STORAGE_KEYS[storageKey];stores.forEach(store=>{const migratedVal=this.pluginsManager?.invokeSingle('storage.migrate',storageEntry,store.engine,this.errorHandler,this.logger);// Skip setting the value if it is null or undefined
|
2958
|
+
// as those values indicate there is no need for migration or
|
2959
|
+
// migration failed
|
2960
|
+
if(!isNullOrUndefined(migratedVal)){store.set(storageEntry,migratedVal);}});});}getConfiguredSessionTrackingInfo(){let autoTrack=state.loadOptions.value.sessions?.autoTrack!==false;// Do not validate any further if autoTrack is disabled
|
2961
|
+
if(!autoTrack){return {autoTrack};}let timeout;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));timeout=DEFAULT_SESSION_TIMEOUT_MS;}else {timeout=configuredSessionTimeout;}if(timeout===0){this.logger?.warn(TIMEOUT_ZERO_WARNING(USER_SESSION_MANAGER));autoTrack=false;}// In case user provides a timeout value greater than 0 but less than 10 seconds SDK will show a warning
|
2919
2962
|
// and will proceed with it
|
2920
|
-
if(
|
2921
|
-
if(state.session.sessionInfo.value.autoTrack){this.startOrRenewAutoTracking();}}/**
|
2963
|
+
if(timeout>0&&timeout<MIN_SESSION_TIMEOUT_MS){this.logger?.warn(TIMEOUT_NOT_RECOMMENDED_WARNING(USER_SESSION_MANAGER,timeout,MIN_SESSION_TIMEOUT_MS));}return {timeout,autoTrack};}/**
|
2922
2964
|
* Handles error
|
2923
2965
|
* @param error The error object
|
2924
2966
|
*/onError(error){if(this.errorHandler){this.errorHandler.onError(error,USER_SESSION_MANAGER);}else {throw error;}}/**
|
@@ -2927,96 +2969,79 @@ if(state.session.sessionInfo.value.autoTrack){this.startOrRenewAutoTracking();}}
|
|
2927
2969
|
* @param value
|
2928
2970
|
*/syncValueToStorage(sessionKey,value){const entries=state.storage.entries.value;const storage=entries[sessionKey]?.type;const key=entries[sessionKey]?.key;if(isStorageTypeValidForStoringData(storage)){const curStore=this.storeManager?.getStore(storageClientDataStoreNameMap[storage]);if(value&&isString(value)||isNonEmptyObject(value)){curStore?.set(key,value);}else {curStore?.remove(key);}}}/**
|
2929
2971
|
* Function to update storage whenever state value changes
|
2930
|
-
*/registerEffects(){
|
2931
|
-
|
2932
|
-
*/O(()=>{this.syncValueToStorage('userId',state.session.userId.value);});/**
|
2933
|
-
* Update user traits in storage automatically when it is updated in state
|
2934
|
-
*/O(()=>{this.syncValueToStorage('userTraits',state.session.userTraits.value);});/**
|
2935
|
-
* Update group id in storage automatically when it is updated in state
|
2936
|
-
*/O(()=>{this.syncValueToStorage('groupId',state.session.groupId.value);});/**
|
2937
|
-
* Update group traits in storage automatically when it is updated in state
|
2938
|
-
*/O(()=>{this.syncValueToStorage('groupTraits',state.session.groupTraits.value);});/**
|
2939
|
-
* Update anonymous user id in storage automatically when it is updated in state
|
2940
|
-
*/O(()=>{this.syncValueToStorage('anonymousId',state.session.anonymousId.value);});/**
|
2941
|
-
* Update initial referrer in storage automatically when it is updated in state
|
2942
|
-
*/O(()=>{this.syncValueToStorage('initialReferrer',state.session.initialReferrer.value);});/**
|
2943
|
-
* Update initial referring domain in storage automatically when it is updated in state
|
2944
|
-
*/O(()=>{this.syncValueToStorage('initialReferringDomain',state.session.initialReferringDomain.value);});/**
|
2945
|
-
* Update session tracking info in storage automatically when it is updated in state
|
2946
|
-
*/O(()=>{this.syncValueToStorage('sessionInfo',state.session.sessionInfo.value);});/**
|
2947
|
-
* Update session tracking info in storage automatically when it is updated in state
|
2948
|
-
*/O(()=>{this.syncValueToStorage('authToken',state.session.authToken.value);});}/**
|
2972
|
+
*/registerEffects(){// This will work as long as the user session entry key names are same as the state keys
|
2973
|
+
USER_SESSION_KEYS.forEach(sessionKey=>{O(()=>{this.syncValueToStorage(sessionKey,state.session[sessionKey].value);});});}/**
|
2949
2974
|
* Sets anonymous id in the following precedence:
|
2950
2975
|
*
|
2951
2976
|
* 1. anonymousId: Id directly provided to the function.
|
2952
2977
|
* 2. rudderAmpLinkerParam: value generated from linker query parm (rudderstack)
|
2953
2978
|
* using parseLinker util.
|
2954
2979
|
* 3. generateUUID: A new unique id is generated and assigned.
|
2955
|
-
*/setAnonymousId(anonymousId,rudderAmpLinkerParam){let finalAnonymousId=anonymousId;if(this.isPersistenceEnabledForStorageEntry('anonymousId')){if(!finalAnonymousId&&rudderAmpLinkerParam){const linkerPluginsResult=this.pluginsManager?.
|
2956
|
-
* Generate a new anonymousId
|
2957
|
-
* @returns string anonymousID
|
2958
|
-
*/generateAnonymousId(){return generateUUID();}/**
|
2980
|
+
*/setAnonymousId(anonymousId,rudderAmpLinkerParam){let finalAnonymousId=anonymousId;if(this.isPersistenceEnabledForStorageEntry('anonymousId')){if(!finalAnonymousId&&rudderAmpLinkerParam){const linkerPluginsResult=this.pluginsManager?.invokeSingle('userSession.anonymousIdGoogleLinker',rudderAmpLinkerParam);finalAnonymousId=linkerPluginsResult;}finalAnonymousId=finalAnonymousId||generateAnonymousId();}else {finalAnonymousId=DEFAULT_USER_SESSION_VALUES.anonymousId;}state.session.anonymousId.value=finalAnonymousId;}/**
|
2959
2981
|
* Fetches anonymousId
|
2960
2982
|
* @param options option to fetch it from external source
|
2961
2983
|
* @returns anonymousId
|
2962
|
-
*/getAnonymousId(options){const storage=state.storage.entries.value.anonymousId?.type
|
2963
|
-
if(isStorageTypeValidForStoringData(storage)){
|
2964
|
-
const autoCapturedAnonymousId=this.pluginsManager?.invokeSingle('storage.getAnonymousId',getStorageEngine,options);persistedAnonymousId=autoCapturedAnonymousId;}state.session.anonymousId.value=persistedAnonymousId||
|
2984
|
+
*/getAnonymousId(options){const storage=state.storage.entries.value.anonymousId?.type;// fetch the anonymousId from storage
|
2985
|
+
if(isStorageTypeValidForStoringData(storage)){let persistedAnonymousId=this.getEntryValue('anonymousId');if(!persistedAnonymousId&&options){// fetch anonymousId from external source
|
2986
|
+
const autoCapturedAnonymousId=this.pluginsManager?.invokeSingle('storage.getAnonymousId',getStorageEngine,options);persistedAnonymousId=autoCapturedAnonymousId;}state.session.anonymousId.value=persistedAnonymousId||generateAnonymousId();}return state.session.anonymousId.value;}getEntryValue(sessionKey){const entries=state.storage.entries.value;const storageType=entries[sessionKey]?.type;if(isStorageTypeValidForStoringData(storageType)){const store=this.storeManager?.getStore(storageClientDataStoreNameMap[storageType]);const storageKey=entries[sessionKey]?.key;return store?.get(storageKey)??null;}return null;}/**
|
2965
2987
|
* Fetches User Id
|
2966
2988
|
* @returns
|
2967
|
-
*/getUserId(){return this.
|
2989
|
+
*/getUserId(){return this.getEntryValue('userId');}/**
|
2968
2990
|
* Fetches User Traits
|
2969
2991
|
* @returns
|
2970
|
-
*/getUserTraits(){return this.
|
2992
|
+
*/getUserTraits(){return this.getEntryValue('userTraits');}/**
|
2971
2993
|
* Fetches Group Id
|
2972
2994
|
* @returns
|
2973
|
-
*/getGroupId(){return this.
|
2995
|
+
*/getGroupId(){return this.getEntryValue('groupId');}/**
|
2974
2996
|
* Fetches Group Traits
|
2975
2997
|
* @returns
|
2976
|
-
*/getGroupTraits(){return this.
|
2998
|
+
*/getGroupTraits(){return this.getEntryValue('groupTraits');}/**
|
2977
2999
|
* Fetches Initial Referrer
|
2978
3000
|
* @returns
|
2979
|
-
*/getInitialReferrer(){return this.
|
3001
|
+
*/getInitialReferrer(){return this.getEntryValue('initialReferrer');}/**
|
2980
3002
|
* Fetches Initial Referring domain
|
2981
3003
|
* @returns
|
2982
|
-
*/getInitialReferringDomain(){return this.
|
3004
|
+
*/getInitialReferringDomain(){return this.getEntryValue('initialReferringDomain');}/**
|
2983
3005
|
* Fetches session tracking information from storage
|
2984
3006
|
* @returns
|
2985
|
-
*/
|
3007
|
+
*/getSessionInfo(){return this.getEntryValue('sessionInfo');}/**
|
2986
3008
|
* Fetches auth token from storage
|
2987
3009
|
* @returns
|
2988
|
-
*/getAuthToken(){return this.
|
3010
|
+
*/getAuthToken(){return this.getEntryValue('authToken');}/**
|
2989
3011
|
* If session is active it returns the sessionId
|
2990
3012
|
* @returns
|
2991
|
-
*/getSessionId(){
|
3013
|
+
*/getSessionId(){const sessionInfo=state.session.sessionInfo.value;if(sessionInfo.autoTrack&&!hasSessionExpired(sessionInfo.expiresAt)||sessionInfo.manualTrack){return sessionInfo.id??null;}return null;}/**
|
2992
3014
|
* A function to update current session info after each event call
|
2993
|
-
*/refreshSession(){
|
3015
|
+
*/refreshSession(){let sessionInfo=state.session.sessionInfo.value;if(sessionInfo.autoTrack||sessionInfo.manualTrack){if(sessionInfo.autoTrack){this.startOrRenewAutoTracking();}// Re-assigning the variable with the same value intentionally as
|
3016
|
+
// startOrRenewAutoTracking() will update the sessionInfo value
|
3017
|
+
sessionInfo=state.session.sessionInfo.value;if(sessionInfo.sessionStart===undefined){state.session.sessionInfo.value={...sessionInfo,sessionStart:true};}else if(sessionInfo.sessionStart){state.session.sessionInfo.value={...sessionInfo,sessionStart:false};}}}/**
|
2994
3018
|
* Reset state values
|
2995
3019
|
* @param resetAnonymousId
|
2996
3020
|
* @param noNewSessionStart
|
2997
3021
|
* @returns
|
2998
|
-
*/reset(resetAnonymousId,noNewSessionStart){const{manualTrack,autoTrack}=
|
2999
|
-
this.setAnonymousId();}if(noNewSessionStart){return;}if(autoTrack){
|
3022
|
+
*/reset(resetAnonymousId,noNewSessionStart){const{session}=state;const{manualTrack,autoTrack}=session.sessionInfo.value;n(()=>{session.userId.value=DEFAULT_USER_SESSION_VALUES.userId;session.userTraits.value=DEFAULT_USER_SESSION_VALUES.userTraits;session.groupId.value=DEFAULT_USER_SESSION_VALUES.groupId;session.groupTraits.value=DEFAULT_USER_SESSION_VALUES.groupTraits;session.authToken.value=DEFAULT_USER_SESSION_VALUES.authToken;if(resetAnonymousId){// This will generate a new anonymous ID
|
3023
|
+
this.setAnonymousId();}if(noNewSessionStart){return;}if(autoTrack){session.sessionInfo.value=DEFAULT_USER_SESSION_VALUES.sessionInfo;this.startOrRenewAutoTracking();}else if(manualTrack){this.startManualTrackingInternal();}});}setSessionInfo(sessionInfo){state.session.sessionInfo.value=this.isPersistenceEnabledForStorageEntry('sessionInfo')?sessionInfo:DEFAULT_USER_SESSION_VALUES.sessionInfo;// If auto session tracking is enabled start the session tracking
|
3024
|
+
if(state.session.sessionInfo.value.autoTrack){this.startOrRenewAutoTracking();}}/**
|
3000
3025
|
* Set user Id
|
3001
3026
|
* @param userId
|
3002
|
-
*/setUserId(userId){
|
3027
|
+
*/setUserId(userId){state.session.userId.value=this.isPersistenceEnabledForStorageEntry('userId')&&userId?userId:DEFAULT_USER_SESSION_VALUES.userId;}/**
|
3003
3028
|
* Set user traits
|
3004
3029
|
* @param traits
|
3005
|
-
*/setUserTraits(traits){
|
3030
|
+
*/setUserTraits(traits){state.session.userTraits.value=this.isPersistenceEnabledForStorageEntry('userTraits')&&traits?mergeDeepRight(state.session.userTraits.value??{},traits):DEFAULT_USER_SESSION_VALUES.userTraits;}/**
|
3006
3031
|
* Set group Id
|
3007
3032
|
* @param groupId
|
3008
|
-
*/setGroupId(groupId){
|
3033
|
+
*/setGroupId(groupId){state.session.groupId.value=this.isPersistenceEnabledForStorageEntry('groupId')&&groupId?groupId:DEFAULT_USER_SESSION_VALUES.groupId;}/**
|
3009
3034
|
* Set group traits
|
3010
3035
|
* @param traits
|
3011
|
-
*/setGroupTraits(traits){
|
3036
|
+
*/setGroupTraits(traits){state.session.groupTraits.value=this.isPersistenceEnabledForStorageEntry('groupTraits')&&traits?mergeDeepRight(state.session.groupTraits.value??{},traits):DEFAULT_USER_SESSION_VALUES.groupTraits;}/**
|
3012
3037
|
* Set initial referrer
|
3013
3038
|
* @param referrer
|
3014
|
-
*/setInitialReferrer(referrer){
|
3039
|
+
*/setInitialReferrer(referrer){state.session.initialReferrer.value=this.isPersistenceEnabledForStorageEntry('initialReferrer')&&referrer?referrer:DEFAULT_USER_SESSION_VALUES.initialReferrer;}/**
|
3015
3040
|
* Set initial referring domain
|
3016
3041
|
* @param {String} referringDomain
|
3017
|
-
*/setInitialReferringDomain(referringDomain){
|
3018
|
-
* A function to check for existing session details and depending on that create a new session
|
3019
|
-
*/startOrRenewAutoTracking(){
|
3042
|
+
*/setInitialReferringDomain(referringDomain){state.session.initialReferringDomain.value=this.isPersistenceEnabledForStorageEntry('initialReferringDomain')&&referringDomain?referringDomain:DEFAULT_USER_SESSION_VALUES.initialReferringDomain;}/**
|
3043
|
+
* A function to check for existing session details and depending on that create a new session
|
3044
|
+
*/startOrRenewAutoTracking(){const sessionInfo=state.session.sessionInfo.value;if(hasSessionExpired(sessionInfo.expiresAt)){state.session.sessionInfo.value=generateAutoTrackingSession(sessionInfo.timeout);}else {const timestamp=Date.now();const timeout=sessionInfo.timeout;state.session.sessionInfo.value=mergeDeepRight(sessionInfo,{expiresAt:timestamp+timeout// set the expiry time of the session
|
3020
3045
|
});}}/**
|
3021
3046
|
* A function method to start a manual session
|
3022
3047
|
* @param {number} id session identifier
|
@@ -3028,7 +3053,7 @@ this.setAnonymousId();}if(noNewSessionStart){return;}if(autoTrack){state.session
|
|
3028
3053
|
*/end(){state.session.sessionInfo.value={};}/**
|
3029
3054
|
* Set auth token
|
3030
3055
|
* @param userId
|
3031
|
-
*/setAuthToken(token){
|
3056
|
+
*/setAuthToken(token){state.session.authToken.value=this.isPersistenceEnabledForStorageEntry('authToken')&&token?token:DEFAULT_USER_SESSION_VALUES.authToken;}}
|
3032
3057
|
|
3033
3058
|
/**
|
3034
3059
|
* A buffer queue to serve as a store for any type of data
|
@@ -3061,11 +3086,11 @@ const eventIntgConfig=event.integrations??DEFAULT_INTEGRATIONS_CONFIG;const dest
|
|
3061
3086
|
*/constructor(pluginsManager,storeManager,errorHandler,logger){this.pluginsManager=pluginsManager;this.errorHandler=errorHandler;this.logger=logger;this.httpClient=new HttpClient(errorHandler,logger);this.storeManager=storeManager;this.onError=this.onError.bind(this);}/**
|
3062
3087
|
* Initializes the event repository
|
3063
3088
|
*/init(){this.dataplaneEventsQueue=this.pluginsManager.invokeSingle(`${DATA_PLANE_QUEUE_EXT_POINT_PREFIX}.init`,state,this.httpClient,this.storeManager,this.errorHandler,this.logger);this.dmtEventsQueue=this.pluginsManager.invokeSingle(`${DMT_EXT_POINT_PREFIX}.init`,state,this.pluginsManager,this.httpClient,this.storeManager,this.errorHandler,this.logger);this.destinationsEventsQueue=this.pluginsManager.invokeSingle(`${DESTINATIONS_QUEUE_EXT_POINT_PREFIX}.init`,state,this.pluginsManager,this.storeManager,this.dmtEventsQueue,this.errorHandler,this.logger);// Start the queue once the client destinations are ready
|
3064
|
-
O(()=>{if(state.nativeDestinations.clientDestinationsReady.value===true){this.destinationsEventsQueue?.start();this.dmtEventsQueue?.start();}});// Start the queue processing only when the destinations are ready or hybrid mode destinations exist
|
3089
|
+
O(()=>{if(state.nativeDestinations.clientDestinationsReady.value===true){this.destinationsEventsQueue?.start();this.dmtEventsQueue?.start();}});const bufferEventsBeforeConsent=shouldBufferEventsForPreConsent(state);// Start the queue processing only when the destinations are ready or hybrid mode destinations exist
|
3065
3090
|
// However, events will be enqueued for now.
|
3066
3091
|
// At the time of processing the events, the integrations config data from destinations
|
3067
3092
|
// is merged into the event object
|
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)&&!
|
3093
|
+
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)&&!bufferEventsBeforeConsent&&this.dataplaneEventsQueue?.scheduleTimeoutActive!==true){globalThis.clearTimeout(timeoutId);this.dataplaneEventsQueue?.start();}});// Force start the data plane events queue processing after a timeout
|
3069
3094
|
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();}}/**
|
3070
3095
|
* Enqueues the event for processing
|
3071
3096
|
* @param event RudderEvent object
|
@@ -3080,11 +3105,13 @@ callback?.(dpQEvent);}catch(error){this.onError(error,API_CALLBACK_INVOKE_ERROR)
|
|
3080
3105
|
* @param shouldAlwaysThrow if it should throw or use logger
|
3081
3106
|
*/onError(error,customMessage,shouldAlwaysThrow){if(this.errorHandler){this.errorHandler.onError(error,EVENT_REPOSITORY,customMessage,shouldAlwaysThrow);}else {throw error;}}}
|
3082
3107
|
|
3108
|
+
const dispatchSDKEvent=event=>{const customEvent=new CustomEvent(event,{detail:{analyticsInstance:globalThis.rudderanalytics},bubbles:true,cancelable:true,composed:true});globalThis.document.dispatchEvent(customEvent);};
|
3109
|
+
|
3083
3110
|
/*
|
3084
3111
|
* Analytics class with lifecycle based on state ad user triggered events
|
3085
|
-
*/class Analytics{
|
3112
|
+
*/class Analytics{/**
|
3086
3113
|
* Initialize services and components or use default ones if singletons
|
3087
|
-
*/constructor(){this.initialized=false;this.errorHandler=defaultErrorHandler;this.logger=defaultLogger;this.externalSrcLoader=new ExternalSrcLoader(this.errorHandler,this.logger);this.capabilitiesManager=new CapabilitiesManager(this.errorHandler,this.logger);this.httpClient=defaultHttpClient;
|
3114
|
+
*/constructor(){this.preloadBuffer=new BufferQueue();this.initialized=false;this.errorHandler=defaultErrorHandler;this.logger=defaultLogger;this.externalSrcLoader=new ExternalSrcLoader(this.errorHandler,this.logger);this.capabilitiesManager=new CapabilitiesManager(this.errorHandler,this.logger);this.httpClient=defaultHttpClient;}/**
|
3088
3115
|
* Start application lifecycle if not already started
|
3089
3116
|
*/load(writeKey,dataPlaneUrl,loadOptions={}){if(state.lifecycle.status.value){return;}let clonedDataPlaneUrl=clone$1(dataPlaneUrl);let clonedLoadOptions=clone$1(loadOptions);// dataPlaneUrl is not provided
|
3090
3117
|
if(isObjectAndNotNull(dataPlaneUrl)){clonedLoadOptions=dataPlaneUrl;clonedDataPlaneUrl=undefined;}// Set initial state values
|
@@ -3095,11 +3122,11 @@ setExposedGlobal('state',state,writeKey);// Configure initial config of any serv
|
|
3095
3122
|
this.startLifecycle();}// Start lifecycle methods
|
3096
3123
|
/**
|
3097
3124
|
* Orchestrate the lifecycle of the application phases/status
|
3098
|
-
*/startLifecycle(){O(()=>{try{switch(state.lifecycle.status.value){case'mounted':this.
|
3099
|
-
retrievePreloadBufferEvents(this);this.prepareInternalServices();this.loadConfig();
|
3125
|
+
*/startLifecycle(){O(()=>{try{switch(state.lifecycle.status.value){case'mounted':this.onMounted();break;case'browserCapabilitiesReady':this.onBrowserCapabilitiesReady();break;case'configured':this.onConfigured();break;case'pluginsLoading':break;case'pluginsReady':this.onPluginsReady();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);}});}onBrowserCapabilitiesReady(){// initialize the preloaded events enqueuing
|
3126
|
+
retrievePreloadBufferEvents(this);this.prepareInternalServices();this.loadConfig();}onLoaded(){this.processBufferedEvents();// Short-circuit the life cycle and move to the ready state if pre-consent behavior is enabled
|
3100
3127
|
if(state.consents.preConsent.value.enabled===true){state.lifecycle.status.value='ready';}else {this.loadDestinations();}}/**
|
3101
3128
|
* Load browser polyfill if required
|
3102
|
-
*/
|
3129
|
+
*/onMounted(){this.capabilitiesManager.init();}/**
|
3103
3130
|
* Enqueue in SDK preload buffer events, used from preloadBuffer component
|
3104
3131
|
*/enqueuePreloadBufferEvents(bufferedEvents){if(Array.isArray(bufferedEvents)){bufferedEvents.forEach(bufferedEvent=>this.preloadBuffer.enqueue(clone$1(bufferedEvent)));}}/**
|
3105
3132
|
* Process the buffer preloaded events by passing their arguments to the respective facade methods
|
@@ -3107,13 +3134,13 @@ if(state.consents.preConsent.value.enabled===true){state.lifecycle.status.value=
|
|
3107
3134
|
* Load configuration
|
3108
3135
|
*/loadConfig(){if(state.lifecycle.writeKey.value){this.httpClient.setAuthHeader(state.lifecycle.writeKey.value);}this.configManager?.init();}/**
|
3109
3136
|
* Initialize the storage and event queue
|
3110
|
-
*/
|
3137
|
+
*/onPluginsReady(){this.errorHandler.init(this.externalSrcLoader);// Initialize storage
|
3111
3138
|
this.storeManager?.init();this.userSessionManager?.init();// Initialize the appropriate consent manager plugin
|
3112
3139
|
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
|
3113
3140
|
this.eventManager?.init();// Mark the SDK as initialized
|
3114
3141
|
state.lifecycle.status.value='initialized';}/**
|
3115
3142
|
* Load plugins
|
3116
|
-
*/
|
3143
|
+
*/onConfigured(){this.pluginsManager?.init();// TODO: are we going to enable custom plugins to be passed as load options?
|
3117
3144
|
// registerCustomPlugins(state.loadOptions.value.customPlugins);
|
3118
3145
|
}/**
|
3119
3146
|
* Trigger onLoaded callback if any is provided in config & emit initialised event
|
@@ -3123,14 +3150,17 @@ this.processDataInPreloadBuffer();// TODO: we need to avoid passing the window o
|
|
3123
3150
|
// Execute onLoaded callback if provided in load options
|
3124
3151
|
if(isFunction(state.loadOptions.value.onLoaded)){state.loadOptions.value.onLoaded(globalThis.rudderanalytics);}// Set lifecycle state
|
3125
3152
|
n(()=>{state.lifecycle.loaded.value=true;state.lifecycle.status.value='loaded';});this.initialized=true;// Emit an event to use as substitute to the onLoaded callback
|
3126
|
-
|
3153
|
+
dispatchSDKEvent('RSA_Initialised');}/**
|
3127
3154
|
* Emit ready event
|
3128
3155
|
*/ // eslint-disable-next-line class-methods-use-this
|
3129
3156
|
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
|
3130
|
-
|
3157
|
+
dispatchSDKEvent('RSA_Ready');}/**
|
3131
3158
|
* Consume preloaded events buffer
|
3132
|
-
*/processBufferedEvents(){//
|
3133
|
-
|
3159
|
+
*/processBufferedEvents(){// This logic has been intentionally implemented without a simple
|
3160
|
+
// for-loop as the individual events that are processed may
|
3161
|
+
// add more events to the buffer (this is needed for the consent API)
|
3162
|
+
let bufferedEvents=state.eventBuffer.toBeProcessedArray.value;while(bufferedEvents.length>0){const bufferedEvent=bufferedEvents.shift();state.eventBuffer.toBeProcessedArray.value=bufferedEvents;if(bufferedEvent){const methodName=bufferedEvent[0];if(isFunction(this[methodName])){// Send additional arg 'true' to indicate that this is a buffered invocation
|
3163
|
+
this[methodName](...bufferedEvent.slice(1),true);}}bufferedEvents=state.eventBuffer.toBeProcessedArray.value;}}/**
|
3134
3164
|
* Load device mode destinations
|
3135
3165
|
*/loadDestinations(){if(state.nativeDestinations.clientDestinationsReady.value){return;}// Set in state the desired activeDestinations to inject in DOM
|
3136
3166
|
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
|
@@ -3142,30 +3172,30 @@ onDestinationsReady(){// May be do any destination specific actions here
|
|
3142
3172
|
// Mark the ready status if not already done
|
3143
3173
|
if(state.lifecycle.status.value!=='ready'){state.lifecycle.status.value='ready';}}// End lifecycle methods
|
3144
3174
|
// Start consumer exposed methods
|
3145
|
-
ready(callback){const type='ready';
|
3175
|
+
ready(callback,isBufferedInvocation=false){const type='ready';if(!state.lifecycle.loaded.value){state.eventBuffer.toBeProcessedArray.value=[...state.eventBuffer.toBeProcessedArray.value,[type,callback]];return;}this.errorHandler.leaveBreadcrumb(`New ${type} invocation`);if(!isFunction(callback)){this.logger.error(READY_API_CALLBACK_ERROR(READY_API));return;}/**
|
3146
3176
|
* If destinations are loaded or no integration is available for loading
|
3147
3177
|
* execute the callback immediately else push the callbacks to a queue that
|
3148
3178
|
* will be executed after loading completes
|
3149
|
-
*/if(state.lifecycle.status.value==='ready'){try{callback();}catch(err){this.errorHandler.onError(err,ANALYTICS_CORE,READY_CALLBACK_INVOKE_ERROR);}}else {state.eventBuffer.readyCallbacksArray.value.push(callback);}}page(payload){const type='page';
|
3179
|
+
*/if(state.lifecycle.status.value==='ready'){try{callback();}catch(err){this.errorHandler.onError(err,ANALYTICS_CORE,READY_CALLBACK_INVOKE_ERROR);}}else {state.eventBuffer.readyCallbacksArray.value.push(callback);}}page(payload,isBufferedInvocation=false){const type='page';if(!state.lifecycle.loaded.value){state.eventBuffer.toBeProcessedArray.value=[...state.eventBuffer.toBeProcessedArray.value,[type,payload]];return;}this.errorHandler.leaveBreadcrumb(`New ${type} event`);state.metrics.triggered.value+=1;this.eventManager?.addEvent({type:'page',category:payload.category,name:payload.name,properties:payload.properties,options:payload.options,callback:payload.callback});// TODO: Maybe we should alter the behavior to send the ad-block page event even if the SDK is still loaded. It'll be pushed into the to be processed queue.
|
3150
3180
|
// Send automatic ad blocked page event if ad-blockers are detected on the page
|
3151
3181
|
// Check page category to avoid infinite loop
|
3152
|
-
if(state.capabilities.isAdBlocked.value===true&&payload.category!==ADBLOCK_PAGE_CATEGORY){
|
3182
|
+
if(state.capabilities.isAdBlocked.value===true&&payload.category!==ADBLOCK_PAGE_CATEGORY){this.page(pageArgumentsToCallOptions(ADBLOCK_PAGE_CATEGORY,ADBLOCK_PAGE_NAME,{// 'title' is intentionally omitted as it does not make sense
|
3153
3183
|
// in v3 implementation
|
3154
|
-
path:ADBLOCK_PAGE_PATH},
|
3155
|
-
if(!isNull(payload.userId)){this.userSessionManager?.setUserId(payload.userId);}this.userSessionManager?.setUserTraits(payload.traits);this.eventManager?.addEvent({type,userId:payload.userId,traits:payload.traits,options:payload.options,callback:payload.callback});}alias(payload){const type='alias';
|
3156
|
-
if(!isNull(payload.groupId)){this.userSessionManager?.setGroupId(payload.groupId);}this.userSessionManager?.setGroupTraits(payload.traits);this.eventManager?.addEvent({type,groupId:payload.groupId,traits:payload.traits,options:payload.options,callback:payload.callback});}reset(resetAnonymousId){const type='reset';
|
3157
|
-
if(!state.lifecycle.loaded.value){state.eventBuffer.toBeProcessedArray.value.
|
3184
|
+
path:ADBLOCK_PAGE_PATH},state.loadOptions.value.sendAdblockPageOptions));}}track(payload,isBufferedInvocation=false){const type='track';if(!state.lifecycle.loaded.value){state.eventBuffer.toBeProcessedArray.value=[...state.eventBuffer.toBeProcessedArray.value,[type,payload]];return;}this.errorHandler.leaveBreadcrumb(`New ${type} event`);state.metrics.triggered.value+=1;this.eventManager?.addEvent({type,name:payload.name||undefined,properties:payload.properties,options:payload.options,callback:payload.callback});}identify(payload,isBufferedInvocation=false){const type='identify';if(!state.lifecycle.loaded.value){state.eventBuffer.toBeProcessedArray.value=[...state.eventBuffer.toBeProcessedArray.value,[type,payload]];return;}this.errorHandler.leaveBreadcrumb(`New ${type} event`);state.metrics.triggered.value+=1;const shouldResetSession=Boolean(payload.userId&&state.session.userId.value&&payload.userId!==state.session.userId.value);if(shouldResetSession){this.reset();}// `null` value indicates that previous user ID needs to be retained
|
3185
|
+
if(!isNull(payload.userId)){this.userSessionManager?.setUserId(payload.userId);}this.userSessionManager?.setUserTraits(payload.traits);this.eventManager?.addEvent({type,userId:payload.userId,traits:payload.traits,options:payload.options,callback:payload.callback});}alias(payload,isBufferedInvocation=false){const type='alias';if(!state.lifecycle.loaded.value){state.eventBuffer.toBeProcessedArray.value=[...state.eventBuffer.toBeProcessedArray.value,[type,payload]];return;}this.errorHandler.leaveBreadcrumb(`New ${type} event`);state.metrics.triggered.value+=1;const previousId=payload.from??this.userSessionManager?.getUserId()??this.userSessionManager?.getAnonymousId();this.eventManager?.addEvent({type,to:payload.to,from:previousId,options:payload.options,callback:payload.callback});}group(payload,isBufferedInvocation=false){const type='group';if(!state.lifecycle.loaded.value){state.eventBuffer.toBeProcessedArray.value=[...state.eventBuffer.toBeProcessedArray.value,[type,payload]];return;}this.errorHandler.leaveBreadcrumb(`New ${type} event`);state.metrics.triggered.value+=1;// `null` value indicates that previous group ID needs to be retained
|
3186
|
+
if(!isNull(payload.groupId)){this.userSessionManager?.setGroupId(payload.groupId);}this.userSessionManager?.setGroupTraits(payload.traits);this.eventManager?.addEvent({type,groupId:payload.groupId,traits:payload.traits,options:payload.options,callback:payload.callback});}reset(resetAnonymousId,isBufferedInvocation=false){const type='reset';if(!state.lifecycle.loaded.value){state.eventBuffer.toBeProcessedArray.value=[...state.eventBuffer.toBeProcessedArray.value,[type,resetAnonymousId]];return;}this.errorHandler.leaveBreadcrumb(`New ${type} invocation, resetAnonymousId: ${resetAnonymousId}`);this.userSessionManager?.reset(resetAnonymousId);}getAnonymousId(options){return this.userSessionManager?.getAnonymousId(options);}setAnonymousId(anonymousId,rudderAmpLinkerParam,isBufferedInvocation=false){const type='setAnonymousId';// Buffering is needed as setting the anonymous ID may require invoking the GoogleLinker plugin
|
3187
|
+
if(!state.lifecycle.loaded.value){state.eventBuffer.toBeProcessedArray.value=[...state.eventBuffer.toBeProcessedArray.value,[type,anonymousId,rudderAmpLinkerParam]];return;}this.errorHandler.leaveBreadcrumb(`New ${type} invocation`);this.userSessionManager?.setAnonymousId(anonymousId,rudderAmpLinkerParam);}// eslint-disable-next-line class-methods-use-this
|
3158
3188
|
getUserId(){return state.session.userId.value;}// eslint-disable-next-line class-methods-use-this
|
3159
3189
|
getUserTraits(){return state.session.userTraits.value;}// eslint-disable-next-line class-methods-use-this
|
3160
3190
|
getGroupId(){return state.session.groupId.value;}// eslint-disable-next-line class-methods-use-this
|
3161
|
-
getGroupTraits(){return state.session.groupTraits.value;}startSession(sessionId){const type='startSession';
|
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);}//
|
3164
|
-
|
3165
|
-
|
3166
|
-
|
3167
|
-
//
|
3168
|
-
this.
|
3191
|
+
getGroupTraits(){return state.session.groupTraits.value;}startSession(sessionId,isBufferedInvocation=false){const type='startSession';if(!state.lifecycle.loaded.value){state.eventBuffer.toBeProcessedArray.value=[...state.eventBuffer.toBeProcessedArray.value,[type,sessionId]];return;}this.errorHandler.leaveBreadcrumb(`New ${type} invocation`);this.userSessionManager?.start(sessionId);}endSession(isBufferedInvocation=false){const type='endSession';if(!state.lifecycle.loaded.value){state.eventBuffer.toBeProcessedArray.value=[...state.eventBuffer.toBeProcessedArray.value,[type]];return;}this.errorHandler.leaveBreadcrumb(`New ${type} invocation`);this.userSessionManager?.end();}// eslint-disable-next-line class-methods-use-this
|
3192
|
+
getSessionId(){const sessionId=this.userSessionManager?.getSessionId();return sessionId??null;}consent(options,isBufferedInvocation=false){const type='consent';if(!state.lifecycle.loaded.value){state.eventBuffer.toBeProcessedArray.value=[...state.eventBuffer.toBeProcessedArray.value,[type,options]];return;}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
|
3193
|
+
if(state.consents.enabled.value&&!state.consents.initialized.value){this.pluginsManager?.invokeSingle(`consentManager.updateConsentsInfo`,state,this.storeManager,this.logger);}// Re-init store manager
|
3194
|
+
this.storeManager?.initializeStorageState();// Re-init user session manager
|
3195
|
+
this.userSessionManager?.syncStorageDataToState();// Resume event manager to process the events to destinations
|
3196
|
+
this.eventManager?.resume();this.loadDestinations();this.sendTrackingEvents(isBufferedInvocation);}sendTrackingEvents(isBufferedInvocation){// If isBufferedInvocation is true, then the tracking events will be added to the end of the
|
3197
|
+
// events buffer array so that any other preload events (mainly from query string API) will be processed first.
|
3198
|
+
if(state.consents.postConsent.value.trackConsent){const trackOptions=trackArgumentsToCallOptions(CONSENT_TRACK_EVENT_NAME);if(isBufferedInvocation){state.eventBuffer.toBeProcessedArray.value=[...state.eventBuffer.toBeProcessedArray.value,['track',trackOptions]];}else {this.track(trackOptions);}}if(state.consents.postConsent.value.sendPageEvent){const pageOptions=pageArgumentsToCallOptions();if(isBufferedInvocation){state.eventBuffer.toBeProcessedArray.value=[...state.eventBuffer.toBeProcessedArray.value,['page',pageOptions]];}else {this.page(pageOptions);}}}setAuthToken(token){this.userSessionManager?.setAuthToken(token);}// End consumer exposed methods
|
3169
3199
|
}
|
3170
3200
|
|
3171
3201
|
/*
|
@@ -3177,8 +3207,7 @@ this.eventManager?.resume();this.loadDestinations();}setAuthToken(token){this.us
|
|
3177
3207
|
constructor(){if(RudderAnalytics.globalSingleton){// START-NO-SONAR-SCAN
|
3178
3208
|
// eslint-disable-next-line no-constructor-return
|
3179
3209
|
return RudderAnalytics.globalSingleton;// END-NO-SONAR-SCAN
|
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.
|
3181
|
-
this.getPreloadBuffer();// start loading if a load event was buffered or wait for explicit load call
|
3210
|
+
}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.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;// start loading if a load event was buffered or wait for explicit load call
|
3182
3211
|
this.triggerBufferedLoadEvent();}/**
|
3183
3212
|
* Set instance to use if no specific writeKey is provided in methods
|
3184
3213
|
* automatically for the first created instance
|
@@ -3188,13 +3217,14 @@ this.triggerBufferedLoadEvent();}/**
|
|
3188
3217
|
*/getAnalyticsInstance(writeKey){const instanceId=writeKey??this.defaultAnalyticsKey;const analyticsInstanceExists=Boolean(this.analyticsInstances[instanceId]);if(!analyticsInstanceExists){this.analyticsInstances[instanceId]=new Analytics();}return this.analyticsInstances[instanceId];}/**
|
3189
3218
|
* Create new analytics instance and trigger application lifecycle start
|
3190
3219
|
*/load(writeKey,dataPlaneUrl,loadOptions){if(!isString(writeKey)){this.logger.error(WRITE_KEY_NOT_A_STRING_ERROR(RS_APP,writeKey));return;}if(this.analyticsInstances[writeKey]){return;}this.setDefaultInstanceKey(writeKey);this.analyticsInstances[writeKey]=new Analytics();this.getAnalyticsInstance(writeKey).load(writeKey,dataPlaneUrl,loadOptions);}/**
|
3191
|
-
*
|
3192
|
-
|
3193
|
-
|
3194
|
-
|
3195
|
-
|
3196
|
-
|
3197
|
-
const loadEvent=getPreloadedLoadEvent(preloadedEventsArray);//
|
3220
|
+
* Trigger load event in buffer queue if exists and stores the
|
3221
|
+
* remaining preloaded events array in global object
|
3222
|
+
*/triggerBufferedLoadEvent(){const preloadedEventsArray=Array.isArray(globalThis.rudderanalytics)?globalThis.rudderanalytics:[];// The array will be mutated in the below method
|
3223
|
+
promotePreloadedConsentEventsToTop(preloadedEventsArray);// Get any load method call that is buffered if any
|
3224
|
+
// BTW, load method is also removed from the array
|
3225
|
+
// So, the Analytics object can directly consume the remaining events
|
3226
|
+
const loadEvent=getPreloadedLoadEvent(preloadedEventsArray);// Set the final preloaded events array in global object
|
3227
|
+
setExposedGlobal(GLOBAL_PRELOAD_BUFFER,clone$1(preloadedEventsArray));// Process load method if present in the buffered requests
|
3198
3228
|
if(loadEvent.length>0){// Remove the event name from the Buffered Event array and keep only arguments
|
3199
3229
|
loadEvent.shift();// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
3200
3230
|
// @ts-ignore
|