@splitsoftware/splitio-commons 3.0.0-rc.0 → 3.0.0-rc.2

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 (189) hide show
  1. package/CHANGES.txt +8 -3
  2. package/cjs/evaluator/index.js +11 -11
  3. package/cjs/logger/constants.js +4 -4
  4. package/cjs/logger/messages/warn.js +0 -1
  5. package/cjs/readiness/constants.js +4 -4
  6. package/cjs/readiness/readinessManager.js +22 -22
  7. package/cjs/readiness/sdkReadinessManager.js +0 -16
  8. package/cjs/sdkClient/sdkLifecycle.js +2 -1
  9. package/cjs/sdkClient/trackMethod.js +2 -2
  10. package/cjs/sdkFactory/index.js +5 -5
  11. package/cjs/sdkManager/index.js +2 -2
  12. package/cjs/services/authProvider.js +67 -0
  13. package/cjs/services/secureSplitHttpClient.js +39 -0
  14. package/cjs/services/splitApi.js +15 -6
  15. package/cjs/storages/AbstractDefinitionsCacheAsync.js +51 -0
  16. package/cjs/storages/AbstractDefinitionsCacheSync.js +76 -0
  17. package/cjs/storages/KeyBuilder.js +6 -6
  18. package/cjs/storages/KeyBuilderCS.js +5 -5
  19. package/cjs/storages/KeyBuilderSS.js +2 -2
  20. package/cjs/storages/getRolloutPlan.js +3 -3
  21. package/cjs/storages/inLocalStorage/DefinitionsCacheInLocal.js +194 -0
  22. package/cjs/storages/inLocalStorage/RBSegmentsCacheInLocal.js +9 -9
  23. package/cjs/storages/inLocalStorage/index.js +6 -6
  24. package/cjs/storages/inLocalStorage/validateCache.js +3 -3
  25. package/cjs/storages/inMemory/DefinitionsCacheInMemory.js +121 -0
  26. package/cjs/storages/inMemory/InMemoryStorage.js +4 -4
  27. package/cjs/storages/inMemory/InMemoryStorageCS.js +5 -5
  28. package/cjs/storages/inMemory/RBSegmentsCacheInMemory.js +4 -4
  29. package/cjs/storages/inMemory/SegmentsCacheInMemory.js +1 -1
  30. package/cjs/storages/inMemory/TelemetryCacheInMemory.js +3 -3
  31. package/cjs/storages/inRedis/{SplitsCacheInRedis.js → DefinitionsCacheInRedis.js} +77 -77
  32. package/cjs/storages/inRedis/index.js +2 -2
  33. package/cjs/storages/pluggable/DefinitionsCachePluggable.js +212 -0
  34. package/cjs/storages/pluggable/index.js +2 -2
  35. package/cjs/storages/setRolloutPlan.js +5 -5
  36. package/cjs/sync/offline/syncTasks/fromObjectSyncTask.js +5 -5
  37. package/cjs/sync/polling/fetchers/splitChangesFetcher.js +1 -1
  38. package/cjs/sync/polling/pollingManagerCS.js +7 -7
  39. package/cjs/sync/polling/pollingManagerSS.js +3 -3
  40. package/cjs/sync/polling/syncTasks/definitionsSyncTask.js +1 -1
  41. package/cjs/sync/polling/syncTasks/segmentsSyncTask.js +2 -3
  42. package/cjs/sync/polling/updaters/definitionChangesUpdater.js +8 -8
  43. package/cjs/sync/polling/updaters/mySegmentsUpdater.js +2 -2
  44. package/cjs/sync/streaming/SSEHandler/NotificationKeeper.js +1 -1
  45. package/cjs/sync/streaming/SSEHandler/index.js +1 -1
  46. package/cjs/sync/streaming/UpdateWorkers/{SplitsUpdateWorker.js → DefinitionsUpdateWorker.js} +15 -15
  47. package/cjs/sync/streaming/constants.js +3 -3
  48. package/cjs/sync/streaming/pushManager.js +13 -13
  49. package/cjs/sync/submitters/telemetrySubmitter.js +1 -2
  50. package/cjs/sync/syncManagerOnline.js +10 -8
  51. package/cjs/utils/Backoff.js +20 -0
  52. package/cjs/utils/lang/sets.js +4 -4
  53. package/cjs/utils/settingsValidation/index.js +2 -0
  54. package/cjs/utils/settingsValidation/url.js +6 -2
  55. package/esm/evaluator/index.js +11 -11
  56. package/esm/logger/constants.js +1 -1
  57. package/esm/logger/messages/warn.js +0 -1
  58. package/esm/readiness/constants.js +3 -3
  59. package/esm/readiness/readinessManager.js +23 -23
  60. package/esm/readiness/sdkReadinessManager.js +1 -17
  61. package/esm/sdkClient/sdkLifecycle.js +2 -1
  62. package/esm/sdkClient/trackMethod.js +2 -2
  63. package/esm/sdkFactory/index.js +6 -6
  64. package/esm/sdkManager/index.js +2 -2
  65. package/esm/services/authProvider.js +63 -0
  66. package/esm/services/secureSplitHttpClient.js +35 -0
  67. package/esm/services/splitApi.js +15 -6
  68. package/esm/storages/AbstractDefinitionsCacheAsync.js +48 -0
  69. package/esm/storages/AbstractDefinitionsCacheSync.js +71 -0
  70. package/esm/storages/KeyBuilder.js +6 -6
  71. package/esm/storages/KeyBuilderCS.js +5 -5
  72. package/esm/storages/KeyBuilderSS.js +2 -2
  73. package/esm/storages/getRolloutPlan.js +3 -3
  74. package/esm/storages/inLocalStorage/DefinitionsCacheInLocal.js +191 -0
  75. package/esm/storages/inLocalStorage/RBSegmentsCacheInLocal.js +6 -6
  76. package/esm/storages/inLocalStorage/index.js +6 -6
  77. package/esm/storages/inLocalStorage/validateCache.js +3 -3
  78. package/esm/storages/inMemory/DefinitionsCacheInMemory.js +118 -0
  79. package/esm/storages/inMemory/InMemoryStorage.js +4 -4
  80. package/esm/storages/inMemory/InMemoryStorageCS.js +5 -5
  81. package/esm/storages/inMemory/RBSegmentsCacheInMemory.js +1 -1
  82. package/esm/storages/inMemory/SegmentsCacheInMemory.js +1 -1
  83. package/esm/storages/inMemory/TelemetryCacheInMemory.js +3 -3
  84. package/esm/storages/inRedis/{SplitsCacheInRedis.js → DefinitionsCacheInRedis.js} +76 -76
  85. package/esm/storages/inRedis/index.js +2 -2
  86. package/esm/storages/pluggable/DefinitionsCachePluggable.js +209 -0
  87. package/esm/storages/pluggable/index.js +2 -2
  88. package/esm/storages/setRolloutPlan.js +5 -5
  89. package/esm/sync/offline/syncTasks/fromObjectSyncTask.js +6 -6
  90. package/esm/sync/polling/fetchers/splitChangesFetcher.js +1 -1
  91. package/esm/sync/polling/pollingManagerCS.js +4 -4
  92. package/esm/sync/polling/pollingManagerSS.js +3 -3
  93. package/esm/sync/polling/syncTasks/definitionsSyncTask.js +1 -1
  94. package/esm/sync/polling/syncTasks/segmentsSyncTask.js +2 -3
  95. package/esm/sync/polling/updaters/definitionChangesUpdater.js +9 -9
  96. package/esm/sync/polling/updaters/mySegmentsUpdater.js +1 -1
  97. package/esm/sync/streaming/SSEHandler/NotificationKeeper.js +2 -2
  98. package/esm/sync/streaming/SSEHandler/index.js +2 -2
  99. package/esm/sync/streaming/UpdateWorkers/{SplitsUpdateWorker.js → DefinitionsUpdateWorker.js} +14 -14
  100. package/esm/sync/streaming/constants.js +2 -2
  101. package/esm/sync/streaming/pushManager.js +14 -14
  102. package/esm/sync/submitters/telemetrySubmitter.js +1 -2
  103. package/esm/sync/syncManagerOnline.js +9 -7
  104. package/esm/utils/Backoff.js +20 -0
  105. package/esm/utils/lang/sets.js +4 -4
  106. package/esm/utils/settingsValidation/index.js +2 -0
  107. package/esm/utils/settingsValidation/url.js +6 -2
  108. package/package.json +1 -1
  109. package/src/dtos/types.ts +2 -2
  110. package/src/evaluator/index.ts +11 -11
  111. package/src/logger/constants.ts +1 -1
  112. package/src/logger/messages/warn.ts +0 -1
  113. package/src/readiness/constants.ts +3 -3
  114. package/src/readiness/readinessManager.ts +22 -22
  115. package/src/readiness/sdkReadinessManager.ts +1 -16
  116. package/src/readiness/types.ts +10 -16
  117. package/src/sdkClient/sdkLifecycle.ts +2 -1
  118. package/src/sdkClient/trackMethod.ts +2 -2
  119. package/src/sdkFactory/index.ts +5 -5
  120. package/src/sdkManager/index.ts +6 -6
  121. package/src/services/authProvider.ts +86 -0
  122. package/src/services/secureSplitHttpClient.ts +44 -0
  123. package/src/services/splitApi.ts +18 -7
  124. package/src/services/types.ts +6 -1
  125. package/src/storages/AbstractDefinitionsCacheAsync.ts +63 -0
  126. package/src/storages/AbstractDefinitionsCacheSync.ts +95 -0
  127. package/src/storages/KeyBuilder.ts +6 -6
  128. package/src/storages/KeyBuilderCS.ts +6 -6
  129. package/src/storages/KeyBuilderSS.ts +2 -2
  130. package/src/storages/getRolloutPlan.ts +3 -3
  131. package/src/storages/inLocalStorage/DefinitionsCacheInLocal.ts +234 -0
  132. package/src/storages/inLocalStorage/RBSegmentsCacheInLocal.ts +6 -6
  133. package/src/storages/inLocalStorage/index.ts +6 -6
  134. package/src/storages/inLocalStorage/validateCache.ts +4 -4
  135. package/src/storages/inMemory/DefinitionsCacheInMemory.ts +130 -0
  136. package/src/storages/inMemory/InMemoryStorage.ts +4 -4
  137. package/src/storages/inMemory/InMemoryStorageCS.ts +5 -5
  138. package/src/storages/inMemory/RBSegmentsCacheInMemory.ts +1 -1
  139. package/src/storages/inMemory/SegmentsCacheInMemory.ts +1 -1
  140. package/src/storages/inMemory/TelemetryCacheInMemory.ts +3 -3
  141. package/src/storages/inRedis/{SplitsCacheInRedis.ts → DefinitionsCacheInRedis.ts} +67 -67
  142. package/src/storages/inRedis/index.ts +2 -2
  143. package/src/storages/pluggable/DefinitionsCachePluggable.ts +230 -0
  144. package/src/storages/pluggable/index.ts +2 -2
  145. package/src/storages/setRolloutPlan.ts +7 -7
  146. package/src/storages/types.ts +19 -19
  147. package/src/sync/offline/syncTasks/fromObjectSyncTask.ts +8 -8
  148. package/src/sync/polling/fetchers/splitChangesFetcher.ts +3 -3
  149. package/src/sync/polling/pollingManagerCS.ts +4 -4
  150. package/src/sync/polling/pollingManagerSS.ts +5 -4
  151. package/src/sync/polling/syncTasks/definitionsSyncTask.ts +1 -1
  152. package/src/sync/polling/syncTasks/segmentsSyncTask.ts +3 -4
  153. package/src/sync/polling/types.ts +1 -1
  154. package/src/sync/polling/updaters/definitionChangesUpdater.ts +11 -11
  155. package/src/sync/polling/updaters/mySegmentsUpdater.ts +1 -1
  156. package/src/sync/streaming/AuthClient/index.ts +2 -2
  157. package/src/sync/streaming/AuthClient/types.ts +14 -11
  158. package/src/sync/streaming/SSEClient/index.ts +2 -2
  159. package/src/sync/streaming/SSEClient/types.ts +2 -2
  160. package/src/sync/streaming/SSEHandler/NotificationKeeper.ts +2 -2
  161. package/src/sync/streaming/SSEHandler/index.ts +2 -2
  162. package/src/sync/streaming/UpdateWorkers/{SplitsUpdateWorker.ts → DefinitionsUpdateWorker.ts} +16 -16
  163. package/src/sync/streaming/constants.ts +2 -2
  164. package/src/sync/streaming/pushManager.ts +16 -16
  165. package/src/sync/streaming/types.ts +2 -2
  166. package/src/sync/submitters/telemetrySubmitter.ts +1 -2
  167. package/src/sync/syncManagerOnline.ts +10 -8
  168. package/src/utils/Backoff.ts +21 -0
  169. package/src/utils/inputValidation/trafficTypeExistence.ts +2 -2
  170. package/src/utils/jwt/types.ts +1 -1
  171. package/src/utils/lang/sets.ts +4 -2
  172. package/src/utils/settingsValidation/index.ts +2 -0
  173. package/src/utils/settingsValidation/url.ts +6 -2
  174. package/types/splitio.d.ts +27 -8
  175. package/cjs/storages/AbstractSplitsCacheAsync.js +0 -51
  176. package/cjs/storages/AbstractSplitsCacheSync.js +0 -76
  177. package/cjs/storages/inLocalStorage/SplitsCacheInLocal.js +0 -194
  178. package/cjs/storages/inMemory/SplitsCacheInMemory.js +0 -121
  179. package/cjs/storages/pluggable/SplitsCachePluggable.js +0 -212
  180. package/esm/storages/AbstractSplitsCacheAsync.js +0 -48
  181. package/esm/storages/AbstractSplitsCacheSync.js +0 -71
  182. package/esm/storages/inLocalStorage/SplitsCacheInLocal.js +0 -191
  183. package/esm/storages/inMemory/SplitsCacheInMemory.js +0 -118
  184. package/esm/storages/pluggable/SplitsCachePluggable.js +0 -209
  185. package/src/storages/AbstractSplitsCacheAsync.ts +0 -63
  186. package/src/storages/AbstractSplitsCacheSync.ts +0 -95
  187. package/src/storages/inLocalStorage/SplitsCacheInLocal.ts +0 -234
  188. package/src/storages/inMemory/SplitsCacheInMemory.ts +0 -130
  189. package/src/storages/pluggable/SplitsCachePluggable.ts +0 -230
