@rudderstack/analytics-js 3.0.1 → 3.0.2

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.
@@ -419,7 +419,7 @@
419
419
 
420
420
  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';
421
421
 
422
- const APP_NAME='RudderLabs JavaScript SDK';const APP_VERSION='3.0.1';const APP_NAMESPACE='com.rudderlabs.javascript';const MODULE_TYPE='npm';const ADBLOCK_PAGE_CATEGORY='RudderJS-Initiated';const ADBLOCK_PAGE_NAME='ad-block page request';const ADBLOCK_PAGE_PATH='/ad-blocked';const GLOBAL_PRELOAD_BUFFER='preloadedEventsBuffer';const CONSENT_TRACK_EVENT_NAME='Consent Management Interaction';
422
+ const APP_NAME='RudderLabs JavaScript SDK';const APP_VERSION='3.0.2';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';
423
423
 
424
424
  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';
425
425
 
@@ -725,7 +725,7 @@
725
725
 
726
726
  const RETRY_QUEUE_PROCESS_ERROR=context=>`${context}${LOG_CONTEXT_SEPARATOR}Process function threw an error.`;const RETRY_QUEUE_ENTRY_REMOVE_ERROR=(context,entry,attempt)=>`${context}${LOG_CONTEXT_SEPARATOR}Failed to remove local storage entry "${entry}" (attempt: ${attempt}.`;
727
727
 
728
- const DEFAULT_MIN_RETRY_DELAY_MS=1000;const DEFAULT_MAX_RETRY_DELAY_MS=30000;const DEFAULT_BACKOFF_FACTOR=2;const DEFAULT_BACKOFF_JITTER=0;const DEFAULT_MAX_RETRY_ATTEMPTS=Infinity;const DEFAULT_MAX_ITEMS=Infinity;const DEFAULT_ACK_TIMER_MS=1000;const DEFAULT_RECLAIM_TIMER_MS=3000;const DEFAULT_RECLAIM_TIMEOUT_MS=10000;const DEFAULT_RECLAIM_WAIT_MS=500;const DEFAULT_MAX_BATCH_SIZE_BYTES=512*1024;// 512 KB; this is also the max size of a batch
728
+ const DEFAULT_MIN_RETRY_DELAY_MS=1000;const DEFAULT_MAX_RETRY_DELAY_MS=30000;const DEFAULT_BACKOFF_FACTOR=2;const DEFAULT_BACKOFF_JITTER=0;const DEFAULT_MAX_RETRY_ATTEMPTS=Infinity;const DEFAULT_MAX_ITEMS=Infinity;const DEFAULT_ACK_TIMER_MS=1000;const DEFAULT_RECLAIM_TIMER_MS=3000;const DEFAULT_RECLAIM_TIMEOUT_MS=10000;const DEFAULT_RECLAIM_WAIT_MS=500;const MIN_TIMER_SCALE_FACTOR=1;const MAX_TIMER_SCALE_FACTOR=10;const DEFAULT_MAX_BATCH_SIZE_BYTES=512*1024;// 512 KB; this is also the max size of a batch
729
729
  const DEFAULT_MAX_BATCH_ITEMS=100;const DEFAULT_BATCH_FLUSH_INTERVAL_MS=60*1000;// 1 minutes
730
730
 
