@splitsoftware/splitio-commons 2.1.0 → 2.1.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 (154) hide show
  1. package/README.md +1 -0
  2. package/cjs/evaluator/combiners/and.js +2 -6
  3. package/cjs/evaluator/combiners/ifelseif.js +6 -6
  4. package/cjs/evaluator/condition/index.js +6 -5
  5. package/cjs/evaluator/index.js +7 -7
  6. package/cjs/evaluator/matchers/index.js +3 -1
  7. package/cjs/evaluator/matchers/matcherTypes.js +1 -0
  8. package/cjs/evaluator/matchers/rbsegment.js +43 -0
  9. package/cjs/evaluator/matchersTransform/index.js +4 -0
  10. package/cjs/evaluator/parser/index.js +2 -2
  11. package/cjs/evaluator/value/sanitize.js +1 -0
  12. package/cjs/logger/constants.js +5 -6
  13. package/cjs/logger/messages/debug.js +3 -4
  14. package/cjs/logger/messages/warn.js +1 -1
  15. package/cjs/services/splitApi.js +2 -2
  16. package/cjs/storages/AbstractSplitsCacheAsync.js +12 -1
  17. package/cjs/storages/AbstractSplitsCacheSync.js +10 -9
  18. package/cjs/storages/KeyBuilder.js +8 -15
  19. package/cjs/storages/KeyBuilderCS.js +12 -3
  20. package/cjs/storages/KeyBuilderSS.js +3 -0
  21. package/cjs/storages/dataLoader.js +1 -2
  22. package/cjs/storages/inLocalStorage/RBSegmentsCacheInLocal.js +117 -0
  23. package/cjs/storages/inLocalStorage/SplitsCacheInLocal.js +14 -16
  24. package/cjs/storages/inLocalStorage/index.js +4 -0
  25. package/cjs/storages/inMemory/InMemoryStorage.js +3 -0
  26. package/cjs/storages/inMemory/InMemoryStorageCS.js +4 -0
  27. package/cjs/storages/inMemory/RBSegmentsCacheInMemory.js +61 -0
  28. package/cjs/storages/inMemory/SplitsCacheInMemory.js +24 -31
  29. package/cjs/storages/inRedis/RBSegmentsCacheInRedis.js +64 -0
  30. package/cjs/storages/inRedis/SplitsCacheInRedis.js +4 -21
  31. package/cjs/storages/inRedis/index.js +2 -0
  32. package/cjs/storages/pluggable/RBSegmentsCachePluggable.js +64 -0
  33. package/cjs/storages/pluggable/SplitsCachePluggable.js +2 -19
  34. package/cjs/storages/pluggable/index.js +2 -0
  35. package/cjs/sync/offline/syncTasks/fromObjectSyncTask.js +12 -13
  36. package/cjs/sync/polling/fetchers/splitChangesFetcher.js +2 -2
  37. package/cjs/sync/polling/pollingManagerCS.js +7 -7
  38. package/cjs/sync/polling/syncTasks/splitsSyncTask.js +1 -1
  39. package/cjs/sync/polling/updaters/mySegmentsUpdater.js +2 -2
  40. package/cjs/sync/polling/updaters/segmentChangesUpdater.js +1 -1
  41. package/cjs/sync/polling/updaters/splitChangesUpdater.js +53 -51
  42. package/cjs/sync/streaming/SSEHandler/index.js +1 -0
  43. package/cjs/sync/streaming/UpdateWorkers/SplitsUpdateWorker.js +106 -77
  44. package/cjs/sync/streaming/constants.js +2 -1
  45. package/cjs/sync/streaming/pushManager.js +3 -16
  46. package/cjs/sync/syncManagerOnline.js +2 -2
  47. package/cjs/utils/constants/index.js +3 -2
  48. package/esm/evaluator/combiners/and.js +2 -6
  49. package/esm/evaluator/combiners/ifelseif.js +7 -7
  50. package/esm/evaluator/condition/index.js +6 -5
  51. package/esm/evaluator/index.js +7 -7
  52. package/esm/evaluator/matchers/index.js +3 -1
  53. package/esm/evaluator/matchers/matcherTypes.js +1 -0
  54. package/esm/evaluator/matchers/rbsegment.js +39 -0
  55. package/esm/evaluator/matchersTransform/index.js +4 -0
  56. package/esm/evaluator/parser/index.js +2 -2
  57. package/esm/evaluator/value/sanitize.js +1 -0
  58. package/esm/logger/constants.js +2 -3
  59. package/esm/logger/messages/debug.js +3 -4
  60. package/esm/logger/messages/warn.js +1 -1
  61. package/esm/services/splitApi.js +2 -2
  62. package/esm/storages/AbstractSplitsCacheAsync.js +12 -1
  63. package/esm/storages/AbstractSplitsCacheSync.js +10 -9
  64. package/esm/storages/KeyBuilder.js +8 -15
  65. package/esm/storages/KeyBuilderCS.js +12 -3
  66. package/esm/storages/KeyBuilderSS.js +3 -0
  67. package/esm/storages/dataLoader.js +1 -2
  68. package/esm/storages/inLocalStorage/RBSegmentsCacheInLocal.js +114 -0
  69. package/esm/storages/inLocalStorage/SplitsCacheInLocal.js +14 -16
  70. package/esm/storages/inLocalStorage/index.js +4 -0
  71. package/esm/storages/inMemory/InMemoryStorage.js +3 -0
  72. package/esm/storages/inMemory/InMemoryStorageCS.js +4 -0
  73. package/esm/storages/inMemory/RBSegmentsCacheInMemory.js +58 -0
  74. package/esm/storages/inMemory/SplitsCacheInMemory.js +24 -31
  75. package/esm/storages/inRedis/RBSegmentsCacheInRedis.js +61 -0
  76. package/esm/storages/inRedis/SplitsCacheInRedis.js +4 -21
  77. package/esm/storages/inRedis/index.js +2 -0
  78. package/esm/storages/pluggable/RBSegmentsCachePluggable.js +61 -0
  79. package/esm/storages/pluggable/SplitsCachePluggable.js +2 -19
  80. package/esm/storages/pluggable/index.js +2 -0
  81. package/esm/sync/offline/syncTasks/fromObjectSyncTask.js +12 -13
  82. package/esm/sync/polling/fetchers/splitChangesFetcher.js +2 -2
  83. package/esm/sync/polling/pollingManagerCS.js +7 -7
  84. package/esm/sync/polling/syncTasks/splitsSyncTask.js +1 -1
  85. package/esm/sync/polling/updaters/mySegmentsUpdater.js +2 -2
  86. package/esm/sync/polling/updaters/segmentChangesUpdater.js +1 -1
  87. package/esm/sync/polling/updaters/splitChangesUpdater.js +53 -51
  88. package/esm/sync/streaming/SSEHandler/index.js +2 -1
  89. package/esm/sync/streaming/UpdateWorkers/SplitsUpdateWorker.js +102 -73
  90. package/esm/sync/streaming/constants.js +1 -0
  91. package/esm/sync/streaming/pushManager.js +6 -19
  92. package/esm/sync/syncManagerOnline.js +2 -2
  93. package/esm/utils/constants/index.js +2 -1
  94. package/package.json +1 -1
  95. package/src/dtos/types.ts +32 -8
  96. package/src/evaluator/Engine.ts +1 -1
  97. package/src/evaluator/combiners/and.ts +5 -4
  98. package/src/evaluator/combiners/ifelseif.ts +7 -9
  99. package/src/evaluator/condition/engineUtils.ts +1 -1
  100. package/src/evaluator/condition/index.ts +12 -12
  101. package/src/evaluator/index.ts +7 -7
  102. package/src/evaluator/matchers/index.ts +3 -1
  103. package/src/evaluator/matchers/matcherTypes.ts +1 -0
  104. package/src/evaluator/matchers/rbsegment.ts +61 -0
  105. package/src/evaluator/matchersTransform/index.ts +3 -0
  106. package/src/evaluator/parser/index.ts +3 -3
  107. package/src/evaluator/types.ts +2 -2
  108. package/src/evaluator/value/index.ts +2 -2
  109. package/src/evaluator/value/sanitize.ts +5 -4
  110. package/src/logger/constants.ts +2 -3
  111. package/src/logger/messages/debug.ts +3 -4
  112. package/src/logger/messages/warn.ts +1 -1
  113. package/src/sdkManager/index.ts +1 -1
  114. package/src/services/splitApi.ts +2 -2
  115. package/src/services/types.ts +1 -1
  116. package/src/storages/AbstractSplitsCacheAsync.ts +15 -5
  117. package/src/storages/AbstractSplitsCacheSync.ts +14 -15
  118. package/src/storages/KeyBuilder.ts +9 -17
  119. package/src/storages/KeyBuilderCS.ts +15 -4
  120. package/src/storages/KeyBuilderSS.ts +4 -0
  121. package/src/storages/dataLoader.ts +1 -2
  122. package/src/storages/inLocalStorage/RBSegmentsCacheInLocal.ts +136 -0
  123. package/src/storages/inLocalStorage/SplitsCacheInLocal.ts +15 -16
  124. package/src/storages/inLocalStorage/index.ts +4 -0
  125. package/src/storages/inMemory/InMemoryStorage.ts +3 -0
  126. package/src/storages/inMemory/InMemoryStorageCS.ts +4 -0
  127. package/src/storages/inMemory/RBSegmentsCacheInMemory.ts +68 -0
  128. package/src/storages/inMemory/SplitsCacheInMemory.ts +22 -27
  129. package/src/storages/inRedis/RBSegmentsCacheInRedis.ts +79 -0
  130. package/src/storages/inRedis/SplitsCacheInRedis.ts +4 -21
  131. package/src/storages/inRedis/index.ts +2 -0
  132. package/src/storages/pluggable/RBSegmentsCachePluggable.ts +76 -0
  133. package/src/storages/pluggable/SplitsCachePluggable.ts +2 -19
  134. package/src/storages/pluggable/index.ts +2 -0
  135. package/src/storages/types.ts +43 -17
  136. package/src/sync/offline/syncTasks/fromObjectSyncTask.ts +14 -15
  137. package/src/sync/polling/fetchers/splitChangesFetcher.ts +2 -1
  138. package/src/sync/polling/fetchers/types.ts +1 -0
  139. package/src/sync/polling/pollingManagerCS.ts +7 -7
  140. package/src/sync/polling/syncTasks/splitsSyncTask.ts +1 -2
  141. package/src/sync/polling/types.ts +2 -2
  142. package/src/sync/polling/updaters/mySegmentsUpdater.ts +2 -2
  143. package/src/sync/polling/updaters/segmentChangesUpdater.ts +1 -1
  144. package/src/sync/polling/updaters/splitChangesUpdater.ts +64 -62
  145. package/src/sync/streaming/SSEHandler/index.ts +2 -1
  146. package/src/sync/streaming/SSEHandler/types.ts +2 -2
  147. package/src/sync/streaming/UpdateWorkers/SplitsUpdateWorker.ts +98 -68
  148. package/src/sync/streaming/constants.ts +1 -0
  149. package/src/sync/streaming/parseUtils.ts +2 -2
  150. package/src/sync/streaming/pushManager.ts +6 -18
  151. package/src/sync/streaming/types.ts +3 -2
  152. package/src/sync/syncManagerOnline.ts +2 -2
  153. package/src/utils/constants/index.ts +2 -1
  154. package/src/utils/lang/index.ts +1 -1
