@splitsoftware/splitio-commons 1.17.1-rc.4 → 1.17.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.
Files changed (261) hide show
  1. package/CHANGES.txt +28 -29
  2. package/LICENSE +1 -1
  3. package/README.md +4 -3
  4. package/cjs/consent/sdkUserConsent.js +4 -2
  5. package/cjs/evaluator/matchers/index.js +1 -3
  6. package/cjs/evaluator/matchers/matcherTypes.js +0 -1
  7. package/cjs/evaluator/matchers/segment.js +0 -6
  8. package/cjs/evaluator/matchersTransform/index.js +1 -4
  9. package/cjs/evaluator/matchersTransform/segment.js +1 -3
  10. package/cjs/logger/constants.js +2 -2
  11. package/cjs/logger/messages/info.js +1 -1
  12. package/cjs/logger/messages/warn.js +1 -1
  13. package/cjs/readiness/readinessManager.js +8 -18
  14. package/cjs/readiness/sdkReadinessManager.js +6 -5
  15. package/cjs/sdkClient/sdkClient.js +5 -5
  16. package/cjs/sdkClient/sdkClientMethod.js +1 -3
  17. package/cjs/sdkClient/sdkClientMethodCS.js +15 -9
  18. package/cjs/sdkClient/sdkClientMethodCSWithTT.js +15 -9
  19. package/cjs/sdkFactory/index.js +10 -32
  20. package/cjs/services/decorateHeaders.js +6 -1
  21. package/cjs/services/splitApi.js +5 -5
  22. package/cjs/services/splitHttpClient.js +5 -2
  23. package/cjs/storages/AbstractSegmentsCacheSync.js +33 -0
  24. package/cjs/storages/AbstractSplitsCacheSync.js +1 -2
  25. package/cjs/storages/KeyBuilderCS.js +5 -23
  26. package/cjs/storages/dataLoader.js +1 -1
  27. package/cjs/storages/inLocalStorage/MySegmentsCacheInLocal.js +56 -33
  28. package/cjs/storages/inLocalStorage/index.js +2 -6
  29. package/cjs/storages/inMemory/InMemoryStorageCS.js +1 -6
  30. package/cjs/storages/inMemory/MySegmentsCacheInMemory.js +44 -13
  31. package/cjs/storages/inMemory/SegmentsCacheInMemory.js +28 -14
  32. package/cjs/storages/inMemory/SplitsCacheInMemory.js +9 -8
  33. package/cjs/storages/inMemory/TelemetryCacheInMemory.js +10 -7
  34. package/cjs/storages/inRedis/SegmentsCacheInRedis.js +21 -15
  35. package/cjs/storages/inRedis/index.js +11 -5
  36. package/cjs/storages/pluggable/SegmentsCachePluggable.js +34 -13
  37. package/cjs/storages/pluggable/inMemoryWrapper.js +1 -1
  38. package/cjs/sync/offline/syncManagerOffline.js +11 -18
  39. package/cjs/sync/polling/fetchers/mySegmentsFetcher.js +8 -5
  40. package/cjs/sync/polling/fetchers/segmentChangesFetcher.js +1 -1
  41. package/cjs/sync/polling/pollingManagerCS.js +1 -1
  42. package/cjs/sync/polling/syncTasks/mySegmentsSyncTask.js +2 -2
  43. package/cjs/sync/polling/updaters/mySegmentsUpdater.js +21 -15
  44. package/cjs/sync/polling/updaters/segmentChangesUpdater.js +28 -12
  45. package/cjs/sync/polling/updaters/splitChangesUpdater.js +1 -1
  46. package/cjs/sync/streaming/AuthClient/index.js +1 -1
  47. package/cjs/sync/streaming/SSEHandler/index.js +5 -3
  48. package/cjs/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.js +48 -107
  49. package/cjs/sync/streaming/UpdateWorkers/SegmentsUpdateWorker.js +3 -3
  50. package/cjs/sync/streaming/constants.js +3 -3
  51. package/cjs/sync/streaming/parseUtils.js +9 -14
  52. package/cjs/sync/streaming/pushManager.js +67 -69
  53. package/cjs/sync/syncManagerOnline.js +21 -20
  54. package/cjs/sync/syncTask.js +2 -2
  55. package/cjs/trackers/eventTracker.js +10 -12
  56. package/cjs/trackers/impressionsTracker.js +14 -16
  57. package/cjs/trackers/uniqueKeysTracker.js +3 -5
  58. package/cjs/utils/constants/index.js +4 -5
  59. package/cjs/utils/settingsValidation/index.js +1 -2
  60. package/esm/consent/sdkUserConsent.js +4 -2
  61. package/esm/evaluator/matchers/index.js +1 -3
  62. package/esm/evaluator/matchers/matcherTypes.js +0 -1
  63. package/esm/evaluator/matchers/segment.js +0 -6
  64. package/esm/evaluator/matchersTransform/index.js +1 -4
  65. package/esm/evaluator/matchersTransform/segment.js +1 -3
  66. package/esm/logger/constants.js +1 -1
  67. package/esm/logger/messages/info.js +1 -1
  68. package/esm/logger/messages/warn.js +1 -1
  69. package/esm/readiness/readinessManager.js +8 -18
  70. package/esm/readiness/sdkReadinessManager.js +6 -5
  71. package/esm/sdkClient/sdkClient.js +5 -5
  72. package/esm/sdkClient/sdkClientMethod.js +1 -3
  73. package/esm/sdkClient/sdkClientMethodCS.js +13 -7
  74. package/esm/sdkClient/sdkClientMethodCSWithTT.js +13 -7
  75. package/esm/sdkFactory/index.js +10 -32
  76. package/esm/services/decorateHeaders.js +4 -0
  77. package/esm/services/splitApi.js +6 -6
  78. package/esm/services/splitHttpClient.js +6 -3
  79. package/esm/storages/AbstractSegmentsCacheSync.js +30 -0
  80. package/esm/storages/AbstractSplitsCacheSync.js +2 -3
  81. package/esm/storages/KeyBuilderCS.js +4 -21
  82. package/esm/storages/dataLoader.js +1 -1
  83. package/esm/storages/inLocalStorage/MySegmentsCacheInLocal.js +56 -33
  84. package/esm/storages/inLocalStorage/index.js +3 -7
  85. package/esm/storages/inMemory/InMemoryStorageCS.js +1 -6
  86. package/esm/storages/inMemory/MySegmentsCacheInMemory.js +44 -13
  87. package/esm/storages/inMemory/SegmentsCacheInMemory.js +28 -14
  88. package/esm/storages/inMemory/SplitsCacheInMemory.js +9 -8
  89. package/esm/storages/inMemory/TelemetryCacheInMemory.js +10 -7
  90. package/esm/storages/inRedis/SegmentsCacheInRedis.js +21 -15
  91. package/esm/storages/inRedis/index.js +11 -5
  92. package/esm/storages/pluggable/SegmentsCachePluggable.js +34 -13
  93. package/esm/storages/pluggable/inMemoryWrapper.js +1 -1
  94. package/esm/sync/offline/syncManagerOffline.js +11 -18
  95. package/esm/sync/polling/fetchers/mySegmentsFetcher.js +8 -5
  96. package/esm/sync/polling/fetchers/segmentChangesFetcher.js +1 -1
  97. package/esm/sync/polling/pollingManagerCS.js +1 -1
  98. package/esm/sync/polling/syncTasks/mySegmentsSyncTask.js +2 -2
  99. package/esm/sync/polling/updaters/mySegmentsUpdater.js +21 -15
  100. package/esm/sync/polling/updaters/segmentChangesUpdater.js +28 -12
  101. package/esm/sync/polling/updaters/splitChangesUpdater.js +1 -1
  102. package/esm/sync/streaming/AuthClient/index.js +1 -1
  103. package/esm/sync/streaming/SSEHandler/index.js +6 -4
  104. package/esm/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.js +49 -108
  105. package/esm/sync/streaming/UpdateWorkers/SegmentsUpdateWorker.js +3 -3
  106. package/esm/sync/streaming/constants.js +2 -2
  107. package/esm/sync/streaming/parseUtils.js +8 -12
  108. package/esm/sync/streaming/pushManager.js +70 -72
  109. package/esm/sync/syncManagerOnline.js +21 -20
  110. package/esm/sync/syncTask.js +2 -2
  111. package/esm/trackers/eventTracker.js +10 -12
  112. package/esm/trackers/impressionsTracker.js +14 -16
  113. package/esm/trackers/uniqueKeysTracker.js +3 -5
  114. package/esm/utils/constants/index.js +2 -3
  115. package/esm/utils/settingsValidation/index.js +1 -2
  116. package/package.json +1 -1
  117. package/src/consent/sdkUserConsent.ts +3 -2
  118. package/src/dtos/types.ts +7 -21
  119. package/src/evaluator/matchers/index.ts +0 -2
  120. package/src/evaluator/matchers/matcherTypes.ts +0 -1
  121. package/src/evaluator/matchers/segment.ts +0 -7
  122. package/src/evaluator/matchersTransform/index.ts +1 -4
  123. package/src/evaluator/matchersTransform/segment.ts +3 -5
  124. package/src/logger/constants.ts +1 -1
  125. package/src/logger/messages/info.ts +1 -1
  126. package/src/logger/messages/warn.ts +1 -1
  127. package/src/readiness/readinessManager.ts +8 -19
  128. package/src/readiness/sdkReadinessManager.ts +7 -7
  129. package/src/readiness/types.ts +2 -5
  130. package/src/sdkClient/sdkClient.ts +5 -5
  131. package/src/sdkClient/sdkClientMethod.ts +1 -4
  132. package/src/sdkClient/sdkClientMethodCS.ts +15 -7
  133. package/src/sdkClient/sdkClientMethodCSWithTT.ts +15 -7
  134. package/src/sdkFactory/index.ts +12 -35
  135. package/src/sdkFactory/types.ts +1 -4
  136. package/src/services/decorateHeaders.ts +5 -0
  137. package/src/services/splitApi.ts +7 -7
  138. package/src/services/splitHttpClient.ts +7 -4
  139. package/src/services/types.ts +2 -2
  140. package/src/storages/AbstractSegmentsCacheSync.ts +68 -0
  141. package/src/storages/AbstractSplitsCacheSync.ts +3 -4
  142. package/src/storages/KeyBuilderCS.ts +5 -34
  143. package/src/storages/dataLoader.ts +1 -1
  144. package/src/storages/inLocalStorage/MySegmentsCacheInLocal.ts +63 -33
  145. package/src/storages/inLocalStorage/index.ts +4 -8
  146. package/src/storages/inMemory/InMemoryStorageCS.ts +1 -6
  147. package/src/storages/inMemory/MySegmentsCacheInMemory.ts +47 -13
  148. package/src/storages/inMemory/SegmentsCacheInMemory.ts +27 -13
  149. package/src/storages/inMemory/SplitsCacheInMemory.ts +9 -7
  150. package/src/storages/inMemory/TelemetryCacheInMemory.ts +11 -7
  151. package/src/storages/inRedis/SegmentsCacheInRedis.ts +24 -15
  152. package/src/storages/inRedis/index.ts +12 -6
  153. package/src/storages/pluggable/SegmentsCachePluggable.ts +37 -13
  154. package/src/storages/pluggable/inMemoryWrapper.ts +1 -1
  155. package/src/storages/types.ts +17 -15
  156. package/src/sync/offline/syncManagerOffline.ts +13 -21
  157. package/src/sync/polling/fetchers/mySegmentsFetcher.ts +10 -8
  158. package/src/sync/polling/fetchers/segmentChangesFetcher.ts +1 -1
  159. package/src/sync/polling/fetchers/types.ts +2 -3
  160. package/src/sync/polling/pollingManagerCS.ts +4 -4
  161. package/src/sync/polling/syncTasks/mySegmentsSyncTask.ts +5 -4
  162. package/src/sync/polling/types.ts +6 -7
  163. package/src/sync/polling/updaters/mySegmentsUpdater.ts +22 -19
  164. package/src/sync/polling/updaters/segmentChangesUpdater.ts +29 -13
  165. package/src/sync/polling/updaters/splitChangesUpdater.ts +1 -1
  166. package/src/sync/streaming/AuthClient/index.ts +1 -1
  167. package/src/sync/streaming/SSEClient/index.ts +6 -4
  168. package/src/sync/streaming/SSEHandler/index.ts +8 -5
  169. package/src/sync/streaming/SSEHandler/types.ts +15 -15
  170. package/src/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.ts +49 -116
  171. package/src/sync/streaming/UpdateWorkers/SegmentsUpdateWorker.ts +4 -4
  172. package/src/sync/streaming/UpdateWorkers/SplitsUpdateWorker.ts +1 -1
  173. package/src/sync/streaming/UpdateWorkers/types.ts +2 -2
  174. package/src/sync/streaming/constants.ts +2 -2
  175. package/src/sync/streaming/parseUtils.ts +11 -19
  176. package/src/sync/streaming/pushManager.ts +72 -73
  177. package/src/sync/streaming/types.ts +10 -10
  178. package/src/sync/submitters/types.ts +5 -8
  179. package/src/sync/syncManagerOnline.ts +17 -17
  180. package/src/sync/syncTask.ts +2 -2
  181. package/src/sync/types.ts +1 -1
  182. package/src/trackers/eventTracker.ts +8 -11
  183. package/src/trackers/impressionsTracker.ts +10 -13
  184. package/src/trackers/types.ts +0 -1
  185. package/src/trackers/uniqueKeysTracker.ts +4 -6
  186. package/src/types.ts +1 -7
  187. package/src/utils/constants/index.ts +2 -3
  188. package/src/utils/settingsValidation/index.ts +2 -3
  189. package/src/utils/settingsValidation/types.ts +1 -1
  190. package/types/dtos/types.d.ts +7 -18
  191. package/types/evaluator/matchersTransform/segment.d.ts +2 -2
  192. package/types/logger/constants.d.ts +1 -1
  193. package/types/readiness/readinessManager.d.ts +2 -2
  194. package/types/readiness/sdkReadinessManager.d.ts +3 -2
  195. package/types/readiness/types.d.ts +2 -5
  196. package/types/sdkClient/sdkClientMethod.d.ts +1 -1
  197. package/types/sdkFactory/types.d.ts +1 -3
  198. package/types/services/decorateHeaders.d.ts +1 -0
  199. package/types/services/splitApi.d.ts +1 -1
  200. package/types/services/splitHttpClient.d.ts +1 -1
  201. package/types/services/types.d.ts +2 -2
  202. package/types/storages/AbstractSegmentsCacheSync.d.ts +11 -9
  203. package/types/storages/AbstractSplitsCacheSync.d.ts +1 -1
  204. package/types/storages/KeyBuilderCS.d.ts +2 -9
  205. package/types/storages/inLocalStorage/MySegmentsCacheInLocal.d.ts +18 -8
  206. package/types/storages/inMemory/MySegmentsCacheInMemory.d.ts +13 -7
  207. package/types/storages/inMemory/SegmentsCacheInMemory.d.ts +8 -6
  208. package/types/storages/inMemory/SplitsCacheInMemory.d.ts +2 -1
  209. package/types/storages/inMemory/TelemetryCacheInMemory.d.ts +6 -4
  210. package/types/storages/inRedis/SegmentsCacheInRedis.d.ts +4 -7
  211. package/types/storages/inRedis/index.d.ts +1 -1
  212. package/types/storages/pluggable/SegmentsCachePluggable.d.ts +17 -5
  213. package/types/storages/pluggable/inMemoryWrapper.d.ts +1 -1
  214. package/types/storages/types.d.ts +15 -11
  215. package/types/sync/polling/fetchers/mySegmentsFetcher.d.ts +2 -2
  216. package/types/sync/polling/fetchers/types.d.ts +2 -2
  217. package/types/sync/polling/syncTasks/mySegmentsSyncTask.d.ts +2 -2
  218. package/types/sync/polling/types.d.ts +4 -7
  219. package/types/sync/polling/updaters/mySegmentsUpdater.d.ts +3 -4
  220. package/types/sync/streaming/SSEHandler/types.d.ts +14 -16
  221. package/types/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.d.ts +2 -4
  222. package/types/sync/streaming/UpdateWorkers/SegmentsUpdateWorker.d.ts +1 -2
  223. package/types/sync/streaming/UpdateWorkers/SplitsUpdateWorker.d.ts +2 -3
  224. package/types/sync/streaming/UpdateWorkers/types.d.ts +2 -2
  225. package/types/sync/streaming/constants.d.ts +2 -2
  226. package/types/sync/streaming/parseUtils.d.ts +5 -4
  227. package/types/sync/streaming/types.d.ts +8 -8
  228. package/types/sync/submitters/types.d.ts +4 -7
  229. package/types/sync/types.d.ts +1 -1
  230. package/types/trackers/eventTracker.d.ts +1 -1
  231. package/types/trackers/impressionsTracker.d.ts +1 -1
  232. package/types/trackers/types.d.ts +0 -1
  233. package/types/types.d.ts +1 -7
  234. package/types/utils/constants/index.d.ts +2 -3
  235. package/types/utils/settingsValidation/types.d.ts +1 -1
  236. package/cjs/evaluator/matchers/large_segment.js +0 -16
  237. package/cjs/sdkClient/identity.js +0 -7
  238. package/cjs/storages/AbstractMySegmentsCacheSync.js +0 -60
  239. package/esm/evaluator/matchers/large_segment.js +0 -12
  240. package/esm/sdkClient/identity.js +0 -3
  241. package/esm/storages/AbstractMySegmentsCacheSync.js +0 -57
  242. package/src/evaluator/matchers/large_segment.ts +0 -18
  243. package/src/sdkClient/identity.ts +0 -5
  244. package/src/storages/AbstractMySegmentsCacheSync.ts +0 -94
  245. package/types/evaluator/matchers/large_segment.d.ts +0 -5
  246. package/types/evaluator/matchers/sember_inlist.d.ts +0 -3
  247. package/types/evaluator/matchersTransform/set.d.ts +0 -5
  248. package/types/evaluator/matchersTransform/string.d.ts +0 -7
  249. package/types/sdkClient/identity.d.ts +0 -2
  250. package/types/storages/AbstractMySegmentsCacheSync.d.ts +0 -39
  251. package/types/storages/AbstractSplitsCache.d.ts +0 -46
  252. package/types/sync/streaming/mySegmentsV2utils.d.ts +0 -27
  253. package/types/sync/streaming/pushManagerCS_Spec1_3.d.ts +0 -9
  254. package/types/sync/streaming/pushManager_Spec1_3.d.ts +0 -9
  255. package/types/trackers/impressionObserver/utils.d.ts +0 -5
  256. package/types/utils/inputValidation/sdkKey.d.ts +0 -7
  257. package/types/utils/inputValidation/splitExistance.d.ts +0 -7
  258. package/types/utils/inputValidation/trafficTypeExistance.d.ts +0 -9
  259. package/types/utils/redis/RedisMock.d.ts +0 -4
  260. package/types/utils/settingsValidation/logger/globalLogLevel.d.ts +0 -8
  261. /package/types/utils/{semVer.d.ts → Semver.d.ts} +0 -0
