@splitsoftware/splitio-commons 3.1.1-rc.10 → 3.1.1-rc.12

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 (237) hide show
  1. package/CHANGES.txt +3 -0
  2. package/cjs/evaluator/condition/index.js +2 -2
  3. package/cjs/evaluator/fallbackTreatmentsCalculator/fallbackSanitizer/index.js +5 -8
  4. package/cjs/evaluator/index.js +81 -71
  5. package/cjs/listeners/browser.js +2 -1
  6. package/cjs/listeners/node.js +4 -4
  7. package/cjs/logger/constants.js +15 -20
  8. package/cjs/logger/messages/debug.js +5 -6
  9. package/cjs/logger/messages/error.js +3 -3
  10. package/cjs/logger/messages/info.js +3 -4
  11. package/cjs/logger/messages/warn.js +6 -7
  12. package/cjs/platform/browser.js +15 -0
  13. package/cjs/platform/getEventSource/browser.js +8 -0
  14. package/cjs/platform/getEventSource/eventsource.js +480 -0
  15. package/cjs/platform/getEventSource/node.js +26 -0
  16. package/cjs/platform/getFetch/browser.js +9 -0
  17. package/cjs/platform/getFetch/node.js +27 -0
  18. package/cjs/platform/getOptions/node.js +25 -0
  19. package/cjs/platform/node.js +17 -0
  20. package/cjs/presets/serverSide.js +2 -2
  21. package/cjs/readiness/constants.js +5 -4
  22. package/cjs/readiness/readinessManager.js +23 -23
  23. package/cjs/readiness/sdkReadinessManager.js +1 -17
  24. package/cjs/sdkClient/client.js +24 -50
  25. package/cjs/sdkClient/clientInputValidation.js +6 -17
  26. package/cjs/sdkClient/sdkClient.js +3 -60
  27. package/cjs/sdkClient/sdkLifecycle.js +74 -0
  28. package/cjs/sdkClient/trackMethod.js +56 -0
  29. package/cjs/sdkFactory/index.js +11 -15
  30. package/cjs/sdkManager/index.js +5 -5
  31. package/cjs/services/authProvider.js +80 -0
  32. package/cjs/services/decorateHeaders.js +2 -1
  33. package/cjs/{sync/streaming/AuthClient/index.js → services/fetchAuth.js} +15 -16
  34. package/cjs/services/secureSplitHttpClient.js +36 -0
  35. package/cjs/services/serviceApi.js +147 -0
  36. package/cjs/services/splitApi.js +24 -10
  37. package/cjs/services/splitHttpClient.js +3 -5
  38. package/cjs/storages/AbstractDefinitionsCacheAsync.js +51 -0
  39. package/cjs/storages/AbstractDefinitionsCacheSync.js +76 -0
  40. package/cjs/storages/KeyBuilder.js +6 -6
  41. package/cjs/storages/KeyBuilderCS.js +5 -5
  42. package/cjs/storages/KeyBuilderSS.js +2 -2
  43. package/cjs/storages/getRolloutPlan.js +3 -3
  44. package/cjs/storages/inLocalStorage/DefinitionsCacheInLocal.js +195 -0
  45. package/cjs/storages/inLocalStorage/MySegmentsCacheInLocal.js +1 -2
  46. package/cjs/storages/inLocalStorage/RBSegmentsCacheInLocal.js +12 -11
  47. package/cjs/storages/inLocalStorage/index.js +6 -6
  48. package/cjs/storages/inLocalStorage/validateCache.js +3 -3
  49. package/cjs/storages/inMemory/DefinitionsCacheInMemory.js +122 -0
  50. package/cjs/storages/inMemory/InMemoryStorage.js +4 -4
  51. package/cjs/storages/inMemory/InMemoryStorageCS.js +5 -5
  52. package/cjs/storages/inMemory/RBSegmentsCacheInMemory.js +7 -6
  53. package/cjs/storages/inMemory/SegmentsCacheInMemory.js +1 -1
  54. package/cjs/storages/inMemory/TelemetryCacheInMemory.js +5 -5
  55. package/cjs/storages/inRedis/{SplitsCacheInRedis.js → DefinitionsCacheInRedis.js} +79 -77
  56. package/cjs/storages/inRedis/RBSegmentsCacheInRedis.js +4 -2
  57. package/cjs/storages/inRedis/index.js +2 -2
  58. package/cjs/storages/pluggable/DefinitionsCachePluggable.js +214 -0
  59. package/cjs/storages/pluggable/RBSegmentsCachePluggable.js +4 -2
  60. package/cjs/storages/pluggable/index.js +2 -2
  61. package/cjs/storages/setRolloutPlan.js +4 -4
  62. package/cjs/storages/utils.js +1 -0
  63. package/cjs/sync/offline/syncTasks/fromObjectSyncTask.js +5 -5
  64. package/cjs/sync/polling/fetchers/splitChangesFetcher.js +24 -15
  65. package/cjs/sync/polling/pollingManagerCS.js +86 -81
  66. package/cjs/sync/polling/pollingManagerSS.js +44 -36
  67. package/cjs/sync/polling/syncTasks/definitionsSyncTask.js +13 -0
  68. package/cjs/sync/polling/syncTasks/segmentsSyncTask.js +2 -3
  69. package/cjs/sync/polling/updaters/definitionChangesUpdater.js +207 -0
  70. package/cjs/sync/polling/updaters/mySegmentsUpdater.js +3 -3
  71. package/cjs/sync/polling/updaters/segmentChangesUpdater.js +6 -6
  72. package/cjs/sync/streaming/SSEHandler/NotificationKeeper.js +1 -1
  73. package/cjs/sync/streaming/SSEHandler/index.js +2 -1
  74. package/cjs/sync/streaming/UpdateWorkers/{SplitsUpdateWorker.js → DefinitionsUpdateWorker.js} +19 -20
  75. package/cjs/sync/streaming/constants.js +4 -3
  76. package/cjs/sync/streaming/parseUtils.js +14 -14
  77. package/cjs/sync/streaming/pushManager.js +22 -26
  78. package/cjs/sync/submitters/eventsSubmitter.js +1 -1
  79. package/cjs/sync/submitters/impressionCountsSubmitter.js +1 -1
  80. package/cjs/sync/submitters/impressionsSubmitter.js +5 -4
  81. package/cjs/sync/submitters/telemetrySubmitter.js +3 -4
  82. package/cjs/sync/submitters/uniqueKeysSubmitter.js +1 -1
  83. package/cjs/sync/syncManagerOnline.js +5 -5
  84. package/cjs/utils/Backoff.js +35 -3
  85. package/cjs/utils/EventEmitter.js +391 -0
  86. package/cjs/utils/filter/bloomFilter.js +37 -0
  87. package/cjs/utils/inputValidation/{split.js → definition.js} +10 -10
  88. package/cjs/utils/inputValidation/{splitExistence.js → definitionExistence.js} +6 -6
  89. package/cjs/utils/inputValidation/definitions.js +25 -0
  90. package/cjs/utils/inputValidation/index.js +7 -7
  91. package/cjs/utils/inputValidation/isOperational.js +4 -4
  92. package/cjs/utils/inputValidation/target.js +22 -0
  93. package/cjs/utils/labels/index.js +3 -3
  94. package/cjs/utils/settingsValidation/index.js +2 -0
  95. package/cjs/utils/settingsValidation/splitFilters.js +3 -3
  96. package/cjs/utils/settingsValidation/url.js +6 -2
  97. package/esm/evaluator/condition/index.js +2 -2
  98. package/esm/evaluator/fallbackTreatmentsCalculator/fallbackSanitizer/index.js +5 -8
  99. package/esm/evaluator/index.js +80 -71
  100. package/esm/listeners/browser.js +2 -1
  101. package/esm/listeners/node.js +4 -4
  102. package/esm/logger/constants.js +12 -17
  103. package/esm/logger/messages/debug.js +5 -6
  104. package/esm/logger/messages/error.js +3 -3
  105. package/esm/logger/messages/info.js +3 -4
  106. package/esm/logger/messages/warn.js +6 -7
  107. package/esm/platform/browser.js +12 -0
  108. package/esm/platform/getEventSource/browser.js +4 -0
  109. package/esm/platform/getEventSource/eventsource.js +480 -0
  110. package/esm/platform/getEventSource/node.js +20 -0
  111. package/esm/platform/getFetch/browser.js +5 -0
  112. package/esm/platform/getFetch/node.js +22 -0
  113. package/esm/platform/getOptions/node.js +20 -0
  114. package/esm/platform/node.js +14 -0
  115. package/esm/presets/serverSide.js +2 -2
  116. package/esm/readiness/constants.js +4 -3
  117. package/esm/readiness/readinessManager.js +24 -24
  118. package/esm/readiness/sdkReadinessManager.js +2 -18
  119. package/esm/sdkClient/client.js +23 -50
  120. package/esm/sdkClient/clientInputValidation.js +8 -19
  121. package/esm/sdkClient/sdkClient.js +3 -60
  122. package/esm/sdkClient/sdkLifecycle.js +70 -0
  123. package/esm/sdkClient/trackMethod.js +52 -0
  124. package/esm/sdkFactory/index.js +12 -16
  125. package/esm/sdkManager/index.js +6 -6
  126. package/esm/services/authProvider.js +76 -0
  127. package/esm/services/decorateHeaders.js +2 -1
  128. package/esm/{sync/streaming/AuthClient/index.js → services/fetchAuth.js} +13 -13
  129. package/esm/services/secureSplitHttpClient.js +32 -0
  130. package/esm/services/serviceApi.js +143 -0
  131. package/esm/services/splitApi.js +24 -10
  132. package/esm/services/splitHttpClient.js +3 -5
  133. package/esm/storages/AbstractDefinitionsCacheAsync.js +48 -0
  134. package/esm/storages/AbstractDefinitionsCacheSync.js +71 -0
  135. package/esm/storages/KeyBuilder.js +6 -6
  136. package/esm/storages/KeyBuilderCS.js +5 -5
  137. package/esm/storages/KeyBuilderSS.js +2 -2
  138. package/esm/storages/getRolloutPlan.js +3 -3
  139. package/esm/storages/inLocalStorage/DefinitionsCacheInLocal.js +192 -0
  140. package/esm/storages/inLocalStorage/MySegmentsCacheInLocal.js +1 -2
  141. package/esm/storages/inLocalStorage/RBSegmentsCacheInLocal.js +9 -8
  142. package/esm/storages/inLocalStorage/index.js +6 -6
  143. package/esm/storages/inLocalStorage/validateCache.js +3 -3
  144. package/esm/storages/inMemory/DefinitionsCacheInMemory.js +119 -0
  145. package/esm/storages/inMemory/InMemoryStorage.js +4 -4
  146. package/esm/storages/inMemory/InMemoryStorageCS.js +5 -5
  147. package/esm/storages/inMemory/RBSegmentsCacheInMemory.js +4 -3
  148. package/esm/storages/inMemory/SegmentsCacheInMemory.js +1 -1
  149. package/esm/storages/inMemory/TelemetryCacheInMemory.js +5 -5
  150. package/esm/storages/inRedis/{SplitsCacheInRedis.js → DefinitionsCacheInRedis.js} +78 -76
  151. package/esm/storages/inRedis/RBSegmentsCacheInRedis.js +4 -2
  152. package/esm/storages/inRedis/index.js +2 -2
  153. package/esm/storages/pluggable/DefinitionsCachePluggable.js +211 -0
  154. package/esm/storages/pluggable/RBSegmentsCachePluggable.js +4 -2
  155. package/esm/storages/pluggable/index.js +2 -2
  156. package/esm/storages/setRolloutPlan.js +4 -4
  157. package/esm/storages/utils.js +1 -0
  158. package/esm/sync/offline/syncTasks/fromObjectSyncTask.js +6 -6
  159. package/esm/sync/polling/fetchers/splitChangesFetcher.js +25 -16
  160. package/esm/sync/polling/pollingManagerCS.js +87 -82
  161. package/esm/sync/polling/pollingManagerSS.js +44 -36
  162. package/esm/sync/polling/syncTasks/definitionsSyncTask.js +9 -0
  163. package/esm/sync/polling/syncTasks/segmentsSyncTask.js +2 -3
  164. package/esm/sync/polling/updaters/definitionChangesUpdater.js +201 -0
  165. package/esm/sync/polling/updaters/mySegmentsUpdater.js +3 -3
  166. package/esm/sync/polling/updaters/segmentChangesUpdater.js +7 -7
  167. package/esm/sync/streaming/SSEHandler/NotificationKeeper.js +2 -2
  168. package/esm/sync/streaming/SSEHandler/index.js +3 -2
  169. package/esm/sync/streaming/UpdateWorkers/{SplitsUpdateWorker.js → DefinitionsUpdateWorker.js} +19 -20
  170. package/esm/sync/streaming/constants.js +3 -2
  171. package/esm/sync/streaming/parseUtils.js +11 -11
  172. package/esm/sync/streaming/pushManager.js +24 -28
  173. package/esm/sync/submitters/eventsSubmitter.js +1 -1
  174. package/esm/sync/submitters/impressionCountsSubmitter.js +1 -1
  175. package/esm/sync/submitters/impressionsSubmitter.js +5 -4
  176. package/esm/sync/submitters/telemetrySubmitter.js +3 -4
  177. package/esm/sync/submitters/uniqueKeysSubmitter.js +1 -1
  178. package/esm/sync/syncManagerOnline.js +4 -4
  179. package/esm/utils/Backoff.js +35 -3
  180. package/esm/utils/EventEmitter.js +387 -0
  181. package/esm/utils/filter/bloomFilter.js +33 -0
  182. package/esm/utils/inputValidation/{split.js → definition.js} +8 -8
  183. package/esm/utils/inputValidation/definitionExistence.js +15 -0
  184. package/esm/utils/inputValidation/definitions.js +21 -0
  185. package/esm/utils/inputValidation/index.js +3 -3
  186. package/esm/utils/inputValidation/isOperational.js +4 -4
  187. package/esm/utils/inputValidation/target.js +18 -0
  188. package/esm/utils/labels/index.js +2 -2
  189. package/esm/utils/settingsValidation/index.js +2 -0
  190. package/esm/utils/settingsValidation/splitFilters.js +3 -3
  191. package/esm/utils/settingsValidation/url.js +6 -2
  192. package/package.json +1 -1
  193. package/src/dtos/types.ts +4 -4
  194. package/src/services/authProvider.ts +2 -2
  195. package/src/{sync/streaming/AuthClient/index.ts → services/fetchAuth.ts} +3 -4
  196. package/src/services/splitApi.ts +1 -1
  197. package/src/services/types.ts +21 -4
  198. package/src/storages/AbstractDefinitionsCacheAsync.ts +3 -3
  199. package/src/storages/AbstractDefinitionsCacheSync.ts +2 -2
  200. package/src/storages/inLocalStorage/DefinitionsCacheInLocal.ts +2 -2
  201. package/src/storages/inLocalStorage/RBSegmentsCacheInLocal.ts +3 -3
  202. package/src/storages/inMemory/DefinitionsCacheInMemory.ts +2 -2
  203. package/src/storages/inMemory/RBSegmentsCacheInMemory.ts +2 -2
  204. package/src/storages/inRedis/DefinitionsCacheInRedis.ts +6 -4
  205. package/src/storages/inRedis/RBSegmentsCacheInRedis.ts +7 -5
  206. package/src/storages/pluggable/DefinitionsCachePluggable.ts +4 -2
  207. package/src/storages/pluggable/RBSegmentsCachePluggable.ts +5 -3
  208. package/src/storages/types.ts +6 -6
  209. package/src/sync/polling/fetchers/splitChangesFetcher.ts +5 -5
  210. package/src/sync/polling/types.ts +22 -1
  211. package/src/sync/polling/updaters/definitionChangesUpdater.ts +26 -20
  212. package/src/sync/streaming/SSEClient/index.ts +1 -1
  213. package/src/sync/streaming/SSEClient/types.ts +1 -1
  214. package/src/sync/streaming/UpdateWorkers/DefinitionsUpdateWorker.ts +15 -11
  215. package/src/sync/streaming/UpdateWorkers/types.ts +6 -0
  216. package/src/sync/streaming/parseUtils.ts +3 -4
  217. package/src/sync/streaming/pushManager.ts +4 -3
  218. package/cjs/storages/AbstractSplitsCacheAsync.js +0 -51
  219. package/cjs/storages/AbstractSplitsCacheSync.js +0 -76
  220. package/cjs/storages/inLocalStorage/SplitsCacheInLocal.js +0 -194
  221. package/cjs/storages/inMemory/SplitsCacheInMemory.js +0 -121
  222. package/cjs/storages/pluggable/SplitsCachePluggable.js +0 -212
  223. package/cjs/sync/polling/syncTasks/splitsSyncTask.js +0 -13
  224. package/cjs/sync/polling/updaters/splitChangesUpdater.js +0 -200
  225. package/cjs/sync/streaming/AuthClient/types.js +0 -2
  226. package/cjs/utils/inputValidation/splits.js +0 -25
  227. package/esm/storages/AbstractSplitsCacheAsync.js +0 -48
  228. package/esm/storages/AbstractSplitsCacheSync.js +0 -71
  229. package/esm/storages/inLocalStorage/SplitsCacheInLocal.js +0 -191
  230. package/esm/storages/inMemory/SplitsCacheInMemory.js +0 -118
  231. package/esm/storages/pluggable/SplitsCachePluggable.js +0 -209
  232. package/esm/sync/polling/syncTasks/splitsSyncTask.js +0 -9
  233. package/esm/sync/polling/updaters/splitChangesUpdater.js +0 -194
  234. package/esm/sync/streaming/AuthClient/types.js +0 -1
  235. package/esm/utils/inputValidation/splitExistence.js +0 -15
  236. package/esm/utils/inputValidation/splits.js +0 -21
  237. package/src/sync/streaming/AuthClient/types.ts +0 -19
