@splitsoftware/splitio-commons 0.1.1-canary.6 → 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 (269) 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 +5 -2
  5. package/cjs/listeners/node.js +9 -2
  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 -1
  12. package/cjs/services/splitApi.js +9 -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/fetchers/segmentChangesFetcher.js +0 -8
  28. package/cjs/sync/polling/updaters/mySegmentsUpdater.js +30 -10
  29. package/cjs/sync/polling/updaters/segmentChangesUpdater.js +2 -4
  30. package/cjs/sync/streaming/SSEClient/index.js +38 -20
  31. package/cjs/sync/streaming/SSEHandler/NotificationKeeper.js +7 -0
  32. package/cjs/sync/streaming/SSEHandler/NotificationParser.js +4 -1
  33. package/cjs/sync/streaming/SSEHandler/index.js +8 -9
  34. package/cjs/sync/streaming/SSEHandler/types.js +14 -0
  35. package/cjs/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.js +5 -5
  36. package/cjs/sync/streaming/UpdateWorkers/SegmentsUpdateWorker.js +2 -1
  37. package/cjs/sync/streaming/UpdateWorkers/SplitsUpdateWorker.js +5 -3
  38. package/cjs/sync/streaming/constants.js +3 -1
  39. package/cjs/sync/streaming/mySegmentsV2utils.js +75 -0
  40. package/cjs/sync/streaming/pushManager.js +148 -40
  41. package/cjs/sync/submitters/metricsSyncTask.js +1 -1
  42. package/cjs/sync/submitters/submitterSyncTask.js +2 -2
  43. package/cjs/sync/syncManagerFromFile.js +15 -0
  44. package/cjs/sync/syncManagerFromObject.js +14 -0
  45. package/cjs/sync/syncManagerOffline.js +3 -3
  46. package/cjs/sync/syncManagerOnline.js +18 -5
  47. package/cjs/sync/syncTask.js +1 -1
  48. package/cjs/trackers/impressionObserver/ImpressionObserver.js +0 -2
  49. package/cjs/trackers/impressionObserver/buildKey.js +3 -9
  50. package/cjs/trackers/impressionObserver/impressionObserverCS.js +2 -2
  51. package/cjs/trackers/impressionObserver/impressionObserverSS.js +3 -3
  52. package/cjs/utils/constants/index.js +4 -1
  53. package/cjs/utils/decompress/index.js +427 -0
  54. package/cjs/utils/murmur3/{commons.js → common.js} +2 -6
  55. package/cjs/utils/murmur3/murmur3.js +11 -12
  56. package/cjs/utils/murmur3/murmur3_128.js +7 -142
  57. package/cjs/utils/murmur3/murmur3_128_x86.js +154 -0
  58. package/cjs/utils/murmur3/murmur3_64.js +36 -0
  59. package/cjs/utils/murmur3/utfx.js +100 -106
  60. package/cjs/utils/promise/wrapper.js +14 -11
  61. package/cjs/utils/settingsValidation/index.js +5 -2
  62. package/cjs/utils/settingsValidation/localhost/index.js +20 -0
  63. package/cjs/utils/settingsValidation/splitFilters.js +0 -1
  64. package/cjs/utils/settingsValidation/storage/storageCS.js +18 -8
  65. package/cjs/utils/settingsValidation/url.js +1 -1
  66. package/esm/evaluator/matchers/matcherTypes.js +2 -2
  67. package/esm/evaluator/matchersTransform/index.js +12 -12
  68. package/esm/evaluator/value/sanitize.js +7 -7
  69. package/esm/listeners/browser.js +5 -2
  70. package/esm/listeners/node.js +9 -2
  71. package/esm/logger/constants.js +2 -0
  72. package/esm/logger/messages/error.js +3 -2
  73. package/esm/logger/messages/info.js +2 -2
  74. package/esm/logger/messages/warn.js +2 -1
  75. package/esm/readiness/readinessManager.js +10 -7
  76. package/esm/sdkFactory/index.js +1 -1
  77. package/esm/services/splitApi.js +9 -1
  78. package/esm/services/splitHttpClient.js +5 -4
  79. package/esm/storages/AbstractSplitsCacheSync.js +1 -1
  80. package/esm/storages/inLocalStorage/index.js +5 -2
  81. package/esm/storages/inMemory/InMemoryStorage.js +2 -0
  82. package/esm/storages/inMemory/InMemoryStorageCS.js +2 -0
  83. package/esm/storages/inRedis/SplitsCacheInRedis.js +6 -2
  84. package/esm/storages/inRedis/index.js +5 -2
  85. package/esm/storages/pluggable/SplitsCachePluggable.js +6 -2
  86. package/esm/storages/pluggable/inMemoryWrapper.js +6 -7
  87. package/esm/storages/pluggable/index.js +5 -2
  88. package/esm/storages/pluggable/wrapperAdapter.js +0 -1
  89. package/esm/sync/offline/splitsParser/splitsParserFromFile.js +90 -88
  90. package/esm/sync/offline/splitsParser/splitsParserFromSettings.js +43 -41
  91. package/esm/sync/offline/syncTasks/fromObjectSyncTask.js +15 -5
  92. package/esm/sync/polling/fetchers/segmentChangesFetcher.js +0 -8
  93. package/esm/sync/polling/updaters/mySegmentsUpdater.js +30 -10
  94. package/esm/sync/polling/updaters/segmentChangesUpdater.js +2 -4
  95. package/esm/sync/streaming/SSEClient/index.js +38 -20
  96. package/esm/sync/streaming/SSEHandler/NotificationKeeper.js +7 -0
  97. package/esm/sync/streaming/SSEHandler/NotificationParser.js +4 -1
  98. package/esm/sync/streaming/SSEHandler/index.js +9 -10
  99. package/esm/sync/streaming/SSEHandler/types.js +13 -1
  100. package/esm/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.js +5 -5
  101. package/esm/sync/streaming/UpdateWorkers/SegmentsUpdateWorker.js +2 -1
  102. package/esm/sync/streaming/UpdateWorkers/SplitsUpdateWorker.js +5 -3
  103. package/esm/sync/streaming/constants.js +2 -0
  104. package/esm/sync/streaming/mySegmentsV2utils.js +69 -0
  105. package/esm/sync/streaming/pushManager.js +150 -42
  106. package/esm/sync/submitters/metricsSyncTask.js +1 -1
  107. package/esm/sync/submitters/submitterSyncTask.js +2 -2
  108. package/esm/sync/syncManagerFromFile.js +11 -0
  109. package/esm/sync/syncManagerFromObject.js +10 -0
  110. package/esm/sync/syncManagerOffline.js +3 -3
  111. package/esm/sync/syncManagerOnline.js +18 -5
  112. package/esm/sync/syncTask.js +1 -1
  113. package/esm/trackers/impressionObserver/ImpressionObserver.js +0 -2
  114. package/esm/trackers/impressionObserver/buildKey.js +2 -9
  115. package/esm/trackers/impressionObserver/impressionObserverCS.js +2 -2
  116. package/esm/trackers/impressionObserver/impressionObserverSS.js +3 -3
  117. package/esm/utils/constants/index.js +3 -0
  118. package/esm/utils/decompress/index.js +424 -0
  119. package/esm/utils/murmur3/{commons.js → common.js} +1 -4
  120. package/esm/utils/murmur3/murmur3.js +1 -2
  121. package/esm/utils/murmur3/murmur3_128.js +7 -142
  122. package/esm/utils/murmur3/murmur3_128_x86.js +150 -0
  123. package/esm/utils/murmur3/murmur3_64.js +32 -0
  124. package/esm/utils/murmur3/utfx.js +96 -106
  125. package/esm/utils/promise/wrapper.js +14 -11
  126. package/esm/utils/settingsValidation/index.js +5 -2
  127. package/esm/utils/settingsValidation/localhost/index.js +16 -0
  128. package/esm/utils/settingsValidation/splitFilters.js +0 -1
  129. package/esm/utils/settingsValidation/storage/storageCS.js +16 -7
  130. package/esm/utils/settingsValidation/url.js +1 -1
  131. package/package.json +5 -5
  132. package/src/evaluator/matchers/matcherTypes.ts +2 -2
  133. package/src/evaluator/matchersTransform/index.ts +12 -12
  134. package/src/evaluator/value/sanitize.ts +7 -7
  135. package/src/listeners/browser.ts +5 -2
  136. package/src/listeners/node.ts +14 -2
  137. package/src/logger/constants.ts +2 -0
  138. package/src/logger/messages/error.ts +3 -2
  139. package/src/logger/messages/info.ts +2 -2
  140. package/src/logger/messages/warn.ts +3 -1
  141. package/src/readiness/readinessManager.ts +9 -7
  142. package/src/sdkFactory/index.ts +1 -1
  143. package/src/sdkFactory/types.ts +4 -5
  144. package/src/services/splitApi.ts +12 -3
  145. package/src/services/splitHttpClient.ts +6 -5
  146. package/src/services/types.ts +7 -3
  147. package/src/storages/AbstractSplitsCacheSync.ts +1 -1
  148. package/src/storages/inLocalStorage/index.ts +8 -4
  149. package/src/storages/inMemory/InMemoryStorage.ts +3 -0
  150. package/src/storages/inMemory/InMemoryStorageCS.ts +3 -0
  151. package/src/storages/inRedis/SplitsCacheInRedis.ts +3 -1
  152. package/src/storages/inRedis/index.ts +8 -4
  153. package/src/storages/pluggable/SegmentsCachePluggable.ts +1 -1
  154. package/src/storages/pluggable/SplitsCachePluggable.ts +3 -1
  155. package/src/storages/pluggable/inMemoryWrapper.ts +6 -7
  156. package/src/storages/pluggable/index.ts +8 -4
  157. package/src/storages/pluggable/wrapperAdapter.ts +0 -1
  158. package/src/storages/types.ts +18 -15
  159. package/src/sync/offline/splitsParser/splitsParserFromFile.ts +110 -105
  160. package/src/sync/offline/splitsParser/splitsParserFromSettings.ts +45 -41
  161. package/src/sync/offline/syncTasks/fromObjectSyncTask.ts +15 -5
  162. package/src/sync/polling/fetchers/segmentChangesFetcher.ts +0 -7
  163. package/src/sync/polling/types.ts +2 -1
  164. package/src/sync/polling/updaters/mySegmentsUpdater.ts +28 -10
  165. package/src/sync/polling/updaters/segmentChangesUpdater.ts +2 -3
  166. package/src/sync/streaming/AuthClient/types.ts +3 -0
  167. package/src/sync/streaming/SSEClient/index.ts +43 -23
  168. package/src/sync/streaming/SSEClient/types.ts +0 -1
  169. package/src/sync/streaming/SSEHandler/NotificationKeeper.ts +8 -0
  170. package/src/sync/streaming/SSEHandler/NotificationParser.ts +4 -2
  171. package/src/sync/streaming/SSEHandler/index.ts +11 -20
  172. package/src/sync/streaming/SSEHandler/types.ts +37 -3
  173. package/src/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.ts +7 -6
  174. package/src/sync/streaming/UpdateWorkers/SegmentsUpdateWorker.ts +2 -1
  175. package/src/sync/streaming/UpdateWorkers/SplitsUpdateWorker.ts +4 -3
  176. package/src/sync/streaming/UpdateWorkers/types.ts +1 -1
  177. package/src/sync/streaming/constants.ts +2 -0
  178. package/src/sync/streaming/mySegmentsV2utils.ts +77 -0
  179. package/src/sync/streaming/pushManager.ts +145 -42
  180. package/src/sync/streaming/types.ts +14 -22
  181. package/src/sync/submitters/metricsSyncTask.ts +1 -1
  182. package/src/sync/submitters/submitterSyncTask.ts +2 -1
  183. package/src/sync/syncManagerFromFile.ts +13 -0
  184. package/src/sync/syncManagerFromObject.ts +12 -0
  185. package/src/sync/syncManagerOffline.ts +3 -3
  186. package/src/sync/syncManagerOnline.ts +19 -5
  187. package/src/sync/syncTask.ts +1 -1
  188. package/src/sync/types.ts +3 -1
  189. package/src/trackers/impressionObserver/ImpressionObserver.ts +4 -6
  190. package/src/trackers/impressionObserver/buildKey.ts +2 -16
  191. package/src/trackers/impressionObserver/impressionObserverCS.ts +2 -2
  192. package/src/trackers/impressionObserver/impressionObserverSS.ts +3 -3
  193. package/src/types.ts +16 -2
  194. package/src/utils/constants/index.ts +6 -1
  195. package/src/utils/decompress/index.ts +429 -0
  196. package/src/utils/lang/index.ts +1 -1
  197. package/src/utils/murmur3/{commons.ts → common.ts} +1 -5
  198. package/src/utils/murmur3/murmur3.ts +5 -5
  199. package/src/utils/murmur3/murmur3_128.ts +7 -180
  200. package/src/utils/murmur3/murmur3_128_x86.ts +188 -0
  201. package/src/utils/murmur3/murmur3_64.ts +36 -0
  202. package/src/utils/murmur3/utfx.ts +92 -110
  203. package/src/utils/promise/wrapper.ts +12 -9
  204. package/src/utils/settingsValidation/index.ts +8 -4
  205. package/src/utils/settingsValidation/localhost/index.ts +19 -0
  206. package/src/utils/settingsValidation/splitFilters.ts +0 -1
  207. package/src/utils/settingsValidation/storage/storageCS.ts +21 -8
  208. package/src/utils/settingsValidation/types.ts +2 -11
  209. package/src/utils/settingsValidation/url.ts +1 -1
  210. package/types/evaluator/matchers/matcherTypes.d.ts +2 -2
  211. package/types/listeners/browser.d.ts +3 -3
  212. package/types/listeners/node.d.ts +3 -2
  213. package/types/logger/constants.d.ts +2 -0
  214. package/types/sdkFactory/types.d.ts +4 -5
  215. package/types/services/types.d.ts +4 -0
  216. package/types/storages/inLocalStorage/index.d.ts +2 -2
  217. package/types/storages/inMemory/InMemoryStorage.d.ts +3 -0
  218. package/types/storages/inMemory/InMemoryStorageCS.d.ts +3 -0
  219. package/types/storages/inRedis/index.d.ts +2 -2
  220. package/types/storages/pluggable/index.d.ts +2 -2
  221. package/types/storages/types.d.ts +15 -15
  222. package/types/sync/offline/splitsParser/splitsParserFromFile.d.ts +2 -7
  223. package/types/sync/offline/splitsParser/splitsParserFromSettings.d.ts +1 -5
  224. package/types/sync/polling/types.d.ts +2 -1
  225. package/types/sync/streaming/AuthClient/indexV1.d.ts +12 -0
  226. package/types/sync/streaming/AuthClient/indexV2.d.ts +8 -0
  227. package/types/sync/streaming/AuthClient/types.d.ts +2 -0
  228. package/types/sync/streaming/SSEClient/index.d.ts +9 -12
  229. package/types/sync/streaming/SSEClient/types.d.ts +0 -1
  230. package/types/sync/streaming/SSEHandler/NotificationParser.d.ts +3 -2
  231. package/types/sync/streaming/SSEHandler/types.d.ts +30 -2
  232. package/types/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.d.ts +4 -3
  233. package/types/sync/streaming/UpdateWorkers/SegmentsUpdateWorker.d.ts +2 -1
  234. package/types/sync/streaming/UpdateWorkers/SplitsUpdateWorker.d.ts +3 -2
  235. package/types/sync/streaming/UpdateWorkers/types.d.ts +1 -1
  236. package/types/sync/streaming/constants.d.ts +3 -1
  237. package/types/sync/streaming/mySegmentsV2utils.d.ts +27 -0
  238. package/types/sync/streaming/pushManagerNoUsers.d.ts +13 -0
  239. package/types/sync/streaming/types.d.ts +9 -5
  240. package/types/sync/submitters/submitterSyncTask.d.ts +1 -1
  241. package/types/sync/syncManagerFromFile.d.ts +2 -0
  242. package/types/sync/syncManagerFromObject.d.ts +2 -0
  243. package/types/sync/syncManagerOffline.d.ts +1 -1
  244. package/types/sync/syncTask.d.ts +1 -1
  245. package/types/sync/types.d.ts +2 -0
  246. package/types/trackers/impressionObserver/ImpressionObserver.d.ts +2 -2
  247. package/types/trackers/impressionObserver/buildKey.d.ts +1 -1
  248. package/types/trackers/impressionObserver/impressionObserverCS.d.ts +2 -2
  249. package/types/trackers/impressionObserver/impressionObserverSS.d.ts +2 -2
  250. package/types/types.d.ts +16 -2
  251. package/types/utils/constants/index.d.ts +5 -1
  252. package/types/utils/decompress/index.d.ts +16 -0
  253. package/types/utils/lang/index.d.ts +1 -1
  254. package/types/utils/murmur3/common.d.ts +12 -0
  255. package/types/utils/murmur3/murmur3.d.ts +2 -2
  256. package/types/utils/murmur3/murmur3_128.d.ts +5 -0
  257. package/types/utils/murmur3/murmur3_128_x86.d.ts +7 -0
  258. package/types/utils/murmur3/murmur3_64.d.ts +10 -0
  259. package/types/utils/murmur3/utfx.d.ts +24 -6
  260. package/types/utils/settingsValidation/index.d.ts +3 -2
  261. package/types/utils/settingsValidation/localhost/index.d.ts +9 -0
  262. package/types/utils/settingsValidation/storage/storageCS.d.ts +7 -1
  263. package/types/utils/settingsValidation/types.d.ts +2 -10
  264. package/cjs/sync/streaming/pushManagerCS.js +0 -178
  265. package/cjs/sync/streaming/pushManagerSS.js +0 -128
  266. package/esm/sync/streaming/pushManagerCS.js +0 -174
  267. package/esm/sync/streaming/pushManagerSS.js +0 -124
  268. package/src/sync/streaming/pushManagerCS.ts +0 -237
  269. package/src/sync/streaming/pushManagerSS.ts +0 -177
