@splitsoftware/splitio-commons 2.12.0 → 3.0.0-rc.1

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 (395) hide show
  1. package/CHANGES.txt +19 -1
  2. package/cjs/evaluator/condition/engineUtils.js +2 -2
  3. package/cjs/evaluator/fallbackConfigsCalculator/fallbackSanitizer/index.js +70 -0
  4. package/cjs/evaluator/fallbackConfigsCalculator/index.js +25 -0
  5. package/cjs/evaluator/fallbackTreatmentsCalculator/fallbackSanitizer/index.js +5 -8
  6. package/cjs/evaluator/fallbackTreatmentsCalculator/index.js +21 -32
  7. package/cjs/evaluator/index.js +73 -48
  8. package/cjs/evaluator/matchers/whitelist.js +1 -1
  9. package/cjs/integrations/pluggable.js +1 -1
  10. package/cjs/listeners/browser.js +4 -3
  11. package/cjs/listeners/node.js +4 -4
  12. package/cjs/logger/constants.js +15 -21
  13. package/cjs/logger/index.js +1 -1
  14. package/cjs/logger/messages/debug.js +6 -7
  15. package/cjs/logger/messages/error.js +4 -4
  16. package/cjs/logger/messages/info.js +2 -4
  17. package/cjs/logger/messages/warn.js +9 -10
  18. package/cjs/platform/browser.js +15 -0
  19. package/cjs/platform/getEventSource/browser.js +8 -0
  20. package/cjs/platform/getEventSource/eventsource.js +480 -0
  21. package/cjs/platform/getEventSource/node.js +26 -0
  22. package/cjs/platform/getFetch/browser.js +9 -0
  23. package/cjs/platform/getFetch/node.js +27 -0
  24. package/cjs/platform/getOptions/node.js +25 -0
  25. package/cjs/platform/node.js +17 -0
  26. package/cjs/readiness/constants.js +5 -4
  27. package/cjs/readiness/readinessManager.js +22 -22
  28. package/cjs/readiness/sdkReadinessManager.js +0 -16
  29. package/cjs/sdkClient/client.js +9 -35
  30. package/cjs/sdkClient/clientAttributesDecoration.js +3 -3
  31. package/cjs/sdkClient/clientInputValidation.js +38 -81
  32. package/cjs/sdkClient/identity.js +1 -1
  33. package/cjs/sdkClient/sdkClient.js +4 -49
  34. package/cjs/sdkClient/sdkLifecycle.js +71 -0
  35. package/cjs/sdkClient/trackMethod.js +56 -0
  36. package/cjs/sdkFactory/index.js +13 -50
  37. package/cjs/sdkManager/index.js +5 -5
  38. package/cjs/services/authProvider.js +67 -0
  39. package/cjs/services/secureSplitHttpClient.js +39 -0
  40. package/cjs/services/splitApi.js +24 -14
  41. package/cjs/services/splitHttpClient.js +1 -1
  42. package/cjs/storages/AbstractDefinitionsCacheAsync.js +51 -0
  43. package/cjs/storages/AbstractDefinitionsCacheSync.js +76 -0
  44. package/cjs/storages/KeyBuilder.js +16 -16
  45. package/cjs/storages/KeyBuilderCS.js +17 -17
  46. package/cjs/storages/KeyBuilderSS.js +16 -16
  47. package/cjs/storages/getRolloutPlan.js +4 -4
  48. package/cjs/storages/inLocalStorage/DefinitionsCacheInLocal.js +194 -0
  49. package/cjs/storages/inLocalStorage/MySegmentsCacheInLocal.js +1 -1
  50. package/cjs/storages/inLocalStorage/RBSegmentsCacheInLocal.js +10 -10
  51. package/cjs/storages/inLocalStorage/index.js +6 -6
  52. package/cjs/storages/inLocalStorage/validateCache.js +3 -3
  53. package/cjs/storages/inMemory/DefinitionsCacheInMemory.js +121 -0
  54. package/cjs/storages/inMemory/ImpressionCountsCacheInMemory.js +1 -1
  55. package/cjs/storages/inMemory/InMemoryStorage.js +4 -4
  56. package/cjs/storages/inMemory/InMemoryStorageCS.js +5 -5
  57. package/cjs/storages/inMemory/MySegmentsCacheInMemory.js +1 -1
  58. package/cjs/storages/inMemory/RBSegmentsCacheInMemory.js +5 -5
  59. package/cjs/storages/inMemory/SegmentsCacheInMemory.js +1 -1
  60. package/cjs/storages/inMemory/TelemetryCacheInMemory.js +5 -5
  61. package/cjs/storages/inRedis/DefinitionsCacheInRedis.js +243 -0
  62. package/cjs/storages/inRedis/EventsCacheInRedis.js +1 -1
  63. package/cjs/storages/inRedis/ImpressionCountsCacheInRedis.js +5 -5
  64. package/cjs/storages/inRedis/ImpressionsCacheInRedis.js +1 -1
  65. package/cjs/storages/inRedis/RBSegmentsCacheInRedis.js +1 -1
  66. package/cjs/storages/inRedis/RedisAdapter.js +8 -8
  67. package/cjs/storages/inRedis/TelemetryCacheInRedis.js +7 -7
  68. package/cjs/storages/inRedis/UniqueKeysCacheInRedis.js +3 -3
  69. package/cjs/storages/inRedis/index.js +2 -2
  70. package/cjs/storages/pluggable/DefinitionsCachePluggable.js +212 -0
  71. package/cjs/storages/pluggable/EventsCachePluggable.js +1 -1
  72. package/cjs/storages/pluggable/ImpressionCountsCachePluggable.js +6 -6
  73. package/cjs/storages/pluggable/RBSegmentsCachePluggable.js +1 -1
  74. package/cjs/storages/pluggable/TelemetryCachePluggable.js +7 -7
  75. package/cjs/storages/pluggable/UniqueKeysCachePluggable.js +2 -2
  76. package/cjs/storages/pluggable/index.js +5 -5
  77. package/cjs/storages/pluggable/wrapperAdapter.js +1 -1
  78. package/cjs/storages/setRolloutPlan.js +6 -6
  79. package/cjs/storages/utils.js +6 -6
  80. package/cjs/sync/offline/splitsParser/parseCondition.js +1 -1
  81. package/cjs/sync/offline/syncTasks/fromObjectSyncTask.js +5 -5
  82. package/cjs/sync/polling/fetchers/segmentChangesFetcher.js +1 -1
  83. package/cjs/sync/polling/fetchers/splitChangesFetcher.js +24 -15
  84. package/cjs/sync/polling/pollingManagerCS.js +18 -18
  85. package/cjs/sync/polling/pollingManagerSS.js +13 -13
  86. package/cjs/sync/polling/syncTasks/definitionsSyncTask.js +12 -0
  87. package/cjs/sync/polling/updaters/{splitChangesUpdater.js → definitionChangesUpdater.js} +72 -64
  88. package/cjs/sync/polling/updaters/mySegmentsUpdater.js +3 -3
  89. package/cjs/sync/polling/updaters/segmentChangesUpdater.js +6 -6
  90. package/cjs/sync/streaming/SSEClient/index.js +2 -2
  91. package/cjs/sync/streaming/SSEHandler/NotificationKeeper.js +1 -1
  92. package/cjs/sync/streaming/SSEHandler/index.js +1 -1
  93. package/cjs/sync/streaming/UpdateWorkers/{SplitsUpdateWorker.js → DefinitionsUpdateWorker.js} +18 -18
  94. package/cjs/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.js +2 -2
  95. package/cjs/sync/streaming/UpdateWorkers/SegmentsUpdateWorker.js +2 -2
  96. package/cjs/sync/streaming/constants.js +3 -3
  97. package/cjs/sync/streaming/parseUtils.js +12 -12
  98. package/cjs/sync/streaming/pushManager.js +14 -14
  99. package/cjs/sync/submitters/impressionsSubmitter.js +6 -6
  100. package/cjs/sync/submitters/submitter.js +1 -1
  101. package/cjs/sync/submitters/telemetrySubmitter.js +1 -2
  102. package/cjs/sync/syncManagerOnline.js +9 -6
  103. package/cjs/trackers/eventTracker.js +10 -12
  104. package/cjs/trackers/impressionObserver/buildKey.js +1 -1
  105. package/cjs/trackers/impressionsTracker.js +37 -20
  106. package/cjs/trackers/uniqueKeysTracker.js +1 -1
  107. package/cjs/utils/Backoff.js +20 -0
  108. package/cjs/utils/EventEmitter.js +391 -0
  109. package/cjs/utils/filter/bloomFilter.js +37 -0
  110. package/cjs/utils/inputValidation/apiKey.js +1 -1
  111. package/cjs/utils/inputValidation/attribute.js +2 -2
  112. package/cjs/utils/inputValidation/{split.js → definition.js} +10 -10
  113. package/cjs/utils/inputValidation/{splitExistence.js → definitionExistence.js} +6 -6
  114. package/cjs/utils/inputValidation/definitions.js +25 -0
  115. package/cjs/utils/inputValidation/eventProperties.js +1 -1
  116. package/cjs/utils/inputValidation/index.js +7 -7
  117. package/cjs/utils/inputValidation/isOperational.js +4 -4
  118. package/cjs/utils/inputValidation/target.js +22 -0
  119. package/cjs/utils/labels/index.js +3 -3
  120. package/cjs/utils/lang/index.js +1 -1
  121. package/cjs/utils/lang/sets.js +4 -4
  122. package/cjs/utils/promise/timeout.js +1 -1
  123. package/cjs/utils/settingsValidation/splitFilters.js +4 -4
  124. package/cjs/utils/settingsValidation/url.js +6 -6
  125. package/esm/evaluator/condition/engineUtils.js +2 -2
  126. package/esm/evaluator/fallbackConfigsCalculator/fallbackSanitizer/index.js +64 -0
  127. package/esm/evaluator/fallbackConfigsCalculator/index.js +21 -0
  128. package/esm/evaluator/fallbackTreatmentsCalculator/fallbackSanitizer/index.js +5 -8
  129. package/esm/evaluator/fallbackTreatmentsCalculator/index.js +21 -33
  130. package/esm/evaluator/index.js +72 -48
  131. package/esm/evaluator/matchers/whitelist.js +1 -1
  132. package/esm/integrations/pluggable.js +1 -1
  133. package/esm/listeners/browser.js +4 -3
  134. package/esm/listeners/node.js +4 -4
  135. package/esm/logger/constants.js +12 -18
  136. package/esm/logger/index.js +1 -1
  137. package/esm/logger/messages/debug.js +5 -6
  138. package/esm/logger/messages/error.js +3 -3
  139. package/esm/logger/messages/info.js +1 -3
  140. package/esm/logger/messages/warn.js +8 -9
  141. package/esm/platform/browser.js +12 -0
  142. package/esm/platform/getEventSource/browser.js +4 -0
  143. package/esm/platform/getEventSource/eventsource.js +480 -0
  144. package/esm/platform/getEventSource/node.js +20 -0
  145. package/esm/platform/getFetch/browser.js +5 -0
  146. package/esm/platform/getFetch/node.js +22 -0
  147. package/esm/platform/getOptions/node.js +20 -0
  148. package/esm/platform/node.js +14 -0
  149. package/esm/readiness/constants.js +4 -3
  150. package/esm/readiness/readinessManager.js +23 -23
  151. package/esm/readiness/sdkReadinessManager.js +1 -17
  152. package/esm/sdkClient/client.js +10 -37
  153. package/esm/sdkClient/clientAttributesDecoration.js +3 -3
  154. package/esm/sdkClient/clientInputValidation.js +40 -83
  155. package/esm/sdkClient/identity.js +1 -1
  156. package/esm/sdkClient/sdkClient.js +4 -49
  157. package/esm/sdkClient/sdkLifecycle.js +67 -0
  158. package/esm/sdkClient/trackMethod.js +52 -0
  159. package/esm/sdkFactory/index.js +14 -51
  160. package/esm/sdkManager/index.js +6 -6
  161. package/esm/services/authProvider.js +63 -0
  162. package/esm/services/secureSplitHttpClient.js +35 -0
  163. package/esm/services/splitApi.js +24 -14
  164. package/esm/services/splitHttpClient.js +1 -1
  165. package/esm/storages/AbstractDefinitionsCacheAsync.js +48 -0
  166. package/esm/storages/AbstractDefinitionsCacheSync.js +71 -0
  167. package/esm/storages/KeyBuilder.js +16 -16
  168. package/esm/storages/KeyBuilderCS.js +16 -16
  169. package/esm/storages/KeyBuilderSS.js +15 -15
  170. package/esm/storages/getRolloutPlan.js +4 -4
  171. package/esm/storages/inLocalStorage/DefinitionsCacheInLocal.js +191 -0
  172. package/esm/storages/inLocalStorage/RBSegmentsCacheInLocal.js +7 -7
  173. package/esm/storages/inLocalStorage/index.js +6 -6
  174. package/esm/storages/inLocalStorage/validateCache.js +3 -3
  175. package/esm/storages/inMemory/DefinitionsCacheInMemory.js +118 -0
  176. package/esm/storages/inMemory/ImpressionCountsCacheInMemory.js +1 -1
  177. package/esm/storages/inMemory/InMemoryStorage.js +4 -4
  178. package/esm/storages/inMemory/InMemoryStorageCS.js +5 -5
  179. package/esm/storages/inMemory/RBSegmentsCacheInMemory.js +2 -2
  180. package/esm/storages/inMemory/SegmentsCacheInMemory.js +1 -1
  181. package/esm/storages/inMemory/TelemetryCacheInMemory.js +5 -5
  182. package/esm/storages/inRedis/DefinitionsCacheInRedis.js +240 -0
  183. package/esm/storages/inRedis/EventsCacheInRedis.js +1 -1
  184. package/esm/storages/inRedis/ImpressionCountsCacheInRedis.js +4 -4
  185. package/esm/storages/inRedis/RBSegmentsCacheInRedis.js +1 -1
  186. package/esm/storages/inRedis/RedisAdapter.js +7 -7
  187. package/esm/storages/inRedis/TelemetryCacheInRedis.js +7 -7
  188. package/esm/storages/inRedis/UniqueKeysCacheInRedis.js +1 -1
  189. package/esm/storages/inRedis/index.js +2 -2
  190. package/esm/storages/pluggable/DefinitionsCachePluggable.js +209 -0
  191. package/esm/storages/pluggable/EventsCachePluggable.js +1 -1
  192. package/esm/storages/pluggable/ImpressionCountsCachePluggable.js +5 -5
  193. package/esm/storages/pluggable/RBSegmentsCachePluggable.js +1 -1
  194. package/esm/storages/pluggable/TelemetryCachePluggable.js +7 -7
  195. package/esm/storages/pluggable/UniqueKeysCachePluggable.js +1 -1
  196. package/esm/storages/pluggable/index.js +4 -4
  197. package/esm/storages/pluggable/wrapperAdapter.js +1 -1
  198. package/esm/storages/setRolloutPlan.js +6 -6
  199. package/esm/storages/utils.js +6 -6
  200. package/esm/sync/offline/splitsParser/parseCondition.js +1 -1
  201. package/esm/sync/offline/syncTasks/fromObjectSyncTask.js +6 -6
  202. package/esm/sync/polling/fetchers/splitChangesFetcher.js +25 -16
  203. package/esm/sync/polling/pollingManagerCS.js +15 -15
  204. package/esm/sync/polling/pollingManagerSS.js +13 -13
  205. package/esm/sync/polling/syncTasks/definitionsSyncTask.js +8 -0
  206. package/esm/sync/polling/updaters/definitionChangesUpdater.js +200 -0
  207. package/esm/sync/polling/updaters/mySegmentsUpdater.js +3 -3
  208. package/esm/sync/polling/updaters/segmentChangesUpdater.js +7 -7
  209. package/esm/sync/streaming/SSEClient/index.js +2 -2
  210. package/esm/sync/streaming/SSEHandler/NotificationKeeper.js +2 -2
  211. package/esm/sync/streaming/SSEHandler/index.js +2 -2
  212. package/esm/sync/streaming/UpdateWorkers/{SplitsUpdateWorker.js → DefinitionsUpdateWorker.js} +17 -17
  213. package/esm/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.js +2 -2
  214. package/esm/sync/streaming/UpdateWorkers/SegmentsUpdateWorker.js +2 -2
  215. package/esm/sync/streaming/constants.js +2 -2
  216. package/esm/sync/streaming/parseUtils.js +10 -10
  217. package/esm/sync/streaming/pushManager.js +16 -16
  218. package/esm/sync/submitters/impressionsSubmitter.js +6 -6
  219. package/esm/sync/submitters/submitter.js +1 -1
  220. package/esm/sync/submitters/telemetrySubmitter.js +1 -2
  221. package/esm/sync/syncManagerOnline.js +8 -5
  222. package/esm/trackers/eventTracker.js +10 -12
  223. package/esm/trackers/impressionObserver/buildKey.js +1 -1
  224. package/esm/trackers/impressionsTracker.js +38 -21
  225. package/esm/trackers/uniqueKeysTracker.js +1 -1
  226. package/esm/utils/Backoff.js +20 -0
  227. package/esm/utils/EventEmitter.js +387 -0
  228. package/esm/utils/filter/bloomFilter.js +33 -0
  229. package/esm/utils/inputValidation/apiKey.js +1 -1
  230. package/esm/utils/inputValidation/attribute.js +2 -2
  231. package/esm/utils/inputValidation/{split.js → definition.js} +8 -8
  232. package/esm/utils/inputValidation/definitionExistence.js +15 -0
  233. package/esm/utils/inputValidation/definitions.js +21 -0
  234. package/esm/utils/inputValidation/index.js +3 -3
  235. package/esm/utils/inputValidation/isOperational.js +4 -4
  236. package/esm/utils/inputValidation/target.js +18 -0
  237. package/esm/utils/labels/index.js +2 -2
  238. package/esm/utils/lang/sets.js +4 -4
  239. package/esm/utils/promise/timeout.js +1 -1
  240. package/esm/utils/settingsValidation/splitFilters.js +4 -4
  241. package/esm/utils/settingsValidation/url.js +6 -6
  242. package/package.json +15 -6
  243. package/src/dtos/types.ts +65 -70
  244. package/src/evaluator/Engine.ts +4 -4
  245. package/src/evaluator/combiners/and.ts +3 -3
  246. package/src/evaluator/combiners/ifelseif.ts +2 -2
  247. package/src/evaluator/condition/engineUtils.ts +2 -2
  248. package/src/evaluator/condition/index.ts +3 -3
  249. package/src/evaluator/fallbackConfigsCalculator/fallbackSanitizer/index.ts +76 -0
  250. package/src/evaluator/fallbackConfigsCalculator/index.ts +24 -0
  251. package/src/evaluator/fallbackTreatmentsCalculator/fallbackSanitizer/index.ts +5 -7
  252. package/src/evaluator/fallbackTreatmentsCalculator/index.ts +27 -41
  253. package/src/evaluator/index.ts +86 -51
  254. package/src/evaluator/matchers/dependency.ts +2 -2
  255. package/src/evaluator/matchers/matcherTypes.ts +2 -2
  256. package/src/evaluator/matchers/prerequisites.ts +4 -4
  257. package/src/evaluator/matchers/rbsegment.ts +2 -2
  258. package/src/evaluator/matchers/whitelist.ts +2 -2
  259. package/src/evaluator/matchersTransform/index.ts +2 -2
  260. package/src/evaluator/matchersTransform/whitelist.ts +2 -2
  261. package/src/evaluator/parser/index.ts +4 -4
  262. package/src/evaluator/treatments/index.ts +2 -2
  263. package/src/evaluator/types.ts +6 -6
  264. package/src/evaluator/value/index.ts +1 -1
  265. package/src/integrations/pluggable.ts +1 -1
  266. package/src/listeners/browser.ts +11 -8
  267. package/src/listeners/node.ts +2 -5
  268. package/src/logger/constants.ts +12 -18
  269. package/src/logger/messages/debug.ts +5 -6
  270. package/src/logger/messages/error.ts +3 -3
  271. package/src/logger/messages/info.ts +1 -3
  272. package/src/logger/messages/warn.ts +8 -9
  273. package/src/platform/browser.ts +14 -0
  274. package/src/platform/getEventSource/browser.ts +4 -0
  275. package/src/platform/getEventSource/eventsource.js +519 -0
  276. package/src/platform/getEventSource/node.ts +23 -0
  277. package/src/platform/getFetch/browser.ts +5 -0
  278. package/src/platform/getFetch/node.ts +27 -0
  279. package/src/platform/getOptions/node.ts +24 -0
  280. package/src/platform/node.ts +16 -0
  281. package/src/readiness/constants.ts +4 -3
  282. package/src/readiness/readinessManager.ts +22 -22
  283. package/src/readiness/sdkReadinessManager.ts +1 -16
  284. package/src/readiness/types.ts +10 -16
  285. package/src/sdkClient/client.ts +11 -41
  286. package/src/sdkClient/clientInputValidation.ts +44 -84
  287. package/src/sdkClient/sdkClient.ts +5 -54
  288. package/src/sdkClient/sdkLifecycle.ts +79 -0
  289. package/src/sdkClient/trackMethod.ts +59 -0
  290. package/src/sdkFactory/index.ts +15 -59
  291. package/src/sdkFactory/types.ts +19 -16
  292. package/src/sdkManager/index.ts +15 -15
  293. package/src/services/authProvider.ts +86 -0
  294. package/src/services/secureSplitHttpClient.ts +44 -0
  295. package/src/services/splitApi.ts +14 -2
  296. package/src/services/types.ts +7 -2
  297. package/src/storages/AbstractDefinitionsCacheAsync.ts +63 -0
  298. package/src/storages/AbstractDefinitionsCacheSync.ts +95 -0
  299. package/src/storages/KeyBuilder.ts +6 -6
  300. package/src/storages/KeyBuilderCS.ts +6 -6
  301. package/src/storages/KeyBuilderSS.ts +2 -2
  302. package/src/storages/getRolloutPlan.ts +3 -3
  303. package/src/storages/inLocalStorage/DefinitionsCacheInLocal.ts +234 -0
  304. package/src/storages/inLocalStorage/RBSegmentsCacheInLocal.ts +8 -8
  305. package/src/storages/inLocalStorage/index.ts +6 -6
  306. package/src/storages/inLocalStorage/validateCache.ts +4 -4
  307. package/src/storages/inMemory/DefinitionsCacheInMemory.ts +130 -0
  308. package/src/storages/inMemory/InMemoryStorage.ts +4 -4
  309. package/src/storages/inMemory/InMemoryStorageCS.ts +5 -5
  310. package/src/storages/inMemory/RBSegmentsCacheInMemory.ts +3 -3
  311. package/src/storages/inMemory/SegmentsCacheInMemory.ts +1 -1
  312. package/src/storages/inMemory/TelemetryCacheInMemory.ts +5 -5
  313. package/src/storages/inRedis/{SplitsCacheInRedis.ts → DefinitionsCacheInRedis.ts} +69 -69
  314. package/src/storages/inRedis/RBSegmentsCacheInRedis.ts +2 -2
  315. package/src/storages/inRedis/index.ts +2 -2
  316. package/src/storages/pluggable/DefinitionsCachePluggable.ts +230 -0
  317. package/src/storages/pluggable/RBSegmentsCachePluggable.ts +2 -2
  318. package/src/storages/pluggable/index.ts +2 -2
  319. package/src/storages/setRolloutPlan.ts +7 -7
  320. package/src/storages/types.ts +34 -29
  321. package/src/sync/offline/splitsParser/parseCondition.ts +2 -2
  322. package/src/sync/offline/splitsParser/splitsParserFromSettings.ts +3 -3
  323. package/src/sync/offline/splitsParser/types.ts +6 -3
  324. package/src/sync/offline/syncManagerOffline.ts +2 -2
  325. package/src/sync/offline/syncTasks/fromObjectSyncTask.ts +14 -14
  326. package/src/sync/polling/fetchers/splitChangesFetcher.ts +58 -23
  327. package/src/sync/polling/fetchers/types.ts +5 -3
  328. package/src/sync/polling/pollingManagerCS.ts +16 -14
  329. package/src/sync/polling/pollingManagerSS.ts +15 -13
  330. package/src/sync/polling/syncTasks/{splitsSyncTask.ts → definitionsSyncTask.ts} +11 -12
  331. package/src/sync/polling/types.ts +3 -3
  332. package/src/sync/polling/updaters/definitionChangesUpdater.ts +239 -0
  333. package/src/sync/polling/updaters/mySegmentsUpdater.ts +3 -3
  334. package/src/sync/polling/updaters/segmentChangesUpdater.ts +7 -7
  335. package/src/sync/streaming/AuthClient/index.ts +2 -2
  336. package/src/sync/streaming/AuthClient/types.ts +14 -11
  337. package/src/sync/streaming/SSEClient/index.ts +2 -2
  338. package/src/sync/streaming/SSEClient/types.ts +2 -2
  339. package/src/sync/streaming/SSEHandler/NotificationKeeper.ts +2 -2
  340. package/src/sync/streaming/SSEHandler/index.ts +2 -2
  341. package/src/sync/streaming/UpdateWorkers/{SplitsUpdateWorker.ts → DefinitionsUpdateWorker.ts} +21 -21
  342. package/src/sync/streaming/constants.ts +2 -2
  343. package/src/sync/streaming/parseUtils.ts +12 -12
  344. package/src/sync/streaming/pushManager.ts +18 -18
  345. package/src/sync/streaming/types.ts +2 -2
  346. package/src/sync/submitters/impressionsSubmitter.ts +9 -9
  347. package/src/sync/submitters/telemetrySubmitter.ts +1 -2
  348. package/src/sync/submitters/types.ts +3 -0
  349. package/src/sync/syncManagerOnline.ts +9 -5
  350. package/src/trackers/eventTracker.ts +7 -10
  351. package/src/trackers/impressionsTracker.ts +42 -26
  352. package/src/trackers/types.ts +3 -1
  353. package/src/utils/Backoff.ts +21 -0
  354. package/src/utils/EventEmitter.js +444 -0
  355. package/src/utils/filter/bloomFilter.ts +38 -0
  356. package/src/utils/inputValidation/definition.ts +27 -0
  357. package/src/utils/inputValidation/definitionExistence.ts +19 -0
  358. package/src/utils/inputValidation/definitions.ts +21 -0
  359. package/src/utils/inputValidation/index.ts +3 -3
  360. package/src/utils/inputValidation/isOperational.ts +4 -4
  361. package/src/utils/inputValidation/target.ts +21 -0
  362. package/src/utils/inputValidation/trafficTypeExistence.ts +2 -2
  363. package/src/utils/jwt/types.ts +1 -1
  364. package/src/utils/labels/index.ts +2 -2
  365. package/src/utils/lang/sets.ts +4 -2
  366. package/src/utils/settingsValidation/splitFilters.ts +3 -3
  367. package/src/utils/settingsValidation/url.ts +1 -1
  368. package/types/splitio.d.ts +222 -11
  369. package/cjs/storages/AbstractSplitsCacheAsync.js +0 -51
  370. package/cjs/storages/AbstractSplitsCacheSync.js +0 -76
  371. package/cjs/storages/inLocalStorage/SplitsCacheInLocal.js +0 -194
  372. package/cjs/storages/inMemory/SplitsCacheInMemory.js +0 -121
  373. package/cjs/storages/inRedis/SplitsCacheInRedis.js +0 -243
  374. package/cjs/storages/pluggable/SplitsCachePluggable.js +0 -212
  375. package/cjs/sync/polling/syncTasks/splitsSyncTask.js +0 -13
  376. package/cjs/utils/inputValidation/splits.js +0 -25
  377. package/esm/storages/AbstractSplitsCacheAsync.js +0 -48
  378. package/esm/storages/AbstractSplitsCacheSync.js +0 -71
  379. package/esm/storages/inLocalStorage/SplitsCacheInLocal.js +0 -191
  380. package/esm/storages/inMemory/SplitsCacheInMemory.js +0 -118
  381. package/esm/storages/inRedis/SplitsCacheInRedis.js +0 -240
  382. package/esm/storages/pluggable/SplitsCachePluggable.js +0 -209
  383. package/esm/sync/polling/syncTasks/splitsSyncTask.js +0 -9
  384. package/esm/sync/polling/updaters/splitChangesUpdater.js +0 -192
  385. package/esm/utils/inputValidation/splitExistence.js +0 -15
  386. package/esm/utils/inputValidation/splits.js +0 -21
  387. package/src/storages/AbstractSplitsCacheAsync.ts +0 -63
  388. package/src/storages/AbstractSplitsCacheSync.ts +0 -95
  389. package/src/storages/inLocalStorage/SplitsCacheInLocal.ts +0 -234
  390. package/src/storages/inMemory/SplitsCacheInMemory.ts +0 -130
  391. package/src/storages/pluggable/SplitsCachePluggable.ts +0 -230
  392. package/src/sync/polling/updaters/splitChangesUpdater.ts +0 -230
  393. package/src/utils/inputValidation/split.ts +0 -27
  394. package/src/utils/inputValidation/splitExistence.ts +0 -19
  395. package/src/utils/inputValidation/splits.ts +0 -21
