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

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 (241) hide show
  1. package/CHANGES.txt +10 -1
  2. package/cjs/evaluator/condition/index.js +1 -1
  3. package/cjs/evaluator/fallbackTreatmentsCalculator/fallbackSanitizer/index.js +8 -5
  4. package/cjs/evaluator/index.js +69 -81
  5. package/cjs/listeners/browser.js +1 -2
  6. package/cjs/listeners/node.js +4 -4
  7. package/cjs/logger/constants.js +20 -15
  8. package/cjs/logger/messages/debug.js +6 -5
  9. package/cjs/logger/messages/error.js +3 -3
  10. package/cjs/logger/messages/info.js +4 -3
  11. package/cjs/logger/messages/warn.js +7 -6
  12. package/cjs/presets/serverSide.js +2 -2
  13. package/cjs/readiness/constants.js +4 -5
  14. package/cjs/readiness/readinessManager.js +23 -23
  15. package/cjs/readiness/sdkReadinessManager.js +17 -1
  16. package/cjs/sdkClient/client.js +34 -9
  17. package/cjs/sdkClient/clientInputValidation.js +17 -6
  18. package/cjs/sdkClient/sdkClient.js +60 -3
  19. package/cjs/sdkFactory/index.js +15 -11
  20. package/cjs/sdkManager/index.js +5 -5
  21. package/cjs/services/decorateHeaders.js +1 -2
  22. package/cjs/services/splitApi.js +1 -14
  23. package/cjs/services/splitHttpClient.js +5 -3
  24. package/cjs/storages/AbstractSplitsCacheAsync.js +51 -0
  25. package/cjs/storages/AbstractSplitsCacheSync.js +76 -0
  26. package/cjs/storages/KeyBuilder.js +6 -6
  27. package/cjs/storages/KeyBuilderCS.js +5 -5
  28. package/cjs/storages/KeyBuilderSS.js +2 -2
  29. package/cjs/storages/getRolloutPlan.js +3 -3
  30. package/cjs/storages/inLocalStorage/MySegmentsCacheInLocal.js +2 -1
  31. package/cjs/storages/inLocalStorage/RBSegmentsCacheInLocal.js +10 -10
  32. package/cjs/storages/inLocalStorage/SplitsCacheInLocal.js +194 -0
  33. package/cjs/storages/inLocalStorage/index.js +6 -6
  34. package/cjs/storages/inLocalStorage/validateCache.js +3 -3
  35. package/cjs/storages/inMemory/InMemoryStorage.js +4 -4
  36. package/cjs/storages/inMemory/InMemoryStorageCS.js +5 -5
  37. package/cjs/storages/inMemory/RBSegmentsCacheInMemory.js +5 -5
  38. package/cjs/storages/inMemory/SegmentsCacheInMemory.js +1 -1
  39. package/cjs/storages/inMemory/SplitsCacheInMemory.js +121 -0
  40. package/cjs/storages/inMemory/TelemetryCacheInMemory.js +5 -5
  41. package/cjs/storages/inRedis/RBSegmentsCacheInRedis.js +1 -1
  42. package/cjs/storages/inRedis/RedisAdapter.js +8 -5
  43. package/cjs/storages/inRedis/{DefinitionsCacheInRedis.js → SplitsCacheInRedis.js} +77 -77
  44. package/cjs/storages/inRedis/index.js +2 -2
  45. package/cjs/storages/pluggable/RBSegmentsCachePluggable.js +1 -1
  46. package/cjs/storages/pluggable/SplitsCachePluggable.js +212 -0
  47. package/cjs/storages/pluggable/index.js +2 -2
  48. package/cjs/storages/setRolloutPlan.js +4 -4
  49. package/cjs/storages/utils.js +0 -1
  50. package/cjs/sync/offline/syncTasks/fromObjectSyncTask.js +5 -5
  51. package/cjs/sync/polling/fetchers/splitChangesFetcher.js +15 -24
  52. package/cjs/sync/polling/pollingManagerCS.js +20 -20
  53. package/cjs/sync/polling/pollingManagerSS.js +15 -15
  54. package/cjs/sync/polling/syncTasks/segmentsSyncTask.js +3 -2
  55. package/cjs/sync/polling/syncTasks/splitsSyncTask.js +13 -0
  56. package/cjs/sync/polling/updaters/mySegmentsUpdater.js +3 -3
  57. package/cjs/sync/polling/updaters/segmentChangesUpdater.js +6 -6
  58. package/cjs/sync/polling/updaters/{definitionChangesUpdater.js → splitChangesUpdater.js} +68 -65
  59. package/cjs/sync/streaming/AuthClient/index.js +1 -1
  60. package/cjs/sync/streaming/SSEHandler/NotificationKeeper.js +1 -1
  61. package/cjs/sync/streaming/SSEHandler/index.js +1 -1
  62. package/cjs/sync/streaming/UpdateWorkers/{DefinitionsUpdateWorker.js → SplitsUpdateWorker.js} +19 -16
  63. package/cjs/sync/streaming/constants.js +3 -3
  64. package/cjs/sync/streaming/parseUtils.js +11 -11
  65. package/cjs/sync/streaming/pushManager.js +16 -16
  66. package/cjs/sync/submitters/eventsSubmitter.js +1 -1
  67. package/cjs/sync/submitters/impressionCountsSubmitter.js +1 -1
  68. package/cjs/sync/submitters/impressionsSubmitter.js +4 -5
  69. package/cjs/sync/submitters/telemetrySubmitter.js +4 -3
  70. package/cjs/sync/submitters/uniqueKeysSubmitter.js +1 -1
  71. package/cjs/sync/syncManagerOnline.js +7 -12
  72. package/cjs/utils/Backoff.js +0 -20
  73. package/cjs/utils/inputValidation/index.js +7 -7
  74. package/cjs/utils/inputValidation/isOperational.js +4 -4
  75. package/cjs/utils/inputValidation/{definition.js → split.js} +10 -10
  76. package/cjs/utils/inputValidation/{definitionExistence.js → splitExistence.js} +6 -6
  77. package/cjs/utils/inputValidation/splits.js +25 -0
  78. package/cjs/utils/labels/index.js +3 -3
  79. package/cjs/utils/settingsValidation/index.js +0 -2
  80. package/cjs/utils/settingsValidation/splitFilters.js +3 -3
  81. package/cjs/utils/settingsValidation/url.js +2 -6
  82. package/esm/evaluator/condition/index.js +1 -1
  83. package/esm/evaluator/fallbackTreatmentsCalculator/fallbackSanitizer/index.js +8 -5
  84. package/esm/evaluator/index.js +69 -80
  85. package/esm/listeners/browser.js +1 -2
  86. package/esm/listeners/node.js +4 -4
  87. package/esm/logger/constants.js +17 -12
  88. package/esm/logger/messages/debug.js +6 -5
  89. package/esm/logger/messages/error.js +3 -3
  90. package/esm/logger/messages/info.js +4 -3
  91. package/esm/logger/messages/warn.js +7 -6
  92. package/esm/presets/serverSide.js +2 -2
  93. package/esm/readiness/constants.js +3 -4
  94. package/esm/readiness/readinessManager.js +24 -24
  95. package/esm/readiness/sdkReadinessManager.js +18 -2
  96. package/esm/sdkClient/client.js +35 -9
  97. package/esm/sdkClient/clientInputValidation.js +19 -8
  98. package/esm/sdkClient/sdkClient.js +60 -3
  99. package/esm/sdkFactory/index.js +16 -12
  100. package/esm/sdkManager/index.js +6 -6
  101. package/esm/services/decorateHeaders.js +1 -2
  102. package/esm/services/splitApi.js +1 -14
  103. package/esm/services/splitHttpClient.js +5 -3
  104. package/esm/storages/AbstractSplitsCacheAsync.js +48 -0
  105. package/esm/storages/AbstractSplitsCacheSync.js +71 -0
  106. package/esm/storages/KeyBuilder.js +6 -6
  107. package/esm/storages/KeyBuilderCS.js +5 -5
  108. package/esm/storages/KeyBuilderSS.js +2 -2
  109. package/esm/storages/getRolloutPlan.js +3 -3
  110. package/esm/storages/inLocalStorage/MySegmentsCacheInLocal.js +2 -1
  111. package/esm/storages/inLocalStorage/RBSegmentsCacheInLocal.js +7 -7
  112. package/esm/storages/inLocalStorage/SplitsCacheInLocal.js +191 -0
  113. package/esm/storages/inLocalStorage/index.js +6 -6
  114. package/esm/storages/inLocalStorage/validateCache.js +3 -3
  115. package/esm/storages/inMemory/InMemoryStorage.js +4 -4
  116. package/esm/storages/inMemory/InMemoryStorageCS.js +5 -5
  117. package/esm/storages/inMemory/RBSegmentsCacheInMemory.js +2 -2
  118. package/esm/storages/inMemory/SegmentsCacheInMemory.js +1 -1
  119. package/esm/storages/inMemory/SplitsCacheInMemory.js +118 -0
  120. package/esm/storages/inMemory/TelemetryCacheInMemory.js +5 -5
  121. package/esm/storages/inRedis/RBSegmentsCacheInRedis.js +1 -1
  122. package/esm/storages/inRedis/RedisAdapter.js +8 -5
  123. package/esm/storages/inRedis/{DefinitionsCacheInRedis.js → SplitsCacheInRedis.js} +76 -76
  124. package/esm/storages/inRedis/index.js +2 -2
  125. package/esm/storages/pluggable/RBSegmentsCachePluggable.js +1 -1
  126. package/esm/storages/pluggable/SplitsCachePluggable.js +209 -0
  127. package/esm/storages/pluggable/index.js +2 -2
  128. package/esm/storages/setRolloutPlan.js +4 -4
  129. package/esm/storages/utils.js +0 -1
  130. package/esm/sync/offline/syncTasks/fromObjectSyncTask.js +6 -6
  131. package/esm/sync/polling/fetchers/splitChangesFetcher.js +16 -25
  132. package/esm/sync/polling/pollingManagerCS.js +17 -17
  133. package/esm/sync/polling/pollingManagerSS.js +15 -15
  134. package/esm/sync/polling/syncTasks/segmentsSyncTask.js +3 -2
  135. package/esm/sync/polling/syncTasks/splitsSyncTask.js +9 -0
  136. package/esm/sync/polling/updaters/mySegmentsUpdater.js +3 -3
  137. package/esm/sync/polling/updaters/segmentChangesUpdater.js +7 -7
  138. package/esm/sync/polling/updaters/{definitionChangesUpdater.js → splitChangesUpdater.js} +68 -65
  139. package/esm/sync/streaming/AuthClient/index.js +1 -1
  140. package/esm/sync/streaming/SSEHandler/NotificationKeeper.js +2 -2
  141. package/esm/sync/streaming/SSEHandler/index.js +2 -2
  142. package/esm/sync/streaming/UpdateWorkers/{DefinitionsUpdateWorker.js → SplitsUpdateWorker.js} +18 -15
  143. package/esm/sync/streaming/constants.js +2 -2
  144. package/esm/sync/streaming/parseUtils.js +9 -9
  145. package/esm/sync/streaming/pushManager.js +18 -18
  146. package/esm/sync/submitters/eventsSubmitter.js +1 -1
  147. package/esm/sync/submitters/impressionCountsSubmitter.js +1 -1
  148. package/esm/sync/submitters/impressionsSubmitter.js +4 -5
  149. package/esm/sync/submitters/telemetrySubmitter.js +4 -3
  150. package/esm/sync/submitters/uniqueKeysSubmitter.js +1 -1
  151. package/esm/sync/syncManagerOnline.js +6 -11
  152. package/esm/utils/Backoff.js +0 -20
  153. package/esm/utils/inputValidation/index.js +3 -3
  154. package/esm/utils/inputValidation/isOperational.js +4 -4
  155. package/esm/utils/inputValidation/{definition.js → split.js} +8 -8
  156. package/esm/utils/inputValidation/splitExistence.js +15 -0
  157. package/esm/utils/inputValidation/splits.js +21 -0
  158. package/esm/utils/labels/index.js +2 -2
  159. package/esm/utils/settingsValidation/index.js +0 -2
  160. package/esm/utils/settingsValidation/splitFilters.js +3 -3
  161. package/esm/utils/settingsValidation/url.js +2 -6
  162. package/package.json +6 -7
  163. package/src/dtos/types.ts +1 -1
  164. package/src/evaluator/Engine.ts +3 -3
  165. package/src/evaluator/condition/index.ts +2 -2
  166. package/src/evaluator/index.ts +27 -35
  167. package/src/evaluator/types.ts +2 -6
  168. package/src/presets/serverSide.ts +3 -3
  169. package/src/sdkClient/client.ts +22 -24
  170. package/src/sdkClient/sdkLifecycle.ts +3 -0
  171. package/src/services/authProvider.ts +41 -19
  172. package/src/services/secureSplitHttpClient.ts +10 -18
  173. package/src/services/serviceApi.ts +27 -24
  174. package/src/services/splitApi.ts +10 -9
  175. package/src/services/types.ts +5 -4
  176. package/src/storages/inRedis/RedisAdapter.ts +8 -5
  177. package/src/sync/polling/pollingManagerCS.ts +80 -78
  178. package/src/sync/polling/pollingManagerSS.ts +49 -45
  179. package/src/sync/polling/updaters/definitionChangesUpdater.ts +3 -3
  180. package/src/sync/polling/updaters/segmentChangesUpdater.ts +1 -1
  181. package/src/sync/streaming/AuthClient/index.ts +14 -15
  182. package/src/sync/streaming/AuthClient/types.ts +9 -13
  183. package/src/sync/streaming/SSEClient/index.ts +2 -2
  184. package/src/sync/streaming/SSEClient/types.ts +2 -2
  185. package/src/sync/streaming/SSEHandler/index.ts +2 -1
  186. package/src/sync/streaming/SSEHandler/types.ts +2 -2
  187. package/src/sync/streaming/constants.ts +1 -0
  188. package/src/sync/streaming/pushManager.ts +32 -42
  189. package/src/sync/streaming/types.ts +3 -2
  190. package/src/sync/submitters/impressionsSubmitter.ts +3 -3
  191. package/src/sync/submitters/types.ts +2 -2
  192. package/src/sync/syncManagerOnline.ts +2 -8
  193. package/src/utils/Backoff.ts +16 -4
  194. package/types/splitio.d.ts +5 -4
  195. package/cjs/platform/browser.js +0 -15
  196. package/cjs/platform/getEventSource/browser.js +0 -8
  197. package/cjs/platform/getEventSource/eventsource.js +0 -480
  198. package/cjs/platform/getEventSource/node.js +0 -26
  199. package/cjs/platform/getFetch/browser.js +0 -9
  200. package/cjs/platform/getFetch/node.js +0 -27
  201. package/cjs/platform/getOptions/node.js +0 -25
  202. package/cjs/platform/node.js +0 -17
  203. package/cjs/sdkClient/sdkLifecycle.js +0 -72
  204. package/cjs/sdkClient/trackMethod.js +0 -56
  205. package/cjs/services/authProvider.js +0 -67
  206. package/cjs/services/secureSplitHttpClient.js +0 -39
  207. package/cjs/services/serviceApi.js +0 -145
  208. package/cjs/storages/AbstractDefinitionsCacheAsync.js +0 -51
  209. package/cjs/storages/AbstractDefinitionsCacheSync.js +0 -76
  210. package/cjs/storages/inLocalStorage/DefinitionsCacheInLocal.js +0 -194
  211. package/cjs/storages/inMemory/DefinitionsCacheInMemory.js +0 -121
  212. package/cjs/storages/pluggable/DefinitionsCachePluggable.js +0 -212
  213. package/cjs/sync/polling/syncTasks/definitionsSyncTask.js +0 -13
  214. package/cjs/utils/EventEmitter.js +0 -391
  215. package/cjs/utils/filter/bloomFilter.js +0 -37
  216. package/cjs/utils/inputValidation/definitions.js +0 -25
  217. package/cjs/utils/inputValidation/target.js +0 -22
  218. package/esm/platform/browser.js +0 -12
  219. package/esm/platform/getEventSource/browser.js +0 -4
  220. package/esm/platform/getEventSource/eventsource.js +0 -480
  221. package/esm/platform/getEventSource/node.js +0 -20
  222. package/esm/platform/getFetch/browser.js +0 -5
  223. package/esm/platform/getFetch/node.js +0 -22
  224. package/esm/platform/getOptions/node.js +0 -20
  225. package/esm/platform/node.js +0 -14
  226. package/esm/sdkClient/sdkLifecycle.js +0 -68
  227. package/esm/sdkClient/trackMethod.js +0 -52
  228. package/esm/services/authProvider.js +0 -63
  229. package/esm/services/secureSplitHttpClient.js +0 -35
  230. package/esm/services/serviceApi.js +0 -141
  231. package/esm/storages/AbstractDefinitionsCacheAsync.js +0 -48
  232. package/esm/storages/AbstractDefinitionsCacheSync.js +0 -71
  233. package/esm/storages/inLocalStorage/DefinitionsCacheInLocal.js +0 -191
  234. package/esm/storages/inMemory/DefinitionsCacheInMemory.js +0 -118
  235. package/esm/storages/pluggable/DefinitionsCachePluggable.js +0 -209
  236. package/esm/sync/polling/syncTasks/definitionsSyncTask.js +0 -9
  237. package/esm/utils/EventEmitter.js +0 -387
  238. package/esm/utils/filter/bloomFilter.js +0 -33
  239. package/esm/utils/inputValidation/definitionExistence.js +0 -15
  240. package/esm/utils/inputValidation/definitions.js +0 -21
  241. package/esm/utils/inputValidation/target.js +0 -18