@@ -13,7 +13,7 @@ var MySegmentsUpdateWorker = /** @class */ (function () {
13
13
  this.mySegmentsSyncTask = mySegmentsSyncTask;
14
14
  this.maxChangeNumber = 0; // keeps the maximum changeNumber among queued events
15
15
  this.handleNewEvent = false;
16
- this.segmentList = undefined; // keeps the segmentList (if included in payload) from the queued event with maximum changeNumber
16
+ this.segmentsData = undefined; // keeps the segmentsData (if included in notification payload) from the queued event with maximum changeNumber
17
17
  this.currentChangeNumber = -1; // @TODO: remove once `/mySegments` endpoint provides the changeNumber
18
18
  this.put = this.put.bind(this);
19
19
  this.__handleMySegmentsUpdateCall = this.__handleMySegmentsUpdateCall.bind(this);
@@ -27,7 +27,7 @@ var MySegmentsUpdateWorker = /** @class */ (function () {
27
27
  this.handleNewEvent = false;
28
28
  var currentMaxChangeNumber_1 = this.maxChangeNumber;
29
29
  // fetch mySegments revalidating data if cached
30
- this.mySegmentsSyncTask.execute(this.segmentList, true).then(function (result) {
30
+ this.mySegmentsSyncTask.execute(this.segmentsData, true).then(function (result) {
31
31
  if (result !== false) // Unlike `Splits|SegmentsUpdateWorker`, we cannot use `mySegmentsCache.getChangeNumber` since `/mySegments` endpoint doesn't provide this value.
32
32
  _this.currentChangeNumber = Math.max(_this.currentChangeNumber, currentMaxChangeNumber_1); // use `currentMaxChangeNumber`, in case that `this.maxChangeNumber` was updated during fetch.
33
33
  if (_this.handleNewEvent) {
@@ -43,15 +43,15 @@ var MySegmentsUpdateWorker = /** @class */ (function () {
43
43
  * Invoked by NotificationProcessor on MY_SEGMENTS_UPDATE event
44
44
  *
45
45
  * @param {number} changeNumber change number of the MY_SEGMENTS_UPDATE notification
46
- * @param {string[] | undefined} segmentList might be undefined
46
+ * @param {SegmentsData | undefined} segmentsData might be undefined
47
47
  */
48
- MySegmentsUpdateWorker.prototype.put = function (changeNumber, segmentList) {
48
+ MySegmentsUpdateWorker.prototype.put = function (changeNumber, segmentsData) {
49
49
  if (changeNumber <= this.currentChangeNumber || changeNumber <= this.maxChangeNumber)
50
50
  return;
51
51
  this.maxChangeNumber = changeNumber;
52
52
  this.handleNewEvent = true;
53
53
  this.backoff.reset();
54
- this.segmentList = segmentList;
54
+ this.segmentsData = segmentsData;
55
55
  if (this.mySegmentsSyncTask.isExecuting())
56
56
  return;
57
57
  this.__handleMySegmentsUpdateCall();
@@ -57,7 +57,8 @@ var SegmentsUpdateWorker = /** @class */ (function () {
57
57
  * @param {number} changeNumber change number of the SEGMENT_UPDATE notification
58
58
  * @param {string} segmentName segment name of the SEGMENT_UPDATE notification
59
59
  */
60
- SegmentsUpdateWorker.prototype.put = function (changeNumber, segmentName) {
60
+ SegmentsUpdateWorker.prototype.put = function (_a) {
61
+ var changeNumber = _a.changeNumber, segmentName = _a.segmentName;
61
62
  var currentChangeNumber = this.segmentsCache.getChangeNumber(segmentName);
62
63
  if (changeNumber <= currentChangeNumber || changeNumber <= this.maxChangeNumbers[segmentName])
63
64
  return;
@@ -49,7 +49,8 @@ var SplitsUpdateWorker = /** @class */ (function () {
49
49
  *
50
50
  * @param {number} changeNumber change number of the SPLIT_UPDATE notification
51
51
  */
52
- SplitsUpdateWorker.prototype.put = function (changeNumber) {
52
+ SplitsUpdateWorker.prototype.put = function (_a) {
53
+ var changeNumber = _a.changeNumber;
53
54
  var currentChangeNumber = this.splitsCache.getChangeNumber();
54
55
  if (changeNumber <= currentChangeNumber || changeNumber <= this.maxChangeNumber)
55
56
  return;
@@ -67,14 +68,15 @@ var SplitsUpdateWorker = /** @class */ (function () {
67
68
  * @param {string} splitName name of split to kill
68
69
  * @param {string} defaultTreatment default treatment value
69
70
  */
70
- SplitsUpdateWorker.prototype.killSplit = function (changeNumber, splitName, defaultTreatment) {
71
+ SplitsUpdateWorker.prototype.killSplit = function (_a) {
72
+ var changeNumber = _a.changeNumber, splitName = _a.splitName, defaultTreatment = _a.defaultTreatment;
71
73
  // @TODO handle retry due to errors in storage, once we allow the definition of custom async storages
72
74
  if (this.splitsCache.killLocally(splitName, defaultTreatment, changeNumber)) {
73
75
  // trigger an SDK_UPDATE if Split was killed locally
74
76
  this.splitsEventEmitter.emit(constants_1.SDK_SPLITS_ARRIVED, true);
75
77
  }
76
78
  // queues the SplitChanges fetch (only if changeNumber is newer)
77
- this.put(changeNumber);
79
+ this.put({ changeNumber: changeNumber });
78
80
  };
79
81
  return SplitsUpdateWorker;
80
82
  }());
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ControlType = exports.OCCUPANCY = exports.CONTROL = exports.SPLIT_UPDATE = exports.SPLIT_KILL = exports.SEGMENT_UPDATE = exports.MY_SEGMENTS_UPDATE = exports.PUSH_SUBSYSTEM_DOWN = exports.PUSH_SUBSYSTEM_UP = exports.PUSH_RETRYABLE_ERROR = exports.PUSH_NONRETRYABLE_ERROR = exports.SECONDS_BEFORE_EXPIRATION = void 0;
3
+ exports.ControlType = exports.OCCUPANCY = exports.CONTROL = exports.SPLIT_UPDATE = exports.SPLIT_KILL = exports.SEGMENT_UPDATE = exports.MY_SEGMENTS_UPDATE_V2 = exports.MY_SEGMENTS_UPDATE = exports.PUSH_SUBSYSTEM_DOWN = exports.PUSH_SUBSYSTEM_UP = exports.PUSH_RETRYABLE_ERROR = exports.PUSH_NONRETRYABLE_ERROR = exports.SECONDS_BEFORE_EXPIRATION = void 0;
4
4
  // time for refresh token
5
5
  exports.SECONDS_BEFORE_EXPIRATION = 600;
6
6
  // Internal SDK events, subscribed by SyncManager and PushManager
@@ -26,6 +26,7 @@ exports.PUSH_SUBSYSTEM_UP = 'PUSH_SUBSYSTEM_UP';
26
26
  exports.PUSH_SUBSYSTEM_DOWN = 'PUSH_SUBSYSTEM_DOWN';
27
27
  // Update-type push notifications, handled by NotificationProcessor
28
28
  exports.MY_SEGMENTS_UPDATE = 'MY_SEGMENTS_UPDATE';
29
+ exports.MY_SEGMENTS_UPDATE_V2 = 'MY_SEGMENTS_UPDATE_V2';
29
30
  exports.SEGMENT_UPDATE = 'SEGMENT_UPDATE';
30
31
  exports.SPLIT_KILL = 'SPLIT_KILL';
31
32
  exports.SPLIT_UPDATE = 'SPLIT_UPDATE';
@@ -37,4 +38,5 @@ var ControlType;
37
38
  ControlType["STREAMING_DISABLED"] = "STREAMING_DISABLED";
38
39
  ControlType["STREAMING_PAUSED"] = "STREAMING_PAUSED";
39
40
  ControlType["STREAMING_RESUMED"] = "STREAMING_RESUMED";
41
+ ControlType["STREAMING_RESET"] = "STREAMING_RESET";
40
42
  })(ControlType = exports.ControlType || (exports.ControlType = {}));
@@ -0,0 +1,75 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isInBitmap = exports.parseBitmap = exports.parseKeyList = void 0;
4
+ var decompress_1 = require("../../utils/decompress");
5
+ var base64_1 = require("../../utils/base64");
6
+ var GZIP = 1;
7
+ var ZLIB = 2;
8
+ function Uint8ArrayToString(myUint8Arr) {
9
+ return String.fromCharCode.apply(null, myUint8Arr);
10
+ }
11
+ function StringToUint8Array(myString) {
12
+ var charCodes = myString.split('').map(function (e) { return e.charCodeAt(0); });
13
+ return new Uint8Array(charCodes);
14
+ }
15
+ /**
16
+ * Decode and decompress 'data' with 'compression' algorithm
17
+ *
18
+ * @param {string} data
19
+ * @param {number} compression 1 GZIP, 2 ZLIB
20
+ * @returns {Uint8Array}
21
+ * @throws if data string cannot be decoded, decompressed or the provided compression value is invalid (not 1 or 2)
22
+ */
23
+ function decompress(data, compression) {
24
+ var compressData = base64_1.decodeFromBase64(data);
25
+ var binData = StringToUint8Array(compressData);
26
+ if (typeof decompress_1.algorithms === 'string')
27
+ throw new Error(decompress_1.algorithms);
28
+ if (compression === GZIP)
29
+ return decompress_1.algorithms.gunzipSync(binData);
30
+ if (compression === ZLIB)
31
+ return decompress_1.algorithms.unzlibSync(binData);
32
+ throw new Error("Invalid compression algorithm #" + compression);
33
+ }
34
+ /**
35
+ * Decode, decompress and parse the provided 'data' into a KeyList object
36
+ *
37
+ * @param {string} data
38
+ * @param {number} compression
39
+ * @returns {{a?: string[], r?: string[] }}
40
+ * @throws if data string cannot be decoded, decompressed or parsed
41
+ */
42
+ function parseKeyList(data, compression) {
43
+ var binKeyList = decompress(data, compression);
44
+ var strKeyList = Uint8ArrayToString(binKeyList);
45
+ // replace numbers to strings, to avoid losing precision
46
+ return JSON.parse(strKeyList.replace(/\d+/g, '"$&"'));
47
+ }
48
+ exports.parseKeyList = parseKeyList;
49
+ /**
50
+ * Decode, decompress and parse the provided 'data' into a Bitmap object
51
+ *
52
+ * @param {string} data
53
+ * @param {number} compression
54
+ * @returns {Uint8Array}
55
+ * @throws if data string cannot be decoded or decompressed
56
+ */
57
+ function parseBitmap(data, compression) {
58
+ return decompress(data, compression);
59
+ }
60
+ exports.parseBitmap = parseBitmap;
61
+ /**
62
+ * Check if the 'bitmap' bit at 'hash64hex' position is 1
63
+ *
64
+ * @param {Uint8Array} bitmap
65
+ * @param {string} hash64hex 16-chars string, representing a number in hexa
66
+ * @returns {boolean}
67
+ */
68
+ function isInBitmap(bitmap, hash64hex) {
69
+ // using the lowest 32 bits as index, to avoid losing precision when converting to number
70
+ var index = parseInt(hash64hex.slice(8), 16) % (bitmap.length * 8);
71
+ var internal = Math.floor(index / 8);
72
+ var offset = index % 8;
73
+ return (bitmap[internal] & 1 << offset) > 0;
74
+ }
75
+ exports.isInBitmap = isInBitmap;
@@ -13,16 +13,24 @@ var SSEClient_1 = tslib_1.__importDefault(require("./SSEClient"));
13
13
  var key_1 = require("../../utils/key");
14
14
  var constants_1 = require("./constants");
15
15
  var constants_2 = require("../../logger/constants");
16
+ var types_1 = require("./SSEHandler/types");
17
+ var mySegmentsV2utils_1 = require("./mySegmentsV2utils");
18
+ var sets_1 = require("../../utils/lang/sets");
19
+ var murmur3_64_1 = require("../../utils/murmur3/murmur3_64");
16
20
  /**
17
21
  * PushManager factory:
18
22
  * - for server-side if key is not provided in settings.
19
23
  * - for client-side, with support for multiple clients, if key is provided in settings
20
24
  */
21
25
  function pushManagerFactory(pollingManager, storage, readiness, fetchAuth, platform, settings) {
26
+ // `userKey` is the matching key of main client in client-side SDK.
27
+ // It can be used to check if running on client-side or server-side SDK.
28
+ var userKey = settings.core.key ? key_1.getMatching(settings.core.key) : undefined; //
22
29
  var log = settings.log;
23
30
  var sseClient;
24
31
  try {
25
- sseClient = new SSEClient_1.default(settings.urls.streaming, platform.getEventSource);
32
+ // `useHeaders` false for client-side, even if the platform EventSource supports headers (e.g., React Native).
33
+ sseClient = new SSEClient_1.default(settings, userKey ? false : true, platform.getEventSource);
26
34
  }
27
35
  catch (e) {
28
36
  log.warn(constants_2.STREAMING_FALLBACK, [e]);
@@ -33,44 +41,58 @@ function pushManagerFactory(pollingManager, storage, readiness, fetchAuth, platf
33
41
  var pushEmitter = new platform.EventEmitter();
34
42
  var sseHandler = SSEHandler_1.default(log, pushEmitter);
35
43
  sseClient.setEventHandler(sseHandler);
44
+ // init workers
45
+ var segmentsUpdateWorker = userKey ? new MySegmentsUpdateWorker_1.default(pollingManager.segmentsSyncTask) : new SegmentsUpdateWorker_1.default(storage.segments, pollingManager.segmentsSyncTask);
46
+ // For server-side we pass the segmentsSyncTask, used by SplitsUpdateWorker to fetch new segments
47
+ var splitsUpdateWorker = new SplitsUpdateWorker_1.default(storage.splits, pollingManager.splitsSyncTask, readiness.splits, userKey ? undefined : pollingManager.segmentsSyncTask);
36
48
  // [Only for client-side] map of hashes to user keys, to dispatch MY_SEGMENTS_UPDATE events to the corresponding MySegmentsUpdateWorker
37
49
  var userKeyHashes = {};
38
- var userKey = settings.core.key ? key_1.getMatching(settings.core.key) : undefined; // matching key of main client
50
+ // [Only for client-side] map of user keys to their corresponding hash64 and MySegmentsUpdateWorkers.
51
+ // Hash64 is used to process MY_SEGMENTS_UPDATE_V2 events and dispatch actions to the corresponding MySegmentsUpdateWorker.
52
+ var clients = {};
39
53
  if (userKey) {
40
54
  var hash = AuthClient_1.hashUserKey(userKey);
41
55
  userKeyHashes[hash] = userKey;
56
+ clients[userKey] = { hash64: murmur3_64_1.hash64(userKey), worker: segmentsUpdateWorker };
42
57
  }
43
- // init workers
44
- var segmentsUpdateWorker = userKey ? new MySegmentsUpdateWorker_1.default(pollingManager.segmentsSyncTask) : new SegmentsUpdateWorker_1.default(storage.segments, pollingManager.segmentsSyncTask);
45
- // [Only for server-side] we pass the segmentsSyncTask, used by SplitsUpdateWorker to fetch new segments
46
- var splitsUpdateWorker = new SplitsUpdateWorker_1.default(storage.splits, pollingManager.splitsSyncTask, readiness.splits, userKey ? undefined : pollingManager.segmentsSyncTask);
47
- // [Only for client-side] map of user keys to their corresponding MySegmentsUpdateWorkers. It has a two-fold intention:
48
- // - stop workers all together when push is disconnected
49
- // - keep the current list of user keys to authenticate
50
- var workers = {};
51
- if (userKey)
52
- workers[userKey] = segmentsUpdateWorker;
53
58
  // [Only for client-side] variable to flag that a new client was added. It is needed to reconnect streaming.
54
59
  var connectForNewClient = false;
55
- // flag that indicates if `disconnectPush` was called, either by the SyncManager (when the client is destroyed) or by a PUSH_NONRETRYABLE_ERROR error.
60
+ // flag that indicates if `stop/disconnectPush` was called, either by the SyncManager, when the client is destroyed, or due to a PUSH_NONRETRYABLE_ERROR error.
56
61
  // It is used to halt the `connectPush` process if it was in progress.
57
62
  var disconnected;
63
+ // flag that indicates a PUSH_NONRETRYABLE_ERROR, condition with which starting pushManager again is ignored.
64
+ var disabled; // `disabled` implies `disconnected === true`
58
65
  /** PushManager functions related to initialization */
59
66
  var connectPushRetryBackoff = new Backoff_1.default(connectPush, settings.scheduler.pushRetryBackoffBase);
60
- var timeoutId;
61
- function scheduleTokenRefresh(issuedAt, expirationTime) {
62
- // clear scheduled token refresh if exists (needed when resuming PUSH)
63
- if (timeoutId)
64
- clearTimeout(timeoutId);
65
- // Set token refresh 10 minutes before expirationTime
66
- var delayInSeconds = expirationTime - issuedAt - constants_1.SECONDS_BEFORE_EXPIRATION;
67
- log.info(constants_2.STREAMING_REFRESH_TOKEN, [delayInSeconds]);
68
- timeoutId = setTimeout(connectPush, delayInSeconds * 1000);
67
+ var timeoutIdTokenRefresh;
68
+ var timeoutIdSseOpen;
69
+ function scheduleTokenRefreshAndSse(authData) {
70
+ // clear scheduled tasks if exist
71
+ if (timeoutIdTokenRefresh)
72
+ clearTimeout(timeoutIdTokenRefresh);
73
+ if (timeoutIdSseOpen)
74
+ clearTimeout(timeoutIdSseOpen);
75
+ // Set token refresh 10 minutes before `expirationTime - issuedAt`
76
+ var decodedToken = authData.decodedToken;
77
+ var refreshTokenDelay = decodedToken.exp - decodedToken.iat - constants_1.SECONDS_BEFORE_EXPIRATION;
78
+ // Default connDelay of 60 secs
79
+ var connDelay = typeof authData.connDelay === 'number' && authData.connDelay >= 0 ? authData.connDelay : 60;
80
+ log.info(constants_2.STREAMING_REFRESH_TOKEN, [refreshTokenDelay, connDelay]);
81
+ timeoutIdTokenRefresh = setTimeout(connectPush, refreshTokenDelay * 1000);
82
+ timeoutIdSseOpen = setTimeout(function () {
83
+ // halt if disconnected
84
+ if (disconnected)
85
+ return;
86
+ sseClient.open(authData);
87
+ }, connDelay * 1000);
69
88
  }
70
89
  function connectPush() {
90
+ // Guard condition in case `stop/disconnectPush` has been called (e.g., calling SDK destroy, or app signal close/background)
91
+ if (disconnected)
92
+ return;
93
+ log.info(constants_2.STREAMING_CONNECTING, [disconnected === undefined ? '' : 'Re-']);
71
94
  disconnected = false;
72
- log.info(constants_2.STREAMING_CONNECTING);
73
- var userKeys = userKey ? Object.keys(workers) : undefined;
95
+ var userKeys = userKey ? Object.keys(clients) : undefined;
74
96
  authenticate(userKeys).then(function (authData) {
75
97
  if (disconnected)
76
98
  return;
@@ -82,12 +104,10 @@ function pushManagerFactory(pollingManager, storage, readiness, fetchAuth, platf
82
104
  return;
83
105
  }
84
106
  // [Only for client-side] don't open SSE connection if a new shared client was added, since it means that a new authentication is taking place
85
- if (userKeys && userKeys.length < Object.keys(workers).length)
107
+ if (userKeys && userKeys.length < Object.keys(clients).length)
86
108
  return;
87
- // Connect to SSE and schedule refresh token
88
- var decodedToken = authData.decodedToken;
89
- sseClient.open(authData);
90
- scheduleTokenRefresh(decodedToken.iat, decodedToken.exp);
109
+ // Schedule SSE connection and refresh token
110
+ scheduleTokenRefreshAndSse(authData);
91
111
  }).catch(function (error) {
92
112
  if (disconnected)
93
113
  return;
@@ -103,11 +123,16 @@ function pushManagerFactory(pollingManager, storage, readiness, fetchAuth, platf
103
123
  }
104
124
  // close SSE connection and cancel scheduled tasks
105
125
  function disconnectPush() {
126
+ // Halt disconnecting, just to avoid redundant logs if called multiple times
127
+ if (disconnected)
128
+ return;
106
129
  disconnected = true;
107
- log.info(constants_2.STREAMING_DISCONNECTING);
108
130
  sseClient.close();
109
- if (timeoutId)
110
- clearTimeout(timeoutId);
131
+ log.info(constants_2.STREAMING_DISCONNECTING);
132
+ if (timeoutIdTokenRefresh)
133
+ clearTimeout(timeoutIdTokenRefresh);
134
+ if (timeoutIdSseOpen)
135
+ clearTimeout(timeoutIdSseOpen);
111
136
  connectPushRetryBackoff.reset();
112
137
  stopWorkers();
113
138
  }
@@ -115,15 +140,23 @@ function pushManagerFactory(pollingManager, storage, readiness, fetchAuth, platf
115
140
  function stopWorkers() {
116
141
  splitsUpdateWorker.backoff.reset();
117
142
  if (userKey)
118
- lang_1.forOwn(workers, function (worker) { return worker.backoff.reset(); });
143
+ lang_1.forOwn(clients, function (_a) {
144
+ var worker = _a.worker;
145
+ return worker.backoff.reset();
146
+ });
119
147
  else
120
148
  segmentsUpdateWorker.backoff.reset();
121
149
  }
122
150
  pushEmitter.on(constants_1.PUSH_SUBSYSTEM_DOWN, stopWorkers);
123
- // restart backoff retry counter once push is connected
124
- pushEmitter.on(constants_1.PUSH_SUBSYSTEM_UP, function () { connectPushRetryBackoff.reset(); });
151
+ // Only required when streaming connects after a PUSH_RETRYABLE_ERROR.
152
+ // Otherwise it is unnecessary (e.g, STREAMING_RESUMED).
153
+ pushEmitter.on(constants_1.PUSH_SUBSYSTEM_UP, function () {
154
+ connectPushRetryBackoff.reset();
155
+ stopWorkers();
156
+ });
125
157
  /** Fallbacking without retry due to: STREAMING_DISABLED control event, or 'pushEnabled: false', or non-recoverable SSE and Authentication errors */
126
158
  pushEmitter.on(constants_1.PUSH_NONRETRYABLE_ERROR, function handleNonRetryableError() {
159
+ disabled = true;
127
160
  // Note: `stopWorkers` is been called twice, but it is not harmful
128
161
  disconnectPush();
129
162
  pushEmitter.emit(constants_1.PUSH_SUBSYSTEM_DOWN); // no harm if polling already
@@ -137,6 +170,16 @@ function pushManagerFactory(pollingManager, storage, readiness, fetchAuth, platf
137
170
  log.info(constants_2.STREAMING_RECONNECT, [delayInMillis / 1000]);
138
171
  pushEmitter.emit(constants_1.PUSH_SUBSYSTEM_DOWN); // no harm if polling already
139
172
  });
173
+ /** STREAMING_RESET notification. Unlike a PUSH_RETRYABLE_ERROR, it doesn't emit PUSH_SUBSYSTEM_DOWN to fallback polling */
174
+ pushEmitter.on(constants_1.ControlType.STREAMING_RESET, function handleStreamingReset() {
175
+ if (disconnected)
176
+ return; // should never happen
177
+ // Minimum required clean-up.
178
+ // `disconnectPush` cannot be called because it sets `disconnected` and thus `connectPush` will not execute
179
+ if (timeoutIdTokenRefresh)
180
+ clearTimeout(timeoutIdTokenRefresh);
181
+ connectPush();
182
+ });
140
183
  /** Functions related to synchronization (Queues and Workers in the spec) */
141
184
  pushEmitter.on(constants_1.SPLIT_KILL, splitsUpdateWorker.killSplit);
142
185
  pushEmitter.on(constants_1.SPLIT_UPDATE, splitsUpdateWorker.put);
@@ -144,11 +187,72 @@ function pushManagerFactory(pollingManager, storage, readiness, fetchAuth, platf
144
187
  pushEmitter.on(constants_1.MY_SEGMENTS_UPDATE, function handleMySegmentsUpdate(parsedData, channel) {
145
188
  var userKeyHash = channel.split('_')[2];
146
189
  var userKey = userKeyHashes[userKeyHash];
147
- if (userKey && workers[userKey]) { // check context since it can be undefined if client has been destroyed
148
- var mySegmentsUpdateWorker = workers[userKey];
149
- mySegmentsUpdateWorker.put(parsedData.changeNumber, parsedData.includesPayload ? parsedData.segmentList ? parsedData.segmentList : [] : undefined);
190
+ if (userKey && clients[userKey]) { // check existence since it can be undefined if client has been destroyed
191
+ clients[userKey].worker.put(parsedData.changeNumber, parsedData.includesPayload ? parsedData.segmentList ? parsedData.segmentList : [] : undefined);
150
192
  }
151
193
  });
194
+ pushEmitter.on(constants_1.MY_SEGMENTS_UPDATE_V2, function handleMySegmentsUpdate(parsedData) {
195
+ switch (parsedData.u) {
196
+ case types_1.UpdateStrategy.BoundedFetchRequest: {
197
+ var bitmap_1;
198
+ try {
199
+ bitmap_1 = mySegmentsV2utils_1.parseBitmap(parsedData.d, parsedData.c);
200
+ }
201
+ catch (e) {
202
+ log.warn(constants_2.STREAMING_PARSING_MY_SEGMENTS_UPDATE_V2, ['BoundedFetchRequest', e]);
203
+ break;
204
+ }
205
+ lang_1.forOwn(clients, function (_a) {
206
+ var hash64 = _a.hash64, worker = _a.worker;
207
+ if (mySegmentsV2utils_1.isInBitmap(bitmap_1, hash64.hex)) {
208
+ worker.put(parsedData.changeNumber); // fetch mySegments
209
+ }
210
+ });
211
+ return;
212
+ }
213
+ case types_1.UpdateStrategy.KeyList: {
214
+ var keyList = void 0, added_1, removed_1;
215
+ try {
216
+ keyList = mySegmentsV2utils_1.parseKeyList(parsedData.d, parsedData.c);
217
+ added_1 = new sets_1._Set(keyList.a);
218
+ removed_1 = new sets_1._Set(keyList.r);
219
+ }
220
+ catch (e) {
221
+ log.warn(constants_2.STREAMING_PARSING_MY_SEGMENTS_UPDATE_V2, ['KeyList', e]);
222
+ break;
223
+ }
224
+ lang_1.forOwn(clients, function (_a) {
225
+ var hash64 = _a.hash64, worker = _a.worker;
226
+ var add = added_1.has(hash64.dec) ? true : removed_1.has(hash64.dec) ? false : undefined;
227
+ if (add !== undefined) {
228
+ worker.put(parsedData.changeNumber, {
229
+ name: parsedData.segmentName,
230
+ add: add
231
+ });
232
+ }
233
+ });
234
+ return;
235
+ }
236
+ case types_1.UpdateStrategy.SegmentRemoval:
237
+ if (!parsedData.segmentName) {
238
+ log.warn(constants_2.STREAMING_PARSING_MY_SEGMENTS_UPDATE_V2, ['SegmentRemoval', 'No segment name was provided']);
239
+ break;
240
+ }
241
+ lang_1.forOwn(clients, function (_a) {
242
+ var worker = _a.worker;
243
+ return worker.put(parsedData.changeNumber, {
244
+ name: parsedData.segmentName,
245
+ add: false
246
+ });
247
+ });
248
+ return;
249
+ }
250
+ // `UpdateStrategy.UnboundedFetchRequest` and fallbacks of other cases
251
+ lang_1.forOwn(clients, function (_a) {
252
+ var worker = _a.worker;
253
+ worker.put(parsedData.changeNumber);
254
+ });
255
+ });
152
256
  }
153
257
  else {
154
258
  pushEmitter.on(constants_1.SEGMENT_UPDATE, segmentsUpdateWorker.put);
@@ -159,13 +263,16 @@ function pushManagerFactory(pollingManager, storage, readiness, fetchAuth, platf
159
263
  // Expose functionality for starting and stoping push mode:
160
264
  stop: disconnectPush,
161
265
  start: function () {
266
+ // Guard condition to avoid calling `connectPush` again if the `start` method is called multiple times or if push has been disabled.
267
+ if (disabled || disconnected === false)
268
+ return;
269
+ disconnected = false;
162
270
  // Run in next event-loop cycle for optimization on client-side: if multiple clients are created in the same cycle than the factory, only one authentication is performed.
163
271
  setTimeout(connectPush);
164
272
  },
165
273
  // [Only for client-side]
166
274
  add: function (userKey, mySegmentsSyncTask) {
167
- var mySegmentsUpdateWorker = new MySegmentsUpdateWorker_1.default(mySegmentsSyncTask);
168
- workers[userKey] = mySegmentsUpdateWorker;
275
+ clients[userKey] = { hash64: murmur3_64_1.hash64(userKey), worker: new MySegmentsUpdateWorker_1.default(mySegmentsSyncTask) };
169
276
  var hash = AuthClient_1.hashUserKey(userKey);
170
277
  if (!userKeyHashes[hash]) {
171
278
  userKeyHashes[hash] = userKey;
@@ -185,6 +292,7 @@ function pushManagerFactory(pollingManager, storage, readiness, fetchAuth, platf
185
292
  remove: function (userKey) {
186
293
  var hash = AuthClient_1.hashUserKey(userKey);
187
294
  delete userKeyHashes[hash];
295
+ delete clients[userKey];
188
296
  }
189
297
  });
190
298
  }
@@ -26,6 +26,6 @@ exports.countsSyncTaskFactory = countsSyncTaskFactory;
26
26
  */
27
27
  function latenciesSyncTaskFactory(log, postMetricsLatencies, latenciesCache, metricsRefreshRate, latencyTracker) {
28
28
  // don't retry metrics.
29
- return submitterSyncTask_1.submitterSyncTaskFactory(log, postMetricsLatencies, latenciesCache, metricsRefreshRate, 'latency metrics', latencyTracker, fromCache('latencies'));
29
+ return submitterSyncTask_1.submitterSyncTaskFactory(log, postMetricsLatencies, latenciesCache, metricsRefreshRate, 'latency metrics', latencyTracker, fromCache('latencies'), 0, true);
30
30
  }
31
31
  exports.latenciesSyncTaskFactory = latenciesSyncTaskFactory;
@@ -7,7 +7,7 @@ var constants_1 = require("../../logger/constants");
7
7
  /**
8
8
  * Base function to create submitter sync tasks, such as ImpressionsSyncTask and EventsSyncTask
9
9
  */
10
- function submitterSyncTaskFactory(log, postClient, sourceCache, postRate, dataName, latencyTracker, fromCacheToPayload, maxRetries) {
10
+ function submitterSyncTaskFactory(log, postClient, sourceCache, postRate, dataName, latencyTracker, fromCacheToPayload, maxRetries, debugLogs) {
11
11
  if (maxRetries === void 0) { maxRetries = 0; }
12
12
  var retries = 0;
13
13
  function postData() {
@@ -15,7 +15,7 @@ function submitterSyncTaskFactory(log, postClient, sourceCache, postRate, dataNa
15
15
  return Promise.resolve();
16
16
  var data = sourceCache.state();
17
17
  var dataCount = typeof data.length === 'number' ? data.length : '';
18
- log.info(constants_1.SUBMITTERS_PUSH, [dataCount, dataName]);
18
+ log[debugLogs ? 'debug' : 'info'](constants_1.SUBMITTERS_PUSH, [dataCount, dataName]);
19
19
  var latencyTrackerStop = latencyTracker && latencyTracker.start();
20
20
  var jsonPayload = JSON.stringify(fromCacheToPayload ? fromCacheToPayload(data) : data);
21
21
  if (!maxRetries)
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.LocalhostFromFile = void 0;
4
+ var splitsParserFromFile_1 = require("./offline/splitsParser/splitsParserFromFile");
5
+ var syncManagerOffline_1 = require("./syncManagerOffline");
6
+ var constants_1 = require("../utils/constants");
7
+ // Factory of Localhost SyncManager based on yaml file.
8
+ // Requires Node 'fs' and 'path' APIs.
9
+ function LocalhostFromFile() {
10
+ var localhost = syncManagerOffline_1.syncManagerOfflineFactory(splitsParserFromFile_1.splitsParserFromFileFactory);
11
+ // @ts-ignore
12
+ localhost.type = constants_1.LOCALHOST_MODE;
13
+ return localhost;
14
+ }
15
+ exports.LocalhostFromFile = LocalhostFromFile;
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.LocalhostFromObject = void 0;
4
+ var splitsParserFromSettings_1 = require("./offline/splitsParser/splitsParserFromSettings");
5
+ var syncManagerOffline_1 = require("./syncManagerOffline");
6
+ var constants_1 = require("../utils/constants");
7
+ // Factory of Localhost SyncManager based on JS object.
8
+ function LocalhostFromObject() {
9
+ var localhost = syncManagerOffline_1.syncManagerOfflineFactory(splitsParserFromSettings_1.splitsParserFromSettingsFactory);
10
+ // @ts-ignore
11
+ localhost.type = constants_1.LOCALHOST_MODE;
12
+ return localhost;
13
+ }
14
+ exports.LocalhostFromObject = LocalhostFromObject;
@@ -14,20 +14,20 @@ function flush() {
14
14
  *
15
15
  * @param splitsParser e.g., `splitsParserFromFile`, `splitsParserFromSettings`.
16
16
  */
17
- function syncManagerOfflineFactory(splitsParser) {
17
+ function syncManagerOfflineFactory(splitsParserFactory) {
18
18
  /**
19
19
  * SyncManager factory for modular SDK
20
20
  */
21
21
  return function (_a) {
22
22
  var settings = _a.settings, readiness = _a.readiness, storage = _a.storage;
23
- return object_assign_1.default(fromObjectSyncTask_1.default(splitsParser, storage, readiness, settings), {
23
+ return object_assign_1.default(fromObjectSyncTask_1.default(splitsParserFactory(), storage, readiness, settings), {
24
24
  // fake flush, that resolves immediately
25
25
  flush: flush,
26
26
  // [Only used for client-side]
27
27
  shared: function (matchingKey, readinessManager) {
28
28
  return {
29
29
  start: function () {
30
- // In LOCALHOST mode, shared clients are ready in the next event cycle than created
30
+ // In LOCALHOST mode, shared clients are ready in the next event-loop cycle than created
31
31
  // SDK_READY cannot be emitted directly because this will not update the readiness status
32
32
  setTimeout(function () {
33
33
  readinessManager.segments.emit(constants_1.SDK_SEGMENTS_ARRIVED); // SDK_SPLITS_ARRIVED emitted by main SyncManager
@@ -56,15 +56,25 @@ function syncManagerOnlineFactory(pollingManagerFactory, pushManagerFactory) {
56
56
  // fetch splits and segments. There is no need to catch this promise (it is always resolved)
57
57
  pollingManager.syncAll();
58
58
  }
59
- var running = false;
59
+ if (pushManager) {
60
+ pushManager.on(constants_1.PUSH_SUBSYSTEM_UP, stopPollingAndSyncAll);
61
+ pushManager.on(constants_1.PUSH_SUBSYSTEM_DOWN, startPolling);
62
+ }
63
+ var running = false; // flag that indicates whether the syncManager has been started (true) or stopped (false)
64
+ var startFirstTime = true; // flag to distinguish calling the `start` method for the first time, to support pausing and resuming the synchronization
60
65
  return {
66
+ pushManager: pushManager,
67
+ /**
68
+ * Method used to start the syncManager for the first time, or resume it after being stopped.
69
+ */
61
70
  start: function () {
62
71
  // start syncing splits and segments
63
72
  if (pushManager) {
64
- pollingManager.syncAll();
65
- pushManager.on(constants_1.PUSH_SUBSYSTEM_UP, stopPollingAndSyncAll);
66
- pushManager.on(constants_1.PUSH_SUBSYSTEM_DOWN, startPolling);
67
- // Run in next event-loop cycle as in client-side SyncManager
73
+ // Doesn't call `syncAll` when the syncManager is resuming
74
+ if (startFirstTime) {
75
+ pollingManager.syncAll();
76
+ startFirstTime = false;
77
+ }
68
78
  pushManager.start();
69
79
  }
70
80
  else {
@@ -74,6 +84,9 @@ function syncManagerOnlineFactory(pollingManagerFactory, pushManagerFactory) {
74
84
  submitter && submitter.start();
75
85
  running = true;
76
86
  },
87
+ /**
88
+ * Method used to stop/pause the syncManager.
89
+ */
77
90
  stop: function () {
78
91
  // stop syncing
79
92
  if (pushManager)
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  var constants_1 = require("../logger/constants");
4
4
  /**
5
- * Creates a syncTask that handles the periodic execution of a givan task ("start" and "stop" methods).
5
+ * Creates a syncTask that handles the periodic execution of a given task ("start" and "stop" methods).
6
6
  * The task can be executed once calling the "execute" method.
7
7
  * NOTE: Multiple calls to "execute" are not queued. Use "isExecuting" method to handle synchronization.
8
8
  *
@@ -8,8 +8,6 @@ var ImpressionObserver = /** @class */ (function () {
8
8
  this.hasher = hasher;
9
9
  }
10
10
  ImpressionObserver.prototype.testAndSet = function (impression) {
11
- if (!impression)
12
- return;
13
11
  var hash = this.hasher(impression);
14
12
  var previous = this.cache.get(hash);
15
13
  this.cache.set(hash, impression.time);
@@ -1,13 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- var UNKNOWN = 'UNKNOWN';
4
- function _unknownIfNull(s) {
5
- return s ? s : UNKNOWN;
6
- }
7
- function _zeroIfNull(l) {
8
- return l ? l : 0;
9
- }
3
+ exports.buildKey = void 0;
10
4
  function buildKey(impression) {
11
- return _unknownIfNull(impression.keyName) + "\n :" + _unknownIfNull(impression.feature) + "\n :" + _unknownIfNull(impression.treatment) + "\n :" + _unknownIfNull(impression.label) + "\n :" + _zeroIfNull(impression.changeNumber);
5
+ return impression.keyName + ":" + impression.feature + ":" + impression.treatment + ":" + impression.label + ":" + impression.changeNumber;
12
6
  }
13
- exports.default = buildKey;
7
+ exports.buildKey = buildKey;
@@ -4,9 +4,9 @@ exports.impressionObserverCSFactory = exports.hashImpression32 = void 0;
4
4
  var tslib_1 = require("tslib");
5
5
  var ImpressionObserver_1 = tslib_1.__importDefault(require("./ImpressionObserver"));
6
6
  var murmur3_1 = require("../../utils/murmur3/murmur3");
7
- var buildKey_1 = tslib_1.__importDefault(require("./buildKey"));
7
+ var buildKey_1 = require("./buildKey");
8
8
  function hashImpression32(impression) {
9
- return impression ? murmur3_1.hash(buildKey_1.default(impression)).toString() : null;
9
+ return murmur3_1.hash(buildKey_1.buildKey(impression));
10
10
  }
11
11
  exports.hashImpression32 = hashImpression32;
12
12
  var LAST_SEEN_CACHE_SIZE = 500; // cache up to 500 impression hashes