@splitsoftware/splitio-commons 2.3.0 → 2.3.1-rc.0

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 (157) hide show
  1. package/CHANGES.txt +4 -0
  2. package/README.md +1 -0
  3. package/cjs/evaluator/Engine.js +40 -61
  4. package/cjs/evaluator/combiners/and.js +2 -6
  5. package/cjs/evaluator/combiners/ifelseif.js +6 -6
  6. package/cjs/evaluator/condition/index.js +6 -5
  7. package/cjs/evaluator/index.js +11 -11
  8. package/cjs/evaluator/matchers/index.js +3 -1
  9. package/cjs/evaluator/matchers/matcherTypes.js +1 -0
  10. package/cjs/evaluator/matchers/prerequisites.js +22 -0
  11. package/cjs/evaluator/matchers/rbsegment.js +56 -0
  12. package/cjs/evaluator/matchersTransform/index.js +4 -0
  13. package/cjs/evaluator/parser/index.js +2 -2
  14. package/cjs/evaluator/value/sanitize.js +1 -0
  15. package/cjs/logger/constants.js +5 -3
  16. package/cjs/logger/messages/debug.js +4 -2
  17. package/cjs/logger/messages/warn.js +1 -1
  18. package/cjs/sdkManager/index.js +2 -1
  19. package/cjs/services/splitApi.js +3 -4
  20. package/cjs/services/splitHttpClient.js +1 -1
  21. package/cjs/storages/AbstractSplitsCacheSync.js +5 -2
  22. package/cjs/storages/KeyBuilder.js +9 -0
  23. package/cjs/storages/KeyBuilderCS.js +3 -0
  24. package/cjs/storages/KeyBuilderSS.js +3 -0
  25. package/cjs/storages/inLocalStorage/RBSegmentsCacheInLocal.js +117 -0
  26. package/cjs/storages/inLocalStorage/SplitsCacheInLocal.js +9 -14
  27. package/cjs/storages/inLocalStorage/index.js +5 -1
  28. package/cjs/storages/inLocalStorage/validateCache.js +2 -1
  29. package/cjs/storages/inMemory/InMemoryStorage.js +3 -0
  30. package/cjs/storages/inMemory/InMemoryStorageCS.js +4 -0
  31. package/cjs/storages/inMemory/RBSegmentsCacheInMemory.js +61 -0
  32. package/cjs/storages/inMemory/SplitsCacheInMemory.js +1 -0
  33. package/cjs/storages/inRedis/RBSegmentsCacheInRedis.js +64 -0
  34. package/cjs/storages/inRedis/index.js +2 -0
  35. package/cjs/storages/pluggable/RBSegmentsCachePluggable.js +64 -0
  36. package/cjs/storages/pluggable/index.js +2 -0
  37. package/cjs/sync/polling/fetchers/splitChangesFetcher.js +54 -4
  38. package/cjs/sync/polling/pollingManagerCS.js +7 -7
  39. package/cjs/sync/polling/syncTasks/splitsSyncTask.js +1 -1
  40. package/cjs/sync/polling/updaters/mySegmentsUpdater.js +2 -2
  41. package/cjs/sync/polling/updaters/segmentChangesUpdater.js +1 -1
  42. package/cjs/sync/polling/updaters/splitChangesUpdater.js +59 -33
  43. package/cjs/sync/streaming/SSEHandler/index.js +1 -0
  44. package/cjs/sync/streaming/UpdateWorkers/SplitsUpdateWorker.js +106 -77
  45. package/cjs/sync/streaming/constants.js +2 -1
  46. package/cjs/sync/streaming/pushManager.js +3 -16
  47. package/cjs/sync/syncManagerOnline.js +2 -2
  48. package/cjs/utils/constants/index.js +6 -2
  49. package/cjs/utils/labels/index.js +2 -1
  50. package/esm/evaluator/Engine.js +40 -62
  51. package/esm/evaluator/combiners/and.js +2 -6
  52. package/esm/evaluator/combiners/ifelseif.js +7 -7
  53. package/esm/evaluator/condition/index.js +6 -5
  54. package/esm/evaluator/index.js +12 -12
  55. package/esm/evaluator/matchers/index.js +3 -1
  56. package/esm/evaluator/matchers/matcherTypes.js +1 -0
  57. package/esm/evaluator/matchers/prerequisites.js +18 -0
  58. package/esm/evaluator/matchers/rbsegment.js +52 -0
  59. package/esm/evaluator/matchersTransform/index.js +4 -0
  60. package/esm/evaluator/parser/index.js +2 -2
  61. package/esm/evaluator/value/sanitize.js +1 -0
  62. package/esm/logger/constants.js +2 -0
  63. package/esm/logger/messages/debug.js +4 -2
  64. package/esm/logger/messages/warn.js +1 -1
  65. package/esm/sdkManager/index.js +2 -1
  66. package/esm/services/splitApi.js +3 -4
  67. package/esm/services/splitHttpClient.js +1 -1
  68. package/esm/storages/AbstractSplitsCacheSync.js +5 -2
  69. package/esm/storages/KeyBuilder.js +9 -0
  70. package/esm/storages/KeyBuilderCS.js +3 -0
  71. package/esm/storages/KeyBuilderSS.js +3 -0
  72. package/esm/storages/inLocalStorage/RBSegmentsCacheInLocal.js +114 -0
  73. package/esm/storages/inLocalStorage/SplitsCacheInLocal.js +9 -14
  74. package/esm/storages/inLocalStorage/index.js +5 -1
  75. package/esm/storages/inLocalStorage/validateCache.js +2 -1
  76. package/esm/storages/inMemory/InMemoryStorage.js +3 -0
  77. package/esm/storages/inMemory/InMemoryStorageCS.js +4 -0
  78. package/esm/storages/inMemory/RBSegmentsCacheInMemory.js +58 -0
  79. package/esm/storages/inMemory/SplitsCacheInMemory.js +1 -0
  80. package/esm/storages/inRedis/RBSegmentsCacheInRedis.js +61 -0
  81. package/esm/storages/inRedis/index.js +2 -0
  82. package/esm/storages/pluggable/RBSegmentsCachePluggable.js +61 -0
  83. package/esm/storages/pluggable/index.js +2 -0
  84. package/esm/sync/polling/fetchers/splitChangesFetcher.js +54 -4
  85. package/esm/sync/polling/pollingManagerCS.js +7 -7
  86. package/esm/sync/polling/syncTasks/splitsSyncTask.js +1 -1
  87. package/esm/sync/polling/updaters/mySegmentsUpdater.js +2 -2
  88. package/esm/sync/polling/updaters/segmentChangesUpdater.js +1 -1
  89. package/esm/sync/polling/updaters/splitChangesUpdater.js +59 -33
  90. package/esm/sync/streaming/SSEHandler/index.js +2 -1
  91. package/esm/sync/streaming/UpdateWorkers/SplitsUpdateWorker.js +102 -73
  92. package/esm/sync/streaming/constants.js +1 -0
  93. package/esm/sync/streaming/pushManager.js +6 -19
  94. package/esm/sync/syncManagerOnline.js +2 -2
  95. package/esm/utils/constants/index.js +5 -1
  96. package/esm/utils/labels/index.js +1 -0
  97. package/package.json +1 -1
  98. package/src/dtos/types.ts +41 -8
  99. package/src/evaluator/Engine.ts +42 -69
  100. package/src/evaluator/combiners/and.ts +5 -4
  101. package/src/evaluator/combiners/ifelseif.ts +7 -9
  102. package/src/evaluator/condition/engineUtils.ts +1 -1
  103. package/src/evaluator/condition/index.ts +12 -12
  104. package/src/evaluator/index.ts +12 -14
  105. package/src/evaluator/matchers/index.ts +3 -1
  106. package/src/evaluator/matchers/matcherTypes.ts +1 -0
  107. package/src/evaluator/matchers/prerequisites.ts +24 -0
  108. package/src/evaluator/matchers/rbsegment.ts +74 -0
  109. package/src/evaluator/matchersTransform/index.ts +3 -0
  110. package/src/evaluator/parser/index.ts +3 -3
  111. package/src/evaluator/types.ts +2 -2
  112. package/src/evaluator/value/index.ts +2 -2
  113. package/src/evaluator/value/sanitize.ts +5 -4
  114. package/src/logger/constants.ts +2 -0
  115. package/src/logger/messages/debug.ts +4 -2
  116. package/src/logger/messages/warn.ts +1 -1
  117. package/src/sdkManager/index.ts +3 -2
  118. package/src/services/splitApi.ts +3 -4
  119. package/src/services/splitHttpClient.ts +1 -1
  120. package/src/services/types.ts +1 -1
  121. package/src/storages/AbstractSplitsCacheSync.ts +6 -3
  122. package/src/storages/KeyBuilder.ts +12 -0
  123. package/src/storages/KeyBuilderCS.ts +4 -0
  124. package/src/storages/KeyBuilderSS.ts +4 -0
  125. package/src/storages/inLocalStorage/RBSegmentsCacheInLocal.ts +136 -0
  126. package/src/storages/inLocalStorage/SplitsCacheInLocal.ts +10 -14
  127. package/src/storages/inLocalStorage/index.ts +5 -1
  128. package/src/storages/inLocalStorage/validateCache.ts +3 -1
  129. package/src/storages/inMemory/InMemoryStorage.ts +3 -0
  130. package/src/storages/inMemory/InMemoryStorageCS.ts +4 -0
  131. package/src/storages/inMemory/RBSegmentsCacheInMemory.ts +68 -0
  132. package/src/storages/inMemory/SplitsCacheInMemory.ts +1 -0
  133. package/src/storages/inRedis/RBSegmentsCacheInRedis.ts +79 -0
  134. package/src/storages/inRedis/index.ts +2 -0
  135. package/src/storages/pluggable/RBSegmentsCachePluggable.ts +76 -0
  136. package/src/storages/pluggable/index.ts +2 -0
  137. package/src/storages/types.ts +33 -1
  138. package/src/sync/polling/fetchers/splitChangesFetcher.ts +65 -4
  139. package/src/sync/polling/fetchers/types.ts +1 -0
  140. package/src/sync/polling/pollingManagerCS.ts +7 -7
  141. package/src/sync/polling/syncTasks/splitsSyncTask.ts +1 -1
  142. package/src/sync/polling/types.ts +2 -2
  143. package/src/sync/polling/updaters/mySegmentsUpdater.ts +2 -2
  144. package/src/sync/polling/updaters/segmentChangesUpdater.ts +1 -1
  145. package/src/sync/polling/updaters/splitChangesUpdater.ts +70 -43
  146. package/src/sync/streaming/SSEHandler/index.ts +2 -1
  147. package/src/sync/streaming/SSEHandler/types.ts +2 -2
  148. package/src/sync/streaming/UpdateWorkers/SplitsUpdateWorker.ts +98 -68
  149. package/src/sync/streaming/constants.ts +1 -0
  150. package/src/sync/streaming/parseUtils.ts +2 -2
  151. package/src/sync/streaming/pushManager.ts +6 -18
  152. package/src/sync/streaming/types.ts +3 -2
  153. package/src/sync/syncManagerOnline.ts +2 -2
  154. package/src/utils/constants/index.ts +6 -1
  155. package/src/utils/labels/index.ts +1 -0
  156. package/src/utils/lang/index.ts +1 -1
  157. package/types/splitio.d.ts +5 -1