@@ -6,7 +6,7 @@ export const SECONDS_BEFORE_EXPIRATION = 600;
6
6
  * emitted on SSE and Authenticate non-recoverable errors, STREAMING_DISABLED control notification and authentication with pushEnabled false
7
7
  * triggers `handleNonRetryableError` call
8
8
  */
9
- export const PUSH_NONRETRYABLE_ERROR = 'PUSH_NONRETRYABLE_ERROR';
9
+ export const PUSH_NON_RETRYABLE_ERROR = 'PUSH_NON_RETRYABLE_ERROR';
10
10
  /**
11
11
  * emitted on SSE and Authenticate recoverable errors
12
12
  * triggers `handleRetryableError` call
@@ -19,7 +19,7 @@ export const PUSH_RETRYABLE_ERROR = 'PUSH_RETRYABLE_ERROR';
19
19
  export const PUSH_SUBSYSTEM_UP = 'PUSH_SUBSYSTEM_UP';
20
20
 
21
21
  /**
22
- * emitted on STREAMING_PAUSED control notification, OCCUPANCY equal to 0, PUSH_NONRETRYABLE_ERROR and PUSH_RETRYABLE_ERROR events.
22
+ * emitted on STREAMING_PAUSED control notification, OCCUPANCY equal to 0, PUSH_NON_RETRYABLE_ERROR and PUSH_RETRYABLE_ERROR events.
23
23
  * triggers `startPolling` and `stopWorkers` calls
24
24
  */
