@splitsoftware/splitio-commons 2.1.1-rc.0 → 2.1.1-rc.2

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 (187) hide show
  1. package/CHANGES.txt +7 -0
  2. package/README.md +0 -1
  3. package/cjs/evaluator/combiners/and.js +6 -2
  4. package/cjs/evaluator/combiners/ifelseif.js +6 -6
  5. package/cjs/evaluator/condition/index.js +5 -6
  6. package/cjs/evaluator/index.js +7 -7
  7. package/cjs/evaluator/matchers/index.js +1 -3
  8. package/cjs/evaluator/matchers/matcherTypes.js +0 -1
  9. package/cjs/evaluator/matchersTransform/index.js +0 -4
  10. package/cjs/evaluator/parser/index.js +2 -2
  11. package/cjs/evaluator/value/sanitize.js +0 -1
  12. package/cjs/logger/constants.js +3 -4
  13. package/cjs/logger/messages/debug.js +2 -3
  14. package/cjs/logger/messages/error.js +1 -1
  15. package/cjs/logger/messages/warn.js +2 -2
  16. package/cjs/readiness/readinessManager.js +6 -0
  17. package/cjs/sdkClient/client.js +29 -19
  18. package/cjs/sdkClient/clientAttributesDecoration.js +19 -25
  19. package/cjs/sdkClient/clientInputValidation.js +28 -26
  20. package/cjs/services/splitApi.js +2 -2
  21. package/cjs/storages/AbstractSplitsCacheAsync.js +0 -7
  22. package/cjs/storages/AbstractSplitsCacheSync.js +2 -12
  23. package/cjs/storages/KeyBuilder.js +0 -9
  24. package/cjs/storages/KeyBuilderCS.js +4 -4
  25. package/cjs/storages/KeyBuilderSS.js +0 -3
  26. package/cjs/storages/dataLoader.js +3 -2
  27. package/cjs/storages/inLocalStorage/SplitsCacheInLocal.js +23 -76
  28. package/cjs/storages/inLocalStorage/index.js +5 -7
  29. package/cjs/storages/inLocalStorage/validateCache.js +79 -0
  30. package/cjs/storages/inMemory/InMemoryStorage.js +0 -3
  31. package/cjs/storages/inMemory/InMemoryStorageCS.js +0 -4
  32. package/cjs/storages/inRedis/index.js +0 -2
  33. package/cjs/storages/pluggable/index.js +2 -3
  34. package/cjs/storages/utils.js +1 -0
  35. package/cjs/sync/offline/syncTasks/fromObjectSyncTask.js +3 -2
  36. package/cjs/sync/polling/fetchers/splitChangesFetcher.js +2 -2
  37. package/cjs/sync/polling/pollingManagerCS.js +7 -7
  38. package/cjs/sync/polling/updaters/mySegmentsUpdater.js +2 -2
  39. package/cjs/sync/polling/updaters/segmentChangesUpdater.js +1 -1
  40. package/cjs/sync/polling/updaters/splitChangesUpdater.js +33 -60
  41. package/cjs/sync/streaming/SSEHandler/index.js +0 -1
  42. package/cjs/sync/streaming/UpdateWorkers/SplitsUpdateWorker.js +77 -106
  43. package/cjs/sync/streaming/constants.js +1 -2
  44. package/cjs/sync/streaming/pushManager.js +16 -3
  45. package/cjs/sync/submitters/impressionsSubmitter.js +3 -2
  46. package/cjs/sync/syncManagerOnline.js +10 -5
  47. package/cjs/trackers/strategy/strategyDebug.js +2 -0
  48. package/cjs/trackers/strategy/strategyOptimized.js +3 -0
  49. package/cjs/utils/constants/index.js +2 -3
  50. package/cjs/utils/inputValidation/eventProperties.js +12 -1
  51. package/cjs/utils/inputValidation/index.js +3 -1
  52. package/cjs/utils/settingsValidation/storage/storageCS.js +1 -1
  53. package/esm/evaluator/combiners/and.js +6 -2
  54. package/esm/evaluator/combiners/ifelseif.js +7 -7
  55. package/esm/evaluator/condition/index.js +5 -6
  56. package/esm/evaluator/index.js +7 -7
  57. package/esm/evaluator/matchers/index.js +1 -3
  58. package/esm/evaluator/matchers/matcherTypes.js +0 -1
  59. package/esm/evaluator/matchersTransform/index.js +0 -4
  60. package/esm/evaluator/parser/index.js +2 -2
  61. package/esm/evaluator/value/sanitize.js +0 -1
  62. package/esm/logger/constants.js +0 -1
  63. package/esm/logger/messages/debug.js +2 -3
  64. package/esm/logger/messages/error.js +1 -1
  65. package/esm/logger/messages/warn.js +2 -2
  66. package/esm/readiness/readinessManager.js +6 -0
  67. package/esm/sdkClient/client.js +29 -19
  68. package/esm/sdkClient/clientAttributesDecoration.js +19 -25
  69. package/esm/sdkClient/clientInputValidation.js +29 -27
  70. package/esm/services/splitApi.js +2 -2
  71. package/esm/storages/AbstractSplitsCacheAsync.js +0 -7
  72. package/esm/storages/AbstractSplitsCacheSync.js +2 -12
  73. package/esm/storages/KeyBuilder.js +0 -9
  74. package/esm/storages/KeyBuilderCS.js +4 -4
  75. package/esm/storages/KeyBuilderSS.js +0 -3
  76. package/esm/storages/dataLoader.js +2 -1
  77. package/esm/storages/inLocalStorage/SplitsCacheInLocal.js +23 -76
  78. package/esm/storages/inLocalStorage/index.js +5 -7
  79. package/esm/storages/inLocalStorage/validateCache.js +75 -0
  80. package/esm/storages/inMemory/InMemoryStorage.js +0 -3
  81. package/esm/storages/inMemory/InMemoryStorageCS.js +0 -4
  82. package/esm/storages/inRedis/index.js +0 -2
  83. package/esm/storages/pluggable/index.js +2 -3
  84. package/esm/storages/utils.js +1 -0
  85. package/esm/sync/offline/syncTasks/fromObjectSyncTask.js +3 -2
  86. package/esm/sync/polling/fetchers/splitChangesFetcher.js +2 -2
  87. package/esm/sync/polling/pollingManagerCS.js +7 -7
  88. package/esm/sync/polling/updaters/mySegmentsUpdater.js +2 -2
  89. package/esm/sync/polling/updaters/segmentChangesUpdater.js +1 -1
  90. package/esm/sync/polling/updaters/splitChangesUpdater.js +34 -61
  91. package/esm/sync/streaming/SSEHandler/index.js +1 -2
  92. package/esm/sync/streaming/UpdateWorkers/SplitsUpdateWorker.js +73 -102
  93. package/esm/sync/streaming/constants.js +0 -1
  94. package/esm/sync/streaming/pushManager.js +19 -6
  95. package/esm/sync/submitters/impressionsSubmitter.js +3 -2
  96. package/esm/sync/syncManagerOnline.js +10 -5
  97. package/esm/trackers/strategy/strategyDebug.js +2 -0
  98. package/esm/trackers/strategy/strategyOptimized.js +3 -0
  99. package/esm/utils/constants/index.js +1 -2
  100. package/esm/utils/inputValidation/eventProperties.js +10 -0
  101. package/esm/utils/inputValidation/index.js +1 -0
  102. package/esm/utils/settingsValidation/storage/storageCS.js +1 -1
  103. package/package.json +1 -1
  104. package/src/dtos/types.ts +8 -32
  105. package/src/evaluator/Engine.ts +1 -1
  106. package/src/evaluator/combiners/and.ts +4 -5
  107. package/src/evaluator/combiners/ifelseif.ts +9 -7
  108. package/src/evaluator/condition/engineUtils.ts +1 -1
  109. package/src/evaluator/condition/index.ts +12 -12
  110. package/src/evaluator/index.ts +7 -7
  111. package/src/evaluator/matchers/index.ts +1 -3
  112. package/src/evaluator/matchers/matcherTypes.ts +0 -1
  113. package/src/evaluator/matchersTransform/index.ts +0 -3
  114. package/src/evaluator/parser/index.ts +3 -3
  115. package/src/evaluator/types.ts +2 -2
  116. package/src/evaluator/value/index.ts +2 -2
  117. package/src/evaluator/value/sanitize.ts +4 -5
  118. package/src/logger/constants.ts +0 -1
  119. package/src/logger/messages/debug.ts +2 -3
  120. package/src/logger/messages/error.ts +1 -1
  121. package/src/logger/messages/warn.ts +2 -2
  122. package/src/readiness/readinessManager.ts +5 -0
  123. package/src/sdkClient/client.ts +31 -21
  124. package/src/sdkClient/clientAttributesDecoration.ts +20 -27
  125. package/src/sdkClient/clientInputValidation.ts +30 -27
  126. package/src/sdkManager/index.ts +1 -1
  127. package/src/services/splitApi.ts +2 -2
  128. package/src/services/types.ts +1 -1
  129. package/src/storages/AbstractSplitsCacheAsync.ts +0 -8
  130. package/src/storages/AbstractSplitsCacheSync.ts +3 -14
  131. package/src/storages/KeyBuilder.ts +0 -12
  132. package/src/storages/KeyBuilderCS.ts +5 -5
  133. package/src/storages/KeyBuilderSS.ts +0 -4
  134. package/src/storages/dataLoader.ts +3 -1
  135. package/src/storages/inLocalStorage/SplitsCacheInLocal.ts +26 -87
  136. package/src/storages/inLocalStorage/index.ts +8 -12
  137. package/src/storages/inLocalStorage/validateCache.ts +91 -0
  138. package/src/storages/inMemory/InMemoryStorage.ts +0 -3
  139. package/src/storages/inMemory/InMemoryStorageCS.ts +0 -4
  140. package/src/storages/inRedis/index.ts +0 -2
  141. package/src/storages/pluggable/index.ts +2 -3
  142. package/src/storages/types.ts +2 -37
  143. package/src/storages/utils.ts +1 -0
  144. package/src/sync/offline/syncTasks/fromObjectSyncTask.ts +6 -5
  145. package/src/sync/polling/fetchers/splitChangesFetcher.ts +1 -2
  146. package/src/sync/polling/fetchers/types.ts +0 -1
  147. package/src/sync/polling/pollingManagerCS.ts +7 -7
  148. package/src/sync/polling/types.ts +2 -2
  149. package/src/sync/polling/updaters/mySegmentsUpdater.ts +2 -2
  150. package/src/sync/polling/updaters/segmentChangesUpdater.ts +1 -1
  151. package/src/sync/polling/updaters/splitChangesUpdater.ts +43 -71
  152. package/src/sync/streaming/SSEHandler/index.ts +1 -2
  153. package/src/sync/streaming/SSEHandler/types.ts +2 -2
  154. package/src/sync/streaming/UpdateWorkers/SplitsUpdateWorker.ts +68 -98
  155. package/src/sync/streaming/constants.ts +0 -1
  156. package/src/sync/streaming/parseUtils.ts +2 -2
  157. package/src/sync/streaming/pushManager.ts +18 -6
  158. package/src/sync/streaming/types.ts +2 -3
  159. package/src/sync/submitters/impressionsSubmitter.ts +3 -2
  160. package/src/sync/submitters/types.ts +23 -33
  161. package/src/sync/syncManagerOnline.ts +11 -5
  162. package/src/trackers/strategy/strategyDebug.ts +2 -0
  163. package/src/trackers/strategy/strategyOptimized.ts +3 -0
  164. package/src/utils/constants/index.ts +1 -2
  165. package/src/utils/inputValidation/eventProperties.ts +10 -0
  166. package/src/utils/inputValidation/index.ts +1 -0
  167. package/src/utils/lang/index.ts +2 -2
  168. package/src/utils/settingsValidation/storage/storageCS.ts +1 -1
  169. package/types/splitio.d.ts +128 -36
  170. package/cjs/evaluator/matchers/rbsegment.js +0 -43
  171. package/cjs/storages/inLocalStorage/RBSegmentsCacheInLocal.js +0 -117
  172. package/cjs/storages/inMemory/RBSegmentsCacheInMemory.js +0 -61
  173. package/cjs/storages/inRedis/RBSegmentsCacheInRedis.js +0 -64
  174. package/cjs/storages/pluggable/RBSegmentsCachePluggable.js +0 -64
  175. package/cjs/utils/constants/browser.js +0 -5
  176. package/esm/evaluator/matchers/rbsegment.js +0 -39
  177. package/esm/storages/inLocalStorage/RBSegmentsCacheInLocal.js +0 -114
  178. package/esm/storages/inMemory/RBSegmentsCacheInMemory.js +0 -58
  179. package/esm/storages/inRedis/RBSegmentsCacheInRedis.js +0 -61
  180. package/esm/storages/pluggable/RBSegmentsCachePluggable.js +0 -61
  181. package/esm/utils/constants/browser.js +0 -2
  182. package/src/evaluator/matchers/rbsegment.ts +0 -61
  183. package/src/storages/inLocalStorage/RBSegmentsCacheInLocal.ts +0 -136
  184. package/src/storages/inMemory/RBSegmentsCacheInMemory.ts +0 -68
  185. package/src/storages/inRedis/RBSegmentsCacheInRedis.ts +0 -79
  186. package/src/storages/pluggable/RBSegmentsCachePluggable.ts +0 -76
  187. package/src/utils/constants/browser.ts +0 -2
