@splitsoftware/splitio-commons 1.17.1-rc.4 → 1.17.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 (261) hide show
  1. package/CHANGES.txt +28 -29
  2. package/LICENSE +1 -1
  3. package/README.md +4 -3
  4. package/cjs/consent/sdkUserConsent.js +4 -2
  5. package/cjs/evaluator/matchers/index.js +1 -3
  6. package/cjs/evaluator/matchers/matcherTypes.js +0 -1
  7. package/cjs/evaluator/matchers/segment.js +0 -6
  8. package/cjs/evaluator/matchersTransform/index.js +1 -4
  9. package/cjs/evaluator/matchersTransform/segment.js +1 -3
  10. package/cjs/logger/constants.js +2 -2
  11. package/cjs/logger/messages/info.js +1 -1
  12. package/cjs/logger/messages/warn.js +1 -1
  13. package/cjs/readiness/readinessManager.js +8 -18
  14. package/cjs/readiness/sdkReadinessManager.js +6 -5
  15. package/cjs/sdkClient/sdkClient.js +5 -5
  16. package/cjs/sdkClient/sdkClientMethod.js +1 -3
  17. package/cjs/sdkClient/sdkClientMethodCS.js +15 -9
  18. package/cjs/sdkClient/sdkClientMethodCSWithTT.js +15 -9
  19. package/cjs/sdkFactory/index.js +10 -32
  20. package/cjs/services/decorateHeaders.js +6 -1
  21. package/cjs/services/splitApi.js +5 -5
  22. package/cjs/services/splitHttpClient.js +5 -2
  23. package/cjs/storages/AbstractSegmentsCacheSync.js +33 -0
  24. package/cjs/storages/AbstractSplitsCacheSync.js +1 -2
  25. package/cjs/storages/KeyBuilderCS.js +5 -23
  26. package/cjs/storages/dataLoader.js +1 -1
  27. package/cjs/storages/inLocalStorage/MySegmentsCacheInLocal.js +56 -33
  28. package/cjs/storages/inLocalStorage/index.js +2 -6
  29. package/cjs/storages/inMemory/InMemoryStorageCS.js +1 -6
  30. package/cjs/storages/inMemory/MySegmentsCacheInMemory.js +44 -13
  31. package/cjs/storages/inMemory/SegmentsCacheInMemory.js +28 -14
  32. package/cjs/storages/inMemory/SplitsCacheInMemory.js +9 -8
  33. package/cjs/storages/inMemory/TelemetryCacheInMemory.js +10 -7
  34. package/cjs/storages/inRedis/SegmentsCacheInRedis.js +21 -15
  35. package/cjs/storages/inRedis/index.js +11 -5
  36. package/cjs/storages/pluggable/SegmentsCachePluggable.js +34 -13
  37. package/cjs/storages/pluggable/inMemoryWrapper.js +1 -1
  38. package/cjs/sync/offline/syncManagerOffline.js +11 -18
  39. package/cjs/sync/polling/fetchers/mySegmentsFetcher.js +8 -5
  40. package/cjs/sync/polling/fetchers/segmentChangesFetcher.js +1 -1
  41. package/cjs/sync/polling/pollingManagerCS.js +1 -1
  42. package/cjs/sync/polling/syncTasks/mySegmentsSyncTask.js +2 -2
  43. package/cjs/sync/polling/updaters/mySegmentsUpdater.js +21 -15
  44. package/cjs/sync/polling/updaters/segmentChangesUpdater.js +28 -12
  45. package/cjs/sync/polling/updaters/splitChangesUpdater.js +1 -1
  46. package/cjs/sync/streaming/AuthClient/index.js +1 -1
  47. package/cjs/sync/streaming/SSEHandler/index.js +5 -3
  48. package/cjs/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.js +48 -107
  49. package/cjs/sync/streaming/UpdateWorkers/SegmentsUpdateWorker.js +3 -3
  50. package/cjs/sync/streaming/constants.js +3 -3
  51. package/cjs/sync/streaming/parseUtils.js +9 -14
  52. package/cjs/sync/streaming/pushManager.js +67 -69
  53. package/cjs/sync/syncManagerOnline.js +21 -20
  54. package/cjs/sync/syncTask.js +2 -2
  55. package/cjs/trackers/eventTracker.js +10 -12
  56. package/cjs/trackers/impressionsTracker.js +14 -16
  57. package/cjs/trackers/uniqueKeysTracker.js +3 -5
  58. package/cjs/utils/constants/index.js +4 -5
  59. package/cjs/utils/settingsValidation/index.js +1 -2
  60. package/esm/consent/sdkUserConsent.js +4 -2
  61. package/esm/evaluator/matchers/index.js +1 -3
  62. package/esm/evaluator/matchers/matcherTypes.js +0 -1
  63. package/esm/evaluator/matchers/segment.js +0 -6
  64. package/esm/evaluator/matchersTransform/index.js +1 -4
  65. package/esm/evaluator/matchersTransform/segment.js +1 -3
  66. package/esm/logger/constants.js +1 -1
  67. package/esm/logger/messages/info.js +1 -1
  68. package/esm/logger/messages/warn.js +1 -1
  69. package/esm/readiness/readinessManager.js +8 -18
  70. package/esm/readiness/sdkReadinessManager.js +6 -5
  71. package/esm/sdkClient/sdkClient.js +5 -5
  72. package/esm/sdkClient/sdkClientMethod.js +1 -3
  73. package/esm/sdkClient/sdkClientMethodCS.js +13 -7
  74. package/esm/sdkClient/sdkClientMethodCSWithTT.js +13 -7
  75. package/esm/sdkFactory/index.js +10 -32
  76. package/esm/services/decorateHeaders.js +4 -0
  77. package/esm/services/splitApi.js +6 -6
  78. package/esm/services/splitHttpClient.js +6 -3
  79. package/esm/storages/AbstractSegmentsCacheSync.js +30 -0
  80. package/esm/storages/AbstractSplitsCacheSync.js +2 -3
  81. package/esm/storages/KeyBuilderCS.js +4 -21
  82. package/esm/storages/dataLoader.js +1 -1
  83. package/esm/storages/inLocalStorage/MySegmentsCacheInLocal.js +56 -33
  84. package/esm/storages/inLocalStorage/index.js +3 -7
  85. package/esm/storages/inMemory/InMemoryStorageCS.js +1 -6
  86. package/esm/storages/inMemory/MySegmentsCacheInMemory.js +44 -13
  87. package/esm/storages/inMemory/SegmentsCacheInMemory.js +28 -14
  88. package/esm/storages/inMemory/SplitsCacheInMemory.js +9 -8
  89. package/esm/storages/inMemory/TelemetryCacheInMemory.js +10 -7
  90. package/esm/storages/inRedis/SegmentsCacheInRedis.js +21 -15
  91. package/esm/storages/inRedis/index.js +11 -5
  92. package/esm/storages/pluggable/SegmentsCachePluggable.js +34 -13
  93. package/esm/storages/pluggable/inMemoryWrapper.js +1 -1
  94. package/esm/sync/offline/syncManagerOffline.js +11 -18
  95. package/esm/sync/polling/fetchers/mySegmentsFetcher.js +8 -5
  96. package/esm/sync/polling/fetchers/segmentChangesFetcher.js +1 -1
  97. package/esm/sync/polling/pollingManagerCS.js +1 -1
  98. package/esm/sync/polling/syncTasks/mySegmentsSyncTask.js +2 -2
  99. package/esm/sync/polling/updaters/mySegmentsUpdater.js +21 -15
  100. package/esm/sync/polling/updaters/segmentChangesUpdater.js +28 -12
  101. package/esm/sync/polling/updaters/splitChangesUpdater.js +1 -1
  102. package/esm/sync/streaming/AuthClient/index.js +1 -1
  103. package/esm/sync/streaming/SSEHandler/index.js +6 -4
  104. package/esm/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.js +49 -108
  105. package/esm/sync/streaming/UpdateWorkers/SegmentsUpdateWorker.js +3 -3
  106. package/esm/sync/streaming/constants.js +2 -2
  107. package/esm/sync/streaming/parseUtils.js +8 -12
  108. package/esm/sync/streaming/pushManager.js +70 -72
  109. package/esm/sync/syncManagerOnline.js +21 -20
  110. package/esm/sync/syncTask.js +2 -2
  111. package/esm/trackers/eventTracker.js +10 -12
  112. package/esm/trackers/impressionsTracker.js +14 -16
  113. package/esm/trackers/uniqueKeysTracker.js +3 -5
  114. package/esm/utils/constants/index.js +2 -3
  115. package/esm/utils/settingsValidation/index.js +1 -2
  116. package/package.json +2 -2
  117. package/src/consent/sdkUserConsent.ts +3 -2
  118. package/src/dtos/types.ts +7 -21
  119. package/src/evaluator/matchers/index.ts +0 -2
  120. package/src/evaluator/matchers/matcherTypes.ts +0 -1
  121. package/src/evaluator/matchers/segment.ts +0 -7
  122. package/src/evaluator/matchersTransform/index.ts +1 -4
  123. package/src/evaluator/matchersTransform/segment.ts +3 -5
  124. package/src/logger/constants.ts +1 -1
  125. package/src/logger/messages/info.ts +1 -1
  126. package/src/logger/messages/warn.ts +1 -1
  127. package/src/readiness/readinessManager.ts +8 -19
  128. package/src/readiness/sdkReadinessManager.ts +7 -7
  129. package/src/readiness/types.ts +2 -5
  130. package/src/sdkClient/sdkClient.ts +5 -5
  131. package/src/sdkClient/sdkClientMethod.ts +1 -4
  132. package/src/sdkClient/sdkClientMethodCS.ts +15 -7
  133. package/src/sdkClient/sdkClientMethodCSWithTT.ts +15 -7
  134. package/src/sdkFactory/index.ts +12 -35
  135. package/src/sdkFactory/types.ts +1 -4
  136. package/src/services/decorateHeaders.ts +5 -0
  137. package/src/services/splitApi.ts +7 -7
  138. package/src/services/splitHttpClient.ts +7 -4
  139. package/src/services/types.ts +2 -2
  140. package/src/storages/AbstractSegmentsCacheSync.ts +68 -0
  141. package/src/storages/AbstractSplitsCacheSync.ts +3 -4
  142. package/src/storages/KeyBuilderCS.ts +5 -34
  143. package/src/storages/dataLoader.ts +1 -1
  144. package/src/storages/inLocalStorage/MySegmentsCacheInLocal.ts +63 -33
  145. package/src/storages/inLocalStorage/index.ts +4 -8
  146. package/src/storages/inMemory/InMemoryStorageCS.ts +1 -6
  147. package/src/storages/inMemory/MySegmentsCacheInMemory.ts +47 -13
  148. package/src/storages/inMemory/SegmentsCacheInMemory.ts +27 -13
  149. package/src/storages/inMemory/SplitsCacheInMemory.ts +9 -7
  150. package/src/storages/inMemory/TelemetryCacheInMemory.ts +11 -7
  151. package/src/storages/inRedis/SegmentsCacheInRedis.ts +24 -15
  152. package/src/storages/inRedis/index.ts +12 -6
  153. package/src/storages/pluggable/SegmentsCachePluggable.ts +37 -13
  154. package/src/storages/pluggable/inMemoryWrapper.ts +1 -1
  155. package/src/storages/types.ts +17 -15
  156. package/src/sync/offline/syncManagerOffline.ts +13 -21
  157. package/src/sync/polling/fetchers/mySegmentsFetcher.ts +10 -8
  158. package/src/sync/polling/fetchers/segmentChangesFetcher.ts +1 -1
  159. package/src/sync/polling/fetchers/types.ts +2 -3
  160. package/src/sync/polling/pollingManagerCS.ts +4 -4
  161. package/src/sync/polling/syncTasks/mySegmentsSyncTask.ts +5 -4
  162. package/src/sync/polling/types.ts +6 -7
  163. package/src/sync/polling/updaters/mySegmentsUpdater.ts +22 -19
  164. package/src/sync/polling/updaters/segmentChangesUpdater.ts +29 -13
  165. package/src/sync/polling/updaters/splitChangesUpdater.ts +1 -1
  166. package/src/sync/streaming/AuthClient/index.ts +1 -1
  167. package/src/sync/streaming/SSEClient/index.ts +6 -4
  168. package/src/sync/streaming/SSEHandler/index.ts +8 -5
  169. package/src/sync/streaming/SSEHandler/types.ts +15 -15
  170. package/src/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.ts +49 -116
  171. package/src/sync/streaming/UpdateWorkers/SegmentsUpdateWorker.ts +4 -4
  172. package/src/sync/streaming/UpdateWorkers/SplitsUpdateWorker.ts +1 -1
  173. package/src/sync/streaming/UpdateWorkers/types.ts +2 -2
  174. package/src/sync/streaming/constants.ts +2 -2
  175. package/src/sync/streaming/parseUtils.ts +11 -19
  176. package/src/sync/streaming/pushManager.ts +72 -73
  177. package/src/sync/streaming/types.ts +10 -10
  178. package/src/sync/submitters/types.ts +5 -8
  179. package/src/sync/syncManagerOnline.ts +17 -17
  180. package/src/sync/syncTask.ts +2 -2
  181. package/src/sync/types.ts +1 -1
  182. package/src/trackers/eventTracker.ts +8 -11
  183. package/src/trackers/impressionsTracker.ts +10 -13
  184. package/src/trackers/types.ts +0 -1
  185. package/src/trackers/uniqueKeysTracker.ts +4 -6
  186. package/src/types.ts +1 -7
  187. package/src/utils/constants/index.ts +2 -3
  188. package/src/utils/settingsValidation/index.ts +2 -3
  189. package/src/utils/settingsValidation/types.ts +1 -1
  190. package/types/dtos/types.d.ts +7 -18
  191. package/types/evaluator/matchersTransform/segment.d.ts +2 -2
  192. package/types/logger/constants.d.ts +1 -1
  193. package/types/readiness/readinessManager.d.ts +2 -2
  194. package/types/readiness/sdkReadinessManager.d.ts +3 -2
  195. package/types/readiness/types.d.ts +2 -5
  196. package/types/sdkClient/sdkClientMethod.d.ts +1 -1
  197. package/types/sdkFactory/types.d.ts +1 -3
  198. package/types/services/decorateHeaders.d.ts +1 -0
  199. package/types/services/splitApi.d.ts +1 -1
  200. package/types/services/splitHttpClient.d.ts +1 -1
  201. package/types/services/types.d.ts +2 -2
  202. package/types/storages/AbstractSegmentsCacheSync.d.ts +11 -9
  203. package/types/storages/AbstractSplitsCacheSync.d.ts +1 -1
  204. package/types/storages/KeyBuilderCS.d.ts +2 -9
  205. package/types/storages/inLocalStorage/MySegmentsCacheInLocal.d.ts +18 -8
  206. package/types/storages/inMemory/MySegmentsCacheInMemory.d.ts +13 -7
  207. package/types/storages/inMemory/SegmentsCacheInMemory.d.ts +8 -6
  208. package/types/storages/inMemory/SplitsCacheInMemory.d.ts +2 -1
  209. package/types/storages/inMemory/TelemetryCacheInMemory.d.ts +6 -4
  210. package/types/storages/inRedis/SegmentsCacheInRedis.d.ts +4 -7
  211. package/types/storages/inRedis/index.d.ts +1 -1
  212. package/types/storages/pluggable/SegmentsCachePluggable.d.ts +17 -5
  213. package/types/storages/pluggable/inMemoryWrapper.d.ts +1 -1
  214. package/types/storages/types.d.ts +15 -11
  215. package/types/sync/polling/fetchers/mySegmentsFetcher.d.ts +2 -2
  216. package/types/sync/polling/fetchers/types.d.ts +2 -2
  217. package/types/sync/polling/syncTasks/mySegmentsSyncTask.d.ts +2 -2
  218. package/types/sync/polling/types.d.ts +4 -7
  219. package/types/sync/polling/updaters/mySegmentsUpdater.d.ts +3 -4
  220. package/types/sync/streaming/SSEHandler/types.d.ts +14 -16
  221. package/types/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.d.ts +2 -4
  222. package/types/sync/streaming/UpdateWorkers/SegmentsUpdateWorker.d.ts +1 -2
  223. package/types/sync/streaming/UpdateWorkers/SplitsUpdateWorker.d.ts +2 -3
  224. package/types/sync/streaming/UpdateWorkers/types.d.ts +2 -2
  225. package/types/sync/streaming/constants.d.ts +2 -2
  226. package/types/sync/streaming/parseUtils.d.ts +5 -4
  227. package/types/sync/streaming/types.d.ts +8 -8
  228. package/types/sync/submitters/types.d.ts +4 -7
  229. package/types/sync/types.d.ts +1 -1
  230. package/types/trackers/eventTracker.d.ts +1 -1
  231. package/types/trackers/impressionsTracker.d.ts +1 -1
  232. package/types/trackers/types.d.ts +0 -1
  233. package/types/types.d.ts +1 -7
  234. package/types/utils/constants/index.d.ts +2 -3
  235. package/types/utils/settingsValidation/types.d.ts +1 -1
  236. package/cjs/evaluator/matchers/large_segment.js +0 -16
  237. package/cjs/sdkClient/identity.js +0 -7
  238. package/cjs/storages/AbstractMySegmentsCacheSync.js +0 -60
  239. package/esm/evaluator/matchers/large_segment.js +0 -12
  240. package/esm/sdkClient/identity.js +0 -3
  241. package/esm/storages/AbstractMySegmentsCacheSync.js +0 -57
  242. package/src/evaluator/matchers/large_segment.ts +0 -18
  243. package/src/sdkClient/identity.ts +0 -5
  244. package/src/storages/AbstractMySegmentsCacheSync.ts +0 -94
  245. package/types/evaluator/matchers/large_segment.d.ts +0 -5
  246. package/types/evaluator/matchers/sember_inlist.d.ts +0 -3
  247. package/types/evaluator/matchersTransform/set.d.ts +0 -5
  248. package/types/evaluator/matchersTransform/string.d.ts +0 -7
  249. package/types/sdkClient/identity.d.ts +0 -2
  250. package/types/storages/AbstractMySegmentsCacheSync.d.ts +0 -39
  251. package/types/storages/AbstractSplitsCache.d.ts +0 -46
  252. package/types/sync/streaming/mySegmentsV2utils.d.ts +0 -27
  253. package/types/sync/streaming/pushManagerCS_Spec1_3.d.ts +0 -9
  254. package/types/sync/streaming/pushManager_Spec1_3.d.ts +0 -9
  255. package/types/trackers/impressionObserver/utils.d.ts +0 -5
  256. package/types/utils/inputValidation/sdkKey.d.ts +0 -7
  257. package/types/utils/inputValidation/splitExistance.d.ts +0 -7
  258. package/types/utils/inputValidation/trafficTypeExistance.d.ts +0 -9
  259. package/types/utils/redis/RedisMock.d.ts +0 -4
  260. package/types/utils/settingsValidation/logger/globalLogLevel.d.ts +0 -8
  261. /package/types/utils/{semVer.d.ts → Semver.d.ts} +0 -0