@@ -2,7 +2,7 @@ import { algorithms } from '../../utils/decompress';
2
2
  import { decodeFromBase64 } from '../../utils/base64';
3
3
  import { hash } from '../../utils/murmur3/murmur3';
4
4
  import { Compression, IMembershipMSUpdateData, KeyList } from './SSEHandler/types';
5
- import { ISplit } from '../../dtos/types';
5
+ import { IRBSegment, ISplit } from '../../dtos/types';
6
6
 
7
7
  const GZIP = 1;
8
8
  const ZLIB = 2;
@@ -82,7 +82,7 @@ export function isInBitmap(bitmap: Uint8Array, hash64hex: string) {
82
82
  /**
83
83
  * Parse feature flags notifications for instant feature flag updates
84
84
  */
85
- export function parseFFUpdatePayload(compression: Compression, data: string): ISplit | undefined {
85
+ export function parseFFUpdatePayload(compression: Compression, data: string): ISplit | IRBSegment | undefined {
86
86
  return compression > 0 ?
87
87
  parseKeyList(data, compression, false) :
88
88
  JSON.parse(decodeFromBase64(data));
@@ -11,10 +11,10 @@ import { authenticateFactory, hashUserKey } from './AuthClient';
11
11
  import { forOwn } from '../../utils/lang';
12
12
  import { SSEClient } from './SSEClient';
13
13
  import { 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, PUSH_RETRYABLE_ERROR, PUSH_SUBSYSTEM_UP, ControlType } from './constants';
15
- import { STREAMING_FALLBACK, STREAMING_REFRESH_TOKEN, STREAMING_CONNECTING, STREAMING_DISABLED, ERROR_STREAMING_AUTH, STREAMING_DISCONNECTING, STREAMING_RECONNECT, STREAMING_PARSING_MEMBERSHIPS_UPDATE, STREAMING_PARSING_SPLIT_UPDATE } from '../../logger/constants';
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';
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
- import { getDelay, isInBitmap, parseBitmap, parseFFUpdatePayload, parseKeyList } from './parseUtils';
17
+ import { getDelay, isInBitmap, parseBitmap, parseKeyList } from './parseUtils';
18
18
  import { Hash64, hash64 } from '../../utils/murmur3/murmur3_64';
19
19
  import { IAuthTokenPushEnabled } from './AuthClient/types';
20
20
  import { TOKEN_REFRESH, AUTH_REJECTION } from '../../utils/constants';
@@ -56,7 +56,7 @@ export function pushManagerFactory(
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
58
  // For server-side we pass the segmentsSyncTask, used by SplitsUpdateWorker to fetch new segments
59
- const splitsUpdateWorker = SplitsUpdateWorker(log, storage.splits, pollingManager.splitsSyncTask, readiness.splits, telemetryTracker, userKey ? undefined : pollingManager.segmentsSyncTask as ISegmentsSyncTask);
59
+ const splitsUpdateWorker = SplitsUpdateWorker(log, storage, pollingManager.splitsSyncTask, readiness.splits, 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> = {};
@@ -219,20 +219,8 @@ export function pushManagerFactory(
219
219
  /** Functions related to synchronization (Queues and Workers in the spec) */
220
220
 
221
221
  pushEmitter.on(SPLIT_KILL, splitsUpdateWorker.killSplit);
222
- pushEmitter.on(SPLIT_UPDATE, (parsedData) => {
223
- if (parsedData.d && parsedData.c !== undefined) {
224
- try {
225
- const payload = parseFFUpdatePayload(parsedData.c, parsedData.d);
226
- if (payload) {
227
- splitsUpdateWorker.put(parsedData, payload);
228
- return;
229
- }
230
- } catch (e) {
231
- log.warn(STREAMING_PARSING_SPLIT_UPDATE, [e]);
232
- }
233
- }
234
- splitsUpdateWorker.put(parsedData);
235
- });
222
+ pushEmitter.on(SPLIT_UPDATE, splitsUpdateWorker.put);
223
+ pushEmitter.on(RB_SEGMENT_UPDATE, splitsUpdateWorker.put);
236
224
 
237
225
  function handleMySegmentsUpdate(parsedData: IMembershipMSUpdateData | IMembershipLSUpdateData) {
238
226
  switch (parsedData.u) {
@@ -16,18 +16,19 @@ export type MEMBERSHIPS_LS_UPDATE = 'MEMBERSHIPS_LS_UPDATE';
16
16
  export type SEGMENT_UPDATE = 'SEGMENT_UPDATE';
17
17
  export type SPLIT_KILL = 'SPLIT_KILL';
18
18
  export type SPLIT_UPDATE = 'SPLIT_UPDATE';
19
+ export type RB_SEGMENT_UPDATE = 'RB_SEGMENT_UPDATE';
19
20
 
20
21
  // Control-type push notifications, handled by NotificationKeeper
21
22
  export type CONTROL = 'CONTROL';
22
23
  export type OCCUPANCY = 'OCCUPANCY';
23
24
 
24
- 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 | ControlType.STREAMING_RESET
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
26
 
26
27
  type IParsedData<T extends IPushEvent> =
27
28
  T extends MEMBERSHIPS_MS_UPDATE ? IMembershipMSUpdateData :
28
29
  T extends MEMBERSHIPS_LS_UPDATE ? IMembershipLSUpdateData :
29
30
  T extends SEGMENT_UPDATE ? ISegmentUpdateData :
30
- T extends SPLIT_UPDATE ? ISplitUpdateData :
31
+ T extends SPLIT_UPDATE | RB_SEGMENT_UPDATE ? ISplitUpdateData :
31
32
  T extends SPLIT_KILL ? ISplitKillData : INotificationData;
32
33
 
33
34
  /**
@@ -155,14 +155,14 @@ export function syncManagerOnlineFactory(
155
155
  if (pushManager) {
156
156
  if (pollingManager.isRunning()) {
157
157
  // if doing polling, we must start the periodic fetch of data
158
- if (storage.splits.usesSegments()) mySegmentsSyncTask.start();
158
+ if (storage.splits.usesSegments() || storage.rbSegments.usesSegments()) mySegmentsSyncTask.start();
159
159
  } else {
160
160
  // if not polling, we must execute the sync task for the initial fetch
161
161
  // of segments since `syncAll` was already executed when starting the main client
162
162
  mySegmentsSyncTask.execute();
163
163
  }
164
164
  } else {
165
- if (storage.splits.usesSegments()) mySegmentsSyncTask.start();
165
+ if (storage.splits.usesSegments() || storage.rbSegments.usesSegments()) mySegmentsSyncTask.start();
166
166
  }
167
167
  } else {
168
168
  if (!readinessManager.isReady()) mySegmentsSyncTask.execute();
@@ -104,8 +104,13 @@ export const DISABLED = 0;
104
104
  export const ENABLED = 1;
105
105
  export const PAUSED = 2;
106
106
 
107
- export const FLAG_SPEC_VERSION = '1.2';
107
+ export const FLAG_SPEC_VERSION = '1.3';
108
108
 
109
109
  // Matcher types
110
110
  export const IN_SEGMENT = 'IN_SEGMENT';
111
111
  export const IN_LARGE_SEGMENT = 'IN_LARGE_SEGMENT';
112
+ export const IN_RULE_BASED_SEGMENT = 'IN_RULE_BASED_SEGMENT';
113
+
114
+ export const STANDARD_SEGMENT = 'standard';
115
+ export const LARGE_SEGMENT = 'large';
116
+ export const RULE_BASED_SEGMENT = 'rule-based';
@@ -6,3 +6,4 @@ export const EXCEPTION = 'exception';
6
6
  export const SPLIT_ARCHIVED = 'archived';
7
7
  export const NOT_IN_SPLIT = 'not in split';
8
8
  export const UNSUPPORTED_MATCHER_TYPE = 'targeting rule type unsupported by sdk';
9
+ export const PREREQUISITES_NOT_MET = 'prerequisites not met';
@@ -111,7 +111,7 @@ export function groupBy<T extends Record<string, any>>(source: T[], prop: string
111
111
  /**
112
112
  * Checks if a given value is a boolean.
113
113
  */
114
- export function isBoolean(val: any): boolean {
114
+ export function isBoolean(val: any): val is boolean {
115
115
  return val === true || val === false;
116
116
  }
117
117
 
@@ -879,7 +879,7 @@ declare namespace SplitIO {
879
879
  /**
880
880
  * The list of treatments available for the feature flag.
881
881
  */
882
- treatments: Array<string>;
882
+ treatments: string[];
883
883
  /**
884
884
  * Current change number of the feature flag.
885
885
  */
@@ -903,6 +903,10 @@ declare namespace SplitIO {
903
903
  * Whether the feature flag has impressions tracking disabled or not.
904
904
  */
905
905
  impressionsDisabled: boolean;
906
+ /**
907
+ * Prerequisites for the feature flag.
908
+ */
909
+ prerequisites: Array<{ flagName: string, treatments: string[] }>;
906
910
  };
907
911
  /**
908
912
  * A promise that resolves to a feature flag view or null if the feature flag is not found.