@@ -1,15 +1,72 @@
1
1
  import { objectAssign } from '../utils/lang/objectAssign';
2
+ import { releaseApiKey, validateAndTrackApiKey } from '../utils/inputValidation/apiKey';
2
3
  import { clientFactory } from './client';
3
4
  import { clientInputValidationDecorator } from './clientInputValidation';
4
- import { sdkLifecycleFactory } from './sdkLifecycle';
5
+ var COOLDOWN_TIME_IN_MILLIS = 1000;
5
6
  /**
6
7
  * Creates an Sdk client, i.e., a base client with status, init, flush and destroy interface
7
8
  */
8
9
  export function sdkClientFactory(params, isSharedClient) {
9
- var sdkReadinessManager = params.sdkReadinessManager, settings = params.settings;
10
+ var sdkReadinessManager = params.sdkReadinessManager, syncManager = params.syncManager, storage = params.storage, signalListener = params.signalListener, settings = params.settings, telemetryTracker = params.telemetryTracker, impressionsTracker = params.impressionsTracker;
11
+ var hasInit = false;
12
+ var lastActionTime = 0;
13
+ function __cooldown(func, time) {
14
+ var now = Date.now();
15
+ //get the actual time elapsed in ms
16
+ var timeElapsed = now - lastActionTime;
17
+ //check if the time elapsed is less than desired cooldown
18
+ if (timeElapsed < time) {
19
+ //if yes, return message with remaining time in seconds
20
+ settings.log.warn("Flush cooldown, remaining time ".concat((time - timeElapsed) / 1000, " seconds"));
21
+ return Promise.resolve();
22
+ }
23
+ else {
24
+ //Do the requested action and re-assign the lastActionTime
25
+ lastActionTime = now;
26
+ return func();
27
+ }
28
+ }
29
+ function __flush() {
30
+ return syncManager ? syncManager.flush() : Promise.resolve();
31
+ }
10
32
  return objectAssign(
11
33
  // Proto-linkage of the readiness Event Emitter
12
34
  Object.create(sdkReadinessManager.sdkStatus),
13
35
  // Client API (getTreatment* & track methods)
14
- clientInputValidationDecorator(settings, clientFactory(params), sdkReadinessManager.readinessManager, params.fallbackCalculator), sdkLifecycleFactory(params, isSharedClient));
36
+ clientInputValidationDecorator(settings, clientFactory(params), sdkReadinessManager.readinessManager, params.fallbackTreatmentsCalculator), {
37
+ init: function () {
38
+ if (hasInit)
39
+ return;
40
+ hasInit = true;
41
+ if (!isSharedClient) {
42
+ validateAndTrackApiKey(settings.log, settings.core.authorizationKey);
43
+ sdkReadinessManager.readinessManager.init();
44
+ impressionsTracker.start();
45
+ syncManager && syncManager.start();
46
+ signalListener && signalListener.start();
47
+ }
48
+ },
49
+ flush: function () {
50
+ // @TODO define cooldown time
51
+ return __cooldown(__flush, COOLDOWN_TIME_IN_MILLIS);
52
+ },
53
+ destroy: function () {
54
+ hasInit = false;
55
+ // Mark the SDK as destroyed immediately
56
+ sdkReadinessManager.readinessManager.destroy();
57
+ // For main client, cleanup the SDK Key, listeners and scheduled jobs, and record stat before flushing data
58
+ if (!isSharedClient) {
59
+ releaseApiKey(settings.core.authorizationKey);
60
+ telemetryTracker.sessionLength();
61
+ signalListener && signalListener.stop();
62
+ impressionsTracker.stop();
63
+ }
64
+ // Stop background jobs
65
+ syncManager && syncManager.stop();
66
+ return __flush().then(function () {
67
+ // Cleanup storage
68
+ return storage.destroy();
69
+ });
70
+ }
71
+ });
15
72
  }