@@ -0,0 +1,52 @@
1
+ import { thenable } from '../utils/promise/thenable';
2
+ import { getMatching } from '../utils/key';
3
+ import { validateTrafficTypeExistence } from '../utils/inputValidation/trafficTypeExistence';
4
+ import { validateKey, validateTrafficType, validateEvent, validateEventValue, validateEventProperties, validateIfNotDestroyed } from '../utils/inputValidation';
5
+ import { TRACK, TRACK_FN_LABEL } from '../utils/constants';
6
+ import { isConsumerMode } from '../utils/settingsValidation/mode';
7
+ /**
8
+ * Creates a standalone `track` function with input validation.
9
+ * Reusable by FF SDK client, Configs SDK, and thin-client SDK.
10
+ */
11
+ export function trackMethodFactory(params, warnTTExistence) {
12
+ if (warnTTExistence === void 0) { warnTTExistence = true; }
13
+ var settings = params.settings, definitions = params.storage.definitions, telemetryTracker = params.telemetryTracker, eventTracker = params.eventTracker, readinessManager = params.sdkReadinessManager.readinessManager;
14
+ var log = settings.log, mode = settings.mode;
15
+ var isAsync = isConsumerMode(mode);
16
+ return function track(maybeKey, maybeTT, maybeEvent, maybeEventValue, maybeProperties) {
17
+ // Input validation
18
+ var key = validateKey(log, maybeKey, TRACK_FN_LABEL);
19
+ var trafficTypeName = validateTrafficType(log, maybeTT, TRACK_FN_LABEL);
20
+ var eventTypeId = validateEvent(log, maybeEvent, TRACK_FN_LABEL);
21
+ var value = validateEventValue(log, maybeEventValue, TRACK_FN_LABEL);
22
+ var _a = validateEventProperties(log, maybeProperties, TRACK_FN_LABEL), properties = _a.properties, size = _a.size;
23
+ var isNotDestroyed = validateIfNotDestroyed(log, readinessManager, TRACK_FN_LABEL);
24
+ if (!(isNotDestroyed && key && trafficTypeName && eventTypeId && value !== false && properties !== false)) {
25
+ return isAsync ? Promise.resolve(false) : false;
26
+ }
27
+ // Core logic
28
+ var stopTelemetryTracker = telemetryTracker.trackEval(TRACK);
29
+ var eventData = {
30
+ eventTypeId: eventTypeId,
31
+ trafficTypeName: trafficTypeName,
32
+ value: value,
33
+ timestamp: Date.now(),
34
+ key: getMatching(key),
35
+ properties: properties
36
+ };
37
+ // This may be async but we only warn, we don't actually care if it is valid or not in terms of queueing the event.
38
+ if (warnTTExistence)
39
+ validateTrafficTypeExistence(log, readinessManager, definitions, mode, trafficTypeName, TRACK_FN_LABEL);
40
+ var result = eventTracker.track(eventData, size);
41
+ if (thenable(result)) {
42
+ return result.then(function (result) {
43
+ stopTelemetryTracker();
44
+ return result;
45
+ });
46
+ }
47
+ else {
48
+ stopTelemetryTracker();
49
+ return result;
50
+ }
51
+ };
52
+ }
@@ -2,16 +2,10 @@ import { sdkReadinessManagerFactory } from '../readiness/sdkReadinessManager';
2
2
  import { impressionsTrackerFactory } from '../trackers/impressionsTracker';
