@splitsoftware/splitio-commons 0.1.1-canary.9 → 0.1.1-rc.18

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 (254) hide show
  1. package/cjs/evaluator/matchers/matcherTypes.js +4 -4
  2. package/cjs/evaluator/matchersTransform/index.js +11 -11
  3. package/cjs/evaluator/value/sanitize.js +6 -6
  4. package/cjs/listeners/browser.js +1 -2
  5. package/cjs/listeners/node.js +0 -3
  6. package/cjs/logger/constants.js +3 -1
  7. package/cjs/logger/messages/error.js +3 -2
  8. package/cjs/logger/messages/info.js +2 -2
  9. package/cjs/logger/messages/warn.js +2 -1
  10. package/cjs/readiness/readinessManager.js +10 -7
  11. package/cjs/sdkFactory/index.js +1 -4
  12. package/cjs/services/splitApi.js +1 -1
  13. package/cjs/services/splitHttpClient.js +5 -4
  14. package/cjs/storages/AbstractSplitsCacheSync.js +1 -1
  15. package/cjs/storages/inLocalStorage/index.js +5 -2
  16. package/cjs/storages/inMemory/InMemoryStorage.js +2 -0
  17. package/cjs/storages/inMemory/InMemoryStorageCS.js +2 -0
  18. package/cjs/storages/inRedis/SplitsCacheInRedis.js +6 -2
  19. package/cjs/storages/inRedis/index.js +5 -2
  20. package/cjs/storages/pluggable/SplitsCachePluggable.js +6 -2
  21. package/cjs/storages/pluggable/inMemoryWrapper.js +6 -7
  22. package/cjs/storages/pluggable/index.js +5 -2
  23. package/cjs/storages/pluggable/wrapperAdapter.js +0 -1
  24. package/cjs/sync/offline/splitsParser/splitsParserFromFile.js +92 -89
  25. package/cjs/sync/offline/splitsParser/splitsParserFromSettings.js +45 -42
  26. package/cjs/sync/offline/syncTasks/fromObjectSyncTask.js +14 -4
  27. package/cjs/sync/polling/updaters/mySegmentsUpdater.js +30 -10
  28. package/cjs/sync/streaming/SSEClient/index.js +0 -11
  29. package/cjs/sync/streaming/SSEHandler/NotificationKeeper.js +7 -0
  30. package/cjs/sync/streaming/SSEHandler/NotificationParser.js +4 -1
  31. package/cjs/sync/streaming/SSEHandler/index.js +8 -9
  32. package/cjs/sync/streaming/SSEHandler/types.js +14 -0
  33. package/cjs/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.js +5 -5
  34. package/cjs/sync/streaming/UpdateWorkers/SegmentsUpdateWorker.js +2 -1
  35. package/cjs/sync/streaming/UpdateWorkers/SplitsUpdateWorker.js +5 -3
  36. package/cjs/sync/streaming/constants.js +3 -1
  37. package/cjs/sync/streaming/mySegmentsV2utils.js +75 -0
  38. package/cjs/sync/streaming/pushManager.js +141 -40
  39. package/cjs/sync/submitters/metricsSyncTask.js +1 -1
  40. package/cjs/sync/submitters/submitterSyncTask.js +2 -2
  41. package/cjs/sync/syncManagerFromFile.js +15 -0
  42. package/cjs/sync/syncManagerFromObject.js +14 -0
  43. package/cjs/sync/syncManagerOffline.js +3 -3
  44. package/cjs/sync/syncManagerOnline.js +5 -3
  45. package/cjs/trackers/impressionObserver/ImpressionObserver.js +0 -2
  46. package/cjs/trackers/impressionObserver/buildKey.js +3 -9
  47. package/cjs/trackers/impressionObserver/impressionObserverCS.js +2 -2
  48. package/cjs/trackers/impressionObserver/impressionObserverSS.js +3 -3
  49. package/cjs/utils/constants/index.js +4 -1
  50. package/cjs/utils/decompress/index.js +427 -0
  51. package/cjs/utils/murmur3/{commons.js → common.js} +2 -6
  52. package/cjs/utils/murmur3/murmur3.js +11 -12
  53. package/cjs/utils/murmur3/murmur3_128.js +7 -142
  54. package/cjs/utils/murmur3/murmur3_128_x86.js +154 -0
  55. package/cjs/utils/murmur3/murmur3_64.js +36 -0
  56. package/cjs/utils/murmur3/utfx.js +100 -106
  57. package/cjs/utils/promise/wrapper.js +14 -11
  58. package/cjs/utils/settingsValidation/index.js +5 -2
  59. package/cjs/utils/settingsValidation/localhost/index.js +20 -0
  60. package/cjs/utils/settingsValidation/splitFilters.js +0 -1
  61. package/cjs/utils/settingsValidation/storage/storageCS.js +18 -8
  62. package/cjs/utils/settingsValidation/url.js +1 -1
  63. package/esm/evaluator/matchers/matcherTypes.js +2 -2
  64. package/esm/evaluator/matchersTransform/index.js +12 -12
  65. package/esm/evaluator/value/sanitize.js +7 -7
  66. package/esm/listeners/browser.js +1 -2
  67. package/esm/listeners/node.js +0 -3
  68. package/esm/logger/constants.js +2 -0
  69. package/esm/logger/messages/error.js +3 -2
  70. package/esm/logger/messages/info.js +2 -2
  71. package/esm/logger/messages/warn.js +2 -1
  72. package/esm/readiness/readinessManager.js +10 -7
  73. package/esm/sdkFactory/index.js +1 -4
  74. package/esm/services/splitApi.js +1 -1
  75. package/esm/services/splitHttpClient.js +5 -4
  76. package/esm/storages/AbstractSplitsCacheSync.js +1 -1
  77. package/esm/storages/inLocalStorage/index.js +5 -2
  78. package/esm/storages/inMemory/InMemoryStorage.js +2 -0
  79. package/esm/storages/inMemory/InMemoryStorageCS.js +2 -0
  80. package/esm/storages/inRedis/SplitsCacheInRedis.js +6 -2
  81. package/esm/storages/inRedis/index.js +5 -2
  82. package/esm/storages/pluggable/SplitsCachePluggable.js +6 -2
  83. package/esm/storages/pluggable/inMemoryWrapper.js +6 -7
  84. package/esm/storages/pluggable/index.js +5 -2
  85. package/esm/storages/pluggable/wrapperAdapter.js +0 -1
  86. package/esm/sync/offline/splitsParser/splitsParserFromFile.js +90 -88
  87. package/esm/sync/offline/splitsParser/splitsParserFromSettings.js +43 -41
  88. package/esm/sync/offline/syncTasks/fromObjectSyncTask.js +15 -5
  89. package/esm/sync/polling/updaters/mySegmentsUpdater.js +30 -10
  90. package/esm/sync/streaming/SSEClient/index.js +0 -11
  91. package/esm/sync/streaming/SSEHandler/NotificationKeeper.js +7 -0
  92. package/esm/sync/streaming/SSEHandler/NotificationParser.js +4 -1
  93. package/esm/sync/streaming/SSEHandler/index.js +9 -10
  94. package/esm/sync/streaming/SSEHandler/types.js +13 -1
  95. package/esm/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.js +5 -5
  96. package/esm/sync/streaming/UpdateWorkers/SegmentsUpdateWorker.js +2 -1
  97. package/esm/sync/streaming/UpdateWorkers/SplitsUpdateWorker.js +5 -3
  98. package/esm/sync/streaming/constants.js +2 -0
  99. package/esm/sync/streaming/mySegmentsV2utils.js +69 -0
  100. package/esm/sync/streaming/pushManager.js +143 -42
  101. package/esm/sync/submitters/metricsSyncTask.js +1 -1
  102. package/esm/sync/submitters/submitterSyncTask.js +2 -2
  103. package/esm/sync/syncManagerFromFile.js +11 -0
  104. package/esm/sync/syncManagerFromObject.js +10 -0
  105. package/esm/sync/syncManagerOffline.js +3 -3
  106. package/esm/sync/syncManagerOnline.js +5 -3
  107. package/esm/trackers/impressionObserver/ImpressionObserver.js +0 -2
  108. package/esm/trackers/impressionObserver/buildKey.js +2 -9
  109. package/esm/trackers/impressionObserver/impressionObserverCS.js +2 -2
  110. package/esm/trackers/impressionObserver/impressionObserverSS.js +3 -3
  111. package/esm/utils/constants/index.js +3 -0
  112. package/esm/utils/decompress/index.js +424 -0
  113. package/esm/utils/murmur3/{commons.js → common.js} +1 -4
  114. package/esm/utils/murmur3/murmur3.js +1 -2
  115. package/esm/utils/murmur3/murmur3_128.js +7 -142
  116. package/esm/utils/murmur3/murmur3_128_x86.js +150 -0
  117. package/esm/utils/murmur3/murmur3_64.js +32 -0
  118. package/esm/utils/murmur3/utfx.js +96 -106
  119. package/esm/utils/promise/wrapper.js +14 -11
  120. package/esm/utils/settingsValidation/index.js +5 -2
  121. package/esm/utils/settingsValidation/localhost/index.js +16 -0
  122. package/esm/utils/settingsValidation/splitFilters.js +0 -1
  123. package/esm/utils/settingsValidation/storage/storageCS.js +16 -7
  124. package/esm/utils/settingsValidation/url.js +1 -1
  125. package/package.json +5 -5
  126. package/src/evaluator/matchers/matcherTypes.ts +2 -2
  127. package/src/evaluator/matchersTransform/index.ts +12 -12
  128. package/src/evaluator/value/sanitize.ts +7 -7
  129. package/src/listeners/browser.ts +1 -1
  130. package/src/listeners/node.ts +1 -2
  131. package/src/logger/constants.ts +2 -0
  132. package/src/logger/messages/error.ts +3 -2
  133. package/src/logger/messages/info.ts +2 -2
  134. package/src/logger/messages/warn.ts +3 -1
  135. package/src/readiness/readinessManager.ts +9 -7
  136. package/src/sdkFactory/index.ts +1 -3
  137. package/src/sdkFactory/types.ts +3 -3
  138. package/src/services/splitApi.ts +2 -3
  139. package/src/services/splitHttpClient.ts +6 -5
  140. package/src/services/types.ts +5 -5
  141. package/src/storages/AbstractSplitsCacheSync.ts +1 -1
  142. package/src/storages/inLocalStorage/index.ts +8 -4
  143. package/src/storages/inMemory/InMemoryStorage.ts +3 -0
  144. package/src/storages/inMemory/InMemoryStorageCS.ts +3 -0
  145. package/src/storages/inRedis/SplitsCacheInRedis.ts +3 -1
  146. package/src/storages/inRedis/index.ts +8 -4
  147. package/src/storages/pluggable/SplitsCachePluggable.ts +3 -1
  148. package/src/storages/pluggable/inMemoryWrapper.ts +6 -7
  149. package/src/storages/pluggable/index.ts +8 -4
  150. package/src/storages/pluggable/wrapperAdapter.ts +0 -1
  151. package/src/storages/types.ts +18 -15
  152. package/src/sync/offline/splitsParser/splitsParserFromFile.ts +110 -105
  153. package/src/sync/offline/splitsParser/splitsParserFromSettings.ts +45 -41
  154. package/src/sync/offline/syncTasks/fromObjectSyncTask.ts +15 -5
  155. package/src/sync/polling/types.ts +2 -1
  156. package/src/sync/polling/updaters/mySegmentsUpdater.ts +28 -10
  157. package/src/sync/streaming/AuthClient/types.ts +3 -0
  158. package/src/sync/streaming/SSEClient/index.ts +1 -15
  159. package/src/sync/streaming/SSEClient/types.ts +0 -1
  160. package/src/sync/streaming/SSEHandler/NotificationKeeper.ts +8 -0
  161. package/src/sync/streaming/SSEHandler/NotificationParser.ts +4 -2
  162. package/src/sync/streaming/SSEHandler/index.ts +11 -20
  163. package/src/sync/streaming/SSEHandler/types.ts +37 -3
  164. package/src/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.ts +7 -6
  165. package/src/sync/streaming/UpdateWorkers/SegmentsUpdateWorker.ts +2 -1
  166. package/src/sync/streaming/UpdateWorkers/SplitsUpdateWorker.ts +4 -3
  167. package/src/sync/streaming/UpdateWorkers/types.ts +1 -1
  168. package/src/sync/streaming/constants.ts +2 -0
  169. package/src/sync/streaming/mySegmentsV2utils.ts +77 -0
  170. package/src/sync/streaming/pushManager.ts +139 -42
  171. package/src/sync/streaming/types.ts +14 -22
  172. package/src/sync/submitters/metricsSyncTask.ts +1 -1
  173. package/src/sync/submitters/submitterSyncTask.ts +2 -1
  174. package/src/sync/syncManagerFromFile.ts +13 -0
  175. package/src/sync/syncManagerFromObject.ts +12 -0
  176. package/src/sync/syncManagerOffline.ts +3 -3
  177. package/src/sync/syncManagerOnline.ts +6 -3
  178. package/src/trackers/impressionObserver/ImpressionObserver.ts +4 -6
  179. package/src/trackers/impressionObserver/buildKey.ts +2 -16
  180. package/src/trackers/impressionObserver/impressionObserverCS.ts +2 -2
  181. package/src/trackers/impressionObserver/impressionObserverSS.ts +3 -3
  182. package/src/types.ts +16 -2
  183. package/src/utils/constants/index.ts +6 -1
  184. package/src/utils/decompress/index.ts +429 -0
  185. package/src/utils/murmur3/{commons.ts → common.ts} +1 -5
  186. package/src/utils/murmur3/murmur3.ts +5 -5
  187. package/src/utils/murmur3/murmur3_128.ts +7 -180
  188. package/src/utils/murmur3/murmur3_128_x86.ts +188 -0
  189. package/src/utils/murmur3/murmur3_64.ts +36 -0
  190. package/src/utils/murmur3/utfx.ts +92 -110
  191. package/src/utils/promise/wrapper.ts +12 -9
  192. package/src/utils/settingsValidation/index.ts +8 -4
  193. package/src/utils/settingsValidation/localhost/index.ts +19 -0
  194. package/src/utils/settingsValidation/splitFilters.ts +0 -1
  195. package/src/utils/settingsValidation/storage/storageCS.ts +21 -8
  196. package/src/utils/settingsValidation/types.ts +2 -11
  197. package/src/utils/settingsValidation/url.ts +1 -1
  198. package/types/evaluator/matchers/matcherTypes.d.ts +2 -2
  199. package/types/listeners/browser.d.ts +1 -0
  200. package/types/listeners/node.d.ts +0 -1
  201. package/types/logger/constants.d.ts +2 -0
  202. package/types/sdkFactory/types.d.ts +3 -3
  203. package/types/services/types.d.ts +1 -0
  204. package/types/storages/inLocalStorage/index.d.ts +2 -2
  205. package/types/storages/inMemory/InMemoryStorage.d.ts +3 -0
  206. package/types/storages/inMemory/InMemoryStorageCS.d.ts +3 -0
  207. package/types/storages/inRedis/index.d.ts +2 -2
  208. package/types/storages/pluggable/index.d.ts +2 -2
  209. package/types/storages/types.d.ts +15 -15
  210. package/types/sync/offline/splitsParser/splitsParserFromFile.d.ts +2 -7
  211. package/types/sync/offline/splitsParser/splitsParserFromSettings.d.ts +1 -5
  212. package/types/sync/polling/types.d.ts +2 -1
  213. package/types/sync/streaming/AuthClient/indexV1.d.ts +12 -0
  214. package/types/sync/streaming/AuthClient/indexV2.d.ts +8 -0
  215. package/types/sync/streaming/AuthClient/types.d.ts +2 -0
  216. package/types/sync/streaming/SSEClient/index.d.ts +1 -9
  217. package/types/sync/streaming/SSEClient/types.d.ts +0 -1
  218. package/types/sync/streaming/SSEHandler/NotificationParser.d.ts +3 -2
  219. package/types/sync/streaming/SSEHandler/types.d.ts +30 -2
  220. package/types/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.d.ts +4 -3
  221. package/types/sync/streaming/UpdateWorkers/SegmentsUpdateWorker.d.ts +2 -1
  222. package/types/sync/streaming/UpdateWorkers/SplitsUpdateWorker.d.ts +3 -2
  223. package/types/sync/streaming/UpdateWorkers/types.d.ts +1 -1
  224. package/types/sync/streaming/constants.d.ts +3 -1
  225. package/types/sync/streaming/mySegmentsV2utils.d.ts +27 -0
  226. package/types/sync/streaming/pushManagerNoUsers.d.ts +13 -0
  227. package/types/sync/streaming/types.d.ts +9 -5
  228. package/types/sync/submitters/submitterSyncTask.d.ts +1 -1
  229. package/types/sync/syncManagerFromFile.d.ts +2 -0
  230. package/types/sync/syncManagerFromObject.d.ts +2 -0
  231. package/types/sync/syncManagerOffline.d.ts +1 -1
  232. package/types/trackers/impressionObserver/ImpressionObserver.d.ts +2 -2
  233. package/types/trackers/impressionObserver/buildKey.d.ts +1 -1
  234. package/types/trackers/impressionObserver/impressionObserverCS.d.ts +2 -2
  235. package/types/trackers/impressionObserver/impressionObserverSS.d.ts +2 -2
  236. package/types/types.d.ts +16 -2
  237. package/types/utils/constants/index.d.ts +5 -1
  238. package/types/utils/decompress/index.d.ts +16 -0
  239. package/types/utils/murmur3/common.d.ts +12 -0
  240. package/types/utils/murmur3/murmur3.d.ts +2 -2
  241. package/types/utils/murmur3/murmur3_128.d.ts +5 -0
  242. package/types/utils/murmur3/murmur3_128_x86.d.ts +7 -0
  243. package/types/utils/murmur3/murmur3_64.d.ts +10 -0
  244. package/types/utils/murmur3/utfx.d.ts +24 -6
  245. package/types/utils/settingsValidation/index.d.ts +3 -2
  246. package/types/utils/settingsValidation/localhost/index.d.ts +9 -0
  247. package/types/utils/settingsValidation/storage/storageCS.d.ts +7 -1
  248. package/types/utils/settingsValidation/types.d.ts +2 -10
  249. package/cjs/sync/streaming/pushManagerCS.js +0 -179
  250. package/cjs/sync/streaming/pushManagerSS.js +0 -128
  251. package/esm/sync/streaming/pushManagerCS.js +0 -175
  252. package/esm/sync/streaming/pushManagerSS.js +0 -124
  253. package/src/sync/streaming/pushManagerCS.ts +0 -238
  254. package/src/sync/streaming/pushManagerSS.ts +0 -177
