@splitsoftware/splitio-commons 2.1.0-rc.2 → 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 (174) hide show
  1. package/CHANGES.txt +2 -7
  2. package/README.md +1 -0
  3. package/cjs/evaluator/combiners/and.js +2 -6
  4. package/cjs/evaluator/combiners/ifelseif.js +6 -6
  5. package/cjs/evaluator/condition/index.js +6 -5
  6. package/cjs/evaluator/index.js +7 -7
  7. package/cjs/evaluator/matchers/index.js +3 -1
  8. package/cjs/evaluator/matchers/matcherTypes.js +1 -0
  9. package/cjs/evaluator/matchers/rbsegment.js +43 -0
  10. package/cjs/evaluator/matchersTransform/index.js +4 -0
  11. package/cjs/evaluator/parser/index.js +2 -2
  12. package/cjs/evaluator/value/sanitize.js +1 -0
  13. package/cjs/logger/constants.js +5 -6
  14. package/cjs/logger/messages/debug.js +3 -4
  15. package/cjs/logger/messages/warn.js +1 -1
  16. package/cjs/readiness/readinessManager.js +0 -6
  17. package/cjs/services/splitApi.js +2 -2
  18. package/cjs/storages/AbstractSplitsCacheAsync.js +19 -1
  19. package/cjs/storages/AbstractSplitsCacheSync.js +17 -9
  20. package/cjs/storages/KeyBuilder.js +8 -15
  21. package/cjs/storages/KeyBuilderCS.js +11 -5
  22. package/cjs/storages/KeyBuilderSS.js +3 -0
  23. package/cjs/storages/dataLoader.js +3 -5
  24. package/cjs/storages/inLocalStorage/RBSegmentsCacheInLocal.js +117 -0
  25. package/cjs/storages/inLocalStorage/SplitsCacheInLocal.js +69 -15
  26. package/cjs/storages/inLocalStorage/index.js +7 -5
  27. package/cjs/storages/inMemory/InMemoryStorage.js +3 -0
  28. package/cjs/storages/inMemory/InMemoryStorageCS.js +4 -0
  29. package/cjs/storages/inMemory/RBSegmentsCacheInMemory.js +61 -0
  30. package/cjs/storages/inMemory/SplitsCacheInMemory.js +24 -31
  31. package/cjs/storages/inRedis/RBSegmentsCacheInRedis.js +64 -0
  32. package/cjs/storages/inRedis/SplitsCacheInRedis.js +4 -21
  33. package/cjs/storages/inRedis/constants.js +1 -1
  34. package/cjs/storages/inRedis/index.js +2 -0
  35. package/cjs/storages/pluggable/RBSegmentsCachePluggable.js +64 -0
  36. package/cjs/storages/pluggable/SplitsCachePluggable.js +2 -19
  37. package/cjs/storages/pluggable/index.js +3 -2
  38. package/cjs/sync/offline/syncTasks/fromObjectSyncTask.js +14 -16
  39. package/cjs/sync/polling/fetchers/splitChangesFetcher.js +2 -2
  40. package/cjs/sync/polling/pollingManagerCS.js +7 -7
  41. package/cjs/sync/polling/syncTasks/splitsSyncTask.js +1 -1
  42. package/cjs/sync/polling/updaters/mySegmentsUpdater.js +2 -2
  43. package/cjs/sync/polling/updaters/segmentChangesUpdater.js +1 -1
  44. package/cjs/sync/polling/updaters/splitChangesUpdater.js +62 -51
  45. package/cjs/sync/streaming/SSEHandler/index.js +1 -0
  46. package/cjs/sync/streaming/UpdateWorkers/SplitsUpdateWorker.js +106 -77
  47. package/cjs/sync/streaming/constants.js +2 -1
  48. package/cjs/sync/streaming/pushManager.js +3 -16
  49. package/cjs/sync/syncManagerOnline.js +5 -10
  50. package/cjs/trackers/uniqueKeysTracker.js +1 -1
  51. package/cjs/utils/constants/browser.js +5 -0
  52. package/cjs/utils/constants/index.js +3 -2
  53. package/cjs/utils/settingsValidation/storage/storageCS.js +1 -1
  54. package/esm/evaluator/combiners/and.js +2 -6
  55. package/esm/evaluator/combiners/ifelseif.js +7 -7
  56. package/esm/evaluator/condition/index.js +6 -5
  57. package/esm/evaluator/index.js +7 -7
  58. package/esm/evaluator/matchers/index.js +3 -1
  59. package/esm/evaluator/matchers/matcherTypes.js +1 -0
  60. package/esm/evaluator/matchers/rbsegment.js +39 -0
  61. package/esm/evaluator/matchersTransform/index.js +4 -0
  62. package/esm/evaluator/parser/index.js +2 -2
  63. package/esm/evaluator/value/sanitize.js +1 -0
  64. package/esm/logger/constants.js +2 -3
  65. package/esm/logger/messages/debug.js +3 -4
  66. package/esm/logger/messages/warn.js +1 -1
  67. package/esm/readiness/readinessManager.js +0 -6
  68. package/esm/services/splitApi.js +2 -2
  69. package/esm/storages/AbstractSplitsCacheAsync.js +19 -1
  70. package/esm/storages/AbstractSplitsCacheSync.js +17 -9
  71. package/esm/storages/KeyBuilder.js +8 -15
  72. package/esm/storages/KeyBuilderCS.js +11 -5
  73. package/esm/storages/KeyBuilderSS.js +3 -0
  74. package/esm/storages/dataLoader.js +2 -4
  75. package/esm/storages/inLocalStorage/RBSegmentsCacheInLocal.js +114 -0
  76. package/esm/storages/inLocalStorage/SplitsCacheInLocal.js +69 -15
  77. package/esm/storages/inLocalStorage/index.js +7 -5
  78. package/esm/storages/inMemory/InMemoryStorage.js +3 -0
  79. package/esm/storages/inMemory/InMemoryStorageCS.js +4 -0
  80. package/esm/storages/inMemory/RBSegmentsCacheInMemory.js +58 -0
  81. package/esm/storages/inMemory/SplitsCacheInMemory.js +24 -31
  82. package/esm/storages/inRedis/RBSegmentsCacheInRedis.js +61 -0
  83. package/esm/storages/inRedis/SplitsCacheInRedis.js +4 -21
  84. package/esm/storages/inRedis/constants.js +1 -1
  85. package/esm/storages/inRedis/index.js +2 -0
  86. package/esm/storages/pluggable/RBSegmentsCachePluggable.js +61 -0
  87. package/esm/storages/pluggable/SplitsCachePluggable.js +2 -19
  88. package/esm/storages/pluggable/index.js +3 -2
  89. package/esm/sync/offline/syncTasks/fromObjectSyncTask.js +14 -16
  90. package/esm/sync/polling/fetchers/splitChangesFetcher.js +2 -2
  91. package/esm/sync/polling/pollingManagerCS.js +7 -7
  92. package/esm/sync/polling/syncTasks/splitsSyncTask.js +1 -1
  93. package/esm/sync/polling/updaters/mySegmentsUpdater.js +2 -2
  94. package/esm/sync/polling/updaters/segmentChangesUpdater.js +1 -1
  95. package/esm/sync/polling/updaters/splitChangesUpdater.js +63 -52
  96. package/esm/sync/streaming/SSEHandler/index.js +2 -1
  97. package/esm/sync/streaming/UpdateWorkers/SplitsUpdateWorker.js +102 -73
  98. package/esm/sync/streaming/constants.js +1 -0
  99. package/esm/sync/streaming/pushManager.js +6 -19
  100. package/esm/sync/syncManagerOnline.js +5 -10
  101. package/esm/trackers/uniqueKeysTracker.js +1 -1
  102. package/esm/utils/constants/browser.js +2 -0
  103. package/esm/utils/constants/index.js +2 -1
  104. package/esm/utils/settingsValidation/storage/storageCS.js +1 -1
  105. package/package.json +1 -1
  106. package/src/dtos/types.ts +32 -8
  107. package/src/evaluator/Engine.ts +1 -1
  108. package/src/evaluator/combiners/and.ts +5 -4
  109. package/src/evaluator/combiners/ifelseif.ts +7 -9
  110. package/src/evaluator/condition/engineUtils.ts +1 -1
  111. package/src/evaluator/condition/index.ts +12 -12
  112. package/src/evaluator/index.ts +7 -7
  113. package/src/evaluator/matchers/index.ts +3 -1
  114. package/src/evaluator/matchers/matcherTypes.ts +1 -0
  115. package/src/evaluator/matchers/rbsegment.ts +61 -0
  116. package/src/evaluator/matchersTransform/index.ts +3 -0
  117. package/src/evaluator/parser/index.ts +3 -3
  118. package/src/evaluator/types.ts +2 -2
  119. package/src/evaluator/value/index.ts +2 -2
  120. package/src/evaluator/value/sanitize.ts +5 -4
  121. package/src/logger/constants.ts +2 -3
  122. package/src/logger/messages/debug.ts +3 -4
  123. package/src/logger/messages/warn.ts +1 -1
  124. package/src/readiness/readinessManager.ts +0 -5
  125. package/src/sdkManager/index.ts +1 -1
  126. package/src/services/splitApi.ts +2 -2
  127. package/src/services/types.ts +1 -1
  128. package/src/storages/AbstractSplitsCacheAsync.ts +23 -5
  129. package/src/storages/AbstractSplitsCacheSync.ts +22 -15
  130. package/src/storages/KeyBuilder.ts +9 -17
  131. package/src/storages/KeyBuilderCS.ts +13 -6
  132. package/src/storages/KeyBuilderSS.ts +4 -0
  133. package/src/storages/dataLoader.ts +2 -5
  134. package/src/storages/inLocalStorage/RBSegmentsCacheInLocal.ts +136 -0
  135. package/src/storages/inLocalStorage/SplitsCacheInLocal.ts +80 -16
  136. package/src/storages/inLocalStorage/index.ts +12 -8
  137. package/src/storages/inMemory/InMemoryStorage.ts +3 -0
  138. package/src/storages/inMemory/InMemoryStorageCS.ts +4 -0
  139. package/src/storages/inMemory/RBSegmentsCacheInMemory.ts +68 -0
  140. package/src/storages/inMemory/SplitsCacheInMemory.ts +22 -27
  141. package/src/storages/inRedis/RBSegmentsCacheInRedis.ts +79 -0
  142. package/src/storages/inRedis/SplitsCacheInRedis.ts +4 -21
  143. package/src/storages/inRedis/constants.ts +1 -1
  144. package/src/storages/inRedis/index.ts +2 -0
  145. package/src/storages/pluggable/RBSegmentsCachePluggable.ts +76 -0
  146. package/src/storages/pluggable/SplitsCachePluggable.ts +2 -19
  147. package/src/storages/pluggable/index.ts +3 -2
  148. package/src/storages/types.ts +47 -18
  149. package/src/sync/offline/syncTasks/fromObjectSyncTask.ts +19 -21
  150. package/src/sync/polling/fetchers/splitChangesFetcher.ts +2 -1
  151. package/src/sync/polling/fetchers/types.ts +1 -0
  152. package/src/sync/polling/pollingManagerCS.ts +7 -7
  153. package/src/sync/polling/syncTasks/splitsSyncTask.ts +1 -2
  154. package/src/sync/polling/types.ts +2 -2
  155. package/src/sync/polling/updaters/mySegmentsUpdater.ts +2 -2
  156. package/src/sync/polling/updaters/segmentChangesUpdater.ts +1 -1
  157. package/src/sync/polling/updaters/splitChangesUpdater.ts +74 -63
  158. package/src/sync/streaming/SSEHandler/index.ts +2 -1
  159. package/src/sync/streaming/SSEHandler/types.ts +2 -2
  160. package/src/sync/streaming/UpdateWorkers/SplitsUpdateWorker.ts +98 -68
  161. package/src/sync/streaming/constants.ts +1 -0
  162. package/src/sync/streaming/parseUtils.ts +2 -2
  163. package/src/sync/streaming/pushManager.ts +6 -18
  164. package/src/sync/streaming/types.ts +3 -2
  165. package/src/sync/syncManagerOnline.ts +5 -11
  166. package/src/trackers/uniqueKeysTracker.ts +1 -1
  167. package/src/utils/constants/browser.ts +2 -0
  168. package/src/utils/constants/index.ts +2 -1
  169. package/src/utils/lang/index.ts +2 -2
  170. package/src/utils/settingsValidation/storage/storageCS.ts +1 -1
  171. package/types/splitio.d.ts +1 -25
  172. package/cjs/storages/inLocalStorage/validateCache.js +0 -79
  173. package/esm/storages/inLocalStorage/validateCache.js +0 -75
  174. package/src/storages/inLocalStorage/validateCache.ts +0 -91