@@ -20,50 +20,44 @@ export function clientAttributesDecoration<TClient extends SplitIO.IClient | Spl
20
20
  const clientGetTreatmentsWithConfigByFlagSets = client.getTreatmentsWithConfigByFlagSets;
21
21
  const clientGetTreatmentsByFlagSet = client.getTreatmentsByFlagSet;
22
22
  const clientGetTreatmentsWithConfigByFlagSet = client.getTreatmentsWithConfigByFlagSet;
23
- const clientTrack = client.track;
24
23
 
25
- function getTreatment(maybeKey: SplitIO.SplitKey, maybeFeatureFlagName: string, maybeAttributes?: SplitIO.Attributes) {
26
- return clientGetTreatment(maybeKey, maybeFeatureFlagName, combineAttributes(maybeAttributes));
24
+ function getTreatment(maybeKey: SplitIO.SplitKey, maybeFeatureFlagName: string, maybeAttributes?: SplitIO.Attributes, maybeOptions?: SplitIO.EvaluationOptions) {
25
+ return clientGetTreatment(maybeKey, maybeFeatureFlagName, combineAttributes(maybeAttributes), maybeOptions);
27
26
  }
28
27
 
29
- function getTreatmentWithConfig(maybeKey: SplitIO.SplitKey, maybeFeatureFlagName: string, maybeAttributes?: SplitIO.Attributes) {
30
- return clientGetTreatmentWithConfig(maybeKey, maybeFeatureFlagName, combineAttributes(maybeAttributes));
28
+ function getTreatmentWithConfig(maybeKey: SplitIO.SplitKey, maybeFeatureFlagName: string, maybeAttributes?: SplitIO.Attributes, maybeOptions?: SplitIO.EvaluationOptions) {
29
+ return clientGetTreatmentWithConfig(maybeKey, maybeFeatureFlagName, combineAttributes(maybeAttributes), maybeOptions);
31
30
  }
32
31
 
33
- function getTreatments(maybeKey: SplitIO.SplitKey, maybeFeatureFlagNames: string[], maybeAttributes?: SplitIO.Attributes) {
34
- return clientGetTreatments(maybeKey, maybeFeatureFlagNames, combineAttributes(maybeAttributes));
32
+ function getTreatments(maybeKey: SplitIO.SplitKey, maybeFeatureFlagNames: string[], maybeAttributes?: SplitIO.Attributes, maybeOptions?: SplitIO.EvaluationOptions) {
33
+ return clientGetTreatments(maybeKey, maybeFeatureFlagNames, combineAttributes(maybeAttributes), maybeOptions);
35
34
  }
36
35
 
37
- function getTreatmentsWithConfig(maybeKey: SplitIO.SplitKey, maybeFeatureFlagNames: string[], maybeAttributes?: SplitIO.Attributes) {
38
- return clientGetTreatmentsWithConfig(maybeKey, maybeFeatureFlagNames, combineAttributes(maybeAttributes));
36
+ function getTreatmentsWithConfig(maybeKey: SplitIO.SplitKey, maybeFeatureFlagNames: string[], maybeAttributes?: SplitIO.Attributes, maybeOptions?: SplitIO.EvaluationOptions) {
37
+ return clientGetTreatmentsWithConfig(maybeKey, maybeFeatureFlagNames, combineAttributes(maybeAttributes), maybeOptions);
39
38
  }
40
39
 
41
- function getTreatmentsByFlagSets(maybeKey: SplitIO.SplitKey, maybeFlagSets: string[], maybeAttributes?: SplitIO.Attributes) {
42
- return clientGetTreatmentsByFlagSets(maybeKey, maybeFlagSets, combineAttributes(maybeAttributes));
40
+ function getTreatmentsByFlagSets(maybeKey: SplitIO.SplitKey, maybeFlagSets: string[], maybeAttributes?: SplitIO.Attributes, maybeOptions?: SplitIO.EvaluationOptions) {
41
+ return clientGetTreatmentsByFlagSets(maybeKey, maybeFlagSets, combineAttributes(maybeAttributes), maybeOptions);
43
42
  }
44
43
 
45
- function getTreatmentsWithConfigByFlagSets(maybeKey: SplitIO.SplitKey, maybeFlagSets: string[], maybeAttributes?: SplitIO.Attributes) {
46
- return clientGetTreatmentsWithConfigByFlagSets(maybeKey, maybeFlagSets, combineAttributes(maybeAttributes));
44
+ function getTreatmentsWithConfigByFlagSets(maybeKey: SplitIO.SplitKey, maybeFlagSets: string[], maybeAttributes?: SplitIO.Attributes, maybeOptions?: SplitIO.EvaluationOptions) {
45
+ return clientGetTreatmentsWithConfigByFlagSets(maybeKey, maybeFlagSets, combineAttributes(maybeAttributes), maybeOptions);
47
46
  }
48
47
 
49
- function getTreatmentsByFlagSet(maybeKey: SplitIO.SplitKey, maybeFlagSet: string, maybeAttributes?: SplitIO.Attributes) {
50
- return clientGetTreatmentsByFlagSet(maybeKey, maybeFlagSet, combineAttributes(maybeAttributes));
48
+ function getTreatmentsByFlagSet(maybeKey: SplitIO.SplitKey, maybeFlagSet: string, maybeAttributes?: SplitIO.Attributes, maybeOptions?: SplitIO.EvaluationOptions) {
49
+ return clientGetTreatmentsByFlagSet(maybeKey, maybeFlagSet, combineAttributes(maybeAttributes), maybeOptions);
51
50
  }
52
51
 
53
- function getTreatmentsWithConfigByFlagSet(maybeKey: SplitIO.SplitKey, maybeFlagSet: string, maybeAttributes?: SplitIO.Attributes) {
54
- return clientGetTreatmentsWithConfigByFlagSet(maybeKey, maybeFlagSet, combineAttributes(maybeAttributes));
52
+ function getTreatmentsWithConfigByFlagSet(maybeKey: SplitIO.SplitKey, maybeFlagSet: string, maybeAttributes?: SplitIO.Attributes, maybeOptions?: SplitIO.EvaluationOptions) {
53
+ return clientGetTreatmentsWithConfigByFlagSet(maybeKey, maybeFlagSet, combineAttributes(maybeAttributes), maybeOptions);
55
54
  }
56
55
 
57
- function track(maybeKey: SplitIO.SplitKey, maybeTT: string, maybeEvent: string, maybeEventValue?: number, maybeProperties?: SplitIO.Properties) {
58
- return clientTrack(maybeKey, maybeTT, maybeEvent, maybeEventValue, maybeProperties);
59
- }
60
-
61
- function combineAttributes(maybeAttributes: SplitIO.Attributes | undefined): SplitIO.Attributes | undefined{
56
+ function combineAttributes(maybeAttributes: SplitIO.Attributes | undefined): SplitIO.Attributes | undefined {
62
57
  const storedAttributes = attributeStorage.getAll();
63
- if (Object.keys(storedAttributes).length > 0) {
64
- return objectAssign({}, storedAttributes, maybeAttributes);
65
- }
66
- return maybeAttributes;
58
+ return Object.keys(storedAttributes).length > 0 ?
59
+ objectAssign({}, storedAttributes, maybeAttributes) :
60
+ maybeAttributes;
67
61
  }
68
62
 
69
63
  return objectAssign(client, {
@@ -75,7 +69,6 @@ export function clientAttributesDecoration<TClient extends SplitIO.IClient | Spl
75
69
  getTreatmentsWithConfigByFlagSets: getTreatmentsWithConfigByFlagSets,
76
70
  getTreatmentsByFlagSet: getTreatmentsByFlagSet,
77
71
  getTreatmentsWithConfigByFlagSet: getTreatmentsWithConfigByFlagSet,
78
- track: track,
79
72
 
80
73
  /**
81
74
  * Add an attribute to client's in memory attributes storage
@@ -9,7 +9,8 @@ import {
9
9
  validateSplits,
10
10
  validateTrafficType,
11
11
  validateIfNotDestroyed,
12
- validateIfOperational
12
+ validateIfOperational,
13
+ validateEvaluationOptions
13
14
  } from '../utils/inputValidation';
14
15
  import { startsWith } from '../utils/lang';
15
16
  import { CONTROL, CONTROL_WITH_CONFIG, GET_TREATMENT, GET_TREATMENTS, GET_TREATMENTS_BY_FLAG_SET, GET_TREATMENTS_BY_FLAG_SETS, GET_TREATMENTS_WITH_CONFIG, GET_TREATMENTS_WITH_CONFIG_BY_FLAG_SET, GET_TREATMENTS_WITH_CONFIG_BY_FLAG_SETS, GET_TREATMENT_WITH_CONFIG, TRACK_FN_LABEL } from '../utils/constants';
@@ -32,7 +33,7 @@ export function clientInputValidationDecorator<TClient extends SplitIO.IClient |
32
33
  /**
33
34
  * Avoid repeating this validations code
34
35
  */
35
- function validateEvaluationParams(maybeKey: SplitIO.SplitKey, maybeNameOrNames: string | string[], maybeAttributes: SplitIO.Attributes | undefined, methodName: string) {
36
+ function validateEvaluationParams(methodName: string, maybeKey: SplitIO.SplitKey, maybeNameOrNames: string | string[], maybeAttributes?: SplitIO.Attributes, maybeOptions?: SplitIO.EvaluationOptions) {
36
37
  const key = validateKey(log, maybeKey, methodName);
37
38
 
38
39
  const nameOrNames = methodName.indexOf('ByFlagSet') > -1 ?
@@ -43,6 +44,7 @@ export function clientInputValidationDecorator<TClient extends SplitIO.IClient |
43
44
 
44
45
  const attributes = validateAttributes(log, maybeAttributes, methodName);
45
46
  const isNotDestroyed = validateIfNotDestroyed(log, readinessManager, methodName);
47
+ const options = validateEvaluationOptions(log, maybeOptions, methodName);
46
48
 
47
49
  validateIfOperational(log, readinessManager, methodName, nameOrNames);
48
50
 
@@ -52,7 +54,8 @@ export function clientInputValidationDecorator<TClient extends SplitIO.IClient |
52
54
  valid,
53
55
  key,
54
56
  nameOrNames,
55
- attributes
57
+ attributes,
58
+ options
56
59
  };
57
60
  }
58
61
 
@@ -60,31 +63,31 @@ export function clientInputValidationDecorator<TClient extends SplitIO.IClient |
60
63
  return isAsync ? Promise.resolve(value) : value;
61
64
  }
62
65
 
63
- function getTreatment(maybeKey: SplitIO.SplitKey, maybeFeatureFlagName: string, maybeAttributes?: SplitIO.Attributes) {
64
- const params = validateEvaluationParams(maybeKey, maybeFeatureFlagName, maybeAttributes, GET_TREATMENT);
66
+ function getTreatment(maybeKey: SplitIO.SplitKey, maybeFeatureFlagName: string, maybeAttributes?: SplitIO.Attributes, maybeOptions?: SplitIO.EvaluationOptions) {
67
+ const params = validateEvaluationParams(GET_TREATMENT, maybeKey, maybeFeatureFlagName, maybeAttributes, maybeOptions);
65
68
 
66
69
  if (params.valid) {
67
- return client.getTreatment(params.key as SplitIO.SplitKey, params.nameOrNames as string, params.attributes as SplitIO.Attributes | undefined);
70
+ return client.getTreatment(params.key as SplitIO.SplitKey, params.nameOrNames as string, params.attributes as SplitIO.Attributes | undefined, params.options);
68
71
  } else {
69
72
  return wrapResult(CONTROL);
70
73
  }
71
74
  }
72
75
 
73
- function getTreatmentWithConfig(maybeKey: SplitIO.SplitKey, maybeFeatureFlagName: string, maybeAttributes?: SplitIO.Attributes) {
74
- const params = validateEvaluationParams(maybeKey, maybeFeatureFlagName, maybeAttributes, GET_TREATMENT_WITH_CONFIG);
76
+ function getTreatmentWithConfig(maybeKey: SplitIO.SplitKey, maybeFeatureFlagName: string, maybeAttributes?: SplitIO.Attributes, maybeOptions?: SplitIO.EvaluationOptions) {
77
+ const params = validateEvaluationParams(GET_TREATMENT_WITH_CONFIG, maybeKey, maybeFeatureFlagName, maybeAttributes, maybeOptions);
75
78
 
76
79
  if (params.valid) {
77
- return client.getTreatmentWithConfig(params.key as SplitIO.SplitKey, params.nameOrNames as string, params.attributes as SplitIO.Attributes | undefined);
80
+ return client.getTreatmentWithConfig(params.key as SplitIO.SplitKey, params.nameOrNames as string, params.attributes as SplitIO.Attributes | undefined, params.options);
78
81
  } else {
79
82
  return wrapResult(objectAssign({}, CONTROL_WITH_CONFIG));
80
83
  }
81
84
  }
82
85
 
83
- function getTreatments(maybeKey: SplitIO.SplitKey, maybeFeatureFlagNames: string[], maybeAttributes?: SplitIO.Attributes) {
84
- const params = validateEvaluationParams(maybeKey, maybeFeatureFlagNames, maybeAttributes, GET_TREATMENTS);
86
+ function getTreatments(maybeKey: SplitIO.SplitKey, maybeFeatureFlagNames: string[], maybeAttributes?: SplitIO.Attributes, maybeOptions?: SplitIO.EvaluationOptions) {
87
+ const params = validateEvaluationParams(GET_TREATMENTS, maybeKey, maybeFeatureFlagNames, maybeAttributes, maybeOptions);
85
88
 
86
89
  if (params.valid) {
87
- return client.getTreatments(params.key as SplitIO.SplitKey, params.nameOrNames as string[], params.attributes as SplitIO.Attributes | undefined);
90
+ return client.getTreatments(params.key as SplitIO.SplitKey, params.nameOrNames as string[], params.attributes as SplitIO.Attributes | undefined, params.options);
88
91
  } else {
89
92
  const res: SplitIO.Treatments = {};
90
93
  if (params.nameOrNames) (params.nameOrNames as string[]).forEach((split: string) => res[split] = CONTROL);
@@ -93,11 +96,11 @@ export function clientInputValidationDecorator<TClient extends SplitIO.IClient |
93
96
  }
94
97
  }
95
98
 
96
- function getTreatmentsWithConfig(maybeKey: SplitIO.SplitKey, maybeFeatureFlagNames: string[], maybeAttributes?: SplitIO.Attributes) {
97
- const params = validateEvaluationParams(maybeKey, maybeFeatureFlagNames, maybeAttributes, GET_TREATMENTS_WITH_CONFIG);
99
+ function getTreatmentsWithConfig(maybeKey: SplitIO.SplitKey, maybeFeatureFlagNames: string[], maybeAttributes?: SplitIO.Attributes, maybeOptions?: SplitIO.EvaluationOptions) {
100
+ const params = validateEvaluationParams(GET_TREATMENTS_WITH_CONFIG, maybeKey, maybeFeatureFlagNames, maybeAttributes, maybeOptions);
98
101
 
99
102
  if (params.valid) {
100
- return client.getTreatmentsWithConfig(params.key as SplitIO.SplitKey, params.nameOrNames as string[], params.attributes as SplitIO.Attributes | undefined);
103
+ return client.getTreatmentsWithConfig(params.key as SplitIO.SplitKey, params.nameOrNames as string[], params.attributes as SplitIO.Attributes | undefined, params.options);
101
104
  } else {
102
105
  const res: SplitIO.TreatmentsWithConfig = {};
103
106
  if (params.nameOrNames) (params.nameOrNames as string[]).forEach(split => res[split] = objectAssign({}, CONTROL_WITH_CONFIG));
@@ -106,41 +109,41 @@ export function clientInputValidationDecorator<TClient extends SplitIO.IClient |
106
109
  }
107
110
  }
108
111
 
109
- function getTreatmentsByFlagSets(maybeKey: SplitIO.SplitKey, maybeFlagSets: string[], maybeAttributes?: SplitIO.Attributes) {
110
- const params = validateEvaluationParams(maybeKey, maybeFlagSets, maybeAttributes, GET_TREATMENTS_BY_FLAG_SETS);
112
+ function getTreatmentsByFlagSets(maybeKey: SplitIO.SplitKey, maybeFlagSets: string[], maybeAttributes?: SplitIO.Attributes, maybeOptions?: SplitIO.EvaluationOptions) {
113
+ const params = validateEvaluationParams(GET_TREATMENTS_BY_FLAG_SETS, maybeKey, maybeFlagSets, maybeAttributes, maybeOptions);
111
114
 
112
115
  if (params.valid) {
113
- return client.getTreatmentsByFlagSets(params.key as SplitIO.SplitKey, params.nameOrNames as string[], params.attributes as SplitIO.Attributes | undefined);
116
+ return client.getTreatmentsByFlagSets(params.key as SplitIO.SplitKey, params.nameOrNames as string[], params.attributes as SplitIO.Attributes | undefined, params.options);
114
117
  } else {
115
118
  return wrapResult({});
116
119
  }
117
120
  }
118
121
 
119
- function getTreatmentsWithConfigByFlagSets(maybeKey: SplitIO.SplitKey, maybeFlagSets: string[], maybeAttributes?: SplitIO.Attributes) {
120
- const params = validateEvaluationParams(maybeKey, maybeFlagSets, maybeAttributes, GET_TREATMENTS_WITH_CONFIG_BY_FLAG_SETS);
122
+ function getTreatmentsWithConfigByFlagSets(maybeKey: SplitIO.SplitKey, maybeFlagSets: string[], maybeAttributes?: SplitIO.Attributes, maybeOptions?: SplitIO.EvaluationOptions) {
123
+ const params = validateEvaluationParams(GET_TREATMENTS_WITH_CONFIG_BY_FLAG_SETS, maybeKey, maybeFlagSets, maybeAttributes, maybeOptions);
121
124
 
122
125
  if (params.valid) {
123
- return client.getTreatmentsWithConfigByFlagSets(params.key as SplitIO.SplitKey, params.nameOrNames as string[], params.attributes as SplitIO.Attributes | undefined);
126
+ return client.getTreatmentsWithConfigByFlagSets(params.key as SplitIO.SplitKey, params.nameOrNames as string[], params.attributes as SplitIO.Attributes | undefined, params.options);
124
127
  } else {
125
128
  return wrapResult({});
126
129
  }
127
130
  }
128
131
 
129
- function getTreatmentsByFlagSet(maybeKey: SplitIO.SplitKey, maybeFlagSet: string, maybeAttributes?: SplitIO.Attributes) {
130
- const params = validateEvaluationParams(maybeKey, [maybeFlagSet], maybeAttributes, GET_TREATMENTS_BY_FLAG_SET);
132
+ function getTreatmentsByFlagSet(maybeKey: SplitIO.SplitKey, maybeFlagSet: string, maybeAttributes?: SplitIO.Attributes, maybeOptions?: SplitIO.EvaluationOptions) {
133
+ const params = validateEvaluationParams(GET_TREATMENTS_BY_FLAG_SET, maybeKey, [maybeFlagSet], maybeAttributes, maybeOptions);
131
134
 
132
135
  if (params.valid) {
133
- return client.getTreatmentsByFlagSet(params.key as SplitIO.SplitKey, (params.nameOrNames as string[])[0], params.attributes as SplitIO.Attributes | undefined);
136
+ return client.getTreatmentsByFlagSet(params.key as SplitIO.SplitKey, (params.nameOrNames as string[])[0], params.attributes as SplitIO.Attributes | undefined, params.options);
134
137
  } else {
135
138
  return wrapResult({});
136
139
  }
137
140
  }
138
141
 
139
- function getTreatmentsWithConfigByFlagSet(maybeKey: SplitIO.SplitKey, maybeFlagSet: string, maybeAttributes?: SplitIO.Attributes) {
140
- const params = validateEvaluationParams(maybeKey, [maybeFlagSet], maybeAttributes, GET_TREATMENTS_WITH_CONFIG_BY_FLAG_SET);
142
+ function getTreatmentsWithConfigByFlagSet(maybeKey: SplitIO.SplitKey, maybeFlagSet: string, maybeAttributes?: SplitIO.Attributes, maybeOptions?: SplitIO.EvaluationOptions) {
143
+ const params = validateEvaluationParams(GET_TREATMENTS_WITH_CONFIG_BY_FLAG_SET, maybeKey, [maybeFlagSet], maybeAttributes, maybeOptions);
141
144
 
142
145
  if (params.valid) {
143
- return client.getTreatmentsWithConfigByFlagSet(params.key as SplitIO.SplitKey, (params.nameOrNames as string[])[0], params.attributes as SplitIO.Attributes | undefined);
146
+ return client.getTreatmentsWithConfigByFlagSet(params.key as SplitIO.SplitKey, (params.nameOrNames as string[])[0], params.attributes as SplitIO.Attributes | undefined, params.options);
144
147
  } else {
145
148
  return wrapResult({});
146
149
  }
@@ -17,7 +17,7 @@ function collectTreatments(splitObject: ISplit) {
17
17
  // Localstorage mode could fall into a no rollout conditions state. Take the first condition in that case.
18
18
  if (!allTreatmentsCondition) allTreatmentsCondition = conditions[0];
19
19
  // Then extract the treatments from the partitions
20
- return allTreatmentsCondition ? allTreatmentsCondition.partitions!.map(v => v.treatment) : [];
20
+ return allTreatmentsCondition ? allTreatmentsCondition.partitions.map(v => v.treatment) : [];
21
21
  }
22
22
 
23
23
  function objectToView(splitObject: ISplit | null): SplitIO.SplitView | null {
@@ -53,8 +53,8 @@ export function splitApiFactory(
53
53
  return splitHttpClient(url, undefined, telemetryTracker.trackHttp(TOKEN));
54
54
  },
55
55
 
56
- fetchSplitChanges(since: number, noCache?: boolean, till?: number, rbSince?: number) {
57
- const url = `${urls.sdk}/splitChanges?s=${flagSpecVersion}&since=${since}${rbSince ? '&rbSince=' + rbSince : ''}${filterQueryString || ''}${till ? '&till=' + till : ''}`;
56
+ fetchSplitChanges(since: number, noCache?: boolean, till?: number) {
57
+ const url = `${urls.sdk}/splitChanges?s=${flagSpecVersion}&since=${since}${filterQueryString || ''}${till ? '&till=' + till : ''}`;
58
58
  return splitHttpClient(url, noCache ? noCacheHeaderOptions : undefined, telemetryTracker.trackHttp(SPLITS))
59
59
  .catch((err) => {
60
60
  if (err.statusCode === 414) settings.log.error(ERROR_TOO_MANY_SETS);
@@ -35,7 +35,7 @@ export type ISplitHttpClient = (url: string, options?: IRequestOptions, latencyT
35
35
 
36
36
  export type IFetchAuth = (userKeys?: string[]) => Promise<IResponse>
37
37
 
38
- export type IFetchSplitChanges = (since: number, noCache?: boolean, till?: number, rbSince?: number) => Promise<IResponse>
38
+ export type IFetchSplitChanges = (since: number, noCache?: boolean, till?: number) => Promise<IResponse>
39
39
 
40
40
  export type IFetchSegmentChanges = (since: number, segmentName: string, noCache?: boolean, till?: number) => Promise<IResponse>
41
41
 
@@ -37,14 +37,6 @@ export abstract class AbstractSplitsCacheAsync implements ISplitsCacheAsync {
37
37
  return Promise.resolve(true);
38
38
  }
39
39
 
40
- /**
41
- * Check if the splits information is already stored in cache.
42
- * Noop, just keeping the interface. This is used by client-side implementations only.
43
- */
44
- checkCache(): Promise<boolean> {
45
- return Promise.resolve(false);
46
- }
47
-
48
40
  /**
49
41
  * Kill `name` split and set `defaultTreatment` and `changeNumber`.
50
42
  * Used for SPLIT_KILL push notifications.
@@ -1,5 +1,5 @@
1
1
  import { ISplitsCacheSync } from './types';
2
- import { IRBSegment, ISplit } from '../dtos/types';
2
+ import { ISplit } from '../dtos/types';
3
3
  import { objectAssign } from '../utils/lang/objectAssign';
4
4
  import { IN_SEGMENT, IN_LARGE_SEGMENT } from '../utils/constants';
5
5
 
@@ -43,14 +43,6 @@ export abstract class AbstractSplitsCacheSync implements ISplitsCacheSync {
43
43
 
44
44
  abstract clear(): void
45
45
 
46
- /**
47
- * Check if the splits information is already stored in cache. This data can be preloaded.
48
- * It is used as condition to emit SDK_SPLITS_CACHE_LOADED, and then SDK_READY_FROM_CACHE.
49
- */
50
- checkCache(): boolean {
51
- return false;
52
- }
53
-
54
46
  /**
55
47
  * Kill `name` split and set `defaultTreatment` and `changeNumber`.
56
48
  * Used for SPLIT_KILL push notifications.
@@ -80,8 +72,8 @@ export abstract class AbstractSplitsCacheSync implements ISplitsCacheSync {
80
72
  * Given a parsed split, it returns a boolean flagging if its conditions use segments matchers (rules & whitelists).
81
73
  * This util is intended to simplify the implementation of `splitsCache::usesSegments` method
82
74
  */
83
- export function usesSegments(ruleEntity: ISplit | IRBSegment) {
84
- const conditions = ruleEntity.conditions || [];
75
+ export function usesSegments(split: ISplit) {
76
+ const conditions = split.conditions || [];
85
77
  for (let i = 0; i < conditions.length; i++) {
86
78
  const matchers = conditions[i].matcherGroup.matchers;
87
79
 
@@ -91,8 +83,5 @@ export function usesSegments(ruleEntity: ISplit | IRBSegment) {
91
83
  }
92
84
  }
93
85
 
94
- const excluded = (ruleEntity as IRBSegment).excluded;
95
- if (excluded && excluded.segments && excluded.segments.length > 0) return true;
96
-
97
86
  return false;
98
87
  }
@@ -37,18 +37,6 @@ export class KeyBuilder {
37
37
  return `${this.prefix}.split.`;
38
38
  }
39
39
 
40
- buildRBSegmentKey(rbsegmentName: string) {
41
- return `${this.prefix}.rbsegment.${rbsegmentName}`;
42
- }
43
-
44
- buildRBSegmentsTillKey() {
45
- return `${this.prefix}.rbsegments.till`;
46
- }
47
-
48
- buildRBSegmentKeyPrefix() {
49
- return `${this.prefix}.rbsegment.`;
50
- }
51
-
52
40
  buildSegmentNameKey(segmentName: string) {
53
41
  return `${this.prefix}.segment.${segmentName}`;
54
42
  }
@@ -15,7 +15,7 @@ export class KeyBuilderCS extends KeyBuilder implements MySegmentsKeyBuilder {
15
15
  constructor(prefix: string, matchingKey: string) {
16
16
  super(prefix);
17
17
  this.matchingKey = matchingKey;
18
- this.regexSplitsCacheKey = new RegExp(`^${prefix}\\.(splits?|trafficType|flagSet|rbsegment)\\.`);
18
+ this.regexSplitsCacheKey = new RegExp(`^${prefix}\\.(splits?|trafficType|flagSet)\\.`);
19
19
  }
20
20
 
21
21
  /**
@@ -47,13 +47,13 @@ export class KeyBuilderCS extends KeyBuilder implements MySegmentsKeyBuilder {
47
47
  return startsWith(key, `${this.prefix}.split.`);
48
48
  }
49
49
 
50
- isRBSegmentKey(key: string) {
51
- return startsWith(key, `${this.prefix}.rbsegment.`);
52
- }
53
-
54
50
  buildSplitsWithSegmentCountKey() {
55
51
  return `${this.prefix}.splits.usingSegments`;
56
52
  }
53
+
54
+ buildLastClear() {
55
+ return `${this.prefix}.lastClear`;
56
+ }
57
57
  }
58
58
 
59
59
  export function myLargeSegmentsKeyBuilder(prefix: string, matchingKey: string): MySegmentsKeyBuilder {
@@ -53,10 +53,6 @@ export class KeyBuilderSS extends KeyBuilder {
53
53
  return `${this.buildSplitKeyPrefix()}*`;
54
54
  }
55
55
 
56
- searchPatternForRBSegmentKeys() {
57
- return `${this.buildRBSegmentKeyPrefix()}*`;
58
- }
59
-
60
56
  /* Telemetry keys */
61
57
 
62
58
  buildLatencyKey(method: Method, bucket: number) {
@@ -1,7 +1,9 @@
1
1
  import { PreloadedData } from '../types';
2
- import { DEFAULT_CACHE_EXPIRATION_IN_MILLIS } from '../utils/constants/browser';
3
2
  import { DataLoader, ISegmentsCacheSync, ISplitsCacheSync } from './types';
4
3
 
4
+ // This value might be eventually set via a config parameter
5
+ const DEFAULT_CACHE_EXPIRATION_IN_MILLIS = 864000000; // 10 days
6
+
5
7
  /**
6
8
  * Factory of client-side storage loader
7
9
  *
@@ -5,7 +5,6 @@ import { KeyBuilderCS } from '../KeyBuilderCS';
5
5
  import { ILogger } from '../../logger/types';
6
6
  import { LOG_PREFIX } from './constants';
7
7
  import { ISettings } from '../../types';
8
- import { getStorageHash } from '../KeyBuilder';
9
8
  import { setToArray } from '../../utils/lang/sets';
10
9
 
11
10
  /**
@@ -15,21 +14,14 @@ export class SplitsCacheInLocal extends AbstractSplitsCacheSync {
15
14
 
16
15
  private readonly keys: KeyBuilderCS;
17
16
  private readonly log: ILogger;
18
- private readonly storageHash: string;
19
17
  private readonly flagSetsFilter: string[];
20
18
  private hasSync?: boolean;
21
- private updateNewFilter?: boolean;
22
19
 
23
- constructor(settings: ISettings, keys: KeyBuilderCS, expirationTimestamp?: number) {
20
+ constructor(settings: ISettings, keys: KeyBuilderCS) {
24
21
  super();
25
22
  this.keys = keys;
26
23
  this.log = settings.log;
27
- this.storageHash = getStorageHash(settings);
28
24
  this.flagSetsFilter = settings.sync.__splitFiltersValidation.groupedFilters.bySet;
29
-
30
- this._checkExpiration(expirationTimestamp);
31
-
32
- this._checkFilterQuery();
33
25
  }
34
26
 
35
27
  private _decrementCount(key: string) {
@@ -39,16 +31,14 @@ export class SplitsCacheInLocal extends AbstractSplitsCacheSync {
39
31
  else localStorage.removeItem(key);
40
32
  }
41
33
 
42
- private _decrementCounts(split: ISplit | null) {
34
+ private _decrementCounts(split: ISplit) {
43
35
  try {
44
- if (split) {
45
- const ttKey = this.keys.buildTrafficTypeKey(split.trafficTypeName);
46
- this._decrementCount(ttKey);
36
+ const ttKey = this.keys.buildTrafficTypeKey(split.trafficTypeName);
37
+ this._decrementCount(ttKey);
47
38
 
48
- if (usesSegments(split)) {
49
- const segmentsCountKey = this.keys.buildSplitsWithSegmentCountKey();
50
- this._decrementCount(segmentsCountKey);
51
- }
39
+ if (usesSegments(split)) {
40
+ const segmentsCountKey = this.keys.buildSplitsWithSegmentCountKey();
41
+ this._decrementCount(segmentsCountKey);
52
42
  }
53
43
  } catch (e) {
54
44
  this.log.error(LOG_PREFIX + e);
@@ -57,14 +47,16 @@ export class SplitsCacheInLocal extends AbstractSplitsCacheSync {
57
47
 
58
48
  private _incrementCounts(split: ISplit) {
59
49
  try {
60
- const ttKey = this.keys.buildTrafficTypeKey(split.trafficTypeName);
61
- // @ts-expect-error
62
- localStorage.setItem(ttKey, toNumber(localStorage.getItem(ttKey)) + 1);
63
-
64
- if (usesSegments(split)) {
65
- const segmentsCountKey = this.keys.buildSplitsWithSegmentCountKey();
50
+ if (split) {
51
+ const ttKey = this.keys.buildTrafficTypeKey(split.trafficTypeName);
66
52
  // @ts-expect-error
67
- localStorage.setItem(segmentsCountKey, toNumber(localStorage.getItem(segmentsCountKey)) + 1);
53
+ localStorage.setItem(ttKey, toNumber(localStorage.getItem(ttKey)) + 1);
54
+
55
+ if (usesSegments(split)) {
56
+ const segmentsCountKey = this.keys.buildSplitsWithSegmentCountKey();
57
+ // @ts-expect-error
58
+ localStorage.setItem(segmentsCountKey, toNumber(localStorage.getItem(segmentsCountKey)) + 1);
59
+ }
68
60
  }
69
61
  } catch (e) {
70
62
  this.log.error(LOG_PREFIX + e);
@@ -77,8 +69,6 @@ export class SplitsCacheInLocal extends AbstractSplitsCacheSync {
77
69
  * We cannot simply call `localStorage.clear()` since that implies removing user items from the storage.
78
70
  */
79
71
  clear() {
80
- this.log.info(LOG_PREFIX + 'Flushing Splits data from localStorage');
81
-
82
72
  // collect item keys
83
73
  const len = localStorage.length;
84
74
  const accum = [];
@@ -101,12 +91,14 @@ export class SplitsCacheInLocal extends AbstractSplitsCacheSync {
101
91
  const splitFromLocalStorage = localStorage.getItem(splitKey);
102
92
  const previousSplit = splitFromLocalStorage ? JSON.parse(splitFromLocalStorage) : null;
103
93
 
94
+ if (previousSplit) {
95
+ this._decrementCounts(previousSplit);
96
+ this.removeFromFlagSets(previousSplit.name, previousSplit.sets);
97
+ }
98
+
104
99
  localStorage.setItem(splitKey, JSON.stringify(split));
105
100
 
106
101
  this._incrementCounts(split);
107
- this._decrementCounts(previousSplit);
108
-
109
- if (previousSplit) this.removeFromFlagSets(previousSplit.name, previousSplit.sets);
110
102
  this.addToFlagSets(split);
111
103
 
112
104
  return true;
@@ -124,7 +116,7 @@ export class SplitsCacheInLocal extends AbstractSplitsCacheSync {
124
116
  localStorage.removeItem(this.keys.buildSplitKey(name));
125
117
 
126
118
  this._decrementCounts(split);
127
- if (split) this.removeFromFlagSets(split.name, split.sets);
119
+ this.removeFromFlagSets(split.name, split.sets);
128
120
 
129
121
  return true;
130
122
  } catch (e) {
@@ -139,19 +131,6 @@ export class SplitsCacheInLocal extends AbstractSplitsCacheSync {
139
131
  }
140
132
 
141
133
  setChangeNumber(changeNumber: number): boolean {
142
-
143
- // when using a new split query, we must update it at the store
144
- if (this.updateNewFilter) {
145
- this.log.info(LOG_PREFIX + 'SDK key, flags filter criteria or flags spec version was modified. Updating cache');
146
- const storageHashKey = this.keys.buildHashKey();
147
- try {
148
- localStorage.setItem(storageHashKey, this.storageHash);
149
- } catch (e) {
150
- this.log.error(LOG_PREFIX + e);
151
- }
152
- this.updateNewFilter = false;
153
- }
154
-
155
134
  try {
156
135
  localStorage.setItem(this.keys.buildSplitsTillKey(), changeNumber + '');
157
136
  // update "last updated" timestamp with current time
@@ -206,51 +185,11 @@ export class SplitsCacheInLocal extends AbstractSplitsCacheSync {
206
185
  const storedCount = localStorage.getItem(this.keys.buildSplitsWithSegmentCountKey());
207
186
  const splitsWithSegmentsCount = storedCount === null ? 0 : toNumber(storedCount);
208
187
 
209
- return isFiniteNumber(splitsWithSegmentsCount) ?
210
- splitsWithSegmentsCount > 0 :
211
- true;
212
- }
213
-
214
- /**
215
- * Check if the splits information is already stored in browser LocalStorage.
216
- * In this function we could add more code to check if the data is valid.
217
- * @override
218
- */
219
- checkCache(): boolean {
220
- return this.getChangeNumber() > -1;
221
- }
222
-
223
- /**
224
- * Clean Splits cache if its `lastUpdated` timestamp is older than the given `expirationTimestamp`,
225
- *
226
- * @param expirationTimestamp - if the value is not a number, data will not be cleaned
227
- */
228
- private _checkExpiration(expirationTimestamp?: number) {
229
- let value: string | number | null = localStorage.getItem(this.keys.buildLastUpdatedKey());
230
- if (value !== null) {
231
- value = parseInt(value, 10);
232
- if (!isNaNNumber(value) && expirationTimestamp && value < expirationTimestamp) this.clear();
233
- }
234
- }
235
-
236
- // @TODO eventually remove `_checkFilterQuery`. Cache should be cleared at the storage level, reusing same logic than PluggableStorage
237
- private _checkFilterQuery() {
238
- const storageHashKey = this.keys.buildHashKey();
239
- const storageHash = localStorage.getItem(storageHashKey);
240
-
241
- if (storageHash !== this.storageHash) {
242
- try {
243
- // mark cache to update the new query filter on first successful splits fetch
244
- this.updateNewFilter = true;
245
-
246
- // if there is cache, clear it
247
- if (this.checkCache()) this.clear();
248
-
249
- } catch (e) {
250
- this.log.error(LOG_PREFIX + e);
251
- }
188
+ if (isFiniteNumber(splitsWithSegmentsCount)) {
189
+ return splitsWithSegmentsCount > 0;
190
+ } else {
191
+ return true;
252
192
  }
253
- // if the filter didn't change, nothing is done
254
193
  }
255
194
 
256
195
  getNamesByFlagSets(flagSets: string[]): Set<string>[] {
@@ -7,23 +7,19 @@ import { KeyBuilderCS, myLargeSegmentsKeyBuilder } from '../KeyBuilderCS';
7
7
  import { isLocalStorageAvailable } from '../../utils/env/isLocalStorageAvailable';
8
8
  import { SplitsCacheInLocal } from './SplitsCacheInLocal';
9
9
  import { MySegmentsCacheInLocal } from './MySegmentsCacheInLocal';
10
- import { DEFAULT_CACHE_EXPIRATION_IN_MILLIS } from '../../utils/constants/browser';
11
10
  import { InMemoryStorageCSFactory } from '../inMemory/InMemoryStorageCS';
12
11
  import { LOG_PREFIX } from './constants';
13
12
  import { STORAGE_LOCALSTORAGE } from '../../utils/constants';
14
13
  import { shouldRecordTelemetry, TelemetryCacheInMemory } from '../inMemory/TelemetryCacheInMemory';
15
14
  import { UniqueKeysCacheInMemoryCS } from '../inMemory/UniqueKeysCacheInMemoryCS';
16
15
  import { getMatching } from '../../utils/key';
17
- import { RBSegmentsCacheInLocal } from './RBSegmentsCacheInLocal';
18
-
19
- export interface InLocalStorageOptions {
20
- prefix?: string
21
- }
16
+ import { validateCache } from './validateCache';
17
+ import SplitIO from '../../../types/splitio';
22
18
 
23
19
  /**
24
20
  * InLocal storage factory for standalone client-side SplitFactory
25
21
  */
26
- export function InLocalStorage(options: InLocalStorageOptions = {}): IStorageSyncFactory {
22
+ export function InLocalStorage(options: SplitIO.InLocalStorageOptions = {}): IStorageSyncFactory {
27
23
 
28
24
  const prefix = validatePrefix(options.prefix);
29
25
 
@@ -38,16 +34,13 @@ export function InLocalStorage(options: InLocalStorageOptions = {}): IStorageSyn
38
34
  const { settings, settings: { log, scheduler: { impressionsQueueSize, eventsQueueSize } } } = params;
39
35
  const matchingKey = getMatching(settings.core.key);
40
36
  const keys = new KeyBuilderCS(prefix, matchingKey);
41
- const expirationTimestamp = Date.now() - DEFAULT_CACHE_EXPIRATION_IN_MILLIS;
42
37
 
43
- const splits = new SplitsCacheInLocal(settings, keys, expirationTimestamp);
44
- const rbSegments = new RBSegmentsCacheInLocal(settings, keys);
38
+ const splits = new SplitsCacheInLocal(settings, keys);
45
39
  const segments = new MySegmentsCacheInLocal(log, keys);
46
40
  const largeSegments = new MySegmentsCacheInLocal(log, myLargeSegmentsKeyBuilder(prefix, matchingKey));
47
41
 
48
42
  return {
49
43
  splits,
50
- rbSegments,
51
44
  segments,
52
45
  largeSegments,
53
46
  impressions: new ImpressionsCacheInMemory(impressionsQueueSize),
@@ -56,6 +49,10 @@ export function InLocalStorage(options: InLocalStorageOptions = {}): IStorageSyn
56
49
  telemetry: shouldRecordTelemetry(params) ? new TelemetryCacheInMemory(splits, segments) : undefined,
57
50
  uniqueKeys: new UniqueKeysCacheInMemoryCS(),
58
51
 
52
+ validateCache() {
53
+ return validateCache(options, settings, keys, splits, segments, largeSegments);
54
+ },
55
+
59
56
  destroy() { },
60
57
 
61
58
  // When using shared instantiation with MEMORY we reuse everything but segments (they are customer per key).
@@ -63,7 +60,6 @@ export function InLocalStorage(options: InLocalStorageOptions = {}): IStorageSyn
63
60
 
64
61
  return {
65
62
  splits: this.splits,
66
- rbSegments: this.rbSegments,
67
63
  segments: new MySegmentsCacheInLocal(log, new KeyBuilderCS(prefix, matchingKey)),
68
64
  largeSegments: new MySegmentsCacheInLocal(log, myLargeSegmentsKeyBuilder(prefix, matchingKey)),
69
65
  impressions: this.impressions,