@splitsoftware/splitio-commons 1.9.1-rc.0 → 1.9.2-rc.0
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/CHANGES.txt +5 -2
- package/cjs/evaluator/index.js +18 -1
- package/cjs/integrations/ga/GaToSplit.js +1 -1
- package/cjs/listeners/browser.js +3 -13
- package/cjs/logger/constants.js +7 -2
- package/cjs/logger/messages/error.js +2 -0
- package/cjs/logger/messages/warn.js +3 -1
- package/cjs/myLogger.js +34 -0
- package/cjs/sdkClient/client.js +33 -0
- package/cjs/sdkClient/clientAttributesDecoration.js +20 -0
- package/cjs/sdkClient/clientCS.js +5 -4
- package/cjs/sdkClient/clientInputValidation.js +52 -3
- package/cjs/sdkManager/index.js +2 -1
- package/cjs/services/splitApi.js +7 -1
- package/cjs/storages/KeyBuilder.js +3 -0
- package/cjs/storages/KeyBuilderSS.js +4 -0
- package/cjs/storages/inLocalStorage/SplitsCacheInLocal.js +63 -27
- package/cjs/storages/inLocalStorage/index.js +2 -2
- package/cjs/storages/inMemory/InMemoryStorage.js +2 -2
- package/cjs/storages/inMemory/InMemoryStorageCS.js +3 -3
- package/cjs/storages/inMemory/SplitsCacheInMemory.js +47 -2
- package/cjs/storages/inRedis/SplitsCacheInRedis.js +11 -0
- package/cjs/storages/pluggable/SplitsCachePluggable.js +11 -0
- package/cjs/sync/polling/syncTasks/splitsSyncTask.js +1 -1
- package/cjs/sync/polling/updaters/splitChangesUpdater.js +24 -4
- package/cjs/sync/streaming/parseUtils.js +1 -0
- package/cjs/sync/submitters/telemetrySubmitter.js +15 -1
- package/cjs/utils/constants/index.js +6 -2
- package/cjs/utils/lang/sets.js +9 -1
- package/cjs/utils/settingsValidation/splitFilters.js +77 -2
- package/esm/evaluator/index.js +16 -0
- package/esm/integrations/ga/GaToSplit.js +1 -1
- package/esm/listeners/browser.js +3 -13
- package/esm/logger/constants.js +5 -0
- package/esm/logger/messages/error.js +2 -0
- package/esm/logger/messages/warn.js +3 -1
- package/esm/myLogger.js +31 -0
- package/esm/sdkClient/client.js +35 -2
- package/esm/sdkClient/clientAttributesDecoration.js +20 -0
- package/esm/sdkClient/clientCS.js +5 -4
- package/esm/sdkClient/clientInputValidation.js +52 -3
- package/esm/sdkManager/index.js +2 -1
- package/esm/services/splitApi.js +7 -1
- package/esm/storages/KeyBuilder.js +3 -0
- package/esm/storages/KeyBuilderSS.js +4 -0
- package/esm/storages/inLocalStorage/SplitsCacheInLocal.js +63 -27
- package/esm/storages/inLocalStorage/index.js +2 -2
- package/esm/storages/inMemory/InMemoryStorage.js +2 -2
- package/esm/storages/inMemory/InMemoryStorageCS.js +3 -3
- package/esm/storages/inMemory/SplitsCacheInMemory.js +47 -2
- package/esm/storages/inRedis/SplitsCacheInRedis.js +11 -0
- package/esm/storages/pluggable/SplitsCachePluggable.js +11 -0
- package/esm/sync/polling/syncTasks/splitsSyncTask.js +1 -1
- package/esm/sync/polling/updaters/splitChangesUpdater.js +24 -4
- package/esm/sync/streaming/parseUtils.js +1 -0
- package/esm/sync/submitters/telemetrySubmitter.js +15 -1
- package/esm/utils/constants/index.js +4 -0
- package/esm/utils/lang/sets.js +7 -0
- package/esm/utils/settingsValidation/splitFilters.js +76 -2
- package/package.json +6 -6
- package/src/dtos/types.ts +3 -2
- package/src/evaluator/index.ts +24 -0
- package/src/integrations/ga/GaToSplit.ts +1 -1
- package/src/listeners/browser.ts +3 -13
- package/src/logger/constants.ts +5 -0
- package/src/logger/messages/error.ts +2 -0
- package/src/logger/messages/warn.ts +3 -1
- package/src/myLogger.ts +36 -0
- package/src/sdkClient/client.ts +42 -2
- package/src/sdkClient/clientAttributesDecoration.ts +24 -0
- package/src/sdkClient/clientCS.ts +5 -4
- package/src/sdkClient/clientInputValidation.ts +56 -4
- package/src/sdkManager/index.ts +2 -1
- package/src/services/splitApi.ts +6 -1
- package/src/storages/AbstractSplitsCacheAsync.ts +2 -0
- package/src/storages/AbstractSplitsCacheSync.ts +3 -0
- package/src/storages/KeyBuilder.ts +4 -0
- package/src/storages/KeyBuilderSS.ts +4 -0
- package/src/storages/inLocalStorage/SplitsCacheInLocal.ts +74 -28
- package/src/storages/inLocalStorage/index.ts +2 -2
- package/src/storages/inMemory/InMemoryStorage.ts +2 -2
- package/src/storages/inMemory/InMemoryStorageCS.ts +3 -3
- package/src/storages/inMemory/SplitsCacheInMemory.ts +50 -1
- package/src/storages/inMemory/TelemetryCacheInMemory.ts +1 -1
- package/src/storages/inRedis/RedisAdapter.ts +1 -1
- package/src/storages/inRedis/SplitsCacheInRedis.ts +12 -0
- package/src/storages/pluggable/SplitsCachePluggable.ts +12 -0
- package/src/storages/types.ts +7 -3
- package/src/sync/polling/syncTasks/splitsSyncTask.ts +1 -0
- package/src/sync/polling/updaters/splitChangesUpdater.ts +27 -4
- package/src/sync/streaming/parseUtils.ts +1 -0
- package/src/sync/submitters/telemetrySubmitter.ts +19 -2
- package/src/sync/submitters/types.ts +7 -1
- package/src/types.ts +118 -1
- package/src/utils/constants/index.ts +4 -0
- package/src/utils/lang/sets.ts +8 -0
- package/src/utils/redis/RedisMock.ts +1 -1
- package/src/utils/settingsValidation/splitFilters.ts +82 -2
- package/types/dtos/types.d.ts +1 -0
- package/types/evaluator/index.d.ts +1 -0
- package/types/listeners/browser.d.ts +0 -1
- package/types/logger/constants.d.ts +5 -0
- package/types/myLogger.d.ts +5 -0
- package/types/sdkClient/clientAttributesDecoration.d.ts +4 -0
- package/types/sdkClient/types.d.ts +18 -0
- package/types/storages/AbstractSplitsCacheAsync.d.ts +2 -0
- package/types/storages/AbstractSplitsCacheSync.d.ts +2 -0
- package/types/storages/KeyBuilder.d.ts +1 -0
- package/types/storages/inLocalStorage/SplitsCacheInLocal.d.ts +6 -1
- package/types/storages/inMemory/CountsCacheInMemory.d.ts +20 -0
- package/types/storages/inMemory/LatenciesCacheInMemory.d.ts +20 -0
- package/types/storages/inMemory/SplitsCacheInMemory.d.ts +9 -1
- package/types/storages/inRedis/CountsCacheInRedis.d.ts +9 -0
- package/types/storages/inRedis/LatenciesCacheInRedis.d.ts +9 -0
- package/types/storages/inRedis/SplitsCacheInRedis.d.ts +8 -0
- package/types/storages/metadataBuilder.d.ts +3 -0
- package/types/storages/pluggable/SplitsCachePluggable.d.ts +8 -0
- package/types/storages/types.d.ts +4 -0
- package/types/sync/offline/LocalhostFromFile.d.ts +2 -0
- package/types/sync/offline/splitsParser/splitsParserFromFile.d.ts +2 -0
- package/types/sync/offline/updaters/splitChangesUpdater.d.ts +0 -0
- package/types/sync/polling/updaters/splitChangesUpdater.d.ts +3 -3
- package/types/sync/submitters/eventsSyncTask.d.ts +8 -0
- package/types/sync/submitters/impressionCountsSubmitterInRedis.d.ts +5 -0
- package/types/sync/submitters/impressionCountsSyncTask.d.ts +13 -0
- package/types/sync/submitters/impressionsSyncTask.d.ts +14 -0
- package/types/sync/submitters/metricsSyncTask.d.ts +12 -0
- package/types/sync/submitters/submitterSyncTask.d.ts +10 -0
- package/types/sync/submitters/types.d.ts +7 -1
- package/types/sync/submitters/uniqueKeysSubmitterInRedis.d.ts +5 -0
- package/types/sync/syncTaskComposite.d.ts +5 -0
- package/types/trackers/filter/bloomFilter.d.ts +10 -0
- package/types/trackers/filter/dictionaryFilter.d.ts +8 -0
- package/types/trackers/filter/types.d.ts +5 -0
- package/types/types.d.ts +118 -1
- package/types/utils/constants/index.d.ts +4 -0
- package/types/utils/lang/sets.d.ts +1 -0
- package/types/utils/settingsValidation/splitFilters.d.ts +1 -0
- package/types/utils/timeTracker/index.d.ts +70 -0
- package/types/sdkClient/identity.d.ts +0 -6
- package/types/utils/inputValidation/sdkKey.d.ts +0 -7
- /package/types/storages/inMemory/{UniqueKeysCacheInMemory.d.ts → uniqueKeysCacheInMemory.d.ts} +0 -0
- /package/types/storages/inMemory/{UniqueKeysCacheInMemoryCS.d.ts → uniqueKeysCacheInMemoryCS.d.ts} +0 -0
- /package/types/storages/inRedis/{UniqueKeysCacheInRedis.d.ts → uniqueKeysCacheInRedis.d.ts} +0 -0
|
@@ -17,6 +17,7 @@ import { IReadinessManager } from '../readiness/types';
|
|
|
17
17
|
import { MaybeThenable } from '../dtos/types';
|
|
18
18
|
import { ISettings, SplitIO } from '../types';
|
|
19
19
|
import { isStorageSync } from '../trackers/impressionObserver/utils';
|
|
20
|
+
import { flagSetsAreValid } from '../utils/settingsValidation/splitFilters';
|
|
20
21
|
|
|
21
22
|
/**
|
|
22
23
|
* Decorator that validates the input before actually executing the client methods.
|
|
@@ -30,21 +31,28 @@ export function clientInputValidationDecorator<TClient extends SplitIO.IClient |
|
|
|
30
31
|
/**
|
|
31
32
|
* Avoid repeating this validations code
|
|
32
33
|
*/
|
|
33
|
-
function validateEvaluationParams(maybeKey: SplitIO.SplitKey, maybeFeatureFlagNameOrNames: string | string[], maybeAttributes: SplitIO.Attributes | undefined, methodName: string) {
|
|
34
|
+
function validateEvaluationParams(maybeKey: SplitIO.SplitKey, maybeFeatureFlagNameOrNames: string | string[] | undefined, maybeAttributes: SplitIO.Attributes | undefined, methodName: string, maybeFlagSetNameOrNames?: string[] | undefined) {
|
|
34
35
|
const multi = startsWith(methodName, 'getTreatments');
|
|
35
36
|
const key = validateKey(log, maybeKey, methodName);
|
|
36
|
-
|
|
37
|
+
let splitOrSplits: string | string[] | false = false;
|
|
38
|
+
let flagSetOrFlagSets: string[] = [];
|
|
39
|
+
if (maybeFeatureFlagNameOrNames) {
|
|
40
|
+
splitOrSplits = multi ? validateSplits(log, maybeFeatureFlagNameOrNames, methodName) : validateSplit(log, maybeFeatureFlagNameOrNames, methodName);
|
|
41
|
+
}
|
|
37
42
|
const attributes = validateAttributes(log, maybeAttributes, methodName);
|
|
38
43
|
const isNotDestroyed = validateIfNotDestroyed(log, readinessManager, methodName);
|
|
39
|
-
|
|
44
|
+
if (maybeFlagSetNameOrNames) {
|
|
45
|
+
flagSetOrFlagSets = flagSetsAreValid(log, methodName, maybeFlagSetNameOrNames, settings.sync.__splitFiltersValidation.groupedFilters.bySet);
|
|
46
|
+
}
|
|
40
47
|
validateIfOperational(log, readinessManager, methodName);
|
|
41
48
|
|
|
42
|
-
const valid = isNotDestroyed && key && splitOrSplits && attributes !== false;
|
|
49
|
+
const valid = isNotDestroyed && key && (splitOrSplits || flagSetOrFlagSets.length > 0) && attributes !== false;
|
|
43
50
|
|
|
44
51
|
return {
|
|
45
52
|
valid,
|
|
46
53
|
key,
|
|
47
54
|
splitOrSplits,
|
|
55
|
+
flagSetOrFlagSets,
|
|
48
56
|
attributes
|
|
49
57
|
};
|
|
50
58
|
}
|
|
@@ -99,6 +107,46 @@ export function clientInputValidationDecorator<TClient extends SplitIO.IClient |
|
|
|
99
107
|
}
|
|
100
108
|
}
|
|
101
109
|
|
|
110
|
+
function getTreatmentsByFlagSets(maybeKey: SplitIO.SplitKey, maybeFlagSets: string[], maybeAttributes?: SplitIO.Attributes) {
|
|
111
|
+
const params = validateEvaluationParams(maybeKey, undefined, maybeAttributes, 'getTreatmentsByFlagSets', maybeFlagSets);
|
|
112
|
+
|
|
113
|
+
if (params.valid) {
|
|
114
|
+
return client.getTreatmentsByFlagSets(params.key as SplitIO.SplitKey, params.flagSetOrFlagSets as string[], params.attributes as SplitIO.Attributes | undefined);
|
|
115
|
+
} else {
|
|
116
|
+
return wrapResult({});
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function getTreatmentsWithConfigByFlagSets(maybeKey: SplitIO.SplitKey, maybeFlagSets: string[], maybeAttributes?: SplitIO.Attributes) {
|
|
121
|
+
const params = validateEvaluationParams(maybeKey, undefined, maybeAttributes, 'getTreatmentsWithConfigByFlagSets', maybeFlagSets);
|
|
122
|
+
|
|
123
|
+
if (params.valid) {
|
|
124
|
+
return client.getTreatmentsWithConfigByFlagSets(params.key as SplitIO.SplitKey, params.flagSetOrFlagSets as string[], params.attributes as SplitIO.Attributes | undefined);
|
|
125
|
+
} else {
|
|
126
|
+
return wrapResult({});
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
function getTreatmentsByFlagSet(maybeKey: SplitIO.SplitKey, maybeFlagSet: string, maybeAttributes?: SplitIO.Attributes) {
|
|
131
|
+
const params = validateEvaluationParams(maybeKey, undefined, maybeAttributes, 'getTreatmentsByFlagSet', [maybeFlagSet]);
|
|
132
|
+
|
|
133
|
+
if (params.valid) {
|
|
134
|
+
return client.getTreatmentsByFlagSet(params.key as SplitIO.SplitKey, params.flagSetOrFlagSets[0] as string, params.attributes as SplitIO.Attributes | undefined);
|
|
135
|
+
} else {
|
|
136
|
+
return wrapResult({});
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
function getTreatmentsWithConfigByFlagSet(maybeKey: SplitIO.SplitKey, maybeFlagSet: string, maybeAttributes?: SplitIO.Attributes) {
|
|
141
|
+
const params = validateEvaluationParams(maybeKey, undefined, maybeAttributes, 'getTreatmentsWithConfigByFlagSet', [maybeFlagSet]);
|
|
142
|
+
|
|
143
|
+
if (params.valid) {
|
|
144
|
+
return client.getTreatmentsWithConfigByFlagSet(params.key as SplitIO.SplitKey, params.flagSetOrFlagSets[0] as string, params.attributes as SplitIO.Attributes | undefined);
|
|
145
|
+
} else {
|
|
146
|
+
return wrapResult({});
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
102
150
|
function track(maybeKey: SplitIO.SplitKey, maybeTT: string, maybeEvent: string, maybeEventValue?: number, maybeProperties?: SplitIO.Properties) {
|
|
103
151
|
const key = validateKey(log, maybeKey, 'track');
|
|
104
152
|
const tt = validateTrafficType(log, maybeTT, 'track');
|
|
@@ -119,6 +167,10 @@ export function clientInputValidationDecorator<TClient extends SplitIO.IClient |
|
|
|
119
167
|
getTreatmentWithConfig,
|
|
120
168
|
getTreatments,
|
|
121
169
|
getTreatmentsWithConfig,
|
|
170
|
+
getTreatmentsByFlagSets,
|
|
171
|
+
getTreatmentsWithConfigByFlagSets,
|
|
172
|
+
getTreatmentsByFlagSet,
|
|
173
|
+
getTreatmentsWithConfigByFlagSet,
|
|
122
174
|
track
|
|
123
175
|
} as TClient;
|
|
124
176
|
}
|
package/src/sdkManager/index.ts
CHANGED
|
@@ -31,7 +31,8 @@ function objectToView(splitObject: ISplit | null): SplitIO.SplitView | null {
|
|
|
31
31
|
killed: splitObject.killed,
|
|
32
32
|
changeNumber: splitObject.changeNumber || 0,
|
|
33
33
|
treatments: collectTreatments(splitObject),
|
|
34
|
-
configs: splitObject.configurations || {}
|
|
34
|
+
configs: splitObject.configurations || {},
|
|
35
|
+
sets: splitObject.sets || []
|
|
35
36
|
};
|
|
36
37
|
}
|
|
37
38
|
|
package/src/services/splitApi.ts
CHANGED
|
@@ -5,6 +5,7 @@ import { ISplitApi } from './types';
|
|
|
5
5
|
import { objectAssign } from '../utils/lang/objectAssign';
|
|
6
6
|
import { ITelemetryTracker } from '../trackers/types';
|
|
7
7
|
import { SPLITS, IMPRESSIONS, IMPRESSIONS_COUNT, EVENTS, TELEMETRY, TOKEN, SEGMENT, MY_SEGMENT } from '../utils/constants';
|
|
8
|
+
import { ERROR_TOO_MANY_SETS } from '../logger/constants';
|
|
8
9
|
|
|
9
10
|
const noCacheHeaderOptions = { headers: { 'Cache-Control': 'no-cache' } };
|
|
10
11
|
|
|
@@ -53,7 +54,11 @@ export function splitApiFactory(
|
|
|
53
54
|
|
|
54
55
|
fetchSplitChanges(since: number, noCache?: boolean, till?: number) {
|
|
55
56
|
const url = `${urls.sdk}/splitChanges?since=${since}${till ? '&till=' + till : ''}${filterQueryString || ''}`;
|
|
56
|
-
return splitHttpClient(url, noCache ? noCacheHeaderOptions : undefined, telemetryTracker.trackHttp(SPLITS))
|
|
57
|
+
return splitHttpClient(url, noCache ? noCacheHeaderOptions : undefined, telemetryTracker.trackHttp(SPLITS))
|
|
58
|
+
.catch((err) => {
|
|
59
|
+
if (err.statusCode === 414) settings.log.error(ERROR_TOO_MANY_SETS);
|
|
60
|
+
throw err;
|
|
61
|
+
});
|
|
57
62
|
},
|
|
58
63
|
|
|
59
64
|
fetchSegmentChanges(since: number, segmentName: string, noCache?: boolean, till?: number) {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ISplitsCacheAsync } from './types';
|
|
2
2
|
import { ISplit } from '../dtos/types';
|
|
3
3
|
import { objectAssign } from '../utils/lang/objectAssign';
|
|
4
|
+
import { ISet } from '../utils/lang/sets';
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* This class provides a skeletal implementation of the ISplitsCacheAsync interface
|
|
@@ -17,6 +18,7 @@ export abstract class AbstractSplitsCacheAsync implements ISplitsCacheAsync {
|
|
|
17
18
|
abstract getChangeNumber(): Promise<number>
|
|
18
19
|
abstract getAll(): Promise<ISplit[]>
|
|
19
20
|
abstract getSplitNames(): Promise<string[]>
|
|
21
|
+
abstract getNamesByFlagSets(flagSets: string[]): Promise<ISet<string>>
|
|
20
22
|
abstract trafficTypeExists(trafficType: string): Promise<boolean>
|
|
21
23
|
abstract clear(): Promise<boolean | void>
|
|
22
24
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ISplitsCacheSync } from './types';
|
|
2
2
|
import { ISplit } from '../dtos/types';
|
|
3
3
|
import { objectAssign } from '../utils/lang/objectAssign';
|
|
4
|
+
import { ISet } from '../utils/lang/sets';
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* This class provides a skeletal implementation of the ISplitsCacheSync interface
|
|
@@ -78,6 +79,8 @@ export abstract class AbstractSplitsCacheSync implements ISplitsCacheSync {
|
|
|
78
79
|
return false;
|
|
79
80
|
}
|
|
80
81
|
|
|
82
|
+
abstract getNamesByFlagSets(flagSets: string[]): ISet<string>
|
|
83
|
+
|
|
81
84
|
}
|
|
82
85
|
|
|
83
86
|
/**
|
|
@@ -20,6 +20,10 @@ export class KeyBuilder {
|
|
|
20
20
|
return `${this.prefix}.trafficType.${trafficType}`;
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
+
buildFlagSetKey(flagSet: string) {
|
|
24
|
+
return `${this.prefix}.flagset.${flagSet}`;
|
|
25
|
+
}
|
|
26
|
+
|
|
23
27
|
buildSplitKey(splitName: string) {
|
|
24
28
|
return `${this.prefix}.split.${splitName}`;
|
|
25
29
|
}
|
|
@@ -7,6 +7,10 @@ export const METHOD_NAMES: Record<Method, string> = {
|
|
|
7
7
|
ts: 'treatments',
|
|
8
8
|
tc: 'treatmentWithConfig',
|
|
9
9
|
tcs: 'treatmentsWithConfig',
|
|
10
|
+
tf: 'treatmentsByFlagSet',
|
|
11
|
+
tfs: 'treatmentsByFlagSets',
|
|
12
|
+
tcf: 'treatmentsWithConfigByFlagSet',
|
|
13
|
+
tcfs: 'treatmentsWithConfigByFlagSets',
|
|
10
14
|
tr: 'track'
|
|
11
15
|
};
|
|
12
16
|
|
|
@@ -4,6 +4,7 @@ import { isFiniteNumber, toNumber, isNaNNumber } from '../../utils/lang';
|
|
|
4
4
|
import { KeyBuilderCS } from '../KeyBuilderCS';
|
|
5
5
|
import { ILogger } from '../../logger/types';
|
|
6
6
|
import { LOG_PREFIX } from './constants';
|
|
7
|
+
import { ISet, _Set, returnSetsUnion, setToArray } from '../../utils/lang/sets';
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* ISplitsCacheSync implementation that stores split definitions in browser LocalStorage.
|
|
@@ -12,8 +13,8 @@ export class SplitsCacheInLocal extends AbstractSplitsCacheSync {
|
|
|
12
13
|
|
|
13
14
|
private readonly keys: KeyBuilderCS;
|
|
14
15
|
private readonly splitFiltersValidation: ISplitFiltersValidation;
|
|
16
|
+
private readonly flagSetsFilter: string[];
|
|
15
17
|
private hasSync?: boolean;
|
|
16
|
-
private cacheReadyButNeedsToFlush: boolean = false;
|
|
17
18
|
private updateNewFilter?: boolean;
|
|
18
19
|
|
|
19
20
|
/**
|
|
@@ -21,10 +22,11 @@ export class SplitsCacheInLocal extends AbstractSplitsCacheSync {
|
|
|
21
22
|
* @param {number | undefined} expirationTimestamp
|
|
22
23
|
* @param {ISplitFiltersValidation} splitFiltersValidation
|
|
23
24
|
*/
|
|
24
|
-
constructor(private readonly log: ILogger, keys: KeyBuilderCS, expirationTimestamp?: number, splitFiltersValidation: ISplitFiltersValidation = { queryString: null, groupedFilters: { byName: [], byPrefix: [] }, validFilters: [] }) {
|
|
25
|
+
constructor(private readonly log: ILogger, keys: KeyBuilderCS, expirationTimestamp?: number, splitFiltersValidation: ISplitFiltersValidation = { queryString: null, groupedFilters: { bySet: [], byName: [], byPrefix: [] }, validFilters: [] }) {
|
|
25
26
|
super();
|
|
26
27
|
this.keys = keys;
|
|
27
28
|
this.splitFiltersValidation = splitFiltersValidation;
|
|
29
|
+
this.flagSetsFilter = this.splitFiltersValidation.groupedFilters.bySet;
|
|
28
30
|
|
|
29
31
|
this._checkExpiration(expirationTimestamp);
|
|
30
32
|
|
|
@@ -106,6 +108,9 @@ export class SplitsCacheInLocal extends AbstractSplitsCacheSync {
|
|
|
106
108
|
this._incrementCounts(split);
|
|
107
109
|
this._decrementCounts(previousSplit);
|
|
108
110
|
|
|
111
|
+
if (previousSplit) this.removeFromFlagSets(previousSplit.name, previousSplit.sets);
|
|
112
|
+
this.addToFlagSets(split);
|
|
113
|
+
|
|
109
114
|
return true;
|
|
110
115
|
} catch (e) {
|
|
111
116
|
this.log.error(LOG_PREFIX + e);
|
|
@@ -119,6 +124,7 @@ export class SplitsCacheInLocal extends AbstractSplitsCacheSync {
|
|
|
119
124
|
localStorage.removeItem(this.keys.buildSplitKey(name));
|
|
120
125
|
|
|
121
126
|
this._decrementCounts(split);
|
|
127
|
+
if (split) this.removeFromFlagSets(split.name, split.sets);
|
|
122
128
|
|
|
123
129
|
return true;
|
|
124
130
|
} catch (e) {
|
|
@@ -133,11 +139,6 @@ export class SplitsCacheInLocal extends AbstractSplitsCacheSync {
|
|
|
133
139
|
}
|
|
134
140
|
|
|
135
141
|
setChangeNumber(changeNumber: number): boolean {
|
|
136
|
-
// when cache is ready but using a new split query, we must clear all split data
|
|
137
|
-
if (this.cacheReadyButNeedsToFlush) {
|
|
138
|
-
this.clear();
|
|
139
|
-
this.cacheReadyButNeedsToFlush = false;
|
|
140
|
-
}
|
|
141
142
|
|
|
142
143
|
// when using a new split query, we must update it at the store
|
|
143
144
|
if (this.updateNewFilter) {
|
|
@@ -220,7 +221,7 @@ export class SplitsCacheInLocal extends AbstractSplitsCacheSync {
|
|
|
220
221
|
* @override
|
|
221
222
|
*/
|
|
222
223
|
checkCache(): boolean {
|
|
223
|
-
return this.getChangeNumber() > -1
|
|
224
|
+
return this.getChangeNumber() > -1;
|
|
224
225
|
}
|
|
225
226
|
|
|
226
227
|
/**
|
|
@@ -237,7 +238,7 @@ export class SplitsCacheInLocal extends AbstractSplitsCacheSync {
|
|
|
237
238
|
}
|
|
238
239
|
|
|
239
240
|
private _checkFilterQuery() {
|
|
240
|
-
const { queryString
|
|
241
|
+
const { queryString } = this.splitFiltersValidation;
|
|
241
242
|
const queryKey = this.keys.buildSplitsFilterQueryKey();
|
|
242
243
|
const currentQueryString = localStorage.getItem(queryKey);
|
|
243
244
|
|
|
@@ -246,29 +247,74 @@ export class SplitsCacheInLocal extends AbstractSplitsCacheSync {
|
|
|
246
247
|
// mark cache to update the new query filter on first successful splits fetch
|
|
247
248
|
this.updateNewFilter = true;
|
|
248
249
|
|
|
249
|
-
// if
|
|
250
|
-
if (this.checkCache())
|
|
251
|
-
|
|
252
|
-
localStorage.setItem(this.keys.buildSplitsTillKey(), '-1');
|
|
253
|
-
|
|
254
|
-
// * remove from cache splits that doesn't match with the new filters
|
|
255
|
-
this.getSplitNames().forEach((splitName) => {
|
|
256
|
-
if (queryString && (
|
|
257
|
-
// @TODO consider redefining `groupedFilters` to expose a method like `groupedFilters::filter(splitName): boolean`
|
|
258
|
-
groupedFilters.byName.indexOf(splitName) > -1 ||
|
|
259
|
-
groupedFilters.byPrefix.some((prefix: string) => splitName.startsWith(prefix + '__'))
|
|
260
|
-
)) {
|
|
261
|
-
// * set `cacheReadyButNeedsToFlush` so that `checkCache` returns true (the storage is ready to be used) and the data is cleared before updating on first successful splits fetch
|
|
262
|
-
this.cacheReadyButNeedsToFlush = true;
|
|
263
|
-
return;
|
|
264
|
-
}
|
|
265
|
-
this.removeSplit(splitName);
|
|
266
|
-
});
|
|
267
|
-
}
|
|
250
|
+
// if there is cache, clear it
|
|
251
|
+
if (this.checkCache()) this.clear();
|
|
252
|
+
|
|
268
253
|
} catch (e) {
|
|
269
254
|
this.log.error(LOG_PREFIX + e);
|
|
270
255
|
}
|
|
271
256
|
}
|
|
272
257
|
// if the filter didn't change, nothing is done
|
|
273
258
|
}
|
|
259
|
+
|
|
260
|
+
getNamesByFlagSets(flagSets: string[]): ISet<string>{
|
|
261
|
+
let toReturn: ISet<string> = new _Set([]);
|
|
262
|
+
flagSets.forEach(flagSet => {
|
|
263
|
+
const flagSetKey = this.keys.buildFlagSetKey(flagSet);
|
|
264
|
+
let flagSetFromLocalStorage = localStorage.getItem(flagSetKey);
|
|
265
|
+
|
|
266
|
+
if (flagSetFromLocalStorage) {
|
|
267
|
+
const flagSetCache = new _Set(JSON.parse(flagSetFromLocalStorage));
|
|
268
|
+
toReturn = returnSetsUnion(toReturn, flagSetCache);
|
|
269
|
+
}
|
|
270
|
+
});
|
|
271
|
+
return toReturn;
|
|
272
|
+
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
private addToFlagSets(featureFlag: ISplit) {
|
|
276
|
+
if (!featureFlag.sets) return;
|
|
277
|
+
|
|
278
|
+
featureFlag.sets.forEach(featureFlagSet => {
|
|
279
|
+
|
|
280
|
+
if (this.flagSetsFilter.length > 0 && !this.flagSetsFilter.some(filterFlagSet => filterFlagSet === featureFlagSet)) return;
|
|
281
|
+
|
|
282
|
+
const flagSetKey = this.keys.buildFlagSetKey(featureFlagSet);
|
|
283
|
+
|
|
284
|
+
let flagSetFromLocalStorage = localStorage.getItem(flagSetKey);
|
|
285
|
+
if (!flagSetFromLocalStorage) flagSetFromLocalStorage = '[]';
|
|
286
|
+
|
|
287
|
+
const flagSetCache = new _Set(JSON.parse(flagSetFromLocalStorage));
|
|
288
|
+
flagSetCache.add(featureFlag.name);
|
|
289
|
+
|
|
290
|
+
localStorage.setItem(flagSetKey, JSON.stringify(setToArray(flagSetCache)));
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
private removeFromFlagSets(featureFlagName: string, flagSets?: string[]) {
|
|
295
|
+
if (!flagSets) return;
|
|
296
|
+
|
|
297
|
+
flagSets.forEach(flagSet => {
|
|
298
|
+
this.removeNames(flagSet, featureFlagName);
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
private removeNames(flagSetName: string, featureFlagName: string) {
|
|
303
|
+
const flagSetKey = this.keys.buildFlagSetKey(flagSetName);
|
|
304
|
+
|
|
305
|
+
let flagSetFromLocalStorage = localStorage.getItem(flagSetKey);
|
|
306
|
+
|
|
307
|
+
if (!flagSetFromLocalStorage) return;
|
|
308
|
+
|
|
309
|
+
const flagSetCache = new _Set(JSON.parse(flagSetFromLocalStorage));
|
|
310
|
+
flagSetCache.delete(featureFlagName);
|
|
311
|
+
|
|
312
|
+
if (flagSetCache.size === 0) {
|
|
313
|
+
localStorage.removeItem(flagSetKey);
|
|
314
|
+
return;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
localStorage.setItem(flagSetKey, JSON.stringify(setToArray(flagSetCache)));
|
|
318
|
+
}
|
|
319
|
+
|
|
274
320
|
}
|
|
@@ -54,7 +54,7 @@ export function InLocalStorage(options: InLocalStorageOptions = {}): IStorageSyn
|
|
|
54
54
|
uniqueKeys: impressionsMode === NONE ? new UniqueKeysCacheInMemoryCS() : undefined,
|
|
55
55
|
|
|
56
56
|
destroy() {
|
|
57
|
-
this.splits = new SplitsCacheInMemory();
|
|
57
|
+
this.splits = new SplitsCacheInMemory(__splitFiltersValidation);
|
|
58
58
|
this.segments = new MySegmentsCacheInMemory();
|
|
59
59
|
this.impressions.clear();
|
|
60
60
|
this.impressionCounts && this.impressionCounts.clear();
|
|
@@ -75,7 +75,7 @@ export function InLocalStorage(options: InLocalStorageOptions = {}): IStorageSyn
|
|
|
75
75
|
telemetry: this.telemetry,
|
|
76
76
|
|
|
77
77
|
destroy() {
|
|
78
|
-
this.splits = new SplitsCacheInMemory();
|
|
78
|
+
this.splits = new SplitsCacheInMemory(__splitFiltersValidation);
|
|
79
79
|
this.segments = new MySegmentsCacheInMemory();
|
|
80
80
|
}
|
|
81
81
|
};
|
|
@@ -14,9 +14,9 @@ import { UniqueKeysCacheInMemory } from './UniqueKeysCacheInMemory';
|
|
|
14
14
|
* @param params parameters required by EventsCacheSync
|
|
15
15
|
*/
|
|
16
16
|
export function InMemoryStorageFactory(params: IStorageFactoryParams): IStorageSync {
|
|
17
|
-
const { settings: { scheduler: { impressionsQueueSize, eventsQueueSize, }, sync: { impressionsMode } } } = params;
|
|
17
|
+
const { settings: { scheduler: { impressionsQueueSize, eventsQueueSize, }, sync: { impressionsMode, __splitFiltersValidation } } } = params;
|
|
18
18
|
|
|
19
|
-
const splits = new SplitsCacheInMemory();
|
|
19
|
+
const splits = new SplitsCacheInMemory(__splitFiltersValidation);
|
|
20
20
|
const segments = new SegmentsCacheInMemory();
|
|
21
21
|
|
|
22
22
|
const storage = {
|
|
@@ -14,9 +14,9 @@ import { UniqueKeysCacheInMemoryCS } from './UniqueKeysCacheInMemoryCS';
|
|
|
14
14
|
* @param params parameters required by EventsCacheSync
|
|
15
15
|
*/
|
|
16
16
|
export function InMemoryStorageCSFactory(params: IStorageFactoryParams): IStorageSync {
|
|
17
|
-
const { settings: { scheduler: { impressionsQueueSize, eventsQueueSize, }, sync: { impressionsMode } } } = params;
|
|
17
|
+
const { settings: { scheduler: { impressionsQueueSize, eventsQueueSize, }, sync: { impressionsMode, __splitFiltersValidation } } } = params;
|
|
18
18
|
|
|
19
|
-
const splits = new SplitsCacheInMemory();
|
|
19
|
+
const splits = new SplitsCacheInMemory(__splitFiltersValidation);
|
|
20
20
|
const segments = new MySegmentsCacheInMemory();
|
|
21
21
|
|
|
22
22
|
const storage = {
|
|
@@ -50,7 +50,7 @@ export function InMemoryStorageCSFactory(params: IStorageFactoryParams): IStorag
|
|
|
50
50
|
|
|
51
51
|
// Set a new splits cache to clean it for the client without affecting other clients
|
|
52
52
|
destroy() {
|
|
53
|
-
this.splits = new SplitsCacheInMemory();
|
|
53
|
+
this.splits = new SplitsCacheInMemory(__splitFiltersValidation);
|
|
54
54
|
this.segments.clear();
|
|
55
55
|
}
|
|
56
56
|
};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { ISplit } from '../../dtos/types';
|
|
1
|
+
import { ISplit, ISplitFiltersValidation } from '../../dtos/types';
|
|
2
2
|
import { AbstractSplitsCacheSync, usesSegments } from '../AbstractSplitsCacheSync';
|
|
3
3
|
import { isFiniteNumber } from '../../utils/lang';
|
|
4
|
+
import { ISet, _Set, returnSetsUnion } from '../../utils/lang/sets';
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* Default ISplitsCacheSync implementation that stores split definitions in memory.
|
|
@@ -8,10 +9,17 @@ import { isFiniteNumber } from '../../utils/lang';
|
|
|
8
9
|
*/
|
|
9
10
|
export class SplitsCacheInMemory extends AbstractSplitsCacheSync {
|
|
10
11
|
|
|
12
|
+
private flagSetsFilter: string[];
|
|
11
13
|
private splitsCache: Record<string, ISplit> = {};
|
|
12
14
|
private ttCache: Record<string, number> = {};
|
|
13
15
|
private changeNumber: number = -1;
|
|
14
16
|
private splitsWithSegmentsCount: number = 0;
|
|
17
|
+
private flagSetsCache: Record<string, ISet<string>> = {};
|
|
18
|
+
|
|
19
|
+
constructor(splitFiltersValidation: ISplitFiltersValidation = { queryString: null, groupedFilters: { bySet: [], byName: [], byPrefix: [] }, validFilters: [] }) {
|
|
20
|
+
super();
|
|
21
|
+
this.flagSetsFilter = splitFiltersValidation.groupedFilters.bySet;
|
|
22
|
+
}
|
|
15
23
|
|
|
16
24
|
clear() {
|
|
17
25
|
this.splitsCache = {};
|
|
@@ -28,6 +36,8 @@ export class SplitsCacheInMemory extends AbstractSplitsCacheSync {
|
|
|
28
36
|
this.ttCache[previousTtName]--;
|
|
29
37
|
if (!this.ttCache[previousTtName]) delete this.ttCache[previousTtName];
|
|
30
38
|
|
|
39
|
+
this.removeFromFlagSets(previousSplit.name, previousSplit.sets);
|
|
40
|
+
|
|
31
41
|
if (usesSegments(previousSplit)) { // Substract from segments count for the previous version of this Split.
|
|
32
42
|
this.splitsWithSegmentsCount--;
|
|
33
43
|
}
|
|
@@ -39,6 +49,7 @@ export class SplitsCacheInMemory extends AbstractSplitsCacheSync {
|
|
|
39
49
|
// Update TT cache
|
|
40
50
|
const ttName = split.trafficTypeName;
|
|
41
51
|
this.ttCache[ttName] = (this.ttCache[ttName] || 0) + 1;
|
|
52
|
+
this.addToFlagSets(split);
|
|
42
53
|
|
|
43
54
|
// Add to segments count for the new version of the Split
|
|
44
55
|
if (usesSegments(split)) this.splitsWithSegmentsCount++;
|
|
@@ -58,6 +69,7 @@ export class SplitsCacheInMemory extends AbstractSplitsCacheSync {
|
|
|
58
69
|
const ttName = split.trafficTypeName;
|
|
59
70
|
this.ttCache[ttName]--; // Update tt cache
|
|
60
71
|
if (!this.ttCache[ttName]) delete this.ttCache[ttName];
|
|
72
|
+
this.removeFromFlagSets(split.name, split.sets);
|
|
61
73
|
|
|
62
74
|
// Update the segments count.
|
|
63
75
|
if (usesSegments(split)) this.splitsWithSegmentsCount--;
|
|
@@ -93,4 +105,41 @@ export class SplitsCacheInMemory extends AbstractSplitsCacheSync {
|
|
|
93
105
|
return this.getChangeNumber() === -1 || this.splitsWithSegmentsCount > 0;
|
|
94
106
|
}
|
|
95
107
|
|
|
108
|
+
getNamesByFlagSets(flagSets: string[]): ISet<string>{
|
|
109
|
+
let toReturn: ISet<string> = new _Set([]);
|
|
110
|
+
flagSets.forEach(flagSet => {
|
|
111
|
+
const featureFlagNames = this.flagSetsCache[flagSet];
|
|
112
|
+
if (featureFlagNames) {
|
|
113
|
+
toReturn = returnSetsUnion(toReturn, featureFlagNames);
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
return toReturn;
|
|
117
|
+
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
private addToFlagSets(featureFlag: ISplit) {
|
|
121
|
+
if (!featureFlag.sets) return;
|
|
122
|
+
featureFlag.sets.forEach(featureFlagSet => {
|
|
123
|
+
|
|
124
|
+
if (this.flagSetsFilter.length > 0 && !this.flagSetsFilter.some(filterFlagSet => filterFlagSet === featureFlagSet)) return;
|
|
125
|
+
|
|
126
|
+
if (!this.flagSetsCache[featureFlagSet]) this.flagSetsCache[featureFlagSet] = new _Set([]);
|
|
127
|
+
|
|
128
|
+
this.flagSetsCache[featureFlagSet].add(featureFlag.name);
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
private removeFromFlagSets(featureFlagName :string, flagSets: string[] | undefined) {
|
|
133
|
+
if (!flagSets) return;
|
|
134
|
+
flagSets.forEach(flagSet => {
|
|
135
|
+
this.removeNames(flagSet, featureFlagName);
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
private removeNames(flagSetName: string, featureFlagName: string) {
|
|
140
|
+
if (!this.flagSetsCache[flagSetName]) return;
|
|
141
|
+
this.flagSetsCache[flagSetName].delete(featureFlagName);
|
|
142
|
+
if (this.flagSetsCache[flagSetName].size === 0) delete this.flagSetsCache[flagSetName];
|
|
143
|
+
}
|
|
144
|
+
|
|
96
145
|
}
|
|
@@ -181,7 +181,7 @@ export class TelemetryCacheInMemory implements ITelemetryCacheSync {
|
|
|
181
181
|
this.e = false;
|
|
182
182
|
}
|
|
183
183
|
|
|
184
|
-
private streamingEvents: StreamingEvent[] = []
|
|
184
|
+
private streamingEvents: StreamingEvent[] = [];
|
|
185
185
|
|
|
186
186
|
popStreamingEvents() {
|
|
187
187
|
return this.streamingEvents.splice(0);
|
|
@@ -33,7 +33,7 @@ interface IRedisCommand {
|
|
|
33
33
|
* Redis adapter on top of the library of choice (written with ioredis) for some extra control.
|
|
34
34
|
*/
|
|
35
35
|
export class RedisAdapter extends ioredis {
|
|
36
|
-
private readonly log: ILogger
|
|
36
|
+
private readonly log: ILogger;
|
|
37
37
|
private _options: object;
|
|
38
38
|
private _notReadyCommandsQueue?: IRedisCommand[];
|
|
39
39
|
private _runningCommands: ISet<Promise<any>>;
|
|
@@ -5,6 +5,7 @@ import { ILogger } from '../../logger/types';
|
|
|
5
5
|
import { LOG_PREFIX } from './constants';
|
|
6
6
|
import { ISplit } from '../../dtos/types';
|
|
7
7
|
import { AbstractSplitsCacheAsync } from '../AbstractSplitsCacheAsync';
|
|
8
|
+
import { ISet, _Set } from '../../utils/lang/sets';
|
|
8
9
|
|
|
9
10
|
/**
|
|
10
11
|
* Discard errors for an answer of multiple operations.
|
|
@@ -188,6 +189,17 @@ export class SplitsCacheInRedis extends AbstractSplitsCacheAsync {
|
|
|
188
189
|
);
|
|
189
190
|
}
|
|
190
191
|
|
|
192
|
+
/**
|
|
193
|
+
* Get list of split names related to a given flag set names list.
|
|
194
|
+
* The returned promise is resolved with the list of split names,
|
|
195
|
+
* or rejected if wrapper operation fails.
|
|
196
|
+
* @todo this is a no-op method to be implemented
|
|
197
|
+
*/
|
|
198
|
+
getNamesByFlagSets(): Promise<ISet<string>> {
|
|
199
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
200
|
+
return new Promise(flagSets => new _Set([]));
|
|
201
|
+
}
|
|
202
|
+
|
|
191
203
|
/**
|
|
192
204
|
* Check traffic type existence.
|
|
193
205
|
* The returned promise is resolved with a boolean indicating whether the TT exist or not.
|
|
@@ -5,6 +5,7 @@ import { ILogger } from '../../logger/types';
|
|
|
5
5
|
import { ISplit } from '../../dtos/types';
|
|
6
6
|
import { LOG_PREFIX } from './constants';
|
|
7
7
|
import { AbstractSplitsCacheAsync } from '../AbstractSplitsCacheAsync';
|
|
8
|
+
import { ISet, _Set } from '../../utils/lang/sets';
|
|
8
9
|
|
|
9
10
|
/**
|
|
10
11
|
* ISplitsCacheAsync implementation for pluggable storages.
|
|
@@ -154,6 +155,17 @@ export class SplitsCachePluggable extends AbstractSplitsCacheAsync {
|
|
|
154
155
|
);
|
|
155
156
|
}
|
|
156
157
|
|
|
158
|
+
/**
|
|
159
|
+
* Get list of split names related to a given flag set names list.
|
|
160
|
+
* The returned promise is resolved with the list of split names,
|
|
161
|
+
* or rejected if wrapper operation fails.
|
|
162
|
+
* @todo this is a no-op method to be implemented
|
|
163
|
+
*/
|
|
164
|
+
getNamesByFlagSets(): Promise<ISet<string>> {
|
|
165
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
166
|
+
return new Promise(flagSets => new _Set([]));
|
|
167
|
+
}
|
|
168
|
+
|
|
157
169
|
/**
|
|
158
170
|
* Check traffic type existence.
|
|
159
171
|
* The returned promise is resolved with a boolean indicating whether the TT exist or not.
|
package/src/storages/types.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { MaybeThenable, ISplit } from '../dtos/types';
|
|
2
2
|
import { EventDataType, HttpErrors, HttpLatencies, ImpressionDataType, LastSync, Method, MethodExceptions, MethodLatencies, MultiMethodExceptions, MultiMethodLatencies, MultiConfigs, OperationType, StoredEventWithMetadata, StoredImpressionWithMetadata, StreamingEvent, UniqueKeysPayloadCs, UniqueKeysPayloadSs, TelemetryUsageStatsPayload, UpdatesFromSSEEnum } from '../sync/submitters/types';
|
|
3
3
|
import { SplitIO, ImpressionDTO, ISettings } from '../types';
|
|
4
|
+
import { ISet } from '../utils/lang/sets';
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* Interface of a pluggable storage wrapper.
|
|
@@ -208,7 +209,8 @@ export interface ISplitsCacheBase {
|
|
|
208
209
|
clear(): MaybeThenable<boolean | void>,
|
|
209
210
|
// should never reject or throw an exception. Instead return false by default, to avoid emitting SDK_READY_FROM_CACHE.
|
|
210
211
|
checkCache(): MaybeThenable<boolean>,
|
|
211
|
-
killLocally(name: string, defaultTreatment: string, changeNumber: number): MaybeThenable<boolean
|
|
212
|
+
killLocally(name: string, defaultTreatment: string, changeNumber: number): MaybeThenable<boolean>,
|
|
213
|
+
getNamesByFlagSets(flagSets: string[]): MaybeThenable<ISet<string>>
|
|
212
214
|
}
|
|
213
215
|
|
|
214
216
|
export interface ISplitsCacheSync extends ISplitsCacheBase {
|
|
@@ -224,7 +226,8 @@ export interface ISplitsCacheSync extends ISplitsCacheBase {
|
|
|
224
226
|
usesSegments(): boolean,
|
|
225
227
|
clear(): void,
|
|
226
228
|
checkCache(): boolean,
|
|
227
|
-
killLocally(name: string, defaultTreatment: string, changeNumber: number): boolean
|
|
229
|
+
killLocally(name: string, defaultTreatment: string, changeNumber: number): boolean,
|
|
230
|
+
getNamesByFlagSets(flagSets: string[]): ISet<string>
|
|
228
231
|
}
|
|
229
232
|
|
|
230
233
|
export interface ISplitsCacheAsync extends ISplitsCacheBase {
|
|
@@ -240,7 +243,8 @@ export interface ISplitsCacheAsync extends ISplitsCacheBase {
|
|
|
240
243
|
usesSegments(): Promise<boolean>,
|
|
241
244
|
clear(): Promise<boolean | void>,
|
|
242
245
|
checkCache(): Promise<boolean>,
|
|
243
|
-
killLocally(name: string, defaultTreatment: string, changeNumber: number): Promise<boolean
|
|
246
|
+
killLocally(name: string, defaultTreatment: string, changeNumber: number): Promise<boolean>,
|
|
247
|
+
getNamesByFlagSets(flagSets: string[]): Promise<ISet<string>>
|
|
244
248
|
}
|
|
245
249
|
|
|
246
250
|
/** Segments cache */
|
|
@@ -24,6 +24,7 @@ export function splitsSyncTaskFactory(
|
|
|
24
24
|
splitChangesFetcherFactory(fetchSplitChanges),
|
|
25
25
|
storage.splits,
|
|
26
26
|
storage.segments,
|
|
27
|
+
settings.sync.__splitFiltersValidation,
|
|
27
28
|
readiness.splits,
|
|
28
29
|
settings.startup.requestTimeoutBeforeReady,
|
|
29
30
|
settings.startup.retriesOnFailureBeforeReady,
|