@@ -136,19 +136,25 @@ var DEFAULT_OPTIONS = {
136136 savedMaxCount : 1000 ,
137137 saveEvents : true ,
138138 sessionTimeout : 30 * 60 * 1000 ,
139- unsentKey : 'amplitude_unsent' ,
140- unsentIdentifyKey : 'amplitude_unsent_identify' ,
141139 uploadBatchSize : 100 ,
142140 batchEvents : false ,
143141 eventUploadThreshold : 30 ,
144142 eventUploadPeriodMillis : 30 * 1000 // 30s
145143} ;
144+
146145var LocalStorageKeys = {
147146 LAST_EVENT_ID : 'amplitude_lastEventId' ,
148147 LAST_IDENTIFY_ID : 'amplitude_lastIdentifyId' ,
149148 LAST_SEQUENCE_NUMBER : 'amplitude_lastSequenceNumber' ,
150149 LAST_EVENT_TIME : 'amplitude_lastEventTime' ,
151- SESSION_ID : 'amplitude_sessionId'
150+ SESSION_ID : 'amplitude_sessionId' ,
151+ UNSENT_EVENTS : 'amplitude_unsent' ,
152+ UNSENT_IDENTIFYS : 'amplitude_unsent_identify' ,
153+
154+ // Previously stored in cookie
155+ DEVICE_ID : 'amplitude_deviceId' ,
156+ USER_ID : 'amplitude_userId' ,
157+ OPT_OUT : 'amplitude_optOut'
152158} ;
153159
154160/*
@@ -216,41 +222,21 @@ Amplitude.prototype.init = function(apiKey, opt_userId, opt_config, callback) {
216222 } ) ;
217223 this . options . domain = Cookie . options ( ) . domain ;
218224
219- _loadCookieData ( this ) ;
220-
221- this . options . deviceId = ( opt_config && opt_config . deviceId !== undefined &&
222- opt_config . deviceId !== null && opt_config . deviceId ) ||
223- this . options . deviceId || UUID ( ) ;
224- this . options . userId = ( opt_userId !== undefined && opt_userId !== null && opt_userId ) || this . options . userId || null ;
225- _saveCookieData ( this ) ;
225+ debugger ;
226226
227- //log('initialized with apiKey=' + apiKey );
228- //opt_userId !== undefined && opt_userId !== null && log('initialized with userId=' + opt_userId );
227+ this . _upgradeStoredData ( ) ;
228+ this . _loadStoredData ( ) ;
229229
230- if ( this . options . saveEvents ) {
231- this . _loadSavedUnsentEvents ( this . options . unsentKey , '_unsentEvents' ) ;
232- this . _loadSavedUnsentEvents ( this . options . unsentIdentifyKey , '_unsentIdentifys' ) ;
233- }
230+ this . setUserId ( opt_userId || this . options . userId || null ) ;
231+ this . setDeviceId ( opt_config && opt_config . deviceId !== undefined &&
232+ opt_config . deviceId !== null && opt_config . deviceId ||
233+ this . options . deviceId || UUID ( ) ) ;
234234
235235 this . _sendEventsIfReady ( ) ;
236236
237237 if ( this . options . includeUtm ) {
238238 this . _initUtmData ( ) ;
239239 }
240-
241- this . _lastEventTime = parseInt ( localStorage . getItem ( LocalStorageKeys . LAST_EVENT_TIME ) ) || null ;
242- this . _sessionId = parseInt ( localStorage . getItem ( LocalStorageKeys . SESSION_ID ) ) || null ;
243- this . _eventId = localStorage . getItem ( LocalStorageKeys . LAST_EVENT_ID ) || 0 ;
244- this . _identifyId = localStorage . getItem ( LocalStorageKeys . LAST_IDENTIFY_ID ) || 0 ;
245- this . _sequenceNumber = localStorage . getItem ( LocalStorageKeys . LAST_SEQUENCE_NUMBER ) || 0 ;
246- var now = new Date ( ) . getTime ( ) ;
247- if ( ! this . _sessionId || ! this . _lastEventTime || now - this . _lastEventTime > this . options . sessionTimeout ) {
248- this . _newSession = true ;
249- this . _sessionId = now ;
250- localStorage . setItem ( LocalStorageKeys . SESSION_ID , this . _sessionId ) ;
251- }
252- this . _lastEventTime = now ;
253- localStorage . setItem ( LocalStorageKeys . LAST_EVENT_TIME , this . _lastEventTime ) ;
254240 } catch ( e ) {
255241 log ( e ) ;
256242 }
@@ -270,15 +256,130 @@ Amplitude.prototype.runQueuedFunctions = function () {
270256 this . _q = [ ] ; // clear function queue after running
271257} ;
272258
273- Amplitude . prototype . _loadSavedUnsentEvents = function ( unsentKey , queue ) {
274- var savedUnsentEventsString = localStorage . getItem ( unsentKey ) ;
259+ /**
260+ * Set an item in local storage. Decorate item key with the api key
261+ * to avoid collisions.
262+ *
263+ * @property item: name of the item to store
264+ * @property value: the value to store
265+ */
266+ Amplitude . prototype . setLocalStorage = function ( item , value ) {
267+ var key = LocalStorageKeys [ item ] + '_' + this . options . apiKey . slice ( 0 , 6 ) ;
268+ localStorage . setItem ( key , value ) ;
269+ } ;
270+
271+ /**
272+ * Fetch an item from local storage. Decorate item key with api key
273+ * to avoid collisions.
274+ *
275+ * @property item: name of the item to fetch
276+ * @property def: default value to return if the item does not exist
277+ */
278+ Amplitude . prototype . getLocalStorage = function ( item , def ) {
279+ var key = LocalStorageKeys [ item ] + '_' + this . options . apiKey . slice ( 0 , 6 ) ;
280+ return localStorage . getItem ( key ) || def ;
281+ } ;
282+
283+ Amplitude . prototype . _upgradeStoredData = function ( ) {
284+ // migrate data from cookie to local storage
285+ var cookieData = Cookie . get ( this . options . cookieName ) ;
286+ if ( cookieData ) {
287+ if ( cookieData . deviceId ) {
288+ this . setLocalStorage ( 'DEVICE_ID' , cookieData . deviceId ) ;
289+ }
290+ if ( cookieData . userId ) {
291+ this . setLocalStorage ( 'USER_ID' , cookieData . userId ) ;
292+ }
293+ if ( cookieData . optOut !== undefined ) {
294+ this . setLocalStorage ( 'OPT_OUT' , cookieData . optOut ) ;
295+ }
296+ // Cookie.remove(this.options.cookieName);
297+ }
298+
299+ // update local storage keys to prevent conflicts
300+ var lastEventId = localStorage . getItem ( LocalStorageKeys . LAST_EVENT_ID ) ;
301+ if ( lastEventId ) {
302+ this . setLocalStorage ( 'LAST_EVENT_ID' , lastEventId ) ;
303+ // localStorage.removeItem(LocalStorageKeys.LAST_EVENT_ID);
304+ }
305+
306+ var lastIdentifyId = localStorage . getItem ( LocalStorageKeys . LAST_IDENTIFY_ID ) ;
307+ if ( lastIdentifyId ) {
308+ this . setLocalStorage ( 'LAST_IDENTIFY_ID' , lastIdentifyId ) ;
309+ // localStorage.removeItem(LocalStorageKeys.LAST_IDENTIFY_ID);
310+ }
311+
312+ var lastSequenceNumber = localStorage . getItem ( LocalStorageKeys . LAST_SEQUENCE_NUMBER ) ;
313+ if ( lastSequenceNumber ) {
314+ this . setLocalStorage ( 'LAST_SEQUENCE_NUMBER' , lastSequenceNumber ) ;
315+ // localStorage.removeItem(LocalStorageKeys.LAST_SEQUENCE_NUMBER);
316+ }
317+
318+ var lastEventTime = localStorage . getItem ( LocalStorageKeys . LAST_EVENT_TIME ) ;
319+ if ( lastEventTime ) {
320+ this . setLocalStorage ( 'LAST_EVENT_TIME' , lastEventTime ) ;
321+ // localStorage.removeItem(LocalStorageKeys.LAST_EVENT_TIME);
322+ }
323+
324+ var sessionId = localStorage . getItem ( LocalStorageKeys . SESSION_ID ) ;
325+ if ( sessionId ) {
326+ this . setLocalStorage ( 'SESSION_ID' , sessionId ) ;
327+ // localStorage.removeItem(LocalStorageKeys.SESSION_ID);
328+ }
329+
330+ var unsentEventsString = localStorage . getItem ( LocalStorageKeys . UNSENT_EVENTS ) ;
331+ if ( unsentEventsString ) {
332+ this . setLocalStorage ( 'UNSENT_EVENTS' , unsentEventsString ) ;
333+ // localStorage.removeItem(LocalStorageKeys.UNSENT_EVENTS);
334+ }
335+
336+ var unsentIdentifysString = localStorage . getItem ( LocalStorageKeys . UNSENT_IDENTIFYS ) ;
337+ if ( unsentIdentifysString ) {
338+ this . setLocalStorage ( 'UNSENT_IDENTIFYS' , unsentIdentifysString ) ;
339+ // localStorage.removeItem(LocalStorageKeys.UNSENT_IDENTIFYS);
340+ }
341+ } ;
342+
343+ Amplitude . prototype . _loadStoredData = function ( ) {
344+ if ( this . options . saveEvents ) {
345+ this . _unsentEvents = this . _loadSavedUnsentEvents ( 'UNSENT_EVENTS' ) ;
346+ this . _unsentIdentifys = this . _loadSavedUnsentEvents ( 'UNSENT_IDENTIFYS' ) ;
347+ }
348+
349+ try {
350+ this . options . deviceId = this . getLocalStorage ( 'DEVICE_ID' , this . options . deviceId ) ;
351+ this . options . userId = this . getLocalStorage ( 'USER_ID' , this . options . userId ) ;
352+ this . options . optOut = ( this . getLocalStorage ( 'OPT_OUT' , String ( this . options . optOut || false ) ) === 'true' ) ;
353+
354+ this . _lastEventTime = parseInt ( this . getLocalStorage ( 'LAST_EVENT_TIME' ) ) ;
355+ this . _sessionId = parseInt ( this . getLocalStorage ( 'SESSION_ID' ) ) ;
356+ this . _eventId = parseInt ( this . getLocalStorage ( 'LAST_EVENT_ID' , 0 ) ) ;
357+ this . _identifyId = parseInt ( this . getLocalStorage ( 'LAST_IDENTIFY_ID' , 0 ) ) ;
358+ this . _sequenceNumber = parseInt ( this . getLocalStorage ( 'LAST_SEQUENCE_NUMBER' , 0 ) ) ;
359+
360+ var now = new Date ( ) . getTime ( ) ;
361+ if ( ! this . _sessionId || ! this . _lastEventTime || now - this . _lastEventTime > this . options . sessionTimeout ) {
362+ this . _newSession = true ;
363+ this . _sessionId = now ;
364+ this . setLocalStorage ( 'SESSION_ID' , this . _sessionId ) ;
365+ }
366+ this . _lastEventTime = now ;
367+ this . setLocalStorage ( 'LAST_EVENT_TIME' , this . _lastEventTime ) ;
368+ } catch ( e ) {
369+ log ( e ) ;
370+ }
371+ } ;
372+
373+ Amplitude . prototype . _loadSavedUnsentEvents = function ( unsentKey ) {
374+ var savedUnsentEventsString = this . getLocalStorage ( unsentKey ) ;
275375 if ( savedUnsentEventsString ) {
276376 try {
277- this [ queue ] = JSON . parse ( savedUnsentEventsString ) ;
377+ return JSON . parse ( savedUnsentEventsString ) ;
278378 } catch ( e ) {
279379 //log(e);
280380 }
281381 }
382+ return [ ] ;
282383} ;
283384
284385Amplitude . prototype . isNewSession = function ( ) {
@@ -334,29 +435,6 @@ Amplitude.prototype._sendEventsIfReady = function(callback) {
334435 return false ;
335436} ;
336437
337- var _loadCookieData = function ( scope ) {
338- var cookieData = Cookie . get ( scope . options . cookieName ) ;
339- if ( cookieData ) {
340- if ( cookieData . deviceId ) {
341- scope . options . deviceId = cookieData . deviceId ;
342- }
343- if ( cookieData . userId ) {
344- scope . options . userId = cookieData . userId ;
345- }
346- if ( cookieData . optOut !== undefined ) {
347- scope . options . optOut = cookieData . optOut ;
348- }
349- }
350- } ;
351-
352- var _saveCookieData = function ( scope ) {
353- Cookie . set ( scope . options . cookieName , {
354- deviceId : scope . options . deviceId ,
355- userId : scope . options . userId ,
356- optOut : scope . options . optOut
357- } ) ;
358- } ;
359-
360438Amplitude . _getUtmParam = function ( name , query ) {
361439 name = name . replace ( / [ \[ ] / , "\\[" ) . replace ( / [ \] ] / , "\\]" ) ;
362440 var regex = new RegExp ( "[\\?&]" + name + "=([^&#]*)" ) ;
@@ -405,8 +483,8 @@ Amplitude.prototype._getReferringDomain = function() {
405483
406484Amplitude . prototype . saveEvents = function ( ) {
407485 try {
408- localStorage . setItem ( this . options . unsentKey , JSON . stringify ( this . _unsentEvents ) ) ;
409- localStorage . setItem ( this . options . unsentIdentifyKey , JSON . stringify ( this . _unsentIdentifys ) ) ;
486+ this . setLocalStorage ( 'UNSENT_EVENTS' , JSON . stringify ( this . _unsentEvents ) ) ;
487+ this . setLocalStorage ( 'UNSENT_IDENTIFYS' , JSON . stringify ( this . _unsentIdentifys ) ) ;
410488 } catch ( e ) {
411489 //log(e);
412490 }
@@ -418,8 +496,10 @@ Amplitude.prototype.setDomain = function(domain) {
418496 domain : domain
419497 } ) ;
420498 this . options . domain = Cookie . options ( ) . domain ;
421- _loadCookieData ( this ) ;
422- _saveCookieData ( this ) ;
499+
500+ this . _upgradeStoredData ( ) ;
501+ this . _loadStoredData ( ) ;
502+
423503 //log('set domain=' + domain);
424504 } catch ( e ) {
425505 log ( e ) ;
@@ -429,7 +509,7 @@ Amplitude.prototype.setDomain = function(domain) {
429509Amplitude . prototype . setUserId = function ( userId ) {
430510 try {
431511 this . options . userId = ( userId !== undefined && userId !== null && ( '' + userId ) ) || null ;
432- _saveCookieData ( this ) ;
512+ this . setLocalStorage ( 'USER_ID' , this . options . userId ) ;
433513 //log('set userId=' + userId);
434514 } catch ( e ) {
435515 log ( e ) ;
@@ -439,7 +519,7 @@ Amplitude.prototype.setUserId = function(userId) {
439519Amplitude . prototype . setOptOut = function ( enable ) {
440520 try {
441521 this . options . optOut = enable ;
442- _saveCookieData ( this ) ;
522+ this . setLocalStorage ( 'OPT_OUT' , this . options . optOut ) ;
443523 //log('set optOut=' + enable);
444524 } catch ( e ) {
445525 log ( e ) ;
@@ -450,7 +530,7 @@ Amplitude.prototype.setDeviceId = function(deviceId) {
450530 try {
451531 if ( deviceId ) {
452532 this . options . deviceId = ( '' + deviceId ) ;
453- _saveCookieData ( this ) ;
533+ this . setLocalStorage ( 'DEVICE_ID' , this . options . deviceId ) ;
454534 }
455535 } catch ( e ) {
456536 log ( e ) ;
@@ -540,19 +620,19 @@ Amplitude.prototype._logEvent = function(eventType, eventProperties, apiProperti
540620 var eventId ;
541621 if ( eventType === IDENTIFY_EVENT ) {
542622 eventId = this . nextIdentifyId ( ) ;
543- localStorage . setItem ( LocalStorageKeys . LAST_IDENTIFY_ID , eventId ) ;
623+ this . setLocalStorage ( ' LAST_IDENTIFY_ID' , eventId ) ;
544624 } else {
545625 eventId = this . nextEventId ( ) ;
546- localStorage . setItem ( LocalStorageKeys . LAST_EVENT_ID , eventId ) ;
626+ this . setLocalStorage ( ' LAST_EVENT_ID' , eventId ) ;
547627 }
548628 var eventTime = new Date ( ) . getTime ( ) ;
549629 var ua = this . _ua ;
550630 if ( ! this . _sessionId || ! this . _lastEventTime || eventTime - this . _lastEventTime > this . options . sessionTimeout ) {
551631 this . _sessionId = eventTime ;
552- localStorage . setItem ( LocalStorageKeys . SESSION_ID , this . _sessionId ) ;
632+ this . setLocalStorage ( ' SESSION_ID' , this . _sessionId ) ;
553633 }
554634 this . _lastEventTime = eventTime ;
555- localStorage . setItem ( LocalStorageKeys . LAST_EVENT_TIME , this . _lastEventTime ) ;
635+ this . setLocalStorage ( ' LAST_EVENT_TIME' , this . _lastEventTime ) ;
556636
557637 userProperties = userProperties || { } ;
558638 // Only add utm properties to user properties for events
0 commit comments