3
3
  import { eventTrackerFactory } from '../trackers/eventTracker';
4
4
  import { telemetryTrackerFactory } from '../trackers/telemetryTracker';
5
- import { validateAndTrackApiKey } from '../utils/inputValidation/apiKey';
6
5
  import { createLoggerAPI } from '../logger/sdkLogger';
7
6
  import { NEW_FACTORY, RETRIEVE_MANAGER } from '../logger/constants';
8
- import { SDK_SPLITS_ARRIVED, SDK_SEGMENTS_ARRIVED, SDK_SPLITS_CACHE_LOADED } from '../readiness/constants';
7
+ import { SDK_DEFINITIONS_ARRIVED, SDK_SEGMENTS_ARRIVED, SDK_DEFINITIONS_CACHE_LOADED } from '../readiness/constants';
9
8
  import { objectAssign } from '../utils/lang/objectAssign';
10
- import { strategyDebugFactory } from '../trackers/strategy/strategyDebug';
11
- import { strategyOptimizedFactory } from '../trackers/strategy/strategyOptimized';
12
- import { strategyNoneFactory } from '../trackers/strategy/strategyNone';
13
- import { uniqueKeysTrackerFactory } from '../trackers/uniqueKeysTracker';
14
- import { DEBUG, OPTIMIZED } from '../utils/constants';
15
9
  import { setRolloutPlan } from '../storages/setRolloutPlan';
