@splitsoftware/splitio-commons 2.1.0 → 2.1.1-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.
Files changed (154) hide show
  1. package/README.md +1 -0
  2. package/cjs/evaluator/combiners/and.js +2 -6
  3. package/cjs/evaluator/combiners/ifelseif.js +6 -6
  4. package/cjs/evaluator/condition/index.js +6 -5
  5. package/cjs/evaluator/index.js +7 -7
  6. package/cjs/evaluator/matchers/index.js +3 -1
  7. package/cjs/evaluator/matchers/matcherTypes.js +1 -0
  8. package/cjs/evaluator/matchers/rbsegment.js +43 -0
  9. package/cjs/evaluator/matchersTransform/index.js +4 -0
  10. package/cjs/evaluator/parser/index.js +2 -2
  11. package/cjs/evaluator/value/sanitize.js +1 -0
  12. package/cjs/logger/constants.js +5 -6
  13. package/cjs/logger/messages/debug.js +3 -4
  14. package/cjs/logger/messages/warn.js +1 -1
  15. package/cjs/services/splitApi.js +2 -2
  16. package/cjs/storages/AbstractSplitsCacheAsync.js +12 -1
  17. package/cjs/storages/AbstractSplitsCacheSync.js +10 -9
  18. package/cjs/storages/KeyBuilder.js +8 -15
  19. package/cjs/storages/KeyBuilderCS.js +12 -3
  20. package/cjs/storages/KeyBuilderSS.js +3 -0
  21. package/cjs/storages/dataLoader.js +1 -2
  22. package/cjs/storages/inLocalStorage/RBSegmentsCacheInLocal.js +117 -0
  23. package/cjs/storages/inLocalStorage/SplitsCacheInLocal.js +14 -16
  24. package/cjs/storages/inLocalStorage/index.js +4 -0
  25. package/cjs/storages/inMemory/InMemoryStorage.js +3 -0
  26. package/cjs/storages/inMemory/InMemoryStorageCS.js +4 -0
  27. package/cjs/storages/inMemory/RBSegmentsCacheInMemory.js +61 -0
  28. package/cjs/storages/inMemory/SplitsCacheInMemory.js +24 -31
  29. package/cjs/storages/inRedis/RBSegmentsCacheInRedis.js +64 -0
  30. package/cjs/storages/inRedis/SplitsCacheInRedis.js +4 -21
  31. package/cjs/storages/inRedis/index.js +2 -0
  32. package/cjs/storages/pluggable/RBSegmentsCachePluggable.js +64 -0
  33. package/cjs/storages/pluggable/SplitsCachePluggable.js +2 -19
  34. package/cjs/storages/pluggable/index.js +2 -0
  35. package/cjs/sync/offline/syncTasks/fromObjectSyncTask.js +12 -13
  36. package/cjs/sync/polling/fetchers/splitChangesFetcher.js +2 -2
  37. package/cjs/sync/polling/pollingManagerCS.js +7 -7
  38. package/cjs/sync/polling/syncTasks/splitsSyncTask.js +1 -1
  39. package/cjs/sync/polling/updaters/mySegmentsUpdater.js +2 -2
  40. package/cjs/sync/polling/updaters/segmentChangesUpdater.js +1 -1
  41. package/cjs/sync/polling/updaters/splitChangesUpdater.js +53 -51
  42. package/cjs/sync/streaming/SSEHandler/index.js +1 -0
  43. package/cjs/sync/streaming/UpdateWorkers/SplitsUpdateWorker.js +106 -77
  44. package/cjs/sync/streaming/constants.js +2 -1
  45. package/cjs/sync/streaming/pushManager.js +3 -16
  46. package/cjs/sync/syncManagerOnline.js +2 -2
  47. package/cjs/utils/constants/index.js +3 -2
  48. package/esm/evaluator/combiners/and.js +2 -6
  49. package/esm/evaluator/combiners/ifelseif.js +7 -7
  50. package/esm/evaluator/condition/index.js +6 -5
  51. package/esm/evaluator/index.js +7 -7
  52. package/esm/evaluator/matchers/index.js +3 -1
  53. package/esm/evaluator/matchers/matcherTypes.js +1 -0
  54. package/esm/evaluator/matchers/rbsegment.js +39 -0
  55. package/esm/evaluator/matchersTransform/index.js +4 -0
  56. package/esm/evaluator/parser/index.js +2 -2
  57. package/esm/evaluator/value/sanitize.js +1 -0
  58. package/esm/logger/constants.js +2 -3
  59. package/esm/logger/messages/debug.js +3 -4
  60. package/esm/logger/messages/warn.js +1 -1
  61. package/esm/services/splitApi.js +2 -2
  62. package/esm/storages/AbstractSplitsCacheAsync.js +12 -1
  63. package/esm/storages/AbstractSplitsCacheSync.js +10 -9
  64. package/esm/storages/KeyBuilder.js +8 -15
  65. package/esm/storages/KeyBuilderCS.js +12 -3
  66. package/esm/storages/KeyBuilderSS.js +3 -0
  67. package/esm/storages/dataLoader.js +1 -2
  68. package/esm/storages/inLocalStorage/RBSegmentsCacheInLocal.js +114 -0
  69. package/esm/storages/inLocalStorage/SplitsCacheInLocal.js +14 -16
  70. package/esm/storages/inLocalStorage/index.js +4 -0
  71. package/esm/storages/inMemory/InMemoryStorage.js +3 -0
  72. package/esm/storages/inMemory/InMemoryStorageCS.js +4 -0
  73. package/esm/storages/inMemory/RBSegmentsCacheInMemory.js +58 -0
  74. package/esm/storages/inMemory/SplitsCacheInMemory.js +24 -31
  75. package/esm/storages/inRedis/RBSegmentsCacheInRedis.js +61 -0
  76. package/esm/storages/inRedis/SplitsCacheInRedis.js +4 -21
  77. package/esm/storages/inRedis/index.js +2 -0
  78. package/esm/storages/pluggable/RBSegmentsCachePluggable.js +61 -0
  79. package/esm/storages/pluggable/SplitsCachePluggable.js +2 -19
  80. package/esm/storages/pluggable/index.js +2 -0
  81. package/esm/sync/offline/syncTasks/fromObjectSyncTask.js +12 -13
  82. package/esm/sync/polling/fetchers/splitChangesFetcher.js +2 -2
  83. package/esm/sync/polling/pollingManagerCS.js +7 -7
  84. package/esm/sync/polling/syncTasks/splitsSyncTask.js +1 -1
  85. package/esm/sync/polling/updaters/mySegmentsUpdater.js +2 -2
  86. package/esm/sync/polling/updaters/segmentChangesUpdater.js +1 -1
  87. package/esm/sync/polling/updaters/splitChangesUpdater.js +53 -51
  88. package/esm/sync/streaming/SSEHandler/index.js +2 -1
  89. package/esm/sync/streaming/UpdateWorkers/SplitsUpdateWorker.js +102 -73
  90. package/esm/sync/streaming/constants.js +1 -0
  91. package/esm/sync/streaming/pushManager.js +6 -19
  92. package/esm/sync/syncManagerOnline.js +2 -2
  93. package/esm/utils/constants/index.js +2 -1
  94. package/package.json +1 -1
  95. package/src/dtos/types.ts +32 -8
  96. package/src/evaluator/Engine.ts +1 -1
  97. package/src/evaluator/combiners/and.ts +5 -4
  98. package/src/evaluator/combiners/ifelseif.ts +7 -9
  99. package/src/evaluator/condition/engineUtils.ts +1 -1
  100. package/src/evaluator/condition/index.ts +12 -12
  101. package/src/evaluator/index.ts +7 -7
  102. package/src/evaluator/matchers/index.ts +3 -1
  103. package/src/evaluator/matchers/matcherTypes.ts +1 -0
  104. package/src/evaluator/matchers/rbsegment.ts +61 -0
  105. package/src/evaluator/matchersTransform/index.ts +3 -0
  106. package/src/evaluator/parser/index.ts +3 -3
  107. package/src/evaluator/types.ts +2 -2
  108. package/src/evaluator/value/index.ts +2 -2
  109. package/src/evaluator/value/sanitize.ts +5 -4
  110. package/src/logger/constants.ts +2 -3
  111. package/src/logger/messages/debug.ts +3 -4
  112. package/src/logger/messages/warn.ts +1 -1
  113. package/src/sdkManager/index.ts +1 -1
  114. package/src/services/splitApi.ts +2 -2
  115. package/src/services/types.ts +1 -1
  116. package/src/storages/AbstractSplitsCacheAsync.ts +15 -5
  117. package/src/storages/AbstractSplitsCacheSync.ts +14 -15
  118. package/src/storages/KeyBuilder.ts +9 -17
  119. package/src/storages/KeyBuilderCS.ts +15 -4
  120. package/src/storages/KeyBuilderSS.ts +4 -0
  121. package/src/storages/dataLoader.ts +1 -2
  122. package/src/storages/inLocalStorage/RBSegmentsCacheInLocal.ts +136 -0
  123. package/src/storages/inLocalStorage/SplitsCacheInLocal.ts +15 -16
  124. package/src/storages/inLocalStorage/index.ts +4 -0
  125. package/src/storages/inMemory/InMemoryStorage.ts +3 -0
  126. package/src/storages/inMemory/InMemoryStorageCS.ts +4 -0
  127. package/src/storages/inMemory/RBSegmentsCacheInMemory.ts +68 -0
  128. package/src/storages/inMemory/SplitsCacheInMemory.ts +22 -27
  129. package/src/storages/inRedis/RBSegmentsCacheInRedis.ts +79 -0
  130. package/src/storages/inRedis/SplitsCacheInRedis.ts +4 -21
  131. package/src/storages/inRedis/index.ts +2 -0
  132. package/src/storages/pluggable/RBSegmentsCachePluggable.ts +76 -0
  133. package/src/storages/pluggable/SplitsCachePluggable.ts +2 -19
  134. package/src/storages/pluggable/index.ts +2 -0
  135. package/src/storages/types.ts +43 -17
  136. package/src/sync/offline/syncTasks/fromObjectSyncTask.ts +14 -15
  137. package/src/sync/polling/fetchers/splitChangesFetcher.ts +2 -1
  138. package/src/sync/polling/fetchers/types.ts +1 -0
  139. package/src/sync/polling/pollingManagerCS.ts +7 -7
  140. package/src/sync/polling/syncTasks/splitsSyncTask.ts +1 -2
  141. package/src/sync/polling/types.ts +2 -2
  142. package/src/sync/polling/updaters/mySegmentsUpdater.ts +2 -2
  143. package/src/sync/polling/updaters/segmentChangesUpdater.ts +1 -1
  144. package/src/sync/polling/updaters/splitChangesUpdater.ts +64 -62
  145. package/src/sync/streaming/SSEHandler/index.ts +2 -1
  146. package/src/sync/streaming/SSEHandler/types.ts +2 -2
  147. package/src/sync/streaming/UpdateWorkers/SplitsUpdateWorker.ts +98 -68
  148. package/src/sync/streaming/constants.ts +1 -0
  149. package/src/sync/streaming/parseUtils.ts +2 -2
  150. package/src/sync/streaming/pushManager.ts +6 -18
  151. package/src/sync/streaming/types.ts +3 -2
  152. package/src/sync/syncManagerOnline.ts +2 -2
  153. package/src/utils/constants/index.ts +2 -1
  154. 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, // IN_LARGE_SEGMENT: 23
