@splitsoftware/splitio-commons 1.6.2-rc.5 → 1.6.2-rc.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cjs/consent/sdkUserConsent.js +2 -2
- package/cjs/evaluator/index.js +10 -11
- package/cjs/integrations/ga/GaToSplit.js +8 -5
- package/cjs/listeners/browser.js +1 -2
- package/cjs/logger/constants.js +1 -2
- package/cjs/sdkFactory/index.js +7 -25
- package/cjs/sdkManager/index.js +3 -11
- package/cjs/services/splitApi.js +0 -20
- package/cjs/storages/AbstractSplitsCacheAsync.js +7 -9
- package/cjs/storages/AbstractSplitsCacheSync.js +7 -9
- package/cjs/storages/KeyBuilderSS.js +0 -6
- package/cjs/storages/dataLoader.js +1 -1
- package/cjs/storages/inLocalStorage/SplitsCacheInLocal.js +5 -6
- package/cjs/storages/inLocalStorage/index.js +0 -4
- package/cjs/storages/inMemory/ImpressionCountsCacheInMemory.js +1 -12
- package/cjs/storages/inMemory/InMemoryStorage.js +1 -5
- package/cjs/storages/inMemory/InMemoryStorageCS.js +1 -5
- package/cjs/storages/inMemory/SplitsCacheInMemory.js +7 -10
- package/cjs/storages/inRedis/SplitsCacheInRedis.js +15 -9
- package/cjs/storages/inRedis/constants.js +1 -4
- package/cjs/storages/inRedis/index.js +1 -15
- package/cjs/storages/pluggable/SplitsCachePluggable.js +14 -9
- package/cjs/sync/offline/syncTasks/fromObjectSyncTask.js +2 -3
- package/cjs/sync/polling/updaters/splitChangesUpdater.js +1 -1
- package/cjs/sync/submitters/submitterManager.js +0 -3
- package/cjs/sync/submitters/telemetrySubmitter.js +0 -1
- package/cjs/trackers/impressionsTracker.js +41 -22
- package/cjs/trackers/telemetryTracker.js +6 -0
- package/cjs/utils/constants/index.js +2 -4
- package/cjs/utils/settingsValidation/impressionsMode.js +2 -2
- package/cjs/utils/settingsValidation/index.js +0 -3
- package/esm/consent/sdkUserConsent.js +2 -2
- package/esm/evaluator/index.js +10 -11
- package/esm/integrations/ga/GaToSplit.js +8 -5
- package/esm/listeners/browser.js +2 -3
- package/esm/logger/constants.js +0 -1
- package/esm/sdkFactory/index.js +7 -25
- package/esm/sdkManager/index.js +3 -11
- package/esm/services/splitApi.js +0 -20
- package/esm/storages/AbstractSplitsCacheAsync.js +7 -9
- package/esm/storages/AbstractSplitsCacheSync.js +7 -9
- package/esm/storages/KeyBuilderSS.js +0 -6
- package/esm/storages/dataLoader.js +1 -1
- package/esm/storages/inLocalStorage/SplitsCacheInLocal.js +5 -6
- package/esm/storages/inLocalStorage/index.js +1 -5
- package/esm/storages/inMemory/ImpressionCountsCacheInMemory.js +1 -12
- package/esm/storages/inMemory/InMemoryStorage.js +2 -6
- package/esm/storages/inMemory/InMemoryStorageCS.js +2 -6
- package/esm/storages/inMemory/SplitsCacheInMemory.js +7 -10
- package/esm/storages/inRedis/SplitsCacheInRedis.js +15 -9
- package/esm/storages/inRedis/constants.js +0 -3
- package/esm/storages/inRedis/index.js +2 -16
- package/esm/storages/pluggable/SplitsCachePluggable.js +14 -9
- package/esm/sync/offline/syncTasks/fromObjectSyncTask.js +2 -3
- package/esm/sync/polling/updaters/splitChangesUpdater.js +1 -1
- package/esm/sync/submitters/submitterManager.js +0 -3
- package/esm/sync/submitters/telemetrySubmitter.js +1 -2
- package/esm/trackers/impressionsTracker.js +41 -22
- package/esm/trackers/telemetryTracker.js +6 -0
- package/esm/utils/constants/index.js +0 -2
- package/esm/utils/settingsValidation/impressionsMode.js +3 -3
- package/esm/utils/settingsValidation/index.js +0 -3
- package/package.json +1 -1
- package/src/consent/sdkUserConsent.ts +2 -2
- package/src/evaluator/index.ts +8 -9
- package/src/integrations/ga/GaToSplit.ts +9 -5
- package/src/integrations/types.ts +2 -1
- package/src/listeners/browser.ts +2 -3
- package/src/logger/.DS_Store +0 -0
- package/src/logger/constants.ts +0 -1
- package/src/sdkFactory/index.ts +7 -28
- package/src/sdkFactory/types.ts +4 -7
- package/src/sdkManager/index.ts +3 -12
- package/src/services/splitApi.ts +0 -22
- package/src/services/types.ts +0 -6
- package/src/storages/AbstractSplitsCacheAsync.ts +13 -14
- package/src/storages/AbstractSplitsCacheSync.ts +14 -16
- package/src/storages/KeyBuilderSS.ts +0 -8
- package/src/storages/dataLoader.ts +1 -1
- package/src/storages/inLocalStorage/SplitsCacheInLocal.ts +8 -10
- package/src/storages/inLocalStorage/index.ts +1 -4
- package/src/storages/inMemory/ImpressionCountsCacheInMemory.ts +1 -16
- package/src/storages/inMemory/InMemoryStorage.ts +2 -5
- package/src/storages/inMemory/InMemoryStorageCS.ts +2 -6
- package/src/storages/inMemory/SplitsCacheInMemory.ts +10 -14
- package/src/storages/inRedis/SplitsCacheInRedis.ts +21 -17
- package/src/storages/inRedis/constants.ts +0 -3
- package/src/storages/inRedis/index.ts +3 -12
- package/src/storages/pluggable/SplitsCachePluggable.ts +20 -17
- package/src/storages/types.ts +21 -40
- package/src/sync/offline/syncTasks/fromObjectSyncTask.ts +5 -6
- package/src/sync/polling/updaters/splitChangesUpdater.ts +2 -2
- package/src/sync/submitters/submitterManager.ts +0 -2
- package/src/sync/submitters/telemetrySubmitter.ts +3 -4
- package/src/sync/submitters/types.ts +1 -20
- package/src/trackers/impressionsTracker.ts +48 -27
- package/src/trackers/telemetryTracker.ts +7 -2
- package/src/trackers/types.ts +4 -26
- package/src/types.ts +1 -3
- package/src/utils/constants/index.ts +0 -2
- package/src/utils/settingsValidation/impressionsMode.ts +3 -3
- package/src/utils/settingsValidation/index.ts +0 -4
- package/types/integrations/types.d.ts +2 -1
- package/types/logger/constants.d.ts +0 -1
- package/types/sdkFactory/types.d.ts +2 -4
- package/types/services/types.d.ts +0 -4
- package/types/storages/AbstractSplitsCacheAsync.d.ts +6 -5
- package/types/storages/AbstractSplitsCacheSync.d.ts +5 -5
- package/types/storages/KeyBuilderSS.d.ts +0 -2
- package/types/storages/inLocalStorage/SplitsCacheInLocal.d.ts +3 -3
- package/types/storages/inMemory/ImpressionCountsCacheInMemory.d.ts +1 -5
- package/types/storages/inMemory/SplitsCacheInMemory.d.ts +3 -2
- package/types/storages/inRedis/SplitsCacheInRedis.d.ts +6 -5
- package/types/storages/inRedis/constants.d.ts +0 -3
- package/types/storages/pluggable/SplitsCachePluggable.d.ts +6 -5
- package/types/storages/types.d.ts +18 -28
- package/types/sync/polling/updaters/splitChangesUpdater.d.ts +1 -1
- package/types/sync/submitters/types.d.ts +1 -18
- package/types/trackers/impressionsTracker.d.ts +6 -4
- package/types/trackers/types.d.ts +4 -21
- package/types/types.d.ts +1 -3
- package/types/utils/constants/index.d.ts +0 -2
- package/types/utils/settingsValidation/index.d.ts +0 -1
- package/cjs/storages/inMemory/uniqueKeysCacheInMemory.js +0 -73
- package/cjs/storages/inMemory/uniqueKeysCacheInMemoryCS.js +0 -78
- package/cjs/storages/inRedis/ImpressionCountsCacheInRedis.js +0 -46
- package/cjs/storages/inRedis/uniqueKeysCacheInRedis.js +0 -55
- package/cjs/sync/submitters/uniqueKeysSubmitter.js +0 -26
- package/cjs/trackers/strategy/strategyDebug.js +0 -25
- package/cjs/trackers/strategy/strategyNone.js +0 -29
- package/cjs/trackers/strategy/strategyOptimized.js +0 -34
- package/cjs/trackers/uniqueKeysTracker.js +0 -31
- package/esm/storages/inMemory/uniqueKeysCacheInMemory.js +0 -70
- package/esm/storages/inMemory/uniqueKeysCacheInMemoryCS.js +0 -75
- package/esm/storages/inRedis/ImpressionCountsCacheInRedis.js +0 -43
- package/esm/storages/inRedis/uniqueKeysCacheInRedis.js +0 -52
- package/esm/sync/submitters/uniqueKeysSubmitter.js +0 -22
- package/esm/trackers/strategy/strategyDebug.js +0 -21
- package/esm/trackers/strategy/strategyNone.js +0 -25
- package/esm/trackers/strategy/strategyOptimized.js +0 -30
- package/esm/trackers/uniqueKeysTracker.js +0 -27
- package/src/storages/inMemory/uniqueKeysCacheInMemory.ts +0 -82
- package/src/storages/inMemory/uniqueKeysCacheInMemoryCS.ts +0 -88
- package/src/storages/inRedis/ImpressionCountsCacheInRedis.ts +0 -48
- package/src/storages/inRedis/uniqueKeysCacheInRedis.ts +0 -61
- package/src/sync/submitters/uniqueKeysSubmitter.ts +0 -35
- package/src/trackers/strategy/strategyDebug.ts +0 -28
- package/src/trackers/strategy/strategyNone.ts +0 -34
- package/src/trackers/strategy/strategyOptimized.ts +0 -42
- package/src/trackers/uniqueKeysTracker.ts +0 -37
- package/types/sdkClient/types.d.ts +0 -18
- package/types/storages/inMemory/CountsCacheInMemory.d.ts +0 -20
- package/types/storages/inMemory/LatenciesCacheInMemory.d.ts +0 -20
- package/types/storages/inMemory/uniqueKeysCacheInMemory.d.ts +0 -35
- package/types/storages/inMemory/uniqueKeysCacheInMemoryCS.d.ts +0 -37
- package/types/storages/inRedis/CountsCacheInRedis.d.ts +0 -9
- package/types/storages/inRedis/ImpressionCountsCacheInRedis.d.ts +0 -13
- package/types/storages/inRedis/LatenciesCacheInRedis.d.ts +0 -9
- package/types/storages/inRedis/uniqueKeysCacheInRedis.d.ts +0 -14
- package/types/sync/offline/LocalhostFromFile.d.ts +0 -2
- package/types/sync/offline/splitsParser/splitsParserFromFile.d.ts +0 -2
- package/types/sync/submitters/eventsSyncTask.d.ts +0 -8
- package/types/sync/submitters/impressionCountsSubmitterInRedis.d.ts +0 -5
- package/types/sync/submitters/impressionCountsSyncTask.d.ts +0 -13
- package/types/sync/submitters/impressionsSyncTask.d.ts +0 -14
- package/types/sync/submitters/metricsSyncTask.d.ts +0 -12
- package/types/sync/submitters/submitterSyncTask.d.ts +0 -10
- package/types/sync/submitters/uniqueKeysSubmitter.d.ts +0 -5
- package/types/sync/submitters/uniqueKeysSubmitterInRedis.d.ts +0 -5
- package/types/sync/syncTaskComposite.d.ts +0 -5
- package/types/trackers/filter/bloomFilter.d.ts +0 -10
- package/types/trackers/filter/dictionaryFilter.d.ts +0 -8
- package/types/trackers/filter/types.d.ts +0 -5
- package/types/trackers/strategy/strategyDebug.d.ts +0 -9
- package/types/trackers/strategy/strategyNone.d.ts +0 -10
- package/types/trackers/strategy/strategyOptimized.d.ts +0 -11
- package/types/trackers/uniqueKeysTracker.d.ts +0 -13
- package/types/utils/timeTracker/index.d.ts +0 -70
|
@@ -12,9 +12,8 @@ import { SplitsCacheInMemory } from '../inMemory/SplitsCacheInMemory';
|
|
|
12
12
|
import { DEFAULT_CACHE_EXPIRATION_IN_MILLIS } from '../../utils/constants/browser';
|
|
13
13
|
import { InMemoryStorageCSFactory } from '../inMemory/InMemoryStorageCS';
|
|
14
14
|
import { LOG_PREFIX } from './constants';
|
|
15
|
-
import { LOCALHOST_MODE,
|
|
15
|
+
import { LOCALHOST_MODE, STORAGE_LOCALSTORAGE } from '../../utils/constants';
|
|
16
16
|
import { shouldRecordTelemetry, TelemetryCacheInMemory } from '../inMemory/TelemetryCacheInMemory';
|
|
17
|
-
import { UniqueKeysCacheInMemoryCS } from '../inMemory/uniqueKeysCacheInMemoryCS';
|
|
18
17
|
|
|
19
18
|
export interface InLocalStorageOptions {
|
|
20
19
|
prefix?: string
|
|
@@ -46,7 +45,6 @@ export function InLocalStorage(options: InLocalStorageOptions = {}): IStorageSyn
|
|
|
46
45
|
impressionCounts: params.optimize ? new ImpressionCountsCacheInMemory() : undefined,
|
|
47
46
|
events: new EventsCacheInMemory(params.eventsQueueSize),
|
|
48
47
|
telemetry: params.mode !== LOCALHOST_MODE && shouldRecordTelemetry() ? new TelemetryCacheInMemory() : undefined,
|
|
49
|
-
uniqueKeys: params.impressionsMode === NONE ? new UniqueKeysCacheInMemoryCS() : undefined,
|
|
50
48
|
|
|
51
49
|
destroy() {
|
|
52
50
|
this.splits = new SplitsCacheInMemory();
|
|
@@ -54,7 +52,6 @@ export function InLocalStorage(options: InLocalStorageOptions = {}): IStorageSyn
|
|
|
54
52
|
this.impressions.clear();
|
|
55
53
|
this.impressionCounts && this.impressionCounts.clear();
|
|
56
54
|
this.events.clear();
|
|
57
|
-
this.uniqueKeys?.clear();
|
|
58
55
|
},
|
|
59
56
|
|
|
60
57
|
// When using shared instanciation with MEMORY we reuse everything but segments (they are customer per key).
|
|
@@ -1,16 +1,8 @@
|
|
|
1
1
|
import { truncateTimeFrame } from '../../utils/time';
|
|
2
|
-
import { DEFAULT_CACHE_SIZE } from '../inRedis/constants';
|
|
3
2
|
import { IImpressionCountsCacheSync } from '../types';
|
|
4
3
|
|
|
5
4
|
export class ImpressionCountsCacheInMemory implements IImpressionCountsCacheSync {
|
|
6
|
-
|
|
7
|
-
private readonly maxStorage: number;
|
|
8
|
-
protected onFullQueue?: () => void;
|
|
9
|
-
private cacheSize = 0;
|
|
10
|
-
|
|
11
|
-
constructor(impressionCountsCacheSize: number = DEFAULT_CACHE_SIZE) {
|
|
12
|
-
this.maxStorage = impressionCountsCacheSize;
|
|
13
|
-
}
|
|
5
|
+
private cache: Record<string, number> = {};
|
|
14
6
|
|
|
15
7
|
/**
|
|
16
8
|
* Builds key to be stored in the cache with the featureName and the timeFrame truncated.
|
|
@@ -26,13 +18,6 @@ export class ImpressionCountsCacheInMemory implements IImpressionCountsCacheSync
|
|
|
26
18
|
const key = this._makeKey(featureName, timeFrame);
|
|
27
19
|
const currentAmount = this.cache[key];
|
|
28
20
|
this.cache[key] = currentAmount ? currentAmount + amount : amount;
|
|
29
|
-
if (this.onFullQueue) {
|
|
30
|
-
this.cacheSize = this.cacheSize + amount;
|
|
31
|
-
if (this.cacheSize >= this.maxStorage) {
|
|
32
|
-
this.onFullQueue();
|
|
33
|
-
this.cacheSize = 0;
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
21
|
}
|
|
37
22
|
|
|
38
23
|
|
|
@@ -4,9 +4,8 @@ import { ImpressionsCacheInMemory } from './ImpressionsCacheInMemory';
|
|
|
4
4
|
import { EventsCacheInMemory } from './EventsCacheInMemory';
|
|
5
5
|
import { IStorageFactoryParams, IStorageSync } from '../types';
|
|
6
6
|
import { ImpressionCountsCacheInMemory } from './ImpressionCountsCacheInMemory';
|
|
7
|
-
import {
|
|
7
|
+
import { LOCALHOST_MODE, STORAGE_MEMORY } from '../../utils/constants';
|
|
8
8
|
import { TelemetryCacheInMemory } from './TelemetryCacheInMemory';
|
|
9
|
-
import { UniqueKeysCacheInMemory } from './uniqueKeysCacheInMemory';
|
|
10
9
|
|
|
11
10
|
/**
|
|
12
11
|
* InMemory storage factory for standalone server-side SplitFactory
|
|
@@ -19,10 +18,9 @@ export function InMemoryStorageFactory(params: IStorageFactoryParams): IStorageS
|
|
|
19
18
|
splits: new SplitsCacheInMemory(),
|
|
20
19
|
segments: new SegmentsCacheInMemory(),
|
|
21
20
|
impressions: new ImpressionsCacheInMemory(params.impressionsQueueSize),
|
|
22
|
-
impressionCounts: params.
|
|
21
|
+
impressionCounts: params.optimize ? new ImpressionCountsCacheInMemory() : undefined,
|
|
23
22
|
events: new EventsCacheInMemory(params.eventsQueueSize),
|
|
24
23
|
telemetry: params.mode !== LOCALHOST_MODE ? new TelemetryCacheInMemory() : undefined, // Always track telemetry in standalone mode on server-side
|
|
25
|
-
uniqueKeys: params.impressionsMode === NONE ? new UniqueKeysCacheInMemory(params.uniqueKeysCacheSize) : undefined,
|
|
26
24
|
|
|
27
25
|
// When using MEMORY we should clean all the caches to leave them empty
|
|
28
26
|
destroy() {
|
|
@@ -31,7 +29,6 @@ export function InMemoryStorageFactory(params: IStorageFactoryParams): IStorageS
|
|
|
31
29
|
this.impressions.clear();
|
|
32
30
|
this.impressionCounts && this.impressionCounts.clear();
|
|
33
31
|
this.events.clear();
|
|
34
|
-
this.uniqueKeys?.clear();
|
|
35
32
|
}
|
|
36
33
|
};
|
|
37
34
|
}
|
|
@@ -4,9 +4,8 @@ import { ImpressionsCacheInMemory } from './ImpressionsCacheInMemory';
|
|
|
4
4
|
import { EventsCacheInMemory } from './EventsCacheInMemory';
|
|
5
5
|
import { IStorageSync, IStorageFactoryParams } from '../types';
|
|
6
6
|
import { ImpressionCountsCacheInMemory } from './ImpressionCountsCacheInMemory';
|
|
7
|
-
import {
|
|
7
|
+
import { LOCALHOST_MODE, STORAGE_MEMORY } from '../../utils/constants';
|
|
8
8
|
import { shouldRecordTelemetry, TelemetryCacheInMemory } from './TelemetryCacheInMemory';
|
|
9
|
-
import { UniqueKeysCacheInMemoryCS } from './uniqueKeysCacheInMemoryCS';
|
|
10
9
|
|
|
11
10
|
/**
|
|
12
11
|
* InMemory storage factory for standalone client-side SplitFactory
|
|
@@ -19,11 +18,9 @@ export function InMemoryStorageCSFactory(params: IStorageFactoryParams): IStorag
|
|
|
19
18
|
splits: new SplitsCacheInMemory(),
|
|
20
19
|
segments: new MySegmentsCacheInMemory(),
|
|
21
20
|
impressions: new ImpressionsCacheInMemory(params.impressionsQueueSize),
|
|
22
|
-
impressionCounts: params.
|
|
21
|
+
impressionCounts: params.optimize ? new ImpressionCountsCacheInMemory() : undefined,
|
|
23
22
|
events: new EventsCacheInMemory(params.eventsQueueSize),
|
|
24
23
|
telemetry: params.mode !== LOCALHOST_MODE && shouldRecordTelemetry() ? new TelemetryCacheInMemory() : undefined,
|
|
25
|
-
uniqueKeys: params.impressionsMode === NONE ? new UniqueKeysCacheInMemoryCS(params.uniqueKeysCacheSize) : undefined,
|
|
26
|
-
|
|
27
24
|
|
|
28
25
|
// When using MEMORY we should clean all the caches to leave them empty
|
|
29
26
|
destroy() {
|
|
@@ -32,7 +29,6 @@ export function InMemoryStorageCSFactory(params: IStorageFactoryParams): IStorag
|
|
|
32
29
|
this.impressions.clear();
|
|
33
30
|
this.impressionCounts && this.impressionCounts.clear();
|
|
34
31
|
this.events.clear();
|
|
35
|
-
this.uniqueKeys?.clear();
|
|
36
32
|
},
|
|
37
33
|
|
|
38
34
|
// When using shared instanciation with MEMORY we reuse everything but segments (they are unique per key)
|
|
@@ -8,7 +8,7 @@ import { isFiniteNumber } from '../../utils/lang';
|
|
|
8
8
|
*/
|
|
9
9
|
export class SplitsCacheInMemory extends AbstractSplitsCacheSync {
|
|
10
10
|
|
|
11
|
-
private splitsCache: Record<string,
|
|
11
|
+
private splitsCache: Record<string, ISplit> = {};
|
|
12
12
|
private ttCache: Record<string, number> = {};
|
|
13
13
|
private changeNumber: number = -1;
|
|
14
14
|
private splitsWithSegmentsCount: number = 0;
|
|
@@ -20,10 +20,9 @@ export class SplitsCacheInMemory extends AbstractSplitsCacheSync {
|
|
|
20
20
|
this.splitsWithSegmentsCount = 0;
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
addSplit(name: string, split:
|
|
24
|
-
const
|
|
25
|
-
if (
|
|
26
|
-
const previousSplit: ISplit = JSON.parse(splitFromMemory);
|
|
23
|
+
addSplit(name: string, split: ISplit): boolean {
|
|
24
|
+
const previousSplit = this.getSplit(name);
|
|
25
|
+
if (previousSplit) { // We had this Split already
|
|
27
26
|
|
|
28
27
|
if (previousSplit.trafficTypeName) {
|
|
29
28
|
const previousTtName = previousSplit.trafficTypeName;
|
|
@@ -36,20 +35,18 @@ export class SplitsCacheInMemory extends AbstractSplitsCacheSync {
|
|
|
36
35
|
}
|
|
37
36
|
}
|
|
38
37
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
if (parsedSplit) {
|
|
38
|
+
if (split) {
|
|
42
39
|
// Store the Split.
|
|
43
40
|
this.splitsCache[name] = split;
|
|
44
41
|
// Update TT cache
|
|
45
|
-
const ttName =
|
|
42
|
+
const ttName = split.trafficTypeName;
|
|
46
43
|
if (ttName) { // safeguard
|
|
47
44
|
if (!this.ttCache[ttName]) this.ttCache[ttName] = 0;
|
|
48
45
|
this.ttCache[ttName]++;
|
|
49
46
|
}
|
|
50
47
|
|
|
51
48
|
// Add to segments count for the new version of the Split
|
|
52
|
-
if (usesSegments(
|
|
49
|
+
if (usesSegments(split)) this.splitsWithSegmentsCount++;
|
|
53
50
|
|
|
54
51
|
return true;
|
|
55
52
|
} else {
|
|
@@ -63,8 +60,7 @@ export class SplitsCacheInMemory extends AbstractSplitsCacheSync {
|
|
|
63
60
|
// Delete the Split
|
|
64
61
|
delete this.splitsCache[name];
|
|
65
62
|
|
|
66
|
-
const
|
|
67
|
-
const ttName = parsedSplit.trafficTypeName;
|
|
63
|
+
const ttName = split.trafficTypeName;
|
|
68
64
|
|
|
69
65
|
if (ttName) { // safeguard
|
|
70
66
|
this.ttCache[ttName]--; // Update tt cache
|
|
@@ -72,7 +68,7 @@ export class SplitsCacheInMemory extends AbstractSplitsCacheSync {
|
|
|
72
68
|
}
|
|
73
69
|
|
|
74
70
|
// Update the segments count.
|
|
75
|
-
if (usesSegments(
|
|
71
|
+
if (usesSegments(split)) this.splitsWithSegmentsCount--;
|
|
76
72
|
|
|
77
73
|
return true;
|
|
78
74
|
} else {
|
|
@@ -80,7 +76,7 @@ export class SplitsCacheInMemory extends AbstractSplitsCacheSync {
|
|
|
80
76
|
}
|
|
81
77
|
}
|
|
82
78
|
|
|
83
|
-
getSplit(name: string):
|
|
79
|
+
getSplit(name: string): ISplit | null {
|
|
84
80
|
return this.splitsCache[name] || null;
|
|
85
81
|
}
|
|
86
82
|
|
|
@@ -65,22 +65,22 @@ export class SplitsCacheInRedis extends AbstractSplitsCacheAsync {
|
|
|
65
65
|
* The returned promise is resolved when the operation success
|
|
66
66
|
* or rejected if it fails (e.g., redis operation fails)
|
|
67
67
|
*/
|
|
68
|
-
addSplit(name: string, split:
|
|
68
|
+
addSplit(name: string, split: ISplit): Promise<boolean> {
|
|
69
69
|
const splitKey = this.keys.buildSplitKey(name);
|
|
70
70
|
return this.redis.get(splitKey).then(splitFromStorage => {
|
|
71
71
|
|
|
72
72
|
// handling parsing errors
|
|
73
|
-
let parsedPreviousSplit,
|
|
73
|
+
let parsedPreviousSplit, newStringifiedSplit;
|
|
74
74
|
try {
|
|
75
75
|
parsedPreviousSplit = splitFromStorage ? JSON.parse(splitFromStorage) : undefined;
|
|
76
|
-
|
|
76
|
+
newStringifiedSplit = JSON.stringify(split);
|
|
77
77
|
} catch (e) {
|
|
78
78
|
throw new Error('Error parsing split definition: ' + e);
|
|
79
79
|
}
|
|
80
80
|
|
|
81
81
|
return Promise.all([
|
|
82
|
-
this.redis.set(splitKey,
|
|
83
|
-
this._incrementCounts(
|
|
82
|
+
this.redis.set(splitKey, newStringifiedSplit),
|
|
83
|
+
this._incrementCounts(split),
|
|
84
84
|
// If it's an update, we decrement the traffic type of the existing split,
|
|
85
85
|
parsedPreviousSplit && this._decrementCounts(parsedPreviousSplit)
|
|
86
86
|
]);
|
|
@@ -92,7 +92,7 @@ export class SplitsCacheInRedis extends AbstractSplitsCacheAsync {
|
|
|
92
92
|
* The returned promise is resolved when the operation success
|
|
93
93
|
* or rejected if it fails (e.g., redis operation fails)
|
|
94
94
|
*/
|
|
95
|
-
addSplits(entries: [string,
|
|
95
|
+
addSplits(entries: [string, ISplit][]): Promise<boolean[]> {
|
|
96
96
|
return Promise.all(entries.map(keyValuePair => this.addSplit(keyValuePair[0], keyValuePair[1])));
|
|
97
97
|
}
|
|
98
98
|
|
|
@@ -104,8 +104,7 @@ export class SplitsCacheInRedis extends AbstractSplitsCacheAsync {
|
|
|
104
104
|
removeSplit(name: string): Promise<number> {
|
|
105
105
|
return this.getSplit(name).then((split) => {
|
|
106
106
|
if (split) {
|
|
107
|
-
|
|
108
|
-
this._decrementCounts(parsedSplit);
|
|
107
|
+
this._decrementCounts(split);
|
|
109
108
|
}
|
|
110
109
|
return this.redis.del(this.keys.buildSplitKey(name));
|
|
111
110
|
});
|
|
@@ -124,14 +123,15 @@ export class SplitsCacheInRedis extends AbstractSplitsCacheAsync {
|
|
|
124
123
|
* Get split definition or null if it's not defined.
|
|
125
124
|
* Returned promise is rejected if redis operation fails.
|
|
126
125
|
*/
|
|
127
|
-
getSplit(name: string): Promise<
|
|
126
|
+
getSplit(name: string): Promise<ISplit | null> {
|
|
128
127
|
if (this.redisError) {
|
|
129
128
|
this.log.error(LOG_PREFIX + this.redisError);
|
|
130
129
|
|
|
131
130
|
return Promise.reject(this.redisError);
|
|
132
131
|
}
|
|
133
132
|
|
|
134
|
-
return this.redis.get(this.keys.buildSplitKey(name))
|
|
133
|
+
return this.redis.get(this.keys.buildSplitKey(name))
|
|
134
|
+
.then(maybeSplit => maybeSplit && JSON.parse(maybeSplit));
|
|
135
135
|
}
|
|
136
136
|
|
|
137
137
|
/**
|
|
@@ -169,10 +169,13 @@ export class SplitsCacheInRedis extends AbstractSplitsCacheAsync {
|
|
|
169
169
|
* @TODO we need to benchmark which is the maximun number of commands we could
|
|
170
170
|
* pipeline without kill redis performance.
|
|
171
171
|
*/
|
|
172
|
-
getAll(): Promise<
|
|
173
|
-
return this.redis.keys(this.keys.searchPatternForSplitKeys())
|
|
174
|
-
(listOfKeys) => this.redis.pipeline(listOfKeys.map(k => ['get', k])).exec()
|
|
175
|
-
|
|
172
|
+
getAll(): Promise<ISplit[]> {
|
|
173
|
+
return this.redis.keys(this.keys.searchPatternForSplitKeys())
|
|
174
|
+
.then((listOfKeys) => this.redis.pipeline(listOfKeys.map(k => ['get', k])).exec())
|
|
175
|
+
.then(processPipelineAnswer)
|
|
176
|
+
.then((splitDefinitions) => splitDefinitions.map((splitDefinition) => {
|
|
177
|
+
return JSON.parse(splitDefinition as string);
|
|
178
|
+
}));
|
|
176
179
|
}
|
|
177
180
|
|
|
178
181
|
/**
|
|
@@ -226,19 +229,20 @@ export class SplitsCacheInRedis extends AbstractSplitsCacheAsync {
|
|
|
226
229
|
* Fetches multiple splits definitions.
|
|
227
230
|
* Returned promise is rejected if redis operation fails.
|
|
228
231
|
*/
|
|
229
|
-
getSplits(names: string[]): Promise<Record<string,
|
|
232
|
+
getSplits(names: string[]): Promise<Record<string, ISplit | null>> {
|
|
230
233
|
if (this.redisError) {
|
|
231
234
|
this.log.error(LOG_PREFIX + this.redisError);
|
|
232
235
|
|
|
233
236
|
return Promise.reject(this.redisError);
|
|
234
237
|
}
|
|
235
238
|
|
|
236
|
-
const splits: Record<string,
|
|
239
|
+
const splits: Record<string, ISplit | null> = {};
|
|
237
240
|
const keys = names.map(name => this.keys.buildSplitKey(name));
|
|
238
241
|
return this.redis.mget(...keys)
|
|
239
242
|
.then(splitDefinitions => {
|
|
240
243
|
names.forEach((name, idx) => {
|
|
241
|
-
|
|
244
|
+
const split = splitDefinitions[idx];
|
|
245
|
+
splits[name] = split && JSON.parse(split);
|
|
242
246
|
});
|
|
243
247
|
return Promise.resolve(splits);
|
|
244
248
|
})
|
|
@@ -6,10 +6,8 @@ import { SplitsCacheInRedis } from './SplitsCacheInRedis';
|
|
|
6
6
|
import { SegmentsCacheInRedis } from './SegmentsCacheInRedis';
|
|
7
7
|
import { ImpressionsCacheInRedis } from './ImpressionsCacheInRedis';
|
|
8
8
|
import { EventsCacheInRedis } from './EventsCacheInRedis';
|
|
9
|
-
import {
|
|
9
|
+
import { STORAGE_REDIS } from '../../utils/constants';
|
|
10
10
|
import { TelemetryCacheInRedis } from './TelemetryCacheInRedis';
|
|
11
|
-
import { UniqueKeysCacheInRedis } from './uniqueKeysCacheInRedis';
|
|
12
|
-
import { ImpressionCountsCacheInRedis } from './ImpressionCountsCacheInRedis';
|
|
13
11
|
|
|
14
12
|
export interface InRedisStorageOptions {
|
|
15
13
|
prefix?: string
|
|
@@ -24,18 +22,15 @@ export function InRedisStorage(options: InRedisStorageOptions = {}): IStorageAsy
|
|
|
24
22
|
|
|
25
23
|
const prefix = validatePrefix(options.prefix);
|
|
26
24
|
|
|
27
|
-
function InRedisStorageFactory({ log, metadata, onReadyCb
|
|
25
|
+
function InRedisStorageFactory({ log, metadata, onReadyCb }: IStorageFactoryParams): IStorageAsync {
|
|
26
|
+
|
|
28
27
|
const keys = new KeyBuilderSS(prefix, metadata);
|
|
29
28
|
const redisClient = new RedisAdapter(log, options.options || {});
|
|
30
29
|
const telemetry = new TelemetryCacheInRedis(log, keys, redisClient);
|
|
31
|
-
const impressionCountsCache = impressionsMode !== DEBUG ? new ImpressionCountsCacheInRedis(log, keys.buildImpressionsCountKey(), redisClient) : undefined;
|
|
32
|
-
const uniqueKeysCache = impressionsMode === NONE ? new UniqueKeysCacheInRedis(log, keys.buildUniqueKeysKey(), redisClient) : undefined;
|
|
33
30
|
|
|
34
31
|
// subscription to Redis connect event in order to emit SDK_READY event on consumer mode
|
|
35
32
|
redisClient.on('connect', () => {
|
|
36
33
|
onReadyCb();
|
|
37
|
-
if (impressionCountsCache) impressionCountsCache.start();
|
|
38
|
-
if (uniqueKeysCache) uniqueKeysCache.start();
|
|
39
34
|
|
|
40
35
|
// Synchronize config
|
|
41
36
|
telemetry.recordConfig();
|
|
@@ -45,17 +40,13 @@ export function InRedisStorage(options: InRedisStorageOptions = {}): IStorageAsy
|
|
|
45
40
|
splits: new SplitsCacheInRedis(log, keys, redisClient),
|
|
46
41
|
segments: new SegmentsCacheInRedis(log, keys, redisClient),
|
|
47
42
|
impressions: new ImpressionsCacheInRedis(log, keys.buildImpressionsKey(), redisClient, metadata),
|
|
48
|
-
impressionCounts: impressionCountsCache,
|
|
49
43
|
events: new EventsCacheInRedis(log, keys.buildEventsKey(), redisClient, metadata),
|
|
50
44
|
telemetry,
|
|
51
|
-
uniqueKeys: uniqueKeysCache,
|
|
52
45
|
|
|
53
46
|
// When using REDIS we should:
|
|
54
47
|
// 1- Disconnect from the storage
|
|
55
48
|
destroy() {
|
|
56
49
|
redisClient.disconnect();
|
|
57
|
-
if (impressionCountsCache) impressionCountsCache.stop();
|
|
58
|
-
if (uniqueKeysCache) uniqueKeysCache.stop();
|
|
59
50
|
// @TODO check that caches works as expected when redisClient is disconnected
|
|
60
51
|
}
|
|
61
52
|
};
|
|
@@ -49,22 +49,22 @@ export class SplitsCachePluggable extends AbstractSplitsCacheAsync {
|
|
|
49
49
|
* The returned promise is resolved when the operation success
|
|
50
50
|
* or rejected if it fails (e.g., wrapper operation fails)
|
|
51
51
|
*/
|
|
52
|
-
addSplit(name: string, split:
|
|
52
|
+
addSplit(name: string, split: ISplit): Promise<boolean> {
|
|
53
53
|
const splitKey = this.keys.buildSplitKey(name);
|
|
54
54
|
return this.wrapper.get(splitKey).then(splitFromStorage => {
|
|
55
55
|
|
|
56
56
|
// handling parsing error
|
|
57
|
-
let parsedPreviousSplit,
|
|
57
|
+
let parsedPreviousSplit, stringifiedNewSplit;
|
|
58
58
|
try {
|
|
59
59
|
parsedPreviousSplit = splitFromStorage ? JSON.parse(splitFromStorage) : undefined;
|
|
60
|
-
|
|
60
|
+
stringifiedNewSplit = JSON.stringify(split);
|
|
61
61
|
} catch (e) {
|
|
62
62
|
throw new Error('Error parsing split definition: ' + e);
|
|
63
63
|
}
|
|
64
64
|
|
|
65
65
|
return Promise.all([
|
|
66
|
-
this.wrapper.set(splitKey,
|
|
67
|
-
this._incrementCounts(
|
|
66
|
+
this.wrapper.set(splitKey, stringifiedNewSplit),
|
|
67
|
+
this._incrementCounts(split),
|
|
68
68
|
// If it's an update, we decrement the traffic type and segment count of the existing split,
|
|
69
69
|
parsedPreviousSplit && this._decrementCounts(parsedPreviousSplit)
|
|
70
70
|
]);
|
|
@@ -76,7 +76,7 @@ export class SplitsCachePluggable extends AbstractSplitsCacheAsync {
|
|
|
76
76
|
* The returned promise is resolved when the operation success
|
|
77
77
|
* or rejected if it fails (e.g., wrapper operation fails)
|
|
78
78
|
*/
|
|
79
|
-
addSplits(entries: [string,
|
|
79
|
+
addSplits(entries: [string, ISplit][]): Promise<boolean[]> {
|
|
80
80
|
return Promise.all(entries.map(keyValuePair => this.addSplit(keyValuePair[0], keyValuePair[1])));
|
|
81
81
|
}
|
|
82
82
|
|
|
@@ -88,8 +88,7 @@ export class SplitsCachePluggable extends AbstractSplitsCacheAsync {
|
|
|
88
88
|
removeSplit(name: string) {
|
|
89
89
|
return this.getSplit(name).then((split) => {
|
|
90
90
|
if (split) {
|
|
91
|
-
|
|
92
|
-
this._decrementCounts(parsedSplit);
|
|
91
|
+
this._decrementCounts(split);
|
|
93
92
|
}
|
|
94
93
|
return this.wrapper.del(this.keys.buildSplitKey(name));
|
|
95
94
|
});
|
|
@@ -109,8 +108,9 @@ export class SplitsCachePluggable extends AbstractSplitsCacheAsync {
|
|
|
109
108
|
* The returned promise is resolved with the split definition or null if it's not defined,
|
|
110
109
|
* or rejected if wrapper operation fails.
|
|
111
110
|
*/
|
|
112
|
-
getSplit(name: string): Promise<
|
|
113
|
-
return this.wrapper.get(this.keys.buildSplitKey(name))
|
|
111
|
+
getSplit(name: string): Promise<ISplit | null> {
|
|
112
|
+
return this.wrapper.get(this.keys.buildSplitKey(name))
|
|
113
|
+
.then(maybeSplit => maybeSplit && JSON.parse(maybeSplit));
|
|
114
114
|
}
|
|
115
115
|
|
|
116
116
|
/**
|
|
@@ -118,13 +118,14 @@ export class SplitsCachePluggable extends AbstractSplitsCacheAsync {
|
|
|
118
118
|
* The returned promise is resolved with a map of split names to their split definition or null if it's not defined,
|
|
119
119
|
* or rejected if wrapper operation fails.
|
|
120
120
|
*/
|
|
121
|
-
getSplits(names: string[]): Promise<Record<string,
|
|
121
|
+
getSplits(names: string[]): Promise<Record<string, ISplit | null>> {
|
|
122
122
|
const keys = names.map(name => this.keys.buildSplitKey(name));
|
|
123
123
|
|
|
124
124
|
return this.wrapper.getMany(keys).then(splitDefinitions => {
|
|
125
|
-
const splits: Record<string,
|
|
125
|
+
const splits: Record<string, ISplit | null> = {};
|
|
126
126
|
names.forEach((name, idx) => {
|
|
127
|
-
|
|
127
|
+
const split = splitDefinitions[idx];
|
|
128
|
+
splits[name] = split && JSON.parse(split);
|
|
128
129
|
});
|
|
129
130
|
return Promise.resolve(splits);
|
|
130
131
|
});
|
|
@@ -135,10 +136,12 @@ export class SplitsCachePluggable extends AbstractSplitsCacheAsync {
|
|
|
135
136
|
* The returned promise is resolved with the list of split definitions,
|
|
136
137
|
* or rejected if wrapper operation fails.
|
|
137
138
|
*/
|
|
138
|
-
getAll(): Promise<
|
|
139
|
-
return this.wrapper.getKeysByPrefix(this.keys.buildSplitKeyPrefix())
|
|
140
|
-
(listOfKeys) =>
|
|
141
|
-
|
|
139
|
+
getAll(): Promise<ISplit[]> {
|
|
140
|
+
return this.wrapper.getKeysByPrefix(this.keys.buildSplitKeyPrefix())
|
|
141
|
+
.then((listOfKeys) => this.wrapper.getMany(listOfKeys))
|
|
142
|
+
.then((splitDefinitions) => splitDefinitions.map((splitDefinition) => {
|
|
143
|
+
return JSON.parse(splitDefinition as string);
|
|
144
|
+
}));
|
|
142
145
|
}
|
|
143
146
|
|
|
144
147
|
/**
|
package/src/storages/types.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { MaybeThenable, IMetadata, ISplitFiltersValidation } from '../dtos/types';
|
|
1
|
+
import { MaybeThenable, IMetadata, ISplitFiltersValidation, ISplit } from '../dtos/types';
|
|
2
2
|
import { ILogger } from '../logger/types';
|
|
3
|
-
import { EventDataType, HttpErrors, HttpLatencies, ImpressionDataType, LastSync, Method, MethodExceptions, MethodLatencies, OperationType, StoredEventWithMetadata, StoredImpressionWithMetadata, StreamingEvent
|
|
3
|
+
import { EventDataType, HttpErrors, HttpLatencies, ImpressionDataType, LastSync, Method, MethodExceptions, MethodLatencies, OperationType, StoredEventWithMetadata, StoredImpressionWithMetadata, StreamingEvent } from '../sync/submitters/types';
|
|
4
4
|
import { SplitIO, ImpressionDTO, SDKMode } from '../types';
|
|
5
5
|
|
|
6
6
|
/**
|
|
@@ -191,14 +191,14 @@ export interface IPluggableStorageWrapper {
|
|
|
191
191
|
/** Splits cache */
|
|
192
192
|
|
|
193
193
|
export interface ISplitsCacheBase {
|
|
194
|
-
addSplits(entries: [string,
|
|
194
|
+
addSplits(entries: [string, ISplit][]): MaybeThenable<boolean[] | void>,
|
|
195
195
|
removeSplits(names: string[]): MaybeThenable<boolean[] | void>,
|
|
196
|
-
getSplit(name: string): MaybeThenable<
|
|
197
|
-
getSplits(names: string[]): MaybeThenable<Record<string,
|
|
196
|
+
getSplit(name: string): MaybeThenable<ISplit | null>,
|
|
197
|
+
getSplits(names: string[]): MaybeThenable<Record<string, ISplit | null>>, // `fetchMany` in spec
|
|
198
198
|
setChangeNumber(changeNumber: number): MaybeThenable<boolean | void>,
|
|
199
199
|
// should never reject or throw an exception. Instead return -1 by default, assuming no splits are present in the storage.
|
|
200
200
|
getChangeNumber(): MaybeThenable<number>,
|
|
201
|
-
getAll(): MaybeThenable<
|
|
201
|
+
getAll(): MaybeThenable<ISplit[]>,
|
|
202
202
|
getSplitNames(): MaybeThenable<string[]>,
|
|
203
203
|
// should never reject or throw an exception. Instead return true by default, asssuming the TT might exist.
|
|
204
204
|
trafficTypeExists(trafficType: string): MaybeThenable<boolean>,
|
|
@@ -211,13 +211,13 @@ export interface ISplitsCacheBase {
|
|
|
211
211
|
}
|
|
212
212
|
|
|
213
213
|
export interface ISplitsCacheSync extends ISplitsCacheBase {
|
|
214
|
-
addSplits(entries: [string,
|
|
214
|
+
addSplits(entries: [string, ISplit][]): boolean[],
|
|
215
215
|
removeSplits(names: string[]): boolean[],
|
|
216
|
-
getSplit(name: string):
|
|
217
|
-
getSplits(names: string[]): Record<string,
|
|
216
|
+
getSplit(name: string): ISplit | null,
|
|
217
|
+
getSplits(names: string[]): Record<string, ISplit | null>,
|
|
218
218
|
setChangeNumber(changeNumber: number): boolean,
|
|
219
219
|
getChangeNumber(): number,
|
|
220
|
-
getAll():
|
|
220
|
+
getAll(): ISplit[],
|
|
221
221
|
getSplitNames(): string[],
|
|
222
222
|
trafficTypeExists(trafficType: string): boolean,
|
|
223
223
|
usesSegments(): boolean,
|
|
@@ -227,13 +227,13 @@ export interface ISplitsCacheSync extends ISplitsCacheBase {
|
|
|
227
227
|
}
|
|
228
228
|
|
|
229
229
|
export interface ISplitsCacheAsync extends ISplitsCacheBase {
|
|
230
|
-
addSplits(entries: [string,
|
|
230
|
+
addSplits(entries: [string, ISplit][]): Promise<boolean[] | void>,
|
|
231
231
|
removeSplits(names: string[]): Promise<boolean[] | void>,
|
|
232
|
-
getSplit(name: string): Promise<
|
|
233
|
-
getSplits(names: string[]): Promise<Record<string,
|
|
232
|
+
getSplit(name: string): Promise<ISplit | null>,
|
|
233
|
+
getSplits(names: string[]): Promise<Record<string, ISplit | null>>,
|
|
234
234
|
setChangeNumber(changeNumber: number): Promise<boolean | void>,
|
|
235
235
|
getChangeNumber(): Promise<number>,
|
|
236
|
-
getAll(): Promise<
|
|
236
|
+
getAll(): Promise<ISplit[]>,
|
|
237
237
|
getSplitNames(): Promise<string[]>,
|
|
238
238
|
trafficTypeExists(trafficType: string): Promise<boolean>,
|
|
239
239
|
usesSegments(): Promise<boolean>,
|
|
@@ -347,7 +347,7 @@ export interface IEventsCacheAsync extends IEventsCacheBase, IRecorderCacheProdu
|
|
|
347
347
|
* Only in memory. Named `ImpressionsCounter` in spec.
|
|
348
348
|
*/
|
|
349
349
|
export interface IImpressionCountsCacheSync extends IRecorderCacheProducerSync<Record<string, number>> {
|
|
350
|
-
// Used by impressions tracker
|
|
350
|
+
// Used by impressions tracker
|
|
351
351
|
track(featureName: string, timeFrame: number, amount: number): void
|
|
352
352
|
|
|
353
353
|
// Used by impressions count submitter in standalone and producer mode
|
|
@@ -355,17 +355,6 @@ export interface IImpressionCountsCacheSync extends IRecorderCacheProducerSync<R
|
|
|
355
355
|
pop(toMerge?: Record<string, number> ): Record<string, number> // pop cache data
|
|
356
356
|
}
|
|
357
357
|
|
|
358
|
-
export interface IUniqueKeysCacheBase {
|
|
359
|
-
// Used by unique Keys tracker
|
|
360
|
-
track(key: string, value: string): void
|
|
361
|
-
|
|
362
|
-
// Used by unique keys submitter in standalone and producer mode
|
|
363
|
-
isEmpty(): boolean // check if cache is empty. Return true if the cache was just created or cleared.
|
|
364
|
-
pop(): UniqueKeysPayloadSs | UniqueKeysPayloadCs // pop cache data
|
|
365
|
-
/* Registers callback for full queue */
|
|
366
|
-
setOnFullQueueCb(cb: () => void): void,
|
|
367
|
-
clear(): void
|
|
368
|
-
}
|
|
369
358
|
|
|
370
359
|
/**
|
|
371
360
|
* Telemetry storage interface for standalone and partial consumer modes.
|
|
@@ -455,18 +444,15 @@ export interface IStorageBase<
|
|
|
455
444
|
TSplitsCache extends ISplitsCacheBase,
|
|
456
445
|
TSegmentsCache extends ISegmentsCacheBase,
|
|
457
446
|
TImpressionsCache extends IImpressionsCacheBase,
|
|
458
|
-
TImpressionsCountCache extends IImpressionCountsCacheSync,
|
|
459
447
|
TEventsCache extends IEventsCacheBase,
|
|
460
|
-
TTelemetryCache extends ITelemetryCacheSync | ITelemetryCacheAsync
|
|
461
|
-
TUniqueKeysCache extends IUniqueKeysCacheBase
|
|
448
|
+
TTelemetryCache extends ITelemetryCacheSync | ITelemetryCacheAsync
|
|
462
449
|
> {
|
|
463
450
|
splits: TSplitsCache,
|
|
464
451
|
segments: TSegmentsCache,
|
|
465
452
|
impressions: TImpressionsCache,
|
|
466
|
-
impressionCounts?:
|
|
453
|
+
impressionCounts?: IImpressionCountsCacheSync,
|
|
467
454
|
events: TEventsCache,
|
|
468
|
-
telemetry?: TTelemetryCache
|
|
469
|
-
uniqueKeys?: TUniqueKeysCache,
|
|
455
|
+
telemetry?: TTelemetryCache
|
|
470
456
|
destroy(): void | Promise<void>,
|
|
471
457
|
shared?: (matchingKey: string, onReadyCb: (error?: any) => void) => this
|
|
472
458
|
}
|
|
@@ -475,20 +461,16 @@ export interface IStorageSync extends IStorageBase<
|
|
|
475
461
|
ISplitsCacheSync,
|
|
476
462
|
ISegmentsCacheSync,
|
|
477
463
|
IImpressionsCacheSync,
|
|
478
|
-
IImpressionCountsCacheSync,
|
|
479
464
|
IEventsCacheSync,
|
|
480
|
-
ITelemetryCacheSync
|
|
481
|
-
IUniqueKeysCacheBase
|
|
465
|
+
ITelemetryCacheSync
|
|
482
466
|
> { }
|
|
483
467
|
|
|
484
468
|
export interface IStorageAsync extends IStorageBase<
|
|
485
469
|
ISplitsCacheAsync,
|
|
486
470
|
ISegmentsCacheAsync,
|
|
487
471
|
IImpressionsCacheAsync | IImpressionsCacheSync,
|
|
488
|
-
IImpressionCountsCacheSync,
|
|
489
472
|
IEventsCacheAsync | IEventsCacheSync,
|
|
490
|
-
ITelemetryCacheAsync
|
|
491
|
-
IUniqueKeysCacheBase
|
|
473
|
+
ITelemetryCacheAsync
|
|
492
474
|
> { }
|
|
493
475
|
|
|
494
476
|
/** StorageFactory */
|
|
@@ -498,11 +480,10 @@ export type DataLoader = (storage: IStorageSync, matchingKey: string) => void
|
|
|
498
480
|
export interface IStorageFactoryParams {
|
|
499
481
|
log: ILogger,
|
|
500
482
|
impressionsQueueSize?: number,
|
|
501
|
-
uniqueKeysCacheSize?: number;
|
|
502
483
|
eventsQueueSize?: number,
|
|
503
484
|
optimize?: boolean /* whether create the `impressionCounts` cache (OPTIMIZED impression mode) or not (DEBUG impression mode) */,
|
|
504
485
|
mode: SDKMode,
|
|
505
|
-
|
|
486
|
+
|
|
506
487
|
// ATM, only used by InLocalStorage
|
|
507
488
|
matchingKey?: string, /* undefined on server-side SDKs */
|
|
508
489
|
splitFiltersValidation?: ISplitFiltersValidation,
|
|
@@ -2,7 +2,7 @@ import { forOwn } from '../../../utils/lang';
|
|
|
2
2
|
import { IReadinessManager } from '../../../readiness/types';
|
|
3
3
|
import { ISplitsCacheSync } from '../../../storages/types';
|
|
4
4
|
import { ISplitsParser } from '../splitsParser/types';
|
|
5
|
-
import { ISplitPartial } from '../../../dtos/types';
|
|
5
|
+
import { ISplit, ISplitPartial } from '../../../dtos/types';
|
|
6
6
|
import { syncTaskFactory } from '../../syncTask';
|
|
7
7
|
import { ISyncTask } from '../../types';
|
|
8
8
|
import { ISettings } from '../../../types';
|
|
@@ -24,7 +24,7 @@ export function fromObjectUpdaterFactory(
|
|
|
24
24
|
let startingUp = true;
|
|
25
25
|
|
|
26
26
|
return function objectUpdater() {
|
|
27
|
-
const splits: [string,
|
|
27
|
+
const splits: [string, ISplit][] = [];
|
|
28
28
|
let loadError = null;
|
|
29
29
|
let splitsMock: false | Record<string, ISplitPartial> = {};
|
|
30
30
|
try {
|
|
@@ -38,9 +38,8 @@ export function fromObjectUpdaterFactory(
|
|
|
38
38
|
log.debug(SYNC_OFFLINE_DATA, [JSON.stringify(splitsMock)]);
|
|
39
39
|
|
|
40
40
|
forOwn(splitsMock, function (val, name) {
|
|
41
|
-
splits.push([
|
|
42
|
-
name,
|
|
43
|
-
JSON.stringify({
|
|
41
|
+
splits.push([ // @ts-ignore Split changeNumber and seed is undefined in localhost mode
|
|
42
|
+
name, {
|
|
44
43
|
name,
|
|
45
44
|
status: 'ACTIVE',
|
|
46
45
|
killed: false,
|
|
@@ -49,7 +48,7 @@ export function fromObjectUpdaterFactory(
|
|
|
49
48
|
conditions: val.conditions || [],
|
|
50
49
|
configurations: val.configurations,
|
|
51
50
|
trafficTypeName: val.trafficTypeName
|
|
52
|
-
}
|
|
51
|
+
}
|
|
53
52
|
]);
|
|
54
53
|
});
|
|
55
54
|
|
|
@@ -40,7 +40,7 @@ export function parseSegments({ conditions }: ISplit): ISet<string> {
|
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
interface ISplitMutations {
|
|
43
|
-
added: [string,
|
|
43
|
+
added: [string, ISplit][],
|
|
44
44
|
removed: string[],
|
|
45
45
|
segments: string[]
|
|
46
46
|
}
|
|
@@ -54,7 +54,7 @@ export function computeSplitsMutation(entries: ISplit[]): ISplitMutations {
|
|
|
54
54
|
const segments = new _Set<string>();
|
|
55
55
|
const computed = entries.reduce((accum, split) => {
|
|
56
56
|
if (split.status === 'ACTIVE') {
|
|
57
|
-
accum.added.push([split.name,
|
|
57
|
+
accum.added.push([split.name, split]);
|
|
58
58
|
|
|
59
59
|
parseSegments(split).forEach((segmentName: string) => {
|
|
60
60
|
segments.add(segmentName);
|