16
10
  import { getMatching } from '../utils/key';
17
11
  import { FallbackTreatmentsCalculator } from '../evaluator/fallbackTreatmentsCalculator';
@@ -19,19 +13,10 @@ import { FallbackTreatmentsCalculator } from '../evaluator/fallbackTreatmentsCal
19
13
  * Modular SDK factory
20
14
  */
21
15
  export function sdkFactory(params) {
22
- var settings = params.settings, platform = params.platform, storageFactory = params.storageFactory, splitApiFactory = params.splitApiFactory, extraProps = params.extraProps, syncManagerFactory = params.syncManagerFactory, SignalListener = params.SignalListener, impressionsObserverFactory = params.impressionsObserverFactory, integrationsManagerFactory = params.integrationsManagerFactory, sdkManagerFactory = params.sdkManagerFactory, sdkClientMethodFactory = params.sdkClientMethodFactory, filterAdapterFactory = params.filterAdapterFactory, lazyInit = params.lazyInit;
23
- var log = settings.log, impressionsMode = settings.sync.impressionsMode, initialRolloutPlan = settings.initialRolloutPlan, key = settings.core.key;
16
+ var settings = params.settings, platform = params.platform, storageFactory = params.storageFactory, splitApiFactory = params.splitApiFactory, extraProps = params.extraProps, syncManagerFactory = params.syncManagerFactory, integrationsManagerFactory = params.integrationsManagerFactory, sdkManagerFactory = params.sdkManagerFactory, sdkClientMethodFactory = params.sdkClientMethodFactory, lazyInit = params.lazyInit;
17
+ var log = settings.log, initialRolloutPlan = settings.initialRolloutPlan, key = settings.core.key;
24
18
  // @TODO handle non-recoverable errors, such as, global `fetch` not available, invalid SDK Key, etc.
25
19
  // On non-recoverable errors, we should mark the SDK as destroyed and not start synchronization.
26
- // initialization
27
- var hasInit = false;
28
- var initCallbacks = [];
29
- function whenInit(cb) {
30
- if (hasInit)
31
- cb();
32
- else
33
- initCallbacks.push(cb);
34
- }
35
20
  var sdkReadinessManager = sdkReadinessManagerFactory(platform.EventEmitter, settings);
36
21
  var readiness = sdkReadinessManager.readinessManager;
37
22
  var storage = storageFactory({
@@ -42,54 +27,33 @@ export function sdkFactory(params) {
42
27
  readiness.timeout();
43
28
  return;
44
29
  }
45
- readiness.splits.emit(SDK_SPLITS_ARRIVED);
30
+ readiness.definitions.emit(SDK_DEFINITIONS_ARRIVED);
46
31
  readiness.segments.emit(SDK_SEGMENTS_ARRIVED);
47
32
  },
48
33
  onReadyFromCacheCb: function () {
49
- readiness.splits.emit(SDK_SPLITS_CACHE_LOADED);
34
+ readiness.definitions.emit(SDK_DEFINITIONS_CACHE_LOADED);
50
35
  }
51
36
  });