@@ -1,12 +1,16 @@
1
- import { ISplit } from '../../../dtos/types';
1
+ import { IRBSegment, ISplit } from '../../../dtos/types';
2
+ import { STREAMING_PARSING_SPLIT_UPDATE } from '../../../logger/constants';
2
3
  import { ILogger } from '../../../logger/types';
3
4
  import { SDK_SPLITS_ARRIVED } from '../../../readiness/constants';
4
5
  import { ISplitsEventEmitter } from '../../../readiness/types';
5
- import { ISplitsCacheSync } from '../../../storages/types';
6
+ import { IRBSegmentsCacheSync, ISplitsCacheSync, IStorageSync } from '../../../storages/types';
6
7
  import { ITelemetryTracker } from '../../../trackers/types';
7
8
  import { Backoff } from '../../../utils/Backoff';
8
9
  import { SPLITS } from '../../../utils/constants';
9
10
  import { ISegmentsSyncTask, ISplitsSyncTask } from '../../polling/types';
11
+ import { InstantUpdate } from '../../polling/updaters/splitChangesUpdater';
12
+ import { RB_SEGMENT_UPDATE } from '../constants';
13
+ import { parseFFUpdatePayload } from '../parseUtils';
10
14
  import { ISplitKillData, ISplitUpdateData } from '../SSEHandler/types';