@@ -1,14 +1,7 @@
1
1
  import { startsWith } from '../utils/lang';
2
2
  import { KeyBuilder } from './KeyBuilder';
3
3
 
4
- export interface MySegmentsKeyBuilder {
5
- buildSegmentNameKey(segmentName: string): string;
6
- extractSegmentName(builtSegmentKeyName: string): string | undefined;
7
- extractOldSegmentKey(builtSegmentKeyName: string): string | undefined;
8
- buildTillKey(): string;
9
- }
10
-
11
- export class KeyBuilderCS extends KeyBuilder implements MySegmentsKeyBuilder {
4
+ export class KeyBuilderCS extends KeyBuilder {
12
5
 
13
6
  protected readonly regexSplitsCacheKey: RegExp;
14
7
  protected readonly matchingKey: string;
@@ -33,6 +26,10 @@ export class KeyBuilderCS extends KeyBuilder implements MySegmentsKeyBuilder {
33
26
  return builtSegmentKeyName.substr(prefix.length);
34
27
  }
35
28
 
29
+ // @BREAKING: The key used to start with the matching key instead of the prefix, this was changed on version 10.17.3
30
+ buildOldSegmentNameKey(segmentName: string) {
31
+ return `${this.matchingKey}.${this.prefix}.segment.${segmentName}`;
32
+ }
36
33
  // @BREAKING: The key used to start with the matching key instead of the prefix, this was changed on version 10.17.3
37
34
  extractOldSegmentKey(builtSegmentKeyName: string) {
38
35
  const prefix = `${this.matchingKey}.${this.prefix}.segment.`;
@@ -48,30 +45,4 @@ export class KeyBuilderCS extends KeyBuilder implements MySegmentsKeyBuilder {
48
45
  isSplitsCacheKey(key: string) {
49
46
  return this.regexSplitsCacheKey.test(key);
50
47
  }
51
-
52
- buildTillKey() {
53
- return `${this.prefix}.${this.matchingKey}.segments.till`;
54
- }
55
- }
56
-
57
- export function myLargeSegmentsKeyBuilder(prefix: string, matchingKey: string): MySegmentsKeyBuilder {
58
- return {
59
- buildSegmentNameKey(segmentName: string) {
60
- return `${prefix}.${matchingKey}.largeSegment.${segmentName}`;
61
- },
62
-
63
- extractSegmentName(builtSegmentKeyName: string) {
64
- const p = `${prefix}.${matchingKey}.largeSegment.`;
65
-
66
- if (startsWith(builtSegmentKeyName, p)) return builtSegmentKeyName.substr(p.length);
67
- },
68
-
69
- extractOldSegmentKey() {
70
- return undefined;
71
- },
72
-
73
- buildTillKey() {
74
- return `${prefix}.${matchingKey}.largeSegments.till`;
75
- }
76
- };
77
48
  }
@@ -50,6 +50,6 @@ export function dataLoaderFactory(preloadedData: SplitIO.PreloadedData): DataLoa
50
50
  return Array.isArray(userIds) && userIds.indexOf(userId) > -1;
51
51
  });
52
52
  }