731
731
  const sortByTime=(a,b)=>a.time-b.time;const RETRY_QUEUE='RetryQueue';/**
@@ -735,13 +735,15 @@
735
735
  * @param {String} name The name of the queue. Will be used to find abandoned queues and retry their items
736
736
  * @param {Object} [opts] Optional argument to override `maxItems`, `maxAttempts`, `minRetryDelay, `maxRetryDelay`, `backoffFactor` and `backoffJitter`.
737
737
  * @param {QueueProcessCallback} fn The function to call in order to process an item added to the queue
738
- */class RetryQueue{constructor(name,options,queueProcessCb,storeManager,storageType=LOCAL_STORAGE,logger,queueBatchItemsSizeCalculatorCb){this.storeManager=storeManager;this.logger=logger;this.name=name;this.id=generateUUID();this.processQueueCb=queueProcessCb;this.batchSizeCalcCb=queueBatchItemsSizeCalculatorCb;this.maxItems=options.maxItems||DEFAULT_MAX_ITEMS;this.maxAttempts=options.maxAttempts||DEFAULT_MAX_RETRY_ATTEMPTS;this.batch={enabled:false};this.configureBatchMode(options);this.backoff={minRetryDelay:options.minRetryDelay||DEFAULT_MIN_RETRY_DELAY_MS,maxRetryDelay:options.maxRetryDelay||DEFAULT_MAX_RETRY_DELAY_MS,factor:options.backoffFactor||DEFAULT_BACKOFF_FACTOR,jitter:options.backoffJitter||DEFAULT_BACKOFF_JITTER};// painstakingly tuned. that's why they're not "easily" configurable
739
- this.timeouts={ackTimer:DEFAULT_ACK_TIMER_MS,reclaimTimer:DEFAULT_RECLAIM_TIMER_MS,reclaimTimeout:DEFAULT_RECLAIM_TIMEOUT_MS,reclaimWait:DEFAULT_RECLAIM_WAIT_MS};this.schedule=new Schedule();this.processId='0';// Set up our empty queues
738
+ */class RetryQueue{constructor(name,options,queueProcessCb,storeManager,storageType=LOCAL_STORAGE,logger,queueBatchItemsSizeCalculatorCb){this.storeManager=storeManager;this.logger=logger;this.name=name;this.id=generateUUID();this.processQueueCb=queueProcessCb;this.batchSizeCalcCb=queueBatchItemsSizeCalculatorCb;this.maxItems=options.maxItems||DEFAULT_MAX_ITEMS;this.maxAttempts=options.maxAttempts||DEFAULT_MAX_RETRY_ATTEMPTS;this.batch={enabled:false};this.configureBatchMode(options);this.backoff={minRetryDelay:options.minRetryDelay||DEFAULT_MIN_RETRY_DELAY_MS,maxRetryDelay:options.maxRetryDelay||DEFAULT_MAX_RETRY_DELAY_MS,factor:options.backoffFactor||DEFAULT_BACKOFF_FACTOR,jitter:options.backoffJitter||DEFAULT_BACKOFF_JITTER};// Limit the timer scale factor to the minimum value
739
+ let timerScaleFactor=Math.max(options.timerScaleFactor??MIN_TIMER_SCALE_FACTOR,MIN_TIMER_SCALE_FACTOR);// Limit the timer scale factor to the maximum value
740
+ timerScaleFactor=Math.min(timerScaleFactor,MAX_TIMER_SCALE_FACTOR);// painstakingly tuned. that's why they're not "easily" configurable
741
+ this.timeouts={ackTimer:Math.round(timerScaleFactor*DEFAULT_ACK_TIMER_MS),reclaimTimer:Math.round(timerScaleFactor*DEFAULT_RECLAIM_TIMER_MS),reclaimTimeout:Math.round(timerScaleFactor*DEFAULT_RECLAIM_TIMEOUT_MS),reclaimWait:Math.round(timerScaleFactor*DEFAULT_RECLAIM_WAIT_MS)};this.schedule=new Schedule();this.processId='0';// Set up our empty queues
740
742
  this.store=this.storeManager.setStore({id:this.id,name:this.name,validKeys:QueueStatuses,type:storageType});this.setDefaultQueueEntries();// bind recurring tasks for ease of use
741
743
  this.ack=this.ack.bind(this);this.checkReclaim=this.checkReclaim.bind(this);this.processHead=this.processHead.bind(this);this.flushBatch=this.flushBatch.bind(this);// Attach visibility change listener to flush the queue
742
744
  this.attachListeners();this.scheduleTimeoutActive=false;}setDefaultQueueEntries(){this.setStorageEntry(QueueStatuses.IN_PROGRESS,{});this.setStorageEntry(QueueStatuses.QUEUE,[]);this.setStorageEntry(QueueStatuses.BATCH_QUEUE,[]);}configureBatchMode(options){this.batchingInProgress=false;if(!isObjectLiteralAndNotNull(options.batch)){return;}const batchOptions=options.batch;this.batch.enabled=batchOptions.enabled===true;if(this.batch.enabled){// Set upper cap on the batch payload size
743
- this.batch.maxSize=Math.min(batchOptions.maxSize??DEFAULT_MAX_BATCH_SIZE_BYTES,DEFAULT_MAX_BATCH_SIZE_BYTES);this.batch.maxItems=batchOptions.maxItems??DEFAULT_MAX_BATCH_ITEMS;this.batch.flushInterval=batchOptions.flushInterval??DEFAULT_BATCH_FLUSH_INTERVAL_MS;}}attachListeners(){if(this.batch.enabled){globalThis.addEventListener('visibilitychange',()=>{if(document.visibilityState==='hidden'){this.flushBatch();}});}}getStorageEntry(name){return this.store.get(name??this.name);}// TODO: fix the type of different queues to be the same if possible
744
- setStorageEntry(name,value){this.store.set(name??this.name,value??[]);}/**
745
+ this.batch.maxSize=Math.min(batchOptions.maxSize??DEFAULT_MAX_BATCH_SIZE_BYTES,DEFAULT_MAX_BATCH_SIZE_BYTES);this.batch.maxItems=batchOptions.maxItems??DEFAULT_MAX_BATCH_ITEMS;this.batch.flushInterval=batchOptions.flushInterval??DEFAULT_BATCH_FLUSH_INTERVAL_MS;}}attachListeners(){if(this.batch.enabled){globalThis.addEventListener('visibilitychange',()=>{if(document.visibilityState==='hidden'){this.flushBatch();}});}}getStorageEntry(name){return this.store.get(name);}// TODO: fix the type of different queues to be the same if possible
746
+ setStorageEntry(name,value){if(isNullOrUndefined(value)){this.store.remove(name);}else {this.store.set(name,value);}}/**
745
747
  * Stops processing the queue
746
748
  */stop(){this.schedule.cancelAll();this.scheduleTimeoutActive=false;}/**
747
749
  * Starts processing the queue
@@ -766,7 +768,7 @@
766
768
  * Handles a new item added to the retry queue when batching is enabled
767
769
  * @param entry New item added to the retry queue
768
770
  * @returns Undefined or batch entry object
769
- */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
771
+ */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.getBatchDispatchInfo(batchQueue);// if batch criteria is met, queue the batch events to the main queue and clear batch queue
770
772
  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
771
773
  if(batchItems.length>0){curEntry=this.genQueueItem(batchItems);}// re-attach the timeout handler
772
774
  this.scheduleFlushBatch();}this.batchingInProgress=false;}else {batchQueue.push(entry);}// update the batch queue
@@ -789,7 +791,7 @@
789
791
  * Returns the information about whether the batch criteria is met or exceeded
790
792
  * @param batchItems Prospective batch items
791
793
  * @returns Batch dispatch info
792
- */getBatchDispInfo(batchItems){let lengthCriteriaMet=false;let lengthCriteriaExceeded=false;const configuredBatchMaxItems=this.batch?.maxItems;if(isDefined(configuredBatchMaxItems)){lengthCriteriaMet=batchItems.length===configuredBatchMaxItems;lengthCriteriaExceeded=batchItems.length>configuredBatchMaxItems;}if(lengthCriteriaMet||lengthCriteriaExceeded){return {criteriaMet:lengthCriteriaMet,criteriaExceeded:lengthCriteriaExceeded};}let sizeCriteriaMet=false;let sizeCriteriaExceeded=false;const configuredBatchMaxSize=this.batch?.maxSize;if(isDefined(configuredBatchMaxSize)&&isDefined(this.batchSizeCalcCb)){const curBatchSize=this.batchSizeCalcCb(batchItems.map(queueItem=>queueItem.item));sizeCriteriaMet=curBatchSize===configuredBatchMaxSize;sizeCriteriaExceeded=curBatchSize>configuredBatchMaxSize;}return {criteriaMet:sizeCriteriaMet,criteriaExceeded:sizeCriteriaExceeded};}processHead(){// cancel the scheduled task if it exists
794
+ */getBatchDispatchInfo(batchItems){let lengthCriteriaMet=false;let lengthCriteriaExceeded=false;const configuredBatchMaxItems=this.batch?.maxItems;if(isDefined(configuredBatchMaxItems)){lengthCriteriaMet=batchItems.length===configuredBatchMaxItems;lengthCriteriaExceeded=batchItems.length>configuredBatchMaxItems;}if(lengthCriteriaMet||lengthCriteriaExceeded){return {criteriaMet:lengthCriteriaMet,criteriaExceeded:lengthCriteriaExceeded};}let sizeCriteriaMet=false;let sizeCriteriaExceeded=false;const configuredBatchMaxSize=this.batch?.maxSize;if(isDefined(configuredBatchMaxSize)&&isDefined(this.batchSizeCalcCb)){const curBatchSize=this.batchSizeCalcCb(batchItems.map(queueItem=>queueItem.item));sizeCriteriaMet=curBatchSize===configuredBatchMaxSize;sizeCriteriaExceeded=curBatchSize>configuredBatchMaxSize;}return {criteriaMet:sizeCriteriaMet,criteriaExceeded:sizeCriteriaExceeded};}processHead(){// cancel the scheduled task if it exists
793
795
  this.schedule.cancel(this.processId);// Pop the head off the queue
794
796
  let queue=this.getStorageEntry(QueueStatuses.QUEUE)??[];const inProgress=this.getStorageEntry(QueueStatuses.IN_PROGRESS)??{};const now=this.schedule.now();const toRun=[];// eslint-disable-next-line @typescript-eslint/no-unused-vars
795
797
  const processItemCallback=(el,id)=>(err,res)=>{const inProgress=this.getStorageEntry(QueueStatuses.IN_PROGRESS)??{};delete inProgress[id];this.setStorageEntry(QueueStatuses.IN_PROGRESS,inProgress);if(err){this.requeue(el.item,el.attemptNumber+1,err,el.id);}};const enqueueItem=(el,id)=>{toRun.push({item:el.item,done:processItemCallback(el,id),attemptNumber:el.attemptNumber});};let inProgressSize=Object.keys(inProgress).length;// eslint-disable-next-line no-plusplus
@@ -797,20 +799,17 @@
797
799
  inProgress[id]={item:el.item,attemptNumber:el.attemptNumber,time:this.schedule.now()};enqueueItem(el,id);}}this.setStorageEntry(QueueStatuses.QUEUE,queue);this.setStorageEntry(QueueStatuses.IN_PROGRESS,inProgress);toRun.forEach(el=>{// TODO: handle processQueueCb timeout
798
800
  try{const willBeRetried=this.shouldRetry(el.item,el.attemptNumber+1);this.processQueueCb(el.item,el.done,el.attemptNumber,this.maxAttempts,willBeRetried);}catch(err){this.logger?.error(RETRY_QUEUE_PROCESS_ERROR(RETRY_QUEUE),err);}});// re-read the queue in case the process function finished immediately or added another item
799
801
  queue=this.getStorageEntry(QueueStatuses.QUEUE)??[];this.schedule.cancel(this.processId);if(queue.length>0){const nextProcessExecutionTime=queue[0].time-now;this.processId=this.schedule.run(this.processHead,nextProcessExecutionTime,ScheduleModes.ASAP);}}// Ack continuously to prevent other tabs from claiming our queue