@@ -0,0 +1,117 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RBSegmentsCacheInLocal = void 0;
4
+ var lang_1 = require("../../utils/lang");
5
+ var sets_1 = require("../../utils/lang/sets");
6
+ var AbstractSplitsCacheSync_1 = require("../AbstractSplitsCacheSync");
7
+ var constants_1 = require("./constants");
8
+ var RBSegmentsCacheInLocal = /** @class */ (function () {
9
+ function RBSegmentsCacheInLocal(settings, keys) {
10
+ this.keys = keys;
11
+ this.log = settings.log;
12
+ }
13
+ RBSegmentsCacheInLocal.prototype.clear = function () {
14
+ var _this = this;
15
+ this.getNames().forEach(function (name) { return _this.remove(name); });
16
+ localStorage.removeItem(this.keys.buildRBSegmentsTillKey());
17
+ };
18
+ RBSegmentsCacheInLocal.prototype.update = function (toAdd, toRemove, changeNumber) {
19
+ var _this = this;
20
+ this.setChangeNumber(changeNumber);
21
+ var updated = toAdd.map(function (toAdd) { return _this.add(toAdd); }).some(function (result) { return result; });
22
+ return toRemove.map(function (toRemove) { return _this.remove(toRemove.name); }).some(function (result) { return result; }) || updated;
23
+ };
24
+ RBSegmentsCacheInLocal.prototype.setChangeNumber = function (changeNumber) {
25
+ try {
26
+ localStorage.setItem(this.keys.buildRBSegmentsTillKey(), changeNumber + '');
27
+ localStorage.setItem(this.keys.buildLastUpdatedKey(), Date.now() + '');
28
+ }
29
+ catch (e) {
30
+ this.log.error(constants_1.LOG_PREFIX + e);
31
+ }
32
+ };
33
+ RBSegmentsCacheInLocal.prototype.updateSegmentCount = function (diff) {
34
+ var segmentsCountKey = this.keys.buildSplitsWithSegmentCountKey();
35
+ var count = (0, lang_1.toNumber)(localStorage.getItem(segmentsCountKey)) + diff;
36
+ // @ts-expect-error
37
+ if (count > 0)
38
+ localStorage.setItem(segmentsCountKey, count);
39
+ else
40
+ localStorage.removeItem(segmentsCountKey);
41
+ };
42
+ RBSegmentsCacheInLocal.prototype.add = function (rbSegment) {
43
+ try {
44
+ var name_1 = rbSegment.name;
45
+ var rbSegmentKey = this.keys.buildRBSegmentKey(name_1);
46
+ var rbSegmentFromLocalStorage = localStorage.getItem(rbSegmentKey);
47
+ var previous = rbSegmentFromLocalStorage ? JSON.parse(rbSegmentFromLocalStorage) : null;
48
+ localStorage.setItem(rbSegmentKey, JSON.stringify(rbSegment));
49
+ var usesSegmentsDiff = 0;
50
+ if (previous && (0, AbstractSplitsCacheSync_1.usesSegments)(previous))
51
+ usesSegmentsDiff--;
52
+ if ((0, AbstractSplitsCacheSync_1.usesSegments)(rbSegment))
53
+ usesSegmentsDiff++;
54
+ if (usesSegmentsDiff !== 0)
55
+ this.updateSegmentCount(usesSegmentsDiff);
56
+ return true;
57
+ }
58
+ catch (e) {
59
+ this.log.error(constants_1.LOG_PREFIX + e);
60
+ return false;
61
+ }
62
+ };
63
+ RBSegmentsCacheInLocal.prototype.remove = function (name) {
64
+ try {
65
+ var rbSegment = this.get(name);
66
+ if (!rbSegment)
67
+ return false;
68
+ localStorage.removeItem(this.keys.buildRBSegmentKey(name));
69
+ if ((0, AbstractSplitsCacheSync_1.usesSegments)(rbSegment))
70
+ this.updateSegmentCount(-1);
71
+ return true;
72
+ }
73
+ catch (e) {
74
+ this.log.error(constants_1.LOG_PREFIX + e);
75
+ return false;
76
+ }
77
+ };
78
+ RBSegmentsCacheInLocal.prototype.getNames = function () {
79
+ var len = localStorage.length;
80
+ var accum = [];
81
+ var cur = 0;
82
+ while (cur < len) {
83
+ var key = localStorage.key(cur);
84
+ if (key != null && this.keys.isRBSegmentKey(key))
85
+ accum.push(this.keys.extractKey(key));
86
+ cur++;
87
+ }
88
+ return accum;
89
+ };
90
+ RBSegmentsCacheInLocal.prototype.get = function (name) {
91
+ var item = localStorage.getItem(this.keys.buildRBSegmentKey(name));
92
+ return item && JSON.parse(item);
93
+ };
94
+ RBSegmentsCacheInLocal.prototype.contains = function (names) {
95
+ var namesArray = (0, sets_1.setToArray)(names);
96
+ var namesInStorage = this.getNames();
97
+ return namesArray.every(function (name) { return namesInStorage.indexOf(name) !== -1; });
98
+ };
99
+ RBSegmentsCacheInLocal.prototype.getChangeNumber = function () {
100
+ var n = -1;
101
+ var value = localStorage.getItem(this.keys.buildRBSegmentsTillKey());
102
+ if (value !== null) {
103
+ value = parseInt(value, 10);
104
+ return (0, lang_1.isNaNNumber)(value) ? n : value;
105
+ }
106
+ return n;
107
+ };
108
+ RBSegmentsCacheInLocal.prototype.usesSegments = function () {
109
+ var storedCount = localStorage.getItem(this.keys.buildSplitsWithSegmentCountKey());
110
+ var splitsWithSegmentsCount = storedCount === null ? 0 : (0, lang_1.toNumber)(storedCount);
111
+ return (0, lang_1.isFiniteNumber)(splitsWithSegmentsCount) ?
112
+ splitsWithSegmentsCount > 0 :
113
+ true;
114
+ };
115
+ return RBSegmentsCacheInLocal;
116
+ }());
117
+ exports.RBSegmentsCacheInLocal = RBSegmentsCacheInLocal;
@@ -5,17 +5,21 @@ var tslib_1 = require("tslib");
5
5
  var AbstractSplitsCacheSync_1 = require("../AbstractSplitsCacheSync");
