@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
@@ -1,13 +1,13 @@
1
1
  import { objectAssign } from '../utils/lang/objectAssign';
2
2
  import { ISettings } from '../types';
3
3
  import SplitIO, { SdkReadyMetadata } from '../../types/splitio';
4
- import { SDK_SPLITS_ARRIVED, SDK_SPLITS_CACHE_LOADED, SDK_SEGMENTS_ARRIVED, SDK_READY_TIMED_OUT, SDK_READY_FROM_CACHE, SDK_UPDATE, SDK_READY } from './constants';
5
- import { IReadinessEventEmitter, IReadinessManager, ISegmentsEventEmitter, ISplitsEventEmitter } from './types';
4
+ import { SDK_DEFINITIONS_ARRIVED, SDK_DEFINITIONS_CACHE_LOADED, SDK_SEGMENTS_ARRIVED, SDK_READY_TIMED_OUT, SDK_READY_FROM_CACHE, SDK_UPDATE, SDK_READY } from './constants';
5
+ import { IReadinessEventEmitter, IReadinessManager, ISegmentsEventEmitter, IDefinitionsEventEmitter } from './types';
6
6
 
7
- function splitsEventEmitterFactory(EventEmitter: new () => SplitIO.IEventEmitter): ISplitsEventEmitter {
8
- const splitsEventEmitter = objectAssign(new EventEmitter(), {
9
- splitsArrived: false,
10
- splitsCacheLoaded: false,
7
+ function definitionsEventEmitterFactory(EventEmitter: new () => SplitIO.IEventEmitter): IDefinitionsEventEmitter {
8
+ const definitionsEventEmitter = objectAssign(new EventEmitter(), {
9
+ definitionsArrived: false,
10
+ definitionsCacheLoaded: false,
11
11
  hasInit: false,
12
12
  initCallbacks: []
13
13
  });
@@ -15,10 +15,10 @@ function splitsEventEmitterFactory(EventEmitter: new () => SplitIO.IEventEmitter
15
15
  // `isSplitKill` condition avoids an edge-case of wrongly emitting SDK_READY if:
16
16
  // - `/memberships` fetch and SPLIT_KILL occurs before `/splitChanges` fetch, and
17
17
  // - storage has cached splits (for which case `splitsStorage.killLocally` can return true)
18
- splitsEventEmitter.on(SDK_SPLITS_ARRIVED, (metadata: SplitIO.SdkUpdateMetadata, isSplitKill: boolean) => { if (!isSplitKill) splitsEventEmitter.splitsArrived = true; });
19
- splitsEventEmitter.once(SDK_SPLITS_CACHE_LOADED, () => { splitsEventEmitter.splitsCacheLoaded = true; });
18
+ definitionsEventEmitter.on(SDK_DEFINITIONS_ARRIVED, (metadata: SplitIO.SdkUpdateMetadata, isSplitKill: boolean) => { if (!isSplitKill) definitionsEventEmitter.definitionsArrived = true; });
19
+ definitionsEventEmitter.once(SDK_DEFINITIONS_CACHE_LOADED, () => { definitionsEventEmitter.definitionsCacheLoaded = true; });
20
20
 
21
- return splitsEventEmitter;
21
+ return definitionsEventEmitter;
22
22
  }
23
23
 
24
24
  function segmentsEventEmitterFactory(EventEmitter: new () => SplitIO.IEventEmitter): ISegmentsEventEmitter {
@@ -37,7 +37,7 @@ function segmentsEventEmitterFactory(EventEmitter: new () => SplitIO.IEventEmitt
37
37
  export function readinessManagerFactory(
38
38
  EventEmitter: new () => SplitIO.IEventEmitter,
39
39
  settings: ISettings,
40
- splits: ISplitsEventEmitter = splitsEventEmitterFactory(EventEmitter),
40
+ definitions: IDefinitionsEventEmitter = definitionsEventEmitterFactory(EventEmitter),
41
41
  isShared?: boolean
42
42
  ): IReadinessManager {
43
43
 
@@ -59,8 +59,8 @@ export function readinessManagerFactory(
59
59
 
60
60
  // emit SDK_READY_FROM_CACHE
61
61
  let isReadyFromCache = false;
62
- if (splits.splitsCacheLoaded) isReadyFromCache = true; // ready from cache, but doesn't emit SDK_READY_FROM_CACHE
63
- else splits.once(SDK_SPLITS_CACHE_LOADED, checkIsReadyFromCache);
62
+ if (definitions.definitionsCacheLoaded) isReadyFromCache = true; // ready from cache, but doesn't emit SDK_READY_FROM_CACHE
63
+ else definitions.once(SDK_DEFINITIONS_CACHE_LOADED, checkIsReadyFromCache);
64
64
 
65
65
  // emit SDK_READY_TIMED_OUT
66
66
  let hasTimedout = false;
@@ -75,7 +75,7 @@ export function readinessManagerFactory(
75
75
 
76
76
  // emit SDK_READY and SDK_UPDATE
77
77
  let isReady = false;
78
- splits.on(SDK_SPLITS_ARRIVED, checkIsReadyOrUpdate);
78
+ definitions.on(SDK_DEFINITIONS_ARRIVED, checkIsReadyOrUpdate);
79
79
  segments.on(SDK_SEGMENTS_ARRIVED, checkIsReadyOrUpdate);
80
80
 
81
81
  let isDestroyed = false;
@@ -85,8 +85,8 @@ export function readinessManagerFactory(
85
85
  if (readyTimeout > 0 && !isReady) readyTimeoutId = setTimeout(timeout, readyTimeout);
86
86
  }
87
87
 
88
- splits.initCallbacks.push(__init);
89
- if (splits.hasInit) __init();
88
+ definitions.initCallbacks.push(__init);
89
+ if (definitions.hasInit) __init();
90
90
 
91
91
  function checkIsReadyFromCache(cacheMetadata: SdkReadyMetadata) {
92
92
  metadataReady = cacheMetadata;
@@ -114,7 +114,7 @@ export function readinessManagerFactory(
114
114
  setTimeout(() => { throw e; }, 0);
115
115
  }
116
116
  } else {
117
- if (splits.splitsArrived && segments.segmentsArrived) {
117
+ if (definitions.definitionsArrived && segments.segmentsArrived) {
118
118
  clearTimeout(readyTimeoutId);
119
119
  isReady = true;
120
120
  try {
@@ -137,12 +137,12 @@ export function readinessManagerFactory(
137
137
  }
138
138
 
139
139
  return {
140
- splits,
140
+ definitions,
141
141
  segments,
142
142
  gate,
143
143
 
144
144
  shared() {
145
- return readinessManagerFactory(EventEmitter, settings, splits, true);
145
+ return readinessManagerFactory(EventEmitter, settings, definitions, true);
146
146
  },
147
147
 
148
148
  // @TODO review/remove next methods when non-recoverable errors are reworked
@@ -153,9 +153,9 @@ export function readinessManagerFactory(
153
153
  setDestroyed() { isDestroyed = true; },
154
154
 
155
155
  init() {
156
- if (splits.hasInit) return;
157
- splits.hasInit = true;
158
- splits.initCallbacks.forEach(cb => cb());
156
+ if (definitions.hasInit) return;
157
+ definitions.hasInit = true;
158
+ definitions.initCallbacks.forEach(cb => cb());
159
159
  },
160
160
 
161
161
  destroy() {
@@ -163,7 +163,7 @@ export function readinessManagerFactory(
163
163
  syncLastUpdate();
164
164
  clearTimeout(readyTimeoutId);
165
165
 
166
- if (!isShared) splits.hasInit = false;
166
+ if (!isShared) definitions.hasInit = false;
167
167
  },
168
168
 
169
169
  isReady() { return isReady; },
@@ -5,10 +5,9 @@ import { ISdkReadinessManager } from './types';
5
5
  import { ISettings } from '../types';
6
6
  import SplitIO from '../../types/splitio';
7
7
  import { SDK_READY, SDK_READY_TIMED_OUT, SDK_READY_FROM_CACHE, SDK_UPDATE } from './constants';
8
- import { ERROR_CLIENT_LISTENER, CLIENT_READY_FROM_CACHE, CLIENT_READY, CLIENT_NO_LISTENER } from '../logger/constants';
8
+ import { ERROR_CLIENT_LISTENER, CLIENT_READY_FROM_CACHE, CLIENT_READY } from '../logger/constants';
9
9
 
10
10
  const NEW_LISTENER_EVENT = 'newListener';
11
- const REMOVE_LISTENER_EVENT = 'removeListener';
12
11
  const TIMEOUT_ERROR = new Error(SDK_READY_TIMED_OUT);
13
12
 
14
13
  /**
@@ -25,19 +24,10 @@ export function sdkReadinessManagerFactory(
25
24
 
26
25
  const log = settings.log;
27
26
 
28
- /** Ready callback warning */
29
- let internalReadyCbCount = 0;
30
- let readyCbCount = 0;
31
- readinessManager.gate.on(REMOVE_LISTENER_EVENT, (event: any) => {
32
- if (event === SDK_READY) readyCbCount--;
33
- });
34
-
35
27
  readinessManager.gate.on(NEW_LISTENER_EVENT, (event: any) => {
36
28
  if (event === SDK_READY || event === SDK_READY_TIMED_OUT) {
37
29
  if (readinessManager.isReady()) {
38
30
  log.error(ERROR_CLIENT_LISTENER, [event === SDK_READY ? 'SDK_READY' : 'SDK_READY_TIMED_OUT']);
39
- } else if (event === SDK_READY) {
40
- readyCbCount++;
41
31
  }
42
32
  } else if (event === SDK_READY_FROM_CACHE && readinessManager.isReadyFromCache()) {
43
33
  log.error(ERROR_CLIENT_LISTENER, ['SDK_READY_FROM_CACHE']);
@@ -61,7 +51,6 @@ export function sdkReadinessManagerFactory(
61
51
  readinessManager.gate.once(SDK_READY, () => {
62
52
  log.info(CLIENT_READY);
63
53
 
64
- if (readyCbCount === internalReadyCbCount && !promise.hasOnFulfilled()) log.warn(CLIENT_NO_LISTENER);
65
54
  resolve();
66
55
  });
67
56
  readinessManager.gate.once(SDK_READY_TIMED_OUT, (message: string) => {
@@ -91,10 +80,6 @@ export function sdkReadinessManagerFactory(
91
80
  return sdkReadinessManagerFactory(EventEmitter, settings, readinessManager.shared());
92
81
  },
93
82
 
94
- incInternalReadyCbCount() {
95
- internalReadyCbCount++;
96
- },
97
-
98
83
  sdkStatus: objectAssign(
99
84
  // Expose Event Emitter functionality
100
85
  Object.create(readinessManager.gate),
@@ -16,17 +16,17 @@ export interface IReadinessEventEmitter extends SplitIO.IEventEmitter {
16
16
 
17
17
  /** Splits data emitter */
18
18
 
19
- type SDK_SPLITS_ARRIVED = 'state::splits-arrived'
20
- type SDK_SPLITS_CACHE_LOADED = 'state::splits-cache-loaded'
21
- type ISplitsEvent = SDK_SPLITS_ARRIVED | SDK_SPLITS_CACHE_LOADED
19
+ type SDK_DEFINITIONS_ARRIVED = 'state::splits-arrived'
20
+ type SDK_DEFINITIONS_CACHE_LOADED = 'state::splits-cache-loaded'
21
+ type IDefinitionsEvent = SDK_DEFINITIONS_ARRIVED | SDK_DEFINITIONS_CACHE_LOADED
22
22
 
23
- export interface ISplitsEventEmitter extends SplitIO.IEventEmitter {
24
- emit(event: ISplitsEvent, ...args: any[]): boolean
25
- on(event: ISplitsEvent, listener: (...args: any[]) => void): this;
23
+ export interface IDefinitionsEventEmitter extends SplitIO.IEventEmitter {
24
+ emit(event: IDefinitionsEvent, ...args: any[]): boolean
25
+ on(event: IDefinitionsEvent, listener: (...args: any[]) => void): this;
26
26
  on(event: SDK_UPDATE, listener: (metadata: SplitIO.SdkUpdateMetadata) => void): this;
27
- once(event: ISplitsEvent, listener: (...args: any[]) => void): this;
28
- splitsArrived: boolean
29
- splitsCacheLoaded: boolean
27
+ once(event: IDefinitionsEvent, listener: (...args: any[]) => void): this;
28
+ definitionsArrived: boolean
29
+ definitionsCacheLoaded: boolean
30
30
  hasInit: boolean,
31
31
  initCallbacks: (() => void)[]
32
32
  }
@@ -48,7 +48,7 @@ export interface ISegmentsEventEmitter extends SplitIO.IEventEmitter {
48
48
 
49
49
  export interface IReadinessManager {
50
50
  /** Event emitters */
51
- splits: ISplitsEventEmitter,
51
+ definitions: IDefinitionsEventEmitter,
52
52
  segments: ISegmentsEventEmitter,
53
53
  gate: IReadinessEventEmitter,
54
54
 
@@ -77,12 +77,6 @@ export interface ISdkReadinessManager {
77
77
  readinessManager: IReadinessManager
78
78
  sdkStatus: SplitIO.IStatusInterface
79
79
 
80
- /**
81
- * Increment internalReadyCbCount, an offset value of SDK_READY listeners that are added/removed internally
82
- * by the SDK. It is required to properly log the warning 'No listeners for SDK Readiness detected'
83
- */
84
- incInternalReadyCbCount(): void
85
-
86
80
  /** for client-side */
87
81
  shared(): ISdkReadinessManager
88
82
  }
@@ -1,17 +1,17 @@
1
1
  import { evaluateFeature, evaluateFeatures, evaluateFeaturesByFlagSets } from '../evaluator';
2
2
  import { thenable } from '../utils/promise/thenable';
3
3
  import { getMatching, getBucketing } from '../utils/key';
4
- import { validateSplitExistence } from '../utils/inputValidation/splitExistence';
5
- import { validateTrafficTypeExistence } from '../utils/inputValidation/trafficTypeExistence';
4
+ import { validateDefinitionExistence } from '../utils/inputValidation/definitionExistence';
6
5
  import { SDK_NOT_READY } from '../utils/labels';
7
- import { CONTROL, TREATMENT, TREATMENTS, TREATMENT_WITH_CONFIG, TREATMENTS_WITH_CONFIG, TRACK, TREATMENTS_WITH_CONFIG_BY_FLAGSETS, TREATMENTS_BY_FLAGSETS, TREATMENTS_BY_FLAGSET, TREATMENTS_WITH_CONFIG_BY_FLAGSET, GET_TREATMENTS_WITH_CONFIG, GET_TREATMENTS_BY_FLAG_SETS, GET_TREATMENTS_WITH_CONFIG_BY_FLAG_SETS, GET_TREATMENTS_BY_FLAG_SET, GET_TREATMENTS_WITH_CONFIG_BY_FLAG_SET, GET_TREATMENT_WITH_CONFIG, GET_TREATMENT, GET_TREATMENTS, TRACK_FN_LABEL } from '../utils/constants';
6
+ import { CONTROL, TREATMENT, TREATMENTS, TREATMENT_WITH_CONFIG, TREATMENTS_WITH_CONFIG, TREATMENTS_WITH_CONFIG_BY_FLAGSETS, TREATMENTS_BY_FLAGSETS, TREATMENTS_BY_FLAGSET, TREATMENTS_WITH_CONFIG_BY_FLAGSET, GET_TREATMENTS_WITH_CONFIG, GET_TREATMENTS_BY_FLAG_SETS, GET_TREATMENTS_WITH_CONFIG_BY_FLAG_SETS, GET_TREATMENTS_BY_FLAG_SET, GET_TREATMENTS_WITH_CONFIG_BY_FLAG_SET, GET_TREATMENT_WITH_CONFIG, GET_TREATMENT, GET_TREATMENTS } from '../utils/constants';
8
7
  import { IEvaluationResult } from '../evaluator/types';
9
8
  import SplitIO from '../../types/splitio';
10
- import { IMPRESSION, IMPRESSION_QUEUEING } from '../logger/constants';
9
+ import { IMPRESSION_QUEUEING } from '../logger/constants';
11
10
  import { ISdkFactoryContext } from '../sdkFactory/types';
12
11
  import { isConsumerMode } from '../utils/settingsValidation/mode';
13
12
  import { Method } from '../sync/submitters/types';
14
13
  import { ImpressionDecorated } from '../trackers/types';
14
+ import { trackMethodFactory } from './trackMethod';
15
15
 
16
16
  const treatmentNotReady = { treatment: CONTROL, label: SDK_NOT_READY };
17
17
 
@@ -23,7 +23,7 @@ function treatmentsNotReady(featureFlagNames: string[]) {
23
23
  return evaluations;
24
24
  }
25
25
 
26
- function stringify(options?: SplitIO.EvaluationOptions) {
26
+ export function stringify(options?: SplitIO.EvaluationOptions) {
27
27
  if (options && options.properties) {
28
28
  try {
29
29
  return JSON.stringify(options.properties);
@@ -35,7 +35,7 @@ function stringify(options?: SplitIO.EvaluationOptions) {
35
35
  * Creator of base client with getTreatments and track methods.
36
36
  */
37
37
  export function clientFactory(params: ISdkFactoryContext): SplitIO.IClient | SplitIO.IAsyncClient {
38
- const { sdkReadinessManager: { readinessManager }, storage, settings, impressionsTracker, eventTracker, telemetryTracker, fallbackTreatmentsCalculator } = params;
38
+ const { sdkReadinessManager: { readinessManager }, storage, settings, impressionsTracker, telemetryTracker, fallbackCalculator } = params;
39
39
  const { log, mode } = settings;
40
40
  const isAsync = isConsumerMode(mode);
41
41
 
@@ -147,16 +147,14 @@ export function clientFactory(params: ISdkFactoryContext): SplitIO.IClient | Spl
147
147
  let { treatment, label, config = null } = evaluation;
148
148
 
149
149
  if (treatment === CONTROL) {
150
- const fallbackTreatment = fallbackTreatmentsCalculator.resolve(featureFlagName, label);
150
+ const fallbackTreatment = fallbackCalculator(featureFlagName, label);
151
151
  treatment = fallbackTreatment.treatment;
152
152
  label = fallbackTreatment.label;
153
153
  config = fallbackTreatment.config;
154
154
  }
155
155
 
156
- log.info(IMPRESSION, [featureFlagName, matchingKey, treatment, label]);
157
-
158
- if (validateSplitExistence(log, readinessManager, featureFlagName, label, invokingMethodName)) {
159
- log.info(IMPRESSION_QUEUEING);
156
+ if (validateDefinitionExistence(log, readinessManager, featureFlagName, label, invokingMethodName)) {
157
+ log.info(IMPRESSION_QUEUEING, ['Feature flag', featureFlagName, matchingKey, treatment, label]);
160
158
  queue.push({
161
159
  imp: {
162
160
  feature: featureFlagName,
@@ -175,42 +173,14 @@ export function clientFactory(params: ISdkFactoryContext): SplitIO.IClient | Spl
175
173
  if (withConfig) {
176
174
  return {
177
175
  treatment,
178
- config
176
+ config: config as string | null
179
177
  };
180
178
  }
181
179
 
182
180
  return treatment;
183
181
  }
184
182
 
185
- function track(key: SplitIO.SplitKey, trafficTypeName: string, eventTypeId: string, value?: number, properties?: SplitIO.Properties, size = 1024) {
186
- const stopTelemetryTracker = telemetryTracker.trackEval(TRACK);
187
-
188
- const matchingKey = getMatching(key);
189
- const timestamp = Date.now();
190
- const eventData: SplitIO.EventData = {
191
- eventTypeId,
192
- trafficTypeName,
193
- value,
194
- timestamp,
195
- key: matchingKey,
196
- properties
197
- };
198
-
199
- // 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.
200
- validateTrafficTypeExistence(log, readinessManager, storage.splits, mode, trafficTypeName, TRACK_FN_LABEL);
201
-
202
- const result = eventTracker.track(eventData, size);
203
-
204
- if (thenable(result)) {
205
- return result.then((result) => {
206
- stopTelemetryTracker();
207
- return result;
208
- });
209
- } else {
210
- stopTelemetryTracker();
211
- return result;
212
- }
213
- }
183
+ const track = trackMethodFactory(params);
214
184
 
215
185
  return {
216
186
  getTreatment,
@@ -1,31 +1,27 @@
1
1
  import {
2
2
  validateAttributes,
3
- validateEvent,
4
- validateEventValue,
5
- validateEventProperties,
6
3
  validateKey,
7
- validateSplit,
8
- validateSplits,
9
- validateTrafficType,
4
+ validateDefinition,
5
+ validateDefinitions,
10
6
  validateIfNotDestroyed,
11
7
  validateIfReadyFromCache,
12
8
  validateEvaluationOptions
13
9
  } from '../utils/inputValidation';
14
10
  import { startsWith } from '../utils/lang';
15
- import { GET_TREATMENT, GET_TREATMENTS, GET_TREATMENTS_BY_FLAG_SET, GET_TREATMENTS_BY_FLAG_SETS, GET_TREATMENTS_WITH_CONFIG, GET_TREATMENTS_WITH_CONFIG_BY_FLAG_SET, GET_TREATMENTS_WITH_CONFIG_BY_FLAG_SETS, GET_TREATMENT_WITH_CONFIG, TRACK_FN_LABEL } from '../utils/constants';
11
+ import { GET_TREATMENT, GET_TREATMENTS, GET_TREATMENTS_BY_FLAG_SET, GET_TREATMENTS_BY_FLAG_SETS, GET_TREATMENTS_WITH_CONFIG, GET_TREATMENTS_WITH_CONFIG_BY_FLAG_SET, GET_TREATMENTS_WITH_CONFIG_BY_FLAG_SETS, GET_TREATMENT_WITH_CONFIG } from '../utils/constants';
16
12
  import { IReadinessManager } from '../readiness/types';
17
13
  import { MaybeThenable } from '../dtos/types';
18
14
  import { ISettings } from '../types';
19
15
  import SplitIO from '../../types/splitio';
20
16
  import { isConsumerMode } from '../utils/settingsValidation/mode';
21
17
  import { validateFlagSets } from '../utils/settingsValidation/splitFilters';
22
- import { IFallbackTreatmentsCalculator } from '../evaluator/fallbackTreatmentsCalculator';
18
+ import { IFallbackCalculator } from '../evaluator/fallbackTreatmentsCalculator';
23
19
 
24
20
  /**
25
21
  * Decorator that validates the input before actually executing the client methods.
26
22
  * We should "guard" the client here, while not polluting the "real" implementation of those methods.
27
23
  */
28
- export function clientInputValidationDecorator<TClient extends SplitIO.IClient | SplitIO.IAsyncClient>(settings: ISettings, client: TClient, readinessManager: IReadinessManager, fallbackTreatmentsCalculator: IFallbackTreatmentsCalculator): TClient {
24
+ export function clientInputValidationDecorator<TClient extends SplitIO.IClient | SplitIO.IAsyncClient>(settings: ISettings, client: TClient, readinessManager: IReadinessManager, fallbackCalculator: IFallbackCalculator): TClient {
29
25
 
30
26
  const { log, mode } = settings;
31
27
  const isAsync = isConsumerMode(mode);
@@ -39,14 +35,14 @@ export function clientInputValidationDecorator<TClient extends SplitIO.IClient |
39
35
  const nameOrNames = methodName.indexOf('ByFlagSet') > -1 ?
40
36
  validateFlagSets(log, methodName, maybeNameOrNames as string[], settings.sync.__splitFiltersValidation.groupedFilters.bySet) :
41
37
  startsWith(methodName, GET_TREATMENTS) ?
42
- validateSplits(log, maybeNameOrNames, methodName) :
43
- validateSplit(log, maybeNameOrNames, methodName);
38
+ validateDefinitions(log, maybeNameOrNames, methodName) :
39
+ validateDefinition(log, maybeNameOrNames, methodName);
44
40
 
45
41
  const attributes = validateAttributes(log, maybeAttributes, methodName);
46
42
  const isNotDestroyed = validateIfNotDestroyed(log, readinessManager, methodName);
47
43
  const options = validateEvaluationOptions(log, maybeOptions, methodName);
48
44
 
49
- validateIfReadyFromCache(log, readinessManager, methodName, nameOrNames);
45
+ validateIfReadyFromCache(log, readinessManager, methodName);
50
46
 
51
47
  const valid = isNotDestroyed && key && nameOrNames && attributes !== false;
52
48
 
@@ -59,17 +55,20 @@ export function clientInputValidationDecorator<TClient extends SplitIO.IClient |
59
55
  };
60
56
  }
61
57
 
62
- function evaluateFallBackTreatment(featureFlagName: string, withConfig: boolean): SplitIO.Treatment | SplitIO.TreatmentWithConfig {
63
- const { treatment, config } = fallbackTreatmentsCalculator.resolve(featureFlagName, '');
58
+ function evaluateFallBackTreatment(featureFlagName: string | false | string[], withConfig: boolean) {
59
+ if (Array.isArray(featureFlagName)) {
60
+ const res: SplitIO.Treatments = {};
61
+ featureFlagName.forEach((split: string) => res[split] = evaluateFallBackTreatment(split, withConfig) as SplitIO.Treatment);
62
+ return res;
63
+ }
64
+
65
+ const { treatment, config } = fallbackCalculator(featureFlagName as string);
64
66
 
65
- if (withConfig) {
66
- return {
67
+ return withConfig ?
68
+ {
67
69
  treatment,
68
70
  config
69
- };
70
- }
71
-
72
- return treatment;
71
+ } : treatment;
73
72
  }
74
73
 
75
74
  function wrapResult<T>(value: T): MaybeThenable<T> {
@@ -79,104 +78,65 @@ export function clientInputValidationDecorator<TClient extends SplitIO.IClient |
79
78
  function getTreatment(maybeKey: SplitIO.SplitKey, maybeFeatureFlagName: string, maybeAttributes?: SplitIO.Attributes, maybeOptions?: SplitIO.EvaluationOptions) {
80
79
  const params = validateEvaluationParams(GET_TREATMENT, maybeKey, maybeFeatureFlagName, maybeAttributes, maybeOptions);
81
80
 
82
- if (params.valid) {
83
- return client.getTreatment(params.key as SplitIO.SplitKey, params.nameOrNames as string, params.attributes as SplitIO.Attributes | undefined, params.options);
84
- } else {
85
- const result = evaluateFallBackTreatment(params.nameOrNames as string, false);
86
- return wrapResult(result);
87
- }
81
+ return params.valid ?
82
+ client.getTreatment(params.key as SplitIO.SplitKey, params.nameOrNames as string, params.attributes as SplitIO.Attributes | undefined, params.options) :
83
+ wrapResult(evaluateFallBackTreatment(params.nameOrNames, false));
88
84
  }
89
85
 
90
86
  function getTreatmentWithConfig(maybeKey: SplitIO.SplitKey, maybeFeatureFlagName: string, maybeAttributes?: SplitIO.Attributes, maybeOptions?: SplitIO.EvaluationOptions) {
91
87
  const params = validateEvaluationParams(GET_TREATMENT_WITH_CONFIG, maybeKey, maybeFeatureFlagName, maybeAttributes, maybeOptions);
92
88
 
93
- if (params.valid) {
94
- return client.getTreatmentWithConfig(params.key as SplitIO.SplitKey, params.nameOrNames as string, params.attributes as SplitIO.Attributes | undefined, params.options);
95
- } else {
96
- const result = evaluateFallBackTreatment(params.nameOrNames as string, true);
97
- return wrapResult(result);
98
- }
89
+ return params.valid ?
90
+ client.getTreatmentWithConfig(params.key as SplitIO.SplitKey, params.nameOrNames as string, params.attributes as SplitIO.Attributes | undefined, params.options) :
91
+ wrapResult(evaluateFallBackTreatment(params.nameOrNames, true));
99
92
  }
100
93
 
101
94
  function getTreatments(maybeKey: SplitIO.SplitKey, maybeFeatureFlagNames: string[], maybeAttributes?: SplitIO.Attributes, maybeOptions?: SplitIO.EvaluationOptions) {
102
95
  const params = validateEvaluationParams(GET_TREATMENTS, maybeKey, maybeFeatureFlagNames, maybeAttributes, maybeOptions);
103
96
 
104
- if (params.valid) {
105
- return client.getTreatments(params.key as SplitIO.SplitKey, params.nameOrNames as string[], params.attributes as SplitIO.Attributes | undefined, params.options);
106
- } else {
107
- const res: SplitIO.Treatments = {};
108
- if (params.nameOrNames) (params.nameOrNames as string[]).forEach((split: string) => res[split] = evaluateFallBackTreatment(split, false) as SplitIO.Treatment);
109
-
110
- return wrapResult(res);
111
- }
97
+ return params.valid ?
98
+ client.getTreatments(params.key as SplitIO.SplitKey, params.nameOrNames as string[], params.attributes as SplitIO.Attributes | undefined, params.options) :
99
+ wrapResult(evaluateFallBackTreatment(params.nameOrNames || [], false));
112
100
  }
113
101
 
114
102
  function getTreatmentsWithConfig(maybeKey: SplitIO.SplitKey, maybeFeatureFlagNames: string[], maybeAttributes?: SplitIO.Attributes, maybeOptions?: SplitIO.EvaluationOptions) {
115
103
  const params = validateEvaluationParams(GET_TREATMENTS_WITH_CONFIG, maybeKey, maybeFeatureFlagNames, maybeAttributes, maybeOptions);
116
104
 
117
- if (params.valid) {
118
- return client.getTreatmentsWithConfig(params.key as SplitIO.SplitKey, params.nameOrNames as string[], params.attributes as SplitIO.Attributes | undefined, params.options);
119
- } else {
120
- const res: SplitIO.TreatmentsWithConfig = {};
121
- if (params.nameOrNames) (params.nameOrNames as string[]).forEach(split => res[split] = evaluateFallBackTreatment(split, true) as SplitIO.TreatmentWithConfig);
122
-
123
- return wrapResult(res);
124
- }
105
+ return params.valid ?
106
+ client.getTreatmentsWithConfig(params.key as SplitIO.SplitKey, params.nameOrNames as string[], params.attributes as SplitIO.Attributes | undefined, params.options) :
107
+ wrapResult(evaluateFallBackTreatment(params.nameOrNames || [], true));
125
108
  }
126
109
 
127
110
  function getTreatmentsByFlagSets(maybeKey: SplitIO.SplitKey, maybeFlagSets: string[], maybeAttributes?: SplitIO.Attributes, maybeOptions?: SplitIO.EvaluationOptions) {
128
111
  const params = validateEvaluationParams(GET_TREATMENTS_BY_FLAG_SETS, maybeKey, maybeFlagSets, maybeAttributes, maybeOptions);
129
112
 
130
- if (params.valid) {
131
- return client.getTreatmentsByFlagSets(params.key as SplitIO.SplitKey, params.nameOrNames as string[], params.attributes as SplitIO.Attributes | undefined, params.options);
132
- } else {
133
- return wrapResult({});
134
- }
113
+ return params.valid ?
114
+ client.getTreatmentsByFlagSets(params.key as SplitIO.SplitKey, params.nameOrNames as string[], params.attributes as SplitIO.Attributes | undefined, params.options) :
115
+ wrapResult({});
135
116
  }
136
117
 
137
118
  function getTreatmentsWithConfigByFlagSets(maybeKey: SplitIO.SplitKey, maybeFlagSets: string[], maybeAttributes?: SplitIO.Attributes, maybeOptions?: SplitIO.EvaluationOptions) {
138
119
  const params = validateEvaluationParams(GET_TREATMENTS_WITH_CONFIG_BY_FLAG_SETS, maybeKey, maybeFlagSets, maybeAttributes, maybeOptions);
139
120
 
140
- if (params.valid) {
141
- return client.getTreatmentsWithConfigByFlagSets(params.key as SplitIO.SplitKey, params.nameOrNames as string[], params.attributes as SplitIO.Attributes | undefined, params.options);
142
- } else {
143
- return wrapResult({});
144
- }
121
+ return params.valid ?
122
+ client.getTreatmentsWithConfigByFlagSets(params.key as SplitIO.SplitKey, params.nameOrNames as string[], params.attributes as SplitIO.Attributes | undefined, params.options) :
123
+ wrapResult({});
145
124
  }
146
125
 
147
126
  function getTreatmentsByFlagSet(maybeKey: SplitIO.SplitKey, maybeFlagSet: string, maybeAttributes?: SplitIO.Attributes, maybeOptions?: SplitIO.EvaluationOptions) {
148
127
  const params = validateEvaluationParams(GET_TREATMENTS_BY_FLAG_SET, maybeKey, [maybeFlagSet], maybeAttributes, maybeOptions);
149
128
 
150
- if (params.valid) {
151
- return client.getTreatmentsByFlagSet(params.key as SplitIO.SplitKey, (params.nameOrNames as string[])[0], params.attributes as SplitIO.Attributes | undefined, params.options);
152
- } else {
153
- return wrapResult({});
154
- }
129
+ return params.valid ?
130
+ client.getTreatmentsByFlagSet(params.key as SplitIO.SplitKey, (params.nameOrNames as string[])[0], params.attributes as SplitIO.Attributes | undefined, params.options) :
131
+ wrapResult({});
155
132
  }
156
133
 
157
134
  function getTreatmentsWithConfigByFlagSet(maybeKey: SplitIO.SplitKey, maybeFlagSet: string, maybeAttributes?: SplitIO.Attributes, maybeOptions?: SplitIO.EvaluationOptions) {
158
135
  const params = validateEvaluationParams(GET_TREATMENTS_WITH_CONFIG_BY_FLAG_SET, maybeKey, [maybeFlagSet], maybeAttributes, maybeOptions);
159
136
 
160
- if (params.valid) {
161
- return client.getTreatmentsWithConfigByFlagSet(params.key as SplitIO.SplitKey, (params.nameOrNames as string[])[0], params.attributes as SplitIO.Attributes | undefined, params.options);
162
- } else {
163
- return wrapResult({});
164
- }
165
- }
166
-
167
- function track(maybeKey: SplitIO.SplitKey, maybeTT: string, maybeEvent: string, maybeEventValue?: number, maybeProperties?: SplitIO.Properties) {
168
- const key = validateKey(log, maybeKey, TRACK_FN_LABEL);
169
- const tt = validateTrafficType(log, maybeTT, TRACK_FN_LABEL);
170
- const event = validateEvent(log, maybeEvent, TRACK_FN_LABEL);
171
- const eventValue = validateEventValue(log, maybeEventValue, TRACK_FN_LABEL);
172
- const { properties, size } = validateEventProperties(log, maybeProperties, TRACK_FN_LABEL);
173
- const isNotDestroyed = validateIfNotDestroyed(log, readinessManager, TRACK_FN_LABEL);
174
-
175
- if (isNotDestroyed && key && tt && event && eventValue !== false && properties !== false) { // @ts-expect-error
176
- return client.track(key, tt, event, eventValue, properties, size);
177
- } else {
178
- return isAsync ? Promise.resolve(false) : false;
179
- }
137
+ return params.valid ?
138
+ client.getTreatmentsWithConfigByFlagSet(params.key as SplitIO.SplitKey, (params.nameOrNames as string[])[0], params.attributes as SplitIO.Attributes | undefined, params.options) :
139
+ wrapResult({});
180
140
  }
181
141
 
182
142
  return {
@@ -188,6 +148,6 @@ export function clientInputValidationDecorator<TClient extends SplitIO.IClient |
188
148
  getTreatmentsWithConfigByFlagSets,
189
149
  getTreatmentsByFlagSet,
190
150
  getTreatmentsWithConfigByFlagSet,
191
- track
151
+ track: client.track,
192
152
  } as TClient;
193
153
  }
@@ -1,39 +1,16 @@
1
1
  import { objectAssign } from '../utils/lang/objectAssign';
2
2
  import SplitIO from '../../types/splitio';
3
- import { releaseApiKey } from '../utils/inputValidation/apiKey';
4
3
  import { clientFactory } from './client';
5
4
  import { clientInputValidationDecorator } from './clientInputValidation';
6
5
  import { ISdkFactoryContext } from '../sdkFactory/types';
7
-
8
- const COOLDOWN_TIME_IN_MILLIS = 1000;
6
+ import { sdkLifecycleFactory } from './sdkLifecycle';
9
7
 
10
8
  /**
11
- * Creates an Sdk client, i.e., a base client with status and destroy interface
9
+ * Creates an Sdk client, i.e., a base client with status, init, flush and destroy interface
12
10
  */
13
11
  export function sdkClientFactory(params: ISdkFactoryContext, isSharedClient?: boolean): SplitIO.IClient | SplitIO.IAsyncClient {
14
- const { sdkReadinessManager, syncManager, storage, signalListener, settings, telemetryTracker, uniqueKeysTracker } = params;
15
-
16
- let lastActionTime = 0;
17
-
18
- function __cooldown(func: Function, time: number) {
19
- const now = Date.now();
20
- //get the actual time elapsed in ms
21
- const timeElapsed = now - lastActionTime;
22
- //check if the time elapsed is less than desired cooldown
23
- if (timeElapsed < time) {
24
- //if yes, return message with remaining time in seconds
25
- settings.log.warn(`Flush cooldown, remaining time ${(time - timeElapsed) / 1000} seconds`);
26
- return Promise.resolve();
27
- } else {
28
- //Do the requested action and re-assign the lastActionTime
29
- lastActionTime = now;
30
- return func();
31
- }
32
- }
12
+ const { sdkReadinessManager, settings } = params;
33
13
 
34
- function __flush() {
35
- return syncManager ? syncManager.flush() : Promise.resolve();
36
- }
37
14
 
38
15
  return objectAssign(
39
16
  // Proto-linkage of the readiness Event Emitter
@@ -44,35 +21,9 @@ export function sdkClientFactory(params: ISdkFactoryContext, isSharedClient?: bo
44
21
  settings,
45
22
  clientFactory(params),
46
23
  sdkReadinessManager.readinessManager,
47
- params.fallbackTreatmentsCalculator
24
+ params.fallbackCalculator
48
25
  ),
49
26
 
50
- // Sdk destroy
51
- {
52
- flush() {
53
- // @TODO define cooldown time
54
- return __cooldown(__flush, COOLDOWN_TIME_IN_MILLIS);
55
- },
56
- destroy() {
57
- // Mark the SDK as destroyed immediately
58
- sdkReadinessManager.readinessManager.destroy();
59
-
60
- // For main client, cleanup the SDK Key, listeners and scheduled jobs, and record stat before flushing data
61
- if (!isSharedClient) {
62
- releaseApiKey(settings.core.authorizationKey);
63
- telemetryTracker.sessionLength();
64
- signalListener && signalListener.stop();
65
- uniqueKeysTracker.stop();
66
- }
67
-
68
- // Stop background jobs
69
- syncManager && syncManager.stop();
70
-
71
- return __flush().then(() => {
72
- // Cleanup storage
73
- return storage.destroy();
74
- });
75
- }
76
- }
27
+ sdkLifecycleFactory(params, isSharedClient)
77
28
  );
78
29
  }