@@ -1,5 +1,5 @@
1
1
  import { findIndex } from '../../utils/lang';
2
- import { matcherTypes, mapper, dataTypes } from '../matchers/matcherTypes';
2
+ import { matcherTypes, matcherTypesMapper, matcherDataTypes } from '../matchers/matcherTypes';
3
3
  import segmentTransform from './segment';
4
4
  import whitelistTransform from './whitelist';
5
5
  import setTransform from './set';
@@ -28,9 +28,9 @@ export default function matchersTransform(matchers: ISplitMatcher[]): IMatcherDt
28
28
  } = matcher;
29
29
 
30
30
  let attribute = keySelector && keySelector.attribute;
31
- let type = mapper(matcherType);
31
+ let type = matcherTypesMapper(matcherType);
32
32
  // As default input data type we use string (even for ALL_KEYS)
33
- let dataType = dataTypes.STRING;
33
+ let dataType = matcherDataTypes.STRING;
34
34
  let value = undefined;
35
35
 
36
36
  if (type === matcherTypes.IN_SEGMENT) {
@@ -39,29 +39,29 @@ export default function matchersTransform(matchers: ISplitMatcher[]): IMatcherDt
39
39
  value = whitelistTransform(whitelistObject as IWhitelistMatcherData);
40
40
  } else if (type === matcherTypes.EQUAL_TO) {
41
41
  value = numericTransform(unaryNumericObject as IUnaryNumericMatcherData);
42
- dataType = dataTypes.NUMBER;
42
+ dataType = matcherDataTypes.NUMBER;
43
43
 
44
44
  if ((unaryNumericObject as IUnaryNumericMatcherData).dataType === 'DATETIME') {
45
45
  value = zeroSinceHH(value);
46
- dataType = dataTypes.DATETIME;
46
+ dataType = matcherDataTypes.DATETIME;
47
47
  }
48
48
  } else if (type === matcherTypes.GREATER_THAN_OR_EQUAL_TO ||
49
49
  type === matcherTypes.LESS_THAN_OR_EQUAL_TO) {
50
50
  value = numericTransform(unaryNumericObject as IUnaryNumericMatcherData);
51
- dataType = dataTypes.NUMBER;
51
+ dataType = matcherDataTypes.NUMBER;
52
52
 
53
53
  if ((unaryNumericObject as IUnaryNumericMatcherData).dataType === 'DATETIME') {
54
54
  value = zeroSinceSS(value);
55
- dataType = dataTypes.DATETIME;
55
+ dataType = matcherDataTypes.DATETIME;
56
56
  }
57
57
  } else if (type === matcherTypes.BETWEEN) {
58
58
  value = betweenObject as IBetweenMatcherData;
59
- dataType = dataTypes.NUMBER;
59
+ dataType = matcherDataTypes.NUMBER;
60
60
 
61
61
  if (value.dataType === 'DATETIME') {
62
62
  value.start = zeroSinceSS(value.start);
63
63
  value.end = zeroSinceSS(value.end);
64
- dataType = dataTypes.DATETIME;
64
+ dataType = matcherDataTypes.DATETIME;
65
65
  }
66
66
  } else if (
67
67
  type === matcherTypes.EQUAL_TO_SET ||
@@ -70,7 +70,7 @@ export default function matchersTransform(matchers: ISplitMatcher[]): IMatcherDt
70
70
  type === matcherTypes.PART_OF_SET
71
71
  ) {
72
72
  value = setTransform(whitelistObject as IWhitelistMatcherData);
73
- dataType = dataTypes.SET;
73
+ dataType = matcherDataTypes.SET;
74
74
  } else if (
75
75
  type === matcherTypes.STARTS_WITH ||
76
76
  type === matcherTypes.ENDS_WITH ||
@@ -79,9 +79,9 @@ export default function matchersTransform(matchers: ISplitMatcher[]): IMatcherDt
79
79
  value = setTransform(whitelistObject as IWhitelistMatcherData);
80
80
  } else if (type === matcherTypes.IN_SPLIT_TREATMENT) {
81
81
  value = dependencyObject;
82
- dataType = dataTypes.NOT_SPECIFIED;
82
+ dataType = matcherDataTypes.NOT_SPECIFIED;
83
83
  } else if (type === matcherTypes.EQUAL_TO_BOOLEAN) {
84
- dataType = dataTypes.BOOLEAN;
84
+ dataType = matcherDataTypes.BOOLEAN;
85
85
  value = booleanMatcherData;
86
86
  } else if (type === matcherTypes.MATCHES_STRING) {
87
87
  value = stringMatcherData;
@@ -3,7 +3,7 @@ import { IDependencyMatcherValue } from '../types';
3
3
  import { ILogger } from '../../logger/types';
4
4
  import { isObject, uniq, toString, toNumber } from '../../utils/lang';
5
5
  import { zeroSinceHH, zeroSinceSS } from '../convertions';
6
- import { matcherTypes, dataTypes } from '../matchers/matcherTypes';
6
+ import { matcherTypes, matcherDataTypes } from '../matchers/matcherTypes';
7
7
  import { ENGINE_SANITIZE } from '../../logger/constants';
8
8
 
9
9
  function sanitizeNumber(val: any): number | undefined {
@@ -74,20 +74,20 @@ export default function sanitize(log: ILogger, matcherTypeID: number, value: str
74
74
  let sanitizedValue: string | number | boolean | Array<string | number> | IDependencyMatcherValue | undefined;
75
75
 
76
76
  switch (dataType) {
77
- case dataTypes.NUMBER:
78
- case dataTypes.DATETIME:
77
+ case matcherDataTypes.NUMBER:
78
+ case matcherDataTypes.DATETIME:
79
79
  sanitizedValue = sanitizeNumber(value);
80
80
  break;
81
- case dataTypes.STRING:
81
+ case matcherDataTypes.STRING:
82
82
  sanitizedValue = sanitizeString(value);
83
83
  break;
84
- case dataTypes.SET:
84
+ case matcherDataTypes.SET:
85
85
  sanitizedValue = sanitizeArray(value);
86
86
  break;
87
- case dataTypes.BOOLEAN:
87
+ case matcherDataTypes.BOOLEAN:
88
88
  sanitizedValue = sanitizeBoolean(value);
89
89
  break;
90
- case dataTypes.NOT_SPECIFIED:
90
+ case matcherDataTypes.NOT_SPECIFIED:
91
91
  sanitizedValue = value;
92
92
  break;
93
93
  default:
@@ -39,7 +39,6 @@ export default class BrowserSignalListener implements ISignalListener {
39
39
  * We add a handler on unload events. The handler flushes remaining impressions and events to the backend.
40
40
  */
41
41
  start() {
42
- this.syncManager?.start();
43
42
  if (typeof window !== 'undefined' && window.addEventListener) {
44
43
  this.settings.log.debug(CLEANUP_REGISTERING, [EVENT_NAME]);
45
44
  window.addEventListener(UNLOAD_DOM_EVENT, this.flushData);
@@ -49,6 +48,7 @@ export default class BrowserSignalListener implements ISignalListener {
49
48
  /**
50
49
  * stop method.
51
50
  * Called when client is destroyed.
51
+ * We need to remove the handler for unload events, since it can break if called when Split context was destroyed.
52
52
  */
53
53
  stop() {
54
54
  if (typeof window !== 'undefined' && window.removeEventListener) {
@@ -22,7 +22,7 @@ export default class NodeSignalListener implements ISignalListener {
22
22
  private settings: ISettings;
23
23
 
24
24
  constructor(
25
- private syncManager: ISyncManager | undefined, // private handler: () => MaybeThenable<void>,
25
+ syncManager: ISyncManager | undefined, // private handler: () => MaybeThenable<void>,
26
26
  settings: ISettings
27
27
  ) {
28
28
  // @TODO review handler logic when implementing Node SDK
@@ -37,7 +37,6 @@ export default class NodeSignalListener implements ISignalListener {
37
37
  }
38
38
 
39
39
  start() {
40
- this.syncManager?.start();
41
40
  this.settings.log.debug(CLEANUP_REGISTERING, [EVENT_NAME]);
42
41
  // eslint-disable-next-line no-undef
43
42
  process.on(SIGTERM, this._sigtermHandler);
@@ -93,6 +93,7 @@ export const WARN_SPLITS_FILTER_INVALID = 220;
93
93
  export const WARN_SPLITS_FILTER_EMPTY = 221;
94
94
  export const WARN_STORAGE_INVALID = 222;
95
95
  export const WARN_API_KEY = 223;
96
+ export const STREAMING_PARSING_MY_SEGMENTS_UPDATE_V2 = 224;
96
97
 
97
98
  export const ERROR_ENGINE_COMBINER_IFELSEIF = 300;
98
99
  export const ERROR_LOGLEVEL_INVALID = 301;
@@ -117,6 +118,7 @@ export const ERROR_EMPTY = 319;
117
118
  export const ERROR_EMPTY_ARRAY = 320;
118
119
  export const ERROR_INVALID_IMPRESSIONS_MODE = 321;
119
120
  export const ERROR_HTTP = 322;
121
+ export const ERROR_LOCALHOST_MODULE_REQUIRED = 323;
120
122
 
121
123
  // Log prefixes (a.k.a. tags or categories)
122
124
  export const LOG_PREFIX_SETTINGS = 'settings';
@@ -11,8 +11,8 @@ export const codesError: [number, string][] = [
11
11
  [c.ERROR_EVENTS_TRACKER, c.LOG_PREFIX_EVENTS_TRACKER + 'Failed to queue %s'],
12
12
  // synchronizer
13
13
  [c.ERROR_SYNC_OFFLINE_LOADING, c.LOG_PREFIX_SYNC_OFFLINE + 'There was an issue loading the mock Splits data, no changes will be applied to the current cache. %s'],
14
- [c.ERROR_STREAMING_SSE, c.LOG_PREFIX_SYNC_STREAMING + 'Fail to connect to streaming, with error message: %s'],
15
- [c.ERROR_STREAMING_AUTH, c.LOG_PREFIX_SYNC_STREAMING + 'Failed to authenticate for streaming. Error: "%s".'],
14
+ [c.ERROR_STREAMING_SSE, c.LOG_PREFIX_SYNC_STREAMING + 'Failed to connect or error on streaming connection, with error message: %s'],
15
+ [c.ERROR_STREAMING_AUTH, c.LOG_PREFIX_SYNC_STREAMING + 'Failed to authenticate for streaming. Error: %s.'],
16
16
  [c.ERROR_HTTP, ' Response status is not OK. Status: %s. URL: %s. Message: %s'],
17
17
  // client status
18
18
  [c.ERROR_CLIENT_LISTENER, 'A listener was added for %s on the SDK, which has already fired and won\'t be emitted again. The callback won\'t be executed.'],
@@ -30,4 +30,5 @@ export const codesError: [number, string][] = [
30
30
  [c.ERROR_EMPTY_ARRAY, '%s: %s must be a non-empty array.'],
31
31
  // initialization / settings validation
32
32
  [c.ERROR_INVALID_IMPRESSIONS_MODE, c.LOG_PREFIX_SETTINGS + ': you passed an invalid "impressionsMode". It should be one of the following values: %s. Defaulting to "%s" mode.'],
33
+ [c.ERROR_LOCALHOST_MODULE_REQUIRED, c.LOG_PREFIX_SETTINGS + ': you didn\'t pass a valid "sync.localhostMode". It should be defined for using the SDK in localhost mode']
33
34
  ];
@@ -22,9 +22,9 @@ export const codesInfo: [number, string][] = codesWarn.concat([
22
22
  [c.SYNC_SPLITS_FETCH_RETRY, c.LOG_PREFIX_SYNC_SPLITS + 'Retrying download of splits #%s. Reason: %s'],
23
23
  [c.SUBMITTERS_PUSH_FULL_EVENTS_QUEUE, c.LOG_PREFIX_SYNC_SUBMITTERS + 'Flushing full events queue and reseting timer.'],
24
24
  [c.SUBMITTERS_PUSH, c.LOG_PREFIX_SYNC_SUBMITTERS + 'Pushing %s %s.'],
25
- [c.STREAMING_REFRESH_TOKEN, c.LOG_PREFIX_SYNC_STREAMING + 'Refreshing streaming token in %s seconds.'],
25
+ [c.STREAMING_REFRESH_TOKEN, c.LOG_PREFIX_SYNC_STREAMING + 'Refreshing streaming token in %s seconds, and connecting streaming in %s seconds.'],
26
26
  [c.STREAMING_RECONNECT, c.LOG_PREFIX_SYNC_STREAMING + 'Attempting to reconnect in %s seconds.'],
27
- [c.STREAMING_CONNECTING, c.LOG_PREFIX_SYNC_STREAMING + 'Connecting to streaming.'],
27
+ [c.STREAMING_CONNECTING, c.LOG_PREFIX_SYNC_STREAMING + '%sConnecting to streaming.'],
28
28
  [c.STREAMING_DISABLED, c.LOG_PREFIX_SYNC_STREAMING + 'Streaming is disabled for given Api key. Switching to polling mode.'],
29
29
  [c.STREAMING_DISCONNECTING, c.LOG_PREFIX_SYNC_STREAMING + 'Disconnecting from streaming.'],
30
30
  [c.SYNC_START_POLLING, c.LOG_PREFIX_SYNC_MANAGER + 'Streaming not available. Starting polling.'],
@@ -30,5 +30,7 @@ export const codesWarn: [number, string][] = codesError.concat([
30
30
  [c.WARN_SPLITS_FILTER_INVALID, c.LOG_PREFIX_SETTINGS+': split filter at position %s is invalid. It must be an object with a valid filter type ("byName" or "byPrefix") and a list of "values".'],
31
31
  [c.WARN_SPLITS_FILTER_EMPTY, c.LOG_PREFIX_SETTINGS+': splitFilters configuration must be a non-empty array of filter objects.'],
32
32
  [c.WARN_STORAGE_INVALID, c.LOG_PREFIX_SETTINGS+': The provided storage is invalid. Fallbacking into default MEMORY storage'],
33
- [c.WARN_API_KEY, c.LOG_PREFIX_SETTINGS+': You already have %s. We recommend keeping only one instance of the factory at all times (Singleton pattern) and reusing it throughout your application']
33
+ [c.WARN_API_KEY, c.LOG_PREFIX_SETTINGS+': You already have %s. We recommend keeping only one instance of the factory at all times (Singleton pattern) and reusing it throughout your application'],
34
+
35
+ [c.STREAMING_PARSING_MY_SEGMENTS_UPDATE_V2, c.LOG_PREFIX_SYNC_STREAMING + 'Fetching MySegments due to an error processing %s notification: %s'],
34
36
  ]);
@@ -41,7 +41,7 @@ export function readinessManagerFactory(
41
41
 
42
42
  // emit SDK_READY_FROM_CACHE
43
43
  let isReadyFromCache = false;
44
- if (splits.splitsCacheLoaded) setTimeout(checkIsReadyFromCache, 0); // don't check status inmediately, to allow attach listeners
44
+ if (splits.splitsCacheLoaded) isReadyFromCache = true; // ready from cache, but doesn't emit SDK_READY_FROM_CACHE
45
45
  else splits.once(SDK_SPLITS_CACHE_LOADED, checkIsReadyFromCache);
46
46
 
47
47
  // emit SDK_READY_TIMED_OUT
@@ -62,13 +62,15 @@ export function readinessManagerFactory(
62
62
  let isDestroyed = false;
63
63
 
64
64
  function checkIsReadyFromCache() {
65
- // @TODO add condition to emit SDK_READY_FROM_CACHE only if SDK_READY has not been emitted
66
- if (!isReadyFromCache && splits.splitsCacheLoaded) {
67
- // Make it async, in case user callbacks throw an exception
68
- setTimeout(() => {
69
- isReadyFromCache = true;
65
+ isReadyFromCache = true;
66
+ // Don't emit SDK_READY_FROM_CACHE if SDK_READY has been emitted
67
+ if (!isReady) {
68
+ try {
70
69
  gate.emit(SDK_READY_FROM_CACHE);
71
- }, 0);
70
+ } catch (e) {
71
+ // throws user callback exceptions in next tick
72
+ setTimeout(() => { throw e; }, 0);
73
+ }
72
74
  }
73
75
  }
74
76
 
@@ -78,9 +78,7 @@ export function sdkFactory(params: ISdkFactoryParams): SplitIO.ICsSDK | SplitIO.
78
78
  const clientMethod = sdkClientMethodFactory({ eventTracker, impressionsTracker, sdkReadinessManager, settings, storage, syncManager, signalListener });
79
79
  const managerInstance = sdkManagerFactory(log, storage.splits, sdkReadinessManager);
80
80
 
81
- // If there is a signalListener, it is in charge of starting the syncManager.
82
- // It is required for RN to consider the app state when the SDK is instantiated (foreground/background).
83
- if (syncManager && !signalListener) syncManager.start();
81
+ syncManager && syncManager.start();
84
82
  signalListener && signalListener.start();
85
83
 
86
84
  log.info(NEW_FACTORY);
@@ -8,10 +8,10 @@ import { IStorageAsync, IStorageSync, ISplitsCacheSync, ISplitsCacheAsync, IStor
8
8
  import { ISyncManager, ISyncManagerFactoryParams } from '../sync/types';
9
9
  import { IImpressionObserver } from '../trackers/impressionObserver/types';
10
10
  import { SplitIO, ISettings, IEventEmitter } from '../types';
11
- import { ISettingsInternal } from '../utils/settingsValidation/types';
12
11
 
13
12
  /**
14
- * Environment related dependencies
13
+ * Environment related dependencies.
14
+ * These getters are called a fixed number of times per factory instantiation.
15
15
  */
16
16
  export interface IPlatform {
17
17
  getOptions?: () => object
@@ -26,7 +26,7 @@ export interface IPlatform {
26
26
  export interface ISdkFactoryParams {
27
27
 
28
28
  // The settings must be already validated
29
- settings: ISettingsInternal,
29
+ settings: ISettings,
30
30
 
31
31
  // Platform dependencies
32
32
  platform: IPlatform,
@@ -2,7 +2,6 @@ import { IPlatform } from '../sdkFactory/types';
2
2
  import { ISettings } from '../types';
3
3
  import { splitHttpClientFactory } from './splitHttpClient';
4
4
  import { ISplitApi } from './types';
5
- import { ISettingsInternal } from '../utils/settingsValidation/types';
6
5
  import objectAssign from 'object-assign';
7
6
 
8
7
  const noCacheHeaderOptions = { headers: { 'Cache-Control': 'no-cache' } };
@@ -20,7 +19,7 @@ function userKeyToQueryParam(userKey: string) {
20
19
  export function splitApiFactory(settings: ISettings, platform: Pick<IPlatform, 'getFetch' | 'getOptions'>): ISplitApi {
21
20
 
22
21
  const urls = settings.urls;
23
- const filterQueryString = (settings as ISettingsInternal).sync.__splitFiltersValidation && (settings as ISettingsInternal).sync.__splitFiltersValidation.queryString;
22
+ const filterQueryString = settings.sync.__splitFiltersValidation && settings.sync.__splitFiltersValidation.queryString;
24
23
  const SplitSDKImpressionsMode = settings.sync.impressionsMode;
25
24
  const splitHttpClient = splitHttpClientFactory(settings, platform.getFetch, platform.getOptions);
26
25
 
@@ -36,7 +35,7 @@ export function splitApiFactory(settings: ISettings, platform: Pick<IPlatform, '
36
35
  },
37
36
 
38
37
  fetchAuth(userMatchingKeys?: string[]) {
39
- let url = `${urls.auth}/auth`;
38
+ let url = `${urls.auth}/v2/auth`;
40
39
  if (userMatchingKeys) { // accounting the possibility that `userMatchingKeys` is undefined (server-side API)
41
40
  const queryParams = userMatchingKeys.map(userKeyToQueryParam).join('&');
42
41
  if (queryParams) // accounting the possibility that `userKeys` and thus `queryParams` are empty
@@ -43,8 +43,8 @@ export function splitHttpClientFactory(settings: Pick<ISettings, 'log' | 'versio
43
43
  return fetch ? fetch(url, request)
44
44
  // https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch#Checking_that_the_fetch_was_successful
45
45
  .then(response => {
46
- if (!response.ok) { // eslint-disable-next-line no-throw-literal
47
- throw { response };
46
+ if (!response.ok) {
47
+ return response.text().then(message => Promise.reject({ response, message }));
48
48
  }
49
49
  return response;
50
50
  })
@@ -56,18 +56,19 @@ export function splitHttpClientFactory(settings: Pick<ISettings, 'log' | 'versio
56
56
  switch (resp.status) {
57
57
  case 404: msg = 'Invalid API key or resource not found.';
58
58
  break;
59
- default: msg = resp.statusText;
59
+ // Don't use resp.statusText since reason phrase is removed in HTTP/2
60
+ default: msg = error.message;
60
61
  break;
61
62
  }
62
63
  } else { // Something else, either an error making the request or a Network error.
63
- msg = error.message;
64
+ msg = error.message || 'Network Error';
64
65
  }
65
66
 
66
67
  if (!resp || resp.status !== 403) { // 403's log we'll be handled somewhere else.
67
68
  log[logErrorsAsInfo ? 'info' : 'error'](ERROR_HTTP, [resp ? resp.status : 'NO_STATUS', url, msg]);
68
69
  }
69
70
 
70
- const networkError: Error & {statusCode?: number} = new Error(msg);
71
+ const networkError: Error & { statusCode?: number } = new Error(msg);
71
72
  // passes `undefined` as statusCode if not an HTTP error (resp === undefined)
72
73
  networkError.statusCode = resp && resp.status;
73
74
  throw networkError;
@@ -7,12 +7,12 @@ export type IRequestOptions = {
7
7
  export type IResponse = {
8
8
  ok: boolean,
9
9
  status: number,
10
- json: () => Promise<any>,
10
+ json: () => Promise<any>, // Used to parse OK response body. Promise rejects if body cannot be parsed
11
+ text: () => Promise<string>, // Used to read Not OK response body. Promise never rejects
11
12
 
12
13
  /** Other available properties when using Unfetch */
13
- // statusText: string,
14
+ // statusText: string, // `undefined` in Web fetch since HTTP/2 doesn't have reason phrases anymore. `node-fetch` overwrites it depending on the status code
14
15
  // url: string,
15
- // text: () => Promise<string>,
16
16
  // blob: () => Promise<Blob>,
17
17
  // clone: () => IResponse,
18
18
  // headers: {
@@ -50,8 +50,8 @@ export type IPostMetricsCounters = (body: string) => Promise<IResponse>
50
50
  export type IPostMetricsTimes = (body: string) => Promise<IResponse>
51
51
 
52
52
  export interface ISplitApi {
53
- getSdkAPIHealthCheck: IHealthCheckAPI;
54
- getEventsAPIHealthCheck: IHealthCheckAPI;
53
+ getSdkAPIHealthCheck: IHealthCheckAPI
54
+ getEventsAPIHealthCheck: IHealthCheckAPI
55
55
  fetchAuth: IFetchAuth
56
56
  fetchSplitChanges: IFetchSplitChanges
57
57
  fetchSegmentChanges: IFetchSegmentChanges
@@ -50,7 +50,7 @@ export default abstract class AbstractSplitsCacheSync implements ISplitsCacheSyn
50
50
  * It is used as condition to emit SDK_SPLITS_CACHE_LOADED, and then SDK_READY_FROM_CACHE.
51
51
  */
52
52
  checkCache(): boolean {
53
- return this.getChangeNumber() > -1;
53
+ return false;
54
54
  }
55
55
 
56
56
  /**
@@ -1,7 +1,7 @@
1
1
  import ImpressionsCacheInMemory from '../inMemory/ImpressionsCacheInMemory';
2
2
  import ImpressionCountsCacheInMemory from '../inMemory/ImpressionCountsCacheInMemory';
3
3
  import EventsCacheInMemory from '../inMemory/EventsCacheInMemory';
4
- import { IStorageFactoryParams, IStorageSyncCS } from '../types';
4
+ import { IStorageFactoryParams, IStorageSyncCS, IStorageSyncFactory } from '../types';
5
5
  import { validatePrefix } from '../KeyBuilder';
6
6
  import KeyBuilderCS from '../KeyBuilderCS';
7
7
  import { isLocalStorageAvailable } from '../../utils/env/isLocalStorageAvailable';
@@ -12,6 +12,7 @@ import SplitsCacheInMemory from '../inMemory/SplitsCacheInMemory';
12
12
  import { DEFAULT_CACHE_EXPIRATION_IN_MILLIS } from '../../utils/constants/browser';
13
13
  import { InMemoryStorageCSFactory } from '../inMemory/InMemoryStorageCS';
14
14
  import { LOG_PREFIX } from './constants';
15
+ import { STORAGE_LOCALSTORAGE } from '../../utils/constants';
15
16
 
16
17
  export interface InLocalStorageOptions {
17
18
  prefix?: string
@@ -20,11 +21,11 @@ export interface InLocalStorageOptions {
20
21
  /**
21
22
  * InLocal storage factory for standalone client-side SplitFactory
22
23
  */
23
- export function InLocalStorage(options: InLocalStorageOptions = {}) {
24
+ export function InLocalStorage(options: InLocalStorageOptions = {}): IStorageSyncFactory {
24
25
 
25
26
  const prefix = validatePrefix(options.prefix);
26
27
 
27
- return function InLocalStorageCSFactory(params: IStorageFactoryParams): IStorageSyncCS {
28
+ function InLocalStorageCSFactory(params: IStorageFactoryParams): IStorageSyncCS {
28
29
 
29
30
  // Fallback to InMemoryStorage if LocalStorage API is not available
30
31
  if (!isLocalStorageAvailable()) {
@@ -69,5 +70,8 @@ export function InLocalStorage(options: InLocalStorageOptions = {}) {
69
70
  };
70
71
  },
71
72
  };
72
- };
73
+ }
74
+
75
+ InLocalStorageCSFactory.type = STORAGE_LOCALSTORAGE;
76
+ return InLocalStorageCSFactory;
73
77
  }
@@ -4,6 +4,7 @@ import ImpressionsCacheInMemory from './ImpressionsCacheInMemory';
4
4
  import EventsCacheInMemory from './EventsCacheInMemory';
5
5
  import { IStorageFactoryParams, IStorageSync } from '../types';
6
6
  import ImpressionCountsCacheInMemory from './ImpressionCountsCacheInMemory';
7
+ import { STORAGE_MEMORY } from '../../utils/constants';
7
8
 
8
9
  /**
9
10
  * InMemory storage factory for standalone server-side SplitFactory
@@ -32,3 +33,5 @@ export function InMemoryStorageFactory(params: IStorageFactoryParams): IStorageS
32
33
  }
33
34
  };
34
35
  }
36
+
37
+ InMemoryStorageFactory.type = STORAGE_MEMORY;
@@ -4,6 +4,7 @@ import ImpressionsCacheInMemory from './ImpressionsCacheInMemory';
4
4
  import EventsCacheInMemory from './EventsCacheInMemory';
5
5
  import { IStorageSyncCS, IStorageFactoryParams } from '../types';
6
6
  import ImpressionCountsCacheInMemory from './ImpressionCountsCacheInMemory';
7
+ import { STORAGE_MEMORY } from '../../utils/constants';
7
8
 
8
9
  /**
9
10
  * InMemory storage factory for standalone client-side SplitFactory
@@ -46,3 +47,5 @@ export function InMemoryStorageCSFactory(params: IStorageFactoryParams): IStorag
46
47
  },
47
48
  };
48
49
  }
50
+
51
+ InMemoryStorageCSFactory.type = STORAGE_MEMORY;
@@ -47,7 +47,9 @@ export default class SplitsCacheInRedis extends AbstractSplitsCacheAsync {
47
47
  private _decrementCounts(split: ISplit) {
48
48
  if (split.trafficTypeName) {
49
49
  const ttKey = this.keys.buildTrafficTypeKey(split.trafficTypeName);
50
- return this.redis.decr(ttKey);
50
+ return this.redis.decr(ttKey).then(count => {
51
+ if (count === 0) return this.redis.del(ttKey);
52
+ });
51
53
  }
52
54
  }
53
55
 
@@ -1,5 +1,5 @@
1
1
  import RedisAdapter from './RedisAdapter';
2
- import { IStorageAsync, IStorageFactoryParams } from '../types';
2
+ import { IStorageAsync, IStorageAsyncFactory, IStorageFactoryParams } from '../types';
3
3
  import { validatePrefix } from '../KeyBuilder';
4
4
  import KeyBuilderSS from '../KeyBuilderSS';
5
5
  import SplitsCacheInRedis from './SplitsCacheInRedis';
@@ -8,6 +8,7 @@ import ImpressionsCacheInRedis from './ImpressionsCacheInRedis';
8
8
  import EventsCacheInRedis from './EventsCacheInRedis';
9
9
  import LatenciesCacheInRedis from './LatenciesCacheInRedis';
10
10
  import CountsCacheInRedis from './CountsCacheInRedis';
11
+ import { STORAGE_REDIS } from '../../utils/constants';
11
12
 
12
13
  export interface InRedisStorageOptions {
13
14
  prefix?: string
@@ -18,11 +19,11 @@ export interface InRedisStorageOptions {
18
19
  * InRedis storage factory for consumer server-side SplitFactory, that uses `Ioredis` Redis client for Node.
19
20
  * @see {@link https://www.npmjs.com/package/ioredis}
20
21
  */
21
- export function InRedisStorage(options: InRedisStorageOptions = {}) {
22
+ export function InRedisStorage(options: InRedisStorageOptions = {}): IStorageAsyncFactory {
22
23
 
23
24
  const prefix = validatePrefix(options.prefix);
24
25
 
25
- return function InRedisStorageFactory({ log, metadata, onReadyCb }: IStorageFactoryParams): IStorageAsync {
26
+ function InRedisStorageFactory({ log, metadata, onReadyCb }: IStorageFactoryParams): IStorageAsync {
26
27
 
27
28
  const keys = new KeyBuilderSS(prefix, metadata);
28
29
  const redisClient = new RedisAdapter(log, options.options || {});
@@ -47,5 +48,8 @@ export function InRedisStorage(options: InRedisStorageOptions = {}) {
47
48
  // @TODO check that caches works as expected when redisClient is disconnected
48
49
  }
49
50
  };
50
- };
51
+ }
52
+
53
+ InRedisStorageFactory.type = STORAGE_REDIS;
54
+ return InRedisStorageFactory;
51
55
  }
@@ -31,7 +31,9 @@ export class SplitsCachePluggable extends AbstractSplitsCacheAsync {
31
31
  private _decrementCounts(split: ISplit) {
32
32
  if (split.trafficTypeName) {
33
33
  const ttKey = this.keys.buildTrafficTypeKey(split.trafficTypeName);
34
- return this.wrapper.decr(ttKey);
34
+ return this.wrapper.decr(ttKey).then(count => {
35
+ if (count === 0) return this.wrapper.del(ttKey);
36
+ });
35
37
  }
36
38
  }
37
39
 
@@ -36,28 +36,27 @@ export function inMemoryWrapperFactory(): ICustomStorageWrapper & { _cache: Reco
36
36
  getKeysByPrefix(prefix: string) {
37
37
  return Promise.resolve(Object.keys(_cache).filter(key => startsWith(key, prefix)));
38
38
  },
39
- getByPrefix(prefix: string) {
40
- return Promise.resolve(Object.keys(_cache).filter(key => startsWith(key, prefix)).map(key => _cache[key] as string));
41
- },
42
39
  incr(key: string) {
43
40
  if (key in _cache) {
44
41
  const count = toNumber(_cache[key]) + 1;
45
- if (isNaN(count)) return Promise.resolve(false);
42
+ if (isNaN(count)) return Promise.reject('Given key is not a number');
46
43
  _cache[key] = count + '';
44
+ return Promise.resolve(count);
47
45
  } else {
48
46
  _cache[key] = '1';
47
+ return Promise.resolve(1);
49
48
  }
50
- return Promise.resolve(true);
51
49
  },
52
50
  decr(key: string) {
53
51
  if (key in _cache) {
54
52
  const count = toNumber(_cache[key]) - 1;
55
- if (isNaN(count)) return Promise.resolve(false);
53
+ if (isNaN(count)) return Promise.reject('Given key is not a number');
56
54
  _cache[key] = count + '';
55
+ return Promise.resolve(count);
57
56
  } else {
58
57
  _cache[key] = '-1';
58
+ return Promise.resolve(-1);
59
59
  }
60
- return Promise.resolve(true);
61
60
  },
62
61
  getMany(keys: string[]) {
63
62
  return Promise.resolve(keys.map(key => _cache[key] ? _cache[key] as string : null));
@@ -1,4 +1,4 @@
1
- import { ICustomStorageWrapper, IStorageAsync, IStorageFactoryParams } from '../types';
1
+ import { ICustomStorageWrapper, IStorageAsync, IStorageAsyncFactory, IStorageFactoryParams } from '../types';
2
2
 
3
3
  import KeyBuilderSS from '../KeyBuilderSS';
4
4
  import { SplitsCachePluggable } from './SplitsCachePluggable';
@@ -8,6 +8,7 @@ import { EventsCachePluggable } from './EventsCachePluggable';
8
8
  import { wrapperAdapter, METHODS_TO_PROMISE_WRAP } from './wrapperAdapter';
9
9
  import { isObject } from '../../utils/lang';
10
10
  import { validatePrefix } from '../KeyBuilder';
11
+ import { STORAGE_CUSTOM } from '../../utils/constants';
11
12
 
12
13
  const NO_VALID_WRAPPER = 'Expecting custom storage `wrapper` in options, but no valid wrapper instance was provided.';
13
14
  const NO_VALID_WRAPPER_INTERFACE = 'The provided wrapper instance doesn’t follow the expected interface. Check our docs.';
@@ -34,13 +35,13 @@ function validatePluggableStorageOptions(options: any) {
34
35
  /**
35
36
  * Pluggable storage factory for consumer server-side & client-side SplitFactory.
36
37
  */
37
- export function PluggableStorage(options: PluggableStorageOptions) {
38
+ export function PluggableStorage(options: PluggableStorageOptions): IStorageAsyncFactory {
38
39
 
39
40
  validatePluggableStorageOptions(options);
40
41
 
41
42
  const prefix = validatePrefix(options.prefix);
42
43
 
43
- return function PluggableStorageFactory({ log, metadata, onReadyCb }: IStorageFactoryParams): IStorageAsync {
44
+ function PluggableStorageFactory({ log, metadata, onReadyCb }: IStorageFactoryParams): IStorageAsync {
44
45
  const keys = new KeyBuilderSS(prefix, metadata);
45
46
  const wrapper = wrapperAdapter(log, options.wrapper);
46
47
 
@@ -63,5 +64,8 @@ export function PluggableStorage(options: PluggableStorageOptions) {
63
64
  return wrapper.close();
64
65
  }
65
66
  };
66
- };
67
+ }
68
+
69
+ PluggableStorageFactory.type = STORAGE_CUSTOM;
70
+ return PluggableStorageFactory;
67
71
  }
@@ -8,7 +8,6 @@ export const METHODS_TO_PROMISE_WRAP: string[] = [
8
8
  'getAndSet',
9
9
  'del',
10
10
  'getKeysByPrefix',
11
- 'getByPrefix',
12
11
  'incr',
13
12
  'decr',
14
13
  'getMany',