6
6
  var lang_1 = require("../../utils/lang");
7
7
  var constants_1 = require("./constants");
8
+ var KeyBuilder_1 = require("../KeyBuilder");
8
9
  var sets_1 = require("../../utils/lang/sets");
9
10
  /**
10
11
  * ISplitsCacheSync implementation that stores split definitions in browser LocalStorage.
11
12
  */
12
13
  var SplitsCacheInLocal = /** @class */ (function (_super) {
13
14
  (0, tslib_1.__extends)(SplitsCacheInLocal, _super);
14
- function SplitsCacheInLocal(settings, keys) {
15
+ function SplitsCacheInLocal(settings, keys, expirationTimestamp) {
15
16
  var _this = _super.call(this) || this;
16
17
  _this.keys = keys;
17
18
  _this.log = settings.log;
19
+ _this.storageHash = (0, KeyBuilder_1.getStorageHash)(settings);
18
20
  _this.flagSetsFilter = settings.sync.__splitFiltersValidation.groupedFilters.bySet;
21
+ _this._checkExpiration(expirationTimestamp);
22
+ _this._checkFilterQuery();
19
23
  return _this;
20
24
  }
21
25
  SplitsCacheInLocal.prototype._decrementCount = function (key) {
@@ -43,15 +47,13 @@ var SplitsCacheInLocal = /** @class */ (function (_super) {
43
47
  };
44
48
  SplitsCacheInLocal.prototype._incrementCounts = function (split) {
45
49
  try {
46
- if (split) {
47
- var ttKey = this.keys.buildTrafficTypeKey(split.trafficTypeName);
50
+ var ttKey = this.keys.buildTrafficTypeKey(split.trafficTypeName);
51
+ // @ts-expect-error
52
+ localStorage.setItem(ttKey, (0, lang_1.toNumber)(localStorage.getItem(ttKey)) + 1);
53
+ if ((0, AbstractSplitsCacheSync_1.usesSegments)(split)) {
54
+ var segmentsCountKey = this.keys.buildSplitsWithSegmentCountKey();
48
55
  // @ts-expect-error
49
- localStorage.setItem(ttKey, (0, lang_1.toNumber)(localStorage.getItem(ttKey)) + 1);
50
- if ((0, AbstractSplitsCacheSync_1.usesSegments)(split)) {
51
- var segmentsCountKey = this.keys.buildSplitsWithSegmentCountKey();
52
- // @ts-expect-error
53
- localStorage.setItem(segmentsCountKey, (0, lang_1.toNumber)(localStorage.getItem(segmentsCountKey)) + 1);
54
- }
56
+ localStorage.setItem(segmentsCountKey, (0, lang_1.toNumber)(localStorage.getItem(segmentsCountKey)) + 1);
55
57
  }
56
58
  }
57
59
  catch (e) {
@@ -63,6 +65,7 @@ var SplitsCacheInLocal = /** @class */ (function (_super) {
63
65
  * We cannot simply call `localStorage.clear()` since that implies removing user items from the storage.
64
66
  */
65
67
  SplitsCacheInLocal.prototype.clear = function () {
68
+ this.log.info(constants_1.LOG_PREFIX + 'Flushing Splits data from localStorage');
66
69
  // collect item keys
67
70
  var len = localStorage.length;
68
71
  var accum = [];
@@ -77,9 +80,10 @@ var SplitsCacheInLocal = /** @class */ (function (_super) {
77
80
  });
78
81
  this.hasSync = false;
79
82
  };
80
- SplitsCacheInLocal.prototype.addSplit = function (name, split) {
83
+ SplitsCacheInLocal.prototype.addSplit = function (split) {
81
84
  try {
82
- var splitKey = this.keys.buildSplitKey(name);
85
+ var name_1 = split.name;
86
+ var splitKey = this.keys.buildSplitKey(name_1);
83
87
  var splitFromLocalStorage = localStorage.getItem(splitKey);
84
88
  var previousSplit = splitFromLocalStorage ? JSON.parse(splitFromLocalStorage) : null;
85
89
  localStorage.setItem(splitKey, JSON.stringify(split));
@@ -98,6 +102,8 @@ var SplitsCacheInLocal = /** @class */ (function (_super) {
98
102
  SplitsCacheInLocal.prototype.removeSplit = function (name) {
99
103
  try {
100
104
  var split = this.getSplit(name);
105
+ if (!split)
106
+ return false;
101
107
  localStorage.removeItem(this.keys.buildSplitKey(name));
102
108
  this._decrementCounts(split);
103
109
  if (split)
@@ -114,6 +120,18 @@ var SplitsCacheInLocal = /** @class */ (function (_super) {
114
120
  return item && JSON.parse(item);
115
121
  };
116
122
  SplitsCacheInLocal.prototype.setChangeNumber = function (changeNumber) {
123
+ // when using a new split query, we must update it at the store
124
+ if (this.updateNewFilter) {
125
+ this.log.info(constants_1.LOG_PREFIX + 'SDK key, flags filter criteria or flags spec version was modified. Updating cache');
126
+ var storageHashKey = this.keys.buildHashKey();
127
+ try {
128
+ localStorage.setItem(storageHashKey, this.storageHash);
129
+ }
130
+ catch (e) {
131
+ this.log.error(constants_1.LOG_PREFIX + e);
132
+ }
133
+ this.updateNewFilter = false;
134
+ }
117
135
  try {
118
136
  localStorage.setItem(this.keys.buildSplitsTillKey(), changeNumber + '');
119
137
  // update "last updated" timestamp with current time
@@ -157,12 +175,48 @@ var SplitsCacheInLocal = /** @class */ (function (_super) {
157
175
  return true;
158
176
  var storedCount = localStorage.getItem(this.keys.buildSplitsWithSegmentCountKey());
159
177
  var splitsWithSegmentsCount = storedCount === null ? 0 : (0, lang_1.toNumber)(storedCount);
160
- if ((0, lang_1.isFiniteNumber)(splitsWithSegmentsCount)) {
161
- return splitsWithSegmentsCount > 0;
178
+ return (0, lang_1.isFiniteNumber)(splitsWithSegmentsCount) ?
179
+ splitsWithSegmentsCount > 0 :
180
+ true;
181
+ };
182
+ /**
183
+ * Check if the splits information is already stored in browser LocalStorage.
184
+ * In this function we could add more code to check if the data is valid.
185
+ * @override
186
+ */
187
+ SplitsCacheInLocal.prototype.checkCache = function () {
188
+ return this.getChangeNumber() > -1;
189
+ };
190
+ /**
191
+ * Clean Splits cache if its `lastUpdated` timestamp is older than the given `expirationTimestamp`,
192
+ *
193
+ * @param expirationTimestamp - if the value is not a number, data will not be cleaned
194
+ */
195
+ SplitsCacheInLocal.prototype._checkExpiration = function (expirationTimestamp) {
196
+ var value = localStorage.getItem(this.keys.buildLastUpdatedKey());
197
+ if (value !== null) {
198
+ value = parseInt(value, 10);
199
+ if (!(0, lang_1.isNaNNumber)(value) && expirationTimestamp && value < expirationTimestamp)
200
+ this.clear();
162
201
  }
163
- else {
164
- return true;
202
+ };
203
+ // @TODO eventually remove `_checkFilterQuery`. Cache should be cleared at the storage level, reusing same logic than PluggableStorage
204
+ SplitsCacheInLocal.prototype._checkFilterQuery = function () {
205
+ var storageHashKey = this.keys.buildHashKey();
206
+ var storageHash = localStorage.getItem(storageHashKey);
207
+ if (storageHash !== this.storageHash) {
208
+ try {
209
+ // mark cache to update the new query filter on first successful splits fetch
210
+ this.updateNewFilter = true;
211
+ // if there is cache, clear it
212
+ if (this.checkCache())
213
+ this.clear();
214
+ }
215
+ catch (e) {
216
+ this.log.error(constants_1.LOG_PREFIX + e);
217
+ }
165
218
  }
219
+ // if the filter didn't change, nothing is done
166
220
  };
167
221
  SplitsCacheInLocal.prototype.getNamesByFlagSets = function (flagSets) {
168
222
  var _this = this;
@@ -9,13 +9,14 @@ var KeyBuilderCS_1 = require("../KeyBuilderCS");
9
9
  var isLocalStorageAvailable_1 = require("../../utils/env/isLocalStorageAvailable");
10
10
  var SplitsCacheInLocal_1 = require("./SplitsCacheInLocal");
11
11
  var MySegmentsCacheInLocal_1 = require("./MySegmentsCacheInLocal");
12
+ var browser_1 = require("../../utils/constants/browser");
12
13
  var InMemoryStorageCS_1 = require("../inMemory/InMemoryStorageCS");
13
14
  var constants_1 = require("./constants");
14
15
  var constants_2 = require("../../utils/constants");
15
16
  var TelemetryCacheInMemory_1 = require("../inMemory/TelemetryCacheInMemory");
16
17
  var UniqueKeysCacheInMemoryCS_1 = require("../inMemory/UniqueKeysCacheInMemoryCS");
17
18
  var key_1 = require("../../utils/key");
18
- var validateCache_1 = require("./validateCache");
19
+ var RBSegmentsCacheInLocal_1 = require("./RBSegmentsCacheInLocal");
19
20
  /**
20
21
  * InLocal storage factory for standalone client-side SplitFactory
21
22
  */
@@ -31,11 +32,14 @@ function InLocalStorage(options) {
31
32
  var settings = params.settings, _a = params.settings, log = _a.log, _b = _a.scheduler, impressionsQueueSize = _b.impressionsQueueSize, eventsQueueSize = _b.eventsQueueSize;
32
33
  var matchingKey = (0, key_1.getMatching)(settings.core.key);
33
34
  var keys = new KeyBuilderCS_1.KeyBuilderCS(prefix, matchingKey);
34
- var splits = new SplitsCacheInLocal_1.SplitsCacheInLocal(settings, keys);
35
+ var expirationTimestamp = Date.now() - browser_1.DEFAULT_CACHE_EXPIRATION_IN_MILLIS;
36
+ var splits = new SplitsCacheInLocal_1.SplitsCacheInLocal(settings, keys, expirationTimestamp);
37
+ var rbSegments = new RBSegmentsCacheInLocal_1.RBSegmentsCacheInLocal(settings, keys);
35
38
  var segments = new MySegmentsCacheInLocal_1.MySegmentsCacheInLocal(log, keys);
36
39
  var largeSegments = new MySegmentsCacheInLocal_1.MySegmentsCacheInLocal(log, (0, KeyBuilderCS_1.myLargeSegmentsKeyBuilder)(prefix, matchingKey));
37
40
  return {
38
41
  splits: splits,
42
+ rbSegments: rbSegments,
39
43
  segments: segments,
40
44
  largeSegments: largeSegments,
41
45
  impressions: new ImpressionsCacheInMemory_1.ImpressionsCacheInMemory(impressionsQueueSize),
@@ -43,14 +47,12 @@ function InLocalStorage(options) {
43
47
  events: new EventsCacheInMemory_1.EventsCacheInMemory(eventsQueueSize),
44
48
  telemetry: (0, TelemetryCacheInMemory_1.shouldRecordTelemetry)(params) ? new TelemetryCacheInMemory_1.TelemetryCacheInMemory(splits, segments) : undefined,
45
49
  uniqueKeys: new UniqueKeysCacheInMemoryCS_1.UniqueKeysCacheInMemoryCS(),
46
- validateCache: function () {
47
- return (0, validateCache_1.validateCache)(options, settings, keys, splits, segments, largeSegments);
48
- },
49
50
  destroy: function () { },
50
51
  // When using shared instantiation with MEMORY we reuse everything but segments (they are customer per key).
51
52
  shared: function (matchingKey) {
52
53
  return {
53
54
  splits: this.splits,
55
+ rbSegments: this.rbSegments,
54
56
  segments: new MySegmentsCacheInLocal_1.MySegmentsCacheInLocal(log, new KeyBuilderCS_1.KeyBuilderCS(prefix, matchingKey)),
55
57
  largeSegments: new MySegmentsCacheInLocal_1.MySegmentsCacheInLocal(log, (0, KeyBuilderCS_1.myLargeSegmentsKeyBuilder)(prefix, matchingKey)),
56
58
  impressions: this.impressions,
@@ -9,6 +9,7 @@ var ImpressionCountsCacheInMemory_1 = require("./ImpressionCountsCacheInMemory")
9
9
  var constants_1 = require("../../utils/constants");
10
10
  var TelemetryCacheInMemory_1 = require("./TelemetryCacheInMemory");
11
11
  var UniqueKeysCacheInMemory_1 = require("./UniqueKeysCacheInMemory");
12
+ var RBSegmentsCacheInMemory_1 = require("./RBSegmentsCacheInMemory");
12
13
  /**
13
14
  * InMemory storage factory for standalone server-side SplitFactory
14
15
  *
@@ -17,9 +18,11 @@ var UniqueKeysCacheInMemory_1 = require("./UniqueKeysCacheInMemory");
17
18
  function InMemoryStorageFactory(params) {
18
19
  var _a = params.settings, _b = _a.scheduler, impressionsQueueSize = _b.impressionsQueueSize, eventsQueueSize = _b.eventsQueueSize, __splitFiltersValidation = _a.sync.__splitFiltersValidation;
19
20
  var splits = new SplitsCacheInMemory_1.SplitsCacheInMemory(__splitFiltersValidation);
21
+ var rbSegments = new RBSegmentsCacheInMemory_1.RBSegmentsCacheInMemory();
20
22
  var segments = new SegmentsCacheInMemory_1.SegmentsCacheInMemory();
21
23
  var storage = {
22
24
  splits: splits,
25
+ rbSegments: rbSegments,
23
26
  segments: segments,
24
27
  impressions: new ImpressionsCacheInMemory_1.ImpressionsCacheInMemory(impressionsQueueSize),
25
28
  impressionCounts: new ImpressionCountsCacheInMemory_1.ImpressionCountsCacheInMemory(),
@@ -9,6 +9,7 @@ var ImpressionCountsCacheInMemory_1 = require("./ImpressionCountsCacheInMemory")
9
9
  var constants_1 = require("../../utils/constants");
10
10
  var TelemetryCacheInMemory_1 = require("./TelemetryCacheInMemory");
11
11
  var UniqueKeysCacheInMemoryCS_1 = require("./UniqueKeysCacheInMemoryCS");
12
+ var RBSegmentsCacheInMemory_1 = require("./RBSegmentsCacheInMemory");
12
13
  /**
13
14
  * InMemory storage factory for standalone client-side SplitFactory
14
15
  *
@@ -17,10 +18,12 @@ var UniqueKeysCacheInMemoryCS_1 = require("./UniqueKeysCacheInMemoryCS");
17
18
  function InMemoryStorageCSFactory(params) {
18
19
  var _a = params.settings, _b = _a.scheduler, impressionsQueueSize = _b.impressionsQueueSize, eventsQueueSize = _b.eventsQueueSize, __splitFiltersValidation = _a.sync.__splitFiltersValidation;
19
20
  var splits = new SplitsCacheInMemory_1.SplitsCacheInMemory(__splitFiltersValidation);
21
+ var rbSegments = new RBSegmentsCacheInMemory_1.RBSegmentsCacheInMemory();
20
22
  var segments = new MySegmentsCacheInMemory_1.MySegmentsCacheInMemory();
21
23
  var largeSegments = new MySegmentsCacheInMemory_1.MySegmentsCacheInMemory();
22
24
  var storage = {
23
25
  splits: splits,
26
+ rbSegments: rbSegments,
24
27
  segments: segments,
25
28
  largeSegments: largeSegments,
26
29
  impressions: new ImpressionsCacheInMemory_1.ImpressionsCacheInMemory(impressionsQueueSize),
@@ -33,6 +36,7 @@ function InMemoryStorageCSFactory(params) {
33
36
  shared: function () {
34
37
  return {
35
38
  splits: this.splits,
39
+ rbSegments: this.rbSegments,
36
40
  segments: new MySegmentsCacheInMemory_1.MySegmentsCacheInMemory(),
37
41
  largeSegments: new MySegmentsCacheInMemory_1.MySegmentsCacheInMemory(),
38
42
  impressions: this.impressions,
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RBSegmentsCacheInMemory = void 0;
4
+ var sets_1 = require("../../utils/lang/sets");
5
+ var AbstractSplitsCacheSync_1 = require("../AbstractSplitsCacheSync");
6
+ var RBSegmentsCacheInMemory = /** @class */ (function () {
7
+ function RBSegmentsCacheInMemory() {
8
+ this.cache = {};
9
+ this.changeNumber = -1;
10
+ this.segmentsCount = 0;
11
+ }
12
+ RBSegmentsCacheInMemory.prototype.clear = function () {
13
+ this.cache = {};
14
+ this.changeNumber = -1;
15
+ this.segmentsCount = 0;
16
+ };
17
+ RBSegmentsCacheInMemory.prototype.update = function (toAdd, toRemove, changeNumber) {
18
+ var _this = this;
19
+ this.changeNumber = changeNumber;
20
+ var updated = toAdd.map(function (toAdd) { return _this.add(toAdd); }).some(function (result) { return result; });
21
+ return toRemove.map(function (toRemove) { return _this.remove(toRemove.name); }).some(function (result) { return result; }) || updated;
22
+ };
23
+ RBSegmentsCacheInMemory.prototype.add = function (rbSegment) {
24
+ var name = rbSegment.name;
25
+ var previous = this.get(name);
26
+ if (previous && (0, AbstractSplitsCacheSync_1.usesSegments)(previous))
27
+ this.segmentsCount--;
28
+ this.cache[name] = rbSegment;
29
+ if ((0, AbstractSplitsCacheSync_1.usesSegments)(rbSegment))
30
+ this.segmentsCount++;
31
+ return true;
32
+ };
33
+ RBSegmentsCacheInMemory.prototype.remove = function (name) {
34
+ var rbSegment = this.get(name);
35
+ if (!rbSegment)
36
+ return false;
37
+ delete this.cache[name];
38
+ if ((0, AbstractSplitsCacheSync_1.usesSegments)(rbSegment))
39
+ this.segmentsCount--;
40
+ return true;
41
+ };
42
+ RBSegmentsCacheInMemory.prototype.getNames = function () {
43
+ return Object.keys(this.cache);
44
+ };
45
+ RBSegmentsCacheInMemory.prototype.get = function (name) {
46
+ return this.cache[name] || null;
47
+ };
48
+ RBSegmentsCacheInMemory.prototype.contains = function (names) {
49
+ var namesArray = (0, sets_1.setToArray)(names);
50
+ var namesInStorage = this.getNames();
51
+ return namesArray.every(function (name) { return namesInStorage.indexOf(name) !== -1; });
52
+ };
53
+ RBSegmentsCacheInMemory.prototype.getChangeNumber = function () {
54
+ return this.changeNumber;
55
+ };
56
+ RBSegmentsCacheInMemory.prototype.usesSegments = function () {
57
+ return this.segmentsCount > 0;
58
+ };
59
+ return RBSegmentsCacheInMemory;
60
+ }());
61
+ exports.RBSegmentsCacheInMemory = RBSegmentsCacheInMemory;
@@ -25,7 +25,8 @@ var SplitsCacheInMemory = /** @class */ (function (_super) {
25
25
  this.changeNumber = -1;
26
26
  this.segmentsCount = 0;
27
27
  };
28
- SplitsCacheInMemory.prototype.addSplit = function (name, split) {
28
+ SplitsCacheInMemory.prototype.addSplit = function (split) {
29
+ var name = split.name;
29
30
  var previousSplit = this.getSplit(name);
30
31
  if (previousSplit) { // We had this Split already
31
32
  var previousTtName = previousSplit.trafficTypeName;
@@ -37,40 +38,32 @@ var SplitsCacheInMemory = /** @class */ (function (_super) {
37
38
  if ((0, AbstractSplitsCacheSync_1.usesSegments)(previousSplit))
38
39
  this.segmentsCount--;
39
40
  }
40
- if (split) {
41
- // Store the Split.
42
- this.splitsCache[name] = split;
43
- // Update TT cache
44
- var ttName = split.trafficTypeName;
45
- this.ttCache[ttName] = (this.ttCache[ttName] || 0) + 1;
46
- this.addToFlagSets(split);
47
- // Add to segments count for the new version of the Split
48
- if ((0, AbstractSplitsCacheSync_1.usesSegments)(split))
49
- this.segmentsCount++;
50
- return true;
51
- }
52
- else {
53
- return false;
54
- }
41
+ // Store the Split.
42
+ this.splitsCache[name] = split;
43
+ // Update TT cache
44
+ var ttName = split.trafficTypeName;
45
+ this.ttCache[ttName] = (this.ttCache[ttName] || 0) + 1;
46
+ this.addToFlagSets(split);
47
+ // Add to segments count for the new version of the Split
48
+ if ((0, AbstractSplitsCacheSync_1.usesSegments)(split))
49
+ this.segmentsCount++;
50
+ return true;
55
51
  };
56
52
  SplitsCacheInMemory.prototype.removeSplit = function (name) {
57
53
  var split = this.getSplit(name);
58
- if (split) {
59
- // Delete the Split
60
- delete this.splitsCache[name];
61
- var ttName = split.trafficTypeName;
62
- this.ttCache[ttName]--; // Update tt cache
63
- if (!this.ttCache[ttName])
64
- delete this.ttCache[ttName];
65
- this.removeFromFlagSets(split.name, split.sets);
66
- // Update the segments count.
67
- if ((0, AbstractSplitsCacheSync_1.usesSegments)(split))
68
- this.segmentsCount--;
69
- return true;
70
- }
71
- else {
54
+ if (!split)
72
55
  return false;
73
- }
56
+ // Delete the Split
57
+ delete this.splitsCache[name];
58
+ var ttName = split.trafficTypeName;
59
+ this.ttCache[ttName]--; // Update tt cache
60
+ if (!this.ttCache[ttName])
61
+ delete this.ttCache[ttName];
62
+ this.removeFromFlagSets(split.name, split.sets);
63
+ // Update the segments count.
64
+ if ((0, AbstractSplitsCacheSync_1.usesSegments)(split))
65
+ this.segmentsCount--;
66
+ return true;
74
67
  };
75
68
  SplitsCacheInMemory.prototype.getSplit = function (name) {
76
69
  return this.splitsCache[name] || null;
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RBSegmentsCacheInRedis = void 0;
4
+ var lang_1 = require("../../utils/lang");
5
+ var constants_1 = require("./constants");
6
+ var sets_1 = require("../../utils/lang/sets");
7
+ var RBSegmentsCacheInRedis = /** @class */ (function () {
8
+ function RBSegmentsCacheInRedis(log, keys, redis) {
9
+ this.log = log;
10
+ this.keys = keys;
11
+ this.redis = redis;
12
+ }
13
+ RBSegmentsCacheInRedis.prototype.get = function (name) {
14
+ return this.redis.get(this.keys.buildRBSegmentKey(name))
15
+ .then(function (maybeRBSegment) { return maybeRBSegment && JSON.parse(maybeRBSegment); });
16
+ };
17
+ RBSegmentsCacheInRedis.prototype.getNames = function () {
18
+ var _this = this;
19
+ return this.redis.keys(this.keys.searchPatternForRBSegmentKeys()).then(function (listOfKeys) { return listOfKeys.map(_this.keys.extractKey); });
20
+ };
21
+ RBSegmentsCacheInRedis.prototype.contains = function (names) {
22
+ var namesArray = (0, sets_1.setToArray)(names);
23
+ return this.getNames().then(function (namesInStorage) {
24
+ return namesArray.every(function (name) { return namesInStorage.includes(name); });
25
+ });
26
+ };
27
+ RBSegmentsCacheInRedis.prototype.update = function (toAdd, toRemove, changeNumber) {
28
+ var _this = this;
29
+ return Promise.all([
30
+ this.setChangeNumber(changeNumber),
31
+ Promise.all(toAdd.map(function (toAdd) {
32
+ var key = _this.keys.buildRBSegmentKey(toAdd.name);
33
+ var stringifiedNewRBSegment = JSON.stringify(toAdd);
34
+ return _this.redis.set(key, stringifiedNewRBSegment).then(function () { return true; });
35
+ })),
36
+ Promise.all(toRemove.map(function (toRemove) {
37
+ var key = _this.keys.buildRBSegmentKey(toRemove.name);
38
+ return _this.redis.del(key).then(function (status) { return status === 1; });
39
+ }))
40
+ ]).then(function (_a) {
41
+ var added = _a[1], removed = _a[2];
42
+ return added.some(function (result) { return result; }) || removed.some(function (result) { return result; });
43
+ });
44
+ };
45
+ RBSegmentsCacheInRedis.prototype.setChangeNumber = function (changeNumber) {
46
+ return this.redis.set(this.keys.buildRBSegmentsTillKey(), changeNumber + '').then(function (status) { return status === 'OK'; });
47
+ };
48
+ RBSegmentsCacheInRedis.prototype.getChangeNumber = function () {
49
+ var _this = this;
50
+ return this.redis.get(this.keys.buildRBSegmentsTillKey()).then(function (value) {
51
+ var i = parseInt(value, 10);
52
+ return (0, lang_1.isNaNNumber)(i) ? -1 : i;
53
+ }).catch(function (e) {
54
+ _this.log.error(constants_1.LOG_PREFIX + 'Could not retrieve changeNumber from storage. Error: ' + e);
55
+ return -1;
56
+ });
57
+ };
58
+ // @TODO implement if required by DataLoader or producer mode
59
+ RBSegmentsCacheInRedis.prototype.clear = function () {
60
+ return Promise.resolve();
61
+ };
62
+ return RBSegmentsCacheInRedis;
63
+ }());
64
+ exports.RBSegmentsCacheInRedis = RBSegmentsCacheInRedis;
@@ -67,8 +67,9 @@ var SplitsCacheInRedis = /** @class */ (function (_super) {
67
67
  * The returned promise is resolved when the operation success
68
68
  * or rejected if it fails (e.g., redis operation fails)
69
69
  */
70
- SplitsCacheInRedis.prototype.addSplit = function (name, split) {
70
+ SplitsCacheInRedis.prototype.addSplit = function (split) {
71
71
  var _this = this;
72
+ var name = split.name;
72
73
  var splitKey = this.keys.buildSplitKey(name);
73
74
  return this.redis.get(splitKey).then(function (splitFromStorage) {
74
75
  // handling parsing error
@@ -92,18 +93,9 @@ var SplitsCacheInRedis = /** @class */ (function (_super) {
92
93
  }).then(function () { return _this._updateFlagSets(name, parsedPreviousSplit && parsedPreviousSplit.sets, split.sets); });
93
94
  }).then(function () { return true; });
94
95
  };
95
- /**
96
- * Add a list of splits.
97
- * The returned promise is resolved when the operation success
98
- * or rejected if it fails (e.g., redis operation fails)
99
- */
100
- SplitsCacheInRedis.prototype.addSplits = function (entries) {
101
- var _this = this;
102
- return Promise.all(entries.map(function (keyValuePair) { return _this.addSplit(keyValuePair[0], keyValuePair[1]); }));
103
- };
104
96
  /**
105
97
  * Remove a given split.
106
- * The returned promise is resolved when the operation success, with 1 or 0 indicating if the split existed or not.
98
+ * The returned promise is resolved when the operation success, with true or false indicating if the split existed (and was removed) or not.
107
99
  * or rejected if it fails (e.g., redis operation fails).
108
100
  */
109
101
  SplitsCacheInRedis.prototype.removeSplit = function (name) {
@@ -113,18 +105,9 @@ var SplitsCacheInRedis = /** @class */ (function (_super) {
113
105
  return _this._decrementCounts(split).then(function () { return _this._updateFlagSets(name, split.sets); });
114
106
  }
115
107
  }).then(function () {
116
- return _this.redis.del(_this.keys.buildSplitKey(name));
108
+ return _this.redis.del(_this.keys.buildSplitKey(name)).then(function (status) { return status === 1; });
117
109
  });
118
110
  };
119
- /**
120
- * Remove a list of splits.
121
- * The returned promise is resolved when the operation success,
122
- * or rejected if it fails (e.g., redis operation fails).
123
- */
124
- SplitsCacheInRedis.prototype.removeSplits = function (names) {
125
- var _this = this;
126
- return Promise.all(names.map(function (name) { return _this.removeSplit(name); }));
127
- };
128
111
  /**
129
112
  * Get split definition or null if it's not defined.
130
113
  * Returned promise is rejected if redis operation fails.
@@ -3,5 +3,5 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.TTL_REFRESH = exports.REFRESH_RATE = exports.DEFAULT_CACHE_SIZE = exports.LOG_PREFIX = void 0;
4
4
  exports.LOG_PREFIX = 'storage:redis: ';
5
5
  exports.DEFAULT_CACHE_SIZE = 30000;
6
- exports.REFRESH_RATE = 300000; // 300.000 ms = start after 5 mins
6
+ exports.REFRESH_RATE = 300000; // 300000 ms = start after 5 mins
7
7
  exports.TTL_REFRESH = 3600; // 1hr
@@ -12,6 +12,7 @@ var TelemetryCacheInRedis_1 = require("./TelemetryCacheInRedis");
12
12
  var UniqueKeysCacheInRedis_1 = require("./UniqueKeysCacheInRedis");
13
13
  var ImpressionCountsCacheInRedis_1 = require("./ImpressionCountsCacheInRedis");
14
14
  var utils_1 = require("../utils");
15
+ var RBSegmentsCacheInRedis_1 = require("./RBSegmentsCacheInRedis");
15
16
  /**
16
17
  * InRedis storage factory for consumer server-side SplitFactory, that uses `Ioredis` Redis client for Node.js
17
18
  * @see {@link https://www.npmjs.com/package/ioredis}
@@ -40,6 +41,7 @@ function InRedisStorage(options) {
40
41
  });
41
42
  return {
42
43
  splits: new SplitsCacheInRedis_1.SplitsCacheInRedis(log, keys, redisClient, settings.sync.__splitFiltersValidation),
44
+ rbSegments: new RBSegmentsCacheInRedis_1.RBSegmentsCacheInRedis(log, keys, redisClient),
43
45
  segments: new SegmentsCacheInRedis_1.SegmentsCacheInRedis(log, keys, redisClient),
44
46
  impressions: new ImpressionsCacheInRedis_1.ImpressionsCacheInRedis(log, keys.buildImpressionsKey(), redisClient, metadata),
45
47
  impressionCounts: impressionCountsCache,