52
- var fallbackTreatmentsCalculator = new FallbackTreatmentsCalculator(settings.fallbackTreatments);
37
+ var fallbackCalculator = FallbackTreatmentsCalculator(settings.fallbackTreatments);
53
38
  if (initialRolloutPlan) {
54
39
  setRolloutPlan(log, initialRolloutPlan, storage, key && getMatching(key));
55
- if (storage.splits.getChangeNumber() > -1)
56
- readiness.splits.emit(SDK_SPLITS_CACHE_LOADED, { initialCacheLoad: false /* Not an initial load, cache exists */ });
40
+ if (storage.definitions.getChangeNumber() > -1)
41
+ readiness.definitions.emit(SDK_DEFINITIONS_CACHE_LOADED, { initialCacheLoad: false /* Not an initial load, cache exists */ });
57
42
  }
58
43
  var clients = {};
59
44
  var telemetryTracker = telemetryTrackerFactory(storage.telemetry, platform.now);
60
45
  var integrationsManager = integrationsManagerFactory && integrationsManagerFactory({ settings: settings, storage: storage, telemetryTracker: telemetryTracker });
61
- var observer = impressionsObserverFactory();
62
- var uniqueKeysTracker = uniqueKeysTrackerFactory(log, storage.uniqueKeys, filterAdapterFactory && filterAdapterFactory());
63
- var noneStrategy = strategyNoneFactory(storage.impressionCounts, uniqueKeysTracker);
64
- var strategy = impressionsMode === OPTIMIZED ?
65
- strategyOptimizedFactory(observer, storage.impressionCounts) :
66
- impressionsMode === DEBUG ?
67
- strategyDebugFactory(observer) :
68
- noneStrategy;
69
- var impressionsTracker = impressionsTrackerFactory(settings, storage.impressions, noneStrategy, strategy, whenInit, integrationsManager, storage.telemetry);
70
- var eventTracker = eventTrackerFactory(settings, storage.events, whenInit, integrationsManager, storage.telemetry);
46
+ var impressionsTracker = impressionsTrackerFactory(params, storage, integrationsManager);
47
+ var eventTracker = eventTrackerFactory(settings, storage.events, integrationsManager, storage.telemetry);
71
48
  // splitApi is used by SyncManager and Browser signal listener
72
49
  var splitApi = splitApiFactory && splitApiFactory(settings, platform, telemetryTracker);
73
- var ctx = { clients: clients, splitApi: splitApi, eventTracker: eventTracker, impressionsTracker: impressionsTracker, telemetryTracker: telemetryTracker, uniqueKeysTracker: uniqueKeysTracker, sdkReadinessManager: sdkReadinessManager, readiness: readiness, settings: settings, storage: storage, platform: platform, fallbackTreatmentsCalculator: fallbackTreatmentsCalculator };
74
- var syncManager = syncManagerFactory && syncManagerFactory(ctx);
75
- ctx.syncManager = syncManager;
76
- var signalListener = SignalListener && new SignalListener(syncManager, settings, storage, splitApi);
77
- ctx.signalListener = signalListener;
50
+ var ctx = { clients: clients, splitApi: splitApi, eventTracker: eventTracker, impressionsTracker: impressionsTracker, telemetryTracker: telemetryTracker, sdkReadinessManager: sdkReadinessManager, readiness: readiness, settings: settings, storage: storage, platform: platform, fallbackCalculator: fallbackCalculator };
51
+ ctx.syncManager = syncManagerFactory && syncManagerFactory(ctx);
78
52
  // SDK client and manager
79
53
  var clientMethod = sdkClientMethodFactory(ctx);
80
- var managerInstance = sdkManagerFactory(settings, storage.splits, sdkReadinessManager);
54
+ var managerInstance = sdkManagerFactory(settings, storage.definitions, sdkReadinessManager);
81
55
  function init() {
82
- if (hasInit)
83
- return;
84
- hasInit = true;
85
- // We will just log and allow for the SDK to end up throwing an SDK_TIMEOUT event for devs to handle.
86
- validateAndTrackApiKey(log, settings.core.authorizationKey);
87
- readiness.init();
88
- uniqueKeysTracker.start();
89
- syncManager && syncManager.start();
90
- signalListener && signalListener.start();
91
- initCallbacks.forEach(function (cb) { return cb(); });
92
- initCallbacks.length = 0;
56
+ Object.keys(clients).map(function (key) { return clients[key].init(); });
93
57
  }