@@ -4,7 +4,7 @@ import { eventTrackerFactory } from '../trackers/eventTracker';
4
4
  import { telemetryTrackerFactory } from '../trackers/telemetryTracker';
5
5
  import { createLoggerAPI } from '../logger/sdkLogger';
6
6
  import { NEW_FACTORY, RETRIEVE_MANAGER } from '../logger/constants';
7
- import { SDK_DEFINITIONS_ARRIVED, SDK_SEGMENTS_ARRIVED, SDK_DEFINITIONS_CACHE_LOADED } from '../readiness/constants';
7
+ import { SDK_SPLITS_ARRIVED, SDK_SEGMENTS_ARRIVED, SDK_SPLITS_CACHE_LOADED } from '../readiness/constants';
8
8
  import { objectAssign } from '../utils/lang/objectAssign';
9
9
  import { setRolloutPlan } from '../storages/setRolloutPlan';
10
10
  import { getMatching } from '../utils/key';
@@ -13,7 +13,7 @@ import { FallbackTreatmentsCalculator } from '../evaluator/fallbackTreatmentsCal
13
13
  * Modular SDK factory
14
14
  */
15
15
  export function sdkFactory(params) {
16
- var settings = params.settings, platform = params.platform, storageFactory = params.storageFactory, serviceApiFactory = params.serviceApiFactory, extraProps = params.extraProps, syncManagerFactory = params.syncManagerFactory, integrationsManagerFactory = params.integrationsManagerFactory, sdkManagerFactory = params.sdkManagerFactory, sdkClientMethodFactory = params.sdkClientMethodFactory, lazyInit = params.lazyInit;
16
+ var settings = params.settings, platform = params.platform, storageFactory = params.storageFactory, splitApiFactory = params.splitApiFactory, extraProps = params.extraProps, syncManagerFactory = params.syncManagerFactory, SignalListener = params.SignalListener, integrationsManagerFactory = params.integrationsManagerFactory, sdkManagerFactory = params.sdkManagerFactory, sdkClientMethodFactory = params.sdkClientMethodFactory, lazyInit = params.lazyInit;
17
17
  var log = settings.log, initialRolloutPlan = settings.initialRolloutPlan, key = settings.core.key;
18
18
  // @TODO handle non-recoverable errors, such as, global `fetch` not available, invalid SDK Key, etc.
19
19
  // On non-recoverable errors, we should mark the SDK as destroyed and not start synchronization.
@@ -27,31 +27,35 @@ export function sdkFactory(params) {
27
27
  readiness.timeout();
28
28
  return;
29
29
  }
30
- readiness.definitions.emit(SDK_DEFINITIONS_ARRIVED);
30
+ readiness.splits.emit(SDK_SPLITS_ARRIVED);
31
31
  readiness.segments.emit(SDK_SEGMENTS_ARRIVED);
32
32
  },