800
- ack(){this.setStorageEntry(QueueStatuses.ACK,this.schedule.now());this.setStorageEntry(QueueStatuses.RECLAIM_START,null);this.setStorageEntry(QueueStatuses.RECLAIM_END,null);this.schedule.run(this.ack,this.timeouts.ackTimer,ScheduleModes.ASAP);}reclaim(id){const other=this.storeManager.setStore({id,name:this.name,validKeys:QueueStatuses,type:LOCAL_STORAGE});const our={queue:this.getStorageEntry(QueueStatuses.QUEUE)??[]};const their={inProgress:other.get(QueueStatuses.IN_PROGRESS)??{},batchQueue:other.get(QueueStatuses.BATCH_QUEUE)??[],queue:other.get(QueueStatuses.QUEUE)??[]};const trackMessageIds=[];const addConcatQueue=(queue,incrementAttemptNumberBy)=>{const concatIterator=el=>{const id=el.id??generateUUID();if(trackMessageIds.includes(id));else {our.queue.push({item:el.item,attemptNumber:el.attemptNumber+incrementAttemptNumberBy,time:this.schedule.now(),id});trackMessageIds.push(id);}};if(Array.isArray(queue)){queue.forEach(concatIterator);}else if(queue){Object.values(queue).forEach(concatIterator);}};// add their queue to ours, resetting run-time to immediate and copying the attempt#
802
+ ack(){this.setStorageEntry(QueueStatuses.ACK,this.schedule.now());if(this.reclaimStartVal!=null){this.reclaimStartVal=null;this.setStorageEntry(QueueStatuses.RECLAIM_START,null);}if(this.reclaimEndVal!=null){this.reclaimEndVal=null;this.setStorageEntry(QueueStatuses.RECLAIM_END,null);}this.schedule.run(this.ack,this.timeouts.ackTimer,ScheduleModes.ASAP);}reclaim(id){const other=this.storeManager.setStore({id,name:this.name,validKeys:QueueStatuses,type:LOCAL_STORAGE});const our={queue:this.getStorageEntry(QueueStatuses.QUEUE)??[]};const their={inProgress:other.get(QueueStatuses.IN_PROGRESS)??{},batchQueue:other.get(QueueStatuses.BATCH_QUEUE)??[],queue:other.get(QueueStatuses.QUEUE)??[]};const trackMessageIds=[];const addConcatQueue=(queue,incrementAttemptNumberBy)=>{const concatIterator=el=>{const id=el.id??generateUUID();if(trackMessageIds.includes(id));else {our.queue.push({item:el.item,attemptNumber:el.attemptNumber+incrementAttemptNumberBy,time:this.schedule.now(),id});trackMessageIds.push(id);}};if(Array.isArray(queue)){queue.forEach(concatIterator);}else if(queue){Object.values(queue).forEach(concatIterator);}};// add their queue to ours, resetting run-time to immediate and copying the attempt#
801
803
  addConcatQueue(their.queue,0);// Process batch queue items
802
804
  if(this.batch.enabled){their.batchQueue.forEach(el=>{const id=el.id??generateUUID();if(trackMessageIds.includes(id));else {this.enqueue(el);trackMessageIds.push(id);}});}else {// if batching is not enabled in the current instance, add those items to the main queue directly
803
805
  addConcatQueue(their.batchQueue,0);}// if the queue is abandoned, all the in-progress are failed. retry them immediately and increment the attempt#
804
806
  addConcatQueue(their.inProgress,1);our.queue=our.queue.sort(sortByTime);this.setStorageEntry(QueueStatuses.QUEUE,our.queue);// remove all keys one by on next tick to avoid NS_ERROR_STORAGE_BUSY error
805
807
  this.clearQueueEntries(other,1);// process the new items we claimed
806
808
  this.processHead();}// eslint-disable-next-line class-methods-use-this
807
- clearQueueEntries(other,localStorageBackoff){this.removeStorageEntry(other,0,localStorageBackoff);}removeStorageEntry(store,entryIdx,backoff,attempt=1){const maxAttempts=2;globalThis.setTimeout(()=>{const queueEntryKeys=Object.keys(QueueStatuses);const entry=QueueStatuses[queueEntryKeys[entryIdx]];try{store.remove(entry);// clear the next entry
809
+ clearQueueEntries(other,localStorageBackoff){this.removeStorageEntry(other,0,localStorageBackoff);}removeStorageEntry(store,entryIdx,backoff,attempt=1){const maxAttempts=2;const queueEntryKeys=Object.keys(QueueStatuses);const entry=QueueStatuses[queueEntryKeys[entryIdx]];globalThis.setTimeout(()=>{try{store.remove(entry);// clear the next entry
808
810
  if(entryIdx+1<queueEntryKeys.length){this.removeStorageEntry(store,entryIdx+1,backoff);}}catch(err){const storageBusyErr='NS_ERROR_STORAGE_BUSY';const isLocalStorageBusy=err.name===storageBusyErr||err.code===storageBusyErr||err.code===0x80630001;if(isLocalStorageBusy&&attempt<maxAttempts){// Try clearing the same entry again with some extra delay
809
- this.removeStorageEntry(store,entryIdx,backoff+40,attempt+1);}else {this.logger?.error(RETRY_QUEUE_ENTRY_REMOVE_ERROR(RETRY_QUEUE,entry,attempt),err);}// clear the next entry
810
- if(attempt===maxAttempts&&entryIdx+1<queueEntryKeys.length){this.removeStorageEntry(store,entryIdx+1,backoff);}}},backoff);}checkReclaim(){const createReclaimStartTask=store=>()=>{if(store.get(QueueStatuses.RECLAIM_END)!==this.id){return;}if(store.get(QueueStatuses.RECLAIM_START)!==this.id){return;}this.reclaim(store.id);};const createReclaimEndTask=store=>()=>{if(store.get(QueueStatuses.RECLAIM_START)!==this.id){return;}store.set(QueueStatuses.RECLAIM_END,this.id);this.schedule.run(createReclaimStartTask(store),this.timeouts.reclaimWait,ScheduleModes.ABANDON);};const tryReclaim=store=>{store.set(QueueStatuses.RECLAIM_START,this.id);store.set(QueueStatuses.ACK,this.schedule.now());this.schedule.run(createReclaimEndTask(store),this.timeouts.reclaimWait,ScheduleModes.ABANDON);};const findOtherQueues=name=>{const res=[];const storage=this.store.getOriginalEngine();for(let i=0;i<storage.length;i++){const k=storage.key(i);const parts=k?k.split('.'):[];if(parts.length!==3){// eslint-disable-next-line no-continue
811
- continue;}if(parts[0]!==name){// eslint-disable-next-line no-continue
812
- continue;}if(parts[2]!==QueueStatuses.ACK){// eslint-disable-next-line no-continue
813
- continue;}res.push(this.storeManager.setStore({id:parts[1],name,validKeys:QueueStatuses,type:LOCAL_STORAGE}));}return res;};findOtherQueues(this.name).forEach(store=>{if(store.id===this.id){return;}if(this.schedule.now()-store.get(QueueStatuses.ACK)<this.timeouts.reclaimTimeout){return;}tryReclaim(store);});this.schedule.run(this.checkReclaim,this.timeouts.reclaimTimer,ScheduleModes.RESCHEDULE);}clear(){this.schedule.cancelAll();this.setDefaultQueueEntries();}}
811
+ this.removeStorageEntry(store,entryIdx,backoff+40,attempt+1);}else {this.logger?.error(RETRY_QUEUE_ENTRY_REMOVE_ERROR(RETRY_QUEUE,entry,attempt),err);}// clear the next entry after we've exhausted our attempts
812
+ if(attempt===maxAttempts&&entryIdx+1<queueEntryKeys.length){this.removeStorageEntry(store,entryIdx+1,backoff);}}},backoff);}checkReclaim(){const createReclaimStartTask=store=>()=>{if(store.get(QueueStatuses.RECLAIM_END)!==this.id){return;}if(store.get(QueueStatuses.RECLAIM_START)!==this.id){return;}this.reclaim(store.id);};const createReclaimEndTask=store=>()=>{if(store.get(QueueStatuses.RECLAIM_START)!==this.id){return;}store.set(QueueStatuses.RECLAIM_END,this.id);this.schedule.run(createReclaimStartTask(store),this.timeouts.reclaimWait,ScheduleModes.ABANDON);};const tryReclaim=store=>{store.set(QueueStatuses.RECLAIM_START,this.id);store.set(QueueStatuses.ACK,this.schedule.now());this.schedule.run(createReclaimEndTask(store),this.timeouts.reclaimWait,ScheduleModes.ABANDON);};const findOtherQueues=name=>{const res=[];const storageKeys=this.store.getOriginalEngine().keys();storageKeys.forEach(k=>{const keyParts=k?k.split('.'):[];if(keyParts.length>=3&&keyParts[0]===name&&keyParts[1]!==this.id&&keyParts[2]===QueueStatuses.ACK){res.push(this.storeManager.setStore({id:keyParts[1],name,validKeys:QueueStatuses,type:LOCAL_STORAGE}));}});return res;};findOtherQueues(this.name).forEach(store=>{if(this.schedule.now()-store.get(QueueStatuses.ACK)<this.timeouts.reclaimTimeout){return;}tryReclaim(store);});this.schedule.run(this.checkReclaim,this.timeouts.reclaimTimer,ScheduleModes.RESCHEDULE);}clear(){this.schedule.cancelAll();this.setDefaultQueueEntries();}}
814
813
 