49
+ largeSegmentMatcherContext,
50
+ ruleBasedSegmentMatcherContext // IN_RULE_BASED_SEGMENT: 24
49
51
  ];
50
52
  /**
51
53
  * Matcher factory.
@@ -23,6 +23,7 @@ export var matcherTypes = {
23
23
  BETWEEN_SEMVER: 21,
24
24
  IN_LIST_SEMVER: 22,
25
25
  IN_LARGE_SEGMENT: 23,
26
+ IN_RULE_BASED_SEGMENT: 24,
26
27
  };
27
28
  export var matcherDataTypes = {
28
29
  BOOLEAN: 'BOOLEAN',
@@ -0,0 +1,39 @@
1
+ import { thenable } from '../../utils/promise/thenable';
2
+ import { getMatching, keyParser } from '../../utils/key';
3
+ import { parser } from '../parser';
4
+ export function ruleBasedSegmentMatcherContext(segmentName, storage, log) {
5
+ return function ruleBasedSegmentMatcher(_a, splitEvaluator) {
6
+ var key = _a.key, attributes = _a.attributes;
7
+ function matchConditions(rbsegment) {
8
+ var conditions = rbsegment.conditions;
9
+ var evaluator = parser(log, conditions, storage);
10
+ var evaluation = evaluator(keyParser(key), undefined, undefined, undefined, attributes, splitEvaluator);
11
+ return thenable(evaluation) ?
12
+ evaluation.then(function (evaluation) { return evaluation ? true : false; }) :
13
+ evaluation ? true : false;
14
+ }
15
+ function isExcluded(rbSegment) {
16
+ var matchingKey = getMatching(key);
17
+ if (rbSegment.excluded.keys.indexOf(matchingKey) !== -1)
18
+ return true;
19
+ var isInSegment = rbSegment.excluded.segments.map(function (segmentName) {
20
+ return storage.segments.isInSegment(segmentName, matchingKey);
21
+ });
22
+ return isInSegment.length && thenable(isInSegment[0]) ?
23
+ Promise.all(isInSegment).then(function (results) { return results.some(function (result) { return result; }); }) :
24
+ isInSegment.some(function (result) { return result; });
25
+ }
26
+ function isInSegment(rbSegment) {
27
+ if (!rbSegment)
28
+ return false;
29
+ var excluded = isExcluded(rbSegment);
30
+ return thenable(excluded) ?
31
+ excluded.then(function (excluded) { return excluded ? false : matchConditions(rbSegment); }) :
32
+ excluded ? false : matchConditions(rbSegment);
33
+ }
34
+ var rbSegment = storage.rbSegments.get(segmentName);
35
+ return thenable(rbSegment) ?
36
+ rbSegment.then(isInSegment) :
37
+ isInSegment(rbSegment);
38
+ };
39
+ }
@@ -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
- // Instanciate evaluator given the set of conditions using if else if logic
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;
@@ -20,9 +20,8 @@ export var RETRIEVE_CLIENT_EXISTING = 28;
20
20
  export var RETRIEVE_MANAGER = 29;
21
21
  export var SYNC_OFFLINE_DATA = 30;
22
22
  export var SYNC_SPLITS_FETCH = 31;
23
- export var SYNC_SPLITS_NEW = 32;
24
- export var SYNC_SPLITS_REMOVED = 33;
25
- export var SYNC_SPLITS_SEGMENTS = 34;
23
+ export var SYNC_SPLITS_UPDATE = 32;
24
+ export var SYNC_RBS_UPDATE = 33;
26
25
  export var STREAMING_NEW_MESSAGE = 35;
27
26
  export var SYNC_TASK_START = 36;
28
27
  export var SYNC_TASK_EXECUTE = 37;
@@ -19,10 +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_NEW, c.LOG_PREFIX_SYNC_SPLITS + 'New feature flags %s'],
24
- [c.SYNC_SPLITS_REMOVED, c.LOG_PREFIX_SYNC_SPLITS + 'Removed feature flags %s'],
25
- [c.SYNC_SPLITS_SEGMENTS, c.LOG_PREFIX_SYNC_SPLITS + 'Segment names collected %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.'],
26
25
  [c.STREAMING_NEW_MESSAGE, c.LOG_PREFIX_SYNC_STREAMING + 'New SSE message received, with data: %s.'],
27
26
  [c.SYNC_TASK_START, c.LOG_PREFIX_SYNC + ': Starting %s. Running each %s millis'],
28
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 SPLIT_UPDATE notification: %s'],
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.'],
@@ -38,8 +38,8 @@ export function splitApiFactory(settings, platform, telemetryTracker) {
38
38
  }
39
39
  return splitHttpClient(url, undefined, telemetryTracker.trackHttp(TOKEN));
40
40
  },
41
- fetchSplitChanges: function (since, noCache, till) {
42
- var url = urls.sdk + "/splitChanges?s=" + flagSpecVersion + "&since=" + since + (filterQueryString || '') + (till ? '&till=' + till : '');
41
+ fetchSplitChanges: function (since, noCache, till, rbSince) {
42
+ var url = urls.sdk + "/splitChanges?s=" + flagSpecVersion + "&since=" + since + (rbSince ? '&rbSince=' + rbSince : '') + (filterQueryString || '') + (till ? '&till=' + till : '');
43
43
  return splitHttpClient(url, noCache ? noCacheHeaderOptions : undefined, telemetryTracker.trackHttp(SPLITS))
44
44
  .catch(function (err) {
45
45
  if (err.statusCode === 414)
@@ -6,6 +6,17 @@ import { objectAssign } from '../utils/lang/objectAssign';
6
6
  var AbstractSplitsCacheAsync = /** @class */ (function () {
7
7
  function AbstractSplitsCacheAsync() {
8
8
  }
9
+ AbstractSplitsCacheAsync.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.addSplit(addedFF); })),
14
+ Promise.all(toRemove.map(function (removedFF) { return _this.removeSplit(removedFF.name); }))
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
+ };
9
20
  // @TODO revisit segment-related methods ('usesSegments', 'getRegisteredSegments', 'registerSegments')
