@rudderstack/analytics-js 3.0.0-beta.11 → 3.0.0-beta.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +25 -0
- package/README.md +57 -10
- package/dist/npm/index.d.ts +174 -76
- package/dist/npm/legacy/cjs/index.js +71 -43
- package/dist/npm/legacy/esm/index.js +71 -43
- package/dist/npm/legacy/umd/index.js +71 -43
- package/dist/npm/modern/bundled/cjs/index.js +66 -38
- package/dist/npm/modern/bundled/esm/index.js +66 -38
- package/dist/npm/modern/bundled/umd/index.js +66 -38
- package/dist/npm/modern/cjs/index.js +44 -29
- package/dist/npm/modern/esm/index.js +44 -29
- package/dist/npm/modern/umd/index.js +44 -29
- package/package.json +1 -1
@@ -415,7 +415,7 @@ if(isDefined(payload.groupId)){payload.groupId=tryStringify(payload.groupId);}el
|
|
415
415
|
|
416
416
|
const CAPABILITIES_MANAGER='CapabilitiesManager';const CONFIG_MANAGER='ConfigManager';const EVENT_MANAGER='EventManager';const PLUGINS_MANAGER='PluginsManager';const USER_SESSION_MANAGER='UserSessionManager';const ERROR_HANDLER='ErrorHandler';const PLUGIN_ENGINE='PluginEngine';const STORE_MANAGER='StoreManager';const READY_API='readyApi';const LOAD_CONFIGURATION='LoadConfiguration';const EVENT_REPOSITORY='EventRepository';const EXTERNAL_SRC_LOADER='ExternalSrcLoader';const HTTP_CLIENT='HttpClient';const RS_APP='RudderStackApplication';const ANALYTICS_CORE='AnalyticsCore';
|
417
417
|
|
418
|
-
const APP_NAME='RudderLabs JavaScript SDK';const APP_VERSION='3.0.0-beta.
|
418
|
+
const APP_NAME='RudderLabs JavaScript SDK';const APP_VERSION='3.0.0-beta.13';const APP_NAMESPACE='com.rudderlabs.javascript';const MODULE_TYPE='npm';const ADBLOCK_PAGE_CATEGORY='RudderJS-Initiated';const ADBLOCK_PAGE_NAME='ad-block page request';const ADBLOCK_PAGE_PATH='/ad-blocked';const GLOBAL_PRELOAD_BUFFER='preloadedEventsBuffer';
|
419
419
|
|
420
420
|
const QUERY_PARAM_TRAIT_PREFIX='ajs_trait_';const QUERY_PARAM_PROPERTY_PREFIX='ajs_prop_';const QUERY_PARAM_ANONYMOUS_ID_KEY='ajs_aid';const QUERY_PARAM_USER_ID_KEY='ajs_uid';const QUERY_PARAM_TRACK_EVENT_NAME_KEY='ajs_event';
|
421
421
|
|
@@ -559,9 +559,9 @@ const DEFAULT_ERROR_REPORTING_PROVIDER='bugsnag';const DEFAULT_STORAGE_ENCRYPTIO
|
|
559
559
|
|
560
560
|
const defaultLoadOptions={logLevel:'ERROR',configUrl:DEFAULT_CONFIG_BE_URL,loadIntegration:true,sessions:{autoTrack:true,timeout:DEFAULT_SESSION_TIMEOUT_MS},sameSiteCookie:'Lax',polyfillIfRequired:true,integrations:{All:true},useBeacon:false,beaconQueueOptions:{},destinationsQueueOptions:{},queueOptions:{},lockIntegrationsVersion:false,uaChTrackLevel:'none',plugins:[],useGlobalIntegrationsConfigInEvents:false,bufferDataPlaneEventsUntilReady:false,dataPlaneEventsBufferTimeout:DEFAULT_DATA_PLANE_EVENTS_BUFFER_TIMEOUT_MS,storage:{encryption:{version:DEFAULT_STORAGE_ENCRYPTION_VERSION},migrate:false},sendAdblockPageOptions:{}};const loadOptionsState=a(clone$1(defaultLoadOptions));
|
561
561
|
|
562
|
-
const userSessionStorageKeys={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'};const defaultUserSessionValues={userId:'',userTraits:{},anonymousId:'',groupId:'',groupTraits:{},initialReferrer:'',initialReferringDomain:'',sessionInfo:{}};
|
562
|
+
const userSessionStorageKeys={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 defaultUserSessionValues={userId:'',userTraits:{},anonymousId:'',groupId:'',groupTraits:{},initialReferrer:'',initialReferringDomain:'',sessionInfo:{},authToken:null};
|
563
563
|
|
564
|
-
const defaultSessionInfo={autoTrack:true,timeout:DEFAULT_SESSION_TIMEOUT_MS};const sessionState={userId:a(defaultUserSessionValues.userId),userTraits:a(defaultUserSessionValues.userTraits),anonymousId:a(defaultUserSessionValues.anonymousId),groupId:a(defaultUserSessionValues.groupId),groupTraits:a(defaultUserSessionValues.groupTraits),initialReferrer:a(defaultUserSessionValues.initialReferrer),initialReferringDomain:a(defaultUserSessionValues.initialReferringDomain),sessionInfo:a(defaultUserSessionValues.sessionInfo)};
|
564
|
+
const defaultSessionInfo={autoTrack:true,timeout:DEFAULT_SESSION_TIMEOUT_MS};const sessionState={userId:a(defaultUserSessionValues.userId),userTraits:a(defaultUserSessionValues.userTraits),anonymousId:a(defaultUserSessionValues.anonymousId),groupId:a(defaultUserSessionValues.groupId),groupTraits:a(defaultUserSessionValues.groupTraits),initialReferrer:a(defaultUserSessionValues.initialReferrer),initialReferringDomain:a(defaultUserSessionValues.initialReferringDomain),sessionInfo:a(defaultUserSessionValues.sessionInfo),authToken:a(defaultUserSessionValues.authToken)};
|
565
565
|
|
566
566
|
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)};
|
567
567
|
|
@@ -671,7 +671,7 @@ const EVENT_PAYLOAD_SIZE_CHECK_FAIL_WARNING=(context,payloadSize,sizeLimit)=>`${
|
|
671
671
|
* @param event RudderEvent object
|
672
672
|
* @param logger Logger instance
|
673
673
|
* @returns stringified event payload. Empty string if error occurs.
|
674
|
-
*/const getDeliveryPayload=(event,logger)=>stringifyWithoutCircular(event,true,undefined,logger);/**
|
674
|
+
*/const getDeliveryPayload=(event,logger)=>stringifyWithoutCircular(event,true,undefined,logger);const getDMTDeliveryPayload=(dmtRequestPayload,logger)=>stringifyWithoutCircular(dmtRequestPayload,true,undefined,logger);/**
|
675
675
|
* Utility to validate final payload size before sending to server
|
676
676
|
* @param event RudderEvent object
|
677
677
|
* @param logger Logger instance
|
@@ -692,7 +692,7 @@ const BEACON_PLUGIN_EVENTS_QUEUE_DEBUG=context=>`${context}${LOG_CONTEXT_SEPARAT
|
|
692
692
|
const DEFAULT_BEACON_QUEUE_MAX_SIZE=10;const DEFAULT_BEACON_QUEUE_FLUSH_INTERVAL_MS=10*60*1000;// 10 minutes
|
693
693
|
// Limit of the Beacon transfer mechanism on the browsers
|
694
694
|
const MAX_BATCH_PAYLOAD_SIZE_BYTES=64*1024;// 64 KB
|
695
|
-
const DEFAULT_BEACON_QUEUE_OPTIONS={maxItems:DEFAULT_BEACON_QUEUE_MAX_SIZE,flushQueueInterval:DEFAULT_BEACON_QUEUE_FLUSH_INTERVAL_MS};const DATA_PLANE_API_VERSION$1='v1';const QUEUE_NAME$
|
695
|
+
const DEFAULT_BEACON_QUEUE_OPTIONS={maxItems:DEFAULT_BEACON_QUEUE_MAX_SIZE,flushQueueInterval:DEFAULT_BEACON_QUEUE_FLUSH_INTERVAL_MS};const DATA_PLANE_API_VERSION$1='v1';const QUEUE_NAME$3='rudder_beacon';const BEACON_QUEUE_PLUGIN='BeaconQueuePlugin';
|
696
696
|
|
697
697
|
/**
|
698
698
|
* Utility to get the stringified event payload as Blob
|
@@ -803,7 +803,7 @@ const pluginName$d='BeaconQueue';const BeaconQueue=()=>({name:pluginName$d,deps:
|
|
803
803
|
* @returns BeaconItemsQueue instance
|
804
804
|
*/init(state,httpClient,storeManager,errorHandler,logger){const writeKey=state.lifecycle.writeKey.value;const dataplaneUrl=state.lifecycle.activeDataplaneUrl.value;const url=getDeliveryUrl$1(dataplaneUrl,writeKey);const finalQOpts=getNormalizedBeaconQueueOptions(state.loadOptions.value.beaconQueueOptions??{});const queueProcessCallback=(itemData,done)=>{logger?.debug(BEACON_PLUGIN_EVENTS_QUEUE_DEBUG(BEACON_QUEUE_PLUGIN));const finalEvents=itemData.map(queueItemData=>getFinalEventForDeliveryMutator(queueItemData.event));const data=getBatchDeliveryPayload$1(finalEvents,logger);if(data){try{const isEnqueuedInBeacon=navigator.sendBeacon(url,data);if(!isEnqueuedInBeacon){logger?.error(BEACON_QUEUE_SEND_ERROR(BEACON_QUEUE_PLUGIN));}done(null,isEnqueuedInBeacon);}catch(err){errorHandler?.onError(err,BEACON_QUEUE_PLUGIN,BEACON_QUEUE_DELIVERY_ERROR(url));// Remove the item from queue
|
805
805
|
done(null);}}else {// Mark the item as done so that it can be removed from the queue
|
806
|
-
done(null);}};const eventsQueue=new RetryQueue(`${QUEUE_NAME$
|
806
|
+
done(null);}};const eventsQueue=new RetryQueue(`${QUEUE_NAME$3}_${writeKey}`,{batch:{enabled:true,flushInterval:finalQOpts.flushQueueInterval,maxSize:MAX_BATCH_PAYLOAD_SIZE_BYTES,// set the hard limit
|
807
807
|
maxItems:finalQOpts.maxItems}},queueProcessCallback,storeManager,LOCAL_STORAGE,logger,itemData=>{const events=itemData.map(queueItemData=>queueItemData.event);// type casting to Blob as we know that the event has already been validated prior to enqueue
|
808
808
|
return getBatchDeliveryPayload$1(events,logger).size;});return eventsQueue;},/**
|
809
809
|
* Add event to the queue for delivery
|
@@ -844,7 +844,7 @@ event.context='Script load failures';}// eslint-disable-next-line no-param-reass
|
|
844
844
|
event.severity='error';};const onError=state=>{const metadataSource=state.source.value?.id;return event=>{try{// Discard the event if it's not originated at the SDK
|
845
845
|
if(!isRudderSDKError(event)){return false;}enhanceErrorEventMutator(event,metadataSource);return true;}catch{// Drop the error event if it couldn't be filtered as
|
846
846
|
// it is most likely a non-SDK error
|
847
|
-
return false;}};};const getReleaseStage=()=>{const host=globalThis.location.hostname;return host&&DEV_HOSTS.includes(host)?'development':'production';};const getGlobalBugsnagLibInstance=()=>globalThis[BUGSNAG_LIB_INSTANCE_GLOBAL_KEY_NAME];const getNewClient=(state,logger)=>{const globalBugsnagLibInstance=getGlobalBugsnagLibInstance();const clientConfig={apiKey:API_KEY,appVersion:'3.0.0-beta.
|
847
|
+
return false;}};};const getReleaseStage=()=>{const host=globalThis.location.hostname;return host&&DEV_HOSTS.includes(host)?'development':'production';};const getGlobalBugsnagLibInstance=()=>globalThis[BUGSNAG_LIB_INSTANCE_GLOBAL_KEY_NAME];const getNewClient=(state,logger)=>{const globalBugsnagLibInstance=getGlobalBugsnagLibInstance();const clientConfig={apiKey:API_KEY,appVersion:'3.0.0-beta.13',// Set SDK version as the app version from build config
|
848
848
|
metaData:{SDK:{name:'JS',installType:'npm'}},beforeSend:onError(state),autoCaptureSessions:false,// auto capture sessions is disabled
|
849
849
|
collectUserIp:false,// collecting user's IP is disabled
|
850
850
|
// enabledBreadcrumbTypes: ['error', 'log', 'user'], // for v7 and above
|
@@ -1044,9 +1044,21 @@ const destinationsToLoad=filterDestinations(state.nativeDestinations.loadOnlyInt
|
|
1044
1044
|
pluginsManager.invokeSingle(`consentManager.isDestinationConsented`,state,dest.config,errorHandler,logger)??true);state.nativeDestinations.activeDestinations.value=consentedDestinations;},load(state,externalSrcLoader,errorHandler,logger,externalScriptOnLoad){const integrationsCDNPath=state.lifecycle.integrationsCDNPath.value;const activeDestinations=state.nativeDestinations.activeDestinations.value;activeDestinations.forEach(dest=>{const sdkName=destDisplayNamesToFileNamesMap[dest.displayName];const destSDKIdentifier=`${sdkName}_RS`;// this is the name of the object loaded on the window
|
1045
1045
|
const sdkTypeName=sdkName;if(!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 {initializeDestination(dest,state,destSDKIdentifier,sdkTypeName,errorHandler,logger);}});}}});
|
1046
1046
|
|
1047
|
-
|
1048
|
-
|
1049
|
-
|
1047
|
+
const DEFAULT_TRANSFORMATION_QUEUE_OPTIONS={minRetryDelay:500,backoffFactor:2,maxAttempts:3};const REQUEST_TIMEOUT_MS$1=10*1000;// 10 seconds
|
1048
|
+
const QUEUE_NAME$2='rudder';const DMT_PLUGIN='DeviceModeTransformationPlugin';
|
1049
|
+
|
1050
|
+
const DMT_TRANSFORMATION_UNSUCCESSFUL_ERROR=(context,displayName,reason,action)=>`${context}${LOG_CONTEXT_SEPARATOR}Event transformation unsuccessful for destination "${displayName}". Reason: ${reason}. ${action}.`;const DMT_REQUEST_FAILED_ERROR=(context,displayName,status,action)=>`${context}${LOG_CONTEXT_SEPARATOR}[Destination: ${displayName}].Transformation request failed with status: ${status}. Retries exhausted. ${action}.`;const DMT_EXCEPTION=displayName=>`[Destination:${displayName}].`;const DMT_SERVER_ACCESS_DENIED_WARNING=context=>`${context}${LOG_CONTEXT_SEPARATOR}Transformation server access is denied. The configuration data seems to be out of sync. Sending untransformed event to the destination.`;
|
1051
|
+
|
1052
|
+
/**
|
1053
|
+
* A helper function that will take rudderEvent and generate
|
1054
|
+
* a batch payload that will be sent to transformation server
|
1055
|
+
*
|
1056
|
+
*/const createPayload=(event,destinationIds,token)=>{const orderNo=Date.now();const payload={metadata:{'Custom-Authorization':token},batch:[{orderNo,destinationIds,event}]};return payload;};const sendTransformedEventToDestinations=(state,pluginsManager,destinationIds,result,status,event,errorHandler,logger)=>{const NATIVE_DEST_EXT_POINT='destinationsEventsQueue.enqueueEventToDestination';const ACTION_TO_SEND_UNTRANSFORMED_EVENT='Sending untransformed event';const ACTION_TO_DROP_EVENT='Dropping the event';const destinations=state.nativeDestinations.initializedDestinations.value.filter(d=>d&&destinationIds.includes(d.id));destinations.forEach(dest=>{try{const eventsToSend=[];switch(status){case 200:{const response=JSON.parse(result);const destTransformedResult=response.transformedBatch.find(e=>e.id===dest.id);destTransformedResult?.payload.forEach(tEvent=>{if(tEvent.status==='200'){eventsToSend.push(tEvent.event);}else {let reason='Unknown';if(tEvent.status==='410'){reason='Transformation is not available';}let action=ACTION_TO_DROP_EVENT;if(dest.propagateEventsUntransformedOnError===true){action=ACTION_TO_SEND_UNTRANSFORMED_EVENT;eventsToSend.push(event);logger?.warn(DMT_TRANSFORMATION_UNSUCCESSFUL_ERROR(DMT_PLUGIN,dest.displayName,reason,action));}else {logger?.error(DMT_TRANSFORMATION_UNSUCCESSFUL_ERROR(DMT_PLUGIN,dest.displayName,reason,action));}}});break;}// Transformation server access denied
|
1057
|
+
case 404:{logger?.warn(DMT_SERVER_ACCESS_DENIED_WARNING(DMT_PLUGIN));eventsToSend.push(event);break;}default:{if(dest.propagateEventsUntransformedOnError===true){logger?.warn(DMT_REQUEST_FAILED_ERROR(DMT_PLUGIN,dest.displayName,status,ACTION_TO_SEND_UNTRANSFORMED_EVENT));eventsToSend.push(event);}else {logger?.error(DMT_REQUEST_FAILED_ERROR(DMT_PLUGIN,dest.displayName,status,ACTION_TO_DROP_EVENT));}break;}}eventsToSend?.forEach(tEvent=>{if(isNonEmptyObject(tEvent)){pluginsManager.invokeSingle(NATIVE_DEST_EXT_POINT,state,tEvent,dest,errorHandler,logger);}});}catch(e){errorHandler?.onError(e,DMT_PLUGIN,DMT_EXCEPTION(dest.displayName));}});};
|
1058
|
+
|
1059
|
+
const pluginName$a='DeviceModeTransformation';const DeviceModeTransformation=()=>({name:pluginName$a,deps:[],initialize:state=>{state.plugins.loadedPlugins.value=[...state.plugins.loadedPlugins.value,pluginName$a];},transformEvent:{init(state,pluginsManager,httpClient,storeManager,errorHandler,logger){const writeKey=state.lifecycle.writeKey.value;httpClient.setAuthHeader(writeKey);const eventsQueue=new RetryQueue(// adding write key to the queue name to avoid conflicts
|
1060
|
+
`${QUEUE_NAME$2}_${writeKey}`,DEFAULT_TRANSFORMATION_QUEUE_OPTIONS,(item,done,attemptNumber,maxRetryAttempts)=>{const payload=createPayload(item.event,item.destinationIds,item.token);httpClient.getAsyncData({url:`${state.lifecycle.dataPlaneUrl.value}/transform`,options:{method:'POST',data:getDMTDeliveryPayload(payload),sendRawData:true},isRawResponse:true,timeout:REQUEST_TIMEOUT_MS$1,callback:(result,details)=>{// null means item will not be requeued
|
1061
|
+
const queueErrResp=isErrRetryable(details)?details:null;if(!queueErrResp||attemptNumber===maxRetryAttempts){sendTransformedEventToDestinations(state,pluginsManager,item.destinationIds,result,details?.xhr?.status,item.event,errorHandler,logger);}done(queueErrResp,result);}});},storeManager,MEMORY_STORAGE);return eventsQueue;},enqueue(state,eventsQueue,event,destinations){const destinationIds=destinations.map(d=>d.id);eventsQueue.addItem({event,destinationIds,token:state.session.authToken.value});}}});
|
1050
1062
|
|
1051
1063
|
const INVALID_SOURCE_CONFIG_ERROR=`Invalid source configuration or source id.`;
|
1052
1064
|
|
@@ -1198,8 +1210,9 @@ const pluginName$5='NativeDestinationQueue';const NativeDestinationQueue=()=>({n
|
|
1198
1210
|
* @param errorHandler Error handler instance
|
1199
1211
|
* @param logger Logger instance
|
1200
1212
|
* @returns IQueue instance
|
1201
|
-
*/init(state,pluginsManager,storeManager,errorHandler,logger){const finalQOpts=getNormalizedQueueOptions$1(state.loadOptions.value.destinationsQueueOptions);const writeKey=state.lifecycle.writeKey.value;const eventsQueue=new RetryQueue(// adding write key to the queue name to avoid conflicts
|
1202
|
-
`${QUEUE_NAME$1}_${writeKey}`,finalQOpts,(rudderEvent,done)=>{const destinationsToSend=filterDestinations(rudderEvent.integrations,state.nativeDestinations.initializedDestinations.value)
|
1213
|
+
*/init(state,pluginsManager,storeManager,dmtQueue,errorHandler,logger){const finalQOpts=getNormalizedQueueOptions$1(state.loadOptions.value.destinationsQueueOptions);const writeKey=state.lifecycle.writeKey.value;const eventsQueue=new RetryQueue(// adding write key to the queue name to avoid conflicts
|
1214
|
+
`${QUEUE_NAME$1}_${writeKey}`,finalQOpts,(rudderEvent,done)=>{const destinationsToSend=filterDestinations(rudderEvent.integrations,state.nativeDestinations.initializedDestinations.value);// list of destinations which are enable for DMT
|
1215
|
+
const destWithTransformationEnabled=[];const clonedRudderEvent=clone$1(rudderEvent);destinationsToSend.forEach(dest=>{const sendEvent=!isEventDenyListed(clonedRudderEvent.type,clonedRudderEvent.event,dest);if(!sendEvent){logger?.warn(DESTINATION_EVENT_FILTERING_WARNING(NATIVE_DESTINATION_QUEUE_PLUGIN,clonedRudderEvent.event,dest.userFriendlyId));return;}if(dest.shouldApplyDeviceModeTransformation){destWithTransformationEnabled.push(dest);}else {sendEventToDestination(clonedRudderEvent,dest,errorHandler);}});if(destWithTransformationEnabled.length>0){pluginsManager.invokeSingle('transformEvent.enqueue',state,dmtQueue,clonedRudderEvent,destWithTransformationEnabled,errorHandler,logger);}// Mark success always
|
1203
1216
|
done(null);},storeManager,MEMORY_STORAGE);// TODO: This seems to not work as expected. Need to investigate
|
1204
1217
|
// effect(() => {
|
1205
1218
|
// if (state.nativeDestinations.clientDestinationsReady.value === true) {
|
@@ -2227,7 +2240,7 @@ const DATA_PLANE_API_VERSION='v1';const QUEUE_NAME='rudder';const XHR_QUEUE_PLUG
|
|
2227
2240
|
|
2228
2241
|
const EVENT_DELIVERY_FAILURE_ERROR_PREFIX=(context,url)=>`${context}${LOG_CONTEXT_SEPARATOR}Failed to deliver event(s) to ${url}.`;
|
2229
2242
|
|
2230
|
-
const getBatchDeliveryPayload=(events,logger)=>
|
2243
|
+
const getBatchDeliveryPayload=(events,logger)=>{const batchPayload={batch:events};return stringifyWithoutCircular(batchPayload,true,undefined,logger);};const getNormalizedQueueOptions=queueOpts=>mergeDeepRight(DEFAULT_RETRY_QUEUE_OPTIONS,queueOpts);const getDeliveryUrl=(dataplaneUrl,endpoint)=>{const dpUrl=new URL(dataplaneUrl);return new URL(removeDuplicateSlashes([dpUrl.pathname,'/',DATA_PLANE_API_VERSION,'/',endpoint].join('')),dpUrl).href;};const getBatchDeliveryUrl=dataplaneUrl=>getDeliveryUrl(dataplaneUrl,'batch');const logErrorOnFailure=(details,url,willBeRetried,attemptNumber,maxRetryAttempts,logger)=>{if(isUndefined(details?.error)||isUndefined(logger)){return;}const isRetryableFailure=isErrRetryable(details);let errMsg=EVENT_DELIVERY_FAILURE_ERROR_PREFIX(XHR_QUEUE_PLUGIN,url);const dropMsg=`The event(s) will be dropped.`;if(isRetryableFailure){if(willBeRetried){errMsg=`${errMsg} It/they will be retried.`;if(attemptNumber>0){errMsg=`${errMsg} Retry attempt ${attemptNumber} of ${maxRetryAttempts}.`;}}else {errMsg=`${errMsg} Retries exhausted (${maxRetryAttempts}). ${dropMsg}`;}}else {errMsg=`${errMsg} ${dropMsg}`;}logger?.error(errMsg);};const getRequestInfo=(itemData,state,logger)=>{let data;let headers;let url;if(Array.isArray(itemData)){const finalEvents=itemData.map(queueItemData=>getFinalEventForDeliveryMutator(queueItemData.event));data=getBatchDeliveryPayload(finalEvents,logger);headers=clone$1(itemData[0].headers);url=getBatchDeliveryUrl(state.lifecycle.activeDataplaneUrl.value);}else {const{url:eventUrl,event,headers:eventHeaders}=itemData;const finalEvent=getFinalEventForDeliveryMutator(event);data=getDeliveryPayload(finalEvent,logger);headers=clone$1(eventHeaders);url=eventUrl;}return {data,headers,url};};
|
2231
2244
|
|
2232
2245
|
const pluginName='XhrQueue';const XhrQueue=()=>({name:pluginName,deps:[],initialize:state=>{state.plugins.loadedPlugins.value=[...state.plugins.loadedPlugins.value,pluginName];},dataplaneEventsQueue:{/**
|
2233
2246
|
* Initialize the queue for delivery
|
@@ -2338,9 +2351,9 @@ xhr.timeout=timeout;Object.keys(options.headers).forEach(headerName=>{if(options
|
|
2338
2351
|
* Clear basic authentication header
|
2339
2352
|
*/resetAuthHeader(){this.basicAuthHeader=undefined;}}const defaultHttpClient=new HttpClient(defaultErrorHandler,defaultLogger);
|
2340
2353
|
|
2341
|
-
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';
|
2354
|
+
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';
|
2342
2355
|
|
2343
|
-
const storageClientDataStoreNameMap={[COOKIE_STORAGE]:CLIENT_DATA_STORE_COOKIE,[LOCAL_STORAGE]:CLIENT_DATA_STORE_LS,[MEMORY_STORAGE]:CLIENT_DATA_STORE_MEMORY};
|
2356
|
+
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};
|
2344
2357
|
|
2345
2358
|
const detectAdBlockers=(errorHandler,logger)=>{// Apparently, '?view=ad' is a query param that is blocked by majority of adblockers
|
2346
2359
|
// Use source config URL here as it is very unlikely to be blocked by adblockers
|
@@ -2356,7 +2369,7 @@ const hasCrypto=()=>!isNullOrUndefined(globalThis.crypto)&&isFunction(globalThis
|
|
2356
2369
|
|
2357
2370
|
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();});}};
|
2358
2371
|
|
2359
|
-
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!==
|
2372
|
+
const isDatasetAvailable=()=>{const testElement=document.createElement('div');testElement.setAttribute('data-a-b','c');return testElement.dataset?testElement.dataset.aB==='c':false;};const legacyJSEngineRequiredPolyfills={URLSearchParams:()=>!globalThis.URLSearchParams,URL:()=>!isFunction(globalThis.URL),MutationObserver:()=>isUndefined(MutationObserver),Promise:()=>isUndefined(Promise),'Number.isNaN':()=>!Number.isNaN,'Number.isInteger':()=>!Number.isInteger,'Array.from':()=>!Array.from,'Array.prototype.find':()=>!Array.prototype.find,'Array.prototype.includes':()=>!Array.prototype.includes,'String.prototype.endsWith':()=>!String.prototype.endsWith,'String.prototype.startsWith':()=>!String.prototype.startsWith,'String.prototype.includes':()=>!String.prototype.includes,'Object.entries':()=>!Object.entries,'Object.values':()=>!Object.values,'Object.assign':()=>typeof Object.assign!=='function','Element.prototype.dataset':()=>!isDatasetAvailable(),'String.prototype.replaceAll':()=>!String.prototype.replaceAll,TextEncoder:()=>isUndefined(TextEncoder),TextDecoder:()=>isUndefined(TextDecoder),'String.fromCodePoint':()=>!String.fromCodePoint,requestAnimationFrame:()=>!isFunction(globalThis.requestAnimationFrame),cancelAnimationFrame:()=>!isFunction(globalThis.cancelAnimationFrame),CustomEvent:()=>!isFunction(globalThis.CustomEvent)};const isLegacyJSEngine=()=>{const requiredCapabilitiesList=Object.keys(legacyJSEngineRequiredPolyfills);let needsPolyfill=false;/* eslint-disable-next-line unicorn/no-for-loop */for(let i=0;i<requiredCapabilitiesList.length;i++){const isCapabilityMissing=legacyJSEngineRequiredPolyfills[requiredCapabilitiesList[i]];if(isCapabilityMissing()){needsPolyfill=true;break;}}return needsPolyfill;};
|
2360
2373
|
|
2361
2374
|
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;};
|
2362
2375
|
|
@@ -2409,7 +2422,7 @@ cookie(cname,1,opts);// If successful
|
|
2409
2422
|
if(cookie(cname)){// Remove cookie from domain
|
2410
2423
|
cookie(cname,null,opts);return domain;}}return '';};
|
2411
2424
|
|
2412
|
-
const getDefaultCookieOptions=()=>{const topDomain=domain(globalThis.location.href);return {maxage:DEFAULT_COOKIE_MAX_AGE_MS,path:'/',domain:!topDomain||topDomain==='.'?undefined:topDomain,samesite:'Lax',enabled:true};};const getDefaultLocalStorageOptions=()=>({enabled:true});const getDefaultInMemoryStorageOptions=()=>({enabled:true});
|
2425
|
+
const getDefaultCookieOptions=()=>{const topDomain=domain(globalThis.location.href);return {maxage:DEFAULT_COOKIE_MAX_AGE_MS,path:'/',domain:!topDomain||topDomain==='.'?undefined:topDomain,samesite:'Lax',enabled:true};};const getDefaultLocalStorageOptions=()=>({enabled:true});const getDefaultSessionStorageOptions=()=>({enabled:true});const getDefaultInMemoryStorageOptions=()=>({enabled:true});
|
2413
2426
|
|
2414
2427
|
/**
|
2415
2428
|
* A storage utility to persist values in cookies via Storage interface
|
@@ -2452,17 +2465,23 @@ if(key===undefined){var ret={};this.forEach(function(key,val){return ret[key]=va
|
|
2452
2465
|
getItem(key){const value=store.get(key);return isUndefined(value)?null:value;}removeItem(key){store.remove(key);this.length=store.keys().length;}clear(){store.clear();this.length=0;}// eslint-disable-next-line class-methods-use-this
|
2453
2466
|
key(index){return store.keys()[index];}}const defaultLocalStorage=new LocalStorage({},defaultLogger);
|
2454
2467
|
|
2468
|
+
/**
|
2469
|
+
* A storage utility to persist values in SessionStorage via Storage interface
|
2470
|
+
*/class SessionStorage{isSupportAvailable=true;isEnabled=true;length=0;store=globalThis.sessionStorage;constructor(options={},logger){this.options=getDefaultSessionStorageOptions();this.logger=logger;this.configure(options);}configure(options){this.options=mergeDeepRight(this.options,options);this.isSupportAvailable=isStorageAvailable(SESSION_STORAGE,this,this.logger);this.isEnabled=Boolean(this.options.enabled&&this.isSupportAvailable);return this.options;}setItem(key,value){this.store.setItem(key,value);this.length=this.store.length;}getItem(key){const value=this.store.getItem(key);return isUndefined(value)?null:value;}removeItem(key){this.store.removeItem(key);this.length=this.store.length;}clear(){this.store.clear();this.length=0;}key(index){return this.store.key(index);}}const defaultSessionStorage=new SessionStorage({},defaultLogger);
|
2471
|
+
|
2455
2472
|
/**
|
2456
2473
|
* A utility to retrieve the storage singleton instance by type
|
2457
|
-
*/const getStorageEngine=type=>{switch(type){case LOCAL_STORAGE:return defaultLocalStorage;case SESSION_STORAGE:return
|
2474
|
+
*/const getStorageEngine=type=>{switch(type){case LOCAL_STORAGE:return defaultLocalStorage;case SESSION_STORAGE:return defaultSessionStorage;case MEMORY_STORAGE:return defaultInMemoryStorage;case COOKIE_STORAGE:return new CookieStorage({},defaultLogger);default:return defaultInMemoryStorage;}};/**
|
2458
2475
|
* Configure cookie storage singleton
|
2459
2476
|
*/const configureCookieStorageEngine=options=>{new CookieStorage({},defaultLogger).configure(options);};/**
|
2460
2477
|
* Configure local storage singleton
|
2461
2478
|
*/const configureLocalStorageEngine=options=>{defaultLocalStorage.configure(options);};/**
|
2462
2479
|
* Configure in memory storage singleton
|
2463
2480
|
*/const configureInMemoryStorageEngine=options=>{defaultInMemoryStorage.configure(options);};/**
|
2481
|
+
* Configure session storage singleton
|
2482
|
+
*/const configureSessionStorageEngine=options=>{defaultSessionStorage.configure(options);};/**
|
2464
2483
|
* Configure all storage singleton instances
|
2465
|
-
*/const configureStorageEngines=(cookieOptions={},localStorageOptions={},inMemoryStorageOptions={})=>{configureCookieStorageEngine(cookieOptions);configureLocalStorageEngine(localStorageOptions);configureInMemoryStorageEngine(inMemoryStorageOptions);};
|
2484
|
+
*/const configureStorageEngines=(cookieOptions={},localStorageOptions={},inMemoryStorageOptions={},sessionStorageOptions={})=>{configureCookieStorageEngine(cookieOptions);configureLocalStorageEngine(localStorageOptions);configureInMemoryStorageEngine(inMemoryStorageOptions);configureSessionStorageEngine(sessionStorageOptions);};
|
2466
2485
|
|
2467
2486
|
/**
|
2468
2487
|
* Store Implementation with dedicated storage
|
@@ -2502,14 +2521,14 @@ return JSON.parse(str);}catch(err){this.onError(new Error(`${STORE_DATA_FETCH_ER
|
|
2502
2521
|
* A service to manage stores & available storage client configurations
|
2503
2522
|
*/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);}/**
|
2504
2523
|
* Configure available storage client instances
|
2505
|
-
*/init(){if(this.isInitialized){return;}const config={cookieOptions:{samesite:state.loadOptions.value.sameSiteCookie,secure:state.loadOptions.value.secureCookie,domain:state.loadOptions.value.setCookieDomain,enabled:true},localStorageOptions:{enabled:true},inMemoryStorageOptions:{enabled:true}};configureStorageEngines(removeUndefinedValues(mergeDeepRight(config.cookieOptions||{},state.storage.cookie?.value||{})),removeUndefinedValues(config.localStorageOptions),removeUndefinedValues(config.inMemoryStorageOptions));this.initClientDataStore();this.isInitialized=true;}/**
|
2524
|
+
*/init(){if(this.isInitialized){return;}const config={cookieOptions:{samesite:state.loadOptions.value.sameSiteCookie,secure:state.loadOptions.value.secureCookie,domain:state.loadOptions.value.setCookieDomain,enabled:true},localStorageOptions:{enabled:true},inMemoryStorageOptions:{enabled:true},sessionStorageOptions:{enabled:true}};configureStorageEngines(removeUndefinedValues(mergeDeepRight(config.cookieOptions||{},state.storage.cookie?.value||{})),removeUndefinedValues(config.localStorageOptions),removeUndefinedValues(config.inMemoryStorageOptions),removeUndefinedValues(config.sessionStorageOptions));this.initClientDataStore();this.isInitialized=true;}/**
|
2506
2525
|
* Create store to persist data used by the SDK like session, used details etc
|
2507
|
-
*/initClientDataStore(){const globalStorageType=state.storage.type.value;let trulyAnonymousTracking=true;const entries=state.loadOptions.value.storage?.entries;const userSessionKeyValues=['userId','userTraits','anonymousId','groupId','groupTraits','initialReferrer','initialReferringDomain','sessionInfo'];userSessionKeyValues.forEach(sessionKey=>{const key=sessionKey;const storageKey=sessionKey;const providedStorageType=entries?.[key]?.type;const storageType=providedStorageType||globalStorageType||DEFAULT_STORAGE_TYPE;let finalStorageType=storageType;switch(storageType){case LOCAL_STORAGE:if(!getStorageEngine(LOCAL_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
|
2508
|
-
if(getStorageEngine(COOKIE_STORAGE)?.isEnabled){finalStorageType=COOKIE_STORAGE;}else if(getStorageEngine(LOCAL_STORAGE)?.isEnabled){finalStorageType=LOCAL_STORAGE;}else {finalStorageType=MEMORY_STORAGE;}break;}if(finalStorageType!==storageType){this.logger?.warn(STORAGE_UNAVAILABLE_WARNING(STORE_MANAGER,storageType,finalStorageType));}if(finalStorageType!==NO_STORAGE){trulyAnonymousTracking=false;}const storageState=state.storage.entries.value;state.storage.entries.value={...storageState,[sessionKey]:{type:finalStorageType,key:userSessionStorageKeys[storageKey]}};});state.storage.trulyAnonymousTracking.value=trulyAnonymousTracking;// TODO: fill in extra config values and bring them in from StoreManagerOptions if needed
|
2526
|
+
*/initClientDataStore(){const globalStorageType=state.storage.type.value;let trulyAnonymousTracking=true;const entries=state.loadOptions.value.storage?.entries;const userSessionKeyValues=['userId','userTraits','anonymousId','groupId','groupTraits','initialReferrer','initialReferringDomain','sessionInfo'];userSessionKeyValues.forEach(sessionKey=>{const key=sessionKey;const storageKey=sessionKey;const providedStorageType=entries?.[key]?.type;const storageType=providedStorageType||globalStorageType||DEFAULT_STORAGE_TYPE;let finalStorageType=storageType;switch(storageType){case LOCAL_STORAGE:if(!getStorageEngine(LOCAL_STORAGE)?.isEnabled){finalStorageType=MEMORY_STORAGE;}break;case SESSION_STORAGE:if(!getStorageEngine(SESSION_STORAGE)?.isEnabled){finalStorageType=MEMORY_STORAGE;}break;case MEMORY_STORAGE:case NO_STORAGE:break;case COOKIE_STORAGE:default:// First try setting the storage to cookie else to local storage
|
2527
|
+
if(getStorageEngine(COOKIE_STORAGE)?.isEnabled){finalStorageType=COOKIE_STORAGE;}else if(getStorageEngine(LOCAL_STORAGE)?.isEnabled){finalStorageType=LOCAL_STORAGE;}else if(getStorageEngine(SESSION_STORAGE)?.isEnabled){finalStorageType=SESSION_STORAGE;}else {finalStorageType=MEMORY_STORAGE;}break;}if(finalStorageType!==storageType){this.logger?.warn(STORAGE_UNAVAILABLE_WARNING(STORE_MANAGER,storageType,finalStorageType));}if(finalStorageType!==NO_STORAGE){trulyAnonymousTracking=false;}const storageState=state.storage.entries.value;state.storage.entries.value={...storageState,[sessionKey]:{type:finalStorageType,key:userSessionStorageKeys[storageKey]}};});state.storage.trulyAnonymousTracking.value=trulyAnonymousTracking;// TODO: fill in extra config values and bring them in from StoreManagerOptions if needed
|
2509
2528
|
// TODO: should we pass the keys for all in order to validate or leave free as v1.1?
|
2510
2529
|
// Initializing all the enabled store because previous user data might be in different storage
|
2511
2530
|
// that needs auto migration
|
2512
|
-
const storageTypesRequiringInitialization=[MEMORY_STORAGE];if(getStorageEngine(LOCAL_STORAGE)?.isEnabled){storageTypesRequiringInitialization.push(LOCAL_STORAGE);}if(getStorageEngine(COOKIE_STORAGE)?.isEnabled){storageTypesRequiringInitialization.push(COOKIE_STORAGE);}storageTypesRequiringInitialization.forEach(storageType=>{this.setStore({id:storageClientDataStoreNameMap[storageType],name:storageClientDataStoreNameMap[storageType],isEncrypted:true,noCompoundKey:true,type:storageType});});}/**
|
2531
|
+
const storageTypesRequiringInitialization=[MEMORY_STORAGE];if(getStorageEngine(LOCAL_STORAGE)?.isEnabled){storageTypesRequiringInitialization.push(LOCAL_STORAGE);}if(getStorageEngine(COOKIE_STORAGE)?.isEnabled){storageTypesRequiringInitialization.push(COOKIE_STORAGE);}if(getStorageEngine(SESSION_STORAGE)?.isEnabled){storageTypesRequiringInitialization.push(SESSION_STORAGE);}storageTypesRequiringInitialization.forEach(storageType=>{this.setStore({id:storageClientDataStoreNameMap[storageType],name:storageClientDataStoreNameMap[storageType],isEncrypted:true,noCompoundKey:true,type:storageType});});}/**
|
2513
2532
|
* Create a new store
|
2514
2533
|
*/setStore(storeConfig){const storageEngine=getStorageEngine(storeConfig.type);this.stores[storeConfig.id]=new Store(storeConfig,storageEngine,this.pluginsManager);return this.stores[storeConfig.id];}/**
|
2515
2534
|
* Retrieve a store
|
@@ -2547,7 +2566,7 @@ const validateWriteKey=writeKey=>{if(!isString(writeKey)||writeKey.trim().length
|
|
2547
2566
|
|
2548
2567
|
/**
|
2549
2568
|
* Plugins to be loaded in the plugins loadOption is not defined
|
2550
|
-
*/const defaultOptionalPluginsList=['BeaconQueue','Bugsnag','DeviceModeDestinations','ErrorReporting','ExternalAnonymousId','GoogleLinker','KetchConsentManager','NativeDestinationQueue','OneTrustConsentManager','StorageEncryption','StorageEncryptionLegacy','StorageMigrator','XhrQueue'];
|
2569
|
+
*/const defaultOptionalPluginsList=['BeaconQueue','Bugsnag','DeviceModeDestinations','DeviceModeTransformation','ErrorReporting','ExternalAnonymousId','GoogleLinker','KetchConsentManager','NativeDestinationQueue','OneTrustConsentManager','StorageEncryption','StorageEncryptionLegacy','StorageMigrator','XhrQueue'];
|
2551
2570
|
|
2552
2571
|
/**
|
2553
2572
|
* A function to check given value is a number or not
|
@@ -2676,7 +2695,7 @@ this.httpClient.getAsyncData({url:state.lifecycle.sourceConfigUrl.value,options:
|
|
2676
2695
|
/**
|
2677
2696
|
* Get the referrer URL
|
2678
2697
|
* @returns The referrer URL
|
2679
|
-
*/const getReferrer=()=>document
|
2698
|
+
*/const getReferrer=()=>document?.referrer||'$direct';/**
|
2680
2699
|
* To get the canonical URL of the page
|
2681
2700
|
* @returns canonical URL
|
2682
2701
|
*/const getCanonicalUrl=()=>{const tags=document.getElementsByTagName('link');let canonicalUrl='';for(let i=0;tags[i];i+=1){const tag=tags[i];if(tag.getAttribute('rel')==='canonical'&&!canonicalUrl){canonicalUrl=tag.getAttribute('href')??'';break;}}return canonicalUrl;};const getUserAgent=()=>{if(isUndefined(globalThis.navigator)){return null;}let{userAgent}=globalThis.navigator;const{brave}=globalThis.navigator;// For supporting Brave browser detection,
|
@@ -2855,14 +2874,14 @@ timeout,sessionStart:undefined,autoTrack:true};};/**
|
|
2855
2874
|
* @param id Provided sessionId
|
2856
2875
|
* @param logger Logger module
|
2857
2876
|
* @returns SessionInfo
|
2858
|
-
*/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===MEMORY_STORAGE);
|
2877
|
+
*/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);
|
2859
2878
|
|
2860
2879
|
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);}/**
|
2861
2880
|
* Initialize User session with values from storage
|
2862
2881
|
*/init(){this.migrateStorageIfNeeded();this.migrateDataFromPreviousStorage();// get the values from storage and set it again
|
2863
|
-
const userId=this.getUserId();const userTraits=this.getUserTraits();const groupId=this.getGroupId();const groupTraits=this.getGroupTraits();const anonymousId=this.getAnonymousId();if(userId){this.setUserId(userId);}if(userTraits){this.setUserTraits(userTraits);}if(groupId){this.setGroupId(groupId);}if(groupTraits){this.setGroupTraits(groupTraits);}if(anonymousId){this.setAnonymousId(anonymousId);}const initialReferrer=this.getInitialReferrer();const initialReferringDomain=this.getInitialReferringDomain();if(initialReferrer&&initialReferringDomain){this.setInitialReferrer(initialReferrer);this.setInitialReferringDomain(initialReferringDomain);}else if(initialReferrer){this.setInitialReferrer(initialReferrer);this.setInitialReferringDomain(getReferringDomain(initialReferrer));}else {const referrer=getReferrer();this.setInitialReferrer(referrer);this.setInitialReferringDomain(getReferringDomain(referrer));}// Initialize session tracking
|
2882
|
+
const userId=this.getUserId();const userTraits=this.getUserTraits();const groupId=this.getGroupId();const groupTraits=this.getGroupTraits();const anonymousId=this.getAnonymousId(state.loadOptions.value.anonymousIdOptions);if(userId){this.setUserId(userId);}if(userTraits){this.setUserTraits(userTraits);}if(groupId){this.setGroupId(groupId);}if(groupTraits){this.setGroupTraits(groupTraits);}if(anonymousId){this.setAnonymousId(anonymousId);}const authToken=this.getAuthToken();if(authToken){this.setAuthToken(authToken);}const initialReferrer=this.getInitialReferrer();const initialReferringDomain=this.getInitialReferringDomain();if(initialReferrer&&initialReferringDomain){this.setInitialReferrer(initialReferrer);this.setInitialReferringDomain(initialReferringDomain);}else if(initialReferrer){this.setInitialReferrer(initialReferrer);this.setInitialReferringDomain(getReferringDomain(initialReferrer));}else {const referrer=getReferrer();this.setInitialReferrer(referrer);this.setInitialReferringDomain(getReferringDomain(referrer));}// Initialize session tracking
|
2864
2883
|
if(this.isPersistenceEnabledForStorageEntry('sessionInfo')){this.initializeSessionTracking();}// Register the effect to sync with storage
|
2865
|
-
this.registerEffects();}isPersistenceEnabledForStorageEntry(entryName){const entries=state.storage.entries.value;return isStorageTypeValidForStoringData(entries[entryName]?.type);}migrateDataFromPreviousStorage(){const entries=state.storage.entries.value;Object.keys(entries).forEach(entry=>{const key=entry;const currentStorage=entries[key]?.type;const curStore=this.storeManager?.getStore(storageClientDataStoreNameMap[currentStorage]);const storages=[COOKIE_STORAGE,LOCAL_STORAGE];storages.forEach(storage=>{const store=this.storeManager?.getStore(storageClientDataStoreNameMap[storage]);if(storage!==currentStorage&&store){if(curStore){const value=store?.get(userSessionStorageKeys[key]);if(isDefinedNotNullAndNotEmptyString(value)){curStore?.set(userSessionStorageKeys[key],value);}}store?.remove(userSessionStorageKeys[key]);}});});}migrateStorageIfNeeded(){if(!state.storage.migrate.value){return;}const cookieStorage=this.storeManager?.getStore(CLIENT_DATA_STORE_COOKIE);const localStorage=this.storeManager?.getStore(CLIENT_DATA_STORE_LS);const stores=[];if(cookieStorage){stores.push(cookieStorage);}if(localStorage){stores.push(localStorage);}Object.keys(userSessionStorageKeys).forEach(storageEntryKey=>{const key=storageEntryKey;const storageEntry=userSessionStorageKeys[key];stores.forEach(store=>{const migratedVal=this.pluginsManager?.invokeSingle('storage.migrate',storageEntry,store.engine,this.errorHandler,this.logger);if(migratedVal){store.set(storageEntry,migratedVal);}});});}/**
|
2884
|
+
this.registerEffects();}isPersistenceEnabledForStorageEntry(entryName){const entries=state.storage.entries.value;return isStorageTypeValidForStoringData(entries[entryName]?.type);}migrateDataFromPreviousStorage(){const entries=state.storage.entries.value;Object.keys(entries).forEach(entry=>{const key=entry;const currentStorage=entries[key]?.type;const curStore=this.storeManager?.getStore(storageClientDataStoreNameMap[currentStorage]);const storages=[COOKIE_STORAGE,LOCAL_STORAGE,SESSION_STORAGE];storages.forEach(storage=>{const store=this.storeManager?.getStore(storageClientDataStoreNameMap[storage]);if(storage!==currentStorage&&store){if(curStore){const value=store?.get(userSessionStorageKeys[key]);if(isDefinedNotNullAndNotEmptyString(value)){curStore?.set(userSessionStorageKeys[key],value);}}store?.remove(userSessionStorageKeys[key]);}});});}migrateStorageIfNeeded(){if(!state.storage.migrate.value){return;}const cookieStorage=this.storeManager?.getStore(CLIENT_DATA_STORE_COOKIE);const localStorage=this.storeManager?.getStore(CLIENT_DATA_STORE_LS);const sessionStorage=this.storeManager?.getStore(CLIENT_DATA_STORE_SESSION);const stores=[];if(cookieStorage){stores.push(cookieStorage);}if(localStorage){stores.push(localStorage);}if(sessionStorage){stores.push(sessionStorage);}Object.keys(userSessionStorageKeys).forEach(storageEntryKey=>{const key=storageEntryKey;const storageEntry=userSessionStorageKeys[key];stores.forEach(store=>{const migratedVal=this.pluginsManager?.invokeSingle('storage.migrate',storageEntry,store.engine,this.errorHandler,this.logger);if(migratedVal){store.set(storageEntry,migratedVal);}});});}/**
|
2866
2885
|
* A function to initialize sessionTracking
|
2867
2886
|
*/initializeSessionTracking(){const sessionInfo=this.getSessionFromStorage()??defaultSessionInfo;let finalAutoTrackingStatus=!(state.loadOptions.value.sessions.autoTrack===false||sessionInfo.manualTrack===true);let sessionTimeout;const configuredSessionTimeout=state.loadOptions.value.sessions.timeout;if(!isPositiveInteger(configuredSessionTimeout)){this.logger?.warn(TIMEOUT_NOT_NUMBER_WARNING(USER_SESSION_MANAGER,configuredSessionTimeout,DEFAULT_SESSION_TIMEOUT_MS));sessionTimeout=DEFAULT_SESSION_TIMEOUT_MS;}else {sessionTimeout=configuredSessionTimeout;}if(sessionTimeout===0){this.logger?.warn(TIMEOUT_ZERO_WARNING(USER_SESSION_MANAGER));finalAutoTrackingStatus=false;}// In case user provides a timeout value greater than 0 but less than 10 seconds SDK will show a warning
|
2868
2887
|
// and will proceed with it
|
@@ -2892,14 +2911,16 @@ if(state.session.sessionInfo.value.autoTrack){this.startOrRenewAutoTracking();}}
|
|
2892
2911
|
* Update initial referring domain in storage automatically when it is updated in state
|
2893
2912
|
*/O(()=>{this.syncValueToStorage('initialReferringDomain',state.session.initialReferringDomain.value);});/**
|
2894
2913
|
* Update session tracking info in storage automatically when it is updated in state
|
2895
|
-
*/O(()=>{this.syncValueToStorage('sessionInfo',state.session.sessionInfo.value);})
|
2914
|
+
*/O(()=>{this.syncValueToStorage('sessionInfo',state.session.sessionInfo.value);});/**
|
2915
|
+
* Update session tracking info in storage automatically when it is updated in state
|
2916
|
+
*/O(()=>{this.syncValueToStorage('authToken',state.session.authToken.value);});}/**
|
2896
2917
|
* Sets anonymous id in the following precedence:
|
2897
2918
|
*
|
2898
2919
|
* 1. anonymousId: Id directly provided to the function.
|
2899
2920
|
* 2. rudderAmpLinkerParam: value generated from linker query parm (rudderstack)
|
2900
2921
|
* using parseLinker util.
|
2901
2922
|
* 3. generateUUID: A new unique id is generated and assigned.
|
2902
|
-
*/setAnonymousId(anonymousId,rudderAmpLinkerParam){let finalAnonymousId=anonymousId;
|
2923
|
+
*/setAnonymousId(anonymousId,rudderAmpLinkerParam){let finalAnonymousId=anonymousId;if(this.isPersistenceEnabledForStorageEntry('anonymousId')){if(!finalAnonymousId&&rudderAmpLinkerParam){const linkerPluginsResult=this.pluginsManager?.invokeMultiple('userSession.anonymousIdGoogleLinker',rudderAmpLinkerParam);finalAnonymousId=linkerPluginsResult?.[0];}state.session.anonymousId.value=finalAnonymousId||this.generateAnonymousId();}}/**
|
2903
2924
|
* Generate a new anonymousId
|
2904
2925
|
* @returns string anonymousID
|
2905
2926
|
*/generateAnonymousId(){return generateUUID();}/**
|
@@ -2930,6 +2951,9 @@ const autoCapturedAnonymousId=this.pluginsManager?.invokeSingle('storage.getAnon
|
|
2930
2951
|
* Fetches session tracking information from storage
|
2931
2952
|
* @returns
|
2932
2953
|
*/getSessionFromStorage(){return this.getItem('sessionInfo');}/**
|
2954
|
+
* Fetches auth token from storage
|
2955
|
+
* @returns
|
2956
|
+
*/getAuthToken(){return this.getItem('authToken');}/**
|
2933
2957
|
* If session is active it returns the sessionId
|
2934
2958
|
* @returns
|
2935
2959
|
*/getSessionId(){if(state.session.sessionInfo.value.autoTrack&&!hasSessionExpired(state.session.sessionInfo.value.expiresAt)||state.session.sessionInfo.value.manualTrack){return state.session.sessionInfo.value.id||null;}return null;}/**
|
@@ -2939,7 +2963,8 @@ const autoCapturedAnonymousId=this.pluginsManager?.invokeSingle('storage.getAnon
|
|
2939
2963
|
* @param resetAnonymousId
|
2940
2964
|
* @param noNewSessionStart
|
2941
2965
|
* @returns
|
2942
|
-
*/reset(resetAnonymousId,noNewSessionStart){const{manualTrack,autoTrack}=state.session.sessionInfo.value;n(()=>{state.session.userId.value=defaultUserSessionValues.userId;state.session.userTraits.value=defaultUserSessionValues.userTraits;state.session.groupId.value=defaultUserSessionValues.groupId;state.session.groupTraits.value=defaultUserSessionValues.groupTraits;
|
2966
|
+
*/reset(resetAnonymousId,noNewSessionStart){const{manualTrack,autoTrack}=state.session.sessionInfo.value;n(()=>{state.session.userId.value=defaultUserSessionValues.userId;state.session.userTraits.value=defaultUserSessionValues.userTraits;state.session.groupId.value=defaultUserSessionValues.groupId;state.session.groupTraits.value=defaultUserSessionValues.groupTraits;state.session.authToken.value=defaultUserSessionValues.authToken;if(resetAnonymousId){// This will generate a new anonymous ID
|
2967
|
+
this.setAnonymousId();}if(noNewSessionStart){return;}if(autoTrack){state.session.sessionInfo.value=defaultUserSessionValues.sessionInfo;this.startOrRenewAutoTracking();}else if(manualTrack){this.startManualTrackingInternal();}});}/**
|
2943
2968
|
* Set user Id
|
2944
2969
|
* @param userId
|
2945
2970
|
*/setUserId(userId){if(this.isPersistenceEnabledForStorageEntry('userId')){state.session.userId.value=userId;}}/**
|
@@ -2968,13 +2993,16 @@ const autoCapturedAnonymousId=this.pluginsManager?.invokeSingle('storage.getAnon
|
|
2968
2993
|
* An internal function to start manual session
|
2969
2994
|
*/startManualTrackingInternal(){this.start(Date.now());}/**
|
2970
2995
|
* A public method to end an ongoing session.
|
2971
|
-
*/end(){state.session.sessionInfo.value={};}
|
2996
|
+
*/end(){state.session.sessionInfo.value={};}/**
|
2997
|
+
* Set auth token
|
2998
|
+
* @param userId
|
2999
|
+
*/setAuthToken(token){if(this.isPersistenceEnabledForStorageEntry('authToken')){state.session.authToken.value=token;}}}
|
2972
3000
|
|
2973
3001
|
/**
|
2974
3002
|
* A buffer queue to serve as a store for any type of data
|
2975
3003
|
*/class BufferQueue{constructor(){this.items=[];}enqueue(item){this.items.push(item);}dequeue(){if(this.items.length===0){return null;}return this.items.shift();}isEmpty(){return this.items.length===0;}size(){return this.items.length;}clear(){this.items=[];}}
|
2976
3004
|
|
2977
|
-
const DATA_PLANE_QUEUE_EXT_POINT_PREFIX='dataplaneEventsQueue';const DESTINATIONS_QUEUE_EXT_POINT_PREFIX='destinationsEventsQueue';
|
3005
|
+
const DATA_PLANE_QUEUE_EXT_POINT_PREFIX='dataplaneEventsQueue';const DESTINATIONS_QUEUE_EXT_POINT_PREFIX='destinationsEventsQueue';const DMT_EXT_POINT_PREFIX='transformEvent';
|
2978
3006
|
|
2979
3007
|
/**
|
2980
3008
|
* Filters and returns the user supplied integrations config that should take preference over the destination specific integrations config
|
@@ -3000,8 +3028,8 @@ const eventIntgConfig=event.integrations??DEFAULT_INTEGRATIONS_CONFIG;const dest
|
|
3000
3028
|
* @param logger Logger object
|
3001
3029
|
*/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);}/**
|
3002
3030
|
* Initializes the event repository
|
3003
|
-
*/init(){this.dataplaneEventsQueue=this.pluginsManager.invokeSingle(`${DATA_PLANE_QUEUE_EXT_POINT_PREFIX}.init`,state,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.errorHandler,this.logger);// Start the queue once the client destinations are ready
|
3004
|
-
O(()=>{if(state.nativeDestinations.clientDestinationsReady.value===true){this.destinationsEventsQueue?.start();}});// Start the queue processing only when the destinations are ready or hybrid mode destinations exist
|
3031
|
+
*/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
|
3032
|
+
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
|
3005
3033
|
// However, events will be enqueued for now.
|
3006
3034
|
// At the time of processing the events, the integrations config data from destinations
|
3007
3035
|
// is merged into the event object
|
@@ -3095,7 +3123,7 @@ getUserId(){return state.session.userId.value;}// eslint-disable-next-line class
|
|
3095
3123
|
getUserTraits(){return state.session.userTraits.value;}// eslint-disable-next-line class-methods-use-this
|
3096
3124
|
getGroupId(){return state.session.groupId.value;}// eslint-disable-next-line class-methods-use-this
|
3097
3125
|
getGroupTraits(){return state.session.groupTraits.value;}startSession(sessionId){const type='startSession';this.errorHandler.leaveBreadcrumb(`New ${type} invocation`);if(!state.lifecycle.loaded.value){state.eventBuffer.toBeProcessedArray.value.push([type,sessionId]);return;}this.userSessionManager?.start(sessionId);}endSession(){const type='endSession';this.errorHandler.leaveBreadcrumb(`New ${type} invocation`);if(!state.lifecycle.loaded.value){state.eventBuffer.toBeProcessedArray.value.push([type]);return;}this.userSessionManager?.end();}// eslint-disable-next-line class-methods-use-this
|
3098
|
-
getSessionId(){const sessionId=this.userSessionManager?.getSessionId();return sessionId??null;}// End consumer exposed methods
|
3126
|
+
getSessionId(){const sessionId=this.userSessionManager?.getSessionId();return sessionId??null;}setAuthToken(token){this.userSessionManager?.setAuthToken(token);}// End consumer exposed methods
|
3099
3127
|
}
|
3100
3128
|
|
3101
3129
|
/*
|
@@ -3107,7 +3135,7 @@ getSessionId(){const sessionId=this.userSessionManager?.getSessionId();return se
|
|
3107
3135
|
constructor(){if(RudderAnalytics.globalSingleton){// START-NO-SONAR-SCAN
|
3108
3136
|
// eslint-disable-next-line no-constructor-return
|
3109
3137
|
return RudderAnalytics.globalSingleton;// END-NO-SONAR-SCAN
|
3110
|
-
}this.setDefaultInstanceKey=this.setDefaultInstanceKey.bind(this);this.getAnalyticsInstance=this.getAnalyticsInstance.bind(this);this.load=this.load.bind(this);this.ready=this.ready.bind(this);this.getPreloadBuffer=this.getPreloadBuffer.bind(this);this.triggerBufferedLoadEvent=this.triggerBufferedLoadEvent.bind(this);this.page=this.page.bind(this);this.track=this.track.bind(this);this.identify=this.identify.bind(this);this.alias=this.alias.bind(this);this.group=this.group.bind(this);this.reset=this.reset.bind(this);this.getAnonymousId=this.getAnonymousId.bind(this);this.setAnonymousId=this.setAnonymousId.bind(this);this.getUserId=this.getUserId.bind(this);this.getUserTraits=this.getUserTraits.bind(this);this.getGroupId=this.getGroupId.bind(this);this.getGroupTraits=this.getGroupTraits.bind(this);this.startSession=this.startSession.bind(this);this.endSession=this.endSession.bind(this);this.getSessionId=this.getSessionId.bind(this);RudderAnalytics.globalSingleton=this;// get the preloaded events before replacing global object
|
3138
|
+
}this.setDefaultInstanceKey=this.setDefaultInstanceKey.bind(this);this.getAnalyticsInstance=this.getAnalyticsInstance.bind(this);this.load=this.load.bind(this);this.ready=this.ready.bind(this);this.getPreloadBuffer=this.getPreloadBuffer.bind(this);this.triggerBufferedLoadEvent=this.triggerBufferedLoadEvent.bind(this);this.page=this.page.bind(this);this.track=this.track.bind(this);this.identify=this.identify.bind(this);this.alias=this.alias.bind(this);this.group=this.group.bind(this);this.reset=this.reset.bind(this);this.getAnonymousId=this.getAnonymousId.bind(this);this.setAnonymousId=this.setAnonymousId.bind(this);this.getUserId=this.getUserId.bind(this);this.getUserTraits=this.getUserTraits.bind(this);this.getGroupId=this.getGroupId.bind(this);this.getGroupTraits=this.getGroupTraits.bind(this);this.startSession=this.startSession.bind(this);this.endSession=this.endSession.bind(this);this.getSessionId=this.getSessionId.bind(this);this.setAuthToken=this.setAuthToken.bind(this);RudderAnalytics.globalSingleton=this;// get the preloaded events before replacing global object
|
3111
3139
|
this.getPreloadBuffer();// start loading if a load event was buffered or wait for explicit load call
|
3112
3140
|
this.triggerBufferedLoadEvent();}/**
|
3113
3141
|
* Set instance to use if no specific writeKey is provided in methods
|
@@ -3140,6 +3168,6 @@ this.load.apply(null,loadEvent);}}/**
|
|
3140
3168
|
* Process alias arguments and forward to page call
|
3141
3169
|
*/alias(to,from,options,callback){this.getAnalyticsInstance().alias(aliasArgumentsToCallOptions(to,from,options,callback));}/**
|
3142
3170
|
* Process group arguments and forward to page call
|
3143
|
-
*/group(groupId,traits,options,callback){if(arguments.length===0){this.logger.error(EMPTY_GROUP_CALL_ERROR(RS_APP));return;}this.getAnalyticsInstance().group(groupArgumentsToCallOptions(groupId,traits,options,callback));}reset(resetAnonymousId){this.getAnalyticsInstance().reset(resetAnonymousId);}getAnonymousId(options){return this.getAnalyticsInstance().getAnonymousId(options);}setAnonymousId(anonymousId,rudderAmpLinkerParam){this.getAnalyticsInstance().setAnonymousId(anonymousId,rudderAmpLinkerParam);}getUserId(){return this.getAnalyticsInstance().getUserId();}getUserTraits(){return this.getAnalyticsInstance().getUserTraits();}getGroupId(){return this.getAnalyticsInstance().getGroupId();}getGroupTraits(){return this.getAnalyticsInstance().getGroupTraits();}startSession(sessionId){return this.getAnalyticsInstance().startSession(sessionId);}endSession(){return this.getAnalyticsInstance().endSession();}getSessionId(){return this.getAnalyticsInstance().getSessionId();}}
|
3171
|
+
*/group(groupId,traits,options,callback){if(arguments.length===0){this.logger.error(EMPTY_GROUP_CALL_ERROR(RS_APP));return;}this.getAnalyticsInstance().group(groupArgumentsToCallOptions(groupId,traits,options,callback));}reset(resetAnonymousId){this.getAnalyticsInstance().reset(resetAnonymousId);}getAnonymousId(options){return this.getAnalyticsInstance().getAnonymousId(options);}setAnonymousId(anonymousId,rudderAmpLinkerParam){this.getAnalyticsInstance().setAnonymousId(anonymousId,rudderAmpLinkerParam);}getUserId(){return this.getAnalyticsInstance().getUserId();}getUserTraits(){return this.getAnalyticsInstance().getUserTraits();}getGroupId(){return this.getAnalyticsInstance().getGroupId();}getGroupTraits(){return this.getAnalyticsInstance().getGroupTraits();}startSession(sessionId){return this.getAnalyticsInstance().startSession(sessionId);}endSession(){return this.getAnalyticsInstance().endSession();}getSessionId(){return this.getAnalyticsInstance().getSessionId();}setAuthToken(token){return this.getAnalyticsInstance().setAuthToken(token);}}
|
3144
3172
|
|
3145
3173
|
exports.RudderAnalytics = RudderAnalytics;
|