@@ -1,5 +1,5 @@
1
1
  import { objectAssign } from '../utils/lang/objectAssign';
2
- import { IEventEmitter, ISettings } from '../types';
2
+ import { IEventEmitter } from '../types';
3
3
  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';
4
4
  import { IReadinessEventEmitter, IReadinessManager, ISegmentsEventEmitter, ISplitsEventEmitter } from './types';
5
5
 
@@ -7,12 +7,10 @@ function splitsEventEmitterFactory(EventEmitter: new () => IEventEmitter): ISpli
7
7
  const splitsEventEmitter = objectAssign(new EventEmitter(), {
8
8
  splitsArrived: false,
9
9
  splitsCacheLoaded: false,
10
- initialized: false,
11
- initCallbacks: []
12
10
  });
13
11
 
14
12
  // `isSplitKill` condition avoids an edge-case of wrongly emitting SDK_READY if:
15
- // - `/memberships` fetch and SPLIT_KILL occurs before `/splitChanges` fetch, and
13
+ // - `/mySegments` fetch and SPLIT_KILL occurs before `/splitChanges` fetch, and
16
14
  // - storage has cached splits (for which case `splitsStorage.killLocally` can return true)
17
15
  splitsEventEmitter.on(SDK_SPLITS_ARRIVED, (isSplitKill: boolean) => { if (!isSplitKill) splitsEventEmitter.splitsArrived = true; });
