From 1be846f78abb546d340f1436c2fd963d0572b95b Mon Sep 17 00:00:00 2001 From: Sai Kumar Battinoju Date: Fri, 28 Jul 2023 10:57:02 +0530 Subject: [PATCH] fix: almost final changes for the feature --- src/core/analytics.js | 29 ++++++++++++++++++-------- src/features/core/session/index.js | 9 ++++---- src/utils/storage/memoryStorage.js | 1 + src/utils/storage/storage.js | 33 ++++++++++++++++++++++-------- src/utils/storage/store.js | 3 ++- 5 files changed, 52 insertions(+), 23 deletions(-) diff --git a/src/core/analytics.js b/src/core/analytics.js index 88507e7b8..a58a9cbcf 100644 --- a/src/core/analytics.js +++ b/src/core/analytics.js @@ -711,14 +711,18 @@ class Analytics { const clonedTraits = R.clone(traits); const clonedOptions = R.clone(options); + const curUserTraits = this.getUserTraits(); if (clonedTraits) { - const curUserTraits = this.getUserTraits(); for (const key in clonedTraits) { curUserTraits[key] = clonedTraits[key]; } - this.storage.setUserTraits(curUserTraits); } const rudderElement = new RudderElementBuilder().setType('identify').build(); + rudderElement.setUserId(normalisedUserId); + rudderElement.message.context.traits = { + ...curUserTraits, + }; + this.storage.setUserTraits(curUserTraits); this.processAndSendDataToDestinations('identify', rudderElement, clonedOptions, callback); } @@ -774,11 +778,13 @@ class Analytics { if (typeof groupId === 'function') (callback = groupId), (options = null), (traits = null), (groupId = this.getGroupId()); - this.storage.setGroupId(getStringId(groupId)); + const normalizedGroupId = getStringId(groupId); + this.storage.setGroupId(normalizedGroupId); const clonedTraits = R.clone(traits); const clonedOptions = R.clone(options); const rudderElement = new RudderElementBuilder().setType('group').build(); + rudderElement.message.groupId = normalizedGroupId; let curGroupTraits; if (clonedTraits) { @@ -790,6 +796,9 @@ class Analytics { curGroupTraits = {}; } this.storage.setGroupTraits(curGroupTraits); + rudderElement.message.traits = { + ...curGroupTraits, + }; this.processAndSendDataToDestinations('group', rudderElement, clonedOptions, callback); } @@ -862,9 +871,11 @@ class Analytics { // assign page properties to context // rudderElement.message.context.page = getDefaultPageProperties(); this.errorReporting.leaveBreadcrumb('Started sending data to destinations'); - rudderElement.message.context.traits = { - ...this.getUserTraits(), - }; + rudderElement.message.context.traits = rudderElement.message.context.traits + ? rudderElement.message.context.traits + : { + ...this.getUserTraits(), + }; // logger.debug("anonymousId: ", this.storage.getAnonymousId()) rudderElement.message.anonymousId = this.getAnonymousId(); @@ -874,10 +885,12 @@ class Analytics { if (type == 'group') { if (this.getGroupId()) { - rudderElement.message.groupId = this.getGroupId(); + rudderElement.message.groupId = rudderElement.message.groupId + ? rudderElement.message.groupId : this.getGroupId(); } if (this.getGroupTraits()) { - rudderElement.message.traits = { + rudderElement.message.traits = rudderElement.message.traits + ? rudderElement.message.traits : { ...this.getGroupTraits(), }; } diff --git a/src/features/core/session/index.js b/src/features/core/session/index.js index 0bcbd8913..5d67b2dae 100644 --- a/src/features/core/session/index.js +++ b/src/features/core/session/index.js @@ -83,8 +83,7 @@ class UserSession { * @param {number} timestamp * @returns boolean */ - isValidSession(timestamp) { - const sessionInfo = this.getSafeSessionInfo(); + isValidSession(sessionInfo, timestamp) { return timestamp <= sessionInfo.expiresAt; } @@ -102,7 +101,7 @@ class UserSession { startAutoTracking(sessionInfo) { let finalSessionInfo = sessionInfo; const timestamp = Date.now(); - if (!this.isValidSession(timestamp)) { + if (!this.isValidSession(finalSessionInfo, timestamp)) { finalSessionInfo = { id: timestamp, // set the current timestamp expiresAt: timestamp + this.timeout, // set the expiry time of the session @@ -156,7 +155,7 @@ class UserSession { getSessionId() { const sessionInfo = this.getSafeSessionInfo(); if ( - (sessionInfo.autoTrack && this.isValidSession(Date.now())) || + (sessionInfo.autoTrack && this.isValidSession(sessionInfo, Date.now())) || sessionInfo.manualTrack ) { return sessionInfo.id; @@ -181,7 +180,7 @@ class UserSession { // renew or create a new auto-tracking session if (sessionInfo.autoTrack) { const timestamp = Date.now(); - if (!this.isValidSession(timestamp)) { + if (!this.isValidSession(sessionInfo, timestamp)) { sessionInfo = this.startAutoTracking(sessionInfo); } else { sessionInfo.expiresAt = timestamp + this.timeout; // set the expiry time of the session diff --git a/src/utils/storage/memoryStorage.js b/src/utils/storage/memoryStorage.js index 59cdb7844..8b00c78ce 100644 --- a/src/utils/storage/memoryStorage.js +++ b/src/utils/storage/memoryStorage.js @@ -15,6 +15,7 @@ class InMemoryStorage { constructor(options) { this.opts = { enabled: true }; this.options(options ?? {}); + this.isSupportAvailable = true; } options(inOpts) { diff --git a/src/utils/storage/storage.js b/src/utils/storage/storage.js index f5eecaad7..f5dd120c3 100644 --- a/src/utils/storage/storage.js +++ b/src/utils/storage/storage.js @@ -137,18 +137,18 @@ class Storage { }; } - options(options = {}) { - const globalStorageType = get(options, 'storage.type'); + options(opts = {}) { + const globalStorageType = opts.type; Object.keys(this.storageEntries).forEach((entry) => { - const storageType = globalStorageType || get(options, `storage.entries.${entry}.type`) || 'cookie'; + const storageType = get(opts, `entries.${entry}.type`) || globalStorageType || 'cookie'; let selectedStorage = null; switch (storageType) { case 'cookie': { if (Cookie.isSupportAvailable) { selectedStorage = Cookie; - } else if (Store.enabled) { + } else if (Store.isSupportAvailable) { selectedStorage = Store; } else { selectedStorage = defaultInMemoryStorage; @@ -157,7 +157,7 @@ class Storage { } case 'localStorage': { - if (Store.enabled) { + if (Store.isSupportAvailable) { selectedStorage = Store; } else { selectedStorage = defaultInMemoryStorage; @@ -170,15 +170,30 @@ class Storage { case 'none': default: selectedStorage = null; + break; } if (selectedStorage) { - selectedStorage.options(options); + selectedStorage.options(opts); } this.storageEntries[entry].storage = selectedStorage; + this.migrateDataFromPreviousStorage(selectedStorage, entry); }); + } - // TODO: Migrate any existing data from previous storage - // TODO: Delete storage data if the storage type is memory or none + migrateDataFromPreviousStorage(curStorage, entry) { + // in the increasing order of preference + const storages = [Store, Cookie]; + storages.forEach((stg) => { + if (stg !== curStorage && stg.isSupportAvailable) { + const value = stg.get(this.storageEntries[entry].key); + if (value) { + if (curStorage) { + curStorage.set(this.storageEntries[entry].key, value); + } + stg.remove(this.storageEntries[entry].key); + } + } + }); } /** @@ -332,7 +347,7 @@ class Storage { * First check the local storage for anonymousId * Ref: https://segment.com/docs/connections/sources/catalog/libraries/website/javascript/#identify */ - if (Store.enabled) { + if (Store.isSupportAvailable) { anonId = Store.get(anonymousIdKeyMap[key]); } // If anonymousId is not present in local storage and check cookie support exists diff --git a/src/utils/storage/store.js b/src/utils/storage/store.js index f2d3ffb5c..5ccdb62fb 100644 --- a/src/utils/storage/store.js +++ b/src/utils/storage/store.js @@ -7,7 +7,8 @@ import store from 'storejs'; class StoreLocal { constructor(options) { this.sOpts = {}; - this.enabled = this.checkSupportAvailability(); + this.isSupportAvailable = this.checkSupportAvailability(); + this.enabled = this.isSupportAvailable; this.options(options); }