@rudderstack/analytics-js 3.11.0 → 3.11.1

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.
@@ -343,74 +343,37 @@
343
343
  * @returns decoded string
344
344
  */const fromBase64=value=>new TextDecoder().decode(base64ToBytes(value));
345
345
 
346
- const LOG_CONTEXT_SEPARATOR=':: ';const SCRIPT_ALREADY_EXISTS_ERROR=id=>`A script with the id "${id}" is already loaded. Skipping the loading of this script to prevent conflicts.`;const SCRIPT_LOAD_ERROR=(id,url)=>`Failed to load the script with the id "${id}" from URL "${url}".`;const SCRIPT_LOAD_TIMEOUT_ERROR=(id,url,timeout)=>`A timeout of ${timeout} ms occurred while trying to load the script with id "${id}" from URL "${url}".`;const CIRCULAR_REFERENCE_WARNING=(context,key)=>`${context}${LOG_CONTEXT_SEPARATOR}A circular reference has been detected in the object and the property "${key}" has been dropped from the output.`;const JSON_STRINGIFY_WARNING=`Failed to convert the value to a JSON string.`;
347
-
348
- const JSON_STRINGIFY='JSONStringify';const getCircularReplacer=(excludeNull,excludeKeys,logger)=>{const ancestors=[];// Here we do not want to use arrow function to use "this" in function context
349
- // eslint-disable-next-line func-names
350
- return function(key,value){if(excludeKeys?.includes(key)){return undefined;}if(excludeNull&&isNullOrUndefined(value)){return undefined;}if(typeof value!=='object'||isNull(value)){return value;}// `this` is the object that value is contained in, i.e., its direct parent.
351
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
352
- // @ts-ignore-next-line
353
- while(ancestors.length>0&&ancestors[ancestors.length-1]!==this){ancestors.pop();}if(ancestors.includes(value)){logger?.warn(CIRCULAR_REFERENCE_WARNING(JSON_STRINGIFY,key));return '[Circular Reference]';}ancestors.push(value);return value;};};/**
354
- * Utility method for JSON stringify object excluding null values & circular references
355
- *
356
- * @param {*} value input
357
- * @param {boolean} excludeNull if it should exclude nul or not
358
- * @param {function} logger optional logger methods for warning
359
- * @returns string
360
- */const stringifyWithoutCircular=(value,excludeNull,excludeKeys,logger)=>{try{return JSON.stringify(value,getCircularReplacer(excludeNull,excludeKeys,logger));}catch(err){logger?.warn(JSON_STRINGIFY_WARNING,err);return null;}};const getReplacer=logger=>{const ancestors=[];// Array to track ancestor objects
361
- // Using a regular function to use `this` for the parent context
362
- return function replacer(key,value){if(isBigInt(value)){return '[BigInt]';// Replace BigInt values
363
- }// `this` is the object that value is contained in, i.e., its direct parent.
364
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
365
- // @ts-ignore-next-line
366
- while(ancestors.length>0&&ancestors[ancestors.length-1]!==this){ancestors.pop();// Remove ancestors that are no longer part of the chain
367
- }// Check for circular references (if the value is already in the ancestors)
368
- if(ancestors.includes(value)){return '[Circular Reference]';}// Add current value to ancestors
369
- ancestors.push(value);return value;};};const traverseWithThis=(obj,replacer)=>{// Create a new result object or array
370
- const result=Array.isArray(obj)?[]:{};// Traverse object properties or array elements
371
- // eslint-disable-next-line no-restricted-syntax
372
- for(const key in obj){if(Object.hasOwnProperty.call(obj,key)){const value=obj[key];// Recursively apply the replacer and traversal
373
- const sanitizedValue=replacer.call(obj,key,value);// If the value is an object or array, continue traversal
374
- if(isObjectLiteralAndNotNull(sanitizedValue)||Array.isArray(sanitizedValue)){result[key]=traverseWithThis(sanitizedValue,replacer);}else {result[key]=sanitizedValue;}}}return result;};/**
375
- * Recursively traverses an object similar to JSON.stringify,
376
- * sanitizing BigInts and circular references
377
- * @param value Input object
378
- * @param logger Logger instance
379
- * @returns Sanitized value
380
- */const getSanitizedValue=(value,logger)=>{const replacer=getReplacer();// This is needed for registering the first ancestor
381
- const newValue=replacer.call(value,'',value);if(isObjectLiteralAndNotNull(value)||Array.isArray(value)){return traverseWithThis(value,replacer);}return newValue;};
382
-
383
346
  // if yes make them null instead of omitting in overloaded cases