11
15
  import { FETCH_BACKOFF_BASE, FETCH_BACKOFF_MAX_WAIT, FETCH_BACKOFF_MAX_RETRIES } from './constants';
12
16
  import { IUpdateWorker } from './types';
@@ -14,102 +18,128 @@ import { IUpdateWorker } from './types';
14
18
  /**
15
19
  * SplitsUpdateWorker factory
16
20
  */
17
- export function SplitsUpdateWorker(log: ILogger, splitsCache: ISplitsCacheSync, splitsSyncTask: ISplitsSyncTask, splitsEventEmitter: ISplitsEventEmitter, telemetryTracker: ITelemetryTracker, segmentsSyncTask?: ISegmentsSyncTask): IUpdateWorker<[updateData: ISplitUpdateData, payload?: ISplit]> & { killSplit(event: ISplitKillData): void } {
21
+ export function SplitsUpdateWorker(log: ILogger, storage: IStorageSync, splitsSyncTask: ISplitsSyncTask, splitsEventEmitter: ISplitsEventEmitter, telemetryTracker: ITelemetryTracker, segmentsSyncTask?: ISegmentsSyncTask): IUpdateWorker<[updateData: ISplitUpdateData]> & { killSplit(event: ISplitKillData): void } {
18
22
 
19
- let maxChangeNumber = 0;
20
- let handleNewEvent = false;
21
- let isHandlingEvent: boolean;
22
- let cdnBypass: boolean;
23
- let payload: ISplit | undefined;
24
- const backoff = new Backoff(__handleSplitUpdateCall, FETCH_BACKOFF_BASE, FETCH_BACKOFF_MAX_WAIT);
23
+ const ff = SplitsUpdateWorker(storage.splits);
24
+ const rbs = SplitsUpdateWorker(storage.rbSegments);
25
25
 
26
- function __handleSplitUpdateCall() {
27
- isHandlingEvent = true;
28
- if (maxChangeNumber > splitsCache.getChangeNumber()) {
29
- handleNewEvent = false;
30
- const splitUpdateNotification = payload ? { payload, changeNumber: maxChangeNumber } : undefined;
31
- // fetch splits revalidating data if cached
32
- splitsSyncTask.execute(true, cdnBypass ? maxChangeNumber : undefined, splitUpdateNotification).then(() => {
33
- if (!isHandlingEvent) return; // halt if `stop` has been called
34
- if (handleNewEvent) {
35
- __handleSplitUpdateCall();
36
- } else {
37
- if (splitUpdateNotification) telemetryTracker.trackUpdatesFromSSE(SPLITS);
38
- // fetch new registered segments for server-side API. Not retrying on error
39
- if (segmentsSyncTask) segmentsSyncTask.execute(true);
26
+ function SplitsUpdateWorker(cache: ISplitsCacheSync | IRBSegmentsCacheSync) {
27
+ let maxChangeNumber = -1;
28
+ let handleNewEvent = false;
29
+ let isHandlingEvent: boolean;
30
+ let cdnBypass: boolean;
31
+ let instantUpdate: InstantUpdate | undefined;
32
+ const backoff = new Backoff(__handleSplitUpdateCall, FETCH_BACKOFF_BASE, FETCH_BACKOFF_MAX_WAIT);
40
33
 
41
- const attempts = backoff.attempts + 1;
34
+ function __handleSplitUpdateCall() {
35
+ isHandlingEvent = true;
36
+ if (maxChangeNumber > cache.getChangeNumber()) {
37
+ handleNewEvent = false;
38
+ // fetch splits revalidating data if cached
39
+ splitsSyncTask.execute(true, cdnBypass ? maxChangeNumber : undefined, instantUpdate).then(() => {
40
+ if (!isHandlingEvent) return; // halt if `stop` has been called
41
+ if (handleNewEvent) {
42
+ __handleSplitUpdateCall();
43
+ } else {
44
+ if (instantUpdate) telemetryTracker.trackUpdatesFromSSE(SPLITS);
45
+ // fetch new registered segments for server-side API. Not retrying on error
46
+ if (segmentsSyncTask) segmentsSyncTask.execute(true);
42
47
 
43
- if (maxChangeNumber <= splitsCache.getChangeNumber()) {
44
- log.debug(`Refresh completed${cdnBypass ? ' bypassing the CDN' : ''} in ${attempts} attempts.`);
45
- isHandlingEvent = false;
46
- return;
47
- }
48
+ const attempts = backoff.attempts + 1;
48
49
 
49
- if (attempts < FETCH_BACKOFF_MAX_RETRIES) {
50
- backoff.scheduleCall();
51
- return;
52
- }
50
+ if (ff.isSync() && rbs.isSync()) {
51
+ log.debug(`Refresh completed${cdnBypass ? ' bypassing the CDN' : ''} in ${attempts} attempts.`);
52
+ isHandlingEvent = false;
53
+ return;
54
+ }
53
55
 
54
- if (cdnBypass) {
55
- log.debug(`No changes fetched after ${attempts} attempts with CDN bypassed.`);
56
- isHandlingEvent = false;
57
- } else {
58
- backoff.reset();
59
- cdnBypass = true;
60
- __handleSplitUpdateCall();
56
+ if (attempts < FETCH_BACKOFF_MAX_RETRIES) {
57
+ backoff.scheduleCall();
58
+ return;
59
+ }
60
+
61
+ if (cdnBypass) {
62
+ log.debug(`No changes fetched after ${attempts} attempts with CDN bypassed.`);
63
+ isHandlingEvent = false;
64
+ } else {
65
+ backoff.reset();
66
+ cdnBypass = true;
67
+ __handleSplitUpdateCall();
68
+ }
61
69
  }
62
- }
63
- });
64
- } else {
65
- isHandlingEvent = false;
70
+ });
71
+ } else {
72
+ isHandlingEvent = false;
73
+ }
66
74
  }
67
- }
68
75
 
69
- /**
70
- * Invoked by NotificationProcessor on SPLIT_UPDATE event
71
- *
72
- * @param changeNumber - change number of the SPLIT_UPDATE notification
73
- */
74
- function put({ changeNumber, pcn }: ISplitUpdateData, _payload?: ISplit) {
75
- const currentChangeNumber = splitsCache.getChangeNumber();
76
+ return {
77
+ /**
78
+ * Invoked by NotificationProcessor on SPLIT_UPDATE or RB_SEGMENT_UPDATE event
79
+ *
80
+ * @param changeNumber - change number of the notification
81
+ */
82
+ put({ changeNumber, pcn, type }: ISplitUpdateData, payload?: ISplit | IRBSegment) {
83
+ const currentChangeNumber = cache.getChangeNumber();
76
84
 
77
- if (changeNumber <= currentChangeNumber || changeNumber <= maxChangeNumber) return;
85
+ if (changeNumber <= currentChangeNumber || changeNumber <= maxChangeNumber) return;
78
86
 
79
- maxChangeNumber = changeNumber;
80
- handleNewEvent = true;
81
- cdnBypass = false;
82
- payload = undefined;
87
+ maxChangeNumber = changeNumber;
88
+ handleNewEvent = true;
89
+ cdnBypass = false;
90
+ instantUpdate = undefined;
83
91
 
84
- if (_payload && currentChangeNumber === pcn) {
85
- payload = _payload;
86
- }
92
+ if (payload && currentChangeNumber === pcn) {
93
+ instantUpdate = { payload, changeNumber, type };
94
+ }
87
95
 
88
- if (backoff.timeoutID || !isHandlingEvent) __handleSplitUpdateCall();
89
- backoff.reset();
96
+ if (backoff.timeoutID || !isHandlingEvent) __handleSplitUpdateCall();
97
+ backoff.reset();
98
+ },
99
+ stop() {
100
+ isHandlingEvent = false;
101
+ backoff.reset();
102
+ },
103
+ isSync() {
104
+ return maxChangeNumber <= cache.getChangeNumber();
105
+ }
106
+ };
90
107
  }
91
108
 
92
109
  return {
93
- put,
110
+ put(parsedData) {
111
+ if (parsedData.d && parsedData.c !== undefined) {
112
+ try {
113
+ const payload = parseFFUpdatePayload(parsedData.c, parsedData.d);
114
+ if (payload) {
115
+ (parsedData.type === RB_SEGMENT_UPDATE ? rbs : ff).put(parsedData, payload);
116
+ return;
117
+ }
118
+ } catch (e) {
119
+ log.warn(STREAMING_PARSING_SPLIT_UPDATE, [parsedData.type, e]);
120
+ }
121
+ }
122
+ (parsedData.type === RB_SEGMENT_UPDATE ? rbs : ff).put(parsedData);
123
+ },
94
124
  /**
95
125
  * Invoked by NotificationProcessor on SPLIT_KILL event
96
126
  *
97
- * @param changeNumber - change number of the SPLIT_UPDATE notification
127
+ * @param changeNumber - change number of the notification
98
128
  * @param splitName - name of split to kill
99
129
  * @param defaultTreatment - default treatment value
100
130
  */
101
131
  killSplit({ changeNumber, splitName, defaultTreatment }: ISplitKillData) {
102
- if (splitsCache.killLocally(splitName, defaultTreatment, changeNumber)) {
132
+ if (storage.splits.killLocally(splitName, defaultTreatment, changeNumber)) {
103
133
  // trigger an SDK_UPDATE if Split was killed locally
104
134
  splitsEventEmitter.emit(SDK_SPLITS_ARRIVED, true);
105
135
  }
106
136
  // queues the SplitChanges fetch (only if changeNumber is newer)
107
- put({ changeNumber } as ISplitUpdateData);
137
+ ff.put({ changeNumber } as ISplitUpdateData);
108
138
  },
109
139
 
110
140
  stop() {
111
- isHandlingEvent = false;
112
- backoff.reset();
141
+ ff.stop();
142
+ rbs.stop();
113
143
  }
114
144
  };
115
145
  }
@@ -30,6 +30,7 @@ export const MEMBERSHIPS_LS_UPDATE = 'MEMBERSHIPS_LS_UPDATE';
30
30
  export const SEGMENT_UPDATE = 'SEGMENT_UPDATE';
31
31
  export const SPLIT_KILL = 'SPLIT_KILL';
32
32
  export const SPLIT_UPDATE = 'SPLIT_UPDATE';
33
+ export const RB_SEGMENT_UPDATE = 'RB_SEGMENT_UPDATE';
33
34
 
34
35
  // Control-type push notifications, handled by NotificationKeeper
35
36
  export const CONTROL = 'CONTROL';
@@ -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
  /**
@@ -149,14 +149,14 @@ export function syncManagerOnlineFactory(
149
149
  if (pushManager) {
150
150
  if (pollingManager.isRunning()) {
151
151
  // if doing polling, we must start the periodic fetch of data
152
- if (storage.splits.usesSegments()) mySegmentsSyncTask.start();
152
+ if (storage.splits.usesSegments() || storage.rbSegments.usesSegments()) mySegmentsSyncTask.start();
153
153
  } else {
154
154
  // if not polling, we must execute the sync task for the initial fetch
155
155
  // of segments since `syncAll` was already executed when starting the main client
156
156
  mySegmentsSyncTask.execute();
157
157
  }
158
158
  } else {
159
- if (storage.splits.usesSegments()) mySegmentsSyncTask.start();
159
+ if (storage.splits.usesSegments() || storage.rbSegments.usesSegments()) mySegmentsSyncTask.start();
160
160
  }
161
161
  } else {
162
162
  if (!readinessManager.isReady()) mySegmentsSyncTask.execute();
@@ -104,8 +104,9 @@ 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';
@@ -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