94
58
  log.info(NEW_FACTORY, [settings.version]);
95
59
  // @ts-ignore
@@ -105,7 +69,6 @@ export function sdkFactory(params) {
105
69
  Logger: createLoggerAPI(log),
106
70
  settings: settings,
107
71
  destroy: function () {
108
- hasInit = false;
109
72
  return Promise.all(Object.keys(clients).map(function (key) { return clients[key].destroy(); })).then(function () { });
110
73
  }
111
74
  }, extraProps && extraProps(ctx), lazyInit ? { init: init } : init());
@@ -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 { validateSplit, validateSplitExistence, validateIfOperational } from '../utils/inputValidation';
4
+ import { validateDefinition, validateDefinitionExistence, 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 = validateSplit(log, featureFlagName, SPLIT_FN_LABEL);
53
+ var splitName = validateDefinition(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.getSplit(splitName);
57
+ var split = splits.get(splitName);
58
58
  if (thenable(split)) {
59
59
  return split.catch(function () { return null; }).then(function (result) {
60
- validateSplitExistence(log, readinessManager, splitName, result, SPLIT_FN_LABEL);
60
+ validateDefinitionExistence(log, readinessManager, splitName, result, SPLIT_FN_LABEL);
61
61
  return objectToView(result);
62
62
  });
63
63
  }
64
- validateSplitExistence(log, readinessManager, splitName, split, SPLIT_FN_LABEL);
64
+ validateDefinitionExistence(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.getSplitNames();
86
+ var splitNames = splits.getNames();
87
87
  return thenable(splitNames) ?
88
88
  splitNames.catch(function () { return []; }) : // handle possible rejections when using pluggable storage
89
89
  splitNames;
@@ -0,0 +1,63 @@
1
+ import { authenticateFactory } from '../sync/streaming/AuthClient';
2
+ import { Backoff } from '../utils/Backoff';
3
+ import { LOG_PREFIX_SYNC_AUTH } from '../logger/constants';
4
+ import { TOKEN } from '../utils/constants';
5
+ var SKEW_SECONDS = 30;
6
+ function isExpired(credential) {
7
+ return Date.now() / 1000 + SKEW_SECONDS >= credential.decodedToken.exp;
8
+ }
9
+ /**
10
+ * Factory of AuthProvider, which provides JWT credentials for authenticated HTTP requests.
11
+ * Credentials are fetched lazily on demand, cached in memory, and retried with backoff on failure.
12
+ */
13
+ export function authProviderFactory(settings, splitHttpClient, telemetryTracker) {
14
+ var urls = settings.urls, log = settings.log;
15
+ function fetchAuth() {
16
+ var url = "".concat(urls.auth, "/v3/auth?capabilities=config");
17
+ return splitHttpClient(url, undefined, telemetryTracker.trackHttp(TOKEN));
18
+ }
19
+ var authenticate = authenticateFactory(fetchAuth);
20
+ var backoff = new Backoff(fetchCredential);
21
+ var cachedCredential;
22
+ var inFlightPromise;
23
+ var stopped = false;
24
+ function fetchCredential() {
25
+ return authenticate().then(function (credential) {
26
+ log.info(LOG_PREFIX_SYNC_AUTH + 'credential fetched successfully');
27
+ cachedCredential = credential;
28
+ inFlightPromise = undefined;
29
+ backoff.reset();
30
+ return credential;
31
+ }).catch(function (error) {
32
+ // Avoid rejected promises and unnecessary retries after stop()
33
+ if (stopped)
34
+ return cachedCredential;
35
+ if (error.statusCode && error.statusCode >= 400 && error.statusCode < 500) {
36
+ log.error(LOG_PREFIX_SYNC_AUTH + 'non-retryable error fetching credential (status ' + error.statusCode + '): ' + error.message);
37
+ inFlightPromise = undefined;
38
+ throw error;
39
+ }
40
+ log.warn(LOG_PREFIX_SYNC_AUTH + 'credential fetch failed (attempt ' + (backoff.attempts + 1) + '). Error: ' + error.message);
41
+ return backoff.scheduleCallAsync();
42
+ });
43
+ }
44
+ return {
45
+ credential: function () {
46
+ if (cachedCredential && !isExpired(cachedCredential)) {
47
+ return Promise.resolve(cachedCredential);
48
+ }
49
+ if (cachedCredential)
50
+ log.debug(LOG_PREFIX_SYNC_AUTH + 'cached credential expired');
51
+ return inFlightPromise || (inFlightPromise = fetchCredential());
52
+ },
53
+ invalidate: function () {
54
+ cachedCredential = undefined;
55
+ },
56
+ stop: function () {
57
+ stopped = true;
58
+ cachedCredential = undefined;
59
+ inFlightPromise = undefined;
60
+ backoff.reset();
61
+ }
62
+ };
63
+ }
@@ -0,0 +1,35 @@
1
+ import { __assign } from "tslib";
2
+ import { splitHttpClientFactory } from './splitHttpClient';
3
+ import { authProviderFactory } from './authProvider';
4
+ /**
5
+ * Factory of Secure HTTP client, which authenticates requests using a JWT token.
6
+ * On 401 responses, invalidates the cached credential and retries once with a fresh token.
7
+ *
8
+ * @param settings - SDK settings
9
+ * @param platform - object containing environment-specific dependencies
10
+ * @param fetchAuth - function to fetch auth credentials from the /v2/auth endpoint
11
+ */
12
+ export function secureSplitHttpClientFactory(settings, platform, telemetryTracker) {
13
+ var splitHttpClient = splitHttpClientFactory(settings, platform);
14
+ var authProvider = authProviderFactory(settings, splitHttpClient, telemetryTracker);
15
+ function makeRequest(url, options, latencyTracker, logErrorsAsInfo, token) {
16
+ return splitHttpClient(url, __assign(__assign({}, options), { headers: __assign(__assign({}, options === null || options === void 0 ? void 0 : options.headers), { Authorization: "Bearer ".concat(token) }) }), latencyTracker, logErrorsAsInfo);
17
+ }
18
+ var httpClient = function (url, options, latencyTracker, logErrorsAsInfo) {
19
+ return authProvider.credential().then(function (credential) {
20
+ return makeRequest(url, options, latencyTracker, logErrorsAsInfo, credential.token)
21
+ .catch(function (error) {
22
+ if (error.statusCode === 401) {
23
+ // retry once for 401, in case the token has just expired
24
+ authProvider.invalidate();
25
+ return authProvider.credential().then(function (newCredential) {
26
+ return makeRequest(url, options, latencyTracker, logErrorsAsInfo, newCredential.token);
27
+ });
28
+ }
29
+ throw error;
30
+ });
31
+ });
32
+ };
33
+ httpClient.stop = function () { return authProvider.stop(); };
34
+ return httpClient;
35
+ }
@@ -13,23 +13,24 @@ function userKeyToQueryParam(userKey) {
13
13
  * @param platform - object containing environment-specific dependencies
14
14
  * @param telemetryTracker - telemetry tracker
15
15
  */
16
- export function splitApiFactory(settings, platform, telemetryTracker) {
16
+ export function splitApiFactory(settings, platform, telemetryTracker, secureSplitHttpClientFactory) {
17
17
  var urls = settings.urls;
18
18
  var filterQueryString = settings.sync.__splitFiltersValidation && settings.sync.__splitFiltersValidation.queryString;
19
19
  var SplitSDKImpressionsMode = settings.sync.impressionsMode;
20
20
  var splitHttpClient = splitHttpClientFactory(settings, platform);
21
+ var secureSplitHttpClient = secureSplitHttpClientFactory ? secureSplitHttpClientFactory(settings, platform, telemetryTracker) : undefined;
21
22
  return {
22
23
  // @TODO throw errors if health check requests fail, to log them in the Synchronizer
23
24
  getSdkAPIHealthCheck: function () {
24
- var url = urls.sdk + "/version";
25
+ var url = "".concat(urls.sdk, "/version");
25
26
  return splitHttpClient(url).then(function () { return true; }).catch(function () { return false; });
26
27
  },
27
28
  getEventsAPIHealthCheck: function () {
28
- var url = urls.events + "/version";
29
+ var url = "".concat(urls.events, "/version");
29
30
  return splitHttpClient(url).then(function () { return true; }).catch(function () { return false; });
30
31
  },
31
32
  fetchAuth: function (userMatchingKeys) {
32
- var url = urls.auth + "/v2/auth?s=" + settings.sync.flagSpecVersion;
33
+ var url = "".concat(urls.auth, "/v2/auth?s=").concat(settings.sync.flagSpecVersion);
33
34
  if (userMatchingKeys) { // `userMatchingKeys` is undefined in server-side
34
35
  var queryParams = userMatchingKeys.map(userKeyToQueryParam).join('&');
35
36
  if (queryParams)
@@ -38,7 +39,7 @@ export function splitApiFactory(settings, platform, telemetryTracker) {
38
39
  return splitHttpClient(url, undefined, telemetryTracker.trackHttp(TOKEN));
39
40
  },
40
41
  fetchSplitChanges: function (since, noCache, till, rbSince) {
41
- var url = urls.sdk + "/splitChanges?s=" + settings.sync.flagSpecVersion + "&since=" + since + (rbSince ? '&rbSince=' + rbSince : '') + (filterQueryString || '') + (till ? '&till=' + till : '');
42
+ var url = "".concat(urls.sdk, "/splitChanges?s=").concat(settings.sync.flagSpecVersion, "&since=").concat(since).concat(rbSince ? '&rbSince=' + rbSince : '').concat(filterQueryString || '').concat(till ? '&till=' + till : '');
42
43
  return splitHttpClient(url, noCache ? noCacheHeaderOptions : undefined, telemetryTracker.trackHttp(SPLITS))
43
44
  .catch(function (err) {
44
45
  if (err.statusCode === 414)
@@ -46,8 +47,13 @@ export function splitApiFactory(settings, platform, telemetryTracker) {
46
47
  throw err;
47
48
  });
48
49
  },
50
+ // @TODO support filterQueryString and handle ERROR_TOO_MANY_SETS error
51
+ fetchConfigs: function (since, noCache, till) {
52
+ var url = "".concat(urls.sdk, "/v1/configs?since=").concat(since).concat(filterQueryString || '').concat(till ? '&till=' + till : '');
53
+ return (secureSplitHttpClient || splitHttpClient)(url, noCache ? noCacheHeaderOptions : undefined);
54
+ },
49
55
  fetchSegmentChanges: function (since, segmentName, noCache, till) {
50
- var url = urls.sdk + "/segmentChanges/" + segmentName + "?since=" + since + (till ? '&till=' + till : '');
56
+ var url = "".concat(urls.sdk, "/segmentChanges/").concat(segmentName, "?since=").concat(since).concat(till ? '&till=' + till : '');
51
57
  return splitHttpClient(url, noCache ? noCacheHeaderOptions : undefined, telemetryTracker.trackHttp(SEGMENT));
52
58
  },
53
59
  fetchMemberships: function (userMatchingKey, noCache, till) {
@@ -57,7 +63,7 @@ export function splitApiFactory(settings, platform, telemetryTracker) {
57
63
  * - avoid 404 responses. E.g.: '/api/memberships/foo/bar'
58
64
  * - match user keys with special characters. E.g.: 'foo%bar', 'foo/bar'
59
65
  */
60
- var url = urls.sdk + "/memberships/" + encodeURIComponent(userMatchingKey) + (till ? '?till=' + till : '');
66
+ var url = "".concat(urls.sdk, "/memberships/").concat(encodeURIComponent(userMatchingKey)).concat(till ? '?till=' + till : '');
61
67
  return splitHttpClient(url, noCache ? noCacheHeaderOptions : undefined, telemetryTracker.trackHttp(MEMBERSHIPS));
62
68
  },
63
69
  /**
@@ -67,7 +73,7 @@ export function splitApiFactory(settings, platform, telemetryTracker) {
67
73
  * @param headers - Optionals headers to overwrite default ones. For example, it is used in producer mode to overwrite metadata headers.
68
74
  */
69
75
  postEventsBulk: function (body, headers) {
70
- var url = urls.events + "/events/bulk";
76
+ var url = "".concat(urls.events, "/events/bulk");
71
77
  return splitHttpClient(url, { method: 'POST', body: body, headers: headers }, telemetryTracker.trackHttp(EVENTS));
72
78
  },
73
79
  /**
@@ -77,7 +83,7 @@ export function splitApiFactory(settings, platform, telemetryTracker) {
77
83
  * @param headers - Optionals headers to overwrite default ones. For example, it is used in producer mode to overwrite metadata headers.
78
84
  */
79
85
  postTestImpressionsBulk: function (body, headers) {
80
- var url = urls.events + "/testImpressions/bulk";
86
+ var url = "".concat(urls.events, "/testImpressions/bulk");
81
87
  return splitHttpClient(url, {
82
88
  // Adding extra headers to send impressions in OPTIMIZED or DEBUG modes.
83
89
  method: 'POST',
@@ -92,7 +98,7 @@ export function splitApiFactory(settings, platform, telemetryTracker) {
92
98
  * @param headers - Optionals headers to overwrite default ones. For example, it is used in producer mode to overwrite metadata headers.
93
99
  */
94
100
  postTestImpressionsCount: function (body, headers) {
95
- var url = urls.events + "/testImpressions/count";
101
+ var url = "".concat(urls.events, "/testImpressions/count");
96
102
  return splitHttpClient(url, { method: 'POST', body: body, headers: headers }, telemetryTracker.trackHttp(IMPRESSIONS_COUNT));
97
103
  },
98
104
  /**
@@ -102,7 +108,7 @@ export function splitApiFactory(settings, platform, telemetryTracker) {
102
108
  * @param headers - Optionals headers to overwrite default ones. For example, it is used in producer mode to overwrite metadata headers.
103
109
  */
104
110
  postUniqueKeysBulkCs: function (body, headers) {
105
- var url = urls.telemetry + "/v1/keys/cs";
111
+ var url = "".concat(urls.telemetry, "/v1/keys/cs");
106
112
  return splitHttpClient(url, { method: 'POST', body: body, headers: headers }, telemetryTracker.trackHttp(TELEMETRY));
107
113
  },
108
114
  /**
@@ -112,16 +118,20 @@ export function splitApiFactory(settings, platform, telemetryTracker) {
112
118
  * @param headers - Optionals headers to overwrite default ones. For example, it is used in producer mode to overwrite metadata headers.
113
119
  */
114
120
  postUniqueKeysBulkSs: function (body, headers) {
115
- var url = urls.telemetry + "/v1/keys/ss";
121
+ var url = "".concat(urls.telemetry, "/v1/keys/ss");
116
122
  return splitHttpClient(url, { method: 'POST', body: body, headers: headers }, telemetryTracker.trackHttp(TELEMETRY));
117
123
  },
118
124
  postMetricsConfig: function (body, headers) {
119
- var url = urls.telemetry + "/v1/metrics/config";
125
+ var url = "".concat(urls.telemetry, "/v1/metrics/config");
120
126
  return splitHttpClient(url, { method: 'POST', body: body, headers: headers }, telemetryTracker.trackHttp(TELEMETRY), true);
121
127
  },
122
128
  postMetricsUsage: function (body, headers) {
123
- var url = urls.telemetry + "/v1/metrics/usage";
129
+ var url = "".concat(urls.telemetry, "/v1/metrics/usage");
124
130
  return splitHttpClient(url, { method: 'POST', body: body, headers: headers }, telemetryTracker.trackHttp(TELEMETRY), true);
131
+ },
132
+ stop: function () {
133
+ if (secureSplitHttpClient)
134
+ secureSplitHttpClient.stop();
125
135
  }
126
136
  };
127
137
  }
@@ -21,7 +21,7 @@ export function splitHttpClientFactory(settings, _a) {
21
21
  var commonHeaders = {
22
22
  'Accept': 'application/json',
23
23
  'Content-Type': 'application/json',
24
- 'Authorization': "Bearer " + authorizationKey,
24
+ 'Authorization': "Bearer ".concat(authorizationKey),
25
25
  'SplitSDKVersion': version
26
26
  };
27
27
  if (ip)
@@ -0,0 +1,48 @@
1
+ import { objectAssign } from '../utils/lang/objectAssign';
2
+ /**
3
+ * This class provides a skeletal implementation of the IDefinitionsCacheAsync interface
4
+ * to minimize the effort required to implement this interface.
5
+ */
6
+ var AbstractDefinitionsCacheAsync = /** @class */ (function () {
7
+ function AbstractDefinitionsCacheAsync() {
8
+ }
9
+ AbstractDefinitionsCacheAsync.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.add(addedFF); })),
14
+ Promise.all(toRemove.map(function (removedFF) { return _this.remove(removedFF); }))
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
+ AbstractDefinitionsCacheAsync.prototype.usesSegments = function () {
23
+ return Promise.resolve(true);
24
+ };
25
+ /**
26
+ * Kill `name` definition and set `defaultTreatment` and `changeNumber`.
27
+ * Used for SPLIT_KILL push notifications.
28
+ *
29
+ * @returns a promise that is resolved once the definition kill operation is performed. The fulfillment value is a boolean: `true` if the operation succeeded updating the definition or `false` if no definition is updated,
30
+ * for instance, if the `changeNumber` is old, or if the definition 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
+ AbstractDefinitionsCacheAsync.prototype.killLocally = function (name, defaultTreatment, changeNumber) {
34
+ var _this = this;
35
+ return this.get(name).then(function (definition) {
36
+ if (definition && (!definition.changeNumber || definition.changeNumber < changeNumber)) {
37
+ var newDefinition = objectAssign({}, definition);
38
+ newDefinition.killed = true;
39
+ newDefinition.defaultTreatment = defaultTreatment;
40
+ newDefinition.changeNumber = changeNumber;
41
+ return _this.add(newDefinition);
42
+ }
43
+ return false;
44
+ }).catch(function () { return false; });
45
+ };
46
+ return AbstractDefinitionsCacheAsync;
47
+ }());
48
+ export { AbstractDefinitionsCacheAsync };
@@ -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 IDefinitionsCacheSync interface
5
+ * to minimize the effort required to implement this interface.
6
+ */
7
+ var AbstractDefinitionsCacheSync = /** @class */ (function () {
8
+ function AbstractDefinitionsCacheSync() {
9
+ }
10
+ AbstractDefinitionsCacheSync.prototype.update = function (toAdd, toRemove, changeNumber) {
11
+ var _this = this;
12
+ var updated = toAdd.map(function (addedFF) { return _this.add(addedFF); }).some(function (result) { return result; });
13
+ updated = toRemove.map(function (removedFF) { return _this.remove(removedFF); }).some(function (result) { return result; }) || updated;
14
+ this.setChangeNumber(changeNumber);
15
+ return updated;
16
+ };
17
+ AbstractDefinitionsCacheSync.prototype.getMany = function (names) {
18
+ var _this = this;
19
+ var definitions = {};
20
+ names.forEach(function (name) {
21
+ definitions[name] = _this.get(name);
22
+ });
23
+ return definitions;
24
+ };
25
+ AbstractDefinitionsCacheSync.prototype.getAll = function () {
26
+ var _this = this;
27
+ return this.getNames().map(function (key) { return _this.get(key); });
28
+ };
29
+ /**
30
+ * Kill `name` definition and set `defaultTreatment` and `changeNumber`.
31
+ * Used for SPLIT_KILL push notifications.
32
+ *
33
+ * @returns `true` if the operation successed updating the definition, or `false` if no definition is updated,
34
+ * for instance, if the `changeNumber` is old, or if the definition is not found (e.g., `/splitchanges` hasn't been fetched yet), or if the storage fails to apply the update.
35
+ */
36
+ AbstractDefinitionsCacheSync.prototype.killLocally = function (name, defaultTreatment, changeNumber) {
37
+ var definition = this.get(name);
38
+ if (definition && (!definition.changeNumber || definition.changeNumber < changeNumber)) {
39
+ var newDefinition = objectAssign({}, definition);
40
+ newDefinition.killed = true;
41
+ newDefinition.defaultTreatment = defaultTreatment;
42
+ newDefinition.changeNumber = changeNumber;
43
+ return this.add(newDefinition);
44
+ }
45
+ return false;
46
+ };
47
+ return AbstractDefinitionsCacheSync;
48
+ }());
49
+ export { AbstractDefinitionsCacheSync };
50
+ /**
51
+ * Given a parsed definition, it returns a boolean flagging if its conditions use segments matchers (rules & whitelists).
52
+ * This util is intended to simplify the implementation of `definitionsCache::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.definitions.usesSegments() || storage.rbSegments.usesSegments();
71
+ }
@@ -10,34 +10,34 @@ var KeyBuilder = /** @class */ (function () {
10
10
  this.prefix = prefix;
11
11
  }
12
12
  KeyBuilder.prototype.buildTrafficTypeKey = function (trafficType) {
13
- return this.prefix + ".trafficType." + trafficType;
13
+ return "".concat(this.prefix, ".trafficType.").concat(trafficType);
14
14
  };
15
- KeyBuilder.prototype.buildFlagSetKey = function (flagSet) {
16
- return this.prefix + ".flagSet." + flagSet;
15
+ KeyBuilder.prototype.buildSetKey = function (set) {
16
+ return "".concat(this.prefix, ".flagSet.").concat(set);
17
17
  };
18
- KeyBuilder.prototype.buildSplitKey = function (splitName) {
19
- return this.prefix + ".split." + splitName;
18
+ KeyBuilder.prototype.buildDefinitionKey = function (definitionName) {
19
+ return "".concat(this.prefix, ".split.").concat(definitionName);
20
20
  };
21
- KeyBuilder.prototype.buildSplitsTillKey = function () {
22
- return this.prefix + ".splits.till";
21
+ KeyBuilder.prototype.buildDefinitionsTillKey = function () {
22
+ return "".concat(this.prefix, ".splits.till");
23
23
  };
24
- KeyBuilder.prototype.buildSplitKeyPrefix = function () {
25
- return this.prefix + ".split.";
24
+ KeyBuilder.prototype.buildDefinitionKeyPrefix = function () {
25
+ return "".concat(this.prefix, ".split.");
26
26
  };
27
27
  KeyBuilder.prototype.buildRBSegmentKey = function (rbsegmentName) {
28
- return this.prefix + ".rbsegment." + rbsegmentName;
28
+ return "".concat(this.prefix, ".rbsegment.").concat(rbsegmentName);
29
29
  };
30
30
  KeyBuilder.prototype.buildRBSegmentsTillKey = function () {
31
- return this.prefix + ".rbsegments.till";
31
+ return "".concat(this.prefix, ".rbsegments.till");
32
32
  };
33
33
  KeyBuilder.prototype.buildRBSegmentKeyPrefix = function () {
34
- return this.prefix + ".rbsegment.";
34
+ return "".concat(this.prefix, ".rbsegment.");
35
35
  };
36
36
  KeyBuilder.prototype.buildSegmentNameKey = function (segmentName) {
37
- return this.prefix + ".segment." + segmentName;
37
+ return "".concat(this.prefix, ".segment.").concat(segmentName);
38
38
  };
39
39
  KeyBuilder.prototype.buildSegmentTillKey = function (segmentName) {
40
- return this.prefix + ".segment." + segmentName + ".till";
40
+ return "".concat(this.prefix, ".segment.").concat(segmentName, ".till");
41
41
  };
42
42
  KeyBuilder.prototype.extractKey = function (builtKey) {
43
43
  var s = builtKey.match(everythingAtTheEnd);
@@ -49,7 +49,7 @@ var KeyBuilder = /** @class */ (function () {
49
49
  }
50
50
  };
51
51
  KeyBuilder.prototype.buildHashKey = function () {
52
- return this.prefix + ".hash";
52
+ return "".concat(this.prefix, ".hash");
53
53
  };
54
54
  return KeyBuilder;
55
55
  }());
@@ -59,5 +59,5 @@ export { KeyBuilder };
59
59
  * The hash is in hexadecimal format (8 characters max, 32 bits).
60
60
  */
61
61
  export function getStorageHash(settings) {
62
- return hash(settings.core.authorizationKey + "::" + settings.sync.__splitFiltersValidation.queryString + "::" + settings.sync.flagSpecVersion).toString(16);
62
+ return hash("".concat(settings.core.authorizationKey, "::").concat(settings.sync.__splitFiltersValidation.queryString, "::").concat(settings.sync.flagSpecVersion)).toString(16);
63
63
  }