@splitsoftware/splitio-commons 3.1.1-rc.1 → 3.1.1-rc.10
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 +10 -1
- package/cjs/evaluator/condition/index.js +2 -2
- package/cjs/evaluator/fallbackTreatmentsCalculator/fallbackSanitizer/index.js +8 -5
- package/cjs/evaluator/index.js +71 -76
- package/cjs/listeners/browser.js +1 -2
- package/cjs/listeners/node.js +4 -4
- package/cjs/logger/constants.js +20 -15
- package/cjs/logger/messages/debug.js +6 -5
- package/cjs/logger/messages/error.js +3 -3
- package/cjs/logger/messages/info.js +4 -3
- package/cjs/logger/messages/warn.js +7 -6
- package/cjs/presets/serverSide.js +2 -2
- package/cjs/readiness/constants.js +4 -5
- package/cjs/readiness/readinessManager.js +23 -23
- package/cjs/readiness/sdkReadinessManager.js +17 -1
- package/cjs/sdkClient/client.js +51 -27
- package/cjs/sdkClient/clientInputValidation.js +17 -6
- package/cjs/sdkClient/sdkClient.js +60 -3
- package/cjs/sdkFactory/index.js +15 -11
- package/cjs/sdkManager/index.js +5 -5
- package/cjs/services/decorateHeaders.js +1 -2
- package/cjs/services/splitApi.js +1 -14
- package/cjs/services/splitHttpClient.js +5 -3
- package/cjs/storages/AbstractSplitsCacheAsync.js +51 -0
- package/cjs/storages/AbstractSplitsCacheSync.js +76 -0
- package/cjs/storages/KeyBuilder.js +6 -6
- package/cjs/storages/KeyBuilderCS.js +5 -5
- package/cjs/storages/KeyBuilderSS.js +2 -2
- package/cjs/storages/getRolloutPlan.js +3 -3
- package/cjs/storages/inLocalStorage/MySegmentsCacheInLocal.js +2 -1
- package/cjs/storages/inLocalStorage/RBSegmentsCacheInLocal.js +10 -10
- package/cjs/storages/inLocalStorage/SplitsCacheInLocal.js +194 -0
- package/cjs/storages/inLocalStorage/index.js +6 -6
- package/cjs/storages/inLocalStorage/validateCache.js +3 -3
- package/cjs/storages/inMemory/InMemoryStorage.js +4 -4
- package/cjs/storages/inMemory/InMemoryStorageCS.js +5 -5
- package/cjs/storages/inMemory/RBSegmentsCacheInMemory.js +5 -5
- package/cjs/storages/inMemory/SegmentsCacheInMemory.js +1 -1
- package/cjs/storages/inMemory/SplitsCacheInMemory.js +121 -0
- package/cjs/storages/inMemory/TelemetryCacheInMemory.js +5 -5
- package/cjs/storages/inRedis/RBSegmentsCacheInRedis.js +1 -1
- package/cjs/storages/inRedis/RedisAdapter.js +8 -5
- package/cjs/storages/inRedis/{DefinitionsCacheInRedis.js → SplitsCacheInRedis.js} +77 -77
- package/cjs/storages/inRedis/index.js +2 -2
- package/cjs/storages/pluggable/RBSegmentsCachePluggable.js +1 -1
- package/cjs/storages/pluggable/SplitsCachePluggable.js +212 -0
- package/cjs/storages/pluggable/index.js +2 -2
- package/cjs/storages/setRolloutPlan.js +4 -4
- package/cjs/storages/utils.js +0 -1
- package/cjs/sync/offline/syncTasks/fromObjectSyncTask.js +5 -5
- package/cjs/sync/polling/fetchers/splitChangesFetcher.js +15 -24
- package/cjs/sync/polling/pollingManagerCS.js +20 -20
- package/cjs/sync/polling/pollingManagerSS.js +15 -15
- package/cjs/sync/polling/syncTasks/segmentsSyncTask.js +3 -2
- package/cjs/sync/polling/syncTasks/splitsSyncTask.js +13 -0
- package/cjs/sync/polling/updaters/mySegmentsUpdater.js +3 -3
- package/cjs/sync/polling/updaters/segmentChangesUpdater.js +6 -6
- package/cjs/sync/polling/updaters/{definitionChangesUpdater.js → splitChangesUpdater.js} +68 -65
- package/cjs/sync/streaming/AuthClient/index.js +1 -1
- package/cjs/sync/streaming/SSEHandler/NotificationKeeper.js +1 -1
- package/cjs/sync/streaming/SSEHandler/index.js +1 -1
- package/cjs/sync/streaming/UpdateWorkers/{DefinitionsUpdateWorker.js → SplitsUpdateWorker.js} +19 -16
- package/cjs/sync/streaming/constants.js +3 -3
- package/cjs/sync/streaming/parseUtils.js +11 -11
- package/cjs/sync/streaming/pushManager.js +16 -16
- package/cjs/sync/submitters/eventsSubmitter.js +1 -1
- package/cjs/sync/submitters/impressionCountsSubmitter.js +1 -1
- package/cjs/sync/submitters/impressionsSubmitter.js +4 -5
- package/cjs/sync/submitters/telemetrySubmitter.js +4 -3
- package/cjs/sync/submitters/uniqueKeysSubmitter.js +1 -1
- package/cjs/sync/syncManagerOnline.js +7 -12
- package/cjs/utils/Backoff.js +0 -20
- package/cjs/utils/inputValidation/index.js +7 -7
- package/cjs/utils/inputValidation/isOperational.js +4 -4
- package/cjs/utils/inputValidation/{definition.js → split.js} +10 -10
- package/cjs/utils/inputValidation/{definitionExistence.js → splitExistence.js} +6 -6
- package/cjs/utils/inputValidation/splits.js +25 -0
- package/cjs/utils/labels/index.js +3 -3
- package/cjs/utils/settingsValidation/index.js +0 -2
- package/cjs/utils/settingsValidation/splitFilters.js +3 -3
- package/cjs/utils/settingsValidation/url.js +2 -6
- package/esm/evaluator/condition/index.js +2 -2
- package/esm/evaluator/fallbackTreatmentsCalculator/fallbackSanitizer/index.js +8 -5
- package/esm/evaluator/index.js +71 -75
- package/esm/listeners/browser.js +1 -2
- package/esm/listeners/node.js +4 -4
- package/esm/logger/constants.js +17 -12
- package/esm/logger/messages/debug.js +6 -5
- package/esm/logger/messages/error.js +3 -3
- package/esm/logger/messages/info.js +4 -3
- package/esm/logger/messages/warn.js +7 -6
- package/esm/presets/serverSide.js +2 -2
- package/esm/readiness/constants.js +3 -4
- package/esm/readiness/readinessManager.js +24 -24
- package/esm/readiness/sdkReadinessManager.js +18 -2
- package/esm/sdkClient/client.js +51 -26
- package/esm/sdkClient/clientInputValidation.js +19 -8
- package/esm/sdkClient/sdkClient.js +60 -3
- package/esm/sdkFactory/index.js +16 -12
- package/esm/sdkManager/index.js +6 -6
- package/esm/services/decorateHeaders.js +1 -2
- package/esm/services/splitApi.js +1 -14
- package/esm/services/splitHttpClient.js +5 -3
- package/esm/storages/AbstractSplitsCacheAsync.js +48 -0
- package/esm/storages/AbstractSplitsCacheSync.js +71 -0
- package/esm/storages/KeyBuilder.js +6 -6
- package/esm/storages/KeyBuilderCS.js +5 -5
- package/esm/storages/KeyBuilderSS.js +2 -2
- package/esm/storages/getRolloutPlan.js +3 -3
- package/esm/storages/inLocalStorage/MySegmentsCacheInLocal.js +2 -1
- package/esm/storages/inLocalStorage/RBSegmentsCacheInLocal.js +7 -7
- package/esm/storages/inLocalStorage/SplitsCacheInLocal.js +191 -0
- package/esm/storages/inLocalStorage/index.js +6 -6
- package/esm/storages/inLocalStorage/validateCache.js +3 -3
- package/esm/storages/inMemory/InMemoryStorage.js +4 -4
- package/esm/storages/inMemory/InMemoryStorageCS.js +5 -5
- package/esm/storages/inMemory/RBSegmentsCacheInMemory.js +2 -2
- package/esm/storages/inMemory/SegmentsCacheInMemory.js +1 -1
- package/esm/storages/inMemory/SplitsCacheInMemory.js +118 -0
- package/esm/storages/inMemory/TelemetryCacheInMemory.js +5 -5
- package/esm/storages/inRedis/RBSegmentsCacheInRedis.js +1 -1
- package/esm/storages/inRedis/RedisAdapter.js +8 -5
- package/esm/storages/inRedis/{DefinitionsCacheInRedis.js → SplitsCacheInRedis.js} +76 -76
- package/esm/storages/inRedis/index.js +2 -2
- package/esm/storages/pluggable/RBSegmentsCachePluggable.js +1 -1
- package/esm/storages/pluggable/SplitsCachePluggable.js +209 -0
- package/esm/storages/pluggable/index.js +2 -2
- package/esm/storages/setRolloutPlan.js +4 -4
- package/esm/storages/utils.js +0 -1
- package/esm/sync/offline/syncTasks/fromObjectSyncTask.js +6 -6
- package/esm/sync/polling/fetchers/splitChangesFetcher.js +16 -25
- package/esm/sync/polling/pollingManagerCS.js +17 -17
- package/esm/sync/polling/pollingManagerSS.js +15 -15
- package/esm/sync/polling/syncTasks/segmentsSyncTask.js +3 -2
- package/esm/sync/polling/syncTasks/splitsSyncTask.js +9 -0
- package/esm/sync/polling/updaters/mySegmentsUpdater.js +3 -3
- package/esm/sync/polling/updaters/segmentChangesUpdater.js +7 -7
- package/esm/sync/polling/updaters/{definitionChangesUpdater.js → splitChangesUpdater.js} +68 -65
- package/esm/sync/streaming/AuthClient/index.js +1 -1
- package/esm/sync/streaming/SSEHandler/NotificationKeeper.js +2 -2
- package/esm/sync/streaming/SSEHandler/index.js +2 -2
- package/esm/sync/streaming/UpdateWorkers/{DefinitionsUpdateWorker.js → SplitsUpdateWorker.js} +18 -15
- package/esm/sync/streaming/constants.js +2 -2
- package/esm/sync/streaming/parseUtils.js +9 -9
- package/esm/sync/streaming/pushManager.js +18 -18
- package/esm/sync/submitters/eventsSubmitter.js +1 -1
- package/esm/sync/submitters/impressionCountsSubmitter.js +1 -1
- package/esm/sync/submitters/impressionsSubmitter.js +4 -5
- package/esm/sync/submitters/telemetrySubmitter.js +4 -3
- package/esm/sync/submitters/uniqueKeysSubmitter.js +1 -1
- package/esm/sync/syncManagerOnline.js +6 -11
- package/esm/utils/Backoff.js +0 -20
- package/esm/utils/inputValidation/index.js +3 -3
- package/esm/utils/inputValidation/isOperational.js +4 -4
- package/esm/utils/inputValidation/{definition.js → split.js} +8 -8
- package/esm/utils/inputValidation/splitExistence.js +15 -0
- package/esm/utils/inputValidation/splits.js +21 -0
- package/esm/utils/labels/index.js +2 -2
- package/esm/utils/settingsValidation/index.js +0 -2
- package/esm/utils/settingsValidation/splitFilters.js +3 -3
- package/esm/utils/settingsValidation/url.js +2 -6
- package/package.json +6 -7
- package/src/dtos/types.ts +1 -1
- package/src/evaluator/index.ts +11 -5
- package/src/evaluator/types.ts +1 -0
- package/src/presets/serverSide.ts +3 -3
- package/src/sdkClient/client.ts +3 -4
- package/src/sdkClient/sdkLifecycle.ts +3 -0
- package/src/services/authProvider.ts +41 -19
- package/src/services/secureSplitHttpClient.ts +10 -18
- package/src/services/serviceApi.ts +27 -24
- package/src/services/splitApi.ts +10 -9
- package/src/services/types.ts +5 -4
- package/src/storages/inRedis/RedisAdapter.ts +8 -5
- package/src/sync/polling/pollingManagerCS.ts +80 -78
- package/src/sync/polling/pollingManagerSS.ts +49 -45
- package/src/sync/polling/updaters/definitionChangesUpdater.ts +3 -3
- package/src/sync/polling/updaters/segmentChangesUpdater.ts +1 -1
- package/src/sync/streaming/AuthClient/index.ts +14 -15
- package/src/sync/streaming/AuthClient/types.ts +9 -13
- package/src/sync/streaming/SSEClient/index.ts +2 -2
- package/src/sync/streaming/SSEClient/types.ts +2 -2
- package/src/sync/streaming/SSEHandler/index.ts +2 -1
- package/src/sync/streaming/SSEHandler/types.ts +2 -2
- package/src/sync/streaming/constants.ts +1 -0
- package/src/sync/streaming/pushManager.ts +32 -42
- package/src/sync/streaming/types.ts +3 -2
- package/src/sync/submitters/impressionsSubmitter.ts +3 -3
- package/src/sync/submitters/types.ts +2 -2
- package/src/sync/syncManagerOnline.ts +2 -8
- package/src/utils/Backoff.ts +16 -4
- package/types/splitio.d.ts +5 -4
- package/cjs/platform/browser.js +0 -15
- package/cjs/platform/getEventSource/browser.js +0 -8
- package/cjs/platform/getEventSource/eventsource.js +0 -480
- package/cjs/platform/getEventSource/node.js +0 -26
- package/cjs/platform/getFetch/browser.js +0 -9
- package/cjs/platform/getFetch/node.js +0 -27
- package/cjs/platform/getOptions/node.js +0 -25
- package/cjs/platform/node.js +0 -17
- package/cjs/sdkClient/sdkLifecycle.js +0 -72
- package/cjs/sdkClient/trackMethod.js +0 -56
- package/cjs/services/authProvider.js +0 -67
- package/cjs/services/secureSplitHttpClient.js +0 -39
- package/cjs/services/serviceApi.js +0 -145
- package/cjs/storages/AbstractDefinitionsCacheAsync.js +0 -51
- package/cjs/storages/AbstractDefinitionsCacheSync.js +0 -76
- package/cjs/storages/inLocalStorage/DefinitionsCacheInLocal.js +0 -194
- package/cjs/storages/inMemory/DefinitionsCacheInMemory.js +0 -121
- package/cjs/storages/pluggable/DefinitionsCachePluggable.js +0 -212
- package/cjs/sync/polling/syncTasks/definitionsSyncTask.js +0 -13
- package/cjs/utils/EventEmitter.js +0 -391
- package/cjs/utils/filter/bloomFilter.js +0 -37
- package/cjs/utils/inputValidation/definitions.js +0 -25
- package/cjs/utils/inputValidation/target.js +0 -22
- package/esm/platform/browser.js +0 -12
- package/esm/platform/getEventSource/browser.js +0 -4
- package/esm/platform/getEventSource/eventsource.js +0 -480
- package/esm/platform/getEventSource/node.js +0 -20
- package/esm/platform/getFetch/browser.js +0 -5
- package/esm/platform/getFetch/node.js +0 -22
- package/esm/platform/getOptions/node.js +0 -20
- package/esm/platform/node.js +0 -14
- package/esm/sdkClient/sdkLifecycle.js +0 -68
- package/esm/sdkClient/trackMethod.js +0 -52
- package/esm/services/authProvider.js +0 -63
- package/esm/services/secureSplitHttpClient.js +0 -35
- package/esm/services/serviceApi.js +0 -141
- package/esm/storages/AbstractDefinitionsCacheAsync.js +0 -48
- package/esm/storages/AbstractDefinitionsCacheSync.js +0 -71
- package/esm/storages/inLocalStorage/DefinitionsCacheInLocal.js +0 -191
- package/esm/storages/inMemory/DefinitionsCacheInMemory.js +0 -118
- package/esm/storages/pluggable/DefinitionsCachePluggable.js +0 -209
- package/esm/sync/polling/syncTasks/definitionsSyncTask.js +0 -9
- package/esm/utils/EventEmitter.js +0 -387
- package/esm/utils/filter/bloomFilter.js +0 -33
- package/esm/utils/inputValidation/definitionExistence.js +0 -15
- package/esm/utils/inputValidation/definitions.js +0 -21
- package/esm/utils/inputValidation/target.js +0 -18
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
import { authenticateFactory } from '../sync/streaming/AuthClient';
|
|
2
|
-
import { Backoff } from '../utils/Backoff';
|
|
3
|
-
import { LOG_PREFIX_SYNC_AUTH } from '../logger/constants';
|
|
4
|
-
import { TOKEN } from '../utils/constants';
|
|
5
|
-
var SKEW_SECONDS = 30;
|
|
6
|
-
function isExpired(credential) {
|
|
7
|
-
return Date.now() / 1000 + SKEW_SECONDS >= credential.decodedToken.exp;
|
|
8
|
-
}
|
|
9
|
-
/**
|
|
10
|
-
* Factory of AuthProvider, which provides JWT credentials for authenticated HTTP requests.
|
|
11
|
-
* Credentials are fetched lazily on demand, cached in memory, and retried with backoff on failure.
|
|
12
|
-
*/
|
|
13
|
-
export function authProviderFactory(settings, splitHttpClient, telemetryTracker) {
|
|
14
|
-
var urls = settings.urls, log = settings.log;
|
|
15
|
-
function fetchAuth() {
|
|
16
|
-
var url = "".concat(urls.auth, "/api/v3/auth?capabilities=config,aiconfig");
|
|
17
|
-
return splitHttpClient(url, undefined, telemetryTracker.trackHttp(TOKEN), false, true);
|
|
18
|
-
}
|
|
19
|
-
var authenticate = authenticateFactory(fetchAuth);
|
|
20
|
-
var backoff = new Backoff(fetchCredential);
|
|
21
|
-
var cachedCredential;
|
|
22
|
-
var inFlightPromise;
|
|
23
|
-
var stopped = false;
|
|
24
|
-
function fetchCredential() {
|
|
25
|
-
return authenticate().then(function (credential) {
|
|
26
|
-
log.info(LOG_PREFIX_SYNC_AUTH + 'credential fetched successfully');
|
|
27
|
-
cachedCredential = credential;
|
|
28
|
-
inFlightPromise = undefined;
|
|
29
|
-
backoff.reset();
|
|
30
|
-
return credential;
|
|
31
|
-
}).catch(function (error) {
|
|
32
|
-
// Avoid rejected promises and unnecessary retries after stop()
|
|
33
|
-
if (stopped)
|
|
34
|
-
return cachedCredential;
|
|
35
|
-
if (error.statusCode && error.statusCode >= 400 && error.statusCode < 500) {
|
|
36
|
-
log.error(LOG_PREFIX_SYNC_AUTH + 'non-retryable error fetching credential (status ' + error.statusCode + '): ' + error.message);
|
|
37
|
-
inFlightPromise = undefined;
|
|
38
|
-
throw error;
|
|
39
|
-
}
|
|
40
|
-
log.warn(LOG_PREFIX_SYNC_AUTH + 'credential fetch failed (attempt ' + (backoff.attempts + 1) + '). Error: ' + error.message);
|
|
41
|
-
return backoff.scheduleCallAsync();
|
|
42
|
-
});
|
|
43
|
-
}
|
|
44
|
-
return {
|
|
45
|
-
credential: function () {
|
|
46
|
-
if (cachedCredential && !isExpired(cachedCredential)) {
|
|
47
|
-
return Promise.resolve(cachedCredential);
|
|
48
|
-
}
|
|
49
|
-
if (cachedCredential)
|
|
50
|
-
log.debug(LOG_PREFIX_SYNC_AUTH + 'cached credential expired');
|
|
51
|
-
return inFlightPromise || (inFlightPromise = fetchCredential());
|
|
52
|
-
},
|
|
53
|
-
invalidate: function () {
|
|
54
|
-
cachedCredential = undefined;
|
|
55
|
-
},
|
|
56
|
-
stop: function () {
|
|
57
|
-
stopped = true;
|
|
58
|
-
cachedCredential = undefined;
|
|
59
|
-
inFlightPromise = undefined;
|
|
60
|
-
backoff.reset();
|
|
61
|
-
}
|
|
62
|
-
};
|
|
63
|
-
}
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { __assign } from "tslib";
|
|
2
|
-
import { splitHttpClientFactory } from './splitHttpClient';
|
|
3
|
-
import { authProviderFactory } from './authProvider';
|
|
4
|
-
/**
|
|
5
|
-
* Factory of Secure HTTP client, which authenticates requests using a JWT token.
|
|
6
|
-
* On 401 responses, invalidates the cached credential and retries once with a fresh token.
|
|
7
|
-
*
|
|
8
|
-
* @param settings - SDK settings
|
|
9
|
-
* @param platform - object containing environment-specific dependencies
|
|
10
|
-
* @param fetchAuth - function to fetch auth credentials from the /v2/auth endpoint
|
|
11
|
-
*/
|
|
12
|
-
export function secureSplitHttpClientFactory(settings, platform, telemetryTracker) {
|
|
13
|
-
var splitHttpClient = splitHttpClientFactory(settings, platform);
|
|
14
|
-
var authProvider = authProviderFactory(settings, splitHttpClient, telemetryTracker);
|
|
15
|
-
function makeRequest(url, options, latencyTracker, logErrorsAsInfo, token) {
|
|
16
|
-
return splitHttpClient(url, __assign(__assign({}, options), { headers: __assign(__assign({}, options === null || options === void 0 ? void 0 : options.headers), { Authorization: "Bearer ".concat(token) }) }), latencyTracker, logErrorsAsInfo, true);
|
|
17
|
-
}
|
|
18
|
-
var httpClient = function (url, options, latencyTracker, logErrorsAsInfo) {
|
|
19
|
-
return authProvider.credential().then(function (credential) {
|
|
20
|
-
return makeRequest(url, options, latencyTracker, logErrorsAsInfo, credential.token)
|
|
21
|
-
.catch(function (error) {
|
|
22
|
-
if (error.statusCode === 401) {
|
|
23
|
-
// retry once for 401, in case the token has just expired
|
|
24
|
-
authProvider.invalidate();
|
|
25
|
-
return authProvider.credential().then(function (newCredential) {
|
|
26
|
-
return makeRequest(url, options, latencyTracker, logErrorsAsInfo, newCredential.token);
|
|
27
|
-
});
|
|
28
|
-
}
|
|
29
|
-
throw error;
|
|
30
|
-
});
|
|
31
|
-
});
|
|
32
|
-
};
|
|
33
|
-
httpClient.stop = function () { return authProvider.stop(); };
|
|
34
|
-
return httpClient;
|
|
35
|
-
}
|
|
@@ -1,141 +0,0 @@
|
|
|
1
|
-
import { splitHttpClientFactory } from './splitHttpClient';
|
|
2
|
-
import { objectAssign } from '../utils/lang/objectAssign';
|
|
3
|
-
import { SPLITS, IMPRESSIONS, IMPRESSIONS_COUNT, EVENTS, TELEMETRY, TOKEN, SEGMENT, MEMBERSHIPS } from '../utils/constants';
|
|
4
|
-
import { ERROR_TOO_MANY_SETS } from '../logger/constants';
|
|
5
|
-
var noCacheHeaderOptions = { headers: { 'Cache-Control': 'no-cache' } };
|
|
6
|
-
function userKeyToQueryParam(userKey) {
|
|
7
|
-
return 'users=' + encodeURIComponent(userKey); // no need to check availability of `encodeURIComponent`, since it is a global highly supported.
|
|
8
|
-
}
|
|
9
|
-
/**
|
|
10
|
-
* Factory of ServiceApi objects, which group the collection of HTTP endpoints used by the SDKs
|
|
11
|
-
*
|
|
12
|
-
* @param settings - validated settings object
|
|
13
|
-
* @param platform - object containing environment-specific dependencies
|
|
14
|
-
* @param telemetryTracker - telemetry tracker
|
|
15
|
-
* @param secureSplitHttpClientFactory - factory of SecureSplitHttpClient objects
|
|
16
|
-
*/
|
|
17
|
-
export function serviceApiFactory(settings, platform, telemetryTracker, secureSplitHttpClientFactory) {
|
|
18
|
-
var urls = settings.urls;
|
|
19
|
-
var filterQueryString = settings.sync.__splitFiltersValidation && settings.sync.__splitFiltersValidation.queryString;
|
|
20
|
-
var SplitSDKImpressionsMode = settings.sync.impressionsMode;
|
|
21
|
-
var splitHttpClient = splitHttpClientFactory(settings, platform);
|
|
22
|
-
var secureSplitHttpClient = secureSplitHttpClientFactory(settings, platform, telemetryTracker);
|
|
23
|
-
return {
|
|
24
|
-
// @TODO throw errors if health check requests fail, to log them in the Synchronizer
|
|
25
|
-
getSdkAPIHealthCheck: function () {
|
|
26
|
-
var url = "".concat(urls.sdk, "/api/version");
|
|
27
|
-
return splitHttpClient(url).then(function () { return true; }).catch(function () { return false; });
|
|
28
|
-
},
|
|
29
|
-
getEventsAPIHealthCheck: function () {
|
|
30
|
-
var url = "".concat(urls.events, "/api/version");
|
|
31
|
-
return splitHttpClient(url).then(function () { return true; }).catch(function () { return false; });
|
|
32
|
-
},
|
|
33
|
-
fetchAuth: function (userMatchingKeys) {
|
|
34
|
-
var url = "".concat(urls.auth, "/api/v2/auth?s=").concat(settings.sync.flagSpecVersion);
|
|
35
|
-
if (userMatchingKeys) { // `userMatchingKeys` is undefined in server-side
|
|
36
|
-
var queryParams = userMatchingKeys.map(userKeyToQueryParam).join('&');
|
|
37
|
-
if (queryParams)
|
|
38
|
-
url += '&' + queryParams;
|
|
39
|
-
}
|
|
40
|
-
return splitHttpClient(url, undefined, telemetryTracker.trackHttp(TOKEN));
|
|
41
|
-
},
|
|
42
|
-
fetchSplitChanges: function (since, noCache, till, rbSince) {
|
|
43
|
-
var url = "".concat(urls.sdk, "/api/splitChanges?s=").concat(settings.sync.flagSpecVersion, "&since=").concat(since).concat(rbSince ? '&rbSince=' + rbSince : '').concat(filterQueryString || '').concat(till ? '&till=' + till : '');
|
|
44
|
-
return splitHttpClient(url, noCache ? noCacheHeaderOptions : undefined, telemetryTracker.trackHttp(SPLITS))
|
|
45
|
-
.catch(function (err) {
|
|
46
|
-
if (err.statusCode === 414)
|
|
47
|
-
settings.log.error(ERROR_TOO_MANY_SETS);
|
|
48
|
-
throw err;
|
|
49
|
-
});
|
|
50
|
-
},
|
|
51
|
-
fetchSegmentChanges: function (since, segmentName, noCache, till) {
|
|
52
|
-
var url = "".concat(urls.sdk, "/api/segmentChanges/").concat(segmentName, "?since=").concat(since).concat(till ? '&till=' + till : '');
|
|
53
|
-
return splitHttpClient(url, noCache ? noCacheHeaderOptions : undefined, telemetryTracker.trackHttp(SEGMENT));
|
|
54
|
-
},
|
|
55
|
-
// @TODO support filterQueryString and handle ERROR_TOO_MANY_SETS error
|
|
56
|
-
fetchConfigs: function (since, noCache, till, rbSince) {
|
|
57
|
-
var url = "".concat(urls.configs, "/api/v1/configs?since=").concat(since).concat(rbSince ? '&rbSince=' + rbSince : '').concat(filterQueryString || '').concat(till ? '&till=' + till : '');
|
|
58
|
-
return secureSplitHttpClient(url, noCache ? noCacheHeaderOptions : undefined);
|
|
59
|
-
},
|
|
60
|
-
fetchConfigsSegmentChanges: function (since, segmentName, noCache, till) {
|
|
61
|
-
var url = "".concat(urls.configs, "/api/v1/segmentChanges/").concat(segmentName, "?since=").concat(since).concat(till ? '&till=' + till : '');
|
|
62
|
-
return secureSplitHttpClient(url, noCache ? noCacheHeaderOptions : undefined);
|
|
63
|
-
},
|
|
64
|
-
fetchMemberships: function (userMatchingKey, noCache, till) {
|
|
65
|
-
/**
|
|
66
|
-
* URI encoding of user keys in order to:
|
|
67
|
-
* - avoid 400 responses (due to URI malformed). E.g.: '/api/memberships/%'
|
|
68
|
-
* - avoid 404 responses. E.g.: '/api/memberships/foo/bar'
|
|
69
|
-
* - match user keys with special characters. E.g.: 'foo%bar', 'foo/bar'
|
|
70
|
-
*/
|
|
71
|
-
var url = "".concat(urls.sdk, "/api/memberships/").concat(encodeURIComponent(userMatchingKey)).concat(till ? '?till=' + till : '');
|
|
72
|
-
return splitHttpClient(url, noCache ? noCacheHeaderOptions : undefined, telemetryTracker.trackHttp(MEMBERSHIPS));
|
|
73
|
-
},
|
|
74
|
-
/**
|
|
75
|
-
* Post events.
|
|
76
|
-
*
|
|
77
|
-
* @param body - Events bulk payload
|
|
78
|
-
* @param headers - Optionals headers to overwrite default ones. For example, it is used in producer mode to overwrite metadata headers.
|
|
79
|
-
*/
|
|
80
|
-
postEventsBulk: function (body, headers) {
|
|
81
|
-
var url = "".concat(urls.events, "/api/events/bulk");
|
|
82
|
-
return splitHttpClient(url, { method: 'POST', body: body, headers: headers }, telemetryTracker.trackHttp(EVENTS));
|
|
83
|
-
},
|
|
84
|
-
/**
|
|
85
|
-
* Post impressions.
|
|
86
|
-
*
|
|
87
|
-
* @param body - Impressions bulk payload
|
|
88
|
-
* @param headers - Optionals headers to overwrite default ones. For example, it is used in producer mode to overwrite metadata headers.
|
|
89
|
-
*/
|
|
90
|
-
postTestImpressionsBulk: function (body, headers) {
|
|
91
|
-
var url = "".concat(urls.events, "/api/testImpressions/bulk");
|
|
92
|
-
return splitHttpClient(url, {
|
|
93
|
-
// Adding extra headers to send impressions in OPTIMIZED or DEBUG modes.
|
|
94
|
-
method: 'POST',
|
|
95
|
-
body: body,
|
|
96
|
-
headers: objectAssign({ SplitSDKImpressionsMode: SplitSDKImpressionsMode }, headers)
|
|
97
|
-
}, telemetryTracker.trackHttp(IMPRESSIONS));
|
|
98
|
-
},
|
|
99
|
-
/**
|
|
100
|
-
* Post impressions counts.
|
|
101
|
-
*
|
|
102
|
-
* @param body - Impressions counts payload
|
|
103
|
-
* @param headers - Optionals headers to overwrite default ones. For example, it is used in producer mode to overwrite metadata headers.
|
|
104
|
-
*/
|
|
105
|
-
postTestImpressionsCount: function (body, headers) {
|
|
106
|
-
var url = "".concat(urls.events, "/api/testImpressions/count");
|
|
107
|
-
return splitHttpClient(url, { method: 'POST', body: body, headers: headers }, telemetryTracker.trackHttp(IMPRESSIONS_COUNT));
|
|
108
|
-
},
|
|
109
|
-
/**
|
|
110
|
-
* Post unique keys for client side.
|
|
111
|
-
*
|
|
112
|
-
* @param body - unique keys payload
|
|
113
|
-
* @param headers - Optionals headers to overwrite default ones. For example, it is used in producer mode to overwrite metadata headers.
|
|
114
|
-
*/
|
|
115
|
-
postUniqueKeysBulkCs: function (body, headers) {
|
|
116
|
-
var url = "".concat(urls.telemetry, "/api/v1/keys/cs");
|
|
117
|
-
return splitHttpClient(url, { method: 'POST', body: body, headers: headers }, telemetryTracker.trackHttp(TELEMETRY));
|
|
118
|
-
},
|
|
119
|
-
/**
|
|
120
|
-
* Post unique keys for server side.
|
|
121
|
-
*
|
|
122
|
-
* @param body - unique keys payload
|
|
123
|
-
* @param headers - Optionals headers to overwrite default ones. For example, it is used in producer mode to overwrite metadata headers.
|
|
124
|
-
*/
|
|
125
|
-
postUniqueKeysBulkSs: function (body, headers) {
|
|
126
|
-
var url = "".concat(urls.telemetry, "/api/v1/keys/ss");
|
|
127
|
-
return splitHttpClient(url, { method: 'POST', body: body, headers: headers }, telemetryTracker.trackHttp(TELEMETRY));
|
|
128
|
-
},
|
|
129
|
-
postMetricsConfig: function (body, headers) {
|
|
130
|
-
var url = "".concat(urls.telemetry, "/api/v1/metrics/config");
|
|
131
|
-
return splitHttpClient(url, { method: 'POST', body: body, headers: headers }, telemetryTracker.trackHttp(TELEMETRY), true);
|
|
132
|
-
},
|
|
133
|
-
postMetricsUsage: function (body, headers) {
|
|
134
|
-
var url = "".concat(urls.telemetry, "/api/v1/metrics/usage");
|
|
135
|
-
return splitHttpClient(url, { method: 'POST', body: body, headers: headers }, telemetryTracker.trackHttp(TELEMETRY), true);
|
|
136
|
-
},
|
|
137
|
-
stop: function () {
|
|
138
|
-
secureSplitHttpClient.stop();
|
|
139
|
-
}
|
|
140
|
-
};
|
|
141
|
-
}
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import { objectAssign } from '../utils/lang/objectAssign';
|
|
2
|
-
/**
|
|
3
|
-
* This class provides a skeletal implementation of the IDefinitionsCacheAsync interface
|
|
4
|
-
* to minimize the effort required to implement this interface.
|
|
5
|
-
*/
|
|
6
|
-
var AbstractDefinitionsCacheAsync = /** @class */ (function () {
|
|
7
|
-
function AbstractDefinitionsCacheAsync() {
|
|
8
|
-
}
|
|
9
|
-
AbstractDefinitionsCacheAsync.prototype.update = function (toAdd, toRemove, changeNumber) {
|
|
10
|
-
var _this = this;
|
|
11
|
-
return Promise.all([
|
|
12
|
-
this.setChangeNumber(changeNumber),
|
|
13
|
-
Promise.all(toAdd.map(function (addedFF) { return _this.add(addedFF); })),
|
|
14
|
-
Promise.all(toRemove.map(function (removedFF) { return _this.remove(removedFF); }))
|
|
15
|
-
]).then(function (_a) {
|
|
16
|
-
var added = _a[1], removed = _a[2];
|
|
17
|
-
return added.some(function (result) { return result; }) || removed.some(function (result) { return result; });
|
|
18
|
-
});
|
|
19
|
-
};
|
|
20
|
-
// @TODO revisit segment-related methods ('usesSegments', 'getRegisteredSegments', 'registerSegments')
|
|
21
|
-
// noop, just keeping the interface. This is used by standalone client-side API only, and so only implemented by InMemory and InLocalStorage.
|
|
22
|
-
AbstractDefinitionsCacheAsync.prototype.usesSegments = function () {
|
|
23
|
-
return Promise.resolve(true);
|
|
24
|
-
};
|
|
25
|
-
/**
|
|
26
|
-
* Kill `name` definition and set `defaultTreatment` and `changeNumber`.
|
|
27
|
-
* Used for SPLIT_KILL push notifications.
|
|
28
|
-
*
|
|
29
|
-
* @returns a promise that is resolved once the definition kill operation is performed. The fulfillment value is a boolean: `true` if the operation succeeded updating the definition or `false` if no definition is updated,
|
|
30
|
-
* for instance, if the `changeNumber` is old, or if the definition is not found (e.g., `/splitchanges` hasn't been fetched yet), or if the storage fails to apply the update.
|
|
31
|
-
* The promise will never be rejected.
|
|
32
|
-
*/
|
|
33
|
-
AbstractDefinitionsCacheAsync.prototype.killLocally = function (name, defaultTreatment, changeNumber) {
|
|
34
|
-
var _this = this;
|
|
35
|
-
return this.get(name).then(function (definition) {
|
|
36
|
-
if (definition && (!definition.changeNumber || definition.changeNumber < changeNumber)) {
|
|
37
|
-
var newDefinition = objectAssign({}, definition);
|
|
38
|
-
newDefinition.killed = true;
|
|
39
|
-
newDefinition.defaultTreatment = defaultTreatment;
|
|
40
|
-
newDefinition.changeNumber = changeNumber;
|
|
41
|
-
return _this.add(newDefinition);
|
|
42
|
-
}
|
|
43
|
-
return false;
|
|
44
|
-
}).catch(function () { return false; });
|
|
45
|
-
};
|
|
46
|
-
return AbstractDefinitionsCacheAsync;
|
|
47
|
-
}());
|
|
48
|
-
export { AbstractDefinitionsCacheAsync };
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
import { objectAssign } from '../utils/lang/objectAssign';
|
|
2
|
-
import { IN_SEGMENT, IN_LARGE_SEGMENT } from '../utils/constants';
|
|
3
|
-
/**
|
|
4
|
-
* This class provides a skeletal implementation of the IDefinitionsCacheSync interface
|
|
5
|
-
* to minimize the effort required to implement this interface.
|
|
6
|
-
*/
|
|
7
|
-
var AbstractDefinitionsCacheSync = /** @class */ (function () {
|
|
8
|
-
function AbstractDefinitionsCacheSync() {
|
|
9
|
-
}
|
|
10
|
-
AbstractDefinitionsCacheSync.prototype.update = function (toAdd, toRemove, changeNumber) {
|
|
11
|
-
var _this = this;
|
|
12
|
-
var updated = toAdd.map(function (addedFF) { return _this.add(addedFF); }).some(function (result) { return result; });
|
|
13
|
-
updated = toRemove.map(function (removedFF) { return _this.remove(removedFF); }).some(function (result) { return result; }) || updated;
|
|
14
|
-
this.setChangeNumber(changeNumber);
|
|
15
|
-
return updated;
|
|
16
|
-
};
|
|
17
|
-
AbstractDefinitionsCacheSync.prototype.getMany = function (names) {
|
|
18
|
-
var _this = this;
|
|
19
|
-
var definitions = {};
|
|
20
|
-
names.forEach(function (name) {
|
|
21
|
-
definitions[name] = _this.get(name);
|
|
22
|
-
});
|
|
23
|
-
return definitions;
|
|
24
|
-
};
|
|
25
|
-
AbstractDefinitionsCacheSync.prototype.getAll = function () {
|
|
26
|
-
var _this = this;
|
|
27
|
-
return this.getNames().map(function (key) { return _this.get(key); });
|
|
28
|
-
};
|
|
29
|
-
/**
|
|
30
|
-
* Kill `name` definition and set `defaultTreatment` and `changeNumber`.
|
|
31
|
-
* Used for SPLIT_KILL push notifications.
|
|
32
|
-
*
|
|
33
|
-
* @returns `true` if the operation successed updating the definition, or `false` if no definition is updated,
|
|
34
|
-
* for instance, if the `changeNumber` is old, or if the definition is not found (e.g., `/splitchanges` hasn't been fetched yet), or if the storage fails to apply the update.
|
|
35
|
-
*/
|
|
36
|
-
AbstractDefinitionsCacheSync.prototype.killLocally = function (name, defaultTreatment, changeNumber) {
|
|
37
|
-
var definition = this.get(name);
|
|
38
|
-
if (definition && (!definition.changeNumber || definition.changeNumber < changeNumber)) {
|
|
39
|
-
var newDefinition = objectAssign({}, definition);
|
|
40
|
-
newDefinition.killed = true;
|
|
41
|
-
newDefinition.defaultTreatment = defaultTreatment;
|
|
42
|
-
newDefinition.changeNumber = changeNumber;
|
|
43
|
-
return this.add(newDefinition);
|
|
44
|
-
}
|
|
45
|
-
return false;
|
|
46
|
-
};
|
|
47
|
-
return AbstractDefinitionsCacheSync;
|
|
48
|
-
}());
|
|
49
|
-
export { AbstractDefinitionsCacheSync };
|
|
50
|
-
/**
|
|
51
|
-
* Given a parsed definition, it returns a boolean flagging if its conditions use segments matchers (rules & whitelists).
|
|
52
|
-
* This util is intended to simplify the implementation of `definitionsCache::usesSegments` method
|
|
53
|
-
*/
|
|
54
|
-
export function usesSegments(ruleEntity) {
|
|
55
|
-
var conditions = ruleEntity.conditions || [];
|
|
56
|
-
for (var i = 0; i < conditions.length; i++) {
|
|
57
|
-
var matchers = conditions[i].matcherGroup.matchers;
|
|
58
|
-
for (var j = 0; j < matchers.length; j++) {
|
|
59
|
-
var matcher = matchers[j].matcherType;
|
|
60
|
-
if (matcher === IN_SEGMENT || matcher === IN_LARGE_SEGMENT)
|
|
61
|
-
return true;
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
var excluded = ruleEntity.excluded;
|
|
65
|
-
if (excluded && excluded.segments && excluded.segments.length > 0)
|
|
66
|
-
return true;
|
|
67
|
-
return false;
|
|
68
|
-
}
|
|
69
|
-
export function usesSegmentsSync(storage) {
|
|
70
|
-
return storage.definitions.usesSegments() || storage.rbSegments.usesSegments();
|
|
71
|
-
}
|
|
@@ -1,191 +0,0 @@
|
|
|
1
|
-
import { __extends } from "tslib";
|
|
2
|
-
import { AbstractDefinitionsCacheSync, usesSegments } from '../AbstractDefinitionsCacheSync';
|
|
3
|
-
import { isFiniteNumber, toNumber, isNaNNumber } from '../../utils/lang';
|
|
4
|
-
import { LOG_PREFIX } from './constants';
|
|
5
|
-
import { setToArray } from '../../utils/lang/sets';
|
|
6
|
-
var DefinitionsCacheInLocal = /** @class */ (function (_super) {
|
|
7
|
-
__extends(DefinitionsCacheInLocal, _super);
|
|
8
|
-
function DefinitionsCacheInLocal(settings, keys, storage) {
|
|
9
|
-
var _this = _super.call(this) || this;
|
|
10
|
-
_this.keys = keys;
|
|
11
|
-
_this.log = settings.log;
|
|
12
|
-
_this.setsFilter = settings.sync.__splitFiltersValidation.groupedFilters.bySet;
|
|
13
|
-
_this.storage = storage;
|
|
14
|
-
return _this;
|
|
15
|
-
}
|
|
16
|
-
DefinitionsCacheInLocal.prototype._decrementCount = function (key) {
|
|
17
|
-
var count = toNumber(this.storage.getItem(key)) - 1;
|
|
18
|
-
if (count > 0)
|
|
19
|
-
this.storage.setItem(key, count + '');
|
|
20
|
-
else
|
|
21
|
-
this.storage.removeItem(key);
|
|
22
|
-
};
|
|
23
|
-
DefinitionsCacheInLocal.prototype._decrementCounts = function (definition) {
|
|
24
|
-
try {
|
|
25
|
-
var ttKey = this.keys.buildTrafficTypeKey(definition.trafficTypeName);
|
|
26
|
-
this._decrementCount(ttKey);
|
|
27
|
-
if (usesSegments(definition)) {
|
|
28
|
-
var segmentsCountKey = this.keys.buildDefinitionsWithSegmentCountKey();
|
|
29
|
-
this._decrementCount(segmentsCountKey);
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
catch (e) {
|
|
33
|
-
this.log.error(LOG_PREFIX + e);
|
|
34
|
-
}
|
|
35
|
-
};
|
|
36
|
-
DefinitionsCacheInLocal.prototype._incrementCounts = function (definition) {
|
|
37
|
-
try {
|
|
38
|
-
var ttKey = this.keys.buildTrafficTypeKey(definition.trafficTypeName);
|
|
39
|
-
this.storage.setItem(ttKey, (toNumber(this.storage.getItem(ttKey)) + 1) + '');
|
|
40
|
-
if (usesSegments(definition)) {
|
|
41
|
-
var segmentsCountKey = this.keys.buildDefinitionsWithSegmentCountKey();
|
|
42
|
-
this.storage.setItem(segmentsCountKey, (toNumber(this.storage.getItem(segmentsCountKey)) + 1) + '');
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
catch (e) {
|
|
46
|
-
this.log.error(LOG_PREFIX + e);
|
|
47
|
-
}
|
|
48
|
-
};
|
|
49
|
-
/**
|
|
50
|
-
* Removes all definitions related data from localStorage (splits, counters, changeNumber and lastUpdated).
|
|
51
|
-
* We cannot simply call `localStorage.clear()` since that implies removing user items from the storage.
|
|
52
|
-
*/
|
|
53
|
-
DefinitionsCacheInLocal.prototype.clear = function () {
|
|
54
|
-
var _this = this;
|
|
55
|
-
// collect item keys
|
|
56
|
-
var len = this.storage.length;
|
|
57
|
-
var accum = [];
|
|
58
|
-
for (var cur = 0; cur < len; cur++) {
|
|
59
|
-
var key = this.storage.key(cur);
|
|
60
|
-
if (key != null && this.keys.isDefinitionsCacheKey(key))
|
|
61
|
-
accum.push(key);
|
|
62
|
-
}
|
|
63
|
-
// remove items
|
|
64
|
-
accum.forEach(function (key) {
|
|
65
|
-
_this.storage.removeItem(key);
|
|
66
|
-
});
|
|
67
|
-
this.hasSync = false;
|
|
68
|
-
};
|
|
69
|
-
DefinitionsCacheInLocal.prototype.add = function (definition) {
|
|
70
|
-
var name = definition.name;
|
|
71
|
-
var definitionKey = this.keys.buildDefinitionKey(name);
|
|
72
|
-
var definitionFromStorage = this.storage.getItem(definitionKey);
|
|
73
|
-
var previousDefinition = definitionFromStorage ? JSON.parse(definitionFromStorage) : null;
|
|
74
|
-
if (previousDefinition) {
|
|
75
|
-
this._decrementCounts(previousDefinition);
|
|
76
|
-
this.removeFromSets(previousDefinition.name, previousDefinition.sets);
|
|
77
|
-
}
|
|
78
|
-
this.storage.setItem(definitionKey, JSON.stringify(definition));
|
|
79
|
-
this._incrementCounts(definition);
|
|
80
|
-
this.addToSets(definition);
|
|
81
|
-
return true;
|
|
82
|
-
};
|
|
83
|
-
DefinitionsCacheInLocal.prototype.remove = function (name) {
|
|
84
|
-
var definition = this.get(name);
|
|
85
|
-
if (!definition)
|
|
86
|
-
return false;
|
|
87
|
-
this.storage.removeItem(this.keys.buildDefinitionKey(name));
|
|
88
|
-
this._decrementCounts(definition);
|
|
89
|
-
this.removeFromSets(definition.name, definition.sets);
|
|
90
|
-
return true;
|
|
91
|
-
};
|
|
92
|
-
DefinitionsCacheInLocal.prototype.get = function (name) {
|
|
93
|
-
var item = this.storage.getItem(this.keys.buildDefinitionKey(name));
|
|
94
|
-
return item && JSON.parse(item);
|
|
95
|
-
};
|
|
96
|
-
DefinitionsCacheInLocal.prototype.setChangeNumber = function (changeNumber) {
|
|
97
|
-
try {
|
|
98
|
-
this.storage.setItem(this.keys.buildDefinitionsTillKey(), changeNumber + '');
|
|
99
|
-
// update "last updated" timestamp with current time
|
|
100
|
-
this.storage.setItem(this.keys.buildLastUpdatedKey(), Date.now() + '');
|
|
101
|
-
this.hasSync = true;
|
|
102
|
-
return true;
|
|
103
|
-
}
|
|
104
|
-
catch (e) {
|
|
105
|
-
this.log.error(LOG_PREFIX + e);
|
|
106
|
-
return false;
|
|
107
|
-
}
|
|
108
|
-
};
|
|
109
|
-
DefinitionsCacheInLocal.prototype.getChangeNumber = function () {
|
|
110
|
-
var n = -1;
|
|
111
|
-
var value = this.storage.getItem(this.keys.buildDefinitionsTillKey());
|
|
112
|
-
if (value !== null) {
|
|
113
|
-
value = parseInt(value, 10);
|
|
114
|
-
return isNaNNumber(value) ? n : value;
|
|
115
|
-
}
|
|
116
|
-
return n;
|
|
117
|
-
};
|
|
118
|
-
DefinitionsCacheInLocal.prototype.getNames = function () {
|
|
119
|
-
var len = this.storage.length;
|
|
120
|
-
var accum = [];
|
|
121
|
-
var cur = 0;
|
|
122
|
-
while (cur < len) {
|
|
123
|
-
var key = this.storage.key(cur);
|
|
124
|
-
if (key != null && this.keys.isDefinitionKey(key))
|
|
125
|
-
accum.push(this.keys.extractKey(key));
|
|
126
|
-
cur++;
|
|
127
|
-
}
|
|
128
|
-
return accum;
|
|
129
|
-
};
|
|
130
|
-
DefinitionsCacheInLocal.prototype.trafficTypeExists = function (trafficType) {
|
|
131
|
-
var ttCount = toNumber(this.storage.getItem(this.keys.buildTrafficTypeKey(trafficType)));
|
|
132
|
-
return isFiniteNumber(ttCount) && ttCount > 0;
|
|
133
|
-
};
|
|
134
|
-
DefinitionsCacheInLocal.prototype.usesSegments = function () {
|
|
135
|
-
// If cache hasn't been synchronized with the cloud, assume we need them.
|
|
136
|
-
if (!this.hasSync)
|
|
137
|
-
return true;
|
|
138
|
-
var storedCount = this.storage.getItem(this.keys.buildDefinitionsWithSegmentCountKey());
|
|
139
|
-
var definitionsWithSegmentsCount = storedCount === null ? 0 : toNumber(storedCount);
|
|
140
|
-
return isFiniteNumber(definitionsWithSegmentsCount) ?
|
|
141
|
-
definitionsWithSegmentsCount > 0 :
|
|
142
|
-
true;
|
|
143
|
-
};
|
|
144
|
-
DefinitionsCacheInLocal.prototype.getNamesBySets = function (sets) {
|
|
145
|
-
var _this = this;
|
|
146
|
-
return sets.map(function (set) {
|
|
147
|
-
var setKey = _this.keys.buildSetKey(set);
|
|
148
|
-
var setFromStorage = _this.storage.getItem(setKey);
|
|
149
|
-
return new Set(setFromStorage ? JSON.parse(setFromStorage) : []);
|
|
150
|
-
});
|
|
151
|
-
};
|
|
152
|
-
DefinitionsCacheInLocal.prototype.addToSets = function (definition) {
|
|
153
|
-
var _this = this;
|
|
154
|
-
if (!definition.sets)
|
|
155
|
-
return;
|
|
156
|
-
definition.sets.forEach(function (set) {
|
|
157
|
-
if (_this.setsFilter.length > 0 && !_this.setsFilter.some(function (filterSet) { return filterSet === set; }))
|
|
158
|
-
return;
|
|
159
|
-
var setKey = _this.keys.buildSetKey(set);
|
|
160
|
-
var setFromStorage = _this.storage.getItem(setKey);
|
|
161
|
-
var setCache = new Set(setFromStorage ? JSON.parse(setFromStorage) : []);
|
|
162
|
-
if (setCache.has(definition.name))
|
|
163
|
-
return;
|
|
164
|
-
setCache.add(definition.name);
|
|
165
|
-
_this.storage.setItem(setKey, JSON.stringify(setToArray(setCache)));
|
|
166
|
-
});
|
|
167
|
-
};
|
|
168
|
-
DefinitionsCacheInLocal.prototype.removeFromSets = function (definitionName, sets) {
|
|
169
|
-
var _this = this;
|
|
170
|
-
if (!sets)
|
|
171
|
-
return;
|
|
172
|
-
sets.forEach(function (set) {
|
|
173
|
-
_this.removeNames(set, definitionName);
|
|
174
|
-
});
|
|
175
|
-
};
|
|
176
|
-
DefinitionsCacheInLocal.prototype.removeNames = function (setName, definitionName) {
|
|
177
|
-
var setKey = this.keys.buildSetKey(setName);
|
|
178
|
-
var setFromStorage = this.storage.getItem(setKey);
|
|
179
|
-
if (!setFromStorage)
|
|
180
|
-
return;
|
|
181
|
-
var setCache = new Set(JSON.parse(setFromStorage));
|
|
182
|
-
setCache.delete(definitionName);
|
|
183
|
-
if (setCache.size === 0) {
|
|
184
|
-
this.storage.removeItem(setKey);
|
|
185
|
-
return;
|
|
186
|
-
}
|
|
187
|
-
this.storage.setItem(setKey, JSON.stringify(setToArray(setCache)));
|
|
188
|
-
};
|
|
189
|
-
return DefinitionsCacheInLocal;
|
|
190
|
-
}(AbstractDefinitionsCacheSync));
|
|
191
|
-
export { DefinitionsCacheInLocal };
|
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
import { __extends } from "tslib";
|
|
2
|
-
import { AbstractDefinitionsCacheSync, usesSegments } from '../AbstractDefinitionsCacheSync';
|
|
3
|
-
import { isFiniteNumber } from '../../utils/lang';
|
|
4
|
-
/**
|
|
5
|
-
* Default IDefinitionsCacheSync implementation that stores split definitions in memory.
|
|
6
|
-
*/
|
|
7
|
-
var DefinitionsCacheInMemory = /** @class */ (function (_super) {
|
|
8
|
-
__extends(DefinitionsCacheInMemory, _super);
|
|
9
|
-
function DefinitionsCacheInMemory(splitFiltersValidation) {
|
|
10
|
-
var _this = _super.call(this) || this;
|
|
11
|
-
_this.definitionsCache = {};
|
|
12
|
-
_this.ttCache = {};
|
|
13
|
-
_this.changeNumber = -1;
|
|
14
|
-
_this.segmentsCount = 0;
|
|
15
|
-
_this.setsCache = {};
|
|
16
|
-
_this.setsFilter = splitFiltersValidation ? splitFiltersValidation.groupedFilters.bySet : [];
|
|
17
|
-
return _this;
|
|
18
|
-
}
|
|
19
|
-
DefinitionsCacheInMemory.prototype.clear = function () {
|
|
20
|
-
this.definitionsCache = {};
|
|
21
|
-
this.ttCache = {};
|
|
22
|
-
this.changeNumber = -1;
|
|
23
|
-
this.segmentsCount = 0;
|
|
24
|
-
this.setsCache = {};
|
|
25
|
-
};
|
|
26
|
-
DefinitionsCacheInMemory.prototype.add = function (definition) {
|
|
27
|
-
var name = definition.name;
|
|
28
|
-
var previousDefinition = this.get(name);
|
|
29
|
-
if (previousDefinition) { // We had this Split already
|
|
30
|
-
var previousTtName = previousDefinition.trafficTypeName;
|
|
31
|
-
this.ttCache[previousTtName]--;
|
|
32
|
-
if (!this.ttCache[previousTtName])
|
|
33
|
-
delete this.ttCache[previousTtName];
|
|
34
|
-
this.removeFromFlagSets(previousDefinition.name, previousDefinition.sets);
|
|
35
|
-
// Subtract from segments count for the previous version of this Split
|
|
36
|
-
if (usesSegments(previousDefinition))
|
|
37
|
-
this.segmentsCount--;
|
|
38
|
-
}
|
|
39
|
-
// Store the Split.
|
|
40
|
-
this.definitionsCache[name] = definition;
|
|
41
|
-
// Update TT cache
|
|
42
|
-
var ttName = definition.trafficTypeName;
|
|
43
|
-
this.ttCache[ttName] = (this.ttCache[ttName] || 0) + 1;
|
|
44
|
-
this.addToFlagSets(definition);
|
|
45
|
-
// Add to segments count for the new version of the Split
|
|
46
|
-
if (usesSegments(definition))
|
|
47
|
-
this.segmentsCount++;
|
|
48
|
-
return true;
|
|
49
|
-
};
|
|
50
|
-
DefinitionsCacheInMemory.prototype.remove = function (name) {
|
|
51
|
-
var definition = this.get(name);
|
|
52
|
-
if (!definition)
|
|
53
|
-
return false;
|
|
54
|
-
// Delete the Split
|
|
55
|
-
delete this.definitionsCache[name];
|
|
56
|
-
var ttName = definition.trafficTypeName;
|
|
57
|
-
this.ttCache[ttName]--; // Update tt cache
|
|
58
|
-
if (!this.ttCache[ttName])
|
|
59
|
-
delete this.ttCache[ttName];
|
|
60
|
-
this.removeFromFlagSets(definition.name, definition.sets);
|
|
61
|
-
// Update the segments count.
|
|
62
|
-
if (usesSegments(definition))
|
|
63
|
-
this.segmentsCount--;
|
|
64
|
-
return true;
|
|
65
|
-
};
|
|
66
|
-
DefinitionsCacheInMemory.prototype.get = function (name) {
|
|
67
|
-
return this.definitionsCache[name] || null;
|
|
68
|
-
};
|
|
69
|
-
DefinitionsCacheInMemory.prototype.setChangeNumber = function (changeNumber) {
|
|
70
|
-
this.changeNumber = changeNumber;
|
|
71
|
-
return true;
|
|
72
|
-
};
|
|
73
|
-
DefinitionsCacheInMemory.prototype.getChangeNumber = function () {
|
|
74
|
-
return this.changeNumber;
|
|
75
|
-
};
|
|
76
|
-
DefinitionsCacheInMemory.prototype.getNames = function () {
|
|
77
|
-
return Object.keys(this.definitionsCache);
|
|
78
|
-
};
|
|
79
|
-
DefinitionsCacheInMemory.prototype.trafficTypeExists = function (trafficType) {
|
|
80
|
-
return isFiniteNumber(this.ttCache[trafficType]) && this.ttCache[trafficType] > 0;
|
|
81
|
-
};
|
|
82
|
-
DefinitionsCacheInMemory.prototype.usesSegments = function () {
|
|
83
|
-
return this.getChangeNumber() === -1 || this.segmentsCount > 0;
|
|
84
|
-
};
|
|
85
|
-
DefinitionsCacheInMemory.prototype.getNamesBySets = function (sets) {
|
|
86
|
-
var _this = this;
|
|
87
|
-
return sets.map(function (set) { return _this.setsCache[set] || new Set(); });
|
|
88
|
-
};
|
|
89
|
-
DefinitionsCacheInMemory.prototype.addToFlagSets = function (featureFlag) {
|
|
90
|
-
var _this = this;
|
|
91
|
-
if (!featureFlag.sets)
|
|
92
|
-
return;
|
|
93
|
-
featureFlag.sets.forEach(function (featureFlagSet) {
|
|
94
|
-
if (_this.setsFilter.length > 0 && !_this.setsFilter.some(function (filterFlagSet) { return filterFlagSet === featureFlagSet; }))
|
|
95
|
-
return;
|
|
96
|
-
if (!_this.setsCache[featureFlagSet])
|
|
97
|
-
_this.setsCache[featureFlagSet] = new Set([]);
|
|
98
|
-
_this.setsCache[featureFlagSet].add(featureFlag.name);
|
|
99
|
-
});
|
|
100
|
-
};
|
|
101
|
-
DefinitionsCacheInMemory.prototype.removeFromFlagSets = function (featureFlagName, sets) {
|
|
102
|
-
var _this = this;
|
|
103
|
-
if (!sets)
|
|
104
|
-
return;
|
|
105
|
-
sets.forEach(function (set) {
|
|
106
|
-
_this.removeNames(set, featureFlagName);
|
|
107
|
-
});
|
|
108
|
-
};
|
|
109
|
-
DefinitionsCacheInMemory.prototype.removeNames = function (setName, featureFlagName) {
|
|
110
|
-
if (!this.setsCache[setName])
|
|
111
|
-
return;
|
|
112
|
-
this.setsCache[setName].delete(featureFlagName);
|
|
113
|
-
if (this.setsCache[setName].size === 0)
|
|
114
|
-
delete this.setsCache[setName];
|
|
115
|
-
};
|
|
116
|
-
return DefinitionsCacheInMemory;
|
|
117
|
-
}(AbstractDefinitionsCacheSync));
|
|
118
|
-
export { DefinitionsCacheInMemory };
|