815
814
  const pluginName$e='BeaconQueue';const BeaconQueue=()=>({name:pluginName$e,deps:[],initialize:state=>{state.plugins.loadedPlugins.value=[...state.plugins.loadedPlugins.value,pluginName$e];},dataplaneEventsQueue:{/**
816
815
  * Initialize the queue for delivery
@@ -863,7 +862,7 @@
863
862
  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
864
863
  if(!isRudderSDKError(event)){return false;}enhanceErrorEventMutator(event,metadataSource);return true;}catch{// Drop the error event if it couldn't be filtered as
865
864
  // it is most likely a non-SDK error
866
- 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.1',// Set SDK version as the app version from build config
865
+ 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.2',// Set SDK version as the app version from build config
867
866
  metaData:{SDK:{name:'JS',installType:'npm'}},beforeSend:onError(state),autoCaptureSessions:false,// auto capture sessions is disabled
868
867
  collectUserIp:false,// collecting user's IP is disabled
869
868
  // enabledBreadcrumbTypes: ['error', 'log', 'user'], // for v7 and above
@@ -2491,13 +2490,12 @@
2491
2490
  // getting a list of all cookie storage keys and remove all values
2492
2491
  // sounds risky to do as it will take on all top domain cookies
2493
2492
  // better to explicitly clear specific ones if needed
2494
- }// This cannot be implemented for cookies
2495
- // eslint-disable-next-line class-methods-use-this
2496
- key(index){const cookies=cookie();const cookieNames=Object.keys(cookies);return isUndefined(cookieNames[index])?null:cookieNames[index];}}
2493
+ }key(index){const curKeys=this.keys();return curKeys[index]??null;}// eslint-disable-next-line class-methods-use-this
2494
+ keys(){return Object.keys(cookie());}}
2497
2495
 
2498
2496
  /**
2499
2497
  * A storage utility to retain values in memory via Storage interface
2500
- */class InMemoryStorage{isEnabled=true;length=0;data={};constructor(options,logger){this.options=getDefaultInMemoryStorageOptions();this.logger=logger;this.configure(options??{});}configure(options){this.options=mergeDeepRight(this.options,options);this.isEnabled=Boolean(this.options.enabled);return this.options;}setItem(key,value){this.data[key]=value;this.length=Object.keys(this.data).length;return value;}getItem(key){if(key in this.data){return this.data[key];}return null;}removeItem(key){if(key in this.data){delete this.data[key];}this.length=Object.keys(this.data).length;return null;}clear(){this.data={};this.length=0;}key(index){return Object.keys(this.data)[index]?Object.keys(this.data)[index]:null;}}const defaultInMemoryStorage=new InMemoryStorage({},defaultLogger);
2498
+ */class InMemoryStorage{isEnabled=true;length=0;data={};constructor(options,logger){this.options=getDefaultInMemoryStorageOptions();this.logger=logger;this.configure(options??{});}configure(options){this.options=mergeDeepRight(this.options,options);this.isEnabled=Boolean(this.options.enabled);return this.options;}setItem(key,value){this.data[key]=value;this.length=Object.keys(this.data).length;return value;}getItem(key){if(key in this.data){return this.data[key];}return null;}removeItem(key){if(key in this.data){delete this.data[key];}this.length=Object.keys(this.data).length;return null;}clear(){this.data={};this.length=0;}key(index){const curKeys=this.keys();return curKeys[index]??null;}keys(){return Object.keys(this.data);}}const defaultInMemoryStorage=new InMemoryStorage({},defaultLogger);
2501
2499
 
2502
2500
  var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
2503
2501
 
@@ -2520,12 +2518,12 @@
2520
2518
  /**
2521
2519
  * A storage utility to persist values in localstorage via Storage interface
2522
2520
  */class LocalStorage{isSupportAvailable=true;isEnabled=true;length=0;constructor(options={},logger){this.options=getDefaultLocalStorageOptions();this.logger=logger;this.configure(options);}configure(options){this.options=mergeDeepRight(this.options,options);this.isSupportAvailable=isStorageAvailable(LOCAL_STORAGE,this,this.logger);this.isEnabled=Boolean(this.options.enabled&&this.isSupportAvailable);return this.options;}setItem(key,value){store.set(key,value);this.length=store.keys().length;}// eslint-disable-next-line class-methods-use-this
2523
- 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
2524
- key(index){return store.keys()[index]?store.keys()[index]:null;}}const defaultLocalStorage=new LocalStorage({},defaultLogger);
2521
+ 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;}key(index){const curKeys=this.keys();return curKeys[index]??null;}// eslint-disable-next-line class-methods-use-this
2522
+ keys(){return store.keys();}}const defaultLocalStorage=new LocalStorage({},defaultLogger);
2525
2523
 
2526
2524
  /**
2527
2525
  * A storage utility to persist values in SessionStorage via Storage interface
2528
- */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);
2526
+ */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);}keys(){const keys=[];for(let i=0;i<this.store.length;i+=1){const key=this.store.key(i);if(key!==null){keys.push(key);}}return keys;}}const defaultSessionStorage=new SessionStorage({},defaultLogger);
2529
2527
 
2530
2528
  /**
2531
2529
  * A utility to retrieve the storage singleton instance by type
@@ -2697,7 +2695,7 @@
2697
2695
  * @param consentManagementOpts consent management options
2698
2696
  * @param logger logger instance
2699
2697
  * @returns Corresponding provider and plugin name of the selected consent manager from the supported consent managers
2700
- */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
2698
+ */const getConsentManagerInfo=(consentManagementOpts,logger)=>{let{provider}=consentManagementOpts;const consentManagerPluginName=provider?ConsentManagersToPluginNameMap[provider]:undefined;if(provider&&!consentManagerPluginName){logger?.error(UNSUPPORTED_CONSENT_MANAGER_ERROR(CONFIG_MANAGER,provider,ConsentManagersToPluginNameMap));// Reset the provider value
2701
2699
  provider=undefined;}return {provider,consentManagerPluginName};};/**
2702
2700
  * Validates and converts the consent management options into a normalized format
2703
2701
  * @param consentManagementOpts Consent management options provided by the user
@@ -2799,7 +2797,7 @@
2799
2797
  if(urlObj.search===''){pageUrl=canonicalUrl+search;}else {pageUrl=canonicalUrl;}path=urlObj.pathname;}catch(err){// Do nothing
2800
2798
  }}const url=getUrlWithoutHash(pageUrl);const{title}=document;const referrer=getReferrer();return {path,referrer,referring_domain:getReferringDomain(referrer),search,title,url,tab_url:tabUrl};};
2801
2799
 
2802
- const POLYFILL_URL=`https://polyfill.io/v3/polyfill.min.js?version=3.111.0&features=${Object.keys(legacyJSEngineRequiredPolyfills).join('%2C')}`;const POLYFILL_LOAD_TIMEOUT=10*1000;// 10 seconds
2800
+ const POLYFILL_URL=`https://polyfill-fastly.io/v3/polyfill.min.js?version=3.111.0&features=${Object.keys(legacyJSEngineRequiredPolyfills).join('%2C')}`;const POLYFILL_LOAD_TIMEOUT=10*1000;// 10 seconds
2803
2801
  const POLYFILL_SCRIPT_ID='rudderstackPolyfill';
2804
2802
 
2805
2803
  class CapabilitiesManager{constructor(errorHandler,logger){this.logger=logger;this.errorHandler=errorHandler;this.externalSrcLoader=new ExternalSrcLoader(this.errorHandler,this.logger);this.onError=this.onError.bind(this);this.onReady=this.onReady.bind(this);}init(){try{this.prepareBrowserCapabilities();this.attachWindowListeners();}catch(err){this.onError(err);}}/**
@@ -408,7 +408,7 @@ if(isDefined(payload.groupId)){payload.groupId=tryStringify(payload.groupId);}el
408
408
 
409
409
  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';
410
410
 
411
- const APP_NAME='RudderLabs JavaScript SDK';const APP_VERSION='3.0.1';const APP_NAMESPACE='com.rudderlabs.javascript';const MODULE_TYPE='npm';const ADBLOCK_PAGE_CATEGORY='RudderJS-Initiated';const ADBLOCK_PAGE_NAME='ad-block page request';const ADBLOCK_PAGE_PATH='/ad-blocked';const GLOBAL_PRELOAD_BUFFER='preloadedEventsBuffer';const CONSENT_TRACK_EVENT_NAME='Consent Management Interaction';
411
+ const APP_NAME='RudderLabs JavaScript SDK';const APP_VERSION='3.0.2';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';
412
412
 
413
413
  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';
414
414
 
@@ -650,7 +650,7 @@ destination.config.useNativeSDK===true);const isHybridModeDestination=destinatio
650
650
  */const pluginNamesList=['BeaconQueue','Bugsnag','CustomConsentManager','DeviceModeDestinations','DeviceModeTransformation','ErrorReporting','ExternalAnonymousId','GoogleLinker','KetchConsentManager','NativeDestinationQueue','OneTrustConsentManager','StorageEncryption','StorageEncryptionLegacy','StorageMigrator','XhrQueue'];
651
651
 
652
652
  const remotesMap = {
653
- 'rudderAnalyticsRemotePlugins':{url:()=>Promise.resolve(window.RudderStackGlobals && window.RudderStackGlobals.app && window.RudderStackGlobals.app.pluginsCDNPath ? "" + window.RudderStackGlobals.app.pluginsCDNPath + "/rsa-plugins.js" : "https://cdn.rudderlabs.com/3.0.1/modern/plugins/rsa-plugins.js"),format:'esm',from:'vite'}
653
+ 'rudderAnalyticsRemotePlugins':{url:()=>Promise.resolve(window.RudderStackGlobals && window.RudderStackGlobals.app && window.RudderStackGlobals.app.pluginsCDNPath ? "" + window.RudderStackGlobals.app.pluginsCDNPath + "/rsa-plugins.js" : "https://cdn.rudderlabs.com/3.0.2/modern/plugins/rsa-plugins.js"),format:'esm',from:'vite'}
654
654
  };
655
655
  const loadJS = async (url, fn) => {
656
656
  const resolvedUrl = typeof url === 'function' ? await url() : url;
@@ -899,13 +899,12 @@ clear(){// Not implemented
899
899
  // getting a list of all cookie storage keys and remove all values
900
900
  // sounds risky to do as it will take on all top domain cookies
901
901
  // better to explicitly clear specific ones if needed
902
- }// This cannot be implemented for cookies
903
- // eslint-disable-next-line class-methods-use-this
904
- key(index){const cookies=cookie();const cookieNames=Object.keys(cookies);return isUndefined(cookieNames[index])?null:cookieNames[index];}}
902
+ }key(index){const curKeys=this.keys();return curKeys[index]??null;}// eslint-disable-next-line class-methods-use-this
903
+ keys(){return Object.keys(cookie());}}
905
904
 
