-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathindex.ts
More file actions
104 lines (87 loc) · 4.5 KB
/
Copy pathindex.ts
File metadata and controls
104 lines (87 loc) · 4.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
import { ImpressionsCacheInMemory } from '../inMemory/ImpressionsCacheInMemory';
import { ImpressionCountsCacheInMemory } from '../inMemory/ImpressionCountsCacheInMemory';
import { EventsCacheInMemory } from '../inMemory/EventsCacheInMemory';
import { IStorageFactoryParams, IStorageSync, IStorageSyncFactory, StorageAdapter } from '../types';
import { validatePrefix } from '../KeyBuilder';
import { KeyBuilderCS, myLargeSegmentsKeyBuilder } from '../KeyBuilderCS';
import { isLocalStorageAvailable, isValidStorageWrapper, isWebStorage } from '../../utils/env/isLocalStorageAvailable';
import { SplitsCacheInLocal } from './SplitsCacheInLocal';
import { RBSegmentsCacheInLocal } from './RBSegmentsCacheInLocal';
import { MySegmentsCacheInLocal } from './MySegmentsCacheInLocal';
import { InMemoryStorageCSFactory } from '../inMemory/InMemoryStorageCS';
import { LOG_PREFIX } from './constants';
import { STORAGE_LOCALSTORAGE } from '../../utils/constants';
import { shouldRecordTelemetry, TelemetryCacheInMemory } from '../inMemory/TelemetryCacheInMemory';
import { UniqueKeysCacheInMemoryCS } from '../inMemory/UniqueKeysCacheInMemoryCS';
import { getMatching } from '../../utils/key';
import { validateCache } from './validateCache';
import { ILogger } from '../../logger/types';
import SplitIO from '../../../types/splitio';
import { storageAdapter } from './storageAdapter';
function validateStorage(log: ILogger, prefix: string, wrapper?: SplitIO.StorageWrapper): StorageAdapter | undefined {
if (wrapper) {
if (isValidStorageWrapper(wrapper)) {
return isWebStorage(wrapper) ?
wrapper as StorageAdapter: // localStorage and sessionStorage don't need adapter
storageAdapter(log, prefix, wrapper);
}
log.warn(LOG_PREFIX + 'Invalid storage provided. Falling back to LocalStorage API');
}
if (isLocalStorageAvailable()) return localStorage;
log.warn(LOG_PREFIX + 'LocalStorage API is unavailable. Falling back to default MEMORY storage');
}
/**
* InLocal storage factory for standalone client-side SplitFactory
*/
export function InLocalStorage(options: SplitIO.InLocalStorageOptions = {}): IStorageSyncFactory {
const prefix = validatePrefix(options.prefix);
function InLocalStorageCSFactory(params: IStorageFactoryParams): IStorageSync {
const { settings, settings: { log, scheduler: { impressionsQueueSize, eventsQueueSize } } } = params;
const storage = validateStorage(log, prefix, options.wrapper);
if (!storage) return InMemoryStorageCSFactory(params);
const matchingKey = getMatching(settings.core.key);
const keys = new KeyBuilderCS(prefix, matchingKey);
const splits = new SplitsCacheInLocal(settings, keys, storage);
const rbSegments = new RBSegmentsCacheInLocal(settings, keys, storage);
const segments = new MySegmentsCacheInLocal(log, keys, storage);
const largeSegments = new MySegmentsCacheInLocal(log, myLargeSegmentsKeyBuilder(prefix, matchingKey), storage);
let validateCachePromise: Promise<boolean> | undefined;
return {
splits,
rbSegments,
segments,
largeSegments,
impressions: new ImpressionsCacheInMemory(impressionsQueueSize),
impressionCounts: new ImpressionCountsCacheInMemory(),
events: new EventsCacheInMemory(eventsQueueSize),
telemetry: shouldRecordTelemetry(params) ? new TelemetryCacheInMemory(splits, segments) : undefined,
uniqueKeys: new UniqueKeysCacheInMemoryCS(),
validateCache() {
return validateCachePromise || (validateCachePromise = validateCache(options, storage, settings, keys, splits, rbSegments, segments, largeSegments));
},
save() {
return storage.save && storage.save();
},
destroy() {
return storage.whenSaved && storage.whenSaved();
},
// When using shared instantiation with MEMORY we reuse everything but segments (they are customer per key).
shared(matchingKey: string) {
return {
splits: this.splits,
rbSegments: this.rbSegments,
segments: new MySegmentsCacheInLocal(log, new KeyBuilderCS(prefix, matchingKey), storage),
largeSegments: new MySegmentsCacheInLocal(log, myLargeSegmentsKeyBuilder(prefix, matchingKey), storage),
impressions: this.impressions,
impressionCounts: this.impressionCounts,
events: this.events,
telemetry: this.telemetry,
uniqueKeys: this.uniqueKeys,
destroy() { }
};
},
};
}
InLocalStorageCSFactory.type = STORAGE_LOCALSTORAGE;
return InLocalStorageCSFactory;
}