25
25
  export const PUSH_SUBSYSTEM_DOWN = 'PUSH_SUBSYSTEM_DOWN';
@@ -6,17 +6,17 @@ import { Backoff } from '../../utils/Backoff';
6
6
  import { SSEHandlerFactory } from './SSEHandler';
7
7
  import { MySegmentsUpdateWorker } from './UpdateWorkers/MySegmentsUpdateWorker';
8
8
  import { SegmentsUpdateWorker } from './UpdateWorkers/SegmentsUpdateWorker';
9
- import { SplitsUpdateWorker } from './UpdateWorkers/SplitsUpdateWorker';
9
+ import { DefinitionsUpdateWorker } from './UpdateWorkers/DefinitionsUpdateWorker';
10
10
  import { authenticateFactory, hashUserKey } from './AuthClient';
11
11
  import { forOwn } from '../../utils/lang';
12
12
  import { SSEClient } from './SSEClient';
13
13
  import { checkIfServerSide, getMatching } from '../../utils/key';
14
- import { MEMBERSHIPS_MS_UPDATE, MEMBERSHIPS_LS_UPDATE, PUSH_NONRETRYABLE_ERROR, PUSH_SUBSYSTEM_DOWN, SECONDS_BEFORE_EXPIRATION, SEGMENT_UPDATE, SPLIT_KILL, SPLIT_UPDATE, RB_SEGMENT_UPDATE, PUSH_RETRYABLE_ERROR, PUSH_SUBSYSTEM_UP, ControlType } from './constants';
14
+ import { MEMBERSHIPS_MS_UPDATE, MEMBERSHIPS_LS_UPDATE, PUSH_NON_RETRYABLE_ERROR, PUSH_SUBSYSTEM_DOWN, SECONDS_BEFORE_EXPIRATION, SEGMENT_UPDATE, SPLIT_KILL, SPLIT_UPDATE, RB_SEGMENT_UPDATE, PUSH_RETRYABLE_ERROR, PUSH_SUBSYSTEM_UP, ControlType } from './constants';
15
15
  import { STREAMING_FALLBACK, STREAMING_REFRESH_TOKEN, STREAMING_CONNECTING, STREAMING_DISABLED, ERROR_STREAMING_AUTH, STREAMING_DISCONNECTING, STREAMING_RECONNECT, STREAMING_PARSING_MEMBERSHIPS_UPDATE } from '../../logger/constants';