906
905
  /**
907
906
  * A storage utility to retain values in memory via Storage interface
908
- */class InMemoryStorage{isEnabled=true;length=0;data={};constructor(options,logger){this.options=getDefaultInMemoryStorageOptions();this.logger=logger;this.configure(options??{});}configure(options){this.options=mergeDeepRight(this.options,options);this.isEnabled=Boolean(this.options.enabled);return this.options;}setItem(key,value){this.data[key]=value;this.length=Object.keys(this.data).length;return value;}getItem(key){if(key in this.data){return this.data[key];}return null;}removeItem(key){if(key in this.data){delete this.data[key];}this.length=Object.keys(this.data).length;return null;}clear(){this.data={};this.length=0;}key(index){return Object.keys(this.data)[index]?Object.keys(this.data)[index]:null;}}const defaultInMemoryStorage=new InMemoryStorage({},defaultLogger);
907
+ */class InMemoryStorage{isEnabled=true;length=0;data={};constructor(options,logger){this.options=getDefaultInMemoryStorageOptions();this.logger=logger;this.configure(options??{});}configure(options){this.options=mergeDeepRight(this.options,options);this.isEnabled=Boolean(this.options.enabled);return this.options;}setItem(key,value){this.data[key]=value;this.length=Object.keys(this.data).length;return value;}getItem(key){if(key in this.data){return this.data[key];}return null;}removeItem(key){if(key in this.data){delete this.data[key];}this.length=Object.keys(this.data).length;return null;}clear(){this.data={};this.length=0;}key(index){const curKeys=this.keys();return curKeys[index]??null;}keys(){return Object.keys(this.data);}}const defaultInMemoryStorage=new InMemoryStorage({},defaultLogger);
909
908
 
910
909
  var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
911
910
 
@@ -928,12 +927,12 @@ if(key===undefined){var ret={};this.forEach(function(key,val){return ret[key]=va
928
927
  /**
929
928
  * A storage utility to persist values in localstorage via Storage interface
930
929
  */class LocalStorage{isSupportAvailable=true;isEnabled=true;length=0;constructor(options={},logger){this.options=getDefaultLocalStorageOptions();this.logger=logger;this.configure(options);}configure(options){this.options=mergeDeepRight(this.options,options);this.isSupportAvailable=isStorageAvailable(LOCAL_STORAGE,this,this.logger);this.isEnabled=Boolean(this.options.enabled&&this.isSupportAvailable);return this.options;}setItem(key,value){store.set(key,value);this.length=store.keys().length;}// eslint-disable-next-line class-methods-use-this
931
- 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
932
- key(index){return store.keys()[index]?store.keys()[index]:null;}}const defaultLocalStorage=new LocalStorage({},defaultLogger);
930
+ 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;}key(index){const curKeys=this.keys();return curKeys[index]??null;}// eslint-disable-next-line class-methods-use-this
931
+ keys(){return store.keys();}}const defaultLocalStorage=new LocalStorage({},defaultLogger);
933
932
 
934
933
  /**
935
934
  * A storage utility to persist values in SessionStorage via Storage interface
936
- */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);
935
+ */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);}keys(){const keys=[];for(let i=0;i<this.store.length;i+=1){const key=this.store.key(i);if(key!==null){keys.push(key);}}return keys;}}const defaultSessionStorage=new SessionStorage({},defaultLogger);
937
936
 
