@splitsoftware/splitio-commons 2.2.1-rc.3 → 2.2.1-rc.5
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/README.md +1 -0
- package/cjs/consent/sdkUserConsent.js +5 -3
- package/cjs/evaluator/combiners/and.js +2 -6
- package/cjs/evaluator/combiners/ifelseif.js +6 -6
- package/cjs/evaluator/condition/index.js +6 -5
- package/cjs/evaluator/index.js +7 -7
- package/cjs/evaluator/matchers/index.js +3 -1
- package/cjs/evaluator/matchers/matcherTypes.js +1 -0
- package/cjs/evaluator/matchers/rbsegment.js +56 -0
- package/cjs/evaluator/matchersTransform/index.js +4 -0
- package/cjs/evaluator/parser/index.js +2 -2
- package/cjs/evaluator/value/sanitize.js +1 -0
- package/cjs/listeners/browser.js +2 -5
- package/cjs/logger/constants.js +4 -3
- package/cjs/logger/messages/debug.js +3 -2
- package/cjs/logger/messages/warn.js +1 -1
- package/cjs/services/splitApi.js +3 -4
- package/cjs/services/splitHttpClient.js +3 -1
- package/cjs/storages/AbstractSplitsCacheSync.js +5 -2
- package/cjs/storages/KeyBuilder.js +9 -0
- package/cjs/storages/KeyBuilderCS.js +3 -0
- package/cjs/storages/KeyBuilderSS.js +3 -0
- package/cjs/storages/inLocalStorage/RBSegmentsCacheInLocal.js +117 -0
- package/cjs/storages/inLocalStorage/SplitsCacheInLocal.js +9 -14
- package/cjs/storages/inLocalStorage/index.js +5 -1
- package/cjs/storages/inLocalStorage/validateCache.js +2 -1
- package/cjs/storages/inMemory/InMemoryStorage.js +3 -0
- package/cjs/storages/inMemory/InMemoryStorageCS.js +4 -0
- package/cjs/storages/inMemory/RBSegmentsCacheInMemory.js +61 -0
- package/cjs/storages/inMemory/SplitsCacheInMemory.js +1 -0
- package/cjs/storages/inRedis/RBSegmentsCacheInRedis.js +64 -0
- package/cjs/storages/inRedis/index.js +5 -3
- package/cjs/storages/pluggable/RBSegmentsCachePluggable.js +64 -0
- package/cjs/storages/pluggable/index.js +2 -0
- package/cjs/sync/polling/fetchers/splitChangesFetcher.js +54 -4
- package/cjs/sync/polling/pollingManagerCS.js +7 -7
- package/cjs/sync/polling/syncTasks/splitsSyncTask.js +1 -1
- package/cjs/sync/polling/updaters/mySegmentsUpdater.js +2 -2
- package/cjs/sync/polling/updaters/segmentChangesUpdater.js +1 -1
- package/cjs/sync/polling/updaters/splitChangesUpdater.js +59 -33
- package/cjs/sync/streaming/SSEHandler/index.js +1 -0
- package/cjs/sync/streaming/UpdateWorkers/SplitsUpdateWorker.js +106 -77
- package/cjs/sync/streaming/constants.js +2 -1
- package/cjs/sync/streaming/pushManager.js +3 -16
- package/cjs/sync/syncManagerOnline.js +2 -2
- package/cjs/utils/constants/index.js +6 -2
- package/esm/consent/sdkUserConsent.js +5 -3
- package/esm/evaluator/combiners/and.js +2 -6
- package/esm/evaluator/combiners/ifelseif.js +7 -7
- package/esm/evaluator/condition/index.js +6 -5
- package/esm/evaluator/index.js +7 -7
- package/esm/evaluator/matchers/index.js +3 -1
- package/esm/evaluator/matchers/matcherTypes.js +1 -0
- package/esm/evaluator/matchers/rbsegment.js +52 -0
- package/esm/evaluator/matchersTransform/index.js +4 -0
- package/esm/evaluator/parser/index.js +2 -2
- package/esm/evaluator/value/sanitize.js +1 -0
- package/esm/listeners/browser.js +2 -5
- package/esm/logger/constants.js +1 -0
- package/esm/logger/messages/debug.js +3 -2
- package/esm/logger/messages/warn.js +1 -1
- package/esm/services/splitApi.js +3 -4
- package/esm/services/splitHttpClient.js +3 -1
- package/esm/storages/AbstractSplitsCacheSync.js +5 -2
- package/esm/storages/KeyBuilder.js +9 -0
- package/esm/storages/KeyBuilderCS.js +3 -0
- package/esm/storages/KeyBuilderSS.js +3 -0
- package/esm/storages/inLocalStorage/RBSegmentsCacheInLocal.js +114 -0
- package/esm/storages/inLocalStorage/SplitsCacheInLocal.js +9 -14
- package/esm/storages/inLocalStorage/index.js +5 -1
- package/esm/storages/inLocalStorage/validateCache.js +2 -1
- package/esm/storages/inMemory/InMemoryStorage.js +3 -0
- package/esm/storages/inMemory/InMemoryStorageCS.js +4 -0
- package/esm/storages/inMemory/RBSegmentsCacheInMemory.js +58 -0
- package/esm/storages/inMemory/SplitsCacheInMemory.js +1 -0
- package/esm/storages/inRedis/RBSegmentsCacheInRedis.js +61 -0
- package/esm/storages/inRedis/index.js +5 -3
- package/esm/storages/pluggable/RBSegmentsCachePluggable.js +61 -0
- package/esm/storages/pluggable/index.js +2 -0
- package/esm/sync/polling/fetchers/splitChangesFetcher.js +54 -4
- package/esm/sync/polling/pollingManagerCS.js +7 -7
- package/esm/sync/polling/syncTasks/splitsSyncTask.js +1 -1
- package/esm/sync/polling/updaters/mySegmentsUpdater.js +2 -2
- package/esm/sync/polling/updaters/segmentChangesUpdater.js +1 -1
- package/esm/sync/polling/updaters/splitChangesUpdater.js +59 -33
- package/esm/sync/streaming/SSEHandler/index.js +2 -1
- package/esm/sync/streaming/UpdateWorkers/SplitsUpdateWorker.js +102 -73
- package/esm/sync/streaming/constants.js +1 -0
- package/esm/sync/streaming/pushManager.js +6 -19
- package/esm/sync/syncManagerOnline.js +2 -2
- package/esm/utils/constants/index.js +5 -1
- package/package.json +1 -1
- package/src/consent/sdkUserConsent.ts +3 -2
- package/src/dtos/types.ts +37 -8
- package/src/evaluator/Engine.ts +1 -1
- package/src/evaluator/combiners/and.ts +5 -4
- package/src/evaluator/combiners/ifelseif.ts +7 -9
- package/src/evaluator/condition/engineUtils.ts +1 -1
- package/src/evaluator/condition/index.ts +12 -12
- package/src/evaluator/index.ts +7 -7
- package/src/evaluator/matchers/index.ts +3 -1
- package/src/evaluator/matchers/matcherTypes.ts +1 -0
- package/src/evaluator/matchers/rbsegment.ts +74 -0
- package/src/evaluator/matchersTransform/index.ts +3 -0
- package/src/evaluator/parser/index.ts +3 -3
- package/src/evaluator/types.ts +2 -2
- package/src/evaluator/value/index.ts +2 -2
- package/src/evaluator/value/sanitize.ts +5 -4
- package/src/listeners/browser.ts +2 -3
- package/src/logger/constants.ts +1 -0
- package/src/logger/messages/debug.ts +3 -2
- package/src/logger/messages/warn.ts +1 -1
- package/src/sdkManager/index.ts +1 -1
- package/src/services/splitApi.ts +3 -4
- package/src/services/splitHttpClient.ts +3 -1
- package/src/services/types.ts +1 -1
- package/src/storages/AbstractSplitsCacheSync.ts +6 -3
- package/src/storages/KeyBuilder.ts +12 -0
- package/src/storages/KeyBuilderCS.ts +4 -0
- package/src/storages/KeyBuilderSS.ts +4 -0
- package/src/storages/inLocalStorage/RBSegmentsCacheInLocal.ts +136 -0
- package/src/storages/inLocalStorage/SplitsCacheInLocal.ts +10 -14
- package/src/storages/inLocalStorage/index.ts +5 -1
- package/src/storages/inLocalStorage/validateCache.ts +3 -1
- package/src/storages/inMemory/InMemoryStorage.ts +3 -0
- package/src/storages/inMemory/InMemoryStorageCS.ts +4 -0
- package/src/storages/inMemory/RBSegmentsCacheInMemory.ts +68 -0
- package/src/storages/inMemory/SplitsCacheInMemory.ts +1 -0
- package/src/storages/inRedis/RBSegmentsCacheInRedis.ts +79 -0
- package/src/storages/inRedis/index.ts +5 -3
- package/src/storages/pluggable/RBSegmentsCachePluggable.ts +76 -0
- package/src/storages/pluggable/index.ts +2 -0
- package/src/storages/types.ts +33 -1
- package/src/sync/polling/fetchers/splitChangesFetcher.ts +65 -4
- package/src/sync/polling/fetchers/types.ts +1 -0
- package/src/sync/polling/pollingManagerCS.ts +7 -7
- package/src/sync/polling/syncTasks/splitsSyncTask.ts +1 -1
- package/src/sync/polling/types.ts +2 -2
- package/src/sync/polling/updaters/mySegmentsUpdater.ts +2 -2
- package/src/sync/polling/updaters/segmentChangesUpdater.ts +1 -1
- package/src/sync/polling/updaters/splitChangesUpdater.ts +70 -43
- package/src/sync/streaming/SSEHandler/index.ts +2 -1
- package/src/sync/streaming/SSEHandler/types.ts +2 -2
- package/src/sync/streaming/UpdateWorkers/SplitsUpdateWorker.ts +98 -68
- package/src/sync/streaming/constants.ts +1 -0
- package/src/sync/streaming/parseUtils.ts +2 -2
- package/src/sync/streaming/pushManager.ts +6 -18
- package/src/sync/streaming/types.ts +3 -2
- package/src/sync/syncManagerOnline.ts +2 -2
- package/src/utils/constants/index.ts +6 -1
- package/src/utils/lang/index.ts +1 -1
|
@@ -21,6 +21,7 @@ import { greaterThanEqualToSemverMatcherContext } from './semver_gte';
|
|
|
21
21
|
import { lessThanEqualToSemverMatcherContext } from './semver_lte';
|
|
22
22
|
import { betweenSemverMatcherContext } from './semver_between';
|
|
23
23
|
import { inListSemverMatcherContext } from './semver_inlist';
|
|
24
|
+
import { ruleBasedSegmentMatcherContext } from './rbsegment';
|
|
24
25
|
var matchers = [
|
|
25
26
|
undefined,
|
|
26
27
|
allMatcherContext,
|
|
@@ -45,7 +46,8 @@ var matchers = [
|
|
|
45
46
|
lessThanEqualToSemverMatcherContext,
|
|
46
47
|
betweenSemverMatcherContext,
|
|
47
48
|
inListSemverMatcherContext,
|
|
48
|
-
largeSegmentMatcherContext,
|
|
49
|
+
largeSegmentMatcherContext,
|
|
50
|
+
ruleBasedSegmentMatcherContext // IN_RULE_BASED_SEGMENT: 24
|
|
49
51
|
];
|
|
50
52
|
/**
|
|
51
53
|
* Matcher factory.
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { thenable } from '../../utils/promise/thenable';
|
|
2
|
+
import { getMatching, keyParser } from '../../utils/key';
|
|
3
|
+
import { parser } from '../parser';
|
|
4
|
+
import { STANDARD_SEGMENT, RULE_BASED_SEGMENT, LARGE_SEGMENT } from '../../utils/constants';
|
|
5
|
+
export function ruleBasedSegmentMatcherContext(segmentName, storage, log) {
|
|
6
|
+
return function ruleBasedSegmentMatcher(_a, splitEvaluator) {
|
|
7
|
+
var key = _a.key, attributes = _a.attributes;
|
|
8
|
+
var matchingKey = getMatching(key);
|
|
9
|
+
function matchConditions(rbsegment) {
|
|
10
|
+
var conditions = rbsegment.conditions || [];
|
|
11
|
+
if (!conditions.length)
|
|
12
|
+
return false;
|
|
13
|
+
var evaluator = parser(log, conditions, storage);
|
|
14
|
+
var evaluation = evaluator(keyParser(key), undefined, undefined, undefined, attributes, splitEvaluator);
|
|
15
|
+
return thenable(evaluation) ?
|
|
16
|
+
evaluation.then(function (evaluation) { return evaluation ? true : false; }) :
|
|
17
|
+
evaluation ? true : false;
|
|
18
|
+
}
|
|
19
|
+
function isInExcludedSegment(_a) {
|
|
20
|
+
var type = _a.type, name = _a.name;
|
|
21
|
+
return type === STANDARD_SEGMENT ?
|
|
22
|
+
storage.segments.isInSegment(name, matchingKey) :
|
|
23
|
+
type === RULE_BASED_SEGMENT ?
|
|
24
|
+
ruleBasedSegmentMatcherContext(name, storage, log)({ key: key, attributes: attributes }, splitEvaluator) :
|
|
25
|
+
type === LARGE_SEGMENT && storage.largeSegments ?
|
|
26
|
+
storage.largeSegments.isInSegment(name, matchingKey) :
|
|
27
|
+
false;
|
|
28
|
+
}
|
|
29
|
+
function isExcluded(rbSegment) {
|
|
30
|
+
var excluded = rbSegment.excluded || {};
|
|
31
|
+
if (excluded.keys && excluded.keys.indexOf(matchingKey) !== -1)
|
|
32
|
+
return true;
|
|
33
|
+
return (excluded.segments || []).reduce(function (result, excludedSegment) {
|
|
34
|
+
return thenable(result) ?
|
|
35
|
+
result.then(function (result) { return result || isInExcludedSegment(excludedSegment); }) :
|
|
36
|
+
result || isInExcludedSegment(excludedSegment);
|
|
37
|
+
}, false);
|
|
38
|
+
}
|
|
39
|
+
function isInRBSegment(rbSegment) {
|
|
40
|
+
if (!rbSegment)
|
|
41
|
+
return false;
|
|
42
|
+
var excluded = isExcluded(rbSegment);
|
|
43
|
+
return thenable(excluded) ?
|
|
44
|
+
excluded.then(function (excluded) { return excluded ? false : matchConditions(rbSegment); }) :
|
|
45
|
+
excluded ? false : matchConditions(rbSegment);
|
|
46
|
+
}
|
|
47
|
+
var rbSegment = storage.rbSegments.get(segmentName);
|
|
48
|
+
return thenable(rbSegment) ?
|
|
49
|
+
rbSegment.then(isInRBSegment) :
|
|
50
|
+
isInRBSegment(rbSegment);
|
|
51
|
+
};
|
|
52
|
+
}
|
|
@@ -78,6 +78,10 @@ export function matchersTransform(matchers) {
|
|
|
78
78
|
type === matcherTypes.LESS_THAN_OR_EQUAL_TO_SEMVER) {
|
|
79
79
|
value = stringMatcherData;
|
|
80
80
|
}
|
|
81
|
+
else if (type === matcherTypes.IN_RULE_BASED_SEGMENT) {
|
|
82
|
+
value = segmentTransform(userDefinedSegmentMatcherData);
|
|
83
|
+
dataType = matcherDataTypes.NOT_SPECIFIED;
|
|
84
|
+
}
|
|
81
85
|
return {
|
|
82
86
|
attribute: attribute,
|
|
83
87
|
negate: negate,
|
|
@@ -50,8 +50,8 @@ export function parser(log, conditions, storage) {
|
|
|
50
50
|
// and break the loop
|
|
51
51
|
break;
|
|
52
52
|
}
|
|
53
|
-
predicates.push(conditionContext(log, andCombinerContext(log, expressions), Treatments.parse(partitions), label, conditionType));
|
|
53
|
+
predicates.push(conditionContext(log, andCombinerContext(log, expressions), partitions && Treatments.parse(partitions), label, conditionType));
|
|
54
54
|
}
|
|
55
|
-
//
|
|
55
|
+
// Instantiate evaluator given the set of conditions using if else if logic
|
|
56
56
|
return ifElseIfCombinerContext(log, predicates);
|
|
57
57
|
}
|
|
@@ -49,6 +49,7 @@ function getProcessingFunction(matcherTypeID, dataType) {
|
|
|
49
49
|
case matcherTypes.BETWEEN:
|
|
50
50
|
return dataType === 'DATETIME' ? zeroSinceSS : undefined;
|
|
51
51
|
case matcherTypes.IN_SPLIT_TREATMENT:
|
|
52
|
+
case matcherTypes.IN_RULE_BASED_SEGMENT:
|
|
52
53
|
return dependencyProcessor;
|
|
53
54
|
default:
|
|
54
55
|
return undefined;
|
package/esm/listeners/browser.js
CHANGED
|
@@ -65,11 +65,8 @@ var BrowserSignalListener = /** @class */ (function () {
|
|
|
65
65
|
};
|
|
66
66
|
this._flushData(events + '/testImpressions/beacon', this.storage.impressions, this.serviceApi.postTestImpressionsBulk, this.fromImpressionsCollector, extraMetadata);
|
|
67
67
|
this._flushData(events + '/events/beacon', this.storage.events, this.serviceApi.postEventsBulk);
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
// @ts-ignore
|
|
71
|
-
if (this.storage.uniqueKeys)
|
|
72
|
-
this._flushData(telemetry + '/v1/keys/cs/beacon', this.storage.uniqueKeys, this.serviceApi.postUniqueKeysBulkCs);
|
|
68
|
+
this._flushData(events + '/testImpressions/count/beacon', this.storage.impressionCounts, this.serviceApi.postTestImpressionsCount, fromImpressionCountsCollector);
|
|
69
|
+
this._flushData(telemetry + '/v1/keys/cs/beacon', this.storage.uniqueKeys, this.serviceApi.postUniqueKeysBulkCs);
|
|
73
70
|
}
|
|
74
71
|
// Flush telemetry data
|
|
75
72
|
if (this.storage.telemetry)
|
package/esm/logger/constants.js
CHANGED
|
@@ -21,6 +21,7 @@ export var RETRIEVE_MANAGER = 29;
|
|
|
21
21
|
export var SYNC_OFFLINE_DATA = 30;
|
|
22
22
|
export var SYNC_SPLITS_FETCH = 31;
|
|
23
23
|
export var SYNC_SPLITS_UPDATE = 32;
|
|
24
|
+
export var SYNC_RBS_UPDATE = 33;
|
|
24
25
|
export var STREAMING_NEW_MESSAGE = 35;
|
|
25
26
|
export var SYNC_TASK_START = 36;
|
|
26
27
|
export var SYNC_TASK_EXECUTE = 37;
|
|
@@ -19,8 +19,9 @@ export var codesDebug = codesInfo.concat([
|
|
|
19
19
|
[c.RETRIEVE_MANAGER, 'Retrieving manager instance.'],
|
|
20
20
|
// synchronizer
|
|
21
21
|
[c.SYNC_OFFLINE_DATA, c.LOG_PREFIX_SYNC_OFFLINE + 'Feature flags data: \n%s'],
|
|
22
|
-
[c.SYNC_SPLITS_FETCH, c.LOG_PREFIX_SYNC_SPLITS + 'Spin up feature flags update using since = %s'],
|
|
23
|
-
[c.SYNC_SPLITS_UPDATE, c.LOG_PREFIX_SYNC_SPLITS + 'New feature flags %s. Removed feature flags %s.
|
|
22
|
+
[c.SYNC_SPLITS_FETCH, c.LOG_PREFIX_SYNC_SPLITS + 'Spin up feature flags update using since = %s and rbSince = %s.'],
|
|
23
|
+
[c.SYNC_SPLITS_UPDATE, c.LOG_PREFIX_SYNC_SPLITS + 'New feature flags %s. Removed feature flags %s.'],
|
|
24
|
+
[c.SYNC_RBS_UPDATE, c.LOG_PREFIX_SYNC_SPLITS + 'New rule-based segments %s. Removed rule-based segments %s.'],
|
|
24
25
|
[c.STREAMING_NEW_MESSAGE, c.LOG_PREFIX_SYNC_STREAMING + 'New SSE message received, with data: %s.'],
|
|
25
26
|
[c.SYNC_TASK_START, c.LOG_PREFIX_SYNC + ': Starting %s. Running each %s millis'],
|
|
26
27
|
[c.SYNC_TASK_EXECUTE, c.LOG_PREFIX_SYNC + ': Running %s'],
|
|
@@ -31,7 +31,7 @@ export var codesWarn = codesError.concat([
|
|
|
31
31
|
[c.WARN_SPLITS_FILTER_EMPTY, c.LOG_PREFIX_SETTINGS + ': feature flag filter configuration must be a non-empty array of filter objects.'],
|
|
32
32
|
[c.WARN_SDK_KEY, c.LOG_PREFIX_SETTINGS + ': You already have %s. We recommend keeping only one instance of the factory at all times (Singleton pattern) and reusing it throughout your application'],
|
|
33
33
|
[c.STREAMING_PARSING_MEMBERSHIPS_UPDATE, c.LOG_PREFIX_SYNC_STREAMING + 'Fetching Memberships due to an error processing %s notification: %s'],
|
|
34
|
-
[c.STREAMING_PARSING_SPLIT_UPDATE, c.LOG_PREFIX_SYNC_STREAMING + 'Fetching SplitChanges due to an error processing
|
|
34
|
+
[c.STREAMING_PARSING_SPLIT_UPDATE, c.LOG_PREFIX_SYNC_STREAMING + 'Fetching SplitChanges due to an error processing %s notification: %s'],
|
|
35
35
|
[c.WARN_INVALID_FLAGSET, '%s: you passed %s, flag set must adhere to the regular expressions %s. This means a flag set must start with a letter or number, be in lowercase, alphanumeric and have a max length of 50 characters. %s was discarded.'],
|
|
36
36
|
[c.WARN_LOWERCASE_FLAGSET, '%s: flag set %s should be all lowercase - converting string to lowercase.'],
|
|
37
37
|
[c.WARN_FLAGSET_WITHOUT_FLAGS, '%s: you passed %s flag set that does not contain cached feature flag names. Please double check what flag sets are in use in the Split user interface.'],
|
package/esm/services/splitApi.js
CHANGED
|
@@ -17,7 +17,6 @@ export function splitApiFactory(settings, platform, telemetryTracker) {
|
|
|
17
17
|
var urls = settings.urls;
|
|
18
18
|
var filterQueryString = settings.sync.__splitFiltersValidation && settings.sync.__splitFiltersValidation.queryString;
|
|
19
19
|
var SplitSDKImpressionsMode = settings.sync.impressionsMode;
|
|
20
|
-
var flagSpecVersion = settings.sync.flagSpecVersion;
|
|
21
20
|
var splitHttpClient = splitHttpClientFactory(settings, platform);
|
|
22
21
|
return {
|
|
23
22
|
// @TODO throw errors if health check requests fail, to log them in the Synchronizer
|
|
@@ -30,7 +29,7 @@ export function splitApiFactory(settings, platform, telemetryTracker) {
|
|
|
30
29
|
return splitHttpClient(url).then(function () { return true; }).catch(function () { return false; });
|
|
31
30
|
},
|
|
32
31
|
fetchAuth: function (userMatchingKeys) {
|
|
33
|
-
var url = urls.auth + "/v2/auth?s=" + flagSpecVersion;
|
|
32
|
+
var url = urls.auth + "/v2/auth?s=" + settings.sync.flagSpecVersion;
|
|
34
33
|
if (userMatchingKeys) { // `userMatchingKeys` is undefined in server-side
|
|
35
34
|
var queryParams = userMatchingKeys.map(userKeyToQueryParam).join('&');
|
|
36
35
|
if (queryParams)
|
|
@@ -38,8 +37,8 @@ export function splitApiFactory(settings, platform, telemetryTracker) {
|
|
|
38
37
|
}
|
|
39
38
|
return splitHttpClient(url, undefined, telemetryTracker.trackHttp(TOKEN));
|
|
40
39
|
},
|
|
41
|
-
fetchSplitChanges: function (since, noCache, till) {
|
|
42
|
-
var url = urls.sdk + "/splitChanges?s=" + flagSpecVersion + "&since=" + since + (filterQueryString || '') + (till ? '&till=' + till : '');
|
|
40
|
+
fetchSplitChanges: function (since, noCache, till, rbSince) {
|
|
41
|
+
var url = urls.sdk + "/splitChanges?s=" + settings.sync.flagSpecVersion + "&since=" + since + (rbSince ? '&rbSince=' + rbSince : '') + (filterQueryString || '') + (till ? '&till=' + till : '');
|
|
43
42
|
return splitHttpClient(url, noCache ? noCacheHeaderOptions : undefined, telemetryTracker.trackHttp(SPLITS))
|
|
44
43
|
.catch(function (err) {
|
|
45
44
|
if (err.statusCode === 414)
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { objectAssign } from '../utils/lang/objectAssign';
|
|
2
2
|
import { ERROR_HTTP, ERROR_CLIENT_CANNOT_GET_READY } from '../logger/constants';
|
|
3
3
|
import { decorateHeaders, removeNonISO88591 } from './decorateHeaders';
|
|
4
|
+
import { timeout } from '../utils/promise/timeout';
|
|
4
5
|
var messageNoFetch = 'Global fetch API is not available.';
|
|
5
6
|
/**
|
|
6
7
|
* Factory of Split HTTP clients, which are HTTP clients with predefined headers for Split endpoints.
|
|
@@ -40,7 +41,8 @@ export function splitHttpClientFactory(settings, _a) {
|
|
|
40
41
|
// https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch#Checking_that_the_fetch_was_successful
|
|
41
42
|
.then(function (response) {
|
|
42
43
|
if (!response.ok) {
|
|
43
|
-
|
|
44
|
+
// timeout after 100ms because `text()` promise doesn't settle in some implementations and cases (e.g. no content)
|
|
45
|
+
return timeout(100, response.text()).then(function (message) { return Promise.reject({ response: response, message: message }); }, function () { return Promise.reject({ response: response }); });
|
|
44
46
|
}
|
|
45
47
|
latencyTracker();
|
|
46
48
|
return response;
|
|
@@ -50,8 +50,8 @@ export { AbstractSplitsCacheSync };
|
|
|
50
50
|
* Given a parsed split, it returns a boolean flagging if its conditions use segments matchers (rules & whitelists).
|
|
51
51
|
* This util is intended to simplify the implementation of `splitsCache::usesSegments` method
|
|
52
52
|
*/
|
|
53
|
-
export function usesSegments(
|
|
54
|
-
var conditions =
|
|
53
|
+
export function usesSegments(ruleEntity) {
|
|
54
|
+
var conditions = ruleEntity.conditions || [];
|
|
55
55
|
for (var i = 0; i < conditions.length; i++) {
|
|
56
56
|
var matchers = conditions[i].matcherGroup.matchers;
|
|
57
57
|
for (var j = 0; j < matchers.length; j++) {
|
|
@@ -60,5 +60,8 @@ export function usesSegments(split) {
|
|
|
60
60
|
return true;
|
|
61
61
|
}
|
|
62
62
|
}
|
|
63
|
+
var excluded = ruleEntity.excluded;
|
|
64
|
+
if (excluded && excluded.segments && excluded.segments.length > 0)
|
|
65
|
+
return true;
|
|
63
66
|
return false;
|
|
64
67
|
}
|
|
@@ -24,6 +24,15 @@ var KeyBuilder = /** @class */ (function () {
|
|
|
24
24
|
KeyBuilder.prototype.buildSplitKeyPrefix = function () {
|
|
25
25
|
return this.prefix + ".split.";
|
|
26
26
|
};
|
|
27
|
+
KeyBuilder.prototype.buildRBSegmentKey = function (rbsegmentName) {
|
|
28
|
+
return this.prefix + ".rbsegment." + rbsegmentName;
|
|
29
|
+
};
|
|
30
|
+
KeyBuilder.prototype.buildRBSegmentsTillKey = function () {
|
|
31
|
+
return this.prefix + ".rbsegments.till";
|
|
32
|
+
};
|
|
33
|
+
KeyBuilder.prototype.buildRBSegmentKeyPrefix = function () {
|
|
34
|
+
return this.prefix + ".rbsegment.";
|
|
35
|
+
};
|
|
27
36
|
KeyBuilder.prototype.buildSegmentNameKey = function (segmentName) {
|
|
28
37
|
return this.prefix + ".segment." + segmentName;
|
|
29
38
|
};
|
|
@@ -32,6 +32,9 @@ var KeyBuilderCS = /** @class */ (function (_super) {
|
|
|
32
32
|
KeyBuilderCS.prototype.isSplitKey = function (key) {
|
|
33
33
|
return startsWith(key, this.prefix + ".split.");
|
|
34
34
|
};
|
|
35
|
+
KeyBuilderCS.prototype.isRBSegmentKey = function (key) {
|
|
36
|
+
return startsWith(key, this.prefix + ".rbsegment.");
|
|
37
|
+
};
|
|
35
38
|
KeyBuilderCS.prototype.buildSplitsWithSegmentCountKey = function () {
|
|
36
39
|
return this.prefix + ".splits.usingSegments";
|
|
37
40
|
};
|
|
@@ -39,6 +39,9 @@ var KeyBuilderSS = /** @class */ (function (_super) {
|
|
|
39
39
|
KeyBuilderSS.prototype.searchPatternForSplitKeys = function () {
|
|
40
40
|
return this.buildSplitKeyPrefix() + "*";
|
|
41
41
|
};
|
|
42
|
+
KeyBuilderSS.prototype.searchPatternForRBSegmentKeys = function () {
|
|
43
|
+
return this.buildRBSegmentKeyPrefix() + "*";
|
|
44
|
+
};
|
|
42
45
|
/* Telemetry keys */
|
|
43
46
|
KeyBuilderSS.prototype.buildLatencyKey = function (method, bucket) {
|
|
44
47
|
return this.latencyPrefix + "::" + this.versionablePrefix + "/" + METHOD_NAMES[method] + "/" + bucket;
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { isFiniteNumber, isNaNNumber, toNumber } from '../../utils/lang';
|
|
2
|
+
import { setToArray } from '../../utils/lang/sets';
|
|
3
|
+
import { usesSegments } from '../AbstractSplitsCacheSync';
|
|
4
|
+
import { LOG_PREFIX } from './constants';
|
|
5
|
+
var RBSegmentsCacheInLocal = /** @class */ (function () {
|
|
6
|
+
function RBSegmentsCacheInLocal(settings, keys) {
|
|
7
|
+
this.keys = keys;
|
|
8
|
+
this.log = settings.log;
|
|
9
|
+
}
|
|
10
|
+
RBSegmentsCacheInLocal.prototype.clear = function () {
|
|
11
|
+
var _this = this;
|
|
12
|
+
this.getNames().forEach(function (name) { return _this.remove(name); });
|
|
13
|
+
localStorage.removeItem(this.keys.buildRBSegmentsTillKey());
|
|
14
|
+
};
|
|
15
|
+
RBSegmentsCacheInLocal.prototype.update = function (toAdd, toRemove, changeNumber) {
|
|
16
|
+
var _this = this;
|
|
17
|
+
this.setChangeNumber(changeNumber);
|
|
18
|
+
var updated = toAdd.map(function (toAdd) { return _this.add(toAdd); }).some(function (result) { return result; });
|
|
19
|
+
return toRemove.map(function (toRemove) { return _this.remove(toRemove.name); }).some(function (result) { return result; }) || updated;
|
|
20
|
+
};
|
|
21
|
+
RBSegmentsCacheInLocal.prototype.setChangeNumber = function (changeNumber) {
|
|
22
|
+
try {
|
|
23
|
+
localStorage.setItem(this.keys.buildRBSegmentsTillKey(), changeNumber + '');
|
|
24
|
+
localStorage.setItem(this.keys.buildLastUpdatedKey(), Date.now() + '');
|
|
25
|
+
}
|
|
26
|
+
catch (e) {
|
|
27
|
+
this.log.error(LOG_PREFIX + e);
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
RBSegmentsCacheInLocal.prototype.updateSegmentCount = function (diff) {
|
|
31
|
+
var segmentsCountKey = this.keys.buildSplitsWithSegmentCountKey();
|
|
32
|
+
var count = toNumber(localStorage.getItem(segmentsCountKey)) + diff;
|
|
33
|
+
// @ts-expect-error
|
|
34
|
+
if (count > 0)
|
|
35
|
+
localStorage.setItem(segmentsCountKey, count);
|
|
36
|
+
else
|
|
37
|
+
localStorage.removeItem(segmentsCountKey);
|
|
38
|
+
};
|
|
39
|
+
RBSegmentsCacheInLocal.prototype.add = function (rbSegment) {
|
|
40
|
+
try {
|
|
41
|
+
var name_1 = rbSegment.name;
|
|
42
|
+
var rbSegmentKey = this.keys.buildRBSegmentKey(name_1);
|
|
43
|
+
var rbSegmentFromLocalStorage = localStorage.getItem(rbSegmentKey);
|
|
44
|
+
var previous = rbSegmentFromLocalStorage ? JSON.parse(rbSegmentFromLocalStorage) : null;
|
|
45
|
+
localStorage.setItem(rbSegmentKey, JSON.stringify(rbSegment));
|
|
46
|
+
var usesSegmentsDiff = 0;
|
|
47
|
+
if (previous && usesSegments(previous))
|
|
48
|
+
usesSegmentsDiff--;
|
|
49
|
+
if (usesSegments(rbSegment))
|
|
50
|
+
usesSegmentsDiff++;
|
|
51
|
+
if (usesSegmentsDiff !== 0)
|
|
52
|
+
this.updateSegmentCount(usesSegmentsDiff);
|
|
53
|
+
return true;
|
|
54
|
+
}
|
|
55
|
+
catch (e) {
|
|
56
|
+
this.log.error(LOG_PREFIX + e);
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
RBSegmentsCacheInLocal.prototype.remove = function (name) {
|
|
61
|
+
try {
|
|
62
|
+
var rbSegment = this.get(name);
|
|
63
|
+
if (!rbSegment)
|
|
64
|
+
return false;
|
|
65
|
+
localStorage.removeItem(this.keys.buildRBSegmentKey(name));
|
|
66
|
+
if (usesSegments(rbSegment))
|
|
67
|
+
this.updateSegmentCount(-1);
|
|
68
|
+
return true;
|
|
69
|
+
}
|
|
70
|
+
catch (e) {
|
|
71
|
+
this.log.error(LOG_PREFIX + e);
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
RBSegmentsCacheInLocal.prototype.getNames = function () {
|
|
76
|
+
var len = localStorage.length;
|
|
77
|
+
var accum = [];
|
|
78
|
+
var cur = 0;
|
|
79
|
+
while (cur < len) {
|
|
80
|
+
var key = localStorage.key(cur);
|
|
81
|
+
if (key != null && this.keys.isRBSegmentKey(key))
|
|
82
|
+
accum.push(this.keys.extractKey(key));
|
|
83
|
+
cur++;
|
|
84
|
+
}
|
|
85
|
+
return accum;
|
|
86
|
+
};
|
|
87
|
+
RBSegmentsCacheInLocal.prototype.get = function (name) {
|
|
88
|
+
var item = localStorage.getItem(this.keys.buildRBSegmentKey(name));
|
|
89
|
+
return item && JSON.parse(item);
|
|
90
|
+
};
|
|
91
|
+
RBSegmentsCacheInLocal.prototype.contains = function (names) {
|
|
92
|
+
var namesArray = setToArray(names);
|
|
93
|
+
var namesInStorage = this.getNames();
|
|
94
|
+
return namesArray.every(function (name) { return namesInStorage.indexOf(name) !== -1; });
|
|
95
|
+
};
|
|
96
|
+
RBSegmentsCacheInLocal.prototype.getChangeNumber = function () {
|
|
97
|
+
var n = -1;
|
|
98
|
+
var value = localStorage.getItem(this.keys.buildRBSegmentsTillKey());
|
|
99
|
+
if (value !== null) {
|
|
100
|
+
value = parseInt(value, 10);
|
|
101
|
+
return isNaNNumber(value) ? n : value;
|
|
102
|
+
}
|
|
103
|
+
return n;
|
|
104
|
+
};
|
|
105
|
+
RBSegmentsCacheInLocal.prototype.usesSegments = function () {
|
|
106
|
+
var storedCount = localStorage.getItem(this.keys.buildSplitsWithSegmentCountKey());
|
|
107
|
+
var splitsWithSegmentsCount = storedCount === null ? 0 : toNumber(storedCount);
|
|
108
|
+
return isFiniteNumber(splitsWithSegmentsCount) ?
|
|
109
|
+
splitsWithSegmentsCount > 0 :
|
|
110
|
+
true;
|
|
111
|
+
};
|
|
112
|
+
return RBSegmentsCacheInLocal;
|
|
113
|
+
}());
|
|
114
|
+
export { RBSegmentsCacheInLocal };
|
|
@@ -38,15 +38,13 @@ var SplitsCacheInLocal = /** @class */ (function (_super) {
|
|
|
38
38
|
};
|
|
39
39
|
SplitsCacheInLocal.prototype._incrementCounts = function (split) {
|
|
40
40
|
try {
|
|
41
|
-
|
|
42
|
-
|
|
41
|
+
var ttKey = this.keys.buildTrafficTypeKey(split.trafficTypeName);
|
|
42
|
+
// @ts-expect-error
|
|
43
|
+
localStorage.setItem(ttKey, toNumber(localStorage.getItem(ttKey)) + 1);
|
|
44
|
+
if (usesSegments(split)) {
|
|
45
|
+
var segmentsCountKey = this.keys.buildSplitsWithSegmentCountKey();
|
|
43
46
|
// @ts-expect-error
|
|
44
|
-
localStorage.setItem(
|
|
45
|
-
if (usesSegments(split)) {
|
|
46
|
-
var segmentsCountKey = this.keys.buildSplitsWithSegmentCountKey();
|
|
47
|
-
// @ts-expect-error
|
|
48
|
-
localStorage.setItem(segmentsCountKey, toNumber(localStorage.getItem(segmentsCountKey)) + 1);
|
|
49
|
-
}
|
|
47
|
+
localStorage.setItem(segmentsCountKey, toNumber(localStorage.getItem(segmentsCountKey)) + 1);
|
|
50
48
|
}
|
|
51
49
|
}
|
|
52
50
|
catch (e) {
|
|
@@ -155,12 +153,9 @@ var SplitsCacheInLocal = /** @class */ (function (_super) {
|
|
|
155
153
|
return true;
|
|
156
154
|
var storedCount = localStorage.getItem(this.keys.buildSplitsWithSegmentCountKey());
|
|
157
155
|
var splitsWithSegmentsCount = storedCount === null ? 0 : toNumber(storedCount);
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
else {
|
|
162
|
-
return true;
|
|
163
|
-
}
|
|
156
|
+
return isFiniteNumber(splitsWithSegmentsCount) ?
|
|
157
|
+
splitsWithSegmentsCount > 0 :
|
|
158
|
+
true;
|
|
164
159
|
};
|
|
165
160
|
SplitsCacheInLocal.prototype.getNamesByFlagSets = function (flagSets) {
|
|
166
161
|
var _this = this;
|
|
@@ -5,6 +5,7 @@ import { validatePrefix } from '../KeyBuilder';
|
|
|
5
5
|
import { KeyBuilderCS, myLargeSegmentsKeyBuilder } from '../KeyBuilderCS';
|
|
6
6
|
import { isLocalStorageAvailable } from '../../utils/env/isLocalStorageAvailable';
|
|
7
7
|
import { SplitsCacheInLocal } from './SplitsCacheInLocal';
|
|
8
|
+
import { RBSegmentsCacheInLocal } from './RBSegmentsCacheInLocal';
|
|
8
9
|
import { MySegmentsCacheInLocal } from './MySegmentsCacheInLocal';
|
|
9
10
|
import { InMemoryStorageCSFactory } from '../inMemory/InMemoryStorageCS';
|
|
10
11
|
import { LOG_PREFIX } from './constants';
|
|
@@ -29,10 +30,12 @@ export function InLocalStorage(options) {
|
|
|
29
30
|
var matchingKey = getMatching(settings.core.key);
|
|
30
31
|
var keys = new KeyBuilderCS(prefix, matchingKey);
|
|
31
32
|
var splits = new SplitsCacheInLocal(settings, keys);
|
|
33
|
+
var rbSegments = new RBSegmentsCacheInLocal(settings, keys);
|
|
32
34
|
var segments = new MySegmentsCacheInLocal(log, keys);
|
|
33
35
|
var largeSegments = new MySegmentsCacheInLocal(log, myLargeSegmentsKeyBuilder(prefix, matchingKey));
|
|
34
36
|
return {
|
|
35
37
|
splits: splits,
|
|
38
|
+
rbSegments: rbSegments,
|
|
36
39
|
segments: segments,
|
|
37
40
|
largeSegments: largeSegments,
|
|
38
41
|
impressions: new ImpressionsCacheInMemory(impressionsQueueSize),
|
|
@@ -41,13 +44,14 @@ export function InLocalStorage(options) {
|
|
|
41
44
|
telemetry: shouldRecordTelemetry(params) ? new TelemetryCacheInMemory(splits, segments) : undefined,
|
|
42
45
|
uniqueKeys: new UniqueKeysCacheInMemoryCS(),
|
|
43
46
|
validateCache: function () {
|
|
44
|
-
return validateCache(options, settings, keys, splits, segments, largeSegments);
|
|
47
|
+
return validateCache(options, settings, keys, splits, rbSegments, segments, largeSegments);
|
|
45
48
|
},
|
|
46
49
|
destroy: function () { },
|
|
47
50
|
// When using shared instantiation with MEMORY we reuse everything but segments (they are customer per key).
|
|
48
51
|
shared: function (matchingKey) {
|
|
49
52
|
return {
|
|
50
53
|
splits: this.splits,
|
|
54
|
+
rbSegments: this.rbSegments,
|
|
51
55
|
segments: new MySegmentsCacheInLocal(log, new KeyBuilderCS(prefix, matchingKey)),
|
|
52
56
|
largeSegments: new MySegmentsCacheInLocal(log, myLargeSegmentsKeyBuilder(prefix, matchingKey)),
|
|
53
57
|
impressions: this.impressions,
|
|
@@ -54,11 +54,12 @@ function validateExpiration(options, settings, keys, currentTimestamp, isThereCa
|
|
|
54
54
|
*
|
|
55
55
|
* @returns `true` if cache is ready to be used, `false` otherwise (cache was cleared or there is no cache)
|
|
56
56
|
*/
|
|
57
|
-
export function validateCache(options, settings, keys, splits, segments, largeSegments) {
|
|
57
|
+
export function validateCache(options, settings, keys, splits, rbSegments, segments, largeSegments) {
|
|
58
58
|
var currentTimestamp = Date.now();
|
|
59
59
|
var isThereCache = splits.getChangeNumber() > -1;
|
|
60
60
|
if (validateExpiration(options, settings, keys, currentTimestamp, isThereCache)) {
|
|
61
61
|
splits.clear();
|
|
62
|
+
rbSegments.clear();
|
|
62
63
|
segments.clear();
|
|
63
64
|
largeSegments.clear();
|
|
64
65
|
// Update last clear timestamp
|
|
@@ -6,6 +6,7 @@ import { ImpressionCountsCacheInMemory } from './ImpressionCountsCacheInMemory';
|
|
|
6
6
|
import { LOCALHOST_MODE, STORAGE_MEMORY } from '../../utils/constants';
|
|
7
7
|
import { shouldRecordTelemetry, TelemetryCacheInMemory } from './TelemetryCacheInMemory';
|
|
8
8
|
import { UniqueKeysCacheInMemory } from './UniqueKeysCacheInMemory';
|
|
9
|
+
import { RBSegmentsCacheInMemory } from './RBSegmentsCacheInMemory';
|
|
9
10
|
/**
|
|
10
11
|
* InMemory storage factory for standalone server-side SplitFactory
|
|
11
12
|
*
|
|
@@ -14,9 +15,11 @@ import { UniqueKeysCacheInMemory } from './UniqueKeysCacheInMemory';
|
|
|
14
15
|
export function InMemoryStorageFactory(params) {
|
|
15
16
|
var _a = params.settings, _b = _a.scheduler, impressionsQueueSize = _b.impressionsQueueSize, eventsQueueSize = _b.eventsQueueSize, __splitFiltersValidation = _a.sync.__splitFiltersValidation;
|
|
16
17
|
var splits = new SplitsCacheInMemory(__splitFiltersValidation);
|
|
18
|
+
var rbSegments = new RBSegmentsCacheInMemory();
|
|
17
19
|
var segments = new SegmentsCacheInMemory();
|
|
18
20
|
var storage = {
|
|
19
21
|
splits: splits,
|
|
22
|
+
rbSegments: rbSegments,
|
|
20
23
|
segments: segments,
|
|
21
24
|
impressions: new ImpressionsCacheInMemory(impressionsQueueSize),
|
|
22
25
|
impressionCounts: new ImpressionCountsCacheInMemory(),
|
|
@@ -6,6 +6,7 @@ import { ImpressionCountsCacheInMemory } from './ImpressionCountsCacheInMemory';
|
|
|
6
6
|
import { LOCALHOST_MODE, STORAGE_MEMORY } from '../../utils/constants';
|
|
7
7
|
import { shouldRecordTelemetry, TelemetryCacheInMemory } from './TelemetryCacheInMemory';
|
|
8
8
|
import { UniqueKeysCacheInMemoryCS } from './UniqueKeysCacheInMemoryCS';
|
|
9
|
+
import { RBSegmentsCacheInMemory } from './RBSegmentsCacheInMemory';
|
|
9
10
|
/**
|
|
10
11
|
* InMemory storage factory for standalone client-side SplitFactory
|
|
11
12
|
*
|
|
@@ -14,10 +15,12 @@ import { UniqueKeysCacheInMemoryCS } from './UniqueKeysCacheInMemoryCS';
|
|
|
14
15
|
export function InMemoryStorageCSFactory(params) {
|
|
15
16
|
var _a = params.settings, _b = _a.scheduler, impressionsQueueSize = _b.impressionsQueueSize, eventsQueueSize = _b.eventsQueueSize, __splitFiltersValidation = _a.sync.__splitFiltersValidation;
|
|
16
17
|
var splits = new SplitsCacheInMemory(__splitFiltersValidation);
|
|
18
|
+
var rbSegments = new RBSegmentsCacheInMemory();
|
|
17
19
|
var segments = new MySegmentsCacheInMemory();
|
|
18
20
|
var largeSegments = new MySegmentsCacheInMemory();
|
|
19
21
|
var storage = {
|
|
20
22
|
splits: splits,
|
|
23
|
+
rbSegments: rbSegments,
|
|
21
24
|
segments: segments,
|
|
22
25
|
largeSegments: largeSegments,
|
|
23
26
|
impressions: new ImpressionsCacheInMemory(impressionsQueueSize),
|
|
@@ -30,6 +33,7 @@ export function InMemoryStorageCSFactory(params) {
|
|
|
30
33
|
shared: function () {
|
|
31
34
|
return {
|
|
32
35
|
splits: this.splits,
|
|
36
|
+
rbSegments: this.rbSegments,
|
|
33
37
|
segments: new MySegmentsCacheInMemory(),
|
|
34
38
|
largeSegments: new MySegmentsCacheInMemory(),
|
|
35
39
|
impressions: this.impressions,
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { setToArray } from '../../utils/lang/sets';
|
|
2
|
+
import { usesSegments } from '../AbstractSplitsCacheSync';
|
|
3
|
+
var RBSegmentsCacheInMemory = /** @class */ (function () {
|
|
4
|
+
function RBSegmentsCacheInMemory() {
|
|
5
|
+
this.cache = {};
|
|
6
|
+
this.changeNumber = -1;
|
|
7
|
+
this.segmentsCount = 0;
|
|
8
|
+
}
|
|
9
|
+
RBSegmentsCacheInMemory.prototype.clear = function () {
|
|
10
|
+
this.cache = {};
|
|
11
|
+
this.changeNumber = -1;
|
|
12
|
+
this.segmentsCount = 0;
|
|
13
|
+
};
|
|
14
|
+
RBSegmentsCacheInMemory.prototype.update = function (toAdd, toRemove, changeNumber) {
|
|
15
|
+
var _this = this;
|
|
16
|
+
this.changeNumber = changeNumber;
|
|
17
|
+
var updated = toAdd.map(function (toAdd) { return _this.add(toAdd); }).some(function (result) { return result; });
|
|
18
|
+
return toRemove.map(function (toRemove) { return _this.remove(toRemove.name); }).some(function (result) { return result; }) || updated;
|
|
19
|
+
};
|
|
20
|
+
RBSegmentsCacheInMemory.prototype.add = function (rbSegment) {
|
|
21
|
+
var name = rbSegment.name;
|
|
22
|
+
var previous = this.get(name);
|
|
23
|
+
if (previous && usesSegments(previous))
|
|
24
|
+
this.segmentsCount--;
|
|
25
|
+
this.cache[name] = rbSegment;
|
|
26
|
+
if (usesSegments(rbSegment))
|
|
27
|
+
this.segmentsCount++;
|
|
28
|
+
return true;
|
|
29
|
+
};
|
|
30
|
+
RBSegmentsCacheInMemory.prototype.remove = function (name) {
|
|
31
|
+
var rbSegment = this.get(name);
|
|
32
|
+
if (!rbSegment)
|
|
33
|
+
return false;
|
|
34
|
+
delete this.cache[name];
|
|
35
|
+
if (usesSegments(rbSegment))
|
|
36
|
+
this.segmentsCount--;
|
|
37
|
+
return true;
|
|
38
|
+
};
|
|
39
|
+
RBSegmentsCacheInMemory.prototype.getNames = function () {
|
|
40
|
+
return Object.keys(this.cache);
|
|
41
|
+
};
|
|
42
|
+
RBSegmentsCacheInMemory.prototype.get = function (name) {
|
|
43
|
+
return this.cache[name] || null;
|
|
44
|
+
};
|
|
45
|
+
RBSegmentsCacheInMemory.prototype.contains = function (names) {
|
|
46
|
+
var namesArray = setToArray(names);
|
|
47
|
+
var namesInStorage = this.getNames();
|
|
48
|
+
return namesArray.every(function (name) { return namesInStorage.indexOf(name) !== -1; });
|
|
49
|
+
};
|
|
50
|
+
RBSegmentsCacheInMemory.prototype.getChangeNumber = function () {
|
|
51
|
+
return this.changeNumber;
|
|
52
|
+
};
|
|
53
|
+
RBSegmentsCacheInMemory.prototype.usesSegments = function () {
|
|
54
|
+
return this.segmentsCount > 0;
|
|
55
|
+
};
|
|
56
|
+
return RBSegmentsCacheInMemory;
|
|
57
|
+
}());
|
|
58
|
+
export { RBSegmentsCacheInMemory };
|