16
16
  import { IMembershipMSUpdateData, IMembershipLSUpdateData, KeyList, UpdateStrategy } from './SSEHandler/types';
17
17
  import { getDelay, isInBitmap, parseBitmap, parseCompressedData } from './parseUtils';
18
18
  import { Hash64, hash64 } from '../../utils/murmur3/murmur3_64';
19
- import { IAuthTokenPushEnabled } from './AuthClient/types';
19
+ import { IJwtCredentialV2 } from './AuthClient/types';
20
20
  import { TOKEN_REFRESH, AUTH_REJECTION } from '../../utils/constants';
21
21
  import { ISdkFactoryContextSync } from '../../sdkFactory/types';
22
22
 
@@ -55,8 +55,8 @@ export function pushManagerFactory(
55
55
  // init workers
56
56
  // MySegmentsUpdateWorker (client-side) are initiated in `add` method
57
57
  const segmentsUpdateWorker = userKey ? undefined : SegmentsUpdateWorker(log, pollingManager.segmentsSyncTask as ISegmentsSyncTask, storage.segments);
58
- // For server-side we pass the segmentsSyncTask, used by SplitsUpdateWorker to fetch new segments
59
- const splitsUpdateWorker = SplitsUpdateWorker(log, storage, pollingManager.definitionsSyncTask, readiness.splits, telemetryTracker, userKey ? undefined : pollingManager.segmentsSyncTask as ISegmentsSyncTask);
58
+ // For server-side we pass the segmentsSyncTask, used by DefinitionsUpdateWorker to fetch new segments
59
+ const definitionsUpdateWorker = DefinitionsUpdateWorker(log, storage, pollingManager.definitionsSyncTask, readiness.definitions, telemetryTracker, userKey ? undefined : pollingManager.segmentsSyncTask as ISegmentsSyncTask);
60
60
 
61
61
  // [Only for client-side] map of hashes to user keys, to dispatch membership update events to the corresponding MySegmentsUpdateWorker
62
62
  const userKeyHashes: Record<string, string> = {};
@@ -67,10 +67,10 @@ export function pushManagerFactory(
67
67
  // [Only for client-side] variable to flag that a new client was added. It is needed to reconnect streaming.
68
68
  let connectForNewClient = false;
69
69
 
70
- // flag that indicates if `stop/disconnectPush` was called, either by the SyncManager, when the client is destroyed, or due to a PUSH_NONRETRYABLE_ERROR error.
70
+ // flag that indicates if `stop/disconnectPush` was called, either by the SyncManager, when the client is destroyed, or due to a PUSH_NON_RETRYABLE_ERROR error.
71
71
  // It is used to halt the `connectPush` process if it was in progress.
72
72
  let disconnected: boolean | undefined;
73
- // flag that indicates a PUSH_NONRETRYABLE_ERROR, condition with which starting pushManager again is ignored.
73
+ // flag that indicates a PUSH_NON_RETRYABLE_ERROR, condition with which starting pushManager again is ignored.
74
74
  // true if STREAMING_DISABLED control event, or 'pushEnabled: false', or non-recoverable SSE or Auth errors.
75
75
  let disabled: boolean | undefined; // `disabled` implies `disconnected === true`
76
76
 
@@ -81,7 +81,7 @@ export function pushManagerFactory(
81
81
  let timeoutIdTokenRefresh: ReturnType<typeof setTimeout>;
82
82
  let timeoutIdSseOpen: ReturnType<typeof setTimeout>;
83
83
 
84
- function scheduleTokenRefreshAndSse(authData: IAuthTokenPushEnabled) {
84
+ function scheduleTokenRefreshAndSse(authData: IJwtCredentialV2) {
85
85
  // clear scheduled tasks if exist
86
86
  if (timeoutIdTokenRefresh) clearTimeout(timeoutIdTokenRefresh);
87
87
  if (timeoutIdSseOpen) clearTimeout(timeoutIdSseOpen);
@@ -117,11 +117,11 @@ export function pushManagerFactory(
117
117
  function (authData) {
118
118
  if (disconnected) return;
119
119
 
120
- // 'pushEnabled: false' is handled as a PUSH_NONRETRYABLE_ERROR instead of PUSH_SUBSYSTEM_DOWN, in order to
120
+ // 'pushEnabled: false' is handled as a PUSH_NON_RETRYABLE_ERROR instead of PUSH_SUBSYSTEM_DOWN, in order to
121
121
  // close the sseClient in case the org has been bloqued while the instance was connected to streaming
122
122
  if (!authData.pushEnabled) {
123
123
  log.info(STREAMING_DISABLED);
124
- pushEmitter.emit(PUSH_NONRETRYABLE_ERROR);
124
+ pushEmitter.emit(PUSH_NON_RETRYABLE_ERROR);
125
125
  return;
126
126
  }
127
127
 
@@ -140,7 +140,7 @@ export function pushManagerFactory(
140
140
  // Handle 4XX HTTP errors: 401 (invalid SDK Key) or 400 (using incorrect SDK Key, i.e., client-side SDK Key on server-side)
141
141
  if (error.statusCode >= 400 && error.statusCode < 500) {
142
142
  telemetryTracker.streamingEvent(AUTH_REJECTION);
143
- pushEmitter.emit(PUSH_NONRETRYABLE_ERROR);
143
+ pushEmitter.emit(PUSH_NON_RETRYABLE_ERROR);
144
144
  return;
145
145
  }
146
146
 
@@ -168,7 +168,7 @@ export function pushManagerFactory(
168
168
 
169
169
  // cancel scheduled fetch retries of Splits, Segments, and MySegments Update Workers
170
170
  function stopWorkers() {
171
- splitsUpdateWorker.stop();
171
+ definitionsUpdateWorker.stop();
172
172
  if (userKey) forOwn(clients, ({ worker }) => worker.stop());
173
173
  else segmentsUpdateWorker!.stop();
174
174
  }
@@ -183,7 +183,7 @@ export function pushManagerFactory(
183
183
 
184
184
  /** Fallback to polling without retry due to: STREAMING_DISABLED control event, or 'pushEnabled: false', or non-recoverable SSE and Authentication errors */
185
185
 
186
- pushEmitter.on(PUSH_NONRETRYABLE_ERROR, function handleNonRetryableError() {
186
+ pushEmitter.on(PUSH_NON_RETRYABLE_ERROR, function handleNonRetryableError() {
187
187
  disabled = true;
188
188
  // Note: `stopWorkers` is been called twice, but it is not harmful
189
189
  disconnectPush();
@@ -218,9 +218,9 @@ export function pushManagerFactory(
218
218
 
219
219
  /** Functions related to synchronization (Queues and Workers in the spec) */
220
220
 
221
- pushEmitter.on(SPLIT_KILL, splitsUpdateWorker.killSplit);
222
- pushEmitter.on(SPLIT_UPDATE, splitsUpdateWorker.put);
223
- pushEmitter.on(RB_SEGMENT_UPDATE, splitsUpdateWorker.put);
221
+ pushEmitter.on(SPLIT_KILL, definitionsUpdateWorker.killDefinition);
222
+ pushEmitter.on(SPLIT_UPDATE, definitionsUpdateWorker.put);
223
+ pushEmitter.on(RB_SEGMENT_UPDATE, definitionsUpdateWorker.put);
224
224
 
225
225
  function handleMySegmentsUpdate(parsedData: IMembershipMSUpdateData | IMembershipLSUpdateData) {
226
226
  switch (parsedData.u) {
@@ -7,7 +7,7 @@ import { ControlType } from './constants';
7
7
  // Internal SDK events, subscribed by SyncManager and PushManager
8
8
  export type PUSH_SUBSYSTEM_UP = 'PUSH_SUBSYSTEM_UP'
9
9
  export type PUSH_SUBSYSTEM_DOWN = 'PUSH_SUBSYSTEM_DOWN'
10
- export type PUSH_NONRETRYABLE_ERROR = 'PUSH_NONRETRYABLE_ERROR'
10
+ export type PUSH_NON_RETRYABLE_ERROR = 'PUSH_NON_RETRYABLE_ERROR'
11
11
  export type PUSH_RETRYABLE_ERROR = 'PUSH_RETRYABLE_ERROR'
12
12
 
13
13
  // Update-type push notifications, handled by NotificationProcessor
@@ -22,7 +22,7 @@ export type RB_SEGMENT_UPDATE = 'RB_SEGMENT_UPDATE';
22
22
  export type CONTROL = 'CONTROL';
23
23
  export type OCCUPANCY = 'OCCUPANCY';
24
24
 
25
- export type IPushEvent = PUSH_SUBSYSTEM_UP | PUSH_SUBSYSTEM_DOWN | PUSH_NONRETRYABLE_ERROR | PUSH_RETRYABLE_ERROR | MEMBERSHIPS_MS_UPDATE | MEMBERSHIPS_LS_UPDATE | SEGMENT_UPDATE | SPLIT_UPDATE | SPLIT_KILL | RB_SEGMENT_UPDATE | ControlType.STREAMING_RESET
25
+ export type IPushEvent = PUSH_SUBSYSTEM_UP | PUSH_SUBSYSTEM_DOWN | PUSH_NON_RETRYABLE_ERROR | PUSH_RETRYABLE_ERROR | MEMBERSHIPS_MS_UPDATE | MEMBERSHIPS_LS_UPDATE | SEGMENT_UPDATE | SPLIT_UPDATE | SPLIT_KILL | RB_SEGMENT_UPDATE | ControlType.STREAMING_RESET
26
26
 
27
27
  type IParsedData<T extends IPushEvent> =
28
28
  T extends MEMBERSHIPS_MS_UPDATE ? IMembershipMSUpdateData :
@@ -119,7 +119,7 @@ export function telemetrySubmitterFactory(params: ISdkFactoryContextSync) {
119
119
  const { storage: { telemetry }, platform: { now } } = params;
120
120
  if (!telemetry || !now) return; // No submitter created if telemetry cache is not defined
121
121
 
122
- const { settings, settings: { log, scheduler: { telemetryRefreshRate } }, splitApi, readiness, sdkReadinessManager } = params;
122
+ const { settings, settings: { log, scheduler: { telemetryRefreshRate } }, splitApi, readiness } = params;
123
123
  const stopTimer = timer(now);
124
124
 
125
125
  const submitter = firstPushWindowDecorator(
@@ -135,7 +135,6 @@ export function telemetrySubmitterFactory(params: ISdkFactoryContextSync) {
135
135
  telemetry.recordTimeUntilReadyFromCache(stopTimer());
136
136
  });
137
137
 
138
- sdkReadinessManager.incInternalReadyCbCount();
139
138
  readiness.gate.once(SDK_READY, () => {
140
139
  telemetry.recordTimeUntilReady(stopTimer());
141
140
 
@@ -9,10 +9,11 @@ import { SYNC_START_POLLING, SYNC_CONTINUE_POLLING, SYNC_STOP_POLLING } from '..
9
9
  import { isConsentGranted } from '../consent';
10
10
  import { POLLING, STREAMING, SYNC_MODE_UPDATE } from '../utils/constants';
11
11
  import { ISdkFactoryContextSync } from '../sdkFactory/types';
12
- import { SDK_SPLITS_CACHE_LOADED } from '../readiness/constants';
13
- import { usesSegmentsSync } from '../storages/AbstractSplitsCacheSync';
12
+ import { SDK_DEFINITIONS_CACHE_LOADED } from '../readiness/constants';
13
+ import { usesSegmentsSync } from '../storages/AbstractDefinitionsCacheSync';
14
14
  import { splitChangesFetcherFactory } from './polling/fetchers/splitChangesFetcher';
15
- import { IDefinitionChangesFetcher } from './polling/fetchers/types';
15
+ import { IDefinitionChangesFetcher, ISegmentChangesFetcher } from './polling/fetchers/types';
16
+ import { segmentChangesFetcherFactory } from './polling/fetchers/segmentChangesFetcher';
16
17
 
17
18
  /**
18
19
  * Online SyncManager factory.
@@ -24,9 +25,10 @@ import { IDefinitionChangesFetcher } from './polling/fetchers/types';
24
25
  * @param definitionChangesFetcherFactory - optional to replace the default split changes fetcher
25
26
  */
26
27
  export function syncManagerOnlineFactory(
27
- pollingManagerFactory?: (params: ISdkFactoryContextSync, definitionChangesFetcher: IDefinitionChangesFetcher) => IPollingManager,
28
+ pollingManagerFactory?: (params: ISdkFactoryContextSync, definitionChangesFetcher: IDefinitionChangesFetcher, segmentChangesFetcher: ISegmentChangesFetcher) => IPollingManager,
28
29
  pushManagerFactory?: (params: ISdkFactoryContextSync, pollingManager: IPollingManager) => IPushManager | undefined,
29
- definitionChangesFetcherFactory = splitChangesFetcherFactory
30
+ definitionFetcherFactory = splitChangesFetcherFactory,
31
+ segmentFetcherFactory = (params: ISdkFactoryContextSync) => segmentChangesFetcherFactory(params.splitApi.fetchSegmentChanges)
30
32
  ): (params: ISdkFactoryContextSync) => ISyncManagerCS {
31
33
 
32
34
  /**
@@ -37,7 +39,7 @@ export function syncManagerOnlineFactory(
37
39
  const { settings, settings: { log, streamingEnabled, sync: { enabled: syncEnabled } }, telemetryTracker, storage, readiness } = params;
38
40
 
39
41
  /** Polling Manager */
40
- const pollingManager = pollingManagerFactory && pollingManagerFactory(params, definitionChangesFetcherFactory(params));
42
+ const pollingManager = pollingManagerFactory && pollingManagerFactory(params, definitionFetcherFactory(params), segmentFetcherFactory(params));
41
43
 
42
44
  /** Push Manager */
43
45
  const pushManager = syncEnabled && streamingEnabled && pollingManager && pushManagerFactory ?
@@ -45,7 +47,7 @@ export function syncManagerOnlineFactory(
45
47
  undefined;
46
48
 
47
49
  /** Submitter Manager */
48
- // It is not inyected as push and polling managers, because at the moment it is required
50
+ // It is not injected as push and polling managers, because at the moment it is required
49
51
  const submitterManager = submitterManagerFactory(params);
50
52
 
51
53
  /** Sync Manager logic */
@@ -102,7 +104,7 @@ export function syncManagerOnlineFactory(
102
104
  if (startFirstTime) {
103
105
  // Emits SDK_READY_FROM_CACHE
104
106
  if (!cacheMetadata.initialCacheLoad) {
105
- readiness.splits.emit(SDK_SPLITS_CACHE_LOADED, cacheMetadata);
107
+ readiness.definitions.emit(SDK_DEFINITIONS_CACHE_LOADED, cacheMetadata);
106
108
  }
107
109
 
108
110
  }
@@ -40,6 +40,27 @@ export class Backoff {
40
40
  return delayInMillis;
41
41
  }
42
42
 
43
+ /**
44
+ * Schedule a delayed call to `cb`
45
+ * @returns a promise that resolves/rejects with the result of the `cb` function, which must return a promise.
46
+ */
47
+ scheduleCallAsync<T>(): Promise<T> {
48
+ const delayInMillis = Math.min(this.baseMillis * Math.pow(2, this.attempts), this.maxMillis);
49
+
50
+ if (this.timeoutID) clearTimeout(this.timeoutID);
51
+ this.attempts++;
52
+
53
+ return new Promise<T>((resolve, reject) => {
54
+ this.timeoutID = setTimeout(() => {
55
+ this.timeoutID = undefined;
56
+ this.cb().then(resolve, reject);
57
+ }, delayInMillis);
58
+ });
59
+ }
60
+
61
+ /**
62
+ * Reset the backoff attempts
63
+ */
43
64
  reset() {
44
65
  this.attempts = 0;
45
66
  if (this.timeoutID) {
@@ -1,6 +1,6 @@
1
1
  import { thenable } from '../promise/thenable';
2
2
  import { LOCALHOST_MODE } from '../constants';
3
- import { ISplitsCacheBase } from '../../storages/types';
3
+ import { IDefinitionsCacheBase } from '../../storages/types';
4
4
  import { IReadinessManager } from '../../readiness/types';
5
5
  import SplitIO from '../../../types/splitio';
6
6
  import { MaybeThenable } from '../../dtos/types';
@@ -14,7 +14,7 @@ function logTTExistenceWarning(log: ILogger, maybeTT: string, method: string) {
14
14
  /**
15
15
  * Separated from the previous method since on some cases it'll be async.
16
16
  */
17
- export function validateTrafficTypeExistence(log: ILogger, readinessManager: IReadinessManager, splitsCache: ISplitsCacheBase, mode: SplitIO.SDKMode, maybeTT: string, method: string): MaybeThenable<boolean> {
17
+ export function validateTrafficTypeExistence(log: ILogger, readinessManager: IReadinessManager, splitsCache: IDefinitionsCacheBase, mode: SplitIO.SDKMode, maybeTT: string, method: string): MaybeThenable<boolean> {
18
18
 
19
19
  // If not ready or in localhost mode, we won't run the validation
20
20
  if (!readinessManager.isReady() || mode === LOCALHOST_MODE) return true;
@@ -1,6 +1,6 @@
1
1
  export interface IDecodedJWTToken {
2
2
  ['x-ably-capability']: string
3
- exp: number
3
+ exp: number // epoch seconds
4
4
  iat: number
5
5
 
6
6
  /** Unused fields: */
@@ -12,6 +12,8 @@ export function returnSetsUnion<T>(set: Set<T>, set2: Set<T>): Set<T> {
12
12
  return new Set(setToArray(set).concat(setToArray(set2)));
13
13
  }
14
14
 
15
- export function returnDifference<T>(list: T[] = [], list2: T[] = []): T[] {
16
- return list.filter(item => list2.indexOf(item) === -1);
15
+ export function returnDifference<T>(list1?: T[] | null, list2?: T[] | null): T[] {
16
+ list1 = list1 || [];
17
+ list2 = list2 || [];
18
+ return list1.filter(item => list2!.indexOf(item) === -1);
17
19
  }
@@ -58,6 +58,8 @@ export const base = {
58
58
  streaming: 'https://streaming.split.io',
59
59
  // Telemetry Server
60
60
  telemetry: 'https://telemetry.split.io/api',
61
+ // Configs Server
62
+ configs: 'https://configs.split.io/api',
61
63
  },
62
64
 
63
65
  // Defines which kind of storage we should instantiate.
@@ -1,9 +1,10 @@
1
1
  import { ISettings } from '../../types';
2
2
 
3
- const telemetryEndpointMatcher = /^\/v1\/metrics\/(config|usage)/;
3
+ const telemetryEndpointMatcher = /^\/v1\/(metrics|keys)\/(config|usage|ss|cs)/;
4
4
  const eventsEndpointMatcher = /^\/(testImpressions|metrics|events)/;
5
- const authEndpointMatcher = /^\/v2\/auth/;
5
+ const authEndpointMatcher = /^\/(v2|v3)\/auth/;
6
6
  const streamingEndpointMatcher = /^\/(sse|event-stream)/;
7
+ const configsEndpointMatcher = /^\/v1\/(configs|segmentChanges)/;
7
8
 
8
9
  /**
9
10
  * Get URL based on a given target (path).
@@ -26,5 +27,8 @@ export function url(settings: ISettings, target: string) {
26
27
  if (streamingEndpointMatcher.test(target)) {
27
28
  return `${settings.urls.streaming}${target}`;
28
29
  }
30
+ if (configsEndpointMatcher.test(target)) {
31
+ return `${settings.urls.configs}${target}`;
32
+ }
29
33
  return `${settings.urls.sdk}${target}`;
30
34
  }
@@ -495,7 +495,7 @@ declare namespace SplitIO {
495
495
  }
496
496
 
497
497
  /**
498
- * Metadata for the update event emitted when the SDK cache is updated with new data for flags or segments.
498
+ * Metadata for the update event emitted when the SDK cache is updated with new data for flags, configs, or segments.
499
499
  */
500
500
  type SdkUpdateMetadata = {
501
501
  /**
@@ -503,7 +503,7 @@ declare namespace SplitIO {
503
503
  */
504
504
  type: SdkUpdateMetadataType;
505
505
  /**
506
- * The names of the flags or segments that were updated.
506
+ * The names of the flags or configs that were updated. Empty array if the update is of type 'SEGMENTS_UPDATE'.
507
507
  */
508
508
  names: string[];
509
509
  }
@@ -644,6 +644,7 @@ declare namespace SplitIO {
644
644
  auth: string;
645
645
  streaming: string;
646
646
  telemetry: string;
647
+ configs: string;
647
648
  };
648
649
  readonly integrations?: IntegrationFactory[];
649
650
  readonly logger?: Logger;
@@ -2316,11 +2317,23 @@ declare namespace SplitIO {
2316
2317
  */
2317
2318
  authorizationKey: string;
2318
2319
  /**
2319
- * Configs definitions refresh rate for polling, in seconds.
2320
+ * Polling rate for configs and segments refresh, in seconds. Minimum value: 5.
2320
2321
  *
2321
2322
  * @defaultValue `60`
2322
2323
  */
2323
- configsRefreshRate?: number;
2324
+ pollingRate?: number;
2325
+ /**
2326
+ * Push rate for events and impressions, in seconds. Minimum value: 60.
2327
+ *
2328
+ * @defaultValue `60`
2329
+ */
2330
+ pushRate?: number;
2331
+ /**
2332
+ * Maximum queue size for events and impressions. When the queue reaches this size, a flush is triggered. Minimum value: 1000.
2333
+ *
2334
+ * @defaultValue `10000`
2335
+ */
2336
+ queueSize?: number;
2324
2337
  /**
2325
2338
  * Logging level.
2326
2339
  *
@@ -2338,11 +2351,17 @@ declare namespace SplitIO {
2338
2351
  */
2339
2352
  urls?: {
2340
2353
  /**
2341
- * String property to override the base URL where the SDK will get rollout plan related data, like feature flags and segments definitions.
2354
+ * String property to override the base URL where the SDK will get JWT authentication credentials.
2355
+ *
2356
+ * @defaultValue `'https://auth.split.io/api'`
2357
+ */
2358
+ auth?: string;
2359
+ /**
2360
+ * String property to override the base URL where the SDK will get rollout plan related data, like configs and segments definitions.
2342
2361
  *
2343
- * @defaultValue `'https://appconfig.split.io/api'`
2362
+ * @defaultValue `'https://configs.split.io/api'`
2344
2363
  */
2345
- sdk?: string;
2364
+ configs?: string;
2346
2365
  /**
2347
2366
  * String property to override the base URL where the SDK will post event-related information like impressions.
2348
2367
  *
@@ -2449,7 +2468,7 @@ declare namespace SplitIO {
2449
2468
  /**
2450
2469
  * Configs SDK client interface.
2451
2470
  */
2452
- interface ConfigsClient extends IStatusInterface {
2471
+ interface ConfigsClient extends Omit<IStatusInterface, 'ready'> {
2453
2472
  /**
2454
2473
  * Destroys the client.
2455
2474
  *
@@ -1,51 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.AbstractSplitsCacheAsync = void 0;
4
- var objectAssign_1 = require("../utils/lang/objectAssign");
5
- /**
6
- * This class provides a skeletal implementation of the ISplitsCacheAsync interface
7
- * to minimize the effort required to implement this interface.
8
- */
9
- var AbstractSplitsCacheAsync = /** @class */ (function () {
10
- function AbstractSplitsCacheAsync() {
11
- }
12
- AbstractSplitsCacheAsync.prototype.update = function (toAdd, toRemove, changeNumber) {
13
- var _this = this;
14
- return Promise.all([
15
- this.setChangeNumber(changeNumber),
16
- Promise.all(toAdd.map(function (addedFF) { return _this.addSplit(addedFF); })),
17
- Promise.all(toRemove.map(function (removedFF) { return _this.removeSplit(removedFF); }))
18
- ]).then(function (_a) {
19
- var added = _a[1], removed = _a[2];
20
- return added.some(function (result) { return result; }) || removed.some(function (result) { return result; });
21
- });
22
- };
23
- // @TODO revisit segment-related methods ('usesSegments', 'getRegisteredSegments', 'registerSegments')
24
- // noop, just keeping the interface. This is used by standalone client-side API only, and so only implemented by InMemory and InLocalStorage.
25
- AbstractSplitsCacheAsync.prototype.usesSegments = function () {
26
- return Promise.resolve(true);
27
- };
28
- /**
29
- * Kill `name` split and set `defaultTreatment` and `changeNumber`.
30
- * Used for SPLIT_KILL push notifications.
31
- *
32
- * @returns a promise that is resolved once the split kill operation is performed. The fulfillment value is a boolean: `true` if the operation successed updating the split or `false` if no split is updated,
33
- * for instance, if the `changeNumber` is old, or if the split is not found (e.g., `/splitchanges` hasn't been fetched yet), or if the storage fails to apply the update.
34
- * The promise will never be rejected.
35
- */
36
- AbstractSplitsCacheAsync.prototype.killLocally = function (name, defaultTreatment, changeNumber) {
37
- var _this = this;
38
- return this.getSplit(name).then(function (split) {
39
- if (split && (!split.changeNumber || split.changeNumber < changeNumber)) {
40
- var newSplit = (0, objectAssign_1.objectAssign)({}, split);
41
- newSplit.killed = true;
42
- newSplit.defaultTreatment = defaultTreatment;
43
- newSplit.changeNumber = changeNumber;
44
- return _this.addSplit(newSplit);
45
- }
46
- return false;
47
- }).catch(function () { return false; });
48
- };
49
- return AbstractSplitsCacheAsync;
50
- }());
51
- exports.AbstractSplitsCacheAsync = AbstractSplitsCacheAsync;
@@ -1,76 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.usesSegmentsSync = exports.usesSegments = exports.AbstractSplitsCacheSync = void 0;
4
- var objectAssign_1 = require("../utils/lang/objectAssign");
5
- var constants_1 = require("../utils/constants");
6
- /**
7
- * This class provides a skeletal implementation of the ISplitsCacheSync interface
8
- * to minimize the effort required to implement this interface.
9
- */
10
- var AbstractSplitsCacheSync = /** @class */ (function () {
11
- function AbstractSplitsCacheSync() {
12
- }
13
- AbstractSplitsCacheSync.prototype.update = function (toAdd, toRemove, changeNumber) {
14
- var _this = this;
15
- var updated = toAdd.map(function (addedFF) { return _this.addSplit(addedFF); }).some(function (result) { return result; });
16
- updated = toRemove.map(function (removedFF) { return _this.removeSplit(removedFF); }).some(function (result) { return result; }) || updated;
17
- this.setChangeNumber(changeNumber);
18
- return updated;
19
- };
20
- AbstractSplitsCacheSync.prototype.getSplits = function (names) {
21
- var _this = this;
22
- var splits = {};
23
- names.forEach(function (name) {
24
- splits[name] = _this.getSplit(name);
25
- });
26
- return splits;
27
- };
28
- AbstractSplitsCacheSync.prototype.getAll = function () {
29
- var _this = this;
30
- return this.getSplitNames().map(function (key) { return _this.getSplit(key); });
31
- };
32
- /**
33
- * Kill `name` split and set `defaultTreatment` and `changeNumber`.
34
- * Used for SPLIT_KILL push notifications.
35
- *
36
- * @returns `true` if the operation successed updating the split, or `false` if no split is updated,
37
- * for instance, if the `changeNumber` is old, or if the split is not found (e.g., `/splitchanges` hasn't been fetched yet), or if the storage fails to apply the update.
38
- */
39
- AbstractSplitsCacheSync.prototype.killLocally = function (name, defaultTreatment, changeNumber) {
40
- var split = this.getSplit(name);
41
- if (split && (!split.changeNumber || split.changeNumber < changeNumber)) {
42
- var newSplit = (0, objectAssign_1.objectAssign)({}, split);
43
- newSplit.killed = true;
44
- newSplit.defaultTreatment = defaultTreatment;
45
- newSplit.changeNumber = changeNumber;
46
- return this.addSplit(newSplit);
47
- }
48
- return false;
49
- };
50
- return AbstractSplitsCacheSync;
51
- }());
52
- exports.AbstractSplitsCacheSync = AbstractSplitsCacheSync;
53
- /**
54
- * Given a parsed split, it returns a boolean flagging if its conditions use segments matchers (rules & whitelists).
55
- * This util is intended to simplify the implementation of `splitsCache::usesSegments` method
56
- */
57
- function usesSegments(ruleEntity) {
58
- var conditions = ruleEntity.conditions || [];
59
- for (var i = 0; i < conditions.length; i++) {
60
- var matchers = conditions[i].matcherGroup.matchers;
61
- for (var j = 0; j < matchers.length; j++) {
62
- var matcher = matchers[j].matcherType;
63
- if (matcher === constants_1.IN_SEGMENT || matcher === constants_1.IN_LARGE_SEGMENT)
64
- return true;
65
- }
66
- }
67
- var excluded = ruleEntity.excluded;
68
- if (excluded && excluded.segments && excluded.segments.length > 0)
69
- return true;
70
- return false;
71
- }
72
- exports.usesSegments = usesSegments;
73
- function usesSegmentsSync(storage) {
74
- return storage.splits.usesSegments() || storage.rbSegments.usesSegments();
75
- }
76
- exports.usesSegmentsSync = usesSegmentsSync;