938
937
  /**
939
938
  * A utility to retrieve the storage singleton instance by type
@@ -1109,7 +1108,7 @@ validOptions.consentManagement=mergeDeepRight(clonedOptions.consentManagement,{e
1109
1108
  * @param consentManagementOpts consent management options
1110
1109
  * @param logger logger instance
1111
1110
  * @returns Corresponding provider and plugin name of the selected consent manager from the supported consent managers
1112
- */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
1111
+ */const getConsentManagerInfo=(consentManagementOpts,logger)=>{let{provider}=consentManagementOpts;const consentManagerPluginName=provider?ConsentManagersToPluginNameMap[provider]:undefined;if(provider&&!consentManagerPluginName){logger?.error(UNSUPPORTED_CONSENT_MANAGER_ERROR(CONFIG_MANAGER,provider,ConsentManagersToPluginNameMap));// Reset the provider value
1113
1112
  provider=undefined;}return {provider,consentManagerPluginName};};/**
1114
1113
  * Validates and converts the consent management options into a normalized format
1115
1114
  * @param consentManagementOpts Consent management options provided by the user
@@ -1211,7 +1210,7 @@ if(canonicalUrl){try{const urlObj=new URL(canonicalUrl);// If existing, query pa
1211
1210
  if(urlObj.search===''){pageUrl=canonicalUrl+search;}else {pageUrl=canonicalUrl;}path=urlObj.pathname;}catch(err){// Do nothing
1212
1211
  }}const url=getUrlWithoutHash(pageUrl);const{title}=document;const referrer=getReferrer();return {path,referrer,referring_domain:getReferringDomain(referrer),search,title,url,tab_url:tabUrl};};
1213
1212
 
1214
- const POLYFILL_URL=`https://polyfill.io/v3/polyfill.min.js?version=3.111.0&features=${Object.keys(legacyJSEngineRequiredPolyfills).join('%2C')}`;const POLYFILL_LOAD_TIMEOUT=10*1000;// 10 seconds
1213
+ const POLYFILL_URL=`https://polyfill-fastly.io/v3/polyfill.min.js?version=3.111.0&features=${Object.keys(legacyJSEngineRequiredPolyfills).join('%2C')}`;const POLYFILL_LOAD_TIMEOUT=10*1000;// 10 seconds
1215
1214
  const POLYFILL_SCRIPT_ID='rudderstackPolyfill';
1216
1215
 
1217
1216
  class CapabilitiesManager{constructor(errorHandler,logger){this.logger=logger;this.errorHandler=errorHandler;this.externalSrcLoader=new ExternalSrcLoader(this.errorHandler,this.logger);this.onError=this.onError.bind(this);this.onReady=this.onReady.bind(this);}init(){try{this.prepareBrowserCapabilities();this.attachWindowListeners();}catch(err){this.onError(err);}}/**
@@ -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.1';const APP_NAMESPACE='com.rudderlabs.javascript';const MODULE_TYPE='npm';const ADBLOCK_PAGE_CATEGORY='RudderJS-Initiated';const ADBLOCK_PAGE_NAME='ad-block page request';const ADBLOCK_PAGE_PATH='/ad-blocked';const GLOBAL_PRELOAD_BUFFER='preloadedEventsBuffer';const CONSENT_TRACK_EVENT_NAME='Consent Management Interaction';
420
+ const APP_NAME='RudderLabs JavaScript SDK';const APP_VERSION='3.0.2';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
 
@@ -723,7 +723,7 @@ let ScheduleModes=/*#__PURE__*/function(ScheduleModes){ScheduleModes[ScheduleMod
723
723
 
724
724
  const RETRY_QUEUE_PROCESS_ERROR=context=>`${context}${LOG_CONTEXT_SEPARATOR}Process function threw an error.`;const RETRY_QUEUE_ENTRY_REMOVE_ERROR=(context,entry,attempt)=>`${context}${LOG_CONTEXT_SEPARATOR}Failed to remove local storage entry "${entry}" (attempt: ${attempt}.`;
725
725
 
726
- const DEFAULT_MIN_RETRY_DELAY_MS=1000;const DEFAULT_MAX_RETRY_DELAY_MS=30000;const DEFAULT_BACKOFF_FACTOR=2;const DEFAULT_BACKOFF_JITTER=0;const DEFAULT_MAX_RETRY_ATTEMPTS=Infinity;const DEFAULT_MAX_ITEMS=Infinity;const DEFAULT_ACK_TIMER_MS=1000;const DEFAULT_RECLAIM_TIMER_MS=3000;const DEFAULT_RECLAIM_TIMEOUT_MS=10000;const DEFAULT_RECLAIM_WAIT_MS=500;const DEFAULT_MAX_BATCH_SIZE_BYTES=512*1024;// 512 KB; this is also the max size of a batch
726
+ const DEFAULT_MIN_RETRY_DELAY_MS=1000;const DEFAULT_MAX_RETRY_DELAY_MS=30000;const DEFAULT_BACKOFF_FACTOR=2;const DEFAULT_BACKOFF_JITTER=0;const DEFAULT_MAX_RETRY_ATTEMPTS=Infinity;const DEFAULT_MAX_ITEMS=Infinity;const DEFAULT_ACK_TIMER_MS=1000;const DEFAULT_RECLAIM_TIMER_MS=3000;const DEFAULT_RECLAIM_TIMEOUT_MS=10000;const DEFAULT_RECLAIM_WAIT_MS=500;const MIN_TIMER_SCALE_FACTOR=1;const MAX_TIMER_SCALE_FACTOR=10;const DEFAULT_MAX_BATCH_SIZE_BYTES=512*1024;// 512 KB; this is also the max size of a batch
727
727
  const DEFAULT_MAX_BATCH_ITEMS=100;const DEFAULT_BATCH_FLUSH_INTERVAL_MS=60*1000;// 1 minutes
728
728
 
729
729
  const sortByTime=(a,b)=>a.time-b.time;const RETRY_QUEUE='RetryQueue';/**
@@ -733,13 +733,15 @@ const sortByTime=(a,b)=>a.time-b.time;const RETRY_QUEUE='RetryQueue';/**
733
733
  * @param {String} name The name of the queue. Will be used to find abandoned queues and retry their items
734
734
  * @param {Object} [opts] Optional argument to override `maxItems`, `maxAttempts`, `minRetryDelay, `maxRetryDelay`, `backoffFactor` and `backoffJitter`.
735
735
  * @param {QueueProcessCallback} fn The function to call in order to process an item added to the queue
736
- */class RetryQueue{constructor(name,options,queueProcessCb,storeManager,storageType=LOCAL_STORAGE,logger,queueBatchItemsSizeCalculatorCb){this.storeManager=storeManager;this.logger=logger;this.name=name;this.id=generateUUID();this.processQueueCb=queueProcessCb;this.batchSizeCalcCb=queueBatchItemsSizeCalculatorCb;this.maxItems=options.maxItems||DEFAULT_MAX_ITEMS;this.maxAttempts=options.maxAttempts||DEFAULT_MAX_RETRY_ATTEMPTS;this.batch={enabled:false};this.configureBatchMode(options);this.backoff={minRetryDelay:options.minRetryDelay||DEFAULT_MIN_RETRY_DELAY_MS,maxRetryDelay:options.maxRetryDelay||DEFAULT_MAX_RETRY_DELAY_MS,factor:options.backoffFactor||DEFAULT_BACKOFF_FACTOR,jitter:options.backoffJitter||DEFAULT_BACKOFF_JITTER};// painstakingly tuned. that's why they're not "easily" configurable
737
- this.timeouts={ackTimer:DEFAULT_ACK_TIMER_MS,reclaimTimer:DEFAULT_RECLAIM_TIMER_MS,reclaimTimeout:DEFAULT_RECLAIM_TIMEOUT_MS,reclaimWait:DEFAULT_RECLAIM_WAIT_MS};this.schedule=new Schedule();this.processId='0';// Set up our empty queues
736
+ */class RetryQueue{constructor(name,options,queueProcessCb,storeManager,storageType=LOCAL_STORAGE,logger,queueBatchItemsSizeCalculatorCb){this.storeManager=storeManager;this.logger=logger;this.name=name;this.id=generateUUID();this.processQueueCb=queueProcessCb;this.batchSizeCalcCb=queueBatchItemsSizeCalculatorCb;this.maxItems=options.maxItems||DEFAULT_MAX_ITEMS;this.maxAttempts=options.maxAttempts||DEFAULT_MAX_RETRY_ATTEMPTS;this.batch={enabled:false};this.configureBatchMode(options);this.backoff={minRetryDelay:options.minRetryDelay||DEFAULT_MIN_RETRY_DELAY_MS,maxRetryDelay:options.maxRetryDelay||DEFAULT_MAX_RETRY_DELAY_MS,factor:options.backoffFactor||DEFAULT_BACKOFF_FACTOR,jitter:options.backoffJitter||DEFAULT_BACKOFF_JITTER};// Limit the timer scale factor to the minimum value
737
+ let timerScaleFactor=Math.max(options.timerScaleFactor??MIN_TIMER_SCALE_FACTOR,MIN_TIMER_SCALE_FACTOR);// Limit the timer scale factor to the maximum value
738
+ timerScaleFactor=Math.min(timerScaleFactor,MAX_TIMER_SCALE_FACTOR);// painstakingly tuned. that's why they're not "easily" configurable
739
+ this.timeouts={ackTimer:Math.round(timerScaleFactor*DEFAULT_ACK_TIMER_MS),reclaimTimer:Math.round(timerScaleFactor*DEFAULT_RECLAIM_TIMER_MS),reclaimTimeout:Math.round(timerScaleFactor*DEFAULT_RECLAIM_TIMEOUT_MS),reclaimWait:Math.round(timerScaleFactor*DEFAULT_RECLAIM_WAIT_MS)};this.schedule=new Schedule();this.processId='0';// Set up our empty queues
738
740
  this.store=this.storeManager.setStore({id:this.id,name:this.name,validKeys:QueueStatuses,type:storageType});this.setDefaultQueueEntries();// bind recurring tasks for ease of use
739
741
  this.ack=this.ack.bind(this);this.checkReclaim=this.checkReclaim.bind(this);this.processHead=this.processHead.bind(this);this.flushBatch=this.flushBatch.bind(this);// Attach visibility change listener to flush the queue
740
742
  this.attachListeners();this.scheduleTimeoutActive=false;}setDefaultQueueEntries(){this.setStorageEntry(QueueStatuses.IN_PROGRESS,{});this.setStorageEntry(QueueStatuses.QUEUE,[]);this.setStorageEntry(QueueStatuses.BATCH_QUEUE,[]);}configureBatchMode(options){this.batchingInProgress=false;if(!isObjectLiteralAndNotNull(options.batch)){return;}const batchOptions=options.batch;this.batch.enabled=batchOptions.enabled===true;if(this.batch.enabled){// Set upper cap on the batch payload size
741
- this.batch.maxSize=Math.min(batchOptions.maxSize??DEFAULT_MAX_BATCH_SIZE_BYTES,DEFAULT_MAX_BATCH_SIZE_BYTES);this.batch.maxItems=batchOptions.maxItems??DEFAULT_MAX_BATCH_ITEMS;this.batch.flushInterval=batchOptions.flushInterval??DEFAULT_BATCH_FLUSH_INTERVAL_MS;}}attachListeners(){if(this.batch.enabled){globalThis.addEventListener('visibilitychange',()=>{if(document.visibilityState==='hidden'){this.flushBatch();}});}}getStorageEntry(name){return this.store.get(name??this.name);}// TODO: fix the type of different queues to be the same if possible
742
- setStorageEntry(name,value){this.store.set(name??this.name,value??[]);}/**
743
+ this.batch.maxSize=Math.min(batchOptions.maxSize??DEFAULT_MAX_BATCH_SIZE_BYTES,DEFAULT_MAX_BATCH_SIZE_BYTES);this.batch.maxItems=batchOptions.maxItems??DEFAULT_MAX_BATCH_ITEMS;this.batch.flushInterval=batchOptions.flushInterval??DEFAULT_BATCH_FLUSH_INTERVAL_MS;}}attachListeners(){if(this.batch.enabled){globalThis.addEventListener('visibilitychange',()=>{if(document.visibilityState==='hidden'){this.flushBatch();}});}}getStorageEntry(name){return this.store.get(name);}// TODO: fix the type of different queues to be the same if possible
744
+ setStorageEntry(name,value){if(isNullOrUndefined(value)){this.store.remove(name);}else {this.store.set(name,value);}}/**
743
745
  * Stops processing the queue
744
746
  */stop(){this.schedule.cancelAll();this.scheduleTimeoutActive=false;}/**
745
747
  * Starts processing the queue
@@ -764,7 +766,7 @@ if(curEntry){this.pushToMainQueue(curEntry);}}/**
764
766
  * Handles a new item added to the retry queue when batching is enabled
765
767
  * @param entry New item added to the retry queue
766
768
  * @returns Undefined or batch entry object
767
- */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
769
+ */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.getBatchDispatchInfo(batchQueue);// if batch criteria is met, queue the batch events to the main queue and clear batch queue
768
770
  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
769
771
  if(batchItems.length>0){curEntry=this.genQueueItem(batchItems);}// re-attach the timeout handler
770
772
  this.scheduleFlushBatch();}this.batchingInProgress=false;}else {batchQueue.push(entry);}// update the batch queue
@@ -787,7 +789,7 @@ this.setStorageEntry(QueueStatuses.BATCH_QUEUE,batchQueue);return curEntry;}push
787
789
  * Returns the information about whether the batch criteria is met or exceeded
788
790
  * @param batchItems Prospective batch items
789
791
  * @returns Batch dispatch info
790
- */getBatchDispInfo(batchItems){let lengthCriteriaMet=false;let lengthCriteriaExceeded=false;const configuredBatchMaxItems=this.batch?.maxItems;if(isDefined(configuredBatchMaxItems)){lengthCriteriaMet=batchItems.length===configuredBatchMaxItems;lengthCriteriaExceeded=batchItems.length>configuredBatchMaxItems;}if(lengthCriteriaMet||lengthCriteriaExceeded){return {criteriaMet:lengthCriteriaMet,criteriaExceeded:lengthCriteriaExceeded};}let sizeCriteriaMet=false;let sizeCriteriaExceeded=false;const configuredBatchMaxSize=this.batch?.maxSize;if(isDefined(configuredBatchMaxSize)&&isDefined(this.batchSizeCalcCb)){const curBatchSize=this.batchSizeCalcCb(batchItems.map(queueItem=>queueItem.item));sizeCriteriaMet=curBatchSize===configuredBatchMaxSize;sizeCriteriaExceeded=curBatchSize>configuredBatchMaxSize;}return {criteriaMet:sizeCriteriaMet,criteriaExceeded:sizeCriteriaExceeded};}processHead(){// cancel the scheduled task if it exists
792
+ */getBatchDispatchInfo(batchItems){let lengthCriteriaMet=false;let lengthCriteriaExceeded=false;const configuredBatchMaxItems=this.batch?.maxItems;if(isDefined(configuredBatchMaxItems)){lengthCriteriaMet=batchItems.length===configuredBatchMaxItems;lengthCriteriaExceeded=batchItems.length>configuredBatchMaxItems;}if(lengthCriteriaMet||lengthCriteriaExceeded){return {criteriaMet:lengthCriteriaMet,criteriaExceeded:lengthCriteriaExceeded};}let sizeCriteriaMet=false;let sizeCriteriaExceeded=false;const configuredBatchMaxSize=this.batch?.maxSize;if(isDefined(configuredBatchMaxSize)&&isDefined(this.batchSizeCalcCb)){const curBatchSize=this.batchSizeCalcCb(batchItems.map(queueItem=>queueItem.item));sizeCriteriaMet=curBatchSize===configuredBatchMaxSize;sizeCriteriaExceeded=curBatchSize>configuredBatchMaxSize;}return {criteriaMet:sizeCriteriaMet,criteriaExceeded:sizeCriteriaExceeded};}processHead(){// cancel the scheduled task if it exists
791
793
  this.schedule.cancel(this.processId);// Pop the head off the queue
792
794
  let queue=this.getStorageEntry(QueueStatuses.QUEUE)??[];const inProgress=this.getStorageEntry(QueueStatuses.IN_PROGRESS)??{};const now=this.schedule.now();const toRun=[];// eslint-disable-next-line @typescript-eslint/no-unused-vars
793
795
  const processItemCallback=(el,id)=>(err,res)=>{const inProgress=this.getStorageEntry(QueueStatuses.IN_PROGRESS)??{};delete inProgress[id];this.setStorageEntry(QueueStatuses.IN_PROGRESS,inProgress);if(err){this.requeue(el.item,el.attemptNumber+1,err,el.id);}};const enqueueItem=(el,id)=>{toRun.push({item:el.item,done:processItemCallback(el,id),attemptNumber:el.attemptNumber});};let inProgressSize=Object.keys(inProgress).length;// eslint-disable-next-line no-plusplus
@@ -795,20 +797,17 @@ while(queue.length>0&&queue[0].time<=now&&inProgressSize++<this.maxItems){const
795
797
  inProgress[id]={item:el.item,attemptNumber:el.attemptNumber,time:this.schedule.now()};enqueueItem(el,id);}}this.setStorageEntry(QueueStatuses.QUEUE,queue);this.setStorageEntry(QueueStatuses.IN_PROGRESS,inProgress);toRun.forEach(el=>{// TODO: handle processQueueCb timeout
796
798
  try{const willBeRetried=this.shouldRetry(el.item,el.attemptNumber+1);this.processQueueCb(el.item,el.done,el.attemptNumber,this.maxAttempts,willBeRetried);}catch(err){this.logger?.error(RETRY_QUEUE_PROCESS_ERROR(RETRY_QUEUE),err);}});// re-read the queue in case the process function finished immediately or added another item
797
799
  queue=this.getStorageEntry(QueueStatuses.QUEUE)??[];this.schedule.cancel(this.processId);if(queue.length>0){const nextProcessExecutionTime=queue[0].time-now;this.processId=this.schedule.run(this.processHead,nextProcessExecutionTime,ScheduleModes.ASAP);}}// Ack continuously to prevent other tabs from claiming our queue
798
- ack(){this.setStorageEntry(QueueStatuses.ACK,this.schedule.now());this.setStorageEntry(QueueStatuses.RECLAIM_START,null);this.setStorageEntry(QueueStatuses.RECLAIM_END,null);this.schedule.run(this.ack,this.timeouts.ackTimer,ScheduleModes.ASAP);}reclaim(id){const other=this.storeManager.setStore({id,name:this.name,validKeys:QueueStatuses,type:LOCAL_STORAGE});const our={queue:this.getStorageEntry(QueueStatuses.QUEUE)??[]};const their={inProgress:other.get(QueueStatuses.IN_PROGRESS)??{},batchQueue:other.get(QueueStatuses.BATCH_QUEUE)??[],queue:other.get(QueueStatuses.QUEUE)??[]};const trackMessageIds=[];const addConcatQueue=(queue,incrementAttemptNumberBy)=>{const concatIterator=el=>{const id=el.id??generateUUID();if(trackMessageIds.includes(id));else {our.queue.push({item:el.item,attemptNumber:el.attemptNumber+incrementAttemptNumberBy,time:this.schedule.now(),id});trackMessageIds.push(id);}};if(Array.isArray(queue)){queue.forEach(concatIterator);}else if(queue){Object.values(queue).forEach(concatIterator);}};// add their queue to ours, resetting run-time to immediate and copying the attempt#
800
+ ack(){this.setStorageEntry(QueueStatuses.ACK,this.schedule.now());if(this.reclaimStartVal!=null){this.reclaimStartVal=null;this.setStorageEntry(QueueStatuses.RECLAIM_START,null);}if(this.reclaimEndVal!=null){this.reclaimEndVal=null;this.setStorageEntry(QueueStatuses.RECLAIM_END,null);}this.schedule.run(this.ack,this.timeouts.ackTimer,ScheduleModes.ASAP);}reclaim(id){const other=this.storeManager.setStore({id,name:this.name,validKeys:QueueStatuses,type:LOCAL_STORAGE});const our={queue:this.getStorageEntry(QueueStatuses.QUEUE)??[]};const their={inProgress:other.get(QueueStatuses.IN_PROGRESS)??{},batchQueue:other.get(QueueStatuses.BATCH_QUEUE)??[],queue:other.get(QueueStatuses.QUEUE)??[]};const trackMessageIds=[];const addConcatQueue=(queue,incrementAttemptNumberBy)=>{const concatIterator=el=>{const id=el.id??generateUUID();if(trackMessageIds.includes(id));else {our.queue.push({item:el.item,attemptNumber:el.attemptNumber+incrementAttemptNumberBy,time:this.schedule.now(),id});trackMessageIds.push(id);}};if(Array.isArray(queue)){queue.forEach(concatIterator);}else if(queue){Object.values(queue).forEach(concatIterator);}};// add their queue to ours, resetting run-time to immediate and copying the attempt#
799
801
  addConcatQueue(their.queue,0);// Process batch queue items
800
802
  if(this.batch.enabled){their.batchQueue.forEach(el=>{const id=el.id??generateUUID();if(trackMessageIds.includes(id));else {this.enqueue(el);trackMessageIds.push(id);}});}else {// if batching is not enabled in the current instance, add those items to the main queue directly
801
803
  addConcatQueue(their.batchQueue,0);}// if the queue is abandoned, all the in-progress are failed. retry them immediately and increment the attempt#
802
804
  addConcatQueue(their.inProgress,1);our.queue=our.queue.sort(sortByTime);this.setStorageEntry(QueueStatuses.QUEUE,our.queue);// remove all keys one by on next tick to avoid NS_ERROR_STORAGE_BUSY error
803
805
  this.clearQueueEntries(other,1);// process the new items we claimed
804
806
  this.processHead();}// eslint-disable-next-line class-methods-use-this
805
- clearQueueEntries(other,localStorageBackoff){this.removeStorageEntry(other,0,localStorageBackoff);}removeStorageEntry(store,entryIdx,backoff,attempt=1){const maxAttempts=2;globalThis.setTimeout(()=>{const queueEntryKeys=Object.keys(QueueStatuses);const entry=QueueStatuses[queueEntryKeys[entryIdx]];try{store.remove(entry);// clear the next entry
807
+ clearQueueEntries(other,localStorageBackoff){this.removeStorageEntry(other,0,localStorageBackoff);}removeStorageEntry(store,entryIdx,backoff,attempt=1){const maxAttempts=2;const queueEntryKeys=Object.keys(QueueStatuses);const entry=QueueStatuses[queueEntryKeys[entryIdx]];globalThis.setTimeout(()=>{try{store.remove(entry);// clear the next entry
806
808
  if(entryIdx+1<queueEntryKeys.length){this.removeStorageEntry(store,entryIdx+1,backoff);}}catch(err){const storageBusyErr='NS_ERROR_STORAGE_BUSY';const isLocalStorageBusy=err.name===storageBusyErr||err.code===storageBusyErr||err.code===0x80630001;if(isLocalStorageBusy&&attempt<maxAttempts){// Try clearing the same entry again with some extra delay
807
- this.removeStorageEntry(store,entryIdx,backoff+40,attempt+1);}else {this.logger?.error(RETRY_QUEUE_ENTRY_REMOVE_ERROR(RETRY_QUEUE,entry,attempt),err);}// clear the next entry
808
- if(attempt===maxAttempts&&entryIdx+1<queueEntryKeys.length){this.removeStorageEntry(store,entryIdx+1,backoff);}}},backoff);}checkReclaim(){const createReclaimStartTask=store=>()=>{if(store.get(QueueStatuses.RECLAIM_END)!==this.id){return;}if(store.get(QueueStatuses.RECLAIM_START)!==this.id){return;}this.reclaim(store.id);};const createReclaimEndTask=store=>()=>{if(store.get(QueueStatuses.RECLAIM_START)!==this.id){return;}store.set(QueueStatuses.RECLAIM_END,this.id);this.schedule.run(createReclaimStartTask(store),this.timeouts.reclaimWait,ScheduleModes.ABANDON);};const tryReclaim=store=>{store.set(QueueStatuses.RECLAIM_START,this.id);store.set(QueueStatuses.ACK,this.schedule.now());this.schedule.run(createReclaimEndTask(store),this.timeouts.reclaimWait,ScheduleModes.ABANDON);};const findOtherQueues=name=>{const res=[];const storage=this.store.getOriginalEngine();for(let i=0;i<storage.length;i++){const k=storage.key(i);const parts=k?k.split('.'):[];if(parts.length!==3){// eslint-disable-next-line no-continue
809
- continue;}if(parts[0]!==name){// eslint-disable-next-line no-continue
810
- continue;}if(parts[2]!==QueueStatuses.ACK){// eslint-disable-next-line no-continue
811
- continue;}res.push(this.storeManager.setStore({id:parts[1],name,validKeys:QueueStatuses,type:LOCAL_STORAGE}));}return res;};findOtherQueues(this.name).forEach(store=>{if(store.id===this.id){return;}if(this.schedule.now()-store.get(QueueStatuses.ACK)<this.timeouts.reclaimTimeout){return;}tryReclaim(store);});this.schedule.run(this.checkReclaim,this.timeouts.reclaimTimer,ScheduleModes.RESCHEDULE);}clear(){this.schedule.cancelAll();this.setDefaultQueueEntries();}}
809
+ this.removeStorageEntry(store,entryIdx,backoff+40,attempt+1);}else {this.logger?.error(RETRY_QUEUE_ENTRY_REMOVE_ERROR(RETRY_QUEUE,entry,attempt),err);}// clear the next entry after we've exhausted our attempts
810
+ if(attempt===maxAttempts&&entryIdx+1<queueEntryKeys.length){this.removeStorageEntry(store,entryIdx+1,backoff);}}},backoff);}checkReclaim(){const createReclaimStartTask=store=>()=>{if(store.get(QueueStatuses.RECLAIM_END)!==this.id){return;}if(store.get(QueueStatuses.RECLAIM_START)!==this.id){return;}this.reclaim(store.id);};const createReclaimEndTask=store=>()=>{if(store.get(QueueStatuses.RECLAIM_START)!==this.id){return;}store.set(QueueStatuses.RECLAIM_END,this.id);this.schedule.run(createReclaimStartTask(store),this.timeouts.reclaimWait,ScheduleModes.ABANDON);};const tryReclaim=store=>{store.set(QueueStatuses.RECLAIM_START,this.id);store.set(QueueStatuses.ACK,this.schedule.now());this.schedule.run(createReclaimEndTask(store),this.timeouts.reclaimWait,ScheduleModes.ABANDON);};const findOtherQueues=name=>{const res=[];const storageKeys=this.store.getOriginalEngine().keys();storageKeys.forEach(k=>{const keyParts=k?k.split('.'):[];if(keyParts.length>=3&&keyParts[0]===name&&keyParts[1]!==this.id&&keyParts[2]===QueueStatuses.ACK){res.push(this.storeManager.setStore({id:keyParts[1],name,validKeys:QueueStatuses,type:LOCAL_STORAGE}));}});return res;};findOtherQueues(this.name).forEach(store=>{if(this.schedule.now()-store.get(QueueStatuses.ACK)<this.timeouts.reclaimTimeout){return;}tryReclaim(store);});this.schedule.run(this.checkReclaim,this.timeouts.reclaimTimer,ScheduleModes.RESCHEDULE);}clear(){this.schedule.cancelAll();this.setDefaultQueueEntries();}}
812
811
 