384
347
  /*
385
348
  * Normalise the overloaded arguments of the page call facade
386
- */const pageArgumentsToCallOptions=(category,name,properties,options,callback)=>{const sanitizedCategory=getSanitizedValue(category);const sanitizedName=getSanitizedValue(name);const sanitizedProperties=getSanitizedValue(properties);const sanitizedOptions=getSanitizedValue(options);const sanitizedCallback=getSanitizedValue(callback);const payload={category:sanitizedCategory,name:sanitizedName,properties:sanitizedProperties,options:sanitizedOptions,callback:undefined};if(isFunction(sanitizedCallback)){payload.callback=sanitizedCallback;}if(isFunction(sanitizedOptions)){payload.category=sanitizedCategory;payload.name=sanitizedName;payload.properties=sanitizedProperties;payload.options=undefined;payload.callback=sanitizedOptions;}if(isFunction(sanitizedProperties)){payload.category=sanitizedCategory;payload.name=sanitizedName;payload.properties=undefined;payload.options=undefined;payload.callback=sanitizedProperties;}if(isFunction(sanitizedName)){payload.category=sanitizedCategory;payload.name=undefined;payload.properties=undefined;payload.options=undefined;payload.callback=sanitizedName;}if(isFunction(sanitizedCategory)){payload.category=undefined;payload.name=undefined;payload.properties=undefined;payload.options=undefined;payload.callback=sanitizedCategory;}if(isObjectLiteralAndNotNull(sanitizedCategory)){payload.name=undefined;payload.category=undefined;payload.properties=sanitizedCategory;if(!isFunction(sanitizedName)){payload.options=sanitizedName;}else {payload.options=undefined;}}else if(isObjectLiteralAndNotNull(sanitizedName)){payload.name=undefined;payload.properties=sanitizedName;if(!isFunction(sanitizedProperties)){payload.options=sanitizedProperties;}else {payload.options=undefined;}}// if the category argument alone is provided b/w category and name,
349
+ */const pageArgumentsToCallOptions=(category,name,properties,options,callback)=>{const payload={category:category,name:name,properties:properties,options:options,callback:undefined};if(isFunction(callback)){payload.callback=callback;}if(isFunction(options)){payload.category=category;payload.name=name;payload.properties=properties;payload.options=undefined;payload.callback=options;}if(isFunction(properties)){payload.category=category;payload.name=name;payload.properties=undefined;payload.options=undefined;payload.callback=properties;}if(isFunction(name)){payload.category=category;payload.name=undefined;payload.properties=undefined;payload.options=undefined;payload.callback=name;}if(isFunction(category)){payload.category=undefined;payload.name=undefined;payload.properties=undefined;payload.options=undefined;payload.callback=category;}if(isObjectLiteralAndNotNull(category)){payload.name=undefined;payload.category=undefined;payload.properties=category;if(!isFunction(name)){payload.options=name;}else {payload.options=undefined;}}else if(isObjectLiteralAndNotNull(name)){payload.name=undefined;payload.properties=name;if(!isFunction(properties)){payload.options=properties;}else {payload.options=undefined;}}// if the category argument alone is provided b/w category and name,
387
350
  // use it as name and set category to undefined
388
- if(isString(sanitizedCategory)&&!isString(sanitizedName)){payload.category=undefined;payload.name=sanitizedCategory;}// Rest of the code is just to clean up undefined values
351
+ if(isString(category)&&!isString(name)){payload.category=undefined;payload.name=category;}// Rest of the code is just to clean up undefined values
389
352
  // and set some proper defaults
390
353
  // Also, to clone the incoming object type arguments
391
354
  if(!isDefined(payload.category)){payload.category=undefined;}if(!isDefined(payload.name)){payload.name=undefined;}payload.properties=payload.properties?clone(payload.properties):{};if(isDefined(payload.options)){payload.options=clone(payload.options);}else {payload.options=undefined;}const nameForProperties=isString(payload.name)?payload.name:payload.properties.name;const categoryForProperties=isString(payload.category)?payload.category:payload.properties.category;// add name and category to properties
392
355
  payload.properties=mergeDeepRight(isObjectLiteralAndNotNull(payload.properties)?payload.properties:{},{...(nameForProperties&&{name:nameForProperties}),...(categoryForProperties&&{category:categoryForProperties})});return payload;};/*
393
356
  * Normalise the overloaded arguments of the track call facade
394
- */const trackArgumentsToCallOptions=(event,properties,options,callback)=>{const sanitizedEvent=getSanitizedValue(event);const sanitizedProperties=getSanitizedValue(properties);const sanitizedOptions=getSanitizedValue(options);const sanitizedCallback=getSanitizedValue(callback);const payload={name:sanitizedEvent,properties:sanitizedProperties,options:sanitizedOptions,callback:undefined};if(isFunction(sanitizedCallback)){payload.callback=sanitizedCallback;}if(isFunction(sanitizedOptions)){payload.properties=sanitizedProperties;payload.options=undefined;payload.callback=sanitizedOptions;}if(isFunction(sanitizedProperties)){payload.properties=undefined;payload.options=undefined;payload.callback=sanitizedProperties;}// Rest of the code is just to clean up undefined values
357
+ */const trackArgumentsToCallOptions=(event,properties,options,callback)=>{const payload={name:event,properties:properties,options:options,callback:undefined};if(isFunction(callback)){payload.callback=callback;}if(isFunction(options)){payload.properties=properties;payload.options=undefined;payload.callback=options;}if(isFunction(properties)){payload.properties=undefined;payload.options=undefined;payload.callback=properties;}// Rest of the code is just to clean up undefined values
395
358
  // and set some proper defaults
396
359
  // Also, to clone the incoming object type arguments
397
360
  payload.properties=isDefinedAndNotNull(payload.properties)?clone(payload.properties):{};if(isDefined(payload.options)){payload.options=clone(payload.options);}else {payload.options=undefined;}return payload;};/*
398
361
  * Normalise the overloaded arguments of the identify call facade
399
- */const identifyArgumentsToCallOptions=(userId,traits,options,callback)=>{const sanitizedUserId=getSanitizedValue(userId);const sanitizedTraits=getSanitizedValue(traits);const sanitizedOptions=getSanitizedValue(options);const sanitizedCallback=getSanitizedValue(callback);const payload={userId:sanitizedUserId,traits:sanitizedTraits,options:sanitizedOptions,callback:undefined};if(isFunction(sanitizedCallback)){payload.callback=sanitizedCallback;}if(isFunction(sanitizedOptions)){payload.userId=sanitizedUserId;payload.traits=sanitizedTraits;payload.options=undefined;payload.callback=sanitizedOptions;}if(isFunction(sanitizedTraits)){payload.userId=sanitizedUserId;payload.traits=undefined;payload.options=undefined;payload.callback=sanitizedTraits;}if(isObjectLiteralAndNotNull(sanitizedUserId)||isNull(sanitizedUserId)){// Explicitly set null to prevent resetting the existing value
362
+ */const identifyArgumentsToCallOptions=(userId,traits,options,callback)=>{const payload={userId:userId,traits:traits,options:options,callback:undefined};if(isFunction(callback)){payload.callback=callback;}if(isFunction(options)){payload.userId=userId;payload.traits=traits;payload.options=undefined;payload.callback=options;}if(isFunction(traits)){payload.userId=userId;payload.traits=undefined;payload.options=undefined;payload.callback=traits;}if(isObjectLiteralAndNotNull(userId)||isNull(userId)){// Explicitly set null to prevent resetting the existing value
400
363
  // in the Analytics class
401
- payload.userId=null;payload.traits=sanitizedUserId;if(!isFunction(sanitizedTraits)){payload.options=sanitizedTraits;}else {payload.options=undefined;}}// Rest of the code is just to clean up undefined values
364
+ payload.userId=null;payload.traits=userId;if(!isFunction(traits)){payload.options=traits;}else {payload.options=undefined;}}// Rest of the code is just to clean up undefined values
402
365
  // and set some proper defaults
403
366
  // Also, to clone the incoming object type arguments
404
367
  payload.userId=tryStringify(payload.userId);if(isObjectLiteralAndNotNull(payload.traits)){payload.traits=clone(payload.traits);}else {payload.traits=undefined;}if(isDefined(payload.options)){payload.options=clone(payload.options);}else {payload.options=undefined;}return payload;};/*
405
368
  * Normalise the overloaded arguments of the alias call facade
406
- */const aliasArgumentsToCallOptions=(to,from,options,callback)=>{const sanitizedTo=getSanitizedValue(to);const sanitizedFrom=getSanitizedValue(from);const sanitizedOptions=getSanitizedValue(options);const sanitizedCallback=getSanitizedValue(callback);const payload={to:sanitizedTo,from:sanitizedFrom,options:sanitizedOptions,callback:undefined};if(isFunction(sanitizedCallback)){payload.callback=sanitizedCallback;}if(isFunction(sanitizedOptions)){payload.to=sanitizedTo;payload.from=sanitizedFrom;payload.options=undefined;payload.callback=sanitizedOptions;}if(isFunction(sanitizedFrom)){payload.to=sanitizedTo;payload.from=undefined;payload.options=undefined;payload.callback=sanitizedFrom;}else if(isObjectLiteralAndNotNull(sanitizedFrom)||isNull(sanitizedFrom)){payload.to=sanitizedTo;payload.from=undefined;payload.options=sanitizedFrom;}// Rest of the code is just to clean up undefined values
369
+ */const aliasArgumentsToCallOptions=(to,from,options,callback)=>{const payload={to,from:from,options:options,callback:undefined};if(isFunction(callback)){payload.callback=callback;}if(isFunction(options)){payload.to=to;payload.from=from;payload.options=undefined;payload.callback=options;}if(isFunction(from)){payload.to=to;payload.from=undefined;payload.options=undefined;payload.callback=from;}else if(isObjectLiteralAndNotNull(from)||isNull(from)){payload.to=to;payload.from=undefined;payload.options=from;}// Rest of the code is just to clean up undefined values
407
370
  // and set some proper defaults
408
371
  // Also, to clone the incoming object type arguments
409
372
  if(isDefined(payload.to)){payload.to=tryStringify(payload.to);}if(isDefined(payload.from)){payload.from=tryStringify(payload.from);}else {payload.from=undefined;}if(isDefined(payload.options)){payload.options=clone(payload.options);}else {payload.options=undefined;}return payload;};/*
410
373
  * Normalise the overloaded arguments of the group call facade
411
- */const groupArgumentsToCallOptions=(groupId,traits,options,callback)=>{const sanitizedGroupId=getSanitizedValue(groupId);const sanitizedTraits=getSanitizedValue(traits);const sanitizedOptions=getSanitizedValue(options);const sanitizedCallback=getSanitizedValue(callback);const payload={groupId:sanitizedGroupId,traits:sanitizedTraits,options:sanitizedOptions,callback:undefined};if(isFunction(sanitizedCallback)){payload.callback=sanitizedCallback;}if(isFunction(sanitizedOptions)){payload.groupId=sanitizedGroupId;payload.traits=sanitizedTraits;payload.options=undefined;payload.callback=sanitizedOptions;}if(isFunction(sanitizedTraits)){payload.groupId=sanitizedGroupId;payload.traits=undefined;payload.options=undefined;payload.callback=sanitizedTraits;}if(isObjectLiteralAndNotNull(sanitizedGroupId)||isNull(sanitizedGroupId)){// Explicitly set null to prevent resetting the existing value
374
+ */const groupArgumentsToCallOptions=(groupId,traits,options,callback)=>{const payload={groupId:groupId,traits:traits,options:options,callback:undefined};if(isFunction(callback)){payload.callback=callback;}if(isFunction(options)){payload.groupId=groupId;payload.traits=traits;payload.options=undefined;payload.callback=options;}if(isFunction(traits)){payload.groupId=groupId;payload.traits=undefined;payload.options=undefined;payload.callback=traits;}if(isObjectLiteralAndNotNull(groupId)||isNull(groupId)){// Explicitly set null to prevent resetting the existing value
412
375
  // in the Analytics class
413
- payload.groupId=null;payload.traits=sanitizedGroupId;if(!isFunction(sanitizedTraits)){payload.options=sanitizedTraits;}else {payload.options=undefined;}}// Rest of the code is just to clean up undefined values
376
+ payload.groupId=null;payload.traits=groupId;if(!isFunction(traits)){payload.options=traits;}else {payload.options=undefined;}}// Rest of the code is just to clean up undefined values
414
377
  // and set some proper defaults
415
378
  // Also, to clone the incoming object type arguments
416
379
  payload.groupId=tryStringify(payload.groupId);if(isObjectLiteralAndNotNull(payload.traits)){payload.traits=clone(payload.traits);}else {payload.traits=undefined;}if(isDefined(payload.options)){payload.options=clone(payload.options);}else {payload.options=undefined;}return payload;};
@@ -458,6 +421,43 @@
458
421
  * @returns ISO formatted timestamp string
459
422
  */const getCurrentTimeFormatted=()=>getFormattedTimestamp(new Date());
460
423
 
424
+ const LOG_CONTEXT_SEPARATOR=':: ';const SCRIPT_ALREADY_EXISTS_ERROR=id=>`A script with the id "${id}" is already loaded. Skipping the loading of this script to prevent conflicts.`;const SCRIPT_LOAD_ERROR=(id,url)=>`Failed to load the script with the id "${id}" from URL "${url}".`;const SCRIPT_LOAD_TIMEOUT_ERROR=(id,url,timeout)=>`A timeout of ${timeout} ms occurred while trying to load the script with id "${id}" from URL "${url}".`;const CIRCULAR_REFERENCE_WARNING=(context,key)=>`${context}${LOG_CONTEXT_SEPARATOR}A circular reference has been detected in the object and the property "${key}" has been dropped from the output.`;const JSON_STRINGIFY_WARNING=`Failed to convert the value to a JSON string.`;
425
+
426
+ const JSON_STRINGIFY='JSONStringify';const getCircularReplacer=(excludeNull,excludeKeys,logger)=>{const ancestors=[];// Here we do not want to use arrow function to use "this" in function context
427
+ // eslint-disable-next-line func-names
428
+ return function(key,value){if(excludeKeys?.includes(key)){return undefined;}if(excludeNull&&isNullOrUndefined(value)){return undefined;}if(typeof value!=='object'||isNull(value)){return value;}// `this` is the object that value is contained in, i.e., its direct parent.
429
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
430
+ // @ts-ignore-next-line
431
+ while(ancestors.length>0&&ancestors[ancestors.length-1]!==this){ancestors.pop();}if(ancestors.includes(value)){logger?.warn(CIRCULAR_REFERENCE_WARNING(JSON_STRINGIFY,key));return '[Circular Reference]';}ancestors.push(value);return value;};};/**
432
+ * Utility method for JSON stringify object excluding null values & circular references
433
+ *
434
+ * @param {*} value input
435
+ * @param {boolean} excludeNull if it should exclude nul or not
436
+ * @param {function} logger optional logger methods for warning
437
+ * @returns string
438
+ */const stringifyWithoutCircular=(value,excludeNull,excludeKeys,logger)=>{try{return JSON.stringify(value,getCircularReplacer(excludeNull,excludeKeys,logger));}catch(err){logger?.warn(JSON_STRINGIFY_WARNING,err);return null;}};const getReplacer=logger=>{const ancestors=[];// Array to track ancestor objects
439
+ // Using a regular function to use `this` for the parent context
440
+ return function replacer(key,value){if(isBigInt(value)){return '[BigInt]';// Replace BigInt values
441
+ }// `this` is the object that value is contained in, i.e., its direct parent.
442
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
443
+ // @ts-ignore-next-line
444
+ while(ancestors.length>0&&ancestors[ancestors.length-1]!==this){ancestors.pop();// Remove ancestors that are no longer part of the chain
445
+ }// Check for circular references (if the value is already in the ancestors)
446
+ if(ancestors.includes(value)){return '[Circular Reference]';}// Add current value to ancestors
447
+ ancestors.push(value);return value;};};const traverseWithThis=(obj,replacer)=>{// Create a new result object or array
448
+ const result=Array.isArray(obj)?[]:{};// Traverse object properties or array elements
449
+ // eslint-disable-next-line no-restricted-syntax
450
+ for(const key in obj){if(Object.hasOwnProperty.call(obj,key)){const value=obj[key];// Recursively apply the replacer and traversal
451
+ const sanitizedValue=replacer.call(obj,key,value);// If the value is an object or array, continue traversal
452
+ if(isObjectLiteralAndNotNull(sanitizedValue)||Array.isArray(sanitizedValue)){result[key]=traverseWithThis(sanitizedValue,replacer);}else {result[key]=sanitizedValue;}}}return result;};/**
453
+ * Recursively traverses an object similar to JSON.stringify,
454
+ * sanitizing BigInts and circular references
455
+ * @param value Input object
456
+ * @param logger Logger instance
457
+ * @returns Sanitized value
458
+ */const getSanitizedValue=(value,logger)=>{const replacer=getReplacer();// This is needed for registering the first ancestor
459
+ const newValue=replacer.call(value,'',value);if(isObjectLiteralAndNotNull(value)||Array.isArray(value)){return traverseWithThis(value,replacer);}return newValue;};
460
+
461
461
  const MANUAL_ERROR_IDENTIFIER='[MANUAL ERROR]';/**
462
462
  * Get mutated error with issue prepended to error message
463
463
  * @param err Original error
@@ -465,7 +465,7 @@
465
465
  * @returns Instance of Error with message prepended with issue
466
466
  */const getMutatedError=(err,issue)=>{let finalError=err;if(!isTypeOfError(err)){finalError=new Error(`${issue}: ${stringifyWithoutCircular(err)}`);}else {finalError.message=`${issue}: ${err.message}`;}return finalError;};const dispatchErrorEvent=error=>{if(isTypeOfError(error)){error.stack=`${error.stack??''}\n${MANUAL_ERROR_IDENTIFIER}`;}globalThis.dispatchEvent(new ErrorEvent('error',{error}));};
467
467
 
468
- const APP_NAME='RudderLabs JavaScript SDK';const APP_VERSION='3.11.0';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';
468
+ const APP_NAME='RudderLabs JavaScript SDK';const APP_VERSION='3.11.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';
469
469
 
470
470
  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';
471
471
 
@@ -328,74 +328,37 @@ const trim=value=>value.replace(/^\s+|\s+$/gm,'');const removeDoubleSpaces=value
328
328
  * @returns base64 encoded string
329
329
  */const toBase64=value=>bytesToBase64(new TextEncoder().encode(value));
330
330
 
331
- const LOG_CONTEXT_SEPARATOR=':: ';const SCRIPT_ALREADY_EXISTS_ERROR=id=>`A script with the id "${id}" is already loaded. Skipping the loading of this script to prevent conflicts.`;const SCRIPT_LOAD_ERROR=(id,url)=>`Failed to load the script with the id "${id}" from URL "${url}".`;const SCRIPT_LOAD_TIMEOUT_ERROR=(id,url,timeout)=>`A timeout of ${timeout} ms occurred while trying to load the script with id "${id}" from URL "${url}".`;const CIRCULAR_REFERENCE_WARNING=(context,key)=>`${context}${LOG_CONTEXT_SEPARATOR}A circular reference has been detected in the object and the property "${key}" has been dropped from the output.`;const JSON_STRINGIFY_WARNING=`Failed to convert the value to a JSON string.`;
332
-
333
- const JSON_STRINGIFY='JSONStringify';const getCircularReplacer=(excludeNull,excludeKeys,logger)=>{const ancestors=[];// Here we do not want to use arrow function to use "this" in function context
334
- // eslint-disable-next-line func-names
335
- return function(key,value){if(excludeKeys?.includes(key)){return undefined;}if(excludeNull&&isNullOrUndefined(value)){return undefined;}if(typeof value!=='object'||isNull(value)){return value;}// `this` is the object that value is contained in, i.e., its direct parent.
336
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
337
- // @ts-ignore-next-line
338
- while(ancestors.length>0&&ancestors[ancestors.length-1]!==this){ancestors.pop();}if(ancestors.includes(value)){logger?.warn(CIRCULAR_REFERENCE_WARNING(JSON_STRINGIFY,key));return '[Circular Reference]';}ancestors.push(value);return value;};};/**
339
- * Utility method for JSON stringify object excluding null values & circular references
340
- *
341
- * @param {*} value input
342
- * @param {boolean} excludeNull if it should exclude nul or not
343
- * @param {function} logger optional logger methods for warning
344
- * @returns string
345
- */const stringifyWithoutCircular=(value,excludeNull,excludeKeys,logger)=>{try{return JSON.stringify(value,getCircularReplacer(excludeNull,excludeKeys,logger));}catch(err){logger?.warn(JSON_STRINGIFY_WARNING,err);return null;}};const getReplacer=logger=>{const ancestors=[];// Array to track ancestor objects
346
- // Using a regular function to use `this` for the parent context
347
- return function replacer(key,value){if(isBigInt(value)){return '[BigInt]';// Replace BigInt values
348
- }// `this` is the object that value is contained in, i.e., its direct parent.
349
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
350
- // @ts-ignore-next-line
351
- while(ancestors.length>0&&ancestors[ancestors.length-1]!==this){ancestors.pop();// Remove ancestors that are no longer part of the chain
352
- }// Check for circular references (if the value is already in the ancestors)
353
- if(ancestors.includes(value)){return '[Circular Reference]';}// Add current value to ancestors
354
- ancestors.push(value);return value;};};const traverseWithThis=(obj,replacer)=>{// Create a new result object or array
355
- const result=Array.isArray(obj)?[]:{};// Traverse object properties or array elements
356
- // eslint-disable-next-line no-restricted-syntax
357
- for(const key in obj){if(Object.hasOwnProperty.call(obj,key)){const value=obj[key];// Recursively apply the replacer and traversal
358
- const sanitizedValue=replacer.call(obj,key,value);// If the value is an object or array, continue traversal
359
- if(isObjectLiteralAndNotNull(sanitizedValue)||Array.isArray(sanitizedValue)){result[key]=traverseWithThis(sanitizedValue,replacer);}else {result[key]=sanitizedValue;}}}return result;};/**
360
- * Recursively traverses an object similar to JSON.stringify,
361
- * sanitizing BigInts and circular references
362
- * @param value Input object
363
- * @param logger Logger instance
364
- * @returns Sanitized value
365
- */const getSanitizedValue=(value,logger)=>{const replacer=getReplacer();// This is needed for registering the first ancestor
366
- const newValue=replacer.call(value,'',value);if(isObjectLiteralAndNotNull(value)||Array.isArray(value)){return traverseWithThis(value,replacer);}return newValue;};
367
-
368
331
  // if yes make them null instead of omitting in overloaded cases
369
332
  /*
370
333
  * Normalise the overloaded arguments of the page call facade
371
- */const pageArgumentsToCallOptions=(category,name,properties,options,callback)=>{const sanitizedCategory=getSanitizedValue(category);const sanitizedName=getSanitizedValue(name);const sanitizedProperties=getSanitizedValue(properties);const sanitizedOptions=getSanitizedValue(options);const sanitizedCallback=getSanitizedValue(callback);const payload={category:sanitizedCategory,name:sanitizedName,properties:sanitizedProperties,options:sanitizedOptions,callback:undefined};if(isFunction(sanitizedCallback)){payload.callback=sanitizedCallback;}if(isFunction(sanitizedOptions)){payload.category=sanitizedCategory;payload.name=sanitizedName;payload.properties=sanitizedProperties;payload.options=undefined;payload.callback=sanitizedOptions;}if(isFunction(sanitizedProperties)){payload.category=sanitizedCategory;payload.name=sanitizedName;payload.properties=undefined;payload.options=undefined;payload.callback=sanitizedProperties;}if(isFunction(sanitizedName)){payload.category=sanitizedCategory;payload.name=undefined;payload.properties=undefined;payload.options=undefined;payload.callback=sanitizedName;}if(isFunction(sanitizedCategory)){payload.category=undefined;payload.name=undefined;payload.properties=undefined;payload.options=undefined;payload.callback=sanitizedCategory;}if(isObjectLiteralAndNotNull(sanitizedCategory)){payload.name=undefined;payload.category=undefined;payload.properties=sanitizedCategory;if(!isFunction(sanitizedName)){payload.options=sanitizedName;}else {payload.options=undefined;}}else if(isObjectLiteralAndNotNull(sanitizedName)){payload.name=undefined;payload.properties=sanitizedName;if(!isFunction(sanitizedProperties)){payload.options=sanitizedProperties;}else {payload.options=undefined;}}// if the category argument alone is provided b/w category and name,
334
+ */const pageArgumentsToCallOptions=(category,name,properties,options,callback)=>{const payload={category:category,name:name,properties:properties,options:options,callback:undefined};if(isFunction(callback)){payload.callback=callback;}if(isFunction(options)){payload.category=category;payload.name=name;payload.properties=properties;payload.options=undefined;payload.callback=options;}if(isFunction(properties)){payload.category=category;payload.name=name;payload.properties=undefined;payload.options=undefined;payload.callback=properties;}if(isFunction(name)){payload.category=category;payload.name=undefined;payload.properties=undefined;payload.options=undefined;payload.callback=name;}if(isFunction(category)){payload.category=undefined;payload.name=undefined;payload.properties=undefined;payload.options=undefined;payload.callback=category;}if(isObjectLiteralAndNotNull(category)){payload.name=undefined;payload.category=undefined;payload.properties=category;if(!isFunction(name)){payload.options=name;}else {payload.options=undefined;}}else if(isObjectLiteralAndNotNull(name)){payload.name=undefined;payload.properties=name;if(!isFunction(properties)){payload.options=properties;}else {payload.options=undefined;}}// if the category argument alone is provided b/w category and name,
372
335
  // use it as name and set category to undefined
373
- if(isString(sanitizedCategory)&&!isString(sanitizedName)){payload.category=undefined;payload.name=sanitizedCategory;}// Rest of the code is just to clean up undefined values
336
+ if(isString(category)&&!isString(name)){payload.category=undefined;payload.name=category;}// Rest of the code is just to clean up undefined values
374
337
  // and set some proper defaults
375
338
  // Also, to clone the incoming object type arguments
376
339
  if(!isDefined(payload.category)){payload.category=undefined;}if(!isDefined(payload.name)){payload.name=undefined;}payload.properties=payload.properties?clone(payload.properties):{};if(isDefined(payload.options)){payload.options=clone(payload.options);}else {payload.options=undefined;}const nameForProperties=isString(payload.name)?payload.name:payload.properties.name;const categoryForProperties=isString(payload.category)?payload.category:payload.properties.category;// add name and category to properties
377
340
  payload.properties=mergeDeepRight(isObjectLiteralAndNotNull(payload.properties)?payload.properties:{},{...(nameForProperties&&{name:nameForProperties}),...(categoryForProperties&&{category:categoryForProperties})});return payload;};/*
378
341
  * Normalise the overloaded arguments of the track call facade
379
- */const trackArgumentsToCallOptions=(event,properties,options,callback)=>{const sanitizedEvent=getSanitizedValue(event);const sanitizedProperties=getSanitizedValue(properties);const sanitizedOptions=getSanitizedValue(options);const sanitizedCallback=getSanitizedValue(callback);const payload={name:sanitizedEvent,properties:sanitizedProperties,options:sanitizedOptions,callback:undefined};if(isFunction(sanitizedCallback)){payload.callback=sanitizedCallback;}if(isFunction(sanitizedOptions)){payload.properties=sanitizedProperties;payload.options=undefined;payload.callback=sanitizedOptions;}if(isFunction(sanitizedProperties)){payload.properties=undefined;payload.options=undefined;payload.callback=sanitizedProperties;}// Rest of the code is just to clean up undefined values
342
+ */const trackArgumentsToCallOptions=(event,properties,options,callback)=>{const payload={name:event,properties:properties,options:options,callback:undefined};if(isFunction(callback)){payload.callback=callback;}if(isFunction(options)){payload.properties=properties;payload.options=undefined;payload.callback=options;}if(isFunction(properties)){payload.properties=undefined;payload.options=undefined;payload.callback=properties;}// Rest of the code is just to clean up undefined values
380
343
  // and set some proper defaults
381
344
  // Also, to clone the incoming object type arguments
382
345
  payload.properties=isDefinedAndNotNull(payload.properties)?clone(payload.properties):{};if(isDefined(payload.options)){payload.options=clone(payload.options);}else {payload.options=undefined;}return payload;};/*
383
346
  * Normalise the overloaded arguments of the identify call facade
384
- */const identifyArgumentsToCallOptions=(userId,traits,options,callback)=>{const sanitizedUserId=getSanitizedValue(userId);const sanitizedTraits=getSanitizedValue(traits);const sanitizedOptions=getSanitizedValue(options);const sanitizedCallback=getSanitizedValue(callback);const payload={userId:sanitizedUserId,traits:sanitizedTraits,options:sanitizedOptions,callback:undefined};if(isFunction(sanitizedCallback)){payload.callback=sanitizedCallback;}if(isFunction(sanitizedOptions)){payload.userId=sanitizedUserId;payload.traits=sanitizedTraits;payload.options=undefined;payload.callback=sanitizedOptions;}if(isFunction(sanitizedTraits)){payload.userId=sanitizedUserId;payload.traits=undefined;payload.options=undefined;payload.callback=sanitizedTraits;}if(isObjectLiteralAndNotNull(sanitizedUserId)||isNull(sanitizedUserId)){// Explicitly set null to prevent resetting the existing value
347
+ */const identifyArgumentsToCallOptions=(userId,traits,options,callback)=>{const payload={userId:userId,traits:traits,options:options,callback:undefined};if(isFunction(callback)){payload.callback=callback;}if(isFunction(options)){payload.userId=userId;payload.traits=traits;payload.options=undefined;payload.callback=options;}if(isFunction(traits)){payload.userId=userId;payload.traits=undefined;payload.options=undefined;payload.callback=traits;}if(isObjectLiteralAndNotNull(userId)||isNull(userId)){// Explicitly set null to prevent resetting the existing value
385
348
  // in the Analytics class
386
- payload.userId=null;payload.traits=sanitizedUserId;if(!isFunction(sanitizedTraits)){payload.options=sanitizedTraits;}else {payload.options=undefined;}}// Rest of the code is just to clean up undefined values
349
+ payload.userId=null;payload.traits=userId;if(!isFunction(traits)){payload.options=traits;}else {payload.options=undefined;}}// Rest of the code is just to clean up undefined values
387
350
  // and set some proper defaults
388
351
  // Also, to clone the incoming object type arguments
389
352
  payload.userId=tryStringify(payload.userId);if(isObjectLiteralAndNotNull(payload.traits)){payload.traits=clone(payload.traits);}else {payload.traits=undefined;}if(isDefined(payload.options)){payload.options=clone(payload.options);}else {payload.options=undefined;}return payload;};/*
390
353
  * Normalise the overloaded arguments of the alias call facade
391
- */const aliasArgumentsToCallOptions=(to,from,options,callback)=>{const sanitizedTo=getSanitizedValue(to);const sanitizedFrom=getSanitizedValue(from);const sanitizedOptions=getSanitizedValue(options);const sanitizedCallback=getSanitizedValue(callback);const payload={to:sanitizedTo,from:sanitizedFrom,options:sanitizedOptions,callback:undefined};if(isFunction(sanitizedCallback)){payload.callback=sanitizedCallback;}if(isFunction(sanitizedOptions)){payload.to=sanitizedTo;payload.from=sanitizedFrom;payload.options=undefined;payload.callback=sanitizedOptions;}if(isFunction(sanitizedFrom)){payload.to=sanitizedTo;payload.from=undefined;payload.options=undefined;payload.callback=sanitizedFrom;}else if(isObjectLiteralAndNotNull(sanitizedFrom)||isNull(sanitizedFrom)){payload.to=sanitizedTo;payload.from=undefined;payload.options=sanitizedFrom;}// Rest of the code is just to clean up undefined values
354
+ */const aliasArgumentsToCallOptions=(to,from,options,callback)=>{const payload={to,from:from,options:options,callback:undefined};if(isFunction(callback)){payload.callback=callback;}if(isFunction(options)){payload.to=to;payload.from=from;payload.options=undefined;payload.callback=options;}if(isFunction(from)){payload.to=to;payload.from=undefined;payload.options=undefined;payload.callback=from;}else if(isObjectLiteralAndNotNull(from)||isNull(from)){payload.to=to;payload.from=undefined;payload.options=from;}// Rest of the code is just to clean up undefined values
392
355
  // and set some proper defaults
393
356
  // Also, to clone the incoming object type arguments
394
357
  if(isDefined(payload.to)){payload.to=tryStringify(payload.to);}if(isDefined(payload.from)){payload.from=tryStringify(payload.from);}else {payload.from=undefined;}if(isDefined(payload.options)){payload.options=clone(payload.options);}else {payload.options=undefined;}return payload;};/*
395
358
  * Normalise the overloaded arguments of the group call facade
396
- */const groupArgumentsToCallOptions=(groupId,traits,options,callback)=>{const sanitizedGroupId=getSanitizedValue(groupId);const sanitizedTraits=getSanitizedValue(traits);const sanitizedOptions=getSanitizedValue(options);const sanitizedCallback=getSanitizedValue(callback);const payload={groupId:sanitizedGroupId,traits:sanitizedTraits,options:sanitizedOptions,callback:undefined};if(isFunction(sanitizedCallback)){payload.callback=sanitizedCallback;}if(isFunction(sanitizedOptions)){payload.groupId=sanitizedGroupId;payload.traits=sanitizedTraits;payload.options=undefined;payload.callback=sanitizedOptions;}if(isFunction(sanitizedTraits)){payload.groupId=sanitizedGroupId;payload.traits=undefined;payload.options=undefined;payload.callback=sanitizedTraits;}if(isObjectLiteralAndNotNull(sanitizedGroupId)||isNull(sanitizedGroupId)){// Explicitly set null to prevent resetting the existing value
359
+ */const groupArgumentsToCallOptions=(groupId,traits,options,callback)=>{const payload={groupId:groupId,traits:traits,options:options,callback:undefined};if(isFunction(callback)){payload.callback=callback;}if(isFunction(options)){payload.groupId=groupId;payload.traits=traits;payload.options=undefined;payload.callback=options;}if(isFunction(traits)){payload.groupId=groupId;payload.traits=undefined;payload.options=undefined;payload.callback=traits;}if(isObjectLiteralAndNotNull(groupId)||isNull(groupId)){// Explicitly set null to prevent resetting the existing value
397
360
  // in the Analytics class
398
- payload.groupId=null;payload.traits=sanitizedGroupId;if(!isFunction(sanitizedTraits)){payload.options=sanitizedTraits;}else {payload.options=undefined;}}// Rest of the code is just to clean up undefined values
361
+ payload.groupId=null;payload.traits=groupId;if(!isFunction(traits)){payload.options=traits;}else {payload.options=undefined;}}// Rest of the code is just to clean up undefined values
399
362
  // and set some proper defaults
400
363
  // Also, to clone the incoming object type arguments
401
364
  payload.groupId=tryStringify(payload.groupId);if(isObjectLiteralAndNotNull(payload.traits)){payload.traits=clone(payload.traits);}else {payload.traits=undefined;}if(isDefined(payload.options)){payload.options=clone(payload.options);}else {payload.options=undefined;}return payload;};
@@ -443,6 +406,43 @@ const getFormattedTimestamp=date=>date.toISOString();/**
443
406
  * @returns ISO formatted timestamp string
444
407
  */const getCurrentTimeFormatted=()=>getFormattedTimestamp(new Date());
445
408
 
409
+ const LOG_CONTEXT_SEPARATOR=':: ';const SCRIPT_ALREADY_EXISTS_ERROR=id=>`A script with the id "${id}" is already loaded. Skipping the loading of this script to prevent conflicts.`;const SCRIPT_LOAD_ERROR=(id,url)=>`Failed to load the script with the id "${id}" from URL "${url}".`;const SCRIPT_LOAD_TIMEOUT_ERROR=(id,url,timeout)=>`A timeout of ${timeout} ms occurred while trying to load the script with id "${id}" from URL "${url}".`;const CIRCULAR_REFERENCE_WARNING=(context,key)=>`${context}${LOG_CONTEXT_SEPARATOR}A circular reference has been detected in the object and the property "${key}" has been dropped from the output.`;const JSON_STRINGIFY_WARNING=`Failed to convert the value to a JSON string.`;
410
+
411
+ const JSON_STRINGIFY='JSONStringify';const getCircularReplacer=(excludeNull,excludeKeys,logger)=>{const ancestors=[];// Here we do not want to use arrow function to use "this" in function context
412
+ // eslint-disable-next-line func-names
413
+ return function(key,value){if(excludeKeys?.includes(key)){return undefined;}if(excludeNull&&isNullOrUndefined(value)){return undefined;}if(typeof value!=='object'||isNull(value)){return value;}// `this` is the object that value is contained in, i.e., its direct parent.
414
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
415
+ // @ts-ignore-next-line
416
+ while(ancestors.length>0&&ancestors[ancestors.length-1]!==this){ancestors.pop();}if(ancestors.includes(value)){logger?.warn(CIRCULAR_REFERENCE_WARNING(JSON_STRINGIFY,key));return '[Circular Reference]';}ancestors.push(value);return value;};};/**
417
+ * Utility method for JSON stringify object excluding null values & circular references
418
+ *
419
+ * @param {*} value input
420
+ * @param {boolean} excludeNull if it should exclude nul or not
421
+ * @param {function} logger optional logger methods for warning
422
+ * @returns string
423
+ */const stringifyWithoutCircular=(value,excludeNull,excludeKeys,logger)=>{try{return JSON.stringify(value,getCircularReplacer(excludeNull,excludeKeys,logger));}catch(err){logger?.warn(JSON_STRINGIFY_WARNING,err);return null;}};const getReplacer=logger=>{const ancestors=[];// Array to track ancestor objects
424
+ // Using a regular function to use `this` for the parent context
425
+ return function replacer(key,value){if(isBigInt(value)){return '[BigInt]';// Replace BigInt values
426
+ }// `this` is the object that value is contained in, i.e., its direct parent.
427
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
428
+ // @ts-ignore-next-line
429
+ while(ancestors.length>0&&ancestors[ancestors.length-1]!==this){ancestors.pop();// Remove ancestors that are no longer part of the chain
430
+ }// Check for circular references (if the value is already in the ancestors)
431
+ if(ancestors.includes(value)){return '[Circular Reference]';}// Add current value to ancestors
432
+ ancestors.push(value);return value;};};const traverseWithThis=(obj,replacer)=>{// Create a new result object or array
433
+ const result=Array.isArray(obj)?[]:{};// Traverse object properties or array elements
434
+ // eslint-disable-next-line no-restricted-syntax
435
+ for(const key in obj){if(Object.hasOwnProperty.call(obj,key)){const value=obj[key];// Recursively apply the replacer and traversal
436
+ const sanitizedValue=replacer.call(obj,key,value);// If the value is an object or array, continue traversal
437
+ if(isObjectLiteralAndNotNull(sanitizedValue)||Array.isArray(sanitizedValue)){result[key]=traverseWithThis(sanitizedValue,replacer);}else {result[key]=sanitizedValue;}}}return result;};/**
438
+ * Recursively traverses an object similar to JSON.stringify,
439
+ * sanitizing BigInts and circular references
440
+ * @param value Input object
441
+ * @param logger Logger instance
442
+ * @returns Sanitized value
443
+ */const getSanitizedValue=(value,logger)=>{const replacer=getReplacer();// This is needed for registering the first ancestor
444
+ const newValue=replacer.call(value,'',value);if(isObjectLiteralAndNotNull(value)||Array.isArray(value)){return traverseWithThis(value,replacer);}return newValue;};
445
+
446
446
  const MANUAL_ERROR_IDENTIFIER='[MANUAL ERROR]';/**
447
447
  * Get mutated error with issue prepended to error message
448
448
  * @param err Original error
@@ -450,7 +450,7 @@ const MANUAL_ERROR_IDENTIFIER='[MANUAL ERROR]';/**
450
450
  * @returns Instance of Error with message prepended with issue
451
451
  */const getMutatedError=(err,issue)=>{let finalError=err;if(!isTypeOfError(err)){finalError=new Error(`${issue}: ${stringifyWithoutCircular(err)}`);}else {finalError.message=`${issue}: ${err.message}`;}return finalError;};const dispatchErrorEvent=error=>{if(isTypeOfError(error)){error.stack=`${error.stack??''}\n${MANUAL_ERROR_IDENTIFIER}`;}globalThis.dispatchEvent(new ErrorEvent('error',{error}));};
452
452
 
453
- const APP_NAME='RudderLabs JavaScript SDK';const APP_VERSION='3.11.0';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';
453
+ const APP_NAME='RudderLabs JavaScript SDK';const APP_VERSION='3.11.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';
454
454
 
455
455
  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';
456
456
 
@@ -334,74 +334,37 @@
334
334
  * @returns base64 encoded string
335
335
  */const toBase64=value=>bytesToBase64(new TextEncoder().encode(value));
336
336
 
337
- const LOG_CONTEXT_SEPARATOR=':: ';const SCRIPT_ALREADY_EXISTS_ERROR=id=>`A script with the id "${id}" is already loaded. Skipping the loading of this script to prevent conflicts.`;const SCRIPT_LOAD_ERROR=(id,url)=>`Failed to load the script with the id "${id}" from URL "${url}".`;const SCRIPT_LOAD_TIMEOUT_ERROR=(id,url,timeout)=>`A timeout of ${timeout} ms occurred while trying to load the script with id "${id}" from URL "${url}".`;const CIRCULAR_REFERENCE_WARNING=(context,key)=>`${context}${LOG_CONTEXT_SEPARATOR}A circular reference has been detected in the object and the property "${key}" has been dropped from the output.`;const JSON_STRINGIFY_WARNING=`Failed to convert the value to a JSON string.`;
338
-
339
- const JSON_STRINGIFY='JSONStringify';const getCircularReplacer=(excludeNull,excludeKeys,logger)=>{const ancestors=[];// Here we do not want to use arrow function to use "this" in function context
340
- // eslint-disable-next-line func-names
341
- return function(key,value){if(excludeKeys?.includes(key)){return undefined;}if(excludeNull&&isNullOrUndefined(value)){return undefined;}if(typeof value!=='object'||isNull(value)){return value;}// `this` is the object that value is contained in, i.e., its direct parent.
342
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
343
- // @ts-ignore-next-line
344
- while(ancestors.length>0&&ancestors[ancestors.length-1]!==this){ancestors.pop();}if(ancestors.includes(value)){logger?.warn(CIRCULAR_REFERENCE_WARNING(JSON_STRINGIFY,key));return '[Circular Reference]';}ancestors.push(value);return value;};};/**
345
- * Utility method for JSON stringify object excluding null values & circular references
346
- *
347
- * @param {*} value input
348
- * @param {boolean} excludeNull if it should exclude nul or not
349
- * @param {function} logger optional logger methods for warning
350
- * @returns string
351
- */const stringifyWithoutCircular=(value,excludeNull,excludeKeys,logger)=>{try{return JSON.stringify(value,getCircularReplacer(excludeNull,excludeKeys,logger));}catch(err){logger?.warn(JSON_STRINGIFY_WARNING,err);return null;}};const getReplacer=logger=>{const ancestors=[];// Array to track ancestor objects
352
- // Using a regular function to use `this` for the parent context
353
- return function replacer(key,value){if(isBigInt(value)){return '[BigInt]';// Replace BigInt values
354
- }// `this` is the object that value is contained in, i.e., its direct parent.
355
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
356
- // @ts-ignore-next-line
357
- while(ancestors.length>0&&ancestors[ancestors.length-1]!==this){ancestors.pop();// Remove ancestors that are no longer part of the chain
358
- }// Check for circular references (if the value is already in the ancestors)
359
- if(ancestors.includes(value)){return '[Circular Reference]';}// Add current value to ancestors
360
- ancestors.push(value);return value;};};const traverseWithThis=(obj,replacer)=>{// Create a new result object or array
361
- const result=Array.isArray(obj)?[]:{};// Traverse object properties or array elements
362
- // eslint-disable-next-line no-restricted-syntax
363
- for(const key in obj){if(Object.hasOwnProperty.call(obj,key)){const value=obj[key];// Recursively apply the replacer and traversal
364
- const sanitizedValue=replacer.call(obj,key,value);// If the value is an object or array, continue traversal
365
- if(isObjectLiteralAndNotNull(sanitizedValue)||Array.isArray(sanitizedValue)){result[key]=traverseWithThis(sanitizedValue,replacer);}else {result[key]=sanitizedValue;}}}return result;};/**
366
- * Recursively traverses an object similar to JSON.stringify,
367
- * sanitizing BigInts and circular references
368
- * @param value Input object
369
- * @param logger Logger instance
370
- * @returns Sanitized value
371
- */const getSanitizedValue=(value,logger)=>{const replacer=getReplacer();// This is needed for registering the first ancestor
372
- const newValue=replacer.call(value,'',value);if(isObjectLiteralAndNotNull(value)||Array.isArray(value)){return traverseWithThis(value,replacer);}return newValue;};
373
-
374
337
  // if yes make them null instead of omitting in overloaded cases
375
338
  /*
376
339
  * Normalise the overloaded arguments of the page call facade
377
- */const pageArgumentsToCallOptions=(category,name,properties,options,callback)=>{const sanitizedCategory=getSanitizedValue(category);const sanitizedName=getSanitizedValue(name);const sanitizedProperties=getSanitizedValue(properties);const sanitizedOptions=getSanitizedValue(options);const sanitizedCallback=getSanitizedValue(callback);const payload={category:sanitizedCategory,name:sanitizedName,properties:sanitizedProperties,options:sanitizedOptions,callback:undefined};if(isFunction(sanitizedCallback)){payload.callback=sanitizedCallback;}if(isFunction(sanitizedOptions)){payload.category=sanitizedCategory;payload.name=sanitizedName;payload.properties=sanitizedProperties;payload.options=undefined;payload.callback=sanitizedOptions;}if(isFunction(sanitizedProperties)){payload.category=sanitizedCategory;payload.name=sanitizedName;payload.properties=undefined;payload.options=undefined;payload.callback=sanitizedProperties;}if(isFunction(sanitizedName)){payload.category=sanitizedCategory;payload.name=undefined;payload.properties=undefined;payload.options=undefined;payload.callback=sanitizedName;}if(isFunction(sanitizedCategory)){payload.category=undefined;payload.name=undefined;payload.properties=undefined;payload.options=undefined;payload.callback=sanitizedCategory;}if(isObjectLiteralAndNotNull(sanitizedCategory)){payload.name=undefined;payload.category=undefined;payload.properties=sanitizedCategory;if(!isFunction(sanitizedName)){payload.options=sanitizedName;}else {payload.options=undefined;}}else if(isObjectLiteralAndNotNull(sanitizedName)){payload.name=undefined;payload.properties=sanitizedName;if(!isFunction(sanitizedProperties)){payload.options=sanitizedProperties;}else {payload.options=undefined;}}// if the category argument alone is provided b/w category and name,
340
+ */const pageArgumentsToCallOptions=(category,name,properties,options,callback)=>{const payload={category:category,name:name,properties:properties,options:options,callback:undefined};if(isFunction(callback)){payload.callback=callback;}if(isFunction(options)){payload.category=category;payload.name=name;payload.properties=properties;payload.options=undefined;payload.callback=options;}if(isFunction(properties)){payload.category=category;payload.name=name;payload.properties=undefined;payload.options=undefined;payload.callback=properties;}if(isFunction(name)){payload.category=category;payload.name=undefined;payload.properties=undefined;payload.options=undefined;payload.callback=name;}if(isFunction(category)){payload.category=undefined;payload.name=undefined;payload.properties=undefined;payload.options=undefined;payload.callback=category;}if(isObjectLiteralAndNotNull(category)){payload.name=undefined;payload.category=undefined;payload.properties=category;if(!isFunction(name)){payload.options=name;}else {payload.options=undefined;}}else if(isObjectLiteralAndNotNull(name)){payload.name=undefined;payload.properties=name;if(!isFunction(properties)){payload.options=properties;}else {payload.options=undefined;}}// if the category argument alone is provided b/w category and name,
378
341
  // use it as name and set category to undefined
379
- if(isString(sanitizedCategory)&&!isString(sanitizedName)){payload.category=undefined;payload.name=sanitizedCategory;}// Rest of the code is just to clean up undefined values
342
+ if(isString(category)&&!isString(name)){payload.category=undefined;payload.name=category;}// Rest of the code is just to clean up undefined values
380
343
  // and set some proper defaults
381
344
  // Also, to clone the incoming object type arguments
382
345
  if(!isDefined(payload.category)){payload.category=undefined;}if(!isDefined(payload.name)){payload.name=undefined;}payload.properties=payload.properties?clone(payload.properties):{};if(isDefined(payload.options)){payload.options=clone(payload.options);}else {payload.options=undefined;}const nameForProperties=isString(payload.name)?payload.name:payload.properties.name;const categoryForProperties=isString(payload.category)?payload.category:payload.properties.category;// add name and category to properties
383
346
  payload.properties=mergeDeepRight(isObjectLiteralAndNotNull(payload.properties)?payload.properties:{},{...(nameForProperties&&{name:nameForProperties}),...(categoryForProperties&&{category:categoryForProperties})});return payload;};/*
384
347
  * Normalise the overloaded arguments of the track call facade
385
- */const trackArgumentsToCallOptions=(event,properties,options,callback)=>{const sanitizedEvent=getSanitizedValue(event);const sanitizedProperties=getSanitizedValue(properties);const sanitizedOptions=getSanitizedValue(options);const sanitizedCallback=getSanitizedValue(callback);const payload={name:sanitizedEvent,properties:sanitizedProperties,options:sanitizedOptions,callback:undefined};if(isFunction(sanitizedCallback)){payload.callback=sanitizedCallback;}if(isFunction(sanitizedOptions)){payload.properties=sanitizedProperties;payload.options=undefined;payload.callback=sanitizedOptions;}if(isFunction(sanitizedProperties)){payload.properties=undefined;payload.options=undefined;payload.callback=sanitizedProperties;}// Rest of the code is just to clean up undefined values
348
+ */const trackArgumentsToCallOptions=(event,properties,options,callback)=>{const payload={name:event,properties:properties,options:options,callback:undefined};if(isFunction(callback)){payload.callback=callback;}if(isFunction(options)){payload.properties=properties;payload.options=undefined;payload.callback=options;}if(isFunction(properties)){payload.properties=undefined;payload.options=undefined;payload.callback=properties;}// Rest of the code is just to clean up undefined values
386
349
  // and set some proper defaults
387
350
  // Also, to clone the incoming object type arguments
388
351
  payload.properties=isDefinedAndNotNull(payload.properties)?clone(payload.properties):{};if(isDefined(payload.options)){payload.options=clone(payload.options);}else {payload.options=undefined;}return payload;};/*
389
352
  * Normalise the overloaded arguments of the identify call facade
390
- */const identifyArgumentsToCallOptions=(userId,traits,options,callback)=>{const sanitizedUserId=getSanitizedValue(userId);const sanitizedTraits=getSanitizedValue(traits);const sanitizedOptions=getSanitizedValue(options);const sanitizedCallback=getSanitizedValue(callback);const payload={userId:sanitizedUserId,traits:sanitizedTraits,options:sanitizedOptions,callback:undefined};if(isFunction(sanitizedCallback)){payload.callback=sanitizedCallback;}if(isFunction(sanitizedOptions)){payload.userId=sanitizedUserId;payload.traits=sanitizedTraits;payload.options=undefined;payload.callback=sanitizedOptions;}if(isFunction(sanitizedTraits)){payload.userId=sanitizedUserId;payload.traits=undefined;payload.options=undefined;payload.callback=sanitizedTraits;}if(isObjectLiteralAndNotNull(sanitizedUserId)||isNull(sanitizedUserId)){// Explicitly set null to prevent resetting the existing value
353
+ */const identifyArgumentsToCallOptions=(userId,traits,options,callback)=>{const payload={userId:userId,traits:traits,options:options,callback:undefined};if(isFunction(callback)){payload.callback=callback;}if(isFunction(options)){payload.userId=userId;payload.traits=traits;payload.options=undefined;payload.callback=options;}if(isFunction(traits)){payload.userId=userId;payload.traits=undefined;payload.options=undefined;payload.callback=traits;}if(isObjectLiteralAndNotNull(userId)||isNull(userId)){// Explicitly set null to prevent resetting the existing value
391
354
  // in the Analytics class
392
- payload.userId=null;payload.traits=sanitizedUserId;if(!isFunction(sanitizedTraits)){payload.options=sanitizedTraits;}else {payload.options=undefined;}}// Rest of the code is just to clean up undefined values
355
+ payload.userId=null;payload.traits=userId;if(!isFunction(traits)){payload.options=traits;}else {payload.options=undefined;}}// Rest of the code is just to clean up undefined values
393
356
  // and set some proper defaults
394
357
  // Also, to clone the incoming object type arguments
395
358
  payload.userId=tryStringify(payload.userId);if(isObjectLiteralAndNotNull(payload.traits)){payload.traits=clone(payload.traits);}else {payload.traits=undefined;}if(isDefined(payload.options)){payload.options=clone(payload.options);}else {payload.options=undefined;}return payload;};/*
396
359
  * Normalise the overloaded arguments of the alias call facade
397
- */const aliasArgumentsToCallOptions=(to,from,options,callback)=>{const sanitizedTo=getSanitizedValue(to);const sanitizedFrom=getSanitizedValue(from);const sanitizedOptions=getSanitizedValue(options);const sanitizedCallback=getSanitizedValue(callback);const payload={to:sanitizedTo,from:sanitizedFrom,options:sanitizedOptions,callback:undefined};if(isFunction(sanitizedCallback)){payload.callback=sanitizedCallback;}if(isFunction(sanitizedOptions)){payload.to=sanitizedTo;payload.from=sanitizedFrom;payload.options=undefined;payload.callback=sanitizedOptions;}if(isFunction(sanitizedFrom)){payload.to=sanitizedTo;payload.from=undefined;payload.options=undefined;payload.callback=sanitizedFrom;}else if(isObjectLiteralAndNotNull(sanitizedFrom)||isNull(sanitizedFrom)){payload.to=sanitizedTo;payload.from=undefined;payload.options=sanitizedFrom;}// Rest of the code is just to clean up undefined values
360
+ */const aliasArgumentsToCallOptions=(to,from,options,callback)=>{const payload={to,from:from,options:options,callback:undefined};if(isFunction(callback)){payload.callback=callback;}if(isFunction(options)){payload.to=to;payload.from=from;payload.options=undefined;payload.callback=options;}if(isFunction(from)){payload.to=to;payload.from=undefined;payload.options=undefined;payload.callback=from;}else if(isObjectLiteralAndNotNull(from)||isNull(from)){payload.to=to;payload.from=undefined;payload.options=from;}// Rest of the code is just to clean up undefined values
398
361
  // and set some proper defaults
399
362
  // Also, to clone the incoming object type arguments
400
363
  if(isDefined(payload.to)){payload.to=tryStringify(payload.to);}if(isDefined(payload.from)){payload.from=tryStringify(payload.from);}else {payload.from=undefined;}if(isDefined(payload.options)){payload.options=clone(payload.options);}else {payload.options=undefined;}return payload;};/*
401
364
  * Normalise the overloaded arguments of the group call facade
402
- */const groupArgumentsToCallOptions=(groupId,traits,options,callback)=>{const sanitizedGroupId=getSanitizedValue(groupId);const sanitizedTraits=getSanitizedValue(traits);const sanitizedOptions=getSanitizedValue(options);const sanitizedCallback=getSanitizedValue(callback);const payload={groupId:sanitizedGroupId,traits:sanitizedTraits,options:sanitizedOptions,callback:undefined};if(isFunction(sanitizedCallback)){payload.callback=sanitizedCallback;}if(isFunction(sanitizedOptions)){payload.groupId=sanitizedGroupId;payload.traits=sanitizedTraits;payload.options=undefined;payload.callback=sanitizedOptions;}if(isFunction(sanitizedTraits)){payload.groupId=sanitizedGroupId;payload.traits=undefined;payload.options=undefined;payload.callback=sanitizedTraits;}if(isObjectLiteralAndNotNull(sanitizedGroupId)||isNull(sanitizedGroupId)){// Explicitly set null to prevent resetting the existing value
365
+ */const groupArgumentsToCallOptions=(groupId,traits,options,callback)=>{const payload={groupId:groupId,traits:traits,options:options,callback:undefined};if(isFunction(callback)){payload.callback=callback;}if(isFunction(options)){payload.groupId=groupId;payload.traits=traits;payload.options=undefined;payload.callback=options;}if(isFunction(traits)){payload.groupId=groupId;payload.traits=undefined;payload.options=undefined;payload.callback=traits;}if(isObjectLiteralAndNotNull(groupId)||isNull(groupId)){// Explicitly set null to prevent resetting the existing value
403
366
  // in the Analytics class
404
- payload.groupId=null;payload.traits=sanitizedGroupId;if(!isFunction(sanitizedTraits)){payload.options=sanitizedTraits;}else {payload.options=undefined;}}// Rest of the code is just to clean up undefined values
367
+ payload.groupId=null;payload.traits=groupId;if(!isFunction(traits)){payload.options=traits;}else {payload.options=undefined;}}// Rest of the code is just to clean up undefined values
405
368
  // and set some proper defaults
406
369
  // Also, to clone the incoming object type arguments
407
370
  payload.groupId=tryStringify(payload.groupId);if(isObjectLiteralAndNotNull(payload.traits)){payload.traits=clone(payload.traits);}else {payload.traits=undefined;}if(isDefined(payload.options)){payload.options=clone(payload.options);}else {payload.options=undefined;}return payload;};
@@ -449,6 +412,43 @@
449
412
  * @returns ISO formatted timestamp string
450
413
  */const getCurrentTimeFormatted=()=>getFormattedTimestamp(new Date());
451
414
 
415
+ const LOG_CONTEXT_SEPARATOR=':: ';const SCRIPT_ALREADY_EXISTS_ERROR=id=>`A script with the id "${id}" is already loaded. Skipping the loading of this script to prevent conflicts.`;const SCRIPT_LOAD_ERROR=(id,url)=>`Failed to load the script with the id "${id}" from URL "${url}".`;const SCRIPT_LOAD_TIMEOUT_ERROR=(id,url,timeout)=>`A timeout of ${timeout} ms occurred while trying to load the script with id "${id}" from URL "${url}".`;const CIRCULAR_REFERENCE_WARNING=(context,key)=>`${context}${LOG_CONTEXT_SEPARATOR}A circular reference has been detected in the object and the property "${key}" has been dropped from the output.`;const JSON_STRINGIFY_WARNING=`Failed to convert the value to a JSON string.`;
416
+
417
+ const JSON_STRINGIFY='JSONStringify';const getCircularReplacer=(excludeNull,excludeKeys,logger)=>{const ancestors=[];// Here we do not want to use arrow function to use "this" in function context
418
+ // eslint-disable-next-line func-names
419
+ return function(key,value){if(excludeKeys?.includes(key)){return undefined;}if(excludeNull&&isNullOrUndefined(value)){return undefined;}if(typeof value!=='object'||isNull(value)){return value;}// `this` is the object that value is contained in, i.e., its direct parent.
420
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
421
+ // @ts-ignore-next-line
422
+ while(ancestors.length>0&&ancestors[ancestors.length-1]!==this){ancestors.pop();}if(ancestors.includes(value)){logger?.warn(CIRCULAR_REFERENCE_WARNING(JSON_STRINGIFY,key));return '[Circular Reference]';}ancestors.push(value);return value;};};/**
423
+ * Utility method for JSON stringify object excluding null values & circular references
424
+ *
425
+ * @param {*} value input
426
+ * @param {boolean} excludeNull if it should exclude nul or not
427
+ * @param {function} logger optional logger methods for warning
428
+ * @returns string
429
+ */const stringifyWithoutCircular=(value,excludeNull,excludeKeys,logger)=>{try{return JSON.stringify(value,getCircularReplacer(excludeNull,excludeKeys,logger));}catch(err){logger?.warn(JSON_STRINGIFY_WARNING,err);return null;}};const getReplacer=logger=>{const ancestors=[];// Array to track ancestor objects
430
+ // Using a regular function to use `this` for the parent context
431
+ return function replacer(key,value){if(isBigInt(value)){return '[BigInt]';// Replace BigInt values
432
+ }// `this` is the object that value is contained in, i.e., its direct parent.
433
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
434
+ // @ts-ignore-next-line
435
+ while(ancestors.length>0&&ancestors[ancestors.length-1]!==this){ancestors.pop();// Remove ancestors that are no longer part of the chain
436
+ }// Check for circular references (if the value is already in the ancestors)
437
+ if(ancestors.includes(value)){return '[Circular Reference]';}// Add current value to ancestors
438
+ ancestors.push(value);return value;};};const traverseWithThis=(obj,replacer)=>{// Create a new result object or array
439
+ const result=Array.isArray(obj)?[]:{};// Traverse object properties or array elements
440
+ // eslint-disable-next-line no-restricted-syntax
441
+ for(const key in obj){if(Object.hasOwnProperty.call(obj,key)){const value=obj[key];// Recursively apply the replacer and traversal
442
+ const sanitizedValue=replacer.call(obj,key,value);// If the value is an object or array, continue traversal
443
+ if(isObjectLiteralAndNotNull(sanitizedValue)||Array.isArray(sanitizedValue)){result[key]=traverseWithThis(sanitizedValue,replacer);}else {result[key]=sanitizedValue;}}}return result;};/**
444
+ * Recursively traverses an object similar to JSON.stringify,
445
+ * sanitizing BigInts and circular references
446
+ * @param value Input object
447
+ * @param logger Logger instance
448
+ * @returns Sanitized value
449
+ */const getSanitizedValue=(value,logger)=>{const replacer=getReplacer();// This is needed for registering the first ancestor
450
+ const newValue=replacer.call(value,'',value);if(isObjectLiteralAndNotNull(value)||Array.isArray(value)){return traverseWithThis(value,replacer);}return newValue;};
451
+
452
452
  const MANUAL_ERROR_IDENTIFIER='[MANUAL ERROR]';/**
453
453
  * Get mutated error with issue prepended to error message
454
454
  * @param err Original error
@@ -456,7 +456,7 @@
456
456
  * @returns Instance of Error with message prepended with issue
457
457
  */const getMutatedError=(err,issue)=>{let finalError=err;if(!isTypeOfError(err)){finalError=new Error(`${issue}: ${stringifyWithoutCircular(err)}`);}else {finalError.message=`${issue}: ${err.message}`;}return finalError;};const dispatchErrorEvent=error=>{if(isTypeOfError(error)){error.stack=`${error.stack??''}\n${MANUAL_ERROR_IDENTIFIER}`;}globalThis.dispatchEvent(new ErrorEvent('error',{error}));};
458
458
 
459
- const APP_NAME='RudderLabs JavaScript SDK';const APP_VERSION='3.11.0';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';
459
+ const APP_NAME='RudderLabs JavaScript SDK';const APP_VERSION='3.11.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';
460
460
 
461
461
  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';
462
462
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rudderstack/analytics-js",
3
- "version": "3.11.0",
3
+ "version": "3.11.1",
4
4
  "description": "RudderStack JavaScript SDK",
5
5
  "main": "dist/npm/modern/cjs/index.cjs",
6
6
  "module": "dist/npm/modern/esm/index.mjs",