Skip to content

Commit 9bea59c

Browse files
committed
migrate cookie to local storage
1 parent 7f64a97 commit 9bea59c

File tree

3 files changed

+295
-137
lines changed

3 files changed

+295
-137
lines changed

amplitude.js

Lines changed: 147 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
146145
var 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

284385
Amplitude.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-
360438
Amplitude._getUtmParam = function(name, query) {
361439
name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
362440
var regex = new RegExp("[\\?&]" + name + "=([^&#]*)");
@@ -405,8 +483,8 @@ Amplitude.prototype._getReferringDomain = function() {
405483

406484
Amplitude.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) {
429509
Amplitude.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) {
439519
Amplitude.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

Comments
 (0)