18
16
  splitsEventEmitter.once(SDK_SPLITS_CACHE_LOADED, () => { splitsEventEmitter.splitsCacheLoaded = true; });
@@ -35,11 +33,9 @@ function segmentsEventEmitterFactory(EventEmitter: new () => IEventEmitter): ISe
35
33
  */
36
34
  export function readinessManagerFactory(
37
35
  EventEmitter: new () => IEventEmitter,
38
- settings: ISettings,
36
+ readyTimeout = 0,
39
37
  splits: ISplitsEventEmitter = splitsEventEmitterFactory(EventEmitter)): IReadinessManager {
40
38
 
41
- const readyTimeout = settings.startup.readyTimeout;
42
-
43
39
  const segments: ISegmentsEventEmitter = segmentsEventEmitterFactory(EventEmitter);
44
40
  const gate: IReadinessEventEmitter = new EventEmitter();
45
41
 
@@ -58,8 +54,8 @@ export function readinessManagerFactory(
58
54
  // emit SDK_READY_TIMED_OUT
59
55
  let hasTimedout = false;
60
56
 
61
- function timeout() { // eslint-disable-next-line no-use-before-define
62
- if (hasTimedout || isReady) return;
57
+ function timeout() {
58
+ if (hasTimedout) return;
63
59
  hasTimedout = true;
64
60
  syncLastUpdate();
65
61
  gate.emit(SDK_READY_TIMED_OUT, 'Split SDK emitted SDK_READY_TIMED_OUT event.');
@@ -67,8 +63,7 @@ export function readinessManagerFactory(
67
63
 
68
64
  let readyTimeoutId: ReturnType<typeof setTimeout>;
69
65
  if (readyTimeout > 0) {
70
- if (splits.initialized) readyTimeoutId = setTimeout(timeout, readyTimeout);
71
- else splits.initCallbacks.push(() => { readyTimeoutId = setTimeout(timeout, readyTimeout); });
66
+ readyTimeoutId = setTimeout(timeout, readyTimeout);
72
67
  }
73
68
 
74
69
  // emit SDK_READY and SDK_UPDATE
@@ -123,9 +118,9 @@ export function readinessManagerFactory(
123
118
  segments,
124
119
  gate,
125
120
 
126
- shared() {
121
+ shared(readyTimeout = 0) {
127
122
  refCount++;
128
- return readinessManagerFactory(EventEmitter, settings, splits);
123
+ return readinessManagerFactory(EventEmitter, readyTimeout, splits);
129
124
  },
130
125
 
131
126
  // @TODO review/remove next methods when non-recoverable errors are reworked
@@ -135,12 +130,6 @@ export function readinessManagerFactory(
135
130
  // tracking and evaluations, while keeping event listeners to emit SDK_READY_TIMED_OUT event
136
131
  setDestroyed() { isDestroyed = true; },
137
132
 
138
- init() {
139
- if (splits.initialized) return;
140
- splits.initialized = true;
141
- splits.initCallbacks.forEach(cb => cb());
142
- },
143
-
144
133
  destroy() {
145
134
  isDestroyed = true;
146
135
  syncLastUpdate();
@@ -2,8 +2,9 @@ import { objectAssign } from '../utils/lang/objectAssign';
2
2
  import { promiseWrapper } from '../utils/promise/wrapper';
3
3
  import { readinessManagerFactory } from './readinessManager';
4
4
  import { ISdkReadinessManager } from './types';
5
- import { IEventEmitter, ISettings } from '../types';
5
+ import { IEventEmitter } from '../types';
6
6
  import { SDK_READY, SDK_READY_TIMED_OUT, SDK_READY_FROM_CACHE, SDK_UPDATE } from './constants';
7
+ import { ILogger } from '../logger/types';
7
8
  import { ERROR_CLIENT_LISTENER, CLIENT_READY_FROM_CACHE, CLIENT_READY, CLIENT_NO_LISTENER } from '../logger/constants';
8
9
 
9
10
  const NEW_LISTENER_EVENT = 'newListener';
@@ -17,11 +18,10 @@ const REMOVE_LISTENER_EVENT = 'removeListener';
17
18
  * @param readinessManager optional readinessManager to use. only used internally for `shared` method
18
19
  */
19
20
  export function sdkReadinessManagerFactory(
21
+ log: ILogger,
20
22
  EventEmitter: new () => IEventEmitter,
21
- settings: ISettings,
22
- readinessManager = readinessManagerFactory(EventEmitter, settings)): ISdkReadinessManager {
23
-
24
- const log = settings.log;
23
+ readyTimeout = 0,
24
+ readinessManager = readinessManagerFactory(EventEmitter, readyTimeout)): ISdkReadinessManager {
25
25
 
26
26
  /** Ready callback warning */
27
27
  let internalReadyCbCount = 0;
@@ -72,8 +72,8 @@ export function sdkReadinessManagerFactory(
72
72
  return {
73
73
  readinessManager,
74
74
 
75
- shared() {
76
- return sdkReadinessManagerFactory(EventEmitter, settings, readinessManager.shared());
75
+ shared(readyTimeout = 0) {
76
+ return sdkReadinessManagerFactory(log, EventEmitter, readyTimeout, readinessManager.shared(readyTimeout));
77
77
  },
78
78
 
79
79
  incInternalReadyCbCount() {
@@ -12,8 +12,6 @@ export interface ISplitsEventEmitter extends IEventEmitter {
12
12
  once(event: ISplitsEvent, listener: (...args: any[]) => void): this;
13
13
  splitsArrived: boolean
14
14
  splitsCacheLoaded: boolean
15
- initialized: boolean,
16
- initCallbacks: (() => void)[]
17
15
  }
18
16
 
19
17
  /** Segments data emitter */
@@ -61,10 +59,9 @@ export interface IReadinessManager {
61
59
  timeout(): void,
62
60
  setDestroyed(): void,
63
61
  destroy(): void,
64
- init(): void,
65
62
 
66
63
  /** for client-side */
67
- shared(): IReadinessManager,
64
+ shared(readyTimeout?: number): IReadinessManager,
68
65
  }
69
66
 
70
67
  /** SDK readiness manager */
@@ -80,5 +77,5 @@ export interface ISdkReadinessManager {
80
77
  incInternalReadyCbCount(): void
81
78
 
82
79
  /** for client-side */
83
- shared(): ISdkReadinessManager
80
+ shared(readyTimeout?: number): ISdkReadinessManager
84
81
  }
@@ -66,11 +66,11 @@ export function sdkClientFactory(params: ISdkFactoryContext, isSharedClient?: bo
66
66
  syncManager && syncManager.stop();
67
67
 
68
68
  return __flush().then(() => {
69
- // For main client, cleanup event listeners and scheduled jobs
70
- if (!isSharedClient) {
71
- signalListener && signalListener.stop();
72
- uniqueKeysTracker && uniqueKeysTracker.stop();
73
- }
69
+ // Cleanup event listeners
70
+ signalListener && signalListener.stop();
71
+
72
+ // @TODO stop only if last client is destroyed
73
+ if (uniqueKeysTracker) uniqueKeysTracker.stop();
74
74
 
75
75
  // Cleanup storage
76
76
  return storage.destroy();
@@ -4,15 +4,12 @@ import { RETRIEVE_CLIENT_DEFAULT } from '../logger/constants';
4
4
  import { ISdkFactoryContext } from '../sdkFactory/types';
5
5
 
6
6
  /**
7
- * Factory of client method for server-side SDKs
7
+ * Factory of client method for server-side SDKs (ISDK and IAsyncSDK)
8
8
  */
9
9
  export function sdkClientMethodFactory(params: ISdkFactoryContext): () => SplitIO.IClient | SplitIO.IAsyncClient {
10
10
  const log = params.settings.log;
11
11
  const clientInstance = sdkClientFactory(params);
12
12
 
13
- // Only one client in server-side without bound key
14
- params.clients[''] = clientInstance;
15
-
16
13
  return function client() {
17
14
  if (arguments.length > 0) {
18
15
  throw new Error('Shared Client not supported by the storage mechanism. Create isolated instances instead.');
@@ -8,14 +8,18 @@ import { objectAssign } from '../utils/lang/objectAssign';
8
8
  import { RETRIEVE_CLIENT_DEFAULT, NEW_SHARED_CLIENT, RETRIEVE_CLIENT_EXISTING, LOG_PREFIX_CLIENT_INSTANTIATION } from '../logger/constants';
9
9
  import { SDK_SEGMENTS_ARRIVED } from '../readiness/constants';
10
10
  import { ISdkFactoryContext } from '../sdkFactory/types';
11
- import { buildInstanceId } from './identity';
11
+
12
+ function buildInstanceId(key: SplitIO.SplitKey) {
13
+ // @ts-ignore
14
+ return `${key.matchingKey ? key.matchingKey : key}-${key.bucketingKey ? key.bucketingKey : key}-`;
15
+ }
12
16
 
13
17
  /**
14
18
  * Factory of client method for the client-side API variant where TT is ignored.
15
19
  * Therefore, clients don't have a bound TT for the track method.
16
20
  */
17
21
  export function sdkClientMethodCSFactory(params: ISdkFactoryContext): (key?: SplitIO.SplitKey) => SplitIO.ICsClient {
18
- const { clients, storage, syncManager, sdkReadinessManager, settings: { core: { key }, log } } = params;
22
+ const { storage, syncManager, sdkReadinessManager, settings: { core: { key }, startup: { readyTimeout }, log } } = params;
19
23
 
20
24
  const mainClientInstance = clientCSDecorator(
21
25
  log,
@@ -27,7 +31,8 @@ export function sdkClientMethodCSFactory(params: ISdkFactoryContext): (key?: Spl
27
31
  const defaultInstanceId = buildInstanceId(parsedDefaultKey);
28
32
 
29
33
  // Cache instances created per factory.
30
- clients[defaultInstanceId] = mainClientInstance;
34
+ const clientInstances: Record<string, SplitIO.ICsClient> = {};
35
+ clientInstances[defaultInstanceId] = mainClientInstance;
31
36
 
32
37
  return function client(key?: SplitIO.SplitKey) {
33
38
  if (key === undefined) {
@@ -43,10 +48,10 @@ export function sdkClientMethodCSFactory(params: ISdkFactoryContext): (key?: Spl
43
48
 
44
49
  const instanceId = buildInstanceId(validKey);
45
50
 
46
- if (!clients[instanceId]) {
51
+ if (!clientInstances[instanceId]) {
47
52
  const matchingKey = getMatching(validKey);
48
53
 
49
- const sharedSdkReadiness = sdkReadinessManager.shared();
54
+ const sharedSdkReadiness = sdkReadinessManager.shared(readyTimeout);
50
55
  const sharedStorage = storage.shared && storage.shared(matchingKey, (err) => {
51
56
  if (err) {
52
57
  sharedSdkReadiness.readinessManager.timeout();
@@ -65,21 +70,24 @@ export function sdkClientMethodCSFactory(params: ISdkFactoryContext): (key?: Spl
65
70
 
66
71
  // As shared clients reuse all the storage information, we don't need to check here if we
67
72
  // will use offline or online mode. We should stick with the original decision.
68
- clients[instanceId] = clientCSDecorator(
73
+ clientInstances[instanceId] = clientCSDecorator(
69
74
  log,
70
75
  sdkClientFactory(objectAssign({}, params, {
71
76
  sdkReadinessManager: sharedSdkReadiness,
72
77
  storage: sharedStorage || storage,
73
78
  syncManager: sharedSyncManager,
79
+ signalListener: undefined, // only the main client "destroy" method stops the signal listener
74
80
  }), true) as SplitIO.IClient,
75
81
  validKey
76
82
  );
77
83
 
84
+ sharedSyncManager && sharedSyncManager.start();
85
+
78
86
  log.info(NEW_SHARED_CLIENT);
79
87
  } else {
80
88
  log.debug(RETRIEVE_CLIENT_EXISTING);
81
89
  }
82
90
 
83
- return clients[instanceId] as SplitIO.ICsClient;
91
+ return clientInstances[instanceId];
84
92
  };
85
93
  }
@@ -9,7 +9,11 @@ import { objectAssign } from '../utils/lang/objectAssign';
9
9
  import { RETRIEVE_CLIENT_DEFAULT, NEW_SHARED_CLIENT, RETRIEVE_CLIENT_EXISTING, LOG_PREFIX_CLIENT_INSTANTIATION } from '../logger/constants';
10
10
  import { SDK_SEGMENTS_ARRIVED } from '../readiness/constants';
11
11
  import { ISdkFactoryContext } from '../sdkFactory/types';
12
- import { buildInstanceId } from './identity';
12
+
13
+ function buildInstanceId(key: SplitIO.SplitKey, trafficType?: string) {
14
+ // @ts-ignore
15
+ return `${key.matchingKey ? key.matchingKey : key}-${key.bucketingKey ? key.bucketingKey : key}-${trafficType !== undefined ? trafficType : ''}`;
16
+ }
13
17
 
14
18
  /**
15
19
  * Factory of client method for the client-side (browser) variant of the Isomorphic JS SDK,
@@ -17,7 +21,7 @@ import { buildInstanceId } from './identity';
17
21
  * (default client) or the client method (shared clients).
18
22
  */
19
23
  export function sdkClientMethodCSFactory(params: ISdkFactoryContext): (key?: SplitIO.SplitKey, trafficType?: string) => SplitIO.ICsClient {
20
- const { clients, storage, syncManager, sdkReadinessManager, settings: { core: { key, trafficType }, log } } = params;
24
+ const { storage, syncManager, sdkReadinessManager, settings: { core: { key, trafficType }, startup: { readyTimeout }, log } } = params;
21
25
 
22
26
  const mainClientInstance = clientCSDecorator(
23
27
  log,
@@ -30,7 +34,8 @@ export function sdkClientMethodCSFactory(params: ISdkFactoryContext): (key?: Spl
30
34
  const defaultInstanceId = buildInstanceId(parsedDefaultKey, trafficType);
31
35
 
32
36
  // Cache instances created per factory.
33
- clients[defaultInstanceId] = mainClientInstance;
37
+ const clientInstances: Record<string, SplitIO.ICsClient> = {};
38
+ clientInstances[defaultInstanceId] = mainClientInstance;
34
39
 
35
40
  return function client(key?: SplitIO.SplitKey, trafficType?: string) {
36
41
  if (key === undefined) {
@@ -53,10 +58,10 @@ export function sdkClientMethodCSFactory(params: ISdkFactoryContext): (key?: Spl
53
58
  }
54
59
  const instanceId = buildInstanceId(validKey, validTrafficType);
55
60
 
56
- if (!clients[instanceId]) {
61
+ if (!clientInstances[instanceId]) {
57
62
  const matchingKey = getMatching(validKey);
58
63
 
59
- const sharedSdkReadiness = sdkReadinessManager.shared();
64
+ const sharedSdkReadiness = sdkReadinessManager.shared(readyTimeout);
60
65
  const sharedStorage = storage.shared && storage.shared(matchingKey, (err) => {
61
66
  if (err) {
62
67
  sharedSdkReadiness.readinessManager.timeout();
@@ -75,22 +80,25 @@ export function sdkClientMethodCSFactory(params: ISdkFactoryContext): (key?: Spl
75
80
 
76
81
  // As shared clients reuse all the storage information, we don't need to check here if we
77
82
  // will use offline or online mode. We should stick with the original decision.
78
- clients[instanceId] = clientCSDecorator(
83
+ clientInstances[instanceId] = clientCSDecorator(
79
84
  log,
80
85
  sdkClientFactory(objectAssign({}, params, {
81
86
  sdkReadinessManager: sharedSdkReadiness,
82
87
  storage: sharedStorage || storage,
83
88
  syncManager: sharedSyncManager,
89
+ signalListener: undefined, // only the main client "destroy" method stops the signal listener
84
90
  }), true) as SplitIO.IClient,
85
91
  validKey,
86
92
  validTrafficType
87
93
  );
88
94
 
95
+ sharedSyncManager && sharedSyncManager.start();
96
+
89
97
  log.info(NEW_SHARED_CLIENT);
90
98
  } else {
91
99
  log.debug(RETRIEVE_CLIENT_EXISTING);
92
100
  }
93
101
 
94
- return clients[instanceId] as SplitIO.ICsClient;
102
+ return clientInstances[instanceId];
95
103
  };
96
104
  }
@@ -3,7 +3,7 @@ import { sdkReadinessManagerFactory } from '../readiness/sdkReadinessManager';
3
3
  import { impressionsTrackerFactory } from '../trackers/impressionsTracker';
4
4
  import { eventTrackerFactory } from '../trackers/eventTracker';
5
5
  import { telemetryTrackerFactory } from '../trackers/telemetryTracker';
6
- import { IBasicClient, SplitIO } from '../types';
6
+ import { SplitIO } from '../types';
7
7
  import { validateAndTrackApiKey } from '../utils/inputValidation/apiKey';
8
8
  import { createLoggerAPI } from '../logger/sdkLogger';
9
9
  import { NEW_FACTORY, RETRIEVE_MANAGER } from '../logger/constants';
@@ -23,22 +23,16 @@ export function sdkFactory(params: ISdkFactoryParams): SplitIO.ICsSDK | SplitIO.
23
23
  const { settings, platform, storageFactory, splitApiFactory, extraProps,
24
24
  syncManagerFactory, SignalListener, impressionsObserverFactory,
25
25
  integrationsManagerFactory, sdkManagerFactory, sdkClientMethodFactory,
26
- filterAdapterFactory, lazyInit } = params;
26
+ filterAdapterFactory } = params;
27
27
  const { log, sync: { impressionsMode } } = settings;
28
28
 
29
29
  // @TODO handle non-recoverable errors, such as, global `fetch` not available, invalid SDK Key, etc.
30
30
  // On non-recoverable errors, we should mark the SDK as destroyed and not start synchronization.
31
31
 
32
- // initialization
33
- let hasInit = false;
34
- const initCallbacks: (() => void)[] = [];
32
+ // We will just log and allow for the SDK to end up throwing an SDK_TIMEOUT event for devs to handle.
33
+ validateAndTrackApiKey(log, settings.core.authorizationKey);
35
34
 
36
- function whenInit(cb: () => void) {
37
- if (hasInit) cb();
38
- else initCallbacks.push(cb);
39
- }
40
-
41
- const sdkReadinessManager = sdkReadinessManagerFactory(platform.EventEmitter, settings);
35
+ const sdkReadinessManager = sdkReadinessManagerFactory(log, platform.EventEmitter, settings.startup.readyTimeout);
42
36
  const readiness = sdkReadinessManager.readinessManager;
43
37
 
44
38
  const storage = storageFactory({
@@ -54,7 +48,7 @@ export function sdkFactory(params: ISdkFactoryParams): SplitIO.ICsSDK | SplitIO.
54
48
  },
55
49
  });
56
50
  // @TODO add support for dataloader: `if (params.dataLoader) params.dataLoader(storage);`
57
- const clients: Record<string, IBasicClient> = {};
51
+
58
52
  const telemetryTracker = telemetryTrackerFactory(storage.telemetry, platform.now);
59
53
  const integrationsManager = integrationsManagerFactory && integrationsManagerFactory({ settings, storage, telemetryTracker });
60
54
 
@@ -73,13 +67,13 @@ export function sdkFactory(params: ISdkFactoryParams): SplitIO.ICsSDK | SplitIO.
73
67
  strategy = strategyDebugFactory(observer);
74
68
  }
75
69
 
76
- const impressionsTracker = impressionsTrackerFactory(settings, storage.impressions, strategy, whenInit, integrationsManager, storage.telemetry);
77
- const eventTracker = eventTrackerFactory(settings, storage.events, whenInit, integrationsManager, storage.telemetry);
70
+ const impressionsTracker = impressionsTrackerFactory(settings, storage.impressions, strategy, integrationsManager, storage.telemetry);
71
+ const eventTracker = eventTrackerFactory(settings, storage.events, integrationsManager, storage.telemetry);
78
72
 
79
73
  // splitApi is used by SyncManager and Browser signal listener
80
74
  const splitApi = splitApiFactory && splitApiFactory(settings, platform, telemetryTracker);
81
75
 
82
- const ctx: ISdkFactoryContext = { clients, splitApi, eventTracker, impressionsTracker, telemetryTracker, uniqueKeysTracker, sdkReadinessManager, readiness, settings, storage, platform };
76
+ const ctx: ISdkFactoryContext = { splitApi, eventTracker, impressionsTracker, telemetryTracker, uniqueKeysTracker, sdkReadinessManager, readiness, settings, storage, platform };
83
77
 
84
78
  const syncManager = syncManagerFactory && syncManagerFactory(ctx as ISdkFactoryContextSync);
85
79
  ctx.syncManager = syncManager;
@@ -91,21 +85,8 @@ export function sdkFactory(params: ISdkFactoryParams): SplitIO.ICsSDK | SplitIO.
91
85
  const clientMethod = sdkClientMethodFactory(ctx);
92
86
  const managerInstance = sdkManagerFactory(settings, storage.splits, sdkReadinessManager);
93
87
 
94
-
95
- function init() {
96
- if (hasInit) return;
97
- hasInit = true;
98
-
99
- // We will just log and allow for the SDK to end up throwing an SDK_TIMEOUT event for devs to handle.
100
- validateAndTrackApiKey(log, settings.core.authorizationKey);
101
- readiness.init();
102
- uniqueKeysTracker && uniqueKeysTracker.start();
103
- syncManager && syncManager.start();
104
- signalListener && signalListener.start();
105
-
106
- initCallbacks.forEach((cb) => cb());
107
- initCallbacks.length = 0;
108
- }
88
+ syncManager && syncManager.start();
89
+ signalListener && signalListener.start();
109
90
 
110
91
  log.info(NEW_FACTORY);
111
92
 
@@ -124,9 +105,5 @@ export function sdkFactory(params: ISdkFactoryParams): SplitIO.ICsSDK | SplitIO.
124
105
  Logger: createLoggerAPI(log),
125
106
 
126
107
  settings,
127
-
128
- destroy() {
129
- return Promise.all(Object.keys(clients).map(key => clients[key].destroy())).then(() => { });
130
- }
131
- }, extraProps && extraProps(ctx), lazyInit ? { init } : init());
108
+ }, extraProps && extraProps(ctx));
132
109
  }
@@ -8,7 +8,7 @@ import { IStorageAsync, IStorageSync, IStorageFactoryParams } from '../storages/
8
8
  import { ISyncManager } from '../sync/types';
9
9
  import { IImpressionObserver } from '../trackers/impressionObserver/types';
10
10
  import { IImpressionsTracker, IEventTracker, ITelemetryTracker, IFilterAdapter, IUniqueKeysTracker } from '../trackers/types';
11
- import { SplitIO, ISettings, IEventEmitter, IBasicClient } from '../types';
11
+ import { SplitIO, ISettings, IEventEmitter } from '../types';
12
12
 
13
13
  /**
14
14
  * Environment related dependencies.
@@ -49,7 +49,6 @@ export interface ISdkFactoryContext {
49
49
  signalListener?: ISignalListener
50
50
  splitApi?: ISplitApi
51
51
  syncManager?: ISyncManager,
52
- clients: Record<string, IBasicClient>,
53
52
  }
54
53
 
55
54
  export interface ISdkFactoryContextSync extends ISdkFactoryContext {
@@ -68,8 +67,6 @@ export interface ISdkFactoryContextAsync extends ISdkFactoryContext {
68
67
  * Object parameter with the modules required to create an SDK factory instance
69
68
  */
70
69
  export interface ISdkFactoryParams {
71
- // If true, the `sdkFactory` is pure (no side effects), and the SDK instance includes a `init` method to run initialization side effects
72
- lazyInit?: boolean,
73
70
 
74
71
  // The settings must be already validated
75
72
  settings: ISettings,
@@ -31,3 +31,8 @@ export function decorateHeaders(settings: ISettings, headers: Record<string, str
31
31
  }
32
32
  return headers;
33
33
  }
34
+
35
+ export function removeNonISO88591(input: string) {
36
+ // eslint-disable-next-line no-control-regex
37
+ return input.replace(/[^\x00-\xFF]/g, '');
38
+ }
@@ -4,7 +4,7 @@ import { splitHttpClientFactory } from './splitHttpClient';
4
4
  import { ISplitApi } from './types';
5
5
  import { objectAssign } from '../utils/lang/objectAssign';
6
6
  import { ITelemetryTracker } from '../trackers/types';
7
- import { SPLITS, IMPRESSIONS, IMPRESSIONS_COUNT, EVENTS, TELEMETRY, TOKEN, SEGMENT, MEMBERSHIPS } from '../utils/constants';
7
+ import { SPLITS, IMPRESSIONS, IMPRESSIONS_COUNT, EVENTS, TELEMETRY, TOKEN, SEGMENT, MY_SEGMENT } from '../utils/constants';
8
8
  import { ERROR_TOO_MANY_SETS } from '../logger/constants';
9
9
 
10
10
  const noCacheHeaderOptions = { headers: { 'Cache-Control': 'no-cache' } };
@@ -22,7 +22,7 @@ function userKeyToQueryParam(userKey: string) {
22
22
  */
23
23
  export function splitApiFactory(
24
24
  settings: ISettings,
25
- platform: Pick<IPlatform, 'getOptions' | 'getFetch'>,
25
+ platform: IPlatform,
26
26
  telemetryTracker: ITelemetryTracker
27
27
  ): ISplitApi {
28
28
 
@@ -67,15 +67,15 @@ export function splitApiFactory(
67
67
  return splitHttpClient(url, noCache ? noCacheHeaderOptions : undefined, telemetryTracker.trackHttp(SEGMENT));
68
68
  },
69
69
 
70
- fetchMemberships(userMatchingKey: string, noCache?: boolean, till?: number) {
70
+ fetchMySegments(userMatchingKey: string, noCache?: boolean) {
71
71
  /**
72
72
  * URI encoding of user keys in order to:
73
- * - avoid 400 responses (due to URI malformed). E.g.: '/api/memberships/%'
74
- * - avoid 404 responses. E.g.: '/api/memberships/foo/bar'
73
+ * - avoid 400 responses (due to URI malformed). E.g.: '/api/mySegments/%'
74
+ * - avoid 404 responses. E.g.: '/api/mySegments/foo/bar'
75
75
  * - match user keys with special characters. E.g.: 'foo%bar', 'foo/bar'
76
76
  */
77
- const url = `${urls.sdk}/memberships/${encodeURIComponent(userMatchingKey)}${till ? '?till=' + till : ''}`;
78
- return splitHttpClient(url, noCache ? noCacheHeaderOptions : undefined, telemetryTracker.trackHttp(MEMBERSHIPS));
77
+ const url = `${urls.sdk}/mySegments/${encodeURIComponent(userMatchingKey)}`;
78
+ return splitHttpClient(url, noCache ? noCacheHeaderOptions : undefined, telemetryTracker.trackHttp(MY_SEGMENT));
79
79
  },
80
80
 
81
81
  /**
@@ -3,8 +3,10 @@ import { objectAssign } from '../utils/lang/objectAssign';
3
3
  import { ERROR_HTTP, ERROR_CLIENT_CANNOT_GET_READY } from '../logger/constants';
4
4
  import { ISettings } from '../types';
5
5
  import { IPlatform } from '../sdkFactory/types';
6
- import { decorateHeaders } from './decorateHeaders';
6
+ import { decorateHeaders, removeNonISO88591 } from './decorateHeaders';
7
+ import { timeout } from '../utils/promise/timeout';
7
8
 
9
+ const PENDING_FETCH_ERROR_TIMEOUT = 100;
8
10
  const messageNoFetch = 'Global fetch API is not available.';
9
11
 
10
12
  /**
@@ -13,7 +15,7 @@ const messageNoFetch = 'Global fetch API is not available.';
13
15
  * @param settings SDK settings, used to access authorizationKey, logger instance and metadata (SDK version, ip and hostname) to set additional headers
14
16
  * @param platform object containing environment-specific dependencies
15
17
  */
16
- export function splitHttpClientFactory(settings: ISettings, { getOptions, getFetch }: Pick<IPlatform, 'getOptions' | 'getFetch'>): ISplitHttpClient {
18
+ export function splitHttpClientFactory(settings: ISettings, { getOptions, getFetch }: IPlatform): ISplitHttpClient {
17
19
 
18
20
  const { log, core: { authorizationKey }, version, runtime: { ip, hostname } } = settings;
19
21
  const options = getOptions && getOptions(settings);
@@ -30,7 +32,7 @@ export function splitHttpClientFactory(settings: ISettings, { getOptions, getFet
30
32
  };
31
33
 
32
34
  if (ip) commonHeaders['SplitSDKMachineIP'] = ip;
33
- if (hostname) commonHeaders['SplitSDKMachineName'] = hostname;
35
+ if (hostname) commonHeaders['SplitSDKMachineName'] = removeNonISO88591(hostname);
34
36
 
35
37
  return function httpClient(url: string, reqOpts: IRequestOptions = {}, latencyTracker: (error?: NetworkError) => void = () => { }, logErrorsAsInfo: boolean = false): Promise<IResponse> {
36
38
 
@@ -45,7 +47,8 @@ export function splitHttpClientFactory(settings: ISettings, { getOptions, getFet
45
47
  // https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch#Checking_that_the_fetch_was_successful
46
48
  .then(response => {
47
49
  if (!response.ok) {
48
- return response.text().then(message => Promise.reject({ response, message }));
50
+ // `text()` promise might not settle in some fetch implementations and cases (e.g. no content)
51
+ return timeout(PENDING_FETCH_ERROR_TIMEOUT, response.text()).then(message => Promise.reject({ response, message }), () => Promise.reject({ response }));
49
52
  }
50
53
  latencyTracker();
51
54
  return response;
@@ -39,7 +39,7 @@ export type IFetchSplitChanges = (since: number, noCache?: boolean, till?: numbe
39
39
 
40
40
  export type IFetchSegmentChanges = (since: number, segmentName: string, noCache?: boolean, till?: number) => Promise<IResponse>
41
41
 
42
- export type IFetchMemberships = (userMatchingKey: string, noCache?: boolean, till?: number) => Promise<IResponse>
42
+ export type IFetchMySegments = (userMatchingKey: string, noCache?: boolean) => Promise<IResponse>
43
43
 
44
44
  export type IPostEventsBulk = (body: string, headers?: Record<string, string>) => Promise<IResponse>
45
45
 
@@ -61,7 +61,7 @@ export interface ISplitApi {
61
61
  fetchAuth: IFetchAuth
62
62
  fetchSplitChanges: IFetchSplitChanges
63
63
  fetchSegmentChanges: IFetchSegmentChanges
64
- fetchMemberships: IFetchMemberships
64
+ fetchMySegments: IFetchMySegments
65
65
  postEventsBulk: IPostEventsBulk
66
66
  postUniqueKeysBulkCs: IPostUniqueKeysBulkCs
67
67
  postUniqueKeysBulkSs: IPostUniqueKeysBulkSs
@@ -0,0 +1,68 @@
1
+ /* eslint-disable @typescript-eslint/no-unused-vars */
2
+ /* eslint-disable no-unused-vars */
3
+ import { ISegmentsCacheSync } from './types';
4
+
5
+ /**
6
+ * This class provides a skeletal implementation of the ISegmentsCacheSync interface
7
+ * to minimize the effort required to implement this interface.
8
+ */
9
+ export abstract class AbstractSegmentsCacheSync implements ISegmentsCacheSync {
10
+ /**
11
+ * For server-side synchronizer: add `segmentKeys` list of keys to `name` segment.
12
+ * For client-side synchronizer: add `name` segment to the cache. `segmentKeys` is undefined.
13
+ */
14
+ abstract addToSegment(name: string, segmentKeys?: string[]): boolean
15
+
16
+ /**
17
+ * For server-side synchronizer: remove `segmentKeys` list of keys from `name` segment.
18
+ * For client-side synchronizer: remove `name` segment from the cache. `segmentKeys` is undefined.
19
+ */
20
+ abstract removeFromSegment(name: string, segmentKeys?: string[]): boolean
21
+
22
+ /**
23
+ * For server-side synchronizer: check if `key` is in `name` segment.
24
+ * For client-side synchronizer: check if `name` segment is in the cache. `key` is undefined.
25
+ */
26
+ abstract isInSegment(name: string, key?: string): boolean
27
+
28
+ /**
29
+ * clear the cache.
30
+ */
31
+ abstract clear(): void
32
+
33
+ /**
34
+ * For server-side synchronizer: add the given list of segments to the cache, with an empty list of keys. The segments that already exist are not modified.
35
+ * For client-side synchronizer: the method is not used.
36
+ */
37
+ registerSegments(names: string[]): boolean { return false; }
38
+
39
+ /**
40
+ * For server-side synchronizer: get the list of segments to fetch changes.
41
+ * Also used for the `seC` (segment count) telemetry stat.
42
+ */
43
+ abstract getRegisteredSegments(): string[]
44
+
45
+ /**
46
+ * Only used for the `skC`(segment keys count) telemetry stat: 1 for client-side, and total count of keys in server-side.
47
+ * @TODO for client-side it should be the number of clients, but it requires a refactor of MySegments caches to simplify the code.
48
+ */
49
+ abstract getKeysCount(): number
50
+
51
+ /**
52
+ * For server-side synchronizer: set the change number of `name` segment.
53
+ * For client-side synchronizer: the method is not used.
54
+ */
55
+ setChangeNumber(name: string, changeNumber: number): boolean { return true; }
56
+
57
+ /**
58
+ * For server-side synchronizer: get the change number of `name` segment.
59
+ * For client-side synchronizer: the method is not used.
60
+ */
61
+ getChangeNumber(name: string): number | undefined { return -1; }
62
+
63
+ /**
64
+ * For server-side synchronizer: the method is not used.
65
+ * For client-side synchronizer: reset the cache with the given list of segments.
66
+ */
67
+ resetSegments(names: string[]): boolean { return true; }
68
+ }
@@ -2,7 +2,7 @@ import { ISplitsCacheSync } from './types';
2
2
  import { ISplit } from '../dtos/types';
3
3
  import { objectAssign } from '../utils/lang/objectAssign';
4
4
  import { ISet } from '../utils/lang/sets';
5
- import { IN_SEGMENT, IN_LARGE_SEGMENT } from '../utils/constants';
5
+ import { IN_SEGMENT } from '../utils/constants';
6
6
 
7
7
  /**
8
8
  * This class provides a skeletal implementation of the ISplitsCacheSync interface
@@ -32,7 +32,7 @@ export abstract class AbstractSplitsCacheSync implements ISplitsCacheSync {
32
32
  return splits;
33
33
  }
34
34
 
35
- abstract setChangeNumber(changeNumber: number): boolean | void
35
+ abstract setChangeNumber(changeNumber: number): boolean
36
36
 
37
37
  abstract getChangeNumber(): number
38
38
 
@@ -94,8 +94,7 @@ export function usesSegments(split: ISplit) {
94
94
  const matchers = conditions[i].matcherGroup.matchers;
95
95
 
96
96
  for (let j = 0; j < matchers.length; j++) {
97
- const matcher = matchers[j].matcherType;
98
- if (matcher === IN_SEGMENT || matcher === IN_LARGE_SEGMENT) return true;
97
+ if (matchers[j].matcherType === IN_SEGMENT) return true;
99
98
  }
100
99
  }
101
100