33
33
  onReadyFromCacheCb: function () {
34
- readiness.definitions.emit(SDK_DEFINITIONS_CACHE_LOADED);
34
+ readiness.splits.emit(SDK_SPLITS_CACHE_LOADED);
35
35
  }
36
36
  });
37
- var fallbackCalculator = FallbackTreatmentsCalculator(settings.fallbackTreatments);
37
+ var fallbackTreatmentsCalculator = FallbackTreatmentsCalculator(settings.fallbackTreatments);
38
38
  if (initialRolloutPlan) {
39
39
  setRolloutPlan(log, initialRolloutPlan, storage, key && getMatching(key));
40
- if (storage.definitions.getChangeNumber() > -1)
41
- readiness.definitions.emit(SDK_DEFINITIONS_CACHE_LOADED, { initialCacheLoad: false /* Not an initial load, cache exists */ });
40
+ if (storage.splits.getChangeNumber() > -1)
41
+ readiness.splits.emit(SDK_SPLITS_CACHE_LOADED, { initialCacheLoad: false /* Not an initial load, cache exists */ });
42
42
  }
43
43
  var clients = {};
44
44
  var telemetryTracker = telemetryTrackerFactory(storage.telemetry, platform.now);
45
45
  var integrationsManager = integrationsManagerFactory && integrationsManagerFactory({ settings: settings, storage: storage, telemetryTracker: telemetryTracker });
