diff --git a/CHANGELOG.md b/CHANGELOG.md index 5af9e65e..febefc92 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ * Add support for passing callback function to identify. * Add support for prepend user property operation. +* Keeping sessions and event metadata in sync across multiple windows/tabs. ### 2.9.1 (March 6, 2016) diff --git a/amplitude.js b/amplitude.js index 975b1b8d..97eaf981 100644 --- a/amplitude.js +++ b/amplitude.js @@ -669,6 +669,7 @@ Amplitude.prototype._logEvent = function(eventType, eventProperties, apiProperti callback = null; } + _loadCookieData(this); if (!eventType || this.options.optOut) { if (callback) { callback(0, 'No request sent'); diff --git a/amplitude.min.js b/amplitude.min.js index 740ba1b7..c954516a 100644 --- a/amplitude.min.js +++ b/amplitude.min.js @@ -1,2 +1,2 @@ -(function umd(require){if("object"==typeof exports){module.exports=require("1")}else if("function"==typeof define&&define.amd){define(function(){return require("1")})}else{this["amplitude"]=require("1")}})(function outer(modules,cache,entries){var global=function(){return this}();function require(name,jumped){if(cache[name])return cache[name].exports;if(modules[name])return call(name,require);throw new Error('cannot find module "'+name+'"')}function call(id,require){var m=cache[id]={exports:{}};var mod=modules[id];var name=mod[2];var fn=mod[0];fn.call(m.exports,function(req){var dep=modules[id][1][req];return require(dep?dep:req)},m,m.exports,outer,modules,cache,entries);if(name)cache[name]=cache[id];return cache[id].exports}for(var id in entries){if(entries[id]){global[entries[id]]=require(id)}else{require(id)}}require.duo=true;require.cache=cache;require.modules=modules;return require}({1:[function(require,module,exports){var Amplitude=require("./amplitude");var old=window.amplitude||{};var instance=new Amplitude;instance._q=old._q||[];module.exports=instance},{"./amplitude":2}],2:[function(require,module,exports){var cookieStorage=require("./cookiestorage");var getUtmData=require("./utm");var Identify=require("./identify");var JSON=require("json");var localStorage=require("./localstorage");var md5=require("JavaScript-MD5");var object=require("object");var Request=require("./xhr");var type=require("./type");var UAParser=require("ua-parser-js");var utils=require("./utils");var UUID=require("./uuid");var version=require("./version");var DEFAULT_OPTIONS=require("./options");var IDENTIFY_EVENT="$identify";var API_VERSION=2;var MAX_STRING_LENGTH=1024;var LocalStorageKeys={LAST_EVENT_ID:"amplitude_lastEventId",LAST_EVENT_TIME:"amplitude_lastEventTime",LAST_IDENTIFY_ID:"amplitude_lastIdentifyId",LAST_SEQUENCE_NUMBER:"amplitude_lastSequenceNumber",REFERRER:"amplitude_referrer",SESSION_ID:"amplitude_sessionId",DEVICE_ID:"amplitude_deviceId",OPT_OUT:"amplitude_optOut",USER_ID:"amplitude_userId"};var Amplitude=function(){this._unsentEvents=[];this._unsentIdentifys=[];this._ua=new UAParser(navigator.userAgent).getResult();this.options=object.merge({},DEFAULT_OPTIONS);this.cookieStorage=(new cookieStorage).getStorage();this._q=[]};Amplitude.prototype._eventId=0;Amplitude.prototype._identifyId=0;Amplitude.prototype._sequenceNumber=0;Amplitude.prototype._sending=false;Amplitude.prototype._lastEventTime=null;Amplitude.prototype._sessionId=null;Amplitude.prototype._newSession=false;Amplitude.prototype._updateScheduled=false;Amplitude.prototype.Identify=Identify;Amplitude.prototype.init=function(apiKey,opt_userId,opt_config,callback){try{this.options.apiKey=apiKey;if(opt_config){if(opt_config.saveEvents!==undefined){this.options.saveEvents=!!opt_config.saveEvents}if(opt_config.domain!==undefined){this.options.domain=opt_config.domain}if(opt_config.includeUtm!==undefined){this.options.includeUtm=!!opt_config.includeUtm}if(opt_config.includeReferrer!==undefined){this.options.includeReferrer=!!opt_config.includeReferrer}if(opt_config.batchEvents!==undefined){this.options.batchEvents=!!opt_config.batchEvents}this.options.platform=opt_config.platform||this.options.platform;this.options.language=opt_config.language||this.options.language;this.options.sessionTimeout=opt_config.sessionTimeout||this.options.sessionTimeout;this.options.uploadBatchSize=opt_config.uploadBatchSize||this.options.uploadBatchSize;this.options.eventUploadThreshold=opt_config.eventUploadThreshold||this.options.eventUploadThreshold;this.options.savedMaxCount=opt_config.savedMaxCount||this.options.savedMaxCount;this.options.eventUploadPeriodMillis=opt_config.eventUploadPeriodMillis||this.options.eventUploadPeriodMillis}this.cookieStorage.options({expirationDays:this.options.cookieExpiration,domain:this.options.domain});this.options.domain=this.cookieStorage.options().domain;_upgradeCookeData(this);_loadCookieData(this);this.options.deviceId=opt_config&&opt_config.deviceId!==undefined&&opt_config.deviceId!==null&&opt_config.deviceId||this.options.deviceId||UUID();this.options.userId=opt_userId!==undefined&&opt_userId!==null&&opt_userId||this.options.userId||null;var now=(new Date).getTime();if(!this._sessionId||!this._lastEventTime||now-this._lastEventTime>this.options.sessionTimeout){this._newSession=true;this._sessionId=now}this._lastEventTime=now;_saveCookieData(this);if(this.options.saveEvents){this._unsentEvents=this._loadSavedUnsentEvents(this.options.unsentKey)||this._unsentEvents;this._unsentIdentifys=this._loadSavedUnsentEvents(this.options.unsentIdentifyKey)||this._unsentIdentifys;for(var i=0;i=this.options.eventUploadThreshold){this.sendEvents(callback);return true}if(!this._updateScheduled){this._updateScheduled=true;setTimeout(function(){this._updateScheduled=false;this.sendEvents()}.bind(this),this.options.eventUploadPeriodMillis)}return false};Amplitude.prototype._getFromStorage=function(storage,key){return storage.getItem(key)};Amplitude.prototype._setInStorage=function(storage,key,value){storage.setItem(key,value)};var _upgradeCookeData=function(scope){var cookieData=scope.cookieStorage.get(scope.options.cookieName);if(cookieData&&cookieData.deviceId&&cookieData.sessionId&&cookieData.lastEventTime){return}var _getAndRemoveFromLocalStorage=function(key){var value=localStorage.getItem(key);localStorage.removeItem(key);return value};var apiKeySuffix="_"+scope.options.apiKey.slice(0,6);var localStorageDeviceId=_getAndRemoveFromLocalStorage(LocalStorageKeys.DEVICE_ID+apiKeySuffix);var localStorageUserId=_getAndRemoveFromLocalStorage(LocalStorageKeys.USER_ID+apiKeySuffix);var localStorageOptOut=_getAndRemoveFromLocalStorage(LocalStorageKeys.OPT_OUT+apiKeySuffix);if(localStorageOptOut!==null&&localStorageOptOut!==undefined){localStorageOptOut=String(localStorageOptOut)==="true"}var localStorageSessionId=parseInt(_getAndRemoveFromLocalStorage(LocalStorageKeys.SESSION_ID));var localStorageLastEventTime=parseInt(_getAndRemoveFromLocalStorage(LocalStorageKeys.LAST_EVENT_TIME));var localStorageEventId=parseInt(_getAndRemoveFromLocalStorage(LocalStorageKeys.LAST_EVENT_ID));var localStorageIdentifyId=parseInt(_getAndRemoveFromLocalStorage(LocalStorageKeys.LAST_IDENTIFY_ID));var localStorageSequenceNumber=parseInt(_getAndRemoveFromLocalStorage(LocalStorageKeys.LAST_SEQUENCE_NUMBER));var _getFromCookie=function(key){return cookieData&&cookieData[key]};scope.options.deviceId=_getFromCookie("deviceId")||localStorageDeviceId;scope.options.userId=_getFromCookie("userId")||localStorageUserId;scope._sessionId=_getFromCookie("sessionId")||localStorageSessionId||scope._sessionId;scope._lastEventTime=_getFromCookie("lastEventTime")||localStorageLastEventTime||scope._lastEventTime;scope._eventId=_getFromCookie("eventId")||localStorageEventId||scope._eventId;scope._identifyId=_getFromCookie("identifyId")||localStorageIdentifyId||scope._identifyId;scope._sequenceNumber=_getFromCookie("sequenceNumber")||localStorageSequenceNumber||scope._sequenceNumber;scope.options.optOut=localStorageOptOut||false;if(cookieData&&cookieData.optOut!==undefined&&cookieData.optOut!==null){scope.options.optOut=String(cookieData.optOut)==="true"}_saveCookieData(scope)};var _loadCookieData=function(scope){var cookieData=scope.cookieStorage.get(scope.options.cookieName);if(cookieData){if(cookieData.deviceId){scope.options.deviceId=cookieData.deviceId}if(cookieData.userId){scope.options.userId=cookieData.userId}if(cookieData.optOut!==null&&cookieData.optOut!==undefined){scope.options.optOut=cookieData.optOut}if(cookieData.sessionId){scope._sessionId=parseInt(cookieData.sessionId)}if(cookieData.lastEventTime){scope._lastEventTime=parseInt(cookieData.lastEventTime)}if(cookieData.eventId){scope._eventId=parseInt(cookieData.eventId)}if(cookieData.identifyId){scope._identifyId=parseInt(cookieData.identifyId)}if(cookieData.sequenceNumber){scope._sequenceNumber=parseInt(cookieData.sequenceNumber)}}};var _saveCookieData=function(scope){scope.cookieStorage.set(scope.options.cookieName,{deviceId:scope.options.deviceId,userId:scope.options.userId,optOut:scope.options.optOut,sessionId:scope._sessionId,lastEventTime:scope._lastEventTime,eventId:scope._eventId,identifyId:scope._identifyId,sequenceNumber:scope._sequenceNumber})};Amplitude.prototype._initUtmData=function(queryParams,cookieParams){queryParams=queryParams||location.search;cookieParams=cookieParams||this.cookieStorage.get("__utmz");this._utmProperties=getUtmData(cookieParams,queryParams)};Amplitude.prototype._getReferrer=function(){return document.referrer};Amplitude.prototype._getReferringDomain=function(referrer){if(referrer===null||referrer===undefined||referrer===""){return null}var parts=referrer.split("/");if(parts.length>=3){return parts[2]}return null};Amplitude.prototype._saveReferrer=function(referrer){if(referrer===null||referrer===undefined||referrer===""){return}var referring_domain=this._getReferringDomain(referrer);var identify=(new Identify).setOnce("initial_referrer",referrer);identify.setOnce("initial_referring_domain",referring_domain);var hasSessionStorage=false;try{if(window.sessionStorage){hasSessionStorage=true}}catch(e){}if(hasSessionStorage&&!this._getFromStorage(sessionStorage,LocalStorageKeys.REFERRER)||!hasSessionStorage){identify.set("referrer",referrer).set("referring_domain",referring_domain);if(hasSessionStorage){this._setInStorage(sessionStorage,LocalStorageKeys.REFERRER,referrer)}}this.identify(identify)};Amplitude.prototype.saveEvents=function(){if(!this._apiKeySet("saveEvents()")){return}try{this._setInStorage(localStorage,this.options.unsentKey,JSON.stringify(this._unsentEvents));this._setInStorage(localStorage,this.options.unsentIdentifyKey,JSON.stringify(this._unsentIdentifys))}catch(e){}};Amplitude.prototype.setDomain=function(domain){if(!this._apiKeySet("setDomain()")){return}try{this.cookieStorage.options({domain:domain});this.options.domain=this.cookieStorage.options().domain;_loadCookieData(this);_saveCookieData(this)}catch(e){utils.log(e)}};Amplitude.prototype.setUserId=function(userId){if(!this._apiKeySet("setUserId()")){return}try{this.options.userId=userId!==undefined&&userId!==null&&""+userId||null;_saveCookieData(this)}catch(e){utils.log(e)}};Amplitude.prototype.setOptOut=function(enable){if(!this._apiKeySet("setOptOut()")){return}try{this.options.optOut=enable;_saveCookieData(this)}catch(e){utils.log(e)}};Amplitude.prototype.setDeviceId=function(deviceId){if(!this._apiKeySet("setDeviceId()")){return}try{if(deviceId){this.options.deviceId=""+deviceId;_saveCookieData(this)}}catch(e){utils.log(e)}};Amplitude.prototype.setUserProperties=function(userProperties){if(!this._apiKeySet("setUserProperties()")){return}var identify=new Identify;for(var property in userProperties){if(userProperties.hasOwnProperty(property)){identify.set(property,userProperties[property])}}this.identify(identify)};Amplitude.prototype.clearUserProperties=function(){if(!this._apiKeySet("clearUserProperties()")){return}var identify=new Identify;identify.clearAll();this.identify(identify)};Amplitude.prototype.identify=function(identify,callback){if(!this._apiKeySet("identify()")){if(callback&&type(callback)==="function"){callback(0,"No request sent")}return}if(type(identify)==="object"&&"_q"in identify){var instance=new Identify;for(var i=0;i0){this._logEvent(IDENTIFY_EVENT,null,null,identify.userPropertiesOperations,callback)}else if(callback&&type(callback)==="function"){callback(0,"No request sent")}};Amplitude.prototype.setVersionName=function(versionName){try{this.options.versionName=versionName}catch(e){utils.log(e)}};Amplitude.prototype._truncate=function(value){if(type(value)==="array"){for(var i=0;iMAX_STRING_LENGTH?value.substring(0,MAX_STRING_LENGTH):value}return value};Amplitude.prototype._logEvent=function(eventType,eventProperties,apiProperties,userProperties,callback){if(type(callback)!=="function"){callback=null}if(!eventType||this.options.optOut){if(callback){callback(0,"No request sent")}return}try{var eventId;if(eventType===IDENTIFY_EVENT){eventId=this.nextIdentifyId()}else{eventId=this.nextEventId()}var sequenceNumber=this.nextSequenceNumber();var eventTime=(new Date).getTime();var ua=this._ua;if(!this._sessionId||!this._lastEventTime||eventTime-this._lastEventTime>this.options.sessionTimeout){this._sessionId=eventTime}this._lastEventTime=eventTime;_saveCookieData(this);userProperties=userProperties||{};if(eventType!==IDENTIFY_EVENT){object.merge(userProperties,this._utmProperties)}apiProperties=apiProperties||{};eventProperties=eventProperties||{};var event={device_id:this.options.deviceId,user_id:this.options.userId||this.options.deviceId,timestamp:eventTime,event_id:eventId,session_id:this._sessionId||-1,event_type:eventType,version_name:this.options.versionName||null,platform:this.options.platform,os_name:ua.browser.name||null,os_version:ua.browser.major||null,device_model:ua.os.name||null,language:this.options.language,api_properties:apiProperties,event_properties:this._truncate(utils.validateProperties(eventProperties)),user_properties:this._truncate(userProperties),uuid:UUID(),library:{name:"amplitude-js",version:version},sequence_number:sequenceNumber};if(eventType===IDENTIFY_EVENT){this._unsentIdentifys.push(event);this._limitEventsQueued(this._unsentIdentifys)}else{this._unsentEvents.push(event);this._limitEventsQueued(this._unsentEvents)}if(this.options.saveEvents){this.saveEvents()}if(!this._sendEventsIfReady(callback)&&callback){callback(0,"No request sent")}return eventId}catch(e){utils.log(e)}};Amplitude.prototype._limitEventsQueued=function(queue){if(queue.length>this.options.savedMaxCount){queue.splice(0,queue.length-this.options.savedMaxCount)}};Amplitude.prototype.logEvent=function(eventType,eventProperties,callback){if(!this._apiKeySet("logEvent()")){if(callback&&type(callback)==="function"){callback(0,"No request sent")}return-1}return this._logEvent(eventType,eventProperties,null,null,callback)};var _isNumber=function(n){return!isNaN(parseFloat(n))&&isFinite(n)};Amplitude.prototype.logRevenue=function(price,quantity,product){if(!this._apiKeySet("logRevenue()")||!_isNumber(price)||quantity!==undefined&&!_isNumber(quantity)){return-1}return this._logEvent("revenue_amount",{},{productId:product,special:"revenue_amount",quantity:quantity||1,price:price})};Amplitude.prototype.removeEvents=function(maxEventId,maxIdentifyId){if(maxEventId>=0){var filteredEvents=[];for(var i=0;imaxEventId){filteredEvents.push(this._unsentEvents[i])}}this._unsentEvents=filteredEvents}if(maxIdentifyId>=0){var filteredIdentifys=[];for(var j=0;jmaxIdentifyId){filteredIdentifys.push(this._unsentIdentifys[j])}}this._unsentIdentifys=filteredIdentifys}};Amplitude.prototype.sendEvents=function(callback){if(!this._apiKeySet("sendEvents()")){if(callback&&type(callback)==="function"){callback(0,"No request sent")}return}if(!this._sending&&!this.options.optOut&&this._unsentCount()>0){this._sending=true;var url=("https:"===window.location.protocol?"https":"http")+"://"+this.options.apiEndpoint+"/";var numEvents=Math.min(this._unsentCount(),this.options.uploadBatchSize);var mergedEvents=this._mergeEventsAndIdentifys(numEvents);var maxEventId=mergedEvents.maxEventId;var maxIdentifyId=mergedEvents.maxIdentifyId;var events=JSON.stringify(mergedEvents.eventsToSend);var uploadTime=(new Date).getTime();var data={client:this.options.apiKey,e:events,v:API_VERSION,upload_time:uploadTime,checksum:md5(API_VERSION+this.options.apiKey+events+uploadTime)};var scope=this;new Request(url,data).send(function(status,response){scope._sending=false;try{if(status===200&&response==="success"){scope.removeEvents(maxEventId,maxIdentifyId);if(scope.options.saveEvents){scope.saveEvents()}if(!scope._sendEventsIfReady(callback)&&callback){callback(status,response)}}else if(status===413){if(scope.options.uploadBatchSize===1){scope.removeEvents(maxEventId,maxIdentifyId)}scope.options.uploadBatchSize=Math.ceil(numEvents/2);scope.sendEvents(callback)}else if(callback){callback(status,response)}}catch(e){}})}else if(callback){callback(0,"No request sent")}};Amplitude.prototype._mergeEventsAndIdentifys=function(numEvents){var eventsToSend=[];var eventIndex=0;var maxEventId=-1;var identifyIndex=0;var maxIdentifyId=-1;while(eventsToSend.length=this._unsentIdentifys.length){event=this._unsentEvents[eventIndex++];maxEventId=event.event_id}else if(eventIndex>=this._unsentEvents.length){event=this._unsentIdentifys[identifyIndex++];maxIdentifyId=event.event_id}else{if(!("sequence_number"in this._unsentEvents[eventIndex])||this._unsentEvents[eventIndex].sequence_number>2;enc2=(chr1&3)<<4|chr2>>4;enc3=(chr2&15)<<2|chr3>>6;enc4=chr3&63;if(isNaN(chr2)){enc3=enc4=64}else if(isNaN(chr3)){enc4=64}output=output+Base64._keyStr.charAt(enc1)+Base64._keyStr.charAt(enc2)+Base64._keyStr.charAt(enc3)+Base64._keyStr.charAt(enc4)}return output},decode:function(input){try{if(window.btoa&&window.atob){return decodeURIComponent(escape(window.atob(input)))}}catch(e){}return Base64._decode(input)},_decode:function(input){var output="";var chr1,chr2,chr3;var enc1,enc2,enc3,enc4;var i=0;input=input.replace(/[^A-Za-z0-9\+\/\=]/g,"");while(i>4;chr2=(enc2&15)<<4|enc3>>2;chr3=(enc3&3)<<6|enc4;output=output+String.fromCharCode(chr1);if(enc3!==64){output=output+String.fromCharCode(chr2)}if(enc4!==64){output=output+String.fromCharCode(chr3)}}output=UTF8.decode(output);return output}};module.exports=Base64},{"./utf8":20}],20:[function(require,module,exports){var UTF8={encode:function(s){var utftext="";for(var n=0;n127&&c<2048){utftext+=String.fromCharCode(c>>6|192);utftext+=String.fromCharCode(c&63|128)}else{utftext+=String.fromCharCode(c>>12|224);utftext+=String.fromCharCode(c>>6&63|128);utftext+=String.fromCharCode(c&63|128)}}return utftext},decode:function(utftext){var s="";var i=0;var c=0,c1=0,c2=0;while(i191&&c<224){c1=utftext.charCodeAt(i+1);s+=String.fromCharCode((c&31)<<6|c1&63);i+=2}else{c1=utftext.charCodeAt(i+1);c2=utftext.charCodeAt(i+2);s+=String.fromCharCode((c&15)<<12|(c1&63)<<6|c2&63);i+=3}}return s}};module.exports=UTF8},{}],6:[function(require,module,exports){var json=window.JSON||{};var stringify=json.stringify;var parse=json.parse;module.exports=parse&&stringify?JSON:require("json-fallback")},{"json-fallback":21}],21:[function(require,module,exports){(function(){"use strict";var JSON=module.exports={};function f(n){return n<10?"0"+n:n}if(typeof Date.prototype.toJSON!=="function"){Date.prototype.toJSON=function(){return isFinite(this.valueOf())?this.getUTCFullYear()+"-"+f(this.getUTCMonth()+1)+"-"+f(this.getUTCDate())+"T"+f(this.getUTCHours())+":"+f(this.getUTCMinutes())+":"+f(this.getUTCSeconds())+"Z":null};String.prototype.toJSON=Number.prototype.toJSON=Boolean.prototype.toJSON=function(){return this.valueOf()}}var cx,escapable,gap,indent,meta,rep;function quote(string){escapable.lastIndex=0;return escapable.test(string)?'"'+string.replace(escapable,function(a){var c=meta[a];return typeof c==="string"?c:"\\u"+("0000"+a.charCodeAt(0).toString(16)).slice(-4)})+'"':'"'+string+'"'}function str(key,holder){var i,k,v,length,mind=gap,partial,value=holder[key];if(value&&typeof value==="object"&&typeof value.toJSON==="function"){value=value.toJSON(key)}if(typeof rep==="function"){value=rep.call(holder,key,value)}switch(typeof value){case"string":return quote(value);case"number":return isFinite(value)?String(value):"null";case"boolean":case"null":return String(value);case"object":if(!value){return"null"}gap+=indent;partial=[];if(Object.prototype.toString.apply(value)==="[object Array]"){length=value.length;for(i=0;ithis.options.sessionTimeout){this._newSession=true;this._sessionId=now}this._lastEventTime=now;_saveCookieData(this);if(this.options.saveEvents){this._unsentEvents=this._loadSavedUnsentEvents(this.options.unsentKey)||this._unsentEvents;this._unsentIdentifys=this._loadSavedUnsentEvents(this.options.unsentIdentifyKey)||this._unsentIdentifys;for(var i=0;i=this.options.eventUploadThreshold){this.sendEvents(callback);return true}if(!this._updateScheduled){this._updateScheduled=true;setTimeout(function(){this._updateScheduled=false;this.sendEvents()}.bind(this),this.options.eventUploadPeriodMillis)}return false};Amplitude.prototype._getFromStorage=function(storage,key){return storage.getItem(key)};Amplitude.prototype._setInStorage=function(storage,key,value){storage.setItem(key,value)};var _upgradeCookeData=function(scope){var cookieData=scope.cookieStorage.get(scope.options.cookieName);if(cookieData&&cookieData.deviceId&&cookieData.sessionId&&cookieData.lastEventTime){return}var _getAndRemoveFromLocalStorage=function(key){var value=localStorage.getItem(key);localStorage.removeItem(key);return value};var apiKeySuffix="_"+scope.options.apiKey.slice(0,6);var localStorageDeviceId=_getAndRemoveFromLocalStorage(LocalStorageKeys.DEVICE_ID+apiKeySuffix);var localStorageUserId=_getAndRemoveFromLocalStorage(LocalStorageKeys.USER_ID+apiKeySuffix);var localStorageOptOut=_getAndRemoveFromLocalStorage(LocalStorageKeys.OPT_OUT+apiKeySuffix);if(localStorageOptOut!==null&&localStorageOptOut!==undefined){localStorageOptOut=String(localStorageOptOut)==="true"}var localStorageSessionId=parseInt(_getAndRemoveFromLocalStorage(LocalStorageKeys.SESSION_ID));var localStorageLastEventTime=parseInt(_getAndRemoveFromLocalStorage(LocalStorageKeys.LAST_EVENT_TIME));var localStorageEventId=parseInt(_getAndRemoveFromLocalStorage(LocalStorageKeys.LAST_EVENT_ID));var localStorageIdentifyId=parseInt(_getAndRemoveFromLocalStorage(LocalStorageKeys.LAST_IDENTIFY_ID));var localStorageSequenceNumber=parseInt(_getAndRemoveFromLocalStorage(LocalStorageKeys.LAST_SEQUENCE_NUMBER));var _getFromCookie=function(key){return cookieData&&cookieData[key]};scope.options.deviceId=_getFromCookie("deviceId")||localStorageDeviceId;scope.options.userId=_getFromCookie("userId")||localStorageUserId;scope._sessionId=_getFromCookie("sessionId")||localStorageSessionId||scope._sessionId;scope._lastEventTime=_getFromCookie("lastEventTime")||localStorageLastEventTime||scope._lastEventTime;scope._eventId=_getFromCookie("eventId")||localStorageEventId||scope._eventId;scope._identifyId=_getFromCookie("identifyId")||localStorageIdentifyId||scope._identifyId;scope._sequenceNumber=_getFromCookie("sequenceNumber")||localStorageSequenceNumber||scope._sequenceNumber;scope.options.optOut=localStorageOptOut||false;if(cookieData&&cookieData.optOut!==undefined&&cookieData.optOut!==null){scope.options.optOut=String(cookieData.optOut)==="true"}_saveCookieData(scope)};var _loadCookieData=function(scope){var cookieData=scope.cookieStorage.get(scope.options.cookieName);if(cookieData){if(cookieData.deviceId){scope.options.deviceId=cookieData.deviceId}if(cookieData.userId){scope.options.userId=cookieData.userId}if(cookieData.optOut!==null&&cookieData.optOut!==undefined){scope.options.optOut=cookieData.optOut}if(cookieData.sessionId){scope._sessionId=parseInt(cookieData.sessionId)}if(cookieData.lastEventTime){scope._lastEventTime=parseInt(cookieData.lastEventTime)}if(cookieData.eventId){scope._eventId=parseInt(cookieData.eventId)}if(cookieData.identifyId){scope._identifyId=parseInt(cookieData.identifyId)}if(cookieData.sequenceNumber){scope._sequenceNumber=parseInt(cookieData.sequenceNumber)}}};var _saveCookieData=function(scope){scope.cookieStorage.set(scope.options.cookieName,{deviceId:scope.options.deviceId,userId:scope.options.userId,optOut:scope.options.optOut,sessionId:scope._sessionId,lastEventTime:scope._lastEventTime,eventId:scope._eventId,identifyId:scope._identifyId,sequenceNumber:scope._sequenceNumber})};Amplitude.prototype._initUtmData=function(queryParams,cookieParams){queryParams=queryParams||location.search;cookieParams=cookieParams||this.cookieStorage.get("__utmz");this._utmProperties=getUtmData(cookieParams,queryParams)};Amplitude.prototype._getReferrer=function(){return document.referrer};Amplitude.prototype._getReferringDomain=function(referrer){if(referrer===null||referrer===undefined||referrer===""){return null}var parts=referrer.split("/");if(parts.length>=3){return parts[2]}return null};Amplitude.prototype._saveReferrer=function(referrer){if(referrer===null||referrer===undefined||referrer===""){return}var referring_domain=this._getReferringDomain(referrer);var identify=(new Identify).setOnce("initial_referrer",referrer);identify.setOnce("initial_referring_domain",referring_domain);var hasSessionStorage=false;try{if(window.sessionStorage){hasSessionStorage=true}}catch(e){}if(hasSessionStorage&&!this._getFromStorage(sessionStorage,LocalStorageKeys.REFERRER)||!hasSessionStorage){identify.set("referrer",referrer).set("referring_domain",referring_domain);if(hasSessionStorage){this._setInStorage(sessionStorage,LocalStorageKeys.REFERRER,referrer)}}this.identify(identify)};Amplitude.prototype.saveEvents=function(){if(!this._apiKeySet("saveEvents()")){return}try{this._setInStorage(localStorage,this.options.unsentKey,JSON.stringify(this._unsentEvents));this._setInStorage(localStorage,this.options.unsentIdentifyKey,JSON.stringify(this._unsentIdentifys))}catch(e){}};Amplitude.prototype.setDomain=function(domain){if(!this._apiKeySet("setDomain()")){return}try{this.cookieStorage.options({domain:domain});this.options.domain=this.cookieStorage.options().domain;_loadCookieData(this);_saveCookieData(this)}catch(e){utils.log(e)}};Amplitude.prototype.setUserId=function(userId){if(!this._apiKeySet("setUserId()")){return}try{this.options.userId=userId!==undefined&&userId!==null&&""+userId||null;_saveCookieData(this)}catch(e){utils.log(e)}};Amplitude.prototype.setOptOut=function(enable){if(!this._apiKeySet("setOptOut()")){return}try{this.options.optOut=enable;_saveCookieData(this)}catch(e){utils.log(e)}};Amplitude.prototype.setDeviceId=function(deviceId){if(!this._apiKeySet("setDeviceId()")){return}try{if(deviceId){this.options.deviceId=""+deviceId;_saveCookieData(this)}}catch(e){utils.log(e)}};Amplitude.prototype.setUserProperties=function(userProperties){if(!this._apiKeySet("setUserProperties()")){return}var identify=new Identify;for(var property in userProperties){if(userProperties.hasOwnProperty(property)){identify.set(property,userProperties[property])}}this.identify(identify)};Amplitude.prototype.clearUserProperties=function(){if(!this._apiKeySet("clearUserProperties()")){return}var identify=new Identify;identify.clearAll();this.identify(identify)};Amplitude.prototype.identify=function(identify,callback){if(!this._apiKeySet("identify()")){if(callback&&type(callback)==="function"){callback(0,"No request sent")}return}if(type(identify)==="object"&&"_q"in identify){var instance=new Identify;for(var i=0;i0){this._logEvent(IDENTIFY_EVENT,null,null,identify.userPropertiesOperations,callback)}else if(callback&&type(callback)==="function"){callback(0,"No request sent")}};Amplitude.prototype.setVersionName=function(versionName){try{this.options.versionName=versionName}catch(e){utils.log(e)}};Amplitude.prototype._truncate=function(value){if(type(value)==="array"){for(var i=0;iMAX_STRING_LENGTH?value.substring(0,MAX_STRING_LENGTH):value}return value};Amplitude.prototype._logEvent=function(eventType,eventProperties,apiProperties,userProperties,callback){if(type(callback)!=="function"){callback=null}_loadCookieData(this);if(!eventType||this.options.optOut){if(callback){callback(0,"No request sent")}return}try{var eventId;if(eventType===IDENTIFY_EVENT){eventId=this.nextIdentifyId()}else{eventId=this.nextEventId()}var sequenceNumber=this.nextSequenceNumber();var eventTime=(new Date).getTime();var ua=this._ua;if(!this._sessionId||!this._lastEventTime||eventTime-this._lastEventTime>this.options.sessionTimeout){this._sessionId=eventTime}this._lastEventTime=eventTime;_saveCookieData(this);userProperties=userProperties||{};if(eventType!==IDENTIFY_EVENT){object.merge(userProperties,this._utmProperties)}apiProperties=apiProperties||{};eventProperties=eventProperties||{};var event={device_id:this.options.deviceId,user_id:this.options.userId||this.options.deviceId,timestamp:eventTime,event_id:eventId,session_id:this._sessionId||-1,event_type:eventType,version_name:this.options.versionName||null,platform:this.options.platform,os_name:ua.browser.name||null,os_version:ua.browser.major||null,device_model:ua.os.name||null,language:this.options.language,api_properties:apiProperties,event_properties:this._truncate(utils.validateProperties(eventProperties)),user_properties:this._truncate(userProperties),uuid:UUID(),library:{name:"amplitude-js",version:version},sequence_number:sequenceNumber};if(eventType===IDENTIFY_EVENT){this._unsentIdentifys.push(event);this._limitEventsQueued(this._unsentIdentifys)}else{this._unsentEvents.push(event);this._limitEventsQueued(this._unsentEvents)}if(this.options.saveEvents){this.saveEvents()}if(!this._sendEventsIfReady(callback)&&callback){callback(0,"No request sent")}return eventId}catch(e){utils.log(e)}};Amplitude.prototype._limitEventsQueued=function(queue){if(queue.length>this.options.savedMaxCount){queue.splice(0,queue.length-this.options.savedMaxCount)}};Amplitude.prototype.logEvent=function(eventType,eventProperties,callback){if(!this._apiKeySet("logEvent()")){if(callback&&type(callback)==="function"){callback(0,"No request sent")}return-1}return this._logEvent(eventType,eventProperties,null,null,callback)};var _isNumber=function(n){return!isNaN(parseFloat(n))&&isFinite(n)};Amplitude.prototype.logRevenue=function(price,quantity,product){if(!this._apiKeySet("logRevenue()")||!_isNumber(price)||quantity!==undefined&&!_isNumber(quantity)){return-1}return this._logEvent("revenue_amount",{},{productId:product,special:"revenue_amount",quantity:quantity||1,price:price})};Amplitude.prototype.removeEvents=function(maxEventId,maxIdentifyId){if(maxEventId>=0){var filteredEvents=[];for(var i=0;imaxEventId){filteredEvents.push(this._unsentEvents[i])}}this._unsentEvents=filteredEvents}if(maxIdentifyId>=0){var filteredIdentifys=[];for(var j=0;jmaxIdentifyId){filteredIdentifys.push(this._unsentIdentifys[j])}}this._unsentIdentifys=filteredIdentifys}};Amplitude.prototype.sendEvents=function(callback){if(!this._apiKeySet("sendEvents()")){if(callback&&type(callback)==="function"){callback(0,"No request sent")}return}if(!this._sending&&!this.options.optOut&&this._unsentCount()>0){this._sending=true;var url=("https:"===window.location.protocol?"https":"http")+"://"+this.options.apiEndpoint+"/";var numEvents=Math.min(this._unsentCount(),this.options.uploadBatchSize);var mergedEvents=this._mergeEventsAndIdentifys(numEvents);var maxEventId=mergedEvents.maxEventId;var maxIdentifyId=mergedEvents.maxIdentifyId;var events=JSON.stringify(mergedEvents.eventsToSend);var uploadTime=(new Date).getTime();var data={client:this.options.apiKey,e:events,v:API_VERSION,upload_time:uploadTime,checksum:md5(API_VERSION+this.options.apiKey+events+uploadTime)};var scope=this;new Request(url,data).send(function(status,response){scope._sending=false;try{if(status===200&&response==="success"){scope.removeEvents(maxEventId,maxIdentifyId);if(scope.options.saveEvents){scope.saveEvents()}if(!scope._sendEventsIfReady(callback)&&callback){callback(status,response)}}else if(status===413){if(scope.options.uploadBatchSize===1){scope.removeEvents(maxEventId,maxIdentifyId)}scope.options.uploadBatchSize=Math.ceil(numEvents/2);scope.sendEvents(callback)}else if(callback){callback(status,response)}}catch(e){}})}else if(callback){callback(0,"No request sent")}};Amplitude.prototype._mergeEventsAndIdentifys=function(numEvents){var eventsToSend=[];var eventIndex=0;var maxEventId=-1;var identifyIndex=0;var maxIdentifyId=-1;while(eventsToSend.length=this._unsentIdentifys.length){event=this._unsentEvents[eventIndex++];maxEventId=event.event_id}else if(eventIndex>=this._unsentEvents.length){event=this._unsentIdentifys[identifyIndex++];maxIdentifyId=event.event_id}else{if(!("sequence_number"in this._unsentEvents[eventIndex])||this._unsentEvents[eventIndex].sequence_number>2;enc2=(chr1&3)<<4|chr2>>4;enc3=(chr2&15)<<2|chr3>>6;enc4=chr3&63;if(isNaN(chr2)){enc3=enc4=64}else if(isNaN(chr3)){enc4=64}output=output+Base64._keyStr.charAt(enc1)+Base64._keyStr.charAt(enc2)+Base64._keyStr.charAt(enc3)+Base64._keyStr.charAt(enc4)}return output},decode:function(input){try{if(window.btoa&&window.atob){return decodeURIComponent(escape(window.atob(input)))}}catch(e){}return Base64._decode(input)},_decode:function(input){var output="";var chr1,chr2,chr3;var enc1,enc2,enc3,enc4;var i=0;input=input.replace(/[^A-Za-z0-9\+\/\=]/g,"");while(i>4;chr2=(enc2&15)<<4|enc3>>2;chr3=(enc3&3)<<6|enc4;output=output+String.fromCharCode(chr1);if(enc3!==64){output=output+String.fromCharCode(chr2)}if(enc4!==64){output=output+String.fromCharCode(chr3)}}output=UTF8.decode(output);return output}};module.exports=Base64},{"./utf8":20}],20:[function(require,module,exports){var UTF8={encode:function(s){var utftext="";for(var n=0;n127&&c<2048){utftext+=String.fromCharCode(c>>6|192);utftext+=String.fromCharCode(c&63|128)}else{utftext+=String.fromCharCode(c>>12|224);utftext+=String.fromCharCode(c>>6&63|128);utftext+=String.fromCharCode(c&63|128)}}return utftext},decode:function(utftext){var s="";var i=0;var c=0,c1=0,c2=0;while(i191&&c<224){c1=utftext.charCodeAt(i+1);s+=String.fromCharCode((c&31)<<6|c1&63);i+=2}else{c1=utftext.charCodeAt(i+1);c2=utftext.charCodeAt(i+2);s+=String.fromCharCode((c&15)<<12|(c1&63)<<6|c2&63);i+=3}}return s}};module.exports=UTF8},{}],6:[function(require,module,exports){var json=window.JSON||{};var stringify=json.stringify;var parse=json.parse;module.exports=parse&&stringify?JSON:require("json-fallback")},{"json-fallback":21}],21:[function(require,module,exports){(function(){"use strict";var JSON=module.exports={};function f(n){return n<10?"0"+n:n}if(typeof Date.prototype.toJSON!=="function"){Date.prototype.toJSON=function(){return isFinite(this.valueOf())?this.getUTCFullYear()+"-"+f(this.getUTCMonth()+1)+"-"+f(this.getUTCDate())+"T"+f(this.getUTCHours())+":"+f(this.getUTCMinutes())+":"+f(this.getUTCSeconds())+"Z":null};String.prototype.toJSON=Number.prototype.toJSON=Boolean.prototype.toJSON=function(){return this.valueOf()}}var cx,escapable,gap,indent,meta,rep;function quote(string){escapable.lastIndex=0;return escapable.test(string)?'"'+string.replace(escapable,function(a){var c=meta[a];return typeof c==="string"?c:"\\u"+("0000"+a.charCodeAt(0).toString(16)).slice(-4)})+'"':'"'+string+'"'}function str(key,holder){var i,k,v,length,mind=gap,partial,value=holder[key];if(value&&typeof value==="object"&&typeof value.toJSON==="function"){value=value.toJSON(key)}if(typeof rep==="function"){value=rep.call(holder,key,value)}switch(typeof value){case"string":return quote(value);case"number":return isFinite(value)?String(value):"null";case"boolean":case"null":return String(value);case"object":if(!value){return"null"}gap+=indent;partial=[];if(Object.prototype.toString.apply(value)==="[object Array]"){length=value.length;for(i=0;i0){if(!this.userPropertiesOperations.hasOwnProperty(AMP_OP_CLEAR_ALL)){utils.log("Need to send $clearAll on its own Identify object without any other operations, skipping $clearAll")}return this}this.userPropertiesOperations[AMP_OP_CLEAR_ALL]="-";return this};Identify.prototype.prepend=function(property,value){this._addOperation(AMP_OP_PREPEND,property,value);return this};Identify.prototype.set=function(property,value){this._addOperation(AMP_OP_SET,property,value);return this};Identify.prototype.setOnce=function(property,value){this._addOperation(AMP_OP_SET_ONCE,property,value);return this};Identify.prototype.unset=function(property){this._addOperation(AMP_OP_UNSET,property,"-");return this};Identify.prototype._addOperation=function(operation,property,value){if(this.userPropertiesOperations.hasOwnProperty(AMP_OP_CLEAR_ALL)){utils.log("This identify already contains a $clearAll operation, skipping operation "+operation);return}if(this.properties.indexOf(property)!==-1){utils.log('User property "'+property+'" already used in this identify, skipping operation '+operation);return}if(!this.userPropertiesOperations.hasOwnProperty(operation)){this.userPropertiesOperations[operation]={}}this.userPropertiesOperations[operation][property]=value;this.properties.push(property)};module.exports=Identify},{"./type":11,"./utils":13}],11:[function(require,module,exports){var toString=Object.prototype.toString;module.exports=function(val){switch(toString.call(val)){case"[object Date]":return"date";case"[object RegExp]":return"regexp";case"[object Arguments]":return"arguments";case"[object Array]":return"array";case"[object Error]":return"error"}if(val===null){return"null"}if(val===undefined){return"undefined"}if(val!==val){return"nan"}if(val&&val.nodeType===1){return"element"}if(typeof Buffer!=="undefined"&&Buffer.isBuffer(val)){return"buffer"}val=val.valueOf?val.valueOf():Object.prototype.valueOf.apply(val);return typeof val}},{}],13:[function(require,module,exports){var type=require("./type");var log=function(s){try{console.log("[Amplitude] "+s)}catch(e){}};var isEmptyString=function(str){return!str||str.length===0};var validateProperties=function(properties){var propsType=type(properties);if(propsType!=="object"){log("Error: invalid event properties format. Expecting Javascript object, received "+propsType+", ignoring");return{}}var copy={};for(var property in properties){if(!properties.hasOwnProperty(property)){continue}var key=property;var keyType=type(key);if(keyType!=="string"){log("WARNING: Non-string property key, received type "+keyType+', coercing to string "'+key+'"');key=String(key)}var value=validatePropertyValue(key,properties[property]);if(value===null){continue}copy[key]=value}return copy};var invalidValueTypes=["null","nan","undefined","function","arguments","regexp","element"];var validatePropertyValue=function(key,value){var valueType=type(value);if(invalidValueTypes.indexOf(valueType)!==-1){log('WARNING: Property key "'+key+'" with invalid value type '+valueType+", ignoring");value=null}else if(valueType==="error"){value=String(value);log('WARNING: Property key "'+key+'" with value type error, coercing to '+value)}else if(valueType==="array"){var arrayCopy=[];for(var i=0;i>16)+(y>>16)+(lsw>>16);return msw<<16|lsw&65535}function bit_rol(num,cnt){return num<>>32-cnt}function md5_cmn(q,a,b,x,s,t){return safe_add(bit_rol(safe_add(safe_add(a,q),safe_add(x,t)),s),b)}function md5_ff(a,b,c,d,x,s,t){return md5_cmn(b&c|~b&d,a,b,x,s,t)}function md5_gg(a,b,c,d,x,s,t){return md5_cmn(b&d|c&~d,a,b,x,s,t)}function md5_hh(a,b,c,d,x,s,t){return md5_cmn(b^c^d,a,b,x,s,t)}function md5_ii(a,b,c,d,x,s,t){return md5_cmn(c^(b|~d),a,b,x,s,t)}function binl_md5(x,len){x[len>>5]|=128<>>9<<4)+14]=len;var i,olda,oldb,oldc,oldd,a=1732584193,b=-271733879,c=-1732584194,d=271733878;for(i=0;i>5]>>>i%32&255)}return output}function rstr2binl(input){var i,output=[];output[(input.length>>2)-1]=undefined;for(i=0;i>5]|=(input.charCodeAt(i/8)&255)<16){bkey=binl_md5(bkey,key.length*8)}for(i=0;i<16;i+=1){ipad[i]=bkey[i]^909522486;opad[i]=bkey[i]^1549556828}hash=binl_md5(ipad.concat(rstr2binl(data)),512+data.length*8);return binl2rstr(binl_md5(opad.concat(hash),512+128))}function rstr2hex(input){var hex_tab="0123456789abcdef",output="",x,i;for(i=0;i>>4&15)+hex_tab.charAt(x&15)}return output}function str2rstr_utf8(input){return unescape(encodeURIComponent(input))}function raw_md5(s){return rstr_md5(str2rstr_utf8(s))}function hex_md5(s){return rstr2hex(raw_md5(s))}function raw_hmac_md5(k,d){return rstr_hmac_md5(str2rstr_utf8(k),str2rstr_utf8(d))}function hex_hmac_md5(k,d){return rstr2hex(raw_hmac_md5(k,d))}function md5(string,key,raw){if(!key){if(!raw){return hex_md5(string)}return raw_md5(string)}if(!raw){return hex_hmac_md5(key,string)}return raw_hmac_md5(key,string)}if(typeof exports!=="undefined"){if(typeof module!=="undefined"&&module.exports){exports=module.exports=md5}exports.md5=md5}else{if(typeof define==="function"&&define.amd){define(function(){return md5})}else{$.md5=md5}}})(this)},{}],9:[function(require,module,exports){var has=Object.prototype.hasOwnProperty;exports.keys=Object.keys||function(obj){var keys=[];for(var key in obj){if(has.call(obj,key)){keys.push(key)}}return keys};exports.values=function(obj){var vals=[];for(var key in obj){if(has.call(obj,key)){vals.push(obj[key])}}return vals};exports.merge=function(a,b){for(var key in b){if(has.call(b,key)){a[key]=b[key]}}return a};exports.length=function(obj){return exports.keys(obj).length};exports.isEmpty=function(obj){return 0==exports.length(obj)}},{}],10:[function(require,module,exports){var querystring=require("querystring");var Request=function(url,data){this.url=url;this.data=data||{}};Request.prototype.send=function(callback){var isIE=window.XDomainRequest?true:false;if(isIE){var xdr=new window.XDomainRequest;xdr.open("POST",this.url,true);xdr.onload=function(){callback(200,xdr.responseText)};xdr.onerror=function(){if(xdr.responseText==="Request Entity Too Large"){callback(413,xdr.responseText)}else{callback(500,xdr.responseText)}};xdr.ontimeout=function(){};xdr.onprogress=function(){};xdr.send(querystring.stringify(this.data))}else{var xhr=new XMLHttpRequest;xhr.open("POST",this.url,true);xhr.onreadystatechange=function(){if(xhr.readyState===4){callback(xhr.status,xhr.responseText)}};xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8");xhr.send(querystring.stringify(this.data))}};module.exports=Request},{querystring:23}],23:[function(require,module,exports){var encode=encodeURIComponent;var decode=decodeURIComponent;var trim=require("trim");var type=require("type");exports.parse=function(str){if("string"!=typeof str)return{};str=trim(str);if(""==str)return{};if("?"==str.charAt(0))str=str.slice(1);var obj={};var pairs=str.split("&");for(var i=0;i0){if(q.length==2){if(typeof q[1]==FUNC_TYPE){result[q[0]]=q[1].call(this,match)}else{result[q[0]]=q[1]}}else if(q.length==3){if(typeof q[1]===FUNC_TYPE&&!(q[1].exec&&q[1].test)){result[q[0]]=match?q[1].call(this,match,q[2]):undefined}else{result[q[0]]=match?match.replace(q[1],q[2]):undefined}}else if(q.length==4){result[q[0]]=match?q[3].call(this,match.replace(q[1],q[2])):undefined}}else{result[q]=match?match:undefined}}}}i+=2}return result},str:function(str,map){for(var i in map){if(typeof map[i]===OBJ_TYPE&&map[i].length>0){for(var j=0;j>a/4).toString(16):([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g,uuid)};module.exports=uuid},{}],15:[function(require,module,exports){module.exports="2.9.1"},{}],16:[function(require,module,exports){var language=require("./language");module.exports={apiEndpoint:"api.amplitude.com",cookieExpiration:365*10,cookieName:"amplitude_id",domain:undefined,includeUtm:false,language:language.language,optOut:false,platform:"Web",savedMaxCount:1e3,saveEvents:true,sessionTimeout:30*60*1e3,unsentKey:"amplitude_unsent",unsentIdentifyKey:"amplitude_unsent_identify",uploadBatchSize:100,batchEvents:false,eventUploadThreshold:30,eventUploadPeriodMillis:30*1e3}},{"./language":26}],26:[function(require,module,exports){var getLanguage=function(){return navigator&&(navigator.languages&&navigator.languages[0]||navigator.language||navigator.userLanguage)||undefined};module.exports={language:getLanguage()}},{}]},{},{1:""})); \ No newline at end of file diff --git a/src/amplitude.js b/src/amplitude.js index 58070a0d..5315f8a5 100644 --- a/src/amplitude.js +++ b/src/amplitude.js @@ -563,6 +563,7 @@ Amplitude.prototype._logEvent = function(eventType, eventProperties, apiProperti callback = null; } + _loadCookieData(this); if (!eventType || this.options.optOut) { if (callback) { callback(0, 'No request sent'); diff --git a/test/amplitude.js b/test/amplitude.js index 6d958b50..347d8555 100644 --- a/test/amplitude.js +++ b/test/amplitude.js @@ -1621,6 +1621,31 @@ describe('Amplitude', function() { 'nested_object': {'k':'v', 'l':[0,1], 'o':{'k2':'v2', 'l2': ['e2']}} }); }); + + it('should synchronize event data across multiple amplitude instances that share the same cookie', function() { + // this test fails if logEvent does not reload cookie data every time + var amplitude1 = new Amplitude(); + amplitude1.init(apiKey, null, {batchEvents: true, eventUploadThreshold: 5}); + var amplitude2 = new Amplitude(); + amplitude2.init(apiKey, null, {batchEvents: true, eventUploadThreshold: 5}); + + amplitude1.logEvent('test1'); + amplitude2.logEvent('test2'); + amplitude1.logEvent('test3'); + amplitude2.logEvent('test4'); + amplitude2.identify(new amplitude2.Identify().set('key', 'value')); + amplitude1.logEvent('test5'); + + // the event ids should all be sequential since amplitude1 and amplitude2 have synchronized cookies + var eventId = amplitude1._unsentEvents[0]['event_id']; + assert.equal(amplitude2._unsentEvents[0]['event_id'], eventId + 1); + assert.equal(amplitude1._unsentEvents[1]['event_id'], eventId + 2); + assert.equal(amplitude2._unsentEvents[1]['event_id'], eventId + 3); + + var sequenceNumber = amplitude1._unsentEvents[0]['sequence_number']; + assert.equal(amplitude2._unsentIdentifys[0]['sequence_number'], sequenceNumber + 4); + assert.equal(amplitude1._unsentEvents[2]['sequence_number'], sequenceNumber + 5); + }); }); describe('optOut', function() {