10
21
  // noop, just keeping the interface. This is used by standalone client-side API only, and so only implemented by InMemory and InLocalStorage.
11
22
  AbstractSplitsCacheAsync.prototype.usesSegments = function () {
@@ -34,7 +45,7 @@ var AbstractSplitsCacheAsync = /** @class */ (function () {
34
45
  newSplit.killed = true;
35
46
  newSplit.defaultTreatment = defaultTreatment;
36
47
  newSplit.changeNumber = changeNumber;
37
- return _this.addSplit(name, newSplit);
48
+ return _this.addSplit(newSplit);
38
49
  }
39
50
  return false;
40
51
  }).catch(function () { return false; });
@@ -7,13 +7,11 @@ import { IN_SEGMENT, IN_LARGE_SEGMENT } from '../utils/constants';
7
7
  var AbstractSplitsCacheSync = /** @class */ (function () {
8
8
  function AbstractSplitsCacheSync() {
9
9
  }
10
- AbstractSplitsCacheSync.prototype.addSplits = function (entries) {
10
+ AbstractSplitsCacheSync.prototype.update = function (toAdd, toRemove, changeNumber) {
11
11
  var _this = this;
12
- return entries.map(function (keyValuePair) { return _this.addSplit(keyValuePair[0], keyValuePair[1]); });
13
- };
14
- AbstractSplitsCacheSync.prototype.removeSplits = function (names) {
15
- var _this = this;
16
- return names.map(function (name) { return _this.removeSplit(name); });
12
+ this.setChangeNumber(changeNumber);
13
+ var updated = toAdd.map(function (addedFF) { return _this.addSplit(addedFF); }).some(function (result) { return result; });
14
+ return toRemove.map(function (removedFF) { return _this.removeSplit(removedFF.name); }).some(function (result) { return result; }) || updated;
17
15
  };
18
16
  AbstractSplitsCacheSync.prototype.getSplits = function (names) {
19
17
  var _this = this;
@@ -48,7 +46,7 @@ var AbstractSplitsCacheSync = /** @class */ (function () {
48
46
  newSplit.killed = true;
49
47
  newSplit.defaultTreatment = defaultTreatment;
50
48
  newSplit.changeNumber = changeNumber;
51
- return this.addSplit(name, newSplit);
49
+ return this.addSplit(newSplit);
52
50
  }
53
51
  return false;
54
52
  };
@@ -59,8 +57,8 @@ export { AbstractSplitsCacheSync };
59
57
  * Given a parsed split, it returns a boolean flagging if its conditions use segments matchers (rules & whitelists).
60
58
  * This util is intended to simplify the implementation of `splitsCache::usesSegments` method
61
59
  */
62
- export function usesSegments(split) {
63
- var conditions = split.conditions || [];
60
+ export function usesSegments(ruleEntity) {
61
+ var conditions = ruleEntity.conditions || [];
64
62
  for (var i = 0; i < conditions.length; i++) {
65
63
  var matchers = conditions[i].matcherGroup.matchers;
66
64
  for (var j = 0; j < matchers.length; j++) {
@@ -69,5 +67,8 @@ export function usesSegments(split) {
69
67
  return true;
70
68
  }
71
69
  }
70
+ var excluded = ruleEntity.excluded;
71
+ if (excluded && excluded.segments && excluded.segments.length > 0)
72
+ return true;
72
73
  return false;
73
74
  }
@@ -1,4 +1,3 @@
1
- import { startsWith } from '../utils/lang';
2
1
  import { hash } from '../utils/murmur3/murmur3';
3
2
  var everythingAtTheEnd = /[^.]+$/;
4
3
  var DEFAULT_PREFIX = 'SPLITIO';
@@ -22,19 +21,17 @@ var KeyBuilder = /** @class */ (function () {
22
21
  KeyBuilder.prototype.buildSplitsTillKey = function () {
23
22
  return this.prefix + ".splits.till";
24
23
  };
25
- // NOT USED
26
- // buildSplitsReady() {
27
- // return `${this.prefix}.splits.ready`;
28
- // }
29
- KeyBuilder.prototype.isSplitKey = function (key) {
30
- return startsWith(key, this.prefix + ".split.");
31
- };
32
24
  KeyBuilder.prototype.buildSplitKeyPrefix = function () {
33
25
  return this.prefix + ".split.";
34
26
  };
35
- // Only used by InLocalStorage.
36
- KeyBuilder.prototype.buildSplitsWithSegmentCountKey = function () {
37
- return this.prefix + ".splits.usingSegments";
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.";
38
35
  };
39
36
  KeyBuilder.prototype.buildSegmentNameKey = function (segmentName) {
40
37
  return this.prefix + ".segment." + segmentName;
@@ -42,10 +39,6 @@ var KeyBuilder = /** @class */ (function () {
42
39
  KeyBuilder.prototype.buildSegmentTillKey = function (segmentName) {
43
40
  return this.prefix + ".segment." + segmentName + ".till";
44
41
  };
45
- // NOT USED
46
- // buildSegmentsReady() {
47
- // return `${this.prefix}.segments.ready`;
48
- // }
49
42
  KeyBuilder.prototype.extractKey = function (builtKey) {
50
43
  var s = builtKey.match(everythingAtTheEnd);
51
44
  if (s && s.length) {
@@ -6,7 +6,7 @@ var KeyBuilderCS = /** @class */ (function (_super) {
6
6
  function KeyBuilderCS(prefix, matchingKey) {
7
7
  var _this = _super.call(this, prefix) || this;
8
8
  _this.matchingKey = matchingKey;
9
- _this.regexSplitsCacheKey = new RegExp("^" + prefix + "\\.(splits?|trafficType|flagSet)\\.");
9
+ _this.regexSplitsCacheKey = new RegExp("^" + prefix + "\\.(splits?|trafficType|flagSet|rbsegment)\\.");
10
10
  return _this;
11
11
  }
12
12
  /**
@@ -18,7 +18,7 @@ var KeyBuilderCS = /** @class */ (function (_super) {
18
18
  KeyBuilderCS.prototype.extractSegmentName = function (builtSegmentKeyName) {
19
19
  var prefix = this.prefix + "." + this.matchingKey + ".segment.";
20
20
  if (startsWith(builtSegmentKeyName, prefix))
21
- return builtSegmentKeyName.substr(prefix.length);
21
+ return builtSegmentKeyName.slice(prefix.length);
22
22
  };
23
23
  KeyBuilderCS.prototype.buildLastUpdatedKey = function () {
24
24
  return this.prefix + ".splits.lastUpdated";
@@ -29,6 +29,15 @@ var KeyBuilderCS = /** @class */ (function (_super) {
29
29
  KeyBuilderCS.prototype.buildTillKey = function () {
30
30
  return this.prefix + "." + this.matchingKey + ".segments.till";
31
31
  };
32
+ KeyBuilderCS.prototype.isSplitKey = function (key) {
33
+ return startsWith(key, this.prefix + ".split.");
34
+ };
35
+ KeyBuilderCS.prototype.isRBSegmentKey = function (key) {
36
+ return startsWith(key, this.prefix + ".rbsegment.");
37
+ };
38
+ KeyBuilderCS.prototype.buildSplitsWithSegmentCountKey = function () {
39
+ return this.prefix + ".splits.usingSegments";
40
+ };
32
41
  return KeyBuilderCS;
33
42
  }(KeyBuilder));
34
43
  export { KeyBuilderCS };
@@ -40,7 +49,7 @@ export function myLargeSegmentsKeyBuilder(prefix, matchingKey) {
40
49
  extractSegmentName: function (builtSegmentKeyName) {
41
50
  var p = prefix + "." + matchingKey + ".largeSegment.";
42
51
  if (startsWith(builtSegmentKeyName, p))
43
- return builtSegmentKeyName.substr(p.length);
52
+ return builtSegmentKeyName.slice(p.length);
44
53
  },
45
54
  buildTillKey: function () {
46
55
  return prefix + "." + matchingKey + ".largeSegments.till";
@@ -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;
@@ -29,9 +29,8 @@ export function dataLoaderFactory(preloadedData) {
29
29
  return;
30
30
  // cleaning up the localStorage data, since some cached splits might need be part of the preloaded data
31
31
  storage.splits.clear();
32
- storage.splits.setChangeNumber(since);
33
32
  // splitsData in an object where the property is the split name and the pertaining value is a stringified json of its data
34
- storage.splits.addSplits(Object.keys(splitsData).map(function (splitName) { return JSON.parse(splitsData[splitName]); }));
33
+ storage.splits.update(Object.keys(splitsData).map(function (splitName) { return JSON.parse(splitsData[splitName]); }), [], since);
35
34
  // add mySegments data
36
35
  var mySegmentsData = preloadedData.mySegmentsData && preloadedData.mySegmentsData[userId];
37
36
  if (!mySegmentsData) {
@@ -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 };
@@ -44,15 +44,13 @@ var SplitsCacheInLocal = /** @class */ (function (_super) {
44
44
  };
45
45
  SplitsCacheInLocal.prototype._incrementCounts = function (split) {
46
46
  try {
47
- if (split) {
48
- var ttKey = this.keys.buildTrafficTypeKey(split.trafficTypeName);
47
+ var ttKey = this.keys.buildTrafficTypeKey(split.trafficTypeName);
48
+ // @ts-expect-error
49
+ localStorage.setItem(ttKey, toNumber(localStorage.getItem(ttKey)) + 1);
50
+ if (usesSegments(split)) {
51
+ var segmentsCountKey = this.keys.buildSplitsWithSegmentCountKey();
49
52
  // @ts-expect-error
50
- localStorage.setItem(ttKey, toNumber(localStorage.getItem(ttKey)) + 1);
51
- if (usesSegments(split)) {
52
- var segmentsCountKey = this.keys.buildSplitsWithSegmentCountKey();
53
- // @ts-expect-error
54
- localStorage.setItem(segmentsCountKey, toNumber(localStorage.getItem(segmentsCountKey)) + 1);
55
- }
53
+ localStorage.setItem(segmentsCountKey, toNumber(localStorage.getItem(segmentsCountKey)) + 1);
56
54
  }
57
55
  }
58
56
  catch (e) {
@@ -79,9 +77,10 @@ var SplitsCacheInLocal = /** @class */ (function (_super) {
79
77
  });
80
78
  this.hasSync = false;
81
79
  };
82
- SplitsCacheInLocal.prototype.addSplit = function (name, split) {
80
+ SplitsCacheInLocal.prototype.addSplit = function (split) {
83
81
  try {
84
- var splitKey = this.keys.buildSplitKey(name);
82
+ var name_1 = split.name;
83
+ var splitKey = this.keys.buildSplitKey(name_1);
85
84
  var splitFromLocalStorage = localStorage.getItem(splitKey);
86
85
  var previousSplit = splitFromLocalStorage ? JSON.parse(splitFromLocalStorage) : null;
87
86
  localStorage.setItem(splitKey, JSON.stringify(split));
@@ -100,6 +99,8 @@ var SplitsCacheInLocal = /** @class */ (function (_super) {
100
99
  SplitsCacheInLocal.prototype.removeSplit = function (name) {
101
100
  try {
102
101
  var split = this.getSplit(name);
102
+ if (!split)
103
+ return false;
103
104
  localStorage.removeItem(this.keys.buildSplitKey(name));
104
105
  this._decrementCounts(split);
105
106
  if (split)
@@ -171,12 +172,9 @@ var SplitsCacheInLocal = /** @class */ (function (_super) {
171
172
  return true;
172
173
  var storedCount = localStorage.getItem(this.keys.buildSplitsWithSegmentCountKey());
173
174
  var splitsWithSegmentsCount = storedCount === null ? 0 : toNumber(storedCount);
174
- if (isFiniteNumber(splitsWithSegmentsCount)) {
175
- return splitsWithSegmentsCount > 0;
176
- }
177
- else {
178
- return true;
179
- }
175
+ return isFiniteNumber(splitsWithSegmentsCount) ?
176
+ splitsWithSegmentsCount > 0 :
177
+ true;
180
178
  };
181
179
  /**
182
180
  * Check if the splits information is already stored in browser LocalStorage.
@@ -13,6 +13,7 @@ import { STORAGE_LOCALSTORAGE } from '../../utils/constants';
13
13
  import { shouldRecordTelemetry, TelemetryCacheInMemory } from '../inMemory/TelemetryCacheInMemory';
14
14
  import { UniqueKeysCacheInMemoryCS } from '../inMemory/UniqueKeysCacheInMemoryCS';
15
15
  import { getMatching } from '../../utils/key';
16
+ import { RBSegmentsCacheInLocal } from './RBSegmentsCacheInLocal';
16
17
  /**
17
18
  * InLocal storage factory for standalone client-side SplitFactory
18
19
  */
@@ -30,10 +31,12 @@ export function InLocalStorage(options) {
30
31
  var keys = new KeyBuilderCS(prefix, matchingKey);
31
32
  var expirationTimestamp = Date.now() - DEFAULT_CACHE_EXPIRATION_IN_MILLIS;
32
33
  var splits = new SplitsCacheInLocal(settings, keys, expirationTimestamp);
34
+ var rbSegments = new RBSegmentsCacheInLocal(settings, keys);
33
35
  var segments = new MySegmentsCacheInLocal(log, keys);
34
36
  var largeSegments = new MySegmentsCacheInLocal(log, myLargeSegmentsKeyBuilder(prefix, matchingKey));
35
37
  return {
36
38
  splits: splits,
39
+ rbSegments: rbSegments,
37
40
  segments: segments,
38
41
  largeSegments: largeSegments,
39
42
  impressions: new ImpressionsCacheInMemory(impressionsQueueSize),
@@ -46,6 +49,7 @@ export function InLocalStorage(options) {
46
49
  shared: function (matchingKey) {
47
50
  return {
48
51
  splits: this.splits,
52
+ rbSegments: this.rbSegments,
49
53
  segments: new MySegmentsCacheInLocal(log, new KeyBuilderCS(prefix, matchingKey)),
50
54
  largeSegments: new MySegmentsCacheInLocal(log, myLargeSegmentsKeyBuilder(prefix, matchingKey)),
51
55
  impressions: this.impressions,
@@ -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 };