46
46
  var impressionsTracker = impressionsTrackerFactory(params, storage, integrationsManager);
47
47
  var eventTracker = eventTrackerFactory(settings, storage.events, integrationsManager, storage.telemetry);
48
- // serviceApi is used by SyncManager and Browser signal listener
49
- var serviceApi = serviceApiFactory && serviceApiFactory(settings, platform, telemetryTracker);
50
- var ctx = { clients: clients, serviceApi: serviceApi, eventTracker: eventTracker, impressionsTracker: impressionsTracker, telemetryTracker: telemetryTracker, sdkReadinessManager: sdkReadinessManager, readiness: readiness, settings: settings, storage: storage, platform: platform, fallbackCalculator: fallbackCalculator };
51
- ctx.syncManager = syncManagerFactory && syncManagerFactory(ctx);
48
+ // splitApi is used by SyncManager and Browser signal listener
49
+ var splitApi = splitApiFactory && splitApiFactory(settings, platform, telemetryTracker);
50
+ var ctx = { clients: clients, splitApi: splitApi, eventTracker: eventTracker, impressionsTracker: impressionsTracker, telemetryTracker: telemetryTracker, sdkReadinessManager: sdkReadinessManager, readiness: readiness, settings: settings, storage: storage, platform: platform, fallbackTreatmentsCalculator: fallbackTreatmentsCalculator };
51
+ var syncManager = syncManagerFactory && syncManagerFactory(ctx);
52
+ ctx.syncManager = syncManager;
53
+ // @TODO: move into platform, and call inside sdkClientFactory (if it's used only there)
54
+ var signalListener = SignalListener && new SignalListener(syncManager, settings, storage, splitApi);
55
+ ctx.signalListener = signalListener;
52
56
  // SDK client and manager
53
57
  var clientMethod = sdkClientMethodFactory(ctx);
54
- var managerInstance = sdkManagerFactory(settings, storage.definitions, sdkReadinessManager);
58
+ var managerInstance = sdkManagerFactory(settings, storage.splits, sdkReadinessManager);
55
59
  function init() {
56
60
  Object.keys(clients).map(function (key) { return clients[key].init(); });
57
61
  }
@@ -1,7 +1,7 @@
1
1
  import { objectAssign } from '../utils/lang/objectAssign';
2
2
  import { thenable } from '../utils/promise/thenable';
3
3
  import { find } from '../utils/lang';
4
- import { validateDefinition, validateDefinitionExistence, validateIfOperational } from '../utils/inputValidation';
4
+ import { validateSplit, validateSplitExistence, validateIfOperational } from '../utils/inputValidation';
5
5
  import { isConsumerMode } from '../utils/settingsValidation/mode';
6
6
  import { SPLIT_FN_LABEL, SPLITS_FN_LABEL, NAMES_FN_LABEL } from '../utils/constants';