53
- storage.segments.resetSegments({ k: mySegmentsData.map(s => ({ n: s })) });
53
+ storage.segments.resetSegments(mySegmentsData);
54
54
  };
55
55
  }
@@ -1,26 +1,36 @@
1
1
  import { ILogger } from '../../logger/types';
2
- import { isNaNNumber } from '../../utils/lang';
3
- import { AbstractMySegmentsCacheSync } from '../AbstractMySegmentsCacheSync';
4
- import type { MySegmentsKeyBuilder } from '../KeyBuilderCS';
2
+ import { AbstractSegmentsCacheSync } from '../AbstractSegmentsCacheSync';
3
+ import { KeyBuilderCS } from '../KeyBuilderCS';
5
4
  import { LOG_PREFIX, DEFINED } from './constants';
6
5
 
7
- export class MySegmentsCacheInLocal extends AbstractMySegmentsCacheSync {
6
+ export class MySegmentsCacheInLocal extends AbstractSegmentsCacheSync {
8
7
 
9
- private readonly keys: MySegmentsKeyBuilder;
8
+ private readonly keys: KeyBuilderCS;
10
9
  private readonly log: ILogger;
11
10
 
12
- constructor(log: ILogger, keys: MySegmentsKeyBuilder) {
11
+ constructor(log: ILogger, keys: KeyBuilderCS) {
13
12
  super();
14
13
  this.log = log;
15
14
  this.keys = keys;
16
15
  // There is not need to flush segments cache like splits cache, since resetSegments receives the up-to-date list of active segments
17
16
  }
18
17
 
19
- protected addSegment(name: string): boolean {
18
+ /**
19
+ * Removes list of segments from localStorage
20
+ * @NOTE this method is not being used at the moment.
21
+ */
22
+ clear() {
23
+ this.log.info(LOG_PREFIX + 'Flushing MySegments data from localStorage');
24
+
25
+ // We cannot simply call `localStorage.clear()` since that implies removing user items from the storage
26
+ // We could optimize next sentence, since it implies iterating over all localStorage items
27
+ this.resetSegments([]);
28
+ }
29
+
30
+ addToSegment(name: string): boolean {
20
31
  const segmentKey = this.keys.buildSegmentNameKey(name);
21
32
 
22
33
  try {
23
- if (localStorage.getItem(segmentKey) === DEFINED) return false;
24
34
  localStorage.setItem(segmentKey, DEFINED);
25
35
  return true;
26
36
  } catch (e) {
@@ -29,11 +39,10 @@ export class MySegmentsCacheInLocal extends AbstractMySegmentsCacheSync {
29
39
  }
30
40
  }
31
41
 
32
- protected removeSegment(name: string): boolean {
42
+ removeFromSegment(name: string): boolean {
33
43
  const segmentKey = this.keys.buildSegmentNameKey(name);
34
44
 
35
45
  try {
36
- if (localStorage.getItem(segmentKey) !== DEFINED) return false;
37
46
  localStorage.removeItem(segmentKey);
38
47
  return true;
39
48
  } catch (e) {
@@ -46,22 +55,31 @@ export class MySegmentsCacheInLocal extends AbstractMySegmentsCacheSync {
46
55
  return localStorage.getItem(this.keys.buildSegmentNameKey(name)) === DEFINED;
47
56
  }
48
57
 
49
- getRegisteredSegments(): string[] {
58
+ /**
59
+ * Reset (update) the cached list of segments with the given list, removing and adding segments if necessary.
60
+ *
61
+ * @param {string[]} segmentNames list of segment names
62
+ * @returns boolean indicating if the cache was updated (i.e., given list was different from the cached one)
63
+ */
64
+ resetSegments(names: string[]): boolean {
65
+ let isDiff = false;
66
+ let index;
67
+
50
68
  // Scan current values from localStorage
51
- return Object.keys(localStorage).reduce((accum, key) => {
69
+ const storedSegmentNames = Object.keys(localStorage).reduce((accum, key) => {
52
70
  let segmentName = this.keys.extractSegmentName(key);
53
71
 
54
72
  if (segmentName) {
55
73
  accum.push(segmentName);
56
74
  } else {
57
- // @TODO @BREAKING: This is only to clean up "old" keys. Remove this whole else code block
75
+ // @TODO @BREAKING: This is only to clean up "old" keys. Remove this whole else code block and reuse `getRegisteredSegments` method.
58
76
  segmentName = this.keys.extractOldSegmentKey(key);
59
77
 
60
78
  if (segmentName) { // this was an old segment key, let's clean up.
61
79
  const newSegmentKey = this.keys.buildSegmentNameKey(segmentName);
62
80
  try {
63
81
  // If the new format key is not there, create it.
64
- if (!localStorage.getItem(newSegmentKey)) {
82
+ if (!localStorage.getItem(newSegmentKey) && names.indexOf(segmentName) > -1) {
65
83
  localStorage.setItem(newSegmentKey, DEFINED);
66
84
  // we are migrating a segment, let's track it.
67
85
  accum.push(segmentName);
@@ -75,32 +93,44 @@ export class MySegmentsCacheInLocal extends AbstractMySegmentsCacheSync {
75
93
 
76
94
  return accum;
77
95
  }, [] as string[]);
78
- }
79
96
 
80
- getKeysCount() {
81
- return 1;
82
- }
97
+ // Extreme fast => everything is empty
98
+ if (names.length === 0 && storedSegmentNames.length === names.length)
99
+ return isDiff;
83
100
 
84
- protected setChangeNumber(changeNumber?: number) {
85
- try {
86
- if (changeNumber) localStorage.setItem(this.keys.buildTillKey(), changeNumber + '');
87
- else localStorage.removeItem(this.keys.buildTillKey());
88
- } catch (e) {
89
- this.log.error(e);
90
- }
91
- }
101
+ // Quick path
102
+ if (storedSegmentNames.length !== names.length) {
103
+ isDiff = true;
92
104
 
93
- getChangeNumber() {
94
- const n = -1;
95
- let value: string | number | null = localStorage.getItem(this.keys.buildTillKey());
105
+ storedSegmentNames.forEach(name => this.removeFromSegment(name));
106
+ names.forEach(name => this.addToSegment(name));
107
+ } else {
108
+ // Slowest path => we need to find at least 1 difference because
109
+ for (index = 0; index < names.length && storedSegmentNames.indexOf(names[index]) !== -1; index++) {
110
+ // TODO: why empty statement?
111
+ }
96
112
 
97
- if (value !== null) {
98
- value = parseInt(value, 10);
113
+ if (index < names.length) {
114
+ isDiff = true;
99
115
 
100
- return isNaNNumber(value) ? n : value;
116
+ storedSegmentNames.forEach(name => this.removeFromSegment(name));
117
+ names.forEach(name => this.addToSegment(name));
118
+ }
101
119
  }
102
120
 
103
- return n;
121
+ return isDiff;
122
+ }
123
+
124
+ getRegisteredSegments(): string[] {
125
+ return Object.keys(localStorage).reduce<string[]>((accum, key) => {
126
+ const segmentName = this.keys.extractSegmentName(key);
127
+ if (segmentName) accum.push(segmentName);
128
+ return accum;
129
+ }, []);
130
+ }
131
+
132
+ getKeysCount() {
133
+ return 1;
104
134
  }
105
135
 
106
136
  }
@@ -3,7 +3,7 @@ import { ImpressionCountsCacheInMemory } from '../inMemory/ImpressionCountsCache
3
3
  import { EventsCacheInMemory } from '../inMemory/EventsCacheInMemory';
4
4
  import { IStorageFactoryParams, IStorageSync, IStorageSyncFactory } from '../types';
5
5
  import { validatePrefix } from '../KeyBuilder';
6
- import { KeyBuilderCS, myLargeSegmentsKeyBuilder } from '../KeyBuilderCS';
6
+ import { KeyBuilderCS } from '../KeyBuilderCS';
7
7
  import { isLocalStorageAvailable } from '../../utils/env/isLocalStorageAvailable';
8
8
  import { SplitsCacheInLocal } from './SplitsCacheInLocal';
9
9
  import { MySegmentsCacheInLocal } from './MySegmentsCacheInLocal';
@@ -38,17 +38,15 @@ export function InLocalStorage(options: InLocalStorageOptions = {}): IStorageSyn
38
38
 
39
39
  const { settings, settings: { log, scheduler: { impressionsQueueSize, eventsQueueSize, }, sync: { impressionsMode, __splitFiltersValidation } } } = params;
40
40
  const matchingKey = getMatching(settings.core.key);
41
- const keys = new KeyBuilderCS(prefix, matchingKey);
41
+ const keys = new KeyBuilderCS(prefix, matchingKey as string);
42
42
  const expirationTimestamp = Date.now() - DEFAULT_CACHE_EXPIRATION_IN_MILLIS;
43
43
 
44
44
  const splits = new SplitsCacheInLocal(settings, keys, expirationTimestamp);
45
45
  const segments = new MySegmentsCacheInLocal(log, keys);
46
- const largeSegments = new MySegmentsCacheInLocal(log, myLargeSegmentsKeyBuilder(prefix, matchingKey));
47
46
 
48
47
  return {
49
48
  splits,
50
49
  segments,
51
- largeSegments,
52
50
  impressions: new ImpressionsCacheInMemory(impressionsQueueSize),
53
51
  impressionCounts: impressionsMode !== DEBUG ? new ImpressionCountsCacheInMemory() : undefined,
54
52
  events: new EventsCacheInMemory(eventsQueueSize),
@@ -58,7 +56,6 @@ export function InLocalStorage(options: InLocalStorageOptions = {}): IStorageSyn
58
56
  destroy() {
59
57
  this.splits = new SplitsCacheInMemory(__splitFiltersValidation);
60
58
  this.segments = new MySegmentsCacheInMemory();
61
- this.largeSegments = new MySegmentsCacheInMemory();
62
59
  this.impressions.clear();
63
60
  this.impressionCounts && this.impressionCounts.clear();
64
61
  this.events.clear();
@@ -67,11 +64,11 @@ export function InLocalStorage(options: InLocalStorageOptions = {}): IStorageSyn
67
64
 
68
65
  // When using shared instanciation with MEMORY we reuse everything but segments (they are customer per key).
69
66
  shared(matchingKey: string) {
67
+ const childKeysBuilder = new KeyBuilderCS(prefix, matchingKey);
70
68
 
71
69
  return {
72
70
  splits: this.splits,
73
- segments: new MySegmentsCacheInLocal(log, new KeyBuilderCS(prefix, matchingKey)),
74
- largeSegments: new MySegmentsCacheInLocal(log, myLargeSegmentsKeyBuilder(prefix, matchingKey)),
71
+ segments: new MySegmentsCacheInLocal(log, childKeysBuilder),
75
72
  impressions: this.impressions,
76
73
  impressionCounts: this.impressionCounts,
77
74
  events: this.events,
@@ -80,7 +77,6 @@ export function InLocalStorage(options: InLocalStorageOptions = {}): IStorageSyn
80
77
  destroy() {
81
78
  this.splits = new SplitsCacheInMemory(__splitFiltersValidation);
82
79
  this.segments = new MySegmentsCacheInMemory();
83
- this.largeSegments = new MySegmentsCacheInMemory();
84
80
  }
85
81
  };
86
82
  },
@@ -18,12 +18,10 @@ export function InMemoryStorageCSFactory(params: IStorageFactoryParams): IStorag
18
18
 
19
19
  const splits = new SplitsCacheInMemory(__splitFiltersValidation);
20
20
  const segments = new MySegmentsCacheInMemory();
21
- const largeSegments = new MySegmentsCacheInMemory();
22
21
 
23
22
  const storage = {
24
23
  splits,
25
24
  segments,
26
- largeSegments,
27
25
  impressions: new ImpressionsCacheInMemory(impressionsQueueSize),
28
26
  impressionCounts: impressionsMode !== DEBUG ? new ImpressionCountsCacheInMemory() : undefined,
29
27
  events: new EventsCacheInMemory(eventsQueueSize),
@@ -34,7 +32,6 @@ export function InMemoryStorageCSFactory(params: IStorageFactoryParams): IStorag
34
32
  destroy() {
35
33
  this.splits.clear();
36
34
  this.segments.clear();
37
- this.largeSegments.clear();
38
35
  this.impressions.clear();
39
36
  this.impressionCounts && this.impressionCounts.clear();
40
37
  this.events.clear();
@@ -46,7 +43,6 @@ export function InMemoryStorageCSFactory(params: IStorageFactoryParams): IStorag
46
43
  return {
47
44
  splits: this.splits,
48
45
  segments: new MySegmentsCacheInMemory(),
49
- largeSegments: new MySegmentsCacheInMemory(),
50
46
  impressions: this.impressions,
51
47
  impressionCounts: this.impressionCounts,
52
48
  events: this.events,
@@ -56,14 +52,13 @@ export function InMemoryStorageCSFactory(params: IStorageFactoryParams): IStorag
56
52
  destroy() {
57
53
  this.splits = new SplitsCacheInMemory(__splitFiltersValidation);
58
54
  this.segments.clear();
59
- this.largeSegments.clear();
60
55
  }
61
56
  };
62
57
  },
63
58
  };
64
59
 
65
60
  // @TODO revisit storage logic in localhost mode
66
- // No tracking in localhost mode to avoid memory leaks: https://github.com/splitio/javascript-commons/issues/181
61
+ // No tracking data in localhost mode to avoid memory leaks
67
62
  if (params.settings.mode === LOCALHOST_MODE) {
68
63
  const noopTrack = () => true;
69
64
  storage.impressions.track = noopTrack;
@@ -1,25 +1,24 @@
1
- import { AbstractMySegmentsCacheSync } from '../AbstractMySegmentsCacheSync';
1
+ import { AbstractSegmentsCacheSync } from '../AbstractSegmentsCacheSync';
2
2
 
3
3
  /**
4
4
  * Default MySegmentsCacheInMemory implementation that stores MySegments in memory.
5
5
  * Supported by all JS runtimes.
6
6
  */
7
- export class MySegmentsCacheInMemory extends AbstractMySegmentsCacheSync {
7
+ export class MySegmentsCacheInMemory extends AbstractSegmentsCacheSync {
8
8
 
9
9
  private segmentCache: Record<string, boolean> = {};
10
- private cn?: number;
11
10
 
12
- protected addSegment(name: string): boolean {
13
- if (this.segmentCache[name]) return false;
11
+ clear() {
12
+ this.segmentCache = {};
13
+ }
14
14
 
15
+ addToSegment(name: string): boolean {
15
16
  this.segmentCache[name] = true;
16
17
 
17
18
  return true;
18
19
  }
19
20
 
20
- protected removeSegment(name: string): boolean {
21
- if (!this.segmentCache[name]) return false;
22
-
21
+ removeFromSegment(name: string): boolean {
23
22
  delete this.segmentCache[name];
24
23
 
25
24
  return true;
@@ -29,13 +28,48 @@ export class MySegmentsCacheInMemory extends AbstractMySegmentsCacheSync {
29
28
  return this.segmentCache[name] === true;
30
29
  }
31
30
 
31
+ /**
32
+ * Reset (update) the cached list of segments with the given list, removing and adding segments if necessary.
33
+ * @NOTE based on the way we use segments in the browser, this way is the best option
34
+ *
35
+ * @param {string[]} names list of segment names
36
+ * @returns boolean indicating if the cache was updated (i.e., given list was different from the cached one)
37
+ */
38
+ resetSegments(names: string[]): boolean {
39
+ let isDiff = false;
40
+ let index;
32
41
 
33
- protected setChangeNumber(changeNumber?: number) {
34
- this.cn = changeNumber;
35
- }
42
+ const storedSegmentKeys = Object.keys(this.segmentCache);
43
+
44
+ // Extreme fast => everything is empty
45
+ if (names.length === 0 && storedSegmentKeys.length === names.length)
46
+ return isDiff;
47
+
48
+ // Quick path
49
+ if (storedSegmentKeys.length !== names.length) {
50
+ isDiff = true;
51
+
52
+ this.segmentCache = {};
53
+ names.forEach(s => {
54
+ this.addToSegment(s);
55
+ });
56
+ } else {
57
+ // Slowest path => we need to find at least 1 difference because
58
+ for (index = 0; index < names.length && this.isInSegment(names[index]); index++) {
59
+ // TODO: why empty statement?
60
+ }
61
+
62
+ if (index < names.length) {
63
+ isDiff = true;
64
+
65
+ this.segmentCache = {};
66
+ names.forEach(s => {
67
+ this.addToSegment(s);
68
+ });
69
+ }
70
+ }
36
71
 
37
- getChangeNumber() {
38
- return this.cn || -1;
72
+ return isDiff;
39
73
  }
40
74
 
41
75
  getRegisteredSegments() {
@@ -1,25 +1,36 @@
1
+ import { AbstractSegmentsCacheSync } from '../AbstractSegmentsCacheSync';
1
2
  import { ISet, _Set } from '../../utils/lang/sets';
2
3
  import { isIntegerNumber } from '../../utils/lang';
3
- import { ISegmentsCacheSync } from '../types';
4
4
 
5
5
  /**
6
- * Default ISplitsCacheSync implementation for server-side that stores segments definitions in memory.
6
+ * Default ISplitsCacheSync implementation that stores split definitions in memory.
7
+ * Supported by all JS runtimes.
7
8
  */
8
- export class SegmentsCacheInMemory implements ISegmentsCacheSync {
9
+ export class SegmentsCacheInMemory extends AbstractSegmentsCacheSync {
9
10
 
10
11
  private segmentCache: Record<string, ISet<string>> = {};
11
12
  private segmentChangeNumber: Record<string, number> = {};
12
13
 
13
- update(name: string, addedKeys: string[], removedKeys: string[], changeNumber: number) {
14
- const keySet = this.segmentCache[name] || new _Set<string>();
14
+ addToSegment(name: string, segmentKeys: string[]): boolean {
15
+ const values = this.segmentCache[name];
16
+ const keySet = values ? values : new _Set<string>();
15
17
 
16
- addedKeys.forEach(k => keySet.add(k));
17
- removedKeys.forEach(k => keySet.delete(k));
18
+ segmentKeys.forEach(k => keySet.add(k));
18
19
 
19
20
  this.segmentCache[name] = keySet;
20
- this.segmentChangeNumber[name] = changeNumber;
21
21
 
22
- return addedKeys.length > 0 || removedKeys.length > 0;
22
+ return true;
23
+ }
24
+
25
+ removeFromSegment(name: string, segmentKeys: string[]): boolean {
26
+ const values = this.segmentCache[name];
27
+ const keySet = values ? values : new _Set<string>();
28
+
29
+ segmentKeys.forEach(k => keySet.delete(k));
30
+
31
+ this.segmentCache[name] = keySet;
32
+
33
+ return true;
23
34
  }
24
35
 
25
36
  isInSegment(name: string, key: string): boolean {
@@ -63,13 +74,16 @@ export class SegmentsCacheInMemory implements ISegmentsCacheSync {
63
74
  }, 0);
64
75
  }
65
76
 
77
+ setChangeNumber(name: string, changeNumber: number) {
78
+ this.segmentChangeNumber[name] = changeNumber;
79
+
80
+ return true;
81
+ }
82
+
66
83
  getChangeNumber(name: string) {
67
84
  const value = this.segmentChangeNumber[name];
68
85
 
69
- return isIntegerNumber(value) ? value : -1;
86
+ return isIntegerNumber(value) ? value : undefined;
70
87
  }
71
88
 
72
- // No-op. Not used in server-side
73
- resetSegments() { return false; }
74
-
75
89
  }
@@ -5,6 +5,7 @@ import { ISet, _Set } from '../../utils/lang/sets';
5
5
 
6
6
  /**
7
7
  * Default ISplitsCacheSync implementation that stores split definitions in memory.
8
+ * Supported by all JS runtimes.
8
9
  */
9
10
  export class SplitsCacheInMemory extends AbstractSplitsCacheSync {
10
11
 
@@ -12,7 +13,7 @@ export class SplitsCacheInMemory extends AbstractSplitsCacheSync {
12
13
  private splitsCache: Record<string, ISplit> = {};
13
14
  private ttCache: Record<string, number> = {};
14
15
  private changeNumber: number = -1;
15
- private segmentsCount: number = 0;
16
+ private splitsWithSegmentsCount: number = 0;
16
17
  private flagSetsCache: Record<string, ISet<string>> = {};
17
18
 
18
19
  constructor(splitFiltersValidation?: ISplitFiltersValidation) {
@@ -24,7 +25,7 @@ export class SplitsCacheInMemory extends AbstractSplitsCacheSync {
24
25
  this.splitsCache = {};
25
26
  this.ttCache = {};
26
27
  this.changeNumber = -1;
27
- this.segmentsCount = 0;
28
+ this.splitsWithSegmentsCount = 0;
28
29
  }
29
30
 
30
31
  addSplit(name: string, split: ISplit): boolean {
@@ -37,8 +38,9 @@ export class SplitsCacheInMemory extends AbstractSplitsCacheSync {
37
38
 
38
39
  this.removeFromFlagSets(previousSplit.name, previousSplit.sets);
39
40
 
40
- // Subtract from segments count for the previous version of this Split
41
- if (usesSegments(previousSplit)) this.segmentsCount--;
41
+ if (usesSegments(previousSplit)) { // Substract from segments count for the previous version of this Split.
42
+ this.splitsWithSegmentsCount--;
43
+ }
42
44
  }
43
45
 
44
46
  if (split) {
@@ -50,7 +52,7 @@ export class SplitsCacheInMemory extends AbstractSplitsCacheSync {
50
52
  this.addToFlagSets(split);
51
53
 
52
54
  // Add to segments count for the new version of the Split
53
- if (usesSegments(split)) this.segmentsCount++;
55
+ if (usesSegments(split)) this.splitsWithSegmentsCount++;
54
56
 
55
57
  return true;
56
58
  } else {
@@ -70,7 +72,7 @@ export class SplitsCacheInMemory extends AbstractSplitsCacheSync {
70
72
  this.removeFromFlagSets(split.name, split.sets);
71
73
 
72
74
  // Update the segments count.
73
- if (usesSegments(split)) this.segmentsCount--;
75
+ if (usesSegments(split)) this.splitsWithSegmentsCount--;
74
76
 
75
77
  return true;
76
78
  } else {
@@ -100,7 +102,7 @@ export class SplitsCacheInMemory extends AbstractSplitsCacheSync {
100
102
  }
101
103
 
102
104
  usesSegments(): boolean {
103
- return this.getChangeNumber() === -1 || this.segmentsCount > 0;
105
+ return this.getChangeNumber() === -1 || this.splitsWithSegmentsCount > 0;
104
106
  }
105
107
 
106
108
  getNamesByFlagSets(flagSets: string[]): ISet<string>[] {
@@ -1,4 +1,4 @@
1
- import { ImpressionDataType, EventDataType, LastSync, HttpErrors, HttpLatencies, StreamingEvent, Method, OperationType, MethodExceptions, MethodLatencies, TelemetryUsageStatsPayload, UpdatesFromSSEEnum, UpdatesFromSSE } from '../../sync/submitters/types';
1
+ import { ImpressionDataType, EventDataType, LastSync, HttpErrors, HttpLatencies, StreamingEvent, Method, OperationType, MethodExceptions, MethodLatencies, TelemetryUsageStatsPayload, UpdatesFromSSEEnum } from '../../sync/submitters/types';
2
2
  import { DEDUPED, DROPPED, LOCALHOST_MODE, QUEUED } from '../../utils/constants';
3
3
  import { findLatencyIndex } from '../findLatencyIndex';
4
4
  import { ISegmentsCacheSync, ISplitsCacheSync, IStorageFactoryParams, ITelemetryCacheSync } from '../types';
@@ -25,7 +25,7 @@ export function shouldRecordTelemetry({ settings }: IStorageFactoryParams) {
25
25
 
26
26
  export class TelemetryCacheInMemory implements ITelemetryCacheSync {
27
27
 
28
- constructor(private splits?: ISplitsCacheSync, private segments?: ISegmentsCacheSync, private largeSegments?: ISegmentsCacheSync) { }
28
+ constructor(private splits?: ISplitsCacheSync, private segments?: ISegmentsCacheSync) { }
29
29
 
30
30
  // isEmpty flag
31
31
  private e = true;
@@ -51,8 +51,6 @@ export class TelemetryCacheInMemory implements ITelemetryCacheSync {
51
51
  spC: this.splits && this.splits.getSplitNames().length,
52
52
  seC: this.segments && this.segments.getRegisteredSegments().length,
53
53
  skC: this.segments && this.segments.getKeysCount(),
54
- lsC: this.largeSegments && this.largeSegments.getRegisteredSegments().length,
55
- lskC: this.largeSegments && this.largeSegments.getKeysCount(),
56
54
  sL: this.getSessionLength(),
57
55
  eQ: this.getEventStats(QUEUED),
58
56
  eD: this.getEventStats(DROPPED),
@@ -247,16 +245,22 @@ export class TelemetryCacheInMemory implements ITelemetryCacheSync {
247
245
  this.e = false;
248
246
  }
249
247
 
250
- private updatesFromSSE: UpdatesFromSSE = {};
248
+ private updatesFromSSE = {
249
+ sp: 0,
250
+ ms: 0
251
+ };
251
252
 
252
253
  popUpdatesFromSSE() {
253
254
  const result = this.updatesFromSSE;
254
- this.updatesFromSSE = {};
255
+ this.updatesFromSSE = {
256
+ sp: 0,
257
+ ms: 0,
258
+ };
255
259
  return result;
256
260
  }
257
261
 
258
262
  recordUpdatesFromSSE(type: UpdatesFromSSEEnum) {
259
- this.updatesFromSSE[type] = (this.updatesFromSSE[type] || 0) + 1;
263
+ this.updatesFromSSE[type]++;
260
264
  this.e = false;
261
265
  }
262
266
 
@@ -17,21 +17,24 @@ export class SegmentsCacheInRedis implements ISegmentsCacheAsync {
17
17
  this.keys = keys;
18
18
  }
19
19
 
20
- /**
21
- * Update the given segment `name` with the lists of `addedKeys`, `removedKeys` and `changeNumber`.
22
- * The returned promise is resolved if the operation success, with `true` if the segment was updated (i.e., some key was added or removed),
23
- * or rejected if it fails (e.g., Redis operation fails).
24
- */
25
- update(name: string, addedKeys: string[], removedKeys: string[], changeNumber: number) {
20
+ addToSegment(name: string, segmentKeys: string[]) {
26
21
  const segmentKey = this.keys.buildSegmentNameKey(name);
27
22
 
28
- return Promise.all([
29
- addedKeys.length && this.redis.sadd(segmentKey, addedKeys),
30
- removedKeys.length && this.redis.srem(segmentKey, removedKeys),
31
- this.redis.set(this.keys.buildSegmentTillKey(name), changeNumber + '')
32
- ]).then(() => {
33
- return addedKeys.length > 0 || removedKeys.length > 0;
34
- });
23
+ if (segmentKeys.length) {
24
+ return this.redis.sadd(segmentKey, segmentKeys).then(() => true);
25
+ } else {
26
+ return Promise.resolve(true);
27
+ }
28
+ }
29
+
30
+ removeFromSegment(name: string, segmentKeys: string[]) {
31
+ const segmentKey = this.keys.buildSegmentNameKey(name);
32
+
33
+ if (segmentKeys.length) {
34
+ return this.redis.srem(segmentKey, segmentKeys).then(() => true);
35
+ } else {
36
+ return Promise.resolve(true);
37
+ }
35
38
  }
36
39
 
37
40
  isInSegment(name: string, key: string) {
@@ -40,14 +43,20 @@ export class SegmentsCacheInRedis implements ISegmentsCacheAsync {
40
43
  ).then(matches => matches !== 0);
41
44
  }
42
45
 
46
+ setChangeNumber(name: string, changeNumber: number) {
47
+ return this.redis.set(
48
+ this.keys.buildSegmentTillKey(name), changeNumber + ''
49
+ ).then(status => status === 'OK');
50
+ }
51
+
43
52
  getChangeNumber(name: string) {
44
53
  return this.redis.get(this.keys.buildSegmentTillKey(name)).then((value: string | null) => {
45
54
  const i = parseInt(value as string, 10);
46
55
 
47
- return isNaNNumber(i) ? -1 : i;
56
+ return isNaNNumber(i) ? undefined : i;
48
57
  }).catch((e) => {
49
58
  this.log.error(LOG_PREFIX + 'Could not retrieve changeNumber from segments storage. Error: ' + e);
50
- return -1;
59
+ return undefined;
51
60
  });
52
61
  }
53
62