813
812
  const pluginName$e='BeaconQueue';const BeaconQueue=()=>({name:pluginName$e,deps:[],initialize:state=>{state.plugins.loadedPlugins.value=[...state.plugins.loadedPlugins.value,pluginName$e];},dataplaneEventsQueue:{/**
814
813
  * Initialize the queue for delivery
@@ -2465,13 +2464,12 @@ clear(){// Not implemented
2465
2464
  // getting a list of all cookie storage keys and remove all values
2466
2465
  // sounds risky to do as it will take on all top domain cookies
2467
2466
  // better to explicitly clear specific ones if needed
2468
- }// This cannot be implemented for cookies
2469
- // eslint-disable-next-line class-methods-use-this
2470
- key(index){const cookies=cookie();const cookieNames=Object.keys(cookies);return isUndefined(cookieNames[index])?null:cookieNames[index];}}
2467
+ }key(index){const curKeys=this.keys();return curKeys[index]??null;}// eslint-disable-next-line class-methods-use-this
2468
+ keys(){return Object.keys(cookie());}}
2471
2469
 
2472
2470
  /**
2473
2471
  * A storage utility to retain values in memory via Storage interface
2474
- */class InMemoryStorage{isEnabled=true;length=0;data={};constructor(options,logger){this.options=getDefaultInMemoryStorageOptions();this.logger=logger;this.configure(options??{});}configure(options){this.options=mergeDeepRight(this.options,options);this.isEnabled=Boolean(this.options.enabled);return this.options;}setItem(key,value){this.data[key]=value;this.length=Object.keys(this.data).length;return value;}getItem(key){if(key in this.data){return this.data[key];}return null;}removeItem(key){if(key in this.data){delete this.data[key];}this.length=Object.keys(this.data).length;return null;}clear(){this.data={};this.length=0;}key(index){return Object.keys(this.data)[index]?Object.keys(this.data)[index]:null;}}const defaultInMemoryStorage=new InMemoryStorage({},defaultLogger);
2472
+ */class InMemoryStorage{isEnabled=true;length=0;data={};constructor(options,logger){this.options=getDefaultInMemoryStorageOptions();this.logger=logger;this.configure(options??{});}configure(options){this.options=mergeDeepRight(this.options,options);this.isEnabled=Boolean(this.options.enabled);return this.options;}setItem(key,value){this.data[key]=value;this.length=Object.keys(this.data).length;return value;}getItem(key){if(key in this.data){return this.data[key];}return null;}removeItem(key){if(key in this.data){delete this.data[key];}this.length=Object.keys(this.data).length;return null;}clear(){this.data={};this.length=0;}key(index){const curKeys=this.keys();return curKeys[index]??null;}keys(){return Object.keys(this.data);}}const defaultInMemoryStorage=new InMemoryStorage({},defaultLogger);
2475
2473
 
2476
2474
  var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
2477
2475
 
@@ -2494,12 +2492,12 @@ if(key===undefined){var ret={};this.forEach(function(key,val){return ret[key]=va
2494
2492
  /**
2495
2493
  * A storage utility to persist values in localstorage via Storage interface
2496
2494
  */class LocalStorage{isSupportAvailable=true;isEnabled=true;length=0;constructor(options={},logger){this.options=getDefaultLocalStorageOptions();this.logger=logger;this.configure(options);}configure(options){this.options=mergeDeepRight(this.options,options);this.isSupportAvailable=isStorageAvailable(LOCAL_STORAGE,this,this.logger);this.isEnabled=Boolean(this.options.enabled&&this.isSupportAvailable);return this.options;}setItem(key,value){store.set(key,value);this.length=store.keys().length;}// eslint-disable-next-line class-methods-use-this
2497
- 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
2498
- key(index){return store.keys()[index]?store.keys()[index]:null;}}const defaultLocalStorage=new LocalStorage({},defaultLogger);
2495
+ 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;}key(index){const curKeys=this.keys();return curKeys[index]??null;}// eslint-disable-next-line class-methods-use-this
2496
+ keys(){return store.keys();}}const defaultLocalStorage=new LocalStorage({},defaultLogger);
2499
2497
 
2500
2498
  /**
2501
2499
  * A storage utility to persist values in SessionStorage via Storage interface
2502
- */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);
2500
+ */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);}keys(){const keys=[];for(let i=0;i<this.store.length;i+=1){const key=this.store.key(i);if(key!==null){keys.push(key);}}return keys;}}const defaultSessionStorage=new SessionStorage({},defaultLogger);
2503
2501
 
2504
2502
  /**
2505
2503
  * A utility to retrieve the storage singleton instance by type
@@ -2671,7 +2669,7 @@ validOptions.consentManagement=mergeDeepRight(clonedOptions.consentManagement,{e
2671
2669
  * @param consentManagementOpts consent management options
2672
2670
  * @param logger logger instance
2673
2671
  * @returns Corresponding provider and plugin name of the selected consent manager from the supported consent managers
2674
- */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
2672
+ */const getConsentManagerInfo=(consentManagementOpts,logger)=>{let{provider}=consentManagementOpts;const consentManagerPluginName=provider?ConsentManagersToPluginNameMap[provider]:undefined;if(provider&&!consentManagerPluginName){logger?.error(UNSUPPORTED_CONSENT_MANAGER_ERROR(CONFIG_MANAGER,provider,ConsentManagersToPluginNameMap));// Reset the provider value
2675
2673
  provider=undefined;}return {provider,consentManagerPluginName};};/**
2676
2674
  * Validates and converts the consent management options into a normalized format
2677
2675
  * @param consentManagementOpts Consent management options provided by the user