7
7
  function collectTreatments(splitObject) {
@@ -50,18 +50,18 @@ export function sdkManagerFactory(settings, splits, _a) {
50
50
  * Get the feature flag object corresponding to the given feature flag name if valid
51
51
  */
52
52
  split: function (featureFlagName) {
53
- var splitName = validateDefinition(log, featureFlagName, SPLIT_FN_LABEL);
53
+ var splitName = validateSplit(log, featureFlagName, SPLIT_FN_LABEL);
54
54
  if (!validateIfOperational(log, readinessManager, SPLIT_FN_LABEL) || !splitName) {
55
55
  return isAsync ? Promise.resolve(null) : null;
56
56
  }
57
- var split = splits.get(splitName);
57
+ var split = splits.getSplit(splitName);
58
58
  if (thenable(split)) {
59
59
  return split.catch(function () { return null; }).then(function (result) {
60
- validateDefinitionExistence(log, readinessManager, splitName, result, SPLIT_FN_LABEL);
60
+ validateSplitExistence(log, readinessManager, splitName, result, SPLIT_FN_LABEL);
61
61
  return objectToView(result);
62
62
  });
63
63
  }
64
- validateDefinitionExistence(log, readinessManager, splitName, split, SPLIT_FN_LABEL);
64
+ validateSplitExistence(log, readinessManager, splitName, split, SPLIT_FN_LABEL);
65
65
  return objectToView(split);
66
66
  },
67
67
  /**
@@ -83,7 +83,7 @@ export function sdkManagerFactory(settings, splits, _a) {
83
83
  if (!validateIfOperational(log, readinessManager, NAMES_FN_LABEL)) {
84
84
  return isAsync ? Promise.resolve([]) : [];
85
85
  }
86
- var splitNames = splits.getNames();
86
+ var splitNames = splits.getSplitNames();
87
87
  return thenable(splitNames) ?
88
88
  splitNames.catch(function () { return []; }) : // handle possible rejections when using pluggable storage
89
89
  splitNames;
@@ -12,8 +12,7 @@ var FORBIDDEN_HEADERS = new Set([
12
12
  'content-encoding',
13
13
  'accept',
14
14
  'keep-alive',
15
- 'x-fastly-debug',
16
- 'x-harness-fme-sdk-version'
15
+ 'x-fastly-debug'
17
16
  ]);
18
17
  export function decorateHeaders(settings, headers) {
19
18
  var _a;
@@ -6,9 +6,8 @@ var noCacheHeaderOptions = { headers: { 'Cache-Control': 'no-cache' } };
6
6
  function userKeyToQueryParam(userKey) {
7
7
  return 'users=' + encodeURIComponent(userKey); // no need to check availability of `encodeURIComponent`, since it is a global highly supported.
8
8
  }
9
- // @TODO remove when migrating to the new `urls` defaults.
10
9
  /**
11
- * Factory of ServiceApi objects, which group the collection of Split HTTP endpoints used by the SDK
10
+ * Factory of SplitApi objects, which group the collection of Split HTTP endpoints used by the SDK
12
11
  *
13
12
  * @param settings - validated settings object
14
13
  * @param platform - object containing environment-specific dependencies
@@ -123,18 +122,6 @@ export function splitApiFactory(settings, platform, telemetryTracker) {
123
122
  postMetricsUsage: function (body, headers) {
124
123
  var url = "".concat(urls.telemetry, "/v1/metrics/usage");
125
124
  return splitHttpClient(url, { method: 'POST', body: body, headers: headers }, telemetryTracker.trackHttp(TELEMETRY), true);
126
- },
127
- // Not used. Just here to satisfy the IServiceApi interface.
128
- fetchConfigs: function (since, noCache, till, rbSince) {
129
- var url = "".concat(urls.configs, "/v1/configs?since=").concat(since).concat(rbSince ? '&rbSince=' + rbSince : '').concat(filterQueryString || '').concat(till ? '&till=' + till : '');
130
- return splitHttpClient(url, noCache ? noCacheHeaderOptions : undefined);
131
- },
132
- fetchConfigsSegmentChanges: function (since, segmentName, noCache, till) {
133
- var url = "".concat(urls.configs, "/v1/segmentChanges/").concat(segmentName, "?since=").concat(since).concat(till ? '&till=' + till : '');
134
- return splitHttpClient(url, noCache ? noCacheHeaderOptions : undefined);
135
- },
136
- stop: function () {
137
- // no-op
138
125
  }
139
126
  };
140
127
  }
@@ -21,17 +21,19 @@ export function splitHttpClientFactory(settings, _a) {
21
21
  var commonHeaders = {
22
22
  'Accept': 'application/json',
23
23
  'Content-Type': 'application/json',
24
- 'Authorization': "Bearer ".concat(authorizationKey)
24
+ 'Authorization': "Bearer ".concat(authorizationKey),
25
+ 'SplitSDKVersion': version
25
26
  };
26
27
  if (ip)
27
28
  commonHeaders['SplitSDKMachineIP'] = ip;
28
29
  if (hostname)
29
30
  commonHeaders['SplitSDKMachineName'] = removeNonISO88591(hostname);
30
- return function httpClient(url, reqOpts, latencyTracker, logErrorsAsInfo, newVersionHeader) {
31
+ return function httpClient(url, reqOpts, latencyTracker, logErrorsAsInfo) {
31
32
  if (reqOpts === void 0) { reqOpts = {}; }
32
33
  if (latencyTracker === void 0) { latencyTracker = function () { }; }
34
+ if (logErrorsAsInfo === void 0) { logErrorsAsInfo = false; }
33
35
  var request = objectAssign({
34
- headers: decorateHeaders(settings, objectAssign(newVersionHeader ? { 'X-Harness-FME-SDK-Version': version } : { 'SplitSDKVersion': version }, commonHeaders, reqOpts.headers || {})),
36
+ headers: decorateHeaders(settings, objectAssign({}, commonHeaders, reqOpts.headers || {})),
35
37
  method: reqOpts.method || 'GET',
36
38
  body: reqOpts.body
37
39
  }, options);
@@ -0,0 +1,48 @@
1
+ import { objectAssign } from '../utils/lang/objectAssign';
2
+ /**
3
+ * This class provides a skeletal implementation of the ISplitsCacheAsync interface
4
+ * to minimize the effort required to implement this interface.
5
+ */
6
+ var AbstractSplitsCacheAsync = /** @class */ (function () {
7
+ function AbstractSplitsCacheAsync() {
8
+ }
9
+ AbstractSplitsCacheAsync.prototype.update = function (toAdd, toRemove, changeNumber) {
10
+ var _this = this;
11
+ return Promise.all([
12
+ this.setChangeNumber(changeNumber),
13
+ Promise.all(toAdd.map(function (addedFF) { return _this.addSplit(addedFF); })),
14
+ Promise.all(toRemove.map(function (removedFF) { return _this.removeSplit(removedFF.name); }))
15
+ ]).then(function (_a) {
16
+ var added = _a[1], removed = _a[2];
17
+ return added.some(function (result) { return result; }) || removed.some(function (result) { return result; });
18
+ });
19
+ };
20
+ // @TODO revisit segment-related methods ('usesSegments', 'getRegisteredSegments', 'registerSegments')
21
+ // noop, just keeping the interface. This is used by standalone client-side API only, and so only implemented by InMemory and InLocalStorage.
22
+ AbstractSplitsCacheAsync.prototype.usesSegments = function () {
23
+ return Promise.resolve(true);
24
+ };
25
+ /**
26
+ * Kill `name` split and set `defaultTreatment` and `changeNumber`.
27
+ * Used for SPLIT_KILL push notifications.
28
+ *
29
+ * @returns a promise that is resolved once the split kill operation is performed. The fulfillment value is a boolean: `true` if the operation successed updating the split or `false` if no split is updated,
30
+ * for instance, if the `changeNumber` is old, or if the split is not found (e.g., `/splitchanges` hasn't been fetched yet), or if the storage fails to apply the update.
31
+ * The promise will never be rejected.
32
+ */
33
+ AbstractSplitsCacheAsync.prototype.killLocally = function (name, defaultTreatment, changeNumber) {
34
+ var _this = this;
35
+ return this.getSplit(name).then(function (split) {
36
+ if (split && (!split.changeNumber || split.changeNumber < changeNumber)) {
37
+ var newSplit = objectAssign({}, split);
38
+ newSplit.killed = true;
39
+ newSplit.defaultTreatment = defaultTreatment;
40
+ newSplit.changeNumber = changeNumber;
41
+ return _this.addSplit(newSplit);
42
+ }
43
+ return false;
44
+ }).catch(function () { return false; });
45
+ };
46
+ return AbstractSplitsCacheAsync;
47
+ }());
48
+ export { AbstractSplitsCacheAsync };
@@ -0,0 +1,71 @@
1
+ import { objectAssign } from '../utils/lang/objectAssign';
2
+ import { IN_SEGMENT, IN_LARGE_SEGMENT } from '../utils/constants';
3
+ /**
4
+ * This class provides a skeletal implementation of the ISplitsCacheSync interface
5
+ * to minimize the effort required to implement this interface.
6
+ */
7
+ var AbstractSplitsCacheSync = /** @class */ (function () {
8
+ function AbstractSplitsCacheSync() {
9
+ }
10
+ AbstractSplitsCacheSync.prototype.update = function (toAdd, toRemove, changeNumber) {
11
+ var _this = this;
12
+ var updated = toAdd.map(function (addedFF) { return _this.addSplit(addedFF); }).some(function (result) { return result; });
13
+ updated = toRemove.map(function (removedFF) { return _this.removeSplit(removedFF.name); }).some(function (result) { return result; }) || updated;
14
+ this.setChangeNumber(changeNumber);
15
+ return updated;
16
+ };
17
+ AbstractSplitsCacheSync.prototype.getSplits = function (names) {
18
+ var _this = this;
19
+ var splits = {};
20
+ names.forEach(function (name) {
21
+ splits[name] = _this.getSplit(name);
22
+ });
23
+ return splits;
24
+ };
25
+ AbstractSplitsCacheSync.prototype.getAll = function () {
26
+ var _this = this;
27
+ return this.getSplitNames().map(function (key) { return _this.getSplit(key); });
28
+ };
29
+ /**
30
+ * Kill `name` split and set `defaultTreatment` and `changeNumber`.
31
+ * Used for SPLIT_KILL push notifications.
32
+ *
33
+ * @returns `true` if the operation successed updating the split, or `false` if no split is updated,
34
+ * for instance, if the `changeNumber` is old, or if the split is not found (e.g., `/splitchanges` hasn't been fetched yet), or if the storage fails to apply the update.
35
+ */
36
+ AbstractSplitsCacheSync.prototype.killLocally = function (name, defaultTreatment, changeNumber) {
37
+ var split = this.getSplit(name);
38
+ if (split && (!split.changeNumber || split.changeNumber < changeNumber)) {
39
+ var newSplit = objectAssign({}, split);
40
+ newSplit.killed = true;
41
+ newSplit.defaultTreatment = defaultTreatment;
42
+ newSplit.changeNumber = changeNumber;
43
+ return this.addSplit(newSplit);
44
+ }
45
+ return false;
46
+ };
47
+ return AbstractSplitsCacheSync;
48
+ }());
49
+ export { AbstractSplitsCacheSync };
50
+ /**
51
+ * Given a parsed split, it returns a boolean flagging if its conditions use segments matchers (rules & whitelists).
52
+ * This util is intended to simplify the implementation of `splitsCache::usesSegments` method
53
+ */
54
+ export function usesSegments(ruleEntity) {
55
+ var conditions = ruleEntity.conditions || [];
56
+ for (var i = 0; i < conditions.length; i++) {
57
+ var matchers = conditions[i].matcherGroup.matchers;
58
+ for (var j = 0; j < matchers.length; j++) {
59
+ var matcher = matchers[j].matcherType;
60
+ if (matcher === IN_SEGMENT || matcher === IN_LARGE_SEGMENT)
61
+ return true;
62
+ }
63
+ }
64
+ var excluded = ruleEntity.excluded;
65
+ if (excluded && excluded.segments && excluded.segments.length > 0)
66
+ return true;
67
+ return false;
68
+ }
69
+ export function usesSegmentsSync(storage) {
70
+ return storage.splits.usesSegments() || storage.rbSegments.usesSegments();
71
+ }
@@ -12,16 +12,16 @@ var KeyBuilder = /** @class */ (function () {
12
12
  KeyBuilder.prototype.buildTrafficTypeKey = function (trafficType) {
13
13
  return "".concat(this.prefix, ".trafficType.").concat(trafficType);
14
14
  };
15
- KeyBuilder.prototype.buildSetKey = function (set) {
16
- return "".concat(this.prefix, ".flagSet.").concat(set);
15
+ KeyBuilder.prototype.buildFlagSetKey = function (flagSet) {
16
+ return "".concat(this.prefix, ".flagSet.").concat(flagSet);
17
17
  };
18
- KeyBuilder.prototype.buildDefinitionKey = function (definitionName) {
19
- return "".concat(this.prefix, ".split.").concat(definitionName);
18
+ KeyBuilder.prototype.buildSplitKey = function (splitName) {
19
+ return "".concat(this.prefix, ".split.").concat(splitName);
20
20
  };
21
- KeyBuilder.prototype.buildDefinitionsTillKey = function () {
21
+ KeyBuilder.prototype.buildSplitsTillKey = function () {
22
22
  return "".concat(this.prefix, ".splits.till");
23
23
  };
24
- KeyBuilder.prototype.buildDefinitionKeyPrefix = function () {
24
+ KeyBuilder.prototype.buildSplitKeyPrefix = function () {
25
25
  return "".concat(this.prefix, ".split.");
26
26
  };
27
27
  KeyBuilder.prototype.buildRBSegmentKey = function (rbsegmentName) {
@@ -6,7 +6,7 @@ var KeyBuilderCS = /** @class */ (function (_super) {
6
6
  function KeyBuilderCS(prefix, matchingKey) {
7
7
  var _this = _super.call(this, prefix) || this;
8
8
  _this.matchingKey = matchingKey;
9
- _this.regexDefinitionsCacheKey = new RegExp("^".concat(prefix, "\\.(splits?|trafficType|flagSet)\\."));
9
+ _this.regexSplitsCacheKey = new RegExp("^".concat(prefix, "\\.(splits?|trafficType|flagSet)\\."));
10
10
  return _this;
11
11
  }
12
12
  /**
@@ -23,19 +23,19 @@ var KeyBuilderCS = /** @class */ (function (_super) {
23
23
  KeyBuilderCS.prototype.buildLastUpdatedKey = function () {
24
24
  return "".concat(this.prefix, ".splits.lastUpdated");
25
25
  };
26
- KeyBuilderCS.prototype.isDefinitionsCacheKey = function (key) {
27
- return this.regexDefinitionsCacheKey.test(key);
26
+ KeyBuilderCS.prototype.isSplitsCacheKey = function (key) {
27
+ return this.regexSplitsCacheKey.test(key);
28
28
  };
29
29
  KeyBuilderCS.prototype.buildTillKey = function () {
30
30
  return "".concat(this.prefix, ".").concat(this.matchingKey, ".segments.till");
31
31
  };
32
- KeyBuilderCS.prototype.isDefinitionKey = function (key) {
32
+ KeyBuilderCS.prototype.isSplitKey = function (key) {
33
33
  return startsWith(key, "".concat(this.prefix, ".split."));
34
34
  };
35
35
  KeyBuilderCS.prototype.isRBSegmentKey = function (key) {
36
36
  return startsWith(key, "".concat(this.prefix, ".rbsegment."));
37
37
  };
38
- KeyBuilderCS.prototype.buildDefinitionsWithSegmentCountKey = function () {
38
+ KeyBuilderCS.prototype.buildSplitsWithSegmentCountKey = function () {
39
39
  return "".concat(this.prefix, ".splits.usingSegments");
40
40
  };
41
41
  KeyBuilderCS.prototype.buildLastClear = function () {
@@ -36,8 +36,8 @@ var KeyBuilderSS = /** @class */ (function (_super) {
36
36
  KeyBuilderSS.prototype.buildEventsKey = function () {
37
37
  return "".concat(this.prefix, ".events");
38
38
  };
39
- KeyBuilderSS.prototype.searchPatternForDefinitionKeys = function () {
40
- return "".concat(this.buildDefinitionKeyPrefix(), "*");
39
+ KeyBuilderSS.prototype.searchPatternForSplitKeys = function () {
40
+ return "".concat(this.buildSplitKeyPrefix(), "*");
41
41
  };
42
42
  KeyBuilderSS.prototype.searchPatternForRBSegmentKeys = function () {
43
43
  return "".concat(this.buildRBSegmentKeyPrefix(), "*");
@@ -6,14 +6,14 @@ import { getMatching } from '../utils/key';
6
6
  export function getRolloutPlan(log, storage, options) {
7
7
  if (options === void 0) { options = {}; }
8
8
  var keys = options.keys, exposeSegments = options.exposeSegments;
9
- var definitions = storage.definitions, segments = storage.segments, rbSegments = storage.rbSegments;
9
+ var splits = storage.splits, segments = storage.segments, rbSegments = storage.rbSegments;
10
10
  log.debug("storage: get feature flags".concat(keys ? ", and memberships for keys: ".concat(keys) : '').concat(exposeSegments ? ', and segments' : ''));
11
11
  return {
12
12
  splitChanges: {
13
13
  ff: {
14
- t: definitions.getChangeNumber(),
14
+ t: splits.getChangeNumber(),
15
15
  s: -1,
16
- d: definitions.getAll(),
16
+ d: splits.getAll(),
17
17
  },
18
18
  rbs: {
19
19
  t: rbSegments.getChangeNumber(),
@@ -4,8 +4,9 @@ import { AbstractMySegmentsCacheSync } from '../AbstractMySegmentsCacheSync';
4
4
  import { DEFINED } from './constants';
5
5
  var MySegmentsCacheInLocal = /** @class */ (function (_super) {
6
6
  __extends(MySegmentsCacheInLocal, _super);
7
- function MySegmentsCacheInLocal(_log, keys, storage) {
7
+ function MySegmentsCacheInLocal(log, keys, storage) {
8
8
  var _this = _super.call(this) || this;
9
+ _this.log = log;
9
10
  _this.keys = keys;
10
11
  _this.storage = storage;
11
12
  return _this;
@@ -1,6 +1,6 @@
1
1
  import { isFiniteNumber, isNaNNumber, toNumber } from '../../utils/lang';
2
2
  import { setToArray } from '../../utils/lang/sets';
3
- import { usesSegments } from '../AbstractDefinitionsCacheSync';
3
+ import { usesSegments } from '../AbstractSplitsCacheSync';
4
4
  import { LOG_PREFIX } from './constants';
5
5
  var RBSegmentsCacheInLocal = /** @class */ (function () {
6
6
  function RBSegmentsCacheInLocal(settings, keys, storage) {
@@ -16,7 +16,7 @@ var RBSegmentsCacheInLocal = /** @class */ (function () {
16
16
  RBSegmentsCacheInLocal.prototype.update = function (toAdd, toRemove, changeNumber) {
17
17
  var _this = this;
18
18
  var updated = toAdd.map(function (toAdd) { return _this.add(toAdd); }).some(function (result) { return result; });
19
- updated = toRemove.map(function (toRemove) { return _this.remove(toRemove); }).some(function (result) { return result; }) || updated;
19
+ updated = toRemove.map(function (toRemove) { return _this.remove(toRemove.name); }).some(function (result) { return result; }) || updated;
20
20
  this.setChangeNumber(changeNumber);
21
21
  return updated;
22
22
  };
@@ -30,7 +30,7 @@ var RBSegmentsCacheInLocal = /** @class */ (function () {
30
30
  }
31
31
  };
32
32
  RBSegmentsCacheInLocal.prototype.updateSegmentCount = function (diff) {
33
- var segmentsCountKey = this.keys.buildDefinitionsWithSegmentCountKey();
33
+ var segmentsCountKey = this.keys.buildSplitsWithSegmentCountKey();
34
34
  var count = toNumber(this.storage.getItem(segmentsCountKey)) + diff;
35
35
  if (count > 0)
36
36
  this.storage.setItem(segmentsCountKey, count + '');
@@ -96,10 +96,10 @@ var RBSegmentsCacheInLocal = /** @class */ (function () {
96
96
  return n;
97
97
  };
98
98
  RBSegmentsCacheInLocal.prototype.usesSegments = function () {
99
- var storedCount = this.storage.getItem(this.keys.buildDefinitionsWithSegmentCountKey());
100
- var definitionsWithSegmentsCount = storedCount === null ? 0 : toNumber(storedCount);
101
- return isFiniteNumber(definitionsWithSegmentsCount) ?
102
- definitionsWithSegmentsCount > 0 :
99
+ var storedCount = this.storage.getItem(this.keys.buildSplitsWithSegmentCountKey());
100
+ var splitsWithSegmentsCount = storedCount === null ? 0 : toNumber(storedCount);
101
+ return isFiniteNumber(splitsWithSegmentsCount) ?
102
+ splitsWithSegmentsCount > 0 :
103
103
  true;
104
104
  };
105
105
  return RBSegmentsCacheInLocal;