@@ -1,13 +1,13 @@
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, SDK_SPLITS_CACHE_LOADED, FLAGS_UPDATE, SEGMENTS_UPDATE } from '../../../readiness/constants';
4
+ import { SDK_DEFINITIONS_ARRIVED, SDK_SEGMENTS_ARRIVED, SDK_DEFINITIONS_CACHE_LOADED, FLAGS_UPDATE, SEGMENTS_UPDATE } 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, splitsCache = storage.splits;
10
+ var log = settings.log, definitions = storage.definitions;
11
11
  var startingUp = true;
12
12
  return function objectUpdater() {
13
13
  var splits = [];
@@ -36,16 +36,16 @@ export function fromObjectUpdaterFactory(splitsParser, storage, readiness, setti
36
36
  });
37
37
  });
38
38
  return Promise.all([
39
- splitsCache.clear(),
40
- splitsCache.update(splits, [], Date.now())
39
+ definitions.clear(),
40
+ definitions.update(splits, [], Date.now())
41
41
  ]).then(function () {
42
- readiness.splits.emit(SDK_SPLITS_ARRIVED, { type: FLAGS_UPDATE, names: [] });
42
+ readiness.definitions.emit(SDK_DEFINITIONS_ARRIVED, { type: FLAGS_UPDATE, names: [] });
43
43
  if (startingUp) {
44
44
  startingUp = false;
45
45
  Promise.resolve(storage.validateCache ? storage.validateCache() : { initialCacheLoad: true /* Fallback: assume initial load when validateCache doesn't exist */ }).then(function (cacheMetadata) {
46
46
  // Emits SDK_READY_FROM_CACHE
47
47
  if (!cacheMetadata.initialCacheLoad) {
48
- readiness.splits.emit(SDK_SPLITS_CACHE_LOADED, cacheMetadata);
48
+ readiness.definitions.emit(SDK_DEFINITIONS_CACHE_LOADED, cacheMetadata);
49
49
  }
50
50
  // Emits SDK_READY
51
51
  readiness.segments.emit(SDK_SEGMENTS_ARRIVED, { type: SEGMENTS_UPDATE, names: [] });
@@ -1,22 +1,31 @@
1
1
  import { FLAG_SPEC_VERSION } from '../../../utils/constants';
2
2
  import { base } from '../../../utils/settingsValidation';
3
- import { LOG_PREFIX_SYNC_SPLITS } from '../../../logger/constants';
3
+ import { LOG_PREFIX_SYNC } from '../../../logger/constants';
4
4
  import { checkIfServerSide } from '../../../utils/key';
5
5
  var PROXY_CHECK_INTERVAL_MILLIS_CS = 60 * 60 * 1000; // 1 hour in Client Side
6
6
  var PROXY_CHECK_INTERVAL_MILLIS_SS = 24 * PROXY_CHECK_INTERVAL_MILLIS_CS; // 24 hours in Server Side
7
7
  function sdkEndpointOverridden(settings) {
8
8
  return settings.urls.sdk !== base.urls.sdk;
9
9
  }
10
+ function isSplitChangesLegacyResponse(data) {
11
+ return data.splits != null;
12
+ }
13
+ function partitionByStatus(items, till, since) {
14
+ var updated = [], removed = [];
15
+ items.forEach(function (item) { return item.status === 'ARCHIVED' ? removed.push(item.name) : updated.push(item); });
16
+ return { updated: updated, removed: removed, till: till, since: since !== null && since !== void 0 ? since : undefined };
17
+ }
10
18
  /**
11
19
  * Factory of SplitChanges fetcher.
12
20
  * SplitChanges fetcher is a wrapper around `splitChanges` API service that parses the response and handle errors.
13
21
  */
14
22
  // @TODO breaking: drop support for Split Proxy below v5.10.0 and simplify the implementation
15
- export function splitChangesFetcherFactory(fetchSplitChanges, settings, storage) {
23
+ export function splitChangesFetcherFactory(params) {
24
+ var fetchSplitChanges = params.serviceApi.fetchSplitChanges, settings = params.settings, storage = params.storage;
16
25
  var log = settings.log;
17
26
  var PROXY_CHECK_INTERVAL_MILLIS = checkIfServerSide(settings) ? PROXY_CHECK_INTERVAL_MILLIS_SS : PROXY_CHECK_INTERVAL_MILLIS_CS;
18
27
  var lastProxyCheckTimestamp;
19
- return function splitChangesFetcher(since, noCache, till, rbSince,
28
+ function splitChangesFetcher(since, noCache, till, rbSince,
20
29
  // Optional decorator for `fetchSplitChanges` promise, such as timeout or time tracker
21
30
  decorator) {
22
31
  // Recheck proxy
@@ -27,7 +36,7 @@ export function splitChangesFetcherFactory(fetchSplitChanges, settings, storage)
27
36
  .catch(function (err) {
28
37
  // Handle proxy error with spec 1.3
29
38
  if ((!err.statusCode || err.statusCode === 400) && sdkEndpointOverridden(settings) && settings.sync.flagSpecVersion === FLAG_SPEC_VERSION) {
30
- log.error(LOG_PREFIX_SYNC_SPLITS + 'Proxy error detected. Retrying with spec 1.2. If you are using Split Proxy, please upgrade to latest version');
39
+ log.error(LOG_PREFIX_SYNC + 'Proxy error detected. Retrying with spec 1.2. If you are using Split Proxy, please upgrade to latest version');
31
40
  lastProxyCheckTimestamp = Date.now();
32
41
  settings.sync.flagSpecVersion = '1.2'; // fallback to 1.2 spec
33
42
  return fetchSplitChanges(since, noCache, till); // retry request without rbSince
@@ -40,26 +49,26 @@ export function splitChangesFetcherFactory(fetchSplitChanges, settings, storage)
40
49
  .then(function (resp) { return resp.json(); })
41
50
  .then(function (data) {
42
51
  // Using flag spec version 1.2 or below
43
- if (data.splits) {
44
- return {
45
- ff: {
46
- d: data.splits,
47
- s: data.since,
48
- t: data.till
49
- }
50
- };
52
+ if (isSplitChangesLegacyResponse(data)) {
53
+ return { d: partitionByStatus(data.splits || [], data.till, data.since) };
51
54
  }
52
55
  // Proxy recovery
53
56
  if (lastProxyCheckTimestamp) {
54
- log.info(LOG_PREFIX_SYNC_SPLITS + 'Proxy error recovered');
57
+ log.info(LOG_PREFIX_SYNC + 'Proxy error recovered');
55
58
  lastProxyCheckTimestamp = undefined;
56
59
  return splitChangesFetcher(-1, undefined, undefined, -1)
57
60
  .then(function (splitChangesResponse) {
58
- return Promise.all([storage.splits.clear(), storage.rbSegments.clear()])
61
+ return Promise.all([storage.definitions.clear(), storage.rbSegments.clear()])
59
62
  .then(function () { return splitChangesResponse; });
60
63
  });
61
64
  }
62
- return data;
65
+ var ff = data.ff, rbs = data.rbs;
66
+ return {
67
+ d: (ff === null || ff === void 0 ? void 0 : ff.d) ? partitionByStatus(ff.d, ff.t, ff.s) : undefined,
68
+ rbs: (rbs === null || rbs === void 0 ? void 0 : rbs.d) ? partitionByStatus(rbs.d, rbs.t, rbs.s) : undefined,
69
+ };
63
70
  });
64
- };
71
+ }
72
+ splitChangesFetcher.type = 'feature flags';
73
+ return splitChangesFetcher;
65
74
  }
@@ -1,96 +1,101 @@
1
1
  import { forOwn } from '../../utils/lang';
2
2
  import { mySegmentsSyncTaskFactory } from './syncTasks/mySegmentsSyncTask';
3
- import { splitsSyncTaskFactory } from './syncTasks/splitsSyncTask';
3
+ import { definitionsSyncTaskFactory } from './syncTasks/definitionsSyncTask';
4
4
  import { getMatching } from '../../utils/key';
5
- import { SDK_SPLITS_ARRIVED, SDK_SEGMENTS_ARRIVED } from '../../readiness/constants';
5
+ import { SDK_DEFINITIONS_ARRIVED, SDK_SEGMENTS_ARRIVED } from '../../readiness/constants';
6
6
  import { POLLING_SMART_PAUSING, POLLING_START, POLLING_STOP } from '../../logger/constants';
7
- import { usesSegmentsSync } from '../../storages/AbstractSplitsCacheSync';
7
+ import { usesSegmentsSync } from '../../storages/AbstractDefinitionsCacheSync';
8
+ import { splitChangesFetcherFactory } from './fetchers/splitChangesFetcher';
8
9
  /**
9
10
  * Expose start / stop mechanism for polling data from services.
10
11
  * For client-side API with multiple clients.
11
12
  */
12
- export function pollingManagerCSFactory(params) {
13
- var splitApi = params.splitApi, storage = params.storage, readiness = params.readiness, settings = params.settings;
14
- var log = settings.log;
15
- var splitsSyncTask = splitsSyncTaskFactory(splitApi.fetchSplitChanges, storage, readiness, settings, true);
16
- // Map of matching keys to their corresponding MySegmentsSyncTask.
17
- var mySegmentsSyncTasks = {};
18
- var matchingKey = getMatching(settings.core.key);
19
- var mySegmentsSyncTask = add(matchingKey, readiness, storage);
20
- function startMySegmentsSyncTasks() {
21
- forOwn(mySegmentsSyncTasks, function (mySegmentsSyncTask) {
22
- mySegmentsSyncTask.start();
23
- });
24
- }
25
- function stopMySegmentsSyncTasks() {
26
- forOwn(mySegmentsSyncTasks, function (mySegmentsSyncTask) {
27
- if (mySegmentsSyncTask.isRunning())
28
- mySegmentsSyncTask.stop();
29
- });
30
- }
31
- // smart pausing
32
- readiness.splits.on(SDK_SPLITS_ARRIVED, function () {
33
- if (!splitsSyncTask.isRunning())
34
- return; // noop if not doing polling
35
- var usingSegments = usesSegmentsSync(storage);
36
- if (usingSegments !== mySegmentsSyncTask.isRunning()) {
37
- log.info(POLLING_SMART_PAUSING, [usingSegments ? 'ON' : 'OFF']);
38
- if (usingSegments) {
39
- startMySegmentsSyncTasks();
40
- }
41
- else {
42
- stopMySegmentsSyncTasks();
43
- }
44
- }
45
- });
46
- function add(matchingKey, readiness, storage) {
47
- var mySegmentsSyncTask = mySegmentsSyncTaskFactory(splitApi.fetchMemberships, storage, readiness, settings, matchingKey);
48
- // smart ready
49
- function smartReady(metadata) {
50
- if (!readiness.isReady() && !usesSegmentsSync(storage))
51
- readiness.segments.emit(SDK_SEGMENTS_ARRIVED, metadata);
13
+ export function pollingManagerCSFactory(definitionFetcherFactory) {
14
+ if (definitionFetcherFactory === void 0) { definitionFetcherFactory = splitChangesFetcherFactory; }
15
+ return function (params) {
16
+ var serviceApi = params.serviceApi, storage = params.storage, readiness = params.readiness, settings = params.settings;
17
+ var log = settings.log;
18
+ var definitionChangesFetcher = definitionFetcherFactory(params);
19
+ var definitionsSyncTask = definitionsSyncTaskFactory(definitionChangesFetcher, storage, readiness, settings);
20
+ // Map of matching keys to their corresponding MySegmentsSyncTask.
21
+ var mySegmentsSyncTasks = {};
22
+ var matchingKey = getMatching(settings.core.key);
23
+ var mySegmentsSyncTask = add(matchingKey, readiness, storage);
24
+ function startMySegmentsSyncTasks() {
25
+ forOwn(mySegmentsSyncTasks, function (mySegmentsSyncTask) {
26
+ mySegmentsSyncTask.start();
27
+ });
52
28
  }
53
- if (!usesSegmentsSync(storage))
54
- setTimeout(smartReady, 0);
55
- else
56
- readiness.splits.once(SDK_SPLITS_ARRIVED, smartReady);
57
- mySegmentsSyncTasks[matchingKey] = mySegmentsSyncTask;
58
- return mySegmentsSyncTask;
59
- }
60
- return {
61
- splitsSyncTask: splitsSyncTask,
62
- segmentsSyncTask: mySegmentsSyncTask,
63
- // Start periodic fetching (polling)
64
- start: function () {
65
- log.info(POLLING_START);
66
- splitsSyncTask.start();
67
- if (usesSegmentsSync(storage))
68
- startMySegmentsSyncTasks();
69
- },
70
- // Stop periodic fetching (polling)
71
- stop: function () {
72
- log.info(POLLING_STOP);
73
- if (splitsSyncTask.isRunning())
74
- splitsSyncTask.stop();
75
- stopMySegmentsSyncTasks();
76
- },
77
- // Used by SyncManager to know if running in polling mode.
78
- isRunning: splitsSyncTask.isRunning,
79
- // fetch splits and segments
80
- syncAll: function () {
81
- var promises = [splitsSyncTask.execute()];
29
+ function stopMySegmentsSyncTasks() {
82
30
  forOwn(mySegmentsSyncTasks, function (mySegmentsSyncTask) {
83
- promises.push(mySegmentsSyncTask.execute());
31
+ if (mySegmentsSyncTask.isRunning())
32
+ mySegmentsSyncTask.stop();
84
33
  });
85
- return Promise.all(promises);
86
- },
87
- // Support for handling mySegments sync of multiple clients
88
- add: add,
89
- remove: function (matchingKey) {
90
- delete mySegmentsSyncTasks[matchingKey];
91
- },
92
- get: function (matchingKey) {
93
- return mySegmentsSyncTasks[matchingKey];
94
34
  }
35
+ // smart pausing
36
+ readiness.definitions.on(SDK_DEFINITIONS_ARRIVED, function () {
37
+ if (!definitionsSyncTask.isRunning())
38
+ return; // noop if not doing polling
39
+ var usingSegments = usesSegmentsSync(storage);
40
+ if (usingSegments !== mySegmentsSyncTask.isRunning()) {
41
+ log.info(POLLING_SMART_PAUSING, [usingSegments ? 'ON' : 'OFF']);
42
+ if (usingSegments) {
43
+ startMySegmentsSyncTasks();
44
+ }
45
+ else {
46
+ stopMySegmentsSyncTasks();
47
+ }
48
+ }
49
+ });
50
+ function add(matchingKey, readiness, storage) {
51
+ var mySegmentsSyncTask = mySegmentsSyncTaskFactory(serviceApi.fetchMemberships, storage, readiness, settings, matchingKey);
52
+ // smart ready
53
+ function smartReady(metadata) {
54
+ if (!readiness.isReady() && !usesSegmentsSync(storage))
55
+ readiness.segments.emit(SDK_SEGMENTS_ARRIVED, metadata);
56
+ }
57
+ if (!usesSegmentsSync(storage))
58
+ setTimeout(smartReady, 0);
59
+ else
60
+ readiness.definitions.once(SDK_DEFINITIONS_ARRIVED, smartReady);
61
+ mySegmentsSyncTasks[matchingKey] = mySegmentsSyncTask;
62
+ return mySegmentsSyncTask;
63
+ }
64
+ return {
65
+ definitionsSyncTask: definitionsSyncTask,
66
+ segmentsSyncTask: mySegmentsSyncTask,
67
+ // Start periodic fetching (polling)
68
+ start: function () {
69
+ log.info(POLLING_START);
70
+ definitionsSyncTask.start();
71
+ if (usesSegmentsSync(storage))
72
+ startMySegmentsSyncTasks();
73
+ },
74
+ // Stop periodic fetching (polling)
75
+ stop: function () {
76
+ log.info(POLLING_STOP);
77
+ if (definitionsSyncTask.isRunning())
78
+ definitionsSyncTask.stop();
79
+ stopMySegmentsSyncTasks();
80
+ },
81
+ // Used by SyncManager to know if running in polling mode.
82
+ isRunning: definitionsSyncTask.isRunning,
83
+ // fetch definitions and segments
84
+ syncAll: function () {
85
+ var promises = [definitionsSyncTask.execute()];
86
+ forOwn(mySegmentsSyncTasks, function (mySegmentsSyncTask) {
87
+ promises.push(mySegmentsSyncTask.execute());
88
+ });
89
+ return Promise.all(promises);
90
+ },
91
+ // Support for handling mySegments sync of multiple clients
92
+ add: add,
93
+ remove: function (matchingKey) {
94
+ delete mySegmentsSyncTasks[matchingKey];
95
+ },
96
+ get: function (matchingKey) {
97
+ return mySegmentsSyncTasks[matchingKey];
98
+ }
99
+ };
95
100
  };
96
101
  }
@@ -1,45 +1,53 @@
1
- import { splitsSyncTaskFactory } from './syncTasks/splitsSyncTask';
1
+ import { definitionsSyncTaskFactory } from './syncTasks/definitionsSyncTask';
2
2
  import { segmentsSyncTaskFactory } from './syncTasks/segmentsSyncTask';
3
3
  import { POLLING_START, POLLING_STOP, LOG_PREFIX_SYNC_POLLING } from '../../logger/constants';
4
+ import { segmentChangesFetcherFactory } from './fetchers/segmentChangesFetcher';
5
+ import { splitChangesFetcherFactory } from './fetchers/splitChangesFetcher';
4
6
  /**
5
7
  * Expose start / stop mechanism for pulling data from services.
6
8
  */
7
- export function pollingManagerSSFactory(params) {
8
- var splitApi = params.splitApi, storage = params.storage, readiness = params.readiness, settings = params.settings;
9
- var log = settings.log;
10
- var splitsSyncTask = splitsSyncTaskFactory(splitApi.fetchSplitChanges, storage, readiness, settings);
11
- var segmentsSyncTask = segmentsSyncTaskFactory(splitApi.fetchSegmentChanges, storage, readiness, settings);
12
- return {
13
- splitsSyncTask: splitsSyncTask,
14
- segmentsSyncTask: segmentsSyncTask,
15
- // Start periodic fetching (polling)
16
- start: function () {
17
- log.info(POLLING_START);
18
- log.debug(LOG_PREFIX_SYNC_POLLING + "Splits will be refreshed each ".concat(settings.scheduler.featuresRefreshRate, " millis"));
19
- log.debug(LOG_PREFIX_SYNC_POLLING + "Segments will be refreshed each ".concat(settings.scheduler.segmentsRefreshRate, " millis"));
20
- var startingUp = splitsSyncTask.start();
21
- if (startingUp) {
22
- startingUp.then(function () {
23
- if (splitsSyncTask.isRunning())
24
- segmentsSyncTask.start();
9
+ export function pollingManagerSSFactory(definitionFetcherFactory, segmentFetcherFactory) {
10
+ if (definitionFetcherFactory === void 0) { definitionFetcherFactory = splitChangesFetcherFactory; }
11
+ if (segmentFetcherFactory === void 0) { segmentFetcherFactory = function (params) { return segmentChangesFetcherFactory(params.serviceApi.fetchSegmentChanges); }; }
12
+ return function (params) {
13
+ var storage = params.storage, readiness = params.readiness, settings = params.settings;
14
+ var log = settings.log;
15
+ var definitionChangesFetcher = definitionFetcherFactory(params);
16
+ var segmentChangesFetcher = segmentFetcherFactory(params);
17
+ var segmentsSyncTask = segmentsSyncTaskFactory(segmentChangesFetcher, storage, readiness, settings);
18
+ var definitionsSyncTask = definitionsSyncTaskFactory(definitionChangesFetcher, storage, readiness, settings, segmentsSyncTask);
19
+ return {
20
+ definitionsSyncTask: definitionsSyncTask,
21
+ segmentsSyncTask: segmentsSyncTask,
22
+ // Start periodic fetching (polling)
23
+ start: function () {
24
+ log.info(POLLING_START);
25
+ log.debug(LOG_PREFIX_SYNC_POLLING + "".concat(definitionChangesFetcher.type, " will be refreshed each ").concat(settings.scheduler.featuresRefreshRate, " millis"));
26
+ log.debug(LOG_PREFIX_SYNC_POLLING + "segments will be refreshed each ".concat(settings.scheduler.segmentsRefreshRate, " millis"));
27
+ var startingUp = definitionsSyncTask.start();
28
+ if (startingUp) {
29
+ startingUp.then(function () {
30
+ if (definitionsSyncTask.isRunning())
31
+ segmentsSyncTask.start();
32
+ });
33
+ }
34
+ },
35
+ // Stop periodic fetching (polling)
36
+ stop: function () {
37
+ log.info(POLLING_STOP);
38
+ if (definitionsSyncTask.isRunning())
39
+ definitionsSyncTask.stop();
40
+ if (segmentsSyncTask.isRunning())
41
+ segmentsSyncTask.stop();
42
+ },
43
+ // Used by SyncManager to know if running in polling mode.
44
+ isRunning: definitionsSyncTask.isRunning,
45
+ syncAll: function () {
46
+ // fetch definitions and segments. There is no need to catch this promise (`DefinitionChangesUpdater` is always resolved with a boolean value)
47
+ return definitionsSyncTask.execute().then(function () {
48
+ return segmentsSyncTask.execute();
25
49
  });
26
50
  }
27
- },
28
- // Stop periodic fetching (polling)
29
- stop: function () {
30
- log.info(POLLING_STOP);
31
- if (splitsSyncTask.isRunning())
32
- splitsSyncTask.stop();
33
- if (segmentsSyncTask.isRunning())
34
- segmentsSyncTask.stop();
35
- },
36
- // Used by SyncManager to know if running in polling mode.
37
- isRunning: splitsSyncTask.isRunning,
38
- syncAll: function () {
39
- // fetch splits and segments. There is no need to catch this promise (`SplitChangesUpdater` is always resolved with a boolean value)
40
- return splitsSyncTask.execute().then(function () {
41
- return segmentsSyncTask.execute();
42
- });
43
- }
51
+ };
44
52
  };
45
53
  }
@@ -0,0 +1,9 @@
1
+ import { syncTaskFactory } from '../../syncTask';
2
+ import { definitionChangesUpdaterFactory } from '../updaters/definitionChangesUpdater';
3
+ /**
4
+ * Creates a sync task that periodically executes a `definitionChangesUpdater` task
5
+ */
6
+ export function definitionsSyncTaskFactory(definitionChangesFetcher, storage, readiness, settings, segmentsSyncTask // undefined for client-side
7
+ ) {
8
+ return syncTaskFactory(settings.log, definitionChangesUpdaterFactory(settings.log, definitionChangesFetcher, storage, settings.sync.__splitFiltersValidation, readiness.definitions, settings.startup.requestTimeoutBeforeReady, settings.startup.retriesOnFailureBeforeReady, segmentsSyncTask), settings.scheduler.featuresRefreshRate, 'definitionChangesUpdater');
9
+ }
@@ -1,9 +1,8 @@
1
1
  import { syncTaskFactory } from '../../syncTask';
2
- import { segmentChangesFetcherFactory } from '../fetchers/segmentChangesFetcher';
3
2
  import { segmentChangesUpdaterFactory } from '../updaters/segmentChangesUpdater';
4
3
  /**
5
4
  * Creates a sync task that periodically executes a `segmentChangesUpdater` task
6
5
  */
7
- export function segmentsSyncTaskFactory(fetchSegmentChanges, storage, readiness, settings) {
8
- return syncTaskFactory(settings.log, segmentChangesUpdaterFactory(settings.log, segmentChangesFetcherFactory(fetchSegmentChanges), storage.segments, readiness, settings.startup.requestTimeoutBeforeReady, settings.startup.retriesOnFailureBeforeReady), settings.scheduler.segmentsRefreshRate, 'segmentChangesUpdater');
6
+ export function segmentsSyncTaskFactory(segmentChangesFetcher, storage, readiness, settings) {
7
+ return syncTaskFactory(settings.log, segmentChangesUpdaterFactory(settings.log, segmentChangesFetcher, storage.segments, readiness, settings.startup.requestTimeoutBeforeReady, settings.startup.retriesOnFailureBeforeReady), settings.scheduler.segmentsRefreshRate, 'segmentChangesUpdater');
9
8
  }
@@ -0,0 +1,201 @@
1
+ import { timeout } from '../../../utils/promise/timeout';
2
+ import { SDK_DEFINITIONS_ARRIVED, FLAGS_UPDATE, SEGMENTS_UPDATE, CONFIGS_UPDATE } from '../../../readiness/constants';
3
+ import { SYNC_FETCH, SYNC_UPDATE, SYNC_FETCH_FAILS, SYNC_FETCH_RETRY } from '../../../logger/constants';
4
+ import { startsWith } from '../../../utils/lang';
5
+ import { IN_RULE_BASED_SEGMENT, IN_SEGMENT, RULE_BASED_SEGMENT, STANDARD_SEGMENT } from '../../../utils/constants';
6
+ import { setToArray } from '../../../utils/lang/sets';
7
+ import { RB_SEGMENT_UPDATE } from '../../streaming/constants';
8
+ import { thenable } from '../../../utils/promise/thenable';
9
+ /**
10
+ * Collect segments from a raw FF or RBS definition.
11
+ * Exported for testing purposes.
12
+ */
13
+ export function parseSegments(ruleEntity, matcherType) {
14
+ if (matcherType === void 0) { matcherType = IN_SEGMENT; }
15
+ var _a = ruleEntity, conditions = _a.conditions, excluded = _a.excluded;
16
+ var segments = new Set();
17
+ if (excluded && excluded.segments) {
18
+ excluded.segments.forEach(function (_a) {
19
+ var type = _a.type, name = _a.name;
20
+ if ((type === STANDARD_SEGMENT && matcherType === IN_SEGMENT) || (type === RULE_BASED_SEGMENT && matcherType === IN_RULE_BASED_SEGMENT)) {
21
+ segments.add(name);
22
+ }
23
+ });
24
+ }
25
+ if (conditions) {
26
+ for (var i = 0; i < conditions.length; i++) {
27
+ var matchers = conditions[i].matcherGroup.matchers;
28
+ matchers.forEach(function (matcher) {
29
+ if (matcher.matcherType === matcherType)
30
+ segments.add(matcher.userDefinedSegmentMatcherData.segmentName);
31
+ });
32
+ }
33
+ }
34
+ return segments;
35
+ }
36
+ /**
37
+ * If there are defined filters and one definition doesn't match with them, its status is changed to 'ARCHIVE' to avoid storing it
38
+ * If there is `bySet` filter, `byName` and `byPrefix` filters are ignored
39
+ *
40
+ * @param definition - definition to be evaluated
41
+ * @param filters - splitFiltersValidation bySet | byName
42
+ */
43
+ function matchFilters(definition, filters) {
44
+ var _a = filters.groupedFilters, setsFilter = _a.bySet, namesFilter = _a.byName, prefixFilter = _a.byPrefix;
45
+ if (setsFilter.length > 0)
46
+ return definition.sets && definition.sets.some(function (definitionSet) { return setsFilter.indexOf(definitionSet) > -1; });
47
+ var namesFilterConfigured = namesFilter.length > 0;
48
+ var prefixFilterConfigured = prefixFilter.length > 0;
49
+ if (!namesFilterConfigured && !prefixFilterConfigured)
50
+ return true;
51
+ var matchNames = namesFilterConfigured && namesFilter.indexOf(definition.name) > -1;
52
+ var matchPrefix = prefixFilterConfigured && prefixFilter.some(function (prefix) { return startsWith(definition.name, prefix); });
53
+ return matchNames || matchPrefix;
54
+ }
55
+ /**
56
+ * Given the list of definitions from /splitChanges or /configs endpoint, it returns the mutations,
57
+ * i.e., an object with added definitions, removed definitions, and used segments.
58
+ * Exported for testing purposes.
59
+ */
60
+ export function computeMutation(update, segments, filters) {
61
+ return update.updated.reduce(function (accum, ruleEntity) {
62
+ if (!filters || matchFilters(ruleEntity, filters)) {
63
+ accum.updated.push(ruleEntity);
64
+ parseSegments(ruleEntity).forEach(function (segmentName) {
65
+ segments.add(segmentName);
66
+ });
67
+ }
68
+ else {
69
+ accum.removed.push(ruleEntity.name);
70
+ }
71
+ accum.names.push(ruleEntity.name);
72
+ return accum;
73
+ }, { updated: [], removed: update.removed, names: update.removed.slice() });
74
+ }
75
+ function convertInstantUpdateToDefinitionChanges(instantUpdate) {
76
+ var payload = instantUpdate.payload, changeNumber = instantUpdate.changeNumber;
77
+ return payload.status === 'ARCHIVED' ?
78
+ { till: changeNumber, updated: [], removed: [payload.name] } :
79
+ { till: changeNumber, updated: [payload], removed: [] };
80
+ }
81
+ /**
82
+ * Factory of DefinitionChanges updater, a task that:
83
+ * - fetches definition changes using `definitionChangesFetcher`
84
+ * - updates definitions storage
85
+ * - uses `definitionsEventEmitter` to emit events related to definition data updates
86
+ *
87
+ * @param log - Logger instance
88
+ * @param definitionChangesFetcher - Fetcher of `/splitChanges` or `/configs`
89
+ * @param definitions - Definitions storage, with sync or async methods
90
+ * @param segments - Segments storage, with sync or async methods
91
+ * @param definitionsEventEmitter - Optional readiness manager. Not required for synchronizer or producer mode.
92
+ * @param requestTimeoutBeforeReady - How long the updater will wait for the request to timeout. Default 0, i.e., never timeout.
93
+ * @param retriesOnFailureBeforeReady - How many retries on `/splitChanges` or `/configs` we the updater do in case of failure or timeout. Default 0, i.e., no retries.
94
+ */
95
+ export function definitionChangesUpdaterFactory(log, definitionChangesFetcher, storage, splitFiltersValidation, definitionsEventEmitter, requestTimeoutBeforeReady, retriesOnFailureBeforeReady, segmentsSyncTask // undefined for client-side
96
+ ) {
97
+ if (requestTimeoutBeforeReady === void 0) { requestTimeoutBeforeReady = 0; }
98
+ if (retriesOnFailureBeforeReady === void 0) { retriesOnFailureBeforeReady = 0; }
99
+ var definitions = storage.definitions, rbSegments = storage.rbSegments, segments = storage.segments;
100
+ var startingUp = true;
101
+ /** timeout decorator for `definitionChangesFetcher` promise */
102
+ function _promiseDecorator(promise) {
103
+ if (startingUp && requestTimeoutBeforeReady)
104
+ promise = timeout(requestTimeoutBeforeReady, promise);
105
+ return promise;
106
+ }
107
+ /**
108
+ * DefinitionChanges updater returns a promise that resolves with a `false` boolean value if it fails to fetch definitions or synchronize them with the storage.
109
+ * Returned promise will not be rejected.
110
+ *
111
+ * @param noCache - true to revalidate data to fetch
112
+ * @param till - query param to bypass CDN requests
113
+ */
114
+ return function definitionChangesUpdater(noCache, till, instantUpdate, pcns) {
115
+ /**
116
+ * @param since - current changeNumber at definitionsCache
117
+ * @param retry - current number of retry attempts
118
+ */
119
+ function _definitionChangesUpdater(sinces, retry) {
120
+ if (retry === void 0) { retry = 0; }
121
+ var since = sinces[0], rbSince = sinces[1];
122
+ // If provided, `since` and `rbSince` must not be higher than it, to avoid missing an update that the scoped `pcn` indicates hasn't been fetched yet.
123
+ if (pcns) {
124
+ if (pcns.since !== undefined && pcns.since < since)
125
+ since = pcns.since;
126
+ if (pcns.rbSince !== undefined && pcns.rbSince < rbSince)
127
+ rbSince = pcns.rbSince;
128
+ }
129
+ var definitionChangesRequest = instantUpdate ?
130
+ instantUpdate.type === RB_SEGMENT_UPDATE ?
131
+ { rbs: convertInstantUpdateToDefinitionChanges(instantUpdate) } :
132
+ // IFFU edge case: a change to definition that adds an IN_RULE_BASED_SEGMENT matcher that is not present yet
133
+ Promise.resolve(rbSegments.contains(parseSegments(instantUpdate.payload, IN_RULE_BASED_SEGMENT))).then(function (contains) {
134
+ return contains ?
135
+ { d: convertInstantUpdateToDefinitionChanges(instantUpdate) } :
136
+ definitionChangesFetcher(since, noCache, till, rbSince, _promiseDecorator);
137
+ }) :
138
+ definitionChangesFetcher(since, noCache, till, rbSince, _promiseDecorator);
139
+ if (thenable(definitionChangesRequest))
140
+ log.debug(SYNC_FETCH, [definitionChangesFetcher.type, since, rbSince]);
141
+ return Promise.resolve(definitionChangesRequest)
142
+ .then(function (definitionChanges) {
143
+ var usedSegments = new Set();
144
+ var updatedDefinitions = [];
145
+ var ffUpdate = false;
146
+ if (definitionChanges.d) {
147
+ var _a = computeMutation(definitionChanges.d, usedSegments, splitFiltersValidation), updated = _a.updated, removed = _a.removed, names = _a.names;
148
+ updatedDefinitions = names;
149
+ log.debug(SYNC_UPDATE, [definitionChangesFetcher.type, updated.length, removed.length]);
150
+ ffUpdate = definitions.update(updated, removed, definitionChanges.d.till);
151
+ }
152
+ var rbsUpdate = false;
153
+ if (definitionChanges.rbs) {
154
+ var _b = computeMutation(definitionChanges.rbs, usedSegments), updated = _b.updated, removed = _b.removed;
155
+ log.debug(SYNC_UPDATE, ['rule-based segments', updated.length, removed.length]);
156
+ rbsUpdate = rbSegments.update(updated, removed, definitionChanges.rbs.till);
157
+ }
158
+ return Promise.all([ffUpdate, rbsUpdate,
159
+ // @TODO if at least 1 segment fetch fails due to 404 and other segments are updated in the storage, SDK_UPDATE is not emitted
160
+ segments.registerSegments(setToArray(usedSegments))
161
+ ]).then(function (_a) {
162
+ var ffChanged = _a[0], rbsChanged = _a[1];
163
+ if (storage.save)
164
+ storage.save();
165
+ startingUp = false;
166
+ if (definitionsEventEmitter) {
167
+ // To emit SDK_DEFINITIONS_ARRIVED for server-side SDK, we must wait for all registered segments to be fetched
168
+ return Promise.resolve(!definitionsEventEmitter.definitionsArrived || ((ffChanged || rbsChanged) && (!segmentsSyncTask || segmentsSyncTask.execute(true))))
169
+ .catch(function () { return false; } /** noop. just to handle a possible `checkAllSegmentsExist` rejection, before emitting SDK event */)
170
+ .then(function (emitSplitsArrivedEvent) {
171
+ // emit SDK events
172
+ if (emitSplitsArrivedEvent) {
173
+ var metadata = {
174
+ type: updatedDefinitions.length > 0 ? definitionChangesFetcher.type === 'configs' ? CONFIGS_UPDATE : FLAGS_UPDATE : SEGMENTS_UPDATE,
175
+ names: updatedDefinitions.length > 0 ? updatedDefinitions : []
176
+ };
177
+ definitionsEventEmitter.emit(SDK_DEFINITIONS_ARRIVED, metadata);
178
+ }
179
+ return true;
180
+ });
181
+ }
182
+ return true;
183
+ });
184
+ })
185
+ .catch(function (error) {
186
+ if (startingUp && retriesOnFailureBeforeReady > retry) {
187
+ retry += 1;
188
+ log.warn(SYNC_FETCH_RETRY, [definitionChangesFetcher.type, retry, error]);
189
+ return _definitionChangesUpdater(sinces, retry);
190
+ }
191
+ else {
192
+ startingUp = false;
193
+ log.warn(SYNC_FETCH_FAILS, [definitionChangesFetcher.type, error]);
194
+ }
195
+ return false;
196
+ });
197
+ }
198
+ // `getChangeNumber` never rejects or throws error
199
+ return Promise.all([definitions.getChangeNumber(), rbSegments.getChangeNumber()]).then(_definitionChangesUpdater);
200
+ };
201
+ }
@@ -1,8 +1,8 @@
1
1
  import { timeout } from '../../../utils/promise/timeout';
2
2
  import { SDK_SEGMENTS_ARRIVED, SEGMENTS_UPDATE } from '../../../readiness/constants';
3
- import { SYNC_MYSEGMENTS_FETCH_RETRY } from '../../../logger/constants';
3
+ import { SYNC_FETCH_RETRY } from '../../../logger/constants';
4
4
  import { MEMBERSHIPS_LS_UPDATE } from '../../streaming/constants';
5
- import { usesSegmentsSync } from '../../../storages/AbstractSplitsCacheSync';
5
+ import { usesSegmentsSync } from '../../../storages/AbstractDefinitionsCacheSync';
6
6
  /**
7
7
  * factory of MySegments updater, a task that:
8
8
  * - fetches mySegments using `mySegmentsFetcher`
@@ -53,7 +53,7 @@ export function mySegmentsUpdaterFactory(log, mySegmentsFetcher, storage, segmen
53
53
  return updaterPromise.catch(function (error) {
54
54
  if (startingUp && retriesOnFailureBeforeReady > retry) {
55
55
  retry += 1;
56
- log.warn(SYNC_MYSEGMENTS_FETCH_RETRY, [retry, error]);
56
+ log.warn(SYNC_FETCH_RETRY, ['memberships', retry, error]);
57
57
  return _mySegmentsUpdater(retry); // no need to forward `segmentList` and `noCache` params
58
58
  }
59
59
  else {