Skip to content

Commit 9549176

Browse files
committed
remove caching logic for availability, refactored the universal storage
1 parent 2549028 commit 9549176

File tree

4 files changed

+86
-75
lines changed

4 files changed

+86
-75
lines changed

packages/browser/src/core/analytics/index.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import { Plugin } from '../plugin'
2626
import { EventQueue } from '../queue/event-queue'
2727
import {
2828
CookieOptions,
29+
getAvailableStorageOptions,
2930
Group,
3031
ID,
3132
UniversalStorage,
@@ -133,9 +134,11 @@ export class Analytics
133134
this.queue =
134135
queue ?? createDefaultQueue(options?.retryQueue, disablePersistance)
135136

136-
this._universalStorage = UniversalStorage.getUniversalStorage(
137-
disablePersistance ? ['memory'] : ['cookie', 'localStorage', 'memory'],
138-
cookieOptions
137+
this._universalStorage = new UniversalStorage(
138+
disablePersistance !== false
139+
? ['localStorage', 'cookie', 'memory']
140+
: ['memory'],
141+
getAvailableStorageOptions(cookieOptions)
139142
)
140143

141144
this._user =

packages/browser/src/core/user/__tests__/index.test.ts

Lines changed: 36 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
Group,
66
UniversalStorage,
77
StoreType,
8+
getAvailableStorageOptions,
89
} from '..'
910
import jar from 'js-cookie'
1011
import assert from 'assert'
@@ -956,49 +957,54 @@ describe('universal storage', function () {
956957
it('picks data from cookies first', function () {
957958
jar.set('ajs_test_key', '🍪')
958959
localStorage.setItem('ajs_test_key', '💾')
959-
const us = UniversalStorage.getUniversalStorage(defaultTargets)
960+
const us = new UniversalStorage(
961+
defaultTargets,
962+
getAvailableStorageOptions()
963+
)
960964
expect(us.get('ajs_test_key')).toEqual('🍪')
961965
})
962966

963967
it('picks data from localStorage if there is no cookie target', function () {
964968
jar.set('ajs_test_key', '🍪')
965969
localStorage.setItem('ajs_test_key', '💾')
966-
const us = UniversalStorage.getUniversalStorage([
967-
'localStorage',
968-
'memory',
969-
])
970+
const us = new UniversalStorage(
971+
['localStorage', 'memory'],
972+
getAvailableStorageOptions()
973+
)
970974
expect(us.get('ajs_test_key')).toEqual('💾')
971975
})
972976

973977
it('get data from memory', function () {
974978
jar.set('ajs_test_key', '🍪')
975979
localStorage.setItem('ajs_test_key', '💾')
976-
const us = UniversalStorage.getUniversalStorage(['memory'])
980+
const us = new UniversalStorage(['memory'], getAvailableStorageOptions())
977981
expect(us.get('ajs_test_key')).toBeNull()
978982
})
979983

980-
it('order of default targets does not matter', function () {
984+
it('order of default targets matters!', function () {
981985
jar.set('ajs_test_key', '🍪')
982986
localStorage.setItem('ajs_test_key', '💾')
983-
const us = UniversalStorage.getUniversalStorage([
984-
'localStorage',
985-
'cookie',
986-
'memory',
987-
])
987+
const us = new UniversalStorage(
988+
['cookie', 'localStorage', 'memory'],
989+
getAvailableStorageOptions()
990+
)
988991
expect(us.get('ajs_test_key')).toEqual('🍪')
989992
})
990993

991994
it('returns null if there are no storage targets', function () {
992995
jar.set('ajs_test_key', '🍪')
993996
localStorage.setItem('ajs_test_key', '💾')
994-
const us = UniversalStorage.getUniversalStorage([])
997+
const us = new UniversalStorage([], getAvailableStorageOptions())
995998
expect(us.get('ajs_test_key')).toBeNull()
996999
})
9971000

9981001
it('can override the default targets', function () {
9991002
jar.set('ajs_test_key', '🍪')
10001003
localStorage.setItem('ajs_test_key', '💾')
1001-
const us = UniversalStorage.getUniversalStorage(defaultTargets)
1004+
const us = new UniversalStorage(
1005+
defaultTargets,
1006+
getAvailableStorageOptions()
1007+
)
10021008
expect(us.get('ajs_test_key', ['localStorage'])).toEqual('💾')
10031009
expect(us.get('ajs_test_key', ['localStorage', 'memory'])).toEqual('💾')
10041010
expect(us.get('ajs_test_key', ['cookie', 'memory'])).toEqual('🍪')
@@ -1010,41 +1016,48 @@ describe('universal storage', function () {
10101016

10111017
describe('#set', function () {
10121018
it('set the data in all storage types', function () {
1013-
const us = UniversalStorage.getUniversalStorage<{ ajs_test_key: string }>(
1014-
defaultTargets
1019+
const us = new UniversalStorage<{ ajs_test_key: string }>(
1020+
defaultTargets,
1021+
getAvailableStorageOptions()
10151022
)
10161023
us.set('ajs_test_key', '💰')
10171024
expect(jar.get('ajs_test_key')).toEqual('💰')
10181025
expect(getFromLS('ajs_test_key')).toEqual('💰')
10191026
})
10201027

10211028
it('skip saving data to localStorage', function () {
1022-
const us = UniversalStorage.getUniversalStorage(['cookie', 'memory'])
1029+
const us = new UniversalStorage(
1030+
['cookie', 'memory'],
1031+
getAvailableStorageOptions()
1032+
)
10231033
us.set('ajs_test_key', '💰')
10241034
expect(jar.get('ajs_test_key')).toEqual('💰')
10251035
expect(localStorage.getItem('ajs_test_key')).toEqual(null)
10261036
})
10271037

10281038
it('skip saving data to cookie', function () {
1029-
const us = UniversalStorage.getUniversalStorage([
1030-
'localStorage',
1031-
'memory',
1032-
])
1039+
const us = new UniversalStorage(
1040+
['localStorage', 'memory'],
1041+
getAvailableStorageOptions()
1042+
)
10331043
us.set('ajs_test_key', '💰')
10341044
expect(jar.get('ajs_test_key')).toEqual(undefined)
10351045
expect(getFromLS('ajs_test_key')).toEqual('💰')
10361046
})
10371047

10381048
it('can save and retrieve from memory when there is no other storage', function () {
1039-
const us = UniversalStorage.getUniversalStorage(['memory'])
1049+
const us = new UniversalStorage(['memory'], getAvailableStorageOptions())
10401050
us.set('ajs_test_key', '💰')
10411051
expect(jar.get('ajs_test_key')).toEqual(undefined)
10421052
expect(localStorage.getItem('ajs_test_key')).toEqual(null)
10431053
expect(us.get('ajs_test_key')).toEqual('💰')
10441054
})
10451055

10461056
it('can override the default targets', function () {
1047-
const us = UniversalStorage.getUniversalStorage(defaultTargets)
1057+
const us = new UniversalStorage(
1058+
defaultTargets,
1059+
getAvailableStorageOptions()
1060+
)
10481061
us.set('ajs_test_key', '💰', ['localStorage'])
10491062
expect(jar.get('ajs_test_key')).toEqual(undefined)
10501063
expect(getFromLS('ajs_test_key')).toEqual('💰')

packages/browser/src/core/user/index.ts

Lines changed: 38 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -62,12 +62,7 @@ class Store {
6262
const ONE_YEAR = 365
6363

6464
export class Cookie extends Store {
65-
static _available: boolean | undefined
6665
static available(): boolean {
67-
if (Cookie._available !== undefined) {
68-
return Cookie._available
69-
}
70-
7166
let cookieEnabled = window.navigator.cookieEnabled
7267

7368
if (!cookieEnabled) {
@@ -76,8 +71,6 @@ export class Cookie extends Store {
7671
jar.remove('ajs:cookies')
7772
}
7873

79-
Cookie._available = cookieEnabled
80-
8174
return cookieEnabled
8275
}
8376

@@ -153,21 +146,13 @@ const localStorageWarning = (key: string, state: 'full' | 'unavailable') => {
153146
}
154147

155148
export class LocalStorage extends Store {
156-
static _available: boolean | undefined
157-
158149
static available(): boolean {
159-
if (LocalStorage._available !== undefined) {
160-
return LocalStorage._available
161-
}
162-
163150
const test = 'test'
164151
try {
165152
localStorage.setItem(test, test)
166153
localStorage.removeItem(test)
167-
LocalStorage._available = true
168154
return true
169155
} catch (e) {
170-
LocalStorage._available = false
171156
return false
172157
}
173158
}
@@ -221,16 +206,26 @@ export interface CookieOptions {
221206
}
222207

223208
export class UniversalStorage<Data extends StorageObject = StorageObject> {
224-
private stores: Store[]
209+
private enabledStores: StoreType[]
210+
private storageOptions: StorageOptions
225211

226-
constructor(stores?: Store[]) {
227-
this.stores = stores || []
212+
constructor(stores: StoreType[], storageOptions: StorageOptions) {
213+
this.storageOptions = storageOptions
214+
this.enabledStores = stores
228215
}
229216

230217
private getStores(storeTypes: StoreType[] | undefined): Store[] {
231-
return storeTypes
232-
? this.stores.filter((s) => storeTypes.indexOf(s.type) !== -1)
233-
: this.stores
218+
const stores: Store[] = []
219+
this.enabledStores
220+
.filter((i) => !storeTypes || storeTypes?.includes(i))
221+
.forEach((storeType) => {
222+
const storage = this.storageOptions[storeType]
223+
if (storage !== undefined) {
224+
stores.push(storage)
225+
}
226+
})
227+
228+
return stores
234229
}
235230

236231
/*
@@ -283,26 +278,21 @@ export class UniversalStorage<Data extends StorageObject = StorageObject> {
283278
store.remove(key)
284279
}
285280
}
281+
}
286282

287-
static getUniversalStorage<T extends Record<string, unknown>>(
288-
defaultTargets: StoreType[] = ['cookie', 'localStorage', 'memory'],
289-
cookieOptions?: CookieOptions
290-
): UniversalStorage<T> {
291-
const stores = []
292-
293-
if (defaultTargets.includes('cookie') && Cookie.available()) {
294-
stores.push(new Cookie(cookieOptions))
295-
}
296-
297-
if (defaultTargets.includes('localStorage') && LocalStorage.available()) {
298-
stores.push(new LocalStorage())
299-
}
300-
301-
if (defaultTargets.includes('memory')) {
302-
stores.push(new Store())
303-
}
283+
type StorageOptions = {
284+
cookie: Cookie | undefined
285+
localStorage: LocalStorage | undefined
286+
memory: Store
287+
}
304288

305-
return new UniversalStorage<T>(stores)
289+
export function getAvailableStorageOptions(
290+
cookieOptions?: CookieOptions
291+
): StorageOptions {
292+
return {
293+
cookie: Cookie.available() ? new Cookie(cookieOptions) : undefined,
294+
localStorage: LocalStorage.available() ? new LocalStorage() : undefined,
295+
memory: new Store(),
306296
}
307297
}
308298

@@ -346,32 +336,34 @@ export class User {
346336
let defaultStorageTargets: StoreType[] = isDisabled
347337
? []
348338
: shouldPersist
349-
? ['cookie', 'localStorage', 'memory']
339+
? ['localStorage', 'cookie', 'memory']
350340
: ['memory']
351341

342+
const storageOptions = getAvailableStorageOptions(cookieOptions)
343+
352344
if (options.localStorageFallbackDisabled) {
353345
defaultStorageTargets = defaultStorageTargets.filter(
354346
(t) => t !== 'localStorage'
355347
)
356348
}
357349

358-
this.identityStore = UniversalStorage.getUniversalStorage(
350+
this.identityStore = new UniversalStorage(
359351
defaultStorageTargets,
360-
cookieOptions
352+
storageOptions
361353
)
362354

363355
// using only cookies for legacy user store
364-
this.legacyUserStore = UniversalStorage.getUniversalStorage(
356+
this.legacyUserStore = new UniversalStorage(
365357
defaultStorageTargets.filter(
366358
(t) => t !== 'localStorage' && t !== 'memory'
367359
),
368-
cookieOptions
360+
storageOptions
369361
)
370362

371363
// using only localStorage / memory for traits store
372-
this.traitsStore = UniversalStorage.getUniversalStorage(
364+
this.traitsStore = new UniversalStorage(
373365
defaultStorageTargets.filter((t) => t !== 'cookie'),
374-
cookieOptions
366+
storageOptions
375367
)
376368

377369
const legacyUser = this.legacyUserStore.get(defaults.cookie.oldKey)

packages/browser/src/plugins/segmentio/normalize.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { tld } from '../../core/user/tld'
77
import { SegmentFacade } from '../../lib/to-facade'
88
import { SegmentioSettings } from './index'
99
import { version } from '../../generated/version'
10-
import { UniversalStorage } from '../../core/user'
10+
import { getAvailableStorageOptions, UniversalStorage } from '../../core/user'
1111

1212
let cookieOptions: jar.CookieAttributes | undefined
1313
function getCookieOptions(): jar.CookieAttributes {
@@ -95,9 +95,12 @@ function referrerId(
9595
ctx: SegmentEvent['context'],
9696
disablePersistance: boolean
9797
): void {
98-
const storage = UniversalStorage.getUniversalStorage<{
98+
const storage = new UniversalStorage<{
9999
's:context.referrer': Ad
100-
}>(disablePersistance ? [] : ['cookie'], getCookieOptions())
100+
}>(
101+
disablePersistance ? [] : ['cookie'],
102+
getAvailableStorageOptions(getCookieOptions())
103+
)
101104

102105
const stored = storage.get('s:context.referrer')
103106
let ad: Ad | undefined | null = ads(query)

0 commit comments

Comments
 (0)