@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,6 +1,5 @@
1
1
  import { isObject, forOwn } from '../../../utils/lang';
2
2
  import parseCondition from './parseCondition';
3
- var previousMock = { 'emptyMock': '1' };
4
3
  function hasTreatmentChanged(prev, curr) {
5
4
  if (typeof prev !== typeof curr)
6
5
  return true;
@@ -11,46 +10,49 @@ function hasTreatmentChanged(prev, curr) {
11
10
  return prev.treatment !== curr.treatment || prev.config !== curr.config;
12
11
  }
13
12
  }
14
- function mockUpdated(currentData) {
15
- var names = Object.keys(currentData);
16
- // Different amount of items
17
- if (names.length !== Object.keys(previousMock).length) {
18
- previousMock = currentData;
19
- return true;
20
- }
21
- return names.some(function (name) {
22
- var newSplit = !previousMock[name];
23
- var newTreatment = hasTreatmentChanged(previousMock[name], currentData[name]);
24
- var changed = newSplit || newTreatment;
25
- if (changed)
13
+ export function splitsParserFromSettingsFactory() {
14
+ var previousMock = { 'emptyMock': '1' };
15
+ function mockUpdated(currentData) {
16
+ var names = Object.keys(currentData);
17
+ // Different amount of items
18
+ if (names.length !== Object.keys(previousMock).length) {
26
19
  previousMock = currentData;
27
- return changed;
28
- });
29
- }
30
- /**
31
- *
32
- * @param features validated object with mocked features mapping.
33
- */
34
- export default function splitsParserFromSettings(settings) {
35
- var features = settings.features || {};
36
- if (!mockUpdated(features))
37
- return false;
38
- var splitObjects = {};
39
- forOwn(features, function (data, splitName) {
40
- var treatment = data;
41
- var config = null;
42
- if (isObject(data)) {
43
- treatment = data.treatment;
44
- config = data.config || config;
20
+ return true;
45
21
  }
46
- var configurations = {};
47
- if (config !== null)
48
- configurations[treatment] = config;
49
- splitObjects[splitName] = {
50
- trafficTypeName: 'localhost',
51
- conditions: [parseCondition({ treatment: treatment })],
52
- configurations: configurations
53
- };
54
- });
55
- return splitObjects;
22
+ return names.some(function (name) {
23
+ var newSplit = !previousMock[name];
24
+ var newTreatment = hasTreatmentChanged(previousMock[name], currentData[name]);
25
+ var changed = newSplit || newTreatment;
26
+ if (changed)
27
+ previousMock = currentData;
28
+ return changed;
29
+ });
30
+ }
31
+ /**
32
+ *
33
+ * @param settings validated object with mocked features mapping.
34
+ */
35
+ return function splitsParserFromSettings(settings) {
36
+ var features = settings.features || {};
37
+ if (!mockUpdated(features))
38
+ return false;
39
+ var splitObjects = {};
40
+ forOwn(features, function (data, splitName) {
41
+ var treatment = data;
42
+ var config = null;
43
+ if (isObject(data)) {
44
+ treatment = data.treatment;
45
+ config = data.config || config;
46
+ }
47
+ var configurations = {};
48
+ if (config !== null)
49
+ configurations[treatment] = config;
50
+ splitObjects[splitName] = {
51
+ trafficTypeName: 'localhost',
52
+ conditions: [parseCondition({ treatment: treatment })],
53
+ configurations: configurations
54
+ };
55
+ });
56
+ return splitObjects;
57
+ };
56
58
  }
@@ -1,13 +1,14 @@
1
1
  import { forOwn } from '../../../utils/lang';
2
2
  import syncTaskFactory from '../../syncTask';
3
3
  import { CONTROL } from '../../../utils/constants';
4
- import { SDK_SPLITS_ARRIVED, SDK_SEGMENTS_ARRIVED } from '../../../readiness/constants';
4
+ import { SDK_SPLITS_ARRIVED, SDK_SEGMENTS_ARRIVED, SDK_SPLITS_CACHE_LOADED } from '../../../readiness/constants';
5
5
  import { SYNC_OFFLINE_DATA, ERROR_SYNC_OFFLINE_LOADING } from '../../../logger/constants';
6
6
  /**
7
7
  * Offline equivalent of `splitChangesUpdaterFactory`
8
8
  */
9
9
  export function fromObjectUpdaterFactory(splitsParser, storage, readiness, settings) {
10
- var log = settings.log;
10
+ var log = settings.log, splitsCache = storage.splits;
11
+ var startingUp = true;
11
12
  return function objectUpdater() {
12
13
  var splits = [];
13
14
  var loadError = null;
@@ -37,11 +38,20 @@ export function fromObjectUpdaterFactory(splitsParser, storage, readiness, setti
37
38
  ]);
38
39
  });
39
40
  return Promise.all([
40
- storage.splits.clear(),
41
- storage.splits.addSplits(splits)
41
+ splitsCache.clear(),
42
+ splitsCache.addSplits(splits)
42
43
  ]).then(function () {
43
44
  readiness.splits.emit(SDK_SPLITS_ARRIVED);
44
- readiness.segments.emit(SDK_SEGMENTS_ARRIVED);
45
+ if (startingUp) {
46
+ startingUp = false;
47
+ Promise.resolve(splitsCache.checkCache()).then(function (cacheReady) {
48
+ // Emits SDK_READY_FROM_CACHE
49
+ if (cacheReady)
50
+ readiness.splits.emit(SDK_SPLITS_CACHE_LOADED);
51
+ // Emits SDK_READY
52
+ readiness.segments.emit(SDK_SEGMENTS_ARRIVED);
53
+ });
54
+ }
45
55
  return true;
46
56
  });
47
57
  }
@@ -20,19 +20,36 @@ export function mySegmentsUpdaterFactory(log, mySegmentsFetcher, splitsCache, my
20
20
  // mySegmentsPromise = tracker.start(tracker.TaskNames.MY_SEGMENTS_FETCH, startingUp ? metricCollectors : false, mySegmentsPromise);
21
21
  }
22
22
  // @TODO if allowing custom storages, handle async execution
23
- function updateSegments(segments) {
24
- // Update the list of segment names available
25
- var shouldNotifyUpdate = mySegmentsCache.resetSegments(segments);
23
+ function updateSegments(segmentsData) {
24
+ var shouldNotifyUpdate;
25
+ if (Array.isArray(segmentsData)) {
26
+ // Update the list of segment names available
27
+ shouldNotifyUpdate = mySegmentsCache.resetSegments(segmentsData);
28
+ }
29
+ else {
30
+ // Add/Delete the segment
31
+ var name_1 = segmentsData.name, add = segmentsData.add;
32
+ if (mySegmentsCache.isInSegment(name_1) !== add) {
33
+ shouldNotifyUpdate = true;
34
+ if (add)
35
+ mySegmentsCache.addToSegment(name_1);
36
+ else
37
+ mySegmentsCache.removeFromSegment(name_1);
38
+ }
39
+ else {
40
+ shouldNotifyUpdate = false;
41
+ }
42
+ }
26
43
  // Notify update if required
27
44
  if (splitsCache.usesSegments() && (shouldNotifyUpdate || readyOnAlreadyExistentState)) {
28
45
  readyOnAlreadyExistentState = false;
29
46
  segmentsEventEmitter.emit(SDK_SEGMENTS_ARRIVED);
30
47
  }
31
48
  }
32
- function _mySegmentsUpdater(retry, segmentList, noCache) {
33
- var updaterPromise = segmentList ?
34
- // If segmentList is provided, there is no need to fetch mySegments
35
- new Promise(function (res) { updateSegments(segmentList); res(true); }) :
49
+ function _mySegmentsUpdater(retry, segmentsData, noCache) {
50
+ var updaterPromise = segmentsData ?
51
+ // If segmentsData is provided, there is no need to fetch mySegments
52
+ new Promise(function (res) { updateSegments(segmentsData); res(true); }) :
36
53
  // If not provided, fetch mySegments
37
54
  mySegmentsFetcher(noCache, _promiseDecorator).then(function (segments) {
38
55
  // Only when we have downloaded segments completely, we should not keep retrying anymore
@@ -56,10 +73,13 @@ export function mySegmentsUpdaterFactory(log, mySegmentsFetcher, splitsCache, my
56
73
  * MySegments updater returns a promise that resolves with a `false` boolean value if it fails to fetch mySegments or synchronize them with the storage.
57
74
  * Returned promise will not be rejected.
58
75
  *
59
- * @param {string[] | undefined} segmentList list of mySegments names to sync in the storage. If the list is `undefined`, it fetches them before syncing in the storage.
76
+ * @param {SegmentsData | undefined} segmentsData it can be:
77
+ * (1) the list of mySegments names to sync in the storage,
78
+ * (2) an object with a segment name and action (true: add, or false: delete) to update the storage,
79
+ * (3) or `undefined`, for which the updater will fetch mySegments in order to sync the storage.
60
80
  * @param {boolean | undefined} noCache true to revalidate data to fetch
61
81
  */
62
- return function mySegmentsUpdater(segmentList, noCache) {
63
- return _mySegmentsUpdater(0, segmentList, noCache);
82
+ return function mySegmentsUpdater(segmentsData, noCache) {
83
+ return _mySegmentsUpdater(0, segmentsData, noCache);
64
84
  };
65
85
  }
@@ -38,7 +38,6 @@ var SSEClient = /** @class */ (function () {
38
38
  if (!this.eventSource)
39
39
  throw new Error('EventSource API is not available. ');
40
40
  this.streamingUrl = settings.urls.streaming + '/sse';
41
- this.reopen = this.reopen.bind(this);
42
41
  // @TODO get `useHeaders` flag from `getEventSource`, to use EventSource headers on client-side SDKs when possible.
43
42
  this.useHeaders = useHeaders;
44
43
  this.headers = buildSSEHeaders(settings);
@@ -54,7 +53,6 @@ var SSEClient = /** @class */ (function () {
54
53
  */
55
54
  SSEClient.prototype.open = function (authToken) {
56
55
  this.close(); // it closes connection if previously opened
57
- this.authToken = authToken;
58
56
  var channelsQueryParam = Object.keys(authToken.channels).map(function (channel) {
59
57
  var params = CONTROL_CHANNEL_REGEX.test(channel) ? '[?occupancy=metrics.publishers]' : '';
60
58
  return encodeURIComponent(params + channel);
@@ -77,15 +75,6 @@ var SSEClient = /** @class */ (function () {
77
75
  if (this.connection)
78
76
  this.connection.close();
79
77
  };
80
- /**
81
- * Re-open the connection with the last given authToken.
82
- *
83
- * @throws {TypeError} if `open` has not been previously called with an authToken
84
- * @TODO this method is not used currently and could be removed.
85
- */
86
- SSEClient.prototype.reopen = function () {
87
- this.open(this.authToken);
88
- };
89
78
  return SSEClient;
90
79
  }());
91
80
  export default SSEClient;
@@ -52,6 +52,13 @@ export default function notificationKeeperFactory(pushEmitter) {
52
52
  }
53
53
  },
54
54
  handleControlEvent: function (controlType, channel, timestamp) {
55
+ /* STREAMING_RESET control event is handled by PushManager directly since it doesn't require
56
+ * tracking timestamp and state like OCCUPANCY or CONTROL. It also ignores previous
57
+ * OCCUPANCY and CONTROL notifications, and whether PUSH_SUBSYSTEM_DOWN has been emitted or not */
58
+ if (controlType === ControlType.STREAMING_RESET) {
59
+ pushEmitter.emit(controlType);
60
+ return;
61
+ }
55
62
  for (var i = 0; i < channels.length; i++) {
56
63
  var c = channels[i];
57
64
  if (c.regex.test(channel)) {
@@ -19,10 +19,13 @@ export function errorParser(error) {
19
19
  * Also assigns the type OCCUPANCY, if it corresponds, so that all supported messages (e.g., SPLIT_UPDATE, CONTROL) have a type.
20
20
  *
21
21
  * @param message
22
- * @returns parsed notification message
22
+ * @returns parsed notification message or undefined if the given event data is falsy (e.g, '' or undefined).
23
+ * For example, the EventSource implementation of React-Native for iOS emits a message event with empty data for Ably keepalive comments.
23
24
  * @throws {SyntaxError} if `message.data` or `JSON.parse(message.data).data` are invalid JSON strings
24
25
  */
25
26
  export function messageParser(message) {
27
+ if (!message.data)
28
+ return;
26
29
  var messageData = JSON.parse(message.data);
27
30
  messageData.parsedData = JSON.parse(messageData.data);
28
31
  // set the event type to OCCUPANCY, to handle all events uniformely
@@ -1,6 +1,6 @@
1
1
  import { errorParser, messageParser } from './NotificationParser';
2
2
  import notificationKeeperFactory from './NotificationKeeper';
3
- import { PUSH_RETRYABLE_ERROR, PUSH_NONRETRYABLE_ERROR, OCCUPANCY, CONTROL, MY_SEGMENTS_UPDATE, SEGMENT_UPDATE, SPLIT_KILL, SPLIT_UPDATE } from '../constants';
3
+ import { PUSH_RETRYABLE_ERROR, PUSH_NONRETRYABLE_ERROR, OCCUPANCY, CONTROL, MY_SEGMENTS_UPDATE, MY_SEGMENTS_UPDATE_V2, SEGMENT_UPDATE, SPLIT_KILL, SPLIT_UPDATE } from '../constants';
4
4
  import { STREAMING_PARSING_ERROR_FAILS, ERROR_STREAMING_SSE, STREAMING_PARSING_MESSAGE_FAILS, STREAMING_NEW_MESSAGE } from '../../../logger/constants';
5
5
  function isRetryableError(error) {
6
6
  if (error.parsedData && error.parsedData.code) {
@@ -36,7 +36,7 @@ export default function SSEHandlerFactory(log, pushEmitter) {
36
36
  catch (err) {
37
37
  log.warn(STREAMING_PARSING_ERROR_FAILS, [err]);
38
38
  }
39
- var errorMessage = errorWithParsedData.parsedData && errorWithParsedData.parsedData.message;
39
+ var errorMessage = (errorWithParsedData.parsedData && errorWithParsedData.parsedData.message) || errorWithParsedData.message;
40
40
  log.error(ERROR_STREAMING_SSE, [errorMessage]);
41
41
  if (isRetryableError(errorWithParsedData)) {
42
42
  pushEmitter.emit(PUSH_RETRYABLE_ERROR);
@@ -50,6 +50,8 @@ export default function SSEHandlerFactory(log, pushEmitter) {
50
50
  var messageWithParsedData;
51
51
  try {
52
52
  messageWithParsedData = messageParser(message);
53
+ if (!messageWithParsedData)
54
+ return; // Messages with empty data are ignored
53
55
  }
54
56
  catch (err) {
55
57
  log.warn(STREAMING_PARSING_MESSAGE_FAILS, [err]);
@@ -58,21 +60,18 @@ export default function SSEHandlerFactory(log, pushEmitter) {
58
60
  var parsedData = messageWithParsedData.parsedData, data = messageWithParsedData.data, channel = messageWithParsedData.channel, timestamp = messageWithParsedData.timestamp;
59
61
  log.debug(STREAMING_NEW_MESSAGE, [data]);
60
62
  // we only handle update events if streaming is up.
61
- if (!notificationKeeper.isStreamingUp() && parsedData.type !== OCCUPANCY && parsedData.type !== CONTROL)
63
+ if (!notificationKeeper.isStreamingUp() && [OCCUPANCY, CONTROL].indexOf(parsedData.type) === -1)
62
64
  return;
63
65
  switch (parsedData.type) {
64
66
  /* update events */
65
67
  case SPLIT_UPDATE:
66
- pushEmitter.emit(SPLIT_UPDATE, parsedData.changeNumber);
67
- break;
68
68
  case SEGMENT_UPDATE:
69
- pushEmitter.emit(SEGMENT_UPDATE, parsedData.changeNumber, parsedData.segmentName);
69
+ case MY_SEGMENTS_UPDATE_V2:
70
+ case SPLIT_KILL:
71
+ pushEmitter.emit(parsedData.type, parsedData);
70
72
  break;
71
73
  case MY_SEGMENTS_UPDATE:
72
- pushEmitter.emit(MY_SEGMENTS_UPDATE, parsedData, channel);
73
- break;
74
- case SPLIT_KILL:
75
- pushEmitter.emit(SPLIT_KILL, parsedData.changeNumber, parsedData.splitName, parsedData.defaultTreatment);
74
+ pushEmitter.emit(parsedData.type, parsedData, channel);
76
75
  break;
77
76
  /* occupancy & control events, handled by NotificationManagerKeeper */
78
77
  case OCCUPANCY:
@@ -1 +1,13 @@
1
- export {};
1
+ export var Compression;
2
+ (function (Compression) {
3
+ Compression[Compression["None"] = 0] = "None";
4
+ Compression[Compression["Gzip"] = 1] = "Gzip";
5
+ Compression[Compression["Zlib"] = 2] = "Zlib";
6
+ })(Compression || (Compression = {}));
7
+ export var UpdateStrategy;
8
+ (function (UpdateStrategy) {
9
+ UpdateStrategy[UpdateStrategy["UnboundedFetchRequest"] = 0] = "UnboundedFetchRequest";
10
+ UpdateStrategy[UpdateStrategy["BoundedFetchRequest"] = 1] = "BoundedFetchRequest";
11
+ UpdateStrategy[UpdateStrategy["KeyList"] = 2] = "KeyList";
12
+ UpdateStrategy[UpdateStrategy["SegmentRemoval"] = 3] = "SegmentRemoval";
13
+ })(UpdateStrategy || (UpdateStrategy = {}));
@@ -10,7 +10,7 @@ var MySegmentsUpdateWorker = /** @class */ (function () {
10
10
  this.mySegmentsSyncTask = mySegmentsSyncTask;
11
11
  this.maxChangeNumber = 0; // keeps the maximum changeNumber among queued events
12
12
  this.handleNewEvent = false;
13
- this.segmentList = undefined; // keeps the segmentList (if included in payload) from the queued event with maximum changeNumber
13
+ this.segmentsData = undefined; // keeps the segmentsData (if included in notification payload) from the queued event with maximum changeNumber
14
14
  this.currentChangeNumber = -1; // @TODO: remove once `/mySegments` endpoint provides the changeNumber
15
15
  this.put = this.put.bind(this);
16
16
  this.__handleMySegmentsUpdateCall = this.__handleMySegmentsUpdateCall.bind(this);
@@ -24,7 +24,7 @@ var MySegmentsUpdateWorker = /** @class */ (function () {
24
24
  this.handleNewEvent = false;
25
25
  var currentMaxChangeNumber_1 = this.maxChangeNumber;
26
26
  // fetch mySegments revalidating data if cached
27
- this.mySegmentsSyncTask.execute(this.segmentList, true).then(function (result) {
27
+ this.mySegmentsSyncTask.execute(this.segmentsData, true).then(function (result) {
28
28
  if (result !== false) // Unlike `Splits|SegmentsUpdateWorker`, we cannot use `mySegmentsCache.getChangeNumber` since `/mySegments` endpoint doesn't provide this value.
29
29
  _this.currentChangeNumber = Math.max(_this.currentChangeNumber, currentMaxChangeNumber_1); // use `currentMaxChangeNumber`, in case that `this.maxChangeNumber` was updated during fetch.
30
30
  if (_this.handleNewEvent) {
@@ -40,15 +40,15 @@ var MySegmentsUpdateWorker = /** @class */ (function () {
40
40
  * Invoked by NotificationProcessor on MY_SEGMENTS_UPDATE event
41
41
  *
42
42
  * @param {number} changeNumber change number of the MY_SEGMENTS_UPDATE notification
43
- * @param {string[] | undefined} segmentList might be undefined
43
+ * @param {SegmentsData | undefined} segmentsData might be undefined
44
44
  */
45
- MySegmentsUpdateWorker.prototype.put = function (changeNumber, segmentList) {
45
+ MySegmentsUpdateWorker.prototype.put = function (changeNumber, segmentsData) {
46
46
  if (changeNumber <= this.currentChangeNumber || changeNumber <= this.maxChangeNumber)
47
47
  return;
48
48
  this.maxChangeNumber = changeNumber;
49
49
  this.handleNewEvent = true;
50
50
  this.backoff.reset();
51
- this.segmentList = segmentList;
51
+ this.segmentsData = segmentsData;
52
52
  if (this.mySegmentsSyncTask.isExecuting())
53
53
  return;
54
54
  this.__handleMySegmentsUpdateCall();
@@ -54,7 +54,8 @@ var SegmentsUpdateWorker = /** @class */ (function () {
54
54
  * @param {number} changeNumber change number of the SEGMENT_UPDATE notification
55
55
  * @param {string} segmentName segment name of the SEGMENT_UPDATE notification
56
56
  */
57
- SegmentsUpdateWorker.prototype.put = function (changeNumber, segmentName) {
57
+ SegmentsUpdateWorker.prototype.put = function (_a) {
58
+ var changeNumber = _a.changeNumber, segmentName = _a.segmentName;
58
59
  var currentChangeNumber = this.segmentsCache.getChangeNumber(segmentName);
59
60
  if (changeNumber <= currentChangeNumber || changeNumber <= this.maxChangeNumbers[segmentName])
60
61
  return;
@@ -46,7 +46,8 @@ var SplitsUpdateWorker = /** @class */ (function () {
46
46
  *
47
47
  * @param {number} changeNumber change number of the SPLIT_UPDATE notification
48
48
  */
49
- SplitsUpdateWorker.prototype.put = function (changeNumber) {
49
+ SplitsUpdateWorker.prototype.put = function (_a) {
50
+ var changeNumber = _a.changeNumber;
50
51
  var currentChangeNumber = this.splitsCache.getChangeNumber();
51
52
  if (changeNumber <= currentChangeNumber || changeNumber <= this.maxChangeNumber)
52
53
  return;
@@ -64,14 +65,15 @@ var SplitsUpdateWorker = /** @class */ (function () {
64
65
  * @param {string} splitName name of split to kill
65
66
  * @param {string} defaultTreatment default treatment value
66
67
  */
67
- SplitsUpdateWorker.prototype.killSplit = function (changeNumber, splitName, defaultTreatment) {
68
+ SplitsUpdateWorker.prototype.killSplit = function (_a) {
69
+ var changeNumber = _a.changeNumber, splitName = _a.splitName, defaultTreatment = _a.defaultTreatment;
68
70
  // @TODO handle retry due to errors in storage, once we allow the definition of custom async storages
69
71
  if (this.splitsCache.killLocally(splitName, defaultTreatment, changeNumber)) {
70
72
  // trigger an SDK_UPDATE if Split was killed locally
71
73
  this.splitsEventEmitter.emit(SDK_SPLITS_ARRIVED, true);
72
74
  }
73
75
  // queues the SplitChanges fetch (only if changeNumber is newer)
74
- this.put(changeNumber);
76
+ this.put({ changeNumber: changeNumber });
75
77
  };
76
78
  return SplitsUpdateWorker;
77
79
  }());
@@ -23,6 +23,7 @@ export var PUSH_SUBSYSTEM_UP = 'PUSH_SUBSYSTEM_UP';
23
23
  export var PUSH_SUBSYSTEM_DOWN = 'PUSH_SUBSYSTEM_DOWN';
24
24
  // Update-type push notifications, handled by NotificationProcessor
25
25
  export var MY_SEGMENTS_UPDATE = 'MY_SEGMENTS_UPDATE';
26
+ export var MY_SEGMENTS_UPDATE_V2 = 'MY_SEGMENTS_UPDATE_V2';
26
27
  export var SEGMENT_UPDATE = 'SEGMENT_UPDATE';
27
28
  export var SPLIT_KILL = 'SPLIT_KILL';
28
29
  export var SPLIT_UPDATE = 'SPLIT_UPDATE';
@@ -34,4 +35,5 @@ export var ControlType;
34
35
  ControlType["STREAMING_DISABLED"] = "STREAMING_DISABLED";
35
36
  ControlType["STREAMING_PAUSED"] = "STREAMING_PAUSED";
36
37
  ControlType["STREAMING_RESUMED"] = "STREAMING_RESUMED";
38
+ ControlType["STREAMING_RESET"] = "STREAMING_RESET";
37
39
  })(ControlType || (ControlType = {}));
@@ -0,0 +1,69 @@
1
+ import { algorithms } from '../../utils/decompress';
2
+ import { decodeFromBase64 } from '../../utils/base64';
3
+ var GZIP = 1;
4
+ var ZLIB = 2;
5
+ function Uint8ArrayToString(myUint8Arr) {
6
+ return String.fromCharCode.apply(null, myUint8Arr);
7
+ }
8
+ function StringToUint8Array(myString) {
9
+ var charCodes = myString.split('').map(function (e) { return e.charCodeAt(0); });
10
+ return new Uint8Array(charCodes);
11
+ }
12
+ /**
13
+ * Decode and decompress 'data' with 'compression' algorithm
14
+ *
15
+ * @param {string} data
16
+ * @param {number} compression 1 GZIP, 2 ZLIB
17
+ * @returns {Uint8Array}
18
+ * @throws if data string cannot be decoded, decompressed or the provided compression value is invalid (not 1 or 2)
19
+ */
20
+ function decompress(data, compression) {
21
+ var compressData = decodeFromBase64(data);
22
+ var binData = StringToUint8Array(compressData);
23
+ if (typeof algorithms === 'string')
24
+ throw new Error(algorithms);
25
+ if (compression === GZIP)
26
+ return algorithms.gunzipSync(binData);
27
+ if (compression === ZLIB)
28
+ return algorithms.unzlibSync(binData);
29
+ throw new Error("Invalid compression algorithm #" + compression);
30
+ }
31
+ /**
32
+ * Decode, decompress and parse the provided 'data' into a KeyList object
33
+ *
34
+ * @param {string} data
35
+ * @param {number} compression
36
+ * @returns {{a?: string[], r?: string[] }}
37
+ * @throws if data string cannot be decoded, decompressed or parsed
38
+ */
39
+ export function parseKeyList(data, compression) {
40
+ var binKeyList = decompress(data, compression);
41
+ var strKeyList = Uint8ArrayToString(binKeyList);
42
+ // replace numbers to strings, to avoid losing precision
43
+ return JSON.parse(strKeyList.replace(/\d+/g, '"$&"'));
44
+ }
45
+ /**
46
+ * Decode, decompress and parse the provided 'data' into a Bitmap object
47
+ *
48
+ * @param {string} data
49
+ * @param {number} compression
50
+ * @returns {Uint8Array}
51
+ * @throws if data string cannot be decoded or decompressed
52
+ */
53
+ export function parseBitmap(data, compression) {
54
+ return decompress(data, compression);
55
+ }
56
+ /**
57
+ * Check if the 'bitmap' bit at 'hash64hex' position is 1
58
+ *
59
+ * @param {Uint8Array} bitmap
60
+ * @param {string} hash64hex 16-chars string, representing a number in hexa
61
+ * @returns {boolean}
62
+ */
63
+ export function isInBitmap(bitmap, hash64hex) {
64
+ // using the lowest 32 bits as index, to avoid losing precision when converting to number
65
+ var index = parseInt(hash64hex.slice(8), 16) % (bitmap.length * 8);
66
+ var internal = Math.floor(index / 8);
67
+ var offset = index % 8;
68
+ return (bitmap[internal] & 1 << offset) > 0;
69
+ }